diff -u --recursive --new-file v2.4.3/linux/CREDITS linux/CREDITS
--- v2.4.3/linux/CREDITS	Sun Mar 25 18:14:20 2001
+++ linux/CREDITS	Fri Apr  6 10:42:55 2001
@@ -311,9 +311,6 @@
 W: http://samba.org/~anton/
 P: 1024/8462A731 4C 55 86 34 44 59 A7 99  2B 97 88 4A 88 9A 0D 97
 D: sun4 port, Sparc hacker
-S: 47 Robert Street
-S: Marrickville NSW 2204
-S: Australia
 
 N: Hugh Blemings
 E: hugh@misc.nu
@@ -766,6 +763,11 @@
 S: S-114 53 Stockholm
 S: Sweden
 
+N: Michael Engel
+E: engel@unix-ag.org
+D: DECstation framebuffer drivers
+S: Germany
+
 N: Paal-Kristian Engstad
 E: engstad@intermetrics.com
 D: Kernel smbfs (to mount WfW, NT and OS/2 network drives.)
@@ -1220,13 +1222,12 @@
 S: USA
 
 N: Harald Hoyer
-E: HarryH@Royal.Net
-W: http://hot.spotline.de/
-W: http://home.pages.de/~saturn
+E: harald.hoyer@parzelle.de
+W: http://parzelle.de/
 D: ip_masq_quake
 D: md boot support
-S: Alleenstrasse 27
-S: D-71679 Asperg
+S: Hohe Strasse 30
+S: D-70176 Stuttgart
 S: Germany
 
 N: Jan Hubicka
@@ -1725,12 +1726,8 @@
 S: Czech Republic
 
 N: Paul Mackerras
-E: paulus@linuxcare.com
+E: paulus@samba.org
 D: Linux port for PCI Power Macintosh
-S: Linuxcare, Inc.
-S: 24 Marcus Clarke Street
-S: Canberra ACT 2601
-S: Australia
 
 N: Pat Mackinlay
 E: pat@it.com.au
@@ -1879,6 +1876,11 @@
 S: 80050-430 - Curitiba - Paraná
 S: Brazil
 
+N: Karsten Merker
+E: merker@linuxtag.org
+D: DECstation framebuffer drivers
+S: Germany
+
 N: Michael Meskes
 E: meskes@debian.org
 P: 1024/04B6E8F5 6C 77 33 CA CC D6 22 03  AB AB 15 A3 AE AD 39 7D
@@ -2359,8 +2361,8 @@
 S: Brazil
 
 N: Stephen Rothwell
-E: sfr@linuxcare.com.au
-W: http://linuxcare.com.au/sfr
+E: sfr@canb.auug.org.au
+W: http://www.canb.auug.org.au/~sfr
 P: 1024/BD8C7805 CD A4 9D 01 10 6E 7E 3B  91 88 FA D9 C8 40 AA 02
 D: Boot/setup/build work for setup > 2K
 D: Author, APM driver
@@ -2403,12 +2405,12 @@
 S: Germany
 
 N: Paul `Rusty' Russell
-E: rusty@linuxcare.com
+E: rusty@rustcorp.com.au
 W: http://www.samba.org/netfilter
 D: Ruggedly handsome.
 D: netfilter, ipchains with Michael Neuling.
-S: 301/222 City Walk
-S: Canberra ACT 2601
+S: 52 Moore St
+S: Turner ACT 2612
 S: Australia
 
 N: Bill Ryder
@@ -2429,11 +2431,11 @@
 S: Finland
 
 N: Thomas Sailer
-E: sailer@ife.ee.ethz.ch
+E: t.sailer@alumni.ethz.ch
 E: HB9JNX@HB9W.CHE.EU (packet radio)
 D: hfmodem, Baycom and sound card radio modem driver
-S: Weinbergstrasse 76
-S: 8408 Winterthur
+S: Markusstrasse 18
+S: 8006 Zuerich
 S: Switzerland
 
 N: Robert Sanders
@@ -2516,6 +2518,14 @@
 S: San Jose, California
 S: USA
 
+N: Robert Siemer
+E: Robert.Siemer@gmx.de
+P: 2048/C99A4289 2F DC 17 2E 56 62 01 C8  3D F2 AC 09 F2 E5 DD EE
+D: miroSOUND PCM20 radio RDS driver, ACI rewrite
+S: Klosterweg 28 / i309
+S: 76131 Karlsruhe
+S: Germany
+
 N: Jaspreet Singh
 E: jaspreet@sangoma.com
 W: www.sangoma.com
@@ -2696,7 +2706,7 @@
 
 N: Andrew Tridgell
 E: tridge@samba.org
-W: http://linuxcare.com.au/tridge/
+W: http://samba.org/tridge/
 D: dosemu, networking, samba
 S: 3 Ballow Crescent
 S: MacGregor A.C.T 2615
diff -u --recursive --new-file v2.4.3/linux/Documentation/DocBook/Makefile linux/Documentation/DocBook/Makefile
--- v2.4.3/linux/Documentation/DocBook/Makefile	Sat Feb  3 12:43:55 2001
+++ linux/Documentation/DocBook/Makefile	Fri Apr  6 10:42:55 2001
@@ -1,6 +1,7 @@
 BOOKS	:= wanbook.sgml z8530book.sgml mcabook.sgml videobook.sgml \
 	   kernel-api.sgml parportbook.sgml kernel-hacking.sgml \
-	   kernel-locking.sgml via-audio.sgml mousedrivers.sgml sis900.sgml
+	   kernel-locking.sgml via-audio.sgml mousedrivers.sgml sis900.sgml \
+	   deviceiobook.sgml
 
 PS	:=	$(patsubst %.sgml, %.ps, $(BOOKS))
 PDF	:=	$(patsubst %.sgml, %.pdf, $(BOOKS))
@@ -9,12 +10,12 @@
 EPS-parportbook := $(patsubst %.fig, %.eps, $(IMG-parportbook))
 JPG-parportbook := $(patsubst %.fig, %.jpeg, $(IMG-parportbook))
 
+books:	$(BOOKS)
+
 $(BOOKS): $(TOPDIR)/scripts/docproc
 
 .PHONY:	books ps pdf html clean mrproper
 
-books:	$(BOOKS)
-
 ps:	$(PS)
 
 pdf:	$(PDF)
@@ -55,6 +56,9 @@
 	$(TOPDIR)/scripts/docgen $(TOPDIR)/drivers/net/sis900.c \
 		<sis900.tmpl >sis900.sgml
 
+deviceiobook.sgml: deviceiobook.tmpl
+	$(TOPDIR)/scripts/docgen <deviceiobook.tmpl >deviceiobook.sgml
+
 mcabook.sgml: mcabook.tmpl $(TOPDIR)/arch/i386/kernel/mca.c
 	$(TOPDIR)/scripts/docgen $(TOPDIR)/arch/i386/kernel/mca.c \
 		<mcabook.tmpl >mcabook.sgml
@@ -64,6 +68,7 @@
 		<videobook.tmpl >videobook.sgml
 
 APISOURCES :=	$(TOPDIR)/drivers/media/video/videodev.c \
+		$(TOPDIR)/arch/i386/kernel/irq.c \
 		$(TOPDIR)/arch/i386/kernel/mca.c \
 		$(TOPDIR)/arch/i386/kernel/mtrr.c \
 		$(TOPDIR)/drivers/char/misc.c \
@@ -77,11 +82,24 @@
 		$(TOPDIR)/drivers/net/wan/syncppp.c \
 		$(TOPDIR)/drivers/net/wan/z85230.c \
 		$(TOPDIR)/drivers/usb/usb.c \
-		$(TOPDIR)/fs/locks.c \
+		$(TOPDIR)/drivers/video/fbmem.c \
+		$(TOPDIR)/drivers/video/fbcmap.c \
+		$(TOPDIR)/drivers/video/fbcon.c \
+		$(TOPDIR)/drivers/video/fbgen.c \
+		$(TOPDIR)/drivers/video/fonts.c \
+		$(TOPDIR)/drivers/video/macmodes.c \
+		$(TOPDIR)/drivers/video/modedb.c \
 		$(TOPDIR)/fs/devfs/base.c \
+		$(TOPDIR)/fs/locks.c \
+		$(TOPDIR)/include/asm-i386/bitops.h \
 		$(TOPDIR)/kernel/pm.c \
 		$(TOPDIR)/kernel/ksyms.c \
 		$(TOPDIR)/kernel/kmod.c \
+		$(TOPDIR)/kernel/printk.c \
+		$(TOPDIR)/kernel/sched.c \
+		$(TOPDIR)/kernel/sysctl.c \
+		$(TOPDIR)/lib/string.c \
+		$(TOPDIR)/lib/vsprintf.c \
 		$(TOPDIR)/net/netsyms.c
  
 kernel-api.sgml: kernel-api.tmpl $(APISOURCES)
diff -u --recursive --new-file v2.4.3/linux/Documentation/DocBook/deviceiobook.tmpl linux/Documentation/DocBook/deviceiobook.tmpl
--- v2.4.3/linux/Documentation/DocBook/deviceiobook.tmpl	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/DocBook/deviceiobook.tmpl	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,232 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[]>
+
+<book id="DoingIO">
+ <bookinfo>
+  <title>Bus-Independent Device Accesses</title>
+  
+  <authorgroup>
+   <author>
+    <firstname>Matthew</firstname>
+    <surname>Wilcox</surname>
+    <affiliation>
+     <address>
+      <email>matthew@wil.cx</email>
+     </address>
+    </affiliation>
+   </author>
+  </authorgroup>
+
+  <authorgroup>
+   <author>
+    <firstname>Alan</firstname>
+    <surname>Cox</surname>
+    <affiliation>
+     <address>
+      <email>alan@redhat.com</email>
+     </address>
+    </affiliation>
+   </author>
+  </authorgroup>
+
+  <copyright>
+   <year>2001</year>
+   <holder>Matthew Wilcox</holder>
+  </copyright>
+
+  <legalnotice>
+   <para>
+     This documentation is free software; you can redistribute
+     it and/or modify it under the terms of the GNU General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later
+     version.
+   </para>
+      
+   <para>
+     This program is distributed in the hope that it will be
+     useful, but WITHOUT ANY WARRANTY; without even the implied
+     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+     See the GNU General Public License for more details.
+   </para>
+      
+   <para>
+     You should have received a copy of the GNU General Public
+     License along with this program; if not, write to the Free
+     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+     MA 02111-1307 USA
+   </para>
+      
+   <para>
+     For more details see the file COPYING in the source
+     distribution of Linux.
+   </para>
+  </legalnotice>
+ </bookinfo>
+
+<toc></toc>
+
+  <chapter id="intro">
+      <title>Introduction</title>
+  <para>
+	Linux provides an API which abstracts performing IO across all busses
+	and devices, allowing device drivers to be written independently of
+	bus type.
+  </para>
+  </chapter>
+
+  <chapter id="bugs">
+     <title>Known Bugs And Assumptions</title>
+  <para>
+	None.	
+  </para>
+  </chapter>
+
+  <chapter id="mmio">
+    <title>Memory Mapped IO</title>
+    <sect1>
+      <title>Getting Access to the Device</title>
+      <para>
+	The most widely supported form of IO is memory mapped IO.
+	That is, a part of the CPU's address space is interpreted
+	not as accesses to memory, but as accesses to a device.  Some
+	architectures define devices to be at a fixed address, but most
+	have some method of discovering devices.  The PCI bus walk is a
+	good example of such a scheme.	This document does not cover how
+	to receive such an address, but assumes you are starting with one.
+	Physical addresses are of type unsigned long. 
+      </para>
+
+      <para>
+	This address should not be used directly.  Instead, to get an
+	address suitable for passing to the accessor functions described
+	below, you should call <function>ioremap</function>.
+	An address suitable for accessing the device will be returned to you.
+      </para>
+
+      <para>
+	After you've finished using the device (say, in your module's
+	exit routine), call <function>iounmap</function> in order to return
+	the address space to the kernel.  Most architectures allocate new
+	address space each time you call <function>ioremap</function>, and
+	they can run out unless you call <function>iounmap</function>.
+      </para>
+    </sect1>
+
+    <sect1>
+      <title>Accessing the device</title>
+      <para>
+	The part of the interface most used by drivers is reading and
+	writing memory-mapped registers on the device.	Linux provides
+	interfaces to read and write 8-bit, 16-bit, 32-bit and 64-bit
+	quantities.  Due to a historical accident, these are named byte,
+	word, long and quad accesses.  Both read and write accesses are
+	supported; there is no prefetch support at this time.
+      </para>
+
+      <para>
+	The functions are named <function>readb</function>,
+	<function>readw</function>, <function>readl</function>,
+	<function>readq</function>, <function>writeb</function>,
+	<function>writew</function>, <function>writel</function> and
+	<function>writeq</function>.
+      </para>
+
+      <para>
+	Some devices (such as framebuffers) would like to use larger
+	transfers than 8 bytes at a time.  For these devices, the
+	<function>memcpy_toio</function>, <function>memcpy_fromio</function>
+	and <function>memset_io</function> functions are provided.
+	Do not use memset or memcpy on IO addresses; they
+	are not guaranteed to copy data in order.
+      </para>
+
+      <para>
+	The read and write functions are defined to be ordered. That is the
+	compiler is not permitted to reorder the I/O sequence. When the 
+	ordering can be compiler optimised, you can use <function>
+	__readb</function> and friends to indicate the relaxed ordering. Use 
+	this with care. The <function>rmb</function> provides a read memory 
+	barrier. The <function>wmb</function> provides a write memory barrier.
+      </para>
+
+      <para>
+	While the basic functions are defined to be synchronous with respect
+	to each other and ordered with respect to each other the busses the
+	devices sit on may themselves have asynchronocity. In paticular many
+	authors are burned by the fact that PCI bus writes are posted
+	asynchronously. A driver author must issue a read from the same
+	device to ensure that writes have occurred in the specific cases the
+	author cares. This kind of property cannot be hidden from driver
+	writers in the API.
+      </para>
+    </sect1>
+
+    <sect1>
+      <title>ISA legacy functions</title>
+      <para>
+	On older kernels (2.2 and earlier) the ISA bus could be read or
+	written with these functions and without ioremap being used. This is
+	no longer true in Linux 2.4. A set of equivalent functions exist for
+	easy legacy driver porting. The functions available are prefixed
+	with 'isa_' and are <function>isa_readb</function>,
+	<function>isa_writeb</function>, <function>isa_readw</function>, 
+	<function>isa_writew</function>, <function>isa_readl</function>,
+	<function>isa_writel</function), <function>isa_memcpy_fromio</function>
+	and <function>isa_memcpy_toio</function>
+      </para>
+      <para>
+	These functions should not be used in new drivers, and will
+	eventually be going away.
+      </para>
+    </sect1>
+
+  </chapter>
+
+  <chapter>
+    <title>Port Space Accesses</title>
+    <sect1>
+      <title>Port Space Explained</title>
+
+      <para>
+	Another form of IO commonly supported is Port Space.  This is a
+	range of addresses separate to the normal memory address space.
+	Access to these addresses is generally not as fast as accesses
+	to the memory mapped addresses, and it also has a potentially
+	smaller address space.
+      </para>
+
+      <para>
+	Unlike memory mapped IO, no preparation is required
+	to access port space.
+      </para>
+
+    </sect1>
+    <sect1>
+      <title>Accessing Port Space</title>
+      <para>
+	Accesses to this space are provided through a set of functions
+	which allow 8-bit, 16-bit and 32-bit accesses; also
+	known as byte, word and long.  These functions are
+	<function>inb</function>, <function>inw</function>,
+	<function>inl</function>, <function>outb</function>,
+	<function>outw</function> and <function>outl</function>.
+      </para>
+
+      <para>
+	Some variants are provided for these functions.  Some devices
+	require that accesses to their ports are slowed down.  This
+	functionality is provided by appending a <function>_p</function>
+	to the end of the function.  There are also equivalents to memcpy.
+	The <function>ins</function> and <function>outs</function>
+	functions copy bytes, words or longs to the given port.
+      </para>
+    </sect1>
+
+  </chapter>
+
+  <chapter id="pubfunctions">
+     <title>Public Functions Provided</title>
+!Einclude/asm-i386/io.h
+  </chapter>
+
+</book>
diff -u --recursive --new-file v2.4.3/linux/Documentation/DocBook/kernel-api.tmpl linux/Documentation/DocBook/kernel-api.tmpl
--- v2.4.3/linux/Documentation/DocBook/kernel-api.tmpl	Fri Mar  2 18:43:10 2001
+++ linux/Documentation/DocBook/kernel-api.tmpl	Fri Apr  6 10:42:55 2001
@@ -36,7 +36,7 @@
 <toc></toc>
 
   <chapter id="Basics">
-     <title>Driver Basic</title>
+     <title>Driver Basics</title>
      <sect1><title>Driver Entry and Exit points</title>
 !Iinclude/linux/init.h
      </sect1>
@@ -44,6 +44,10 @@
      <sect1><title>Atomics</title>
 !Iinclude/asm-i386/atomic.h
      </sect1>
+
+     <sect1><title>Delaying, scheduling, and timer routines</title>
+!Ekernel/sched.c
+     </sect1>
   </chapter>
 
   <chapter id="adt">
@@ -53,6 +57,29 @@
      </sect1>
   </chapter>
 
+  <chapter id="libc">
+     <title>Basic C Library Functions</title>
+
+     <para>
+       When writing drivers, you cannot in general use routines which are
+       from the C Library.  Some of the functions have been found generally
+       useful and they are listed below.  The behaviour of these functions
+       may vary slightly from those defined by ANSI, and these deviations
+       are noted in the text.
+     </para>
+
+     <sect1><title>String Conversions</title>
+!Ilib/vsprintf.c
+!Elib/vsprintf.c
+     </sect1>
+     <sect1><title>String Manipulation</title>
+!Ilib/string.c
+     </sect1>
+     <sect1><title>Bit Operations</title>
+!Iinclude/asm-i386/bitops.h
+     </sect1>
+  </chapter>
+
   <chapter id="mm">
      <title>Memory Management in Linux</title>
      <sect1><title>The Slab Cache</title>
@@ -60,6 +87,14 @@
       </sect1>
   </chapter>
 
+  <chapter id="proc">
+     <title>The proc filesystem</title>
+ 
+     <sect1><title>sysctl interface</title>
+!Ekernel/sysctl.c
+     </sect1>
+  </chapter>
+
   <chapter id="vfs">
      <title>The Linux VFS</title>
      <sect1><title>The Directory Cache</title>
@@ -177,5 +212,68 @@
 !Edrivers/net/wan/z85230.c
   </chapter>
 
+  <chapter id="fbdev">
+     <title>Frame Buffer Library</title>
+
+     <para>
+       The frame buffer drivers depend heavily on four data structures.  
+       These structures are declared in include/linux/fb.h.  They are 
+       fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs. 
+       The last three can be made available to and from userland. 
+     </para>
+
+     <para>
+       fb_info defines the current state of a particular video card. 
+       Inside fb_info, there exists a fb_ops structure which is a 
+       collection of needed functions to make fbdev and fbcon work.
+       fb_info is only visible to the kernel.
+     </para>
+
+     <para>
+       fb_var_screeninfo is used to describe the features of a video card 
+       that are user defined.  With fb_var_screeninfo, things such as
+       depth and the resolution may be defined.
+     </para>
+
+     <para>
+       The next structure is fb_fix_screeninfo. This defines the 
+       properties of a card that are created when a mode is set and can't 
+       be changed otherwise.  A good example of this is the start of the 
+       frame buffer memory.  This "locks" the address of the frame buffer
+       memory, so that it cannot be changed or moved.
+     </para>
+
+     <para>
+       The last structure is fb_monospecs. In the old API, there was 
+       little importance for fb_monospecs. This allowed for forbidden things 
+       such as setting a mode of 800x600 on a fix frequency monitor. With 
+       the new API, fb_monospecs prevents such things, and if used 
+       correctly, can prevent a monitor from being cooked.  fb_monospecs
+       will not be useful until kernels 2.5.x.
+     </para>
+
+     <sect1><title>Frame Buffer Memory</title>
+!Edrivers/video/fbmem.c
+     </sect1>
+     <sect1><title>Frame Buffer Console</title>
+!Edrivers/video/fbcon.c
+     </sect1>
+     <sect1><title>Frame Buffer Colormap</title>
+!Edrivers/video/fbcmap.c
+     </sect1>
+     <sect1><title>Frame Buffer Generic Functions</title>
+!Idrivers/video/fbgen.c
+     </sect1>
+     <sect1><title>Frame Buffer Video Mode Database</title>
+!Idrivers/video/modedb.c
+!Edrivers/video/modedb.c
+     </sect1>
+     <sect1><title>Frame Buffer Macintosh Video Mode Database</title>
+!Idrivers/video/macmodes.c
+     </sect1>
+     <sect1><title>Frame Buffer Fonts</title>
+!Idrivers/video/fonts.c
+     </sect1>
+  </chapter>
 
 </book>
diff -u --recursive --new-file v2.4.3/linux/Documentation/DocBook/kernel-hacking.tmpl linux/Documentation/DocBook/kernel-hacking.tmpl
--- v2.4.3/linux/Documentation/DocBook/kernel-hacking.tmpl	Thu Feb  8 16:32:44 2001
+++ linux/Documentation/DocBook/kernel-hacking.tmpl	Fri Apr  6 10:42:55 2001
@@ -11,7 +11,7 @@
     <surname>Russell</surname>
     <affiliation>
      <address>
-      <email>rusty@linuxcare.com</email>
+      <email>rusty@rustcorp.com.au</email>
      </address>
     </affiliation>
    </author>
@@ -336,6 +336,11 @@
   </para>
 
   <para>
+   If all your routine does is read or write some parameter, consider
+   implementing a <function>sysctl</function> interface instead.
+  </para>
+
+  <para>
    Inside the ioctl you're in user context to a process.  When a
    error occurs you return a negated errno (see
    <filename class=headerfile>include/linux/errno.h</filename>),
@@ -407,7 +412,7 @@
   <para>
    Note that some functions may sleep implicitly: common ones are
    the user space access functions (*_user) and memory allocation
-   functions without GFP_ATOMIC.
+   functions without <symbol>GFP_ATOMIC</symbol>.
   </para>
 
   <para>
@@ -608,7 +613,8 @@
     for some weird device, you have a problem: it is poorly supported
     in Linux because after some time memory fragmentation in a running
     kernel makes it hard.  The best way is to allocate the block early
-    in the boot process.
+    in the boot process via the <function>alloc_bootmem()</function>
+    routine.
    </para>
 
    <para>
@@ -631,6 +637,20 @@
    </para>
   </sect1>
 
+  <sect1 id="routines-udelay">
+   <title><function>udelay()</function>/<function>mdelay()</function>
+     <filename class=headerfile>include/asm/delay.h</filename> 
+     <filename class=headerfile>include/linux/delay.h</filename> 
+   </title>
+
+   <para>
+    The <function>udelay()</function> function can be used for small pauses.
+    Do not use large values with <function>udelay()</function> as you risk
+    overflow - the helper function <function>mdelay()</function> is useful
+    here, or even consider <function>schedule_timeout()</function>.
+   </para> 
+  </sect1>
+ 
   <sect1 id="routines-local-irqs">
    <title><function>local_irq_save()</function>/<function>local_irq_restore()</function>
     <filename class=headerfile>include/asm/system.h</filename>
@@ -687,8 +707,14 @@
     modules this directive is currently ignored).  <type>__exit</type>
     is used to declare a function which is only required on exit: the
     function will be dropped if this file is not compiled as a module.
-    See the header file for use.
+    See the header file for use. Note that it makes no sense for a function
+    marked with <type>__init</type> to be exported to modules with 
+    <function>EXPORT_SYMBOL()</function> - this will break.
    </para>
+   <para>
+   Static data structures marked as <type>__initdata</type> must be initialised
+   (as opposed to ordinary static data which is zeroed BSS).
+   </para> 
 
   </sect1>
 
@@ -775,6 +801,21 @@
         return 0;
 }
    </programlisting>
+
+   <para>
+   You can often avoid having to deal with these problems by using the 
+   <structfield>owner</structfield> field of the 
+   <structname>file_operations</structname> structure. Set this field
+   as the macro <symbol>THIS_MODULE</symbol>.
+   </para>
+
+   <para>
+   For more complicated module unload locking requirements, you can set the
+   <structfield>can_unload</structfield> function pointer to your own routine,
+   which should return <returnvalue>0</returnvalue> if the module is
+   unloadable, or <returnvalue>-EBUSY</returnvalue> otherwise.
+   </para> 
+  
   </sect1>
  </chapter>
 
@@ -822,6 +863,17 @@
     <returnvalue>-ERESTARTSYS</returnvalue> if a signal is received.
     The <function>wait_event()</function> version ignores signals.
    </para>
+   <para>
+   Do not use the <function>sleep_on()</function> function family -
+   it is very easy to accidentally introduce races; almost certainly
+   one of the <function>wait_event()</function> family will do, or a
+   loop around <function>schedule_timeout()</function>. If you choose
+   to loop around <function>schedule_timeout()</function> remember
+   you must set the task state (with 
+   <function>set_current_state()</function>) on each iteration to avoid
+   busy-looping.
+   </para>
+ 
   </sect1>
 
   <sect1 id="queue-waking">
@@ -1212,6 +1264,13 @@
      <filename>MAINTAINERS</filename> means you want to be consulted
      when changes are made to a subsystem, and hear about bugs; it
      implies a more-than-passing commitment to some part of the code.
+    </para>
+   </listitem>
+   
+   <listitem>
+    <para>
+     Finally, don't forget to read <filename>Documentation/SubmittingPatches</filename>
+     and possibly <filename>Documentation/SubmittingDrivers</filename>.
     </para>
    </listitem>
   </itemizedlist>
diff -u --recursive --new-file v2.4.3/linux/Documentation/DocBook/kernel-locking.tmpl linux/Documentation/DocBook/kernel-locking.tmpl
--- v2.4.3/linux/Documentation/DocBook/kernel-locking.tmpl	Fri Feb 16 15:53:08 2001
+++ linux/Documentation/DocBook/kernel-locking.tmpl	Fri Apr  6 10:42:55 2001
@@ -11,7 +11,7 @@
     <surname>Russell</surname>
     <affiliation>
      <address>
-      <email>rusty@linuxcare.com</email>
+      <email>rusty@rustcorp.com.au</email>
      </address>
     </affiliation>
    </author>
diff -u --recursive --new-file v2.4.3/linux/Documentation/SubmittingDrivers linux/Documentation/SubmittingDrivers
--- v2.4.3/linux/Documentation/SubmittingDrivers	Thu Feb  8 16:32:44 2001
+++ linux/Documentation/SubmittingDrivers	Fri Apr  6 10:42:55 2001
@@ -111,7 +111,7 @@
 
 Kernel traffic:
 	Weekly summary of kernel list activity (much easier to read)
-	[http://kt.linuxcare.com/kernel-traffic]
+	[http://kt.zork.net/kernel-traffic]
 
 Linux USB project:
 	http://sourceforge.net/projects/linux-usb/
diff -u --recursive --new-file v2.4.3/linux/Documentation/cris/README linux/Documentation/cris/README
--- v2.4.3/linux/Documentation/cris/README	Thu Feb  8 16:32:44 2001
+++ linux/Documentation/cris/README	Fri Apr  6 10:42:55 2001
@@ -1,20 +1,22 @@
 Linux 2.4 on the CRIS architecture
 ==================================
-$Id: README,v 1.5 2001/01/10 17:20:55 bjornw Exp $
+$Id: README,v 1.6 2001/02/21 15:27:25 bjornw Exp $
 
-This is a port of Linux 2.4 to Axis Communications ETRAX 100LX embedded network CPU. For
-more information about CRIS and ETRAX please see further below.
+This is a port of Linux 2.4 to Axis Communications ETRAX 100LX embedded 
+network CPU. For more information about CRIS and ETRAX please see further
+below.
 
-<... to come: instructions on how to grab the right gcc, compiling and booting ...>
+<to come: instructions on how to grab the right gcc, compiling and booting>
 
 
 What is CRIS ?
 --------------
 
-CRIS is an acronym for 'Code Reduced Instruction Set'. It is the CPU architecture in Axis
-Communication AB's range of embedded network CPU's, called ETRAX. The latest CPU is called
-ETRAX 100LX, where LX stands for 'Linux' because the chip was designed to be a good host for
-the Linux operating system.
+CRIS is an acronym for 'Code Reduced Instruction Set'. It is the CPU
+architecture in Axis Communication AB's range of embedded network CPU's,
+called ETRAX. The latest CPU is called ETRAX 100LX, where LX stands for
+'Linux' because the chip was designed to be a good host for the Linux
+operating system.
 
 The ETRAX 100LX chip
 --------------------
@@ -23,8 +25,8 @@
 
 http://www.axis.com/news/us/001101_etrax.htm
 
-The ETRAX 100LX is a 100 MIPS processor with 8kB cache, MMU, and a very broad range of 
-built-in interfaces, all with modern scatter/gather DMA.
+The ETRAX 100LX is a 100 MIPS processor with 8kB cache, MMU, and a very broad 
+range of  built-in interfaces, all with modern scatter/gather DMA.
 
 Memory interfaces:
 
@@ -44,40 +46,41 @@
 	* two parallel-ports
 	* two generic 8-bit ports
 	
-	(not all interfaces are available at the same time due to chip pin multiplexing)
+	(not all interfaces are available at the same time due to chip pin 
+         multiplexing)
 
-The previous version of the ETRAX, the ETRAX 100, sits in almost all of Axis shipping 
-thin-servers like the Axis 2100 web camera or the developer-board. It lacks an MMU so the
-Linux we run on that is a version of uClinux (Linux 2.0 without MM-support) ported to the CRIS
-architecture. The new Linux 2.4 port has full MM and needs a CPU with an MMU, so it will not
-run on the ETRAX 100. 
-
-A version of the Axis developer-board with ETRAX 100LX will be available as soon as the chip 
-is ramped up (please see http://developer.axis.com for further information on that).
+The previous version of the ETRAX, the ETRAX 100, sits in almost all of
+Axis shipping thin-servers like the Axis 2100 web camera or the ETRAX 100
+developer-board. It lacks an MMU so the Linux we run on that is a version
+of uClinux (Linux 2.0 without MM-support) ported to the CRIS architecture.
+The new Linux 2.4 port has full MM and needs a CPU with an MMU, so it will
+not run on the ETRAX 100.
 
+A version of the Axis developer-board with ETRAX 100LX (running Linux
+2.4) is now available. For more information please see developer.axis.com.
 
 
 Bootlog
 -------
 
-Just as an example, this is the debug-output from a boot of Linux 2.4 on an Axis
-developer-board with ETRAX 100LX. The displayed BogoMIPS value is 5 times too small :)
+Just as an example, this is the debug-output from a boot of Linux 2.4 on
+a board with ETRAX 100LX. The displayed BogoMIPS value is 5 times too small :)
 At the end you see some user-mode programs booting like telnet and ftp daemons.
 
-Linux version 2.4.0-test11 (bjornw@godzilla.axis.se) (gcc version 2.96 20000427 (experimental)) #358 Wed Nov 22 19:29:15 CET 2000
-ROM fs in RAM, size 368640 bytes
+Linux version 2.4.1 (bjornw@godzilla.axis.se) (gcc version 2.96 20000427 (experimental)) #207 Wed Feb 21 15:48:15 CET 2001
+ROM fs in RAM, size 1376256 bytes
 Setting up paging and the MMU.
-On node 0 totalpages: 1024
-zone(0): 1024 pages.
+On node 0 totalpages: 2048
+zone(0): 2048 pages.
 zone(1): 0 pages.
 zone(2): 0 pages.
-Linux/CRIS port (c) 2000 Axis Communications AB
+Linux/CRIS port on ETRAX 100LX (c) 2001 Axis Communications AB
 Kernel command line: 
-Calibrating delay loop... 19.92 BogoMIPS
-Memory: 6864k/8192k available (531k kernel code, 1328k reserved, 85k data, 24k init)
+Calibrating delay loop... 19.91 BogoMIPS
+Memory: 13872k/16384k available (587k kernel code, 2512k reserved, 44k data, 24k init)
 kmem_create: Forcing size word alignment - vm_area_struct
 kmem_create: Forcing size word alignment - filp
-Dentry-cache hash table entries: 1024 (order: 0, 8192 bytes)
+Dentry-cache hash table entries: 2048 (order: 1, 16384 bytes)
 Buffer-cache hash table entries: 2048 (order: 0, 8192 bytes)
 Page-cache hash table entries: 2048 (order: 0, 8192 bytes)
 kmem_create: Forcing size word alignment - kiobuf
@@ -87,41 +90,52 @@
 POSIX conformance testing by UNIFIX
 Linux NET4.0 for Linux 2.4
 Based upon Swansea University Computer Society NET3.039
-kmem_create: Forcing size word alignment - skbuff_head_cache
 Starting kswapd v1.8
 kmem_create: Forcing size word alignment - file lock cache
 kmem_create: Forcing size word alignment - blkdev_requests
+block: queued sectors max/low 9109kB/3036kB, 64 slots per queue
 ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000 Axis Communications AB
 eth0 initialized
 eth0: changed MAC to 00:40:8C:CD:00:00
-ETRAX 100LX serial-driver $Revision: 1.5 $, (c) 2000 Axis Communications AB
+ETRAX 100LX serial-driver $Revision: 1.6 $, (c) 2000 Axis Communications AB
 ttyS0 at 0xb0000060 is a builtin UART with DMA
 ttyS1 at 0xb0000068 is a builtin UART with DMA
 ttyS2 at 0xb0000070 is a builtin UART with DMA
 ttyS3 at 0xb0000078 is a builtin UART with DMA
+Axis flash mapping: 200000 at 50000000
+Axis flash: Found 1 x16 CFI device at 0x0 in 16 bit mode
+ Amd/Fujitsu Extended Query Table v1.0 at 0x0040
+Axis flash: JEDEC Device ID is 0xC4. Assuming broken CFI table.
+Axis flash: Swapping erase regions for broken CFI table.
+number of CFI chips: 1
+ Using default partition table
+I2C driver v2.2, (c) 1999-2001 Axis Communications AB
+ETRAX 100LX GPIO driver v2.1, (c) 2001 Axis Communications AB
 NET4: Linux TCP/IP 1.0 for NET4.0
 IP Protocols: ICMP, UDP, TCP
 kmem_create: Forcing size word alignment - ip_dst_cache
 IP: routing cache hash table of 1024 buckets, 8Kbytes
-TCP: Hash tables configured (established 1024 bind 1024)
+TCP: Hash tables configured (established 2048 bind 2048)
 NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
 VFS: Mounted root (cramfs filesystem) readonly.
 Init starts up...
+Mounted none on /proc ok.
 Setting up eth0 with ip 10.13.9.116 and mac 00:40:8c:18:04:60
 eth0: changed MAC to 00:40:8C:18:04:60
 Setting up lo with ip 127.0.0.1
 Default gateway is 10.13.9.1
 Hostname is bbox1
 Telnetd starting, using port 23.
-  using /bin/sh as shell.
-sftpd[14]: sftpd $Revision: 1.5 $ starting up
+  using /bin/sash as shell.
+sftpd[15]: sftpd $Revision: 1.6 $ starting up
+
 
 
 And here is how some /proc entries look:
 
 17# cd /proc
 17# cat cpuinfo
-cpu             : ETRAX
+cpu             : CRIS
 cpu revision    : 10
 cpu model       : ETRAX 100LX
 cache size      : 8 kB
@@ -133,6 +147,7 @@
 ata             : yes
 usb             : yes
 bogomips        : 99.84
+
 17# cat meminfo
         total:    used:    free:  shared: buffers:  cached:
 Mem:   7028736   925696  6103040   114688        0   229376
diff -u --recursive --new-file v2.4.3/linux/Documentation/dnotify.txt linux/Documentation/dnotify.txt
--- v2.4.3/linux/Documentation/dnotify.txt	Fri Mar  2 18:38:37 2001
+++ linux/Documentation/dnotify.txt	Fri Apr  6 10:42:48 2001
@@ -1,7 +1,7 @@
 		Linux Directory Notification
 		============================
 
-	   Stephen Rothwell <sfr@linuxcare.com.au>
+	   Stephen Rothwell <sfr@canb.auug.org.au>
 
 The intention of directory notification is to allow user applications
 to be notified when a directory, or any of the files in it, are changed.
diff -u --recursive --new-file v2.4.3/linux/Documentation/filesystems/devfs/ChangeLog linux/Documentation/filesystems/devfs/ChangeLog
--- v2.4.3/linux/Documentation/filesystems/devfs/ChangeLog	Wed Jul  5 21:36:49 2000
+++ linux/Documentation/filesystems/devfs/ChangeLog	Fri Apr  6 10:42:48 2001
@@ -495,7 +495,7 @@
 
 - Replaced dummy .epoch inode with .devfsd character device
 
-- Modified rc.devfs to take acount of above change
+- Modified rc.devfs to take account of above change
 
 - Removed spurious driver warning messages when CONFIG_DEVFS_FS=n
 
diff -u --recursive --new-file v2.4.3/linux/Documentation/filesystems/proc.txt linux/Documentation/filesystems/proc.txt
--- v2.4.3/linux/Documentation/filesystems/proc.txt	Mon Nov 27 17:47:38 2000
+++ linux/Documentation/filesystems/proc.txt	Fri Apr  6 10:42:48 2001
@@ -49,7 +49,7 @@
 the SuSE  Linux distribution. As  there is  no complete documentation  for the
 /proc file system and we've used  many freely available sources to write these
 chapters, it  seems only fair  to give the work  back to the  Linux community.
-This work is  based on the 2.2.*  kernel version and the  upcomming 2.4.*. I'm
+This work is  based on the 2.2.*  kernel version and the  upcoming 2.4.*. I'm
 afraid it's still far from complete, but we  hope it will be useful. As far as
 we know, it is the first 'all-in-one' document about the /proc file system. It
 is focused  on the Intel  x86 hardware,  so if you  are looking for  PPC, ARM,
@@ -281,7 +281,7 @@
 
 ERR is incremented in the case of errors in the IO-APIC bus (the bus that
 connects the CPUs in a SMP system. This means that an error has been detected,
-the IO-APIC automatically retry the transmision, so it should not be a big
+the IO-APIC automatically retry the transmission, so it should not be a big
 problem, but you should read the SMP-FAQ.
 
 In this context it could be interesting to note the new irq directory in 2.4.
diff -u --recursive --new-file v2.4.3/linux/Documentation/joystick-api.txt linux/Documentation/joystick-api.txt
--- v2.4.3/linux/Documentation/joystick-api.txt	Fri Jul 28 12:50:51 2000
+++ linux/Documentation/joystick-api.txt	Fri Apr  6 10:42:48 2001
@@ -114,7 +114,7 @@
 ~~~~~~~~~~~~~~~~~
 
 The time an event was generated is stored in ``js_event.time''. It's a time
-in miliseconds since ... well, since sometime in the past.  This eases the
+in milliseconds since ... well, since sometime in the past.  This eases the
 task of detecting double clicks, figuring out if movement of axis and button
 presses happened at the same time, and similar.
 
diff -u --recursive --new-file v2.4.3/linux/Documentation/kernel-docs.txt linux/Documentation/kernel-docs.txt
--- v2.4.3/linux/Documentation/kernel-docs.txt	Wed Aug 23 09:33:09 2000
+++ linux/Documentation/kernel-docs.txt	Fri Apr  6 10:42:48 2001
@@ -608,7 +608,7 @@
        produced during the week. Published every Thursday.
        
      * Name: "Kernel Traffic"
-       URL: http://kt.linuxcare.com
+       URL: http://kt.zork.net
        Keywords: linux-kernel mailing list, weekly kernel news.
        Description: Weekly newsletter covering the most relevant
        discussions of the linux-kernel mailing list.
diff -u --recursive --new-file v2.4.3/linux/Documentation/networking/comx.txt linux/Documentation/networking/comx.txt
--- v2.4.3/linux/Documentation/networking/comx.txt	Fri Jul 28 12:50:51 2000
+++ linux/Documentation/networking/comx.txt	Fri Apr  6 10:42:48 2001
@@ -162,7 +162,7 @@
 some restricions in order to be able to use non-async lines too.
 If configured, this driver can use Van Jacobson TCP header compression (you'll
 need the slhc.o module for this).
-Additionaly to use this protocol, enable async ppp in your kernel config, and
+Additionally to use this protocol, enable async ppp in your kernel config, and
 create the comx device special files in /dev. They're character special files
 with major 88, and their names must be the same as their network interface
 counterparts (i.e /dev/comx0 with minor 0 corresponds interface comx0 and so
diff -u --recursive --new-file v2.4.3/linux/Documentation/parport.txt linux/Documentation/parport.txt
--- v2.4.3/linux/Documentation/parport.txt	Mon Mar 26 15:41:19 2001
+++ linux/Documentation/parport.txt	Fri Apr  6 10:42:51 2001
@@ -174,7 +174,7 @@
 		peripherals.  This is a port-wide setting, i.e. it
 		applies to all devices on a particular port.
 
-timeslice	The number of miliseconds that a device driver is
+timeslice	The number of milliseconds that a device driver is
 		allowed to keep a port claimed for.  This is advisory,
 		and driver can ignore it if it must.
 
diff -u --recursive --new-file v2.4.3/linux/Documentation/pm.txt linux/Documentation/pm.txt
--- v2.4.3/linux/Documentation/pm.txt	Thu Oct 26 14:22:24 2000
+++ linux/Documentation/pm.txt	Fri Apr  6 10:42:55 2001
@@ -33,7 +33,7 @@
 Go ahead and start both.  If ACPI or APM is not available on your
 system the associated daemon will exit gracefully.
 
-  apmd:   http://linuxcare.com.au/apm/
+  apmd:   http://worldvisions.ca/~apenwarr/apmd/
   acpid:  http://phobos.fs.tum.de/acpi/
 
 Driver Interface
diff -u --recursive --new-file v2.4.3/linux/MAINTAINERS linux/MAINTAINERS
--- v2.4.3/linux/MAINTAINERS	Sun Mar 25 18:14:20 2001
+++ linux/MAINTAINERS	Fri Apr  6 15:51:50 2001
@@ -106,6 +106,13 @@
 L:	linux-net@vger.kernel.org
 S:	Maintained
 
+ACI MIXER DRIVER
+P:	Robert Siemer
+M:	Robert.Siemer@gmx.de
+L:	linux-sound@vger.kernel.org
+W:	http://www.uni-karlsruhe.de/~Robert.Siemer/Private/
+S:	Maintained
+
 ACPI
 P:	Andy Grover
 M:	andrew.grover@intel.com
@@ -141,9 +148,9 @@
 
 APM DRIVER
 P:	Stephen Rothwell
-M:	apm@linuxcare.com.au
+M:	sfr@canb.auug.org.au
 L:	linux-laptop@vger.kernel.org
-W:	http://linuxcare.com.au/apm/
+W:	http://www.canb.auug.org.au/~sfr/
 S:	Supported
 
 APPLETALK NETWORK LAYER
@@ -293,6 +300,13 @@
 M:	jam@acm.org
 S:	Maintained
 
+CRIS PORT
+P:	Bjorn Wesen
+M:	bjornw@axis.com
+L:	dev-etrax@axis.com
+W:	http://developer.axis.com
+S:	Maintained
+
 CYBERPRO FB DRIVER
 P:	Russell King
 M:	linux@arm.linux.org.uk
@@ -368,7 +382,7 @@
 
 DIRECTORY NOTIFICATION
 P:	Stephen Rothwell
-M:	sfr@linuxcare.com.au
+M:	sfr@canb.auug.org.au
 L:	linux-kernel@vger.kernel.org
 S:	Supported
 
@@ -398,6 +412,12 @@
 L:	dri-devel@lists.sourceforge.net
 S:	Supported
 
+DSCC4 DRIVER
+P:	François Romieu
+M:	romieu@cogenit.fr
+M:	romieu@ensta.fr
+S:	Maintained
+
 EATA-DMA SCSI DRIVER
 P:	Michael Neuffer
 M:	mike@i-Connect.Net
@@ -490,6 +510,12 @@
 W:	http://www.icp-vortex.com/
 S:	Supported
 
+GENERIC HDLC DRIVER, N2 AND C101 DRIVERS
+P:	Krzysztof Halasa
+M:	khc@pm.waw.pl
+W:	http://hq.pm.waw.pl/hdlc/
+S:	Maintained
+
 HAYES ESP SERIAL DRIVER
 P:	Andrew J. Robinson
 M:	arobinso@nyx.net
@@ -535,7 +561,7 @@
 
 HIPPI
 P:	Jes Sorensen
-M:	Jes.Sorensen@cern.ch
+M:	jes@linuxcare.com
 L:	linux-hippi@sunsite.auc.dk
 S:	Maintained
 
@@ -600,7 +626,14 @@
 W:	http://www.kernel.dk
 S:	Maintained
 
-IDE/ATAPI TAPE/FLOPPY DRIVERS
+IDE/ATAPI FLOPPY DRIVERS
+P:	Paul Bristow
+M:	Paul Bristow <paul@paulbristow.net>
+W:	http://paulbristow.net/linux/idefloppy.html
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
+IDE/ATAPI TAPE DRIVERS
 P:	Gadi Oxman
 M:	Gadi Oxman <gadio@netvision.net.il>
 L:	linux-kernel@vger.kernel.org
@@ -750,14 +783,14 @@
 
 LINUX FOR POWER MACINTOSH
 P:	Paul Mackerras
-M:	paulus@linuxcare.com
+M:	paulus@samba.org
 W:	http://www.linuxppc.org/
 L:	linuxppc-dev@lists.linuxppc.org
 S:	Maintained
 
 M68K
 P:	Jes Sorensen
-M:	Jes.Sorensen@cern.ch
+M:	jes@linuxcare.com
 W:	http://www.clark.net/pub/lawrencc/linux/index.html
 L:	linux-m68k@lists.linux-m68k.org
 S:	Maintained
@@ -775,7 +808,7 @@
 W:	http://www.tazenda.demon.co.uk/phil/linux-hp
 S:	Maintained
 
-MAESTRO PCI SOUND DRIVER
+MAESTRO PCI SOUND DRIVERS
 P:	Zach Brown
 M:	zab@zabbo.net
 S:	Odd Fixes
@@ -787,6 +820,12 @@
 L:	mtd@infradead.org
 S:	Maintained
 
+MICROTEK X6 SCANNER
+P:      Oliver Neukum
+M:      drivers@neukum.org
+W:      http://fachschaft.cup.uni-muenchen.de/~neukum/scanner.html
+S:      Maintained
+
 MIPS
 P:	Ralf Baechle
 M:	ralf@gnu.ai.mit.edu
@@ -837,10 +876,14 @@
 
 NETFILTER
 P:	Rusty Russell
-M:	rusty@linuxcare.com
+M:	rusty@rustcorp.com.au
 P:	Marc Boucher
 M:	marc@mbsi.ca
-W:	http://www.samba.org/netfilter/
+P:	James Morris
+M:	jamesm@intercode.com.au
+P:	Harald Welte
+M:	laforge@gnumonks.org
+W:	http://netfilter.samba.org
 W:	http://netfilter.kernelnotes.org
 W:	http://netfilter.filewatcher.org
 L:	netfilter@lists.samba.org
@@ -904,8 +947,9 @@
 NTFS FILESYSTEM
 P:	Anton Altaparmakov
 M:	aia21@cus.cam.ac.uk
+L:	linux-ntfs-dev@lists.sourceforge.net
 L:	linux-kernel@vger.kernel.org
-S:	Odd Fixes
+S:	Maintained
 
 NVIDIA (RIVA) FRAMEBUFFER DRIVER
 P:	Ani Joshi
@@ -997,7 +1041,7 @@
 
 PPP PROTOCOL DRIVERS AND COMPRESSORS
 P:	Paul Mackerras
-M:	paulus@linuxcare.com
+M:	paulus@samba.org
 L:	linux-ppp@vger.kernel.org
 S:	Maintained
 
@@ -1037,6 +1081,13 @@
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
+REISERFS FILE SYSTEM
+P:      Hans Reiser
+M:      reiserfs-dev@namesys.com
+L:      reiserfs-list@namesys.com
+W:      http://www.namesys.com
+S:      Supported
+
 ROSE NETWORK LAYER
 P:	Jean-Paul Roubelat
 M:	jpr@f6fbb.org
@@ -1056,6 +1107,14 @@
 W:	www.rtlinux.org
 S:	Maintained
 
+S390
+P:	Martin Schwidefsky
+M:	schwidefsky@de.ibm.com
+M:	linux390@de.ibm.com
+L:	linux-390@vm.marist.edu
+W:	http://oss.software.ibm.com/developerworks/opensource/linux390
+S:	Supported
+
 SA1100 SUPPORT
 P:	Nicolas Pitre
 M:	nico@cam.org
@@ -1174,6 +1233,11 @@
 W:	http://www.stallion.com
 S:	Supported
 
+STARFIRE/DURALAN NETWORK DRIVER
+P:	Ion Badulescu
+M:	ionut@cs.columbia.edu
+S:	Maintained
+
 STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
 W:	http://mosquitonet.Stanford.EDU/strip.html
 S:	Unsupported ?
@@ -1357,11 +1421,11 @@
 
 USB SERIAL KEYSPAN DRIVER
 P:	Hugh Blemings
-M:	hugh@linuxcare.com
+M:	hugh@misc.nu
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
-W:	http://www.linuxcare.com.au/hugh/keyspan.html
+W:	http://misc.nu/hugh/keyspan/
 
 USB SERIAL DRIVER
 P:	Greg Kroah-Hartman
@@ -1457,6 +1521,12 @@
 X86 3-LEVEL PAGING (PAE) SUPPORT
 P:	Ingo Molnar
 M:	mingo@redhat.com
+S:	Maintained
+
+YAM DRIVER FOR AX.25
+P:	Jean-Paul Roubelat
+M:	jpr@f6fbb.org
+L:	linux-hams@vger.kernel.org
 S:	Maintained
 
 Z85230 SYNCHRONOUS DRIVER
diff -u --recursive --new-file v2.4.3/linux/Makefile linux/Makefile
--- v2.4.3/linux/Makefile	Thu Mar 29 20:13:15 2001
+++ linux/Makefile	Fri Apr  6 17:56:00 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 3
-EXTRAVERSION =
+SUBLEVEL = 4
+EXTRAVERSION =-pre1
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -u --recursive --new-file v2.4.3/linux/REPORTING-BUGS linux/REPORTING-BUGS
--- v2.4.3/linux/REPORTING-BUGS	Mon Aug 21 08:57:35 2000
+++ linux/REPORTING-BUGS	Fri Apr  6 10:42:48 2001
@@ -25,10 +25,9 @@
 overlook things, and easier for the developers to find the pieces of 
 information they're really interested in. Don't feel you have to follow it.
 
-   First run the ver_linux script included as scripts/ver_linux or
-at <URL:ftp://ftp.sai.msu.su/pub/Linux/ver_linux> It checks out
-the version of some important subsystems.  Run it with the command
-"sh scripts/ver_linux"
+      First run the ver_linux script included as scripts/ver_linux, which
+reports the version of some important subsystems.  Run this script with
+the command "sh scripts/ver_linux".
 
 Use that information to fill in all fields of the bug report form, and
 post it to the mailing list with a subject of "PROBLEM: <one line
diff -u --recursive --new-file v2.4.3/linux/arch/cris/Makefile linux/arch/cris/Makefile
--- v2.4.3/linux/arch/cris/Makefile	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/Makefile	Fri Apr  6 10:42:55 2001
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.11 2000/11/27 17:58:30 bjornw Exp $
+# $Id: Makefile,v 1.15 2001/02/16 17:50:04 larsv Exp $
 # cris/Makefile
 #
 # This file is included by the global makefile so that you can add your own
@@ -25,7 +25,7 @@
 # regenerating stuff (even for incremental linking of subsystems!) is
 # even more nauseating.
 LD = if [ ! -e $(LD_SCRIPT).tmp -o $(LD_SCRIPT) -nt $(LD_SCRIPT).tmp ]; then \
-          sed -e s/@ETRAX_DRAM_BASE@/0x$(ETRAX_DRAM_BASE)/ \
+          sed -e s/@ETRAX_DRAM_VIRTUAL_BASE@/0x$(ETRAX_DRAM_VIRTUAL_BASE)/ \
               -e s/@ETRAX_DRAM_SIZE_M@/$(ETRAX_DRAM_SIZE)/ \
               < $(LD_SCRIPT) > $(LD_SCRIPT).tmp; \
      else true; \
@@ -49,7 +49,7 @@
 
 HEAD := arch/cris/kernel/head.o
 
-SUBDIRS += arch/cris/kernel arch/cris/mm arch/cris/lib arch/cris/drivers
+SUBDIRS += arch/cris/kernel arch/cris/mm arch/cris/lib arch/cris/drivers arch/cris/boot/rescue
 CORE_FILES += arch/cris/kernel/kernel.o arch/cris/mm/mm.o arch/cris/drivers/drivers.o
 LIBGCC = $(shell $(CC) $(CFLAGS) -print-file-name=libgcc.a)
 LIBS := $(TOPDIR)/arch/cris/lib/lib.a $(LIBS) $(TOPDIR)/arch/cris/lib/lib.a $(LIBGCC)
@@ -76,10 +76,18 @@
 
 cramfs:
 ## cramfs      - Creates a cramfs image
-	mkcramfs -p 8192 root cramfs.img
+	mkcramfs -b 8192 root cramfs.img
 	cat vmlinux.bin cramfs.img >timage
 
-zImage: vmlinux
+clinux: vmlinux.bin decompress.bin rescue.bin
+
+decompress.bin: dummy
+	@make -C arch/cris/boot/compressed decompress.bin
+
+rescue.bin: dummy
+	@make -C arch/cris/boot/rescue rescue.bin
+
+zImage: vmlinux.bin
 ## zImage     - Compressed kernel (gzip)
 	@$(MAKEBOOT) zImage
 
diff -u --recursive --new-file v2.4.3/linux/arch/cris/boot/compressed/Makefile linux/arch/cris/boot/compressed/Makefile
--- v2.4.3/linux/arch/cris/boot/compressed/Makefile	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/boot/compressed/Makefile	Fri Apr  6 10:42:55 2001
@@ -16,11 +16,14 @@
 
 all: vmlinuz
 
-vmlinuz: piggy.img $(OBJECTS)
-	$(LD) -mcriself -T decompress.ld -o decompress.o $(OBJECTS)
+decompress.bin: $(OBJECTS)
+	$(LD) -T decompress.ld -o decompress.o $(OBJECTS)
 	$(OBJCOPY) -O binary --remove-section=.bss decompress.o decompress.bin
 # save it for mkprod in the topdir.
 	cp decompress.bin $(TOPDIR)
+
+
+vmlinuz: piggy.img decompress.bin
 	cat decompress.bin piggy.img $(TOPDIR)/cramfs.img > vmlinuz
 	rm -f piggy.img
 
diff -u --recursive --new-file v2.4.3/linux/arch/cris/boot/compressed/decompress.ld linux/arch/cris/boot/compressed/decompress.ld
--- v2.4.3/linux/arch/cris/boot/compressed/decompress.ld	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/boot/compressed/decompress.ld	Fri Apr  6 10:42:55 2001
@@ -1,3 +1,5 @@
+OUTPUT_FORMAT(elf32-us-cris)
+
 MEMORY 
 	{
 	dram : ORIGIN = 0x40700000,
diff -u --recursive --new-file v2.4.3/linux/arch/cris/boot/compressed/head.S linux/arch/cris/boot/compressed/head.S
--- v2.4.3/linux/arch/cris/boot/compressed/head.S	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/boot/compressed/head.S	Fri Apr  6 10:42:55 2001
@@ -8,7 +8,6 @@
  *
  */
 
-#include <linux/config.h>
 #define ASSEMBLER_MACROS_ONLY
 #include <asm/sv_addr_ag.h>
 
@@ -22,23 +21,24 @@
 	nop
 	di
 
-#ifndef CONFIG_SVINTO_SIM	
-
-	;; We need to setup the bus registers before we start using the DRAM
+	;; We need to initialze DRAM registers before we start using the DRAM
+#include "../../lib/dram_init.S"
+	
+dram_init_finished:
+	
+	;; Initiate the PA and PB ports
 
-	move.d   DEF_R_WAITSTATES, r0
-	move.d   r0, [R_WAITSTATES]
+	move.b   DEF_R_PORT_PA_DATA, r0
+	move.b   r0, [R_PORT_PA_DATA]
 
-	move.d   DEF_R_BUS_CONFIG, r0
-	move.d   r0, [R_BUS_CONFIG]
-  
-	move.d   DEF_R_DRAM_CONFIG, r0
-	move.d   r0, [R_DRAM_CONFIG]
+	move.b   DEF_R_PORT_PA_DIR, r0
+	move.b   r0, [R_PORT_PA_DIR]
 
-	move.d   DEF_R_DRAM_TIMING, r0
-	move.d   r0, [R_DRAM_TIMING]
+	move.b   DEF_R_PORT_PB_DATA, r0
+	move.b   r0, [R_PORT_PB_DATA]
 
-#endif
+	move.b   DEF_R_PORT_PB_DIR, r0
+	move.b   r0, [R_PORT_PB_DIR]
 
 	;; Setup the stack to a suitably high address.
 	;; We assume 8 MB is the minimum DRAM in an eLinux
@@ -83,7 +83,7 @@
 	;; Do the decompression and save compressed size in _inptr
 	
 	jsr	_decompress_kernel
-
+	
 	;; Put start address of cramfs in r9 so the kernel can use it
 	;; when mounting from flash
 
@@ -91,7 +91,6 @@
 	add.d	[_inptr], r9		; size of compressed kernel
 
 	;; Enter the decompressed kernel
-		
 	jump	0x40004000	; kernel is linked to this address
 	
 	.data
diff -u --recursive --new-file v2.4.3/linux/arch/cris/boot/compressed/misc.c linux/arch/cris/boot/compressed/misc.c
--- v2.4.3/linux/arch/cris/boot/compressed/misc.c	Tue Feb 13 14:13:43 2001
+++ linux/arch/cris/boot/compressed/misc.c	Fri Apr  6 10:42:55 2001
@@ -13,7 +13,7 @@
  */
 
 /* where the piggybacked kernel image expects itself to live.
- * it is the same address we use when we network load an uncompressed
+ * it is the same adress we use when we network load an uncompressed
  * image into DRAM, and it is the address the kernel is linked to live
  * at by etrax100.ld.
  */
diff -u --recursive --new-file v2.4.3/linux/arch/cris/boot/rescue/Makefile linux/arch/cris/boot/rescue/Makefile
--- v2.4.3/linux/arch/cris/boot/rescue/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/boot/rescue/Makefile	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,50 @@
+#
+# Makefile for rescue code
+#
+ifndef TOPDIR
+TOPDIR = ../../../..
+endif
+CC = gcc-cris -I $(TOPDIR)/include
+CFLAGS = -O2
+LD = ld-cris
+OBJCOPY = objcopy-cris
+
+all: rescue.bin testrescue.bin kimagerescue.bin
+
+rescue: rescue.bin
+	# do nothing
+
+rescue.bin: head.o
+	$(LD) -T rescue.ld -o rescue.o head.o
+	$(OBJCOPY) -O binary --remove-section=.bss rescue.o rescue.bin
+	cp rescue.bin $(TOPDIR)
+
+testrescue.bin: testrescue.o
+	$(OBJCOPY) -O binary --remove-section=.bss testrescue.o tr.bin
+# Pad it to 784 bytes
+	dd if=/dev/zero of=tmp2423 bs=1 count=784
+	cat tr.bin tmp2423 >testrescue_tmp.bin
+	dd if=testrescue_tmp.bin of=testrescue.bin bs=1 count=784
+	rm tr.bin tmp2423 testrescue_tmp.bin
+
+kimagerescue.bin: kimagerescue.o
+	$(OBJCOPY) -O binary --remove-section=.bss kimagerescue.o ktr.bin
+# Pad it to 784 bytes, that's what the rescue loader expects
+	dd if=/dev/zero of=tmp2423 bs=1 count=784
+	cat ktr.bin tmp2423 >kimagerescue_tmp.bin
+	dd if=kimagerescue_tmp.bin of=kimagerescue.bin bs=1 count=784
+	rm ktr.bin tmp2423 kimagerescue_tmp.bin
+
+head.o: head.S
+	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
+
+testrescue.o: testrescue.S
+	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
+
+kimagerescue.o: kimagerescue.S
+	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
+
+clean:
+	rm -f *.o *.bin
+
+fastdep:
diff -u --recursive --new-file v2.4.3/linux/arch/cris/boot/rescue/head.S linux/arch/cris/boot/rescue/head.S
--- v2.4.3/linux/arch/cris/boot/rescue/head.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/boot/rescue/head.S	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,323 @@
+	;; $Id: head.S,v 1.3 2001/02/14 16:57:25 larsv Exp $
+	;; 
+	;; Rescue code, made to reside at the beginning of the
+	;; flash-memory. when it starts, it checks a partition
+	;; table at the first sector after the rescue sector.
+	;; the partition table was generated by the product builder
+	;; script and contains offsets, lengths, types and checksums
+	;; for each partition that this code should check.
+	;;
+	;; If any of the checksums fail, we assume the flash is so
+	;; corrupt that we cant use it to boot into the ftp flash
+	;; loader, and instead we initialize the serial port to
+	;; receive a flash-loader and new flash image. we dont include
+	;; any flash code here, but just accept a certain amount of
+	;; bytes from the serial port and jump into it. the downloaded
+	;; code is put in the cache.
+	;;
+	;; The partitiontable is designed so that it is transparent to
+	;; code execution - it has a relative branch opcode in the
+	;; beginning that jumps over it. each entry contains extra
+	;; data so we can add stuff later.
+	;;
+	;; Partition table format:
+	;;
+	;;     Code transparency:
+	;; 
+	;;     2 bytes    [opcode 'nop']
+	;;     2 bytes    [opcode 'di']
+	;;     4 bytes    [opcode 'ba <offset>', 8-bit or 16-bit version]
+	;;     2 bytes    [opcode 'nop', delay slot]
+	;;
+	;;     Table validation (at +10):	
+	;; 
+	;;     2 bytes    [magic/version word for partitiontable - 0xef, 0xbe]
+	;;     2 bytes    [length of all entries plus the end marker]
+	;;     4 bytes    [checksum for the partitiontable itself]
+	;;
+	;;     Entries, each with the following format, last has offset -1:	
+	;;    
+	;;        4 bytes    [offset in bytes, from start of flash]
+	;;        4 bytes    [length in bytes of partition]
+	;;        4 bytes    [checksum, simple longword sum]
+	;;        2 bytes    [partition type]
+	;;        2 bytes    [flags, only bit 0 used, ro/rw = 1/0]
+	;;        16 bytes   [reserved for future use]
+	;;
+	;;     End marker
+	;;
+	;;        4 bytes    [-1]
+	;; 
+	;;	 10 bytes    [0, padding]
+	;; 
+	;; Bit 0 in flags signifies RW or RO. The rescue code only bothers
+	;; to check the checksum for RO partitions, since the others will
+	;; change its data without updating the checksums. A 1 in bit 0
+	;; means RO, 0 means RW. That way, it is possible to set a partition
+	;; in RO mode initially, and later mark it as RW, since you can always
+	;; write 0's to the flash.
+	;;
+	;; During the wait for serial input, the status LED will flash so the
+	;; user knows something went wrong.
+	;; 
+	;; Copyright (C) 1999 Axis Communications AB
+
+#include <linux/config.h>
+#define ASSEMBLER_MACROS_ONLY
+#include <asm/sv_addr_ag.h>
+
+	;; The partitiontable is looked for at the first sector after the boot
+	;; sector. Sector size is 65536 bytes in all flashes we use.
+		
+#define PTABLE_START 0x10000
+#define PTABLE_MAGIC 0xbeef
+
+	;; The normal Etrax100 on-chip boot ROM does serial boot at 0x380000f0.
+	;; That is not where we put our downloaded serial boot-code. The length is
+	;; enough for downloading code that loads the rest of itself (after
+	;; having setup the DRAM etc). It is the same length as the on-chip
+	;; ROM loads, so the same host loader can be used to load a rescued
+	;; product as well as one booted through the Etrax serial boot code.
+		
+#define CODE_START 0x40000000
+#define CODE_LENGTH 784
+
+#ifdef CONFIG_RESCUE_SER0
+#define SERXOFF R_SERIAL0_XOFF
+#define SERBAUD R_SERIAL0_BAUD
+#define SERRECC R_SERIAL0_REC_CTRL
+#define SERRDAT R_SERIAL0_REC_DATA
+#define SERSTAT R_SERIAL0_STATUS
+#endif
+#ifdef CONFIG_RESCUE_SER1
+#define SERXOFF R_SERIAL1_XOFF
+#define SERBAUD R_SERIAL1_BAUD
+#define SERRECC R_SERIAL1_REC_CTRL
+#define SERRDAT R_SERIAL1_REC_DATA
+#define SERSTAT R_SERIAL1_STATUS
+#endif
+#ifdef CONFIG_RESCUE_SER2
+#define SERXOFF R_SERIAL2_XOFF
+#define SERBAUD R_SERIAL2_BAUD
+#define SERRECC R_SERIAL2_REC_CTRL
+#define SERRDAT R_SERIAL2_REC_DATA
+#define SERSTAT R_SERIAL2_STATUS
+#endif	
+#ifdef CONFIG_RESCUE_SER3
+#define SERXOFF R_SERIAL3_XOFF
+#define SERBAUD R_SERIAL3_BAUD
+#define SERRECC R_SERIAL3_REC_CTRL
+#define SERRDAT R_SERIAL3_REC_DATA
+#define SERSTAT R_SERIAL3_STATUS
+#endif
+
+#define NOP_DI 0xf025050f
+	
+	.text
+	
+	;; This is the entry point of the rescue code
+	;; 0x80000000 if loaded in flash (as it should be)
+	;; since etrax actually starts at address 2 when booting from flash, we
+	;; put a nop (2 bytes) here first so we dont accidentally skip the di
+	
+	nop	
+	di
+
+	jump	in_cache	; enter cached area instead
+in_cache:	
+
+	;; first put a jump test to give a possibility of upgrading the rescue code
+	;; without erasing/reflashing the sector. we put a longword of -1 here and if
+	;; its not -1, we jump using the value as jump target. since we can always
+	;; change 1's to 0's without erasing the sector, it is possible to add new
+	;; code after this and altering the jumptarget in an upgrade.
+
+jtcd:	move.d	[jumptarget], r0
+	cmp.d	0xffffffff, r0
+	beq	no_newjump
+	nop
+	
+	jump	[r0]
+
+jumptarget:	
+	.dword	0xffffffff	; can be overwritten later to insert new code
+	
+no_newjump:	
+	;; We need to setup the bus registers before we start using the DRAM
+#include "../../lib/dram_init.S"
+
+	;; we now should go through the checksum-table and check the listed
+	;; partitions for errors.
+	
+	move.d	PTABLE_START, r3
+	move.d	[r3], r0
+	cmp.d	NOP_DI, r0	; make sure the nop/di is there...
+	bne	do_rescue
+	nop
+	
+	;; skip the code transparency block (10 bytes).
+
+	addq	10, r3
+	
+	;; check for correct magic
+	
+	move.w	[r3+], r0
+	cmp.w	PTABLE_MAGIC, r0
+	bne	do_rescue	; didn't recognize - trig rescue
+	nop
+
+	;; check for correct ptable checksum
+
+	movu.w	[r3+], r2	; ptable length
+	move.d	r2, r8		; save for later, length of total ptable
+	addq	28, r8		; account for the rest
+	move.d	[r3+], r4	; ptable checksum
+	move.d	r3, r1
+	jsr	checksum	; r1 source, r2 length, returns in r0
+
+	cmp.d	r0, r4
+	bne	do_rescue	; didn't match - trig rescue
+	nop
+	
+	;; ptable is ok. validate each entry.
+
+	moveq	-1, r7
+	
+ploop:	move.d	[r3+], r1	; partition offset (from ptable start)
+	bne	notfirst	; check if its the partition containing ptable
+	nop			; yes..
+	move.d	r8, r1		; for its checksum check, skip the ptable
+	move.d	[r3+], r2	; partition length
+	sub.d	r8, r2		; minus the ptable length
+	ba	bosse
+	nop
+notfirst:	
+	cmp.d	-1, r1		; the end of the ptable ?
+	beq	flash_ok	;   if so, the flash is validated
+	move.d	[r3+], r2	; partition length
+bosse:	move.d	[r3+], r5	; checksum
+	move.d	[r3+], r4	; type and flags
+	addq	16, r3		; skip the reserved bytes
+	btstq	16, r4		; check ro flag
+	bpl	ploop		;   rw partition, skip validation
+	nop
+	btstq	17, r4		; check bootable flag
+	bpl	1f
+	nop
+	move.d	r1, r7		; remember boot partition offset
+1:	
+
+	add.d	PTABLE_START, r1
+	
+	jsr	checksum	; checksum the partition
+	
+	cmp.d	r0, r5
+	beq	ploop		; checksums matched, go to next entry
+	nop
+
+	;; otherwise fall through to the rescue code.
+	
+do_rescue:
+	;; setup port PA and PB default initial directions and data
+	;; (so we can flash LEDs, and so that DTR and others are set)
+	
+	move.b	DEF_R_PORT_PA_DIR, r0
+	move.b	r0, [R_PORT_PA_DIR]
+	move.b	DEF_R_PORT_PA_DATA, r0
+	move.b	r0, [R_PORT_PA_DATA]
+	
+	move.b	DEF_R_PORT_PB_DIR, r0
+	move.b	r0, [R_PORT_PB_DIR]
+	move.b	DEF_R_PORT_PB_DATA, r0
+	move.b	r0, [R_PORT_PB_DATA]
+
+	;; setup the serial port at 115200 baud
+	
+	moveq	0, r0
+	move.d	r0, [SERXOFF] 
+
+	move.b	0x99, r0
+	move.b	r0, [SERBAUD]		; 115.2kbaud for both transmit and receive
+
+	move.b	0x40, r0		; rec enable
+	move.b	r0, [SERRECC] 
+
+	moveq	0, r1		; "timer" to clock out a LED red flash
+	move.d	CODE_START, r3	; destination counter
+	movu.w	CODE_LENGTH, r4	; length
+	
+wait_ser:
+	addq	1, r1
+#ifndef CONFIG_ETRAX_NO_LEDS
+#ifdef CONFIG_ETRAX_PA_LEDS
+	move.b	DEF_R_PORT_PA_DATA, r2
+#endif
+#ifdef CONFIG_ETRAX_PB_LEDS
+	move.b	DEF_R_PORT_PB_DATA, r2
+#endif
+	move.d	(1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), r0
+	btstq	16, r1
+	bpl	1f
+	nop
+	or.d	r0, r2		; set bit
+	ba	2f
+	nop
+1:	not	r0		; clear bit
+	and.d	r0, r2
+2:	
+#ifdef CONFIG_ETRAX_PA_LEDS
+	move.b	r2, [R_PORT_PA_DATA]	
+#endif	
+#ifdef CONFIG_ETRAX_PB_LEDS
+	move.b	r2, [R_PORT_PB_DATA]	
+#endif
+#ifdef CONFIG_ETRAX_90000000_LEDS
+	move.b	r2, [0x90000000]
+#endif
+#endif
+	
+	;; check if we got something on the serial port
+	
+	move.b	[SERSTAT], r0
+	btstq	0, r0		; data_avail
+	bpl	wait_ser
+	nop
+
+	;; got something - copy the byte and loop
+
+	move.b	[SERRDAT], r0
+	move.b	r0, [r3+]
+	
+	subq	1, r4		; decrease length
+	bne	wait_ser
+	nop
+
+	;; jump into downloaded code
+	
+	jump	CODE_START
+
+flash_ok:
+	;; check r7, which contains either -1 or the partition to boot from
+
+	cmp.d	-1, r7
+	bne	1f
+	nop
+	move.d	PTABLE_START, r7; otherwise use the ptable start
+1:	
+	jump	r7		; boot!
+
+
+	;; Helper subroutines
+
+	;; Will checksum by simple addition
+	;; r1 - source
+	;; r2 - length in bytes
+	;; result will be in r0
+checksum:
+	moveq	0, r0
+1:	addu.b	[r1+], r0
+	subq	1, r2
+	bne	1b
+	nop
+	ret
+	nop
diff -u --recursive --new-file v2.4.3/linux/arch/cris/boot/rescue/kimagerescue.S linux/arch/cris/boot/rescue/kimagerescue.S
--- v2.4.3/linux/arch/cris/boot/rescue/kimagerescue.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/boot/rescue/kimagerescue.S	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,143 @@
+	;; $Id: kimagerescue.S,v 1.2 2001/02/14 16:57:25 larsv Exp $
+	;; 
+	;; Rescue code to be prepended on a kimage and copied to the
+	;; rescue serial port.
+	;; This is called from the rescue code, it will copy received data to
+	;; 4000500 and after a timeout jump to it.
+	
+#include <linux/config.h>
+#define ASSEMBLER_MACROS_ONLY
+#include <asm/sv_addr_ag.h>
+
+#define CODE_START 0x40000500
+#define CODE_LENGTH 784
+#define TIMEOUT_VALUE 1000
+	
+		
+#ifdef CONFIG_RESCUE_SER0
+#define SERXOFF R_SERIAL0_XOFF
+#define SERBAUD R_SERIAL0_BAUD
+#define SERRECC R_SERIAL0_REC_CTRL
+#define SERRDAT R_SERIAL0_REC_DATA
+#define SERSTAT R_SERIAL0_STATUS
+#endif
+#ifdef CONFIG_RESCUE_SER1
+#define SERXOFF R_SERIAL1_XOFF
+#define SERBAUD R_SERIAL1_BAUD
+#define SERRECC R_SERIAL1_REC_CTRL
+#define SERRDAT R_SERIAL1_REC_DATA
+#define SERSTAT R_SERIAL1_STATUS
+#endif
+#ifdef CONFIG_RESCUE_SER2
+#define SERXOFF R_SERIAL2_XOFF
+#define SERBAUD R_SERIAL2_BAUD
+#define SERRECC R_SERIAL2_REC_CTRL
+#define SERRDAT R_SERIAL2_REC_DATA
+#define SERSTAT R_SERIAL2_STATUS
+#endif	
+#ifdef CONFIG_RESCUE_SER3
+#define SERXOFF R_SERIAL3_XOFF
+#define SERBAUD R_SERIAL3_BAUD
+#define SERRECC R_SERIAL3_REC_CTRL
+#define SERRDAT R_SERIAL3_REC_DATA
+#define SERSTAT R_SERIAL3_STATUS
+#endif
+
+	.text
+	;; This is the entry point of the rescue code
+	;; 0x80000000 if loaded in flash (as it should be)
+	;; since etrax actually starts at address 2 when booting from flash, we
+	;; put a nop (2 bytes) here first so we dont accidentally skip the di
+	
+	nop	
+	di
+#ifndef CONFIG_SVINTO_SIM	
+	;; setup port PA and PB default initial directions and data
+	;; (so we can flash LEDs, and so that DTR and others are set)
+	
+	move.b	DEF_R_PORT_PA_DIR, r0
+	move.b	r0, [R_PORT_PA_DIR]
+	move.b	DEF_R_PORT_PA_DATA, r0
+	move.b	r0, [R_PORT_PA_DATA]
+	
+	move.b	DEF_R_PORT_PB_DIR, r0
+	move.b	r0, [R_PORT_PB_DIR]
+	move.b	DEF_R_PORT_PB_DATA, r0
+	move.b	r0, [R_PORT_PB_DATA]
+	
+	;; We need to setup the bus registers before we start using the DRAM
+#include "../../lib/dram_init.S"
+	
+#endif
+	;; Setup the stack to a suitably high address.
+	;; We assume 8 MB is the minimum DRAM in an eLinux
+	;; product and put the sp at the top for now.
+
+	move.d	0x40800000, sp
+	
+	;; setup the serial port at 115200 baud
+	
+	moveq	0, r0
+	move.d	r0, [SERXOFF] 
+
+	move.b	0x99, r0
+	move.b	r0, [SERBAUD]		; 115.2kbaud for both transmit and receive
+
+	move.b	0x40, r0		; rec enable
+	move.b	r0, [SERRECC] 
+
+
+	moveq	0, r1		; "timer" to clock out a LED red flash
+	move.d	CODE_START, r3	; destination counter
+	move.d	CODE_LENGTH, r4	; length
+	move.d	TIMEOUT_VALUE, r5	; "timeout" until jump
+
+wait_ser:
+	addq	1, r1
+	subq	1, r5		; decrease timeout
+	beq	jump_start	; timed out
+	nop
+#ifndef CONFIG_ETRAX_NO_LEDS
+#ifdef CONFIG_ETRAX_PA_LEDS
+	move.b	DEF_R_PORT_PA_DATA, r2
+#endif
+#ifdef CONFIG_ETRAX_PB_LEDS
+	move.b	DEF_R_PORT_PB_DATA, r2
+#endif
+	move.d	(1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), r0
+	btstq	16, r1
+	bpl	1f
+	nop
+	or.d	r0, r2		; set bit
+	ba	2f
+	nop
+1:	not	r0		; clear bit
+	and.d	r0, r2
+2:	
+#ifdef CONFIG_ETRAX_PA_LEDS
+	move.b	r2, [R_PORT_PA_DATA]
+#endif	
+#ifdef CONFIG_ETRAX_PB_LEDS
+	move.b	r2, [R_PORT_PB_DATA]
+#endif
+#endif
+		
+	;; check if we got something on the serial port
+	
+	move.b	[SERSTAT], r0
+	btstq	0, r0		; data_avail
+	bpl	wait_ser
+	nop
+
+	;; got something - copy the byte and loop
+
+	move.b	[SERRDAT], r0
+	move.b	r0, [r3+]
+	move.d	TIMEOUT_VALUE, r5	; reset "timeout"
+	subq	1, r4		; decrease length
+	bne	wait_ser
+	nop
+jump_start:
+	;; jump into downloaded code
+
+	jump	CODE_START
diff -u --recursive --new-file v2.4.3/linux/arch/cris/boot/rescue/rescue.ld linux/arch/cris/boot/rescue/rescue.ld
--- v2.4.3/linux/arch/cris/boot/rescue/rescue.ld	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/boot/rescue/rescue.ld	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,20 @@
+MEMORY 
+	{
+	flash : ORIGIN = 0x00000000,
+	        LENGTH = 0x00100000
+	}
+
+SECTIONS
+{
+	.text :
+	{
+		_stext = . ;
+		*(.text)
+		_etext = . ;
+	} > flash
+	.data :
+	{
+		*(.data)
+		_edata = . ;
+	} > flash
+}
diff -u --recursive --new-file v2.4.3/linux/arch/cris/boot/rescue/testrescue.S linux/arch/cris/boot/rescue/testrescue.S
--- v2.4.3/linux/arch/cris/boot/rescue/testrescue.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/boot/rescue/testrescue.S	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,25 @@
+	;; $Id: testrescue.S,v 1.1 2001/01/31 15:32:09 johana Exp $
+	;;
+	;; Simple testcode to download by the rescue block.
+	;; Just lits some LEDs to show it was downloaded correctly.
+	;; 
+	;; Copyright (C) 1999 Axis Communications AB
+
+#define ASSEMBLER_MACROS_ONLY
+#include <asm/sv_addr_ag.h>
+
+	.text
+
+	nop
+	nop
+	moveq	-1, r2
+	move.b	r2, [R_PORT_PA_DIR]
+	moveq	0, r2
+	move.b	r2, [R_PORT_PA_DATA]	
+
+endless:
+	nop
+	ba	endless
+	nop
+
+	
diff -u --recursive --new-file v2.4.3/linux/arch/cris/boot/tools/build.c linux/arch/cris/boot/tools/build.c
--- v2.4.3/linux/arch/cris/boot/tools/build.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/boot/tools/build.c	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,288 @@
+/*
+ *  linux/tools/build.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+/*
+ * This file builds a disk-image from three different files:
+ *
+ * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest
+ * - setup: 8086 machine code, sets up system parm
+ * - system: 80386 code for actual system
+ *
+ * It does some checking that all files are of the correct type, and
+ * just writes the result to stdout, removing headers and padding to
+ * the right amount. It also writes some system data to stderr.
+ */
+
+/*
+ * Changes by tytso to allow root device specification
+ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+ * Cross compiling fixes by Gertjan van Wingerde, July 1996
+ */
+
+#include <stdio.h>	/* fprintf */
+#include <string.h>
+#include <stdlib.h>	/* contains exit */
+#include <sys/types.h>	/* unistd.h needs this */
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <unistd.h>	/* contains read/write */
+#include <fcntl.h>
+#include <linux/a.out.h>
+#include <errno.h>
+
+#define MINIX_HEADER 32
+
+#define N_MAGIC_OFFSET 1024
+#ifndef __BFD__
+static int GCC_HEADER = sizeof(struct exec);
+#endif
+
+#ifdef __BIG_KERNEL__
+#define SYS_SIZE 0xffff
+#else
+#define SYS_SIZE DEF_SYSSIZE
+#endif
+
+#define DEFAULT_MAJOR_ROOT 0
+#define DEFAULT_MINOR_ROOT 0
+
+/* max nr of sectors of setup: don't change unless you also change
+ * bootsect etc */
+#define SETUP_SECTS 4
+
+#define STRINGIFY(x) #x
+
+typedef union {
+	int i;
+	long l;
+	short s[2];
+	char b[4];
+} conv;
+
+long intel_long(long l)
+{
+	conv t;
+
+	t.b[0] = l & 0xff; l >>= 8;
+	t.b[1] = l & 0xff; l >>= 8;
+	t.b[2] = l & 0xff; l >>= 8;
+	t.b[3] = l & 0xff; l >>= 8;
+	return t.l;
+}
+
+int intel_int(int i)
+{
+	conv t;
+
+	t.b[0] = i & 0xff; i >>= 8;
+        t.b[1] = i & 0xff; i >>= 8;
+        t.b[2] = i & 0xff; i >>= 8;
+        t.b[3] = i & 0xff; i >>= 8;
+        return t.i;
+}
+
+short intel_short(short l)
+{
+	conv t;
+
+	t.b[0] = l & 0xff; l >>= 8;
+	t.b[1] = l & 0xff; l >>= 8;
+	return t.s[0];
+}
+
+void die(const char * str)
+{
+	fprintf(stderr,"%s\n",str);
+	exit(1);
+}
+
+void usage(void)
+{
+	die("Usage: build bootsect setup system [rootdev] [> image]");
+}
+
+int main(int argc, char ** argv)
+{
+	int i,c,id,sz,tmp_int;
+	unsigned long sys_size, tmp_long;
+	char buf[1024];
+#ifndef __BFD__
+	struct exec *ex = (struct exec *)buf;
+#endif
+	char major_root, minor_root;
+	struct stat sb;
+	unsigned char setup_sectors;
+
+	if ((argc < 4) || (argc > 5))
+		usage();
+	if (argc > 4) {
+		if (!strcmp(argv[4], "CURRENT")) {
+			if (stat("/", &sb)) {
+				perror("/");
+				die("Couldn't stat /");
+			}
+			major_root = major(sb.st_dev);
+			minor_root = minor(sb.st_dev);
+		} else if (strcmp(argv[4], "FLOPPY")) {
+			if (stat(argv[4], &sb)) {
+				perror(argv[4]);
+				die("Couldn't stat root device.");
+			}
+			major_root = major(sb.st_rdev);
+			minor_root = minor(sb.st_rdev);
+		} else {
+			major_root = 0;
+			minor_root = 0;
+		}
+	} else {
+		major_root = DEFAULT_MAJOR_ROOT;
+		minor_root = DEFAULT_MINOR_ROOT;
+	}
+	fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
+	for (i=0;i<sizeof buf; i++) buf[i]=0;
+	if ((id=open(argv[1],O_RDONLY,0))<0)
+		die("Unable to open 'boot'");
+	if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
+		die("Unable to read header of 'boot'");
+	if (((long *) buf)[0]!=intel_long(0x04100301))
+		die("Non-Minix header of 'boot'");
+	if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
+		die("Non-Minix header of 'boot'");
+	if (((long *) buf)[3] != 0)
+		die("Illegal data segment in 'boot'");
+	if (((long *) buf)[4] != 0)
+		die("Illegal bss in 'boot'");
+	if (((long *) buf)[5] != 0)
+		die("Non-Minix header of 'boot'");
+	if (((long *) buf)[7] != 0)
+		die("Illegal symbol table in 'boot'");
+	i=read(id,buf,sizeof buf);
+	fprintf(stderr,"Boot sector %d bytes.\n",i);
+	if (i != 512)
+		die("Boot block must be exactly 512 bytes");
+	if ((*(unsigned short *)(buf+510)) != (unsigned short)intel_short(0xAA55))
+		die("Boot block hasn't got boot flag (0xAA55)");
+	buf[508] = (char) minor_root;
+	buf[509] = (char) major_root;	
+	i=write(1,buf,512);
+	if (i!=512)
+		die("Write call failed");
+	close (id);
+	
+	if ((id=open(argv[2],O_RDONLY,0))<0)
+		die("Unable to open 'setup'");
+	if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
+		die("Unable to read header of 'setup'");
+	if (((long *) buf)[0]!=intel_long(0x04100301))
+		die("Non-Minix header of 'setup'");
+	if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
+		die("Non-Minix header of 'setup'");
+	if (((long *) buf)[3] != 0)
+		die("Illegal data segment in 'setup'");
+	if (((long *) buf)[4] != 0)
+		die("Illegal bss in 'setup'");
+	if (((long *) buf)[5] != 0)
+		die("Non-Minix header of 'setup'");
+	if (((long *) buf)[7] != 0)
+		die("Illegal symbol table in 'setup'");
+	for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )
+#ifdef __BIG_KERNEL__
+	{
+		if (!i) {
+			/* Working with memcpy because of alignment constraints
+			   on Sparc - Gertjan */
+			memcpy(&tmp_long, &buf[2], sizeof(long));
+			if (tmp_long != intel_long(0x53726448) )
+				die("Wrong magic in loader header of 'setup'");
+			memcpy(&tmp_int, &buf[6], sizeof(int));
+			if (tmp_int < intel_int(0x200))
+				die("Wrong version of loader header of 'setup'");
+			buf[0x11] = 1; /* LOADED_HIGH */
+			tmp_long = intel_long(0x100000);
+			memcpy(&buf[0x14], &tmp_long, sizeof(long));  /* code32_start */
+		}
+#endif
+		if (write(1,buf,c)!=c)
+			die("Write call failed");
+#ifdef __BIG_KERNEL__
+	}
+#endif
+	if (c != 0)
+		die("read-error on 'setup'");
+	close (id);
+	setup_sectors = (unsigned char)((i + 511) / 512);
+	/* for compatibility with LILO */
+	if (setup_sectors < SETUP_SECTS)
+		setup_sectors = SETUP_SECTS;
+	fprintf(stderr,"Setup is %d bytes.\n",i);
+	for (c=0 ; c<sizeof(buf) ; c++)
+		buf[c] = '\0';
+	while (i < setup_sectors * 512) {
+		c = setup_sectors * 512 - i;
+		if (c > sizeof(buf))
+			c = sizeof(buf);
+		if (write(1,buf,c) != c)
+			die("Write call failed");
+		i += c;
+	}
+	
+	if ((id=open(argv[3],O_RDONLY,0))<0)
+		die("Unable to open 'system'");
+#ifndef __BFD__
+	if (read(id,buf,GCC_HEADER) != GCC_HEADER)
+		die("Unable to read header of 'system'");
+	if (N_MAGIC(*ex) == ZMAGIC) {
+		GCC_HEADER = N_MAGIC_OFFSET;
+		lseek(id, GCC_HEADER, SEEK_SET);
+	} else if (N_MAGIC(*ex) != QMAGIC)
+		die("Non-GCC header of 'system'");
+	fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n",
+		(ex->a_text+ex->a_data+ex->a_bss)/1024,
+		ex->a_text /1024,
+		ex->a_data /1024,
+		ex->a_bss  /1024);
+	sz = N_SYMOFF(*ex) - GCC_HEADER + 4;
+#else
+	if (fstat (id, &sb)) {
+	  perror ("fstat");
+	  die ("Unable to stat 'system'");
+	}
+	sz = sb.st_size;
+	fprintf (stderr, "System is %d kB\n", sz/1024);
+#endif
+	sys_size = (sz + 15) / 16;
+	if (sys_size > SYS_SIZE)
+		die("System is too big");
+	while (sz > 0) {
+		int l, n;
+
+		l = sz;
+		if (l > sizeof(buf))
+			l = sizeof(buf);
+		if ((n=read(id, buf, l)) != l) {
+			if (n == -1) 
+				perror(argv[1]);
+			else
+				fprintf(stderr, "Unexpected EOF\n");
+			die("Can't read 'system'");
+		}
+		if (write(1, buf, l) != l)
+			die("Write failed");
+		sz -= l;
+	}
+	close(id);
+	if (lseek(1, 497, 0) == 497) {
+		if (write(1, &setup_sectors, 1) != 1)
+			die("Write of setup sectors failed");
+	}
+	if (lseek(1,500,0) == 500) {
+		buf[0] = (sys_size & 0xff);
+		buf[1] = ((sys_size >> 8) & 0xff);
+		if (write(1, buf, 2) != 2)
+			die("Write failed");
+	}
+	return(0);
+}
diff -u --recursive --new-file v2.4.3/linux/arch/cris/config.in linux/arch/cris/config.in
--- v2.4.3/linux/arch/cris/config.in	Fri Feb 16 15:53:08 2001
+++ linux/arch/cris/config.in	Fri Apr  6 10:42:55 2001
@@ -36,15 +36,19 @@
 comment 'Hardware setup'
 
 choice 'Processor type' \
-	"Etrax-100-LX	CONFIG_ETRAX100LX	\
-	 Etrax-100-LX-for-xsim-simulator   CONFIG_SVINTO_SIM" Etrax-100-LX
+	"Etrax-100-LX-v1	CONFIG_ETRAX100LX	\
+	 Etrax-100-LX-v2	CONFIG_ETRAX100LX_V2	\
+	 Etrax-100-LX-for-xsim-simulator   CONFIG_SVINTO_SIM" Etrax-100-LX-v1
 
 # For both LX version 1 and the current simulator we enable the low VM mapping
-# Later when LX version 2 and above exist, this should be done with an if
 
-define_bool CONFIG_CRIS_LOW_MAP y
+if [ "$CONFIG_ETRAX100LX" = "y" -o "$CONFIG_SVINTO_SIM" = "y" ]; then
+	define_bool CONFIG_CRIS_LOW_MAP y
+	define_hex  ETRAX_DRAM_VIRTUAL_BASE 60000000
+else
+	define_hex  ETRAX_DRAM_VIRTUAL_BASE c0000000
+fi
 
-hex 'DRAM base (hex)' ETRAX_DRAM_BASE 40000000
 int 'DRAM size (dec, in MB)' ETRAX_DRAM_SIZE 8
 
 int 'Max possible flash size (dec, in MB)' CONFIG_ETRAX_FLASH_LENGTH 2
@@ -69,12 +73,29 @@
 	"Serial-0	CONFIG_DEBUG_PORT0	\
 	 Serial-1	CONFIG_DEBUG_PORT1	\
 	 Serial-2	CONFIG_DEBUG_PORT2	\
-	 Serial-3	CONFIG_DEBUG_PORT3" Serial-0
+	 Serial-3	CONFIG_DEBUG_PORT3	\
+	 disabled	CONFIG_DEBUG_PORT_NULL" Serial-0 
+
+choice 'Product rescue-port' \
+	"Serial-0	CONFIG_RESCUE_SER0	\
+	 Serial-1	CONFIG_RESCUE_SER1	\
+	 Serial-2	CONFIG_RESCUE_SER2	\
+	 Serial-3	CONFIG_RESCUE_SER3" Serial-0
 
 hex 'R_WAITSTATES' DEF_R_WAITSTATES 95a6
 hex 'R_BUS_CONFIG' DEF_R_BUS_CONFIG 104
-hex 'R_DRAM_CONFIG' DEF_R_DRAM_CONFIG 1a200040
-hex 'R_DRAM_TIMING' DEF_R_DRAM_TIMING 5611
+
+bool 'SDRAM support' CONFIG_SDRAM n
+if [ "$CONFIG_SDRAM" = "n" ]; then
+	hex 'R_DRAM_CONFIG' DEF_R_DRAM_CONFIG 1a200040
+	hex 'R_DRAM_TIMING' DEF_R_DRAM_TIMING 5611
+fi
+
+if [ "$CONFIG_SDRAM" = "y" ]; then
+	hex 'R_SDRAM_CONFIG' DEF_R_SDRAM_CONFIG d2fa7878
+	hex 'R_SDRAM_TIMING' DEF_R_SDRAM_TIMING 80004801
+fi
+
 hex 'R_PORT_PA_DIR' DEF_R_PORT_PA_DIR 1c
 hex 'R_PORT_PA_DATA' DEF_R_PORT_PA_DATA 00
 hex 'R_PORT_PB_CONFIG' DEF_R_PORT_PB_CONFIG 00
@@ -82,24 +103,6 @@
 hex 'R_PORT_PB_DATA' DEF_R_PORT_PB_DATA ff
 
 endmenu
-
-# only configure IP numbers if the kernel ifconfig/route setup is enabled
-
-if [ "$CONFIG_KERNEL_IFCONFIG" = "y" ]; then
-  mainmenu_option next_comment	
-  comment 'IP address selection'
-
-  comment 'All addresses are in hexadecimal form without 0x prefix'
-
-  hex 'IP address' ELTEST_IPADR ab1005af
-  hex 'Network' ELTEST_NETWORK ab100000
-  hex 'Netmask' ELTEST_NETMASK ffff0000
-  hex 'Broadcast' ELTEST_BROADCAST ab10ffff
-  hex 'Gateway' ELTEST_GATEWAY ab100101
-  hwaddr 'Ethernet address' ELTEST_ETHADR 00408ccd0000
-
-  endmenu
-fi
 
 # bring in Etrax built-in drivers
 
diff -u --recursive --new-file v2.4.3/linux/arch/cris/cris.ld linux/arch/cris/cris.ld
--- v2.4.3/linux/arch/cris/cris.ld	Tue Feb 13 14:13:43 2001
+++ linux/arch/cris/cris.ld	Fri Apr  6 10:42:55 2001
@@ -1,13 +1,10 @@
 /* ld script to make the Linux/CRIS kernel
  * Authors: Bjorn Wesen (bjornw@axis.com)
- *
- * For now, on Etrax-100 LX, the DRAM starts virtually at 0x6. Normally
- * it should be at 0xc.
  */	
 
 SECTIONS
 {
-	. = 0x60000000;               /* DRAM starts virtually at 0x60000000 */
+	. = @ETRAX_DRAM_VIRTUAL_BASE@;
 	_dram_start = .;
 	_ibr_start = .;
 	. = . + 0x4000; /* see head.S and pages reserved at the start */
@@ -21,6 +18,7 @@
 		*(.fixup)
 		*(.text.__*)
 		*(.rodata)
+		*(.rodata.__*)
 	}
 
 	. = ALIGN(4);                /* Exception table */
@@ -77,5 +75,5 @@
 		*(.exitcall.exit)
         }
 
-	_dram_end = 0x60000000 + @ETRAX_DRAM_SIZE_M@*1024*1024;
+	_dram_end = _dram_start + @ETRAX_DRAM_SIZE_M@*1024*1024;
 }
diff -u --recursive --new-file v2.4.3/linux/arch/cris/defconfig linux/arch/cris/defconfig
--- v2.4.3/linux/arch/cris/defconfig	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/defconfig	Fri Apr  6 10:42:55 2001
@@ -24,10 +24,13 @@
 # Hardware setup
 #
 CONFIG_ETRAX100LX=y
+# CONFIG_ETRAX100LX_V2 is not set
 # CONFIG_SVINTO_SIM is not set
 CONFIG_CRIS_LOW_MAP=y
-ETRAX_DRAM_BASE=40000000
+ETRAX_DRAM_VIRTUAL_BASE=60000000
 ETRAX_DRAM_SIZE=8
+CONFIG_ETRAX_FLASH_LENGTH=2
+CONFIG_ETRAX_FLASH_BUSWIDTH=2
 CONFIG_ETRAX_PA_LEDS=y
 # CONFIG_ETRAX_PB_LEDS is not set
 # CONFIG_ETRAX_90000000_LEDS is not set
@@ -40,8 +43,13 @@
 # CONFIG_DEBUG_PORT1 is not set
 # CONFIG_DEBUG_PORT2 is not set
 # CONFIG_DEBUG_PORT3 is not set
+CONFIG_RESCUE_SER0=y
+# CONFIG_RESCUE_SER1 is not set
+# CONFIG_RESCUE_SER2 is not set
+# CONFIG_RESCUE_SER3 is not set
 DEF_R_WAITSTATES=95a6
 DEF_R_BUS_CONFIG=104
+# CONFIG_SDRAM is not set
 DEF_R_DRAM_CONFIG=1a200040
 DEF_R_DRAM_TIMING=5611
 DEF_R_PORT_PA_DIR=1d
@@ -56,6 +64,87 @@
 CONFIG_ETRAX_ETHERNET=y
 CONFIG_NET_ETHERNET=y
 CONFIG_ETRAX_SERIAL=y
+# CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB is not set
+CONFIG_ETRAX_SERIAL_PORT1=y
+# CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PB is not set
+# CONFIG_ETRAX_SERIAL_PORT2 is not set
+# CONFIG_ETRAX_SERIAL_PORT3 is not set
+# CONFIG_RS485 is not set
+# CONFIG_ETRAX_SYNCHRONOUS_SERIAL is not set
+# CONFIG_ETRAX_IDE is not set
+CONFIG_ETRAX_AXISFLASHMAP=y
+CONFIG_MTD=y
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_AMDSTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_ETRAX_I2C=y
+CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C=y
+CONFIG_ETRAX_GPIO=y
+CONFIG_ETRAX_PA_BUTTON_BITMASK=02
+CONFIG_PA_CHANGEABLE_DIR=00
+CONFIG_PA_CHANGEABLE_BITS=FF
+CONFIG_PB_CHANGEABLE_DIR=00
+CONFIG_PB_CHANGEABLE_BITS=FF
+# CONFIG_JULIETTE is not set
+# CONFIG_JULIETTE_VIDEO is not set
+# CONFIG_JULIETTE_CCD is not set
+# CONFIG_JULIETTE_SS1M is not set
+# CONFIG_JULIETTE_MEGCCD is not set
+# CONFIG_ETRAX_USB_HOST is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG 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
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_MTDRAM is not set
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_CFI_GEOMETRY is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_AMDSTD=y
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_PNC2000 is not set
+# CONFIG_MTD_RPXLITE is not set
+# CONFIG_MTD_SBC_MEDIAGX is not set
+# CONFIG_MTD_ELAN_104NC is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_CSTM_CFI_JEDEC is not set
+# CONFIG_MTD_JEDEC is not set
+# CONFIG_MTD_MIXMEM is not set
+# CONFIG_MTD_OCTAGON is not set
+# CONFIG_MTD_VMAX is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_NAND_SPIA is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL 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
@@ -90,10 +179,6 @@
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
-
-#
-#  
-#
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_DECNET is not set
@@ -101,6 +186,7 @@
 # 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
@@ -112,11 +198,61 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+# CONFIG_BLK_DEV_IDE is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDEDISK is not set
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD 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_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
+
+#
 # 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
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -177,6 +313,16 @@
 # CONFIG_WAN is not set
 
 #
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
 # ISDN subsystem
 #
 # CONFIG_ISDN is not set
@@ -187,6 +333,60 @@
 # CONFIG_CD_NO_IDESCSI is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT 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_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK 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
@@ -259,59 +459,14 @@
 # CONFIG_NLS 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_UNIX98_PTYS is not set
-# CONFIG_PRINTER is not set
-# CONFIG_PPDEV is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_JOYSTICK is not set
-
-#
-# Input core support is needed for joysticks
-#
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
+# Sound
 #
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
+# CONFIG_SOUND is not set
 
 #
-# Sound
+# USB support
 #
-# CONFIG_SOUND is not set
+# CONFIG_USB is not set
 
 #
 # Kernel hacking
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/Config.in linux/arch/cris/drivers/Config.in
--- v2.4.3/linux/arch/cris/drivers/Config.in	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/drivers/Config.in	Fri Apr  6 10:42:55 2001
@@ -1,16 +1,74 @@
 mainmenu_option next_comment
 comment 'Drivers for Etrax built-in interfaces'
 
-bool 'Ethernet support' CONFIG_ETRAX_ETHERNET y
+bool 'Ethernet support' CONFIG_ETRAX_ETHERNET
 if [ "$CONFIG_ETRAX_ETHERNET" = "y" ]; then
 # this is just so that the user does not have to go into the
 # normal ethernet driver section just to enable ethernetworking
   define_bool CONFIG_NET_ETHERNET y
+else
+  define_bool CONFIG_NET_ETHERNET n
 fi
 
-bool 'Serial-port support' CONFIG_ETRAX_SERIAL y
+bool 'Serial-port support' CONFIG_ETRAX_SERIAL
+if [ "$CONFIG_ETRAX_SERIAL" = "y" ]; then
+  comment '  Port 0 is always enabled'
+  bool '  Ser0 DTR, RI, DSR, CD on PB' CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB
+  if [ "$CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB" = "y" ]; then
+    int '    Ser0 DTR on PB bit' CONFIG_ETRAX_SER0_DTR_ON_PB_BIT 4
+    int '    Ser0 RI  on PB bit' CONFIG_ETRAX_SER0_RI_ON_PB_BIT 5
+    int '    Ser0 DSR on PB bit' CONFIG_ETRAX_SER0_DSR_ON_PB_BIT 6
+    int '    Ser0 CD  on PB bit' CONFIG_ETRAX_SER0_CD_ON_PB_BIT 7
+  fi
+ 
+  bool '  Serial port 1 enabled' CONFIG_ETRAX_SERIAL_PORT1
+  if [ "$CONFIG_ETRAX_SERIAL_PORT1" = "y" ]; then
+    bool '  Ser1 DTR, RI, DSR, CD on PB' CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PB
+    if [ "$CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PB" = "y" ]; then
+      int '    Ser1 DTR on PB bit' CONFIG_ETRAX_SER1_DTR_ON_PB_BIT 4
+      int '    Ser1 RI  on PB bit' CONFIG_ETRAX_SER1_RI_ON_PB_BIT 5
+      int '    Ser1 DSR on PB bit' CONFIG_ETRAX_SER1_DSR_ON_PB_BIT 6
+      int '    Ser1 CD  on PB bit' CONFIG_ETRAX_SER1_CD_ON_PB_BIT 7
+    fi
+  fi
+  if [ "$CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB" = "y" -a \
+       "$CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PB" = "y" ]; then
+    comment 'Make sure you dont have the same PB bits more than once!'
+  fi
+  bool '  Serial port 2 enabled' CONFIG_ETRAX_SERIAL_PORT2
+  if [ "$CONFIG_ETRAX_SERIAL_PORT2" = "y" ]; then
+    bool '    Ser2 DTR, RI, DSR, CD on PA' CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PA
+    if [ "$CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PA" = "y" ]; then
+      int '      Ser2 DTR on PA bit' CONFIG_ETRAX_SER2_DTR_ON_PA_BIT 4
+      int '      Ser2 RI  on PA bit' CONFIG_ETRAX_SER2_RI_ON_PA_BIT 5
+      int '      Ser2 DSR on PA bit' CONFIG_ETRAX_SER2_DSR_ON_PA_BIT 6
+      int '      Ser2 CD  on PA bit' CONFIG_ETRAX_SER2_CD_ON_PA_BIT 7
+    fi 
+  fi
+  bool '  Serial port 3 enabled' CONFIG_ETRAX_SERIAL_PORT3
+  bool '  RS-485 support' CONFIG_RS485
+  if [ "$CONFIG_RS485" = "y" ]; then
+    bool '    RS-485 mode on PA' CONFIG_RS485_ON_PA
+    if [ "$CONFIG_RS485_ON_PA" = "y" ]; then
+      int '      RS-485 mode on PA bit' CONFIG_RS485_ON_PA_BIT 3
+    fi
+    bool '    Disable serial receiver' CONFIG_RS485_DISABLE_RECEIVER
+  fi
+fi
+
+bool 'Synchronous serial port support' CONFIG_ETRAX_SYNCHRONOUS_SERIAL
+if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL" = "y" ]; then 
+  bool '  Synchronous serial port 0 enabled' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0
+  if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0" = "y" ]; then
+    bool '    Synchronous serial port 0 uses DMA' CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA y
+  fi
+  bool '  Synchronous serial port 1 enabled' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1
+  if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1" = "y" ]; then
+    bool '    Synchronous serial port 1 uses DMA' CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA y
+  fi 
+fi
 
-bool 'ATA/IDE support' CONFIG_ETRAX_IDE n
+bool 'ATA/IDE support' CONFIG_ETRAX_IDE
 
 if [ "$CONFIG_ETRAX_IDE" = "y" ]; then
 # here we should add the CONFIG_'s necessary to enable the basic
@@ -25,14 +83,18 @@
 
 	define_bool CONFIG_BLK_DEV_IDEDMA y
 	define_bool CONFIG_DMA_NONPCI y
- 
+	
+	int 'Delay for drives to regain consciousness' CONFIG_IDE_DELAY 15
+	
 	choice 'IDE reset pin' \
   	"Port_PB_Bit_7  CONFIG_ETRAX_IDE_PB7_RESET\
    	 Port_G_Bit_27  CONFIG_ETRAX_IDE_G27_RESET\
    	 Port_CSE1_Bit_16  CONFIG_ETRAX_IDE_CSE1_16_RESET" Port_PB_Bit_7 
+else
+	define_bool CONFIG_IDE n
 fi
 
-bool 'Axis flash-map support' CONFIG_ETRAX_AXISFLASHMAP n
+bool 'Axis flash-map support' CONFIG_ETRAX_AXISFLASHMAP
 
 if [ "$CONFIG_ETRAX_AXISFLASHMAP" = "y" ]; then
 # here we define the CONFIG_'s necessary to enable MTD support
@@ -43,7 +105,39 @@
 	define_bool CONFIG_MTD_CFI_INTELEXT n
 	define_bool CONFIG_MTD_CFI_AMDSTD y
 
+	define_bool CONFIG_MTD_AMDSTD y
+
 	define_bool CONFIG_MTD_CHAR y
+	define_bool CONFIG_MTD_BLOCK y
+fi
+
+bool 'I2C support' CONFIG_ETRAX_I2C
+if [ "$CONFIG_ETRAX_I2C" = "y" ]; then
+# this is true for most products since PB-I2C seems to be somewhat
+# flawed.. 
+	bool 'I2C uses PB not PB-I2C' CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
+fi
+
+bool 'GPIO support' CONFIG_ETRAX_GPIO
+if [ "$CONFIG_ETRAX_GPIO" = "y" ]; then
+  hex  '  PA-buttons bitmask' CONFIG_ETRAX_PA_BUTTON_BITMASK 02
+  hex  '  PA user changeable dir mask' CONFIG_PA_CHANGEABLE_DIR 00
+  hex  '  PA user changeable bits mask' CONFIG_PA_CHANGEABLE_BITS FF
+  hex  '  PB user changeable dir mask' CONFIG_PB_CHANGEABLE_DIR 00
+  hex  '  PB user changeable bits mask' CONFIG_PB_CHANGEABLE_BITS FF
+fi
+
+bool 'Juliette support' CONFIG_JULIETTE n
+
+if [ "$CONFIG_JULIETTE" = "y" ]; then
+   source arch/cris/drivers/juliette/Config.in
+fi
+
+bool 'USB host' CONFIG_ETRAX_USB_HOST
+if [ "$CONFIG_ETRAX_USB_HOST" = "y" ]; then
+	define_bool CONFIG_USB y
+	bool '  USB port 1 enabled' CONFIG_ETRAX_USB_HOST_PORT1 n
+	bool '  USB port 2 enabled' CONFIG_ETRAX_USB_HOST_PORT2 n
 fi
 
 endmenu
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/Makefile linux/arch/cris/drivers/Makefile
--- v2.4.3/linux/arch/cris/drivers/Makefile	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/drivers/Makefile	Fri Apr  6 10:42:55 2001
@@ -6,9 +6,16 @@
 
 obj-y :=
 
-obj-$(CONFIG_ETRAX_ETHERNET)     += ethernet.o
-obj-$(CONFIG_ETRAX_SERIAL)       += serial.o
-obj-$(CONFIG_ETRAX_IDE)          += ide.o
-obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o
+
+obj-$(CONFIG_ETRAX_ETHERNET)           += ethernet.o
+obj-$(CONFIG_ETRAX_SERIAL)             += serial.o
+obj-$(CONFIG_ETRAX_IDE)                += ide.o
+obj-$(CONFIG_ETRAX_AXISFLASHMAP)       += axisflashmap.o
+obj-$(CONFIG_ETRAX_I2C) 	       += i2c.o
+obj-$(CONFIG_ETRAX_GPIO) 	       += gpio.o
+obj-$(CONFIG_ETRAX_USB_HOST)           += usb-host.o
+obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
+obj-$(CONFIG_JULIETTE)                 += juliette/juliette.o
+subdir-$(CONFIG_JULIETTE)              += juliette
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/axisflashmap.c linux/arch/cris/drivers/axisflashmap.c
--- v2.4.3/linux/arch/cris/drivers/axisflashmap.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/drivers/axisflashmap.c	Fri Apr  6 10:42:55 2001
@@ -11,6 +11,17 @@
  * partition split defined below.
  *
  * $Log: axisflashmap.c,v $
+ * Revision 1.4  2001/02/23 12:47:15  bjornw
+ * Uncached flash in LOW_MAP moved from 0xe to 0x8
+ *
+ * Revision 1.3  2001/02/16 12:11:45  jonashg
+ * MTD driver amd_flash is now included in MTD CVS repository.
+ * (It's now in drivers/mtd).
+ *
+ * Revision 1.2  2001/02/09 11:12:22  jonashg
+ * Support for AMD compatible non-CFI flash chips.
+ * Only tested with Toshiba TC58FVT160 so far.
+ *
  * Revision 1.1  2001/01/12 17:01:18  bjornw
  * * Added axisflashmap.c, a physical mapping for MTD that reads and understands
  *   Axis partition-table format.
@@ -31,7 +42,7 @@
 #include <asm/mmu.h>
 
 #ifdef CONFIG_CRIS_LOW_MAP
-#define FLASH_UNCACHED_ADDR  KSEG_E
+#define FLASH_UNCACHED_ADDR  KSEG_8
 #define FLASH_CACHED_ADDR    KSEG_5
 #else
 #define FLASH_UNCACHED_ADDR  KSEG_E
@@ -205,8 +216,14 @@
 
 	mymtd = do_cfi_probe(&axis_map);
 
+#ifdef CONFIG_MTD_AMDSTD
+	if (!mymtd) {
+		mymtd = do_amd_flash_probe(&axis_map);
+	}
+#endif
+
 	if(!mymtd) {
-		printk("cfi_probe erred %d\n", mymtd);
+		printk("%s: No flash chip found!\n", axis_map.name);
 		return -ENXIO;
 	}
 
@@ -218,7 +235,8 @@
 	 * now at least.
 	 */
 
-	ptable_head = FLASH_CACHED_ADDR + PTABLE_SECTOR + PARTITION_TABLE_OFFSET;
+	ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR +
+		PTABLE_SECTOR + PARTITION_TABLE_OFFSET);
 	pidx++;  /* first partition is always set to the default */
 
 	if ((ptable_head->magic == PARTITION_TABLE_MAGIC)
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/ethernet.c linux/arch/cris/drivers/ethernet.c
--- v2.4.3/linux/arch/cris/drivers/ethernet.c	Tue Feb 13 14:13:43 2001
+++ linux/arch/cris/drivers/ethernet.c	Fri Apr  6 10:42:55 2001
@@ -1,12 +1,23 @@
-/* $Id: ethernet.c,v 1.5 2000/11/29 17:22:22 bjornw Exp $
+/* $Id: ethernet.c,v 1.8 2001/02/27 13:52:48 bjornw Exp $
  *
  * e100net.c: A network driver for the ETRAX 100LX network controller.
  *
- * Copyright (c) 1998-2000 Axis Communications AB.
+ * Copyright (c) 1998-2001 Axis Communications AB.
  *
  * The outline of this driver comes from skeleton.c.
  *
  * $Log: ethernet.c,v $
+ * Revision 1.8  2001/02/27 13:52:48  bjornw
+ * malloc.h -> slab.h
+ *
+ * Revision 1.7  2001/02/23 13:46:38  bjornw
+ * Spellling check
+ *
+ * Revision 1.6  2001/01/26 15:21:04  starvik
+ * Don't disable interrupts while reading MDIO registers (MDIO is slow)
+ * Corrected promiscuous mode
+ * Improved deallocation of IRQs ("ifconfig eth0 down" now works)
+ *
  * Revision 1.5  2000/11/29 17:22:22  bjornw
  * Get rid of the udword types legacy stuff
  *
@@ -39,7 +50,7 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/string.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -53,7 +64,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
-#include <asm/svinto.h>
+#include <asm/svinto.h>     /* DMA and register descriptions */
 
 //#define ETHDEBUG
 
@@ -483,9 +494,6 @@
 	unsigned short data;   /* Data read from MDIO */
 	int bitCounter;
 	
-	save_flags(flags);
-	cli();
-	
 	/* Start of frame, OP Code, Physical Address, Register Address */
 	cmd = (MDIO_START << 14) | (MDIO_READ << 12) | (MDIO_PHYS_ADDR << 7) |
 		(reg_num << 2);
@@ -498,8 +506,7 @@
 	for(bitCounter=15; bitCounter>=0 ; bitCounter--) {
 		data |= (e100_receive_mdio_bit() << bitCounter);
 	}
-	
-	restore_flags(flags);
+
 	return data;
 }
 
@@ -555,9 +562,6 @@
 	unsigned short data;
 	int bitCounter;
 
-	save_flags(flags);
-	cli();
-
 	data = e100_get_mdio_reg(MDIO_BASE_CONTROL_REG);
 
 	cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (MDIO_PHYS_ADDR << 7) | (MDIO_BASE_CONTROL_REG << 2);
@@ -569,8 +573,6 @@
 	for(bitCounter = 15; bitCounter >= 0 ; bitCounter--) {
 		e100_send_mdio_bit(GET_BIT(bitCounter, data));
 	}
-	
-	restore_flags(flags);
 }
 
 /* Called by upper layers if they decide it took too long to complete
@@ -858,9 +860,9 @@
 
 	/* Flush the Tx and disable Rx here. */
 
-	free_irq(NETWORK_DMARX_IRQ, NULL);
-	free_irq(NETWORK_DMATX_IRQ, NULL);
-	free_irq(NETWORK_STATUS_IRQ, NULL);
+	free_irq(NETWORK_DMARX_IRQ, (void *)dev);
+	free_irq(NETWORK_DMATX_IRQ, (void *)dev);
+	free_irq(NETWORK_STATUS_IRQ, (void *)dev);
 
 	free_dma(0);
 	free_dma(1);
@@ -926,10 +928,21 @@
 		/* promiscuous mode */
 		lo_bits = 0xfffffffful;
 		hi_bits = 0xfffffffful;
+
+                /* Enable individual receive */
+		*R_NETWORK_REC_CONFIG =
+		  IO_STATE(R_NETWORK_REC_CONFIG, broadcast,  receive) |
+		  IO_STATE(R_NETWORK_REC_CONFIG, ma0,        enable) |
+		  IO_STATE(R_NETWORK_REC_CONFIG, individual, receive);
 	} else if (num_addr == 0) {
 		/* Normal, clear the mc list */
 		lo_bits = 0x00000000ul;
 		hi_bits = 0x00000000ul;
+
+                /* Disable individual receive */
+		*R_NETWORK_REC_CONFIG =
+		  IO_STATE(R_NETWORK_REC_CONFIG, broadcast,  receive) |
+		  IO_STATE(R_NETWORK_REC_CONFIG, ma0,        enable);
 	} else {
 		/* MC mode, receive normal and MC packets */
 		char hash_ix;
@@ -971,6 +984,10 @@
 			}
 			dmi = dmi->next;
 		}
+                /* Disable individual receive */
+		*R_NETWORK_REC_CONFIG =
+		  IO_STATE(R_NETWORK_REC_CONFIG, broadcast,  receive) |
+		  IO_STATE(R_NETWORK_REC_CONFIG, ma0,        enable);
 	}
 	*R_NETWORK_GA_0 = lo_bits;
 	*R_NETWORK_GA_1 = hi_bits;
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/examples/kiobuftest.c linux/arch/cris/drivers/examples/kiobuftest.c
--- v2.4.3/linux/arch/cris/drivers/examples/kiobuftest.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/examples/kiobuftest.c	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,108 @@
+/*
+ * Example showing how to pin down a range of virtual pages from user-space
+ * to be able to do for example DMA directly into them.
+ *
+ * It is necessary because the pages the virtual pointers reference, might
+ * not exist in memory (could be mapped to the zero-page, filemapped etc)
+ * and DMA cannot trigger the MMU to force them in (and would have time 
+ * contraints making it impossible to wait for it anyway).
+ *
+ * Author:  Bjorn Wesen
+ *
+ * $Log: kiobuftest.c,v $
+ * Revision 1.2  2001/02/27 13:52:50  bjornw
+ * malloc.h -> slab.h
+ *
+ * Revision 1.1  2001/01/19 15:57:49  bjornw
+ * Example of how to do direct HW -> user-mode DMA
+ *
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/iobuf.h>
+
+#define KIOBUFTEST_MAJOR 124  /* in the local range, experimental */
+
+
+static ssize_t
+kiobuf_read(struct file *filp, char *buf, size_t len, loff_t *ppos)
+{
+
+     struct kiobuf *iobuf;
+     int res, i;
+ 
+     /* Make a kiobuf that maps the entire length the reader has given
+      * us
+      */
+
+     res = alloc_kiovec(1, &iobuf);
+     if (res)
+	     return res;
+     
+     if((res = map_user_kiobuf(READ, iobuf, (unsigned long)buf, len))) {
+	     printk("map_user_kiobuf failed, return %d\n", res);
+	     return res;
+     }
+
+     /* At this point, the virtual area buf[0] -> buf[len-1] will
+      * have corresponding pages mapped in physical memory and locked
+      * until we unmap the kiobuf. They cannot be swapped out or moved
+      * around.
+      */
+
+     printk("nr_pages == %d\noffset == %d\nlength == %d\n",
+	    iobuf->nr_pages, iobuf->offset, iobuf->length);
+
+     for(i = 0; i < iobuf->nr_pages; i++) {
+	     printk("page_add(maplist[%d]) == 0x%x\n", i,
+		    page_address(iobuf->maplist[i]));
+     }
+
+     /* This is the place to create the necessary scatter-gather vector
+      * for the DMA using the iobuf->maplist array and page_address
+      * (don't forget __pa if the DMA needs the actual physical DRAM address)
+      * and run it.
+      */
+
+
+
+
+     /* Release the mapping and exit */
+
+     unmap_kiobuf(iobuf); /* The unlock_kiobuf is implicit here */
+
+     return len;
+}
+
+
+static struct file_operations kiobuf_fops = {
+	owner:    THIS_MODULE,
+	read:     kiobuf_read
+};
+
+static int __init
+kiobuftest_init(void)
+{
+	int res;
+
+	/* register char device */
+
+	res = register_chrdev(KIOBUFTEST_MAJOR, "kiobuftest", &kiobuf_fops);
+	if(res < 0) {
+		printk(KERN_ERR "kiobuftest: couldn't get a major number.\n");
+		return res;
+	}
+
+	printk("Initializing kiobuf-test device\n");
+}
+
+module_init(kiobuftest_init);
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/gpio.c linux/arch/cris/drivers/gpio.c
--- v2.4.3/linux/arch/cris/drivers/gpio.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/gpio.c	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,298 @@
+/* $Id: gpio.c,v 1.4 2001/02/27 13:52:48 bjornw Exp $
+ *
+ * Etrax general port I/O device
+ *
+ * Copyright (c) 1999, 2000, 2001 Axis Communications AB
+ *
+ * Authors:    Bjorn Wesen      (initial version)
+ *             Ola Knutsson     (LED handling)
+ *             Johan Adolfsson  (read/set directions)
+ *
+ * $Log: gpio.c,v $
+ * Revision 1.4  2001/02/27 13:52:48  bjornw
+ * malloc.h -> slab.h
+ *
+ * Revision 1.3  2001/01/24 15:06:48  bjornw
+ * gpio_wq correct type
+ *
+ * Revision 1.2  2001/01/18 16:07:30  bjornw
+ * 2.4 port
+ *
+ * Revision 1.1  2001/01/18 15:55:16  bjornw
+ * Verbatim copy of etraxgpio.c from elinux 2.0 added
+ *
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+
+#include <asm/etraxgpio.h>
+#include <asm/svinto.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#define GPIO_MAJOR 120  /* experimental MAJOR number */
+
+#define D(x)
+
+static char gpio_name[] = "etrax gpio";
+
+static wait_queue_head_t *gpio_wq;
+
+static int gpio_ioctl(struct inode *inode, struct file *file,
+		      unsigned int cmd, unsigned long arg);
+static int gpio_open(struct inode *inode, struct file *filp);
+static int gpio_release(struct inode *inode, struct file *filp);
+static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
+
+/* private data per open() of this driver */
+
+struct gpio_private {
+	struct gpio_private *next;
+	volatile unsigned char *port, *shadow;
+	volatile unsigned char *dir, *dir_shadow;
+	unsigned char changeable_dir;
+	unsigned char changeable_bits;
+	unsigned char highalarm, lowalarm;
+	wait_queue_head_t alarm_wq;
+	int minor;
+};
+
+/* linked list of alarms to check for */
+
+static struct gpio_private *alarmlist = 0;
+
+#define NUM_PORTS 2
+static volatile unsigned char *ports[2] = { R_PORT_PA_DATA, R_PORT_PB_DATA };
+static volatile unsigned char *shads[2] = {
+	&port_pa_data_shadow, &port_pb_data_shadow };
+
+/* What direction bits that are user changeable 1=changeable*/
+#ifndef CONFIG_PA_CHANGEABLE_DIR
+#define CONFIG_PA_CHANGEABLE_DIR 0x00
+#endif
+#ifndef CONFIG_PB_CHANGEABLE_DIR
+#define CONFIG_PB_CHANGEABLE_DIR 0x00
+#endif
+
+#ifndef CONFIG_PA_CHANGEABLE_BITS
+#define CONFIG_PA_CHANGEABLE_BITS 0xFF
+#endif
+#ifndef CONFIG_PB_CHANGEABLE_BITS
+#define CONFIG_PB_CHANGEABLE_BITS 0xFF
+#endif
+
+
+static unsigned char changeable_dir[2] = { CONFIG_PA_CHANGEABLE_DIR,
+                                           CONFIG_PB_CHANGEABLE_DIR };
+static unsigned char changeable_bits[2] = { CONFIG_PA_CHANGEABLE_BITS,
+                                            CONFIG_PB_CHANGEABLE_BITS };
+
+static volatile unsigned char *dir[2] = { R_PORT_PA_DIR, R_PORT_PB_DIR };
+
+static volatile unsigned char *dir_shadow[2] = {
+	&port_pa_dir_shadow, &port_pb_dir_shadow };
+
+#define LEDS 2
+
+static unsigned int 
+gpio_poll(struct file *filp,
+	  struct poll_table_struct *wait)
+{
+	/* TODO poll on alarms! */
+#if 0
+        if(!ANYTHING_WANTED) {
+		D(printk("gpio_select sleeping task\n"));
+	        select_wait(&gpio_wq, table);
+	        return 0;
+	}
+	D(printk("gpio_select ready\n"));
+#endif
+	return 1;
+}
+
+static int
+gpio_open(struct inode *inode, struct file *filp)
+{
+	struct gpio_private *priv;
+	int p = MINOR(inode->i_rdev);
+
+	if(p >= NUM_PORTS && p != LEDS)
+		return -EINVAL;
+
+	priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private), 
+					      GFP_KERNEL);
+
+	if(!priv)
+		return -ENOMEM;
+
+	priv->minor = p;
+
+	/* initialize the io/alarm struct and link it into our alarmlist */
+
+	priv->next = alarmlist;
+	alarmlist = priv;
+	priv->port = ports[p];
+	priv->shadow = shads[p];
+
+	priv->changeable_dir = changeable_dir[p];
+	priv->changeable_bits = changeable_bits[p];
+	priv->dir = dir[p];
+	priv->dir_shadow = dir_shadow[p];
+
+	priv->highalarm = 0;
+	priv->lowalarm = 0;
+	init_waitqueue_head(&priv->alarm_wq);
+
+	filp->private_data = (void *)priv;
+
+	return 0;
+}
+
+static int
+gpio_release(struct inode *inode, struct file *filp)
+{
+	struct gpio_private *p = alarmlist;
+	struct gpio_private *todel = (struct gpio_private *)filp->private_data;
+
+	/* unlink from alarmlist and free the private structure */
+
+	if(p == todel) {
+		alarmlist = todel->next;
+	} else {
+		while(p->next != todel)
+			p = p->next;
+		p->next = todel->next;
+	}
+
+	kfree(todel);
+
+	return 0;
+}
+
+/* Main device API. ioctl's to read/set/clear bits, as well as to 
+ * set alarms to wait for using a subsequent select().
+ */
+
+static int
+gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
+
+static int
+gpio_ioctl(struct inode *inode, struct file *file,
+	   unsigned int cmd, unsigned long arg)
+{
+	struct gpio_private *priv = (struct gpio_private *)file->private_data;
+
+	if(_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
+		return -EINVAL;
+	}
+
+	switch (_IOC_NR(cmd)) {
+		case IO_READBITS:
+			// read the port
+			return *priv->port;
+		case IO_SETBITS:
+			// set changeable bits with a 1 in arg
+			*priv->port = *priv->shadow |= 
+			  ((unsigned char)arg & priv->changeable_bits);
+			break;
+		case IO_CLRBITS:
+			// clear changeable bits with a 1 in arg
+			*priv->port = *priv->shadow &= 
+			  ~((unsigned char)arg & priv->changeable_bits);
+			break;
+		case IO_HIGHALARM:
+			// set alarm when bits with 1 in arg go high
+			priv->highalarm |= (unsigned char)arg;
+			break;
+		case IO_LOWALARM:
+			// set alarm when bits with 1 in arg go low
+			priv->lowalarm |= (unsigned char)arg;
+			break;
+		case IO_CLRALARM:
+			// clear alarm for bits with 1 in arg
+			priv->highalarm &= ~(unsigned char)arg;
+			priv->lowalarm  &= ~(unsigned char)arg;
+			break;
+		case IO_READDIR:
+			/* Read direction 0=input 1=output */
+			return *priv->dir_shadow;
+		case IO_SETINPUT:
+			/* Set direction 0=unchanged 1=input */
+			*priv->dir = *priv->dir_shadow &= 
+			~((unsigned char)arg & priv->changeable_dir);
+			return *priv->dir_shadow;
+		case IO_SETOUTPUT:
+			/* Set direction 0=unchanged 1=output */
+			*priv->dir = *priv->dir_shadow |= 
+			  ((unsigned char)arg & priv->changeable_dir);
+			return *priv->dir_shadow;
+		default:
+			if(priv->minor == LEDS)
+				return gpio_leds_ioctl(cmd, arg);
+			else
+				return -EINVAL;
+	}
+	
+	return 0;
+}
+
+static int
+gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
+{
+	unsigned char green;
+	unsigned char red;
+
+	switch (_IOC_NR(cmd)) {
+		case IO_LEDACTIVE_SET:
+			green = ((unsigned char) arg) & 1;
+			red   = (((unsigned char) arg) >> 1) & 1;
+			LED_ACTIVE_SET_G(green);
+			LED_ACTIVE_SET_R(red);
+			break;
+		default:
+			return -EINVAL;
+	}
+}
+
+struct file_operations gpio_fops = {
+	owner:       THIS_MODULE,
+	poll:        gpio_poll,
+	ioctl:       gpio_ioctl,
+	open:        gpio_open,
+	release:     gpio_release,
+};
+
+/* main driver initialization routine, called from mem.c */
+
+static __init int
+gpio_init(void)
+{
+	int res;
+
+	/* do the formalities */
+
+	res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
+	if(res < 0) {
+		printk(KERN_ERR "gpio: couldn't get a major number.\n");
+		return res;
+	}
+	
+	printk("ETRAX 100LX GPIO driver v2.1, (c) 2001 Axis Communications AB\n");
+
+	return res;
+}
+
+/* this makes sure that gpio_init is called during kernel boot */
+
+module_init(gpio_init);
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/i2c.c linux/arch/cris/drivers/i2c.c
--- v2.4.3/linux/arch/cris/drivers/i2c.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/i2c.c	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,691 @@
+/*!***************************************************************************
+*!
+*! FILE NAME  : i2c.c
+*!
+*! DESCRIPTION: implements an interface for IIC/I2C, both directly from other
+*!              kernel modules (i2c_writereg/readreg) and from userspace using
+*!              ioctl()'s
+*!
+*! Nov 30 1998  Torbjorn Eliasson  Initial version.
+*!              Bjorn Wesen        Elinux kernel version.
+*! Jan 14 2000  Johan Adolfsson    Fixed PB shadow register stuff - 
+*!                                 don't use PB_I2C if DS1302 uses same bits,
+*!                                 use PB.
+*! $Log: i2c.c,v $
+*! Revision 1.5  2001/02/27 13:52:48  bjornw
+*! malloc.h -> slab.h
+*!
+*! Revision 1.4  2001/02/15 07:17:40  starvik
+*! Corrected usage if port_pb_i2c_shadow
+*!
+*! Revision 1.3  2001/01/26 17:55:13  bjornw
+*! * Made I2C_USES_PB_NOT_PB_I2C a CONFIG option instead of assigning it
+*!   magically. Config.in needs to set it for the options that need it, like
+*!   Dallas 1302 support. Actually, it should be default since it screws up
+*!   the PB bits even if you don't use I2C..
+*! * Include linux/config.h to get the above
+*!
+*! Revision 1.2  2001/01/18 15:49:30  bjornw
+*! 2.4 port of I2C including some cleanups (untested of course)
+*!
+*! Revision 1.1  2001/01/18 15:35:25  bjornw
+*! Verbatim copy of the Etrax i2c driver, 2.0 elinux version
+*!
+*!
+*! ---------------------------------------------------------------------------
+*!
+*! (C) Copyright 1999, 2000, 2001 Axis Communications AB, LUND, SWEDEN
+*!
+*!***************************************************************************/
+/* $Id: i2c.c,v 1.5 2001/02/27 13:52:48 bjornw Exp $ */
+/****************** INCLUDE FILES SECTION ***********************************/
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/config.h>
+
+#include <asm/etraxi2c.h>
+
+#include <asm/system.h>
+#include <asm/svinto.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+
+#include "i2c.h"
+
+/****************** I2C DEFINITION SECTION *************************/
+
+#define D(x)
+
+#define I2C_MAJOR 123  /* LOCAL/EXPERIMENTAL */
+static const char i2c_name[] = "i2c";
+
+#define CLOCK_LOW_TIME            8
+#define CLOCK_HIGH_TIME           8
+#define START_CONDITION_HOLD_TIME 8
+#define STOP_CONDITION_HOLD_TIME  8
+#define ENABLE_OUTPUT 0x01
+#define ENABLE_INPUT 0x00
+#define I2C_CLOCK_HIGH 1
+#define I2C_CLOCK_LOW 0
+#define I2C_DATA_HIGH 1
+#define I2C_DATA_LOW 0
+
+#if 0
+/* TODO: fix this so the CONFIG_ETRAX_I2C_USES... is set in Config.in instead */
+#if defined(CONFIG_DS1302) && (CONFIG_DS1302_SDABIT==0) && \
+           (CONFIG_DS1302_SCLBIT == 1)
+#define CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
+#endif
+#endif
+
+#ifdef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
+/* Use PB and not PB_I2C */
+#define SDABIT 0
+#define SCLBIT 1
+#define i2c_enable() 
+#define i2c_disable() 
+
+/* enable or disable output-enable, to select output or input on the i2c bus */
+
+#define i2c_dir_out() \
+  REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, SDABIT, 1)
+#define i2c_dir_in()  \
+  REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, SDABIT, 0)
+
+/* control the i2c clock and data signals */
+
+#define i2c_clk(x) \
+  REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, SCLBIT, x)
+#define i2c_data(x) \
+  REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, SDABIT, x)
+
+/* read a bit from the i2c interface */
+
+#define i2c_getbit() (*R_PORT_PB_READ & (1 << SDABIT))
+
+#else
+/* enable or disable the i2c interface */
+
+#define i2c_enable() *R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_en))
+#define i2c_disable() *R_PORT_PB_I2C = (port_pb_i2c_shadow &= ~IO_MASK(R_PORT_PB_I2C, i2c_en))
+
+/* enable or disable output-enable, to select output or input on the i2c bus */
+
+#define i2c_dir_out() *R_PORT_PB_I2C = (port_pb_i2c_shadow &= ~IO_MASK(R_PORT_PB_I2C, i2c_oe_))
+#define i2c_dir_in() *R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_oe_))
+
+/* control the i2c clock and data signals */
+
+#define i2c_clk(x) *R_PORT_PB_I2C = (port_pb_i2c_shadow = (port_pb_i2c_shadow & \
+       ~IO_MASK(R_PORT_PB_I2C, i2c_clk)) | IO_FIELD(R_PORT_PB_I2C, i2c_clk, (x)))
+
+#define i2c_data(x) *R_PORT_PB_I2C = (port_pb_i2c_shadow = (port_pb_i2c_shadow & \
+       ~IO_MASK(R_PORT_PB_I2C, i2c_d)) | IO_FIELD(R_PORT_PB_I2C, i2c_d, (x)))
+
+/* read a bit from the i2c interface */
+
+#define i2c_getbit() (*R_PORT_PB_READ & 0x1)
+#endif
+
+/* use the kernels delay routine */
+
+#define i2c_delay(usecs) udelay(usecs)
+
+
+/****************** FUNCTION DEFINITION SECTION *************************/
+
+
+/* generate i2c start condition */
+
+static void
+i2c_start(void)
+{
+	//
+	// SCL=1 SDA=1
+	//
+	i2c_dir_out();
+	i2c_delay(CLOCK_HIGH_TIME/6);
+	i2c_data(I2C_DATA_HIGH);
+	i2c_clk(I2C_CLOCK_HIGH);
+	i2c_delay(CLOCK_HIGH_TIME);
+	//
+	// SCL=1 SDA=0
+	//
+	i2c_data(I2C_DATA_LOW);
+	i2c_delay(START_CONDITION_HOLD_TIME);
+	//
+	// SCL=0 SDA=0
+	//
+	i2c_clk(I2C_CLOCK_LOW);
+	i2c_delay(CLOCK_LOW_TIME);
+}
+
+/* generate i2c stop condition */
+
+static void
+i2c_stop(void)
+{
+	i2c_dir_out();
+
+	//
+	// SCL=0 SDA=0
+	//
+	i2c_clk(I2C_CLOCK_LOW);
+	i2c_data(I2C_DATA_LOW);
+	i2c_delay(CLOCK_LOW_TIME*2);
+	//
+	// SCL=1 SDA=0
+	//
+	i2c_clk(I2C_CLOCK_HIGH);
+	i2c_delay(CLOCK_HIGH_TIME*2);
+	//
+	// SCL=1 SDA=1
+	//
+	i2c_data(I2C_DATA_HIGH);
+	i2c_delay(STOP_CONDITION_HOLD_TIME);
+
+	i2c_dir_in();
+}
+
+/* write a byte to the i2c interface */
+
+static void
+i2c_outbyte(unsigned char x)
+{
+	int i;
+	
+	i2c_dir_out();
+
+	for (i = 0; i < 8; i++) {
+		if (x & 0x80)
+			i2c_data(I2C_DATA_HIGH);
+		else
+			i2c_data(I2C_DATA_LOW);
+		
+		i2c_delay(CLOCK_LOW_TIME/2);
+		i2c_clk(I2C_CLOCK_HIGH);
+		i2c_delay(CLOCK_HIGH_TIME);
+		i2c_clk(I2C_CLOCK_LOW);
+		i2c_delay(CLOCK_LOW_TIME/2);
+		x <<= 1;
+	}
+	i2c_data(I2C_DATA_LOW);
+	i2c_delay(CLOCK_LOW_TIME/2);
+
+	//
+	// enable input
+	//
+	i2c_dir_in();
+}
+
+/* read a byte from the i2c interface */
+
+static unsigned char
+i2c_inbyte(void)
+{
+	unsigned char aBitByte = 0;
+	int i;
+	int iaa;
+	//int dd= 0;
+
+	//
+	// enable output
+	//
+	i2c_dir_out();
+	//
+	// Release data bus by setting
+	// data high
+	//
+	i2c_data(I2C_DATA_HIGH);
+	//
+	// enable input
+	//
+	i2c_dir_in();
+	//
+	// Use PORT PB instead of I2C
+	// for input. (I2C not working)
+	//
+	i2c_clk(1);
+	i2c_data(1);
+/*	*R_PORT_PB_DATA = *R_PORT_PB_READ | 0x03;*/
+	//
+	// get bits
+	//
+	for (i = 0; i < 8; i++) {
+		i2c_delay(CLOCK_LOW_TIME/2);
+		//
+		// low clock period
+		//
+		i2c_clk(I2C_CLOCK_HIGH);
+		//
+		// switch off I2C
+		//
+		i2c_data(1);
+		i2c_disable();
+		i2c_dir_in();
+		//
+		// wait before getting bit
+		//
+		i2c_delay(CLOCK_HIGH_TIME/2);
+		aBitByte = (aBitByte << 1);
+		iaa = i2c_getbit();
+		aBitByte = aBitByte | iaa ;
+		//if (iaa > 0) dd++;
+		//
+		// wait
+		//
+		i2c_delay(CLOCK_HIGH_TIME/2);
+		//
+		// end clock puls
+		//
+		i2c_enable();
+		i2c_dir_out();
+		i2c_clk(I2C_CLOCK_LOW);
+		//
+		// low clock period
+		//
+		i2c_delay(CLOCK_LOW_TIME/2);
+	}
+	i2c_dir_out();
+	return aBitByte;
+}
+
+/*#---------------------------------------------------------------------------
+*#
+*# FUNCTION NAME: i2c_getack
+*#
+*# DESCRIPTION  : checks if ack was received from ic2
+*#
+*#--------------------------------------------------------------------------*/
+
+static int
+i2c_getack(void)
+{
+	int ack = 1;
+	//
+	// enable output
+	//
+	i2c_dir_out();
+	//
+	// Release data bus by setting
+	// data high
+	//
+	i2c_data(I2C_DATA_HIGH);
+	//
+	// enable input
+	//
+	i2c_dir_in();
+	i2c_delay(CLOCK_HIGH_TIME/4);
+	//
+	// generate ACK clock pulse
+	//
+	i2c_clk(I2C_CLOCK_HIGH);
+	//
+	// Use PORT PB instead of I2C
+	// for input. (I2C not working)
+	//
+	i2c_clk(1);
+	i2c_data(1);
+  
+/*	*R_PORT_PB_DATA = *R_PORT_PB_READ | 0x03;*/
+	//
+	// switch off I2C
+	//
+	i2c_data(1);
+	i2c_disable();
+	i2c_dir_in();
+	//
+	// now wait for ack
+	//
+	i2c_delay(CLOCK_HIGH_TIME/2);
+	//
+	// check for ack
+	//
+	if(i2c_getbit())
+		ack = 0;
+	i2c_delay(CLOCK_HIGH_TIME/2);
+	if(!ack){
+		if(!i2c_getbit()) /* receiver pulld SDA low */
+			ack = 1;
+		i2c_delay(CLOCK_HIGH_TIME/2);
+	}
+
+	//
+	// end clock pulse
+	//
+	i2c_enable();
+	i2c_dir_out();
+	i2c_clk(I2C_CLOCK_LOW);
+	i2c_delay(CLOCK_HIGH_TIME/4);
+	//
+	// enable output
+	//
+	i2c_dir_out();
+	//
+	// remove ACK clock pulse
+	//
+	i2c_data(I2C_DATA_HIGH);
+	i2c_delay(CLOCK_LOW_TIME/2);
+	return ack;
+}
+
+/*#---------------------------------------------------------------------------
+*#
+*# FUNCTION NAME: I2C::sendAck
+*#
+*# DESCRIPTION  : Send ACK on received data
+*#
+*#--------------------------------------------------------------------------*/
+static void
+i2c_sendack(void)
+{
+	//
+	// enable output
+	//
+	i2c_delay(CLOCK_LOW_TIME);
+	i2c_dir_out();
+	//
+	// set ack pulse high
+	//
+	i2c_data(I2C_DATA_LOW);
+	//
+	// generate clock pulse
+	//
+	i2c_delay(CLOCK_HIGH_TIME/6);
+	i2c_clk(I2C_CLOCK_HIGH);
+	i2c_delay(CLOCK_HIGH_TIME);
+	i2c_clk(I2C_CLOCK_LOW);
+	i2c_delay(CLOCK_LOW_TIME/6);
+	//
+	// reset data out
+	//
+	i2c_data(I2C_DATA_HIGH);
+	i2c_delay(CLOCK_LOW_TIME);
+	//
+	i2c_dir_in();
+}
+
+/*#---------------------------------------------------------------------------
+*#
+*# FUNCTION NAME: i2c_writereg
+*#
+*# DESCRIPTION  : Writes a value to an I2C device
+*#
+*#--------------------------------------------------------------------------*/
+int
+i2c_writereg(unsigned char theSlave, unsigned char theReg,
+	     unsigned char theValue)
+{
+	int error, cntr = 3;
+		
+	do {
+		error = 0;
+		//
+		// we don't like to be interrupted
+		//
+		cli();
+		//
+		// generate start condition
+		//
+		i2c_start();
+		//
+		// dummy preamble
+		//
+		i2c_outbyte(0x01);
+		i2c_data(I2C_DATA_HIGH);
+		i2c_clk(I2C_CLOCK_HIGH);
+		i2c_delay(CLOCK_HIGH_TIME); /* Dummy Acknowledge */
+		i2c_clk(I2C_CLOCK_LOW);
+		i2c_delay(CLOCK_LOW_TIME);
+		i2c_clk(I2C_CLOCK_HIGH);
+		i2c_delay(CLOCK_LOW_TIME); /* Repeated Start Condition */
+		i2c_data(I2C_DATA_LOW);
+		i2c_delay(CLOCK_HIGH_TIME);
+		i2c_clk(I2C_CLOCK_LOW);
+		i2c_delay(CLOCK_LOW_TIME);
+
+		i2c_start();
+		//
+		// send slave address
+		//
+		i2c_outbyte(theSlave);
+		//
+		// wait for ack
+		//
+		if(!i2c_getack())
+			error = 1;
+		//
+		// now select register
+		//
+		i2c_dir_out();
+		i2c_outbyte(theReg);
+		//
+		// now it's time to wait for ack
+		//
+		if(!i2c_getack())
+			error |= 2;
+		//
+		// send register register data
+		//
+		i2c_outbyte(theValue);
+		//
+		// now it's time to wait for ack
+		//
+		if(!i2c_getack())
+			error |= 4;
+		//
+		// end byte stream
+		//
+		i2c_stop();
+		//
+		// enable interrupt again
+		//
+		sti();
+		
+	} while(error && cntr--);
+	
+	i2c_delay(CLOCK_LOW_TIME);
+	
+	return -error;
+}
+
+/*#---------------------------------------------------------------------------
+*#
+*# FUNCTION NAME: i2c_readreg
+*#
+*# DESCRIPTION  : Reads a value from the decoder registers.
+*#
+*#--------------------------------------------------------------------------*/
+unsigned char
+i2c_readreg(unsigned char theSlave, unsigned char theReg)
+{
+	unsigned char b = 0;
+	int error, cntr = 3;
+		
+	do {
+		error = 0;
+		//
+		// we don't like to be interrupted
+		//
+		cli();
+		//
+		// generate start condition
+		//
+		i2c_start();
+		//
+		// dummy preamble
+		//
+		i2c_outbyte(0x01);
+		i2c_data(I2C_DATA_HIGH);
+		i2c_clk(I2C_CLOCK_HIGH);
+		i2c_delay(CLOCK_HIGH_TIME); /* Dummy Acknowledge */
+		i2c_clk(I2C_CLOCK_LOW);
+		i2c_delay(CLOCK_LOW_TIME);
+		i2c_clk(I2C_CLOCK_HIGH);
+		i2c_delay(CLOCK_LOW_TIME); /* Repeated Start Condition */
+		i2c_data(I2C_DATA_LOW);
+		i2c_delay(CLOCK_HIGH_TIME);
+		i2c_clk(I2C_CLOCK_LOW);
+		i2c_delay(CLOCK_LOW_TIME);
+    
+		i2c_start();
+    
+		//
+		// send slave address
+		//
+		i2c_outbyte(theSlave);
+		//
+		// wait for ack
+		//
+		if(!i2c_getack())
+			error = 1;
+		//
+		// now select register
+		//
+		i2c_dir_out();
+		i2c_outbyte(theReg);
+		//
+		// now it's time to wait for ack
+		//
+		if(!i2c_getack())
+			error = 1;
+		//
+		// repeat start condition
+		//
+		i2c_delay(CLOCK_LOW_TIME);
+		i2c_start();
+		//
+		// send slave address
+		//
+		i2c_outbyte(theSlave | 0x01);
+		//
+		// wait for ack
+		//
+		if(!i2c_getack())
+			error = 1;
+		//
+		// fetch register
+		//
+		b = i2c_inbyte();
+		//
+		// send Ack
+		//
+		i2c_sendack();
+		//
+		// end sequence
+		//
+		i2c_stop();
+		//
+		// enable interrupt again
+		//
+		sti();	
+	} while(error && cntr--);
+
+	return b;
+}
+
+static int
+i2c_open(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+static int
+i2c_release(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+/* Main device API. ioctl's to write or read to/from i2c registers.
+ */
+
+static int
+i2c_ioctl(struct inode *inode, struct file *file,
+	  unsigned int cmd, unsigned long arg)
+{
+	if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) {
+		return -EINVAL;
+	}
+
+	switch (_IOC_NR(cmd)) {
+		case I2C_WRITEREG:
+			// write to an i2c slave
+			D(printk("i2cw %d %d %d\n", 
+				 I2C_ARGSLAVE(arg),
+				 I2C_ARGREG(arg),
+				 I2C_ARGVALUE(arg)));
+
+			return i2c_writereg(I2C_ARGSLAVE(arg),
+					    I2C_ARGREG(arg),
+					    I2C_ARGVALUE(arg));
+		case I2C_READREG:
+		{
+			unsigned char val;
+			// read from an i2c slave
+			D(printk("i2cr %d %d ", 
+				I2C_ARGSLAVE(arg),
+				I2C_ARGREG(arg)));
+			val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
+			D(printk("= %d\n", val));
+			return val;
+		}					    
+		default:
+			return -EINVAL;
+
+	}
+	
+	return 0;
+}
+
+static struct file_operations i2c_fops = {
+	owner:    THIS_MODULE,
+	ioctl:    i2c_ioctl,
+	open:     i2c_open,
+	release:  i2c_release,
+};
+
+static int __init
+i2c_init(void)
+{
+	int res;
+
+	/* Setup and enable the Port B I2C interface */
+
+#ifndef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
+	*R_PORT_PB_I2C = port_pb_i2c_shadow |= 
+		IO_STATE(R_PORT_PB_I2C, i2c_en,  on) |
+		IO_FIELD(R_PORT_PB_I2C, i2c_d,   1)  |
+		IO_FIELD(R_PORT_PB_I2C, i2c_clk, 1)  |
+		IO_STATE(R_PORT_PB_I2C, i2c_oe_, enable);
+#endif
+
+	port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir0);
+	port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir1);
+
+	*R_PORT_PB_DIR = (port_pb_dir_shadow |=
+			  IO_STATE(R_PORT_PB_DIR, dir0, input)  |
+			  IO_STATE(R_PORT_PB_DIR, dir1, output));
+
+	/* register char device */
+
+	res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops);
+	if(res < 0) {
+		printk(KERN_ERR "i2c: couldn't get a major number.\n");
+		return res;
+	}
+
+	printk("I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n");
+}
+
+/* this makes sure that i2c_init is called during boot */
+
+module_init(i2c_init);
+
+/****************** END OF FILE i2c.c ********************************/
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/i2c.h linux/arch/cris/drivers/i2c.h
--- v2.4.3/linux/arch/cris/drivers/i2c.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/i2c.h	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,16 @@
+/* $Id: i2c.h,v 1.2 2001/01/18 15:49:30 bjornw Exp $ */
+
+/* High level I2C actions */
+int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue);
+unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg);
+
+/* Low level I2C */
+static void i2c_start(void);
+static void i2c_stop(void);
+static void i2c_outbyte(unsigned char x);
+static unsigned char i2c_inbyte(void);
+static int i2c_getack(void);
+static void i2c_sendack(void);
+
+
+
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/ide.c linux/arch/cris/drivers/ide.c
--- v2.4.3/linux/arch/cris/drivers/ide.c	Tue Feb 13 14:13:43 2001
+++ linux/arch/cris/drivers/ide.c	Fri Apr  6 10:42:55 2001
@@ -1,4 +1,4 @@
-/* $Id: ide.c,v 1.4 2001/01/10 21:14:32 bjornw Exp $
+/* $Id: ide.c,v 1.9 2001/03/01 13:11:18 bjornw Exp $
  *
  * Etrax specific IDE functions, like init and PIO-mode setting etc.
  * Almost the entire ide.c is used for the rest of the Etrax ATA driver.
@@ -8,6 +8,23 @@
  *             Mikael Starvik     (pio setup stuff)
  *
  * $Log: ide.c,v $
+ * Revision 1.9  2001/03/01 13:11:18  bjornw
+ * 100 -> HZ
+ *
+ * Revision 1.8  2001/03/01 09:32:56  matsfg
+ * Moved IDE delay to a CONFIG-parameter instead
+ *
+ * Revision 1.7  2001/02/23 13:46:38  bjornw
+ * Spellling check
+ *
+ * Revision 1.6  2001/02/22 15:44:30  bjornw
+ * * Use ioremap when mapping the CSE1 memory-mapped reset-line for LX v2
+ * * sw_len for a 65536 descriptor is 0, not 65536
+ * * Express concern for G27 reset code
+ *
+ * Revision 1.5  2001/02/16 07:35:38  matsfg
+ * Now handles DMA request blocks between 64k and 128k by split into two descriptors.
+ *
  * Revision 1.4  2001/01/10 21:14:32  bjornw
  * Initialize hwif->ideproc, for the new way of handling ide_xxx_data
  *
@@ -63,8 +80,13 @@
 /* number of Etrax DMA descriptors */
 #define MAX_DMA_DESCRS 64
 
+#ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
+/* address where the memory-mapped IDE reset bit lives, if used */
+static volatile unsigned long *reset_addr;
+#endif
+
 #define LOWDB(x)
-#define D(x)
+#define D(x) 
 
 void OUT_BYTE(unsigned char data, ide_ioreg_t reg) {
 	LOWDB(printk("ob: data 0x%x, reg 0x%x\n", data, reg));
@@ -208,7 +230,8 @@
 static void e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
 			  void *buffer, unsigned int length);        /* defined below */
 
-void __init init_e100_ide (void)
+void __init 
+init_e100_ide (void)
 {
 	volatile unsigned int dummy;
 	int h;
@@ -226,6 +249,8 @@
 	}
 	/* actually reset and configure the etrax100 ide/ata interface */
 
+	/* This is mystifying; why is not G27 SET anywhere ? It's just reset here twice. */
+
 	/* de-assert bus-reset */
 #ifdef CONFIG_ETRAX_IDE_PB7_RESET  
 	port_pb_dir_shadow = port_pb_dir_shadow | 
@@ -252,7 +277,16 @@
 	*R_GEN_CONFIG = genconfig_shadow;
 
 #ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
-	*(volatile long *)(MEM_CSE1_START | MEM_NON_CACHEABLE) = 0;
+#ifndef CONFIG_CRIS_LOW_MAP
+	/* remap the I/O-mapped reset-bit from CSE1 to something inside our kernel space */
+	reset_addr = (unsigned long *)ioremap((unsigned long)(MEM_CSE1_START |
+							      MEM_NON_CACHEABLE), 16);
+	*reset_addr = 0;
+#else
+	/* LOW_MAP, can't do the ioremap, but it's already mapped straight over */
+	reset_addr = (unsigned long *)(MEM_CSE1_START | MEM_NON_CACHEABLE);
+	*reset_addr = 0;
+#endif
 #endif
 
 	/* wait some */
@@ -262,9 +296,11 @@
 	dummy = 3;
 
 #ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
-	*(volatile long *)(MEM_CSE1_START | MEM_NON_CACHEABLE) = 1 << 16;
-	*R_PORT_G_DATA = 0;  /* de-assert bus-reset */
+	*reset_addr = 1 << 16;
 #endif
+#ifdef CONFIG_ETRAX_IDE_G27_RESET
+	*R_PORT_G_DATA = 0; /* de-assert bus-reset */
+#endif 
 
 	/* make a dummy read to set the ata controller in a proper state */
 	dummy = *R_ATA_STATUS_DATA;
@@ -286,9 +322,9 @@
 			     IO_STATE( R_IRQ_MASK0_SET, ata_irq2, set ) |
 			     IO_STATE( R_IRQ_MASK0_SET, ata_irq3, set ) );
 
-	printk("ide: waiting 10 seconds for drives to regain consciousness\n");
+	printk("ide: waiting %d seconds for drives to regain consciousness\n", CONFIG_IDE_DELAY);
 
-	h = jiffies + 1000;
+	h = jiffies + (CONFIG_IDE_DELAY * HZ);
 	while(jiffies < h) ;
 
   /* reset the dma channels we will use */
@@ -560,14 +596,6 @@
 			return 1;
 		}
 
-		/* uh.. I'm lazy.. if size >= 65536, it should loop below and split it in
-		   more than one descriptor */
-
-		if(size >= 65536) {
-			printk("too large ATA DMA request block, size = %d!\n", size);
-			return 1;
-		}
-
 		/* however, this case is more difficult - R_ATA_TRANSFER_CNT cannot be more
 		   than 65536 words per transfer, so in that case we need to either 
 		   1) use a DMA interrupt to re-trigger R_ATA_TRANSFER_CNT and continue with
@@ -581,8 +609,22 @@
 			return 1;
 		}
 
-		/* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
+		/* If size > 65536 it has to be splitted into new descriptors. Since we don't handle 
+                   size > 131072 only one split is necessary */
 
+		if(size > 65536) {
+ 		        /* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
+                        ata_descrs[count].sw_len = 0;  /* 0 means 65536, this is a 16-bit field */
+                        ata_descrs[count].ctrl = 0;
+                        ata_descrs[count].buf = addr;
+                        ata_descrs[count].next = virt_to_phys(&ata_descrs[count + 1]);
+                        count++;
+                        ata_tot_size += 65536;
+                        /* size and addr should refere to not handled data */
+                        size -= 65536;
+                        addr += 65536;
+                }
+		/* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
 		ata_descrs[count].sw_len = size;
 		ata_descrs[count].ctrl = 0;
 		ata_descrs[count].buf = addr;
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/serial.c linux/arch/cris/drivers/serial.c
--- v2.4.3/linux/arch/cris/drivers/serial.c	Fri Mar  2 18:38:40 2001
+++ linux/arch/cris/drivers/serial.c	Fri Apr  6 10:42:55 2001
@@ -1,12 +1,26 @@
-/* $Id: serial.c,v 1.6 2000/11/22 16:36:09 bjornw Exp $
+/* $Id: serial.c,v 1.10 2001/03/05 13:14:07 bjornw Exp $
  *
  * Serial port driver for the ETRAX 100LX chip
  *
- *      Copyright (C) 1998, 1999, 2000  Axis Communications AB
+ *      Copyright (C) 1998, 1999, 2000, 2001  Axis Communications AB
  *
  *      Many, many authors. Based once upon a time on serial.c for 16x50.
  *
  * $Log: serial.c,v $
+ * Revision 1.10  2001/03/05 13:14:07  bjornw
+ * Another spelling fix
+ *
+ * Revision 1.9  2001/02/23 13:46:38  bjornw
+ * Spellling check
+ *
+ * Revision 1.8  2001/01/23 14:56:35  markusl
+ * Made use of ser1 optional
+ * Needed by USB
+ *
+ * Revision 1.7  2001/01/19 16:14:48  perf
+ * Added kernel options for serial ports 234.
+ * Changed option names from CONFIG_ETRAX100_XYZ to CONFIG_ETRAX_XYZ.
+ *
  * Revision 1.6  2000/11/22 16:36:09  bjornw
  * Please marketing by using the correct case when spelling Etrax.
  *
@@ -176,7 +190,7 @@
  *
  */
 
-static char *serial_version = "$Revision: 1.6 $";
+static char *serial_version = "$Revision: 1.10 $";
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -252,12 +266,12 @@
 //#define SERIAL_HANDLE_EARLY_ERRORS
 
 
-#ifndef CONFIG_ETRAX100_SERIAL_RX_TIMEOUT_TICKS
+#ifndef CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS
 /* Default number of timer ticks before flushing rx fifo 
  * When using "little data, low latency applications: use 0
  * When using "much data applications (PPP)" use ~5
  */
-#define CONFIG_ETRAX100_SERIAL_RX_TIMEOUT_TICKS 5 
+#define CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS 5 
 #endif
 
 #define MAX_FLUSH_TIME 8
@@ -367,36 +381,36 @@
 {
 /* Ser 0 */
   {
-#if defined(CONFIG_ETRAX100_SER0_DTR_RI_DSR_CD_ON_PB)
+#if defined(CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB)
     R_PORT_PB_DATA,  &port_pb_data_shadow,  &port_pb_dir_shadow,
-    CONFIG_ETRAX100_SER0_DTR_ON_PB_BIT,
-	  CONFIG_ETRAX100_SER0_RI_ON_PB_BIT, 
-	  CONFIG_ETRAX100_SER0_DSR_ON_PB_BIT, 
-	  CONFIG_ETRAX100_SER0_CD_ON_PB_BIT
+    CONFIG_ETRAX_SER0_DTR_ON_PB_BIT,
+    CONFIG_ETRAX_SER0_RI_ON_PB_BIT, 
+    CONFIG_ETRAX_SER0_DSR_ON_PB_BIT, 
+    CONFIG_ETRAX_SER0_CD_ON_PB_BIT
 #else
     &dummy_ser0, &dummy_ser0, &dummy_dir_ser0, 0, 1, 2, 3
 #endif   
   },
 /* Ser 1 */
   {
-#if defined(CONFIG_ETRAX100_SER1_DTR_RI_DSR_CD_ON_PB)
+#if defined(CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PB)
     R_PORT_PB_DATA,  &port_pb_data_shadow,  &port_pb_dir_shadow,
-    CONFIG_ETRAX100_SER1_DTR_ON_PB_BIT,
-	  CONFIG_ETRAX100_SER1_RI_ON_PB_BIT, 
-	  CONFIG_ETRAX100_SER1_DSR_ON_PB_BIT, 
-	  CONFIG_ETRAX100_SER1_CD_ON_PB_BIT
+    CONFIG_ETRAX_SER1_DTR_ON_PB_BIT,
+    CONFIG_ETRAX_SER1_RI_ON_PB_BIT, 
+    CONFIG_ETRAX_SER1_DSR_ON_PB_BIT, 
+    CONFIG_ETRAX_SER1_CD_ON_PB_BIT
 #else
     &dummy_ser1, &dummy_ser1, &dummy_dir_ser1, 0, 1, 2, 3
 #endif   
   },  
 /* Ser 2 */
   {
-#if defined(CONFIG_ETRAX100_SER2_DTR_RI_DSR_CD_ON_PA)
+#if defined(CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PA)
     R_PORT_PA_DATA,  &port_pa_data_shadow,  &port_pa_dir_shadow,
-    CONFIG_ETRAX100_SER2_DTR_ON_PA_BIT,
-	  CONFIG_ETRAX100_SER2_RI_ON_PA_BIT, 
-	  CONFIG_ETRAX100_SER2_DSR_ON_PA_BIT, 
-	  CONFIG_ETRAX100_SER2_CD_ON_PA_BIT
+    CONFIG_ETRAX_SER2_DTR_ON_PA_BIT,
+    CONFIG_ETRAX_SER2_RI_ON_PA_BIT, 
+    CONFIG_ETRAX_SER2_DSR_ON_PA_BIT, 
+    CONFIG_ETRAX_SER2_CD_ON_PA_BIT
 #else
     &dummy_ser2, &dummy_ser2, &dummy_dir_ser2, 0, 1, 2, 3
 #endif   
@@ -459,7 +473,7 @@
 static struct semaphore tmp_buf_sem = MUTEX;
 #endif
 
-#ifdef CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST
+#ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
 #define TIMER1_IRQ_NBR 3
 
 /* clock select 10 for timer 1 gives 230400 Hz */
@@ -494,7 +508,7 @@
 	*R_IRQ_MASK0_SET = IO_STATE(R_IRQ_MASK0_SET, timer1, set);
 	fast_timer_started = 1;
 }
-#endif /* CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST */
+#endif /* CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST */
 
 /*
  * This function maps from the Bxxxx defines in asm/termbits.h into real
@@ -1267,12 +1281,12 @@
 
 /* dma fifo/buffer timeout handler
    forces an end-of-packet for the dma input channel if no chars 
-   have been received for CONFIG_ETRAX100_RX_TIMEOUT_TICKS/100 s.
-   If CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST is configured then this
+   have been received for CONFIG_ETRAX_RX_TIMEOUT_TICKS/100 s.
+   If CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST is configured then this
    handler is instead run at 15360 Hz.
 */
 
-#ifndef CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST
+#ifndef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
 static int timeout_divider = 0;
 #endif
 
@@ -1467,7 +1481,7 @@
 		info->xmit.buf = (unsigned char *) page;
 		
 #ifdef SERIAL_DEBUG_OPEN
-	printk("starting up ttyS%d (xmit_buf 0x%x)...\n", info->line, info->xmit_buf);
+	printk("starting up ttyS%d (xmit_buf 0x%x)...\n", info->line, info->xmit.buf);
 #endif
 
 	if(info->tty) {
@@ -2688,12 +2702,15 @@
 		return -ENODEV;
 
 	/* dont allow opening ports that are not enabled in the HW config */
-
-#ifndef CONFIG_ETRAX100_SERIAL_PORT2
+#ifndef CONFIG_ETRAX_SERIAL_PORT1
+	if (line == 1)
+		return -ENODEV;
+#endif
+#ifndef CONFIG_ETRAX_SERIAL_PORT2
 	if (line == 2)
 		return -ENODEV;
 #endif
-#ifndef CONFIG_ETRAX100_SERIAL_PORT3
+#ifndef CONFIG_ETRAX_SERIAL_PORT3
 	if (line == 3)
 		return -ENODEV;
 #endif
@@ -2955,7 +2972,7 @@
 	for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
 		info->line = i;
 		info->tty = 0;
-		info->type = PORT_ETRAX100;
+		info->type = PORT_ETRAX;
 		info->tr_running = 0;
 		info->fifo_magic = 0;
 		info->fifo_didmagic = 0;
@@ -2990,25 +3007,27 @@
 	if(request_irq(8, ser_interrupt, SA_INTERRUPT, "serial ", NULL))
 		panic("irq8");
 #endif
+#ifdef CONFIG_ETRAX_SERIAL_PORT1
 	if(request_irq(24, tr_interrupt, SA_INTERRUPT, "serial 1 dma tr", NULL))
 		panic("irq24");
 	if(request_irq(25, rec_interrupt, SA_INTERRUPT, "serial 1 dma rec", NULL))
 		panic("irq25");
-#ifdef CONFIG_ETRAX100_SERIAL_PORT2
+#endif
+#ifdef CONFIG_ETRAX_SERIAL_PORT2
 	/* DMA Shared with par0 (and SCSI0 and ATA) */
 	if(request_irq(18, tr_interrupt, SA_SHIRQ, "serial 2 dma tr", NULL))
 		panic("irq18");
 	if(request_irq(19, rec_interrupt, SA_SHIRQ, "serial 2 dma rec", NULL))
 		panic("irq19");
 #endif
-#ifdef CONFIG_ETRAX100_SERIAL_PORT3
+#ifdef CONFIG_ETRAX_SERIAL_PORT3
 	/* DMA Shared with par1 (and SCSI1 and Extern DMA 0) */
 	if(request_irq(20, tr_interrupt, SA_SHIRQ, "serial 3 dma tr", NULL))
 		panic("irq20");
 	if(request_irq(21, rec_interrupt, SA_SHIRQ, "serial 3 dma rec", NULL))
 		panic("irq21");
 #endif
-#ifdef CONFIG_ETRAX100_SERIAL_FLUSH_DMA_FAST
+#ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
 	/* TODO: a timeout_interrupt needs to be written that calls timeout_handler */
 	if(request_irq(TIMER1_IRQ_NBR, timeout_interrupt, SA_SHIRQ,
 		       "fast serial dma timeout", NULL)) {
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/serial.h linux/arch/cris/drivers/serial.h
--- v2.4.3/linux/arch/cris/drivers/serial.h	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/drivers/serial.h	Fri Apr  6 10:42:55 2001
@@ -4,8 +4,8 @@
  * Copyright (C) 1998, 1999, 2000 Axis Communications AB
  */
 
-#ifndef _ETRAX100_SERIAL_H
-#define _ETRAX100_SERIAL_H
+#ifndef _ETRAX_SERIAL_H
+#define _ETRAX_SERIAL_H
 
 #include <linux/config.h>
 #include <linux/circ_buf.h>
@@ -64,7 +64,7 @@
 	unsigned long		event;
 	unsigned long		last_active;
 	int			line;
-	int                     type;  /* PORT_ETRAX100 */
+	int                     type;  /* PORT_ETRAX */
 	int			count;	    /* # of fd on device */
 	int			blocked_open; /* # of blocked opens */
 	long			session; /* Session of opening process */
@@ -93,7 +93,7 @@
  * system.
  */
 
-#define PORT_ETRAX100 1
+#define PORT_ETRAX 1
 
 /*
  * Events are used to schedule things to happen at timer-interrupt
@@ -103,4 +103,4 @@
 
 #endif /* __KERNEL__ */
 
-#endif /* !(_ETRAX100_SERIAL_H) */
+#endif /* !(_ETRAX_SERIAL_H) */
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/sync_serial.c linux/arch/cris/drivers/sync_serial.c
--- v2.4.3/linux/arch/cris/drivers/sync_serial.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/sync_serial.c	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,873 @@
+/*  
+ * Simple synchronous serial port driver for ETRAX 100LX.
+ *
+ * Synchronous serial ports are used for continous streamed data like audio.
+ * The deault setting for this driver is compatible with the STA 013 MP3 decoder
+ * The driver can easily be tuned to fit other audio encoder/decoders and SPI
+ *
+ * Copyright (c) 2001 Axis Communications AB
+ * 
+ * Author: Mikael Starvik 
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/svinto.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/sync_serial.h>
+
+/* The receiver is a bit tricky beacuse of the continous stream of data. */
+/*									 */
+/* Two DMA descriptors are linked together. Each DMA descriptor is	 */
+/* responsible for one half of a common buffer.				 */
+/*									 */
+/* ------------------------------					 */
+/* |   ----------   ----------	|					 */
+/* --> | Descr1 |-->| Descr2 |---					 */
+/*     ----------   ----------						 */
+/*	 |	       |						 */
+/*	 v	       v						 */
+/*	 -----------------------------					 */
+/*	 |	      BUFFER	     |					 */
+/*	 -----------------------------					 */
+/*	 |		|						 */
+/*	readp	      writep						 */
+/*									 */
+/* If the application keeps up the pace readp will be right after writep.*/
+/* If the application can't keep the pace we have to throw away data.	 */ 
+/* The idea is that readp should be ready with the data pointed out by	 */
+/* Descr1 when the DMA has filled in Descr2. Otherwise we will discard	 */
+/* the rest of the data pointed out by Descr1 and set readp to the start */
+/* of Descr2								 */
+
+#define SYNC_SERIAL_MAJOR 125
+
+#define IN_BUFFER_SIZE 8192
+#define OUT_BUFFER_SIZE 4096
+
+#define DEBUG(x) 
+
+/* Define some macros to access Etrax 100 registers */
+#define SETF(var, reg, field, val) var = (var & ~IO_MASK(##reg##, field)) | \
+					  IO_FIELD(##reg##, field, val)
+#define SETS(var, reg, field, val) var = (var & ~IO_MASK(##reg##, field)) | \
+					  IO_STATE(##reg##, field, val)
+
+typedef struct sync_port
+{
+	/* Etrax registers and bits*/
+	volatile unsigned * const status;
+	volatile unsigned * const ctrl_data;
+	volatile unsigned * const output_dma_first;
+	volatile unsigned char * const output_dma_cmd;
+	volatile unsigned char * const output_dma_clr_irq;
+	volatile unsigned * const input_dma_first;
+	volatile unsigned char * const input_dma_cmd;
+	volatile unsigned char * const input_dma_clr_irq;
+	volatile unsigned * const data_out;
+	volatile unsigned * const data_in;
+	char data_avail_bit; /* In R_IRQ_MASK1_RD */
+	char transmitter_ready_bit; /* In R_IRQ_MASK1_RD */
+	char ready_irq_bit; /* In R_IRQ_MASK1_SET and R_IRQ_MASK1_CLR */
+	char input_dma_eop_bit;   /* In R_IRQ_MASK2_RD */
+	char input_dma_descr_bit; /* In R_IRQ_MASK2_RD */
+	char output_dma_bit; /* In R_IRQ_MASK2_RD */
+	char eop_bit; /* In R_SET_EOP */
+
+	int enabled;  /* 1 if port is enabled */
+	int use_dma;  /* 1 if port uses dma */
+	int port_nbr; /* Port 0 or 1 */
+	unsigned ctrl_data_shadow; /* Register shadow */
+	char busy; /* 1 if port is busy */
+	wait_queue_head_t out_wait_q;
+	wait_queue_head_t in_wait_q;
+	struct etrax_dma_descr out_descr;
+	struct etrax_dma_descr in_descr1;
+	struct etrax_dma_descr in_descr2;
+	char out_buffer[OUT_BUFFER_SIZE];
+	int out_count; /* Remaining bytes for current transfer */
+	char* outp; /* Current position in out_buffer */
+	char in_buffer[IN_BUFFER_SIZE];
+	volatile char* readp;  /* Next byte to be read by application */
+	volatile char* writep; /* Next byte to be written by etrax */
+	int odd_output; /* 1 if writing odd nible in 12 bit mode */
+	int odd_input;  /* 1 if reading odd nible in 12 bit mode */
+} sync_port;
+
+
+static int etrax_sync_serial_init(void);
+static void initialize_port(int portnbr);
+static int sync_serial_open(struct inode *, struct file*);
+static int sync_serial_release(struct inode*, struct file*);
+static int sync_serial_ioctl(struct inode*, struct file*,
+			     unsigned int cmd, unsigned long arg);
+static ssize_t sync_serial_write(struct file * file, const char * buf, 
+				 size_t count, loff_t *ppos);
+static ssize_t sync_serial_manual_write(struct file * file, const char * buf, 
+					size_t count, loff_t *ppos);
+static ssize_t sync_serial_read(struct file *file, char *buf, 
+				size_t count, loff_t *ppos);
+static void send_word(sync_port* port);
+static void start_dma(struct sync_port *port, const char* data, int count);
+static void start_dma_in(sync_port* port);
+static void tr_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static void rx_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static void manual_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static void flush_handler(void);
+
+/* The ports */
+static struct sync_port ports[]=
+{
+	{
+		R_SYNC_SERIAL1_STATUS,  /* status */
+		R_SYNC_SERIAL1_CTRL,    /* ctrl_data */
+		R_DMA_CH8_FIRST,	    /* output_dma_first */
+		R_DMA_CH8_CMD,	    /* output_dma_cmd */
+		R_DMA_CH8_CLR_INTR,	    /* output_dma_clr_irq */
+		R_DMA_CH9_FIRST,	    /* input_dma_first */
+		R_DMA_CH9_CMD,	    /* input_dma_cmd */
+		R_DMA_CH9_CLR_INTR,	    /* input_dma_clr_irq */
+		R_SYNC_SERIAL1_TR_DATA, /* data_out */
+		R_SYNC_SERIAL1_REC_DATA,/* data in */
+		IO_BITNR(R_IRQ_MASK1_RD, ser1_data),   /* data_avail_bit */
+		IO_BITNR(R_IRQ_MASK1_RD, ser1_ready),  /* transmitter_ready_bit */
+		IO_BITNR(R_IRQ_MASK1_SET, ser1_ready), /* ready_irq_bit */
+		IO_BITNR(R_IRQ_MASK2_RD, dma9_eop),	   /* input_dma_eop_bit */
+		IO_BITNR(R_IRQ_MASK2_RD, dma9_descr),  /* input_dma_descr_bit */
+		IO_BITNR(R_IRQ_MASK2_RD, dma8_eop),	   /* output_dma_bit */
+		IO_BITNR(R_SET_EOP, ch9_eop)	   /* eop_bit */
+	},
+	{
+		R_SYNC_SERIAL3_STATUS,  /* status */
+		R_SYNC_SERIAL3_CTRL,    /* ctrl_data */
+		R_DMA_CH4_FIRST,	    /* output_dma_first */
+		R_DMA_CH4_CMD,	    /* output_dma_cmd */
+		R_DMA_CH4_CLR_INTR,	    /* output_dma_clr_irq */
+		R_DMA_CH5_FIRST,	    /* input_dma_first */
+		R_DMA_CH5_CMD,	    /* input_dma_cmd */
+		R_DMA_CH5_CLR_INTR,	    /* input_dma_clr_irq */
+		R_SYNC_SERIAL3_TR_DATA, /* data_out */
+		R_SYNC_SERIAL3_REC_DATA,/* data in */
+		IO_BITNR(R_IRQ_MASK1_RD, ser3_data),   /* data_avail_bit */
+		IO_BITNR(R_IRQ_MASK1_RD, ser3_ready),  /* transmitter_ready_bit */
+		IO_BITNR(R_IRQ_MASK1_SET, ser3_ready), /* ready_irq_bit */
+		IO_BITNR(R_IRQ_MASK2_RD, dma5_eop),	   /* input_dma_eop_bit */
+		IO_BITNR(R_IRQ_MASK2_RD, dma5_descr),  /* input_dma_eop_bit */
+		IO_BITNR(R_IRQ_MASK2_RD, dma4_eop),	   /* output_dma_bit */
+		IO_BITNR(R_SET_EOP, ch5_eop)	   /* eop_bit */
+	}
+};
+
+/* Register shadows */
+static unsigned sync_serial_prescale_shadow = 0;
+static unsigned gen_config_ii_shadow = 0;
+
+/* Timer used to flush data from the DMA */
+static struct timer_list flush_timer;
+
+#define NUMBER_OF_PORTS (sizeof(ports)/sizeof(sync_port))
+
+static struct file_operations sync_serial_fops = {
+       owner:	THIS_MODULE,
+       write:	sync_serial_write,
+       read:	sync_serial_read,
+       ioctl:	sync_serial_ioctl,
+       open:	sync_serial_open,
+       release: sync_serial_release
+};
+
+static int __init etrax_sync_serial_init(void)
+{
+	ports[0].enabled = 0;
+	ports[1].enabled = 0;
+
+	if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 ) 
+	{
+		printk("unable to get major for synchronous serial port\n");
+		return -EBUSY;
+	}
+
+	/* Deselect synchronous serial ports */
+	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
+	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
+	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, ser3, select);
+	*R_GEN_CONFIG_II = gen_config_ii_shadow;
+  
+	/* Initialize Ports */
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
+	ports[0].enabled = 1;
+	SETS(port_pb_i2c_shadow, R_PORT_PB_I2C, syncser1, ss1extra); 
+	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync);
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
+	ports[0].use_dma = 1;
+	initialize_port(0);
+	if(request_irq(24, tr_interrupt, 0, "synchronous serial 1 dma tr", NULL))
+		 panic("Can't allocate sync serial port 1 IRQ");
+	if(request_irq(25, rx_interrupt, 0, "synchronous serial 1 dma rx", NULL))
+		panic("Can't allocate sync serial port 1 IRQ");
+	RESET_DMA(8); WAIT_DMA(8);
+	RESET_DMA(9); WAIT_DMA(9);
+	*R_DMA_CH8_CLR_INTR = 3;  /* Clear IRQ */
+	*R_DMA_CH9_CLR_INTR = 3;  /* Clear IRQ */
+	*R_IRQ_MASK2_SET =
+	  IO_STATE(R_IRQ_MASK2_SET, dma8_eop, set) |
+	  IO_STATE(R_IRQ_MASK2_SET, dma8_descr, set) |
+          IO_STATE(R_IRQ_MASK2_SET, dma9_eop, set) | 
+          IO_STATE(R_IRQ_MASK2_SET, dma9_descr, set);
+	start_dma_in(&ports[0]);
+#else
+	ports[0].use_dma = 0;
+	initialize_port(0);
+	if (request_irq(8, manual_interrupt, SA_SHIRQ, "synchronous serial manual irq", NULL))
+		panic("Can't allocate sync serial manual irq");
+	*R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, ser1_data, set);	 
+#endif
+#endif
+
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
+	ports[1].enabled = 1;
+	SETS(port_pb_i2c_shadow, R_PORT_PB_I2C, syncser3, ss3extra);
+	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync);
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
+	ports[1].use_dma = 1;
+	initialize_port(1);
+	if(request_irq(20, tr_interrupt, 0, "synchronous serial 3 dma tr", NULL))
+		panic("Can't allocate sync serial port 1 IRQ");
+	if(request_irq(21, rx_interrupt, 0, "synchronous serial 3 dma rx", NULL))
+		panic("Can't allocate sync serial port 1 IRQ");
+	RESET_DMA(4); WAIT_DMA(4);
+	RESET_DMA(5); WAIT_DMA(5);
+	*R_DMA_CH4_CLR_INTR = 3;  /* Clear IRQ */
+	*R_DMA_CH5_CLR_INTR = 3;  /* Clear IRQ */
+	*R_IRQ_MASK2_SET =
+	  IO_STATE(R_IRQ_MASK2_SET, dma4_eop, set) |
+	  IO_STATE(R_IRQ_MASK2_SET, dma4_descr, set) |
+	  IO_STATE(R_IRQ_MASK2_SET, dma5_eop, set) | 
+	  IO_STATE(R_IRQ_MASK2_SET, dma5_descr, set);
+	start_dma_in(&ports[1]);
+#else
+	ports[1].use_dma = 0;	
+	initialize_port(1);
+	if (port[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */
+	{
+		if (request_irq(8, manual_interrupt, SA_SHIRQ, "synchronous serial manual irq", NULL))
+			panic("Can't allocate sync serial manual irq");
+	}
+	*R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, ser3_data, set);	 
+#endif
+#endif
+
+	*R_PORT_PB_I2C = port_pb_i2c_shadow; /* Use PB4/PB7 */
+
+	/* Set up timing */
+	*R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow = (
+	  IO_STATE(R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec) | 
+	  IO_STATE(R_SYNC_SERIAL_PRESCALE, word_stb_sel_u1, external) | 
+	  IO_STATE(R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec) | 
+	  IO_STATE(R_SYNC_SERIAL_PRESCALE, word_stb_sel_u3, external) | 
+	  IO_STATE(R_SYNC_SERIAL_PRESCALE, prescaler, div4) | 
+	  IO_FIELD(R_SYNC_SERIAL_PRESCALE, frame_rate, 0) | 
+	  IO_FIELD(R_SYNC_SERIAL_PRESCALE, word_rate, 7) | 
+	  IO_STATE(R_SYNC_SERIAL_PRESCALE, warp_mode, normal));
+
+	/* Select synchronous ports */
+	*R_GEN_CONFIG_II = gen_config_ii_shadow;
+
+	/*Initialize DMA flush timer if dma is used */
+	if (ports[0].use_dma || ports[1].use_dma) 
+	{
+		init_timer(&flush_timer);
+		flush_timer.function = flush_handler;
+		mod_timer(&flush_timer, jiffies + 10);
+	}
+
+	printk("Etrax100LX synchronous serial port driver\n");
+	return 0;
+}
+
+static void initialize_port(int portnbr)
+{
+	struct sync_port* port = &ports[portnbr];
+
+	DEBUG(printk("Init sync serial port %d\n", portnbr));
+    
+	port->port_nbr = portnbr;	
+	port->busy = 0;		
+	port->readp = port->in_buffer;
+	port->writep = port->in_buffer + IN_BUFFER_SIZE/2;
+	port->odd_input = 0;
+
+	init_waitqueue_head(&port->out_wait_q);
+	init_waitqueue_head(&port->in_wait_q);
+
+	port->ctrl_data_shadow =
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, tr_baud, c115k2Hz)   | 
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, mode, master_output) | 
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, error, ignore)       |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, rec_enable, disable) |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, f_synctype, normal)  |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, f_syncsize, word)    |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, f_sync, on)	     |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, clk_mode, normal)    |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, clk_halt, running)   |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, bitorder, msb)	     |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, tr_enable, enable)   |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit)  |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, buf_empty, lmt_8)    |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, buf_full, lmt_8)     |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled)  |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, clk_polarity, neg)   |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, frame_polarity, normal)|
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, status_polarity, inverted)|
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, clk_driver, normal)   |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, frame_driver, normal) |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, status_driver, normal)|
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, def_out0, high);
+  
+	if (port->use_dma)
+		port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL, dma_enable, on);
+	else
+		port->ctrl_data_shadow |= IO_STATE(R_SYNC_SERIAL1_CTRL, dma_enable, off);
+  
+	*port->ctrl_data = port->ctrl_data_shadow;
+}
+
+static int sync_serial_open(struct inode *inode, struct file *file)
+{
+	int dev = MINOR(inode->i_rdev);
+	DEBUG(printk("Open sync serial port %d\n", dev)); 
+  
+	if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
+	{
+		DEBUG(printk("Invalid minor %d\n", dev));
+		return -ENODEV;
+	}
+	if (ports[dev].busy)
+	{
+		DEBUG(printk("Device is busy.. \n"));
+		return -EBUSY;
+	}
+	ports[dev].busy = 1;
+	return 0;
+}
+
+static int sync_serial_release(struct inode *inode, struct file *file)
+{
+	ports[MINOR(inode->i_rdev)].busy = 0;
+	return 0;
+}
+
+static int sync_serial_ioctl(struct inode *inode, struct file *file,
+		  unsigned int cmd, unsigned long arg)
+{
+	int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+	sync_port* port = &ports[dev];
+
+	/* Disable port while changing config */
+	if (dev)
+	{
+		RESET_DMA(4); WAIT_DMA(4);
+		*R_DMA_CH4_CLR_INTR = 3;  
+		SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
+	}
+	else
+	{
+		RESET_DMA(8); WAIT_DMA(8);
+		*R_DMA_CH8_CLR_INTR = 3;  
+		SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
+	}
+	*R_GEN_CONFIG_II = gen_config_ii_shadow;
+
+	switch(cmd)
+	{
+		case SSP_SPEED:
+			if (GET_SPEED(arg) == CODEC)
+			{
+				if (dev)
+					SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec);
+				else
+					SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, codec);
+
+				SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, prescaler, GET_FREQ(arg));
+				SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, frame_rate, GET_FRAME_RATE(arg));
+				SETF(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, word_rate, GET_WORD_RATE(arg));
+			}
+			else
+			{
+				SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_baud, GET_SPEED(arg));
+				if (dev)
+					SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u3, baudrate);
+				else
+					SETS(sync_serial_prescale_shadow, R_SYNC_SERIAL_PRESCALE, clk_sel_u1, baudrate);
+			}
+			break;
+		case SSP_MODE:
+			if (arg > 5)
+				return -EINVAL;
+			SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, arg);
+			break;
+		case SSP_FRAME_SYNC:
+			if (arg & NORMAL_SYNC)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal);
+			else if (arg & EARLY_SYNC)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, early);
+    
+			if (arg & BIT_SYNC)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, bit);
+			else if (arg & WORD_SYNC)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word);
+			else if (arg & EXTENDED_SYNC)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, extended);
+    
+			if (arg & SYNC_ON)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on);
+			else if (arg & SYNC_OFF)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, off);
+    
+			if (arg & WORD_SIZE_8)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit);
+			else if (arg & WORD_SIZE_12)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size12bit);
+			else if (arg & WORD_SIZE_16)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size16bit);
+			else if (arg & WORD_SIZE_24)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size24bit);
+			else if (arg & WORD_SIZE_32)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size32bit);
+    
+			if (arg & BIT_ORDER_MSB)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb);
+			else if (arg & BIT_ORDER_LSB)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, lsb);
+
+			if (arg & FLOW_CONTROL_ENABLE)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, enabled);
+			else if (arg & FLOW_CONTROL_DISABLE)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled);
+
+			if (arg & CLOCK_NOT_GATED)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, normal);
+			else if (arg & CLOCK_GATED)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_mode, gated);
+    
+			break;
+		case SSP_IPOLARITY:
+			if (arg & CLOCK_NORMAL)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg);
+			else if (arg & CLOCK_INVERT)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, pos);
+
+			if (arg & FRAME_NORMAL)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, normal);
+			else if (arg & FRAME_INVERT)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted);
+
+			if (arg & STATUS_NORMAL)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, normal);
+			else if (arg & STATUS_INVERT)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_polarity, inverted);
+			break;
+		case SSP_OPOLARITY:
+			if (arg & CLOCK_NORMAL)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, normal);
+			else if (arg & CLOCK_INVERT)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted);
+    
+			if (arg & FRAME_NORMAL)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, normal);
+			else if (arg & FRAME_INVERT)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted);
+
+			if (arg & STATUS_NORMAL)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, normal);
+			else if (arg & STATUS_INVERT)
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, status_driver, inverted);
+			break;
+		case SSP_SPI:
+			SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, flow_ctrl, disabled);
+			SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, bitorder, msb);
+			SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, wordsize, size8bit);
+			SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_sync, on);
+			SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_syncsize, word);
+			SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, f_synctype, normal);
+			if (arg & SPI_SLAVE)
+			{
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_polarity, inverted);
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_polarity, neg);
+				SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, SLAVE_INPUT);
+			}
+			else
+			{
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, frame_driver, inverted);
+				SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_driver, inverted);
+				SETF(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, mode, MASTER_OUTPUT);
+			}
+			break;
+		default:
+			return -EINVAL;
+	}
+	/* Set config and enable port */
+	*port->ctrl_data = port->ctrl_data_shadow;
+	*R_SYNC_SERIAL_PRESCALE = sync_serial_prescale_shadow;
+	if (dev)
+		SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, sync);
+	else
+		SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync);
+
+	*R_GEN_CONFIG_II = gen_config_ii_shadow;
+	return 0;
+}
+
+static ssize_t sync_serial_manual_write(struct file * file, const char * buf, 
+                                        size_t count, loff_t *ppos)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	sync_port* port = &ports[MINOR(file->f_dentry->d_inode->i_rdev)];
+
+	copy_from_user(port->out_buffer, buf, count);
+	port->outp = port->out_buffer;
+	port->out_count = count;
+	port->odd_output = 1;
+	add_wait_queue(&port->out_wait_q, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	*R_IRQ_MASK1_SET = 1 << port->ready_irq_bit; /* transmitter ready IRQ on */
+	send_word(port); /* Start sender by sending first word */
+	schedule();
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&port->out_wait_q, &wait);
+	return count;
+}
+
+static ssize_t sync_serial_write(struct file * file, const char * buf, 
+                                 size_t count, loff_t *ppos)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	sync_port *port = &ports[MINOR(file->f_dentry->d_inode->i_rdev)];
+
+	DEBUG(printk("Write dev %d count %d\n", port->port_nbr, count));
+
+	if (!port->use_dma)
+	{
+		return sync_serial_manual_write(file, buf, count, ppos); 
+	}
+  
+	copy_from_user(port->out_buffer, buf, count);
+	add_wait_queue(&port->out_wait_q, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	start_dma(port, buf, count);
+	schedule();
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&port->out_wait_q, &wait);
+	return count;
+}
+
+static ssize_t sync_serial_read(struct file * file, char * buf, 
+				size_t count, loff_t *ppos)
+{
+	int avail;
+	sync_port *port = &ports[MINOR(file->f_dentry->d_inode->i_rdev)];
+	char* start; 
+	char* end;
+	unsigned long flags;	
+
+	DEBUG(printk("Read dev %d count\n"));
+
+	/* Calculate number of available bytes */
+	while (port->readp == port->writep) /* No data */
+	{
+		if (file->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+			interruptible_sleep_on(&port->in_wait_q);
+	}
+	
+	/* Save pointers to avoid that they are modified by interrupt */
+	start = port->readp;
+	end = port->writep;
+
+	/* Lazy read, never return wrapped data. */
+	if (end > start)
+		avail = end - start;
+	else 
+		avail = port->in_buffer + IN_BUFFER_SIZE - start;
+  
+	count = count > avail ? avail : count;
+	copy_to_user(buf, start, count);
+
+	/* Disable interrupts while updating readp */
+	save_flags(flags);
+	cli();	
+	port->readp += count;
+	if (port->readp == port->in_buffer + IN_BUFFER_SIZE) /* Wrap? */
+		port->readp = port->in_buffer;
+	restore_flags(flags);
+
+	DEBUG(printk("%d bytes read\n", count));
+	return count;
+}
+
+static void send_word(sync_port* port)
+{
+	switch(port->ctrl_data_shadow & IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize))
+	{
+		case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit):
+			port->out_count--;
+			*port->data_out = *port->outp++;
+			break;
+		case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
+			port->out_count--;
+			if (port->odd_output)
+				*port->data_out = ((*port->outp) << 16) | (*(unsigned short *)(port->outp + 1));
+			else
+				*port->data_out = ((*(unsigned short *)port->outp) << 8) | (*(port->outp + 1));
+			port->odd_output = !port->odd_output;
+			port->outp++;
+			break;
+		case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
+			port->out_count-=2;
+			*port->data_out = *(unsigned short *)port->outp;
+			port->outp+=2;
+			break;
+		case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit):
+			port->out_count-=3;
+			*port->data_out = *(unsigned int *)port->outp;
+			port->outp+=3;
+			break;
+		case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit):
+			port->out_count-=4;
+			*port->data_out = *(unsigned int *)port->outp;
+			port->outp+=4;
+			break;
+	}
+}
+
+static void start_dma(struct sync_port* port, const char* data, int count)
+{
+	port->out_descr.hw_len = 0;
+	port->out_descr.next = 0;
+	port->out_descr.ctrl = d_int | d_eol | d_eop;
+	port->out_descr.sw_len = count;
+	port->out_descr.buf = virt_to_phys(port->out_buffer);
+	port->out_descr.status = 0;
+
+	*port->output_dma_first = virt_to_phys(&port->out_descr);
+	*port->output_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start);
+}
+
+static void start_dma_in(sync_port* port)
+{
+	if (port->writep > port->in_buffer + IN_BUFFER_SIZE)
+	{
+		panic("Offset too large in sync serial driver\n");
+		return;
+	}
+	port->in_descr1.hw_len = 0;
+	port->in_descr1.ctrl = d_eop | d_int;
+	port->in_descr1.status = 0;
+	port->in_descr1.next = virt_to_phys(&port->in_descr2);
+	port->in_descr2.hw_len = 0;
+	port->in_descr2.next = virt_to_phys(&port->in_descr1);
+	port->in_descr2.ctrl = d_eop | d_int;
+	port->in_descr2.status = 0;
+
+	/* Find out which descriptor to start */
+	if (port->writep >= port->in_buffer + IN_BUFFER_SIZE/2)
+	{
+		/* Start descriptor 2 */
+		port->in_descr1.sw_len = IN_BUFFER_SIZE/2; /* All data available in 1 */
+		port->in_descr1.buf = virt_to_phys(port->in_buffer);
+		port->in_descr2.sw_len = port->in_buffer + IN_BUFFER_SIZE - port->writep;
+		port->in_descr2.buf = virt_to_phys(port->writep);
+		*port->input_dma_first = virt_to_phys(&port->in_descr2);
+	}
+	else
+	{
+		/* Start descriptor 1 */
+		port->in_descr1.sw_len = port->in_buffer + IN_BUFFER_SIZE/2 - port->writep;
+		port->in_descr1.buf = virt_to_phys(port->writep);
+		port->in_descr2.sw_len = IN_BUFFER_SIZE/2;
+		port->in_descr2.buf = virt_to_phys(port->in_buffer + IN_BUFFER_SIZE / 2);
+		*port->input_dma_first = virt_to_phys(&port->in_descr1);
+	}
+	*port->input_dma_cmd = IO_STATE(R_DMA_CH0_CMD, cmd, start);
+}
+
+static void tr_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	unsigned long ireg = *R_IRQ_MASK2_RD;
+	int i;
+
+	for (i = 0; i < NUMBER_OF_PORTS; i++) 
+	{
+		sync_port *port = &ports[i];
+		if (ireg & (1 << port->output_dma_bit)) /* IRQ active for the port? */
+		{
+			/* Clear IRQ */
+			*port->output_dma_clr_irq = 
+			  IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do) |
+			  IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do);
+			wake_up_interruptible(&port->out_wait_q); /* wake up the waiting process */
+		} 
+	}
+}
+
+static void rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	unsigned long ireg = *R_IRQ_MASK2_RD;
+	int i;	
+
+	for (i = 0; i < NUMBER_OF_PORTS; i++) 
+	{
+		int update = 0;
+		sync_port *port = &ports[i];
+
+		if (!port->enabled)
+		{
+			continue;
+		}    
+
+		if (ireg & (1 << port->input_dma_descr_bit)) /* Descriptor interrupt */
+		{
+			/* DMA has reached end of descriptor */
+			*port->input_dma_clr_irq = 
+			  IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do) | 
+			  IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do);
+
+			/* Find out which descriptor that is ready */
+			if (port->writep >= port->in_buffer + IN_BUFFER_SIZE/2) 
+			{
+				/* Descr 2 was ready. Restart DMA at descriptor 1 */
+				port->writep = port->in_buffer;
+	
+				/* Throw away data? */
+				if (port->readp < port->in_buffer + IN_BUFFER_SIZE/2)
+					port->readp = port->in_buffer + IN_BUFFER_SIZE/2;
+			}
+			else
+			{
+				/* Descr 1 was ready. Restart DMA at descriptor 2 */
+				port->writep = port->in_buffer + IN_BUFFER_SIZE/2;
+
+				/* Throw away data? */
+				if (port->readp >= port->in_buffer + IN_BUFFER_SIZE/2)
+					port->readp = port->in_buffer;
+			}
+			start_dma_in(port);
+			wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */
+		}
+		else if (ireg & (1 << port->input_dma_eop_bit)) /* EOP interrupt */
+		{
+			/* EOP interrupt means that DMA has not reached end of descriptor */
+			*port->input_dma_clr_irq = 
+			  IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do) | 
+			  IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do);
+
+			/* Find out the current descriptor */
+			if (port->writep >= port->in_buffer + IN_BUFFER_SIZE/2)
+				port->writep += port->in_descr2.hw_len;
+			else
+				port->writep += port->in_descr1.hw_len;
+
+			start_dma_in(port);
+			wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */
+		}
+	}
+}
+
+static void manual_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	int i;
+
+	for (i = 0; i < NUMBER_OF_PORTS; i++)
+	{
+		sync_port* port = &ports[i];
+
+		if (!port->enabled)
+		{
+			continue;
+		}
+
+		if (*R_IRQ_MASK1_RD & (1 << port->data_avail_bit))	/* Data received? */
+		{
+			/* Read data */
+			switch(port->ctrl_data_shadow & IO_MASK(R_SYNC_SERIAL1_CTRL, wordsize))
+			{
+				case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit):
+					*port->writep++ = *(volatile char *)port->data_in;
+					break;
+				case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size12bit):
+				{
+					int data = *(unsigned short *)port->data_in;
+					if (port->odd_input)
+					{
+						*port->writep |= (data & 0x0f00) >> 8;
+						*(port->writep + 1) = data & 0xff;
+					}
+					else
+					{
+						*port->writep = (data & 0x0ff0) >> 4;
+						*(port->writep + 1) = (data & 0x0f) << 4;
+					}
+					port->odd_input = !port->odd_input;
+					port->writep+=1;
+				}
+				break;
+				case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size16bit):
+					*(unsigned short*)port->writep = *(volatile unsigned short *)port->data_in;
+					port->writep+=2;
+					break;
+				case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size24bit):
+					*(unsigned int*)port->writep = *port->data_in;
+					port->writep+=3;
+					break;
+				case IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size32bit):
+					*(unsigned int*)port->writep = *port->data_in;
+					port->writep+=4;
+					break;
+			}
+
+			if (port->writep > port->in_buffer + IN_BUFFER_SIZE) /* Wrap? */
+				port->writep = port->in_buffer;
+			wake_up_interruptible(&port->in_wait_q); /* Wake up application */
+		}
+
+		if (*R_IRQ_MASK1_RD & (1 << port->transmitter_ready_bit)) /* Transmitter ready? */
+		{
+			if (port->out_count) /* More data to send */
+				send_word(port);
+			else /* transmission finished */
+			{
+				*R_IRQ_MASK1_CLR = 1 << port->ready_irq_bit; /* Turn off IRQ */
+				wake_up_interruptible(&port->out_wait_q); /* Wake up application */
+			}
+		}
+	}
+}
+
+static void flush_handler(void)
+{
+	int i;
+	
+	for (i = 0; i < NUMBER_OF_PORTS; i++)
+	{
+		if (ports[i].enabled)
+		{
+			*R_SET_EOP = 1 << ports[i].eop_bit;  
+		}
+	}
+	/* restart flush timer */
+	mod_timer(&flush_timer, jiffies + 10);
+}
+
+module_init(etrax_sync_serial_init);
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/usb-host.c linux/arch/cris/drivers/usb-host.c
--- v2.4.3/linux/arch/cris/drivers/usb-host.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/usb-host.c	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,2501 @@
+/*
+ * usb-host.c: ETRAX 100LX USB Host Controller Driver (HCD)
+ *
+ * Copyright (c) 2001 Axis Communications AB.
+ *
+ * $Id: usb-host.c,v 1.8 2001/02/27 13:52:48 bjornw Exp $
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/list.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/svinto.h>
+
+#include <linux/usb.h>
+#include "usb-host.h"
+
+#define ETRAX_USB_HC_IRQ 31
+#define ETRAX_USB_RX_IRQ 25
+#define ETRAX_USB_TX_IRQ 24
+
+static const char *usb_hcd_version = "$Revision: 1.8 $";
+
+#undef KERN_DEBUG
+#define KERN_DEBUG ""
+
+#undef USB_DEBUG_RH
+#undef USB_DEBUG_EP
+#undef USB_DEBUG_DESC
+#undef USB_DEBUG_TRACE
+#undef USB_DEBUG_CTRL
+#undef USB_DEBUG_BULK
+#undef USB_DEBUG_INTR
+
+#ifdef USB_DEBUG_RH
+#define dbg_rh(format, arg...) printk(KERN_DEBUG __FILE__ ": (RH) " format "\n" , ## arg)
+#else
+#define dbg_rh(format, arg...) do {} while (0)
+#endif
+
+#ifdef USB_DEBUG_EP
+#define dbg_ep(format, arg...) printk(KERN_DEBUG __FILE__ ": (EP) " format "\n" , ## arg)
+#else
+#define dbg_ep(format, arg...) do {} while (0)
+#endif
+
+#ifdef USB_DEBUG_CTRL
+#define dbg_ctrl(format, arg...) printk(KERN_DEBUG __FILE__ ": (CTRL) " format "\n" , ## arg)
+#else
+#define dbg_ctrl(format, arg...) do {} while (0)
+#endif
+
+#ifdef USB_DEBUG_BULK
+#define dbg_bulk(format, arg...) printk(KERN_DEBUG __FILE__ ": (BULK) " format "\n" , ## arg)
+#else
+#define dbg_bulk(format, arg...) do {} while (0)
+#endif
+
+#ifdef USB_DEBUG_INTR
+#define dbg_intr(format, arg...) printk(KERN_DEBUG __FILE__ ": (INTR) " format "\n" , ## arg)
+#else
+#define dbg_intr(format, arg...) do {} while (0)
+#endif
+
+#ifdef USB_DEBUG_TRACE
+#define DBFENTER (printk(KERN_DEBUG __FILE__ ": Entering : " __FUNCTION__ "\n"))
+#define DBFEXIT  (printk(KERN_DEBUG __FILE__ ": Exiting  : " __FUNCTION__ "\n"))
+#else
+#define DBFENTER (NULL)
+#define DBFEXIT  (NULL)
+#endif
+
+/*-------------------------------------------------------------------
+ Virtual Root Hub
+ -------------------------------------------------------------------*/
+
+static __u8 root_hub_dev_des[] =
+{
+	0x12,  /*  __u8  bLength; */
+	0x01,  /*  __u8  bDescriptorType; Device */
+	0x00,  /*  __u16 bcdUSB; v1.0 */
+	0x01,
+	0x09,  /*  __u8  bDeviceClass; HUB_CLASSCODE */
+	0x00,  /*  __u8  bDeviceSubClass; */
+	0x00,  /*  __u8  bDeviceProtocol; */
+	0x08,  /*  __u8  bMaxPacketSize0; 8 Bytes */
+	0x00,  /*  __u16 idVendor; */
+	0x00,
+	0x00,  /*  __u16 idProduct; */
+	0x00,
+	0x00,  /*  __u16 bcdDevice; */
+	0x00,
+	0x00,  /*  __u8  iManufacturer; */
+	0x02,  /*  __u8  iProduct; */
+	0x01,  /*  __u8  iSerialNumber; */
+	0x01   /*  __u8  bNumConfigurations; */
+};
+
+/* Configuration descriptor */
+static __u8 root_hub_config_des[] =
+{
+	0x09,  /*  __u8  bLength; */
+	0x02,  /*  __u8  bDescriptorType; Configuration */
+	0x19,  /*  __u16 wTotalLength; */
+	0x00,
+	0x01,  /*  __u8  bNumInterfaces; */
+	0x01,  /*  __u8  bConfigurationValue; */
+	0x00,  /*  __u8  iConfiguration; */
+	0x40,  /*  __u8  bmAttributes; Bit 7: Bus-powered */
+	0x00,  /*  __u8  MaxPower; */
+
+     /* interface */
+	0x09,  /*  __u8  if_bLength; */
+	0x04,  /*  __u8  if_bDescriptorType; Interface */
+	0x00,  /*  __u8  if_bInterfaceNumber; */
+	0x00,  /*  __u8  if_bAlternateSetting; */
+	0x01,  /*  __u8  if_bNumEndpoints; */
+	0x09,  /*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
+	0x00,  /*  __u8  if_bInterfaceSubClass; */
+	0x00,  /*  __u8  if_bInterfaceProtocol; */
+	0x00,  /*  __u8  if_iInterface; */
+
+     /* endpoint */
+	0x07,  /*  __u8  ep_bLength; */
+	0x05,  /*  __u8  ep_bDescriptorType; Endpoint */
+	0x81,  /*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
+	0x03,  /*  __u8  ep_bmAttributes; Interrupt */
+	0x08,  /*  __u16 ep_wMaxPacketSize; 8 Bytes */
+	0x00,
+	0xff   /*  __u8  ep_bInterval; 255 ms */
+};
+
+static __u8 root_hub_hub_des[] =
+{
+	0x09,  /*  __u8  bLength; */
+	0x29,  /*  __u8  bDescriptorType; Hub-descriptor */
+	0x02,  /*  __u8  bNbrPorts; */
+	0x00,  /* __u16  wHubCharacteristics; */
+	0x00,
+	0x01,  /*  __u8  bPwrOn2pwrGood; 2ms */
+	0x00,  /*  __u8  bHubContrCurrent; 0 mA */
+	0x00,  /*  __u8  DeviceRemovable; *** 7 Ports max *** */
+	0xff   /*  __u8  PortPwrCtrlMask; *** 7 ports max *** */
+};
+
+
+#define OK(x) len = (x); dbg_rh("OK(%d): line: %d", x, __LINE__); break
+#define CHECK_ALIGN(x) if (((__u32)(x)) & 0x00000003) \
+{panic("Alignment check (DWORD) failed at %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);}
+
+static submit_urb_count = 0;
+
+//#define ETRAX_USB_INTR_IRQ
+//#define ETRAX_USB_INTR_ERROR_FATAL
+
+#define RX_BUF_SIZE        32768
+#define RX_DESC_BUF_SIZE   64
+#define NBR_OF_RX_DESC     (RX_BUF_SIZE / RX_DESC_BUF_SIZE)
+
+#define NBR_OF_EP_DESC     32
+
+#define MAX_INTR_INTERVAL 128
+
+static __u32 ep_usage_bitmask;
+static __u32 ep_really_active;
+
+static unsigned char RxBuf[RX_BUF_SIZE];
+static USB_IN_Desc_t RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned (4)));
+
+static volatile USB_IN_Desc_t *myNextRxDesc;
+static volatile USB_IN_Desc_t *myLastRxDesc;
+static volatile USB_IN_Desc_t *myPrevRxDesc;
+
+static USB_EP_Desc_t TxCtrlEPList[NBR_OF_EP_DESC] __attribute__ ((aligned (4)));
+static USB_EP_Desc_t TxBulkEPList[NBR_OF_EP_DESC] __attribute__ ((aligned (4)));
+
+static USB_EP_Desc_t TxIntrEPList[MAX_INTR_INTERVAL] __attribute__ ((aligned (4)));
+static USB_SB_Desc_t TxIntrSB_zout __attribute__ ((aligned (4)));
+
+static urb_t *URB_List[NBR_OF_EP_DESC];
+static kmem_cache_t *usb_desc_cache;
+static struct usb_bus *etrax_usb_bus;
+
+static void dump_urb (purb_t purb);
+static void init_rx_buffers(void);
+static int etrax_rh_unlink_urb (urb_t *urb);
+static void etrax_rh_send_irq(urb_t *urb);
+static void etrax_rh_init_int_timer(urb_t *urb);
+static void etrax_rh_int_timer_do(unsigned long ptr);
+
+static void etrax_usb_setup_epid(char epid, char devnum, char endpoint,
+				 char packsize, char slow);
+static int etrax_usb_lookup_epid(unsigned char devnum, char endpoint, char slow, int maxp);
+static int etrax_usb_allocate_epid(void);
+static void etrax_usb_free_epid(char epid);
+static void cleanup_sb(USB_SB_Desc_t *sb);
+
+static int etrax_usb_do_ctrl_hw_add(urb_t *urb, char epid, char maxlen);
+static int etrax_usb_do_bulk_hw_add(urb_t *urb, char epid, char maxlen);
+
+static int etrax_usb_submit_ctrl_urb(urb_t *urb);
+
+static int etrax_usb_submit_urb(urb_t *urb);
+static int etrax_usb_unlink_urb(urb_t *urb);
+static int etrax_usb_get_frame_number(struct usb_device *usb_dev);
+static int etrax_usb_allocate_dev(struct usb_device *usb_dev);
+static int etrax_usb_deallocate_dev(struct usb_device *usb_dev);
+
+static void etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs);
+static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs);
+static void etrax_usb_hc_intr_top_half(int irq, void *vhc, struct pt_regs *regs);
+
+static int etrax_rh_submit_urb (urb_t *urb);
+
+static int etrax_usb_hc_init(void);
+static void etrax_usb_hc_cleanup(void);
+
+static struct usb_operations etrax_usb_device_operations =
+{
+	etrax_usb_allocate_dev,
+	etrax_usb_deallocate_dev,
+	etrax_usb_get_frame_number,
+	etrax_usb_submit_urb,
+	etrax_usb_unlink_urb
+};
+
+#ifdef USB_DEBUG_DESC
+static void dump_urb(purb_t purb)
+{
+	printk("\nurb                   :0x%08X\n", purb);
+	printk("next                  :0x%08X\n", purb->next);
+	printk("dev                   :0x%08X\n", purb->dev);
+	printk("pipe                  :0x%08X\n", purb->pipe);
+	printk("status                :%d\n", purb->status);
+	printk("transfer_flags        :0x%08X\n", purb->transfer_flags);
+	printk("transfer_buffer       :0x%08X\n", purb->transfer_buffer);
+	printk("transfer_buffer_length:%d\n", purb->transfer_buffer_length);
+	printk("actual_length         :%d\n", purb->actual_length);
+	printk("setup_packet          :0x%08X\n", purb->setup_packet);
+	printk("start_frame           :%d\n", purb->start_frame);
+	printk("number_of_packets     :%d\n", purb->number_of_packets);
+	printk("interval              :%d\n", purb->interval);
+	printk("error_count           :%d\n", purb->error_count);
+	printk("context               :0x%08X\n", purb->context);
+	printk("complete              :0x%08X\n\n", purb->complete);
+}
+
+static void dump_in_desc(USB_IN_Desc_t *in)
+{
+	printk("\nUSB_IN_Desc at 0x%08X\n", in);
+	printk("  sw_len  : 0x%04X (%d)\n", in->sw_len, in->sw_len);
+	printk("  command : 0x%04X\n", in->command);
+	printk("  next    : 0x%08X\n", in->next);
+	printk("  buf     : 0x%08X\n", in->buf);
+	printk("  hw_len  : 0x%04X (%d)\n", in->hw_len, in->hw_len);
+	printk("  status  : 0x%04X\n\n", in->status);
+}
+
+static void dump_sb_desc(USB_SB_Desc_t *sb)
+{
+	printk("\nUSB_SB_Desc at 0x%08X\n", sb);
+	printk("  sw_len  : 0x%04X (%d)\n", sb->sw_len, sb->sw_len);
+	printk("  command : 0x%04X\n", sb->command);
+	printk("  next    : 0x%08X\n", sb->next);
+	printk("  buf     : 0x%08X\n\n", sb->buf);
+}
+
+
+static void dump_ep_desc(USB_EP_Desc_t *ep)
+{
+	printk("\nUSB_EP_Desc at 0x%08X\n", ep);
+	printk("  hw_len  : 0x%04X (%d)\n", ep->hw_len, ep->hw_len);
+	printk("  command : 0x%08X\n", ep->command);
+	printk("  sub     : 0x%08X\n", ep->sub);
+	printk("  nep     : 0x%08X\n\n", ep->nep);
+}
+
+
+#else
+#define dump_urb(...)     (NULL)
+#define dump_ep_desc(...) (NULL)
+#define dump_sb_desc(...) (NULL)
+#define dump_in_desc(...) (NULL)
+#endif
+
+static void init_rx_buffers(void)
+{
+	int i;
+	
+	DBFENTER;
+	
+	for (i = 0; i < (NBR_OF_RX_DESC - 1); i++) {
+		RxDescList[i].sw_len = RX_DESC_BUF_SIZE;
+		RxDescList[i].command = 0;
+		RxDescList[i].next = virt_to_phys(&RxDescList[i + 1]);
+		RxDescList[i].buf = virt_to_phys(RxBuf + (i * RX_DESC_BUF_SIZE));
+		RxDescList[i].hw_len = 0;
+		RxDescList[i].status = 0;
+	}
+	
+	RxDescList[i].sw_len = RX_DESC_BUF_SIZE;
+	RxDescList[i].command = IO_STATE(USB_IN_command, eol, yes);
+	RxDescList[i].next = virt_to_phys(&RxDescList[0]);
+	RxDescList[i].buf = virt_to_phys(RxBuf + (i * RX_DESC_BUF_SIZE));
+	RxDescList[i].hw_len = 0;
+	RxDescList[i].status = 0;
+
+	myNextRxDesc = &RxDescList[0];
+	myLastRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
+	myPrevRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
+
+	*R_DMA_CH9_FIRST = virt_to_phys(myNextRxDesc);
+	*R_DMA_CH9_CMD = IO_STATE(R_DMA_CH9_CMD, cmd, start);
+	
+	DBFEXIT;
+}
+
+static void init_tx_ctrl_ep(void)
+{
+	int i;
+	
+	DBFENTER;
+	
+	for (i = 0; i < (NBR_OF_EP_DESC - 1); i++) {
+		TxCtrlEPList[i].hw_len = 0;
+		TxCtrlEPList[i].command = IO_FIELD(USB_EP_command, epid, i);
+		TxCtrlEPList[i].sub = 0;
+		TxCtrlEPList[i].nep = virt_to_phys(&TxCtrlEPList[i + 1]);
+	}
+	
+	TxCtrlEPList[i].hw_len = 0;
+	TxCtrlEPList[i].command = IO_STATE(USB_EP_command, eol, yes) |
+		IO_FIELD(USB_EP_command, epid, i);
+
+	TxCtrlEPList[i].sub = 0;
+	TxCtrlEPList[i].nep = virt_to_phys(&TxCtrlEPList[0]);
+	
+	*R_DMA_CH8_SUB1_EP = virt_to_phys(&TxCtrlEPList[0]);
+	*R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start);
+	
+	DBFEXIT;
+}
+
+static void init_tx_bulk_ep(void)
+{
+	int i;
+	
+	DBFENTER;
+	
+	for (i = 0; i < (NBR_OF_EP_DESC - 1); i++) {
+		TxBulkEPList[i].hw_len = 0;
+		TxBulkEPList[i].command = IO_FIELD(USB_EP_command, epid, i);
+		TxBulkEPList[i].sub = 0;
+		TxBulkEPList[i].nep = virt_to_phys(&TxBulkEPList[i + 1]);
+	}
+	
+	TxBulkEPList[i].hw_len = 0;
+	TxBulkEPList[i].command = IO_STATE(USB_EP_command, eol, yes) |
+		IO_FIELD(USB_EP_command, epid, i);
+
+	TxBulkEPList[i].sub = 0;
+	TxBulkEPList[i].nep = virt_to_phys(&TxBulkEPList[0]);
+	
+	*R_DMA_CH8_SUB0_EP = virt_to_phys(&TxBulkEPList[0]);
+	*R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start);
+	
+	DBFEXIT;
+}
+
+static void init_tx_intr_ep(void)
+{
+	int i;
+
+	DBFENTER;
+
+	TxIntrSB_zout.sw_len = 0;
+	TxIntrSB_zout.next = 0;
+	TxIntrSB_zout.buf = 0;
+	TxIntrSB_zout.command = IO_FIELD(USB_SB_command, rem, 0) |
+		IO_STATE(USB_SB_command, tt, zout) |
+		IO_STATE(USB_SB_command, full, yes) |
+		IO_STATE(USB_SB_command, eot, yes) |
+		IO_STATE(USB_SB_command, eol, yes);
+
+	for (i = 0; i < (MAX_INTR_INTERVAL - 1); i++) {
+		TxIntrEPList[i].hw_len = 0;
+		TxIntrEPList[i].command = IO_STATE(USB_EP_command, eof, yes) |
+			IO_STATE(USB_EP_command, enable, yes) |
+			IO_FIELD(USB_EP_command, epid, 0);
+		TxIntrEPList[i].sub = virt_to_phys(&TxIntrSB_zout);
+		TxIntrEPList[i].nep = virt_to_phys(&TxIntrEPList[i + 1]);
+	}
+	
+	TxIntrEPList[i].hw_len = 0;
+	TxIntrEPList[i].command =
+		IO_STATE(USB_EP_command, eof, yes) |
+		IO_STATE(USB_EP_command, enable, yes) |
+		IO_FIELD(USB_EP_command, epid, 0);
+	TxIntrEPList[i].sub = virt_to_phys(&TxIntrSB_zout);
+	TxIntrEPList[i].nep = virt_to_phys(&TxIntrEPList[0]);
+
+	*R_DMA_CH8_SUB2_EP = virt_to_phys(&TxIntrEPList[0]);
+	*R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start);
+	
+	DBFEXIT;
+}
+
+
+static int etrax_usb_unlink_intr_urb(urb_t *urb)
+{
+	struct usb_device *usb_dev = urb->dev;
+	etrax_hc_t *hc = usb_dev->bus->hcpriv;
+
+	USB_EP_Desc_t *tmp_ep;
+	USB_EP_Desc_t *first_ep;
+	
+	USB_EP_Desc_t *ep_desc;
+	USB_SB_Desc_t *sb_desc;
+	
+	char epid;
+	char devnum;
+	char endpoint;
+	char slow;
+	int maxlen;
+	int i;
+	
+	etrax_urb_priv_t *urb_priv;
+	unsigned long flags;
+	
+	DBFENTER;
+
+	devnum = usb_pipedevice(urb->pipe);
+	endpoint = usb_pipeendpoint(urb->pipe);
+	slow = usb_pipeslow(urb->pipe);
+	maxlen = usb_maxpacket(urb->dev, urb->pipe,
+			       usb_pipeout(urb->pipe));
+
+	epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen);
+	if (epid == -1) {
+		err("Trying to unlink urb that is not in traffic queue!!");
+		return -1;  /* fix this */
+	}
+
+	*R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, stop);
+	/* Somehow wait for the DMA to finish current activities */
+	i = jiffies + 100;
+	while (jiffies < i);	
+	
+	first_ep = &TxIntrEPList[0];
+	tmp_ep = first_ep;
+	
+	do {
+		if (IO_EXTRACT(USB_EP_command, epid, ((USB_EP_Desc_t *)phys_to_virt(tmp_ep->nep))->command)
+		    == epid) {
+			/* Unlink it !!! */
+			dbg_intr("Found urb to unlink for epid %d", epid);
+			
+			ep_desc = phys_to_virt(tmp_ep->nep);
+			tmp_ep->nep = ep_desc->nep;
+			kmem_cache_free(usb_desc_cache, phys_to_virt(ep_desc->sub));
+			kmem_cache_free(usb_desc_cache, ep_desc);
+		}
+
+		tmp_ep = phys_to_virt(tmp_ep->nep);
+		
+	} while (tmp_ep != first_ep);
+
+	/* We should really try to move the EP register to an EP that is not removed
+	   instead of restarting, but this will work too */
+	*R_DMA_CH8_SUB2_EP = virt_to_phys(&TxIntrEPList[0]);
+	*R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start);
+
+	clear_bit(epid, (void *)&ep_really_active);
+	URB_List[epid] = NULL;
+	etrax_usb_free_epid(epid);
+	
+	DBFEXIT;
+
+	return 0;
+}
+
+void etrax_usb_do_intr_recover(int epid)
+{
+	USB_EP_Desc_t *first_ep, *tmp_ep;
+	
+	first_ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB2_EP);
+	tmp_ep = first_ep;
+
+	do {
+		if (IO_EXTRACT(USB_EP_command, epid, tmp_ep->command) == epid &&
+		    !(tmp_ep->command & IO_MASK(USB_EP_command, enable))) {
+			tmp_ep->command |= IO_STATE(USB_EP_command, enable, yes);
+		}
+		
+		tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->nep);
+		
+	} while (tmp_ep != first_ep);
+}
+
+static int etrax_usb_submit_intr_urb(urb_t *urb)
+{
+	USB_EP_Desc_t *tmp_ep;
+	USB_EP_Desc_t *first_ep;
+	
+	USB_SB_Desc_t *sb_desc;
+	
+	char epid;
+	char devnum;
+	char endpoint;
+	char maxlen;
+	char slow;
+	int interval;
+	int i;
+	
+	etrax_urb_priv_t *urb_priv;
+	unsigned long flags;
+	
+	DBFENTER;
+
+	devnum = usb_pipedevice(urb->pipe);
+	endpoint = usb_pipeendpoint(urb->pipe);
+	maxlen = usb_maxpacket(urb->dev, urb->pipe,
+			       usb_pipeout(urb->pipe));
+
+	slow = usb_pipeslow(urb->pipe);
+	interval = urb->interval;
+
+	dbg_intr("Intr traffic for dev %d, endpoint %d, maxlen %d, slow %d",
+		 devnum, endpoint, maxlen, slow);
+	
+	epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen);
+	if (epid == -1) {
+		epid = etrax_usb_allocate_epid();
+		if (epid == -1) {
+			/* We're out of endpoints, return some error */
+			err("We're out of endpoints");
+			return -ENOMEM;
+		}
+		/* Now we have to fill in this ep */
+		etrax_usb_setup_epid(epid, devnum, endpoint, maxlen, slow);
+	}
+	/* Ok, now we got valid endpoint, lets insert some traffic */
+
+	urb_priv = (etrax_urb_priv_t *)kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL);
+	urb_priv->first_sb = 0;
+	urb_priv->rx_offset = 0;
+	urb_priv->eot = 0;
+	INIT_LIST_HEAD(&urb_priv->ep_in_list);
+	urb->hcpriv = urb_priv;
+
+	/* This is safe since there cannot be any other URB's for this epid */
+	URB_List[epid] = urb;
+#if 0
+	first_ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB2_EP);
+#else
+	first_ep = &TxIntrEPList[0];
+#endif
+
+	/* Round of the interval to 2^n, it is obvious that this code favours
+	   smaller numbers, but that is actually a good thing */
+	for (i = 0; interval; i++) {
+		interval = interval >> 1;
+	}
+
+	urb->interval = interval = 1 << (i - 1);
+
+	dbg_intr("Interval rounded to %d", interval);
+
+	tmp_ep = first_ep;
+	i = 0;
+	do {
+		if (tmp_ep->command & IO_MASK(USB_EP_command, eof)) {
+			if ((i % interval) == 0) {
+				/* Insert the traffic ep after tmp_ep */
+				USB_EP_Desc_t *traffic_ep;
+				USB_SB_Desc_t *traffic_sb;
+
+				traffic_ep = (USB_EP_Desc_t *)
+					kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+				traffic_sb = (USB_SB_Desc_t *)
+					kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+
+				traffic_ep->hw_len = 0;
+				traffic_ep->command = IO_FIELD(USB_EP_command, epid, epid) |
+					IO_STATE(USB_EP_command, enable, yes);
+				traffic_ep->sub = virt_to_phys(traffic_sb);
+
+				if (usb_pipein(urb->pipe)) {
+					traffic_sb->sw_len = urb->transfer_buffer_length ?
+						(urb->transfer_buffer_length - 1) / maxlen + 1 : 0;
+					traffic_sb->next = 0;
+					traffic_sb->buf = 0;
+					traffic_sb->command = IO_FIELD(USB_SB_command, rem,
+								       urb->transfer_buffer_length % maxlen) |
+						IO_STATE(USB_SB_command, tt, in) |
+						IO_STATE(USB_SB_command, eot, yes) |
+						IO_STATE(USB_SB_command, eol, yes);
+					
+				} else if (usb_pipeout(urb->pipe)) {
+					traffic_sb->sw_len = urb->transfer_buffer_length;
+					traffic_sb->next = 0;
+					traffic_sb->buf = virt_to_phys(urb->transfer_buffer);
+					traffic_sb->command = IO_FIELD(USB_SB_command, rem, 0) |
+						IO_STATE(USB_SB_command, tt, out) |
+						IO_STATE(USB_SB_command, eot, yes) |
+						IO_STATE(USB_SB_command, eol, yes) |
+						IO_STATE(USB_SB_command, full, yes);
+				}
+
+				traffic_ep->nep = tmp_ep->nep;
+				tmp_ep->nep = virt_to_phys(traffic_ep);
+				dbg_intr("One ep successfully inserted");
+			}
+			i++;
+		}
+		tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->nep);
+	} while (tmp_ep != first_ep);
+
+	set_bit(epid, (void *)&ep_really_active);
+	
+	*R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start);
+
+	DBFEXIT;
+	
+	return 0;
+}
+
+
+static int handle_intr_transfer_attn(char epid, int status)
+{
+	urb_t *old_urb;
+
+	DBFENTER;
+
+	old_urb = URB_List[epid];
+	
+	/* if (status == 0 && IN) find data and copy to urb */
+	if (status == 0 && usb_pipein(old_urb->pipe)) {
+		unsigned long flags;
+		etrax_urb_priv_t *urb_priv;
+		struct list_head *entry;
+		struct in_chunk *in;
+
+		urb_priv = (etrax_urb_priv_t *)old_urb->hcpriv;
+		
+		save_flags(flags);
+		cli();
+
+		list_for_each(entry, &urb_priv->ep_in_list) {
+			in = list_entry(entry, struct in_chunk, list);
+			memcpy(old_urb->transfer_buffer, in->data, in->length);
+			old_urb->actual_length = in->length;
+			old_urb->status = status;
+			
+			if (old_urb->complete) {
+				old_urb->complete(old_urb);
+			}
+			
+			list_del(entry);
+			kfree(in->data);
+			kfree(in);
+		}		
+		
+		restore_flags(flags);
+
+	} else if (status != 0) {
+		warn("Some sort of error for INTR EP !!!!");
+#ifdef ETRAX_USB_INTR_ERROR_FATAL
+		/* This means that an INTR error is fatal for that endpoint */
+		etrax_usb_unlink_intr_urb(old_urb);
+		old_urb->status = status;
+		if (old_urb->complete) {
+			old_urb->complete(old_urb);
+		}
+#else
+		/* In this case we reenable the disabled endpoint(s) */
+		etrax_usb_do_intr_recover(epid);
+#endif	
+	}
+	
+	DBFEXIT;
+}
+
+static int etrax_rh_unlink_urb (urb_t *urb)
+{
+	etrax_hc_t *hc;
+	
+	DBFENTER;
+	
+	hc = urb->dev->bus->hcpriv;
+	
+	if (hc->rh.urb == urb) {
+		hc->rh.send = 0;
+		del_timer(&hc->rh.rh_int_timer);
+	}
+	
+	DBFEXIT;
+	return 0;
+}
+
+static void etrax_rh_send_irq(urb_t *urb)
+{
+	__u16 data = 0;
+	etrax_hc_t *hc = urb->dev->bus->hcpriv;
+//	static prev_wPortStatus_1 = 0;
+//	static prev_wPortStatus_2 = 0;
+	
+/*	DBFENTER; */
+	
+	
+/*
+  dbg_rh("R_USB_FM_NUMBER   : 0x%08X", *R_USB_FM_NUMBER);
+  dbg_rh("R_USB_FM_REMAINING: 0x%08X", *R_USB_FM_REMAINING);
+*/
+	
+	data |= (hc->rh.wPortChange_1) ? (1 << 1) : 0;
+	data |= (hc->rh.wPortChange_2) ? (1 << 2) : 0;
+
+	*((__u16 *)urb->transfer_buffer) = cpu_to_le16(data);
+	urb->actual_length = 1;
+	urb->status = 0;
+
+	
+	if (data && hc->rh.send && urb->complete) {
+		dbg_rh("wPortChange_1: 0x%04X", hc->rh.wPortChange_1); 
+		dbg_rh("wPortChange_2: 0x%04X", hc->rh.wPortChange_2);
+
+		urb->complete(urb);
+	}
+  
+/*	DBFEXIT; */
+}
+
+static void etrax_rh_init_int_timer(urb_t *urb)
+{
+	etrax_hc_t *hc;
+	
+/*	DBFENTER; */
+	
+	hc = urb->dev->bus->hcpriv;
+	hc->rh.interval = urb->interval;
+	init_timer(&hc->rh.rh_int_timer);
+	hc->rh.rh_int_timer.function = etrax_rh_int_timer_do;
+	hc->rh.rh_int_timer.data = (unsigned long)urb;
+	hc->rh.rh_int_timer.expires = jiffies + ((HZ * hc->rh.interval) / 1000);
+	add_timer(&hc->rh.rh_int_timer);
+	
+/*	DBFEXIT; */
+}
+
+static void etrax_rh_int_timer_do(unsigned long ptr)
+{
+	urb_t *urb;
+	etrax_hc_t *hc;
+	
+/*	DBFENTER; */
+	
+	urb = (urb_t*)ptr;
+	hc = urb->dev->bus->hcpriv;
+	
+	if (hc->rh.send) {
+		etrax_rh_send_irq(urb);
+	}
+	
+	etrax_rh_init_int_timer(urb);
+	
+/*	DBFEXIT; */
+}
+
+static void etrax_usb_setup_epid(char epid, char devnum, char endpoint, char packsize, char slow)
+{
+	unsigned long flags;
+	
+	DBFENTER;
+
+	save_flags(flags);
+	cli();
+	
+	if (test_bit(epid, (void *)&ep_usage_bitmask)) {
+		warn("Trying to setup used epid %d", epid);
+		DBFEXIT;
+		return;
+	}
+	
+	set_bit(epid, (void *)&ep_usage_bitmask);
+	dbg_ep("Setting up ep_id %d with devnum %d, endpoint %d and max_len %d",
+	       epid, devnum, endpoint, packsize);
+	
+	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
+	nop();
+	*R_USB_EPT_DATA = IO_STATE(R_USB_EPT_DATA, valid, yes) |
+		IO_FIELD(R_USB_EPT_DATA, ep, endpoint) |
+		IO_FIELD(R_USB_EPT_DATA, dev, devnum) |
+		IO_FIELD(R_USB_EPT_DATA, max_len, packsize) |
+		IO_FIELD(R_USB_EPT_DATA, low_speed, slow);
+
+	restore_flags(flags);
+
+	DBFEXIT;
+}
+
+static void etrax_usb_free_epid(char epid)
+{
+	unsigned long flags;
+	
+	DBFENTER;
+
+	if (!test_bit(epid, (void *)&ep_usage_bitmask)) {
+		warn("Trying to free unused epid %d", epid);
+		DBFEXIT;
+		return;
+	}
+
+	save_flags(flags);
+	cli();
+	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
+	nop();
+	while (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold))printk("+");
+	*R_USB_EPT_DATA = 0;
+	clear_bit(epid, (void *)&ep_usage_bitmask);
+	restore_flags(flags);
+	dbg_ep("epid: %d freed", epid);
+	
+	DBFEXIT;
+}
+
+
+static int etrax_usb_lookup_epid(unsigned char devnum, char endpoint, char slow, int maxp)
+{
+	int i;
+	unsigned long flags;
+	__u32 data;
+	
+	DBFENTER;
+
+	save_flags(flags);
+	
+	/* Skip first ep_id since it is reserved when intr. or iso traffic is used */
+	for (i = 0; i < NBR_OF_EP_DESC; i++) {
+		if (test_bit(i, (void *)&ep_usage_bitmask)) {
+			*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, i);
+			nop();
+			data = *R_USB_EPT_DATA;
+			if ((IO_MASK(R_USB_EPT_DATA, valid) & data) &&
+			    (IO_EXTRACT(R_USB_EPT_DATA, dev, data) == devnum) &&
+			    (IO_EXTRACT(R_USB_EPT_DATA, ep, data) == endpoint) &&
+			    (IO_EXTRACT(R_USB_EPT_DATA, low_speed, data) == slow) &&
+			    (IO_EXTRACT(R_USB_EPT_DATA, max_len, data) == maxp)) {
+				dbg_ep("Found ep_id %d for devnum %d, endpoint %d",
+				       i, devnum, endpoint);
+				DBFEXIT;
+				return i;
+			}
+		}
+	}
+
+	restore_flags(flags);
+	
+	dbg_ep("Found no ep_id for devnum %d, endpoint %d",
+	       devnum, endpoint);
+	DBFEXIT;
+	return -1;
+}
+
+static int etrax_usb_allocate_epid(void)
+{
+	int i;
+	
+	DBFENTER;
+
+	for (i = 0; i < NBR_OF_EP_DESC; i++) {
+		if (!test_bit(i, (void *)&ep_usage_bitmask)) {
+			dbg_ep("Found free ep_id at %d", i);
+			DBFEXIT;
+			return i;
+		}
+	}
+
+	dbg_ep("Found no free ep_id's");
+	DBFEXIT;
+	return -1;
+}
+
+static int etrax_usb_submit_bulk_urb(urb_t *urb)
+{
+	char epid;
+	char devnum;
+	char endpoint;
+	char maxlen;
+	char slow;
+
+	urb_t *tmp_urb;
+	
+	etrax_urb_priv_t *urb_priv;
+	unsigned long flags;
+	
+	DBFENTER;
+
+	devnum = usb_pipedevice(urb->pipe);
+	endpoint = usb_pipeendpoint(urb->pipe);
+	maxlen = usb_maxpacket(urb->dev, urb->pipe,
+			       usb_pipeout(urb->pipe));
+	slow = usb_pipeslow(urb->pipe);
+	
+	epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen);
+	if (epid == -1) {
+		epid = etrax_usb_allocate_epid();
+		if (epid == -1) {
+			/* We're out of endpoints, return some error */
+			err("We're out of endpoints");
+			return -ENOMEM;
+		}
+		/* Now we have to fill in this ep */
+		etrax_usb_setup_epid(epid, devnum, endpoint, maxlen, slow);
+	}
+	/* Ok, now we got valid endpoint, lets insert some traffic */
+
+	urb->status = -EINPROGRESS;
+
+	save_flags(flags);
+	cli();
+	
+	if (URB_List[epid]) {
+		/* Find end of list and add */
+		for (tmp_urb = URB_List[epid]; tmp_urb->next; tmp_urb = tmp_urb->next)
+			dump_urb(tmp_urb);
+
+		tmp_urb->next = urb;
+		restore_flags(flags);
+	} else {
+		/* If this is the first URB, add the URB and do HW add */
+		URB_List[epid] = urb;
+		restore_flags(flags);
+		etrax_usb_do_bulk_hw_add(urb, epid, maxlen);
+	}
+
+	DBFEXIT;
+
+	return 0;
+}
+
+static int etrax_usb_do_bulk_hw_add(urb_t *urb, char epid, char maxlen)
+{
+	USB_SB_Desc_t *sb_desc_1;
+
+	etrax_urb_priv_t *urb_priv;
+
+	unsigned long flags;
+	__u32 r_usb_ept_data;
+
+	DBFENTER;
+
+	urb_priv = kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL);
+	sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+
+	if (usb_pipeout(urb->pipe)) {
+
+		dbg_bulk("Bulk transfer for epid %d is OUT", epid);
+		dbg_bulk("transfer_buffer_length == %d", urb->transfer_buffer_length);
+		dbg_bulk("actual_length == %d", urb->actual_length);
+	
+		if (urb->transfer_buffer_length > 0xffff) {
+			panic(__FILE__ __FUNCTION__ ":urb->transfer_buffer_length > 0xffff\n");
+		}
+
+		sb_desc_1->sw_len = urb->transfer_buffer_length;  /* was actual_length */
+		sb_desc_1->command = IO_FIELD(USB_SB_command, rem, 0) |
+			IO_STATE(USB_SB_command, tt, out) |
+
+#if 0
+			IO_STATE(USB_SB_command, full, no) |
+#else
+			IO_STATE(USB_SB_command, full, yes) |
+#endif
+
+			IO_STATE(USB_SB_command, eot, yes) |
+			IO_STATE(USB_SB_command, eol, yes);
+		
+		dbg_bulk("transfer_buffer is at 0x%08X", urb->transfer_buffer);
+		
+		sb_desc_1->buf = virt_to_phys(urb->transfer_buffer);
+		sb_desc_1->next = 0;
+		
+	} else if (usb_pipein(urb->pipe)) {
+
+		dbg_bulk("Transfer for epid %d is IN", epid);
+		dbg_bulk("transfer_buffer_length = %d", urb->transfer_buffer_length);
+		dbg_bulk("rem is calculated to %d", urb->transfer_buffer_length % maxlen);
+		
+		sb_desc_1->sw_len = urb->transfer_buffer_length ?
+			(urb->transfer_buffer_length - 1) / maxlen + 1 : 0;
+		dbg_bulk("sw_len got %d", sb_desc_1->sw_len);
+		dbg_bulk("transfer_buffer is at 0x%08X", urb->transfer_buffer);
+		
+		sb_desc_1->command =
+			IO_FIELD(USB_SB_command, rem,
+				 urb->transfer_buffer_length % maxlen) |
+			IO_STATE(USB_SB_command, tt, in) |
+			IO_STATE(USB_SB_command, eot, yes) |
+			IO_STATE(USB_SB_command, eol, yes);
+		
+		sb_desc_1->buf = 0;
+		sb_desc_1->next = 0;
+
+		urb_priv->rx_offset = 0;
+		urb_priv->eot = 0;
+	}
+	
+	urb_priv->first_sb = sb_desc_1;
+	
+	urb->hcpriv = (void *)urb_priv;
+	
+	/* Reset toggle bits and reset error count, remeber to di and ei */
+	/* Warning: it is possible that this locking doesn't work with bottom-halves */
+
+	save_flags(flags);
+	cli();
+
+	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop();
+	if (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)) {
+		panic("Hold was set in %s\n", __FUNCTION__);
+	}
+
+	*R_USB_EPT_DATA &=
+		~(IO_MASK(R_USB_EPT_DATA, error_count_in) |
+		  IO_MASK(R_USB_EPT_DATA, error_count_out));
+	
+	if (usb_pipeout(urb->pipe)) {
+		char toggle =
+		usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
+		*R_USB_EPT_DATA &= ~IO_MASK(R_USB_EPT_DATA, t_out);
+		*R_USB_EPT_DATA |= IO_FIELD(R_USB_EPT_DATA, t_out, toggle);
+	} else {
+		char toggle =
+		usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
+		*R_USB_EPT_DATA &= ~IO_MASK(R_USB_EPT_DATA, t_in);
+		*R_USB_EPT_DATA |= IO_FIELD(R_USB_EPT_DATA, t_in, toggle);
+	}
+		
+	/* Enable the EP descr. */
+
+	set_bit(epid, (void *)&ep_really_active);
+	
+	TxBulkEPList[epid].sub = virt_to_phys(sb_desc_1);
+	TxBulkEPList[epid].hw_len = 0;
+	TxBulkEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
+
+	restore_flags(flags);
+
+	if (!(*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd))) {
+		*R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start);
+		
+	}
+
+	DBFEXIT;
+}
+
+static int handle_bulk_transfer_attn(char epid, int status)
+{
+	urb_t *old_urb;
+	etrax_urb_priv_t *hc_priv;
+	unsigned long flags;
+
+	DBFENTER;
+
+	clear_bit(epid, (void *)&ep_really_active);
+	
+	old_urb = URB_List[epid];
+	URB_List[epid] = old_urb->next;
+
+	/* if (status == 0 && IN) find data and copy to urb */
+	if (status == 0 && usb_pipein(old_urb->pipe)) {
+		etrax_urb_priv_t *urb_priv;
+		
+		urb_priv = (etrax_urb_priv_t *)old_urb->hcpriv;
+		save_flags(flags);
+		cli();
+		if (urb_priv->eot == 1) {
+			old_urb->actual_length = urb_priv->rx_offset;
+		} else {
+			if (urb_priv->rx_offset == 0) {
+				status = 0;
+			} else {
+				status = -EPROTO;
+			}
+			
+			old_urb->actual_length = 0;
+			err("(BULK) No eot set in IN data!!! rx_offset is: %d", urb_priv->rx_offset);
+		}
+		
+		restore_flags(flags);
+	}
+
+	save_flags(flags);
+	cli();
+		
+	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop();
+	if (usb_pipeout(old_urb->pipe)) {
+		char toggle =
+		IO_EXTRACT(R_USB_EPT_DATA, t_out, *R_USB_EPT_DATA);
+		usb_settoggle(old_urb->dev, usb_pipeendpoint(old_urb->pipe),
+			      usb_pipeout(old_urb->pipe), toggle);
+	} else {
+		char toggle =
+		IO_EXTRACT(R_USB_EPT_DATA, t_in, *R_USB_EPT_DATA);
+		usb_settoggle(old_urb->dev, usb_pipeendpoint(old_urb->pipe),
+			      usb_pipeout(old_urb->pipe), toggle);
+	}
+	restore_flags(flags);
+	
+	/* If there are any more URB's in the list we'd better start sending */
+	if (URB_List[epid]) {
+		etrax_usb_do_bulk_hw_add(URB_List[epid], epid,
+					 usb_maxpacket(URB_List[epid]->dev, URB_List[epid]->pipe,
+						       usb_pipeout(URB_List[epid]->pipe)));
+	}
+#if 1
+	else {
+		/* This means that this EP is now free, deconfigure it */
+		etrax_usb_free_epid(epid);
+	}
+#endif
+	
+	/* Remember to free the SB's */
+	hc_priv = (etrax_urb_priv_t *)old_urb->hcpriv;
+	cleanup_sb(hc_priv->first_sb);
+	kfree(hc_priv);
+
+	old_urb->status = status;
+	if (old_urb->complete) {
+		old_urb->complete(old_urb);
+	}
+
+	DBFEXIT;
+}
+
+/* ---------------------------------------------------------------------------- */
+
+static int etrax_usb_submit_ctrl_urb(urb_t *urb)
+{
+	char epid;
+	char devnum;
+	char endpoint;
+	char maxlen;
+	char slow;
+
+	urb_t *tmp_urb;
+	
+	etrax_urb_priv_t *urb_priv;
+	unsigned long flags;
+	
+	DBFENTER;
+
+	devnum = usb_pipedevice(urb->pipe);
+	endpoint = usb_pipeendpoint(urb->pipe);
+	maxlen = usb_maxpacket(urb->dev, urb->pipe,
+			       usb_pipeout(urb->pipe));
+	slow = usb_pipeslow(urb->pipe);
+	
+	epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen);
+	if (epid == -1) {
+		epid = etrax_usb_allocate_epid();
+		if (epid == -1) {
+			/* We're out of endpoints, return some error */
+			err("We're out of endpoints");
+			return -ENOMEM;
+		}
+		/* Now we have to fill in this ep */
+		etrax_usb_setup_epid(epid, devnum, endpoint, maxlen, slow);
+	}
+	/* Ok, now we got valid endpoint, lets insert some traffic */
+
+	urb->status = -EINPROGRESS;
+
+	save_flags(flags);
+	cli();
+	
+	if (URB_List[epid]) {
+		/* Find end of list and add */
+		for (tmp_urb = URB_List[epid]; tmp_urb->next; tmp_urb = tmp_urb->next)
+			dump_urb(tmp_urb);
+
+		tmp_urb->next = urb;
+		restore_flags(flags);
+	} else {
+		/* If this is the first URB, add the URB and do HW add */
+		URB_List[epid] = urb;
+		restore_flags(flags);
+		etrax_usb_do_ctrl_hw_add(urb, epid, maxlen);
+	}
+
+	DBFEXIT;
+
+	return 0;
+}
+
+static int etrax_usb_do_ctrl_hw_add(urb_t *urb, char epid, char maxlen)
+{
+	USB_SB_Desc_t *sb_desc_1;
+	USB_SB_Desc_t *sb_desc_2;
+	USB_SB_Desc_t *sb_desc_3;
+
+	etrax_urb_priv_t *urb_priv;
+
+	unsigned long flags;
+	__u32 r_usb_ept_data;
+	
+
+	DBFENTER;
+
+	urb_priv = kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL);
+	sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+	sb_desc_2 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+
+	if (!(sb_desc_1 && sb_desc_2)) {
+		panic("kmem_cache_alloc in ctrl_hw_add gave NULL pointers !!!\n");
+	}
+	
+	sb_desc_1->sw_len = 8;
+	sb_desc_1->command = IO_FIELD(USB_SB_command, rem, 0) |
+		IO_STATE(USB_SB_command, tt, setup) |
+		IO_STATE(USB_SB_command, full, yes) |
+		IO_STATE(USB_SB_command, eot, yes);
+	
+	sb_desc_1->buf = virt_to_phys(urb->setup_packet);
+	sb_desc_1->next = virt_to_phys(sb_desc_2);
+	dump_sb_desc(sb_desc_1);
+
+	if (usb_pipeout(urb->pipe)) {
+		dbg_ctrl("Transfer for epid %d is OUT", epid);
+
+		/* If this Control OUT transfer has an optional data stage we add an OUT token
+		   before the mandatory IN (status) token, hence the reordered SB list */
+		
+		if (urb->transfer_buffer) {
+			dbg_ctrl("This OUT transfer has an extra data stage");
+			sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+
+			sb_desc_1->next = virt_to_phys(sb_desc_3);
+			
+			sb_desc_3->sw_len = urb->transfer_buffer_length;
+			sb_desc_3->command = IO_STATE(USB_SB_command, tt, out) |
+				IO_STATE(USB_SB_command, full, yes) |
+				IO_STATE(USB_SB_command, eot, yes);
+			sb_desc_3->buf = virt_to_phys(urb->transfer_buffer);
+			sb_desc_3->next = virt_to_phys(sb_desc_2);
+		}
+		
+		sb_desc_2->sw_len = 1;
+		sb_desc_2->command = IO_FIELD(USB_SB_command, rem, 0) |
+			IO_STATE(USB_SB_command, tt, in) |
+			IO_STATE(USB_SB_command, eot, yes) |
+			IO_STATE(USB_SB_command, eol, yes);
+
+		sb_desc_2->buf = 0;
+		sb_desc_2->next = 0;
+		dump_sb_desc(sb_desc_2);
+		
+	} else if (usb_pipein(urb->pipe)) {
+
+		dbg_ctrl("Transfer for epid %d is IN", epid);
+		dbg_ctrl("transfer_buffer_length = %d", urb->transfer_buffer_length);
+		dbg_ctrl("rem is calculated to %d", urb->transfer_buffer_length % maxlen);
+
+		sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+		
+		sb_desc_2->sw_len = urb->transfer_buffer_length ?
+			(urb->transfer_buffer_length - 1) / maxlen + 1 : 0;
+		dbg_ctrl("sw_len got %d", sb_desc_2->sw_len);
+		
+		sb_desc_2->command =
+			IO_FIELD(USB_SB_command, rem,
+				 urb->transfer_buffer_length % maxlen) |
+			IO_STATE(USB_SB_command, tt, in) |
+			IO_STATE(USB_SB_command, eot, yes);
+		
+		sb_desc_2->buf = 0;
+		sb_desc_2->next = virt_to_phys(sb_desc_3);
+		dump_sb_desc(sb_desc_2);
+
+		sb_desc_3->sw_len = 1;
+		sb_desc_3->command = IO_FIELD(USB_SB_command, rem, 0) |
+			IO_STATE(USB_SB_command, tt, zout) |
+			IO_STATE(USB_SB_command, full, yes) |
+			IO_STATE(USB_SB_command, eot, yes) |
+			IO_STATE(USB_SB_command, eol, yes);
+				
+		sb_desc_3->buf = 0;
+		sb_desc_3->next = 0;
+		dump_sb_desc(sb_desc_3);
+
+		urb_priv->rx_offset = 0;
+		urb_priv->eot = 0;
+	}
+	
+	urb_priv->first_sb = sb_desc_1;
+	
+	urb->hcpriv = (void *)urb_priv;
+	
+	/* Reset toggle bits and reset error count, remeber to di and ei */
+	/* Warning: it is possible that this locking doesn't work with bottom-halves */
+
+	save_flags(flags);
+	cli();
+
+	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop();
+	if (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)) {
+		panic("Hold was set in %s\n", __FUNCTION__);
+	}
+	
+
+	*R_USB_EPT_DATA &=
+		~(IO_MASK(R_USB_EPT_DATA, error_count_in) |
+		  IO_MASK(R_USB_EPT_DATA, error_count_out) |
+		  IO_MASK(R_USB_EPT_DATA, t_in) |
+		  IO_MASK(R_USB_EPT_DATA, t_out));
+
+	/* Enable the EP descr. */
+
+	set_bit(epid, (void *)&ep_really_active);
+	
+	TxCtrlEPList[epid].sub = virt_to_phys(sb_desc_1);
+	TxCtrlEPList[epid].hw_len = 0;
+	TxCtrlEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
+	restore_flags(flags);
+
+	dump_ep_desc(&TxCtrlEPList[epid]);
+
+	if (!(*R_DMA_CH8_SUB1_CMD & IO_MASK(R_DMA_CH8_SUB1_CMD, cmd))) {
+		*R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start);
+		
+	}
+	
+	DBFEXIT;
+}
+
+static int etrax_usb_submit_urb(urb_t *urb)
+{
+	etrax_hc_t *hc;
+	int rval = -EINVAL;
+	
+	DBFENTER;
+
+	dump_urb(urb);
+	submit_urb_count++;
+	
+	hc = (etrax_hc_t*) urb->dev->bus->hcpriv;
+	
+	if (usb_pipedevice(urb->pipe) == hc->rh.devnum) {
+		/* This request if for the Virtual Root Hub */
+		rval = etrax_rh_submit_urb(urb);
+		
+	} else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
+		rval = etrax_usb_submit_ctrl_urb(urb);
+
+	} else if (usb_pipetype(urb->pipe) == PIPE_BULK) {
+		rval = etrax_usb_submit_bulk_urb(urb);
+
+	} else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
+		int bustime;
+
+		if (urb->bandwidth == 0) {
+			bustime = usb_check_bandwidth(urb->dev, urb);
+			if (bustime < 0) {
+				rval = bustime;
+			} else {
+				usb_claim_bandwidth(urb->dev, urb, bustime, 0);
+				rval = etrax_usb_submit_intr_urb(urb);
+			}
+			
+		}
+	} else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+		warn("Isochronous traffic is not supported !!!");
+		rval = -EINVAL;
+	}
+
+	DBFEXIT;
+
+	return rval;
+}
+
+static int etrax_usb_unlink_urb(urb_t *urb)
+{
+	etrax_hc_t *hc = urb->dev->bus->hcpriv;
+	int epid;
+	int pos;
+	int devnum, endpoint, slow, maxlen;
+	etrax_urb_priv_t *hc_priv;
+	unsigned long flags;
+	
+	DBFENTER;
+	dump_urb(urb);
+	devnum = usb_pipedevice(urb->pipe);
+	endpoint = usb_pipeendpoint(urb->pipe);
+	slow = usb_pipeslow(urb->pipe);
+	maxlen = usb_maxpacket(urb->dev, urb->pipe,
+			       usb_pipeout(urb->pipe));
+
+	epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen);
+
+	if (epid == -1)
+		return 0;
+	
+	
+	if (usb_pipedevice(urb->pipe) == hc->rh.devnum) {
+		int ret;
+		ret =  etrax_rh_unlink_urb(urb);
+		DBFEXIT;
+		return ret;
+	} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) {
+		int ret;
+		ret = etrax_usb_unlink_intr_urb(urb);
+		urb->status = -ENOENT;
+		if (urb->complete) {
+			urb->complete(urb);
+		}
+		DBFEXIT;
+		return ret;
+	}
+
+	info("Unlink of BULK or CTRL");
+
+	save_flags(flags);
+	cli();
+	
+	for (epid = 0; epid < 32; epid++) {
+		urb_t *u = URB_List[epid];
+		pos = 0;
+
+		for (; u; u = u->next) {
+			pos++;
+			if (u == urb) {
+				info("Found urb at epid %d, pos %d", epid, pos);
+
+				if (pos == 1) {
+					if (usb_pipetype(u->pipe) == PIPE_CONTROL) {
+						if (TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
+							/* The EP was enabled, disable it and wait */
+							TxCtrlEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
+							while (*R_DMA_CH8_SUB1_EP == virt_to_phys(&TxCtrlEPList[epid]));
+						}
+						
+					} else if (usb_pipetype(u->pipe) == PIPE_BULK) {
+						if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
+							TxBulkEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
+							while (*R_DMA_CH8_SUB0_EP == virt_to_phys(&TxBulkEPList[epid]));
+						}
+					}
+
+					URB_List[epid] = u->next;
+				
+				} else {
+					urb_t *up;
+					for (up = URB_List[epid]; up->next != u; up = up->next);
+					up->next = u->next;
+				}
+				u->status = -ENOENT;
+				if (u->complete) {
+					u->complete(u);
+				}
+				
+				hc_priv = (etrax_urb_priv_t *)u->hcpriv;
+				cleanup_sb(hc_priv->first_sb);
+				kfree(hc_priv);
+			}
+		}
+	}
+
+	restore_flags(flags);
+		
+	DBFEXIT;
+	return 0;
+}
+
+static int etrax_usb_get_frame_number(struct usb_device *usb_dev)
+{
+	DBFENTER;
+	DBFEXIT;
+	return (*R_USB_FM_NUMBER);
+}
+
+static int etrax_usb_allocate_dev(struct usb_device *usb_dev)
+{  
+	DBFENTER;
+	DBFEXIT;
+	return 0;
+}
+
+static int etrax_usb_deallocate_dev(struct usb_device *usb_dev)
+{
+	DBFENTER;
+	DBFEXIT;
+	return 0;
+}
+
+static void etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs)
+{
+	etrax_hc_t *hc = (etrax_hc_t *)vhc;
+	int epid;
+	char eol;
+	urb_t *urb;
+	USB_EP_Desc_t *tmp_ep;
+	USB_SB_Desc_t *tmp_sb;
+	
+	DBFENTER;
+
+	if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub0_descr)) {
+		info("dma8_sub0_descr (BULK) intr.");
+		*R_DMA_CH8_SUB0_CLR_INTR = IO_STATE(R_DMA_CH8_SUB0_CLR_INTR, clr_descr, do);
+	}
+	if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub1_descr)) {
+		info("dma8_sub1_descr (CTRL) intr.");
+		*R_DMA_CH8_SUB1_CLR_INTR = IO_STATE(R_DMA_CH8_SUB1_CLR_INTR, clr_descr, do);
+	}
+	if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub2_descr)) {
+		info("dma8_sub2_descr (INT) intr.");
+		*R_DMA_CH8_SUB2_CLR_INTR = IO_STATE(R_DMA_CH8_SUB2_CLR_INTR, clr_descr, do);
+	}
+	if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub3_descr)) {
+		info("dma8_sub3_descr (ISO) intr.");
+		*R_DMA_CH8_SUB3_CLR_INTR = IO_STATE(R_DMA_CH8_SUB3_CLR_INTR, clr_descr, do);
+	}
+	
+	DBFEXIT;
+}
+
+static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs)
+{
+	int epid = 0;
+	urb_t *urb;
+	etrax_urb_priv_t *urb_priv;
+		
+	*R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do);
+
+	while (myNextRxDesc->status & IO_MASK(USB_IN_status, eop)) {
+		if (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata)) {
+
+			goto skip_out;
+		}
+
+		if (myNextRxDesc->status & IO_MASK(USB_IN_status, error)) {
+			
+			goto skip_out;
+		}
+		
+		epid = IO_EXTRACT(USB_IN_status, epid, myNextRxDesc->status);
+
+		urb = URB_List[epid];
+
+		if (urb && usb_pipein(urb->pipe)) {
+			urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
+
+			if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
+				struct in_chunk *in;
+				dbg_intr("Packet for epid %d in rx buffers", epid);
+				in = kmalloc(sizeof(struct in_chunk), GFP_ATOMIC);
+				in->length = myNextRxDesc->hw_len;
+				in->data = kmalloc(in->length, GFP_ATOMIC);
+				memcpy(in->data, phys_to_virt(myNextRxDesc->buf), in->length);
+				list_add_tail(&in->list, &urb_priv->ep_in_list);
+#ifndef ETRAX_USB_INTR_IRQ
+				etrax_usb_hc_intr_top_half(irq, vhc, regs);
+#endif
+				
+			} else {
+				if ((urb_priv->rx_offset + myNextRxDesc->hw_len) >
+				    urb->transfer_buffer_length) {
+					err("Packet (epid: %d) in RX buffer was bigger "
+					    "than the URB has room for !!!", epid);
+					goto skip_out;
+				}
+				
+				memcpy(urb->transfer_buffer + urb_priv->rx_offset,
+				       phys_to_virt(myNextRxDesc->buf), myNextRxDesc->hw_len);
+				
+				urb_priv->rx_offset += myNextRxDesc->hw_len;
+			}
+			
+			if (myNextRxDesc->status & IO_MASK(USB_IN_status, eot)) {
+				urb_priv->eot = 1;
+			}
+			
+		} else {
+			err("This is almost fatal, inpacket for epid %d which does not exist "
+			    " or is out !!!\nURB was at 0x%08X", epid, urb);
+			
+			goto skip_out;
+		}
+
+	skip_out:
+		myPrevRxDesc = myNextRxDesc;
+		myPrevRxDesc->command |= IO_MASK(USB_IN_command, eol);
+		myLastRxDesc->command &= ~IO_MASK(USB_IN_command, eol);
+		myLastRxDesc = myPrevRxDesc;
+
+		myNextRxDesc->status = 0;
+		myNextRxDesc = phys_to_virt(myNextRxDesc->next);
+	}
+}
+
+
+
+static void cleanup_sb(USB_SB_Desc_t *sb)
+{
+	USB_SB_Desc_t *next_sb;
+	
+	DBFENTER;
+
+	if (sb == NULL) {
+		err("cleanup_sb was given a NULL pointer");
+		return;
+	}
+
+	while (!(sb->command & IO_MASK(USB_SB_command, eol))) {
+		next_sb = (USB_SB_Desc_t *)phys_to_virt(sb->next);
+		kmem_cache_free(usb_desc_cache, sb);
+		sb = next_sb;
+	}
+
+	kmem_cache_free(usb_desc_cache, sb);
+
+	DBFEXIT;
+
+}
+
+static int handle_control_transfer_attn(char epid, int status)
+{
+	urb_t *old_urb;
+	etrax_urb_priv_t *hc_priv;	
+
+	DBFENTER;
+
+	clear_bit(epid, (void *)&ep_really_active);
+	
+	old_urb = URB_List[epid];
+	URB_List[epid] = old_urb->next;
+	
+	/* if (status == 0 && IN) find data and copy to urb */
+	if (status == 0 && usb_pipein(old_urb->pipe)) {
+		unsigned long flags;
+		etrax_urb_priv_t *urb_priv;
+
+		urb_priv = (etrax_urb_priv_t *)old_urb->hcpriv;
+		save_flags(flags);
+		cli();
+		if (urb_priv->eot == 1) {
+			old_urb->actual_length = urb_priv->rx_offset;
+			dbg_ctrl("urb_priv->rx_offset: %d in handle_control_attn", urb_priv->rx_offset);
+		} else {
+			status = -EPROTO;
+			old_urb->actual_length = 0;
+			err("(CTRL) No eot set in IN data!!! rx_offset: %d", urb_priv->rx_offset);
+		}
+
+		restore_flags(flags);
+	}
+	
+	/* If there are any more URB's in the list we'd better start sending */
+	if (URB_List[epid]) {
+		etrax_usb_do_ctrl_hw_add(URB_List[epid], epid,
+					 usb_maxpacket(URB_List[epid]->dev, URB_List[epid]->pipe,
+						       usb_pipeout(URB_List[epid]->pipe)));
+	}
+#if 1
+	else {
+		/* This means that this EP is now free, deconfigure it */
+		etrax_usb_free_epid(epid);
+	}
+#endif
+	
+	/* Remember to free the SB's */
+	hc_priv = (etrax_urb_priv_t *)old_urb->hcpriv;
+	cleanup_sb(hc_priv->first_sb);
+	kfree(hc_priv);
+
+	old_urb->status = status;
+	if (old_urb->complete) {
+		old_urb->complete(old_urb);
+	}
+
+	DBFEXIT;
+}
+
+
+
+static void etrax_usb_hc_intr_bottom_half(void *data)
+{
+	struct usb_reg_context *reg = (struct usb_reg_context *)data;
+	urb_t *old_urb;
+	
+	int error_code;
+	int epid;
+
+	__u32 r_usb_ept_data;
+
+	etrax_hc_t *hc = reg->hc; 
+	__u16 r_usb_rh_port_status_1;
+	__u16 r_usb_rh_port_status_2;
+	
+	DBFENTER;
+
+	if (reg->r_usb_irq_mask_read & IO_MASK(R_USB_IRQ_MASK_READ, port_status)) {
+
+		/*
+		  The Etrax RH does not include a wPortChange register, so this has
+		  to be handled in software. See section 11.16.2.6.2 in USB 1.1 spec
+		  for details.
+		*/
+		
+		r_usb_rh_port_status_1 = reg->r_usb_rh_port_status_1;
+		r_usb_rh_port_status_2 = reg->r_usb_rh_port_status_2;
+		
+		dbg_rh("port_status pending");
+		dbg_rh("r_usb_rh_port_status_1: 0x%04X", r_usb_rh_port_status_1);
+		dbg_rh("r_usb_rh_port_status_2: 0x%04X", r_usb_rh_port_status_2);
+
+		/* C_PORT_CONNECTION is set on any transition */
+		hc->rh.wPortChange_1 |=
+			((r_usb_rh_port_status_1 & (1 << RH_PORT_CONNECTION)) !=
+			 (hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_CONNECTION))) ?
+			(1 << RH_PORT_CONNECTION) : 0;
+		
+		hc->rh.wPortChange_2 |=
+			((r_usb_rh_port_status_2 & (1 << RH_PORT_CONNECTION)) !=
+			 (hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_CONNECTION))) ?
+			(1 << RH_PORT_CONNECTION) : 0;
+
+		/* C_PORT_ENABLE is _only_ set on a one to zero transition */
+		hc->rh.wPortChange_1 |=
+			((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_ENABLE))
+			 && !(r_usb_rh_port_status_1 & (1 << RH_PORT_ENABLE))) ?
+			(1 << RH_PORT_ENABLE) : 0;
+		
+		hc->rh.wPortChange_2 |=
+			((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_ENABLE))
+			 && !(r_usb_rh_port_status_2 & (1 << RH_PORT_ENABLE))) ?
+			(1 << RH_PORT_ENABLE) : 0;
+		
+		/* C_PORT_SUSPEND seems difficult, lets ignore it.. (for now) */
+		
+		/* C_PORT_RESET is _only_ set on a transition from the resetting state
+		   to the enabled state */
+		hc->rh.wPortChange_1 |=
+			((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_RESET))
+			 && (r_usb_rh_port_status_1 & (1 << RH_PORT_ENABLE))) ?
+			(1 << RH_PORT_RESET) : 0;
+		
+		hc->rh.wPortChange_2 |=
+			((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_RESET))
+			 && (r_usb_rh_port_status_2 & (1 << RH_PORT_ENABLE))) ?
+			(1 << RH_PORT_RESET) : 0;
+		
+		hc->rh.prev_wPortStatus_1 = r_usb_rh_port_status_1;
+		hc->rh.prev_wPortStatus_2 = r_usb_rh_port_status_2;	
+	}
+
+	for (epid = 0; epid < 32; epid++) {
+
+		unsigned long flags;
+
+		save_flags(flags);
+		cli();
+		*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop();
+		r_usb_ept_data = *R_USB_EPT_DATA;
+		restore_flags(flags);
+
+		if (r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, hold)) {
+			warn("Was hold for epid %d", epid);
+			continue;
+		}
+
+		if (!(r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, valid))) {
+			continue;
+		}
+		
+		
+		if (test_bit(epid, (void *)&reg->r_usb_epid_attn)) {
+
+			if (URB_List[epid] == NULL) {
+				err("R_USB_EPT_DATA is 0x%08X", r_usb_ept_data);
+				err("submit urb has been called %d times..", submit_urb_count);
+				err("EPID_ATTN for epid %d, with NULL entry in list", epid);
+				return;
+			}
+			
+			dbg_ep("r_usb_ept_data [%d] == 0x%08X", epid,
+			       r_usb_ept_data);
+			
+			error_code = IO_EXTRACT(R_USB_EPT_DATA, error_code,
+						r_usb_ept_data);
+			
+			if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
+				/* no_error means that this urb was successfully sent or that we have
+				   some undefinde error*/
+				
+				if (IO_EXTRACT(R_USB_EPT_DATA, error_count_out, r_usb_ept_data) == 3 ||
+				    IO_EXTRACT(R_USB_EPT_DATA, error_count_in, r_usb_ept_data) == 3) {
+				/* Actually there were transmission errors */
+					warn("Undefined error for endpoint %d", epid);
+					if (usb_pipetype(URB_List[epid]->pipe) == PIPE_CONTROL) {
+						handle_control_transfer_attn(epid, -EPROTO);
+					} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_BULK) {
+						handle_bulk_transfer_attn(epid, -EPROTO);
+					} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) {
+						handle_intr_transfer_attn(epid, -EPROTO);
+					}
+							   
+				} else {
+
+					if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) {
+						if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) {
+							etrax_usb_do_intr_recover(epid);
+						} else {
+							panic("Epid attention for epid %d (none INTR), with no errors and no "
+							      "exessive retry r_usb_status is 0x%02X\n",
+							      epid, reg->r_usb_status);
+						}
+						
+					} else if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) {
+						panic("Epid attention for epid %d, with no errors and no "
+						      "exessive retry r_usb_status is 0x%02X\n",
+						      epid, reg->r_usb_status);
+						
+					}
+					
+					warn("Epid attention for epid %d, with no errors and no "
+					     "exessive retry r_usb_status is 0x%02X",
+					     epid, reg->r_usb_status);
+					warn("OUT error count: %d", IO_EXTRACT(R_USB_EPT_DATA, error_count_out,
+									       r_usb_ept_data));
+					warn("IN  error count: %d", IO_EXTRACT(R_USB_EPT_DATA, error_count_in,
+									       r_usb_ept_data));
+					
+
+				}
+				
+			} else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, stall)) {
+				warn("Stall for endpoint %d", epid);
+				if (usb_pipetype(URB_List[epid]->pipe) == PIPE_CONTROL) {
+					handle_control_transfer_attn(epid, -EPIPE);
+				} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_BULK) {
+					handle_bulk_transfer_attn(epid, -EPIPE);
+				} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) {
+					handle_intr_transfer_attn(epid, -EPIPE);
+				}
+				
+				
+			} else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, bus_error)) {
+				panic("USB bus error for endpoint %d\n", epid);
+				
+			} else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, buffer_error)) {
+				warn("Buffer error for endpoint %d", epid);
+
+				if (usb_pipetype(URB_List[epid]->pipe) == PIPE_CONTROL) {
+					handle_control_transfer_attn(epid, -EPROTO);
+				} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_BULK) {
+					handle_bulk_transfer_attn(epid, -EPROTO);
+				} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) {
+					handle_intr_transfer_attn(epid, -EPROTO);
+				}
+
+			}
+		} else if (test_bit(epid, (void *)&ep_really_active)) {
+			/* Should really be else if (testbit(really active)) */
+
+			if (usb_pipetype(URB_List[epid]->pipe) == PIPE_CONTROL) {
+
+				if (!(TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable))) {
+					/* Now we have to verify that this CTRL endpoint got disabled
+					   cause it reached end of list with no error */
+					
+					if (IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data) ==
+					    IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
+						/*
+						  This means that the endpoint has no error, is disabled
+						  and had inserted traffic,
+						  i.e. transfer successfully completed
+						*/
+						dbg_ctrl("Last SB for CTRL %d sent successfully", epid);
+						handle_control_transfer_attn(epid, 0);
+					}
+				}
+				
+			} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_BULK) {
+				if (!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable))) {
+					/* Now we have to verify that this BULK endpoint go disabled
+					   cause it reached end of list with no error */
+
+					if (IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data) ==
+					    IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
+						/*
+						  This means that the endpoint has no error, is disabled
+						  and had inserted traffic,
+						  i.e. transfer successfully completed
+						*/
+						dbg_bulk("Last SB for BULK %d sent successfully", epid);
+						handle_bulk_transfer_attn(epid, 0);
+					}
+				}
+			} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) {
+				handle_intr_transfer_attn(epid, 0);
+			}
+		}
+		
+	}	
+
+	kfree(reg);
+
+	DBFEXIT;
+}
+
+
+static void etrax_usb_hc_intr_top_half(int irq, void *vhc, struct pt_regs *regs)
+{
+	struct usb_reg_context *reg;
+
+	DBFENTER;
+
+	reg = (struct usb_reg_context *)kmalloc(sizeof(struct usb_reg_context), GFP_ATOMIC);
+
+	if (!(reg)) {
+		panic("kmalloc failed in top_half\n");
+	}
+
+	reg->hc = (etrax_hc_t *)vhc;
+	reg->r_usb_irq_mask_read    = *R_USB_IRQ_MASK_READ;
+	reg->r_usb_status           = *R_USB_STATUS;
+
+#if 0
+	if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) {
+		panic("r_usb_status said perror\n");
+	}
+	if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) {
+		panic("r_usb_status said ourun !!!\n");
+	}
+#endif
+	
+	reg->r_usb_epid_attn        = *R_USB_EPID_ATTN;
+
+	reg->r_usb_rh_port_status_1 = *R_USB_RH_PORT_STATUS_1;
+	reg->r_usb_rh_port_status_2 = *R_USB_RH_PORT_STATUS_2;
+
+	reg->usb_bh.sync = 0;
+	reg->usb_bh.routine = etrax_usb_hc_intr_bottom_half;
+	reg->usb_bh.data = reg;
+
+	queue_task(&reg->usb_bh, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+
+	DBFEXIT;
+}
+
+static int etrax_rh_submit_urb(urb_t *urb)
+{
+	struct usb_device *usb_dev = urb->dev;
+	etrax_hc_t *hc = usb_dev->bus->hcpriv;
+	unsigned int pipe = urb->pipe;
+	devrequest *cmd = (devrequest *) urb->setup_packet;
+	void *data = urb->transfer_buffer;
+	int leni = urb->transfer_buffer_length;
+	int len = 0;
+	int status = 0;
+	int stat = 0;
+	int i;
+
+	__u16 cstatus;
+
+	__u16 bmRType_bReq;
+	__u16 wValue;
+	__u16 wIndex;
+	__u16 wLength;
+
+	DBFENTER;
+
+	if (usb_pipetype (pipe) == PIPE_INTERRUPT) {
+		dbg_rh("Root-Hub submit IRQ: every %d ms", urb->interval);
+		hc->rh.urb = urb;
+		hc->rh.send = 1;
+		hc->rh.interval = urb->interval;
+		etrax_rh_init_int_timer(urb);
+		DBFEXIT;
+		
+		return 0;
+	}
+
+	bmRType_bReq = cmd->requesttype | cmd->request << 8;
+	wValue = le16_to_cpu(cmd->value);
+	wIndex = le16_to_cpu(cmd->index);
+	wLength = le16_to_cpu(cmd->length);
+
+	dbg_rh("bmRType_bReq : 0x%04X (%d)", bmRType_bReq, bmRType_bReq);
+	dbg_rh("wValue       : 0x%04X (%d)", wValue, wValue);
+	dbg_rh("wIndex       : 0x%04X (%d)", wIndex, wIndex);
+	dbg_rh("wLength      : 0x%04X (%d)", wLength, wLength);
+	
+	switch (bmRType_bReq) {
+		
+		/* Request Destination:
+		   without flags: Device, 
+		   RH_INTERFACE: interface, 
+		   RH_ENDPOINT: endpoint,
+		   RH_CLASS means HUB here, 
+		   RH_OTHER | RH_CLASS  almost ever means HUB_PORT here 
+		 */
+
+	case RH_GET_STATUS:
+		*(__u16 *) data = cpu_to_le16 (1);
+		OK (2);
+		
+	case RH_GET_STATUS | RH_INTERFACE:
+		*(__u16 *) data = cpu_to_le16 (0);
+		OK (2);
+		
+	case RH_GET_STATUS | RH_ENDPOINT:
+		*(__u16 *) data = cpu_to_le16 (0);
+		OK (2);
+		
+	case RH_GET_STATUS | RH_CLASS:
+		*(__u32 *) data = cpu_to_le32 (0);
+		OK (4);		/* hub power ** */
+		
+	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+                if (wIndex == 1) {
+			*((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_1);
+			*((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_1);
+                }
+                else if (wIndex == 2) {
+			*((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_2);
+			*((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_2);
+                }
+                else {
+			dbg_rh("RH_GET_STATUS whith invalid wIndex !!");
+			OK(0);
+                }
+		
+                OK(4);
+                
+	case RH_CLEAR_FEATURE | RH_ENDPOINT:
+		switch (wValue) {
+		case (RH_ENDPOINT_STALL):
+			OK (0);
+		}
+		break;
+
+	case RH_CLEAR_FEATURE | RH_CLASS:
+		switch (wValue) {
+		case (RH_C_HUB_OVER_CURRENT):
+			OK (0);	/* hub power over current ** */
+		}
+		break;
+
+	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+		switch (wValue) {
+		case (RH_PORT_ENABLE):
+			if (wIndex == 1) {
+
+				dbg_rh("trying to do disable of port 1");
+
+				*R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, yes);
+				while (hc->rh.prev_wPortStatus_1 &
+				       IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, yes));
+				*R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, no);
+				dbg_rh("Port 1 is disabled");
+
+			} else if (wIndex == 2) {
+
+				dbg_rh("trying to do disable of port 2");
+				
+				*R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, yes);
+				while (hc->rh.prev_wPortStatus_2 &
+				       IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, yes));
+				*R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, no);
+				dbg_rh("Port 2 is disabled");
+
+			} else {
+				dbg_rh("RH_CLEAR_FEATURE->RH_PORT_ENABLE "
+				       "with invalid wIndex == %d!!", wIndex);
+			}			
+				
+			OK (0);
+		case (RH_PORT_SUSPEND):
+			/* Opposite to suspend should be resume, so well do a resume */
+			if (wIndex == 1) {
+				*R_USB_COMMAND =
+					IO_STATE(R_USB_COMMAND, port_sel, port1) |
+					IO_STATE(R_USB_COMMAND, port_cmd, resume)|
+					IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
+			} else if (wIndex == 2) {
+				*R_USB_COMMAND =
+					IO_STATE(R_USB_COMMAND, port_sel, port2) |
+					IO_STATE(R_USB_COMMAND, port_cmd, resume)|
+					IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
+			} else {
+				dbg_rh("RH_CLEAR_FEATURE->RH_PORT_SUSPEND "
+				       "with invalid wIndex == %d!!", wIndex);
+			}
+			
+			OK (0);
+		case (RH_PORT_POWER):
+			OK (0);	/* port power ** */
+		case (RH_C_PORT_CONNECTION):
+			
+                        if (wIndex == 1) {
+				hc->rh.wPortChange_1 &= ~(1 << RH_PORT_CONNECTION);
+                        }
+                        else if (wIndex == 2) {
+				hc->rh.wPortChange_2 &= ~(1 << RH_PORT_CONNECTION);
+                        }
+                        else {
+				dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_CONNECTION "
+				       "with invalid wIndex == %d!!", wIndex);
+                        }
+
+			OK (0);
+		case (RH_C_PORT_ENABLE):
+			if (wIndex == 1) {
+				hc->rh.wPortChange_1 &= ~(1 << RH_PORT_ENABLE);
+			}
+			else if (wIndex == 2) {
+				hc->rh.wPortChange_2 &= ~(1 << RH_PORT_ENABLE);
+			}
+			else {
+				dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_ENABLE "
+				       "with invalid wIndex == %d!!", wIndex);
+			}
+			OK (0);
+		case (RH_C_PORT_SUSPEND):
+/*** WR_RH_PORTSTAT(RH_PS_PSSC); */
+			OK (0);
+		case (RH_C_PORT_OVER_CURRENT):
+			OK (0);	/* port power over current ** */
+		case (RH_C_PORT_RESET):
+			if (wIndex == 1) {
+				hc->rh.wPortChange_1 &= ~(1 << RH_PORT_RESET);
+			}
+			else if (wIndex == 2) {
+				dbg_rh("This is wPortChange before clear: 0x%04X", hc->rh.wPortChange_2);
+				
+				hc->rh.wPortChange_2 &= ~(1 << RH_PORT_RESET);
+				dbg_rh("This is wPortChange after clear: 0x%04X", hc->rh.wPortChange_2);
+			} else {
+				dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_RESET "
+				       "with invalid index == %d!!", wIndex);
+			}
+
+			OK (0);
+		
+		}
+		break;
+		
+	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+		switch (wValue) {
+		case (RH_PORT_SUSPEND):
+			if (wIndex == 1) {
+				*R_USB_COMMAND =
+					IO_STATE(R_USB_COMMAND, port_sel, port1) |
+					IO_STATE(R_USB_COMMAND, port_cmd, suspend) |
+					IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
+			} else if (wIndex == 2) {
+				*R_USB_COMMAND =
+					IO_STATE(R_USB_COMMAND, port_sel, port2) |
+					IO_STATE(R_USB_COMMAND, port_cmd, suspend) |
+					IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
+			} else {
+				dbg_rh("RH_SET_FEATURE->RH_C_PORT_SUSPEND "
+				       "with invalid wIndex == %d!!", wIndex);
+			}			
+
+			OK (0);
+		case (RH_PORT_RESET):
+                        if (wIndex == 1) {
+				int port1_retry;
+				
+			port1_redo:
+				dbg_rh("Doing reset of port 1");
+
+				*R_USB_COMMAND =
+					IO_STATE(R_USB_COMMAND, port_cmd, reset) |
+					IO_STATE(R_USB_COMMAND, port_sel, port1);
+
+				/* We must once again wait at least 10ms for the device to recover */
+
+				port1_retry = 0;
+				while (!((*((volatile __u16 *)&hc->rh.prev_wPortStatus_1)) &
+					 IO_STATE(R_USB_RH_PORT_STATUS_1,
+						  enabled, yes))) {
+					printk(""); if (port1_retry++ >= 10000) {goto port1_redo;}
+				}
+				
+				/* This only seems to work if we use printk,
+				   not even schedule() works !!! WHY ?? */
+
+				udelay(15000);
+                        }
+                        else if (wIndex == 2) {
+				int port2_retry;
+				
+			port2_redo:
+				dbg_rh("Doing reset of port 2");
+				
+				*R_USB_COMMAND =
+					IO_STATE(R_USB_COMMAND, port_cmd, reset) |
+					IO_STATE(R_USB_COMMAND, port_sel, port2);
+
+				/* We must once again wait at least 10ms for the device to recover */
+
+				port2_retry = 0;
+				while (!((*((volatile __u16 *)&hc->rh.prev_wPortStatus_2)) &
+					 IO_STATE(R_USB_RH_PORT_STATUS_2,
+						  enabled, yes))) {
+					printk(""); if (port2_retry++ >= 10000) {goto port2_redo;}
+				}
+				
+				/* This only seems to work if we use printk,
+				   not even schedule() works !!! WHY ?? */
+
+				udelay(15000);
+                        }
+
+			/* Try to bring the HC into running state */
+			*R_USB_COMMAND =
+				IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run);
+			
+			nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
+			
+                        dbg_rh("...Done");
+                        OK(0);
+                        
+		case (RH_PORT_POWER):
+			OK (0);	/* port power ** */
+		case (RH_PORT_ENABLE):
+			/* There is no rh port enable command in the Etrax USB interface!!!! */
+			OK (0);
+                        
+		}
+		break;
+		
+	case RH_SET_ADDRESS:
+		hc->rh.devnum = wValue;
+                dbg_rh("RH address set to: %d", hc->rh.devnum);
+		OK (0);
+		
+	case RH_GET_DESCRIPTOR:
+		switch ((wValue & 0xff00) >> 8) {
+		case (0x01):	/* device descriptor */
+			len = min (leni, min (sizeof (root_hub_dev_des), wLength));
+			memcpy (data, root_hub_dev_des, len);
+			OK (len);
+		case (0x02):	/* configuration descriptor */
+			len = min (leni, min (sizeof (root_hub_config_des), wLength));
+			memcpy (data, root_hub_config_des, len);
+			OK (len);
+		case (0x03):	/* string descriptors */
+			len = usb_root_hub_string (wValue & 0xff,
+						   0xff, "ETRAX 100LX",
+						   data, wLength);
+			if (len > 0) {
+				OK (min (leni, len));
+			} else 
+				stat = -EPIPE;
+		}
+		break;
+		
+	case RH_GET_DESCRIPTOR | RH_CLASS:
+		root_hub_hub_des[2] = hc->rh.numports;
+		len = min (leni, min (sizeof (root_hub_hub_des), wLength));
+		memcpy (data, root_hub_hub_des, len);
+		OK (len);
+		
+	case RH_GET_CONFIGURATION:
+		*(__u8 *) data = 0x01;
+		OK (1);
+		
+	case RH_SET_CONFIGURATION:
+		OK (0);
+		
+	default:
+		stat = -EPIPE;
+	}
+
+	urb->actual_length = len;
+	urb->status = stat;
+	urb->dev=NULL;
+	if (urb->complete) {
+		urb->complete (urb);
+	}
+	DBFEXIT;
+	
+	return 0;
+}
+
+static int __init etrax_usb_hc_init(void)
+{
+	static etrax_hc_t *hc;
+	struct usb_bus *bus;
+	struct usb_device *usb_rh;
+	
+	DBFENTER;
+
+	info("ETRAX 100LX USB-HCD %s (c) 2001 Axis Communications AB\n", usb_hcd_version);
+	
+	hc = kmalloc(sizeof(etrax_hc_t), GFP_KERNEL);
+
+	/* We use kmem_cache_* to make sure that all DMA desc. are dword aligned */
+	usb_desc_cache = kmem_cache_create("usb_desc_cache", sizeof(USB_EP_Desc_t), 0, 0, 0, 0);
+	if (!usb_desc_cache) {
+		panic("USB Desc Cache allocation failed !!!\n");
+	}
+	
+	etrax_usb_bus = bus = usb_alloc_bus(&etrax_usb_device_operations);
+	hc->bus = bus;
+	bus->hcpriv = hc;
+        
+	/* Initalize RH to the default address.
+	   And make sure that we have no status change indication */
+	hc->rh.numports = 2;  /* The RH has two ports */
+	hc->rh.devnum = 0;
+	hc->rh.wPortChange_1 = 0;
+	hc->rh.wPortChange_2 = 0;
+
+	/* Also initate the previous values to zero */
+	hc->rh.prev_wPortStatus_1 = 0;
+	hc->rh.prev_wPortStatus_2 = 0;
+
+	/* Initialize the intr-traffic flags */
+	hc->intr.sleeping = 0;
+	hc->intr.wq = NULL;
+        
+	/* Initially all ep's are free except ep 0 */
+	ep_usage_bitmask = 0;
+	set_bit(0, (void *)&ep_usage_bitmask);
+	ep_really_active = 0;
+
+	memset(URB_List, 0, sizeof(URB_List));
+
+	/* This code should really be moved */
+
+        if (request_dma(8, "ETRAX 100LX built-in USB (Tx)")) {
+		err("Could not allocate DMA ch 8 for USB");
+		etrax_usb_hc_cleanup();
+		DBFEXIT;
+		return -1;
+	}
+	
+	if (request_dma(9, "ETRAX 100LX built-in USB (Rx)")) {
+		err("Could not allocate DMA ch 9 for USB");
+		etrax_usb_hc_cleanup();
+		DBFEXIT;
+		return -1;
+	}	
+#if 0  /* Moved to head.S */        
+	*R_GEN_CONFIG = genconfig_shadow =
+		(genconfig_shadow & ~(IO_MASK(R_GEN_CONFIG, usb1) |
+				      IO_MASK(R_GEN_CONFIG, usb2) |
+				      IO_MASK(R_GEN_CONFIG, dma8) |
+				      IO_MASK(R_GEN_CONFIG, dma9))) |
+		IO_STATE(R_GEN_CONFIG, dma8, usb) |
+		IO_STATE(R_GEN_CONFIG, dma9, usb)
+#ifdef CONFIG_ETRAX_USB_HOST_PORT1
+		| IO_STATE(R_GEN_CONFIG, usb1, select)
+#endif
+#ifdef CONFIG_ETRAX_USB_HOST_PORT2
+		| IO_STATE(R_GEN_CONFIG, usb2, select)
+#endif
+	;
+#endif
+	
+	usb_register_bus(hc->bus);
+
+	/* We may have to set more bits, but these are the obvious ones */
+	*R_IRQ_MASK2_SET =
+		IO_STATE(R_IRQ_MASK2_SET, dma8_sub0_descr, set) |
+		IO_STATE(R_IRQ_MASK2_SET, dma8_sub1_descr, set) |
+		IO_STATE(R_IRQ_MASK2_SET, dma8_sub2_descr, set) |
+		IO_STATE(R_IRQ_MASK2_SET, dma8_sub3_descr, set);
+
+	*R_IRQ_MASK2_SET =
+		IO_STATE(R_IRQ_MASK2_SET, dma9_eop, set) |
+		IO_STATE(R_IRQ_MASK2_SET, dma9_descr, set);
+
+	*R_USB_IRQ_MASK_SET = 
+		IO_STATE(R_USB_IRQ_MASK_SET, ctl_status, set) |
+		IO_STATE(R_USB_IRQ_MASK_SET, ctl_eot, set) |
+		IO_STATE(R_USB_IRQ_MASK_SET, bulk_eot, set) |
+#ifdef ETRAX_USB_INTR_IRQ
+		IO_STATE(R_USB_IRQ_MASK_SET, intr_eot, set) |
+#endif
+		IO_STATE(R_USB_IRQ_MASK_SET, epid_attn, set) |
+		IO_STATE(R_USB_IRQ_MASK_SET, port_status, set);
+	
+	if (request_irq(ETRAX_USB_HC_IRQ, etrax_usb_hc_intr_top_half, 0,
+			"ETRAX 100LX built-in USB (HC)", hc)) {
+		err("Could not allocate IRQ %d for USB", ETRAX_USB_HC_IRQ);
+		etrax_usb_hc_cleanup();
+		DBFEXIT;
+		return -1;
+	}
+	
+	if (request_irq(ETRAX_USB_RX_IRQ, etrax_usb_rx_interrupt, 0,
+			"ETRAX 100LX built-in USB (Rx)", hc)) {
+		err("Could not allocate IRQ %d for USB", ETRAX_USB_RX_IRQ);
+		etrax_usb_hc_cleanup();
+		DBFEXIT;
+		return -1;
+	}
+	
+	if (request_irq(ETRAX_USB_TX_IRQ, etrax_usb_tx_interrupt, 0,
+			"ETRAX 100LX built-in USB (Tx)", hc)) {
+		err("Could not allocate IRQ %d for USB", ETRAX_USB_TX_IRQ);
+		etrax_usb_hc_cleanup();
+		DBFEXIT;
+		return -1;
+	}
+
+	/* Reset the USB interface (configures as HC) */
+	*R_USB_COMMAND =
+		IO_STATE(R_USB_COMMAND, ctrl_cmd, reset) |
+		IO_STATE(R_USB_COMMAND, port_cmd, reset);
+	
+	nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
+#if 1
+	/* Initate PSTART to all unallocatable bit times */
+	*R_USB_FM_PSTART = IO_FIELD(R_USB_FM_PSTART, value, 10000);
+#endif
+
+#ifdef CONFIG_ETRAX_USB_HOST_PORT1
+	*R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, no);
+#endif
+	
+#ifdef CONFIG_ETRAX_USB_HOST_PORT2
+	*R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, no);
+#endif
+	
+	*R_USB_COMMAND =
+		IO_STATE(R_USB_COMMAND, ctrl_cmd, host_config) |
+		IO_STATE(R_USB_COMMAND, port_cmd, reset);
+	
+	nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
+
+	*R_USB_COMMAND =
+		IO_STATE(R_USB_COMMAND, port_sel, port1) |
+		IO_STATE(R_USB_COMMAND, port_cmd, reset);
+
+	nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
+
+	/* Here we must wait at least 10ms so the device has time to recover */
+	udelay(15000);
+
+	init_rx_buffers();
+	init_tx_bulk_ep();
+	init_tx_ctrl_ep();
+	init_tx_intr_ep();
+
+	/* This works. It seems like the host_run command only has effect when a device is connected,
+	 i.e. it has to be done when a interrup */
+	*R_USB_COMMAND =
+		IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run);
+	
+	nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
+
+	usb_rh = usb_alloc_dev(NULL, hc->bus);
+	hc->bus->root_hub = usb_rh;
+	usb_connect(usb_rh);
+	usb_new_device(usb_rh);
+
+	DBFEXIT;
+	
+	return 0;
+}
+
+static void etrax_usb_hc_cleanup(void)
+{
+	DBFENTER;
+	
+	free_irq(ETRAX_USB_HC_IRQ, NULL);
+	free_irq(ETRAX_USB_RX_IRQ, NULL);
+	free_irq(ETRAX_USB_TX_IRQ, NULL);
+
+	free_dma(8);
+	free_dma(9);
+	usb_deregister_bus(etrax_usb_bus);
+
+	DBFEXIT;
+}
+
+module_init(etrax_usb_hc_init);
+module_exit(etrax_usb_hc_cleanup);
diff -u --recursive --new-file v2.4.3/linux/arch/cris/drivers/usb-host.h linux/arch/cris/drivers/usb-host.h
--- v2.4.3/linux/arch/cris/drivers/usb-host.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/usb-host.h	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,245 @@
+#ifndef __LINUX_ETRAX_USB_H
+#define __LINUX_ETRAX_USB_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+typedef struct USB_IN_Desc {
+	__u16 sw_len;
+	__u16 command;
+	unsigned long next;
+	unsigned long buf;
+	__u16 hw_len;
+	__u16 status;
+} USB_IN_Desc_t;
+
+typedef struct USB_SB_Desc {
+	__u16 sw_len;
+	__u16 command;
+	unsigned long next;
+	unsigned long buf;
+	__u32 dummy;
+} USB_SB_Desc_t;
+
+typedef struct USB_EP_Desc {
+	__u16 hw_len;
+	__u16 command;
+	unsigned long sub;
+	unsigned long nep;
+	__u32 dummy;
+} USB_EP_Desc_t;
+
+struct virt_root_hub {
+	int devnum;
+	void *urb;
+	void *int_addr;
+	int send;
+	int interval;
+	int numports;
+	struct timer_list rh_int_timer;
+	__u16 wPortChange_1;
+	__u16 wPortChange_2;
+	__u16 prev_wPortStatus_1;
+	__u16 prev_wPortStatus_2;
+};
+
+struct etrax_usb_intr_traffic {
+	int sleeping;
+	int error;
+	struct wait_queue *wq;
+};
+
+typedef struct etrax_usb_hc {
+	struct usb_bus *bus;
+	struct virt_root_hub rh;
+	struct etrax_usb_intr_traffic intr;
+} etrax_hc_t;
+
+typedef enum {idle, eot, nodata}  etrax_usb_rx_state_t;
+
+typedef struct etrax_usb_urb_priv {
+	USB_SB_Desc_t *first_sb;
+	__u32 rx_offset;
+	etrax_usb_rx_state_t rx_state;
+	__u8 eot;
+	struct list_head ep_in_list;
+} etrax_urb_priv_t;
+
+
+struct usb_reg_context
+{
+	etrax_hc_t *hc;
+	__u32 r_usb_epid_attn;
+	__u8 r_usb_status;
+	__u32 r_usb_rh_port_status_1;
+	__u32 r_usb_rh_port_status_2;
+	__u32 r_usb_irq_mask_read;
+	struct tq_struct usb_bh;
+#if 0
+	__u32 r_usb_ept_data[32];
+#endif
+};
+
+struct in_chunk
+{
+	void *data;
+	int length;
+	char epid;
+	struct list_head list;
+};
+
+  
+/* --------------------------------------------------------------------------- 
+   Virtual Root HUB 
+   ------------------------------------------------------------------------- */
+/* destination of request */
+#define RH_INTERFACE               0x01
+#define RH_ENDPOINT                0x02
+#define RH_OTHER                   0x03
+
+#define RH_CLASS                   0x20
+#define RH_VENDOR                  0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS           0x0080
+#define RH_CLEAR_FEATURE        0x0100
+#define RH_SET_FEATURE          0x0300
+#define RH_SET_ADDRESS		0x0500
+#define RH_GET_DESCRIPTOR	0x0680
+#define RH_SET_DESCRIPTOR       0x0700
+#define RH_GET_CONFIGURATION	0x0880
+#define RH_SET_CONFIGURATION	0x0900
+#define RH_GET_STATE            0x0280
+#define RH_GET_INTERFACE        0x0A80
+#define RH_SET_INTERFACE        0x0B00
+#define RH_SYNC_FRAME           0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP               0x2000
+
+
+/* Hub port features */
+#define RH_PORT_CONNECTION         0x00
+#define RH_PORT_ENABLE             0x01
+#define RH_PORT_SUSPEND            0x02
+#define RH_PORT_OVER_CURRENT       0x03
+#define RH_PORT_RESET              0x04
+#define RH_PORT_POWER              0x08
+#define RH_PORT_LOW_SPEED          0x09
+#define RH_C_PORT_CONNECTION       0x10
+#define RH_C_PORT_ENABLE           0x11
+#define RH_C_PORT_SUSPEND          0x12
+#define RH_C_PORT_OVER_CURRENT     0x13
+#define RH_C_PORT_RESET            0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER       0x00
+#define RH_C_HUB_OVER_CURRENT      0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP    0x00
+#define RH_ENDPOINT_STALL          0x01
+
+/* Our Vendor Specific feature */
+#define RH_REMOVE_EP               0x00
+
+
+#define RH_ACK                     0x01
+#define RH_REQ_ERR                 -1
+#define RH_NACK                    0x00
+
+#define min(a,b) (((a)<(b))?(a):(b))
+
+/* Field definitions for */
+
+#define USB_IN_command__eol__BITNR      0 /* command macros */
+#define USB_IN_command__eol__WIDTH      1
+#define USB_IN_command__eol__no         0
+#define USB_IN_command__eol__yes        1
+
+#define USB_IN_command__intr__BITNR     3
+#define USB_IN_command__intr__WIDTH     1
+#define USB_IN_command__intr__no        0
+#define USB_IN_command__intr__yes       1
+
+#define USB_IN_status__eop__BITNR       1 /* status macros. */
+#define USB_IN_status__eop__WIDTH       1
+#define USB_IN_status__eop__no          0
+#define USB_IN_status__eop__yes         1
+
+#define USB_IN_status__eot__BITNR       5
+#define USB_IN_status__eot__WIDTH       1
+#define USB_IN_status__eot__no          0
+#define USB_IN_status__eot__yes         1
+
+#define USB_IN_status__error__BITNR     6
+#define USB_IN_status__error__WIDTH     1
+#define USB_IN_status__error__no        0
+#define USB_IN_status__error__yes       1
+
+#define USB_IN_status__nodata__BITNR    7
+#define USB_IN_status__nodata__WIDTH    1
+#define USB_IN_status__nodata__no       0
+#define USB_IN_status__nodata__yes      1
+
+#define USB_IN_status__epid__BITNR      8
+#define USB_IN_status__epid__WIDTH      5
+
+#define USB_EP_command__eol__BITNR      0
+#define USB_EP_command__eol__WIDTH      1
+#define USB_EP_command__eol__no         0
+#define USB_EP_command__eol__yes        1
+
+#define USB_EP_command__eof__BITNR      1
+#define USB_EP_command__eof__WIDTH      1
+#define USB_EP_command__eof__no         0
+#define USB_EP_command__eof__yes        1
+
+#define USB_EP_command__intr__BITNR     3
+#define USB_EP_command__intr__WIDTH     1
+#define USB_EP_command__intr__no        0
+#define USB_EP_command__intr__yes       1
+
+#define USB_EP_command__enable__BITNR   4
+#define USB_EP_command__enable__WIDTH   1
+#define USB_EP_command__enable__no      0
+#define USB_EP_command__enable__yes     1
+
+#define USB_EP_command__hw_valid__BITNR 5
+#define USB_EP_command__hw_valid__WIDTH 1
+#define USB_EP_command__hw_valid__no    0
+#define USB_EP_command__hw_valid__yes   1
+
+#define USB_EP_command__epid__BITNR     8
+#define USB_EP_command__epid__WIDTH     5
+
+#define USB_SB_command__eol__BITNR      0 /* command macros. */
+#define USB_SB_command__eol__WIDTH      1
+#define USB_SB_command__eol__no         0
+#define USB_SB_command__eol__yes        1
+
+#define USB_SB_command__eot__BITNR      1
+#define USB_SB_command__eot__WIDTH      1
+#define USB_SB_command__eot__no         0
+#define USB_SB_command__eot__yes        1
+
+#define USB_SB_command__intr__BITNR     3
+#define USB_SB_command__intr__WIDTH     1
+#define USB_SB_command__intr__no        0
+#define USB_SB_command__intr__yes       1
+
+#define USB_SB_command__tt__BITNR       4
+#define USB_SB_command__tt__WIDTH       2
+#define USB_SB_command__tt__zout        0
+#define USB_SB_command__tt__in          1
+#define USB_SB_command__tt__out         2
+#define USB_SB_command__tt__setup       3
+
+
+#define USB_SB_command__rem__BITNR      8
+#define USB_SB_command__rem__WIDTH      6
+
+#define USB_SB_command__full__BITNR     6
+#define USB_SB_command__full__WIDTH     1
+#define USB_SB_command__full__no        0
+#define USB_SB_command__full__yes       1
+
+#endif
diff -u --recursive --new-file v2.4.3/linux/arch/cris/kernel/entry.S linux/arch/cris/kernel/entry.S
--- v2.4.3/linux/arch/cris/kernel/entry.S	Fri Mar  2 18:38:40 2001
+++ linux/arch/cris/kernel/entry.S	Fri Apr  6 10:42:55 2001
@@ -1,12 +1,30 @@
-/* $Id: entry.S,v 1.11 2001/01/10 21:13:29 bjornw Exp $
+/* $Id: entry.S,v 1.15 2001/03/05 13:14:30 bjornw Exp $
  *
  *  linux/arch/cris/entry.S
  *
- *  Copyright (C) 2000 Axis Communications AB
+ *  Copyright (C) 2000, 2001 Axis Communications AB
  *
  *  Authors:	Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: entry.S,v $
+ *  Revision 1.15  2001/03/05 13:14:30  bjornw
+ *  Spelling fix
+ *
+ *  Revision 1.14  2001/02/23 08:36:36  perf
+ *  New ABI; syscallnr=r9, arg5=mof, arg6=srp.
+ *  Corrected tracesys call check.
+ *
+ *  Revision 1.13  2001/02/15 08:40:55  perf
+ *  H-P by way of perf;
+ *  - (_system_call): Don't read system call function address into r1.
+ *  - (RBFExit): There is no such thing as a null pop.  Adjust sp by addq.
+ *  - (_system_call): Don't use r10 and don't save and restore it.
+ *  - (THREAD_ESP0): New constant.
+ *  - (_system_call): Inline set_esp0.
+ *
+ *  Revision 1.12  2001/01/31 17:56:25  orjanf
+ *  Added definition of LTASK_PID and made it global.
+ *
  *  Revision 1.11  2001/01/10 21:13:29  bjornw
  *  SYMBOL_NAME is defined incorrectly for the compiler options we currently use
  *
@@ -79,7 +97,8 @@
 	.globl _mmu_bus_fault
 				
 	.globl _sys_call_table
-		
+	
+	.globl LTASK_PID	
 	;; syscall error codes
 	
 LENOSYS = 38
@@ -90,7 +109,17 @@
 LTASK_SIGPENDING  =  8
 LTASK_NEEDRESCHED = 20
 LTASK_PTRACE      = 24
+LTASK_PID         = 105
+
+	;; process bits for ptrace
 
+PT_TRACESYS_BIT	  = 1
+
+	;; Offset for esp0 into task_struct: current->thread.esp0.
+	;; FIXME: In need of padding somewhere, to get dword-alignment.
+
+THREAD_ESP0	  = 597
+	
 	;; some pt_regs offsets (from ptrace.h)
 	
 LORIG_R10	= 4
@@ -98,8 +127,8 @@
 LR12		= 12
 LR11		= 16
 LR10		= 20
-LR1		= 56
-LR0		= 60	
+LR9		= 24
+LMOF		= 64
 LDCCR		= 68
 LSRP		= 72
 LIRP		= 76
@@ -124,7 +153,7 @@
 	nop
 	ba	ret_with_reschedule  ; go back but check schedule and signals first 
 	nop
-		
+
 reschedule:
 	;; keep r9 intact
 	push	r9
@@ -170,41 +199,38 @@
 	push	r10		; push orig_r10
 	clear.d [sp=sp-4]	; frametype == 0, normal stackframe
 	
-	move.d	r10,r2		; save for later
-	
-	movs.w	-LENOSYS,r10
-	move.d	r10,[sp+LR10]	; put the default return value in r10 in the frame
-	
-	move.d	sp,r10
-	jsr	_set_esp0	; save top of frame (clobbers r9...)
+	movs.w	-LENOSYS,r0
+	move.d	r0,[sp+LR10]	; put the default return value in r10 in the frame
+
+	;; Perform "current->thread.esp0 = sp".
+	;; This used to be a separate function; set_esp0(ssp).
+	movs.w -8192,r0		; THREAD_SIZE == 8192
+	and.d sp,r0
+
+	move.d sp,[r0+THREAD_ESP0]
 
 	;; check if this process is syscall-traced
 
-	move.d	sp, r10
-	and.d	-8192, r10		; THREAD_SIZE == 8192
-	move.d	[r10+LTASK_PTRACE],r10
-	btstq	2, r10	                ; PT_TRACESYS
+	move.d	[r0+LTASK_PTRACE],r0
+	btstq	PT_TRACESYS_BIT, r0
 	bmi	tracesys
 	nop	
 
 	;; check for sanity in the requested syscall number
 	
-	cmpu.w	NR_syscalls,r1	
+	cmpu.w	NR_syscalls,r9	
 	bcc	_ret_from_sys_call
-	lslq	2,r1		;  multiply by 4, in the delay slot
-
-	;; read the system call vector into r1
-	
-	move.d	[r1+_sys_call_table],r1	
+	lslq	2,r9		;  multiply by 4, in the delay slot
 
-	;; the parameter carrying registers r11, r12 and 13 are intact - restore r10.
-	;; the fifth parameter (if any) was in r0, and we need to put it on the stack
+	;; the parameter carrying registers r10, r11, r12 and 13 are intact.
+	;; the fifth and sixth parameters (if any) was in mof and srp 
+	;; respectively, and we need to put them on the stack.
 
-	push	r0
-	move.d	r2,r10
+	push	srp
+	push	mof
 	
-	jsr	r1		; actually call the corresponding system call
-	addq	4,sp		; pop the r0 parameter
+	jsr	[r9+_sys_call_table]	; actually do the system call
+	addq	2*4,sp		; pop the mof and srp parameters
 	move.d	r10,[sp+LR10]	; save the return value
 
 	moveq	1,r9		; "parameter" to ret_from_sys_call to show it was a sys call
@@ -269,10 +295,8 @@
 	;; just get the PC value to restart it with, and skip the rest of
 	;; the frame.
 	pop	irp		; fixup location will be here
-	pop	p8		; null pop
-	pop	p8		; null pop
 	reti			; return to IRP, taking U-flag into account
-	pop	p8		; null pop in delayslot
+	addq	12,sp		; Skip rest of SBFS frame.
 
 
 tracesys:
@@ -289,30 +313,32 @@
 
 	;; check for sanity in the requested syscall number
 
-	move.d	[sp+LR1], r1
+	move.d	[sp+LR9], r9
 	movs.w	-LENOSYS, r10
-	cmpu.w	NR_syscalls,r1	
+	cmpu.w	NR_syscalls,r9	
 	bcc	1f
-	lslq	2,r1		;  multiply by 4, in the delay slot
+	lslq	2,r9		;  multiply by 4, in the delay slot
 
-	;; read the system call vector entry into r1
+	;; read the system call vector entry into r9
 	
-	move.d	[r1+_sys_call_table],r1
+	move.d	[r9+_sys_call_table],r9
 
-	;; restore r10, r11, r12, r13 and r0 into the needed registers
+	;; restore r10, r11, r12, r13, mof and srp into the needed registers
 
 	move.d	[sp+LORIG_R10], r10  ; LR10 is already filled with -LENOSYS
 	move.d	[sp+LR11],      r11
 	move.d	[sp+LR12],      r12
 	move.d	[sp+LR13],      r13
-	move.d	[sp+LR0],       r0
+	move	[sp+LMOF],      mof
+	move	[sp+LSRP],      srp
 
-	;; the fifth parameter needs to be put on the stack for the system
-	;; call to find it
+	;; the fifth and sixth parameters needs to be put on the stack for
+	;; the system call to find them
 
-	push	r0
-	jsr	r1		; actually call the system-call
-	addq	4,sp		; pop the r0 parameter
+	push	srp
+	push	mof
+	jsr	r9		; actually call the system-call
+	addq	2*4,sp		; pop the r0 parameter
 
 1:	move.d	r10,[sp+LR10]	; save the return value
 
diff -u --recursive --new-file v2.4.3/linux/arch/cris/kernel/head.S linux/arch/cris/kernel/head.S
--- v2.4.3/linux/arch/cris/kernel/head.S	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/head.S	Fri Apr  6 10:42:55 2001
@@ -1,46 +1,75 @@
-	;; $Id: head.S,v 1.11 2001/01/16 16:31:38 bjornw Exp $
-	;; 
-	;; Head of the kernel - alter with care
-	;;
-	;; Copyright (C) 2000, 2001 Axis Communications AB
-	;;
-	;; Authors:	Bjorn Wesen (bjornw@axis.com)
-	;; 
-	;; $Log: head.S,v $
-	;; Revision 1.11  2001/01/16 16:31:38  bjornw
-	;; * Changed name and semantics of running_from_flash to romfs_in_flash,
-	;;   set by head.S to indicate to setup.c whether there is a cramfs image
-	;;   after the kernels BSS or not. Should work for all three boot-cases
-	;;   (DRAM with cramfs in DRAM, DRAM with cramfs in flash (compressed boot),
-	;;    and flash with cramfs in flash)
-	;;
-	;; Revision 1.10  2001/01/16 14:12:21  bjornw
-	;; * Check for cramfs start passed in r9 from the decompressor, if all other
-	;;   cramfs options fail (if we boot from DRAM but don't find a cramfs image
-	;;   after the kernel in DRAM, it is probably still in the flash)
-	;; * Check magic in cramfs detection when booting from flash directly
-	;;
-	;; Revision 1.9  2001/01/15 17:17:02  bjornw
-	;; * Corrected the code that detects the cramfs lengths
-	;; * Added a comment saying that the above does not work due to other
-	;;   reasons..
-	;;
-	;; Revision 1.8  2001/01/15 16:27:51  jonashg
-	;; Made boot after flashing work.
-	;; * end destination is __vmlinux_end in RAM.
-	;; * _romfs_start moved because of virtual memory.
-	;;
-	;; Revision 1.7  2000/11/21 13:55:29  bjornw
-	;; Use CONFIG_CRIS_LOW_MAP for the low VM map instead of explicit CPU type
-	;;
-	;; Revision 1.6  2000/10/06 12:36:55  bjornw
-	;; Forgot swapper_pg_dir when changing memory map..
-	;;
-	;; Revision 1.5  2000/10/04 16:49:30  bjornw
-	;; * Fixed memory mapping in LX
-	;; * Check for cramfs instead of romfs
-	;;
-	;;
+/* $Id: head.S,v 1.20 2001/02/23 12:47:56 bjornw Exp $
+ * 
+ * Head of the kernel - alter with care
+ *
+ * Copyright (C) 2000, 2001 Axis Communications AB
+ *
+ * Authors:	Bjorn Wesen (bjornw@axis.com)
+ * 
+ * $Log: head.S,v $
+ * Revision 1.20  2001/02/23 12:47:56  bjornw
+ * MMU regs during LOW_MAP updated to reflect a newer reality
+ *
+ * Revision 1.19  2001/02/19 11:12:07  bjornw
+ * Changed comment header format
+ *
+ * Revision 1.18  2001/02/15 07:25:38  starvik
+ * Added support for synchronous serial ports
+ *
+ * Revision 1.17  2001/02/08 15:53:13  starvik
+ * Last commit removed some important ifdefs
+ *
+ * Revision 1.16  2001/02/08 15:20:38  starvik
+ * Include dram_init.S as inline
+ *
+ * Revision 1.15  2001/01/29 18:12:01  bjornw
+ * Corrected some comments
+ *
+ * Revision 1.14  2001/01/29 13:11:29  starvik
+ * Include dram_init.S (with DRAM/SDRAM initialization)
+ *
+ * Revision 1.13  2001/01/23 14:54:57  markusl
+ * Updated for USB
+ * i.e. added r_gen_config settings
+ *
+ * Revision 1.12  2001/01/19 16:16:29  perf
+ * Added temporary mapping of 0x0c->0x0c to avoid flash loading confusion.
+ * Renamed serial options from ETRAX100 to ETRAX.
+ *
+ * Revision 1.11  2001/01/16 16:31:38  bjornw
+ * * Changed name and semantics of running_from_flash to romfs_in_flash,
+ *   set by head.S to indicate to setup.c whether there is a cramfs image
+ *   after the kernels BSS or not. Should work for all three boot-cases
+ *   (DRAM with cramfs in DRAM, DRAM with cramfs in flash (compressed boot),
+ *    and flash with cramfs in flash)
+ *
+ * Revision 1.10  2001/01/16 14:12:21  bjornw
+ * * Check for cramfs start passed in r9 from the decompressor, if all other
+ *   cramfs options fail (if we boot from DRAM but don't find a cramfs image
+ *   after the kernel in DRAM, it is probably still in the flash)
+ * * Check magic in cramfs detection when booting from flash directly
+ *
+ * Revision 1.9  2001/01/15 17:17:02  bjornw
+ * * Corrected the code that detects the cramfs lengths
+ * * Added a comment saying that the above does not work due to other
+ *   reasons..
+ *
+ * Revision 1.8  2001/01/15 16:27:51  jonashg
+ * Made boot after flashing work.
+ * * end destination is __vmlinux_end in RAM.
+ * * _romfs_start moved because of virtual memory.
+ *
+ * Revision 1.7  2000/11/21 13:55:29  bjornw
+ * Use CONFIG_CRIS_LOW_MAP for the low VM map instead of explicit CPU type
+ *
+ * Revision 1.6  2000/10/06 12:36:55  bjornw
+ * Forgot swapper_pg_dir when changing memory map..
+ *
+ * Revision 1.5  2000/10/04 16:49:30  bjornw
+ * * Fixed memory mapping in LX
+ * * Check for cramfs instead of romfs
+ *
+ */
 	
 #include <linux/config.h>
 #define ASSEMBLER_MACROS_ONLY
@@ -82,13 +111,13 @@
 	;; slightly different. We also let the simulator get this mapping for now.
 
 #ifdef CONFIG_CRIS_LOW_MAP
-	move.d	0x0800b000, r0	; kseg mappings
+	move.d	0x0004b098, r0	; kseg mappings, temporary map of 0xc0->0x40
 	move.d	r0, [R_MMU_KBASE_HI]
 
 	move.d	0x04040000, r0	; temporary map of 0x40->0x40 and 0x00->0x00 
 	move.d	r0, [R_MMU_KBASE_LO]
 
-	move.d	0x80074871, r0	; mmu enable, segs e,b,6,5,4,0 segment mapped
+	move.d	0x80075c71, r0	; mmu enable, segs c,b,9,8,6,5,4,0 segment mapped
 	move.d	r0, [R_MMU_CONFIG]
 #else
 	move.d	0x0804b000, r0	; kseg mappings
@@ -131,24 +160,9 @@
 	jump	inram		; enter cached ram
 	
 inflash:
+	;; We need to initialze DRAM registers before we start using the DRAM
+#include "../lib/dram_init.S"	
 
-#ifndef CONFIG_SVINTO_SIM	
-
-	;; We need to setup the bus registers before we start using the DRAM
-
-	move.d   DEF_R_WAITSTATES, r0
-	move.d   r0, [R_WAITSTATES]
-
-	move.d   DEF_R_BUS_CONFIG, r0
-	move.d   r0, [R_BUS_CONFIG]
-  
-	move.d   DEF_R_DRAM_CONFIG, r0
-	move.d   r0, [R_DRAM_CONFIG]
-
-	move.d   DEF_R_DRAM_TIMING, r0
-	move.d   r0, [R_DRAM_TIMING]
-
-#endif
 	;; Copy text+data to DRAM
 	;; This is fragile - the calculation of r4 as the image size depends
 	;; on that the labels below actually are the first and last positions
@@ -357,27 +371,38 @@
 #if !defined(CONFIG_KGDB) && !defined(CONFIG_DMA_MEMCPY)
 	or.d	0x140000,r0	; DMA channels 6 and 7 to ser0, kgdb doesnt want DMA
 #endif
-#if !defined(CONFIG_KGDB) || !defined(CONFIG_DEBUG_PORT1)
+#if !defined(CONFIG_KGDB) || !defined(CONFIG_DEBUG_PORT1)	
 	or.d	0xc00000,r0	; DMA channels 8 and 9 to ser1, kgdb doesnt want DMA
-#endif
+#endif	
 #ifdef CONFIG_DMA_MEMCPY
 	or.d	0x003c0000,r0	; 6/7 memory-memory DMA
 #endif
-#ifdef CONFIG_ETRAX100_SERIAL_PORT2
+#ifdef CONFIG_ETRAX_SERIAL_PORT2
 	or.d	0x2808,r0	; DMA channels 2 and 3 to serport 2, port 2 enabled
 #endif
-#ifdef CONFIG_ETRAX100_SERIAL_PORT3
+#if defined(CONFIG_ETRAX_SERIAL_PORT3) || defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
 	or.d	0x28100,r0	; DMA channels 4 and 5 to serport 3, port 3 enabled
-#endif
-#if defined(CONFIG_ETRAX100_PARALLEL_PORT0) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE)
+#endif	
+#if defined(CONFIG_ETRAX_PARALLEL_PORT0) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE)
 	or.w	0x4,r0	; parport 0 enabled using DMA 2/3
 #endif
-#if defined(CONFIG_ETRAX100_PARALLEL_PORT1) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE)
+#if defined(CONFIG_ETRAX_PARALLEL_PORT1) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE)
 	or.w	0x80,r0	; parport 1 enabled using DMA 4/5
 #endif
 #ifdef CONFIG_BLK_DEV_ETRAXIDE
 	or.d	0x3c02,r0	; DMA channels 2 and 3 to ATA, ATA enabled
 #endif
+	
+#ifdef CONFIG_ETRAX_USB_HOST_PORT1
+	or.d	0x20000000,r0	; Set the USB port 1 enable bit
+#endif
+#ifdef CONFIG_ETRAX_USB_HOST_PORT2
+	or.d	0x40000000,r0	; Set the USB port 2 enable bit
+#endif
+#ifdef CONFIG_ETRAX_USB_HOST
+	and.d	0xff3fffff,r0	; Connect DMA channels 8 and 9 to USB
+#endif
+	
 #ifdef CONFIG_JULIETTE
 	or.d	0x3c000,r0	; DMA channels 4 and 5 to EXTDMA0, for Juliette
 #ifndef CONFIG_BLK_DEV_ETRAXIDE
@@ -438,6 +463,9 @@
 	move.b	DEF_R_PORT_PB_DATA,r0
 	move.b	r0,[_port_pb_data_shadow]
 	move.b	r0,[R_PORT_PB_DATA]
+	move.d  0, r0
+	move.d  r0,[_port_pb_i2c_shadow]
+	move.d  r0, [R_PORT_PB_I2C]
 
 	moveq	0,r0
 	move.d	r0,[_port_g_data_shadow]
@@ -478,7 +506,7 @@
 	move.d	r0,[0x90000000]
 #endif
 	
-#ifdef CONFIG_ETRAX100_SERIAL_PORT3	
+#ifdef CONFIG_ETRAX_SERIAL_PORT3	
 	;; setup the serial port 3 at 115200 baud for debug purposes
 	
 	moveq	0,r0
@@ -497,8 +525,7 @@
 #endif /* CONFIG_SVINTO_SIM */
 
 	jump	_start_kernel	; jump into the C-function _start_kernel in init/main.c
-
-	
+		
 	.data
 _etrax_irv:	
 	.dword	0
@@ -508,7 +535,7 @@
 	.dword	0
 _romfs_in_flash:
 	.dword	0
-
+	
 	;; put some special pages at the beginning of the kernel aligned
 	;; to page boundaries - the kernel cannot start until after this
 
diff -u --recursive --new-file v2.4.3/linux/arch/cris/kernel/irq.c linux/arch/cris/kernel/irq.c
--- v2.4.3/linux/arch/cris/kernel/irq.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/irq.c	Fri Apr  6 10:42:55 2001
@@ -1,8 +1,8 @@
-/* $Id: irq.c,v 1.5 2000/08/17 15:35:15 bjornw Exp $
+/* $Id: irq.c,v 1.11 2001/02/27 13:52:52 bjornw Exp $
  *
  *	linux/arch/cris/kernel/irq.c
  *
- *      Copyright (c) 2000 Axis Communications AB
+ *      Copyright (c) 2000,2001 Axis Communications AB
  *
  *      Authors: Bjorn Wesen (bjornw@axis.com)
  *
@@ -30,7 +30,7 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/random.h>
 
 #include <asm/system.h>
@@ -160,6 +160,8 @@
 BUILD_IRQ(23, 0x800000)
 BUILD_IRQ(24, 0x1000000)
 BUILD_IRQ(25, 0x2000000)
+/* IRQ 26-30 are resereved */	
+BUILD_IRQ(31, 0x80000000)
  
 /*
  * Pointers to the low-level handlers 
@@ -172,7 +174,8 @@
 	IRQ12_interrupt, IRQ13_interrupt, NULL, NULL,	
 	IRQ16_interrupt, IRQ17_interrupt, IRQ18_interrupt, IRQ19_interrupt,	
 	IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt,	
-	IRQ24_interrupt, IRQ25_interrupt
+	IRQ24_interrupt, IRQ25_interrupt, NULL, NULL, NULL, NULL, NULL,
+	IRQ31_interrupt
 };
 
 static void (*sinterrupt[NR_IRQS])(void) = {
@@ -182,7 +185,8 @@
 	sIRQ12_interrupt, sIRQ13_interrupt, NULL, NULL,	
 	sIRQ16_interrupt, sIRQ17_interrupt, sIRQ18_interrupt, sIRQ19_interrupt,	
 	sIRQ20_interrupt, sIRQ21_interrupt, sIRQ22_interrupt, sIRQ23_interrupt,	
-	sIRQ24_interrupt, sIRQ25_interrupt
+	sIRQ24_interrupt, sIRQ25_interrupt, NULL, NULL, NULL, NULL, NULL,
+	sIRQ31_interrupt
 };
 
 static void (*bad_interrupt[NR_IRQS])(void) = {
@@ -198,7 +202,9 @@
 	bad_IRQ18_interrupt, bad_IRQ19_interrupt,
 	bad_IRQ20_interrupt, bad_IRQ21_interrupt,
 	bad_IRQ22_interrupt, bad_IRQ23_interrupt,
-	bad_IRQ24_interrupt, bad_IRQ25_interrupt
+	bad_IRQ24_interrupt, bad_IRQ25_interrupt,
+	NULL, NULL, NULL, NULL, NULL,
+	bad_IRQ31_interrupt
 };
 
 /*
@@ -212,7 +218,8 @@
 	NULL, NULL, NULL, NULL,
 	NULL, NULL, NULL, NULL,
 	NULL, NULL, NULL, NULL,
-	NULL, NULL
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL
 };
 
 int get_irq_list(char *buf)
@@ -412,6 +419,8 @@
 */
 
 void system_call(void);  /* from entry.S */
+void gdb_handle_breakpoint(void); /* from traps.c */
+void do_sigtrap(void); /* also from traps.c */
 
 void init_IRQ(void)
 {
@@ -431,14 +440,22 @@
 
 	for(i = 0; i < NR_IRQS; i++)
 		irq_shortcuts[i] = NULL;
-	
-	for (i = 0; i < 256; i++)
-		etrax_irv->v[i] = weird_irq;
-      
+        
+        for (i = 0; i < 256; i++)
+               etrax_irv->v[i] = weird_irq;
+
+        /* the entries in the break vector contain actual code to be
+           executed by the associated break handler, rather than just a jump
+           address. therefore we need to setup a default breakpoint handler
+           for all breakpoints */
+
+	for (i = 0; i < 16; i++)
+                set_break_vector(i, do_sigtrap);
+        
 	/* set all etrax irq's to the bad handlers */
 	for (i = 2; i < NR_IRQS; i++)
 		set_int_vector(i, bad_interrupt[i], 0);
-
+        
 	/* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */
 
 	set_int_vector(15, multiple_interrupt, 0);
@@ -456,12 +473,15 @@
 
 	set_break_vector(13, system_call);
 
+        /* setup a breakpoint handler for debugging used for both user and
+           kernel mode debugging  (which is why it is not inside an ifdef
+           CONFIG_KGDB) */
+        set_break_vector(8, gdb_handle_breakpoint);
+
 #ifdef CONFIG_KGDB
 	/* setup kgdb if its enabled, and break into the debugger */
-
 	kgdb_init();
-
 	breakpoint();
 #endif
 
-} 
+}
diff -u --recursive --new-file v2.4.3/linux/arch/cris/kernel/kgdb.c linux/arch/cris/kernel/kgdb.c
--- v2.4.3/linux/arch/cris/kernel/kgdb.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/kgdb.c	Fri Apr  6 10:42:55 2001
@@ -18,6 +18,12 @@
 *! Jul 21 1999  Bjorn Wesen     eLinux port
 *!
 *! $Log: kgdb.c,v $
+*! Revision 1.4  2001/02/23 13:45:19  bjornw
+*! config.h check
+*!
+*! Revision 1.3  2001/01/31 18:08:23  orjanf
+*! Removed kgdb_handle_breakpoint from being the break 8 handler.
+*!
 *! Revision 1.2  2001/01/12 14:22:25  orjanf
 *! Updated kernel debugging support to work with ETRAX 100LX.
 *!
@@ -43,7 +49,7 @@
 *!
 *!---------------------------------------------------------------------------
 *!
-*! $Id: kgdb.c,v 1.2 2001/01/12 14:22:25 orjanf Exp $
+*! $Id: kgdb.c,v 1.4 2001/02/23 13:45:19 bjornw Exp $
 *!
 *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN
 *!
@@ -1531,7 +1537,7 @@
 {
 	/* could initialize debug port as well but it's done in head.S already... */
 
-	set_break_vector(8, kgdb_handle_breakpoint);
+        /* breakpoint handler is now set in irq.c */
 	set_int_vector(8, kgdb_handle_serial, 0);
 	
 	enableDebugIRQ();
diff -u --recursive --new-file v2.4.3/linux/arch/cris/kernel/process.c linux/arch/cris/kernel/process.c
--- v2.4.3/linux/arch/cris/kernel/process.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/process.c	Fri Apr  6 10:42:55 2001
@@ -1,9 +1,9 @@
-/* $Id: process.c,v 1.8 2000/09/13 14:34:13 bjornw Exp $
+/* $Id: process.c,v 1.12 2001/02/27 13:52:52 bjornw Exp $
  * 
  *  linux/arch/cris/kernel/process.c
  *
  *  Copyright (C) 1995  Linus Torvalds
- *  Copyright (C) 2000  Axis Communications AB
+ *  Copyright (C) 2000, 2001  Axis Communications AB
  *
  *  Authors:   Bjorn Wesen (bjornw@axis.com)
  *
@@ -23,7 +23,7 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/a.out.h>
 #include <linux/interrupt.h>
@@ -71,11 +71,6 @@
 
 #define currentregs ((struct pt_regs *)current->thread.esp0)
 
-asmlinkage void set_esp0(unsigned long ssp)
-{
-	current->thread.esp0 = ssp;
-}
-
 void disable_hlt(void)
 {
 	hlt_counter++;
@@ -134,7 +129,7 @@
 	register long __a __asm__ ("r10");
 	
 	__asm__ __volatile__
-		("movu.w %1,r1\n\t"     /* r1 contains syscall number, to sys_clone */
+		("movu.w %1,r9\n\t"     /* r9 contains syscall number, to sys_clone */
 		 "clear.d r10\n\t"      /* r10 is argument 1 to clone */
 		 "move.d %2,r11\n\t"    /* r11 is argument 2 to clone, the flags */
 		 "break 13\n\t"         /* call sys_clone, this will fork */
@@ -143,14 +138,14 @@
 		 "nop\n\t"              /* delay slot */
 		 "move.d %4,r10\n\t"    /* set argument to function to call */
 		 "jsr %5\n\t"           /* call specified function */
-		 "movu.w %3,r1\n\t"     /* r1 is sys_exit syscall number */
+		 "movu.w %3,r9\n\t"     /* r9 is sys_exit syscall number */
 		 "moveq -1,r10\n\t"     /* Give a really bad exit-value */
 		 "break 13\n\t"         /* call sys_exit, killing the child */
 		 "1:\n\t"
 		 : "=r" (__a) 
 		 : "g" (__NR_clone), "r" (flags | CLONE_VM), "g" (__NR_exit),
 		   "r" (arg), "r" (fn) 
-		 : "r10", "r11", "r1");
+		 : "r10", "r11", "r9");
 	
 	return __a;
 }
diff -u --recursive --new-file v2.4.3/linux/arch/cris/kernel/setup.c linux/arch/cris/kernel/setup.c
--- v2.4.3/linux/arch/cris/kernel/setup.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/setup.c	Fri Apr  6 10:42:55 2001
@@ -1,9 +1,9 @@
-/* $Id: setup.c,v 1.8 2001/01/16 16:31:38 bjornw Exp $
+/* $Id: setup.c,v 1.11 2001/03/02 15:52:03 bjornw Exp $
  *
  *  linux/arch/cris/kernel/setup.c
  *
  *  Copyright (C) 1995  Linus Torvalds
- *  Copyright (c) 2000  Axis Communications AB
+ *  Copyright (c) 2001  Axis Communications AB
  */
 
 /*
@@ -17,7 +17,7 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/ptrace.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/user.h>
 #include <linux/a.out.h>
 #include <linux/tty.h>
@@ -75,7 +75,8 @@
  *
  */
 
-void __init setup_arch(char **cmdline_p)
+void __init 
+setup_arch(char **cmdline_p)
 {
         unsigned long bootmap_size;
 	unsigned long start_pfn, max_pfn;
@@ -179,7 +180,7 @@
 
 	/* give credit for the CRIS port */
 
-	printk("Linux/CRIS port on ETRAX 100LX (c) 2000 Axis Communications AB\n");
+	printk("Linux/CRIS port on ETRAX 100LX (c) 2001 Axis Communications AB\n");
 
 }
 
@@ -192,6 +193,7 @@
 #define HAS_ATA		0x0020
 #define HAS_USB		0x0040
 #define HAS_IRQ_BUG	0x0080
+#define HAS_MMU_BUG     0x0100
 
 static struct cpu_info {
 	char *model;
@@ -214,7 +216,8 @@
 	{ "Simulator",     8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA },
 	{ "ETRAX 100",     8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_IRQ_BUG },
 	{ "ETRAX 100",     8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA },
-	{ "ETRAX 100LX",  8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB | HAS_MMU },
+	{ "ETRAX 100LX",  8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB | HAS_MMU | HAS_MMU_BUG },
+	{ "ETRAX 100LX v2",  8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB | HAS_MMU },
 	{ "Unknown",   0, 0 },
 };
 
@@ -241,6 +244,7 @@
 		       "cache size\t: %d kB\n"
 		       "fpu\t\t: %s\n"
 		       "mmu\t\t: %s\n"
+		       "mmu DMA bug\t: %s\n"
 		       "ethernet\t: %s Mbps\n"
 		       "token ring\t: %s\n"
 		       "scsi\t\t: %s\n"
@@ -253,6 +257,7 @@
 		       cpu_info[revision].cache,
 		       cpu_info[revision].flags & HAS_FPU ? "yes" : "no",
 		       cpu_info[revision].flags & HAS_MMU ? "yes" : "no",
+		       cpu_info[revision].flags & HAS_MMU_BUG ? "yes" : "no",
 		       cpu_info[revision].flags & HAS_ETHERNET100 ? "10/100" : "10",
 		       cpu_info[revision].flags & HAS_TOKENRING ? "4/16 Mbps" : "no",
 		       cpu_info[revision].flags & HAS_SCSI ? "yes" : "no",
diff -u --recursive --new-file v2.4.3/linux/arch/cris/kernel/signal.c linux/arch/cris/kernel/signal.c
--- v2.4.3/linux/arch/cris/kernel/signal.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/signal.c	Fri Apr  6 10:42:55 2001
@@ -38,9 +38,6 @@
 
 #define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->irp -= 2;
 
-int sys_wait4(pid_t pid, unsigned long *stat_addr,
-			 int options, unsigned long *ru);
-
 int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs);
 
 int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
@@ -391,9 +388,9 @@
 	} else {
 		/* trampoline - the desired return ip is the retcode itself */
 		return_ip = (unsigned long)&frame->retcode;
-		/* This is movu.w __NR_sigreturn, r1; break 13; */
+		/* This is movu.w __NR_sigreturn, r9; break 13; */
 		/* TODO: check byteorder */
-		err |= __put_user(0x1c5f,         (short *)(frame->retcode+0));
+		err |= __put_user(0x9c5f,         (short *)(frame->retcode+0));
 		err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2));
 		err |= __put_user(0xe93d,         (short *)(frame->retcode+4));
 	}
@@ -453,9 +450,9 @@
 	} else {
 		/* trampoline - the desired return ip is the retcode itself */
 		return_ip = (unsigned long)&frame->retcode;
-		/* This is movu.w __NR_sigreturn, r1; break 13; */
+		/* This is movu.w __NR_sigreturn, r9; break 13; */
 		/* TODO: check byteorder */
-		err |= __put_user(0x1c5f,         (short *)(frame->retcode+0));
+		err |= __put_user(0x9c5f,         (short *)(frame->retcode+0));
 		err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2));
 		err |= __put_user(0xe93d,         (short *)(frame->retcode+4));
 	}
diff -u --recursive --new-file v2.4.3/linux/arch/cris/kernel/sys_cris.c linux/arch/cris/kernel/sys_cris.c
--- v2.4.3/linux/arch/cris/kernel/sys_cris.c	Mon Mar 19 12:35:11 2001
+++ linux/arch/cris/kernel/sys_cris.c	Fri Apr  6 10:42:55 2001
@@ -1,4 +1,4 @@
-/* $Id: sys_cris.c,v 1.3 2000/08/02 13:59:02 bjornw Exp $
+/* $Id: sys_cris.c,v 1.4 2001/01/31 14:55:58 perf Exp $
  *
  * linux/arch/cris/kernel/sys_etrax.c
  *
@@ -97,10 +97,22 @@
         return error;
 }
 
-asmlinkage unsigned long old_mmap(unsigned long addr, size_t len, int prot,
-                                  int flags, int fd, off_t offset)
-{
-        return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+asmlinkage unsigned long old_mmap(unsigned long *args)
+{        
+	unsigned long buffer[6];
+	int err = -EFAULT;
+
+	if (copy_from_user(&buffer, args, sizeof(buffer)))
+		goto out;
+
+	err = -EINVAL;
+	if (buffer[5] & ~PAGE_MASK) /* verify that offset is on page boundary */
+		goto out;
+
+	err = do_mmap2(buffer[0], buffer[1], buffer[2], buffer[3],
+                       buffer[4], buffer[5] >> PAGE_SHIFT);
+out:
+	return err;
 }
 
 asmlinkage long
diff -u --recursive --new-file v2.4.3/linux/arch/cris/kernel/traps.c linux/arch/cris/kernel/traps.c
--- v2.4.3/linux/arch/cris/kernel/traps.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/traps.c	Fri Apr  6 10:42:55 2001
@@ -1,16 +1,19 @@
-/* $Id: traps.c,v 1.3 2000/10/04 16:50:06 bjornw Exp $
+/* $Id: traps.c,v 1.8 2001/02/23 13:45:20 bjornw Exp $
  *
  *  linux/arch/cris/traps.c
  *
- *  Etrax100 does not have any hardware traps, only IRQ's, which we setup
- *  in irq.c instead. Here we just define the die_if_kernel Oops'er.
- *
- *  Copyright (C) 2000 Axis Communications AB
+ *  Here we handle the break vectors not used by the system call 
+ *  mechanism, as well as some general stack/register dumping 
+ *  things.
+ * 
+ *  Copyright (C) 2000,2001 Axis Communications AB
  *
  *  Authors:   Bjorn Wesen
+ *             Orjan Friberg
  *
  */
 
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -35,7 +38,8 @@
 
 #define MODULE_RANGE (8*1024*1024)
 
-void show_stack(unsigned long *sp)
+void 
+show_stack(unsigned long *sp)
 {
         unsigned long *stack, addr, module_start, module_end;
         int i;
@@ -86,7 +90,8 @@
 #if 0
 /* displays a short stack trace */
 
-int show_stack()
+int 
+show_stack()
 {
 	unsigned long *sp = (unsigned long *)rdusp();
 	int i;
@@ -97,7 +102,8 @@
 }
 #endif
 
-void show_registers(struct pt_regs * regs)
+void 
+show_registers(struct pt_regs * regs)
 {
 	unsigned long usp = rdusp();
 
@@ -145,9 +151,8 @@
 #endif
 }
 
-
-
-void die_if_kernel(const char * str, struct pt_regs * regs, long err)
+void 
+die_if_kernel(const char * str, struct pt_regs * regs, long err)
 {
 	if(user_mode(regs))
 		return;
@@ -160,8 +165,68 @@
 	do_exit(SIGSEGV);
 }
 
-void __init trap_init(void)
+void __init 
+trap_init(void)
 {
-  
 
 }
+
+/* Use static variables instead of the stack for temporary storage.  */
+static int saved_r0 = 0;
+static int saved_dccr = 0;
+
+asm ("
+  .global _gdb_handle_breakpoint
+  .global _do_sigtrap
+_gdb_handle_breakpoint:
+;;
+;; This handles a break instruction for entering a debug session.
+;;
+  move     dccr,[_saved_dccr]       ; Save dccr.
+  move.d   r0,[_saved_r0]           ; Save r0. "
+#ifdef CONFIG_KGDB
+" 
+  move     ccr,r0                   
+  btstq    8,r0                     ; Test the U-flag.
+  bmi      _ugdb_handle_breakpoint  ; Go to user mode debugging.
+  nop                               ; Delay slot.
+  move.d   [_saved_r0],r0           ; Restore r0.
+  move     [_saved_dccr],dccr       ; Restore dccr.
+  ba       _kgdb_handle_breakpoint  ; Go to kernel debugging.
+  nop                               ; Delay slot. "
+#endif
+" 
+_ugdb_handle_breakpoint:
+;;
+;; Yes, we could do a 'push brp' here and let gdb adjust the pc once it
+;; starts talking to the target again, but this way we avoid a 'P' packet.
+;;
+  move     brp,r0               ; Use r0 temporarily for calculation.
+  subq     2,r0                 ; Set to address of previous instruction.
+  move     r0,brp               ; Restore new brp.
+  move.d   [_saved_r0],r0       ; Restore r0.
+  move     [_saved_dccr],dccr   ; Restore dccr.
+
+_do_sigtrap:
+;; 
+;; SIGTRAP the process that executed the break instruction.
+;; Make a frame that Rexit in entry.S expects.
+;;
+  push     brp                  ; Push breakpoint return pointer.
+  push     srp                  ; Push subroutine return pointer.
+  push     dccr                 ; Push condition codes.
+  push     mof                  ; Push multiply overflow reg.
+  di                            ; Need to disable irq's at this point.
+  subq     14*4,sp              ; Make room for r0-r13.
+  movem    r13,[sp]             ; Push the r0-r13 registers.
+  push     r10                  ; Push orig_r10.
+  clear.d  [sp=sp-4]            ; Frametype - this is a normal stackframe.
+
+  movs.w   -8192,r9             ; THREAD_SIZE == 8192
+  and.d    sp,r9
+  move.d   [r9+LTASK_PID],r10   ; current->pid as arg1.
+  moveq    5,r11                ; SIGTRAP as arg2.
+  jsr      _sys_kill       
+
+  jump     _ret_from_intr       ; Use the return routine for interrupts.
+");
diff -u --recursive --new-file v2.4.3/linux/arch/cris/lib/checksum.S linux/arch/cris/lib/checksum.S
--- v2.4.3/linux/arch/cris/lib/checksum.S	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/lib/checksum.S	Fri Apr  6 10:42:55 2001
@@ -1,16 +1,21 @@
-	;; $Id: checksum.S,v 1.1 2000/07/10 16:25:21 bjornw Exp $
-	;; A fast checksum routine using movem
-	;; Copyright (c) 1998 Bjorn Wesen/Axis Communications AB
+/* $Id: checksum.S,v 1.4 2001/02/19 11:11:33 bjornw Exp $
+ * A fast checksum routine using movem
+ * Copyright (c) 1998-2001 Axis Communications AB
+ *
+ * csum_partial(const unsigned char * buff, int len, unsigned int sum)
+ */
 
-	;; csum_partial(const unsigned char * buff, int len, unsigned int sum)
-	
 	.globl	_csum_partial
 _csum_partial:
 	
+	;; r10 - src
+	;; r11 - length
+	;; r12 - checksum
+
 	;; check for breakeven length between movem and normal word looping versions
 	
 	cmpu.w	80,r11
-	bcs	no_movem
+	blo	word_loop
 	nop
 
 	;; need to save the registers we use below in the movem loop
@@ -21,10 +26,6 @@
 	
 	;; do a movem checksum
 
-	;; r10 - src
-	;; r11 - length
-	;; r12 - checksum
-
 	subq	10*4,r11	; update length for the first loop
 	
 mloop:	movem	[r10+],r9	; read 10 longwords
@@ -65,23 +66,30 @@
 
 	addq	10*4,r11	; compensate for last loop underflowing length
 
-	;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below
-	
-	moveq	-1,r1		; put 0xffff in r1, faster than move.d 0xffff,r1
-	lsrq	16,r1
-	
-	move.d	r12,r0
-	lsrq	16,r0		; r0 = checksum >> 16
-	and.d	r1,r12		; checksum = checksum & 0xffff
-	add.d	r0,r12		; checksum += r0
-	move.d	r12,r0		; do the same again, maybe we got a carry last add
-	lsrq	16,r0
-	and.d	r1,r12
-	add.d	r0,r12
-	
 	movem	[sp+],r8	; restore regs
 
-no_movem:
+word_loop:
+	;; only fold if there is anything to fold.
+
+	cmpq	0,r12
+	beq	no_fold
+
+	;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below.
+	;; r9 and r13 can be used as temporaries.
+	
+	moveq	-1,r9		; put 0xffff in r9, faster than move.d 0xffff,r9
+	lsrq	16,r9
+	
+	move.d	r12,r13
+	lsrq	16,r13		; r13 = checksum >> 16
+	and.d	r9,r12		; checksum = checksum & 0xffff
+	add.d	r13,r12		; checksum += r13
+	move.d	r12,r13		; do the same again, maybe we got a carry last add
+	lsrq	16,r13
+	and.d	r9,r12
+	add.d	r13,r12
+
+no_fold:
 	cmpq	2,r11
 	blt	no_words
 	nop
@@ -110,4 +118,3 @@
 	ret
 	move.d	r12, r10
 		
-	
\ No newline at end of file
diff -u --recursive --new-file v2.4.3/linux/arch/cris/lib/checksumcopy.S linux/arch/cris/lib/checksumcopy.S
--- v2.4.3/linux/arch/cris/lib/checksumcopy.S	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/lib/checksumcopy.S	Fri Apr  6 10:42:55 2001
@@ -1,19 +1,25 @@
-	;; $Id: checksumcopy.S,v 1.2 2000/08/08 16:57:31 bjornw Exp $
-	;; A fast checksum+copy routine using movem
-	;; Copyright (c) 1998, 2000 Axis Communications AB
-	;;
-	;; Authors:	Bjorn Wesen
-	;; 
-	;; csum_partial_copy_nocheck(const char *src, char *dst,
-	;;		             int len, unsigned int sum)
+/* $Id: checksumcopy.S,v 1.4 2001/02/19 11:11:34 bjornw Exp $
+ * A fast checksum+copy routine using movem
+ * Copyright (c) 1998, 2001 Axis Communications AB
+ *
+ * Authors:	Bjorn Wesen
+ * 
+ * csum_partial_copy_nocheck(const char *src, char *dst,
+ *		             int len, unsigned int sum)
+ */
 
 	.globl	_csum_partial_copy_nocheck
 _csum_partial_copy_nocheck:	
 	
+	;; r10 - src
+	;; r11 - dst
+	;; r12 - length
+	;; r13 - checksum
+
 	;; check for breakeven length between movem and normal word looping versions
 	
 	cmpu.w	80,r12
-	bcs	no_movem
+	blo	word_loop
 	nop
 
 	;; need to save the registers we use below in the movem loop
@@ -24,11 +30,6 @@
 	
 	;; do a movem copy and checksum
 
-	;; r10 - src
-	;; r11 - dst
-	;; r12 - length
-	;; r13 - checksum
-
 	subq	10*4,r12	; update length for the first loop
 	
 mloop:	movem	[r10+],r9	; read 10 longwords
@@ -61,6 +62,8 @@
 	
 	ax
 	addq	0,r13
+	ax			; do it again, since we might have generated a carry
+	addq	0,r13
 
 	subq	10*4,r12
 	bge	mloop
@@ -68,23 +71,27 @@
 
 	addq	10*4,r12	; compensate for last loop underflowing length
 
+	movem	[sp+],r8	; restore regs
+
+word_loop:
+	;; only fold if there is anything to fold.
+
+	cmpq	0,r13
+	beq	no_fold
+
 	;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below
+	;; r9 can be used as temporary.
 	
-	moveq	-1,r1		; put 0xffff in r1, faster than move.d 0xffff,r1
-	lsrq	16,r1
-	
-	move.d	r13,r0
-	lsrq	16,r0		; r0 = checksum >> 16
-	and.d	r1,r13		; checksum = checksum & 0xffff
-	add.d	r0,r13		; checksum += r0
-	move.d	r13,r0		; do the same again, maybe we got a carry last add
-	lsrq	16,r0
-	and.d	r1,r13
-	add.d	r0,r13
+	move.d	r13,r9
+	lsrq	16,r9		; r0 = checksum >> 16
+	and.d	0xffff,r13	; checksum = checksum & 0xffff
+	add.d	r9,r13		; checksum += r0
+	move.d	r13,r9		; do the same again, maybe we got a carry last add
+	lsrq	16,r9
+	and.d	0xffff,r13
+	add.d	r9,r13
 	
-	movem	[sp+],r8	; restore regs
-		
-no_movem:
+no_fold:
 	cmpq	2,r12
 	blt	no_words
 	nop
@@ -117,4 +124,4 @@
 	ret
 	move.d	r13, r10
 		
-	
\ No newline at end of file
+	
diff -u --recursive --new-file v2.4.3/linux/arch/cris/lib/dram_init.S linux/arch/cris/lib/dram_init.S
--- v2.4.3/linux/arch/cris/lib/dram_init.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/lib/dram_init.S	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,123 @@
+	;; $Id: dram_init.S,v 1.2 2001/02/08 15:20:00 starvik Exp $
+	;; 
+	;; DRAM/SDRAM initialization - alter with care
+	;; This file is intended to be included from other assembler files
+	;;
+	;; Copyright (C) 2000 Axis Communications AB
+	;;
+	;; Authors:  Mikael Starvik (starvik@axis.com)	
+	;;           Bjorn Wesen (bjornw@axis.com)
+	;; 
+	;; $Log: dram_init.S,v $
+	;; Revision 1.2  2001/02/08 15:20:00  starvik
+	;; Corrected SDRAM initialization
+	;; Should now be included as inline
+	;;
+	;; Revision 1.1  2001/01/29 13:08:02  starvik
+	;; Initial version
+	;; This file should be included from all assembler files that needs to
+	;; initialize DRAM/SDRAM.
+	;;
+	;;
+	;;
+
+#include <linux/config.h>
+
+#ifndef CONFIG_SVINTO_SIM	
+	move.d   DEF_R_WAITSTATES, r0
+	move.d   r0, [R_WAITSTATES]
+
+	move.d   DEF_R_BUS_CONFIG, r0
+	move.d   r0, [R_BUS_CONFIG]
+	
+#ifndef CONFIG_SDRAM
+	move.d   DEF_R_DRAM_CONFIG, r0
+	move.d   r0, [R_DRAM_CONFIG]
+
+	move.d   DEF_R_DRAM_TIMING, r0
+	move.d   r0, [R_DRAM_TIMING]
+#else	
+	; Refer to ETRAX 100LX Designers Reference for a description of SDRAM initialization
+	
+	; Bank configuration
+        move.d   DEF_R_SDRAM_CONFIG, r0
+	move.d   r0, [R_SDRAM_CONFIG]
+
+	; Calculate value of mrs_data 
+	; cas_delay = 2 && bus_width = 32 => 0x40
+	; cas_delay = 3 && bus_width = 32 => 0x60
+	; cas_delay = 2 && bus_width = 16 => 0x20
+	; cas_delay = 3 && bus_width = 16 => 0x30
+	
+	move.d   0x40, r2       ; Assume 32 bits and cas_delay = 2
+	move.d   DEF_R_SDRAM_TIMING, r1
+	and.d    0x0c, r1	; Get cas delay
+	cmp.d    0x08, r1	; cas_delay = 2?
+        beq      bw_check
+	nop
+	or.d     0x20, r2       ; cas_delay = 3
+bw_check:
+	move.d   DEF_R_SDRAM_CONFIG, r1
+	and.d    0x800000, r1	; DRAM width is bit 23
+	bne      set_timing
+	nop
+	lsrq     1, r2		;  16 bits. Shift down value.
+
+	; Set timing parameters. Starts master clock
+set_timing:
+	move.d   DEF_R_SDRAM_TIMING, r1
+	or.d     0x80000000, r1	; Make sure sdram enable bit is set
+	lslq     16, r2		; mrs data starts at bit 16
+	or.d     r2, r1 
+	move.d   r1, [R_SDRAM_TIMING]	
+		
+	; Wait 200ns
+	move.d   10, r2
+sdram_loop:
+	bne      sdram_loop
+	subq     1, r2
+	
+	; Issue initialization command sequence
+	move.d   sdram_commands_start, r2
+	move.d   sdram_commands_end,  r3
+command_loop:
+	clear.d  r4
+	move.b   [r2+], r4
+	lslq     9, r4		; Command starts at bit 9
+	or.d     r1, r4
+	move.d   r4, [R_SDRAM_TIMING]
+	nop			; Wait five nop cycles between each command
+	nop
+	nop
+	nop
+	nop
+	cmp.d    r2, r3
+	bne      command_loop
+	nop
+	ba       sdram_commands_end
+	nop
+
+sdram_commands_start:
+	.byte   3	; Precharge
+	.byte   0       ; nop
+	.byte   2	; refresh
+	.byte   0	; nop
+	.byte   2	; refresh
+	.byte   0	; nop
+	.byte   2	; refresh
+	.byte   0	; nop
+	.byte   2	; refresh
+	.byte   0	; nop
+	.byte   2	; refresh
+	.byte   0	; nop
+	.byte   2	; refresh
+	.byte   0	; nop
+	.byte   2	; refresh
+	.byte   0	; nop
+	.byte   2	; refresh
+	.byte   0	; nop
+	.byte   1	; mrs
+	.byte   0	; nop 
+sdram_commands_end:		
+#endif
+#endif
diff -u --recursive --new-file v2.4.3/linux/arch/cris/mm/Makefile linux/arch/cris/mm/Makefile
--- v2.4.3/linux/arch/cris/mm/Makefile	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/mm/Makefile	Fri Apr  6 10:42:55 2001
@@ -8,6 +8,6 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := mm.o
-obj-y	 := init.o fault.o tlb.o extable.o
+obj-y	 := init.o fault.o tlb.o extable.o ioremap.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.3/linux/arch/cris/mm/fault.c linux/arch/cris/mm/fault.c
--- v2.4.3/linux/arch/cris/mm/fault.c	Mon Mar 19 12:35:11 2001
+++ linux/arch/cris/mm/fault.c	Fri Apr  6 10:42:55 2001
@@ -6,6 +6,9 @@
  *  Authors:  Bjorn Wesen 
  * 
  *  $Log: fault.c,v $
+ *  Revision 1.9  2001/03/05 13:22:20  bjornw
+ *  Spell-fix and fix in vmalloc_fault handling
+ *
  *  Revision 1.8  2000/11/22 14:45:31  bjornw
  *  * 2.4.0-test10 removed the set_pgdir instantaneous kernel global mapping
  *    into all processes. Instead we fill in the missing PTE entries on demand.
@@ -301,7 +304,7 @@
 	/* Are we prepared to handle this kernel fault?
 	 *
 	 * (The kernel has valid exception-points in the source 
-	 *  when it acesses user-memory. When it fails in one
+	 *  when it accesses user-memory. When it fails in one
 	 *  of those points, we find it in a table and do a jump
 	 *  to some fixup code that loads an appropriate error
 	 *  code)
diff -u --recursive --new-file v2.4.3/linux/arch/cris/mm/init.c linux/arch/cris/mm/init.c
--- v2.4.3/linux/arch/cris/mm/init.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/mm/init.c	Fri Apr  6 10:42:55 2001
@@ -2,11 +2,22 @@
  *  linux/arch/cris/mm/init.c
  *
  *  Copyright (C) 1995  Linus Torvalds
- *  Copyright (C) 2000  Axis Communications AB
+ *  Copyright (C) 2000,2001  Axis Communications AB
  *
  *  Authors:  Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: init.c,v $
+ *  Revision 1.18  2001/02/23 12:46:44  bjornw
+ *  * 0xc was not CSE1; 0x8 is, same as uncached flash, so we move the uncached
+ *    flash during CRIS_LOW_MAP from 0xe to 0x8 so both the flash and the I/O
+ *    is mapped straight over (for !CRIS_LOW_MAP the uncached flash is still 0xe)
+ *
+ *  Revision 1.17  2001/02/22 15:05:21  bjornw
+ *  Map 0x9 straight over during LOW_MAP to allow for memory mapped LEDs
+ *
+ *  Revision 1.16  2001/02/22 15:02:35  bjornw
+ *  Map 0xc straight over during LOW_MAP to allow for memory mapped I/O
+ *
  *  Revision 1.15  2001/01/10 21:12:10  bjornw
  *  loops_per_sec -> loops_per_jiffy
  *
@@ -287,16 +298,19 @@
 	 * The Juliette chip is mapped at 0xa so we pass that segment straight
 	 * through. We cannot vremap it because the vmalloc area is below 0x8
 	 * and Juliette needs an uncached area above 0x8.
+	 *
+	 * Same thing with 0xc and 0x9, which is memory-mapped I/O on some boards.
+	 * We map them straight over in LOW_MAP, but use vremap in LX version 2.
 	 */
 
 	*R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, page ) | 
-			IO_STATE(R_MMU_KSEG, seg_e, seg  ) |  /* uncached flash */
+			IO_STATE(R_MMU_KSEG, seg_e, page ) |
 			IO_STATE(R_MMU_KSEG, seg_d, page ) | 
-			IO_STATE(R_MMU_KSEG, seg_c, page ) | 
+			IO_STATE(R_MMU_KSEG, seg_c, page ) |   
 			IO_STATE(R_MMU_KSEG, seg_b, seg  ) |  /* kernel reg area */
 			IO_STATE(R_MMU_KSEG, seg_a, seg  ) |  /* Juliette etc. */
-			IO_STATE(R_MMU_KSEG, seg_9, page ) |
-			IO_STATE(R_MMU_KSEG, seg_8, page ) |
+			IO_STATE(R_MMU_KSEG, seg_9, seg  ) |  /* LED's on some boards */
+			IO_STATE(R_MMU_KSEG, seg_8, seg  ) |  /* CSE0/1, flash and I/O */
 			IO_STATE(R_MMU_KSEG, seg_7, page ) |  /* kernel vmalloc area */
 			IO_STATE(R_MMU_KSEG, seg_6, seg  ) |  /* kernel DRAM area */
 			IO_STATE(R_MMU_KSEG, seg_5, seg  ) |  /* cached flash */
@@ -307,13 +321,13 @@
 			IO_STATE(R_MMU_KSEG, seg_0, page ) ); /* user area */
 
 	*R_MMU_KBASE_HI = ( IO_FIELD(R_MMU_KBASE_HI, base_f, 0x0 ) |
-			    IO_FIELD(R_MMU_KBASE_HI, base_e, 0x8 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_e, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_c, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_a, 0xa ) |
-			    IO_FIELD(R_MMU_KBASE_HI, base_9, 0x0 ) |
-			    IO_FIELD(R_MMU_KBASE_HI, base_8, 0x0 ) );
+			    IO_FIELD(R_MMU_KBASE_HI, base_9, 0x9 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_8, 0x8 ) );
 	
 	*R_MMU_KBASE_LO = ( IO_FIELD(R_MMU_KBASE_LO, base_7, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_LO, base_6, 0x4 ) |
diff -u --recursive --new-file v2.4.3/linux/arch/cris/mm/ioremap.c linux/arch/cris/mm/ioremap.c
--- v2.4.3/linux/arch/cris/mm/ioremap.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/mm/ioremap.c	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,164 @@
+/*
+ * arch/cris/mm/ioremap.c
+ *
+ * Re-map IO memory to kernel address space so that we can access it.
+ * Needed for memory-mapped I/O devices mapped outside our normal DRAM
+ * window (that is, all memory-mapped I/O devices).
+ *
+ * (C) Copyright 1995 1996 Linus Torvalds
+ * CRIS-port by Axis Communications AB
+ */
+
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+#include <asm/pgalloc.h>
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
+	unsigned long phys_addr, unsigned long flags)
+{
+	unsigned long end;
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	if (address >= end)
+		BUG();
+	do {
+		if (!pte_none(*pte)) {
+			printk("remap_area_pte: page already exists\n");
+			BUG();
+		}
+		set_pte(pte, mk_pte_phys(phys_addr, __pgprot(_PAGE_PRESENT | __READABLE | 
+							     __WRITEABLE | _PAGE_GLOBAL |
+							     _PAGE_KERNEL | 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;
+	phys_addr -= address;
+	if (address >= end)
+		BUG();
+	do {
+		pte_t * pte = pte_alloc_kernel(pmd, address);
+		if (!pte)
+			return -ENOMEM;
+		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+		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)
+{
+	pgd_t * dir;
+	unsigned long end = address + size;
+
+	phys_addr -= address;
+	dir = pgd_offset(&init_mm, address);
+	flush_cache_all();
+	if (address >= end)
+		BUG();
+	do {
+		pmd_t *pmd;
+		pmd = pmd_alloc_kernel(dir, address);
+		if (!pmd)
+			return -ENOMEM;
+		if (remap_area_pmd(pmd, address, end - address,
+					 phys_addr + address, flags))
+			return -ENOMEM;
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	} while (address && (address < end));
+	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;
+
+#if 0
+	/* TODO: Here we can put checks for driver-writer abuse...  */
+
+	/*
+	 * Don't remap the low PCI/ISA area, it's always mapped..
+	 */
+	if (phys_addr >= 0xA0000 && last_addr < 0x100000)
+		return phys_to_virt(phys_addr);
+
+	/*
+	 * Don't allow anybody to remap normal RAM that we're using..
+	 */
+	if (phys_addr < virt_to_phys(high_memory)) {
+		char *t_addr, *t_end;
+		struct page *page;
+
+		t_addr = __va(phys_addr);
+		t_end = t_addr + (size - 1);
+	   
+		for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
+			if(!PageReserved(page))
+				return NULL;
+	}
+#endif
+
+	/*
+	 * 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);
+	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 (addr > high_memory)
+		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
+}
diff -u --recursive --new-file v2.4.3/linux/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S
--- v2.4.3/linux/arch/i386/boot/setup.S	Sat Jan 27 10:51:35 2001
+++ linux/arch/i386/boot/setup.S	Fri Apr  6 10:42:47 2001
@@ -18,7 +18,7 @@
  * March 1993/June 1994 (Christoph.Niemann@linux.org)
  *
  * add APM BIOS checking by Stephen Rothwell, May 1994
- * (Stephen.Rothwell@canb.auug.org.au)
+ * (sfr@canb.auug.org.au)
  *
  * High load stuff, initrd support and position independency
  * by Hans Lermen & Werner Almesberger, February 1996
diff -u --recursive --new-file v2.4.3/linux/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c
--- v2.4.3/linux/arch/i386/kernel/apm.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/i386/kernel/apm.c	Fri Apr  6 10:42:47 2001
@@ -1,6 +1,6 @@
 /* -*- linux-c -*-
  * APM BIOS driver for Linux
- * Copyright 1994-2000 Stephen Rothwell (sfr@linuxcare.com)
+ * Copyright 1994-2001 Stephen Rothwell (sfr@canb.auug.org.au)
  *
  * Initial development of this driver was funded by NEC Australia P/L
  *	and NEC Corporation
@@ -23,7 +23,7 @@
  * March 1996, Rik Faith (faith@cs.unc.edu):
  *    Prohibit APM BIOS calls unless apm_enabled.
  *    (Thanks to Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>)
- * April 1996, Stephen Rothwell (Stephen.Rothwell@canb.auug.org.au)
+ * April 1996, Stephen Rothwell (sfr@canb.auug.org.au)
  *    Version 1.0 and 1.1
  * May 1996, Version 1.2
  * Feb 1998, Version 1.3
@@ -119,7 +119,7 @@
  *         Make power off under SMP work again.
  *         Fix thinko with initial engaging of BIOS.
  *         Make sure power off only happens on CPU 0
- *         (Paul "Rusty" Russell <rusty@linuxcare.com>).
+ *         (Paul "Rusty" Russell <rusty@rustcorp.com.au>).
  *         Do error notification to user mode if BIOS calls fail.
  *         Move entrypoint offset fix to ...boot/setup.S
  *         where it belongs (Cosmos <gis88564@cis.nctu.edu.tw>).
@@ -227,6 +227,8 @@
  * P: Toshiba 1950S: battery life information only gets updated after resume
  * P: Midwest Micro Soundbook Elite DX2/66 monochrome: screen blanking
  * 	broken in BIOS [Reported by Garst R. Reese <reese@isn.net>]
+ * ?: AcerNote-950: oops on reading /proc/apm - workaround is a WIP
+ * 	Neale Banks <neale@lowendale.com.au> December 2000
  *
  * Legend: U = unusable with APM patches
  *         P = partially usable with APM patches
@@ -1550,6 +1552,9 @@
 			apm_disabled = 1;
 		if (strncmp(str, "on", 2) == 0)
 			apm_disabled = 0;
+		if ((strncmp(str, "broken-psr", 10) == 0) ||
+		    (strncmp(str, "broken_psr", 10) == 0))
+			apm_info.get_power_status_broken = 1;
 		invert = (strncmp(str, "no-", 3) == 0);
 		if (invert)
 			str += 3;
diff -u --recursive --new-file v2.4.3/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- v2.4.3/linux/arch/i386/kernel/i386_ksyms.c	Fri Mar  2 12:03:49 2001
+++ linux/arch/i386/kernel/i386_ksyms.c	Fri Apr  6 11:27:46 2001
@@ -61,7 +61,6 @@
 EXPORT_SYMBOL(dump_extended_fpu);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(__io_virt_debug);
 EXPORT_SYMBOL(enable_irq);
 EXPORT_SYMBOL(disable_irq);
 EXPORT_SYMBOL(disable_irq_nosync);
@@ -72,6 +71,10 @@
 EXPORT_SYMBOL(get_cmos_time);
 EXPORT_SYMBOL(apm_info);
 EXPORT_SYMBOL(gdt);
+
+#ifdef CONFIG_IO_DEBUG
+EXPORT_SYMBOL(__io_virt_debug);
+#endif
 
 EXPORT_SYMBOL_NOVERS(__down_failed);
 EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
diff -u --recursive --new-file v2.4.3/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c
--- v2.4.3/linux/arch/i386/kernel/mtrr.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/i386/kernel/mtrr.c	Tue Apr  3 10:15:12 2001
@@ -538,7 +538,7 @@
      * Note: shift==0xf means 4G, this is unsupported.
      */
     if (shift)
-      *size = (reg < 7 ? 0x1UL : 0x40UL) << shift;
+      *size = (reg < 7 ? 0x1UL : 0x40UL) << (shift - 1);
     else
       *size = 0;
 
diff -u --recursive --new-file v2.4.3/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.4.3/linux/arch/i386/kernel/setup.c	Sun Mar 25 18:24:31 2001
+++ linux/arch/i386/kernel/setup.c	Fri Apr  6 10:42:55 2001
@@ -58,6 +58,12 @@
  *  Massive cleanup of CPU detection and bug handling;
  *  Transmeta CPU detection,
  *  H. Peter Anvin <hpa@zytor.com>, November 2000
+ *
+ *  Added E820 sanitization routine (removes overlapping memory regions);
+ *  Brian Moyle <bmoyle@mvista.com>, February 2001
+ *
+ *  VIA C3 Support.
+ *  Dave Jones <davej@suse.de>, March 2001
  */
 
 /*
@@ -440,6 +446,170 @@
 }
 
 /*
+ * Sanitize the BIOS e820 map.
+ *
+ * Some e820 responses include overlapping entries.  The following 
+ * replaces the original e820 map with a new one, removing overlaps.
+ *
+ */
+static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
+{
+	struct change_member {
+		struct e820entry *pbios; /* pointer to original bios entry */
+		unsigned long long addr; /* address for this change point */
+	};
+	struct change_member change_point_list[2*E820MAX];
+	struct change_member *change_point[2*E820MAX];
+	struct e820entry *overlap_list[E820MAX];
+	struct e820entry new_bios[E820MAX];
+	struct change_member *change_tmp;
+	unsigned long current_type, last_type;
+	unsigned long long last_addr;
+	int chgidx, still_changing;
+	int overlap_entries;
+	int new_bios_entry;
+	int old_nr, new_nr;
+	int i;
+
+	/*
+		Visually we're performing the following (1,2,3,4 = memory types)...
+
+		Sample memory map (w/overlaps):
+		   ____22__________________
+		   ______________________4_
+		   ____1111________________
+		   _44_____________________
+		   11111111________________
+		   ____________________33__
+		   ___________44___________
+		   __________33333_________
+		   ______________22________
+		   ___________________2222_
+		   _________111111111______
+		   _____________________11_
+		   _________________4______
+
+		Sanitized equivalent (no overlap):
+		   1_______________________
+		   _44_____________________
+		   ___1____________________
+		   ____22__________________
+		   ______11________________
+		   _________1______________
+		   __________3_____________
+		   ___________44___________
+		   _____________33_________
+		   _______________2________
+		   ________________1_______
+		   _________________4______
+		   ___________________2____
+		   ____________________33__
+		   ______________________4_
+	*/
+
+	/* if there's only one memory region, don't bother */
+	if (*pnr_map < 2)
+		return -1;
+
+	old_nr = *pnr_map;
+
+	/* bail out if we find any unreasonable addresses in bios map */
+	for (i=0; i<old_nr; i++)
+		if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
+			return -1;
+
+	/* create pointers for initial change-point information (for sorting) */
+	for (i=0; i < 2*old_nr; i++)
+		change_point[i] = &change_point_list[i];
+
+	/* record all known change-points (starting and ending addresses) */
+	chgidx = 0;
+	for (i=0; i < old_nr; i++)	{
+		change_point[chgidx]->addr = biosmap[i].addr;
+		change_point[chgidx++]->pbios = &biosmap[i];
+		change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
+		change_point[chgidx++]->pbios = &biosmap[i];
+	}
+
+	/* sort change-point list by memory addresses (low -> high) */
+	still_changing = 1;
+	while (still_changing)	{
+		still_changing = 0;
+		for (i=1; i < 2*old_nr; i++)  {
+			/* if <current_addr> > <last_addr>, swap */
+			/* or, if current=<start_addr> & last=<end_addr>, swap */
+			if ((change_point[i]->addr < change_point[i-1]->addr) ||
+				((change_point[i]->addr == change_point[i-1]->addr) &&
+				 (change_point[i]->addr == change_point[i]->pbios->addr) &&
+				 (change_point[i-1]->addr != change_point[i-1]->pbios->addr))
+			   )
+			{
+				change_tmp = change_point[i];
+				change_point[i] = change_point[i-1];
+				change_point[i-1] = change_tmp;
+				still_changing=1;
+			}
+		}
+	}
+
+	/* create a new bios memory map, removing overlaps */
+	overlap_entries=0;	 /* number of entries in the overlap table */
+	new_bios_entry=0;	 /* index for creating new bios map entries */
+	last_type = 0;		 /* start with undefined memory type */
+	last_addr = 0;		 /* start with 0 as last starting address */
+	/* loop through change-points, determining affect on the new bios map */
+	for (chgidx=0; chgidx < 2*old_nr; chgidx++)
+	{
+		/* keep track of all overlapping bios entries */
+		if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
+		{
+			/* add map entry to overlap list (> 1 entry implies an overlap) */
+			overlap_list[overlap_entries++]=change_point[chgidx]->pbios;
+		}
+		else
+		{
+			/* remove entry from list (order independent, so swap with last) */
+			for (i=0; i<overlap_entries; i++)
+			{
+				if (overlap_list[i] == change_point[chgidx]->pbios)
+					overlap_list[i] = overlap_list[overlap_entries-1];
+			}
+			overlap_entries--;
+		}
+		/* if there are overlapping entries, decide which "type" to use */
+		/* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */
+		current_type = 0;
+		for (i=0; i<overlap_entries; i++)
+			if (overlap_list[i]->type > current_type)
+				current_type = overlap_list[i]->type;
+		/* continue building up new bios map based on this information */
+		if (current_type != last_type)	{
+			if (last_type != 0)	 {
+				new_bios[new_bios_entry].size =
+					change_point[chgidx]->addr - last_addr;
+				/* move forward only if the new size was non-zero */
+				if (new_bios[new_bios_entry].size != 0)
+					if (++new_bios_entry >= E820MAX)
+						break; 	/* no more space left for new bios entries */
+			}
+			if (current_type != 0)	{
+				new_bios[new_bios_entry].addr = change_point[chgidx]->addr;
+				new_bios[new_bios_entry].type = current_type;
+				last_addr=change_point[chgidx]->addr;
+			}
+			last_type = current_type;
+		}
+	}
+	new_nr = new_bios_entry;   /* retain count for new bios entries */
+
+	/* copy new bios mapping into original location */
+	memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry));
+	*pnr_map = new_nr;
+
+	return 0;
+}
+
+/*
  * Copy the BIOS e820 map into a safe place.
  *
  * Sanity-check it while we're at it..
@@ -506,6 +676,7 @@
 	 * Otherwise fake a memory map; one section from 0k->640k,
 	 * the next section from 1mb->appropriate_mem_k
 	 */
+	sanitize_e820_map(E820_MAP, &E820_MAP_NR);
 	if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) {
 		unsigned long mem_size;
 
@@ -560,7 +731,7 @@
 				 * blow away any automatically generated
 				 * size
 				 */
-				unsigned long start_at, mem_size;
+				unsigned long long start_at, mem_size;
  
 				if (usermem == 0) {
 					/* first time in: zap the whitelist
@@ -1401,7 +1572,7 @@
 
 		case 6:
 			switch (c->x86_model) {
-				case 6:	/* Cyrix III */
+				case 6 ... 7:		/* Cyrix III or C3 */
 					rdmsr (0x1107, lo, hi);
 					lo |= (1<<1 | 1<<7);	/* Report CX8 & enable PGE */
 					wrmsr (0x1107, lo, hi);
@@ -1481,6 +1652,32 @@
 	wrmsr(0x80860004, cap_mask, uk);
 }
 
+
+static void __init init_rise(struct cpuinfo_x86 *c)
+{
+	printk("CPU: Rise iDragon");
+	if (c->x86_model > 2)
+		printk(" II");
+	printk("\n");
+	printk("If you have one of these please email davej@suse.de\n");
+
+	/* Unhide possibly hidden capability flags
+	   The mp6 iDragon family don't have MSRs.
+	   We switch on extra features with this cpuid wierdness: */
+	__asm__ (
+		"movl $0x6363452a, %%eax\n\t"
+		"movl $0x3231206c, %%ecx\n\t"
+		"movl $0x2a32313a, %%edx\n\t"
+		"cpuid\n\t"
+		"movl $0x63634523, %%eax\n\t"
+		"movl $0x32315f6c, %%ecx\n\t"
+		"movl $0x2333313a, %%edx\n\t"
+		"cpuid\n\t" : : : "eax", "ebx", "ecx", "edx"
+	);
+	set_bit(X86_FEATURE_CX8, &c->x86_capability);
+}
+
+
 extern void trap_init_f00f_bug(void);
 
 static void __init init_intel(struct cpuinfo_x86 *c)
@@ -1732,8 +1929,8 @@
 	  { "Nx586", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	    NULL, NULL, NULL, NULL, NULL, NULL, NULL }},
 	{ X86_VENDOR_RISE,	5,
-	  { "mP6", "mP6", NULL, NULL, NULL, NULL, NULL,
-	    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }},
+	  { "iDragon", NULL, "iDragon", NULL, NULL, NULL, NULL,
+	    NULL, "iDragon II", "iDragon II", NULL, NULL, NULL, NULL, NULL, NULL }},
 };
 
 /* Look up CPU names by table lookup. */
@@ -1997,6 +2194,15 @@
 	case X86_VENDOR_UNKNOWN:
 	default:
 		/* Not much we can do here... */
+		/* Check if at least it has cpuid */
+		if (c->cpuid_level == -1)
+		{
+			/* No cpuid. It must be an ancient CPU */
+			if (c->x86 == 4)
+				strcpy(c->x86_model_id, "486");
+			else if (c->x86 == 3)
+				strcpy(c->x86_model_id, "386");
+		}
 		break;
 
 	case X86_VENDOR_CYRIX:
@@ -2021,6 +2227,10 @@
 
 	case X86_VENDOR_TRANSMETA:
 		init_transmeta(c);
+		break;
+
+	case X86_VENDOR_RISE:
+		init_rise(c);
 		break;
 	}
 	
diff -u --recursive --new-file v2.4.3/linux/arch/i386/lib/Makefile linux/arch/i386/lib/Makefile
--- v2.4.3/linux/arch/i386/lib/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/i386/lib/Makefile	Fri Apr  6 10:42:47 2001
@@ -8,8 +8,8 @@
 L_TARGET = lib.a
 
 obj-y = checksum.o old-checksum.o delay.o \
-	usercopy.o getuser.o putuser.o iodebug.o \
-	memcpy.o
+	usercopy.o getuser.o putuser.o \
+	memcpy.o strstr.o
 
 obj-$(CONFIG_X86_USE_3DNOW) += mmx.o
 obj-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
diff -u --recursive --new-file v2.4.3/linux/arch/i386/lib/strstr.c linux/arch/i386/lib/strstr.c
--- v2.4.3/linux/arch/i386/lib/strstr.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/i386/lib/strstr.c	Fri Apr  6 10:42:47 2001
@@ -0,0 +1,31 @@
+#include <linux/string.h>
+
+char * strstr(const char * cs,const char * ct)
+{
+int	d0, d1;
+register char * __res;
+__asm__ __volatile__(
+	"movl %6,%%edi\n\t"
+	"repne\n\t"
+	"scasb\n\t"
+	"notl %%ecx\n\t"
+	"decl %%ecx\n\t"	/* NOTE! This also sets Z if searchstring='' */
+	"movl %%ecx,%%edx\n"
+	"1:\tmovl %6,%%edi\n\t"
+	"movl %%esi,%%eax\n\t"
+	"movl %%edx,%%ecx\n\t"
+	"repe\n\t"
+	"cmpsb\n\t"
+	"je 2f\n\t"		/* also works for empty string, see above */
+	"xchgl %%eax,%%esi\n\t"
+	"incl %%esi\n\t"
+	"cmpb $0,-1(%%eax)\n\t"
+	"jne 1b\n\t"
+	"xorl %%eax,%%eax\n\t"
+	"2:"
+	:"=a" (__res), "=&c" (d0), "=&S" (d1)
+	:"0" (0), "1" (0xffffffff), "2" (cs), "g" (ct)
+	:"dx", "di");
+return __res;
+}
+
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/control_w.h linux/arch/i386/math-emu/control_w.h
--- v2.4.3/linux/arch/i386/math-emu/control_w.h	Thu Jun 29 08:25:27 1995
+++ linux/arch/i386/math-emu/control_w.h	Fri Apr  6 10:42:47 2001
@@ -42,4 +42,4 @@
 /* FULL_PRECISION simulates all exceptions masked */
 #define FULL_PRECISION  (PR_64_BITS | RC_RND | 0x3f)
 
-#endif _CONTROLW_H_
+#endif /* _CONTROLW_H_ */
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/div_Xsig.S linux/arch/i386/math-emu/div_Xsig.S
--- v2.4.3/linux/arch/i386/math-emu/div_Xsig.S	Fri Aug 27 10:18:17 1999
+++ linux/arch/i386/math-emu/div_Xsig.S	Fri Apr  6 10:42:47 2001
@@ -70,7 +70,7 @@
 	.long	0
 FPU_result_1:
 	.long	0
-#endif NON_REENTRANT_FPU
+#endif /* NON_REENTRANT_FPU */
 
 
 .text
@@ -79,7 +79,7 @@
 	movl	%esp,%ebp
 #ifndef NON_REENTRANT_FPU
 	subl	$28,%esp
-#endif NON_REENTRANT_FPU
+#endif /* NON_REENTRANT_FPU */ 
 
 	pushl	%esi
 	pushl	%edi
@@ -91,7 +91,7 @@
 #ifdef PARANOID
 	testl	$0x80000000, XsigH(%ebx)	/* Divisor */
 	je	L_bugged
-#endif PARANOID
+#endif /* PARANOID */
 
 
 /*---------------------------------------------------------------------------+
@@ -164,7 +164,7 @@
 
 #ifdef PARANOID
 	jb	L_bugged_1
-#endif PARANOID
+#endif /* PARANOID */ 
 
 	/* need to subtract another once of the denom */
 	incl	FPU_result_3	/* Correct the answer */
@@ -177,7 +177,7 @@
 #ifdef PARANOID
 	sbbl	$0,FPU_accum_3
 	jne	L_bugged_1	/* Must check for non-zero result here */
-#endif PARANOID
+#endif /* PARANOID */ 
 
 /*----------------------------------------------------------------------*/
 /* Half of the main problem is done, there is just a reduced numerator
@@ -207,7 +207,7 @@
 
 #ifdef PARANOID
 	je	L_bugged_2	/* Can't bump the result to 1.0 */
-#endif PARANOID
+#endif /* PARANOID */ 
 
 LDo_2nd_div:
 	cmpl	$0,%ecx		/* augmented denom msw */
@@ -230,7 +230,7 @@
 
 #ifdef PARANOID
 	jc	L_bugged_2
-#endif PARANOID
+#endif /* PARANOID */
 
 	movl	FPU_result_2,%eax	/* Get the result back */
 	mull	XsigL(%ebx)	/* now mul the ls dw of the denom */
@@ -241,14 +241,14 @@
 
 #ifdef PARANOID
 	jc	L_bugged_2
-#endif PARANOID
+#endif /* PARANOID */
 
 	jz	LDo_3rd_32_bits
 
 #ifdef PARANOID
 	cmpl	$1,FPU_accum_2
 	jne	L_bugged_2
-#endif PARANOID
+#endif /* PARANOID */ 
 
 	/* need to subtract another once of the denom */
 	movl	XsigL(%ebx),%eax
@@ -260,14 +260,14 @@
 #ifdef PARANOID
 	jc	L_bugged_2
 	jne	L_bugged_2
-#endif PARANOID
+#endif /* PARANOID */ 
 
 	addl	$1,FPU_result_2	/* Correct the answer */
 	adcl	$0,FPU_result_3
 
 #ifdef PARANOID
 	jc	L_bugged_2	/* Must check for non-zero result here */
-#endif PARANOID
+#endif /* PARANOID */ 
 
 /*----------------------------------------------------------------------*/
 /* The division is essentially finished here, we just need to perform
@@ -362,4 +362,4 @@
 	call	EXCEPTION
 	pop	%ebx
 	jmp	L_exit
-#endif PARANOID
+#endif /* PARANOID */ 
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/errors.c linux/arch/i386/math-emu/errors.c
--- v2.4.3/linux/arch/i386/math-emu/errors.c	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/errors.c	Fri Apr  6 10:42:47 2001
@@ -141,7 +141,7 @@
 if ( partial_status & SW_Zero_Div )    printk("SW: divide by zero\n");
 if ( partial_status & SW_Denorm_Op )   printk("SW: denormalized operand\n");
 if ( partial_status & SW_Invalid )     printk("SW: invalid operation\n");
-#endif DEBUGGING
+#endif /* DEBUGGING */
 
   printk(" SW: b=%d st=%ld es=%d sf=%d cc=%d%d%d%d ef=%d%d%d%d%d%d\n",
 	 partial_status & 0x8000 ? 1 : 0,   /* busy */
@@ -327,7 +327,7 @@
 #ifdef PRINT_MESSAGES
       /* My message from the sponsor */
       printk(FPU_VERSION" "__DATE__" (C) W. Metzenthen.\n");
-#endif PRINT_MESSAGES
+#endif /* PRINT_MESSAGES */
       
       /* Get a name string for error reporting */
       for (i=0; exception_names[i].type; i++)
@@ -338,7 +338,7 @@
 	{
 #ifdef PRINT_MESSAGES
 	  printk("FP Exception: %s!\n", exception_names[i].name);
-#endif PRINT_MESSAGES
+#endif /* PRINT_MESSAGES */
 	}
       else
 	printk("FPU emulator: Unknown Exception: 0x%04x!\n", n);
@@ -351,7 +351,7 @@
 #ifdef PRINT_MESSAGES
       else
 	FPU_printall();
-#endif PRINT_MESSAGES
+#endif /* PRINT_MESSAGES */
 
       /*
        * The 80486 generates an interrupt on the next non-control FPU
@@ -363,7 +363,7 @@
 
 #ifdef __DEBUG__
   math_abort(FPU_info,SIGFPE);
-#endif __DEBUG__
+#endif /* __DEBUG__ */
 
 }
 
@@ -469,7 +469,7 @@
   else
 #ifdef PARANOID
     if (tagb == TW_NaN)
-#endif PARANOID
+#endif /* PARANOID */
     {
       signalling = !(b->sigh & 0x40000000);
       x = b;
@@ -481,7 +481,7 @@
       EXCEPTION(EX_INTERNAL|0x113);
       x = &CONST_QNaN;
     }
-#endif PARANOID
+#endif /* PARANOID */
 
   if ( (!signalling) || (control_word & CW_Invalid) )
     {
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/exception.h linux/arch/i386/math-emu/exception.h
--- v2.4.3/linux/arch/i386/math-emu/exception.h	Mon Dec 11 13:34:33 2000
+++ linux/arch/i386/math-emu/exception.h	Fri Apr  6 10:42:47 2001
@@ -18,7 +18,7 @@
 
 #ifndef SW_C1
 #include "fpu_emu.h"
-#endif SW_C1
+#endif /* SW_C1 */
 
 #define FPU_BUSY        Const_(0x8000)   /* FPU busy bit (8087 compatibility) */
 #define EX_ErrorSummary Const_(0x0080)   /* Error summary status */
@@ -48,6 +48,6 @@
 #define	EXCEPTION(x)	FPU_exception(x)
 #endif
 
-#endif __ASSEMBLY__
+#endif /* __ASSEMBLY__ */ 
 
-#endif _EXCEPTION_H_
+#endif /* _EXCEPTION_H_ */
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/fpu_asm.h linux/arch/i386/math-emu/fpu_asm.h
--- v2.4.3/linux/arch/i386/math-emu/fpu_asm.h	Mon Dec 11 13:34:33 2000
+++ linux/arch/i386/math-emu/fpu_asm.h	Fri Apr  6 10:42:47 2001
@@ -29,4 +29,4 @@
 #define	SIGL(x)	SIGL_OFFSET##(x)
 #define	SIGH(x)	4(x)
 
-#endif _FPU_ASM_H_
+#endif /* _FPU_ASM_H_ */
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/fpu_emu.h linux/arch/i386/math-emu/fpu_emu.h
--- v2.4.3/linux/arch/i386/math-emu/fpu_emu.h	Mon Dec 11 13:34:33 2000
+++ linux/arch/i386/math-emu/fpu_emu.h	Fri Apr  6 10:42:47 2001
@@ -88,7 +88,7 @@
 #else
 #  define RE_ENTRANT_CHECK_OFF
 #  define RE_ENTRANT_CHECK_ON
-#endif RE_ENTRANT_CHECKING
+#endif /* RE_ENTRANT_CHECKING */
 
 #define FWAIT_OPCODE 0x9b
 #define OP_SIZE_PREFIX 0x66
@@ -212,6 +212,6 @@
 #include "fpu_proto.h"
 #endif
 
-#endif __ASSEMBLY__
+#endif /* __ASSEMBLY__ */
 
-#endif _FPU_EMU_H_
+#endif /* _FPU_EMU_H_ */
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/fpu_entry.c linux/arch/i386/math-emu/fpu_entry.c
--- v2.4.3/linux/arch/i386/math-emu/fpu_entry.c	Mon Jun 19 18:10:44 2000
+++ linux/arch/i386/math-emu/fpu_entry.c	Fri Apr  6 10:42:47 2001
@@ -78,7 +78,7 @@
   fdivr_,   FPU_trigb,  __BAD__, __BAD__, fdiv_i,  __BAD__, fdivp_,  __BAD__,
 };
 
-#endif NO_UNDOC_CODE
+#endif /* NO_UNDOC_CODE */
 
 
 #define _NONE_ 0   /* Take no special action */
@@ -120,12 +120,12 @@
   _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
 };
 
-#endif NO_UNDOC_CODE
+#endif /* NO_UNDOC_CODE */
 
 
 #ifdef RE_ENTRANT_CHECKING
 u_char emulating=0;
-#endif RE_ENTRANT_CHECKING
+#endif /* RE_ENTRANT_CHECKING */
 
 static int valid_prefix(u_char *Byte, u_char **fpu_eip,
 			overrides *override);
@@ -152,7 +152,7 @@
       printk("ERROR: wm-FPU-emu is not RE-ENTRANT!\n");
     }
   RE_ENTRANT_CHECK_ON;
-#endif RE_ENTRANT_CHECKING
+#endif /* RE_ENTRANT_CHECKING */
 
   if (!current->used_math)
     {
@@ -251,7 +251,7 @@
 #ifdef PARANOID
       EXCEPTION(EX_INTERNAL|0x128);
       math_abort(FPU_info,SIGILL);
-#endif PARANOID
+#endif /* PARANOID */
     }
 
   RE_ENTRANT_CHECK_OFF;
@@ -386,7 +386,7 @@
 			/* fdiv or fsub */
 			real_2op_NaN(&loaded_data, loaded_tag, 0, &loaded_data);
 		      else
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */ 
 			/* fadd, fdivr, fmul, or fsubr */
 			real_2op_NaN(&loaded_data, loaded_tag, 0, st0_ptr);
 		    }
@@ -497,7 +497,7 @@
 	 to do this: */
       operand_address.offset = 0;
       operand_address.selector = FPU_DS;
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 
       st0_ptr = &st(0);
       st0_tag = FPU_gettag0();
@@ -557,7 +557,7 @@
   RE_ENTRANT_CHECK_OFF;
   FPU_printall();
   RE_ENTRANT_CHECK_ON;
-#endif DEBUG
+#endif /* DEBUG */
 
   if (FPU_lookahead && !current->need_resched)
     {
@@ -669,7 +669,7 @@
 	__asm__("movl %0,%%esp ; ret": :"g" (((long) info)-4));
 #ifdef PARANOID
       printk("ERROR: wm-FPU-emu math_abort failed!\n");
-#endif PARANOID
+#endif /* PARANOID */
 }
 
 
@@ -739,7 +739,7 @@
   S387->twd |= 0xffff0000;
   S387->fcs &= ~0xf8000000;
   S387->fos |= 0xffff0000;
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
   __copy_to_user(d, &S387->cwd, 7*4);
   RE_ENTRANT_CHECK_ON;
 
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/fpu_etc.c linux/arch/i386/math-emu/fpu_etc.c
--- v2.4.3/linux/arch/i386/math-emu/fpu_etc.c	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/fpu_etc.c	Fri Apr  6 10:42:47 2001
@@ -68,7 +68,7 @@
 	      /* This is weird! */
 	      if (getsign(st0_ptr) == SIGN_POS)
 		setcc(SW_C3);
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 	      return;
 	    }
 	  break;
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/fpu_trig.c linux/arch/i386/math-emu/fpu_trig.c
--- v2.4.3/linux/arch/i386/math-emu/fpu_trig.c	Thu Nov  4 09:10:22 1999
+++ linux/arch/i386/math-emu/fpu_trig.c	Fri Apr  6 10:42:47 2001
@@ -98,7 +98,7 @@
 	      q++;
 	    }
 	}
-#endif BETTER_THAN_486
+#endif /* BETTER_THAN_486 */
     }
 #ifdef BETTER_THAN_486
   else
@@ -138,7 +138,7 @@
 	    }
 	}
     }
-#endif BETTER_THAN_486
+#endif /* BETTER_THAN_486 */
 
   FPU_settag0(st0_tag);
   control_word = old_cw;
@@ -186,7 +186,7 @@
 #ifdef PARANOID
   else
     EXCEPTION(EX_INTERNAL|0x0112);
-#endif PARANOID
+#endif /* PARANOID */
 }
 
 
@@ -232,7 +232,7 @@
 #ifdef PARANOID
     default:
       EXCEPTION(EX_INTERNAL|0x0112);
-#endif PARANOID
+#endif /* PARANOID */
     }
 }
 
@@ -463,7 +463,7 @@
 #ifdef PARANOID
   else
     EXCEPTION(EX_INTERNAL | 0x119);
-#endif PARANOID
+#endif /* PARANOID */
 }
 
 
@@ -716,7 +716,7 @@
 	  set_precision_flag_down();  /* 80486 appears to do this. */
 #else
 	  set_precision_flag_up();  /* Must be up. */
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 	  return 0;
 	}
     }
@@ -1008,7 +1008,7 @@
 	      setcc(SW_C2);
 #else
 	      setcc(0);
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 	      return;
 	    }
 	  cc = SW_C2;
@@ -1114,7 +1114,7 @@
 #ifdef PARANOID
   if ( (st0_tag != TW_NaN) && (st1_tag != TW_NaN) )
       EXCEPTION(EX_INTERNAL | 0x118);
-#endif PARANOID
+#endif /* PARANOID */
 
   real_2op_NaN(st1_ptr, st1_tag, 0, st1_ptr);
 
@@ -1315,7 +1315,7 @@
 	  sign = getsign(st1_ptr);
 	  if ( FPU_divide_by_zero(1, sign) < 0 )
 	    return;
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 
 	  changesign(st1_ptr);
 	}
@@ -1451,7 +1451,7 @@
 #ifdef PARANOID
   else
     EXCEPTION(EX_INTERNAL | 0x125);
-#endif PARANOID
+#endif /* PARANOID */
 
   FPU_pop();
   set_precision_flag_up();  /* We do not really know if up or down */
@@ -1542,7 +1542,7 @@
 #ifdef PARANOID
 	  EXCEPTION(EX_INTERNAL | 0x116);
 	  return;
-#endif PARANOID
+#endif /* PARANOID */
 	}
     }
   else if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
@@ -1560,7 +1560,7 @@
 #else
 		  if ( arith_invalid(1) < 0 )
 		    return;
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 		}
 	      else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
 		return;
@@ -1583,7 +1583,7 @@
 		  changesign(st1_ptr);
 #else
 		  if ( arith_invalid(1) < 0 ) return;
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 		}
 	      else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
 		return;
@@ -1618,14 +1618,14 @@
 	  /* This should have higher priority than denormals, but... */
 	  if ( arith_invalid(1) < 0 )  /* log(-infinity) */
 	    return;
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 	  if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
 	    return;
 #ifdef PECULIAR_486
 	  /* Denormal operands actually get higher priority */
 	  if ( arith_invalid(1) < 0 )  /* log(-infinity) */
 	    return;
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 	}
       else if ( st1_tag == TAG_Zero )
 	{
@@ -1654,7 +1654,7 @@
       EXCEPTION(EX_INTERNAL | 0x117);
       return;
     }
-#endif PARANOID
+#endif /* PARANOID */
 
   FPU_pop();
   return;
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/get_address.c linux/arch/i386/math-emu/get_address.c
--- v2.4.3/linux/arch/i386/math-emu/get_address.c	Mon Jun 19 12:56:08 2000
+++ linux/arch/i386/math-emu/get_address.c	Fri Apr  6 10:42:47 2001
@@ -143,7 +143,7 @@
       EXCEPTION(EX_INTERNAL|0x130);
       math_abort(FPU_info,SIGSEGV);
     }
-#endif PARANOID
+#endif /* PARANOID */
   addr->selector = VM86_REG_(segment);
   return (unsigned long)VM86_REG_(segment) << 4;
 }
@@ -166,7 +166,7 @@
       EXCEPTION(EX_INTERNAL|0x132);
       math_abort(FPU_info,SIGSEGV);
     }
-#endif PARANOID
+#endif /* PARANOID */
 
   switch ( segment )
     {
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/load_store.c linux/arch/i386/math-emu/load_store.c
--- v2.4.3/linux/arch/i386/math-emu/load_store.c	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/load_store.c	Fri Apr  6 10:42:47 2001
@@ -85,7 +85,7 @@
 #ifdef PARANOID
       else
 	EXCEPTION(EX_INTERNAL|0x140);
-#endif PARANOID
+#endif /* PARANOID */
     }
 
   switch ( type_table[type] )
@@ -112,7 +112,7 @@
     default:
       EXCEPTION(EX_INTERNAL|0x141);
       return 0;
-#endif PARANOID
+#endif /* PARANOID */
     }
 
   switch ( type )
@@ -217,7 +217,7 @@
 	partial_status &= ~(SW_Summary | SW_Backward);
 #ifdef PECULIAR_486
       control_word |= 0x40;  /* An 80486 appears to always set this bit */
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
       return 1;
     case 025:      /* fld m80real */
       clear_C1();
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/poly.h linux/arch/i386/math-emu/poly.h
--- v2.4.3/linux/arch/i386/math-emu/poly.h	Thu Nov  4 09:10:22 1999
+++ linux/arch/i386/math-emu/poly.h	Fri Apr  6 10:42:47 2001
@@ -118,4 +118,4 @@
                :"=g" (*x):"g" (x):"si","ax","cx");
 }
 
-#endif _POLY_H
+#endif /* _POLY_H */
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/poly_2xm1.c linux/arch/i386/math-emu/poly_2xm1.c
--- v2.4.3/linux/arch/i386/math-emu/poly_2xm1.c	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/poly_2xm1.c	Fri Apr  6 10:42:47 2001
@@ -67,7 +67,7 @@
       EXCEPTION(EX_INTERNAL|0x127);
       return 1;
     }
-#endif PARANOID
+#endif /* PARANOID */
 
   argSignif.lsw = 0;
   XSIG_LL(argSignif) = Xll = significand(arg);
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/poly_atan.c linux/arch/i386/math-emu/poly_atan.c
--- v2.4.3/linux/arch/i386/math-emu/poly_atan.c	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/poly_atan.c	Fri Apr  6 10:42:47 2001
@@ -124,7 +124,7 @@
 	      EXCEPTION(EX_INTERNAL|0x104);  /* There must be a logic error */
 	      return;
 	    }
-#endif PARANOID
+#endif /* PARANOID */
 	  argSignif.msw = 0;   /* Make the transformed arg -> 0.0 */
 	}
       else
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/poly_l2.c linux/arch/i386/math-emu/poly_l2.c
--- v2.4.3/linux/arch/i386/math-emu/poly_l2.c	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/poly_l2.c	Fri Apr  6 10:42:47 2001
@@ -157,7 +157,7 @@
 #else
 	  if ( arith_invalid(1) < 0 )
 	    return 1;
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 	}
 
       /* 80486 appears to do this */
@@ -243,7 +243,7 @@
 	  /* The argument is too large */
 	}
     }
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 
   arg_signif.lsw = argSignif.lsw; XSIG_LL(arg_signif) = XSIG_LL(argSignif);
   adj = norm_Xsig(&argSignif);
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/poly_sin.c linux/arch/i386/math-emu/poly_sin.c
--- v2.4.3/linux/arch/i386/math-emu/poly_sin.c	Thu Nov  4 09:10:22 1999
+++ linux/arch/i386/math-emu/poly_sin.c	Fri Apr  6 10:42:47 2001
@@ -199,7 +199,7 @@
     {
       EXCEPTION(EX_INTERNAL|0x150);
     }
-#endif PARANOID
+#endif /* PARANOID */
 
 }
 
@@ -224,7 +224,7 @@
       FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
       return;
     }
-#endif PARANOID
+#endif /* PARANOID */
 
   exponent = exponent(st0_ptr);
 
@@ -392,6 +392,6 @@
     {
       EXCEPTION(EX_INTERNAL|0x151);
     }
-#endif PARANOID
+#endif /* PARANOID */
 
 }
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/poly_tan.c linux/arch/i386/math-emu/poly_tan.c
--- v2.4.3/linux/arch/i386/math-emu/poly_tan.c	Wed Jul  5 10:56:13 2000
+++ linux/arch/i386/math-emu/poly_tan.c	Fri Apr  6 10:42:47 2001
@@ -66,7 +66,7 @@
 #ifdef PARANOID
   if ( signnegative(st0_ptr) )	/* Can't hack a number < 0.0 */
     { arith_invalid(0); return; }  /* Need a positive number */
-#endif PARANOID
+#endif /* PARANOID */
 
   /* Split the problem into two domains, smaller and larger than pi/4 */
   if ( (exponent == 0) || ((exponent == -1) && (st0_ptr->sigh > 0xc90fdaa2)) )
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/reg_compare.c linux/arch/i386/math-emu/reg_compare.c
--- v2.4.3/linux/arch/i386/math-emu/reg_compare.c	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/reg_compare.c	Fri Apr  6 10:42:47 2001
@@ -136,7 +136,7 @@
 #ifdef PARANOID
   if (!(st0_ptr->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
   if (!(b->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
-#endif PARANOID
+#endif /* PARANOID */
 
   diff = exp0 - expb;
   if ( diff == 0 )
@@ -203,7 +203,7 @@
 	EXCEPTION(EX_INTERNAL|0x121);
 	f = SW_C3 | SW_C2 | SW_C0;
 	break;
-#endif PARANOID
+#endif /* PARANOID */
       }
   setcc(f);
   if (c & COMP_Denormal)
@@ -255,7 +255,7 @@
 	EXCEPTION(EX_INTERNAL|0x122);
 	f = SW_C3 | SW_C2 | SW_C0;
 	break;
-#endif PARANOID
+#endif /* PARANOID */
       }
   setcc(f);
   if (c & COMP_Denormal)
@@ -312,7 +312,7 @@
 	EXCEPTION(EX_INTERNAL|0x123);
 	f = SW_C3 | SW_C2 | SW_C0;
 	break;
-#endif PARANOID
+#endif /* PARANOID */ 
       }
   setcc(f);
   if (c & COMP_Denormal)
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/reg_constant.h linux/arch/i386/math-emu/reg_constant.h
--- v2.4.3/linux/arch/i386/math-emu/reg_constant.h	Mon Dec 11 13:34:34 2000
+++ linux/arch/i386/math-emu/reg_constant.h	Fri Apr  6 10:42:47 2001
@@ -28,4 +28,4 @@
 extern FPU_REG const CONST_MINF;
 extern FPU_REG const CONST_QNaN;
 
-#endif _REG_CONSTANT_H_
+#endif /* _REG_CONSTANT_H_ */
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/reg_divide.c linux/arch/i386/math-emu/reg_divide.c
--- v2.4.3/linux/arch/i386/math-emu/reg_divide.c	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/reg_divide.c	Fri Apr  6 10:42:47 2001
@@ -201,6 +201,6 @@
       EXCEPTION(EX_INTERNAL|0x102);
       return FPU_Exception;
     }
-#endif PARANOID
+#endif /* PARANOID */ 
 
 }
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/reg_ld_str.c linux/arch/i386/math-emu/reg_ld_str.c
--- v2.4.3/linux/arch/i386/math-emu/reg_ld_str.c	Sun Jan 25 11:01:48 1998
+++ linux/arch/i386/math-emu/reg_ld_str.c	Fri Apr  6 10:42:47 2001
@@ -439,7 +439,7 @@
 		 converts to decide underflow. */
 	      if ( !((tmp.sigh == 0x00100000) && (tmp.sigl == 0) &&
 		  (st0_ptr->sigl & 0x000007ff)) )
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 		{
 		  EXCEPTION(EX_Underflow);
 		  /* This is a special case: see sec 16.2.5.1 of
@@ -559,7 +559,7 @@
 	  /* Underflow has priority. */
 	  if ( control_word & CW_Underflow )
 	    denormal_operand();
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 	  reg_copy(st0_ptr, &tmp);
 	  goto denormal_arg;
 	}
@@ -659,7 +659,7 @@
 		 converts to decide underflow. */
 	      if ( !((tmp.sigl == 0x00800000) &&
 		  ((st0_ptr->sigh & 0x000000ff) || st0_ptr->sigl)) )
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 		{
 		  EXCEPTION(EX_Underflow);
 		  /* This is a special case: see sec 16.2.5.1 of
@@ -776,7 +776,7 @@
 	  /* Underflow has priority. */
 	  if ( control_word & CW_Underflow )
 	    denormal_operand();
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */ 
 	  goto denormal_arg;
 	}
       else if (st0_tag == TW_Infinity)
@@ -1221,7 +1221,7 @@
 
 #ifdef PECULIAR_486
   control_word &= ~0xe080;
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */ 
 
   top = (partial_status >> SW_Top_Shift) & 7;
 
@@ -1303,7 +1303,7 @@
       FPU_put_user(control_word & ~0xe080, (unsigned long *) d);
 #else
       FPU_put_user(control_word, (unsigned short *) d);
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
       FPU_put_user(status_word(), (unsigned short *) (d+2));
       FPU_put_user(fpu_tag_word, (unsigned short *) (d+4));
       FPU_put_user(instruction_address.offset, (unsigned short *) (d+6));
@@ -1335,7 +1335,7 @@
       fpu_tag_word |= 0xffff0000;
       I387.soft.fcs &= ~0xf8000000;
       I387.soft.fos |= 0xffff0000;
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
       __copy_to_user(d, &control_word, 7*4);
       RE_ENTRANT_CHECK_ON;
       d += 0x1c;
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/reg_mul.c linux/arch/i386/math-emu/reg_mul.c
--- v2.4.3/linux/arch/i386/math-emu/reg_mul.c	Wed Jun 24 14:30:08 1998
+++ linux/arch/i386/math-emu/reg_mul.c	Fri Apr  6 10:42:47 2001
@@ -126,6 +126,6 @@
       EXCEPTION(EX_INTERNAL|0x102);
       return FPU_Exception;
     }
-#endif PARANOID
+#endif /* PARANOID */ 
 
 }
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/reg_round.S linux/arch/i386/math-emu/reg_round.S
--- v2.4.3/linux/arch/i386/math-emu/reg_round.S	Thu Nov  4 09:10:22 1999
+++ linux/arch/i386/math-emu/reg_round.S	Fri Apr  6 10:42:47 2001
@@ -100,7 +100,7 @@
 	.byte	0
 FPU_denormal:
 	.byte	0
-#endif NON_REENTRANT_FPU
+#endif /* NON_REENTRANT_FPU */
 
 
 .text
@@ -126,13 +126,13 @@
 
 #ifndef NON_REENTRANT_FPU
 	pushl	%ebx		/* adjust the stack pointer */
-#endif NON_REENTRANT_FPU
+#endif /* NON_REENTRANT_FPU */ 
 
 #ifdef PARANOID
 /* Cannot use this here yet */
 /*	orl	%eax,%eax */
 /*	jns	L_entry_bugged */
-#endif PARANOID
+#endif /* PARANOID */
 
 	cmpw	EXP_UNDER,EXP(%edi)
 	jle	L_Make_denorm			/* The number is a de-normal */
@@ -160,12 +160,12 @@
 	je	LRound_To_64
 #ifdef PARANOID
 	jmp	L_bugged_denorm_486
-#endif PARANOID
+#endif /* PARANOID */ 
 #else
 #ifdef PARANOID
 	jmp	L_bugged_denorm	/* There is no bug, just a bad control word */
-#endif PARANOID
-#endif PECULIAR_486
+#endif /* PARANOID */ 
+#endif /* PECULIAR_486 */
 
 
 /* Round etc to 24 bit precision */
@@ -186,7 +186,7 @@
 
 #ifdef PARANOID
 	jmp	L_bugged_round24
-#endif PARANOID
+#endif /* PARANOID */ 
 
 LUp_24:
 	cmpb	SIGN_POS,PARAM5
@@ -266,7 +266,7 @@
 
 #ifdef PARANOID
 	jmp	L_bugged_round53
-#endif PARANOID
+#endif /* PARANOID */ 
 
 LUp_53:
 	cmpb	SIGN_POS,PARAM5
@@ -340,7 +340,7 @@
 
 #ifdef PARANOID
 	jmp	L_bugged_round64
-#endif PARANOID
+#endif /* PARANOID */ 
 
 LUp_64:
 	cmpb	SIGN_POS,PARAM5
@@ -430,7 +430,7 @@
 
 #ifndef NON_REENTRANT_FPU
 	popl	%ebx		/* adjust the stack pointer */
-#endif NON_REENTRANT_FPU
+#endif /* NON_REENTRANT_FPU */ 
 
 fpu_Arith_exit:
 	popl	%ebx
@@ -570,7 +570,7 @@
 	/* But check it... just in case. */
 	cmpw	EXP_UNDER+1,EXP(%edi)
 	jne	L_norm_bugged
-#endif PARANOID
+#endif /* PARANOID */
 
 #ifdef PECULIAR_486
 	/*
@@ -586,7 +586,7 @@
 #else
 	orl	%eax,%eax		/* ms bits */
 	js	L_Normalised		/* No longer a denormal */
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */ 
 
 	jnz	LDenormal_adj_exponent
 
@@ -673,7 +673,7 @@
 	call	EXCEPTION
 	popl	%ebx
 	jmp	L_exception_exit
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */ 
 
 L_bugged_round24:
 	pushl	EX_INTERNAL|0x231
@@ -706,4 +706,4 @@
 L_exception_exit:
 	mov	$-1,%eax
 	jmp	fpu_reg_round_special_exit
-#endif PARANOID
+#endif /* PARANOID */ 
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/reg_u_add.S linux/arch/i386/math-emu/reg_u_add.S
--- v2.4.3/linux/arch/i386/math-emu/reg_u_add.S	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/reg_u_add.S	Fri Apr  6 10:42:47 2001
@@ -72,7 +72,7 @@
 
 	testl	$0x80000000,SIGH(%esi)
 	je	L_bugged
-#endif PARANOID
+#endif /* PARANOID */
 
 /* The number to be shifted is in %eax:%ebx:%edx */
 	cmpw	$32,%cx		/* shrd only works for 0..31 bits */
@@ -164,4 +164,4 @@
 	popl	%esi
 	leave
 	ret
-#endif PARANOID
+#endif /* PARANOID */
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/reg_u_div.S linux/arch/i386/math-emu/reg_u_div.S
--- v2.4.3/linux/arch/i386/math-emu/reg_u_div.S	Fri Aug 27 10:18:17 1999
+++ linux/arch/i386/math-emu/reg_u_div.S	Fri Apr  6 10:42:47 2001
@@ -67,7 +67,7 @@
 	.long	0
 FPU_ovfl_flag:
 	.byte	0
-#endif NON_REENTRANT_FPU
+#endif /* NON_REENTRANT_FPU */
 
 #define REGA	PARAM1
 #define REGB	PARAM2
@@ -79,7 +79,7 @@
 	movl	%esp,%ebp
 #ifndef NON_REENTRANT_FPU
 	subl	$28,%esp
-#endif NON_REENTRANT_FPU
+#endif /* NON_REENTRANT_FPU */
 
 	pushl	%esi
 	pushl	%edi
@@ -112,7 +112,7 @@
 /*	je	L_bugged */
 	testl	$0x80000000, SIGH(%ebx)	/* Divisor */
 	je	L_bugged
-#endif PARANOID
+#endif /* PARANOID */ 
 
 /* Check if the divisor can be treated as having just 32 bits */
 	cmpl	$0,SIGL(%ebx)
@@ -248,7 +248,7 @@
 
 #ifdef PARANOID
 	jb	L_bugged_1
-#endif PARANOID
+#endif /* PARANOID */ 
 
 	/* need to subtract another once of the denom */
 	incl	FPU_result_2	/* Correct the answer */
@@ -261,7 +261,7 @@
 #ifdef PARANOID
 	sbbl	$0,FPU_accum_3
 	jne	L_bugged_1	/* Must check for non-zero result here */
-#endif PARANOID
+#endif /* PARANOID */ 
 
 /*----------------------------------------------------------------------*/
 /* Half of the main problem is done, there is just a reduced numerator
@@ -291,7 +291,7 @@
 
 #ifdef PARANOID
 	je	L_bugged_2	/* Can't bump the result to 1.0 */
-#endif PARANOID
+#endif /* PARANOID */ 
 
 LDo_2nd_div:
 	cmpl	$0,%ecx		/* augmented denom msw */
@@ -314,7 +314,7 @@
 
 #ifdef PARANOID
 	jc	L_bugged_2
-#endif PARANOID
+#endif /* PARANOID */ 
 
 	movl	FPU_result_1,%eax	/* Get the result back */
 	mull	SIGL(%ebx)	/* now mul the ls dw of the denom */
@@ -325,14 +325,14 @@
 
 #ifdef PARANOID
 	jc	L_bugged_2
-#endif PARANOID
+#endif /* PARANOID */ 
 
 	jz	LDo_3rd_32_bits
 
 #ifdef PARANOID
 	cmpl	$1,FPU_accum_2
 	jne	L_bugged_2
-#endif PARANOID
+#endif /* PARANOID */
 
 	/* need to subtract another once of the denom */
 	movl	SIGL(%ebx),%eax
@@ -344,14 +344,14 @@
 #ifdef PARANOID
 	jc	L_bugged_2
 	jne	L_bugged_2
-#endif PARANOID
+#endif /* PARANOID */ 
 
 	addl	$1,FPU_result_1	/* Correct the answer */
 	adcl	$0,FPU_result_2
 
 #ifdef PARANOID
 	jc	L_bugged_2	/* Must check for non-zero result here */
-#endif PARANOID
+#endif /* PARANOID */
 
 /*----------------------------------------------------------------------*/
 /* The division is essentially finished here, we just need to perform
@@ -470,4 +470,4 @@
 
 	leave
 	ret
-#endif PARANOID
+#endif /* PARANOID */ 
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/reg_u_mul.S linux/arch/i386/math-emu/reg_u_mul.S
--- v2.4.3/linux/arch/i386/math-emu/reg_u_mul.S	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/reg_u_mul.S	Fri Apr  6 10:42:47 2001
@@ -40,7 +40,7 @@
 	.long	0
 FPU_accum_1:
 	.long	0
-#endif NON_REENTRANT_FPU
+#endif /* NON_REENTRANT_FPU */
 
 
 .text
@@ -49,7 +49,7 @@
 	movl	%esp,%ebp
 #ifndef NON_REENTRANT_FPU
 	subl	$8,%esp
-#endif NON_REENTRANT_FPU
+#endif /* NON_REENTRANT_FPU */ 
 
 	pushl	%esi
 	pushl	%edi
@@ -63,7 +63,7 @@
 	jz	L_bugged
 	testl	$0x80000000,SIGH(%edi)
 	jz	L_bugged
-#endif PARANOID
+#endif /* PARANOID */
 
 	xorl	%ecx,%ecx
 	xorl	%ebx,%ebx
@@ -144,5 +144,5 @@
 	popl	%esi
 	leave
 	ret
-#endif PARANOID
+#endif /* PARANOID */ 
 
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/reg_u_sub.S linux/arch/i386/math-emu/reg_u_sub.S
--- v2.4.3/linux/arch/i386/math-emu/reg_u_sub.S	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/reg_u_sub.S	Fri Apr  6 10:42:47 2001
@@ -54,7 +54,7 @@
 
 	testl	$0x80000000,SIGH(%esi)
 	je	L_bugged_2
-#endif PARANOID
+#endif /* PARANOID */
 
 /*--------------------------------------+
  |	Form a register holding the     |
@@ -165,7 +165,7 @@
 #ifdef PARANOID
 	/* We can never get a borrow */
 	jc	L_bugged
-#endif PARANOID
+#endif /* PARANOID */
 
 /*--------------------------------------+
  |	Normalize the result		|
@@ -199,7 +199,7 @@
 #ifdef PARANOID
 	orl	%edx,%edx
 	jnz	L_bugged_3
-#endif PARANOID
+#endif /* PARANOID */ 
 
 	/* The result is zero */
 	movw	$0,EXP(%edi)		/* exponent */
@@ -262,7 +262,7 @@
 L_error_exit:
 	movl	$-1,%eax
 
-#endif PARANOID
+#endif /* PARANOID */
 
 L_exit:
 	popl	%ebx
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/status_w.h linux/arch/i386/math-emu/status_w.h
--- v2.4.3/linux/arch/i386/math-emu/status_w.h	Mon Dec 11 13:34:33 2000
+++ linux/arch/i386/math-emu/status_w.h	Fri Apr  6 10:42:47 2001
@@ -58,8 +58,8 @@
 #  define clear_C1()  { partial_status &= ~SW_C1; }
 # else
 #  define clear_C1()
-#endif PECULIAR_486
+#endif /* PECULIAR_486 */
 
-#endif __ASSEMBLY__
+#endif /* __ASSEMBLY__ */
 
-#endif _STATUS_H_
+#endif /* _STATUS_H_ */
diff -u --recursive --new-file v2.4.3/linux/arch/i386/math-emu/wm_sqrt.S linux/arch/i386/math-emu/wm_sqrt.S
--- v2.4.3/linux/arch/i386/math-emu/wm_sqrt.S	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/wm_sqrt.S	Fri Apr  6 10:42:47 2001
@@ -70,7 +70,7 @@
 	.long	0
 FPU_fsqrt_arg_0:
 	.long	0		/* ls word, at most the ms bit is set */
-#endif NON_REENTRANT_FPU
+#endif /* NON_REENTRANT_FPU */ 
 
 
 .text
@@ -79,7 +79,7 @@
 	movl	%esp,%ebp
 #ifndef NON_REENTRANT_FPU
 	subl	$28,%esp
-#endif NON_REENTRANT_FPU
+#endif /* NON_REENTRANT_FPU */
 	pushl	%esi
 	pushl	%edi
 	pushl	%ebx
@@ -210,7 +210,7 @@
 /* It should be possible to get here only if the arg is ffff....ffff */
 	cmp	$0xffffffff,FPU_fsqrt_arg_1
 	jnz	sqrt_stage_2_error
-#endif PARANOID
+#endif /* PARANOID */
 
 /* The best rounded result. */
 	xorl	%eax,%eax
@@ -224,7 +224,7 @@
 sqrt_stage_2_error:
 	pushl	EX_INTERNAL|0x213
 	call	EXCEPTION
-#endif PARANOID
+#endif /* PARANOID */ 
 
 sqrt_stage_2_done:
 
@@ -279,7 +279,7 @@
 	call	EXCEPTION
 
 sqrt_stage_3_no_error:
-#endif PARANOID
+#endif /* PARANOID */
 
 	movl	FPU_accum_2,%edx
 	movl	FPU_accum_1,%eax
@@ -385,7 +385,7 @@
 	call	EXCEPTION
 
 sqrt_near_exact_ok:
-#endif PARANOID
+#endif /* PARANOID */ 
 
 	or	%ebx,%ebx
 	js	sqrt_near_exact_small
@@ -445,7 +445,7 @@
 	call	EXCEPTION
 
 sqrt_more_prec_ok:
-#endif PARANOID
+#endif /* PARANOID */ 
 
 	or	%ebx,%ebx
 	js	sqrt_more_prec_small
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/Makefile linux/arch/ia64/Makefile
--- v2.4.3/linux/arch/ia64/Makefile	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/Makefile	Thu Apr  5 12:51:46 2001
@@ -5,7 +5,7 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 1998-2000 by David Mosberger-Tang <davidm@hpl.hp.com>
+# Copyright (C) 1998-2001 by David Mosberger-Tang <davidm@hpl.hp.com>
 #
 
 NM := $(CROSS_COMPILE)nm -B
@@ -14,13 +14,13 @@
 export AWK
 
 LINKFLAGS = -static -T arch/$(ARCH)/vmlinux.lds
-AFLAGS += -Wa,-x 
+AFLAGS += -Wa,-x
 AFLAGS_KERNEL := -mconstant-gp
 EXTRA	=
 
 CFLAGS := $(CFLAGS) -pipe $(EXTRA) -Wa,-x -ffixed-r13 -mfixed-range=f10-f15,f32-f127 \
 	  -funwind-tables -falign-functions=32
-# -frename-registers
+# -frename-registers (this crashes the Nov 17 compiler...)
 CFLAGS_KERNEL := -mconstant-gp
 
 ifeq ($(CONFIG_ITANIUM_ASTEP_SPECIFIC),y)
@@ -53,7 +53,7 @@
 endif
 
 ifdef CONFIG_IA64_SGI_SN1
-CFLAGS += -DBRINGUP
+	CFLAGS		+= -DBRINGUP
         SUBDIRS         :=      arch/$(ARCH)/sn/sn1	\
 				arch/$(ARCH)/sn		\
 				arch/$(ARCH)/sn/io	\
@@ -103,6 +103,11 @@
 
 FORCE: ;
 
+compressed: vmlinux
+	$(OBJCOPY) --strip-all vmlinux vmlinux-tmp
+	gzip -9 vmlinux-tmp
+	mv vmlinux-tmp.gz vmlinux.gz
+
 rawboot:
 	@$(MAKEBOOT) rawboot
 
@@ -120,8 +125,6 @@
 	@$(MAKEBOOT) srmboot
 
 archclean:
-	@$(MAKE) -C arch/$(ARCH)/kernel clean
-	@$(MAKE) -C arch/$(ARCH)/tools clean
 	@$(MAKEBOOT) clean
 
 archmrproper:
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/boot/bootloader.c linux/arch/ia64/boot/bootloader.c
--- v2.4.3/linux/arch/ia64/boot/bootloader.c	Mon Oct  9 17:54:53 2000
+++ linux/arch/ia64/boot/bootloader.c	Thu Apr  5 12:51:47 2001
@@ -3,8 +3,8 @@
  *
  * Loads an ELF kernel.
  *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.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 Stephane Eranian <eranian@hpl.hp.com>
  *
  * 01/07/99 S.Eranian modified to pass command line arguments to kernel
@@ -65,35 +65,22 @@
 	}
 }
 
-void
-enter_virtual_mode (unsigned long new_psr)
-{
-	long tmp;
-
-	asm volatile ("movl %0=1f" : "=r"(tmp));
-	asm volatile ("mov cr.ipsr=%0" :: "r"(new_psr));
-	asm volatile ("mov cr.iip=%0" :: "r"(tmp));
-	asm volatile ("mov cr.ifs=r0");
-	asm volatile ("rfi;;");
-	asm volatile ("1:");
-}
-
 #define MAX_ARGS 32
 
 void
 _start (void)
 {
-	register long sp asm ("sp");
 	static char stack[16384] __attribute__ ((aligned (16)));
 	static char mem[4096];
 	static char buffer[1024];
-	unsigned long flags, off;
+	unsigned long off;
 	int fd, i;
 	struct disk_req req;
 	struct disk_stat stat;
 	struct elfhdr *elf;
 	struct elf_phdr *elf_phdr;	/* program header */
 	unsigned long e_entry, e_phoff, e_phnum;
+	register struct ia64_boot_param *bp;
 	char *kpath, *args;
 	long arglen = 0;
 
@@ -107,15 +94,13 @@
 	ssc(0, 0, 0, 0, SSC_CONSOLE_INIT);
 
 	/*
-	 * S.Eranian: extract the commandline argument from the 
-	 * simulator
+	 * S.Eranian: extract the commandline argument from the simulator
 	 *
 	 * The expected format is as follows:
          *
 	 *	kernelname args...
 	 *
-	 * Both are optional but you can't have the second one without the 
-	 * first.
+	 * Both are optional but you can't have the second one without the first.
 	 */
 	arglen = ssc((long) buffer, 0, 0, 0, SSC_GET_ARGS);
 
@@ -183,6 +168,10 @@
 		e_phoff += sizeof(*elf_phdr);
 
 		elf_phdr = (struct elf_phdr *) mem;
+
+		if (elf_phdr->p_type != PT_LOAD)
+			continue;
+
 		req.len = elf_phdr->p_filesz;
 		req.addr = __pa(elf_phdr->p_vaddr);
 		ssc(fd, 1, (long) &req, elf_phdr->p_offset, SSC_READ);
@@ -197,38 +186,12 @@
 	/* fake an I/O base address: */
 	asm volatile ("mov ar.k0=%0" :: "r"(0xffffc000000UL));
 
-	/*
-	 * Install a translation register that identity maps the
-	 * kernel's 256MB page.
-	 */
-	ia64_clear_ic(flags);
-	ia64_set_rr(          0, (0x1000 << 8) | (_PAGE_SIZE_1M << 2));
-	ia64_set_rr(PAGE_OFFSET, (ia64_rid(0, PAGE_OFFSET) << 8) | (_PAGE_SIZE_256M << 2));
-	ia64_srlz_d();
-	ia64_itr(0x3, 0, 1024*1024,
-		 pte_val(mk_pte_phys(1024*1024, __pgprot(__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RWX))),
-		 _PAGE_SIZE_1M);
-	ia64_itr(0x3, 1, PAGE_OFFSET,
-		 pte_val(mk_pte_phys(0, __pgprot(__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RWX))),
-		 _PAGE_SIZE_256M);
-	ia64_srlz_i();
-
-	enter_virtual_mode(flags | IA64_PSR_IT | IA64_PSR_IC | IA64_PSR_DT | IA64_PSR_RT
-			   | IA64_PSR_DFH | IA64_PSR_BN);
-
-	sys_fw_init(args, arglen);
+	bp = sys_fw_init(args, arglen);
 
 	ssc(0, (long) kpath, 0, 0, SSC_LOAD_SYMBOLS);
 
-	/*
-	 * Install the kernel's command line argument on ZERO_PAGE
-	 * just after the botoparam structure.
-	 * In case we don't have any argument just put \0
-	 */
-	memcpy(((struct ia64_boot_param *)ZERO_PAGE_ADDR) + 1, args, arglen);
-	sp = __pa(&stack);
-
-	asm volatile ("br.sptk.few %0" :: "b"(e_entry));
+	asm volatile ("mov sp=%2; mov r28=%1; br.sptk.few %0"
+		      :: "b"(e_entry), "r"(bp), "r"(__pa(&stack)));
 
 	cons_write("kernel returned!\n");
 	ssc(-1, 0, 0, 0, SSC_EXIT);
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/config.in linux/arch/ia64/config.in
--- v2.4.3/linux/arch/ia64/config.in	Fri Feb 16 15:53:08 2001
+++ linux/arch/ia64/config.in	Thu Apr  5 12:51:47 2001
@@ -24,6 +24,10 @@
 define_bool CONFIG_MCA n
 define_bool CONFIG_SBUS n
 
+choice 'IA-64 processor type' \
+	"Itanium			CONFIG_ITANIUM \
+	 McKinley			CONFIG_MCKINLEY" Itanium
+
 choice 'IA-64 system type'					\
 	"generic		CONFIG_IA64_GENERIC		\
 	 DIG-compliant		CONFIG_IA64_DIG			\
@@ -36,24 +40,47 @@
 	 16KB			CONFIG_IA64_PAGE_SIZE_16KB		\
 	 64KB			CONFIG_IA64_PAGE_SIZE_64KB" 16KB
 
-if [ "$CONFIG_IA64_DIG" = "y" ]; then
-	define_bool CONFIG_ITANIUM y
+if [ "$CONFIG_ITANIUM" = "y" ]; then
 	define_bool CONFIG_IA64_BRL_EMU y
 	bool '  Enable Itanium A-step specific code' CONFIG_ITANIUM_ASTEP_SPECIFIC
 	bool '  Enable Itanium B-step specific code' CONFIG_ITANIUM_BSTEP_SPECIFIC
 	if [ "$CONFIG_ITANIUM_BSTEP_SPECIFIC" = "y" ]; then
 	  bool '   Enable Itanium B0-step specific code' CONFIG_ITANIUM_B0_SPECIFIC
+        fi
+	if [ "$CONFIG_ITANIUM_BSTEP_SPECIFIC" = "y" ]; then
 	  bool '   Enable Itanium B1-step specific code' CONFIG_ITANIUM_B1_SPECIFIC
+	fi
+	if [ "$CONFIG_ITANIUM_BSTEP_SPECIFIC" = "y" ]; then
 	  bool '   Enable Itanium B2-step specific code' CONFIG_ITANIUM_B2_SPECIFIC
 	fi
 	bool '  Enable Itanium C-step specific code' CONFIG_ITANIUM_CSTEP_SPECIFIC
 	if [ "$CONFIG_ITANIUM_CSTEP_SPECIFIC" = "y" ]; then
 	  bool '   Enable Itanium C0-step specific code' CONFIG_ITANIUM_C0_SPECIFIC
 	fi
+	if [ "$CONFIG_ITANIUM_ASTEP_SPECIFIC" = "y" -o "$CONFIG_ITANIUM_B0_SPECIFIC" = "y" \
+	     -o "$CONFIG_ITANIUM_B1_SPECIFIC" = "y" -o "$CONFIG_ITANIUM_B2_SPECIFIC" = "y" ]; then
+	  define_bool CONFIG_ITANIUM_PTCG n
+	else
+	  define_bool CONFIG_ITANIUM_PTCG y
+	fi
+	if [ "$CONFIG_IA64_SGI_SN1" = "y" ]; then
+	  define_int CONFIG_IA64_L1_CACHE_SHIFT 7 # align cache-sensitive data to 128 bytes
+	else
+	  define_int CONFIG_IA64_L1_CACHE_SHIFT 6 # align cache-sensitive data to 64 bytes
+	fi
+fi
+
+if [ "$CONFIG_MCKINLEY" = "y" ]; then
+	define_bool CONFIG_ITANIUM_PTCG y
+	define_int CONFIG_IA64_L1_CACHE_SHIFT 7
+	bool '  Enable McKinley A-step specific code' CONFIG_MCKINLEY_ASTEP_SPECIFIC
+	if [ "$CONFIG_MCKINLEY_ASTEP_SPECIFIC" = "y" ]; then
+	  bool '   Enable McKinley A0/A1-step specific code' CONFIG_MCKINLEY_A0_SPECIFIC
+	fi
+fi
+
+if [ "$CONFIG_IA64_DIG" = "y" ]; then
 	bool '  Force interrupt redirection' CONFIG_IA64_HAVE_IRQREDIR
-	bool '  Enable use of global TLB purge instruction (ptc.g)' CONFIG_ITANIUM_PTCG
-	bool '  Enable SoftSDV hacks' CONFIG_IA64_SOFTSDV_HACKS
-	bool '  Enable AzusA hacks' CONFIG_IA64_AZUSA_HACKS
 	bool '  Enable IA-64 Machine Check Abort' CONFIG_IA64_MCA
 	bool '  Enable ACPI 2.0 with errata 1.3' CONFIG_ACPI20
 	bool '  ACPI kernel configuration manager (EXPERIMENTAL)' CONFIG_ACPI_KERNEL_CONFIG
@@ -65,11 +92,6 @@
 fi
 
 if [ "$CONFIG_IA64_SGI_SN1" = "y" ]; then
-	bool '  Enable use of global TLB purge instruction (ptc.g)' CONFIG_ITANIUM_PTCG
-	bool '  Enable Itanium B-step specific code' CONFIG_ITANIUM_BSTEP_SPECIFIC
-	if [ "$CONFIG_ITANIUM_BSTEP_SPECIFIC" = "y" ]; then
-	  bool '    Enable Itanium B0-step specific code' CONFIG_ITANIUM_B0_SPECIFIC
-	fi
 	bool '  Enable SGI Medusa Simulator Support' CONFIG_IA64_SGI_SN1_SIM
 	define_bool CONFIG_DEVFS_DEBUG y
 	define_bool CONFIG_DEVFS_FS y
@@ -87,7 +109,8 @@
 
 bool 'SMP support' CONFIG_SMP
 bool 'Performance monitor support' CONFIG_PERFMON
-bool '/proc/pal support' CONFIG_IA64_PALINFO
+tristate '/proc/pal support' CONFIG_IA64_PALINFO
+tristate '/proc/efi support' CONFIG_IA64_EFIVARS
 
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
@@ -253,7 +276,6 @@
 bool 'Turn on compare-and-exchange bug checking (slow!)' CONFIG_IA64_DEBUG_CMPXCHG
 bool 'Turn on irq debug checks (slow!)' CONFIG_IA64_DEBUG_IRQ
 bool 'Print possible IA64 hazards to console' CONFIG_IA64_PRINT_HAZARDS
-bool 'Enable new unwind support' CONFIG_IA64_NEW_UNWIND
 bool 'Disable VHPT' CONFIG_DISABLE_VHPT
 
 endmenu
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/dig/setup.c linux/arch/ia64/dig/setup.c
--- v2.4.3/linux/arch/ia64/dig/setup.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/dig/setup.c	Thu Apr  5 12:51:47 2001
@@ -1,9 +1,9 @@
 /*
- * Platform dependent support for Intel SoftSDV simulator.
+ * Platform dependent support for DIG64 platforms.
  *
  * Copyright (C) 1999 Intel Corp.
- * Copyright (C) 1999 Hewlett-Packard Co
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999, 2001 Hewlett-Packard Co
+ * Copyright (C) 1999, 2001 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>
@@ -48,18 +48,14 @@
 	 */
 	ROOT_DEV = to_kdev_t(0x0802);		/* default to second partition on first drive */
 
-#ifdef	CONFIG_IA64_SOFTSDV_HACKS
-	ROOT_DEV = to_kdev_t(0x0302);		/* 2nd partion on 1st IDE */
-#endif /* CONFIG_IA64_SOFTSDV_HACKS */
-
 #ifdef CONFIG_SMP
 	init_smp_config();
 #endif
 
 	memset(&screen_info, 0, sizeof(screen_info));
 
-	if (!ia64_boot_param.console_info.num_rows
-	    || !ia64_boot_param.console_info.num_cols)
+	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");
 		orig_x = 0;
@@ -68,10 +64,10 @@
 		num_rows = 25;
 		font_height = 16;
 	} else {
-		orig_x = ia64_boot_param.console_info.orig_x;
-		orig_y = ia64_boot_param.console_info.orig_y;
-		num_cols = ia64_boot_param.console_info.num_cols;
-		num_rows = ia64_boot_param.console_info.num_rows;
+		orig_x = ia64_boot_param->console_info.orig_x;
+		orig_y = ia64_boot_param->console_info.orig_y;
+		num_cols = ia64_boot_param->console_info.num_cols;
+		num_rows = ia64_boot_param->console_info.num_rows;
 		font_height = 400 / num_rows;
 	}
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/hp/hpsim_irq.c linux/arch/ia64/hp/hpsim_irq.c
--- v2.4.3/linux/arch/ia64/hp/hpsim_irq.c	Thu Jun 22 07:09:44 2000
+++ linux/arch/ia64/hp/hpsim_irq.c	Thu Apr  5 12:51:47 2001
@@ -1,8 +1,8 @@
 /*
  * Platform dependent support for HP simulator.
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <linux/init.h>
@@ -35,10 +35,12 @@
 void __init
 hpsim_irq_init (void)
 {
+	irq_desc_t *idesc;
 	int i;
 
-	for (i = IA64_MIN_VECTORED_IRQ; i <= IA64_MAX_VECTORED_IRQ; ++i) {
-		if (irq_desc[i].handler == &no_irq_type)
-			irq_desc[i].handler = &irq_type_hp_sim;
+	for (i = 0; i < NR_IRQS; ++i) {
+		idesc = irq_desc(i);
+		if (idesc->handler == &no_irq_type)
+			idesc->handler = &irq_type_hp_sim;
 	}
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/ia32/binfmt_elf32.c linux/arch/ia64/ia32/binfmt_elf32.c
--- v2.4.3/linux/arch/ia64/ia32/binfmt_elf32.c	Thu Mar 22 09:24:58 2001
+++ linux/arch/ia64/ia32/binfmt_elf32.c	Thu Apr  5 12:51:47 2001
@@ -57,28 +57,30 @@
 
 	if (page_count(page) != 1)
 		printk("mem_map disagrees with %p at %08lx\n", (void *) page, address);
+
 	pgd = pgd_offset(tsk->mm, address);
-	pmd = pmd_alloc(pgd, address);
-	if (!pmd) {
-		__free_page(page);
-		force_sig(SIGKILL, tsk);
-		return 0;
-	}
-	pte = pte_alloc(pmd, address);
-	if (!pte) {
-		__free_page(page);
-		force_sig(SIGKILL, tsk);
-		return 0;
-	}
-	if (!pte_none(*pte)) {
-		pte_ERROR(*pte);
-		__free_page(page);
-		return 0;
+
+	spin_lock(&tsk->mm->page_table_lock);
+	{
+		pmd = pmd_alloc(tsk->mm, pgd, address);
+		if (!pmd)
+			goto out;
+		pte = pte_alloc(tsk->mm, pmd, address);
+		if (!pte)
+			goto out;
+		if (!pte_none(*pte))
+			goto out;
+		flush_page_to_ram(page);
+		set_pte(pte, pte_mkwrite(mk_pte(page, PAGE_SHARED)));
 	}
-	flush_page_to_ram(page);
-	set_pte(pte, pte_mkwrite(mk_pte(page, PAGE_SHARED)));
+	spin_unlock(&tsk->mm->page_table_lock);
 	/* no need for flush_tlb */
 	return page;
+
+  out:
+	spin_unlock(&tsk->mm->page_table_lock);
+	__free_page(page);
+	return 0;
 }
 
 void ia64_elf32_init(struct pt_regs *regs)
@@ -90,12 +92,13 @@
 		put_shared_page(current, virt_to_page(ia32_tss), IA32_PAGE_OFFSET + PAGE_SIZE);
 
 	nr = smp_processor_id();
-	
+
 	/* Do all the IA-32 setup here */
 
-	current->thread.map_base  =  0x40000000;
-	current->thread.task_size =  0xc0000000;	/* use what Linux/x86 uses... */
- 
+	current->thread.map_base  = 0x40000000;
+	current->thread.task_size = 0xc0000000;		/* use what Linux/x86 uses... */
+	set_fs(USER_DS);				/* set addr limit for new TASK_SIZE */
+
 	/* setup ia32 state for ia32_load_state */
 
 	current->thread.eflag = IA32_EFLAG;
@@ -124,14 +127,8 @@
 		: "r" ((ulong)IA32_FCR_DEFAULT));
 	__asm__("mov ar.fir = r0");
 	__asm__("mov ar.fdr = r0");
-	__asm__("mov %0=ar.k0 ;;" : "=r" (current->thread.old_iob));
-	__asm__("mov ar.k0=%0 ;;" :: "r"(IA32_IOBASE));
-	/* TSS */
-	__asm__("mov ar.k1 = %0"
-		: /* no outputs */
-		: "r" IA64_SEG_DESCRIPTOR(IA32_PAGE_OFFSET + PAGE_SIZE,
-					  0x1FFFL, 0xBL, 1L,
-					  3L, 1L, 1L, 1L));
+	current->thread.old_iob = ia64_get_kr(IA64_KR_IO_BASE);
+	ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
 
 	/* Get the segment selectors right */
 	regs->r16 = (__USER_DS << 16) |  (__USER_DS); /* ES == DS, GS, FS are zero */
@@ -149,23 +146,10 @@
 	regs->r31 = IA64_SEG_DESCRIPTOR(0xc0000000L, 0x400L, 0x3L, 1L, 3L,
 					1L, 1L, 1L);
 
-       	/* Clear psr.ac */
+	/* Clear psr.ac */
 	regs->cr_ipsr &= ~IA64_PSR_AC;
 
 	regs->loadrs = 0;
-	/*
-	 *  According to the ABI %edx points to an `atexit' handler.
-	 *  Since we don't have one we'll set it to 0 and initialize
-	 *  all the other registers just to make things more deterministic,
-	 *  ala the i386 implementation.
-	 */
-	regs->r8 = 0;	/* %eax */
-	regs->r11 = 0;	/* %ebx */
-	regs->r9 = 0;	/* %ecx */
-	regs->r10 = 0;	/* %edx */
-	regs->r13 = 0;	/* %ebp */
-	regs->r14 = 0;	/* %esi */
-	regs->r15 = 0;	/* %edi */
 }
 
 #undef STACK_TOP
@@ -185,9 +169,9 @@
 	bprm->exec += stack_base;
 
 	mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-	if (!mpnt) 
-		return -ENOMEM; 
-	
+	if (!mpnt)
+		return -ENOMEM;
+
 	{
 		mpnt->vm_mm = current->mm;
 		mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
@@ -200,7 +184,7 @@
 		mpnt->vm_private_data = 0;
 		insert_vm_struct(current->mm, mpnt);
 		current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
-	} 
+	}
 
 	for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
 		if (bprm->page[i]) {
@@ -208,7 +192,7 @@
 		}
 		stack_base += PAGE_SIZE;
 	}
-	
+
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/ia32/ia32_entry.S linux/arch/ia64/ia32/ia32_entry.S
--- v2.4.3/linux/arch/ia64/ia32/ia32_entry.S	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/ia32/ia32_entry.S	Thu Apr  5 12:51:47 2001
@@ -4,11 +4,34 @@
 
 #include "../kernel/entry.h"
 
+	/*
+	 * execve() is special because in case of success, we need to
+	 * setup a null register window frame (in case an IA-32 process
+	 * is exec'ing an IA-64 program).
+	 */
+ENTRY(ia32_execve)
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3)
+	alloc loc1=ar.pfs,3,2,4,0
+	mov loc0=rp
+	.body
+	mov out0=in0			// filename
+	;;				// stop bit between alloc and call
+	mov out1=in1			// argv
+	mov out2=in2			// envp
+	add out3=16,sp			// regs
+	br.call.sptk.few rp=sys32_execve
+1:	cmp4.ge p6,p0=r8,r0
+	mov ar.pfs=loc1			// restore ar.pfs
+	;;
+(p6)	mov ar.pfs=r0			// clear ar.pfs in case of success
+	sxt4 r8=r8			// return 64-bit result
+	mov rp=loc0
+	br.ret.sptk.few rp
+END(ia32_execve)
+
 	//
 	// Get possibly unaligned sigmask argument into an aligned
 	//   kernel buffer
-	.text
-
 GLOBAL_ENTRY(ia32_rt_sigsuspend)
 	// We'll cheat and not do an alloc here since we are ultimately
 	// going to do a simple branch to the IA64 sys_rt_sigsuspend.
@@ -16,38 +39,30 @@
 	// We copy this 4-byte aligned value to an 8-byte aligned buffer
 	// in the task structure and then jump to the IA64 code.
 
-	mov r8=r0		// no memory access errors yet
-	add r10=4,r32
-	;;
-1:
-	ld4 r2=[r32]		// get first half of sigmask
-	ld4 r3=[r10]		// get second half of sigmask
-2:
-	cmp.lt p6,p0=r8,r0	// check memory access
+	EX(.Lfail, ld4 r2=[r32],4)		// load low part of sigmask
 	;;
-(p6)	br.ret.sptk.many rp	//   it failed
-
+	EX(.Lfail, ld4 r3=[r32])		// load high part of sigmask
 	adds r32=IA64_TASK_THREAD_SIGMASK_OFFSET,r13
+	;;
+	st8 [r32]=r2
 	adds r10=IA64_TASK_THREAD_SIGMASK_OFFSET+4,r13
 	;;
-	st4 [r32]=r2
+
 	st4 [r10]=r3
 	br.cond.sptk.many sys_rt_sigsuspend
-END(ia32_rt_sigsuspend)
 
-	.section __ex_table,"a"
-	data4 @gprel(1b)
-	data4 (2b-1b)|1
-	.previous
+.Lfail:	br.ret.sptk.many rp	// failed to read sigmask
+END(ia32_rt_sigsuspend)
 
 GLOBAL_ENTRY(ia32_ret_from_syscall)
 	PT_REGS_UNWIND_INFO(0)
 
 	cmp.ge p6,p7=r8,r0                      // syscall executed successfully?
 	adds r2=IA64_PT_REGS_R8_OFFSET+16,sp    // r2 = &pt_regs.r8
-	;; 
+	;;
+	alloc r3=ar.pfs,0,0,0,0			// drop the syscall argument frame
 	st8 [r2]=r8                             // store return value in slot for r8
-	br.cond.sptk.few ia64_leave_kernel
+	br.cond.sptk.many ia64_leave_kernel
 END(ia32_ret_from_syscall)
 
 	//
@@ -69,7 +84,8 @@
 	;;
 	st8.spill [r2]=r8			// store return value in slot for r8
 	br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch return value
-.ret2:	br.cond.sptk.many ia64_leave_kernel	// rp MUST be != ia64_leave_kernel!
+.ret2:	alloc r2=ar.pfs,0,0,0,0			// drop the syscall argument frame
+	br.cond.sptk.many ia64_leave_kernel	// rp MUST be != ia64_leave_kernel!
 END(ia32_trace_syscall)
 
 GLOBAL_ENTRY(sys32_vfork)
@@ -79,7 +95,7 @@
 END(sys32_vfork)
 
 GLOBAL_ENTRY(sys32_fork)
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2))
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
 	alloc r16=ar.pfs,2,2,4,0
 	mov out0=SIGCHLD			// out0 = clone_flags
 	;;
@@ -88,14 +104,14 @@
 	mov loc1=r16				// save ar.pfs across do_fork
 	DO_SAVE_SWITCH_STACK
 
-	UNW(.body)
+	.body
 
 	mov out1=0
 	mov out3=0
 	adds out2=IA64_SWITCH_STACK_SIZE+16,sp	// out2 = &regs
 	br.call.sptk.few rp=do_fork
 .ret3:	mov ar.pfs=loc1
-	UNW(.restore sp)
+	.restore sp
 	adds sp=IA64_SWITCH_STACK_SIZE,sp	// pop the switch stack
 	mov rp=loc0
 	br.ret.sptk.many rp
@@ -104,7 +120,7 @@
 	.rodata
 	.align 8
 	.globl ia32_syscall_table
-ia32_syscall_table:	
+ia32_syscall_table:
 	data8 sys32_ni_syscall	  /* 0	-  old "setup(" system call*/
 	data8 sys_exit
 	data8 sys32_fork
@@ -116,7 +132,7 @@
 	data8 sys_creat
 	data8 sys_link
 	data8 sys_unlink	  /* 10 */
-	data8 sys32_execve
+	data8 ia32_execve
 	data8 sys_chdir
 	data8 sys32_time
 	data8 sys_mknod
@@ -133,8 +149,8 @@
 	data8 sys32_ni_syscall /* sys_stime is not supported on IA64 */  /* 25 */
 	data8 sys32_ptrace
 	data8 sys32_alarm
-	data8 sys_pause
 	data8 sys32_ni_syscall
+	data8 sys_pause
 	data8 ia32_utime	  /* 30 */
 	data8 sys32_ni_syscall	  /* old stty syscall holder */
 	data8 sys32_ni_syscall	  /* old gtty syscall holder */
@@ -153,7 +169,7 @@
 	data8 sys_brk		  /* 45 */
 	data8 sys_setgid
 	data8 sys_getgid
-	data8 sys32_ni_syscall
+	data8 sys32_signal
 	data8 sys_geteuid
 	data8 sys_getegid	  /* 50 */
 	data8 sys_acct
@@ -227,7 +243,7 @@
 	data8 sys32_sigreturn
 	data8 sys_clone		  /* 120 */
 	data8 sys_setdomainname
-	data8 sys_newuname
+	data8 sys32_newuname
 	data8 sys_modify_ldt
 	data8 sys_adjtimex
 	data8 sys32_mprotect	  /* 125 */
@@ -249,12 +265,12 @@
 	data8 sys32_getdents
 	data8 sys32_select
 	data8 sys_flock
-	data8 sys_msync
+	data8 sys32_msync
 	data8 sys32_readv	  /* 145 */
 	data8 sys32_writev
 	data8 sys_getsid
 	data8 sys_fdatasync
-	data8 sys_sysctl
+	data8 sys32_sysctl
 	data8 sys_mlock		  /* 150 */
 	data8 sys_munlock
 	data8 sys_mlockall
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/ia32/ia32_support.c linux/arch/ia64/ia32/ia32_support.c
--- v2.4.3/linux/arch/ia64/ia32/ia32_support.c	Mon Oct  9 17:54:53 2000
+++ linux/arch/ia64/ia32/ia32_support.c	Thu Apr  5 12:51:47 2001
@@ -2,6 +2,7 @@
  * IA32 helper functions
  *
  * 06/16/00	A. Mallick	added csd/ssd/tssd for ia32 thread context
+ * 02/19/01	D. Mosberger	dropped tssd; it's not needed
  */
 
 #include <linux/kernel.h>
@@ -22,7 +23,7 @@
 void
 ia32_save_state (struct thread_struct *thread)
 {
-	unsigned long eflag, fsr, fcr, fir, fdr, csd, ssd, tssd;
+	unsigned long eflag, fsr, fcr, fir, fdr, csd, ssd;
 
 	asm ("mov %0=ar.eflag;"
 	     "mov %1=ar.fsr;"
@@ -31,9 +32,7 @@
 	     "mov %4=ar.fdr;"
 	     "mov %5=ar.csd;"
 	     "mov %6=ar.ssd;"
-	     "mov %7=ar.k1"
-	     : "=r"(eflag), "=r"(fsr), "=r"(fcr), "=r"(fir), "=r"(fdr),
-	       "=r"(csd), "=r"(ssd), "=r"(tssd));
+	     : "=r"(eflag), "=r"(fsr), "=r"(fcr), "=r"(fir), "=r"(fdr), "=r"(csd), "=r"(ssd));
 	thread->eflag = eflag;
 	thread->fsr = fsr;
 	thread->fcr = fcr;
@@ -41,14 +40,13 @@
 	thread->fdr = fdr;
 	thread->csd = csd;
 	thread->ssd = ssd;
-	thread->tssd = tssd;
 	asm ("mov ar.k0=%0 ;;" :: "r"(thread->old_iob));
 }
 
 void
 ia32_load_state (struct thread_struct *thread)
 {
-	unsigned long eflag, fsr, fcr, fir, fdr, csd, ssd, tssd;
+	unsigned long eflag, fsr, fcr, fir, fdr, csd, ssd;
 
 	eflag = thread->eflag;
 	fsr = thread->fsr;
@@ -57,7 +55,6 @@
 	fdr = thread->fdr;
 	csd = thread->csd;
 	ssd = thread->ssd;
-	tssd = thread->tssd;
 
 	asm volatile ("mov ar.eflag=%0;"
 		      "mov ar.fsr=%1;"
@@ -66,9 +63,7 @@
 		      "mov ar.fdr=%4;"
 		      "mov ar.csd=%5;"
 		      "mov ar.ssd=%6;"
-		      "mov ar.k1=%7"
-		      :: "r"(eflag), "r"(fsr), "r"(fcr), "r"(fir), "r"(fdr),
-		         "r"(csd), "r"(ssd), "r"(tssd));
+		      :: "r"(eflag), "r"(fsr), "r"(fcr), "r"(fir), "r"(fdr), "r"(csd), "r"(ssd));
 	asm ("mov %0=ar.k0 ;;" : "=r"(thread->old_iob));
 	asm ("mov ar.k0=%0 ;;" :: "r"(IA32_IOBASE));
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/ia32/sys_ia32.c linux/arch/ia64/ia32/sys_ia32.c
--- v2.4.3/linux/arch/ia64/ia32/sys_ia32.c	Mon Mar 19 12:35:10 2001
+++ linux/arch/ia64/ia32/sys_ia32.c	Thu Apr  5 12:51:47 2001
@@ -1,12 +1,12 @@
 /*
  * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Based on
- *             sys_sparc32 
+ *             sys_sparc32
  *
  * Copyright (C) 2000		VA Linux Co
  * Copyright (C) 2000		Don Dugger <n0ano@valinux.com>
- * Copyright (C) 1999 		Arun Sharma <arun.sharma@intel.com>
- * Copyright (C) 1997,1998 	Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 1997 		David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1999		Arun Sharma <arun.sharma@intel.com>
+ * Copyright (C) 1997,1998	Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1997		David S. Miller (davem@caip.rutgers.edu)
  * Copyright (C) 2000		Hewlett-Packard Co.
  * Copyright (C) 2000		David Mosberger-Tang <davidm@hpl.hp.com>
  *
@@ -16,9 +16,10 @@
 
 #include <linux/config.h>
 #include <linux/kernel.h>
+#include <linux/sysctl.h>
 #include <linux/sched.h>
-#include <linux/fs.h> 
-#include <linux/file.h> 
+#include <linux/fs.h>
+#include <linux/file.h>
 #include <linux/signal.h>
 #include <linux/utime.h>
 #include <linux/resource.h>
@@ -64,96 +65,87 @@
 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
 
 extern asmlinkage long sys_execve (char *, char **, char **, struct pt_regs *);
-extern asmlinkage long sys_munmap (unsigned long, size_t len);
 extern asmlinkage long sys_mprotect (unsigned long, size_t, unsigned long);
 
 static int
-nargs(unsigned int arg, char **ap)
+nargs (unsigned int arg, char **ap)
 {
 	int n, err, addr;
 
+	if (!arg)
+		return 0;
+
 	n = 0;
 	do {
 		err = get_user(addr, (int *)A(arg));
 		if (err)
 			return err;
-		if (ap) {		/* no access_ok needed, we allocated */
-			err = __put_user((char *)A(addr), ap++);
-			if (err)
-				return err;
-		}
+		if (ap)
+			*ap++ = (char *) A(addr);
 		arg += sizeof(unsigned int);
 		n++;
 	} while (addr);
-	return(n - 1);
+	return n - 1;
 }
 
 asmlinkage long
-sys32_execve(
-char *filename,
-unsigned int argv,
-unsigned int envp,
-int dummy3,
-int dummy4,
-int dummy5,
-int dummy6,
-int dummy7,
-int stack)
+sys32_execve (char *filename, unsigned int argv, unsigned int envp,
+	      int dummy3, int dummy4, int dummy5, int dummy6, int dummy7,
+	      int stack)
 {
 	struct pt_regs *regs = (struct pt_regs *)&stack;
+	unsigned long old_map_base, old_task_size;
 	char **av, **ae;
 	int na, ne, len;
 	long r;
 
 	na = nargs(argv, NULL);
 	if (na < 0)
-		return(na);
+		return na;
 	ne = nargs(envp, NULL);
 	if (ne < 0)
-		return(ne);
+		return ne;
 	len = (na + ne + 2) * sizeof(*av);
-	/*
-	 *  kmalloc won't work because the `sys_exec' code will attempt
-	 *  to do a `get_user' on the arg list and `get_user' will fail
-	 *  on a kernel address (simplifies `get_user').  Instead we
-	 *  do an mmap to get a user address.  Note that since a successful
-	 *  `execve' frees all current memory we only have to do an
-	 *  `munmap' if the `execve' failes.
-	 */
-	down_write(&current->mm->mmap_sem);
-
-	av = (char **) do_mmap_pgoff(0, 0UL, len, PROT_READ | PROT_WRITE,
-				     MAP_PRIVATE | MAP_ANONYMOUS, 0);
-
-	up_write(&current->mm->mmap_sem);
+	av = kmalloc(len, GFP_KERNEL);
+	if (!av)
+		return -ENOMEM;
 
-	if (IS_ERR(av))
-		return (long)av;
 	ae = av + na + 1;
-	r = __put_user(0, (av + na));
-	if (r)
-		goto out;
-	r = __put_user(0, (ae + ne));
-	if (r)
-		goto out;
+	av[na] = NULL;
+	ae[ne] = NULL;
+
 	r = nargs(argv, av);
 	if (r < 0)
 		goto out;
 	r = nargs(envp, ae);
 	if (r < 0)
 		goto out;
+
+	old_map_base  = current->thread.map_base;
+	old_task_size = current->thread.task_size;
+
+	/* we may be exec'ing a 64-bit process: reset map base & task-size: */
+	current->thread.map_base  = DEFAULT_MAP_BASE;
+	current->thread.task_size = DEFAULT_TASK_SIZE;
+
+	set_fs(KERNEL_DS);
 	r = sys_execve(filename, av, ae, regs);
-	if (r < 0)
-out:
-		sys_munmap((unsigned long) av, len);
-	return(r);
+	if (r < 0) {
+		/* oops, execve failed, switch back to old map base & task-size: */
+		current->thread.map_base  = old_map_base;
+		current->thread.task_size = old_task_size;
+		set_fs(USER_DS);	/* establish new task-size as the address-limit */
+	  out:
+		kfree(av);
+	}
+	return r;
 }
 
 static inline int
 putstat(struct stat32 *ubuf, struct stat *kbuf)
 {
 	int err;
-	
+
 	err = put_user (kbuf->st_dev, &ubuf->st_dev);
 	err |= __put_user (kbuf->st_ino, &ubuf->st_ino);
 	err |= __put_user (kbuf->st_mode, &ubuf->st_mode);
@@ -178,8 +170,8 @@
 	int ret;
 	struct stat s;
 	mm_segment_t old_fs = get_fs();
-	
-	set_fs (KERNEL_DS);
+
+	set_fs(KERNEL_DS);
 	ret = sys_newstat(filename, &s);
 	set_fs (old_fs);
 	if (putstat (statbuf, &s))
@@ -195,7 +187,7 @@
 	int ret;
 	struct stat s;
 	mm_segment_t old_fs = get_fs();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_newlstat(filename, &s);
 	set_fs (old_fs);
@@ -212,7 +204,7 @@
 	int ret;
 	struct stat s;
 	mm_segment_t old_fs = get_fs();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_newfstat(fd, &s);
 	set_fs (old_fs);
@@ -221,7 +213,6 @@
 	return ret;
 }
 
-#define ALIGN4K(a)	(((a) + 0xfff) & ~0xfff)
 #define OFFSET4K(a)	((a) & 0xfff)
 
 unsigned long
@@ -287,19 +278,19 @@
 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 	prot |= PROT_EXEC;
 
- 	if ((flags & MAP_FIXED) && ((addr & ~PAGE_MASK) || (offset & ~PAGE_MASK)))
- 		error = do_mmap_fake(file, addr, len, prot, flags, (loff_t)offset);
+	if ((flags & MAP_FIXED) && ((addr & ~PAGE_MASK) || (offset & ~PAGE_MASK)))
+		error = do_mmap_fake(file, addr, len, prot, flags, (loff_t)offset);
 	else {
- 		poff = offset & PAGE_MASK;
- 		len += offset - poff;
+		poff = offset & PAGE_MASK;
+		len += offset - poff;
+
+		down_write(&current->mm->mmap_sem);
+		error = do_mmap_pgoff(file, addr, len, prot, flags, poff >> PAGE_SHIFT);
+		up_write(&current->mm->mmap_sem);
 
- 		down_write(&current->mm->mmap_sem);
- 		error = do_mmap_pgoff(file, addr, len, prot, flags, poff >> PAGE_SHIFT);
-  		up_write(&current->mm->mmap_sem);
-
- 		if (!IS_ERR((void *) error))
- 			error += offset - poff;
- 	}
+		if (!IS_ERR((void *) error))
+			error += offset - poff;
+	}
 	return error;
 }
 
@@ -328,18 +319,46 @@
 	if (copy_from_user(&a, arg, sizeof(a)))
 		return -EFAULT;
 
+	if (PAGE_ALIGN(a.len) == 0)
+		return a.addr;
+
 	if (!(a.flags & MAP_ANONYMOUS)) {
 		file = fget(a.fd);
 		if (!file)
 			return -EBADF;
 	}
+#ifdef	CONFIG_IA64_PAGE_SIZE_4KB
+	if ((a.offset & ~PAGE_MASK) != 0)
+		return -EINVAL;
+
+	down_write(&current->mm->mmap_sem);
+	retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, a.offset >> PAGE_SHIFT);
+	up_write(&current->mm->mmap_sem);
+#else	// CONFIG_IA64_PAGE_SIZE_4KB
 	retval = ia32_do_mmap(file, a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
+#endif	// CONFIG_IA64_PAGE_SIZE_4KB
 	if (file)
 		fput(file);
 	return retval;
 }
 
 asmlinkage long
+sys32_mprotect(unsigned long start, size_t len, unsigned long prot)
+{
+
+#ifdef	CONFIG_IA64_PAGE_SIZE_4KB
+	return(sys_mprotect(start, len, prot));
+#else	// CONFIG_IA64_PAGE_SIZE_4KB
+	if (prot == 0)
+		return(0);
+	len += start & ~PAGE_MASK;
+	if ((start & ~PAGE_MASK) && (prot & PROT_WRITE))
+		prot |= PROT_EXEC;
+	return(sys_mprotect(start & PAGE_MASK, len & PAGE_MASK, prot));
+#endif	// CONFIG_IA64_PAGE_SIZE_4KB
+}
+
+asmlinkage long
 sys32_pipe(int *fd)
 {
 	int retval;
@@ -355,15 +374,17 @@
 }
 
 asmlinkage long
-sys32_mprotect(unsigned long start, size_t len, unsigned long prot)
+sys32_signal (int sig, unsigned int handler)
 {
+	struct k_sigaction new_sa, old_sa;
+	int ret;
 
-	if (prot == 0)
-		return(0);
-	len += start & ~PAGE_MASK;
-	if ((start & ~PAGE_MASK) && (prot & PROT_WRITE))
-		prot |= PROT_EXEC;
-	return(sys_mprotect(start & PAGE_MASK, len & PAGE_MASK, prot));
+	new_sa.sa.sa_handler = (__sighandler_t) A(handler);
+	new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK;
+
+	ret = do_sigaction(sig, &new_sa, &old_sa);
+
+	return ret ? ret : (unsigned long)old_sa.sa.sa_handler;
 }
 
 asmlinkage long
@@ -393,7 +414,7 @@
 				| (((long)set32.sig[1]) << 32);
 		}
 		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
-		
+
 		if (ret)
 			return -EFAULT;
 	}
@@ -436,7 +457,7 @@
 	sigset32_t s32;
 	int ret;
 	mm_segment_t old_fs = get_fs();
-	
+
 	if (set) {
 		if (copy_from_user (&s32, set, sizeof(sigset32_t)))
 			return -EFAULT;
@@ -449,7 +470,7 @@
 	}
 	set_fs (KERNEL_DS);
 	ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL,
-				 sigsetsize); 
+				 sigsetsize);
 	set_fs (old_fs);
 	if (ret) return ret;
 	if (oset) {
@@ -469,7 +490,7 @@
 put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
 {
 	int err;
-	
+
 	err = put_user (kbuf->f_type, &ubuf->f_type);
 	err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
 	err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
@@ -491,7 +512,7 @@
 	int ret;
 	struct statfs s;
 	mm_segment_t old_fs = get_fs();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_statfs((const char *)path, &s);
 	set_fs (old_fs);
@@ -508,7 +529,7 @@
 	int ret;
 	struct statfs s;
 	mm_segment_t old_fs = get_fs();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_fstatfs(fd, &s);
 	set_fs (old_fs);
@@ -534,7 +555,6 @@
 	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
 		(__get_user(o->tv_sec, &i->tv_sec) |
 		 __get_user(o->tv_usec, &i->tv_usec)));
-	return ENOSYS;
 }
 
 static inline long
@@ -553,18 +573,16 @@
 		 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
 		 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
 		 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
-	return ENOSYS;
 }
 
 static inline long
 put_it32(struct itimerval32 *o, struct itimerval *i)
 {
-	return (!access_ok(VERIFY_WRITE, i, sizeof(*i)) ||
+	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
 		(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
 		 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
 		 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
 		 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
-	return ENOSYS;
 }
 
 extern int do_getitimer(int which, struct itimerval *value);
@@ -605,7 +623,7 @@
 	return 0;
 
 }
-asmlinkage unsigned long 
+asmlinkage unsigned long
 sys32_alarm(unsigned int seconds)
 {
 	struct itimerval it_new, it_old;
@@ -638,7 +656,7 @@
 ia32_utime(char * filename, struct utimbuf_32 *times32)
 {
 	mm_segment_t old_fs = get_fs();
-	struct timeval tv[2];
+	struct timeval tv[2], *tvp;
 	long ret;
 
 	if (times32) {
@@ -647,15 +665,10 @@
 		get_user(tv[1].tv_sec, &times32->mtime);
 		tv[1].tv_usec = 0;
 		set_fs (KERNEL_DS);
-	} else {
-		set_fs (KERNEL_DS);
-		ret = sys_gettimeofday(&tv[0], 0);
-		if (ret < 0)
-			goto out;
-		tv[1] = tv[0];
-	}
-	ret = sys_utimes(filename, tv);
-  out:
+		tvp = tv;
+	} else
+		tvp = NULL;
+	ret = sys_utimes(filename, tvp);
 	set_fs (old_fs);
 	return ret;
 }
@@ -685,7 +698,7 @@
 	struct timeval ktv;
 	struct timezone ktz;
 
- 	if (tv) {
+	if (tv) {
 		if (get_tv32(&ktv, tv))
 			return -EFAULT;
 	}
@@ -872,7 +885,7 @@
 	/*
 	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
 	 * since we used fdset we need to allocate memory in units of
-	 * long-words. 
+	 * long-words.
 	 */
 	ret = -ENOMEM;
 	size = FDS_BYTES(n);
@@ -946,11 +959,11 @@
 }
 
 struct timespec32 {
-	int 	tv_sec;
+	int	tv_sec;
 	int	tv_nsec;
 };
 
-extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp); 
+extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
 
 asmlinkage long
 sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
@@ -958,7 +971,7 @@
 	struct timespec t;
 	int ret;
 	mm_segment_t old_fs = get_fs ();
-	
+
 	if (get_user (t.tv_sec, &rqtp->tv_sec) ||
 	    __get_user (t.tv_nsec, &rqtp->tv_nsec))
 		return -EFAULT;
@@ -967,7 +980,7 @@
 	set_fs (old_fs);
 	if (rmtp && ret == -EINTR) {
 		if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
-	    	    __put_user (t.tv_nsec, &rmtp->tv_nsec))
+		    __put_user (t.tv_nsec, &rmtp->tv_nsec))
 			return -EFAULT;
 	}
 	return ret;
@@ -1072,7 +1085,7 @@
 	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);
@@ -1092,7 +1105,7 @@
 	int ret;
 	mm_segment_t old_fs = get_fs ();
 
-	if (resource >= RLIM_NLIMITS) return -EINVAL;	
+	if (resource >= RLIM_NLIMITS) return -EINVAL;
 	if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
 	    __get_user (r.rlim_max, &rlim->rlim_max))
 		return -EFAULT;
@@ -1109,7 +1122,7 @@
 /*
  *  Declare the IA32 version of the msghdr
  */
- 
+
 struct msghdr32 {
 	unsigned int    msg_name;	/* Socket name			*/
 	int		msg_namelen;	/* Length of name		*/
@@ -1157,7 +1170,7 @@
 {
 	int size, err, ct;
 	struct iovec32 *iov32;
-	
+
 	if(m->msg_namelen)
 	{
 		if(mode==VERIFY_READ)
@@ -1166,7 +1179,7 @@
 			if(err<0)
 				goto out;
 		}
-		
+
 		m->msg_name = address;
 	} else
 		m->msg_name = NULL;
@@ -1195,7 +1208,7 @@
 }
 
 /* XXX This really belongs in some header file... -DaveM */
-#define MAX_SOCK_ADDR	128		/* 108 for Unix domain - 
+#define MAX_SOCK_ADDR	128		/* 108 for Unix domain -
 					   16 for IP, 16 for IPX,
 					   24 for IPv6,
 					   about 80 for AX.25 */
@@ -1215,13 +1228,13 @@
 	unsigned char *ctl_buf = ctl;
 	struct msghdr msg_sys;
 	int err, ctl_len, iov_size, total_len;
-	
+
 	err = -EFAULT;
 	if (shape_msg(&msg_sys, msg))
-		goto out; 
+		goto out;
 
 	sock = sockfd_lookup(fd, &err);
-	if (!sock) 
+	if (!sock)
 		goto out;
 
 	/* do not move before msg_sys is valid */
@@ -1240,7 +1253,7 @@
 
 	/* This will also move the address data into kernel space */
 	err = verify_iovec32(&msg_sys, iov, address, VERIFY_READ);
-	if (err < 0) 
+	if (err < 0)
 		goto out_freeiov;
 	total_len = err;
 
@@ -1248,14 +1261,14 @@
 
 	if (msg_sys.msg_controllen > INT_MAX)
 		goto out_freeiov;
-	ctl_len = msg_sys.msg_controllen; 
-	if (ctl_len) 
+	ctl_len = msg_sys.msg_controllen;
+	if (ctl_len)
 	{
 		if (ctl_len > sizeof(ctl))
 		{
 			err = -ENOBUFS;
 			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
-			if (ctl_buf == NULL) 
+			if (ctl_buf == NULL)
 				goto out_freeiov;
 		}
 		err = -EFAULT;
@@ -1270,14 +1283,14 @@
 	err = sock_sendmsg(sock, &msg_sys, total_len);
 
 out_freectl:
-	if (ctl_buf != ctl)    
+	if (ctl_buf != ctl)
 		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
 out_freeiov:
 	if (iov != iovstack)
 		sock_kfree_s(sock->sk, iov, iov_size);
 out_put:
 	sockfd_put(sock);
-out:       
+out:
 	return err;
 }
 
@@ -1301,7 +1314,7 @@
 	/* user mode address pointers */
 	struct sockaddr *uaddr;
 	int *uaddr_len;
-	
+
 	err=-EFAULT;
 	if (shape_msg(&msg_sys, msg))
 		goto out;
@@ -1313,7 +1326,7 @@
 	err = -EINVAL;
 	if (msg_sys.msg_iovlen > UIO_MAXIOV)
 		goto out_put;
-	
+
 	/* Check whether to allocate the iovec area*/
 	err = -ENOMEM;
 	iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
@@ -1327,7 +1340,7 @@
 	 *	Save the user-mode address (verify_iovec will change the
 	 *	kernel msghdr to use the kernel address space)
 	 */
-	 
+
 	uaddr = msg_sys.msg_name;
 	uaddr_len = &msg->msg_namelen;
 	err = verify_iovec32(&msg_sys, iov, addr, VERIFY_WRITE);
@@ -1337,7 +1350,7 @@
 
 	cmsg_ptr = (unsigned long)msg_sys.msg_control;
 	msg_sys.msg_flags = 0;
-	
+
 	if (sock->file->f_flags & O_NONBLOCK)
 		flags |= MSG_DONTWAIT;
 	err = sock_recvmsg(sock, &msg_sys, total_len, flags);
@@ -1353,7 +1366,7 @@
 	err = __put_user(msg_sys.msg_flags, &msg->msg_flags);
 	if (err)
 		goto out_freeiov;
-	err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr, 
+	err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr,
 							 &msg->msg_controllen);
 	if (err)
 		goto out_freeiov;
@@ -1371,15 +1384,15 @@
 /* Argument list sizes for sys_socketcall */
 #define AL(x) ((x) * sizeof(u32))
 static unsigned char nas[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
-                                AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
-                                AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
+				AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
+				AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
 #undef AL
 
 extern asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
 extern asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr,
 				  int addrlen);
 extern asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr,
-				 int *upeer_addrlen); 
+				 int *upeer_addrlen);
 extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr,
 				      int *usockaddr_len);
 extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr,
@@ -1406,15 +1419,15 @@
 	int ret;
 	u32 a[6];
 	u32 a0,a1;
-				 
+
 	if (call<SYS_SOCKET||call>SYS_RECVMSG)
 		return -EINVAL;
 	if (copy_from_user(a, args, nas[call]))
 		return -EFAULT;
 	a0=a[0];
 	a1=a[1];
-	
-	switch(call) 
+
+	switch(call)
 	{
 		case SYS_SOCKET:
 			ret = sys_socket(a0, a1, a[2]);
@@ -1490,52 +1503,52 @@
 
 struct ipc_perm32
 {
-	key_t    	  key;
-        __kernel_uid_t32  uid;
-        __kernel_gid_t32  gid;
-        __kernel_uid_t32  cuid;
-        __kernel_gid_t32  cgid;
-        __kernel_mode_t32 mode;
-        unsigned short  seq;
+	key_t	  key;
+	__kernel_uid_t32  uid;
+	__kernel_gid_t32  gid;
+	__kernel_uid_t32  cuid;
+	__kernel_gid_t32  cgid;
+	__kernel_mode_t32 mode;
+	unsigned short  seq;
 };
 
 struct semid_ds32 {
-        struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
-        __kernel_time_t32 sem_otime;              /* last semop time */
-        __kernel_time_t32 sem_ctime;              /* last change time */
-        u32 sem_base;              /* ptr to first semaphore in array */
-        u32 sem_pending;          /* pending operations to be processed */
-        u32 sem_pending_last;    /* last pending operation */
-        u32 undo;                  /* undo requests on this array */
-        unsigned short  sem_nsems;              /* no. of semaphores in array */
+	struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
+	__kernel_time_t32 sem_otime;              /* last semop time */
+	__kernel_time_t32 sem_ctime;              /* last change time */
+	u32 sem_base;              /* ptr to first semaphore in array */
+	u32 sem_pending;          /* pending operations to be processed */
+	u32 sem_pending_last;    /* last pending operation */
+	u32 undo;                  /* undo requests on this array */
+	unsigned short  sem_nsems;              /* no. of semaphores in array */
 };
 
 struct msqid_ds32
 {
-        struct ipc_perm32 msg_perm;
-        u32 msg_first;
-        u32 msg_last;
-        __kernel_time_t32 msg_stime;
-        __kernel_time_t32 msg_rtime;
-        __kernel_time_t32 msg_ctime;
-        u32 wwait;
-        u32 rwait;
-        unsigned short msg_cbytes;
-        unsigned short msg_qnum;  
-        unsigned short msg_qbytes;
-        __kernel_ipc_pid_t32 msg_lspid;
-        __kernel_ipc_pid_t32 msg_lrpid;
+	struct ipc_perm32 msg_perm;
+	u32 msg_first;
+	u32 msg_last;
+	__kernel_time_t32 msg_stime;
+	__kernel_time_t32 msg_rtime;
+	__kernel_time_t32 msg_ctime;
+	u32 wwait;
+	u32 rwait;
+	unsigned short msg_cbytes;
+	unsigned short msg_qnum;
+	unsigned short msg_qbytes;
+	__kernel_ipc_pid_t32 msg_lspid;
+	__kernel_ipc_pid_t32 msg_lrpid;
 };
 
 struct shmid_ds32 {
-        struct ipc_perm32       shm_perm;
-        int                     shm_segsz;
-        __kernel_time_t32       shm_atime;
-        __kernel_time_t32       shm_dtime;
-        __kernel_time_t32       shm_ctime;
-        __kernel_ipc_pid_t32    shm_cpid; 
-        __kernel_ipc_pid_t32    shm_lpid; 
-        unsigned short          shm_nattch;
+	struct ipc_perm32       shm_perm;
+	int                     shm_segsz;
+	__kernel_time_t32       shm_atime;
+	__kernel_time_t32       shm_dtime;
+	__kernel_time_t32       shm_ctime;
+	__kernel_ipc_pid_t32    shm_cpid;
+	__kernel_ipc_pid_t32    shm_lpid;
+	unsigned short          shm_nattch;
 };
 
 #define IPCOP_MASK(__x)	(1UL << (__x))
@@ -1876,7 +1889,7 @@
 		err = do_sys32_shmat (first, second, third,
 				      version, (void *)AA(ptr));
 		break;
-	case SHMDT: 
+	case SHMDT:
 		err = sys_shmdt ((char *)AA(ptr));
 		break;
 	case SHMGET:
@@ -1902,7 +1915,7 @@
 {
 	int i;
 
-	/* SMP: This is fairly trivial. We grab CURRENT_TIME and 
+	/* SMP: This is fairly trivial. We grab CURRENT_TIME and
 	   stuff it to user space. No side effects */
 	i = CURRENT_TIME;
 	if (tloc) {
@@ -1913,29 +1926,29 @@
 }
 
 struct rusage32 {
-        struct timeval32 ru_utime;
-        struct timeval32 ru_stime;
-        int    ru_maxrss;
-        int    ru_ixrss;
-        int    ru_idrss;
-        int    ru_isrss;
-        int    ru_minflt;
-        int    ru_majflt;
-        int    ru_nswap;
-        int    ru_inblock;
-        int    ru_oublock;
-        int    ru_msgsnd; 
-        int    ru_msgrcv; 
-        int    ru_nsignals;
-        int    ru_nvcsw;
-        int    ru_nivcsw;
+	struct timeval32 ru_utime;
+	struct timeval32 ru_stime;
+	int    ru_maxrss;
+	int    ru_ixrss;
+	int    ru_idrss;
+	int    ru_isrss;
+	int    ru_minflt;
+	int    ru_majflt;
+	int    ru_nswap;
+	int    ru_inblock;
+	int    ru_oublock;
+	int    ru_msgsnd;
+	int    ru_msgrcv;
+	int    ru_nsignals;
+	int    ru_nvcsw;
+	int    ru_nivcsw;
 };
 
 static int
 put_rusage (struct rusage32 *ru, struct rusage *r)
 {
 	int err;
-	
+
 	err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
 	err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
 	err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
@@ -1968,7 +1981,7 @@
 		int ret;
 		unsigned int status;
 		mm_segment_t old_fs = get_fs();
-		
+
 		set_fs (KERNEL_DS);
 		ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
 		set_fs (old_fs);
@@ -1995,7 +2008,7 @@
 	struct rusage r;
 	int ret;
 	mm_segment_t old_fs = get_fs();
-		
+
 	set_fs (KERNEL_DS);
 	ret = sys_getrusage(who, &r);
 	set_fs (old_fs);
@@ -2009,7 +2022,7 @@
 	__kernel_clock_t32 tms_cutime;
 	__kernel_clock_t32 tms_cstime;
 };
-                                
+
 extern asmlinkage long sys_times(struct tms * tbuf);
 
 asmlinkage long
@@ -2019,7 +2032,7 @@
 	long ret;
 	mm_segment_t old_fs = get_fs ();
 	int err;
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_times(tbuf ? &t : NULL);
 	set_fs (old_fs);
@@ -2069,7 +2082,7 @@
 #define PT_GS	10
 #define PT_ORIG_EAX 11
 #define PT_EIP	12
-#define PT_CS 	13
+#define PT_CS	13
 #define PT_EFL	14
 #define PT_UESP	15
 #define PT_SS	16
@@ -2385,7 +2398,7 @@
 		break;
 
 	      case IA32_PTRACE_GETREGS:
-	  	if (!access_ok(VERIFY_WRITE, (int *)data, 17*sizeof(int))) {
+		if (!access_ok(VERIFY_WRITE, (int *)data, 17*sizeof(int))) {
 			ret = -EIO;
 			break;
 		}
@@ -2399,7 +2412,7 @@
 	      case IA32_PTRACE_SETREGS:
 	      {
 		unsigned int tmp;
-	  	if (!access_ok(VERIFY_READ, (int *)data, 17*sizeof(int))) {
+		if (!access_ok(VERIFY_READ, (int *)data, 17*sizeof(int))) {
 			ret = -EIO;
 			break;
 		}
@@ -2444,7 +2457,7 @@
 get_flock32(struct flock *kfl, struct flock32 *ufl)
 {
 	int err;
-	
+
 	err = get_user(kfl->l_type, &ufl->l_type);
 	err |= __get_user(kfl->l_whence, &ufl->l_whence);
 	err |= __get_user(kfl->l_start, &ufl->l_start);
@@ -2457,7 +2470,7 @@
 put_flock32(struct flock *kfl, struct flock32 *ufl)
 {
 	int err;
-	
+
 	err = __put_user(kfl->l_type, &ufl->l_type);
 	err |= __put_user(kfl->l_whence, &ufl->l_whence);
 	err |= __put_user(kfl->l_start, &ufl->l_start);
@@ -2480,7 +2493,7 @@
 	case F_GETLK:
 	case F_SETLK:
 	case F_SETLKW:
-		if(cmd != F_GETLK && get_flock32(&f, (struct flock32 *)((long)arg)))
+		if(get_flock32(&f, (struct flock32 *)((long)arg)))
 			return -EFAULT;
 		old_fs = get_fs();
 		set_fs(KERNEL_DS);
@@ -2501,27 +2514,27 @@
 asmlinkage long
 sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
 {
-        struct k_sigaction new_ka, old_ka;
-        int ret;
+	struct k_sigaction new_ka, old_ka;
+	int ret;
 
-        if (act) {
+	if (act) {
 		old_sigset32_t mask;
-		
+
 		ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
 		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
 		ret |= __get_user(mask, &act->sa_mask);
 		if (ret)
 			return ret;
 		siginitset(&new_ka.sa.sa_mask, mask);
-        }
+	}
 
-        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 
 	if (!ret && oact) {
 		ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
 		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 		ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
-        }
+	}
 
 	return ret;
 }
@@ -2658,6 +2671,85 @@
 	return -ERESTARTNOHAND;
 }
 
+asmlinkage long sys_msync(unsigned long start, size_t len, int flags);
+
+asmlinkage int
+sys32_msync(unsigned int start, unsigned int len, int flags)
+{
+	unsigned int addr;
+
+	if (OFFSET4K(start))
+		return -EINVAL;
+	addr = start & PAGE_MASK;
+	return(sys_msync(addr, len + (start - addr), flags));
+}
+
+struct sysctl_ia32 {
+	unsigned int	name;
+	int		nlen;
+	unsigned int	oldval;
+	unsigned int	oldlenp;
+	unsigned int	newval;
+	unsigned int	newlen;
+	unsigned int	__unused[4];
+};
+
+extern asmlinkage long sys_sysctl(struct __sysctl_args *args);
+
+asmlinkage long
+sys32_sysctl(struct sysctl_ia32 *args32)
+{
+	struct sysctl_ia32 a32;
+	mm_segment_t old_fs = get_fs ();
+	void *oldvalp, *newvalp;
+	size_t oldlen;
+	int *namep;
+	long ret;
+
+	if (copy_from_user(&a32, args32, sizeof (a32)))
+		return -EFAULT;
+
+	/*
+	 * We need to pre-validate these because we have to disable address checking
+	 * before calling do_sysctl() because of OLDLEN but we can't run the risk of the
+	 * user specifying bad addresses here.  Well, since we're dealing with 32 bit
+	 * addresses, we KNOW that access_ok() will always succeed, so this is an
+	 * expensive NOP, but so what...
+	 */
+	namep = (int *) A(a32.name);
+	oldvalp = (void *) A(a32.oldval);
+	newvalp = (void *) A(a32.newval);
+
+	if ((oldvalp && get_user(oldlen, (int *) A(a32.oldlenp)))
+	    || !access_ok(VERIFY_WRITE, namep, 0)
+	    || !access_ok(VERIFY_WRITE, oldvalp, 0)
+	    || !access_ok(VERIFY_WRITE, newvalp, 0))
+		return -EFAULT;
+
+	set_fs(KERNEL_DS);
+	lock_kernel();
+	ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen);
+	unlock_kernel();
+	set_fs(old_fs);
+
+	if (oldvalp && put_user (oldlen, (int *) A(a32.oldlenp)))
+		return -EFAULT;
+
+	return ret;
+}
+
+asmlinkage long
+sys32_newuname(struct new_utsname * name)
+{
+	extern asmlinkage long sys_newuname(struct new_utsname * name);
+	int ret = sys_newuname(name);
+
+	if (!ret)
+		if (copy_to_user(name->machine, "i686\0\0\0", 8))
+			ret = -EFAULT;
+	return ret;
+}
+
 #ifdef	NOTYET  /* UNTESTED FOR IA64 FROM HERE DOWN */
 
 /* In order to reduce some races, while at the same time doing additional
@@ -2721,7 +2813,7 @@
     __kernel_time_t32 dqb_btime;
     __kernel_time_t32 dqb_itime;
 };
-                                
+
 extern asmlinkage long sys_quotactl(int cmd, const char *special, int id,
 				   caddr_t addr);
 
@@ -2733,7 +2825,7 @@
 	struct dqblk d;
 	mm_segment_t old_fs;
 	char *spec;
-	
+
 	switch (cmds) {
 	case Q_GETQUOTA:
 		break;
@@ -2782,7 +2874,7 @@
 	mm_segment_t old_fs;
 	int ret;
 	char *filenam;
-	
+
 	if (!times)
 		return sys_utime(filename, NULL);
 	if (get_user (t.actime, &times->actime) ||
@@ -2792,7 +2884,7 @@
 	ret = PTR_ERR(filenam);
 	if (!IS_ERR(filenam)) {
 		old_fs = get_fs();
-		set_fs (KERNEL_DS); 
+		set_fs (KERNEL_DS);
 		ret = sys_utime(filenam, &t);
 		set_fs (old_fs);
 		putname (filenam);
@@ -2869,18 +2961,18 @@
 }
 
 struct ncp_mount_data32 {
-        int version;
-        unsigned int ncp_fd;
-        __kernel_uid_t32 mounted_uid;
-        __kernel_pid_t32 wdog_pid;
-        unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
-        unsigned int time_out;
-        unsigned int retry_count;
-        unsigned int flags;
-        __kernel_uid_t32 uid;
-        __kernel_gid_t32 gid;
-        __kernel_mode_t32 file_mode;
-        __kernel_mode_t32 dir_mode;
+	int version;
+	unsigned int ncp_fd;
+	__kernel_uid_t32 mounted_uid;
+	__kernel_pid_t32 wdog_pid;
+	unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
+	unsigned int time_out;
+	unsigned int retry_count;
+	unsigned int flags;
+	__kernel_uid_t32 uid;
+	__kernel_gid_t32 gid;
+	__kernel_mode_t32 file_mode;
+	__kernel_mode_t32 dir_mode;
 };
 
 static void *
@@ -2901,12 +2993,12 @@
 }
 
 struct smb_mount_data32 {
-        int version;
-        __kernel_uid_t32 mounted_uid;
-        __kernel_uid_t32 uid;
-        __kernel_gid_t32 gid;
-        __kernel_mode_t32 file_mode;
-        __kernel_mode_t32 dir_mode;
+	int version;
+	__kernel_uid_t32 mounted_uid;
+	__kernel_uid_t32 uid;
+	__kernel_gid_t32 gid;
+	__kernel_mode_t32 file_mode;
+	__kernel_mode_t32 dir_mode;
 };
 
 static void *
@@ -3020,16 +3112,16 @@
 }
 
 struct sysinfo32 {
-        s32 uptime;
-        u32 loads[3];
-        u32 totalram;
-        u32 freeram;
-        u32 sharedram;
-        u32 bufferram;
-        u32 totalswap;
-        u32 freeswap;
-        unsigned short procs;
-        char _f[22];
+	s32 uptime;
+	u32 loads[3];
+	u32 totalram;
+	u32 freeram;
+	u32 sharedram;
+	u32 bufferram;
+	u32 totalswap;
+	u32 freeswap;
+	unsigned short procs;
+	char _f[22];
 };
 
 extern asmlinkage long sys_sysinfo(struct sysinfo *info);
@@ -3040,7 +3132,7 @@
 	struct sysinfo s;
 	int ret, err;
 	mm_segment_t old_fs = get_fs ();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_sysinfo(&s);
 	set_fs (old_fs);
@@ -3059,7 +3151,7 @@
 		return -EFAULT;
 	return ret;
 }
-                
+
 extern asmlinkage long sys_sched_rr_get_interval(pid_t pid,
 						struct timespec *interval);
 
@@ -3069,7 +3161,7 @@
 	struct timespec t;
 	int ret;
 	mm_segment_t old_fs = get_fs ();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_sched_rr_get_interval(pid, &t);
 	set_fs (old_fs);
@@ -3088,7 +3180,7 @@
 	old_sigset_t s;
 	int ret;
 	mm_segment_t old_fs = get_fs();
-	
+
 	if (set && get_user (s, set)) return -EFAULT;
 	set_fs (KERNEL_DS);
 	ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
@@ -3106,7 +3198,7 @@
 	old_sigset_t s;
 	int ret;
 	mm_segment_t old_fs = get_fs();
-		
+
 	set_fs (KERNEL_DS);
 	ret = sys_sigpending(&s);
 	set_fs (old_fs);
@@ -3123,7 +3215,7 @@
 	sigset_t32 s32;
 	int ret;
 	mm_segment_t old_fs = get_fs();
-		
+
 	set_fs (KERNEL_DS);
 	ret = sys_rt_sigpending(&s, sigsetsize);
 	set_fs (old_fs);
@@ -3234,7 +3326,7 @@
 	mm_segment_t old_fs = get_fs();
 	siginfo_t info;
 	siginfo_t32 info32;
-		
+
 	if (copy_from_user (&s32, uthese, sizeof(sigset_t32)))
 		return -EFAULT;
 	switch (_NSIG_WORDS) {
@@ -3270,7 +3362,7 @@
 	siginfo_t32 info32;
 	int ret;
 	mm_segment_t old_fs = get_fs();
-	
+
 	if (copy_from_user (&info32, uinfo, sizeof(siginfo_t32)))
 		return -EFAULT;
 	/* XXX: Is this correct? */
@@ -3315,7 +3407,7 @@
 	uid_t a, b, c;
 	int ret;
 	mm_segment_t old_fs = get_fs();
-		
+
 	set_fs (KERNEL_DS);
 	ret = sys_getresuid(&a, &b, &c);
 	set_fs (old_fs);
@@ -3354,12 +3446,12 @@
 
 asmlinkage long
 sys32_getresgid(__kernel_gid_t32 *rgid, __kernel_gid_t32 *egid,
-		__kernel_gid_t32 *sgid) 
+		__kernel_gid_t32 *sgid)
 {
 	gid_t a, b, c;
 	int ret;
 	mm_segment_t old_fs = get_fs();
-		
+
 	set_fs (KERNEL_DS);
 	ret = sys_getresgid(&a, &b, &c);
 	set_fs (old_fs);
@@ -3379,7 +3471,7 @@
 	gid_t gl[NGROUPS];
 	int ret, i;
 	mm_segment_t old_fs = get_fs ();
-	
+
 	set_fs (KERNEL_DS);
 	ret = sys_getgroups(gidsetsize, gl);
 	set_fs (old_fs);
@@ -3398,13 +3490,13 @@
 	gid_t gl[NGROUPS];
 	int ret, i;
 	mm_segment_t old_fs = get_fs ();
-	
+
 	if ((unsigned) gidsetsize > NGROUPS)
 		return -EINVAL;
 	for (i = 0; i < gidsetsize; i++, grouplist++)
 		if (__get_user (gl[i], grouplist))
 			return -EFAULT;
-        set_fs (KERNEL_DS);
+	set_fs (KERNEL_DS);
 	ret = sys_setgroups(gidsetsize, gl);
 	set_fs (old_fs);
 	return ret;
@@ -3442,26 +3534,26 @@
 }
 
 struct msghdr32 {
-        u32               msg_name;
-        int               msg_namelen;
-        u32               msg_iov;
-        __kernel_size_t32 msg_iovlen;
-        u32               msg_control;
-        __kernel_size_t32 msg_controllen;
-        unsigned          msg_flags;
+	u32               msg_name;
+	int               msg_namelen;
+	u32               msg_iov;
+	__kernel_size_t32 msg_iovlen;
+	u32               msg_control;
+	__kernel_size_t32 msg_controllen;
+	unsigned          msg_flags;
 };
 
 struct cmsghdr32 {
-        __kernel_size_t32 cmsg_len;
-        int               cmsg_level;
-        int               cmsg_type;
+	__kernel_size_t32 cmsg_len;
+	int               cmsg_level;
+	int               cmsg_type;
 };
 
 /* Bleech... */
 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) \
-        __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
+	__cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
 #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) \
-        cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
+	cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
 
 #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
 
@@ -3479,7 +3571,7 @@
 
 __inline__ struct cmsghdr32 *
 __cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
-		struct cmsghdr32 *__cmsg, int __cmsg_len) 
+		struct cmsghdr32 *__cmsg, int __cmsg_len)
 {
 	struct cmsghdr32 * __ptr;
 
@@ -3541,7 +3633,7 @@
 	err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
 	err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
 	err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
-	
+
 	return err;
 }
 
@@ -3588,7 +3680,7 @@
  */
 static int
 cmsghdr_from_user32_to_kern(struct msghdr *kmsg, unsigned char *stackbuf,
-			    int stackbuf_size) 
+			    int stackbuf_size)
 {
 	struct cmsghdr32 *ucmsg;
 	struct cmsghdr *kcmsg, *kcmsg_base;
@@ -3812,7 +3904,7 @@
 		kcmsg32->cmsg_len = clen32;
 
 		ucmsg = (struct cmsghdr *) (((char *)ucmsg) +
-					    CMSG_ALIGN(clen64)); 
+					    CMSG_ALIGN(clen64));
 		wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
 	}
 
@@ -3985,7 +4077,7 @@
 }
 
 extern asmlinkage long sys_init_module(const char *name_user,
-				      struct module *mod_user); 
+				      struct module *mod_user);
 
 /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
  * module structure, even if from 32bit modutils... Why to pollute kernel... :))
@@ -4275,7 +4367,7 @@
 
 asmlinkage long
 sys32_query_module(char *name_user, int which, char *buf,
-		   __kernel_size_t32 bufsize, u32 ret) 
+		   __kernel_size_t32 bufsize, u32 ret)
 {
 	struct module *mod;
 	int err;
@@ -4340,7 +4432,7 @@
 	u32 value;
 	char name[60];
 };
-		 
+
 extern asmlinkage long sys_get_kernel_syms(struct kernel_sym *table);
 
 asmlinkage long
@@ -4349,7 +4441,7 @@
 	int len, i;
 	struct kernel_sym *tbl;
 	mm_segment_t old_fs;
-	
+
 	len = sys_get_kernel_syms(NULL);
 	if (!table) return len;
 	tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
@@ -4477,7 +4569,7 @@
 nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
 {
 	int err;
-	
+
 	err = __get_user(karg->ca_version, &arg32->ca32_version);
 	err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
 	err |= __get_user(karg->ca_svc.svc_nthreads,
@@ -4489,7 +4581,7 @@
 nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
 {
 	int err;
-	
+
 	err = __get_user(karg->ca_version, &arg32->ca32_version);
 	err |= copy_from_user(&karg->ca_client.cl_ident[0],
 			  &arg32->ca32_client.cl32_ident[0],
@@ -4513,7 +4605,7 @@
 nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
 {
 	int err;
-	
+
 	err = __get_user(karg->ca_version, &arg32->ca32_version);
 	err |= copy_from_user(&karg->ca_export.ex_client[0],
 			  &arg32->ca32_export.ex32_client[0],
@@ -4589,7 +4681,7 @@
 nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
 {
 	int err;
-	
+
 	err = __get_user(karg->ca_version, &arg32->ca32_version);
 	err |= copy_from_user(&karg->ca_getfh.gf_addr,
 			  &arg32->ca32_getfh.gf32_addr,
@@ -4607,7 +4699,7 @@
 nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
 {
 	int err;
-	
+
 	err = copy_to_user(&res32->cr32_getfh,
 			&kres->cr_getfh,
 			sizeof(res32->cr32_getfh));
@@ -4772,19 +4864,6 @@
 }
 
 
-extern asmlinkage long sys_newuname(struct new_utsname * name);
-
-asmlinkage long
-sys32_newuname(struct new_utsname * name)
-{
-	int ret = sys_newuname(name);
-	
-	if (current->personality == PER_LINUX32 && !ret) {
-		ret = copy_to_user(name->machine, "sparc\0\0", 8);
-	}
-	return ret;
-}
-
 extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
 				    size_t count, loff_t pos);
 
@@ -4825,7 +4904,7 @@
 }
 
 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset,
-				       size_t count); 
+				       size_t count);
 
 asmlinkage long
 sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
@@ -4833,17 +4912,17 @@
 	mm_segment_t old_fs = get_fs();
 	int ret;
 	off_t of;
-	
+
 	if (offset && get_user(of, offset))
 		return -EFAULT;
-		
+
 	set_fs(KERNEL_DS);
 	ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
 	set_fs(old_fs);
-	
+
 	if (!ret && offset && put_user(of, offset))
 		return -EFAULT;
-		
+
 	return ret;
 }
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/Makefile linux/arch/ia64/kernel/Makefile
--- v2.4.3/linux/arch/ia64/kernel/Makefile	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/Makefile	Thu Apr  5 12:51:47 2001
@@ -11,19 +11,18 @@
 
 O_TARGET := kernel.o
 
-obj-y := acpi.o entry.o gate.o efi.o efi_stub.o irq.o irq_ia64.o irq_sapic.o ivt.o \
+export-objs := ia64_ksyms.o
+
+obj-y := acpi.o entry.o gate.o efi.o efi_stub.o ia64_ksyms.o irq.o irq_ia64.o irq_sapic.o ivt.o \
 	 machvec.o pal.o process.o perfmon.o ptrace.o sal.o semaphore.o setup.o	\
 	 signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o
 obj-$(CONFIG_IA64_GENERIC) += machvec.o iosapic.o
 obj-$(CONFIG_IA64_DIG) += iosapic.o
 obj-$(CONFIG_IA64_PALINFO) += palinfo.o
+obj-$(CONFIG_IA64_EFIVARS) += efivars.o
 obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_SMP) += smp.o smpboot.o
 obj-$(CONFIG_IA64_MCA) += mca.o mca_asm.o
 obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o
-
-export-objs := ia64_ksyms.o
-
-clean::
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/acpi.c linux/arch/ia64/kernel/acpi.c
--- v2.4.3/linux/arch/ia64/kernel/acpi.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/acpi.c	Thu Apr  5 12:51:47 2001
@@ -1,9 +1,9 @@
 /*
- * Advanced Configuration and Power Interface 
+ * Advanced Configuration and Power Interface
  *
- * Based on 'ACPI Specification 1.0b' February 2, 1999 and 
+ * Based on 'ACPI Specification 1.0b' February 2, 1999 and
  * 'IA-64 Extensions to ACPI Specification' Revision 0.6
- * 
+ *
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
  * Copyright (C) 2000 Hewlett-Packard Co.
@@ -111,15 +111,15 @@
  * Identify usable CPU's and remember them for SMP bringup later.
  */
 static void __init
-acpi20_lsapic (char *p) 
+acpi20_lsapic (char *p)
 {
 	int add = 1;
 
 	acpi20_entry_lsapic_t *lsapic = (acpi20_entry_lsapic_t *) p;
-	printk("      CPU %d (%.04x:%.04x): ", total_cpus, lsapic->eid, lsapic->id);
+	printk("      CPU %.04x:%.04x: ", lsapic->eid, lsapic->id);
 
 	if ((lsapic->flags & LSAPIC_ENABLED) == 0) {
-		printk("Disabled.\n");
+		printk("disabled.\n");
 		add = 0;
 	}
 
@@ -127,11 +127,14 @@
 	smp_boot_data.cpu_phys_id[total_cpus] = -1;
 #endif
 	if (add) {
-		printk("Available.\n");
 		available_cpus++;
+		printk("available");
 #ifdef CONFIG_SMP
 		smp_boot_data.cpu_phys_id[total_cpus] = (lsapic->id << 8) | lsapic->eid;
-#endif /* CONFIG_SMP */
+		if (hard_smp_processor_id() == smp_boot_data.cpu_phys_id[total_cpus])
+			printk(" (BSP)");
+#endif
+		printk(".\n");
 	}
 	total_cpus++;
 }
@@ -199,7 +202,7 @@
 			printk("ACPI 2.0 MADT: LOCAL SAPIC\n");
 			acpi20_lsapic(p);
 			break;
-	
+
 		case ACPI20_ENTRY_IO_SAPIC:
 			iosapic = (acpi_entry_iosapic_t *) p;
 			if (iosapic_init)
@@ -233,7 +236,7 @@
 	end = p + (madt->header.length - sizeof(acpi_madt_t));
 
 	while (p < end) {
-		
+
 		switch (*p) {
 		case ACPI20_ENTRY_INT_SRC_OVERRIDE:
 			printk("ACPI 2.0 MADT: INT SOURCE Override\n");
@@ -251,7 +254,7 @@
 		available_cpus, total_cpus);
 }
 
-int __init 
+int __init
 acpi20_parse (acpi20_rsdp_t *rsdp20)
 {
 	acpi_xsdt_t *xsdt;
@@ -311,12 +314,12 @@
 		printk("ACPI: Found 0 CPUS; assuming 1\n");
 		available_cpus = 1; /* We've got at least one of these, no? */
 	}
-	smp_boot_data.cpu_count = available_cpus;
+	smp_boot_data.cpu_count = total_cpus;
 #endif
 	return 1;
 }
 /*
- * ACPI 1.0b with 0.71 IA64 extensions functions; should be removed once all 
+ * ACPI 1.0b with 0.71 IA64 extensions functions; should be removed once all
  * platforms start supporting ACPI 2.0
  */
 
@@ -324,13 +327,13 @@
  * Identify usable CPU's and remember them for SMP bringup later.
  */
 static void __init
-acpi_lsapic (char *p) 
+acpi_lsapic (char *p)
 {
 	int add = 1;
 
 	acpi_entry_lsapic_t *lsapic = (acpi_entry_lsapic_t *) p;
 
-	if ((lsapic->flags & LSAPIC_PRESENT) == 0) 
+	if ((lsapic->flags & LSAPIC_PRESENT) == 0)
 		return;
 
 	printk("      CPU %d (%.04x:%.04x): ", total_cpus, lsapic->eid, lsapic->id);
@@ -388,7 +391,7 @@
 		      case ACPI_ENTRY_LOCAL_SAPIC:
 			acpi_lsapic(p);
 			break;
-	
+
 		      case ACPI_ENTRY_IO_SAPIC:
 			iosapic = (acpi_entry_iosapic_t *) p;
 			if (iosapic_init)
@@ -415,7 +418,7 @@
 	printk("      %d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
 }
 
-int __init 
+int __init
 acpi_parse (acpi_rsdp_t *rsdp)
 {
 	acpi_rsdt_t *rsdt;
@@ -433,9 +436,9 @@
 		return 0;
 	}
 
-	printk("ACPI: %.6s %.8s %d.%d\n", rsdt->header.oem_id, rsdt->header.oem_table_id, 
+	printk("ACPI: %.6s %.8s %d.%d\n", rsdt->header.oem_id, rsdt->header.oem_table_id,
 	       rsdt->header.oem_revision >> 16, rsdt->header.oem_revision & 0xffff);
-	
+
 #ifdef CONFIG_ACPI_KERNEL_CONFIG
 	acpi_cf_init(rsdp);
 #endif
@@ -460,7 +463,7 @@
 		printk("ACPI: Found 0 CPUS; assuming 1\n");
 		available_cpus = 1; /* We've got at least one of these, no? */
 	}
-	smp_boot_data.cpu_count = available_cpus;
+	smp_boot_data.cpu_count = total_cpus;
 #endif
 	return 1;
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/brl_emu.c linux/arch/ia64/kernel/brl_emu.c
--- v2.4.3/linux/arch/ia64/kernel/brl_emu.c	Thu Jun 22 07:09:44 2000
+++ linux/arch/ia64/kernel/brl_emu.c	Thu Apr  5 12:51:47 2001
@@ -1,6 +1,6 @@
 /*
  *  Emulation of the "brl" instruction for IA64 processors that
- *  don't support it in hardware. 
+ *  don't support it in hardware.
  *  Author: Stephan Zeisset, Intel Corp. <Stephan.Zeisset@intel.com>
  */
 
@@ -23,9 +23,9 @@
  *  of an and operation with the mask must be all 0's
  *  or all 1's for the address to be valid.
  */
-#define unimplemented_virtual_address(va) (					\
-	((va) & my_cpu_data.unimpl_va_mask) != 0 &&				\
-	((va) & my_cpu_data.unimpl_va_mask) != my_cpu_data.unimpl_va_mask	\
+#define unimplemented_virtual_address(va) (						\
+	((va) & local_cpu_data->unimpl_va_mask) != 0 &&					\
+	((va) & local_cpu_data->unimpl_va_mask) != local_cpu_data->unimpl_va_mask	\
 )
 
 /*
@@ -35,13 +35,13 @@
  *  address to be valid.
  */
 #define unimplemented_physical_address(pa) (		\
-	((pa) & my_cpu_data.unimpl_pa_mask) != 0	\
+	((pa) & local_cpu_data->unimpl_pa_mask) != 0	\
 )
 
 /*
- *  Handle an illegal operation fault that was caused by an 
+ *  Handle an illegal operation fault that was caused by an
  *  unimplemented "brl" instruction.
- *  If we are not successful (e.g because the illegal operation 
+ *  If we are not successful (e.g because the illegal operation
  *  wasn't caused by a "brl" after all), we return -1.
  *  If we are successful, we return either 0 or the address
  *  of a "fixup" function for manipulating preserved register
@@ -64,8 +64,8 @@
 	 *  Decode the instruction bundle.
 	 */
 
-        if (copy_from_user(bundle, (void *) (regs->cr_iip), sizeof(bundle)))
-                return rv; 
+	if (copy_from_user(bundle, (void *) (regs->cr_iip), sizeof(bundle)))
+		return rv;
 
 	next_ip = (unsigned long) regs->cr_iip + 16;
 
@@ -79,14 +79,14 @@
 	btype = ((bundle[1] >> 29) & 0x7);
 	qp = ((bundle[1] >> 23) & 0x3f);
 	offset = ((bundle[1] & 0x0800000000000000L) << 4)
-		| ((bundle[1] & 0x00fffff000000000L) >> 32) 
+		| ((bundle[1] & 0x00fffff000000000L) >> 32)
 		| ((bundle[1] & 0x00000000007fffffL) << 40)
 		| ((bundle[0] & 0xffff000000000000L) >> 24);
 
 	tmp_taken = regs->pr & (1L << qp);
 
 	switch(opcode) {
-		
+
 		case 0xC:
 			/*
 			 *  Long Branch.
@@ -169,7 +169,7 @@
 			 */
 			regs->cr_ifs = ((regs->cr_ifs & 0xffffffc00000007f)
 					- ((regs->cr_ifs >> 7) & 0x7f));
-				
+
 			break;
 
 		default:
@@ -180,7 +180,7 @@
 
 	}
 
-	regs->cr_iip += offset; 
+	regs->cr_iip += offset;
 	ia64_psr(regs)->ri = 0;
 
 	if (ia64_psr(regs)->it == 0)
@@ -188,7 +188,7 @@
 	else
 		unimplemented_address = unimplemented_virtual_address(regs->cr_iip);
 
-	if (unimplemented_address) { 
+	if (unimplemented_address) {
 		/*
 		 *  The target address contains unimplemented bits.
 		 */
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/efi.c linux/arch/ia64/kernel/efi.c
--- v2.4.3/linux/arch/ia64/kernel/efi.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/kernel/efi.c	Thu Apr  5 12:51:47 2001
@@ -5,9 +5,9 @@
  *
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999-2000 Hewlett-Packard Co.
+ * Copyright (C) 1999-2001 Hewlett-Packard Co.
  * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999-2000 Stephane Eranian <eranian@hpl.hp.com>
+ * Copyright (C) 1999-2001 Stephane Eranian <eranian@hpl.hp.com>
  *
  * All EFI Runtime Services are not implemented yet as EFI only
  * supports physical mode addressing on SoftSDV. This is to be fixed
@@ -16,7 +16,7 @@
  * Implemented EFI runtime services and virtual mode calls.  --davidm
  *
  * Goutham Rao: <goutham.rao@intel.com>
- * 	Skip non-WB memory and ignore empty memory ranges.
+ *	Skip non-WB memory and ignore empty memory ranges.
  */
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -26,6 +26,7 @@
 
 #include <asm/efi.h>
 #include <asm/io.h>
+#include <asm/kregs.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 
@@ -128,9 +129,9 @@
 	efi_memory_desc_t *md;
 	u64 efi_desc_size, start, end;
 
-	efi_map_start = __va(ia64_boot_param.efi_memmap);
-	efi_map_end   = efi_map_start + ia64_boot_param.efi_memmap_size;
-	efi_desc_size = ia64_boot_param.efi_memdesc_size;
+	efi_map_start = __va(ia64_boot_param->efi_memmap);
+	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+	efi_desc_size = ia64_boot_param->efi_memdesc_size;
 
 	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
 		md = p;
@@ -203,9 +204,9 @@
 	u64 mask, flags;
 	u64 vaddr;
 
-	efi_map_start = __va(ia64_boot_param.efi_memmap);
-	efi_map_end   = efi_map_start + ia64_boot_param.efi_memmap_size;
-	efi_desc_size = ia64_boot_param.efi_memdesc_size;
+	efi_map_start = __va(ia64_boot_param->efi_memmap);
+	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+	efi_desc_size = ia64_boot_param->efi_memdesc_size;
 
 	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
 		md = p;
@@ -218,61 +219,48 @@
 			continue;
 		}
 		/*
-		 * We must use the same page size as the one used
-		 * for the kernel region when we map the PAL code.
-		 * This way, we avoid overlapping TRs if code is 
-		 * executed nearby. The Alt I-TLB installs 256MB
-		 * page sizes as defined for region 7.
+		 * The only ITLB entry in region 7 that is used is the one installed by
+		 * __start().  That entry covers a 64MB range.
 		 *
 		 * XXX Fixme: should be dynamic here (for page size)
 		 */
-		mask  = ~((1 << _PAGE_SIZE_256M)-1);
+		mask  = ~((1 << _PAGE_SIZE_64M) - 1);
 		vaddr = PAGE_OFFSET + md->phys_addr;
 
 		/*
-		 * We must check that the PAL mapping won't overlap
-		 * with the kernel mapping on ITR1. 
+		 * We must check that the PAL mapping won't overlap with the kernel
+		 * mapping.
 		 *
-		 * PAL code is guaranteed to be aligned on a power of 2
-		 * between 4k and 256KB.
-		 * Also from the documentation, it seems like there is an
-		 * implicit guarantee that you will need only ONE ITR to
-		 * map it. This implies that the PAL code is always aligned
-		 * on its size, i.e., the closest matching page size supported
-		 * by the TLB. Therefore PAL code is guaranteed never to cross
-		 * a 256MB unless it is bigger than 256MB (very unlikely!).
-		 * So for now the following test is enough to determine whether
-		 * or not we need a dedicated ITR for the PAL code.
+		 * PAL code is guaranteed to be aligned on a power of 2 between 4k and
+		 * 256KB.  Also from the documentation, it seems like there is an implicit
+		 * guarantee that you will need only ONE ITR to map it. This implies that
+		 * the PAL code is always aligned on its size, i.e., the closest matching
+		 * page size supported by the TLB. Therefore PAL code is guaranteed never
+		 * to cross a 64MB unless it is bigger than 64MB (very unlikely!).  So for
+		 * now the following test is enough to determine whether or not we need a
+		 * dedicated ITR for the PAL code.
 		 */
-		if ((vaddr & mask) == (PAGE_OFFSET & mask)) {
-			printk(__FUNCTION__ " : no need to install ITR for PAL Code\n");
+		if ((vaddr & mask) == (KERNEL_START & mask)) {
+			printk(__FUNCTION__ " : no need to install ITR for PAL code\n");
 			continue;
 		}
 
-	  	printk("CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
+		printk("CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
 		       smp_processor_id(), md->phys_addr, md->phys_addr + (md->num_pages << 12),
-		       vaddr & mask, (vaddr & mask) + 256*1024*1024);
+		       vaddr & mask, (vaddr & mask) + 64*1024*1024);
 
 		/*
 		 * Cannot write to CRx with PSR.ic=1
 		 */
 		ia64_clear_ic(flags);
-
-		/*
-		 * ITR0/DTR0: used for kernel code/data
-		 * ITR1/DTR1: used by HP simulator
-		 * ITR2/DTR2: map PAL code
-		 */
-		ia64_itr(0x1, 2, vaddr & mask,
-			 pte_val(mk_pte_phys(md->phys_addr,
-					     __pgprot(__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RX))),
-			 _PAGE_SIZE_256M);
+		ia64_itr(0x1, IA64_TR_PALCODE, vaddr & mask,
+			 pte_val(mk_pte_phys(md->phys_addr, PAGE_KERNEL)), _PAGE_SIZE_64M);
 		local_irq_restore(flags);
-		ia64_srlz_i ();
+		ia64_srlz_i();
 	}
 }
 
-void __init 
+void __init
 efi_init (void)
 {
 	void *efi_map_start, *efi_map_end;
@@ -301,14 +289,14 @@
 	if (mem_limit != ~0UL)
 		printk("Ignoring memory above %luMB\n", mem_limit >> 20);
 
-	efi.systab = __va(ia64_boot_param.efi_systab);
+	efi.systab = __va(ia64_boot_param->efi_systab);
 
 	/*
 	 * Verify the EFI Table
- 	 */
-	if (efi.systab == NULL) 
+	 */
+	if (efi.systab == NULL)
 		panic("Woah! Can't find EFI system table.\n");
-	if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) 
+	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: "
@@ -360,9 +348,9 @@
 	efi.get_next_high_mono_count = phys_get_next_high_mono_count;
 	efi.reset_system = phys_reset_system;
 
-	efi_map_start = __va(ia64_boot_param.efi_memmap);
-	efi_map_end   = efi_map_start + ia64_boot_param.efi_memmap_size;
-	efi_desc_size = ia64_boot_param.efi_memdesc_size;
+	efi_map_start = __va(ia64_boot_param->efi_memmap);
+	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+	efi_desc_size = ia64_boot_param->efi_memdesc_size;
 
 #if EFI_DEBUG
 	/* print EFI memory map: */
@@ -380,16 +368,7 @@
 #endif
 
 	efi_map_pal_code();
-
-#ifndef CONFIG_IA64_SOFTSDV_HACKS
-	/*
-	 * (Some) SoftSDVs seem to have a problem with this call.
-	 * Since it's mostly a performance optimization, just don't do
-	 * it for now...  --davidm 99/12/6
-	 */
 	efi_enter_virtual_mode();
-#endif
-
 }
 
 void
@@ -400,9 +379,9 @@
 	efi_status_t status;
 	u64 efi_desc_size;
 
-	efi_map_start = __va(ia64_boot_param.efi_memmap);
-	efi_map_end   = efi_map_start + ia64_boot_param.efi_memmap_size;
-	efi_desc_size = ia64_boot_param.efi_memdesc_size;
+	efi_map_start = __va(ia64_boot_param->efi_memmap);
+	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+	efi_desc_size = ia64_boot_param->efi_memdesc_size;
 
 	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
 		md = p;
@@ -441,9 +420,9 @@
 	}
 
 	status = efi_call_phys(__va(runtime->set_virtual_address_map),
-			       ia64_boot_param.efi_memmap_size,
-			       efi_desc_size, ia64_boot_param.efi_memdesc_version,
-			       ia64_boot_param.efi_memmap);
+			       ia64_boot_param->efi_memmap_size,
+			       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=%lu)\n", status);
 		return;
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/efi_stub.S linux/arch/ia64/kernel/efi_stub.S
--- v2.4.3/linux/arch/ia64/kernel/efi_stub.S	Fri Jul 14 16:08:11 2000
+++ linux/arch/ia64/kernel/efi_stub.S	Thu Apr  5 12:51:47 2001
@@ -33,13 +33,6 @@
 #include <asm/processor.h>
 #include <asm/asmmacro.h>
 
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
-
-	.text
-
 /*
  * Inputs:
  *	in0 = address of function descriptor of EFI routine to call
@@ -50,15 +43,15 @@
  */
 
 GLOBAL_ENTRY(efi_call_phys)
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8))
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
 	alloc loc1=ar.pfs,8,5,7,0
 	ld8 r2=[in0],8			// load EFI function's entry point
 	mov loc0=rp
-	UNW(.body)
+	.body
 	;;
 	mov loc2=gp			// save global pointer
 	mov loc4=ar.rsc			// save RSE configuration
-	mov ar.rsc=r0			// put RSE in enforced lazy, LE mode
+	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	;;
 
 	ld8 gp=[in0]			// load EFI function's global pointer
@@ -80,7 +73,7 @@
 	mov out5=in6
 	mov out6=in7
 	br.call.sptk.few rp=b6		// call the EFI function
-.ret1:	mov ar.rsc=r0			// put RSE in enforced lazy, LE mode
+.ret1:	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	mov r16=loc3
 	br.call.sptk.few rp=ia64_switch_mode // return to virtual mode
 .ret2:	mov ar.rsc=loc4			// restore RSE configuration
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/efivars.c linux/arch/ia64/kernel/efivars.c
--- v2.4.3/linux/arch/ia64/kernel/efivars.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ia64/kernel/efivars.c	Thu Apr  5 12:51:47 2001
@@ -0,0 +1,433 @@
+/*
+ * EFI Variables - efivars.c
+ *
+ * Copyright (C) 2001 Dell Computer Corporation <Matt_Domsch@dell.com>
+ *
+ * This code takes all variables accessible from EFI runtime and
+ *  exports them via /proc
+ *
+ * Reads to /proc/efi/varname return an efi_variable_t structure.
+ * Writes to /proc/efi/varname must be an efi_variable_t structure.
+ * Writes with DataSize = 0 or Attributes = 0 deletes the variable.
+ * Writes with a new value in VariableName+VendorGuid creates
+ * a new variable.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Changelog:
+ *
+ *  12 March 2001 - Matt Domsch <Matt_Domsch@dell.com>
+ *   Feedback received from Stephane Eranian incorporated.
+ *   efivar_write() checks copy_from_user() return value.
+ *   efivar_read/write() returns proper errno.
+ *   v0.02 release to linux-ia64@linuxia64.org
+ *
+ *  26 February 2001 - Matt Domsch <Matt_Domsch@dell.com>
+ *   v0.01 release to linux-ia64@linuxia64.org
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>		/* for capable() */
+#include <linux/mm.h>
+#include <linux/module.h>
+
+#include <asm/efi.h>
+#include <asm/uaccess.h>
+#ifdef CONFIG_SMP
+#include <linux/smp.h>
+#endif
+
+MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
+MODULE_DESCRIPTION("/proc interface to EFI Variables");
+
+#define EFIVARS_VERSION "0.02 2001-Mar-12"
+
+static int
+efivar_read(char *page, char **start, off_t off,
+	    int count, int *eof, void *data);
+static int
+efivar_write(struct file *file, const char *buffer,
+	     unsigned long count, void *data);
+
+
+/*
+ * The maximum size of VariableName + Data = 1024
+ * Therefore, it's reasonable to save that much
+ * space in each part of the structure,
+ * and we use a page for reading/writing.
+ */
+
+typedef struct _efi_variable_t {
+	efi_char16_t  VariableName[1024/sizeof(efi_char16_t)];
+	efi_guid_t    VendorGuid;
+	unsigned long DataSize;
+	__u8          Data[1024];
+	efi_status_t  Status;
+	__u32         Attributes;
+} __attribute__((packed)) efi_variable_t;
+
+
+typedef struct _efivar_entry_t {
+	efi_variable_t          var;
+	struct proc_dir_entry   *entry;
+	struct list_head        list;
+} efivar_entry_t;
+
+spinlock_t efivars_lock = SPIN_LOCK_UNLOCKED;
+static LIST_HEAD(efivar_list);
+static struct proc_dir_entry *efi_dir = NULL;
+
+#define efivar_entry(n) list_entry(n, efivar_entry_t, list)
+
+/* Return the number of unicode characters in data */
+static unsigned long
+utf8_strlen(efi_char16_t *data, unsigned long maxlength)
+{
+	unsigned long length = 0;
+	while (*data++ != 0 && length < maxlength)
+		length++;
+	return length;
+}
+
+/* Return the number of bytes is the length of this string */
+/* Note: this is NOT the same as the number of unicode characters */
+static inline unsigned long
+utf8_strsize(efi_char16_t *data, unsigned long maxlength)
+{
+	return utf8_strlen(data, maxlength/sizeof(efi_char16_t)) *
+		sizeof(efi_char16_t);
+}
+
+
+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 void
+uuid_unparse(efi_guid_t *guid, char *out)
+{
+	sprintf(out, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		guid->data1, guid->data2, guid->data3,
+		guid->data4[0], guid->data4[1], guid->data4[2], guid->data4[3],
+		guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7]);
+}
+
+
+
+
+
+/*
+ * efivar_create_proc_entry()
+ * Requires:
+ *    variable_name_size = number of bytes required to hold
+ *                         variable_name (not counting the NULL
+ *                         character at the end.
+ * Returns 1 on failure, 0 on success
+ */
+static int
+efivar_create_proc_entry(unsigned long variable_name_size,
+			 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);
+	if (!short_name || !new_efivar)  {
+		if (short_name)        kfree(short_name);
+		if (new_efivar)        kfree(new_efivar);
+		return 1;
+	}
+	memset(short_name, 0, short_name_size+1);
+	memset(new_efivar, 0, sizeof(efivar_entry_t));
+
+	memcpy(new_efivar->var.VariableName, variable_name,
+	       variable_name_size);
+	memcpy(&(new_efivar->var.VendorGuid), vendor_guid, sizeof(efi_guid_t));
+
+	/* Convert Unicode to normal chars (assume top bits are 0),
+	   ala UTF-8 */
+	for (i=0; i<variable_name_size / sizeof(efi_char16_t); i++) {
+		short_name[i] = variable_name[i] & 0xFF;
+	}
+
+	/* This is ugly, but necessary to separate one vendor's
+	   private variables from another's.         */
+
+	*(short_name + strlen(short_name)) = '-';
+	uuid_unparse(vendor_guid, short_name + strlen(short_name));
+
+
+	/* Create the entry in proc */
+	new_efivar->entry = create_proc_entry(short_name, 0600, efi_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;
+
+	list_add(&new_efivar->list, &efivar_list);
+
+
+	return 0;
+}
+
+
+
+/***********************************************************
+ * efivar_read()
+ * Requires:
+ * Modifies: page
+ * Returns: number of bytes written, or -EINVAL on failure
+ ***********************************************************/
+
+static int
+efivar_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int len = sizeof(efi_variable_t);
+	efivar_entry_t *efi_var = data;
+	efi_variable_t *var_data = (efi_variable_t *)page;
+
+	if (!page || !data) return -EINVAL;
+
+	spin_lock(&efivars_lock);
+	MOD_INC_USE_COUNT;
+
+	memcpy(var_data, &efi_var->var, len);
+
+	var_data->DataSize = 1024;
+	var_data->Status = efi.get_variable(var_data->VariableName,
+					    &var_data->VendorGuid,
+					    &var_data->Attributes,
+					    &var_data->DataSize,
+					    var_data->Data);
+
+	MOD_DEC_USE_COUNT;
+	spin_unlock(&efivars_lock);
+
+	return proc_calc_metrics(page, start, off, count, eof, len);
+}
+
+/***********************************************************
+ * efivar_write()
+ * Requires: data is an efi_setvariable_t data type,
+ *           properly filled in, possibly by a call
+ *           first to efivar_read().
+ *           Caller must have CAP_SYS_ADMIN
+ * Modifies: NVRAM
+ * Returns: var_data->DataSize on success, errno on failure
+ *
+ ***********************************************************/
+static int
+efivar_write(struct file *file, const char *buffer,
+	     unsigned long count, void *data)
+{
+	unsigned long strsize1, strsize2;
+	int found=0;
+	struct list_head *pos;
+	unsigned long size = sizeof(efi_variable_t);
+	efi_status_t status;
+	efivar_entry_t *efivar = data, *search_efivar = NULL;
+	efi_variable_t *var_data;
+	if (!data || count != size) {
+		printk(KERN_WARNING "efivars: improper struct of size 0x%lx passed.\n", count);
+		return -EINVAL;
+	}
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	spin_lock(&efivars_lock);
+	MOD_INC_USE_COUNT;
+
+	var_data = kmalloc(size, GFP_KERNEL);
+	if (!var_data) {
+		MOD_DEC_USE_COUNT;
+		spin_unlock(&efivars_lock);
+		return -ENOMEM;
+	}
+	if (copy_from_user(var_data, buffer, size)) {
+		MOD_DEC_USE_COUNT;
+		spin_unlock(&efivars_lock);
+		return -EFAULT;
+	}
+
+
+	/* Since the data ptr we've currently got is probably for
+	   a different variable find the right variable.
+	   This allows any properly formatted data structure to
+	   be written to any of the files in /proc/efi and it will work.
+	*/
+	list_for_each(pos, &efivar_list) {
+		search_efivar = efivar_entry(pos);
+		strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024);
+		strsize2 = utf8_strsize(var_data->VariableName, 1024);
+		if ( strsize1 == strsize2 &&
+		     !memcmp(&(search_efivar->var.VariableName),
+			     var_data->VariableName, strsize1) &&
+		     !efi_guidcmp(search_efivar->var.VendorGuid,
+				  var_data->VendorGuid)) {
+			found = 1;
+			break;
+		}
+	}
+	if (found) efivar = search_efivar;
+
+	status = efi.set_variable(var_data->VariableName,
+				  &var_data->VendorGuid,
+				  var_data->Attributes,
+				  var_data->DataSize,
+				  var_data->Data);
+
+	if (status != EFI_SUCCESS) {
+		printk(KERN_WARNING "set_variable() failed: status=%lx\n", status);
+		kfree(var_data);
+		MOD_DEC_USE_COUNT;
+		spin_unlock(&efivars_lock);
+		return -EIO;
+	}
+
+
+	if (!var_data->DataSize || !var_data->Attributes) {
+		/* We just deleted the NVRAM variable */
+		remove_proc_entry(efivar->entry->name, efi_dir);
+		list_del(&efivar->list);
+		kfree(efivar);
+	}
+
+	/* If this is a new variable, set up the proc entry for it. */
+	if (!found) {
+		efivar_create_proc_entry(utf8_strsize(var_data->VariableName,
+						      1024),
+					 var_data->VariableName,
+					 &var_data->VendorGuid);
+	}
+
+	kfree(var_data);
+	MOD_DEC_USE_COUNT;
+	spin_unlock(&efivars_lock);
+	return size;
+}
+
+
+
+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);
+
+	/* Per EFI spec, the maximum storage allocated for both
+	   the variable name and variable data is 1024 bytes.
+	*/
+
+	efi_dir = proc_mkdir("efi", NULL);
+
+	memset(variable_name, 0, 1024);
+
+	do {
+		variable_name_size=1024;
+
+		status = efi.get_next_variable(&variable_name_size,
+					       variable_name,
+					       &vendor_guid);
+
+
+		switch (status) {
+		case EFI_SUCCESS:
+			efivar_create_proc_entry(variable_name_size,
+						 variable_name,
+						 &vendor_guid);
+			break;
+		case EFI_NOT_FOUND:
+			break;
+		default:
+			printk(KERN_WARNING "get_next_variable: status=%lx\n", status);
+			status = EFI_NOT_FOUND;
+			break;
+		}
+
+	} while (status != EFI_NOT_FOUND);
+
+	kfree(variable_name);
+	spin_unlock(&efivars_lock);
+	return 0;
+}
+
+static void __exit
+efivars_exit(void)
+{
+	struct list_head *pos;
+	efivar_entry_t *efivar;
+
+	spin_lock(&efivars_lock);
+
+	list_for_each(pos, &efivar_list) {
+		efivar = efivar_entry(pos);
+		remove_proc_entry(efivar->entry->name, efi_dir);
+		list_del(&efivar->list);
+		kfree(efivar);
+	}
+	remove_proc_entry(efi_dir->name, NULL);
+	spin_unlock(&efivars_lock);
+
+}
+
+module_init(efivars_init);
+module_exit(efivars_exit);
+
+/*
+ * 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
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/entry.S linux/arch/ia64/kernel/entry.S
--- v2.4.3/linux/arch/ia64/kernel/entry.S	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/entry.S	Thu Apr  5 12:51:47 2001
@@ -3,8 +3,8 @@
  *
  * Kernel entry points.
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  * Copyright (C) 1999 Asit Mallick <Asit.K.Mallick@intel.com>
@@ -15,8 +15,6 @@
  * kernel stack. This allows us to handle interrupts without changing
  * to physical mode.
  *
- * ar.k4 is now used to hold last virtual map address
- * 
  * Jonathan Nickin	<nicklin@missioncriticallinux.com>
  * Patrick O'Rourke	<orourke@missioncriticallinux.com>
  * 11/07/2000
@@ -25,66 +23,84 @@
  * Global (preserved) predicate usage on syscall entry/exit path:
  *
  *	pKern:		See entry.h.
+ *	pUser:		See entry.h.
  *	pSys:		See entry.h.
  *	pNonSys:	!pSys
- *	p2:		(Alias of pKern!) True if any signals are pending.
  */
 
 #include <linux/config.h>
 
 #include <asm/cache.h>
 #include <asm/errno.h>
+#include <asm/kregs.h>
 #include <asm/offsets.h>
 #include <asm/processor.h>
 #include <asm/unistd.h>
 #include <asm/asmmacro.h>
 #include <asm/pgtable.h>
-	
-#include "entry.h"
 
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
+#include "minstate.h"
 
 	/*
 	 * execve() is special because in case of success, we need to
 	 * setup a null register window frame.
 	 */
 ENTRY(ia64_execve)
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3))
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3)
 	alloc loc1=ar.pfs,3,2,4,0
 	mov loc0=rp
-	UNW(.body)
+	.body
 	mov out0=in0			// filename
 	;;				// stop bit between alloc and call
 	mov out1=in1			// argv
 	mov out2=in2			// envp
 	add out3=16,sp			// regs
 	br.call.sptk.few rp=sys_execve
-.ret0:	cmp4.ge p6,p0=r8,r0
+.ret0:	cmp4.ge p6,p7=r8,r0
 	mov ar.pfs=loc1			// restore ar.pfs
-	;;
-(p6)	mov ar.pfs=r0			// clear ar.pfs in case of success
 	sxt4 r8=r8			// return 64-bit result
+	;;
+	stf.spill [sp]=f0
+(p6)	cmp.ne pKern,pUser=r0,r0	// a successful execve() lands us in user-mode...
 	mov rp=loc0
+(p6)	mov ar.pfs=r0			// clear ar.pfs on success
+(p7)	br.ret.sptk.few rp
 
+	/*
+	 * In theory, we'd have to zap this state only to prevent leaking of
+	 * security sensitive state (e.g., if current->dumpable is zero).  However,
+	 * this executes in less than 20 cycles even on Itanium, so it's not worth
+	 * optimizing for...).
+	 */
+	mov r4=0;		mov f2=f0;		mov b1=r0
+	mov r5=0;		mov f3=f0;		mov b2=r0
+	mov r6=0;		mov f4=f0;		mov b3=r0
+	mov r7=0;		mov f5=f0;		mov b4=r0
+	mov ar.unat=0;		mov f10=f0;		mov b5=r0
+	ldf.fill f11=[sp];	ldf.fill f12=[sp];	mov f13=f0
+	ldf.fill f14=[sp];	ldf.fill f15=[sp];	mov f16=f0
+	ldf.fill f17=[sp];	ldf.fill f18=[sp];	mov f19=f0
+	ldf.fill f20=[sp];	ldf.fill f21=[sp];	mov f22=f0
+	ldf.fill f23=[sp];	ldf.fill f24=[sp];	mov f25=f0
+	ldf.fill f26=[sp];	ldf.fill f27=[sp];	mov f28=f0
+	ldf.fill f29=[sp];	ldf.fill f30=[sp];	mov f31=f0
+	mov ar.lc=0
 	br.ret.sptk.few rp
 END(ia64_execve)
 
 GLOBAL_ENTRY(sys_clone2)
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2))
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
 	alloc r16=ar.pfs,3,2,4,0
 	DO_SAVE_SWITCH_STACK
 	mov loc0=rp
 	mov loc1=r16				// save ar.pfs across do_fork
-	UNW(.body)
+	.body
 	mov out1=in1
 	mov out3=in2
 	adds out2=IA64_SWITCH_STACK_SIZE+16,sp	// out2 = &regs
 	mov out0=in0				// out0 = clone_flags
 	br.call.sptk.few rp=do_fork
-.ret1:	UNW(.restore sp)
+.ret1:	.restore sp
 	adds sp=IA64_SWITCH_STACK_SIZE,sp	// pop the switch stack
 	mov ar.pfs=loc1
 	mov rp=loc0
@@ -92,43 +108,42 @@
 END(sys_clone2)
 
 GLOBAL_ENTRY(sys_clone)
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2))
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
 	alloc r16=ar.pfs,2,2,4,0
 	DO_SAVE_SWITCH_STACK
 	mov loc0=rp
 	mov loc1=r16				// save ar.pfs across do_fork
-	UNW(.body)
+	.body
 	mov out1=in1
 	mov out3=0
 	adds out2=IA64_SWITCH_STACK_SIZE+16,sp	// out2 = &regs
 	mov out0=in0				// out0 = clone_flags
 	br.call.sptk.few rp=do_fork
-.ret2:	UNW(.restore sp)
+.ret2:	.restore sp
 	adds sp=IA64_SWITCH_STACK_SIZE,sp	// pop the switch stack
 	mov ar.pfs=loc1
 	mov rp=loc0
 	br.ret.sptk.many rp
 END(sys_clone)
 
-#define KSTACK_TR	2
-
 /*
  * prev_task <- ia64_switch_to(struct task_struct *next)
  */
 GLOBAL_ENTRY(ia64_switch_to)
-	UNW(.prologue)
+	.prologue
 	alloc r16=ar.pfs,1,0,0,0
 	DO_SAVE_SWITCH_STACK
-	UNW(.body)
+	.body
 
 	adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13
-	mov r27=ar.k4
+	mov r27=IA64_KR(CURRENT_STACK)
 	dep r20=0,in0,61,3		// physical address of "current"
 	;;
 	st8 [r22]=sp			// save kernel stack pointer of old task
-	shr.u r26=r20,_PAGE_SIZE_256M
+	shr.u r26=r20,_PAGE_SIZE_64M
+	mov r16=1
 	;;
-	cmp.eq p7,p6=r26,r0		// check < 256M
+	cmp.ne p6,p7=r26,r16		// check >= 64M && < 128M
 	adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0
 	;;
 	/*
@@ -142,50 +157,36 @@
 (p6)	ssm psr.ic			// if we we had to map, renable the psr.ic bit FIRST!!!
 	;;
 (p6)	srlz.d
-	mov ar.k6=r20			// copy "current" into ar.k6
+	mov IA64_KR(CURRENT)=r20	// update "current" application register
 	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
-	DO_LOAD_SWITCH_STACK( )
+	DO_LOAD_SWITCH_STACK
 
 #ifdef CONFIG_SMP
 	sync.i				// ensure "fc"s done by this CPU are visible on other CPUs
-#endif 
+#endif
 	br.ret.sptk.few rp		// boogie on out in new context
 
 .map:
 	rsm psr.i | psr.ic
-	movl r25=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RWX
+	movl r25=PAGE_KERNEL
 	;;
 	srlz.d
 	or r23=r25,r20			// construct PA | page properties
-	mov r25=_PAGE_SIZE_256M<<2
+	mov r25=_PAGE_SIZE_64M<<2
 	;;
 	mov cr.itir=r25
 	mov cr.ifa=in0			// VA of next task...
 	;;
-	mov r25=KSTACK_TR		// use tr entry #2...
-	mov ar.k4=r26			// remember last page we mapped...
+	mov r25=IA64_TR_CURRENT_STACK
+	mov IA64_KR(CURRENT_STACK)=r26	// remember last page we mapped...
 	;;
 	itr.d dtr[r25]=r23		// wire in new mapping...
 	br.cond.sptk.many .done
-	;;
 END(ia64_switch_to)
 
-#ifndef CONFIG_IA64_NEW_UNWIND
-	/*
-	 * Like save_switch_stack, but also save the stack frame that is active
-	 * at the time this function is called.
-	 */
-ENTRY(save_switch_stack_with_current_frame)
-	UNW(.prologue)
-	alloc r16=ar.pfs,0,0,0,0		// pass ar.pfs to save_switch_stack
-	DO_SAVE_SWITCH_STACK
-	br.ret.sptk.few rp
-END(save_switch_stack_with_current_frame)
-#endif /* !CONFIG_IA64_NEW_UNWIND */
-
 /*
  * Note that interrupts are enabled during save_switch_stack and
  * load_switch_stack.  This means that we may get an interrupt with
@@ -205,95 +206,108 @@
  *	- rp (b0) holds return address to save
  */
 GLOBAL_ENTRY(save_switch_stack)
-	UNW(.prologue)
-	UNW(.altrp b7)
+	.prologue
+	.altrp b7
 	flushrs			// flush dirty regs to backing store (must be first in insn group)
+	.save @priunat,r17
 	mov r17=ar.unat		// preserve caller's
-	adds r2=16,sp		// r2 = &sw->caller_unat
+	.body
+#if !(defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) \
+      || defined(CONFIG_ITANIUM_B0_SPECIFIC) || defined(CONFIG_ITANIUM_B1_SPECIFIC))
+	adds r3=80,sp
 	;;
-	mov r18=ar.fpsr		// preserve fpsr
-	mov ar.rsc=r0		// put RSE in mode: enforced lazy, little endian, pl 0
+	lfetch.fault.excl.nt1 [r3],128
+#endif
+	mov ar.rsc=0		// put RSE in mode: enforced lazy, little endian, pl 0
+#if !(defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) \
+      || defined(CONFIG_ITANIUM_B0_SPECIFIC) || defined(CONFIG_ITANIUM_B1_SPECIFIC))
+	adds r2=16+128,sp
 	;;
-	mov r19=ar.rnat
-	adds r3=24,sp		// r3 = &sw->ar_fpsr
+	lfetch.fault.excl.nt1 [r2],128
+	lfetch.fault.excl.nt1 [r3],128
+#endif
+	adds r14=SW(R4)+16,sp
+#if !(defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) \
+      || defined(CONFIG_ITANIUM_B0_SPECIFIC) || defined(CONFIG_ITANIUM_B1_SPECIFIC))
+	;;
+	lfetch.fault.excl [r2]
+	lfetch.fault.excl [r3]
+#endif
+	adds r15=SW(R5)+16,sp
 	;;
-	.savesp ar.unat,SW(CALLER_UNAT)
-	st8 [r2]=r17,16
-	.savesp ar.fpsr,SW(AR_FPSR)
-	st8 [r3]=r18,24
+	mov r18=ar.fpsr		// preserve fpsr
+	mov r19=ar.rnat
+	add r2=SW(F2)+16,sp	// r2 = &sw->f2
+.mem.offset 0,0; st8.spill [r14]=r4,16		// spill r4
+.mem.offset 8,0; st8.spill [r15]=r5,16		// spill r5
+	add r3=SW(F3)+16,sp	// r3 = &sw->f3
 	;;
-	UNW(.body)
 	stf.spill [r2]=f2,32
 	stf.spill [r3]=f3,32
 	mov r21=b0
+.mem.offset 0,0; st8.spill [r14]=r6,16		// spill r6
+.mem.offset 8,0; st8.spill [r15]=r7,16		// spill r7
+	mov r22=b1
 	;;
+	// since we're done with the spills, read and save ar.unat:
+	mov r29=ar.unat		// M-unit
+	mov r20=ar.bspstore	// M-unit
+	mov r23=b2
 	stf.spill [r2]=f4,32
 	stf.spill [r3]=f5,32
+	mov r24=b3
 	;;
+	st8 [r14]=r21,16	// save b0
+	st8 [r15]=r22,16	// save b1
+	mov r25=b4
 	stf.spill [r2]=f10,32
 	stf.spill [r3]=f11,32
-	mov r22=b1
+	mov r26=b5
 	;;
+	st8 [r14]=r23,16	// save b2
+	st8 [r15]=r24,16	// save b3
+	mov r21=ar.lc		// I-unit
 	stf.spill [r2]=f12,32
 	stf.spill [r3]=f13,32
-	mov r23=b2
 	;;
+	st8 [r14]=r25,16	// save b4
+	st8 [r15]=r26,16	// save b5
 	stf.spill [r2]=f14,32
 	stf.spill [r3]=f15,32
-	mov r24=b3
 	;;
+	st8 [r14]=r16		// save ar.pfs
+	st8 [r15]=r21		// save ar.lc
 	stf.spill [r2]=f16,32
 	stf.spill [r3]=f17,32
-	mov r25=b4
 	;;
 	stf.spill [r2]=f18,32
 	stf.spill [r3]=f19,32
-	mov r26=b5
 	;;
 	stf.spill [r2]=f20,32
 	stf.spill [r3]=f21,32
-	mov r17=ar.lc				// I-unit
 	;;
 	stf.spill [r2]=f22,32
 	stf.spill [r3]=f23,32
 	;;
 	stf.spill [r2]=f24,32
 	stf.spill [r3]=f25,32
+	add r14=SW(CALLER_UNAT)+16,sp
 	;;
 	stf.spill [r2]=f26,32
 	stf.spill [r3]=f27,32
+	add r15=SW(AR_FPSR)+16,sp
 	;;
 	stf.spill [r2]=f28,32
 	stf.spill [r3]=f29,32
-	;;
-	stf.spill [r2]=f30,32
-	stf.spill [r3]=f31,24
-	;;
-.mem.offset 0,0;	st8.spill [r2]=r4,16
-.mem.offset 8,0;	st8.spill [r3]=r5,16
-	;;
-.mem.offset 0,0;	st8.spill [r2]=r6,16
-.mem.offset 8,0;	st8.spill [r3]=r7,16
-	;;
-	st8 [r2]=r21,16		// save b0
-	st8 [r3]=r22,16		// save b1
-	/* since we're done with the spills, read and save ar.unat: */
-	mov r18=ar.unat		// M-unit
-	mov r20=ar.bspstore	// M-unit
-	;;
-	st8 [r2]=r23,16		// save b2
-	st8 [r3]=r24,16		// save b3
-	;;
-	st8 [r2]=r25,16		// save b4
-	st8 [r3]=r26,16		// save b5
-	;;
-	st8 [r2]=r16,16		// save ar.pfs
-	st8 [r3]=r17,16		// save ar.lc
+	st8 [r14]=r17		// save caller_unat
+	st8 [r15]=r18		// save fpsr
 	mov r21=pr
 	;;
-	st8 [r2]=r18,16		// save ar.unat
+	stf.spill [r2]=f30,(SW(AR_UNAT)-SW(F30))
+	stf.spill [r3]=f31,(SW(AR_RNAT)-SW(F31))
+	;;
+	st8 [r2]=r29,16		// save ar.unat
 	st8 [r3]=r19,16		// save ar.rnat
-	mov b7=r28
 	;;
 	st8 [r2]=r20		// save ar.bspstore
 	st8 [r3]=r21		// save predicate registers
@@ -303,16 +317,27 @@
 
 /*
  * load_switch_stack:
+ *	- "invala" MUST be done at call site (normally in DO_LOAD_SWITCH_STACK)
  *	- b7 holds address to return to
+ *	- must not touch r8-r11
  */
 ENTRY(load_switch_stack)
-	UNW(.prologue)
-	UNW(.altrp b7)
-	invala			// invalidate ALAT
-	UNW(.body)
-	adds r2=IA64_SWITCH_STACK_B0_OFFSET+16,sp	// get pointer to switch_stack.b0
-	mov ar.rsc=r0		// put RSE into enforced lazy mode
-	adds r3=IA64_SWITCH_STACK_B0_OFFSET+24,sp	// get pointer to switch_stack.b1
+	.prologue
+	.altrp b7
+	.body
+#if !(defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) \
+      || defined(CONFIG_ITANIUM_B0_SPECIFIC) || defined(CONFIG_ITANIUM_B1_SPECIFIC))
+
+	lfetch.fault.nt1 [sp]
+#endif
+	adds r2=SW(AR_BSPSTORE)+16,sp
+	adds r3=SW(AR_UNAT)+16,sp
+	mov ar.rsc=0						// put RSE into enforced lazy mode
+	adds r14=SW(CALLER_UNAT)+16,sp
+	adds r15=SW(AR_FPSR)+16,sp
+	;;
+	ld8 r27=[r2],(SW(B0)-SW(AR_BSPSTORE))	// bspstore
+	ld8 r29=[r3],(SW(B1)-SW(AR_UNAT))	// unat
 	;;
 	ld8 r21=[r2],16		// restore b0
 	ld8 r22=[r3],16		// restore b1
@@ -323,84 +348,77 @@
 	ld8 r25=[r2],16		// restore b4
 	ld8 r26=[r3],16		// restore b5
 	;;
-	ld8 r16=[r2],16		// restore ar.pfs
-	ld8 r17=[r3],16		// restore ar.lc
+	ld8 r16=[r2],(SW(PR)-SW(AR_PFS))	// ar.pfs
+	ld8 r17=[r3],(SW(AR_RNAT)-SW(AR_LC))	// ar.lc
 	;;
-	ld8 r18=[r2],16		// restore ar.unat
-	ld8 r19=[r3],16		// restore ar.rnat
-	mov b0=r21
+	ld8 r28=[r2]		// restore pr
+	ld8 r30=[r3]		// restore rnat
 	;;
-	ld8 r20=[r2]		// restore ar.bspstore
-	ld8 r21=[r3]		// restore predicate registers
-	mov ar.pfs=r16
+	ld8 r18=[r14],16	// restore caller's unat
+	ld8 r19=[r15],24	// restore fpsr
 	;;
-	mov ar.bspstore=r20
+	ldf.fill f2=[r14],32
+	ldf.fill f3=[r15],32
 	;;
-	loadrs			// invalidate stacked regs outside current frame
-	adds r2=16-IA64_SWITCH_STACK_SIZE,r2	// get pointer to switch_stack.caller_unat
-	;;			// stop bit for rnat dependency
-	mov ar.rnat=r19
-	mov ar.unat=r18		// establish unat holding the NaT bits for r4-r7
-	adds r3=16-IA64_SWITCH_STACK_SIZE,r3	// get pointer to switch_stack.ar_fpsr
+	ldf.fill f4=[r14],32
+	ldf.fill f5=[r15],32
 	;;
-	ld8 r18=[r2],16		// restore caller's unat
-	ld8 r19=[r3],24		// restore fpsr
-	mov ar.lc=r17
+	ldf.fill f10=[r14],32
+	ldf.fill f11=[r15],32
+	;;
+	ldf.fill f12=[r14],32
+	ldf.fill f13=[r15],32
 	;;
-	ldf.fill f2=[r2],32
-	ldf.fill f3=[r3],32
-	mov pr=r21,-1
+	ldf.fill f14=[r14],32
+	ldf.fill f15=[r15],32
 	;;
-	ldf.fill f4=[r2],32
-	ldf.fill f5=[r3],32
+	ldf.fill f16=[r14],32
+	ldf.fill f17=[r15],32
 	;;
-	ldf.fill f10=[r2],32
-	ldf.fill f11=[r3],32
+	ldf.fill f18=[r14],32
+	ldf.fill f19=[r15],32
+	mov b0=r21
+	;;
+	ldf.fill f20=[r14],32
+	ldf.fill f21=[r15],32
 	mov b1=r22
 	;;
-	ldf.fill f12=[r2],32
-	ldf.fill f13=[r3],32
+	ldf.fill f22=[r14],32
+	ldf.fill f23=[r15],32
 	mov b2=r23
 	;;
-	ldf.fill f14=[r2],32
-	ldf.fill f15=[r3],32
+	mov ar.bspstore=r27
+	mov ar.unat=r29		// establish unat holding the NaT bits for r4-r7
 	mov b3=r24
 	;;
-	ldf.fill f16=[r2],32
-	ldf.fill f17=[r3],32
+	ldf.fill f24=[r14],32
+	ldf.fill f25=[r15],32
 	mov b4=r25
 	;;
-	ldf.fill f18=[r2],32
-	ldf.fill f19=[r3],32
+	ldf.fill f26=[r14],32
+	ldf.fill f27=[r15],32
 	mov b5=r26
 	;;
-	ldf.fill f20=[r2],32
-	ldf.fill f21=[r3],32
-	;;
-	ldf.fill f22=[r2],32
-	ldf.fill f23=[r3],32
-	;;
-	ldf.fill f24=[r2],32
-	ldf.fill f25=[r3],32
-	;;
-	ldf.fill f26=[r2],32
-	ldf.fill f27=[r3],32
-	;;
-	ldf.fill f28=[r2],32
-	ldf.fill f29=[r3],32
+	ldf.fill f28=[r14],32
+	ldf.fill f29=[r15],32
+	mov ar.pfs=r16
 	;;
-	ldf.fill f30=[r2],32
-	ldf.fill f31=[r3],24
+	ldf.fill f30=[r14],32
+	ldf.fill f31=[r15],24
+	mov ar.lc=r17
 	;;
-	ld8.fill r4=[r2],16
-	ld8.fill r5=[r3],16
+	ld8.fill r4=[r14],16
+	ld8.fill r5=[r15],16
+	mov pr=r28,-1
 	;;
-	ld8.fill r6=[r2],16
-	ld8.fill r7=[r3],16
+	ld8.fill r6=[r14],16
+	ld8.fill r7=[r15],16
+
 	mov ar.unat=r18				// restore caller's unat
+	mov ar.rnat=r30				// must restore after bspstore but before rsc!
 	mov ar.fpsr=r19				// restore fpsr
 	mov ar.rsc=3				// put RSE back into eager mode, pl 0
-	br.cond.sptk.few b7
+	br.cond.sptk.many b7
 END(load_switch_stack)
 
 GLOBAL_ENTRY(__ia64_syscall)
@@ -415,17 +433,16 @@
 	br.ret.sptk.few rp
 END(__ia64_syscall)
 
-	//
-	// We invoke syscall_trace through this intermediate function to
-	// ensure that the syscall input arguments are not clobbered.  We
-	// also use it to preserve b6, which contains the syscall entry point.
-	//
+	/*
+	 * We invoke syscall_trace through this intermediate function to
+	 * ensure that the syscall input arguments are not clobbered.  We
+	 * also use it to preserve b6, which contains the syscall entry point.
+	 */
 GLOBAL_ENTRY(invoke_syscall_trace)
-#ifdef CONFIG_IA64_NEW_UNWIND
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8))
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
 	alloc loc1=ar.pfs,8,3,0,0
 	mov loc0=rp
-	UNW(.body)
+	.body
 	mov loc2=b6
 	;;
 	br.call.sptk.few rp=syscall_trace
@@ -433,33 +450,18 @@
 	mov ar.pfs=loc1
 	mov b6=loc2
 	br.ret.sptk.few rp
-#else /* !CONFIG_IA64_NEW_SYSCALL */
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8))
-	alloc loc1=ar.pfs,8,3,0,0
-	;;			// WAW on CFM at the br.call
-	mov loc0=rp
-	br.call.sptk.many rp=save_switch_stack_with_current_frame	// must preserve b6!!
-.ret4:	mov loc2=b6
-	br.call.sptk.few rp=syscall_trace
-.ret5:	adds sp=IA64_SWITCH_STACK_SIZE,sp	// drop switch_stack frame
-	mov rp=loc0
-	mov ar.pfs=loc1
-	mov b6=loc2
-	;;
-	br.ret.sptk.few rp
-#endif /* !CONFIG_IA64_NEW_SYSCALL */
 END(invoke_syscall_trace)
 
-	//
-	// Invoke a system call, but do some tracing before and after the call.
-	// We MUST preserve the current register frame throughout this routine
-	// because some system calls (such as ia64_execve) directly
-	// manipulate ar.pfs.
-	//
-	// Input:
-	//	r15 = syscall number
-	//	b6  = syscall entry point
-	//
+	/*
+	 * Invoke a system call, but do some tracing before and after the call.
+	 * We MUST preserve the current register frame throughout this routine
+	 * because some system calls (such as ia64_execve) directly
+	 * manipulate ar.pfs.
+	 *
+	 * Input:
+	 *	r15 = syscall number
+	 *	b6  = syscall entry point
+	 */
 	.global ia64_strace_leave_kernel
 
 GLOBAL_ENTRY(ia64_trace_syscall)
@@ -468,8 +470,8 @@
 .ret6:	br.call.sptk.few rp=b6			// do the syscall
 strace_check_retval:
 	cmp.lt p6,p0=r8,r0			// syscall failed?
-	adds r2=IA64_PT_REGS_R8_OFFSET+16,sp	// r2 = &pt_regs.r8
-	adds r3=IA64_PT_REGS_R8_OFFSET+32,sp	// r3 = &pt_regs.r10
+	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
+	adds r3=PT(R10)+16,sp			// r3 = &pt_regs.r10
 	mov r10=0
 (p6)	br.cond.sptk.few strace_error		// syscall failed ->
 	;;					// avoid RAW on r10
@@ -492,28 +494,14 @@
 	br.cond.sptk.few strace_save_retval
 END(ia64_trace_syscall)
 
-/*
- * A couple of convenience macros to help implement/understand the state
- * restoration that happens at the end of ia64_ret_from_syscall.
- */
-#define rARPR		r31
-#define rCRIFS		r30
-#define rCRIPSR		r29
-#define rCRIIP		r28
-#define rARRSC		r27
-#define rARPFS		r26
-#define rARUNAT		r25
-#define rARRNAT		r24
-#define rARBSPSTORE	r23
-#define rKRBS		r22
-#define rB6		r21
-
 GLOBAL_ENTRY(ia64_ret_from_clone)
 	PT_REGS_UNWIND_INFO(0)
 #ifdef CONFIG_SMP
-	// In SMP mode, 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.
+	/*
+	 * In SMP mode, we need to call invoke_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.few rp=invoke_schedule_tail
 .ret8:
 #endif
@@ -530,8 +518,8 @@
 GLOBAL_ENTRY(ia64_ret_from_syscall)
 	PT_REGS_UNWIND_INFO(0)
 	cmp.ge p6,p7=r8,r0			// syscall executed successfully?
-	adds r2=IA64_PT_REGS_R8_OFFSET+16,sp	// r2 = &pt_regs.r8
-	adds r3=IA64_PT_REGS_R8_OFFSET+32,sp	// r3 = &pt_regs.r10
+	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
+	adds r3=PT(R10)+16,sp			// r3 = &pt_regs.r10
 	;;
 	.mem.offset 0,0
 (p6)	st8.spill [r2]=r8	// store return value in slot for r8 and set unat bit
@@ -541,78 +529,57 @@
 END(ia64_ret_from_syscall)
 	// fall through
 GLOBAL_ENTRY(ia64_leave_kernel)
-	// check & deliver software interrupts:
-
 	PT_REGS_UNWIND_INFO(0)
-#ifdef CONFIG_SMP
-	adds r2=IA64_TASK_PROCESSOR_OFFSET,r13
-	movl r3=irq_stat		// softirq_active
-	;;
-	ld4 r2=[r2]
+	cmp.eq p16,p0=r0,r0			// set the "first_time" flag
+	movl r15=PERCPU_ADDR+IA64_CPU_SOFTIRQ_ACTIVE_OFFSET  // r15 = &cpu_data.softirq.active
 	;;
-	shl r2=r2,SMP_CACHE_SHIFT	// can't use shladd here...
+	ld8 r2=[r15]
+	movl r14=.restart
 	;;
-	add r3=r2,r3
-#else
-	movl r3=irq_stat		// softirq_active
+	lfetch.fault [sp]
+	shr.u r3=r2,32			// r3 = cpu_data.softirq.mask
+	MOVBR(.ret.sptk,rp,r14,.restart)
+.restart:
+	adds r17=IA64_TASK_NEED_RESCHED_OFFSET,r13
+	adds r18=IA64_TASK_SIGPENDING_OFFSET,r13
+#ifdef CONFIG_PERFMON
+	adds r19=IA64_TASK_PFM_NOTIFY_OFFSET,r13
 #endif
 	;;
-	ld8 r2=[r3]		// r3 (softirq_active+softirq_mask) is guaranteed to be 8-byte aligned!
-	;;
-	shr r3=r2,32
+	ld8 r17=[r17]				// load current->need_resched
+	ld4 r18=[r18]				// load current->sigpending
+(p16)	and r2=r2,r3				// r2 <- (softirq.active & softirq.mask)
 	;;
-	and r2=r2,r3
+#ifdef CONFIG_PERFMON
+	ld8 r19=[r19]				// load current->task.pfm_notify
+#endif
+(p16)	cmp4.ne.unc p6,p0=r2,r0			// p6 <- (softirq.active & softirq.mask) != 0
+(pUser)	cmp.ne.unc p7,p0=r17,r0			// current->need_resched != 0?
 	;;
-	cmp4.ne p6,p7=r2,r0
-(p6)	br.call.spnt.many rp=invoke_do_softirq
-1:
-(pKern)	br.cond.dpnt.many restore_all	// yup -> skip check for rescheduling & signal delivery
-
-	// call schedule() until we find a task that doesn't have need_resched set:
-
-back_from_resched:
-	{ .mii
-	  adds r2=IA64_TASK_NEED_RESCHED_OFFSET,r13
-	  mov r3=ip
-	  adds r14=IA64_TASK_SIGPENDING_OFFSET,r13
-	}
+(pUser)	cmp.ne.unc p8,p0=r18,r0			// current->sigpending != 0?
+#ifdef CONFIG_PERFMON
+	cmp.ne p9,p0=r19,r0			// current->task.pfm_notify != 0?
+#endif
+	cmp.ne p16,p0=r0,r0			// clear the "first_time" flag
 	;;
-	ld8 r2=[r2]
-	ld4 r14=[r14]
-	mov rp=r3			// arrange for schedule() to return to back_from_resched
+# if __GNUC__ < 3
+(p6)	br.call.spnt.many b7=invoke_do_softirq
+# else
+(p6)	br.call.spnt.many b7=do_softirq
+# endif
+#ifdef CONFIG_PERFMON
+(p9)	br.call.spnt.many b7=pfm_overflow_notify
+#endif
+# if __GNUC__ < 3
+(p7)	br.call.spnt.many b7=invoke_schedule
+#else
+(p7)	br.call.spnt.many b7=schedule
+#endif
+	adds r2=PT(R8)+16,r12
+	adds r3=PT(R9)+16,r12
+(p8)	br.call.spnt.many b7=handle_signal_delivery	// check & deliver pending signals
 	;;
-	cmp.ne p6,p0=r2,r0
-	cmp.ne p2,p0=r14,r0		// NOTE: pKern is an alias for p2!!
-	srlz.d
-(p6)	br.call.spnt.many b6=invoke_schedule	// ignore return value
-2:
-	// check & deliver pending signals:
-(p2)	br.call.spnt.few rp=handle_signal_delivery
-.ret9:
-#ifdef CONFIG_IA64_SOFTSDV_HACKS
-	// Check for lost ticks
-	rsm psr.i
-	mov r2 = ar.itc
-	movl r14 = 1000			// latency tolerance
-	mov r3 = cr.itm
-	;;
-	sub r2 = r2, r3
-	;;
-	sub r2 = r2, r14
-	;;
-	cmp.ge p6,p7 = r2, r0
-(p6)	br.call.spnt.few rp=invoke_ia64_reset_itm
-.ret10:
-	;;
-	ssm psr.i
-#endif 
-restore_all:
-
 	// start restoring the state saved on the kernel stack (struct pt_regs):
-
-	adds r2=IA64_PT_REGS_R8_OFFSET+16,r12
-	adds r3=IA64_PT_REGS_R8_OFFSET+24,r12
-	;;
 	ld8.fill r8=[r2],16
 	ld8.fill r9=[r3],16
 	;;
@@ -643,6 +610,9 @@
 	ld8.fill r30=[r2],16
 	ld8.fill r31=[r3],16
 	;;
+	rsm psr.i | psr.ic	// initiate turning off of interrupts & interruption collection
+	invala			// invalidate ALAT
+	;;
 	ld8 r1=[r2],16		// ar.ccv
 	ld8 r13=[r3],16		// ar.fpsr
 	;;
@@ -658,14 +628,11 @@
 	mov ar.ccv=r1
 	mov ar.fpsr=r13
 	mov b0=r14
-	// turn off interrupts, interrupt collection
-	rsm psr.i | psr.ic
 	;;
-	srlz.i			// EAS 2.5
+	srlz.i			// ensure interrupts & interruption collection are off
 	mov b7=r15
 	;;
-	invala			// invalidate ALAT
-	bsw.0;;			// switch back to bank 0 (must be last in insn group)
+	bsw.0			// switch back to bank 0
 	;;
 #ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
 	nop.i 0x0
@@ -683,17 +650,18 @@
 	;;
 	ld8 rCRIFS=[r16],16	// load cr.ifs
 	ld8 rARUNAT=[r17],16	// load ar.unat
+	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
 	;;
 	ld8 rARPFS=[r16],16	// load ar.pfs
 	ld8 rARRSC=[r17],16	// load ar.rsc
 	;;
 	ld8 rARRNAT=[r16],16	// load ar.rnat (may be garbage)
-	ld8 rARBSPSTORE=[r17],16	// load ar.bspstore (may be garbage)
+	ld8 rARBSPSTORE=[r17],16 // load ar.bspstore (may be garbage)
 	;;
 	ld8 rARPR=[r16],16	// load predicates
 	ld8 rB6=[r17],16	// load b6
 	;;
-	ld8 r18=[r16],16	// load ar.rsc value for "loadrs"
+	ld8 r19=[r16],16	// load ar.rsc value for "loadrs"
 	ld8.fill r1=[r17],16	// load r1
 	;;
 	ld8.fill r2=[r16],16
@@ -701,62 +669,102 @@
 	;;
 	ld8.fill r12=[r16],16
 	ld8.fill r13=[r17],16
-	extr.u r19=rCRIPSR,32,2	// extract ps.cpl
 	;;
-	ld8.fill r14=[r16],16
-	ld8.fill r15=[r17],16
-	cmp.eq p6,p7=r0,r19	// are we returning to kernel mode? (psr.cpl==0)
+	ld8.fill r14=[r16]
+	ld8.fill r15=[r17]
+	shr.u r18=r19,16	// get byte size of existing "dirty" partition
 	;;
-	mov b6=rB6
-	mov ar.pfs=rARPFS
-(p6)	br.cond.dpnt.few skip_rbs_switch
-
+	mov r16=ar.bsp		// get existing backing store pointer
+	movl r17=PERCPU_ADDR+IA64_CPU_PHYS_STACKED_SIZE_P8_OFFSET
+	;;
+	ld4 r17=[r17]		// r17 = cpu_data->phys_stacked_size_p8
+(pKern)	br.cond.dpnt.few skip_rbs_switch
 	/*
 	 * Restore user backing store.
 	 *
 	 * NOTE: alloc, loadrs, and cover can't be predicated.
-	 *
-	 * XXX This needs some scheduling/tuning once we believe it
-	 *     really does work as intended.
 	 */
-	mov r16=ar.bsp			// get existing backing store pointer
 (pNonSys) br.cond.dpnt.few dont_preserve_current_frame
 	cover				// add current frame into dirty partition
 	;;
-	mov rCRIFS=cr.ifs		// fetch the cr.ifs value that "cover" produced
-	mov r17=ar.bsp			// get new backing store pointer
-	;;
-	sub r16=r17,r16			// calculate number of bytes that were added to rbs
+	mov r19=ar.bsp			// get new backing store pointer
+	sub r16=r16,r18			// krbs = old bsp - size of dirty partition
+	cmp.ne p9,p0=r0,r0		// clear p9 to skip restore of cr.ifs
 	;;
-	shl r16=r16,16			// shift additional frame size into position for loadrs
+	sub r19=r19,r16			// calculate total byte size of dirty partition
+	add r18=64,r18			// don't force in0-in7 into memory...
 	;;
-	add r18=r16,r18			// adjust the loadrs value
+	shl r19=r19,16			// shift size of dirty partition into loadrs position
 	;;
 dont_preserve_current_frame:
-	alloc r16=ar.pfs,0,0,0,0	// drop the current call frame (noop for syscalls)
-	;;
-	mov ar.rsc=r18			// load ar.rsc to be used for "loadrs"
-#ifdef CONFIG_IA32_SUPPORT
-	tbit.nz p6,p0=rCRIPSR,IA64_PSR_IS_BIT
+	/*
+	 * To prevent leaking bits between the kernel and user-space,
+	 * we must clear the stacked registers in the "invalid" partition here.
+	 * Not pretty, but at least it's fast (3.34 registers/cycle).
+	 * Architecturally, this loop could go at 4.67 registers/cycle, but that would
+	 * oversubscribe Itanium.
+	 */
+#	define pRecurse	p6
+#	define pReturn	p7
+#	define Nregs	10
+	alloc loc0=ar.pfs,2,Nregs-2,2,0
+	shr.u loc1=r18,9		// RNaTslots <= dirtySize / (64*8) + 1
+	sub r17=r17,r18			// r17 = (physStackedSize + 8) - dirtySize
+	;;
+	mov ar.rsc=r19			// load ar.rsc to be used for "loadrs"
+	shladd in0=loc1,3,r17
+	mov in1=0
+	;;
+	.align 32
+rse_clear_invalid:
+	// cycle 0
+ { .mii
+	alloc loc0=ar.pfs,2,Nregs-2,2,0
+	cmp.lt pRecurse,p0=Nregs*8,in0	// if more than Nregs regs left to clear, (re)curse
+	add out0=-Nregs*8,in0
+}{ .mfb
+	add out1=1,in1			// increment recursion count
+	nop.f 0
+	nop.b 0				// can't do br.call here because of alloc (WAW on CFM)
+	;;
+}{ .mfi	// cycle 1
+	mov loc1=0
+	nop.f 0
+	mov loc2=0
+}{ .mib
+	mov loc3=0
+	mov loc4=0
+(pRecurse) br.call.sptk.few b6=rse_clear_invalid
+
+}{ .mfi	// cycle 2
+	mov loc5=0
+	nop.f 0
+	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
+}{ .mib
+	mov loc6=0
+	mov loc7=0
+(pReturn) br.ret.sptk.few b6
+}
+#	undef pRecurse
+#	undef pReturn
+
+	alloc r17=ar.pfs,0,0,0,0	// drop current register frame
 	;;
-(p6)	mov ar.rsc=r0                   // returning to IA32 mode
-#endif
- 	;;
 	loadrs
 	;;
-	mov ar.bspstore=rARBSPSTORE
-	;;
-	mov ar.rnat=rARRNAT	// must happen with RSE in lazy mode
-
 skip_rbs_switch:
+	mov b6=rB6
+	mov ar.pfs=rARPFS
+(pUser)	mov ar.bspstore=rARBSPSTORE
+(p9)	mov cr.ifs=rCRIFS
+	mov cr.ipsr=rCRIPSR
+	mov cr.iip=rCRIIP
+	;;
+(pUser)	mov ar.rnat=rARRNAT	// must happen with RSE in lazy mode
 	mov ar.rsc=rARRSC
 	mov ar.unat=rARUNAT
-	mov cr.ifs=rCRIFS	// restore cr.ifs only if not a (synchronous) syscall
 	mov pr=rARPR,-1
-	mov cr.iip=rCRIIP
-	mov cr.ipsr=rCRIPSR
-	;;
-	rfi;;			// must be last instruction in an insn group
+	rfi
 END(ia64_leave_kernel)
 
 ENTRY(handle_syscall_error)
@@ -784,13 +792,13 @@
 	br.cond.sptk.many ia64_leave_kernel
 END(handle_syscall_error)
 
-#ifdef CONFIG_SMP
+# ifdef CONFIG_SMP
 	/*
 	 * Invoke schedule_tail(task) while preserving in0-in7, which may be needed
 	 * in case a system call gets restarted.
 	 */
 ENTRY(invoke_schedule_tail)
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8))
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
 	alloc loc1=ar.pfs,8,2,1,0
 	mov loc0=rp
 	mov out0=r8				// Address of previous task
@@ -801,35 +809,24 @@
 	br.ret.sptk.many rp
 END(invoke_schedule_tail)
 
-#endif /* CONFIG_SMP */
-
-#ifdef CONFIG_IA64_SOFTSDV_HACKS
-
-ENTRY(invoke_ia64_reset_itm)
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8))
-	alloc loc1=ar.pfs,8,2,0,0
-	mov loc0=rp
-	;;
-	UNW(.body)
-	br.call.sptk.many rp=ia64_reset_itm
-.ret12:	;;
-	mov ar.pfs=loc1
-	mov rp=loc0
-	br.ret.sptk.many rp
-END(invoke_ia64_reset_itm)
-
-#endif /* CONFIG_IA64_SOFTSDV_HACKS */
+# endif /* CONFIG_SMP */
 
+#if __GNUC__ < 3
 	/*
 	 * Invoke do_softirq() while preserving in0-in7, which may be needed
-	 * in case a system call gets restarted.
+	 * in case a system call gets restarted.  Note that declaring do_softirq()
+	 * with asmlinkage() is NOT enough because that will only preserve as many
+	 * registers as there are formal arguments.
+	 *
+	 * XXX fix me: with gcc 3.0, we won't need this anymore because syscall_linkage
+	 *	renders all eight input registers (in0-in7) as "untouchable".
 	 */
 ENTRY(invoke_do_softirq)
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8))
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
 	alloc loc1=ar.pfs,8,2,0,0
 	mov loc0=rp
 	;;
-	UNW(.body)
+	.body
 	br.call.sptk.few rp=do_softirq
 .ret13:	mov ar.pfs=loc1
 	mov rp=loc0
@@ -838,27 +835,33 @@
 
 	/*
 	 * Invoke schedule() while preserving in0-in7, which may be needed
-	 * in case a system call gets restarted.
+	 * in case a system call gets restarted.  Note that declaring schedule()
+	 * with asmlinkage() is NOT enough because that will only preserve as many
+	 * registers as there are formal arguments.
+	 *
+	 * XXX fix me: with gcc 3.0, we won't need this anymore because syscall_linkage
+	 *	renders all eight input registers (in0-in7) as "untouchable".
 	 */
 ENTRY(invoke_schedule)
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8))
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
 	alloc loc1=ar.pfs,8,2,0,0
 	mov loc0=rp
 	;;
-	UNW(.body)
+	.body
 	br.call.sptk.few rp=schedule
 .ret14:	mov ar.pfs=loc1
 	mov rp=loc0
 	br.ret.sptk.many rp
 END(invoke_schedule)
 
-	//
-	// Setup stack and call ia64_do_signal.  Note that pSys and pNonSys need to
-	// be set up by the caller.  We declare 8 input registers so the system call
-	// args get preserved, in case we need to restart a system call.
-	//
+#endif /* __GNUC__ < 3 */
+
+	/*
+	 * Setup stack and call ia64_do_signal.  Note that pSys and pNonSys need to
+	 * be set up by the caller.  We declare 8 input registers so the system call
+	 * args get preserved, in case we need to restart a system call.
+	 */
 ENTRY(handle_signal_delivery)
-#ifdef CONFIG_IA64_NEW_UNWIND
 	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
 	alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!
 	mov r9=ar.unat
@@ -882,26 +885,9 @@
 	mov ar.unat=r9
 	mov ar.pfs=loc1
 	br.ret.sptk.many rp
-#else /* !CONFIG_IA64_NEW_UNWIND */
-	.prologue
-	alloc r16=ar.pfs,8,0,3,0 // preserve all eight input regs in case of syscall restart!
-	DO_SAVE_SWITCH_STACK
-	UNW(.body)
-
-	mov out0=0				// there is no "oldset"
-	adds out1=16,sp				// out1=&sigscratch
-	.pred.rel.mutex pSys, pNonSys
-(pSys)	mov out2=1				// out2==1 => we're in a syscall
-(pNonSys) mov out2=0				// out2==0 => not a syscall
-	br.call.sptk.few rp=ia64_do_signal
-.ret16:	// restore the switch stack (ptrace may have modified it)
-	DO_LOAD_SWITCH_STACK( )
-	br.ret.sptk.many rp
-#endif /* !CONFIG_IA64_NEW_UNWIND */
 END(handle_signal_delivery)
 
 GLOBAL_ENTRY(sys_rt_sigsuspend)
-#ifdef CONFIG_IA64_NEW_UNWIND
 	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
 	alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!
 	mov r9=ar.unat
@@ -924,87 +910,43 @@
 	mov ar.unat=r9
 	mov ar.pfs=loc1
 	br.ret.sptk.many rp
-#else /* !CONFIG_IA64_NEW_UNWIND */
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2))
-	alloc r16=ar.pfs,2,0,3,0
-	DO_SAVE_SWITCH_STACK
-	UNW(.body)
-
-	mov out0=in0				// mask
-	mov out1=in1				// sigsetsize
-	adds out2=16,sp				// out1=&sigscratch
-	br.call.sptk.many rp=ia64_rt_sigsuspend
-.ret18:	// restore the switch stack (ptrace may have modified it)
-	DO_LOAD_SWITCH_STACK( )
-	br.ret.sptk.many rp
-#endif /* !CONFIG_IA64_NEW_UNWIND */
 END(sys_rt_sigsuspend)
 
 ENTRY(sys_rt_sigreturn)
-#ifdef CONFIG_IA64_NEW_UNWIND
-	.regstk 0,0,3,0	// inherited from gate.s:invoke_sighandler()
 	PT_REGS_UNWIND_INFO(0)
+	alloc r2=ar.pfs,0,0,1,0
 	.prologue
 	PT_REGS_SAVES(16)
 	adds sp=-16,sp
 	.body
-	cmp.eq pNonSys,p0=r0,r0			// sigreturn isn't a normal syscall...
+	cmp.eq pNonSys,pSys=r0,r0		// sigreturn isn't a normal syscall...
 	;;
 	adds out0=16,sp				// out0 = &sigscratch
 	br.call.sptk.few rp=ia64_rt_sigreturn
-.ret19:	adds sp=16,sp		// doesn't drop pt_regs, so don't mark it as restoring sp!
-	PT_REGS_UNWIND_INFO(0)	// instead, create a new body section with the smaller frame
+.ret19:	.restore sp 0
+	adds sp=16,sp
 	;;
 	ld8 r9=[sp]				// load new ar.unat
-	mov b7=r8
+	MOVBR(.sptk,b7,r8,ia64_leave_kernel)
 	;;
 	mov ar.unat=r9
 	br b7
-#else /* !CONFIG_IA64_NEW_UNWIND */
-	.regstk 0,0,3,0	// inherited from gate.s:invoke_sighandler()
-	PT_REGS_UNWIND_INFO(0)
-	UNW(.prologue)
-	UNW(.fframe IA64_PT_REGS_SIZE+IA64_SWITCH_STACK_SIZE)
-	UNW(.spillsp rp, PT(CR_IIP)+IA64_SWITCH_STACK_SIZE)
-	UNW(.spillsp ar.pfs, PT(CR_IFS)+IA64_SWITCH_STACK_SIZE)
-	UNW(.spillsp ar.unat, PT(AR_UNAT)+IA64_SWITCH_STACK_SIZE)
-	UNW(.spillsp pr, PT(PR)+IA64_SWITCH_STACK_SIZE)
-	adds sp=-IA64_SWITCH_STACK_SIZE,sp
-	cmp.eq pNonSys,p0=r0,r0			// sigreturn isn't a normal syscall...
-	;;
-	UNW(.body)
-
-	adds out0=16,sp				// out0 = &sigscratch
-	br.call.sptk.few rp=ia64_rt_sigreturn
-.ret20:	adds r3=IA64_SWITCH_STACK_CALLER_UNAT_OFFSET+16,sp
-	;;
-	ld8 r9=[r3]			// load new ar.unat
-	mov b7=r8
-	;;
-	PT_REGS_UNWIND_INFO(0)
-	adds sp=IA64_SWITCH_STACK_SIZE,sp	// drop (dummy) switch-stack frame
-	mov ar.unat=r9
-	br b7
-#endif /* !CONFIG_IA64_NEW_UNWIND */
 END(sys_rt_sigreturn)
 
 GLOBAL_ENTRY(ia64_prepare_handle_unaligned)
 	//
-	// r16 = fake ar.pfs, we simply need to make sure 
+	// r16 = fake ar.pfs, we simply need to make sure
 	// privilege is still 0
 	//
-	PT_REGS_UNWIND_INFO(0)
-	mov r16=r0 				
-	UNW(.prologue)
+	mov r16=r0
+	.prologue
 	DO_SAVE_SWITCH_STACK
 	br.call.sptk.few rp=ia64_handle_unaligned // stack frame setup in ivt
 .ret21:	.body
-	DO_LOAD_SWITCH_STACK(PT_REGS_UNWIND_INFO(0))
+	DO_LOAD_SWITCH_STACK
 	br.cond.sptk.many rp			  // goes to ia64_leave_kernel
 END(ia64_prepare_handle_unaligned)
 
-#ifdef CONFIG_IA64_NEW_UNWIND
-
 	//
 	// unw_init_running(void (*callback)(info, arg), void *arg)
 	//
@@ -1050,8 +992,6 @@
 	br.ret.sptk.many rp
 END(unw_init_running)
 
-#endif
-
 	.rodata
 	.align 8
 	.globl sys_call_table
@@ -1229,7 +1169,7 @@
 	data8 sys_accept
 	data8 sys_getsockname			// 1195
 	data8 sys_getpeername
-	data8 sys_socketpair 
+	data8 sys_socketpair
 	data8 sys_send
 	data8 sys_sendto
 	data8 sys_recv				// 1200
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/entry.h linux/arch/ia64/kernel/entry.h
--- v2.4.3/linux/arch/ia64/kernel/entry.h	Thu Jun 22 07:09:44 2000
+++ linux/arch/ia64/kernel/entry.h	Thu Apr  5 12:51:47 2001
@@ -1,65 +1,77 @@
+#include <linux/config.h>
+
+/* XXX fixme */
+#if defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_B1_SPECIFIC)
+# define MOVBR(type,br,gr,lbl)	mov br=gr
+#else
+# define MOVBR(type,br,gr,lbl)	mov##type br=gr,lbl
+#endif
+
 /*
  * Preserved registers that are shared between code in ivt.S and entry.S.  Be
  * careful not to step on these!
  */
 #define pKern		p2	/* will leave_kernel return to kernel-mode? */
+#define pUser		p3	/* will leave_kernel return to user-mode? */
 #define pSys		p4	/* are we processing a (synchronous) system call? */
 #define pNonSys		p5	/* complement of pSys */
 
-#define PT(f)		(IA64_PT_REGS_##f##_OFFSET + 16)
-#define SW(f)		(IA64_SWITCH_STACK_##f##_OFFSET + 16)
+#define PT(f)		(IA64_PT_REGS_##f##_OFFSET)
+#define SW(f)		(IA64_SWITCH_STACK_##f##_OFFSET)
 
-#define PT_REGS_SAVES(off)				\
-	UNW(.unwabi @svr4, 'i');			\
-	UNW(.fframe IA64_PT_REGS_SIZE+16+(off));	\
-	UNW(.spillsp rp, PT(CR_IIP)+(off));		\
-	UNW(.spillsp ar.pfs, PT(CR_IFS)+(off));		\
-	UNW(.spillsp ar.unat, PT(AR_UNAT)+(off));	\
-	UNW(.spillsp ar.fpsr, PT(AR_FPSR)+(off));	\
-	UNW(.spillsp pr, PT(PR)+(off));
+#define PT_REGS_SAVES(off)			\
+	.unwabi @svr4, 'i';			\
+	.fframe IA64_PT_REGS_SIZE+16+(off);	\
+	.spillsp rp, PT(CR_IIP)+16+(off);	\
+	.spillsp ar.pfs, PT(CR_IFS)+16+(off);	\
+	.spillsp ar.unat, PT(AR_UNAT)+16+(off);	\
+	.spillsp ar.fpsr, PT(AR_FPSR)+16+(off);	\
+	.spillsp pr, PT(PR)+16+(off);
 
 #define PT_REGS_UNWIND_INFO(off)		\
-	UNW(.prologue);				\
+	.prologue;				\
 	PT_REGS_SAVES(off);			\
-	UNW(.body)
+	.body
 
-#define SWITCH_STACK_SAVES(off)									  \
-	UNW(.savesp ar.unat,SW(CALLER_UNAT)+(off)); UNW(.savesp ar.fpsr,SW(AR_FPSR)+(off));	  \
-	UNW(.spillsp f2,SW(F2)+(off)); UNW(.spillsp f3,SW(F3)+(off));				  \
-	UNW(.spillsp f4,SW(F4)+(off)); UNW(.spillsp f5,SW(F5)+(off));				  \
-	UNW(.spillsp f16,SW(F16)+(off)); UNW(.spillsp f17,SW(F17)+(off));			  \
-	UNW(.spillsp f18,SW(F18)+(off)); UNW(.spillsp f19,SW(F19)+(off));			  \
-	UNW(.spillsp f20,SW(F20)+(off)); UNW(.spillsp f21,SW(F21)+(off));			  \
-	UNW(.spillsp f22,SW(F22)+(off)); UNW(.spillsp f23,SW(F23)+(off));			  \
-	UNW(.spillsp f24,SW(F24)+(off)); UNW(.spillsp f25,SW(F25)+(off));			  \
-	UNW(.spillsp f26,SW(F26)+(off)); UNW(.spillsp f27,SW(F27)+(off));			  \
-	UNW(.spillsp f28,SW(F28)+(off)); UNW(.spillsp f29,SW(F29)+(off));			  \
-	UNW(.spillsp f30,SW(F30)+(off)); UNW(.spillsp f31,SW(F31)+(off));			  \
-	UNW(.spillsp r4,SW(R4)+(off)); UNW(.spillsp r5,SW(R5)+(off));				  \
-	UNW(.spillsp r6,SW(R6)+(off)); UNW(.spillsp r7,SW(R7)+(off));				  \
-	UNW(.spillsp b0,SW(B0)+(off)); UNW(.spillsp b1,SW(B1)+(off));				  \
-	UNW(.spillsp b2,SW(B2)+(off)); UNW(.spillsp b3,SW(B3)+(off));				  \
-	UNW(.spillsp b4,SW(B4)+(off)); UNW(.spillsp b5,SW(B5)+(off));				  \
-	UNW(.spillsp ar.pfs,SW(AR_PFS)+(off)); UNW(.spillsp ar.lc,SW(AR_LC)+(off));		  \
-	UNW(.spillsp @priunat,SW(AR_UNAT)+(off));						  \
-	UNW(.spillsp ar.rnat,SW(AR_RNAT)+(off)); UNW(.spillsp ar.bspstore,SW(AR_BSPSTORE)+(off)); \
-	UNW(.spillsp pr,SW(PR)+(off))
+#define SWITCH_STACK_SAVES(off)							\
+	.savesp ar.unat,SW(CALLER_UNAT)+16+(off);				\
+	.savesp ar.fpsr,SW(AR_FPSR)+16+(off);					\
+	.spillsp f2,SW(F2)+16+(off); .spillsp f3,SW(F3)+16+(off);		\
+	.spillsp f4,SW(F4)+16+(off); .spillsp f5,SW(F5)+16+(off);		\
+	.spillsp f16,SW(F16)+16+(off); .spillsp f17,SW(F17)+16+(off);		\
+	.spillsp f18,SW(F18)+16+(off); .spillsp f19,SW(F19)+16+(off);		\
+	.spillsp f20,SW(F20)+16+(off); .spillsp f21,SW(F21)+16+(off);		\
+	.spillsp f22,SW(F22)+16+(off); .spillsp f23,SW(F23)+16+(off);		\
+	.spillsp f24,SW(F24)+16+(off); .spillsp f25,SW(F25)+16+(off);		\
+	.spillsp f26,SW(F26)+16+(off); .spillsp f27,SW(F27)+16+(off);		\
+	.spillsp f28,SW(F28)+16+(off); .spillsp f29,SW(F29)+16+(off);		\
+	.spillsp f30,SW(F30)+16+(off); .spillsp f31,SW(F31)+16+(off);		\
+	.spillsp r4,SW(R4)+16+(off); .spillsp r5,SW(R5)+16+(off);		\
+	.spillsp r6,SW(R6)+16+(off); .spillsp r7,SW(R7)+16+(off);		\
+	.spillsp b0,SW(B0)+16+(off); .spillsp b1,SW(B1)+16+(off);		\
+	.spillsp b2,SW(B2)+16+(off); .spillsp b3,SW(B3)+16+(off);		\
+	.spillsp b4,SW(B4)+16+(off); .spillsp b5,SW(B5)+16+(off);		\
+	.spillsp ar.pfs,SW(AR_PFS)+16+(off); .spillsp ar.lc,SW(AR_LC)+16+(off);	\
+	.spillsp @priunat,SW(AR_UNAT)+16+(off);					\
+	.spillsp ar.rnat,SW(AR_RNAT)+16+(off);					\
+	.spillsp ar.bspstore,SW(AR_BSPSTORE)+16+(off);				\
+	.spillsp pr,SW(PR)+16+(off))
 
 #define DO_SAVE_SWITCH_STACK			\
 	movl r28=1f;				\
 	;;					\
 	.fframe IA64_SWITCH_STACK_SIZE;		\
 	adds sp=-IA64_SWITCH_STACK_SIZE,sp;	\
-	mov b7=r28;				\
+	MOVBR(.ret.sptk,b7,r28,1f);		\
 	SWITCH_STACK_SAVES(0);			\
 	br.cond.sptk.many save_switch_stack;	\
 1:
 
-#define DO_LOAD_SWITCH_STACK(extra)		\
+#define DO_LOAD_SWITCH_STACK			\
 	movl r28=1f;				\
 	;;					\
-	mov b7=r28;				\
+	invala;					\
+	MOVBR(.ret.sptk,b7,r28,1f);		\
 	br.cond.sptk.many load_switch_stack;	\
-1:	UNW(.restore sp);			\
-	extra;					\
+1:	.restore sp;				\
 	adds sp=IA64_SWITCH_STACK_SIZE,sp
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/fw-emu.c linux/arch/ia64/kernel/fw-emu.c
--- v2.4.3/linux/arch/ia64/kernel/fw-emu.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/fw-emu.c	Thu Apr  5 12:51:47 2001
@@ -1,8 +1,8 @@
 /*
  * PAL & SAL emulation.
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * For the HP simulator, this file gets include in boot/bootloader.c.
  * For SoftSDV, this file gets included in sys_softsdv.c.
@@ -22,7 +22,8 @@
 
 #define NUM_MEM_DESCS	2
 
-static char fw_mem[(  sizeof(efi_system_table_t)
+static char fw_mem[(  sizeof(struct ia64_boot_param)
+		    + sizeof(efi_system_table_t)
 		    + sizeof(efi_runtime_services_t)
 		    + 1*sizeof(efi_config_table_t)
 		    + sizeof(struct ia64_sal_systab)
@@ -151,6 +152,14 @@
 	movl r10=0x100000100		/* bus_ratio<<32 (1/256) */
 	movl r11=0x100000064		/* itc_ratio<<32 (1/100) */
 	;;
+1:	cmp.eq p6,p7=19,r28		/* PAL_RSE_INFO */
+(p7)	br.cond.sptk.few 1f
+	mov r8=0			/* status = 0 */
+	mov r9=96			/* num phys stacked */
+	mov r10=0			/* hints */
+	mov r11=0
+	br.cond.sptk.few rp
+
 1:	cmp.eq p6,p7=1,r28		/* PAL_CACHE_FLUSH */
 (p7)	br.cond.sptk.few 1f
 	mov r9=ar.lc
@@ -168,8 +177,7 @@
 	;;
 	mov ar.lc=r9
 	mov r8=r0
-1:
-	br.cond.sptk.few rp
+1:	br.cond.sptk.few rp
 
 stacked:
 	br.ret.sptk.few rp
@@ -249,13 +257,7 @@
 			 * or something platform specific?  The SAL
 			 * doc ain't exactly clear on this...
 			 */
-#if defined(CONFIG_IA64_SOFTSDV_HACKS)
-			r9 =   4000000;
-#elif defined(CONFIG_IA64_SDV)
-			r9 = 300000000;
-#else
 			r9 = 700000000;
-#endif
 			break;
 
 		      case SAL_FREQ_BASE_REALTIME_CLOCK:
@@ -332,7 +334,7 @@
 	return (void *) addr;
 }
 
-void
+struct ia64_boot_param *
 sys_fw_init (const char *args, int arglen)
 {
 	efi_system_table_t *efi_systab;
@@ -358,6 +360,7 @@
 	sal_systab  = (void *) cp; cp += sizeof(*sal_systab);
 	sal_ed      = (void *) cp; cp += sizeof(*sal_ed);
 	efi_memmap  = (void *) cp; cp += NUM_MEM_DESCS*sizeof(*efi_memmap);
+	bp	    = (void *) cp; cp += sizeof(*bp);
 	cmd_line    = (void *) cp;
 
 	if (args) {
@@ -423,7 +426,7 @@
 	strcpy(sal_systab->product_id, "SN1");
 #endif
 
-	/* fill in an entry point: */	
+	/* fill in an entry point: */
 	sal_ed->type = SAL_DESC_ENTRY_POINT;
 	sal_ed->pal_proc = __pa(pal_desc[0]);
 	sal_ed->sal_proc = __pa(sal_desc[0]);
@@ -440,15 +443,15 @@
 	md->pad = 0;
 	md->phys_addr = 2*MB;
 	md->virt_addr = 0;
-	md->num_pages = (64*MB) >> 12;	/* 64MB (in 4KB pages) */
+	md->num_pages = (128*MB) >> 12;	/* 128MB (in 4KB pages) */
 	md->attribute = EFI_MEMORY_WB;
 
 	/* descriptor for firmware emulator: */
 	md = &efi_memmap[1];
-	md->type = EFI_RUNTIME_SERVICES_DATA;
+	md->type = EFI_PAL_CODE;
 	md->pad = 0;
 	md->phys_addr = 1*MB;
-	md->virt_addr = 0;
+	md->virt_addr = 1*MB;
 	md->num_pages = (1*MB) >> 12;	/* 1MB (in 4KB pages) */
 	md->attribute = EFI_MEMORY_WB;
 
@@ -468,7 +471,6 @@
 	md->attribute = EFI_MEMORY_WB;
 #endif
 
-	bp = id(ZERO_PAGE_ADDR);
 	bp->efi_systab = __pa(&fw_mem);
 	bp->efi_memmap = __pa(efi_memmap);
 	bp->efi_memmap_size = NUM_MEM_DESCS*sizeof(efi_memory_desc_t);
@@ -479,6 +481,7 @@
 	bp->console_info.num_rows = 25;
 	bp->console_info.orig_x = 0;
 	bp->console_info.orig_y = 24;
-	bp->num_pci_vectors = 0;
 	bp->fpswa = 0;
+
+	return bp;
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/gate.S linux/arch/ia64/kernel/gate.S
--- v2.4.3/linux/arch/ia64/kernel/gate.S	Fri Jul 14 16:08:11 2000
+++ linux/arch/ia64/kernel/gate.S	Thu Apr  5 12:51:47 2001
@@ -1,10 +1,9 @@
 /*
- * This file contains the code that gets mapped at the upper end of
- * each task's text region.  For now, it contains the signal
- * trampoline code only.
+ * This file contains the code that gets mapped at the upper end of each task's text
+ * region.  For now, it contains the signal trampoline code only.
  *
- * Copyright (C) 1999-2000 Hewlett-Packard Co
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2001 Hewlett-Packard Co
+ * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <asm/asmmacro.h>
@@ -14,11 +13,7 @@
 #include <asm/unistd.h>
 #include <asm/page.h>
 
-	.psr abi64
-	.psr lsb
-	.lsb
-
-	.section __gate_section,"ax"
+	.section .text.gate,"ax"
 
 	.align PAGE_SIZE
 
@@ -51,28 +46,24 @@
 	 *   |            space              |
 	 *   +-------------------------------+ <-- sp
 	 *
-	 * The register stack looks _exactly_ the way it looked at the
-	 * time the signal occurred.  In other words, we're treading
-	 * on a potential mine-field: each incoming general register
-	 * may be a NaT value (includeing sp, in which case the process
-	 * ends up dying with a SIGSEGV).
+	 * The register stack looks _exactly_ the way it looked at the time the signal
+	 * occurred.  In other words, we're treading on a potential mine-field: each
+	 * incoming general register may be a NaT value (including sp, in which case the
+	 * process ends up dying with a SIGSEGV).
 	 *
-	 * The first need to do is a cover to get the registers onto
-	 * the backing store.  Once that is done, we invoke the signal
-	 * handler which may modify some of the machine state.  After
-	 * returning from the signal handler, we return control to the
-	 * previous context by executing a sigreturn system call.  A
-	 * signal handler may call the rt_sigreturn() function to
-	 * directly return to a given sigcontext.  However, the
-	 * user-level sigreturn() needs to do much more than calling
-	 * the rt_sigreturn() system call as it needs to unwind the
-	 * stack to restore preserved registers that may have been
-	 * saved on the signal handler's call stack.
+	 * The first need to do is a cover to get the registers onto the backing store.
+	 * Once that is done, we invoke the signal handler which may modify some of the
+	 * machine state.  After returning from the signal handler, we return control to
+	 * the previous context by executing a sigreturn system call.  A signal handler
+	 * may call the rt_sigreturn() function to directly return to a given sigcontext.
+	 * However, the user-level sigreturn() needs to do much more than calling the
+	 * rt_sigreturn() system call as it needs to unwind the stack to restore preserved
+	 * registers that may have been saved on the signal handler's call stack.
 	 *
 	 * On entry:
 	 *	r2	= signal number
 	 *	r3	= plabel of signal handler
-	 *	r15	= new register backing store (ignored)
+	 *	r15	= new register backing store
 	 *	[sp+16] = sigframe
 	 */
 
@@ -153,7 +144,7 @@
 
 ENTRY(setup_rbs)
 	flushrs					// must be first in insn
-	mov ar.rsc=r0				// put RSE into enforced lazy mode
+	mov ar.rsc=0				// put RSE into enforced lazy mode
 	adds r16=(RNAT_OFF+SIGCONTEXT_OFF),sp
 	;;
 	mov r14=ar.rnat				// get rnat as updated by flushrs
@@ -167,7 +158,7 @@
 
 ENTRY(restore_rbs)
 	flushrs
-	mov ar.rsc=r0				// put RSE into enforced lazy mode
+	mov ar.rsc=0				// put RSE into enforced lazy mode
 	adds r16=(RNAT_OFF+SIGCONTEXT_OFF),sp
 	;;
 	ld8 r14=[r16]				// get new rnat
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/head.S linux/arch/ia64/kernel/head.S
--- v2.4.3/linux/arch/ia64/kernel/head.S	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/head.S	Thu Apr  5 12:51:47 2001
@@ -5,8 +5,9 @@
  * to set up the kernel's global pointer and jump to the kernel
  * entry point.
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 2001 Stephane Eranian <eranian@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  * Copyright (C) 1999 Intel Corp.
@@ -18,16 +19,15 @@
 
 #include <asm/asmmacro.h>
 #include <asm/fpu.h>
-#include <asm/pal.h>
+#include <asm/kregs.h>
+#include <asm/mmu_context.h>
 #include <asm/offsets.h>
+#include <asm/pal.h>
+#include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/ptrace.h>
 #include <asm/system.h>
 
-	.psr abi64
-	.psr lsb
-	.lsb
-
 	.section __special_page_section,"ax"
 
 	.global empty_zero_page
@@ -38,29 +38,66 @@
 swapper_pg_dir:
 	.skip PAGE_SIZE
 
-	.global empty_bad_page
-empty_bad_page:
-	.skip PAGE_SIZE
-
-	.global empty_bad_pte_table
-empty_bad_pte_table:
-	.skip PAGE_SIZE
-
-	.global empty_bad_pmd_table
-empty_bad_pmd_table:
-	.skip PAGE_SIZE
-
 	.rodata
 halt_msg:
 	stringz "Halting kernel\n"
 
 	.text
 
+	.global start_ap
+
+	/*
+	 * Start the kernel.  When the bootloader passes control to _start(), r28
+	 * points to the address of the boot parameter area.  Execution reaches
+	 * here in physical mode.
+	 */
 GLOBAL_ENTRY(_start)
-	UNW(.prologue)
-	UNW(.save rp, r4)		// terminate unwind chain with a NULL rp
-	UNW(mov r4=r0)
-	UNW(.body)
+start_ap:
+	.prologue
+	.save rp, r4		// terminate unwind chain with a NULL rp
+	mov r4=r0
+	.body
+
+	/*
+	 * Initialize the region register for region 7 and install a translation register
+	 * that maps the kernel's text and data:
+	 */
+	rsm psr.i | psr.ic
+	mov r16=((ia64_rid(IA64_REGION_ID_KERNEL, PAGE_OFFSET) << 8) | (_PAGE_SIZE_64M << 2))
+	;;
+	srlz.i
+	mov r18=_PAGE_SIZE_64M<<2
+	movl r17=PAGE_OFFSET + 64*1024*1024
+	;;
+	mov rr[r17]=r16
+	mov cr.itir=r18
+	mov cr.ifa=r17
+	mov r16=IA64_TR_KERNEL
+	movl r18=(64*1024*1024 | PAGE_KERNEL)
+	;;
+	srlz.i
+	;;
+	itr.i itr[r16]=r18
+	;;
+	itr.d dtr[r16]=r18
+	;;
+	srlz.i
+
+	/*
+	 * Switch into virtual mode:
+	 */
+	movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN)
+	;;
+	mov cr.ipsr=r16
+	movl r17=1f
+	;;
+	mov cr.iip=r17
+	mov cr.ifs=r0
+	;;
+	rfi
+	;;
+1:	// now we are in virtual mode
+
 	// set IVT entry point---can't access I/O ports without it
 	movl r3=ia64_ivt
 	;;
@@ -74,7 +111,7 @@
 	;;
 
 #ifdef CONFIG_IA64_EARLY_PRINTK
-	mov r3=(6<<8) | (28<<2)
+	mov r3=(6<<8) | (_PAGE_SIZE_64M<<2)
 	movl r2=6<<61
 	;;
 	mov rr[r2]=r3
@@ -83,27 +120,32 @@
 	;;
 #endif
 
-#define isAP	p2	// are we booting an Application Processor (not the BSP)?
+#define isAP	p2	// are we an Application Processor?
+#define isBP	p3	// are we the Bootstrap Processor?
 
-	// Find the init_task for the currently booting CPU.  At poweron, and in
-	// UP mode, cpu_now_booting is 0
+	/*
+	 * Find the init_task for the currently booting CPU.  At poweron, and in
+	 * UP mode, cpu_now_booting is 0.
+	 */
 	movl r3=cpu_now_booting
  	;;
-	ld4 r3=[r3]
+	ld4 r3=[r3]		// r3 <- smp_processor_id()
 	movl r2=init_tasks
-	;; 
+	;;
 	shladd r2=r3,3,r2
 	;;
 	ld8 r2=[r2]
-	cmp4.ne isAP,p0=r3,r0	// p9 == true if this is an application processor (ap)
+	cmp4.ne isAP,isBP=r3,r0
 	;;			// RAW on r2
 	extr r3=r2,0,61		// r3 == phys addr of task struct
 	;;
 
-	// load the "current" pointer (r13) and ar.k6 with the current task 
+	// load the "current" pointer (r13) and ar.k6 with the current task
 	mov r13=r2
-	mov ar.k6=r3		// Physical address
-	;;
+	mov IA64_KR(CURRENT)=r3		// Physical address
+
+	// initialize k4 to a safe value (64-128MB is mapped by TR_KERNEL)
+	mov IA64_KR(CURRENT_STACK)=1
 	/*
 	 * Reserve space at the top of the stack for "struct pt_regs".  Kernel threads
 	 * don't store interesting values in that structure, but the space still needs
@@ -113,14 +155,18 @@
 	 */
 	addl r12=IA64_STK_OFFSET-IA64_PT_REGS_SIZE-16,r2
 	addl r2=IA64_RBS_OFFSET,r2	// initialize the RSE
-	mov ar.rsc=r0		// place RSE in enforced lazy mode
+	mov ar.rsc=0		// place RSE in enforced lazy mode
 	;;
-	mov ar.bspstore=r2	// establish the new RSE stack
+	loadrs			// clear the dirty partition
 	;;
-	loadrs			// load zero bytes from the register stack
+	mov ar.bspstore=r2	// establish the new RSE stack
 	;;
 	mov ar.rsc=0x3		// place RSE in eager mode
+
+(isBP)	dep r28=-1,r28,61,3	// make address virtual
+(isBP)	movl r2=ia64_boot_param
 	;;
+(isBP)	st8 [r2]=r28		// save the address of the boot param area passed by the bootloader
 
 #ifdef CONFIG_IA64_EARLY_PRINTK
 	.rodata
@@ -135,16 +181,12 @@
 1:	// force new bundle
 #endif /* CONFIG_IA64_EARLY_PRINTK */
 
-	alloc r2=ar.pfs,8,0,2,0
-	;;
 #ifdef CONFIG_SMP
 (isAP)	br.call.sptk.few rp=smp_callin
 .ret0:
 (isAP)	br.cond.sptk.few self
 #endif
 
-#undef isAP
-
 	// This is executed by the bootstrap processor (bsp) only:
 
 #ifdef CONFIG_IA64_FW_EMU
@@ -153,9 +195,11 @@
 .ret1:
 #endif
 	br.call.sptk.few rp=start_kernel
-.ret2:	addl r2=@ltoff(halt_msg),gp
+.ret2:	addl r3=@ltoff(halt_msg),gp
+	;;
+	alloc r2=ar.pfs,8,0,2,0
 	;;
-	ld8 out0=[r2]
+	ld8 out0=[r3]
 	br.call.sptk.few b0=console_print
 self:	br.sptk.few self		// endless loop
 END(_start)
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/ia64_ksyms.c linux/arch/ia64/kernel/ia64_ksyms.c
--- v2.4.3/linux/arch/ia64/kernel/ia64_ksyms.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/ia64_ksyms.c	Thu Apr  5 12:51:47 2001
@@ -24,8 +24,11 @@
 EXPORT_SYMBOL(strstr);
 EXPORT_SYMBOL(strtok);
 
-#include <asm/hw_irq.h>
+#include <linux/irq.h>
 EXPORT_SYMBOL(isa_irq_to_vector_map);
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(disable_irq_nosync);
 
 #include <linux/in6.h>
 #include <asm/checksum.h>
@@ -40,10 +43,14 @@
 EXPORT_SYMBOL(__ia64_memcpy_toio);
 EXPORT_SYMBOL(__ia64_memset_c_io);
 
-#include <asm/irq.h>
-EXPORT_SYMBOL(enable_irq);
-EXPORT_SYMBOL(disable_irq);
-EXPORT_SYMBOL(disable_irq_nosync);
+#include <asm/semaphore.h>
+EXPORT_SYMBOL_NOVERS(__down);
+EXPORT_SYMBOL_NOVERS(__down_interruptible);
+EXPORT_SYMBOL_NOVERS(__down_trylock);
+EXPORT_SYMBOL_NOVERS(__up);
+EXPORT_SYMBOL_NOVERS(__down_read_failed);
+EXPORT_SYMBOL_NOVERS(__down_write_failed);
+EXPORT_SYMBOL_NOVERS(__rwsem_wake);
 
 #include <asm/page.h>
 EXPORT_SYMBOL(clear_page);
@@ -57,14 +64,20 @@
 EXPORT_SYMBOL(last_cli_ip);
 #endif
 
+#include <asm/pgalloc.h>
+
 #ifdef CONFIG_SMP
 
+EXPORT_SYMBOL(smp_flush_tlb_all);
+
 #include <asm/current.h>
 #include <asm/hardirq.h>
 EXPORT_SYMBOL(synchronize_irq);
 
 #include <asm/smp.h>
 EXPORT_SYMBOL(smp_call_function);
+EXPORT_SYMBOL(smp_call_function_single);
+EXPORT_SYMBOL(cpu_online_map);
 
 #include <linux/smp.h>
 EXPORT_SYMBOL(smp_num_cpus);
@@ -78,7 +91,11 @@
 EXPORT_SYMBOL(__global_save_flags);
 EXPORT_SYMBOL(__global_restore_flags);
 
-#endif
+#else /* !CONFIG_SMP */
+
+EXPORT_SYMBOL(__flush_tlb_all);
+
+#endif /* !CONFIG_SMP */
 
 #include <asm/uaccess.h>
 EXPORT_SYMBOL(__copy_user);
@@ -111,3 +128,12 @@
 
 extern unsigned long ia64_iobase;
 EXPORT_SYMBOL(ia64_iobase);
+
+#include <asm/pal.h>
+EXPORT_SYMBOL(ia64_pal_call_phys_stacked);
+EXPORT_SYMBOL(ia64_pal_call_phys_static);
+EXPORT_SYMBOL(ia64_pal_call_stacked);
+EXPORT_SYMBOL(ia64_pal_call_static);
+
+extern struct efi efi;
+EXPORT_SYMBOL(efi);
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/iosapic.c linux/arch/ia64/kernel/iosapic.c
--- v2.4.3/linux/arch/ia64/kernel/iosapic.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/iosapic.c	Thu Apr  5 12:51:47 2001
@@ -11,7 +11,7 @@
  * 00/04/19	D. Mosberger	Rewritten to mirror more closely the x86 I/O APIC code.
  *				In particular, we now have separate handlers for edge
  *				and level triggered interrupts.
- * 00/10/27	Asit Mallick, Goutham Rao <goutham.rao@intel.com> IRQ vector allocation 
+ * 00/10/27	Asit Mallick, Goutham Rao <goutham.rao@intel.com> IRQ vector allocation
  *				PCI to vector mapping, shared PCI interrupts.
  * 00/10/27	D. Mosberger	Document things a bit more to make them more understandable.
  *				Clean up much of the old IOSAPIC cruft.
@@ -79,27 +79,27 @@
 static struct iosapic_irq {
 	char *addr;			/* base address of IOSAPIC */
 	unsigned char base_irq;		/* first irq assigned to this IOSAPIC */
-        char pin;			/* IOSAPIC pin (-1 => not an IOSAPIC irq) */
-	unsigned char dmode 	: 3;	/* delivery mode (see iosapic.h) */
+	char pin;			/* IOSAPIC pin (-1 => not an IOSAPIC irq) */
+	unsigned char dmode	: 3;	/* delivery mode (see iosapic.h) */
 	unsigned char polarity	: 1;	/* interrupt polarity (see iosapic.h) */
 	unsigned char trigger	: 1;	/* trigger mode (see iosapic.h) */
-} iosapic_irq[NR_IRQS];
+} iosapic_irq[IA64_NUM_VECTORS];
 
 /*
  * Translate IOSAPIC irq number to the corresponding IA-64 interrupt vector.  If no
  * entry exists, return -1.
  */
-static int 
+static int
 iosapic_irq_to_vector (int irq)
 {
 	int vector;
 
-	for (vector = 0; vector < NR_IRQS; ++vector)
+	for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
 		if (iosapic_irq[vector].base_irq + iosapic_irq[vector].pin == irq)
 			return vector;
 	return -1;
 }
-		
+
 /*
  * Map PCI pin to the corresponding IA-64 interrupt vector.  If no such mapping exists,
  * return -1.
@@ -137,14 +137,8 @@
 		 (dmode << IOSAPIC_DELIVERY_SHIFT) |
 		 vector);
 
-#ifdef CONFIG_IA64_AZUSA_HACKS
-	/* set Flush Disable bit */
-	if (addr != (char *) 0xc0000000fec00000)
-		low32 |= (1 << 17);
-#endif
-
 	/* dest contains both id and eid */
-	high32 = (dest << IOSAPIC_DEST_SHIFT);	
+	high32 = (dest << IOSAPIC_DEST_SHIFT);
 
 	writel(IOSAPIC_RTE_HIGH(pin), addr + IOSAPIC_REG_SELECT);
 	writel(high32, addr + IOSAPIC_WINDOW);
@@ -158,16 +152,17 @@
 	/* do nothing... */
 }
 
-static void 
-mask_irq (unsigned int vector)
+static void
+mask_irq (unsigned int irq)
 {
 	unsigned long flags;
 	char *addr;
 	u32 low32;
 	int pin;
+	ia64_vector vec = irq_to_vector(irq);
 
-	addr = iosapic_irq[vector].addr;
-	pin = iosapic_irq[vector].pin;
+	addr = iosapic_irq[vec].addr;
+	pin = iosapic_irq[vec].pin;
 
 	if (pin < 0)
 		return;			/* not an IOSAPIC interrupt! */
@@ -183,16 +178,17 @@
 	spin_unlock_irqrestore(&iosapic_lock, flags);
 }
 
-static void 
-unmask_irq (unsigned int vector)
+static void
+unmask_irq (unsigned int irq)
 {
 	unsigned long flags;
 	char *addr;
 	u32 low32;
 	int pin;
+	ia64_vector vec = irq_to_vector(irq);
 
-	addr = iosapic_irq[vector].addr;
-	pin = iosapic_irq[vector].pin;
+	addr = iosapic_irq[vec].addr;
+	pin = iosapic_irq[vec].pin;
 	if (pin < 0)
 		return;			/* not an IOSAPIC interrupt! */
 
@@ -209,7 +205,7 @@
 
 
 static void
-iosapic_set_affinity (unsigned int vector, unsigned long mask)
+iosapic_set_affinity (unsigned int irq, unsigned long mask)
 {
 	printk("iosapic_set_affinity: not implemented yet\n");
 }
@@ -219,16 +215,18 @@
  */
 
 static unsigned int
-iosapic_startup_level_irq (unsigned int vector)
+iosapic_startup_level_irq (unsigned int irq)
 {
-	unmask_irq(vector);
+	unmask_irq(irq);
 	return 0;
 }
 
 static void
-iosapic_end_level_irq (unsigned int vector)
+iosapic_end_level_irq (unsigned int irq)
 {
-	writel(vector, iosapic_irq[vector].addr + IOSAPIC_EOI);
+	ia64_vector vec = irq_to_vector(irq);
+
+	writel(vec, iosapic_irq[vec].addr + IOSAPIC_EOI);
 }
 
 #define iosapic_shutdown_level_irq	mask_irq
@@ -252,9 +250,9 @@
  */
 
 static unsigned int
-iosapic_startup_edge_irq (unsigned int vector)
+iosapic_startup_edge_irq (unsigned int irq)
 {
-	unmask_irq(vector);
+	unmask_irq(irq);
 	/*
 	 * IOSAPIC simply drops interrupts pended while the
 	 * corresponding pin was masked, so we can't know if an
@@ -264,15 +262,16 @@
 }
 
 static void
-iosapic_ack_edge_irq (unsigned int vector)
+iosapic_ack_edge_irq (unsigned int irq)
 {
+	irq_desc_t *idesc = irq_desc(irq);
 	/*
 	 * Once we have recorded IRQ_PENDING already, we can mask the
 	 * interrupt for real. This prevents IRQ storms from unhandled
 	 * devices.
 	 */
-	if ((irq_desc[vector].status & (IRQ_PENDING|IRQ_DISABLED)) == (IRQ_PENDING|IRQ_DISABLED))
-		mask_irq(vector);
+	if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) == (IRQ_PENDING|IRQ_DISABLED))
+		mask_irq(irq);
 }
 
 #define iosapic_enable_edge_irq		unmask_irq
@@ -291,7 +290,7 @@
 };
 
 static unsigned int
-iosapic_version (char *addr) 
+iosapic_version (char *addr)
 {
 	/*
 	 * IOSAPIC Version Register return 32 bit structure like:
@@ -335,6 +334,7 @@
 {
 	struct hw_interrupt_type *irq_type;
 	int i, irq, max_pin, vector;
+	irq_desc_t *idesc;
 	unsigned int ver;
 	char *addr;
 	static int first_time = 1;
@@ -342,18 +342,18 @@
 	if (first_time) {
 		first_time = 0;
 
-		for (vector = 0; vector < NR_IRQS; ++vector)
+		for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
 			iosapic_irq[vector].pin = -1;	/* mark as unused */
 
-		/* 
+		/*
 		 * Fetch the PCI interrupt routing table:
 		 */
 #ifdef CONFIG_ACPI_KERNEL_CONFIG
 		acpi_cf_get_pci_vectors(&pci_irq.route, &pci_irq.num_routes);
 #else
 		pci_irq.route =
-			(struct pci_vector_struct *) __va(ia64_boot_param.pci_vectors);
-		pci_irq.num_routes = ia64_boot_param.num_pci_vectors;
+			(struct pci_vector_struct *) __va(ia64_boot_param->pci_vectors);
+		pci_irq.num_routes = ia64_boot_param->num_pci_vectors;
 #endif
 	}
 
@@ -361,8 +361,8 @@
 
 	ver = iosapic_version(addr);
 	max_pin = (ver >> 16) & 0xff;
-	
-	printk("IOSAPIC: version %x.%x, address 0x%lx, IRQs 0x%02x-0x%02x\n", 
+
+	printk("IOSAPIC: version %x.%x, address 0x%lx, IRQs 0x%02x-0x%02x\n",
 	       (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, base_irq, base_irq + max_pin);
 
 	if (base_irq == 0)
@@ -385,20 +385,20 @@
 			       irq, iosapic_irq[vector].base_irq + iosapic_irq[vector].pin,
 			       vector);
 #endif
-		  	irq_type = &irq_type_iosapic_edge;
-			if (irq_desc[vector].handler != irq_type) {
-				if (irq_desc[vector].handler != &no_irq_type)
+			irq_type = &irq_type_iosapic_edge;
+			idesc = irq_desc(vector);
+			if (idesc->handler != irq_type) {
+				if (idesc->handler != &no_irq_type)
 					printk("iosapic_init: changing vector 0x%02x from %s to "
-					       "%s\n", irq, irq_desc[vector].handler->typename,
+					       "%s\n", irq, idesc->handler->typename,
 					       irq_type->typename);
-				irq_desc[vector].handler = irq_type;
+				idesc->handler = irq_type;
 			}
 
 			/* program the IOSAPIC routing table: */
 			set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
 		}
 
-#ifndef CONFIG_IA64_SOFTSDV_HACKS
 	for (i = 0; i < pci_irq.num_routes; i++) {
 		irq = pci_irq.route[i].irq;
 
@@ -428,18 +428,17 @@
 		       iosapic_irq[vector].base_irq + iosapic_irq[vector].pin, vector);
 # endif
 		irq_type = &irq_type_iosapic_level;
-		if (irq_desc[vector].handler != irq_type){
-			if (irq_desc[vector].handler != &no_irq_type)
+		idesc = irq_desc(vector);
+		if (idesc->handler != irq_type){
+			if (idesc->handler != &no_irq_type)
 				printk("iosapic_init: changing vector 0x%02x from %s to %s\n",
-				       vector, irq_desc[vector].handler->typename,
-				       irq_type->typename);
-			irq_desc[vector].handler = irq_type;
+				       vector, idesc->handler->typename, irq_type->typename);
+			idesc->handler = irq_type;
 		}
 
 		/* program the IOSAPIC routing table: */
 		set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
 	}
-#endif /* !CONFIG_IA64_SOFTSDV_HACKS */
 }
 
 void
@@ -492,7 +491,7 @@
 		 * Nothing to fixup
 		 * Fix out-of-range IRQ numbers
 		 */
-		if (dev->irq >= NR_IRQS)
+		if (dev->irq >= IA64_NUM_VECTORS)
 			dev->irq = 15;	/* Spurious interrupts */
 	}
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/irq.c linux/arch/ia64/kernel/irq.c
--- v2.4.3/linux/arch/ia64/kernel/irq.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/ia64/kernel/irq.c	Thu Apr  5 12:51:47 2001
@@ -63,7 +63,7 @@
 /*
  * Controller mappings for all interrupt sources:
  */
-irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
+irq_desc_t _irq_desc[NR_IRQS] __cacheline_aligned =
 	{ [0 ... NR_IRQS-1] = { IRQ_DISABLED, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
 
 static void register_irq_proc (unsigned int irq);
@@ -131,6 +131,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	irq_desc_t *idesc;
 	char *p = buf;
 
 	p += sprintf(p, "           ");
@@ -139,8 +140,9 @@
 	*p++ = '\n';
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
-		action = irq_desc[i].action;
-		if (!action) 
+		idesc = irq_desc(i);
+		action = idesc->action;
+		if (!action)
 			continue;
 		p += sprintf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
@@ -150,7 +152,7 @@
 			p += sprintf(p, "%10u ",
 				kstat.irqs[cpu_logical_map(j)][i]);
 #endif
-		p += sprintf(p, " %14s", irq_desc[i].handler->typename);
+		p += sprintf(p, " %14s", idesc->handler->typename);
 		p += sprintf(p, "  %s", action->name);
 
 		for (action=action->next; action; action = action->next)
@@ -193,10 +195,10 @@
 	printk("\n%s, CPU %d:\n", str, cpu);
 	printk("irq:  %d [",irqs_running());
 	for(i=0;i < smp_num_cpus;i++)
-		printk(" %d",local_irq_count(i));
+		printk(" %d",irq_count(i));
 	printk(" ]\nbh:   %d [",spin_is_locked(&global_bh_lock) ? 1 : 0);
 	for(i=0;i < smp_num_cpus;i++)
-		printk(" %d",local_bh_count(i));
+		printk(" %d",bh_count(i));
 
 	printk(" ]\nStack dumps:");
 #if defined(__ia64__)
@@ -224,7 +226,7 @@
 		esp &= ~(THREAD_SIZE-1);
 		esp += sizeof(struct task_struct);
 		show_stack((void*)esp);
- 	}
+	}
 #else
 	You lose...
 #endif
@@ -232,7 +234,7 @@
 	show_stack(NULL);
 	printk("\n");
 }
-	
+
 #define MAXCOUNT 100000000
 
 /*
@@ -266,7 +268,7 @@
 # endif
 #endif
 
-static inline void wait_on_irq(int cpu)
+static inline void wait_on_irq(void)
 {
 	int count = MAXCOUNT;
 
@@ -278,7 +280,7 @@
 		 * already executing in one..
 		 */
 		if (!irqs_running())
-			if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock))
+			if (local_bh_count() || !spin_is_locked(&global_bh_lock))
 				break;
 
 		/* Duh, we have to loop. Release the lock to avoid deadlocks */
@@ -290,13 +292,13 @@
 				count = ~0;
 			}
 			__sti();
-			SYNC_OTHER_CORES(cpu);
+			SYNC_OTHER_CORES(smp_processor_id());
 			__cli();
 			if (irqs_running())
 				continue;
 			if (global_irq_lock)
 				continue;
-			if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock))
+			if (!local_bh_count() && spin_is_locked(&global_bh_lock))
 				continue;
 			if (!test_and_set_bit(0,&global_irq_lock))
 				break;
@@ -320,28 +322,28 @@
 	}
 }
 
-static inline void get_irqlock(int cpu)
+static inline void get_irqlock(void)
 {
 	if (test_and_set_bit(0,&global_irq_lock)) {
 		/* do we already hold the lock? */
-		if (cpu == global_irq_holder)
+		if (smp_processor_id() == global_irq_holder)
 			return;
 		/* Uhhuh.. Somebody else got it. Wait.. */
 		do {
 			do {
 			} while (test_bit(0,&global_irq_lock));
-		} while (test_and_set_bit(0,&global_irq_lock));		
+		} while (test_and_set_bit(0,&global_irq_lock));
 	}
-	/* 
+	/*
 	 * We also to make sure that nobody else is running
-	 * in an interrupt context. 
+	 * in an interrupt context.
 	 */
-	wait_on_irq(cpu);
+	wait_on_irq();
 
 	/*
 	 * Ok, finally..
 	 */
-	global_irq_holder = cpu;
+	global_irq_holder = smp_processor_id();
 }
 
 #define EFLAGS_IF_SHIFT 9
@@ -365,28 +367,24 @@
 #ifdef __ia64__
 	__save_flags(flags);
 	if (flags & IA64_PSR_I) {
-		int cpu = smp_processor_id();
 		__cli();
-		if (!local_irq_count(cpu))
-			get_irqlock(cpu);
+		if (!local_irq_count())
+			get_irqlock();
 	}
 #else
 	__save_flags(flags);
 	if (flags & (1 << EFLAGS_IF_SHIFT)) {
-		int cpu = smp_processor_id();
 		__cli();
-		if (!local_irq_count(cpu))
-			get_irqlock(cpu);
+		if (!local_irq_count())
+			get_irqlock();
 	}
 #endif
 }
 
 void __global_sti(void)
 {
-	int cpu = smp_processor_id();
-
-	if (!local_irq_count(cpu))
-		release_irqlock(cpu);
+	if (!local_irq_count())
+		release_irqlock(smp_processor_id());
 	__sti();
 }
 
@@ -414,7 +412,7 @@
 	retval = 2 + local_enabled;
 
 	/* check for global flags if we're not in an interrupt */
-	if (!local_irq_count(cpu)) {
+	if (!local_irq_count()) {
 		if (local_enabled)
 			retval = 1;
 		if (global_irq_holder == cpu)
@@ -456,9 +454,8 @@
 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);
+	local_irq_enter(irq);
 
 	status = 1;	/* Force the "do bottom halves" bit */
 
@@ -474,7 +471,7 @@
 		add_interrupt_randomness(irq);
 	__cli();
 
-	irq_exit(cpu, irq);
+	local_irq_exit(irq);
 
 	return status;
 }
@@ -483,11 +480,11 @@
  * Generic enable/disable code: this just calls
  * down into the PIC-specific version for the actual
  * hardware disable after having gotten the irq
- * controller lock. 
+ * controller lock.
  */
 void inline disable_irq_nosync(unsigned int irq)
 {
-	irq_desc_t *desc = irq_desc + irq;
+	irq_desc_t *desc = irq_desc(irq);
 	unsigned long flags;
 
 	spin_lock_irqsave(&desc->lock, flags);
@@ -507,17 +504,17 @@
 	disable_irq_nosync(irq);
 
 #ifdef CONFIG_SMP
-	if (!local_irq_count(smp_processor_id())) {
+	if (!local_irq_count()) {
 		do {
 			barrier();
-		} while (irq_desc[irq].status & IRQ_INPROGRESS);
+		} while (irq_desc(irq)->status & IRQ_INPROGRESS);
 	}
 #endif
 }
 
 void enable_irq(unsigned int irq)
 {
-	irq_desc_t *desc = irq_desc + irq;
+	irq_desc_t *desc = irq_desc(irq);
 	unsigned long flags;
 
 	spin_lock_irqsave(&desc->lock, flags);
@@ -541,26 +538,14 @@
 	spin_unlock_irqrestore(&desc->lock, flags);
 }
 
-void do_IRQ_per_cpu(unsigned long irq, struct pt_regs *regs)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	int cpu = smp_processor_id();
-
-	kstat.irqs[cpu][irq]++;
-
-	desc->handler->ack(irq);
-	handle_IRQ_event(irq, regs, desc->action);
-	desc->handler->end(irq);
-}
-
 /*
  * do_IRQ handles all normal device IRQ's (the special
  * SMP cross-CPU interrupts have their own specific
  * handlers).
  */
 unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
-{	
-	/* 
+{
+	/*
 	 * We ack quickly, we don't want the irq controller
 	 * thinking we're snobs just because some other CPU has
 	 * disabled global interrupts (we have already done the
@@ -571,75 +556,82 @@
 	 * handled by some other CPU. (or is disabled)
 	 */
 	int cpu = smp_processor_id();
-	irq_desc_t *desc = irq_desc + irq;
+	irq_desc_t *desc = irq_desc(irq);
 	struct irqaction * action;
 	unsigned int status;
 
 	kstat.irqs[cpu][irq]++;
-	spin_lock(&desc->lock);
-	desc->handler->ack(irq);
-	/*
-	   REPLAY is when Linux resends an IRQ that was dropped earlier
-	   WAITING is used by probe to mark irqs that are being tested
-	   */
-	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
-	status |= IRQ_PENDING; /* we _want_ to handle it */
 
-	/*
-	 * If the IRQ is disabled for whatever reason, we cannot
-	 * use the action we have.
-	 */
-	action = NULL;
-	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
-		action = desc->action;
-		status &= ~IRQ_PENDING; /* we commit to handling */
-		status |= IRQ_INPROGRESS; /* we are handling it */
-	}
-	desc->status = status;
+	if (desc->status & IRQ_PER_CPU) {
+		/* no locking required for CPU-local interrupts: */
+		desc->handler->ack(irq);
+		handle_IRQ_event(irq, regs, desc->action);
+		desc->handler->end(irq);
+	} else {
+		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 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;
+		/*
+		 * 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;
 
-	/*
-	 * 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 (;;) {
+		/*
+		 * 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);
-		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);
-
 	return 1;
 }
 
-int request_irq(unsigned int irq, 
+int request_irq(unsigned int irq,
 		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
+		unsigned long irqflags,
 		const char * devname,
 		void *dev_id)
 {
@@ -655,7 +647,7 @@
 	 */
 	if (irqflags & SA_SHIRQ) {
 		if (!dev_id)
-			printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
+			printk("Bad boy: %s called us without a dev_id!\n", devname);
 	}
 #endif
 
@@ -681,7 +673,7 @@
 		kfree(action);
 	return retval;
 }
-		
+
 void free_irq(unsigned int irq, void *dev_id)
 {
 	irq_desc_t *desc;
@@ -691,7 +683,7 @@
 	if (irq >= NR_IRQS)
 		return;
 
-	desc = irq_desc + irq;
+	desc = irq_desc(irq);
 	spin_lock_irqsave(&desc->lock,flags);
 	p = &desc->action;
 	for (;;) {
@@ -739,16 +731,16 @@
 	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. 
+	 * flush such a longstanding irq before considering it as spurious.
 	 */
 	for (i = NR_IRQS-1; i > 0; i--)  {
-		desc = irq_desc + i;
+		desc = irq_desc(i);
 
 		spin_lock_irq(&desc->lock);
-		if (!irq_desc[i].action) 
-			irq_desc[i].handler->startup(i);
+		if (!desc->action)
+			desc->handler->startup(i);
 		spin_unlock_irq(&desc->lock);
 	}
 
@@ -762,7 +754,7 @@
 	 * happened in the previous stage, it may have masked itself)
 	 */
 	for (i = NR_IRQS-1; i > 0; i--) {
-		desc = irq_desc + i;
+		desc = irq_desc(i);
 
 		spin_lock_irq(&desc->lock);
 		if (!desc->action) {
@@ -784,7 +776,7 @@
 	 */
 	val = 0;
 	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
+		irq_desc_t *desc = irq_desc(i);
 		unsigned int status;
 
 		spin_lock_irq(&desc->lock);
@@ -816,7 +808,7 @@
 
 	mask = 0;
 	for (i = 0; i < 16; i++) {
-		irq_desc_t *desc = irq_desc + i;
+		irq_desc_t *desc = irq_desc(i);
 		unsigned int status;
 
 		spin_lock_irq(&desc->lock);
@@ -846,7 +838,7 @@
 	nr_irqs = 0;
 	irq_found = 0;
 	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
+		irq_desc_t *desc = irq_desc(i);
 		unsigned int status;
 
 		spin_lock_irq(&desc->lock);
@@ -869,13 +861,12 @@
 	return irq_found;
 }
 
-/* this was setup_x86_irq but it seems pretty generic */
 int setup_irq(unsigned int irq, struct irqaction * new)
 {
 	int shared = 0;
 	unsigned long flags;
 	struct irqaction *old, **p;
-	irq_desc_t *desc = irq_desc + irq;
+	irq_desc_t *desc = irq_desc(irq);
 
 	/*
 	 * Some drivers like serial.c use request_irq() heavily,
@@ -986,7 +977,7 @@
 	int irq = (long) data, full_count = count, err;
 	unsigned long new_value;
 
-	if (!irq_desc[irq].handler->set_affinity)
+	if (!irq_desc(irq)->handler->set_affinity)
 		return -EIO;
 
 	err = parse_hex_value(buffer, count, &new_value);
@@ -1002,7 +993,7 @@
 #endif
 
 	irq_affinity[irq] = new_value;
-	irq_desc[irq].handler->set_affinity(irq, new_value);
+	irq_desc(irq)->handler->set_affinity(irq, new_value);
 
 	return full_count;
 }
@@ -1037,7 +1028,7 @@
 	struct proc_dir_entry *entry;
 	char name [MAX_NAMELEN];
 
-	if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type))
+	if (!root_irq_dir || (irq_desc(irq)->handler == &no_irq_type))
 		return;
 
 	memset(name, 0, MAX_NAMELEN);
@@ -1079,9 +1070,8 @@
 	 * Create entries for all existing IRQs.
 	 */
 	for (i = 0; i < NR_IRQS; i++) {
-		if (irq_desc[i].handler == &no_irq_type)
+		if (irq_desc(i)->handler == &no_irq_type)
 			continue;
 		register_irq_proc(i);
 	}
 }
-
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/irq_ia64.c linux/arch/ia64/kernel/irq_ia64.c
--- v2.4.3/linux/arch/ia64/kernel/irq_ia64.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/ia64/kernel/irq_ia64.c	Thu Apr  5 12:51:47 2001
@@ -39,7 +39,7 @@
 #define IRQ_DEBUG	0
 
 /* default base addr of IPI table */
-unsigned long ipi_base_addr = (__IA64_UNCACHED_OFFSET | IPI_DEFAULT_BASE_ADDR);	
+unsigned long ipi_base_addr = (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR);
 
 /*
  * Legacy IRQ to IA-64 vector translation table.
@@ -53,21 +53,23 @@
 int
 ia64_alloc_irq (void)
 {
-	static int next_irq = FIRST_DEVICE_IRQ;
+	static int next_irq = IA64_FIRST_DEVICE_VECTOR;
 
-	if (next_irq > LAST_DEVICE_IRQ)
+	if (next_irq > IA64_LAST_DEVICE_VECTOR)
 		/* XXX could look for sharable vectors instead of panic'ing... */
 		panic("ia64_alloc_irq: out of interrupt vectors!");
 	return next_irq++;
 }
 
+extern unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs);
+
 /*
  * That's where the IVT branches when we get an external
  * interrupt. This branches to the correct hardware IRQ handler via
  * function ptr.
  */
 void
-ia64_handle_irq (unsigned long vector, struct pt_regs *regs)
+ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
 {
 	unsigned long saved_tpr;
 
@@ -89,7 +91,7 @@
 			static unsigned char count;
 			static long last_time;
 
-			if (count > 5 && jiffies - last_time > 5*HZ)
+			if (jiffies - last_time > 5*HZ)
 				count = 0;
 			if (++count < 5) {
 				last_time = jiffies;
@@ -109,19 +111,10 @@
 	saved_tpr = ia64_get_tpr();
 	ia64_srlz_d();
 	do {
-		if (vector >= NR_IRQS) {
-			printk("handle_irq: invalid vector %lu\n", vector);
-			ia64_set_tpr(saved_tpr);
-			ia64_srlz_d();
-			return;
-		}
 		ia64_set_tpr(vector);
 		ia64_srlz_d();
 
-		if ((irq_desc[vector].status & IRQ_PER_CPU) != 0)
-			do_IRQ_per_cpu(vector, regs);
-		else
-			do_IRQ(vector, regs);
+		do_IRQ(local_vector_to_irq(vector), regs);
 
 		/*
 		 * Disable interrupts and send EOI:
@@ -130,7 +123,7 @@
 		ia64_set_tpr(saved_tpr);
 		ia64_eoi();
 		vector = ia64_get_ivr();
-	} while (vector != IA64_SPURIOUS_INT);
+	} while (vector != IA64_SPURIOUS_INT_VECTOR);
 }
 
 #ifdef CONFIG_SMP
@@ -144,33 +137,30 @@
 };
 #endif
 
+void
+register_percpu_irq (ia64_vector vec, struct irqaction *action)
+{
+	irq_desc_t *desc;
+	unsigned int irq;
+
+	for (irq = 0; irq < NR_IRQS; ++irq)
+		if (irq_to_vector(irq) == vec) {
+			desc = irq_desc(irq);
+			desc->status |= IRQ_PER_CPU;
+			desc->handler = &irq_type_ia64_sapic;
+			if (action)
+				setup_irq(irq, action);
+		}
+}
+
 void __init
 init_IRQ (void)
 {
-	/*
-	 * Disable all local interrupts
-	 */
-	ia64_set_itv(0, 1);
-	ia64_set_lrr0(0, 1);
-	ia64_set_lrr1(0, 1);
-
-	irq_desc[IA64_SPURIOUS_INT].handler = &irq_type_ia64_sapic;
+	register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
 #ifdef CONFIG_SMP
-	/* 
-	 * Configure the IPI vector and handler
-	 */
-	irq_desc[IPI_IRQ].status |= IRQ_PER_CPU;
-	irq_desc[IPI_IRQ].handler = &irq_type_ia64_sapic;
-	setup_irq(IPI_IRQ, &ipi_irqaction);
+	register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction);
 #endif
-
-	ia64_set_pmv(1 << 16);
-	ia64_set_cmcv(CMC_IRQ);			/* XXX fix me */
-
 	platform_irq_init();
-
-	/* clear TPR to enable all interrupt classes: */
-	ia64_set_tpr(0);
 }
 
 void
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/ivt.S linux/arch/ia64/kernel/ivt.S
--- v2.4.3/linux/arch/ia64/kernel/ivt.S	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/ivt.S	Thu Apr  5 12:51:47 2001
@@ -1,9 +1,9 @@
 /*
  * arch/ia64/kernel/ivt.S
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
  * Copyright (C) 1998, 1999 Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 1998-2000 David Mosberger <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 David Mosberger <davidm@hpl.hp.com>
  *
  * 00/08/23 Asit Mallick <asit.k.mallick@intel.com> TLB handling for SMP
  * 00/12/20 David Mosberger-Tang <davidm@hpl.hp.com> DTLB/ITLB handler now uses virtual PT.
@@ -14,7 +14,7 @@
  *
  * External interrupts only use 1 entry. All others are internal interrupts
  *
- * The first 20 entries of the table contain 64 bundles each while the 
+ * The first 20 entries of the table contain 64 bundles each while the
  * remaining 48 entries contain only 16 bundles each.
  *
  * The 64 bundles are used to allow inlining the whole handler for critical
@@ -22,7 +22,7 @@
  *
  *  For each entry, the comment is as follows:
  *
- * 		// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
+ *		// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
  *  entry offset ----/     /         /                  /          /
  *  entry number ---------/         /                  /          /
  *  size of the entry -------------/                  /          /
@@ -37,7 +37,9 @@
 
 #include <linux/config.h>
 
+#include <asm/asmmacro.h>
 #include <asm/break.h>
+#include <asm/kregs.h>
 #include <asm/offsets.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -45,6 +47,22 @@
 #include <asm/system.h>
 #include <asm/unistd.h>
 
+#if 1
+# define PSR_DEFAULT_BITS	psr.ac
+#else
+# define PSR_DEFAULT_BITS	0
+#endif
+
+#if 0
+  /*
+   * This lets you track the last eight faults that occurred on the CPU.  Make sure ar.k2 isn't
+   * needed for something else before enabling this...
+   */
+# define DBG_FAULT(i)	mov r16=ar.k2;;	shl r16=r16,8;;	add r16=(i),r16;;mov ar.k2=r16
+#else
+# define DBG_FAULT(i)
+#endif
+
 #define MINSTATE_VIRT	/* needed by minstate.h */
 #include "minstate.h"
 
@@ -57,8 +75,8 @@
  * As we don't (hopefully) use the space available, we need to fill it with
  * nops. the parameter may be used for debugging and is representing the entry
  * number
- */ 
-#define BREAK_BUNDLE(a) 	break.m (a); \
+ */
+#define BREAK_BUNDLE(a)	break.m (a); \
 				break.i (a); \
 				break.i (a)
 /*
@@ -71,17 +89,15 @@
  */
 #define BREAK_BUNDLE8(a); BREAK_BUNDLE4(a); BREAK_BUNDLE4(a)
 
-	.psr abi64
-	.psr lsb
-	.lsb
-
-	.section __ivt_section,"ax"
+	.section .text.ivt,"ax"
 
 	.align 32768	// align on 32KB boundary
 	.global ia64_ivt
 ia64_ivt:
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47)
+ENTRY(vhpt_miss)
+	DBG_FAULT(0)
 	/*
 	 * The VHPT vector is invoked when the TLB entry for the virtual page table
 	 * is missing.  This happens only as a result of a previous
@@ -103,7 +119,7 @@
 	;;
 	rsm psr.dt				// use physical addressing for data
 	mov r31=pr				// save the predicate registers
-	mov r19=ar.k7				// get page table base address
+	mov r19=IA64_KR(PT_BASE)		// get page table base address
 	shl r21=r16,3				// shift bit 60 into sign bit
 	shr.u r17=r16,61			// get the region number into r17
 	;;
@@ -146,19 +162,21 @@
 (p6)	br.spnt.many page_fault			// handle bad address/page not present (page fault)
 	mov cr.ifa=r22
 
-	// Now compute and insert the TLB entry for the virtual page table.
-	// We never execute in a page table page so there is no need to set
-	// the exception deferral bit.
+	/*
+	 * Now compute and insert the TLB entry for the virtual page table.  We never
+	 * execute in a page table page so there is no need to set the exception deferral
+	 * bit.
+	 */
 	adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23
 	;;
 (p7)	itc.d r24
 	;;
 #ifdef CONFIG_SMP
-	//
-	// Re-check L2 and L3 pagetable.  If they changed, we may have received
-	// a ptc.g between reading the pagetable and the "itc".  If so,
-	// flush the entry we inserted and retry.
-	//
+	/*
+	 * Re-check L2 and L3 pagetable.  If they changed, we may have received a ptc.g
+	 * between reading the pagetable and the "itc".  If so, flush the entry we
+	 * inserted and retry.
+	 */
 	ld8 r25=[r21]				// read L3 PTE again
 	ld8 r26=[r17]				// read L2 entry again
 	;;
@@ -173,26 +191,29 @@
 
 	mov pr=r31,-1				// restore predicate registers
 	rfi
-	;;
+END(vhpt_miss)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x0400 Entry 1 (size 64 bundles) ITLB (21)
+ENTRY(itlb_miss)
+	DBG_FAULT(1)
 	/*
 	 * The ITLB handler accesses the L3 PTE via the virtually mapped linear
 	 * page table.  If a nested TLB miss occurs, we switch into physical
 	 * mode, walk the page table, and then re-execute the L3 PTE read
 	 * and go on normally after that.
 	 */
-itlb_fault:
 	mov r16=cr.ifa				// get virtual address
 	mov r29=b0				// save b0
 	mov r31=pr				// save predicates
+itlb_fault:
 	mov r17=cr.iha				// get virtual address of L3 PTE
 	movl r30=1f				// load nested fault continuation point
 	;;
 1:	ld8 r18=[r17]				// read L3 PTE
 	;;
+	mov b0=r29
 	tbit.z p6,p0=r18,_PAGE_P_BIT		// page present bit cleared?
 (p6)	br.cond.spnt.many page_fault
 	;;
@@ -208,26 +229,29 @@
 #endif
 	mov pr=r31,-1
 	rfi
-	;;
+END(itlb_miss)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x0800 Entry 2 (size 64 bundles) DTLB (9,48)
+ENTRY(dtlb_miss)
+	DBG_FAULT(2)
 	/*
 	 * The DTLB handler accesses the L3 PTE via the virtually mapped linear
 	 * page table.  If a nested TLB miss occurs, we switch into physical
 	 * mode, walk the page table, and then re-execute the L3 PTE read
 	 * and go on normally after that.
 	 */
-dtlb_fault:
 	mov r16=cr.ifa				// get virtual address
 	mov r29=b0				// save b0
 	mov r31=pr				// save predicates
+dtlb_fault:
 	mov r17=cr.iha				// get virtual address of L3 PTE
 	movl r30=1f				// load nested fault continuation point
 	;;
 1:	ld8 r18=[r17]				// read L3 PTE
 	;;
+	mov b0=r29
 	tbit.z p6,p0=r18,_PAGE_P_BIT		// page present bit cleared?
 (p6)	br.cond.spnt.many page_fault
 	;;
@@ -243,24 +267,27 @@
 #endif
 	mov pr=r31,-1
 	rfi
-	;;
+END(dtlb_miss)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
+ENTRY(alt_itlb_miss)
+	DBG_FAULT(3)
 	mov r16=cr.ifa		// get address that caused the TLB miss
-	movl r17=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RWX
+	movl r17=PAGE_KERNEL
 	mov r21=cr.ipsr
 	mov r31=pr
 	;;
 #ifdef CONFIG_DISABLE_VHPT
 	shr.u r22=r16,61			// get the region number into r21
 	;;
-	cmp.gt p8,p0=6,r22			// user mode 
+	cmp.gt p8,p0=6,r22			// user mode
 	;;
 (p8)	thash r17=r16
 	;;
 (p8)	mov cr.iha=r17
+(p8)	mov r29=b0				// save b0
 (p8)	br.cond.dptk.many itlb_fault
 #endif
 	extr.u r23=r21,IA64_PSR_CPL0_BIT,2	// extract psr.cpl
@@ -277,13 +304,15 @@
 	itc.i r19		// insert the TLB entry
 	mov pr=r31,-1
 	rfi
-	;;
+END(alt_itlb_miss)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
+ENTRY(alt_dtlb_miss)
+	DBG_FAULT(4)
 	mov r16=cr.ifa		// get address that caused the TLB miss
-	movl r17=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RWX
+	movl r17=PAGE_KERNEL
 	mov r20=cr.isr
 	mov r21=cr.ipsr
 	mov r31=pr
@@ -296,6 +325,7 @@
 (p8)	thash r17=r16
 	;;
 (p8)	mov cr.iha=r17
+(p8)	mov r29=b0				// save b0
 (p8)	br.cond.dptk.many dtlb_fault
 #endif
 	extr.u r23=r21,IA64_PSR_CPL0_BIT,2	// extract psr.cpl
@@ -316,70 +346,63 @@
 (p7)	itc.d r19		// insert the TLB entry
 	mov pr=r31,-1
 	rfi
-	;;
+END(alt_dtlb_miss)
 
 	//-----------------------------------------------------------------------------------
 	// call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address)
-page_fault:
+ENTRY(page_fault)
 	ssm psr.dt
 	;;
 	srlz.i
 	;;
 	SAVE_MIN_WITH_COVER
-	//
-	// Copy control registers to temporary registers, then turn on psr bits,
-	// then copy the temporary regs to the output regs.  We have to do this
-	// because the "alloc" can cause a mandatory store which could lead to
-	// an "Alt DTLB" fault which we can handle only if psr.ic is on.
-	//
-	mov r8=cr.ifa
-	mov r9=cr.isr
+	alloc r15=ar.pfs,0,0,3,0
+	mov out0=cr.ifa
+	mov out1=cr.isr
 	adds r3=8,r2				// set up second base pointer
 	;;
-	ssm psr.ic
+	ssm psr.ic | PSR_DEFAULT_BITS
 	;;
 	srlz.i					// guarantee that interrupt collection is enabled
 	;;
 (p15)	ssm psr.i				// restore psr.i
 	movl r14=ia64_leave_kernel
 	;;
-	alloc r15=ar.pfs,0,0,3,0		// must be first in insn group
-	mov out0=r8
-	mov out1=r9
-	;;
 	SAVE_REST
 	mov rp=r14
 	;;
 	adds out2=16,r12			// out2 = pointer to pt_regs
 	br.call.sptk.many b6=ia64_do_page_fault	// ignore return address
-	;;
+END(page_fault)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45)
-	//
-	// In the absence of kernel bugs, we get here when the virtually mapped linear page
-	// table is accessed non-speculatively (e.g.,  in the Dirty-bit, Instruction
-	// Access-bit, or Data Access-bit faults).  If the DTLB entry for the virtual page
-	// table is missing, a nested TLB miss fault is triggered and control is transferred
-	// to this point.  When this happens, we lookup the pte for the faulting address
-	// by walking the page table in physical mode and return to the continuation point
-	// passed in register r30 (or call page_fault if the address is not mapped).
-	//
-	// Input:	r16:	faulting address
-	//		r29:	saved b0
-	//		r30:	continuation address
-	//		r31:	saved pr
-	//
-	// Output:	r17:	physical address of L3 PTE of faulting address
-	//		r29:	saved b0
-	//		r30:	continuation address
-	//		r31:	saved pr
-	//
-	// Clobbered:	b0, r18, r19, r21, psr.dt (cleared)
-	//
+ENTRY(nested_dtlb_miss)
+	/*
+	 * In the absence of kernel bugs, we get here when the virtually mapped linear
+	 * page table is accessed non-speculatively (e.g., in the Dirty-bit, Instruction
+	 * Access-bit, or Data Access-bit faults).  If the DTLB entry for the virtual page
+	 * table is missing, a nested TLB miss fault is triggered and control is
+	 * transferred to this point.  When this happens, we lookup the pte for the
+	 * faulting address by walking the page table in physical mode and return to the
+	 * continuation point passed in register r30 (or call page_fault if the address is
+	 * not mapped).
+	 *
+	 * Input:	r16:	faulting address
+	 *		r29:	saved b0
+	 *		r30:	continuation address
+	 *		r31:	saved pr
+	 *
+	 * Output:	r17:	physical address of L3 PTE of faulting address
+	 *		r29:	saved b0
+	 *		r30:	continuation address
+	 *		r31:	saved pr
+	 *
+	 * Clobbered:	b0, r18, r19, r21, psr.dt (cleared)
+	 */
 	rsm psr.dt				// switch to using physical data addressing
-	mov r19=ar.k7				// get the page table base address
+	mov r19=IA64_KR(PT_BASE)		// get the page table base address
 	shl r21=r16,3				// shift bit 60 into sign bit
 	;;
 	shr.u r17=r16,61			// get the region number into r17
@@ -399,7 +422,6 @@
 	shr.u r18=r16,PMD_SHIFT			// shift L2 index into position
 	;;
 	ld8 r17=[r17]				// fetch the L1 entry (may be 0)
-	mov b0=r30
 	;;
 (p7)	cmp.eq p6,p7=r17,r0			// was L1 entry NULL?
 	dep r17=r18,r17,3,(PAGE_SHIFT-3)	// compute address of L2 page table entry
@@ -409,34 +431,41 @@
 	;;
 (p7)	cmp.eq.or.andcm p6,p7=r17,r0		// was L2 entry NULL?
 	dep r17=r19,r17,3,(PAGE_SHIFT-3)	// compute address of L3 page table entry
-	;;
 (p6)	br.cond.spnt.many page_fault
+	mov b0=r30
 	br.sptk.many b0				// return to continuation point
-	;;
+END(nested_dtlb_miss)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24)
+ENTRY(ikey_miss)
+	DBG_FAULT(6)
 	FAULT(6)
+END(ikey_miss)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51)
+ENTRY(dkey_miss)
+	DBG_FAULT(7)
 	FAULT(7)
+END(dkey_miss)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54)
-	//
-	// What we do here is to simply turn on the dirty bit in the PTE.  We need
-	// to update both the page-table and the TLB entry.  To efficiently access
-	// the PTE, we address it through the virtual page table.  Most likely, the
-	// TLB entry for the relevant virtual page table page is still present in
-	// the TLB so we can normally do this without additional TLB misses.
-	// In case the necessary virtual page table TLB entry isn't present, we take
-	// a nested TLB miss hit where we look up the physical address of the L3 PTE
-	// and then continue at label 1 below.
-	//
+ENTRY(dirty_bit)
+	DBG_FAULT(8)
+	/*
+	 * What we do here is to simply turn on the dirty bit in the PTE.  We need to
+	 * update both the page-table and the TLB entry.  To efficiently access the PTE,
+	 * we address it through the virtual page table.  Most likely, the TLB entry for
+	 * the relevant virtual page table page is still present in the TLB so we can
+	 * normally do this without additional TLB misses.  In case the necessary virtual
+	 * page table TLB entry isn't present, we take a nested TLB miss hit where we look
+	 * up the physical address of the L3 PTE and then continue at label 1 below.
+	 */
 	mov r16=cr.ifa				// get the address that caused the fault
 	movl r30=1f				// load continuation point in case of nested fault
 	;;
@@ -477,11 +506,13 @@
 #endif
 	mov pr=r31,-1				// restore pr
 	rfi
-	;;
+END(idirty_bit)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27)
+ENTRY(iaccess_bit)
+	DBG_FAULT(9)
 	// Like Entry 8, except for instruction access
 	mov r16=cr.ifa				// get the address that caused the fault
 	movl r30=1f				// load continuation point in case of nested fault
@@ -504,14 +535,14 @@
 	mov r28=ar.ccv				// save ar.ccv
 	;;
 1:	ld8 r18=[r17]
+	;;
 # if defined(CONFIG_IA32_SUPPORT) && \
     (defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_B0_SPECIFIC))
-	//
-	// Erratum 85 (Access bit fault could be reported before page not present fault)
-	//   If the PTE is indicates the page is not present, then just turn this into a
-	//   page fault.
-	//
-	;;
+	/*
+	 * Erratum 85 (Access bit fault could be reported before page not present fault)
+	 *   If the PTE is indicates the page is not present, then just turn this into a
+	 *   page fault.
+	 */
 	tbit.z p6,p0=r18,_PAGE_P_BIT		// page present bit cleared?
 (p6)	br.sptk page_fault			// page wasn't present
 # endif
@@ -538,11 +569,11 @@
 	;;
 # if defined(CONFIG_IA32_SUPPORT) && \
     (defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_B0_SPECIFIC))
-	//
-	// Erratum 85 (Access bit fault could be reported before page not present fault)
-	//   If the PTE is indicates the page is not present, then just turn this into a
-	//   page fault.
-	//
+	/*
+	 * Erratum 85 (Access bit fault could be reported before page not present fault)
+	 *   If the PTE is indicates the page is not present, then just turn this into a
+	 *   page fault.
+	 */
 	tbit.z p6,p0=r18,_PAGE_P_BIT		// page present bit cleared?
 (p6)	br.sptk page_fault			// page wasn't present
 # endif
@@ -554,11 +585,13 @@
 #endif /* !CONFIG_SMP */
 	mov pr=r31,-1
 	rfi
-	;;
+END(iaccess_bit)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55)
+ENTRY(daccess_bit)
+	DBG_FAULT(10)
 	// Like Entry 8, except for data access
 	mov r16=cr.ifa				// get the address that caused the fault
 	movl r30=1f				// load continuation point in case of nested fault
@@ -599,11 +632,13 @@
 	mov b0=r29				// restore b0
 	mov pr=r31,-1
 	rfi
-	;;
+END(daccess_bit)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x2c00 Entry 11 (size 64 bundles) Break instruction (33)
+ENTRY(break_fault)
+	DBG_FAULT(11)
 	mov r16=cr.iim
 	mov r17=__IA64_BREAK_SYSCALL
 	mov r31=pr		// prepare to save predicates
@@ -613,8 +648,7 @@
 
 	SAVE_MIN				// uses r31; defines r2:
 
-	// turn interrupt collection back on:
-	ssm psr.ic
+	ssm psr.ic | PSR_DEFAULT_BITS
 	;;
 	srlz.i					// guarantee that interrupt collection is enabled
 	cmp.eq pSys,pNonSys=r0,r0		// set pSys=1, pNonSys=0
@@ -667,12 +701,12 @@
 	;;
 	st8 [r16]=r18				// store new value for cr.isr
 
-(p8)	br.call.sptk.many b6=b6			// ignore this return addr 
+(p8)	br.call.sptk.many b6=b6			// ignore this return addr
 	br.call.sptk.many rp=ia64_trace_syscall	// rp will be overwritten (ignored)
 	// NOT REACHED
+END(break_fault)
 
-	.proc demine_args
-demine_args:
+ENTRY(demine_args)
 	alloc r2=ar.pfs,8,0,0,0
 	tnat.nz p8,p0=in0
 	tnat.nz p9,p0=in1
@@ -696,16 +730,18 @@
 (p14)	mov in6=-1
 (p15)	mov in7=-1
 	br.ret.sptk.many rp
-	.endp demine_args
+END(demine_args)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
+ENTRY(interrupt)
+	DBG_FAULT(12)
 	mov r31=pr		// prepare to save predicates
 	;;
 
 	SAVE_MIN_WITH_COVER	// uses r31; defines r2 and r3
-	ssm psr.ic		// turn interrupt collection
+	ssm psr.ic | PSR_DEFAULT_BITS
 	;;
 	adds r3=8,r2		// set up second base pointer for SAVE_REST
 	srlz.i			// ensure everybody knows psr.ic is back on
@@ -721,41 +757,38 @@
 	;;
 	mov rp=r14
 	br.call.sptk.many b6=ia64_handle_irq
-	;;
+END(interrupt)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x3400 Entry 13 (size 64 bundles) Reserved
+	DBG_FAULT(13)
 	FAULT(13)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x3800 Entry 14 (size 64 bundles) Reserved
+	DBG_FAULT(14)
 	FAULT(14)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x3c00 Entry 15 (size 64 bundles) Reserved
+	DBG_FAULT(15)
 	FAULT(15)
 
-//
-//  Squatting in this space ...
-//
-//  This special case dispatcher for illegal operation faults
-//  allows preserved registers to be modified through a 
-//  callback function (asm only) that is handed back from
-//  the fault handler in r8. Up to three arguments can be
-//  passed to the callback function by returning an aggregate
-//  with the callback as its first element, followed by the
-//  arguments.
-//
-dispatch_illegal_op_fault:
+	/*
+	 * Squatting in this space ...
+	 *
+	 * This special case dispatcher for illegal operation faults allows preserved
+	 * registers to be modified through a callback function (asm only) that is handed
+	 * back from the fault handler in r8. Up to three arguments can be passed to the
+	 * callback function by returning an aggregate with the callback as its first
+	 * element, followed by the arguments.
+	 */
+ENTRY(dispatch_illegal_op_fault)
 	SAVE_MIN_WITH_COVER
-	//
-	// The "alloc" can cause a mandatory store which could lead to
-	// an "Alt DTLB" fault which we can handle only if psr.ic is on.
-	//
-	ssm psr.ic
+	ssm psr.ic | PSR_DEFAULT_BITS
 	;;
 	srlz.i		// guarantee that interrupt collection is enabled
 	;;
@@ -781,27 +814,30 @@
 	cmp.ne p6,p0=0,r8
 (p6)	br.call.dpnt b6=b6		// call returns to ia64_leave_kernel
 	br.sptk ia64_leave_kernel
-	;;
+END(dispatch_illegal_op_fault)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4000 Entry 16 (size 64 bundles) Reserved
+	DBG_FAULT(16)
 	FAULT(16)
 
 #ifdef CONFIG_IA32_SUPPORT
 
-	// There is no particular reason for this code to be here, other than that
-	// there happens to be space here that would go unused otherwise.  If this
-	// fault ever gets "unreserved", simply moved the following code to a more
-	// suitable spot...
+	/*
+	 * There is no particular reason for this code to be here, other than that
+	 * there happens to be space here that would go unused otherwise.  If this
+	 * fault ever gets "unreserved", simply moved the following code to a more
+	 * suitable spot...
+	 */
 
 	// IA32 interrupt entry point
 
-dispatch_to_ia32_handler:
+ENTRY(dispatch_to_ia32_handler)
 	SAVE_MIN
 	;;
 	mov r14=cr.isr
-	ssm psr.ic
+	ssm psr.ic | PSR_DEFAULT_BITS
 	;;
 	srlz.i					// guarantee that interrupt collection is enabled
 	;;
@@ -812,7 +848,7 @@
 	;;
 	mov r15=0x80
 	shr r14=r14,16          // Get interrupt number
-	;; 
+	;;
 	cmp.ne p6,p0=r14,r15
 (p6)    br.call.dpnt.many b6=non_ia32_syscall
 
@@ -823,7 +859,7 @@
 	st8 [r15]=r8		// save orignal EAX in r1 (IA32 procs don't use the GP)
 	;;
 	alloc r15=ar.pfs,0,0,6,0	// must first in an insn group
-	;; 
+	;;
 	ld4 r8=[r14],8          // r8 == EAX (syscall number)
 	mov r15=222		// sys_vfork - last implemented system call
 	;;
@@ -842,10 +878,10 @@
 	;;
 	ld4 out4=[r14]           // R15 == edi
 	movl r16=ia32_syscall_table
-	;; 
+	;;
 (p6)    shladd r16=r8,3,r16     // Force ni_syscall if not valid syscall number
 	ld8 r2=[r2]		// r2 = current->ptrace
-	;; 
+	;;
 	ld8 r16=[r16]
 	tbit.z p8,p0=r2,PT_TRACESYS_BIT	// (current->ptrace & PT_TRACESYS) == 0?
 	;;
@@ -857,7 +893,7 @@
 	;;
 	br.call.sptk.many rp=ia32_trace_syscall	// rp will be overwritten (ignored)
 
-non_ia32_syscall:       
+non_ia32_syscall:
 	alloc r15=ar.pfs,0,0,2,0
 	mov out0=r14                            // interrupt #
 	add out1=16,sp                          // pointer to pt_regs
@@ -867,16 +903,17 @@
 	;;
 	mov rp=r15
 	br.ret.sptk.many rp
-	;;
+END(dispatch_to_ia32_handler)
 
 #endif /* CONFIG_IA32_SUPPORT */
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4400 Entry 17 (size 64 bundles) Reserved
+	DBG_FAULT(17)
 	FAULT(17)
 
-non_syscall:
+ENTRY(non_syscall)
 	SAVE_MIN_WITH_COVER
 
 	// There is no particular reason for this code to be here, other than that
@@ -884,49 +921,45 @@
 	// fault ever gets "unreserved", simply moved the following code to a more
 	// suitable spot...
 
-	mov r8=cr.iim			// get break immediate (must be done while psr.ic is off)
+	alloc r14=ar.pfs,0,0,2,0
+	mov out0=cr.iim
+	add out1=16,sp
 	adds r3=8,r2			// set up second base pointer for SAVE_REST
 
-	// turn interrupt collection back on:
-	ssm psr.ic
+	ssm psr.ic | PSR_DEFAULT_BITS
 	;;
 	srlz.i				// guarantee that interrupt collection is enabled
 	;;
 (p15)	ssm psr.i			// restore psr.i
 	movl r15=ia64_leave_kernel
 	;;
-	alloc r14=ar.pfs,0,0,2,0
-	mov out0=r8			// break number
-	add out1=16,sp			// pointer to pt_regs
-	;;
 	SAVE_REST
 	mov rp=r15
 	;;
 	br.call.sptk.many b6=ia64_bad_break	// avoid WAW on CFM and ignore return addr
-	;;
+END(non_syscall)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4800 Entry 18 (size 64 bundles) Reserved
+	DBG_FAULT(18)
 	FAULT(18)
 
-	// There is no particular reason for this code to be here, other than that
-	// there happens to be space here that would go unused otherwise.  If this
-	// fault ever gets "unreserved", simply moved the following code to a more
-	// suitable spot...
+	/*
+	 * There is no particular reason for this code to be here, other than that
+	 * there happens to be space here that would go unused otherwise.  If this
+	 * fault ever gets "unreserved", simply moved the following code to a more
+	 * suitable spot...
+	 */
 
-dispatch_unaligned_handler:
+ENTRY(dispatch_unaligned_handler)
 	SAVE_MIN_WITH_COVER
 	;;
-	//
-	// we can't have the alloc while psr.ic is cleared because 
-	// we might get a mandatory RSE (when you reach the end of the 
-	// rotating partition when doing the alloc) spill which could cause 
-	// a page fault on the kernel virtual address and the handler 
-	// wouldn't get the state to recover.
-	//
-	mov r15=cr.ifa
-	ssm psr.ic
+	alloc r14=ar.pfs,0,0,2,0		// now it's safe (must be first in insn group!)
+	mov out0=cr.ifa
+	adds out1=16,sp
+
+	ssm psr.ic | PSR_DEFAULT_BITS
 	;;
 	srlz.i					// guarantee that interrupt collection is enabled
 	;;
@@ -934,66 +967,53 @@
 	adds r3=8,r2				// set up second base pointer
 	;;
 	SAVE_REST
-	;;
-	alloc r14=ar.pfs,0,0,2,0		// now it's safe (must be first in insn group!)
-	;;					// avoid WAW on r14
 	movl r14=ia64_leave_kernel
-	mov out0=r15				// out0 = faulting address
-	adds out1=16,sp				// out1 = pointer to pt_regs
 	;;
 	mov rp=r14
 	br.sptk.many ia64_prepare_handle_unaligned
-	;;
+END(dispatch_unaligned_handler)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4c00 Entry 19 (size 64 bundles) Reserved
+	DBG_FAULT(19)
 	FAULT(19)
 
-	// There is no particular reason for this code to be here, other than that
-	// there happens to be space here that would go unused otherwise.  If this
-	// fault ever gets "unreserved", simply moved the following code to a more
-	// suitable spot...
+	/*
+	 * There is no particular reason for this code to be here, other than that
+	 * there happens to be space here that would go unused otherwise.  If this
+	 * fault ever gets "unreserved", simply moved the following code to a more
+	 * suitable spot...
+	 */
 
-dispatch_to_fault_handler:
-	//
-	// Input:
-	//	psr.ic:	off
-	//	r19:	fault vector number (e.g., 24 for General Exception)
-	//	r31:	contains saved predicates (pr)
-	//
+ENTRY(dispatch_to_fault_handler)
+	/*
+	 * Input:
+	 *	psr.ic:	off
+	 *	r19:	fault vector number (e.g., 24 for General Exception)
+	 *	r31:	contains saved predicates (pr)
+	 */
 	SAVE_MIN_WITH_COVER_R19
-	//
-	// Copy control registers to temporary registers, then turn on psr bits,
-	// then copy the temporary regs to the output regs.  We have to do this
-	// because the "alloc" can cause a mandatory store which could lead to
-	// an "Alt DTLB" fault which we can handle only if psr.ic is on.
-	//
-	mov r8=cr.isr
-	mov r9=cr.ifa
-	mov r10=cr.iim
-	mov r11=cr.itir
+	alloc r14=ar.pfs,0,0,5,0
+	mov out0=r15
+	mov out1=cr.isr
+	mov out2=cr.ifa
+	mov out3=cr.iim
+	mov out4=cr.itir
 	;;
-	ssm psr.ic
+	ssm psr.ic | PSR_DEFAULT_BITS
 	;;
 	srlz.i					// guarantee that interrupt collection is enabled
 	;;
 (p15)	ssm psr.i				// restore psr.i
 	adds r3=8,r2				// set up second base pointer for SAVE_REST
 	;;
-	alloc r14=ar.pfs,0,0,5,0		// must be first in insn group
-	mov out0=r15
-	mov out1=r8
-	mov out2=r9
-	mov out3=r10
-	mov out4=r11
-	;;
 	SAVE_REST
 	movl r14=ia64_leave_kernel
 	;;
 	mov rp=r14
 	br.call.sptk.many b6=ia64_fault
-	;;
+END(dispatch_to_fault_handler)
 
 //
 // --- End of long entries, Beginning of short entries
@@ -1002,55 +1022,67 @@
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
+ENTRY(page_not_present)
+	DBG_FAULT(20)
 	mov r16=cr.ifa
 	rsm psr.dt
-	// The Linux page fault handler doesn't expect non-present pages to be in
-	// the TLB.  Flush the existing entry now, so we meet that expectation.
-	mov r17=_PAGE_SIZE_4K<<2
+	/*
+	 * The Linux page fault handler doesn't expect non-present pages to be in
+	 * the TLB.  Flush the existing entry now, so we meet that expectation.
+	 */
+	mov r17=PAGE_SHIFT<<2
 	;;
 	ptc.l r16,r17
 	;;
 	mov r31=pr
 	srlz.d
 	br.sptk.many page_fault
-	;;
+END(page_not_present)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52)
+ENTRY(key_permission)
+	DBG_FAULT(21)
 	mov r16=cr.ifa
 	rsm psr.dt
 	mov r31=pr
 	;;
 	srlz.d
 	br.sptk.many page_fault
-	;;
+END(key_permission)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
+ENTRY(iaccess_rights)
+	DBG_FAULT(22)
 	mov r16=cr.ifa
 	rsm psr.dt
 	mov r31=pr
 	;;
 	srlz.d
 	br.sptk.many page_fault
-	;;
+END(iaccess_rights)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
+ENTRY(daccess_rights)
+	DBG_FAULT(23)
 	mov r16=cr.ifa
 	rsm psr.dt
 	mov r31=pr
 	;;
 	srlz.d
 	br.sptk.many page_fault
-	;;
+END(daccess_rights)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
+ENTRY(general_exception)
+	DBG_FAULT(24)
 	mov r16=cr.isr
 	mov r31=pr
 	;;
@@ -1059,39 +1091,44 @@
 	;;
 	mov r19=24		// fault number
 	br.sptk.many dispatch_to_fault_handler
-	;;
+END(general_exception)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5500 Entry 25 (size 16 bundles) Disabled FP-Register (35)
+ENTRY(disabled_fp_reg)
+	DBG_FAULT(25)
 	rsm psr.dfh		// ensure we can access fph
 	;;
 	srlz.d
 	mov r31=pr
 	mov r19=25
 	br.sptk.many dispatch_to_fault_handler
-	;;
+END(disabled_fp_reg)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
+ENTRY(nat_consumption)
+	DBG_FAULT(26)
 	FAULT(26)
+END(nat_consumption)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5700 Entry 27 (size 16 bundles) Speculation (40)
-	//
-	// A [f]chk.[as] instruction needs to take the branch to
-	// the recovery code but this part of the architecture is
-	// not implemented in hardware on some CPUs, such as Itanium.
-	// Thus, in general we need to emulate the behavior.
-	// IIM contains the relative target (not yet sign extended).
-	// So after sign extending it we simply add it to IIP.
-	// We also need to reset the EI field of the IPSR to zero,
-	// i.e., the slot to restart into.
-	//
-	// cr.imm contains zero_ext(imm21)
-	//
+ENTRY(speculation_vector)
+	DBG_FAULT(27)
+	/*
+	 * A [f]chk.[as] instruction needs to take the branch to the recovery code but
+	 * this part of the architecture is not implemented in hardware on some CPUs, such
+	 * as Itanium.  Thus, in general we need to emulate the behavior.  IIM contains
+	 * the relative target (not yet sign extended).  So after sign extending it we
+	 * simply add it to IIP.  We also need to reset the EI field of the IPSR to zero,
+	 * i.e., the slot to restart into.
+	 *
+	 * cr.imm contains zero_ext(imm21)
+	 */
 	mov r18=cr.iim
 	;;
 	mov r17=cr.iip
@@ -1112,105 +1149,130 @@
 	;;
 
 	rfi				// and go back
-	;;
+END(speculation_vector)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5800 Entry 28 (size 16 bundles) Reserved
+	DBG_FAULT(28)
 	FAULT(28)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56)
+ENTRY(debug_vector)
+	DBG_FAULT(29)
 	FAULT(29)
+END(debug_vector)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5a00 Entry 30 (size 16 bundles) Unaligned Reference (57)
+ENTRY(unaligned_access)
+	DBG_FAULT(30)
 	mov r16=cr.ipsr
 	mov r31=pr		// prepare to save predicates
-	;;									
-	br.sptk.many dispatch_unaligned_handler
 	;;
+	br.sptk.many dispatch_unaligned_handler
+END(unaligned_access)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5b00 Entry 31 (size 16 bundles) Unsupported Data Reference (57)
+	DBG_FAULT(31)
 	FAULT(31)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5c00 Entry 32 (size 16 bundles) Floating-Point Fault (64)
+	DBG_FAULT(32)
 	FAULT(32)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5d00 Entry 33 (size 16 bundles) Floating Point Trap (66)
+	DBG_FAULT(33)
 	FAULT(33)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5e00 Entry 34 (size 16 bundles) Lower Privilege Tranfer Trap (66)
+	DBG_FAULT(34)
 	FAULT(34)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5f00 Entry 35 (size 16 bundles) Taken Branch Trap (68)
+	DBG_FAULT(35)
 	FAULT(35)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6000 Entry 36 (size 16 bundles) Single Step Trap (69)
+	DBG_FAULT(36)
 	FAULT(36)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6100 Entry 37 (size 16 bundles) Reserved
+	DBG_FAULT(37)
 	FAULT(37)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6200 Entry 38 (size 16 bundles) Reserved
+	DBG_FAULT(38)
 	FAULT(38)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6300 Entry 39 (size 16 bundles) Reserved
+	DBG_FAULT(39)
 	FAULT(39)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6400 Entry 40 (size 16 bundles) Reserved
+	DBG_FAULT(40)
 	FAULT(40)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6500 Entry 41 (size 16 bundles) Reserved
+	DBG_FAULT(41)
 	FAULT(41)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6600 Entry 42 (size 16 bundles) Reserved
+	DBG_FAULT(42)
 	FAULT(42)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6700 Entry 43 (size 16 bundles) Reserved
+	DBG_FAULT(43)
 	FAULT(43)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6800 Entry 44 (size 16 bundles) Reserved
+	DBG_FAULT(44)
 	FAULT(44)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6900 Entry 45 (size 16 bundles) IA-32 Exeception (17,18,29,41,42,43,44,58,60,61,62,72,73,75,76,77)
+ENTRY(ia32_exception)
+	DBG_FAULT(45)
 	FAULT(45)
+END(ia32_exception)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6a00 Entry 46 (size 16 bundles) IA-32 Intercept  (30,31,59,70,71)
+ENTRY(ia32_intercept)
+	DBG_FAULT(46)
 #ifdef	CONFIG_IA32_SUPPORT
 	mov r31=pr
 	mov r16=cr.isr
@@ -1219,129 +1281,152 @@
 	mov r18=ar.eflag
 	mov r19=cr.iim		// old eflag value
 	;;
-	cmp.ne p2,p0=2,r17
-(p2)	br.cond.spnt 1f		// not a system flag fault
+	cmp.ne p6,p0=2,r17
+(p6)	br.cond.spnt 1f		// not a system flag fault
 	xor r16=r18,r19
 	;;
 	extr.u r17=r16,18,1	// get the eflags.ac bit
 	;;
-	cmp.eq p2,p0=0,r17
-(p2)	br.cond.spnt 1f		// eflags.ac bit didn't change
+	cmp.eq p6,p0=0,r17
+(p6)	br.cond.spnt 1f		// eflags.ac bit didn't change
 	;;
 	mov pr=r31,-1		// restore predicate registers
 	rfi
-	;;
+
 1:
 #endif	// CONFIG_IA32_SUPPORT
 	FAULT(46)
+END(ia32_intercept)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6b00 Entry 47 (size 16 bundles) IA-32 Interrupt  (74)
+ENTRY(ia32_interrupt)
+	DBG_FAULT(47)
 #ifdef CONFIG_IA32_SUPPORT
 	mov r31=pr
 	br.sptk.many dispatch_to_ia32_handler
-	;;
 #else
 	FAULT(47)
 #endif
+END(ia32_interrupt)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6c00 Entry 48 (size 16 bundles) Reserved
+	DBG_FAULT(48)
 	FAULT(48)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6d00 Entry 49 (size 16 bundles) Reserved
+	DBG_FAULT(49)
 	FAULT(49)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6e00 Entry 50 (size 16 bundles) Reserved
+	DBG_FAULT(50)
 	FAULT(50)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x6f00 Entry 51 (size 16 bundles) Reserved
+	DBG_FAULT(51)
 	FAULT(51)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7000 Entry 52 (size 16 bundles) Reserved
+	DBG_FAULT(52)
 	FAULT(52)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7100 Entry 53 (size 16 bundles) Reserved
+	DBG_FAULT(53)
 	FAULT(53)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7200 Entry 54 (size 16 bundles) Reserved
+	DBG_FAULT(54)
 	FAULT(54)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7300 Entry 55 (size 16 bundles) Reserved
+	DBG_FAULT(55)
 	FAULT(55)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7400 Entry 56 (size 16 bundles) Reserved
+	DBG_FAULT(56)
 	FAULT(56)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7500 Entry 57 (size 16 bundles) Reserved
+	DBG_FAULT(57)
 	FAULT(57)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7600 Entry 58 (size 16 bundles) Reserved
+	DBG_FAULT(58)
 	FAULT(58)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7700 Entry 59 (size 16 bundles) Reserved
+	DBG_FAULT(59)
 	FAULT(59)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7800 Entry 60 (size 16 bundles) Reserved
+	DBG_FAULT(60)
 	FAULT(60)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7900 Entry 61 (size 16 bundles) Reserved
+	DBG_FAULT(61)
 	FAULT(61)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7a00 Entry 62 (size 16 bundles) Reserved
+	DBG_FAULT(62)
 	FAULT(62)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7b00 Entry 63 (size 16 bundles) Reserved
+	DBG_FAULT(63)
 	FAULT(63)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7c00 Entry 64 (size 16 bundles) Reserved
+	DBG_FAULT(64)
 	FAULT(64)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7d00 Entry 65 (size 16 bundles) Reserved
+	DBG_FAULT(65)
 	FAULT(65)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7e00 Entry 66 (size 16 bundles) Reserved
+	DBG_FAULT(66)
 	FAULT(66)
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x7f00 Entry 67 (size 16 bundles) Reserved
+	DBG_FAULT(67)
 	FAULT(67)
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/mca.c linux/arch/ia64/kernel/mca.c
--- v2.4.3/linux/arch/ia64/kernel/mca.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/kernel/mca.c	Thu Apr  5 12:51:47 2001
@@ -1,16 +1,16 @@
 /*
- * File: 	mca.c
- * Purpose: 	Generic MCA handling layer
+ * File:	mca.c
+ * Purpose:	Generic MCA handling layer
  *
  * Updated for latest kernel
  * Copyright (C) 2000 Intel
  * Copyright (C) Chuck Fleckenstein (cfleck@co.intel.com)
- *  
+ *
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) Vijay Chander(vijay@engr.sgi.com)
  *
- * 00/03/29 C. Fleckenstein  Fixed PAL/SAL update issues, began MCA bug fixes, logging issues, 
- *                           added min save state dump, added INIT handler. 
+ * 00/03/29 C. Fleckenstein  Fixed PAL/SAL update issues, began MCA bug fixes, logging issues,
+ *                           added min save state dump, added INIT handler.
  */
 #include <linux/config.h>
 #include <linux/types.h>
@@ -27,8 +27,9 @@
 #include <asm/mca.h>
 
 #include <asm/irq.h>
+#include <asm/machvec.h>
+
 
- 
 typedef struct ia64_fptr {
 	unsigned long fp;
 	unsigned long gp;
@@ -43,8 +44,8 @@
 u64				ia64_mca_bspstore[1024];
 u64				ia64_init_stack[INIT_TASK_SIZE] __attribute__((aligned(16)));
 
-static void			ia64_mca_cmc_vector_setup(int 		enable, 
-							  int_vector_t 	cmc_vector);
+static void			ia64_mca_cmc_vector_setup(int		enable,
+							  int_vector_t	cmc_vector);
 static void			ia64_mca_wakeup_ipi_wait(void);
 static void			ia64_mca_wakeup(int cpu);
 static void			ia64_mca_wakeup_all(void);
@@ -77,7 +78,7 @@
  * console, then we would call the appropriate debug hooks here.
  */
 void
-init_handler_platform (struct pt_regs *regs) 
+init_handler_platform (struct pt_regs *regs)
 {
 	/* if a kernel debugger is available call it here else just dump the registers */
 	show_regs(regs);		/* dump the state info */
@@ -87,7 +88,7 @@
 log_print_platform ( void *cur_buff_ptr, prfunc_t prfunc)
 {
 }
-	
+
 void
 ia64_mca_init_platform (void)
 {
@@ -131,7 +132,7 @@
 				tpmss_ptr++;  /* skip to next entry */
 				continue;
 			}
-		} 
+		}
 
 		printk("%5s=0x%16.16lx ",min_state_labels[i],*tpmss_ptr++);
 
@@ -142,7 +143,7 @@
 	/* hang city for now, until we include debugger or copy to ptregs to show: */
 	while (1);
 }
- 
+
 /*
  * ia64_mca_cmc_vector_setup
  *	Setup the correctable machine check vector register in the processor
@@ -154,14 +155,14 @@
  *	None
  */
 static void
-ia64_mca_cmc_vector_setup(int 		enable, 
-			  int_vector_t 	cmc_vector)
+ia64_mca_cmc_vector_setup(int		enable,
+			  int_vector_t	cmc_vector)
 {
 	cmcv_reg_t	cmcv;
 
-	cmcv.cmcv_regval 	= 0;
-	cmcv.cmcv_mask  	= enable;
-	cmcv.cmcv_vector 	= cmc_vector;
+	cmcv.cmcv_regval	= 0;
+	cmcv.cmcv_mask	= enable;
+	cmcv.cmcv_vector	= cmc_vector;
 	ia64_set_cmcv(cmcv.cmcv_regval);
 }
 
@@ -223,25 +224,27 @@
 	for(i = 0 ; i < IA64_MAXCPUS; i++)
 		ia64_mc_info.imi_rendez_checkin[i] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
 
-	/* NOTE : The actual irqs for the rendez, wakeup and 
+	/* NOTE : The actual irqs for the rendez, wakeup and
 	 * cmc interrupts are requested in the platform-specific
 	 * mca initialization code.
 	 */
-	/* 
+	/*
 	 * Register the rendezvous spinloop and wakeup mechanism with SAL
 	 */
 
 	/* Register the rendezvous interrupt vector with SAL */
 	if (ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_INT,
 				   SAL_MC_PARAM_MECHANISM_INT,
-				   IA64_MCA_RENDEZ_INT_VECTOR,
-				   IA64_MCA_RENDEZ_TIMEOUT))
+				   IA64_MCA_RENDEZ_VECTOR,
+				   IA64_MCA_RENDEZ_TIMEOUT,
+				   0))
 		return;
 
 	/* Register the wakeup interrupt vector with SAL */
 	if (ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_WAKEUP,
 				   SAL_MC_PARAM_MECHANISM_INT,
-				   IA64_MCA_WAKEUP_INT_VECTOR,
+				   IA64_MCA_WAKEUP_VECTOR,
+				   0,
 				   0))
 		return;
 
@@ -249,17 +252,16 @@
 	/*
 	 * Setup the correctable machine check vector
 	 */
-	ia64_mca_cmc_vector_setup(IA64_CMC_INT_ENABLE, 
-				  IA64_MCA_CMC_INT_VECTOR);
+	ia64_mca_cmc_vector_setup(IA64_CMC_INT_ENABLE, IA64_CMC_VECTOR);
 
 	IA64_MCA_DEBUG("ia64_mca_init : correctable mca vector setup done\n");
 
-	ia64_mc_info.imi_mca_handler 		= __pa(ia64_os_mca_dispatch);
+	ia64_mc_info.imi_mca_handler		= __pa(ia64_os_mca_dispatch);
 	/*
 	 * XXX - disable SAL checksum by setting size to 0; should be
 	 *	__pa(ia64_os_mca_dispatch_end) - __pa(ia64_os_mca_dispatch);
 	 */
-	ia64_mc_info.imi_mca_handler_size	= 0; 
+	ia64_mc_info.imi_mca_handler_size	= 0;
 	/* Register the os mca handler with SAL */
 	if (ia64_sal_set_vectors(SAL_VECTOR_OS_MCA,
 				 ia64_mc_info.imi_mca_handler,
@@ -271,13 +273,13 @@
 
 	IA64_MCA_DEBUG("ia64_mca_init : registered os mca handler with SAL\n");
 
-	/* 
+	/*
 	 * XXX - disable SAL checksum by setting size to 0, should be
-	 * IA64_INIT_HANDLER_SIZE 
+	 * IA64_INIT_HANDLER_SIZE
 	 */
-	ia64_mc_info.imi_monarch_init_handler 		= __pa(mon_init_ptr->fp);
+	ia64_mc_info.imi_monarch_init_handler		= __pa(mon_init_ptr->fp);
 	ia64_mc_info.imi_monarch_init_handler_size	= 0;
-	ia64_mc_info.imi_slave_init_handler 		= __pa(slave_init_ptr->fp);
+	ia64_mc_info.imi_slave_init_handler		= __pa(slave_init_ptr->fp);
 	ia64_mc_info.imi_slave_init_handler_size	= 0;
 
 	IA64_MCA_DEBUG("ia64_mca_init : os init handler at %lx\n",ia64_mc_info.imi_monarch_init_handler);
@@ -296,7 +298,7 @@
 
 	IA64_MCA_DEBUG("ia64_mca_init : registered os init handler with SAL\n");
 
-	/* Initialize the areas set aside by the OS to buffer the 
+	/* Initialize the areas set aside by the OS to buffer the
 	 * platform/processor error states for MCA/INIT/CMC
 	 * handling.
 	 */
@@ -308,7 +310,7 @@
 	ia64_log_init(SAL_INFO_TYPE_CMC, SAL_SUB_INFO_TYPE_PLATFORM);
 
 	ia64_mca_init_platform();
-	
+
 	IA64_MCA_DEBUG("ia64_mca_init : platform-specific mca handling setup done\n");
 
 #if defined(MCA_TEST)
@@ -321,9 +323,9 @@
 /*
  * ia64_mca_wakeup_ipi_wait
  *	Wait for the inter-cpu interrupt to be sent by the
- * 	monarch processor once it is done with handling the
+ *	monarch processor once it is done with handling the
  *	MCA.
- * Inputs 
+ * Inputs
  *	None
  * Outputs
  *	None
@@ -331,8 +333,8 @@
 void
 ia64_mca_wakeup_ipi_wait(void)
 {
-	int	irr_num = (IA64_MCA_WAKEUP_INT_VECTOR >> 6);
-	int	irr_bit = (IA64_MCA_WAKEUP_INT_VECTOR & 0x3f);
+	int	irr_num = (IA64_MCA_WAKEUP_VECTOR >> 6);
+	int	irr_bit = (IA64_MCA_WAKEUP_VECTOR & 0x3f);
 	u64	irr = 0;
 
 	do {
@@ -356,7 +358,7 @@
 /*
  * ia64_mca_wakeup
  *	Send an inter-cpu interrupt to wake-up a particular cpu
- * 	and mark that cpu to be out of rendez.
+ *	and mark that cpu to be out of rendez.
  * Inputs
  *	cpuid
  * Outputs
@@ -365,9 +367,8 @@
 void
 ia64_mca_wakeup(int cpu)
 {
-	platform_send_ipi(cpu, IA64_MCA_WAKEUP_INT_VECTOR, IA64_IPI_DM_INT, 0);
+	platform_send_ipi(cpu, IA64_MCA_WAKEUP_VECTOR, IA64_IPI_DM_INT, 0);
 	ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
-	
 }
 /*
  * ia64_mca_wakeup_all
@@ -390,10 +391,10 @@
 }
 /*
  * ia64_mca_rendez_interrupt_handler
- *	This is handler used to put slave processors into spinloop 
+ *	This is handler used to put slave processors into spinloop
  *	while the monarch processor does the mca handling and later
  *	wake each slave up once the monarch is done.
- * Inputs 
+ * Inputs
  *	None
  * Outputs
  *	None
@@ -403,7 +404,7 @@
 {
 	int flags, cpu = 0;
 	/* Mask all interrupts */
-        save_and_cli(flags);
+	save_and_cli(flags);
 
 #ifdef CONFIG_SMP
 	cpu = cpu_logical_id(hard_smp_processor_id());
@@ -414,7 +415,7 @@
 	 */
 	ia64_sal_mc_rendez();
 
-	/* Wait for the wakeup IPI from the monarch 
+	/* Wait for the wakeup IPI from the monarch
 	 * This waiting is done by polling on the wakeup-interrupt
 	 * vector bit in the processor's IRRs
 	 */
@@ -430,30 +431,30 @@
 /*
  * ia64_mca_wakeup_int_handler
  *	The interrupt handler for processing the inter-cpu interrupt to the
- * 	slave cpu which was spinning in the rendez loop.
+ *	slave cpu which was spinning in the rendez loop.
  *	Since this spinning is done by turning off the interrupts and
- *	polling on the wakeup-interrupt bit in the IRR, there is 
+ *	polling on the wakeup-interrupt bit in the IRR, there is
  *	nothing useful to be done in the handler.
  *  Inputs
  *	wakeup_irq	(Wakeup-interrupt bit)
  *	arg		(Interrupt handler specific argument)
  *	ptregs		(Exception frame at the time of the interrupt)
  *  Outputs
- *	
+ *
  */
 void
 ia64_mca_wakeup_int_handler(int wakeup_irq, void *arg, struct pt_regs *ptregs)
 {
-	
+
 }
 
 /*
  * ia64_return_to_sal_check
  *	This is function called before going back from the OS_MCA handler
- * 	to the OS_MCA dispatch code which finally takes the control back
- * 	to the SAL.
+ *	to the OS_MCA dispatch code which finally takes the control back
+ *	to the SAL.
  *	The main purpose of this routine is to setup the OS_MCA to SAL
- *	return state which can be used by the OS_MCA dispatch code 
+ *	return state which can be used by the OS_MCA dispatch code
  *	just before going back to SAL.
  * Inputs
  *	None
@@ -467,16 +468,16 @@
 	/* Copy over some relevant stuff from the sal_to_os_mca_handoff
 	 * so that it can be used at the time of os_mca_to_sal_handoff
 	 */
-	ia64_os_to_sal_handoff_state.imots_sal_gp = 
+	ia64_os_to_sal_handoff_state.imots_sal_gp =
 		ia64_sal_to_os_handoff_state.imsto_sal_gp;
 
-	ia64_os_to_sal_handoff_state.imots_sal_check_ra = 
+	ia64_os_to_sal_handoff_state.imots_sal_check_ra =
 		ia64_sal_to_os_handoff_state.imsto_sal_check_ra;
 
 	/* For now ignore the MCA */
 	ia64_os_to_sal_handoff_state.imots_os_status = IA64_MCA_CORRECTED;
 }
-/* 
+/*
  * ia64_mca_ucmc_handler
  *	This is uncorrectable machine check handler called from OS_MCA
  *	dispatch code which is in turn called from SAL_CHECK().
@@ -503,7 +504,7 @@
 
 	ia64_log_print(SAL_INFO_TYPE_MCA, SAL_SUB_INFO_TYPE_PROCESSOR, (prfunc_t)printk);
 
-	/* 
+	/*
 	 * Do some error handling - Platform-specific mca handler is called at this point
 	 */
 
@@ -520,11 +521,11 @@
 	ia64_return_to_sal_check();
 }
 
-/* 
+/*
  * ia64_mca_cmc_int_handler
  *	This is correctable machine check interrupt handler.
  *	Right now the logs are extracted and displayed in a well-defined
- *	format. 
+ *	format.
  * Inputs
  *	None
  * Outputs
@@ -532,7 +533,7 @@
  */
 void
 ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
-{	
+{
 	/* Get the CMC processor log */
 	ia64_log_get(SAL_INFO_TYPE_CMC, SAL_SUB_INFO_TYPE_PROCESSOR, (prfunc_t)printk);
 	/* Get the CMC platform log */
@@ -543,8 +544,7 @@
 	cmci_handler_platform(cmc_irq, arg, ptregs);
 
 	/* Clear the CMC SAL logs now that they have been saved in the OS buffer */
-	ia64_sal_clear_state_info(SAL_INFO_TYPE_CMC, SAL_SUB_INFO_TYPE_PROCESSOR);
-	ia64_sal_clear_state_info(SAL_INFO_TYPE_CMC, SAL_SUB_INFO_TYPE_PLATFORM);
+	ia64_sal_clear_state_info(SAL_INFO_TYPE_CMC);
 }
 
 /*
@@ -563,17 +563,17 @@
 static ia64_state_log_t	ia64_state_log[IA64_MAX_LOG_TYPES][IA64_MAX_LOG_SUBTYPES];
 
 #define IA64_LOG_LOCK_INIT(it, sit)	spin_lock_init(&ia64_state_log[it][sit].isl_lock)
-#define IA64_LOG_LOCK(it, sit)	 	spin_lock_irqsave(&ia64_state_log[it][sit].isl_lock, s)
-#define IA64_LOG_UNLOCK(it, sit) 	spin_unlock_irqrestore(&ia64_state_log[it][sit].isl_lock,\
+#define IA64_LOG_LOCK(it, sit)		spin_lock_irqsave(&ia64_state_log[it][sit].isl_lock, s)
+#define IA64_LOG_UNLOCK(it, sit)	spin_unlock_irqrestore(&ia64_state_log[it][sit].isl_lock,\
 							       s)
 #define IA64_LOG_NEXT_INDEX(it, sit)	ia64_state_log[it][sit].isl_index
-#define IA64_LOG_CURR_INDEX(it, sit) 	1 - ia64_state_log[it][sit].isl_index
+#define IA64_LOG_CURR_INDEX(it, sit)	1 - ia64_state_log[it][sit].isl_index
 #define IA64_LOG_INDEX_INC(it, sit)	\
 	ia64_state_log[it][sit].isl_index = 1 - ia64_state_log[it][sit].isl_index
 #define IA64_LOG_INDEX_DEC(it, sit)	\
 	ia64_state_log[it][sit].isl_index = 1 - ia64_state_log[it][sit].isl_index
-#define IA64_LOG_NEXT_BUFFER(it, sit) 	(void *)(&(ia64_state_log[it][sit].isl_log[IA64_LOG_NEXT_INDEX(it,sit)]))
-#define IA64_LOG_CURR_BUFFER(it, sit) 	(void *)(&(ia64_state_log[it][sit].isl_log[IA64_LOG_CURR_INDEX(it,sit)]))
+#define IA64_LOG_NEXT_BUFFER(it, sit)	(void *)(&(ia64_state_log[it][sit].isl_log[IA64_LOG_NEXT_INDEX(it,sit)]))
+#define IA64_LOG_CURR_BUFFER(it, sit)	(void *)(&(ia64_state_log[it][sit].isl_log[IA64_LOG_CURR_INDEX(it,sit)]))
 
 /*
  * C portion of the OS INIT handler
@@ -582,7 +582,7 @@
  *
  * Inputs: pointer to pt_regs where processor info was saved.
  *
- * Returns: 
+ * Returns:
  *   0 if SAL must warm boot the System
  *   1 if SAL must retrun to interrupted context using PAL_MC_RESUME
  *
@@ -601,49 +601,48 @@
 	/* Get the INIT platform log */
 	ia64_log_get(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PLATFORM, (prfunc_t)printk);
 
-#ifdef IA64_DUMP_ALL_PROC_INFO 
+#ifdef IA64_DUMP_ALL_PROC_INFO
 	ia64_log_print(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PROCESSOR, (prfunc_t)printk);
-#endif 
+#endif
 
-	/* 
+	/*
 	 * get pointer to min state save area
 	 *
 	 */
 	plog_ptr=(ia64_psilog_t *)IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_INIT,
 						       SAL_SUB_INFO_TYPE_PROCESSOR);
 	proc_ptr = &plog_ptr->devlog.proclog;
-	
+
 	ia64_process_min_state_save(&proc_ptr->slpi_min_state_area,regs);
 
 	init_handler_platform(regs);              /* call platform specific routines */
 
 	/* Clear the INIT SAL logs now that they have been saved in the OS buffer */
-	ia64_sal_clear_state_info(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PROCESSOR);
-	ia64_sal_clear_state_info(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PLATFORM);
+	ia64_sal_clear_state_info(SAL_INFO_TYPE_INIT);
 }
 
 /*
  * ia64_log_init
- * 	Reset the OS ia64 log buffer
- * Inputs 	:	info_type 	(SAL_INFO_TYPE_{MCA,INIT,CMC})
+ *	Reset the OS ia64 log buffer
+ * Inputs	:	info_type	(SAL_INFO_TYPE_{MCA,INIT,CMC})
  *			sub_info_type	(SAL_SUB_INFO_TYPE_{PROCESSOR,PLATFORM})
- * Outputs	: 	None
+ * Outputs	:	None
  */
 void
 ia64_log_init(int sal_info_type, int sal_sub_info_type)
 {
 	IA64_LOG_LOCK_INIT(sal_info_type, sal_sub_info_type);
 	IA64_LOG_NEXT_INDEX(sal_info_type, sal_sub_info_type) = 0;
-	memset(IA64_LOG_NEXT_BUFFER(sal_info_type, sal_sub_info_type), 0, 
+	memset(IA64_LOG_NEXT_BUFFER(sal_info_type, sal_sub_info_type), 0,
 	       sizeof(ia64_psilog_t) * IA64_MAX_LOGS);
 }
 
-/* 
+/*
  * ia64_log_get
- * 	Get the current MCA log from SAL and copy it into the OS log buffer.
- * Inputs 	:	info_type 	(SAL_INFO_TYPE_{MCA,INIT,CMC})
+ *	Get the current MCA log from SAL and copy it into the OS log buffer.
+ * Inputs	:	info_type	(SAL_INFO_TYPE_{MCA,INIT,CMC})
  *			sub_info_type	(SAL_SUB_INFO_TYPE_{PROCESSOR,PLATFORM})
- * Outputs	: 	None
+ * Outputs	:	None
  *
  */
 void
@@ -658,7 +657,7 @@
 	/* Get the process state information */
 	log_buffer = IA64_LOG_NEXT_BUFFER(sal_info_type, sal_sub_info_type);
 
-	if (!(total_len=ia64_sal_get_state_info(sal_info_type, sal_sub_info_type ,(u64 *)log_buffer)))
+	if (!(total_len=ia64_sal_get_state_info(sal_info_type,(u64 *)log_buffer)))
 		prfunc("ia64_mca_log_get : Getting processor log failed\n");
 
 	IA64_MCA_DEBUG("ia64_log_get: retrieved %d bytes of error information\n",total_len);
@@ -669,21 +668,21 @@
 
 }
 
-/* 
+/*
  * ia64_log_clear
- * 	Clear the current MCA log from SAL and dpending on the clear_os_buffer flags
+ *	Clear the current MCA log from SAL and dpending on the clear_os_buffer flags
  *	clear the OS log buffer also
- * Inputs 	:	info_type 	(SAL_INFO_TYPE_{MCA,INIT,CMC})
+ * Inputs	:	info_type	(SAL_INFO_TYPE_{MCA,INIT,CMC})
  *			sub_info_type	(SAL_SUB_INFO_TYPE_{PROCESSOR,PLATFORM})
- *			clear_os_buffer 
+ *			clear_os_buffer
  *			prfunc		(print function)
- * Outputs	: 	None
+ * Outputs	:	None
  *
  */
 void
 ia64_log_clear(int sal_info_type, int sal_sub_info_type, int clear_os_buffer, prfunc_t prfunc)
 {
-	if (ia64_sal_clear_state_info(sal_info_type, sal_sub_info_type))
+	if (ia64_sal_clear_state_info(sal_info_type))
 		prfunc("ia64_mca_log_get : Clearing processor log failed\n");
 
 	if (clear_os_buffer) {
@@ -698,7 +697,7 @@
 		memset(log_buffer, 0, sizeof(ia64_psilog_t));
 
 		IA64_LOG_INDEX_DEC(sal_info_type, sal_sub_info_type);
-	
+
 		IA64_LOG_UNLOCK(sal_info_type, sal_sub_info_type);
 	}
 
@@ -708,19 +707,19 @@
  * ia64_log_processor_regs_print
  *	Print the contents of the saved processor register(s) in the format
  *		<reg_prefix>[<index>] <value>
- *		
- * Inputs	:	regs 		(Register save buffer)
- *			reg_num 	(# of registers)
+ *
+ * Inputs	:	regs		(Register save buffer)
+ *			reg_num	(# of registers)
  *			reg_class	(application/banked/control/bank1_general)
  *			reg_prefix	(ar/br/cr/b1_gr)
- * Outputs	: 	None
+ * Outputs	:	None
  *
  */
 void
-ia64_log_processor_regs_print(u64 	*regs, 
-			      int 	reg_num,
-			      char 	*reg_class,
-			      char 	*reg_prefix,
+ia64_log_processor_regs_print(u64	*regs,
+			      int	reg_num,
+			      char	*reg_class,
+			      char	*reg_prefix,
 			      prfunc_t	prfunc)
 {
 	int i;
@@ -756,14 +755,14 @@
  * ia64_log_cache_check_info_print
  *	Display the machine check information related to cache error(s).
  * Inputs	:	i		(Multiple errors are logged, i - index of logged error)
- *			info		(Machine check info logged by the PAL and later 
+ *			info		(Machine check info logged by the PAL and later
  *					 captured by the SAL)
  *			target_addr	(Address which caused the cache error)
- * Outputs	: 	None
+ * Outputs	:	None
  */
-void 
-ia64_log_cache_check_info_print(int 			i, 
-				pal_cache_check_info_t 	info,
+void
+ia64_log_cache_check_info_print(int			i,
+				pal_cache_check_info_t	info,
 				u64			target_addr,
 				prfunc_t		prfunc)
 {
@@ -794,13 +793,13 @@
  * ia64_log_tlb_check_info_print
  *	Display the machine check information related to tlb error(s).
  * Inputs	:	i		(Multiple errors are logged, i - index of logged error)
- *			info		(Machine check info logged by the PAL and later 
+ *			info		(Machine check info logged by the PAL and later
  *					 captured by the SAL)
- * Outputs	: 	None
+ * Outputs	:	None
  */
 
 void
-ia64_log_tlb_check_info_print(int 			i,
+ia64_log_tlb_check_info_print(int			i,
 			      pal_tlb_check_info_t	info,
 			      prfunc_t			prfunc)
 {
@@ -826,16 +825,16 @@
  * ia64_log_bus_check_info_print
  *	Display the machine check information related to bus error(s).
  * Inputs	:	i		(Multiple errors are logged, i - index of logged error)
- *			info		(Machine check info logged by the PAL and later 
+ *			info		(Machine check info logged by the PAL and later
  *					 captured by the SAL)
  *			req_addr	(Address of the requestor of the transaction)
  *			resp_addr	(Address of the responder of the transaction)
  *			target_addr	(Address where the data was to be delivered to  or
  *					 obtained from)
- * Outputs	: 	None
+ * Outputs	:	None
  */
 void
-ia64_log_bus_check_info_print(int 			i,
+ia64_log_bus_check_info_print(int			i,
 			      pal_bus_check_info_t	info,
 			      u64			req_addr,
 			      u64			resp_addr,
@@ -868,9 +867,9 @@
  * ia64_log_processor_info_print
  *	Display the processor-specific information logged by PAL as a part
  *	of MCA or INIT or CMC.
- * Inputs 	:	lh	(Pointer of the sal log header which specifies the format
+ * Inputs	:	lh	(Pointer of the sal log header which specifies the format
  *				 of SAL state info as specified by the SAL spec).
- * Outputs	: 	None
+ * Outputs	:	None
  */
 void
 ia64_log_processor_info_print(sal_log_header_t *lh, prfunc_t prfunc)
@@ -892,29 +891,29 @@
 	}
 
 	/* Print branch register contents if valid */
-	if (slpi->slpi_valid.slpi_br) 
+	if (slpi->slpi_valid.slpi_br)
 		ia64_log_processor_regs_print(slpi->slpi_br, 8, "Branch", "br", prfunc);
 
 	/* Print control register contents if valid */
-	if (slpi->slpi_valid.slpi_cr) 
+	if (slpi->slpi_valid.slpi_cr)
 		ia64_log_processor_regs_print(slpi->slpi_cr, 128, "Control", "cr", prfunc);
 
 	/* Print application register contents if valid */
-	if (slpi->slpi_valid.slpi_ar) 
+	if (slpi->slpi_valid.slpi_ar)
 		ia64_log_processor_regs_print(slpi->slpi_br, 128, "Application", "ar", prfunc);
 
 	/* Print region register contents if valid */
-	if (slpi->slpi_valid.slpi_rr) 
+	if (slpi->slpi_valid.slpi_rr)
 		ia64_log_processor_regs_print(slpi->slpi_rr, 8, "Region", "rr", prfunc);
 
 	/* Print floating-point register contents if valid */
-	if (slpi->slpi_valid.slpi_fr) 
-		ia64_log_processor_regs_print(slpi->slpi_fr, 128, "Floating-point", "fr", 
+	if (slpi->slpi_valid.slpi_fr)
+		ia64_log_processor_regs_print(slpi->slpi_fr, 128, "Floating-point", "fr",
 					      prfunc);
 
 	/* Print the cache check information if any*/
 	for (i = 0 ; i < MAX_CACHE_ERRORS; i++)
-		ia64_log_cache_check_info_print(i, 
+		ia64_log_cache_check_info_print(i,
 					slpi->slpi_cache_check_info[i].slpi_cache_check,
 					slpi->slpi_cache_check_info[i].slpi_target_address,
 						prfunc);
@@ -924,7 +923,7 @@
 
 	/* Print the bus check information if any*/
 	for (i = 0 ; i < MAX_BUS_ERRORS; i++)
-		ia64_log_bus_check_info_print(i, 
+		ia64_log_bus_check_info_print(i,
 					slpi->slpi_bus_check_info[i].slpi_bus_check,
 					slpi->slpi_bus_check_info[i].slpi_requestor_addr,
 					slpi->slpi_bus_check_info[i].slpi_responder_addr,
@@ -935,15 +934,15 @@
 
 /*
  * ia64_log_print
- * 	Display the contents of the OS error log information
- * Inputs 	:	info_type 	(SAL_INFO_TYPE_{MCA,INIT,CMC})
+ *	Display the contents of the OS error log information
+ * Inputs	:	info_type	(SAL_INFO_TYPE_{MCA,INIT,CMC})
  *			sub_info_type	(SAL_SUB_INFO_TYPE_{PROCESSOR,PLATFORM})
- * Outputs	: 	None
+ * Outputs	:	None
  */
 void
 ia64_log_print(int sal_info_type, int sal_sub_info_type, prfunc_t prfunc)
 {
-	char 	*info_type, *sub_info_type;
+	char	*info_type, *sub_info_type;
 
 	switch(sal_info_type) {
 	case SAL_INFO_TYPE_MCA:
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/mca_asm.S linux/arch/ia64/kernel/mca_asm.S
--- v2.4.3/linux/arch/ia64/kernel/mca_asm.S	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/kernel/mca_asm.S	Thu Apr  5 12:51:47 2001
@@ -1,4 +1,4 @@
-// 
+//
 // assembly portion of the IA64 MCA handling
 //
 // Mods by cfleck to integrate into kernel build
@@ -8,6 +8,7 @@
 //		   kstack, switch modes, jump to C INIT handler
 //
 #include <linux/config.h>
+
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/mca_asm.h>
@@ -17,13 +18,9 @@
  * When we get an machine check, the kernel stack pointer is no longer
  * valid, so we need to set a new stack pointer.
  */
-#define	MINSTATE_PHYS	/* Make sure stack access is physical for MINSTATE */ 
+#define	MINSTATE_PHYS	/* Make sure stack access is physical for MINSTATE */
 
 #include "minstate.h"
-	
-	.psr abi64
-	.psr lsb
-	.lsb
 
 /*
  *	SAL_TO_OS_MCA_HANDOFF_STATE
@@ -35,26 +32,26 @@
  *		6. GR12 = Return address to location within SAL_CHECK
  */
 #define SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(_tmp)		\
-        movl	_tmp=ia64_sal_to_os_handoff_state;;	\
-        st8	[_tmp]=r1,0x08;;			\
-        st8	[_tmp]=r8,0x08;;			\
-        st8	[_tmp]=r9,0x08;;			\
-        st8	[_tmp]=r10,0x08;;			\
-        st8	[_tmp]=r11,0x08;;			\
-        st8	[_tmp]=r12,0x08;;
+	movl	_tmp=ia64_sal_to_os_handoff_state;;	\
+	st8	[_tmp]=r1,0x08;;			\
+	st8	[_tmp]=r8,0x08;;			\
+	st8	[_tmp]=r9,0x08;;			\
+	st8	[_tmp]=r10,0x08;;			\
+	st8	[_tmp]=r11,0x08;;			\
+	st8	[_tmp]=r12,0x08;;
 
 /*
  *	OS_MCA_TO_SAL_HANDOFF_STATE
  *		1. GR8 = OS_MCA status
  *		2. GR9 = SAL GP (physical)
  *		3. GR22 = New min state save area pointer
- */	
+ */
 #define OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(_tmp)	\
-        movl	_tmp=ia64_os_to_sal_handoff_state;;	\
+	movl	_tmp=ia64_os_to_sal_handoff_state;;	\
 	DATA_VA_TO_PA(_tmp);;				\
-        ld8	r8=[_tmp],0x08;;			\
-        ld8	r9=[_tmp],0x08;;			\
-        ld8	r22=[_tmp],0x08;;
+	ld8	r8=[_tmp],0x08;;			\
+	ld8	r9=[_tmp],0x08;;			\
+	ld8	r22=[_tmp],0x08;;
 
 /*
  *	BRANCH
@@ -65,9 +62,9 @@
  *		"ip" is the address of the instruction
  *	located at "from_label".
  *		"temp" is a scratch register like r2
- *		"adjust" needed for HP compiler. 
+ *		"adjust" needed for HP compiler.
  *	A screwup somewhere with constant arithmetic.
- */	
+ */
 #define BRANCH(to_label, temp, p, adjust)		\
 100:	(p)	mov		temp=ip;		\
 		;;					\
@@ -76,7 +73,7 @@
 	(p)	adds		temp=adjust,temp;	\
 		;;					\
 	(p)	mov		b1=temp	;		\
-	(p)	br		b1	
+	(p)	br		b1
 
 	.global ia64_os_mca_dispatch
 	.global ia64_os_mca_dispatch_end
@@ -88,11 +85,11 @@
 	.global	ia64_mca_stack
 	.global	ia64_mca_stackframe
 	.global	ia64_mca_bspstore
-	.global ia64_init_stack	
-			
+	.global ia64_init_stack
+
 	.text
 	.align 16
-	
+
 ia64_os_mca_dispatch:
 
 #if defined(MCA_TEST)
@@ -114,23 +111,23 @@
 	;;
 begin_os_mca_dump:
 	BRANCH(ia64_os_mca_proc_state_dump, r2, p0, 0x0)
-        ;;
+	;;
 ia64_os_mca_done_dump:
 
-	// Setup new stack frame for OS_MCA handling 
-        movl        r2=ia64_mca_bspstore		// local bspstore area location in r2
-        movl        r3=ia64_mca_stackframe		// save stack frame to memory in r3
-        rse_switch_context(r6,r3,r2);;                  // RSC management in this new context
-        movl        r12=ia64_mca_stack;;
+	// Setup new stack frame for OS_MCA handling
+	movl        r2=ia64_mca_bspstore		// local bspstore area location in r2
+	movl        r3=ia64_mca_stackframe		// save stack frame to memory in r3
+	rse_switch_context(r6,r3,r2);;                  // RSC management in this new context
+	movl        r12=ia64_mca_stack;;
 
 	// Enter virtual mode from physical mode
 	VIRTUAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_begin, r4)
 ia64_os_mca_virtual_begin:
 
 	// call our handler
-        movl		r2=ia64_mca_ucmc_handler;;
-        mov		b6=r2;;
-        br.call.sptk.few	b0=b6
+	movl		r2=ia64_mca_ucmc_handler;;
+	mov		b6=r2;;
+	br.call.sptk.few	b0=b6
 .ret0:
 	// Revert back to physical mode before going back to SAL
 	PHYSICAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_end, r4)
@@ -144,42 +141,36 @@
 #endif	/* #if defined(MCA_TEST) */
 
 	// restore the original stack frame here
-        movl    r2=ia64_mca_stackframe               // restore stack frame from memory at r2
+	movl    r2=ia64_mca_stackframe               // restore stack frame from memory at r2
 	;;
 	DATA_VA_TO_PA(r2)
-        movl    r4=IA64_PSR_MC
+	movl    r4=IA64_PSR_MC
 	;;
-        rse_return_context(r4,r3,r2)                 // switch from interrupt context for RSE
-	
+	rse_return_context(r4,r3,r2)                 // switch from interrupt context for RSE
+
 	// let us restore all the registers from our PSI structure
-        mov		r8=gp
+	mov		r8=gp
 	;;
 begin_os_mca_restore:
 	BRANCH(ia64_os_mca_proc_state_restore, r2, p0, 0x0)
-        ;;
+	;;
 
 ia64_os_mca_done_restore:
 	;;
-#ifdef SOFTSDV
-	VIRTUAL_MODE_ENTER(r2,r3, vmode_enter, r4)
-vmode_enter:	
-	br.ret.sptk.few		b0	
-#else
 	// branch back to SALE_CHECK
 	OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(r2)
-        ld8		r3=[r2];;              
-        mov		b0=r3                       // SAL_CHECK return address
-        br		b0
-        ;;
-#endif /* #ifdef SOFTSDV */
-ia64_os_mca_dispatch_end:	
+	ld8		r3=[r2];;
+	mov		b0=r3                       // SAL_CHECK return address
+	br		b0
+	;;
+ia64_os_mca_dispatch_end:
 //EndMain//////////////////////////////////////////////////////////////////////
 
 
 //++
 // Name:
 //      ia64_os_mca_proc_state_dump()
-// 
+//
 // Stub Description:
 //
 //       This stub dumps the processor state during MCHK to a data area
@@ -188,223 +179,223 @@
 
 ia64_os_mca_proc_state_dump:
 // Get and save GR0-31 from Proc. Min. State Save Area to SAL PSI
-        movl		r2=ia64_mca_proc_state_dump;;           // Os state dump area
+	movl		r2=ia64_mca_proc_state_dump;;           // Os state dump area
 
-// save ar.NaT 
-        mov		r5=ar.unat                  // ar.unat
+// save ar.NaT
+	mov		r5=ar.unat                  // ar.unat
 
 // save banked GRs 16-31 along with NaT bits
-        bsw.1;;
-        st8.spill	[r2]=r16,8;;
-        st8.spill	[r2]=r17,8;;
-        st8.spill	[r2]=r18,8;;
-        st8.spill	[r2]=r19,8;;
-        st8.spill	[r2]=r20,8;;
-        st8.spill	[r2]=r21,8;;
-        st8.spill	[r2]=r22,8;;
-        st8.spill	[r2]=r23,8;;
-        st8.spill	[r2]=r24,8;;
-        st8.spill	[r2]=r25,8;;
-        st8.spill	[r2]=r26,8;;
-        st8.spill	[r2]=r27,8;;
-        st8.spill	[r2]=r28,8;;
-        st8.spill	[r2]=r29,8;;
-        st8.spill	[r2]=r30,8;;
-        st8.spill	[r2]=r31,8;;
-
-        mov		r4=ar.unat;;
-        st8		[r2]=r4,8                // save User NaT bits for r16-r31
-        mov		ar.unat=r5                  // restore original unat
-        bsw.0;;
+	bsw.1;;
+	st8.spill	[r2]=r16,8;;
+	st8.spill	[r2]=r17,8;;
+	st8.spill	[r2]=r18,8;;
+	st8.spill	[r2]=r19,8;;
+	st8.spill	[r2]=r20,8;;
+	st8.spill	[r2]=r21,8;;
+	st8.spill	[r2]=r22,8;;
+	st8.spill	[r2]=r23,8;;
+	st8.spill	[r2]=r24,8;;
+	st8.spill	[r2]=r25,8;;
+	st8.spill	[r2]=r26,8;;
+	st8.spill	[r2]=r27,8;;
+	st8.spill	[r2]=r28,8;;
+	st8.spill	[r2]=r29,8;;
+	st8.spill	[r2]=r30,8;;
+	st8.spill	[r2]=r31,8;;
+
+	mov		r4=ar.unat;;
+	st8		[r2]=r4,8                // save User NaT bits for r16-r31
+	mov		ar.unat=r5                  // restore original unat
+	bsw.0;;
 
 //save BRs
-        add		r4=8,r2                  // duplicate r2 in r4
-        add		r6=2*8,r2                // duplicate r2 in r4
+	add		r4=8,r2                  // duplicate r2 in r4
+	add		r6=2*8,r2                // duplicate r2 in r4
 
-        mov		r3=b0
-        mov		r5=b1
-        mov		r7=b2;;
-        st8		[r2]=r3,3*8
-        st8		[r4]=r5,3*8
-        st8		[r6]=r7,3*8;;  
-
-        mov		r3=b3
-        mov		r5=b4
-        mov		r7=b5;;
-        st8		[r2]=r3,3*8
-        st8		[r4]=r5,3*8
-        st8		[r6]=r7,3*8;;  
-
-        mov		r3=b6
-        mov		r5=b7;;
-        st8		[r2]=r3,2*8
-        st8		[r4]=r5,2*8;;
+	mov		r3=b0
+	mov		r5=b1
+	mov		r7=b2;;
+	st8		[r2]=r3,3*8
+	st8		[r4]=r5,3*8
+	st8		[r6]=r7,3*8;;
+
+	mov		r3=b3
+	mov		r5=b4
+	mov		r7=b5;;
+	st8		[r2]=r3,3*8
+	st8		[r4]=r5,3*8
+	st8		[r6]=r7,3*8;;
+
+	mov		r3=b6
+	mov		r5=b7;;
+	st8		[r2]=r3,2*8
+	st8		[r4]=r5,2*8;;
 
 cSaveCRs:
 // save CRs
-        add		r4=8,r2                  // duplicate r2 in r4
-        add		r6=2*8,r2                // duplicate r2 in r4
+	add		r4=8,r2                  // duplicate r2 in r4
+	add		r6=2*8,r2                // duplicate r2 in r4
 
-        mov		r3=cr0                      // cr.dcr
-        mov		r5=cr1                      // cr.itm
-        mov		r7=cr2;;                    // cr.iva
-
-        st8		[r2]=r3,8*8
-        st8		[r4]=r5,3*8
-        st8		[r6]=r7,3*8;;            // 48 byte rements
+	mov		r3=cr0                      // cr.dcr
+	mov		r5=cr1                      // cr.itm
+	mov		r7=cr2;;                    // cr.iva
+
+	st8		[r2]=r3,8*8
+	st8		[r4]=r5,3*8
+	st8		[r6]=r7,3*8;;            // 48 byte rements
 
-        mov		r3=cr8;;                    // cr.pta
-        st8		[r2]=r3,8*8;;            // 64 byte rements
+	mov		r3=cr8;;                    // cr.pta
+	st8		[r2]=r3,8*8;;            // 64 byte rements
 
 // if PSR.ic=0, reading interruption registers causes an illegal operation fault
-        mov		r3=psr;;
-        tbit.nz.unc	p2,p0=r3,PSR_IC;;           // PSI Valid Log bit pos. test
-(p2)    st8		[r2]=r0,9*8+160             // increment by 168 byte inc.
-begin_skip_intr_regs:	
-	BRANCH(SkipIntrRegs,  r9, p2, 0x0)
-	;; 
-        add		r4=8,r2                  // duplicate r2 in r4
-        add		r6=2*8,r2                // duplicate r2 in r6
-        
-        mov		r3=cr16                     // cr.ipsr
-        mov		r5=cr17                     // cr.isr
-        mov		r7=r0;;                     // cr.ida => cr18
-        st8		[r2]=r3,3*8
-        st8		[r4]=r5,3*8
-        st8		[r6]=r7,3*8;;                                      
-
-        mov		r3=cr19                     // cr.iip
-        mov		r5=cr20                     // cr.idtr
-        mov		r7=cr21;;                   // cr.iitr
-        st8		[r2]=r3,3*8
-        st8		[r4]=r5,3*8
-        st8		[r6]=r7,3*8;;                                      
-
-        mov		r3=cr22                     // cr.iipa
-        mov		r5=cr23                     // cr.ifs
-        mov		r7=cr24;;                   // cr.iim
-        st8		[r2]=r3,3*8
-        st8		[r4]=r5,3*8
-        st8		[r6]=r7,3*8;;    
-                                          
-        mov		r3=cr25;;                   // cr.iha
-        st8		[r2]=r3,160;;               // 160 byte rement
+	mov		r3=psr;;
+	tbit.nz.unc	p6,p0=r3,PSR_IC;;           // PSI Valid Log bit pos. test
+(p6)    st8		[r2]=r0,9*8+160             // increment by 168 byte inc.
+begin_skip_intr_regs:
+	BRANCH(SkipIntrRegs,  r9, p6, 0x0)
+	;;
+	add		r4=8,r2                  // duplicate r2 in r4
+	add		r6=2*8,r2                // duplicate r2 in r6
+
+	mov		r3=cr16                     // cr.ipsr
+	mov		r5=cr17                     // cr.isr
+	mov		r7=r0;;                     // cr.ida => cr18
+	st8		[r2]=r3,3*8
+	st8		[r4]=r5,3*8
+	st8		[r6]=r7,3*8;;
+
+	mov		r3=cr19                     // cr.iip
+	mov		r5=cr20                     // cr.idtr
+	mov		r7=cr21;;                   // cr.iitr
+	st8		[r2]=r3,3*8
+	st8		[r4]=r5,3*8
+	st8		[r6]=r7,3*8;;
+
+	mov		r3=cr22                     // cr.iipa
+	mov		r5=cr23                     // cr.ifs
+	mov		r7=cr24;;                   // cr.iim
+	st8		[r2]=r3,3*8
+	st8		[r4]=r5,3*8
+	st8		[r6]=r7,3*8;;
+
+	mov		r3=cr25;;                   // cr.iha
+	st8		[r2]=r3,160;;               // 160 byte rement
 
 SkipIntrRegs:
-        st8		[r2]=r0,168                 // another 168 byte .
+	st8		[r2]=r0,168                 // another 168 byte .
 
-        mov		r3=cr66;;                   // cr.lid
-        st8		[r2]=r3,40                  // 40 byte rement
+	mov		r3=cr66;;                   // cr.lid
+	st8		[r2]=r3,40                  // 40 byte rement
 
-        mov		r3=cr71;;                   // cr.ivr
-        st8		[r2]=r3,8
+	mov		r3=cr71;;                   // cr.ivr
+	st8		[r2]=r3,8
 
-        mov		r3=cr72;;                   // cr.tpr
-        st8		[r2]=r3,24                  // 24 byte increment
-    
-        mov		r3=r0;;                     // cr.eoi => cr75
-        st8		[r2]=r3,168                 // 168 byte inc.
-    
-        mov		r3=r0;;                     // cr.irr0 => cr96
-        st8		[r2]=r3,16               // 16 byte inc.
+	mov		r3=cr72;;                   // cr.tpr
+	st8		[r2]=r3,24                  // 24 byte increment
 
-        mov		r3=r0;;                     // cr.irr1 => cr98
-        st8		[r2]=r3,16               // 16 byte inc.
+	mov		r3=r0;;                     // cr.eoi => cr75
+	st8		[r2]=r3,168                 // 168 byte inc.
 
-        mov		r3=r0;;                     // cr.irr2 => cr100
-        st8		[r2]=r3,16               // 16 byte inc
+	mov		r3=r0;;                     // cr.irr0 => cr96
+	st8		[r2]=r3,16               // 16 byte inc.
 
-        mov		r3=r0;;                     // cr.irr3 => cr100
-        st8		[r2]=r3,16               // 16b inc.
+	mov		r3=r0;;                     // cr.irr1 => cr98
+	st8		[r2]=r3,16               // 16 byte inc.
 
-        mov		r3=r0;;                     // cr.itv => cr114
-        st8		[r2]=r3,16               // 16 byte inc.
+	mov		r3=r0;;                     // cr.irr2 => cr100
+	st8		[r2]=r3,16               // 16 byte inc
 
-        mov		r3=r0;;                     // cr.pmv => cr116
-        st8		[r2]=r3,8
+	mov		r3=r0;;                     // cr.irr3 => cr100
+	st8		[r2]=r3,16               // 16b inc.
 
-        mov		r3=r0;;                     // cr.lrr0 => cr117
-        st8		[r2]=r3,8
+	mov		r3=r0;;                     // cr.itv => cr114
+	st8		[r2]=r3,16               // 16 byte inc.
 
-        mov		r3=r0;;                     // cr.lrr1 => cr118
-        st8		[r2]=r3,8
+	mov		r3=r0;;                     // cr.pmv => cr116
+	st8		[r2]=r3,8
 
-        mov		r3=r0;;                     // cr.cmcv => cr119
-        st8		[r2]=r3,8*10;;
+	mov		r3=r0;;                     // cr.lrr0 => cr117
+	st8		[r2]=r3,8
+
+	mov		r3=r0;;                     // cr.lrr1 => cr118
+	st8		[r2]=r3,8
+
+	mov		r3=r0;;                     // cr.cmcv => cr119
+	st8		[r2]=r3,8*10;;
 
 cSaveARs:
 // save ARs
-        add		r4=8,r2                  // duplicate r2 in r4
-        add		r6=2*8,r2                // duplicate r2 in r6
+	add		r4=8,r2                  // duplicate r2 in r4
+	add		r6=2*8,r2                // duplicate r2 in r6
 
-        mov		r3=ar0                      // ar.kro
-        mov		r5=ar1                      // ar.kr1
-        mov		r7=ar2;;                    // ar.kr2
-        st8		[r2]=r3,3*8
-        st8		[r4]=r5,3*8
-        st8		[r6]=r7,3*8;;
-
-        mov		r3=ar3                      // ar.kr3                               
-        mov		r5=ar4                      // ar.kr4
-        mov		r7=ar5;;                    // ar.kr5
-        st8		[r2]=r3,3*8
-        st8		[r4]=r5,3*8
-        st8		[r6]=r7,3*8;;
-
-        mov		r3=ar6                      // ar.kr6
-        mov		r5=ar7                      // ar.kr7
-        mov		r7=r0;;                     // ar.kr8
-        st8		[r2]=r3,10*8
-        st8		[r4]=r5,10*8
-        st8		[r6]=r7,10*8;;           // rement by 72 bytes
+	mov		r3=ar0                      // ar.kro
+	mov		r5=ar1                      // ar.kr1
+	mov		r7=ar2;;                    // ar.kr2
+	st8		[r2]=r3,3*8
+	st8		[r4]=r5,3*8
+	st8		[r6]=r7,3*8;;
+
+	mov		r3=ar3                      // ar.kr3
+	mov		r5=ar4                      // ar.kr4
+	mov		r7=ar5;;                    // ar.kr5
+	st8		[r2]=r3,3*8
+	st8		[r4]=r5,3*8
+	st8		[r6]=r7,3*8;;
+
+	mov		r3=ar6                      // ar.kr6
+	mov		r5=ar7                      // ar.kr7
+	mov		r7=r0;;                     // ar.kr8
+	st8		[r2]=r3,10*8
+	st8		[r4]=r5,10*8
+	st8		[r6]=r7,10*8;;           // rement by 72 bytes
 
-        mov		r3=ar16                     // ar.rsc
+	mov		r3=ar16                     // ar.rsc
 	mov		ar16=r0			    // put RSE in enforced lazy mode
-        mov		r5=ar17                     // ar.bsp
+	mov		r5=ar17                     // ar.bsp
 	;;
-        mov		r7=ar18;;                   // ar.bspstore
-        st8		[r2]=r3,3*8
-        st8		[r4]=r5,3*8
-        st8		[r6]=r7,3*8;;
+	mov		r7=ar18;;                   // ar.bspstore
+	st8		[r2]=r3,3*8
+	st8		[r4]=r5,3*8
+	st8		[r6]=r7,3*8;;
 
-        mov		r3=ar19;;                   // ar.rnat
-        st8		[r2]=r3,8*13             // increment by 13x8 bytes
+	mov		r3=ar19;;                   // ar.rnat
+	st8		[r2]=r3,8*13             // increment by 13x8 bytes
 
-        mov		r3=ar32;;                   // ar.ccv
-        st8		[r2]=r3,8*4
+	mov		r3=ar32;;                   // ar.ccv
+	st8		[r2]=r3,8*4
 
-        mov		r3=ar36;;                   // ar.unat
-        st8		[r2]=r3,8*4
+	mov		r3=ar36;;                   // ar.unat
+	st8		[r2]=r3,8*4
 
-        mov		r3=ar40;;                   // ar.fpsr
-        st8		[r2]=r3,8*4
+	mov		r3=ar40;;                   // ar.fpsr
+	st8		[r2]=r3,8*4
 
-        mov		r3=ar44;;                   // ar.itc
-        st8		[r2]=r3,160                 // 160
+	mov		r3=ar44;;                   // ar.itc
+	st8		[r2]=r3,160                 // 160
 
-        mov		r3=ar64;;                   // ar.pfs
-        st8		[r2]=r3,8
+	mov		r3=ar64;;                   // ar.pfs
+	st8		[r2]=r3,8
 
-        mov		r3=ar65;;                   // ar.lc
-        st8		[r2]=r3,8
+	mov		r3=ar65;;                   // ar.lc
+	st8		[r2]=r3,8
+
+	mov		r3=ar66;;                   // ar.ec
+	st8		[r2]=r3
+	add		r2=8*62,r2               //padding
 
-        mov		r3=ar66;;                   // ar.ec
-        st8		[r2]=r3
-        add		r2=8*62,r2               //padding
-    
 // save RRs
-        mov		ar.lc=0x08-1
-        movl		r4=0x00;;
+	mov		ar.lc=0x08-1
+	movl		r4=0x00;;
 
 cStRR:
-        mov		r3=rr[r4];;
-        st8		[r2]=r3,8
-        add		r4=1,r4
-        br.cloop.sptk.few	cStRR
-        ;;
+	mov		r3=rr[r4];;
+	st8		[r2]=r3,8
+	add		r4=1,r4
+	br.cloop.sptk.few	cStRR
+	;;
 end_os_mca_dump:
 	BRANCH(ia64_os_mca_done_dump, r2, p0, -0x10)
-        ;;
+	;;
 
 //EndStub//////////////////////////////////////////////////////////////////////
 
@@ -412,7 +403,7 @@
 //++
 // Name:
 //       ia64_os_mca_proc_state_restore()
-// 
+//
 // Stub Description:
 //
 //       This is a stub to restore the saved processor state during MCHK
@@ -421,225 +412,225 @@
 
 ia64_os_mca_proc_state_restore:
 
-// Restore bank1 GR16-31 
+// Restore bank1 GR16-31
 	movl		r2=ia64_mca_proc_state_dump	// Convert virtual address
 	;;						// of OS state dump area
 	DATA_VA_TO_PA(r2)				// to physical address
 	;;
 restore_GRs:                                    // restore bank-1 GRs 16-31
-        bsw.1;;
-        add		r3=16*8,r2;;                // to get to NaT of GR 16-31
-        ld8		r3=[r3];;
-        mov		ar.unat=r3;;                // first restore NaT
-
-        ld8.fill	r16=[r2],8;;
-        ld8.fill	r17=[r2],8;;
-        ld8.fill	r18=[r2],8;;
-        ld8.fill	r19=[r2],8;;
-        ld8.fill	r20=[r2],8;;
-        ld8.fill	r21=[r2],8;;
-        ld8.fill	r22=[r2],8;;
-        ld8.fill	r23=[r2],8;;
-        ld8.fill	r24=[r2],8;;
-        ld8.fill	r25=[r2],8;;
-        ld8.fill	r26=[r2],8;;
-        ld8.fill	r27=[r2],8;;
-        ld8.fill	r28=[r2],8;;
-        ld8.fill	r29=[r2],8;;
-        ld8.fill	r30=[r2],8;;
-        ld8.fill	r31=[r2],8;;
+	bsw.1;;
+	add		r3=16*8,r2;;                // to get to NaT of GR 16-31
+	ld8		r3=[r3];;
+	mov		ar.unat=r3;;                // first restore NaT
+
+	ld8.fill	r16=[r2],8;;
+	ld8.fill	r17=[r2],8;;
+	ld8.fill	r18=[r2],8;;
+	ld8.fill	r19=[r2],8;;
+	ld8.fill	r20=[r2],8;;
+	ld8.fill	r21=[r2],8;;
+	ld8.fill	r22=[r2],8;;
+	ld8.fill	r23=[r2],8;;
+	ld8.fill	r24=[r2],8;;
+	ld8.fill	r25=[r2],8;;
+	ld8.fill	r26=[r2],8;;
+	ld8.fill	r27=[r2],8;;
+	ld8.fill	r28=[r2],8;;
+	ld8.fill	r29=[r2],8;;
+	ld8.fill	r30=[r2],8;;
+	ld8.fill	r31=[r2],8;;
 
-        ld8		r3=[r2],8;;              // increment to skip NaT
-        bsw.0;;
+	ld8		r3=[r2],8;;              // increment to skip NaT
+	bsw.0;;
 
 restore_BRs:
-        add		r4=8,r2                  // duplicate r2 in r4
-        add		r6=2*8,r2;;              // duplicate r2 in r4
+	add		r4=8,r2                  // duplicate r2 in r4
+	add		r6=2*8,r2;;              // duplicate r2 in r4
 
-        ld8		r3=[r2],3*8
-        ld8		r5=[r4],3*8
-        ld8		r7=[r6],3*8;;  
-        mov		b0=r3
-        mov		b1=r5
-        mov		b2=r7;;
-
-        ld8		r3=[r2],3*8
-        ld8		r5=[r4],3*8
-        ld8		r7=[r6],3*8;;  
-        mov		b3=r3
-        mov		b4=r5
-        mov		b5=r7;;
-
-        ld8		r3=[r2],2*8
-        ld8		r5=[r4],2*8;;  
-        mov		b6=r3
-        mov		b7=r5;;
+	ld8		r3=[r2],3*8
+	ld8		r5=[r4],3*8
+	ld8		r7=[r6],3*8;;
+	mov		b0=r3
+	mov		b1=r5
+	mov		b2=r7;;
+
+	ld8		r3=[r2],3*8
+	ld8		r5=[r4],3*8
+	ld8		r7=[r6],3*8;;
+	mov		b3=r3
+	mov		b4=r5
+	mov		b5=r7;;
+
+	ld8		r3=[r2],2*8
+	ld8		r5=[r4],2*8;;
+	mov		b6=r3
+	mov		b7=r5;;
 
 restore_CRs:
-        add		r4=8,r2                  // duplicate r2 in r4
-        add		r6=2*8,r2;;              // duplicate r2 in r4
+	add		r4=8,r2                  // duplicate r2 in r4
+	add		r6=2*8,r2;;              // duplicate r2 in r4
 
-        ld8		r3=[r2],8*8
-        ld8		r5=[r4],3*8
-        ld8		r7=[r6],3*8;;            // 48 byte increments
-        mov		cr0=r3                      // cr.dcr
-        mov		cr1=r5                      // cr.itm
-        mov		cr2=r7;;                    // cr.iva
+	ld8		r3=[r2],8*8
+	ld8		r5=[r4],3*8
+	ld8		r7=[r6],3*8;;            // 48 byte increments
+	mov		cr0=r3                      // cr.dcr
+	mov		cr1=r5                      // cr.itm
+	mov		cr2=r7;;                    // cr.iva
 
-        ld8		r3=[r2],8*8;;            // 64 byte increments
+	ld8		r3=[r2],8*8;;            // 64 byte increments
 //      mov		cr8=r3                      // cr.pta
 
 
 // if PSR.ic=1, reading interruption registers causes an illegal operation fault
-        mov		r3=psr;;
-        tbit.nz.unc	p2,p0=r3,PSR_IC;;           // PSI Valid Log bit pos. test
-(p2)    st8		[r2]=r0,9*8+160             // increment by 160 byte inc.
-
-begin_rskip_intr_regs:	
-	BRANCH(rSkipIntrRegs, r9, p2, 0x0)
-	;; 
-
-        add		r4=8,r2                  // duplicate r2 in r4
-        add		r6=2*8,r2;;              // duplicate r2 in r4
-
-        ld8		r3=[r2],3*8
-        ld8		r5=[r4],3*8
-        ld8		r7=[r6],3*8;;
-        mov		cr16=r3                     // cr.ipsr
-        mov		cr17=r5                     // cr.isr is read only
+	mov		r3=psr;;
+	tbit.nz.unc	p6,p0=r3,PSR_IC;;           // PSI Valid Log bit pos. test
+(p6)    st8		[r2]=r0,9*8+160             // increment by 160 byte inc.
+
+begin_rskip_intr_regs:
+	BRANCH(rSkipIntrRegs, r9, p6, 0x0)
+	;;
+
+	add		r4=8,r2                  // duplicate r2 in r4
+	add		r6=2*8,r2;;              // duplicate r2 in r4
+
+	ld8		r3=[r2],3*8
+	ld8		r5=[r4],3*8
+	ld8		r7=[r6],3*8;;
+	mov		cr16=r3                     // cr.ipsr
+	mov		cr17=r5                     // cr.isr is read only
 //      mov		cr18=r7;;                   // cr.ida
 
-        ld8		r3=[r2],3*8
-        ld8		r5=[r4],3*8
-        ld8		r7=[r6],3*8;;
-        mov		cr19=r3                     // cr.iip
-        mov		cr20=r5                     // cr.idtr
-        mov		cr21=r7;;                   // cr.iitr
-
-        ld8		r3=[r2],3*8
-        ld8		r5=[r4],3*8
-        ld8		r7=[r6],3*8;;
-        mov		cr22=r3                     // cr.iipa
-        mov		cr23=r5                     // cr.ifs
-        mov		cr24=r7                     // cr.iim
+	ld8		r3=[r2],3*8
+	ld8		r5=[r4],3*8
+	ld8		r7=[r6],3*8;;
+	mov		cr19=r3                     // cr.iip
+	mov		cr20=r5                     // cr.idtr
+	mov		cr21=r7;;                   // cr.iitr
+
+	ld8		r3=[r2],3*8
+	ld8		r5=[r4],3*8
+	ld8		r7=[r6],3*8;;
+	mov		cr22=r3                     // cr.iipa
+	mov		cr23=r5                     // cr.ifs
+	mov		cr24=r7                     // cr.iim
 
-        ld8		r3=[r2],160;;               // 160 byte increment
-        mov		cr25=r3                     // cr.iha 
+	ld8		r3=[r2],160;;               // 160 byte increment
+	mov		cr25=r3                     // cr.iha
 
 rSkipIntrRegs:
-        ld8		r3=[r2],168;;               // another 168 byte inc.
+	ld8		r3=[r2],168;;               // another 168 byte inc.
 
-        ld8		r3=[r2],40;;                // 40 byte increment
-        mov		cr66=r3                     // cr.lid
+	ld8		r3=[r2],40;;                // 40 byte increment
+	mov		cr66=r3                     // cr.lid
 
-        ld8		r3=[r2],8;;
+	ld8		r3=[r2],8;;
 //      mov		cr71=r3                     // cr.ivr is read only
-        ld8		r3=[r2],24;;                // 24 byte increment
-        mov		cr72=r3                     // cr.tpr
-   
-        ld8		r3=[r2],168;;               // 168 byte inc.
+	ld8		r3=[r2],24;;                // 24 byte increment
+	mov		cr72=r3                     // cr.tpr
+
+	ld8		r3=[r2],168;;               // 168 byte inc.
 //      mov		cr75=r3                     // cr.eoi
-   
-        ld8		r3=[r2],16;;             // 16 byte inc.
+
+	ld8		r3=[r2],16;;             // 16 byte inc.
 //      mov		cr96=r3                     // cr.irr0 is read only
 
-        ld8		r3=[r2],16;;             // 16 byte inc.
+	ld8		r3=[r2],16;;             // 16 byte inc.
 //      mov		cr98=r3                     // cr.irr1 is read only
 
-        ld8		r3=[r2],16;;             // 16 byte inc
+	ld8		r3=[r2],16;;             // 16 byte inc
 //      mov		cr100=r3                    // cr.irr2 is read only
 
-        ld8		r3=[r2],16;;             // 16b inc.
+	ld8		r3=[r2],16;;             // 16b inc.
 //      mov		cr102=r3                    // cr.irr3 is read only
 
-        ld8		r3=[r2],16;;             // 16 byte inc.
+	ld8		r3=[r2],16;;             // 16 byte inc.
 //      mov		cr114=r3                    // cr.itv
 
-        ld8		r3=[r2],8;;
+	ld8		r3=[r2],8;;
 //      mov		cr116=r3                    // cr.pmv
-        ld8		r3=[r2],8;;
+	ld8		r3=[r2],8;;
 //      mov		cr117=r3                    // cr.lrr0
-        ld8		r3=[r2],8;;
+	ld8		r3=[r2],8;;
 //      mov		cr118=r3                    // cr.lrr1
-        ld8		r3=[r2],8*10;;
+	ld8		r3=[r2],8*10;;
 //      mov		cr119=r3                    // cr.cmcv
 
 restore_ARs:
-        add		r4=8,r2                  // duplicate r2 in r4
-        add		r6=2*8,r2;;              // duplicate r2 in r4
+	add		r4=8,r2                  // duplicate r2 in r4
+	add		r6=2*8,r2;;              // duplicate r2 in r4
 
-        ld8		r3=[r2],3*8
-        ld8		r5=[r4],3*8
-        ld8		r7=[r6],3*8;;
-        mov		ar0=r3                      // ar.kro
-        mov		ar1=r5                      // ar.kr1
-        mov		ar2=r7;;                    // ar.kr2
-
-        ld8		r3=[r2],3*8
-        ld8		r5=[r4],3*8
-        ld8		r7=[r6],3*8;;
-        mov		ar3=r3                      // ar.kr3                               
-        mov		ar4=r5                      // ar.kr4
-        mov		ar5=r7;;                    // ar.kr5
-
-        ld8		r3=[r2],10*8
-        ld8		r5=[r4],10*8
-        ld8		r7=[r6],10*8;;
-        mov		ar6=r3                      // ar.kr6
-        mov		ar7=r5                      // ar.kr7
+	ld8		r3=[r2],3*8
+	ld8		r5=[r4],3*8
+	ld8		r7=[r6],3*8;;
+	mov		ar0=r3                      // ar.kro
+	mov		ar1=r5                      // ar.kr1
+	mov		ar2=r7;;                    // ar.kr2
+
+	ld8		r3=[r2],3*8
+	ld8		r5=[r4],3*8
+	ld8		r7=[r6],3*8;;
+	mov		ar3=r3                      // ar.kr3
+	mov		ar4=r5                      // ar.kr4
+	mov		ar5=r7;;                    // ar.kr5
+
+	ld8		r3=[r2],10*8
+	ld8		r5=[r4],10*8
+	ld8		r7=[r6],10*8;;
+	mov		ar6=r3                      // ar.kr6
+	mov		ar7=r5                      // ar.kr7
 //      mov		ar8=r6                      // ar.kr8
-        ;;
+	;;
 
-        ld8		r3=[r2],3*8
-        ld8		r5=[r4],3*8
-        ld8		r7=[r6],3*8;;
+	ld8		r3=[r2],3*8
+	ld8		r5=[r4],3*8
+	ld8		r7=[r6],3*8;;
 //      mov		ar16=r3                     // ar.rsc
 //      mov		ar17=r5                     // ar.bsp is read only
 	mov		ar16=r0			    // make sure that RSE is in enforced lazy mode
 	;;
-        mov		ar18=r7;;                   // ar.bspstore
+	mov		ar18=r7;;                   // ar.bspstore
 
-        ld8		r9=[r2],8*13;;
-        mov		ar19=r9                     // ar.rnat
+	ld8		r9=[r2],8*13;;
+	mov		ar19=r9                     // ar.rnat
 
 	mov		ar16=r3			    // ar.rsc
-        ld8		r3=[r2],8*4;;
-        mov		ar32=r3                     // ar.ccv
+	ld8		r3=[r2],8*4;;
+	mov		ar32=r3                     // ar.ccv
 
-        ld8		r3=[r2],8*4;;
-        mov		ar36=r3                     // ar.unat
+	ld8		r3=[r2],8*4;;
+	mov		ar36=r3                     // ar.unat
 
-        ld8		r3=[r2],8*4;;
-        mov		ar40=r3                     // ar.fpsr
+	ld8		r3=[r2],8*4;;
+	mov		ar40=r3                     // ar.fpsr
 
-        ld8		r3=[r2],160;;               // 160
+	ld8		r3=[r2],160;;               // 160
 //      mov		ar44=r3                     // ar.itc
 
-        ld8		r3=[r2],8;;
-        mov		ar64=r3                     // ar.pfs
+	ld8		r3=[r2],8;;
+	mov		ar64=r3                     // ar.pfs
+
+	ld8		r3=[r2],8;;
+	mov		ar65=r3                     // ar.lc
 
-        ld8		r3=[r2],8;;
-        mov		ar65=r3                     // ar.lc
+	ld8		r3=[r2];;
+	mov		ar66=r3                     // ar.ec
+	add		r2=8*62,r2;;             // padding
 
-        ld8		r3=[r2];;
-        mov		ar66=r3                     // ar.ec
-        add		r2=8*62,r2;;             // padding 
-    
 restore_RRs:
-        mov		r5=ar.lc
-        mov		ar.lc=0x08-1
-        movl		r4=0x00
+	mov		r5=ar.lc
+	mov		ar.lc=0x08-1
+	movl		r4=0x00
 cStRRr:
-        ld8		r3=[r2],8;;
+	ld8		r3=[r2],8;;
 //      mov		rr[r4]=r3                   // what are its access previledges?
-        add		r4=1,r4
-        br.cloop.sptk.few	cStRRr
-        ;;
-        mov		ar.lc=r5
+	add		r4=1,r4
+	br.cloop.sptk.few	cStRRr
+	;;
+	mov		ar.lc=r5
 	;;
 end_os_mca_restore:
 	BRANCH(ia64_os_mca_done_restore, r2, p0, -0x20)
-	;; 
+	;;
 //EndStub//////////////////////////////////////////////////////////////////////
 
 // ok, the issue here is that we need to save state information so
@@ -647,16 +638,16 @@
 // In order to do this, our best bet is save the current state (plus
 // the state information obtain from the MIN_STATE_AREA) into a pt_regs
 // format.  This way we can pass it on in a useable format.
-//				
+//
 
 //
 // SAL to OS entry point for INIT on the monarch processor
-// This has been defined for registration purposes with SAL 
+// This has been defined for registration purposes with SAL
 // as a part of ia64_mca_init.
 //
 // When we get here, the follow registers have been
 // set by the SAL for our use
-//		
+//
 //		1. GR1 = OS INIT GP
 //		2. GR8 = PAL_PROC physical address
 //		3. GR9 = SAL_PROC physical address
@@ -665,14 +656,14 @@
 //			0 = Received INIT for event other than crash dump switch
 //			1 = Received wakeup at the end of an OS_MCA corrected machine check
 //			2 = Received INIT dude to CrashDump switch assertion
-//	
+//
 //		6. GR12 = Return address to location within SAL_INIT procedure
 
-				
+
 	.text
 	.align 16
-.global ia64_monarch_init_handler       
-.proc ia64_monarch_init_handler       
+.global ia64_monarch_init_handler
+.proc ia64_monarch_init_handler
 ia64_monarch_init_handler:
 
 #if defined(CONFIG_SMP) && defined(SAL_MPINIT_WORKAROUND)
@@ -680,6 +671,7 @@
 	// work around SAL bug that sends all processors to monarch entry
 	//
 	mov	r17=cr.lid
+	// XXX fix me: this is wrong: hard_smp_processor_id() is a pair of lid/eid
 	movl	r18=__cpu_physical_id
 	;;
 	dep	r18=0,r18,61,3		// convert to physical address
@@ -694,7 +686,7 @@
 	;;
 #endif
 
-	
+
 //
 // ok, the first thing we do is stash the information
 // the SAL passed to os
@@ -706,8 +698,8 @@
 	;;
 	st8	[_tmp]=r1,0x08;;
 	st8	[_tmp]=r8,0x08;;
-	st8	[_tmp]=r9,0x08;;			
-	st8	[_tmp]=r10,0x08;;			
+	st8	[_tmp]=r9,0x08;;
+	st8	[_tmp]=r10,0x08;;
 	st8	[_tmp]=r11,0x08;;
 	st8	[_tmp]=r12,0x08;;
 
@@ -719,12 +711,12 @@
 	adds r3=8,r2				// set up second base pointer
 	;;
 	SAVE_REST
-	
+
 // ok, enough should be saved at this point to be dangerous, and  supply
 // information for a dump
 // We need to switch to Virtual mode before hitting the C functions.
 //
-// 
+//
 //
 	movl	r2=IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN
 	mov	r3=psr	// get the current psr, minimum enabled at this point
@@ -739,7 +731,7 @@
 	rfi
 	;;
 IVirtual_Switch:
-	//	
+	//
 	// We should now be running virtual
 	//
 	// Lets call the C handler to get the rest of the state info
@@ -759,7 +751,7 @@
 
 //
 // SAL to OS entry point for INIT on the slave processor
-// This has been defined for registration purposes with SAL 
+// This has been defined for registration purposes with SAL
 // as a part of ia64_mca_init.
 //
 
@@ -767,10 +759,10 @@
 	.align 16
 .global ia64_slave_init_handler
 .proc ia64_slave_init_handler
-ia64_slave_init_handler:		
+ia64_slave_init_handler:
 
 
-slave_init_spin_me:	
+slave_init_spin_me:
 	br.sptk slave_init_spin_me
 	;;
 	.endp
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/minstate.h linux/arch/ia64/kernel/minstate.h
--- v2.4.3/linux/arch/ia64/kernel/minstate.h	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/minstate.h	Thu Apr  5 12:51:47 2001
@@ -29,20 +29,20 @@
  */
 #define MINSTATE_START_SAVE_MIN_VIRT								\
 	dep r1=-1,r1,61,3;				/* r1 = current (virtual) */		\
-(p7)	mov ar.rsc=r0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
+(pUser)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
 	;;											\
-(p7)	addl rKRBS=IA64_RBS_OFFSET,r1;			/* compute base of RBS */		\
-(p7)	mov rARRNAT=ar.rnat;									\
+(pUser)	addl rKRBS=IA64_RBS_OFFSET,r1;			/* compute base of RBS */		\
+(pUser)	mov rARRNAT=ar.rnat;									\
 (pKern) mov r1=sp;					/* get sp  */				\
 	;;											\
-(p7)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
-(p7)	mov rARBSPSTORE=ar.bspstore;			/* save ar.bspstore */			\
+(pUser)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
+(pUser)	mov rARBSPSTORE=ar.bspstore;			/* save ar.bspstore */			\
 	;;											\
 (pKern) addl r1=-IA64_PT_REGS_SIZE,r1;			/* if in kernel mode, use sp (r12) */	\
-(p7)	mov ar.bspstore=rKRBS;				/* switch to kernel RBS */		\
+(pUser)	mov ar.bspstore=rKRBS;				/* switch to kernel RBS */		\
 	;;											\
-(p7)	mov r18=ar.bsp;										\
-(p7)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
+(pUser)	mov r18=ar.bsp;										\
+(pUser)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
 
 #define MINSTATE_END_SAVE_MIN_VIRT								\
 	or r13=r13,r14;		/* make `current' a kernel virtual address */			\
@@ -55,20 +55,20 @@
  */
 #define MINSTATE_START_SAVE_MIN_PHYS								\
 (pKern) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE;				\
-(p7)	mov ar.rsc=r0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
-(p7)	addl rKRBS=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
+(pUser)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
+(pUser)	addl rKRBS=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
 	;;											\
-(p7)	mov rARRNAT=ar.rnat;									\
+(pUser)	mov rARRNAT=ar.rnat;									\
 (pKern) dep r1=0,sp,61,3;				/* compute physical addr of sp	*/	\
-(p7)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
-(p7)	mov rARBSPSTORE=ar.bspstore;			/* save ar.bspstore */			\
-(p7)	dep rKRBS=-1,rKRBS,61,3;			/* compute kernel virtual addr of RBS */\
+(pUser)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
+(pUser)	mov rARBSPSTORE=ar.bspstore;			/* save ar.bspstore */			\
+(pUser)	dep rKRBS=-1,rKRBS,61,3;			/* compute kernel virtual addr of RBS */\
 	;;											\
 (pKern) addl r1=-IA64_PT_REGS_SIZE,r1;		/* if in kernel mode, use sp (r12) */		\
-(p7)	mov ar.bspstore=rKRBS;			/* switch to kernel RBS */			\
+(pUser)	mov ar.bspstore=rKRBS;			/* switch to kernel RBS */			\
 	;;											\
-(p7)	mov r18=ar.bsp;										\
-(p7)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
+(pUser)	mov r18=ar.bsp;										\
+(pUser)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
 
 #define MINSTATE_END_SAVE_MIN_PHYS								\
 	or r12=r12,r14;		/* make sp a kernel virtual address */				\
@@ -101,29 +101,30 @@
  *	r12 = kernel sp (kernel virtual address)
  *	r13 = points to current task_struct (kernel virtual address)
  *	p15 = TRUE if psr.i is set in cr.ipsr
- *	predicate registers (other than p6, p7, and p15), b6, r3, r8, r9, r10, r11, r14, r15:
+ *	predicate registers (other than p2, p3, and p15), b6, r3, r8, r9, r10, r11, r14, r15:
  *		preserved
  *
  * Note that psr.ic is NOT turned on by this macro.  This is so that
  * we can pass interruption state as arguments to a handler.
  */
-#define DO_SAVE_MIN(COVER,EXTRA)								  \
+#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA)							  \
 	mov rARRSC=ar.rsc;									  \
 	mov rARPFS=ar.pfs;									  \
 	mov rR1=r1;										  \
 	mov rARUNAT=ar.unat;									  \
 	mov rCRIPSR=cr.ipsr;									  \
-	mov rB6=b6;		/* rB6 = branch reg 6 */					  \
+	mov rB6=b6;				/* rB6 = branch reg 6 */			  \
 	mov rCRIIP=cr.iip;									  \
-	mov r1=ar.k6;		/* r1 = current (physical) */					  \
+	mov r1=IA64_KR(CURRENT);		/* r1 = current (physical) */			  \
+	COVER;											  \
 	;;											  \
 	invala;											  \
 	extr.u r16=rCRIPSR,32,2;		/* extract psr.cpl */				  \
 	;;											  \
-	cmp.eq pKern,p7=r0,r16;			/* are we in kernel mode already? (psr.cpl==0) */ \
+	cmp.eq pKern,pUser=r0,r16;		/* are we in kernel mode already? (psr.cpl==0) */ \
 	/* switch from user to kernel RBS: */							  \
-	COVER;											  \
 	;;											  \
+	SAVE_IFS;										  \
 	MINSTATE_START_SAVE_MIN									  \
 	;;											  \
 	mov r16=r1;					/* initialize first base pointer */	  \
@@ -135,7 +136,7 @@
 	;;											  \
 	st8 [r16]=rCRIFS,16;	/* save cr.ifs */						  \
 	st8 [r17]=rARUNAT,16;	/* save ar.unat */						  \
-(p7)	sub r18=r18,rKRBS;	/* r18=RSE.ndirty*8 */						  \
+(pUser)	sub r18=r18,rKRBS;	/* r18=RSE.ndirty*8 */						  \
 	;;											  \
 	st8 [r16]=rARPFS,16;	/* save ar.pfs */						  \
 	st8 [r17]=rARRSC,16;	/* save ar.rsc */						  \
@@ -143,8 +144,8 @@
 	;;			/* avoid RAW on r16 & r17 */					  \
 (pKern)	adds r16=16,r16;	/* skip over ar_rnat field */					  \
 (pKern)	adds r17=16,r17;	/* skip over ar_bspstore field */				  \
-(p7)	st8 [r16]=rARRNAT,16;	/* save ar.rnat */						  \
-(p7)	st8 [r17]=rARBSPSTORE,16;	/* save ar.bspstore */					  \
+(pUser)	st8 [r16]=rARRNAT,16;	/* save ar.rnat */						  \
+(pUser)	st8 [r17]=rARBSPSTORE,16;	/* save ar.bspstore */					  \
 	;;											  \
 	st8 [r16]=rARPR,16;	/* save predicates */						  \
 	st8 [r17]=rB6,16;	/* save b6 */							  \
@@ -171,7 +172,7 @@
 	;;											  \
 .mem.offset 0,0;		st8.spill [r16]=r10,16;						  \
 .mem.offset 8,0;		st8.spill [r17]=r11,16;						  \
-	mov r13=ar.k6;		/* establish `current' */					  \
+	mov r13=IA64_KR(CURRENT);	/* establish `current' */				  \
 	;;											  \
 	EXTRA;											  \
 	movl r1=__gp;		/* establish kernel global pointer */				  \
@@ -240,6 +241,6 @@
 # define STOPS
 #endif
 
-#define SAVE_MIN_WITH_COVER	DO_SAVE_MIN(cover;; mov rCRIFS=cr.ifs,) STOPS
-#define SAVE_MIN_WITH_COVER_R19	DO_SAVE_MIN(cover;; mov rCRIFS=cr.ifs, mov r15=r19) STOPS
-#define SAVE_MIN		DO_SAVE_MIN(mov rCRIFS=r0,) STOPS
+#define SAVE_MIN_WITH_COVER	DO_SAVE_MIN(cover, mov rCRIFS=cr.ifs,) STOPS
+#define SAVE_MIN_WITH_COVER_R19	DO_SAVE_MIN(cover, mov rCRIFS=cr.ifs, mov r15=r19) STOPS
+#define SAVE_MIN		DO_SAVE_MIN(     , mov rCRIFS=r0, ) STOPS
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/pal.S linux/arch/ia64/kernel/pal.S
--- v2.4.3/linux/arch/ia64/kernel/pal.S	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/pal.S	Thu Apr  5 12:51:47 2001
@@ -14,11 +14,6 @@
 #include <asm/asmmacro.h>
 #include <asm/processor.h>
 
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
-
 	.data
 pal_entry_point:
 	data8 ia64_pal_default_handler
@@ -58,7 +53,7 @@
  *
  */
 GLOBAL_ENTRY(ia64_pal_call_static)
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6))
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6)
 	alloc loc1 = ar.pfs,6,90,0,0
 	movl loc2 = pal_entry_point
 1:	{
@@ -73,7 +68,7 @@
 	;;
 	mov loc3 = psr
 	mov loc0 = rp
-	UNW(.body)
+	.body
 	mov r30 = in2
 
 (p6)	rsm psr.i | psr.ic
@@ -101,14 +96,14 @@
  * 	in2 - in3   Remaning PAL arguments
  */
 GLOBAL_ENTRY(ia64_pal_call_stacked)
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5))
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
 	alloc loc1 = ar.pfs,5,4,87,0
 	movl loc2 = pal_entry_point
 
 	mov r28  = in0			// Index MUST be copied to r28
 	mov out0 = in0			// AND in0 of PAL function
 	mov loc0 = rp
-	UNW(.body)
+	.body
 	;;
 	ld8 loc2 = [loc2]		// loc2 <- entry point
 	mov out1 = in1
@@ -148,7 +143,7 @@
 
 
 GLOBAL_ENTRY(ia64_pal_call_phys_static)
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6))
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6)
 	alloc loc1 = ar.pfs,6,90,0,0
 	movl loc2 = pal_entry_point
 1:	{
@@ -156,7 +151,7 @@
 	  mov r8   = ip			// save ip to compute branch
 	  mov loc0 = rp			// save rp
 	}
-	UNW(.body)
+	.body
 	;;
 	ld8 loc2 = [loc2]		// loc2 <- entry point
 	mov r29  = in1			// first argument
@@ -171,7 +166,7 @@
 	dep.z r8=r8,0,61		// convert rp to physical
 	;;
 	mov b7 = loc2			// install target to branch reg
-	mov ar.rsc=r0			// put RSE in enforced lazy, LE mode
+	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	movl r16=PAL_PSR_BITS_TO_CLEAR
 	movl r17=PAL_PSR_BITS_TO_SET
 	;;
@@ -182,7 +177,7 @@
 .ret1:	mov rp = r8			// install return address (physical)
 	br.cond.sptk.few b7
 1:
-	mov ar.rsc=r0			// put RSE in enforced lazy, LE mode
+	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	mov r16=loc3			// r16= original psr
 	br.call.sptk.few rp=ia64_switch_mode // return to virtual mode
 .ret2:
@@ -204,7 +199,7 @@
  * 	in2 - in3   Remaning PAL arguments
  */
 GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
-	UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5))
+	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
 	alloc	loc1 = ar.pfs,5,5,86,0
 	movl	loc2 = pal_entry_point
 1:	{
@@ -224,7 +219,7 @@
 	mov loc4=ar.rsc			// save RSE configuration
 	dep.z loc2=loc2,0,61		// convert pal entry point to physical
 	;;
-	mov ar.rsc=r0			// put RSE in enforced lazy, LE mode
+	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	movl r16=PAL_PSR_BITS_TO_CLEAR
 	movl r17=PAL_PSR_BITS_TO_SET
 	;;
@@ -236,7 +231,7 @@
 .ret6:
 	br.call.sptk.many rp=b7		// now make the call
 .ret7:
-	mov ar.rsc=r0			// put RSE in enforced lazy, LE mode
+	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	mov r16=loc3			// r16= original psr
 	br.call.sptk.few rp=ia64_switch_mode	// return to virtual mode
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/palinfo.c linux/arch/ia64/kernel/palinfo.c
--- v2.4.3/linux/arch/ia64/kernel/palinfo.c	Fri Feb 16 15:53:08 2001
+++ linux/arch/ia64/kernel/palinfo.c	Thu Apr  5 12:51:47 2001
@@ -5,16 +5,13 @@
  * This code is based on specification of PAL as of the
  * Intel IA-64 Architecture Software Developer's Manual v1.0.
  *
- * 
+ *
  * Copyright (C) 2000 Hewlett-Packard Co
  * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com>
- * 
+ *
  * 05/26/2000	S.Eranian	initial release
  * 08/21/2000	S.Eranian	updated to July 2000 PAL specs
- *
- * ISSUES:
- *	- as of 2.2.9/2.2.12, the following values are still wrong
- *		PAL_VM_SUMMARY: key & rid sizes
+ * 02/05/2001   S.Eranian	fixed module support
  */
 #include <linux/config.h>
 #include <linux/types.h>
@@ -36,12 +33,7 @@
 MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>");
 MODULE_DESCRIPTION("/proc interface to IA-64 PAL");
 
-/*
- * Hope to get rid of this one in a near future
-*/
-#define IA64_PAL_VERSION_BUG		1
-
-#define PALINFO_VERSION "0.3"
+#define PALINFO_VERSION "0.4"
 
 #ifdef CONFIG_SMP
 #define cpu_is_online(i) (cpu_online_map & (1UL << i))
@@ -83,7 +75,7 @@
 	"Non-temporal, all levels",
 	"Reserved",
 	"Reserved",
-	"Reserved",	
+	"Reserved",
 	"Reserved"
 };
 
@@ -94,7 +86,7 @@
 	"Non-temporal, all levels",
 	"Reserved",
 	"Reserved",
-	"Reserved",	
+	"Reserved",
 	"Reserved"
 };
 
@@ -108,7 +100,7 @@
 #define RSE_HINTS_COUNT (sizeof(rse_hints)/sizeof(const char *))
 
 /*
- * The current revision of the Volume 2 (July 2000) of 
+ * 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:
@@ -116,7 +108,7 @@
  *      bit 4 - 100 - UC
  *      bit 5 - 101 - UCE
  *      bit 6 - 110 - WC
- *      bit 7 - 111 - NatPage 
+ *      bit 7 - 111 - NatPage
  */
 static const char *mem_attrib[]={
 	"Write Back (WB)",		/* 000 */
@@ -136,7 +128,7 @@
  *
  * Input:
  *	- a pointer to a buffer to hold the string
- * 	- a 64-bit vector
+ *	- a 64-bit vector
  * Ouput:
  *	- a pointer to the end of the buffer
  *
@@ -163,7 +155,7 @@
  *
  * Input:
  *	- a pointer to a buffer to hold the string
- * 	- a 64-bit vector
+ *	- a 64-bit vector
  * Ouput:
  *	- a pointer to the end of the buffer
  *
@@ -181,7 +173,7 @@
 		if (i != 0 && (i%64) == 0) value = *++reg_info;
 
 		if ((value & 0x1) == 0 && skip == 0) {
-			if (begin  <= i - 2) 
+			if (begin  <= i - 2)
 				p += sprintf(p, "%d-%d ", begin, i-1);
 			else
 				p += sprintf(p, "%d ", i-1);
@@ -194,7 +186,7 @@
 		value >>=1;
 	}
 	if (begin > -1) {
-		if (begin < 127) 
+		if (begin < 127)
 			p += sprintf(p, "%d-127", begin);
 		else
 			p += sprintf(p, "127");
@@ -219,7 +211,7 @@
 		if (halt_info[i].pal_power_mgmt_info_s.im == 1) {
 			p += sprintf(p,	"Power level %d:\n" \
 					"\tentry_latency       : %d cycles\n" \
-				 	"\texit_latency        : %d cycles\n" \
+					"\texit_latency        : %d cycles\n" \
 					"\tpower consumption   : %d mW\n" \
 					"\tCache+TLB coherency : %s\n", i,
 				halt_info[i].pal_power_mgmt_info_s.entry_latency,
@@ -233,7 +225,7 @@
 	return p - page;
 }
 
-static int 
+static int
 cache_info(char *page)
 {
 	char *p = page;
@@ -288,13 +280,13 @@
 
 			for(k=0; k < 8; k++ ) {
 				if ( cci.pcci_st_hints & 0x1) p += sprintf(p, "[%s]", cache_st_hints[k]);
-				cci.pcci_st_hints >>=1; 
+				cci.pcci_st_hints >>=1;
 			}
 			p += sprintf(p, "\n\tLoad hints     : ");
 
 			for(k=0; k < 8; k++ ) {
 				if ( cci.pcci_ld_hints & 0x1) p += sprintf(p, "[%s]", cache_ld_hints[k]);
-				cci.pcci_ld_hints >>=1; 
+				cci.pcci_ld_hints >>=1;
 			}
 			p += sprintf(p, "\n\tAlias boundary : %d byte(s)\n" \
 					"\tTag LSB        : %d\n" \
@@ -384,7 +376,7 @@
 			ptce.stride[1]);
 
 	p += sprintf(p, "TC Levels                      : %d\n" \
-			"Unique TC(s)                   : %d\n", 
+			"Unique TC(s)                   : %d\n",
 			vm_info_1.pal_vm_info_1_s.num_tc_levels,
 			vm_info_1.pal_vm_info_1_s.max_unique_tcs);
 
@@ -392,7 +384,7 @@
 		for (j=2; j>0 ; j--) {
 			tc_pages = 0; /* just in case */
 
-		
+
 			/* even without unification, some levels may not be present */
 			if ((status=ia64_pal_vm_info(i,j, &tc_info, &tc_pages)) != 0) {
 				continue;
@@ -422,7 +414,7 @@
 	}
 	p += sprintf(p, "\n");
 
-	return p - page;	
+	return p - page;
 }
 
 
@@ -446,7 +438,7 @@
 
 		if (ia64_pal_register_info(info, &reg_info[0], &reg_info[1]) != 0) return 0;
 
-	 	p += sprintf(p, "%-32s : ", info_type[info]);
+		p += sprintf(p, "%-32s : ", info_type[info]);
 
 		p = bitregister_process(p, reg_info, 128);
 
@@ -458,8 +450,8 @@
 	p += sprintf(p, "RSE stacked physical registers   : %ld\n" \
 			"RSE load/store hints             : %ld (%s)\n",
 			phys_stacked,
-			hints.ph_data, 
-		     	hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(\?\?)");
+			hints.ph_data,
+			hints.ph_data < RSE_HINTS_COUNT ? rse_hints[hints.ph_data]: "(\?\?)");
 
 	if (ia64_pal_debug_info(&iregs, &dregs)) return 0;
 
@@ -486,15 +478,15 @@
 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	"Disable BINIT on processor time-out",
 	"Disable dynamic power management (DPM)",
-	"Disable coherency", 
-	"Disable cache", 
+	"Disable coherency",
+	"Disable cache",
 	"Enable CMCI promotion",
 	"Enable MCA to BINIT promotion",
 	"Enable MCA promotion",
 	"Enable BEER promotion"
 };
 
-	
+
 static int
 processor_info(char *page)
 {
@@ -508,7 +500,7 @@
 
 	for(i=0; i < 64; i++, v++,avail >>=1, status >>=1, control >>=1) {
 		if ( ! *v ) continue;
-		p += sprintf(p, "%-40s : %s%s %s\n", *v, 
+		p += sprintf(p, "%-40s : %s%s %s\n", *v,
 				avail & 0x1 ? "" : "NotImpl",
 				avail & 0x1 ? (status & 0x1 ? "On" : "Off"): "",
 				avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): "");
@@ -526,9 +518,9 @@
 	"Enable Half Transfer",
 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL, 
-	"Enable Cache Line Repl. Exclusive", 
-	"Enable Cache Line Repl. Shared", 
+	NULL, NULL, NULL, NULL,
+	"Enable Cache Line Repl. Exclusive",
+	"Enable Cache Line Repl. Shared",
 	"Disable Transaction Queuing",
 	"Disable Reponse Error Checking",
 	"Disable Bus Error Checking",
@@ -541,7 +533,7 @@
 	"Disable Bus Data Error Checking"
 };
 
-	
+
 static int
 bus_info(char *page)
 {
@@ -560,7 +552,7 @@
 
 	for(i=0; i < 64; i++, v++, avail >>=1, status >>=1, control >>=1) {
 		if ( ! *v ) continue;
-		p += sprintf(p, "%-48s : %s%s %s\n", *v, 
+		p += sprintf(p, "%-48s : %s%s %s\n", *v,
 				avail & 0x1 ? "" : "NotImpl",
 				avail & 0x1 ? (status  & 0x1 ? "On" : "Off"): "",
 				avail & 0x1 ? (control & 0x1 ? "Ctrl" : "NoCtrl"): "");
@@ -568,62 +560,39 @@
 	return p - page;
 }
 
-
-/*
- * physical mode call for PAL_VERSION is working fine.
- * This function is meant to go away once PAL get fixed.
- */
-static inline s64 
-ia64_pal_version_phys(pal_version_u_t *pal_min_version, pal_version_u_t *pal_cur_version) 
-{	
-	struct ia64_pal_retval iprv;
-	PAL_CALL_PHYS(iprv, PAL_VERSION, 0, 0, 0);
-	if (pal_min_version)
-		pal_min_version->pal_version_val = iprv.v0;
-	if (pal_cur_version)
-		pal_cur_version->pal_version_val = iprv.v1;
-	return iprv.status; 
-}
-
 static int
 version_info(char *page)
 {
-	s64 status;
 	pal_version_u_t min_ver, cur_ver;
 	char *p = page;
 
-#ifdef IA64_PAL_VERSION_BUG
-	/* The virtual mode call is buggy. But the physical mode call seems
-	 * to be ok. Until they fix virtual mode, we do physical.
-	 */
-	status = ia64_pal_version_phys(&min_ver, &cur_ver);
-#else
-	/* The system crashes if you enable this code with the wrong PAL 
-	 * code
+	/* The PAL_VERSION call is advertised as being able to support
+	 * both physical and virtual mode calls. This seems to be a documentation
+	 * bug rather than firmware bug. In fact, it does only support physical mode.
+	 * So now the code reflects this fact and the pal_version() has been updated
+	 * accordingly.
 	 */
-	status = ia64_pal_version(&min_ver, &cur_ver);
-#endif
-	if (status != 0) return 0;
+	if (ia64_pal_version(&min_ver, &cur_ver) != 0) return 0;
 
 	p += sprintf(p, "PAL_vendor : 0x%02x (min=0x%02x)\n" \
 			"PAL_A      : %x.%x.%x (min=%x.%x.%x)\n" \
 			"PAL_B      : %x.%x.%x (min=%x.%x.%x)\n",
-	     		cur_ver.pal_version_s.pv_pal_vendor,
-	     		min_ver.pal_version_s.pv_pal_vendor,
+			cur_ver.pal_version_s.pv_pal_vendor,
+			min_ver.pal_version_s.pv_pal_vendor,
 
-	     		cur_ver.pal_version_s.pv_pal_a_model>>4,
-	     		cur_ver.pal_version_s.pv_pal_a_model&0xf,
-	     		cur_ver.pal_version_s.pv_pal_a_rev,
-	     		min_ver.pal_version_s.pv_pal_a_model>>4,
-	     		min_ver.pal_version_s.pv_pal_a_model&0xf,
-	     		min_ver.pal_version_s.pv_pal_a_rev,
-
-	     		cur_ver.pal_version_s.pv_pal_b_model>>4,
-	     		cur_ver.pal_version_s.pv_pal_b_model&0xf,
-	     		cur_ver.pal_version_s.pv_pal_b_rev,
-	     		min_ver.pal_version_s.pv_pal_b_model>>4,
-	     		min_ver.pal_version_s.pv_pal_b_model&0xf,
-	     		min_ver.pal_version_s.pv_pal_b_rev);
+			cur_ver.pal_version_s.pv_pal_a_model>>4,
+			cur_ver.pal_version_s.pv_pal_a_model&0xf,
+			cur_ver.pal_version_s.pv_pal_a_rev,
+			min_ver.pal_version_s.pv_pal_a_model>>4,
+			min_ver.pal_version_s.pv_pal_a_model&0xf,
+			min_ver.pal_version_s.pv_pal_a_rev,
+
+			cur_ver.pal_version_s.pv_pal_b_model>>4,
+			cur_ver.pal_version_s.pv_pal_b_model&0xf,
+			cur_ver.pal_version_s.pv_pal_b_rev,
+			min_ver.pal_version_s.pv_pal_b_model>>4,
+			min_ver.pal_version_s.pv_pal_b_model&0xf,
+			min_ver.pal_version_s.pv_pal_b_rev);
 
 	return p - page;
 }
@@ -650,7 +619,7 @@
 			"Counter width                 : %d bits\n" \
 			"Cycle event number            : %d\n" \
 			"Retired event number          : %d\n" \
-			"Implemented PMC               : ", 
+			"Implemented PMC               : ",
 			pm_info.pal_perf_mon_info_s.generic,
 			pm_info.pal_perf_mon_info_s.width,
 			pm_info.pal_perf_mon_info_s.cycles,
@@ -659,15 +628,15 @@
 	p = bitregister_process(p, pm_buffer, 256);
 
 	p += sprintf(p, "\nImplemented PMD               : ");
-	
+
 	p = bitregister_process(p, pm_buffer+4, 256);
 
 	p += sprintf(p, "\nCycles count capable          : ");
-	
+
 	p = bitregister_process(p, pm_buffer+8, 256);
 
 	p += sprintf(p, "\nRetired bundles count capable : ");
-	
+
 	p = bitregister_process(p, pm_buffer+12, 256);
 
 	p += sprintf(p, "\n");
@@ -683,7 +652,7 @@
 	u64 base;
 
 	if (ia64_pal_freq_base(&base) == -1)
-		p += sprintf(p, "Output clock            : not implemented\n"); 
+		p += sprintf(p, "Output clock            : not implemented\n");
 	else
 		p += sprintf(p, "Output clock            : %ld ticks/s\n", base);
 
@@ -762,7 +731,7 @@
 
 		if (ifa_reg->valid == 0) continue;
 
-		gr_reg   = (struct gr_reg *)tr_buffer;	
+		gr_reg   = (struct gr_reg *)tr_buffer;
 		itir_reg = (struct itir_reg *)&tr_buffer[1];
 		rid_reg  = (struct rid_reg *)&tr_buffer[3];
 
@@ -788,7 +757,7 @@
 				"\trid  : %x\n" \
 				"\tp    : %d\n" \
 				"\tma   : %d\n" \
-				"\td    : %d\n", 
+				"\td    : %d\n",
 				gr_reg->pl,
 				gr_reg->ar,
 				rid_reg->rid,
@@ -807,7 +776,7 @@
  */
 static palinfo_entry_t palinfo_entries[]={
 	{ "version_info",	version_info, },
-	{ "vm_info", 		vm_info, },
+	{ "vm_info",		vm_info, },
 	{ "cache_info",		cache_info, },
 	{ "power_info",		power_info, },
 	{ "register_info",	register_info, },
@@ -821,14 +790,14 @@
 #define NR_PALINFO_ENTRIES	(sizeof(palinfo_entries)/sizeof(palinfo_entry_t))
 
 /*
- * this array is used to keep track of the proc entries we create. This is 
+ * this array is used to keep track of the proc entries we create. This is
  * required in the module mode when we need to remove all entries. The procfs code
  * does not do recursion of deletion
  *
  * Notes:
  *	- first +1 accounts for the cpuN entry
  *	- second +1 account for toplevel palinfo
- * 
+ *
  */
 #define NR_PALINFO_PROC_ENTRIES	(NR_CPUS*(NR_PALINFO_ENTRIES+1)+1)
 
@@ -855,7 +824,7 @@
 #ifdef CONFIG_SMP
 
 /*
- * used to hold information about final function to call 
+ * used to hold information about final function to call
  */
 typedef struct {
 	palinfo_func_t	func;	/* pointer to function to call */
@@ -888,7 +857,7 @@
  *	0 : error or nothing to output
  *	otherwise how many bytes in the "page" buffer were written
  */
-static 
+static
 int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page)
 {
 	palinfo_smp_data_t ptr;
@@ -908,7 +877,7 @@
 	return ptr.ret;
 }
 #else /* ! CONFIG_SMP */
-static 
+static
 int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page)
 {
 	printk(__FUNCTION__" should not be called with non SMP kernel\n");
@@ -930,25 +899,25 @@
 	 * in SMP mode, we may need to call another CPU to get correct
 	 * information. PAL, by definition, is processor specific
 	 */
-	if (f->req_cpu == smp_processor_id()) 
+	if (f->req_cpu == smp_processor_id())
 		len = (*palinfo_entries[f->func_id].proc_read)(page);
 	else
 		len = palinfo_handle_smp(f, page);
 
-        if (len <= off+count) *eof = 1;
+	if (len <= off+count) *eof = 1;
 
-        *start = page + off;
-        len   -= off;
+	*start = page + off;
+	len   -= off;
 
-        if (len>count) len = count;
-        if (len<0) len = 0;
+	if (len>count) len = count;
+	if (len<0) len = 0;
 
 	MOD_DEC_USE_COUNT;
 
-        return len;
+	return len;
 }
 
-static int __init 
+static int __init
 palinfo_init(void)
 {
 #	define CPUSTR	"cpu%d"
@@ -979,7 +948,7 @@
 
 		for (j=0; j < NR_PALINFO_ENTRIES; j++) {
 			f.func_id = j;
-			*pdir++ = create_proc_read_entry (palinfo_entries[j].name, 0, cpu_dir, 
+			*pdir++ = create_proc_read_entry (palinfo_entries[j].name, 0, cpu_dir,
 						palinfo_read_entry, (void *)f.value);
 		}
 		*pdir++ = cpu_dir;
@@ -994,9 +963,10 @@
 {
 	int i = 0;
 
-	/* remove all nodes: depth first pass */
+	/* remove all nodes: depth first pass. Could optimize this  */
 	for (i=0; i< NR_PALINFO_PROC_ENTRIES ; i++) {
-		remove_proc_entry (palinfo_proc_entries[i]->name, NULL);
+		if (palinfo_proc_entries[i])
+			remove_proc_entry (palinfo_proc_entries[i]->name, NULL);
 	}
 }
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/perfmon.c linux/arch/ia64/kernel/perfmon.c
--- v2.4.3/linux/arch/ia64/kernel/perfmon.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/perfmon.c	Thu Apr  5 12:51:47 2001
@@ -7,57 +7,40 @@
  * Modifications by Stephane Eranian, Hewlett-Packard Co.
  * Copyright (C) 1999 Ganesh Venkitachalam <venkitac@us.ibm.com>
  * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com>
+ * Copyright (C) 2000-2001 Stephane Eranian <eranian@hpl.hp.com>
  */
 
 #include <linux/config.h>
-
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/smp_lock.h>
 #include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/wrapper.h>
+#include <linux/mm.h>
 
+#include <asm/bitops.h>
+#include <asm/efi.h>
 #include <asm/errno.h>
 #include <asm/hw_irq.h>
+#include <asm/page.h>
+#include <asm/pal.h>
+#include <asm/perfmon.h>
+#include <asm/pgtable.h>
 #include <asm/processor.h>
+#include <asm/signal.h>
+#include <asm/system.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/pal.h>
-
-/* Long blurb on how this works: 
- * We set dcr.pp, psr.pp, and the appropriate pmc control values with
- * this.  Notice that we go about modifying _each_ task's pt_regs to
- * set cr_ipsr.pp.  This will start counting when "current" does an
- * _rfi_. Also, since each task's cr_ipsr.pp, and cr_ipsr is inherited
- * across forks, we do _not_ need additional code on context
- * switches. On stopping of the counters we dont need to go about
- * changing every task's cr_ipsr back to where it wuz, because we can
- * just set pmc[0]=1. But we do it anyways becuase we will probably
- * add thread specific accounting later.
- *
- * The obvious problem with this is that on SMP systems, it is a bit
- * of work (when someone wants to do it:-)) - it would be easier if we
- * just added code to the context-switch path, but if we wanted to support
- * per-thread accounting, the context-switch path might be long unless 
- * we introduce a flag in the task_struct. Right now, the following code 
- * will NOT work correctly on MP (for more than one reason:-)).
- *
- * The short answer is that to make this work on SMP,  we would need 
- * to lock the run queue to ensure no context switches, send 
- * an IPI to each processor, and in that IPI handler, set processor regs,
- * and just modify the psr bit of only the _current_ thread, since we have 
- * modified the psr bit correctly in the kernel stack for every process 
- * which is not running. Also, we need pmd arrays per-processor, and 
- * the READ_PMD command will need to get values off of other processors. 
- * IPIs are the answer, irrespective of what the question is. Might 
- * crash on SMP systems without the lock_kernel().
- */
+#include <asm/delay.h> /* for ia64_get_itc() */
 
 #ifdef CONFIG_PERFMON
 
-#define MAX_PERF_COUNTER	4	/* true for Itanium, at least */
+#define PFM_VERSION		"0.2"
+#define PFM_SMPL_HDR_VERSION	1
+
 #define PMU_FIRST_COUNTER	4	/* first generic counter */
 
 #define PFM_WRITE_PMCS		0xa0
@@ -67,293 +50,1019 @@
 #define PFM_START		0xa4
 #define PFM_ENABLE		0xa5	/* unfreeze only */
 #define PFM_DISABLE		0xa6	/* freeze only */
-/* 
+#define PFM_RESTART		0xcf
+#define PFM_CREATE_CONTEXT	0xa7
+/*
  * Those 2 are just meant for debugging. I considered using sysctl() for
  * that but it is a little bit too pervasive. This solution is at least
  * self-contained.
  */
-#define PFM_DEBUG_ON		0xe0	
+#define PFM_DEBUG_ON		0xe0
 #define PFM_DEBUG_OFF		0xe1
 
+
+/*
+ * perfmon API flags
+ */
+#define PFM_FL_INHERIT_NONE	 0x00	/* never inherit a context across fork (default) */
+#define PFM_FL_INHERIT_ONCE	 0x01	/* clone pfm_context only once across fork() */
+#define PFM_FL_INHERIT_ALL	 0x02	/* always clone pfm_context across fork() */
+#define PFM_FL_SMPL_OVFL_NOBLOCK 0x04	/* do not block on sampling buffer overflow */
+#define PFM_FL_SYSTEMWIDE	 0x08	/* create a systemwide context */
+
+/*
+ * PMC API flags
+ */
+#define PFM_REGFL_OVFL_NOTIFY	1		/* send notification on overflow */
+
+/*
+ * Private flags and masks
+ */
+#define PFM_FL_INHERIT_MASK	(PFM_FL_INHERIT_NONE|PFM_FL_INHERIT_ONCE|PFM_FL_INHERIT_ALL)
+
 #ifdef CONFIG_SMP
 #define cpu_is_online(i) (cpu_online_map & (1UL << i))
 #else
 #define cpu_is_online(i)	1
 #endif
 
-#define PMC_IS_IMPL(i)		(pmu_conf.impl_regs[i>>6] & (1<< (i&~(64-1))))
-#define PMD_IS_IMPL(i)  	(pmu_conf.impl_regs[4+(i>>6)] & (1<< (i&~(64-1))))
+#define PMC_IS_IMPL(i)		(i < pmu_conf.num_pmcs && pmu_conf.impl_regs[i>>6] & (1<< (i&~(64-1))))
+#define PMD_IS_IMPL(i)	(i < pmu_conf.num_pmds &&  pmu_conf.impl_regs[4+(i>>6)] & (1<< (i&~(64-1))))
 #define PMD_IS_COUNTER(i)	(i>=PMU_FIRST_COUNTER && i < (PMU_FIRST_COUNTER+pmu_conf.max_counters))
 #define PMC_IS_COUNTER(i)	(i>=PMU_FIRST_COUNTER && i < (PMU_FIRST_COUNTER+pmu_conf.max_counters))
 
+/* This is the Itanium-specific PMC layout for counter config */
+typedef struct {
+	unsigned long pmc_plm:4;	/* privilege level mask */
+	unsigned long pmc_ev:1;		/* external visibility */
+	unsigned long pmc_oi:1;		/* overflow interrupt */
+	unsigned long pmc_pm:1;		/* privileged monitor */
+	unsigned long pmc_ig1:1;	/* reserved */
+	unsigned long pmc_es:7;		/* event select */
+	unsigned long pmc_ig2:1;	/* reserved */
+	unsigned long pmc_umask:4;	/* unit mask */
+	unsigned long pmc_thres:3;	/* threshold */
+	unsigned long pmc_ig3:1;	/* reserved (missing from table on p6-17) */
+	unsigned long pmc_ism:2;	/* instruction set mask */
+	unsigned long pmc_ig4:38;	/* reserved */
+} pmc_counter_reg_t;
+
+/* test for EAR/BTB configuration */
+#define PMU_DEAR_EVENT	0x67
+#define PMU_IEAR_EVENT	0x23
+#define PMU_BTB_EVENT	0x11
+
+#define PMC_IS_DEAR(a)		(((pmc_counter_reg_t *)(a))->pmc_es == PMU_DEAR_EVENT)
+#define PMC_IS_IEAR(a)		(((pmc_counter_reg_t *)(a))->pmc_es == PMU_IEAR_EVENT)
+#define PMC_IS_BTB(a)		(((pmc_counter_reg_t *)(a))->pmc_es == PMU_BTB_EVENT)
+
 /*
- * this structure needs to be enhanced
+ * This header is at the beginning of the sampling buffer returned to the user.
+ * It is exported as Read-Only at this point. It is directly followed with the
+ * first record.
  */
 typedef struct {
-	unsigned long	pfr_reg_num;	/* which register */
-	unsigned long	pfr_reg_value;	/* configuration (PMC) or initial value (PMD) */
-	unsigned long	pfr_reg_reset;	/* reset value on overflow (PMD) */
-	void		*pfr_smpl_buf;	/* pointer to user buffer for EAR/BTB */
-	unsigned long	pfr_smpl_size;	/* size of user buffer for EAR/BTB */
-	pid_t		pfr_notify_pid;	/* process to notify */
-	int		pfr_notify_sig;	/* signal for notification, 0=no notification */
-} perfmon_req_t;
+	int		hdr_version;		/* could be used to differentiate formats */
+	int		hdr_reserved;
+	unsigned long	hdr_entry_size;		/* size of one entry in bytes */
+	unsigned long	hdr_count;		/* how many valid entries */
+	unsigned long	hdr_pmds;		/* which pmds are recorded */
+} perfmon_smpl_hdr_t;
 
-#if 0
+/*
+ * Header entry in the buffer as a header as follows.
+ * The header is directly followed with the PMDS to saved in increasing index order:
+ * PMD4, PMD5, .... How many PMDs are present is determined by the tool which must
+ * keep track of it when generating the final trace file.
+ */
 typedef struct {
-	unsigned long pmu_reg_data;	/* generic PMD register */
-	unsigned long pmu_reg_num;	/* which register number */
-} perfmon_reg_t; 
-#endif
+	int		pid;		/* identification of process */
+	int		cpu;		/* which cpu was used */
+	unsigned long	rate;		/* initial value of this counter */
+	unsigned long	stamp;		/* timestamp */
+	unsigned long	ip;		/* where did the overflow interrupt happened */
+	unsigned long	regs;		/* which registers overflowed (up to 64)*/
+} perfmon_smpl_entry_t;
 
 /*
- * This structure is initialize at boot time and contains
+ * There is one such data structure per perfmon context. It is used to describe the
+ * sampling buffer. It is to be shared among siblings whereas the pfm_context isn't.
+ * Therefore we maintain a refcnt which is incremented on fork().
+ * This buffer is private to the kernel only the actual sampling buffer including its
+ * header are exposed to the user. This construct allows us to export the buffer read-write,
+ * if needed, without worrying about security problems.
+ */
+typedef struct {
+	atomic_t		psb_refcnt;	/* how many users for the buffer */
+	int			reserved;
+	void			*psb_addr;	/* points to location of first entry */
+	unsigned long		psb_entries;	/* maximum number of entries */
+	unsigned long		psb_size;	/* aligned size of buffer */
+	unsigned long		psb_index;	/* next free entry slot */
+	unsigned long		psb_entry_size;	/* size of each entry including entry header */
+	perfmon_smpl_hdr_t	*psb_hdr;	/* points to sampling buffer header */
+} pfm_smpl_buffer_desc_t;
+
+
+/*
+ * This structure is initialized at boot time and contains
  * a description of the PMU main characteristic as indicated
  * by PAL
  */
 typedef struct {
+	unsigned long pfm_is_disabled;	/* indicates if perfmon is working properly */
 	unsigned long perf_ovfl_val;	/* overflow value for generic counters   */
 	unsigned long max_counters;	/* upper limit on counter pair (PMC/PMD) */
+	unsigned long num_pmcs ;	/* highest PMC implemented (may have holes) */
+	unsigned long num_pmds;		/* highest PMD implemented (may have holes) */
 	unsigned long impl_regs[16];	/* buffer used to hold implememted PMC/PMD mask */
 } pmu_config_t;
 
+#define PERFMON_IS_DISABLED() pmu_conf.pfm_is_disabled
+
+typedef struct {
+	__u64		val;		/* virtual 64bit counter value */
+	__u64		ival;		/* initial value from user */
+	__u64		smpl_rval;	/* reset value on sampling overflow */
+	__u64		ovfl_rval;	/* reset value on overflow */
+	int		flags;		/* notify/do not notify */
+} pfm_counter_t;
+#define PMD_OVFL_NOTIFY(ctx, i)	((ctx)->ctx_pmds[i].flags &  PFM_REGFL_OVFL_NOTIFY)
+
+/*
+ * perfmon context. One per process, is cloned on fork() depending on inheritance flags
+ */
+typedef struct {
+	unsigned int inherit:2;	/* inherit mode */
+	unsigned int noblock:1;	/* block/don't block on overflow with notification */
+	unsigned int system:1;	/* do system wide monitoring */
+	unsigned int frozen:1;	/* pmu must be kept frozen on ctxsw in */
+	unsigned int reserved:27;
+} pfm_context_flags_t;
+
+typedef struct pfm_context {
+
+	pfm_smpl_buffer_desc_t	*ctx_smpl_buf;		/* sampling buffer descriptor, if any */
+	unsigned long		ctx_dear_counter;	/* which PMD holds D-EAR */
+	unsigned long		ctx_iear_counter;	/* which PMD holds I-EAR */
+	unsigned long		ctx_btb_counter;	/* which PMD holds BTB */
+
+	pid_t			ctx_notify_pid;	/* who to notify on overflow */
+	int			ctx_notify_sig;	/* XXX: SIGPROF or other */
+	pfm_context_flags_t	ctx_flags;	/* block/noblock */
+	pid_t			ctx_creator;	/* pid of creator (debug) */
+	unsigned long		ctx_ovfl_regs;	/* which registers just overflowed (notification) */
+	unsigned long		ctx_smpl_regs;	/* which registers to record on overflow */
+
+	struct semaphore	ctx_restart_sem; /* use for blocking notification mode */
+
+	pfm_counter_t		ctx_pmds[IA64_NUM_PMD_COUNTERS]; /* XXX: size should be dynamic */
+} pfm_context_t;
+
+#define ctx_fl_inherit	ctx_flags.inherit
+#define ctx_fl_noblock	ctx_flags.noblock
+#define ctx_fl_system	ctx_flags.system
+#define ctx_fl_frozen	ctx_flags.frozen
+
+#define CTX_IS_DEAR(c,n)	((c)->ctx_dear_counter == (n))
+#define CTX_IS_IEAR(c,n)	((c)->ctx_iear_counter == (n))
+#define CTX_IS_BTB(c,n)		((c)->ctx_btb_counter == (n))
+#define CTX_OVFL_NOBLOCK(c)	((c)->ctx_fl_noblock == 1)
+#define CTX_INHERIT_MODE(c)	((c)->ctx_fl_inherit)
+#define CTX_HAS_SMPL(c)		((c)->ctx_smpl_buf != NULL)
+
 static pmu_config_t pmu_conf;
 
 /* for debug only */
-static unsigned long pfm_debug=1;	/* 0= nodebug, >0= debug output on */
-#define DBprintk(a)	{\
-	if (pfm_debug >0) { printk a; } \
+static unsigned long pfm_debug=0;	/* 0= nodebug, >0= debug output on */
+#define DBprintk(a) \
+	do { \
+		if (pfm_debug >0) { printk(__FUNCTION__" "); printk a; } \
+	} while (0);
+
+static void perfmon_softint(unsigned long ignored);
+static void ia64_reset_pmu(void);
+
+DECLARE_TASKLET(pfm_tasklet, perfmon_softint, 0);
+
+/*
+ * structure used to pass information between the interrupt handler
+ * and the tasklet.
+ */
+typedef struct {
+	pid_t		to_pid;		/* which process to notify */
+	pid_t		from_pid;	/* which process is source of overflow */
+	int		sig;		/* with which signal */
+	unsigned long	bitvect;	/* which counters have overflowed */
+} notification_info_t;
+
+#define notification_is_invalid(i)	(i->to_pid < 2)
+
+/* will need to be cache line padded */
+static notification_info_t notify_info[NR_CPUS];
+
+/*
+ * We force cache line alignment to avoid false sharing
+ * given that we have one entry per CPU.
+ */
+static struct {
+	struct task_struct *owner;
+} ____cacheline_aligned pmu_owners[NR_CPUS];
+/* helper macros */
+#define SET_PMU_OWNER(t)	do { pmu_owners[smp_processor_id()].owner = (t); } while(0);
+#define PMU_OWNER()		pmu_owners[smp_processor_id()].owner
+
+/* for debug only */
+static struct proc_dir_entry *perfmon_dir;
+
+/*
+ * finds the number of PM(C|D) registers given
+ * the bitvector returned by PAL
+ */
+static unsigned long __init
+find_num_pm_regs(long *buffer)
+{
+	int i=3; /* 4 words/per bitvector */
+
+	/* start from the most significant word */
+	while (i>=0 && buffer[i] == 0 ) i--;
+	if (i< 0) {
+		printk(KERN_ERR "perfmon: No bit set in pm_buffer\n");
+		return 0;
+	}
+	return 1+ ia64_fls(buffer[i]) + 64 * i;
 }
 
+
 /*
- * could optimize to avoid cache line conflicts in SMP
+ * Generates a unique (per CPU) timestamp
  */
-static struct task_struct *pmu_owners[NR_CPUS];
+static inline unsigned long
+perfmon_get_stamp(void)
+{
+	/*
+	 * XXX: maybe find something more efficient
+	 */
+	return ia64_get_itc();
+}
+
+/* Given PGD from the address space's page table, return the kernel
+ * virtual mapping of the physical memory mapped at ADR.
+ */
+static inline unsigned long
+uvirt_to_kva(pgd_t *pgd, unsigned long adr)
+{
+	unsigned long ret = 0UL;
+	pmd_t *pmd;
+	pte_t *ptep, pte;
+
+	if (!pgd_none(*pgd)) {
+		pmd = pmd_offset(pgd, adr);
+		if (!pmd_none(*pmd)) {
+			ptep = pte_offset(pmd, adr);
+			pte = *ptep;
+			if (pte_present(pte)) {
+				ret = (unsigned long) page_address(pte_page(pte));
+				ret |= (adr & (PAGE_SIZE - 1));
+			}
+		}
+	}
+	DBprintk(("uv2kva(%lx-->%lx)\n", adr, ret));
+	return ret;
+}
+
+
+/* Here we want the physical address of the memory.
+ * This is used when initializing the contents of the
+ * area and marking the pages as reserved.
+ */
+static inline unsigned long
+kvirt_to_pa(unsigned long adr)
+{
+	__u64 pa;
+	__asm__ __volatile__ ("tpa %0 = %1" : "=r"(pa) : "r"(adr) : "memory");
+	DBprintk(("kv2pa(%lx-->%lx)\n", adr, pa));
+	return pa;
+}
+
+static void *
+rvmalloc(unsigned long size)
+{
+	void *mem;
+	unsigned long adr, page;
+
+	/* XXX: may have to revisit this part because
+	 * vmalloc() does not necessarily return a page-aligned buffer.
+	 * This maybe a security problem when mapped at user level
+	 */
+	mem=vmalloc(size);
+	if (mem) {
+		memset(mem, 0, size); /* Clear the ram out, no junk to the user */
+		adr=(unsigned long) mem;
+		while (size > 0) {
+			page = kvirt_to_pa(adr);
+			mem_map_reserve(virt_to_page(__va(page)));
+			adr+=PAGE_SIZE;
+			size-=PAGE_SIZE;
+		}
+	}
+	return mem;
+}
+
+static void
+rvfree(void *mem, unsigned long size)
+{
+	unsigned long adr, page;
+
+	if (mem) {
+		adr=(unsigned long) mem;
+		while (size > 0) {
+			page = kvirt_to_pa(adr);
+			mem_map_unreserve(virt_to_page(__va(page)));
+			adr+=PAGE_SIZE;
+			size-=PAGE_SIZE;
+		}
+		vfree(mem);
+	}
+}
+
+static pfm_context_t *
+pfm_context_alloc(void)
+{
+	pfm_context_t *pfc;
+
+	/* allocate context descriptor */
+	pfc = vmalloc(sizeof(*pfc));
+	if (pfc) memset(pfc, 0, sizeof(*pfc));
+
+	return pfc;
+}
+
+static void
+pfm_context_free(pfm_context_t *pfc)
+{
+	if (pfc) vfree(pfc);
+}
 
 static int
-do_perfmonctl (struct task_struct *task, int cmd, int flags, perfmon_req_t *req, int count, struct pt_regs *regs)
+pfm_remap_buffer(unsigned long buf, unsigned long addr, unsigned long size)
 {
-        perfmon_req_t tmp;
-        int i;
+	unsigned long page;
 
-        switch (cmd) {
-		case PFM_WRITE_PMCS:          
-			/* we don't quite support this right now */
-			if (task != current) return -EINVAL;
+	while (size > 0) {
+		page = kvirt_to_pa(buf);
 
-			if (!access_ok(VERIFY_READ, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT;
+		if (remap_page_range(addr, page, PAGE_SIZE, PAGE_SHARED)) return -ENOMEM;
+
+		addr  += PAGE_SIZE;
+		buf   += PAGE_SIZE;
+		size  -= PAGE_SIZE;
+	}
+	return 0;
+}
+
+/*
+ * counts the number of PMDS to save per entry.
+ * This code is generic enough to accomodate more than 64 PMDS when they become available
+ */
+static unsigned long
+pfm_smpl_entry_size(unsigned long *which, unsigned long size)
+{
+	unsigned long res = 0;
+	int i;
+
+	for (i=0; i < size; i++, which++) res += hweight64(*which);
+
+	DBprintk((" res=%ld\n", res));
 
-			for (i = 0; i < count; i++, req++) {
-				copy_from_user(&tmp, req, sizeof(tmp));
+	return res;
+}
+
+/*
+ * Allocates the sampling buffer and remaps it into caller's address space
+ */
+static int
+pfm_smpl_buffer_alloc(pfm_context_t *ctx, unsigned long which_pmds, unsigned long entries, void **user_addr)
+{
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
+	unsigned long addr, size, regcount;
+	void *smpl_buf;
+	pfm_smpl_buffer_desc_t *psb;
+
+	regcount = pfm_smpl_entry_size(&which_pmds, 1);
+
+	/* note that regcount might be 0, in this case only the header for each
+	 * entry will be recorded.
+	 */
+
+	/*
+	 * 1 buffer hdr and for each entry a header + regcount PMDs to save
+	 */
+	size = PAGE_ALIGN(  sizeof(perfmon_smpl_hdr_t)
+			  + entries * (sizeof(perfmon_smpl_entry_t) + regcount*sizeof(u64)));
+	/*
+	 * check requested size to avoid Denial-of-service attacks
+	 * XXX: may have to refine this test
+	 */
+	if (size > current->rlim[RLIMIT_MEMLOCK].rlim_cur) return -EAGAIN;
+
+	/* find some free area in address space */
+	addr = get_unmapped_area(0, size);
+	if (!addr) goto no_addr;
+
+	DBprintk((" entries=%ld aligned size=%ld, unmapped @0x%lx\n", entries, size, addr));
+
+	/* allocate vma */
+	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+	if (!vma) goto no_vma;
+
+	/* XXX: see rvmalloc() for page alignment problem */
+	smpl_buf = rvmalloc(size);
+	if (smpl_buf == NULL) goto no_buffer;
+
+	DBprintk((" smpl_buf @%p\n", smpl_buf));
+
+	if (pfm_remap_buffer((unsigned long)smpl_buf, addr, size)) goto cant_remap;
+
+	/* allocate sampling buffer descriptor now */
+	psb = vmalloc(sizeof(*psb));
+	if (psb == NULL) goto no_buffer_desc;
+
+	/* start with something clean */
+	memset(smpl_buf, 0x0, size);
+
+	psb->psb_hdr	 = smpl_buf;
+	psb->psb_addr    = (char *)smpl_buf+sizeof(perfmon_smpl_hdr_t); /* first entry */
+	psb->psb_size    = size; /* aligned size */
+	psb->psb_index   = 0;
+	psb->psb_entries = entries;
+
+	atomic_set(&psb->psb_refcnt, 1);
+
+	psb->psb_entry_size = sizeof(perfmon_smpl_entry_t) + regcount*sizeof(u64);
+
+	DBprintk((" psb @%p entry_size=%ld hdr=%p addr=%p\n", (void *)psb,psb->psb_entry_size, (void *)psb->psb_hdr, (void *)psb->psb_addr));
+
+	/* initialize some of the fields of header */
+	psb->psb_hdr->hdr_version    = PFM_SMPL_HDR_VERSION;
+	psb->psb_hdr->hdr_entry_size = sizeof(perfmon_smpl_entry_t)+regcount*sizeof(u64);
+	psb->psb_hdr->hdr_pmds	     = which_pmds;
+
+	/* store which PMDS to record */
+	ctx->ctx_smpl_regs = which_pmds;
+
+	/* link to perfmon context */
+	ctx->ctx_smpl_buf  = psb;
+
+	/*
+	 * initialize the vma for the sampling buffer
+	 */
+	vma->vm_mm	  = mm;
+	vma->vm_start	  = addr;
+	vma->vm_end	  = addr + size;
+	vma->vm_flags	  = VM_READ|VM_MAYREAD;
+	vma->vm_page_prot = PAGE_READONLY; /* XXX may need to change */
+	vma->vm_ops	  = NULL;
+	vma->vm_pgoff	  = 0;
+	vma->vm_file	  = NULL;
+	vma->vm_raend	  = 0;
+
+	vma->vm_private_data = ctx;	/* link to pfm_context(not yet used) */
+
+	/*
+	 * now insert the vma in the vm list for the process
+	 */
+	insert_vm_struct(mm, vma);
+
+	mm->total_vm  += size >> PAGE_SHIFT;
+
+	/*
+	 * that's the address returned to the user
+	 */
+	*user_addr = (void *)addr;
+
+	return 0;
+
+	/* outlined error handling */
+no_addr:
+	DBprintk(("Cannot find unmapped area for size %ld\n", size));
+	return -ENOMEM;
+no_vma:
+	DBprintk(("Cannot allocate vma\n"));
+	return -ENOMEM;
+cant_remap:
+	DBprintk(("Can't remap buffer\n"));
+	rvfree(smpl_buf, size);
+no_buffer:
+	DBprintk(("Can't allocate sampling buffer\n"));
+	kmem_cache_free(vm_area_cachep, vma);
+	return -ENOMEM;
+no_buffer_desc:
+	DBprintk(("Can't allocate sampling buffer descriptor\n"));
+	kmem_cache_free(vm_area_cachep, vma);
+	rvfree(smpl_buf, size);
+	return -ENOMEM;
+}
+
+static int
+pfx_is_sane(pfreq_context_t *pfx)
+{
+	/* valid signal */
+	if (pfx->notify_sig < 1 || pfx->notify_sig >= _NSIG) return 0;
+
+	/* cannot send to process 1, 0 means do not notify */
+	if (pfx->notify_pid < 0 || pfx->notify_pid == 1) return 0;
+
+	/* asked for sampling, but nothing to record ! */
+	if (pfx->smpl_entries > 0 && pfm_smpl_entry_size(&pfx->smpl_regs, 1) == 0) return 0;
+
+	/* probably more to add here */
+
+
+	return 1;
+}
+
+static int
+pfm_context_create(struct task_struct *task, int flags, perfmon_req_t *req)
+{
+	pfm_context_t *ctx;
+	perfmon_req_t tmp;
+	void *uaddr = NULL;
+	int ret = -EFAULT;
+	int ctx_flags;
+
+	/* to go away */
+	if (flags) {
+		printk("perfmon: use context flags instead of perfmon() flags. Obsoleted API\n");
+	}
 
-				/* XXX needs to check validity of the data maybe */
+	if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
 
-				if (!PMC_IS_IMPL(tmp.pfr_reg_num)) {
-					DBprintk((__FUNCTION__ " invalid pmc[%ld]\n", tmp.pfr_reg_num));
-					return -EINVAL;
-				}
-
-				/* XXX: for counters, need to some checks */
-				if (PMC_IS_COUNTER(tmp.pfr_reg_num)) {
-					current->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].sig = tmp.pfr_notify_sig;
-					current->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].pid = tmp.pfr_notify_pid;
-
-					DBprintk((__FUNCTION__" setting PMC[%ld] send sig %d to %d\n",tmp.pfr_reg_num, tmp.pfr_notify_sig, tmp.pfr_notify_pid));
-				}
-				ia64_set_pmc(tmp.pfr_reg_num, tmp.pfr_reg_value);
+	ctx_flags = tmp.pfr_ctx.flags;
 
-				DBprintk((__FUNCTION__" setting PMC[%ld]=0x%lx\n", tmp.pfr_reg_num, tmp.pfr_reg_value));
+	/* not yet supported */
+	if (ctx_flags & PFM_FL_SYSTEMWIDE) return -EINVAL;
+
+	if (!pfx_is_sane(&tmp.pfr_ctx)) return -EINVAL;
+
+	ctx = pfm_context_alloc();
+	if (!ctx) return -ENOMEM;
+
+	/* record who the creator is (for debug) */
+	ctx->ctx_creator = task->pid;
+
+	ctx->ctx_notify_pid = tmp.pfr_ctx.notify_pid;
+	ctx->ctx_notify_sig = SIGPROF;	/* siginfo imposes a fixed signal */
+
+	if (tmp.pfr_ctx.smpl_entries) {
+		DBprintk((" sampling entries=%ld\n",tmp.pfr_ctx.smpl_entries));
+		if ((ret=pfm_smpl_buffer_alloc(ctx, tmp.pfr_ctx.smpl_regs, tmp.pfr_ctx.smpl_entries, &uaddr)) ) goto buffer_error;
+		tmp.pfr_ctx.smpl_vaddr = uaddr;
+	}
+	/* initialization of context's flags */
+	ctx->ctx_fl_inherit = ctx_flags & PFM_FL_INHERIT_MASK;
+	ctx->ctx_fl_noblock = (ctx_flags & PFM_FL_SMPL_OVFL_NOBLOCK) ? 1 : 0;
+	ctx->ctx_fl_system  = (ctx_flags & PFM_FL_SYSTEMWIDE) ? 1: 0;
+	ctx->ctx_fl_frozen  = 0;
+
+	sema_init(&ctx->ctx_restart_sem, 0); /* init this semaphore to locked */
+
+	if (copy_to_user(req, &tmp, sizeof(tmp))) goto buffer_error;
+
+	DBprintk((" context=%p, pid=%d notify_sig %d notify_pid=%d\n",(void *)ctx, task->pid, ctx->ctx_notify_sig, ctx->ctx_notify_pid));
+	DBprintk((" context=%p, pid=%d flags=0x%x inherit=%d noblock=%d system=%d\n",(void *)ctx, task->pid, ctx_flags, ctx->ctx_fl_inherit, ctx->ctx_fl_noblock, ctx->ctx_fl_system));
+
+	/* link with task */
+	task->thread.pfm_context = ctx;
+
+	return 0;
+
+buffer_error:
+	vfree(ctx);
+
+	return ret;
+}
+
+static void
+pfm_reset_regs(pfm_context_t *ctx)
+{
+	unsigned long mask = ctx->ctx_ovfl_regs;
+	int i, cnum;
+
+	DBprintk((" ovfl_regs=0x%lx\n", mask));
+	/*
+	 * now restore reset value on sampling overflowed counters
+	 */
+	for(i=0, cnum=PMU_FIRST_COUNTER; i < pmu_conf.max_counters; i++, cnum++, mask >>= 1) {
+		if (mask & 0x1) {
+			DBprintk((" reseting PMD[%d]=%lx\n", cnum, ctx->ctx_pmds[i].smpl_rval & pmu_conf.perf_ovfl_val));
+
+			/* upper part is ignored on rval */
+			ia64_set_pmd(cnum, ctx->ctx_pmds[i].smpl_rval);
+		}
+	}
+}
+
+static int
+pfm_write_pmcs(struct task_struct *ta, perfmon_req_t *req, int count)
+{
+	struct thread_struct *th = &ta->thread;
+	pfm_context_t *ctx = th->pfm_context;
+	perfmon_req_t tmp;
+	unsigned long cnum;
+	int i;
+
+	/* XXX: ctx locking may be required here */
+
+	for (i = 0; i < count; i++, req++) {
+
+		if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
+
+		cnum = tmp.pfr_reg.reg_num;
+
+		/* XXX needs to check validity of the data maybe */
+		if (!PMC_IS_IMPL(cnum)) {
+			DBprintk((" invalid pmc[%ld]\n", cnum));
+			return -EINVAL;
+		}
+
+		if (PMC_IS_COUNTER(cnum)) {
+
+			/*
+			 * we keep track of EARS/BTB to speed up sampling later
+			 */
+			if (PMC_IS_DEAR(&tmp.pfr_reg.reg_value)) {
+				ctx->ctx_dear_counter = cnum;
+			} else if (PMC_IS_IEAR(&tmp.pfr_reg.reg_value)) {
+				ctx->ctx_iear_counter = cnum;
+			} else if (PMC_IS_BTB(&tmp.pfr_reg.reg_value)) {
+				ctx->ctx_btb_counter = cnum;
 			}
+
+			if (tmp.pfr_reg.reg_flags & PFM_REGFL_OVFL_NOTIFY)
+				ctx->ctx_pmds[cnum - PMU_FIRST_COUNTER].flags |= PFM_REGFL_OVFL_NOTIFY;
+		}
+
+		ia64_set_pmc(cnum, tmp.pfr_reg.reg_value);
+			DBprintk((" setting PMC[%ld]=0x%lx flags=0x%x\n", cnum, tmp.pfr_reg.reg_value, ctx->ctx_pmds[cnum - PMU_FIRST_COUNTER].flags));
+
+	}
+	/*
+	 * we have to set this here event hough we haven't necessarily started monitoring
+	 * because we may be context switched out
+	 */
+	th->flags |= IA64_THREAD_PM_VALID;
+
+	return 0;
+}
+
+static int
+pfm_write_pmds(struct task_struct *ta, perfmon_req_t *req, int count)
+{
+	struct thread_struct *th = &ta->thread;
+	pfm_context_t *ctx = th->pfm_context;
+	perfmon_req_t tmp;
+	unsigned long cnum;
+	int i;
+
+	/* XXX: ctx locking may be required here */
+
+	for (i = 0; i < count; i++, req++) {
+		int k;
+
+		if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
+
+		cnum = tmp.pfr_reg.reg_num;
+
+		k = cnum - PMU_FIRST_COUNTER;
+
+		if (!PMD_IS_IMPL(cnum)) return -EINVAL;
+
+		/* update virtualized (64bits) counter */
+		if (PMD_IS_COUNTER(cnum)) {
+			ctx->ctx_pmds[k].ival = tmp.pfr_reg.reg_value;
+			ctx->ctx_pmds[k].val  = tmp.pfr_reg.reg_value & ~pmu_conf.perf_ovfl_val;
+			ctx->ctx_pmds[k].smpl_rval = tmp.pfr_reg.reg_smpl_reset;
+			ctx->ctx_pmds[k].ovfl_rval = tmp.pfr_reg.reg_ovfl_reset;
+		}
+
+		/* writes to unimplemented part is ignored, so this is safe */
+		ia64_set_pmd(cnum, tmp.pfr_reg.reg_value);
+
+		/* to go away */
+		ia64_srlz_d();
+		DBprintk((" setting PMD[%ld]:  pmd.val=0x%lx pmd.ovfl_rval=0x%lx pmd.smpl_rval=0x%lx pmd=%lx\n",
+					cnum,
+					ctx->ctx_pmds[k].val,
+					ctx->ctx_pmds[k].ovfl_rval,
+					ctx->ctx_pmds[k].smpl_rval,
+					ia64_get_pmd(cnum) & pmu_conf.perf_ovfl_val));
+	}
+	/*
+	 * we have to set this here event hough we haven't necessarily started monitoring
+	 * because we may be context switched out
+	 */
+	th->flags |= IA64_THREAD_PM_VALID;
+
+	return 0;
+}
+
+static int
+pfm_read_pmds(struct task_struct *ta, perfmon_req_t *req, int count)
+{
+	struct thread_struct *th = &ta->thread;
+	pfm_context_t *ctx = th->pfm_context;
+	unsigned long val=0;
+	perfmon_req_t tmp;
+	int i;
+
+	/*
+	 * XXX: MUST MAKE SURE WE DON"T HAVE ANY PENDING OVERFLOW BEFORE READING
+	 * This is required when the monitoring has been stoppped by user of kernel.
+	 * If ity is still going on, then that's fine because we a re not gauranteed
+	 * to return an accurate value in this case
+	 */
+
+	/* XXX: ctx locking may be required here */
+
+	for (i = 0; i < count; i++, req++) {
+		int k;
+
+		if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
+
+		if (!PMD_IS_IMPL(tmp.pfr_reg.reg_num)) return -EINVAL;
+
+		k = tmp.pfr_reg.reg_num - PMU_FIRST_COUNTER;
+
+		if (PMD_IS_COUNTER(tmp.pfr_reg.reg_num)) {
+			if (ta == current){
+				val = ia64_get_pmd(tmp.pfr_reg.reg_num);
+			} else {
+				val = th->pmd[k];
+			}
+			val &= pmu_conf.perf_ovfl_val;
 			/*
-			 * we have to set this here event hough we haven't necessarily started monitoring
-			 * because we may be context switched out
+			 * lower part of .val may not be zero, so we must be an addition because of
+			 * residual count (see update_counters).
 			 */
-			current->thread.flags |= IA64_THREAD_PM_VALID;
-                	break;
+			val += ctx->ctx_pmds[k].val;
+		} else {
+			/* for now */
+			if (ta != current) return -EINVAL;
 
-		case PFM_WRITE_PMDS:
+			val = ia64_get_pmd(tmp.pfr_reg.reg_num);
+		}
+		tmp.pfr_reg.reg_value = val;
+
+		DBprintk((" reading PMD[%ld]=0x%lx\n", tmp.pfr_reg.reg_num, val));
+
+		if (copy_to_user(req, &tmp, sizeof(tmp))) return -EFAULT;
+	}
+	return 0;
+}
+
+static int
+pfm_do_restart(struct task_struct *task)
+{
+	struct thread_struct *th = &task->thread;
+	pfm_context_t *ctx = th->pfm_context;
+	void *sem = &ctx->ctx_restart_sem;
+
+	if (task == current) {
+		DBprintk((" restartig self %d frozen=%d \n", current->pid, ctx->ctx_fl_frozen));
+
+		pfm_reset_regs(ctx);
+
+		/*
+		 * We ignore block/don't block because we never block
+		 * for a self-monitoring process.
+		 */
+		ctx->ctx_fl_frozen = 0;
+
+		if (CTX_HAS_SMPL(ctx)) {
+			ctx->ctx_smpl_buf->psb_hdr->hdr_count = 0;
+			ctx->ctx_smpl_buf->psb_index = 0;
+		}
+
+		/* pfm_reset_smpl_buffers(ctx,th->pfm_ovfl_regs);*/
+
+		/* simply unfreeze */
+		ia64_set_pmc(0, 0);
+		ia64_srlz_d();
+
+		return 0;
+	}
+
+	/* check if blocking */
+	if (CTX_OVFL_NOBLOCK(ctx) == 0) {
+		DBprintk((" unblocking %d \n", task->pid));
+		up(sem);
+		return 0;
+	}
+
+	/*
+	 * in case of non blocking mode, then it's just a matter of
+	 * of reseting the sampling buffer (if any) index. The PMU
+	 * is already active.
+	 */
+
+	/*
+	 * must reset the header count first
+	 */
+	if (CTX_HAS_SMPL(ctx)) {
+		DBprintk((" resetting sampling indexes for %d \n", task->pid));
+		ctx->ctx_smpl_buf->psb_hdr->hdr_count = 0;
+		ctx->ctx_smpl_buf->psb_index = 0;
+	}
+
+	return 0;
+}
+
+
+static int
+do_perfmonctl (struct task_struct *task, int cmd, int flags, perfmon_req_t *req, int count, struct pt_regs *regs)
+{
+	perfmon_req_t tmp;
+	struct thread_struct *th = &task->thread;
+	pfm_context_t *ctx = th->pfm_context;
+
+	memset(&tmp, 0, sizeof(tmp));
+
+	switch (cmd) {
+		case PFM_CREATE_CONTEXT:
+			/* a context has already been defined */
+			if (ctx) return -EBUSY;
+
+			/* may be a temporary limitation */
+			if (task != current) return -EINVAL;
+
+			if (req == NULL || count != 1) return -EINVAL;
+
+			if (!access_ok(VERIFY_READ, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT;
+
+			return pfm_context_create(task, flags, req);
+
+		case PFM_WRITE_PMCS:
 			/* we don't quite support this right now */
 			if (task != current) return -EINVAL;
 
 			if (!access_ok(VERIFY_READ, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT;
 
-			for (i = 0; i < count; i++, req++) {
-				copy_from_user(&tmp, req, sizeof(tmp));
+			if (!ctx) {
+				DBprintk((" PFM_WRITE_PMCS: no context for task %d\n", task->pid));
+				return -EINVAL;
+			}
+			return pfm_write_pmcs(task, req, count);
+
+		case PFM_WRITE_PMDS:
+			/* we don't quite support this right now */
+			if (task != current) return -EINVAL;
 
-				if (!PMD_IS_IMPL(tmp.pfr_reg_num)) return -EINVAL;
+			if (!access_ok(VERIFY_READ, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT;
 
-				/* update virtualized (64bits) counter */
-				if (PMD_IS_COUNTER(tmp.pfr_reg_num)) {
-					current->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].val  = tmp.pfr_reg_value & ~pmu_conf.perf_ovfl_val;
-					current->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].rval = tmp.pfr_reg_reset;
-				}
-				/* writes to unimplemented part is ignored, so this is safe */
-				ia64_set_pmd(tmp.pfr_reg_num, tmp.pfr_reg_value);
-				/* to go away */
-				ia64_srlz_d();
-				DBprintk((__FUNCTION__" setting PMD[%ld]:  pmod.val=0x%lx pmd=0x%lx rval=0x%lx\n", tmp.pfr_reg_num, current->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].val, ia64_get_pmd(tmp.pfr_reg_num),current->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].rval));
+			if (!ctx) {
+				DBprintk((" PFM_WRITE_PMDS: no context for task %d\n", task->pid));
+				return -EINVAL;
 			}
-			/*
-			 * we have to set this here event hough we haven't necessarily started monitoring
-			 * because we may be context switched out
-			 */
-			current->thread.flags |= IA64_THREAD_PM_VALID;
-                	break;
+			return pfm_write_pmds(task, req, count);
 
 		case PFM_START:
 			/* we don't quite support this right now */
 			if (task != current) return -EINVAL;
 
-			pmu_owners[smp_processor_id()] = current;
+			if (!ctx) {
+				DBprintk((" PFM_START: no context for task %d\n", task->pid));
+				return -EINVAL;
+			}
+
+			SET_PMU_OWNER(current);
 
 			/* will start monitoring right after rfi */
 			ia64_psr(regs)->up = 1;
 
-			/* 
-		 	 * mark the state as valid.
-		 	 * this will trigger save/restore at context switch
-		 	 */
-			current->thread.flags |= IA64_THREAD_PM_VALID;
+			/*
+			 * mark the state as valid.
+			 * this will trigger save/restore at context switch
+			 */
+			th->flags |= IA64_THREAD_PM_VALID;
 
 			ia64_set_pmc(0, 0);
+			ia64_srlz_d();
 
-                	break;
+		break;
 
 		case PFM_ENABLE:
 			/* we don't quite support this right now */
 			if (task != current) return -EINVAL;
 
-			pmu_owners[smp_processor_id()] = current;
+			if (!ctx) {
+				DBprintk((" PFM_ENABLE: no context for task %d\n", task->pid));
+				return -EINVAL;
+			}
+
+			/* reset all registers to stable quiet state */
+			ia64_reset_pmu();
+
+			/* make sure nothing starts */
+			ia64_psr(regs)->up = 0;
+			ia64_psr(regs)->pp = 0;
+
+			/* do it on the live register as well */
+			__asm__ __volatile__ ("rsm psr.pp|psr.pp;;"::: "memory");
+
+			SET_PMU_OWNER(current);
 
-			/* 
-		 	 * mark the state as valid.
-		 	 * this will trigger save/restore at context switch
-		 	 */
-			current->thread.flags |= IA64_THREAD_PM_VALID;
+			/*
+			 * mark the state as valid.
+			 * this will trigger save/restore at context switch
+			 */
+			th->flags |= IA64_THREAD_PM_VALID;
 
 			/* simply unfreeze */
 			ia64_set_pmc(0, 0);
+			ia64_srlz_d();
 			break;
 
 		case PFM_DISABLE:
 			/* we don't quite support this right now */
 			if (task != current) return -EINVAL;
 
-			/* simply unfreeze */
+			/* simply freeze */
 			ia64_set_pmc(0, 1);
 			ia64_srlz_d();
 			break;
 
-	        case PFM_READ_PMDS:
+		case PFM_READ_PMDS:
 			if (!access_ok(VERIFY_READ, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT;
 			if (!access_ok(VERIFY_WRITE, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT;
 
-		/* This looks shady, but IMHO this will work fine. This is  
-		 * the sequence that I could come up with to avoid races
-		 * with the interrupt handler. See explanation in the 
-		 * following comment.
-		 */
-#if 0
-/* irrelevant with user monitors */
-		local_irq_save(flags);
-		__asm__ __volatile__("rsm psr.pp\n");
-		dcr = ia64_get_dcr();
-		dcr &= ~IA64_DCR_PP;
-		ia64_set_dcr(dcr);
-		local_irq_restore(flags);
-#endif
-		/*
-		 * We cannot write to pmc[0] to stop counting here, as
-		 * that particular instruction might cause an overflow
-		 * and the mask in pmc[0] might get lost. I'm _not_ 
-		 * sure of the hardware behavior here. So we stop
-		 * counting by psr.pp = 0. And we reset dcr.pp to
-		 * prevent an interrupt from mucking up psr.pp in the
-		 * meanwhile. Perfmon interrupts are pended, hence the
-		 * above code should be ok if one of the above instructions 
-		 * caused overflows, i.e the interrupt should get serviced
-		 * when we re-enabled interrupts. When I muck with dcr, 
-		 * is the irq_save/restore needed?
-		 */
-
-		for (i = 0; i < count; i++, req++) {
-			unsigned long val=0;
-
-			copy_from_user(&tmp, req, sizeof(tmp));
-
-			if (!PMD_IS_IMPL(tmp.pfr_reg_num)) return -EINVAL;
-
-			if (PMD_IS_COUNTER(tmp.pfr_reg_num)) {
-				if (task == current){
-					val = ia64_get_pmd(tmp.pfr_reg_num) & pmu_conf.perf_ovfl_val;
-				} else {
-					val = task->thread.pmd[tmp.pfr_reg_num - PMU_FIRST_COUNTER] & pmu_conf.perf_ovfl_val;
-				}
-				val += task->thread.pmu_counters[tmp.pfr_reg_num - PMU_FIRST_COUNTER].val;
-			} else {
-				/* for now */
-				if (task != current) return -EINVAL;
-
-				val = ia64_get_pmd(tmp.pfr_reg_num);
+			if (!ctx) {
+				DBprintk((" PFM_READ_PMDS: no context for task %d\n", task->pid));
+				return -EINVAL;
 			}
-			tmp.pfr_reg_value = val;
-
-DBprintk((__FUNCTION__" reading PMD[%ld]=0x%lx\n", tmp.pfr_reg_num, val));
-
-			if (copy_to_user(req, &tmp, sizeof(tmp))) return -EFAULT;
-		}
-#if 0
-/* irrelevant with user monitors */
-		local_irq_save(flags);
-		__asm__ __volatile__("ssm psr.pp");
-		dcr = ia64_get_dcr();
-		dcr |= IA64_DCR_PP;
-		ia64_set_dcr(dcr);
-		local_irq_restore(flags);
-#endif
-                break;
+			return pfm_read_pmds(task, req, count);
 
 	      case PFM_STOP:
-		/* we don't quite support this right now */
-		if (task != current) return -EINVAL;
+			/* we don't quite support this right now */
+			if (task != current) return -EINVAL;
 
-		ia64_set_pmc(0, 1);
-		ia64_srlz_d();
+			ia64_set_pmc(0, 1);
+			ia64_srlz_d();
 
-		ia64_psr(regs)->up = 0;
+			ia64_psr(regs)->up = 0;
 
-		current->thread.flags &= ~IA64_THREAD_PM_VALID;
+			th->flags &= ~IA64_THREAD_PM_VALID;
 
-		pmu_owners[smp_processor_id()] = NULL;
+			SET_PMU_OWNER(NULL);
 
-#if 0
-/* irrelevant with user monitors */
-		local_irq_save(flags);
-		dcr = ia64_get_dcr();
-		dcr &= ~IA64_DCR_PP;
-		ia64_set_dcr(dcr);
-		local_irq_restore(flags);
-		ia64_psr(regs)->up = 0;
-#endif
-
-		break;
+			/* we probably will need some more cleanup here */
+			break;
 
 	      case PFM_DEBUG_ON:
-			printk(__FUNCTION__" debuggin on\n");
+			printk(" debugging on\n");
 			pfm_debug = 1;
 			break;
 
 	      case PFM_DEBUG_OFF:
-			printk(__FUNCTION__" debuggin off\n");
+			printk(" debugging off\n");
 			pfm_debug = 0;
 			break;
 
+	      case PFM_RESTART: /* temporary, will most likely end up as a PFM_ENABLE */
+
+			if ((th->flags & IA64_THREAD_PM_VALID) == 0) {
+				printk(" PFM_RESTART not monitoring\n");
+				return -EINVAL;
+			}
+			if (!ctx) {
+				printk(" PFM_RESTART no ctx for %d\n", task->pid);
+				return -EINVAL;
+			}
+			if (CTX_OVFL_NOBLOCK(ctx) == 0 && ctx->ctx_fl_frozen==0) {
+				printk("task %d without pmu_frozen set\n", task->pid);
+				return -EINVAL;
+			}
+
+			return pfm_do_restart(task); /* we only look at first entry */
+
 	      default:
-		DBprintk((__FUNCTION__" UNknown command 0x%x\n", cmd));
-		return -EINVAL;
-		break;
-        }
-        return 0;
+			DBprintk((" UNknown command 0x%x\n", cmd));
+			return -EINVAL;
+	}
+	return 0;
+}
+
+/*
+ * XXX: do something better here
+ */
+static int
+perfmon_bad_permissions(struct task_struct *task)
+{
+	/* stolen from bad_signal() */
+	return (current->session != task->session)
+	    && (current->euid ^ task->suid) && (current->euid ^ task->uid)
+	    && (current->uid ^ task->suid) && (current->uid ^ task->uid);
 }
 
 asmlinkage int
@@ -361,8 +1070,16 @@
 {
 	struct pt_regs *regs = (struct pt_regs *) &stack;
 	struct task_struct *child = current;
-	int ret;
+	int ret = -ESRCH;
+
+	/* sanity check:
+	 *
+	 * ensures that we don't do bad things in case the OS
+	 * does not have enough storage to save/restore PMC/PMD
+	 */
+	if (PERFMON_IS_DISABLED()) return -ENOSYS;
 
+	/* XXX: pid interface is going away in favor of pfm context */
 	if (pid != current->pid) {
 		read_lock(&tasklist_lock);
 		{
@@ -370,37 +1087,245 @@
 			if (child)
 				get_task_struct(child);
 		}
-		if (!child) { 
-			read_unlock(&tasklist_lock);
-			return -ESRCH;
-		}
+
+		if (!child) goto abort_call;
+
+		ret = -EPERM;
+
+		if (perfmon_bad_permissions(child)) goto abort_call;
+
 		/*
 		 * XXX: need to do more checking here
 		 */
-		if (child->state != TASK_ZOMBIE) {
-			DBprintk((__FUNCTION__" warning process %d not in stable state %ld\n", pid, child->state));
+		if (child->state != TASK_ZOMBIE && child->state != TASK_STOPPED) {
+			DBprintk((" warning process %d not in stable state %ld\n", pid, child->state));
 		}
-	} 
+	}
 	ret = do_perfmonctl(child, cmd, flags, req, count, regs);
 
+abort_call:
 	if (child != current) read_unlock(&tasklist_lock);
 
 	return ret;
 }
 
 
-static inline int
-update_counters (u64 pmc0)
+/*
+ * This function is invoked on the exit path of the kernel. Therefore it must make sure
+ * it does does modify the caller's input registers (in0-in7) in case of entry by system call
+ * which can be restarted. That's why it's declared as a system call and all 8 possible args
+ * are declared even though not used.
+ */
+#if __GNUC__ >= 3
+void asmlinkage
+pfm_overflow_notify(void)
+#else
+void asmlinkage
+pfm_overflow_notify(u64 arg0, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7)
+#endif
 {
-	unsigned long mask, i, cnum;
-	struct thread_struct *th;
-	struct task_struct *ta;
+	struct task_struct *task;
+	struct thread_struct *th = &current->thread;
+	pfm_context_t *ctx = current->thread.pfm_context;
+	struct siginfo si;
+	int ret;
 
-	if (pmu_owners[smp_processor_id()] == NULL) {
-		DBprintk((__FUNCTION__" Spurious overflow interrupt: PMU not owned\n"));
-		return 0;
+	/*
+	 * do some sanity checks first
+	 */
+	if (!ctx) {
+		printk("perfmon: process %d has no PFM context\n", current->pid);
+		return;
+	}
+	if (ctx->ctx_notify_pid < 2) {
+		printk("perfmon: process %d invalid notify_pid=%d\n", current->pid, ctx->ctx_notify_pid);
+		return;
+	}
+
+	DBprintk((" current=%d ctx=%p bv=0%lx\n", current->pid, (void *)ctx, ctx->ctx_ovfl_regs));
+	/*
+	 * NO matter what notify_pid is,
+	 * we clear overflow, won't notify again
+	 */
+	th->pfm_pend_notify = 0;
+
+	/*
+	 * When measuring in kernel mode and non-blocking fashion, it is possible to
+	 * get an overflow while executing this code. Therefore the state of pend_notify
+	 * and ovfl_regs can be altered. The important point is not to loose any notification.
+	 * It is fine to get called for nothing. To make sure we do collect as much state as
+	 * possible, update_counters() always uses |= to add bit to the ovfl_regs field.
+	 *
+	 * In certain cases, it is possible to come here, with ovfl_regs == 0;
+	 *
+	 * XXX: pend_notify and ovfl_regs could be merged maybe !
+	 */
+	if (ctx->ctx_ovfl_regs == 0) {
+		printk("perfmon: spurious overflow notification from pid %d\n", current->pid);
+		return;
 	}
-	
+	read_lock(&tasklist_lock);
+
+	task = find_task_by_pid(ctx->ctx_notify_pid);
+
+	if (task) {
+		si.si_signo    = ctx->ctx_notify_sig;
+		si.si_errno    = 0;
+		si.si_code     = PROF_OVFL; /* goes to user */
+		si.si_addr     = NULL;
+		si.si_pid      = current->pid; /* who is sending */
+		si.si_pfm_ovfl = ctx->ctx_ovfl_regs;
+
+		DBprintk((" SIGPROF to %d @ %p\n", task->pid, (void *)task));
+
+		/* must be done with tasklist_lock locked */
+		ret = send_sig_info(ctx->ctx_notify_sig, &si, task);
+		if (ret != 0) {
+			DBprintk((" send_sig_info(process %d, SIGPROF)=%d\n", ctx->ctx_notify_pid, ret));
+			task = NULL; /* will cause return */
+		}
+	} else {
+		printk("perfmon: notify_pid %d not found\n", ctx->ctx_notify_pid);
+	}
+
+	read_unlock(&tasklist_lock);
+
+	/* now that we have released the lock handle error condition */
+	if (!task || CTX_OVFL_NOBLOCK(ctx)) {
+		/* we clear all pending overflow bits in noblock mode */
+		ctx->ctx_ovfl_regs = 0;
+		return;
+	}
+	DBprintk((" CPU%d %d before sleep\n", smp_processor_id(), current->pid));
+
+	/*
+	 * may go through without blocking on SMP systems
+	 * if restart has been received already by the time we call down()
+	 */
+	ret = down_interruptible(&ctx->ctx_restart_sem);
+
+	DBprintk((" CPU%d %d after sleep ret=%d\n", smp_processor_id(), current->pid, ret));
+
+	/*
+	 * in case of interruption of down() we don't restart anything
+	 */
+	if (ret >= 0) {
+		/* we reactivate on context switch */
+		ctx->ctx_fl_frozen = 0;
+		/*
+		 * the ovfl_sem is cleared by the restart task and this is safe because we always
+		 * use the local reference
+		 */
+
+		pfm_reset_regs(ctx);
+
+		/* now we can clear this mask */
+		ctx->ctx_ovfl_regs = 0;
+
+		/*
+		 * Unlock sampling buffer and reset index atomically
+		 * XXX: not really needed when blocking
+		 */
+		if (CTX_HAS_SMPL(ctx)) {
+			ctx->ctx_smpl_buf->psb_hdr->hdr_count = 0;
+			ctx->ctx_smpl_buf->psb_index = 0;
+		}
+
+		DBprintk((" CPU%d %d unfreeze PMU\n", smp_processor_id(), current->pid));
+
+		ia64_set_pmc(0, 0);
+		ia64_srlz_d();
+
+		/* state restored, can go back to work (user mode) */
+	}
+}
+
+static void
+perfmon_softint(unsigned long ignored)
+{
+	notification_info_t *info;
+	int my_cpu = smp_processor_id();
+	struct task_struct *task;
+	struct siginfo si;
+
+	info = notify_info+my_cpu;
+
+	DBprintk((" CPU%d current=%d to_pid=%d from_pid=%d bv=0x%lx\n", \
+		smp_processor_id(), current->pid, info->to_pid, info->from_pid, info->bitvect));
+
+	/* assumption check */
+	if (info->from_pid == info->to_pid) {
+		DBprintk((" Tasklet assumption error: from=%d tor=%d\n", info->from_pid, info->to_pid));
+		return;
+	}
+
+	if (notification_is_invalid(info)) {
+		DBprintk((" invalid notification information\n"));
+		return;
+	}
+
+	/* sanity check */
+	if (info->to_pid == 1) {
+		DBprintk((" cannot notify init\n"));
+		return;
+	}
+	/*
+	 * XXX: needs way more checks here to make sure we send to a task we have control over
+	 */
+	read_lock(&tasklist_lock);
+
+	task = find_task_by_pid(info->to_pid);
+
+	DBprintk((" after find %p\n", (void *)task));
+
+	if (task) {
+		int ret;
+
+		si.si_signo    = SIGPROF;
+		si.si_errno    = 0;
+		si.si_code     = PROF_OVFL; /* goes to user */
+		si.si_addr     =  NULL;
+		si.si_pid      = info->from_pid; /* who is sending */
+		si.si_pfm_ovfl = info->bitvect;
+
+		DBprintk((" SIGPROF to %d @ %p\n", task->pid, (void *)task));
+
+		/* must be done with tasklist_lock locked */
+		ret = send_sig_info(SIGPROF, &si, task);
+		if (ret != 0)
+			DBprintk((" send_sig_info(process %d, SIGPROF)=%d\n", info->to_pid, ret));
+
+		/* invalidate notification */
+		info->to_pid  = info->from_pid = 0;
+		info->bitvect = 0;
+	}
+
+	read_unlock(&tasklist_lock);
+
+	DBprintk((" after unlock %p\n", (void *)task));
+
+	if (!task) {
+		printk("perfmon: CPU%d cannot find process %d\n", smp_processor_id(), info->to_pid);
+	}
+}
+
+/*
+ * main overflow processing routine.
+ * it can be called from the interrupt path or explicitely during the context switch code
+ * Return:
+ *	0 : do not unfreeze the PMU
+ *	1 : PMU can be unfrozen
+ */
+static unsigned long
+update_counters (struct task_struct *ta, u64 pmc0, struct pt_regs *regs)
+{
+	unsigned long mask, i, cnum;
+	struct thread_struct *th;
+	pfm_context_t *ctx;
+	unsigned long bv = 0;
+	int my_cpu = smp_processor_id();
+	int ret = 1, buffer_is_full = 0;
+	int ovfl_is_smpl, can_notify, need_reset_pmd16=0;
 	/*
 	 * 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
@@ -408,76 +1333,269 @@
 	 *
 	 * For monitoring, however, we do need to get access to the task which caused the overflow
 	 * to account for overflow on the counters.
+	 *
 	 * We accomplish this by maintaining a current owner of the PMU per CPU. During context
-	 * switch the ownership is changed in a way such that the reflected owner is always the 
+	 * switch the ownership is changed in a way such that the reflected owner is always the
 	 * valid one, i.e. the one that caused the interrupt.
 	 */
-	ta = pmu_owners[smp_processor_id()];
-	th = &pmu_owners[smp_processor_id()]->thread;
+
+	if (ta == NULL) {
+		DBprintk((" owners[%d]=NULL\n", my_cpu));
+		return 0x1;
+	}
+	th  = &ta->thread;
+	ctx = th->pfm_context;
 
 	/*
-	 * Don't think this could happen given first test. Keep as sanity check
+	 * XXX: debug test
+	 * Don't think this could happen given upfront tests
 	 */
 	if ((th->flags & IA64_THREAD_PM_VALID) == 0) {
-		DBprintk((__FUNCTION__" Spurious overflow interrupt: process %d not using perfmon\n", ta->pid));
+		printk("perfmon: Spurious overflow interrupt: process %d not using perfmon\n", ta->pid);
+		return 0x1;
+	}
+	if (!ctx) {
+		printk("perfmon: Spurious overflow interrupt: process %d has no PFM context\n", ta->pid);
 		return 0;
 	}
 
 	/*
-	 * if PMU not frozen: spurious from previous context 
-	 * if PMC[0] = 0x1 : frozen but no overflow reported: leftover from previous context
-	 *
-	 * in either case we don't touch the state upon return from handler
+	 * sanity test. Should never happen
 	 */
-	if ((pmc0 & 0x1) == 0 || pmc0 == 0x1) { 
-		DBprintk((__FUNCTION__" Spurious overflow interrupt: process %d freeze=0\n",ta->pid));
-		return 0;
+	if ((pmc0 & 0x1 )== 0) {
+		printk("perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n", ta->pid, pmc0);
+		return 0x0;
 	}
 
-	mask = pmc0 >> 4;
+	mask = pmc0 >> PMU_FIRST_COUNTER;
 
-	for (i = 0, cnum = PMU_FIRST_COUNTER; i < pmu_conf.max_counters; cnum++, i++, mask >>= 1) {
+	DBprintk(("pmc0=0x%lx pid=%d\n", pmc0, ta->pid));
 
-		if (mask & 0x1) {
-			DBprintk((__FUNCTION__ " PMD[%ld] overflowed pmd=0x%lx pmod.val=0x%lx\n", cnum, ia64_get_pmd(cnum), th->pmu_counters[i].val)); 
-			
+	DBprintk(("ctx is in %s mode\n", CTX_OVFL_NOBLOCK(ctx) ? "NO-BLOCK" : "BLOCK"));
+
+	if (CTX_HAS_SMPL(ctx)) {
+		pfm_smpl_buffer_desc_t *psb = ctx->ctx_smpl_buf;
+		unsigned long *e, m, idx=0;
+		perfmon_smpl_entry_t *h;
+		int j;
+
+		idx = ia64_fetch_and_add(1, &psb->psb_index);
+		DBprintk((" trying to record index=%ld entries=%ld\n", idx, psb->psb_entries));
+
+		/*
+		 * XXX: there is a small chance that we could run out on index before resetting
+		 * but index is unsigned long, so it will take some time.....
+		 */
+		if (idx > psb->psb_entries) {
+			buffer_is_full = 1;
+			goto reload_pmds;
+		}
+
+		/* first entry is really entry 0, not 1 caused by fetch_and_add */
+		idx--;
+
+		h = (perfmon_smpl_entry_t *)(((char *)psb->psb_addr) + idx*(psb->psb_entry_size));
+
+		h->pid  = ta->pid;
+		h->cpu  = my_cpu;
+		h->rate = 0;
+		h->ip   = regs ? regs->cr_iip : 0x0; /* where did the fault happened */
+		h->regs = mask; /* which registers overflowed */
+
+		/* guaranteed to monotonically increase on each cpu */
+		h->stamp = perfmon_get_stamp();
+
+		e = (unsigned long *)(h+1);
+		/*
+		 * selectively store PMDs in increasing index number
+		 */
+		for (j=0, m = ctx->ctx_smpl_regs; m; m >>=1, j++) {
+			if (m & 0x1) {
+				if (PMD_IS_COUNTER(j))
+					*e =  ctx->ctx_pmds[j-PMU_FIRST_COUNTER].val
+					    + (ia64_get_pmd(j) & pmu_conf.perf_ovfl_val);
+				else
+					*e = ia64_get_pmd(j); /* slow */
+				DBprintk((" e=%p pmd%d =0x%lx\n", (void *)e, j, *e));
+				e++;
+			}
+		}
+		/* make the new entry visible to user, needs to be atomic */
+		ia64_fetch_and_add(1, &psb->psb_hdr->hdr_count);
+
+		DBprintk((" index=%ld entries=%ld hdr_count=%ld\n", idx, psb->psb_entries, psb->psb_hdr->hdr_count));
+
+		/* sampling buffer full ? */
+		if (idx == (psb->psb_entries-1)) {
+			bv = mask;
+			buffer_is_full = 1;
+
+			DBprintk((" sampling buffer full must notify bv=0x%lx\n", bv));
+
+			if (!CTX_OVFL_NOBLOCK(ctx)) goto buffer_full;
 			/*
-			 * Because we somtimes (EARS/BTB) reset to a specific value, we cannot simply use 
-			 * val to count the number of times we overflowed. Otherwise we would loose the value
-			 * current in the PMD (which can be >0). So to make sure we don't loose
-			 * the residual counts we set val to contain full 64bits value of the counter.
+			 * here, we have a full buffer but we are in non-blocking mode
+			 * so we need to reloads overflowed PMDs with sampling reset values
+			 * and restart
 			 */
-			th->pmu_counters[i].val += 1+pmu_conf.perf_ovfl_val+(ia64_get_pmd(cnum) &pmu_conf.perf_ovfl_val);
+		}
+	}
+reload_pmds:
+	ovfl_is_smpl = CTX_OVFL_NOBLOCK(ctx) && buffer_is_full;
+	can_notify   = CTX_HAS_SMPL(ctx) == 0 && ctx->ctx_notify_pid;
 
-			/* writes to upper part are ignored, so this is safe */
-			ia64_set_pmd(cnum, th->pmu_counters[i].rval);
+	for (i = 0, cnum = PMU_FIRST_COUNTER; mask ; cnum++, i++, mask >>= 1) {
+
+		if ((mask & 0x1) == 0) continue;
+
+		DBprintk((" PMD[%ld] overflowed pmd=0x%lx pmod.val=0x%lx\n", cnum, ia64_get_pmd(cnum), ctx->ctx_pmds[i].val));
 
-			DBprintk((__FUNCTION__ " pmod[%ld].val=0x%lx pmd=0x%lx\n", i, th->pmu_counters[i].val, ia64_get_pmd(cnum)&pmu_conf.perf_ovfl_val)); 
+		/*
+		 * Because we sometimes (EARS/BTB) reset to a specific value, we cannot simply use
+		 * val to count the number of times we overflowed. Otherwise we would loose the current value
+		 * in the PMD (which can be >0). So to make sure we don't loose
+		 * the residual counts we set val to contain full 64bits value of the counter.
+		 *
+		 * XXX: is this needed for EARS/BTB ?
+		 */
+		ctx->ctx_pmds[i].val += 1 + pmu_conf.perf_ovfl_val
+				      + (ia64_get_pmd(cnum) & pmu_conf.perf_ovfl_val); /* slow */
+
+		DBprintk((" pmod[%ld].val=0x%lx pmd=0x%lx\n", i, ctx->ctx_pmds[i].val, ia64_get_pmd(cnum)&pmu_conf.perf_ovfl_val));
+
+		if (can_notify && PMD_OVFL_NOTIFY(ctx, i)) {
+			DBprintk((" CPU%d should notify process %d with signal %d\n", my_cpu, ctx->ctx_notify_pid, ctx->ctx_notify_sig));
+			bv |= 1 << i;
+		} else {
+			DBprintk((" CPU%d PMD[%ld] overflow, no notification\n", my_cpu, cnum));
+			/*
+			 * In case no notification is requested, we reload the reset value right away
+			 * otherwise we wait until the notify_pid process has been called and has
+			 * has finished processing data. Check out pfm_overflow_notify()
+			 */
 
-			if (th->pmu_counters[i].pid != 0 && th->pmu_counters[i].sig>0) {
-				DBprintk((__FUNCTION__ " shouild notify process %d with signal %d\n",th->pmu_counters[i].pid, th->pmu_counters[i].sig)); 
+			/* writes to upper part are ignored, so this is safe */
+			if (ovfl_is_smpl) {
+				DBprintk((" CPU%d PMD[%ld] reloaded with smpl_val=%lx\n", my_cpu, cnum,ctx->ctx_pmds[i].smpl_rval));
+				ia64_set_pmd(cnum, ctx->ctx_pmds[i].smpl_rval);
+			} else {
+				DBprintk((" CPU%d PMD[%ld] reloaded with ovfl_val=%lx\n", my_cpu, cnum,ctx->ctx_pmds[i].smpl_rval));
+				ia64_set_pmd(cnum, ctx->ctx_pmds[i].ovfl_rval);
 			}
 		}
+		if (cnum == ctx->ctx_btb_counter) need_reset_pmd16=1;
 	}
-	return 1;
+	/*
+	 * In case of BTB, overflow
+	 * we need to reset the BTB index.
+	 */
+	if (need_reset_pmd16) {
+		DBprintk(("reset PMD16\n"));
+		ia64_set_pmd(16, 0);
+	}
+buffer_full:
+	/* see pfm_overflow_notify() on details for why we use |= here */
+	ctx->ctx_ovfl_regs  |= bv;
+
+	/* nobody to notify, return and unfreeze */
+	if (!bv) return 0x0;
+
+
+	if (ctx->ctx_notify_pid == ta->pid) {
+		struct siginfo si;
+
+		si.si_errno    = 0;
+		si.si_addr     = NULL;
+		si.si_pid      = ta->pid; /* who is sending */
+
+
+		si.si_signo    = ctx->ctx_notify_sig; /* is SIGPROF */
+		si.si_code     = PROF_OVFL; /* goes to user */
+		si.si_pfm_ovfl = bv;
+
+
+		/*
+		 * 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((" sending %d notification to self %d\n", si.si_signo, ta->pid));
+
+
+		/* this call is safe in an interrupt handler */
+		ret = send_sig_info(ctx->ctx_notify_sig, &si, ta);
+		if (ret != 0)
+			printk(" send_sig_info(process %d, SIGPROF)=%d\n", ta->pid, ret);
+		/*
+		 * no matter if we block or not, we keep PMU frozen and do not unfreeze on ctxsw
+		 */
+		ctx->ctx_fl_frozen = 1;
+
+	} else {
+#if 0
+			/*
+			 * The tasklet is guaranteed to be scheduled for this CPU only
+			 */
+			notify_info[my_cpu].to_pid   = ctx->notify_pid;
+			notify_info[my_cpu].from_pid = ta->pid; /* for debug only */
+			notify_info[my_cpu].bitvect  = bv;
+			/* tasklet is inserted and active */
+			tasklet_schedule(&pfm_tasklet);
+#endif
+			/*
+			 * stored the vector of overflowed registers for use in notification
+			 * mark that a notification/blocking is pending (arm the trap)
+			 */
+		th->pfm_pend_notify = 1;
+
+		/*
+		 * if we do block, then keep PMU frozen until restart
+		 */
+		if (!CTX_OVFL_NOBLOCK(ctx)) ctx->ctx_fl_frozen = 1;
+
+		DBprintk((" process %d notify ovfl_regs=0x%lx\n", ta->pid, bv));
+	}
+	/*
+	 * keep PMU frozen (and overflowed bits cleared) when we have to stop,
+	 * otherwise return a resume 'value' for PMC[0]
+	 *
+	 * XXX: maybe that's enough to get rid of ctx_fl_frozen ?
+	 */
+	DBprintk((" will return pmc0=0x%x\n",ctx->ctx_fl_frozen ? 0x1 : 0x0));
+	return ctx->ctx_fl_frozen ? 0x1 : 0x0;
 }
 
 static void
 perfmon_interrupt (int irq, void *arg, struct pt_regs *regs)
 {
-	/* unfreeze if not spurious */
-	if ( update_counters(ia64_get_pmc(0)) ) {
-		ia64_set_pmc(0, 0);
+	u64 pmc0;
+	struct task_struct *ta;
+
+	pmc0 = ia64_get_pmc(0); /* slow */
+
+	/*
+	 * if we have some pending bits set
+	 * assumes : if any PM[0].bit[63-1] is set, then PMC[0].fr = 1
+	 */
+	if ((pmc0 & ~0x1) && (ta=PMU_OWNER())) {
+
+		/* assumes, PMC[0].fr = 1 at this point */
+		pmc0 = update_counters(ta, pmc0, regs);
+
+		/*
+		 * if pmu_frozen = 0
+		 *	pmc0 = 0 and we resume monitoring right away
+		 * else
+		 *	pmc0 = 0x1 frozen but all pending bits are cleared
+		 */
+		ia64_set_pmc(0, pmc0);
 		ia64_srlz_d();
+	} else {
+		printk("perfmon: Spurious PMU overflow interrupt: pmc0=0x%lx owner=%p\n", pmc0, (void *)PMU_OWNER());
 	}
 }
 
-static struct irqaction perfmon_irqaction = {
-	handler:	perfmon_interrupt,
-	flags:		SA_INTERRUPT,
-	name:		"perfmon"
-};
-
+/* for debug only */
 static int
 perfmon_proc_info(char *page)
 {
@@ -487,56 +1605,79 @@
 
 	p += sprintf(p, "PMC[0]=%lx\nPerfmon debug: %s\n", pmc0, pfm_debug ? "On" : "Off");
 	for(i=0; i < NR_CPUS; i++) {
-		if (cpu_is_online(i)) 
-			p += sprintf(p, "CPU%d.PMU %d\n", i, pmu_owners[i] ? pmu_owners[i]->pid: -1);
+		if (cpu_is_online(i))
+			p += sprintf(p, "CPU%d.PMU %d\n", i, pmu_owners[i].owner ? pmu_owners[i].owner->pid: 0);
 	}
 	return p - page;
 }
 
+/* for debug only */
 static int
 perfmon_read_entry(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
 	int len = perfmon_proc_info(page);
 
-        if (len <= off+count) *eof = 1;
+	if (len <= off+count) *eof = 1;
 
-        *start = page + off;
-        len   -= off;
+	*start = page + off;
+	len   -= off;
 
-        if (len>count) len = count;
-        if (len<0) len = 0;
+	if (len>count) len = count;
+	if (len<0) len = 0;
 
-        return len;
+	return len;
 }
 
-static struct proc_dir_entry *perfmon_dir;
+static struct irqaction perfmon_irqaction = {
+	handler:	perfmon_interrupt,
+	flags:		SA_INTERRUPT,
+	name:		"perfmon"
+};
 
 void __init
 perfmon_init (void)
 {
 	pal_perf_mon_info_u_t pm_info;
 	s64 status;
-	
-	irq_desc[PERFMON_IRQ].status |= IRQ_PER_CPU;
-	irq_desc[PERFMON_IRQ].handler = &irq_type_ia64_sapic;
-	setup_irq(PERFMON_IRQ, &perfmon_irqaction);
 
-	ia64_set_pmv(PERFMON_IRQ);
+	register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
+
+	ia64_set_pmv(IA64_PERFMON_VECTOR);
 	ia64_srlz_d();
 
-	printk("perfmon: Initialized vector to %u\n",PERFMON_IRQ);
+	pmu_conf.pfm_is_disabled = 1;
+
+	printk("perfmon: version %s\n", PFM_VERSION);
+	printk("perfmon: Interrupt vectored to %u\n", IA64_PERFMON_VECTOR);
 
 	if ((status=ia64_pal_perf_mon_info(pmu_conf.impl_regs, &pm_info)) != 0) {
-		printk(__FUNCTION__ " pal call failed (%ld)\n", status);
+		printk("perfmon: PAL call failed (%ld)\n", status);
 		return;
-	} 
-	pmu_conf.perf_ovfl_val = (1L << pm_info.pal_perf_mon_info_s.width) - 1; 
-
-	/* XXX need to use PAL instead */
+	}
+	pmu_conf.perf_ovfl_val = (1L << pm_info.pal_perf_mon_info_s.width) - 1;
 	pmu_conf.max_counters  = pm_info.pal_perf_mon_info_s.generic;
+	pmu_conf.num_pmds      = find_num_pm_regs(pmu_conf.impl_regs);
+	pmu_conf.num_pmcs      = find_num_pm_regs(&pmu_conf.impl_regs[4]);
 
 	printk("perfmon: Counters are %d bits\n", pm_info.pal_perf_mon_info_s.width);
 	printk("perfmon: Maximum counter value 0x%lx\n", pmu_conf.perf_ovfl_val);
+	printk("perfmon: %ld PMC/PMD pairs\n", pmu_conf.max_counters);
+	printk("perfmon: %ld PMCs, %ld PMDs\n", pmu_conf.num_pmcs, pmu_conf.num_pmds);
+	printk("perfmon: Sampling format v%d\n", PFM_SMPL_HDR_VERSION);
+
+	/* sanity check */
+	if (pmu_conf.num_pmds >= IA64_NUM_PMD_REGS || pmu_conf.num_pmcs >= IA64_NUM_PMC_REGS) {
+		printk(KERN_ERR "perfmon: ERROR not enough PMC/PMD storage in kernel, perfmon is DISABLED\n");
+		return; /* no need to continue anyway */
+	}
+	/* we are all set */
+	pmu_conf.pfm_is_disabled = 0;
+
+	/*
+	 * Insert the tasklet in the list.
+	 * It is still disabled at this point, so it won't run
+	printk(__FUNCTION__" tasklet is %p state=%d, count=%d\n", &perfmon_tasklet, perfmon_tasklet.state, perfmon_tasklet.count);
+	 */
 
 	/*
 	 * for now here for debug purposes
@@ -547,7 +1688,7 @@
 void
 perfmon_init_percpu (void)
 {
-	ia64_set_pmv(PERFMON_IRQ);
+	ia64_set_pmv(IA64_PERFMON_VECTOR);
 	ia64_srlz_d();
 }
 
@@ -555,14 +1696,19 @@
  * XXX: for system wide this function MUST never be called
  */
 void
-ia64_save_pm_regs (struct task_struct *ta)
+pfm_save_regs (struct task_struct *ta)
 {
-	struct thread_struct *t = &ta->thread;
+	struct task_struct *owner;
+	struct thread_struct *t;
 	u64 pmc0, psr;
-	int i,j;
+	int i;
 
+	if (ta == NULL) {
+		panic(__FUNCTION__" task is NULL\n");
+	}
+	t = &ta->thread;
 	/*
-	 * We must maek sure that we don't loose any potential overflow
+	 * We must make sure that we don't loose any potential overflow
 	 * interrupt while saving PMU context. In this code, external
 	 * interrupts are always enabled.
 	 */
@@ -575,94 +1721,102 @@
 	/*
 	 * stop monitoring:
 	 * This is the only way to stop monitoring without destroying overflow
-	 * information in PMC[0..3].
+	 * information in PMC[0].
 	 * This is the last instruction which can cause overflow when monitoring
 	 * in kernel.
-	 * By now, we could still have an overflow interrupt in flight.
+	 * By now, we could still have an overflow interrupt in-flight.
 	 */
-	__asm__ __volatile__ ("rsm psr.up;;"::: "memory");
-	
+	__asm__ __volatile__ ("rum psr.up;;"::: "memory");
+
+	/*
+	 * Mark the PMU as not owned
+	 * This will cause the interrupt handler to do nothing in case an overflow
+	 * interrupt was in-flight
+	 * This also guarantees that pmc0 will contain the final state
+	 * It virtually gives us full control over overflow processing from that point
+	 * on.
+	 * It must be an atomic operation.
+	 */
+	owner = PMU_OWNER();
+	SET_PMU_OWNER(NULL);
+
 	/*
 	 * read current overflow status:
 	 *
-	 * We may be reading stale information at this point, if we got interrupt
-	 * just before the read(pmc0) but that's all right. However, if we did
-	 * not get the interrupt before, this read reflects LAST state.
-	 *
+	 * we are guaranteed to read the final stable state
 	 */
-	pmc0 = ia64_get_pmc(0);
+	ia64_srlz_d();
+	pmc0 = ia64_get_pmc(0); /* slow */
 
 	/*
 	 * freeze PMU:
 	 *
 	 * This destroys the overflow information. This is required to make sure
 	 * next process does not start with monitoring on if not requested
-	 * (PSR.up may not be enough).
-	 *
-	 * We could still get an overflow interrupt by now. However the handler
-	 * will not do anything if is sees PMC[0].fr=1 but no overflow bits
-	 * are set. So PMU will stay in frozen state. This implies that pmc0
-	 * will still be holding the correct unprocessed information.
-	 *
 	 */
 	ia64_set_pmc(0, 1);
 	ia64_srlz_d();
 
 	/*
-	 * check for overflow bits set:
+	 * Check for overflow bits and proceed manually if needed
 	 *
-	 * If pmc0 reports PMU frozen, this means we have a pending overflow,
-	 * therefore we invoke the handler. Handler is reentrant with regards
-	 * to PMC[0] so it is safe to call it twice.
-	 *
-	 * IF pmc0 reports overflow, we need to reread current PMC[0] value
-	 * in case the handler was invoked right after the first pmc0 read.
-	 * it is was not invoked then pmc0==PMC[0], otherwise it's been invoked
-	 * and overflow information has been processed, so we don't need to call.
-	 *
-	 * Test breakdown:
-	 *	- pmc0 & ~0x1: test if overflow happened
-	 * 	- second part: check if current register reflects this as well.
-	 *
-	 * NOTE: testing for pmc0 & 0x1 is not enough has it would trigger call
-	 * when PM_VALID and PMU.fr which is common when setting up registers
-	 * just before actually starting monitors.
-	 *
-	 */
-	if ((pmc0 & ~0x1) && ((pmc0=ia64_get_pmc(0)) &~0x1) ) {
-		printk(__FUNCTION__" Warning: pmc[0]=0x%lx\n", pmc0);
-		update_counters(pmc0);
-		/* 
-		 * XXX: not sure that's enough. the next task may still get the
-		 * interrupt.
-		 */
+	 * It is safe to call the interrupt handler now because it does
+	 * not try to block the task right away. Instead it will set a
+	 * flag and let the task proceed. The blocking will only occur
+	 * next time the task exits from the kernel.
+	 */
+	if (pmc0 & ~0x1) {
+		if (owner != ta) printk(__FUNCTION__" owner=%p task=%p\n", (void *)owner, (void *)ta);
+		printk(__FUNCTION__" Warning: pmc[0]=0x%lx explicit call\n", pmc0);
+
+		pmc0 = update_counters(owner, pmc0, NULL);
+		/* we will save the updated version of pmc0 */
 	}
 
 	/*
 	 * restore PSR for context switch to save
 	 */
-	__asm__ __volatile__ ("mov psr.l=%0;;"::"r"(psr): "memory");
+	__asm__ __volatile__ ("mov psr.l=%0;; srlz.i;;"::"r"(psr): "memory");
+
 
 	/*
-	 * XXX: this will need to be extended beyong just counters
+	 * XXX needs further optimization.
+	 * Also must take holes into account
 	 */
-	for (i=0,j=4; i< IA64_NUM_PMD_COUNTERS; i++,j++) {
-		t->pmd[i] = ia64_get_pmd(j);
-		t->pmc[i] = ia64_get_pmc(j);
+	for (i=0; i< pmu_conf.num_pmds; i++) {
+		t->pmd[i] = ia64_get_pmd(i);
+	}
+
+	/* skip PMC[0], we handle it separately */
+	for (i=1; i< pmu_conf.num_pmcs; i++) {
+		t->pmc[i] = ia64_get_pmc(i);
 	}
+
 	/*
-	 * PMU is frozen, PMU context is saved: nobody owns the PMU on this CPU
-	 * At this point, we should not receive any pending interrupt from the 
-	 * 'switched out' task
+	 * Throughout this code we could have gotten an overflow interrupt. It is transformed
+	 * into a spurious interrupt as soon as we give up pmu ownership.
 	 */
-	pmu_owners[smp_processor_id()] = NULL;
 }
 
 void
-ia64_load_pm_regs (struct task_struct *ta)
+pfm_load_regs (struct task_struct *ta)
 {
 	struct thread_struct *t = &ta->thread;
-	int i,j;
+	pfm_context_t *ctx = ta->thread.pfm_context;
+	int i;
+
+	/*
+	 * XXX needs further optimization.
+	 * Also must take holes into account
+	 */
+	for (i=0; i< pmu_conf.num_pmds; i++) {
+		ia64_set_pmd(i, t->pmd[i]);
+	}
+
+	/* skip PMC[0] to avoid side effects */
+	for (i=1; i< pmu_conf.num_pmcs; i++) {
+		ia64_set_pmc(i, t->pmc[i]);
+	}
 
 	/*
 	 * we first restore ownership of the PMU to the 'soon to be current'
@@ -670,26 +1824,277 @@
 	 * of this function, we get an interrupt, we attribute it to the correct
 	 * task
 	 */
-	pmu_owners[smp_processor_id()] = ta;
+	SET_PMU_OWNER(ta);
+
+#if 0
+	/*
+	 * check if we had pending overflow before context switching out
+	 * If so, we invoke the handler manually, i.e. simulate interrupt.
+	 *
+	 * XXX: given that we do not use the tasklet anymore to stop, we can
+	 * move this back to the pfm_save_regs() routine.
+	 */
+	if (t->pmc[0] & ~0x1) {
+		/* freeze set in pfm_save_regs() */
+		DBprintk((" pmc[0]=0x%lx manual interrupt\n",t->pmc[0]));
+		update_counters(ta, t->pmc[0], NULL);
+	}
+#endif
 
 	/*
-	 * XXX: this will need to be extended beyong just counters 
+	 * unfreeze only when possible
 	 */
-	for (i=0,j=4; i< IA64_NUM_PMD_COUNTERS; i++,j++) {
-		ia64_set_pmd(j, t->pmd[i]);
-		ia64_set_pmc(j, t->pmc[i]);
+	if (ctx->ctx_fl_frozen == 0) {
+		ia64_set_pmc(0, 0);
+		ia64_srlz_d();
+	}
+}
+
+
+/*
+ * This function is called when a thread exits (from exit_thread()).
+ * This is a simplified pfm_save_regs() that simply flushes hthe current
+ * register state into the save area taking into account any pending
+ * overflow. This time no notification is sent because the taks is dying
+ * anyway. The inline processing of overflows avoids loosing some counts.
+ * The PMU is frozen on exit from this call and is to never be reenabled
+ * again for this task.
+ */
+void
+pfm_flush_regs (struct task_struct *ta)
+{
+	pfm_context_t *ctx;
+	u64 pmc0, psr, mask;
+	int i,j;
+
+	if (ta == NULL) {
+		panic(__FUNCTION__" task is NULL\n");
 	}
+	ctx = ta->thread.pfm_context;
+	if (ctx == NULL) {
+		panic(__FUNCTION__" no PFM ctx is NULL\n");
+	}
+	/*
+	 * We must make sure that we don't loose any potential overflow
+	 * interrupt while saving PMU context. In this code, external
+	 * interrupts are always enabled.
+	 */
+
+	/*
+	 * save current PSR: needed because we modify it
+	 */
+	__asm__ __volatile__ ("mov %0=psr;;": "=r"(psr) :: "memory");
+
+	/*
+	 * stop monitoring:
+	 * This is the only way to stop monitoring without destroying overflow
+	 * information in PMC[0].
+	 * This is the last instruction which can cause overflow when monitoring
+	 * in kernel.
+	 * By now, we could still have an overflow interrupt in-flight.
+	 */
+	__asm__ __volatile__ ("rsm psr.up;;"::: "memory");
+
+	/*
+	 * Mark the PMU as not owned
+	 * This will cause the interrupt handler to do nothing in case an overflow
+	 * interrupt was in-flight
+	 * This also guarantees that pmc0 will contain the final state
+	 * It virtually gives us full control on overflow processing from that point
+	 * on.
+	 * It must be an atomic operation.
+	 */
+	SET_PMU_OWNER(NULL);
+
+	/*
+	 * read current overflow status:
+	 *
+	 * we are guaranteed to read the final stable state
+	 */
+	ia64_srlz_d();
+	pmc0 = ia64_get_pmc(0); /* slow */
+
+	/*
+	 * freeze PMU:
+	 *
+	 * This destroys the overflow information. This is required to make sure
+	 * next process does not start with monitoring on if not requested
+	 */
+	ia64_set_pmc(0, 1);
+	ia64_srlz_d();
+
+	/*
+	 * restore PSR for context switch to save
+	 */
+	__asm__ __volatile__ ("mov psr.l=%0;;srlz.i;"::"r"(psr): "memory");
+
 	/*
-	 * unfreeze PMU
+	 * This loop flushes the PMD into the PFM context.
+	 * IT also processes overflow inline.
+	 *
+	 * IMPORTANT: No notification is sent at this point as the process is dying.
+	 * The implicit notification will come from a SIGCHILD or a return from a
+	 * waitpid().
+	 *
+	 * XXX: must take holes into account
 	 */
-	ia64_set_pmc(0, 0);
+	mask = pmc0 >> PMU_FIRST_COUNTER;
+	for (i=0,j=PMU_FIRST_COUNTER; i< pmu_conf.max_counters; i++,j++) {
+
+		/* collect latest results */
+		ctx->ctx_pmds[i].val += ia64_get_pmd(j) & pmu_conf.perf_ovfl_val;
+
+		/* take care of overflow inline */
+		if (mask & 0x1) {
+			ctx->ctx_pmds[i].val += 1 + pmu_conf.perf_ovfl_val;
+			DBprintk((" PMD[%d] overflowed pmd=0x%lx pmds.val=0x%lx\n",
+			j, ia64_get_pmd(j), ctx->ctx_pmds[i].val));
+		}
+	}
+}
+
+/*
+ * XXX: this routine is not very portable for PMCs
+ * XXX: make this routine able to work with non current context
+ */
+static void
+ia64_reset_pmu(void)
+{
+	int i;
+
+	/* PMU is frozen, no pending overflow bits */
+	ia64_set_pmc(0,1);
+
+	/* extra overflow bits + counter configs cleared */
+	for(i=1; i< PMU_FIRST_COUNTER + pmu_conf.max_counters ; i++) {
+		ia64_set_pmc(i,0);
+	}
+
+	/* opcode matcher set to all 1s */
+	ia64_set_pmc(8,~0);
+	ia64_set_pmc(9,~0);
+
+	/* I-EAR config cleared, plm=0 */
+	ia64_set_pmc(10,0);
+
+	/* D-EAR config cleared, PMC[11].pt must be 1 */
+	ia64_set_pmc(11,1 << 28);
+
+	/* BTB config. plm=0 */
+	ia64_set_pmc(12,0);
+
+	/* Instruction address range, PMC[13].ta must be 1 */
+	ia64_set_pmc(13,1);
+
+	/* clears all PMD registers */
+	for(i=0;i< pmu_conf.num_pmds; i++) {
+		if (PMD_IS_IMPL(i)) ia64_set_pmd(i,0);
+	}
 	ia64_srlz_d();
 }
 
+/*
+ * task is the newly created task
+ */
+int
+pfm_inherit(struct task_struct *task)
+{
+	pfm_context_t *ctx = current->thread.pfm_context;
+	pfm_context_t *nctx;
+	struct thread_struct *th = &task->thread;
+	int i, cnum;
+
+	/*
+	 * takes care of easiest case first
+	 */
+	if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_NONE) {
+		DBprintk((" removing PFM context for %d\n", task->pid));
+		task->thread.pfm_context     = NULL;
+		task->thread.pfm_pend_notify = 0;
+		/* copy_thread() clears IA64_THREAD_PM_VALID */
+		return 0;
+	}
+	nctx = pfm_context_alloc();
+	if (nctx == NULL) return -ENOMEM;
+
+	/* copy content */
+	*nctx = *ctx;
+
+	if (ctx->ctx_fl_inherit == PFM_FL_INHERIT_ONCE) {
+		nctx->ctx_fl_inherit = PFM_FL_INHERIT_NONE;
+		DBprintk((" downgrading to INHERIT_NONE for %d\n", task->pid));
+	}
+
+	/* initialize counters in new context */
+	for(i=0, cnum= PMU_FIRST_COUNTER; i < pmu_conf.max_counters; cnum++, i++) {
+		nctx->ctx_pmds[i].val = nctx->ctx_pmds[i].ival & ~pmu_conf.perf_ovfl_val;
+		th->pmd[cnum]	      = nctx->ctx_pmds[i].ival & pmu_conf.perf_ovfl_val;
+
+	}
+	/* clear BTB index register */
+	th->pmd[16] = 0;
+
+	/* if sampling then increment number of users of buffer */
+	if (nctx->ctx_smpl_buf) {
+		atomic_inc(&nctx->ctx_smpl_buf->psb_refcnt);
+	}
+
+	nctx->ctx_fl_frozen = 0;
+	nctx->ctx_ovfl_regs = 0;
+	sema_init(&nctx->ctx_restart_sem, 0); /* reset this semaphore to locked */
+
+	/* clear pending notification */
+	th->pfm_pend_notify = 0;
+
+	/* link with new task */
+	th->pfm_context     = nctx;
+
+	DBprintk((" nctx=%p for process %d\n", (void *)nctx, task->pid));
+
+	/*
+	 * the copy_thread routine automatically clears
+	 * IA64_THREAD_PM_VALID, so we need to reenable it, if it was used by the caller
+	 */
+	if (current->thread.flags & IA64_THREAD_PM_VALID) {
+		DBprintk(("  setting PM_VALID for %d\n", task->pid));
+		th->flags |= IA64_THREAD_PM_VALID;
+	}
+
+	return 0;
+}
+
+/* called from exit_thread() */
+void
+pfm_context_exit(struct task_struct *task)
+{
+	pfm_context_t *ctx = task->thread.pfm_context;
+
+	if (!ctx) {
+		DBprintk((" invalid context for %d\n", task->pid));
+		return;
+	}
+
+	/* check is we have a sampling buffer attached */
+	if (ctx->ctx_smpl_buf) {
+		pfm_smpl_buffer_desc_t *psb = ctx->ctx_smpl_buf;
+
+		/* if only user left, then remove */
+		DBprintk((" pid %d: task %d sampling psb->refcnt=%d\n", current->pid, task->pid, psb->psb_refcnt.counter));
+
+		if (atomic_dec_and_test(&psb->psb_refcnt) ) {
+			rvfree(psb->psb_hdr, psb->psb_size);
+			vfree(psb);
+			DBprintk((" pid %d: cleaning task %d sampling buffer\n", current->pid, task->pid ));
+		}
+	}
+	DBprintk((" pid %d: task %d pfm_context is freed @%p\n", current->pid, task->pid, (void *)ctx));
+	pfm_context_free(ctx);
+}
+
 #else /* !CONFIG_PERFMON */
 
-asmlinkage unsigned long
-sys_perfmonctl (int cmd, int count, void *ptr)
+asmlinkage int
+sys_perfmonctl (int pid, int cmd, int flags, perfmon_req_t *req, int count, long arg6, long arg7, long arg8, long stack)
 {
 	return -ENOSYS;
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/process.c linux/arch/ia64/kernel/process.c
--- v2.4.3/linux/arch/ia64/kernel/process.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/process.c	Thu Apr  5 12:51:47 2001
@@ -1,8 +1,8 @@
 /*
  * Architecture-specific setup.
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #define __KERNEL_SYSCALLS__	/* see <asm/unistd.h> */
 #include <linux/config.h>
@@ -20,6 +20,7 @@
 
 #include <asm/delay.h>
 #include <asm/efi.h>
+#include <asm/perfmon.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/sal.h>
@@ -27,8 +28,6 @@
 #include <asm/unwind.h>
 #include <asm/user.h>
 
-#ifdef CONFIG_IA64_NEW_UNWIND
-
 static void
 do_show_stack (struct unw_frame_info *info, void *arg)
 {
@@ -46,12 +45,9 @@
 	} while (unw_unwind(info) >= 0);
 }
 
-#endif
-
 void
 show_stack (struct task_struct *task)
 {
-#ifdef CONFIG_IA64_NEW_UNWIND
 	if (!task)
 		unw_init_running(do_show_stack, 0);
 	else {
@@ -60,7 +56,6 @@
 		unw_init_from_blocked_task(&info, task);
 		do_show_stack(&info, 0);
 	}
-#endif
 }
 
 void
@@ -108,10 +103,8 @@
 			       ((i == sof - 1) || (i % 3) == 2) ? "\n" : " ");
 		}
 	}
-#ifdef CONFIG_IA64_NEW_UNWIND
 	if (!user_mode(regs))
 		show_stack(0);
-#endif
 }
 
 void __attribute__((noreturn))
@@ -147,7 +140,7 @@
 		ia64_save_debug_regs(&task->thread.dbr[0]);
 #ifdef CONFIG_PERFMON
 	if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
-		ia64_save_pm_regs(task);
+		pfm_save_regs(task);
 #endif
 	if (IS_IA32_PROCESS(ia64_task_regs(task)))
 		ia32_save_state(&task->thread);
@@ -160,7 +153,7 @@
 		ia64_load_debug_regs(&task->thread.dbr[0]);
 #ifdef CONFIG_PERFMON
 	if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
-		ia64_load_pm_regs(task);
+		pfm_load_regs(task);
 #endif
 	if (IS_IA32_PROCESS(ia64_task_regs(task)))
 		ia32_load_state(&task->thread);
@@ -210,6 +203,7 @@
 	struct switch_stack *child_stack, *stack;
 	extern char ia64_ret_from_clone;
 	struct pt_regs *child_ptregs;
+	int retval = 0;
 
 #ifdef CONFIG_SMP
 	/*
@@ -290,15 +284,17 @@
 	if (IS_IA32_PROCESS(ia64_task_regs(current)))
 		ia32_save_state(&p->thread);
 #endif
-	return 0;
+#ifdef CONFIG_PERFMON
+	if (current->thread.pfm_context)
+		retval = pfm_inherit(p);
+#endif
+	return retval;
 }
 
-#ifdef CONFIG_IA64_NEW_UNWIND
-
 void
 do_copy_regs (struct unw_frame_info *info, void *arg)
 {
-	unsigned long ar_bsp, ndirty, *krbs, addr, mask, sp, nat_bits = 0, ip;
+	unsigned long ar_bsp, addr, mask, sp, nat_bits = 0, ip, ar_rnat;
 	elf_greg_t *dst = arg;
 	struct pt_regs *pt;
 	char nat;
@@ -313,18 +309,18 @@
 	unw_get_sp(info, &sp);
 	pt = (struct pt_regs *) (sp + 16);
 
-	krbs = (unsigned long *) current + IA64_RBS_OFFSET/8;
-	ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19));
-	ar_bsp = (unsigned long) ia64_rse_skip_regs((long *) pt->ar_bspstore, ndirty);
+	ar_bsp = ia64_get_user_bsp(current, pt);
 
 	/*
-	 * Write portion of RSE backing store living on the kernel
-	 * stack to the VM of the process.
+	 * Write portion of RSE backing store living on the kernel stack to the VM of the
+	 * process.
 	 */
 	for (addr = pt->ar_bspstore; addr < ar_bsp; addr += 8)
-		if (ia64_peek(pt, current, addr, &val) == 0)
+		if (ia64_peek(current, ar_bsp, addr, &val) == 0)
 			access_process_vm(current, addr, &val, sizeof(val), 1);
 
+	ia64_peek(current, ar_bsp, (long) ia64_rse_rnat_addr((long *) addr - 1), &ar_rnat);
+
 	/*
 	 * coredump format:
 	 *	r0-r31
@@ -361,7 +357,7 @@
 	 */
 	dst[46] = ar_bsp;
 	dst[47] = pt->ar_bspstore;
-	unw_get_ar(info, UNW_AR_RNAT, &dst[48]);
+	dst[48] = ar_rnat;
 	unw_get_ar(info, UNW_AR_CCV, &dst[49]);
 	unw_get_ar(info, UNW_AR_UNAT, &dst[50]);
 	unw_get_ar(info, UNW_AR_FPSR, &dst[51]);
@@ -391,91 +387,16 @@
 		memcpy(dst + 32, current->thread.fph, 96*16);
 }
 
-#endif /* CONFIG_IA64_NEW_UNWIND */
-
 void
 ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst)
 {
-#ifdef CONFIG_IA64_NEW_UNWIND
 	unw_init_running(do_copy_regs, dst);
-#else
-	struct switch_stack *sw = ((struct switch_stack *) pt) - 1;
-	unsigned long ar_ec, cfm, ar_bsp, ndirty, *krbs, addr;
-
-	ar_ec = (sw->ar_pfs >> 52) & 0x3f;
-
-	cfm = pt->cr_ifs & ((1UL << 63) - 1);
-	if ((pt->cr_ifs & (1UL << 63)) == 0) {
-		/* if cr_ifs isn't valid, we got here through a syscall or a break */
-		cfm = sw->ar_pfs & ((1UL << 38) - 1);
-	}
-
-	krbs = (unsigned long *) current + IA64_RBS_OFFSET/8;
-	ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19));
-	ar_bsp = (unsigned long) ia64_rse_skip_regs((long *) pt->ar_bspstore, ndirty);
-
-	/*
-	 * Write portion of RSE backing store living on the kernel
-	 * stack to the VM of the process.
-	 */
-	for (addr = pt->ar_bspstore; addr < ar_bsp; addr += 8) {
-		long val;
-		if (ia64_peek(pt, current, addr, &val) == 0)
-			access_process_vm(current, addr, &val, sizeof(val), 1);
-	}
-
-	/*	r0-r31
-	 *	NaT bits (for r0-r31; bit N == 1 iff rN is a NaT)
-	 *	predicate registers (p0-p63)
-	 *	b0-b7
-	 *	ip cfm user-mask
-	 *	ar.rsc ar.bsp ar.bspstore ar.rnat
-	 *	ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec
-	 */
-	memset(dst, 0, sizeof(dst));	/* don't leak any "random" bits */
-
-	/* r0 is zero */   dst[ 1] =  pt->r1; dst[ 2] =  pt->r2; dst[ 3] = pt->r3;
-	dst[ 4] =  sw->r4; dst[ 5] =  sw->r5; dst[ 6] =  sw->r6; dst[ 7] = sw->r7;
-	dst[ 8] =  pt->r8; dst[ 9] =  pt->r9; dst[10] = pt->r10; dst[11] = pt->r11;
-	dst[12] = pt->r12; dst[13] = pt->r13; dst[14] = pt->r14; dst[15] = pt->r15;
-	memcpy(dst + 16, &pt->r16, 16*8);	/* r16-r31 are contiguous */
-
-	dst[32] = ia64_get_nat_bits(pt, sw);
-	dst[33] = pt->pr;
-
-	/* branch regs: */
-	dst[34] = pt->b0; dst[35] = sw->b1; dst[36] = sw->b2; dst[37] = sw->b3;
-	dst[38] = sw->b4; dst[39] = sw->b5; dst[40] = pt->b6; dst[41] = pt->b7;
-
-	dst[42] = pt->cr_iip + ia64_psr(pt)->ri;
-	dst[43] = pt->cr_ifs;
-	dst[44] = pt->cr_ipsr & IA64_PSR_UM;
-
-	dst[45] = pt->ar_rsc; dst[46] = ar_bsp; dst[47] = pt->ar_bspstore;  dst[48] = pt->ar_rnat;
-	dst[49] = pt->ar_ccv; dst[50] = pt->ar_unat; dst[51] = sw->ar_fpsr; dst[52] = pt->ar_pfs;
-	dst[53] = sw->ar_lc; dst[54] = (sw->ar_pfs >> 52) & 0x3f;
-#endif /* !CONFIG_IA64_NEW_UNWIND */
 }
 
 int
 dump_fpu (struct pt_regs *pt, elf_fpregset_t dst)
 {
-#ifdef CONFIG_IA64_NEW_UNWIND
 	unw_init_running(do_dump_fpu, dst);
-#else
-	struct switch_stack *sw = ((struct switch_stack *) pt) - 1;
-
-	memset(dst, 0, sizeof (dst));	/* don't leak any "random" bits */
-
-	/* f0 is 0.0 */  /* f1 is 1.0 */  dst[2] = sw->f2; dst[3] = sw->f3;
-	dst[4] = sw->f4; dst[5] = sw->f5; dst[6] = pt->f6; dst[7] = pt->f7;
-	dst[8] = pt->f8; dst[9] = pt->f9;
-	memcpy(dst + 10, &sw->f10, 22*16);	/* f10-f31 are contiguous */
-
-	ia64_flush_fph(current);
-	if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0)
-		memcpy(dst + 32, current->thread.fph, 96*16);
-#endif
 	return 1;	/* f0-f31 are always valid so we always return 1 */
 }
 
@@ -523,6 +444,15 @@
 #endif
 }
 
+#ifdef CONFIG_PERFMON
+void
+release_thread (struct task_struct *task)
+{
+	if (task->thread.pfm_context)
+		pfm_context_exit(task);
+}
+#endif
+
 /*
  * Clean up state associated with current thread.  This is called when
  * the thread calls exit().
@@ -545,7 +475,7 @@
 		 * we garantee no race.  this call we also stop
 		 * monitoring
 		 */
-		ia64_save_pm_regs(current);
+		pfm_flush_regs(current);
 		/*
 		 * make sure that switch_to() will not save context again
 		 */
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/ptrace.c linux/arch/ia64/kernel/ptrace.c
--- v2.4.3/linux/arch/ia64/kernel/ptrace.c	Tue Feb 13 14:13:43 2001
+++ linux/arch/ia64/kernel/ptrace.c	Thu Apr  5 12:51:47 2001
@@ -1,8 +1,8 @@
 /*
  * Kernel support for the ptrace() and syscall tracing interfaces.
  *
- * Copyright (C) 1999-2000 Hewlett-Packard Co
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2001 Hewlett-Packard Co
+ * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * Derived from the x86 and Alpha versions.  Most of the code in here
  * could actually be factored into a common set of routines.
@@ -22,6 +22,7 @@
 #include <asm/rse.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/unwind.h>
 
 /*
  * Bits in the PSR that we allow ptrace() to change:
@@ -36,8 +37,6 @@
 	(IA64_PSR_UM | IA64_PSR_DB | IA64_PSR_IS | IA64_PSR_ID | IA64_PSR_DD | IA64_PSR_RI)
 #define IPSR_READ_MASK	IPSR_WRITE_MASK
 
-#ifdef CONFIG_IA64_NEW_UNWIND
-
 #define PTRACE_DEBUG	1
 
 #if PTRACE_DEBUG
@@ -97,57 +96,6 @@
 #	undef PUT_BITS
 }
 
-#else /* !CONFIG_IA64_NEW_UNWIND */
-
-/*
- * Collect the NaT bits for r1-r31 from sw->caller_unat and
- * sw->ar_unat and return a NaT bitset where bit i is set iff the NaT
- * bit of register i is set.
- */
-long
-ia64_get_nat_bits (struct pt_regs *pt, struct switch_stack *sw)
-{
-#	define GET_BITS(str, first, last, unat)						\
-	({										\
-		unsigned long bit = ia64_unat_pos(&str->r##first);			\
-		unsigned long mask = ((1UL << (last - first + 1)) - 1) << first;	\
-		(ia64_rotl(unat, first) >> bit) & mask;					\
-	})
-	unsigned long val;
-
-	val  = GET_BITS(pt,  1,  3, sw->caller_unat);
-	val |= GET_BITS(pt, 12, 15, sw->caller_unat);
-	val |= GET_BITS(pt,  8, 11, sw->caller_unat);
-	val |= GET_BITS(pt, 16, 31, sw->caller_unat);
-	val |= GET_BITS(sw,  4,  7, sw->ar_unat);
-	return val;
-
-#	undef GET_BITS
-}
-
-/*
- * Store the NaT bitset NAT in pt->caller_unat and sw->ar_unat.
- */
-void
-ia64_put_nat_bits (struct pt_regs *pt, struct switch_stack *sw, unsigned long nat)
-{
-#	define PUT_BITS(str, first, last, nat)					\
-	({									\
-		unsigned long bit = ia64_unat_pos(&str->r##first);		\
-		unsigned long mask = ((1UL << (last - first + 1)) - 1) << bit;	\
-		(ia64_rotr(nat, first) << bit) & mask;				\
-	})
-	sw->caller_unat  = PUT_BITS(pt,  1,  3, nat);
-	sw->caller_unat |= PUT_BITS(pt, 12, 15, nat);
-	sw->caller_unat |= PUT_BITS(pt,  8, 11, nat);
-	sw->caller_unat |= PUT_BITS(pt, 16, 31, nat);
-	sw->ar_unat      = PUT_BITS(sw,  4,  7, nat);
-
-#	undef PUT_BITS
-}
-
-#endif /* !CONFIG_IA64_NEW_UNWIND */
-
 #define IA64_MLX_TEMPLATE	0x2
 #define IA64_MOVL_OPCODE	6
 
@@ -215,7 +163,7 @@
  * | slot01 | > child_regs->ar_rnat
  * +--------+ |
  * | slot02 | /				kernel rbs
- * +--------+ 				+--------+
+ * +--------+				+--------+
  *	    <- child_regs->ar_bspstore	| slot61 | <-- krbs
  * +- - - - +				+--------+
  *					| slot62 |
@@ -275,7 +223,7 @@
 		/* some bits need to be merged in from pt->ar_rnat */
 		kmask = ~((1UL << ia64_rse_slot_num(ubspstore)) - 1);
 		urnat = (pt->ar_rnat & ~kmask);
-	} 
+	}
 	if (rnat0_kaddr >= kbsp) {
 		rnat0 = sw->ar_rnat;
 	} else if (rnat0_kaddr > krbs) {
@@ -319,7 +267,7 @@
 		/* 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);
-	} 
+	}
 	/*
 	 * 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.
@@ -342,9 +290,9 @@
 }
 
 long
-ia64_peek (struct pt_regs *regs, struct task_struct *child, unsigned long addr, long *val)
+ia64_peek (struct task_struct *child, unsigned long user_bsp, unsigned long addr, long *val)
 {
-	unsigned long *bspstore, *krbs, krbs_num_regs, regnum, *rbs_end, *laddr;
+	unsigned long *bspstore, *krbs, regnum, *laddr, *ubsp = (long *) user_bsp;
 	struct switch_stack *child_stack;
 	struct pt_regs *child_regs;
 	size_t copied;
@@ -352,35 +300,22 @@
 
 	laddr = (unsigned long *) addr;
 	child_regs = ia64_task_regs(child);
-#ifdef CONFIG_IA64_NEW_UNWIND
 	child_stack = (struct switch_stack *) (child->thread.ksp + 16);
-#else
-	child_stack = (struct switch_stack *) child_regs - 1;
-#endif
 	bspstore = (unsigned long *) child_regs->ar_bspstore;
 	krbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
-	krbs_num_regs = ia64_rse_num_regs(krbs, (unsigned long *) child_stack->ar_bspstore);
-	rbs_end = ia64_rse_skip_regs(bspstore, krbs_num_regs);
-	if (laddr >= bspstore && laddr <= ia64_rse_rnat_addr(rbs_end)) {
+	if (laddr >= bspstore && laddr <= ia64_rse_rnat_addr(ubsp)) {
 		/*
-		 * Attempt to read the RBS in an area that's actually
-		 * on the kernel RBS => read the corresponding bits in
-		 * the kernel RBS.
+		 * Attempt to read the RBS in an area that's actually on the kernel RBS =>
+		 * read the corresponding bits in the kernel RBS.
 		 */
 		if (ia64_rse_is_rnat_slot(laddr))
 			ret = get_rnat(child_regs, child_stack, krbs, laddr);
 		else {
-			regnum = ia64_rse_num_regs(bspstore, laddr);
-			laddr = ia64_rse_skip_regs(krbs, regnum);
-			if (regnum >= krbs_num_regs) {
+			if (laddr >= ubsp)
 				ret = 0;
-			} else {
-				if  ((unsigned long) laddr >= (unsigned long) high_memory) {
-					printk("yikes: trying to access long at %p\n",
-					       (void *) laddr);
-					return -EIO;
-				}
-				ret = *laddr;
+			else {
+				regnum = ia64_rse_num_regs(bspstore, laddr);
+				ret = *ia64_rse_skip_regs(krbs, regnum);
 			}
 		}
 	} else {
@@ -393,36 +328,28 @@
 }
 
 long
-ia64_poke (struct pt_regs *regs, struct task_struct *child, unsigned long addr, long val)
+ia64_poke (struct task_struct *child, unsigned long user_bsp, unsigned long addr, long val)
 {
-	unsigned long *bspstore, *krbs, krbs_num_regs, regnum, *rbs_end, *laddr;
+	unsigned long *bspstore, *krbs, regnum, *laddr, *ubsp = (long *) user_bsp;
 	struct switch_stack *child_stack;
 	struct pt_regs *child_regs;
 
 	laddr = (unsigned long *) addr;
 	child_regs = ia64_task_regs(child);
-#ifdef CONFIG_IA64_NEW_UNWIND
 	child_stack = (struct switch_stack *) (child->thread.ksp + 16);
-#else
-	child_stack = (struct switch_stack *) child_regs - 1;
-#endif
 	bspstore = (unsigned long *) child_regs->ar_bspstore;
 	krbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
-	krbs_num_regs = ia64_rse_num_regs(krbs, (unsigned long *) child_stack->ar_bspstore);
-	rbs_end = ia64_rse_skip_regs(bspstore, krbs_num_regs);
-	if (laddr >= bspstore && laddr <= ia64_rse_rnat_addr(rbs_end)) {
+	if (laddr >= bspstore && laddr <= ia64_rse_rnat_addr(ubsp)) {
 		/*
-		 * Attempt to write the RBS in an area that's actually
-		 * on the kernel RBS => write the corresponding bits
-		 * in the kernel RBS.
+		 * Attempt to write the RBS in an area that's actually on the kernel RBS
+		 * => write the corresponding bits in the kernel RBS.
 		 */
 		if (ia64_rse_is_rnat_slot(laddr))
 			put_rnat(child_regs, child_stack, krbs, laddr, val);
 		else {
-			regnum = ia64_rse_num_regs(bspstore, laddr);
-			laddr = ia64_rse_skip_regs(krbs, regnum);
-			if (regnum < krbs_num_regs) {
-				*laddr = val;
+			if (laddr < ubsp) {
+				regnum = ia64_rse_num_regs(bspstore, laddr);
+				*ia64_rse_skip_regs(krbs, regnum) = val;
 			}
 		}
 	} else if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val)) {
@@ -432,83 +359,76 @@
 }
 
 /*
- * Synchronize (i.e, write) the RSE backing store living in kernel
- * space to the VM of the indicated child process.
- *
- * If new_bsp is non-zero, the bsp will (effectively) be updated to
- * the new value upon resumption of the child process.  This is
- * accomplished by setting the loadrs value to zero and the bspstore
- * value to the new bsp value.
- *
- * When new_bsp and force_loadrs_to_zero are both 0, the register
- * backing store in kernel space is written to user space and the
- * loadrs and bspstore values are left alone.
- *
- * When new_bsp is zero and force_loadrs_to_zero is 1 (non-zero),
- * loadrs is set to 0, and the bspstore value is set to the old bsp
- * value.  This will cause the stacked registers (r32 and up) to be
- * obtained entirely from the child's memory space rather than
- * from the kernel.  (This makes it easier to write code for
- * modifying the stacked registers in multi-threaded programs.)
- *
- * Note:  I had originally written this function without the
- * force_loadrs_to_zero parameter; it was written so that loadrs would
- * always be set to zero.  But I had problems with certain system
- * calls apparently causing a portion of the RBS to be zeroed.  (I
- * still don't understand why this was happening.) Anyway, it'd
- * definitely less intrusive to leave loadrs and bspstore alone if
- * possible.
+ * Calculate the user-level address that would have been in ar.bsp had the user executed a
+ * "cover" instruction right before entering the kernel.
  */
-static long
-sync_kernel_register_backing_store (struct task_struct *child,
-                                    long new_bsp,
-                                    int force_loadrs_to_zero)
+unsigned long
+ia64_get_user_bsp (struct task_struct *child, struct pt_regs *pt)
 {
-	unsigned long *krbs, bspstore, *kbspstore, bsp, rbs_end, addr, val;
-	long ndirty, ret = 0;
-	struct pt_regs *child_regs = ia64_task_regs(child);
-
-#ifdef CONFIG_IA64_NEW_UNWIND
+	unsigned long *krbs, *bspstore, cfm;
 	struct unw_frame_info info;
-	unsigned long cfm, sof;
-
-	unw_init_from_blocked_task(&info, child);
-	if (unw_unwind_to_user(&info) < 0)
-		return -1;
-
-	unw_get_bsp(&info, (unsigned long *) &kbspstore);
+	long ndirty;
 
 	krbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
-	ndirty = ia64_rse_num_regs(krbs, krbs + (child_regs->loadrs >> 19));
-	bspstore = child_regs->ar_bspstore;
-	bsp = (long) ia64_rse_skip_regs((long *)bspstore, ndirty);
-
-	cfm = child_regs->cr_ifs;
-	if (!(cfm & (1UL << 63)))
-		unw_get_cfm(&info, &cfm);
-	sof = (cfm & 0x7f);
-	rbs_end = (long) ia64_rse_skip_regs((long *)bspstore, sof);
-#else
-	struct switch_stack *child_stack;
-	unsigned long krbs_num_regs;
+	bspstore = (unsigned long *) pt->ar_bspstore;
+	ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19));
 
-	child_stack = (struct switch_stack *) child_regs - 1;
-	kbspstore = (unsigned long *) child_stack->ar_bspstore;
-	krbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
-	ndirty = ia64_rse_num_regs(krbs, krbs + (child_regs->loadrs >> 19));
-	bspstore = child_regs->ar_bspstore;
-	bsp = (long) ia64_rse_skip_regs((long *)bspstore, ndirty);
-	krbs_num_regs = ia64_rse_num_regs(krbs, kbspstore);
-	rbs_end = (long) ia64_rse_skip_regs((long *)bspstore, krbs_num_regs);
-#endif
+	if ((long) pt->cr_ifs >= 0) {
+		/*
+		 * If bit 63 of cr.ifs is cleared, the kernel was entered via a system
+		 * call and we need to recover the CFM that existed on entry to the
+		 * kernel by unwinding the kernel stack.
+		 */
+		unw_init_from_blocked_task(&info, child);
+		if (unw_unwind_to_user(&info) == 0) {
+			unw_get_cfm(&info, &cfm);
+			ndirty += (cfm & 0x7f);
+		}
+	}
+	return (unsigned long) ia64_rse_skip_regs(bspstore, ndirty);
+}
 
-	/* Return early if nothing to do */
-	if (bsp == new_bsp)
+/*
+ * Synchronize (i.e, write) the RSE backing store living in kernel space to the VM of the
+ * indicated child process.
+ *
+ * If new_bsp is non-zero, the bsp will (effectively) be updated to the new value upon
+ * resumption of the child process.  This is accomplished by setting the loadrs value to
+ * zero and the bspstore value to the new bsp value.
+ *
+ * When new_bsp and flush_user_rbs are both 0, the register backing store in kernel space
+ * is written to user space and the loadrs and bspstore values are left alone.
+ *
+ * When new_bsp is zero and flush_user_rbs is 1 (non-zero), loadrs is set to 0, and the
+ * bspstore value is set to the old bsp value.  This will cause the stacked registers (r32
+ * and up) to be obtained entirely from the child's memory space rather than from the
+ * kernel.  (This makes it easier to write code for modifying the stacked registers in
+ * multi-threaded programs.)
+ *
+ * Note: I had originally written this function without the flush_user_rbs parameter; it
+ * was written so that loadrs would always be set to zero.  But I had problems with
+ * certain system calls apparently causing a portion of the RBS to be zeroed.  (I still
+ * don't understand why this was happening.) Anyway, it'd definitely less intrusive to
+ * leave loadrs and bspstore alone if possible.
+ */
+static long
+sync_kernel_register_backing_store (struct task_struct *child, long user_bsp, long new_bsp,
+				    int flush_user_rbs)
+{
+	struct pt_regs *child_regs = ia64_task_regs(child);
+	unsigned long addr, val;
+	long ret;
+
+	/*
+	 * Return early if nothing to do.  Note that new_bsp will be zero if the caller
+	 * wants to force synchronization without changing bsp.
+	 */
+	if (user_bsp == new_bsp)
 		return 0;
 
 	/* Write portion of backing store living on kernel stack to the child's VM. */
-	for (addr = bspstore; addr < rbs_end; addr += 8) {
-		ret = ia64_peek(child_regs, child, addr, &val);
+	for (addr = child_regs->ar_bspstore; addr < user_bsp; addr += 8) {
+		ret = ia64_peek(child, user_bsp, addr, &val);
 		if (ret != 0)
 			return ret;
 		if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
@@ -516,27 +436,26 @@
 	}
 
 	if (new_bsp != 0) {
-		force_loadrs_to_zero = 1;
-		bsp = new_bsp;
+		flush_user_rbs = 1;
+		user_bsp = new_bsp;
 	}
 
-	if (force_loadrs_to_zero) {
+	if (flush_user_rbs) {
 		child_regs->loadrs = 0;
-		child_regs->ar_bspstore = bsp;
+		child_regs->ar_bspstore = user_bsp;
 	}
-
-	return ret;
+	return 0;
 }
 
 static void
-sync_thread_rbs (struct task_struct *child, struct mm_struct *mm, int make_writable)
+sync_thread_rbs (struct task_struct *child, long bsp, struct mm_struct *mm, int make_writable)
 {
 	struct task_struct *p;
 	read_lock(&tasklist_lock);
 	{
 		for_each_task(p) {
 			if (p->mm == mm && p->state != TASK_RUNNING)
-				sync_kernel_register_backing_store(p, 0, make_writable);
+				sync_kernel_register_backing_store(p, bsp, 0, make_writable);
 		}
 	}
 	read_unlock(&tasklist_lock);
@@ -588,10 +507,6 @@
 	psr->dfh = 1;
 }
 
-#ifdef CONFIG_IA64_NEW_UNWIND
-
-#include <asm/unwind.h>
-
 static int
 access_fr (struct unw_frame_info *info, int regnum, int hi, unsigned long *data, int write_access)
 {
@@ -613,7 +528,7 @@
 static int
 access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data, int write_access)
 {
-	unsigned long *ptr, *rbs, *bspstore, ndirty, regnum;
+	unsigned long *ptr, regnum, bsp, rnat_addr;
 	struct switch_stack *sw;
 	struct unw_frame_info info;
 	struct pt_regs *pt;
@@ -710,36 +625,16 @@
 		/* scratch state */
 		switch (addr) {
 		      case PT_AR_BSP:
+			bsp = ia64_get_user_bsp(child, pt);
 			if (write_access)
-				/* FIXME? Account for lack of ``cover'' in the syscall case */
-				return sync_kernel_register_backing_store(child, *data, 1);
+				return sync_kernel_register_backing_store(child, bsp, *data, 1);
 			else {
-				rbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
-				bspstore = (unsigned long *) pt->ar_bspstore;
-				ndirty = ia64_rse_num_regs(rbs, rbs + (pt->loadrs >> 19));
-
-				/*
-				 * If we're in a system call, no ``cover'' was done.  So to
-				 * make things uniform, we'll add the appropriate displacement
-				 * onto bsp if we're in a system call.
-				 */
-				if (!(pt->cr_ifs & (1UL << 63))) {
-					struct unw_frame_info info;
-					unsigned long cfm;
-
-					unw_init_from_blocked_task(&info, child);
-					if (unw_unwind_to_user(&info) < 0)
-						return -1;
-
-					unw_get_cfm(&info, &cfm);
-					ndirty += cfm & 0x7f;
-				}
-				*data = (unsigned long) ia64_rse_skip_regs(bspstore, ndirty);
+				*data = bsp;
 				return 0;
 			}
 
 		      case PT_CFM:
-			if (pt->cr_ifs & (1UL << 63)) {
+			if ((long) pt->cr_ifs < 0) {
 				if (write_access)
 					pt->cr_ifs = ((pt->cr_ifs & ~0x3fffffffffUL)
 						      | (*data & 0x3fffffffffUL));
@@ -770,7 +665,15 @@
 				*data = (pt->cr_ipsr & IPSR_READ_MASK);
 			return 0;
 
-		      		   case PT_R1:  case PT_R2:  case PT_R3:
+		      case PT_AR_RNAT:
+			bsp = ia64_get_user_bsp(child, pt);
+			rnat_addr = (long) ia64_rse_rnat_addr((long *) bsp - 1);
+			if (write_access)
+				return ia64_poke(child, bsp, rnat_addr, *data);
+			else
+				return ia64_peek(child, bsp, rnat_addr, data);
+
+				   case PT_R1:  case PT_R2:  case PT_R3:
 		      case PT_R8:  case PT_R9:  case PT_R10: case PT_R11:
 		      case PT_R12: case PT_R13: case PT_R14: case PT_R15:
 		      case PT_R16: case PT_R17: case PT_R18: case PT_R19:
@@ -781,7 +684,7 @@
 		      case PT_F6:  case PT_F6+8: case PT_F7: case PT_F7+8:
 		      case PT_F8:  case PT_F8+8: case PT_F9: case PT_F9+8:
 		      case PT_AR_BSPSTORE:
-		      case PT_AR_RSC: case PT_AR_UNAT: case PT_AR_PFS: case PT_AR_RNAT:
+		      case PT_AR_RSC: case PT_AR_UNAT: case PT_AR_PFS:
 		      case PT_AR_CCV: case PT_AR_FPSR: case PT_CR_IIP: case PT_PR:
 			/* scratch register */
 			ptr = (unsigned long *) ((long) pt + addr - PT_CR_IPSR);
@@ -799,7 +702,7 @@
 		if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
 			child->thread.flags |= IA64_THREAD_DBG_VALID;
 			memset(child->thread.dbr, 0, sizeof(child->thread.dbr));
-			memset(child->thread.ibr, 0, sizeof( child->thread.ibr));
+			memset(child->thread.ibr, 0, sizeof(child->thread.ibr));
 		}
 		if (addr >= PT_IBR) {
 			regnum = (addr - PT_IBR) >> 3;
@@ -830,173 +733,13 @@
 	return 0;
 }
 
-#else /* !CONFIG_IA64_NEW_UNWIND */
-
-static int
-access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data, int write_access)
-{
-	unsigned long *ptr = NULL, *rbs, *bspstore, ndirty, regnum;
-	struct switch_stack *sw;
-	struct pt_regs *pt;
-
-	if ((addr & 0x7) != 0)
-		return -1;
-
-	if (addr < PT_F127+16) {
-		/* accessing fph */
-		if (write_access)
-			ia64_sync_fph(child);
-		else
-			ia64_flush_fph(child);
-		ptr = (unsigned long *) ((unsigned long) &child->thread.fph + addr);
-	} else if (addr < PT_F9+16) {
-		/* accessing switch_stack or pt_regs: */
-		pt = ia64_task_regs(child);
-		sw = (struct switch_stack *) pt - 1;
-
-		switch (addr) {
-		      case PT_NAT_BITS:
-			if (write_access)
-				ia64_put_nat_bits(pt, sw, *data);
-			else
-				*data = ia64_get_nat_bits(pt, sw);
-			return 0;
-
-		      case PT_AR_BSP:
-			if (write_access)
-				/* FIXME? Account for lack of ``cover'' in the syscall case */
-				return sync_kernel_register_backing_store(child, *data, 1);
-			else {
-				rbs = (unsigned long *) child + IA64_RBS_OFFSET/8;
-				bspstore = (unsigned long *) pt->ar_bspstore;
-				ndirty = ia64_rse_num_regs(rbs, rbs + (pt->loadrs >> 19));
-
-				/*
-				 * If we're in a system call, no ``cover'' was done.  So to
-				 * make things uniform, we'll add the appropriate displacement
-				 * onto bsp if we're in a system call.
-				 */
-				if (!(pt->cr_ifs & (1UL << 63)))
-					ndirty += sw->ar_pfs & 0x7f;
-				*data = (unsigned long) ia64_rse_skip_regs(bspstore, ndirty);
-				return 0;
-			}
-
-		      case PT_CFM:
-			if (write_access) {
-				if (pt->cr_ifs & (1UL << 63))
-					pt->cr_ifs = ((pt->cr_ifs & ~0x3fffffffffUL)
-						      | (*data & 0x3fffffffffUL));
-				else
-					sw->ar_pfs = ((sw->ar_pfs & ~0x3fffffffffUL)
-						      | (*data & 0x3fffffffffUL));
-				return 0;
-			} else {
-				if ((pt->cr_ifs & (1UL << 63)) == 0)
-					*data = sw->ar_pfs;
-				else
-					/* return only the CFM */
-					*data = pt->cr_ifs & 0x3fffffffffUL;
-				return 0;
-			}
-
-		      case PT_CR_IPSR:
-			if (write_access)
-				pt->cr_ipsr = ((*data & IPSR_WRITE_MASK)
-					       | (pt->cr_ipsr & ~IPSR_WRITE_MASK));
-			else
-				*data = (pt->cr_ipsr & IPSR_READ_MASK);
-			return 0;
-
-		      case PT_AR_EC:
-			if (write_access)
-				sw->ar_pfs = (((*data & 0x3f) << 52)
-					      | (sw->ar_pfs & ~(0x3fUL << 52)));
-			else
-				*data = (sw->ar_pfs >> 52) & 0x3f;
-			break;
-
-		      case PT_R1: case PT_R2: case PT_R3:
-		      case PT_R4: case PT_R5: case PT_R6: case PT_R7:
-		      case PT_R8: case PT_R9: case PT_R10: case PT_R11:
-		      case PT_R12: case PT_R13: case PT_R14: case PT_R15:
-		      case PT_R16: case PT_R17: case PT_R18: case PT_R19:
-		      case PT_R20: case PT_R21: case PT_R22: case PT_R23:
-		      case PT_R24: case PT_R25: case PT_R26: case PT_R27:
-		      case PT_R28: case PT_R29: case PT_R30: case PT_R31:
-		      case PT_B0: case PT_B1: case PT_B2: case PT_B3:
-		      case PT_B4: case PT_B5: case PT_B6: case PT_B7:
-		      case PT_F2: case PT_F2+8: case PT_F3: case PT_F3+8:
-		      case PT_F4: case PT_F4+8: case PT_F5: case PT_F5+8:
-		      case PT_F6: case PT_F6+8: case PT_F7: case PT_F7+8:
-  		      case PT_F8: case PT_F8+8: case PT_F9: case PT_F9+8:
-		      case PT_F10: case PT_F10+8: case PT_F11: case PT_F11+8:
-		      case PT_F12: case PT_F12+8: case PT_F13: case PT_F13+8:
-		      case PT_F14: case PT_F14+8: case PT_F15: case PT_F15+8:
-		      case PT_F16: case PT_F16+8: case PT_F17: case PT_F17+8:
-		      case PT_F18: case PT_F18+8: case PT_F19: case PT_F19+8:
-  		      case PT_F20: case PT_F20+8: case PT_F21: case PT_F21+8:
-		      case PT_F22: case PT_F22+8: case PT_F23: case PT_F23+8: 
-		      case PT_F24: case PT_F24+8: case PT_F25: case PT_F25+8:
-		      case PT_F26: case PT_F26+8: case PT_F27: case PT_F27+8:
- 		      case PT_F28: case PT_F28+8: case PT_F29: case PT_F29+8:
-		      case PT_F30: case PT_F30+8: case PT_F31: case PT_F31+8:
-		      case PT_AR_BSPSTORE:
-		      case PT_AR_RSC: case PT_AR_UNAT: case PT_AR_PFS: case PT_AR_RNAT:
-		      case PT_AR_CCV: case PT_AR_FPSR: case PT_CR_IIP: case PT_PR:
-		      case PT_AR_LC:
-			ptr = (unsigned long *) ((long) sw + addr - PT_NAT_BITS);
-			break;
-
-		      default:
-			/* disallow accessing anything else... */
-			return -1;
-		}
-	} else {
-
-		/* access debug registers */
-
-		if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
-			child->thread.flags |= IA64_THREAD_DBG_VALID;
-			memset(child->thread.dbr, 0, sizeof child->thread.dbr);
-			memset(child->thread.ibr, 0, sizeof child->thread.ibr);
-		}
-		if (addr >= PT_IBR) {
-			regnum = (addr - PT_IBR) >> 3;
-			ptr = &child->thread.ibr[0];
-		} else {
-			regnum = (addr - PT_DBR) >> 3;
-			ptr = &child->thread.dbr[0];
-		}
-
-		if (regnum >= 8)
-			return -1;
-
-		ptr += regnum;
-
-		if (write_access)
-			/* don't let the user set kernel-level breakpoints... */
-			*ptr = *data & ~(7UL << 56);
-		else
-			*data = *ptr;
-		return 0;
-	}
-	if (write_access)
-		*ptr = *data;
-	else
-		*data = *ptr;
-	return 0;
-}
-
-#endif /* !CONFIG_IA64_NEW_UNWIND */
-
 asmlinkage long
 sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
 	    long arg4, long arg5, long arg6, long arg7, long stack)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
+	struct pt_regs *pt, *regs = (struct pt_regs *) &stack;
 	struct task_struct *child;
-	unsigned long flags;
+	unsigned long flags, bsp;
 	long ret;
 
 	lock_kernel();
@@ -1031,10 +774,10 @@
 		    (current->uid != child->euid) ||
 		    (current->uid != child->suid) ||
 		    (current->uid != child->uid) ||
-	 	    (current->gid != child->egid) ||
-	 	    (current->gid != child->sgid) ||
-	 	    (!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
-	 	    (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
+		    (current->gid != child->egid) ||
+		    (current->gid != child->sgid) ||
+		    (!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
+		    (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
 			goto out_tsk;
 		/* the same process cannot be attached many times */
 		if (child->ptrace & PT_PTRACED)
@@ -1065,10 +808,13 @@
 	if (child->p_pptr != current)
 		goto out_tsk;
 
+	pt = ia64_task_regs(child);
+
 	switch (request) {
 	      case PTRACE_PEEKTEXT:
 	      case PTRACE_PEEKDATA:		/* read word at location addr */
-	        if (!(child->thread.flags & IA64_THREAD_KRBS_SYNCED)) {
+		bsp = ia64_get_user_bsp(child, pt);
+		if (!(child->thread.flags & IA64_THREAD_KRBS_SYNCED)) {
 			struct mm_struct *mm;
 			long do_sync;
 
@@ -1079,9 +825,9 @@
 			}
 			task_unlock(child);
 			if (do_sync)
-				sync_thread_rbs(child, mm, 0);
+				sync_thread_rbs(child, bsp, mm, 0);
 		}
-		ret = ia64_peek(regs, child, addr, &data);
+		ret = ia64_peek(child, bsp, addr, &data);
 		if (ret == 0) {
 			ret = data;
 			regs->r8 = 0;	/* ensure "ret" is not mistaken as an error code */
@@ -1090,7 +836,8 @@
 
 	      case PTRACE_POKETEXT:
 	      case PTRACE_POKEDATA:		/* write the word at location addr */
-	        if (!(child->thread.flags & IA64_THREAD_KRBS_SYNCED)) {
+		bsp = ia64_get_user_bsp(child, pt);
+		if (!(child->thread.flags & IA64_THREAD_KRBS_SYNCED)) {
 			struct mm_struct *mm;
 			long do_sync;
 
@@ -1101,9 +848,9 @@
 			}
 			task_unlock(child);
 			if (do_sync)
-				sync_thread_rbs(child, mm, 1);
+				sync_thread_rbs(child, bsp, mm, 1);
 		}
-		ret = ia64_poke(regs, child, addr, data);
+		ret = ia64_poke(child, bsp, addr, data);
 		goto out_tsk;
 
 	      case PTRACE_PEEKUSR:		/* read the word at addr in the USER area */
@@ -1125,21 +872,19 @@
 
 	      case PTRACE_GETSIGINFO:
 		ret = -EIO;
-		if (!access_ok(VERIFY_WRITE, data, sizeof (siginfo_t))
-		    || child->thread.siginfo == 0)
+		if (!access_ok(VERIFY_WRITE, data, sizeof (siginfo_t)) || !child->thread.siginfo)
 			goto out_tsk;
-		copy_to_user((siginfo_t *) data, child->thread.siginfo, sizeof (siginfo_t));
-		ret = 0;
+		ret = copy_siginfo_to_user((siginfo_t *) data, child->thread.siginfo);
 		goto out_tsk;
-		break;
+
 	      case PTRACE_SETSIGINFO:
 		ret = -EIO;
 		if (!access_ok(VERIFY_READ, data, sizeof (siginfo_t))
 		    || child->thread.siginfo == 0)
 			goto out_tsk;
-		copy_from_user(child->thread.siginfo, (siginfo_t *) data, sizeof (siginfo_t));
-		ret = 0;
+		ret = copy_siginfo_from_user(child->thread.siginfo, (siginfo_t *) data);
 		goto out_tsk;
+
 	      case PTRACE_SYSCALL:	/* continue and stop at next (return from) syscall */
 	      case PTRACE_CONT:		/* restart after signal. */
 		ret = -EIO;
@@ -1152,8 +897,8 @@
 		child->exit_code = data;
 
 		/* make sure the single step/take-branch tra bits are not set: */
-		ia64_psr(ia64_task_regs(child))->ss = 0;
-		ia64_psr(ia64_task_regs(child))->tb = 0;
+		ia64_psr(pt)->ss = 0;
+		ia64_psr(pt)->tb = 0;
 
 		/* Turn off flag indicating that the KRBS is sync'd with child's VM: */
 		child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED;
@@ -1173,8 +918,8 @@
 		child->exit_code = SIGKILL;
 
 		/* make sure the single step/take-branch tra bits are not set: */
-		ia64_psr(ia64_task_regs(child))->ss = 0;
-		ia64_psr(ia64_task_regs(child))->tb = 0;
+		ia64_psr(pt)->ss = 0;
+		ia64_psr(pt)->tb = 0;
 
 		/* Turn off flag indicating that the KRBS is sync'd with child's VM: */
 		child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED;
@@ -1191,9 +936,9 @@
 
 		child->ptrace &= ~PT_TRACESYS;
 		if (request == PTRACE_SINGLESTEP) {
-			ia64_psr(ia64_task_regs(child))->ss = 1;
+			ia64_psr(pt)->ss = 1;
 		} else {
-			ia64_psr(ia64_task_regs(child))->tb = 1;
+			ia64_psr(pt)->tb = 1;
 		}
 		child->exit_code = data;
 
@@ -1219,8 +964,8 @@
 		write_unlock_irqrestore(&tasklist_lock, flags);
 
 		/* make sure the single step/take-branch tra bits are not set: */
-		ia64_psr(ia64_task_regs(child))->ss = 0;
-		ia64_psr(ia64_task_regs(child))->tb = 0;
+		ia64_psr(pt)->ss = 0;
+		ia64_psr(pt)->tb = 0;
 
 		/* Turn off flag indicating that the KRBS is sync'd with child's VM: */
 		child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED;
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/setup.c linux/arch/ia64/kernel/setup.c
--- v2.4.3/linux/arch/ia64/kernel/setup.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/setup.c	Thu Apr  5 12:51:47 2001
@@ -1,8 +1,8 @@
 /*
  * Architecture-specific setup.
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1998, 1999 Stephane Eranian <eranian@hpl.hp.com>
  * Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
  * Copyright (C) 1999 VA Linux Systems
@@ -42,16 +42,20 @@
 # include <linux/blk.h>
 #endif
 
+#if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
+# error "struct cpuinfo_ia64 too big!"
+#endif
+
 extern char _end;
 
 /* cpu_data[0] is data for the bootstrap processor: */
-struct cpuinfo_ia64 cpu_data[NR_CPUS];
+struct cpuinfo_ia64 cpu_data[NR_CPUS] __attribute__ ((section ("__special_page_section")));
 
 unsigned long ia64_cycles_per_usec;
-struct ia64_boot_param ia64_boot_param;
+struct ia64_boot_param *ia64_boot_param;
 struct screen_info screen_info;
 /* This tells _start which CPU is booting.  */
-int cpu_now_booting = 0;
+int cpu_now_booting;
 
 #ifdef CONFIG_SMP
 volatile unsigned long cpu_online_map;
@@ -119,14 +123,7 @@
 
 	unw_init();
 
-	/*
-	 * The secondary bootstrap loader passes us the boot
-	 * parameters at the beginning of the ZERO_PAGE, so let's
-	 * stash away those values before ZERO_PAGE gets cleared out.
-	 */
-	memcpy(&ia64_boot_param, (void *) ZERO_PAGE_ADDR, sizeof(ia64_boot_param));
-
-	*cmdline_p = __va(ia64_boot_param.command_line);
+	*cmdline_p = __va(ia64_boot_param->command_line);
 	strncpy(saved_command_line, *cmdline_p, sizeof(saved_command_line));
 	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';		/* for safety */
 
@@ -140,9 +137,8 @@
 	 * change APIs, they'd do things for the better.  Grumble...
 	 */
 	bootmap_start = PAGE_ALIGN(__pa(&_end));
-	if (ia64_boot_param.initrd_size)
-		bootmap_start = PAGE_ALIGN(bootmap_start
-					   + ia64_boot_param.initrd_size);
+	if (ia64_boot_param->initrd_size)
+		bootmap_start = PAGE_ALIGN(bootmap_start + ia64_boot_param->initrd_size);
 	bootmap_size = init_bootmem(bootmap_start >> PAGE_SHIFT, max_pfn);
 
 	efi_memmap_walk(free_available_memory, 0);
@@ -150,7 +146,7 @@
 	reserve_bootmem(bootmap_start, bootmap_size);
 
 #ifdef CONFIG_BLK_DEV_INITRD
-	initrd_start = ia64_boot_param.initrd_start;
+	initrd_start = ia64_boot_param->initrd_start;
 
 	if (initrd_start) {
 		u64 start, size;
@@ -163,16 +159,16 @@
 			       "for initrd, please upgrade the loader\n");
 		else
 #endif
-			/* 
+			/*
 			 * The loader ONLY passes physical addresses
 			 */
 			initrd_start = (unsigned long)__va(initrd_start);
-		initrd_end = initrd_start+ia64_boot_param.initrd_size;
+		initrd_end = initrd_start+ia64_boot_param->initrd_size;
 		start      = initrd_start;
-		size       = ia64_boot_param.initrd_size;
+		size       = ia64_boot_param->initrd_size;
 
 		printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
-		       (void *) initrd_start, ia64_boot_param.initrd_size);
+		       (void *) initrd_start, ia64_boot_param->initrd_size);
 
 		/*
 		 * The kernel end and the beginning of initrd can be
@@ -218,19 +214,19 @@
 	/* process SAL system table: */
 	ia64_sal_init(efi.sal_systab);
 
-#ifdef CONFIG_SMP
-	current->processor = 0;
-	cpu_physical_id(0) = hard_smp_processor_id();
-#endif
 	/*
 	 *  Set `iobase' to the appropriate address in region 6
 	 *    (uncached access range)
 	 */
-	__asm__ ("mov %0=ar.k0;;" : "=r"(ia64_iobase));
+	ia64_iobase = ia64_get_kr(IA64_KR_IO_BASE);
 	ia64_iobase = __IA64_UNCACHED_OFFSET | (ia64_iobase & ~PAGE_OFFSET);
 
 	cpu_init();	/* initialize the bootstrap CPU */
 
+#ifdef CONFIG_SMP
+	cpu_physical_id(0) = hard_smp_processor_id();
+#endif
+
 #ifdef CONFIG_IA64_GENERIC
 	machvec_init(acpi_get_sysname());
 #endif
@@ -239,7 +235,7 @@
 	if (efi.acpi20) {
 		/* Parse the ACPI 2.0 tables */
 		acpi20_parse(efi.acpi20);
-	} else 
+	} else
 #endif
 	if (efi.acpi) {
 		/* Parse the ACPI tables */
@@ -259,8 +255,8 @@
 	ia64_mca_init();
 #endif
 
-	paging_init();
 	platform_setup(cmdline_p);
+	paging_init();
 }
 
 /*
@@ -325,7 +321,7 @@
 			     c->ppn, c->number, c->proc_freq / 1000000, c->proc_freq % 1000000,
 			     c->itc_freq / 1000000, c->itc_freq % 1000000,
 			     lpj*HZ/500000, (lpj*HZ/5000) % 100);
-        }
+	}
 	return p - buffer;
 }
 
@@ -362,8 +358,6 @@
 	for (i = 0; i < 5; ++i)
 		cpuid.bits[i] = ia64_get_cpuid(i);
 
-	memset(c, 0, sizeof(struct cpuinfo_ia64));
-
 	memcpy(c->vendor, cpuid.field.vendor, 16);
 	c->ppn = cpuid.field.ppn;
 	c->number = cpuid.field.number;
@@ -382,12 +376,6 @@
 	       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));
-
-#ifdef CONFIG_IA64_SOFTSDV_HACKS
-	/* BUG: SoftSDV doesn't support the cpuid registers. */
-	if (c->vendor[0] == '\0') 
-		memcpy(c->vendor, "Intel", 6);
-#endif
 }
 
 /*
@@ -397,12 +385,18 @@
 void
 cpu_init (void)
 {
-	extern void __init ia64_rid_init (void);
-	extern void __init ia64_tlb_init (void);
+	extern void __init ia64_mmu_init (void);
+	unsigned long num_phys_stacked;
 	pal_vm_info_2_u_t vmi;
 	unsigned int max_ctx;
 
-	identify_cpu(&my_cpu_data);
+	/*
+	 * We can't pass "local_cpu_data" do identify_cpu() because we haven't called
+	 * ia64_mmu_init() yet.  And we can't call ia64_mmu_init() first because it
+	 * depends on the data returned by identify_cpu().  We break the dependency by
+	 * accessing cpu_data[] the old way, through identity mapped space.
+	 */
+	identify_cpu(&cpu_data[smp_processor_id()]);
 
 	/* Clear the stack memory reserved for pt_regs: */
 	memset(ia64_task_regs(current), 0, sizeof(struct pt_regs));
@@ -415,22 +409,30 @@
 	ia64_set_dcr(  IA64_DCR_DM | IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR
 		     | IA64_DCR_DA | IA64_DCR_DD);
 #ifndef CONFIG_SMP
-	ia64_set_fpu_owner(0);		/* initialize ar.k5 */
+	ia64_set_fpu_owner(0);
 #endif
 
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
 
-	ia64_rid_init();
-	ia64_tlb_init();
+	ia64_mmu_init();
 
-#ifdef	CONFIG_IA32_SUPPORT
+#ifdef CONFIG_IA32_SUPPORT
 	/* initialize global ia32 state - CR0 and CR4 */
 	__asm__("mov ar.cflg = %0"
 		: /* no outputs */
 		: "r" (((ulong) IA32_CR4 << 32) | IA32_CR0));
 #endif
 
+	/* disable all local interrupt sources: */
+	ia64_set_itv(1 << 16);
+	ia64_set_lrr0(1 << 16);
+	ia64_set_lrr1(1 << 16);
+	ia64_set_pmv(1 << 16);
+	ia64_set_cmcv(1 << 16);
+
+	/* clear TPR & XTP to enable all interrupt classes: */
+	ia64_set_tpr(0);
 #ifdef CONFIG_SMP
 	normal_xtp();
 #endif
@@ -439,7 +441,7 @@
 	if (ia64_pal_vm_summary(NULL, &vmi) == 0)
 		max_ctx = (1U << (vmi.pal_vm_info_2_s.rid_size - 3)) - 1;
 	else {
-		printk("ia64_rid_init: PAL VM summary failed, assuming 18 RID bits\n");
+		printk("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) {
@@ -447,4 +449,10 @@
 		if (cmpxchg(&ia64_ctx.max_ctx, old, max_ctx) == old)
 			break;
 	}
+
+	if (ia64_pal_rse_info(&num_phys_stacked, 0) != 0) {
+		printk ("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 -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/signal.c linux/arch/ia64/kernel/signal.c
--- v2.4.3/linux/arch/ia64/kernel/signal.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/signal.c	Thu Apr  5 12:51:47 2001
@@ -1,8 +1,8 @@
 /*
  * Architecture-specific signal handling support.
  *
- * Copyright (C) 1999-2000 Hewlett-Packard Co
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2001 Hewlett-Packard Co
+ * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * Derived from i386 and Alpha versions.
  */
@@ -38,12 +38,8 @@
 #endif
 
 struct sigscratch {
-#ifdef CONFIG_IA64_NEW_UNWIND
 	unsigned long scratch_unat;	/* ar.unat for the general registers saved in pt */
 	unsigned long pad;
-#else
-	struct switch_stack sw;
-#endif
 	struct pt_regs pt;
 };
 
@@ -52,7 +48,6 @@
 	struct sigcontext sc;
 };
 
-extern long sys_wait4 (int, int *, int, struct rusage *);
 extern long ia64_do_signal (sigset_t *, struct sigscratch *, long);	/* forward decl */
 
 long
@@ -141,11 +136,7 @@
 	ia64_psr(&scr->pt)->ri = ip & 0x3;
 	scr->pt.cr_ipsr = (scr->pt.cr_ipsr & ~IA64_PSR_UM) | (um & IA64_PSR_UM);
 
-#ifdef CONFIG_IA64_NEW_UNWIND
 	scr->scratch_unat = ia64_put_scratch_nat_bits(&scr->pt, nat);
-#else
-	ia64_put_nat_bits(&scr->pt, &scr->sw, nat);	/* restore the original scratch NaT bits */
-#endif
 
 	if ((flags & IA64_SC_FLAG_FPH_VALID) != 0) {
 		struct ia64_psr *psr = ia64_psr(&scr->pt);
@@ -162,7 +153,7 @@
 int
 copy_siginfo_to_user (siginfo_t *to, siginfo_t *from)
 {
-	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+	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));
@@ -190,6 +181,11 @@
 			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);
+		      case __SI_PROF >> 16:
+			err |= __put_user(from->si_uid, &to->si_uid);
+			err |= __put_user(from->si_pid, &to->si_pid);
+			err |= __put_user(from->si_pfm_ovfl, &to->si_pfm_ovfl);
+			break;
 		      default:
 			err |= __put_user(from->si_uid, &to->si_uid);
 			err |= __put_user(from->si_pid, &to->si_pid);
@@ -200,6 +196,43 @@
 	}
 }
 
+int
+copy_siginfo_from_user (siginfo_t *to, siginfo_t *from)
+{
+	if (!access_ok(VERIFY_READ, from, sizeof(siginfo_t)))
+		return -EFAULT;
+	if (__copy_from_user(to, from, sizeof(siginfo_t)) != 0)
+		return -EFAULT;
+
+	if (SI_FROMUSER(to))
+		return 0;
+
+	to->si_code &= ~__SI_MASK;
+	if (to->si_code != 0) {
+		switch (to->si_signo) {
+		      case SIGILL: case SIGFPE: case SIGSEGV: case SIGBUS: case SIGTRAP:
+			to->si_code |= __SI_FAULT;
+			break;
+
+		      case SIGCHLD:
+			to->si_code |= __SI_CHLD;
+			break;
+
+		      case SIGPOLL:
+			to->si_code |= __SI_POLL;
+			break;
+
+		      case SIGPROF:
+			to->si_code |= __SI_PROF;
+			break;
+
+		      default:
+			break;
+		}
+	}
+	return 0;
+}
+
 long
 ia64_rt_sigreturn (struct sigscratch *scr)
 {
@@ -212,19 +245,17 @@
 	sc = &((struct sigframe *) (scr->pt.r12 + 16))->sc;
 
 	/*
-	 * When we return to the previously executing context, r8 and
-	 * r10 have already been setup the way we want them.  Indeed,
-	 * if the signal wasn't delivered while in a system call, we
-	 * must not touch r8 or r10 as otherwise user-level stat could
-	 * be corrupted.
+	 * When we return to the previously executing context, r8 and r10 have already
+	 * been setup the way we want them.  Indeed, if the signal wasn't delivered while
+	 * in a system call, we must not touch r8 or r10 as otherwise user-level state
+	 * could be corrupted.
 	 */
 	retval = (long) &ia64_leave_kernel;
 	if (current->ptrace & PT_TRACESYS)
 		/*
-		 * strace expects to be notified after sigreturn
-		 * returns even though the context to which we return
-		 * may not be in the middle of a syscall.  Thus, the
-		 * return-value that strace displays for sigreturn is
+		 * strace expects to be notified after sigreturn returns even though the
+		 * context to which we return may not be in the middle of a syscall.
+		 * Thus, the return-value that strace displays for sigreturn is
 		 * meaningless.
 		 */
 		retval = (long) &ia64_strace_leave_kernel;
@@ -301,11 +332,7 @@
 	 * preserved registers (r4-r7) are never being looked at by
 	 * the signal handler (registers r4-r7 are used instead).
 	 */
-#ifdef CONFIG_IA64_NEW_UNWIND
 	nat = ia64_get_scratch_nat_bits(&scr->pt, scr->scratch_unat);
-#else
-	nat = ia64_get_nat_bits(&scr->pt, &scr->sw);
-#endif
 
 	err  = __put_user(flags, &sc->sc_flags);
 
@@ -371,21 +398,11 @@
 	scr->pt.cr_iip = tramp_addr;
 	ia64_psr(&scr->pt)->ri = 0;			/* start executing in first slot */
 
-#ifdef CONFIG_IA64_NEW_UNWIND
 	/*
 	 * Note: this affects only the NaT bits of the scratch regs
 	 * (the ones saved in pt_regs), which is exactly what we want.
 	 */
 	scr->scratch_unat = 0; /* ensure NaT bits of at least r2, r3, r12, and r15 are clear */
-#else
-	/*
-	 * Note: this affects only the NaT bits of the scratch regs
-	 * (the ones saved in pt_regs), which is exactly what we want.
-	 * The NaT bits for the preserved regs (r4-r7) are in
-	 * sw->ar_unat iff this process is being PTRACED.
-	 */
-	scr->sw.caller_unat = 0; /* ensure NaT bits of at least r2, r3, r12, and r15 are clear */
-#endif
 
 #if DEBUG_SIG
 	printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%lx\n",
@@ -437,13 +454,8 @@
 }
 
 /*
- * 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.
+ * 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.
  */
 long
 ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
@@ -454,9 +466,9 @@
 	long errno = scr->pt.r8;
 
 	/*
-	 * In the ia64_leave_kernel code path, 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.
+	 * In the ia64_leave_kernel code path, 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(&scr->pt))
 		return 0;
@@ -476,11 +488,10 @@
 #endif
 	if (scr->pt.r10 != -1) {
 		/*
-		 * A system calls has to be restarted only if one of
-		 * the error codes ERESTARTNOHAND, ERESTARTSYS, or
-		 * ERESTARTNOINTR is returned.  If r10 isn't -1 then
-		 * r8 doesn't hold an error code and we don't need to
-		 * restart the syscall, so we set in_syscall to zero.
+		 * A system calls has to be restarted only if one of the error codes
+		 * ERESTARTNOHAND, ERESTARTSYS, or ERESTARTNOINTR is returned.  If r10
+		 * isn't -1 then r8 doesn't hold an error code and we don't need to
+		 * restart the syscall, so we can clear the "restart" flag here.
 		 */
 		restart = 0;
 	}
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/smp.c linux/arch/ia64/kernel/smp.c
--- v2.4.3/linux/arch/ia64/kernel/smp.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/smp.c	Thu Apr  5 12:51:47 2001
@@ -2,8 +2,8 @@
  * SMP Support
  *
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- * 
+ * Copyright (C) 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ *
  * Lots of stuff stolen from arch/alpha/kernel/smp.c
  *
  *  00/09/11 David Mosberger <davidm@hpl.hp.com> Do loops_per_jiffy calibration on each CPU.
@@ -37,8 +37,8 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/page.h>
-#include <asm/pgtable.h>
 #include <asm/pgalloc.h>
+#include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/ptrace.h>
 #include <asm/sal.h>
@@ -50,9 +50,8 @@
 extern void machine_halt(void);
 extern void start_ap(void);
 
-extern int cpu_now_booting;			     /* Used by head.S to find idle task */
-extern volatile unsigned long cpu_online_map;	     /* Bitmap of available cpu's */
-extern struct cpuinfo_ia64 cpu_data[NR_CPUS];	     /* Duh... */
+extern int cpu_now_booting;			/* used by head.S to find idle task */
+extern volatile unsigned long cpu_online_map;	/* bitmap of available cpu's */
 
 struct smp_boot_data smp_boot_data __initdata;
 
@@ -60,18 +59,19 @@
 
 char __initdata no_int_routing;
 
+/* don't make this a CPU-local variable: it's used for IPIs, mostly...  */
+int __cpu_physical_id[NR_CPUS];			/* logical ID -> physical CPU ID map */
+
 unsigned char smp_int_redirect;			/* are INT and IPI redirectable by the chipset? */
-volatile int __cpu_physical_id[NR_CPUS] = { -1, };    /* Logical ID -> SAPIC ID */
-int smp_num_cpus = 1;		
-volatile int smp_threads_ready;			     /* Set when the idlers are all forked */
-cycles_t cacheflush_time;
-unsigned long ap_wakeup_vector = -1;		     /* External Int to use to wakeup AP's */
+int smp_num_cpus = 1;
+volatile int smp_threads_ready;			/* set when the idlers are all forked */
+unsigned long ap_wakeup_vector;			/* external Int to use to wakeup AP's */
 
 static volatile unsigned long cpu_callin_map;
 static volatile int smp_commenced;
 
-static int max_cpus = -1;			     /* Command line */
-static unsigned long ipi_op[NR_CPUS];
+static int max_cpus = -1;			/* command line */
+
 struct smp_call_struct {
 	void (*func) (void *info);
 	void *info;
@@ -99,7 +99,8 @@
  *	SMP mode to <NUM>.
  */
 
-static int __init nosmp(char *str)
+static int __init
+nosmp (char *str)
 {
 	max_cpus = 0;
 	return 1;
@@ -107,7 +108,8 @@
 
 __setup("nosmp", nosmp);
 
-static int __init maxcpus(char *str)
+static int __init
+maxcpus (char *str)
 {
 	get_option(&str, &max_cpus);
 	return 1;
@@ -116,7 +118,7 @@
 __setup("maxcpus=", maxcpus);
 
 static int __init
-nointroute(char *str)
+nointroute (char *str)
 {
 	no_int_routing = 1;
 	return 1;
@@ -125,21 +127,20 @@
 __setup("nointroute", nointroute);
 
 /*
- * Yoink this CPU from the runnable list... 
+ * Yoink this CPU from the runnable list...
  */
 void
-halt_processor(void) 
+halt_processor (void)
 {
-        clear_bit(smp_processor_id(), &cpu_online_map);
+	clear_bit(smp_processor_id(), &cpu_online_map);
 	max_xtp();
 	__cli();
-        for (;;)
+	for (;;)
 		;
-
 }
 
 static inline int
-pointer_lock(void *lock, void *data, int retry)
+pointer_lock (void *lock, void *data, int retry)
 {
 	volatile long *ptr = lock;
  again:
@@ -156,14 +157,13 @@
 }
 
 void
-handle_IPI(int irq, void *dev_id, struct pt_regs *regs) 
+handle_IPI (int irq, void *dev_id, struct pt_regs *regs)
 {
-	int this_cpu = smp_processor_id();
-	unsigned long *pending_ipis = &ipi_op[this_cpu];
+	unsigned long *pending_ipis = &local_cpu_data->ipi_operation;
 	unsigned long ops;
 
 	/* Count this now; we may make a call that never returns. */
-	cpu_data[this_cpu].ipi_count++;
+	local_cpu_data->ipi_count++;
 
 	mb();	/* Order interrupt and bit testing. */
 	while ((ops = xchg(pending_ipis, 0)) != 0) {
@@ -173,16 +173,16 @@
 
 		which = ffz(~ops);
 		ops &= ~(1 << which);
-		
+
 		switch (which) {
 		case IPI_RESCHEDULE:
-			/* 
-			 * Reschedule callback.  Everything to be done is done by the 
-			 * interrupt return path.  
+			/*
+			 * Reschedule callback.  Everything to be done is done by the
+			 * interrupt return path.
 			 */
 			break;
-			
-		case IPI_CALL_FUNC: 
+
+		case IPI_CALL_FUNC:
 			{
 				struct smp_call_struct *data;
 				void (*func)(void *info);
@@ -203,7 +203,7 @@
 
 				/* Notify the sending CPU that the task is done.  */
 				mb();
-				if (wait) 
+				if (wait)
 					atomic_dec(&data->unfinished_count);
 			}
 			break;
@@ -214,7 +214,7 @@
 
 #ifndef CONFIG_ITANIUM_PTCG
 		case IPI_FLUSH_TLB:
-                {
+		{
 			extern unsigned long flush_start, flush_end, flush_nbits, flush_rid;
 			extern atomic_t flush_cpu_count;
 			unsigned long saved_rid = ia64_get_rr(flush_start);
@@ -223,6 +223,8 @@
 			unsigned long nbits = flush_nbits;
 
 			/*
+			 * Current CPU may be running with different RID so we need to
+			 * reload the RID of flushed address.
 			 * Current CPU may be running with different
 			 * RID so we need to reload the RID of flushed
 			 * address.  Purging the translation also
@@ -235,7 +237,7 @@
 				ia64_set_rr(flush_start, flush_rid);
 				ia64_srlz_d();
 			}
-			
+
 			do {
 				/*
 				 * Purge local TLB entries.
@@ -258,7 +260,8 @@
 #endif	/* !CONFIG_ITANIUM_PTCG */
 
 		default:
-			printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which);
+			printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n",
+			       smp_processor_id(), which);
 			break;
 		} /* Switch */
 	  } while (ops);
@@ -268,21 +271,21 @@
 }
 
 static inline void
-send_IPI_single (int dest_cpu, int op) 
+send_IPI_single (int dest_cpu, int op)
 {
-	
-	if (dest_cpu == -1) 
-                return;
-        
-	set_bit(op, &ipi_op[dest_cpu]);
-	platform_send_ipi(dest_cpu, IPI_IRQ, IA64_IPI_DM_INT, 0);
+
+	if (dest_cpu == -1)
+		return;
+
+	set_bit(op, &cpu_data[dest_cpu].ipi_operation);
+	platform_send_ipi(dest_cpu, IA64_IPI_VECTOR, IA64_IPI_DM_INT, 0);
 }
 
 static inline void
-send_IPI_allbutself(int op)
+send_IPI_allbutself (int op)
 {
 	int i;
-	
+
 	for (i = 0; i < smp_num_cpus; i++) {
 		if (i != smp_processor_id())
 			send_IPI_single(i, op);
@@ -290,7 +293,7 @@
 }
 
 static inline void
-send_IPI_all(int op)
+send_IPI_all (int op)
 {
 	int i;
 
@@ -299,30 +302,42 @@
 }
 
 static inline void
-send_IPI_self(int op)
+send_IPI_self (int op)
 {
 	send_IPI_single(smp_processor_id(), op);
 }
 
 void
-smp_send_reschedule(int cpu)
+smp_send_reschedule (int cpu)
 {
 	send_IPI_single(cpu, IPI_RESCHEDULE);
 }
 
 void
-smp_send_stop(void)
+smp_send_stop (void)
 {
 	send_IPI_allbutself(IPI_CPU_STOP);
 }
 
 #ifndef CONFIG_ITANIUM_PTCG
+
 void
-smp_send_flush_tlb(void)
+smp_send_flush_tlb (void)
 {
 	send_IPI_allbutself(IPI_FLUSH_TLB);
 }
-#endif	/* !CONFIG_ITANIUM_PTCG */
+
+void
+smp_resend_flush_tlb(void)
+{
+	/*
+	 * Really need a null IPI but since this rarely should happen & since this code
+	 * will go away, lets not add one.
+	 */
+	send_IPI_allbutself(IPI_RESCHEDULE);
+}
+
+#endif /* !CONFIG_ITANIUM_PTCG */
 
 /*
  * Run a function on another CPU
@@ -347,7 +362,7 @@
 		printk(__FUNCTION__" trying to call self\n");
 		return -EBUSY;
 	}
-	
+
 	data.func = func;
 	data.info = info;
 	data.wait = wait;
@@ -392,7 +407,6 @@
  * Does not return until remote CPUs are nearly ready to execute <func>
  * or are or have executed.
  */
-
 int
 smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
 {
@@ -402,7 +416,7 @@
 
 	if (cpus == 0)
 		return 0;
-	
+
 	data.func = func;
 	data.info = info;
 	data.wait = wait;
@@ -425,7 +439,7 @@
 		int i;
 		for (i = 0; i < smp_num_cpus; i++) {
 			if (i != smp_processor_id())
-				platform_send_ipi(i, IPI_IRQ, IA64_IPI_DM_INT, 0);
+				platform_send_ipi(i, IA64_IPI_VECTOR, IA64_IPI_DM_INT, 0);
 		}
 		goto retry;
 #else
@@ -446,7 +460,7 @@
  * want to ensure all TLB's flushed before proceeding.
  */
 void
-smp_flush_tlb_all(void)
+smp_flush_tlb_all (void)
 {
 	smp_call_function((void (*)(void *))__flush_tlb_all, NULL, 1, 1);
 	__flush_tlb_all();
@@ -456,21 +470,19 @@
  * Ideally sets up per-cpu profiling hooks.  Doesn't do much now...
  */
 static inline void __init
-smp_setup_percpu_timer(int cpuid)
+smp_setup_percpu_timer(void)
 {
-        cpu_data[cpuid].prof_counter = 1;
-        cpu_data[cpuid].prof_multiplier = 1;
+	local_cpu_data->prof_counter = 1;
+	local_cpu_data->prof_multiplier = 1;
 }
 
-void 
-smp_do_timer(struct pt_regs *regs)
+void
+smp_do_timer (struct pt_regs *regs)
 {
-        int cpu = smp_processor_id();
-        int user = user_mode(regs);
-	struct cpuinfo_ia64 *data = &cpu_data[cpu];
+	int user = user_mode(regs);
 
-        if (--data->prof_counter <= 0) {
-		data->prof_counter = data->prof_multiplier;
+	if (--local_cpu_data->prof_counter <= 0) {
+		local_cpu_data->prof_counter = local_cpu_data->prof_multiplier;
 		update_process_times(user);
 	}
 }
@@ -480,7 +492,7 @@
  * AP's start using C here.
  */
 void __init
-smp_callin (void) 
+smp_callin (void)
 {
 	extern void ia64_rid_init(void);
 	extern void ia64_init_itm(void);
@@ -493,12 +505,12 @@
 	if (test_and_set_bit(cpu, &cpu_online_map)) {
 		printk("CPU#%d already initialized!\n", cpu);
 		machine_halt();
-	}  
+	}
 
 	efi_map_pal_code();
 	cpu_init();
 
-	smp_setup_percpu_timer(cpu);
+	smp_setup_percpu_timer();
 
 	/* setup the CPU local timer tick */
 	ia64_init_itm();
@@ -506,15 +518,10 @@
 #ifdef CONFIG_PERFMON
 	perfmon_init_percpu();
 #endif
-
-	/* Disable all local interrupts */
-	ia64_set_lrr0(0, 1);	
-	ia64_set_lrr1(0, 1);	
-
 	local_irq_enable();		/* Interrupts have been off until now */
 
 	calibrate_delay();
-	my_cpu_data.loops_per_jiffy = loops_per_jiffy;
+	local_cpu_data->loops_per_jiffy = loops_per_jiffy;
 
 	/* allow the master to continue */
 	set_bit(cpu, &cpu_callin_map);
@@ -531,8 +538,8 @@
  * path in which case the new idle task could get scheduled before we
  * had a chance to remove it from the run-queue...
  */
-static int __init 
-fork_by_hand(void)
+static int __init
+fork_by_hand (void)
 {
 	/*
 	 * Don't care about the usp and regs settings since we'll never
@@ -545,22 +552,22 @@
  * Bring one cpu online.  Return 0 if this fails for any reason.
  */
 static int __init
-smp_boot_one_cpu(int cpu)
+smp_boot_one_cpu (int cpu)
 {
 	struct task_struct *idle;
 	int cpu_phys_id = cpu_physical_id(cpu);
 	long timeout;
 
-	/* 
+	/*
 	 * Create an idle task for this CPU.  Note that the address we
 	 * give to kernel_thread is irrelevant -- it's going to start
 	 * where OS_BOOT_RENDEVZ vector in SAL says to start.  But
 	 * this gets all the other task-y sort of data structures set
-	 * up like we wish.   We need to pull the just created idle task 
-	 * off the run queue and stuff it into the init_tasks[] array.  
+	 * up like we wish.   We need to pull the just created idle task
+	 * off the run queue and stuff it into the init_tasks[] array.
 	 * Sheesh . . .
 	 */
-	if (fork_by_hand() < 0) 
+	if (fork_by_hand() < 0)
 		panic("failed fork for CPU 0x%x", cpu_phys_id);
 	/*
 	 * We remove it from the pidhash and the runqueue
@@ -571,7 +578,7 @@
 		panic("No idle process for CPU 0x%x", cpu_phys_id);
 	init_tasks[cpu] = idle;
 	del_from_runqueue(idle);
-        unhash_process(idle);
+	unhash_process(idle);
 
 	/* Schedule the first task manually.  */
 	idle->processor = cpu;
@@ -590,50 +597,41 @@
 		udelay(100);
 	}
 
-	printk(KERN_ERR "SMP: Processor 0x%x is stuck.\n", cpu_phys_id);
+	printk(KERN_ERR "SMP: CPU 0x%x is stuck\n", cpu_phys_id);
 	return 0;
 }
 
 
 
 /*
- * Called by smp_init bring all the secondaries online and hold them.  
- * XXX: this is ACPI specific; it uses "magic" variables exported from acpi.c 
- *      to 'discover' the AP's.  Blech.
+ * Called by smp_init bring all the secondaries online and hold them.
  */
 void __init
-smp_boot_cpus(void)
+smp_boot_cpus (void)
 {
 	int i, cpu_count = 1;
 	unsigned long bogosum;
 
-	/* Take care of some initial bookkeeping.  */
-	memset(&__cpu_physical_id, -1, sizeof(__cpu_physical_id));
-	memset(&ipi_op, 0, sizeof(ipi_op));
-
-	/* Setup BP mappings */
-	__cpu_physical_id[0] = hard_smp_processor_id();
-
 	/* on the BP, the kernel already called calibrate_delay_loop() in init/main.c */
-	my_cpu_data.loops_per_jiffy = loops_per_jiffy;
+	local_cpu_data->loops_per_jiffy = loops_per_jiffy;
 #if 0
 	smp_tune_scheduling();
 #endif
- 	smp_setup_percpu_timer(0);
+	smp_setup_percpu_timer();
 
 	if (test_and_set_bit(0, &cpu_online_map)) {
 		printk("CPU#%d already initialized!\n", smp_processor_id());
 		machine_halt();
-	}  
+	}
 	init_idle();
 
 	/* Nothing to do when told not to.  */
 	if (max_cpus == 0) {
-	        printk(KERN_INFO "SMP mode deactivated.\n");
+		printk(KERN_INFO "SMP mode deactivated.\n");
 		return;
 	}
 
-	if (max_cpus != -1) 
+	if (max_cpus != -1)
 		printk("Limiting CPUs to %d\n", max_cpus);
 
 	if (smp_boot_data.cpu_count > 1) {
@@ -650,7 +648,7 @@
 				continue;	/* failed */
 
 			cpu_count++; /* Count good CPUs only... */
-			/* 
+			/*
 			 * Bail if we've started as many CPUS as we've been told to.
 			 */
 			if (cpu_count == max_cpus)
@@ -663,10 +661,10 @@
 	}
 
 	bogosum = 0;
-        for (i = 0; i < NR_CPUS; i++) {
+	for (i = 0; i < NR_CPUS; i++) {
 		if (cpu_online_map & (1L << i))
 			bogosum += cpu_data[i].loops_per_jiffy;
-        }
+	}
 
 	printk(KERN_INFO "SMP: Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
 	       cpu_count, bogosum*HZ/500000, (bogosum*HZ/5000) % 100);
@@ -674,31 +672,31 @@
 	smp_num_cpus = cpu_count;
 }
 
-/* 
+/*
  * Called when the BP is just about to fire off init.
  */
-void __init 
-smp_commence(void)
+void __init
+smp_commence (void)
 {
 	smp_commenced = 1;
 }
 
 int __init
-setup_profiling_timer(unsigned int multiplier)
+setup_profiling_timer (unsigned int multiplier)
 {
-        return -EINVAL;
+	return -EINVAL;
 }
 
 /*
  * Assume that CPU's have been discovered by some platform-dependant
  * interface.  For SoftSDV/Lion, that would be ACPI.
  *
- * Setup of the IPI irq handler is done in irq.c:init_IRQ_SMP().
+ * Setup of the IPI irq handler is done in irq.c:init_IRQ().
  *
  * This also registers the AP OS_MC_REDVEZ address with SAL.
  */
 void __init
-init_smp_config(void)
+init_smp_config (void)
 {
 	struct fptr {
 		unsigned long fp;
@@ -708,14 +706,13 @@
 
 	/* Tell SAL where to drop the AP's.  */
 	ap_startup = (struct fptr *) start_ap;
-	sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ,
-				       __pa(ap_startup->fp), __pa(ap_startup->gp), 0, 
-				       0, 0, 0);
+	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", ia64_sal_strerror(sal_ret));
 		printk("     Forcing UP mode\n");
 		max_cpus = 0;
-		smp_num_cpus = 1; 
+		smp_num_cpus = 1;
 	}
 
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/smpboot.c linux/arch/ia64/kernel/smpboot.c
--- v2.4.3/linux/arch/ia64/kernel/smpboot.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/kernel/smpboot.c	Thu Apr  5 12:51:47 2001
@@ -1,74 +1,4 @@
 /*
- * SMP Support
- *
- * Application processor startup code, moved from smp.c to better support kernel profile
  */
 
-#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 <asm/atomic.h>
-#include <asm/bitops.h>
-#include <asm/current.h>
-#include <asm/delay.h>
-#include <asm/efi.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
-#include <asm/processor.h>
-#include <asm/ptrace.h>
-#include <asm/sal.h>
-#include <asm/system.h>
-#include <asm/unistd.h>
-
-/* 
- * SAL shoves the AP's here when we start them.  Physical mode, no kernel TR, 
- * no RRs set, better than even chance that psr is bogus.  Fix all that and 
- * call _start.  In effect, pretend to be lilo.
- *
- * Stolen from lilo_start.c.  Thanks David! 
- */
-void
-start_ap(void)
-{
-	extern void _start (void);
-	unsigned long flags;
-
-	/*
-	 * Install a translation register that identity maps the
-	 * kernel's 256MB page(s).
-	 */
-	ia64_clear_ic(flags);
-	ia64_set_rr(          0, (0x1000 << 8) | (_PAGE_SIZE_1M << 2));
-	ia64_set_rr(PAGE_OFFSET, (ia64_rid(0, PAGE_OFFSET) << 8) | (_PAGE_SIZE_256M << 2));
-	ia64_srlz_d();
-	ia64_itr(0x3, 1, PAGE_OFFSET,
-		 pte_val(mk_pte_phys(0, __pgprot(__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RWX))),
-		 _PAGE_SIZE_256M);
-	ia64_srlz_i();
-
-	flags = (IA64_PSR_IT | IA64_PSR_IC | IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_DFH | 
-		 IA64_PSR_BN);
-	
-	asm volatile ("movl r8 = 1f\n"
-		      ";;\n"
-		      "mov cr.ipsr=%0\n"
-		      "mov cr.iip=r8\n" 
-		      "mov cr.ifs=r0\n"
-		      ";;\n"
-		      "rfi;;"
-		      "1:\n"
-		      "movl r1 = __gp" :: "r"(flags) : "r8");
-	_start();
-}
-
-
+/* place holder... */
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/sys_ia64.c linux/arch/ia64/kernel/sys_ia64.c
--- v2.4.3/linux/arch/ia64/kernel/sys_ia64.c	Mon Mar 19 12:35:10 2001
+++ linux/arch/ia64/kernel/sys_ia64.c	Thu Apr  5 12:51:47 2001
@@ -25,13 +25,14 @@
 get_unmapped_area (unsigned long addr, unsigned long len)
 {
 	struct vm_area_struct * vmm;
+	long map_shared = (current->thread.flags & IA64_THREAD_MAP_SHARED) != 0;
 
 	if (len > RGN_MAP_LIMIT)
 		return 0;
 	if (!addr)
 		addr = TASK_UNMAPPED_BASE;
 
-	if (current->thread.flags & IA64_THREAD_MAP_SHARED)
+	if (map_shared)
 		addr = COLOR_ALIGN(addr);
 	else
 		addr = PAGE_ALIGN(addr);
@@ -45,11 +46,13 @@
 		if (!vmm || addr + len <= vmm->vm_start)
 			return addr;
 		addr = vmm->vm_end;
+		if (map_shared)
+			addr = COLOR_ALIGN(addr);
 	}
 }
 
 asmlinkage long
-ia64_getpriority (int which, int who, long arg2, long arg3, long arg4, long arg5, long arg6, 
+ia64_getpriority (int which, int who, long arg2, long arg3, long arg4, long arg5, long arg6,
 		  long arg7, long stack)
 {
 	struct pt_regs *regs = (struct pt_regs *) &stack;
@@ -246,15 +249,15 @@
 asmlinkage long
 sys_vm86 (long arg0, long arg1, long arg2, long arg3)
 {
-        printk(KERN_ERR "sys_vm86(%lx, %lx, %lx, %lx)!\n", arg0, arg1, arg2, arg3);
-        return -ENOSYS;
+	printk(KERN_ERR "sys_vm86(%lx, %lx, %lx, %lx)!\n", arg0, arg1, arg2, arg3);
+	return -ENOSYS;
 }
 
 asmlinkage long
 sys_modify_ldt (long arg0, long arg1, long arg2, long arg3)
 {
-        printk(KERN_ERR "sys_modify_ldt(%lx, %lx, %lx, %lx)!\n", arg0, arg1, arg2, arg3);
-        return -ENOSYS;
+	printk(KERN_ERR "sys_modify_ldt(%lx, %lx, %lx, %lx)!\n", arg0, arg1, arg2, arg3);
+	return -ENOSYS;
 }
 
 asmlinkage unsigned long
@@ -392,7 +395,7 @@
 	}
 	return err;
 }
- 
+
 #endif
 
 #ifndef CONFIG_PCI
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/time.c linux/arch/ia64/kernel/time.c
--- v2.4.3/linux/arch/ia64/kernel/time.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/time.c	Thu Apr  5 12:51:47 2001
@@ -1,9 +1,9 @@
 /*
  * linux/arch/ia64/kernel/time.c
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
  * Copyright (C) 1998-2000 Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 1999-2000 David Mosberger <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2001 David Mosberger <davidm@hpl.hp.com>
  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
  * Copyright (C) 1999-2000 VA Linux Systems
  * Copyright (C) 1999-2000 Walt Drummond <drummond@valinux.com>
@@ -32,14 +32,6 @@
 
 #endif
 
-static struct {
-	unsigned long delta;
-	union {
-		unsigned long count;
-		unsigned char pad[SMP_CACHE_BYTES];
-	} next[NR_CPUS];
-} itm;
-
 static void
 do_profile (unsigned long ip)
 {
@@ -61,7 +53,7 @@
 			ip = prof_len - 1;
 
 		atomic_inc((atomic_t *) &prof_buffer[ip]);
-	} 
+	}
 }
 
 /*
@@ -82,7 +74,7 @@
 	unsigned long now = ia64_get_itc(), last_tick;
 	unsigned long elapsed_cycles, lost = jiffies - wall_jiffies;
 
-	last_tick = (itm.next[smp_processor_id()].count - (lost+1)*itm.delta);
+	last_tick = (local_cpu_data->itm_next - (lost+1)*local_cpu_data->itm_delta);
 # if 1
 	if ((long) (now - last_tick) < 0) {
 		printk("Yikes: now < last_tick (now=0x%lx,last_tick=%lx)!  No can do.\n",
@@ -91,7 +83,7 @@
 	}
 # endif
 	elapsed_cycles = now - last_tick;
-	return (elapsed_cycles*my_cpu_data.usec_per_cyc) >> IA64_USEC_PER_CYC_SHIFT;
+	return (elapsed_cycles*local_cpu_data->usec_per_cyc) >> IA64_USEC_PER_CYC_SHIFT;
 #endif
 }
 
@@ -132,7 +124,7 @@
 	read_lock_irqsave(&xtime_lock, flags);
 	{
 		usec = gettimeoffset();
-	
+
 		sec = xtime.tv_sec;
 		usec += xtime.tv_usec;
 	}
@@ -150,10 +142,9 @@
 static void
 timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	int cpu = smp_processor_id();
 	unsigned long new_itm;
 
-	new_itm = itm.next[cpu].count;
+	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",
@@ -165,7 +156,7 @@
 		 * four so that we can use a prof_shift of 2 to get instruction-level
 		 * instead of just bundle-level accuracy.
 		 */
-		if (!user_mode(regs)) 
+		if (!user_mode(regs))
 			do_profile(regs->cr_iip + 4*ia64_psr(regs)->ri);
 
 #ifdef CONFIG_SMP
@@ -183,52 +174,50 @@
 			write_unlock(&xtime_lock);
 		}
 
-		new_itm += itm.delta;
-		itm.next[cpu].count = new_itm;
+		new_itm += local_cpu_data->itm_delta;
+		local_cpu_data->itm_next = new_itm;
 		if (time_after(new_itm, ia64_get_itc()))
 			break;
 	}
 
-	/*
-	 * If we're too close to the next clock tick for comfort, we
-	 * increase the saftey margin by intentionally dropping the
-	 * next tick(s).  We do NOT update itm.next accordingly
-	 * because that would force us to call do_timer() which in
-	 * turn would let our clock run too fast (with the potentially
-	 * devastating effect of losing monotony of time).
-	 */
-	while (!time_after(new_itm, ia64_get_itc() + itm.delta/2))
-		new_itm += itm.delta;
-	ia64_set_itm(new_itm);
-}
-
-#ifdef CONFIG_IA64_SOFTSDV_HACKS
-
-/*
- * Interrupts must be disabled before calling this routine.
- */
-void
-ia64_reset_itm (void)
-{
-	timer_interrupt(0, 0, ia64_task_regs(current));
+	do {
+	    /*
+	     * If we're too close to the next clock tick for comfort, we increase the
+	     * saftey margin by intentionally dropping the next tick(s).  We do NOT update
+	     * itm.next because that would force us to call do_timer() which in turn would
+	     * let our clock run too fast (with the potentially devastating effect of
+	     * losing monotony of time).
+	     */
+	    while (!time_after(new_itm, ia64_get_itc() + local_cpu_data->itm_delta/2))
+	      new_itm += local_cpu_data->itm_delta;
+	    ia64_set_itm(new_itm);
+	    /* double check, in case we got hit by a (slow) PMI: */
+	} while (time_after_eq(ia64_get_itc(), new_itm));
 }
 
-#endif
-
 /*
  * Encapsulate access to the itm structure for SMP.
  */
 void __init
-ia64_cpu_local_tick(void)
+ia64_cpu_local_tick (void)
 {
-#ifdef CONFIG_IA64_SOFTSDV_HACKS
-	ia64_set_itc(0);
-#endif
+	int cpu = smp_processor_id();
+	unsigned long shift = 0, delta;
 
 	/* arrange for the cycle counter to generate a timer interrupt: */
-	ia64_set_itv(TIMER_IRQ, 0);
-	itm.next[smp_processor_id()].count = ia64_get_itc() + itm.delta;
-	ia64_set_itm(itm.next[smp_processor_id()].count);
+	ia64_set_itv(IA64_TIMER_VECTOR);
+
+	delta = local_cpu_data->itm_delta;
+	/*
+	 * Stagger the timer tick for each CPU so they don't occur all at (almost) the
+	 * same time:
+	 */
+	if (cpu) {
+		unsigned long hi = 1UL << ia64_fls(cpu);
+		shift = (2*(cpu - hi) + 1) * delta/hi/2;
+	}
+	local_cpu_data->itm_next = ia64_get_itc() + delta + shift;
+	ia64_set_itm(local_cpu_data->itm_next);
 }
 
 void __init
@@ -258,33 +247,28 @@
 		itc_ratio.num = 3;
 		itc_ratio.den = 1;
 	}
-#ifdef CONFIG_IA64_SOFTSDV_HACKS
-	platform_base_freq = 10000000;
-	proc_ratio.num = 4; proc_ratio.den = 1;
-	itc_ratio.num  = 4; itc_ratio.den  = 1;
-#else
 	if (platform_base_freq < 40000000) {
 		printk("Platform base frequency %lu bogus---resetting to 75MHz!\n",
 		       platform_base_freq);
 		platform_base_freq = 75000000;
 	}
-#endif
 	if (!proc_ratio.den)
-		proc_ratio.num = 1;	/* avoid division by zero */
+		proc_ratio.den = 1;	/* avoid division by zero */
 	if (!itc_ratio.den)
-		itc_ratio.num = 1;	/* avoid division by zero */
+		itc_ratio.den = 1;	/* avoid division by zero */
 
-        itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den;
-        itm.delta = itc_freq / HZ;
-        printk("CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, ITC freq=%lu.%03luMHz\n",
+	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(),
 	       platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000,
-               itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000);
+	       itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000);
 
-	my_cpu_data.proc_freq = (platform_base_freq*proc_ratio.num)/proc_ratio.den;
-	my_cpu_data.itc_freq = itc_freq;
-	my_cpu_data.cyc_per_usec = itc_freq / 1000000;
-	my_cpu_data.usec_per_cyc = (1000000UL << IA64_USEC_PER_CYC_SHIFT) / itc_freq;
+	local_cpu_data->proc_freq = (platform_base_freq*proc_ratio.num)/proc_ratio.den;
+	local_cpu_data->itc_freq = itc_freq;
+	local_cpu_data->cyc_per_usec = (itc_freq + 500000) / 1000000;
+	local_cpu_data->usec_per_cyc = ((1000000UL<<IA64_USEC_PER_CYC_SHIFT)
+					+ itc_freq/2)/itc_freq;
 
 	/* Setup the CPU local timer tick */
 	ia64_cpu_local_tick();
@@ -299,11 +283,7 @@
 void __init
 time_init (void)
 {
-	/* we can't do request_irq() here because the kmalloc() would fail... */
-	irq_desc[TIMER_IRQ].status |= IRQ_PER_CPU;
-	irq_desc[TIMER_IRQ].handler = &irq_type_ia64_sapic;
-	setup_irq(TIMER_IRQ, &timer_irqaction);
-
+	register_percpu_irq(IA64_TIMER_VECTOR, &timer_irqaction);
 	efi_gettimeofday(&xtime);
 	ia64_init_itm();
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/traps.c linux/arch/ia64/kernel/traps.c
--- v2.4.3/linux/arch/ia64/kernel/traps.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/traps.c	Thu Apr  5 12:51:47 2001
@@ -7,8 +7,6 @@
  * 05/12/00 grao <goutham.rao@intel.com> : added isr in siginfo for SIGFPE
  */
 
-#define FPSWA_DEBUG	1
-
 /*
  * The fpu_fault() handler needs to be able to access and update all
  * floating point registers.  Those saved in pt_regs can be accessed
@@ -47,31 +45,10 @@
 void __init
 trap_init (void)
 {
-	printk("fpswa interface at %lx\n", ia64_boot_param.fpswa);
-	if (ia64_boot_param.fpswa) {
-#define OLD_FIRMWARE
-#ifdef OLD_FIRMWARE
-		/*
-		 * HACK to work around broken firmware.  This code
-		 * applies the label fixup to the FPSWA interface and
-		 * works both with old and new (fixed) firmware.
-		 */
-		unsigned long addr = (unsigned long) __va(ia64_boot_param.fpswa);
-		unsigned long gp_val = *(unsigned long *)(addr + 8);
-
-		/* go indirect and indexed to get table address */
-		addr = gp_val;
-		gp_val = *(unsigned long *)(addr + 8);
-
-		while (gp_val == *(unsigned long *)(addr + 8)) {
-			*(unsigned long *)addr |= PAGE_OFFSET;
-			*(unsigned long *)(addr + 8) |= PAGE_OFFSET;
-			addr += 16;
-		}
-#endif
+	printk("fpswa interface at %lx\n", ia64_boot_param->fpswa);
+	if (ia64_boot_param->fpswa)
 		/* FPSWA fixup: make the interface pointer a kernel virtual address: */
-		fpswa_interface = __va(ia64_boot_param.fpswa);
-	}
+		fpswa_interface = __va(ia64_boot_param->fpswa);
 }
 
 void
@@ -240,6 +217,7 @@
 {
 	fp_state_t fp_state;
 	fpswa_ret_t ret;
+#define FPSWA_BUG
 #ifdef FPSWA_BUG
 	struct ia64_fpreg f6_15[10];
 #endif
@@ -250,7 +228,7 @@
 	memset(&fp_state, 0, sizeof(fp_state_t));
 
 	/*
-	 * compute fp_state.  only FP registers f6 - f11 are used by the 
+	 * compute fp_state.  only FP registers f6 - f11 are used by the
 	 * kernel, so set those bits in the mask and set the low volatile
 	 * pointer to point to these registers.
 	 */
@@ -263,15 +241,15 @@
 	f6_15[1] = regs->f7;
 	f6_15[2] = regs->f8;
 	f6_15[3] = regs->f9;
- 	__asm__ ("stf.spill %0=f10%P0" : "=m"(f6_15[4]));
- 	__asm__ ("stf.spill %0=f11%P0" : "=m"(f6_15[5]));
- 	__asm__ ("stf.spill %0=f12%P0" : "=m"(f6_15[6]));
- 	__asm__ ("stf.spill %0=f13%P0" : "=m"(f6_15[7]));
- 	__asm__ ("stf.spill %0=f14%P0" : "=m"(f6_15[8]));
- 	__asm__ ("stf.spill %0=f15%P0" : "=m"(f6_15[9]));
+	__asm__ ("stf.spill %0=f10%P0" : "=m"(f6_15[4]));
+	__asm__ ("stf.spill %0=f11%P0" : "=m"(f6_15[5]));
+	__asm__ ("stf.spill %0=f12%P0" : "=m"(f6_15[6]));
+	__asm__ ("stf.spill %0=f13%P0" : "=m"(f6_15[7]));
+	__asm__ ("stf.spill %0=f14%P0" : "=m"(f6_15[8]));
+	__asm__ ("stf.spill %0=f15%P0" : "=m"(f6_15[9]));
 	fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) f6_15;
 #endif
-        /*
+	/*
 	 * unsigned long (*EFI_FPSWA) (
 	 *      unsigned long    trap_type,
 	 *	void             *Bundle,
@@ -287,12 +265,12 @@
 					(unsigned long *) isr, (unsigned long *) pr,
 					(unsigned long *) ifs, &fp_state);
 #ifdef FPSWA_BUG
- 	__asm__ ("ldf.fill f10=%0%P0" :: "m"(f6_15[4]));
- 	__asm__ ("ldf.fill f11=%0%P0" :: "m"(f6_15[5]));
- 	__asm__ ("ldf.fill f12=%0%P0" :: "m"(f6_15[6]));
- 	__asm__ ("ldf.fill f13=%0%P0" :: "m"(f6_15[7]));
- 	__asm__ ("ldf.fill f14=%0%P0" :: "m"(f6_15[8]));
- 	__asm__ ("ldf.fill f15=%0%P0" :: "m"(f6_15[9]));
+	__asm__ ("ldf.fill f10=%0%P0" :: "m"(f6_15[4]));
+	__asm__ ("ldf.fill f11=%0%P0" :: "m"(f6_15[5]));
+	__asm__ ("ldf.fill f12=%0%P0" :: "m"(f6_15[6]));
+	__asm__ ("ldf.fill f13=%0%P0" :: "m"(f6_15[7]));
+	__asm__ ("ldf.fill f14=%0%P0" :: "m"(f6_15[8]));
+	__asm__ ("ldf.fill f15=%0%P0" :: "m"(f6_15[9]));
 	regs->f6 = f6_15[0];
 	regs->f7 = f6_15[1];
 	regs->f8 = f6_15[2];
@@ -319,21 +297,20 @@
 	if (copy_from_user(bundle, (void *) fault_ip, sizeof(bundle)))
 		return -1;
 
-#ifdef FPSWA_DEBUG
-	if (fpu_swa_count > 5 && jiffies - last_time > 5*HZ)
+	if (jiffies - last_time > 5*HZ)
 		fpu_swa_count = 0;
 	if (++fpu_swa_count < 5) {
 		last_time = jiffies;
-		printk("%s(%d): floating-point assist fault at ip %016lx\n",
+		printk(KERN_WARNING "%s(%d): floating-point assist fault at ip %016lx\n",
 		       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri);
 	}
-#endif
+
 	exception = fp_emulate(fp_fault, bundle, &regs->cr_ipsr, &regs->ar_fpsr, &isr, &regs->pr,
- 			       &regs->cr_ifs, regs);
+			       &regs->cr_ifs, regs);
 	if (fp_fault) {
 		if (exception == 0) {
 			/* emulation was successful */
- 			ia64_increment_ip(regs);
+			ia64_increment_ip(regs);
 		} else if (exception == -1) {
 			printk("handle_fpu_swa: fp_emulate() returned -1\n");
 			return -1;
@@ -392,7 +369,7 @@
 	struct siginfo si;
 	char buf[128];
 
-#ifdef CONFIG_IA64_BRL_EMU	
+#ifdef CONFIG_IA64_BRL_EMU
 	{
 		extern struct illegal_op_return ia64_emulate_brl (struct pt_regs *, unsigned long);
 
@@ -431,7 +408,7 @@
 		"IA-64 Reserved Register/Field fault",
 		"Disabled Instruction Set Transition fault",
 		"Unknown fault 5", "Unknown fault 6", "Unknown fault 7", "Illegal Hazard fault",
-		"Unknown fault 9", "Unknown fault 10", "Unknown fault 11", "Unknown fault 12", 
+		"Unknown fault 9", "Unknown fault 10", "Unknown fault 11", "Unknown fault 12",
 		"Unknown fault 13", "Unknown fault 14", "Unknown fault 15"
 	};
 
@@ -444,7 +421,7 @@
 		unsigned long n = vector;
 		char buf[32], *cp;
 
-		if (count > 5 && jiffies - last_time > 5*HZ)
+		if (jiffies - last_time > 5*HZ)
 			count = 0;
 
 		if (count++ < 5) {
@@ -502,7 +479,7 @@
 	      case 35: /* Taken Branch Trap */
 	      case 36: /* Single Step Trap */
 		switch (vector) {
-		      case 29: 
+		      case 29:
 			siginfo.si_code = TRAP_HWBKPT;
 #ifdef CONFIG_ITANIUM
 			/*
@@ -513,7 +490,7 @@
 			  ifa = regs->cr_iip;
 #endif
 			siginfo.si_addr = (void *) ifa;
-		        break;
+			break;
 		      case 35: siginfo.si_code = TRAP_BRANCH; break;
 		      case 36: siginfo.si_code = TRAP_TRACE; break;
 		}
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/unaligned.c linux/arch/ia64/kernel/unaligned.c
--- v2.4.3/linux/arch/ia64/kernel/unaligned.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/kernel/unaligned.c	Thu Apr  5 12:51:47 2001
@@ -1,12 +1,16 @@
 /*
  * Architecture-specific unaligned trap handling.
  *
- * Copyright (C) 1999-2000 Hewlett-Packard Co
+ * Copyright (C) 1999-2001 Hewlett-Packard Co
  * Copyright (C) 1999-2000 Stephane Eranian <eranian@hpl.hp.com>
+ * Copyright (C) 2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * 2001/01/17	Add support emulation of unaligned kernel accesses.
  */
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
+
 #include <asm/uaccess.h>
 #include <asm/rse.h>
 #include <asm/processor.h>
@@ -17,14 +21,28 @@
 #undef DEBUG_UNALIGNED_TRAP
 
 #ifdef DEBUG_UNALIGNED_TRAP
-#define DPRINT(a) { printk("%s, line %d: ", __FUNCTION__, __LINE__); printk a;}
+# define DPRINT(a...)	do { printk("%s.%u: ", __FUNCTION__, __LINE__); printk (a); } while (0)
+# define DDUMP(str,vp,len)	dump(str, vp, len)
+
+static void
+dump (const char *str, void *vp, size_t len)
+{
+	unsigned char *cp = vp;
+	int i;
+
+	printk("%s", str);
+	for (i = 0; i < len; ++i)
+		printk (" %02x", *cp++);
+	printk("\n");
+}
 #else
-#define DPRINT(a)
+# define DPRINT(a...)
+# define DDUMP(str,vp,len)
 #endif
 
 #define IA64_FIRST_STACKED_GR	32
 #define IA64_FIRST_ROTATING_FR	32
-#define SIGN_EXT9		__IA64_UL(0xffffffffffffff00)
+#define SIGN_EXT9		0xffffffffffffff00ul
 
 /*
  * For M-unit:
@@ -35,33 +53,34 @@
  * --------|------|---------|
  *     4   |   1  |    6    | = 11 bits
  * --------------------------
- * However bits [31:30] are not directly useful to distinguish between 
- * load/store so we can use [35:32] instead, which gives the following 
+ * However bits [31:30] are not directly useful to distinguish between
+ * load/store so we can use [35:32] instead, which gives the following
  * mask ([40:32]) using 9 bits. The 'e' comes from the fact that we defer
  * checking the m-bit until later in the load/store emulation.
  */
-#define IA64_OPCODE_MASK	0x1ef00000000
+#define IA64_OPCODE_MASK	0x1ef
+#define IA64_OPCODE_SHIFT	32
 
 /*
  * Table C-28 Integer Load/Store
- * 
+ *
  * We ignore [35:32]= 0x6, 0x7, 0xE, 0xF
  *
- * ld8.fill, st8.fill  MUST be aligned because the RNATs are based on 
+ * ld8.fill, st8.fill  MUST be aligned because the RNATs are based on
  * the address (bits [8:3]), so we must failed.
  */
-#define LD_OP            0x08000000000
-#define LDS_OP           0x08100000000
-#define LDA_OP           0x08200000000
-#define LDSA_OP          0x08300000000
-#define LDBIAS_OP        0x08400000000
-#define LDACQ_OP         0x08500000000
+#define LD_OP            0x080
+#define LDS_OP           0x081
+#define LDA_OP           0x082
+#define LDSA_OP          0x083
+#define LDBIAS_OP        0x084
+#define LDACQ_OP         0x085
 /* 0x086, 0x087 are not relevant */
-#define LDCCLR_OP        0x08800000000
-#define LDCNC_OP         0x08900000000
-#define LDCCLRACQ_OP     0x08a00000000
-#define ST_OP            0x08c00000000
-#define STREL_OP         0x08d00000000
+#define LDCCLR_OP        0x088
+#define LDCNC_OP         0x089
+#define LDCCLRACQ_OP     0x08a
+#define ST_OP            0x08c
+#define STREL_OP         0x08d
 /* 0x08e,0x8f are not relevant */
 
 /*
@@ -73,38 +92,38 @@
 
 /*
  * Table C-30 Integer Load/Store +Imm
- * 
+ *
  * We ignore [35:32]= 0x6, 0x7, 0xE, 0xF
  *
- * ld8.fill, st8.fill  must be aligned because the Nat register are based on 
+ * ld8.fill, st8.fill  must be aligned because the Nat register are based on
  * the address, so we must fail and the program must be fixed.
  */
-#define LD_IMM_OP            0x0a000000000
-#define LDS_IMM_OP           0x0a100000000
-#define LDA_IMM_OP           0x0a200000000
-#define LDSA_IMM_OP          0x0a300000000
-#define LDBIAS_IMM_OP        0x0a400000000
-#define LDACQ_IMM_OP         0x0a500000000
+#define LD_IMM_OP            0x0a0
+#define LDS_IMM_OP           0x0a1
+#define LDA_IMM_OP           0x0a2
+#define LDSA_IMM_OP          0x0a3
+#define LDBIAS_IMM_OP        0x0a4
+#define LDACQ_IMM_OP         0x0a5
 /* 0x0a6, 0xa7 are not relevant */
-#define LDCCLR_IMM_OP        0x0a800000000
-#define LDCNC_IMM_OP         0x0a900000000
-#define LDCCLRACQ_IMM_OP     0x0aa00000000
-#define ST_IMM_OP            0x0ac00000000
-#define STREL_IMM_OP         0x0ad00000000
+#define LDCCLR_IMM_OP        0x0a8
+#define LDCNC_IMM_OP         0x0a9
+#define LDCCLRACQ_IMM_OP     0x0aa
+#define ST_IMM_OP            0x0ac
+#define STREL_IMM_OP         0x0ad
 /* 0x0ae,0xaf are not relevant */
 
 /*
  * Table C-32 Floating-point Load/Store
  */
-#define LDF_OP           0x0c000000000
-#define LDFS_OP          0x0c100000000
-#define LDFA_OP          0x0c200000000
-#define LDFSA_OP         0x0c300000000
+#define LDF_OP           0x0c0
+#define LDFS_OP          0x0c1
+#define LDFA_OP          0x0c2
+#define LDFSA_OP         0x0c3
 /* 0x0c6 is irrelevant */
-#define LDFCCLR_OP       0x0c800000000
-#define LDFCNC_OP        0x0c900000000
+#define LDFCCLR_OP       0x0c8
+#define LDFCNC_OP        0x0c9
 /* 0x0cb is irrelevant  */
-#define STF_OP           0x0cc00000000
+#define STF_OP           0x0cc
 
 /*
  * Table C-33 Floating-point Load +Reg
@@ -116,17 +135,17 @@
 /*
  * Table C-34 Floating-point Load/Store +Imm
  */
-#define LDF_IMM_OP       0x0e000000000
-#define LDFS_IMM_OP      0x0e100000000
-#define LDFA_IMM_OP      0x0e200000000
-#define LDFSA_IMM_OP     0x0e300000000
+#define LDF_IMM_OP       0x0e0
+#define LDFS_IMM_OP      0x0e1
+#define LDFA_IMM_OP      0x0e2
+#define LDFSA_IMM_OP     0x0e3
 /* 0x0e6 is irrelevant */
-#define LDFCCLR_IMM_OP   0x0e800000000
-#define LDFCNC_IMM_OP    0x0e900000000
-#define STF_IMM_OP       0x0ec00000000
+#define LDFCCLR_IMM_OP   0x0e8
+#define LDFCNC_IMM_OP    0x0e9
+#define STF_IMM_OP       0x0ec
 
 typedef struct {
-	unsigned long  	 qp:6;	/* [0:5]   */
+	unsigned long	 qp:6;	/* [0:5]   */
 	unsigned long    r1:7;	/* [6:12]  */
 	unsigned long   imm:7;	/* [13:19] */
 	unsigned long    r3:7;	/* [20:26] */
@@ -170,7 +189,7 @@
 #define FR_IN_SW(x)	(fr_info[x] & 0x1)
 
 static u16 gr_info[32]={
-	0, 			/* r0 is read-only : WE SHOULD NEVER GET THIS */
+	0,			/* r0 is read-only : WE SHOULD NEVER GET THIS */
 
 	RPT(r1), RPT(r2), RPT(r3),
 
@@ -186,7 +205,7 @@
 };
 
 static u16 fr_info[32]={
-	0, 			/* constant : WE SHOULD NEVER GET THIS */
+	0,			/* constant : WE SHOULD NEVER GET THIS */
 	0,			/* constant : WE SHOULD NEVER GET THIS */
 
 	RSW(f2), RSW(f3), RSW(f4), RSW(f5),
@@ -255,162 +274,160 @@
 }
 
 static void
-set_rse_reg(struct pt_regs *regs, unsigned long r1, unsigned long val, int nat)
+set_rse_reg (struct pt_regs *regs, unsigned long r1, unsigned long val, int nat)
 {
-	struct switch_stack *sw = (struct switch_stack *)regs - 1;
-	unsigned long *kbs	= ((unsigned long *)current) + IA64_RBS_OFFSET/8;
+	struct switch_stack *sw = (struct switch_stack *) regs - 1;
+	unsigned long *bsp, *bspstore, *addr, *rnat_addr, *ubs_end;
+	unsigned long *kbs = (void *) current + IA64_RBS_OFFSET;
+	unsigned long rnats, nat_mask;
 	unsigned long on_kbs;
-	unsigned long *bsp, *bspstore, *addr, *ubs_end, *slot;
-	unsigned long rnats;
-	long nlocals;
+	long sof = (regs->cr_ifs) & 0x7f;
 
-	/*
-	 * cr_ifs=[rv:ifm], ifm=[....:sof(6)]
-	 * nlocal=number of locals (in+loc) register of the faulting function
-	 */
-	nlocals = (regs->cr_ifs) & 0x7f;
+	DPRINT("r%lu, sw.bspstore=%lx pt.bspstore=%lx sof=%ld sol=%ld\n",
+	       r1, sw->ar_bspstore, regs->ar_bspstore, sof, (regs->cr_ifs >> 7) & 0x7f);
 
-	DPRINT(("sw.bsptore=%lx pt.bspstore=%lx\n", sw->ar_bspstore, regs->ar_bspstore));
-	DPRINT(("cr.ifs=%lx sof=%ld sol=%ld\n",
-		regs->cr_ifs, regs->cr_ifs &0x7f, (regs->cr_ifs>>7)&0x7f));
+	if ((r1 - 32) >= sof) {
+		/* this should never happen, as the "rsvd register fault" has higher priority */
+		DPRINT("ignoring write to r%lu; only %lu registers are allocated!\n", r1, sof);
+		return;
+	}
 
-	on_kbs   = ia64_rse_num_regs(kbs, (unsigned long *)sw->ar_bspstore);
-	bspstore = (unsigned long *)regs->ar_bspstore;
+	on_kbs = ia64_rse_num_regs(kbs, (unsigned long *) sw->ar_bspstore);
+	addr = ia64_rse_skip_regs((unsigned long *) sw->ar_bspstore, -sof + (r1 - 32));
+	if (addr >= kbs) {
+		/* the register is on the kernel backing store: easy... */
+		rnat_addr = ia64_rse_rnat_addr(addr);
+		if ((unsigned long) rnat_addr >= sw->ar_bspstore)
+			rnat_addr = &sw->ar_rnat;
+		nat_mask = 1UL << ia64_rse_slot_num(addr);
 
-	DPRINT(("rse_slot_num=0x%lx\n",ia64_rse_slot_num((unsigned long *)sw->ar_bspstore)));
-	DPRINT(("kbs=%p nlocals=%ld\n", (void *) kbs, nlocals));
-	DPRINT(("bspstore next rnat slot %p\n",
-		(void *) ia64_rse_rnat_addr((unsigned long *)sw->ar_bspstore)));
-	DPRINT(("on_kbs=%ld rnats=%ld\n",
-		on_kbs, ((sw->ar_bspstore-(unsigned long)kbs)>>3) - on_kbs));
+		*addr = val;
+		if (nat)
+			*rnat_addr |=  nat_mask;
+		else
+			*rnat_addr &= ~nat_mask;
+		return;
+	}
 
 	/*
-	 * See get_rse_reg() for an explanation on the following instructions
+	 * Avoid using user_mode() here: with "epc", we cannot use the privilege level to
+	 * infer whether the interrupt task was running on the kernel backing store.
 	 */
+	if (regs->r12 >= TASK_SIZE) {
+		DPRINT("ignoring kernel write to r%lu; register isn't on the RBS!", r1);
+		return;
+	}
+
+	bspstore = (unsigned long *) regs->ar_bspstore;
 	ubs_end = ia64_rse_skip_regs(bspstore, on_kbs);
-	bsp     = ia64_rse_skip_regs(ubs_end, -nlocals);
-	addr    = slot = ia64_rse_skip_regs(bsp, r1 - 32);
+	bsp     = ia64_rse_skip_regs(ubs_end, -sof);
+	addr    = ia64_rse_skip_regs(bsp, r1 - 32);
 
-	DPRINT(("ubs_end=%p bsp=%p addr=%p slot=0x%lx\n",
-		(void *) ubs_end, (void *) bsp, (void *) addr, ia64_rse_slot_num(addr)));
+	DPRINT("ubs_end=%p bsp=%p addr=%px\n", (void *) ubs_end, (void *) bsp, (void *) addr);
 
-	ia64_poke(regs, current, (unsigned long)addr, val);
+	ia64_poke(current, (unsigned long) ubs_end, (unsigned long) addr, val);
 
-	/*
-	 * addr will now contain the address of the RNAT for the register
-	 */
-	addr = ia64_rse_rnat_addr(addr);
+	rnat_addr = ia64_rse_rnat_addr(addr);
 
-	ia64_peek(regs, current, (unsigned long)addr, &rnats);
-	DPRINT(("rnat @%p = 0x%lx nat=%d rnatval=%lx\n",
-		(void *) addr, rnats, nat, rnats &ia64_rse_slot_num(slot)));
-	
-	if (nat) {
-		rnats |= __IA64_UL(1) << ia64_rse_slot_num(slot);
-	} else {
-		rnats &= ~(__IA64_UL(1) << ia64_rse_slot_num(slot));
-	}
-	ia64_poke(regs, current, (unsigned long)addr, rnats);
+	ia64_peek(current, (unsigned long) ubs_end, (unsigned long) rnat_addr, &rnats);
+	DPRINT("rnat @%p = 0x%lx nat=%d old nat=%ld\n",
+	       (void *) rnat_addr, rnats, nat, (rnats >> ia64_rse_slot_num(addr)) & 1);
 
-	DPRINT(("rnat changed to @%p = 0x%lx\n", (void *) addr, rnats));
+	nat_mask = 1UL << ia64_rse_slot_num(addr);
+	if (nat)
+		rnats |=  nat_mask;
+	else
+		rnats &= ~nat_mask;
+	ia64_poke(current, (unsigned long) ubs_end, (unsigned long) rnat_addr, rnats);
+
+	DPRINT("rnat changed to @%p = 0x%lx\n", (void *) rnat_addr, rnats);
 }
 
 
 static void
-get_rse_reg(struct pt_regs *regs, unsigned long r1, unsigned long *val, int *nat)
+get_rse_reg (struct pt_regs *regs, unsigned long r1, unsigned long *val, int *nat)
 {
-	struct switch_stack *sw = (struct switch_stack *)regs - 1;
-	unsigned long *kbs	= (unsigned long *)current + IA64_RBS_OFFSET/8;
+	struct switch_stack *sw = (struct switch_stack *) regs - 1;
+	unsigned long *bsp, *addr, *rnat_addr, *ubs_end, *bspstore;
+	unsigned long *kbs = (void *) current + IA64_RBS_OFFSET;
+	unsigned long rnats, nat_mask;
 	unsigned long on_kbs;
-	long nlocals;
-	unsigned long *bsp, *addr, *ubs_end, *slot, *bspstore;
-	unsigned long rnats;
+	long sof = (regs->cr_ifs) & 0x7f;
 
-	/*
-	 * cr_ifs=[rv:ifm], ifm=[....:sof(6)]
-	 * nlocals=number of local registers in the faulting function
-	 */
-	nlocals = (regs->cr_ifs) & 0x7f;
+	DPRINT("r%lu, sw.bspstore=%lx pt.bspstore=%lx sof=%ld sol=%ld\n",
+	       r1, sw->ar_bspstore, regs->ar_bspstore, sof, (regs->cr_ifs >> 7) & 0x7f);
 
-	/*
-	 * save_switch_stack does a flushrs and saves bspstore.
-	 * on_kbs = actual number of registers saved on kernel backing store
-	 *          (taking into accound potential RNATs)
-	 *
-	 * Note that this number can be greater than nlocals if the dirty
-	 * parititions included more than one stack frame at the time we
-	 * switched to KBS
-	 */
-	on_kbs   = ia64_rse_num_regs(kbs, (unsigned long *)sw->ar_bspstore);
-	bspstore = (unsigned long *)regs->ar_bspstore;
+	if ((r1 - 32) >= sof) {
+		/* this should never happen, as the "rsvd register fault" has higher priority */
+		DPRINT("ignoring read from r%lu; only %lu registers are allocated!\n", r1, sof);
+		return;
+	}
+
+	on_kbs = ia64_rse_num_regs(kbs, (unsigned long *) sw->ar_bspstore);
+	addr = ia64_rse_skip_regs((unsigned long *) sw->ar_bspstore, -sof + (r1 - 32));
+	if (addr >= kbs) {
+		/* the register is on the kernel backing store: easy... */
+		*val = *addr;
+		if (nat) {
+			rnat_addr = ia64_rse_rnat_addr(addr);
+			if ((unsigned long) rnat_addr >= sw->ar_bspstore)
+				rnat_addr = &sw->ar_rnat;
+			nat_mask = 1UL << ia64_rse_slot_num(addr);
+			*nat = (*rnat_addr & nat_mask) != 0;
+		}
+		return;
+	}
 
 	/*
-	 * To simplify the logic, we calculate everything as if there was only
-	 * one backing store i.e., the user one (UBS). We let it to peek/poke
-	 * to figure out whether the register we're looking for really is
-	 * on the UBS or on KBS.
-	 *
-	 * regs->ar_bsptore = address of last register saved on UBS (before switch)
-	 *
-	 * ubs_end = virtual end of the UBS (if everything had been spilled there)
-	 *
-	 * We know that ubs_end is the point where the last register on the
-	 * stack frame we're interested in as been saved. So we need to walk
-	 * our way backward to figure out what the BSP "was" for that frame,
-	 * this will give us the location of r32. 
-	 *
-	 * bsp = "virtual UBS" address of r32 for our frame
-	 *
-	 * Finally, get compute the address of the register we're looking for
-	 * using bsp as our base (move up again).
-	 *
-	 * Please note that in our case, we know that the register is necessarily
-	 * on the KBS because we are only interested in the current frame at the moment
-	 * we got the exception i.e., bsp is not changed until we switch to KBS.
+	 * Avoid using user_mode() here: with "epc", we cannot use the privilege level to
+	 * infer whether the interrupt task was running on the kernel backing store.
 	 */
+	if (regs->r12 >= TASK_SIZE) {
+		DPRINT("ignoring kernel read of r%lu; register isn't on the RBS!", r1);
+		return;
+	}
+
+	bspstore = (unsigned long *)regs->ar_bspstore;
 	ubs_end = ia64_rse_skip_regs(bspstore, on_kbs);
-	bsp     = ia64_rse_skip_regs(ubs_end, -nlocals);
-	addr    = slot = ia64_rse_skip_regs(bsp, r1 - 32);
+	bsp     = ia64_rse_skip_regs(ubs_end, -sof);
+	addr    = ia64_rse_skip_regs(bsp, r1 - 32);
 
-	DPRINT(("ubs_end=%p bsp=%p addr=%p slot=0x%lx\n",
-		(void *) ubs_end, (void *) bsp, (void *) addr, ia64_rse_slot_num(addr)));
-	
-	ia64_peek(regs, current, (unsigned long)addr, val);
+	DPRINT("ubs_end=%p bsp=%p addr=%p\n", (void *) ubs_end, (void *) bsp, (void *) addr);
 
-	/*
-	 * addr will now contain the address of the RNAT for the register
-	 */
-	addr = ia64_rse_rnat_addr(addr);
+	ia64_peek(current, (unsigned long) ubs_end, (unsigned long) addr, val);
 
-	ia64_peek(regs, current, (unsigned long)addr, &rnats);
-	DPRINT(("rnat @%p = 0x%lx\n", (void *) addr, rnats));
-	
-	if (nat)
-		*nat = rnats >> ia64_rse_slot_num(slot) & 0x1;
+	if (nat) {
+		rnat_addr = ia64_rse_rnat_addr(addr);
+		nat_mask = 1UL << ia64_rse_slot_num(addr);
+
+		DPRINT("rnat @%p = 0x%lx\n", (void *) rnat_addr, rnats);
+
+		ia64_peek(current, (unsigned long) ubs_end, (unsigned long) rnat_addr, &rnats);
+		*nat = (rnats & nat_mask) != 0;
+	}
 }
 
 
 static void
-setreg(unsigned long regnum, unsigned long val, int nat, struct pt_regs *regs)
+setreg (unsigned long regnum, unsigned long val, int nat, struct pt_regs *regs)
 {
-	struct switch_stack *sw = (struct switch_stack *)regs -1;
+	struct switch_stack *sw = (struct switch_stack *) regs - 1;
 	unsigned long addr;
 	unsigned long bitmask;
 	unsigned long *unat;
 
-
 	/*
 	 * First takes care of stacked registers
 	 */
- 	if (regnum >= IA64_FIRST_STACKED_GR) {
+	if (regnum >= IA64_FIRST_STACKED_GR) {
 		set_rse_reg(regs, regnum, val, nat);
 		return;
 	}
 
 	/*
-	 * Using r0 as a target raises a General Exception fault which has 
-	 * higher priority than the Unaligned Reference fault.
-	 */ 
+	 * Using r0 as a target raises a General Exception fault which has higher priority
+	 * than the Unaligned Reference fault.
+	 */
 
 	/*
 	 * Now look at registers in [0-31] range and init correct UNAT
@@ -422,8 +439,8 @@
 		addr = (unsigned long)regs;
 		unat = &sw->caller_unat;
 	}
-	DPRINT(("tmp_base=%lx switch_stack=%s offset=%d\n",
-		addr, unat==&sw->ar_unat ? "yes":"no", GR_OFFS(regnum)));
+	DPRINT("tmp_base=%lx switch_stack=%s offset=%d\n",
+	       addr, unat==&sw->ar_unat ? "yes":"no", GR_OFFS(regnum));
 	/*
 	 * add offset from base of struct
 	 * and do it !
@@ -436,20 +453,20 @@
 	 * We need to clear the corresponding UNAT bit to fully emulate the load
 	 * UNAT bit_pos = GR[r3]{8:3} form EAS-2.4
 	 */
-	bitmask   = __IA64_UL(1) << (addr >> 3 & 0x3f);
-	DPRINT(("*0x%lx=0x%lx NaT=%d prev_unat @%p=%lx\n", addr, val, nat, (void *) unat, *unat));
+	bitmask   = 1UL << (addr >> 3 & 0x3f);
+	DPRINT("*0x%lx=0x%lx NaT=%d prev_unat @%p=%lx\n", addr, val, nat, (void *) unat, *unat);
 	if (nat) {
 		*unat |= bitmask;
 	} else {
 		*unat &= ~bitmask;
 	}
-	DPRINT(("*0x%lx=0x%lx NaT=%d new unat: %p=%lx\n", addr, val, nat, (void *) unat,*unat));
+	DPRINT("*0x%lx=0x%lx NaT=%d new unat: %p=%lx\n", addr, val, nat, (void *) unat,*unat);
 }
 
 #define IA64_FPH_OFFS(r) (r - IA64_FIRST_ROTATING_FR)
 
 static void
-setfpreg(unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs)
+setfpreg (unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs)
 {
 	struct switch_stack *sw = (struct switch_stack *)regs - 1;
 	unsigned long addr;
@@ -465,7 +482,7 @@
 	 *
 	 * For now, we are using approach (1).
 	 */
- 	if (regnum >= IA64_FIRST_ROTATING_FR) {
+	if (regnum >= IA64_FIRST_ROTATING_FR) {
 		ia64_sync_fph(current);
 		current->thread.fph[IA64_FPH_OFFS(regnum)] = *fpval;
 	} else {
@@ -477,18 +494,18 @@
 		} else {
 			addr = (unsigned long)regs;
 		}
-		
-		DPRINT(("tmp_base=%lx offset=%d\n", addr, FR_OFFS(regnum)));
+
+		DPRINT("tmp_base=%lx offset=%d\n", addr, FR_OFFS(regnum));
 
 		addr += FR_OFFS(regnum);
 		*(struct ia64_fpreg *)addr = *fpval;
 
 		/*
-	 	 * mark the low partition as being used now
+		 * mark the low partition as being used now
 		 *
 		 * It is highly unlikely that this bit is not already set, but
 		 * let's do it for safety.
-	 	 */
+		 */
 		regs->cr_ipsr |= IA64_PSR_MFL;
 	}
 }
@@ -497,40 +514,40 @@
  * Those 2 inline functions generate the spilled versions of the constant floating point
  * registers which can be used with stfX
  */
-static inline void 
-float_spill_f0(struct ia64_fpreg *final)
+static inline void
+float_spill_f0 (struct ia64_fpreg *final)
 {
 	__asm__ __volatile__ ("stf.spill [%0]=f0" :: "r"(final) : "memory");
 }
 
-static inline void 
-float_spill_f1(struct ia64_fpreg *final)
+static inline void
+float_spill_f1 (struct ia64_fpreg *final)
 {
 	__asm__ __volatile__ ("stf.spill [%0]=f1" :: "r"(final) : "memory");
 }
 
 static void
-getfpreg(unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs)
+getfpreg (unsigned long regnum, struct ia64_fpreg *fpval, struct pt_regs *regs)
 {
-	struct switch_stack *sw = (struct switch_stack *)regs -1;
+	struct switch_stack *sw = (struct switch_stack *) regs - 1;
 	unsigned long addr;
 
 	/*
-	 * From EAS-2.5: FPDisableFault has higher priority than 
-	 * Unaligned Fault. Thus, when we get here, we know the partition is 
+	 * From EAS-2.5: FPDisableFault has higher priority than
+	 * Unaligned Fault. Thus, when we get here, we know the partition is
 	 * enabled.
 	 *
 	 * When regnum > 31, the register is still live and we need to force a save
 	 * to current->thread.fph to get access to it.  See discussion in setfpreg()
 	 * for reasons and other ways of doing this.
 	 */
- 	if (regnum >= IA64_FIRST_ROTATING_FR) {
+	if (regnum >= IA64_FIRST_ROTATING_FR) {
 		ia64_flush_fph(current);
 		*fpval = current->thread.fph[IA64_FPH_OFFS(regnum)];
 	} else {
 		/*
 		 * f0 = 0.0, f1= 1.0. Those registers are constant and are thus
-	 	 * not saved, we must generate their spilled form on the fly
+		 * not saved, we must generate their spilled form on the fly
 		 */
 		switch(regnum) {
 		case 0:
@@ -546,8 +563,8 @@
 			addr =  FR_IN_SW(regnum) ? (unsigned long)sw
 						 : (unsigned long)regs;
 
-			DPRINT(("is_sw=%d tmp_base=%lx offset=0x%x\n",
-				FR_IN_SW(regnum), addr, FR_OFFS(regnum)));
+			DPRINT("is_sw=%d tmp_base=%lx offset=0x%x\n",
+			       FR_IN_SW(regnum), addr, FR_OFFS(regnum));
 
 			addr  += FR_OFFS(regnum);
 			*fpval = *(struct ia64_fpreg *)addr;
@@ -557,12 +574,12 @@
 
 
 static void
-getreg(unsigned long regnum, unsigned long *val, int *nat, struct pt_regs *regs)
+getreg (unsigned long regnum, unsigned long *val, int *nat, struct pt_regs *regs)
 {
-	struct switch_stack *sw = (struct switch_stack *)regs -1;
+	struct switch_stack *sw = (struct switch_stack *) regs - 1;
 	unsigned long addr, *unat;
 
- 	if (regnum >= IA64_FIRST_STACKED_GR) {
+	if (regnum >= IA64_FIRST_STACKED_GR) {
 		get_rse_reg(regs, regnum, val, nat);
 		return;
 	}
@@ -588,7 +605,7 @@
 		unat = &sw->caller_unat;
 	}
 
-	DPRINT(("addr_base=%lx offset=0x%x\n", addr,  GR_OFFS(regnum)));
+	DPRINT("addr_base=%lx offset=0x%x\n", addr,  GR_OFFS(regnum));
 
 	addr += GR_OFFS(regnum);
 
@@ -602,16 +619,16 @@
 }
 
 static void
-emulate_load_updates(update_t type, load_store_t *ld, struct pt_regs *regs, unsigned long ifa)
-{		
+emulate_load_updates (update_t type, load_store_t ld, struct pt_regs *regs, unsigned long ifa)
+{
 	/*
-	 * IMPORTANT: 
+	 * IMPORTANT:
 	 * Given the way we handle unaligned speculative loads, we should
 	 * not get to this point in the code but we keep this sanity check,
 	 * just in case.
 	 */
-	if (ld->x6_op == 1 || ld->x6_op == 3) {
-		printk(KERN_ERR __FUNCTION__": register update on speculative load, error\n");	
+	if (ld.x6_op == 1 || ld.x6_op == 3) {
+		printk(KERN_ERR __FUNCTION__": register update on speculative load, error\n");
 		die_if_kernel("unaligned reference on specualtive load with register update\n",
 			      regs, 30);
 	}
@@ -624,18 +641,18 @@
 	if (type == UPD_IMMEDIATE) {
 		unsigned long imm;
 
-		/* 
-	 	 * Load +Imm: ldXZ r1=[r3],imm(9)
-	 	 *
+		/*
+		 * Load +Imm: ldXZ r1=[r3],imm(9)
+		 *
 		 *
-	   	 * form imm9: [13:19] contain the first 7 bits
-      		 */		 
-		imm = ld->x << 7 | ld->imm;
+		 * form imm9: [13:19] contain the first 7 bits
+		 */
+		imm = ld.x << 7 | ld.imm;
 
 		/*
 		 * sign extend (1+8bits) if m set
 		 */
-		if (ld->m) imm |= SIGN_EXT9;
+		if (ld.m) imm |= SIGN_EXT9;
 
 		/*
 		 * ifa == r3 and we know that the NaT bit on r3 was clear so
@@ -643,109 +660,79 @@
 		 */
 		ifa += imm;
 
-		setreg(ld->r3, ifa, 0, regs);
+		setreg(ld.r3, ifa, 0, regs);
 
-		DPRINT(("ld.x=%d ld.m=%d imm=%ld r3=0x%lx\n", ld->x, ld->m, imm, ifa));
+		DPRINT("ld.x=%d ld.m=%d imm=%ld r3=0x%lx\n", ld.x, ld.m, imm, ifa);
 
-	} else if (ld->m) {
+	} else if (ld.m) {
 		unsigned long r2;
 		int nat_r2;
 
 		/*
 		 * Load +Reg Opcode: ldXZ r1=[r3],r2
 		 *
-		 * Note: that we update r3 even in the case of ldfX.a 
+		 * Note: that we update r3 even in the case of ldfX.a
 		 * (where the load does not happen)
 		 *
 		 * The way the load algorithm works, we know that r3 does not
 		 * have its NaT bit set (would have gotten NaT consumption
-		 * before getting the unaligned fault). So we can use ifa 
+		 * before getting the unaligned fault). So we can use ifa
 		 * which equals r3 at this point.
 		 *
 		 * IMPORTANT:
-	 	 * The above statement holds ONLY because we know that we
+		 * The above statement holds ONLY because we know that we
 		 * never reach this code when trying to do a ldX.s.
-		 * If we ever make it to here on an ldfX.s then 
+		 * If we ever make it to here on an ldfX.s then
 		 */
-		getreg(ld->imm, &r2, &nat_r2, regs);
-		
+		getreg(ld.imm, &r2, &nat_r2, regs);
+
 		ifa += r2;
-		
+
 		/*
 		 * propagate Nat r2 -> r3
 		 */
-		setreg(ld->r3, ifa, nat_r2, regs);
+		setreg(ld.r3, ifa, nat_r2, regs);
 
-		DPRINT(("imm=%d r2=%ld r3=0x%lx nat_r2=%d\n",ld->imm, r2, ifa, nat_r2));
+		DPRINT("imm=%d r2=%ld r3=0x%lx nat_r2=%d\n",ld.imm, r2, ifa, nat_r2);
 	}
 }
 
 
 static int
-emulate_load_int(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
+emulate_load_int (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
 {
-	unsigned long val;
-	unsigned int len = 1<< ld->x6_sz;
-
-	/*
-	 * the macro supposes sequential access (which is the case)
-	 * if the first byte is an invalid address we return here. Otherwise
-	 * there is a guard page at the top of the user's address page and 
-	 * the first access would generate a NaT consumption fault and return
-	 * with a SIGSEGV, which is what we want.
-	 *
-	 * Note: the first argument is ignored 
-	 */
-	if (access_ok(VERIFY_READ, (void *)ifa, len) < 0) {
-		DPRINT(("verify area failed on %lx\n", ifa));
-		return -1;
-	}
+	unsigned int len = 1 << ld.x6_sz;
 
 	/*
 	 * r0, as target, doesn't need to be checked because Illegal Instruction
 	 * faults have higher priority than unaligned faults.
 	 *
-	 * r0 cannot be found as the base as it would never generate an 
+	 * r0 cannot be found as the base as it would never generate an
 	 * unaligned reference.
 	 */
 
 	/*
-	 * ldX.a we don't try to emulate anything but we must
-	 * invalidate the ALAT entry.
+	 * ldX.a we don't try to emulate anything but we must invalidate the ALAT entry.
 	 * See comment below for explanation on how we handle ldX.a
 	 */
-	if (ld->x6_op != 0x2) {
-		/*
-		 * we rely on the macros in unaligned.h for now i.e.,
-		 * we let the compiler figure out how to read memory gracefully.
-		 *
-		 * We need this switch/case because the way the inline function
-		 * works. The code is optimized by the compiler and looks like
-		 * a single switch/case.
-		 */
-		switch(len) {
-			case 2:
-				val = ia64_get_unaligned((void *)ifa, 2);
-				break;
-			case 4:
-				val = ia64_get_unaligned((void *)ifa, 4);
-				break;
-			case 8:
-				val = ia64_get_unaligned((void *)ifa, 8);
-				break;
-			default:
-				DPRINT(("unknown size: x6=%d\n", ld->x6_sz));
-				return -1;
-		}
+	if (ld.x6_op != 0x2) {
+		unsigned long val = 0;
 
-		setreg(ld->r1, val, 0, regs);
+		if (len != 2 && len != 4 && len != 8) {
+			DPRINT("unknown size: x6=%d\n", ld.x6_sz);
+			return -1;
+		}
+		/* this assumes little-endian byte-order: */
+		if (copy_from_user(&val, (void *) ifa, len))
+		    return -1;
+		setreg(ld.r1, val, 0, regs);
 	}
 
 	/*
 	 * check for updates on any kind of loads
 	 */
-	if (ld->op == 0x5 || ld->m)
-		emulate_load_updates(ld->op == 0x5 ? UPD_IMMEDIATE: UPD_REG, ld, regs, ifa);
+	if (ld.op == 0x5 || ld.m)
+		emulate_load_updates(ld.op == 0x5 ? UPD_IMMEDIATE: UPD_REG, ld, regs, ifa);
 
 	/*
 	 * handling of various loads (based on EAS2.4):
@@ -753,7 +740,6 @@
 	 * ldX.acq (ordered load):
 	 *	- acquire semantics would have been used, so force fence instead.
 	 *
-	 *
 	 * ldX.c.clr (check load and clear):
 	 *	- if we get to this handler, it's because the entry was not in the ALAT.
 	 *	  Therefore the operation reverts to a normal load
@@ -764,15 +750,15 @@
 	 * ldX.c.clr.acq (ordered check load and clear):
 	 *	- same as above for c.clr part. The load needs to have acquire semantics. So
 	 *	  we use the fence semantics which is stronger and thus ensures correctness.
-	 *	
+	 *
 	 * ldX.a (advanced load):
-	 *	- suppose ldX.a r1=[r3]. If we get to the unaligned trap it's because the 
-	 * 	  address doesn't match requested size alignement. This means that we would 
+	 *	- suppose ldX.a r1=[r3]. If we get to the unaligned trap it's because the
+	 *	  address doesn't match requested size alignement. This means that we would
 	 *	  possibly need more than one load to get the result.
 	 *
 	 *	  The load part can be handled just like a normal load, however the difficult
 	 *	  part is to get the right thing into the ALAT. The critical piece of information
-	 * 	  in the base address of the load & size. To do that, a ld.a must be executed,
+	 *	  in the base address of the load & size. To do that, a ld.a must be executed,
 	 *	  clearly any address can be pushed into the table by using ld1.a r1=[r3]. Now
 	 *	  if we use the same target register, we will be okay for the check.a instruction.
 	 *	  If we look at the store, basically a stX [r3]=r1 checks the ALAT  for any entry
@@ -791,7 +777,7 @@
 	 *		store & shift to temporary;
 	 *		ld1.a r1=[r3]
 	 *		store & shift to temporary;
-	 * 		r1=temporary
+	 *		r1=temporary
 	 *
 	 *	  So int this case, you would get the right value is r1 but the wrong info in
 	 *	  the ALAT.  Notice that you could do it in reverse to finish with address 3
@@ -815,7 +801,7 @@
 	 *	  So it's okay NOT to do any actual load on an unaligned ld.a. However the ALAT
 	 *	  must be invalidated for the register (so that's chck.a.*,ld.c.* don't pick up
 	 *	  a stale entry later) The register base update MUST also be performed.
-	 *	  
+	 *
 	 *	  Now what is the content of the register and its NaT bit in the case we don't
 	 *	  do the load ?  EAS2.4, says (in case an actual load is needed)
 	 *
@@ -828,40 +814,26 @@
 	 */
 
 	/*
-	 * when the load has the .acq completer then 
+	 * when the load has the .acq completer then
 	 * use ordering fence.
 	 */
-	if (ld->x6_op == 0x5 || ld->x6_op == 0xa)
+	if (ld.x6_op == 0x5 || ld.x6_op == 0xa)
 		mb();
 
 	/*
 	 * invalidate ALAT entry in case of advanced load
 	 */
-	if (ld->x6_op == 0x2)
-		invala_gr(ld->r1);
+	if (ld.x6_op == 0x2)
+		invala_gr(ld.r1);
 
 	return 0;
 }
 
 static int
-emulate_store_int(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
+emulate_store_int (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
 {
 	unsigned long r2;
-	unsigned int len = 1<< ld->x6_sz;
-	
-	/*
-	 * the macro supposes sequential access (which is the case)
-	 * if the first byte is an invalid address we return here. Otherwise
-	 * there is a guard page at the top of the user's address page and 
-	 * the first access would generate a NaT consumption fault and return
-	 * with a SIGSEGV, which is what we want.
-	 *
-	 * Note: the first argument is ignored 
-	 */
-	if (access_ok(VERIFY_WRITE, (void *)ifa, len) < 0) {
-		DPRINT(("verify area failed on %lx\n",ifa));
-		return -1;
-	}
+	unsigned int len = 1 << ld.x6_sz;
 
 	/*
 	 * if we get to this handler, Nat bits on both r3 and r2 have already
@@ -869,7 +841,7 @@
 	 *
 	 * extract the value to be stored
 	 */
-	getreg(ld->imm, &r2, 0, regs);
+	getreg(ld.imm, &r2, 0, regs);
 
 	/*
 	 * we rely on the macros in unaligned.h for now i.e.,
@@ -879,48 +851,43 @@
 	 * works. The code is optimized by the compiler and looks like
 	 * a single switch/case.
 	 */
-	DPRINT(("st%d [%lx]=%lx\n", len, ifa, r2));
+	DPRINT("st%d [%lx]=%lx\n", len, ifa, r2);
 
-	switch(len) {
-		case 2:
-			ia64_put_unaligned(r2, (void *)ifa, 2);
-			break;
-		case 4:
-			ia64_put_unaligned(r2, (void *)ifa, 4);
-			break;
-		case 8:
-			ia64_put_unaligned(r2, (void *)ifa, 8);
-			break;
-		default:
-			DPRINT(("unknown size: x6=%d\n", ld->x6_sz));
-			return -1;
+	if (len != 2 && len != 4 && len != 8) {
+		DPRINT("unknown size: x6=%d\n", ld.x6_sz);
+		return -1;
 	}
+
+	/* this assumes little-endian byte-order: */
+	if (copy_to_user((void *) ifa, &r2, len))
+		return -1;
+
 	/*
 	 * stX [r3]=r2,imm(9)
 	 *
 	 * NOTE:
-	 * ld->r3 can never be r0, because r0 would not generate an 
+	 * ld.r3 can never be r0, because r0 would not generate an
 	 * unaligned access.
 	 */
-	if (ld->op == 0x5) {
+	if (ld.op == 0x5) {
 		unsigned long imm;
 
 		/*
 		 * form imm9: [12:6] contain first 7bits
 		 */
-		imm = ld->x << 7 | ld->r1;
+		imm = ld.x << 7 | ld.r1;
 		/*
 		 * sign extend (8bits) if m set
 		 */
-		if (ld->m) imm |= SIGN_EXT9; 
+		if (ld.m) imm |= SIGN_EXT9;
 		/*
 		 * ifa == r3 (NaT is necessarily cleared)
 		 */
 		ifa += imm;
 
-		DPRINT(("imm=%lx r3=%lx\n", imm, ifa));
-	
-		setreg(ld->r3, ifa, 0, regs);
+		DPRINT("imm=%lx r3=%lx\n", imm, ifa);
+
+		setreg(ld.r3, ifa, 0, regs);
 	}
 	/*
 	 * we don't have alat_invalidate_multiple() so we need
@@ -931,7 +898,7 @@
 	/*
 	 * stX.rel: use fence instead of release
 	 */
-	if (ld->x6_op == 0xd)
+	if (ld.x6_op == 0xd)
 		mb();
 
 	return 0;
@@ -940,120 +907,108 @@
 /*
  * floating point operations sizes in bytes
  */
-static const unsigned short float_fsz[4]={
+static const unsigned char float_fsz[4]={
 	16, /* extended precision (e) */
 	8,  /* integer (8)            */
 	4,  /* single precision (s)   */
 	8   /* double precision (d)   */
 };
 
-static inline void 
-mem2float_extended(struct ia64_fpreg *init, struct ia64_fpreg *final)
+static inline void
+mem2float_extended (struct ia64_fpreg *init, struct ia64_fpreg *final)
 {
 	__asm__ __volatile__ ("ldfe f6=[%0];; stf.spill [%1]=f6"
 			      :: "r"(init), "r"(final) : "f6","memory");
 }
 
-static inline void 
-mem2float_integer(struct ia64_fpreg *init, struct ia64_fpreg *final)
+static inline void
+mem2float_integer (struct ia64_fpreg *init, struct ia64_fpreg *final)
 {
 	__asm__ __volatile__ ("ldf8 f6=[%0];; stf.spill [%1]=f6"
 			      :: "r"(init), "r"(final) : "f6","memory");
 }
 
-static inline void 
-mem2float_single(struct ia64_fpreg *init, struct ia64_fpreg *final)
+static inline void
+mem2float_single (struct ia64_fpreg *init, struct ia64_fpreg *final)
 {
 	__asm__ __volatile__ ("ldfs f6=[%0];; stf.spill [%1]=f6"
 			      :: "r"(init), "r"(final) : "f6","memory");
 }
 
-static inline void 
-mem2float_double(struct ia64_fpreg *init, struct ia64_fpreg *final)
+static inline void
+mem2float_double (struct ia64_fpreg *init, struct ia64_fpreg *final)
 {
 	__asm__ __volatile__ ("ldfd f6=[%0];; stf.spill [%1]=f6"
 			      :: "r"(init), "r"(final) : "f6","memory");
 }
 
-static inline void 
-float2mem_extended(struct ia64_fpreg *init, struct ia64_fpreg *final)
+static inline void
+float2mem_extended (struct ia64_fpreg *init, struct ia64_fpreg *final)
 {
 	__asm__ __volatile__ ("ldf.fill f6=[%0];; stfe [%1]=f6"
 			      :: "r"(init), "r"(final) : "f6","memory");
 }
 
-static inline void 
-float2mem_integer(struct ia64_fpreg *init, struct ia64_fpreg *final)
+static inline void
+float2mem_integer (struct ia64_fpreg *init, struct ia64_fpreg *final)
 {
 	__asm__ __volatile__ ("ldf.fill f6=[%0];; stf8 [%1]=f6"
 			      :: "r"(init), "r"(final) : "f6","memory");
 }
 
-static inline void 
-float2mem_single(struct ia64_fpreg *init, struct ia64_fpreg *final)
+static inline void
+float2mem_single (struct ia64_fpreg *init, struct ia64_fpreg *final)
 {
 	__asm__ __volatile__ ("ldf.fill f6=[%0];; stfs [%1]=f6"
 			      :: "r"(init), "r"(final) : "f6","memory");
 }
 
-static inline void 
-float2mem_double(struct ia64_fpreg *init, struct ia64_fpreg *final)
+static inline void
+float2mem_double (struct ia64_fpreg *init, struct ia64_fpreg *final)
 {
 	__asm__ __volatile__ ("ldf.fill f6=[%0];; stfd [%1]=f6"
 			      :: "r"(init), "r"(final) : "f6","memory");
 }
 
 static int
-emulate_load_floatpair(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
+emulate_load_floatpair (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
 {
 	struct ia64_fpreg fpr_init[2];
 	struct ia64_fpreg fpr_final[2];
-	unsigned long len = float_fsz[ld->x6_sz];
+	unsigned long len = float_fsz[ld.x6_sz];
 
-	if (access_ok(VERIFY_READ, (void *)ifa, len<<1) < 0) {
-		DPRINT(("verify area failed on %lx\n", ifa));
-		return -1;
-	}
 	/*
 	 * fr0 & fr1 don't need to be checked because Illegal Instruction
 	 * faults have higher priority than unaligned faults.
 	 *
-	 * r0 cannot be found as the base as it would never generate an 
+	 * r0 cannot be found as the base as it would never generate an
 	 * unaligned reference.
 	 */
 
-	/* 
+	/*
 	 * make sure we get clean buffers
 	 */
-	memset(&fpr_init,0, sizeof(fpr_init));
-	memset(&fpr_final,0, sizeof(fpr_final));
+	memset(&fpr_init, 0, sizeof(fpr_init));
+	memset(&fpr_final, 0, sizeof(fpr_final));
 
 	/*
 	 * ldfpX.a: we don't try to emulate anything but we must
 	 * invalidate the ALAT entry and execute updates, if any.
 	 */
-	if (ld->x6_op != 0x2) {
-		/*
-		 * does the unaligned access
-		 */
-		memcpy(&fpr_init[0], (void *)ifa, len);
-		memcpy(&fpr_init[1], (void *)(ifa+len), len);
+	if (ld.x6_op != 0x2) {
+		/* this assumes little-endian byte-order: */
 
-		DPRINT(("ld.r1=%d ld.imm=%d x6_sz=%d\n", ld->r1, ld->imm, ld->x6_sz));
-#ifdef DEBUG_UNALIGNED_TRAP
-		{ int i; char *c = (char *)&fpr_init;
-			printk("fpr_init= ");
-			for(i=0; i < len<<1; i++ ) {
-				printk("%02x ", c[i]&0xff);
-			}
-			printk("\n");
-		}
-#endif
+		if (copy_from_user(&fpr_init[0], (void *) ifa, len)
+		    || copy_from_user(&fpr_init[1], (void *) (ifa + len), len))
+			return -1;
+
+		DPRINT("ld.r1=%d ld.imm=%d x6_sz=%d\n", ld.r1, ld.imm, ld.x6_sz);
+		DDUMP("frp_init =", &fpr_init, 2*len);
 		/*
 		 * XXX fixme
-		 * Could optimize inlines by using ldfpX & 2 spills 
+		 * Could optimize inlines by using ldfpX & 2 spills
 		 */
-		switch( ld->x6_sz ) {
+		switch( ld.x6_sz ) {
 			case 0:
 				mem2float_extended(&fpr_init[0], &fpr_final[0]);
 				mem2float_extended(&fpr_init[1], &fpr_final[1]);
@@ -1071,15 +1026,7 @@
 				mem2float_double(&fpr_init[1], &fpr_final[1]);
 				break;
 		}
-#ifdef DEBUG_UNALIGNED_TRAP
-		{ int i; char *c = (char *)&fpr_final;
-			printk("fpr_final= ");
-			for(i=0; i < len<<1; i++ ) {
-				printk("%02x ", c[i]&0xff);
-			}
-			printk("\n");
-		}
-#endif
+		DDUMP("fpr_final =", &fpr_final, 2*len);
 		/*
 		 * XXX fixme
 		 *
@@ -1087,16 +1034,15 @@
 		 * use the storage from the saved context i.e., the actual final
 		 * destination (pt_regs, switch_stack or thread structure).
 		 */
-		setfpreg(ld->r1, &fpr_final[0], regs);
-		setfpreg(ld->imm, &fpr_final[1], regs);
+		setfpreg(ld.r1, &fpr_final[0], regs);
+		setfpreg(ld.imm, &fpr_final[1], regs);
 	}
 
 	/*
 	 * Check for updates: only immediate updates are available for this
 	 * instruction.
 	 */
-	if (ld->m) {
-
+	if (ld.m) {
 		/*
 		 * the immediate is implicit given the ldsz of the operation:
 		 * single: 8 (2x4) and for  all others it's 16 (2x8)
@@ -1104,57 +1050,45 @@
 		ifa += len<<1;
 
 		/*
-		 * IMPORTANT: 
+		 * IMPORTANT:
 		 * the fact that we force the NaT of r3 to zero is ONLY valid
 		 * as long as we don't come here with a ldfpX.s.
 		 * For this reason we keep this sanity check
 		 */
-		if (ld->x6_op == 1 || ld->x6_op == 3) {
-			printk(KERN_ERR "%s: register update on speculative load pair, error\n",
-			       __FUNCTION__);	
-		}
-
+		if (ld.x6_op == 1 || ld.x6_op == 3)
+			printk(KERN_ERR __FUNCTION__": register update on speculative load pair, "
+			       "error\n");
 
-		setreg(ld->r3, ifa, 0, regs);
+		setreg(ld.r3, ifa, 0, regs);
 	}
 
 	/*
 	 * Invalidate ALAT entries, if any, for both registers.
 	 */
-	if (ld->x6_op == 0x2) {
-		invala_fr(ld->r1);
-		invala_fr(ld->imm);
+	if (ld.x6_op == 0x2) {
+		invala_fr(ld.r1);
+		invala_fr(ld.imm);
 	}
 	return 0;
 }
 
 
 static int
-emulate_load_float(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
+emulate_load_float (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
 {
 	struct ia64_fpreg fpr_init;
 	struct ia64_fpreg fpr_final;
-	unsigned long len = float_fsz[ld->x6_sz];
+	unsigned long len = float_fsz[ld.x6_sz];
 
 	/*
-	 * check for load pair because our masking scheme is not fine grain enough
-	if (ld->x == 1) return emulate_load_floatpair(ifa,ld,regs);
-	 */
-
-	if (access_ok(VERIFY_READ, (void *)ifa, len) < 0) {
-		DPRINT(("verify area failed on %lx\n", ifa));
-		return -1;
-	}
-	/*
 	 * fr0 & fr1 don't need to be checked because Illegal Instruction
 	 * faults have higher priority than unaligned faults.
 	 *
-	 * r0 cannot be found as the base as it would never generate an 
+	 * r0 cannot be found as the base as it would never generate an
 	 * unaligned reference.
 	 */
 
-
-	/* 
+	/*
 	 * make sure we get clean buffers
 	 */
 	memset(&fpr_init,0, sizeof(fpr_init));
@@ -1165,27 +1099,16 @@
 	 * invalidate the ALAT entry.
 	 * See comments in ldX for descriptions on how the various loads are handled.
 	 */
-	if (ld->x6_op != 0x2) {
-
-		/*
-		 * does the unaligned access
-		 */
-		memcpy(&fpr_init, (void *)ifa, len);
+	if (ld.x6_op != 0x2) {
+		if (copy_from_user(&fpr_init, (void *) ifa, len))
+			return -1;
 
-		DPRINT(("ld.r1=%d x6_sz=%d\n", ld->r1, ld->x6_sz));
-#ifdef DEBUG_UNALIGNED_TRAP
-		{ int i; char *c = (char *)&fpr_init;
-			printk("fpr_init= ");
-			for(i=0; i < len; i++ ) {
-				printk("%02x ", c[i]&0xff);
-			}
-			printk("\n");
-		}
-#endif
+		DPRINT("ld.r1=%d x6_sz=%d\n", ld.r1, ld.x6_sz);
+		DDUMP("fpr_init =", &fpr_init, len);
 		/*
 		 * we only do something for x6_op={0,8,9}
 		 */
-		switch( ld->x6_sz ) {
+		switch( ld.x6_sz ) {
 			case 0:
 				mem2float_extended(&fpr_init, &fpr_final);
 				break;
@@ -1199,15 +1122,7 @@
 				mem2float_double(&fpr_init, &fpr_final);
 				break;
 		}
-#ifdef DEBUG_UNALIGNED_TRAP
-		{ int i; char *c = (char *)&fpr_final;
-			printk("fpr_final= ");
-			for(i=0; i < len; i++ ) {
-				printk("%02x ", c[i]&0xff);
-			}
-			printk("\n");
-		}
-#endif
+		DDUMP("fpr_final =", &fpr_final, len);
 		/*
 		 * XXX fixme
 		 *
@@ -1215,66 +1130,51 @@
 		 * use the storage from the saved context i.e., the actual final
 		 * destination (pt_regs, switch_stack or thread structure).
 		 */
-		setfpreg(ld->r1, &fpr_final, regs);
+		setfpreg(ld.r1, &fpr_final, regs);
 	}
 
 	/*
 	 * check for updates on any loads
 	 */
-	if (ld->op == 0x7 || ld->m)
-		emulate_load_updates(ld->op == 0x7 ? UPD_IMMEDIATE: UPD_REG, ld, regs, ifa);
+	if (ld.op == 0x7 || ld.m)
+		emulate_load_updates(ld.op == 0x7 ? UPD_IMMEDIATE: UPD_REG, ld, regs, ifa);
 
 	/*
 	 * invalidate ALAT entry in case of advanced floating point loads
 	 */
-	if (ld->x6_op == 0x2)
-		invala_fr(ld->r1);
+	if (ld.x6_op == 0x2)
+		invala_fr(ld.r1);
 
 	return 0;
 }
 
 
 static int
-emulate_store_float(unsigned long ifa, load_store_t *ld, struct pt_regs *regs)
+emulate_store_float (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
 {
 	struct ia64_fpreg fpr_init;
 	struct ia64_fpreg fpr_final;
-	unsigned long len = float_fsz[ld->x6_sz];
-	
-	/*
-	 * the macro supposes sequential access (which is the case)
-	 * if the first byte is an invalid address we return here. Otherwise
-	 * there is a guard page at the top of the user's address page and 
-	 * the first access would generate a NaT consumption fault and return
-	 * with a SIGSEGV, which is what we want.
-	 *
-	 * Note: the first argument is ignored 
-	 */
-	if (access_ok(VERIFY_WRITE, (void *)ifa, len) < 0) {
-		DPRINT(("verify area failed on %lx\n",ifa));
-		return -1;
-	}
+	unsigned long len = float_fsz[ld.x6_sz];
 
-	/* 
+	/*
 	 * make sure we get clean buffers
 	 */
 	memset(&fpr_init,0, sizeof(fpr_init));
 	memset(&fpr_final,0, sizeof(fpr_final));
 
-
 	/*
 	 * if we get to this handler, Nat bits on both r3 and r2 have already
 	 * been checked. so we don't need to do it
 	 *
 	 * extract the value to be stored
 	 */
-	getfpreg(ld->imm, &fpr_init, regs);
+	getfpreg(ld.imm, &fpr_init, regs);
 	/*
 	 * during this step, we extract the spilled registers from the saved
 	 * context i.e., we refill. Then we store (no spill) to temporary
 	 * aligned location
 	 */
-	switch( ld->x6_sz ) {
+	switch( ld.x6_sz ) {
 		case 0:
 			float2mem_extended(&fpr_init, &fpr_final);
 			break;
@@ -1288,56 +1188,40 @@
 			float2mem_double(&fpr_init, &fpr_final);
 			break;
 	}
-	DPRINT(("ld.r1=%d x6_sz=%d\n", ld->r1, ld->x6_sz));
-#ifdef DEBUG_UNALIGNED_TRAP
-		{ int i; char *c = (char *)&fpr_init;
-			printk("fpr_init= ");
-			for(i=0; i < len; i++ ) {
-				printk("%02x ", c[i]&0xff);
-			}
-			printk("\n");
-		}
-		{ int i; char *c = (char *)&fpr_final;
-			printk("fpr_final= ");
-			for(i=0; i < len; i++ ) {
-				printk("%02x ", c[i]&0xff);
-			}
-			printk("\n");
-		}
-#endif
+	DPRINT("ld.r1=%d x6_sz=%d\n", ld.r1, ld.x6_sz);
+	DDUMP("fpr_init =", &fpr_init, len);
+	DDUMP("fpr_final =", &fpr_final, len);
 
-	/*
-	 * does the unaligned store
-	 */
-	memcpy((void *)ifa, &fpr_final, len);
+	if (copy_to_user((void *) ifa, &fpr_final, len))
+		return -1;
 
 	/*
 	 * stfX [r3]=r2,imm(9)
 	 *
 	 * NOTE:
-	 * ld->r3 can never be r0, because r0 would not generate an 
+	 * ld.r3 can never be r0, because r0 would not generate an
 	 * unaligned access.
 	 */
-	if (ld->op == 0x7) {
+	if (ld.op == 0x7) {
 		unsigned long imm;
 
 		/*
 		 * form imm9: [12:6] contain first 7bits
 		 */
-		imm = ld->x << 7 | ld->r1;
+		imm = ld.x << 7 | ld.r1;
 		/*
 		 * sign extend (8bits) if m set
 		 */
-		if (ld->m)
-			imm |= SIGN_EXT9; 
+		if (ld.m)
+			imm |= SIGN_EXT9;
 		/*
 		 * ifa == r3 (NaT is necessarily cleared)
 		 */
 		ifa += imm;
 
-		DPRINT(("imm=%lx r3=%lx\n", imm, ifa));
-	
-		setreg(ld->r3, ifa, 0, regs);
+		DPRINT("imm=%lx r3=%lx\n", imm, ifa);
+
+		setreg(ld.r3, ifa, 0, regs);
 	}
 	/*
 	 * we don't have alat_invalidate_multiple() so we need
@@ -1348,132 +1232,106 @@
 	return 0;
 }
 
-void
-ia64_handle_unaligned(unsigned long ifa, struct pt_regs *regs)
+/*
+ * Make sure we log the unaligned access, so that user/sysadmin can notice it and
+ * eventually fix the program.  However, we don't want to do that for every access so we
+ * pace it with jiffies.  This isn't really MP-safe, but it doesn't really have to be
+ * either...
+ */
+static int
+within_logging_rate_limit (void)
 {
-	static unsigned long unalign_count;
-	static long last_time;
+	static unsigned long count, last_time;
 
+	if (jiffies - last_time > 5*HZ)
+		count = 0;
+	if (++count < 5) {
+		last_time = jiffies;
+		return 1;
+	}
+	return 0;
+
+}
+
+void
+ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
+{
+	struct exception_fixup fix = { 0 };
 	struct ia64_psr *ipsr = ia64_psr(regs);
-	unsigned long *bundle_addr;
+	mm_segment_t old_fs = get_fs();
+	unsigned long bundle[2];
 	unsigned long opcode;
-	unsigned long op;
-	load_store_t *insn;
+	struct siginfo si;
+	union {
+		unsigned long l;
+		load_store_t insn;
+	} u;
 	int ret = -1;
 
+	if (ia64_psr(regs)->be) {
+		/* we don't support big-endian accesses */
+		die_if_kernel("big-endian unaligned accesses are not supported", regs, 0);
+		goto force_sigbus;
+	}
+
 	/*
-	 * Unaligned references in the kernel could come from unaligned
-	 *   arguments to system calls.  We fault the user process in
-	 *   these cases and panic the kernel otherwise (the kernel should
-	 *   be fixed to not make unaligned accesses).
+	 * Treat kernel accesses for which there is an exception handler entry the same as
+	 * user-level unaligned accesses.  Otherwise, a clever program could trick this
+	 * handler into reading an arbitrary kernel addresses...
 	 */
 	if (!user_mode(regs)) {
-		const struct exception_table_entry *fix;
-
+#ifdef GAS_HAS_LOCAL_TAGS
+		fix = search_exception_table(regs->cr_iip + ia64_psr(regs)->ri);
+#else
 		fix = search_exception_table(regs->cr_iip);
-		if (fix) {
-			regs->r8 = -EFAULT;
-			if (fix->skip & 1) {
-				regs->r9 = 0;
-			}
-			regs->cr_iip += ((long) fix->skip) & ~15;
-			regs->cr_ipsr &= ~IA64_PSR_RI;	/* clear exception slot number */
-			return;
-		}
-		die_if_kernel("Unaligned reference while in kernel\n", regs, 30);
-		/* NOT_REACHED */
-	}
-	/*
-	 * For now, we don't support user processes running big-endian
-	 * which do unaligned accesses
-	 */
-	if (ia64_psr(regs)->be) {
-		struct siginfo si;
-
-		printk(KERN_ERR "%s(%d): big-endian unaligned access %016lx (ip=%016lx) not "
-		       "yet supported\n",
-		       current->comm, current->pid, ifa, regs->cr_iip + ipsr->ri);
-
-		si.si_signo = SIGBUS;
-		si.si_errno = 0;
-		si.si_code = BUS_ADRALN;
-		si.si_addr = (void *) ifa;
-		force_sig_info(SIGBUS, &si, current);
-		return;
-	}
-
-	if (current->thread.flags & IA64_THREAD_UAC_SIGBUS) {
-		struct siginfo si;
-
-		si.si_signo = SIGBUS;
-		si.si_errno = 0;
-		si.si_code = BUS_ADRALN;
-		si.si_addr = (void *) ifa;
-		force_sig_info(SIGBUS, &si, current);
-		return;
+#endif
 	}
-
-	if (!(current->thread.flags & IA64_THREAD_UAC_NOPRINT)) {
-		/*
-		 * Make sure we log the unaligned access, so that
-		 * user/sysadmin can notice it and eventually fix the
-		 * program.
-		 *
-		 * We don't want to do that for every access so we
-		 * pace it with jiffies.
-		 */
-		if (unalign_count > 5 && jiffies - last_time > 5*HZ)
-			unalign_count = 0;
-		if (++unalign_count < 5) {
+	if (user_mode(regs) || fix.cont) {
+		if ((current->thread.flags & IA64_THREAD_UAC_SIGBUS) != 0)
+			goto force_sigbus;
+
+		if (!(current->thread.flags & IA64_THREAD_UAC_NOPRINT)
+		    && within_logging_rate_limit())
+		{
 			char buf[200];	/* comm[] is at most 16 bytes... */
 			size_t len;
 
-			last_time = jiffies;
-			len = sprintf(buf, "%s(%d): unaligned access to 0x%016lx, ip=0x%016lx\n\r",
-				      current->comm, current->pid, ifa, regs->cr_iip + ipsr->ri);
+			len = sprintf(buf, "%s(%d): unaligned access to 0x%016lx, "
+				      "ip=0x%016lx\n\r", current->comm, current->pid,
+				      ifa, regs->cr_iip + ipsr->ri);
 			tty_write_message(current->tty, buf);
 			buf[len-1] = '\0';	/* drop '\r' */
-			printk("%s", buf);	/* guard against command names containing %s!! */
+			printk(KERN_WARNING "%s", buf);	/* watch for command names containing %s */
 		}
+	} else {
+		if (within_logging_rate_limit())
+			printk(KERN_WARNING "kernel unaligned access to 0x%016lx, ip=0x%016lx\n",
+			       ifa, regs->cr_iip + ipsr->ri);
+		set_fs(KERNEL_DS);
 	}
 
-	DPRINT(("iip=%lx ifa=%lx isr=%lx\n", regs->cr_iip, ifa, regs->cr_ipsr));
-	DPRINT(("ISR.ei=%d ISR.sp=%d\n", ipsr->ri, ipsr->it));
+	DPRINT("iip=%lx ifa=%lx isr=%lx (ei=%d, sp=%d)\n",
+	       regs->cr_iip, ifa, regs->cr_ipsr, ipsr->ri, ipsr->it);
 
-	bundle_addr = (unsigned long *)(regs->cr_iip);
+	if (__copy_from_user(bundle, (void *) regs->cr_iip, 16))
+		goto failure;
 
 	/*
 	 * extract the instruction from the bundle given the slot number
 	 */
-	switch ( ipsr->ri ) {
-		case 0: op = *bundle_addr >> 5;
-			break;
-
-		case 1: op = *bundle_addr >> 46 | (*(bundle_addr+1) & 0x7fffff)<<18;
-			break;
-
-		case 2: op = *(bundle_addr+1) >> 23;
-		 	break;
+	switch (ipsr->ri) {
+	      case 0: u.l = (bundle[0] >>  5); break;
+	      case 1: u.l = (bundle[0] >> 46) | (bundle[1] << 18); break;
+	      case 2: u.l = (bundle[1] >> 23); break;
 	}
+	opcode = (u.l >> IA64_OPCODE_SHIFT) & IA64_OPCODE_MASK;
 
-	insn   = (load_store_t *)&op;
-	opcode = op & IA64_OPCODE_MASK;
-
-	DPRINT(("opcode=%lx ld.qp=%d ld.r1=%d ld.imm=%d ld.r3=%d ld.x=%d ld.hint=%d "
-		"ld.x6=0x%x ld.m=%d ld.op=%d\n",
-		opcode,
-		insn->qp,
-		insn->r1,
-		insn->imm,
-		insn->r3,
-		insn->x,
-		insn->hint,
-		insn->x6_sz,
-		insn->m,
-		insn->op));
+	DPRINT("opcode=%lx ld.qp=%d ld.r1=%d ld.imm=%d ld.r3=%d ld.x=%d ld.hint=%d "
+	       "ld.x6=0x%x ld.m=%d ld.op=%d\n", opcode, u.insn.qp, u.insn.r1, u.insn.imm,
+	       u.insn.r3, u.insn.x, u.insn.hint, u.insn.x6_sz, u.insn.m, u.insn.op);
 
 	/*
-  	 * IMPORTANT:
+	 * IMPORTANT:
 	 * Notice that the swictch statement DOES not cover all possible instructions
 	 * that DO generate unaligned references. This is made on purpose because for some
 	 * instructions it DOES NOT make sense to try and emulate the access. Sometimes it
@@ -1483,104 +1341,124 @@
 	 *	load/store:
 	 *		- ldX.spill
 	 *		- stX.spill
-	 * 	Reason: RNATs are based on addresses
+	 *	Reason: RNATs are based on addresses
 	 *
 	 *	synchronization:
 	 *		- cmpxchg
 	 *		- fetchadd
 	 *		- xchg
-	 * 	Reason: ATOMIC operations cannot be emulated properly using multiple 
-	 * 	        instructions.
+	 *	Reason: ATOMIC operations cannot be emulated properly using multiple
+	 *	        instructions.
 	 *
 	 *	speculative loads:
 	 *		- ldX.sZ
-	 *	Reason: side effects, code must be ready to deal with failure so simpler 
-	 * 		to let the load fail.
+	 *	Reason: side effects, code must be ready to deal with failure so simpler
+	 *		to let the load fail.
 	 * ---------------------------------------------------------------------------------
 	 * XXX fixme
 	 *
 	 * I would like to get rid of this switch case and do something
 	 * more elegant.
 	 */
-	switch(opcode) {
-		case LDS_OP:
-		case LDSA_OP:
-		case LDS_IMM_OP:
-		case LDSA_IMM_OP:
-		case LDFS_OP:
-		case LDFSA_OP:
-		case LDFS_IMM_OP:
-			/*
-			 * The instruction will be retried with defered exceptions
-			 * turned on, and we should get Nat bit installed
-			 *
-			 * IMPORTANT:
-			 * When PSR_ED is set, the register & immediate update
-			 * forms are actually executed even though the operation
-			 * failed. So we don't need to take care of this.
-			 */
-			DPRINT(("forcing PSR_ED\n"));
-			regs->cr_ipsr |= IA64_PSR_ED;
-			return;
-
-		case LD_OP:
-		case LDA_OP:
-		case LDBIAS_OP:
-		case LDACQ_OP:
-		case LDCCLR_OP:
-		case LDCNC_OP:
-		case LDCCLRACQ_OP:
-		case LD_IMM_OP:
-		case LDA_IMM_OP:
-		case LDBIAS_IMM_OP:
-		case LDACQ_IMM_OP:
-		case LDCCLR_IMM_OP:
-		case LDCNC_IMM_OP:
-		case LDCCLRACQ_IMM_OP:
-			ret = emulate_load_int(ifa, insn, regs);
-			break;
-		case ST_OP:
-		case STREL_OP:
-		case ST_IMM_OP:
-		case STREL_IMM_OP:
-			ret = emulate_store_int(ifa, insn, regs);
-			break;
-		case LDF_OP:
-		case LDFA_OP:
-		case LDFCCLR_OP:
-		case LDFCNC_OP:
-		case LDF_IMM_OP:
-		case LDFA_IMM_OP:
-		case LDFCCLR_IMM_OP:
-		case LDFCNC_IMM_OP:
-			ret = insn->x ? 
-			      emulate_load_floatpair(ifa, insn, regs):
-			      emulate_load_float(ifa, insn, regs);
-			break;
-		case STF_OP:
-		case STF_IMM_OP:
-			ret = emulate_store_float(ifa, insn, regs);
-	}
-
-	DPRINT(("ret=%d\n", ret));
-	if (ret) {
-		struct siginfo si;
-
-		si.si_signo = SIGBUS;
-		si.si_errno = 0;
-		si.si_code = BUS_ADRALN;
-		si.si_addr = (void *) ifa;
-	        force_sig_info(SIGBUS, &si, current);
-	} else {
+	switch (opcode) {
+	      case LDS_OP:
+	      case LDSA_OP:
+	      case LDS_IMM_OP:
+	      case LDSA_IMM_OP:
+	      case LDFS_OP:
+	      case LDFSA_OP:
+	      case LDFS_IMM_OP:
 		/*
-	 	 * given today's architecture this case is not likely to happen
-	 	 * because a memory access instruction (M) can never be in the 
-	 	 * last slot of a bundle. But let's keep it for  now.
-	 	 */
-		if (ipsr->ri == 2)
-			regs->cr_iip += 16;
-		ipsr->ri = ++ipsr->ri & 3;
-	}
+		 * The instruction will be retried with deferred exceptions turned on, and
+		 * we should get Nat bit installed
+		 *
+		 * IMPORTANT: When PSR_ED is set, the register & immediate update forms
+		 * are actually executed even though the operation failed. So we don't
+		 * need to take care of this.
+		 */
+		DPRINT("forcing PSR_ED\n");
+		regs->cr_ipsr |= IA64_PSR_ED;
+		goto done;
+
+	      case LD_OP:
+	      case LDA_OP:
+	      case LDBIAS_OP:
+	      case LDACQ_OP:
+	      case LDCCLR_OP:
+	      case LDCNC_OP:
+	      case LDCCLRACQ_OP:
+	      case LD_IMM_OP:
+	      case LDA_IMM_OP:
+	      case LDBIAS_IMM_OP:
+	      case LDACQ_IMM_OP:
+	      case LDCCLR_IMM_OP:
+	      case LDCNC_IMM_OP:
+	      case LDCCLRACQ_IMM_OP:
+		ret = emulate_load_int(ifa, u.insn, regs);
+		break;
+
+	      case ST_OP:
+	      case STREL_OP:
+	      case ST_IMM_OP:
+	      case STREL_IMM_OP:
+		ret = emulate_store_int(ifa, u.insn, regs);
+		break;
+
+	      case LDF_OP:
+	      case LDFA_OP:
+	      case LDFCCLR_OP:
+	      case LDFCNC_OP:
+	      case LDF_IMM_OP:
+	      case LDFA_IMM_OP:
+	      case LDFCCLR_IMM_OP:
+	      case LDFCNC_IMM_OP:
+		if (u.insn.x)
+			ret = emulate_load_floatpair(ifa, u.insn, regs);
+		else
+			ret = emulate_load_float(ifa, u.insn, regs);
+		break;
+
+	      case STF_OP:
+	      case STF_IMM_OP:
+		ret = emulate_store_float(ifa, u.insn, regs);
+		break;
+
+	      default:
+		goto failure;
+	}
+	DPRINT("ret=%d\n", ret);
+	if (ret)
+		goto failure;
+
+	if (ipsr->ri == 2)
+		/*
+		 * given today's architecture this case is not likely to happen because a
+		 * memory access instruction (M) can never be in the last slot of a
+		 * bundle. But let's keep it for now.
+		 */
+		regs->cr_iip += 16;
+	ipsr->ri = (ipsr->ri + 1) & 0x3;
+
+	DPRINT("ipsr->ri=%d iip=%lx\n", ipsr->ri, regs->cr_iip);
+  done:
+	set_fs(old_fs);		/* restore original address limit */
+	return;
 
-	DPRINT(("ipsr->ri=%d iip=%lx\n", ipsr->ri, regs->cr_iip));
+  failure:
+	/* something went wrong... */
+	if (!user_mode(regs)) {
+		if (fix.cont) {
+			handle_exception(regs, fix);
+			goto done;
+		}
+		die_if_kernel("error during unaligned kernel access\n", regs, ret);
+		/* NOT_REACHED */
+	}
+  force_sigbus:
+	si.si_signo = SIGBUS;
+	si.si_errno = 0;
+	si.si_code = BUS_ADRALN;
+	si.si_addr = (void *) ifa;
+	force_sig_info(SIGBUS, &si, current);
+	goto done;
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/kernel/unwind.c linux/arch/ia64/kernel/unwind.c
--- v2.4.3/linux/arch/ia64/kernel/unwind.c	Tue Feb 13 14:13:43 2001
+++ linux/arch/ia64/kernel/unwind.c	Thu Apr  5 12:51:47 2001
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 1999-2000 Hewlett-Packard Co
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2001 Hewlett-Packard Co
+ * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 /*
  * This file implements call frame unwind support for the Linux
@@ -31,8 +31,6 @@
 
 #include <asm/unwind.h>
 
-#ifdef CONFIG_IA64_NEW_UNWIND
-
 #include <asm/delay.h>
 #include <asm/page.h>
 #include <asm/ptrace.h>
@@ -306,7 +304,7 @@
 		}
 	} else {
 		/* access a stacked register */
-		addr = ia64_rse_skip_regs((unsigned long *) info->bsp, regnum);
+		addr = ia64_rse_skip_regs((unsigned long *) info->bsp, regnum - 32);
 		nat_addr = ia64_rse_rnat_addr(addr);
 		if ((unsigned long) addr < info->regstk.limit
 		    || (unsigned long) addr >= info->regstk.top)
@@ -660,7 +658,7 @@
 	 */
 	if (sr->any_spills) {
 		off = sr->spill_offset;
-		alloc_spill_area(&off, 16, sr->curr.reg + UNW_REG_F2, sr->curr.reg + UNW_REG_F31); 
+		alloc_spill_area(&off, 16, sr->curr.reg + UNW_REG_F2, sr->curr.reg + UNW_REG_F31);
 		alloc_spill_area(&off,  8, sr->curr.reg + UNW_REG_B1, sr->curr.reg + UNW_REG_B5);
 		alloc_spill_area(&off,  8, sr->curr.reg + UNW_REG_R4, sr->curr.reg + UNW_REG_R7);
 	}
@@ -911,6 +909,10 @@
 	struct unw_reg_state *rs;
 
 	rs = alloc_reg_state();
+	if (!rs) {
+		printk("unwind: cannot stack!\n");
+		return;
+	}
 	memcpy(rs, &sr->curr, sizeof(*rs));
 	rs->label = label;
 	rs->next = sr->reg_state_list;
@@ -927,7 +929,7 @@
 	if (sr->when_target <= sr->region_start + MIN((int)t, sr->region_len - 1))
 		return 0;
 	if (qp > 0) {
-		if ((sr->pr_val & (1UL << qp)) == 0) 
+		if ((sr->pr_val & (1UL << qp)) == 0)
 			return 0;
 		sr->pr_mask |= (1UL << qp);
 	}
@@ -944,7 +946,7 @@
 
 	r = sr->curr.reg + decode_abreg(abreg, 0);
 	r->where = UNW_WHERE_NONE;
-	r->when = sr->region_start + MIN((int)t, sr->region_len - 1);
+	r->when = UNW_WHEN_NEVER;
 	r->val = 0;
 }
 
@@ -1443,12 +1445,17 @@
 		 * sp has been restored and all values on the memory stack below
 		 * psp also have been restored.
 		 */
-		sr.curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE;
 		sr.curr.reg[UNW_REG_PSP].val = 0;
+		sr.curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE;
+		sr.curr.reg[UNW_REG_PSP].when = UNW_WHEN_NEVER;
 		for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r)
 			if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10)
 			    || r->where == UNW_WHERE_SPREL)
+			{
+				r->val = 0;
 				r->where = UNW_WHERE_NONE;
+				r->when = UNW_WHEN_NEVER;
+			}
 	}
 
 	script->flags = sr.flags;
@@ -1477,7 +1484,7 @@
 			      case UNW_WHERE_PSPREL: printk("[psp+0x%lx]", r->val); break;
 			      case UNW_WHERE_NONE:
 				printk("%s+0x%lx", unw.preg_name[r - sr.curr.reg], r->val);
-				break; 
+				break;
 			      default:		     printk("BADWHERE(%d)", r->where); break;
 			}
 			printk("\t\t%d\n", r->when);
@@ -1604,7 +1611,9 @@
 
 		      case UNW_INSN_LOAD:
 #if UNW_DEBUG
-			if ((s[val] & (my_cpu_data.unimpl_va_mask | 0x7)) || s[val] < TASK_SIZE) {
+			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]);
 				break;
 			}
@@ -1636,7 +1645,7 @@
 	int have_write_lock = 0;
 	struct unw_script *scr;
 
-	if ((info->ip & (my_cpu_data.unimpl_va_mask | 0xf)) || info->ip < TASK_SIZE) {
+	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);
 		info->rp_loc = 0;
@@ -1672,7 +1681,7 @@
 	unsigned long ip, pr, num_regs;
 	STAT(unsigned long start, flags;)
 	int retval;
-	
+
 	STAT(local_irq_save(flags); ++unw.stat.api.unwinds; start = ia64_get_itc());
 
 	prev_ip = info->ip;
@@ -1818,140 +1827,14 @@
 	STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags));
 }
 
-#endif /* CONFIG_IA64_NEW_UNWIND */
-
 void
 unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t)
 {
 	struct switch_stack *sw = (struct switch_stack *) (t->thread.ksp + 16);
 
-#ifdef CONFIG_IA64_NEW_UNWIND
 	unw_init_frame_info(info, t, sw);
-#else
-	unsigned long sol, limit, top;
-
-	memset(info, 0, sizeof(*info));
-
-	sol = (sw->ar_pfs >> 7) & 0x7f;	/* size of locals */
-
-	limit = (unsigned long) t + IA64_RBS_OFFSET;
-	top   = sw->ar_bspstore;
-	if (top - (unsigned long) t >= IA64_STK_OFFSET)
-		top = limit;
-
-	info->regstk.limit = limit;
-	info->regstk.top   = top;
-	info->sw  = sw;
-	info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->regstk.top, -sol);
-	info->cfm_loc = &sw->ar_pfs;
-	info->ip  = sw->b0;
-#endif
 }
 
-void
-unw_init_from_current (struct unw_frame_info *info, struct pt_regs *regs)
-{
-#ifdef CONFIG_IA64_NEW_UNWIND
-	struct switch_stack *sw = (struct switch_stack *) regs - 1;
-
-	unw_init_frame_info(info, current, sw);
-	/* skip over interrupt frame: */
-	unw_unwind(info);
-#else
-	struct switch_stack *sw = (struct switch_stack *) regs - 1;
-	unsigned long sol, sof, *bsp, limit, top;
-
-	limit = (unsigned long) current + IA64_RBS_OFFSET;
-	top   = sw->ar_bspstore;
-	if (top - (unsigned long) current >= IA64_STK_OFFSET)
-		top = limit;
-
-	memset(info, 0, sizeof(*info));
-
-	sol = (sw->ar_pfs >> 7) & 0x7f;	/* size of frame */
-
-	/* this gives us the bsp top level frame (kdb interrupt frame): */
-	bsp = ia64_rse_skip_regs((unsigned long *) top, -sol);
-
-	/* now skip past the interrupt frame: */
-	sof = regs->cr_ifs & 0x7f;	/* size of frame */
-
-	info->regstk.limit = limit;
-	info->regstk.top   = top;
-	info->sw = sw;
-	info->bsp = (unsigned long) ia64_rse_skip_regs(bsp, -sof);
-	info->cfm_loc = &regs->cr_ifs;
-	info->ip  = regs->cr_iip;
-#endif
-}
-
-#ifndef CONFIG_IA64_NEW_UNWIND
-
-static unsigned long
-read_reg (struct unw_frame_info *info, int regnum, int *is_nat)
-{
-	unsigned long *addr, *rnat_addr, rnat;
-
-	addr = ia64_rse_skip_regs((unsigned long *) info->bsp, regnum);
-	if ((unsigned long) addr < info->regstk.limit
-	    || (unsigned long) addr >= info->regstk.top || ((long) addr & 0x7) != 0)
-	{
-		*is_nat = 1;
-		return 0xdeadbeefdeadbeef;
-	}
-	rnat_addr = ia64_rse_rnat_addr(addr);
-
-	if ((unsigned long) rnat_addr >= info->regstk.top)
-		rnat = info->sw->ar_rnat;
-	else
-		rnat = *rnat_addr;
-	*is_nat = (rnat & (1UL << ia64_rse_slot_num(addr))) != 0;
-	return *addr;
-}
-
-/*
- * On entry, info->regstk.top should point to the register backing
- * store for r32.
- */
-int
-unw_unwind (struct unw_frame_info *info)
-{
-	unsigned long sol, cfm = *info->cfm_loc;
-	int is_nat;
-
-	sol = (cfm >> 7) & 0x7f;	/* size of locals */
-
-	/*
-	 * In general, we would have to make use of unwind info to
-	 * unwind an IA-64 stack, but for now gcc uses a special
-	 * convention that makes this possible without full-fledged
-	 * unwindo info.  Specifically, we expect "rp" in the second
-	 * last, and "ar.pfs" in the last local register, so the
-	 * number of locals in a frame must be at least two.  If it's
-	 * less than that, we reached the end of the C call stack.
-	 */
-	if (sol < 2)
-		return -1;
-
-	info->ip = read_reg(info, sol - 2, &is_nat);
-	if (is_nat || (info->ip & (my_cpu_data.unimpl_va_mask | 0xf)))
-		/* reject let obviously bad addresses */
-		return -1;
-
-	info->cfm_loc = ia64_rse_skip_regs((unsigned long *) info->bsp, sol - 1);
-	cfm = read_reg(info, sol - 1, &is_nat);
-	if (is_nat)
-		return -1;
-
-	sol = (cfm >> 7) & 0x7f;
-
-	info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->bsp, -sol);
-	return 0;
-}
-#endif /* !CONFIG_IA64_NEW_UNWIND */
-
-#ifdef CONFIG_IA64_NEW_UNWIND
-
 static void
 init_unwind_table (struct unw_table *table, const char *name, unsigned long segment_base,
 		   unsigned long gp, void *table_start, void *table_end)
@@ -1979,7 +1862,7 @@
 		dprintk("unwind: ignoring attempt to insert empty unwind table\n");
 		return 0;
 	}
-	
+
 	table = kmalloc(sizeof(*table), GFP_USER);
 	if (!table)
 		return 0;
@@ -2052,12 +1935,10 @@
 
 	kfree(table);
 }
-#endif /* CONFIG_IA64_NEW_UNWIND */
 
 void
 unw_init (void)
 {
-#ifdef CONFIG_IA64_NEW_UNWIND
 	extern int ia64_unw_start, ia64_unw_end, __gp;
 	extern void unw_hash_index_t_is_too_narrow (void);
 	long i, off;
@@ -2093,5 +1974,4 @@
 
 	init_unwind_table(&unw.kernel_table, "kernel", KERNEL_START, (unsigned long) &__gp,
 			  &ia64_unw_start, &ia64_unw_end);
-#endif /* CONFIG_IA64_NEW_UNWIND */
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/Makefile linux/arch/ia64/lib/Makefile
--- v2.4.3/linux/arch/ia64/lib/Makefile	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/lib/Makefile	Thu Apr  5 12:51:47 2001
@@ -7,18 +7,18 @@
 
 L_TARGET = lib.a
 
+export-objs := io.o swiotlb.o
+
 obj-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o					\
 	__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o					\
 	checksum.o clear_page.o csum_partial_copy.o copy_page.o				\
 	copy_user.o clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o	\
-	flush.o do_csum.o								\
+	flush.o io.o do_csum.o								\
 	swiotlb.o
 
 ifneq ($(CONFIG_ITANIUM_ASTEP_SPECIFIC),y)
   obj-y += memcpy.o memset.o strlen.o
 endif
-
-export-objs += io.o
 
 IGNORE_FLAGS_OBJS =	__divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
 			__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/clear_page.S linux/arch/ia64/lib/clear_page.S
--- v2.4.3/linux/arch/ia64/lib/clear_page.S	Thu Jun 22 07:09:44 2000
+++ linux/arch/ia64/lib/clear_page.S	Thu Apr  5 12:51:47 2001
@@ -6,29 +6,24 @@
  *
  * Inputs:
  *	in0:	address of page
- * 
+ *
  * Output:
  * 	none
  *
- * Copyright (C) 1999-2000 Hewlett-Packard Co
+ * Copyright (C) 1999-2001 Hewlett-Packard Co
  * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #include <asm/asmmacro.h>
 #include <asm/page.h>
 
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
-
 GLOBAL_ENTRY(clear_page)
-	UNW(.prologue)
+	.prologue
 	alloc r11=ar.pfs,1,0,0,0
-	UNW(.save ar.lc, r16)
+	.save ar.lc, r16
 	mov r16=ar.lc		// slow
 
-	UNW(.body)
+	.body
 
 	mov r17=PAGE_SIZE/32-1	// -1 = repeat/until
 	;;
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/clear_user.S linux/arch/ia64/lib/clear_user.S
--- v2.4.3/linux/arch/ia64/lib/clear_user.S	Thu Jun 22 07:09:44 2000
+++ linux/arch/ia64/lib/clear_user.S	Thu Apr  5 12:51:47 2001
@@ -6,8 +6,8 @@
  *	in1:	length of buffer in bytes
  * Outputs:
  *	r8:	number of bytes that didn't get cleared due to a fault
- * 
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
+ *
+ * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
  * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
  */
 
@@ -51,27 +51,12 @@
 //	have side effects (same thing for writing).
 //
 
-// The label comes first because our store instruction contains a comma
-// and confuse the preprocessor otherwise
-//
-#define EX(y,x...)				\
-	.section __ex_table,"a";		\
-	data4 @gprel(99f);			\
-	data4 y-99f;				\
-	.previous;				\
-99:	x
-
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
-
 GLOBAL_ENTRY(__do_clear_user)
-	UNW(.prologue)
-	UNW(.save ar.pfs, saved_pfs)
- 	alloc	saved_pfs=ar.pfs,2,0,0,0
+	.prologue
+	.save ar.pfs, saved_pfs
+	alloc	saved_pfs=ar.pfs,2,0,0,0
 	cmp.eq p6,p0=r0,len		// check for zero length
-	UNW(.save ar.lc, saved_lc)
+	.save ar.lc, saved_lc
 	mov saved_lc=ar.lc		// preserve ar.lc (slow)
 	.body
 	;;				// avoid WAW on CFM
@@ -80,7 +65,7 @@
 (p6)	br.ret.spnt.few rp
 	;;
 	cmp.lt p6,p0=16,len		// if len > 16 then long memset
-	mov ar.lc=tmp			// initialize lc for small count 
+	mov ar.lc=tmp			// initialize lc for small count
 (p6)	br.cond.dptk.few long_do_clear
 	;;				// WAR on ar.lc
 	//
@@ -91,7 +76,7 @@
 	// the various counters compared to how long the loop is supposed
 	// to last on average does not make this solution viable.
 	//
-1:	
+1:
 	EX( .Lexit1, st1 [buf]=r0,1 )
 	adds len=-1,len			// countdown length using len
 	br.cloop.dptk.few 1b
@@ -99,7 +84,7 @@
 	//
 	// .Lexit4: comes from byte by byte loop
 	//	    len contains bytes left
-.Lexit1:			
+.Lexit1:
 	mov ret0=len			// faster than using ar.lc
 	mov ar.lc=saved_lc
 	br.ret.sptk.few rp		// end of short clear_user
@@ -110,7 +95,7 @@
 	// so we focus on alignment (no branches required)
 	//
 	// The use of len/len2 for countdown of the number of bytes left
-	// instead of ret0 is due to the fact that the exception code 
+	// instead of ret0 is due to the fact that the exception code
 	// changes the values of r8.
 	//
 long_do_clear:
@@ -131,10 +116,10 @@
 	EX( .Lexit3, (p6) st8 [buf]=r0,8 )	// 8-byte aligned
 (p6)	adds len=-8,len;;
 	shr.u cnt=len,4		// number of 128-bit (2x64bit) words
-	;;	
+	;;
 	cmp.eq p6,p0=r0,cnt
 	adds tmp=-1,cnt
-(p6)	br.cond.dpnt.few .dotail 	// we have less than 16 bytes left
+(p6)	br.cond.dpnt.few .dotail	// we have less than 16 bytes left
 	;;
 	adds buf2=8,buf			// setup second base pointer
 	mov ar.lc=tmp
@@ -143,32 +128,30 @@
 	//
 	// 16bytes/iteration core loop
 	//
-	// The second store can never generate a fault because 
+	// The second store can never generate a fault because
 	// we come into the loop only when we are 16-byte aligned.
 	// This means that if we cross a page then it will always be
 	// in the first store and never in the second.
 	//
-	// 
+	//
 	// We need to keep track of the remaining length. A possible (optimistic)
-	// way would be to ue ar.lc and derive how many byte were left by
+	// way would be to use ar.lc and derive how many byte were left by
 	// doing : left= 16*ar.lc + 16.  this would avoid the addition at
-	// every iteration. 
+	// every iteration.
 	// However we need to keep the synchronization point. A template
 	// M;;MB does not exist and thus we can keep the addition at no
 	// extra cycle cost (use a nop slot anyway). It also simplifies the
 	// (unlikely)  error recovery code
 	//
 
-2:					
-
-	EX(.Lexit3, st8 [buf]=r0,16 )
+2:	EX(.Lexit3, st8 [buf]=r0,16 )
 	;;				// needed to get len correct when error
 	st8 [buf2]=r0,16
-	adds len=-16,len		
+	adds len=-16,len
 	br.cloop.dptk.few 2b
 	;;
 	mov ar.lc=saved_lc
-	// 
+	//
 	// tail correction based on len only
 	//
 	// We alternate the use of len3,len2 to allow parallelism and correct
@@ -176,14 +159,14 @@
 	// The addition of len2/len3 does not cost anything more compared to
 	// the regular memset as we had empty slots.
 	//
-.dotail:				
+.dotail:
 	mov len2=len			// for parallelization of error handling
 	mov len3=len
-	tbit.nz p6,p0=len,3	
+	tbit.nz p6,p0=len,3
 	;;
 	EX( .Lexit2, (p6) st8 [buf]=r0,8 )	// at least 8 bytes
 (p6)	adds len3=-8,len2
-	tbit.nz p7,p6=len,2	
+	tbit.nz p7,p6=len,2
 	;;
 	EX( .Lexit2, (p7) st4 [buf]=r0,4 )	// at least 4 bytes
 (p7)	adds len2=-4,len3
@@ -207,8 +190,8 @@
 	//
 	//
 	// .Lexit2:
-	// 	if p6 -> coming from st8 or st2 : len2 contains what's left
-	// 	if p7 -> coming from st4 or st1 : len3 contains what's left
+	//	if p6 -> coming from st8 or st2 : len2 contains what's left
+	//	if p7 -> coming from st4 or st1 : len3 contains what's left
 	// We must restore lc/pr even though might not have been used.
 .Lexit2:
 	.pred.rel "mutex", p6, p7
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/copy_page.S linux/arch/ia64/lib/copy_page.S
--- v2.4.3/linux/arch/ia64/lib/copy_page.S	Thu Jun 22 07:09:44 2000
+++ linux/arch/ia64/lib/copy_page.S	Thu Apr  5 12:51:47 2001
@@ -3,14 +3,14 @@
  * Optimized version of the standard copy_page() function
  *
  * Based on comments from ddd. Try not to overflow write buffer.
- * 
+ *
  * Inputs:
- * 	in0:	address of target page
+ *	in0:	address of target page
  *	in1:	address of source page
  * Output:
- * 	no return value
+ *	no return value
  *
- * Copyright (C) 1999 Hewlett-Packard Co
+ * Copyright (C) 1999, 2001 Hewlett-Packard Co
  * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
  */
 #include <asm/asmmacro.h>
@@ -28,28 +28,23 @@
 #define tgt1		r22
 #define tgt2		r23
 
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
-
 GLOBAL_ENTRY(copy_page)
-	UNW(.prologue)
-	UNW(.save ar.pfs, saved_pfs)
+	.prologue
+	.save ar.pfs, saved_pfs
 	alloc saved_pfs=ar.pfs,3,((2*PIPE_DEPTH+7)&~7),0,((2*PIPE_DEPTH+7)&~7)
 
 	.rotr t1[PIPE_DEPTH], t2[PIPE_DEPTH]
 	.rotp p[PIPE_DEPTH]
 
-	UNW(.save ar.lc, saved_lc)
+	.save ar.lc, saved_lc
 	mov saved_lc=ar.lc	// save ar.lc ahead of time
-	UNW(.save pr, saved_pr)
+	.save pr, saved_pr
 	mov saved_pr=pr		// rotating predicates are preserved
 				// resgisters we must save.
-	UNW(.body)
+	.body
 
-	mov src1=in1		// initialize 1st stream source 
-	adds src2=8,in1		// initialize 2nd stream source 
+	mov src1=in1		// initialize 1st stream source
+	adds src2=8,in1		// initialize 2nd stream source
 	mov lcount=PAGE_SIZE/16-1 // as many 16bytes as there are on a page
 				  // -1 is because br.ctop is repeat/until
 
@@ -72,7 +67,7 @@
 	//
 	// The initialization of the prolog is done via the predicate registers:
 	// the choice of EPI DEPENDS on the depth of the pipeline (n).
-	// When lc > 0 pr63=1 and it is fed back into pr16 and pr16-pr62 
+	// When lc > 0 pr63=1 and it is fed back into pr16 and pr16-pr62
 	// are then shifted right at every iteration,
 	// Thus by initializing pr16=1 and the rest to 0 before the loop
 	// we get EPI=1 after n iterations.
@@ -87,7 +82,7 @@
 				// stores but no loads anymore
 	;;
 	mov pr=saved_pr,0xffffffffffff0000	// restore predicates
-	mov ar.pfs=saved_pfs	// restore ar.ec 
+	mov ar.pfs=saved_pfs	// restore ar.ec
 	mov ar.lc=saved_lc	// restore saved lc
 	br.ret.sptk.few rp	// bye...
 END(copy_page)
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/copy_user.S linux/arch/ia64/lib/copy_user.S
--- v2.4.3/linux/arch/ia64/lib/copy_user.S	Tue Mar  6 19:44:35 2001
+++ linux/arch/ia64/lib/copy_user.S	Thu Apr  5 12:51:47 2001
@@ -12,41 +12,25 @@
  *
  * Inputs:
  *	in0	address of source buffer
- * 	in1	address of destination buffer
+ *	in1	address of destination buffer
  *	in2	number of bytes to copy
  *
- * Outputs: 
- * 	ret0	0 in case of success. The number of bytes NOT copied in
- * 		case of error.
+ * Outputs:
+ *	ret0	0 in case of success. The number of bytes NOT copied in
+ *		case of error.
  *
  * Copyright (C) 2000 Hewlett-Packard Co
  * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com>
  *
  * Fixme:
  *	- handle the case where we have more than 16 bytes and the alignment
- * 	  are different.
+ *	  are different.
  *	- more benchmarking
- * 	- fix extraneous stop bit introduced by the EX() macro.
+ *	- fix extraneous stop bit introduced by the EX() macro.
  */
 
 #include <asm/asmmacro.h>
 
-// The label comes first because our store instruction contains a comma
-// and confuse the preprocessor otherwise
-//
-#undef DEBUG
-#ifdef DEBUG
-#define EX(y,x...)				\
-99:	x
-#else
-#define EX(y,x...)				\
-	.section __ex_table,"a";		\
-	data4 @gprel(99f);			\
-	data4 y-99f;				\
-	.previous;				\
-99:	x
-#endif
-
 //
 // Tuneable parameters
 //
@@ -85,13 +69,10 @@
 #define enddst		r29
 #define endsrc		r30
 #define saved_pfs	r31
- 	.text
- 	.psr	abi64
- 	.psr	lsb
 
 GLOBAL_ENTRY(__copy_user)
-	UNW(.prologue)
-	UNW(.save ar.pfs, saved_pfs)
+	.prologue
+	.save ar.pfs, saved_pfs
 	alloc saved_pfs=ar.pfs,3,((2*PIPE_DEPTH+7)&~7),0,((2*PIPE_DEPTH+7)&~7)
 
 	.rotr val1[PIPE_DEPTH],val2[PIPE_DEPTH]
@@ -102,16 +83,16 @@
 
 	;;			// RAW of cfm when len=0
 	cmp.eq p8,p0=r0,len	// check for zero length
-	UNW(.save ar.lc, saved_lc)
+	.save ar.lc, saved_lc
 	mov saved_lc=ar.lc	// preserve ar.lc (slow)
 (p8)	br.ret.spnt.few rp	// empty mempcy()
 	;;
 	add enddst=dst,len	// first byte after end of source
 	add endsrc=src,len	// first byte after end of destination
-	UNW(.save pr, saved_pr)
+	.save pr, saved_pr
 	mov saved_pr=pr		// preserve predicates
 
-	UNW(.body)
+	.body
 
 	mov dst1=dst		// copy because of rotation
 	mov ar.ec=PIPE_DEPTH
@@ -119,7 +100,7 @@
 
 	mov src1=src		// copy because of rotation
 	mov ar.lc=len2		// initialize lc for small count
-	cmp.lt p10,p7=COPY_BREAK,len	// if len > COPY_BREAK then long copy 
+	cmp.lt p10,p7=COPY_BREAK,len	// if len > COPY_BREAK then long copy
 
 	xor tmp=src,dst		// same alignment test prepare
 (p10)	br.cond.dptk.few long_copy_user
@@ -128,9 +109,8 @@
 	// Now we do the byte by byte loop with software pipeline
 	//
 	// p7 is necessarily false by now
-1:				
+1:
 	EX(failure_in_pipe1,(p16) ld1 val1[0]=[src1],1)
-
 	EX(failure_out,(EPI) st1 [dst1]=val1[PIPE_DEPTH-1],1)
 	br.ctop.dptk.few 1b
 	;;
@@ -148,10 +128,10 @@
 	and src2=0x7,src1				// src offset
 	and dst2=0x7,dst1				// dst offset
 	;;
-	// The basic idea is that we copy byte-by-byte at the head so 
-	// that we can reach 8-byte alignment for both src1 and dst1. 
-	// Then copy the body using software pipelined 8-byte copy, 
-	// shifting the two back-to-back words right and left, then copy 
+	// The basic idea is that we copy byte-by-byte at the head so
+	// that we can reach 8-byte alignment for both src1 and dst1.
+	// Then copy the body using software pipelined 8-byte copy,
+	// shifting the two back-to-back words right and left, then copy
 	// the tail by copying byte-by-byte.
 	//
 	// Fault handling. If the byte-by-byte at the head fails on the
@@ -162,18 +142,18 @@
 	// handled simply by failure_in_pipe1.
 	//
 	// The case p14 represents the source has more bytes in the
-	// the first word (by the shifted part), whereas the p15 needs to 
-	// copy some bytes from the 2nd word of the source that has the 
+	// the first word (by the shifted part), whereas the p15 needs to
+	// copy some bytes from the 2nd word of the source that has the
 	// tail of the 1st of the destination.
 	//
 
 	//
-	// Optimization. If dst1 is 8-byte aligned (not rarely), we don't need 
-	// to copy the head to dst1, to start 8-byte copy software pipleline. 
+	// Optimization. If dst1 is 8-byte aligned (not rarely), we don't need
+	// to copy the head to dst1, to start 8-byte copy software pipleline.
 	// We know src1 is not 8-byte aligned in this case.
 	//
 	cmp.eq p14,p15=r0,dst2
-(p15)	br.cond.spnt.few 1f				
+(p15)	br.cond.spnt.few 1f
 	;;
 	sub t1=8,src2
 	mov t2=src2
@@ -182,10 +162,10 @@
 	sub len1=len,t1					// set len1
 	;;
 	sub lshift=64,rshift
-	;; 
+	;;
 	br.cond.spnt.few word_copy_user
-	;; 
-1:			
+	;;
+1:
 	cmp.leu	p14,p15=src2,dst2
 	sub t1=dst2,src2
 	;;
@@ -196,30 +176,29 @@
 	;;
 	// For the case p14, we don't need to copy the shifted part to
 	// the 1st word of destination.
-	sub t2=8,t1	
+	sub t2=8,t1
 (p14)	sub word1=word1,t1
 	;;
 	sub len1=len,word1				// resulting len
 (p15)	shl rshift=t1,3					// in bits
 (p14)	shl rshift=t2,3
-	;; 
+	;;
 (p14)	sub len1=len1,t1
 	adds cnt=-1,word1
-	;; 
+	;;
 	sub lshift=64,rshift
 	mov ar.ec=PIPE_DEPTH
 	mov pr.rot=1<<16	// p16=true all others are false
 	mov ar.lc=cnt
-	;; 
-2:	
+	;;
+2:
 	EX(failure_in_pipe2,(p16) ld1 val1[0]=[src1],1)
-	;; 
 	EX(failure_out,(EPI) st1 [dst1]=val1[PIPE_DEPTH-1],1)
 	br.ctop.dptk.few 2b
 	;;
-	clrrrb	
-	;; 
-word_copy_user:		
+	clrrrb
+	;;
+word_copy_user:
 	cmp.gtu p9,p0=16,len1
 (p9)	br.cond.spnt.few 4f		// if (16 > len1) skip 8-byte copy
 	;;
@@ -227,7 +206,7 @@
 	;;
 	adds cnt=-1,cnt
 	;;
-	.pred.rel "mutex", p14, p15	
+	.pred.rel "mutex", p14, p15
 (p14)	sub src1=src1,t2
 (p15)	sub src1=src1,t1
 	//
@@ -237,23 +216,23 @@
 	mov ar.lc=cnt
 	mov ar.ec=PIPE_DEPTH
 	mov pr.rot=1<<16	// p16=true all others are false
-	;; 
+	;;
 3:
 	//
-	// The pipleline consists of 3 stages:	
+	// The pipleline consists of 3 stages:
 	// 1 (p16):	Load a word from src1
 	// 2 (EPI_1):	Shift right pair, saving to tmp
 	// 3 (EPI):	Store tmp to dst1
 	//
-	// To make it simple, use at least 2 (p16) loops to set up val1[n] 
+	// To make it simple, use at least 2 (p16) loops to set up val1[n]
 	// because we need 2 back-to-back val1[] to get tmp.
 	// Note that this implies EPI_2 must be p18 or greater.
-	// 
+	//
 
 #define EPI_1		p[PIPE_DEPTH-2]
 #define SWITCH(pred, shift)	cmp.eq pred,p0=shift,rshift
 #define CASE(pred, shift)	\
-	(pred)	br.cond.spnt.few copy_user_bit##shift	
+	(pred)	br.cond.spnt.few copy_user_bit##shift
 #define BODY(rshift)							\
 copy_user_bit##rshift:							\
 1:									\
@@ -267,11 +246,11 @@
 	//
 	// Since the instruction 'shrp' requires a fixed 128-bit value
 	// specifying the bits to shift, we need to provide 7 cases
-	// below. 
+	// below.
 	//
 	SWITCH(p6, 8)
 	SWITCH(p7, 16)
-	SWITCH(p8, 24)	
+	SWITCH(p8, 24)
 	SWITCH(p9, 32)
 	SWITCH(p10, 40)
 	SWITCH(p11, 48)
@@ -289,40 +268,40 @@
 	BODY(16)
 	BODY(24)
 	BODY(32)
-	BODY(40)		
+	BODY(40)
 	BODY(48)
 	BODY(56)
-	;; 
-.diff_align_do_tail:	
-	.pred.rel "mutex", p14, p15		
+	;;
+.diff_align_do_tail:
+	.pred.rel "mutex", p14, p15
 (p14)	sub src1=src1,t1
-(p14)	adds dst1=-8,dst1			
+(p14)	adds dst1=-8,dst1
 (p15)	sub dst1=dst1,t1
-	;; 
-4:	
+	;;
+4:
 	// Tail correction.
 	//
 	// The problem with this piplelined loop is that the last word is not
-	// loaded and thus parf of the last word written is not correct. 
+	// loaded and thus parf of the last word written is not correct.
 	// To fix that, we simply copy the tail byte by byte.
-	
+
 	sub len1=endsrc,src1,1
 	clrrrb
-	;; 
+	;;
 	mov ar.ec=PIPE_DEPTH
 	mov pr.rot=1<<16	// p16=true all others are false
 	mov ar.lc=len1
 	;;
-5:		
+5:
 	EX(failure_in_pipe1,(p16) ld1 val1[0]=[src1],1)
-	
 	EX(failure_out,(EPI) st1 [dst1]=val1[PIPE_DEPTH-1],1)
 	br.ctop.dptk.few 5b
 	;;
+	mov ar.lc=saved_lc
 	mov pr=saved_pr,0xffffffffffff0000
 	mov ar.pfs=saved_pfs
 	br.ret.dptk.few rp
-	
+
 	//
 	// Beginning of long mempcy (i.e. > 16 bytes)
 	//
@@ -353,6 +332,7 @@
 	// we have never executed the ld1, therefore st1 is not executed.
 	//
 	EX(failure_in1,(p8) ld4 val2[0]=[src1],4)	// 4-byte aligned
+	;;
 	EX(failure_out,(p6) st1 [dst1]=val1[0],1)
 	tbit.nz p9,p0=src1,3
 	;;
@@ -369,12 +349,12 @@
 	shr.u cnt=len1,4		// number of 128-bit (2x64bit) words
 	;;
 	EX(failure_out, (p9) st8 [dst1]=val2[1],8)
-	tbit.nz p6,p0=len1,3	
+	tbit.nz p6,p0=len1,3
 	cmp.eq p7,p0=r0,cnt
 	adds tmp=-1,cnt			// br.ctop is repeat/until
 (p7)	br.cond.dpnt.few .dotail	// we have less than 16 bytes left
 	;;
-	adds src2=8,src1	
+	adds src2=8,src1
 	adds dst2=8,dst1
 	mov ar.lc=tmp
 	;;
@@ -395,12 +375,12 @@
 	// No matter where we come from (loop or test) the src1 pointer
 	// is 16 byte aligned AND we have less than 16 bytes to copy.
 	//
-.dotail:			
+.dotail:
 	EX(failure_in1,(p6) ld8 val1[0]=[src1],8)	// at least 8 bytes
 	tbit.nz p7,p0=len1,2
 	;;
 	EX(failure_in1,(p7) ld4 val1[1]=[src1],4)	// at least 4 bytes
- 	tbit.nz p8,p0=len1,1
+	tbit.nz p8,p0=len1,1
 	;;
 	EX(failure_in1,(p8) ld2 val2[0]=[src1],2)	// at least 2 bytes
 	tbit.nz p9,p0=len1,0
@@ -430,7 +410,7 @@
 	//
 	//	  In the same loop iteration, the dst1 pointer does not directly
 	//	  reflect where the faulty load was.
-	//	  
+	//
 	//	- pipeline effect
 	//	  When you get a fault on load, you may have valid data from
 	//	  previous loads not yet store in transit. Such data must be
@@ -442,7 +422,7 @@
 	//	- we don't disrupt the pipeline, i.e. data in transit in
 	//	  the software pipeline will be eventually move to memory.
 	//	  We simply replace the load with a simple mov and keep the
-	//	  pipeline going. We can't really do this inline because 
+	//	  pipeline going. We can't really do this inline because
 	//	  p16 is always reset to 1 when lc > 0.
 	//
 failure_in_pipe1:
@@ -459,7 +439,7 @@
 
 	//
 	// This is the case where the byte by byte copy fails on the load
-	// when we copy the head. We need to finish the pipeline and copy 
+	// when we copy the head. We need to finish the pipeline and copy
 	// zeros for the rest of the destination. Since this happens
 	// at the top we still need to fill the body and tail.
 failure_in_pipe2:
@@ -471,7 +451,7 @@
 	;;
 	sub len=enddst,dst1,1		// precompute len
 	br.cond.dptk.few failure_in1bis
-	;; 
+	;;
 
 	//
 	// Here we handle the head & tail part when we check for alignment.
@@ -482,7 +462,7 @@
 	//
 	// However some simplifications are possible given the way
 	// things work.
-	// 
+	//
 	// 1) HEAD
 	// Theory of operation:
 	//
@@ -506,23 +486,23 @@
 	//
 	// Key point:
 	//	- if you fail on 1, 2, 4 then you have never executed any smaller
-	//	  size loads, e.g. failing ld4 means no ld1 nor ld2 executed 
+	//	  size loads, e.g. failing ld4 means no ld1 nor ld2 executed
 	//	  before.
 	//
 	// This allows us to simplify the cleanup code, because basically you
 	// only have to worry about "pending" stores in the case of a failing
-	// ld8(). Given the way the code is written today, this means only 
+	// ld8(). Given the way the code is written today, this means only
 	// worry about st2, st4. There we can use the information encapsulated
 	// into the predicates.
-	// 
+	//
 	// Other key point:
-	// 	- if you fail on the ld8 in the head, it means you went straight
+	//	- if you fail on the ld8 in the head, it means you went straight
 	//	  to it, i.e. 8byte alignment within an unexisting page.
 	// Again this comes from the fact that if you crossed just for the ld8 then
 	// you are 8byte aligned but also 16byte align, therefore you would
 	// either go for the 16byte copy loop OR the ld8 in the tail part.
 	// The combination ld1, ld2, ld4, ld8 where you fail on ld8 is impossible
-	// because it would mean you had 15bytes to copy in which case you 
+	// because it would mean you had 15bytes to copy in which case you
 	// would have defaulted to the byte by byte copy.
 	//
 	//
@@ -533,18 +513,18 @@
 	// Key point:
 	// This means that we either:
 	//		- are right on a page boundary
-	//	OR 
-	//		- are at more than 16 bytes from a page boundary with 
+	//	OR
+	//		- are at more than 16 bytes from a page boundary with
 	//		  at most 15 bytes to copy: no chance of crossing.
 	//
 	// This allows us to assume that if we fail on a load we haven't possibly
-	// executed any of the previous (tail) ones, so we don't need to do 
-	// any stores. For instance, if we fail on ld2, this means we had 
+	// executed any of the previous (tail) ones, so we don't need to do
+	// any stores. For instance, if we fail on ld2, this means we had
 	// 2 or 3 bytes left to copy and we did not execute the ld8 nor ld4.
 	//
-	// This means that we are in a situation similar the a fault in the 
-	// head part. That's nice! 
-	// 
+	// This means that we are in a situation similar the a fault in the
+	// head part. That's nice!
+	//
 failure_in1:
 //	sub ret0=enddst,dst1	// number of bytes to zero, i.e. not copied
 //	sub len=enddst,dst1,1
@@ -563,7 +543,7 @@
 	;;
 5:
 	st1 [dst1]=r0,1
-	br.cloop.dptk.few 5b	
+	br.cloop.dptk.few 5b
 	;;
 skip_loop:
 	mov pr=saved_pr,0xffffffffffff0000
@@ -574,7 +554,7 @@
 	//
 	// Here we simply restart the loop but instead
 	// of doing loads we fill the pipeline with zeroes
-	// We can't simply store r0 because we may have valid 
+	// We can't simply store r0 because we may have valid
 	// data in transit in the pipeline.
 	// ar.lc and ar.ec are setup correctly at this point
 	//
@@ -593,7 +573,7 @@
 	;;
 	cmp.ne p6,p0=dst1,enddst	// Do we need to finish the tail ?
 	sub len=enddst,dst1,1		// precompute len
-(p6)	br.cond.dptk.few failure_in1bis	
+(p6)	br.cond.dptk.few failure_in1bis
 	;;
 	mov pr=saved_pr,0xffffffffffff0000
 	mov ar.lc=saved_lc
@@ -610,13 +590,13 @@
 	;;
 	cmp.ne p6,p0=dst1,enddst	// Do we need to finish the tail ?
 	sub len=enddst,dst1,1		// precompute len
-(p6)	br.cond.dptk.few failure_in1bis	
+(p6)	br.cond.dptk.few failure_in1bis
 	;;
 	mov pr=saved_pr,0xffffffffffff0000
 	mov ar.lc=saved_lc
 	mov ar.pfs=saved_pfs
 	br.ret.dptk.few rp
-	
+
 	//
 	// handling of failures on stores: that's the easy part
 	//
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/csum_partial_copy.c linux/arch/ia64/lib/csum_partial_copy.c
--- v2.4.3/linux/arch/ia64/lib/csum_partial_copy.c	Sun Feb  6 18:42:40 2000
+++ linux/arch/ia64/lib/csum_partial_copy.c	Thu Apr  5 12:51:47 2001
@@ -1,6 +1,6 @@
 /*
  * Network Checksum & Copy routine
- * 
+ *
  * Copyright (C) 1999 Hewlett-Packard Co
  * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
  *
@@ -107,22 +107,18 @@
 do_csum_partial_copy_from_user (const char *src, char *dst, int len,
 				unsigned int psum, int *errp)
 {
-	const unsigned char *psrc = src;
 	unsigned long result;
-	int cplen = len;
-	int r = 0;
 
 	/* XXX Fixme
-	 * for now we separate the copy from checksum for obvious 
+	 * for now we separate the copy from checksum for obvious
 	 * alignment difficulties. Look at the Alpha code and you'll be
 	 * scared.
 	 */
 
-	while ( cplen-- ) r |=__get_user(*dst++,psrc++);
-
-	if ( r && errp ) *errp = r;
+	if (__copy_from_user(dst, src, len) != 0 && errp)
+		*errp = -EFAULT;
 
-	result = do_csum(src, len);
+	result = do_csum(dst, len);
 
 	/* add in old sum, and carry.. */
 	result += psum;
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/do_csum.S linux/arch/ia64/lib/do_csum.S
--- v2.4.3/linux/arch/ia64/lib/do_csum.S	Thu Jun 22 07:09:44 2000
+++ linux/arch/ia64/lib/do_csum.S	Thu Apr  5 12:51:47 2001
@@ -7,8 +7,8 @@
  * Inputs:
  *	in0: address of buffer to checksum (char *)
  *	in1: length of the buffer (int)
- * 
- * Copyright (C) 1999 Hewlett-Packard Co
+ *
+ * Copyright (C) 1999, 2001 Hewlett-Packard Co
  * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
  *
  */
@@ -39,7 +39,7 @@
 //	This version avoids synchronization in the core loop by also using a
 //	pipeline for the accumulation of the checksum in result[].
 //
-//	 p[]     
+//	 p[]
 //	|---|
 //     0|   | r32 : new value loaded in pipeline
 //	|---|
@@ -50,7 +50,7 @@
 //     3|   | r35 : previous value added to checksum (previous iteration)
 //      |---|
 //
-//	result[] 
+//	result[]
 //	|---|
 //     0|   | r36 : new checksum
 //	|---|
@@ -68,7 +68,7 @@
 //	- Maybe another algorithm which would take care of the folding at the
 //	  end in a different manner
 //	- Work with people more knowledgeable than me on the network stack
-//	  to figure out if we could not split the function depending on the 
+//	  to figure out if we could not split the function depending on the
 //	  type of packet or alignment we get. Like the ip_fast_csum() routine
 //	  where we know we have at least 20bytes worth of data to checksum.
 //	- Look at RFCs about checksums to see whether or not we can do better
@@ -94,17 +94,11 @@
 #define buf		in0
 #define len		in1
 
-
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
-
 // unsigned long do_csum(unsigned char *buf,int len)
 
 GLOBAL_ENTRY(do_csum)
-	UNW(.prologue)
-	UNW(.save ar.pfs, saved_pfs)
+	.prologue
+	.save ar.pfs, saved_pfs
 	alloc saved_pfs=ar.pfs,2,8,0,8
 
 	.rotr p[4], result[3]
@@ -126,7 +120,7 @@
 	;;
 	and lastoff=7,tmp1	// how many bytes off for last element
 	andcm last=tmp2,tmp3	// address of word containing last byte
-	UNW(.save pr, saved_pr)
+	.save pr, saved_pr
 	mov saved_pr=pr		// preserve predicates (rotation)
 	;;
 	sub tmp3=last,first	// tmp3=distance from first to last
@@ -144,14 +138,14 @@
 	;;
 
 	shl tmp1=tmp1,3		// number of bits
-	shl hmask=hmask,tmp2 	// build head mask, mask off [0,firstoff[
+	shl hmask=hmask,tmp2	// build head mask, mask off [0,firstoff[
 	;;
 	shr.u tmask=tmask,tmp1	// build tail mask, mask off ]8,lastoff]
-	UNW(.save ar.lc, saved_lc)
+	.save ar.lc, saved_lc
 	mov saved_lc=ar.lc	// save lc
 	;;
 
-	UNW(.body)
+	.body
 
 (p8)	and hmask=hmask,tmask	// apply tail mask to head mask if 1 word only
 (p9)	and p[1]=lastval,tmask	// mask last it as appropriate
@@ -163,7 +157,7 @@
 	;;
 	// XXX Fixme: not very nice initialization here
 	//
-	// Setup loop control registers: 
+	// Setup loop control registers:
 	//
 	// tmp3=0 (1 word)   : lc=0, ec=2, p16=F
 	// tmp3=1 (2 words)  : lc=0, ec=3, p16=F
@@ -227,7 +221,7 @@
 	add ret0=tmp1,tmp2
 	mov pr=saved_pr,0xffffffffffff0000
 	;;
-	// if buf was odd then swap bytes 
+	// if buf was odd then swap bytes
 	mov ar.pfs=saved_pfs		// restore ar.ec
 (p10)	mux1 ret0=ret0,@rev		// reverse word
 	;;
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/flush.S linux/arch/ia64/lib/flush.S
--- v2.4.3/linux/arch/ia64/lib/flush.S	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/lib/flush.S	Thu Apr  5 12:51:47 2001
@@ -1,30 +1,25 @@
 /*
  * Cache flushing routines.
  *
- * Copyright (C) 1999-2000 Hewlett-Packard Co
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2001 Hewlett-Packard Co
+ * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #include <asm/asmmacro.h>
 #include <asm/page.h>
 
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
-
 	/*
 	 * flush_icache_range(start,end)
 	 *	Must flush range from start to end-1 but nothing else (need to
 	 *	be careful not to touch addresses that may be unmapped).
 	 */
 GLOBAL_ENTRY(flush_icache_range)
-	UNW(.prologue)
+	.prologue
 	alloc r2=ar.pfs,2,0,0,0
 	sub r8=in1,in0,1
 	;;
 	shr.u r8=r8,5			// we flush 32 bytes per iteration
-	UNW(.save ar.lc, r3)
-	mov r3=ar.lc			// save ar.lc	
+	.save ar.lc, r3
+	mov r3=ar.lc			// save ar.lc
 	;;
 
 	.body
@@ -38,7 +33,7 @@
 	sync.i
 	;;
 	srlz.i
-	;;	
+	;;
 	mov ar.lc=r3			// restore ar.lc
 	br.ret.sptk.many rp
 END(flush_icache_range)
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/idiv64.S linux/arch/ia64/lib/idiv64.S
--- v2.4.3/linux/arch/ia64/lib/idiv64.S	Mon Oct  9 17:54:56 2000
+++ linux/arch/ia64/lib/idiv64.S	Thu Apr  5 12:51:47 2001
@@ -37,28 +37,29 @@
 #define NAME		PASTE(PASTE(__,SGN),PASTE(OP,di3))
 
 GLOBAL_ENTRY(NAME)
-	UNW(.prologue)
+	.prologue
 	.regstk 2,0,0,0
 	// Transfer inputs to FP registers.
 	setf.sig f8 = in0
 	setf.sig f9 = in1
-	UNW(.fframe 16)
-	UNW(.save.f 0x20)
+	;;
+	.fframe 16
+	.save.f 0x20
 	stf.spill [sp] = f17,-16
 
 	// Convert the inputs to FP, to avoid FP software-assist faults.
 	INT_TO_FP(f8, f8)
 	;;
 
-	UNW(.save.f 0x10)
+	.save.f 0x10
 	stf.spill [sp] = f16
-	UNW(.body)
+	.body
 	INT_TO_FP(f9, f9)
 	;;
 	frcpa.s1 f17, p6 = f8, f9	// y0 = frcpa(b)
 	;;
 (p6)	fmpy.s1 f7 = f8, f17		// q0 = a*y0
-(p6)	fnma.s1 f6 = f9, f17, f1	// e0 = -b*y0 + 1 
+(p6)	fnma.s1 f6 = f9, f17, f1	// e0 = -b*y0 + 1
 	;;
 (p6)	fma.s1 f16 = f7, f6, f7		// q1 = q0*e0 + q0
 (p6)	fmpy.s1 f7 = f6, f6		// e1 = e0*e0
@@ -70,7 +71,7 @@
 (p6)	fma.s1 f6 = f17, f6, f17	// y1 = y0*e0 + y0
 	;;
 (p6)	fma.s1 f6 = f6, f7, f6		// y2 = y1*e1 + y1
-(p6)	fnma.s1 f7 = f9, f16, f8	// r = -b*q2 + a 
+(p6)	fnma.s1 f7 = f9, f16, f8	// r = -b*q2 + a
 	;;
 #ifdef MODULO
 	setf.sig f8 = in0		// f8 = a
@@ -78,7 +79,7 @@
 #endif
 (p6)	fma.s1 f17 = f7, f6, f16	// q3 = r*y2 + q2
 	;;
-	UNW(.restore sp)
+	.restore sp
 	ldf.fill f16 = [sp], 16
 	FP_TO_INT(f17, f17)		// q = trunc(q3)
 	;;
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/memcpy.S linux/arch/ia64/lib/memcpy.S
--- v2.4.3/linux/arch/ia64/lib/memcpy.S	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/lib/memcpy.S	Thu Apr  5 12:51:47 2001
@@ -68,19 +68,19 @@
 	 * the more general copy routine handling arbitrary
 	 * sizes/alignment etc.
 	 */
-	UNW(.prologue)
-	UNW(.save ar.pfs, saved_pfs)
+	.prologue
+	.save ar.pfs, saved_pfs
 	alloc saved_pfs=ar.pfs,3,Nrot,0,Nrot
-	UNW(.save ar.lc, saved_lc)
+	.save ar.lc, saved_lc
 	mov saved_lc=ar.lc
 	or t0=in0,in1
 	;;
 
 	or t0=t0,in2
-	UNW(.save pr, saved_pr)
+	.save pr, saved_pr
 	mov saved_pr=pr
 
-	UNW(.body)
+	.body
 
 	cmp.eq p6,p0=in2,r0	// zero length?
 	mov retval=in0		// return dst
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/memset.S linux/arch/ia64/lib/memset.S
--- v2.4.3/linux/arch/ia64/lib/memset.S	Thu Jun 22 07:09:44 2000
+++ linux/arch/ia64/lib/memset.S	Thu Apr  5 12:51:47 2001
@@ -3,14 +3,13 @@
  * Optimized version of the standard memset() function
  *
  * Return: none
- *         
  *
  * Inputs:
  *	in0:	address of buffer
  * 	in1:	byte value to use for storing
  *	in2:	length of the buffer
  *
- * Copyright (C) 1999 Hewlett-Packard Co
+ * Copyright (C) 1999, 2001 Hewlett-Packard Co
  * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
  */
 
@@ -31,20 +30,16 @@
 #define saved_lc	r20
 #define tmp		r21
 
- 	.text
- 	.psr	abi64
- 	.psr	lsb
-
 GLOBAL_ENTRY(memset)
-	UNW(.prologue)
-	UNW(.save ar.pfs, saved_pfs)
- 	alloc	saved_pfs=ar.pfs,3,0,0,0	// cnt is sink here
+	.prologue
+	.save ar.pfs, saved_pfs
+ 	alloc saved_pfs=ar.pfs,3,0,0,0	// cnt is sink here
 	cmp.eq p8,p0=r0,len	// check for zero length
-	UNW(.save ar.lc, saved_lc)
+	.save ar.lc, saved_lc
 	mov saved_lc=ar.lc	// preserve ar.lc (slow)
-	;; 
+	;;
 
-	UNW(.body)
+	.body
 
 	adds tmp=-1,len		// br.ctop is repeat/until
 	tbit.nz p6,p0=buf,0	// odd alignment
@@ -82,7 +77,7 @@
 (p6)	st8 [buf]=val,8		// 8-byte aligned
 (p6)	adds len=-8,len;;
 	shr.u cnt=len,4		// number of 128-bit (2x64bit) words
-	;;	
+	;;
 	cmp.eq p6,p0=r0,cnt
 	adds tmp=-1,cnt
 (p6)	br.cond.dpnt.few .dotail // we have less than 16 bytes left
@@ -96,10 +91,10 @@
 	br.cloop.dptk.few 2b
 	;;
 .dotail:			// tail correction based on len only
-	tbit.nz p6,p0=len,3	
+	tbit.nz p6,p0=len,3
 	;;
 (p6)	st8 [buf]=val,8		// at least 8 bytes
-	tbit.nz p6,p0=len,2	
+	tbit.nz p6,p0=len,2
 	;;
 (p6)	st4 [buf]=val,4		// at least 4 bytes
 	tbit.nz p6,p0=len,1
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/strlen.S linux/arch/ia64/lib/strlen.S
--- v2.4.3/linux/arch/ia64/lib/strlen.S	Tue Mar  6 19:44:35 2001
+++ linux/arch/ia64/lib/strlen.S	Thu Apr  5 12:51:47 2001
@@ -5,12 +5,12 @@
  *
  * Inputs:
  *	in0	address of string
- * 
- * Outputs: 
- * 	ret0	the number of characters in the string (0 if empty string)
- *         	does not count the \0
  *
- * Copyright (C) 1999 Hewlett-Packard Co
+ * Outputs:
+ *	ret0	the number of characters in the string (0 if empty string)
+ *	does not count the \0
+ *
+ * Copyright (C) 1999, 2001 Hewlett-Packard Co
  * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
  *
  * 09/24/99 S.Eranian add speculation recovery code
@@ -30,7 +30,7 @@
 //	  string may not be 8-byte aligned. In this case we load the 8byte
 //	  quantity which includes the start of the string and mask the unused
 //	  bytes with 0xff to avoid confusing czx.
-//	  We use speculative loads and software pipelining to hide memory 
+//	  We use speculative loads and software pipelining to hide memory
 //	  latency and do read ahead safely. This way we defer any exception.
 //
 //	  Because we don't want the kernel to be relying on particular
@@ -42,7 +42,7 @@
 //	  The fact that speculation may fail can be caused, for instance, by
 //	  the DCR.dm bit being set. In this case TLB misses are deferred, i.e.,
 //	  a NaT bit will be set if the translation is not present. The normal
-//	  load, on the other hand, will cause the translation to be inserted 
+//	  load, on the other hand, will cause the translation to be inserted
 //	  if the mapping exists.
 //
 //	  It should be noted that we execute recovery code only when we need
@@ -50,22 +50,22 @@
 //	  recovery code on pure read ahead data.
 //
 // Remarks:
-//	- the cmp r0,r0 is used as a fast way to initialize a predicate 
+//	- the cmp r0,r0 is used as a fast way to initialize a predicate
 //	  register to 1. This is required to make sure that we get the parallel
 //	  compare correct.
 //
 //	- we don't use the epilogue counter to exit the loop but we need to set
 //	  it to zero beforehand.
 //
-//	- after the loop we must test for Nat values because neither the 
+//	- after the loop we must test for Nat values because neither the
 //	  czx nor cmp instruction raise a NaT consumption fault. We must be
-//	  careful not to look too far for a Nat for which we don't care. 
+//	  careful not to look too far for a Nat for which we don't care.
 //	  For instance we don't need to look at a NaT in val2 if the zero byte
 //	  was in val1.
 //
 //	- Clearly performance tuning is required.
 //
-// 
+//
 //
 #define saved_pfs	r11
 #define	tmp		r10
@@ -78,15 +78,9 @@
 #define val1		r22
 #define val2		r23
 
-
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
-
 GLOBAL_ENTRY(strlen)
-	UNW(.prologue)
-	UNW(.save ar.pfs, saved_pfs)
+	.prologue
+	.save ar.pfs, saved_pfs
 	alloc saved_pfs=ar.pfs,11,0,0,8 // rotating must be multiple of 8
 
 	.rotr v[2], w[2]	// declares our 4 aliases
@@ -94,11 +88,11 @@
 	extr.u tmp=in0,0,3	// tmp=least significant 3 bits
 	mov orig=in0		// keep trackof initial byte address
 	dep src=0,in0,0,3	// src=8byte-aligned in0 address
-	UNW(.save pr, saved_pr)
+	.save pr, saved_pr
 	mov saved_pr=pr		// preserve predicates (rotation)
 	;;
 
-	UNW(.body)
+	.body
 
 	ld8 v[1]=[src],8	// must not speculate: can fail here
 	shl tmp=tmp,3		// multiply by 8bits/byte
@@ -115,8 +109,8 @@
 	or v[1]=v[1],mask	// now we have a safe initial byte pattern
 	;;
 1:
-	ld8.s v[0]=[src],8	// speculatively load next 
-	czx1.r val1=v[1]	// search 0 byte from right 
+	ld8.s v[0]=[src],8	// speculatively load next
+	czx1.r val1=v[1]	// search 0 byte from right
 	czx1.r val2=w[1]	// search 0 byte from right following 8bytes
 	;;
 	ld8.s w[0]=[src],8	// speculatively load next to next
@@ -132,11 +126,7 @@
 	//	- there must be a better way of doing the test
 	//
 	cmp.eq  p8,p9=8,val1	// p6 = val1 had zero (disambiguate)
-#ifdef notyet
 	tnat.nz p6,p7=val1	// test NaT on val1
-#else
-	tnat.z p7,p6=val1	// test NaT on val1
-#endif
 (p6)	br.cond.spnt.few recover// jump to recovery if val1 is NaT
 	;;
 	//
@@ -154,7 +144,7 @@
 	sub tmp=8,val1		// which byte in word
 	mov pr=saved_pr,0xffffffffffff0000
 	;;
-	sub ret0=ret0,tmp	// adjust 
+	sub ret0=ret0,tmp	// adjust
 	mov ar.pfs=saved_pfs	// because of ar.ec, restore no matter what
 	br.ret.sptk.few rp	// end of normal execution
 
@@ -167,8 +157,8 @@
 	//
 	// IMPORTANT:
 	// Please note that in the case of strlen() as opposed to strlen_user()
-	// we don't use the exception mechanism, as this function is not 
-	// supposed to fail. If that happens it means we have a bug and the 
+	// we don't use the exception mechanism, as this function is not
+	// supposed to fail. If that happens it means we have a bug and the
 	// code will cause of kernel fault.
 	//
 	// XXX Fixme
@@ -187,7 +177,7 @@
 2:
 (p6)	ld8 val=[base],8	// will fail if unrecoverable fault
 	;;
-	czx1.r val1=val		// search 0 byte from right 
+	czx1.r val1=val		// search 0 byte from right
 	;;
 	cmp.eq p6,p0=8,val1	// val1==8 ?
 (p6)	br.wtop.dptk.few 2b	// loop until p6 == 0
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/strlen_user.S linux/arch/ia64/lib/strlen_user.S
--- v2.4.3/linux/arch/ia64/lib/strlen_user.S	Tue Mar  6 19:44:35 2001
+++ linux/arch/ia64/lib/strlen_user.S	Thu Apr  5 12:51:47 2001
@@ -6,9 +6,9 @@
  *
  * Outputs:
  *	ret0	0 in case of fault, strlen(buffer)+1 otherwise
- * 
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.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 Stephane Eranian <eranian@hpl.hp.com>
  *
  * 01/19/99 S.Eranian heavily enhanced version (see details below)
@@ -24,8 +24,8 @@
 //	- length of string + 1
 //	- 0 in case an exception is raised
 //
-// This is an enhanced version of the basic strlen_user. it includes a 
-// combination of compute zero index (czx), parallel comparisons, speculative 
+// This is an enhanced version of the basic strlen_user. it includes a
+// combination of compute zero index (czx), parallel comparisons, speculative
 // loads and loop unroll using rotating registers.
 //
 // General Ideas about the algorithm:
@@ -34,7 +34,7 @@
 //	  string may not be 8-byte aligned. In this case we load the 8byte
 //	  quantity which includes the start of the string and mask the unused
 //	  bytes with 0xff to avoid confusing czx.
-//	  We use speculative loads and software pipelining to hide memory 
+//	  We use speculative loads and software pipelining to hide memory
 //	  latency and do read ahead safely. This way we defer any exception.
 //
 //	  Because we don't want the kernel to be relying on particular
@@ -45,7 +45,7 @@
 //	  The fact that speculation may fail can be caused, for instance, by
 //	  the DCR.dm bit being set. In this case TLB misses are deferred, i.e.,
 //	  a NaT bit will be set if the translation is not present. The normal
-//	  load, on the other hand, will cause the translation to be inserted 
+//	  load, on the other hand, will cause the translation to be inserted
 //	  if the mapping exists.
 //
 //	  It should be noted that we execute recovery code only when we need
@@ -53,30 +53,21 @@
 //	  recovery code on pure read ahead data.
 //
 // Remarks:
-//	- the cmp r0,r0 is used as a fast way to initialize a predicate 
+//	- the cmp r0,r0 is used as a fast way to initialize a predicate
 //	  register to 1. This is required to make sure that we get the parallel
 //	  compare correct.
 //
 //	- we don't use the epilogue counter to exit the loop but we need to set
 //	  it to zero beforehand.
 //
-//	- after the loop we must test for Nat values because neither the 
+//	- after the loop we must test for Nat values because neither the
 //	  czx nor cmp instruction raise a NaT consumption fault. We must be
-//	  careful not to look too far for a Nat for which we don't care. 
+//	  careful not to look too far for a Nat for which we don't care.
 //	  For instance we don't need to look at a NaT in val2 if the zero byte
 //	  was in val1.
 //
 //	- Clearly performance tuning is required.
 //
-// 
-//
-
-#define EX(y,x...)				\
-	.section __ex_table,"a";		\
-	data4 @gprel(99f);			\
-	data4 y-99f;				\
-	.previous;				\
-99:	x
 
 #define saved_pfs	r11
 #define	tmp		r10
@@ -89,15 +80,9 @@
 #define val1		r22
 #define val2		r23
 
-
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
-
 GLOBAL_ENTRY(__strlen_user)
-	UNW(.prologue)
-	UNW(.save ar.pfs, saved_pfs)
+	.prologue
+	.save ar.pfs, saved_pfs
 	alloc saved_pfs=ar.pfs,11,0,0,8
 
 	.rotr v[2], w[2]	// declares our 4 aliases
@@ -105,7 +90,7 @@
 	extr.u tmp=in0,0,3	// tmp=least significant 3 bits
 	mov orig=in0		// keep trackof initial byte address
 	dep src=0,in0,0,3	// src=8byte-aligned in0 address
-	UNW(.save pr, saved_pr)
+	.save pr, saved_pr
 	mov saved_pr=pr		// preserve predicates (rotation)
 	;;
 
@@ -127,8 +112,8 @@
 	or v[1]=v[1],mask	// now we have a safe initial byte pattern
 	;;
 1:
-	ld8.s v[0]=[src],8	// speculatively load next 
-	czx1.r val1=v[1]	// search 0 byte from right 
+	ld8.s v[0]=[src],8	// speculatively load next
+	czx1.r val1=v[1]	// search 0 byte from right
 	czx1.r val2=w[1]	// search 0 byte from right following 8bytes
 	;;
 	ld8.s w[0]=[src],8	// speculatively load next to next
@@ -144,11 +129,7 @@
 	//	- there must be a better way of doing the test
 	//
 	cmp.eq  p8,p9=8,val1	// p6 = val1 had zero (disambiguate)
-#ifdef notyet
 	tnat.nz p6,p7=val1	// test NaT on val1
-#else
-	tnat.z p7,p6=val1	// test NaT on val1
-#endif
 (p6)	br.cond.spnt.few recover// jump to recovery if val1 is NaT
 	;;
 	//
@@ -193,7 +174,7 @@
 2:
 	EX(.Lexit1, (p6) ld8 val=[base],8)
 	;;
-	czx1.r val1=val		// search 0 byte from right 
+	czx1.r val1=val		// search 0 byte from right
 	;;
 	cmp.eq p6,p0=8,val1	// val1==8 ?
 (p6)	br.wtop.dptk.few 2b	// loop until p6 == 0
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/strncpy_from_user.S linux/arch/ia64/lib/strncpy_from_user.S
--- v2.4.3/linux/arch/ia64/lib/strncpy_from_user.S	Thu Jun 22 07:09:44 2000
+++ linux/arch/ia64/lib/strncpy_from_user.S	Thu Apr  5 12:51:47 2001
@@ -8,9 +8,9 @@
  *	in2:	length of buffer in bytes
  * Outputs:
  *	r8:	-EFAULT in case of fault or number of bytes copied if no fault
- * 
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * 00/03/06 D. Mosberger Fixed to return proper return value (bug found by
  *			 by Andreas Schwab <schwab@suse.de>).
@@ -18,18 +18,6 @@
 
 #include <asm/asmmacro.h>
 
-#define EX(x...)				\
-99:	x;					\
-	.section __ex_table,"a";		\
-	data4 @gprel(99b);			\
-	data4 .Lexit-99b;			\
-	.previous
-
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
-
 GLOBAL_ENTRY(__strncpy_from_user)
 	alloc r2=ar.pfs,3,0,0,0
 	mov r8=0
@@ -41,15 +29,16 @@
 
 	// XXX braindead copy loop---this needs to be optimized
 .Loop1:
-	EX(ld1 r8=[in1],1;; st1 [in0]=r8,1; cmp.ne p6,p7=r8,r0)
+	EX(.Lexit, ld1 r8=[in1],1)
+	;;
+	EX(.Lexit, st1 [in0]=r8,1)
+	cmp.ne p6,p7=r8,r0
 	;;
 (p6)	cmp.ne.unc p8,p0=in1,r10
 (p8)	br.cond.dpnt.few .Loop1
 	;;
 (p6)	mov r8=in2		// buffer filled up---return buffer length
 (p7)	sub r8=in1,r9,1		// return string length (excluding NUL character)
-	br.ret.sptk.few rp
-
-.Lexit:
+[.Lexit:]
 	br.ret.sptk.few rp
 END(__strncpy_from_user)
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/strnlen_user.S linux/arch/ia64/lib/strnlen_user.S
--- v2.4.3/linux/arch/ia64/lib/strnlen_user.S	Thu Jun 22 07:09:44 2000
+++ linux/arch/ia64/lib/strnlen_user.S	Thu Apr  5 12:51:47 2001
@@ -8,41 +8,28 @@
  *	in1:	string length limit N
  * Outputs:
  *	r8:	0 in case of fault, strlen(buffer)+1 otherwise
- * 
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * Copyright (C) 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <asm/asmmacro.h>
 
-/* If a fault occurs, r8 gets set to -EFAULT and r9 gets cleared.  */
-#define EX(x...)				\
-	.section __ex_table,"a";		\
-	data4 @gprel(99f);			\
-	data4 (.Lexit-99f)|1;			\
-	.previous				\
-99:	x;
-
-	.text
-	.psr abi64
-	.psr lsb
-	.lsb
-
 GLOBAL_ENTRY(__strnlen_user)
-	UNW(.prologue)
+	.prologue
 	alloc r2=ar.pfs,2,0,0,0
-	UNW(.save ar.lc, r16)
+	.save ar.lc, r16
 	mov r16=ar.lc			// preserve ar.lc
 
-	UNW(.body)
+	.body
 
 	add r3=-1,in1
 	;;
 	mov ar.lc=r3
 	mov r9=0
-
+	;;
 	// XXX braindead strlen loop---this needs to be optimized
 .Loop1:
-	EX(ld1 r8=[in0],1)
+	EXCLR(.Lexit, ld1 r8=[in0],1)
 	add r9=1,r9
 	;;
 	cmp.eq p6,p0=r8,r0
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/lib/swiotlb.c linux/arch/ia64/lib/swiotlb.c
--- v2.4.3/linux/arch/ia64/lib/swiotlb.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/lib/swiotlb.c	Thu Apr  5 12:51:47 2001
@@ -11,6 +11,7 @@
  */
 
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
@@ -50,14 +51,14 @@
 static unsigned int io_tlb_index;
 
 /*
- * We need to save away the original address corresponding to a mapped entry for the sync 
+ * We need to save away the original address corresponding to a mapped entry for the sync
  * operations.
  */
 static unsigned char **io_tlb_orig_addr;
 
 /*
  * Protect the above data structures in the map and unmap calls
- */ 
+ */
 static spinlock_t io_tlb_lock = SPIN_LOCK_UNLOCKED;
 
 static int __init
@@ -132,7 +133,7 @@
 	{
 		wrap = index = ALIGN(io_tlb_index, stride);
 
-		if (index >= io_tlb_nslabs) 
+		if (index >= io_tlb_nslabs)
 			wrap = index = 0;
 
 		do {
@@ -164,12 +165,12 @@
 		} while (index != wrap);
 
 		/*
-		 * XXX What is a suitable recovery mechanism here?  We cannot 
+		 * XXX What is a suitable recovery mechanism here?  We cannot
 		 * sleep because we are called from with in interrupts!
 		 */
 		panic("map_single: could not allocate software IO TLB (%ld bytes)", size);
-found:
 	}
+  found:
 	spin_unlock_irqrestore(&io_tlb_lock, flags);
 
 	/*
@@ -199,9 +200,9 @@
 	 */
 	if ((direction == PCI_DMA_FROMDEVICE) || (direction == PCI_DMA_BIDIRECTIONAL))
 		/*
- 	 	 * bounce... copy the data back into the original buffer * and delete the
- 	 	 * bounce buffer.
- 	 	 */
+		 * bounce... copy the data back into the original buffer * and delete the
+		 * bounce buffer.
+		 */
 		memcpy(buffer, dma_addr, size);
 
 	/*
@@ -236,9 +237,9 @@
 	char *buffer = io_tlb_orig_addr[index];
 
 	/*
-  	 * bounce... copy the data back into/from the original buffer
+	 * bounce... copy the data back into/from the original buffer
 	 * XXX How do you handle PCI_DMA_BIDIRECTIONAL here ?
- 	 */
+	 */
 	if (direction == PCI_DMA_FROMDEVICE)
 		memcpy(buffer, dma_addr, size);
 	else if (direction == PCI_DMA_TODEVICE)
@@ -298,8 +299,8 @@
 		 */
 		return pci_addr;
 
-	/* 
-	 * get a bounce buffer: 
+	/*
+	 * get a bounce buffer:
 	 */
 	pci_addr = virt_to_phys(map_single(hwdev, ptr, size, direction));
 
@@ -325,12 +326,8 @@
 	pg_addr = PAGE_ALIGN((unsigned long) addr);
 	end = (unsigned long) addr + size;
 	while (pg_addr + PAGE_SIZE <= end) {
-#if 0
-		set_bit(PG_arch_1, virt_to_page(pg_addr));
-#else
-		if (!VALID_PAGE(virt_to_page(pg_addr)))
-			printk("Invalid addr %lx!!!\n", pg_addr);
-#endif
+		struct page *page = virt_to_page(pg_addr);
+		set_bit(PG_arch_1, &page->flags);
 		pg_addr += PAGE_SIZE;
 	}
 }
@@ -454,3 +451,14 @@
 {
 	return virt_to_phys(sg->address);
 }
+
+EXPORT_SYMBOL(swiotlb_init);
+EXPORT_SYMBOL(swiotlb_map_single);
+EXPORT_SYMBOL(swiotlb_unmap_single);
+EXPORT_SYMBOL(swiotlb_map_sg);
+EXPORT_SYMBOL(swiotlb_unmap_sg);
+EXPORT_SYMBOL(swiotlb_sync_single);
+EXPORT_SYMBOL(swiotlb_sync_sg);
+EXPORT_SYMBOL(swiotlb_dma_address);
+EXPORT_SYMBOL(swiotlb_alloc_consistent);
+EXPORT_SYMBOL(swiotlb_free_consistent);
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/mm/extable.c linux/arch/ia64/mm/extable.c
--- v2.4.3/linux/arch/ia64/mm/extable.c	Sun Feb  6 18:42:40 2000
+++ linux/arch/ia64/mm/extable.c	Thu Apr  5 12:51:47 2001
@@ -1,8 +1,8 @@
 /*
  * Kernel exception handling table support.  Derived from arch/alpha/mm/extable.c.
  *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <linux/config.h>
@@ -43,14 +43,22 @@
         return 0;
 }
 
-register unsigned long gp __asm__("gp");
+#ifndef CONFIG_MODULE
+register unsigned long main_gp __asm__("gp");
+#endif
 
-const struct exception_table_entry *
+struct exception_fixup
 search_exception_table (unsigned long addr)
 {
+	const struct exception_table_entry *entry;
+	struct exception_fixup fix = { 0 };
+
 #ifndef CONFIG_MODULE
 	/* There is only the kernel to search.  */
-	return search_one_table(__start___ex_table, __stop___ex_table - 1, addr - gp);
+	entry = search_one_table(__start___ex_table, __stop___ex_table - 1, addr - main_gp);
+	if (entry)
+		fix.cont = entry->cont + main_gp;
+	return fix;
 #else
 	struct exception_table_entry *ret;
 	/* The kernel is the last "module" -- no need to treat it special. */
@@ -59,10 +67,22 @@
 	for (mp = module_list; mp ; mp = mp->next) {
 		if (!mp->ex_table_start)
 			continue;
-		ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, addr - mp->gp);
-		if (ret)
-			return ret;
+		entry = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, addr - mp->gp);
+		if (entry) {
+			fix.cont = entry->cont + mp->gp;
+			return fix;
+		}
 	}
-	return 0;
 #endif
+	return fix;
+}
+
+void
+handle_exception (struct pt_regs *regs, struct exception_fixup fix)
+{
+	regs->r8 = -EFAULT;
+	if (fix.cont & 4)
+		regs->r9 = 0;
+	regs->cr_iip = (long) fix.cont & ~0xf;
+	ia64_psr(regs)->ri = fix.cont & 0x3;		/* set continuation slot number */
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/mm/fault.c linux/arch/ia64/mm/fault.c
--- v2.4.3/linux/arch/ia64/mm/fault.c	Mon Mar 19 12:35:10 2001
+++ linux/arch/ia64/mm/fault.c	Thu Apr  5 12:51:47 2001
@@ -47,7 +47,7 @@
 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
 {
 	struct mm_struct *mm = current->mm;
-	const struct exception_table_entry *fix;
+	struct exception_fixup fix;
 	struct vm_area_struct *vma, *prev_vma;
 	struct siginfo si;
 	int signal = SIGSEGV;
@@ -163,14 +163,13 @@
 		return;
 	}
 
+#ifdef GAS_HAS_LOCAL_TAGS
+	fix = search_exception_table(regs->cr_iip + ia64_psr(regs)->ri);
+#else
 	fix = search_exception_table(regs->cr_iip);
-	if (fix) {
-		regs->r8 = -EFAULT;
-		if (fix->skip & 1) {
-			regs->r9 = 0;
-		}
-		regs->cr_iip += ((long) fix->skip) & ~15;
-		regs->cr_ipsr &= ~IA64_PSR_RI;	/* clear exception slot number */
+#endif
+	if (fix.cont) {
+		handle_exception(regs, fix);
 		return;
 	}
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/mm/init.c linux/arch/ia64/mm/init.c
--- v2.4.3/linux/arch/ia64/mm/init.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/mm/init.c	Thu Apr  5 12:51:47 2001
@@ -1,8 +1,8 @@
 /*
  * Initialize MMU support.
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -23,116 +23,33 @@
 #include <asm/pgalloc.h>
 #include <asm/sal.h>
 #include <asm/system.h>
+#include <asm/uaccess.h>
 
 /* References to section boundaries: */
 extern char _stext, _etext, _edata, __init_begin, __init_end;
 
-/*
- * These are allocated in head.S so that we get proper page alignment.
- * If you change the size of these then change head.S as well.
- */
-extern char empty_bad_page[PAGE_SIZE];
-extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD];
-extern pte_t empty_bad_pte_table[PTRS_PER_PTE];
-
 extern void ia64_tlb_init (void);
 
-static unsigned long totalram_pages;
-
-/*
- * Fill in empty_bad_pmd_table with entries pointing to
- * empty_bad_pte_table and return the address of this PMD table.
- */
-static pmd_t *
-get_bad_pmd_table (void)
-{
-	pmd_t v;
-	int i;
-
-	pmd_set(&v, empty_bad_pte_table);
+unsigned long MAX_DMA_ADDRESS = PAGE_OFFSET + 0x100000000UL;
 
-	for (i = 0; i < PTRS_PER_PMD; ++i)
-		empty_bad_pmd_table[i] = v;
-
-	return empty_bad_pmd_table;
-}
-
-/*
- * Fill in empty_bad_pte_table with PTEs pointing to empty_bad_page
- * and return the address of this PTE table.
- */
-static pte_t *
-get_bad_pte_table (void)
-{
-	pte_t v;
-	int i;
-
-	set_pte(&v, pte_mkdirty(mk_pte_phys(__pa(empty_bad_page), PAGE_SHARED)));
-
-	for (i = 0; i < PTRS_PER_PTE; ++i)
-		empty_bad_pte_table[i] = v;
-
-	return empty_bad_pte_table;
-}
-
-void
-__handle_bad_pgd (pgd_t *pgd)
-{
-	pgd_ERROR(*pgd);
-	pgd_set(pgd, get_bad_pmd_table());
-}
-
-void
-__handle_bad_pmd (pmd_t *pmd)
-{
-	pmd_ERROR(*pmd);
-	pmd_set(pmd, get_bad_pte_table());
-}
-
-/*
- * Allocate and initialize an L3 directory page and set
- * the L2 directory entry PMD to the newly allocated page.
- */
-pte_t*
-get_pte_slow (pmd_t *pmd, unsigned long offset)
-{
-	pte_t *pte;
-
-	pte = (pte_t *) __get_free_page(GFP_KERNEL);
-	if (pmd_none(*pmd)) {
-		if (pte) {
-			/* everything A-OK */
-			clear_page(pte);
-			pmd_set(pmd, pte);
-			return pte + offset;
-		}
-		pmd_set(pmd, get_bad_pte_table());
-		return NULL;
-	}
-	free_page((unsigned long) pte);
-	if (pmd_bad(*pmd)) {
-		__handle_bad_pmd(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + offset;
-}
+static unsigned long totalram_pages;
 
 int
 do_check_pgt_cache (int low, int high)
 {
 	int freed = 0;
 
-        if (pgtable_cache_size > high) {
-                do {
-                        if (pgd_quicklist)
-                                free_page((unsigned long)get_pgd_fast()), ++freed;
-                        if (pmd_quicklist)
-                                free_page((unsigned long)get_pmd_fast()), ++freed;
-                        if (pte_quicklist)
-                                free_page((unsigned long)get_pte_fast()), ++freed;
-                } while (pgtable_cache_size > low);
-        }
-        return freed;
+	if (pgtable_cache_size > high) {
+		do {
+			if (pgd_quicklist)
+				free_page((unsigned long)pgd_alloc_one_fast()), ++freed;
+			if (pmd_quicklist)
+				free_page((unsigned long)pmd_alloc_one_fast(0, 0)), ++freed;
+			if (pte_quicklist)
+				free_page((unsigned long)pte_alloc_one_fast(0, 0)), ++freed;
+		} while (pgtable_cache_size > low);
+	}
+	return freed;
 }
 
 /*
@@ -188,12 +105,12 @@
 {
 	/*
 	 * EFI uses 4KB pages while the kernel can use 4KB  or bigger.
-	 * Thus EFI and the kernel may have different page sizes. It is 
-	 * therefore possible to have the initrd share the same page as 
-	 * the end of the kernel (given current setup). 
+	 * Thus EFI and the kernel may have different page sizes. It is
+	 * therefore possible to have the initrd share the same page as
+	 * the end of the kernel (given current setup).
 	 *
 	 * To avoid freeing/using the wrong page (kernel sized) we:
-	 * 	- align up the beginning of initrd
+	 *	- align up the beginning of initrd
 	 *	- keep the end untouched
 	 *
 	 *  |             |
@@ -201,8 +118,8 @@
 	 *  |             |
 	 *  |             |
 	 *  |             | 9000
-	 *  |/////////////| 
-	 *  |/////////////| 
+	 *  |/////////////|
+	 *  |/////////////|
 	 *  |=============| 8000
 	 *  |///INITRD////|
 	 *  |/////////////|
@@ -211,9 +128,9 @@
 	 *  |KKKKKKKKKKKKK|
 	 *  |=============| 6000
 	 *  |KKKKKKKKKKKKK|
-	 *  |KKKKKKKKKKKKK| 
+	 *  |KKKKKKKKKKKKK|
 	 *  K=kernel using 8KB pages
-	 * 
+	 *
 	 * In this example, we must free page 8000 ONLY. So we must align up
 	 * initrd_start and keep initrd_end as is.
 	 */
@@ -286,52 +203,59 @@
 		       page_address(page));
 
 	pgd = pgd_offset_k(address);		/* note: this is NOT pgd_offset()! */
-	pmd = pmd_alloc(pgd, address);
-	if (!pmd) {
-		__free_page(page);
-		panic("Out of memory.");
-		return 0;
-	}
-	pte = pte_alloc(pmd, address);
-	if (!pte) {
-		__free_page(page);
-		panic("Out of memory.");
-		return 0;
-	}
-	if (!pte_none(*pte)) {
-		pte_ERROR(*pte);
-		__free_page(page);
-		return 0;
+
+	spin_lock(&init_mm.page_table_lock);
+	{
+		pmd = pmd_alloc(&init_mm, pgd, address);
+		if (!pmd)
+			goto out;
+		pte = pte_alloc(&init_mm, pmd, address);
+		if (!pte)
+			goto out;
+		if (!pte_none(*pte)) {
+			pte_ERROR(*pte);
+			goto out;
+		}
+		flush_page_to_ram(page);
+		set_pte(pte, mk_pte(page, PAGE_GATE));
 	}
-	flush_page_to_ram(page);
-	set_pte(pte, mk_pte(page, PAGE_GATE));
+  out:	spin_unlock(&init_mm.page_table_lock);
 	/* no need for flush_tlb */
 	return page;
 }
 
 void __init
-ia64_rid_init (void)
+ia64_mmu_init (void)
 {
 	unsigned long flags, rid, pta, impl_va_bits;
+	extern void __init tlb_init (void);
 #ifdef CONFIG_DISABLE_VHPT
 #	define VHPT_ENABLE_BIT	0
 #else
 #	define VHPT_ENABLE_BIT	1
 #endif
 
-	/* Set up the kernel identity mappings (regions 6 & 7) and the vmalloc area (region 5): */
+	/*
+	 * Set up the kernel identity mapping for regions 6 and 5.  The mapping for region
+	 * 7 is setup up in _start().
+	 */
 	ia64_clear_ic(flags);
 
 	rid = ia64_rid(IA64_REGION_ID_KERNEL, __IA64_UNCACHED_OFFSET);
-	ia64_set_rr(__IA64_UNCACHED_OFFSET, (rid << 8) | (_PAGE_SIZE_256M << 2));
-
-	rid = ia64_rid(IA64_REGION_ID_KERNEL, PAGE_OFFSET);
-	ia64_set_rr(PAGE_OFFSET, (rid << 8) | (_PAGE_SIZE_256M << 2));
+	ia64_set_rr(__IA64_UNCACHED_OFFSET, (rid << 8) | (_PAGE_SIZE_64M << 2));
 
 	rid = ia64_rid(IA64_REGION_ID_KERNEL, VMALLOC_START);
 	ia64_set_rr(VMALLOC_START, (rid << 8) | (PAGE_SHIFT << 2) | 1);
 
+	/* ensure rr6 is up-to-date before inserting the PERCPU_ADDR translation: */
+	ia64_srlz_d();
+
+	ia64_itr(0x2, IA64_TR_PERCPU_DATA, PERCPU_ADDR,
+		 pte_val(mk_pte_phys(__pa(&cpu_data[smp_processor_id()]), PAGE_KERNEL)),
+		 PAGE_SHIFT);
+
 	__restore_flags(flags);
+	ia64_srlz_i();
 
 	/*
 	 * Check if the virtually mapped linear page table (VMLPT) overlaps with a mapped
@@ -356,7 +280,7 @@
 #	define vmlpt_bits		(impl_va_bits - PAGE_SHIFT + pte_bits)
 #	define POW2(n)			(1ULL << (n))
 
-	impl_va_bits = ffz(~my_cpu_data.unimpl_va_mask);
+	impl_va_bits = ffz(~(local_cpu_data->unimpl_va_mask | (7UL << 61)));
 
 	if (impl_va_bits < 51 || impl_va_bits > 61)
 		panic("CPU has bogus IMPL_VA_MSB value of %lu!\n", impl_va_bits - 1);
@@ -374,6 +298,8 @@
 	 * enabled.
 	 */
 	ia64_set_pta(pta | (0 << 8) | (vmlpt_bits << 2) | VHPT_ENABLE_BIT);
+
+	ia64_tlb_init();
 }
 
 /*
@@ -390,7 +316,7 @@
 
 	memset(zones_size, 0, sizeof(zones_size));
 
-	max_dma = (PAGE_ALIGN(MAX_DMA_ADDRESS) >> PAGE_SHIFT);
+	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
 	if (max_low_pfn < max_dma)
 		zones_size[ZONE_DMA] = max_low_pfn;
 	else {
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/mm/tlb.c linux/arch/ia64/mm/tlb.c
--- v2.4.3/linux/arch/ia64/mm/tlb.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/mm/tlb.c	Thu Apr  5 12:51:47 2001
@@ -1,11 +1,11 @@
 /*
  * TLB support routines.
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  *
- * 08/02/00 A. Mallick <asit.k.mallick@intel.com>	
- *		Modified RID allocation for SMP 
+ * 08/02/00 A. Mallick <asit.k.mallick@intel.com>
+ *		Modified RID allocation for SMP
  *          Goutham Rao <goutham.rao@intel.com>
  *              IPI based ptc implementation and A-step IPI implementation.
  */
@@ -41,7 +41,7 @@
 };
 
 /*
- * Seralize usage of ptc.g 
+ * Seralize usage of ptc.g
  */
 spinlock_t ptcg_lock = SPIN_LOCK_UNLOCKED; /* see <asm/pgtable.h> */
 
@@ -49,7 +49,7 @@
 
 #include <linux/irq.h>
 
-unsigned long 	flush_end, flush_start, flush_nbits, flush_rid;
+unsigned long	flush_end, flush_start, flush_nbits, flush_rid;
 atomic_t flush_cpu_count;
 
 /*
@@ -71,7 +71,7 @@
 	if (!(flags & IA64_PSR_I)) {
 		saved_tpr = ia64_get_tpr();
 		ia64_srlz_d();
-		ia64_set_tpr(IPI_IRQ - 16);
+		ia64_set_tpr(IA64_IPI_VECTOR - 16);
 		ia64_srlz_d();
 		local_irq_enable();
 	}
@@ -97,13 +97,14 @@
 	/*
 	 * Wait for other CPUs to finish purging entries.
 	 */
-#if (defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_BSTEP_SPECIFIC))
+#if defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_ITANIUM_BSTEP_SPECIFIC)
 	{
+		extern void smp_resend_flush_tlb (void);
 		unsigned long start = ia64_get_itc();
+
 		while (atomic_read(&flush_cpu_count) > 0) {
-			if ((ia64_get_itc() - start) > 40000UL) {
-				atomic_set(&flush_cpu_count, smp_num_cpus - 1);
-				smp_send_flush_tlb();
+			if ((ia64_get_itc() - start) > 400000UL) {
+				smp_resend_flush_tlb();
 				start = ia64_get_itc();
 			}
 		}
@@ -148,7 +149,7 @@
 		if (tsk_context == ia64_ctx.next) {
 			if (++ia64_ctx.next >= ia64_ctx.limit) {
 				/* empty range: reset the range limit and start over */
-				if (ia64_ctx.next > max_ctx) 
+				if (ia64_ctx.next > max_ctx)
 					ia64_ctx.next = 300;
 				ia64_ctx.limit = max_ctx + 1;
 				goto repeat;
@@ -166,11 +167,11 @@
 {
 	unsigned long i, j, flags, count0, count1, stride0, stride1, addr;
 
-	addr    = my_cpu_data.ptce_base;
-	count0  = my_cpu_data.ptce_count[0];
-	count1  = my_cpu_data.ptce_count[1];
-	stride0 = my_cpu_data.ptce_stride[0];
-	stride1 = my_cpu_data.ptce_stride[1];
+	addr    = local_cpu_data->ptce_base;
+	count0  = local_cpu_data->ptce_count[0];
+	count1  = local_cpu_data->ptce_count[1];
+	stride0 = local_cpu_data->ptce_stride[0];
+	stride1 = local_cpu_data->ptce_stride[1];
 
 	local_irq_save(flags);
 	for (i = 0; i < count0; ++i) {
@@ -249,11 +250,11 @@
 	ia64_ptce_info_t ptce_info;
 
 	ia64_get_ptce(&ptce_info);
-	my_cpu_data.ptce_base = ptce_info.base;
-	my_cpu_data.ptce_count[0] = ptce_info.count[0];
-	my_cpu_data.ptce_count[1] = ptce_info.count[1];
-	my_cpu_data.ptce_stride[0] = ptce_info.stride[0];
-	my_cpu_data.ptce_stride[1] = ptce_info.stride[1];
+	local_cpu_data->ptce_base = ptce_info.base;
+	local_cpu_data->ptce_count[0] = ptce_info.count[0];
+	local_cpu_data->ptce_count[1] = ptce_info.count[1];
+	local_cpu_data->ptce_stride[0] = ptce_info.stride[0];
+	local_cpu_data->ptce_stride[1] = ptce_info.stride[1];
 
 	__flush_tlb_all();		/* nuke left overs from bootstrapping... */
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/Makefile linux/arch/ia64/sn/Makefile
--- v2.4.3/linux/arch/ia64/sn/Makefile	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/Makefile	Thu Apr  5 12:51:47 2001
@@ -8,12 +8,11 @@
 EXTRA_CFLAGS	:= -DSN -DLANGUAGE_C=1 -D_LANGUAGE_C=1 -I. -DBRINGUP \
 		   -DDIRECT_L1_CONSOLE -DNUMA_BASE -DSIMULATED_KLGRAPH \
 		   -DNUMA_MIGR_CONTROL -DLITTLE_ENDIAN -DREAL_HARDWARE \
-		   -DNEW_INTERRUPTS -DCONFIG_IA64_SGI_IO
+		   -DNEW_INTERRUPTS
 all: sn.a
 
 O_TARGET        = sn.a
-O_HEADERS       =
-O_OBJS          = sn1/sn1.a
+obj-y           = sn1/sn1.a
 
 clean::
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/fprom/Makefile linux/arch/ia64/sn/fprom/Makefile
--- v2.4.3/linux/arch/ia64/sn/fprom/Makefile	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/fprom/Makefile	Thu Apr  5 12:51:47 2001
@@ -13,6 +13,7 @@
 LIB     = ../../lib/lib.a
 
 OBJ=fpromasm.o main.o  fw-emu.o fpmem.o
+obj-y=fprom
 
 fprom: $(OBJ)
 	$(LD) -static -Tfprom.lds -o fprom $(OBJ) $(LIB)
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/fprom/fw-emu.c linux/arch/ia64/sn/fprom/fw-emu.c
--- v2.4.3/linux/arch/ia64/sn/fprom/fw-emu.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/fprom/fw-emu.c	Thu Apr  5 12:51:47 2001
@@ -8,6 +8,8 @@
  * Copyright (C) 2000 Silicon Graphics, Inc.
  * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
  */
+#include <linux/config.h>
+
 #include <asm/efi.h>
 #include <asm/pal.h>
 #include <asm/sal.h>
@@ -62,6 +64,7 @@
 func_ptr_t	ap_entry;
 
 
+static efi_runtime_services_t    *efi_runtime_p;
 static char fw_mem[(  sizeof(efi_system_table_t)
 		    + sizeof(efi_runtime_services_t)
 		    + NUM_EFI_DESCS*sizeof(efi_config_table_t)
@@ -88,8 +91,8 @@
 	.text
 	.proc pal_emulator_static
 pal_emulator_static:
-	mov r8=-1
-	cmp.eq p6,p7=6,r28		/* PAL_PTCE_INFO */
+	mov r8=-1;;
+	cmp.eq p6,p7=6,r28;;		/* PAL_PTCE_INFO */
 (p7)	br.cond.sptk.few 1f
 	;;
 	mov r8=0			/* status = 0 */
@@ -98,20 +101,20 @@
 	movl r11=0x1000000000002000	/* stride[0], stride[1] */
 	br.cond.sptk.few rp
 
-1:	cmp.eq p6,p7=14,r28		/* PAL_FREQ_RATIOS */
-(p7)	br.cond.sptk.few 1f
+1:	cmp.eq p6,p7=14,r28;;		/* PAL_FREQ_RATIOS */
+(p7)	br.cond.sptk.few 1f;;
 	mov r8=0			/* status = 0 */
 	movl r9 =0x100000064		/* proc_ratio (1/100) */
 	movl r10=0x100000100		/* bus_ratio<<32 (1/256) */
 	movl r11=0x10000000a		/* itc_ratio<<32 (1/100) */
 
-1:	cmp.eq p6,p7=22,r28		/* PAL_MC_DRAIN */
-(p7)	br.cond.sptk.few 1f
+1:	cmp.eq p6,p7=22,r28;;		/* PAL_MC_DRAIN */
+(p7)	br.cond.sptk.few 1f;;
 	mov r8=0
 	br.cond.sptk.few rp
 
-1:	cmp.eq p6,p7=23,r28		/* PAL_MC_EXPECTED */
-(p7)	br.cond.sptk.few 1f
+1:	cmp.eq p6,p7=23,r28;;		/* PAL_MC_EXPECTED */
+(p7)	br.cond.sptk.few 1f;;
 	mov r8=0
 	br.cond.sptk.few rp
 
@@ -256,6 +259,36 @@
 	_fp->gp = __fwtab_pa(base_nasid, _fp->gp);
 }
 
+void
+fix_virt_function_pointer(void *fptr)
+{
+        func_ptr_t      *fp;
+
+        fp = fptr;
+        fp->pc = fp->pc | PAGE_OFFSET;
+        fp->gp = fp->gp | PAGE_OFFSET;
+}
+
+
+int
+efi_set_virtual_address_map(void)
+{
+        efi_runtime_services_t            *runtime;
+
+        runtime = efi_runtime_p;
+        fix_virt_function_pointer((void*)runtime->get_time);
+        fix_virt_function_pointer((void*)runtime->set_time);
+        fix_virt_function_pointer((void*)runtime->get_wakeup_time);
+        fix_virt_function_pointer((void*)runtime->set_wakeup_time);
+        fix_virt_function_pointer((void*)runtime->set_virtual_address_map);
+        fix_virt_function_pointer((void*)runtime->get_variable);
+        fix_virt_function_pointer((void*)runtime->get_next_variable);
+        fix_virt_function_pointer((void*)runtime->set_variable);
+        fix_virt_function_pointer((void*)runtime->get_next_high_mono_count);
+        fix_virt_function_pointer((void*)runtime->reset_system);
+        return EFI_SUCCESS;;
+}
+
 
 void
 sys_fw_init (const char *args, int arglen, int bsp)
@@ -305,7 +338,7 @@
 
 	cp = fw_mem;
 	efi_systab  = (void *) cp; cp += sizeof(*efi_systab);
-	efi_runtime = (void *) cp; cp += sizeof(*efi_runtime);
+	efi_runtime_p = efi_runtime = (void *) cp; cp += sizeof(*efi_runtime);
 	efi_tables  = (void *) cp; cp += NUM_EFI_DESCS*sizeof(*efi_tables);
 	sal_systab  = (void *) cp; cp += sizeof(*sal_systab);
 	sal_ed      = (void *) cp; cp += sizeof(*sal_ed);
@@ -354,7 +387,7 @@
 	efi_runtime->set_time = __fwtab_pa(base_nasid, &efi_unimplemented);
 	efi_runtime->get_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented);
 	efi_runtime->set_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented);
-	efi_runtime->set_virtual_address_map = __fwtab_pa(base_nasid, &efi_success);
+	efi_runtime->set_virtual_address_map = __fwtab_pa(base_nasid, &efi_set_virtual_address_map);
 	efi_runtime->get_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
 	efi_runtime->get_next_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
 	efi_runtime->set_variable = __fwtab_pa(base_nasid, &efi_unimplemented);
@@ -370,10 +403,11 @@
 	fix_function_pointer(&efi_get_time);
 	fix_function_pointer(&efi_success);
 	fix_function_pointer(&efi_reset_system);
+	fix_function_pointer(&efi_set_virtual_address_map);
 
 	/* fill in the ACPI system table: */
 	memcpy(acpi_systab->signature, "RSD PTR ", 8);
-	acpi_systab->rsdt = (acpi_rsdt_t*)__fwtab_pa(base_nasid, acpi_rsdt);
+	acpi_systab->rsdt = (struct acpi_rsdt*)__fwtab_pa(base_nasid, acpi_rsdt);
 
 	memcpy(acpi_rsdt->header.signature, "RSDT",4);
 	acpi_rsdt->header.length = sizeof(acpi_rsdt_t);
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/Makefile linux/arch/ia64/sn/io/Makefile
--- v2.4.3/linux/arch/ia64/sn/io/Makefile	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/io/Makefile	Thu Apr  5 12:51:47 2001
@@ -18,15 +18,15 @@
 EXTRA_CFLAGS	:= -DSN -DLANGUAGE_C=1 -D_LANGUAGE_C=1 -I. -DBRINGUP \
 		   -DDIRECT_L1_CONSOLE -DNUMA_BASE -DSIMULATED_KLGRAPH \
 		   -DNUMA_MIGR_CONTROL -DLITTLE_ENDIAN -DREAL_HARDWARE \
-		   -DNEW_INTERRUPTS -DCONFIG_IA64_SGI_IO
+		   -DNEW_INTERRUPTS
 O_TARGET := sgiio.o
-O_OBJS   := stubs.o sgi_if.o pciio.o pcibr.o xtalk.o xbow.o xswitch.o hubspc.o \
-		klgraph_hack.o io.o hubdev.o \
+obj-y   := stubs.o sgi_if.o pciio.o pcibr.o xtalk.o xbow.o xswitch.o hubspc.o \
+		klgraph_hack.o io.o hubdev.o huberror.o \
 		hcl.o labelcl.o invent.o klgraph.o klconflib.o sgi_io_sim.o \
 		module.o sgi_io_init.o klgraph_hack.o ml_SN_init.o \
-		ml_SN_intr.o ip37.o \
+		ml_SN_intr.o ip37.o pciba.o \
 		ml_iograph.o hcl_util.o cdl.o \
 		mem_refcnt.o devsupport.o alenlist.o pci_bus_cvlink.o \
-		eeprom.o pci.o pci_dma.o l1.o l1_command.o
+		eeprom.o pci.o pci_dma.o l1.o l1_command.o ate_utils.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/alenlist.c linux/arch/ia64/sn/io/alenlist.c
--- v2.4.3/linux/arch/ia64/sn/io/alenlist.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/alenlist.c	Thu Apr  5 12:51:47 2001
@@ -201,8 +201,8 @@
 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) atomicAddInt((ptr), 1);
-#define DECR_COUNT(ptr) atomicAddInt((ptr), -1);
+#define INCR_COUNT(ptr) atomic_inc((ptr));
+#define DECR_COUNT(ptr) atomic_dec((ptr));
 #else
 #define INCR_COUNT(ptr)
 #define DECR_COUNT(ptr)
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/cdl.c linux/arch/ia64/sn/io/cdl.c
--- v2.4.3/linux/arch/ia64/sn/io/cdl.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/cdl.c	Thu Apr  5 12:51:47 2001
@@ -67,7 +67,7 @@
 void
 cdl_del(cdl_p reg)
 {
-	printk("SGI IO INFRASTRUCTURE - cdl_del not supported.\n");
+	return;
 }
 
 /*
@@ -77,7 +77,7 @@
   Do nothing.
  */
 int
-cdl_add_driver(cdl_p reg, int key1, int key2, char *prefix, int flags)
+cdl_add_driver(cdl_p reg, int key1, int key2, char *prefix, int flags, cdl_drv_f *func)
 {
     return 0;
 }
@@ -86,11 +86,9 @@
  * cdl_del_driver: Not supported.
  */
 void
-cdl_del_driver(cdl_p reg,
-	       char *prefix)
+cdl_del_driver(cdl_p reg, char *prefix, cdl_drv_f *func)
 {
-
-	printk("SGI IO INFRASTRUCTURE - cdl_del_driver not supported.\n");
+	return;
 }
 
 /*
@@ -106,7 +104,7 @@
  */
 int
 cdl_add_connpt(cdl_p reg, int part_num, int mfg_num, 
-	       devfs_handle_t connpt)
+	       devfs_handle_t connpt, int drv_flags)
 {
 	int i;
 	
@@ -123,27 +121,12 @@
 			if (sgi_infrastructure_drivers[i].attach) {
 			    return(sgi_infrastructure_drivers[i].attach(connpt));
 			}
-#ifdef BRINGUP
-			/*
-			 * XXX HACK ALERT bypassing fops for now..
-			 */
-			else {
-			    printk("cdl_add_connpt: NEED FOPS FOR OUR DRIVERS!!\n");
-			    printk("cdl_add_connpt: part_num= 0x%x  mfg_num= 0x%x\n",
-				part_num, mfg_num);
-			    return(-1);
-			}
-#endif /* BRINGUP */
 		} else {
 			continue;
 		}
-
-		printk("**** cdl_add_connpt: driver not found for part_num %d mfg_num %d ****\n", part_num, mfg_num);
-
-		return(-1);
 	}	
-	if ( (i == MAX_SGI_IO_INFRA_DRVR) ) 
-		printk("**** cdl_add_connpt: Driver not found for part_num 0x%x mfg_num 0x%x ****\n", part_num, mfg_num);
+
+	/* printk("WARNING: cdl_add_connpt: Driver not found for part_num 0x%x mfg_num 0x%x\n", part_num, mfg_num); */
 
 	return (0);
 }
@@ -151,11 +134,11 @@
 /*
  * cdl_del_connpt: Not implemented.
  */
-void
-cdl_del_connpt(cdl_p reg, int key1, int key2, devfs_handle_t connpt)
+int
+cdl_del_connpt(cdl_p reg, int key1, int key2, devfs_handle_t connpt, int drv_flags)
 {
 
-	printk("SGI IO INFRASTRUCTURE - cdl_del_cdl_del_connpt not supported.\n");
+	return(0);
 }
 
 /*
@@ -166,65 +149,54 @@
 	    char *prefix,
 	    cdl_iter_f * func)
 {
-
-	printk("SGI IO INFRASTRUCTURE - cdl_iterate not supported.\n");
+	return;
 }
 
 async_attach_t 
 async_attach_new(void)
 {
 
-	printk("SGI IO INFRASTRUCTURE - async_attach_new not supported.\n");
 	return(0);
 }
 
 void 
 async_attach_free(async_attach_t aa)
 {
-	printk("SGI IO INFRASTRUCTURE - async_attach_free not supported.\n");
+	return;
 }
 
 async_attach_t 
 async_attach_get_info(devfs_handle_t vhdl)
 {
 
-	printk("SGI IO INFRASTRUCTURE - async_attach_get_info not supported.\n");
 	return(0);
 }
 
 void            
 async_attach_add_info(devfs_handle_t vhdl, async_attach_t aa)
 {
-	printk("SGI IO INFRASTRUCTURE - async_attach_add_info not supported.\n");
+	return;
 
 }
 
 void            
 async_attach_del_info(devfs_handle_t vhdl)
 {
-
-	printk("SGI IO INFRASTRUCTURE - async_attach_del_info not supported.\n");
-
+	return;
 }
 
 void async_attach_signal_start(async_attach_t aa)
 {
-
-	printk("SGI IO INFRASTRUCTURE - async_attach_signal_start not supported.\n");
-
+	return;
 }
 
 void async_attach_signal_done(async_attach_t aa)
 {
-
-	printk("SGI IO INFRASTRUCTURE - async_attach_signal_done not supported.\n");
-
+	return;
 }
 
 void async_attach_waitall(async_attach_t aa)
 {
-
-	printk("SGI IO INFRASTRUCTURE - async_attach_waitall not supported.\n");
-
+	return;
 }
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/devsupport.c linux/arch/ia64/sn/io/devsupport.c
--- v2.4.3/linux/arch/ia64/sn/io/devsupport.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/devsupport.c	Thu Apr  5 12:51:47 2001
@@ -1,5 +1,3 @@
-#define ilvt_t int
-
 /* $Id$
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -28,7 +26,7 @@
 /* =====Generic iobus support===== */
 
 /* String table to hold names of interrupts. */
-#ifdef notyet
+#ifdef LATER
 static struct string_table device_desc_string_table;
 #endif
 
@@ -36,7 +34,7 @@
 static void
 device_desc_init(void)
 {
-#ifdef notyet
+#ifdef LATER
 	string_table_init(&device_desc_string_table);
 #endif
 	FIXME("device_desc_init");
@@ -47,7 +45,7 @@
 static device_desc_t
 device_desc_alloc(void)
 {
-#ifdef notyet
+#ifdef LATER
 	device_desc_t device_desc;
 
 	device_desc = (device_desc_t)kmem_zalloc(sizeof(struct device_desc_s), 0);
@@ -69,7 +67,7 @@
 void
 device_desc_free(device_desc_t device_desc)
 {
-#ifdef notyet
+#ifdef LATER
 	if (!(device_desc->flags & D_IS_ASSOC)) /* sanity */
 		kfree(device_desc);
 #endif
@@ -79,7 +77,7 @@
 device_desc_t
 device_desc_dup(devfs_handle_t dev)
 {
-#ifdef notyet
+#ifdef LATER
 	device_desc_t orig_device_desc, new_device_desc;
 
 
@@ -111,7 +109,7 @@
 device_desc_t	
 device_desc_default_get(devfs_handle_t dev)
 {
-#ifdef notyet
+#ifdef LATER
 	graph_error_t rc;
 	device_desc_t device_desc;
 
@@ -130,7 +128,7 @@
 void		
 device_desc_default_set(devfs_handle_t dev, device_desc_t new_device_desc)
 {
-#ifdef notyet
+#ifdef LATER
 	graph_error_t rc;
 	device_desc_t old_device_desc = NULL;
 
@@ -164,7 +162,7 @@
 devfs_handle_t
 device_desc_intr_target_get(device_desc_t device_desc)
 {
-#ifdef notyet
+#ifdef LATER
 	return(device_desc->intr_target);
 #else
 	FIXME("device_desc_intr_target_get");
@@ -175,7 +173,7 @@
 int
 device_desc_intr_policy_get(device_desc_t device_desc)
 {
-#ifdef notyet
+#ifdef LATER
 	return(device_desc->intr_policy);
 #else
 	FIXME("device_desc_intr_policy_get");
@@ -186,7 +184,7 @@
 ilvl_t
 device_desc_intr_swlevel_get(device_desc_t device_desc)
 {
-#ifdef notyet
+#ifdef LATER
 	return(device_desc->intr_swlevel);
 #else
 	FIXME("device_desc_intr_swlevel_get");
@@ -197,7 +195,7 @@
 char *
 device_desc_intr_name_get(device_desc_t device_desc)
 {
-#ifdef notyet
+#ifdef LATER
 	return(device_desc->intr_name);
 #else
 	FIXME("device_desc_intr_name_get");
@@ -208,7 +206,7 @@
 int
 device_desc_flags_get(device_desc_t device_desc)
 {
-#ifdef notyet
+#ifdef LATER
 	return(device_desc->flags);
 #else
 	FIXME("device_desc_flags_get");
@@ -240,7 +238,7 @@
 void
 device_desc_intr_name_set(device_desc_t device_desc, char *name)
 {
-#ifdef notyet
+#ifdef LATER
 	if ( device_desc != (device_desc_t)0 )
 		device_desc->intr_name = string_table_insert(&device_desc_string_table, name);
 #else
@@ -325,7 +323,7 @@
 static void
 dev_admin_registry_init(dev_admin_registry_t *registry)
 {
-#ifdef notyet
+#ifdef LATER
 	if ( registry != (dev_admin_registry_t *)0 )
 		DEV_ADMIN_REGISTRY_INITLOCK(&registry->reg_lock,
 				    "dev_admin_registry_lock");
@@ -349,7 +347,7 @@
 		       char			*name,
 		       char			*val)
 {
-#ifdef notyet
+#ifdef LATER
 	dev_admin_list_t	*reg_entry;
 	dev_admin_list_t	*scan = 0;
 
@@ -404,7 +402,7 @@
 static char *
 dev_admin_registry_find(dev_admin_registry_t *registry,char *name)
 {
-#ifdef notyet
+#ifdef LATER
 	dev_admin_list_t	*scan = 0;
 	
 	DEV_ADMIN_REGISTRY_RDLOCK(&registry->reg_lock);
@@ -433,7 +431,7 @@
 device_admin_info_get(devfs_handle_t	dev_vhdl,
 		      char		*info_lbl)
 {
-#ifdef notyet
+#ifdef LATER
 	char		*info = 0;
 
 	/* return value need not be GRAPH_SUCCESS as the labelled
@@ -460,7 +458,7 @@
 		      char		*dev_info_lbl,
 		      char		*dev_info_val)
 {
-#ifdef notyet
+#ifdef LATER
 	graph_error_t		rv;
 	arbitrary_info_t	old_info;
 
@@ -570,7 +568,7 @@
 device_driver_admin_info_get(char		*driver_prefix,
 			     char		*driver_info_lbl)
 {
-#ifdef notyet
+#ifdef LATER
 	device_driver_t driver;
 
 	driver = device_driver_get(driver_prefix);
@@ -592,7 +590,7 @@
 			     char		*driver_info_lbl,
 			     char		*driver_info_val)
 {
-#ifdef notyet
+#ifdef LATER
 	device_driver_t driver;
 
 	driver = device_driver_get(driver_prefix);
@@ -623,7 +621,7 @@
 void
 device_admin_table_init(void)
 {
-#ifdef notyet
+#ifdef LATER
 	extended_dev_admin_table_size = 0;
 	mrinit(&extended_dev_admin_table_lock,
 	       "extended_dev_admin_table_lock");
@@ -638,7 +636,7 @@
 void
 device_admin_table_update(char *name,char *label,char *value)
 {
-#ifdef notyet
+#ifdef LATER
 	dev_admin_info_t	*p;
 
 	mrupdate(&extended_dev_admin_table_lock);
@@ -678,7 +676,7 @@
 void
 device_driver_admin_table_init(void)
 {
-#ifdef notyet
+#ifdef LATER
 	extended_drv_admin_table_size = 0;
 	mrinit(&extended_drv_admin_table_lock,
 	       "extended_drv_admin_table_lock");
@@ -693,7 +691,7 @@
 void
 device_driver_admin_table_update(char *name,char *label,char *value)
 {
-#ifdef notyet
+#ifdef LATER
 	dev_admin_info_t	*p;
 
 	mrupdate(&extended_dev_admin_table_lock);
@@ -730,7 +728,7 @@
 void
 device_admin_info_update(devfs_handle_t	dev_vhdl)
 {
-#ifdef notyet
+#ifdef LATER
 	int			i = 0;
 	dev_admin_info_t	*scan;
 	devfs_handle_t		scan_vhdl;
@@ -779,7 +777,7 @@
 void
 device_driver_admin_info_update(device_driver_t	driver)
 {
-#ifdef notyet
+#ifdef LATER
 	int			i = 0;
 	dev_admin_info_t	*scan;
 
@@ -823,7 +821,7 @@
 */
 
 #define DEVICE_DRIVER_HASH_SIZE 32
-#ifdef notyet
+#ifdef LATER
 lock_t device_driver_lock[DEVICE_DRIVER_HASH_SIZE];
 device_driver_t device_driver_hash[DEVICE_DRIVER_HASH_SIZE];
 static struct string_table driver_prefix_string_table;
@@ -835,7 +833,7 @@
 void
 device_driver_init(void)
 {
-#ifdef notyet
+#ifdef LATER
 	int i;
 	extern void alenlist_init(void);
 	extern void hwgraph_init(void);
@@ -849,7 +847,7 @@
 	string_table_init(&driver_prefix_string_table);
 
 	for (i=0; i<DEVICE_DRIVER_HASH_SIZE; i++) {
-		spinlock_init(&device_driver_lock[i], "devdrv");
+		spin_lock_init(&device_driver_lock[i]);
 		device_driver_hash[i] = NULL;
 	}
 
@@ -877,7 +875,7 @@
 static int
 driver_prefix_hash(char *prefix)
 {
-#ifdef notyet
+#ifdef LATER
 	int accum = 0;
 	char nextchar;
 
@@ -903,10 +901,10 @@
 device_driver_t
 device_driver_alloc(char *prefix)
 {
-#ifdef notyet
+#ifdef LATER
 	int which_hash;
 	device_driver_t new_driver;
-	int s;
+	unsigned long s;
 		
 	which_hash = driver_prefix_hash(prefix);
 
@@ -964,9 +962,9 @@
 void
 device_driver_free(device_driver_t driver)
 {
-#ifdef notyet
+#ifdef LATER
 	int which_hash;
-	int s;
+	unsigned long s;
 
 	if (!driver)
 		return;
@@ -1027,10 +1025,10 @@
 device_driver_t
 device_driver_get(char *prefix)
 {
-#ifdef notyet
+#ifdef LATER
 	int which_hash;
 	device_driver_t drvscan;
-	int s;
+	unsigned long s;
 
 	if (prefix == NULL)
 		return(NULL);
@@ -1060,7 +1058,7 @@
 device_driver_t
 device_driver_getbydev(devfs_handle_t device)
 {
-#ifdef notyet
+#ifdef LATER
 	struct bdevsw *my_bdevsw;
 	struct cdevsw *my_cdevsw;
 
@@ -1093,7 +1091,7 @@
 			struct bdevsw *my_bdevsw,
 			struct cdevsw *my_cdevsw)
 {
-#ifdef notyet
+#ifdef LATER
 	int i;
 
 	if (!driver)
@@ -1194,7 +1192,7 @@
 void 
 device_info_set(devfs_handle_t device, void *info)
 {
-#ifdef notyet
+#ifdef LATER
 	hwgraph_fastinfo_set(device, (arbitrary_info_t)info);
 #endif
 	FIXME("device_info_set");
@@ -1207,7 +1205,7 @@
 void *
 device_info_get(devfs_handle_t device)
 {
-#ifdef notyet
+#ifdef LATER
 	return((void *)hwgraph_fastinfo_get(device));
 #else
 	FIXME("device_info_get");
@@ -1222,7 +1220,7 @@
 int
 device_driver_sysgen_thread_pri_get(char *dev_prefix)
 {
-#ifdef notyet
+#ifdef LATER
 	int pri;
 	char *pri_s;
 	char *class;
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/eeprom.c linux/arch/ia64/sn/io/eeprom.c
--- v2.4.3/linux/arch/ia64/sn/io/eeprom.c	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/io/eeprom.c	Thu Apr  5 12:51:47 2001
@@ -53,7 +53,6 @@
 #include <asm/sn/labelcl.h>
 #include <asm/sn/eeprom.h>
 #include <asm/sn/ksys/i2c.h>
-#include <asm/sn/cmn_err.h>
 /* #include <sys/SN/SN1/ip27log.h> */
 #include <asm/sn/router.h>
 #include <asm/sn/module.h>
@@ -949,6 +948,7 @@
 #else
     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 */
@@ -981,11 +981,26 @@
 	}
 
 	/* check response */
-	if( sc_interpret_resp( msg, 5, 
+	if( (resp = sc_interpret_resp( msg, 5, 
 			       L1_ARG_INT, &spd_len,
-			       L1_ARG_UNKNOWN, &len, spd_p ) < 0 )
+			       L1_ARG_UNKNOWN, &len, spd_p )) < 0 )
 	{
-	    return( EEP_L1 );
+            /*
+             * 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 )
@@ -1201,7 +1216,9 @@
 #else
     int r;
     uint64_t uid = 0;
+#ifdef LOG_GETENV
     char uid_str[32];
+#endif
     int l1_compt, subch;
 
     if ( IS_RUNNING_ON_SIMULATOR() )
@@ -1228,6 +1245,13 @@
     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:
@@ -1252,13 +1276,6 @@
 	l1_compt = L1_EEP_PIMM( component & COMPT_MASK );
 	break;
 
-      case C_DIMM:
-	/* one of the DIMMs */
-	l1_compt = L1_EEP_DIMM( component & COMPT_MASK );
-	r = read_spd( scp, subch, l1_compt, buf->spd );
-	sc_close( scp, subch );
-	return r;
-
       default:
 	/* unsupported board type */
 	sc_close( scp, subch );
@@ -1297,8 +1314,7 @@
 	scp = get_l1sc();
     }
     else {
-	elsc_t *get_elsc(void);
-	scp = get_elsc();
+	scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
     }
 
     return _cbrick_eeprom_read( buf, scp, component );
@@ -1333,8 +1349,7 @@
 	scp = get_l1sc();
     }
     else {
-	elsc_t *get_elsc(void);
-	scp = get_elsc();
+	scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
     }
 
     if( (subch = sc_open( scp, L1_ADDR_LOCALIO )) < 0 )
@@ -1350,9 +1365,11 @@
 
 	if( r != EEP_OK ) {
 	    sc_close( scp, subch );
-#ifdef BRINGUP /* Once EEPROMs are universally available, remove this */
+	/*
+	 * 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() );
-#endif /* BRINGUP */
 	    return r;
 	}
 	break;
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/hcl.c linux/arch/ia64/sn/io/hcl.c
--- v2.4.3/linux/arch/ia64/sn/io/hcl.c	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/io/hcl.c	Thu Apr  5 12:51:47 2001
@@ -30,6 +30,7 @@
 #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.
@@ -41,7 +42,9 @@
 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.
@@ -49,6 +52,12 @@
 spinlock_t hcl_spinlock;
 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 
@@ -98,6 +107,7 @@
 }
 
 struct file_operations hcl_fops = {
+	(struct module *)0,
 	NULL,		/* lseek - default */
 	NULL,		/* read - general block-dev read */
 	NULL,		/* write - general block-dev write */
@@ -110,9 +120,9 @@
 	hcl_close,	/* release */
 	NULL,		/* fsync */
 	NULL,		/* fasync */
-	NULL,		/* check_media_change */
-	NULL,		/* revalidate */
-	NULL		/* lock */
+	NULL,		/* lock */
+	NULL,		/* readv */
+	NULL,		/* writev */
 };
 
 
@@ -134,13 +144,15 @@
 	extern struct string_table label_string_table;
 	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);
-#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
+
 	hcl_debug = hcl_debug_init;
 	printk ("%s: hcl_debug: 0x%0x\n", HCL_NAME, hcl_debug);
-#endif
 	printk ("\n%s: boot_options: 0x%0x\n", HCL_NAME, boot_options);
+#endif
+
 	spin_lock_init(&hcl_spinlock);
 
 	/*
@@ -148,7 +160,7 @@
 	 */
 	rv = hwgraph_path_add(NULL, "hw", &hwgraph_root);
 	if (rv)
-		printk ("init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
+		printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
 
 	/*
 	 * Create the hcl driver to support inventory entry manipulations.
@@ -171,6 +183,15 @@
 	 */
 	string_table_init(&label_string_table);
 
+	/*
+	 * Create the directory that links Linux bus numbers to our Xwidget.
+	 */
+	rv = hwgraph_path_add(hwgraph_root, "linux/busnum", &linux_busnum);
+	if (linux_busnum == NULL) {
+		panic("HCL: Unable to create hw/linux/busnum\n");
+		return(0);
+	}
+
 	return(0);
 
 }
@@ -190,7 +211,6 @@
 {
     while ( (*str != '\0') && !isspace (*str) )
     {
-	printk("HCL: Boot time parameter %s\n", str);
 #ifdef CONFIG_HCL_DEBUG
         if (strncmp (str, "all", 3) == 0) {
             hcl_debug_init |= HCL_DEBUG_ALL;
@@ -445,7 +465,7 @@
 		/*
 		 * We need to clean up!
 		 */
-		printk("HCL: Unable to set the connect point to it's parent 0x%p\n",
+		printk(KERN_WARNING "HCL: Unable to set the connect point to it's parent 0x%p\n",
 			new_devfs_handle);
 	}
 
@@ -561,19 +581,44 @@
 {
 
 	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, (const char *)&path[name_start],
+			       DEVFS_FL_DEFAULT, path,
 			       &handle, NULL);
 
 	name_start = devfs_generate_path (handle, path, 1024);
@@ -744,7 +789,6 @@
 		*placeptr = which_place + 1;
 		if (curr && name) {
 			tempname = devfs_get_name(*target, &namelen);
-			printk("hwgraph_edge_get_next: Component name = %s, length = %d\n", tempname, namelen);
 			if (tempname && namelen)
 				strcpy(name, tempname);
 		}
@@ -1335,7 +1379,7 @@
 		return(DEVNAME_UNKNOWN);
 }
 
-#ifdef IRIX
+#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
@@ -1440,7 +1484,7 @@
 
   return (mem_vhdl);
 }
-#endif /* IRIX */
+#endif /* LATER */
 
 
 /*
@@ -1454,7 +1498,7 @@
 {
 	devfs_handle_t xx = NULL;
 
-	printk("FIXME: hwgraph_char_device_add() called. Use hwgraph_register.\n");
+	printk("WARNING: hwgraph_char_device_add() not supported .. use hwgraph_register.\n");
 	*devhdl = xx;	// Must set devhdl
 	return(GRAPH_SUCCESS);
 }
@@ -1462,14 +1506,13 @@
 graph_error_t
 hwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr)
 {
-	printk("FIXME: hwgraph_edge_remove\n");
+	printk("WARNING: hwgraph_edge_remove NOT supported.\n");
 	return(GRAPH_ILLEGAL_REQUEST);
 }
 
 graph_error_t
 hwgraph_vertex_unref(devfs_handle_t vhdl)
 {
-	printk("FIXME: hwgraph_vertex_unref\n");
 	return(GRAPH_ILLEGAL_REQUEST);
 }
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/hcl_util.c linux/arch/ia64/sn/io/hcl_util.c
--- v2.4.3/linux/arch/ia64/sn/io/hcl_util.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/hcl_util.c	Thu Apr  5 12:51:47 2001
@@ -137,6 +137,20 @@
 	}
 }
 
+/*
+** 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
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/hubdev.c linux/arch/ia64/sn/io/hubdev.c
--- v2.4.3/linux/arch/ia64/sn/io/hubdev.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/hubdev.c	Thu Apr  5 12:51:47 2001
@@ -31,7 +31,7 @@
 void
 hubdev_init(void)
 {
-	mutex_init(&hubdev_callout_mutex, MUTEX_DEFAULT, "hubdev");
+	mutex_init(&hubdev_callout_mutex);
         hubdev_callout_list = NULL;
 }
         
@@ -45,9 +45,9 @@
         callout =  (hubdev_callout_t *)kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP);
         ASSERT(callout);
         
-	mutex_lock(&hubdev_callout_mutex, PZERO);
+	mutex_lock(&hubdev_callout_mutex);
         /*
-         * Insert at the front of the list
+         * Insert at the end of the list
          */
         callout->fp = hubdev_callout_list;
         hubdev_callout_list = callout;
@@ -62,7 +62,7 @@
         
         ASSERT(attach_method);
    
-	mutex_lock(&hubdev_callout_mutex, PZERO);
+	mutex_lock(&hubdev_callout_mutex);
         /*
          * Remove registry element containing attach_method
          */
@@ -86,7 +86,7 @@
         hubdev_callout_t *p;
         int errcode;
 
-	mutex_lock(&hubdev_callout_mutex, PZERO);
+	mutex_lock(&hubdev_callout_mutex);
         
         for (p = hubdev_callout_list; p != NULL; p = p->fp) {
                 ASSERT(p->attach_method);
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/huberror.c linux/arch/ia64/sn/io/huberror.c
--- v2.4.3/linux/arch/ia64/sn/io/huberror.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ia64/sn/io/huberror.c	Thu Apr  5 12:51:47 2001
@@ -0,0 +1,475 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2000 by Alan Mayer
+ */
+
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/smp.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/nodemask.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/synergy.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/xtalk/xtalk.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/intr.h>
+
+extern void hubni_eint_init(cnodeid_t cnode);
+extern void hubii_eint_init(cnodeid_t cnode);
+extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep);
+extern void snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs);
+
+extern int maxcpus;
+
+#define HUB_ERROR_PERIOD        (120 * HZ)      /* 2 minutes */
+
+
+void
+hub_error_clear(nasid_t nasid)
+{
+	int i;
+	hubreg_t idsr;
+	int sn;
+
+	for(sn=0; sn<NUM_SUBNODES; sn++) {
+		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_PEND, -1);
+		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS0_A_CLR, -1);
+		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS0_B_CLR, -1);
+		REMOTE_HUB_PI_S(nasid, sn, PI_SPURIOUS_HDR_0, 0);
+		REMOTE_HUB_PI_S(nasid, sn, PI_SPURIOUS_HDR_1, 0);
+	}
+
+	REMOTE_HUB_L(nasid, MD_DIR_ERROR_CLR);
+	REMOTE_HUB_L(nasid, MD_MEM_ERROR_CLR);
+	REMOTE_HUB_L(nasid, MD_MISC1_ERROR_CLR);
+	REMOTE_HUB_L(nasid, MD_PROTOCOL_ERR_CLR);
+
+    /*
+     * Make sure spurious write response errors are cleared
+     * (values are from hub_set_prb())
+     */
+    for (i = 0; i <= HUB_WIDGET_ID_MAX - HUB_WIDGET_ID_MIN + 1; i++) {
+        iprb_t prb;
+
+	prb.iprb_regval = REMOTE_HUB_L(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)));
+
+        /* Clear out some fields */
+        prb.iprb_ovflow = 1;
+        prb.iprb_bnakctr = 0;
+        prb.iprb_anakctr = 0;
+
+	/*
+	 * PIO reads in fire-and-forget mode on bedrock 1.0 don't
+	 * frob the credit count properly, making the responses appear
+	 * spurious.  So don't use fire-and-forget mode.  Bug 761802.
+	 */
+        prb.iprb_ff = 0;        /* disable fire-and-forget mode by default */
+
+        prb.iprb_xtalkctr = 3;  /* approx. PIO credits for the widget */
+
+        REMOTE_HUB_S(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)), prb.iprb_regval);
+    }
+
+    REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, -1);
+    idsr = REMOTE_HUB_L(nasid, IIO_IIDSR);
+    REMOTE_HUB_S(nasid, IIO_IIDSR, (idsr & ~(IIO_IIDSR_SENT_MASK)));
+
+    REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
+    /* No need to clear NI_PORT_HEADER regs; they are continually overwritten*/
+
+    REMOTE_HUB_S(nasid, LB_ERROR_MASK_CLR, -1);
+    REMOTE_HUB_S(nasid, LB_ERROR_HDR1, 0);
+
+    /* Clear XB error regs, in order */
+    for (i = 0;
+         i <= XB_FIRST_ERROR_CLEAR - XB_POQ0_ERROR_CLEAR;
+         i += sizeof(hubreg_t)) {
+        REMOTE_HUB_S(nasid, XB_POQ0_ERROR_CLEAR + i, 0);
+    }
+}
+
+
+/*
+ * Function	: hub_error_init
+ * Purpose	: initialize the error handling requirements for a given hub.
+ * Parameters	: cnode, the compact nodeid.
+ * Assumptions	: Called only once per hub, either by a local cpu. Or by a 
+ *			remote cpu, when this hub is headless.(cpuless)
+ * Returns	: None
+ */
+
+void
+hub_error_init(cnodeid_t cnode)
+{
+	nasid_t nasid;
+
+    nasid = cnodeid_to_nasid(cnode);
+    hub_error_clear(nasid);
+
+#ifdef ajm
+    if (cnode == 0) {
+	/*
+	 * Allocate log for storing the node specific error info
+	 */
+	for (i = 0; i < numnodes; i++) {
+	    kl_error_log[i]  = kmem_zalloc_node(sizeof(sn0_error_log_t), 
+						KM_NOSLEEP, i);
+	    hub_err_count[i] = kmem_zalloc_node(sizeof(hub_errcnt_t),
+						VM_DIRECT | KM_NOSLEEP, i);
+	    ASSERT_ALWAYS(kl_error_log[i] && hub_err_count[i]);
+	}
+    }
+
+    /*
+     * Assumption: There will be only one cpu who will initialize
+     * a hub. we need to setup the ii and each pi error interrupts.
+     * The SN1 hub (bedrock) has two PI, one for up to two processors.
+     */
+
+    if (cpuid_to_cnodeid(smp_processor_id()) == cnode) { 
+	int generic_intr_mask = PI_ERR_GENERIC; /* These interrupts are sent to only 1 CPU per NODE */
+
+	ASSERT_ALWAYS(kl_error_log[cnode]);
+	ASSERT_ALWAYS(hub_err_count[cnode]);
+	MD_ERR_LOG_INIT(kl_error_log[cnode]);
+
+	/* One for each CPU */
+	recover_error_init(RECOVER_ERROR_TABLE(cnode, 0));
+	recover_error_init(RECOVER_ERROR_TABLE(cnode, 1));
+	recover_error_init(RECOVER_ERROR_TABLE(cnode, 2));
+	recover_error_init(RECOVER_ERROR_TABLE(cnode, 3));
+
+	/*
+	 * Setup error intr masks.
+	 */
+	for(sn=0; sn<NUM_SUBNODES; sn++) {
+		int cpuA_present = REMOTE_HUB_PI_L(nasid, sn, PI_CPU_ENABLE_A);
+		int cpuB_present = REMOTE_HUB_PI_L(nasid, sn, PI_CPU_ENABLE_B);
+
+		if (cpuA_present) {
+			if (cpuB_present) {		/* A && B */
+	    			REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A,
+					(PI_FATAL_ERR_CPU_B | PI_MISC_ERR_CPU_A|generic_intr_mask));
+	    			REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B,
+					(PI_FATAL_ERR_CPU_A | PI_MISC_ERR_CPU_B));
+
+			} else {			/* A && !B */
+	    			REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A,
+					(PI_FATAL_ERR_CPU_A | PI_MISC_ERR_CPU_A|generic_intr_mask));
+			}
+			generic_intr_mask = 0;
+		} else {
+			if (cpuB_present) {		/* !A && B */
+	    			REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B,
+					(PI_FATAL_ERR_CPU_B | PI_MISC_ERR_CPU_B|generic_intr_mask));
+				generic_intr_mask = 0;
+
+			} else {			/* !A && !B */
+				/* nothing to set up */
+			}
+		}
+	}
+
+	/*
+	 * Turn off UNCAC_UNCORR interrupt in the masks. Anyone interested
+	 * in these errors will peek at the int pend register to see if its
+	 * set.
+	 */ 
+	for(sn=0; sn<NUM_SUBNODES; sn++) {
+		misc = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_INT_MASK_A);
+		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A, (misc & ~PI_ERR_UNCAC_UNCORR_A));
+		misc = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_INT_MASK_B);
+		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B, (misc & ~PI_ERR_UNCAC_UNCORR_B));
+	}
+
+	/*
+	 * enable all error indicators to turn on, in case of errors.
+	 *
+	 * This is not good on single cpu node boards.
+	 **** LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL);
+	 */
+	for(sn=0; sn<NUM_SUBNODES; sn++) {
+		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS1_A_CLR, 0);
+		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS1_B_CLR, 0);
+	}
+
+	/* Set up stack for each present processor */
+	for(sn=0; sn<NUM_SUBNODES; sn++) {
+		if (REMOTE_HUB_PI_L(nasid, sn, PI_CPU_PRESENT_A)) {
+	    	SN0_ERROR_LOG(cnode)->el_spool_cur_addr[0] =
+			SN0_ERROR_LOG(cnode)->el_spool_last_addr[0] =
+		    	REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_A);
+		}
+	    
+		if (REMOTE_HUB_PI_L(nasid, sn, PI_CPU_PRESENT_B)) {
+	    	SN0_ERROR_LOG(cnode)->el_spool_cur_addr[1] =
+			SN0_ERROR_LOG(cnode)->el_spool_last_addr[1] =
+		    	REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_B);
+		}
+	}
+
+
+	PI_SPOOL_SIZE_BYTES = 
+	    ERR_STACK_SIZE_BYTES(REMOTE_HUB_L(nasid, PI_ERR_STACK_SIZE));
+
+#ifdef BRINGUP
+/* BRINGUP: The following code looks like a check to make sure
+the prom set up the error spool correctly for 2 processors.  I
+don't think it is needed.  */
+	for(sn=0; sn<NUM_SUBNODES; sn++) {
+		if (REMOTE_HUB_PI_L(nasid, sn, PI_CPU_PRESENT_B)) {
+			__psunsigned_t addr_a = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_A);
+			__psunsigned_t addr_b = REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_B);
+			if ((addr_a & ~0xff) == (addr_b & ~0xff)) {
+			    REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STACK_ADDR_B, 	
+					addr_b + PI_SPOOL_SIZE_BYTES);
+	
+			    SN0_ERROR_LOG(cnode)->el_spool_cur_addr[1] =
+				SN0_ERROR_LOG(cnode)->el_spool_last_addr[1] =
+				    REMOTE_HUB_PI_L(nasid, sn, PI_ERR_STACK_ADDR_B);
+	
+		    }
+		}
+	}
+#endif /* BRINGUP */
+
+	/* programming our own hub. Enable error_int_pend intr.
+	 * If both present, CPU A takes CPU b's error interrupts and any
+	 * generic ones. CPU B takes CPU A error ints.
+	 */
+	if (cause_intr_connect (SRB_ERR_IDX,
+				(intr_func_t)(hubpi_eint_handler),
+				SR_ALL_MASK|SR_IE)) {
+	    cmn_err(ERR_WARN, 
+		    "hub_error_init: cause_intr_connect failed on %d", cnode);
+	}
+    }
+    else {
+	/* programming remote hub. The only valid reason that this
+	 * is called will be on headless hubs. No interrupts 
+	 */
+	for(sn=0; sn<NUM_SUBNODES; sn++) {
+		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_A, 0); /* not necessary */
+		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_MASK_B, 0); /* not necessary */
+	}
+    }
+#endif /* ajm */
+    /*
+     * Now setup the hub ii and ni error interrupt handler.
+     */
+
+    hubii_eint_init(cnode);
+    hubni_eint_init(cnode);
+
+#ifdef ajm
+    /*** XXX FIXME XXX resolve the following***/
+    /* INT_PEND1 bits set up for one hub only:
+     *	SHUTDOWN_INTR
+     *	MD_COR_ERR_INTR
+     *  COR_ERR_INTR_A and COR_ERR_INTR_B should be sent to the
+     *  appropriate CPU only.
+     */
+
+    if (cnode == 0) {
+	    error_consistency_check.eps_state = 0;
+	    error_consistency_check.eps_cpuid = -1;
+	    spinlock_init(&error_consistency_check.eps_lock, "error_dump_lock");
+    }
+#endif
+
+    nodepda->huberror_ticks = HUB_ERROR_PERIOD;
+    return;
+}
+
+/*
+ * Function	: hubii_eint_init
+ * Parameters	: cnode
+ * Purpose	: to initialize the hub iio error interrupt.
+ * Assumptions	: Called once per hub, by the cpu which will ultimately
+ *			handle this interrupt.
+ * Returns	: None.
+ */
+
+
+void
+hubii_eint_init(cnodeid_t cnode)
+{
+    int			bit, rv;
+    ii_iidsr_u_t    	hubio_eint;
+    hubinfo_t		hinfo; 
+    cpuid_t		intr_cpu;
+    devfs_handle_t 	hub_v;
+    ii_ilcsr_u_t	ilcsr;
+
+    hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode);
+    ASSERT_ALWAYS(hub_v);
+    hubinfo_get(hub_v, &hinfo);
+
+    ASSERT(hinfo);
+    ASSERT(hinfo->h_cnodeid == cnode);
+
+    ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
+
+    if ((ilcsr.ii_ilcsr_fld_s.i_llp_stat & 0x2) == 0) {
+	/* 
+	 * HUB II link is not up. 
+	 * Just disable LLP, and don't connect any interrupts.
+	 */
+	ilcsr.ii_ilcsr_fld_s.i_llp_en = 0;
+	REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval);
+	return;
+    }
+    /* Select a possible interrupt target where there is a free interrupt
+     * bit and also reserve the interrupt bit for this IO error interrupt
+     */
+    intr_cpu = intr_heuristic(hub_v,0,INTRCONNECT_ANYBIT,II_ERRORINT,hub_v,
+			      "HUB IO error interrupt",&bit);
+    if (intr_cpu == CPU_NONE) {
+	printk("hubii_eint_init: intr_reserve_level failed, cnode %d", cnode);
+	return;
+    }
+	
+    rv = intr_connect_level(intr_cpu, bit, 0,(intr_func_t)(NULL),
+			    (void *)(long)hub_v, NULL);
+    synergy_intr_connect(bit, intr_cpu);
+    request_irq(bit_pos_to_irq(bit) + (intr_cpu << 8), hubii_eint_handler, 0, NULL, (void *)hub_v);
+    ASSERT_ALWAYS(rv >= 0);
+    hubio_eint.ii_iidsr_regval = 0;
+    hubio_eint.ii_iidsr_fld_s.i_enable = 1;
+    hubio_eint.ii_iidsr_fld_s.i_level = bit;/* Take the least significant bits*/
+    hubio_eint.ii_iidsr_fld_s.i_node = COMPACT_TO_NASID_NODEID(cnode);
+    hubio_eint.ii_iidsr_fld_s.i_pi_id = cpuid_to_subnode(intr_cpu);
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, hubio_eint.ii_iidsr_regval);
+
+}
+
+void
+hubni_eint_init(cnodeid_t cnode)
+{
+    int intr_bit;
+    cpuid_t targ;
+
+
+    if ((targ = cnodeid_to_cpuid(cnode)) == CPU_NONE)
+	return;
+
+	/* The prom chooses which cpu gets these interrupts, but we
+	*  don't know which one it chose.  We will register all of the 
+	*  cpus to be sure.  This only costs us an irqaction per cpu.
+	*/
+    for (; targ < CPUS_PER_NODE; targ++) {
+	if (!cpu_enabled(targ) ) continue;
+	/* connect the INTEND1 bits. */
+	for (intr_bit = XB_ERROR; intr_bit <= MSC_PANIC_INTR; intr_bit++) {
+		intr_connect_level(targ, intr_bit, II_ERRORINT, NULL, NULL, NULL);
+	}
+	request_irq(SGI_HUB_ERROR_IRQ + (targ << 8), snia_error_intr_handler, 0, NULL, NULL);
+	/* synergy masks are initialized in the prom to enable all interrupts. */
+	/* We'll just leave them that way, here, for these interrupts. */
+    }
+}
+
+
+/*ARGSUSED*/
+void
+hubii_eint_handler (int irq, void *arg, struct pt_regs *ep)
+{
+    devfs_handle_t	hub_v;
+    hubinfo_t		hinfo; 
+    ii_wstat_u_t	wstat;
+    hubreg_t		idsr;
+
+	panic("Hubii interrupt\n");
+#ifdef ajm
+    /*
+     * If the NI has a problem, everyone has a problem.  We shouldn't
+     * even attempt to handle other errors when an NI error is present.
+     */
+    if (check_ni_errors()) {
+	hubni_error_handler("II interrupt", 1);
+	/* NOTREACHED */
+    }
+
+    /* two levels of casting avoids compiler warning.!! */
+    hub_v = (devfs_handle_t)(long)(arg); 
+    ASSERT(hub_v);
+
+    hubinfo_get(hub_v, &hinfo);
+    
+    /* 
+     * Identify the reason for error. 
+     */
+    wstat.ii_wstat_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_WSTAT);
+
+    if (wstat.ii_wstat_fld_s.w_crazy) {
+	char	*reason;
+	/*
+	 * We can do a couple of things here. 
+	 * Look at the fields TX_MX_RTY/XT_TAIL_TO/XT_CRD_TO to check
+	 * which of these caused the CRAZY bit to be set. 
+	 * You may be able to check if the Link is up really.
+	 */
+	if (wstat.ii_wstat_fld_s.w_tx_mx_rty)
+		reason = "Micro Packet Retry Timeout";
+	else if (wstat.ii_wstat_fld_s.w_xt_tail_to)
+		reason = "Crosstalk Tail Timeout";
+	else if (wstat.ii_wstat_fld_s.w_xt_crd_to)
+		reason = "Crosstalk Credit Timeout";
+	else {
+		hubreg_t	hubii_imem;
+		/*
+		 * Check if widget 0 has been marked as shutdown, or
+		 * if BTE 0/1 has been marked.
+		 */
+		hubii_imem = REMOTE_HUB_L(hinfo->h_nasid, IIO_IMEM);
+		if (hubii_imem & IIO_IMEM_W0ESD)
+			reason = "Hub Widget 0 has been Shutdown";
+		else if (hubii_imem & IIO_IMEM_B0ESD)
+			reason = "BTE 0 has been shutdown";
+		else if (hubii_imem & IIO_IMEM_B1ESD)
+			reason = "BTE 1 has been shutdown";
+		else	reason = "Unknown";
+	
+	}
+	/*
+	 * Note: we may never be able to print this, if the II talking
+	 * to Xbow which hosts the console is dead. 
+	 */
+	printk("Hub %d to Xtalk Link failed (II_ECRAZY) Reason: %s", 
+		hinfo->h_cnodeid, reason);
+    }
+
+    /* 
+     * It's a toss as to which one among PRB/CRB to check first. 
+     * Current decision is based on the severity of the errors. 
+     * IO CRB errors tend to be more severe than PRB errors.
+     *
+     * It is possible for BTE errors to have been handled already, so we
+     * may not see any errors handled here. 
+     */
+    (void)hubiio_crb_error_handler(hub_v, hinfo);
+    (void)hubiio_prb_error_handler(hub_v, hinfo);
+    /*
+     * If we reach here, it indicates crb/prb handlers successfully
+     * handled the error. So, re-enable II to send more interrupt
+     * and return.
+     */
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, 0xffffff);
+    idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR) & ~IIO_IIDSR_SENT_MASK;
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, idsr);
+#endif /* ajm */
+}
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/hubspc.c linux/arch/ia64/sn/io/hubspc.c
--- v2.4.3/linux/arch/ia64/sn/io/hubspc.c	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/io/hubspc.c	Thu Apr  5 12:51:47 2001
@@ -61,7 +61,7 @@
 }cpuprom_info_t;
 
 static cpuprom_info_t	*cpuprom_head;
-lock_t	cpuprom_spinlock;
+spinlock_t	cpuprom_spinlock;
 #define	PROM_LOCK()	mutex_spinlock(&cpuprom_spinlock)
 #define	PROM_UNLOCK(s)	mutex_spinunlock(&cpuprom_spinlock, (s))
 
@@ -72,7 +72,7 @@
 prominfo_add(devfs_handle_t hub, devfs_handle_t prom)
 {
 	cpuprom_info_t	*info;
-	int	s;
+	unsigned long	s;
 
 	info = kmalloc(sizeof(cpuprom_info_t), GFP_KERNEL);
 	ASSERT(info);
@@ -89,7 +89,7 @@
 void
 prominfo_del(devfs_handle_t prom)
 {
-	int	s;
+	unsigned long	s;
 	cpuprom_info_t	*info;
 	cpuprom_info_t	**prev;
 
@@ -111,7 +111,7 @@
 devfs_handle_t
 prominfo_nodeget(devfs_handle_t prom)
 {
-	int	s;
+	unsigned long	s;
 	cpuprom_info_t	*info;
 
 	s = PROM_LOCK();
@@ -297,7 +297,7 @@
 	printf("hubspc_init: Completed\n");
 #endif	/* HUBSPC_DEBUG */
 	/* Initialize spinlocks */
-	spinlock_init(&cpuprom_spinlock, "promlist");
+	mutex_spinlock_init(&cpuprom_spinlock);
 }
 
 /* ARGSUSED */
@@ -312,12 +312,6 @@
                 break;
 
         case HUBSPC_PROM:
-		/* Check if the user has proper access rights to 
-		 * read/write the prom space.
-		 */
-                if (!cap_able(CAP_DEVICE_MGT)) {
-                        errcode = EPERM;
-                }                
                 break;
 
         default:
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/invent.c linux/arch/ia64/sn/io/invent.c
--- v2.4.3/linux/arch/ia64/sn/io/invent.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/invent.c	Thu Apr  5 12:51:47 2001
@@ -61,6 +61,9 @@
  * 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)
@@ -74,11 +77,15 @@
 		 * 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)
+		if (rv == LABELCL_SUCCESS) {
+			place->invplace_vhdl = device;
+		}
+		else {
+			place->invplace_vhdl = GRAPH_VERTEX_NONE;
 			return(NULL);
-		place->invplace_vhdl = device;
-		place->invplace_inv = NULL; /* Start from beginning invent on this device */
+		}
 	}
 
 	return(pinv);
@@ -91,6 +98,23 @@
 	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.
  *
@@ -106,11 +130,13 @@
 
 	ie = 0;
 	rc = 0;
-	while ( (ie = (inventory_t *)get_next_inventory(&iplace)) ) {
+	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;
 }
 
@@ -127,6 +153,7 @@
 {
 	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;
@@ -146,6 +173,7 @@
 			continue;
 		break;
 	}
+	end_scan_inventory(&iplace);
 
 	return(pinv);
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/io.c linux/arch/ia64/sn/io/io.c
--- v2.4.3/linux/arch/ia64/sn/io/io.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/io.c	Thu Apr  5 12:51:47 2001
@@ -13,7 +13,6 @@
 #include <linux/slab.h>
 #include <asm/sn/types.h>
 #include <asm/sn/sgi.h>
-#include <asm/sn/cmn_err.h>
 #include <asm/sn/iobus.h>
 #include <asm/sn/iograph.h>
 #include <asm/param.h>
@@ -28,16 +27,12 @@
 #include <asm/sn/intr.h>
 #include <asm/sn/xtalk/xtalkaddrs.h>
 #include <asm/sn/klconfig.h>
+#include <asm/sn/xtalk/xwidget.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_cpuid.h>
 
 extern xtalk_provider_t hub_provider;
 
-#ifndef CONFIG_IA64_SGI_IO
-/* Global variables */
-extern pdaindr_t       pdaindr[MAXCPUS];
-#endif
-
 /*
  * Perform any initializations needed to support hub-based I/O.
  * Called once during startup.
@@ -45,7 +40,7 @@
 void
 hubio_init(void)
 {
-#if 0
+#ifdef	LATER
 	/* This isn't needed unless we port the entire sio driver ... */
         extern void early_brl1_port_init( void );
 	early_brl1_port_init();
@@ -101,17 +96,14 @@
 		hub_piomap->hpio_flags = HUB_PIOMAP_IS_BIGWINDOW;
 		IIO_ITTE_DISABLE(nasid, bigwin);
 	}
-#ifdef	BRINGUP
 	hub_set_piomode(nasid, HUB_PIO_CONVEYOR);
-#else
-	/* Set all the xwidgets in fire-and-forget mode
-	 * by default
-	 */
-	hub_set_piomode(nasid, HUB_PIO_FIRE_N_FORGET);
-#endif	/* BRINGUP */
 
-	sv_init(&hubinfo->h_bwwait, SV_FIFO, "bigwin");
-	spinlock_init(&hubinfo->h_bwlock, "bigwin");
+	mutex_spinlock_init(&hubinfo->h_bwlock);
+/*
+ * If this lock can be acquired from interrupts or bh's, add SV_INTS or SV_BHS,
+ * respectively, to the flags here.
+ */
+	sv_init(&hubinfo->h_bwwait, &hubinfo->h_bwlock, SV_ORDER_FIFO | SV_MON_SPIN); 
 }
 
 /* 
@@ -143,7 +135,7 @@
 	int bigwin, free_bw_index;
 	nasid_t nasid;
 	volatile hubreg_t junk;
-	int s;
+	unsigned long s;
 
 	/* sanity check */
 	if (byte_count_max > byte_count)
@@ -222,7 +214,7 @@
 				goto done;
 			}
 
-			sv_wait(&hubinfo->h_bwwait, PZERO, &hubinfo->h_bwlock, s);
+			sv_wait(&hubinfo->h_bwwait, 0, 0);
 			goto tryagain;
 		}
 	}
@@ -282,7 +274,7 @@
 	devfs_handle_t hubv;
 	hubinfo_t hubinfo;
 	nasid_t nasid;
-	int s;
+	unsigned long s;
 
 	/* 
 	 * Small windows are permanently mapped to corresponding widgets,
@@ -463,9 +455,9 @@
 	    if (!(dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
 		vhdl = dmamap->hdma_xtalk_info.xd_dev;
 #if defined(SUPPORT_PRINTING_V_FORMAT)
-		cmn_err(CE_WARN, "%v: hub_dmamap_addr re-uses dmamap.\n",vhdl);
+		PRINT_WARNING("%v: hub_dmamap_addr re-uses dmamap.\n",vhdl);
 #else
-		cmn_err(CE_WARN, "0x%p: hub_dmamap_addr re-uses dmamap.\n", &vhdl);
+		PRINT_WARNING("0x%x: hub_dmamap_addr re-uses dmamap.\n", vhdl);
 #endif
 	    }
 	} else {
@@ -496,9 +488,9 @@
 	    if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
 		vhdl = hub_dmamap->hdma_xtalk_info.xd_dev;
 #if defined(SUPPORT_PRINTING_V_FORMAT)
-		cmn_err(CE_WARN,"%v: hub_dmamap_list re-uses dmamap\n",vhdl);
+		PRINT_WARNING("%v: hub_dmamap_list re-uses dmamap\n",vhdl);
 #else
-		cmn_err(CE_WARN,"0x%p: hub_dmamap_list re-uses dmamap\n", &vhdl);
+		PRINT_WARNING("0x%x: hub_dmamap_list re-uses dmamap\n", vhdl);
 #endif
 	    }
 	} else {
@@ -525,9 +517,9 @@
 	    if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
 		vhdl = hub_dmamap->hdma_xtalk_info.xd_dev;
 #if defined(SUPPORT_PRINTING_V_FORMAT)
-		cmn_err(CE_WARN, "%v: hub_dmamap_done already done with dmamap\n",vhdl);
+		PRINT_WARNING("%v: hub_dmamap_done already done with dmamap\n",vhdl);
 #else
-		cmn_err(CE_WARN, "0x%p: hub_dmamap_done already done with dmamap\n", &vhdl);
+		PRINT_WARNING("0x%x: hub_dmamap_done already done with dmamap\n", vhdl);
 #endif
 	    }
 	}
@@ -629,16 +621,17 @@
  * 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 */
+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;			/* cpu to receive interrupt */
+	cpuid_t cpu = (cpuid_t)0;			/* cpu to receive interrupt */
         int cpupicked = 0;
 	int bit;			/* interrupt vector */
 	/*REFERENCED*/
-	int intr_resflags;
+	int intr_resflags = 0;
 	hub_intr_t intr_hdl;
 	cnodeid_t nodeid;		/* node to receive interrupt */
 	/*REFERENCED*/
@@ -665,7 +658,7 @@
 		intr_swlevel = device_desc_intr_swlevel_get(dev_desc);
 		if (dev_desc->flags & D_INTR_ISERR) {
 			intr_resflags = II_ERRORINT;
-		} else if (!(dev_desc->flags & D_INTR_NOTHREAD)) {
+		} else if (!uncond_nothread && !(dev_desc->flags & D_INTR_NOTHREAD)) {
 			intr_resflags = II_THREADED;
 		} else {
 			/* Neither an error nor a thread. */
@@ -673,7 +666,8 @@
 		}
 	} else {
 		intr_swlevel = default_intr_pri;
-		intr_resflags = II_THREADED;
+		if (!uncond_nothread)
+			intr_resflags = II_THREADED;
 	}
 
 	/* XXX - Need to determine if the interrupt should be threaded. */
@@ -692,13 +686,11 @@
 	/* At this point we SHOULD have a valid cpu */
 	if (cpu == CPU_NONE) {
 #if defined(SUPPORT_PRINTING_V_FORMAT)
-		cmn_err(CE_WARN, 
-			"%v hub_intr_alloc could not allocate interrupt\n",
+		PRINT_WARNING("%v hub_intr_alloc could not allocate interrupt\n",
 			owner_dev);
 #else
-		cmn_err(CE_WARN, 
-			"0x%p hub_intr_alloc could not allocate interrupt\n",
-			&owner_dev);
+		PRINT_WARNING("0x%x hub_intr_alloc could not allocate interrupt\n",
+			owner_dev);
 #endif
 		return(0);
 
@@ -714,15 +706,13 @@
 					 owner_dev, intr_name);
 		if (bit < 0) {
 #if defined(SUPPORT_PRINTING_V_FORMAT)
-			cmn_err(CE_WARN,
-				"Could not reserve an interrupt bit for cpu "
+			PRINT_WARNING("Could not reserve an interrupt bit for cpu "
 				" %d and dev %v\n",
 				cpu,owner_dev);
 #else
-			cmn_err(CE_WARN,
-				"Could not reserve an interrupt bit for cpu "
+			PRINT_WARNING("Could not reserve an interrupt bit for cpu "
 				" %d and dev 0x%x\n",
-				cpu, &owner_dev);
+				cpu, owner_dev);
 #endif
 				
 			return(0);
@@ -751,8 +741,6 @@
 	xtalk_info->xi_dev = dev;
 	xtalk_info->xi_vector = bit;
 	xtalk_info->xi_addr = xtalk_addr;
-	xtalk_info->xi_flags =  (intr_resflags == II_THREADED) ?
-				0 : XTALK_INTR_NOTHREAD;
 
 	/*
 	 * Regardless of which CPU we ultimately interrupt, a given crosstalk
@@ -779,6 +767,31 @@
 	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.
@@ -1001,7 +1014,7 @@
 {
 	iprb_t prb;
 	int prb_offset;
-#ifdef IRIX
+#ifdef LATER
 	extern int force_fire_and_forget;
 	extern volatile int ignore_conveyor_override;
 
@@ -1063,7 +1076,7 @@
 	int direct_connect;
 	hubii_wcr_t ii_wcr;
 	int prbnum;
-	int s, cons_lock = 0;
+	int cons_lock = 0;
 
 	ASSERT(NASID_TO_COMPACT_NODEID(nasid) != INVALID_CNODEID);
 	if (nasid == get_console_nasid()) {
@@ -1098,15 +1111,6 @@
 		hub_setup_prb(nasid, prbnum, 3, conveyor);
 	}
 
-#ifdef IRIX
-	/*
-	 * In direct connect mode, disable access to all widgets but 0.
-	 * Later, the prom will do this for us.
-	 */
-	if (direct_connect)
-		ii_iowa = 1;
-#endif
-
 	REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, ii_iowa);
 
 	if (cons_lock)
@@ -1151,7 +1155,8 @@
 	devfs_handle_t		hub_vhdl    = xwidget_info_master_get(widget_info);
 	hubinfo_t		hub_info = 0;
 	nasid_t			nasid;
-	int			s,rv;
+	unsigned long		s;
+	int			rv;
 
 	/* Use the nasid from the hub info hanging off the hub vertex
 	 * and widget number from the widget vertex
@@ -1178,7 +1183,7 @@
 	devfs_handle_t		hub_vhdl    = xwidget_info_master_get(widget_info);
 	hubinfo_t		hub_info = 0;
 	nasid_t			nasid;
-	int			s;
+	unsigned long			s;
 
 	/* Use the nasid from the hub info hanging off the hub vertex
 	 * and widget number from the widget vertex
@@ -1201,7 +1206,7 @@
 	devfs_handle_t		hub_vhdl    = xwidget_info_master_get(widget_info);
 	hubinfo_t		hub_info = 0;
 	nasid_t			nasid;
-	int			s;
+	unsigned long		s;
 
 	/* Use the nasid from the hub info hanging off the hub vertex
 	 * and widget number from the widget vertex
@@ -1253,25 +1258,23 @@
 	ii_iowa 	= REMOTE_HUB_L(nasid, IIO_IOWA);
 
 #if defined(SUPPORT_PRINTING_V_FORMAT)
-	cmn_err(CE_CONT, "Inquiry Info for %v\n", xconn);
+	printk("Inquiry Info for %v\n", xconn);
 #else
-	cmn_err(CE_CONT, "Inquiry Info for 0x%p\n", &xconn);
+	printk("Inquiry Info for 0x%x\n", xconn);
 #endif
 
-	cmn_err(CE_CONT,"\tDevices shutdown [ ");
+	printk("\tDevices shutdown [ ");
 
 	for (d = 0 ; d <= 7 ; d++)
 		if (!(ii_iidem & (IIO_IIDEM_WIDGETDEV_MASK(widget,d))))
-			cmn_err(CE_CONT, " %d", d);
+			printk(" %d", d);
 
-	cmn_err(CE_CONT,"]\n");
+	printk("]\n");
 
-	cmn_err(CE_CONT,
-		"\tInbound access ? %s\n",
+	printk("\tInbound access ? %s\n",
 		ii_iiwa & IIO_IIWA_WIDGET(widget) ? "yes" : "no");
 
-	cmn_err(CE_CONT,
-		"\tOutbound access ? %s\n",
+	printk("\tOutbound access ? %s\n",
 		ii_iowa & IIO_IOWA_WIDGET(widget) ? "yes" : "no");
 
 }
@@ -1300,6 +1303,7 @@
 	(xtalk_dmalist_drain_f *)	hub_dmalist_drain,
 
 	(xtalk_intr_alloc_f *)		hub_intr_alloc,
+	(xtalk_intr_alloc_f *)		hub_intr_alloc_nothd,
 	(xtalk_intr_free_f *)		hub_intr_free,
 	(xtalk_intr_connect_f *)	hub_intr_connect,
 	(xtalk_intr_disconnect_f *)	hub_intr_disconnect,
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/ip37.c linux/arch/ia64/sn/io/ip37.c
--- v2.4.3/linux/arch/ia64/sn/io/ip37.c	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/io/ip37.c	Thu Apr  5 12:51:47 2001
@@ -30,10 +30,6 @@
 		
 	ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid,IIO_WCR);
 
-	printk("hub_widget_id: Found Hub Widget ID 0x%x from Register 0x%p\n", ii_wcr.wcr_fields_s.wcr_widget_id, REMOTE_HUB_ADDR(nasid, IIO_WCR));
-
-	printk("hub_widget_id: Found Hub Widget 0x%lx wcr_reg_value 0x%lx\n", REMOTE_HUB_L(nasid,IIO_WCR), ii_wcr.wcr_reg_value);
-
 	return ii_wcr.wcr_fields_s.wcr_widget_id;
 }
 
@@ -64,8 +60,6 @@
 get_hub_chiprev(nasid_t nasid)
 {
 
-	printk("get_hub_chiprev: Hub Chip Rev 0x%lx\n",
-		(REMOTE_HUB_L(nasid, LB_REV_ID) & LRI_REV_MASK) >> LRI_REV_SHFT);
 	return ((REMOTE_HUB_L(nasid, LB_REV_ID) & LRI_REV_MASK)
 		                                         >> LRI_REV_SHFT);
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/klconflib.c linux/arch/ia64/sn/io/klconflib.c
--- v2.4.3/linux/arch/ia64/sn/io/klconflib.c	Fri Feb 16 16:02:34 2001
+++ linux/arch/ia64/sn/io/klconflib.c	Thu Apr  5 12:51:47 2001
@@ -82,7 +82,7 @@
 		}
 		index = j;
 		if (index == KLCF_NUM_COMPS(brd)) {
-			printf("find_component: Bad pointer: 0x%p\n", kli);
+			DBG("find_component: Bad pointer: 0x%p\n", kli);
 			return (klinfo_t *)NULL;
 		}
 		index++;	/* next component */
@@ -152,11 +152,6 @@
 	return (lboard_t *)NULL;
 }
 
-#ifndef CONFIG_IA64_SGI_IO
-#define tolower(c)	(isupper(c) ? (c) - 'A' + 'a' : (c))
-#define toupper(c)	(islower(c) ? (c) - 'a' + 'A' : (c))
-#endif
-
 
 /*
  * Convert a NIC name to a name for use in the hardware graph.
@@ -205,10 +200,6 @@
             !strncmp(new_name, "mio", 3) || 
 	    !strncmp(new_name, "media_io", 8))
 		strcpy(new_name, "baseio");
-#if !defined(CONFIG_SGI_IP35) && !defined(CONFIG_IA64_SGI_SN1) && !defined(CONFIG_IA64_GENERIC)
-	else if (!strncmp(new_name, "ip29", 4))
-		strcpy(new_name,SN00_MOTHERBOARD);
-#endif
 	else if (!strncmp(new_name, "divo", 4))
 		strcpy(new_name, "divo") ;
 
@@ -284,11 +275,11 @@
 
 	/*
  	 * PV # 540860
-	 * If the name is not 'baseio' or SN00 MOTHERBOARD
+	 * 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 and SN00 MOTHERBOARD
+	 * divo. We could do this for baseio 
  	 * but it has some special case names that we would not
  	 * like to disturb at this point.
 	 */
@@ -355,11 +346,7 @@
 	/*
 	 * look for boards that might contain an xbow or xbridge
 	 */
-#if SN0
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_MIDPLANE8);
-#else
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_PBRICK_XBOW);
-#endif
+	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))
@@ -369,7 +356,7 @@
 	if (!XBOW_PORT_TYPE_IO(xbow_p, link) || !XBOW_PORT_IS_ENABLED(xbow_p, link))
 	    return 0;
 
-	printf("xbow_port_io_enabled:  brd 0x%p xbow_p 0x%p \n", brd, xbow_p);
+	DBG("xbow_port_io_enabled:  brd 0x%p xbow_p 0x%p \n", brd, xbow_p);
 
 	return 1;
 }
@@ -395,6 +382,9 @@
 			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;
@@ -420,22 +410,17 @@
 			
 	modnum = brd->brd_module;
 
-#if defined(SN0)
-	slot = brd->brd_slot;
-	get_slotname(slot, slot_name);
-
-	ASSERT(modnum >= 0);
-
-	sprintf(path, "%H/" EDGE_LBL_SLOT "/%s/%s", 
-		modnum, slot_name, board_name);
-#else
 	ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE);
-#ifdef BRINGUP /* fix IP35 hwgraph */
-	sprintf(path, EDGE_LBL_MODULE "/%x/%s", modnum, board_name);
+#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
-#endif
 }
 
 /*
@@ -455,172 +440,8 @@
 }
 
 
-#ifndef CONFIG_IA64_SGI_IO
-#if 1
-/*
- *  find_gfxpipe(#)
- *
- *  XXXmacko
- *  This is only used by graphics drivers, and should be moved
- *  over to gfx/kern/graphics/SN0 as soon as it's convenient.
- */
-static klgfx_t *graphics_pipe_list = NULL;
-static devfs_handle_t hwgraph_all_gfxids = GRAPH_VERTEX_NONE;
-
-void
-setup_gfxpipe_link(devfs_handle_t vhdl,int pipenum)
-{
-	char idbuf[8];
-	extern graph_hdl_t hwgraph;
-
-	graph_info_add_LBL(hwgraph, vhdl, INFO_LBL_GFXID, INFO_DESC_EXPORT, 
-		(arbitrary_info_t)pipenum);
-	if (hwgraph_all_gfxids == GRAPH_VERTEX_NONE)
-		hwgraph_path_add(hwgraph_root, EDGE_LBL_GFX, &hwgraph_all_gfxids);
-	sprintf(idbuf, "%d", pipenum);
-	hwgraph_edge_add(hwgraph_all_gfxids, vhdl, idbuf);
-
-}
-#endif
-
-/* 
- * find the pipenum'th logical graphics pipe (KLCLASS_GFX)
- */
-lboard_t *
-find_gfxpipe(int pipenum)
-{
-        gda_t           *gdap;
-        cnodeid_t       cnode;
-        nasid_t         nasid;
-        lboard_t        *lb;
-	klgfx_t		*kg,**pkg;
-	int		i;
-
-        gdap = (gda_t *)GDA_ADDR(get_nasid());
-        if (gdap->g_magic != GDA_MAGIC)
-        	return NULL;
-
-	if (!graphics_pipe_list) {
-		/* for all nodes */
-        	for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) {
-                	nasid = gdap->g_nasidtable[cnode];
-                	if (nasid == INVALID_NASID)
-                        	continue;
-			lb = KL_CONFIG_INFO(nasid) ;
-			while (lb = find_lboard_class(lb, KLCLASS_GFX)) {
-				moduleid_t kgm, pkgm;
-				int	kgs, pkgs;
-
-#if defined(DEBUG) && (defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)) && defined(BRINGUP)
-				printf("find_gfxpipe(): PIPE: %s mod %M slot %d\n",lb?lb->brd_name:"!LBRD",
-					lb->brd_module,lb->brd_slot);
-#endif
-				/* insert lb into list */
-				if (!(kg = (klgfx_t*)find_first_component(lb,KLSTRUCT_GFX))) {
-					lb = KLCF_NEXT(lb);
-					continue;
-				}
-				/* set moduleslot now that we have brd_module set */
-				kg->moduleslot = (lb->brd_module << 8) | SLOTNUM_GETSLOT(lb->brd_slot);
-				/* make sure board has device flag set */
-				kg->gfx_info.flags |= KLINFO_DEVICE;
-				if (kg->cookie < KLGFX_COOKIE) {
-				    kg->gfx_next_pipe = NULL;
-				    kg->cookie = KLGFX_COOKIE;
-				}
-
-				kgm = kg->moduleslot>>8;
-				kgs = kg->moduleslot&0xff;
-				pkg = &graphics_pipe_list;
-				while (*pkg) {
-					pkgm = (*pkg)->moduleslot>>8;
-					pkgs = (*pkg)->moduleslot&0xff;
-
-					if (!(MODULE_CMP(kgm, pkgm) > 0 ||
-					      (MODULE_CMP(kgm, pkgm) == 0 &&
-					       kgs > pkgs)))
-					    break;
-
-					pkg = &(*pkg)->gfx_next_pipe;
-				}
-				kg->gfx_next_pipe = *pkg;
-				*pkg = kg;
-				lb = KLCF_NEXT(lb);
-			}
-		}
-#ifdef FIND_GFXPIPE_DEBUG
-		i = 0;
-		kg = graphics_pipe_list;
-		while (kg) {
-			lboard_t *lb;
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-			lb = find_lboard_class(KL_CONFIG_INFO(kg->gfx_info.nasid), KLCLASS_GFX);
-#else
-#error Need to figure out how to find graphics boards ...
-#endif
-#if defined(SUPPORT_PRINTING_M_FORMAT)
-			printf("find_gfxpipe(): %s pipe %d mod %M slot %d\n",lb?lb->brd_name:"!LBRD",i,
-				(kg->moduleslot>>8),(kg->moduleslot&0xff));
-#else
-			printf("find_gfxpipe(): %s pipe %d mod 0x%x slot %d\n",lb?lb->brd_name:"!LBRD",i,
-				(kg->moduleslot>>8),(kg->moduleslot&0xff));
-#endif
-			kg = kg->gfx_next_pipe;
-			i++;
-		}
-#endif
-        }
-
-	i = 0;
-	kg = graphics_pipe_list;
-	while (kg && (i < pipenum)) {
-		kg = kg->gfx_next_pipe;
-		i++;
-		}
-
-	if (!kg) return NULL;
-
-#if defined(SN0)
-	return find_lboard_modslot(KL_CONFIG_INFO(kg->gfx_info.nasid),
-				(kg->moduleslot>>8),
-				SLOTNUM_XTALK_CLASS|(kg->moduleslot&0xff));
-#elif defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-	return find_lboard_class(KL_CONFIG_INFO(kg->gfx_info.nasid), KLCLASS_GFX);
-#else
-#error Need to figure out how to find graphics boards ...
-#endif
-}
-#endif
-
-
 #define MHZ	1000000
 
-#ifndef CONFIG_IA64_SGI_IO
-uint
-cpu_cycles_adjust(uint orig_cycles)
-{
-	klcpu_t *acpu;
-	uint speed;
-
-	acpu  = nasid_slice_to_cpuinfo(get_nasid(), get_slice());
-
-	if (acpu == NULL) return orig_cycles;
-
-	/*
-	 * cpu cycles seem to be half of the real value, hack and mult by 2
-	 * for now.
-	 */
-	speed = (orig_cycles * 2) / MHZ;
-
-	/*
-	 * if the cpu thinks its running at some random speed nowhere close 
-	 * the programmed speed, do nothing.
-	 */
-	if ((speed < (acpu->cpu_speed - 2)) || (speed > (acpu->cpu_speed + 2)))
-	    return orig_cycles;
-	return (acpu->cpu_speed * MHZ/2);
-}
-#endif /* CONFIG_IA64_SGI_IO */
 
 /* Get the canonical hardware graph name for the given pci component
  * on the given io board.
@@ -633,9 +454,6 @@
 	moduleid_t 	modnum;
 	slotid_t 	slot;
 	char 		board_name[20];
-#ifdef SN0
-	char 		slot_name[SLOTNUM_MAXLENGTH];
-#endif
 
 	ASSERT(brd);
 
@@ -646,13 +464,7 @@
 	 * into a string 
 	 */
 	slot = brd->brd_slot;
-#ifdef SN0
-	get_slotname(slot, slot_name);
-
-	ASSERT(modnum >= 0);
-#else
 	ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE);
-#endif
 
 	/* Get the io board name  */
 	if (!brd || (brd->brd_sversion < 2)) {
@@ -662,18 +474,10 @@
 	}
 
 	/* Give out the canonical  name of the pci device*/
-#ifdef SN0
-	sprintf(name, 
-		"/hw/"EDGE_LBL_MODULE "/%M/"EDGE_LBL_SLOT"/%s/%s/"
-		EDGE_LBL_PCI"/%d", 
-		modnum, slot_name, board_name,KLCF_BRIDGE_W_ID(component));
-#elif defined (CONFIG_SGI_IP35)  || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 	sprintf(name, 
 		"/dev/hw/"EDGE_LBL_MODULE "/%x/"EDGE_LBL_SLOT"/%s/"
 		EDGE_LBL_PCI"/%d", 
 		modnum, board_name,KLCF_BRIDGE_W_ID(component));
-#endif
-	
 }
 
 /*
@@ -894,90 +698,6 @@
 }
 
 #include "asm/sn/sn_private.h"
-#ifndef CONFIG_IA64_SGI_IO
-/*
- * Given a physical address get the name of memory dimm bank
- * in a hwgraph name format.
- */
-void
-membank_pathname_get(paddr_t paddr,char *name)
-{
-	cnodeid_t	cnode;
-	char		slotname[SLOTNUM_MAXLENGTH];
-
-	cnode = paddr_cnode(paddr);
-	/* Make sure that we have a valid name buffer */
-	if (!name)
-		return;
-
-	name[0] = 0;
-	/* Make sure that the cnode is valid */
-	if ((cnode == CNODEID_NONE) || (cnode > numnodes))
-		return;
-	/* Given a slotid(class:type) get the slotname */
-#if defined (SN0)
-	get_slotname(NODE_SLOTID(cnode),slotname);
-	sprintf(name,
-		"/hw/"EDGE_LBL_MODULE"/%M/"EDGE_LBL_SLOT"/%s/"EDGE_LBL_NODE
-		"/"EDGE_LBL_MEMORY"/dimm_bank/%d",
-		NODE_MODULEID(cnode),slotname,paddr_dimm(paddr));
-#elif defined (CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-	sprintf(name,
-		"/dev/hw/"EDGE_LBL_MODULE"/%M/"EDGE_LBL_NODE
-		"/"EDGE_LBL_MEMORY"/dimm_bank/%d",
-		NODE_MODULEID(cnode),paddr_dimm(paddr));
-#endif
-}
-
-
-
-int
-membank_check_mixed_hidensity(nasid_t nasid)
-{
-	lboard_t *brd;
-	klmembnk_t *mem;
-	int min_size = 1024, max_size = 0;
-	int bank, mem_size;
-
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
-	ASSERT(brd);
-
-	mem = (klmembnk_t *)find_first_component(brd, KLSTRUCT_MEMBNK);
-	ASSERT(mem);
-
-
-	for (mem_size = 0, bank = 0; bank < MD_MEM_BANKS; bank++) {
-		mem_size = KLCONFIG_MEMBNK_SIZE(mem, bank);
-		if (mem_size < min_size)
-		    min_size = mem_size;
-		if (mem_size > max_size)
-		    max_size = mem_size;
-	}
-	
-	if ((max_size == 512) && (max_size != min_size))
-	    return 1;
-
-	return 0;
-}
-
-
-int
-mem_mixed_hidensity_banks(void)
-{
-	cnodeid_t cnode;
-	nasid_t nasid;
-
-	for (cnode = 0; cnode < maxnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-		if (nasid == INVALID_NASID)
-		    continue;
-		if (membank_check_mixed_hidensity(nasid))
-		    return 1;
-	}
-	return 0;
-
-}
-#endif /* CONFIG_IA64_SGI_IO */
 
 xwidgetnum_t
 nodevertex_widgetnum_get(devfs_handle_t node_vtx)
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/klgraph.c linux/arch/ia64/sn/io/klgraph.c
--- v2.4.3/linux/arch/ia64/sn/io/klgraph.c	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/io/klgraph.c	Thu Apr  5 12:51:47 2001
@@ -23,18 +23,15 @@
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
 
-#include <asm/sn/cmn_err.h>
 #include <asm/sn/agent.h>
-#ifdef CONFIG_IA64_SGI_IO
 #include <asm/sn/kldir.h>
-#endif
 #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
+/* #define KLGRAPH_DEBUG 1 */
 #ifdef KLGRAPH_DEBUG
 #define GRPRINTF(x)	printk x
 #define CE_GRPANIC	CE_PANIC
@@ -48,25 +45,6 @@
 extern char arg_maxnodes[];
 extern int maxnodes;
 
-#ifndef BRINGUP
-/*
- * Gets reason for diagval using table lookup.
- */
-static char*
-get_diag_string(uint diagcode)
-{
-  int num_entries;
-  int i;
-  num_entries = sizeof(diagval_map) / sizeof(diagval_t);
-  for (i = 0; i < num_entries; i++){
-    if ((unchar)diagval_map[i].dv_code == (unchar)diagcode)
-      return diagval_map[i].dv_msg;
-  }
-  return "Unknown";
-}
-
-#endif /* ndef BRINGUP */
-
 
 /*
  * Support for verbose inventory via hardware graph. 
@@ -105,7 +83,7 @@
 		klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t));
 	baseio_inventory->im_type = INV_IO6PROM;
 	/* Read the io6prom revision from the nvram */
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef LATER
 	nvram_prom_version_get(&version,&revision);
 #endif
 	/* Store the revision info  in the inventory */
@@ -169,7 +147,7 @@
 	(void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv);
 	rc = device_master_set(myhubv, node_vertex);
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	/*
 	 * Activate when we support hub stats.
 	 */
@@ -178,8 +156,7 @@
 #endif
 
 	if (rc != GRAPH_SUCCESS) {
-		cmn_err(CE_WARN,
-			"klhwg_add_hub: Can't add hub info label 0x%p, code %d",
+		PRINT_WARNING("klhwg_add_hub: Can't add hub info label 0x%p, code %d",
 			myhubv, rc);
 	}
 
@@ -187,15 +164,12 @@
 
 #ifndef BRINGUP
 	init_hub_stats(cnode, NODEPDA(cnode));
-#endif /* ndef BRINGUP */
-
-#ifndef CONFIG_IA64_SGI_IO
 	sndrv_attach(myhubv);
 #else
 	/*
 	 * Need to call our driver to do the attach?
 	 */
-	printk("klhwg_add_hub: Need to add code to do the attach.\n");
+	FIXME("klhwg_add_hub: Need to add code to do the attach.\n");
 #endif
 }
 
@@ -350,7 +324,7 @@
 		rps_invent->ir_gen.ig_flag = INVENT_ENABLED;
 }
 
-#endif /* ndef BRINGUP */
+#endif /* BRINGUP */
 
 void
 klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid)
@@ -366,7 +340,7 @@
 
 #if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || defined(CONFIG_IA64_GENERIC)
 	if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid),
-				KLTYPE_PBRICK_XBOW)) == NULL)
+				KLTYPE_IOBRICK_XBOW)) == NULL)
 			return;
 #endif
 
@@ -380,7 +354,7 @@
 	    == NULL)
 	    return;
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	/*
 	 * We cannot support this function in devfs .. see below where 
 	 * we use hwgraph_path_add() to create this vertex with a known 
@@ -390,21 +364,19 @@
 	ASSERT(err == GRAPH_SUCCESS);
 
 	xswitch_vertex_init(xbow_v);
-#endif /* !CONFIG_IA64_SGI_IO */
+#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);
-		printk("klhwg_add_xbow: Found xbow port type hub hub_nasid %d widgetnum %d\n", hub_nasid, widgetnum);
 		if (hub_nasid == INVALID_NASID) {
-			cmn_err(CE_WARN, "hub widget %d, skipping xbow graph\n", widgetnum);
+			PRINT_WARNING("hub widget %d, skipping xbow graph\n", widgetnum);
 			continue;
 		}
 
 		hub_cnode = NASID_TO_COMPACT_NODEID(hub_nasid);
-		printk("klhwg_add_xbow: cnode %d cnode %d\n", nasid_to_compact_node[0], nasid_to_compact_node[1]);
 
 		if (is_specified(arg_maxnodes) && hub_cnode == INVALID_CNODEID) {
 			continue;
@@ -412,21 +384,18 @@
 			
 		hubv = cnodeid_to_vertex(hub_cnode);
 
-#ifdef CONFIG_IA64_SGI_IO
-		printk("klhwg_add_xbow: Hub Vertex found = %p hub_cnode %d\n", hubv, hub_cnode);
 		err = hwgraph_path_add(hubv, EDGE_LBL_XTALK, &xbow_v);
                 if (err != GRAPH_SUCCESS) {
                         if (err == GRAPH_DUP)
-                                cmn_err(CE_WARN, "klhwg_add_xbow: Check for "
+                                PRINT_WARNING("klhwg_add_xbow: Check for "
                                         "working routers and router links!");
 
-                        cmn_err(CE_GRPANIC, "klhwg_add_xbow: Failed to add "
+                        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);
                 }
 		xswitch_vertex_init(xbow_v); 
-#endif
 
 		NODEPDA(hub_cnode)->xbow_vhdl = xbow_v;
 
@@ -443,14 +412,14 @@
 		GRPRINTF(("klhwg_add_xbow: adding port nasid %d %s to vertex 0x%p\n",
 			hub_nasid, EDGE_LBL_XTALK, hubv));
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 		err = hwgraph_edge_add(hubv, xbow_v, EDGE_LBL_XTALK);
 		if (err != GRAPH_SUCCESS) {
 			if (err == GRAPH_DUP)
-				cmn_err(CE_WARN, "klhwg_add_xbow: Check for "
+				PRINT_WARNING("klhwg_add_xbow: Check for "
 					"working routers and router links!");
 
-			cmn_err(CE_GRPANIC, "klhwg_add_xbow: Failed to add "
+			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);
@@ -488,9 +457,8 @@
 			path_buffer, hwgraph_root));
 		rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
 
-		printk("klhwg_add_node: rv = %d graph success %d node_vertex 0x%p\n", rv, GRAPH_SUCCESS, node_vertex);
 		if (rv != GRAPH_SUCCESS)
-			cmn_err(CE_PANIC, "Node vertex creation failed.  "
+			PRINT_PANIC("Node vertex creation failed.  "
 					  "Path == %s",
 				path_buffer);
 
@@ -504,11 +472,8 @@
 		if(!board_disabled) {
 			mark_nodevertex_as_node(node_vertex,
 					    cnode + board_disabled * numnodes);
-			printk("klhwg_add_node: node_vertex %p, cnode %d numnodes %d\n", node_vertex, cnode, numnodes);
 
 			s = dev_to_name(node_vertex, path_buffer, sizeof(path_buffer));
-			printk("klhwg_add_node: s %s\n", s);
-
 			NODEPDA(cnode)->hwg_node_name =
 						kmalloc(strlen(s) + 1,
 						GFP_KERNEL);
@@ -581,7 +546,7 @@
 			rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
 
 			if (rv != GRAPH_SUCCESS)
-				cmn_err(CE_PANIC, "Router vertex creation "
+				PRINT_PANIC("Router vertex creation "
 						  "failed.  Path == %s",
 					path_buffer);
 
@@ -629,12 +594,11 @@
 			return;
 
 	if (rc != GRAPH_SUCCESS)
-		cmn_err(CE_WARN, "Can't find router: %s", path_buffer);
+		PRINT_WARNING("Can't find router: %s", path_buffer);
 
 	/* We don't know what to do with multiple router components */
 	if (brd->brd_numcompts != 1) {
-		cmn_err(CE_PANIC,
-			"klhwg_connect_one_router: %d cmpts on router\n",
+		PRINT_PANIC("klhwg_connect_one_router: %d cmpts on router\n",
 			brd->brd_numcompts);
 		return;
 	}
@@ -668,7 +632,7 @@
 		if (rc != GRAPH_SUCCESS) {
 			if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
 				continue;
-			cmn_err(CE_PANIC, "Can't find router: %s", dest_path);
+			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));
@@ -685,7 +649,7 @@
 		}
 
 		if (rc != GRAPH_SUCCESS && !is_specified(arg_maxnodes))
-			cmn_err(CE_GRPANIC, "Can't create edge: %s/%s to vertex 0x%p error 0x%x\n",
+			PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n",
 				path_buffer, dest_path, dest_hndl, rc);
 		
 	}
@@ -768,7 +732,7 @@
 		rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl);
 
 		if (rc != GRAPH_SUCCESS)
-			cmn_err(CE_WARN, "Can't find hub: %s", path_buffer);
+			PRINT_WARNING("Can't find hub: %s", path_buffer);
 
 		dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
 				hub->hub_port.port_nasid,
@@ -782,7 +746,7 @@
 		if (rc != GRAPH_SUCCESS) {
 			if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
 				continue;
-			cmn_err(CE_PANIC, "Can't find board: %s", dest_path);
+			PRINT_PANIC("Can't find board: %s", dest_path);
 		} else {
 		
 
@@ -792,7 +756,7 @@
 			rc = hwgraph_edge_add(hub_hndl, dest_hndl, EDGE_LBL_INTERCONNECT);
 
 			if (rc != GRAPH_SUCCESS)
-				cmn_err(CE_GRPANIC, "Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n",
+				PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n",
 				path_buffer, dest_path, dest_hndl, rc);
 
 		}
@@ -815,7 +779,7 @@
 					 */
 	char		device_name[MAXDEVNAME];
 	
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	device_admin_table_init();
 #endif
 	for(cnode = 0; cnode < numnodes; cnode++) {
@@ -853,7 +817,7 @@
 				device_component_canonical_name_get(board,
 							    component,
 							    device_name);
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 				device_admin_table_update(device_name,
 							  ADMIN_LBL_DISABLED,
 							  "yes");
@@ -877,13 +841,20 @@
 	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);
@@ -893,9 +864,15 @@
 
 		/* 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); 
@@ -905,7 +882,7 @@
 				     INFO_LBL_ELSC,
 				     (arbitrary_info_t) (__psint_t) 1);
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 		sndrv_attach(vhdl);
 #else
 		/*
@@ -923,13 +900,10 @@
 	gda_t		*gdap;
 	cnodeid_t	cnode;
 
-#ifdef SIMULATED_KLGRAPH
-	//gdap = 0xa800000000011000;
-	gdap = (gda_t *)0xe000000000011000;
-	printk("klhwg_add_all_nodes: SIMULATED_KLGRAPH FIXME: gdap= 0x%p\n", gdap);
-#else
-	gdap = GDA;
-#endif /* SIMULATED_KLGRAPH */
+	gdap = (gda_t *)0xe000000000002400;
+
+	FIXME("klhwg_add_all_nodes: FIX GDA\n");
+
 	for (cnode = 0; cnode < numnodes; cnode++) {
 		ASSERT(gdap->g_nasidtable[cnode] != INVALID_NASID);
 		klhwg_add_node(hwgraph_root, cnode, gdap);
@@ -938,12 +912,7 @@
 	for (cnode = 0; cnode < numnodes; cnode++) {
 		ASSERT(gdap->g_nasidtable[cnode] != INVALID_NASID);
 
-#ifndef CONFIG_IA64_SGI_IO
 		klhwg_add_xbow(cnode, gdap->g_nasidtable[cnode]);
-#else
-		printk("klhwg_add_all_nodes: Fix me by getting real nasid\n");
-		klhwg_add_xbow(cnode, 0);
-#endif
 	}
 
 	/*
@@ -959,7 +928,7 @@
 	 * routers in the system.
 	 */
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	router_guardians_set(hwgraph_root);
 #endif
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/klgraph_hack.c linux/arch/ia64/sn/io/klgraph_hack.c
--- v2.4.3/linux/arch/ia64/sn/io/klgraph_hack.c	Fri Feb 16 16:02:34 2001
+++ linux/arch/ia64/sn/io/klgraph_hack.c	Thu Apr  5 12:51:47 2001
@@ -35,55 +35,6 @@
 extern void clear_ii_error(void);
 #endif /* BRINGUP */
 
-void
-simulated_BW0_init(void)
-{
-
-	unsigned long *cnode0_hub;
-	unsigned long hub_widget = 0x1000000;
-	unsigned long hub_offset = 0x800000;
-	unsigned long hub_reg_base = 0;
-	extern void * vmalloc(unsigned long);
-
-	memset(&nasid_to_compact_node[0], 0, sizeof(cnodeid_t) * MAX_NASIDS);
-
-	BW0 = vmalloc(0x10000000);
-	if (BW0 == NULL) {
-		printk("Darn it .. cannot create space for Big Window 0\n");
-	}
-	printk("BW0: Start Address %p\n", BW0);
-	
-	memset(BW0+(0x10000000 - 8), 0xf, 0x8);
-
-	printk("BW0: Last WORD address %p has value 0x%lx\n", (char *)(BW0 +(0x10000000 - 8)), *(long *)(BW0 +(0x10000000 - 8)));
-
-	printk("XWIDGET 8 Address = 0x%p\n", (unsigned long *)(NODE_SWIN_BASE(0, 8)) ); 
-
-	/*
-	 * Do some HUB Register Hack ..
-	 */
-	hub_reg_base = (unsigned long)BW0 + hub_widget + hub_offset;
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_WID); *cnode0_hub = 0x1c110049;
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_WSTAT); *cnode0_hub = 0x0;
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_WCR); *cnode0_hub = 0x401b;
-	printk("IIO_WCR address = 0x%p\n", cnode0_hub);
-
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_ILAPR); *cnode0_hub = 0xffffffffffffffff;
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_ILAPO); *cnode0_hub = 0x0;
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_IOWA); *cnode0_hub = 0xff01;
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_IIWA); *cnode0_hub = 0xff01;
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_IIDEM); *cnode0_hub = 0xffffffffffffffff;
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_ILCSR); *cnode0_hub = 0x3fc03ff640a;
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_ILLR); *cnode0_hub = 0x0;
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_IIDSR); *cnode0_hub = 0x1000040;
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_IGFX0); *cnode0_hub = 0x0;
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_IGFX1); *cnode0_hub = 0x0;
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_ISCR0); *cnode0_hub = 0x23d;
-        cnode0_hub = (unsigned long *)(hub_reg_base + IIO_ISCR1); *cnode0_hub = 0x0;
-#endif	/* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
-}
-
 #define SYNERGY_WIDGET          ((char *)0xc0000e0000000000)
 #define SYNERGY_SWIZZLE         ((char *)0xc0000e0000000400)
 #define HUBREG                  ((char *)0xc0000a0001e00000)
@@ -136,10 +87,10 @@
 	klxbow_t	*klxbow_ptr;
 	klinfo_t	*klinfo_ptr;
 	klcomp_t	*klcomp_ptr;
+#if 0
 	uint64_t	*tmp;
 	volatile u32	*tmp32;
 
-#if 0
 	/* Preset some values */
 	/* Write IOERR clear to clear the CRAZY bit in the status */
 	tmp = (uint64_t *)0xc0000a0001c001f8; *tmp = (uint64_t)0xffffffff;
@@ -164,7 +115,6 @@
 	*tmp32 = 0xba98;
 	tmp32 = (volatile u32 *)0xc0000a000f000288L;
 	*tmp32 = 0xba98;
-#endif
 
 printk("Widget ID Address 0x%p Value 0x%lx\n", (uint64_t *)0xc0000a0001e00000, *( (volatile uint64_t *)0xc0000a0001e00000) );
 
@@ -181,6 +131,7 @@
 
 printk("Xbow ID Address 0x%p Value 0x%x\n", (uint64_t *)0xc000020000000004, *( (volatile uint32_t *)0xc000020000000004) );
 
+#endif
 
 	if ( test )
 		test_io_regs();
@@ -210,9 +161,8 @@
 	 */
 	linux_klcfg = (kl_config_hdr_t *)0xe000000000030000;
 	if (linux_klcfg->ch_magic == 0xbeedbabe) {
-		printk("Linux Kernel Booted from Disk\n");
+		return;
 	} else {
-		printk("Linux Kernel Booted from PROM\n");
 		linux_klcfg = kl_hdr_ptr;
 	}
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/l1.c linux/arch/ia64/sn/io/l1.c
--- v2.4.3/linux/arch/ia64/sn/io/l1.c	Tue Mar  6 19:44:35 2001
+++ linux/arch/ia64/sn/io/l1.c	Thu Apr  5 12:51:47 2001
@@ -34,6 +34,7 @@
 #include <linux/types.h>
 #include <linux/config.h>
 #include <linux/slab.h>
+#include <linux/spinlock.h>
 #include <asm/sn/sgi.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
@@ -42,7 +43,6 @@
 #include <asm/sn/labelcl.h>
 #include <asm/sn/eeprom.h>
 #include <asm/sn/ksys/i2c.h>
-#include <asm/sn/cmn_err.h>
 #include <asm/sn/router.h>
 #include <asm/sn/module.h>
 #include <asm/sn/ksys/l1.h>
@@ -51,6 +51,20 @@
 
 #include <asm/sn/sn1/uart16550.h>
 
+/*
+ * Delete this when atomic_clear is part of atomic.h.
+ */
+static __inline__ int
+atomic_clear (int i, atomic_t *v)
+{
+	__s32 old, new;
+
+	do {
+		old = atomic_read(v);
+		new = old & ~i;
+	} while (ia64_cmpxchg("acq", v, old, new, sizeof(atomic_t)) != old);
+	return new;
+}
 
 #if defined(EEPROM_DEBUG)
 #define db_printf(x) printk x
@@ -73,6 +87,7 @@
 /* location of uart receive/xmit data register */
 #define L1_UART_BASE(n)	((ulong)REMOTE_HSPEC_ADDR((n), HSPEC_UART_0))
 #define LOCAL_HUB	LOCAL_HUB_ADDR
+#define LOCK_HUB	REMOTE_HUB_ADDR
 
 #define ADDR_L1_REG(n, r)	\
     (L1_UART_BASE(n) | ( (r) << 3 ))
@@ -84,21 +99,10 @@
     ( SD(ADDR_L1_REG((n), (r)), (v)) )
 
 
-/* Avoid conflicts with symmon...*/
-#define CONS_HW_LOCK(x)
-#define CONS_HW_UNLOCK(x)
-
-#define L1_CONS_HW_LOCK(sc)	CONS_HW_LOCK(sc->uart == BRL1_LOCALUART)
-#define L1_CONS_HW_UNLOCK(sc)	CONS_HW_UNLOCK(sc->uart == BRL1_LOCALUART)
-
-#if DEBUG
-static int debuglock_ospl; /* For CONS_HW_LOCK macro */
-#endif
-
 /* UART-related #defines */
 
 #define UART_BAUD_RATE		57600
-#define UART_FIFO_DEPTH		16
+#define UART_FIFO_DEPTH		0xf0
 #define UART_DELAY_SPAN		10
 #define UART_PUTC_TIMEOUT	50000
 #define UART_INIT_TIMEOUT	100000
@@ -146,6 +150,9 @@
 	    _xyz[0] = _b[_i++];			\
 	}
 #else	/* BIG_ENDIAN */
+
+extern char *bcopy(const char * src, char * dest, int count);
+
 #define COPY_INT_TO_BUFFER(_b, _i, _n)			\
 	{						\
 		bcopy((char *)&_n, _b, sizeof(_n));	\
@@ -165,13 +172,148 @@
 	}
 #endif	/* LITTLE_ENDIAN */
 
-int atomicAddInt(int *int_ptr, int value);
-int atomicClearInt(int *int_ptr, int value);
 void kmem_free(void *where, int size);
 
 #define BCOPY(x,y,z)	memcpy(y,x,z)
 
-extern char *bcopy(const char * src, char * dest, int count);
+/*
+ * Console locking defines and functions.
+ *
+ */
+
+#ifdef BRINGUP
+#define FORCE_CONSOLE_NASID
+#endif
+
+#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 */
+
+inline void
+lock_console(nasid_t nasid)
+{
+	int ret;
+
+	ret = hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
+	if ( ret != 0 ) {
+		/* 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);
+	}
+}
+
+inline void
+unlock_console(nasid_t nasid)
+{
+	hub_unlock(nasid, HUB_LOCK);
+}
 
 
 int 
@@ -189,7 +331,7 @@
     UART_DELAY( delay_span );
 }
 
-#define UART_PUTC_READY(n)	(READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE)
+#define UART_PUTC_READY(n)      ( (READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE) && (READ_L1_UART_REG((n), REG_MSR) & MSR_CTS) )
 
 static int
 uart_putc( l1sc_t *sc ) 
@@ -198,6 +340,10 @@
     /* need a delay to avoid dropping chars */
     UART_DELAY(57);
 #endif
+#ifdef FORCE_CONSOLE_NASID
+    /* We need this for the console write path _elscuart_flush() -> brl1_send() */
+    sc->nasid = 0;
+#endif
     WRITE_L1_UART_REG( sc->nasid, REG_DAT,
 		       sc->send[sc->sent] );
     return UART_SUCCESS;
@@ -210,6 +356,10 @@
     u_char lsr_reg = 0;
     nasid_t nasid = sc->nasid;
 
+#ifdef FORCE_CONSOLE_NASID
+    nasid = sc->nasid = 0;
+#endif
+
     if( (lsr_reg = READ_L1_UART_REG( nasid, REG_LSR )) & 
 	(LSR_RCA | LSR_PARERR | LSR_FRMERR) ) 
     {
@@ -246,7 +396,8 @@
 	}
     }
 
-    L1_CONS_HW_LOCK( sc );
+    if ( sc->uart == BRL1_LOCALUART )
+	lock_console(nasid);
 
     WRITE_L1_UART_REG( nasid, REG_LCR, LCR_DLAB );
 	uart_delay( UART_DELAY_SPAN );
@@ -271,17 +422,17 @@
     WRITE_L1_UART_REG( nasid, REG_FCR,
 	FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO );
 
-    L1_CONS_HW_UNLOCK( sc );
+    if ( sc->uart == BRL1_LOCALUART )
+	unlock_console(nasid);
 }
 
+/* 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;
 
-    L1_CONS_HW_LOCK(sc);
-
     /* make sure that the DLAB bit in the LCR register is 0
      */
     lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
@@ -293,18 +444,15 @@
     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)*/ );
-
-    L1_CONS_HW_UNLOCK(sc);
 }
 
+/* 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;
 
-    L1_CONS_HW_LOCK(sc);
-
     /* make sure that the DLAB bit in the LCR register is 0
      */
     lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
@@ -316,8 +464,6 @@
     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)*/ );
-
-    L1_CONS_HW_UNLOCK(sc);
 }
 
 #define uart_enable_xmit_intr(sc) \
@@ -353,15 +499,9 @@
 	}						\
     }
 
-#ifdef SABLE
-#define RTR_UART_PUTC_TIMEOUT	0
-#define RTR_UART_DELAY_SPAN	0
-#define RTR_UART_INIT_TIMEOUT	0
-#else
 #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
-#endif
 
 static int
 rtr_uart_putc( l1sc_t *sc )
@@ -370,7 +510,11 @@
     nasid_t nasid = sc->nasid;
     net_vec_t path = sc->uart;
     rtc_time_t expire = rtc_time() + RTR_UART_PUTC_TIMEOUT;
-    
+
+#ifdef FORCE_CONSOLE_NASID
+    /* We need this for the console write path _elscuart_flush() -> brl1_send() */
+    nasid = sc->nasid = 0;
+#endif
     c = (sc->send[sc->sent] & 0xffULL);
     
     while( 1 ) 
@@ -399,6 +543,10 @@
     nasid_t nasid = sc->nasid;
     net_vec_t path = sc->uart;
 
+#ifdef FORCE_CONSOLE_NASID
+    nasid = sc->nasid = 0;
+#endif
+
     READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
     if( regval & (LSR_RCA | LSR_PARERR | LSR_FRMERR) )
     {
@@ -468,28 +616,6 @@
 
     return 0;
 }
-    
-	
-
-/*********************************************************************
- * locking macros 
- */
-
-#define L1SC_SEND_LOCK(l,pl)						\
-     { if( (l)->uart == BRL1_LOCALUART )				\
-	 (pl) = mutex_spinlock_spl( &((l)->send_lock), spl7 ); }
-
-#define L1SC_SEND_UNLOCK(l,pl)				\
-     { if( (l)->uart == BRL1_LOCALUART )		\
-	 mutex_spinunlock( &((l)->send_lock), (pl)); }
-
-#define L1SC_RECV_LOCK(l,pl)						\
-     { if( (l)->uart == BRL1_LOCALUART )				\
-	 (pl) = mutex_spinlock_spl( &((l)->recv_lock), spl7 ); }
-
-#define L1SC_RECV_UNLOCK(l,pl)				\
-     { if( (l)->uart == BRL1_LOCALUART )		\
-	 mutex_spinunlock( &((l)->recv_lock), (pl)); }
 
 
 /*********************************************************************
@@ -501,60 +627,17 @@
  *
  */
 
-
 #ifdef SPINLOCKS_WORK
-#define SUBCH_LOCK(sc,pl) \
-     (pl) = mutex_spinlock_spl( &((sc)->subch_lock), spl7 )
-#define SUBCH_UNLOCK(sc,pl) \
-     mutex_spinunlock( &((sc)->subch_lock), (pl) )
-
-#define SUBCH_DATA_LOCK(sbch,pl) \
-     (pl) = mutex_spinlock_spl( &((sbch)->data_lock), spl7 )
-#define SUBCH_DATA_UNLOCK(sbch,pl) \
-     mutex_spinunlock( &((sbch)->data_lock), (pl) )
+#define SUBCH_LOCK(sc)			spin_lock_irq( &((sc)->subch_lock) )
+#define SUBCH_UNLOCK(sc)		spin_unlock_irq( &((sc)->subch_lock) )
+#define SUBCH_DATA_LOCK(sbch) 		spin_lock_irq( &((sbch)->data_lock) )
+#define SUBCH_DATA_UNLOCK(sbch)		spin_unlock_irq( &((sbch)->data_lock) )
 #else
-#define SUBCH_LOCK(sc,pl) 
-#define SUBCH_UNLOCK(sc,pl)
-#define SUBCH_DATA_LOCK(sbch,pl)
-#define SUBCH_DATA_UNLOCK(sbch,pl)
-#endif	/* SPINLOCKS_WORK */
-
-/*
- * 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 )
-{
-    int pl;
-    L1SC_SEND_LOCK( sc, pl );
-    sc->subch[ch].tx_notify = func;
-    
-    /* some upper layer is asking to be notified of low-water, but if the 
-     * send buffer isn't already in use, we're going to need to get the
-     * interrupts going on the uart...
-     */
-    if( func && !sc->send_in_use )
-	uart_enable_xmit_intr( sc );
-    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 )
-{
-#ifdef SPINLOCKS_WORK
-    int pl;
+#define SUBCH_LOCK(sc)
+#define SUBCH_UNLOCK(sc)
+#define SUBCH_DATA_LOCK(sbch)
+#define SUBCH_DATA_UNLOCK(sbch)
 #endif
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    SUBCH_DATA_LOCK( subch, pl );
-    sc->subch[ch].rx_notify = func;
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
 
 
 /* get_myid is an internal function that reads the PI_CPU_NUM
@@ -680,21 +763,18 @@
 /* timeouts */
 #define BRL1_INIT_TIMEOUT	500000
 
-extern l1sc_t * get_elsc( void );
-
 /*
  * brl1_discard_packet is a dummy "receive callback" used to get rid
  * of packets we don't want
  */
 void brl1_discard_packet( l1sc_t *sc, int ch )
 {
-    int pl;
     brl1_sch_t *subch = &sc->subch[ch];
     sc_cq_t *q = subch->iqp;
-    SUBCH_DATA_LOCK( subch, pl );
+    SUBCH_DATA_LOCK( subch );
     q->opos = q->ipos;
-    atomicClearInt( &(subch->packet_arrived), ~((unsigned)0) );
-    SUBCH_DATA_UNLOCK( subch, pl );
+    atomic_clear( &(subch->packet_arrived), ~((unsigned)0) );
+    SUBCH_DATA_UNLOCK( subch );
 }
 
 
@@ -720,18 +800,14 @@
      */
     if( sc->uart == BRL1_LOCALUART ) 
     {
-	CONS_HW_LOCK(1);
 	if( !(sc->fifo_space) && UART_PUTC_READY( sc->nasid ) )
-//	    sc->fifo_space = UART_FIFO_DEPTH;
-	    sc->fifo_space = 1000;
+	    sc->fifo_space = UART_FIFO_DEPTH;
 	
 	while( (sc->sent < sc->send_len) && (sc->fifo_space) ) {
 	    uart_putc( sc );
 	    sc->fifo_space--;
 	    sc->sent++;
 	}
-
-	CONS_HW_UNLOCK(1);
     }
 
     else
@@ -770,7 +846,6 @@
 	    }
 	}
     }
-    
     return sc->sent;
 }
 
@@ -786,20 +861,25 @@
  * until our message has been completely transmitted.
  */
 
-int
+static int
 brl1_send( l1sc_t *sc, char *msg, int len, u_char type_and_subch, int wait )
 {
-    int pl;
     int index;
     int pkt_len = 0;
     unsigned short crc = INIT_CRC;
     char *send_ptr = sc->send;
 
-    L1SC_SEND_LOCK(sc, pl);
+#ifdef BRINGUP
+    /* We want to be sure that we are sending the entire packet before returning */
+    wait = 1;
+#endif
+    if ( sc->uart == BRL1_LOCALUART )
+	lock_console(sc->nasid);
 
     if( sc->send_in_use ) {
 	if( !wait ) {
-	    L1SC_SEND_UNLOCK(sc, pl);
+    	    if ( sc->uart == BRL1_LOCALUART )
+	    	unlock_console(sc->nasid);
 	    return 0; /* couldn't send anything; wait for buffer to drain */
 	}
 	else {
@@ -880,61 +960,12 @@
 	/* enable low-water interrupts so buffer will be drained */
 	uart_enable_xmit_intr(sc);
     }
-    L1SC_SEND_UNLOCK(sc, pl);
+    if ( sc->uart == BRL1_LOCALUART )
+	unlock_console(sc->nasid);
     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.
- */
-int
-brl1_send_cont( l1sc_t *sc )
-{
-    int pl;
-    int done = 0;
-    brl1_notif_t callups[BRL1_NUM_SUBCHANS];
-    brl1_notif_t *callup;
-    brl1_sch_t *subch;
-    int index;
-
-    L1SC_SEND_LOCK(sc, pl);
-    brl1_send_chars( sc );
-    done = (sc->sent == sc->send_len);
-    if( done ) {
-
-	sc->send_in_use = 0;
-	uart_disable_xmit_intr(sc);
-
-	/* collect pointers to callups *before* unlocking */
-	subch = sc->subch;
-	callup = callups;
-	for( index = 0; index < BRL1_NUM_SUBCHANS; index++ ) {
-	    *callup = subch->tx_notify;
-	    subch++;
-	    callup++;
-	}
-    }
-    L1SC_SEND_UNLOCK(sc, pl);
-
-    if( done ) {
-	/* call any upper layer that's asked for low-water notification */
-	callup = callups;
-	for( index = 0; index < BRL1_NUM_SUBCHANS; index++ ) {
-	    if( *callup )
-		(*(*callup))( sc, index );
-	    callup++;
-	}
-    }
-    return 0;
-}
-
-
 /* internal function -- used by brl1_receive to read a character 
  * from the uart and check whether errors occurred in the process.
  */
@@ -1039,14 +1070,16 @@
 {
     int result;		/* value to be returned by brl1_receive */
     int c;		/* most-recently-read character	     	*/
-    int pl;		/* priority level for UART receive lock */
     int done;		/* set done to break out of recv loop	*/
     sc_cq_t *q;		/* pointer to queue we're working with	*/
 
     result = BRL1_NO_MESSAGE;
 
-    L1SC_RECV_LOCK( sc, pl );
-    L1_CONS_HW_LOCK( sc );
+#ifdef FORCE_CONSOLE_NASID
+    sc->nasid = 0;
+#endif
+    if ( sc->uart == BRL1_LOCALUART )
+	lock_console(sc->nasid);
 
     done = 0;
     while( !done )
@@ -1171,7 +1204,6 @@
 		unsigned short crc;	/* holds the crc as we calculate it */
 		int i;			/* index variable */
 		brl1_sch_t *subch;      /* subchannel for received packet */
-		int sch_pl;		/* cookie for subchannel lock */
 		brl1_notif_t callup;	/* "data ready" callup */
 
 		/* whatever else may happen, we've seen a flag and we're
@@ -1226,7 +1258,7 @@
 
 		/* get the subchannel and lock it */
 		subch = &(sc->subch[SUBCH( LAST_HDR_GET(sc) )]);
-		SUBCH_DATA_LOCK( subch, sch_pl );
+		SUBCH_DATA_LOCK( subch );
 		
 		/* if this isn't a console packet, we need to record
 		 * a length byte
@@ -1242,16 +1274,16 @@
 		/* notify subchannel owner that there's something
 		 * on the queue for them
 		 */
-		atomicAddInt( &(subch->packet_arrived), 1);
+		atomic_inc(&(subch->packet_arrived));
 		callup = subch->rx_notify;
-		SUBCH_DATA_UNLOCK( subch, sch_pl );
+		SUBCH_DATA_UNLOCK( subch );
 
 		if( callup ) {
-		    L1_CONS_HW_UNLOCK( sc );
-		    L1SC_RECV_UNLOCK( sc, pl );
+		    if ( sc->uart == BRL1_LOCALUART )
+			unlock_console(sc->nasid);
 		    (*callup)( sc, SUBCH(LAST_HDR_GET(sc)) );
-		    L1SC_RECV_LOCK( sc, pl );
-		    L1_CONS_HW_LOCK( sc );
+		    if ( sc->uart == BRL1_LOCALUART )
+			lock_console(sc->nasid);
 		}
 		continue;	/* go back for more! */
 	    }
@@ -1320,8 +1352,8 @@
 	} /* end of switch( STATE_GET(sc) ) */
     } /* end of while(!done) */
     
-    L1_CONS_HW_UNLOCK( sc );
-    L1SC_RECV_UNLOCK(sc, pl);
+    if ( sc->uart == BRL1_LOCALUART )
+	unlock_console(sc->nasid);
 
     return result;
 }	    
@@ -1338,6 +1370,9 @@
     brl1_sch_t *subch;
 
     bzero( sc, sizeof( *sc ) );
+#ifdef FORCE_CONSOLE_NASID
+    nasid = (nasid_t)0;
+#endif
     sc->nasid = nasid;
     sc->uart = uart;
     sc->getc_f = (uart == BRL1_LOCALUART ? uart_getc : rtr_uart_getc);
@@ -1351,9 +1386,9 @@
     /* assign processor TTY channels */
     for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {
 	subch->use = BRL1_SUBCH_RSVD;
-	subch->packet_arrived = 0;
-	spinlock_init( &(subch->data_lock), NULL );
-	sv_init( &(subch->arrive_sv), SV_FIFO, NULL );
+	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;
@@ -1364,9 +1399,9 @@
      * processor's individual TTY channel has been assigned)
      */
     subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = 0;
-    spinlock_init( &(subch->data_lock), NULL );
-    sv_init( &(subch->arrive_sv), SV_FIFO, NULL );
+    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_LOCALUART ) {
 	subch->iqp = kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
@@ -1387,7 +1422,7 @@
      */
     for( ; i < 0x10; i++, subch++ ) {
 	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = 0;
+	subch->packet_arrived = ATOMIC_INIT(0);
 	subch->tx_notify = NULL;
 	subch->rx_notify = brl1_discard_packet;
 	subch->iqp = &sc->garbage_q;
@@ -1396,7 +1431,7 @@
     /* remaining subchannels are free */
     for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {
 	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = 0;
+	subch->packet_arrived = ATOMIC_INIT(0);
 	subch->tx_notify = NULL;
 	subch->rx_notify = brl1_discard_packet;
 	subch->iqp = &sc->garbage_q;
@@ -1404,9 +1439,7 @@
 
     /* initialize synchronization structures
      */
-    spinlock_init( &(sc->send_lock), NULL );
-    spinlock_init( &(sc->recv_lock), NULL );
-    spinlock_init( &(sc->subch_lock), NULL );
+    spin_lock_init( &(sc->subch_lock) );
 
     if( sc->uart == BRL1_LOCALUART ) {
 	uart_init( sc, UART_BAUD_RATE );
@@ -1423,146 +1456,46 @@
 	extern int elsc_module_get(l1sc_t *);
 
 	sc->modid = elsc_module_get( sc );
-	sc->modid = 
-	    (sc->modid < 0 ? INVALID_MODULE : sc->modid);
-
+	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 in a loop by the
- * xthread that services L1 interrupts.
- */
-#ifdef IRIX
-void
-brl1_intrd( struct eframe_s *ep )
-{
-    u_char isr_reg;
-    l1sc_t *sc = get_elsc();
-
-    isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-
-    while( isr_reg & (ISR_RxRDY | ISR_TxRDY) ) {
-
-	if( isr_reg & ISR_RxRDY ) {
-	    brl1_receive(sc);
-	}
-	if( (isr_reg & ISR_TxRDY) || 
-	    (sc->send_in_use && UART_PUTC_READY(sc->nasid)) ) 
-	{
-	    brl1_send_cont(sc);
-	}
-	isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-    }
-
-    /* uart interrupts were blocked at bedrock when the interrupt
-     * was initially answered; reenable them now
-     */
-    intr_unblock_bit( sc->intr_cpu, UART_INTR );
-    ep = ep; /* placate the compiler */
-}
-#endif
-
-
-
-/* brl1_intr is called directly from the uart interrupt; after it runs, the
- * interrupt "daemon" xthread is signalled to continue.
- */
-#ifdef IRIX
-void
-brl1_intr( struct eframe_s *ep )
-{
-    /* Disable the UART interrupt, giving the xthread time to respond.
-     * When the daemon (xthread) finishes doing its thing, it will
-     * unblock the interrupt.
-     */
-    intr_block_bit( get_elsc()->intr_cpu, UART_INTR );
-    ep = ep; /* placate the compiler */
-}
-
-
-/* set up uart interrupt handling for this node's uart
- */
-void
-brl1_connect_intr( l1sc_t *sc )
-{
-    cpuid_t last_cpu;
-
-    sc->intr_cpu = nodepda->node_first_cpu;
-
-    if( intr_connect_level(sc->intr_cpu, UART_INTR, INTPEND0_MAXMASK,
-			   (intr_func_t)brl1_intrd, 0, 
-			   (intr_func_t)brl1_intr) )
-	cmn_err(CE_PANIC, "brl1_connect_intr: Can't connect UART interrupt.");
-
-    uart_enable_recv_intr( sc );
-}
-#endif	/* IRIX */
-
-#ifdef SABLE
-/* this function is called periodically to generate fake interrupts
- * and allow brl1_intrd to send/receive characters
- */
-void
-hubuart_service( void )
-{
-    l1sc_t *sc = get_elsc();
-    /* note that we'll lose error state by reading the lsr_reg.
-     * This is probably ok in the frictionless domain of sable.
-     */
-    int lsr_reg;
-    nasid_t nasid = sc->nasid;
-    lsr_reg = READ_L1_UART_REG( nasid, REG_LSR );
-    if( lsr_reg & (LSR_RCA | LSR_XSRE) ) {
-        REMOTE_HUB_PI_SEND_INTR(0, 0, UART_INTR);
-    }
-}
-#endif /* SABLE */
-
-
-/*********************************************************************
- * The following function allows the kernel to "go around" the
- * uninitialized l1sc structure to allow console output during
- * early system startup.
- */
-
 /* These are functions to use from serial_in/out when in protocol
- * mode to send and receive uart control regs.
+ * mode to send and receive uart control regs. These are external
+ * interfaces into the protocol driver.
  */
 void
-brl1_send_control(int offset, int value)
+l1_control_out(int offset, int value)
 {
-	nasid_t nasid = get_nasid();
+	nasid_t nasid = 0; //(get_elsc())->nasid;
 	WRITE_L1_UART_REG(nasid, offset, value); 
 }
 
 int
-brl1_get_control(int offset)
+l1_control_in(int offset)
 {
-	nasid_t nasid = get_nasid();
+	nasid_t nasid = 0; //(get_elsc())->nasid;
 	return(READ_L1_UART_REG(nasid, offset)); 
 }
 
 #define PUTCHAR(ch) \
     { \
-        while( !(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XHRE) );  \
+        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) ); \
     }
 
 int
-brl1_send_console_packet( char *str, int len )
+l1_serial_out( char *str, int len )
 {
     int sent = len;
     char crc_char;
     unsigned short crc = INIT_CRC;
-    nasid_t nasid = get_nasid();
+    nasid_t nasid = 0; //(get_elsc())->nasid;
+
+    lock_console(nasid);
 
     PUTCHAR( BRL1_FLAG_CH );
     PUTCHAR( BRL1_EVENT | SC_CONS_SYSTEM );
@@ -1598,9 +1531,18 @@
     PUTCHAR( crc_char );
     PUTCHAR( BRL1_FLAG_CH );
 
+    unlock_console(nasid);
     return sent - len;
 }
 
+int
+l1_serial_in(void)
+{
+	static int l1_cons_getc( l1sc_t *sc );
+
+	return(l1_cons_getc(get_elsc()));
+}
+
 
 /*********************************************************************
  * l1_cons functions
@@ -1612,7 +1554,7 @@
  *
  */
 
-int
+static int
 l1_cons_poll( l1sc_t *sc )
 {
     /* in case this gets called before the l1sc_t structure for the module_t
@@ -1623,13 +1565,13 @@
 	return 0;
     }
 
-    if( sc->subch[SC_CONS_SYSTEM].packet_arrived ) {
+    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
 	return 1;
     }
 
     brl1_receive( sc );
 
-    if( sc->subch[SC_CONS_SYSTEM].packet_arrived ) {
+    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
 	return 1;
     }
     return 0;
@@ -1638,13 +1580,11 @@
 
 /* pull a character off of the system console queue (if one is available)
  */
-int
+static int
 l1_cons_getc( l1sc_t *sc )
 {
     int c;
-#ifdef SPINLOCKS_WORK
-    int pl;
-#endif
+
     brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
     sc_cq_t *q = subch->iqp;
 
@@ -1652,16 +1592,16 @@
 	return 0;
     }
 
-    SUBCH_DATA_LOCK( subch, pl );
+    SUBCH_DATA_LOCK( subch );
     if( cq_empty( q ) ) {
-	subch->packet_arrived = 0;
-	SUBCH_DATA_UNLOCK( subch, pl );
+	atomic_set(&subch->packet_arrived, 0);
+	SUBCH_DATA_UNLOCK( subch );
 	return 0;
     }
     cq_rem( q, c );
     if( cq_empty( q ) )
-	subch->packet_arrived = 0;
-    SUBCH_DATA_UNLOCK( subch, pl );
+	atomic_set(&subch->packet_arrived, 0);
+    SUBCH_DATA_UNLOCK( subch );
 
     return c;
 }
@@ -1672,106 +1612,15 @@
 void
 l1_cons_init( l1sc_t *sc )
 {
-#ifdef SPINLOCKS_WORK
-    int pl;
-#endif
     brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
 
-    SUBCH_DATA_LOCK( subch, pl );
-    subch->packet_arrived = 0;
+    SUBCH_DATA_LOCK( subch );
+    atomic_set(&subch->packet_arrived, 0);
     cq_init( subch->iqp );
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-
-/*
- * 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_cons_write( l1sc_t *sc, char *msg, int len, int wait )
-{
-    return( brl1_send( sc, msg, len, (SC_CONS_SYSTEM | BRL1_EVENT), wait ) );
-}
-
-
-/* 
- * Read as many characters from the system console receive queue as are
- * available there (up to avail bytes).
- */
-int
-l1_cons_read( l1sc_t *sc, char *buf, int avail )
-{
-    int pl;
-    int before_wrap, after_wrap;
-    brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
-    sc_cq_t *q = subch->iqp;
-
-    if( !(subch->packet_arrived) )
-	return 0;
-
-    SUBCH_DATA_LOCK( subch, pl );
-    if( q->opos > q->ipos ) {
-	before_wrap = BRL1_QSIZE - q->opos;
-	if( before_wrap >= avail ) {
-	    before_wrap = avail;
-	    after_wrap = 0;
-	}
-	else {
-	    avail -= before_wrap;
-	    after_wrap = q->ipos;
-	    if( after_wrap > avail )
-		after_wrap = avail;
-	}
-    }
-    else {
-	before_wrap = q->ipos - q->opos;
-	if( before_wrap > avail )
-	    before_wrap = avail;
-	after_wrap = 0;
-    }
-
-
-    BCOPY( q->buf + q->opos, buf, before_wrap  );
-    if( after_wrap )
-        BCOPY( q->buf, buf + before_wrap, after_wrap  );
-    q->opos = ((q->opos + before_wrap + after_wrap) % BRL1_QSIZE);
-
-    subch->packet_arrived = 0;
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return( before_wrap + after_wrap );
-}
-	
-
-/*
- * Install a callback function for the system console subchannel 
- * to allow an upper layer to be notified when the send buffer 
- * has been emptied.
- */
-void
-l1_cons_tx_notif( l1sc_t *sc, brl1_notif_t func )
-{
-    subch_set_tx_notify( sc, 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.
- */
-void
-l1_cons_rx_notif( l1sc_t *sc, brl1_notif_t func )
-{
-    subch_set_rx_notify( sc, SC_CONS_SYSTEM, func );
+    SUBCH_DATA_UNLOCK( subch );
 }
 
 
-
-
 /*********************************************************************
  * The following functions and definitions implement the "message"-
  * style interface to the L1 system controller.
@@ -1795,7 +1644,9 @@
 sc_data_ready( l1sc_t *sc, int ch )
 {
     brl1_sch_t *subch = &(sc->subch[ch]);
+    SUBCH_DATA_LOCK( subch );
     sv_signal( &(subch->arrive_sv) );
+    SUBCH_DATA_UNLOCK( subch );
 }
 
 /* sc_open reserves a subchannel to send a request to the L1 (the
@@ -1810,10 +1661,9 @@
      * subchannel assignment.
      */
     int ch;
-    int pl;
     brl1_sch_t *subch;
 
-    SUBCH_LOCK( sc, pl );
+    SUBCH_LOCK( sc );
 
     /* Look for a free subchannel. Subchannels 0-15 are reserved
      * for other purposes.
@@ -1826,17 +1676,17 @@
 
     if( ch == BRL1_NUM_SUBCHANS ) {
         /* there were no subchannels available! */
-        SUBCH_UNLOCK( sc, pl );
+        SUBCH_UNLOCK( sc );
         return SC_NSUBCH;
     }
 
     subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
+    SUBCH_UNLOCK( sc );
 
-    subch->packet_arrived = 0;
+    atomic_set(&subch->packet_arrived, 0);
     subch->target = target;
-    sv_init( &(subch->arrive_sv), SV_FIFO, NULL );
-    spinlock_init( &(subch->data_lock), NULL );
+    spin_lock_init( &(subch->data_lock) );
+    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
     subch->tx_notify = NULL;
     subch->rx_notify = sc_data_ready;
     subch->iqp = kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
@@ -1854,27 +1704,28 @@
 sc_close( l1sc_t *sc, int ch )
 {
     brl1_sch_t *subch;
-    int pl;
 
-    SUBCH_LOCK( sc, pl );
+    SUBCH_LOCK( sc );
     subch = &(sc->subch[ch]);
     if( subch->use != BRL1_SUBCH_RSVD ) {
         /* we're trying to close a subchannel that's not open */
         return SC_NOPEN;
     }
 
-    subch->packet_arrived = 0;
+    atomic_set(&subch->packet_arrived, 0);
     subch->use = BRL1_SUBCH_FREE;
 
+    SUBCH_DATA_LOCK( subch );
     sv_broadcast( &(subch->arrive_sv) );
     sv_destroy( &(subch->arrive_sv) );
-    spinlock_destroy( &(subch->data_lock) );
+    SUBCH_DATA_UNLOCK( subch );
+    spin_lock_destroy( &(subch->data_lock) );
 
     ASSERT( subch->iqp && (subch->iqp != &sc->garbage_q) );
     kmem_free( subch->iqp, sizeof(sc_cq_t) );
     subch->iqp = &sc->garbage_q;
 
-    SUBCH_UNLOCK( sc, pl );
+    SUBCH_UNLOCK( sc );
 
     return SC_SUCCESS;
 }
@@ -2248,7 +2099,7 @@
     else {
 	q->opos = ((q->opos + before_wrap) & (BRL1_QSIZE - 1));
     }
-    atomicAddInt( &(subch->packet_arrived), -1 );
+    atomic_dec(&(subch->packet_arrived));
 }
 
 
@@ -2263,7 +2114,6 @@
 int
 sc_recv_poll( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
 {
-    int pl;             /* lock cookie */
     int is_msg = 0;
     brl1_sch_t *subch = &(sc->subch[ch]);
 
@@ -2278,7 +2128,7 @@
         /* kick the next lower layer and see if it pulls anything in
          */
 	brl1_receive( sc );
-	is_msg = subch->packet_arrived;
+	is_msg = atomic_read(&subch->packet_arrived);
 
     } while( block && !is_msg && (rtc_time() < exp_time) );
 
@@ -2287,9 +2137,9 @@
 	return( SC_NMSG );
     }
 
-    SUBCH_DATA_LOCK( subch, pl );
+    SUBCH_DATA_LOCK( subch );
     subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
+    SUBCH_DATA_UNLOCK( subch );
 
     return( SC_SUCCESS );
 }
@@ -2305,17 +2155,16 @@
 int
 sc_recv_intr( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
 {
-    int pl;             /* lock cookie */
     int is_msg = 0;
     brl1_sch_t *subch = &(sc->subch[ch]);
 
     do {
-	SUBCH_DATA_LOCK(subch, pl);
-	is_msg = subch->packet_arrived;
+	SUBCH_DATA_LOCK(subch);
+	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, &(subch->data_lock), pl );
+	    sv_wait( &(subch->arrive_sv), 0, 0);
 	    if( subch->use == BRL1_SUBCH_FREE ) {
 		/* oops-- somebody closed our subchannel while we were
 		 * sleeping!
@@ -2329,12 +2178,12 @@
 
     if( !is_msg ) {
 	/* no message and we didn't care to wait for one */
-	SUBCH_DATA_UNLOCK( subch, pl );
+	SUBCH_DATA_UNLOCK( subch );
 	return( SC_NMSG );
     }
 
     subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
+    SUBCH_DATA_UNLOCK( subch );
 
     return( SC_SUCCESS );
 }
@@ -2388,12 +2237,12 @@
     }
     
     /* block on sc_recv_* */
-#ifdef notyet
+#ifdef LATER
     if( sc->uart == BRL1_LOCALUART ) {
 	return( sc_recv_intr( sc, ch, resp, len, __WAIT_RECV ) );
     }
     else
-#endif
+#endif	/* LATER */
     {
 	return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
     }
@@ -2438,12 +2287,12 @@
 {
     brl1_sch_t *subch = &(sc->subch[ch]);
 
-    if( subch->packet_arrived )
+    if( atomic_read(&subch->packet_arrived) )
 	return 1;
 
     brl1_receive( sc );
 
-    if( subch->packet_arrived )
+    if( atomic_read(&subch->packet_arrived) )
 	return 1;
 
     return 0;
@@ -2461,6 +2310,9 @@
 /* sc_dispatch_env_event handles events sent from the system control
  * network's environmental monitor tasks.
  */
+
+#ifdef LINUX_KERNEL_THREADS
+
 static void
 sc_dispatch_env_event( uint code, int argc, char *args, int maxlen )
 {
@@ -2512,18 +2364,16 @@
 	for( ;
 	     i < j && ((args[i] == 0xd) || (args[i] == 0xa));
 	     i++ );
-	
-	/* write the event to syslog */
-#ifdef IRIX
-	cmn_err_tag( ESPcode, CE_WARN, &(args[i]) );
-#endif
     }
 }
+#endif	/* LINUX_KERNEL_THREADS */
 
 
 /* sc_event waits for events to arrive from the system controller, and
  * prints appropriate messages to the syslog.
  */
+
+#ifdef LINUX_KERNEL_THREADS
 static void
 sc_event( l1sc_t *sc, int ch )
 {
@@ -2544,7 +2394,7 @@
 	 */
 	result = sc_recv_intr( sc, ch, event, &event_len, 1 );
 	if( result != SC_SUCCESS ) {
-	    cmn_err( CE_WARN, "Error receiving sysctl event on nasid %d\n",
+	    PRINT_WARNING("Error receiving sysctl event on nasid %d\n",
 		     sc->nasid );
 	}
 	else {
@@ -2588,13 +2438,13 @@
 	
     }			
 }
+#endif	/* LINUX_KERNEL_THREADS */
 
 /* sc_listen sets up a service thread to listen for incoming events.
  */
 void
 sc_listen( l1sc_t *sc )
 {
-    int pl;
     int result;
     brl1_sch_t *subch;
 
@@ -2602,24 +2452,26 @@
     int         len;    /* length of message being sent */
     int         ch;     /* system controller subchannel used */
 
+#ifdef LINUX_KERNEL_THREADS
     extern int msc_shutdown_pri;
+#endif
 
     /* grab the designated "event subchannel" */
-    SUBCH_LOCK( sc, pl );
+    SUBCH_LOCK( sc );
     subch = &(sc->subch[BRL1_EVENT_SUBCH]);
     if( subch->use != BRL1_SUBCH_FREE ) {
-	SUBCH_UNLOCK( sc, pl );
-	cmn_err( CE_WARN, "sysctl event subchannel in use! "
+	SUBCH_UNLOCK( sc );
+	PRINT_WARNING("sysctl event subchannel in use! "
 		 "Not monitoring sysctl events.\n" );
 	return;
     }
     subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
+    SUBCH_UNLOCK( sc );
 
-    subch->packet_arrived = 0;
+    atomic_set(&subch->packet_arrived, 0);
     subch->target = BRL1_LOCALUART;
-    sv_init( &(subch->arrive_sv), SV_FIFO, NULL );
-    spinlock_init( &(subch->data_lock), NULL );
+    spin_lock_init( &(subch->data_lock) );
+    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
     subch->tx_notify = NULL;
     subch->rx_notify = sc_data_ready;
     subch->iqp = kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
@@ -2670,7 +2522,7 @@
 	
 err_return:
     /* there was a problem; complain */
-    cmn_err( CE_WARN, "failed to set sysctl event-monitoring subchannel.  "
+    PRINT_WARNING("failed to set sysctl event-monitoring subchannel.  "
 	     "Sysctl events will not be monitored.\n" );
 }
 
@@ -2825,7 +2677,7 @@
 int
 _elscuart_readc( l1sc_t *sc )
 {
-    int c, pl;
+    int c;
     sc_cq_t *q;
     brl1_sch_t *subch;
 
@@ -2833,32 +2685,32 @@
 	subch = &(sc->subch[ SC_CONS_SYSTEM ]);
 	q = subch->iqp;
 	
-	SUBCH_DATA_LOCK( subch, pl );
+	SUBCH_DATA_LOCK( subch );
         if( !cq_empty( q ) ) {
             cq_rem( q, c );
 	    if( cq_empty( q ) ) {
-		subch->packet_arrived = 0;
+		atomic_set(&subch->packet_arrived, 0);
 	    }
-	    SUBCH_DATA_UNLOCK( subch, pl );
+	    SUBCH_DATA_UNLOCK( subch );
             return c;
         }
-	SUBCH_DATA_UNLOCK( subch, pl );
+	SUBCH_DATA_UNLOCK( subch );
     }
 
     subch = &(sc->subch[ L1_ELSCUART_SUBCH(get_myid()) ]);
     q = subch->iqp;
 
-    SUBCH_DATA_LOCK( subch, pl );
+    SUBCH_DATA_LOCK( subch );
     if( cq_empty( q ) ) {
-	SUBCH_DATA_UNLOCK( subch, pl );
+	SUBCH_DATA_UNLOCK( subch );
         return -1;
     }
 
     cq_rem( q, c );
     if( cq_empty ( q ) ) {
-	subch->packet_arrived = 0;
+	atomic_set(&subch->packet_arrived, 0);
     }
-    SUBCH_DATA_UNLOCK( subch, pl );
+    SUBCH_DATA_UNLOCK( subch );
 
     return c;
 }
@@ -2918,6 +2770,7 @@
 #else
     char ver[BRL1_QSIZE];
     extern int elsc_version( l1sc_t *, char * );
+
     if ( IS_RUNNING_ON_SIMULATOR() )
     	return 0;
     return( elsc_version(sc, ver) >= 0 );
@@ -2932,43 +2785,13 @@
 void
 _elscuart_init( l1sc_t *sc )
 {
-    int pl;
     brl1_sch_t *subch = &sc->subch[L1_ELSCUART_SUBCH(get_myid())];
 
-    SUBCH_DATA_LOCK(subch, pl);
+    SUBCH_DATA_LOCK(subch);
 
-    subch->packet_arrived = 0;
+    atomic_set(&subch->packet_arrived, 0);
     cq_init( subch->iqp );
     cq_init( &sc->oq[MAP_OQ(L1_ELSCUART_SUBCH(get_myid()))] );
 
-    SUBCH_DATA_UNLOCK(subch, pl);
-}
-
-
-#ifdef IRIX
-
-/* elscuart_syscon_listen causes the processor on which it's
- * invoked to "listen" to the system console subchannel (that
- * is, subchannel 4) for console input.
- */
-void
-elscuart_syscon_listen( l1sc_t *sc )
-{
-    int pl;
-    brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
-
-    /* if we're already listening, don't bother */
-    if( sc->cons_listen )
-        return;
-
-    SUBCH_DATA_LOCK( subch, pl );
-
-    subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = 0;
-
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-
-    sc->cons_listen = 1;
+    SUBCH_DATA_UNLOCK(subch);
 }
-#endif	/* IRIX */
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/l1_command.c linux/arch/ia64/sn/io/l1_command.c
--- v2.4.3/linux/arch/ia64/sn/io/l1_command.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/l1_command.c	Thu Apr  5 12:51:47 2001
@@ -18,7 +18,6 @@
 #include <asm/sn/labelcl.h>
 #include <asm/sn/eeprom.h>
 #include <asm/sn/ksys/i2c.h>
-#include <asm/sn/cmn_err.h>
 #include <asm/sn/router.h>
 #include <asm/sn/module.h>
 #include <asm/sn/ksys/l1.h>
@@ -68,7 +67,6 @@
 
 #define SC_COMMAND sc_command
 
-
 /*
  * elsc_init
  *
@@ -206,6 +204,7 @@
     return -1;
 }
 
+
 /*
  * Command Set
  */
@@ -312,6 +311,7 @@
     return 0;
 }
 
+
 /*
  * elsc_rack_bay_get fills in the two int * arguments with the
  * rack number and bay number of the L1 being addressed
@@ -447,8 +447,9 @@
 
     /* construct module ID from rack and slot info */
 
-    if ((ret = elsc_rack_bay_type_get(e, &rnum, &bay, &bricktype)) < 0)
+    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)
@@ -935,6 +936,7 @@
     return cbrick_uid_get( e->nasid, nic );
 }
 
+
 int _elsc_hbt(elsc_t *e, int ival, int rdly)
 {
     e = e;
@@ -958,11 +960,12 @@
 
     /* fill in msg with the opcode & params */
     bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCAL );
 
-    L1_BUILD_ADDR( &target, compt, rack, bay, L1_ADDR_TASK_CMD );
+    L1_BUILD_ADDR( &target, compt, rack, bay, 0 );
+    subch = sc_open( sc, target );
+
     if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 target, L1_REQ_EXEC_CMD, 2,
+				 L1_ADDR_TASK_CMD, L1_REQ_EXEC_CMD, 2,
 				 L1_ARG_ASCII, cmd )) < 0 )
     {
 	sc_close( sc, subch );
@@ -970,7 +973,7 @@
     }
 		   
     /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) < 0 )
+    if( SC_COMMAND( sc, subch, msg, msg, &len ) < 0 )
     {
 	sc_close( sc, subch );
 	return( ELSC_ERROR_CMD_SEND );
@@ -988,6 +991,38 @@
     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
@@ -1115,10 +1150,6 @@
     if ((ret = iobrick_rack_bay_type_get(sc, &rnum, &bay, &brick_type)) < 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;
 
@@ -1203,28 +1234,101 @@
  */
 
 int
-iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up )
+iobrick_pci_pwr( l1sc_t *sc, int bus, int slot, int req_code )
 {
-    char cmd[BRL1_QSIZE];
-    unsigned rack, bay, brick_type;
-    if( iobrick_rack_bay_type_get( sc, &rack, &bay, &brick_type ) < 0 )
+#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 );
-    sprintf( cmd, "pci %d %d %s", bus, slot,
-	     (up ? "u" : "d") );
-    return( sc_command_interp
-	    ( sc, L1_ADDR_TYPE_L1, rack, bay, cmd ) );
+    }
+
+    /* 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 )
 {
-    char cmd[BRL1_QSIZE];
-    unsigned rack, bay, brick_type;
-    if( iobrick_rack_bay_type_get( sc, &rack, &bay, &brick_type ) < 0 )
-	return( ELSC_ERROR_CMD_SEND );
-    sprintf( cmd, "pci %d %s", bus, (up ? "u" : "d") );
-    return( sc_command_interp
-	    ( sc, L1_ADDR_TYPE_L1, rack, bay, cmd ) );
+    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 );
 }
 
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/labelcl.c linux/arch/ia64/sn/io/labelcl.c
--- v2.4.3/linux/arch/ia64/sn/io/labelcl.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/labelcl.c	Thu Apr  5 12:51:47 2001
@@ -286,7 +286,7 @@
 		if (!strcmp(info_name, old_label_list[i].name)) {
 			/* Not allowed to add duplicate labelled info names. */
 			kfree(new_label_list);
-			printk("labelcl_info_add_LBL: Duplicate label name %s for vertex 0x%p\n", info_name, de);
+			printk(KERN_WARNING "labelcl_info_add_LBL: Duplicate label name %s for vertex 0x%p\n", info_name, de);
 			return(-1);
 		}
 		new_label_list[i] = old_label_list[i]; /* structure copy */
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/mem_refcnt.c linux/arch/ia64/sn/io/mem_refcnt.c
--- v2.4.3/linux/arch/ia64/sn/io/mem_refcnt.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/mem_refcnt.c	Thu Apr  5 12:51:47 2001
@@ -17,6 +17,7 @@
 #include <asm/sn/nodepda.h>
 #include <asm/sn/hubspc.h>
 #include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
 #include <asm/sn/mem_refcnt.h>
 #include <asm/sn/hwcntrs.h>
 // From numa_hw.h
@@ -58,15 +59,8 @@
 mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp)
 {
         cnodeid_t node;
-#ifndef CONFIG_IA64_SGI_SN1
-	extern int numnodes;
-#endif
-        
-        ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(*devp) == HUBSPC_REFCOUNTERS );
 
-        if (!cap_able(CAP_MEMORY_MGT)) {
-                return (EPERM);
-        }
+        ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(*devp) == HUBSPC_REFCOUNTERS );
 
         node = master_node_get(*devp);
 
@@ -97,9 +91,6 @@
         int errcode;
         char* buffer;
         size_t blen;
-#ifndef CONFIG_IA64_SGI_SN1
-	extern int numnodes;
-#endif
         
         ASSERT( (hubspc_subdevice_t)(ulong)device_info_get(dev) == HUBSPC_REFCOUNTERS );
 
@@ -186,7 +177,7 @@
                 
                 rcb.rcb_cnodeid = node;
                 rcb.rcb_granularity = MD_PAGE_SIZE;
-#ifdef notyet
+#ifdef LATER
                 rcb.rcb_hw_counter_max = MIGR_COUNTER_MAX_GET(node);
                 rcb.rcb_diff_threshold = MIGR_THRESHOLD_DIFF_GET(node);
 #endif
@@ -209,7 +200,7 @@
                 ASSERT(nslots <= MAX_MEM_SLOTS);
                 for (s = 0; s < nslots; s++) {
                         slot[s].base = (uint64_t)ctob(slot_getbasepfn(node, s));
-#ifdef notyet
+#ifdef LATER
                         slot[s].size  = (uint64_t)ctob(slot_getsize(node, s));
 #else
                         slot[s].size  = (uint64_t)1;
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/ml_SN_init.c linux/arch/ia64/sn/io/ml_SN_init.c
--- v2.4.3/linux/arch/ia64/sn/io/ml_SN_init.c	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/io/ml_SN_init.c	Thu Apr  5 12:51:47 2001
@@ -45,25 +45,8 @@
 
 extern xwidgetnum_t hub_widget_id(nasid_t);
 
-#ifndef CONFIG_IA64_SGI_IO
-#if defined (IP27)
-short		cputype = CPU_IP27;
-#elif defined (IP33)
-short		cputype = CPU_IP33;
-#elif defined (IP35)
-short		cputype = CPU_IP35;
-#else
-#error <BOMB! define new cputype here >
-#endif
-#endif /* CONFIG_IA64_SGI_IO */
-
 static int	fine_mode = 0;
 
-#ifndef CONFIG_IA64_SGI_IO
-/* Global variables */
-pdaindr_t	pdaindr[MAXCPUS];
-#endif
-
 static cnodemask_t	hub_init_mask;	/* Mask of cpu in a node doing init */
 static volatile cnodemask_t hub_init_done_mask;
 					/* Node mask where we wait for
@@ -101,7 +84,7 @@
 		master_nasid = get_nasid();
 		set_master_bridge_base();
 		FIXME("mlreset: Enable when we support ioc3 ..");
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 		if (get_console_nasid() == master_nasid) 
 			/* Set up the IOC3 */
 			ioc3_mlreset((ioc3_cfg_t *)KL_CONFIG_CH_CONS_INFO(master_nasid)->config_base,
@@ -113,7 +96,7 @@
 		nvram_baseinit();
 
 		fine_mode = is_fine_dirmode();
-#endif /* CONFIG_IA64_SGI_IO */
+#endif /* LATER */
 
 		/* We're the master processor */
 		master_procid = smp_processor_id();
@@ -125,7 +108,7 @@
 		 */
 		ASSERT_ALWAYS(master_nasid == get_nasid());
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 
 	/*
 	 * Activate when calias is implemented.
@@ -155,7 +138,7 @@
 				((HUB_PIO_MAP_TO_MEM << IIO_ITTE_IOSP_SHIFT) |
 				(0 << IIO_ITTE_WIDGET_SHIFT)));
 		}
-#endif /* CONFIG_IA64_SGI_IO */
+#endif /* LATER */
 
 		/* Set up the hub initialization mask and init the lock */
 		CNODEMASK_CLRALL(hub_init_mask);
@@ -169,7 +152,7 @@
 		/* Initialize Hub Pseudodriver Management */
 		hubdev_init();
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 		/*
 		 * Our IO system doesn't require cache writebacks.  Set some
 		 * variables appropriately.
@@ -192,7 +175,7 @@
                  * keep redundant PROM code in memory.
                  */
 		he_arcs_set_vectors();
-#endif /* CONFIG_IA64_SGI_IO */
+#endif /* LATER */
 
 	} else { /* slave != 0 */
 		/*
@@ -216,8 +199,10 @@
 
 	extern void router_map_init(nodepda_t *);
 	extern void router_queue_init(nodepda_t *,cnodeid_t);
+	extern void intr_init_vecblk(nodepda_t *, cnodeid_t, int);
+
 #if defined(DEBUG)
-	extern lock_t		intr_dev_targ_map_lock;
+	extern spinlock_t	intr_dev_targ_map_lock;
 	extern uint64_t 	intr_dev_targ_map_size;
 
 	/* Initialize the lock to access the device - target cpu mapping
@@ -229,7 +214,7 @@
 		 * There is always a cnode 0 present.
 		 */
 		intr_dev_targ_map_size = 0;
-		init_spinlock(&intr_dev_targ_map_lock,"dtmap_lock",0);
+		spin_lock_init(&intr_dev_targ_map_lock);
 	}
 #endif	/* DEBUG */
 	/* Allocate per-node platform-dependent data */
@@ -241,8 +226,6 @@
 	hubinfo->h_cnodeid = node;
 	hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(node);
 
-	printk("init_platform_nodepda: hubinfo 0x%p, &hubinfo->h_crblock 0x%p\n", hubinfo, &hubinfo->h_crblock);
-
 	spin_lock_init(&hubinfo->h_crblock);
 
 	hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid);
@@ -265,21 +248,18 @@
 	for (sn=0; sn<NUM_SUBNODES; sn++) {
 		SNPDA(npda,sn)->prof_count = 0;
 		SNPDA(npda,sn)->next_prof_timeout = 0;
-// ajm
-#ifndef CONFIG_IA64_SGI_IO
 		intr_init_vecblk(npda, node, sn);
-#endif
 	}
 
 	npda->vector_unit_busy = 0;
 
 	spin_lock_init(&npda->vector_lock);
-	init_MUTEX_LOCKED(&npda->xbow_sema); /* init it locked? */
+	mutex_init_locked(&npda->xbow_sema); /* init it locked? */
 	spin_lock_init(&npda->fprom_lock);
 
 	spin_lock_init(&npda->node_utlbswitchlock);
 	npda->ni_error_print = 0;
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	if (need_utlbmiss_patch) {
 		npda->node_need_utlbmiss_patch = 1;
 		npda->node_utlbmiss_patched = 1;
@@ -299,7 +279,7 @@
 		npda->nasid_mask[nasid / 8] |= (1 << nasid % 8);
 	}
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	npda->node_first_cpu = get_cnode_cpu(node);
 #endif
 
@@ -324,7 +304,7 @@
 	 * may not be guaranteed shared memory at that time
 	 * which precludes depending on a global dump stack
 	 */
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	npda->dump_stack = (uint64_t *)kmem_zalloc_node(DUMP_STACK_SIZE,VM_NOSLEEP,
 							  node);
 	ASSERT_ALWAYS(npda->dump_stack);
@@ -334,7 +314,7 @@
 	 * both the cpus on a node to proceed with nmi
 	 * handling.
 	 */
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	npda->dump_count = 0;
 
 	/* Setup the (module,slot) --> nic mapping for all the routers
@@ -356,7 +336,7 @@
 		npda->node_bte_info[i] = (bteinfo_t *)NULL;
 	}
 #endif
-#endif /* CONFIG_IA64_SGI_IO */
+#endif /* LATER */
 }
 
 /* XXX - Move the interrupt stuff to intr.c ? */
@@ -369,13 +349,15 @@
 void init_platform_pda(cpuid_t cpu)
 {
 	hub_intmasks_t *intmasks;
+#ifdef	LATER
 	cpuinfo_t cpuinfo;
+#endif
 	int i;
 	cnodeid_t	cnode;
 	synergy_da_t	*sda;
 	int	which_synergy;
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	/* Allocate per-cpu platform-dependent data */
 	cpuinfo = (cpuinfo_t)kmem_alloc_node(sizeof(struct cpuinfo_s), GFP_ATOMIC, cputocnode(cpu));
 	ASSERT_ALWAYS(cpuinfo);
@@ -390,7 +372,7 @@
 	// intmasks = &ppda->p_intmasks;
 	intmasks = &sda->s_intmasks;
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	ASSERT_ALWAYS(&ppda->p_nodepda);
 #endif
 
@@ -400,15 +382,15 @@
 
 	/* Set up pointer to the vector block in the nodepda. */
 	/* (Cant use SUBNODEPDA - not working yet) */
-	intmasks->dispatch0 = &Nodepdaindr[cnode]->snpda[cputosubnode(cpu)].intr_dispatch0;
-	intmasks->dispatch1 = &Nodepdaindr[cnode]->snpda[cputosubnode(cpu)].intr_dispatch1;
+	intmasks->dispatch0 = &Nodepdaindr[cnode]->snpda[cpuid_to_subnode(cpu)].intr_dispatch0;
+	intmasks->dispatch1 = &Nodepdaindr[cnode]->snpda[cpuid_to_subnode(cpu)].intr_dispatch1;
 
 	/* Clear INT_PEND1 masks. */
 	for (i = 0; i < N_INTPEND1_MASKS; i++)
 		intmasks->intpend1_masks[i] = 0;
 
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	/* Don't read the routers unless we're the master. */
 	ppda->p_routertick = 0;
 #endif
@@ -419,7 +401,7 @@
 #error "need protect_hub_calias, protect_nmi_handler_data"
 #endif
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 /*
  * For now, just protect the first page (exception handlers). We
  * may want to protect more stuff later.
@@ -433,13 +415,6 @@
 	for (i = 0; i < MAX_REGIONS; i++) {
 		if (i == nasid_to_region(nasid))
 			continue;
-#ifndef BRINGUP
-		/* Protect the exception handlers. */
-		*(__psunsigned_t *)BDPRT_ENTRY(pa, i) = MD_PROT_NO;
-
-		/* Protect the ARCS SPB. */
-		*(__psunsigned_t *)BDPRT_ENTRY(pa + 4096, i) = MD_PROT_NO;
-#endif
 	}
 }
 
@@ -455,15 +430,12 @@
 	for (i = 0; i < MAX_REGIONS; i++) {
 		if (i == nasid_to_region(nasid))
 			continue;
-#ifndef BRINGUP
-		*(__psunsigned_t *)BDPRT_ENTRY(pa, i) = MD_PROT_NO;
-#endif
 	}
 }
-#endif /* CONFIG_IA64_SGI_IO */
+#endif /* LATER */
 
 
-#ifdef IRIX
+#ifdef LATER
 /*
  * Protect areas of memory that we access uncached by marking them as
  * poisoned so the T5 can't read them speculatively and erroneously
@@ -492,7 +464,7 @@
 				CACHE_ERR_AREA_SIZE, 1);
 #error "SN1 not handled correctly"
 }
-#endif	/* IRIX */
+#endif	/* LATER */
 
 /*
  * per_hub_init
@@ -509,15 +481,10 @@
 	ii_icmr_u_t	ii_icmr;
 	ii_ibcr_u_t	ii_ibcr;
 #endif
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	int i;
 #endif
 
-#ifdef SIMULATED_KLGRAPH
-	compact_to_nasid_node[0] = 0;
-	nasid_to_compact_node[0] = 0;
-	FIXME("per_hub_init: SIMULATED_KLCONFIG: compact_to_nasid_node[0] = 0\n");
-#endif /* SIMULATED_KLGRAPH */
 	nasid = COMPACT_TO_NASID_NODEID(cnode);
 
 	ASSERT(nasid != INVALID_NASID);
@@ -546,15 +513,26 @@
 	if (!done) {
 		npdap = NODEPDA(cnode);
 
+#if defined(CONFIG_IA64_SGI_SYNERGY_PERF)
+		/* initialize per-node synergy perf instrumentation */
+		npdap->synergy_perf_enabled = 0; /* off by default */
+		npdap->synergy_perf_lock = SPIN_LOCK_UNLOCKED;
+		npdap->synergy_perf_freq = SYNERGY_PERF_FREQ_DEFAULT;
+		npdap->synergy_inactive_intervals = 0;
+		npdap->synergy_active_intervals = 0;
+		npdap->synergy_perf_data = NULL;
+		npdap->synergy_perf_first = NULL;
+#endif /* CONFIG_IA64_SGI_SYNERGY_PERF */
+
 		npdap->hub_chip_rev = get_hub_chiprev(nasid);
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 		for (i = 0; i < CPUS_PER_NODE; i++) {
 			cpu = cnode_slice_to_cpuid(cnode, i);
 			if (!cpu_enabled(cpu))
 			    SET_CPU_LEDS(nasid, i, 0xf);
 		}
-#endif /* CONFIG_IA64_SGI_IO */
+#endif /* LATER */
 
 #if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC) /* SN1 specific */
 
@@ -582,7 +560,6 @@
 #endif /* SN0_HWDEBUG */
 
 
-#ifndef CONFIG_IA64_SGI_IO
 
 		/* Reserve all of the hardwired interrupt levels. */
 		intr_reserve_hardwired(cnode);
@@ -590,6 +567,7 @@
 		/* Initialize error interrupts for this hub. */
 		hub_error_init(cnode);
 
+#ifdef LATER
 		/* Set up correctable memory/directory ECC error interrupt. */
 		install_eccintr(cnode);
 
@@ -599,7 +577,7 @@
 		/* Enable RT clock interrupts */
 		hub_rtc_init(cnode);
 		hub_migrintr_init(cnode); /* Enable migration interrupt */
-#endif
+#endif	/* LATER */
 
 		spin_lock(&hub_mask_lock);
 		CNODEMASK_SETB(hub_init_done_mask, cnode);
@@ -609,9 +587,14 @@
 		/*
 		 * Wait for the other CPU to complete the initialization.
 		 */
-		while (CNODEMASK_TSTB(hub_init_done_mask, cnode) == 0)
+		while (CNODEMASK_TSTB(hub_init_done_mask, cnode) == 0) {
+			/*
+			 * On SNIA64 we should never get here ..
+			 */
+			printk("WARNING: per_hub_init: Should NEVER get here!\n");
 			/* LOOP */
 			;
+		}
 	}
 }
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/ml_SN_intr.c linux/arch/ia64/sn/io/ml_SN_intr.c
--- v2.4.3/linux/arch/ia64/sn/io/ml_SN_intr.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/ml_SN_intr.c	Thu Apr  5 12:51:47 2001
@@ -34,6 +34,15 @@
 #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 defined (CONFIG_SGI_IP35)
+
+#include <asm/sn/pci/pciio.h>		/* For SN1 + pcibr Addressing Limitation */
+#include <asm/sn/pci/pcibr.h>		/* For SN1 + pcibr Addressing Limitation */
+#include <asm/sn/pci/pcibr_private.h>	/* For SN1 + pcibr Addressing Limitation */
+#endif /* SN1 */
 
 #if DEBUG_INTR_TSTAMP_DEBUG
 #include <sys/debug.h>
@@ -65,6 +74,8 @@
 
 extern cnodeid_t master_node_get(devfs_handle_t vhdl);
 
+extern snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs);
+
 
 #define INTR_LOCK(vecblk) \
      (s = mutex_spinlock(&(vecblk)->vector_lock))
@@ -99,7 +110,7 @@
 void
 intr_stray(void *lvl)
 {
-    printk("Stray Interrupt - level %ld to cpu %d", (long)lvl, cpuid());
+    PRINT_WARNING("Stray Interrupt - level %ld to cpu %d", (long)lvl, cpuid());
 }
 
 #if defined(DEBUG)
@@ -119,7 +130,7 @@
 
 intr_dev_targ_map_t 	intr_dev_targ_map[MAX_DEVICES];
 uint64_t		intr_dev_targ_map_size;
-lock_t			intr_dev_targ_map_lock;
+spinlock_t		intr_dev_targ_map_lock;
 
 /* Print out the device - target cpu mapping.
  * This routine is used only in the idbg command
@@ -220,7 +231,7 @@
 
 	    }
 
-	spinlock_init(&vecblk->vector_lock, "ivecb");
+	mutex_spinlock_init(&vecblk->vector_lock);
 
 	vecblk->vector_count = 0;    
 	for (i = 0; i < CPUS_PER_SUBNODE; i++)
@@ -254,7 +265,7 @@
 {
     intr_vecblk_t	*vecblk;
     hub_intmasks_t 	*hub_intmasks;
-    int s;
+    unsigned long s;
     int rv = 0;
     int ip;
     synergy_da_t	*sda;
@@ -283,8 +294,7 @@
     INTR_LOCK(vecblk);
 
     if (bit <= -1) {
-	// bit = 0;
-	bit = 7;  /* First available on SNIA */
+	bit = 0;
 	ASSERT(reserve == II_RESERVE);
 	/* Choose any available level */
 	for (; bit < N_INTPEND_BITS; bit++) {
@@ -449,9 +459,9 @@
 {
     intr_vecblk_t	*vecblk;
     hubreg_t		*intpend_masks;
-    int s;
     int rv = 0;
     int ip;
+    unsigned long s;
 
     ASSERT(bit < N_INTPEND_BITS * 2);
 
@@ -530,7 +540,7 @@
 {
     intr_vecblk_t	*vecblk;
     hubreg_t		*intpend_masks;
-    int s;
+    unsigned long s;
     int rv = 0;
     int ip;
 
@@ -582,8 +592,8 @@
 do_intr_block_bit(cpuid_t cpu, int bit, int block)
 {
 	intr_vecblk_t *vecblk;
-	int s;
 	int ip;
+	unsigned long s;
 	hubreg_t *intpend_masks;
 	volatile hubreg_t mask_value;
 	volatile hubreg_t *mask_reg;
@@ -671,7 +681,6 @@
 		int local_cpu_num;
 
 		cpu = cnode_slice_to_cpuid(cnode, slice);
-		cpu = cpu_logical_id(cpu);
 		if (cpu == CPU_NONE)
 			continue;
 
@@ -711,7 +720,7 @@
 }
 
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 /*
  * Convert a subnode vertex into a (cnodeid, which_subnode) pair.
  * Return 0 on success, non-zero on failure.
@@ -736,7 +745,7 @@
 	return(0); /* success */
 }
 
-#endif /* CONFIG_IA64_SGI_IO */
+#endif /* LATER */
 
 /* Make it easy to identify subnode vertices in the hwgraph */
 void
@@ -755,13 +764,14 @@
 }
 
 
-#ifndef CONFIG_IA64_SGI_IO
 /*
  * Given a device descriptor, extract interrupt target information and
  * choose an appropriate CPU.  Return CPU_NONE if we can't make sense
  * out of the target information.
  * TBD: Should this be considered platform-independent code?
  */
+
+#ifdef	LATER
 static cpuid_t
 intr_target_from_desc(device_desc_t dev_desc, int favor_subnode)
 {
@@ -799,10 +809,10 @@
 cpuchosen:
 	return(cpuid);
 }
-#endif /* CONFIG_IA64_SGI_IO */
+#endif	/* LATER */
 
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 /*
  * Check if we had already visited this candidate cnode
  */
@@ -824,7 +834,7 @@
 	return(visited_cnodes);
 }
 
-#endif /* CONFIG_IA64_SGI_IO */
+#endif /* LATER */
 
 
 
@@ -915,7 +925,7 @@
 {
 	cpuid_t		cpuid;				/* possible intr targ*/
 	cnodeid_t 	candidate;			/* possible canidate */
-#ifndef BRINGUP
+#ifdef LATER
 	cnodeid_t	visited_cnodes[MAX_NASIDS], 	/* nodes seen so far */
 		        center,				/* node we are on */
 		        candidate;			/* possible canidate */
@@ -926,10 +936,10 @@
 							 */
 		        maxradius = physmem_maxradius();
 	void		*rv;
-#endif /* BRINGUP */
+#endif /* LATER */
 	int		which_subnode = SUBNODE_ANY;
 
-#if CONFIG_IA64_SGI_IO /* SN1 + pcibr Addressing Limitation */
+/* SN1 + pcibr Addressing Limitation */
 	{
 	devfs_handle_t pconn_vhdl;
 	pcibr_soft_t pcibr_soft;
@@ -962,9 +972,8 @@
 		}
 	}
 	}
-#endif /* CONFIG_IA64_SGI_IO */
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	/* 
 	 * If an interrupt target was specified for this
 	 * interrupt allocation, try to use it.
@@ -998,7 +1007,7 @@
 		 */
 
 	}
-#endif  /* CONFIG_IA64_SGI_IO */
+#endif  /* LATER */
 	
 	/* Check if we can find a valid interrupt target candidate on
 	 * the master node for the device.
@@ -1019,7 +1028,7 @@
 			intr_unreserve_level(cpuid, *resp_bit);
 	}
 
-	printk("Cannot target interrupts to closest node(%d): %ld (0x%lx)\n",
+	PRINT_WARNING("Cannot target interrupts to closest node(%d): %ld (0x%lx)\n",
 		master_node_get(dev),(long) owner_dev, (unsigned long)owner_dev);
 
 	/* Fall through into the default algorithm
@@ -1076,10 +1085,11 @@
 #else  /* BRINGUP */
 	{
 	// Do a stupid round-robin assignment of the node.
-		static cnodeid_t last_node = 0;
+		static cnodeid_t last_node = -1;
 
-		if (last_node > numnodes) last_node = 0;
-		for (candidate = last_node; candidate <= numnodes; candidate++) {
+		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,
@@ -1091,18 +1101,18 @@
 
 			if (cpuid != CPU_NONE) {
 				if (cpu_on_subnode(cpuid, which_subnode)) {
-					last_node++;
+					last_node = candidate;
 					return(cpuid);	/* got a valid interrupt target */
 				}
 				else
 					intr_unreserve_level(cpuid, *resp_bit);
 			}
-			last_node++;
 		}
+		last_node = candidate;
 	}
 #endif
 
-	printk("Cannot target interrupts to any close node: %ld (0x%lx)\n",
+	PRINT_WARNING("Cannot target interrupts to any close node: %ld (0x%lx)\n",
 		(long)owner_dev, (unsigned long)owner_dev);
 
 	/* In the worst case try to allocate interrupt bits on the
@@ -1127,7 +1137,7 @@
 			intr_unreserve_level(cpuid, *resp_bit);
 	}
 
-	printk("Cannot target interrupts: %ld (0x%lx)\n",
+	PRINT_WARNING("Cannot target interrupts: %ld (0x%lx)\n",
 		(long)owner_dev, (unsigned long)owner_dev);
 
 	return(CPU_NONE);	/* Should never get here */
@@ -1515,6 +1525,7 @@
 	}
 }
 
+#endif /* BRINGUP */
 
 struct hardwired_intr_s {
 	signed char level;
@@ -1525,17 +1536,9 @@
 	{ 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" },
-#if defined(SN1) && !defined(DIRECT_L1_CONSOLE)
 	{ INT_PEND0_BASELVL + UART_INTR,	II_THREADED, "Bedrock/L1" },
-#else
-	{ INT_PEND0_BASELVL + UART_INTR,	0,	"Hub I2C" },
-#endif
 	{ INT_PEND0_BASELVL + CC_PEND_A,	0,	"Crosscall A" },
 	{ INT_PEND0_BASELVL + CC_PEND_B,	0,	"Crosscall B" },
-	{ INT_PEND0_BASELVL + MSC_MESG_INTR,	II_THREADED, "MSC Message" },
-	{ INT_PEND0_BASELVL + CPU_ACTION_A,	0,	"CPU Action A" },
-	{ INT_PEND0_BASELVL + CPU_ACTION_B,	0,	"CPU Action B" },
-	{ INT_PEND1_BASELVL + IO_ERROR_INTR,	II_ERRORINT, "IO Error" },
 	{ 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" },
@@ -1546,13 +1549,11 @@
 	{ 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" },
-#ifdef SN1
 	{ 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" },
-#endif /* SN1 */	
-	{ -1, 0, (char *)NULL}
+	{ -1, 0, (char *)NULL},
 };
 
 /*
@@ -1567,7 +1568,13 @@
 	int i;
 	char subnode_done[NUM_SUBNODES];
 
-	cpu = cnodetocpu(cnode);
+	// 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;
@@ -1576,7 +1583,7 @@
 	for (i=0; i<NUM_SUBNODES; i++)
 		subnode_done[i] = 0;
 
-	for (; cpu<maxcpus && cpu_enabled(cpu) && cputocnode(cpu) == cnode; cpu++) {
+	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;
@@ -1594,7 +1601,6 @@
 	}
 }
 
-#endif /* BRINGUP */
 
 /*
  * Check and clear interrupts.
@@ -1612,7 +1618,7 @@
 		for (i = 0; i < N_INTPEND_BITS; i++) {
 			if (bits & (1 << i)) {
 #ifdef INTRDEBUG
-				printk( "Nasid %d interrupt bit %d set in %s",
+				PRINT_WARNING("Nasid %d interrupt bit %d set in %s",
 					nasid, i, name);
 #endif
 				LOCAL_HUB_CLR_INTR(base_level + i);
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/ml_iograph.c linux/arch/ia64/sn/io/ml_iograph.c
--- v2.4.3/linux/arch/ia64/sn/io/ml_iograph.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/ml_iograph.c	Thu Apr  5 12:51:47 2001
@@ -20,6 +20,7 @@
 #include <asm/sn/labelcl.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/pci/bridge.h>
+#include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/eeprom.h>
 #include <asm/sn/sn_private.h>
@@ -32,6 +33,13 @@
 
 extern int maxnodes;
 
+/* #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 */
@@ -44,7 +52,7 @@
  * xswitch vertex is created.
  */
 typedef struct xswitch_vol_s {
-	struct semaphore xswitch_volunteer_mutex;
+	mutex_t xswitch_volunteer_mutex;
 	int		xswitch_volunteer_count;
 	devfs_handle_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];
 } *xswitch_vol_t;
@@ -56,7 +64,7 @@
 	int rc;
 
 	xvolinfo = kmalloc(sizeof(struct xswitch_vol_s), GFP_KERNEL);
-	init_MUTEX(&xvolinfo->xswitch_volunteer_mutex);
+	mutex_init(&xvolinfo->xswitch_volunteer_mutex);
 	xvolinfo->xswitch_volunteer_count = 0;
 	rc = hwgraph_info_add_LBL(xswitch, 
 			INFO_LBL_XSWITCH_VOL,
@@ -78,7 +86,7 @@
 	rc = hwgraph_info_remove_LBL(xswitch, 
 				INFO_LBL_XSWITCH_VOL,
 				(arbitrary_info_t *)&xvolinfo);
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef LATER
 	ASSERT(rc == GRAPH_SUCCESS); rc = rc;
 #endif
 
@@ -97,64 +105,26 @@
 				INFO_LBL_XSWITCH_VOL, 
 				(arbitrary_info_t *)&xvolinfo);
 	if (xvolinfo == NULL) {
-#ifndef CONFIG_IA64_SGI_IO
-	    if (!is_headless_node_vertex(master))
-		cmn_err(CE_WARN, 
-			"volunteer for widgets: vertex %v has no info label",
+#ifdef LATER
+	    if (!is_headless_node_vertex(master)) {
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+		PRINT_WARNING("volunteer for widgets: vertex %v has no info label",
+			xswitch);
+#else
+		PRINT_WARNING("volunteer for widgets: vertex 0x%x has no info label",
 			xswitch);
 #endif
+	    }
+#endif	/* LATER */
 	    return;
 	}
 
-#ifndef CONFIG_IA64_SGI_IO
-	mutex_lock(&xvolinfo->xswitch_volunteer_mutex, PZERO);
-#endif
+	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++;
-#ifndef CONFIG_IA64_SGI_IO
 	mutex_unlock(&xvolinfo->xswitch_volunteer_mutex);
-#endif
-}
-
-#ifndef	BRINGUP
-/* 
- * The "ideal fixed assignment" of 12 IO slots to 4 node slots.
- * At index N is the node slot number of the node board that should
- * ideally control the widget in IO slot N.  Note that if there is
- * only one node board on a given xbow, it will control all of the
- * devices on that xbow regardless of these defaults.
- *
- * 	N1 controls IO slots IO1, IO3, IO5	(upper left)
- * 	N3 controls IO slots IO2, IO4, IO6	(upper right)
- * 	N2 controls IO slots IO7, IO9, IO11	(lower left)
- * 	N4 controls IO slots IO8, IO10, IO12	(lower right)
- *
- * This makes assignments predictable and easily controllable.
- * TBD: Allow administrator to override these defaults.
- */
-static slotid_t ideal_assignment[] = {
-	-1,	/* IO0 -->non-existent */
-	1,	/* IO1 -->N1 */
-	3,	/* IO2 -->N3 */
-	1,	/* IO3 -->N1 */
-	3,	/* IO4 -->N3 */
-	1,	/* IO5 -->N1 */
-	3,	/* IO6 -->N3 */
-	2,	/* IO7 -->N2 */
-	4,	/* IO8 -->N4 */
-	2,	/* IO9 -->N2 */
-	4,	/* IO10-->N4 */
-	2,	/* IO11-->N2 */
-	4	/* IO12-->N4 */
-};
-
-static int
-is_ideal_assignment(slotid_t hubslot, slotid_t ioslot)
-{
-	return(ideal_assignment[ioslot] == hubslot);
 }
-#endif /* ifndef BRINGUP */
 
 extern int xbow_port_io_enabled(nasid_t nasid, int widgetnum);
 
@@ -166,15 +136,12 @@
 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;
-	xwidgetnum_t widgetnum;
-	int curr_volunteer, num_volunteer;
 	nasid_t nasid;
 	hubinfo_t hubinfo;
-#ifndef BRINGUP
-	int xbownum;
-#endif
 
 	hubinfo_get(hubv, &hubinfo);
 	nasid = hubinfo->h_nasid;
@@ -186,13 +153,19 @@
 				INFO_LBL_XSWITCH_VOL, 
 				(arbitrary_info_t *)&xvolinfo);
 	if (xvolinfo == NULL) {
-#ifndef CONFIG_IA64_SGI_IO
-	    if (!is_headless_node_vertex(hubv))
-		cmn_err(CE_WARN, 
-			"assign_widgets_to_volunteers:vertex %v has "
+#ifdef LATER
+	    if (!is_headless_node_vertex(hubv)) {
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+		PRINT_WARNING("assign_widgets_to_volunteers:vertex %v has "
+			" no info label",
+			xswitch);
+#else
+		PRINT_WARNING("assign_widgets_to_volunteers:vertex 0x%x has "
 			" no info label",
 			xswitch);
 #endif
+	    }
+#endif	/* LATER */
 	    return;
 	}
 
@@ -206,10 +179,6 @@
 		xswitch_info_master_assignment_set(xswitch_info, (xwidgetnum_t)0, hubv);
 	}
 
-#ifndef	BRINGUP
-	xbownum = get_node_crossbow(nasid);
-#endif /* ifndef BRINGUP */
-
 	/*
 	 * TBD: Use administrative information to alter assignment of
 	 * widgets to hubs.
@@ -239,29 +208,12 @@
 				if (nasid == get_console_nasid())
 					goto do_assignment;
 			}
-#ifndef CONFIG_IA64_SGI_IO
-			cmn_err(CE_PANIC,
-				"Nasid == %d, console nasid == %d",
+#ifdef LATER
+			PRINT_PANIC("Nasid == %d, console nasid == %d",
 				nasid, get_console_nasid());
 #endif
 		}
 
-#ifndef	BRINGUP
-		/*
-		 * Try to do the "ideal" assignment if IO slots to nodes.
-		 */
-		for (i=0; i<num_volunteer; i++) {
-			hubv = xvolinfo->xswitch_volunteer[i];
-			hubinfo_get(hubv, &hubinfo);
-			nasid = hubinfo->h_nasid;
-			if (is_ideal_assignment(SLOTNUM_GETSLOT(get_node_slotid(nasid)),
-						SLOTNUM_GETSLOT(get_widget_slotnum(xbownum, widgetnum)))) {
-
-				goto do_assignment;
-				
-			}
-		}
-#endif /* ifndef BRINGUP */
 
 		/*
 		 * Do a round-robin assignment among the volunteer nodes.
@@ -301,13 +253,13 @@
 	for(cnode = 0; cnode < numnodes; cnode++) {
 		nasid = COMPACT_TO_NASID_NODEID(cnode);
 		board = (lboard_t *)KL_CONFIG_INFO(nasid);
-		printk("iograph_early_init: Found board 0x%p\n", board);
+		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);
-			printk("iograph_early_init: Found board 0x%p\n", board);
+			DBG("iograph_early_init: Found board 0x%p\n", board);
 
 
 		}
@@ -316,7 +268,7 @@
 	hubio_init();
 }
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef LATER
 /* There is an identical definition of this in os/scheduler/runq.c */
 #define INIT_COOKIE(cookie) cookie.must_run = 0; cookie.cpu = PDA_RUNANYWHERE
 /*
@@ -363,12 +315,11 @@
 {
 	restoremustrun(cookie);
 }
-static sema_t io_init_sema;
-
-#endif	/* !CONFIG_IA64_SGI_IO */
-
-struct semaphore io_init_sema;
+#endif	/* LATER */
 
+#ifdef LINUX_KERNEL_THREADS
+static struct semaphore io_init_sema;
+#endif
 
 /*
  * Let boot processor know that we're done initializing our node's IO
@@ -378,9 +329,11 @@
 static void
 io_init_done(cnodeid_t cnodeid,cpu_cookie_t c)
 {
-#ifndef CONFIG_IA64_SGI_IO
 	/* 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 
 	 */
@@ -420,17 +373,12 @@
 		 * We're able to read from a widget because our hub's 
 		 * WIDGET_ID was set up earlier.
 		 */
-#ifdef	BRINGUP
 		widgetreg_t widget_id = *(volatile widgetreg_t *)
 			(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
 
-		printk("early_probe_for_widget: Hub Vertex 0x%p is UP widget_id = 0x%x Register 0x%p\n", hubv, 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) );
 
-#else	/* !BRINGUP */
-		widgetreg_t widget_id = XWIDGET_ID_READ(nasid, 0);
-#endif	/* BRINGUP */
-
 		hwid->part_num = XWIDGET_PART_NUM(widget_id);
 		hwid->rev_num = XWIDGET_REV_NUM(widget_id);
 		hwid->mfg_num = XWIDGET_MFG_NUM(widget_id);
@@ -438,8 +386,6 @@
 		/* TBD: link reset */
 	} else {
 
-		panic("\n\n**** early_probe_for_widget: Hub Vertex 0x%p is DOWN llp_csr_reg 0x%x ****\n\n", hubv, llp_csr_reg);
-
 		hwid->part_num = XWIDGET_PART_NUM_NONE;
 		hwid->rev_num = XWIDGET_REV_NUM_NONE;
 		hwid->mfg_num = XWIDGET_MFG_NUM_NONE;
@@ -499,8 +445,9 @@
 	moduleid_t		module;
 	slotid_t		slot;
 	lboard_t		*board = NULL;
+	char			buffer[16];
 	
-	printk("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum);
+	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.
 	 */
@@ -546,8 +493,8 @@
 		 * but I don't feel like figuring out vhdl right now..
 		 * and I know for a fact the answer is 0x2d000049 
 		 */
-		printk("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n");
-		printk("XWIDGET_PART_NUM(0x2d000049)= 0x%x\n", XWIDGET_PART_NUM(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)) {
@@ -557,8 +504,18 @@
 				module,
 				KLTYPE_IOBRICK);
 
-			if (board)
-				printk("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type);
+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;
+			}
+				
+}
 
 			/*
 			 * BRINGUP
@@ -568,11 +525,16 @@
 
 #ifdef SUPPORT_PRINTING_M_FORMAT
 			sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-#else
-			sprintf(pathname, EDGE_LBL_MODULE "/%x/"
-#endif
 				"%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
 #ifdef BRINGUP
 
 				(board->brd_type == KLTYPE_IBRICK) ? 'I' :
@@ -584,7 +546,7 @@
 				EDGE_LBL_XTALK, widgetnum);
 		} 
 		
-		printk("io_xswitch_widget_init: path= %s\n", pathname);
+		DBG("io_xswitch_widget_init: path= %s\n", pathname);
 		rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv);
 		
 		ASSERT(rc == GRAPH_SUCCESS);
@@ -612,7 +574,7 @@
 			module 	= NODEPDA(cnode)->module_id;
 
 #ifdef XBRIDGE_REGS_SIM
-			printk("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n");
+			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)) {
@@ -647,16 +609,21 @@
 			 	 */
 #ifdef SUPPORT_PRINTING_M_FORMAT
 				sprintf(pathname, EDGE_LBL_MODULE "/%M/"
+                                                EDGE_LBL_SLOT "/%s/%s",
+                                        NODEPDA(cnode)->module_id,
+                                        slotname, new_name);
 #else
-				sprintf(pathname, EDGE_LBL_MODULE "/%x/"
-#endif
+				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",
-					NODEPDA(cnode)->module_id,
+					buffer,
 					slotname, new_name);
+#endif
 			}
 
 			rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv);
-			printk("io_xswitch_widget_init: (2) path= %s\n", pathname);
+			DBG("io_xswitch_widget_init: (2) path= %s\n", pathname);
 		        /*
 		         * This is a weird ass code needed for error injection
 		         * purposes.
@@ -666,7 +633,7 @@
 			klhwg_baseio_inventory_add(widgetv,cnode);
 		}
 		sprintf(name, "%d", widgetnum);
-		printk("io_xswitch_widget_init: FIXME hwgraph_edge_add %s xswitchv 0x%p, widgetv 0x%p\n", name, xswitchv, widgetv);
+		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);
 		
 		/*
@@ -683,7 +650,7 @@
 		 */
 #ifdef XBRIDGE_REGS_SIM
 		widget_id = 0x2d000049;
-		printk("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: id hardwired to widget_id\n");
+		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 */
@@ -715,21 +682,13 @@
 
 	aa = async_attach_new();
 	
-	printk("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode);
+	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++) {
-#ifdef BRINGUP
-		if (widgetnum != 0xe) 
-			io_xswitch_widget_init(xswitchv,
-				       cnodeid_to_vertex(cnode),
-				       widgetnum, aa);
-
-#else
 		io_xswitch_widget_init(xswitchv,
 				       cnodeid_to_vertex(cnode),
 				       widgetnum, aa);
-#endif /* BRINGUP */
 	}
 	/* 
 	 * Wait for parallel attach threads, if any, to complete.
@@ -798,9 +757,12 @@
 #endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
 		}
 		if (board == NULL) {
-#ifndef CONFIG_IA64_SGI_IO
-			cmn_err(CE_WARN,
-				"Could not find PROM info for vertex %v, "
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+			PRINT_WARNING("Could not find PROM info for vertex %v, "
+				"FRU analyzer may fail",
+				vhdl);
+#else
+			PRINT_WARNING("Could not find PROM info for vertex 0x%x, "
 				"FRU analyzer may fail",
 				vhdl);
 #endif
@@ -828,16 +790,13 @@
 	hubinfo_t hubinfo;
 	int is_xswitch;
 	nodepda_t	*npdap;
-#ifndef CONFIG_IA64_SGI_IO
-	sema_t 		*peer_sema = 0;
-#else
 	struct semaphore *peer_sema = 0;
-#endif
 	uint32_t	widget_partnum;
 	nodepda_router_info_t *npda_rip;
 	cpu_cookie_t	c = 0;
+	extern int hubdev_docallouts(devfs_handle_t);
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef LATER
 	/* Try to execute on the node that we're initializing. */
 	c = setnoderun(cnodeid);
 #endif
@@ -851,13 +810,11 @@
 	 * form /hw/module/%M/slot/%d/node
 	 */
 	hubv = cnodeid_to_vertex(cnodeid);
-	printk("io_init_node: Initialize IO for cnode %d hubv(node) 0x%p npdap 0x%p\n", cnodeid, hubv, npdap);
+	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);
 
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
 	hubdev_docallouts(hubv);
-#endif
 
 	/*
 	 * Set up the dependent routers if we have any.
@@ -877,10 +834,10 @@
 	/*
 	 * Read mfg info on this hub
 	 */
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef LATER
 	printk("io_init_node: FIXME need to implement HUB_VERTEX_MFG_INFO\n");
 	HUB_VERTEX_MFG_INFO(hubv);
-#endif /* CONFIG_IA64_SGI_IO */
+#endif /* LATER */
 
 	/* 
 	 * If nothing connected to this hub's xtalk port, we're done.
@@ -892,7 +849,7 @@
 			int index;
 
 			for (index = 0; index < 600; index++)
-				printk("Interfering with device probing!!!\n");
+				DBG("Interfering with device probing!!!\n");
 		}
 #endif
 		/* io_init_done takes cpu cookie as 2nd argument 
@@ -900,8 +857,8 @@
 		 * at the start of this thread 
 		 */
 		
-		printk("**** io_init_node: Node's 0x%p hub widget has XWIDGET_PART_NUM_NONE ****\n", hubv);
-		io_init_done(cnodeid,c);
+		DBG("**** io_init_node: Node's 0x%p hub widget has XWIDGET_PART_NUM_NONE ****\n", hubv);
+		return;
 		/* NOTREACHED */
 	}
 
@@ -931,13 +888,13 @@
 
 	(void)hwgraph_path_add(hubv, EDGE_LBL_XTALK, &switchv);
 
-	printk("io_init_node: Created 'xtalk' entry to '../node/' xtalk vertex 0x%p\n", 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);
 
-	printk("io_init_node: Created symlink 'io' from ../node/io to ../node/xtalk \n");
+	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
@@ -951,7 +908,7 @@
 				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);
 
-		printk("io_init_node: Found XBRIDGE widget_partnum= 0x%x\n", widget_partnum);
+		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) {
@@ -959,7 +916,7 @@
 		 * Xbow control register does not have the widget ID field.
 		 * So, hard code the widget ID to be zero.
 		 */
-		printk("io_init_node: Found XBOW widget_partnum= 0x%x\n", widget_partnum);
+		DBG("io_init_node: Found XBOW widget_partnum= 0x%x\n", widget_partnum);
 		npdap->basew_id = 0;
 
 #if defined(BRINGUP)
@@ -982,7 +939,7 @@
 		char widname[10];
 		sprintf(widname, "%x", npdap->basew_id);
 		(void)hwgraph_path_add(switchv, widname, &widgetv);
-		printk("io_init_node: Created '%s' to '..node/xtalk/' vertex 0x%p\n", widname, widgetv);
+		DBG("io_init_node: Created '%s' to '..node/xtalk/' vertex 0x%p\n", widname, widgetv);
 		ASSERT(widgetv != GRAPH_VERTEX_NONE);
 	}
 	
@@ -1043,13 +1000,13 @@
 
 		/* Signal that we're done */
 		if (peer_sema) {
-			up(peer_sema);
+			mutex_unlock(peer_sema);
 		}
 		
 	}
 	else {
 	    /* Wait 'til master is done assigning widgets. */
-	    down(&npdap->xbow_sema);
+	    mutex_lock(&npdap->xbow_sema);
 	}
 
 #ifdef PROBE_TEST
@@ -1057,7 +1014,7 @@
 		int index;
 
 		for (index = 0; index < 500; index++)
-			printk("Interfering with device probing!!!\n");
+			DBG("Interfering with device probing!!!\n");
 	}
 #endif
 	/* Now both nodes can safely inititialize widgets */
@@ -1070,15 +1027,12 @@
 	 */
 	io_init_done(cnodeid,c);
 
-	printk("\nio_init_node: DONE INITIALIZED ALL I/O FOR CNODEID %d\n\n", cnodeid);
+	DBG("\nio_init_node: DONE INITIALIZED ALL I/O FOR CNODEID %d\n\n", cnodeid);
 }
 
 
 #define IOINIT_STKSZ	(16 * 1024)
 
-#ifndef CONFIG_IA64_SGI_IO
-#include <sys/sn/iograph.h>
-#endif
 #define __DEVSTR1 	"/../.master/"
 #define __DEVSTR2 	"/target/"
 #define __DEVSTR3 	"/lun/0/disk/partition/"
@@ -1145,6 +1099,7 @@
 		{"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 */
 	};
 
@@ -1181,11 +1136,7 @@
 }
 
 
-#ifndef CONFIG_IA64_SGI_IO
-#include <sys/asm/sn/ioerror_handling.h>
-#else
 #include <asm/sn/ioerror_handling.h>
-#endif
 extern devfs_handle_t 	ioc3_console_vhdl_get(void);
 devfs_handle_t		sys_critical_graph_root = GRAPH_VERTEX_NONE;
 
@@ -1203,7 +1154,7 @@
 	int			slot;
 	devfs_handle_t		baseio_console_conn;
 
-	printk("sys_critical_graph_init: FIXME.\n");
+	DBG("sys_critical_graph_init: FIXME.\n");
 	baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl);
 
 	if (baseio_console_conn == NULL) {
@@ -1303,7 +1254,7 @@
 	devfs_handle_t		console_vhdl, pci_vhdl, enet_vhdl;
 
 
-	printk("baseio_ctlr_num_set; FIXME\n");
+	DBG("baseio_ctlr_num_set; FIXME\n");
 	console_vhdl = ioc3_console_vhdl_get();
 	if (console_vhdl == GRAPH_VERTEX_NONE)
 		return;
@@ -1384,10 +1335,8 @@
 	else {
 		rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 4,1, 4,0, 0,0, 0,0);
 	}
-#ifndef CONFIG_IA64_SGI_IO
 	if (rtn_val)
-		cmn_err(CE_WARN, "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
-#endif
+		PRINT_WARNING("sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
 
 	if ((vendor_list[5] != PCIIO_VENDOR_ID_NONE) && 
 	    (vendor_list[7] != PCIIO_VENDOR_ID_NONE)) {
@@ -1406,10 +1355,8 @@
 		/* nothing in slot 5 or 7 */
 		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 4,1, 4,0, 0,0, 0,0);
 	}
-#ifndef CONFIG_IA64_SGI_IO
 	if (rtn_val)
-		cmn_err(CE_WARN, "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
-#endif
+		PRINT_WARNING("sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
 }
 
 
@@ -1423,17 +1370,18 @@
 	/* Governor on init threads..bump up when safe 
 	 * (beware many devfs races) 
 	 */
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef LATER
 	int io_init_node_threads = 2;	
 #endif
 	cnodeid_t cnodeid, active;
 
-	init_MUTEX(&io_init_sema);
-
+#ifdef LINUX_KERNEL_THREADS
+	sema_init(&io_init_sema, 0);
+#endif
 
 	active = 0;
 	for (cnodeid = 0; cnodeid < maxnodes; cnodeid++) {
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef LINUX_KERNEL_THREADS
 		char thread_name[16];
 		extern int io_init_pri;
 
@@ -1448,20 +1396,17 @@
 			io_init_pri, KT_PS, (st_func_t *)io_init_node,
 			(void *)(long)cnodeid, 0, 0, 0);
 #else
-                printk("init_all_devices: Calling io_init_node() for cnode %d\n", cnodeid);
+                DBG("init_all_devices: Calling io_init_node() for cnode %d\n", cnodeid);
                 io_init_node(cnodeid);
 
-		printk("init_all_devices: Done io_init_node() for cnode %d\n", cnodeid);
-
-#endif /* !CONFIG_IA64_SGI_IO */
+		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 */
-#ifdef AA_DEBUG
-		printk("started thread for cnode %d\n", cnodeid);
-#endif
-#ifdef LINUX_KERNEL_THREADS
+		DBG("started thread for cnode %d\n", cnodeid);
 		active++;
 		if (io_init_node_threads && 
 			active >= io_init_node_threads) {
@@ -1476,9 +1421,9 @@
 
 	while (active > 0) {
 #ifdef AA_DEBUG
-	    printk("waiting, %d still active\n", active);
+	    DBG("waiting, %d still active\n", active);
 #endif
-	    sema(&io_init_sema);
+	    down(&io_init_sema);
 	    active--;
 	}
 
@@ -1534,22 +1479,22 @@
 		int i;
 		int viable_found = 0;
 
-		printk("Only controller numbers 0..%d  are supported for\n", NUM_BASE_IO_SCSI_CTLR-1);
-		printk("prom \"root\" variables of the form dksXdXsX.\n");
-		printk("To use another disk you must use the full hardware graph path\n\n");
-		printk("Possible controller numbers for use in 'dksXdXsX' on this system: ");
+		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) {
-				printk("%d ", i);
+				DBG("%d ", i);
 				viable_found=1;
 			}
 		}
 		if (viable_found)
-			printk("\n");
+			DBG("\n");
 		else
-			printk("none found!\n");
+			DBG("none found!\n");
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef LATER
 		if (kdebug)
 			debug("ring");
 #endif
@@ -1579,4 +1524,132 @@
 	*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 -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/module.c linux/arch/ia64/sn/io/module.c
--- v2.4.3/linux/arch/ia64/sn/io/module.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/module.c	Thu Apr  5 12:51:47 2001
@@ -15,21 +15,26 @@
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
-#include <asm/sn/cmn_err.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/pci/bridge.h>
+#include <asm/sn/xtalk/xbow.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	
+/* #define LDEBUG	1	*/
 
-#define DPRINTF		if (LDEBUG) printk
+#ifdef LDEBUG
+#define DPRINTF		printk
 #define printf		printk
+#else
+#define DPRINTF(x...)
+#endif
 
 module_t	       *modules[MODULE_MAX];
 int			nummodules;
@@ -100,8 +105,6 @@
 {
     int			i;
 
-    DPRINTF("module_lookup: id=%d\n", id);
-
     for (i = 0; i < nummodules; i++)
 	if (modules[i]->id == id) {
 	    DPRINTF("module_lookup: found m=0x%p\n", modules[i]);
@@ -125,29 +128,29 @@
 {
     module_t	       *m;
     int			i;
+    char		buffer[16];
 
-    DPRINTF("module_add_node: id=%x node=%d\n", id, n);
+#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) {
-#ifndef CONFIG_IA64_SGI_IO
+#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));
-	printk("Module nodecnt = %d\n", m->nodecnt); 
 #endif
 	ASSERT_ALWAYS(m);
 
-	DPRINTF("module_add_node: m=0x%p\n", m);
-
 	m->id = id;
 	spin_lock_init(&m->lock);
 
-	init_MUTEX_LOCKED(&m->thdcnt);
-
-printk("Set elsc to 0x%p on node %d\n", &m->elsc, get_nasid());
+	mutex_init_locked(&m->thdcnt);
 
-set_elsc(&m->elsc);
+// set_elsc(&m->elsc);
 	elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n));
 	spin_lock_init(&m->elsclock);
 
@@ -162,8 +165,7 @@
 
     m->nodes[m->nodecnt++] = n;
 
-printk("module_add_node: module %x now has %d nodes\n", id, m->nodecnt);
-    DPRINTF("module_add_node: module %x now has %d nodes\n", id, m->nodecnt);
+    DPRINTF("module_add_node: module %s now has %d nodes\n", buffer, m->nodecnt);
 
     return m;
 }
@@ -172,6 +174,7 @@
 {
     lboard_t	       *board;
     klmod_serial_num_t *comp;
+    char * bcopy(const char * src, char * dest, int count);
 
     board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid),
 			KLTYPE_MIDPLANE8);
@@ -204,14 +207,8 @@
     if (m->snum_valid)
 	return 1;
     else {
-#ifndef CONFIG_IA64_SGI_IO
-	cmn_err(CE_WARN | CE_MAINTENANCE,
-		"Invalid serial number for module %d, "
+	DPRINTF("Invalid serial number for module %d, "
 		"possible missing or invalid NIC.", m->id);
-#else
-	printk("Invalid serial number for module %d, "
-		"possible missing or invalid NIC.", m->id);
-#endif
 	return 0;
     }
 }
@@ -246,32 +243,12 @@
 	    nserial);
 
     if (nserial == 0)
-	cmn_err(CE_WARN, "No serial number found.");
+	PRINT_WARNING("io_module_init: No serial number found.\n");
 }
 
-#ifdef BRINGUP
-elsc_t *Elsc[100];
-
-void
-set_elsc(elsc_t *p)
-{
-      Elsc[get_nasid()] = p;
-}
-#endif
-
 elsc_t *get_elsc(void)
 {
-#ifdef BRINGUP
-return(Elsc[get_nasid()]);
-#else
-	if ( NODEPDA(get_nasid())->module == (module_t *)0 ) {
-		printf("get_elsc() for nasd %d fails\n", get_nasid());
-//		return((elsc_t *)0);
-	}
-	return &NODEPDA(get_nasid())->module->elsc;
-
-//	return &NODEPDA(NASID_TO_COMPACT_NODEID(0))->module->elsc;
-#endif
+	return &NODEPDA(cpuid_to_cnodeid(smp_processor_id()))->module->elsc;
 }
 
 int
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/pci.c linux/arch/ia64/sn/io/pci.c
--- v2.4.3/linux/arch/ia64/sn/io/pci.c	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/io/pci.c	Thu Apr  5 12:51:47 2001
@@ -14,7 +14,6 @@
 #include <linux/pci.h>
 #include <asm/sn/types.h>
 #include <asm/sn/sgi.h>
-#include <asm/sn/cmn_err.h>
 #include <asm/sn/iobus.h>
 #include <asm/sn/iograph.h>
 #include <asm/param.h>
@@ -250,18 +249,9 @@
 pci_fixup_ioc3(struct pci_dev *d)
 {
         int 		i;
-	int 		slot;
-	unsigned long 	res = 0;
-	unsigned int 	val, size;
-	int 		ret;
-	u_short 	command;
+	unsigned int 	size;
 
-	devfs_handle_t 	device_vertex;
 	devfs_handle_t	bridge_vhdl = pci_bus_to_vertex(d->bus->number);
-	pcibr_soft_t 	pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl);
-	devfs_handle_t  xconn_vhdl = pcibr_soft->bs_conn;
-	bridge_t 	*bridge = pcibr_soft->bs_base;
-	bridgereg_t 	devreg;
 
         /* IOC3 only decodes 0x20 bytes of the config space, reading
 	 * beyond that is relatively benign but writing beyond that
@@ -271,7 +261,7 @@
 	 *       currently we hack this with special code in 
 	 *	 sgi_pci_intr_support()
 	 */
-        printk("pci_fixup_ioc3: Fixing base addresses for ioc3 device %s\n", d->slot_name);
+        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
@@ -296,7 +286,9 @@
 	 * DEV_DIRECT bit.  This will not work if IOC3 is not on Slot 
 	 * 4.
 	 */
-	*(volatile u32 *)0xc0000a000f000220 |= 0x90000;
+	DBG("pci_fixup_ioc3: FIXME .. need to take NASID into account when setting IOC3 devreg 0x%x\n", *(volatile u32 *)0xc0000a000f000220);
+
+ 	*(volatile u32 *)0xc0000a000f000220 |= 0x90000; 
 
         d->subsystem_vendor = 0;
         d->subsystem_device = 0;
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/pci_bus_cvlink.c linux/arch/ia64/sn/io/pci_bus_cvlink.c
--- v2.4.3/linux/arch/ia64/sn/io/pci_bus_cvlink.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/pci_bus_cvlink.c	Thu Apr  5 12:51:47 2001
@@ -11,12 +11,12 @@
 #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/cmn_err.h>
 #include <asm/sn/iobus.h>
 #include <asm/sn/iograph.h>
 #include <asm/param.h>
@@ -31,24 +31,35 @@
 #include <asm/sn/intr.h>
 #include <asm/sn/xtalk/xtalkaddrs.h>
 #include <asm/sn/klconfig.h>
+#include <asm/sn/xtalk/xwidget.h>
 #include <asm/sn/io.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
 
 #include <asm/sn/pci/pciio.h>
 // #include <sys/ql.h>
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/pci/pcibr_private.h>
 extern int bridge_rev_b_data_check_disable;
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pci_bus_cvlink.h>
 
 #define MAX_PCI_XWIDGET 256
-devfs_handle_t busnum_to_xwidget[MAX_PCI_XWIDGET];
+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 SN1_IOPORTS_UNIT 256
+#define MAX_IOPORTS 0xffff
+#define MAX_IOPORTS_CHUNKS (MAX_IOPORTS / SN1_IOPORTS_UNIT)
+struct ioports_to_tlbs_s ioports_to_tlbs[MAX_IOPORTS_CHUNKS];
+unsigned long sn1_allocate_ioports(unsigned long pci_address);
+
+
+
 /*
  * pci_bus_cvlink_init() - To be called once during initialization before 
  *	SGI IO Infrastructure init is called.
@@ -56,9 +67,13 @@
 void
 pci_bus_cvlink_init(void)
 {
-
-	memset(busnum_to_xwidget, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET);
+	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;
 }
 
@@ -70,27 +85,13 @@
 pci_bus_to_vertex(unsigned char busnum)
 {
 
-	devfs_handle_t	xwidget;
 	devfs_handle_t	pci_bus = NULL;
 
 
 	/*
 	 * First get the xwidget vertex.
 	 */
-	xwidget = busnum_to_xwidget[busnum];
-	if (!xwidget)
-		return (NULL);
-
-	/*
-	 * Use devfs to get the pci vertex from xwidget.
-	 */
-	if (hwgraph_traverse(xwidget, EDGE_LBL_PCI, &pci_bus) != GRAPH_SUCCESS) {
-		if (!pci_bus) {
-			printk("pci_bus_to_vertex: Cannot find pci bus for given bus number %d\n", busnum);
-			return (NULL);
-		}
-	}
-
+	pci_bus = busnum_to_pcibr_vhdl[busnum];
 	return(pci_bus);
 }
 
@@ -138,7 +139,6 @@
 
 	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
 		if (!device_vertex) {
-			printk("devfn_to_vertex: Unable to get slot&func %s from pci vertex 0x%p\n", name, pci_bus);
 			return(NULL);
 		}
 	}
@@ -175,6 +175,61 @@
 }
 
 /*
+ * sn1_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 sn1_ioport_num = 0x100; /* Reserve room for Legacy stuff */
+unsigned long
+sn1_allocate_ioports(unsigned long pci_address)
+{
+	
+	unsigned long ioport_index;
+
+	/*
+	 * Just some idiot checking ..
+	 */
+	if ( sn1_ioport_num > 0xffff ) {
+		printk("sn1_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 = sn1_ioport_num / SN1_IOPORTS_UNIT;
+	ioports_to_tlbs[ioport_index].ppn = pci_address;
+	ioports_to_tlbs[ioport_index].p = 1; /* Present Bit */
+	ioports_to_tlbs[ioport_index].ma = 5; /* Memory Attributes */
+	ioports_to_tlbs[ioport_index].a = 0; /* Set Data Access Bit Fault */
+	ioports_to_tlbs[ioport_index].d = 0; /* Dirty Bit */
+	ioports_to_tlbs[ioport_index].pl = 3;/* Privilege Level - All levels can R/W*/
+	ioports_to_tlbs[ioport_index].ar = 2; /* Access Rights - R/W only*/
+	ioports_to_tlbs[ioport_index].ed = 0; /* Exception Deferral Bit */
+	ioports_to_tlbs[ioport_index].ig = 0; /* Ignored */
+
+	printk("sn1_allocate_ioports: ioport_index 0x%x ioports_to_tlbs 0x%p\n", ioport_index, ioports_to_tlbs[ioport_index].ppn);
+	
+	sn1_ioport_num += SN1_IOPORTS_UNIT;
+
+	return(sn1_ioport_num - SN1_IOPORTS_UNIT);
+}
+
+/*
  * sn1_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
@@ -189,6 +244,11 @@
 	struct pci_dev *device_dev = NULL;
 	struct sn1_widget_sysdata *widget_sysdata;
 	struct sn1_device_sysdata *device_sysdata;
+	unsigned long ioport;
+	pciio_intr_t intr_handle;
+	int cpuid, bit;
+	devfs_handle_t *device_vertex;
+	pciio_intr_line_t lines;
 	extern void sn1_pci_find_bios(void);
 
 
@@ -204,7 +264,6 @@
         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("Before Changing PIO Map Address:\n");
         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);
@@ -280,16 +339,11 @@
 			size = device_dev->resource[idx].end -
 				device_dev->resource[idx].start;
 			if (size) {
-res = 0;
-res = pciio_config_get(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + idx, 4);
-printk("Before pciio_pio_addr Base address %d = 0x%lx\n", idx, res);
-
-				printk(" Changing device %d:%d resource start address from 0x%lx", 
-				PCI_SLOT(device_dev->devfn),PCI_FUNC(device_dev->devfn),
-				device_dev->resource[idx].start);
-				device_dev->resource[idx].start = 
-				(unsigned long)pciio_pio_addr(vhdl, 0, 
-					PCIIO_SPACE_WIN(idx), 0, size, 0, PCIIO_BYTE_STREAM);
+				res = 0;
+				res = pciio_config_get(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + idx, 4);
+				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, PCIIO_BYTE_STREAM);
+
+/* printk("sn1_pci_fixup: Mapped Address = 0x%p size = 0x%x\n", device_dev->resource[idx].start, size); */
 			}
 			else
 				continue;
@@ -304,13 +358,14 @@
 				device_dev->resource[idx].start & 0xfffff7ffffffffff;
 			device_dev->resource[idx].end = 
 				device_dev->resource[idx].end & 0xfffff7ffffffffff;
-			printk(" to 0x%lx\n", device_dev->resource[idx].start);
-res = 0;
-res = pciio_config_get(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + idx, 4);
-printk("After pciio_pio_addr Base address %d = 0x%lx\n", idx, res);
-
-			if (device_dev->resource[idx].flags & IORESOURCE_IO)
+			res = 0;
+			res = pciio_config_get(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + idx, 4);
+			if (device_dev->resource[idx].flags & IORESOURCE_IO) {
 				cmd |= PCI_COMMAND_IO;
+				ioport = sn1_allocate_ioports(device_dev->resource[idx].start);
+				/* device_dev->resource[idx].start = ioport; */
+				/* device_dev->resource[idx].end = ioport + SN1_IOPORTS_UNIT */
+			}
 			else if (device_dev->resource[idx].flags & IORESOURCE_MEM)
 				cmd |= PCI_COMMAND_MEMORY;
 		}
@@ -319,9 +374,6 @@
 		 */
 		size = device_dev->resource[PCI_ROM_RESOURCE].end -
 			device_dev->resource[PCI_ROM_RESOURCE].start;
-		printk(" Changing device %d:%d ROM resource start address from 0x%lx", 
-			PCI_SLOT(device_dev->devfn),PCI_FUNC(device_dev->devfn),
-			device_dev->resource[PCI_ROM_RESOURCE].start);
 		device_dev->resource[PCI_ROM_RESOURCE].start =
 			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
 				size, 0, PCIIO_BYTE_STREAM);
@@ -341,24 +393,26 @@
 					   /* bit gets dropped .. no harm */
 		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
 
-		printk("  to 0x%lx\n", device_dev->resource[PCI_ROM_RESOURCE].start);
+		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, &lines);
+#ifdef BRINGUP
+		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
+			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
+				lines = 1;
+		}
 
-		/*
-		 * Set the irq correctly.
-		 * Bits 7:3 = slot
-		 * Bits 2:0 = function
-		 *
-		 * In the IRQ we will have:
-		 *	Bits 24:16 = bus number
-		 *	Bits 15:8 = slot|func number
-		 */
-		irq = 0;
-		irq = (irq | (device_dev->devfn << 8));
-		irq = (irq | ( (device_dev->bus->number & 0xff) << 16) );
+#endif
+ 
+		device_sysdata = (struct sn1_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, NULL, NULL, NULL);
 		device_dev->irq = irq;
-printk("sn1_pci_fixup: slot= %d  fn= %d  vendor= 0x%x  device= 0x%x  irq= 0x%x\n",
-PCI_SLOT(device_dev->devfn),PCI_FUNC(device_dev->devfn),device_dev->vendor,
-device_dev->device, device_dev->irq);
 
 	}
 #endif	/* REAL_HARDWARE */
@@ -369,7 +423,6 @@
         pcibr_soft_t    pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl);
         bridge_t        *bridge = pcibr_soft->bs_base;
 
-printk("After Changing PIO Map Address:\n");
         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);
@@ -386,6 +439,25 @@
 
 /*
  * 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)
@@ -402,10 +474,21 @@
 	/*
 	 * Loop throught this vertex and get the Xwidgets ..
 	 */
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
+	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
+        {
+                int pos;
+                char dname[256];
+                pos = devfs_generate_path(xtalk, dname, 256);
+                printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
+        }
+
 		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)
@@ -425,25 +508,35 @@
 		 * Should not be any race here ...
 		 */
 		num_bridges++;
-		busnum_to_xwidget[num_bridges - 1] = xwidget;
+		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(" **** pci_bus_map_create: Unable to get .master for vertex 0x%p **** \n", xwidget);
+			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", xwidget);
 		}
 	
 		hubinfo_get(master_node_vertex, &hubinfo);
 		if (!hubinfo) {
-			printk(" **** pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p ****\n", master_node_vertex);
+			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", master_node_vertex);
 			return(1);
 		} else {
 			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
 		}
 
-		printk("pci_bus_map_create: Found Hub nasid %d PCI Xwidget 0x%p  widgetnum= %d\n", hubinfo->h_nasid, xwidget, widgetnum);
+		/*
+		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
+		 */
+		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
+			sizeof(struct sn1_dma_maps_s) * 512, GFP_KERNEL);
+		if (!busnum_to_atedmamaps[num_bridges - 1])
+			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, xwidget);
+
+		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
+			sizeof(struct sn1_dma_maps_s) * 512);
+
 	}
 
         return(0);
@@ -468,6 +561,9 @@
 	graph_vertex_place_t placeptr = EDGE_PLACE_WANT_REAL_EDGES;
 	int rv = 0;
 	char name[256];
+	int master_iobrick;
+	moduleid_t iobrick_id;
+	int i;
 
 	/*
 	 * Iterate throught each xtalk links in the system ..
@@ -480,42 +576,48 @@
 	devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module");
 
 	/*
-	 * Loop throught this directory "/devfs/hw/module/" and get each 
-	 * of it's entry.
-	 */
-	while (1) {
-	
-		/* Get vertex of component /dev/hw/<module_number> */
-		memset((char *)name, '0', 256);
-		module_comp = NULL;
-		rv = hwgraph_edge_get_next(devfs_hdl, (char *)name, &module_comp, (uint *)&placeptr);
-		if ((rv == 0) && (module_comp)) {
-			/* Found a valid entry */
-			node = NULL;
-			rv = hwgraph_edge_get(module_comp, "node", &node);
-
-		} else {
-			printk("pci_bus_to_hcl_cvlink: No more Module Component.\n");
-			return(0);
+	 * 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;
+			}
 		}
+	}
 
-		if ( (rv != 0) || (!node) ){
-			printk("pci_bus_to_hcl_cvlink: Module Component does not have node vertex.\n");
-			continue;
-		} else {
-			xtalk = NULL;
-			rv = hwgraph_edge_get(node, "xtalk", &xtalk);
-			if ( (rv != 0) || (xtalk == NULL) ){
-				printk("pci_bus_to_hcl_cvlink: Node has no xtalk vertex.\n");
-				continue;
-			}
+	/*
+	 * 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. */
 		}
 
-		printk("pci_bus_to_hcl_cvlink: Found Module %s node vertex = 0x%p xtalk vertex = 0x%p\n", name, node, xtalk);
-		/*
-		 * Call routine to get the existing PCI Xwidget and create
-		 * the convenience link from "/devfs/hw/pci_bus/.."
-		 */
+		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);
 	}
 
@@ -539,10 +641,8 @@
 	struct sn1_widget_sysdata *widget_sysdata;
 	struct sn1_device_sysdata *device_sysdata;
 
-	printk("sgi_pci_intr_support: Called with requested_irq 0x%x\n", requested_irq);
-
 	if (!dev_desc || !bus_vertex || !device_vertex) {
-		printk("sgi_pci_intr_support: Invalid parameter dev_desc 0x%p, bus_vertex 0x%p, device_vertex 0x%p\n", dev_desc, bus_vertex, device_vertex);
+		printk("WARNING: sgi_pci_intr_support: Invalid parameter dev_desc 0x%p, bus_vertex 0x%p, device_vertex 0x%p\n", dev_desc, bus_vertex, device_vertex);
 		return(-1);
 	}
 
@@ -577,15 +677,11 @@
 	if (pci_dev->vendor == PCI_VENDOR_ID_SGI &&
 	    pci_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
 		*lines = 1;
-		printk("%s : IOC3 HACK: lines= %d\n", __FUNCTION__, *lines);
 	}
 #endif /* BRINGUP */
 
 	/* Not supported currently */
 	*dev_desc = NULL;
-
-	printk("sgi_pci_intr_support: Device Descriptor 0x%p, Bus Vertex 0x%p, Interrupt Pins 0x%x, Device Vertex 0x%p\n", *dev_desc, *bus_vertex, *lines, *device_vertex);
-
 	return(0);
 
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/pci_dma.c linux/arch/ia64/sn/io/pci_dma.c
--- v2.4.3/linux/arch/ia64/sn/io/pci_dma.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/pci_dma.c	Thu Apr  5 12:51:47 2001
@@ -21,9 +21,6 @@
 #ifndef _LANGUAGE_C
 #define _LANGUAGE_C 99
 #endif
-#ifndef CONFIG_IA64_SGI_IO
-#define CONFIG_IA64_SGI_IO 99
-#endif
 
 #include <asm/io.h>
 #include <asm/sn/sgi.h>
@@ -32,9 +29,14 @@
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/pci/pcibr_private.h>
 #include <asm/sn/iobus.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
 #include <asm/sn/types.h>
+#include <asm/sn/sgi.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/alenlist.h>
+#include <asm/sn/pci/pci_bus_cvlink.h>
 
 /*
  * this is REALLY ugly, blame it on gcc's lame inlining that we
@@ -43,13 +45,69 @@
 #if LANGUAGE_C == 99
 #undef LANGUAGE_C
 #endif
-#if _LANGUAGE_C == 99
-#undef _LANGUAGE_C
-#endif
 #if CONFIG_IA64_SGI_IO == 99
 #undef CONFIG_IA64_SGI_IO
 #endif
 
+pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t);
+struct sn1_dma_maps_s *find_sn1_dma_map(dma_addr_t, unsigned char);
+extern devfs_handle_t busnum_to_pcibr_vhdl[];
+extern nasid_t busnum_to_nid[];
+extern void * busnum_to_atedmamaps[];
+
+/*
+ * Get a free pciio_dmamap_t entry.
+ */
+pciio_dmamap_t
+get_free_pciio_dmamap(devfs_handle_t pci_bus)
+{
+	int i;
+	struct sn1_dma_maps_s *sn1_dma_map = NULL;
+
+	/*
+	 * Darn, we need to get the maps allocated for this bus.
+	 */
+	for (i=0; i<512; i++) {
+		if (busnum_to_pcibr_vhdl[i] == pci_bus) {
+			sn1_dma_map = busnum_to_atedmamaps[i];
+		}
+	}
+
+	/*
+	 * Now get a free dmamap entry from this list.
+	 */
+	for (i=0; i<512; i++, sn1_dma_map++) {
+		if (!sn1_dma_map->dma_addr) {
+			sn1_dma_map->dma_addr = -1;
+			return( (pciio_dmamap_t) sn1_dma_map );
+		}
+	}
+
+printk("get_pciio_dmamap: Unable to find a free dmamap\n");
+	return(NULL);
+
+}
+
+struct sn1_dma_maps_s *
+find_sn1_dma_map(dma_addr_t dma_addr, unsigned char busnum)
+{
+
+	struct sn1_dma_maps_s *sn1_dma_map = NULL;
+	int i;
+
+	sn1_dma_map = busnum_to_atedmamaps[busnum];
+
+	for (i=0; i<512; i++, sn1_dma_map++) {
+		if (sn1_dma_map->dma_addr == dma_addr) {
+			return( sn1_dma_map );
+		}
+	}
+
+printk("find_pciio_dmamap: Unable find the corresponding dma map\n");
+	return(NULL);
+
+}
+
 /*
  * sn1 platform specific pci_alloc_consistent()
  *
@@ -74,7 +132,7 @@
 	device_sysdata = (struct sn1_device_sysdata *) hwdev->sysdata;
 	vhdl = device_sysdata->vhdl;
 
-        if ( ret = (void *)__get_free_pages(gfp, get_order(size)) ) {
+        if ( (ret = (void *)__get_free_pages(gfp, get_order(size))) ) {
 		memset(ret, 0, size);
 	} else {
 		return(NULL);
@@ -142,6 +200,8 @@
 	dma_addr_t dma_addr;
 	paddr_t temp_ptr;
 	struct sn1_device_sysdata *device_sysdata;
+	pciio_dmamap_t dma_map;
+
 
 
 	if (direction == PCI_DMA_NONE)
@@ -153,7 +213,7 @@
 	device_sysdata = (struct sn1_device_sysdata *) hwdev->sysdata;
 	vhdl = device_sysdata->vhdl;
 	for (i = 0; i < nents; i++, sg++) {
-		sg->orig_address = sg->address;
+		sg->orig_address = (char *)NULL;
 		dma_addr = 0;
 		temp_ptr = (paddr_t) __pa(sg->address);
 
@@ -166,7 +226,6 @@
 				PCIBR_BARRIER | PCIIO_BYTE_STREAM |
 				PCIIO_DMA_CMD | PCIIO_DMA_A64 );
 			sg->address = (char *)dma_addr;
-/* printk("pci_map_sg: 64Bits hwdev %p DMA Address 0x%p alt_address 0x%p orig_address 0x%p length 0x%x\n", hwdev, sg->address, sg->alt_address, sg->orig_address, sg->length); */
 			continue;
 		}
 
@@ -180,17 +239,28 @@
 				PCIIO_DMA_CMD);
 			if (dma_addr) {
 				sg->address = (char *)dma_addr;
-/* printk("pci_map_single: 32Bit direct pciio_dmatrans_addr pcidev %p returns dma_addr 0x%lx\n", hwdev, dma_addr); */
 				continue;
-			} else {
-				/*
-				 * We need to map this request by using ATEs.
-				 */
-				printk("pci_map_single: 32Bits DMA Page Map support not available yet!");
-				BUG();
-
 			}
+
+		}
+
+		/*
+		 * It is a 32bit card and we cannot do Direct mapping.
+		 * Let's 32Bit Page map the request.
+		 */
+		dma_map = NULL;
+		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length, 
+				PCIBR_BARRIER | PCIIO_BYTE_STREAM |
+				PCIIO_DMA_CMD);
+		if (!dma_map) {
+			printk("pci_map_sg: Unable to allocate anymore 32Bits Page Map entries.\n");
+			BUG();
 		}
+		dma_addr = (dma_addr_t)pciio_dmamap_addr(dma_map, temp_ptr, sg->length);
+		/* printk("pci_map_sg: dma_map 0x%p Phys Addr 0x%p dma_addr 0x%p\n", dma_map, temp_ptr, dma_addr); */
+		sg->address = (char *)dma_addr;
+		sg->orig_address = (char *)dma_map;
+		
 	}
 
 	return nents;
@@ -206,13 +276,25 @@
 sn1_pci_unmap_sg (struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction)
 {
 	int i;
+	struct sn1_dma_maps_s *sn1_dma_map;
+
 
 	if (direction == PCI_DMA_NONE)
 		BUG();
+
 	for (i = 0; i < nelems; i++, sg++)
-		if (sg->orig_address != sg->address) {
+		if (sg->orig_address) {
+			/*
+			 * We maintain the DMA Map pointer in sg->orig_address if 
+			 * it is ever allocated.
+			 */
 			/* phys_to_virt((dma_addr_t)sg->address | ~0x80000000); */
-			sg->address = sg->orig_address;
+			/* sg->address = sg->orig_address; */
+			sg->address = (char *)-1;
+			sn1_dma_map = (struct sn1_dma_maps_s *)sg->orig_address;
+			pciio_dmamap_done((pciio_dmamap_t)sn1_dma_map);
+			pciio_dmamap_free((pciio_dmamap_t)sn1_dma_map);
+			sn1_dma_map->dma_addr = 0;
 			sg->orig_address = 0;
 		}
 }
@@ -234,24 +316,20 @@
 	dma_addr_t dma_addr;
 	paddr_t temp_ptr;
 	struct sn1_device_sysdata *device_sysdata;
+	pciio_dmamap_t dma_map = NULL;
+	struct sn1_dma_maps_s *sn1_dma_map;
 
 
 	if (direction == PCI_DMA_NONE)
 		BUG();
 
-	if (IS_PCI32L(hwdev)) {
-		/*
-		 * SNIA64 cannot support DMA Addresses smaller than 32 bits.
-		 */
-		return ((dma_addr_t) NULL);
-	}
 
 	/*
 	 * find vertex for the device
 	 */
 	device_sysdata = (struct sn1_device_sysdata *)hwdev->sysdata;
 	vhdl = device_sysdata->vhdl;
-/* printk("pci_map_single: Called vhdl = 0x%p ptr = 0x%p size = %d\n", vhdl, ptr, size); */
+
 	/*
 	 * Call our dmamap interface
 	 */
@@ -266,7 +344,6 @@
 			temp_ptr, size,
 			PCIBR_BARRIER | PCIIO_BYTE_STREAM | PCIIO_DMA_CMD
 			| PCIIO_DMA_A64 );
-/* printk("pci_map_single: 64Bit pciio_dmatrans_addr pcidev %p returns dma_addr 0x%lx\n", hwdev, dma_addr); */
 		return (dma_addr);
 	}
 
@@ -281,14 +358,7 @@
 			temp_ptr, size,
 			PCIBR_BARRIER | PCIIO_BYTE_STREAM | PCIIO_DMA_CMD);
 		if (dma_addr) {
-/* printk("pci_map_single: 32Bit direct pciio_dmatrans_addr pcidev %p returns dma_addr 0x%lx\n", hwdev, dma_addr); */
 			return (dma_addr);
-		} else {
-			/*
-			 * We need to map this request by using ATEs.
-			 */
-			printk("pci_map_single: 32Bits DMA Page Map support not available yet!");
-			BUG();
 		}
 	}
 
@@ -297,23 +367,56 @@
 		 * SNIA64 cannot support DMA Addresses smaller than 32 bits.
 		 */
 		return ((dma_addr_t) NULL);
+        }
+
+	/*
+	 * It is a 32bit card and we cannot do Direct mapping.
+	 * Let's 32Bit Page map the request.
+	 */
+	dma_map = NULL;
+	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, PCIBR_BARRIER | 
+			PCIIO_BYTE_STREAM | PCIIO_DMA_CMD);
+	if (!dma_map) {
+		printk("pci_map_single: Unable to allocate anymore 32Bits Page Map entries.\n");
+		BUG();
 	}
 
-	return ((dma_addr_t) NULL);
+	dma_addr = (dma_addr_t) pciio_dmamap_addr(dma_map, temp_ptr, size);
+	/* printk("pci_map_single: dma_map 0x%p Phys Addr 0x%p dma_addr 0x%p\n", dma_map, 
+		temp_ptr, dma_addr); */
+	sn1_dma_map = (struct sn1_dma_maps_s *)dma_map;
+	sn1_dma_map->dma_addr = dma_addr;
 
+	return ((dma_addr_t)dma_addr);
 }
 
 void
 sn1_pci_unmap_single (struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
 {
+
+	struct sn1_dma_maps_s *sn1_dma_map = NULL;
+
         if (direction == PCI_DMA_NONE)
-                BUG();
-        /* Nothing to do */
+		BUG();
+
+	/*
+	 * Get the sn1_dma_map entry.
+	 */
+	if (IS_PCI32_MAPPED(dma_addr))
+		sn1_dma_map = find_sn1_dma_map(dma_addr, hwdev->bus->number);
+
+	if (sn1_dma_map) {
+		pciio_dmamap_done((pciio_dmamap_t)sn1_dma_map);
+		pciio_dmamap_free((pciio_dmamap_t)sn1_dma_map);
+		sn1_dma_map->dma_addr = (dma_addr_t)NULL;
+	}
+
 }
 
 void
 sn1_pci_dma_sync_single (struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
 {
+	
         if (direction == PCI_DMA_NONE)
                 BUG();
         /* Nothing to do */
@@ -330,5 +433,5 @@
 unsigned long
 sn1_dma_address (struct scatterlist *sg)
 {
-	return (sg->address);
+	return ((unsigned long)sg->address);
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/pciba.c linux/arch/ia64/sn/io/pciba.c
--- v2.4.3/linux/arch/ia64/sn/io/pciba.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ia64/sn/io/pciba.c	Thu Apr  5 12:51:47 2001
@@ -0,0 +1,1718 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2000 by Colin Ngam
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/pci/bridge.h>
+#include <asm/sn/prio.h>
+#include <asm/sn/ioerror_handling.h>
+#include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/eeprom.h>
+#include <asm/sn/sn1/bedrock.h>
+#include <asm/sn/sn_private.h>
+#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
+#include <asm/sn/sn1/hubio.h>
+#include <asm/sn/sn1/hubio_next.h>
+#endif
+
+#define copyin(_a, _b, _c)	copy_from_user(_b, _a, _c)
+
+#ifndef	DEBUG_PCIBA
+#define	DEBUG_PCIBA		0
+#endif
+
+/* v_mapphys does not percolate page offset back. */
+#define	PCIBA_ALIGN_CHECK	1
+
+#include <asm/sn/pci/pciba.h>
+
+/* grab an unused space code for "User DMA" space */
+#ifndef	PCIBA_SPACE_UDMA
+#define	PCIBA_SPACE_UDMA	(14)
+#endif
+
+#if DEBUG_REFCT
+extern int		hwgraph_vertex_refct(vertex_hdl_t);
+#endif
+extern int		pci_user_dma_max_pages;
+
+#define NEW(ptr)	(ptr = kmem_zalloc(sizeof (*(ptr)), KM_SLEEP))
+#define DEL(ptr)	(kfree(ptr))
+
+/* Oops -- no standard "pci address" type! */
+typedef uint64_t        pciaddr_t;
+
+/* ================================================================
+ *            driver types
+ */
+typedef struct pciba_slot_s *pciba_slot_t;
+typedef struct pciba_comm_s *pciba_comm_t;
+typedef struct pciba_soft_s *pciba_soft_t;
+typedef struct pciba_map_s *pciba_map_t, **pciba_map_h;
+typedef struct pciba_dma_s *pciba_dma_t, **pciba_dma_h;
+typedef struct pciba_bus_s *pciba_bus_t;
+
+#define	TRACKED_SPACES	16
+struct pciba_comm_s {
+    devfs_handle_t	    conn;
+    pciba_bus_t             bus;
+    int			    refct;
+    pciba_soft_t	    soft[TRACKED_SPACES][2];
+    struct semaphore        lock;
+    pciba_dma_t             dmap;
+};
+
+/* pciba_soft: device_info() for all openables */
+struct pciba_soft_s {
+    pciba_comm_t	    comm;
+    devfs_handle_t          vhdl;
+    int			    refct;
+    pciio_space_t           space;
+    size_t                  size;
+    pciio_space_t           iomem;
+    pciaddr_t               base;
+    unsigned		    flags;
+};
+
+#define	pciba_soft_get(v)	(pciba_soft_t)hwgraph_fastinfo_get(v)
+#define	pciba_soft_set(v,i)	hwgraph_fastinfo_set(v,(arbitrary_info_t)(i))
+
+#define	pciba_soft_lock(soft)	down(&soft->comm->lock)
+#define	pciba_soft_unlock(soft)	up(&soft->comm->lock)
+
+/* pciba_map: data describing a mapping.
+ * (ie. a user mmap request)
+ */
+struct pciba_map_s {
+    pciba_map_t             next;
+#ifdef LATER
+    uthread_t              *uthread;
+#endif
+    __psunsigned_t          handle;
+    uvaddr_t                uvaddr;
+    size_t                  size;
+    pciio_piomap_t          map;
+    pciio_space_t           space;
+    pciaddr_t               base;
+    unsigned		    flags;
+};
+
+/* pciba_dma: data describing a DMA mapping.
+ */
+struct pciba_dma_s {
+    pciba_dma_t             next;
+    iopaddr_t               paddr;	/* starting phys addr */
+    caddr_t                 kaddr;	/* starting kern addr */
+    pciio_dmamap_t          map;	/* mapping resources (ugh!) */
+    pciaddr_t               daddr;	/* starting pci addr */
+    size_t                  pages;	/* size of block in pages */
+    size_t                  bytes;	/* size of block in bytes */
+    __psunsigned_t          handle;	/* mapping handle */
+};
+
+/* pciba_bus: common bus info for all openables
+ * descended from the same master vertex.
+ */
+struct pciba_bus_s {
+    struct semaphore        lock;
+    pciba_map_t             maps;	/* stack of mappings */
+    int			    refct;
+};
+
+#define	pciba_bus_lock(bus)	down(&bus->lock)
+#define	pciba_bus_unlock(bus)	up(&bus->lock)
+
+typedef union ioctl_arg_buffer_u {
+    char                    data[IOCPARM_MASK + 1];
+    uint8_t                 uc;
+    uint16_t                us;
+    uint32_t                ui;
+    uint64_t                ud;
+    caddr_t                 ca;
+#if ULI
+    struct uliargs          uli;
+    struct uliargs32	    uli32;
+#endif
+} ioctl_arg_buffer_t;
+
+/* ================================================================
+ *            driver variables
+ */
+char                   *pciba_mversion = "mload version 7.0";
+int                     pciba_devflag = 0x1 |
+                                        0x200 |
+                                        0x400;
+
+/* this counts the reasons why we can not
+ * currently unload this driver.
+ */
+atomic_t                pciba_prevent_unload = ATOMIC_INIT(0);
+
+#if DEBUG_PCIBA
+static struct reg_values space_v[] =
+{
+    {PCIIO_SPACE_NONE, "none"},
+    {PCIIO_SPACE_ROM, "ROM"},
+    {PCIIO_SPACE_IO, "I/O"},
+    {PCIIO_SPACE_MEM, "MEM"},
+    {PCIIO_SPACE_MEM32, "MEM(32)"},
+    {PCIIO_SPACE_MEM64, "MEM(64)"},
+    {PCIIO_SPACE_CFG, "CFG"},
+    {PCIIO_SPACE_WIN(0), "WIN(0)"},
+    {PCIIO_SPACE_WIN(1), "WIN(1)"},
+    {PCIIO_SPACE_WIN(2), "WIN(2)"},
+    {PCIIO_SPACE_WIN(3), "WIN(3)"},
+    {PCIIO_SPACE_WIN(4), "WIN(4)"},
+    {PCIIO_SPACE_WIN(5), "WIN(5)"},
+    {PCIBA_SPACE_UDMA, "UDMA"},
+    {PCIIO_SPACE_BAD, "BAD"},
+    {0}
+};
+
+static struct reg_desc  space_desc[] =
+{
+    {0xFF, 0, "space", 0, space_v},
+    {0}
+};
+#endif
+
+char                    pciba_edge_lbl_base[] = "base";
+char                    pciba_edge_lbl_cfg[] = "config";
+char                    pciba_edge_lbl_dma[] = "dma";
+char                    pciba_edge_lbl_intr[] = "intr";
+char                    pciba_edge_lbl_io[] = "io";
+char                    pciba_edge_lbl_mem[] = "mem";
+char                    pciba_edge_lbl_rom[] = "rom";
+char                   *pciba_edge_lbl_win[6] =
+{"0", "1", "2", "3", "4", "5"};
+
+#define	PCIBA_EDGE_LBL_BASE	pciba_edge_lbl_base
+#define	PCIBA_EDGE_LBL_CFG	pciba_edge_lbl_cfg
+#define	PCIBA_EDGE_LBL_DMA	pciba_edge_lbl_dma
+#define	PCIBA_EDGE_LBL_INTR	pciba_edge_lbl_intr
+#define	PCIBA_EDGE_LBL_IO	pciba_edge_lbl_io
+#define	PCIBA_EDGE_LBL_MEM	pciba_edge_lbl_mem
+#define	PCIBA_EDGE_LBL_ROM	pciba_edge_lbl_rom
+#define	PCIBA_EDGE_LBL_WIN(n)	pciba_edge_lbl_win[n]
+
+#define	PCIBA_EDGE_LBL_FLIP	pciba_edge_lbl_flip
+
+static char             pciba_info_lbl_bus[] = "pciba_bus";
+
+#define	PCIBA_INFO_LBL_BUS	pciba_info_lbl_bus
+
+struct file_operations pciba_fops = {
+	owner:	THIS_MODULE,
+	llseek: NULL,
+	read: NULL,
+	write: NULL,
+	readdir: NULL,
+	poll: NULL,
+	ioctl: NULL,
+	mmap: NULL,
+	open: NULL,
+	flush: NULL,
+	release: NULL,
+	fsync: NULL,
+	fasync: NULL,
+	lock: NULL,
+	readv: NULL,
+	writev: NULL
+};
+	
+/* ================================================================
+ *            function table of contents
+ */
+
+void                    pciba_init(void);
+int                     pciba_attach(devfs_handle_t);
+
+static void		pciba_sub_attach(pciba_comm_t,
+					 pciio_space_t, pciio_space_t, pciaddr_t,
+					 devfs_handle_t, devfs_handle_t, char *);
+
+static pciba_bus_t      pciba_find_bus(devfs_handle_t, int);
+#ifdef LATER
+static void             pciba_map_push(pciba_bus_t, pciba_map_t);
+static pciba_map_t      pciba_map_pop_hdl(pciba_bus_t, __psunsigned_t);
+static void             pciba_sub_detach(devfs_handle_t, char *);
+static pciio_iter_f     pciba_unload_me;
+#endif
+
+int                     pciba_unload(void);
+int                     pciba_unreg(void);
+int                     pciba_detach(devfs_handle_t);
+
+int                     pciba_open(dev_t *, int, int, struct cred *);
+int                     pciba_close(dev_t);
+int                     pciba_read(dev_t, cred_t *);
+int                     pciba_write(dev_t, cred_t *);
+int                     pciba_ioctl(dev_t, int, void *, int, cred_t *, int *);
+
+int                     pciba_map(dev_t, vhandl_t *, off_t, size_t, uint32_t);
+int                     pciba_unmap(dev_t, vhandl_t *);
+
+#if ULI
+void                    pciba_clearuli(struct uli *);
+static intr_func_f      pciba_intr;
+#endif /* Undef as it gets implemented */
+
+/* ================================================================
+ *            driver load, register, and setup
+ */
+void
+pciba_init(void)
+{
+
+	/*
+	 * What do we need to do here?
+	 */
+#if DEBUG_PCIBA
+    printk("pciba_init()\n");
+#endif
+}
+
+#ifdef LATER
+#if HWG_PERF_CHECK && IP30 && !DEBUG
+void
+pciba_timeout(void *arg1, void *arg2)
+{
+    struct semaphore       *semap = (sema_t *) arg1;
+    unsigned long          *cvalp = (unsigned long *) arg2;
+
+    if (cvalp)
+	cvalp[0] = RAW_COUNT();
+    if (semap)
+	up(semap);
+}
+
+volatile unsigned long  cNval[1];
+struct semaphore        tsema;
+
+void
+pciba_timeout_test(void)
+{
+    unsigned long           c0val, cval;
+    toid_t                  tid;
+
+    extern void             hwg_hprint(unsigned long, char *);
+
+    sema_init(&tsema, 0);
+
+    cNval[0] = 0;
+    c0val = RAW_COUNT();
+    tid = timeout((void (*)()) pciba_timeout, (void *) 0, 1, (void *) cNval);
+    DELAY(1000000);
+    cval = cNval[0];
+    if (cval == 0) {
+	untimeout(tid);
+	PRINT_ALERT("pciba: one-tick timeout did not happen in a second\n");
+	return;
+    }
+    cval = cval - c0val;
+    hwg_hprint(cval, "timeout(1)");
+
+    cNval[0] = 0;
+    c0val = RAW_COUNT();
+    tid = timeout((void (*)()) pciba_timeout, (void *) &tsema, 2, (void *) cNval);
+
+    /* FIXME : this probably needs to be down_interruptible() */
+
+    if (down(&tsema) < 0) {	/* wait for the pciba_timeout */
+	untimeout(tid);
+	PRINT_WARNING("pciba: timeout(2) time check aborted\n");
+	return;
+    }
+    cval = cNval[0];
+    if (cval == 0) {
+	untimeout(tid);
+	PRINT_WARNING("pciba: timeout(2) time not logged\n");
+	return;
+    }
+    cval = cval - c0val;
+    hwg_hprint(cval, "timeout(2)");
+
+    cNval[0] = 0;
+    c0val = RAW_COUNT();
+    tid = timeout((void (*)()) pciba_timeout, (void *) &tsema, HZ, (void *) cNval);
+
+    /* FIXME : this probably needs to be down_interruptible() */
+
+    if (down(&tsema) < 0) {	/* wait for the pciba_timeout */
+	untimeout(tid);
+	PRINT_WARNING("pciba: timeout(HZ) time check aborted\n");
+	return;
+    }
+    cval = cNval[0];
+    if (cval == 0) {
+	untimeout(tid);
+	PRINT_WARNING("pciba: timeout(HZ) time not logged\n");
+	return;
+    }
+    cval = cval - c0val;
+    hwg_hprint(cval, "timeout(HZ)");
+
+    printk("verifying untimeout() cancells ...\n");
+    cNval[0] = 0;
+    tid = timeout((void (*)()) pciba_timeout, (void *) 0, 2, (void *) cNval);
+    untimeout(tid);
+    DELAY(1000000);
+    cval = cNval[0];
+    if (cval != 0) {
+	PRINT_ALERT("pciba: unable to cancel two-tick timeout\n");
+	cval -= c0val;
+	hwg_hprint(cval, "CANCELLED timeout(2)");
+    }
+}
+#endif
+
+int
+pciba_reg(void)
+{
+#if DEBUG_PCIBA
+    printk("pciba_reg()\n");
+#endif
+    pciio_driver_register(-1, -1, "pciba_", 0);
+
+#if HWG_PERF_CHECK && IP30 && !DEBUG
+    printk("%s %d\n", __FUNCTION__, __LINE__);
+pciba_timeout_test();
+#endif
+
+#if DEBUG_REFCT
+    {
+	char	       *cname = "pciba";
+	char	       *dname = "ptv";
+	char           *cpath0 = "node/xtalk/15";
+	char           *uname0 = "0";
+	char           *cpath1 = "node/xtalk/13";
+	char           *uname1 = "1";
+	devfs_handle_t conn;
+	devfs_handle_t conv;
+	devfs_handle_t vhdl;
+	int		ret;
+
+	printk("pciba refct tests:\n");
+
+#define	SHOWREF(vhdl,func)	printk("ref=%d\t%s\t(%d) %v\n", hwgraph_vertex_refct(vhdl), #func, vhdl, vhdl);
+
+	if (GRAPH_SUCCESS != (ret = hwgraph_path_add(hwgraph_root, cname, &conv)))
+	    printk("\tunable to create conv (ret=%d)\n", ret);
+	else {						SHOWREF(conv, hwgraph_path_add);
+	    if (GRAPH_SUCCESS != (ret = hwgraph_traverse(hwgraph_root, cpath0, &conn)))
+		printk("\tunable to find %s (ret=%d)\n", cpath0, ret);
+	    else {					SHOWREF(conn, hwgraph_traverse);
+		if (GRAPH_SUCCESS != (ret = hwgraph_char_device_add(conn, dname, "pciba_", &vhdl)))
+		    printk("unable to create %v/%s (ret=%d)\n", conn, dname, ret);
+		else {					SHOWREF(vhdl, hwgraph_char_device_add);
+		    hwgraph_chmod(vhdl, 0666);		SHOWREF(vhdl, hwgraph_chmod);
+		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_add(conv, vhdl, uname0)))
+			printk("unable to create %v/%s (ret=%d)\n", conn, uname0, vhdl, ret);
+		    else				SHOWREF(vhdl, hwgraph_edge_add);
+		    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(vhdl)))
+			printk("unable to unref %v\n", vhdl);
+		    else				SHOWREF(vhdl, hwgraph_vertex_unref);
+		}
+		if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conn)))
+		    printk("unable to unref %v\n", conn);
+		else					SHOWREF(conn, hwgraph_vertex_unref);
+	    }
+ 
+	    if (GRAPH_SUCCESS != (ret = hwgraph_traverse(hwgraph_root, cpath1, &conn)))
+		printk("\tunable to find %s (ret=%d)\n", cpath1, ret);
+	    else {					SHOWREF(conn, hwgraph_traverse);
+		if (GRAPH_SUCCESS != (ret = hwgraph_char_device_add(conn, dname, "pciba_", &vhdl)))
+		    printk("unable to create %v/%s (ret=%d)\n", conn, dname, ret);
+		else {					SHOWREF(vhdl, hwgraph_char_device_add);
+		    hwgraph_chmod(vhdl, 0666);		SHOWREF(vhdl, hwgraph_chmod);
+		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_add(conv, vhdl, uname1)))
+			printk("unable to create %v/%s (ret=%d)\n", conn, uname1, vhdl, ret);
+		    else				SHOWREF(vhdl, hwgraph_edge_add);
+		    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(vhdl)))
+			printk("unable to unref %v\n", vhdl);
+		    else				SHOWREF(vhdl, hwgraph_vertex_unref);
+		}
+		if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conn)))
+		    printk("unable to unref %v\n", conn);
+		else					SHOWREF(conn, hwgraph_vertex_unref);
+	    }
+ 
+	    if (GRAPH_SUCCESS != (ret = hwgraph_traverse(hwgraph_root, cpath0, &conn)))
+		printk("\tunable to find %s (ret=%d)\n", cpath0, ret);
+	    else {					SHOWREF(conn, hwgraph_traverse);
+		if (GRAPH_SUCCESS != (ret = hwgraph_traverse(conn, dname, &vhdl)))
+		    printk("\tunable to find %v/%s (ret=%d)\n", conn, dname, ret);
+		else {					SHOWREF(vhdl, hwgraph_traverse);
+		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(conv, uname0, NULL)))
+			printk("\tunable to remove edge %v/%s (ret=%d)\n", conv, uname0, ret);
+		    else				SHOWREF(vhdl, hwgraph_edge_remove);
+		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(conn, dname, NULL)))
+			printk("\tunable to remove edge %v/%s (ret=%d)\n", conn, dname, ret);
+		    else				SHOWREF(vhdl, hwgraph_edge_remove);
+		    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(vhdl)))
+			printk("unable to unref %v\n", vhdl);
+		    else				SHOWREF(vhdl, hwgraph_vertex_unref);
+		    if (GRAPH_SUCCESS == (ret = hwgraph_vertex_destroy(vhdl)))
+			printk("\tvertex %d destroyed OK\n", vhdl);
+		    else				SHOWREF(vhdl, hwgraph_vertex_destroy);
+		}
+		if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conn)))
+		    printk("unable to unref %v\n", conn);
+		else					SHOWREF(conn, hwgraph_vertex_unref);
+	    }
+
+	    if (GRAPH_SUCCESS != (ret = hwgraph_traverse(hwgraph_root, cpath1, &conn)))
+		printk("\tunable to find %s (ret=%d)\n", cpath1, ret);
+	    else {					SHOWREF(conn, hwgraph_traverse);
+		if (GRAPH_SUCCESS != (ret = hwgraph_traverse(conn, dname, &vhdl)))
+		    printk("\tunable to find %v/%s (ret=%d)\n", conn, dname, ret);
+		else {					SHOWREF(vhdl, hwgraph_traverse);
+		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(conv, uname1, NULL)))
+			printk("\tunable to remove edge %v/%s (ret=%d)\n", conv, uname1, ret);
+		    else				SHOWREF(vhdl, hwgraph_edge_remove);
+		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(conn, dname, NULL)))
+			printk("\tunable to remove edge %v/%s (ret=%d)\n", conn, dname, ret);
+		    else				SHOWREF(vhdl, hwgraph_edge_remove);
+		    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(vhdl)))
+			printk("unable to unref %v\n", vhdl);
+		    else				SHOWREF(vhdl, hwgraph_vertex_unref);
+		    if (GRAPH_SUCCESS == (ret = hwgraph_vertex_destroy(vhdl)))
+			printk("\tvertex %d destroyed OK\n", vhdl);
+		    else				SHOWREF(vhdl, hwgraph_vertex_destroy);
+		}
+		if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conn)))
+		    printk("unable to unref %v\n", conn);
+		else					SHOWREF(conn, hwgraph_vertex_unref);
+	    }
+
+	    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(hwgraph_root, cname, NULL)))
+		printk("\tunable to remove edge %v/%s (ret=%d)\n", hwgraph_root, cname, ret);
+	    else				SHOWREF(conv, hwgraph_edge_remove);
+	    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conv)))
+		printk("unable to unref %v\n", conv);
+	    else					SHOWREF(conv, hwgraph_vertex_unref);
+	    if (GRAPH_SUCCESS == (ret = hwgraph_vertex_destroy(conv)))
+		printk("\tvertex %d destroyed OK\n", conv);
+	    else					SHOWREF(conv, hwgraph_vertex_destroy);
+	}
+    }
+#endif
+
+    return 0;
+}
+
+#endif
+int
+pciba_attach(devfs_handle_t hconn)
+{
+#if defined(PCIIO_SLOT_NONE)
+    pciio_info_t            info = pciio_info_get(hconn);
+    pciio_slot_t            slot = pciio_info_slot_get(info);
+#endif
+    pciba_comm_t	    comm;
+    pciba_bus_t             bus;
+    int                     ht;
+    devfs_handle_t	    hbase;
+    devfs_handle_t          gconn;
+    devfs_handle_t          gbase;
+    int                     win;
+    int                     wins;
+    pciio_space_t           space;
+    pciaddr_t               base;
+
+    int                     iwins;
+    int                     mwins;
+
+#if DEBUG_PCIBA
+    printk("pciba_attach(%p)\n", hconn);
+#endif
+
+    /* Pick up "dualslot guest" vertex,
+     * which gets all functionality except
+     * config space access.
+     */
+    if ((GRAPH_SUCCESS !=
+	 hwgraph_traverse(hconn, ".guest", &gconn)) ||
+	(hconn == gconn))
+	gconn = GRAPH_VERTEX_NONE;
+
+    bus = pciba_find_bus(hconn, 1);
+    bus->refct ++;
+
+    /* set up data common to all pciba openables
+     * on this connection point.
+     */
+    NEW(comm);
+    comm->conn = hconn;
+    comm->bus = bus;
+    comm->refct = 0;
+    sema_init(&comm->lock, 1);
+
+#if !defined(PCIIO_SLOT_NONE)
+    if (bus->refct == 1)
+#else
+    if (slot == PCIIO_SLOT_NONE)
+#endif
+    {
+	pciio_info_t            pciio_info;
+	devfs_handle_t          master;
+
+	pciio_info = pciio_info_get(hconn);
+	master = pciio_info_master_get(pciio_info);
+
+	pciba_sub_attach(comm, PCIIO_SPACE_IO, PCIIO_SPACE_IO, 0, master, master, PCIBA_EDGE_LBL_IO);
+	pciba_sub_attach(comm, PCIIO_SPACE_MEM, PCIIO_SPACE_MEM, 0, master, master, PCIBA_EDGE_LBL_MEM);
+#if defined(PCIIO_SLOT_NONE)
+	return 0;
+#endif
+    }
+
+    ht = 0x7F & pciio_config_get(hconn, PCI_CFG_HEADER_TYPE, 1);
+
+    wins = ((ht == 0x00) ? 6 :
+	    (ht == 0x01) ? 2 :
+	    0);
+
+    mwins = iwins = 0;
+
+    hbase = GRAPH_VERTEX_NONE;
+    gbase = GRAPH_VERTEX_NONE;
+
+    for (win = 0; win < wins; win++) {
+
+	base = pciio_config_get(hconn, PCI_CFG_BASE_ADDR(win), 4);
+	if (base & 1) {
+	    space = PCIIO_SPACE_IO;
+	    base &= 0xFFFFFFFC;
+	} else if ((base & 7) == 4) {
+	    space = PCIIO_SPACE_MEM;
+	    base &= 0xFFFFFFF0;
+	    base |= ((pciaddr_t) pciio_config_get(hconn, PCI_CFG_BASE_ADDR(win + 1), 4)) << 32;
+	} else {
+	    space = PCIIO_SPACE_MEM;
+	    base &= 0xFFFFFFF0;
+	}
+
+	if (!base)
+	    break;
+
+#if PCIBA_ALIGN_CHECK
+	if (base & (_PAGESZ - 1)) {
+#if DEBUG_PCIBA
+	    PRINT_WARNING("%p pciba: BASE%d not page aligned!\n"
+		    "\tmmap this window at offset 0x%x via \".../pci/%s\"\n",
+		    hconn, win, base,
+		    (space == PCIIO_SPACE_IO) ? "io" : "mem");
+#endif
+	    continue;			/* next window */
+	}
+#endif
+
+	if ((hbase == GRAPH_VERTEX_NONE) &&
+	    ((GRAPH_SUCCESS !=
+	      hwgraph_path_add(hconn, PCIBA_EDGE_LBL_BASE, &hbase)) ||
+	     (hbase == GRAPH_VERTEX_NONE)))
+	    break;			/* no base vertex, no more windows. */
+
+	if ((gconn != GRAPH_VERTEX_NONE) &&
+	    (gbase == GRAPH_VERTEX_NONE) &&
+	    ((GRAPH_SUCCESS !=
+	      hwgraph_path_add(gconn, PCIBA_EDGE_LBL_BASE, &gbase)) ||
+	     (gbase == GRAPH_VERTEX_NONE)))
+	    break;			/* no base vertex, no more windows. */
+
+	pciba_sub_attach(comm, PCIIO_SPACE_WIN(win), space, base, hbase, gbase, PCIBA_EDGE_LBL_WIN(win));
+
+	if (space == PCIIO_SPACE_IO) {
+	    if (!iwins++) {
+		pciba_sub_attach(comm, PCIIO_SPACE_WIN(win), space, base, hconn, gconn, PCIBA_EDGE_LBL_IO);
+	    }
+	} else {
+	    if (!mwins++) {
+		pciba_sub_attach(comm, PCIIO_SPACE_WIN(win), space, base, hconn, gconn, PCIBA_EDGE_LBL_MEM);
+	    }
+	}
+
+	if ((base & 7) == 4)
+	    win++;
+    }
+
+    pciba_sub_attach(comm, PCIIO_SPACE_CFG, PCIIO_SPACE_NONE, 0, hconn, gconn, PCIBA_EDGE_LBL_CFG);
+    pciba_sub_attach(comm, PCIBA_SPACE_UDMA, PCIIO_SPACE_NONE, 0, hconn, gconn, PCIBA_EDGE_LBL_DMA);
+#if ULI
+    pciba_sub_attach(comm, PCIIO_SPACE_NONE, PCIIO_SPACE_NONE, 0, hconn, gconn, PCIBA_EDGE_LBL_INTR);
+#endif
+
+    /* XXX should ignore if device is an IOC3 */
+    if (ht == 0x01)
+	base = pciio_config_get(hconn, PCI_EXPANSION_ROM+8, 4);
+    else
+	base = pciio_config_get(hconn, PCI_EXPANSION_ROM, 4);
+
+    base &= 0xFFFFF000;
+
+    if (base) {
+	if (base & (_PAGESZ - 1))
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+	    PRINT_WARNING("%v pciba: ROM is 0x%x\n"
+		    "\tnot page aligned, mmap will be difficult\n",
+		    hconn, base);
+#else
+	    PRINT_WARNING("0x%x pciba: ROM is 0x%x\n"
+		    "\tnot page aligned, mmap will be difficult\n",
+		    hconn, base);
+#endif
+	pciba_sub_attach(comm, PCIIO_SPACE_ROM, PCIIO_SPACE_MEM, base, hconn, gconn, PCIBA_EDGE_LBL_ROM);
+    }
+
+#if !FICUS	/* FICUS shorts the refct by one on path_add */
+    if (hbase != GRAPH_VERTEX_NONE)
+	hwgraph_vertex_unref(hbase);
+
+    if (gbase != GRAPH_VERTEX_NONE)
+	hwgraph_vertex_unref(gbase);
+#endif
+
+    return 0;
+}
+
+static void
+pciba_sub_attach2(pciba_comm_t comm,
+		  pciio_space_t space,
+		  pciio_space_t iomem,
+		  pciaddr_t base,
+		  devfs_handle_t from,
+		  char *name,
+		  char *suf,
+		  unsigned bigend)
+{
+    char		nbuf[128];
+    pciba_soft_t            soft;
+    devfs_handle_t	handle = NULL;
+
+    if (suf && *suf) {
+	strcpy(nbuf, name);
+	name = nbuf;
+	strcat(name, suf);
+    }
+
+#if DEBUG_PCIBA
+    printk("pciba_sub_attach2 %p/%s %p at %p[%x]\n",
+	   from, name, space, space_desc, iomem, space_desc, base, from, name);
+#endif
+
+    if (space < TRACKED_SPACES)
+	if ((soft = comm->soft[space][bigend]) != NULL) {
+	    soft->refct ++;
+	    hwgraph_edge_add(from, soft->vhdl, name);
+	    return;
+	}
+
+    NEW(soft);
+    if (!soft)
+	return;
+
+    soft->comm = comm;
+    soft->space = space;
+    soft->size = 0;
+    soft->iomem = iomem;
+    soft->base = base;
+    soft->refct = 1;
+
+    if (space == PCIIO_SPACE_NONE)
+	soft->flags = 0;
+    else if (bigend)
+	soft->flags = PCIIO_BYTE_STREAM;
+    else
+	soft->flags = PCIIO_WORD_VALUES;
+
+    handle = hwgraph_register(from, name,
+		0, DEVFS_FL_AUTO_DEVNUM,
+		0, 0,
+		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+		&pciba_fops, NULL);
+    soft->vhdl = handle;
+    pciba_soft_set(soft->vhdl, soft);
+    if (space < TRACKED_SPACES)
+	comm->soft[space][bigend] = soft;
+    comm->refct ++;
+}
+
+static void
+pciba_sub_attach1(pciba_comm_t comm,
+		  pciio_space_t space,
+		  pciio_space_t iomem,
+		  pciaddr_t base,
+		  devfs_handle_t hfrom,
+		  devfs_handle_t gfrom,
+		  char *name,
+		  char *suf,
+		  unsigned bigend)
+{
+    pciba_sub_attach2(comm, space, iomem, base, hfrom, name, suf, bigend);
+    if ((gfrom != GRAPH_VERTEX_NONE) && (gfrom != hfrom))
+	pciba_sub_attach2(comm, space, iomem, base, gfrom, name, suf, bigend);
+}
+
+static void
+pciba_sub_attach(pciba_comm_t comm,
+		 pciio_space_t space,
+		 pciio_space_t iomem,
+		 pciaddr_t base,
+		 devfs_handle_t hfrom,
+		 devfs_handle_t gfrom,
+		 char *name)
+{
+    pciba_sub_attach1(comm, space, iomem, base, hfrom, gfrom, name, NULL, 0);
+    if (iomem != PCIIO_SPACE_NONE) {
+	pciba_sub_attach1(comm, space, iomem, base, hfrom, gfrom, name, "_le", 0);
+	pciba_sub_attach1(comm, space, iomem, base, hfrom, gfrom, name, "_be", 1);
+    }
+}
+
+#ifdef LATER
+static void
+pciba_reload_me(devfs_handle_t pconn_vhdl)
+{
+    devfs_handle_t            vhdl;
+
+#if DEBUG_PCIBA
+    printf("pciba_reload_me(%v)\n", pconn_vhdl);
+#endif
+
+    if (GRAPH_SUCCESS !=
+	hwgraph_traverse(pconn_vhdl, PCIBA_EDGE_LBL_CFG, &vhdl))
+	return;
+
+    hwgraph_vertex_unref(vhdl);
+}
+#endif	/* LATER */
+
+static                  pciba_bus_t
+pciba_find_bus(devfs_handle_t pconn, int cflag)
+{
+    pciio_info_t            pciio_info;
+    devfs_handle_t          master;
+    arbitrary_info_t        ainfo;
+    pciba_bus_t             bus;
+
+    pciio_info = pciio_info_get(pconn);
+    master = pciio_info_master_get(pciio_info);
+
+    if (GRAPH_SUCCESS ==
+	hwgraph_info_get_LBL(master, PCIBA_INFO_LBL_BUS, &ainfo))
+	return (pciba_bus_t) ainfo;
+
+    if (!cflag)
+	return 0;
+
+    NEW(bus);
+    if (!bus)
+	return 0;
+
+    sema_init(&bus->lock, 1);
+
+    ainfo = (arbitrary_info_t) bus;
+    hwgraph_info_add_LBL(master, PCIBA_INFO_LBL_BUS, ainfo);
+    hwgraph_info_get_LBL(master, PCIBA_INFO_LBL_BUS, &ainfo);
+    if ((pciba_bus_t) ainfo != bus)
+	DEL(bus);
+#if DEBUG_PCIBA
+    else
+	printk("pcbia_find_bus: new bus at %p\n", master);
+#endif
+
+    return (pciba_bus_t) ainfo;
+}
+
+#ifdef LATER
+static void
+pciba_map_push(pciba_bus_t bus, pciba_map_t map)
+{
+#if DEBUG_PCIBA
+    printk("pciba_map_push(bus=0x%x, map=0x%x, hdl=0x%x\n",
+	   bus, map, map->handle);
+#endif
+    pciba_bus_lock(bus);
+    map->next = bus->maps;
+    bus->maps = map;
+    pciba_bus_unlock(bus);
+}
+
+static                  pciba_map_t
+pciba_map_pop_hdl(pciba_bus_t bus, __psunsigned_t handle)
+{
+    pciba_map_h             hdl;
+    pciba_map_t             map;
+
+    pciba_bus_lock(bus);
+    for (hdl = &bus->maps; map = *hdl; hdl = &map->next)
+	if (map->handle == handle) {
+	    *hdl = map->next;
+	    break;
+	}
+    pciba_bus_unlock(bus);
+#if DEBUG_PCIBA
+    printk("pciba_map_pop_va(bus=0x%x, handle=0x%x) returns map=0x%x\n",
+	   bus, handle, map);
+#endif
+    return map;
+}
+
+/* ================================================================
+ *            driver teardown, unregister and unload
+ */
+int
+pciba_unload(void)
+{
+#if DEBUG_PCIBA
+    printk("pciba_unload()\n");
+#endif
+
+    if (atomic_read(&pciba_prevent_unload))
+	return -1;
+
+    pciio_iterate("pciba_", pciba_unload_me);
+
+    return 0;
+}
+
+int
+pciba_unreg(void)
+{
+
+#if DEBUG_PCIBA
+    printf("pciba_unreg()\n");
+#endif
+
+    if (atomic_read(&pciba_prevent_unload))
+	return -1;
+
+    pciio_driver_unregister("pciba_");
+    return 0;
+}
+
+int
+pciba_detach(devfs_handle_t conn)
+{
+    devfs_handle_t          base;
+    pciba_bus_t             bus;
+    devfs_handle_t          gconn;
+    devfs_handle_t          gbase;
+
+    pciio_info_t            pciio_info;
+    devfs_handle_t          master;
+    arbitrary_info_t        ainfo;
+    int			    ret;
+
+#if DEBUG_PCIBA
+    printf("pciba_detach(%v)\n", conn);
+#endif
+
+    if ((GRAPH_SUCCESS !=
+	 hwgraph_traverse(conn, ".guest", &gconn)) ||
+	(conn == gconn))
+	gconn = GRAPH_VERTEX_NONE;
+
+    if (gconn != GRAPH_VERTEX_NONE) {
+	pciba_sub_detach(gconn, PCIBA_EDGE_LBL_CFG);
+	pciba_sub_detach(gconn, PCIBA_EDGE_LBL_DMA);
+	pciba_sub_detach(gconn, PCIBA_EDGE_LBL_ROM);
+#if ULI
+	pciba_sub_detach(gconn, PCIBA_EDGE_LBL_INTR);
+#endif
+	if (GRAPH_SUCCESS == hwgraph_edge_remove(conn, PCIBA_EDGE_LBL_BASE, &gbase)) {
+	    pciba_sub_detach(gconn, PCIBA_EDGE_LBL_MEM);
+	    pciba_sub_detach(gconn, PCIBA_EDGE_LBL_IO);
+	    pciba_sub_detach(gbase, "0");
+	    pciba_sub_detach(gbase, "1");
+	    pciba_sub_detach(gbase, "2");
+	    pciba_sub_detach(gbase, "3");
+	    pciba_sub_detach(gbase, "4");
+	    pciba_sub_detach(gbase, "5");
+	    hwgraph_vertex_unref(gbase);
+	    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_destroy(gbase))) {
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+		PRINT_WARNING("pciba: hwgraph_vertex_destroy(%v/base) failed (%d)",
+			conn, ret);
+#else
+		PRINT_WARNING("pciba: hwgraph_vertex_destroy(0x%x/base) failed (%d)",
+			conn, ret);
+#endif
+#if DEBUG_REFCT
+		printk("\tretained refct %d\n", hwgraph_vertex_refct(gbase));
+#endif
+	    }
+	}
+    }
+
+    pciba_sub_detach(conn, PCIBA_EDGE_LBL_CFG);
+    pciba_sub_detach(conn, PCIBA_EDGE_LBL_DMA);
+    pciba_sub_detach(conn, PCIBA_EDGE_LBL_ROM);
+#if ULI
+    pciba_sub_detach(conn, PCIBA_EDGE_LBL_INTR);
+#endif
+
+    if (GRAPH_SUCCESS == hwgraph_edge_remove(conn, PCIBA_EDGE_LBL_BASE, &base)) {
+	pciba_sub_detach(conn, PCIBA_EDGE_LBL_MEM);
+	pciba_sub_detach(conn, PCIBA_EDGE_LBL_IO);
+	pciba_sub_detach(base, "0");
+	pciba_sub_detach(base, "1");
+	pciba_sub_detach(base, "2");
+	pciba_sub_detach(base, "3");
+	pciba_sub_detach(base, "4");
+	pciba_sub_detach(base, "5");
+	hwgraph_vertex_unref(base);
+	if (GRAPH_SUCCESS != (ret = hwgraph_vertex_destroy(base))) {
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+	    PRINT_WARNING(CE_WARN, "pciba: hwgraph_vertex_destroy(%v/base) failed (%d)",
+		    conn, ret);
+#else
+	    PRINT_WARNING(CE_WARN, "pciba: hwgraph_vertex_destroy(0x%x/base) failed (%d)",
+		    conn, ret);
+#endif
+#if DEBUG_REFCT
+	    printk("\tretained refct %d\n", hwgraph_vertex_refct(base));
+#endif
+	}
+    }
+
+    bus = pciba_find_bus(conn, 0);
+    if (bus && !--(bus->refct)) {
+
+	pciio_info = pciio_info_get(conn);
+
+	master = pciio_info_master_get(pciio_info);
+
+	pciba_sub_detach(master, PCIBA_EDGE_LBL_IO);
+	pciba_sub_detach(master, PCIBA_EDGE_LBL_MEM);
+	pciba_sub_detach(master, PCIBA_EDGE_LBL_CFG);
+	hwgraph_info_remove_LBL(master, PCIBA_INFO_LBL_BUS, &ainfo);
+
+#if DEBUG_PCIBA
+	printf("pcbia_detach: DEL(bus) at %v\n", master);
+#endif
+	DEL(bus);
+    } 
+
+    return 0;
+}
+
+static void
+pciba_sub_detach1(devfs_handle_t conn,
+		  char *name,
+		  char *suf)
+{
+    devfs_handle_t         vhdl;
+    pciba_soft_t            soft;
+    pciba_comm_t	    comm;
+    int			    ret;
+    char		nbuf[128];
+
+    if (suf && *suf) {
+	strcpy(nbuf, name);
+	name = nbuf;
+	strcat(name, suf);
+    }
+
+    if ((GRAPH_SUCCESS == hwgraph_edge_remove(conn, name, &vhdl)) &&
+	((soft = pciba_soft_get(vhdl)) != NULL)) {
+#if DEBUG_PCIBA
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+	prink("pciba_sub_detach(%v,%s)\n", conn, name);
+#else
+	prink("pciba_sub_detach(0x%x,%s)\n", conn, name);
+#endif
+#endif
+
+	hwgraph_vertex_unref(soft->vhdl);
+#if DEBUG_REFCT
+	printk("\tadjusted refct %d (soft ref: %d)\n",
+		hwgraph_vertex_refct(vhdl),
+		soft->refct);
+#endif
+	if (!--(soft->refct)) {
+	    comm = soft->comm;
+	    if (!--(comm->refct)) {
+		DEL(comm);
+	    }
+	    pciba_soft_set(vhdl, 0);
+	    DEL(soft);
+
+	    hwgraph_vertex_unref(vhdl);
+	    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_destroy(vhdl))) {
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+		PRINT_WARNING("pciba: hwgraph_vertex_destroy(0x%x/%s) failed (%d)",
+			conn, name, ret);
+#else
+		PRINT_WARNING("pciba: hwgraph_vertex_destroy(%v/%s) failed (%d)",
+			conn, name, ret);
+#endif
+#if DEBUG_REFCT
+		printk("\tretained refct %d\n", hwgraph_vertex_refct(vhdl));
+#endif
+	    }
+	}
+    }
+}
+
+static void
+pciba_sub_detach(devfs_handle_t conn,
+		 char *name)
+{
+    pciba_sub_detach1(conn, name, "");
+    pciba_sub_detach1(conn, name, "_le");
+    pciba_sub_detach1(conn, name, "_be");
+}
+
+static void
+pciba_unload_me(devfs_handle_t pconn_vhdl)
+{
+    devfs_handle_t         c_vhdl;
+
+#if DEBUG_PCIBA
+    printf("pciba_unload_me(%v)\n", pconn_vhdl);
+#endif
+
+    if (GRAPH_SUCCESS !=
+	hwgraph_traverse(pconn_vhdl, PCIBA_EDGE_LBL_CFG, &c_vhdl))
+	return;
+
+    hwgraph_vertex_unref(c_vhdl);
+}
+
+/* ================================================================
+ *            standard unix entry points
+ */
+
+/*ARGSUSED */
+int
+pciba_open(dev_t *devp, int flag, int otyp, struct cred *crp)
+{
+
+#if DEBUG_PCIBA
+    printf("pciba_open(%V)\n", *devp);
+#endif
+    return 0;
+}
+
+/*ARGSUSED */
+int
+pciba_close(dev_t dev)
+{
+    devfs_handle_t         vhdl = dev_to_vhdl(dev);
+    pciba_soft_t            soft = pciba_soft_get(vhdl);
+
+#if DEBUG_PCIBA
+    printf("pciba_close(%V)\n", dev);
+#endif
+
+    /* if there is pending DMA for this device, hit the
+     * device over the head with a baseball bat and
+     * release the system memory resources.
+     */
+    if (soft && soft->comm->dmap) {
+	pciba_dma_t             next;
+	pciba_dma_t             dmap;
+
+	pciba_soft_lock(soft);
+	if (dmap = soft->comm->dmap) {
+	    soft->comm->dmap = 0;
+
+	    pciio_reset(soft->comm->conn);
+
+	    do {
+		if (!dmap->kaddr)
+		    break;
+		if (!dmap->paddr)
+		    break;
+		if (dmap->bytes < NBPP)
+		    break;
+		next = dmap->next;
+		kvpfree(dmap->kaddr, dmap->bytes / NBPP);
+		dmap->paddr = 0;
+		dmap->bytes = 0;
+		DEL(dmap);
+	    } while (dmap = next);
+	}
+	pciba_soft_unlock(soft);
+    }
+    return 0;
+}
+
+/* ARGSUSED */
+int
+pciba_read(dev_t dev, cred_t *crp)
+{
+#if DEBUG_PCIBA
+    printf("pciba_read(%V)\n", dev);
+#endif
+
+    return EINVAL;
+}
+
+/* ARGSUSED */
+int
+pciba_write(dev_t dev, cred_t *crp)
+{
+#if DEBUG_PCIBA
+    printf("pciba_write(%V)\n", dev);
+#endif
+
+    return EINVAL;
+}
+
+/*ARGSUSED */
+int
+pciba_ioctl(dev_t dev, int cmd, void *uarg, int mode, cred_t *crp, int *rvalp)
+{
+    devfs_handle_t          vhdl;
+    pciba_soft_t            soft;
+    pciio_space_t           space;
+    ioctl_arg_buffer_t      arg;
+    int                     psize;
+    int                     err = 0;
+
+#if ULI
+    char		    abi = get_current_abi();
+    pciio_intr_t            intr=0;
+    device_desc_t           desc;
+    cpuid_t                 intrcpu;
+    unsigned                lines;
+    struct uli             *uli = 0;
+#endif
+    unsigned                flags;
+    void                   *kaddr = 0;
+    iopaddr_t               paddr;
+    pciba_dma_h             dmah;
+    pciba_dma_t             dmap = 0;
+    pciio_dmamap_t          dmamap = 0;
+    size_t                  bytes;
+    int                     pages;
+    pciaddr_t               daddr;
+
+#if DEBUG_PCIBA
+    printf("pciba_ioctl(%V,0x%x)\n", dev, cmd);
+#endif
+
+    psize = (cmd >> 16) & IOCPARM_MASK;
+
+#if ULI
+    ASSERT(sizeof(struct uliargs) > 8);	/* prevent CFG access conflict */
+    ASSERT(sizeof(struct uliargs) <= IOCPARM_MASK);
+#endif
+
+    arg.ca = uarg;
+
+    if ((psize > 0) && (cmd & (IOC_OUT | IOC_IN))) {
+	if (psize > sizeof(arg))
+	    err = EINVAL;		/* "bad parameter size */
+	else {
+	    if (cmd & IOC_OUT)
+		bzero(arg.data, psize);
+	    if ((cmd & IOC_IN) &&
+		(copyin(uarg, arg.data, psize) < 0))
+		err = EFAULT;		/* "parameter copyin failed" */
+	}
+    }
+    vhdl = dev_to_vhdl(dev);
+    soft = pciba_soft_get(vhdl);
+    space = soft->space;
+
+    if (err == 0) {
+	err = EINVAL;			/* "invalid ioctl for this vertex" */
+	switch (space) {
+#if ULI
+	case PCIIO_SPACE_NONE:		/* the "intr" vertex */
+	    /* PCIIOCSETULI: set up user interrupts.
+	     */
+	    lines = cmd & 15;
+	    if (ABI_IS_64BIT(abi)) {
+		if (cmd != PCIIOCSETULI(lines)) {
+		    err = EINVAL;		/* "invalid ioctl for this vertex" */
+		    break;
+		}
+	    }
+	    else {
+		struct uliargs uliargs;
+
+		if (cmd != PCIIOCSETULI32(lines)) {
+		    err = EINVAL;		/* "invalid ioctl for this vertex" */
+		    break;
+		}
+		
+		uliargs32_to_uliargs(&arg.uli32, &uliargs);
+		arg.uli = uliargs;
+	    }
+	    desc = device_desc_dup(soft->comm->conn);
+	    device_desc_flags_set(desc, (device_desc_flags_get(desc) |
+					 D_INTR_NOTHREAD));
+	    device_desc_intr_swlevel_set(desc, INTR_SWLEVEL_NOTHREAD_DEFAULT);
+	    device_desc_intr_name_set(desc, "PCIBA");
+	    device_desc_default_set(soft->comm->conn, desc);
+
+	    /* When designating interrupts, the slot number
+	     * is taken from the connection point.
+	     * Bits 0..3 are used to select INTA..INTD; more
+	     * than one bit can be specified. These should
+	     * be constructed using PCIIO_INTR_LINE_[ABCD].
+	     */
+	    intr = pciio_intr_alloc
+		(soft->comm->conn, desc, lines, soft->vhdl);
+	    if (intr == 0) {
+		err = ENOMEM;		/* "insufficient resources" */
+		break;
+	    }
+	    intrcpu = cpuvertex_to_cpuid(pciio_intr_cpu_get(intr));
+
+	    if (err = new_uli(&arg.uli, &uli, intrcpu)) {
+		break;			/* "unable to set up ULI" */
+	    }
+	    atomic_inc(&pciba_prevent_unload);
+
+	    pciio_intr_connect(intr, pciba_intr, uli, (void *) 0);
+
+	    /* NOTE: don't set the teardown function
+	     * until the interrupt is connected.
+	     */
+	    uli->teardownarg1 = (__psint_t) intr;
+	    uli->teardown = pciba_clearuli;
+
+	    arg.uli.id = uli->index;
+
+	    if (!ABI_IS_64BIT(abi)) {
+		struct uliargs32 uliargs32;
+		uliargs_to_uliargs32(&arg.uli, &uliargs32);
+		arg.uli32 = uliargs32;
+	    }
+
+	    err = 0;
+	    break;
+#endif
+
+	case PCIBA_SPACE_UDMA:		/* the "dma" vertex */
+
+	    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.
+		 * NOTE: this allocates memory local to the
+		 * CPU doing the ioctl, not local to the
+		 * device that will be doing the DMA.
+		 */
+
+		if (!_CAP_ABLE(CAP_DEVICE_MGT)) {
+		    err = EPERM;
+		    break;
+		}
+		/* separate the halves of the incoming parameter */
+		flags = arg.ud >> 32;
+		bytes = arg.ud & 0xFFFFFFFF;
+
+#if DEBUG_PCIBA
+		printf("pciba: user wants 0x%x bytes of DMA, flags 0x%x\n",
+		       bytes, flags);
+#endif
+
+		/* round up the requested size to the next highest page */
+		pages = (bytes + NBPP - 1) / NBPP;
+
+		/* make sure the requested size is something reasonable */
+		if (pages > pci_user_dma_max_pages) {
+#if DEBUG_PCIBA
+		    printf("pciba: request for too much buffer space\n");
+#endif
+		    err = EINVAL;
+		    break;		/* "request for too much buffer space" */
+		}
+		/* "correct" number of bytes */
+		bytes = pages * NBPP;
+
+		/* allocate the space */
+		/* XXX- force to same node as the device? */
+		/* XXX- someday, we want to handle user buffers,
+		 *    and noncontiguous pages, but this will
+		 *      require either fancy mapping or handing
+		 *      a list of blocks back to the user. For
+		 *      now, just tell users to allocate a lot of
+		 *      individual single-pages and manage their
+		 *      scatter-gather manually.
+		 */
+		kaddr = kvpalloc(pages, VM_DIRECT | KM_NOSLEEP, 0);
+		if (kaddr == 0) {
+#if DEBUG_PCIBA
+		    printf("pciba: unable to get %d contiguous pages\n", pages);
+#endif
+		    err = EAGAIN;	/* "insufficient resources, try again later" */
+		    break;
+		}
+#if DEBUG_PCIBA
+		printf("pciba: kaddr is 0x%x\n", kaddr);
+#endif
+		paddr = kvtophys(kaddr);
+
+		daddr = pciio_dmatrans_addr
+		    (soft->comm->conn, 0, paddr, bytes, flags);
+		if (daddr == 0) {	/* "no direct path available" */
+#if DEBUG_PCIBA
+		    printf("pciba: dmatrans failed, trying dmamap\n");
+#endif
+		    dmamap = pciio_dmamap_alloc
+			(soft->comm->conn, 0, bytes, flags);
+		    if (dmamap == 0) {
+#if DEBUG_PCIBA
+			printf("pciba: unable to allocate dmamap\n");
+#endif
+			err = ENOMEM;
+			break;		/* "out of mapping resources" */
+		    }
+		    daddr = pciio_dmamap_addr
+			(dmamap, paddr, bytes);
+		    if (daddr == 0) {
+#if DEBUG_PCIBA
+			printf("pciba: dmamap_addr failed\n");
+#endif
+			err = EINVAL;
+			break;		/* "can't get there from here" */
+		    }
+		}
+#if DEBUG_PCIBA
+		printf("pciba: daddr is 0x%x\n", daddr);
+#endif
+		NEW(dmap);
+		if (!dmap) {
+		    err = ENOMEM;
+		    break;		/* "no memory available" */
+		}
+		dmap->bytes = bytes;
+		dmap->pages = pages;
+		dmap->paddr = paddr;
+		dmap->kaddr = kaddr;
+		dmap->map = dmamap;
+		dmap->daddr = daddr;
+		dmap->handle = 0;
+
+#if DEBUG_PCIBA
+		printf("pciba: dmap 0x%x contains va 0x%x bytes 0x%x pa 0x%x pages 0x%x daddr 0x%x\n",
+		       dmap, kaddr, bytes, paddr, pages, daddr);
+#endif
+
+		arg.ud = dmap->daddr;
+
+		err = 0;
+		break;
+
+	    case PCIIOCDMAFREE:
+		/* PCIIOCDMAFREE: Find the chunk of
+		 * User DMA memory, and release its
+		 * resources back to the system.
+		 */
+
+		if (!_CAP_ABLE(CAP_DEVICE_MGT)) {
+		    err = EPERM;	/* "you can't do that" */
+		    break;
+		}
+		if (soft->comm->dmap == NULL) {
+		    err = EINVAL;	/* "no User DMA to free" */
+		    break;
+		}
+		/* find the request. */
+		daddr = arg.ud;
+		err = EINVAL;		/* "block not found" */
+		pciba_soft_lock(soft);
+		for (dmah = &soft->comm->dmap; dmap = *dmah; dmah = &dmap->next) {
+		    if (dmap->daddr == daddr) {
+			if (dmap->handle != 0) {
+			    dmap = 0;	/* don't DEL this dmap! */
+			    err = EINVAL;	/* "please unmap first" */
+			    break;		/* break outa for loop. */
+			}
+			*dmah = dmap->next;
+
+			if (dmamap = dmap->map) {
+			    pciio_dmamap_free(dmamap);
+			    dmamap = 0;	/* don't free it twice! */
+			}
+			kvpfree(dmap->kaddr, dmap->bytes / NBPP);
+			DEL(dmap);
+			dmap = 0;	/* don't link this back into the list! */
+			err = 0;	/* "all done" */
+			break;		/* break outa for loop. */
+		    }
+		}
+		pciba_soft_unlock(soft);
+		break;		/* break outa case PCIIOCDMAFREE: */
+	    }
+	    break;		/* break outa case PCIBA_SPACE_UDMA: */
+
+	case PCIIO_SPACE_CFG:
+
+	    /* PCIIOCCFG{RD,WR}: read and/or write
+	     * PCI configuration space. If both,
+	     * the read happens first (this becomes
+	     * a swap operation, atomic with respect
+	     * to other updates through this path).
+	     *
+	     * Should be *last* IOCTl command checked,
+	     * so other patterns can nip useless codes
+	     * out of the space this decodes.
+	     */
+	    err = EINVAL;
+	    if ((psize > 0) || (psize <= 8) &&
+		(((cmd & 0xFF) + psize) <= 256) &&
+		(cmd & (IOC_IN | IOC_OUT))) {
+
+		uint64_t                rdata;
+		uint64_t                wdata;
+		int                     shft;
+
+		shft = 64 - (8 * psize);
+
+		wdata = arg.ud >> shft;
+
+		pciba_soft_lock(soft);
+
+		if (cmd & IOC_OUT)
+		    rdata = pciio_config_get(soft->comm->conn, cmd & 0xFFFF, psize);
+		if (cmd & IOC_IN)
+		    pciio_config_set(soft->comm->conn, cmd & 0xFFFF, psize, wdata);
+
+		pciba_soft_unlock(soft);
+
+		arg.ud = rdata << shft;
+		err = 0;
+		break;
+	    }
+	    break;
+	}
+    }
+    /* done: come here if all went OK.
+     */
+    if ((err == 0) &&
+	((cmd & IOC_OUT) && (psize > 0)) &&
+	copyout(arg.data, uarg, psize))
+	err = EFAULT;
+
+    /* This gets delayed until after the copyout so we
+     * do not free the dmap on a copyout error, or
+     * alternately end up with a dangling allocated
+     * buffer that the user never got back.
+     */
+    if ((err == 0) && dmap) {
+	pciba_soft_lock(soft);
+	dmap->next = soft->comm->dmap;
+	soft->comm->dmap = dmap;
+	pciba_soft_unlock(soft);
+    }
+    if (err) {
+	/* Things went badly. Clean up.
+	 */
+#if ULI
+	if (intr) {
+	    pciio_intr_disconnect(intr);
+	    pciio_intr_free(intr);
+	}
+	if (uli)
+	    free_uli(uli);
+#endif
+	if (dmap) {
+	    if (dmap->map && (dmap->map != dmamap))
+		pciio_dmamap_free(dmap->map);
+	    DEL(dmap);
+	}
+	if (dmamap)
+	    pciio_dmamap_free(dmamap);
+	if (kaddr)
+	    kvpfree(kaddr, pages);
+    }
+    return *rvalp = err;
+}
+
+/* ================================================================
+ *            mapping support
+ */
+
+/*ARGSUSED */
+int
+pciba_map(dev_t dev, vhandl_t *vt,
+	  off_t off, size_t len, uint32_t prot)
+{
+    devfs_handle_t          vhdl = dev_to_vhdl(dev);
+    pciba_soft_t            soft = pciba_soft_get(vhdl);
+    devfs_handle_t          conn = soft->comm->conn;
+    pciio_space_t           space = soft->space;
+    size_t                  pages = (len + NBPP - 1) / NBPP;
+    pciio_piomap_t          pciio_piomap = 0;
+    caddr_t                 kaddr;
+    pciba_map_t             map;
+    pciba_dma_t             dmap;
+
+#if DEBUG_PCIBA
+    printf("pciba_map(%V,vt=0x%x)\n", dev, vt);
+#endif
+
+    if (space == PCIBA_SPACE_UDMA) {
+	pciba_soft_lock(soft);
+
+	for (dmap = soft->comm->dmap; dmap != NULL; dmap = dmap->next) {
+	    if (off == dmap->daddr) {
+		if (pages != dmap->pages) {
+		    pciba_soft_unlock(soft);
+		    return EINVAL;	/* "size mismatch" */
+		}
+		v_mapphys(vt, dmap->kaddr, dmap->bytes);
+		dmap->handle = v_gethandle(vt);
+		pciba_soft_unlock(soft);
+#if DEBUG_PCIBA
+		printf("pciba: mapped dma at kaddr 0x%x via handle 0x%x\n",
+		       dmap->kaddr, dmap->handle);
+#endif
+		return 0;
+	    }
+	}
+	pciba_soft_unlock(soft);
+	return EINVAL;			/* "block not found" */
+    }
+    if (soft->iomem == PCIIO_SPACE_NONE)
+	return EINVAL;			/* "mmap not supported" */
+
+    kaddr = (caddr_t) pciio_pio_addr
+	(conn, 0, space, off, len, &pciio_piomap, soft->flags | PCIIO_FIXED );
+
+#if DEBUG_PCIBA
+    printf("pciba: mapped %R[0x%x..0x%x] via map 0x%x to kaddr 0x%x\n",
+	   space, space_desc, off, off + len - 1, pciio_piomap, kaddr);
+#endif
+
+    if (kaddr == NULL)
+	return EINVAL;			/* "you can't get there from here" */
+
+    NEW(map);
+    if (map == NULL) {
+	if (pciio_piomap)
+	    pciio_piomap_free(pciio_piomap);
+	return ENOMEM;			/* "unable to get memory resources */
+    }
+#ifdef LATER
+    map->uthread = curuthread;
+#endif
+    map->handle = v_gethandle(vt);
+    map->uvaddr = v_getaddr(vt);
+    map->map = pciio_piomap;
+    map->space = soft->iomem;
+    map->base = soft->base + off;
+    map->size = len;
+    pciba_map_push(soft->comm->bus, map);
+
+    /* Inform the system of the correct
+     * kvaddr corresponding to the thing
+     * that is being mapped.
+     */
+    v_mapphys(vt, kaddr, len);
+
+    return 0;
+}
+
+/*ARGSUSED */
+int
+pciba_unmap(dev_t dev, vhandl_t *vt)
+{
+    devfs_handle_t         vhdl = dev_to_vhdl(dev);
+    pciba_soft_t            soft = pciba_soft_get(vhdl);
+    pciba_bus_t             bus = soft->comm->bus;
+    pciba_map_t             map;
+    __psunsigned_t          handle = v_gethandle(vt);
+
+#if DEBUG_PCIBA
+    printf("pciba_unmap(%V,vt=%x)\n", dev, vt);
+#endif
+
+    /* If this is a userDMA buffer,
+     * make a note that it has been unmapped
+     * so it can be released.
+     */
+    if (soft->comm->dmap) {
+	pciba_dma_t             dmap;
+
+	pciba_soft_lock(soft);
+	for (dmap = soft->comm->dmap; dmap != NULL; dmap = dmap->next)
+	    if (handle == dmap->handle) {
+		dmap->handle = 0;
+		pciba_soft_unlock(soft);
+#if DEBUG_PCIBA
+		printf("pciba: unmapped dma at kaddr 0x%x via handle 0x%x\n",
+		       dmap->kaddr, handle);
+#endif
+		return 0;		/* found userPCI */
+	    }
+	pciba_soft_unlock(soft);
+    }
+    map = pciba_map_pop_hdl(bus, handle);
+    if (map == NULL)
+	return EINVAL;			/* no match */
+
+    if (map->map)
+	pciio_piomap_free(map->map);
+    DEL(map);
+
+    return (0);				/* all done OK */
+}
+
+#if ULI
+void
+pciba_clearuli(struct uli *uli)
+{
+    pciio_intr_t            intr = (pciio_intr_t) uli->teardownarg1;
+
+#if DEBUG_PCIBA
+    printf("pciba_clearuli(0x%x)\n", uli);
+#endif
+
+    pciio_intr_disconnect(intr);
+    pciio_intr_free(intr);
+    atomic_dec(&pciba_prevent_unload);
+}
+
+void
+pciba_intr(intr_arg_t arg)
+{
+    struct uli             *uli = (struct uli *) arg;
+    int                     ulinum = uli->index;
+
+    extern void frs_handle_uli(void);
+
+    if (ulinum >= 0 && ulinum < MAX_ULIS) {
+	    uli_callup(ulinum);
+
+	    if (private.p_frs_flags)
+		    frs_handle_uli();
+    }
+}
+#endif
+#endif /* LATER - undef as we implement each routine */
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/pcibr.c linux/arch/ia64/sn/io/pcibr.c
--- v2.4.3/linux/arch/ia64/sn/io/pcibr.c	Tue Mar  6 19:44:35 2001
+++ linux/arch/ia64/sn/io/pcibr.c	Thu Apr  5 12:51:47 2001
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/config.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <asm/sn/sgi.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
@@ -22,16 +23,17 @@
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
-#include <asm/sn/cmn_err.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/pci/bridge.h>
 #include <asm/sn/prio.h>
 #include <asm/sn/ioerror_handling.h>
 #include <asm/sn/xtalk/xbow.h>
+#include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
 #include <asm/sn/eeprom.h>
 #include <asm/sn/sn1/bedrock.h>
@@ -41,6 +43,14 @@
 #include <asm/sn/sn1/hubio_next.h>
 #endif
 
+#ifdef __ia64
+#define rmallocmap atemapalloc
+#define rmfreemap atemapfree
+#define rmfree atefree
+#define rmalloc atealloc
+#endif
+
+#undef PCIBR_ATE_DEBUG
 #if defined(BRINGUP)
 #if 0
 #define DEBUG 1	 /* To avoid lots of bad printk() formats leave off */
@@ -54,6 +64,24 @@
 #define	LOCAL		static
 #endif
 
+/*
+ * Macros related to the Lucent USS 302/312 usb timeout workaround.  It
+ * appears that if the lucent part can get into a retry loop if it sees a
+ * DAC on the bus during a pio read retry.  The loop is broken after about
+ * 1ms, so we need to set up bridges holding this part to allow at least
+ * 1ms for pio.
+ */
+
+#define USS302_TIMEOUT_WAR
+
+#ifdef USS302_TIMEOUT_WAR
+#include <asm/sn/io.h>
+#define LUCENT_USBHC_VENDOR_ID_NUM	0x11c1
+#define LUCENT_USBHC302_DEVICE_ID_NUM	0x5801
+#define LUCENT_USBHC312_DEVICE_ID_NUM	0x5802
+#define USS302_BRIDGE_TIMEOUT_HLD	4
+#endif
+
 #define PCIBR_LLP_CONTROL_WAR
 #if defined (PCIBR_LLP_CONTROL_WAR)
 int                     pcibr_llp_control_war_cnt;
@@ -69,6 +97,7 @@
 
 int                     pcibr_devflag = D_MP;
 
+#ifdef LATER
 #define F(s,n)		{ 1l<<(s),-(s), n }
 
 struct reg_desc         bridge_int_status_desc[] =
@@ -246,6 +275,7 @@
     {0}
 };
 #endif
+#endif	/* LATER */
 
 /* kbrick widgetnum-to-bus layout */
 int p_busnum[MAX_PORT_NUM] = {                  /* widget#      */
@@ -275,8 +305,8 @@
  * CPU to a particular IO device are synched before the start of the next
  * set of PIO operations to the same device.
  */
-#define pcibr_lock(pcibr_soft)		io_splock(pcibr_soft->bs_lock)
-#define pcibr_unlock(pcibr_soft, s)	io_spunlock(pcibr_soft->bs_lock,s)
+#define pcibr_lock(pcibr_soft)		io_splock(&pcibr_soft->bs_lock)
+#define pcibr_unlock(pcibr_soft,s)	io_spunlock(&pcibr_soft->bs_lock,s)
 
 #if PCIBR_SOFT_LIST
 typedef struct pcibr_list_s *pcibr_list_p;
@@ -302,6 +332,31 @@
 extern int      hub_device_flags_set(devfs_handle_t       widget_dev,
                                      hub_widget_flags_t flags);
 #endif
+extern pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t);
+
+/*
+ * This is the file operation table for the pcibr driver.
+ * As each of the functions are implemented, put the 
+ * appropriate function name below.
+ */
+struct file_operations pcibr_fops = {
+        owner:  THIS_MODULE,
+        llseek: NULL,
+        read: NULL,
+        write: NULL,
+        readdir: NULL,
+        poll: NULL,
+        ioctl: NULL,
+        mmap: NULL,
+        open: NULL,
+        flush: NULL,
+        release: NULL,
+        fsync: NULL,
+        fasync: NULL,
+        lock: NULL,
+        readv: NULL,
+        writev: NULL
+};
 
 extern devfs_handle_t hwgraph_root;
 extern graph_error_t hwgraph_vertex_unref(devfs_handle_t vhdl);
@@ -317,7 +372,7 @@
 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 void cmn_err_tag(int seqnumber, register int level, char *fmt, ...);
+extern int io_path_map_widget(devfs_handle_t vertex);
 
 
 
@@ -363,17 +418,13 @@
 
 void                    pcibr_freeblock_sub(iopaddr_t *, iopaddr_t *, iopaddr_t, size_t);
 
-#ifndef BRINGUP
 LOCAL int               pcibr_init_ext_ate_ram(bridge_t *);
-#endif
 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 int		pcibr_device_attach(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_device_detach(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);
@@ -411,7 +462,7 @@
 
 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_list_func(intr_arg_t);
+void                    pcibr_intr_func(intr_arg_t);
 
 LOCAL void              print_bridge_errcmd(uint32_t, char *);
 
@@ -450,21 +501,32 @@
 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);
+void                    pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, ulong);
 
-LOCAL int		pcibr_slot_reset(devfs_handle_t,pciio_slot_t);
 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);
-LOCAL int		pcibr_slot_call_device_detach(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);
 
-int			pcibr_slot_powerup(devfs_handle_t,pciio_slot_t);
-int			pcibr_slot_shutdown(devfs_handle_t,pciio_slot_t);
-int			pcibr_slot_inquiry(devfs_handle_t,pciio_slot_t);		
+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
@@ -754,7 +816,7 @@
     int                     final_vchan0;
     int                     final_vchan1;
     int                     avail_rrbs;
-    unsigned                s;
+    unsigned long           s;
     int                     error;
 
     /*
@@ -930,7 +992,7 @@
     pciio_info_t            pciio_info;
     pciio_slot_t            pciio_slot;
     pcibr_soft_t            pcibr_soft;
-    unsigned                s;
+    unsigned long           s;
     int                     error = -1;
 
     if ((pciio_info = pciio_info_get(pconn_vhdl)) &&
@@ -978,11 +1040,7 @@
 		     int dev_3_rrbs, int virt3, int dev_4_rrbs, int virt4)
 {
     devfs_handle_t            pcibr_vhdl;
-#ifdef colin
-    pcibr_soft_t            pcibr_soft;
-#else
-    pcibr_soft_t	pcibr_soft = NULL;
-#endif
+    pcibr_soft_t            pcibr_soft = NULL;
     bridge_t               *bridge = NULL;
 
     uint32_t              rrb_setting = 0;
@@ -991,7 +1049,7 @@
     int                     dev_rrbs[4];
     int                     virt[4];
     int                     i, j;
-    unsigned                s;
+    unsigned long           s;
 
     if (GRAPH_SUCCESS ==
 	hwgraph_traverse(vhdl, EDGE_LBL_PCI, &pcibr_vhdl)) {
@@ -1089,7 +1147,7 @@
     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                s;
+    unsigned long           s;
     reg_p                   rrbp;
     unsigned                rrbm;
     int                     i;
@@ -1141,7 +1199,7 @@
     bridgereg_t             badd32;
     bridgereg_t             badd64;
     bridgereg_t             fix;
-    unsigned                s;
+    unsigned long           s;
     bridgereg_t             xmask;
 
     xmask = mask;
@@ -1203,29 +1261,16 @@
     /* Generic macro flags
      */
     if (flags & PCIIO_DMA_DATA) {
-#ifdef colin
-	new = new
-	    & ~BRIDGE_DEV_BARRIER	/* barrier off */
-	    | BRIDGE_DEV_PREF;		/* prefetch on */
-#else
 	new = (new
             & ~BRIDGE_DEV_BARRIER)      /* barrier off */
             | BRIDGE_DEV_PREF;          /* prefetch on */
-#endif
 
     }
     if (flags & PCIIO_DMA_CMD) {
-#ifdef colin
-	new = new
-	    & ~BRIDGE_DEV_PREF		/* prefetch off */
-	    & ~BRIDGE_DEV_WRGA_BITS	/* write gather off */
-	    | BRIDGE_DEV_BARRIER;	/* barrier on */
-#else
         new = ((new
             & ~BRIDGE_DEV_PREF)         /* prefetch off */
             & ~BRIDGE_DEV_WRGA_BITS)    /* write gather off */
             | BRIDGE_DEV_BARRIER;       /* barrier on */
-#endif
     }
     /* Generic detail flags
      */
@@ -1297,13 +1342,8 @@
 	     * but the alternative is not allowing
 	     * the new stream at all.
 	     */
-#ifdef colin
-	    if (fix = bad & (BRIDGE_DEV_PRECISE |
-			     BRIDGE_DEV_BARRIER)) {
-#else
             if ( (fix = bad & (BRIDGE_DEV_PRECISE |
                              BRIDGE_DEV_BARRIER)) ){
-#endif
 		bad &= ~fix;
 		/* don't change these bits if
 		 * they are already set in "old"
@@ -1317,13 +1357,8 @@
 	     * but the alternative is not allowing
 	     * the new stream at all.
 	     */
-#ifdef colin
-	    if (fix = bad & (BRIDGE_DEV_WRGA_BITS |
-			     BRIDGE_DEV_PREF)) {
-#else
 	    if ( (fix = bad & (BRIDGE_DEV_WRGA_BITS |
-			     BRIDGE_DEV_PREF)) ){
-#endif
+			     BRIDGE_DEV_PREF)) ) {
 		bad &= ~fix;
 		/* don't change these bits if
 		 * we wanted to turn them on.
@@ -1379,7 +1414,7 @@
 		     bridgereg_t mask)
 {
     pcibr_soft_slot_t       slotp;
-    unsigned                s;
+    unsigned long           s;
 
     slotp = &pcibr_soft->bs_slot[slot];
 
@@ -1403,7 +1438,7 @@
               pciio_slot_t slot)
 {
     bridge_t               *bridge;
-    unsigned                s;
+    unsigned long          s;
     volatile uint32_t     wrf;
     s = pcibr_lock(pcibr_soft);
     bridge = pcibr_soft->bs_base;
@@ -1429,14 +1464,14 @@
 {
     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;
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#if defined(BRINGUP)
 	/*
 	 * The xbridge doesn't clear b_err_int_view unless
 	 * multi-err is cleared...
@@ -1445,8 +1480,6 @@
 	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
 		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
 	    }
-#endif	/* BRINGUP */
-#endif	/* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
 
     if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) {
 	bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR;
@@ -1454,8 +1487,6 @@
     }
     rv = badaddr_val((void *) cfg, 4, valp);
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#if defined(BRINGUP)
 	/*
 	 * The xbridge doesn't set master timeout in b_int_status
 	 * here.  Fortunately it's in error_interrupt_view.
@@ -1465,8 +1496,6 @@
 		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
 		rv = 1;		/* unoccupied slot */
 	    }
-#endif	/* BRINGUP */
-#endif /* CONFIG_SGI_IP35 */
 
     bridge->b_int_enable = old_enable;
     bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
@@ -1514,10 +1543,6 @@
 int
 pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
 {
-#ifndef CONFIG_IA64_SGI_IO
-    if (!_CAP_CRABLE((uint64_t)credp, (uint64_t)CAP_DEVICE_MGT))
-	return EPERM;
-#endif
     return 0;
 }
 
@@ -1630,42 +1655,10 @@
 
     return slot;
 }
+
 /*==========================================================================
  *	BRIDGE PCI SLOT RELATED IOCTLs
  */
-/*
- * pcibr_slot_powerup
- *	Software initialize the pci slot.
- */
-int
-pcibr_slot_powerup(devfs_handle_t pcibr_vhdl,pciio_slot_t slot)
-{
-    /* Check for the valid slot */
-    if (!PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    if (pcibr_device_attach(pcibr_vhdl,slot))
-	return(EINVAL);
-
-    return(0);
-}
-/*
- * pcibr_slot_shutdown
- *	Software shutdown the pci slot
- */
-int
-pcibr_slot_shutdown(devfs_handle_t pcibr_vhdl,pciio_slot_t slot)
-{
-    /* Check for valid slot */
-    if (!PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    if (pcibr_device_detach(pcibr_vhdl,slot))
-	return(EINVAL);
-
-    return(0);
-}
-
 char *pci_space_name[] = {"NONE", 
 			  "ROM",
 			  "IO",
@@ -1683,177 +1676,163 @@
 			  "",
 			  "BAD"};
 
+
+#ifdef LATER
+
 void
-pcibr_slot_func_info_print(pcibr_info_h pcibr_infoh, int func, int verbose)
+pcibr_slot_func_info_return(pcibr_info_h pcibr_infoh,
+                            int func,
+                            pcibr_slot_func_info_resp_t funcp)
 {
-    pcibr_info_t	pcibr_info = pcibr_infoh[func];
-    char		name[MAXDEVNAME];
-    int			win;
-    
-    if (!pcibr_info)
-	return;
+    pcibr_info_t                 pcibr_info = pcibr_infoh[func];
+    int                          win;
 
+    funcp->resp_f_status = 0;
+
+    if (!pcibr_info) {
+        return;
+    }
+
+    funcp->resp_f_status |= FUNC_IS_VALID;
 #ifdef SUPPORT_PRINTING_V_FORMAT
-    sprintf(name, "%v", pcibr_info->f_vertex);
-#endif
-    if (!verbose) {
-	printk("\tSlot Name : %s\n",name);
-    } else {
-	printk("\tPER-SLOT FUNCTION INFO\n");
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	sprintf(name, "%v", pcibr_info->f_vertex);
+    sprintf(funcp->resp_f_slot_name, "%v", pcibr_info->f_vertex);
+#else
+    sprintf(funcp->resp_f_slot_name, "%x", pcibr_info->f_vertex);
 #endif
-	printk("\tSlot Name : %s\n",name);
-	printk("\tPCI Bus : %d ",pcibr_info->f_bus);
-	printk("Slot : %d ", pcibr_info->f_slot);
-	printk("Function : %d\n", pcibr_info->f_func);
+
+    if(is_sys_critical_vertex(pcibr_info->f_vertex)) {
+        funcp->resp_f_status |= FUNC_IS_SYS_CRITICAL;
+    }
+
+    funcp->resp_f_bus = pcibr_info->f_bus;
+    funcp->resp_f_slot = pcibr_info->f_slot;
+    funcp->resp_f_func = pcibr_info->f_func;
 #ifdef SUPPORT_PRINTING_V_FORMAT
-	sprintf(name, "%v", pcibr_info->f_master);
+    sprintf(funcp->resp_f_master_name, "%v", pcibr_info->f_master);
+#else
+    sprintf(funcp->resp_f_master_name, "%x", pcibr_info->f_master);
 #endif
-	printk("\tBus provider : %s\n",name);
-	printk("\tProvider Fns : 0x%p ", pcibr_info->f_pops);
-	printk("Error Handler : 0x%p Arg 0x%p\n", 
-		pcibr_info->f_efunc,pcibr_info->f_einfo);
+    funcp->resp_f_pops = pcibr_info->f_pops;
+    funcp->resp_f_efunc = pcibr_info->f_efunc;
+    funcp->resp_f_einfo = pcibr_info->f_einfo;
+
+    funcp->resp_f_vendor = pcibr_info->f_vendor;
+    funcp->resp_f_device = pcibr_info->f_device;
+
+    for(win = 0 ; win < 6 ; win++) {
+        funcp->resp_f_window[win].resp_w_base =
+                                  pcibr_info->f_window[win].w_base;
+        funcp->resp_f_window[win].resp_w_size =
+                                  pcibr_info->f_window[win].w_size;
+        sprintf(funcp->resp_f_window[win].resp_w_space,
+                "%s",
+                pci_space_name[pcibr_info->f_window[win].w_space]);
     }
-    printk("\tVendorId : 0x%x " , pcibr_info->f_vendor);
-    printk("DeviceId : 0x%x\n", pcibr_info->f_device);
 
-    printk("\n\tBase Register Info\n");
-    printk("\t\tReg#\tBase\t\tSize\t\tSpace\n");
-    for(win = 0 ; win < 6 ; win++) 
-	printk("\t\t%d\t0x%lx\t%s0x%lx\t%s%s\n",
-		win,
-		pcibr_info->f_window[win].w_base,
-		pcibr_info->f_window[win].w_base >= 0x100000 ? "": "\t",
-		pcibr_info->f_window[win].w_size,
-		pcibr_info->f_window[win].w_size >= 0x100000 ? "": "\t",
-		pci_space_name[pcibr_info->f_window[win].w_space]);
-
-    printk("\t\t7\t0x%x\t%s0x%x\t%sROM\n", 
-	    pcibr_info->f_rbase,
-	    pcibr_info->f_rbase > 0x100000 ? "" : "\t",
-	    pcibr_info->f_rsize,
-	    pcibr_info->f_rsize > 0x100000 ? "" : "\t");
+    funcp->resp_f_rbase = pcibr_info->f_rbase;
+    funcp->resp_f_rsize = pcibr_info->f_rsize;
 
-    printk("\n\tInterrupt Bit Map\n");
-    printk("\t\tPCI Int#\tBridge Pin#\n");
-    for (win = 0 ; win < 4; win++)
-	printk("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]);
-    printk("\n");
-}
+    for (win = 0 ; win < 4; win++) {
+        funcp->resp_f_ibit[win] = pcibr_info->f_ibit[win];
+    }
 
+    funcp->resp_f_att_det_error = pcibr_info->f_att_det_error;
 
-void
-pcibr_slot_info_print(pcibr_soft_t 	pcibr_soft, 
-		      pciio_slot_t 	slot, 
-		      int	   	verbose)
-{
-    pcibr_soft_slot_t	pss;
-    char		slot_conn_name[MAXDEVNAME];
-    int			func;
-    bridge_t		*bridge = pcibr_soft->bs_base;
-    bridgereg_t		b_resp;
-    reg_p		b_respp;
-    int			dev;
-    bridgereg_t		b_int_device;
-    bridgereg_t		b_int_host;
-    bridgereg_t		b_int_enable;
-    int			pin = 0;
-    int			int_bits = 0;
+}
+
+int
+pcibr_slot_info_return(pcibr_soft_t             pcibr_soft,
+                       pciio_slot_t             slot,
+                       pcibr_slot_info_resp_t   respp)
+{
+    pcibr_soft_slot_t            pss;
+    int                          func;
+    bridge_t                    *bridge = pcibr_soft->bs_base;
+    reg_p                        b_respp;
+    pcibr_slot_info_resp_t       slotp;
+    pcibr_slot_func_info_resp_t  funcp;
+
+    slotp = kmem_zalloc(sizeof(*slotp), KM_SLEEP);
+    if (slotp == NULL) {
+        return(ENOMEM);
+    }
 
     pss = &pcibr_soft->bs_slot[slot];
     
     printk("\nPCI INFRASTRUCTURAL INFO FOR SLOT %d\n\n", slot);
 
-    if (verbose) {
-	printk("\tHost Present ? %s ", pss->has_host ? "yes" : "no");
-	printk("\tHost Slot : %d\n",pss->host_slot);
+    slotp->resp_has_host = pss->has_host;
+    slotp->resp_host_slot = pss->host_slot;
 #ifdef SUPPORT_PRINTING_V_FORMAT
-	sprintf(slot_conn_name, "%v", pss->slot_conn);
+    sprintf(slotp->resp_slot_conn_name, "%v", pss->slot_conn);
+#else
+    sprintf(slotp->resp_slot_conn_name, "%x", pss->slot_conn);
 #endif
-	printk("\tSlot Conn : %s\n",slot_conn_name);	
-	printk("\t#Functions : %d\n",pss->bss_ninfo);
+    slotp->resp_slot_status = pss->slot_status;
+    slotp->resp_l1_bus_num = io_path_map_widget(pcibr_soft->bs_vhdl);
+
+    if (is_sys_critical_vertex(pss->slot_conn)) {
+        slotp->resp_slot_status |= SLOT_IS_SYS_CRITICAL;
     }
-    for (func = 0; func < pss->bss_ninfo; func++)
-	pcibr_slot_func_info_print(pss->bss_infos,func, verbose);
-    printk("\tDevio[Space:%s,Base:0x%lx,Shadow:0x%x]\n",
-	    pci_space_name[pss->bss_devio.bssd_space],
-	    pss->bss_devio.bssd_base,
-	    pss->bss_device);
-
-    if (verbose) {
-	printk("\tUsage counts : pmu %d d32 %d d64 %d\n",
-		pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr);
-    
-	printk("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x"
-		"d32_base 0x%x d32_flags 0x%x\n",
-		(unsigned int)pss->bss_d64_base, pss->bss_d64_flags,
-		(unsigned int)pss->bss_d32_base, pss->bss_d32_flags);
-    
-	printk("\tExt ATEs active ? %s", 
-		pss->bss_ext_ates_active ? "yes" : "no");
-	printk(" Command register : 0x%p ", pss->bss_cmd_pointer);
-	printk(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow);
+
+    slotp->resp_bss_ninfo = pss->bss_ninfo;
+
+    for (func = 0; func < pss->bss_ninfo; func++) {
+        funcp = &(slotp->resp_func[func]);
+        pcibr_slot_func_info_return(pss->bss_infos, func, funcp);
     }
 
-    printk("\tSoft RRB 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]);
+    sprintf(slotp->resp_bss_devio_bssd_space, "%s",
+            pci_space_name[pss->bss_devio.bssd_space]);
+    slotp->resp_bss_devio_bssd_base = pss->bss_devio.bssd_base;
+    slotp->resp_bss_device = pss->bss_device;
 
+    slotp->resp_bss_pmu_uctr = pss->bss_pmu_uctr;
+    slotp->resp_bss_d32_uctr = pss->bss_d32_uctr;
+    slotp->resp_bss_d64_uctr = pss->bss_d64_uctr;
 
-    if (slot & 1)
-	b_respp = &bridge->b_odd_resp;
-    else
-	b_respp = &bridge->b_even_resp;
+    slotp->resp_bss_d64_base = pss->bss_d64_base;
+    slotp->resp_bss_d64_flags = pss->bss_d64_flags;
+    slotp->resp_bss_d32_base = pss->bss_d32_base;
+    slotp->resp_bss_d32_flags = pss->bss_d32_flags;
 
-    b_resp = *b_respp;
+    slotp->resp_bss_ext_ates_active = atomic_read(&pss->bss_ext_ates_active);
 
-    printk("\n\tBridge RRB Info\n");
-    printk("\t\tRRB#\tVirtual\n");
-    for (dev = 0; dev < 8; dev++) {
-	if ((b_resp & BRIDGE_RRB_EN) &&
-	    (b_resp & BRIDGE_RRB_PDEV) == (slot >> 1))
-	    printk( "\t\t%d\t%s\n", 
-		    dev,
-		    (b_resp & BRIDGE_RRB_VDEV) ? "yes" : "no");
-	b_resp >>= 4;
-	    
-    }
-    b_int_device = bridge->b_int_device;
-    b_int_enable = bridge->b_int_enable;
+    slotp->resp_bss_cmd_pointer = pss->bss_cmd_pointer;
+    slotp->resp_bss_cmd_shadow = pss->bss_cmd_shadow;
 
-    printk("\n\tBridge Interrupt Info\n"
-	    "\t\tInt_device 0x%x\n\t\tInt_enable 0x%x "
-	    "\n\t\tEnabled pin#s for this slot: ",
-	    b_int_device,
-	    b_int_enable);
+    slotp->resp_bs_rrb_valid = pcibr_soft->bs_rrb_valid[slot];
+    slotp->resp_bs_rrb_valid_v = pcibr_soft->bs_rrb_valid[slot +
+                                                      PCIBR_RRB_SLOT_VIRTUAL];
+    slotp->resp_bs_rrb_res = pcibr_soft->bs_rrb_res[slot];
 
-    while (b_int_device) {
-	if (((b_int_device & 7) == slot) &&
-	    (b_int_enable & (1 << pin))) {
-	    int_bits |= (1 << pin);
-	    printk("%d ", pin); 
-	}
-	pin++;
-	b_int_device >>= 3;
+    if (slot & 1) {
+        b_respp = &bridge->b_odd_resp;
+    } else {
+        b_respp = &bridge->b_even_resp;
     }
 
-    if (!int_bits)
-	printk("NONE ");
+    slotp->resp_b_resp = *b_respp;
 
-    b_int_host = bridge->b_int_addr[slot].addr;
+    slotp->resp_b_int_device = bridge->b_int_device;
+    slotp->resp_b_int_enable = bridge->b_int_enable;
+    slotp->resp_b_int_host = bridge->b_int_addr[slot].addr;
 
-    printk("\n\t\tInt_host_addr 0x%x\n",
-	    b_int_host);
-    
+    if (COPYOUT(slotp, respp, sizeof(*respp))) {
+        return(EFAULT);
+    }
+
+    kmem_free(slotp, sizeof(*slotp));
+
+    return(0);
 }
 
-int verbose = 0;
 /*
- * pcibr_slot_inquiry
- *	Print information about the pci slot maintained by the infrastructure.
- *	Current information displayed
+ * pcibr_slot_query
+ *	Return information about the PCI slot maintained by the infrastructure.
+ *	Information is requested in the request structure.
+ *
+ *      Information returned in the response structure:
  *		Slot hwgraph name
  *		Vendor/Device info
  *		Base register info
@@ -1861,7 +1840,6 @@
  *		Devio register
  *		Software RRB info
  *		RRB register info
- *	In verbose mode following additional info is displayed
  *		Host/Gues info
  *		PCI Bus #,slot #, function #
  *		Slot provider hwgraph name
@@ -1872,28 +1850,76 @@
  *		External SSRAM workaround info
  */
 int
-pcibr_slot_inquiry(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
+pcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_info_req_t reqp)
 {
-    pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    pciio_slot_t            slot = reqp->req_slot;
+    pciio_slot_t            tmp_slot;
+    pcibr_slot_info_resp_t  respp = (pcibr_slot_info_resp_t) reqp->req_respp;
+    int                     size = reqp->req_size;
+    int                     error;
 
     /* Make sure that we are dealing with a bridge device vertex */
-    if (!pcibr_soft)
-	return(EINVAL);
+    if (!pcibr_soft) {
+        return(EINVAL);
+    }
 
-    /* Make sure that we have a valid pci slot number or PCIIO_SLOT_NONE */
-    if ((!PCIBR_VALID_SLOT(slot)) && (slot != PCIIO_SLOT_NONE))
-	return(EINVAL);
+    /* Make sure that we have a valid PCI slot number or PCIIO_SLOT_NONE */
+    if ((!PCIBR_VALID_SLOT(slot)) && (slot != PCIIO_SLOT_NONE)) {
+        return(EINVAL);
+    }
 
-    /* Print information for the requested pci slot */
+#ifdef LATER
+    /* Do not allow a query of a slot in a shoehorn */
+    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
+       return(EPERM);
+    }
+#endif
+
+    /* Return information for the requested PCI slot */
     if (slot != PCIIO_SLOT_NONE) {
-	pcibr_slot_info_print(pcibr_soft,slot,verbose);
-	return(0);
+        if (size < sizeof(*respp)) {
+            return(EINVAL);
+        }
+
+        /* Acquire read access to the slot */
+        mrlock(pcibr_soft->bs_slot[slot].slot_lock, MR_ACCESS, PZERO);
+
+        error = pcibr_slot_info_return(pcibr_soft, slot, respp);
+
+        /* Release the slot lock */
+        mrunlock(pcibr_soft->bs_slot[slot].slot_lock);
+
+        return(error);
     }
-    /* Print information for all the slots */
-    for (slot = 0; slot < 8; slot++)
-	pcibr_slot_info_print(pcibr_soft, slot,verbose);
-    return(0);
+
+    /* Return information for all the slots */
+    for (tmp_slot = 0; tmp_slot < 8; tmp_slot++) {
+
+        if (size < sizeof(*respp)) {
+            return(EINVAL);
+        }
+
+        /* Acquire read access to the slot */
+        mrlock(pcibr_soft->bs_slot[tmp_slot].slot_lock, MR_ACCESS, PZERO);
+
+        error = pcibr_slot_info_return(pcibr_soft, tmp_slot, respp);
+
+        /* Release the slot lock */
+        mrunlock(pcibr_soft->bs_slot[tmp_slot].slot_lock);
+
+        if (error) {
+            return(error);
+        }
+
+        ++respp;
+        size -= sizeof(*respp);
+    }
+
+    return(error);
 }
+#endif	/* LATER */
+
 
 /*ARGSUSED */
 int
@@ -1905,7 +1931,7 @@
 	    int *rvalp)
 {
     devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t)dev);
-#ifdef colin
+#ifdef LATER
     pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
 #endif
     int                     error = 0;
@@ -1913,7 +1939,7 @@
     hwgraph_vertex_unref(pcibr_vhdl);
 
     switch (cmd) {
-#ifdef colin
+#ifdef LATER
     case GIOCSETBW:
 	{
 	    grio_ioctl_info_t       info;
@@ -1969,7 +1995,6 @@
 		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_LOW);
 	    break;
 	}
-#endif /* colin */
 
     case PCIBR_SLOT_POWERUP:
 	{
@@ -1985,31 +2010,33 @@
 	    break;
 	}
     case PCIBR_SLOT_SHUTDOWN:
-	{
-	    pciio_slot_t	slot;
-
 	    if (!cap_able(CAP_DEVICE_MGT)) {
 		error = EPERM;
 		break;
 	    }
 
 	    slot = (pciio_slot_t)(uint64_t)arg;
-	    error = pcibr_slot_shutdown(pcibr_vhdl,slot);
+	    error = pcibr_slot_powerup(pcibr_vhdl,slot);
 	    break;
 	}
-    case PCIBR_SLOT_INQUIRY:
+    case PCIBR_SLOT_QUERY:
 	{
-	    pciio_slot_t	slot;
+	    struct pcibr_slot_info_req_s        req;
 
 	    if (!cap_able(CAP_DEVICE_MGT)) {
 		error = EPERM;
 		break;
 	    }
 
-	    slot = (pciio_slot_t)(uint64_t)arg;
-	    error = pcibr_slot_inquiry(pcibr_vhdl,slot);
+            if (COPYIN(arg, &req, sizeof(req))) {
+                error = EFAULT;
+                break;
+            }
+
+            error = pcibr_slot_query(pcibr_vhdl, &req);
 	    break;
 	}
+#endif	/* LATER */
     default:
 	break;
 
@@ -2055,7 +2082,6 @@
 	*free_basep = last + 1;		/* keep upper chunk */
 }
 
-#ifdef IRIX
 /* Convert from ssram_bits in control register to number of SSRAM entries */
 #define ATE_NUM_ENTRIES(n) _ate_info[n]
 
@@ -2070,14 +2096,12 @@
 
 #define ATE_NUM_SIZES (sizeof(_ate_info) / sizeof(int))
 #define ATE_PROBE_VALUE 0x0123456789abcdefULL
-#endif	/* IRIX */
 
 /*
  * 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.
  */
-#ifndef BRINGUP
 LOCAL int
 pcibr_init_ext_ate_ram(bridge_t *bridge)
 {
@@ -2087,9 +2111,6 @@
     bridgereg_t             old_enable, new_enable;
     int                     s;
 
-    if (is_xbridge(bridge))
-	return 0;
-
     /* Probe SSRAM to determine its size. */
     old_enable = bridge->b_int_enable;
     new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
@@ -2116,11 +2137,9 @@
      */
 
     s = splhi();
-#ifdef colin
     bridge->b_wid_control = (bridge->b_wid_control
 	& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
 	| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
-#endif
     bridge->b_wid_control;		/* inval addr bug war */
     splx(s);
 
@@ -2139,7 +2158,6 @@
 
     return (num_entries);
 }
-#endif	/* !BRINGUP */
 
 /*
  * Allocate "count" contiguous Bridge Address Translation Entries
@@ -2155,6 +2173,7 @@
     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);
@@ -2174,6 +2193,8 @@
     /* 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,
@@ -2233,8 +2254,6 @@
 	/*
 	 * Record the info in the sparse func info space.
 	 */
-printk("pcibr_device_info_new: slot= %d  func= %d  bss_ninfo= %d  pcibr_info= 0x%p\n", slot, func, pcibr_soft->bs_slot[slot].bss_ninfo, pcibr_info);
-
 	if (func < pcibr_soft->bs_slot[slot].bss_ninfo)
 	    pcibr_soft->bs_slot[slot].bss_infos[func] = pcibr_info;
     }
@@ -2281,7 +2300,7 @@
     slotp->bss_d32_flags = 0;
 
     /* Clear out shadow info necessary for the external SSRAM workaround */
-    slotp->bss_ext_ates_active = 0;
+    slotp->bss_ext_ates_active = ATOMIC_INIT(0);
     slotp->bss_cmd_pointer = 0;
     slotp->bss_cmd_shadow = 0;
 
@@ -2336,55 +2355,10 @@
 	   pcibr_soft->bs_spinfo.pci_mem_last);
 
 /*
- * pcibr_slot_reset
- *	Reset the pci device in the particular slot .
- */
-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_VALID_SLOT(slot))
-		return(1);
-
-	if (!pcibr_soft)
-		return(1);
-
-	/* 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);
-}
-/*
  * 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.
+ *	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,
@@ -2401,6 +2375,9 @@
     pciio_vendor_id_t       vendor;
     pciio_device_id_t       device;
     unsigned                htype;
+#if !defined(CONFIG_IA64_SGI_SN1)
+    int			    nbars;
+#endif
     cfg_p                   wptr;
     int                     win;
     pciio_space_t           space;
@@ -2416,40 +2393,41 @@
     /* Get the basic software information required to proceed */
     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     if (!pcibr_soft)
-	return(1);
+	return(EINVAL);
 
     bridge = pcibr_soft->bs_base;
     if (!PCIBR_VALID_SLOT(slot))
-	return(1);
-
-    slotp = &pcibr_soft->bs_slot[slot];
-
-    /* Load the current values of allocated pci address spaces */
-    PCI_ADDR_SPACE_LIMITS_LOAD();
+	return(EINVAL);
 
-    /* If we have a host slot (eg:- IOC3 has 2 pci slots and the initialization
+    /* 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);
+    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;
 
-#ifdef BRINGUP
-    if (slot < 3  || slot == 7) 
-	return (0);
-    else
-#endif /* BRINGUP */
-    if (pcibr_probe_slot(bridge, cfgw, &idword))
-	return(0);
+    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(0);			/* next slot */
+    if (vendor == 0xFFFF) 
+	return(ENODEV);			
     
     device = 0xFFFF & (idword >> 16);
     htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
@@ -2503,7 +2481,13 @@
 	if (htype != 0x00) {
 	    PRINT_WARNING("%s pcibr: pci slot %d func %d has strange header type 0x%x\n",
 		    pcibr_soft->bs_name, slot, func, htype);
+#if defined(CONFIG_IA64_SGI_SN1)
 	    continue;
+#else
+	    nbars = 2;
+	} else {
+	    nbars = PCI_CFG_BASE_ADDRS;
+#endif
 	}
 #if DEBUG && ATTACH_DEBUG
 	PRINT_NOTICE( 
@@ -2516,13 +2500,17 @@
 	conn_vhdl = pciio_device_info_register(pcibr_vhdl, &pcibr_info->f_c);
 	if (func == 0)
 	    slotp->slot_conn = conn_vhdl;
-	
+
 	cmd_reg = cfgw[PCI_CFG_COMMAND / 4];
 	
 	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
 
-
-	for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win) {
+#if defined(CONFIG_IA64_SGI_SN1)
+	for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win)
+#else
+	for (win = 0; win < nbars; ++win)
+#endif
+	{
 	    iopaddr_t               base, mask, code;
 	    size_t                  size;
 
@@ -2573,9 +2561,9 @@
 	    base = wptr[((win*4)^4)/4];
 #else
 	    base = wptr[win];
-#endif /* LITTLE_ENDIAN */
+#endif
 
-	    if (base & 1) {
+	    if (base & PCI_BA_IO_SPACE) {
 		/* BASE is in I/O space. */
 		space = PCIIO_SPACE_IO;
 		mask = -4;
@@ -2590,7 +2578,7 @@
 		/* BASE is in MEM space. */
 		space = PCIIO_SPACE_MEM;
 		mask = -16;
-		code = base & 15;
+		code = base & PCI_BA_MEM_LOCATION;	/* extract BAR type */
 		base = base & mask;
 		if (base == 0) {
 		    ;		/* not assigned */
@@ -2697,37 +2685,30 @@
 	}				/* next win */
     }				/* next func */
 
-    /* Store back the values for allocated pci address spaces */
+    /* 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.
+ *	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_slot_info_free(devfs_handle_t pcibr_vhdl,
+                     pciio_slot_t slot)
 {
     pcibr_soft_t	pcibr_soft;
     pcibr_info_h	pcibr_infoh;
     int			nfunc;
-#if defined(PCI_HOTSWAP_DEBUG)
-    cfg_p		cfgw;
-    bridge_t		*bridge;
-    int			win;
-    cfg_p		wptr;
-#endif /* PCI_HOTSWAP_DEBUG */
-
-    
 
     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
     if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(1);
+	return(EINVAL);
 
-#if defined(PCI_HOTSWAP_DEBUG)
+#if !defined(CONFIG_IA64_SGI_SN1)
     /* Clean out all the base registers */
     bridge = pcibr_soft->bs_base;
     cfgw = bridge->b_type0_cfg_dev[slot].l;
@@ -2739,7 +2720,7 @@
 #else
 	wptr[win] = 0;
 #endif  /* LITTLE_ENDIAN */
-#endif /* PCI_HOTSWAP_DEBUG */
+#endif	/* !CONFIG_IA64_SGI_SN1 */
 
     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
 
@@ -2750,13 +2731,12 @@
     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 
+ *	Reserve chunks of PCI address space as required by 
  * 	the base registers in the card.
  */
 int
@@ -2772,38 +2752,40 @@
     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(1);
+	return(EINVAL);
 
     bridge = pcibr_soft->bs_base;
 
-    /* Get the current values for the allocated pci address spaces */
+    /* Get the current values for the allocated PCI address spaces */
     PCI_ADDR_SPACE_LIMITS_LOAD();
 
     if (as_debug)
-#ifdef colin
+#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)
+    if (pcibr_soft->bs_slot[slot].has_host) {
 	return(0);
+    }
 
     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
     if (nfunc < 1)
-	return(0);
+	return(EINVAL);
 
     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
     if (!pcibr_infoh)
-	return(0);
+	return(EINVAL);
 
     /*
      * Try to make the DevIO windows not
@@ -2842,7 +2824,16 @@
 	cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
 	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
 
-	for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win) {
+#if defined(CONFIG_IA64_SGI_SN1)
+	nbars = PCI_CFG_BASE_ADDRS;
+#else
+	if ((do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1) & 0x7f) != 0)
+	    nbars = 2;
+	else
+	    nbars = PCI_CFG_BASE_ADDRS;
+#endif
+
+	for (win = 0; win < nbars; ++win) {
 
 	    space = pcibr_info->f_window[win].w_space;
 	    base = pcibr_info->f_window[win].w_base;
@@ -2908,7 +2899,9 @@
 	    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 */
@@ -2976,7 +2969,22 @@
 	 * be sure are set.
 	 */
 	pci_cfg_cmd_reg_add |= PCI_CMD_IO_SPACE;
-	pci_cfg_cmd_reg_add |= PCI_CMD_MEM_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;
@@ -2991,28 +2999,30 @@
 	
     }				/* next func */
 
-    /* Now that we have allocated new chunks of pci address spaces to this
+    /* 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.
+     * 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.
+ * 	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_slot_device_init(devfs_handle_t pcibr_vhdl,
+		       pciio_slot_t slot)
 {
-    pcibr_soft_t	pcibr_soft;
+    pcibr_soft_t	 pcibr_soft;
     bridge_t		*bridge;
-    bridgereg_t		devreg;
+    bridgereg_t		 devreg;
 
     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
     if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(1);
+	return(EINVAL);
 
     bridge = pcibr_soft->bs_base;
 
@@ -3036,13 +3046,13 @@
 #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.
+ *	Setup the host/guest relations for a PCI slot.
  */
 int
 pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,
@@ -3056,7 +3066,7 @@
     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
 
     if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(1);
+	return(EINVAL);
 
     slotp = &pcibr_soft->bs_slot[slot];
 
@@ -3103,17 +3113,17 @@
 
     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
+ * 	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_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl,
+			     pciio_slot_t slot)
 {
     pcibr_soft_t	pcibr_soft;
     pcibr_info_h	pcibr_infoh;
@@ -3123,16 +3133,17 @@
     int			r;
 
     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+
     if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(1);
+	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
@@ -3149,7 +3160,7 @@
 	    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(0);
+	return(ENODEV);
     }
 
     pcibr_soft->bs_rrb_avail[slot & 1] -= c0 + c1;
@@ -3173,17 +3184,19 @@
 	    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
+ *	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)
+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;
@@ -3192,14 +3205,19 @@
     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(1);
+	return(EINVAL);
 
 
-    if (pcibr_soft->bs_slot[slot].has_host)
-        return(0);
+    if (pcibr_soft->bs_slot[slot].has_host) {
+        return(EPERM);
+    }
     
     xconn_vhdl = pcibr_soft->bs_conn;
     aa = async_attach_get_info(xconn_vhdl);
@@ -3207,8 +3225,6 @@
     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
 
-    printk("\npcibr_slot_call_device_attach: link 0x%p pci bus 0x%p slot %d\n", xconn_vhdl, pcibr_vhdl, slot);
-
     for (func = 0; func < nfunc; ++func) {
 
 	pcibr_info = pcibr_infoh[func];
@@ -3221,51 +3237,77 @@
 
 	conn_vhdl = pcibr_info->f_vertex;
 
-	/* If the pci device has been disabled in the prom,
+	/* If the PCI device has been disabled in the prom,
 	 * do not set it up for driver attach. NOTE: usrpci
 	 * and pciba will not "see" this connection point!
 	 */
 	if (device_admin_info_get(conn_vhdl, ADMIN_LBL_DISABLED)) {
 #ifdef SUPPORT_PRINTING_V_FORMAT
-	    PRINT_WARNING( "pcibr_slot_call_device_attach: %v disabled\n", 
+	    PRINT_WARNING("pcibr_slot_call_device_attach: %v disabled\n", 
 		    conn_vhdl);
 #endif
 	    continue;
 	}
+#ifdef LATER
+	/*
+	 * Activate if and when we support cdl.
+	 */
 	if (aa)
 	    async_attach_add_info(conn_vhdl, aa);
-	pciio_device_attach(conn_vhdl);
-    }				/* next func */
+#endif	/* LATER */
 
-    printk("\npcibr_slot_call_device_attach: DONE\n");
+	error_func = pciio_device_attach(conn_vhdl, drv_flags);
 
-    return(0);
+        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
+ *	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)
+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;
+    devfs_handle_t	conn_vhdl = GRAPH_VERTEX_NONE;
     int			nfunc;
-    int			ndetach = 1;
+    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(1);
 
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+	return(EINVAL);
 
     if (pcibr_soft->bs_slot[slot].has_host)
-        return(0);
-    
+        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;
@@ -3281,94 +3323,120 @@
 	    continue;
 
 	conn_vhdl = pcibr_info->f_vertex;
-	
-	/* Make sure that we do not detach a system critical device
-	 * vertex.
-	 */
-	if (is_sys_critical_vertex(conn_vhdl)) {
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	    PRINT_WARNING( "%v is a system critical device vertex\n",
-		    conn_vhdl);
-#endif
-	    continue;
-	}
-	
-	ndetach = 0;
-	pciio_device_detach(conn_vhdl);
+
+	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;
 
-    return(ndetach);
+    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_device_attach
+ * pcibr_slot_detach
  *	This is a place holder routine to keep track of all the
- *	slot-specific initialization that needs to be done.
- *	This is usually called when we want to initialize a new
- * 	pci card on the bus.
+ *	slot-specific freeing that needs to be done.
  */
 int
-pcibr_device_attach(devfs_handle_t 	pcibr_vhdl,
-		    pciio_slot_t	slot)
+pcibr_slot_detach(devfs_handle_t pcibr_vhdl,
+		  pciio_slot_t slot,
+		  int          drv_flags)
 {
-    return (
-	    /* Reset the slot */
-	    pcibr_slot_reset(pcibr_vhdl,slot)			||
-	    /* FInd out what is out there */
-	    pcibr_slot_info_init(pcibr_vhdl,slot)		||
-
-	    /* Set up the address space for this slot in the pci land */
-	    pcibr_slot_addr_space_init(pcibr_vhdl,slot) 	||
-
-	    /* Setup the device register */
-	    pcibr_slot_device_init(pcibr_vhdl, slot)		||
-
-	    /* Setup host/guest relations */
-	    pcibr_slot_guest_info_init(pcibr_vhdl,slot)		||
-
-	    /* Initial RRB management */
-	    pcibr_slot_initial_rrb_alloc(pcibr_vhdl,slot)	||
-
-	    /* Call the device attach */
-	    pcibr_slot_call_device_attach(pcibr_vhdl,slot)
-	    );
+    int		  error;
+    
+    /* Call the device detach function */
+    error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags));
+    return (error);
 
 }
+
 /*
- * pcibr_device_detach
- *	This is a place holder routine to keep track of all the
- *	slot-specific freeing that needs to be done.
+ * 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_device_detach(devfs_handle_t 	pcibr_vhdl,
-		    pciio_slot_t	slot)
+pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl,
+                      pciio_slot_t slot)
 {
-    
-    /* Call the device detach */
-    return (pcibr_slot_call_device_detach(pcibr_vhdl,slot));
+    pcibr_soft_t        pcibr_soft;
+    pcibr_info_h        pcibr_infoh;
+    pcibr_info_t        pcibr_info;
+    devfs_handle_t        conn_vhdl = GRAPH_VERTEX_NONE;
+    int                 nfunc;
+    int                 func;
+
+    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
+        return(0);
+
+    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
+    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
+
+    for (func = 0; func < nfunc; ++func) {
+
+        pcibr_info = pcibr_infoh[func];
+        if (!pcibr_info)
+            continue;
+
+        if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
+            continue;
+
+        conn_vhdl = pcibr_info->f_vertex;
+        if (is_sys_critical_vertex(conn_vhdl)) { 
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+            PRINT_WARNING("%v is a system critical device vertex\n", conn_vhdl);
+#else
+            PRINT_WARNING("%p is a system critical device vertex\n", conn_vhdl);
+#endif
+            return(1); 
+        }
+
+    }
 
+    return(0);
 }
+
 /*
  * pcibr_device_unregister
- *	This frees up any hardware resources reserved for this pci device
- * 	and removes any pci infrastructural information setup for it.
- *	This is usually used at the time of shutting down of the pci card.
+ *	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.
  */
-void
+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;
+    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);
 
-    /* Detach the pciba name space */
-    pciio_device_detach(pconn_vhdl);
-
     pcibr_vhdl = pciio_info_master_get(pciio_info);
     slot = pciio_info_slot_get(pciio_info);
 
@@ -3382,19 +3450,31 @@
     pcibr_rrb_flush(pconn_vhdl);
 
     /* Free the rrbs allocated to this slot */
-    do_pcibr_rrb_free(bridge, slot, 
-		      pcibr_soft->bs_rrb_valid[slot] +
-		      pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL]);
+    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 !! */
-    (void)pcibr_wrb_flush(pconn_vhdl);
+    error_call = pcibr_wrb_flush(pconn_vhdl);
+
+    if (error_call)
+        error = error_call;
+
     /* Clear the information specific to the slot */
-    (void)pcibr_slot_info_free(pcibr_vhdl, slot);
+    error_call = pcibr_slot_info_free(pcibr_vhdl, slot);
+
+    if (error_call)
+        error = error_call;
+
+    return(error);
     
 }
 
@@ -3467,6 +3547,7 @@
 	return (rv == GRAPH_SUCCESS);
 }
 
+
 /*
  *    pcibr_attach: called every time the crosstalk
  *      infrastructure is asked to initialize a widget
@@ -3502,11 +3583,15 @@
     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;
 
@@ -3542,8 +3627,6 @@
 	NeedXbridgeSwap = 1;
 #endif
 
-	printk("pcibr_attach: Called with vertex 0x%p, b_wid_stat 0x%x, gio 0x%x\n",xconn_vhdl, bridge->b_wid_stat, BRIDGE_STAT_PCI_GIO_N);
-
     /*
      * Create the vertex for the PCI bus, which we
      * will also use to hold the pcibr_soft and
@@ -3558,8 +3641,14 @@
     rc = hwgraph_path_add(xconn_vhdl, EDGE_LBL_PCI, &pcibr_vhdl);
     ASSERT(rc == GRAPH_SUCCESS);
 
-    rc = hwgraph_char_device_add(pcibr_vhdl, EDGE_LBL_CONTROLLER, "pcibr_", &ctlr_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
@@ -3606,6 +3695,10 @@
 	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
@@ -3660,7 +3753,7 @@
     /*
      * Init bridge lock.
      */
-    spinlock_init(&pcibr_soft->bs_lock, "pcibr_loc");
+    spin_lock_init(&pcibr_soft->bs_lock);
 
     /*
      * If we have one, process the hints structure.
@@ -3691,12 +3784,18 @@
 	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 = 0;
+	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_list = 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;
     }
 
     /*
@@ -3733,7 +3832,7 @@
 	iopaddr_t               xbase;
 	xwidgetnum_t            xport;
 	iopaddr_t               offset;
-	int                     num_entries;
+	int                     num_entries = 0;
 	int                     entry;
 	cnodeid_t		cnodeid;
 	nasid_t			nasid;
@@ -3801,10 +3900,6 @@
 
 	    dirmap = xport << BRIDGE_DIRMAP_W_ID_SHFT;
 
-#ifdef IRIX
-	    dirmap |= BRIDGE_DIRMAP_RMF_64;
-#endif
-
 	    if (xbase)
 		dirmap |= BRIDGE_DIRMAP_OFF & xbase;
 	    else if (offset >= (512 << 20))
@@ -3855,15 +3950,10 @@
 	 * recomparing against BRIDGE_INTERNAL_ATES every
 	 * time.
 	 */
-#ifdef BRINGUP
-	/*
-	 * 082799: for some reason pcibr_init_ext_ate_ram is causing
-	 * a Data Bus Error.  It should be zero anyway so just force it.
-	 */
-	num_entries = 0;
-#else
-	num_entries = pcibr_init_ext_ate_ram(bridge);
-#endif
+	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.
@@ -3947,7 +4037,6 @@
 
     pcibr_soft->bsi_err_intr = xtalk_intr;
 
-#if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
     /*
      * On IP35 with XBridge, we do some extra checks in pcibr_setwidint
      * in order to work around some addressing limitations.  In order
@@ -3955,9 +4044,6 @@
      * start from a known clean state.
      */
     pcibr_clearwidint(bridge);
-#endif
-
-    printk("pribr_attach:  FIXME Error Interrupt not registered\n");
 
     xtalk_intr_connect(xtalk_intr,
 		       (intr_func_t) pcibr_error_intr_handler,
@@ -4054,13 +4140,13 @@
     }
 #endif
 
-#ifdef IRIX
+#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);
+	(void)pcibr_slot_reset(pcibr_vhdl, slot);
 #endif
 
     for (slot = 0; slot < 8; ++slot)
@@ -4075,6 +4161,7 @@
 	/* Setup the device register */
 	(void)pcibr_slot_device_init(pcibr_vhdl, slot);
 
+#ifndef __ia64
 #if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
     for (slot = 0; slot < 8; ++slot)  
 	/* Set up convenience links */
@@ -4082,6 +4169,7 @@
 		if (pcibr_soft->bs_slot[slot].bss_ninfo > 0) /* if occupied */
 			pcibr_bus_cnvlink(pcibr_info->f_vertex, slot);
 #endif
+#endif
 
     for (slot = 0; slot < 8; ++slot)  
 	/* Setup host/guest relations */
@@ -4091,12 +4179,34 @@
 	/* Initial RRB management */
 	(void)pcibr_slot_initial_rrb_alloc(pcibr_vhdl,slot);
 
-#ifdef dagum
     /* 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);
-#endif /* dagum */
+	(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)) {
@@ -4119,13 +4229,13 @@
 #endif
     }
 #else
-	printk("pcibr_attach: FIXME to call do_pcibr_rrb_autoalloc nicinfo 0x%p\n", nicinfo);
+	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);
+    pciio_device_attach(noslot_conn, 0);
 
 
     /* 
@@ -4166,14 +4276,14 @@
 	printk("pcibr_device_detach called for %p/%d\n",
 		pcibr_vhdl,slot);
 #endif
-	pcibr_device_detach(pcibr_vhdl, slot);
+	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));
 
-    spinlock_destroy(&pcibr_soft->bs_lock);
+    spin_lock_destroy(&pcibr_soft->bs_lock);
     kfree(pcibr_soft->bs_name);
     
     /* Error handler gets unregistered when the widget info is 
@@ -4264,7 +4374,7 @@
     size_t                  msize;	/* size of devio(x) mapped area on PCI */
     size_t                  mmask;	/* addr bits stored in Device(x) */
 
-    unsigned                s;
+    unsigned long           s;
 
     s = pcibr_lock(pcibr_soft);
 
@@ -4327,7 +4437,7 @@
 	if (wspace == PCIIO_SPACE_NONE)
 	    goto done;
 
-	/* get pci base and size */
+	/* get PCI base and size */
 	wbase = pcibr_info->f_window[bar].w_base;
 	wsize = pcibr_info->f_window[bar].w_size;
 
@@ -4587,7 +4697,7 @@
     pcibr_piomap_t          pcibr_piomap;
     iopaddr_t               xio_addr;
     xtalk_piomap_t          xtalk_piomap;
-    unsigned                s;
+    unsigned long           s;
 
     /* Make sure that the req sizes are non-zero */
     if ((req_size < 1) || (req_size_max < 1))
@@ -4631,7 +4741,7 @@
     pcibr_piomap->bp_pciaddr = pci_addr;
     pcibr_piomap->bp_mapsz = req_size;
     pcibr_piomap->bp_soft = pcibr_soft;
-    pcibr_piomap->bp_toc[0] = 0;
+    pcibr_piomap->bp_toc[0] = ATOMIC_INIT(0);
 
     if (mapptr) {
 	s = pcibr_lock(pcibr_soft);
@@ -4733,7 +4843,7 @@
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
 
     pciio_piospace_t        piosp;
-    int                     s;
+    unsigned long           s;
 
     iopaddr_t              *pciaddr, *pcilast;
     iopaddr_t               start_addr;
@@ -4751,7 +4861,7 @@
     /*
      * First look if a previously allocated chunk exists.
      */
-    if ((piosp = pcibr_info->f_piospace) != (pciio_piospace_t)0) {
+    if ((piosp = pcibr_info->f_piospace)) {
 	/*
 	 * Look through the list for a right sized free chunk.
 	 */
@@ -4825,7 +4935,7 @@
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
 
     pciio_piospace_t        piosp;
-    int                     s;
+    unsigned long           s;
     char                    name[1024];
 
     /*
@@ -4901,7 +5011,7 @@
     iopaddr_t               attributes = 0;
 
     /* Sanity check: Bridge only allows use of VCHAN1 via 64-bit addrs */
-#ifdef IRIX
+#ifdef LATER
     ASSERT_ALWAYS(!(flags & PCIBR_VCHAN1) || (flags & PCIIO_DMA_A64));
 #endif
 
@@ -5031,7 +5141,16 @@
     /* 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;
 
@@ -5162,7 +5281,7 @@
 	    pcibr_dmamap->bd_pci_addr =
 		PCI32_MAPPED_BASE + IOPGSIZE * ate_index;
 	    /*
-	     * for xbridge the byte-swap bit == bit 29 of pci address
+	     * for xbridge the byte-swap bit == bit 29 of PCI address
 	     */
 	    if (pcibr_soft->bs_xbridge) {
 		    if (flags & PCIIO_BYTE_STREAM)
@@ -5201,7 +5320,7 @@
 		bridge_t               *bridge = pcibr_soft->bs_base;
 		volatile unsigned      *cmd_regp;
 		unsigned                cmd_reg;
-		unsigned                s;
+		unsigned long           s;
 
 		pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_SSRAM;
 
@@ -5239,20 +5358,15 @@
     pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
     pciio_slot_t            slot = pcibr_dmamap->bd_slot;
 
-#ifdef IRIX
     unsigned                flags = pcibr_dmamap->bd_flags;
-#endif
 
     /* Make sure that bss_ext_ates_active
      * is properly kept up to date.
      */
-#ifdef IRIX
+
     if (PCIBR_DMAMAP_BUSY & flags)
 	if (PCIBR_DMAMAP_SSRAM & flags)
-	    atomicAddInt(&(pcibr_soft->
-			   bs_slot[slot].
-			   bss_ext_ates_active), -1);
-#endif
+	    atomic_dec(&(pcibr_soft->bs_slot[slot]. bss_ext_ates_active));
 
     xtalk_dmamap_free(pcibr_dmamap->bd_xtalk);
 
@@ -5265,7 +5379,9 @@
 		       pcibr_dmamap->bd_ate_count);
 	pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_PMU_BITS);
     }
+#ifdef IRIX
     DEL(pcibr_dmamap);
+#endif
 }
 
 /*
@@ -5325,7 +5441,6 @@
 /* We are starting to get more complexity
  * surrounding writing ATEs, so pull
  * the writing code into this new function.
- * XXX mail ranga@engr for IP27 prom!
  */
 
 #if PCIBR_FREEZE_TIME
@@ -5342,13 +5457,13 @@
 	   unsigned *cmd_regs)
 {
     pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-#ifdef IRIX
+#ifdef LATER
     int                     dma_slot = pcibr_dmamap->bd_slot;
 #endif
     int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
     int                     slot;
 
-    unsigned                s;
+    unsigned long           s;
     unsigned                cmd_reg;
     volatile unsigned      *cmd_lwa;
     unsigned                cmd_lwd;
@@ -5371,27 +5486,22 @@
      */
     s = pcibr_lock(pcibr_soft);
 
-#ifdef IRIX
+#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)
-	    atomicAddInt(&(pcibr_soft->
-			   bs_slot[dma_slot].
-			   bss_ext_ates_active), -1);
+	    atomic_dec(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
 	xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
     }
-#endif
+#endif	/* LATER */
 #if PCIBR_FREEZE_TIME
     *freeze_time_ptr = get_timestamp();
 #endif
 
     cmd_lwa = 0;
     for (slot = 0; slot < 8; ++slot)
-	if (pcibr_soft->
-	    bs_slot[slot].
-	    bss_ext_ates_active) {
-
+	if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
 	    cmd_reg = pcibr_soft->
 		bs_slot[slot].
 		bss_cmd_shadow;
@@ -5418,9 +5528,7 @@
 
 	    /* Flush all the write buffers in the bridge */
 	    for (slot = 0; slot < 8; ++slot)
-		    if (pcibr_soft->
-			bs_slot[slot].
-			bss_ext_ates_active) {
+		    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.
 			     */
@@ -5462,9 +5570,7 @@
 	 unsigned s)
 {
     pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-#ifdef IRIX
     int                     dma_slot = pcibr_dmamap->bd_slot;
-#endif
     int                     slot;
     bridge_t               *bridge = pcibr_soft->bs_base;
     int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
@@ -5486,11 +5592,7 @@
 	    bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg;
 
     pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY;
-#ifdef IRIX
-    atomicAddInt(&(pcibr_soft->
-		   bs_slot[dma_slot].
-		   bss_ext_ates_active), 1);
-#endif
+    atomic_inc(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
 
 #if PCIBR_FREEZE_TIME
     freeze_time = get_timestamp() - freeze_time_start;
@@ -5685,11 +5787,7 @@
 		  unsigned flags)
 {
     pcibr_soft_t            pcibr_soft;
-#ifdef IRIX
-    bridge_t               *bridge;
-#else
     bridge_t               *bridge=NULL;
-#endif
 
     unsigned                al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
     int                     inplace = flags & PCIIO_INPLACE;
@@ -5699,19 +5797,11 @@
     size_t                  length;
     iopaddr_t               offset;
     unsigned                direct64;
-#ifdef IRIX
-    int                     ate_index;
-    int                     ate_count;
-    int                     ate_total = 0;
-    bridge_ate_p            ate_ptr;
-    bridge_ate_t            ate_proto;
-#else
     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;
-#endif
     bridge_ate_t            ate_prev;
     bridge_ate_t            ate;
     alenaddr_t              xio_addr;
@@ -5899,16 +5989,12 @@
      * between _addr/_list and _done, but Hub does.
      */
 
-#ifdef IRIX
     if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) {
 	pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY;
 
 	if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM)
-	    atomicAddInt(&(pcibr_dmamap->bd_soft->
-			   bs_slot[pcibr_dmamap->bd_slot].
-			   bss_ext_ates_active), -1);
+	    atomic_dec(&(pcibr_dmamap->bd_soft->bs_slot[pcibr_dmamap->bd_slot]. bss_ext_ates_active));
     }
-#endif
 
     xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
 }
@@ -6332,11 +6418,7 @@
 	 */
 	if (xio_port == pcibr_soft->bs_xid) {
 	    pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size);
-#ifdef IRIX
-	    if (pci_addr == NULL)
-#else
 	    if ( (pci_addr == (alenaddr_t)NULL) )
-#endif
 		goto fail;
 	} else if (direct64) {
 	    ASSERT(xio_port != 0);
@@ -6371,11 +6453,7 @@
 	}
     }
 
-#ifdef IRIX
-    if (relbits)
-#else
     if (relbits) {
-#endif
 	if (direct64) {
 	    slotp->bss_d64_flags = flags;
 	    slotp->bss_d64_base = pci_base;
@@ -6383,9 +6461,7 @@
 	    slotp->bss_d32_flags = flags;
 	    slotp->bss_d32_base = pci_base;
 	}
-#ifndef IRIX
     }
-#endif
     if (!inplace)
 	alenlist_done(xtalk_alenlist);
 
@@ -6480,26 +6556,155 @@
     return bbits;
 }
 
-#ifdef IRIX
+
+/*
+ *	Get the next wrapper pointer queued in the interrupt circular buffer.
+ */
+#ifdef KERNEL_THREADS
+pcibr_intr_wrap_t
+pcibr_wrap_get(pcibr_intr_cbuf_t cbuf)
+{
+    pcibr_intr_wrap_t	wrap;
+
+	if (cbuf->ib_in == cbuf->ib_out)
+	    PRINT_PANIC("pcibr intr circular buffer empty, cbuf=0x%x, ib_in=ib_out=%d\n",
+		cbuf, cbuf->ib_out);
+
+	wrap = cbuf->ib_cbuf[cbuf->ib_out++];
+	cbuf->ib_out = cbuf->ib_out % IBUFSIZE;
+	return(wrap);
+}
+
+/* 
+ *	Queue a wrapper pointer in the interrupt circular buffer.
+ */
+void
+pcibr_wrap_put(pcibr_intr_wrap_t wrap, pcibr_intr_cbuf_t cbuf)
+{
+	int	in;
+	unsigned long	s;
+
+	/*
+	 * Multiple CPUs could be executing this code simultaneously
+	 * if a handler has registered multiple interrupt lines and
+	 * the interrupts are directed to different CPUs.
+	 */
+	s = mutex_spinlock(&cbuf->ib_lock);
+	in = (cbuf->ib_in + 1) % IBUFSIZE;
+	if (in == cbuf->ib_out) 
+	    PRINT_PANIC("pcibr intr circular buffer full, cbuf=0x%x, ib_in=%d\n",
+		cbuf, cbuf->ib_in);
+
+	cbuf->ib_cbuf[cbuf->ib_in] = wrap;
+	cbuf->ib_in = in;
+	mutex_spinunlock(&cbuf->ib_lock, s);
+	return;
+}
+#endif	/* KERNEL_THREADS */
+
+/*
+ *	There are end cases where a deadlock can occur if interrupt 
+ *	processing completes and the Bridge b_int_status bit is still set.
+ *
+ *	One scenerio is if a second PCI interrupt occurs within 60ns of
+ *	the previous interrupt being cleared. In this case the Bridge
+ *	does not detect the transition, the Bridge b_int_status bit
+ *	remains set, and because no transition was detected no interrupt
+ *	packet is sent to the Hub/Heart.
+ *
+ *	A second scenerio is possible when a b_int_status bit is being
+ *	shared by multiple devices:
+ *						Device #1 generates interrupt
+ *						Bridge b_int_status bit set
+ *						Device #2 generates interrupt
+ *		interrupt processing begins
+ *		  ISR for device #1 runs and
+ *			clears interrupt
+ *						Device #1 generates interrupt
+ *		  ISR for device #2 runs and
+ *			clears interrupt
+ *						(b_int_status bit still set)
+ *		interrupt processing completes
+ *		  
+ *	Interrupt processing is now complete, but an interrupt is still
+ *	outstanding for Device #1. But because there was no transition of
+ *	the b_int_status bit, no interrupt packet will be generated and
+ *	a deadlock will occur.
+ *
+ *	To avoid these deadlock situations, this function is used
+ *	to check if a specific Bridge b_int_status bit is set, and if so,
+ *	cause the setting of the corresponding interrupt bit.
+ *
+ *	On a XBridge (IP35), we do this by writing the appropriate Bridge Force 
+ *	Interrupt register.
+ */
+void
+pcibr_force_interrupt(pcibr_intr_wrap_t wrap)
+{
+	unsigned	bit;
+	pcibr_soft_t    pcibr_soft = wrap->iw_soft;
+	bridge_t       *bridge = pcibr_soft->bs_base;
+	cpuid_t cpuvertex_to_cpuid(devfs_handle_t vhdl);
+
+	bit = wrap->iw_intr;
+
+	if (pcibr_soft->bs_xbridge) {
+	    bridge->b_force_pin[bit].intr = 1;
+	} else if ((1 << bit) & *wrap->iw_stat) {
+	    cpuid_t	    cpu;
+	    unsigned        intr_bit;
+	    xtalk_intr_t    xtalk_intr =
+				pcibr_soft->bs_intr[bit].bsi_xtalk_intr;
+
+	    intr_bit = (short) xtalk_intr_vector_get(xtalk_intr);
+	    cpu = cpuvertex_to_cpuid(xtalk_intr_cpu_get(xtalk_intr));
+	    REMOTE_CPU_SEND_INTR(cpu, intr_bit);
+	}
+}
+
 /* Wrapper for pcibr interrupt threads. */
+#ifdef KERNEL_THREADS
 static void
 pcibr_intrd(pcibr_intr_t intr)
 {
+    pcibr_intr_wrap_t	wrap;
+
 	/* Called on each restart */
 	ASSERT(cpuid() == intr->bi_mustruncpu);
 
 #ifdef ITHREAD_LATENCY
-	xthread_update_latstats(intr->bi_tinfo->thd_latstats);
+	xthread_update_latstats(intr->bi_tinfo.thd_latstats);
 #endif /* ITHREAD_LATENCY */
 
 	ASSERT(intr->bi_func != NULL);
 	intr->bi_func(intr->bi_arg);		/* Invoke the interrupt handler */
 
+	/*
+	 * The pcibr_intrd thread needs access to the wrapper struct
+	 * specific to the current interrupt it is processing. Because
+	 * multiple calls/wakeups to the thread could be queued, each
+	 * potentially from a different interrupt line (PCIIO_INTR_LINE_A,
+	 * etc), multiple wrapper struct pointers need to be queued. This 
+	 * is done via a circular buffer of wrapper struct pointers. 
+	 */
+	wrap = pcibr_wrap_get(&intr->bi_ibuf);
+
+	/* 
+	 * The interrupt handler has completed. Now decrement the running
+	 * count tracking the number of handlers still running for this line.
+	 * If this was the last handler to complete (i.e., iw_hdlrcnt == 0),
+	 * avoid a potential deadlock condition and ensure that another
+	 * interrupt will occur if the Bridge b_int_status bit is still
+	 * set. 
+	 */
+	atomicAddInt(&(wrap->iw_hdlrcnt), -1);
+	if (wrap->iw_hdlrcnt == 0)
+		pcibr_force_interrupt(wrap);
+
 	ipsema(&intr->bi_tinfo.thd_isync);	/* Sleep 'till next interrupt */
 	/* NOTREACHED */
 }
 
-
 static void
 pcibr_intrd_start(pcibr_intr_t intr)
 {
@@ -6519,14 +6724,16 @@
 	char thread_name[32];
 
 	sprintf(thread_name, "pcibr_intrd[0x%x]", bridge_levels);
+	thread_name[IT_NAMELEN-1] = '\0';
 
 	/* XXX need to adjust priority whenever an interrupt is connected */
+	intr->bi_tinfo.thd_pri = intr_swlevel;
 	atomicSetInt(&intr->bi_tinfo.thd_flags, THD_ISTHREAD | THD_REG);
 	xthread_setup(thread_name, intr_swlevel, &intr->bi_tinfo,
 			(xt_func_t *)pcibr_intrd_start,
 			(void *)intr);
 }
-#endif	/* IRIX */
+#endif	/* KERNEL_THREADS */
 
 
 
@@ -6542,13 +6749,16 @@
     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;
+    int                     is_threaded = 0;
+#ifdef KERNEL_THREADS
+    cpuid_t		    mustruncpu = CPU_NONE;
+    cpuid_t		    old_intrcpu = CPU_NONE;
+#endif
     int                     thread_swlevel;
 
     xtalk_intr_t           *xtalk_intr_p;
     pcibr_intr_t           *pcibr_intr_p;
     pcibr_intr_list_t      *intr_list_p;
-    pcibr_intr_wrap_t      *intr_wrap_p;
 
     unsigned                pcibr_int_bits;
     unsigned                pcibr_int_bit;
@@ -6557,7 +6767,6 @@
     pcibr_intr_t            pcibr_intr;
     pcibr_intr_list_t       intr_entry;
     pcibr_intr_list_t       intr_list;
-    pcibr_intr_wrap_t       intr_wrap;
     bridgereg_t             int_dev;
 
 #if DEBUG && INTR_DEBUG
@@ -6576,9 +6785,29 @@
 	return NULL;
 
     if (dev_desc) {
+	cpuid_t intr_target_from_desc(device_desc_t, int);
+
+#ifdef KERNEL_THREADS
 	is_threaded = !(device_desc_flags_get(dev_desc) & D_INTR_NOTHREAD);
-	if (is_threaded)
+	if (is_threaded) {
+	    /*
+	     * If the device descriptor contains interrupt target info,
+	     * save the CPU requested. This is the CPU the pcibr_intrd
+	     * thread will be set to run on. 
+	     *
+	     * We need to get the interrupt target info at this time, because
+	     * the original intr_target value can be overwritten, as part of
+	     * the xtalk_intr_alloc_nothd() call, with the actual interrupt CPU.
+	     * This can be different than the requested CPU if the lower layers
+	     * could not direct the hardware interrupt to the requested CPU. 
+	     * Regardless of which CPU processes the hardware interrupt, the 
+	     * ISR thread will still be setup to run on the CPU originally 
+	     * requested.
+	     */
+		mustruncpu = intr_target_from_desc(dev_desc, SUBNODE_ANY);
 		thread_swlevel = device_desc_intr_swlevel_get(dev_desc);
+	}
+#endif	/* KERNEL_THREADS */
     } else {
 	extern int default_intr_pri;
 
@@ -6594,6 +6823,11 @@
     pcibr_intr->bi_arg = 0;		/* unset until connect */
     pcibr_intr->bi_flags = is_threaded ? 0 : PCIIO_INTR_NOTHREAD;
     pcibr_intr->bi_mustruncpu = CPU_NONE;
+#ifdef KERNEL_THREADS
+    pcibr_intr->bi_ibuf.ib_in = 0;
+    pcibr_intr->bi_ibuf.ib_out = 0;
+#endif
+    mutex_spinlock_init(&pcibr_intr->bi_ibuf.ib_lock);
 
     pcibr_int_bits = pcibr_soft->bs_intr_bits((pciio_info_t)pcibr_info, lines);
 
@@ -6626,7 +6860,17 @@
 		 *    single Bridge. (IP35-specific code forces this, and we
 		 *    verify in pcibr_setwidint.)
 		 */
-		xtalk_intr = xtalk_intr_alloc(xconn_vhdl, dev_desc, owner_dev);
+
+		/*
+		 * 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
@@ -6690,32 +6934,64 @@
 		}
 	    }
 
-	    /*
-	     * For threaded drivers, set the interrupt thread to run wherever
-	     * the interrupt is targeted.
-	     */
-#ifdef notyet
+#ifdef KERNEL_THREADS
 	    if (is_threaded) {
-		cpuid_t old_mustrun = pcibr_intr->bi_mustruncpu;
-		pcibr_intr->bi_mustruncpu = cpuvertex_to_cpuid(xtalk_intr_cpu_get(xtalk_intr));
-		ASSERT(pcibr_intr->bi_mustruncpu >= 0);
+		cpuid_t intrcpu = cpuvertex_to_cpuid(xtalk_intr_cpu_get(xtalk_intr));
 
 		/*
-		 * This is possible, but very unlikely: It means that 2 (or more) interrupts
-		 * originating on a single Bridge and used by a single device were unable to
-		 * find sufficient xtalk interrupt resources that would allow them all to be
-		 * handled by the same CPU.  If someone tries to target lots of interrupts to
-		 * a single CPU, we might hit this case.  Things should still operate correctly,
-		 * but it's a sub-optimal configuration.
+		 * It is possible that 2 (or more) interrupts originating on a
+		 * single Bridge and used by a single device were assigned to
+		 * different CPUs. If this occurs issue a warning message for
+		 * this sub-optimal configuration. There are two ways this 
+		 * could happen:
+		 *
+		 *  - There were insufficient xtalk interrupt resources to
+		 *    allow all interrupts to be assigned to the same CPU.
+		 *    This is an unlikely case, but could happen if someone
+		 *    tries to target a lot of interrupts to a single CPU.
+		 *
+		 * - If there is no device descriptor associated with this
+		 *   device, the xtalk/hub/heart layers will not know to
+		 *   assign the same CPU to any additional interrupts this
+		 *   driver has specified, and will perform the normal load
+		 *   leveling of interrupts across CPUs.
+		 *   (The lower layers store the CPU assigned to the first
+		 *   interrupt in the device desc, if present, and then when
+		 *   called again for additional interrupts for the same device,
+		 *   use this information to assign the same CPU to these
+		 *   interrupts.)
 		 */
-		if ((old_mustrun != CPU_NONE) && (old_mustrun != pcibr_intr->bi_mustruncpu)) {
-#ifdef SUPPORT_PRINTING_V_FORMAT
-			PRINT_WARNING( "Conflict on where to schedule interrupts for %v\n", pconn_vhdl);
+		if ((old_intrcpu != CPU_NONE) && (old_intrcpu != intrcpu)) {
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+			PRINT_WARNING("Conflict on where to schedule interrupts for %v\n", pconn_vhdl);
+#else
+			PRINT_WARNING("Conflict on where to schedule interrupts for 0x%x\n", pconn_vhdl);
 #endif
-			PRINT_WARNING( "(on cpu %d or on cpu %d)\n", old_mustrun, pcibr_intr->bi_mustruncpu);
+			PRINT_WARNING("(on cpu %d or on cpu %d), cpu %d used\n", old_intrcpu, intrcpu, intrcpu);
+		}
+		if (old_intrcpu == CPU_NONE)
+			old_intrcpu = intrcpu;
+	    /*
+	     * For threaded drivers, set the interrupt thread to run wherever
+	     * the interrupt is targeted, or where requested in the dev_desc.
+	     */
+		if (mustruncpu != CPU_NONE) {
+			pcibr_intr->bi_mustruncpu = mustruncpu;
+			if (mustruncpu != intrcpu) {
+				PRINT_WARNING("Request to target PCI interrupts to CPU %d could not\n"
+                		"      be satisfied, CPU %d used. However, interrupt thread\n"
+                		"      pcibr_intrd will run on CPU %d as requested.\n"
+                		"      %v (0x%x)\n",
+                		mustruncpu, intrcpu, mustruncpu, owner_dev,
+				owner_dev);
+			}
+		} else {
+			pcibr_intr->bi_mustruncpu = intrcpu;
 		}
+		ASSERT(pcibr_intr->bi_mustruncpu >= 0);
+
 	    }
-#endif
+#endif	/* KERNEL_THREADS */
 
 	    pcibr_intr->bi_ibits |= 1 << pcibr_int_bit;
 
@@ -6723,8 +6999,20 @@
 	    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
 
-	    intr_list_p = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_list;
 	    if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
 		/* we are the first interrupt on this bridge bit.
 		 */
@@ -6751,29 +7039,12 @@
 	    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.
-		 * switch to local wrapper.
 		 */
+		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
-		NEW(intr_wrap);
-		intr_wrap->iw_soft = pcibr_soft;
-		intr_wrap->iw_stat = &(bridge->b_int_status);
-		intr_wrap->iw_intr = 1 << pcibr_int_bit;
-		intr_wrap->iw_list = intr_list;
-		intr_wrap_p = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap;
-		if (!compare_and_swap_ptr((void **) intr_wrap_p, NULL, intr_wrap)) {
-		    /* someone else set up the wrapper.
-		     */
-		    DEL(intr_wrap);
-		    continue;
-#if DEBUG && INTR_DEBUG
-		} else {
-		    printk("%v bridge bit %d wrapper state created\n",
-			    pconn_vhdl, pcibr_int_bit);
-#endif
-		}
 		continue;
 	    }
 	    while (1) {
@@ -6807,13 +7078,13 @@
 	}
     }
 
-#ifdef IRIX
+#ifdef KERNEL_THREADS
     if (is_threaded) {
 	/* Set pcibr_intr->bi_tinfo */
 	pcibr_thread_setup(pcibr_intr, pcibr_int_bits, thread_swlevel);
 	ASSERT(!(pcibr_intr->bi_flags & PCIIO_INTR_CONNECTED));
     }
-#endif
+#endif	/* KERNEL_THREADS */
 
 #if DEBUG && INTR_DEBUG
     printk("%v pcibr_intr_alloc complete\n", pconn_vhdl);
@@ -6832,13 +7103,13 @@
     pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
     unsigned                pcibr_int_bit;
     pcibr_intr_list_t       intr_list;
-    pcibr_intr_wrap_t	    intr_wrap;
+    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_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, 
@@ -6852,10 +7123,11 @@
 	    /* If this interrupt line is not being shared between multiple
 	     * devices release the xtalk interrupt resources.
 	     */
-	    intr_wrap = 
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap;
+	    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_wrap == NULL) && (*xtalk_intrp)) {
+
+	    if ((!intr_shared) && (*xtalk_intrp)) {
 
 		bridge_t 	*bridge = pcibr_soft->bs_base;
 		bridgereg_t	int_dev;
@@ -6900,7 +7172,7 @@
     unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
     unsigned                pcibr_int_bit;
     bridgereg_t             b_int_enable;
-    unsigned                s;
+    unsigned long           s;
 
     if (pcibr_intr == NULL)
 	return -1;
@@ -6924,59 +7196,29 @@
 	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
 	    pcibr_intr_wrap_t       intr_wrap;
 	    xtalk_intr_t            xtalk_intr;
-	    int                    *setptr;
 
 	    xtalk_intr = pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
 
-	    /* if we have no wrap structure,
-	     * tell xtalk to deliver the interrupt
-	     * directly to the client.
+	    intr_wrap = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap;
+	    /*
+	     * If this interrupt line is being shared and the connect has
+	     * already been done, no need to do it again.
 	     */
-	    intr_wrap = pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap;
-	    if (intr_wrap == NULL) {
-		xtalk_intr_connect(xtalk_intr,
-				   (intr_func_t) intr_func,
-				   (intr_arg_t) intr_arg,
-				   (xtalk_intr_setfunc_t) pcibr_setpciint,
-				   (void *) &(bridge->b_int_addr[pcibr_int_bit].addr),
-				   thread);
-#if DEBUG && INTR_DEBUG
-		printk("%v bridge bit %d routed by xtalk\n",
-			pcibr_intr->bi_dev, pcibr_int_bit);
-#endif
+	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected)
 		continue;
-	    }
-
-	    setptr = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_wrap_set;
-	    if (*setptr)
-		continue;
-
 
-	    /* We have a wrap structure, so we're sharing a Bridge interrupt level */
-
-	    xtalk_intr_disconnect(xtalk_intr); /* Disconnect old interrupt */
 
 	    /*
-		If the existing xtalk_intr was allocated without the NOTHREAD flag,
-		we need to allocate a new one that's NOTHREAD, and connect to the
-		new one.   pcibr_intr_list_func expects to run at interrupt level
-		rather than in a thread.  With today's devices, this can't happen,
-		so let's punt on writing the code till we need it (probably never).
-		Instead, just ASSERT that we're a NOTHREAD xtalk_intr.
-	    */
-#ifdef IRIX
-	    ASSERT_ALWAYS(!(pcibr_intr->bi_flags & PCIIO_INTR_NOTHREAD) ||
-			xtalk_intr_flags_get(xtalk_intr) & XTALK_INTR_NOTHREAD);
-#endif
-
-	    /* Use the wrapper dispatch function to handle shared Bridge interrupts */
+	     * Use the pcibr wrapper function to handle all Bridge interrupts
+	     * regardless of whether the interrupt line is shared or not.
+	     */
 	    xtalk_intr_connect(xtalk_intr,
-			       pcibr_intr_list_func,
+				pcibr_intr_func,
 			       (intr_arg_t) intr_wrap,
 			       (xtalk_intr_setfunc_t) pcibr_setpciint,
 			       (void *) &(bridge->b_int_addr[pcibr_int_bit].addr),
 			       0);
-	    *setptr = 1;
+	    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",
@@ -7001,9 +7243,9 @@
     bridge_t               *bridge = pcibr_soft->bs_base;
     unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
     unsigned                pcibr_int_bit;
-    pcibr_intr_wrap_t       intr_wrap;
+    pcibr_intr_wrap_t	    intr_wrap;
     bridgereg_t             b_int_enable;
-    unsigned                s;
+    unsigned long           s;
 
     /* Stop calling the function. Now.
      */
@@ -7021,7 +7263,7 @@
      */
     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_wrap_set))
+	    (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;
@@ -7035,26 +7277,32 @@
 
     for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
 	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    /* if we have set up the share wrapper,
+	    /* if the interrupt line is now shared,
 	     * do not disconnect it.
 	     */
-	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_wrap_set)
+	    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 have a share wrapper state,
+	    /* if we are sharing the interrupt line,
 	     * connect us up; this closes the hole
-	     * where the connection of the wrapper
+	     * where the another pcibr_intr_alloc()
 	     * was in progress as we disconnected.
 	     */
-	    intr_wrap = pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap;
-	    if (intr_wrap == NULL) 
+	    intr_wrap = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap;
+	    if (!pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)
 		continue;
 
 
 	    xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr,
-			       pcibr_intr_list_func,
+			       pcibr_intr_func,
 			       (intr_arg_t) intr_wrap,
 			       (xtalk_intr_setfunc_t) pcibr_setpciint,
 			       (void *) &(bridge->b_int_addr[pcibr_int_bit].addr),
@@ -7168,7 +7416,7 @@
 	bridge->b_int_enable |= ~BRIDGE_IMR_INT_MSK;
 
     } else {
-	/* routing a pci device interrupt.
+	/* 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.
@@ -7187,46 +7435,71 @@
     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_list_func(intr_arg_t arg)
+pcibr_intr_func(intr_arg_t arg)
 {
     pcibr_intr_wrap_t       wrap = (pcibr_intr_wrap_t) arg;
-    reg_p                   statp = wrap->iw_stat;
-    bridgereg_t             mask = wrap->iw_intr;
     reg_p                   wrbf;
-    pcibr_intr_list_t       list;
-    pcibr_intr_t            intr;
     intr_func_t             func;
+    pcibr_intr_t            intr;
+    pcibr_intr_list_t       list;
     int                     clearit;
-    int                     thread_count = 0;
+#ifdef KERNEL_THREADS
+    int			    do_nonthreaded = 0;
+    int			    do_threaded = 1;
+    int			    is_threaded = 0;
+#else
+    int			    do_nonthreaded = 1;
+    int			    do_threaded = 0;
+    int			    is_threaded = 0;
+#endif
+    int			    nonthreaded_count = 0;
+    int			    x = 0;
+
+	/*
+	 * If any handler is still running from a previous interrupt
+	 * just return. If there's a need to call the handler(s) again,
+	 * another interrupt will be generated either by the device or by
+	 * pcibr_force_interrupt().
+	 */
+
+	if (wrap->iw_hdlrcnt) {
+		return;
+	}
 
     /*
-     * Loop until either
-     * 1) All interrupts have been removed by direct-called interrupt handlers OR
-     * 2) We've woken up at least one interrupt thread that will presumably clear
-     *    Bridge interrupt bits
+     * 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.
      */
 	
-    while ((!thread_count) && (mask & *statp)) {
 	clearit = 1;
-	for (list = wrap->iw_list;
-	     list != NULL;
-	     list = list->il_next) {
-	    if ((intr = list->il_intr) &&
-		(intr->bi_flags & PCIIO_INTR_CONNECTED)) {
-    		int is_threaded;
+	while (do_threaded || do_nonthreaded) {
+	    for (list = wrap->iw_list; list != NULL; list = list->il_next) {
+		if ((intr = list->il_intr) &&
+		    (intr->bi_flags & PCIIO_INTR_CONNECTED)) {
 
-		ASSERT(intr->bi_func);
+		    ASSERT(intr->bi_func);
 
 		/*
 		 * This device may have initiated write
 		 * requests since the bridge last saw
 		 * an edge on this interrupt input; flushing
-		 * the buffer here 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
+		 * 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
@@ -7238,28 +7511,96 @@
 		 * has completed, but before observing the
 		 * contents of memory?
 		 */
-#ifdef IRIX
-		if (wrbf = list->il_wrbf)
+
+#ifdef KERNEL_THREADS
+		    is_threaded = !(intr->bi_flags & PCIIO_INTR_NOTHREAD);
+		    if (!is_threaded) {
+			nonthreaded_count++;
+		    }
+
+		    if ((do_threaded) && (is_threaded)) {
+			/* Only need to flush write buffers if sharing */
+
+			if ((wrap->iw_shared) && (wrbf = list->il_wrbf)) {
+			    if (x = *wrbf)	/* write request buffer flush */
+#ifdef SUPPORT_PRINTING_V_FORMAT
+				PRINT_ALERT("pcibr_intr_func %v: \n"
+				    "write buffer flush failed, wrbf=0x%x\n", 
+				    list->il_intr->bi_dev, wrbf);
 #else
-		if ((wrbf = list->il_wrbf))
+				PRINT_ALERT("pcibr_intr_func 0x%x: \n"
+				    "write buffer flush failed, wrbf=0x%x\n", 
+				    list->il_intr->bi_dev, wrbf);
 #endif
-		    (void) *wrbf;	/* write request buffer flush */
+			}
+
+			/*
+			 * Keep a running count of the number of interrupt
+			 * handlers that have yet to complete. 
+			 */
+			atomicAddInt(&(wrap->iw_hdlrcnt), 1);
+
+			/* 
+			 * Prior to waking up pcibr_intrd, a pointer to the 
+			 * wrapper struct corresponding to the interrupt taken
+			 * needs to be queued in the interrupt circular buffer.
+			 * The pcibr_intrd thread needs the wrapper pointer in
+			 * order to decrement the handler count (iw_hdlrcnt).
+			 */
+			pcibr_wrap_put(wrap, &intr->bi_ibuf);
+#ifdef ITHREAD_LATENCY
+			xthread_set_istamp(intr->bi_tinfo.thd_latstats);
+#endif /* ITHREAD_LATENCY */
+		     	up(&intr->bi_tinfo.thd_isync); 
+		    } else
+#endif	/* KERNEL_THREADS */
+			if ((do_nonthreaded) && (!is_threaded)) {
+			/* Non-threaded. 
+			 * Call the interrupt handler at interrupt level
+			 */
 
-		is_threaded = !(intr->bi_flags & PCIIO_INTR_NOTHREAD);
+			/* Only need to flush write buffers if sharing */
 
-		if (is_threaded) {
-			thread_count++;
-#ifdef IRIX
-			icvsema(&intr->bi_tinfo.thd_isync, intr->bi_tinfo.thd_pri,
-				NULL, NULL, NULL);
+			if ((wrap->iw_shared) && (wrbf = list->il_wrbf)) {
+			    if ((x = *wrbf))	/* write request buffer flush */
+#ifdef SUPPORT_PRINTING_V_FORMAT
+				PRINT_ALERT("pcibr_intr_func %v: \n"
+				    "write buffer flush failed, wrbf=0x%x\n", 
+				    list->il_intr->bi_dev, wrbf);
+#else
+				PRINT_ALERT("pcibr_intr_func %p: \n"
+				    "write buffer flush failed, wrbf=0x%x\n", 
+				    list->il_intr->bi_dev, wrbf);
 #endif
-		} else {
-			/* Non-threaded.  Call the interrupt handler at interrupt level */
+			}
+
 			func = intr->bi_func;
 			func(intr->bi_arg);
+		    }
+
+		    clearit = 0;
 		}
+	    }
+
+	    if (do_threaded) {
+		/* 
+		 * All threaded handlers have been called;
+		 * next do non-threaded, if any.
+		 */
+		do_threaded = 0;
 
-		clearit = 0;
+		if (nonthreaded_count)
+			do_nonthreaded = 1;
+	    } else {
+		do_nonthreaded = 0;
+		/*
+		 * If the non-threaded handler was the last to complete,
+		 * (i.e., no threaded handlers still running) force an
+		 * interrupt to avoid a potential deadlock situation.
+		 */
+		if (wrap->iw_hdlrcnt == 0) {
+			pcibr_force_interrupt(wrap);
+		}
 	    }
 	}
 
@@ -7275,7 +7616,8 @@
 	    pcibr_soft_t            pcibr_soft = wrap->iw_soft;
 	    bridge_t               *bridge = pcibr_soft->bs_base;
 	    bridgereg_t             b_int_enable;
-	    unsigned                s;
+	    bridgereg_t		    mask = 1 << wrap->iw_intr;
+	    unsigned long           s;
 
 	    s = pcibr_lock(pcibr_soft);
 	    b_int_enable = bridge->b_int_enable;
@@ -7285,7 +7627,6 @@
 	    pcibr_unlock(pcibr_soft, s);
 	    return;
 	}
-    }
 }
 
 /* =====================================================================
@@ -7403,7 +7744,7 @@
 		bridge->b_pci_err_lower);
     }
     if (int_status & BRIDGE_ISR_ERROR_FATAL) {
-	cmn_err_tag(14, (int)CE_PANIC, "PCI Bridge Error interrupt killed the system");
+	PRINT_PANIC("PCI Bridge Error interrupt killed the system");
 	/*NOTREACHED */
     } else {
 	PRINT_ALERT( "Non-fatal Error in Bridge..");
@@ -7491,10 +7832,8 @@
 				soft->bs_slot[slot].bss_window[win].bssw_base;
 			else if (map->bp_space == PCIIO_SPACE_ROM)
 			    base += pcibr_info->f_rbase;
-#ifdef IRIX
 			if ((pci_addr >= base) && (pci_addr < (base + size)))
-			    atomicAddInt(map->bp_toc, 1);
-#endif
+			    atomic_inc(map->bp_toc);
 		    }
 		}
 	    }
@@ -7532,34 +7871,8 @@
     bridgereg_t             err_status;
     int                     i;
 
-#if defined(SN0_HWDEBUG)
-    extern int		    la_trigger_nasid1;
-    extern int		    la_trigger_nasid2;
-    extern long		    la_trigger_val;
-#endif
-
     /* REFERENCED */
     bridgereg_t             disable_errintr_mask = 0;
-#ifdef IRIX
-    int 		    rv;
-#else
-    int                     rv = 0;
-#endif
-    int 		    error_code = IOECODE_DMA | IOECODE_READ;
-    ioerror_mode_t 	    mode = MODE_DEVERROR;
-    ioerror_t 	            ioe;
-
-#if defined(SN0_HWDEBUG)
-   /*
-    * trigger points for logic analyzer. Used to debug the DMA timeout
-    * note that 0xcafe is added to the trigger values to avoid false
-    * triggers when la_trigger_val shows up in a cacheline as data
-    */
-   if (la_trigger_nasid1 != -1) 
-	REMOTE_HUB_PI_S(la_trigger_nasid1, 0, PI_CPU_NUM, la_trigger_val + 0xcafe);
-   if (la_trigger_nasid2 != -1) 
-	REMOTE_HUB_PI_S(la_trigger_nasid2, 0, PI_CPU_NUM, la_trigger_val + 0xcafe);
-#endif
 
 #if PCIBR_SOFT_LIST
     /* IP27 seems to be handing us junk.
@@ -7635,7 +7948,7 @@
 
 		bs_estat->bs_errcount_total++;
 
-#ifdef IRIX
+#ifdef LATER
 		current_tick = lbolt;
 #else
 		current_tick = 0;
@@ -7777,7 +8090,7 @@
     if ((err_status & BRIDGE_ISR_INVLD_ADDR) &&
 	((((uint64_t) bridge->b_wid_err_upper << 32) | (bridge->b_wid_err_lower))
 	 == (BRIDGE_INT_RST_STAT & 0xff0))) {
-#ifdef IRIX
+#ifdef LATER
 	if (kdebug)
 	    PRINT_NOTICE( "%s bridge: ignoring llp/control address interrupt",
 		    pcibr_soft->bs_name);
@@ -7787,32 +8100,6 @@
     }
 #endif				/* PCIBR_LLP_CONTROL_WAR */
 
-    /* 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.
-	 */
-#if defined(CONFIG_SGI_IO_ERROR_HANDLING)
-	(void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_LOOKUP);
-#endif
-	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.
-	 */
-#if defined(CONFIG_SGI_IO_ERROR_HANDLING)
-	(void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_ACTION);
-#endif
-	rv = pcibr_error_handler((error_handler_arg_t)pcibr_soft,
-				 error_code,
-				 mode,
-				 &ioe);
-    }
-    if (rv != IOERROR_HANDLED) {
 #ifdef	DEBUG
 	if (err_status & BRIDGE_ISR_ERROR_DUMP)
 	    pcibr_error_dump(pcibr_soft);
@@ -7822,7 +8109,7 @@
 	    pcibr_error_dump(pcibr_soft);
 	}
 #endif
-    }
+
     /*
      * We can't return without re-enabling the interrupt, since
      * it would cause problems for devices like IOC3 (Lost
@@ -7853,11 +8140,7 @@
 		  iopaddr_t *offsetp,
 		  pciio_function_t *funcp)
 {
-#ifdef IRIX
-    int                     s, f, w;
-#else
     int                     s, f=0, w;
-#endif
     iopaddr_t               base;
     size_t                  size;
     pciio_piospace_t        piosp;
@@ -8082,7 +8365,7 @@
  * decodes the PCI specific portions -- we count on our
  * callers to dump the raw IOE data.
  */
-#ifdef colin
+#ifdef LATER
 #define BEM_ADD_IOE(ioe)						\
 	do {								\
 	    if (IOERROR_FIELDVALID(ioe, busspace)) {			\
@@ -8165,7 +8448,7 @@
      * and need to construct the slot/space/offset.
      */
 
-#ifdef colin
+#ifdef LATER
     bad_xaddr = IOERROR_GETVALUE(ioe, xtalkaddr);
 #else
     bad_xaddr = -1;
@@ -8207,7 +8490,7 @@
 	if (x > 1)
 	    x--;
 	/* x is which devio reg; no guarantee
-	 * pci slot x will be responding.
+	 * PCI slot x will be responding.
 	 * still need to figure out who decodes
 	 * space/offset on the bus.
 	 */
@@ -8253,7 +8536,7 @@
 
     if ((slot == PCIIO_SLOT_NONE) && (space != PCIIO_SPACE_NONE)) {
 	/* we've got a space/offset but not which
-	 * pci slot decodes it. Check through our
+	 * PCI slot decodes it. Check through our
 	 * notions of which devices decode where.
 	 *
 	 * Yes, this "duplicates" some logic in
@@ -8353,9 +8636,7 @@
 		wx = PCIIO_SPACE_MEM;
 	    wl = wb + ws;
 	    if ((wx == raw_space) && (raw_paddr >= wb) && (raw_paddr < wl)) {
-#ifdef IRIX
-		atomicAddInt(map->bp_toc, 1);
-#endif
+		atomic_inc(map->bp_toc);
 		if (slot == PCIIO_SLOT_NONE) {
 		    slot = cs;
 		    space = map->bp_space;
@@ -8369,7 +8650,7 @@
 
     if (space != PCIIO_SPACE_NONE) {
 	if (slot != PCIIO_SLOT_NONE) {
-#ifdef IRIX
+#ifdef LATER
 	    if (func != PCIIO_FUNC_NONE)
 		IOERROR_SETVALUE(ioe, widgetdev, 
 				 pciio_widgetdev_create(slot,func));
@@ -8451,10 +8732,10 @@
      * error interrupt is due to read/write error..
      */
 
-    /* We know the xtalk addr, the raw pci bus space,
-     * the raw pci bus address, the decoded pci bus
+    /* We know the xtalk addr, the raw PCI bus space,
+     * the raw PCI bus address, the decoded PCI bus
      * space, the offset within that space, and the
-     * decoded pci slot (which may be "PCIIO_SLOT_NONE" if no slot
+     * decoded PCI slot (which may be "PCIIO_SLOT_NONE" if no slot
      * is known to be involved).
      */
 
@@ -8506,7 +8787,7 @@
 	    BEM_ADD_VAR(raw_paddr);
 	    if (IOERROR_FIELDVALID(ioe, widgetdev)) {
 
-#ifdef colin
+#ifdef LATER
 		slot = pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioe, 
 								 widgetdev));
 		func = pciio_widgetdev_func_get(IOERROR_GETVALUE(ioe, 
@@ -8545,7 +8826,7 @@
 	 *      Need a way to ensure we don't inadvertently clear some
 	 *      other errors.
 	 */
-#ifdef IRIX
+#ifdef LATER
 	if (IOERROR_FIELDVALID(ioe, widgetdev))
 	    pcibr_device_disable(pcibr_soft, 
 				 pciio_widgetdev_slot_get(
@@ -8586,7 +8867,7 @@
      * Look up the address, in the bridge error registers, and
      * take appropriate action
      */
-#ifdef colin
+#ifdef LATER
     ASSERT(IOERROR_GETVALUE(ioe, widgetnum) == pcibr_soft->bs_xid);
     ASSERT(bridge);
 #endif
@@ -8618,7 +8899,7 @@
 
     retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe);
     if (retval != IOERROR_HANDLED)
-#ifdef colin
+#ifdef LATER
 	pcibr_device_disable(pcibr_soft, 
 			     pciio_widgetdev_slot_get(
 				      IOERROR_GETVALUE(ioe,widgetdev)));
@@ -8690,7 +8971,7 @@
 
     retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe);
 
-#ifdef IRIX
+#ifdef LATER
     if (retval != IOERROR_HANDLED) {
 	pcibr_device_disable(pcibr_soft, 
 			     pciio_widgetdev_slot_get(
@@ -8722,22 +9003,8 @@
 {
     pcibr_soft_t            pcibr_soft;
     int                     retval = IOERROR_BADERRORCODE;
-    devfs_handle_t	    xconn_vhdl,pcibr_vhdl;
-#if defined(CONFIG_SGI_IO_ERROR_HANDLING)
-    error_state_t	    e_state;
-#endif
-    pcibr_soft = (pcibr_soft_t) einfo;
-
-    xconn_vhdl = pcibr_soft->bs_conn;
-    pcibr_vhdl = pcibr_soft->bs_vhdl;
 
-#if defined(CONFIG_SGI_IO_ERROR_HANDLING)
-    e_state = error_state_get(xconn_vhdl);
-    
-    if (error_state_set(pcibr_vhdl, e_state) == 
-	ERROR_RETURN_CODE_CANNOT_SET_STATE)
-	return(IOERROR_UNHANDLED);
-#endif
+    pcibr_soft = (pcibr_soft_t) einfo;
 
     /* If we are in the action handling phase clean out the error state
      * on the xswitch.
@@ -8844,7 +9111,7 @@
     bridge_t               *bridge = pcibr_soft->bs_base;
     bridgereg_t             ctlreg;
     unsigned                cfgctl[8];
-    unsigned                s;
+    unsigned long           s;
     int                     f, nf;
     pcibr_info_h            pcibr_infoh;
     pcibr_info_t            pcibr_info;
@@ -8869,11 +9136,7 @@
 	/* XXX delay? */
 
 	for (f = 0; f < nf; ++f)
-#ifdef IRIX
-	    if (pcibr_info = pcibr_infoh[f])
-#else
 	    if ((pcibr_info = pcibr_infoh[f]))
-#endif
 		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] =
@@ -8901,7 +9164,7 @@
     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                s;
+    unsigned long           s;
 
     /*
      * Bridge supports hardware swapping; so we can always
@@ -8944,7 +9207,7 @@
 			pciio_slot_t pciio_slot,
 			pciio_priority_t device_prio)
 {
-    int                     s;
+    unsigned long           s;
     int                    *counter;
     bridgereg_t             rtbits = 0;
     bridgereg_t             devreg;
@@ -8966,9 +9229,9 @@
      * 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
+     * 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
+     * on PCI bus. GBR and RR can still be uniquely used per
      * device. NETLIST MERGE DONE, WILL BE FIXED IN REV C.
      */
 
@@ -8983,18 +9246,12 @@
     s = pcibr_lock(pcibr_soft);
     devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
     if (device_prio == PCI_PRIO_HIGH) {
-#ifdef IRIX
-	if (++*counter == 1)
-#else
 	if ((++*counter == 1)) {
-#endif
 	    if (rtbits)
 		devreg |= rtbits;
 	    else
 		rc = PRIO_FAIL;
-#ifndef IRIX
 	}
-#endif
     } else if (device_prio == PCI_PRIO_LOW) {
 	if (*counter <= 0)
 	    rc = PRIO_FAIL;
@@ -9082,15 +9339,11 @@
 
     if (set || clr) {
 	bridgereg_t             devreg;
-	unsigned                s;
+	unsigned long           s;
 
 	s = pcibr_lock(pcibr_soft);
 	devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
-#ifdef IRIX
-	devreg = devreg & ~clr | set;
-#else
 	devreg = (devreg & ~clr) | set;
-#endif
 	if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
 	    bridge_t               *bridge = pcibr_soft->bs_base;
 
@@ -9146,13 +9399,9 @@
 
     pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
 
-    if ( (pcibr_soft_t)0 != pcibr_soft ) {
-	bridge = pcibr_soft->bs_base;
-	if ( (bridge_t *)0 != bridge ) {
-		cfgbase = bridge->b_type0_cfg_dev[pciio_slot].f[pciio_func].l;
-	}
-    }
+    bridge = pcibr_soft->bs_base;
 
+    cfgbase = bridge->b_type0_cfg_dev[pciio_slot].f[pciio_func].l;
 
     return cfgbase;
 }
@@ -9215,7 +9464,7 @@
     case 3:
 	if (reg & 1) {
 	    CB(cfgbase, reg) = value;
-	    CS(cfgbase, reg + 1) = value >> 8;
+	    CS(cfgbase, (reg + 1)) = value >> 8;
 	} else {
 	    CS(cfgbase, reg) = value;
 	    CB(cfgbase, reg + 2) = value >> 16;
@@ -9266,6 +9515,16 @@
 
     (pciio_error_devenable_f *) pcibr_error_devenable,
     (pciio_error_extract_f *) pcibr_error_extract,
+
+#ifdef LATER
+    (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback,
+    (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback,
+#else
+    (pciio_driver_reg_callback_f *) 0,
+    (pciio_driver_unreg_callback_f *) 0,
+#endif
+    (pciio_device_unregister_f 	*) pcibr_device_unregister,
+    (pciio_dma_enabled_f		*) pcibr_dma_enabled,
 };
 
 LOCAL                   pcibr_hints_t
@@ -9299,7 +9558,7 @@
     return (pcibr_hints_t) ainfo;
 
 abnormal_exit:
-#ifdef IRIX
+#ifdef LATER
     printf("SHOULD NOT BE HERE\n");
 #endif
     DEL(hint);
@@ -9417,12 +9676,7 @@
 	if (ainfo == (arbitrary_info_t) subdevp)
 	    return;
 	DEL(subdevp);
-#ifdef IRIX
-	if (ainfo == NULL)
-#else
-	if (ainfo == (arbitrary_info_t) NULL)
-#endif
-	{
+	if (ainfo == (arbitrary_info_t) NULL) {
 #if DEBUG
 	    printk("pcibr_hints_subdevs: null subdevs ptr at\n"
 		    "\t%p\n", pconn_vhdl);
@@ -9438,7 +9692,7 @@
 }
 
 
-#ifdef colin
+#ifdef LATER
 
 #include <sys/idbg.h>
 #include <sys/idbgentry.h>
@@ -9531,7 +9785,7 @@
 	    pss->bss_d32_base, pss->bss_d32_flags);
     
     qprintf("\tExt ATEs active ? %s", 
-	    pss->bss_ext_ates_active ? "yes" : "no");
+	    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);
 
@@ -9559,7 +9813,7 @@
 	qprintf("Invalid ips %d\n",ips);
 }
 
-#endif /* colin */
+#endif /* LATER */
 
 int
 pcibr_dma_enabled(devfs_handle_t pconn_vhdl)
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/pciio.c linux/arch/ia64/sn/io/pciio.c
--- v2.4.3/linux/arch/ia64/sn/io/pciio.c	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/io/pciio.c	Thu Apr  5 12:51:47 2001
@@ -14,6 +14,7 @@
 #include <linux/config.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>
@@ -23,6 +24,7 @@
 #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>
 
 #define DEBUG_PCIIO
 #undef DEBUG_PCIIO	/* turn this on for yet more console output */
@@ -38,28 +40,30 @@
 int
 badaddr_val(volatile void *addr, int len, volatile void *ptr)
 {
+	int ret = 0;
+	volatile void *new_addr;
+
 	switch (len) {
-		case 4: *(volatile u32*)ptr = *(((volatile u32*)(((u64) addr)^4)));
-		default: printk("FIXME: argh fix badaddr_val\n");
+		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);
 	}
-	/* no such thing as a bad addr .... */
-	return(0);
-}
 
+	if (ret < 0)
+		panic("badaddr_val: unexpected status (%d) in probing", ret);
+	return(ret);
 
-void
-cmn_err_tag(int seqnumber, register int level, char *fmt, ...)
-{
 }
 
+
 nasid_t
 get_console_nasid(void)
 {
-#ifdef IRIX
+	extern nasid_t console_nasid;
 	return console_nasid;
-#else
-	return 0;
-#endif
 }
 
 int
@@ -208,8 +212,8 @@
 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			pciio_device_detach(devfs_handle_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);
@@ -234,13 +238,30 @@
     pciio_info_t            card_info;
     pciio_provider_t       *provider_fns;
 
-    card_info = pciio_info_get(dev);
-    ASSERT(card_info != NULL);
+    /*
+     * 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%x: provider_fns == NULL", dev);
+#endif
 
-    provider_fns = pciio_info_pops_get(card_info);
-    ASSERT(provider_fns != NULL);
+    return provider_fns;
 
-    return (provider_fns);
 }
 
 #define DEV_FUNC(dev,func)	pciio_to_provider_fns(dev)->func
@@ -672,15 +693,21 @@
     error_state_t	    e_state;
 #endif
 
-#ifdef IRIX
 #if DEBUG && ERROR_DEBUG
-    cmn_err(CE_CONT, "%v: pciio_error_handler\n", pciio_vhdl);
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+    printk("%v: pciio_error_handler\n", pciio_vhdl);
+#else
+    printk("0x%x: pciio_error_handler\n", pciio_vhdl);
 #endif
 #endif
 
-    IOERR_PRINTF(cmn_err(CE_NOTE,
-			 "%v: PCI Bus Error: Error code: %d Error mode: %d\n",
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+    IOERR_PRINTF(printk("%v: PCI Bus Error: Error code: %d Error mode: %d\n",
 			 pciio_vhdl, error_code, mode));
+#else
+    IOERR_PRINTF(printk("0x%x: PCI Bus Error: Error code: %d Error mode: %d\n",
+			 pciio_vhdl, error_code, mode));
+#endif
 
     /* If there is an error handler sitting on
      * the "no-slot" connection point, give it
@@ -715,7 +742,7 @@
 	 * widgetdev is a 4byte value encoded as slot in the higher order
 	 * 2 bytes and function in the lower order 2 bytes.
 	 */
-#ifdef IRIX
+#ifdef LATER
 	slot = pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioerror, widgetdev));
 #else
 	slot = 0;
@@ -732,9 +759,12 @@
 #if defined(CONFIG_SGI_IO_ERROR_HANDLING)
 		e_state = error_state_get(pciio_vhdl);
 
+
 		if (e_state == ERROR_STATE_ACTION)
 		    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);
 
+
+
 		if (error_state_set(pconn_vhdl,e_state) ==
 		    ERROR_RETURN_CODE_CANNOT_SET_STATE)
 		    return(IOERROR_UNHANDLED);
@@ -825,12 +855,18 @@
     ASSERT((desired_end == PCIDMA_ENDIAN_BIG) || (desired_end == PCIDMA_ENDIAN_LITTLE));
 
 #if DEBUG
-    cmn_err(CE_ALERT,
-	    "%v: pciio_endian_set is going away.\n"
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+    PRINT_ALERT("%v: pciio_endian_set is going away.\n"
+	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
+	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
+	    dev);
+#else
+    PRINT_ALERT("0x%x: pciio_endian_set is going away.\n"
 	    "\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);
@@ -1027,8 +1063,6 @@
 	(pciio_info->c_fingerprint != pciio_info_fingerprint)) {
 #endif /* BRINGUP */
 
-	printk("pciio_info_get: Found fastinfo 0x%p but wrong fingerprint %s\n", pciio_info,
-	pciio_info->c_fingerprint);
 	return((pciio_info_t)-1); /* Should panic .. */
     }
 	
@@ -1198,7 +1232,11 @@
 pciio_attach(devfs_handle_t pciio)
 {
 #if DEBUG && ATTACH_DEBUG
-    cmn_err(CE_CONT, "%v: pciio_attach\n", pciio);
+#if defined(SUPPORT_PRINTING_V_FORMAT)
+    printk("%v: pciio_attach\n", pciio);
+#else
+    printk("0x%x: pciio_attach\n", pciio);
+#endif
 #endif
     return 0;
 }
@@ -1220,11 +1258,7 @@
 {
     arbitrary_info_t        ainfo;
 
-#ifdef IRIX
-    hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, &ainfo);
-#else
     hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, (long *) &ainfo);
-#endif
 }
 
 /*
@@ -1258,7 +1292,7 @@
 
     return cdl_add_driver(pciio_registry,
 			  vendor_id, device_id,
-			  driver_prefix, flags);
+			  driver_prefix, flags, NULL);
 }
 
 /*
@@ -1274,7 +1308,33 @@
      */
     ASSERT(pciio_registry != NULL);
 
-    cdl_del_driver(pciio_registry, driver_prefix);
+    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)
+{
 }
 
 /*
@@ -1307,7 +1367,6 @@
 		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));
@@ -1366,8 +1425,6 @@
 			    pciio_info->c_slot,
 			    pciio_info->c_func);
 
-    printk("pciio_device_info_register: connectpt 0x%p, pciio_info 0x%p\n", connectpt, pciio_info);
-
     if (GRAPH_SUCCESS !=
 	hwgraph_path_add(connectpt, name, &pconn))
 	return pconn;
@@ -1379,7 +1436,9 @@
 	int pos;
 	char dname[256];
 	pos = devfs_generate_path(pconn, dname, 256);
+#ifdef DEBUG_PCIIO
 	printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);
+#endif
     }
 #endif /* BRINGUP */
 
@@ -1421,6 +1480,7 @@
     /* Remove the link to our pci provider */
     hwgraph_edge_remove(pconn, EDGE_LBL_MASTER, NULL);
 
+
     hwgraph_vertex_unref(pconn);
     hwgraph_vertex_destroy(pconn);
     
@@ -1447,18 +1507,21 @@
 static void
 pciio_device_inventory_remove(devfs_handle_t pconn_vhdl)
 {
-#ifdef IRIX
+#ifdef LATER
     hwgraph_inventory_remove(pconn_vhdl,-1,-1,-1,-1,-1);
 #endif
 }
 
 /*ARGSUSED */
 int
-pciio_device_attach(devfs_handle_t pconn)
+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;
+    int pciba_attach(devfs_handle_t);
+
 
     pciio_device_inventory_add(pconn);
     pciio_info = pciio_info_get(pconn);
@@ -1466,8 +1529,6 @@
     vendor_id = pciio_info->c_vendor;
     device_id = pciio_info->c_device;
 
-    printk("pciio_device_attach: Function 0x%p, vendor 0x%x, device_id %x\n", pconn, vendor_id, device_id);
-
     /* we don't start attaching things until
      * all the driver init routines (including
      * pciio_init) have been called; so we
@@ -1475,12 +1536,17 @@
      */
     ASSERT(pciio_registry != NULL);
 
-    return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn));
+    /*
+     * Since pciba is not called from cdl routines .. call it here.
+     */
+    pciba_attach(pconn);
 
+    return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags));
 }
 
 int
-pciio_device_detach(devfs_handle_t pconn)
+pciio_device_detach(devfs_handle_t pconn,
+		    int          drv_flags)
 {
     pciio_info_t            pciio_info;
     pciio_vendor_id_t       vendor_id;
@@ -1499,10 +1565,9 @@
      */
     ASSERT(pciio_registry != NULL);
 
-    cdl_del_connpt(pciio_registry, vendor_id, device_id, pconn);
+    return(cdl_del_connpt(pciio_registry, vendor_id, device_id,
+		          pconn, drv_flags));
 
-    return(0);
-    
 }
 
 /*
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/sgi_if.c linux/arch/ia64/sn/io/sgi_if.c
--- v2.4.3/linux/arch/ia64/sn/io/sgi_if.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/sgi_if.c	Thu Apr  5 12:51:47 2001
@@ -21,8 +21,6 @@
 #include <asm/sn/pci/pciio.h>
 #include <asm/sn/slotnum.h>
 
-#define spinlock_init(x,name) mutex_init(x, MUTEX_DEFAULT, name);
-
 void *
 kmem_zalloc(size_t size, int flag)
 {
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/sgi_io_init.c linux/arch/ia64/sn/io/sgi_io_init.c
--- v2.4.3/linux/arch/ia64/sn/io/sgi_io_init.c	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/io/sgi_io_init.c	Thu Apr  5 12:51:47 2001
@@ -79,13 +79,8 @@
 void
 sgi_master_io_infr_init(void)
 {
-#ifdef Colin
-	/*
-	 * Simulate Big Window 0.
-	 * Only when we build for lutsen etc. ..
-	 */
-	simulated_BW0_init();
-#endif
+	int cnode;
+	extern int maxnodes;
 
 	/*
 	 * Do any early init stuff .. einit_tbl[] etc.
@@ -122,7 +117,9 @@
 	sn_mp_setup();
 
 	DBG("--> sgi_master_io_infr_init: calling per_hub_init(0).\n");
-	per_hub_init(0); /* Need to get and send in actual cnode number */
+	for (cnode = 0; cnode < maxnodes; cnode++) {
+		per_hub_init(cnode);
+	}
 
 	/* We can do headless hub cnodes here .. */
 
@@ -188,7 +185,7 @@
 	/* Emulate cboot() .. */
 	mlreset(1); /* This is a slave cpu */
 
-	per_hub_init(0); /* Need to get and send in actual cnode number */
+	// per_hub_init(0); /* Need to get and send in actual cnode number */
 
 	/* Done */
 }
@@ -212,12 +209,8 @@
 	 * do not currently support yet .. just a hack for now.
 	 */
 #ifdef NUMA_BASE
-	DBG("sn_mp_setup(): maxnodes= %d  numnodes= %d\n", maxnodes,numnodes);
         maxnodes = numnodes;
-#ifdef SIMULATED_KLGRAPH
-	maxnodes = 1;
-	numnodes = 1;
-#endif /* SIMULATED_KLGRAPH */
+	DBG("sn_mp_setup(): maxnodes= %d  numnodes= %d\n", maxnodes,numnodes);
         printk("sn_mp_setup(): Allocating backing store for *Nodepdaindr[%2d] \n",
                 maxnodes);
 
@@ -259,6 +252,14 @@
 	 *      ml/SN/promif.c
 	 */
 
+#ifdef CONFIG_IA64_SGI_SN1
+	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
+		/* Skip holes in CPU space */
+		if (cpu_enabled(cpu)) {
+			init_platform_pda(cpu);
+		}
+	}
+#endif
 	for (cnode = 0; cnode < maxnodes; cnode++) {
 		/*
 		 * Set up platform-dependent nodepda fields.
@@ -267,29 +268,7 @@
 		 */
 		DBG("sn_mp_io_setup: calling init_platform_nodepda(%2d)\n",cnode);
 		init_platform_nodepda(Nodepdaindr[cnode], cnode);
-
-		/*
-		 * This routine clears the Hub's Interrupt registers.
-		 */
-#ifndef CONFIG_IA64_SGI_IO
-		/*
-		 * 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));
-#endif
 	}
-
-#ifdef CONFIG_IA64_SGI_IO
-	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-		/* Skip holes in CPU space */
-		if (cpu_enabled(cpu)) {
-			init_platform_pda(cpu);
-		}
-	}
-#endif
-
 	/*
 	 * Initialize platform-dependent vertices in the hwgraph:
 	 *	module
@@ -309,4 +288,26 @@
 	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 < maxnodes; cnode++) {
+
+		/*
+		 * This routine clears the Hub's Interrupt registers.
+		 */
+#ifdef CONFIG_IA64_SGI_SN1
+		/*
+		 * We need to move this intr_clear_all() routine 
+		 * from SN/intr.c to a more appropriate file.
+		 * Talk to Al Mayer.
+		 */
+                intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
+		/* now init the hub */
+	//	per_hub_init(cnode);
+#endif
+	}
+
+#if defined(CONFIG_IA64_SGI_SYNERGY_PERF)
+	synergy_perf_init();
+#endif /* CONFIG_IA64_SGI_SYNERGY_PERF */
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/sgi_io_sim.c linux/arch/ia64/sn/io/sgi_io_sim.c
--- v2.4.3/linux/arch/ia64/sn/io/sgi_io_sim.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/sgi_io_sim.c	Thu Apr  5 12:51:47 2001
@@ -17,9 +17,6 @@
 #include <asm/sn/sn_private.h>
 #include <asm/sn/synergy.h>
 
-cnodeid_t nasid_to_compact_node[MAX_NASIDS];
-nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
-cnodeid_t cpuid_to_compact_node[MAXCPUS];
 cpuid_t         master_procid = 0;
 int maxnodes;
 char arg_maxnodes[4];
@@ -42,12 +39,6 @@
         return (strlen(s) != 0);
 }
 
-
-void pciba_init(void)
-{
-	FIXME("pciba_init : no-op\n");
-}
-
 void xbmon_init(void)
 {
 	FIXME("xbmon_init : no-op\n");
@@ -82,7 +73,7 @@
  * Routines provided by ml/SN/promif.c.
  */
 static __psunsigned_t master_bridge_base = (__psunsigned_t)NULL;
-static nasid_t console_nasid;
+nasid_t console_nasid;
 static char console_wid;
 static char console_pcislot;
 
@@ -90,19 +81,12 @@
 set_master_bridge_base(void)
 {
 
-#ifdef SIMULATED_KLGRAPH
-	printk("set_master_bridge_base: SIMULATED_KLGRAPH FIXME hardwired master.\n");
-	console_nasid = 0;
-	console_wid = 0x8;
-	console_pcislot = 0x2;
-#else
         console_nasid = KL_CONFIG_CH_CONS_INFO(master_nasid)->nasid;
         console_wid = WIDGETID_GET(KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base);
         console_pcislot = KL_CONFIG_CH_CONS_INFO(master_nasid)->npci;
-#endif /* SIMULATED_KLGRAPH */
-
         master_bridge_base = (__psunsigned_t)NODE_SWIN_BASE(console_nasid,
                                                             console_wid);
+	FIXME("WARNING: set_master_bridge_base: NON NASID 0 DOES NOT WORK\n");
 }
 
 int
@@ -133,21 +117,6 @@
         } else {
                 return 0;
         }
-}
-
-cnodeid_t
-nasid_to_compact_nodeid(nasid_t nasid)
-{
-        ASSERT(nasid >= 0 && nasid < MAX_NASIDS);
-        return nasid_to_compact_node[nasid];
-}
-
-nasid_t
-compact_to_nasid_nodeid(cnodeid_t cnode)
-{
-        ASSERT(cnode >= 0 && cnode <= MAX_COMPACT_NODES);
-        ASSERT(compact_to_nasid_node[cnode] >= 0);
-        return compact_to_nasid_node[cnode];
 }
 
 /*
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/stubs.c linux/arch/ia64/sn/io/stubs.c
--- v2.4.3/linux/arch/ia64/sn/io/stubs.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/stubs.c	Thu Apr  5 12:51:47 2001
@@ -31,8 +31,6 @@
 int force_fire_and_forget;
 int ignore_conveyor_override;
 
-#define spinlock_init(x,name) mutex_init(x, MUTEX_DEFAULT, name);
-
 devfs_handle_t dummy_vrtx;	/* Needed for cpuid_to_vertex() in hack.h */
 
 
@@ -105,32 +103,6 @@
 	return((zone_t *)0);
 }
 
-uint64_t
-rmalloc(struct map *mp, size_t size)
-{
-	FIXME("rmalloc : returns NULL");
-	return((uint64_t)0);
-}
-
-void
-rmfree(struct map *mp, size_t size, uint64_t a)
-{
-	FIXME("rmfree : no-op");
-}
-
-struct map *
-rmallocmap(uint64_t mapsiz)
-{
-	FIXME("rmallocmap : returns NULL");
-	return((struct map *)0);
-}
-
-void
-rmfreemap(struct map *mp)
-{
-	FIXME("rmfreemap : no-op");
-}
-
 int
 compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr)
 {
@@ -170,40 +142,6 @@
 ioc3_console_vhdl_get(void)
 	{FIXME("ioc3_console_vhdl_get"); return( (devfs_handle_t)-1);}
 
-
-#if 0
-#define io_splock(l) 1
-#define io_spunlock(l,s)
-
-#define spinlock_destroy(a)     /* needed by pcibr_detach() */
-#define mutex_spinlock(a) 0
-#define mutex_spinunlock(a,b)
-#define mutex_init(a,b,c)               ;
-#define mutex_lock(a,b)                 ;
-#define mutex_unlock(a)                 ;
-#define dev_to_vhdl(dev) 0
-#define get_timestamp() 0
-#define us_delay(a)
-#define v_mapphys(a,b,c) 0
-#define splhi()  0
-#define splx(s)
-#define spinlock_init(x,name) mutex_init(x, MUTEX_DEFAULT, name);
-#endif /* 0 */
-
-int
-cap_able(uint64_t x)
-{
-	FIXME("cap_able : returns 1");
-	return(1);
-}
-
-int
-cap_able_cred(uint64_t a, uint64_t b)
-{
-	FIXME("cap_able_cred : returns 1");
-	return(1);
-}
-
 void
 nic_vmc_check(devfs_handle_t vhdl, char *nicinfo)
 {
@@ -236,21 +174,5 @@
               uint64_t value)
 {
 	FIXME("vector_write_node\n");
-	return(0);
-}
-
-int
-atomicAddInt(int *int_ptr, int value)
-{
-//	FIXME("atomicAddInt : simple add\n");
-	*int_ptr += value;
-	return(0);
-}
-
-int
-atomicClearInt(int *int_ptr, int value)
-{
-	FIXME("atomicClearInt : simple clear\n");
-	*int_ptr &= ~value;
 	return(0);
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/xbow.c linux/arch/ia64/sn/io/xbow.c
--- v2.4.3/linux/arch/ia64/sn/io/xbow.c	Tue Feb 13 14:13:43 2001
+++ linux/arch/ia64/sn/io/xbow.c	Thu Apr  5 12:51:47 2001
@@ -17,19 +17,18 @@
 #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>
 
-#define DEBUG		1
-#define XBOW_DEBUG	1
+/* #define DEBUG		1 */
+/* #define XBOW_DEBUG	1 */
 
 
 /*
  * Files needed to get the device driver entry points
  */
 
-/* #include <asm/cred.h> */
-
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/xtalk/xtalk.h>
 #include <asm/sn/xtalk/xswitch.h>
@@ -66,7 +65,7 @@
     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];
-    lock_t                  xbow_perf_lock;
+    spinlock_t              xbow_perf_lock;
     int                     link_monitor;
     widget_cfg_t	   *wpio[MAX_XBOW_PORTS];	/* cached PIO pointer */
 
@@ -74,7 +73,7 @@
      * destination port since contention happens there.
      * Implicit mapping from xbow ports (8..f) -> (0..7) array indices.
      */
-    lock_t		    xbow_bw_alloc_lock;		/* bw allocation lock */
+    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 */
 };
@@ -118,15 +117,8 @@
 
 int                     xbow_disable_llp_monitor(devfs_handle_t);
 int                     xbow_enable_llp_monitor(devfs_handle_t);
-
-#ifdef IRIX
-int			xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t,
-				unsigned long long, unsigned long long);
-#else
 int                     xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t,
                                 unsigned long long, unsigned long long);
-#endif
-
 
 xswitch_reset_link_f    xbow_reset_link;
 
@@ -237,7 +229,11 @@
     int			    xbow_num;
 	
 #if DEBUG && ATTACH_DEBUG
-    cmn_err(CE_CONT, "%v: xbow_attach\n", conn);
+#if defined(SUPPORT_PRINTING_V_FORMAT
+    printk("%v: xbow_attach\n", conn);
+#else
+    printk("0x%x: xbow_attach\n", conn);
+#endif
 #endif
 
     /*
@@ -261,7 +257,9 @@
      * 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);
 
@@ -283,8 +281,7 @@
                         S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
                         /* &hcl_fops */ (void *)&vhdl, NULL);
     if (!vhdl) {
-        printk("xbow_attach: Unable to create char device for xbow conn
-0x%p\n",
+        printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n",
                 conn);
     }
 
@@ -306,11 +303,7 @@
     /* Add xbow number as a suffix to the hwgraph name of the xbow.
      * This is helpful while looking at the error/warning messages.
      */
-#if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
     xbow_num = 0;
-#else
-    xbow_num = xswitch_id_get(busv);
-#endif
 
     /*
      * get the name of this xbow vertex and keep the info.
@@ -341,7 +334,7 @@
      * Crossbow is DOWNREV: these chips are not good
      * to have around, and the operator should be told.
      */
-#ifdef IRIX
+#ifdef	LATER
 #if !DEBUG
     if (
 #if SHOW_REVS
@@ -349,8 +342,7 @@
 #endif	/* SHOW_REVS */
 	   (rev < XBOW_REV_1_1))
 #endif	/* !DEBUG  */
-	cmn_err((rev < XBOW_REV_1_1) ? CE_WARN : CE_CONT,
-		"%sCrossbow ASIC: rev %s (code=%d) at %s%s",
+	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" :
@@ -362,14 +354,13 @@
 		"unknown",
 		rev, soft->name,
 		(rev < XBOW_REV_1_1) ? "" : "\n");
-#endif	/* IRIX */
-
-    spinlock_init(&soft->xbow_perf_lock, "xbow_perf_lock");
+#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 */
-    spinlock_init(&soft->xbow_bw_alloc_lock, "xbow_bw_alloc_lock");
+    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 */
@@ -403,7 +394,7 @@
     xwidget_error_register(conn, xbow_error_handler, soft);
 
 #else
-    printk("xbow_attach: Fixme: we bypassed attaching xbow error interrupt.\n");
+    FIXME("xbow_attach: Fixme: we bypassed attaching xbow error interrupt.\n");
 #endif /* LATER */
 
     /*
@@ -479,8 +470,6 @@
 int
 xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
 {
-    if (!_CAP_CRABLE((uint64_t)credp, CAP_DEVICE_MGT))
-	return EPERM;
     return 0;
 
 }
@@ -525,28 +514,9 @@
 	char		devname[MAXDEVNAME];
 	xwidget_info_t	xwidget_info;
 	int		i;
-#if IP27
-	cnodeid_t	cnodeid = CNODEID_NONE;
-#endif
 
 	vertex_to_name(dev, devname, MAXDEVNAME);
 
-#if IP30
-	/* If there is a ".connection" edge from this vertex,
-	 * then it must be "/hw/node" vertex. Return the widget
-	 * number for heart: 8.
-	 */
-	if (hwgraph_edge_get(dev, EDGE_LBL_CONN, &tdev) ==
-			GRAPH_SUCCESS) {
-		return ((xwidgetnum_t) 8);
-	}
-#elif IP27
-	if ((cnodeid = nodevertex_to_cnodeid(dev)) != CNODEID_NONE) {
-		ASSERT(cnodeid < maxnodes);
-		return(hub_widget_id(COMPACT_TO_NASID_NODEID(cnodeid)));
-	}
-#endif
-
 	/* If this is a pci controller vertex, traverse up using
 	 * the ".." links to get to the widget.
 	 */
@@ -601,7 +571,7 @@
     ASSERT_ALWAYS(rc != 0);
 #endif
     switch (cmd) {
-#ifdef IRIX
+#ifdef LATER
     case XBOWIOC_PERF_ENABLE:
     case XBOWIOC_PERF_DISABLE:
 	{
@@ -630,7 +600,7 @@
 	}
 #endif
 
-#ifdef IRIX
+#ifdef LATER
     case XBOWIOC_PERF_GET:
 	{
 	    xbow_perf_link_t       *xbow_perf_cnt;
@@ -652,10 +622,6 @@
 #endif
 
     case XBOWIOC_LLP_ERROR_ENABLE:
-	if (!_CAP_CRABLE((uint64_t)cr, CAP_DEVICE_MGT)) {
-	    error = EPERM;
-	    break;
-	}
 	if ((error = xbow_enable_llp_monitor(vhdl)) != 0)
 	    error = EINVAL;
 
@@ -663,16 +629,12 @@
 
     case XBOWIOC_LLP_ERROR_DISABLE:
 
-	if (!_CAP_CRABLE((uint64_t)cr, CAP_DEVICE_MGT)) {
-	    error = EPERM;
-	    break;
-	}
 	if ((error = xbow_disable_llp_monitor(vhdl)) != 0)
 	    error = EINVAL;
 
 	break;
 
-#ifdef IRIX
+#ifdef LATER
     case XBOWIOC_LLP_ERROR_GET:
 	{
 	    xbow_link_status_t     *xbow_llp_status;
@@ -693,17 +655,12 @@
 	}
 #endif
 
-#ifdef IRIX
+#ifdef LATER
     case GIOCSETBW:
 	{
 	    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;
@@ -863,14 +820,14 @@
     xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
 }
 
-#define	XEM_ADD_STR(s)		cmn_err(CE_CONT, "%s", (s))
-#define	XEM_ADD_NVAR(n,v)	cmn_err(CE_CONT, "\t%20s: 0x%x\n", (n), (v))
+#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 IRIX
+#ifdef LATER
 static void
 xem_add_ioe(ioerror_t *ioe)
 {
@@ -891,7 +848,7 @@
 }
 
 #define XEM_ADD_IOE()	(xem_add_ioe(ioe))
-#endif	/* IRIX */
+#endif	/* LATER */
 
 int                     xbow_xmit_retry_errors = 0;
 
@@ -971,7 +928,6 @@
 static void
 xbow_errintr_handler(intr_arg_t arg)
 {
-#ifdef IRIX
     ioerror_t               ioe[1];
     xbow_soft_t             soft = (xbow_soft_t) arg;
     xbow_t                 *xbow = soft->base;
@@ -1065,9 +1021,8 @@
 		    xwidget_vhdl = xbow_widget_lookup(soft->busv,port);
 		    xwidget_name = xwidget_name_get(xwidget_vhdl);
 
-#ifdef IRIX
-		    cmn_err(CE_CONT,
-			    "%s port %X[%s] XIO Bus Error",
+#ifdef	LATER
+		    printk("%s port %X[%s] XIO Bus Error",
 			    soft->name, port, xwidget_name);
 		    if (link_status & XB_STAT_MULTI_ERR)
 			XEM_ADD_STR("\tMultiple Errors\n");
@@ -1089,8 +1044,7 @@
 			XEM_ADD_STR("\tMaximum Request Timeout\n");
 		    if (link_status & XB_STAT_SRC_TOUT_ERR)
 			XEM_ADD_STR("\tSource Timeout Error\n");
-#endif
-
+#endif	/* LATER */
 		    {
 			int                     other_port;
 
@@ -1130,8 +1084,7 @@
 			| XB_WID_STAT_XTALK_ERR
 			| XB_WID_STAT_REG_ACC_ERR)) {
 
-	    cmn_err(CE_CONT,
-		    "%s Port 0 XIO Bus Error",
+	    printk("%s Port 0 XIO Bus Error",
 		    soft->name);
 	    if (wid_stat & XB_WID_STAT_MULTI_ERR)
 		XEM_ADD_STR("\tMultiple Error\n");
@@ -1150,9 +1103,8 @@
 	XEM_ADD_VAR(wid_err_upper);
 	XEM_ADD_VAR(wid_err_lower);
 	XEM_ADD_VAR(wid_err_addr);
-	cmn_err_tag(8, CE_PANIC, "XIO Bus Error");
+	PRINT_PANIC("XIO Bus Error");
     }
-#endif
 }
 #endif	/* LATER */
 
@@ -1180,7 +1132,6 @@
 		      ioerror_mode_t mode,
 		      ioerror_t *ioerror)
 {
-#ifdef IRIX
     int                     retval = IOERROR_WIDGETLEVEL;
 
     xbow_soft_t             soft = (xbow_soft_t) einfo;
@@ -1204,7 +1155,7 @@
     busv = soft->busv;
 
 #if DEBUG && ERROR_DEBUG
-    cmn_err(CE_CONT, "%s: xbow_error_handler\n", soft->name, busv);
+    printk("%s: xbow_error_handler\n", soft->name, busv);
 #endif
 
     port = IOERROR_GETVALUE(ioerror, widgetnum);
@@ -1217,14 +1168,12 @@
 	    return IOERROR_HANDLED;
 
 	if (error_code & IOECODE_DMA) {
-	    cmn_err(CE_ALERT,
-		    "DMA error blamed on Crossbow at %s\n"
+	    PRINT_ALERT("DMA error blamed on Crossbow at %s\n"
 		    "\tbut Crosbow never initiates DMA!",
 		    soft->name);
 	}
 	if (error_code & IOECODE_PIO) {
-	    cmn_err(CE_ALERT,
-		    "PIO Error on XIO Bus %s\n"
+	    PRINT_ALERt("PIO Error on XIO Bus %s\n"
 		    "\tattempting to access XIO controller\n"
 		    "\twith offset 0x%X",
 		    soft->name,
@@ -1258,14 +1207,12 @@
 	    return IOERROR_HANDLED;
 
 	if (error_code & IOECODE_DMA) {
-	    cmn_err(CE_ALERT,
-		    "DMA error blamed on XIO port at %s/%d\n"
+	    PRINT_ALERT("DMA error blamed on XIO port at %s/%d\n"
 		    "\tbut Crossbow does not support that port",
 		    soft->name, port);
 	}
 	if (error_code & IOECODE_PIO) {
-	    cmn_err(CE_ALERT,
-		    "PIO Error on XIO Bus %s\n"
+	    PRINT_ALERT("PIO Error on XIO Bus %s\n"
 		    "\tattempting to access XIO port %d\n"
 		    "\t(which Crossbow does not support)"
 		    "\twith offset 0x%X",
@@ -1309,14 +1256,12 @@
 	    return IOERROR_HANDLED;
 
 	if (error_code & IOECODE_DMA) {
-	    cmn_err(CE_ALERT,
-		    "DMA error blamed on XIO port at %s/%d\n"
+	    PRINT_ALERT("DMA error blamed on XIO port at %s/%d\n"
 		    "\tbut there is no device connected there.",
 		    soft->name, port);
 	}
 	if (error_code & IOECODE_PIO) {
-	    cmn_err(CE_ALERT,
-		    "PIO Error on XIO Bus %s\n"
+	    PRINT_ALERT("PIO Error on XIO Bus %s\n"
 		    "\tattempting to access XIO port %d\n"
 		    "\t(which has no device connected)"
 		    "\twith offset 0x%X",
@@ -1349,16 +1294,14 @@
 	if (mode == MODE_DEVPROBE)
 	    return IOERROR_HANDLED;
 
-	cmn_err(CE_ALERT,
-		"%s%sError on XIO Bus %s port %d",
+	PRINT_ALERT("%s%sError on XIO Bus %s port %d",
 		(error_code & IOECODE_DMA) ? "DMA " : "",
 		(error_code & IOECODE_PIO) ? "PIO " : "",
 		soft->name, port);
 
 	if ((error_code & IOECODE_PIO) &&
 	    (IOERROR_FIELDVALID(ioerror, xtalkaddr))) {
-	    cmn_err(CE_CONT,
-		    "\tAccess attempted to offset 0x%X\n",
+	    printk("\tAccess attempted to offset 0x%X\n",
 		    IOERROR_GETVALUE(ioerror, xtalkaddr));
 	}
 	if (link_aux_status & XB_AUX_LINKFAIL_RST_BAD)
@@ -1393,16 +1336,14 @@
     if (retval == IOERROR_UNHANDLED) {
 	retval = IOERROR_PANIC;
 
-	cmn_err(CE_ALERT,
-		"%s%sError on XIO Bus %s port %d",
+	PRINT_ALERT("%s%sError on XIO Bus %s port %d",
 		(error_code & IOECODE_DMA) ? "DMA " : "",
 		(error_code & IOECODE_PIO) ? "PIO " : "",
 		soft->name, port);
 
 	if ((error_code & IOECODE_PIO) &&
 	    (IOERROR_FIELDVALID(ioerror, xtalkaddr))) {
-	    cmn_err(CE_CONT,
-		    "\tAccess attempted to offset 0x%X\n",
+	    printk("\tAccess attempted to offset 0x%X\n",
 		    IOERROR_GETVALUE(ioerror, xtalkaddr));
 	}
     }
@@ -1428,7 +1369,6 @@
      */
 
     return retval;
-#endif /* IRIX */
 }
 
 #endif	/* LATER */
@@ -1440,7 +1380,8 @@
     xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
     xbow_perf_link_t       *xbow_plink = xbow_soft->xbow_perflink;
     xbow_perfcount_t        perf_reg;
-    int                     link, s, i;
+    unsigned long           s;
+    int                     link, i;
 
     for (i = 0; i < XBOW_PERF_COUNTERS; i++, xbow_perf++) {
 	if (xbow_perf->xp_mode == XBOW_MONITOR_NONE)
@@ -1460,7 +1401,7 @@
     }
     /* Do port /mode multiplexing here */
 
-#ifdef IRIX
+#ifdef LATER
     (void) timeout(xbow_update_perf_counters,
 		   (void *) (__psunsigned_t) vhdl, XBOW_PERF_TIMEOUT);
 #endif
@@ -1484,7 +1425,8 @@
     xbow_linkctrl_t         xbow_link_ctrl;
     xbow_t                 *xbow = xbow_soft->base;
     xbow_perfcount_t        perf_reg;
-    int                     s, i;
+    unsigned long           s;
+    int                     i;
 
     link -= BASE_XBOW_PORT;
     if ((link < 0) || (link >= MAX_XBOW_PORTS))
@@ -1525,7 +1467,7 @@
     *(xbowreg_t *) xbow_perf->xp_perf_reg = perf_reg.xb_counter_val;
     xbow_perf->xp_current = perf_reg.xb_perf.count;
 
-#ifdef IRIX
+#ifdef LATER
     (void) timeout(xbow_update_perf_counters,
 		   (void *) (__psunsigned_t) vhdl, XBOW_PERF_TIMEOUT);
 #endif
@@ -1578,13 +1520,13 @@
 	    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 IRIX
-	    cmn_err(CE_WARN, "link %d[%s]: bad status 0x%x\n",
+#ifdef	LATER
+	    PRINT_WARNING("link %d[%s]: bad status 0x%x\n",
 		    link, xwidget_name, lnk_sts.linkstatus);
 #endif
 	}
     }
-#ifdef IRIX
+#ifdef LATER
     if (xbow_soft->link_monitor)
 	(void) timeout(xbow_update_llp_status,
 		       (void *) (__psunsigned_t) vhdl, XBOW_STATS_TIMEOUT);
@@ -1611,7 +1553,7 @@
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
 
-#ifdef IRIX
+#ifdef LATER
     (void) timeout(xbow_update_llp_status,
 		   (void *) (__psunsigned_t) vhdl, XBOW_STATS_TIMEOUT);
 #endif
@@ -1690,7 +1632,7 @@
     int                     i;
     xb_linkregs_t          *link;
 
-#ifdef IRIX
+#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);
@@ -1702,7 +1644,7 @@
 	xbow = (xbow_t *) regs;
     }
 
-#ifdef IRIX
+#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,
@@ -1716,7 +1658,7 @@
 
     for (i = 8; i <= 0xf; i++) {
 	link = &xbow->xb_link(i);
-#ifdef IRIX
+#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,
@@ -1795,7 +1737,7 @@
     xbow_soft_t             soft = xbow_soft_get(vhdl);
     volatile xbowreg_t     *xreg;
     xbowreg_t               mask;
-    int                     s;
+    unsigned long           s;
     int                     error = 0;
     bandwidth_t             old_bw_BYTES, req_bw_BYTES;
     xbowreg_t               old_xreg;
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/xswitch.c linux/arch/ia64/sn/io/xswitch.c
--- v2.4.3/linux/arch/ia64/sn/io/xswitch.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/io/xswitch.c	Thu Apr  5 12:51:47 2001
@@ -88,13 +88,15 @@
 
     xswitch_info = (xswitch_info_t)
 	hwgraph_fastinfo_get(xwidget);
-#ifdef IRIX
+#ifdef	LATER
     if ((xswitch_info != NULL) &&
 	(xswitch_info->fingerprint != xswitch_info_fingerprint))
-	cmn_err(CE_PANIC, "%v xswitch_info_get bad fingerprint", xwidget);
+#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
-
-    printk("xswitch_info_get: xwidget 0x%p xswitch_info 0x%p\n", xwidget, xswitch_info);
+#endif	/* LATER */
 
     return (xswitch_info);
 }
@@ -118,9 +120,9 @@
 xswitch_info_vhdl_get(xswitch_info_t xswitch_info,
 		      xwidgetnum_t port)
 {
-#ifdef IRIX
+#ifdef	LATER
     if (xswitch_info == NULL)
-	cmn_err(CE_PANIC, "xswitch_info_vhdl_get: null xswitch_info");
+	PRINT_PANIC("xswitch_info_vhdl_get: null xswitch_info");
 #endif
 
 #if XSWITCH_CENSUS_PORT_MIN
@@ -196,8 +198,6 @@
 					       GRAPH_VERTEX_NONE);
 	}
 	xswitch_info_set(xwidget, xswitch_info);
-	printk("xswitch_info_new: xswitch_info_set xwidget 0x%p, xswitch_info 0x%p\n",
-		xwidget, xswitch_info);
     }
     return xswitch_info;
 }
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/io/xtalk.c linux/arch/ia64/sn/io/xtalk.c
--- v2.4.3/linux/arch/ia64/sn/io/xtalk.c	Tue Feb 13 14:13:43 2001
+++ linux/arch/ia64/sn/io/xtalk.c	Thu Apr  5 12:51:47 2001
@@ -71,6 +71,7 @@
 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, intr_func_t, intr_arg_t, xtalk_intr_setfunc_t, void *, void *);
 void                    xtalk_intr_disconnect(xtalk_intr_t);
@@ -318,7 +319,7 @@
 			       unsigned flags)
 {
 #if DEBUG
-    cmn_err(CE_PANIC, "null_xtalk_early_piotrans_addr");
+    PRINT_PANIC("null_xtalk_early_piotrans_addr");
 #endif
     return NULL;
 }
@@ -439,6 +440,19 @@
 	(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.
@@ -527,7 +541,11 @@
     xwidget_info_t          xwidget_info;
 
 #if DEBUG && ERROR_DEBUG
-    cmn_err(CE_CONT, "%v: xtalk_error_handler\n", xconn);
+#ifdef SUPPORT_PRINTING_V_FORMAT
+    printk("%v: xtalk_error_handler\n", xconn);
+#else
+    printk("%x: xtalk_error_handler\n", xconn);
+#endif
 #endif
 
     xwidget_info = xwidget_info_get(xconn);
@@ -549,9 +567,13 @@
 	(mode == MODE_DEVREENABLE))
 	return IOERROR_HANDLED;
 
-#ifdef IRIX
-    cmn_err(CE_WARN, "Xbow at %v encountered Fatal error", xconn);
+#ifdef	LATER
+#ifdef SUPPORT_PRINTING_V_FORMAT
+    PRINT_WARNING("Xbow at %v encountered Fatal error", xconn);
+#else
+    PRINT_WARNING("Xbow at %x encountered Fatal error", xconn);
 #endif
+#endif	/* LATER */
     ioerror_dump("xtalk", error_code, mode, ioerror);
 
     return IOERROR_UNHANDLED;
@@ -648,13 +670,6 @@
     return (xtalk_intr->xi_sfarg);
 }
 
-
-int
-xtalk_intr_flags_get(xtalk_intr_t xtalk_intr)
-{
-	return(xtalk_intr->xi_flags);
-}
-
 /****** Generic crosstalk pio interfaces ******/
 devfs_handle_t
 xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap)
@@ -726,11 +741,15 @@
     widget_info = (xwidget_info_t)
 	hwgraph_fastinfo_get(xwidget);
 
-#ifdef IRIX
+#ifdef	LATER
     if ((widget_info != NULL) &&
 	(widget_info->w_fingerprint != widget_info_fingerprint))
-	cmn_err(CE_PANIC, "%v bad xwidget_info", xwidget);
+#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);
 }
@@ -894,7 +913,7 @@
 
     return cdl_add_driver(xtalk_registry,
 			  part_num, mfg_num,
-			  driver_prefix, flags);
+			  driver_prefix, flags, NULL);
 }
 
 /*
@@ -910,7 +929,7 @@
      */
     ASSERT(xtalk_registry != NULL);
 
-    cdl_del_driver(xtalk_registry, driver_prefix);
+    cdl_del_driver(xtalk_registry, driver_prefix, NULL);
 }
 
 /*
@@ -963,7 +982,6 @@
      * long as we have it, we can use it elsewhere.
      */
     s = dev_to_name(widget,devnm,MAXDEVNAME);
-    printk("xwidget_register: dev_to_name widget id 0x%p, s = %s\n", widget, s);
     widget_info->w_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
     strcpy(widget_info->w_name,s);
     
@@ -985,7 +1003,8 @@
     if (aa)
 	    async_attach_add_info(widget, aa);
 
-    return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num, widget);
+    return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
+                          widget, 0);
 }
 
 /*
@@ -1009,8 +1028,8 @@
     
     hwid = &(widget_info->w_hwid);
 
-    cdl_del_connpt(xtalk_registry, hwid->part_num, 
-		   hwid->mfg_num, widget);
+    cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
+                   widget, 0);
 
     /* Clean out the xwidget information */
     (void)kfree(widget_info->w_name);
@@ -1051,7 +1070,7 @@
 
     xswitch_reset_link(xwidget);
     info = xwidget_info_get(xwidget);
-#ifdef IRIX
+#ifdef LATER
     ASSERT_ALWAYS(info != NULL);
 #endif
 
@@ -1083,26 +1102,7 @@
 	ASSERT(info != NULL);
 	return(xwidget_info_name_get(info));
 }
-/*
- * xtalk_device_powerup
- *	Reset and initialize the specified xtalk widget
- */
-int 
-xtalk_device_powerup(devfs_handle_t xbus_vhdl, xwidgetnum_t widget)
-{
-#ifndef CONFIG_IA64_SGI_IO
-	extern void	io_xswitch_widget_init(devfs_handle_t,
-					       devfs_handle_t,
-					       xwidgetnum_t,
-					       async_attach_t);
-	io_xswitch_widget_init(xbus_vhdl, 
-			       hwgraph_connectpt_get(xbus_vhdl),
-			       widget,
-			       NULL);
-#endif	/* CONFIG_IA64_SGI_IO */
-	
-	return(0);
-}
+
 /*
  * xtalk_device_shutdown
  *	Disable  the specified xtalk widget and clean out all the software
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/Makefile linux/arch/ia64/sn/sn1/Makefile
--- v2.4.3/linux/arch/ia64/sn/sn1/Makefile	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/sn1/Makefile	Thu Apr  5 12:51:47 2001
@@ -8,7 +8,7 @@
 EXTRA_CFLAGS	:= -DSN -DLANGUAGE_C=1 -D_LANGUAGE_C=1 -I. -DBRINGUP \
 		   -DDIRECT_L1_CONSOLE -DNUMA_BASE -DSIMULATED_KLGRAPH \
 		   -DNUMA_MIGR_CONTROL -DLITTLE_ENDIAN -DREAL_HARDWARE \
-		   -DNEW_INTERRUPTS -DCONFIG_IA64_SGI_IO
+		   -DNEW_INTERRUPTS
 
 .S.s:
 	$(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $<
@@ -18,18 +18,13 @@
 all: sn1.a
 
 O_TARGET        = sn1.a
-O_HEADERS       =
-O_OBJS          = irq.o setup.o iomv.o mm.o smp.o synergy.o sn1_asm.o \
-		discontig.o
 
-ifeq ($(CONFIG_IA64_SGI_AUTOTEST),y)
-O_OBJS          += llsc4.o
-endif
+obj-y          = irq.o setup.o iomv.o mm.o smp.o synergy.o sn1_asm.o \
+		discontig.o probe.o error.o sv.o
 
-
-ifeq ($(CONFIG_IA64_GENERIC),y)
-O_OBJS		+= machvec.o
-endif
+obj-$(CONFIG_IA64_SGI_AUTOTEST)	+= llsc4.o
+obj-$(CONFIG_IA64_GENERIC)	+= machvec.o
+obj-$(CONFIG_MODULES)		+= sn1_ksyms.o
 
 clean::
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/discontig.c linux/arch/ia64/sn/sn1/discontig.c
--- v2.4.3/linux/arch/ia64/sn/sn1/discontig.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/sn1/discontig.c	Thu Apr  5 12:51:47 2001
@@ -139,35 +139,6 @@
 	dump_bootmem_info() ;
 }
 
-void __init
-discontig_paging_init(void)
-{
-	int i;
-	unsigned long max_dma, zones_size[MAX_NR_ZONES];
-	void dump_node_data(void);
-
-        max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-	for (i = 0; i < numnodes; i++) {
-	       extern void free_unused_memmap_node(int);
-               unsigned long startpfn = __pa((void *)NODE_START(i)) >> PAGE_SHIFT;
-               unsigned long numpfn = NODE_SIZE(i) >> PAGE_SHIFT;
-               memset(zones_size, 0, sizeof(zones_size));
-
-               if ((startpfn + numpfn) < max_dma) {
-                       zones_size[ZONE_DMA] = numpfn;
-               } else if (startpfn > max_dma) {
-                       zones_size[ZONE_NORMAL] = numpfn;
-               } else {
-                       zones_size[ZONE_DMA] = (max_dma - startpfn);
-                       zones_size[ZONE_NORMAL] = numpfn - zones_size[ZONE_DMA];
-               }
-               free_area_init_node(i, NODE_DATA(i), NULL, zones_size, startpfn<<PAGE_SHIFT, 0);
-	       free_unused_memmap_node(i);
-	}
-	dump_node_data();
-}
-
-
 void
 dump_node_data(void)
 {
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/error.c linux/arch/ia64/sn/sn1/error.c
--- v2.4.3/linux/arch/ia64/sn/sn1/error.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ia64/sn/sn1/error.c	Thu Apr  5 12:51:47 2001
@@ -0,0 +1,149 @@
+
+
+/*
+ * SN1 Platform specific error Support
+ *
+ * Copyright (C) 2001 Silicon Graphics, Inc.
+ * Copyright (C) 2001 Alan Mayer (ajm@sgi.com)
+ */
+
+
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/ptrace.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/smp.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/sn1/bedrock.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/addrs.h>
+
+void
+snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs) {
+	unsigned long long intpend_val;
+	unsigned long long bit;
+
+	switch (irq) {
+	case SGI_UART_IRQ:
+		// This isn't really an error interrupt.  We're just
+		// here because we have to do something with them.
+		// This is probably wrong, and this code will be
+		// removed.
+		intpend_val = LOCAL_HUB_L(PI_INT_PEND0);
+		if ( (bit = ~(1L<<GFX_INTR_A)) ==
+			(intpend_val & ~(1L<<GFX_INTR_A)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			return;
+		}
+		if ( (bit = ~(1L<<GFX_INTR_B)) ==
+			(intpend_val & ~(1L<<GFX_INTR_B)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			return;
+		}
+		if ( (bit = ~(1L<<PG_MIG_INTR)) ==
+			(intpend_val & ~(1L<<PG_MIG_INTR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			return;
+		}
+		if ( (bit = ~(1L<<UART_INTR)) ==
+			(intpend_val & ~(1L<<UART_INTR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			return;
+		}
+		if ( (bit = ~(1L<<CC_PEND_A)) ==
+			(intpend_val & ~(1L<<CC_PEND_A)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			return;
+		}
+		if ( (bit = ~(1L<<CC_PEND_B)) ==
+			(intpend_val & ~(1L<<CC_PEND_B)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			return;
+		}
+		printk("Received SGI_UART_IRQ (65), but no intpend0 bits were set???\n");
+		return;
+	case SGI_HUB_ERROR_IRQ:
+		// These are mostly error interrupts of various
+		// sorts.  We need to do more than panic here, but
+		// what the heck, this is bring up.
+		intpend_val = LOCAL_HUB_L(PI_INT_PEND1);
+		
+		if ( (bit = ~(1L<<XB_ERROR)) ==
+			(intpend_val & ~(1L<<XB_ERROR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED XB_ERROR on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<LB_ERROR)) ==
+			(intpend_val & ~(1L<<LB_ERROR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED LB_ERROR on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<NACK_INT_A)) ==
+			(intpend_val & ~(1L<<NACK_INT_A)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED NACK_INT_A on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<NACK_INT_B)) ==
+			(intpend_val & ~(1L<<NACK_INT_B)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED NACK_INT_B on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<CLK_ERR_INTR)) ==
+			(intpend_val & ~(1L<<CLK_ERR_INTR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED CLK_ERR_INTR on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<COR_ERR_INTR_A)) ==
+			(intpend_val & ~(1L<<COR_ERR_INTR_A)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED COR_ERR_INTR_A on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<COR_ERR_INTR_B)) ==
+			(intpend_val & ~(1L<<COR_ERR_INTR_B)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED COR_ERR_INTR_B on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<MD_COR_ERR_INTR)) ==
+			(intpend_val & ~(1L<<MD_COR_ERR_INTR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED MD_COR_ERR_INTR on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<NI_ERROR_INTR)) ==
+			(intpend_val & ~(1L<<NI_ERROR_INTR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED NI_ERROR_INTR on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		if ( (bit = ~(1L<<MSC_PANIC_INTR)) ==
+			(intpend_val & ~(1L<<MSC_PANIC_INTR)) ) {
+			LOCAL_HUB_CLR_INTR(bit);
+			panic("RECEIVED MSC_PANIC_INTR on cpu %d, cnode %d\n",
+				smp_processor_id(), 
+				cpuid_to_cnodeid(smp_processor_id()));
+		}
+		printk("Received SGI_XB_ERROR_IRQ (182) but no intpend1 bits are set???\n");
+		return;
+	default:
+		printk("Received invalid irq in snia_error_intr_handler()/n");
+	}
+}
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/iomv.c linux/arch/ia64/sn/sn1/iomv.c
--- v2.4.3/linux/arch/ia64/sn/sn1/iomv.c	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/sn1/iomv.c	Thu Apr  5 12:51:47 2001
@@ -25,11 +25,8 @@
  		 * for accessing registers in bedrock local block
  		 * (so we don't do port&0xfff)
  		 */
-		if (port == 0x1f6 || port == 0x1f7
-			|| port == 0x3f6 || port == 0x3f7
-			|| port == 0x1f0 || port == 0x1f1
-			|| port == 0x1f3 || port == 0x1f4
-			|| port == 0x1f2 || port == 0x1f5)  {
+		if (port >= 0x1f0 && port <= 0x1f7 ||
+			port == 0x3f6 || port == 0x3f7) {
 			io_base = __IA64_UNCACHED_OFFSET | 0x00000FFFFC000000;
 			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
 		} else {
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/irq.c linux/arch/ia64/sn/sn1/irq.c
--- v2.4.3/linux/arch/ia64/sn/sn1/irq.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/sn1/irq.c	Thu Apr  5 12:51:47 2001
@@ -4,11 +4,13 @@
  * Copyright (C) 2000   Silicon Graphics
  * Copyright (C) 2000   Jack Steiner (steiner@sgi.com)
  * Copyright (C) 2000   Alan Mayer (ajm@sgi.com)
+ * Copyright (C) 2000   Kanoj Sarcar (kanoj@sgi.com)
  */
 
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <asm/current.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
@@ -30,28 +32,23 @@
 #include <asm/sn/sn1/arch.h>
 #include <asm/sn/synergy.h>
 
+#define IRQ_BIT_OFFSET 64
 
-int bit_pos_to_irq(int bit);
-int irq_to_bit_pos(int irq);
-void add_interrupt_randomness(int irq);
-void * kmalloc(size_t size, int flags);
-void kfree(const void *);
-int sgi_pci_intr_support (unsigned int, device_desc_t *, devfs_handle_t *, pciio_intr_line_t *, devfs_handle_t *);
-pciio_intr_t pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
-int request_irq(unsigned int, void (*)(int, void *, struct pt_regs *), unsigned long, const char *, void *);
-
-/* This should be dynamically allocated, at least part of it. */
-/* For the time being, though, we'll statically allocate it */
-/* because kmalloc hasn't been initiallized at the time this */
-/* array is initiallized.  One way to do it would be to statically */
-/* allocate the data for node 0, then let other nodes, as they */
-/* need it, dynamically allocate their own data space. */
-
-struct sn1_cnode_action_list *sn1_node_actions[MAX_COMPACT_NODES];
-struct sn1_cnode_action_list sn1_actions[MAX_COMPACT_NODES][256];
+int bit_pos_to_irq(int bit)
+{
+	if (bit > 118)
+		bit = 118;
+	return (bit + IRQ_BIT_OFFSET);
+}
 
+static inline int irq_to_bit_pos(int irq)
+{
+	int bit = irq - IRQ_BIT_OFFSET;
 
-extern int numnodes;
+	if (bit > 63)
+		bit -= 64;
+	return bit;
+}
 
 static unsigned int
 sn1_startup_irq(unsigned int irq)
@@ -82,6 +79,10 @@
 static void
 sn1_end_irq(unsigned int irq)
 {
+	int bit;
+
+	bit = irq_to_bit_pos(irq);
+	LOCAL_HUB_CLR_INTR(bit);
 }
 
 static void
@@ -89,38 +90,6 @@
 {
 }
 
-
-static void
-sn1_handle_irq(int irq, void *dummy, struct pt_regs *regs)
-{
-	int bit, cnode;
-	struct sn1_cnode_action_list *alp;
-	struct sn1_intr_action *ap;
-	void (*handler)(int, void *, struct pt_regs *);
-	unsigned long flags = 0;
-	int cpuid = smp_processor_id();
-
-
-	bit = irq_to_bit_pos(irq);
-	LOCAL_HUB_CLR_INTR(bit);
-	cnode = cpuid_to_cnodeid(cpuid);
-	alp = sn1_node_actions[cnode];
-	ap = alp[irq].action_list;
-	if (ap == NULL) {
-		return;
-	}
-	while (ap) {
-		flags |= ap->flags;
-		handler = ap->handler;
-		(*handler)(irq,ap->intr_arg,regs);
-		ap = ap->next;
-	}
-	if ((flags & SA_SAMPLE_RANDOM) != 0)
-                add_interrupt_randomness(irq);
-
-        return;
-}
-
 struct hw_interrupt_type irq_type_sn1 = {
         "sn1_irq",
         sn1_startup_irq,
@@ -132,134 +101,83 @@
         sn1_set_affinity_irq
 };
 
-struct irqaction sn1_irqaction = {
-	sn1_handle_irq,
-	0,
-	0,
-	NULL,
-	NULL,
-	NULL,
-};
 
 void
 sn1_irq_init (void)
 {
-	int i,j;
+	int i;
 
 	for (i = 0; i <= NR_IRQS; ++i) {
-		if (irq_desc[i].handler == &no_irq_type) {
-			irq_desc[i].handler = &irq_type_sn1;
-			if (i >=71 && i <= 181) {
-				irq_desc[i].action = &sn1_irqaction;
-			}
-		}
-	}
-
-	for (i = 0; i < numnodes; i++) {
-		sn1_node_actions[i] = sn1_actions[i];
-		memset(sn1_node_actions[i], 0,
-			sizeof(struct sn1_cnode_action_list) *
-			(IA64_MAX_VECTORED_IRQ + 1));
-		for (j=0; j<IA64_MAX_VECTORED_IRQ+1; j++) {
-			spin_lock_init(&sn1_node_actions[i][j].action_list_lock);
+		if (idesc_from_vector(i)->handler == &no_irq_type) {
+			idesc_from_vector(i)->handler = &irq_type_sn1;
 		}
 	}
 }
 
 
-int          
-sn1_request_irq (unsigned int requested_irq, void (*handler)(int, void *, struct pt_regs *),
-             unsigned long irqflags, const char * devname, void *dev_id)
-{ 
-	devfs_handle_t curr_dev;
-	devfs_handle_t dev;
-	pciio_intr_t intr_handle;
-	pciio_intr_line_t line;
-	device_desc_t dev_desc;
-        int cpuid, bit, cnode;
-	struct sn1_intr_action *ap, *new_ap;
-	struct sn1_cnode_action_list *alp;
-	int irq;
-
-	if ( (requested_irq & 0xff) == 0 ) {
-		int ret;
-
-		sgi_pci_intr_support(requested_irq,
-			&dev_desc, &dev, &line, &curr_dev);
-		intr_handle = pciio_intr_alloc(curr_dev, NULL, line, curr_dev);
-		bit = intr_handle->pi_irq;
-		cpuid = intr_handle->pi_cpu;
-		irq = bit_pos_to_irq(bit);
-		cnode = cpuid_to_cnodeid(cpuid);
-		new_ap = (struct sn1_intr_action *)kmalloc(
-			sizeof(struct sn1_intr_action), GFP_KERNEL);
-		irq_desc[irq].status = 0;
-		new_ap->handler = handler;
-		new_ap->intr_arg = dev_id;
-		new_ap->flags = irqflags;
-		new_ap->next = NULL;
-		alp = sn1_node_actions[cnode];
-
-		spin_lock(&alp[irq].action_list_lock);
-		ap = alp[irq].action_list;
-		/* check action list for "share" consistency */
-		while (ap){
-			if (!(ap->flags & irqflags & SA_SHIRQ) ) {
-				return(-EBUSY);
-				spin_unlock(&alp[irq].action_list_lock);
-			}
-			ap = ap->next;
-		}
-		ap = alp[irq].action_list;
-		if (ap) {
-			while (ap->next) {
-				ap = ap->next;
-			}
-			ap->next = new_ap;
-		} else {
-			alp[irq].action_list = new_ap;
-		}
-		ret = pciio_intr_connect(intr_handle, (intr_func_t)handler, dev_id, NULL);
-		if (ret) { /* connect failed, undo what we did. */
-			new_ap = alp[irq].action_list;
-			if (new_ap == ap) {
-				alp[irq].action_list = NULL;
-				kfree(ap);
-			} else {
-				while (new_ap->next && new_ap->next != ap) {
-					new_ap = new_ap->next;
-				}
-				if (new_ap->next == ap) {
-					new_ap->next = ap->next;
-					kfree(ap);
-				}
-			}
-		}
-			
-		spin_unlock(&alp[irq].action_list_lock);
-		return(ret);
-	} else {
-		return(request_irq(requested_irq, handler, irqflags, devname, dev_id));
-	}
-}
 
-#if !defined(CONFIG_IA64_SGI_IO)
+#if !defined(CONFIG_IA64_SGI_SN1)
 void
 sn1_pci_fixup(int arg)
 {
 }
 #endif
 
-int
-bit_pos_to_irq(int bit) {
-#define BIT_TO_IRQ 64
+#ifdef CONFIG_PERCPU_IRQ
+
+extern irq_desc_t irq_descX[NR_IRQS];
+irq_desc_t *irq_desc_ptr[NR_CPUS] = { irq_descX };
+
+/*
+ * Each slave AP allocates its own irq table.
+ */
+int __init cpu_irq_init(void)
+{
+	irq_desc_ptr[smp_processor_id()] = (irq_desc_t *)kmalloc(sizeof(irq_descX), GFP_KERNEL);
+	if (irq_desc_ptr[smp_processor_id()] == 0)
+		return(-1);
+	memcpy(irq_desc_ptr[smp_processor_id()], irq_desc_ptr[0], 
+							sizeof(irq_descX));
+	return(0);
+}
+
+/*
+ * This can also allocate the irq tables for the other cpus, specifically
+ * on their nodes.
+ */
+int __init master_irq_init(void)
+{
+	return(0);
+}
+
+/*
+ * The input is an ivt level.
+ */
+irq_desc_t *idesc_from_vector(unsigned int ivnum)
+{
+	return(irq_desc_ptr[smp_processor_id()] + ivnum);
+}
 
-        return bit + BIT_TO_IRQ;
+/*
+ * The input is a "soft" level, that we encoded in.
+ */
+irq_desc_t *idesc_from_irq(unsigned int irq)
+{
+	return(irq_desc_ptr[irq >> 8] + (irq & 0xff));
 }
 
-int
-irq_to_bit_pos(int irq) {
-#define IRQ_TO_BIT 64
+unsigned int ivector_from_irq(unsigned int irq)
+{
+	return(irq & 0xff);
+}
 
-        return irq - IRQ_TO_BIT;
+/*
+ * This should return the Linux irq # for the i/p vector on the
+ * i/p cpu. We currently do not track this.
+ */
+unsigned int irq_from_cpuvector(int cpunum, unsigned int vector)
+{
+	return (vector);
 }
+
+#endif /* CONFIG_PERCPU_IRQ */
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/llsc4.c linux/arch/ia64/sn/sn1/llsc4.c
--- v2.4.3/linux/arch/ia64/sn/sn1/llsc4.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/sn1/llsc4.c	Thu Apr  5 12:51:47 2001
@@ -35,6 +35,15 @@
 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    ""
+
 
 /*
  * Test parameter table for AUTOTEST
@@ -46,22 +55,22 @@
 } autotest_table_t;
 
 autotest_table_t autotest_table[] = {
-	{1000000,	2,	0x2b4		},
-	{1000000,	16,	0,		},
-	{1000000,	16,	4,		},
-	{1000000,	128,	0x44		},
-	{1000000,	128,	0x84		},
-	{1000000,	128,	0x200		},
-	{1000000,	128,	0x204		},
-	{1000000,	128,	0x2b4		},
-	{1000000,	2,	8*MB+0x2b4	},
-	{1000000,	16,	8*MB+0		},
-	{1000000,	16,	8*MB+4		},
-	{1000000,	128,	8*MB+0x44	},
-	{1000000,	128,	8*MB+0x84	},
-	{1000000,	128,	8*MB+0x200	},
-	{1000000,	128,	8*MB+0x204	},
-	{1000000,	128,	8*MB+0x2b4	},
+	{5000000,	2,	0x2b4		},
+	{5000000,	16,	0,		},
+	{5000000,	16,	4,		},
+	{5000000,	128,	0x44		},
+	{5000000,	128,	0x84		},
+	{5000000,	128,	0x200		},
+	{5000000,	128,	0x204		},
+	{5000000,	128,	0x2b4		},
+	{5000000,	2,	8*MB+0x2b4	},
+	{5000000,	16,	8*MB+0		},
+	{5000000,	16,	8*MB+4		},
+	{5000000,	128,	8*MB+0x44	},
+	{5000000,	128,	8*MB+0x84	},
+	{5000000,	128,	8*MB+0x200	},
+	{5000000,	128,	8*MB+0x204	},
+	{5000000,	128,	8*MB+0x2b4	},
 	{0}};
 
 /*
@@ -134,20 +143,21 @@
 static void Speedo(void);
 
 int autotest_enabled=0;
-static int autotest_explicit_flush=0;
 static int llsctest_number=-1;
 static int errstop_enabled=0;
 static int fail_enabled=0;
 static int selective_trigger=0;
+static int dump_block_addrs_opt=0;
+static uint errlock=0;
 
 static int __init autotest_enable(char *str)
 {
         autotest_enabled = 1;
 	return 1;
 }
-static int __init set_llscxflush(char *str)
+static int __init set_llscblkadr(char *str)
 {
-	autotest_explicit_flush = 1;
+	dump_block_addrs_opt = 1;
 	return 1;
 }
 static int __init set_llscselt(char *str)
@@ -179,55 +189,39 @@
 	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 ("     llscxflush  \t%s\tEnable explicit FC in test\n", autotest_explicit_flush ? "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 ("  SEMFIX: %s\n", IA64_SEMFIX);
 	printk ("\n");
 }
 __setup("autotest", autotest_enable);
 __setup("llsctest=", set_llsctest);
 __setup("llscerrstop", set_llscerrstop);
-__setup("llscxflush", set_llscxflush);
 __setup("llscfail", set_llscfail);
 __setup("llscselt", set_llscselt);
+__setup("llscblkadr", set_llscblkadr);
 
 
-extern inline void
-flush_buddy(void *p)
-{
-	long	lp;
-
-	if (autotest_explicit_flush)  {
-		lp = (long)p;
-		lp ^= 0x40;
-		asm volatile ("fc %0" :: "r"(lp) : "memory");
-		ia64_sync_i();
-		ia64_srlz_d();
-	}
-}
-
-static int
+extern inline int
 set_lock(uint *lock, uint id)
 {
 	uint	old;
-	flush_buddy(lock);
 	old = cmpxchg_acq(lock, 0, id);
 	return (old == 0);
 }
 
-static int
+extern inline int
 clr_lock(uint *lock, uint id)
 {
 	uint	old;
-	flush_buddy(lock);
 	old = cmpxchg_rel(lock, id, 0);
 	return (old == id);
 }
 
-static void
+extern inline void
 zero_lock(uint *lock)
 {
-	flush_buddy(lock);
 	*lock = 0;
 }
 
@@ -322,7 +316,6 @@
 					return 1;
 				}
 				if (correct_errors) {
-					flush_buddy(privp);
 					tp->private[linei] = *privp;
 				}
 				errs++;
@@ -343,7 +336,6 @@
 				errs++;
 			}
 			pval++;
-			flush_buddy(privp);
 			*privp = pval;
 			tp->private[linei] = pval;
 			break;
@@ -425,9 +417,7 @@
 				errs++;
 			}
 
-			flush_buddy(sharep);
 			*sharep = lockpat;
-			flush_buddy(sharecopy);
 			*sharecopy = lockpat;
 
 
@@ -471,7 +461,7 @@
 static int
 rerr(capture_t *cap, char *msg, void *lp, void *slp, int thread, int pass, int linei, int exp, int found, int stillbad)
 {
-	int		cpu;
+	int		cpu, i;
 	long 		synerr;
 	int		selt;
 
@@ -487,6 +477,11 @@
 	}
 
 	spin(1);
+	i = 100;
+	while (i && set_lock(&errlock, 1) != 1) {
+		spin(1);
+		i--;
+	}
 	printk ("\nDataError!: %-20s, test %ld, thread %d, line:%d, pass %d (0x%x), time %ld expected:%x, found:%x\n",
 	    msg, k_testnumber, thread, linei, pass, pass, jiffies, exp, found);
 
@@ -512,6 +507,7 @@
 		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();
@@ -639,8 +635,10 @@
 		testnumber = llsctest_number;
 	} else {
 		testnumber++;
-		if (autotest_table[testnumber].passes == 0)
+		if (autotest_table[testnumber].passes == 0) {
 			testnumber = 0;
+			dump_block_addrs_opt = 0;
+		}
 	}
 	k_passes = autotest_table[testnumber].passes;
 	k_linepad = autotest_table[testnumber].linepad;
@@ -704,6 +702,22 @@
 }
 
 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) {
@@ -717,6 +731,7 @@
 build_mem_map(unsigned long start, unsigned long end, void *arg)
 {
 	long	lstart;
+	long	align = 8*MB;
 	/*
 	 * HACK - skip the kernel on the first node 
 	 */
@@ -731,9 +746,11 @@
 	while (lstart > start && (!PageReserved(virt_to_page(lstart-PAGE_SIZE)) && virt_to_page(lstart-PAGE_SIZE)->count.counter == 0))
 		lstart -= PAGE_SIZE;
 
-	printk ("     memmap: start 0x%lx, end 0x%lx\n", lstart, end);
+	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;
@@ -812,6 +829,8 @@
 		if (k_linecount > MAX_LINECOUNT) k_linecount = MAX_LINECOUNT;
 		k_linecount = k_linecount & ~1;
 		setup_block_addresses();
+		if (dump_block_addrs_opt)
+			dump_block_addrs();
 
 		k_currentpass = pass++;
 		k_go = ST_RUN;
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/machvec.c linux/arch/ia64/sn/sn1/machvec.c
--- v2.4.3/linux/arch/ia64/sn/sn1/machvec.c	Fri Aug 11 19:09:06 2000
+++ linux/arch/ia64/sn/sn1/machvec.c	Thu Apr  5 12:51:47 2001
@@ -1,2 +1,18 @@
 #define MACHVEC_PLATFORM_NAME	sn1
 #include <asm/machvec_init.h>
+#include <asm/io.h>
+#include <linux/pci.h>
+void*
+sn1_mk_io_addr_MACRO
+
+dma_addr_t
+sn1_pci_map_single_MACRO
+
+int
+sn1_pci_map_sg_MACRO
+
+unsigned long
+sn1_virt_to_phys_MACRO
+
+void *
+sn1_phys_to_virt_MACRO
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/mm.c linux/arch/ia64/sn/sn1/mm.c
--- v2.4.3/linux/arch/ia64/sn/sn1/mm.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/sn1/mm.c	Thu Apr  5 12:51:47 2001
@@ -1,7 +1,7 @@
 /*
- * Copyright, 2000, Silicon Graphics.
+ * Copyright, 2000-2001, Silicon Graphics.
  * Copyright Srinivasa Thirumalachar (sprasad@engr.sgi.com)
- * Copyright 2000 Kanoj Sarcar (kanoj@sgi.com)
+ * Copyright 2000-2001 Kanoj Sarcar (kanoj@sgi.com)
  */
 
 #include <linux/config.h>
@@ -11,32 +11,23 @@
 #include <asm/efi.h>
 #include <asm/sn/mmzone_sn1.h>
 
-#       define MIN(a,b)         ((a) < (b) ? (a) : (b))
-#       define MAX(a,b)         ((a) > (b) ? (a) : (b))
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#define MAX(a,b)	((a) > (b) ? (a) : (b))
+
+#define DONE_NOTHING	0
+#define DONE_FINDING	1
+#define DONE_BUILDING	2
 
-/*
- * Note that the nodemem[] data structure does not support arbitrary
- * memory types and memory descriptors inside the node. For example, 
- * you can not have multiple efi-mem-type segments in the node and
- * expect the OS not to use specific mem-types. Currently, the 
- * assumption is that "start" is the start of virtual/physical memory 
- * on the node. PROM can reserve some memory _only_ at the beginning. 
- * This is tracked via the "usable" field, that maintains where the 
- * os can start using memory from on a node (ie end of PROM memory).
- * setup_node_bootmem() is passed the above "usable" value, and is
- * expected to make bootmem calls that ensure lower memory is not used.
- * Note that the bootmem for a node is initialized on the entire node, 
- * without regards to any holes - then we reserve the holes in 
- * setup_sn1_bootmem(), to make sure the holes are not handed out by
- * alloc_bootmem, as well as the corresponding mem_map entries are not
- * considered allocatable by the page_alloc routines.
- */
 struct nodemem_s {
-        u64     start ;
-        u64     end   ;
-        u64 	hole[SN1_MAX_BANK_PER_NODE] ;
-	u64	usable;
-} nodemem[MAXNODES] ;
+        u64     start;	/* start of kernel usable memory */
+        u64     end;	/* end of kernel usable memory */
+	u64	mtot;	/* total kernel usable memory */
+	u64	done;	/* state of bootmem initialization */
+	u64	bstart;	/* where should the bootmem area be */
+	u64	bsize;	/* bootmap size */
+        u64 	hole[SN1_MAX_BANK_PER_NODE];
+} nodemem[MAXNODES];
+
 static int nodemem_valid = 0;
 
 static int __init
@@ -46,7 +37,7 @@
         unsigned long count = 0;
 
 	if (start >= end)
-		return 0 ;
+		return 0;
 
 	/*
 	 * Get the memmap ptrs to the start and end of the holes.
@@ -54,31 +45,33 @@
 	 * Can we do virt_to_page(end), if end is on the next node?
 	 */
 
-	page = virt_to_page(start-1);
-	page++ ;
-	pageend = virt_to_page(end) ;
+	page = virt_to_page(start - 1);
+	page++;
+	pageend = virt_to_page(end);
 
 	printk("hpage=0x%lx, hpageend=0x%lx\n", (u64)page, (u64)pageend) ;
 	free_bootmem_node(NODE_DATA(nid), __pa(page), (u64)pageend - (u64)page);
 
-	return count ;
+	return count;
 }
 
-void
+static void __init
 free_unused_memmap_node(int nid)
 {
-	u64	i = 0 ;
-	u64	holestart = -1 ;
+	u64	i = 0;
+	u64	holestart = -1;
+	u64	start = nodemem[nid].start;
 
+	start = ((start >> SN1_NODE_ADDR_SHIFT) << SN1_NODE_ADDR_SHIFT);
 	do {
-		holestart = nodemem[nid].hole[i] ;
-		i++ ;
+		holestart = nodemem[nid].hole[i];
+		i++;
 		while ((i < SN1_MAX_BANK_PER_NODE) && 
-			(nodemem[nid].hole[i] == (u64)-1))
-			i++ ;
+					(nodemem[nid].hole[i] == (u64)-1))
+			i++;
 		if (i < SN1_MAX_BANK_PER_NODE)
 			free_unused_memmap_hole(nid, holestart, 
-				nodemem[nid].start + (i<<SN1_BANK_ADDR_SHIFT));
+				start + (i<<SN1_BANK_ADDR_SHIFT));
 	} while (i<SN1_MAX_BANK_PER_NODE);
 }
 
@@ -98,7 +91,6 @@
 		cnodeid = NASID_TO_CNODEID(nasid);
 		bankid = GetBankId(__pa(vaddr));
 		nodemem[cnodeid].start = MIN(nodemem[cnodeid].start, vaddr);
-		nodemem[cnodeid].usable = MIN(nodemem[cnodeid].usable, vaddr);
 		nvaddr = (unsigned long)__va((unsigned long)(++nasid) << 
 							SN1_NODE_ADDR_SHIFT);
 		nodemem[cnodeid].end = MAX(nodemem[cnodeid].end, MIN(end, nvaddr));
@@ -118,11 +110,14 @@
 pgtbl_size_ok(int nid)
 {
 	unsigned long numpfn, bank0size, nodesize ;
+	unsigned long start = nodemem[nid].start;
+
+	start = ((start >> SN1_NODE_ADDR_SHIFT) << SN1_NODE_ADDR_SHIFT);
 	
-	nodesize 	= nodemem[nid].end - nodemem[nid].start ;
+	nodesize 	= nodemem[nid].end - start ;
 	numpfn 		= nodesize >> PAGE_SHIFT;
 
-	bank0size 	= nodemem[nid].hole[0] - nodemem[nid].start ;
+	bank0size 	= nodemem[nid].hole[0] - start ;
 	/* If nid == master node && no kernel text replication */
 	bank0size      -= 0xA00000 ;	/* Kernel text + stuff */
 	bank0size      -= ((numpfn + 7) >> 3);
@@ -163,198 +158,198 @@
 
 #ifdef CONFIG_DISCONTIGMEM
 
-extern bootmem_data_t 	bdata[] ;
-static int	 	curnodeid ;
+extern bootmem_data_t bdata[];
 
+/*
+ * This assumes there will be a hole in kernel-usable memory between nodes
+ * (due to prom). The memory descriptors invoked via efi_memmap_walk are 
+ * in increasing order. It tries to identify first suitable free area to 
+ * put the bootmem for the node in. When presented with the md holding
+ * the kernel, it only searches at the end of the kernel area.
+ */
 static int __init
-setup_node_bootmem(unsigned long start, unsigned long end, unsigned long nodefree)
+find_node_bootmem(unsigned long start, unsigned long end, void *arg)
 {
+	int nasid = GetNasId(__pa(start));
+	int cnodeid = NASID_TO_CNODEID(nasid);
+	unsigned long nodesize;
 	extern char _end;
-	int i;
-	unsigned long kernelend = PAGE_ALIGN((unsigned long)(&_end));
-	unsigned long pkernelend = __pa(kernelend);
-	unsigned long bootmap_start, bootmap_size;
-	unsigned long pstart, pend;
-
-	pstart = __pa(start) ;
-	pend   = __pa(end) ;
-
-	/* If we are past a node mem boundary, on simulated dig numa
-	 * increment current node id. */
-
-	curnodeid = NASID_TO_CNODEID(GetNasId(pstart)) ;
-
-       /*
-        * Make sure we are being passed page aligned addresses.
-        */
-	if ((start & (PAGE_SIZE - 1)) || (end & (PAGE_SIZE - 1)))
-               panic("setup_node_bootmem:align");
+	unsigned long kaddr = (unsigned long)&_end;
 
-
-	/* For now, just go to the lower CHUNK alignment so that 
-	 * chunktonid of 0-8MB and other lower mem pages get initted. */
-
-	pstart &= CHUNKMASK ;
-	pend = (pend+CHUNKSZ-1) & CHUNKMASK;
-
-	/* If pend == 0, both addrs below 8 MB, special case it
-	 * FIX: CHUNKNUM(pend-1) broken if pend == 0 
-	 * both addrs within 8MB */
-
-	if (pend == 0) {
-		chunktonid[0] = 0;
-		return 0;
-	}
-
-	/* Fill up the chunktonid array first. */
-
-        for (i = PCHUNKNUM(pstart); i <= PCHUNKNUM(pend-1); i++)
-               chunktonid[i] = curnodeid;
-
-	/* This check is bogus for now till MAXCHUNKS is properly
-	 * defined to say if it includes holes or not. */
-
-	if ((CHUNKTONID(PCHUNKNUM(pend)) > MAXCHUNKS) || 
-		(PCHUNKNUM(pstart) >= PCHUNKNUM(pend))) {
-		printk("Ign 0x%lx-0x%lx, ", __pa(start), __pa(end));
+	/*
+	 * Track memory available to kernel.
+	 */
+	nodemem[cnodeid].mtot += ((end - start) >> PAGE_SHIFT);
+	if (nodemem[cnodeid].done != DONE_NOTHING)
 		return(0);
-	}
+	nodesize = nodemem[cnodeid].end - ((nodemem[cnodeid].start >> 
+				SN1_NODE_ADDR_SHIFT) << SN1_NODE_ADDR_SHIFT);
+	nodesize >>= PAGE_SHIFT;
 
-	/* This routine gets called many times in node 0.
-	 * The first one to reach here would be the one after
-	 * kernelend to end of first node. */
-
-	NODE_DATA(curnodeid)->bdata = &(bdata[curnodeid]);
-
-	if (curnodeid == 0) {
-		/* for master node, forcibly assign these values
-		 * This gets called many times on dig but we
-		 * want these exact values 
-		 * Also on softsdv, the memdesc for 0 is missing */
-		NODE_START(curnodeid) = PAGE_OFFSET;
-		NODE_SIZE(curnodeid) = (end - PAGE_OFFSET);
-	} else {
-		/* This gets called only once for non zero nodes
-		 * If it does not, then NODE_STARt should be 
-		 * LOCAL_BASE(nid) */
+	/*
+	 * Adjust limits for the md holding the kernel.
+	 */
+	if ((start < kaddr) && (end > kaddr))
+		start = PAGE_ALIGN(kaddr);
 
-		NODE_START(curnodeid) = start;
-		NODE_SIZE(curnodeid) = (end - start);
+	/*
+	 * We need space for mem_map, bootmem map plus a few more pages
+	 * to satisfy alloc_bootmems out of node 0.
+	 */
+	if ((end - start) > ((nodesize * sizeof(struct page)) + (nodesize/8)
+						+ (10 * PAGE_SIZE))) {
+		nodemem[cnodeid].bstart = start;
+		nodemem[cnodeid].done = DONE_FINDING;
 	}
+	return(0);
+}
 
-	/* if end < kernelend do not do anything below this */
-	if (pend < pkernelend)
-		return 0 ;
+/*
+ * This assumes there will be a hole in kernel-usable memory between nodes
+ * (due to prom). The memory descriptors invoked via efi_memmap_walk are 
+ * in increasing order.
+ */
+static int __init
+build_node_bootmem(unsigned long start, unsigned long end, void *arg)
+{
+	int nasid = GetNasId(__pa(start));
+	int curnodeid = NASID_TO_CNODEID(nasid);
+	int i;
+	unsigned long pstart, pend;
+	extern char _end, _stext;
+	unsigned long kaddr = (unsigned long)&_end;
 
-       /*
-        * Handle the node that contains kernel text/data. It would
-        * be nice if the loader loads the kernel at a "chunk", ie
-        * not in memory that the kernel will ignore (else free_initmem
-        * has to worry about not freeing memory that the kernel ignores).
-        * Note that we assume the space from the node start to
-        * KERNEL_START can not hold all the bootmem data, but from kernel
-        * end to node end can.
-        */
-
-	/* TBD: This may be bogus in light of the above check. */
-
-	if ((pstart < pkernelend) && (pend >= pkernelend)) {
-               bootmap_start = pkernelend;
-	} else {
-               bootmap_start = __pa(start);    /* chunk & page aligned */
+	if (nodemem[curnodeid].done == DONE_FINDING) {
+		/*
+		 * This is where we come to know the node is present.
+		 * Do node wide tasks.
+		 */
+		nodemem[curnodeid].done = DONE_BUILDING;
+		NODE_DATA(curnodeid)->bdata = &(bdata[curnodeid]);
+
+		/*
+	 	 * Update the chunktonid array as a node wide task. There
+		 * are too many smalls mds on first node to do this per md.
+	 	 */
+		pstart = __pa(nodemem[curnodeid].start);
+		pend = __pa(nodemem[curnodeid].end);
+		pstart &= CHUNKMASK;
+		pend = (pend + CHUNKSZ - 1) & CHUNKMASK;
+		/* Possible check point to enforce minimum node size */
+		if (nodemem[curnodeid].bstart == -1) {
+			printk("No valid bootmem area on node %d\n", curnodeid);
+			while(1);
+		}
+		for (i = PCHUNKNUM(pstart); i <= PCHUNKNUM(pend - 1); i++)
+			chunktonid[i] = curnodeid;
+		if ((CHUNKTONID(PCHUNKNUM(pend)) > MAXCHUNKS) || 
+				(PCHUNKNUM(pstart) >= PCHUNKNUM(pend))) {
+			printk("Ign 0x%lx-0x%lx, ", __pa(start), __pa(end));
+			return(0);
+		}
+
+		/*
+		 * NODE_START and NODE_SIZE determine the physical range
+		 * on the node that mem_map array needs to be set up for.
+		 */
+		NODE_START(curnodeid) = ((nodemem[curnodeid].start >> 
+				SN1_NODE_ADDR_SHIFT) << SN1_NODE_ADDR_SHIFT);
+		NODE_SIZE(curnodeid) = (nodemem[curnodeid].end - 
+							NODE_START(curnodeid));
+
+        	nodemem[curnodeid].bsize = 
+			init_bootmem_node(NODE_DATA(curnodeid),
+			(__pa(nodemem[curnodeid].bstart) >> PAGE_SHIFT),
+			(__pa((nodemem[curnodeid].start >> SN1_NODE_ADDR_SHIFT)
+			<< SN1_NODE_ADDR_SHIFT) >> PAGE_SHIFT),
+			(__pa(nodemem[curnodeid].end) >> PAGE_SHIFT));
+
+	} else if (nodemem[curnodeid].done == DONE_NOTHING) {
+		printk("build_node_bootmem: node %d weirdness\n", curnodeid);
+		while(1);		/* Paranoia */
 	}
 
 	/*
-	 * Low memory is reserved for PROM use on SN1. The current node
-	 * memory model is [PROM mem ... kernel ... free], where the 
-	 * first two components are optional on a node.
+	 * Free the entire md.
 	 */
-	if (bootmap_start < __pa(nodefree))
-		bootmap_start = __pa(nodefree);
-
-/* XXX TBD */
-/* For curnodeid of 0, this gets called many times because of many
- * < 8MB segments. start gets bumped each time. We want to fix it
- * to 0 now. 
- */
-	if (curnodeid == 0)
-		start=PAGE_OFFSET;
-/*
- * This makes sure that in free_area_init_core - paging_init
- * idx is the entire node page range and for loop goes thro
- * all pages. test_bit for kernel pages should remain reserved
- * because free available mem takes care of kernel_start and end
- */
-
-        bootmap_size = init_bootmem_node(NODE_DATA(curnodeid),
-			(bootmap_start >> PAGE_SHIFT),
-			(__pa(start) >> PAGE_SHIFT), (__pa(end) >> PAGE_SHIFT));
+	free_bootmem_node(NODE_DATA(curnodeid), __pa(start), (end - start));
 
-	free_bootmem_node(NODE_DATA(curnodeid), bootmap_start + bootmap_size,
-				__pa(end) - (bootmap_start + bootmap_size));
+	/*
+	 * Reclaim back the bootmap and kernel areas.
+	 */
+	if ((start <= nodemem[curnodeid].bstart) && (end >
+						nodemem[curnodeid].bstart))
+		reserve_bootmem_node(NODE_DATA(curnodeid),
+		    __pa(nodemem[curnodeid].bstart), nodemem[curnodeid].bsize);
+	if ((start <= kaddr) && (end > kaddr))
+		reserve_bootmem_node(NODE_DATA(curnodeid),
+		    __pa(&_stext), (&_end - &_stext));
 
 	return(0);
 }
 
-void
+void __init
 setup_sn1_bootmem(int maxnodes)
 {
         int     i;
 
-        for (i=0;i<MAXNODES;i++) {
-                nodemem[i].usable = nodemem[i].start = -1 ;
-                nodemem[i].end   = 0 ;
-		memset(&nodemem[i].hole, -1, sizeof(nodemem[i].hole)) ;
+        for (i = 0; i < MAXNODES; i++) {
+                nodemem[i].start = nodemem[i].bstart = -1;
+                nodemem[i].end = nodemem[i].bsize = nodemem[i].mtot = 0;
+		nodemem[i].done = DONE_NOTHING;
+		memset(&nodemem[i].hole, -1, sizeof(nodemem[i].hole));
         }
-        efi_memmap_walk(build_nodemem_map, 0) ;
+        efi_memmap_walk(build_nodemem_map, 0);
 
-	/*
-	 * Run thru all the nodes, adjusting their starts. This is needed
-	 * because efi_memmap_walk() might not process certain mds that 
-	 * are marked reserved for PROM at node low memory.
-	 */
-	for (i = 0; i < maxnodes; i++)
-		nodemem[i].start = ((nodemem[i].start >> SN1_NODE_ADDR_SHIFT) <<
-					SN1_NODE_ADDR_SHIFT);
-	nodemem_valid = 1 ;
+	nodemem_valid = 1;
 
-	/* After building the nodemem map, check if the page table
+	/* 
+	 * After building the nodemem map, check if the node memmap
 	 * will fit in the first bank of each node. If not change
-	 * the node end addr till it fits. We dont want to do this
-	 * in mm/page_alloc.c
+	 * the node end addr till it fits.
  	 */
 
-        for (i=0;i<maxnodes;i++)
-		check_pgtbl_size(i) ;
-
-        for (i=0;i<maxnodes;i++)
-                setup_node_bootmem(nodemem[i].start, nodemem[i].end, nodemem[i].usable);
+        for (i = 0; i < maxnodes; i++)
+		check_pgtbl_size(i);
 
-	/*
-	 * Mark the holes as reserved, so the corresponding mem_map
-	 * entries will not be marked allocatable in free_all_bootmem*().
-	 */
-	for (i = 0; i < maxnodes; i++) {
-		int j = 0 ;
-		u64 holestart = -1 ;
-
-		do {
-			holestart = nodemem[i].hole[j++];
-			while ((j < SN1_MAX_BANK_PER_NODE) && 
-					(nodemem[i].hole[j] == (u64)-1))
-				j++;
-			if (j < SN1_MAX_BANK_PER_NODE)
-				reserve_bootmem_node(NODE_DATA(i), 
-					__pa(holestart), (nodemem[i].start + 
-					((long)j <<  SN1_BANK_ADDR_SHIFT) - 
-					 holestart));
-		} while (j < SN1_MAX_BANK_PER_NODE);
-	}
+	dump_nodemem_map(maxnodes);
 
-	dump_nodemem_map(maxnodes) ;
+	efi_memmap_walk(find_node_bootmem, 0);
+	efi_memmap_walk(build_node_bootmem, 0);
 }
 #endif
 
+void __init
+discontig_paging_init(void)
+{
+	int i;
+	unsigned long max_dma, zones_size[MAX_NR_ZONES], holes_size[MAX_NR_ZONES];
+	extern void dump_node_data(void);
+
+	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+	for (i = 0; i < numnodes; i++) {
+		unsigned long startpfn = __pa((void *)NODE_START(i)) >> PAGE_SHIFT;
+		unsigned long numpfn = NODE_SIZE(i) >> PAGE_SHIFT;
+		memset(zones_size, 0, sizeof(zones_size));
+		memset(holes_size, 0, sizeof(holes_size));
+		holes_size[ZONE_DMA] = numpfn - nodemem[i].mtot;
+
+		if ((startpfn + numpfn) < max_dma) {
+			zones_size[ZONE_DMA] = numpfn;
+		} else if (startpfn > max_dma) {
+			zones_size[ZONE_NORMAL] = numpfn;
+			panic("discontig_paging_init: %d\n", i);
+		} else {
+			zones_size[ZONE_DMA] = (max_dma - startpfn);
+			zones_size[ZONE_NORMAL] = numpfn - zones_size[ZONE_DMA];
+			panic("discontig_paging_init: %d\n", i);
+		}
+		free_area_init_node(i, NODE_DATA(i), NULL, zones_size, startpfn<<PAGE_SHIFT, holes_size);
+		free_unused_memmap_node(i);
+	}
+	dump_node_data();
+}
+
 /*
  * This used to be invoked from an SN1 specific hack in efi_memmap_walk.
  * It tries to ignore banks which the kernel is ignoring because bank 0 
@@ -386,10 +381,10 @@
 	int	i,j;
 
         printk("NODEMEM_S info ....\n") ;
-        printk("Node         start                end                 usable\n");
+        printk("Node         start                end\n");
         for (i=0;i<maxnodes;i++) {
-                printk("%d      0x%lx   0x%lx   0x%lx\n",
-                       i, nodemem[i].start, nodemem[i].end, nodemem[i].usable);
+                printk("%d      0x%lx   0x%lx\n",
+                       i, nodemem[i].start, nodemem[i].end);
                 printk("Holes -> ") ;
                 for (j=0;j<SN1_MAX_BANK_PER_NODE;j++)
                         printk("0x%lx ", nodemem[i].hole[j]) ;
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/probe.c linux/arch/ia64/sn/sn1/probe.c
--- v2.4.3/linux/arch/ia64/sn/sn1/probe.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ia64/sn/sn1/probe.c	Thu Apr  5 12:51:47 2001
@@ -0,0 +1,62 @@
+/*
+ * Platform dependent support for IO probing.
+ *
+ * Copyright (C) 2000   Silicon Graphics
+ * Copyright (C) 2000   Jack Steiner (steiner@sgi.com)
+ */
+
+#include <asm/sn/sn_sal.h>
+
+/*
+ * ia64_sn_probe_io_slot
+ *	This function will probe a physical address to determine if
+ *	the address can be read. If reading the address causes a BUS
+ *	error, an error is returned. If the probe succeeds, the contents 
+ *	of the memory location is returned.
+ *
+ *   Calling sequence:
+ *		ia64_probe_io_slot(paddr, size, data_ptr)
+ *
+ *   Input:
+ *	paddr		Physical address to probe
+ *	size		Number bytes to read (1,2,4,8)
+ *	data_ptr	Address to store value read by probe
+ *		          (-1 returned if probe fails)
+ *
+ *   Output:
+ *	Status
+ *		 0 - probe successful
+ *		 1 - probe failed (generated MCA)
+ *		 2 - Bad arg
+ *		<0 - PAL error
+ */
+
+
+u64
+ia64_sn_probe_io_slot(long paddr, long size, void *data_ptr)
+{
+	struct ia64_sal_retval isrv;
+
+	SAL_CALL(isrv, SN_SAL_PROBE, paddr, size, 0, 0, 0, 0, 0);
+
+	if (data_ptr) {
+		switch (size) {
+			case 1:
+				*((u8*)data_ptr) = (u8)isrv.v0;
+				break;
+			case 2:
+				*((u16*)data_ptr) = (u16)isrv.v0;
+				break;
+			case 4:
+				*((u32*)data_ptr) = (u32)isrv.v0;
+				break;
+			case 8:
+				*((u64*)data_ptr) = (u64)isrv.v0;
+				break;
+			default:
+				isrv.status = 2;	
+		}
+	}
+
+	return isrv.status;
+}
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/setup.c linux/arch/ia64/sn/sn1/setup.c
--- v2.4.3/linux/arch/ia64/sn/sn1/setup.c	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/sn1/setup.c	Thu Apr  5 12:51:47 2001
@@ -15,12 +15,30 @@
 #include <linux/sched.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/serial.h>
 
 #include <asm/sn/mmzone_sn1.h>
 #include <asm/io.h>
+#include <asm/dma.h>
 #include <asm/machvec.h>
 #include <asm/system.h>
 #include <asm/processor.h>
+#include <asm-ia64/sn/arch.h>
+#include <asm-ia64/sn/addrs.h>
+
+
+/*
+ * This is the address of the RRegs in the HSpace of the global
+ * master.  It is used by a hack in serial.c (serial_[in|out],
+ * printk.c (early_printk), and kdb_io.c to put console output on that
+ * node's Bedrock UART.  It is initialized here to 0, so that
+ * early_printk won't try to access the UART before
+ * master_node_bedrock_address is properly calculated.
+ */
+u64 master_node_bedrock_address = 0UL;
+
+static void sn_fix_ivt_for_partitioned_system(void);
+
 
 /*
  * The format of "screen_info" is strange, and due to early i386-setup
@@ -58,31 +76,169 @@
 #endif
 }
 
+#if defined(BRINGUP) && defined(CONFIG_IA64_EARLY_PRINTK)
+void __init
+early_sn1_setup(void)
+{
+	master_node_bedrock_address = 
+		(u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
+	printk("early_sn1_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address);
+}
+#endif /* BRINGUP && CONFIG_IA64_EARLY_PRINTK */
+
 void __init
 sn1_setup(char **cmdline_p)
 {
-	extern void init_sn1_smp_config(void);
+#if defined(CONFIG_SERIAL) && !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
+	struct serial_struct req;
+#endif
+
+	MAX_DMA_ADDRESS = PAGE_OFFSET + 0x10000000000UL;
+	master_node_bedrock_address = 
+		(u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
+	printk("sn1_setup: setting master_node_bedrock_address to 0x%lx\n",
+		   master_node_bedrock_address);
+
+#if defined(CONFIG_SERIAL) && !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
+	/*
+	 * We do early_serial_setup() to clean out the rs-table[] from the
+	 * statically compiled in version.
+	 */
+	memset(&req, 0, sizeof(struct serial_struct));
+	req.line = 0;
+	req.baud_base = 124800;
+	req.port = 0;
+	req.port_high = 0;
+	req.irq = 0;
+	req.flags = (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST);
+	req.io_type = SERIAL_IO_MEM;
+	req.hub6 = 0;
+	req.iomem_base = (u8 *)(master_node_bedrock_address + 0x80);
+	req.iomem_reg_shift = 3;
+	req.type = 0;
+	req.xmit_fifo_size = 0;
+	req.custom_divisor = 0;
+	req.closing_wait = 0;
+	early_serial_setup(&req);
+#endif /* CONFIG_SERIAL && !CONFIG_SERIAL_SGI_L1_PROTOCOL */
+
 	ROOT_DEV = to_kdev_t(0x0301);		/* default to first IDE drive */
+	sn_fix_ivt_for_partitioned_system();
 
-	init_sn1_smp_config();
-#ifdef ZZZ
-#if !defined (CONFIG_IA64_SOFTSDV_HACKS)
-        /*
-         * Program the timer to deliver timer ticks.  0x40 is the I/O port
-         * address of PIT counter 0, 0x43 is the I/O port address of the
-         * PIT control word.
-         */
-        request_region(0x40,0x20,"timer");
-        outb(0x34, 0x43);            /* Control word */
-        outb(LATCH & 0xff , 0x40);   /* LSB */
-        outb(LATCH >> 8, 0x40);      /* MSB */
-        printk("PIT: LATCH at 0x%x%x for %d HZ\n", LATCH >> 8, LATCH & 0xff, HZ);
-#endif
-#endif
 #ifdef CONFIG_SMP
 	init_smp_config();
 #endif
 	screen_info = sn1_screen_info;
+}
+
+
+/* 
+ * sn_fix_ivt_for_partitioned_system
+ *
+ * This is an ugly hack that is needed for partitioned systems.
+ *
+ * On a partitioned system, most partitions do NOT have a physical address 0.
+ * Unfortunately, the exception handling code in ivt.S has a couple of physical
+ * addresses of kernel structures hardcoded into "movl" instructions.
+ * These addresses are correct on partition 0 only. On all other partitions,
+ * the addresses must be changed to reference the correct address.
+ *
+ * This routine scans the ivt code and replaces the hardcoded addresses with 
+ * the correct address.
+ *
+ * Note that we could have made the ivt.S code dynamically determine the correct
+ * address but this would add code to performance critical pathes. This option
+ * was rejected.
+ */
+
+#define TEMP_mlx	4		/* template type that contains movl instruction */
+#define TEMP_mlX	5		/* template type that contains movl instruction */
+
+typedef union {				/* Instruction encoding for movl instruction */
+	struct {
+		unsigned long	qp:6;
+		unsigned long	r1:7;
+		unsigned long	imm7b:7;
+		unsigned long	vc:1;
+		unsigned long	ic:1;
+		unsigned long	imm5c:5;
+		unsigned long	imm9d:9;
+		unsigned long	i:1;
+		unsigned long	op:4;
+		unsigned long	fill:23;
+	} b;
+	unsigned long	l;
+} movl_instruction_t;
+
+#define MOVL_OPCODE	6
+#define MOVL_ARG(a,b)	(((long)a.i<<63) | ((long)b<<22) | ((long)a.ic<<21) | \
+			((long)a.imm5c<<16) | ((long)a.imm9d<<7) | ((long)a.imm7b))
+
+typedef struct {				/* Instruction bundle */
+	unsigned long template:5;
+	unsigned long ins2:41;
+	unsigned long ins1l:18;
+	unsigned long ins1u:23;
+	unsigned long ins0:41;
+} instruction_bundle_t;
+
+
+static void __init
+sn_fix_ivt_for_partitioned_system(void)
+{
+	extern int		ia64_ivt;
+	instruction_bundle_t	*p, *pend;
+	movl_instruction_t	ins0, ins1, ins2;
+	long			new_ins1, phys_offset;
+	unsigned long		val;
+
+	/*
+	 * Setup to scan the ivt code.
+	 */
+	p = (instruction_bundle_t*)&ia64_ivt;
+	pend = p + 0x8000/sizeof(instruction_bundle_t);
+	phys_offset = __pa(p) & ~0x1ffffffffUL;
+
+	/*
+	 * Hunt for movl instructions that contain the node 0 physical address 
+	 * of "SWAPPER_PGD_ADDR".  These addresses must be relocated to reference the 
+	 * actual node that the kernel is loaded on.
+	 */
+	for (; p < pend; p++) {
+		if (p->template != TEMP_mlx && p->template != TEMP_mlX)
+			continue;
+		ins0.l =  p->ins0;
+		if (ins0.b.op != MOVL_OPCODE)
+			continue;
+		ins1.l =  ((long)p->ins1u<<18) | p->ins1l;
+		ins2.l =  p->ins2;
+		val = MOVL_ARG(ins0.b, ins1.l);
+
+		/*
+		 * Test for correct address. SWAPPER_PGD_ADDR will
+		 * always be a node 0 virtual address. Note that we cant
+		 * use the __pa or __va macros here since they may contain
+		 * debug code that gets fooled here.
+		 */
+		if ((PAGE_OFFSET | val)  != SWAPPER_PGD_ADDR)
+			continue;
+
+		/*
+		 * We found an instruction that needs to be fixed. The following
+		 * inserts the NASID of the ivt into the movl instruction.
+		 */
+		new_ins1 = ins1.l | (phys_offset>>22);
+		p->ins1l = new_ins1 & 0x3ffff;
+		p->ins1u = (new_ins1>>18) & 0x7fffff;
+		ia64_fc(p);
+	}
+
+	/*
+	 * Do necessary serialization.
+	 */
+	ia64_sync_i();
+	ia64_srlz_i();
+
 }
 
 int
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/smp.c linux/arch/ia64/sn/sn1/smp.c
--- v2.4.3/linux/arch/ia64/sn/sn1/smp.c	Thu Jan  4 13:00:15 2001
+++ linux/arch/ia64/sn/sn1/smp.c	Thu Apr  5 12:51:47 2001
@@ -124,10 +124,10 @@
 
 #ifdef CONFIG_SMP
 
+#ifdef PTC_NOTYET
 static void __init
 process_sal_ptc_domain_info(ia64_sal_ptc_domain_info_t *di, int domain)
 {
-#ifdef PTC_NOTYET
 	ia64_sal_ptc_domain_proc_entry_t	*pe;
 	int 					i, sapicid, cpuid;
 
@@ -138,7 +138,6 @@
 		sn_sapicid_info[cpuid].domain = domain;
 		sn_sapicid_info[cpuid].sapicid = sapicid;
 	}
-#endif
 }
 
 
@@ -153,6 +152,7 @@
 		process_sal_ptc_domain_info(di, i);	
 	}
 }
+#endif
 
 
 void __init
@@ -179,7 +179,7 @@
 {
 
 #ifdef PTC_NOTYET
-	sn_sapicid_info[0].sapicid = hard_processor_sapicid();
+	sn_sapicid_info[0].sapicid = hard_smp_processor_id();
 #endif
 }
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/sn1_asm.S linux/arch/ia64/sn/sn1/sn1_asm.S
--- v2.4.3/linux/arch/ia64/sn/sn1/sn1_asm.S	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/sn1/sn1_asm.S	Thu Apr  5 12:51:47 2001
@@ -4,3 +4,146 @@
  * Copyright (C) 2000 Jack Steiner (steiner@sgi.com)
  */
 
+#include <linux/config.h>
+#ifdef CONFIG_IA64_SGI_AUTOTEST
+
+// Testing only.
+// Routine will cause MCAs
+//   zzzmsa(n)
+//      n=0 MCA via duplicate TLB dropin
+//      n=0 MCA via read of garbage address
+//
+
+#define ITIR(key, ps)           ((key<<8) | (ps<<2))
+#define TLB_PAGESIZE            28                      // Use 256MB pages for now.
+
+                        .global zzzmca
+                        .proc   zzzmca
+zzzmca:
+                        alloc   loc4       = ar.pfs,2,8,1,0;;
+                        cmp.ne  p6,p0=r32,r0;;
+                        movl    r2=0x2dead
+                        movl    r3=0x3dead
+                        movl    r15=0x15dead
+                        movl    r16=0x16dead
+                        movl    r31=0x31dead
+                        movl    loc0=0x34beef
+                        movl    loc1=0x35beef
+                        movl    loc2=0x36beef
+                        movl    loc3=0x37beef
+                        movl    out0=0x42beef
+
+                        movl    r20=0x32feed;;
+                        mov     ar32=r20
+                        movl    r20=0x36feed;;
+                        mov     ar36=r20
+                        movl    r20=0x65feed;;
+                        mov     ar65=r20
+                        movl    r20=0x66feed;;
+                        mov     ar66=r20
+
+(p6)                    br.cond.sptk    1f
+
+                        rsm      0x2000;;
+                        srlz.d;
+                        mov      r11      = 1
+                        mov      r3       = ITIR(0,TLB_PAGESIZE);;
+                        mov      cr.itir  = r3
+                        mov      r10      = 0;;
+                        itr.d    dtr[r11] = r10;;
+                        mov      r11      = 2
+
+                        itr.d    dtr[r11] = r10;;
+                        br      9f
+
+1:                      movl    r8=0xfe00000048;;
+                        ld8     r9=[r8];;
+                        mf
+                        mf.a
+                        srlz.d
+
+9:                      mov     ar.pfs=loc4
+                        br.ret.sptk     rp
+
+                        .endp   zzzmca
+
+                        .global zzzspec
+                        .proc   zzzspec
+zzzspec:
+			mov	r8=r32
+			movl	r9=0xe000000000000000
+			movl	r10=0x4000;;
+			ld8.s	r16=[r8];;
+			ld8.s	r17=[r9];;
+			add	r8=r8,r10;;
+			ld8.s	r18=[r8];;
+			add	r8=r8,r10;;
+			ld8.s	r19=[r8];;
+			add	r8=r8,r10;;
+			ld8.s	r20=[r8];;
+			mov	r8=r0
+			tnat.nz	p6,p0=r16
+			tnat.nz	p7,p0=r17
+			tnat.nz	p8,p0=r18
+			tnat.nz	p9,p0=r19
+			tnat.nz	p10,p0=r20;;
+		(p6)	dep	r8=-1,r8,0,1;;
+		(p7)	dep	r8=-1,r8,1,1;;
+		(p8)	dep	r8=-1,r8,2,1;;
+		(p9)	dep	r8=-1,r8,3,1;;
+		(p10)	dep	r8=-1,r8,4,1;;
+                        br.ret.sptk     rp
+                        .endp   zzzspec
+
+                        .global zzzspec2
+                        .proc   zzzspec2
+zzzspec2:
+			cmp.eq	p6,p7=r2,r2
+			movl	r16=0xc0000a0001000020
+			;;
+			mf
+			;;
+			ld8	r9=[r16]
+		(p6)	br.spnt	1f
+			ld8	r10=[r32]
+			;;
+		1:	mf.a
+			mf
+
+			ld8	r9=[r16];;
+			cmp.ne	p6,p7=r9,r16
+		(p6)	br.spnt	1f
+			ld8	r10=[r32]
+			;;
+		1:	mf.a
+			mf
+
+			ld8	r9=[r33];;
+			cmp.ne	p6,p7=r9,r33
+		(p6)	br.spnt	1f
+			ld8	r10=[r32]
+			;;
+		1:	mf.a
+			mf
+
+			tpa	r23=r32
+			add	r20=512,r33
+			add	r21=1024,r33;;
+			ld8	r9=[r20]
+			ld8	r10=[r21];;
+			nop.i	0
+			{ .mib
+			nop.m 0
+			cmp.ne	p6,p7=r10,r33
+		(p6)	br.spnt	1f
+			}
+			ld8	r10=[r32]
+			;;
+		1:	mf.a
+			mf
+			br.ret.sptk     rp
+
+                        .endp   zzzspec
+
+#endif
+
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/sn1_ksyms.c linux/arch/ia64/sn/sn1/sn1_ksyms.c
--- v2.4.3/linux/arch/ia64/sn/sn1/sn1_ksyms.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ia64/sn/sn1/sn1_ksyms.c	Thu Apr  5 12:51:47 2001
@@ -0,0 +1,39 @@
+/* 
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2000 Jesse Barnes (jbarnes@sgi.com)
+ */
+
+
+/*
+ * Architecture-specific kernel symbols
+ */
+
+#include <linux/module.h>
+
+#include <asm/machvec.h>
+
+/*
+ * I/O routines
+ */
+EXPORT_SYMBOL(sn1_outb);
+EXPORT_SYMBOL(sn1_outl);
+EXPORT_SYMBOL(sn1_outw);
+EXPORT_SYMBOL(sn1_inw);
+EXPORT_SYMBOL(sn1_inb);
+EXPORT_SYMBOL(sn1_inl);
+
+/*
+ * other stuff (more to be added later, cleanup then)
+ */
+EXPORT_SYMBOL(sn1_pci_map_sg);
+EXPORT_SYMBOL(sn1_pci_unmap_sg);
+EXPORT_SYMBOL(sn1_pci_alloc_consistent);
+EXPORT_SYMBOL(sn1_pci_free_consistent);
+EXPORT_SYMBOL(sn1_dma_address);
+
+#include <linux/mm.h>
+EXPORT_SYMBOL(alloc_pages);
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/sv.c linux/arch/ia64/sn/sn1/sv.c
--- v2.4.3/linux/arch/ia64/sn/sn1/sv.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ia64/sn/sn1/sv.c	Thu Apr  5 12:51:47 2001
@@ -0,0 +1,551 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Silicon Graphics, Inc.  All rights reserved
+ *
+ * This implemenation of synchronization variables is heavily based on
+ * one done by Steve Lord <lord@sgi.com>
+ *
+ * Paul Cassella <pwc@sgi.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/semaphore.h>
+#include <asm/hardirq.h>
+#include <asm/softirq.h>
+#include <asm/current.h>
+
+#include <asm/sn/sv.h>
+
+/* Define this to have sv_test() run some simple tests.
+   kernel_thread() must behave as expected when this is called.  */
+#undef RUN_SV_TEST
+
+#define DEBUG
+
+/* Set up some macros so sv_wait(), sv_signal(), and sv_broadcast()
+   can sanity check interrupt state on architectures where we know
+   how. */
+#ifdef DEBUG
+ #define SV_DEBUG_INTERRUPT_STATE
+ #ifdef __mips64
+  #define SV_TEST_INTERRUPTS_ENABLED(flags) ((flags & 0x1) != 0)
+  #define SV_TEST_INTERRUPTS_DISABLED(flags) ((flags & 0x1) == 0)
+  #define SV_INTERRUPT_TEST_WORKERS 31
+ #elif defined(__ia64)
+  #define SV_TEST_INTERRUPTS_ENABLED(flags) ((flags & 0x4000) != 0)
+  #define SV_TEST_INTERRUPTS_DISABLED(flags) ((flags & 0x4000) == 0)
+  #define SV_INTERRUPT_TEST_WORKERS 4 /* simulator's slow */
+ #else
+  #undef  SV_DEBUG_INTERRUPT_STATE
+  #define SV_INTERRUPT_TEST_WORKERS 4 /* reasonable? default. */
+ #endif /* __mips64 */
+#endif /* DEBUG */
+
+
+/* XXX FIXME hack hack hack.  Our mips64 tree is from before the
+   switch to WQ_FLAG_EXCLUSIVE, and our ia64 tree is from after it. */
+#ifdef TASK_EXCLUSIVE
+  #undef EXCLUSIVE_IN_QUEUE
+#else
+  #define EXCLUSIVE_IN_QUEUE
+  #define TASK_EXCLUSIVE 0 /* for the set_current_state() in sv_wait() */
+#endif
+
+
+static inline void sv_lock(sv_t *sv) {
+	spin_lock(&sv->sv_lock);
+}
+
+static inline void sv_unlock(sv_t *sv) {
+	spin_unlock(&sv->sv_lock);
+}
+
+/* up() is "extern inline", so we can't pass its address to sv_wait.
+   Use this function's address instead. */
+static void up_wrapper(struct semaphore *sem) {
+	up(sem);
+}
+
+/* spin_unlock() is sometimes a macro. */
+static void spin_unlock_wrapper(spinlock_t *s) {
+	spin_unlock(s);
+}
+
+/* XXX Perhaps sv_wait() should do the switch() each time and avoid
+   the extra indirection and the need for the _wrapper functions? */
+
+static inline void sv_set_mon_type(sv_t *sv, int type) {
+	switch (type) {
+	case SV_MON_SPIN:
+		sv->sv_mon_unlock_func =
+		  (sv_mon_unlock_func_t)spin_unlock_wrapper;
+		break;
+	case SV_MON_SEMA:
+		sv->sv_mon_unlock_func =
+		  (sv_mon_unlock_func_t)up_wrapper;
+		if(sv->sv_flags & SV_INTS) {
+			printk(KERN_ERR "sv_set_mon_type: The monitor lock "
+			       "cannot be shared with interrupts if it is a "
+			       "semaphore!\n");
+			BUG();
+		}
+		if(sv->sv_flags & SV_BHS) {
+			printk(KERN_ERR "sv_set_mon_type: The monitor lock "
+			       "cannot be shared with bottom-halves if it is "
+			       "a semaphore!\n");
+			BUG();
+		}
+		break;
+#if 0 
+	/*
+	 * If needed, and will need to think about interrupts.  This
+	 * may be needed, for example, if someone wants to use sv's
+	 * with something like dev_base; writers need to hold two
+	 * locks. 
+	 */
+	case SV_MON_CUSTOM: 
+		{
+		struct sv_mon_custom *c = lock;
+		sv->sv_mon_unlock_func = c->sv_mon_unlock_func;
+		sv->sv_mon_lock        = c->sv_mon_lock;
+		break;
+		}
+#endif
+		
+	default:
+		printk(KERN_ERR "sv_set_mon_type: unknown type %d (0x%x)! "
+		       "(flags 0x%x)\n", type, type, sv->sv_flags);
+		BUG();
+		break;
+	}
+	sv->sv_flags |= type;
+}
+
+static inline void sv_set_ord(sv_t *sv, int ord) {
+	if (!ord)
+		ord = SV_ORDER_DEFAULT;
+
+	if (ord != SV_ORDER_FIFO && ord != SV_ORDER_LIFO) {
+		printk(KERN_EMERG "sv_set_ord: unknown order %d (0x%x)! ",
+		       ord, ord);
+		BUG();
+	}
+
+	sv->sv_flags |= ord;
+}
+
+void sv_init(sv_t *sv, sv_mon_lock_t *lock, int flags) 
+{
+	int ord = flags & SV_ORDER_MASK;
+	int type = flags & SV_MON_MASK;
+
+	/* Copy all non-order, non-type flags */
+	sv->sv_flags = (flags & ~(SV_ORDER_MASK | SV_MON_MASK));
+
+	if((sv->sv_flags & (SV_INTS | SV_BHS)) == (SV_INTS | SV_BHS)) {
+	  printk(KERN_ERR "sv_init: do not set both SV_INTS and SV_BHS, only SV_INTS.\n");
+	  BUG();
+	}
+
+	sv_set_ord(sv, ord);
+	sv_set_mon_type(sv, type);
+
+	/* If lock is NULL, we'll get it from sv_wait_compat() (and
+           ignore it in sv_signal() and sv_broadcast()). */
+	sv->sv_mon_lock = lock;
+
+	spin_lock_init(&sv->sv_lock);
+	init_waitqueue_head(&sv->sv_waiters);
+}
+
+/*
+ * The associated lock must be locked on entry.  It is unlocked on return.
+ *
+ * Return values:
+ *
+ * n < 0 : interrupted,  -n jiffies remaining on timeout, or -1 if timeout == 0
+ * n = 0 : timeout expired
+ * n > 0 : sv_signal()'d, n jiffies remaining on timeout, or 1 if timeout == 0
+ */
+signed long sv_wait(sv_t *sv, int sv_wait_flags, unsigned long timeout) 
+{
+	DECLARE_WAITQUEUE( wait, current );
+	unsigned long flags;
+	signed long ret = 0;
+
+#ifdef SV_DEBUG_INTERRUPT_STATE
+	{
+	unsigned long flags;
+	__save_flags(flags);
+
+	if(sv->sv_flags & SV_INTS) {
+		if(SV_TEST_INTERRUPTS_ENABLED(flags)) {
+			printk(KERN_ERR "sv_wait: SV_INTS and interrupts "
+			       "enabled (flags: 0x%lx)\n", flags);
+			BUG();
+		}
+	} else {
+		if (SV_TEST_INTERRUPTS_DISABLED(flags)) {
+			printk(KERN_WARNING "sv_wait: !SV_INTS and interrupts "
+			       "disabled! (flags: 0x%lx)\n", flags);
+		}
+	}
+	}
+#endif  /* SV_DEBUG_INTERRUPT_STATE */
+
+	sv_lock(sv);
+
+	sv->sv_mon_unlock_func(sv->sv_mon_lock);
+
+	/* Add ourselves to the wait queue and set the state before
+	 * releasing the sv_lock so as to avoid racing with the
+	 * wake_up() in sv_signal() and sv_broadcast(). 
+	 */
+
+	/* don't need the _irqsave part, but there is no wq_write_lock() */
+	wq_write_lock_irqsave(&sv->sv_waiters.lock, flags);
+
+#ifdef EXCLUSIVE_IN_QUEUE
+	wait.flags |= WQ_FLAG_EXCLUSIVE;
+#endif
+
+	switch(sv->sv_flags & SV_ORDER_MASK) {
+	case SV_ORDER_FIFO:
+		__add_wait_queue_tail(&sv->sv_waiters, &wait);
+		break;
+	case SV_ORDER_FILO:
+		__add_wait_queue(&sv->sv_waiters, &wait);
+		break;
+	default:
+		printk(KERN_ERR "sv_wait: unknown order!  (sv: 0x%p, flags: 0x%x)\n",
+					sv, sv->sv_flags);
+		BUG();
+	}
+	wq_write_unlock_irqrestore(&sv->sv_waiters.lock, flags);
+
+	if(sv_wait_flags & SV_WAIT_SIG)
+		set_current_state(TASK_EXCLUSIVE | TASK_INTERRUPTIBLE  );
+	else
+		set_current_state(TASK_EXCLUSIVE | TASK_UNINTERRUPTIBLE);
+
+	spin_unlock(&sv->sv_lock);
+
+	if(sv->sv_flags & SV_INTS)
+		local_irq_enable();
+	else if(sv->sv_flags & SV_BHS)
+		local_bh_enable();
+
+	if (timeout)
+		ret = schedule_timeout(timeout);
+	else
+		schedule();
+
+	if(current->state != TASK_RUNNING) /* XXX Is this possible? */ {
+		printk(KERN_ERR "sv_wait: state not TASK_RUNNING after "
+		       "schedule().\n");
+		set_current_state(TASK_RUNNING);
+	}
+
+	remove_wait_queue(&sv->sv_waiters, &wait);
+
+	/* Return cases:
+	   - woken by a sv_signal/sv_broadcast
+	   - woken by a signal
+	   - woken by timeout expiring
+	*/
+
+	/* XXX This isn't really accurate; we may have been woken
+           before the signal anyway.... */
+	if(signal_pending(current))
+		return timeout ? -ret : -1;
+	return timeout ? ret : 1;
+}
+
+
+void sv_signal(sv_t *sv) 
+{
+	/* If interrupts can acquire this lock, they can also acquire the
+	   sv_mon_lock, which we must already have to have called this, so
+	   interrupts must be disabled already.  If interrupts cannot
+	   contend for this lock, we don't have to worry about it. */
+
+#ifdef SV_DEBUG_INTERRUPT_STATE
+	if(sv->sv_flags & SV_INTS) {
+		unsigned long flags;
+		__save_flags(flags);
+		if(SV_TEST_INTERRUPTS_ENABLED(flags))
+			printk(KERN_ERR "sv_signal: SV_INTS and "
+			"interrupts enabled! (flags: 0x%lx)\n", flags);
+	}
+#endif /* SV_DEBUG_INTERRUPT_STATE */
+
+	sv_lock(sv);
+	wake_up(&sv->sv_waiters);
+	sv_unlock(sv);
+}
+
+void sv_broadcast(sv_t *sv) 
+{
+#ifdef SV_DEBUG_INTERRUPT_STATE
+	if(sv->sv_flags & SV_INTS) {
+		unsigned long flags;
+		__save_flags(flags);
+		if(SV_TEST_INTERRUPTS_ENABLED(flags))
+			printk(KERN_ERR "sv_broadcast: SV_INTS and "
+			       "interrupts enabled! (flags: 0x%lx)\n", flags);
+	}
+#endif /* SV_DEBUG_INTERRUPT_STATE */
+
+	sv_lock(sv);
+	wake_up_all(&sv->sv_waiters);
+	sv_unlock(sv);
+}
+
+void sv_destroy(sv_t *sv) 
+{
+	if(!spin_trylock(&sv->sv_lock)) {
+		printk(KERN_ERR "sv_destroy: someone else has sv 0x%p locked!\n", sv);
+		BUG();
+	}
+
+	/* XXX Check that the waitqueue is empty? 
+	       Mark the sv destroyed?
+	*/
+}
+
+
+#ifdef RUN_SV_TEST
+
+static DECLARE_MUTEX_LOCKED(talkback);
+static DECLARE_MUTEX_LOCKED(sem);
+sv_t sv;
+sv_t sv_filo;
+
+static int sv_test_1_w(void *arg) 
+{
+	printk("sv_test_1_w: acquiring spinlock 0x%p...\n", arg);
+
+	spin_lock((spinlock_t*)arg);
+	printk("sv_test_1_w: spinlock acquired, waking sv_test_1_s.\n");
+
+	up(&sem);
+
+	printk("sv_test_1_w: sv_spin_wait()'ing.\n");
+
+	sv_spin_wait(&sv, arg);
+
+	printk("sv_test_1_w: talkback.\n");
+	up(&talkback);
+
+	printk("sv_test_1_w: exiting.\n");
+	return 0;
+}
+
+static int sv_test_1_s(void *arg) 
+{
+	printk("sv_test_1_s: waiting for semaphore.\n");
+	down(&sem);
+	printk("sv_test_1_s: semaphore acquired.  Acquiring spinlock.\n");
+	spin_lock((spinlock_t*)arg);
+	printk("sv_test_1_s: spinlock acquired.  sv_signaling.\n");
+	sv_signal(&sv);
+	printk("sv_test_1_s: talkback.\n");
+	up(&talkback);
+	printk("sv_test_1_s: exiting.\n");
+	return 0;
+
+}
+
+static int count;
+static DECLARE_MUTEX(monitor);
+
+static int sv_test_2_w(void *arg) 
+{
+	int dummy = count++;
+	sv_t *sv = (sv_t *)arg;
+
+	down(&monitor);
+	up(&talkback);
+	printk("sv_test_2_w: thread %d started, sv_waiting.\n", dummy);
+	sv_sema_wait(sv, &monitor);
+	printk("sv_test_2_w: thread %d woken, exiting.\n", dummy);
+	up(&sem);
+	return 0;
+}
+
+static int sv_test_2_s_1(void *arg) 
+{
+	int i;
+	sv_t *sv = (sv_t *)arg;
+
+	down(&monitor);
+	for(i = 0; i < 3; i++) {
+		printk("sv_test_2_s_1: waking one thread.\n");
+		sv_signal(sv);
+		down(&sem);
+	}
+
+	printk("sv_test_2_s_1: signaling and broadcasting again.  Nothing should happen.\n");
+	sv_signal(sv);
+	sv_broadcast(sv);
+	sv_signal(sv);
+	sv_broadcast(sv);
+
+	printk("sv_test_2_s_1: talkbacking.\n");
+	up(&talkback);
+	up(&monitor);
+	return 0;
+}
+
+static int sv_test_2_s(void *arg) 
+{
+	int i;
+	sv_t *sv = (sv_t *)arg;
+
+	down(&monitor);
+	for(i = 0; i < 3; i++) {
+		printk("sv_test_2_s: waking one thread (should be %d.)\n", i);
+		sv_signal(sv);
+		down(&sem);
+	}
+
+	printk("sv_test_3_s: waking remaining threads with broadcast.\n");
+	sv_broadcast(sv);
+	for(; i < 10; i++)
+		down(&sem);
+
+	printk("sv_test_3_s: sending talkback.\n");
+	up(&talkback);
+
+	printk("sv_test_3_s: exiting.\n");
+	up(&monitor);
+	return 0;
+}
+
+
+static void big_test(sv_t *sv) 
+{
+	int i;
+
+	count = 0;
+
+	for(i = 0; i < 3; i++) {
+		printk("big_test: spawning thread %d.\n", i);
+		kernel_thread(sv_test_2_w, sv, 0);
+		down(&talkback);
+	}
+
+	printk("big_test: spawning first wake-up thread.\n");
+	kernel_thread(sv_test_2_s_1, sv, 0);
+
+	down(&talkback);
+	printk("big_test: talkback happened.\n");
+
+
+	for(i = 3; i < 13; i++) {
+		printk("big_test: spawning thread %d.\n", i);
+		kernel_thread(sv_test_2_w, sv, 0);
+		down(&talkback);
+	}
+
+	printk("big_test: spawning wake-up thread.\n");
+	kernel_thread(sv_test_2_s, sv, 0);
+
+	down(&talkback);
+}
+
+sv_t int_test_sv;
+spinlock_t int_test_spin = SPIN_LOCK_UNLOCKED;
+int int_test_ready;
+static int irqtestcount;
+
+static int interrupt_test_worker(void *unused) 
+{
+	int id = ++irqtestcount;
+	int it = 0;
+			unsigned long flags, flags2;
+
+	printk("ITW: thread %d started.\n", id);
+
+	while(1) {
+		__save_flags(flags2);
+		if(jiffies % 3) {
+			printk("ITW %2d %5d: irqsaving          (%lx)\n", id, it, flags2);
+			spin_lock_irqsave(&int_test_spin, flags);
+		} else {
+			printk("ITW %2d %5d: spin_lock_irqing   (%lx)\n", id, it, flags2);
+			spin_lock_irq(&int_test_spin);
+		}
+
+		__save_flags(flags2);
+		printk("ITW %2d %5d: locked, sv_waiting (%lx).\n", id, it, flags2);
+		sv_wait(&int_test_sv, 0, 0);
+
+		__save_flags(flags2);
+		printk("ITW %2d %5d: wait finished      (%lx), pausing\n", id, it, flags2);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(jiffies & 0xf);
+		if(current->state != TASK_RUNNING)
+		  printk("ITW:  current->state isn't RUNNING after schedule!\n");
+		it++;
+	}
+}
+
+static void interrupt_test(void) 
+{
+	int i;
+
+	printk("interrupt_test: initing sv.\n");
+	sv_init(&int_test_sv, &int_test_spin, SV_MON_SPIN | SV_INTS);
+
+	for(i = 0; i < SV_INTERRUPT_TEST_WORKERS; i++) {
+		printk("interrupt_test: starting test thread %d.\n", i);
+		kernel_thread(interrupt_test_worker, 0, 0);
+	}
+	printk("interrupt_test: done with init part.\n");
+	int_test_ready = 1;
+}
+
+int sv_test(void) 
+{
+	spinlock_t s = SPIN_LOCK_UNLOCKED;
+
+	sv_init(&sv, &s, SV_MON_SPIN);
+	printk("sv_test: starting sv_test_1_w.\n");
+	kernel_thread(sv_test_1_w, &s, 0);
+	printk("sv_test: starting sv_test_1_s.\n");
+	kernel_thread(sv_test_1_s, &s, 0);
+
+	printk("sv_test: waiting for talkback.\n");
+	down(&talkback); down(&talkback);
+	printk("sv_test: talkback happened, sv_destroying.\n");
+	sv_destroy(&sv);
+
+	count = 0;
+
+	printk("sv_test: beginning big_test on sv.\n");
+
+	sv_init(&sv, &monitor, SV_MON_SEMA);
+	big_test(&sv);
+	sv_destroy(&sv);
+
+	printk("sv_test: beginning big_test on sv_filo.\n");
+	sv_init(&sv_filo, &monitor, SV_MON_SEMA | SV_ORDER_FILO);
+	big_test(&sv_filo);
+	sv_destroy(&sv_filo);
+
+	interrupt_test();
+
+	printk("sv_test: done.\n");
+	return 0;
+}
+
+__initcall(sv_test);
+
+#endif /* RUN_SV_TEST */
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/sn/sn1/synergy.c linux/arch/ia64/sn/sn1/synergy.c
--- v2.4.3/linux/arch/ia64/sn/sn1/synergy.c	Thu Jan  4 15:25:55 2001
+++ linux/arch/ia64/sn/sn1/synergy.c	Thu Apr  5 12:51:47 2001
@@ -8,9 +8,12 @@
 
 
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/proc_fs.h>
 
 #include <asm/ptrace.h>
 #include <linux/devfs_fs_kernel.h>
@@ -26,8 +29,6 @@
 void setclear_mask_a(int irq, int cpuid, int set);
 void * kmalloc(size_t size, int flags);
 
-extern struct sn1_cnode_action_list *sn1_node_actions[];
-
 
 void
 synergy_intr_alloc(int bit, int cpuid) {
@@ -40,9 +41,7 @@
 {
 	int irq;
 	unsigned is_b;
-int nasid;
 
-nasid = cpuid_to_nasid(cpuid);
 	irq = bit_pos_to_irq(bit);
 
 	is_b = (cpuid_to_slice(cpuid)) & 1;
@@ -202,3 +201,229 @@
 		REMOTE_SYNERGY_STORE(nasid, synergy, reg, val);
 	}
 }
+
+#if defined(CONFIG_IA64_SGI_SYNERGY_PERF)
+
+/*
+ * Synergy perf registers. Multiplexed via timer_interrupt
+ */
+static struct proc_dir_entry *synergy_perf_proc = NULL;
+
+/*
+ * read handler for /proc/synergy
+ */
+static int
+synergy_perf_read_proc (char *page, char **start, off_t off,
+                                 int count, int *eof, void *data)
+{
+	cnodeid_t       cnode;
+	nodepda_t       *npdap;
+	synergy_perf_t	*p;
+	int		len = 0;
+
+	len += sprintf(page+len, "# cnode module slot event synergy-A synergy-B\n");
+
+	/* walk the event list for each node */
+	for (cnode=0; cnode < numnodes; cnode++) {
+		npdap = NODEPDA(cnode);
+		if (npdap->synergy_perf_enabled == 0) {
+			len += sprintf(page+len, "# DISABLED\n");
+			break;
+		}
+
+		spin_lock_irq(&npdap->synergy_perf_lock);
+		for (p = npdap->synergy_perf_first; p;) {
+			uint64_t cnt_a=0, cnt_b=0;
+
+			if (p->intervals > 0) {
+				cnt_a = p->counts[0] * npdap->synergy_active_intervals / p->intervals;
+				cnt_b = p->counts[1] * npdap->synergy_active_intervals / p->intervals;
+			}
+
+			len += sprintf(page+len, "%d %d %d %12lx %lu %lu\n",
+				(int)cnode, (int)npdap->module_id, (int)npdap->slotdesc,
+				p->modesel, cnt_a, cnt_b);
+
+			p = p->next;
+			if (p == npdap->synergy_perf_first)
+				break;
+		}
+		spin_unlock_irq(&npdap->synergy_perf_lock);
+	}
+
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+
+	return len;
+}
+
+static int
+synergy_perf_append(uint64_t modesel)
+{
+	int		cnode;
+	nodepda_t       *npdap;
+	synergy_perf_t	*p;
+	int		err = 0;
+
+	/* bit 45 is enable */
+	modesel |= (1UL << 45);
+
+	for (cnode=0; cnode < numnodes; cnode++) {
+		/* for each node, insert a new synergy_perf entry */
+		if ((npdap = NODEPDA(cnode)) == NULL) {
+			printk("synergy_perf_append: cnode=%d NODEPDA(cnode)==NULL, nodepda=%p\n", cnode, nodepda);
+			continue;
+		}
+
+		/* XX use kmem_alloc_node() when it is implemented */
+		p = (synergy_perf_t *)kmalloc(sizeof(synergy_perf_t), GFP_KERNEL);
+		if (p == NULL)
+			err = -ENOMEM;
+		else {
+			memset(p, 0, sizeof(synergy_perf_t));
+			p->modesel = modesel;
+			if (npdap->synergy_perf_data == NULL) {
+				/* circular list */
+				p->next = p;
+				npdap->synergy_perf_data = p;
+				npdap->synergy_perf_first = p;
+			}
+			else {
+				/*
+				 * Jumble up the insertion order so we get better sampling.
+				 * Once the list is complete, "first" stays the same so the
+				 * reporting order is consistent.
+				 */
+				p->next = npdap->synergy_perf_first->next;
+				npdap->synergy_perf_first->next = p;
+				npdap->synergy_perf_first = p->next;
+			}
+		}
+	}
+
+	return err;
+}
+
+static int
+synergy_perf_write_proc (struct file *file, const char *buffer,
+                                unsigned long count, void *data)
+{
+	int		cnode;
+	nodepda_t       *npdap;
+	uint64_t	modesel;
+	char		cmd[64];
+	extern long	atoi(char *);
+    
+	if (count == sizeof(uint64_t)) {
+	    if (copy_from_user(&modesel, buffer, sizeof(uint64_t)))
+		    return -EFAULT;
+	    synergy_perf_append(modesel);
+	}
+	else {
+	    if (copy_from_user(cmd, buffer, count < sizeof(cmd) ? count : sizeof(cmd)))
+		    return -EFAULT;
+	    if (strncmp(cmd, "enable", 6) == 0) {
+		/* enable counting */
+		for (cnode=0; cnode < numnodes; cnode++) {
+			npdap = NODEPDA(cnode);
+			npdap->synergy_perf_enabled = 1;
+		}
+		printk("NOTICE: synergy perf counting enabled\n");
+	    }
+	    else
+	    if (strncmp(cmd, "disable", 7) == 0) {
+		/* disable counting */
+		for (cnode=0; cnode < numnodes; cnode++) {
+			npdap = NODEPDA(cnode);
+			npdap->synergy_perf_enabled = 0;
+		}
+		printk("NOTICE: synergy perf counting disabled\n");
+	    }
+	    else
+	    if (strncmp(cmd, "frequency", 9) == 0) {
+		/* set the update frequency (timer-interrupts per update) */
+		int freq;
+
+		if (count < 12)
+			return -EINVAL;
+		freq = atoi(cmd + 10);
+		if (freq <= 0 || freq > 100)
+			return -EINVAL;
+		for (cnode=0; cnode < numnodes; cnode++) {
+			npdap = NODEPDA(cnode);
+			npdap->synergy_perf_freq = (uint64_t)freq;
+		}
+		printk("NOTICE: synergy perf freq set to %d\n", freq);
+	    }
+	    else
+		return -EINVAL;
+	}
+	
+	return count;
+}
+
+void
+synergy_perf_update(int cpu)
+{
+	nasid_t		nasid;
+	cnodeid_t       cnode = cpuid_to_cnodeid(cpu);
+	struct nodepda_s *npdap;
+	extern struct nodepda_s *nodepda;
+
+	if (nodepda == NULL || (npdap=NODEPDA(cnode)) == NULL || npdap->synergy_perf_enabled == 0 ||
+		npdap->synergy_perf_data == NULL) {
+		/* I/O not initialized, or not enabled, or no events to monitor */
+		return;
+	}
+
+	if (npdap->synergy_inactive_intervals++ % npdap->synergy_perf_freq != 0) {
+		/* don't multiplex on every timer interrupt */
+		return;
+	}
+
+	/*
+	 * Read registers for last interval and increment counters.
+	 * Hold the per-node synergy_perf_lock so concurrent readers get
+	 * consistent values.
+	 */
+	spin_lock_irq(&npdap->synergy_perf_lock);
+
+	nasid = cpuid_to_nasid(cpu);
+	npdap->synergy_active_intervals++;
+	npdap->synergy_perf_data->intervals++;
+
+	npdap->synergy_perf_data->counts[0] += 0xffffffffffUL &
+		REMOTE_SYNERGY_LOAD(nasid, 0, PERF_CNTR0_A);
+
+	npdap->synergy_perf_data->counts[1] += 0xffffffffffUL &
+		REMOTE_SYNERGY_LOAD(nasid, 1, PERF_CNTR0_B);
+
+	/* skip to next in circular list */
+	npdap->synergy_perf_data = npdap->synergy_perf_data->next;
+
+	spin_unlock_irq(&npdap->synergy_perf_lock);
+
+	/* set the counter 0 selection modes for both A and B */
+	REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTL0_A, npdap->synergy_perf_data->modesel);
+	REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTL0_B, npdap->synergy_perf_data->modesel);
+
+	/* and reset the counter registers to zero */
+	REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTR0_A, 0UL);
+	REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTR0_B, 0UL);
+}
+
+void
+synergy_perf_init(void)
+{
+        if ((synergy_perf_proc = create_proc_entry("synergy", 0644, NULL)) != NULL) {
+                synergy_perf_proc->read_proc = synergy_perf_read_proc;
+                synergy_perf_proc->write_proc = synergy_perf_write_proc;
+                printk("markgw: synergy_perf_init()\n");
+        }
+}
+
+#endif /* CONFIG_IA64_SGI_SYNERGY_PERF */
+
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/tools/print_offsets.awk linux/arch/ia64/tools/print_offsets.awk
--- v2.4.3/linux/arch/ia64/tools/print_offsets.awk	Fri Jul 14 16:08:12 2000
+++ linux/arch/ia64/tools/print_offsets.awk	Thu Apr  5 12:51:47 2001
@@ -28,6 +28,10 @@
 	inside_table = 0
 }
 
+/.*[.]rodata/ {
+	inside_table = 0
+}
+
 {
 	if (inside_table) {
 		if ($1 == "//") getline;
@@ -61,7 +65,7 @@
 	inside_table = 1
 }
 
-/tab#:/ {
+/tab\#:/ {
 	inside_table = 1
 }
 
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/tools/print_offsets.c linux/arch/ia64/tools/print_offsets.c
--- v2.4.3/linux/arch/ia64/tools/print_offsets.c	Thu Jan  4 12:50:17 2001
+++ linux/arch/ia64/tools/print_offsets.c	Thu Apr  5 12:51:47 2001
@@ -1,8 +1,8 @@
 /*
  * Utility to generate asm-ia64/offsets.h.
  *
- * Copyright (C) 1999-2000 Hewlett-Packard Co
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2001 Hewlett-Packard Co
+ * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * Note that this file has dual use: when building the kernel
  * natively, the file is translated into a binary and executed.  When
@@ -45,9 +45,8 @@
     { "IA64_PT_REGS_SIZE",		sizeof (struct pt_regs) },
     { "IA64_SWITCH_STACK_SIZE",		sizeof (struct switch_stack) },
     { "IA64_SIGINFO_SIZE",		sizeof (struct siginfo) },
-#ifdef CONFIG_IA64_NEW_UNWIND
+    { "IA64_CPU_SIZE",			sizeof (struct cpuinfo_ia64) },
     { "UNW_FRAME_INFO_SIZE",		sizeof (struct unw_frame_info) },
-#endif
     { "", 0 },			/* spacer */
     { "IA64_TASK_PTRACE_OFFSET",	offsetof (struct task_struct, ptrace) },
     { "IA64_TASK_SIGPENDING_OFFSET",	offsetof (struct task_struct, sigpending) },
@@ -58,6 +57,9 @@
 #ifdef CONFIG_IA32_SUPPORT
     { "IA64_TASK_THREAD_SIGMASK_OFFSET",offsetof (struct task_struct, thread.un.sigmask) },
 #endif
+#ifdef CONFIG_PERFMON
+    { "IA64_TASK_PFM_NOTIFY_OFFSET",	offsetof(struct task_struct, thread.pfm_pend_notify) },
+#endif
     { "IA64_TASK_PID_OFFSET",		offsetof (struct task_struct, pid) },
     { "IA64_TASK_MM_OFFSET",		offsetof (struct task_struct, mm) },
     { "IA64_PT_REGS_CR_IPSR_OFFSET",	offsetof (struct pt_regs, cr_ipsr) },
@@ -157,6 +159,11 @@
     { "IA64_SIGCONTEXT_FR6_OFFSET",	offsetof (struct sigcontext, sc_fr[6]) },
     { "IA64_CLONE_VFORK",		CLONE_VFORK },
     { "IA64_CLONE_VM",			CLONE_VM },
+    { "IA64_CPU_IRQ_COUNT_OFFSET",	offsetof (struct cpuinfo_ia64, irq_stat.f.irq_count) },
+    { "IA64_CPU_BH_COUNT_OFFSET",	offsetof (struct cpuinfo_ia64, irq_stat.f.bh_count) },
+    { "IA64_CPU_SOFTIRQ_ACTIVE_OFFSET",		offsetof (struct cpuinfo_ia64, softirq.active) },
+    { "IA64_CPU_SOFTIRQ_MASK_OFFSET",		offsetof (struct cpuinfo_ia64, softirq.mask) },
+    { "IA64_CPU_PHYS_STACKED_SIZE_P8_OFFSET",	offsetof (struct cpuinfo_ia64, phys_stacked_size_p8) },
 };
 
 static const char *tabs = "\t\t\t\t\t\t\t\t\t\t";
diff -u --recursive --new-file v2.4.3/linux/arch/ia64/vmlinux.lds.S linux/arch/ia64/vmlinux.lds.S
--- v2.4.3/linux/arch/ia64/vmlinux.lds.S	Fri Aug 11 19:09:06 2000
+++ linux/arch/ia64/vmlinux.lds.S	Thu Apr  5 12:51:47 2001
@@ -5,10 +5,18 @@
 
 OUTPUT_FORMAT("elf64-ia64-little")
 OUTPUT_ARCH(ia64)
-ENTRY(_start)
+ENTRY(phys_start)
 SECTIONS
 {
+  /* Sections to be discarded */
+  /DISCARD/ : {
+	*(.text.exit)
+	*(.data.exit)
+	*(.exitcall.exit)
+	}
+
   v = PAGE_OFFSET;	/* this symbol is here to make debugging easier... */
+  phys_start = _start - PAGE_OFFSET;
 
   . = KERNEL_START;
 
@@ -16,11 +24,11 @@
   _stext = .;
   .text : AT(ADDR(.text) - PAGE_OFFSET)
     {
-	*(__ivt_section)
+	*(.text.ivt)
 	/* these are not really text pages, but the zero page needs to be in a fixed location: */
 	*(__special_page_section)
 	__start_gate_section = .;
-	*(__gate_section)
+	*(.text.gate)
 	__stop_gate_section = .;
 	*(.text)
     }
@@ -34,7 +42,7 @@
 
   /* Read-only data */
 
-  __gp = ALIGN(8) + 0x200000;
+  __gp = ALIGN(16) + 0x200000;	/* gp must be 16-byte aligned for exc. table */
 
   /* Global data */
   _data = .;
@@ -60,13 +68,19 @@
 	{ *(__ksymtab) }
   __stop___ksymtab = .;
 
-  /* Unwind table */
+  __start___kallsyms = .;	/* All kernel symbols for debugging */
+  __kallsyms : AT(ADDR(__kallsyms) - PAGE_OFFSET)
+	{ *(__kallsyms) }
+  __stop___kallsyms = .;
+
+  /* Unwind info & table: */
+  .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - PAGE_OFFSET)
+	{ *(.IA_64.unwind_info*) }
+  . = ALIGN(8);
   ia64_unw_start = .;
   .IA_64.unwind : AT(ADDR(.IA_64.unwind) - PAGE_OFFSET)
-	{ *(.IA_64.unwind) }
+	{ *(.IA_64.unwind*) }
   ia64_unw_end = .;
-  .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - PAGE_OFFSET)
-	{ *(.IA_64.unwind_info) }
 
   .rodata : AT(ADDR(.rodata) - PAGE_OFFSET)
 	{ *(.rodata) }
@@ -129,13 +143,6 @@
 	{ *(.bss) *(COMMON) }
   . = ALIGN(64 / 8);
   _end = .;
-
-  /* Sections to be discarded */
-  /DISCARD/ : {
-	*(.text.exit)
-	*(.data.exit)
-	*(.exitcall.exit)
-	}
 
   /* Stabs debugging sections.  */
   .stab 0 : { *(.stab) }
diff -u --recursive --new-file v2.4.3/linux/arch/m68k/config.in linux/arch/m68k/config.in
--- v2.4.3/linux/arch/m68k/config.in	Thu Jan  4 13:00:55 2001
+++ linux/arch/m68k/config.in	Fri Apr  6 10:42:47 2001
@@ -487,8 +487,10 @@
    fi
 fi
 if [ "$CONFIG_APOLLO" = "y" ]; then
-   bool 'Support for DN serial port (dummy)' CONFIG_SERIAL
+   bool 'Support for DN serial port (dummy)' CONFIG_DN_SERIAL
    bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
+
+   define_tristate CONFIG_SERIAL $CONFIG_DN_SERIAL
 fi 
 bool 'Support for user serial device modules' CONFIG_USERIAL
 bool 'Watchdog Timer Support'	CONFIG_WATCHDOG
diff -u --recursive --new-file v2.4.3/linux/arch/m68k/ifpsp060/src/fpsp.S linux/arch/m68k/ifpsp060/src/fpsp.S
--- v2.4.3/linux/arch/m68k/ifpsp060/src/fpsp.S	Tue Mar  6 19:44:35 2001
+++ linux/arch/m68k/ifpsp060/src/fpsp.S	Fri Apr  6 10:42:47 2001
@@ -19594,7 +19594,7 @@
 # in the data register file. If it's actually out in memory, use one of	#
 # the mem_read() routines to fetch it. If the mem_read() access returns	#
 # a failing value, exit through the special facc_in() routine which	#
-# will create an acess error exception frame from the current exception #
+# will create an access error exception frame from the current exception #
 # frame.								#
 # 	Immediate data and regular data accesses are separated because 	#
 # if an immediate data access fails, the resulting fault status		#
@@ -24608,7 +24608,7 @@
 # made out of the current exception stack frame. 			#
 #	So, we first call restore() which makes sure that any updated	#
 # -(an)+ register gets returned to its pre-exception value and then	#
-# we change the stack to an acess error stack frame.			#
+# we change the stack to an access error stack frame.			#
 #									#
 #########################################################################
 
diff -u --recursive --new-file v2.4.3/linux/arch/m68k/ifpsp060/src/pfpsp.S linux/arch/m68k/ifpsp060/src/pfpsp.S
--- v2.4.3/linux/arch/m68k/ifpsp060/src/pfpsp.S	Tue Mar  6 19:44:36 2001
+++ linux/arch/m68k/ifpsp060/src/pfpsp.S	Fri Apr  6 10:42:48 2001
@@ -14568,7 +14568,7 @@
 # made out of the current exception stack frame. 			#
 #	So, we first call restore() which makes sure that any updated	#
 # -(an)+ register gets returned to its pre-exception value and then	#
-# we change the stack to an acess error stack frame.			#
+# we change the stack to an access error stack frame.			#
 #									#
 #########################################################################
 
diff -u --recursive --new-file v2.4.3/linux/arch/m68k/mm/motorola.c linux/arch/m68k/mm/motorola.c
--- v2.4.3/linux/arch/m68k/mm/motorola.c	Mon Aug  7 21:02:27 2000
+++ linux/arch/m68k/mm/motorola.c	Fri Apr  6 10:42:48 2001
@@ -286,6 +286,7 @@
 }
 
 extern char __init_begin, __init_end;
+extern unsigned long totalram_pages;
 
 void free_initmem(void)
 {
@@ -296,6 +297,7 @@
 		virt_to_page(addr)->flags &= ~(1 << PG_reserved);
 		set_page_count(virt_to_page(addr), 1);
 		free_page(addr);
+		totalram_pages++;
 	}
 }
 
diff -u --recursive --new-file v2.4.3/linux/arch/m68k/q40/config.c linux/arch/m68k/q40/config.c
--- v2.4.3/linux/arch/m68k/q40/config.c	Tue Mar  6 19:44:36 2001
+++ linux/arch/m68k/q40/config.c	Fri Apr  6 10:42:48 2001
@@ -238,7 +238,7 @@
     mach_max_dma_address = 32*1024*1024;   /* no DMA at all, but ide-scsi requires it.. */
 
 
-/* userfull for early debugging stages writes kernel messages into SRAM */
+/* useful for early debugging stages - writes kernel messages into SRAM */
 
     if (!strncmp( m68k_debug_device,"mem",3 ))
       {
diff -u --recursive --new-file v2.4.3/linux/arch/s390x/tools/silo/silo.c linux/arch/s390x/tools/silo/silo.c
--- v2.4.3/linux/arch/s390x/tools/silo/silo.c	Tue Feb 13 14:13:44 2001
+++ linux/arch/s390x/tools/silo/silo.c	Fri Apr  6 10:42:55 2001
@@ -376,7 +376,7 @@
     if ( errno == ENOENT ) {
       ITRY (creat ( o-> bootmap, O_RDWR ));
     } else {
-      PRINT_LEVEL(1,"Cannot acces bootmap file '%s': %s\n",o->bootmap,
+      PRINT_LEVEL(1,"Cannot access bootmap file '%s': %s\n",o->bootmap,
 		  strerror(errno));
     }
   }
diff -u --recursive --new-file v2.4.3/linux/arch/sparc/mm/generic.c linux/arch/sparc/mm/generic.c
--- v2.4.3/linux/arch/sparc/mm/generic.c	Wed Aug  9 13:49:55 2000
+++ linux/arch/sparc/mm/generic.c	Thu Apr  5 14:38:29 2001
@@ -21,11 +21,7 @@
 		struct page *ptpage = pte_page(page);
 		if ((!VALID_PAGE(ptpage)) || PageReserved(ptpage))
 			return;
-		/* 
-		 * free_page() used to be able to clear swap cache
-		 * entries.  We may now have to do it manually.  
-		 */
-		free_page_and_swap_cache(ptpage);
+		page_cache_release(page);
 		return;
 	}
 	swap_free(pte_to_swp_entry(page));
diff -u --recursive --new-file v2.4.3/linux/arch/sparc64/mm/generic.c linux/arch/sparc64/mm/generic.c
--- v2.4.3/linux/arch/sparc64/mm/generic.c	Mon Mar 26 15:42:57 2001
+++ linux/arch/sparc64/mm/generic.c	Thu Apr  5 14:38:45 2001
@@ -21,11 +21,7 @@
 		struct page *ptpage = pte_page(page);
 		if ((!VALID_PAGE(ptpage)) || PageReserved(ptpage))
 			return;
-		/* 
-		 * free_page() used to be able to clear swap cache
-		 * entries.  We may now have to do it manually.  
-		 */
-		free_page_and_swap_cache(ptpage);
+		page_cache_release(ptpage);
 		return;
 	}
 	swap_free(pte_to_swp_entry(page));
diff -u --recursive --new-file v2.4.3/linux/drivers/block/paride/Config.in linux/drivers/block/paride/Config.in
--- v2.4.3/linux/drivers/block/paride/Config.in	Mon Jan 24 11:21:47 2000
+++ linux/drivers/block/paride/Config.in	Fri Apr  6 10:42:55 2001
@@ -20,7 +20,8 @@
 dep_tristate '  Parallel port generic ATAPI devices' CONFIG_PARIDE_PG $CONFIG_PARIDE
 comment 'Parallel IDE protocol modules'
 dep_tristate '    ATEN EH-100 protocol' CONFIG_PARIDE_ATEN $CONFIG_PARIDE
-dep_tristate '    MicroSolutions backpack protocol' CONFIG_PARIDE_BPCK $CONFIG_PARIDE
+dep_tristate '    MicroSolutions backpack (Series 5) protocol' CONFIG_PARIDE_BPCK $CONFIG_PARIDE
+dep_tristate '    MicroSolutions backpack (Series 6) protocol' CONFIG_PARIDE_BPCK6 $CONFIG_PARIDE
 dep_tristate '    DataStor Commuter protocol' CONFIG_PARIDE_COMM $CONFIG_PARIDE
 dep_tristate '    DataStor EP-2000 protocol' CONFIG_PARIDE_DSTR $CONFIG_PARIDE
 dep_tristate '    FIT TD-2000 protocol' CONFIG_PARIDE_FIT2 $CONFIG_PARIDE
diff -u --recursive --new-file v2.4.3/linux/drivers/block/paride/Makefile linux/drivers/block/paride/Makefile
--- v2.4.3/linux/drivers/block/paride/Makefile	Fri Dec 29 14:07:21 2000
+++ linux/drivers/block/paride/Makefile	Fri Apr  6 10:42:55 2001
@@ -27,5 +27,6 @@
 obj-$(CONFIG_PARIDE_ON20)	+= on20.o
 obj-$(CONFIG_PARIDE_ON26)	+= on26.o
 obj-$(CONFIG_PARIDE_KTTI)	+= ktti.o
+obj-$(CONFIG_PARIDE_BPCK6)	+= bpck6.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.3/linux/drivers/block/paride/bpck6.c linux/drivers/block/paride/bpck6.c
--- v2.4.3/linux/drivers/block/paride/bpck6.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/block/paride/bpck6.c	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,317 @@
+/*
+	backpack.c (c) 2001 Micro Solutions Inc.
+		Released under the terms of the GNU General Public license
+
+	backpack.c is a low-level protocol driver for the Micro Solutions
+		"BACKPACK" parallel port IDE adapter
+		(Works on Series 6 drives)
+
+	Written by: Ken Hahn     (linux-dev@micro-solutions.com)
+	            Clive Turvey (linux-dev@micro-solutions.com)
+
+*/
+
+/*
+   This is Ken's linux wrapper for the PPC library
+   Version 1.0.0 is the backpack driver for which source is not available
+   Version 2.0.0 is the first to have source released 
+   Version 2.0.1 is the "Cox-ified" source code 
+   Version 2.0.2 - fixed version string usage, and made ppc functions static 
+*/
+
+
+/* PARAMETERS */
+int verbose=0; /* set this to 1 to see debugging messages and whatnot */
+
+#define BACKPACK_VERSION "2.0.2"
+
+#define EXPORT_SYMTAB 
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/types.h>
+#include <asm/io.h>
+
+#if defined(CONFIG_PARPORT_MODULE)||defined(CONFIG_PARPORT)
+#include <linux/parport.h>
+#endif
+
+#include "ppc6lnx.c"
+#include "paride.h"
+
+ 
+
+#define PPCSTRUCT(pi) ((PPC *)(pi->private))
+
+/****************************************************************/
+/*
+ ATAPI CDROM DRIVE REGISTERS
+*/
+#define ATAPI_DATA       0      /* data port                  */
+#define ATAPI_ERROR      1      /* error register (read)      */
+#define ATAPI_FEATURES   1      /* feature register (write)   */
+#define ATAPI_INT_REASON 2      /* interrupt reason register  */
+#define ATAPI_COUNT_LOW  4      /* byte count register (low)  */
+#define ATAPI_COUNT_HIGH 5      /* byte count register (high) */
+#define ATAPI_DRIVE_SEL  6      /* drive select register      */
+#define ATAPI_STATUS     7      /* status port (read)         */
+#define ATAPI_COMMAND    7      /* command port (write)       */
+#define ATAPI_ALT_STATUS 0x0e /* alternate status reg (read) */
+#define ATAPI_DEVICE_CONTROL 0x0e /* device control (write)   */
+/****************************************************************/
+
+static int bpck6_read_regr(PIA *pi, int cont, int reg)
+{
+	unsigned int out;
+
+	/* check for bad settings */
+	if (reg<0 || reg>7 || cont<0 || cont>2)
+	{
+		return(-1);
+	}
+	out=ppc6_rd_port(PPCSTRUCT(pi),cont?reg|8:reg);
+	return(out);
+}
+
+static void bpck6_write_regr(PIA *pi, int cont, int reg, int val)
+{
+	/* check for bad settings */
+	if (reg>=0 && reg<=7 && cont>=0 && cont<=1)
+	{
+		ppc6_wr_port(PPCSTRUCT(pi),cont?reg|8:reg,(u8)val);
+	}
+}
+
+static void bpck6_write_block( PIA *pi, char * buf, int len )
+{
+	ppc6_wr_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1); 
+}
+
+static void bpck6_read_block( PIA *pi, char * buf, int len )
+{
+	ppc6_rd_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1);
+}
+
+static void bpck6_connect ( PIA *pi  )
+{
+	if(verbose)
+	{
+		printk(KERN_DEBUG "connect\n");
+	}
+
+	if(pi->mode >=2)
+  	{
+		PPCSTRUCT(pi)->mode=4+pi->mode-2;	
+	}
+	else if(pi->mode==1)
+	{
+		PPCSTRUCT(pi)->mode=3;	
+	}
+	else
+	{
+		PPCSTRUCT(pi)->mode=1;		
+	}
+
+	ppc6_open(PPCSTRUCT(pi));  
+	ppc6_wr_extout(PPCSTRUCT(pi),0x3);
+}
+
+static void bpck6_disconnect ( PIA *pi )
+{
+	if(verbose)
+	{
+		printk("disconnect\n");
+	}
+	ppc6_wr_extout(PPCSTRUCT(pi),0x0);
+	ppc6_close(PPCSTRUCT(pi));
+}
+
+static int bpck6_test_port ( PIA *pi )   /* check for 8-bit port */
+{
+	if(verbose)
+	{
+		printk(KERN_DEBUG "PARPORT indicates modes=%x for lp=0x%lx\n",
+               		((struct pardevice*)(pi->pardev))->port->modes,
+			((struct pardevice *)(pi->pardev))->port->base); 
+	}
+
+	/*copy over duplicate stuff.. initialize state info*/
+	PPCSTRUCT(pi)->ppc_id=pi->unit;
+	PPCSTRUCT(pi)->lpt_addr=pi->port;
+
+#ifdef CONFIG_PARPORT_PC_MODULE
+#define CONFIG_PARPORT_PC
+#endif
+
+#ifdef CONFIG_PARPORT_PC
+	/* look at the parport device to see if what modes we can use */
+	if(((struct pardevice *)(pi->pardev))->port->modes & 
+		(PARPORT_MODE_EPP)
+          )
+	{
+		return 5; /* Can do EPP*/
+	}
+	else if(((struct pardevice *)(pi->pardev))->port->modes & 
+			(PARPORT_MODE_TRISTATE)
+               )
+	{
+		return 2;
+	}
+	else /*Just flat SPP*/
+	{
+		return 1;
+	}
+#else
+	/* there is no way of knowing what kind of port we have
+	   default to the highest mode possible */
+	return 5;
+#endif
+}
+
+static int bpck6_probe_unit ( PIA *pi )
+{
+	int out;
+
+	if(verbose)
+	{
+		printk(KERN_DEBUG "PROBE UNIT %x on port:%x\n",pi->unit,pi->port);
+	}
+
+	/*SET PPC UNIT NUMBER*/
+	PPCSTRUCT(pi)->ppc_id=pi->unit;
+
+	/*LOWER DOWN TO UNIDIRECTIONAL*/
+	PPCSTRUCT(pi)->mode=1;		
+
+	out=ppc6_open(PPCSTRUCT(pi));
+
+	if(verbose)
+	{
+		printk(KERN_DEBUG "ppc_open returned %2x\n",out);
+	}
+
+  	if(out)
+ 	{
+		ppc6_close(PPCSTRUCT(pi));
+		return(1);	
+		if(verbose)
+		{
+			printk(KERN_DEBUG "leaving probe\n");
+		}
+	}
+  	else
+  	{
+		if(verbose)
+		{
+			printk(KERN_DEBUG "Failed open\n");
+		}
+    		return(0);
+  	}
+}
+
+static void bpck6_log_adapter( PIA *pi, char * scratch, int verbose )
+{
+	char *mode_string[5]=
+		{"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
+
+	printk("%s: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n",pi->device);
+	printk("%s: Copyright 2001 by Micro Solutions, Inc., DeKalb IL.\n",pi->device);
+	printk("%s: BACKPACK %s, Micro Solutions BACKPACK Drive at 0x%x\n",
+		pi->device,BACKPACK_VERSION,pi->port);
+	printk("%s: Unit: %d Mode:%d (%s) Delay %d\n",pi->device,
+		pi->unit,pi->mode,mode_string[pi->mode],pi->delay);
+}
+
+static void bpck6_init_proto(PIA *pi)
+{
+	int i;
+
+	/* allocate a state structure for this item */
+	pi->private=(int)kmalloc(sizeof(PPC),GFP_KERNEL);
+
+	if(pi->private==(int)NULL)
+	{
+		printk(KERN_ERR "%s: ERROR COULDN'T ALLOCATE MEMORY\n",pi->device); 
+		return;
+	}
+	else
+	{	
+		MOD_INC_USE_COUNT; 
+	}
+
+	for(i=0;i<sizeof(PPC);i++)
+	{
+		((unsigned char *)(pi->private))[i]=0;
+	}
+}
+
+static void bpck6_release_proto(PIA *pi)
+{
+	MOD_DEC_USE_COUNT;
+	/* free after use count decremented so that we aren't using it
+		when it is decremented */
+	kfree((void *)(pi->private)); 
+}
+
+struct pi_protocol bpck6 = { "bpck6", /* name for proto*/
+				0, /* index into proto table */
+				5, /* max mode =5 */
+				2, /* 2-5 use epp (need 8 ports) */
+				0, /* no delay (not used anyway) */
+				255, /* we can have units  up to 255 */
+				bpck6_write_regr,
+				bpck6_read_regr,
+				bpck6_write_block,
+				bpck6_read_block,
+				bpck6_connect,
+				bpck6_disconnect,
+				bpck6_test_port,
+ 				bpck6_probe_unit,
+				0,
+				bpck6_log_adapter,
+				bpck6_init_proto,
+				bpck6_release_proto
+                        };
+
+
+EXPORT_SYMBOL(bpck6_write_regr);
+EXPORT_SYMBOL(bpck6_read_regr);
+EXPORT_SYMBOL(bpck6_write_block);
+EXPORT_SYMBOL(bpck6_read_block);
+EXPORT_SYMBOL(bpck6_connect);
+EXPORT_SYMBOL(bpck6_disconnect);
+EXPORT_SYMBOL(bpck6_test_port);
+EXPORT_SYMBOL(bpck6_probe_unit);
+EXPORT_SYMBOL(bpck6_log_adapter);
+EXPORT_SYMBOL(bpck6_init_proto);
+EXPORT_SYMBOL(bpck6_release_proto);
+
+/*---------------------------MODULE STUFF-----------------------*/
+
+#ifdef MODULE
+/*module information*/
+
+static int init_module(void)
+{
+	printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n");
+	printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n");
+
+	if(verbose)
+	{
+		printk(KERN_DEBUG "bpck6: verbose debug enabled.\n");
+	}
+
+	return pi_register(&bpck6) - 1;  
+}
+
+void    cleanup_module(void)
+{
+	pi_unregister(&bpck6);
+}
+
+MODULE_AUTHOR("Micro Solutions Inc.");
+MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
+MODULE_PARM(verbose,"i");
+
+#endif
+
diff -u --recursive --new-file v2.4.3/linux/drivers/block/paride/paride.c linux/drivers/block/paride/paride.c
--- v2.4.3/linux/drivers/block/paride/paride.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/paride.c	Fri Apr  6 10:42:55 2001
@@ -15,9 +15,10 @@
 	1.04    GRG 1998.11.28  added support for FRIQ 
 	1.05    TMW 2000.06.06  use parport_find_number instead of
 				parport_enumerate
+	1.06    TMW 2001.03.26  more sane parport-or-not resource management
 */
 
-#define PI_VERSION      "1.05"
+#define PI_VERSION      "1.06"
 
 #include <linux/module.h>
 #include <linux/config.h>
@@ -160,8 +161,10 @@
 void pi_release( PIA *pi)
 
 {	pi_unregister_parport(pi);
-	if ((!pi->pardev)&&(pi->reserved)) 
+#ifndef CONFIG_PARPORT
+	if (pi->reserved)
 		release_region(pi->port,pi->reserved);
+#endif /* !CONFIG_PARPORT */
 	pi->proto->release_proto(pi);
 }
 
@@ -234,7 +237,7 @@
 	MOD_DEC_USE_COUNT;
 }
 
-static void pi_register_parport( PIA *pi, int verbose)
+static int pi_register_parport( PIA *pi, int verbose)
 
 {
 #ifdef CONFIG_PARPORT
@@ -242,15 +245,16 @@
 	struct parport *port;
 
 	port = parport_find_base (pi->port);
-	if (!port) return;
+	if (!port)
+	  return 0;
 
 	pi->pardev = parport_register_device(port,
 					     pi->device,NULL,
 					     pi_wake_up,NULL,
 					     0,(void *)pi);
 	parport_put_port (port);
-	if (!pi->pardev) return;
-
+	if (!pi->pardev)
+	  return 0;
 
 	init_waitqueue_head(&pi->parq);
 
@@ -258,8 +262,9 @@
 			    port->name);
 	
 	pi->parname = (char *)port->name;
-
 #endif
+
+	return 1;
 }
 
 static int pi_probe_mode( PIA *pi, int max, char * scratch, int verbose)
@@ -271,7 +276,9 @@
 		range = 3;
 		if (pi->mode >= pi->proto->epp_first) range = 8;
 		if ((range == 8) && (pi->port % 8)) return 0;
-		if ((!pi->pardev) && check_region(pi->port,range)) return 0;
+#ifndef CONFIG_PARPORT
+		if (check_region(pi->port,range)) return 0;
+#endif /* !CONFIG_PARPORT */
 		pi->reserved = range;
 		return (!pi_test_proto(pi,scratch,verbose));
 	}
@@ -280,7 +287,9 @@
 		range = 3;
 		if (pi->mode >= pi->proto->epp_first) range = 8;
 		if ((range == 8) && (pi->port % 8)) break;
-		if ((!pi->pardev) && check_region(pi->port,range)) break;
+#ifndef CONFIG_PARPORT
+		if (check_region(pi->port,range)) break;
+#endif /* !CONFIG_PARPORT */
 		pi->reserved = range;
 		if (!pi_test_proto(pi,scratch,verbose)) best = pi->mode;
 	}
@@ -299,9 +308,12 @@
 		e = pi->proto->max_units; 
 	}
 
-	pi_register_parport(pi,verbose);
+	if (!pi_register_parport(pi,verbose))
+	  return 0;
 
-	if ((!pi->pardev) && check_region(pi->port,3)) return 0;
+#ifndef CONFIG_PARPORT
+	if (check_region(pi->port,3)) return 0;
+#endif /* !CONFIG_PARPORT */
 
 	if (pi->proto->test_port) {
 		pi_claim(pi);
@@ -391,8 +403,9 @@
 		return 0;
 	}
 
-	if (!pi->pardev)
-	   request_region(pi->port,pi->reserved,pi->device);
+#ifndef CONFIG_PARPORT
+	request_region(pi->port,pi->reserved,pi->device);
+#endif /* !CONFIG_PARPORT */
 
 	if (pi->parname)
 	   printk("%s: Sharing %s at 0x%x\n",pi->device,
@@ -407,11 +420,16 @@
 
 int	init_module(void)
 
-{	int k;
+{
+	int k;
+	const char *indicate_pp = "";
+#ifdef CONFIG_PARPORT
+	indicate_pp = " (parport)";
+#endif
 
 	for (k=0;k<MAX_PROTOS;k++) protocols[k] = 0;
 
-	printk("paride: version %s installed\n",PI_VERSION);
+	printk("paride: version %s installed%s\n",PI_VERSION,indicate_pp);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.3/linux/drivers/block/paride/ppc6lnx.c linux/drivers/block/paride/ppc6lnx.c
--- v2.4.3/linux/drivers/block/paride/ppc6lnx.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/block/paride/ppc6lnx.c	Fri Apr  6 10:42:55 2001
@@ -0,0 +1,950 @@
+/*
+	ppc6lnx.c (c) 2001 Micro Solutions Inc.
+		Released under the terms of the GNU General Public license
+
+	ppc6lnx.c  is a par of the protocol driver for the Micro Solutions
+		"BACKPACK" parallel port IDE adapter
+		(Works on Series 6 drives)
+
+*/
+
+//***************************************************************************
+
+// PPC 6 Code in C sanitized for LINUX
+// Original x86 ASM by Ron, Converted to C by Clive
+
+//***************************************************************************
+
+
+#define port_stb					1
+#define port_afd					2
+#define cmd_stb						port_afd
+#define port_init					4
+#define data_stb					port_init
+#define port_sel					8
+#define port_int					16
+#define port_dir					0x20
+
+#define ECR_EPP	0x80
+#define ECR_BI	0x20
+
+//***************************************************************************
+
+//  60772 Commands
+
+#define ACCESS_REG				0x00
+#define ACCESS_PORT				0x40
+
+#define ACCESS_READ				0x00
+#define ACCESS_WRITE			0x20
+
+//  60772 Command Prefix
+
+#define CMD_PREFIX_SET		0xe0		// Special command that modifies the next command's operation
+#define CMD_PREFIX_RESET	0xc0		// Resets current cmd modifier reg bits
+ #define PREFIX_IO16			0x01		// perform 16-bit wide I/O
+ #define PREFIX_FASTWR		0x04		// enable PPC mode fast-write
+ #define PREFIX_BLK				0x08		// enable block transfer mode
+
+// 60772 Registers
+
+#define REG_STATUS				0x00		// status register
+ #define STATUS_IRQA			0x01		// Peripheral IRQA line
+ #define STATUS_EEPROM_DO	0x40		// Serial EEPROM data bit
+#define REG_VERSION				0x01		// PPC version register (read)
+#define REG_HWCFG					0x02		// Hardware Config register
+#define REG_RAMSIZE				0x03		// Size of RAM Buffer
+ #define RAMSIZE_128K			0x02
+#define REG_EEPROM				0x06		// EEPROM control register
+ #define EEPROM_SK				0x01		// eeprom SK bit
+ #define EEPROM_DI				0x02		// eeprom DI bit
+ #define EEPROM_CS				0x04		// eeprom CS bit
+ #define EEPROM_EN				0x08		// eeprom output enable
+#define REG_BLKSIZE				0x08		// Block transfer len (24 bit)
+
+//***************************************************************************
+
+typedef struct ppc_storage {
+	u16	lpt_addr;				// LPT base address
+	u8	ppc_id;
+	u8	mode;						// operating mode
+					// 0 = PPC Uni SW
+					// 1 = PPC Uni FW
+					// 2 = PPC Bi SW
+					// 3 = PPC Bi FW
+					// 4 = EPP Byte
+					// 5 = EPP Word
+					// 6 = EPP Dword
+	u8	ppc_flags;
+	u8	org_data;				// original LPT data port contents
+	u8	org_ctrl;				// original LPT control port contents
+	u8	cur_ctrl;				// current control port contents
+} PPC;
+
+//***************************************************************************
+
+// ppc_flags
+
+#define fifo_wait					0x10
+
+//***************************************************************************
+
+// DONT CHANGE THESE LEST YOU BREAK EVERYTHING - BIT FIELD DEPENDENCIES
+
+#define PPCMODE_UNI_SW		0
+#define PPCMODE_UNI_FW		1
+#define PPCMODE_BI_SW			2
+#define PPCMODE_BI_FW			3
+#define PPCMODE_EPP_BYTE	4
+#define PPCMODE_EPP_WORD	5
+#define PPCMODE_EPP_DWORD	6
+
+//***************************************************************************
+
+static int ppc6_select(PPC *ppc);
+static void ppc6_deselect(PPC *ppc);
+static void ppc6_send_cmd(PPC *ppc, u8 cmd);
+static void ppc6_wr_data_byte(PPC *ppc, u8 data);
+static u8 ppc6_rd_data_byte(PPC *ppc);
+static u8 ppc6_rd_port(PPC *ppc, u8 port);
+static void ppc6_wr_port(PPC *ppc, u8 port, u8 data);
+static u8 ppc6_rd_reg(PPC *ppc, u8 reg);
+static void ppc6_wr_reg(PPC *ppc, u8 reg, u8 data);
+static u8 ppc6_version(PPC *ppc);
+static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count);
+static void ppc6_wait_for_fifo(PPC *ppc);
+static void ppc6_wr_data_blk(PPC *ppc, u8 *data, long count);
+static void ppc6_rd_port16_blk(PPC *ppc, u8 port, u8 *data, long length);
+static u16 ppc6_rd_port16(PPC *ppc, u8 port);
+static void ppc6_wr_port16(PPC *ppc, u8 port, u16 data);
+static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length);
+static u8 ppc6_rd_eeprom_reg(PPC *ppc);
+static void ppc6_wr_eeprom_reg(PPC *ppc, u8 data);
+static void ppc6_eeprom_start(PPC *ppc);
+static void ppc6_eeprom_end(PPC *ppc);
+static void ppc6_set_cs(PPC *ppc);
+static void ppc6_reset_cs(PPC *ppc);
+static u8 ppc6_rd_eeprom_bit(PPC *ppc);
+static void ppc6_eeprom_ready_wait(PPC *ppc);
+static void ppc6_wr_eeprom_bit(PPC *ppc, u8 bit);
+static u16 ppc6_eeprom_read(PPC *ppc, u8 addr);
+static u8 ppc6_irq_test(PPC *ppc);
+static u8 ppc6_rd_extout(PPC *ppc);
+static void ppc6_wr_extout(PPC *ppc, u8 regdata);
+static int ppc6_open(PPC *ppc);
+static void ppc6_close(PPC *ppc);
+
+//***************************************************************************
+
+static int ppc6_select(PPC *ppc)
+{
+	u8 i, j, k;
+
+	i = inb(ppc->lpt_addr + 1);
+
+	if (i & 1)
+		outb(i, ppc->lpt_addr + 1);
+
+	ppc->org_data = inb(ppc->lpt_addr);
+
+	ppc->org_ctrl = inb(ppc->lpt_addr + 2) & 0x5F; // readback ctrl
+
+	ppc->cur_ctrl = ppc->org_ctrl;
+
+	ppc->cur_ctrl |= port_sel;
+
+	outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+	if (ppc->org_data == 'b')
+		outb('x', ppc->lpt_addr);
+
+	outb('b', ppc->lpt_addr);
+	outb('p', ppc->lpt_addr);
+	outb(ppc->ppc_id, ppc->lpt_addr);
+	outb(~ppc->ppc_id,ppc->lpt_addr);
+
+	ppc->cur_ctrl &= ~port_sel;
+
+	outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+	ppc->cur_ctrl = (ppc->cur_ctrl & port_int) | port_init;
+
+	outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+	i = ppc->mode & 0x0C;
+
+	if (i == 0)
+		i = (ppc->mode & 2) | 1;
+
+	outb(i, ppc->lpt_addr);
+
+	ppc->cur_ctrl |= port_sel;
+
+	outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+	// DELAY
+
+	ppc->cur_ctrl |= port_afd;
+
+	outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+	j = ((i & 0x08) << 4) | ((i & 0x07) << 3);
+
+	k = inb(ppc->lpt_addr + 1) & 0xB8;
+
+	if (j == k)
+	{
+		ppc->cur_ctrl &= ~port_afd;
+
+		outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+		k = (inb(ppc->lpt_addr + 1) & 0xB8) ^ 0xB8;
+
+		if (j == k)
+		{
+			if (i & 4)	// EPP
+				ppc->cur_ctrl &= ~(port_sel | port_init);
+			else				// PPC/ECP
+				ppc->cur_ctrl &= ~port_sel;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			return(1);
+		}
+	}
+
+	outb(ppc->org_ctrl, ppc->lpt_addr + 2);
+
+	outb(ppc->org_data, ppc->lpt_addr);
+
+	return(0); // FAIL
+}
+
+//***************************************************************************
+
+static void ppc6_deselect(PPC *ppc)
+{
+	if (ppc->mode & 4)	// EPP
+		ppc->cur_ctrl |= port_init;
+	else								// PPC/ECP
+		ppc->cur_ctrl |= port_sel;
+
+	outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+	outb(ppc->org_data, ppc->lpt_addr);
+
+	outb((ppc->org_ctrl | port_sel), ppc->lpt_addr + 2);
+
+	outb(ppc->org_ctrl, ppc->lpt_addr + 2);
+}
+
+//***************************************************************************
+
+static void ppc6_send_cmd(PPC *ppc, u8 cmd)
+{
+	switch(ppc->mode)
+	{
+		case PPCMODE_UNI_SW :
+		case PPCMODE_UNI_FW :
+		case PPCMODE_BI_SW :
+		case PPCMODE_BI_FW :
+		{
+			outb(cmd, ppc->lpt_addr);
+
+			ppc->cur_ctrl ^= cmd_stb;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			break;
+		}
+
+		case PPCMODE_EPP_BYTE :
+		case PPCMODE_EPP_WORD :
+		case PPCMODE_EPP_DWORD :
+		{
+			outb(cmd, ppc->lpt_addr + 3);
+
+			break;
+		}
+	}
+}
+
+//***************************************************************************
+
+static void ppc6_wr_data_byte(PPC *ppc, u8 data)
+{
+	switch(ppc->mode)
+	{
+		case PPCMODE_UNI_SW :
+		case PPCMODE_UNI_FW :
+		case PPCMODE_BI_SW :
+		case PPCMODE_BI_FW :
+		{
+			outb(data, ppc->lpt_addr);
+
+			ppc->cur_ctrl ^= data_stb;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			break;
+		}
+
+		case PPCMODE_EPP_BYTE :
+		case PPCMODE_EPP_WORD :
+		case PPCMODE_EPP_DWORD :
+		{
+			outb(data, ppc->lpt_addr + 4);
+
+			break;
+		}
+	}
+}
+
+//***************************************************************************
+
+static u8 ppc6_rd_data_byte(PPC *ppc)
+{
+	u8 data;
+
+	switch(ppc->mode)
+	{
+		case PPCMODE_UNI_SW :
+		case PPCMODE_UNI_FW :
+		{
+			ppc->cur_ctrl = (ppc->cur_ctrl & ~port_stb) ^ data_stb;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			// DELAY
+
+			data = inb(ppc->lpt_addr + 1);
+
+			data = ((data & 0x80) >> 1) | ((data & 0x38) >> 3);
+
+			ppc->cur_ctrl |= port_stb;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			// DELAY
+
+			data |= inb(ppc->lpt_addr + 1) & 0xB8;
+
+			break;
+		}
+
+		case PPCMODE_BI_SW :
+		case PPCMODE_BI_FW :
+		{
+			ppc->cur_ctrl |= port_dir;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			ppc->cur_ctrl = (ppc->cur_ctrl | port_stb) ^ data_stb;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			data = inb(ppc->lpt_addr);
+
+			ppc->cur_ctrl &= ~port_stb;
+
+			outb(ppc->cur_ctrl,ppc->lpt_addr + 2);
+
+			ppc->cur_ctrl &= ~port_dir;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			break;
+		}
+
+		case PPCMODE_EPP_BYTE :
+		case PPCMODE_EPP_WORD :
+		case PPCMODE_EPP_DWORD :
+		{
+			outb((ppc->cur_ctrl | port_dir),ppc->lpt_addr + 2);
+
+			data = inb(ppc->lpt_addr + 4);
+
+			outb(ppc->cur_ctrl,ppc->lpt_addr + 2);
+
+			break;
+		}
+	}
+
+	return(data);
+}
+
+//***************************************************************************
+
+static u8 ppc6_rd_port(PPC *ppc, u8 port)
+{
+	ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_READ));
+
+	return(ppc6_rd_data_byte(ppc));
+}
+
+//***************************************************************************
+
+static void ppc6_wr_port(PPC *ppc, u8 port, u8 data)
+{
+	ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_WRITE));
+
+	ppc6_wr_data_byte(ppc, data);
+}
+
+//***************************************************************************
+
+static u8 ppc6_rd_reg(PPC *ppc, u8 reg)
+{
+	ppc6_send_cmd(ppc,(u8)(reg | ACCESS_REG | ACCESS_READ));
+
+	return(ppc6_rd_data_byte(ppc));
+}
+
+//***************************************************************************
+
+static void ppc6_wr_reg(PPC *ppc, u8 reg, u8 data)
+{
+	ppc6_send_cmd(ppc,(u8)(reg | ACCESS_REG | ACCESS_WRITE));
+
+	ppc6_wr_data_byte(ppc, data);
+}
+
+//***************************************************************************
+
+static u8 ppc6_version(PPC *ppc)
+{
+	ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_READ));
+
+	return(ppc6_rd_data_byte(ppc) & 0x3F);
+}
+
+//***************************************************************************
+
+static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count)
+{
+	switch(ppc->mode)
+	{
+		case PPCMODE_UNI_SW :
+		case PPCMODE_UNI_FW :
+		{
+			while(count)
+			{
+				u8 d;
+
+				ppc->cur_ctrl = (ppc->cur_ctrl & ~port_stb) ^ data_stb;
+
+				outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+				// DELAY
+
+				d = inb(ppc->lpt_addr + 1);
+
+				d = ((d & 0x80) >> 1) | ((d & 0x38) >> 3);
+
+				ppc->cur_ctrl |= port_stb;
+
+				outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+				// DELAY
+
+				d |= inb(ppc->lpt_addr + 1) & 0xB8;
+
+				*data++ = d;
+				count--;
+			}
+
+			break;
+		}
+
+		case PPCMODE_BI_SW :
+		case PPCMODE_BI_FW :
+		{
+			ppc->cur_ctrl |= port_dir;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			ppc->cur_ctrl |= port_stb;
+
+			while(count)
+			{
+				ppc->cur_ctrl ^= data_stb;
+
+				outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+				*data++ = inb(ppc->lpt_addr);
+				count--;
+			}
+
+			ppc->cur_ctrl &= ~port_stb;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			ppc->cur_ctrl &= ~port_dir;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			break;
+		}
+
+		case PPCMODE_EPP_BYTE :
+		{
+			outb((ppc->cur_ctrl | port_dir), ppc->lpt_addr + 2);
+
+			// DELAY
+
+			while(count)
+			{
+				*data++ = inb(ppc->lpt_addr + 4);
+				count--;
+			}
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			break;
+		}
+
+		case PPCMODE_EPP_WORD :
+		{
+			outb((ppc->cur_ctrl | port_dir), ppc->lpt_addr + 2);
+
+			// DELAY
+
+			while(count > 1)
+			{
+				*((u16 *)data) = inw(ppc->lpt_addr + 4);
+				data  += 2;
+				count -= 2;
+			}
+
+			while(count)
+			{
+				*data++ = inb(ppc->lpt_addr + 4);
+				count--;
+			}
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			break;
+		}
+
+		case PPCMODE_EPP_DWORD :
+		{
+			outb((ppc->cur_ctrl | port_dir),ppc->lpt_addr + 2);
+
+			// DELAY
+
+			while(count > 3)
+			{
+				*((u32 *)data) = inl(ppc->lpt_addr + 4);
+				data  += 4;
+				count -= 4;
+			}
+
+			while(count)
+			{
+				*data++ = inb(ppc->lpt_addr + 4);
+				count--;
+			}
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			break;
+		}
+	}
+
+}
+
+//***************************************************************************
+
+static void ppc6_wait_for_fifo(PPC *ppc)
+{
+	int i;
+
+	if (ppc->ppc_flags & fifo_wait)
+	{
+		for(i=0; i<20; i++)
+			inb(ppc->lpt_addr + 1);
+	}
+}
+
+//***************************************************************************
+
+static void ppc6_wr_data_blk(PPC *ppc, u8 *data, long count)
+{
+	switch(ppc->mode)
+	{
+		case PPCMODE_UNI_SW :
+		case PPCMODE_BI_SW :
+		{
+			while(count--)
+			{
+				outb(*data++, ppc->lpt_addr);
+
+				ppc->cur_ctrl ^= data_stb;
+
+				outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+			}
+
+			break;
+		}
+
+		case PPCMODE_UNI_FW :
+		case PPCMODE_BI_FW :
+		{
+			u8 this, last;
+
+			ppc6_send_cmd(ppc,(CMD_PREFIX_SET | PREFIX_FASTWR));
+
+			ppc->cur_ctrl |= port_stb;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			last = *data;
+
+			outb(last, ppc->lpt_addr);
+
+			while(count)
+			{
+				this = *data++;
+				count--;
+
+				if (this == last)
+				{
+					ppc->cur_ctrl ^= data_stb;
+
+					outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+				}
+				else
+				{
+					outb(this, ppc->lpt_addr);
+
+					last = this;
+				}
+			}
+
+			ppc->cur_ctrl &= ~port_stb;
+
+			outb(ppc->cur_ctrl, ppc->lpt_addr + 2);
+
+			ppc6_send_cmd(ppc,(CMD_PREFIX_RESET | PREFIX_FASTWR));
+
+			break;
+		}
+
+		case PPCMODE_EPP_BYTE :
+		{
+			while(count)
+			{
+				outb(*data++,ppc->lpt_addr + 4);
+				count--;
+			}
+
+			ppc6_wait_for_fifo(ppc);
+
+			break;
+		}
+
+		case PPCMODE_EPP_WORD :
+		{
+			while(count > 1)
+			{
+				outw(*((u16 *)data),ppc->lpt_addr + 4);
+				data  += 2;
+				count -= 2;
+			}
+
+			while(count)
+			{
+				outb(*data++,ppc->lpt_addr + 4);
+				count--;
+			}
+
+			ppc6_wait_for_fifo(ppc);
+
+			break;
+		}
+
+		case PPCMODE_EPP_DWORD :
+		{
+			while(count > 3)
+			{
+				outl(*((u32 *)data),ppc->lpt_addr + 4);
+				data  += 4;
+				count -= 4;
+			}
+
+			while(count)
+			{
+				outb(*data++,ppc->lpt_addr + 4);
+				count--;
+			}
+
+			ppc6_wait_for_fifo(ppc);
+
+			break;
+		}
+	}
+}
+
+//***************************************************************************
+
+static void ppc6_rd_port16_blk(PPC *ppc, u8 port, u8 *data, long length)
+{
+	length = length << 1;
+
+	ppc6_send_cmd(ppc, (REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE));
+	ppc6_wr_data_byte(ppc,(u8)length);
+	ppc6_wr_data_byte(ppc,(u8)(length >> 8));
+	ppc6_wr_data_byte(ppc,0);
+
+	ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK));
+
+	ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_READ));
+
+	ppc6_rd_data_blk(ppc, data, length);
+
+	ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK));
+}
+
+//***************************************************************************
+
+static u16 ppc6_rd_port16(PPC *ppc, u8 port)
+{
+	u16 data;
+
+	ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16));
+
+	ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_READ));
+
+	data = ppc6_rd_data_byte(ppc);
+
+	ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_READ));
+
+	data += (u16)ppc6_rd_data_byte(ppc) << 8;
+
+	ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16));
+
+	return(data);
+}
+
+//***************************************************************************
+
+static void ppc6_wr_port16(PPC *ppc, u8 port, u16 data)
+{
+	ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16));
+
+	ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_WRITE));
+
+	ppc6_wr_data_byte(ppc, (u8)data);
+
+	ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_WRITE));
+
+	ppc6_wr_data_byte(ppc, (u8)(data >> 8));
+
+	ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16));
+}
+
+//***************************************************************************
+
+static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length)
+{
+	length = length << 1;
+
+	ppc6_send_cmd(ppc, (REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE));
+	ppc6_wr_data_byte(ppc,(u8)length);
+	ppc6_wr_data_byte(ppc,(u8)(length >> 8));
+	ppc6_wr_data_byte(ppc,0);
+
+	ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK));
+
+	ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_WRITE));
+
+	ppc6_wr_data_blk(ppc, data, length);
+
+	ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK));
+}
+
+//***************************************************************************
+
+static u8 ppc6_rd_eeprom_reg(PPC *ppc)
+{
+	ppc6_send_cmd(ppc, (REG_EEPROM | ACCESS_REG | ACCESS_READ));
+
+	return(ppc6_rd_data_byte(ppc));
+}
+
+//***************************************************************************
+
+static void ppc6_wr_eeprom_reg(PPC *ppc, u8 data)
+{
+	ppc6_send_cmd(ppc, (REG_EEPROM | ACCESS_REG | ACCESS_WRITE));
+
+	ppc6_wr_data_byte(ppc, data);
+}
+
+//***************************************************************************
+
+static void ppc6_eeprom_start(PPC *ppc)
+{
+	ppc6_wr_eeprom_reg(ppc, EEPROM_EN);
+}
+
+//***************************************************************************
+
+static void ppc6_eeprom_end(PPC *ppc)
+{
+	ppc6_wr_eeprom_reg(ppc, 0);
+}
+
+//***************************************************************************
+
+static void ppc6_set_cs(PPC *ppc)
+{
+	ppc6_wr_eeprom_reg(ppc, (u8)(ppc6_rd_eeprom_reg(ppc) | EEPROM_CS));
+}
+
+//***************************************************************************
+
+static void ppc6_reset_cs(PPC *ppc)
+{
+	ppc6_wr_eeprom_reg(ppc, (u8)(ppc6_rd_eeprom_reg(ppc) & ~EEPROM_CS));
+}
+
+//***************************************************************************
+
+static u8 ppc6_rd_eeprom_bit(PPC *ppc)
+{
+	ppc6_send_cmd(ppc, (REG_STATUS | ACCESS_REG | ACCESS_READ));
+
+	if (ppc6_rd_data_byte(ppc) & STATUS_EEPROM_DO)
+		return(1);
+	else
+		return(0);
+}
+
+//***************************************************************************
+
+static void ppc6_eeprom_ready_wait(PPC *ppc)
+{
+	ppc6_set_cs(ppc);
+
+	while(ppc6_rd_eeprom_bit(ppc));
+
+	ppc6_reset_cs(ppc);
+}
+
+//***************************************************************************
+
+static void ppc6_wr_eeprom_bit(PPC *ppc, u8 bit)
+{
+	u8 eereg;
+
+	eereg = ppc6_rd_eeprom_reg(ppc);
+
+	eereg &= ~(EEPROM_SK | EEPROM_DI);
+
+	if (bit & 1)
+		eereg |= EEPROM_DI;
+
+	ppc6_wr_eeprom_reg(ppc, eereg);
+
+	eereg |= EEPROM_SK;
+
+	ppc6_wr_eeprom_reg(ppc, eereg);
+
+	eereg &= ~EEPROM_SK;
+
+	ppc6_wr_eeprom_reg(ppc, eereg);
+}
+
+//***************************************************************************
+
+static u16 ppc6_eeprom_read(PPC *ppc, u8 addr)
+{
+	int i;
+	u16 data;
+
+	ppc6_set_cs(ppc);
+
+	ppc6_wr_eeprom_bit(ppc, 1); // Start bit
+
+	ppc6_wr_eeprom_bit(ppc, 1); // opcode 10 (read)
+	ppc6_wr_eeprom_bit(ppc, 0);
+
+	for(i=0; i<6; i++)
+		ppc6_wr_eeprom_bit(ppc, (u8)((addr >> (5 - i)) & 1));
+
+	data = 0;
+
+	for(i=0; i<16; i++)
+	{
+		ppc6_wr_eeprom_bit(ppc,0);
+
+		data = (data << 1) | ppc6_rd_eeprom_bit(ppc);
+	}
+
+	ppc6_reset_cs(ppc);
+
+	return(data);
+}
+
+//***************************************************************************
+
+static u8 ppc6_irq_test(PPC *ppc)
+{
+	ppc6_send_cmd(ppc,(REG_STATUS | ACCESS_REG | ACCESS_READ));
+
+	return(ppc6_rd_data_byte(ppc) & STATUS_IRQA);
+}
+
+//***************************************************************************
+
+static u8 ppc6_rd_extout(PPC *ppc)
+{
+	ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_READ));
+
+	return((ppc6_rd_data_byte(ppc) & 0xC0) >> 6);
+}
+
+//***************************************************************************
+
+static void ppc6_wr_extout(PPC *ppc, u8 regdata)
+{
+	ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_WRITE));
+
+	ppc6_wr_data_byte(ppc, (u8)((regdata & 0x03) << 6));
+}
+
+//***************************************************************************
+
+static int ppc6_open(PPC *ppc)
+{
+	int ret;
+
+	ret = ppc6_select(ppc);
+
+	if (ret == 0)
+		return(ret);
+
+	ppc->ppc_flags &= ~fifo_wait;
+
+	ppc6_send_cmd(ppc, (ACCESS_REG | ACCESS_WRITE | REG_RAMSIZE));
+	ppc6_wr_data_byte(ppc, RAMSIZE_128K);
+
+	ppc6_send_cmd(ppc, (ACCESS_REG | ACCESS_READ | REG_VERSION));
+
+	if ((ppc6_rd_data_byte(ppc) & 0x3F) == 0x0C)
+		ppc->ppc_flags |= fifo_wait;
+
+	return(ret);
+}
+
+//***************************************************************************
+
+static void ppc6_close(PPC *ppc)
+{
+	ppc6_deselect(ppc);
+}
+
+//***************************************************************************
+
diff -u --recursive --new-file v2.4.3/linux/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c
--- v2.4.3/linux/drivers/cdrom/sbpcd.c	Fri Feb 16 16:02:35 2001
+++ linux/drivers/cdrom/sbpcd.c	Fri Apr  6 10:42:55 2001
@@ -350,7 +350,7 @@
 
 #ifndef SBPCD_ISSUE
 #define SBPCD_ISSUE 1
-#endif SBPCD_ISSUE
+#endif /* SBPCD_ISSUE */
 
 #include <linux/module.h>
 
@@ -420,7 +420,7 @@
 #else
 #define SBPCD_CLI
 #define SBPCD_STI
-#endif SBPCD_DIS_IRQ
+#endif /* SBPCD_DIS_IRQ */
 /*==========================================================================*/
 /*
  * auto-probing address list
@@ -478,9 +478,9 @@
 	0x370, 0, /* Lasermate, CI-101P */
 	0x290, 1, /* Soundblaster 16 */
 	0x310, 0, /* Lasermate, CI-101P, WDH-7001C */
-#endif MODULE
+#endif /* MODULE */
 #endif
-#endif DISTRIBUTION
+#endif /* DISTRIBUTION */
 };
 #else
 static int sbpcd[] = {CDROM_PORT, SBPRO}; /* probe with user's setup only */
@@ -570,7 +570,7 @@
 			  (1<<DBG_TOC) |
 			  (1<<DBG_MUL) |
 			  (1<<DBG_UPC));
-#endif DISTRIBUTION
+#endif /* DISTRIBUTION */
 
 static int sbpcd_ioaddr = CDROM_PORT;	/* default I/O base address */
 static int sbpro_type = SBPRO;
@@ -622,7 +622,7 @@
 
 #if FUTURE
 static DECLARE_WAIT_QUEUE_HEAD(sbp_waitq);
-#endif FUTURE
+#endif /* FUTURE */
 
 static int teac=SBP_TEAC_SPEED;
 static int buffers=SBP_BUFFER_FRAMES;
@@ -647,7 +647,7 @@
 #if OLD_BUSY
 static volatile u_char busy_data;
 static volatile u_char busy_audio; /* true semaphores would be safer */
-#endif OLD_BUSY
+#endif /* OLD_BUSY */ 
 static DECLARE_MUTEX(ioctl_read_sem);
 static u_long timeout;
 static volatile u_char timed_out_delay;
@@ -664,7 +664,7 @@
 static u_int maxtim_data= 9000;
 #else
 static u_int maxtim_data= 3000;
-#endif LONG_TIMING
+#endif /* LONG_TIMING */ 
 #if DISTRIBUTION
 static int n_retries=6;
 #else
@@ -729,7 +729,7 @@
 	u_char vol_ctrl2;
 	char vol_chan3;
 	u_char vol_ctrl3;
-#endif 000
+#endif /*000 */
 	u_char volume_control; /* TEAC on/off bits */
 	
 	u_char SubQ_ctl_adr;
@@ -758,7 +758,7 @@
 	u_int TocEnt_address;
 #if SAFE_MIXED
 	char has_data;
-#endif SAFE_MIXED
+#endif /* SAFE_MIXED */ 
 	u_char ored_ctl_adr; /* to detect if CDROM contains data tracks */
 	
 	struct {
@@ -808,7 +808,7 @@
 #define MSG_LEVEL KERN_NOTICE
 #else
 #define MSG_LEVEL KERN_INFO
-#endif DISTRIBUTION
+#endif /* DISTRIBUTION */
 
 	char buf[256];
 	va_list args;
@@ -824,7 +824,7 @@
 	printk(buf);
 #if KLOGD_PAUSE
 	sbp_sleep(KLOGD_PAUSE); /* else messages get lost */
-#endif KLOGD_PAUSE
+#endif /* KLOGD_PAUSE */ 
 	return;
 }
 /*==========================================================================*/
@@ -1148,7 +1148,7 @@
 	}
 	j=i-response_count;
 	if (j>0) msg(DBG_INF,"ResponseInfo: got %d trailing bytes.\n",j);
-#endif 000
+#endif /* 000 */
 	for (j=0;j<i;j++)
 		sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
 	msgbuf[j*3]=0;
@@ -1400,7 +1400,7 @@
 		if (drvcmd[0]==CMDT_READ_VER) sbp_sleep(HZ); /* fixme */
 #if 01
 		OUT(CDo_sel_i_d,1);
-#endif 01
+#endif /* 01 */
 		if (teac==2)
                   {
                     if ((i=CDi_stat_loop_T()) == -1) break;
@@ -1409,7 +1409,7 @@
                   {
 #if 0
                     OUT(CDo_sel_i_d,1);
-#endif 0
+#endif /* 0 */ 
                     i=inb(CDi_status);
                   }
 		if (!(i&s_not_data_ready)) /* f.e. CMDT_DISKINFO */
@@ -1433,7 +1433,7 @@
                                                         l=1;
                                                         msg(DBG_TEA,"cmd_out_T: do_16bit: false first byte!\n");
                                                 }
-#endif TEST_FALSE_FF
+#endif /* TEST_FALSE_FF */ 
                                         }
                                         else infobuf[l++]=inb(CDi_data);
                                         i=inb(CDi_status);
@@ -2028,7 +2028,7 @@
 		msg(DBG_TEA, "================CMDT_RESET given=================.\n");
 		sbp_sleep(3*HZ);
 	}
-#endif 1
+#endif /* 1 */ 
 	flush_status();
 	i=GetStatus();
 	if (i<0) return i;
@@ -2349,7 +2349,7 @@
 		i=ResponseStatus();
 #if 0
                 sbp_sleep(HZ);
-#endif 0
+#endif /* 0 */ 
 		i=ResponseStatus();
 	}
 	if (i<0)
@@ -2694,7 +2694,7 @@
 	D_S[d].vol_ctrl2=0xFF;
 	D_S[d].vol_chan3=3;
 	D_S[d].vol_ctrl3=0xFF;
-#endif 000
+#endif /*  000 */
 	D_S[d].diskstate_flags |= volume_bit;
 	return (0);
 }
@@ -2994,20 +2994,20 @@
 	int i;
 #if TEST_UPC
 	int block, checksum;
-#endif TEST_UPC
+#endif /* TEST_UPC */ 
 	
 	if (fam2_drive) return (0); /* not implemented yet */
 	if (famT_drive)	return (0); /* not implemented yet */
 	if (famV_drive)	return (0); /* not implemented yet */
 #if 1
 	if (fam0_drive) return (0); /* but it should work */
-#endif 1
+#endif
 	
 	D_S[d].diskstate_flags &= ~upc_bit;
 #if TEST_UPC
 	for (block=CD_MSF_OFFSET+1;block<CD_MSF_OFFSET+200;block++)
 	{
-#endif TEST_UPC
+#endif /* TEST_UPC */ 
 		clr_cmdbuf();
 		if (fam1_drive)
 		{
@@ -3016,7 +3016,7 @@
 			drvcmd[1]=(block>>16)&0xFF;
 			drvcmd[2]=(block>>8)&0xFF;
 			drvcmd[3]=block&0xFF;
-#endif TEST_UPC
+#endif /* TEST_UPC */ 
 			response_count=8;
 			flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
 		}
@@ -3027,7 +3027,7 @@
 			drvcmd[2]=(block>>16)&0xFF;
 			drvcmd[3]=(block>>8)&0xFF;
 			drvcmd[4]=block&0xFF;
-#endif TEST_UPC
+#endif /* TEST_UPC */ 
 			response_count=0;
 			flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
 		}
@@ -3058,12 +3058,12 @@
 		}
 #if TEST_UPC
 		checksum=0;
-#endif TEST_UPC
+#endif /* TEST_UPC */ 
 		for (i=0;i<(fam1_drive?8:16);i++)
 		{
 #if TEST_UPC
 			checksum |= infobuf[i];
-#endif TEST_UPC
+#endif /* TEST_UPC */ 
 			sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
 		}
 		msgbuf[i*3]=0;
@@ -3071,7 +3071,7 @@
 #if TEST_UPC
 		if ((checksum&0x7F)!=0) break;
 	}
-#endif TEST_UPC
+#endif /* TEST_UPC */ 
 	D_S[d].UPC_ctl_adr=0;
 	if (fam1_drive) i=0;
 	else i=2;
@@ -3256,7 +3256,7 @@
 	i=cmd_out(); /* which buffer to use? */
 	return (i);
 }
-#endif FUTURE
+#endif /* FUTURE */ 
 /*==========================================================================*/
 static void __init check_datarate(void)
 {
@@ -3283,7 +3283,7 @@
 		datarate++;
 #if 1
 		if (datarate>0x6FFFFFFF) break;
-#endif 00000
+#endif 
 	}
 	while (!timed_out_delay);
 	del_timer(&delay_timer);
@@ -3299,7 +3299,7 @@
 	maxtim_data=datarate/100;
 #else
 	maxtim_data=datarate/300;
-#endif LONG_TIMING
+#endif /* LONG_TIMING */ 
 #if 0
 	msg(DBG_TIM,"maxtim_8 %d, maxtim_data %d.\n", maxtim_8, maxtim_data);
 #endif
@@ -3453,7 +3453,7 @@
 		OUT(CDo_reset,0);
 		sbp_sleep(6*HZ);
 		OUT(CDo_enable,D_S[d].drv_sel);
-#endif 0
+#endif
 		drvcmd[0]=CMD2_READ_VER;
 		response_count=12;
 		flags_cmd_out=f_putcmd;
@@ -3743,7 +3743,7 @@
 	OUT(port+3,save_port3);
 	return (0); /* in any case - no real "function" at time */
 }
-#endif PATH_CHECK
+#endif /* PATH_CHECK */ 
 /*==========================================================================*/
 /*==========================================================================*/
 /*
@@ -3850,7 +3850,7 @@
 	if (func2==tell_UPC) return (-1);
 #else
 	return (0);
-#endif 000
+#endif
 }
 /*==========================================================================*/
 static int check_allowed2(u_char func1, u_char func2)
@@ -3868,7 +3868,7 @@
 	}
 #else
 	return (0);
-#endif 000
+#endif
 }
 /*==========================================================================*/
 static int check_allowed3(u_char func1, u_char func2)
@@ -3902,7 +3902,7 @@
 	if (func1==audio_resume) return (-1);
 #else
 	return (0);
-#endif 000
+#endif
 }
 /*==========================================================================*/
 static int seek_pos_audio_end(void)
@@ -3914,7 +3914,7 @@
 	i=cc_Seek(i,0);
 	return (i);
 }
-#endif FUTURE
+#endif /* FUTURE */ 
 /*==========================================================================*/
 static int ReadToC(void)
 {
@@ -4152,7 +4152,7 @@
     }
 	return (0);
 }
-#endif FUTURE
+#endif /* FUTURE */ 
 /*==========================================================================*/
 /*==========================================================================*/
 /*
@@ -4250,7 +4250,7 @@
 		msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n");
 #if SAFE_MIXED
 		if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
-#endif SAFE_MIXED
+#endif /* SAFE_MIXED */
 		cc_ModeSelect(CD_FRAMESIZE);
 		cc_ModeSense();
 		D_S[d].mode=READ_M1;
@@ -4260,7 +4260,7 @@
 		msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n");
 #if SAFE_MIXED
 		if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
-#endif SAFE_MIXED
+#endif /* SAFE_MIXED */
 		cc_ModeSelect(CD_FRAMESIZE_RAW1);
 		cc_ModeSense();
 		D_S[d].mode=READ_M2;
@@ -4303,7 +4303,7 @@
 		if (famT_drive) RETURN_UP(-EINVAL);
 #if SAFE_MIXED
 		if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
-#endif SAFE_MIXED
+#endif /* SAFE_MIXED */ 
 		if (D_S[d].aud_buf==NULL) RETURN_UP(-EINVAL);
 		i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_read_audio));
 		if (i) RETURN_UP(i);
@@ -4328,7 +4328,7 @@
 #if OLD_BUSY
 		while (busy_data) sbp_sleep(HZ/10); /* wait a bit */
 		busy_audio=1;
-#endif OLD_BUSY
+#endif /* OLD_BUSY */ 
 		error_flag=0;
 		for (data_tries=5; data_tries>0; data_tries--)
 		{
@@ -4460,7 +4460,7 @@
 				i=cc_DriveReset();                /* ugly fix to prevent a hang */
 #else
 				i=cc_ReadError();
-#endif 0000
+#endif
 				continue;
 			}
 			if (fam0L_drive)
@@ -4515,7 +4515,7 @@
 		D_S[d].mode=READ_M1;
 #if OLD_BUSY
 		busy_audio=0;
-#endif OLD_BUSY
+#endif /* OLD_BUSY */ 
 		if (data_tries == 0)
 		{
 			msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__);
@@ -4601,7 +4601,7 @@
 		msg(DBG_IOC,"ioctl: CDROMPLAYMSF entered.\n");
 #if SAFE_MIXED
 		if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
-#endif SAFE_MIXED
+#endif /* SAFE_MIXED */ 
 		if (D_S[d].audio_state==audio_playing)
 		{
 			i=cc_Pause_Resume(1);
@@ -4636,7 +4636,7 @@
 		msg(DBG_IOC,"ioctl: CDROMPLAYTRKIND entered.\n");
 #if SAFE_MIXED
 		if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
-#endif SAFE_MIXED
+#endif /* SAFE_MIXED */ 
 		if (D_S[d].audio_state==audio_playing)
 		{
 			msg(DBG_IOX,"CDROMPLAYTRKIND: already audio_playing.\n");
@@ -4699,7 +4699,7 @@
 		msg(DBG_IOC,"ioctl: CDROMSTOP entered.\n");
 #if SAFE_MIXED
 		if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
-#endif SAFE_MIXED
+#endif /* SAFE_MIXED */ 
 		i=cc_Pause_Resume(1);
 		D_S[d].audio_state=0;
 #if 0
@@ -4942,7 +4942,7 @@
 #if OLD_BUSY
 	while (busy_audio) sbp_sleep(HZ); /* wait a bit */
 	busy_data=1;
-#endif OLD_BUSY
+#endif /* OLD_BUSY */
 	
 	if (D_S[i].audio_state==audio_playing) goto err_done;
 	if (d!=i) switch_drive(i);
@@ -4973,7 +4973,7 @@
 	i=prepare(0,0); /* at moment not really a hassle check, but ... */
 	if (i!=0)
 		msg(DBG_INF,"\"prepare\" tells error %d -- ignored\n", i);
-#endif FUTURE
+#endif /* FUTURE */ 
 	
 	if (!st_spinning) cc_SpinUp();
 	
@@ -4999,7 +4999,7 @@
 		{
 #if SAFE_MIXED
 			D_S[d].has_data=2; /* is really a data disk */
-#endif SAFE_MIXED
+#endif /* SAFE_MIXED */ 
 #ifdef DEBUG_GTL
 			printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 3, Time:%li\n",
 				xnr, req, req->sector, req->nr_sectors, jiffies);
@@ -5014,7 +5014,7 @@
  err_done:
 #if OLD_BUSY
 	busy_data=0;
-#endif OLD_BUSY
+#endif /* OLD_BUSY */
 #ifdef DEBUG_GTL
 	printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 4 (error), Time:%li\n",
 		xnr, req, req->sector, req->nr_sectors, jiffies);
@@ -5373,17 +5373,17 @@
 	
 #if 0
 	if (!success)
-#endif 0
+#endif
 		do
 		{
 			if (fam0LV_drive) cc_ReadStatus();
 #if 1
 			if (famT_drive) msg(DBG_TEA, "================before ResponseStatus=================.\n", i);
-#endif 1
+#endif
 			i=ResponseStatus();  /* builds status_bits, returns orig. status (old) or faked p_success (new) */
 #if 1
 			if (famT_drive)	msg(DBG_TEA, "================ResponseStatus: %d=================.\n", i);
-#endif 1
+#endif
 			if (i<0)
 			{
 				msg(DBG_INF,"bad cc_ReadStatus after read: %02X\n", D_S[d].status_bits);
@@ -5443,11 +5443,11 @@
 			msg(DBG_INF,"CD contains no data tracks.\n");
 #if SAFE_MIXED
 			D_S[d].has_data=0;
-#endif SAFE_MIXED
+#endif /* SAFE_MIXED */
 		}
 #if SAFE_MIXED
 		else if (D_S[d].has_data<1) D_S[d].has_data=1;
-#endif SAFE_MIXED
+#endif /* SAFE_MIXED */ 
 	}
 	if (!st_spinning) cc_SpinUp();
 	RETURN_UP(0);
@@ -5485,7 +5485,7 @@
 			D_S[d].open_count=0; 
 #if SAFE_MIXED
 			D_S[d].has_data=0;
-#endif SAFE_MIXED
+#endif /* SAFE_MIXED */ 
 		}
 	}
 	up(&ioctl_read_sem);
@@ -5697,7 +5697,7 @@
 int __init __SBPCD_INIT(void)
 #else
 int __init SBPCD_INIT(void)
-#endif MODULE
+#endif /* MODULE */ 
 {
 	char nbuff[16];
 	int i=0, j=0;
@@ -5724,10 +5724,10 @@
 		msg(DBG_INF,"with your REAL address.\n");
 		msg(DBG_INF,"= = = = = = = = = = END of WARNING = = = = = == = = =\n");
 	}
-#endif DISTRIBUTION
+#endif /* DISTRIBUTION */
 	sbpcd[0]=sbpcd_ioaddr; /* possibly changed by kernel command line */
 	sbpcd[1]=sbpro_type; /* possibly changed by kernel command line */
-#endif MODULE
+#endif /* MODULE */
 	
 	for (port_index=0;port_index<NUM_PROBE;port_index+=2)
 	{
@@ -5745,7 +5745,7 @@
 		sbpcd_setup((char *)type);
 #if DISTRIBUTION
 		msg(DBG_INF,"Scanning 0x%X (%s)...\n", CDo_command, type);
-#endif DISTRIBUTION
+#endif /* DISTRIBUTION */
 		if (sbpcd[port_index+1]==2)
 		{
 			i=config_spea();
@@ -5753,7 +5753,7 @@
 		}
 #ifdef PATH_CHECK
 		if (check_card(addr[1])) continue;
-#endif PATH_CHECK
+#endif /* PATH_CHECK */ 
 		i=check_drives();
 		msg(DBG_INI,"check_drives done.\n");
 		if (i>=0) break; /* drive found */
@@ -5766,7 +5766,7 @@
 		return -EIO;
 #else
 		goto init_done;
-#endif MODULE
+#endif /* MODULE */
 	}
 	
 	if (port_index>0)
@@ -5783,7 +5783,7 @@
 		switch_drive(j);
 #if 1
 		if (!famL_drive) cc_DriveReset();
-#endif 0
+#endif
 		if (!st_spinning) cc_SpinUp();
 		D_S[j].sbp_first_frame = -1;  /* First frame in buffer */
 		D_S[j].sbp_last_frame = -1;   /* Last frame in buffer  */
@@ -5794,7 +5794,7 @@
 		D_S[j].f_eject=0;
 #if EJECT
 		if (!fam0_drive) D_S[j].f_eject=1;
-#endif EJECT
+#endif /* EJECT */ 
 		cc_ReadStatus();
 		i=ResponseStatus();  /* returns orig. status or p_busy_new */
 		if (famT_drive) i=ResponseStatus();  /* returns orig. status or p_busy_new */
@@ -5840,7 +5840,7 @@
 #if SOUND_BASE
 	OUT(MIXER_addr,MIXER_CD_Volume); /* select SB Pro mixer register */
 	OUT(MIXER_data,0xCC); /* one nibble per channel, max. value: 0xFF */
-#endif SOUND_BASE
+#endif /* SOUND_BASE */ 
 	
 	if (devfs_register_blkdev(MAJOR_NR, major_name, &cdrom_fops) != 0)
 	{
@@ -5849,7 +5849,7 @@
 		return -EIO;
 #else
 		goto init_done;
-#endif MODULE
+#endif /* MODULE */
 	}
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
 #ifdef DONT_MERGE_REQUESTS
@@ -5871,7 +5871,7 @@
 		switch_drive(j);
 #if SAFE_MIXED
 		D_S[j].has_data=0;
-#endif SAFE_MIXED
+#endif /* SAFE_MIXED */ 
 		/*
 		 * allocate memory for the frame buffers
 		 */
@@ -5894,7 +5894,7 @@
 		}
 #ifdef MODULE
 		msg(DBG_INF,"data buffer size: %d frames.\n",buffers);
-#endif MODULE
+#endif /* MODULE */
 		if (D_S[j].sbp_audsiz>0)
 		{
 			D_S[j].aud_buf=(u_char *) vmalloc(D_S[j].sbp_audsiz*CD_FRAMESIZE_RAW);
@@ -5934,15 +5934,15 @@
 #if !(SBPCD_ISSUE-1)
 #ifdef CONFIG_SBPCD2
 	sbpcd2_init();
-#endif CONFIG_SBPCD2
+#endif /* CONFIG_SBPCD2 */
 #ifdef CONFIG_SBPCD3
 	sbpcd3_init();
-#endif CONFIG_SBPCD3
+#endif /* CONFIG_SBPCD3 */ 
 #ifdef CONFIG_SBPCD4
 	sbpcd4_init();
-#endif CONFIG_SBPCD4
-#endif !(SBPCD_ISSUE-1)
-#endif MODULE
+#endif /* CONFIG_SBPCD4 */ 
+#endif /* !(SBPCD_ISSUE-1) */ 
+#endif /* MODULE */
 	return 0;
 }
 /*==========================================================================*/
@@ -5981,7 +5981,7 @@
 module_exit(sbpcd_exit);
 
 
-#endif MODULE
+#endif /* MODULE */ 
 /*==========================================================================*/
 /*
  * Check if the media has changed in the CD-ROM drive.
@@ -6004,7 +6004,7 @@
 		D_S[d].diskstate_flags &= ~cd_size_bit;
 #if SAFE_MIXED
 		D_S[d].has_data=0;
-#endif SAFE_MIXED
+#endif /* SAFE_MIXED */ 
 
                 return (1);
         }
diff -u --recursive --new-file v2.4.3/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
--- v2.4.3/linux/drivers/char/cyclades.c	Wed Nov 15 00:41:03 2000
+++ linux/drivers/char/cyclades.c	Fri Apr  6 10:42:55 2001
@@ -209,7 +209,7 @@
  * board type.
  *  
  * Revision 1.36.4.30  1997/05/16 15:30:00  daniel
- * Changes to suport new cycladesZ boards.
+ * Changes to support new cycladesZ boards.
  *
  * Revision 1.36.4.29  1997/05/12 11:30:00  daniel
  * Merge of Bentson's and Daniel's version 1.36.4.28.
@@ -241,7 +241,7 @@
  * varying too fast.
  *
  * Revision 1.36.4.27  1997/03/26 10:30:00  daniel
- * Changed for suport linux versions 2.1.X.
+ * Changed for support linux versions 2.1.X.
  * Backward compatible with linux versions 2.0.X.
  * Corrected illegal use of filler field in
  * CH_CTRL struct.
@@ -676,14 +676,6 @@
 
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
-
-#ifdef CONFIG_COBALT_27
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-#define	CACHED_TO_UNCACHED(x)	(((unsigned long)(x) & \
-				  (unsigned long)0x1fffffff) + KSEG1)
-#endif
 
 #define cy_put_user	put_user
 
diff -u --recursive --new-file v2.4.3/linux/drivers/char/esp.c linux/drivers/char/esp.c
--- v2.4.3/linux/drivers/char/esp.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/char/esp.c	Fri Apr  6 10:42:55 2001
@@ -1907,7 +1907,7 @@
 			    return get_lsr_info(info, (unsigned int *) arg);
 
 		case TIOCSERSWILD:
-			if (!suser())
+			if (!capable(CAP_SYS_ADMIN))
 				return -EPERM;
 			return 0;
 
diff -u --recursive --new-file v2.4.3/linux/drivers/char/ftape/zftape/zftape-vtbl.c linux/drivers/char/ftape/zftape/zftape-vtbl.c
--- v2.4.3/linux/drivers/char/ftape/zftape/zftape-vtbl.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/char/ftape/zftape/zftape-vtbl.c	Fri Apr  6 10:42:55 2001
@@ -431,7 +431,7 @@
 /* this functions translates the failed_sector_log, misused as
  * EOF-marker list, into a virtual volume table. The table mustn't be
  * written to tape, because this would occupy the first data segment,
- * which should be the volume table, but is actualy the first segment
+ * which should be the volume table, but is actually the first segment
  * that is filled with data (when using standard ftape).  We assume,
  * that we get a non-empty failed_sector_log.
  */
diff -u --recursive --new-file v2.4.3/linux/drivers/char/isicom.c linux/drivers/char/isicom.c
--- v2.4.3/linux/drivers/char/isicom.c	Wed Dec  6 12:06:18 2000
+++ linux/drivers/char/isicom.c	Fri Apr  6 10:42:55 2001
@@ -16,6 +16,10 @@
  *
  *	10/6/99 sameer			Merged the ISA and PCI drivers to
  *					a new unified driver.
+ *	09/06/01 acme@conectiva.com.br	use capable, not suser, do
+ *					restore_flags on failure in
+ *					isicom_send_break, verify put_user
+ *					result
  *	***********************************************************
  *
  *	To use this driver you also need the support package. You 
@@ -1354,13 +1358,13 @@
 	while (((inw(base + 0x0e) & 0x0001) == 0) && (wait-- > 0));	
 	if (!wait) {
 		printk(KERN_DEBUG "ISICOM: Card found busy in isicom_send_break.\n");
-		return;
+		goto out;
 	}	
 	outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
 	outw((length & 0xff) << 8 | 0x00, base);
 	outw((length & 0xff00), base);
 	InterruptTheCard(base);
-	restore_flags(flags);
+out:	restore_flags(flags);
 }
 
 static int isicom_get_modem_info(struct isi_port * port, unsigned int * value)
@@ -1375,8 +1379,7 @@
 		((status & ISI_DSR) ? TIOCM_DSR : 0) |
 		((status & ISI_CTS) ? TIOCM_CTS : 0) |
 		((status & ISI_RI ) ? TIOCM_RI  : 0);
-	put_user(info, (unsigned int *) value);
-	return 0;	
+	return put_user(info, (unsigned int *) value);
 }
 
 static int isicom_set_modem_info(struct isi_port * port, unsigned int cmd,
@@ -1438,7 +1441,7 @@
 	reconfig_port = ((port->flags & ASYNC_SPD_MASK) != 
 			 (newinfo.flags & ASYNC_SPD_MASK));
 	
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if ((newinfo.close_delay != port->close_delay) ||
 		    (newinfo.closing_wait != port->closing_wait) ||
 		    ((newinfo.flags & ~ASYNC_USR_MASK) != 
diff -u --recursive --new-file v2.4.3/linux/drivers/char/n_r3964.c linux/drivers/char/n_r3964.c
--- v2.4.3/linux/drivers/char/n_r3964.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/char/n_r3964.c	Fri Apr  6 10:51:19 2001
@@ -7,7 +7,7 @@
  * http://www.pap-philips.de
  * -----------------------------------------------------------
  * This software may be used and distributed according to the terms of
- * the GNU Public License, incorporated herein by reference.
+ * the GNU General Public License, incorporated herein by reference.
  *
  * Author:
  * L. Haag
@@ -65,7 +65,7 @@
 
 //#define DEBUG_QUEUE
 
-/* Log successfull handshake and protocol operations  */
+/* Log successful handshake and protocol operations  */
 //#define DEBUG_PROTO_S
 
 /* Log handshake and protocol errors: */
diff -u --recursive --new-file v2.4.3/linux/drivers/char/n_tty.c linux/drivers/char/n_tty.c
--- v2.4.3/linux/drivers/char/n_tty.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/char/n_tty.c	Fri Apr  6 10:42:55 2001
@@ -15,7 +15,7 @@
  * This file also contains code originally written by Linus Torvalds,
  * Copyright 1991, 1992, 1993, and by Julian Cowley, Copyright 1994.
  * 
- * This file may be redistributed under the terms of the GNU Public
+ * This file may be redistributed under the terms of the GNU General Public
  * License.
  *
  * Reduced memory usage for older ARM systems  - Russell King.
@@ -100,7 +100,7 @@
 	unsigned long flags;
 	/*
 	 *	The problem of stomping on the buffers ends here.
-	 *	Why didn't anyone see this one comming? --AJK
+	 *	Why didn't anyone see this one coming? --AJK
 	*/
 	spin_lock_irqsave(&tty->read_lock, flags);
 	put_tty_queue_nolock(c, tty);
diff -u --recursive --new-file v2.4.3/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c
--- v2.4.3/linux/drivers/char/pc_keyb.c	Fri Mar  2 18:38:37 2001
+++ linux/drivers/char/pc_keyb.c	Fri Apr  6 10:42:55 2001
@@ -1016,6 +1016,8 @@
 
 	misc_register(&psaux_mouse);
 	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
+	if (queue == NULL)
+		panic("psaux_init(): out of memory");
 	memset(queue, 0, sizeof(*queue));
 	queue->head = queue->tail = 0;
 	init_waitqueue_head(&queue->proc_list);
diff -u --recursive --new-file v2.4.3/linux/drivers/char/pcwd.c linux/drivers/char/pcwd.c
--- v2.4.3/linux/drivers/char/pcwd.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/char/pcwd.c	Fri Apr  6 10:42:55 2001
@@ -462,8 +462,8 @@
 			outb_p(0xA5, current_readport + 3);
 			spin_unlock(&io_lock);
 		}
-		unlock_kernel();
 #endif
+		unlock_kernel();
 	}
 	return 0;
 }
diff -u --recursive --new-file v2.4.3/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- v2.4.3/linux/drivers/char/serial.c	Tue Mar  6 20:13:51 2001
+++ linux/drivers/char/serial.c	Fri Apr  6 10:44:56 2001
@@ -59,8 +59,8 @@
  *
  */
 
-static char *serial_version = "5.05";
-static char *serial_revdate = "2000-12-13";
+static char *serial_version = "5.05a";
+static char *serial_revdate = "2001-03-20";
 
 /*
  * Serial driver configuration section.  Here are the various options:
@@ -3924,11 +3924,6 @@
 	       return;
        }
 
-       if (!(board->flags & SPCI_FL_ISPNP) && pci_enable_device(dev)) {
-	       printk("serial: PCI device enable failed\n");
-	       return;
-       }
-
 	/*
 	 * Run the initialization function, if any
 	 */
@@ -4610,7 +4605,8 @@
 	 * (Should we try to make guesses for multiport serial devices
 	 * later?) 
 	 */
-	if ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL ||
+	if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
+	    ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
 	    (dev->class & 0xff) > 6)
 		return 1;
 
@@ -4639,6 +4635,7 @@
 				     const struct pci_device_id *ent)
 {
 	struct pci_board *board, tmp;
+	int rc;
 
 	for (board = pci_boards; board->vendor; board++) {
 		if (board->vendor != (unsigned short) PCI_ANY_ID &&
@@ -4656,6 +4653,9 @@
 		break;
 	}
 
+	rc = pci_enable_device(dev);
+	if (rc) return rc;
+
 	if (board->vendor == 0 && serial_pci_guess_board(dev, board))
 		return -ENODEV;
 	else if (serial_pci_guess_board(dev, &tmp) == 0) {
@@ -4708,6 +4708,8 @@
 static struct pci_device_id serial_pci_tbl[] __devinitdata = {
        { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
 	 PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00, },
+       { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+	 PCI_CLASS_COMMUNICATION_MODEM << 8, 0xffff00, },
        { 0, }
 };
 
diff -u --recursive --new-file v2.4.3/linux/drivers/char/sx.c linux/drivers/char/sx.c
--- v2.4.3/linux/drivers/char/sx.c	Tue Mar  6 19:44:34 2001
+++ linux/drivers/char/sx.c	Fri Apr  6 10:42:55 2001
@@ -1767,6 +1767,20 @@
 }
 
 
+static void sx_break (struct tty_struct * tty, int flag)
+{
+	struct sx_port *port = tty->driver_data;
+	int rv;
+
+	if (flag) 
+		rv = sx_send_command (port, HS_START, -1, HS_IDLE_BREAK);
+	else 
+		rv = sx_send_command (port, HS_STOP, -1, HS_IDLE_OPEN);
+	if (rv != 1) printk (KERN_ERR "sx: couldn't send break (%x).\n",
+			read_sx_byte (port->board, CHAN_OFFSET (port, hi_hstat)));
+}
+
+
 static int sx_ioctl (struct tty_struct * tty, struct file * filp, 
                      unsigned int cmd, unsigned long arg)
 {
@@ -1835,7 +1849,6 @@
 			sx_reconfigure_port(port);
 		}
 		break;
-
 	default:
 		rc = -ENOIOCTLCMD;
 		break;
@@ -2215,6 +2228,7 @@
 	sx_driver.table = sx_table;
 	sx_driver.termios = sx_termios;
 	sx_driver.termios_locked = sx_termios_locked;
+	sx_driver.break_ctl = sx_break;
 
 	sx_driver.open	= sx_open;
 	sx_driver.close = gs_close;
diff -u --recursive --new-file v2.4.3/linux/drivers/char/toshiba.c linux/drivers/char/toshiba.c
--- v2.4.3/linux/drivers/char/toshiba.c	Wed Sep 27 13:53:56 2000
+++ linux/drivers/char/toshiba.c	Fri Apr  6 10:42:55 2001
@@ -1,19 +1,24 @@
 /* toshiba.c -- Linux driver for accessing the SMM on Toshiba laptops
  *
- * Copyright (c) 1996-2000  Jonathan A. Buzzard (jonathan@buzzard.org.uk)
+ * Copyright (c) 1996-2001  Jonathan A. Buzzard (jonathan@buzzard.org.uk)
  *
  * Valuable assistance and patches from:
  *     Tom May <tom@you-bastards.com>
  *     Rob Napier <rnapier@employees.org>
  *
  * Fn status port numbers for machine ID's courtesy of
+ *     0xfc02: Scott Eisert <scott.e@sky-eye.com>
+ *     0xfc04: Steve VanDevender <stevev@efn.org>
  *     0xfc08: Garth Berry <garth@itsbruce.net>
+ *     0xfc0a: Egbert Eich <eich@xfree86.org>
+ *     0xfc10: Andrew Lofthouse <Andrew.Lofthouse@robins.af.mil>
  *     0xfc11: Spencer Olson <solson@novell.com>
  *     0xfc13: Claudius Frankewitz <kryp@gmx.de>
  *     0xfc15: Tom May <tom@you-bastards.com>
  *     0xfc17: Dave Konrad <konrad@xenia.it>
  *     0xfc1a: George Betzos <betzos@engr.colostate.edu>
  *     0xfc1d: Arthur Liu <armie@slap.mine.nu>
+ *     0xfcd1: Mr. Dave Konrad <konrad@xenia.it>
  *
  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
  *
@@ -46,7 +51,7 @@
  *
  */
 
-#define TOSH_VERSION "1.7 22/6/2000"
+#define TOSH_VERSION "1.9 22/3/2001"
 #define TOSH_DEBUG 0
 
 #include <linux/module.h>
@@ -117,27 +122,6 @@
 
 
 /*
- * At some point we need to emulate setting the HDD auto off times for
- * the new laptops. We can do this by calling the ide_ioctl on /dev/hda.
- * The values we need for the various times are
- *
- *    Disabled   0x00
- *    1 minute   0x0c
- *    3 minutes  0x24
- *    5 minutes  0x3c
- *   10 minutes  0x78
- *   15 minutes  0xb4
- *   20 minutes  0xf0
- *   30 minutes  0xf1
- *
- */
-/*static int tosh_emulate_hdd(SMMRegisters *regs)
-{
-	return 0;
-}*/
-
-
-/*
  * For the Portage 610CT and the Tecra 700CS/700CDT emulate the HCI fan function
  */
 static int tosh_emulate_fan(SMMRegisters *regs)
@@ -348,11 +332,12 @@
 static void tosh_set_fn_port(void)
 {
 	switch (tosh_id) {
+		case 0xfc02: case 0xfc04: case 0xfc09: case 0xfc0a: case 0xfc10:
 		case 0xfc11: case 0xfc13: case 0xfc15: case 0xfc1a:
 			tosh_fn = 0x62;
 			break;
-		case 0xfc08: case 0xfc17: case 0xfc1d: case 0xfcd1:
-		case 0xfce0: case 0xfce2:
+		case 0xfc08: case 0xfc17: case 0xfc1d: case 0xfcd1: case 0xfce0:
+		case 0xfce2:
 			tosh_fn = 0x68;
 			break;
 		default:
@@ -472,7 +457,6 @@
 	   0xa0-0xbf we can't. We just have to live dangerously and use the
 	   ports anyway, oh boy! */
 
-
 	/* do we need to emulate the fan? */
 
 	if ((tosh_id==0xfccb) || (tosh_id==0xfccc))
@@ -501,7 +485,9 @@
 	misc_register(&tosh_device);
 
 	/* register the proc entry */
+
 	create_proc_info_entry("toshiba", 0, NULL, tosh_get_info);
+
 	return 0;
 }
 
@@ -514,9 +500,11 @@
 void cleanup_module(void)
 {
 	/* remove the proc entry */
+
 	remove_proc_entry("toshiba", NULL);
 
 	/* unregister the device file */
+
 	misc_deregister(&tosh_device);
 }
 #endif
diff -u --recursive --new-file v2.4.3/linux/drivers/md/md.c linux/drivers/md/md.c
--- v2.4.3/linux/drivers/md/md.c	Mon Mar 12 18:13:28 2001
+++ linux/drivers/md/md.c	Fri Apr  6 10:42:55 2001
@@ -1063,10 +1063,10 @@
 	}
 	printk(".\n");
 	if (err) {
-		printk("errors occured during superblock update, repeating\n");
+		printk("errors occurred during superblock update, repeating\n");
 		if (--count)
 			goto repeat;
-		printk("excessive errors occured during superblock update, exiting\n");
+		printk("excessive errors occurred during superblock update, exiting\n");
 	}
 	return 0;
 }
diff -u --recursive --new-file v2.4.3/linux/drivers/media/video/cpia.c linux/drivers/media/video/cpia.c
--- v2.4.3/linux/drivers/media/video/cpia.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/video/cpia.c	Fri Apr  6 10:42:55 2001
@@ -2832,7 +2832,7 @@
 		DBG("VIDIOCMCAPTURE: %d / %d / %dx%d\n", vm.format, vm.frame,
 		    vm.width, vm.height);
 #endif
-		if (vm.frame<0||vm.frame>FRAME_NUM) {
+		if (vm.frame<0||vm.frame>=FRAME_NUM) {
 			retval = -EINVAL;
 			break;
 		}
diff -u --recursive --new-file v2.4.3/linux/drivers/media/video/stradis.c linux/drivers/media/video/stradis.c
--- v2.4.3/linux/drivers/media/video/stradis.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/video/stradis.c	Fri Apr  6 10:42:55 2001
@@ -54,8 +54,8 @@
 #include "cs8420.h"
 
 #define DEBUG(x) 		/* debug driver */
-#undef  IDEBUG(x) 		/* debug irq handler */
-#undef  MDEBUG(x) 		/* debug memory management */
+#undef  IDEBUG	 		/* debug irq handler */
+#undef  MDEBUG	 		/* debug memory management */
 
 #define SAA7146_MAX 6
 
diff -u --recursive --new-file v2.4.3/linux/drivers/mtd/pmc551.c linux/drivers/mtd/pmc551.c
--- v2.4.3/linux/drivers/mtd/pmc551.c	Fri Feb 16 16:02:36 2001
+++ linux/drivers/mtd/pmc551.c	Fri Apr  6 10:42:55 2001
@@ -13,17 +13,17 @@
  *
  * Description:
  *	 This driver is intended to support the PMC551 PCI Ram device from
- *	 Ramix Inc.  The PMC551 is a PMC Mezzanine module for cPCI embeded
+ *	 Ramix Inc.  The PMC551 is a PMC Mezzanine module for cPCI embedded
  *	 systems.  The device contains a single SROM that initally programs the
  *	 V370PDC chipset onboard the device, and various banks of DRAM/SDRAM
  *	 onboard.  This driver implements this PCI Ram device as an MTD (Memory
  *	 Technologies Device) so that it can be used to hold a filesystem, or
- *	 for added swap space in embeded systems.  Since the memory on this
+ *	 for added swap space in embedded systems.  Since the memory on this
  *	 board isn't as fast as main memory we do not try to hook it into main
  *	 memeory as that would simply reduce performance on the system.  Using
  *	 it as a block device allows us to use it as high speed swap or for a
- *	 high speed disk device of some sort.  Which becomes very usefull on
- *	 diskless systems in the embeded market I might add.
+ *	 high speed disk device of some sort.  Which becomes very useful on
+ *	 diskless systems in the embedded market I might add.
  *	 
  * Notes:
  *	 Due to what I assume is more buggy SROM, the 64M PMC551 I have
diff -u --recursive --new-file v2.4.3/linux/drivers/net/8139too.c linux/drivers/net/8139too.c
--- v2.4.3/linux/drivers/net/8139too.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/net/8139too.c	Fri Apr  6 11:50:02 2001
@@ -149,7 +149,7 @@
 #include <asm/io.h>
 
 
-#define RTL8139_VERSION "0.9.15c"
+#define RTL8139_VERSION "0.9.15d"
 #define MODNAME "8139too"
 #define RTL8139_DRIVER_NAME   MODNAME " Fast Ethernet driver " RTL8139_VERSION
 #define PFX MODNAME ": "
@@ -204,6 +204,7 @@
 #define RX_BUF_PAD 16
 #define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
 #define RX_BUF_TOT_LEN (RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
+#define RX_EARLY_THRESH 2
 
 /* Number of Tx descriptor registers. */
 #define NUM_TX_DESC	4
@@ -662,7 +663,7 @@
 	TxErr | TxOK | RxErr | RxOK;
 
 static const unsigned int rtl8139_rx_config =
-	  RxCfgEarlyRxNone | RxCfgRcv32K | RxNoWrap |
+	  (RX_EARLY_THRESH << RxCfgEarlyRxShift) | RxCfgRcv32K | RxNoWrap |
 	  (RX_FIFO_THRESH << RxCfgFIFOShift) |
 	  (RX_DMA_BURST << RxCfgDMAShift);
 
@@ -1843,10 +1844,9 @@
 }
 
 
-/* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the
-   field alignments and semantics. */
 static void rtl8139_rx_interrupt (struct net_device *dev,
-				  struct rtl8139_private *tp, void *ioaddr)
+				  struct rtl8139_private *tp, void *ioaddr,
+				  u16 status)
 {
 	unsigned char *rx_ring;
 	u16 cur_rx;
@@ -1863,6 +1863,11 @@
 		 RTL_R16 (RxBufAddr),
 		 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
 
+	if (status & RxFIFOOver)
+		status = RxOverflow | RxOK;
+	else
+		status = RxOK;
+
 	while ((RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
 		int ring_offset = cur_rx % RX_BUF_LEN;
 		u32 rx_status;
@@ -1889,17 +1894,10 @@
 		}
 #endif
 
-		/* E. Gill */
-		/* Note from BSD driver:
-		 * Here's a totally undocumented fact for you. When the
-		 * RealTek chip is in the process of copying a packet into
-		 * RAM for you, the length will be 0xfff0. If you spot a
-		 * packet header with this value, you need to stop. The
-		 * datasheet makes absolutely no mention of this and
-		 * RealTek should be shot for this.
-		 */
-		if (rx_size == 0xfff0)
+		if (rx_size == 0xfff0) { /* Early Rx in progress */
+			RTL_W16_F (IntrStatus, status);
 			break;
+		}
 
 		/* If Rx err or invalid rx_size/rx_status received
 		 * (which happens if we get lost in the ring),
@@ -1942,7 +1940,9 @@
 		}
 
 		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
-		RTL_W16_F (RxBufPtr, cur_rx - 16);
+		RTL_W16 (RxBufPtr, cur_rx - 16);
+		RTL_W16_F (IntrStatus, status);
+		barrier();
 	}
 
 	DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
@@ -1996,11 +1996,6 @@
 		tp->stats.rx_length_errors++;
 	if (status & (RxUnderrun | RxFIFOOver))
 		tp->stats.rx_fifo_errors++;
-	if (status & RxOverflow) {
-		tp->stats.rx_over_errors++;
-		tp->cur_rx = RTL_R16 (RxBufAddr) % RX_BUF_LEN;
-		RTL_W16_F (RxBufPtr, tp->cur_rx - 16);
-	}
 	if (status & PCIErr) {
 		u16 pci_cmd_status;
 		pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
@@ -2020,7 +2015,8 @@
 	struct rtl8139_private *tp = dev->priv;
 	int boguscnt = max_interrupt_work;
 	void *ioaddr = tp->mmio_addr;
-	int status = 0, link_changed = 0; /* avoid bogus "uninit" warning */
+	int ackstat, status;
+	int link_changed = 0; /* avoid bogus "uninit" warning */
 
 	do {
 		status = RTL_R16 (IntrStatus);
@@ -2053,26 +2049,26 @@
 		   CPU speed, lower CPU speed --> more errors).
 		   After clearing the RxOverflow bit the transfer of the
 		   packet was repeated and all data are error free transferred */
-		RTL_W16_F (IntrStatus, (status & RxFIFOOver) ? (status | RxOverflow) : status);
+		ackstat = status & ~(RxFIFOOver | RxOverflow | RxOK);
+		RTL_W16 (IntrStatus, ackstat);
 
-		DPRINTK ("%s: interrupt  status=%#4.4x new intstat=%#4.4x.\n",
-				dev->name, status,
-				RTL_R16 (IntrStatus));
+		DPRINTK ("%s: interrupt  status=%#4.4x ackstat=%#4.4x new intstat=%#4.4x.\n",
+			 dev->name, ackstat, status, RTL_R16 (IntrStatus));
 
 		if ((status &
 		     (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
 		      RxFIFOOver | TxErr | TxOK | RxErr | RxOK)) == 0)
 			break;
 
+		if (netif_running (dev) &&
+		    status & (RxOK | RxUnderrun | RxOverflow | RxFIFOOver))	/* Rx interrupt */
+			rtl8139_rx_interrupt (dev, tp, ioaddr, status);
+
 		/* Check uncommon events with one test. */
 		if (status & (PCIErr | PCSTimeout | RxUnderrun | RxOverflow |
 		  	      RxFIFOOver | TxErr | RxErr))
 			rtl8139_weird_interrupt (dev, tp, ioaddr,
 						 status, link_changed);
-
-		if (netif_running (dev) &&
-		    status & (RxOK | RxUnderrun | RxOverflow | RxFIFOOver))	/* Rx interrupt */
-			rtl8139_rx_interrupt (dev, tp, ioaddr);
 
 		if (netif_running (dev) &&
 		    status & (TxOK | TxErr)) {
diff -u --recursive --new-file v2.4.3/linux/drivers/net/pci-skeleton.c linux/drivers/net/pci-skeleton.c
--- v2.4.3/linux/drivers/net/pci-skeleton.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/net/pci-skeleton.c	Fri Apr  6 10:51:19 2001
@@ -36,7 +36,7 @@
 	-----<snip>-----
 
 	This software may be used and distributed according to the terms
-	of the GNU Public License, incorporated herein by reference.
+	of the GNU General Public License, incorporated herein by reference.
 
 
 -----------------------------------------------------------------------------
diff -u --recursive --new-file v2.4.3/linux/drivers/net/sundance.c linux/drivers/net/sundance.c
--- v2.4.3/linux/drivers/net/sundance.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/net/sundance.c	Fri Apr  6 10:42:55 2001
@@ -1239,7 +1239,7 @@
 	struct net_device *dev = pci_get_drvdata(pdev);
 	
 	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
-	while (dev) {
+	if (dev) {
 		unregister_netdev(dev);
 		pci_release_regions(pdev);
 #ifndef USE_IO_OPS
diff -u --recursive --new-file v2.4.3/linux/drivers/net/tulip/21142.c linux/drivers/net/tulip/21142.c
--- v2.4.3/linux/drivers/net/tulip/21142.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/tulip/21142.c	Tue Apr  3 10:19:43 2001
@@ -2,14 +2,15 @@
 	drivers/net/tulip/21142.c
 
 	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
-	Copyright 2000  The Linux Kernel Team
-	Written/copyright 1994-1999 by Donald Becker.
+	Copyright 2000,2001  The Linux Kernel Team
+	Written/copyright 1994-2001 by Donald Becker.
 
 	This software may be used and distributed according to the terms
 	of the GNU General Public License, incorporated herein by reference.
 
-	Please refer to Documentation/networking/tulip.txt for more
-	information on this driver.
+	Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
+	for more information on this driver, or visit the project
+	Web page at http://sourceforge.net/projects/tulip/
 
 */
 
@@ -107,16 +108,17 @@
 	dev->if_port = 0;
 	tp->nway = tp->mediasense = 1;
 	tp->nwayset = tp->lpar = 0;
+	if (tp->chip_id == PNIC2) {
+		tp->csr6 = 0x01000000 | (tp->to_advertise & 0x0040 ? FullDuplex : 0);
+		return;
+	}
 	if (tulip_debug > 1)
 		printk(KERN_DEBUG "%s: Restarting 21143 autonegotiation, csr14=%8.8x.\n",
 			   dev->name, csr14);
 	outl(0x0001, ioaddr + CSR13);
 	udelay(100);
 	outl(csr14, ioaddr + CSR14);
-	if (tp->chip_id == PNIC2)
-	  tp->csr6 = 0x01a80000 | (tp->to_advertise & 0x0040 ? 0x0200 : 0);
-	else
-	  tp->csr6 = 0x82420000 | (tp->to_advertise & 0x0040 ? 0x0200 : 0);
+	tp->csr6 = 0x82420000 | (tp->to_advertise & 0x0040 ? FullDuplex : 0);
 	tulip_outl_csr(tp, tp->csr6, CSR6);
 	if (tp->mtable  &&  tp->mtable->csr15dir) {
 		outl(tp->mtable->csr15dir, ioaddr + CSR15);
diff -u --recursive --new-file v2.4.3/linux/drivers/net/tulip/ChangeLog linux/drivers/net/tulip/ChangeLog
--- v2.4.3/linux/drivers/net/tulip/ChangeLog	Fri Mar  2 11:02:14 2001
+++ linux/drivers/net/tulip/ChangeLog	Tue Apr  3 10:19:43 2001
@@ -1,3 +1,80 @@
+2001-04-03  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	* tulip_core.c: Remove code that existed when one or more of
+	  the following defines existed.  These defines were never used
+	  by normal users in practice: TULIP_FULL_DUPLEX,
+	  TULIP_DEFAULT_MEDIA, and TULIP_NO_MEDIA_SWITCH.
+	  
+	* tulip.h, eeprom.c: Move EE_* constants from tulip.h to eeprom.c.
+	* tulip.h, media.c: Move MDIO_* constants from tulip.h to media.c.
+
+	* media.c: Add barrier() to mdio_read/write's PNIC status check
+	  loops.
+
+2001-04-03  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	Merged from Becker's tulip.c 0.92t:
+
+	* tulip.h: Add MEDIA_MASK constant for bounding medianame[]
+	  array lookups.
+	* eeprom.c, media.c, timer.c, tulip_core.c: Use it.
+
+	* media.c, tulip_core.c: mdio_{read,write} cleanup.  Since this
+	  is called [pretty much] directly from ioctl, we mask
+	  read/write arguments to limit the values passed.
+	  Added mii_lock.  Added comet_miireg2offset and better
+	  Comet-specific mdio_read/write code.	Pay closer attention
+	  to the bits we set in ioctl.	Remove spinlocks from ioctl,
+	  they are in mdio_read/write now.  Use mask to limit
+	  phy number in tulip_init_one's MII scan.
+
+2001-04-03  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	Merged from Becker's tulip.c 0.92t:
+
+	* 21142.c, tulip_core.c: PNIC2 MAC address and NWay fixes.
+	* tulip.h: Add FullDuplex constant, used in above change.
+
+2001-04-03  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	* timer.c: Do not call netif_carrier_{on,off}, it is not used in
+	  the main tree.  Leave code in, disabled, as markers for future
+	  carrier notification.
+
+2001-04-03  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	Merged from Becker's tulip.c 0.92t, except for the tulip.h
+	whitespace cleanup:
+
+	* interrupt.c: If Rx stops, make sure to update the
+	  multicast filter before restarting.
+	* tulip.h: Add COMET_MAC_ADDR feature flag, clean up flags.
+	  Add Accept* Rx mode bit constants.
+	  Add mc_filter[] to driver private struct.
+	* tulip_core.c: Add new Comet PCI id 0x1113:0x9511.
+	  Add COMET_MAC_ADDR feature flag to comet entry in board info array.
+	  Prefer to test COMET_MAC_ADDR flag to testing chip_id for COMET,
+	  when dealing with the Comet's MAC address.
+	  Enable Tx underrun recovery for Comet chips.
+	  Use new Accept* constants in set_rx_mode.
+	  Prefer COMET_MAC_ADDR flag test to chip_id test in set_rx_mode.
+	  Store built mc_filter for later use in intr handler by Comets.
+
+2001-04-03  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	* tulip_core.c: Use tp->cur_tx when building the
+	  setup frame, instead of assuming that the setup
+	  frame is always built in slot zero.  This case is
+	  hit during PM resume.
+
+2001-04-03  Jeff Garzik  <jgarzik@mandrakesoft.com>
+
+	* *.c: Update file headers (copyright, urls, etc.)
+	* Makefile: re-order to that chip-specific modules on own line
+	* eeprom.c: BSS/zero-init cleanup (Andrey Panin)
+	* tulip_core.c: merge medianame[] update from tulip.c.
+	  Additional arch-specific rx_copybreak, csr0 values. (various)
+
 2001-02-20  Jeff Garzik  <jgarzik@mandrakesoft.com>
 
 	* media.c (tulip_select_media): No need to initialize
diff -u --recursive --new-file v2.4.3/linux/drivers/net/tulip/Makefile linux/drivers/net/tulip/Makefile
--- v2.4.3/linux/drivers/net/tulip/Makefile	Fri Dec 29 14:07:22 2000
+++ linux/drivers/net/tulip/Makefile	Tue Apr  3 10:19:43 2001
@@ -9,7 +9,9 @@
 
 O_TARGET := tulip.o
 
-obj-y   := 21142.o eeprom.o interrupt.o media.o pnic.o timer.o tulip_core.o
+obj-y   := eeprom.o interrupt.o media.o \
+	   timer.o tulip_core.o		\
+	   21142.o pnic.o
 obj-m   := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.3/linux/drivers/net/tulip/eeprom.c linux/drivers/net/tulip/eeprom.c
--- v2.4.3/linux/drivers/net/tulip/eeprom.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/tulip/eeprom.c	Tue Apr  3 10:19:43 2001
@@ -2,14 +2,15 @@
 	drivers/net/tulip/eeprom.c
 
 	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
-	Copyright 2000  The Linux Kernel Team
-	Written/copyright 1994-1999 by Donald Becker.
+	Copyright 2000,2001  The Linux Kernel Team
+	Written/copyright 1994-2001 by Donald Becker.
 
 	This software may be used and distributed according to the terms
 	of the GNU General Public License, incorporated herein by reference.
 
-	Please refer to Documentation/networking/tulip.txt for more
-	information on this driver.
+	Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
+	for more information on this driver, or visit the project
+	Web page at http://sourceforge.net/projects/tulip/
 
 */
 
@@ -77,9 +78,9 @@
 void __devinit tulip_parse_eeprom(struct net_device *dev)
 {
 	/* The last media info list parsed, for multiport boards.  */
-	static struct mediatable *last_mediatable = NULL;
-	static unsigned char *last_ee_data = NULL;
-	static int controller_index = 0;
+	static struct mediatable *last_mediatable;
+	static unsigned char *last_ee_data;
+	static int controller_index;
 	struct tulip_private *tp = (struct tulip_private *)dev->priv;
 	unsigned char *ee_data = tp->eeprom;
 	int i;
@@ -143,9 +144,10 @@
 
 		printk(KERN_INFO "%s: 21041 Media table, default media %4.4x (%s).\n",
 			   dev->name, media,
-			   media & 0x0800 ? "Autosense" : medianame[media & 15]);
+			   media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
 		for (i = 0; i < count; i++) {
-			unsigned char media_code = *p++;
+			unsigned char media_block = *p++;
+			int media_code = media_block & MEDIA_MASK;
 			if (media_code & 0x40)
 				p += 6;
 			printk(KERN_INFO "%s:  21041 media #%d, %s.\n",
@@ -182,7 +184,7 @@
 		mtable->csr15dir = mtable->csr15val = 0;
 
 		printk(KERN_INFO "%s:  EEPROM default media type %s.\n", dev->name,
-			   media & 0x0800 ? "Autosense" : medianame[media & 15]);
+			   media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
 		for (i = 0; i < count; i++) {
 			struct medialeaf *leaf = &mtable->mleaf[i];
 
@@ -216,7 +218,7 @@
 					new_advertise |= get_u16(&p[7+gpr_len+reset_len]);
 				} else {
 					mtable->has_nonmii = 1;
-					leaf->media = p[2] & 0x0f;
+					leaf->media = p[2] & MEDIA_MASK;
 					/* Davicom's media number for 100BaseTX is strange */
 					if (tp->chip_id == DM910X && leaf->media == 1)
 						leaf->media = 3;
@@ -261,6 +263,23 @@
 	}
 }
 /* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/
+
+/*  EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK	0x02	/* EEPROM shift clock. */
+#define EE_CS			0x01	/* EEPROM chip select. */
+#define EE_DATA_WRITE	0x04	/* Data from the Tulip to EEPROM. */
+#define EE_WRITE_0		0x01
+#define EE_WRITE_1		0x05
+#define EE_DATA_READ	0x08	/* Data from the EEPROM chip. */
+#define EE_ENB			(0x4800 | EE_CS)
+
+/* Delay between EEPROM clock transitions.
+   Even at 33Mhz current PCI implementations don't overrun the EEPROM clock.
+   We add a bus turn-around to insure that this remains true. */
+#define eeprom_delay()	inl(ee_addr)
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_READ_CMD		(6)
 
 /* Note: this routine returns extra data bits for size detection. */
 int __devinit tulip_read_eeprom(long ioaddr, int location, int addr_len)
diff -u --recursive --new-file v2.4.3/linux/drivers/net/tulip/interrupt.c linux/drivers/net/tulip/interrupt.c
--- v2.4.3/linux/drivers/net/tulip/interrupt.c	Fri Mar  2 11:02:14 2001
+++ linux/drivers/net/tulip/interrupt.c	Tue Apr  3 10:19:43 2001
@@ -2,14 +2,15 @@
 	drivers/net/tulip/interrupt.c
 
 	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
-	Copyright 2000  The Linux Kernel Team
-	Written/copyright 1994-1999 by Donald Becker.
+	Copyright 2000,2001  The Linux Kernel Team
+	Written/copyright 1994-2001 by Donald Becker.
 
 	This software may be used and distributed according to the terms
 	of the GNU General Public License, incorporated herein by reference.
 
-	Please refer to Documentation/networking/tulip.txt for more
-	information on this driver.
+	Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
+	for more information on this driver, or visit the project
+	Web page at http://sourceforge.net/projects/tulip/
 
 */
 
@@ -299,6 +300,12 @@
 				/* Restart the transmit process. */
 				tulip_restart_rxtx(tp, tp->csr6);
 				outl(0, ioaddr + CSR1);
+			}
+			if (csr5 & (RxDied | RxNoBuf)) {
+				if (tp->flags & COMET_MAC_ADDR) {
+					outl(tp->mc_filter[0], ioaddr + 0xAC);
+					outl(tp->mc_filter[1], ioaddr + 0xB0);
+				}
 			}
 			if (csr5 & RxDied) {		/* Missed a Rx frame. */
 				tp->stats.rx_errors++;
diff -u --recursive --new-file v2.4.3/linux/drivers/net/tulip/media.c linux/drivers/net/tulip/media.c
--- v2.4.3/linux/drivers/net/tulip/media.c	Fri Mar  2 11:02:14 2001
+++ linux/drivers/net/tulip/media.c	Tue Apr  3 10:19:43 2001
@@ -2,14 +2,15 @@
 	drivers/net/tulip/media.c
 
 	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
-	Copyright 2000  The Linux Kernel Team
-	Written/copyright 1994-1999 by Donald Becker.
+	Copyright 2000,2001  The Linux Kernel Team
+	Written/copyright 1994-2001 by Donald Becker.
 
 	This software may be used and distributed according to the terms
 	of the GNU General Public License, incorporated herein by reference.
 
-	Please refer to Documentation/networking/tulip.txt for more
-	information on this driver.
+	Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
+	for more information on this driver, or visit the project
+	Web page at http://sourceforge.net/projects/tulip/
 
 */
 
@@ -22,6 +23,25 @@
    10base2(!) packets trigger a full-duplex-request interrupt. */
 #define FULL_DUPLEX_MAGIC	0x6969
 
+/* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
+   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
+   "overclocking" issues or future 66Mhz PCI. */
+#define mdio_delay() inl(mdio_addr)
+
+/* Read and write the MII registers using software-generated serial
+   MDIO protocol.  It is just different enough from the EEPROM protocol
+   to not share code.  The maxium data clock rate is 2.5 Mhz. */
+#define MDIO_SHIFT_CLK		0x10000
+#define MDIO_DATA_WRITE0	0x00000
+#define MDIO_DATA_WRITE1	0x20000
+#define MDIO_ENB		0x00000 /* Ignore the 0x02000 databook setting. */
+#define MDIO_ENB_IN		0x40000
+#define MDIO_DATA_READ		0x80000
+
+static const unsigned char comet_miireg2offset[32] = {
+	0xB4, 0xB8, 0xBC, 0xC0,  0xC4, 0xC8, 0xCC, 0,  0,0,0,0,  0,0,0,0,
+	0,0xD0,0,0,  0,0,0,0,  0,0,0,0, 0, 0xD4, 0xD8, 0xDC, };
+
 
 /* MII transceiver control section.
    Read and write the MII registers using software-generated serial
@@ -32,32 +52,34 @@
 {
 	struct tulip_private *tp = (struct tulip_private *)dev->priv;
 	int i;
-	int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
+	int read_cmd = (0xf6 << 10) | ((phy_id & 0x1f) << 5) | location;
 	int retval = 0;
 	long ioaddr = dev->base_addr;
 	long mdio_addr = ioaddr + CSR9;
+	unsigned long flags;
+
+	if (location & ~0x1f)
+		return 0xffff;
+
+	if (tp->chip_id == COMET  &&  phy_id == 30) {
+		if (comet_miireg2offset[location])
+			return inl(ioaddr + comet_miireg2offset[location]);
+		return 0xffff;
+	}
 
+	spin_lock_irqsave(&tp->mii_lock, flags);
 	if (tp->chip_id == LC82C168) {
 		int i = 1000;
 		outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
 		inl(ioaddr + 0xA0);
 		inl(ioaddr + 0xA0);
-		while (--i > 0)
+		while (--i > 0) {
+			barrier();
 			if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
-				return retval & 0xffff;
-		return 0xffff;
-	}
-
-	if (tp->chip_id == COMET) {
-		if (phy_id == 1) {
-			if (location < 7)
-				return inl(ioaddr + 0xB4 + (location<<2));
-			else if (location == 17)
-				return inl(ioaddr + 0xD0);
-			else if (location >= 29 && location <= 31)
-				return inl(ioaddr + 0xD4 + ((location-29)<<2));
+				break;
 		}
-		return 0xffff;
+		spin_unlock_irqrestore(&tp->mii_lock, flags);
+		return retval & 0xffff;
 	}
 
 	/* Establish sync by sending at least 32 logic ones. */
@@ -84,36 +106,39 @@
 		outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
+
+	spin_unlock_irqrestore(&tp->mii_lock, flags);
 	return (retval>>1) & 0xffff;
 }
 
-void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int value)
+void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int val)
 {
 	struct tulip_private *tp = (struct tulip_private *)dev->priv;
 	int i;
-	int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
+	int cmd = (0x5002 << 16) | ((phy_id & 0x1f) << 23) | (location<<18) | (val & 0xffff);
 	long ioaddr = dev->base_addr;
 	long mdio_addr = ioaddr + CSR9;
+	unsigned long flags;
+
+	if (location & ~0x1f)
+		return;
+
+	if (tp->chip_id == COMET && phy_id == 30) {
+		if (comet_miireg2offset[location])
+			outl(val, ioaddr + comet_miireg2offset[location]);
+		return;
+	}
 
+	spin_lock_irqsave(&tp->mii_lock, flags);
 	if (tp->chip_id == LC82C168) {
 		int i = 1000;
 		outl(cmd, ioaddr + 0xA0);
-		do
+		do {
+			barrier();
 			if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
 				break;
-		while (--i > 0);
-		return;
-	}
-
-	if (tp->chip_id == COMET) {
-		if (phy_id != 1)
-			return;
-		if (location < 7)
-			outl(value, ioaddr + 0xB4 + (location<<2));
-		else if (location == 17)
-			outl(value, ioaddr + 0xD0);
-		else if (location >= 29 && location <= 31)
-			outl(value, ioaddr + 0xD4 + ((location-29)<<2));
+		} while (--i > 0);
+		spin_unlock_irqrestore(&tp->mii_lock, flags);
 		return;
 	}
 
@@ -139,6 +164,8 @@
 		outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
+
+	spin_unlock_irqrestore(&tp->mii_lock, flags);
 }
 
 
@@ -172,7 +199,7 @@
 			for (i = 0; i < 5; i++)
 				setup[i] = get_u16(&p[i*2 + 1]);
 
-			dev->if_port = p[0] & 15;
+			dev->if_port = p[0] & MEDIA_MASK;
 			if (tulip_media_cap[dev->if_port] & MediaAlwaysFD)
 				tp->full_duplex = 1;
 
diff -u --recursive --new-file v2.4.3/linux/drivers/net/tulip/pnic.c linux/drivers/net/tulip/pnic.c
--- v2.4.3/linux/drivers/net/tulip/pnic.c	Fri Mar  2 11:02:14 2001
+++ linux/drivers/net/tulip/pnic.c	Tue Apr  3 10:19:43 2001
@@ -2,14 +2,15 @@
 	drivers/net/tulip/pnic.c
 
 	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
-	Copyright 2000  The Linux Kernel Team
-	Written/copyright 1994-1999 by Donald Becker.
+	Copyright 2000,2001  The Linux Kernel Team
+	Written/copyright 1994-2001 by Donald Becker.
 
 	This software may be used and distributed according to the terms
 	of the GNU General Public License, incorporated herein by reference.
 
-	Please refer to Documentation/networking/tulip.txt for more
-	information on this driver.
+	Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
+	for more information on this driver, or visit the project
+	Web page at http://sourceforge.net/projects/tulip/
 
 */
 
diff -u --recursive --new-file v2.4.3/linux/drivers/net/tulip/timer.c linux/drivers/net/tulip/timer.c
--- v2.4.3/linux/drivers/net/tulip/timer.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/tulip/timer.c	Tue Apr  3 10:19:43 2001
@@ -2,14 +2,15 @@
 	drivers/net/tulip/timer.c
 
 	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
-	Copyright 2000  The Linux Kernel Team
-	Written/copyright 1994-1999 by Donald Becker.
+	Copyright 2000,2001  The Linux Kernel Team
+	Written/copyright 1994-2001 by Donald Becker.
 
 	This software may be used and distributed according to the terms
 	of the GNU General Public License, incorporated herein by reference.
 
-	Please refer to Documentation/networking/tulip.txt for more
-	information on this driver.
+	Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
+	for more information on this driver, or visit the project
+	Web page at http://sourceforge.net/projects/tulip/
 
 */
 
@@ -133,13 +134,13 @@
 				((csr12 & (1 << ((bitnum >> 1) & 7))) != 0)) {
 				if (tulip_debug > 2)
 					printk(KERN_DEBUG "%s: Link beat detected for %s.\n", dev->name,
-						   medianame[mleaf->media]);
+					       medianame[mleaf->media & MEDIA_MASK]);
 				if ((p[2] & 0x61) == 0x01)	/* Bogus Znyx board. */
 					goto actually_mii;
-				netif_carrier_on(dev);
+				/* netif_carrier_on(dev); */
 				break;
 			}
-			netif_carrier_off(dev);
+			/* netif_carrier_off(dev); */
 			if (tp->medialock)
 				break;
 	  select_next_media:
@@ -152,9 +153,9 @@
 				goto select_next_media; /* Skip FD entries. */
 			if (tulip_debug > 1)
 				printk(KERN_DEBUG "%s: No link beat on media %s,"
-					   " trying transceiver type %s.\n",
-					   dev->name, medianame[mleaf->media & 15],
-					   medianame[tp->mtable->mleaf[tp->cur_index].media]);
+				       " trying transceiver type %s.\n",
+				       dev->name, medianame[mleaf->media & MEDIA_MASK],
+				       medianame[tp->mtable->mleaf[tp->cur_index].media]);
 			tulip_select_media(dev, 0);
 			/* Restart the transmit process. */
 			tulip_restart_rxtx(tp, tp->csr6);
@@ -164,9 +165,9 @@
 		case 1:  case 3:		/* 21140, 21142 MII */
 		actually_mii:
 			if (tulip_check_duplex(dev) < 0)
-				netif_carrier_off(dev);
+				{ /* netif_carrier_off(dev); */ }
 			else
-				netif_carrier_on(dev);
+				{ /* netif_carrier_on(dev); */ }
 			next_tick = 60*HZ;
 			break;
 		case 2:					/* 21142 serial block has no link beat. */
diff -u --recursive --new-file v2.4.3/linux/drivers/net/tulip/tulip.h linux/drivers/net/tulip/tulip.h
--- v2.4.3/linux/drivers/net/tulip/tulip.h	Tue Mar  6 22:44:16 2001
+++ linux/drivers/net/tulip/tulip.h	Tue Apr  3 10:19:43 2001
@@ -1,12 +1,16 @@
 /*
 	drivers/net/tulip/tulip.h
 
-	Copyright 2000  The Linux Kernel Team
-	Written/copyright 1994-1999 by Donald Becker.
+	Copyright 2000,2001  The Linux Kernel Team
+	Written/copyright 1994-2001 by Donald Becker.
 
 	This software may be used and distributed according to the terms
 	of the GNU General Public License, incorporated herein by reference.
 
+	Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
+	for more information on this driver, or visit the project
+	Web page at http://sourceforge.net/projects/tulip/
+
 */
 
 #ifndef __NET_TULIP_H__
@@ -46,17 +50,18 @@
 
 
 enum tbl_flag {
-	HAS_MII = 1,
-	HAS_MEDIA_TABLE = 2,
-	CSR12_IN_SROM = 4,
-	ALWAYS_CHECK_MII = 8,
-	HAS_ACPI = 0x10,
-	MC_HASH_ONLY = 0x20,	/* Hash-only multicast filter. */
-	HAS_PNICNWAY = 0x80,
-	HAS_NWAY = 0x40,	/* Uses internal NWay xcvr. */
-	HAS_INTR_MITIGATION = 0x100,
-	IS_ASIX = 0x200,
-	HAS_8023X = 0x400,
+	HAS_MII			= 0x0001,
+	HAS_MEDIA_TABLE		= 0x0002,
+	CSR12_IN_SROM		= 0x0004,
+	ALWAYS_CHECK_MII	= 0x0008,
+	HAS_ACPI		= 0x0010,
+	MC_HASH_ONLY		= 0x0020, /* Hash-only multicast filter. */
+	HAS_PNICNWAY		= 0x0080,
+	HAS_NWAY		= 0x0040, /* Uses internal NWay xcvr. */
+	HAS_INTR_MITIGATION	= 0x0100,
+	IS_ASIX			= 0x0200,
+	HAS_8023X		= 0x0400,
+	COMET_MAC_ADDR		= 0x0800,
 };
 
 
@@ -139,6 +144,15 @@
 };
 
 
+enum tulip_rx_modes {
+	FullDuplex		= 0x0200,
+	AcceptBroadcast		= 0x0100,
+	AcceptAllMulticast	= 0x0080,
+	AcceptAllPhys		= 0x0040,
+	AcceptRunt		= 0x0008,
+};
+
+
 /* The Tulip Rx and Tx buffer descriptors. */
 struct tulip_rx_desc {
 	s32 status;
@@ -236,6 +250,7 @@
 #define TX_RING_SIZE	16
 #define RX_RING_SIZE	32
 
+#define MEDIA_MASK     31
 
 #define PKT_BUF_SZ		1536	/* Size of each temporary Rx buffer. */
 
@@ -251,45 +266,11 @@
 #define DESC_RING_WRAP 0x02000000
 
 
-/*  EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK	0x02	/* EEPROM shift clock. */
-#define EE_CS			0x01	/* EEPROM chip select. */
-#define EE_DATA_WRITE	0x04	/* Data from the Tulip to EEPROM. */
-#define EE_WRITE_0		0x01
-#define EE_WRITE_1		0x05
-#define EE_DATA_READ	0x08	/* Data from the EEPROM chip. */
-#define EE_ENB			(0x4800 | EE_CS)
-
-/* Delay between EEPROM clock transitions.
-   Even at 33Mhz current PCI implementations don't overrun the EEPROM clock.
-   We add a bus turn-around to insure that this remains true. */
-#define eeprom_delay()	inl(ee_addr)
-
-/* The EEPROM commands include the alway-set leading bit. */
-#define EE_READ_CMD		(6)
-
 #define EEPROM_SIZE 128 	/* 2 << EEPROM_ADDRLEN */
 
 
-/* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
-   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
-   "overclocking" issues or future 66Mhz PCI. */
-#define mdio_delay() inl(mdio_addr)
-
-/* Read and write the MII registers using software-generated serial
-   MDIO protocol.  It is just different enough from the EEPROM protocol
-   to not share code.  The maxium data clock rate is 2.5 Mhz. */
-#define MDIO_SHIFT_CLK	0x10000
-#define MDIO_DATA_WRITE0 0x00000
-#define MDIO_DATA_WRITE1 0x20000
-#define MDIO_ENB		0x00000		/* Ignore the 0x02000 databook setting. */
-#define MDIO_ENB_IN		0x40000
-#define MDIO_DATA_READ	0x80000
-
-
 #define RUN_AT(x) (jiffies + (x))
 
-
 #if defined(__i386__)			/* AKA get_unaligned() */
 #define get_u16(ptr) (*(u16 *)(ptr))
 #else
@@ -346,7 +327,9 @@
 	int flags;
 	struct net_device_stats stats;
 	struct timer_list timer;	/* Media selection timer. */
+	u32 mc_filter[2];
 	spinlock_t lock;
+	spinlock_t mii_lock;
 	unsigned int cur_rx, cur_tx;	/* The next free ring entry */
 	unsigned int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
 	unsigned int full_duplex:1;	/* Full-duplex operation requested. */
diff -u --recursive --new-file v2.4.3/linux/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c
--- v2.4.3/linux/drivers/net/tulip/tulip_core.c	Fri Mar  2 11:02:14 2001
+++ linux/drivers/net/tulip/tulip_core.c	Tue Apr  3 10:19:43 2001
@@ -2,20 +2,15 @@
 
 /*
 	Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
-	Copyright 2000  The Linux Kernel Team
-	Written/copyright 1994-1999 by Donald Becker.
+	Copyright 2000,2001  The Linux Kernel Team
+	Written/copyright 1994-2001 by Donald Becker.
 
 	This software may be used and distributed according to the terms
 	of the GNU General Public License, incorporated herein by reference.
 
-	Please read Documentation/networking/tulip.txt for more
-	information.
-
-	For this specific driver variant please use linux-kernel for
-	bug reports.
-
-	Additional information available at
-	http://cesdis.gsfc.nasa.gov/linux/drivers/tulip.html
+	Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
+	for more information on this driver, or visit the project
+	Web page at http://sourceforge.net/projects/tulip/
 
 */
 
@@ -28,7 +23,7 @@
 #include <asm/unaligned.h>
 
 static char version[] __devinitdata =
-	"Linux Tulip driver version 0.9.14 (February 20, 2001)\n";
+	"Linux Tulip driver version 0.9.14d (April 3, 2001)\n";
 
 
 /* A few user-configurable values. */
@@ -43,16 +38,19 @@
 static int mtu[MAX_UNITS];			/* Jumbo MTU for interfaces. */
 
 /*  The possible media types that can be set in options[] are: */
-const char * const medianame[] = {
+const char * const medianame[32] = {
 	"10baseT", "10base2", "AUI", "100baseTx",
-	"10baseT-FD", "100baseTx-FD", "100baseT4", "100baseFx",
-	"100baseFx-FD", "MII 10baseT", "MII 10baseT-FD", "MII",
-	"10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FD", "MII 100baseT4",
+	"10baseT-FDX", "100baseTx-FDX", "100baseT4", "100baseFx",
+	"100baseFx-FDX", "MII 10baseT", "MII 10baseT-FDX", "MII",
+	"10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FDX", "MII 100baseT4",
+	"MII 100baseFx-HDX", "MII 100baseFx-FDX", "Home-PNA 1Mbps", "Invalid-19",
+	"","","","", "","","","",  "","","","Transceiver reset",
 };
 
 /* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
 #if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
-	|| defined(__sparc_) || defined(__ia64__)
+	|| defined(__sparc_) || defined(__ia64__) \
+	|| defined(__sh__) || defined(__mips__)
 static int rx_copybreak = 1518;
 #else
 static int rx_copybreak = 100;
@@ -81,7 +79,7 @@
  * any more than that.
  */
 static int csr0 = 0x01A00000 | 0x9000;
-#elif defined(__arm__)
+#elif defined(__arm__) || defined(__sh__)
 static int csr0 = 0x01A00000 | 0x4800;
 #else
 #warning Processor architecture undefined!
@@ -162,7 +160,7 @@
 
   /* COMET */
   { "ADMtek Comet", 256, 0x0001abef,
-	MC_HASH_ONLY, comet_timer },
+	MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer },
 
   /* COMPEX9881 */
   { "Compex 9881 PMAC", 128, 0x0001ebef,
@@ -204,14 +202,15 @@
 	{ 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
 	{ 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
+	{ 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{0, }
 };
 MODULE_DEVICE_TABLE(pci, tulip_pci_tbl);
 
 
 /* A full-duplex map for media types. */
-const char tulip_media_cap[] =
-{0,0,0,16,  3,19,16,24,  27,4,7,5, 0,20,23,20 };
+const char tulip_media_cap[32] =
+{0,0,0,16,  3,19,16,24,  27,4,7,5, 0,20,23,20,  28,31,0,0, };
 u8 t21040_csr13[] = {2,0x0C,8,4,  4,0,0,0, 0,0,0,0, 4,0,0,0};
 
 /* 21041 transceiver register settings: 10-T, 10-2, AUI, 10-T, 10T-FD*/
@@ -286,6 +285,14 @@
 	if (tulip_debug > 1)
 		printk(KERN_DEBUG "%s: tulip_up(), irq==%d.\n", dev->name, dev->irq);
 
+	if (tp->chip_id == PNIC2) {
+		u32 addr_high = (dev->dev_addr[1]<<8) + (dev->dev_addr[0]<<0);
+		/* This address setting does not appear to impact chip operation?? */
+		outl((dev->dev_addr[5]<<8) + dev->dev_addr[4] +
+			(dev->dev_addr[3]<<24) + (dev->dev_addr[2]<<16),
+			ioaddr + 0xB0);
+		outl(addr_high + (addr_high<<16), ioaddr + 0xB8);
+	}
 	if (tp->flags & MC_HASH_ONLY) {
 		u32 addr_low = cpu_to_le32(get_unaligned((u32 *)dev->dev_addr));
 		u32 addr_high = cpu_to_le32(get_unaligned((u16 *)(dev->dev_addr+4)));
@@ -294,7 +301,7 @@
 			outl(addr_low,  ioaddr + CSR14);
 			outl(1, ioaddr + CSR13);
 			outl(addr_high, ioaddr + CSR14);
-		} else if (tp->chip_id == COMET) {
+		} else if (tp->flags & COMET_MAC_ADDR) {
 			outl(addr_low,  ioaddr + 0xA4);
 			outl(addr_high, ioaddr + 0xA8);
 			outl(0, ioaddr + 0xAC);
@@ -316,13 +323,13 @@
 		mapping = pci_map_single(tp->pdev, tp->setup_frame,
 					 sizeof(tp->setup_frame),
 					 PCI_DMA_TODEVICE);
-		tp->tx_buffers[0].skb = NULL;
-		tp->tx_buffers[0].mapping = mapping;
+		tp->tx_buffers[tp->cur_tx].skb = NULL;
+		tp->tx_buffers[tp->cur_tx].mapping = mapping;
 
 		/* Put the setup frame on the Tx list. */
-		tp->tx_ring[0].length = cpu_to_le32(0x08000000 | 192);
-		tp->tx_ring[0].buffer1 = cpu_to_le32(mapping);
-		tp->tx_ring[0].status = cpu_to_le32(DescOwned);
+		tp->tx_ring[tp->cur_tx].length = cpu_to_le32(0x08000000 | 192);
+		tp->tx_ring[tp->cur_tx].buffer1 = cpu_to_le32(mapping);
+		tp->tx_ring[tp->cur_tx].status = cpu_to_le32(DescOwned);
 
 		tp->cur_tx++;
 	}
@@ -349,7 +356,7 @@
 			}
 	}
 	if ((tp->mtable->defaultmedia & 0x0800) == 0) {
-		int looking_for = tp->mtable->defaultmedia & 15;
+		int looking_for = tp->mtable->defaultmedia & MEDIA_MASK;
 		for (i = 0; i < tp->mtable->leafcount; i++)
 			if (tp->mtable->mleaf[i].media == looking_for) {
 				printk(KERN_INFO "%s: Using EEPROM-set media %s.\n",
@@ -418,7 +425,9 @@
 		outl(0x0000, ioaddr + CSR14);
 		outl(0x0008, ioaddr + CSR15);
 	} else if (tp->chip_id == COMET) {
-		dev->if_port = 0;
+		/* Enable automatic Tx underrun recovery. */
+		outl(inl(ioaddr + 0x88) | 1, ioaddr + 0x88);
+		dev->if_port = tp->mii_cnt ? 11 : 0;
 		tp->csr6 = 0x00040000;
 	} else if (tp->chip_id == AX88140) {
 		tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100;
@@ -789,16 +798,16 @@
 
 
 /* Provide ioctl() calls to examine the MII xcvr state. */
-static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+	struct tulip_private *tp = dev->priv;
 	long ioaddr = dev->base_addr;
-	u16 *data = (u16 *)&rq->ifr_data;
+	u16 *data = (u16 *) & rq->ifr_data;
 	int phy = tp->phys[0] & 0x1f;
-	long flags;
+	unsigned int regnum = data[1];
 
-	switch(cmd) {
-	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
+	switch (cmd) {
+	case SIOCDEVPRIVATE:	/* Get the address of the PHY in use. */
 		if (tp->mii_cnt)
 			data[0] = phy;
 		else if (tp->flags & HAS_NWAY)
@@ -807,42 +816,64 @@
 			data[0] = 1;
 		else
 			return -ENODEV;
-	case SIOCDEVPRIVATE+1:		/* Read the specified MII register. */
-		if (data[0] == 32  &&  (tp->flags & HAS_NWAY)) {
-			int csr12 = inl(ioaddr + CSR12);
-			int csr14 = inl(ioaddr + CSR14);
-			switch (data[1]) {
-			case 0: {
-				data[3] = (csr14<<5) & 0x1000;
-				break; }
+	case SIOCDEVPRIVATE + 1:	/* Read the specified MII register. */
+		if (data[0] == 32 && (tp->flags & HAS_NWAY)) {
+			int csr12 = inl (ioaddr + CSR12);
+			int csr14 = inl (ioaddr + CSR14);
+			switch (regnum) {
+			case 0:
+				data[3] = (csr14 << 5) & 0x1000;
+				break;
 			case 1:
-				data[3] = 0x7848 + ((csr12&0x7000) == 0x5000 ? 0x20 : 0)
-					+ (csr12&0x06 ? 0x04 : 0);
+				data[3] =
+				  0x7848 +
+				  ((csr12 & 0x7000) == 0x5000 ? 0x20 : 0) +
+				  (csr12 & 0x06 ? 0x04 : 0);
 				break;
-			case 4: {
-				data[3] = ((csr14>>9)&0x07C0) +
-					((inl(ioaddr + CSR6)>>3)&0x0040) + ((csr14>>1)&0x20) + 1;
+			case 4:
+				data[3] =
+				  ((csr14 >> 9) & 0x07C0) +
+				  ((inl (ioaddr + CSR6) >> 3) & 0x0040) +
+				  ((csr14 >> 1) & 0x20) + 1;
+				break;
+			case 5:
+				data[3] = csr12 >> 16;
+				break;
+			default:
+				data[3] = 0;
 				break;
-			}
-			case 5: data[3] = csr12 >> 16; break;
-			default: data[3] = 0; break;
 			}
 		} else {
-			spin_lock_irqsave (&tp->lock, flags);
-			data[3] = tulip_mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f);
-			spin_unlock_irqrestore (&tp->lock, flags);
+			data[3] = tulip_mdio_read (dev, data[0] & 0x1f, regnum);
 		}
 		return 0;
-	case SIOCDEVPRIVATE+2:		/* Write the specified MII register */
-		if (!capable(CAP_NET_ADMIN))
+	case SIOCDEVPRIVATE + 2:	/* Write the specified MII register */
+		if (!capable (CAP_NET_ADMIN))
 			return -EPERM;
-		if (data[0] == 32  &&  (tp->flags & HAS_NWAY)) {
-			if (data[1] == 5)
+		if (regnum & ~0x1f)
+			return -EINVAL;
+		if (data[0] == phy) {
+			u16 value = data[2];
+			switch (regnum) {
+			case 0:	/* Check for autonegotiation on or reset. */
+				tp->full_duplex_lock = (value & 0x9000) ? 0 : 1;
+				if (tp->full_duplex_lock)
+					tp->full_duplex = (value & 0x0100) ? 1 : 0;
+				break;
+			case 4:
 				tp->to_advertise = data[2];
+				break;
+			}
+		}
+		if (data[0] == 32 && (tp->flags & HAS_NWAY)) {
+			u16 value = data[2];
+			if (regnum == 0) {
+				if ((value & 0x1200) == 0x1200)
+					t21142_start_nway (dev);
+			} else if (regnum == 4)
+				tp->to_advertise = value;
 		} else {
-			spin_lock_irqsave (&tp->lock, flags);
-			tulip_mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
-			spin_unlock_irqrestore(&tp->lock, flags);
+			tulip_mdio_write (dev, data[0] & 0x1f, regnum, data[2]);
 		}
 		return 0;
 	default:
@@ -967,38 +998,56 @@
 
 	tp->csr6 &= ~0x00D5;
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
-		tp->csr6 |= 0x00C0;
-		csr6 |= 0x00C0;
+		tp->csr6 |= AcceptAllMulticast | AcceptAllPhys;
+		csr6 |= AcceptAllMulticast | AcceptAllPhys;
 		/* Unconditionally log net taps. */
 		printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name);
 	} else if ((dev->mc_count > 1000)  ||  (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to filter well -- accept all multicasts. */
-		tp->csr6 |= 0x0080;
-		csr6 |= 0x0080;
+		tp->csr6 |= AcceptAllMulticast;
+		csr6 |= AcceptAllMulticast;
 	} else	if (tp->flags & MC_HASH_ONLY) {
 		/* Some work-alikes have only a 64-entry hash filter table. */
 		/* Should verify correctness on big-endian/__powerpc__ */
 		struct dev_mc_list *mclist;
 		int i;
-		u32 mc_filter[2];		 /* Multicast hash filter */
 		if (dev->mc_count > 64) {		/* Arbitrary non-effective limit. */
-			tp->csr6 |= 0x0080;
-			csr6 |= 0x0080;
+			tp->csr6 |= AcceptAllMulticast;
+			csr6 |= AcceptAllMulticast;
 		} else {
-			mc_filter[1] = mc_filter[0] = 0;
+			u32 mc_filter[2] = {0, 0};		 /* Multicast hash filter */
+			int filterbit;
 			for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-				 i++, mclist = mclist->next)
-				set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26, mc_filter);
-
-			if (tp->chip_id == AX88140) {
+				 i++, mclist = mclist->next) {
+				if (tp->flags & COMET_MAC_ADDR)
+					filterbit = ether_crc_le(ETH_ALEN, mclist->dmi_addr);
+				else
+					filterbit = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+				filterbit &= 0x3f;
+				set_bit(filterbit, mc_filter);
+				if (tulip_debug > 2) {
+					printk(KERN_INFO "%s: Added filter for %2.2x:%2.2x:%2.2x:"
+						   "%2.2x:%2.2x:%2.2x  %8.8x bit %d.\n", dev->name,
+						   mclist->dmi_addr[0], mclist->dmi_addr[1],
+						   mclist->dmi_addr[2], mclist->dmi_addr[3],
+						   mclist->dmi_addr[4], mclist->dmi_addr[5],
+						   ether_crc(ETH_ALEN, mclist->dmi_addr), filterbit);
+				}
+			}
+			if (mc_filter[0] == tp->mc_filter[0]  &&
+				mc_filter[1] == tp->mc_filter[1])
+				;				/* No change. */
+			else if (tp->flags & IS_ASIX) {
 				outl(2, ioaddr + CSR13);
 				outl(mc_filter[0], ioaddr + CSR14);
 				outl(3, ioaddr + CSR13);
 				outl(mc_filter[1], ioaddr + CSR14);
-			} else if (tp->chip_id == COMET) { /* Has a simple hash filter. */
+			} else if (tp->flags & COMET_MAC_ADDR) {
 				outl(mc_filter[0], ioaddr + 0xAC);
 				outl(mc_filter[1], ioaddr + 0xB0);
 			}
+			tp->mc_filter[0] = mc_filter[0];
+			tp->mc_filter[1] = mc_filter[1];
 		}
 	} else {
 		unsigned long flags;
@@ -1204,22 +1253,12 @@
 	tp->revision = chip_rev;
 	tp->csr0 = csr0;
 	spin_lock_init(&tp->lock);
+	spin_lock_init(&tp->mii_lock);
 
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
 	pci_set_drvdata(pdev, dev);
 
-#ifdef TULIP_FULL_DUPLEX
-	tp->full_duplex = 1;
-	tp->full_duplex_lock = 1;
-#endif
-#ifdef TULIP_DEFAULT_MEDIA
-	tp->default_port = TULIP_DEFAULT_MEDIA;
-#endif
-#ifdef TULIP_NO_MEDIA_SWITCH
-	tp->medialock = 1;
-#endif
-
 	printk(KERN_INFO "%s: %s rev %d at %#3lx,",
 		   dev->name, tulip_tbl[chip_idx].chip_name, chip_rev, ioaddr);
 
@@ -1332,15 +1371,18 @@
 
 	/* The lower four bits are the media type. */
 	if (board_idx >= 0  &&  board_idx < MAX_UNITS) {
-		tp->default_port = options[board_idx] & 15;
-		if ((options[board_idx] & 0x90) || full_duplex[board_idx] > 0)
+		if (options[board_idx] & MEDIA_MASK)
+			tp->default_port = options[board_idx] & MEDIA_MASK;
+		if ((options[board_idx] & FullDuplex) || full_duplex[board_idx] > 0)
 			tp->full_duplex = 1;
 		if (mtu[board_idx] > 0)
 			dev->mtu = mtu[board_idx];
 	}
-	if (dev->mem_start)
-		tp->default_port = dev->mem_start;
+	if (dev->mem_start & MEDIA_MASK)
+		tp->default_port = dev->mem_start & MEDIA_MASK;
 	if (tp->default_port) {
+		printk(KERN_INFO "%s: Transceiver selection forced to %s.\n",
+		       dev->name, medianame[tp->default_port & MEDIA_MASK]);
 		tp->medialock = 1;
 		if (tulip_media_cap[tp->default_port] & MediaAlwaysFD)
 			tp->full_duplex = 1;
@@ -1365,7 +1407,7 @@
 	if ((tp->flags & ALWAYS_CHECK_MII) ||
 		(tp->mtable  &&  tp->mtable->has_mii) ||
 		( ! tp->mtable  &&  (tp->flags & HAS_MII))) {
-		int phy, phy_idx;
+		int phyn, phy_idx = 0;
 		if (tp->mtable  &&  tp->mtable->has_mii) {
 			for (i = 0; i < tp->mtable->leafcount; i++)
 				if (tp->mtable->mleaf[i].media == 11) {
@@ -1379,8 +1421,8 @@
 		/* Find the connected MII xcvrs.
 		   Doing this in open() would allow detecting external xcvrs later,
 		   but takes much time. */
-		for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys);
-			 phy++) {
+		for (phyn = 1; phyn <= 32 && phy_idx < sizeof(tp->phys); phyn++) {
+			int phy = phyn & 0x1f;
 			int mii_status = tulip_mdio_read(dev, phy, 1);
 			if ((mii_status & 0x8301) == 0x8001 ||
 				((mii_status & 0x8000) == 0  && (mii_status & 0x7800) != 0)) {
diff -u --recursive --new-file v2.4.3/linux/drivers/pci/setup-res.c linux/drivers/pci/setup-res.c
--- v2.4.3/linux/drivers/pci/setup-res.c	Mon Dec 11 13:46:26 2000
+++ linux/drivers/pci/setup-res.c	Fri Apr  6 10:51:19 2001
@@ -163,6 +163,10 @@
 				size = ln->res->end - ln->res->start;
 			if (r_size > size) {
 				tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+				if (!tmp) {
+					printk("pdev_sort_resources(): kmalloc() failed!\n");
+					continue;
+				}
 				tmp->next = ln;
 				tmp->res = r;
 				tmp->dev = dev;
diff -u --recursive --new-file v2.4.3/linux/drivers/pcmcia/pci_socket.c linux/drivers/pcmcia/pci_socket.c
--- v2.4.3/linux/drivers/pcmcia/pci_socket.c	Thu Nov 16 16:38:16 2000
+++ linux/drivers/pcmcia/pci_socket.c	Fri Apr  6 10:51:19 2001
@@ -172,13 +172,20 @@
 static int __devinit add_pci_socket(int nr, struct pci_dev *dev, struct pci_socket_ops *ops)
 {
 	pci_socket_t *socket = nr + pci_socket_array;
-
+	int err;
+	
 	memset(socket, 0, sizeof(*socket));
 	socket->dev = dev;
 	socket->op = ops;
 	dev->driver_data = socket;
 	spin_lock_init(&socket->event_lock);
-	return socket->op->open(socket);
+	err = socket->op->open(socket);
+	if(err)
+	{
+		socket->dev = NULL;
+		dev->driver_data = NULL;
+	}
+	return err;
 }
 
 void cardbus_register(pci_socket_t *socket)
@@ -195,8 +202,7 @@
 
 	for (s = 0; s < MAX_SOCKETS; s++) {
 		if (pci_socket_array [s].dev == 0) {
-			add_pci_socket (s, dev, &yenta_operations);
-			return 0;
+			return add_pci_socket (s, dev, &yenta_operations);
 		}
 	}
 	return -ENODEV;
diff -u --recursive --new-file v2.4.3/linux/drivers/pcmcia/yenta.c linux/drivers/pcmcia/yenta.c
--- v2.4.3/linux/drivers/pcmcia/yenta.c	Thu Nov 16 18:25:16 2000
+++ linux/drivers/pcmcia/yenta.c	Fri Apr  6 10:51:19 2001
@@ -755,6 +755,9 @@
  */
 static void yenta_close(pci_socket_t *sock)
 {
+	/* Disable all events so we don't die in an IRQ storm */
+	cb_writel(sock, CB_SOCKET_MASK, 0x0);
+
 	if (sock->cb_irq)
 		free_irq(sock->cb_irq, sock);
 	else
diff -u --recursive --new-file v2.4.3/linux/drivers/scsi/advansys.c linux/drivers/scsi/advansys.c
--- v2.4.3/linux/drivers/scsi/advansys.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/scsi/advansys.c	Fri Apr  6 10:51:19 2001
@@ -1,10 +1,10 @@
-/* $Id: advansys.c,v 1.69 1999/11/29 18:37:53 bobf Exp bobf $ */
-#define ASC_VERSION "3.2M"    /* AdvanSys Driver Version */
+#define ASC_VERSION "3.3G"    /* AdvanSys Driver Version */
 
 /*
  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
- * 
- * Copyright (c) 1995-1999 Advanced System Products, Inc.
+ *
+ * Copyright (c) 1995-2000 Advanced System Products, Inc.
+ * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
  * All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -12,52 +12,51 @@
  * code retain the above copyright notice and this comment without
  * modification.
  *
+ * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
+ * changed its name to ConnectCom Solutions, Inc.
+ *
  * There is an AdvanSys Linux WWW page at:
+ *  http://www.connectcom.net/downloads/software/os/linux.html
  *  http://www.advansys.com/linux.html
  *
- * The latest version of the AdvanSys driver is available at:
+ * The latest released version of the AdvanSys driver is available at:
  *  ftp://ftp.advansys.com/pub/linux/linux.tgz
+ *  ftp://ftp.connectcom.net/pub/linux/linux.tgz
  *
  * Please send questions, comments, bug reports to:
- *  linux@advansys.com
+ *  support@connectcom.net
  */
 
 /*
 
   Documentation for the AdvanSys Driver
 
-  A. Linux Kernel Testing
+  A. Linux Kernels Supported by this Driver
   B. Adapters Supported by this Driver
-  C. Linux v1.2.X - Directions for Adding the AdvanSys Driver
-  D. Linux v1.3.1 - v1.3.57 - Directions for Adding the AdvanSys Driver
-  E. Linux v1.3.58 and Newer - Upgrading the AdvanSys Driver
-  F. Source Comments
-  G. Driver Compile Time Options and Debugging
-  H. Driver LILO Option
-  I. Release History
-  J. Known Problems/Fix List
-  K. Credits
-  L. AdvanSys Contact Information
-
-  A. Linux Kernel Testing
-
-     This driver has been tested in the following Linux kernels: v1.2.13,
-     v1.3.57, v2.0.38, v2.2.13, and v2.3.28. These kernel versions are major
-     releases of Linux or the latest Linux kernel versions available when
-     this version of the driver was released. The driver should also work
-     in earlier versions of the Linux kernel. Beginning with v1.3.58 the
-     AdvanSys driver is included with all Linux kernels. Please refer to
-     sections C, D, and E for instructions on adding or upgrading the
-     AdvanSys driver. The driver is supported for x86 and alpha systems.
+  C. Linux source files modified by AdvanSys Driver
+  D. Source Comments
+  E. Driver Compile Time Options and Debugging
+  F. Driver LILO Option
+  G. Tests to run before releasing new driver
+  H. Release History
+  I. Known Problems/Fix List
+  J. Credits (Chronological Order)
+  K. ConnectCom (AdvanSys) Contact Information
+
+  A. Linux Kernels Supported by this Driver
+
+     This driver has been tested in the following Linux kernels: v2.2.18
+     v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
+     alpha, and PowerPC platforms.
 
   B. Adapters Supported by this Driver
- 
+
      AdvanSys (Advanced System Products, Inc.) manufactures the following
      RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
      (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
      buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
      transfer) SCSI Host Adapters for the PCI bus.
-     
+
      The CDB counts below indicate the number of SCSI CDB (Command
      Descriptor Block) requests that can be stored in the RISC chip
      cache and board LRAM. A CDB is a single SCSI command. The driver
@@ -65,6 +64,9 @@
      adapter detected. The number of CDBs used by the driver can be
      lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
 
+     Laptop Products:
+        ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
+
      Connectivity Products:
         ABP510/5150 - Bus-Master ISA (240 CDB)
         ABP5140 - Bus-Master ISA PnP (16 CDB)
@@ -80,7 +82,7 @@
         ABP930UA - Bus-Master PCI Ultra (16 CDB)
         ABP960 - Bus-Master PCI MAC/PC (16 CDB)
         ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
-     
+
      Single Channel Products:
         ABP542 - Bus-Master ISA with floppy (240 CDB)
         ABP742 - Bus-Master EISA (240 CDB)
@@ -94,7 +96,7 @@
         ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
         ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
         ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
-     
+
      Multi-Channel Products:
         ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
         ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
@@ -104,37 +106,33 @@
         ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
         ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
         ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
-     
-  C. Linux v1.2.X - Directions for Adding the AdvanSys Driver
+        ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
+
+  C. Linux source files modified by AdvanSys Driver
+
+     This section for historical purposes documents the changes
+     originally made to the Linux kernel source to add the advansys
+     driver. As Linux has changed some of these files have also
+     been modified.
+
+     1. linux/arch/i386/config.in:
 
-     These directions apply to v1.2.13. For versions that follow v1.2.13.
-     but precede v1.3.57 some of the changes for Linux v1.3.X listed
-     below may need to be modified or included. A patch is available
-     for v1.2.13 from the AdvanSys WWW and FTP sites.
- 
-     There are two source files: advansys.h and advansys.c. Copy
-     both of these files to the directory /usr/src/linux/drivers/scsi.
-    
-     1. Add the following line to /usr/src/linux/arch/i386/config.in
-        after "comment 'SCSI low-level drivers'":
-    
           bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
-    
-     2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
-        after "#include "hosts.h"":
-    
+
+     2. linux/drivers/scsi/hosts.c:
+
           #ifdef CONFIG_SCSI_ADVANSYS
           #include "advansys.h"
           #endif
-    
+
         and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
-    
+
           #ifdef CONFIG_SCSI_ADVANSYS
           ADVANSYS,
           #endif
-    
-     3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
-    
+
+     3. linux/drivers/scsi/Makefile:
+
           ifdef CONFIG_SCSI_ADVANSYS
           SCSI_SRCS := $(SCSI_SRCS) advansys.c
           SCSI_OBJS := $(SCSI_OBJS) advansys.o
@@ -142,12 +140,7 @@
           SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
           endif
 
-     4. (Optional) If you would like to enable the LILO command line
-        and /etc/lilo.conf 'advansys' option, make the following changes.
-        This option can be used to disable I/O port scanning or to limit
-        I/O port scanning to specific addresses. Refer to the 'Driver
-        LILO Option' section below. Add the following lines to
-        /usr/src/linux/init/main.c in the prototype section:
+     4. linux/init/main.c:
 
           extern void advansys_setup(char *str, int *ints);
 
@@ -157,118 +150,19 @@
              { "advansys=", advansys_setup },
           #endif
 
-     5. If you have the HP 4020i CD-R driver and Linux v1.2.X you should
-        add a fix to the CD-ROM target driver. This fix will allow
-        you to mount CDs with the iso9660 file system. Linux v1.3.X
-        already has this fix. In the file /usr/src/linux/drivers/scsi/sr.c
-        and function get_sectorsize() after the line:
-
-        if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
-
-        add the following line:
-
-        if(scsi_CDs[i].sector_size == 2340) scsi_CDs[i].sector_size = 2048;
-
-     6. In the directory /usr/src/linux run 'make config' to configure
-        the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
-        make the kernel. If the AdvanSys driver is not configured, then
-        a loadable module can be built by running 'make modules' and
-        'make modules_install'. Use 'insmod' and 'rmmod' to install
-        and remove advansys.o.
- 
-  D. Linux v1.3.1 - v1.3.57 - Directions for Adding the AdvanSys Driver
-
-     These directions apply to v1.3.57. For versions that precede v1.3.57
-     some of these changes may need to be modified or eliminated. A patch
-     is available for v1.3.57 from the AdvanSys WWW and FTP sites.
-     Beginning with v1.3.58 this driver is included with the Linux
-     distribution eliminating the need for making any changes.
-
-     There are two source files: advansys.h and advansys.c. Copy
-     both of these files to the directory /usr/src/linux/drivers/scsi.
-   
-     1. Add the following line to /usr/src/linux/drivers/scsi/Config.in
-        after "comment 'SCSI low-level drivers'":
-   
-          dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
-   
-     2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
-        after "#include "hosts.h"":
-   
-          #ifdef CONFIG_SCSI_ADVANSYS
-          #include "advansys.h"
-          #endif
-   
-        and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
-   
-          #ifdef CONFIG_SCSI_ADVANSYS
-          ADVANSYS,
-          #endif
-   
-     3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
-   
-          ifeq ($(CONFIG_SCSI_ADVANSYS),y)
-          L_OBJS += advansys.o
-          else
-            ifeq ($(CONFIG_SCSI_ADVANSYS),m)
-            M_OBJS += advansys.o
-            endif
-          endif
-   
-     4. Add the following line to /usr/src/linux/include/linux/proc_fs.h
-        in the enum scsi_directory_inos array:
-   
-          PROC_SCSI_ADVANSYS,
-   
-     5. (Optional) If you would like to enable the LILO command line
-        and /etc/lilo.conf 'advansys' option, make the following changes.
-        This option can be used to disable I/O port scanning or to limit
-        I/O port scanning to specific addresses. Refer to the 'Driver
-        LILO Option' section below. Add the following lines to
-        /usr/src/linux/init/main.c in the prototype section:
-   
-          extern void advansys_setup(char *str, int *ints);
-   
-        and add the following lines to the bootsetups[] array.
-   
-          #ifdef CONFIG_SCSI_ADVANSYS
-             { "advansys=", advansys_setup },
-          #endif
-   
-     6. In the directory /usr/src/linux run 'make config' to configure
-        the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
-        make the kernel. If the AdvanSys driver is not configured, then
-        a loadable module can be built by running 'make modules' and
-        'make modules_install'. Use 'insmod' and 'rmmod' to install
-        and remove advansys.o.
-
-  E. Linux v1.3.58 and Newer - Upgrading the AdvanSys Driver
-
-     To upgrade the AdvanSys driver in a Linux v1.3.58 and newer
-     kernel, first check the version of the current driver. The
-     version is defined by the manifest constant ASC_VERSION at
-     the beginning of advansys.c. The new driver should have a
-     ASC_VERSION value greater than the current version. To install
-     the new driver rename advansys.c and advansys.h in the Linux
-     kernel source tree drivers/scsi directory to different names
-     or save them to a different directory in case you want to revert
-     to the old version of the driver. After the old driver is saved
-     copy the new advansys.c and advansys.h to drivers/scsi, rebuild
-     the kernel, and install the new kernel. No other changes are needed.
+  D. Source Comments
 
-  F. Source Comments
- 
      1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
- 
+
      2. This driver should be maintained in multiple files. But to make
         it easier to include with Linux and to follow Linux conventions,
         the whole driver is maintained in the source files advansys.h and
         advansys.c. In this file logical sections of the driver begin with
         a comment that contains '---'. The following are the logical sections
         of the driver below.
- 
+
            --- Linux Version
-           --- Linux Include Files 
+           --- Linux Include File
            --- Driver Options
            --- Debugging Header
            --- Asc Library Constants and Macros
@@ -285,27 +179,27 @@
            --- Tracing and Debugging Functions
            --- Asc Library Functions
            --- Adv Library Functions
- 
+
      3. The string 'XXX' is used to flag code that needs to be re-written
         or that contains a problem that needs to be addressed.
- 
+
      4. I have stripped comments from and reformatted the source for the
         Asc Library and Adv Library to reduce the size of this file. This
         source can be found under the following headings. The Asc Library
         is used to support Narrow Boards. The Adv Library is used to
         support Wide Boards.
- 
+
            --- Asc Library Constants and Macros
            --- Adv Library Constants and Macros
            --- Asc Library Functions
            --- Adv Library Functions
- 
-  G. Driver Compile Time Options and Debugging
- 
+
+  E. Driver Compile Time Options and Debugging
+
      In this source file the following constants can be defined. They are
      defined in the source below. Both of these options are enabled by
      default.
- 
+
      1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
 
         Enabling this option adds assertion logic statements to the
@@ -325,11 +219,11 @@
         the kernel name space. This option is very useful for debugging
         the driver, but it will add to the size of the driver execution
         image and add overhead to the execution of the driver.
- 
+
         The amount of debugging output can be controlled with the global
         variable 'asc_dbglvl'. The higher the number the more output. By
         default the debug level is 0.
-        
+
         If the driver is loaded at boot time and the LILO Driver Option
         is included in the system, the debug level can be changed by
         specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
@@ -343,28 +237,44 @@
         If the driver is built as a loadable module this variable can be
         defined when the driver is loaded. The following insmod command
         will set the debug level to one.
-  
+
            insmod advansys.o asc_dbglvl=1
- 
+
         Debugging Message Levels:
            0: Errors Only
            1: High-Level Tracing
            2-N: Verbose Tracing
- 
-        I don't know the approved way for turning on printk()s to the
-        console. Here's a program I use to do this. Debug output is
-        logged in /var/adm/messages.
- 
+
+        To enable debug output to console, please make sure that:
+
+        a. System and kernel logging is enabled (syslogd, klogd running).
+        b. Kernel messages are routed to console output. Check
+           /etc/syslog.conf for an entry similar to this:
+
+                kern.*                  /dev/console
+
+        c. klogd is started with the appropriate -c parameter
+           (e.g. klogd -c 8)
+
+        This will cause printk() messages to be be displayed on the
+        current console. Refer to the klogd(8) and syslogd(8) man pages
+        for details.
+
+        Alternatively you can enable printk() to console with this
+        program. However, this is not the 'official' way to do this.
+        Debug output is logged in /var/log/messages.
+
           main()
           {
                   syscall(103, 7, 0, 0);
           }
- 
-        I found that increasing LOG_BUF_LEN to 40960 in kernel/printk.c
-        prevents most level 1 debug messages from being lost.
+
+        Increasing LOG_BUF_LEN in kernel/printk.c to something like
+        40960 allows more debug messages to be buffered in the kernel
+        and written to the console or log file.
 
      3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
- 
+
         Enabling this option adds statistics collection and display
         through /proc to the driver. The information is useful for
         monitoring driver and device performance. It will add to the
@@ -387,8 +297,8 @@
         When ADVANSYS_STATS is not defined the AdvanSys /proc files only
         contain adapter and device configuration information.
 
-  H. Driver LILO Option
- 
+  F. Driver LILO Option
+
      If init/main.c is modified as described in the 'Directions for Adding
      the AdvanSys Driver to Linux' section (B.4.) above, the driver will
      recognize the 'advansys' LILO command line and /etc/lilo.conf option.
@@ -418,9 +328,24 @@
      the 'Driver Compile Time Options and Debugging' section above for
      more information.
 
-  I. Release History
+  G. Tests to run before releasing new driver
+
+     1. In the supported kernels verify there are no warning or compile
+        errors when the kernel is built as both a driver and as a module
+        and with the following options:
+
+        ADVANSYS_DEBUG - enabled and disabled
+        CONFIG_SMP - enabled and disabled
+        CONFIG_PROC_FS - enabled and disabled
+
+     2. Run tests on an x86, alpha, and PowerPC with at least one narrow
+        card and one wide card attached to a hard disk and CD-ROM drive:
+        fdisk, mkfs, fsck, bonnie, copy/compare test from the
+        CD-ROM to the hard drive.
+
+  H. Release History
 
-     BETA-1.0 (12/23/95): 
+     BETA-1.0 (12/23/95):
          First Release
 
      BETA-1.1 (12/28/95):
@@ -454,7 +379,7 @@
          4. Remove reset request loop problem from the "Known Problems or
             Issues" section. This problem was isolated and fixed in the
             mid-level SCSI driver.
-        
+
      1.5 (8/8/96):
          1. Add support for ABP-940U (PCI Ultra) adapter.
          2. Add support for IRQ sharing by setting the SA_SHIRQ flag for
@@ -677,7 +602,75 @@
          1. Really fix bug in adv_get_sglist().
          2. Incorporate v2.3.29 changes into driver.
 
-  J. Known Problems/Fix List (XXX)
+     3.2N (4/1/00):
+         1. Add CONFIG_ISA ifdef code.
+         2. Include advansys_interrupts_enabled name change patch.
+         3. For >= v2.3.28 use new SCSI error handling with new function
+            advansys_eh_bus_reset(). Don't include an abort function
+            because of base library limitations.
+         4. For >= v2.3.28 use per board lock instead of io_request_lock.
+         5. For >= v2.3.28 eliminate advansys_command() and
+            advansys_command_done().
+         6. Add some changes for PowerPC (Big Endian) support, but it isn't
+            working yet.
+         7. Fix "nonexistent resource free" problem that occurred on a module
+            unload for boards with an I/O space >= 255. The 'n_io_port' field
+            is only one byte and can not be used to hold an ioport length more
+            than 255.
+
+     3.3A (4/4/00):
+         1. Update to Adv Library 5.8.
+         2. For wide cards add support for CDBs up to 16 bytes.
+         3. Eliminate warnings when CONFIG_PROC_FS is not defined.
+
+     3.3B (5/1/00):
+         1. Support for PowerPC (Big Endian) wide cards. Narrow cards
+            still need work.
+         2. Change bitfields to shift and mask access for endian
+            portability.
+
+     3.3C (10/13/00):
+         1. Update for latest 2.4 kernel.
+         2. Test ABP-480 CardBus support in 2.4 kernel - works!
+         3. Update to Asc Library S123.
+         4. Update to Adv Library 5.12.
+
+     3.3D (11/22/00):
+         1. Update for latest 2.4 kernel.
+         2. Create patches for 2.2 and 2.4 kernels.
+
+     3.3E (1/9/01):
+         1. Now that 2.4 is released remove ifdef code for kernel versions
+            less than 2.2. The driver is now only supported in kernels 2.2,
+            2.4, and greater.
+         2. Add code to release and acquire the io_request_lock in
+            the driver entrypoint functions: advansys_detect and
+            advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
+            still holds the io_request_lock on entry to SCSI low-level drivers.
+            This was supposed to be removed before 2.4 was released but never
+            happened. When the mid-level SCSI driver is changed all references
+            to the io_request_lock should be removed from the driver.
+         3. Simplify error handling by removing advansys_abort(),
+            AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
+            now handled by resetting the SCSI bus and fully re-initializing
+            the chip. This simple method of error recovery has proven to work
+            most reliably after attempts at different methods. Also now only
+            support the "new" error handling method and remove the obsolete
+            error handling interface.
+         4. Fix debug build errors.
+
+     3.3F (1/24/01):
+         1. Merge with ConnectCom version from Andy Kellner which
+            updates Adv Library to 5.14.
+         2. Make PowerPC (Big Endian) work for narrow cards and
+            fix problems writing EEPROM for wide cards.
+         3. Remove interrupts_enabled assertion function.
+
+     3.3G (2/16/01):
+         1. Return an error from narrow boards if passed a 16 byte
+            CDB. The wide board can already handle 16 byte CDBs.
+
+  I. Known Problems/Fix List (XXX)
 
      1. Need to add memory mapping workaround. Test the memory mapping.
         If it doesn't work revert to I/O port access. Can a test be done
@@ -687,12 +680,12 @@
         has not occurred then print a message and run in polled mode.
      3. Allow bus type scanning order to be changed.
      4. Need to add support for target mode commands, cf. CAM XPT.
-     5  Need to add support for new Linux SCSI error handling method.
-     6. Need to fix sti/cli code in Asc Library.
-     7. Need to fix abort code in Adv Library.
-     8. Reduce io_request_lock hold time.
 
-  K. Credits
+  J. Credits (Chronological Order)
+
+     Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
+     and maintained it up to 3.3F. He continues to answer questions
+     and help maintain the driver.
 
      Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
      basis for the Linux v1.3.X changes which were included in the
@@ -712,22 +705,47 @@
      support in the 3.1A driver.
 
      Doug Gilbert <dgilbert@interlog.com> has made changes and
-     suggestions to improve the driver and done testing.
+     suggestions to improve the driver and done a lot of testing.
 
      Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
      in 3.2K.
 
-  L. AdvanSys Contact Information
- 
-     Mail:                   Advanced System Products, Inc.
+     Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
+     patch and helped with PowerPC wide and narrow board support.
+
+     Philip Blundell <philip.blundell@pobox.com> provided an
+     advansys_interrupts_enabled patch.
+
+     Dave Jones <dave@denial.force9.co.uk> reported the compiler
+     warnings generated when CONFIG_PROC_FS was not defined in
+     the 3.2M driver.
+
+     Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
+     problems) for wide cards.
+
+     Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
+     card error handling.
+
+     Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
+     board support and fixed a bug in AscGetEEPConfig().
+
+     Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
+     save_flags/restore_flags changes.
+
+     Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
+     driver development for ConnectCom (Version > 3.3F).
+
+  K. ConnectCom (AdvanSys) Contact Information
+
+     Mail:                   ConnectCom Solutions, Inc.
                              1150 Ringwood Court
                              San Jose, CA 95131
      Operator/Sales:         1-408-383-9400
      FAX:                    1-408-383-9612
      Tech Support:           1-408-467-2930
-     Tech Support E-Mail:    support@advansys.com
-     FTP Site:               ftp.advansys.com (login: anonymous)
-     Web Site:               http://www.advansys.com
+     Tech Support E-Mail:    linux@connectcom.net
+     FTP Site:               ftp.connectcom.net (login: anonymous)
+     Web Site:               http://www.connectcom.net
 
 */
 
@@ -736,78 +754,62 @@
  * --- Linux Version
  */
 
-/* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
-#define ASC_LINUX_VERSION(V, P, S)    (((V) * 65536) + ((P) * 256) + (S))
-
 #ifndef LINUX_VERSION_CODE
 #include <linux/version.h>
 #endif /* LINUX_VERSION_CODE */
 
+/* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
+#define ASC_LINUX_VERSION(V, P, S)    (((V) * 65536) + ((P) * 256) + (S))
+#define ASC_LINUX_KERNEL22 (LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
+#define ASC_LINUX_KERNEL24 (LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,4,0))
+
+/* Driver supported only in version 2.2 and version >= 2.4. */
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,2,0) || \
+    (LINUX_VERSION_CODE > ASC_LINUX_VERSION(2,3,0) && \
+     LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
+#error "AdvanSys driver supported only in 2.2 and 2.4 or greater kernels."
+#endif
 
 /*
- * --- Linux Include Files 
+ * --- Linux Include Files
  */
 
 #include <linux/config.h>
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
 #ifdef MODULE
 #include <linux/module.h>
 #endif /* MODULE */
-#endif /* version >= v1.3.0 */
+
+#if defined(CONFIG_X86) && !defined(CONFIG_ISA)
+#define CONFIG_ISA
+#endif /* CONFIG_X86 && !CONFIG_ISA */
+
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
-#include <linux/head.h>
-#endif /* verions < v2.1.0 */
 #include <linux/types.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
+#include <linux/malloc.h>
 #include <linux/mm.h>
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
 #include <linux/proc_fs.h>
-#endif /* version >= v1.3.0 */
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,23)
 #include <linux/init.h>
-#endif /* version >= v2.1.23 */
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/dma.h>
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
-#include "../block/blk.h"
-#else /* version >= v1.3.0 */
 #include <linux/blk.h>
 #include <linux/stat.h>
-#endif /* version >= v1.3.0 */
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,18)
+#if ASC_LINUX_KERNEL24
 #include <linux/spinlock.h>
-#elif LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,95)
+#elif ASC_LINUX_KERNEL22
 #include <asm/spinlock.h>
-#endif /* version >= 2.1.95 */
+#endif
 #include "scsi.h"
 #include "hosts.h"
 #include "sd.h"
 #include "advansys.h"
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,93)
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
 #endif /* CONFIG_PCI */
-#else /* version < v2.1.93 */
-/*
- * For earlier than v2.1.93 the driver has its own PCI configuration.
- * If PCI is not needed in a kernel before v2.1.93 this define can be
- * turned-off to make the driver object smaller.
- */
-#define ASC_CONFIG_PCI
-#endif /* version < v2.1.93 */
-
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
-#define cpu_to_le16(word)       (word)
-#define le16_to_cpu(word)       (word)
-#define cpu_to_le32(dword)      (dword)
-#define le32_to_cpu(dword)      (dword)
-#endif /* version < v2.1.0 */
 
 
 /*
@@ -817,19 +819,12 @@
 /* Enable driver assertions. */
 #define ADVANSYS_ASSERT
 
+/* Enable driver /proc statistics. */
+#define ADVANSYS_STATS
+
 /* Enable driver tracing. */
 /* #define ADVANSYS_DEBUG */
 
-/*
- * Because of no /proc to display them, statistics are disabled
- * for versions prior to v1.3.0.
- */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
-#undef ADVANSYS_STATS /* Disable statistics */
-#else /* version >= v1.3.0 */
-#define ADVANSYS_STATS /* Enable statistics. */
-#endif /* version >= v1.3.0 */
-
 
 /*
  * --- Debugging Header
@@ -848,7 +843,7 @@
 
 #define ASC_LIB_VERSION_MAJOR  1
 #define ASC_LIB_VERSION_MINOR  24
-#define ASC_LIB_SERIAL_NUMBER  121
+#define ASC_LIB_SERIAL_NUMBER  123
 
 /*
  * Portable Data Types
@@ -858,7 +853,7 @@
  * types must be used. In Linux the char, short, and int types
  * are all consistent at 8, 16, and 32 bits respectively. Pointers
  * and long types are 64 bits on Alpha and UltraSPARC.
- */ 
+ */
 #define ASC_PADDR __u32         /* Physical/Bus address data type. */
 #define ASC_VADDR __u32         /* Virtual address data type. */
 #define ASC_DCNT  __u32         /* Unsigned Data count type. */
@@ -907,7 +902,7 @@
 #define ASC_PCI_VENDORID                  0x10CD
 #define ASC_PCI_DEVICEID_1200A            0x1100
 #define ASC_PCI_DEVICEID_1200B            0x1200
-#define ASC_PCI_DEVICEID_ULTRA            0x1300 
+#define ASC_PCI_DEVICEID_ULTRA            0x1300
 #define ASC_PCI_REVISION_3150             0x02
 #define ASC_PCI_REVISION_3050             0x03
 
@@ -924,13 +919,13 @@
 #define CC_VERY_LONG_SG_LIST 0
 #define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
 
-#define PortAddr            unsigned short    /* port address size  */
-#define inp(port)           inb(port)
-#define inpw(port)          inw(port)
-#define inpl(port)          inl(port)
-#define outp(port, byte)    outb((byte), (port))
-#define outpw(port, word)   outw((word), (port))
-#define outpl(port, dword) outl((dword), (port))
+#define PortAddr                 unsigned short    /* port address size  */
+#define inp(port)                inb(port)
+#define outp(port, byte)         outb((byte), (port))
+
+#define inpw(port)               inw(port)
+#define outpw(port, word)        outw((word), (port))
+
 #define ASC_MAX_SG_QUEUE    7
 #define ASC_MAX_SG_LIST     255
 
@@ -977,12 +972,7 @@
 #define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
 #define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
 #define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
-#ifndef inpw_noswap
-#define inpw_noswap(port)         inpw(port)
-#endif
-#ifndef outpw_noswap
-#define outpw_noswap(port, data)  outpw(port, data)
-#endif
+
 #define ASC_SCSI_ID_BITS  3
 #define ASC_SCSI_TIX_TYPE     uchar
 #define ASC_ALL_DEVICE_BIT_SET  0xFF
@@ -1024,6 +1014,8 @@
 #define SCSICMD_ReadHeader        0x44
 #define SCSICMD_ModeSelect10      0x55
 #define SCSICMD_ModeSense10       0x5A
+
+/* Inquiry Data Peripheral Device Types */
 #define SCSI_TYPE_DASD     0x00
 #define SCSI_TYPE_SASD     0x01
 #define SCSI_TYPE_PRN      0x02
@@ -1035,10 +1027,20 @@
 #define SCSI_TYPE_MED_CHG  0x08
 #define SCSI_TYPE_COMM     0x09
 #define SCSI_TYPE_UNKNOWN  0x1F
-#define SCSI_TYPE_NO_DVC   0xFF
-#define INQ_CLOCKING_ST_ONLY    0x0
-#define INQ_CLOCKING_DT_ONLY    0x1
-#define INQ_CLOCKING_ST_AND_DT  0x3
+
+#define ADV_INQ_CLOCKING_ST_ONLY    0x0
+#define ADV_INQ_CLOCKING_DT_ONLY    0x1
+#define ADV_INQ_CLOCKING_ST_AND_DT  0x3
+
+/*
+ * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
+ * and CmdDt (Command Support Data) field bit definitions.
+ */
+#define ADV_INQ_RTN_VPD_AND_CMDDT           0x3
+#define ADV_INQ_RTN_CMDDT_FOR_OP_CODE       0x2
+#define ADV_INQ_RTN_VPD_FOR_PG_CODE         0x1
+#define ADV_INQ_RTN_STD_INQUIRY_DATA        0x0
+
 #define ASC_SCSIDIR_NOCHK    0x00
 #define ASC_SCSIDIR_T2H      0x08
 #define ASC_SCSIDIR_H2T      0x10
@@ -1102,77 +1104,49 @@
 #define M2_QTAG_MSG_ORDERED     0x22
 #define M2_IGNORE_WIDE_RESIDUE  0x23
 
-typedef struct {
-    uchar               peri_dvc_type:5;
-    uchar               peri_qualifier:3;
-} ASC_SCSI_INQ0;
-
-typedef struct {
-    uchar               dvc_type_modifier:7;
-    uchar               rmb:1;
-} ASC_SCSI_INQ1;
-
-typedef struct {
-    uchar               ansi_apr_ver:3;
-    uchar               ecma_ver:3;
-    uchar               iso_ver:2;
-} ASC_SCSI_INQ2;
-
-typedef struct {
-    uchar               rsp_data_fmt:4;
-    uchar               res:2;
-    uchar               TemIOP:1;
-    uchar               aenc:1;
-} ASC_SCSI_INQ3;
-
-typedef struct {
-    uchar               StfRe:1;
-    uchar               CmdQue:1;
-    uchar               Reserved:1;
-    uchar               Linked:1;
-    uchar               Sync:1;
-    uchar               WBus16:1;
-    uchar               WBus32:1;
-    uchar               RelAdr:1;
-} ASC_SCSI_INQ7;
+/*
+ * Inquiry data structure and bitfield macros
+ *
+ * Only quantities of more than 1 bit are shifted, since the others are
+ * just tested for true or false. C bitfields aren't portable between big
+ * and little-endian platforms so they are not used.
+ */
+
+#define ASC_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
+#define ASC_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
+#define ASC_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
+#define ASC_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
+#define ASC_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
+#define ASC_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
+#define ASC_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
+#define ASC_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
+#define ASC_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
+#define ASC_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
+#define ASC_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
+#define ASC_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
+#define ASC_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
+#define ASC_INQ_SYNC(inq)           ((inq)->flags & 0x10)
+#define ASC_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
+#define ASC_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
+#define ASC_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
+#define ASC_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
+#define ASC_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
+#define ASC_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
 
 typedef struct {
-    ASC_SCSI_INQ0       byte0;
-    ASC_SCSI_INQ1       byte1;
-    ASC_SCSI_INQ2       byte2;
-    ASC_SCSI_INQ3       byte3;
+    uchar               periph;
+    uchar               devtype;
+    uchar               ver;
+    uchar               byte3;
     uchar               add_len;
     uchar               res1;
     uchar               res2;
-    ASC_SCSI_INQ7       byte7;
+    uchar               flags;
     uchar               vendor_id[8];
     uchar               product_id[16];
     uchar               product_rev_level[4];
 } ASC_SCSI_INQUIRY;
 
-typedef struct asc_req_sense {
-    uchar               err_code:7;
-    uchar               info_valid:1;
-    uchar               segment_no;
-    uchar               sense_key:4;
-    uchar               reserved_bit:1;
-    uchar               sense_ILI:1;
-    uchar               sense_EOM:1;
-    uchar               file_mark:1;
-    uchar               info1[4];
-    uchar               add_sense_len;
-    uchar               cmd_sp_info[4];
-    uchar               asc;
-    uchar               ascq;
-    uchar               fruc;
-    uchar               sks_byte0:7;
-    uchar               sks_valid:1;
-    uchar               sks_bytes[2];
-    uchar               notused[2];
-    uchar               ex_sense_code;
-    uchar               info2[4];
-} ASC_REQ_SENSE;
-
 #define ASC_SG_LIST_PER_Q   7
 #define QS_FREE        0x00
 #define QS_READY       0x01
@@ -1286,7 +1260,7 @@
 #define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
 #define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))
 
-typedef struct asc_scisq_1 {
+typedef struct asc_scsiq_1 {
     uchar               status;
     uchar               q_no;
     uchar               cntl;
@@ -1300,7 +1274,7 @@
     uchar               extra_bytes;
 } ASC_SCSIQ_1;
 
-typedef struct asc_scisq_2 {
+typedef struct asc_scsiq_2 {
     ASC_VADDR           srb_ptr;
     uchar               target_ix;
     uchar               flag;
@@ -1378,8 +1352,8 @@
 typedef struct asc_scsi_req_q {
     ASC_SCSIQ_1         r1;
     ASC_SCSIQ_2         r2;
-    uchar       *cdbptr;
-    ASC_SG_HEAD *sg_head;
+    uchar               *cdbptr;
+    ASC_SG_HEAD         *sg_head;
     uchar               *sense_ptr;
     ASC_SCSIQ_3         r3;
     uchar               cdb[ASC_MAX_CDB_LEN];
@@ -1461,6 +1435,10 @@
 #define ASCQ_ERR_SEND_SCSI_Q          0x22
 #define ASCQ_ERR_HOST_REQ_RISC_HALT   0x23
 #define ASCQ_ERR_RESET_SDTR           0x24
+
+/*
+ * Warning code values are set in ASC_DVC_VAR  'warn_code'.
+ */
 #define ASC_WARN_NO_ERROR             0x0000
 #define ASC_WARN_IO_PORT_ROTATE       0x0001
 #define ASC_WARN_EEPROM_CHKSUM        0x0002
@@ -1470,6 +1448,10 @@
 #define ASC_WARN_EEPROM_RECOVER       0x0020
 #define ASC_WARN_CFG_MSW_RECOVER      0x0040
 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
+
+/*
+ * Error code values are set in ASC_DVC_VAR  'err_code'.
+ */
 #define ASC_IERR_WRITE_EEPROM         0x0001
 #define ASC_IERR_MCODE_CHKSUM         0x0002
 #define ASC_IERR_SET_PC_ADDR          0x0004
@@ -1484,6 +1466,7 @@
 #define ASC_IERR_SCAM                 0x0800
 #define ASC_IERR_SET_SDTR             0x1000
 #define ASC_IERR_RW_LRAM              0x8000
+
 #define ASC_DEF_IRQ_NO  10
 #define ASC_MAX_IRQ_NO  15
 #define ASC_MIN_IRQ_NO  10
@@ -1578,8 +1561,8 @@
     ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
     ASC_SCSI_BIT_ID_TYPE disc_enable;
     ASC_SCSI_BIT_ID_TYPE sdtr_enable;
-    uchar               chip_scsi_id:4;
-    uchar               isa_dma_speed:4;
+    uchar               chip_scsi_id;
+    uchar               isa_dma_speed;
     uchar               isa_dma_channel;
     uchar               chip_version;
     ushort              pci_device_id;
@@ -1703,6 +1686,20 @@
 #define ASC_MAX_INIT_BUSY_RETRY   8
 #define ASC_EEP_ISA_PNP_WSIZE    16
 
+/*
+ * These macros keep the chip SCSI id and ISA DMA speed
+ * bitfields in board order. C bitfields aren't portable
+ * between big and little-endian platforms so they are
+ * not used.
+ */
+
+#define ASC_EEP_GET_CHIP_ID(cfg)    ((cfg)->id_speed & 0x0f)
+#define ASC_EEP_GET_DMA_SPD(cfg)    (((cfg)->id_speed & 0xf0) >> 4)
+#define ASC_EEP_SET_CHIP_ID(cfg, sid) \
+   ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
+#define ASC_EEP_SET_DMA_SPD(cfg, spd) \
+   ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
+
 typedef struct asceep_config {
     ushort              cfg_lsw;
     ushort              cfg_msw;
@@ -1715,8 +1712,8 @@
     uchar               bios_scan;
     uchar               power_up_wait;
     uchar               no_scam;
-    uchar               chip_scsi_id:4;
-    uchar               isa_dma_speed:4;
+    uchar               id_speed; /* low order 4 bits is chip scsi id */
+                                  /* high order 4 bits is isa dma speed */
     uchar               dos_int13_table[ASC_MAX_TID + 1];
     uchar               adapter_info[6];
     ushort              cntl;
@@ -1962,8 +1959,6 @@
 #define AscSetChipLramAddr(port, addr)    outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
 #define AscGetChipLramData(port)          (ushort)inpw((port)+IOP_RAM_DATA)
 #define AscSetChipLramData(port, data)    outpw((port)+IOP_RAM_DATA, data)
-#define AscGetChipLramDataNoSwap(port)         (ushort)inpw_noswap((port)+IOP_RAM_DATA)
-#define AscSetChipLramDataNoSwap(port, data)   outpw_noswap((port)+IOP_RAM_DATA, data)
 #define AscGetChipIFC(port)               (uchar)inp((port)+IOP_REG_IFC)
 #define AscSetChipIFC(port, data)          outp((port)+IOP_REG_IFC, data)
 #define AscGetChipStatus(port)            (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
@@ -2021,21 +2016,24 @@
 STATIC void      AscEnableInterrupt(PortAddr);
 STATIC void      AscSetBank(PortAddr, uchar);
 STATIC int       AscResetChipAndScsiBus(ASC_DVC_VAR *);
+#ifdef CONFIG_ISA
 STATIC ushort    AscGetIsaDmaChannel(PortAddr);
 STATIC ushort    AscSetIsaDmaChannel(PortAddr, ushort);
 STATIC uchar     AscSetIsaDmaSpeed(PortAddr, uchar);
 STATIC uchar     AscGetIsaDmaSpeed(PortAddr);
+#endif /* CONFIG_ISA */
 STATIC uchar     AscReadLramByte(PortAddr, ushort);
 STATIC ushort    AscReadLramWord(PortAddr, ushort);
+#if CC_VERY_LONG_SG_LIST
 STATIC ASC_DCNT  AscReadLramDWord(PortAddr, ushort);
+#endif /* CC_VERY_LONG_SG_LIST */
 STATIC void      AscWriteLramWord(PortAddr, ushort, ushort);
-STATIC void      AscWriteLramDWord(PortAddr, ushort, ASC_DCNT);
 STATIC void      AscWriteLramByte(PortAddr, ushort, uchar);
 STATIC ASC_DCNT  AscMemSumLramWord(PortAddr, ushort, int);
 STATIC void      AscMemWordSetLram(PortAddr, ushort, ushort, int);
-STATIC void      AscMemWordCopyToLram(PortAddr, ushort, ushort *, int);
-STATIC void      AscMemDWordCopyToLram(PortAddr, ushort, ASC_DCNT *, int);
-STATIC void      AscMemWordCopyFromLram(PortAddr, ushort, ushort *, int);
+STATIC void      AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
+STATIC void      AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
+STATIC void      AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
 STATIC ushort    AscInitAscDvcVar(ASC_DVC_VAR *);
 STATIC ushort    AscInitFromEEP(ASC_DVC_VAR *);
 STATIC ushort    AscInitFromAscDvcVar(ASC_DVC_VAR *);
@@ -2047,21 +2045,8 @@
 STATIC uchar     AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
 STATIC uchar     AscAllocFreeQueue(PortAddr, uchar);
 STATIC uchar     AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
-STATIC int       AscRiscHaltedAbortSRB(ASC_DVC_VAR *, ASC_DCNT);
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-STATIC int       AscRiscHaltedAbortTIX(ASC_DVC_VAR *, uchar);
-#endif /* version >= v1.3.89 */
 STATIC int       AscHostReqRiscHalt(PortAddr);
 STATIC int       AscStopQueueExe(PortAddr);
-STATIC int       AscStartQueueExe(PortAddr);
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-STATIC int       AscCleanUpDiscQueue(PortAddr);
-#endif /* version >= v1.3.89 */
-STATIC int       AscCleanUpBusyQueue(PortAddr);
-STATIC int       AscWaitTixISRDone(ASC_DVC_VAR *, uchar);
-STATIC int       AscWaitISRDone(ASC_DVC_VAR *);
-STATIC ASC_PADDR AscGetOnePhyAddr(ASC_DVC_VAR *, uchar *,
-                    ASC_DCNT);
 STATIC int       AscSendScsiQueue(ASC_DVC_VAR *,
                     ASC_SCSI_Q * scsiq,
                     uchar n_q_required);
@@ -2072,48 +2057,43 @@
 STATIC int       AscSetChipSynRegAtID(PortAddr, uchar, uchar);
 STATIC int       AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
 STATIC ushort    AscInitLram(ASC_DVC_VAR *);
-STATIC int       AscReInitLram(ASC_DVC_VAR *);
 STATIC ushort    AscInitQLinkVar(ASC_DVC_VAR *);
 STATIC int       AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-STATIC int       _AscWaitQDone(PortAddr, ASC_SCSI_Q *);
-#endif /* version >= v1.3.89 */
 STATIC int       AscIsrChipHalted(ASC_DVC_VAR *);
 STATIC uchar     _AscCopyLramScsiDoneQ(PortAddr, ushort,
                     ASC_QDONE_INFO *, ASC_DCNT);
 STATIC int       AscIsrQDone(ASC_DVC_VAR *);
 STATIC int       AscCompareString(uchar *, uchar *, int);
+#ifdef CONFIG_ISA
 STATIC ushort    AscGetEisaChipCfg(PortAddr);
 STATIC ASC_DCNT  AscGetEisaProductID(PortAddr);
 STATIC PortAddr  AscSearchIOPortAddrEISA(PortAddr);
+STATIC PortAddr  AscSearchIOPortAddr11(PortAddr);
+STATIC PortAddr  AscSearchIOPortAddr(PortAddr, ushort);
+STATIC void      AscSetISAPNPWaitForKey(void);
+#endif /* CONFIG_ISA */
 STATIC uchar     AscGetChipScsiCtrl(PortAddr);
 STATIC uchar     AscSetChipScsiID(PortAddr, uchar);
 STATIC uchar     AscGetChipVersion(PortAddr, ushort);
 STATIC ushort    AscGetChipBusType(PortAddr);
-STATIC ASC_DCNT  AscLoadMicroCode(PortAddr, ushort, ushort *, ushort);
+STATIC ASC_DCNT  AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
 STATIC int       AscFindSignature(PortAddr);
-STATIC PortAddr  AscSearchIOPortAddr11(PortAddr);
 STATIC void      AscToggleIRQAct(PortAddr);
-STATIC void      AscSetISAPNPWaitForKey(void);
 STATIC uchar     AscGetChipIRQ(PortAddr, ushort);
 STATIC uchar     AscSetChipIRQ(PortAddr, uchar, ushort);
 STATIC ushort    AscGetChipBiosAddress(PortAddr, ushort);
-STATIC int       DvcEnterCritical(void);
-STATIC void      DvcLeaveCritical(int);
-STATIC void      DvcInPortWords(PortAddr, ushort *, int);
-STATIC void      DvcOutPortWords(PortAddr, ushort *, int);
-STATIC void      DvcOutPortDWords(PortAddr, ASC_DCNT *, int);
+STATIC inline ulong DvcEnterCritical(void);
+STATIC inline void DvcLeaveCritical(ulong);
+#ifdef CONFIG_PCI
 STATIC uchar     DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
 STATIC void      DvcWritePCIConfigByte(ASC_DVC_VAR *,
                     ushort, uchar);
+#endif /* CONFIG_PCI */
 STATIC ushort      AscGetChipBiosAddress(PortAddr, ushort);
 STATIC void      DvcSleepMilliSecond(ASC_DCNT);
 STATIC void      DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
-STATIC ASC_DCNT  DvcGetSGList(ASC_DVC_VAR *, uchar *,
-                    ASC_DCNT, ASC_SG_HEAD *);
-STATIC void      DvcPutScsiQ(PortAddr, ushort, ushort *, int);
-STATIC void      DvcGetQinfo(PortAddr, ushort, ushort *, int);
-STATIC PortAddr  AscSearchIOPortAddr(PortAddr, ushort);
+STATIC void      DvcPutScsiQ(PortAddr, ushort, uchar *, int);
+STATIC void      DvcGetQinfo(PortAddr, ushort, uchar *, int);
 STATIC ushort    AscInitGetConfig(ASC_DVC_VAR *);
 STATIC ushort    AscInitSetConfig(ASC_DVC_VAR *);
 STATIC ushort    AscInitAsc1000Driver(ASC_DVC_VAR *);
@@ -2127,12 +2107,9 @@
 STATIC uint      AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar,
                     uchar);
 STATIC int       AscSgListToQueue(int);
-STATIC int       AscAbortSRB(ASC_DVC_VAR *, ASC_VADDR);
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-STATIC int       AscResetDevice(ASC_DVC_VAR *, uchar);
-#endif /* version >= v1.3.89 */
-STATIC int       AscResetSB(ASC_DVC_VAR *);
+#ifdef CONFIG_ISA
 STATIC void      AscEnableIsaDma(uchar);
+#endif /* CONFIG_ISA */
 STATIC ASC_DCNT  AscGetMaxDmaCount(ushort);
 
 
@@ -2141,7 +2118,7 @@
  */
 
 #define ADV_LIB_VERSION_MAJOR  5
-#define ADV_LIB_VERSION_MINOR  5
+#define ADV_LIB_VERSION_MINOR  14
 
 /* d_os_dep.h */
 #define ADV_OS_LINUX
@@ -2158,7 +2135,7 @@
  * types must be used. In Linux the char, short, and int types
  * are all consistent at 8, 16, and 32 bits respectively. Pointers
  * and long types are 64 bits on Alpha and UltraSPARC.
- */ 
+ */
 #define ADV_PADDR __u32         /* Physical address data type. */
 #define ADV_VADDR __u32         /* Virtual address data type. */
 #define ADV_DCNT  __u32         /* Unsigned Data count type. */
@@ -2175,11 +2152,7 @@
 #define ADV_VADDR_TO_U32   virt_to_bus
 #define ADV_U32_TO_VADDR   bus_to_virt
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
-#define AdvPortAddr  unsigned short     /* I/O Port address size */
-#else /* version >= v1,3,0 */
 #define AdvPortAddr  ulong              /* Virtual memory address size */
-#endif /* version >= v1,3,0 */
 
 /*
  * Define Adv Library required memory access macros.
@@ -2188,16 +2161,15 @@
 #define ADV_MEM_READW(addr) readw(addr)
 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
+#define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
+
+#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
 
 /*
- * The I/O memory mapping function names changed in 2.1.X.
+ * For wide  boards a CDB length maximum of 16 bytes
+ * is supported.
  */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
-#define ioremap vremap
-#define iounmap vfree
-#endif /* version < v2.1.0 */
-
-#define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
+#define ADV_MAX_CDB_LEN     16
 
 /*
  * Define total number of simultaneous maximum element scatter-gather
@@ -2207,7 +2179,7 @@
  * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
  * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
  * structures or 255 scatter-gather elements.
- * 
+ *
  */
 #define ADV_TOT_SG_BLOCK        ASC_DEF_MAX_HOST_QNG
 
@@ -2225,10 +2197,10 @@
 #define ADV_SG_TOTAL_MEM_SIZE \
     (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
 
-#define ASC_PAGE_SIZE PAGE_SIZE
+#define ADV_PAGE_SIZE PAGE_SIZE
 
 #define ADV_NUM_PAGE_CROSSING \
-    ((ADV_SG_TOTAL_MEM_SIZE + (ASC_PAGE_SIZE - 1))/ASC_PAGE_SIZE)
+    ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
 
 /* a_condor.h */
 #define ADV_PCI_VENDOR_ID               0x10CD
@@ -2236,12 +2208,12 @@
 #define ADV_PCI_DEVID_38C0800_REV1      0x2500
 #define ADV_PCI_DEVID_38C1600_REV1      0x2700
 
-#define ASC_EEP_DVC_CFG_BEGIN           (0x00)
-#define ASC_EEP_DVC_CFG_END             (0x15)
-#define ASC_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
-#define ASC_EEP_MAX_WORD_ADDR           (0x1E)
+#define ADV_EEP_DVC_CFG_BEGIN           (0x00)
+#define ADV_EEP_DVC_CFG_END             (0x15)
+#define ADV_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
+#define ADV_EEP_MAX_WORD_ADDR           (0x1E)
 
-#define ASC_EEP_DELAY_MS                100
+#define ADV_EEP_DELAY_MS                100
 
 #define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
 #define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
@@ -2252,6 +2224,18 @@
  */
 #define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
 #define ADV_EEPROM_CIS_LD              0x2000   /* EEPROM Bit 13 */
+/*
+ * ASC38C1600 Bit 11
+ *
+ * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
+ * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
+ * Function 0 will specify INT B.
+ *
+ * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
+ * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
+ * Function 1 will specify INT A.
+ */
+#define ADV_EEPROM_INTAB               0x0800   /* EEPROM Bit 11 */
 
 typedef struct adveep_3550_config
 {
@@ -2262,20 +2246,20 @@
                                 /*  bit 14 set - BIOS Enable */
                                 /*  bit 15 set - Big Endian Mode */
   ushort cfg_msw;               /* 01 unused      */
-  ushort disc_enable;           /* 02 disconnect enable */         
+  ushort disc_enable;           /* 02 disconnect enable */
   ushort wdtr_able;             /* 03 Wide DTR able */
   ushort sdtr_able;             /* 04 Synchronous DTR able */
-  ushort start_motor;           /* 05 send start up motor */      
+  ushort start_motor;           /* 05 send start up motor */
   ushort tagqng_able;           /* 06 tag queuing able */
-  ushort bios_scan;             /* 07 BIOS device control */   
-  ushort scam_tolerant;         /* 08 no scam */  
- 
+  ushort bios_scan;             /* 07 BIOS device control */
+  ushort scam_tolerant;         /* 08 no scam */
+
   uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
   uchar  bios_boot_delay;       /*    power up wait */
- 
+
   uchar  scsi_reset_delay;      /* 10 reset delay */
   uchar  bios_id_lun;           /*    first boot device scsi id & lun */
-                                /*    high nibble is lun */  
+                                /*    high nibble is lun */
                                 /*    low nibble is scsi id */
 
   uchar  termination;           /* 11 0 - automatic */
@@ -2284,33 +2268,33 @@
                                 /*    3 - low on  / high on */
                                 /*    There is no low on  / high off */
 
-  uchar  reserved1;             /*    reserved byte (not used) */                                  
+  uchar  reserved1;             /*    reserved byte (not used) */
 
   ushort bios_ctrl;             /* 12 BIOS control bits */
-                                /*  bit 0  set: BIOS don't act as initiator. */
-                                /*  bit 1  set: BIOS > 1 GB support */
-                                /*  bit 2  set: BIOS > 2 Disk Support */
-                                /*  bit 3  set: BIOS don't support removables */
-                                /*  bit 4  set: BIOS support bootable CD */
-                                /*  bit 5  set: */
-                                /*  bit 6  set: BIOS support multiple LUNs */
-                                /*  bit 7  set: BIOS display of message */
-                                /*  bit 8  set: */
-                                /*  bit 9  set: Reset SCSI bus during init. */
-                                /*  bit 10 set: */
-                                /*  bit 11 set: No verbose initialization. */
-                                /*  bit 12 set: SCSI parity enabled */
-                                /*  bit 13 set: */
-                                /*  bit 14 set: */
-                                /*  bit 15 set: */
-  ushort  ultra_able;           /* 13 ULTRA speed able */ 
+                                /*  bit 0  BIOS don't act as initiator. */
+                                /*  bit 1  BIOS > 1 GB support */
+                                /*  bit 2  BIOS > 2 Disk Support */
+                                /*  bit 3  BIOS don't support removables */
+                                /*  bit 4  BIOS support bootable CD */
+                                /*  bit 5  BIOS scan enabled */
+                                /*  bit 6  BIOS support multiple LUNs */
+                                /*  bit 7  BIOS display of message */
+                                /*  bit 8  SCAM disabled */
+                                /*  bit 9  Reset SCSI bus during init. */
+                                /*  bit 10 */
+                                /*  bit 11 No verbose initialization. */
+                                /*  bit 12 SCSI parity enabled */
+                                /*  bit 13 */
+                                /*  bit 14 */
+                                /*  bit 15 */
+  ushort  ultra_able;           /* 13 ULTRA speed able */
   ushort  reserved2;            /* 14 reserved */
   uchar   max_host_qng;         /* 15 maximum host queuing */
   uchar   max_dvc_qng;          /*    maximum per device queuing */
   ushort  dvc_cntl;             /* 16 control bit for driver */
   ushort  bug_fix;              /* 17 control bit for bug fix */
-  ushort  serial_number_word1;  /* 18 Board serial number word 1 */  
-  ushort  serial_number_word2;  /* 19 Board serial number word 2 */  
+  ushort  serial_number_word1;  /* 18 Board serial number word 1 */
+  ushort  serial_number_word2;  /* 19 Board serial number word 2 */
   ushort  serial_number_word3;  /* 20 Board serial number word 3 */
   ushort  check_sum;            /* 21 EEP check sum */
   uchar   oem_name[16];         /* 22 OEM name */
@@ -2319,9 +2303,9 @@
   ushort  adv_err_addr;         /* 32 last uc error address */
   ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
   ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
-  ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */  
+  ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
   ushort  num_of_err;           /* 36 number of error */
-} ADVEEP_3550_CONFIG; 
+} ADVEEP_3550_CONFIG;
 
 typedef struct adveep_38C0800_config
 {
@@ -2361,22 +2345,22 @@
                                 /*    There is no low on  / high off */
 
   ushort bios_ctrl;             /* 12 BIOS control bits */
-                                /*  bit 0  set: BIOS don't act as initiator. */
-                                /*  bit 1  set: BIOS > 1 GB support */
-                                /*  bit 2  set: BIOS > 2 Disk Support */
-                                /*  bit 3  set: BIOS don't support removables */
-                                /*  bit 4  set: BIOS support bootable CD */
-                                /*  bit 5  set: BIOS scan enabled */
-                                /*  bit 6  set: BIOS support multiple LUNs */
-                                /*  bit 7  set: BIOS display of message */
-                                /*  bit 8  set: */
-                                /*  bit 9  set: Reset SCSI bus during init. */
-                                /*  bit 10 set: */
-                                /*  bit 11 set: No verbose initialization. */
-                                /*  bit 12 set: SCSI parity enabled */
-                                /*  bit 13 set: */
-                                /*  bit 14 set: */
-                                /*  bit 15 set: */
+                                /*  bit 0  BIOS don't act as initiator. */
+                                /*  bit 1  BIOS > 1 GB support */
+                                /*  bit 2  BIOS > 2 Disk Support */
+                                /*  bit 3  BIOS don't support removables */
+                                /*  bit 4  BIOS support bootable CD */
+                                /*  bit 5  BIOS scan enabled */
+                                /*  bit 6  BIOS support multiple LUNs */
+                                /*  bit 7  BIOS display of message */
+                                /*  bit 8  SCAM disabled */
+                                /*  bit 9  Reset SCSI bus during init. */
+                                /*  bit 10 */
+                                /*  bit 11 No verbose initialization. */
+                                /*  bit 12 SCSI parity enabled */
+                                /*  bit 13 */
+                                /*  bit 14 */
+                                /*  bit 15 */
   ushort  sdtr_speed2;          /* 13 SDTR speed TID 4-7 */
   ushort  sdtr_speed3;          /* 14 SDTR speed TID 8-11 */
   uchar   max_host_qng;         /* 15 maximum host queueing */
@@ -2424,6 +2408,109 @@
   ushort  reserved63;           /* 63 reserved */
 } ADVEEP_38C0800_CONFIG;
 
+typedef struct adveep_38C1600_config
+{
+                                /* Word Offset, Description */
+
+  ushort cfg_lsw;               /* 00 power up initialization */
+                                /*  bit 11 set - Func. 0 INTB, Func. 1 INTA */
+                                /*       clear - Func. 0 INTA, Func. 1 INTB */
+                                /*  bit 13 set - Load CIS */
+                                /*  bit 14 set - BIOS Enable */
+                                /*  bit 15 set - Big Endian Mode */
+  ushort cfg_msw;               /* 01 unused */
+  ushort disc_enable;           /* 02 disconnect enable */
+  ushort wdtr_able;             /* 03 Wide DTR able */
+  ushort sdtr_speed1;           /* 04 SDTR Speed TID 0-3 */
+  ushort start_motor;           /* 05 send start up motor */
+  ushort tagqng_able;           /* 06 tag queuing able */
+  ushort bios_scan;             /* 07 BIOS device control */
+  ushort scam_tolerant;         /* 08 no scam */
+
+  uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
+  uchar  bios_boot_delay;       /*    power up wait */
+
+  uchar  scsi_reset_delay;      /* 10 reset delay */
+  uchar  bios_id_lun;           /*    first boot device scsi id & lun */
+                                /*    high nibble is lun */
+                                /*    low nibble is scsi id */
+
+  uchar  termination_se;        /* 11 0 - automatic */
+                                /*    1 - low off / high off */
+                                /*    2 - low off / high on */
+                                /*    3 - low on  / high on */
+                                /*    There is no low on  / high off */
+
+  uchar  termination_lvd;       /* 11 0 - automatic */
+                                /*    1 - low off / high off */
+                                /*    2 - low off / high on */
+                                /*    3 - low on  / high on */
+                                /*    There is no low on  / high off */
+
+  ushort bios_ctrl;             /* 12 BIOS control bits */
+                                /*  bit 0  BIOS don't act as initiator. */
+                                /*  bit 1  BIOS > 1 GB support */
+                                /*  bit 2  BIOS > 2 Disk Support */
+                                /*  bit 3  BIOS don't support removables */
+                                /*  bit 4  BIOS support bootable CD */
+                                /*  bit 5  BIOS scan enabled */
+                                /*  bit 6  BIOS support multiple LUNs */
+                                /*  bit 7  BIOS display of message */
+                                /*  bit 8  SCAM disabled */
+                                /*  bit 9  Reset SCSI bus during init. */
+                                /*  bit 10 Basic Integrity Checking disabled */
+                                /*  bit 11 No verbose initialization. */
+                                /*  bit 12 SCSI parity enabled */
+                                /*  bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
+                                /*  bit 14 */
+                                /*  bit 15 */
+  ushort  sdtr_speed2;          /* 13 SDTR speed TID 4-7 */
+  ushort  sdtr_speed3;          /* 14 SDTR speed TID 8-11 */
+  uchar   max_host_qng;         /* 15 maximum host queueing */
+  uchar   max_dvc_qng;          /*    maximum per device queuing */
+  ushort  dvc_cntl;             /* 16 control bit for driver */
+  ushort  sdtr_speed4;          /* 17 SDTR speed 4 TID 12-15 */
+  ushort  serial_number_word1;  /* 18 Board serial number word 1 */
+  ushort  serial_number_word2;  /* 19 Board serial number word 2 */
+  ushort  serial_number_word3;  /* 20 Board serial number word 3 */
+  ushort  check_sum;            /* 21 EEP check sum */
+  uchar   oem_name[16];         /* 22 OEM name */
+  ushort  dvc_err_code;         /* 30 last device driver error code */
+  ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
+  ushort  adv_err_addr;         /* 32 last uc error address */
+  ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
+  ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
+  ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
+  ushort  reserved36;           /* 36 reserved */
+  ushort  reserved37;           /* 37 reserved */
+  ushort  reserved38;           /* 38 reserved */
+  ushort  reserved39;           /* 39 reserved */
+  ushort  reserved40;           /* 40 reserved */
+  ushort  reserved41;           /* 41 reserved */
+  ushort  reserved42;           /* 42 reserved */
+  ushort  reserved43;           /* 43 reserved */
+  ushort  reserved44;           /* 44 reserved */
+  ushort  reserved45;           /* 45 reserved */
+  ushort  reserved46;           /* 46 reserved */
+  ushort  reserved47;           /* 47 reserved */
+  ushort  reserved48;           /* 48 reserved */
+  ushort  reserved49;           /* 49 reserved */
+  ushort  reserved50;           /* 50 reserved */
+  ushort  reserved51;           /* 51 reserved */
+  ushort  reserved52;           /* 52 reserved */
+  ushort  reserved53;           /* 53 reserved */
+  ushort  reserved54;           /* 54 reserved */
+  ushort  reserved55;           /* 55 reserved */
+  ushort  cisptr_lsw;           /* 56 CIS PTR LSW */
+  ushort  cisprt_msw;           /* 57 CIS PTR MSW */
+  ushort  subsysvid;            /* 58 SubSystem Vendor ID */
+  ushort  subsysid;             /* 59 SubSystem ID */
+  ushort  reserved60;           /* 60 reserved */
+  ushort  reserved61;           /* 61 reserved */
+  ushort  reserved62;           /* 62 reserved */
+  ushort  reserved63;           /* 63 reserved */
+} ADVEEP_38C1600_CONFIG;
+
 /*
  * EEPROM Commands
  */
@@ -2445,6 +2532,7 @@
 #define BIOS_CTRL_RESET_SCSI_BUS     0x0200
 #define BIOS_CTRL_INIT_VERBOSE       0x0800
 #define BIOS_CTRL_SCSI_PARITY        0x1000
+#define BIOS_CTRL_AIPP_DIS           0x2000
 
 #define ADV_3550_MEMSIZE   0x2000       /* 8 KB Internal Memory */
 #define ADV_3550_IOLEN     0x40         /* I/O Port Range in bytes */
@@ -2452,7 +2540,14 @@
 #define ADV_38C0800_MEMSIZE  0x4000     /* 16 KB Internal Memory */
 #define ADV_38C0800_IOLEN    0x100      /* I/O Port Range in bytes */
 
-#define ADV_38C1600_MEMSIZE  0x4000    /* 16 KB Internal Memory */
+/*
+ * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
+ * a special 16K Adv Library and Microcode version. After the issue is
+ * resolved, should restore 32K support.
+ *
+ * #define ADV_38C1600_MEMSIZE  0x8000L   * 32 KB Internal Memory *
+ */
+#define ADV_38C1600_MEMSIZE  0x4000   /* 16 KB Internal Memory */
 #define ADV_38C1600_IOLEN    0x100     /* I/O Port Range 256 bytes */
 #define ADV_38C1600_MEMLEN   0x1000    /* Memory Range 4KB bytes */
 
@@ -2653,8 +2748,8 @@
 #define SLEW_RATE       0x1000  /* SCSI output buffer slew rate */
 #define FILTER_SEL      0x0C00  /* Filter Period Selection */
 #define  FLTR_DISABLE    0x0000  /* Input Filtering Disabled */
-#define  FLTR_11_TO_20NS 0x0800  /* Input Filtering 11ns to 20ns */          
-#define  FLTR_21_TO_39NS 0x0C00  /* Input Filtering 21ns to 39ns */          
+#define  FLTR_11_TO_20NS 0x0800  /* Input Filtering 11ns to 20ns */
+#define  FLTR_21_TO_39NS 0x0C00  /* Input Filtering 21ns to 39ns */
 #define ACTIVE_DBL      0x0200  /* Disable Active Negation */
 #define DIFF_MODE       0x0100  /* SCSI differential Mode (Read-Only) */
 #define DIFF_SENSE      0x0080  /* 1: No SE cables, 0: SE cable (Read-Only) */
@@ -2666,6 +2761,14 @@
 
 /*
  * Addendum for ASC-38C0800 Chip
+ *
+ * The ASC-38C1600 Chip uses the same definitions except that the
+ * bus mode override bits [12:10] have been moved to byte register
+ * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
+ * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
+ * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
+ * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
+ * and [1:0]. Bits [14], [7:6], [3:2] are unused.
  */
 #define DIS_TERM_DRV    0x4000  /* 1: Read c_det[3:0], 0: cannot read */
 #define HVD_LVD_SE      0x1C00  /* Device Detect Bits */
@@ -2745,6 +2848,33 @@
 #define PRE_TEST_VALUE        0x05
 #define NORMAL_VALUE          0x00
 
+/*
+ * ASC38C1600 Definitions
+ *
+ * IOPB_PCI_INT_CFG Bit Field Definitions
+ */
+
+#define INTAB_LD        0x80    /* Value loaded from EEPROM Bit 11. */
+
+/*
+ * Bit 1 can be set to change the interrupt for the Function to operate in
+ * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
+ * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
+ * mode, otherwise the operating mode is undefined.
+ */
+#define TOTEMPOLE       0x02
+
+/*
+ * Bit 0 can be used to change the Int Pin for the Function. The value is
+ * 0 by default for both Functions with Function 0 using INT A and Function
+ * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
+ * INT A is used.
+ *
+ * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
+ * value specified in the PCI Configuration Space.
+ */
+#define INTAB           0x01
+
 /* a_advlib.h */
 
 /*
@@ -2759,7 +2889,7 @@
 
 
 /*
- * ASC_DVC_VAR 'warn_code' values
+ * ADV_DVC_VAR 'warn_code' values
  */
 #define ASC_WARN_BUSRESET_ERROR         0x0001 /* SCSI Bus Reset error */
 #define ASC_WARN_EEPROM_CHKSUM          0x0002 /* EEP check sum error */
@@ -2770,11 +2900,8 @@
 #define ADV_MAX_TID                     15 /* max. target identifier */
 #define ADV_MAX_LUN                     7  /* max. logical unit number */
 
-
 /*
- * AscInitGetConfig() and AscInitAsc1000Driver() Definitions
- *
- * Error code values are set in ASC_DVC_VAR 'err_code'.
+ * Error code values are set in ADV_DVC_VAR 'err_code'.
  */
 #define ASC_IERR_WRITE_EEPROM       0x0001 /* write EEPROM error */
 #define ASC_IERR_MCODE_CHKSUM       0x0002 /* micro code check sum error */
@@ -2829,6 +2956,7 @@
 #define ASC_MC_CAM_MODE_MASK            0x015E /* CAM mode TID bitmask. */
 #define ASC_MC_ICQ                      0x0160
 #define ASC_MC_IRQ                      0x0164
+#define ASC_MC_PPR_ABLE                 0x017A
 
 /*
  * BIOS LRAM variable absolute offsets.
@@ -2845,6 +2973,7 @@
  * and handled by the microcode.
  */
 #define CONTROL_FLAG_IGNORE_PERR        0x0001 /* Ignore DMA Parity Errors */
+#define CONTROL_FLAG_ENABLE_AIPP        0x0002 /* Enabled AIPP checking. */
 
 /*
  * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
@@ -2876,6 +3005,10 @@
 #define ASC_QSC_HEAD_TAG    0x40 /* Use Head Tag Message (0x21). */
 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
 
+/*
+ * All fields here are accessed by the board microcode and need to be
+ * little-endian.
+ */
 typedef struct adv_carr_t
 {
     ADV_VADDR   carr_va;       /* Carrier Virtual Address */
@@ -2896,12 +3029,11 @@
 #define ASC_NEXT_VPA_MASK       0xFFFFFFF0
 
 #define ASC_RQ_DONE             0x00000001
+#define ASC_RQ_GOOD             0x00000002
 #define ASC_CQ_STOPPER          0x00000000
 
 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
 
-#define ADV_PAGE_SIZE   4096    /* Assume 4KB page size. */
-
 #define ADV_CARRIER_NUM_PAGE_CROSSING \
     (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
         (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
@@ -2929,7 +3061,7 @@
  * This structure can be discarded after initialization. Don't add
  * fields here needed after initialization.
  *
- * Field naming convention: 
+ * Field naming convention:
  *
  *  *_enable indicates the field enables or disables a feature. The
  *  value of the field is never reset.
@@ -2949,7 +3081,7 @@
   ushort serial1;           /* EEPROM serial number word 1 */
   ushort serial2;           /* EEPROM serial number word 2 */
   ushort serial3;           /* EEPROM serial number word 3 */
-} ADV_DVC_CFG; 
+} ADV_DVC_CFG;
 
 struct adv_dvc_var;
 struct adv_scsi_req_q;
@@ -2965,7 +3097,7 @@
  *
  * One structure is required per host adapter.
  *
- * Field naming convention: 
+ * Field naming convention:
  *
  *  *_able indicates both whether a feature should be enabled or disabled
  *  and whether a device isi capable of the feature. At initialization
@@ -2986,6 +3118,7 @@
   ushort sdtr_speed3;     /* EEPROM SDTR Speed for TID 8-11  */
   ushort sdtr_speed4;     /* EEPROM SDTR Speed for TID 12-15 */
   ushort tagqng_able;     /* try tagged queuing with a device */
+  ushort ppr_able;        /* PPR message capable per TID bitmask. */
   uchar  max_dvc_qng;     /* maximum number of tagged commands per device */
   ushort start_motor;     /* start motor command allowed */
   uchar  scsi_reset_wait; /* delay in seconds after scsi bus reset */
@@ -3007,13 +3140,13 @@
   * driver may discard the buffer after initialization is done.
   */
   ADV_DVC_CFG *cfg; /* temporary configuration structure  */
-} ADV_DVC_VAR; 
+} ADV_DVC_VAR;
 
 #define NO_OF_SG_PER_BLOCK              15
 
 typedef struct asc_sg_block {
-    uchar reserved1; 
-    uchar reserved2; 
+    uchar reserved1;
+    uchar reserved2;
     uchar reserved3;
     uchar sg_cnt;                     /* Valid entries in block. */
     ADV_PADDR sg_ptr;                 /* Pointer to next sg block. */
@@ -3030,6 +3163,9 @@
  * The microcode makes assumptions about the size and ordering of fields
  * in this structure. Do not change the structure definition here without
  * coordinating the change with the microcode.
+ *
+ * All fields accessed by microcode must be maintained in little_endian
+ * order.
  */
 typedef struct adv_scsi_req_q {
     uchar       cntl;           /* Ucode flags and state (ASC_MC_QC_*). */
@@ -3042,16 +3178,16 @@
     ADV_PADDR   carr_pa;
     uchar       mflag;
     uchar       sense_len;
-    uchar       cdb_len;        /* SCSI CDB length. */
+    uchar       cdb_len;        /* SCSI CDB length. Must <= 16 bytes. */
     uchar       scsi_cntl;
     uchar       done_status;    /* Completion status. */
     uchar       scsi_status;    /* SCSI status byte. */
     uchar       host_status;    /* Ucode host status. */
     uchar       sg_working_ix;
-    uchar       cdb[12];        /* SCSI command block. */
+    uchar       cdb[12];        /* SCSI CDB bytes 0-11. */
     ADV_PADDR   sg_real_addr;   /* SG list physical address. */
     ADV_PADDR   scsiq_rptr;
-    ADV_DCNT    sg_working_data_cnt;
+    uchar       cdb16[4];       /* SCSI CDB bytes 12-15. */
     ADV_VADDR   scsiq_ptr;
     ADV_VADDR   carr_va;
     /*
@@ -3062,6 +3198,7 @@
     ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
     char        *vdata_addr;   /* Data buffer virtual address. */
     uchar       a_flag;
+    uchar       pad[2];        /* Pad out to a word boundary. */
 } ADV_SCSI_REQ_Q;
 
 /*
@@ -3097,14 +3234,16 @@
 #define ADV_ASYNC_RDMA_FAILURE          0x01 /* Fatal RDMA failure. */
 #define ADV_ASYNC_SCSI_BUS_RESET_DET    0x02 /* Detected SCSI Bus Reset. */
 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
+#define ADV_RDMA_IN_CARR_AND_Q_INVALID  0x04 /* RDMAed-in data invalid. */
+
 
 #define ADV_HOST_SCSI_BUS_RESET      0x80 /* Host Initiated SCSI Bus Reset. */
 
 /*
  * Device drivers must define the following functions.
  */
-STATIC int   DvcEnterCritical(void);
-STATIC void  DvcLeaveCritical(int);
+STATIC inline ulong DvcEnterCritical(void);
+STATIC inline void  DvcLeaveCritical(ulong);
 STATIC void  DvcSleepMilliSecond(ADV_DCNT);
 STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
 STATIC void  DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
@@ -3120,6 +3259,7 @@
 STATIC int     AdvInitGetConfig(ADV_DVC_VAR *);
 STATIC int     AdvInitAsc3550Driver(ADV_DVC_VAR *);
 STATIC int     AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
+STATIC int     AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
 STATIC int     AdvResetChipAndSB(ADV_DVC_VAR *);
 STATIC int     AdvResetSB(ADV_DVC_VAR *asc_dvc);
 
@@ -3130,10 +3270,13 @@
 STATIC void   AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
 STATIC int    AdvInitFrom3550EEP(ADV_DVC_VAR *);
 STATIC int    AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
+STATIC int    AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
 STATIC ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
 STATIC void   AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
 STATIC ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
 STATIC void   AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
+STATIC ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
+STATIC void   AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
 STATIC void   AdvWaitEEPCmd(AdvPortAddr);
 STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
 
@@ -3143,71 +3286,9 @@
 #define AscPCICmdRegBits_BusMastering     0x0007
 #define AscPCICmdRegBits_ParErrRespCtrl   0x0040
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
-
 /* Read byte from a register. */
 #define AdvReadByteRegister(iop_base, reg_off) \
-    (inp((iop_base) + (reg_off)))
-
-/* Write byte to a register. */
-#define AdvWriteByteRegister(iop_base, reg_off, byte) \
-    (outp((iop_base) + (reg_off), (byte)))
-
-/* Read word (2 bytes) from a register. */
-#define AdvReadWordRegister(iop_base, reg_off) \
-    (le16_to_cpu(inpw((iop_base) + (reg_off))))
-
-/* Write word (2 bytes) to a register. */
-#define AdvWriteWordRegister(iop_base, reg_off, word) \
-    (outpw((iop_base) + (reg_off), cpu_to_le16(word)))
-
-/* Read byte from LRAM. */
-#define AdvReadByteLram(iop_base, addr, byte) \
-do { \
-    outpw((iop_base) + IOPW_RAM_ADDR, (addr)); \
-    (byte) = inp((iop_base) + IOPB_RAM_DATA); \
-} while (0)
-
-/* Write byte to LRAM. */
-#define AdvWriteByteLram(iop_base, addr, byte) \
-    (outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
-     outp((iop_base) + IOPB_RAM_DATA, (byte)))
-
-/* Read word (2 bytes) from LRAM. */
-#define AdvReadWordLram(iop_base, addr, word) \
-do { \
-    outpw((iop_base) + IOPW_RAM_ADDR, (addr));  \
-    (word) = le16_to_cpu(inpw((iop_base) + IOPW_RAM_DATA)); \
-} while (0)
-
-/* Write word (2 bytes) to LRAM. */
-#define AdvWriteWordLram(iop_base, addr, word) \
-    (outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
-     outpw((iop_base) + IOPW_RAM_DATA, cpu_to_le16(word)))
-
-/* Write double word (4 bytes) to LRAM */
-/* Because of unspecified C language ordering don't use auto-increment. */
-#define AdvWriteDWordLram(iop_base, addr, dword) \
-    ((outpw((iop_base) + IOPW_RAM_ADDR, (addr)), \
-      outpw((iop_base) + IOPW_RAM_DATA, \
-        cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
-     (outpw((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
-      outpw((iop_base) + IOPW_RAM_DATA, \
-        cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
-
-/* Read word (2 bytes) from LRAM assuming that the address is already set. */
-#define AdvReadWordAutoIncLram(iop_base) \
-     (le16_to_cpu(inpw((iop_base) + IOPW_RAM_DATA)))
-
-/* Write word (2 bytes) to LRAM assuming that the address is already set. */
-#define AdvWriteWordAutoIncLram(iop_base, word) \
-     (outpw((iop_base) + IOPW_RAM_DATA, cpu_to_le16(word)))
-
-#else /* version >= v1,3,0 */
-
-/* Read byte from a register. */
-#define AdvReadByteRegister(iop_base, reg_off) \
-     (ADV_MEM_READB((iop_base) + (reg_off)))
+     (ADV_MEM_READB((iop_base) + (reg_off)))
 
 /* Write byte to a register. */
 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
@@ -3215,11 +3296,15 @@
 
 /* Read word (2 bytes) from a register. */
 #define AdvReadWordRegister(iop_base, reg_off) \
-     le16_to_cpu(ADV_MEM_READW((iop_base) + (reg_off)))
+     (ADV_MEM_READW((iop_base) + (reg_off)))
 
 /* Write word (2 bytes) to a register. */
 #define AdvWriteWordRegister(iop_base, reg_off, word) \
-     (ADV_MEM_WRITEW((iop_base) + (reg_off), cpu_to_le16(word)))
+     (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
+
+/* Write dword (4 bytes) to a register. */
+#define AdvWriteDWordRegister(iop_base, reg_off, dword) \
+     (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
 
 /* Read byte from LRAM. */
 #define AdvReadByteLram(iop_base, addr, byte) \
@@ -3237,17 +3322,17 @@
 #define AdvReadWordLram(iop_base, addr, word) \
 do { \
     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
-    (word) = le16_to_cpu(ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
+    (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
 } while (0)
 
 /* Write word (2 bytes) to LRAM. */
 #define AdvWriteWordLram(iop_base, addr, word) \
     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
-     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, cpu_to_le16(word)))
+     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
 
-/* Write double word (4 bytes) to LRAM */
+/* Write little-endian double word (4 bytes) to LRAM */
 /* Because of unspecified C language ordering don't use auto-increment. */
-#define AdvWriteDWordLram(iop_base, addr, dword) \
+#define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
     ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
                      cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
@@ -3257,13 +3342,12 @@
 
 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
 #define AdvReadWordAutoIncLram(iop_base) \
-     le16_to_cpu(ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
+     (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
 
 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
 #define AdvWriteWordAutoIncLram(iop_base, word) \
-     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, cpu_to_le16(word)))
+     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
 
-#endif /* version >= v1,3,0 */
 
 /*
  * Define macro to check for Condor signature.
@@ -3288,7 +3372,7 @@
 /*
  * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
  * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
- * 
+ *
  * If the request has not yet been sent to the device it will simply be
  * aborted from RISC memory. If the request is disconnected it will be
  * aborted on reselection by sending an Abort Message to the target ID.
@@ -3376,6 +3460,7 @@
  */
 extern ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
 extern ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
+extern ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
 
 /*
  * DvcGetPhyAddr() flag arguments
@@ -3388,8 +3473,9 @@
 #define ADV_IS_CARRIER_FLAG     0x20 /* 'addr' is ADV_CARR_T pointer */
 
 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
-#define ADV_DWALIGN(addr)       (((ulong) (addr) + 0x3) & ~0x3)
+#define ADV_8BALIGN(addr)      (((ulong) (addr) + 0x7) & ~0x7)
 #define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
+#define ADV_32BALIGN(addr)     (((ulong) (addr) + 0x1F) & ~0x1F)
 
 /*
  * Total contiguous memory needed for driver SG blocks.
@@ -3399,50 +3485,76 @@
  * single request.
  */
 
-#ifndef ADV_MAX_SG_LIST
-Forced Error: Driver must define ADV_MAX_SG_LIST.
-#endif /* ADV_MAX_SG_LIST */
-
 #define ADV_SG_LIST_MAX_BYTE_SIZE \
          (sizeof(ADV_SG_BLOCK) * \
           ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
 
+/*
+ * Inquiry data structure and bitfield macros
+ *
+ * Using bitfields to access the subchar data isn't portable across
+ * endianness, so instead mask and shift. Only quantities of more
+ * than 1 bit are shifted, since the others are just tested for true
+ * or false.
+ */
+
+#define ADV_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
+#define ADV_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
+#define ADV_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
+#define ADV_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
+#define ADV_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
+#define ADV_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
+#define ADV_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
+#define ADV_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
+#define ADV_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
+#define ADV_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
+#define ADV_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
+#define ADV_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
+#define ADV_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
+#define ADV_INQ_SYNC(inq)           ((inq)->flags & 0x10)
+#define ADV_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
+#define ADV_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
+#define ADV_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
+#define ADV_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
+#define ADV_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
+#define ADV_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
+
 typedef struct {
-  uchar peri_dvc_type   : 5;    /* peripheral device type */
-  uchar peri_qualifier  : 3;    /* peripheral qualifier */
-  uchar dvc_type_modifier : 7;  /* device type modifier (for SCSI I) */
-  uchar rmb      : 1;           /* RMB - removable medium bit */
-  uchar ansi_apr_ver : 3;       /* ANSI approved version */
-  uchar ecma_ver : 3;           /* ECMA version */
-  uchar iso_ver  : 2;           /* ISO version */
-  uchar rsp_data_fmt : 4;       /* response data format */
+  uchar periph;                 /* peripheral device type [0:4] */
+                                /* peripheral qualifier [5:7] */
+  uchar devtype;                /* device type modifier (for SCSI I) [0:6] */
+                                /* RMB - removable medium bit [7] */
+  uchar ver;                    /* ANSI approved version [0:2] */
+                                /* ECMA version [3:5] */
+                                /* ISO version [6:7] */
+  uchar byte3;                  /* response data format [0:3] */
                                 /* 0 SCSI 1 */
                                 /* 1 CCS */
                                 /* 2 SCSI-2 */
                                 /* 3-F reserved */
-  uchar res1     : 2;           /* reserved */
-  uchar TemIOP   : 1;           /* terminate I/O process bit (see 5.6.22) */
-  uchar aenc     : 1;           /* asynch. event notification (processor) */
+                                /* reserved [4:5] */
+                                /* terminate I/O process bit (see 5.6.22) [6] */
+                                /* asynch. event notification (processor) [7] */
   uchar add_len;                /* additional length */
+  uchar res1;                   /* reserved */
   uchar res2;                   /* reserved */
-  uchar res3;                   /* reserved */
-  uchar StfRe   : 1;            /* soft reset implemented */
-  uchar CmdQue  : 1;            /* command queuing */
-  uchar res4    : 1;            /* reserved */
-  uchar Linked  : 1;            /* linked command for this logical unit */
-  uchar Sync    : 1;            /* synchronous data transfer */
-  uchar WBus16  : 1;            /* wide bus 16 bit data transfer */
-  uchar WBus32  : 1;            /* wide bus 32 bit data transfer */
-  uchar RelAdr  : 1;            /* relative addressing mode */
+  uchar flags;                  /* soft reset implemented [0] */
+                                /* command queuing [1] */
+                                /* reserved [2] */
+                                /* linked command for this logical unit [3] */
+                                /* synchronous data transfer [4] */
+                                /* wide bus 16 bit data transfer [5] */
+                                /* wide bus 32 bit data transfer [6] */
+                                /* relative addressing mode [7] */
   uchar vendor_id[8];           /* vendor identification */
   uchar product_id[16];         /* product identification */
   uchar product_rev_level[4];   /* product revision level */
   uchar vendor_specific[20];    /* vendor specific */
-  uchar IUS      : 1;           /* information unit supported */
-  uchar QAS      : 1;           /* quick arbitrate supported */
-  uchar Clocking : 2;           /* clocking field */
-  uchar res5     : 4;           /* reserved */
-  uchar res6;                   /* reserved */
+  uchar info;                   /* information unit supported [0] */
+                                /* quick arbitrate supported [1] */
+                                /* clocking field [2:3] */
+                                /* reserved [4:7] */
+  uchar res3;                   /* reserved */
 } ADV_SCSI_INQUIRY; /* 58 bytes */
 
 
@@ -3459,7 +3571,6 @@
 
 /* asc_board_t flags */
 #define ASC_HOST_IN_RESET       0x01
-#define ASC_HOST_IN_ABORT       0x02
 #define ASC_IS_WIDE_BOARD       0x04    /* AdvanSys Wide Board */
 #define ASC_SELECT_QUEUE_DEPTHS 0x08
 
@@ -3473,22 +3584,17 @@
  * and data after loading, define macros for this purpose. These macros
  * are not used when the driver is built as a module, cf. linux/init.h.
  */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,23)
-#define ASC_INITFUNC(type, func)        type func
-#define ASC_INITDATA
-#define ASC_INIT
-#else /* version >= v2.1.23 */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,16)
-#define ASC_INITFUNC(type, func)        __initfunc(type func)
-#else /* version >= v2.3.16 */
+#if ASC_LINUX_KERNEL24
 #define ASC_INITFUNC(type, func)        type __init func
-#endif /* version >= v2.3.16 */
+#elif ASC_LINUX_KERNEL22
+#define ASC_INITFUNC(type, func)        __initfunc(type func)
+#endif
 #define ASC_INITDATA                    __initdata
 #define ASC_INIT                        __init
-#endif /* version >= v2.1.23 */
 
 #define ASC_INFO_SIZE           128            /* advansys_info() line size */
 
+#ifdef CONFIG_PROC_FS
 /* /proc/scsi/advansys/[0...] related definitions */
 #define ASC_PRTBUF_SIZE         2048
 #define ASC_PRTLINE_SIZE        160
@@ -3504,6 +3610,37 @@
     }
 
 #define ASC_MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif /* CONFIG_PROC_FS */
+
+/*
+ * XXX - Release and acquire the io_request_lock. These macros are needed
+ * because the 2.4 kernel SCSI mid-level driver holds the 'io_request_lock'
+ * on entry to SCSI low-level drivers.
+ *
+ * These definitions and all code that uses code should be removed when the
+ * SCSI mid-level driver no longer holds the 'io_request_lock' on entry to
+ * SCSI low-level driver detect, queuecommand, and reset entrypoints.
+ *
+ * The interrupt flags values doesn't matter in the macros because the
+ * SCSI mid-level will save and restore the flags values before and after
+ * calling advansys_detect, advansys_queuecommand, and advansys_reset where
+ * these macros are used. We do want interrupts enabled after the lock is
+ * released so an explicit sti() is done. The driver only needs interrupts
+ * disabled when it acquires the per board lock.
+ */
+#define ASC_UNLOCK_IO_REQUEST_LOCK \
+    { \
+        ulong flags; /* flags value not needed, cf. comment above. */ \
+        save_flags(flags); \
+        spin_unlock_irqrestore(&io_request_lock, flags); \
+        sti(); /* enable interrupts */ \
+    }
+
+#define ASC_LOCK_IO_REQUEST_LOCK \
+    { \
+        ulong flags; /* flags value not needed, cf. comment above. */ \
+        spin_lock_irqsave(&io_request_lock, flags); \
+    }
 
 /* Asc Library return codes */
 #define ASC_TRUE        1
@@ -3627,12 +3764,13 @@
 #define PCI_MAX_BUS             0xFF
 #define PCI_IOADDRESS_MASK      0xFFFE
 #define ASC_PCI_VENDORID        0x10CD
-#define ASC_PCI_DEVICE_ID_CNT   5       /* PCI Device ID count. */
+#define ASC_PCI_DEVICE_ID_CNT   6       /* PCI Device ID count. */
 #define ASC_PCI_DEVICE_ID_1100  0x1100
 #define ASC_PCI_DEVICE_ID_1200  0x1200
 #define ASC_PCI_DEVICE_ID_1300  0x1300
 #define ASC_PCI_DEVICE_ID_2300  0x2300  /* ASC-3550 */
 #define ASC_PCI_DEVICE_ID_2500  0x2500  /* ASC-38C0800 */
+#define ASC_PCI_DEVICE_ID_2700  0x2700  /* ASC-38C1600 */
 
 /* PCI IO Port Addresses to generate special cycle */
 
@@ -3843,10 +3981,8 @@
 /* Per board statistics structure */
 struct asc_stats {
     /* Driver Entrypoint Statistics */
-    ADV_DCNT command;         /* # calls to advansys_command() */
     ADV_DCNT queuecommand;    /* # calls to advansys_queuecommand() */
-    ADV_DCNT abort;           /* # calls to advansys_abort() */
-    ADV_DCNT reset;           /* # calls to advansys_reset() */
+    ADV_DCNT reset;           /* # calls to advansys_eh_bus_reset() */
     ADV_DCNT biosparam;       /* # calls to advansys_biosparam() */
     ADV_DCNT interrupt;       /* # advansys_interrupt() calls */
     ADV_DCNT callback;        /* # calls to asc/adv_isr_callback() */
@@ -3899,16 +4035,18 @@
  * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
  * up to 255 scatter-gather elements may be used per request or
  * ADV_SCSI_REQ_Q.
+ *
+ * Both structures must be 32 byte aligned.
  */
 typedef struct adv_sgblk {
-    ADV_SG_BLOCK        sg_block;        /* Sgblock structure. */
-    uchar               align2[4];       /* Sgblock structure padding. */
-    struct adv_sgblk    *next_sgblkp;    /* Next scatter-gather structure. */
+    ADV_SG_BLOCK        sg_block;     /* Sgblock structure. */
+    uchar               align[32];    /* Sgblock structure padding. */
+    struct adv_sgblk    *next_sgblkp; /* Next scatter-gather structure. */
 } adv_sgblk_t;
 
 typedef struct adv_req {
     ADV_SCSI_REQ_Q      scsi_req_q;   /* Adv Library request structure. */
-    uchar               align1[4];    /* Request structure padding. */
+    uchar               align[32];    /* Request structure padding. */
     Scsi_Cmnd           *cmndp;       /* Mid-Level SCSI command pointer. */
     adv_sgblk_t         *sgblkp;      /* Adv Library scatter-gather pointer. */
     struct adv_req      *next_reqp;   /* Next Request Structure. */
@@ -3932,6 +4070,7 @@
         ASC_DVC_CFG      asc_dvc_cfg;           /* Narrow board */
         ADV_DVC_CFG      adv_dvc_cfg;           /* Wide board */
     } dvc_cfg;
+    ushort               asc_n_io_port;         /* Number I/O ports. */
     asc_queue_t          active;                /* Active command queue */
     asc_queue_t          waiting;               /* Waiting command queue */
     asc_queue_t          done;                  /* Done command queue */
@@ -3944,12 +4083,14 @@
         ASCEEP_CONFIG         asc_eep;          /* Narrow EEPROM config. */
         ADVEEP_3550_CONFIG    adv_3550_eep;     /* 3550 EEPROM config. */
         ADVEEP_38C0800_CONFIG adv_38C0800_eep;  /* 38C0800 EEPROM config. */
+        ADVEEP_38C1600_CONFIG adv_38C1600_eep;  /* 38C1600 EEPROM config. */
     } eep_config;
     ulong                last_reset;            /* Saved last reset time */
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+    spinlock_t lock;                            /* Board spinlock */
+#ifdef CONFIG_PROC_FS
     /* /proc/scsi/advansys/[0...] */
-    char                 *prtbuf;               /* Statistics Print Buffer */
-#endif /* version >= v1.3.0 */
+    char                 *prtbuf;               /* /proc print buffer */
+#endif /* CONFIG_PROC_FS */
 #ifdef ADVANSYS_STATS
     struct asc_stats     asc_stats;             /* Board statistics */
 #endif /* ADVANSYS_STATS */
@@ -4032,8 +4173,8 @@
 
 /* Note: All driver global data should be initialized. */
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,28) && \
-    LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+#if ASC_LINUX_KERNEL22
+#ifdef CONFIG_PROC_FS
 struct proc_dir_entry proc_scsi_advansys =
 {
     PROC_SCSI_ADVANSYS,              /* unsigned short low_ino */
@@ -4042,13 +4183,14 @@
     S_IFDIR | S_IRUGO | S_IXUGO,     /* mode_t mode */
     2                                /* nlink_t nlink */
 };
-#endif /* v2.3.28 > version >= v1.3.0 */
+#endif /* CONFIG_PROC_FS */
+#endif /* ASC_LINUX_KERNEL22 */
 
 /* Number of boards detected in system. */
 STATIC int asc_board_count = 0;
 STATIC struct Scsi_Host    *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
 
-/* Overrun buffer shared between all boards. */
+/* Overrun buffer used by all narrow boards. */
 STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
 
 /*
@@ -4065,12 +4207,6 @@
     ASC_IS_PCI,
 };
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-STATIC int pci_scan_method ASC_INITDATA = -1;
-#endif /* ASC_CONFIG_PCI */
-#endif /* version < v2.1.93 */
-
 /*
  * Used with the LILO 'advansys' option to eliminate or
  * limit I/O port probing at boot time, cf. advansys_setup().
@@ -4078,19 +4214,6 @@
 STATIC int asc_iopflag = ASC_FALSE;
 STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
-/*
- * In kernels earlier than v1.3.0, kmalloc() does not work
- * during driver initialization. Therefore statically declare
- * 16 elements of each structure. v1.3.0 kernels will probably
- * not need any more than this number.
- */
-uchar adv_carr_buf[20 * sizeof(ADV_CARR_T)] = { 0 };
-uchar adv_req_buf[16 * sizeof(adv_req_t)] = { 0 };
-#define ADV_SGBLK_BUF_CNT       32
-uchar adv_sgblk_buf[ADV_SGBLK_BUF_CNT * sizeof(adv_sgblk_t)] = { 0 };
-#endif /* version >= v1,3,0 */
-
 #ifdef ADVANSYS_DEBUG
 STATIC char *
 asc_bus_name[ASC_NUM_BUS] = {
@@ -4100,7 +4223,7 @@
     "ASC_IS_PCI",
 };
 
-STATIC int          asc_dbglvl = 2;
+STATIC int          asc_dbglvl = 3;
 #endif /* ADVANSYS_DEBUG */
 
 /* Declaration for Asc Library internal data referenced by driver. */
@@ -4113,19 +4236,9 @@
  * advansys.h contains function prototypes for functions global to Linux.
  */
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
-STATIC int          asc_proc_copy(off_t, off_t, char *, int , char *, int);
-#endif /* version >= v1.3.0 */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
-STATIC void         advansys_interrupt(int, struct pt_regs *);
-#else /* version >= v1.3.70 */
-STATIC void         advansys_interrupt(int, void *, struct pt_regs *);
-#endif /* version >= v1.3.70 */
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-STATIC void         advansys_select_queue_depths(struct Scsi_Host *,
-                                                Scsi_Device *);
-#endif /* version >= v1.3.89 */
-STATIC void       advansys_command_done(Scsi_Cmnd *);
+STATIC void       advansys_interrupt(int, void *, struct pt_regs *);
+STATIC void       advansys_select_queue_depths(struct Scsi_Host *,
+                                               Scsi_Device *);
 STATIC void       asc_scsi_done_list(Scsi_Cmnd *);
 STATIC int        asc_execute_scsi_cmnd(Scsi_Cmnd *);
 STATIC int        asc_build_req(asc_board_t *, Scsi_Cmnd *);
@@ -4134,24 +4247,13 @@
 STATIC void       asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
 STATIC void       adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
 STATIC void       adv_async_callback(ADV_DVC_VAR *, uchar);
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-STATIC int        asc_srch_pci_dev(PCI_DEVICE *);
-STATIC uchar      asc_scan_method(void);
-STATIC int        asc_pci_find_dev(PCI_DEVICE *);
-STATIC void       asc_get_pci_cfg(PCI_DEVICE *, PCI_CONFIG_SPACE *);
-STATIC ushort     asc_get_cfg_word(PCI_DATA *);
-STATIC uchar      asc_get_cfg_byte(PCI_DATA *);
-STATIC void       asc_put_cfg_byte(PCI_DATA *, uchar);
-#endif /* ASC_CONFIG_PCI */
-#endif /* version < v2.1.93 */
 STATIC void       asc_enqueue(asc_queue_t *, REQP, int);
 STATIC REQP       asc_dequeue(asc_queue_t *, int);
 STATIC REQP       asc_dequeue_list(asc_queue_t *, REQP *, int);
 STATIC int        asc_rmqueue(asc_queue_t *, REQP);
-STATIC int        asc_isqueued(asc_queue_t *, REQP);
 STATIC void       asc_execute_queue(asc_queue_t *);
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+#ifdef CONFIG_PROC_FS
+STATIC int        asc_proc_copy(off_t, off_t, char *, int , char *, int);
 STATIC int        asc_prt_board_devices(struct Scsi_Host *, char *, int);
 STATIC int        asc_prt_adv_bios(struct Scsi_Host *, char *, int);
 STATIC int        asc_get_eeprom_string(ushort *serialnum, uchar *cp);
@@ -4161,16 +4263,21 @@
 STATIC int        asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
 STATIC int        asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
 STATIC int        asc_prt_line(char *, int, char *fmt, ...);
-#endif /* version >= v1.3.0 */
+#endif /* CONFIG_PROC_FS */
 
 /* Declaration for Asc Library internal functions referenced by driver. */
 STATIC int          AscFindSignature(PortAddr);
 STATIC ushort       AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
 
+/* Statistics function prototypes. */
 #ifdef ADVANSYS_STATS
+#ifdef CONFIG_PROC_FS
 STATIC int          asc_prt_board_stats(struct Scsi_Host *, char *, int);
+STATIC int          asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
+#endif /* CONFIG_PROC_FS */
 #endif /* ADVANSYS_STATS */
 
+/* Debug function prototypes. */
 #ifdef ADVANSYS_DEBUG
 STATIC void         asc_prt_scsi_host(struct Scsi_Host *);
 STATIC void         asc_prt_scsi_cmnd(Scsi_Cmnd *);
@@ -4185,16 +4292,12 @@
 STATIC void         asc_prt_hex(char *f, uchar *, int);
 #endif /* ADVANSYS_DEBUG */
 
-#ifdef ADVANSYS_ASSERT
-STATIC int             advansys_interrupts_enabled(void);
-#endif /* ADVANSYS_ASSERT */
-
 
 /*
  * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
  */
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+#ifdef CONFIG_PROC_FS
 /*
  * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
  *
@@ -4216,10 +4319,9 @@
  * user just won't get all the available statistics.
  */
 int
-advansys_proc_info(char *buffer, char **start, off_t offset, int length, 
+advansys_proc_info(char *buffer, char **start, off_t offset, int length,
                    int hostno, int inout)
 {
-#ifdef CONFIG_PROC_FS
     struct Scsi_Host    *shp;
     asc_board_t         *boardp;
     int                 i;
@@ -4231,6 +4333,9 @@
     char                *curbuf;
     off_t               advoffset;
     Scsi_Device         *scd;
+#ifdef ADVANSYS_STATS
+    int                 tgt_id;
+#endif /* ADVANSYS_STATS */
 
     ASC_DBG(1, "advansys_proc_info: begin\n");
 
@@ -4322,11 +4427,7 @@
      * Display target driver information for each device attached
      * to the board.
      */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,75)
-    for (scd = scsi_devices; scd; scd = scd->next)
-#else /* version >= v2.1.75 */
     for (scd = shp->host_queue; scd; scd = scd->next)
-#endif /* version >= v2.1.75 */
     {
         if (scd->host == shp) {
             cp = boardp->prtbuf;
@@ -4347,7 +4448,7 @@
             curbuf += cnt;
         }
     }
-    
+
     /*
      * Display EEPROM configuration for the board.
      */
@@ -4390,7 +4491,7 @@
      */
     cp = boardp->prtbuf;
     cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
-    ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
+    ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
     totcnt += cnt;
     leftlen -= cnt;
@@ -4400,6 +4501,24 @@
     }
     advoffset += cplen;
     curbuf += cnt;
+
+    /*
+     * Display driver statistics for each target.
+     */
+    for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
+      cp = boardp->prtbuf;
+      cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE);
+      ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
+      cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
+      totcnt += cnt;
+      leftlen -= cnt;
+      if (leftlen == 0) {
+        ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
+        return totcnt;
+      }
+      advoffset += cplen;
+      curbuf += cnt;
+    }
 #endif /* ADVANSYS_STATS */
 
     /*
@@ -4426,11 +4545,8 @@
     ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
 
     return totcnt;
-#else /* CONFIG_PROC_FS */
-    return 0;
-#endif /* CONFIG_PROC_FS */
 }
-#endif /* version >= v1.3.0 */
+#endif /* CONFIG_PROC_FS */
 
 /*
  * advansys_detect()
@@ -4461,19 +4577,6 @@
     int                 ioport = 0;
     int                 share_irq = FALSE;
     int                 iolen = 0;
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-    int                 pci_init_search = 0;
-    PCI_DEVICE          pci_device[ASC_NUM_BOARD_SUPPORTED];
-    int                 pci_card_cnt_max = 0;
-    int                 pci_card_cnt = 0;
-    PCI_DEVICE          pciDevice;
-    PCI_CONFIG_SPACE    pciConfig;
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
-    ADV_PADDR           pci_memory_address;
-#endif /* version >= v1,3,0 */
-#endif /* ASC_CONFIG_PCI */
-#else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
     int                 pci_init_search = 0;
     struct pci_dev      *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
@@ -4486,11 +4589,11 @@
                                     ASC_PCI_DEVICE_ID_1200,
                                     ASC_PCI_DEVICE_ID_1300,
                                     ASC_PCI_DEVICE_ID_2300,
-                                    ASC_PCI_DEVICE_ID_2500
+                                    ASC_PCI_DEVICE_ID_2500,
+                                    ASC_PCI_DEVICE_ID_2700
                         };
     ADV_PADDR           pci_memory_address;
 #endif /* CONFIG_PCI */
-#endif /* version >= v2.1.93 */ 
     int                 warn_code, err_code;
     int                 ret;
 
@@ -4503,11 +4606,18 @@
 
     ASC_DBG(1, "advansys_detect: begin\n");
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,28)
+    /*
+     * XXX - Remove this comment and the next line when SCSI mid-level
+     * no longer acquires 'io_request_lock' before calling the SCSI
+     * low-level detect entrypoint.
+     */
+    ASC_UNLOCK_IO_REQUEST_LOCK
+
+#if ASC_LINUX_KERNEL24
     tpnt->proc_name = "advansys";
-#elif LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+#elif ASC_LINUX_KERNEL22
     tpnt->proc_dir = &proc_scsi_advansys;
-#endif /* version >= v1.3.0 */
+#endif
 
     asc_board_count = 0;
 
@@ -4517,7 +4627,7 @@
      */
     if (asc_iopflag == ASC_TRUE) {
         for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
-            ASC_DBG2(1, "advansys_detect: asc_ioport[%d] %x\n",
+            ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
                 ioport, asc_ioport[ioport]);
             if (asc_ioport[ioport] != 0) {
                 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
@@ -4536,15 +4646,6 @@
         ioport = 0;
     }
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-    memset(&pciDevice, 0, sizeof(PCI_DEVICE));
-    memset(&pciConfig, 0, sizeof(PCI_CONFIG_SPACE));
-    pciDevice.maxBusNumber = PCI_MAX_BUS;
-    pciDevice.endSlot = PCI_MAX_SLOT;
-#endif /* ASC_CONFIG_PCI */
-#endif /* version < v2.1.93 */ 
-
     for (bus = 0; bus < ASC_NUM_BUS; bus++) {
 
         ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
@@ -4559,6 +4660,7 @@
             switch (asc_bus[bus]) {
             case ASC_IS_ISA:
             case ASC_IS_VL:
+#ifdef CONFIG_ISA
                 if (asc_iopflag == ASC_FALSE) {
                     iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
                 } else {
@@ -4577,7 +4679,8 @@
                         }
                     }
                     if (iop) {
-                        ASC_DBG1(1, "advansys_detect: probing I/O port %x...\n",
+                        ASC_DBG1(1,
+                                "advansys_detect: probing I/O port 0x%x...\n",
                             iop);
                         if (check_region(iop, ASC_IOADR_GAP) != 0) {
                             printk(
@@ -4618,74 +4721,16 @@
                         asc_ioport[ioport++] = 0;
                     }
                 }
+#endif /* CONFIG_ISA */
                 break;
 
             case ASC_IS_EISA:
+#ifdef CONFIG_ISA
                 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
+#endif /* CONFIG_ISA */
                 break;
 
             case ASC_IS_PCI:
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-                if (pci_init_search == 0) {
-                    int i, j;
-
-                    pci_init_search = 1;
-
-                    /* Find all PCI cards. */
-                    while (asc_srch_pci_dev(&pciDevice) == PCI_DEVICE_FOUND) {
-                        pci_device[pci_card_cnt_max++] = pciDevice;
-                    }
-
-                    /*
-                     * Sort PCI cards in ascending order by PCI Bus, Slot,
-                     * and Device Number.
-                     */
-                    for (i = 0; i < pci_card_cnt_max - 1; i++)
-                    {
-                        for (j = i + 1; j < pci_card_cnt_max; j++) {
-                            if ((pci_device[j].busNumber <
-                                 pci_device[i].busNumber) ||
-                                ((pci_device[j].busNumber ==
-                                  pci_device[i].busNumber) &&
-                                  (pci_device[j].slotNumber <
-                                   pci_device[i].slotNumber)) ||
-                                ((pci_device[j].busNumber ==
-                                  pci_device[i].busNumber) &&
-                                  (pci_device[j].slotNumber ==
-                                   pci_device[i].slotNumber) &&
-                                  (pci_device[j].devFunc <
-                                   pci_device[i].devFunc))) {
-                                pciDevice = pci_device[i];
-                                pci_device[i] = pci_device[j];
-                                pci_device[j] = pciDevice;
-                            }
-                        }
-                    }
-
-                    pci_card_cnt = 0;
-                } else {
-                    pci_card_cnt++;
-                }
-
-                if (pci_card_cnt == pci_card_cnt_max) {
-                    iop = 0;
-                } else {
-                    pciDevice = pci_device[pci_card_cnt];
-                    ASC_DBG2(2,
-                        "advansys_detect: slotFound %d, busNumber %d\n",
-                        pciDevice.slotFound, pciDevice.busNumber);
-                    asc_get_pci_cfg(&pciDevice, &pciConfig);
-                    iop = pciConfig.baseAddress[0] & PCI_IOADDRESS_MASK;
-                    ASC_DBG2(1,
-                        "advansys_detect: vendorID %X, deviceID %X\n",
-                        pciConfig.vendorID, pciConfig.deviceID);
-                    ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
-                        iop, pciConfig.irqLine);
-                }
-                break;
-#endif /* ASC_CONFIG_PCI */
-#else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
                 if (pci_init_search == 0) {
                     int i, j;
@@ -4699,8 +4744,13 @@
                             NULL) {
                             pci_device_id_cnt++;
                         } else {
-			    if (pci_enable_device(pci_devp) == 0)
-                            	pci_devicep[pci_card_cnt_max++] = pci_devp;
+#if ASC_LINUX_KERNEL24
+                            if (pci_enable_device(pci_devp) == 0) {
+                                pci_devicep[pci_card_cnt_max++] = pci_devp;
+                            }
+#elif ASC_LINUX_KERNEL22
+                            pci_devicep[pci_card_cnt_max++] = pci_devp;
+#endif
                         }
                     }
 
@@ -4737,11 +4787,11 @@
                     ASC_DBG2(2,
                         "advansys_detect: devfn %d, bus number %d\n",
                         pci_devp->devfn, pci_devp->bus->number);
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,13)
-                    iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK;
-#else /* version >= v2.3.13 */ 
+#if ASC_LINUX_KERNEL24
                     iop = pci_resource_start(pci_devp, 0);
-#endif /* version >= v2.3.13 */ 
+#elif ASC_LINUX_KERNEL22
+                    iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK;
+#endif
                     ASC_DBG2(1,
                         "advansys_detect: vendorID %X, deviceID %X\n",
                         pci_devp->vendor, pci_devp->device);
@@ -4749,7 +4799,6 @@
                         iop, pci_devp->irq);
                 }
 #endif /* CONFIG_PCI */
-#endif /* version >= v2.1.93 */ 
                 break;
 
             default:
@@ -4757,7 +4806,7 @@
                     asc_bus[bus]);
                 break;
             }
-            ASC_DBG1(1, "advansys_detect: iop %x\n", iop);
+            ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
 
             /*
              * Adapter not found, try next bus type.
@@ -4774,9 +4823,10 @@
              */
             ASC_DBG(2, "advansys_detect: scsi_register()\n");
             shp = scsi_register(tpnt, sizeof(asc_board_t));
-            
-            if(shp==NULL)
-            	continue;
+
+            if (shp == NULL) {
+                continue;
+            }
 
             /* Save a pointer to the Scsi_host of each board found. */
             asc_host[asc_board_count++] = shp;
@@ -4786,6 +4836,9 @@
             memset(boardp, 0, sizeof(asc_board_t));
             boardp->id = asc_board_count - 1;
 
+            /* Initialize spinlock. */
+            boardp->lock = SPIN_LOCK_UNLOCKED;
+
             /*
              * Handle both narrow and wide boards.
              *
@@ -4793,25 +4846,15 @@
              * wide board flag. Set-up the board structure based on
              * the board type.
              */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-            if (asc_bus[bus] == ASC_IS_PCI &&
-                (pciConfig.deviceID == ASC_PCI_DEVICE_ID_2300 ||
-                 pciConfig.deviceID == ASC_PCI_DEVICE_ID_2500))
-            {
-                boardp->flags |= ASC_IS_WIDE_BOARD;
-            }
-#endif /* ASC_CONFIG_PCI */
-#else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
             if (asc_bus[bus] == ASC_IS_PCI &&
                 (pci_devp->device == ASC_PCI_DEVICE_ID_2300 ||
-                 pci_devp->device == ASC_PCI_DEVICE_ID_2500))
+                 pci_devp->device == ASC_PCI_DEVICE_ID_2500 ||
+                 pci_devp->device == ASC_PCI_DEVICE_ID_2700))
             {
                 boardp->flags |= ASC_IS_WIDE_BOARD;
             }
 #endif /* CONFIG_PCI */
-#endif /* version >= v2.1.93 */ 
 
             if (ASC_NARROW_BOARD(boardp)) {
                 ASC_DBG(1, "advansys_detect: narrow board\n");
@@ -4829,36 +4872,22 @@
                 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
                 adv_dvc_varp->isr_callback = adv_isr_callback;
                 adv_dvc_varp->async_callback = adv_async_callback;
-
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-                if (pciConfig.deviceID == ASC_PCI_DEVICE_ID_2300)
-                {
-                    ASC_DBG(1, "advansys_detect: ASC-3550\n");
-                    adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
-                } else
-                {
-                    ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
-                    adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
-                }
-#endif /* ASC_CONFIG_PCI */
-#else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
                 if (pci_devp->device == ASC_PCI_DEVICE_ID_2300)
                 {
                     ASC_DBG(1, "advansys_detect: ASC-3550\n");
                     adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
-                } else
+                } else if (pci_devp->device == ASC_PCI_DEVICE_ID_2500)
                 {
                     ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
                     adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
+                } else
+                {
+                    ASC_DBG(1, "advansys_detect: ASC-38C1600\n");
+                    adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
                 }
 #endif /* CONFIG_PCI */
-#endif /* version >= v2.1.93 */ 
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
-                adv_dvc_varp->iop_base = iop;
-#else /* version >= v1,3,0 */
                 /*
                  * Map the board's registers into virtual memory for
                  * PCI slave access. Only memory accesses are used to
@@ -4873,76 +4902,53 @@
                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
                 {
                     iolen = ADV_3550_IOLEN;
-                } else {
+                } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
+                {
                     iolen = ADV_38C0800_IOLEN;
+                } else
+                {
+                    iolen = ADV_38C1600_IOLEN;
                 }
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-                pci_memory_address = pciConfig.baseAddress[1];
-                ASC_DBG1(1, "advansys_detect: pci_memory_address: %lu\n",
-                    (ulong) pci_memory_address);
-                if ((boardp->ioremap_addr =
-                    ioremap(pci_memory_address & PAGE_MASK,
-                         PAGE_SIZE)) == 0) {
-                   ASC_PRINT3(
-"advansys_detect: board %d: ioremap(%lu, %x) returned NULL\n",
-                   boardp->id, (ulong) pci_memory_address, iolen);
-                   scsi_unregister(shp);
-                   asc_board_count--;
-                   continue;
-                }
-                ASC_DBG1(1, "advansys_detect: ioremap_addr: %lx\n",
-                    (ulong) boardp->ioremap_addr);
-                adv_dvc_varp->iop_base = (AdvPortAddr)
-                    (boardp->ioremap_addr +
-                     (pci_memory_address - (pci_memory_address & PAGE_MASK)));
-                ASC_DBG1(1, "advansys_detect: iop_base: %lx\n",
-                    adv_dvc_varp->iop_base);
-#endif /* ASC_CONFIG_PCI */
-#else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,13)
-                pci_memory_address = pci_devp->base_address[1];
-#else /* version >= v2.3.13 */ 
+#if ASC_LINUX_KERNEL24
                 pci_memory_address = pci_resource_start(pci_devp, 1);
-#endif /* version >= v2.3.13 */ 
-                ASC_DBG1(1, "advansys_detect: pci_memory_address: %x\n",
-                    pci_memory_address);
+#elif ASC_LINUX_KERNEL22
+                pci_memory_address = pci_devp->base_address[1];
+#endif
+                ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n",
+                    (ulong) pci_memory_address);
                 if ((boardp->ioremap_addr =
                     ioremap(pci_memory_address & PAGE_MASK,
                          PAGE_SIZE)) == 0) {
                    ASC_PRINT3(
 "advansys_detect: board %d: ioremap(%x, %d) returned NULL\n",
-                   boardp->id, pci_memory_address, iolen);
+                       boardp->id, pci_memory_address, iolen);
                    scsi_unregister(shp);
                    asc_board_count--;
                    continue;
                 }
-                ASC_DBG1(1, "advansys_detect: ioremap_addr: %lx\n",
+                ASC_DBG1(1, "advansys_detect: ioremap_addr: 0x%lx\n",
                     (ulong) boardp->ioremap_addr);
                 adv_dvc_varp->iop_base = (AdvPortAddr)
                     (boardp->ioremap_addr +
                      (pci_memory_address - (pci_memory_address & PAGE_MASK)));
-                ASC_DBG1(1, "advansys_detect: iop_base: %lx\n",
+                ASC_DBG1(1, "advansys_detect: iop_base: 0x%lx\n",
                     adv_dvc_varp->iop_base);
 #endif /* CONFIG_PCI */
-#endif /* version >= v2.1.93 */ 
-#endif /* version >= v1,3,0 */
 
                 /*
-                 * Even though it isn't used to access the board in
-                 * kernels greater than or equal to v1.3.0, save
-                 * the I/O Port address so that it can be reported and
-                 * displayed.
+                 * Even though it isn't used to access wide boards, other
+                 * than for the debug line below, save I/O Port address so
+                 * that it can be reported.
                  */
                 boardp->ioport = iop;
 
                 ASC_DBG2(1,
-                    "advansys_detect: iopb_chip_id_1 %x, iopw_chip_id_0 %x\n",
+"advansys_detect: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
                     (ushort) inp(iop + 1), (ushort) inpw(iop));
             }
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+#ifdef CONFIG_PROC_FS
             /*
              * Allocate buffer for printing information from
              * /proc/scsi/advansys/[0...].
@@ -4956,7 +4962,7 @@
                 asc_board_count--;
                 continue;
             }
-#endif /* version >= v1.3.0 */
+#endif /* CONFIG_PROC_FS */
 
             if (ASC_NARROW_BOARD(boardp)) {
                 /*
@@ -4964,6 +4970,7 @@
                  * calling AscInitGetConfig().
                  */
                 switch (asc_dvc_varp->bus_type) {
+#ifdef CONFIG_ISA
                 case ASC_IS_ISA:
                     shp->unchecked_isa_dma = TRUE;
                     share_irq = FALSE;
@@ -4976,20 +4983,7 @@
                     shp->unchecked_isa_dma = FALSE;
                     share_irq = TRUE;
                     break;
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-                case ASC_IS_PCI:
-                    shp->irq = asc_dvc_varp->irq_no = pciConfig.irqLine;
-                    asc_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
-                    asc_dvc_varp->cfg->pci_slot_info =
-                        ASC_PCI_MKID(pciDevice.busNumber,
-                            pciDevice.slotFound,
-                            pciDevice.devFunc);
-                    shp->unchecked_isa_dma = FALSE;
-                    share_irq = TRUE;
-                    break;
-#endif /* ASC_CONFIG_PCI */
-#else /* version >= v2.1.93 */ 
+#endif /* CONFIG_ISA */
 #ifdef CONFIG_PCI
                 case ASC_IS_PCI:
                     shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
@@ -5002,7 +4996,6 @@
                     share_irq = TRUE;
                     break;
 #endif /* CONFIG_PCI */
-#endif /* version >= v2.1.93 */ 
                 default:
                     ASC_PRINT2(
 "advansys_detect: board %d: unknown adapter type: %d\n",
@@ -5016,18 +5009,6 @@
                  * For Wide boards set PCI information before calling
                  * AdvInitGetConfig().
                  */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-                shp->irq = adv_dvc_varp->irq_no = pciConfig.irqLine;
-                adv_dvc_varp->cfg->pci_device_id = pciConfig.deviceID;
-                adv_dvc_varp->cfg->pci_slot_info =
-                    ASC_PCI_MKID(pciDevice.busNumber,
-                        pciDevice.slotFound,
-                        pciDevice.devFunc);
-                shp->unchecked_isa_dma = FALSE;
-                share_irq = TRUE;
-#endif /* ASC_CONFIG_PCI */
-#else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
                 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
                 adv_dvc_varp->cfg->pci_device_id = pci_devp->device;
@@ -5038,7 +5019,6 @@
                 shp->unchecked_isa_dma = FALSE;
                 share_irq = TRUE;
 #endif /* CONFIG_PCI */
-#endif /* version >= v2.1.93 */ 
             }
 
             /*
@@ -5082,33 +5062,33 @@
                     break;
                 default:
                     ASC_PRINT2(
-"AscInitGetConfig: board %d: unknown warning: %x\n",
+"AscInitGetConfig: board %d: unknown warning: 0x%x\n",
                         boardp->id, ret);
                     break;
                 }
                 if ((err_code = asc_dvc_varp->err_code) != 0) {
                     ASC_PRINT3(
-"AscInitGetConfig: board %d error: init_state %x, err_code %x\n",
+"AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
                         boardp->id, asc_dvc_varp->init_state,
                         asc_dvc_varp->err_code);
                 }
             } else {
                 ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
                 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
-                    ASC_PRINT2("AdvInitGetConfig: board %d: warning: %x\n",
+                    ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
                         boardp->id, ret);
                 }
                 if ((err_code = adv_dvc_varp->err_code) != 0) {
                     ASC_PRINT2(
-"AdvInitGetConfig: board %d error: err_code %x\n",
+"AdvInitGetConfig: board %d error: err_code 0x%x\n",
                         boardp->id, adv_dvc_varp->err_code);
                 }
             }
-        
+
             if (err_code != 0) {
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+#ifdef CONFIG_PROC_FS
                 kfree(boardp->prtbuf);
-#endif /* version >= v1.3.0 */
+#endif /* CONFIG_PROC_FS */
                 scsi_unregister(shp);
                 asc_board_count--;
                 continue;
@@ -5136,12 +5116,12 @@
                 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
                 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
                 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
-                ep->isa_dma_speed = asc_dvc_varp->cfg->isa_dma_speed;
+                ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
                 ep->start_motor = asc_dvc_varp->start_motor;
                 ep->cntl = asc_dvc_varp->dvc_cntl;
                 ep->no_scam = asc_dvc_varp->no_scam;
                 ep->max_total_qng = asc_dvc_varp->max_total_qng;
-                ep->chip_scsi_id = asc_dvc_varp->cfg->chip_scsi_id;
+                ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
                 /* 'max_tag_qng' is set to the same value for every device. */
                 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
                 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
@@ -5186,18 +5166,18 @@
                     break;
                 default:
                     ASC_PRINT2(
-"AscInitSetConfig: board %d: unknown warning: %x\n",
+"AscInitSetConfig: board %d: unknown warning: 0x%x\n",
                         boardp->id, ret);
                     break;
                 }
                 if (asc_dvc_varp->err_code != 0) {
                     ASC_PRINT3(
-"AscInitSetConfig: board %d error: init_state %x, err_code %x\n",
+"AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
                         boardp->id, asc_dvc_varp->init_state,
                         asc_dvc_varp->err_code);
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+#ifdef CONFIG_PROC_FS
                     kfree(boardp->prtbuf);
-#endif /* version >= v1.3.0 */
+#endif /* CONFIG_PROC_FS */
                     scsi_unregister(shp);
                     asc_board_count--;
                     continue;
@@ -5213,6 +5193,7 @@
             } else {
                 ADVEEP_3550_CONFIG      *ep_3550;
                 ADVEEP_38C0800_CONFIG   *ep_38C0800;
+                ADVEEP_38C1600_CONFIG   *ep_38C1600;
 
                 /*
                  * Save Wide EEP Configuration Information.
@@ -5239,7 +5220,7 @@
                         adv_dvc_varp->cfg->serial2;
                     ep_3550->serial_number_word3 =
                         adv_dvc_varp->cfg->serial3;
-                } else
+                } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
                 {
                     ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
 
@@ -5266,6 +5247,33 @@
                         adv_dvc_varp->cfg->serial2;
                     ep_38C0800->serial_number_word3 =
                         adv_dvc_varp->cfg->serial3;
+                } else
+                {
+                    ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
+
+                    ep_38C1600->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
+                    ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
+                    ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
+                    ep_38C1600->termination_lvd =
+                        adv_dvc_varp->cfg->termination;
+                    ep_38C1600->disc_enable = adv_dvc_varp->cfg->disc_enable;
+                    ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
+                    ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
+                    ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
+                    ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
+                    ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
+                    ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
+                    ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
+                    ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
+                    ep_38C1600->start_motor = adv_dvc_varp->start_motor;
+                    ep_38C1600->scsi_reset_delay =
+                        adv_dvc_varp->scsi_reset_wait;
+                    ep_38C1600->serial_number_word1 =
+                        adv_dvc_varp->cfg->serial1;
+                    ep_38C1600->serial_number_word2 =
+                        adv_dvc_varp->cfg->serial2;
+                    ep_38C1600->serial_number_word3 =
+                        adv_dvc_varp->cfg->serial3;
                 }
 
                 /*
@@ -5280,20 +5288,18 @@
                 shp->irq = adv_dvc_varp->irq_no;
             }
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
             /*
-             * Channels are numbered beginning with 0. For AdvanSys One host
+             * Channels are numbered beginning with 0. For AdvanSys one host
              * structure supports one channel. Multi-channel boards have a
-             * separate host structure for each channel. 
+             * separate host structure for each channel.
              */
             shp->max_channel = 0;
-#endif /* version >= v1.3.89 */
             if (ASC_NARROW_BOARD(boardp)) {
                 shp->max_id = ASC_MAX_TID + 1;
                 shp->max_lun = ASC_MAX_LUN + 1;
 
                 shp->io_port = asc_dvc_varp->iop_base;
-                shp->n_io_port = ASC_IOADR_GAP;
+                boardp->asc_n_io_port = ASC_IOADR_GAP;
                 shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
 
                 /* Set maximum number of queues the adapter can handle. */
@@ -5303,13 +5309,13 @@
                 shp->max_lun = ADV_MAX_LUN + 1;
 
                 /*
-                 * Save the I/O Port address and length even though the
-                 * in v1.3.0 and greater kernels the region is not used
-                 * by a Wide board. Instead the board is accessed with
-                 * Memory Mapped I/O.
+                 * Save the I/O Port address and length even though
+                 * I/O ports are not used to access Wide boards.
+                 * Instead the Wide boards are accessed with
+                 * PCI Memory Mapped I/O.
                  */
                 shp->io_port = iop;
-                shp->n_io_port = iolen;
+                boardp->asc_n_io_port = iolen;
 
                 shp->this_id = adv_dvc_varp->chip_scsi_id;
 
@@ -5317,18 +5323,15 @@
                 shp->can_queue = adv_dvc_varp->max_host_qng;
             }
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
             /*
-             * In old kernels without tag queuing support and with memory
-             * allocation problems set a conservative 'cmd_per_lun' value.
+             * 'n_io_port' currently is one byte.
+             *
+             * Set a value to 'n_io_port', but never referenced it because
+             * it may be truncated.
              */
-#ifdef MODULE
-            shp->cmd_per_lun = 1;
-#else /* MODULE */
-            shp->cmd_per_lun = 4;
-#endif /* MODULE */
-            ASC_DBG1(1, "advansys_detect: cmd_per_lun: %d\n", shp->cmd_per_lun);
-#else /* version >= v1.3.89 */
+            shp->n_io_port = boardp->asc_n_io_port <= 255 ?
+                boardp->asc_n_io_port : 255;
+
             /*
              * Following v1.3.89, 'cmd_per_lun' is no longer needed
              * and should be set to zero.
@@ -5348,7 +5351,6 @@
              * the number of commands to queue per device.
              */
             shp->select_queue_depths = advansys_select_queue_depths;
-#endif /* version >= v1.3.89 */
 
             /*
              * Set the maximum number of scatter-gather elements the
@@ -5368,20 +5370,6 @@
                 shp->sg_tablesize = ADV_MAX_SG_LIST;
             }
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
-#ifdef MODULE
-            /*
-             * If the driver is compiled as a module, set a limit on the
-             * 'sg_tablesize' value to prevent memory allocation failures.
-             * Memory allocation errors are more likely to occur at module
-             * load time, then at driver initialization time.
-             */
-            if (shp->sg_tablesize > 64) {
-                shp->sg_tablesize = 64;
-            }
-#endif /* MODULE */
-#endif /* version < v2.0.0 */
-
             /*
              * The value of 'sg_tablesize' can not exceed the SCSI
              * mid-level driver definition of SG_ALL. SG_ALL also
@@ -5397,11 +5385,11 @@
 
             /* BIOS start address. */
             if (ASC_NARROW_BOARD(boardp)) {
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,29)
+#if ASC_LINUX_KERNEL24
                 shp->base =
-#else /* version >= v2.3.29 */
+#elif ASC_LINUX_KERNEL22
                 shp->base = (char *)
-#endif /* version < v2.3.29 */
+#endif
                         ((ulong) AscGetChipBiosAddress(
                             asc_dvc_varp->iop_base,
                             asc_dvc_varp->bus_type));
@@ -5420,11 +5408,11 @@
                     boardp->bios_codelen);
 
                 ASC_DBG2(1,
-                    "advansys_detect: bios_signature %x, bios_version %x\n",
+                    "advansys_detect: bios_signature 0x%x, bios_version 0x%x\n",
                     boardp->bios_signature, boardp->bios_version);
 
                 ASC_DBG2(1,
-                    "advansys_detect: bios_codeseg %x, bios_codelen %x\n",
+                    "advansys_detect: bios_codeseg 0x%x, bios_codelen 0x%x\n",
                     boardp->bios_codeseg, boardp->bios_codelen);
 
                 /*
@@ -5436,11 +5424,10 @@
                      * Convert x86 realmode code segment to a linear
                      * address by shifting left 4.
                      */
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,29)
                     shp->base =
-#else /* version >= v2.3.29 */
-                    shp->base = (char *)
-#endif /* version < v2.3.29 */
+#if ASC_LINUX_KERNEL22
+                        (char *)
+#endif
                         ((ulong) boardp->bios_codeseg << 4);
                 } else {
                     shp->base = 0;
@@ -5451,12 +5438,37 @@
              * Register Board Resources - I/O Port, DMA, IRQ
              */
 
-            /* Register I/O port range. */
-            ASC_DBG(2, "advansys_detect: request_region()\n");
-            request_region(shp->io_port, shp->n_io_port, "advansys");
+            /*
+             * Register I/O port range.
+             *
+             * For Wide boards the I/O ports are not used to access
+             * the board, but request the region anyway.
+             *
+             * 'shp->n_io_port' is not referenced, because it may be truncated.
+             */
+            ASC_DBG2(2,
+                "advansys_detect: request_region port 0x%lx, len 0x%x\n",
+                (ulong) shp->io_port, boardp->asc_n_io_port);
+#if ASC_LINUX_KERNEL24
+            if (request_region(shp->io_port, boardp->asc_n_io_port,
+                               "advansys") == NULL) {
+                ASC_PRINT3(
+"advansys_detect: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
+                    boardp->id, (ulong) shp->io_port, boardp->asc_n_io_port);
+#ifdef CONFIG_PROC_FS
+                kfree(boardp->prtbuf);
+#endif /* CONFIG_PROC_FS */
+                scsi_unregister(shp);
+                asc_board_count--;
+                continue;
+            }
+#elif ASC_LINUX_KERNEL22
+            request_region(shp->io_port, boardp->asc_n_io_port, "advansys");
+#endif
 
             /* Register DMA Channel for Narrow boards. */
             shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
+#ifdef CONFIG_ISA
             if (ASC_NARROW_BOARD(boardp)) {
                 /* Register DMA channel for ISA bus. */
                 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
@@ -5466,10 +5478,10 @@
                         ASC_PRINT3(
 "advansys_detect: board %d: request_dma() %d failed %d\n",
                             boardp->id, shp->dma_channel, ret);
-                        release_region(shp->io_port, shp->n_io_port);
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+                        release_region(shp->io_port, boardp->asc_n_io_port);
+#ifdef CONFIG_PROC_FS
                         kfree(boardp->prtbuf);
-#endif /* version >= v1.3.0 */
+#endif /* CONFIG_PROC_FS */
                         scsi_unregister(shp);
                         asc_board_count--;
                         continue;
@@ -5477,13 +5489,10 @@
                     AscEnableIsaDma(shp->dma_channel);
                 }
             }
+#endif /* CONFIG_ISA */
 
             /* Register IRQ Number. */
             ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
-            if ((ret = request_irq(shp->irq, advansys_interrupt,
-                            SA_INTERRUPT, "advansys")) != 0)
-#else /* version >= v1.3.70 */
            /*
             * If request_irq() fails with the SA_INTERRUPT flag set,
             * then try again without the SA_INTERRUPT flag set. This
@@ -5499,31 +5508,28 @@
                 ((ret = request_irq(shp->irq, advansys_interrupt,
                             (share_irq == TRUE ? SA_SHIRQ : 0),
                             "advansys", boardp)) != 0))
-#endif /* version >= v1.3.70 */
             {
                 if (ret == -EBUSY) {
                     ASC_PRINT2(
-"advansys_detect: board %d: request_irq(): IRQ %d already in use.\n",
+"advansys_detect: board %d: request_irq(): IRQ 0x%x already in use.\n",
                         boardp->id, shp->irq);
                 } else if (ret == -EINVAL) {
                     ASC_PRINT2(
-"advansys_detect: board %d: request_irq(): IRQ %d not valid.\n",
+"advansys_detect: board %d: request_irq(): IRQ 0x%x not valid.\n",
                         boardp->id, shp->irq);
                 } else {
                     ASC_PRINT3(
-"advansys_detect: board %d: request_irq(): IRQ %d failed with %d\n",
+"advansys_detect: board %d: request_irq(): IRQ 0x%x failed with %d\n",
                         boardp->id, shp->irq, ret);
                 }
-                release_region(shp->io_port, shp->n_io_port);
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+                release_region(shp->io_port, boardp->asc_n_io_port);
                 iounmap(boardp->ioremap_addr);
-#endif /* version >= v1,3,0 */
                 if (shp->dma_channel != NO_ISA_DMA) {
                     free_dma(shp->dma_channel);
                 }
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+#ifdef CONFIG_PROC_FS
                 kfree(boardp->prtbuf);
-#endif /* version >= v1.3.0 */
+#endif /* CONFIG_PROC_FS */
                 scsi_unregister(shp);
                 asc_board_count--;
                 continue;
@@ -5539,7 +5545,7 @@
 
                 if (warn_code || err_code) {
                     ASC_PRINT4(
-"AscInitAsc1000Driver: board %d: error: init_state %x, warn %x error %x\n",
+"advansys_detect: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
                         boardp->id, asc_dvc_varp->init_state,
                         warn_code, err_code);
                 }
@@ -5549,25 +5555,13 @@
                 adv_req_t       *reqp = NULL;
                 int             sg_cnt = 0;
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
-                carrp = (ADV_CARR_T *) &adv_carr_buf[0];
-                req_cnt = sizeof(adv_req_buf)/sizeof(adv_req_t);
-                sg_cnt = sizeof(adv_sgblk_buf)/sizeof(adv_sgblk_t);
-                reqp = (adv_req_t *) &adv_req_buf[0];
-                boardp->adv_sgblkp = NULL;
-                for (sg_cnt = 0; sg_cnt < ADV_SGBLK_BUF_CNT; sg_cnt++) {
-                    sgp = (adv_sgblk_t *) &adv_sgblk_buf[sg_cnt];
-                    sgp->next_sgblkp = boardp->adv_sgblkp;
-                    boardp->adv_sgblkp = sgp;
-                }
-#else /* version >= v1.3.0 */
                 /*
                  * Allocate buffer carrier structures. The total size
                  * is about 4 KB, so allocate all at once.
                  */
                 carrp =
                     (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
-                ASC_DBG1(1, "advansys_detect: carrp %lx\n", (ulong) carrp);
+                ASC_DBG1(1, "advansys_detect: carrp 0x%lx\n", (ulong) carrp);
 
                 if (carrp == NULL) {
                     goto kmalloc_error;
@@ -5586,7 +5580,7 @@
                         kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
 
                     ASC_DBG3(1,
-                        "advansys_detect: reqp %lx, req_cnt %d, bytes %lu\n",
+                        "advansys_detect: reqp 0x%lx, req_cnt %d, bytes %lu\n",
                         (ulong) reqp, req_cnt,
                         (ulong) sizeof(adv_req_t) * req_cnt);
 
@@ -5631,24 +5625,24 @@
                 if (carrp == NULL)
                 {
                     ASC_PRINT1(
-"advansys_detect: board %d: error: failed to kmalloc() carrier buffer.\n",
+"advansys_detect: board %d error: failed to kmalloc() carrier buffer.\n",
                         boardp->id);
                     err_code = ADV_ERROR;
                 } else if (reqp == NULL) {
                     kfree(carrp);
                     ASC_PRINT1(
-"advansys_detect: board %d: error: failed to kmalloc() adv_req_t buffer.\n",
+"advansys_detect: board %d error: failed to kmalloc() adv_req_t buffer.\n",
                         boardp->id);
                     err_code = ADV_ERROR;
                 } else if (boardp->adv_sgblkp == NULL) {
                     kfree(carrp);
                     kfree(reqp);
                     ASC_PRINT1(
-"advansys_detect: board %d: error: failed to kmalloc() adv_sgblk_t buffers.\n",
+"advansys_detect: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
                         boardp->id);
                     err_code = ADV_ERROR;
                 } else {
-                    
+
                     /* Save carrier buffer pointer. */
                     boardp->orig_carrp = carrp;
 
@@ -5657,7 +5651,6 @@
                      * driver is built as a module and can be unloaded.
                      */
                     boardp->orig_reqp = reqp;
-#endif /* version >= v1.3.0 */
 
                     adv_dvc_varp->carrier_buf = carrp;
 
@@ -5677,26 +5670,27 @@
                         ASC_DBG(2,
                             "advansys_detect: AdvInitAsc3550Driver()\n");
                         warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
-                    } else {
+                    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
                         ASC_DBG(2,
                             "advansys_detect: AdvInitAsc38C0800Driver()\n");
                         warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
+                    } else {
+                        ASC_DBG(2,
+                            "advansys_detect: AdvInitAsc38C1600Driver()\n");
+                        warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
                     }
                     err_code = adv_dvc_varp->err_code;
 
                     if (warn_code || err_code) {
                         ASC_PRINT3(
-"AdvInitAsc3550/38C0800Driver: board %d: error: warn %x, error %x\n",
+"advansys_detect: board %d error: warn 0x%x, error 0x%x\n",
                             boardp->id, warn_code, err_code);
                     }
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
                 }
-#endif /* version >= v1,3,0 */
             }
 
             if (err_code != 0) {
-                release_region(shp->io_port, shp->n_io_port);
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+                release_region(shp->io_port, boardp->asc_n_io_port);
                 if (ASC_WIDE_BOARD(boardp)) {
                     iounmap(boardp->ioremap_addr);
                     if (boardp->orig_carrp) {
@@ -5713,18 +5707,13 @@
                         kfree(sgp);
                     }
                 }
-#endif /* version >= v1,3,0 */
                 if (shp->dma_channel != NO_ISA_DMA) {
                     free_dma(shp->dma_channel);
                 }
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+#ifdef CONFIG_PROC_FS
                 kfree(boardp->prtbuf);
-#endif /* version >= v1.3.0 */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
-                free_irq(shp->irq);
-#else /* version >= v1.3.70 */
+#endif /* CONFIG_PROC_FS */
                 free_irq(shp->irq, boardp);
-#endif /* version >= v1.3.70 */
                 scsi_unregister(shp);
                 asc_board_count--;
                 continue;
@@ -5732,6 +5721,14 @@
             ASC_DBG_PRT_SCSI_HOST(2, shp);
         }
     }
+
+    /*
+     * XXX - Remove this comment and the next line when SCSI mid-level
+     * no longer acquires 'io_request_lock' before calling the SCSI
+     * low-level detect entrypoint.
+     */
+    ASC_LOCK_IO_REQUEST_LOCK
+
     ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
     return asc_board_count;
 }
@@ -5748,17 +5745,12 @@
 
     ASC_DBG(1, "advansys_release: begin\n");
     boardp = ASC_BOARDP(shp);
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
-    free_irq(shp->irq);
-#else /* version >= v1.3.70 */
     free_irq(shp->irq, boardp);
-#endif /* version >= v1.3.70 */
     if (shp->dma_channel != NO_ISA_DMA) {
         ASC_DBG(1, "advansys_release: free_dma()\n");
         free_dma(shp->dma_channel);
     }
-    release_region(shp->io_port, shp->n_io_port);
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+    release_region(shp->io_port, boardp->asc_n_io_port);
     if (ASC_WIDE_BOARD(boardp)) {
         adv_sgblk_t    *sgp = NULL;
 
@@ -5777,9 +5769,10 @@
             kfree(sgp);
         }
     }
+#ifdef CONFIG_PROC_FS
     ASC_ASSERT(boardp->prtbuf != NULL);
     kfree(boardp->prtbuf);
-#endif /* version >= v1.3.0 */
+#endif /* CONFIG_PROC_FS */
     scsi_unregister(shp);
     ASC_DBG(1, "advansys_release: end\n");
     return 0;
@@ -5815,51 +5808,37 @@
             } else {
                 busname = "ISA";
             }
+            /* Don't reference 'shp->n_io_port'; It may be truncated. */
             sprintf(info,
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
-"AdvanSys SCSI %s: %s %u CDB: BIOS %lX, IO %lX/%X, IRQ %u, DMA %u",
-#else /* version >= v2.1.92 */ 
-"AdvanSys SCSI %s: %s %u CDB: BIOS %lX, IO %lX/%X, IRQ %u, DMA %u",
-#endif /* version >= v2.1.92 */ 
-                ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
-                (ulong) shp->base,
-                (ulong) shp->io_port, shp->n_io_port - 1,
+"AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
+                ASC_VERSION, busname,
+                (ulong) shp->io_port,
+                (ulong) shp->io_port + boardp->asc_n_io_port - 1,
                 shp->irq, shp->dma_channel);
-        } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
-            if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
-                == ASC_IS_PCI_ULTRA) {
-                busname = "PCI Ultra";
-            } else {
-                busname = "PCI";
-            }
-            sprintf(info,
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
-                "AdvanSys SCSI %s: %s %u CDB: IO %X/%X, IRQ %u",
-#else /* version >= v2.1.92 */ 
-                "AdvanSys SCSI %s: %s %u CDB: IO %lX/%X, IRQ %u",
-#endif /* version >= v2.1.92 */ 
-                ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
-                shp->io_port, shp->n_io_port - 1, shp->irq);
         } else {
             if (asc_dvc_varp->bus_type & ASC_IS_VL) {
                 busname = "VL";
             } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
                 busname = "EISA";
+            } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
+                if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
+                    == ASC_IS_PCI_ULTRA) {
+                    busname = "PCI Ultra";
+                } else {
+                    busname = "PCI";
+                }
             } else {
                 busname = "?";
-                ASC_PRINT2(
-    "advansys_info: board %d: unknown bus type %d\n",
+                ASC_PRINT2( "advansys_info: board %d: unknown bus type %d\n",
                     boardp->id, asc_dvc_varp->bus_type);
             }
+            /* Don't reference 'shp->n_io_port'; It may be truncated. */
             sprintf(info,
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,92)
-                "AdvanSys SCSI %s: %s %u CDB: BIOS %lX, IO %X/%X, IRQ %u",
-#else /* version >= v2.1.92 */ 
-                "AdvanSys SCSI %s: %s %u CDB: BIOS %lX, IO %lX/%X, IRQ %u",
-#endif /* version >= v2.1.92 */ 
-                ASC_VERSION, busname, asc_dvc_varp->max_total_qng,
-                (ulong) shp->base, shp->io_port - 1,
-                shp->n_io_port, shp->irq);
+                "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
+                ASC_VERSION, busname,
+                (ulong) shp->io_port,
+                (ulong) shp->io_port + boardp->asc_n_io_port - 1,
+                shp->irq);
         }
     } else {
         /*
@@ -5874,29 +5853,21 @@
         {
             iolen = ADV_3550_IOLEN;
             widename = "Ultra-Wide";
-        } else {
+        } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
+        {
             iolen = ADV_38C0800_IOLEN;
             widename = "Ultra2-Wide";
+        } else
+        {
+            iolen = ADV_38C1600_IOLEN;
+            widename = "Ultra3-Wide";
         }
-        if (boardp->bios_signature == 0x55AA) {
-            sprintf(info,
-"AdvanSys SCSI %s: PCI %s: BIOS %X/%X, IO %X/%X, IRQ %u",
-                ASC_VERSION,
-                widename,
-                boardp->bios_codeseg << 4,
-                boardp->bios_codelen > 0 ?
-                (boardp->bios_codelen << 9) - 1 : 0,
-                (unsigned) boardp->ioport, iolen - 1,
-                shp->irq);
-        } else {
-            sprintf(info,
-"AdvanSys SCSI %s: PCI %s: IO %X/%X, IRQ %u",
-                ASC_VERSION,
-                widename,
-                (unsigned) boardp->ioport,
-                (iolen - 1),
-                shp->irq);
-        }
+        sprintf(info, "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
+            ASC_VERSION,
+            widename,
+            (ulong) adv_dvc_varp->iop_base,
+            (ulong) adv_dvc_varp->iop_base + iolen - 1,
+            shp->irq);
     }
     ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
     ASC_DBG(1, "advansys_info: end\n");
@@ -5904,30 +5875,6 @@
 }
 
 /*
- * advansys_command() - polled I/O entrypoint.
- *
- * Apparently host drivers shouldn't return until the command
- * is finished.
- *
- * Note: This is an old interface that is no longer used by the SCSI
- * mid-level driver. The new interface, advansys_queuecommand(),
- * currently handles all requests.
- */
-int
-advansys_command(Scsi_Cmnd *scp)
-{
-    ASC_DBG1(1, "advansys_command: scp %lx\n", (ulong) scp);
-    ASC_STATS(scp->host, command);
-    scp->SCp.Status = 0; /* Set to a known state */
-    advansys_queuecommand(scp, advansys_command_done);
-    while (scp->SCp.Status == 0) {
-        continue;
-    }
-    ASC_DBG1(1, "advansys_command: result %x\n", scp->result);
-    return scp->result;
-}
-
-/*
  * advansys_queuecommand() - interrupt-driven I/O entrypoint.
  *
  * This function always returns 0. Command return status is saved
@@ -5938,7 +5885,7 @@
 {
     struct Scsi_Host    *shp;
     asc_board_t         *boardp;
-    int                 flags;
+    ulong               flags;
     Scsi_Cmnd           *done_scp;
 
     shp = scp->host;
@@ -5946,28 +5893,22 @@
     ASC_STATS(shp, queuecommand);
 
     /*
-     * Disable interrupts to preserve request ordering and provide
-     * mutually exclusive access to global structures used to initiate
-     * a request.
+     * XXX - Remove this comment and the next line when SCSI mid-level
+     * no longer acquires 'io_request_lock' before calling the SCSI
+     * low-level queuecommand entrypoint.
      */
-    save_flags(flags);
-    cli();
+    ASC_UNLOCK_IO_REQUEST_LOCK
+
+    spin_lock_irqsave(&boardp->lock, flags);
 
     /*
      * Block new commands while handling a reset or abort request.
      */
-    if (boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
-        if (boardp->flags & ASC_HOST_IN_RESET) {
-            ASC_DBG1(1,
-                "advansys_queuecommand: scp %lx blocked for reset request\n",
-                (ulong) scp);
-            scp->result = HOST_BYTE(DID_RESET);
-        } else {
-            ASC_DBG1(1,
-                "advansys_queuecommand: scp %lx blocked for abort request\n",
-                (ulong) scp);
-            scp->result = HOST_BYTE(DID_ABORT);
-        }
+    if (boardp->flags & ASC_HOST_IN_RESET) {
+        ASC_DBG1(1,
+            "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
+            (ulong) scp);
+        scp->result = HOST_BYTE(DID_RESET);
 
         /*
          * Add blocked requests to the board's 'done' queue. The queued
@@ -5975,7 +5916,7 @@
          * handling.
          */
         asc_enqueue(&boardp->done, scp, ASC_BACK);
-        restore_flags(flags);
+        spin_unlock_irqrestore(&boardp->lock, flags);
         return 0;
     }
 
@@ -5992,13 +5933,15 @@
      * Save the function pointer to Linux mid-level 'done' function
      * and attempt to execute the command.
      *
-     * If ASC_ERROR is returned the request has been added to the
+     * If ASC_NOERROR is returned the request has been added to the
      * board's 'active' queue and will be completed by the interrupt
      * handler.
      *
      * If ASC_BUSY is returned add the request to the board's per
-     * target waiting list.
-     * 
+     * target waiting list. This is the first time the request has
+     * been tried. Add it to the back of the waiting list. It will be
+     * retried later.
+     *
      * If an error occurred, the request will have been placed on the
      * board's 'done' queue and must be completed before returning.
      */
@@ -6017,645 +5960,223 @@
         break;
     }
 
-    restore_flags(flags);
-    return 0;
-}
-
-/*
- * advansys_abort()
- *
- * Abort the command specified by 'scp'.
- */
-int
-advansys_abort(Scsi_Cmnd *scp)
-{
-    struct Scsi_Host    *shp;
-    asc_board_t         *boardp;
-    ASC_DVC_VAR         *asc_dvc_varp;
-    ADV_DVC_VAR         *adv_dvc_varp;
-    int                 flags;
-    int                 do_scsi_done;
-    int                 scp_found;
-    Scsi_Cmnd           *done_scp = NULL;
-    int                 ret;
-
-    /* Save current flags and disable interrupts. */
-    save_flags(flags);
-    cli();
-
-    ASC_DBG1(1, "advansys_abort: scp %lx\n", (ulong) scp);
-
-#ifdef ADVANSYS_STATS
-    if (scp->host != NULL) {
-        ASC_STATS(scp->host, abort);
-    }    
-#endif /* ADVANSYS_STATS */
-
-#ifdef ADVANSYS_ASSERT
-    do_scsi_done = ASC_ERROR;
-    scp_found = ASC_ERROR;
-    ret = ASC_ERROR;
-#endif /* ADVANSYS_ASSERT */
-
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-    if (scp->serial_number != scp->serial_number_at_timeout) {
-        ASC_PRINT1(
-"advansys_abort: timeout serial number changed for request %lx\n",
-            (ulong) scp);
-        do_scsi_done = ASC_FALSE;
-        scp_found = ASC_FALSE;
-        ret = SCSI_ABORT_NOT_RUNNING;
-    } else
-#endif /* version >= v1.3.89 */
-    if ((shp = scp->host) == NULL) {
-        scp->result = HOST_BYTE(DID_ERROR);
-        do_scsi_done = ASC_TRUE;
-        scp_found = ASC_FALSE;
-        ret = SCSI_ABORT_ERROR;
-    } else if ((boardp = ASC_BOARDP(shp))->flags & 
-                (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
-        ASC_PRINT2(
-"advansys_abort: board %d: Nested host reset or abort, flags 0x%x\n",
-            boardp->id, boardp->flags);
-        do_scsi_done = ASC_TRUE;
-        if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
-            (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
-            scp_found = ASC_TRUE;
-        } else {
-            scp_found = ASC_FALSE;
-        }
-        scp->result = HOST_BYTE(DID_ERROR);
-        ret = SCSI_ABORT_ERROR;
-    } else {
-        /* Set abort flag to avoid nested reset or abort requests. */
-        boardp->flags |= ASC_HOST_IN_ABORT;
-
-        do_scsi_done = ASC_TRUE;
-        if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE) {
-            /*
-             * If asc_rmqueue() found the command on the waiting
-             * queue, it had not been sent to the device. After
-             * the queue is removed, no other handling is required.
-             */
-            ASC_DBG1(1, "advansys_abort: scp %lx found on waiting queue\n",
-                (ulong) scp);
-            scp_found = ASC_TRUE;
-            scp->result = HOST_BYTE(DID_ABORT);
-            ret = SCSI_ABORT_SUCCESS;
-        } else if (asc_isqueued(&boardp->active, scp) == ASC_TRUE) {
-            /*
-             * If asc_isqueued() found the command on the active
-             * queue, it has been sent to the device. The command
-             * will be returned through the interrupt handler after
-             * it has been aborted.
-             */
-
-            if (ASC_NARROW_BOARD(boardp)) {
-                /*
-                 * Narrow Board
-                 */
-                asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
-                scp->result = HOST_BYTE(DID_ABORT);
-
-                /* sti(); XXX */ /* Enable interrupts for AscAbortSRB(). */
-                ASC_DBG1(1, "advansys_abort: before AscAbortSRB(), scp %lx\n",
-                    (ulong) scp);
-                /* XXX */
-                switch (AscAbortSRB(asc_dvc_varp, ASC_VADDR_TO_U32(scp))) {
-                case ASC_TRUE:
-                    /* asc_isr_callback() will be called */
-                    ASC_DBG(1, "advansys_abort: AscAbortSRB() TRUE\n");
-                    ret = SCSI_ABORT_PENDING;
-                    break;
-                case ASC_FALSE:
-                    /* Request has apparently already completed. */
-                    ASC_DBG(1, "advansys_abort: AscAbortSRB() FALSE\n");
-                    ret = SCSI_ABORT_NOT_RUNNING;
-                    break;
-                case ASC_ERROR:
-                default:
-                    ASC_DBG(1, "advansys_abort: AscAbortSRB() ERROR\n");
-                    ret = SCSI_ABORT_ERROR;
-                    break;
-                }
-                cli();
-            } else {
-                /*
-                 * Wide Board
-                 */
-                adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
-                scp->result = HOST_BYTE(DID_ABORT);
-
-                ASC_DBG1(1,
-                    "advansys_abort: before AdvAbortQueue(), scp %lx\n",
-                    (ulong) scp);
-#if 0 /* XXX */
-                switch (AdvAbortQueue(adv_dvc_varp, (ADV_VADDR) XXX)) {
-                case ASC_TRUE:
-                    /* asc_isr_callback() will be called */
-                    ASC_DBG(1, "advansys_abort: AdvAbortQueue() TRUE\n");
-                    ret = SCSI_ABORT_PENDING;
-                    break;
-                case ASC_FALSE:
-                    /* Request has apparently already completed. */
-                    ASC_DBG(1, "advansys_abort: AdvAbortQueue() FALSE\n");
-                    ret = SCSI_ABORT_NOT_RUNNING;
-                    break;
-                case ASC_ERROR:
-                default:
-                    ASC_DBG(1, "advansys_abort: AdvAbortQueue() ERROR\n");
-                    ret = SCSI_ABORT_ERROR;
-                    break;
-                }
-                /*
-                 * Ensure all requests completed by the microcode have
-                 * been processed by calling AdvISR().
-                 */
-                (void) AdvISR(adv_dvc_varp);
-#else /* XXX */
-                (void) AdvResetChipAndSB(adv_dvc_varp);
-                ret = SCSI_ABORT_SUCCESS;
-#endif /* XXX */
-            }
-
-            /*
-             * The request will either still be on the active queue
-             * or have been added to the board's done queue.
-             */
-            if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE) {
-                scp->result = HOST_BYTE(DID_ABORT);
-                scp_found = ASC_TRUE;
-            } else {
-                scp_found = asc_rmqueue(&boardp->done, scp);
-                ASC_ASSERT(scp_found == ASC_TRUE);
-            }
-        } else {
-            /*
-             * The command was not found on the active or waiting queues.
-             */
-            do_scsi_done = ASC_TRUE;
-            scp_found = ASC_FALSE;
-            ret = SCSI_ABORT_NOT_RUNNING;
-        }
-
-        /* Clear abort flag. */
-        boardp->flags &= ~ASC_HOST_IN_ABORT;
-
-        /*
-         * Because the ASC_HOST_IN_ABORT flag causes both
-         * 'advansys_interrupt' and 'asc_isr_callback' to
-         * queue requests to the board's 'done' queue and
-         * prevents waiting commands from being executed,
-         * these queued requests must be handled here.
-         */
-        done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
-
-        /*
-         * Start any waiting commands for the board.
-         */
-        if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
-            ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
-            asc_execute_queue(&boardp->waiting);
-        }
-    }
-
-    /* Interrupts could be enabled here. */
-
-    /*
-     * Complete the request to be aborted, unless it has been
-     * restarted as detected above, even if it was not found on
-     * the device active or waiting queues.
-     */
-    ASC_ASSERT(do_scsi_done != ASC_ERROR);
-    ASC_ASSERT(scp_found != ASC_ERROR);
-    if (do_scsi_done == ASC_TRUE) {
-        if (scp->scsi_done == NULL) {
-            ASC_PRINT1(
-"advansys_abort: aborted request scsi_done() is NULL, %lx\n",
-                (ulong) scp);
-        } else {
-            if (scp_found == ASC_FALSE) {
-                ASC_PRINT1(
-"advansys_abort: abort request not active or waiting, completing anyway %lx\n",
-                    (ulong) scp);
-            }
-            ASC_STATS(scp->host, done);
-            scp->scsi_done(scp);
-        }
-    }
+    spin_unlock_irqrestore(&boardp->lock, flags);
 
     /*
-     * It is possible for the request done function to re-enable
-     * interrupts without confusing the driver. But here interrupts
-     * aren't enabled until all requests have been completed.
+     * XXX - Remove this comment and the next line when SCSI mid-level
+     * no longer acquires 'io_request_lock' before calling the SCSI
+     * low-level queuecommand entrypoint.
      */
-    if (done_scp != NULL) {
-        asc_scsi_done_list(done_scp);
-    }
-
-    ASC_DBG1(1, "advansys_abort: ret %d\n", ret);
-
-    /* Re-enable interrupts, if they were enabled on entry. */
-    restore_flags(flags);
+    ASC_LOCK_IO_REQUEST_LOCK
 
-    ASC_ASSERT(ret != ASC_ERROR);
-    return ret;
+    return 0;
 }
 
 /*
  * advansys_reset()
  *
- * Reset the device associated with the command 'scp'.
+ * Reset the bus associated with the command 'scp'.
+ *
+ * This function runs its own thread. Interrupts must be blocked but
+ * sleeping is allowed and no locking other than for host structures is
+ * required. Returns SUCCESS or FAILED.
  */
 int
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
 advansys_reset(Scsi_Cmnd *scp)
-#else /* version >= v1.3.89 */
-advansys_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
-#endif /* version >= v1.3.89 */
 {
     struct Scsi_Host     *shp;
     asc_board_t          *boardp;
     ASC_DVC_VAR          *asc_dvc_varp;
     ADV_DVC_VAR          *adv_dvc_varp;
-    int                  flags;
+    ulong                flags;
     Scsi_Cmnd            *done_scp = NULL, *last_scp = NULL;
     Scsi_Cmnd            *tscp, *new_last_scp;
-    int                  do_scsi_done;
-    int                  scp_found;
     int                  status;
-    int                  target;
-    int                  ret;
-    int                  device_reset = ASC_FALSE;
-
-    /* Save current flags and disable interrupts. */
-    save_flags(flags);
-    cli();
+    int                  ret = SUCCESS;
 
-    ASC_DBG1(1, "advansys_reset: %lx\n", (ulong) scp);
+    ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong) scp);
 
 #ifdef ADVANSYS_STATS
     if (scp->host != NULL) {
         ASC_STATS(scp->host, reset);
-    }    
+    }
 #endif /* ADVANSYS_STATS */
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-    if ((reset_flags & SCSI_RESET_ASYNCHRONOUS) &&
-        (scp->serial_number != scp->serial_number_at_timeout)) {
-        ASC_PRINT1(
-"advansys_reset: timeout serial number changed for request %lx\n",
-            (ulong) scp);
-        do_scsi_done = ASC_FALSE;
-        scp_found = ASC_FALSE;
-        ret = SCSI_RESET_NOT_RUNNING;
-    } else
-#endif /* version >= v1.3.89 */
     if ((shp = scp->host) == NULL) {
         scp->result = HOST_BYTE(DID_ERROR);
-        do_scsi_done = ASC_TRUE;
-        scp_found = ASC_FALSE;
-        ret = SCSI_RESET_ERROR;
-    } else if ((boardp = ASC_BOARDP(shp))->flags & 
-                (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) {
-        ASC_PRINT2(
-"advansys_reset: board %d: Nested host reset or abort, flags 0x%x\n",
-            boardp->id, boardp->flags);
-        do_scsi_done = ASC_TRUE;
-        if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
-            (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
-            scp_found = ASC_TRUE;
-        } else {
-            scp_found = ASC_FALSE;
-        }
-        scp->result = HOST_BYTE(DID_ERROR);
-        ret = SCSI_RESET_ERROR;
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,0)
-    } else if (time_after_eq(jiffies, boardp->last_reset) &&
-               time_before(jiffies, boardp->last_reset + (10 * HZ))) {
-#else /* version < v2.1.0 */
-    } else if (jiffies >= boardp->last_reset &&
-               jiffies < (boardp->last_reset + (10 * HZ))) {
-#endif /* version < v2.1.0 */
-        /*
-         * Don't allow a reset to be attempted within 10 seconds
-         * of the last reset.
-         *
-         * If 'jiffies' wrapping occurs, the reset request will go
-         * through, because a wrapped 'jiffies' would not pass the
-         * test above.
-         */
-        ASC_DBG(1,
-            "advansys_reset: reset within 10 sec of last reset ignored\n");
-        do_scsi_done = ASC_TRUE;
-        if ((asc_rmqueue(&boardp->active, scp) == ASC_TRUE) ||
-            (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE)) {
-            scp_found = ASC_TRUE;
-        } else {
-            scp_found = ASC_FALSE;
-        }
-        scp->result = HOST_BYTE(DID_ERROR);
-        ret = SCSI_RESET_ERROR;
-    } else {
-        do_scsi_done = ASC_TRUE;
-
-        /* Set reset flag to avoid nested reset or abort requests. */
-        boardp->flags |= ASC_HOST_IN_RESET;
+        return FAILED;
+    }
 
-        /*
-          * If the request is on the target waiting or active queue
-         * or the board done queue, then remove it and note that it
-         * was found.
-         */
-        if (asc_rmqueue(&boardp->active, scp) == ASC_TRUE) {
-            ASC_DBG(1, "advansys_reset: active scp_found = TRUE\n");
-            scp_found = ASC_TRUE;
-        } else if (asc_rmqueue(&boardp->waiting, scp) == ASC_TRUE) {
-            ASC_DBG(1, "advansys_reset: waiting scp_found = TRUE\n");
-            scp_found = ASC_TRUE;
-        } else if (asc_rmqueue(&boardp->done, scp) == ASC_TRUE) {
-            scp_found = ASC_TRUE;
-        } else {
-            scp_found = ASC_FALSE;
-        }
+    boardp = ASC_BOARDP(shp);
 
+    ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
+        boardp->id);
+    /*
+     * Check for re-entrancy.
+     */
+    spin_lock_irqsave(&boardp->lock, flags);
+    if (boardp->flags & ASC_HOST_IN_RESET) {
+        spin_unlock_irqrestore(&boardp->lock, flags);
+        return FAILED;
+    }
+    boardp->flags |= ASC_HOST_IN_RESET;
+    spin_unlock_irqrestore(&boardp->lock, flags);
 
-        if (ASC_NARROW_BOARD(boardp)) {
-            /*
-             * Narrow Board
-             *
-             * If the suggest reset bus flags are set, then reset the bus.
-             * Otherwise only reset the device.
-             */
-            asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-            if (reset_flags &
-                (SCSI_RESET_SUGGEST_BUS_RESET |
-                 SCSI_RESET_SUGGEST_HOST_RESET)) {
-#endif /* version >= v1.3.89 */
+    /*
+     * XXX - Remove this comment and the next line when SCSI mid-level
+     * no longer acquires 'io_request_lock' before calling the SCSI
+     * low-level reset entrypoint.
+     */
+    ASC_UNLOCK_IO_REQUEST_LOCK
 
-                /*
-                 * Reset the target's SCSI bus.
-                 */
-                ASC_DBG(1, "advansys_reset: before AscResetSB()\n");
-                /* sti(); XXX */ /* Enable interrupts for AscResetSB(). */
-                status = AscResetSB(asc_dvc_varp);
-                /* cli(); XXX */
-                switch (status) {
-                case ASC_TRUE:
-                    ASC_DBG(1, "advansys_reset: AscResetSB() success\n");
-                    ret = SCSI_RESET_SUCCESS;
-                    break;
-                case ASC_ERROR:
-                default:
-                    ASC_DBG(1, "advansys_reset: AscResetSB() failed\n");
-                    ret = SCSI_RESET_ERROR;
-                    break;
-                }
+    if (ASC_NARROW_BOARD(boardp)) {
+        /*
+         * Narrow Board
+         */
+        asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-            } else {
-                /*
-                 * Reset the specified device. If the device reset fails,
-                 * then reset the SCSI bus.
-                 */
+        /*
+         * Reset the chip and SCSI bus.
+         */
+        ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
+        status = AscInitAsc1000Driver(asc_dvc_varp);
 
-                ASC_DBG1(1,
-                    "advansys_reset: before AscResetDevice(), target %d\n",
-                    scp->target);
-                /* sti(); XXX */ /* Enable interrupts for AscResetDevice(). */
-                status = AscResetDevice(asc_dvc_varp, scp->target);
-                /* cli(); XXX */
-
-                switch (status) {
-                case ASC_TRUE:
-                    ASC_DBG(1, "advansys_reset: AscResetDevice() success\n");
-                    device_reset = ASC_TRUE;
-                    ret = SCSI_RESET_SUCCESS;
-                    break;
-                case ASC_ERROR:
-                default:
-                    ASC_DBG(1,
-"advansys_reset: AscResetDevice() failed; Calling AscResetSB()\n");
-                    /* sti(); XXX */ /* Enable interrupts for AscResetSB(). */
-                    status = AscResetSB(asc_dvc_varp);
-                    /* cli(); XXX */
-                    switch (status) {
-                    case ASC_TRUE:
-                        ASC_DBG(1, "advansys_reset: AscResetSB() TRUE\n");
-                        ret = SCSI_RESET_SUCCESS;
-                        break;
-                    case ASC_ERROR:
-                    default:
-                        ASC_DBG(1, "advansys_reset: AscResetSB() ERROR\n");
-                        ret = SCSI_RESET_ERROR;
-                        break;
-                    }
-                    break;
-                }
-            }
-#endif /* version >= v1.3.89 */
+        /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
+        if (asc_dvc_varp->err_code) {
+            ASC_PRINT2(
+                "advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
+                boardp->id, asc_dvc_varp->err_code);
+            ret = FAILED;
+        } else if (status) {
+            ASC_PRINT2(
+                "advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
+                boardp->id, status);
         } else {
-            /*
-             * Wide Board
-             *
-             * If the suggest reset bus flags are set, then reset the bus.
-             * Otherwise only reset the device.
-             */
-            adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-            if (reset_flags &
-                (SCSI_RESET_SUGGEST_BUS_RESET |
-                 SCSI_RESET_SUGGEST_HOST_RESET)) {
-#endif /* version >= v1.3.89 */
-
-                /*
-                 * Reset the target's SCSI bus.
-                 */
-                ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
-                switch (AdvResetChipAndSB(adv_dvc_varp)) {
-                case ASC_TRUE:
-                    ASC_DBG(1,
-                        "advansys_reset: AdvResetChipAndSB() success\n");
-                    ret = SCSI_RESET_SUCCESS;
-                    break;
-                case ASC_FALSE:
-                default:
-                    ASC_DBG(1, "advansys_reset: AdvResetChipAndSB() failed\n");
-                    ret = SCSI_RESET_ERROR;
-                    break;
-                }
-                /*
-                 * Ensure all requests completed by the microcode have
-                 * been processed by calling AdvISR().
-                 */
-                (void) AdvISR(adv_dvc_varp);
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-            } else {
-                /*
-                 * Reset the specified device. If the device reset fails,
-                 * then reset the SCSI bus.
-                 */
-
-                ASC_DBG1(1,
-                    "advansys_reset: before AdvResetDevice(), target %d\n",
-                    scp->target);
-                
-                switch (AdvResetDevice(adv_dvc_varp, scp->target)) {
-                case ASC_TRUE:
-                    ASC_DBG(1, "advansys_reset: AdvResetDevice() success\n");
-                    device_reset = ASC_TRUE;
-                    ret = SCSI_RESET_SUCCESS;
-                    break;
-                case ASC_FALSE:
-                default:
-                    ASC_DBG(1,
-"advansys_reset: AdvResetDevice() failed; Calling AdvResetChipAndSB()\n");
-                    
-                    switch (AdvResetChipAndSB(adv_dvc_varp)) {
-                    case ASC_TRUE:
-                        ASC_DBG(1,
-                            "advansys_reset: AdvResetChipAndSB() TRUE\n");
-                        ret = SCSI_RESET_SUCCESS;
-                        break;
-                    case ASC_FALSE:
-                    default:
-                        ASC_DBG(1,
-                            "advansys_reset: AdvResetChipAndSB() ERROR\n");
-                        ret = SCSI_RESET_ERROR;
-                        break;
-                    }
-                    break;
-                }
-                /*
-                 * Ensure all requests completed by the microcode have
-                 * been processed by calling AdvISR().
-                 */
-                (void) AdvISR(adv_dvc_varp);
-            }
-#endif /* version >= v1.3.89 */
+            ASC_PRINT1(
+                "advansys_reset: board %d: SCSI bus reset successful.\n",
+                boardp->id);
         }
 
+        ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
+
         /*
-         * Because the ASC_HOST_IN_RESET flag causes both
-         * 'advansys_interrupt' and 'asc_isr_callback' to
-         * queue requests to the board's 'done' queue and
-         * prevents waiting commands from being executed,
-         * these queued requests must be handled here.
+         * Acquire the board lock.
          */
-        done_scp = asc_dequeue_list(&boardp->done, &last_scp,
-                                    ASC_TID_ALL);
+        spin_lock_irqsave(&boardp->lock, flags);
 
+    } else {
         /*
-         * If a device reset was performed dequeue all waiting
-         * and active requests for the device and set the request
-         * status to DID_RESET.
+         * Wide Board
          *
-         * If a SCSI bus reset was performed dequeue all waiting
-         * and active requests for all devices and set the request
-         * status to DID_RESET.
+         * If the suggest reset bus flags are set, then reset the bus.
+         * Otherwise only reset the device.
          */
-        if (device_reset == ASC_TRUE) {
-            target = scp->target;
-        } else {
-            target = ASC_TID_ALL;
-        }
+        adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
 
         /*
-         * Add active requests to 'done_scp' and set the request status
-         * to DID_RESET.
+         * Reset the target's SCSI bus.
          */
-        if (done_scp == NULL) {
-            done_scp = asc_dequeue_list(&boardp->active, &last_scp, target);
-            for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
-                tscp->result = HOST_BYTE(DID_RESET);
-            }
-        } else {
-            ASC_ASSERT(last_scp != NULL);
-            REQPNEXT(last_scp) = asc_dequeue_list(&boardp->active,
-                &new_last_scp, target);
-            if (new_last_scp != NULL) {
-                ASC_ASSERT(REQPNEXT(last_scp) != NULL);
-                for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
-                    tscp->result = HOST_BYTE(DID_RESET);
-                }
-                last_scp = new_last_scp;
-            }
+        ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
+        switch (AdvResetChipAndSB(adv_dvc_varp)) {
+        case ASC_TRUE:
+            ASC_PRINT1("advansys_reset: board %d: SCSI bus reset successful.\n",
+                boardp->id);
+            break;
+        case ASC_FALSE:
+        default:
+            ASC_PRINT1("advansys_reset: board %d: SCSI bus reset error.\n",
+                boardp->id);
+            ret = FAILED;
+            break;
         }
-
         /*
-         * Add waiting requests to 'done_scp' and set the request status
-         * to DID_RESET.
+         * Acquire the board lock and ensure all requests completed by the
+         * microcode have been processed by calling AdvISR().
          */
-        if (done_scp == NULL) {
-            done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, target);
-            for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
-                tscp->result = HOST_BYTE(DID_RESET);
-            }
-        } else {
-            ASC_ASSERT(last_scp != NULL);
-            REQPNEXT(last_scp) = asc_dequeue_list(&boardp->waiting,
-                &new_last_scp, target);
-            if (new_last_scp != NULL) {
-                ASC_ASSERT(REQPNEXT(last_scp) != NULL);
-                for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
-                    tscp->result = HOST_BYTE(DID_RESET);
-                }
-                last_scp = new_last_scp;
-            }
-        }
+        spin_lock_irqsave(&boardp->lock, flags);
+        (void) AdvISR(adv_dvc_varp);
+    }
 
-        /* Save the time of the most recently completed reset. */
-        boardp->last_reset = jiffies;
+    /* Board lock is held. */
 
-        /* Clear reset flag. */
-        boardp->flags &= ~ASC_HOST_IN_RESET;
+    /*
+     * Dequeue all board 'done' requests. A pointer to the last request
+     * is returned in 'last_scp'.
+     */
+    done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
 
-        /*
-         * Start any waiting commands for the board.
-         */
-        if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
-            ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
-            asc_execute_queue(&boardp->waiting);
+    /*
+     * Dequeue all board 'active' requests for all devices and set
+     * the request status to DID_RESET. A pointer to the last request
+     * is returned in 'last_scp'.
+     */
+    if (done_scp == NULL) {
+        done_scp = asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
+        for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
+            tscp->result = HOST_BYTE(DID_RESET);
+        }
+    } else {
+        /* Append to 'done_scp' at the end with 'last_scp'. */
+        ASC_ASSERT(last_scp != NULL);
+        REQPNEXT(last_scp) = asc_dequeue_list(&boardp->active,
+            &new_last_scp, ASC_TID_ALL);
+        if (new_last_scp != NULL) {
+            ASC_ASSERT(REQPNEXT(last_scp) != NULL);
+            for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
+                tscp->result = HOST_BYTE(DID_RESET);
+            }
+            last_scp = new_last_scp;
         }
-        ret = SCSI_RESET_SUCCESS;
     }
 
-    /* Interrupts could be enabled here. */
-
-    ASC_ASSERT(do_scsi_done != ASC_ERROR);
-    ASC_ASSERT(scp_found != ASC_ERROR);
-    if (do_scsi_done == ASC_TRUE) {
-        if (scp->scsi_done == NULL) {
-            ASC_PRINT1(
-"advansys_reset: reset request scsi_done() is NULL, %lx\n",
-                (ulong) scp);
-        } else {
-            if (scp_found == ASC_FALSE) {
-                ASC_PRINT1(
-"advansys_reset: reset request not active or waiting, completing anyway %lx\n",
-                    (ulong) scp);
+    /*
+     * Dequeue all 'waiting' requests and set the request status
+     * to DID_RESET.
+     */
+    if (done_scp == NULL) {
+        done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
+        for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
+            tscp->result = HOST_BYTE(DID_RESET);
+        }
+    } else {
+        /* Append to 'done_scp' at the end with 'last_scp'. */
+        ASC_ASSERT(last_scp != NULL);
+        REQPNEXT(last_scp) = asc_dequeue_list(&boardp->waiting,
+            &new_last_scp, ASC_TID_ALL);
+        if (new_last_scp != NULL) {
+            ASC_ASSERT(REQPNEXT(last_scp) != NULL);
+            for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
+                tscp->result = HOST_BYTE(DID_RESET);
             }
-            ASC_STATS(scp->host, done);
-            scp->scsi_done(scp);
+            last_scp = new_last_scp;
         }
     }
 
+    /* Save the time of the most recently completed reset. */
+    boardp->last_reset = jiffies;
+
+    /* Clear reset flag. */
+    boardp->flags &= ~ASC_HOST_IN_RESET;
+
+    /* Release the board. */
+    spin_unlock_irqrestore(&boardp->lock, flags);
+
     /*
-     * It is possible for the request done function to re-enable
-     * interrupts without confusing the driver. But here interrupts
-     * aren't enabled until requests have been completed.
+     * Complete all the 'done_scp' requests.
      */
     if (done_scp != NULL) {
         asc_scsi_done_list(done_scp);
     }
 
-    ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
+    /*
+     * XXX - Remove this comment and the next line when SCSI mid-level
+     * no longer acquires 'io_request_lock' before calling the SCSI
+     * low-level reset entrypoint.
+     */
+    ASC_LOCK_IO_REQUEST_LOCK
 
-    /* Re-enable interrupts, if they were enabled on entry. */
-    restore_flags(flags);
+    ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
 
-    ASC_ASSERT(ret != ASC_ERROR);
     return ret;
 }
 
@@ -6671,11 +6192,7 @@
  * ip[2]: cylinders
  */
 int
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
-advansys_biosparam(Disk *dp, int dep, int ip[])
-#else /* version >= v1.3.0 */
 advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
-#endif /* version >= v1.3.0 */
 {
     asc_board_t     *boardp;
 
@@ -6771,14 +6288,14 @@
 #ifdef ADVANSYS_DEBUG
     ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
     for (i = 1; i < ints[0]; i++) {
-        ASC_DBG2(1, " ints[%d] %x", i, ints[i]);
+        ASC_DBG2(1, " ints[%d] 0x%x", i, ints[i]);
     }
     ASC_DBG(1, "\n");
 #endif /* ADVANSYS_DEBUG */
 
     for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
         asc_ioport[i-1] = ints[i];
-        ASC_DBG2(1, "advansys_setup: asc_ioport[%d] %x\n",
+        ASC_DBG2(1, "advansys_setup: asc_ioport[%d] 0x%x\n",
             i - 1, asc_ioport[i-1]);
     }
 }
@@ -6788,8 +6305,15 @@
  * --- Loadable Driver Support
  */
 
+#if ASC_LINUX_KERNEL24
 static Scsi_Host_Template driver_template = ADVANSYS;
 # include "scsi_module.c"
+#elif ASC_LINUX_KERNEL22
+#ifdef MODULE
+Scsi_Host_Template driver_template = ADVANSYS;
+# include "scsi_module.c"
+#endif /* MODULE */
+#endif
 
 
 /*
@@ -6799,41 +6323,21 @@
 /*
  * First-level interrupt handler.
  *
- * For versions > v1.3.70, 'dev_id' is a pointer to the interrupting
- * adapter's asc_board_t. Because all boards are currently checked
- * for interrupts on each interrupt, 'dev_id' is not referenced. 'dev_id'
- * could be used to identify an interrupt passed to the AdvanSys driver,
- * which is for a device sharing an interrupt with an AdvanSys adapter.
+ * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
+ * all boards are currently checked for interrupts on each interrupt, 'dev_id'
+ * is not referenced. 'dev_id' could be used to identify an interrupt passed
+ * to the AdvanSys driver which is for a device sharing an interrupt with
+ * an AdvanSys adapter.
  */
 STATIC void
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,70)
-advansys_interrupt(int irq, struct pt_regs *regs)
-#else /* version >= v1.3.70 */
 advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-#endif /* version >= v1.3.70 */
 {
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
-    int             flags;
-#else /* version >= v2.1.95 */
-    unsigned long   flags;
-#endif /* version >= v2.1.95 */
+    ulong           flags;
     int             i;
     asc_board_t     *boardp;
     Scsi_Cmnd       *done_scp = NULL, *last_scp = NULL;
     Scsi_Cmnd       *new_last_scp;
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
-    /* Disable interrupts, if they aren't already disabled. */
-    save_flags(flags);
-    cli();
-#else /* version >= v2.1.95 */
-    /*
-     * Disable interrupts, if they aren't already disabled and acquire
-     * the I/O spinlock.
-     */
-    spin_lock_irqsave(&io_request_lock, flags);
-#endif /* version >= v2.1.95 */
-
     ASC_DBG(1, "advansys_interrupt: begin\n");
 
     /*
@@ -6842,8 +6346,9 @@
      */
     for (i = 0; i < asc_board_count; i++) {
         boardp = ASC_BOARDP(asc_host[i]);
-        ASC_DBG2(2, "advansys_interrupt: i %d, boardp %lx\n",
-            i, (ulong) boardp)            
+        ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n",
+            i, (ulong) boardp);
+        spin_lock_irqsave(&boardp->lock, flags);
         if (ASC_NARROW_BOARD(boardp)) {
             /*
              * Narrow Board
@@ -6865,13 +6370,12 @@
 
         /*
          * Start waiting requests and create a list of completed requests.
-         * 
-         * If a reset or abort request is being performed for the board,
-         * the reset or abort handler will complete pending requests after
-         * it has completed.
+         *
+         * If a reset request is being performed for the board, the reset
+         * handler will complete pending requests after it has completed.
          */
-        if ((boardp->flags & (ASC_HOST_IN_RESET | ASC_HOST_IN_ABORT)) == 0) {
-            ASC_DBG2(1, "advansys_interrupt: done_scp %lx, last_scp %lx\n",
+        if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
+            ASC_DBG2(1, "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n",
                 (ulong) done_scp, (ulong) last_scp);
 
             /* Start any waiting commands for the board. */
@@ -6900,38 +6404,21 @@
                 }
             }
         }
+        spin_unlock_irqrestore(&boardp->lock, flags);
     }
 
-    /* Interrupts could be enabled here. */
-
     /*
-     * It is possible for the request done function to re-enable
-     * interrupts without confusing the driver. But here the
-     * original flags aren't restored until all requests have been
-     * completed.
+     * If interrupts were enabled on entry, then they
+     * are now enabled here.
+     *
+     * Complete all requests on the done list.
      */
     asc_scsi_done_list(done_scp);
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,95)
-    /*
-     * Restore the original flags which will enable interrupts
-     * if and only if they were enabled on entry.
-     */
-    restore_flags(flags);
-#else /* version >= v2.1.95 */
-    /*
-     * Release the I/O spinlock and restore the original flags
-     * which will enable interrupts if and only if they were
-     * enabled on entry.
-     */
-    spin_unlock_irqrestore(&io_request_lock, flags);
-#endif /* version >= v2.1.95 */
-
     ASC_DBG(1, "advansys_interrupt: end\n");
     return;
 }
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
 /*
  * Set the number of commands to queue per device for the
  * specified host adapter.
@@ -6960,22 +6447,11 @@
             device->queue_depth =
                 boardp->dvc_var.adv_dvc_var.max_dvc_qng;
         }
-        ASC_DBG3(1, "advansys_select_queue_depths: shp %lx, id %d, depth %d\n",
+        ASC_DBG3(1,
+            "advansys_select_queue_depths: shp 0x%lx, id %d, depth %d\n",
             (ulong) shp, device->id, device->queue_depth);
     }
 }
-#endif /* version >= v1.3.89 */
-
-/*
- * Function used only with polled I/O requests that are initiated by
- * advansys_command().
- */
-STATIC void
-advansys_command_done(Scsi_Cmnd *scp)
-{
-    ASC_DBG1(1, "advansys_command_done: scp %lx\n", (ulong) scp);
-    scp->SCp.Status = 1;
-}
 
 /*
  * Complete all requests on the singly linked list pointed
@@ -6990,7 +6466,7 @@
 
     ASC_DBG(2, "asc_scsi_done_list: begin\n");
     while (scp != NULL) {
-        ASC_DBG1(3, "asc_scsi_done_list: scp %lx\n", (ulong) scp);
+        ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
         tscp = REQPNEXT(scp);
         REQPNEXT(scp) = NULL;
         ASC_STATS(scp->host, done);
@@ -7038,12 +6514,15 @@
  *    scsi_done - used to save caller's done function
  *    host_scribble - used for pointer to another Scsi_Cmnd
  *
- * If this function returns ASC_NOERROR or ASC_ERROR the request
- * has been enqueued on the board's 'done' queue and must be
- * completed by the caller.
+ * If this function returns ASC_NOERROR the request has been enqueued
+ * on the board's 'active' queue and will be completed from the
+ * interrupt handler.
+ *
+ * If this function returns ASC_NOERROR the request has been enqueued
+ * on the board's 'done' queue and must be completed by the caller.
  *
- * If ASC_BUSY is returned the request must be enqueued by the
- * caller and re-tried later.
+ * If ASC_BUSY is returned the request will be enqueued by the
+ * caller on the target's waiting queue and re-tried later.
  */
 STATIC int
 asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
@@ -7055,8 +6534,7 @@
     Scsi_Device        *device;
     int                ret;
 
-    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
-    ASC_DBG2(1, "asc_execute_scsi_cmnd: scp %lx, done %lx\n",
+    ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
         (ulong) scp, (ulong) scp->scsi_done);
 
     boardp = ASC_BOARDP(scp->host);
@@ -7073,6 +6551,10 @@
          * Build Asc Library request structure using the
          * global structures 'asc_scsi_req' and 'asc_sg_head'.
          *
+         * If an error is returned, then the request has been
+         * queued on the board done queue. It will be completed
+         * by the caller.
+         *
          * asc_build_req() can not return ASC_BUSY.
          */
         if (asc_build_req(boardp, scp) == ASC_ERROR) {
@@ -7092,18 +6574,20 @@
              * request counter. Wrapping doesn't matter.
              */
             boardp->reqcnt[scp->target]++;
-
             asc_enqueue(&boardp->active, scp, ASC_BACK);
             ASC_DBG(1,
                 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
             break;
         case ASC_BUSY:
-            /* Caller must enqueue request and retry later. */
+            /*
+             * Caller will enqueue request on the target's waiting queue
+             * and retry later.
+             */
             ASC_STATS(scp->host, exe_busy);
             break;
         case ASC_ERROR:
             ASC_PRINT2(
-"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code %x\n",
+"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
                 boardp->id, asc_dvc_varp->err_code);
             ASC_STATS(scp->host, exe_error);
             scp->result = HOST_BYTE(DID_ERROR);
@@ -7111,7 +6595,7 @@
             break;
         default:
             ASC_PRINT2(
-"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code %x\n",
+"asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
                 boardp->id, asc_dvc_varp->err_code);
             ASC_STATS(scp->host, exe_unknown);
             scp->result = HOST_BYTE(DID_ERROR);
@@ -7127,7 +6611,7 @@
         /*
          * Build and get a pointer to an Adv Library request structure.
          *
-         * If the request is successfully built then send  it below,
+         * If the request is successfully built then send it below,
          * otherwise return with an error.
          */
         switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
@@ -7136,14 +6620,28 @@
             break;
         case ASC_BUSY:
             ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
+            /*
+             * If busy is returned the request has not been enqueued.
+             * It will be enqueued by the caller on the target's waiting
+             * queue and retried later.
+             *
+             * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
+             * count wide board busy conditions. They are updated in
+             * adv_build_req and adv_get_sglist, respectively.
+             */
             return ASC_BUSY;
         case ASC_ERROR:
+             /* 
+              * If an error is returned, then the request has been
+              * queued on the board done queue. It will be completed
+              * by the caller.
+              */
         default:
             ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
             ASC_STATS(scp->host, build_error);
             return ASC_ERROR;
         }
-    
+
         /*
          * Execute the command. If there is no error, add the command
          * to the active queue.
@@ -7161,12 +6659,15 @@
                 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
             break;
         case ASC_BUSY:
-            /* Caller must enqueue request and retry later. */
+            /*
+             * Caller will enqueue request on the target's waiting queue
+             * and retry later.
+             */
             ASC_STATS(scp->host, exe_busy);
             break;
         case ASC_ERROR:
             ASC_PRINT2(
-"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code %x\n",
+"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
                 boardp->id, adv_dvc_varp->err_code);
             ASC_STATS(scp->host, exe_error);
             scp->result = HOST_BYTE(DID_ERROR);
@@ -7174,7 +6675,7 @@
             break;
         default:
             ASC_PRINT2(
-"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code %x\n",
+"asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
                 boardp->id, adv_dvc_varp->err_code);
             ASC_STATS(scp->host, exe_unknown);
             scp->result = HOST_BYTE(DID_ERROR);
@@ -7184,7 +6685,6 @@
     }
 
     ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
-    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
     return ret;
 }
 
@@ -7194,7 +6694,8 @@
  * The global structures 'asc_scsi_q' and 'asc_sg_head' are
  * used to build the request.
  *
- * If an error occurs, then return ASC_ERROR.
+ * If an error occurs, then queue the request on the board done
+ * queue and return ASC_ERROR.
  */
 STATIC int
 asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
@@ -7212,21 +6713,24 @@
 
     /*
      * Build the ASC_SCSI_Q request.
+     *
+     * For narrow boards a CDB length maximum of 12 bytes
+     * is supported.
      */
-    ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
     if (scp->cmd_len > ASC_MAX_CDB_LEN) {
-        scp->cmd_len = ASC_MAX_CDB_LEN;
+        ASC_PRINT3(
+"asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN  %d\n",
+            boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
+        scp->result = HOST_BYTE(DID_ERROR);
+        asc_enqueue(&boardp->done, scp, ASC_BACK);
+        return ASC_ERROR;
     }
     asc_scsi_q.cdbptr = &scp->cmnd[0];
     asc_scsi_q.q2.cdb_len = scp->cmd_len;
     asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
     asc_scsi_q.q1.target_lun = scp->lun;
     asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun);
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
-    asc_scsi_q.q1.sense_addr = (ADV_PADDR) &scp->sense_buffer[0];
-#else /* version >= v2.0.0 */
     asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
-#endif /* version >= v2.0.0 */
     asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
 
     /*
@@ -7238,7 +6742,7 @@
      *
      * The request count is incremented below for every successfully
      * started request.
-     * 
+     *
      */
     if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->target] > 0) &&
         (boardp->reqcnt[scp->target] % 255) == 0) {
@@ -7256,13 +6760,9 @@
          * CDB request of single contiguous buffer.
          */
         ASC_STATS(scp->host, cont_cnt);
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
-        asc_scsi_q.q1.data_addr = (ADV_PADDR) scp->request_buffer;
-#else /* version >= v2.0.0 */
         asc_scsi_q.q1.data_addr =
             cpu_to_le32(virt_to_bus(scp->request_buffer));
-#endif /* version >= v2.0.0 */
-        asc_scsi_q.q1.data_cnt = scp->request_bufflen;
+        asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
         ASC_STATS_ADD(scp->host, cont_xfer,
                       ASC_CEILING(scp->request_bufflen, 512));
         asc_scsi_q.q1.sg_queue_cnt = 0;
@@ -7295,6 +6795,7 @@
         asc_scsi_q.sg_head = &asc_sg_head;
         asc_scsi_q.q1.data_cnt = 0;
         asc_scsi_q.q1.data_addr = 0;
+        /* This is a byte value, otherwise it would need to be swapped. */
         asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
         ASC_STATS_ADD(scp->host, sg_elem, asc_sg_head.entry_cnt);
 
@@ -7303,12 +6804,8 @@
          */
         slp = (struct scatterlist *) scp->request_buffer;
         for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
-            asc_sg_head.sg_list[sgcnt].addr = (ADV_PADDR) slp->address;
-#else /* version >= v2.0.0 */
             asc_sg_head.sg_list[sgcnt].addr =
                 cpu_to_le32(virt_to_bus(slp->address));
-#endif /* version >= v2.0.0 */
             asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(slp->length);
             ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
         }
@@ -7354,9 +6851,9 @@
     }
 
     /*
-     * Get 4-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
+     * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
      */
-    scsiqp = (ADV_SCSI_REQ_Q *) ADV_DWALIGN(&reqp->scsi_req_q);
+    scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
 
     /*
      * Initialize the structure.
@@ -7379,24 +6876,31 @@
 
     /*
      * Set CDB length and copy it to the request structure.
+     * For wide  boards a CDB length maximum of 16 bytes
+     * is supported.
      */
-    ASC_ASSERT(scp->cmd_len <= ASC_MAX_CDB_LEN);
-    if (scp->cmd_len > ASC_MAX_CDB_LEN) {
-        scp->cmd_len = ASC_MAX_CDB_LEN;
+    if (scp->cmd_len > ADV_MAX_CDB_LEN) {
+        ASC_PRINT3(
+"adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN  %d\n",
+            boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
+        scp->result = HOST_BYTE(DID_ERROR);
+        asc_enqueue(&boardp->done, scp, ASC_BACK);
+        return ASC_ERROR;
     }
     scsiqp->cdb_len = scp->cmd_len;
-    for (i = 0; i < scp->cmd_len; i++) {
+    /* Copy first 12 CDB bytes to cdb[]. */
+    for (i = 0; i < scp->cmd_len && i < 12; i++) {
         scsiqp->cdb[i] = scp->cmnd[i];
     }
+    /* Copy last 4 CDB bytes, if present, to cdb16[]. */
+    for (; i < scp->cmd_len; i++) {
+        scsiqp->cdb16[i - 12] = scp->cmnd[i];
+    }
 
     scsiqp->target_id = scp->target;
     scsiqp->target_lun = scp->lun;
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
-    scsiqp->sense_addr = (ADV_PADDR) &scp->sense_buffer[0];
-#else /* version >= v2.0.0 */
     scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
-#endif /* version >= v2.0.0 */
     scsiqp->sense_len = sizeof(scp->sense_buffer);
 
     /*
@@ -7405,11 +6909,7 @@
      */
     scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
     scsiqp->vdata_addr = scp->request_buffer;
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
-    scsiqp->data_addr = (ADV_PADDR) scp->request_buffer;
-#else /* version >= v2.0.0 */
     scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
-#endif /* version >= v2.0.0 */
 
     if (scp->use_sg == 0) {
         /*
@@ -7488,7 +6988,7 @@
     ADV_PADDR           sg_block_paddr;
     int                 i;
 
-    scsiqp = (ADV_SCSI_REQ_Q *) ADV_DWALIGN(&reqp->scsi_req_q);
+    scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
     slp = (struct scatterlist *) scp->request_buffer;
     sg_elem_cnt = scp->use_sg;
     prev_sg_block = NULL;
@@ -7525,16 +7025,11 @@
             sgblkp->next_sgblkp = NULL;
 
             /*
-             * Get 4 byte aligned virtual and physical addresses for
+             * Get 8 byte aligned virtual and physical addresses for
              * the allocated ADV_SG_BLOCK structure.
              */
-            sg_block = (ADV_SG_BLOCK *) ADV_DWALIGN(&sgblkp->sg_block);
-            sg_block_paddr =
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
-                (ADV_PADDR) sg_block;
-#else /* version >= v2.0.0 */
-                virt_to_bus(sg_block);
-#endif /* version >= v2.0.0 */
+            sg_block = (ADV_SG_BLOCK *) ADV_8BALIGN(&sgblkp->sg_block);
+            sg_block_paddr = virt_to_bus(sg_block);
 
             /*
              * Check if this is the first 'adv_sgblk_t' for the request.
@@ -7568,11 +7063,7 @@
         for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
         {
             sg_block->sg_list[i].sg_addr =
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
-                (ADV_PADDR) slp->address;
-#else /* version >= v2.0.0 */
                 cpu_to_le32(virt_to_bus(slp->address));
-#endif /* version >= v2.0.0 */
             sg_block->sg_list[i].sg_count = cpu_to_le32(slp->length);
             ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
 
@@ -7604,8 +7095,7 @@
     struct Scsi_Host    *shp;
     int                 i;
 
-    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
-    ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp %lx, qdonep %lx\n",
+    ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
         (ulong) asc_dvc_varp, (ulong) qdonep);
     ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
 
@@ -7614,7 +7104,7 @@
      * command that has been completed.
      */
     scp = (Scsi_Cmnd *) ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
-    ASC_DBG1(1, "asc_isr_callback: scp %lx\n", (ulong) scp);
+    ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong) scp);
 
     if (scp == NULL) {
         ASC_PRINT("asc_isr_callback: scp is NULL\n");
@@ -7634,24 +7124,24 @@
     }
     if (i == asc_board_count) {
         ASC_PRINT2(
-            "asc_isr_callback: scp %lx has bad host pointer, host %lx\n",
+            "asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
             (ulong) scp, (ulong) shp);
         return;
     }
 
     ASC_STATS(shp, callback);
-    ASC_DBG1(1, "asc_isr_callback: shp %lx\n", (ulong) shp);
+    ASC_DBG1(1, "asc_isr_callback: shp 0x%lx\n", (ulong) shp);
 
     /*
      * If the request isn't found on the active queue, it may
-     * have been removed to handle a reset or abort request.
+     * have been removed to handle a reset request.
      * Display a message and return.
      */
     boardp = ASC_BOARDP(shp);
     ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
     if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
         ASC_PRINT2(
-            "asc_isr_callback: board %d: scp %lx not on active queue\n",
+            "asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
             boardp->id, (ulong) scp);
         return;
     }
@@ -7675,20 +7165,20 @@
                 (ASC_SCSI_INQUIRY *) scp->request_buffer);
         }
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,19)
+#if ASC_LINUX_KERNEL24
         /*
          * Check for an underrun condition.
          *
          * If there was no error and an underrun condition, then
          * then return the number of underrun bytes.
          */
-        if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 && 
+        if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
             qdonep->remain_bytes <= scp->request_bufflen != 0) {
             ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
             (unsigned) qdonep->remain_bytes);
             scp->resid = qdonep->remain_bytes;
         }
-#endif /* version >= v2.3.19 */
+#endif
         break;
 
     case QD_WITH_ERROR:
@@ -7710,15 +7200,15 @@
                  * byte as it is defined by SCSI.
                  */
                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
-                    STATUS_BYTE(qdonep->d3.scsi_stat); 
+                    STATUS_BYTE(qdonep->d3.scsi_stat);
             } else {
-                scp->result = STATUS_BYTE(qdonep->d3.scsi_stat); 
+                scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
             }
             break;
 
         default:
             /* QHSTA error occurred */
-            ASC_DBG1(1, "asc_isr_callback: host_stat %x\n",
+            ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
                 qdonep->d3.host_stat);
             scp->result = HOST_BYTE(DID_BAD_TARGET);
             break;
@@ -7732,7 +7222,7 @@
         break;
 
     default:
-        ASC_DBG1(1, "asc_isr_callback: done_stat %x\n", qdonep->d3.done_stat);
+        ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", qdonep->d3.done_stat);
         scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
                 STATUS_BYTE(qdonep->d3.scsi_stat);
         break;
@@ -7749,7 +7239,7 @@
         boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
     }
 
-    /* 
+    /*
      * Because interrupts may be enabled by the 'Scsi_Cmnd' done
      * function, add the command to the end of the board's done queue.
      * The done function for the command will be called from
@@ -7774,9 +7264,12 @@
     Scsi_Cmnd           *scp;
     struct Scsi_Host    *shp;
     int                 i;
+#if ASC_LINUX_KERNEL24
+    ADV_DCNT            resid_cnt;
+#endif
 
-    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
-    ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp %lx, scsiqp %lx\n",
+
+    ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
         (ulong) adv_dvc_varp, (ulong) scsiqp);
     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
 
@@ -7786,7 +7279,7 @@
      * completed ADV_SCSI_REQ_Q structure.
      */
     reqp = (adv_req_t *) ADV_U32_TO_VADDR(scsiqp->srb_ptr);
-    ASC_DBG1(1, "adv_isr_callback: reqp %lx\n", (ulong) reqp);
+    ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong) reqp);
     if (reqp == NULL) {
         ASC_PRINT("adv_isr_callback: reqp is NULL\n");
         return;
@@ -7801,7 +7294,7 @@
      * determined.
      */
     scp = reqp->cmndp;
-    ASC_DBG1(1, "adv_isr_callback: scp %lx\n", (ulong) scp);
+    ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong) scp);
     if (scp == NULL) {
         ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
         return;
@@ -7824,18 +7317,17 @@
      */
     if (i == asc_board_count) {
         ASC_PRINT2(
-            "adv_isr_callback: scp %lx has bad host pointer, host %lx\n",
+            "adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
             (ulong) scp, (ulong) shp);
         return;
     }
 
     ASC_STATS(shp, callback);
-    ASC_DBG1(1, "adv_isr_callback: shp %lx\n", (ulong) shp);
+    ASC_DBG1(1, "adv_isr_callback: shp 0x%lx\n", (ulong) shp);
 
     /*
      * If the request isn't found on the active queue, it may have been
-     * removed to handle a reset or abort request. Display a message and
-     * return.
+     * removed to handle a reset request. Display a message and return.
      *
      * Note: Because the structure may still be in use don't attempt
      * to free the adv_req_t and adv_sgblk_t, if any, structures.
@@ -7844,7 +7336,7 @@
     ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
     if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
         ASC_PRINT2(
-            "adv_isr_callback: board %d: scp %lx not on active queue\n",
+            "adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
             boardp->id, (ulong) scp);
         return;
     }
@@ -7857,20 +7349,21 @@
         ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
         scp->result = 0;
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,3,19)
+#if ASC_LINUX_KERNEL24
         /*
          * Check for an underrun condition.
          *
          * If there was no error and an underrun condition, then
          * then return the number of underrun bytes.
          */
-        if (scp->request_bufflen != 0 && scsiqp->data_cnt != 0 &&
-            scsiqp->data_cnt <= scp->request_bufflen) {
+        resid_cnt = le32_to_cpu(scsiqp->data_cnt);
+        if (scp->request_bufflen != 0 && resid_cnt != 0 &&
+            resid_cnt <= scp->request_bufflen) {
             ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
-            (ulong) scsiqp->data_cnt);
-            scp->resid = scsiqp->data_cnt;
+                (ulong) resid_cnt);
+            scp->resid = resid_cnt;
         }
-#endif /* version >= v2.3.19 */
+#endif
         break;
 
     case QD_WITH_ERROR:
@@ -7900,7 +7393,7 @@
 
         default:
             /* Some other QHSTA error occurred. */
-            ASC_DBG1(1, "adv_isr_callback: host_status %x\n",
+            ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
                 scsiqp->host_status);
             scp->result = HOST_BYTE(DID_BAD_TARGET);
             break;
@@ -7913,7 +7406,7 @@
         break;
 
     default:
-        ASC_DBG1(1, "adv_isr_callback: done_status %x\n", scsiqp->done_status);
+        ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", scsiqp->done_status);
         scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
         break;
     }
@@ -7929,7 +7422,7 @@
         boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
     }
 
-    /* 
+    /*
      * Because interrupts may be enabled by the 'Scsi_Cmnd' done
      * function, add the command to the end of the board's done queue.
      * The done function for the command will be called from
@@ -8000,415 +7493,6 @@
     }
 }
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-/*
- * Search for an AdvanSys PCI device in the PCI configuration space.
- */
-ASC_INITFUNC(
-STATIC int,
-asc_srch_pci_dev(PCI_DEVICE *pciDevice)
-)
-{
-    int                        ret = PCI_DEVICE_NOT_FOUND;
-
-    ASC_DBG(2, "asc_srch_pci_dev: begin\n");
-
-    if (pci_scan_method == -1) {
-        pci_scan_method = asc_scan_method();
-    }
-    pciDevice->type = pci_scan_method;
-    ASC_DBG1(2, "asc_srch_pci_dev: type %d\n", pciDevice->type);
-
-    ret = asc_pci_find_dev(pciDevice);
-    ASC_DBG1(2, "asc_srch_pci_dev: asc_pci_find_dev() return %d\n", ret);
-    if (ret == PCI_DEVICE_FOUND) {
-        pciDevice->slotNumber = pciDevice->slotFound + 1;
-        pciDevice->startSlot = pciDevice->slotFound + 1;
-    } else {
-        if (pciDevice->bridge > pciDevice->busNumber) {
-            ASC_DBG2(2, "asc_srch_pci_dev: bridge %x, busNumber %x\n",
-                pciDevice->bridge, pciDevice->busNumber);
-            pciDevice->busNumber++;
-            pciDevice->slotNumber = 0;
-            pciDevice->startSlot = 0;
-            pciDevice->endSlot = 0x0f;
-            ret = asc_srch_pci_dev(pciDevice);
-            ASC_DBG1(2, "asc_srch_pci_dev: recursive call return %d\n", ret);
-        }
-    }
-
-    ASC_DBG1(2, "asc_srch_pci_dev: return %d\n", ret);
-    return ret;
-}
-
-/*
- * Determine the access method to be used for 'pciDevice'.
- */
-ASC_INITFUNC(
-STATIC uchar,
-asc_scan_method(void)
-)
-{
-    ushort      data;
-    PCI_DATA    pciData;
-    uchar       type;
-    uchar       slot;
-
-    ASC_DBG(2, "asc_scan_method: begin\n");
-    memset(&pciData, 0, sizeof(pciData));
-    for (type = 1; type < 3; type++) {
-        pciData.type = type;
-        for (slot = 0; slot < PCI_MAX_SLOT; slot++) {
-            pciData.slot = slot;
-            data = asc_get_cfg_word(&pciData);
-            if ((data != 0xFFFF) && (data != 0x0000)) {
-                ASC_DBG2(4, "asc_scan_method: data %x, type %d\n", data, type);
-                return (type);
-            }
-        }
-    }
-    ASC_DBG1(4, "asc_scan_method: type %d\n", type);
-    return (type);
-}
-
-/*
- * Check for an AdvanSys PCI device in 'pciDevice'.
- *
- * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND.
- */
-ASC_INITFUNC(
-STATIC int,
-asc_pci_find_dev(PCI_DEVICE *pciDevice)
-)
-{
-    PCI_DATA    pciData;
-    ushort      vendorid, deviceid;
-    uchar       classcode, subclass;
-    uchar       lslot;
-
-    ASC_DBG(3, "asc_pci_find_dev: begin\n");
-    pciData.type = pciDevice->type;
-    pciData.bus = pciDevice->busNumber;
-    pciData.func = pciDevice->devFunc;
-    lslot = pciDevice->startSlot;
-    for (; lslot < pciDevice->endSlot; lslot++) {
-        pciData.slot = lslot;
-        pciData.offset = VENDORID_OFFSET;
-        vendorid = asc_get_cfg_word(&pciData);
-        ASC_DBG1(3, "asc_pci_find_dev: vendorid %x\n", vendorid);
-        if (vendorid != 0xffff) {
-            pciData.offset = DEVICEID_OFFSET;
-            deviceid = asc_get_cfg_word(&pciData);
-            ASC_DBG1(3, "asc_pci_find_dev: deviceid %x\n", deviceid);
-            if ((vendorid == ASC_PCI_VENDORID) &&
-                ((deviceid == ASC_PCI_DEVICE_ID_1100) ||
-                 (deviceid == ASC_PCI_DEVICE_ID_1200) ||
-                 (deviceid == ASC_PCI_DEVICE_ID_1300) ||
-                 (deviceid == ASC_PCI_DEVICE_ID_2300) ||
-                 (deviceid == ASC_PCI_DEVICE_ID_2500))) {
-                pciDevice->slotFound = lslot;
-                ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n");
-                return PCI_DEVICE_FOUND;
-            } else {
-                pciData.offset = SUBCLASS_OFFSET;
-                subclass = asc_get_cfg_byte(&pciData);
-                pciData.offset = CLASSCODE_OFFSET;
-                classcode = asc_get_cfg_byte(&pciData);
-                if ((classcode & PCI_BASE_CLASS_BRIDGE_DEVICE) &&
-                    (subclass & PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER)) {
-                    pciDevice->bridge++;
-                }
-                ASC_DBG2(3, "asc_pci_find_dev: subclass %x, classcode %x\n",
-                    subclass, classcode);
-            }
-        }
-    }
-    return PCI_DEVICE_NOT_FOUND;
-}
-
-/*
- * Read PCI configuration data into 'pciConfig'.
- */
-ASC_INITFUNC(
-STATIC void,
-asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)
-)
-{
-    PCI_DATA    pciData;
-    uchar       counter;
-    uchar       *localConfig;
-
-    ASC_DBG1(4, "asc_get_pci_cfg: slotFound %d\n ",
-        pciDevice->slotFound);
-
-    pciData.type = pciDevice->type;
-    pciData.bus = pciDevice->busNumber;
-    pciData.slot = pciDevice->slotFound;
-    pciData.func = pciDevice->devFunc;
-    localConfig = (uchar *) pciConfig;
-
-    for (counter = 0; counter < sizeof(PCI_CONFIG_SPACE); counter++) {
-        pciData.offset = counter;
-        *localConfig = asc_get_cfg_byte(&pciData);
-        ASC_DBG1(4, "asc_get_pci_cfg: byte %x\n", *localConfig);
-        localConfig++;
-    }
-    ASC_DBG1(4, "asc_get_pci_cfg: counter %d\n", counter);
-}
-
-/*
- * Read a word (16 bits) from the PCI configuration space.
- *
- * The configuration mechanism is checked for the correct access method.
- */
-ASC_INITFUNC(
-STATIC ushort,
-asc_get_cfg_word(PCI_DATA *pciData)
-)
-{
-    ushort   tmp;
-    ADV_DCNT address;
-    ADV_DCNT lbus = pciData->bus;
-    ADV_DCNT lslot = pciData->slot;
-    ADV_DCNT lfunc = pciData->func;
-    uchar    t2CFA, t2CF8;
-    ADV_DCNT t1CF8, t1CFC;
-
-    ASC_DBG4(4, "asc_get_cfg_word: type %d, bus %u, slot %u, func %u\n",
-        pciData->type, (unsigned) lbus, (unsigned) lslot, (unsigned) lfunc);
-
-    /*
-     * Check type of configuration mechanism.
-     */
-    if (pciData->type == 2) {
-        /*
-         * Save registers to be restored later.
-         */
-        t2CFA = inp(0xCFA);    /* save PCI bus register */
-        t2CF8 = inp(0xCF8);    /* save config space enable register */
-
-        /*
-         * Write the bus and enable registers.
-         */
-        /* set for type 1 cycle, if needed */
-        outp(0xCFA, pciData->bus);
-        /* set the function number */
-        outp(0xCF8, 0x10 | (pciData->func << 1));
-
-        /*
-         * Read the configuration space type 2 locations.
-         */
-        tmp = (ushort) inpw(0xC000 | ((pciData->slot << 8) + pciData->offset));
-
-        outp(0xCFA, t2CFA);    /* save PCI bus register */
-        outp(0xCF8, t2CF8);    /* save config space enable register */
-    } else {
-        /*
-         * Type 1 or 3 configuration mechanism.
-         *
-         * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
-         */
-        t1CF8 = inpl(0xCF8);
-        t1CFC = inpl(0xCFC);
-
-        /*
-         * enable <31>, bus = <23:16>, slot = <15:11>,
-         * func = <10:8>, reg = <7:2>
-         */
-        address = (ADV_DCNT) ((lbus << 16) | (lslot << 11) |
-            (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
-
-        /*
-         * Write out the address to CONFIG_ADDRESS.
-         */
-        outpl(0xCF8, address);
-
-        /*
-         * Read in word from CONFIG_DATA.
-         */
-        tmp = (ushort) ((inpl(0xCFC) >>
-                 ((pciData->offset & 2) * 8)) & 0xFFFF);
-
-        /*
-         * Restore registers.
-         */
-        outpl(0xCF8, t1CF8);
-        outpl(0xCFC, t1CFC);
-    }
-    ASC_DBG1(4, "asc_get_cfg_word: config data: %x\n", tmp);
-    return tmp;
-}
-
-/*
- * Reads a byte from the PCI configuration space.
- *
- * The configuration mechanism is checked for the correct access method.
- */
-ASC_INITFUNC(
-STATIC uchar,
-asc_get_cfg_byte(PCI_DATA *pciData)
-)
-{
-    uchar    tmp;
-    ADV_DCNT address;
-    ADV_DCNT lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
-    ADV_DCNT t2CFA, t2CF8;
-    ADV_DCNT t1CF8, t1CFC;
-
-    ASC_DBG1(4, "asc_get_cfg_byte: type: %d\n", pciData->type);
-
-    /*
-     * Check type of configuration mechanism.
-     */
-    if (pciData->type == 2) {
-        /*
-         * Save registers to be restored later.
-         */
-        t2CFA = inp(0xCFA);    /* save PCI bus register */
-        t2CF8 = inp(0xCF8);    /* save config space enable register */
-
-        /*
-         * Write the bus and enable registers.
-         */
-        /* set for type 1 cycle, if needed */
-        outp(0xCFA, pciData->bus);
-        /* set the function number */
-        outp(0xCF8, 0x10 | (pciData->func << 1));
-
-        /*
-         * Read configuration space type 2 locations.
-         */
-        tmp = inp(0xC000 | ((pciData->slot << 8) + pciData->offset));
-
-        /*
-         * Restore registers.
-         */
-        outp(0xCF8, t2CF8);    /* restore the enable register */
-        outp(0xCFA, t2CFA);    /* restore PCI bus register */
-    } else {
-        /*
-         * Type 1 or 3 configuration mechanism.
-         *
-         * Save CONFIG_ADDRESS and CONFIG_DATA register values.
-         */
-        t1CF8 = inpl(0xCF8);
-        t1CFC = inpl(0xCFC);
-
-        /*
-         * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
-         * reg = <7:2>
-         */
-        address = (ADV_DCNT) ((lbus << 16) | (lslot << 11) |
-            (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
-
-        /*
-         * Write out address to CONFIG_ADDRESS.
-         */
-        outpl(0xCF8, address);
-
-        /*
-         * Read in word from CONFIG_DATA.
-         */
-        tmp = (uchar) ((inpl(0xCFC) >> ((pciData->offset & 3) * 8)) & 0xFF);
-
-        /*
-         * Restore registers.
-         */
-        outpl(0xCF8, t1CF8);
-        outpl(0xCFC, t1CFC);
-    }
-    ASC_DBG1(4, "asc_get_cfg_byte: config data: %x\n", tmp);
-    return tmp;
-}
-
-/*
- * Write a byte to the PCI configuration space.
- */
-ASC_INITFUNC(
-STATIC void,
-asc_put_cfg_byte(PCI_DATA *pciData, uchar byte_data)
-)
-{
-    ADV_DCNT tmpl;
-    ADV_DCNT address;
-    ADV_DCNT lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
-    uchar    t2CFA, t2CF8;
-    ADV_DCNT t1CF8, t1CFC;
-
-    ASC_DBG2(4, "asc_put_cfg_byte: type: %d, byte_data %x\n",
-        pciData->type, byte_data);
-
-    /*
-     * Check type of configuration mechanism.
-     */
-    if (pciData->type == 2) {
-
-        /*
-         * Save registers to be restored later.
-         */
-        t2CFA = inp(0xCFA);    /* save PCI bus register */
-        t2CF8 = inp(0xCF8);    /* save config space enable register */
-
-        /*
-         * Write bus and enable registers.
-         */
-        outp(0xCFA, pciData->bus);
-
-        /*
-         * Set the function number.
-         */
-        outp(0xCF8, 0x10 | (pciData->func << 1));
-
-        /*
-         * Write the configuration space type 2 locations.
-         */
-        outp(0xC000 | ((pciData->slot << 8) + pciData->offset), byte_data);
-
-        /*
-         * Restore registers.
-         */
-        outp(0xCF8, t2CF8);    /* restore the enable register */
-        outp(0xCFA, t2CFA);    /* restore PCI bus register    */
-    } else {
-
-        /*
-         * Type 1 or 3 configuration mechanism.
-         *
-         * Save the CONFIG_ADDRESS and CONFIG_DATA register values.
-         */
-        t1CF8 = inpl(0xCF8);
-        t1CFC = inpl(0xCFC);
-
-        /*
-         * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
-         * reg = <7:2>
-         */
-        address = (ADV_DCNT) ((lbus << 16) | (lslot << 11) | (lfunc << 8) |
-                (pciData->offset & 0xFC) | 0x80000000L);
-        /*
-         * Write out address to CONFIG_ADDRESS.
-         */
-        outpl(0xCF8, address);
-
-        /*
-         * Write double word to CONFIG_DATA preserving the bytes
-         * in the double not written.
-         */
-        tmpl = inpl(0xCFC) & ~(0xFF << ((pciData->offset & 3) * 8));
-        outpl(0xCFC, tmpl | (byte_data << ((pciData->offset & 3) * 8)));
-
-        /*
-         * Restore registers.
-         */
-        outpl(0xCF8, t1CF8);
-        outpl(0xCFC, t1CFC);
-    }
-    ASC_DBG(4, "asc_put_cfg_byte: end\n");
-}
-#endif /* ASC_CONFIG_PCI */
-#endif /* version < v2.1.93 */
-
 /*
  * Add a 'REQP' to the end of specified queue. Set 'tidmask'
  * to indicate a command is queued for the device.
@@ -8422,9 +7506,8 @@
 {
     int        tid;
 
-    ASC_DBG3(3, "asc_enqueue: ascq %lx, reqp %lx, flag %d\n",
+    ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
         (ulong) ascq, (ulong) reqp, flag);
-    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
     ASC_ASSERT(reqp != NULL);
     ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
     tid = REQPTID(reqp);
@@ -8460,7 +7543,7 @@
     }
     REQPTIME(reqp) = REQTIMESTAMP();
 #endif /* ADVANSYS_STATS */
-    ASC_DBG1(3, "asc_enqueue: reqp %lx\n", (ulong) reqp);
+    ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong) reqp);
     return;
 }
 
@@ -8476,8 +7559,7 @@
 {
     REQP    reqp;
 
-    ASC_DBG2(3, "asc_dequeue: ascq %lx, tid %d\n", (ulong) ascq, tid);
-    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
+    ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
     if ((reqp = ascq->q_first[tid]) != NULL) {
         ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
@@ -8495,7 +7577,7 @@
         REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
 #endif /* ADVANSYS_STATS */
     }
-    ASC_DBG1(3, "asc_dequeue: reqp %lx\n", (ulong) reqp);
+    ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong) reqp);
     return reqp;
 }
 
@@ -8503,7 +7585,7 @@
  * Return a pointer to a singly linked list of all the requests queued
  * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
  *
- * If 'lastpp' is not NULL, '*lastpp' will be set to point to the 
+ * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
  * the last request returned in the singly linked list.
  *
  * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
@@ -8525,8 +7607,7 @@
     REQP    firstp, lastp;
     int     i;
 
-    ASC_DBG2(3, "asc_dequeue_list: ascq %lx, tid %d\n", (ulong) ascq, tid);
-    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
+    ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
     ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
 
     /*
@@ -8586,7 +7667,7 @@
     if (lastpp) {
         *lastpp = lastp;
     }
-    ASC_DBG1(3, "asc_dequeue_list: firstp %lx\n", (ulong) firstp);
+    ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong) firstp);
     return firstp;
 }
 
@@ -8607,9 +7688,8 @@
     int         tid;
     int         ret = ASC_FALSE;
 
-    ASC_DBG2(3, "asc_rmqueue: ascq %lx, reqp %lx\n",
+    ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
         (ulong) ascq, (ulong) reqp);
-    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
     ASC_ASSERT(reqp != NULL);
 
     tid = REQPTID(reqp);
@@ -8660,37 +7740,7 @@
     }
     ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
 #endif /* ADVANSYS_STATS */
-    ASC_DBG2(3, "asc_rmqueue: reqp %lx, ret %d\n", (ulong) reqp, ret);
-    return ret;
-}
-
-/*
- * If the specified 'REQP' is queued on the specified queue for
- * the specified target device, return ASC_TRUE.
- */
-STATIC int
-asc_isqueued(asc_queue_t *ascq, REQP reqp)
-{
-    REQP        treqp;
-    int            tid;
-    int            ret = ASC_FALSE;
-
-    ASC_DBG2(3, "asc_isqueued: ascq %lx, reqp %lx\n",
-        (ulong) ascq, (ulong) reqp);
-    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
-    ASC_ASSERT(reqp != NULL);
-
-    tid = REQPTID(reqp);
-    ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
-
-    for (treqp = ascq->q_first[tid]; treqp; treqp = REQPNEXT(treqp)) {
-        ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
-        if (treqp == reqp) {
-            ret = ASC_TRUE;
-            break;
-        }
-    }
-    ASC_DBG1(3, "asc_isqueued: ret %x\n", ret);
+    ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong) reqp, ret);
     return ret;
 }
 
@@ -8706,8 +7756,7 @@
     REQP                    reqp;
     int                     i;
 
-    ASC_DBG1(1, "asc_execute_queue: ascq %lx\n", (ulong) ascq);
-    ASC_ASSERT(advansys_interrupts_enabled() == ASC_FALSE);
+    ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong) ascq);
     /*
      * Execute queued commands for devices attached to
      * the current board in round-robin fashion.
@@ -8721,7 +7770,10 @@
                 } else if (asc_execute_scsi_cmnd((Scsi_Cmnd *) reqp)
                             == ASC_BUSY) {
                     scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
-                    /* Put the request back at front of the list. */
+                    /*
+                     * The request returned ASC_BUSY. Enqueue at the front of
+                     * target's waiting list to maintain correct ordering.
+                     */
                     asc_enqueue(ascq, reqp, ASC_FRONT);
                 }
             }
@@ -8730,7 +7782,7 @@
     return;
 }
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0)
+#ifdef CONFIG_PROC_FS
 /*
  * asc_prt_board_devices()
  *
@@ -8810,7 +7862,7 @@
 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
         ASC_PRT_NEXT();
         len = asc_prt_line(cp, leftlen,
-"can be found at the AdvanSys FTP site: ftp://ftp.advansys.com/pub\n");
+"can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
         ASC_PRT_NEXT();
     } else {
         major = (boardp->bios_version >> 12) & 0xF;
@@ -8829,10 +7881,10 @@
         if (major < 3 || (major <= 3 && minor < 1) ||
             (major <= 3 && minor <= 1 && letter < ('I'- 'A'))) {
             len = asc_prt_line(cp, leftlen,
-"Newer version of ROM BIOS is available at the AdvanSys FTP site:\n");
+"Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
             ASC_PRT_NEXT();
             len = asc_prt_line(cp, leftlen,
-"ftp://ftp.advansys.com/pub\n");
+"ftp://ftp.connectcom.net/pub\n");
             ASC_PRT_NEXT();
         }
     }
@@ -8960,7 +8012,9 @@
     int                len;
     ASCEEP_CONFIG      *ep;
     int                i;
+#ifdef CONFIG_ISA
     int                isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
+#endif /* CONFIG_ISA */
     uchar              serialstr[13];
 
     boardp = ASC_BOARDP(shp);
@@ -8992,11 +8046,11 @@
 
     len = asc_prt_line(cp, leftlen,
 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
-        ep->chip_scsi_id, ep->max_total_qng, ep->max_tag_qng);
+        ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, ep->max_tag_qng);
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-" cntl %x, no_scam %x\n",
+" cntl 0x%x, no_scam 0x%x\n",
         ep->cntl, ep->no_scam);
     ASC_PRT_NEXT();
 
@@ -9054,12 +8108,14 @@
     len = asc_prt_line(cp, leftlen, "\n");
     ASC_PRT_NEXT();
 
+#ifdef CONFIG_ISA
     if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
         len = asc_prt_line(cp, leftlen,
 " Host ISA DMA speed:   %d MB/S\n",
-            isa_dma_speed[ep->isa_dma_speed]);
+            isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
         ASC_PRT_NEXT();
     }
+#endif /* CONFIG_ISA */
 
      return totlen;
 }
@@ -9088,6 +8144,7 @@
     uchar                       serialstr[13];
     ADVEEP_3550_CONFIG          *ep_3550 = NULL;
     ADVEEP_38C0800_CONFIG       *ep_38C0800 = NULL;
+    ADVEEP_38C1600_CONFIG       *ep_38C1600 = NULL;
     ushort                      word;
     ushort                      *wordp;
     ushort                      sdtr_speed = 0;
@@ -9097,9 +8154,12 @@
     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
     {
         ep_3550 = &boardp->eep_config.adv_3550_eep;
-    } else
+    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
     {
         ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
+    } else
+    {
+        ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
     }
 
     leftlen = cplen;
@@ -9112,9 +8172,12 @@
     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
     {
         wordp = &ep_3550->serial_number_word1;
-    } else
+    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
     {
         wordp = &ep_38C0800->serial_number_word1;
+    } else
+    {
+        wordp = &ep_38C1600->serial_number_word1;
     }
 
     if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
@@ -9133,20 +8196,30 @@
             ep_3550->adapter_scsi_id, ep_3550->max_host_qng,
             ep_3550->max_dvc_qng);
         ASC_PRT_NEXT();
-    } else
+    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
     {
         len = asc_prt_line(cp, leftlen,
 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
             ep_38C0800->adapter_scsi_id, ep_38C0800->max_host_qng,
             ep_38C0800->max_dvc_qng);
         ASC_PRT_NEXT();
+    } else
+    {
+        len = asc_prt_line(cp, leftlen,
+" Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
+            ep_38C1600->adapter_scsi_id, ep_38C1600->max_host_qng,
+            ep_38C1600->max_dvc_qng);
+        ASC_PRT_NEXT();
     }
     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
     {
         word = ep_3550->termination;
-    } else
+    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
     {
         word = ep_38C0800->termination_lvd;
+    } else
+    {
+        word = ep_38C1600->termination_lvd;
     }
     switch (word) {
         case 1:
@@ -9167,15 +8240,21 @@
     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
     {
         len = asc_prt_line(cp, leftlen,
-" termination: %u (%s), bios_ctrl: %x\n",
+" termination: %u (%s), bios_ctrl: 0x%x\n",
             ep_3550->termination, termstr, ep_3550->bios_ctrl);
         ASC_PRT_NEXT();
-    } else
+    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
     {
         len = asc_prt_line(cp, leftlen,
-" termination: %u (%s), bios_ctrl: %x\n",
+" termination: %u (%s), bios_ctrl: 0x%x\n",
             ep_38C0800->termination_lvd, termstr, ep_38C0800->bios_ctrl);
         ASC_PRT_NEXT();
+    } else
+    {
+        len = asc_prt_line(cp, leftlen,
+" termination: %u (%s), bios_ctrl: 0x%x\n",
+            ep_38C1600->termination_lvd, termstr, ep_38C1600->bios_ctrl);
+        ASC_PRT_NEXT();
     }
 
     len = asc_prt_line(cp, leftlen,
@@ -9191,9 +8270,12 @@
     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
     {
         word = ep_3550->disc_enable;
-    } else
+    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
     {
         word = ep_38C0800->disc_enable;
+    } else
+    {
+        word = ep_38C1600->disc_enable;
     }
     len = asc_prt_line(cp, leftlen,
 " Disconnects:         ");
@@ -9209,9 +8291,12 @@
     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
     {
         word = ep_3550->tagqng_able;
-    } else
+    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
     {
         word = ep_38C0800->tagqng_able;
+    } else
+    {
+        word = ep_38C1600->tagqng_able;
     }
     len = asc_prt_line(cp, leftlen,
 " Command Queuing:     ");
@@ -9227,9 +8312,12 @@
     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
     {
         word = ep_3550->start_motor;
-    } else
+    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
     {
         word = ep_38C0800->start_motor;
+    } else
+    {
+        word = ep_38C1600->start_motor;
     }
     len = asc_prt_line(cp, leftlen,
 " Start Motor:         ");
@@ -9273,9 +8361,12 @@
     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
     {
         word = ep_3550->wdtr_able;
-    } else
+    } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
     {
         word = ep_38C0800->wdtr_able;
+    } else
+    {
+        word = ep_38C1600->wdtr_able;
     }
     len = asc_prt_line(cp, leftlen,
 " Wide Transfer:       ");
@@ -9288,7 +8379,8 @@
     len = asc_prt_line(cp, leftlen, "\n");
     ASC_PRT_NEXT();
 
-    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
+    if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
+        adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600)
     {
         len = asc_prt_line(cp, leftlen,
 " Synchronous Transfer Speed (Mhz):\n  ");
@@ -9352,9 +8444,7 @@
     int                    totlen;
     int                    len;
     int                    chip_scsi_id;
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
     int                    i;
-#endif /* version >= v1.3.89 */
 
     boardp = ASC_BOARDP(shp);
 
@@ -9367,39 +8457,31 @@
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
-" host_busy %u, last_reset %u, max_id %u, max_lun %u\n",
-        shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun);
-#else /* version >= v1.3.89 */
 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
         shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
         shp->max_channel);
-#endif /* version >= v1.3.89 */
     ASC_PRT_NEXT();
-    
+
     len = asc_prt_line(cp, leftlen,
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57)
-" can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
-        shp->can_queue, shp->this_id, shp->sg_tablesize, shp->cmd_per_lun);
-#else /* version >= v1.3.57 */
 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
         shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
         shp->cmd_per_lun);
-#endif /* version >= v1.3.57 */
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,57)
-" unchecked_isa_dma %d, loaded_as_module %d\n",
-        shp->unchecked_isa_dma, shp->loaded_as_module);
-#else /* version >= v1.3.57 */
 " unchecked_isa_dma %d, use_clustering %d, loaded_as_module %d\n",
         shp->unchecked_isa_dma, shp->use_clustering, shp->loaded_as_module);
-#endif /* version >= v1.3.57 */
     ASC_PRT_NEXT();
 
-    len = asc_prt_line(cp, leftlen, " flags %x, last_reset %x, jiffies %x\n",
-        boardp->flags, boardp->last_reset, jiffies);
+    len = asc_prt_line(cp, leftlen,
+" flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
+        boardp->flags, boardp->last_reset, jiffies, boardp->asc_n_io_port);
+    ASC_PRT_NEXT();
+
+     /* 'shp->n_io_port' may be truncated because it is only one byte. */
+    len = asc_prt_line(cp, leftlen,
+" io_port 0x%x, n_io_port 0x%x\n",
+        shp->io_port, shp->n_io_port);
     ASC_PRT_NEXT();
 
     if (ASC_NARROW_BOARD(boardp)) {
@@ -9408,7 +8490,6 @@
         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
     }
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
     if (boardp->flags & ASC_SELECT_QUEUE_DEPTHS) {
         len = asc_prt_line(cp, leftlen, " queue_depth:");
         ASC_PRT_NEXT();
@@ -9427,7 +8508,6 @@
         len = asc_prt_line(cp, leftlen, "\n");
         ASC_PRT_NEXT();
     }
-#endif /* version >= v1.3.89 */
 
     return totlen;
 }
@@ -9470,12 +8550,12 @@
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-" chip_version %u, lib_version %x, lib_serial_no %u, mcode_date %x\n",
+" chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
         c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-" mcode_version %x, err_code %u\n",
+" mcode_version 0x%x, err_code %u\n",
          c->mcode_version, v->err_code);
     ASC_PRT_NEXT();
 
@@ -9663,14 +8743,14 @@
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-" iop_base %lx, cable_detect: %X, err_code %u\n",
+" iop_base 0x%lx, cable_detect: %X, err_code %u\n",
          v->iop_base,
          AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
          v->err_code);
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-" chip_version %u, lib_version %x, mcode_date %x, mcode_version %x\n",
+" chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
         c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
     ASC_PRT_NEXT();
 
@@ -9862,7 +8942,7 @@
 }
 
 /*
- * asc_proc_copy() 
+ * asc_proc_copy()
  *
  * Copy proc information to a read buffer taking into account the current
  * read offset in the file and the remaining space in the read buffer.
@@ -9872,13 +8952,13 @@
               char *cp, int cplen)
 {
     int cnt = 0;
-    
+
     ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
             (unsigned) offset, (unsigned) advoffset, cplen);
     if (offset <= advoffset) {
         /* Read offset below current offset, copy everything. */
         cnt = ASC_MIN(cplen, leftlen);
-        ASC_DBG3(2, "asc_proc_copy: curbuf %lx, cp %lx, cnt %d\n",
+        ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
                 (ulong) curbuf, (ulong) cp, cnt);
         memcpy(curbuf, cp, cnt);
     } else if (offset < advoffset + cplen) {
@@ -9886,7 +8966,7 @@
         cnt = (advoffset + cplen) - offset;
         cp = (cp + cplen) - cnt;
         cnt = ASC_MIN(cnt, leftlen);
-        ASC_DBG3(2, "asc_proc_copy: curbuf %lx, cp %lx, cnt %d\n",
+        ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
                 (ulong) curbuf, (ulong) cp, cnt);
         memcpy(curbuf, cp, cnt);
     }
@@ -9924,7 +9004,7 @@
     va_end(args);
     return ret;
 }
-#endif /* version >= v1.3.0 */
+#endif /* CONFIG_PROC_FS */
 
 
 /*
@@ -9940,56 +9020,33 @@
 STATIC void
 DvcSleepMilliSecond(ADV_DCNT n)
 {
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,0)
-    ADV_DCNT i;
-#endif /* version < v2.1.0 */ 
-
     ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong) n);
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,1,0)
     mdelay(n);
-#else /* version < v2.1.0 */ 
-    for (i = 0; i < n; i++) {
-        udelay(1000);
-    }
-#endif /* version < v2.1.0 */ 
 }
 
-STATIC int
+/*
+ * Currently and inline noop but leave as a placeholder.
+ * Leave DvcEnterCritical() as a noop placeholder.
+ */
+STATIC inline ulong
 DvcEnterCritical(void)
 {
-    int    flags;
-
-    save_flags(flags);
-    cli();
-    return flags;
+    return 0;
 }
 
-STATIC void
-DvcLeaveCritical(int flags)
+/*
+ * Critical sections are all protected by the board spinlock.
+ * Leave DvcLeaveCritical() as a noop placeholder.
+ */
+STATIC inline void
+DvcLeaveCritical(ulong flags)
 {
-    restore_flags(flags);
-}
-
-STATIC ADV_DCNT
-DvcGetSGList(ASC_DVC_VAR *asc_dvc_sg, uchar *buf_addr, ADV_DCNT buf_len,
-             ASC_SG_HEAD *asc_sg_head_ptr)
-{
-    ADV_DCNT buf_size;
-
-    buf_size = buf_len;
-    asc_sg_head_ptr->entry_cnt = 1;
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
-    asc_sg_head_ptr->sg_list[0].addr = (ADV_PADDR) buf_addr;
-#else /* version >= v2.0.0 */
-    asc_sg_head_ptr->sg_list[0].addr = virt_to_bus(buf_addr);
-#endif /* version >= v2.0.0 */
-    asc_sg_head_ptr->sg_list[0].bytes = buf_size;
-    return buf_size;
+    return;
 }
 
 /*
  * void
- * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
+ * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
  *
  * Calling/Exit State:
  *    none
@@ -9998,23 +9055,24 @@
  *     Output an ASC_SCSI_Q structure to the chip
  */
 STATIC void
-DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
+DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
 {
     int    i;
 
-    ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", (uchar *) outbuf, 2 * words);
+    ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
     AscSetChipLramAddr(iop_base, s_addr);
-    for (i = 0; i < words; i++, outbuf++) {
-        if (i == 2 || i == 10) {
+    for (i = 0; i < 2 * words; i += 2) {
+        if (i == 4 || i == 20) {
             continue;
         }
-        AscSetChipLramDataNoSwap(iop_base, *outbuf);
+        outpw(iop_base + IOP_RAM_DATA,
+            ((ushort) outbuf[i + 1] << 8) | outbuf[i]);
     }
 }
 
 /*
  * void
- * DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
+ * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
  *
  * Calling/Exit State:
  *    none
@@ -10023,79 +9081,21 @@
  *     Input an ASC_QDONE_INFO structure from the chip
  */
 STATIC void
-DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
+DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
 {
     int    i;
+    ushort word;
 
     AscSetChipLramAddr(iop_base, s_addr);
-    for (i = 0; i < words; i++, inbuf++) {
-        if (i == 5) {
+    for (i = 0; i < 2 * words; i += 2) {
+        if (i == 10) {
             continue;
         }
-        *inbuf = AscGetChipLramDataNoSwap(iop_base);
-    }
-    ASC_DBG_PRT_HEX(2, "DvcGetQinfo", (uchar *) inbuf, 2 * words);
-}
-
-/*
- * void    DvcOutPortWords(ushort iop_base, ushort &outbuf, int words)
- *
- * Calling/Exit State:
- *    none
- *
- * Description:
- *     output a buffer to an i/o port address
- */
-STATIC void
-DvcOutPortWords(ushort iop_base, ushort *outbuf, int words)
-{
-    int    i;
-
-    for (i = 0; i < words; i++, outbuf++)
-        outpw(iop_base, *outbuf);
-}
-
-/*
- * void    DvcInPortWords(ushort iop_base, ushort &outbuf, int words)
- *
- * Calling/Exit State:
- *    none
- *
- * Description:
- *     input a buffer from an i/o port address
- */
-STATIC void
-DvcInPortWords(ushort iop_base, ushort *inbuf, int words)
-{
-    int    i;
-
-    for (i = 0; i < words; i++, inbuf++)
-        *inbuf = inpw(iop_base);
-}
-
-/*
- * void DvcOutPortDWords(PortAddr port, ADV_DCNT *pdw, int dwords)
- *
- * Calling/Exit State:
- *    none
- *
- * Description:
- *     output a buffer of 32-bit integers to an i/o port address in
- *  16 bit integer units
- */
-STATIC void  
-DvcOutPortDWords(PortAddr port, ADV_DCNT *pdw, int dwords)
-{
-    int       i;
-    int       words;
-    ushort    *pw;
-
-    pw = (ushort *) pdw;
-    words = dwords << 1;
-    for(i = 0; i < words; i++, pw++) {
-        outpw(port, *pw);
+        word = inpw(iop_base + IOP_RAM_DATA);
+        inbuf[i] = word & 0xff;
+        inbuf[i + 1] = (word >> 8) & 0xff;
     }
-    return;
+    ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
 }
 
 /*
@@ -10104,24 +9104,10 @@
 ASC_INITFUNC(
 STATIC uchar,
 DvcReadPCIConfigByte(
-        ASC_DVC_VAR *asc_dvc, 
+        ASC_DVC_VAR *asc_dvc,
         ushort offset)
 )
 {
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-    PCI_DATA    pciData;
-
-    pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
-    pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
-    pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
-    pciData.offset = offset;
-    pciData.type = pci_scan_method;
-    return asc_get_cfg_byte(&pciData);
-#else /* ASC_CONFIG_PCI */
-    return 0;
-#endif /* ASC_CONFIG_PCI */
-#else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
     uchar byte_data;
     pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
@@ -10129,10 +9115,9 @@
             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
         offset, &byte_data);
     return byte_data;
-#else /* CONFIG_PCI */
+#else /* !defined(CONFIG_PCI) */
     return 0;
-#endif /* CONFIG_PCI */
-#endif /* version >= v2.1.93 */ 
+#endif /* !defined(CONFIG_PCI) */
 }
 
 /*
@@ -10141,30 +9126,17 @@
 ASC_INITFUNC(
 STATIC void,
 DvcWritePCIConfigByte(
-        ASC_DVC_VAR *asc_dvc, 
-        ushort offset, 
+        ASC_DVC_VAR *asc_dvc,
+        ushort offset,
         uchar  byte_data)
 )
 {
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-    PCI_DATA    pciData;
-
-    pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
-    pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
-    pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
-    pciData.offset = offset;
-    pciData.type = pci_scan_method;
-    asc_put_cfg_byte(&pciData, byte_data);
-#endif /* ASC_CONFIG_PCI */
-#else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
     pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
         offset, byte_data);
 #endif /* CONFIG_PCI */
-#endif /* version >= v2.1.93 */ 
 }
 
 /*
@@ -10192,6 +9164,7 @@
         return(0);
     }
 
+#ifdef CONFIG_ISA
     if((bus_type & ASC_IS_EISA) != 0)
     {
         cfg_lsw = AscGetEisaChipCfg(iop_base);
@@ -10200,6 +9173,7 @@
                                 (cfg_lsw * ASC_BIOS_BANK_SIZE));
         return(bios_addr);
     }/* if */
+#endif /* CONFIG_ISA */
 
     cfg_lsw = AscGetChipCfgLsw(iop_base);
 
@@ -10238,14 +9212,10 @@
 {
     ADV_PADDR           paddr;
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,0,0)
-    paddr = (ADV_PADDR) vaddr;
-#else /* version >= v2.0.0 */
     paddr = virt_to_bus(vaddr);
-#endif /* version >= v2.0.0 */
 
     ASC_DBG4(4,
-        "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n", 
+        "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
         (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), (ulong) paddr);
 
     return paddr;
@@ -10257,24 +9227,10 @@
 ASC_INITFUNC(
 STATIC uchar,
 DvcAdvReadPCIConfigByte(
-        ADV_DVC_VAR *asc_dvc, 
+        ADV_DVC_VAR *asc_dvc,
         ushort offset)
 )
 {
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-    PCI_DATA    pciData;
-
-    pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
-    pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
-    pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
-    pciData.offset = offset;
-    pciData.type = pci_scan_method;
-    return asc_get_cfg_byte(&pciData);
-#else /* ASC_CONFIG_PCI */
-    return 0;
-#endif /* ASC_CONFIG_PCI */
-#else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
     uchar byte_data;
     pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
@@ -10285,7 +9241,6 @@
 #else /* CONFIG_PCI */
     return 0;
 #endif /* CONFIG_PCI */
-#endif /* version >= v2.1.93 */ 
 }
 
 /*
@@ -10294,30 +9249,19 @@
 ASC_INITFUNC(
 STATIC void,
 DvcAdvWritePCIConfigByte(
-        ADV_DVC_VAR *asc_dvc, 
-        ushort offset, 
+        ADV_DVC_VAR *asc_dvc,
+        ushort offset,
         uchar  byte_data)
 )
 {
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,93)
-#ifdef ASC_CONFIG_PCI
-    PCI_DATA    pciData;
-
-    pciData.bus = ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info);
-    pciData.slot = ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info);
-    pciData.func = ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info);
-    pciData.offset = offset;
-    pciData.type = pci_scan_method;
-    asc_put_cfg_byte(&pciData, byte_data);
-#endif /* ASC_CONFIG_PCI */
-#else /* version >= v2.1.93 */ 
 #ifdef CONFIG_PCI
     pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
         offset, byte_data);
+#else /* CONFIG_PCI */
+    return 0;
 #endif /* CONFIG_PCI */
-#endif /* version >= v2.1.93 */ 
 }
 
 /*
@@ -10325,6 +9269,7 @@
  */
 
 #ifdef ADVANSYS_STATS
+#ifdef CONFIG_PROC_FS
 /*
  * asc_prt_board_stats()
  *
@@ -10341,11 +9286,7 @@
     int                    totlen;
     int                    len;
     struct asc_stats       *s;
-    int                    i;
-    ushort                 chip_scsi_id;
     asc_board_t            *boardp;
-    asc_queue_t            *active;
-    asc_queue_t            *waiting;
 
     leftlen = cplen;
     totlen = len = 0;
@@ -10356,15 +9297,16 @@
     len = asc_prt_line(cp, leftlen,
 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
     ASC_PRT_NEXT();
-    
+
     len = asc_prt_line(cp, leftlen,
-" command %lu, queuecommand %lu, abort %lu, reset %lu, biosparam %lu\n",
-        s->command, s->queuecommand, s->abort, s->reset, s->biosparam);
+" queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
+        s->queuecommand, s->reset, s->biosparam, s->interrupt);
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
-" interrupt %lu, callback %lu, done %lu\n",
-        s->interrupt, s->callback, s->done);
+" callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
+        s->callback, s->done, s->build_error, s->adv_build_noreq,
+        s->adv_build_nosg);
     ASC_PRT_NEXT();
 
     len = asc_prt_line(cp, leftlen,
@@ -10372,17 +9314,6 @@
         s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
     ASC_PRT_NEXT();
 
-    if (ASC_NARROW_BOARD(boardp)) {
-        len = asc_prt_line(cp, leftlen,
-" build_error %lu\n",
-         s->build_error);
-    } else {
-        len = asc_prt_line(cp, leftlen,
-" build_error %lu, build_noreq %lu, build_nosg %lu\n",
-         s->build_error, s->adv_build_noreq, s->adv_build_nosg);
-    }
-    ASC_PRT_NEXT();
-
     /*
      * Display data transfer statistics.
      */
@@ -10437,6 +9368,40 @@
 " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
     ASC_PRT_NEXT();
 
+
+     return totlen;
+}
+
+/*
+ * asc_prt_target_stats()
+ *
+ * Note: no single line should be greater than ASC_PRTLINE_SIZE,
+ * cf. asc_prt_line().
+ *
+ * This is separated from asc_prt_board_stats because a full set
+ * of targets will overflow ASC_PRTBUF_SIZE.
+ *
+ * Return the number of characters copied into 'cp'. No more than
+ * 'cplen' characters will be copied to 'cp'.
+ */
+STATIC int
+asc_prt_target_stats(struct Scsi_Host *shp, int tgt_id, char *cp, int cplen)
+{
+    int                    leftlen;
+    int                    totlen;
+    int                    len;
+    struct asc_stats       *s;
+    ushort                 chip_scsi_id;
+    asc_board_t            *boardp;
+    asc_queue_t            *active;
+    asc_queue_t            *waiting;
+
+    leftlen = cplen;
+    totlen = len = 0;
+
+    boardp = ASC_BOARDP(shp);
+    s = &boardp->asc_stats;
+
     active = &ASC_BOARDP(shp)->active;
     waiting = &ASC_BOARDP(shp)->waiting;
 
@@ -10446,70 +9411,77 @@
         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
     }
 
-    for (i = 0; i <= ADV_MAX_TID; i++) {
-
-        if ((chip_scsi_id == i) ||
-            ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
-            continue;
-        }
+    if ((chip_scsi_id == tgt_id) ||
+        ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
+        return 0;
+    }
 
-        if (active->q_tot_cnt[i] > 0 || waiting->q_tot_cnt[i] > 0) {
-            len = asc_prt_line(cp, leftlen, " target %d\n", i);
+    do {
+        if (active->q_tot_cnt[tgt_id] > 0 || waiting->q_tot_cnt[tgt_id] > 0) {
+            len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
             ASC_PRT_NEXT();
 
             len = asc_prt_line(cp, leftlen,
 "   active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
-                active->q_cur_cnt[i], active->q_max_cnt[i],
-                active->q_tot_cnt[i],
-                active->q_min_tim[i], active->q_max_tim[i],
-                (active->q_tot_cnt[i] == 0) ? 0 :
-                (active->q_tot_tim[i]/active->q_tot_cnt[i]),
-                (active->q_tot_cnt[i] == 0) ? 0 :
-                ASC_TENTHS(active->q_tot_tim[i], active->q_tot_cnt[i]));
-            ASC_PRT_NEXT();
+                active->q_cur_cnt[tgt_id], active->q_max_cnt[tgt_id],
+                active->q_tot_cnt[tgt_id],
+                active->q_min_tim[tgt_id], active->q_max_tim[tgt_id],
+                (active->q_tot_cnt[tgt_id] == 0) ? 0 :
+                (active->q_tot_tim[tgt_id]/active->q_tot_cnt[tgt_id]),
+                (active->q_tot_cnt[tgt_id] == 0) ? 0 :
+                ASC_TENTHS(active->q_tot_tim[tgt_id],
+                active->q_tot_cnt[tgt_id]));
+             ASC_PRT_NEXT();
 
-            len = asc_prt_line(cp, leftlen,
+             len = asc_prt_line(cp, leftlen,
 "   waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
-                waiting->q_cur_cnt[i], waiting->q_max_cnt[i],
-                waiting->q_tot_cnt[i],
-                waiting->q_min_tim[i], waiting->q_max_tim[i],
-                (waiting->q_tot_cnt[i] == 0) ? 0 :
-                (waiting->q_tot_tim[i]/waiting->q_tot_cnt[i]),
-                (waiting->q_tot_cnt[i] == 0) ? 0 :
-                ASC_TENTHS(waiting->q_tot_tim[i], waiting->q_tot_cnt[i]));
-            ASC_PRT_NEXT();
+                waiting->q_cur_cnt[tgt_id], waiting->q_max_cnt[tgt_id],
+                waiting->q_tot_cnt[tgt_id],
+                waiting->q_min_tim[tgt_id], waiting->q_max_tim[tgt_id],
+                (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
+                (waiting->q_tot_tim[tgt_id]/waiting->q_tot_cnt[tgt_id]),
+                (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
+                ASC_TENTHS(waiting->q_tot_tim[tgt_id],
+                waiting->q_tot_cnt[tgt_id]));
+             ASC_PRT_NEXT();
         }
-    }
+    } while (0);
 
      return totlen;
 }
+#endif /* CONFIG_PROC_FS */
 #endif /* ADVANSYS_STATS */
 
 #ifdef ADVANSYS_DEBUG
 /*
  * asc_prt_scsi_host()
  */
-STATIC void 
+STATIC void
 asc_prt_scsi_host(struct Scsi_Host *s)
 {
     asc_board_t         *boardp;
 
     boardp = ASC_BOARDP(s);
 
-    printk("Scsi_Host at addr %lx\n", (ulong) s);
+    printk("Scsi_Host at addr 0x%lx\n", (ulong) s);
     printk(
-" next %lx, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
+" next 0x%lx, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
         (ulong) s->next, s->extra_bytes, s->host_busy, s->host_no,
         (unsigned) s->last_reset);
 
+#if ASC_LINUX_KERNEL24
+    printk(
+" host_queue 0x%lx, hostt 0x%lx\n",
+        (ulong) s->host_queue, (ulong) s->hostt);
+#elif ASC_LINUX_KERNEL22
     printk(
-" host_queue %lx, hostt %lx, block %lx,\n",
+" host_queue 0x%lx, hostt 0x%lx, block 0x%lx,\n",
         (ulong) s->host_queue, (ulong) s->hostt, (ulong) s->block);
+#endif
 
     printk(
-" base %lu, io_port %lu, n_io_port %u, irq %d,\n",
-	(ulong) s->base, (ulong) s->io_port, s->n_io_port,
-        s->irq);
+" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
+        (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq);
 
     printk(
 " dma_channel %d, this_id %d, can_queue %d,\n",
@@ -10532,49 +9504,49 @@
 /*
  * asc_prt_scsi_cmnd()
  */
-STATIC void 
+STATIC void
 asc_prt_scsi_cmnd(Scsi_Cmnd *s)
 {
-    printk("Scsi_Cmnd at addr %lx\n", (ulong) s);
+    printk("Scsi_Cmnd at addr 0x%lx\n", (ulong) s);
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
     printk(
-" host %x, device %x, target %u, lun %u\n",
-        (unsigned) s->host, (unsigned) s->device, s->target, s->lun);
-#else /* version >= v1.3.0 */
-    printk(
-" host %lx, device %lx, target %u, lun %u, channel %u,\n",
+" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
         (ulong) s->host, (ulong) s->device, s->target, s->lun,
         s->channel);
-#endif /* version >= v1.3.0 */
 
     asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
 
+#if ASC_LINUX_KERNEL24
+    printk (
+"sc_data_direction %u, resid %d\n",
+        s->sc_data_direction, s->resid);
+#endif
+
     printk(
-" use_sg %u, sglist_len %u, abort_reason %x\n",
+" use_sg %u, sglist_len %u, abort_reason 0x%x\n",
         s->use_sg, s->sglist_len, s->abort_reason);
 
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
-    printk(
-" retries %d, allowed %d\n",
-         s->retries, s->allowed);
-#else /* version >= v1.3.89 */
     printk(
-" serial_number %x, serial_number_at_timeout %x, retries %d, allowed %d\n",
+" serial_number 0x%x, serial_number_at_timeout 0x%x, retries %d, allowed %d\n",
         (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout,
          s->retries, s->allowed);
-#endif /* version >= v1.3.89 */
 
     printk(
 " timeout_per_command %d, timeout_total %d, timeout %d\n",
         s->timeout_per_command, s->timeout_total, s->timeout);
 
+#if ASC_LINUX_KERNEL24
+    printk(
+" internal_timeout %u, flags %u\n",
+        s->internal_timeout, s->flags);
+#elif ASC_LINUX_KERNEL22
     printk(
 " internal_timeout %u, flags %u, this_count %d\n",
-        s->internal_timeout, s->flags, s->this_count);
+        s->internal_timeout, s->flags,s->this_count);
+#endif
 
     printk(
-" scsi_done %lx, done %lx, host_scribble %lx, result %x\n",
+" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
         (ulong) s->scsi_done, (ulong) s->done,
         (ulong) s->host_scribble, s->result);
 
@@ -10586,57 +9558,59 @@
 /*
  * asc_prt_asc_dvc_var()
  */
-STATIC void 
+STATIC void
 asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
 {
-    printk("ASC_DVC_VAR at addr %lx\n", (ulong) h);
+    printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong) h);
 
     printk(
-" iop_base %x, err_code %x, dvc_cntl %x, bug_fix_cntl %d,\n",
+" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
         h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
 
     printk(
-" bus_type %d, isr_callback %lx, exe_callback %lx, init_sdtr %x,\n",
+" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
         h->bus_type, (ulong) h->isr_callback, (ulong) h->exe_callback,
         (unsigned) h->init_sdtr);
 
     printk(
-" sdtr_done %x, use_tagged_qng %x, unit_not_ready %x, chip_no %x,\n",
+" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
         (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
         (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
-        
+
     printk(
-" queue_full_or_busy %x, start_motor %x, scsi_reset_wait %x, irq_no %x,\n",
+" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
         (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
-        (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
+        (unsigned) h->scsi_reset_wait);
 
     printk(
-" is_in_int %x, max_total_qng %x, cur_total_qng %x, in_critical_cnt %x,\n",
+" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
         (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
         (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
 
     printk(
-" last_q_shortage %x, init_state %x, no_scam %x, pci_fix_asyn_xfer %x,\n",
+" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
         (unsigned) h->last_q_shortage, (unsigned) h->init_state,
         (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
 
     printk(
-" cfg %lx\n",
-        (ulong) h->cfg);
+" cfg 0x%lx, irq_no 0x%x\n",
+        (ulong) h->cfg, (unsigned) h->irq_no);
 }
 
 /*
  * asc_prt_asc_dvc_cfg()
  */
-STATIC void 
+STATIC void
 asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
 {
-    printk("ASC_DVC_CFG at addr %lx\n", (ulong) h);
+    printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong) h);
 
     printk(
-" can_tagged_qng %x, cmd_qng_enabled %x, disc_enable %x, sdtr_enable %x,\n",
-            h->can_tagged_qng, h->cmd_qng_enabled, h->disc_enable,
-            h->sdtr_enable);
+" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
+            h->can_tagged_qng, h->cmd_qng_enabled);
+    printk(
+" disc_enable 0x%x, sdtr_enable 0x%x,\n",
+            h->disc_enable, h->sdtr_enable);
 
     printk(
 " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
@@ -10644,48 +9618,49 @@
              h->chip_version);
 
     printk(
-" pci_device_id %d, lib_serial_no %x, lib_version %x, mcode_date %x,\n",
+" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
           h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
 
     printk(
-" mcode_version %d, overrun_buf %lx\n",
+" mcode_version %d, overrun_buf 0x%lx\n",
             h->mcode_version, (ulong) h->overrun_buf);
 }
 
 /*
  * asc_prt_asc_scsi_q()
  */
-STATIC void 
+STATIC void
 asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
 {
     ASC_SG_HEAD    *sgp;
     int i;
 
-    printk("ASC_SCSI_Q at addr %lx\n", (ulong) q);
+    printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong) q);
 
     printk(
-" target_ix %u, target_lun %u, srb_ptr %x, tag_code %u,\n",
+" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
             q->q2.target_ix, q->q1.target_lun,
-            (unsigned) q->q2.srb_ptr, q->q2.tag_code);
+            (ulong) q->q2.srb_ptr, q->q2.tag_code);
 
     printk(
-" data_addr %lx, data_cnt %lu, sense_addr %lx, sense_len %u,\n",
-            (ulong) q->q1.data_addr, (ulong) q->q1.data_cnt,
-            (ulong) q->q1.sense_addr, q->q1.sense_len);
+" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
+            (ulong) le32_to_cpu(q->q1.data_addr),
+            (ulong) le32_to_cpu(q->q1.data_cnt),
+            (ulong) le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
 
     printk(
-" cdbptr %lx, cdb_len %u, sg_head %lx, sg_queue_cnt %u\n",
+" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
             (ulong) q->cdbptr, q->q2.cdb_len,
             (ulong) q->sg_head, q->q1.sg_queue_cnt);
 
     if (q->sg_head) {
         sgp = q->sg_head;
-        printk("ASC_SG_HEAD at addr %lx\n", (ulong) sgp);
+        printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong) sgp);
         printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
         for (i = 0; i < sgp->entry_cnt; i++) {
-            printk(" [%u]: addr %lx, bytes %lu\n",
-                i, (ulong) sgp->sg_list[i].addr,
-                (ulong) sgp->sg_list[i].bytes);
+            printk(" [%u]: addr 0x%lx, bytes %lu\n",
+                i, (ulong) le32_to_cpu(sgp->sg_list[i].addr),
+                (ulong) le32_to_cpu(sgp->sg_list[i].bytes));
         }
 
     }
@@ -10694,17 +9669,17 @@
 /*
  * asc_prt_asc_qdone_info()
  */
-STATIC void 
+STATIC void
 asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
 {
-    printk("ASC_QDONE_INFO at addr %lx\n", (ulong) q);
+    printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong) q);
     printk(
-" srb_ptr %x, target_ix %u, cdb_len %u, tag_code %u, done_stat %x\n",
-            (unsigned) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
-            q->d2.tag_code, q->d3.done_stat);
+" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
+            (ulong) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
+            q->d2.tag_code);
     printk(
-" host_stat %x, scsi_stat %x, scsi_msg %x\n",
-            q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
+" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
+            q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
 }
 
 /*
@@ -10712,7 +9687,7 @@
  *
  * Display an ADV_DVC_VAR structure.
  */
-STATIC void 
+STATIC void
 asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
 {
     printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
@@ -10723,8 +9698,8 @@
 
     printk(
 "  isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
-        (ulong) h->isr_callback, (unsigned) h->wdtr_able,
-        (unsigned) h->sdtr_able);
+        (ulong) h->isr_callback, (unsigned) h->sdtr_able,
+        (unsigned) h->wdtr_able);
 
     printk(
 "  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
@@ -10732,12 +9707,12 @@
         (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
 
     printk(
-"  max_host_qng %x, max_dvc_qng %x, carr_freelist %lxn\n",
+"  max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
         (unsigned) h->max_host_qng, (unsigned) h->max_dvc_qng,
         (ulong) h->carr_freelist);
 
     printk(
-"  icq_sp %lx, irq_sp %lx\n",
+"  icq_sp 0x%lx, irq_sp 0x%lx\n",
         (ulong) h->icq_sp, (ulong) h->irq_sp);
 
     printk(
@@ -10745,7 +9720,7 @@
         (unsigned) h->no_scam, (unsigned) h->tagqng_able);
 
     printk(
-"  chip_scsi_id 0x%x, cfg %lx\n",
+"  chip_scsi_id 0x%x, cfg 0x%lx\n",
         (unsigned) h->chip_scsi_id, (ulong) h->cfg);
 }
 
@@ -10754,7 +9729,7 @@
  *
  * Display an ADV_DVC_CFG structure.
  */
-STATIC void 
+STATIC void
 asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
 {
     printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
@@ -10768,7 +9743,7 @@
         h->chip_version, h->mcode_date);
 
     printk(
-"  mcode_version 0x%x, pci_device_id 0x%x, lib_version 0x%x\n",
+"  mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
        h->mcode_version, h->pci_device_id, h->lib_version);
 
     printk(
@@ -10781,37 +9756,38 @@
  *
  * Display an ADV_SCSI_REQ_Q structure.
  */
-STATIC void 
+STATIC void
 asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
 {
     int                 sg_blk_cnt;
     struct asc_sg_block *sg_ptr;
 
-    printk("ADV_SCSI_REQ_Q at addr %lx\n", (ulong) q);
+    printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong) q);
 
     printk(
 "  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
             q->target_id, q->target_lun, (ulong) q->srb_ptr, q->a_flag);
 
     printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
-            q->cntl, (ulong) q->data_addr, (ulong) q->vdata_addr);
+            q->cntl, (ulong) le32_to_cpu(q->data_addr), (ulong) q->vdata_addr);
 
     printk(
 "  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
-            (ulong) q->data_cnt, (ulong) q->sense_addr, q->sense_len);
+            (ulong) le32_to_cpu(q->data_cnt),
+            (ulong) le32_to_cpu(q->sense_addr), q->sense_len);
 
     printk(
 "  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
             q->cdb_len, q->done_status, q->host_status, q->scsi_status);
 
     printk(
-"  sg_working_ix %x, sg_working_data_cnt %lx, target_cmd %u\n",
-            q->sg_working_ix, (ulong) q->sg_working_data_cnt, q->target_cmd);
+"  sg_working_ix 0x%x, target_cmd %u\n",
+            q->sg_working_ix, q->target_cmd);
 
     printk(
-"  scsiq_rptr %lx, sg_real_addr %lx, sg_list_ptr %lx\n",
-            (ulong) q->scsiq_rptr, (ulong) q->sg_real_addr,
-            (ulong) q->sg_list_ptr);
+"  scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
+            (ulong) le32_to_cpu(q->scsiq_rptr),
+            (ulong) le32_to_cpu(q->sg_real_addr), (ulong) q->sg_list_ptr);
 
     /* Display the request's ADV_SG_BLOCK structures. */
     if (q->sg_list_ptr != NULL)
@@ -10846,17 +9822,17 @@
 {
     int i;
 
-    printk(" ASC_SG_BLOCK at addr %lx (sgblockno %d)\n",
+    printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
         (ulong) b, sgblockno);
-    printk("  sg_cnt %u, sg_ptr %lx\n",
-        b->sg_cnt, (ulong) b->sg_ptr);
+    printk("  sg_cnt %u, sg_ptr 0x%lx\n",
+        b->sg_cnt, (ulong) le32_to_cpu(b->sg_ptr));
     ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
     if (b->sg_ptr != 0)
     {
         ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
     }
     for (i = 0; i < b->sg_cnt; i++) {
-        printk("  [%u]: sg_addr %lx, sg_count %lx\n",
+        printk("  [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
             i, (ulong) b->sg_list[i].sg_addr, (ulong) b->sg_list[i].sg_count);
     }
 }
@@ -10864,10 +9840,10 @@
 /*
  * asc_prt_hex()
  *
- * Print hexadecimal output in 4 byte groupings 32 bytes 
+ * Print hexadecimal output in 4 byte groupings 32 bytes
  * or 8 double-words per line.
  */
-STATIC void 
+STATIC void
 asc_prt_hex(char *f, uchar *s, int l)
 {
     int            i;
@@ -10878,7 +9854,7 @@
     printk("%s: (%d bytes)\n", f, l);
 
     for (i = 0; i < l; i += 32) {
-        
+
         /* Display a maximum of 8 double-words per line. */
         if ((k = (l - i) / 4) >= 8) {
             k = 8;
@@ -10919,27 +9895,6 @@
 }
 #endif /* ADVANSYS_DEBUG */
 
-#ifdef ADVANSYS_ASSERT
-/*
- * advansys_interrupts_enabled()
- *
- * Return 1 if interrupts are enabled, otherwise return 0.
- */
-STATIC int
-advansys_interrupts_enabled(void)
-{
-    int flags;
-
-    save_flags(flags);
-    if (flags & 0x0200) {
-        return ASC_TRUE;
-    } else {
-        return ASC_FALSE;
-    }
-}
-#endif /* ADVANSYS_ASSERT */
-
-
 /*
  * --- Asc Library Functions
  */
@@ -11047,42 +10002,47 @@
     return (0);
 }
 
-ASC_INITFUNC(
-STATIC ASC_DCNT,
+STATIC ASC_DCNT
 AscLoadMicroCode(
                     PortAddr iop_base,
                     ushort s_addr,
-                    ushort *mcode_buf,
+                    uchar *mcode_buf,
                     ushort mcode_size
 )
-)
 {
     ASC_DCNT            chksum;
     ushort              mcode_word_size;
     ushort              mcode_chksum;
 
+    /* Write the microcode buffer starting at LRAM address 0. */
     mcode_word_size = (ushort) (mcode_size >> 1);
     AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
-    AscMemWordCopyToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
+    AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
+
     chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
+    ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong) chksum);
     mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
-                                              (ushort) ASC_CODE_SEC_BEG,
+          (ushort) ASC_CODE_SEC_BEG,
           (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
+    ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
+        (ulong) mcode_chksum);
     AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
     AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
     return (chksum);
 }
 
-ASC_INITFUNC(
-STATIC int,
+STATIC int
 AscFindSignature(
                     PortAddr iop_base
 )
-)
 {
     ushort              sig_word;
 
+    ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
+        iop_base, AscGetChipSignatureByte(iop_base));
     if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
+        ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
+            iop_base, AscGetChipSignatureWord(iop_base));
         sig_word = AscGetChipSignatureWord(iop_base);
         if ((sig_word == (ushort) ASC_1000_ID0W) ||
             (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
@@ -11092,13 +10052,15 @@
     return (0);
 }
 
-STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
 STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
 {
     0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
     ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
 };
 
+#ifdef CONFIG_ISA
+STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
+
 ASC_INITFUNC(
 STATIC PortAddr,
 AscSearchIOPortAddr(
@@ -11155,11 +10117,11 @@
         iop_base = _asc_def_iop_base[i];
         if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
             ASC_DBG1(1,
-               "AscSearchIOPortAddr11: check_region() failed I/O port %x\n",
+               "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
                      iop_base);
             continue;
         }
-        ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port %x\n", iop_base);
+        ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base);
         if (AscFindSignature(iop_base)) {
             return (iop_base);
         }
@@ -11169,24 +10131,25 @@
 
 ASC_INITFUNC(
 STATIC void,
-AscToggleIRQAct(
-                   PortAddr iop_base
-)
+AscSetISAPNPWaitForKey(
+    void)
 )
 {
-    AscSetChipStatus(iop_base, CIW_IRQ_ACT);
-    AscSetChipStatus(iop_base, 0);
+    outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
+    outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
     return;
 }
+#endif /* CONFIG_ISA */
 
 ASC_INITFUNC(
 STATIC void,
-AscSetISAPNPWaitForKey(
-    void)
+AscToggleIRQAct(
+                   PortAddr iop_base
+)
 )
 {
-    outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
-    outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
+    AscSetChipStatus(iop_base, CIW_IRQ_ACT);
+    AscSetChipStatus(iop_base, 0);
     return;
 }
 
@@ -11267,6 +10230,7 @@
     return (0);
 }
 
+#ifdef CONFIG_ISA
 ASC_INITFUNC(
 STATIC void,
 AscEnableIsaDma(
@@ -11283,8 +10247,9 @@
     }
     return;
 }
+#endif /* CONFIG_ISA */
 
-STATIC int 
+STATIC int
 AscIsrChipHalted(
                     ASC_DVC_VAR *asc_dvc
 )
@@ -11343,10 +10308,10 @@
         return (0);
     } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
 
-        AscMemWordCopyFromLram(iop_base,
+        AscMemWordCopyPtrFromLram(iop_base,
                                ASCV_MSGIN_BEG,
-                               (ushort *) & ext_msg,
-                               (ushort) (sizeof (EXT_MSG) >> 1));
+                               (uchar *) &ext_msg,
+                               sizeof(EXT_MSG) >> 1);
 
         if (ext_msg.msg_type == MS_EXTEND &&
             ext_msg.msg_req == MS_SDTR_CODE &&
@@ -11420,10 +10385,10 @@
                    ext_msg.msg_len == MS_WDTR_LEN) {
 
             ext_msg.wdtr_width = 0;
-            AscMemWordCopyToLram(iop_base,
+            AscMemWordCopyPtrToLram(iop_base,
                                  ASCV_MSGOUT_BEG,
-                                 (ushort *) & ext_msg,
-                                 (ushort) (sizeof (EXT_MSG) >> 1));
+                                 (uchar *) &ext_msg,
+                                 sizeof(EXT_MSG) >> 1);
             q_cntl |= QC_MSG_OUT;
             AscWriteLramByte(iop_base,
                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
@@ -11433,10 +10398,10 @@
         } else {
 
             ext_msg.msg_type = M1_MSG_REJECT;
-            AscMemWordCopyToLram(iop_base,
+            AscMemWordCopyPtrToLram(iop_base,
                                  ASCV_MSGOUT_BEG,
-                                 (ushort *) & ext_msg,
-                                 (ushort) (sizeof (EXT_MSG) >> 1));
+                                 (uchar *) &ext_msg,
+                                 sizeof(EXT_MSG) >> 1);
             q_cntl |= QC_MSG_OUT;
             AscWriteLramByte(iop_base,
                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
@@ -11496,10 +10461,10 @@
         return (0);
     } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
 
-        AscMemWordCopyFromLram(iop_base,
+        AscMemWordCopyPtrFromLram(iop_base,
                                ASCV_MSGOUT_BEG,
-                               (ushort *) & out_msg,
-                               (ushort) (sizeof (EXT_MSG) >> 1));
+                               (uchar *) &out_msg,
+                               sizeof(EXT_MSG) >> 1);
 
         if ((out_msg.msg_type == MS_EXTEND) &&
             (out_msg.msg_len == MS_SDTR_LEN) &&
@@ -11554,7 +10519,9 @@
         }
         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
         return (0);
-    } else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC)
+    }
+#if CC_VERY_LONG_SG_LIST
+    else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC)
     {
         uchar              q_no;
         ushort             q_addr;
@@ -11678,16 +10645,15 @@
              }
 
              scsi_sg_q.q_no = next_qp;
-             AscMemWordCopyToLram(iop_base,
-                          (ushort) (q_addr+ASC_SCSIQ_SGHD_CPY_BEG),
-                          (ushort *) &scsi_sg_q,
-                          (ushort) (sizeof(ASC_SG_LIST_Q) >> 1));
-
-             AscMemDWordCopyToLram( iop_base,
-                          (ushort) (q_addr+ASC_SGQ_LIST_BEG ),
-                          (ADV_PADDR *)
-                               &sg_head->sg_list[scsiq->next_sg_index],
-                          (ushort) sg_list_dwords);
+             AscMemWordCopyPtrToLram(iop_base,
+                          q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
+                          (uchar *) &scsi_sg_q,
+                          sizeof(ASC_SG_LIST_Q) >> 1);
+
+             AscMemDWordCopyPtrToLram(iop_base,
+                          q_addr + ASC_SGQ_LIST_BEG,
+                          (uchar *) &sg_head->sg_list[scsiq->next_sg_index],
+                          sg_list_dwords);
 
              scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
 
@@ -11713,6 +10679,7 @@
         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
         return(0);
     }
+#endif /* CC_VERY_LONG_SG_LIST */
     return (0);
 }
 
@@ -11728,9 +10695,10 @@
     uchar               sg_queue_cnt;
 
     DvcGetQinfo(iop_base,
-                (ushort) (q_addr + (ushort) ASC_SCSIQ_DONE_INFO_BEG),
-                (ushort *) scsiq,
-              (ushort) ((sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2));
+                q_addr + ASC_SCSIQ_DONE_INFO_BEG,
+                (uchar *) scsiq,
+                (sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2);
+
     _val = AscReadLramWord(iop_base,
                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
     scsiq->q_status = (uchar) _val;
@@ -11994,7 +10962,8 @@
     return (int_pending);
 }
 
-STATIC uchar _asc_mcode_buf[] ASC_INITDATA =
+/* Microcode buffer is kept after initialization for error recovery. */
+STATIC uchar _asc_mcode_buf[] =
 {
   0x01,  0x03,  0x01,  0x19,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
   0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
@@ -12142,8 +11111,8 @@
   0xF1,  0xC7,  0x41,  0x23,  0xF8,  0x88,  0x11,  0x23,  0xA1,  0x01,  0x04,  0x23,  0xA0,  0x01,  0xE6,  0x84,
 };
 
-STATIC ushort _asc_mcode_size ASC_INITDATA = sizeof(_asc_mcode_buf);
-STATIC ADV_DCNT _asc_mcode_chksum ASC_INITDATA = 0x012C453FUL;
+STATIC ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
+STATIC ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
 
 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
 STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
@@ -12173,7 +11142,7 @@
 )
 {
     PortAddr            iop_base;
-    int                 last_int_level;
+    ulong               last_int_level;
     int                 sta;
     int                 n_q_required;
     int                 disable_syn_offset_one_fix;
@@ -12235,6 +11204,8 @@
 #if !CC_VERY_LONG_SG_LIST
         if (sg_entry_cnt > ASC_MAX_SG_LIST)
         {
+            asc_dvc->in_critical_cnt--;
+            DvcLeaveCritical(last_int_level);
             return(ERR);
         }
 #endif /* !CC_VERY_LONG_SG_LIST */
@@ -12252,10 +11223,10 @@
         if (scsiq->q1.cntl & QC_SG_HEAD) {
             data_cnt = 0;
             for (i = 0; i < sg_entry_cnt; i++) {
-                data_cnt += (ADV_DCNT) sg_head->sg_list[i].bytes;
+                data_cnt += (ADV_DCNT) le32_to_cpu(sg_head->sg_list[i].bytes);
             }
         } else {
-            data_cnt = scsiq->q1.data_cnt;
+            data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
         }
         if (data_cnt != 0UL) {
             if (data_cnt < 512UL) {
@@ -12279,7 +11250,7 @@
         scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
                                ASC_TAG_FLAG_DISABLE_DISCONNECT);
     } else {
-        scsiq->q2.tag_code &= 0x23;
+        scsiq->q2.tag_code &= 0x27;
     }
     if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
         if (asc_dvc->bug_fix_cntl) {
@@ -12287,23 +11258,27 @@
                 if ((scsi_cmd == SCSICMD_Read6) ||
                     (scsi_cmd == SCSICMD_Read10)) {
                     addr =
-                        (ADV_PADDR)
-                            sg_head->sg_list[sg_entry_cnt_minus_one].addr +
-                        (ADV_DCNT)
-                            sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
+                        (ADV_PADDR) le32_to_cpu(
+                            sg_head->sg_list[sg_entry_cnt_minus_one].addr) +
+                        (ADV_DCNT) le32_to_cpu(
+                            sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
                     if ((extra_bytes != 0) &&
                         ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
                          == 0)) {
                         scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
                         scsiq->q1.extra_bytes = extra_bytes;
-                        sg_head->sg_list[sg_entry_cnt_minus_one].bytes -=
-                            (ASC_DCNT) extra_bytes;
+                        data_cnt = le32_to_cpu(
+                            sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
+                        data_cnt -= (ASC_DCNT) extra_bytes;
+                        sg_head->sg_list[sg_entry_cnt_minus_one].bytes =
+                            cpu_to_le32(data_cnt);
                     }
                 }
             }
         }
         sg_head->entry_to_copy = sg_head->entry_cnt;
+#if CC_VERY_LONG_SG_LIST
         /*
          * Set the sg_entry_cnt to the maximum possible. The rest of
          * the SG elements will be copied when the RISC completes the
@@ -12313,6 +11288,7 @@
         {
              sg_entry_cnt = ASC_MAX_SG_LIST;
         }
+#endif /* CC_VERY_LONG_SG_LIST */
         n_q_required = AscSgListToQueue(sg_entry_cnt);
         if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
             (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
@@ -12331,14 +11307,17 @@
             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
                 if ((scsi_cmd == SCSICMD_Read6) ||
                     (scsi_cmd == SCSICMD_Read10)) {
-                    addr = scsiq->q1.data_addr + scsiq->q1.data_cnt;
+                    addr = le32_to_cpu(scsiq->q1.data_addr) +
+                        le32_to_cpu(scsiq->q1.data_cnt);
                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
                     if ((extra_bytes != 0) &&
                         ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
                           == 0)) {
-                        if (((ushort) scsiq->q1.data_cnt & 0x01FF) == 0) {
+                        data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
+                        if (((ushort) data_cnt & 0x01FF) == 0) {
                             scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
-                            scsiq->q1.data_cnt -= (ASC_DCNT) extra_bytes;
+                            data_cnt -= (ASC_DCNT) extra_bytes;
+                            scsiq->q1.data_cnt = cpu_to_le32(data_cnt);
                             scsiq->q1.extra_bytes = extra_bytes;
                         }
                     }
@@ -12501,14 +11480,15 @@
         scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
     }
     scsiq->q1.status = QS_FREE;
-    AscMemWordCopyToLram(iop_base,
-                         (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
-                         (ushort *) scsiq->cdbptr,
-                         (ushort) ((ushort) scsiq->q2.cdb_len >> 1));
+    AscMemWordCopyPtrToLram(iop_base,
+                         q_addr + ASC_SCSIQ_CDB_BEG,
+                         (uchar *) scsiq->cdbptr,
+                         scsiq->q2.cdb_len >> 1);
+
     DvcPutScsiQ(iop_base,
-                (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
-                (ushort *) & scsiq->q1.cntl,
-      (ushort) ((((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1)));
+                q_addr + ASC_SCSIQ_CPY_BEG,
+                (uchar *) &scsiq->q1.cntl,
+                ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
     AscWriteLramWord(iop_base,
                      (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
              (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
@@ -12541,6 +11521,7 @@
     saved_data_cnt = scsiq->q1.data_cnt;
     scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
     scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
+#if CC_VERY_LONG_SG_LIST
     /*
      * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
      * then not all SG elements will fit in the allocated queues.
@@ -12551,10 +11532,10 @@
     {
          /*
           * Set sg_entry_cnt to be the number of SG elements that
-          * will fit in the allocated SG queues. It is minus 1 because
-          * first SG element handled above. ASC_MAX_SG_LIST is already
-          * inflated by 1 to account for this. For example it may
-          * be 50 which is 1 + 7 queues * 7 SG elements.
+          * will fit in the allocated SG queues. It is minus 1, because
+          * the first SG element is handled above. ASC_MAX_SG_LIST is
+          * already inflated by 1 to account for this. For example it
+          * may be 50 which is 1 + 7 queues * 7 SG elements.
           */
          sg_entry_cnt = ASC_MAX_SG_LIST - 1;
 
@@ -12565,13 +11546,16 @@
          scsiq->remain_sg_entry_cnt = sg_head->entry_cnt - ASC_MAX_SG_LIST;
     } else
     {
+#endif /* CC_VERY_LONG_SG_LIST */
          /*
           * Set sg_entry_cnt to be the number of SG elements that
-          * will fit in the allocated SG queues. Refer to comment
-          * above regarding why it is - 1.
+          * will fit in the allocated SG queues. It is minus 1, because
+          * the first SG element is handled above.
           */
          sg_entry_cnt = sg_head->entry_cnt - 1;
+#if CC_VERY_LONG_SG_LIST
     }
+#endif /* CC_VERY_LONG_SG_LIST */
     if (sg_entry_cnt != 0) {
         scsiq->q1.cntl |= QC_SG_HEAD;
         q_addr = ASC_QNO_TO_QADDR(q_no);
@@ -12592,6 +11576,7 @@
                     scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
                 }
             } else {
+#if CC_VERY_LONG_SG_LIST
                 /*
                  * This is the last SG queue in the list of
                  * allocated SG queues. If there are more
@@ -12603,8 +11588,11 @@
                     scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
                 } else
                 {
+#endif /* CC_VERY_LONG_SG_LIST */
                     scsi_sg_q.cntl |= QCSG_SG_XFER_END;
+#if CC_VERY_LONG_SG_LIST
                 }
+#endif /* CC_VERY_LONG_SG_LIST */
                 sg_list_dwords = sg_entry_cnt << 1;
                 if (i == 0) {
                     scsi_sg_q.sg_list_cnt = sg_entry_cnt;
@@ -12619,14 +11607,14 @@
                                       (ushort) (q_addr + ASC_SCSIQ_B_FWD));
             scsi_sg_q.q_no = next_qp;
             q_addr = ASC_QNO_TO_QADDR(next_qp);
-            AscMemWordCopyToLram(iop_base,
-                                 (ushort) (q_addr + ASC_SCSIQ_SGHD_CPY_BEG),
-                                 (ushort *) & scsi_sg_q,
-                                 (ushort) (sizeof (ASC_SG_LIST_Q) >> 1));
-            AscMemDWordCopyToLram(iop_base,
-                                  (ushort) (q_addr + ASC_SGQ_LIST_BEG),
-                                  (ADV_PADDR *) &sg_head->sg_list[sg_index],
-                                  (ushort) sg_list_dwords);
+            AscMemWordCopyPtrToLram(iop_base,
+                                q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
+                                (uchar *) &scsi_sg_q,
+                                sizeof(ASC_SG_LIST_Q) >> 1);
+            AscMemDWordCopyPtrToLram(iop_base,
+                                q_addr + ASC_SGQ_LIST_BEG,
+                                (uchar *) &sg_head->sg_list[sg_index],
+                                sg_list_dwords);
             sg_index += ASC_SG_LIST_PER_Q;
             scsiq->next_sg_index = sg_index;
         }
@@ -12640,173 +11628,32 @@
 }
 
 STATIC int
-AscAbortSRB(
-               ASC_DVC_VAR *asc_dvc,
-               ADV_VADDR srb_ptr
+AscSetRunChipSynRegAtID(
+                           PortAddr iop_base,
+                           uchar tid_no,
+                           uchar sdtr_data
 )
 {
-    int                 sta;
-    ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
-    PortAddr            iop_base;
+    int                 sta = FALSE;
 
-    iop_base = asc_dvc->iop_base;
-    sta = ERR;
-    saved_unit_not_ready = asc_dvc->unit_not_ready;
-    asc_dvc->unit_not_ready = 0xFF;
-    AscWaitISRDone(asc_dvc);
-    if (AscStopQueueExe(iop_base) == 1) {
-        if (AscRiscHaltedAbortSRB(asc_dvc, srb_ptr) == 1) {
-            sta = 1;
-            AscCleanUpBusyQueue(iop_base);
-            AscStartQueueExe(iop_base);
-        } else {
-            sta = 0;
-            AscStartQueueExe(iop_base);
-        }
+    if (AscHostReqRiscHalt(iop_base)) {
+        sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
+        AscStartChip(iop_base);
+        return (sta);
     }
-    asc_dvc->unit_not_ready = saved_unit_not_ready;
     return (sta);
 }
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
 STATIC int
-AscResetDevice(
-                  ASC_DVC_VAR *asc_dvc,
-                  uchar target_ix
+AscSetChipSynRegAtID(
+                        PortAddr iop_base,
+                        uchar id,
+                        uchar sdtr_data
 )
 {
-    PortAddr            iop_base;
-    int                 sta;
-    uchar               tid_no;
-
-    ASC_SCSI_BIT_ID_TYPE target_id;
+    ASC_SCSI_BIT_ID_TYPE org_id;
     int                 i;
-    ASC_SCSI_REQ_Q      scsiq_buf;
-    ASC_SCSI_REQ_Q *scsiq;
-    uchar       *buf;
-    ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
-    iop_base = asc_dvc->iop_base;
-    tid_no = ASC_TIX_TO_TID(target_ix);
-    target_id = ASC_TID_TO_TARGET_ID(tid_no);
-    saved_unit_not_ready = asc_dvc->unit_not_ready;
-    asc_dvc->unit_not_ready = target_id;
-    sta = ERR;
-    AscWaitTixISRDone(asc_dvc, target_ix);
-    if (AscStopQueueExe(iop_base) == 1) {
-        if (AscRiscHaltedAbortTIX(asc_dvc, target_ix) == 1) {
-            AscCleanUpBusyQueue(iop_base);
-            AscStartQueueExe(iop_base);
-            AscWaitTixISRDone(asc_dvc, target_ix);
-            sta = TRUE;
-            scsiq = (ASC_SCSI_REQ_Q *) & scsiq_buf;
-            buf = (uchar *) & scsiq_buf;
-            for (i = 0; i < sizeof (ASC_SCSI_REQ_Q); i++) {
-                *buf++ = 0x00;
-            }
-            scsiq->r1.status = (uchar) QS_READY;
-            scsiq->r2.cdb_len = 6;
-            scsiq->r2.tag_code = M2_QTAG_MSG_SIMPLE;
-            scsiq->r1.target_id = target_id;
-            scsiq->r2.target_ix = ASC_TIDLUN_TO_IX(tid_no, 0);
-            scsiq->cdbptr = (uchar *) scsiq->cdb;
-            scsiq->r1.cntl = QC_NO_CALLBACK | QC_MSG_OUT | QC_URGENT;
-            AscWriteLramByte(asc_dvc->iop_base, ASCV_MSGOUT_BEG,
-                             M1_BUS_DVC_RESET);
-            asc_dvc->unit_not_ready &= ~target_id;
-            asc_dvc->sdtr_done |= target_id;
-            if (AscExeScsiQueue(asc_dvc, (ASC_SCSI_Q *) scsiq)
-                == 1) {
-                asc_dvc->unit_not_ready = target_id;
-                DvcSleepMilliSecond(1000);
-                _AscWaitQDone(iop_base, (ASC_SCSI_Q *) scsiq);
-                if (AscStopQueueExe(iop_base) == 1) {
-                    AscCleanUpDiscQueue(iop_base);
-                    AscStartQueueExe(iop_base);
-                    if (asc_dvc->pci_fix_asyn_xfer & target_id) {
-                        AscSetRunChipSynRegAtID(iop_base, tid_no,
-                                             ASYN_SDTR_DATA_FIX_PCI_REV_AB);
-                    }
-                    AscWaitTixISRDone(asc_dvc, target_ix);
-                }
-            } else {
-                sta = 0;
-            }
-            asc_dvc->sdtr_done &= ~target_id;
-        } else {
-            sta = ERR;
-            AscStartQueueExe(iop_base);
-        }
-    }
-    asc_dvc->unit_not_ready = saved_unit_not_ready;
-    return (sta);
-}
-#endif /* version >= v1.3.89 */
-
-STATIC int
-AscResetSB(
-              ASC_DVC_VAR *asc_dvc
-)
-{
-    int                 sta;
-    int                 i;
-    PortAddr            iop_base;
-
-    iop_base = asc_dvc->iop_base;
-    asc_dvc->unit_not_ready = 0xFF;
-    sta = TRUE;
-    AscWaitISRDone(asc_dvc);
-    AscStopQueueExe(iop_base);
-    asc_dvc->sdtr_done = 0;
-    AscResetChipAndScsiBus(asc_dvc);
-    DvcSleepMilliSecond((ASC_DCNT) ((ushort) asc_dvc->scsi_reset_wait * 1000));
-    AscReInitLram(asc_dvc);
-    for (i = 0; i <= ASC_MAX_TID; i++) {
-        asc_dvc->cur_dvc_qng[i] = 0;
-        if (asc_dvc->pci_fix_asyn_xfer & (ASC_SCSI_BIT_ID_TYPE) (0x01 << i)) {
-            AscSetChipSynRegAtID(iop_base, i, ASYN_SDTR_DATA_FIX_PCI_REV_AB);
-        }
-    }
-    asc_dvc->err_code = 0;
-    AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
-    if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
-        sta = ERR;
-    }
-    if (AscStartChip(iop_base) == 0) {
-        sta = ERR;
-    }
-    AscStartQueueExe(iop_base);
-    asc_dvc->unit_not_ready = 0;
-    asc_dvc->queue_full_or_busy = 0;
-    return (sta);
-}
-
-STATIC int
-AscSetRunChipSynRegAtID(
-                           PortAddr iop_base,
-                           uchar tid_no,
-                           uchar sdtr_data
-)
-{
-    int                 sta = FALSE;
-
-    if (AscHostReqRiscHalt(iop_base)) {
-        sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
-        AscStartChip(iop_base);
-        return (sta);
-    }
-    return (sta);
-}
-
-STATIC int
-AscSetChipSynRegAtID(
-                        PortAddr iop_base,
-                        uchar id,
-                        uchar sdtr_data
-)
-{
-    ASC_SCSI_BIT_ID_TYPE org_id;
-    int                 i;
-    int                 sta = TRUE;
+    int                 sta = TRUE;
 
     AscSetBank(iop_base, 1);
     org_id = AscReadChipDvcID(iop_base);
@@ -12831,16 +11678,6 @@
     return (sta);
 }
 
-STATIC int
-AscReInitLram(
-                 ASC_DVC_VAR *asc_dvc
-)
-{
-    AscInitLram(asc_dvc);
-    AscInitQLinkVar(asc_dvc);
-    return (0);
-}
-
 STATIC ushort
 AscInitLram(
                ASC_DVC_VAR *asc_dvc
@@ -12942,31 +11779,7 @@
 }
 
 
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-STATIC int
-_AscWaitQDone(
-                 PortAddr iop_base,
-                 ASC_SCSI_Q * scsiq
-)
-{
-    ushort              q_addr;
-    uchar               q_status;
-    int                 count = 0;
-
-    while (scsiq->q1.q_no == 0);
-    q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no);
-    do {
-        q_status = AscReadLramByte(iop_base, q_addr + ASC_SCSIQ_B_STATUS);
-        DvcSleepMilliSecond(100L);
-        if (count++ > 30) {
-            return (0);
-        }
-    } while ((q_status & QS_READY) != 0);
-    return (1);
-}
-#endif /* version >= v1.3.89 */
-
-STATIC uchar 
+STATIC uchar
 AscMsgOutSDTR(
                  ASC_DVC_VAR *asc_dvc,
                  uchar sdtr_period,
@@ -12987,18 +11800,18 @@
     if ((sdtr_period_index =
          AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
         asc_dvc->max_sdtr_index) {
-        AscMemWordCopyToLram(iop_base,
+        AscMemWordCopyPtrToLram(iop_base,
                              ASCV_MSGOUT_BEG,
-                             (ushort *) & sdtr_buf,
-                             (ushort) (sizeof (EXT_MSG) >> 1));
+                             (uchar *) &sdtr_buf,
+                             sizeof (EXT_MSG) >> 1);
         return ((sdtr_period_index << 4) | sdtr_offset);
     } else {
 
         sdtr_buf.req_ack_offset = 0;
-        AscMemWordCopyToLram(iop_base,
+        AscMemWordCopyPtrToLram(iop_base,
                              ASCV_MSGOUT_BEG,
-                             (ushort *) & sdtr_buf,
-                             (ushort) (sizeof (EXT_MSG) >> 1));
+                             (uchar *) &sdtr_buf,
+                             sizeof (EXT_MSG) >> 1);
         return (0);
     }
 }
@@ -13101,95 +11914,6 @@
 }
 
 STATIC int
-AscRiscHaltedAbortSRB(
-                         ASC_DVC_VAR *asc_dvc,
-                         ASC_VADDR srb_ptr
-)
-{
-    PortAddr            iop_base;
-    ushort              q_addr;
-    uchar               q_no;
-    ASC_QDONE_INFO      scsiq_buf;
-    ASC_QDONE_INFO *scsiq;
-    ASC_ISR_CALLBACK    asc_isr_callback;
-    int                 last_int_level;
-
-    iop_base = asc_dvc->iop_base;
-    asc_isr_callback = asc_dvc->isr_callback;
-    last_int_level = DvcEnterCritical();
-    scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
-    for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
-         q_no++) {
-        q_addr = ASC_QNO_TO_QADDR(q_no);
-        scsiq->d2.srb_ptr = AscReadLramDWord(iop_base,
-                           (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR));
-        if (scsiq->d2.srb_ptr == srb_ptr) {
-            _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
-            if (((scsiq->q_status & QS_READY) != 0)
-                 && ((scsiq->q_status & QS_ABORTED) == 0)
-                 && ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
-                scsiq->q_status |= QS_ABORTED;
-                scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
-                AscWriteLramDWord(iop_base,
-                            (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
-                                  0L);
-                AscWriteLramByte(iop_base,
-                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
-                                 scsiq->q_status);
-                (*asc_isr_callback) (asc_dvc, scsiq);
-                return (1);
-            }
-        }
-    }
-    DvcLeaveCritical(last_int_level);
-    return (0);
-}
-
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-STATIC int
-AscRiscHaltedAbortTIX(
-                         ASC_DVC_VAR *asc_dvc,
-                         uchar target_ix
-)
-{
-    PortAddr            iop_base;
-    ushort              q_addr;
-    uchar               q_no;
-    ASC_QDONE_INFO      scsiq_buf;
-    ASC_QDONE_INFO *scsiq;
-    ASC_ISR_CALLBACK    asc_isr_callback;
-    int                 last_int_level;
-
-    iop_base = asc_dvc->iop_base;
-    asc_isr_callback = asc_dvc->isr_callback;
-    last_int_level = DvcEnterCritical();
-    scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
-    for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
-         q_no++) {
-        q_addr = ASC_QNO_TO_QADDR(q_no);
-        _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
-        if (((scsiq->q_status & QS_READY) != 0) &&
-            ((scsiq->q_status & QS_ABORTED) == 0) &&
-            ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
-            if (scsiq->d2.target_ix == target_ix) {
-                scsiq->q_status |= QS_ABORTED;
-                scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
-                AscWriteLramDWord(iop_base,
-                            (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
-                                  0L);
-                AscWriteLramByte(iop_base,
-                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
-                                 scsiq->q_status);
-                (*asc_isr_callback) (asc_dvc, scsiq);
-            }
-        }
-    }
-    DvcLeaveCritical(last_int_level);
-    return (1);
-}
-#endif /* version >= v1.3.89 */
-
-STATIC int
 AscHostReqRiscHalt(
                       PortAddr iop_base
 )
@@ -13237,119 +11961,6 @@
     return (0);
 }
 
-STATIC int
-AscStartQueueExe(
-                    PortAddr iop_base
-)
-{
-    if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
-        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
-    }
-    return (1);
-}
-
-STATIC int
-AscCleanUpBusyQueue(
-                       PortAddr iop_base
-)
-{
-    int                 count;
-    uchar               stop_code;
-
-    count = 0;
-    if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
-        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
-                         ASC_STOP_CLEAN_UP_BUSY_Q);
-        do {
-            stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
-            if ((stop_code & ASC_STOP_CLEAN_UP_BUSY_Q) == 0)
-                break;
-            DvcSleepMilliSecond(100);
-        } while (count++ < 20);
-    }
-    return (1);
-}
-
-#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,89)
-STATIC int
-AscCleanUpDiscQueue(
-                       PortAddr iop_base
-)
-{
-    int                 count;
-    uchar               stop_code;
-
-    count = 0;
-    if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
-        AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
-                         ASC_STOP_CLEAN_UP_DISC_Q);
-        do {
-            stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
-            if ((stop_code & ASC_STOP_CLEAN_UP_DISC_Q) == 0)
-                break;
-            DvcSleepMilliSecond(100);
-        } while (count++ < 20);
-    }
-    return (1);
-}
-#endif /* version >= v1.3.89 */
-
-STATIC int
-AscWaitTixISRDone(
-                     ASC_DVC_VAR *asc_dvc,
-                     uchar target_ix
-)
-{
-    uchar               cur_req;
-    uchar               tid_no;
-    int                 i = 0;
-
-    tid_no = ASC_TIX_TO_TID(target_ix);
-    while (i++ < 10) {
-        if ((cur_req = asc_dvc->cur_dvc_qng[tid_no]) == 0) {
-            break;
-        }
-        DvcSleepMilliSecond(1000L);
-        if (asc_dvc->cur_dvc_qng[tid_no] == cur_req) {
-            break;
-        }
-    }
-    return (1);
-}
-
-STATIC int
-AscWaitISRDone(
-                  ASC_DVC_VAR *asc_dvc
-)
-{
-    int                 tid;
-
-    for (tid = 0; tid <= ASC_MAX_TID; tid++) {
-        AscWaitTixISRDone(asc_dvc, ASC_TID_TO_TIX(tid));
-    }
-    return (1);
-}
-
-STATIC ASC_PADDR
-AscGetOnePhyAddr(
-                    ASC_DVC_VAR *asc_dvc,
-                    uchar * buf_addr,
-                    ASC_DCNT buf_size
-)
-{
-    ASC_MIN_SG_HEAD     sg_head;
-
-    sg_head.entry_cnt = ASC_MIN_SG_LIST;
-    if (DvcGetSGList(asc_dvc, (uchar *) buf_addr,
-                  buf_size, (ASC_SG_HEAD *) &sg_head) != buf_size) {
-        return (0L);
-    }
-    if (sg_head.entry_cnt > 1) {
-        return (0L);
-    }
-    return ((ASC_PADDR) sg_head.sg_list[0].addr);
-}
-
 STATIC void
 DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
 {
@@ -13362,6 +11973,7 @@
     udelay((nano_sec + 999)/1000);
 }
 
+#ifdef CONFIG_ISA
 ASC_INITFUNC(
 STATIC ASC_DCNT,
 AscGetEisaProductID(
@@ -13420,6 +12032,7 @@
     }
     return (0);
 }
+#endif /* CONFIG_ISA */
 
 STATIC int
 AscStartChip(
@@ -13593,6 +12206,7 @@
     return (ASC_MAX_PCI_DMA_COUNT);
 }
 
+#ifdef CONFIG_ISA
 ASC_INITFUNC(
 STATIC ushort,
 AscGetIsaDmaChannel(
@@ -13664,6 +12278,7 @@
     AscSetBank(iop_base, 0);
     return (speed_value);
 }
+#endif /* CONFIG_ISA */
 
 ASC_INITFUNC(
 STATIC ushort,
@@ -13841,19 +12456,19 @@
         asc_dvc->cfg->chip_scsi_id) {
         asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
     }
+#ifdef CONFIG_ISA
     if (asc_dvc->bus_type & ASC_IS_ISA) {
         AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
         AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
     }
+#endif /* CONFIG_ISA */
     return (warn_code);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort
 AscInitAsc1000Driver(
                         ASC_DVC_VAR *asc_dvc
 )
-)
 {
     ushort              warn_code;
     PortAddr            iop_base;
@@ -13877,7 +12492,9 @@
     warn_code |= AscInitLram(asc_dvc);
     if (asc_dvc->err_code != 0)
         return (UW_ERR);
-    if (AscLoadMicroCode(iop_base, 0, (ushort *) _asc_mcode_buf,
+    ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
+        (ulong) _asc_mcode_chksum);
+    if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
                          _asc_mcode_size) != _asc_mcode_chksum) {
         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
         return (warn_code);
@@ -13912,7 +12529,7 @@
     asc_dvc->bug_fix_cntl = 0;
     asc_dvc->pci_fix_asyn_xfer = 0;
     asc_dvc->pci_fix_asyn_xfer_always = 0;
-    asc_dvc->init_state = 0;
+    /* asc_dvc->init_state initalized in AscInitGetConfig(). */
     asc_dvc->sdtr_done = 0;
     asc_dvc->cur_total_qng = 0;
     asc_dvc->is_in_int = 0;
@@ -13988,9 +12605,11 @@
         AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
         asc_dvc->bus_type = ASC_IS_ISAPNP;
     }
+#ifdef CONFIG_ISA
     if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
         asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
     }
+#endif /* CONFIG_ISA */
     for (i = 0; i <= ASC_MAX_TID; i++) {
         asc_dvc->cur_dvc_qng[i] = 0;
         asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
@@ -14037,7 +12656,7 @@
         asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
         return (warn_code);
     }
-    eep_config = (ASCEEP_CONFIG *) & eep_config_buf;
+    eep_config = (ASCEEP_CONFIG *) &eep_config_buf;
     cfg_msw = AscGetChipCfgMsw(iop_base);
     cfg_lsw = AscGetChipCfgLsw(iop_base);
     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
@@ -14046,6 +12665,7 @@
         AscSetChipCfgMsw(iop_base, cfg_msw);
     }
     chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
+    ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
     if (chksum == 0) {
         chksum = 0xaa55;
     }
@@ -14064,10 +12684,14 @@
     }
     eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
     eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
+    ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
+        eep_config->chksum);
     if (chksum != eep_config->chksum) {
             if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
                     ASC_CHIP_VER_PCI_ULTRA_3050 )
             {
+                ASC_DBG(1,
+"AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
                 eep_config->init_sdtr = 0xFF;
                 eep_config->disc_enable = 0xFF;
                 eep_config->start_motor = 0xFF;
@@ -14075,7 +12699,7 @@
                 eep_config->max_total_qng = 0xF0;
                 eep_config->max_tag_qng = 0x20;
                 eep_config->cntl = 0xBFFF;
-                eep_config->chip_scsi_id = 7;
+                ASC_EEP_SET_CHIP_ID(eep_config, 7);
                 eep_config->no_scam = 0;
                 eep_config->adapter_info[0] = 0;
                 eep_config->adapter_info[1] = 0;
@@ -14085,6 +12709,8 @@
                 /* Indicate EEPROM-less board. */
                 eep_config->adapter_info[5] = 0xBB;
             } else {
+                ASC_PRINT(
+"AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
                 write_eep = 1;
                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
             }
@@ -14092,7 +12718,7 @@
     asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
     asc_dvc->cfg->disc_enable = eep_config->disc_enable;
     asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
-    asc_dvc->cfg->isa_dma_speed = eep_config->isa_dma_speed;
+    asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
     asc_dvc->start_motor = eep_config->start_motor;
     asc_dvc->dvc_cntl = eep_config->cntl;
     asc_dvc->no_scam = eep_config->no_scam;
@@ -14136,8 +12762,8 @@
     if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
         asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
     }
-    eep_config->chip_scsi_id &= ASC_MAX_TID;
-    asc_dvc->cfg->chip_scsi_id = eep_config->chip_scsi_id;
+    ASC_EEP_SET_CHIP_ID(eep_config, ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
+    asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
     if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
         !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
         asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
@@ -14152,22 +12778,27 @@
     }
     eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
     if (write_eep) {
-        (void) AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
+        if ((i = AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type)) !=
+             0) {
+                ASC_PRINT1(
+"AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", i);
+        } else {
+                ASC_PRINT("AscInitFromEEP: Succesfully re-wrote EEPROM.");
+        }
     }
     return (warn_code);
 }
 
-ASC_INITFUNC(
-STATIC ushort,
+STATIC ushort
 AscInitMicroCodeVar(
                        ASC_DVC_VAR *asc_dvc
 )
-)
 {
     int                 i;
     ushort              warn_code;
     PortAddr            iop_base;
     ASC_PADDR           phy_addr;
+    ASC_DCNT            phy_size;
 
     iop_base = asc_dvc->iop_base;
     warn_code = 0;
@@ -14176,26 +12807,27 @@
                                 asc_dvc->cfg->sdtr_period_offset[i]
 );
     }
+
     AscInitQLinkVar(asc_dvc);
     AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
                      asc_dvc->cfg->disc_enable);
     AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
                      ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
-    if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
-                                 (uchar *) asc_dvc->cfg->overrun_buf,
-                                     ASC_OVERRUN_BSIZE)) == 0L) {
-        asc_dvc->err_code |= ASC_IERR_GET_PHY_ADDR;
-    } else {
-        /* Align on an 8 byte boundary. */
-        phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
-        AscWriteLramDWord(iop_base, ASCV_OVERRUN_PADDR_D, phy_addr);
-        AscWriteLramDWord(iop_base, ASCV_OVERRUN_BSIZE_D,
-                          ASC_OVERRUN_BSIZE - 8);
-    }
-    asc_dvc->cfg->mcode_date = AscReadLramWord(iop_base,
-                                               (ushort) ASCV_MC_DATE_W);
-    asc_dvc->cfg->mcode_version = AscReadLramWord(iop_base,
-                                                  (ushort) ASCV_MC_VER_W);
+
+    /* Align overrun buffer on an 8 byte boundary. */
+    phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
+    phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
+    AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
+        (uchar *) &phy_addr, 1);
+    phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
+    AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
+        (uchar *) &phy_size, 1);
+
+    asc_dvc->cfg->mcode_date =
+        AscReadLramWord(iop_base, (ushort) ASCV_MC_DATE_W);
+    asc_dvc->cfg->mcode_version =
+        AscReadLramWord(iop_base, (ushort) ASCV_MC_VER_W);
+
     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
         asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
@@ -14205,6 +12837,7 @@
         asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
         return (warn_code);
     }
+
     return (warn_code);
 }
 
@@ -14368,16 +13001,15 @@
     ushort              *wbuf;
     int                 cfg_beg;
     int                 cfg_end;
+    int                 uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
     int                 s_addr;
-    int                 isa_pnp_wsize;
 
     wbuf = (ushort *) cfg_buf;
     sum = 0;
-    isa_pnp_wsize = 0;
-    for (s_addr = 0; s_addr < (2 + isa_pnp_wsize); s_addr++, wbuf++) {
-        wval = AscReadEEPWord(iop_base, (uchar) s_addr);
-        sum += wval;
-        *wbuf = wval;
+    /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
+    for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
+        *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
+        sum += *wbuf;
     }
     if (bus_type & ASC_IS_VL) {
         cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
@@ -14386,12 +13018,24 @@
         cfg_beg = ASC_EEP_DVC_CFG_BEG;
         cfg_end = ASC_EEP_MAX_DVC_ADDR;
     }
-    for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
-         s_addr++, wbuf++) {
-        wval = AscReadEEPWord(iop_base, (uchar) s_addr);
-        sum += wval;
-        *wbuf = wval;
+    for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
+        wval = AscReadEEPWord( iop_base, ( uchar )s_addr ) ;
+        if (s_addr <= uchar_end_in_config) {
+            /*
+             * Swap all char fields - must unswap bytes already swapped
+             * by AscReadEEPWord().
+             */
+            *wbuf = le16_to_cpu(wval);
+        } else {
+            /* Don't swap word field at the end - cntl field. */
+            *wbuf = wval;
+        }
+        sum += wval; /* Checksum treats all EEPROM data as words. */
     }
+    /*
+     * Read the checksum word which will be compared against 'sum'
+     * by the caller. Word field already swapped.
+     */
     *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
     return (sum);
 }
@@ -14405,15 +13049,19 @@
 )
 {
     int                 n_error;
-    ushort      *wbuf;
+    ushort              *wbuf;
+    ushort              word;
     ushort              sum;
     int                 s_addr;
     int                 cfg_beg;
     int                 cfg_end;
+    int                 uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
+
 
     wbuf = (ushort *) cfg_buf;
     n_error = 0;
     sum = 0;
+    /* Write two config words; AscWriteEEPWord() will swap bytes. */
     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
         sum += *wbuf;
         if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
@@ -14427,29 +13075,66 @@
         cfg_beg = ASC_EEP_DVC_CFG_BEG;
         cfg_end = ASC_EEP_MAX_DVC_ADDR;
     }
-    for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
-         s_addr++, wbuf++) {
-        sum += *wbuf;
-        if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
-            n_error++;
+    for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
+        if (s_addr <= uchar_end_in_config) {
+            /*
+             * This is a char field. Swap char fields before they are
+             * swapped again by AscWriteEEPWord().
+             */
+            word = cpu_to_le16(*wbuf);
+            if (word != AscWriteEEPWord( iop_base, (uchar) s_addr, word)) {
+                n_error++;
+            }
+        } else {
+            /* Don't swap word field at the end - cntl field. */
+            if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
+                n_error++;
+            }
         }
+        sum += *wbuf; /* Checksum calculated from word values. */
     }
+    /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
     *wbuf = sum;
     if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
         n_error++;
     }
+
+    /* Read EEPROM back again. */
     wbuf = (ushort *) cfg_buf;
+    /*
+     * Read two config words; Byte-swapping done by AscReadEEPWord().
+     */
     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
         if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
             n_error++;
         }
     }
-    for (s_addr = cfg_beg; s_addr <= cfg_end;
-         s_addr++, wbuf++) {
-        if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
+    if (bus_type & ASC_IS_VL) {
+        cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
+        cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
+    } else {
+        cfg_beg = ASC_EEP_DVC_CFG_BEG;
+        cfg_end = ASC_EEP_MAX_DVC_ADDR;
+    }
+    for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
+        if (s_addr <= uchar_end_in_config) {
+            /*
+             * Swap all char fields. Must unswap bytes already swapped
+             * by AscReadEEPWord().
+             */
+            word = le16_to_cpu(AscReadEEPWord(iop_base, (uchar) s_addr));
+        } else {
+            /* Don't swap word field at the end - cntl field. */
+            word = AscReadEEPWord(iop_base, (uchar) s_addr);
+        }
+        if (*wbuf != word) {
             n_error++;
         }
     }
+    /* Read checksum; Byte swapping not needed. */
+    if (AscReadEEPWord(iop_base, (uchar) s_addr) != sum) {
+        n_error++;
+    }
     return (n_error);
 }
 
@@ -14486,7 +13171,7 @@
     uchar                       dvc_type;
     ASC_SCSI_BIT_ID_TYPE        tid_bits;
 
-    dvc_type = inq->byte0.peri_dvc_type;
+    dvc_type = ASC_INQ_DVC_TYPE(inq);
     tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
 
     if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)
@@ -14546,11 +13231,12 @@
     asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
     asc_dvc->use_tagged_qng &= ~tid_bit;
 
-    if (inq->byte3.rsp_data_fmt >= 2 || inq->byte2.ansi_apr_ver >= 2) {
-        if ((asc_dvc->cfg->sdtr_enable & tid_bit) && inq->byte7.Sync) {
+    if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
+        if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
             asc_dvc->init_sdtr |= tid_bit;
         }
-        if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) && inq->byte7.CmdQue) {
+        if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
+             ASC_INQ_CMD_QUEUE(inq)) {
             if (AscTagQueuingSafe(inq)) {
                 asc_dvc->use_tagged_qng |= tid_bit;
                 asc_dvc->cfg->can_tagged_qng |= tid_bit;
@@ -14615,7 +13301,6 @@
     }
     return (byte_data);
 }
-
 STATIC ushort
 AscReadLramWord(
                    PortAddr iop_base,
@@ -14629,6 +13314,7 @@
     return (word_data);
 }
 
+#if CC_VERY_LONG_SG_LIST
 STATIC ASC_DCNT
 AscReadLramDWord(
                     PortAddr iop_base,
@@ -14644,6 +13330,7 @@
     dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
     return (dword_data);
 }
+#endif /* CC_VERY_LONG_SG_LIST */
 
 STATIC void
 AscWriteLramWord(
@@ -14658,23 +13345,6 @@
 }
 
 STATIC void
-AscWriteLramDWord(
-                     PortAddr iop_base,
-                     ushort addr,
-                     ASC_DCNT dword_val
-)
-{
-    ushort              word_val;
-
-    AscSetChipLramAddr(iop_base, addr);
-    word_val = (ushort) dword_val;
-    AscSetChipLramData(iop_base, word_val);
-    word_val = (ushort) (dword_val >> 16);
-    AscSetChipLramData(iop_base, word_val);
-    return;
-}
-
-STATIC void
 AscWriteLramByte(
                     PortAddr iop_base,
                     ushort addr,
@@ -14697,42 +13367,87 @@
     return;
 }
 
+/*
+ * Copy 2 bytes to LRAM.
+ *
+ * The source data is assumed to be in little-endian order in memory
+ * and is maintained in little-endian order when written to LRAM.
+ */
 STATIC void
-AscMemWordCopyToLram(
+AscMemWordCopyPtrToLram(
                         PortAddr iop_base,
                         ushort s_addr,
-                        ushort * s_buffer,
+                        uchar *s_buffer,
                         int words
 )
 {
-    AscSetChipLramAddr(iop_base, s_addr);
-    DvcOutPortWords(iop_base + IOP_RAM_DATA, s_buffer, words);
+    int    i;
+
+    AscSetChipLramAddr(iop_base, s_addr);
+    for (i = 0; i < 2 * words; i += 2) {
+        /*
+         * On a little-endian system the second argument below
+         * produces a little-endian ushort which is written to
+         * LRAM in little-endian order. On a big-endian system
+         * the second argument produces a big-endian ushort which
+         * is "transparently" byte-swapped by outpw() and written
+         * in little-endian order to LRAM.
+         */
+        outpw(iop_base + IOP_RAM_DATA,
+            ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]);
+    }
     return;
 }
 
+/*
+ * Copy 4 bytes to LRAM.
+ *
+ * The source data is assumed to be in little-endian order in memory
+ * and is maintained in little-endian order when writen to LRAM.
+ */
 STATIC void
-AscMemDWordCopyToLram(
+AscMemDWordCopyPtrToLram(
                          PortAddr iop_base,
                          ushort s_addr,
-                         ASC_DCNT *s_buffer,
+                         uchar *s_buffer,
                          int dwords
 )
 {
+    int       i;
+
     AscSetChipLramAddr(iop_base, s_addr);
-    DvcOutPortDWords(iop_base + IOP_RAM_DATA, s_buffer, dwords);
+    for (i = 0; i < 4 * dwords; i += 4) {
+        outpw(iop_base + IOP_RAM_DATA,
+            ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
+        outpw(iop_base + IOP_RAM_DATA,
+            ((ushort) s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
+    }
     return;
 }
 
+/*
+ * Copy 2 bytes from LRAM.
+ *
+ * The source data is assumed to be in little-endian order in LRAM
+ * and is maintained in little-endian order when written to memory.
+ */
 STATIC void
-AscMemWordCopyFromLram(
+AscMemWordCopyPtrFromLram(
                           PortAddr iop_base,
                           ushort s_addr,
-                          ushort * d_buffer,
+                          uchar *d_buffer,
                           int words
 )
 {
+    int i;
+    ushort word;
+
     AscSetChipLramAddr(iop_base, s_addr);
-    DvcInPortWords(iop_base + IOP_RAM_DATA, d_buffer, words);
+    for (i = 0; i < 2 * words; i += 2) {
+        word = inpw(iop_base + IOP_RAM_DATA);
+        d_buffer[i] = word & 0xff;
+        d_buffer[i + 1] = (word >> 8) & 0xff;
+    }
     return;
 }
 
@@ -14776,676 +13491,1078 @@
  */
 
 /* a_mcode.h */
+
+/* Microcode buffer is kept after initialization for error recovery. */
 STATIC unsigned char _adv_asc3550_buf[] = {
-  0x00,  0x00,  0x00,  0xf2,  0x00,  0xf0,  0x00,  0x16,  0x00,  0xfc,  0x48,  0xe4,  0x01,  0x00,  0x18,  0xe4,
-  0x00,  0xf6,  0x01,  0xf6,  0x18,  0x80,  0x48,  0x19,  0x02,  0x00,  0xff,  0xff,  0x03,  0xf6,  0x00,  0xfa,
-  0xff,  0x00,  0x82,  0xe7,  0x01,  0xfa,  0x9e,  0xe7,  0x09,  0xe7,  0x3a,  0x0e,  0x00,  0xea,  0x01,  0xe6,
-  0x55,  0xf0,  0x03,  0x00,  0x08,  0x00,  0x18,  0xf4,  0x3e,  0x01,  0x3e,  0x57,  0x04,  0x00,  0x85,  0xf0,
-  0x00,  0xe6,  0x00,  0xec,  0x1e,  0xf0,  0x32,  0xf0,  0x34,  0x19,  0x86,  0xf0,  0xd0,  0x01,  0xd5,  0xf0,
-  0xde,  0x0c,  0x98,  0x57,  0xbc,  0x00,  0x0c,  0x1c,  0x0e,  0x13,  0x38,  0x54,  0xb1,  0xf0,  0xb4,  0x00,
-  0x01,  0xfc,  0x03,  0xfc,  0xd8,  0x0c,  0x00,  0x57,  0x01,  0xf0,  0x02,  0x13,  0x03,  0xe6,  0x10,  0x00,
-  0x18,  0x40,  0x3e,  0x1c,  0x6c,  0x01,  0x6e,  0x01,  0xbd,  0x00,  0xe0,  0x00,  0x02,  0x48,  0x02,  0x80,
-  0x08,  0x12,  0x30,  0xe4,  0x3c,  0x00,  0x4e,  0x01,  0x64,  0x12,  0x80,  0x00,  0x9c,  0x15,  0xbb,  0x00,
-  0x00,  0x4e,  0x01,  0x01,  0x01,  0xea,  0x04,  0x12,  0x9e,  0x0f,  0xb6,  0x00,  0xb9,  0x54,  0xe2,  0x0f,
-  0x00,  0x80,  0x06,  0xf7,  0x10,  0x44,  0x24,  0x01,  0x28,  0x01,  0x32,  0x00,  0x3c,  0x01,  0x3c,  0x56,
-  0x3e,  0x00,  0x4b,  0xe4,  0x4c,  0x1c,  0x68,  0x01,  0x6a,  0x01,  0x70,  0x01,  0x72,  0x01,  0x74,  0x01,
-  0x76,  0x01,  0x78,  0x01,  0xe2,  0x0c,  0x00,  0x01,  0x02,  0xee,  0x02,  0xfc,  0x03,  0x58,  0x03,  0xf7,
-  0x04,  0x80,  0x05,  0xfc,  0x08,  0x44,  0x09,  0xf0,  0x0f,  0x00,  0x1b,  0x80,  0x20,  0x01,  0x38,  0x1c,
-  0x40,  0x00,  0x40,  0x15,  0x4b,  0xf4,  0x4e,  0x1c,  0x5b,  0xf0,  0x5d,  0xf0,  0xaa,  0x00,  0xbb,  0x55,
-  0xbe,  0x00,  0xc0,  0x00,  0xe0,  0x08,  0xe0,  0x14,  0xec,  0x0f,  0x00,  0x4c,  0x00,  0xdc,  0x02,  0x4a,
-  0x05,  0x00,  0x05,  0xf0,  0x05,  0xf8,  0x06,  0x13,  0x08,  0x13,  0x0c,  0x00,  0x0e,  0x47,  0x0e,  0xf7,
-  0x19,  0x00,  0x20,  0x00,  0x2a,  0x01,  0x30,  0x0e,  0x32,  0x1c,  0x36,  0x00,  0x45,  0x5a,  0x59,  0xf0,
-  0x62,  0x0a,  0x69,  0x08,  0x72,  0x0b,  0x83,  0x59,  0xb8,  0xf0,  0xbd,  0x56,  0xcc,  0x12,  0xec,  0x17,
-  0xee,  0x0f,  0xf0,  0x00,  0xf8,  0x17,  0x01,  0x48,  0x02,  0xfa,  0x03,  0xfa,  0x04,  0x10,  0x04,  0xea,
-  0x04,  0xf6,  0x04,  0xfc,  0x05,  0x80,  0x05,  0xe6,  0x06,  0x00,  0x06,  0x12,  0x0a,  0x10,  0x0b,  0xf0,
-  0x0c,  0x10,  0x0c,  0xf0,  0x12,  0x10,  0x26,  0x0e,  0x30,  0x1c,  0x33,  0x00,  0x34,  0x00,  0x38,  0x44,
-  0x40,  0x5c,  0x4a,  0xe4,  0x62,  0x1a,  0x68,  0x08,  0x68,  0x54,  0x83,  0x55,  0x83,  0x5a,  0x8c,  0x14,
-  0x8e,  0x0a,  0x90,  0x14,  0x91,  0x44,  0xa4,  0x00,  0xb0,  0x57,  0xb5,  0x00,  0xba,  0x00,  0xce,  0x45,
-  0xd0,  0x00,  0xd8,  0x16,  0xe1,  0x00,  0xe7,  0x00,  0x00,  0x54,  0x01,  0x58,  0x02,  0x10,  0x02,  0xe6,
-  0x03,  0xa1,  0x04,  0x13,  0x06,  0x83,  0x06,  0xf0,  0x07,  0x00,  0x0a,  0x00,  0x0a,  0x12,  0x0a,  0xf0,
-  0x0c,  0x04,  0x0c,  0x12,  0x0c,  0x90,  0x10,  0x10,  0x10,  0x13,  0x12,  0x1c,  0x17,  0x00,  0x19,  0xe4,
-  0x1a,  0x10,  0x1c,  0x00,  0x1c,  0x12,  0x1d,  0xf7,  0x1e,  0x13,  0x20,  0x1c,  0x20,  0xe7,  0x22,  0x01,
-  0x26,  0x01,  0x2a,  0x12,  0x30,  0xe7,  0x34,  0x1c,  0x36,  0x1c,  0x38,  0x12,  0x41,  0x58,  0x43,  0x48,
-  0x44,  0x55,  0x46,  0x1c,  0x4c,  0x0e,  0x4e,  0xe4,  0x52,  0x14,  0x5c,  0xf0,  0x72,  0x02,  0x74,  0x03,
-  0x77,  0x57,  0x89,  0x48,  0x8e,  0x90,  0x99,  0x00,  0x9b,  0x00,  0x9c,  0x32,  0x9e,  0x00,  0xa8,  0x00,
-  0xb9,  0x00,  0xba,  0x06,  0xbc,  0x12,  0xbf,  0x57,  0xc0,  0x01,  0xfe,  0x9c,  0xf0,  0x26,  0x02,  0xfe,
-  0x00,  0x0d,  0xff,  0x10,  0x00,  0x00,  0xfe,  0xc2,  0x01,  0xfe,  0x56,  0x19,  0x00,  0xfc,  0xfe,  0x80,
-  0x01,  0xff,  0x03,  0x00,  0x00,  0xfe,  0x6a,  0x13,  0xfe,  0x05,  0x05,  0xff,  0x40,  0x00,  0x00,  0x0d,
-  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,  0x01,  0x01,  0xff,  0x10,  0xff,  0xff,  0xff,  0x1f,  0x00,  0x00,
-  0xff,  0x10,  0xff,  0xff,  0xff,  0x0f,  0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,
-  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xfc,  0x2b,  0x51,  0x0c,  0x01,  0xfe,  0xea,  0x0e,  0xfe,  0x04,  0xf7,
-  0xfc,  0x51,  0x0c,  0x1d,  0x2b,  0xfe,  0x3d,  0xf0,  0xfe,  0xf8,  0x01,  0xfe,  0x20,  0xf0,  0xd0,  0x04,
-  0x56,  0x4b,  0x02,  0xfe,  0x1c,  0x0d,  0x01,  0xfe,  0x7c,  0x0d,  0xfe,  0xe9,  0x12,  0x02,  0xfe,  0x04,
-  0x03,  0xfe,  0x28,  0x1c,  0x04,  0xfe,  0xa6,  0x00,  0xfe,  0xdd,  0x12,  0x4e,  0x12,  0xfe,  0xa6,  0x00,
-  0xc5,  0xfe,  0x48,  0xf0,  0xfe,  0x7c,  0x02,  0xfe,  0x49,  0xf0,  0xfe,  0x96,  0x02,  0xfe,  0x4a,  0xf0,
-  0xfe,  0xb4,  0x02,  0xfe,  0x46,  0xf0,  0xfe,  0x46,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x4c,  0x02,  0xfe,
-  0x43,  0xf0,  0xfe,  0x3a,  0x02,  0xfe,  0x44,  0xf0,  0xfe,  0x3e,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x42,
-  0x02,  0x09,  0x0c,  0x9e,  0x09,  0x06,  0x12,  0xbb,  0x02,  0x26,  0xfe,  0x00,  0x1c,  0xfe,  0xf1,  0x10,
-  0xfe,  0x02,  0x1c,  0xfe,  0xed,  0x10,  0xfe,  0x1e,  0x1c,  0xfe,  0xe9,  0x10,  0x01,  0xfe,  0x4c,  0x17,
-  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xf7,  0x0e,  0x78,  0x01,  0xab,  0x02,  0x26,  0x17,  0x55,  0x4a,
-  0xbd,  0x01,  0xfe,  0x60,  0x0f,  0x0e,  0x78,  0x01,  0x8b,  0xfe,  0xbd,  0x10,  0x0e,  0x78,  0x01,  0x8b,
-  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x09,  0x06,  0x12,  0xbb,  0x2b,  0x22,  0x26,
-  0xfe,  0x3d,  0xf0,  0xfe,  0xf8,  0x01,  0x27,  0xfe,  0x8a,  0x02,  0xfe,  0x5a,  0x1c,  0xd5,  0xfe,  0x14,
-  0x1c,  0x17,  0xfe,  0x30,  0x00,  0x4a,  0xbd,  0x01,  0xfe,  0x50,  0x0f,  0x09,  0x06,  0x12,  0xbb,  0x02,
-  0xfe,  0xc2,  0x01,  0x21,  0x2a,  0x05,  0x10,  0x35,  0xfe,  0x69,  0x10,  0x09,  0x06,  0x12,  0xbb,  0xfe,
-  0x04,  0xec,  0x2a,  0x08,  0x2a,  0x09,  0x3c,  0x1d,  0x01,  0x46,  0x7f,  0xfe,  0x05,  0xf6,  0xf7,  0x01,
-  0xfe,  0x76,  0x16,  0x0a,  0x41,  0x89,  0x38,  0x11,  0x47,  0x1d,  0xca,  0x08,  0x1c,  0x09,  0x43,  0x01,
-  0x71,  0x02,  0x26,  0x0e,  0x3d,  0x01,  0x15,  0x05,  0x10,  0x2c,  0x08,  0x1c,  0x09,  0x43,  0x01,  0x7b,
-  0xfe,  0x28,  0x10,  0x0e,  0xc0,  0x01,  0x15,  0xe6,  0x0e,  0x79,  0x01,  0x15,  0xfe,  0x49,  0x54,  0x74,
-  0xfe,  0x12,  0x03,  0x08,  0x1c,  0x09,  0x43,  0x01,  0x71,  0x02,  0x26,  0x2b,  0x7f,  0xfe,  0x02,  0xe8,
-  0x2f,  0xfb,  0xfe,  0x9e,  0x43,  0xf0,  0xfe,  0x07,  0x4b,  0xfe,  0x20,  0xf0,  0xd0,  0xfe,  0x40,  0x1c,
-  0x22,  0xef,  0xfe,  0x26,  0xf0,  0xfe,  0x70,  0x03,  0xfe,  0xa0,  0xf0,  0xfe,  0x5e,  0x03,  0xfe,  0x11,
-  0xf0,  0xd0,  0xfe,  0x0e,  0x10,  0xfe,  0x9f,  0xf0,  0xfe,  0x7e,  0x03,  0xe9,  0x13,  0xfe,  0x11,  0x00,
-  0x02,  0x62,  0x2b,  0xfe,  0x48,  0x1c,  0xe9,  0x22,  0xef,  0x34,  0xef,  0xfe,  0x82,  0xf0,  0xfe,  0x84,
-  0x03,  0x2d,  0x21,  0xbe,  0x6a,  0x16,  0xbe,  0x0e,  0x79,  0x01,  0x15,  0x6a,  0x7d,  0x08,  0x1c,  0x09,
-  0x43,  0x01,  0x46,  0x11,  0x3d,  0x08,  0x3d,  0x09,  0x99,  0x01,  0x71,  0xf5,  0x11,  0xfe,  0xe4,  0x00,
-  0x2e,  0xfe,  0xca,  0x03,  0x22,  0x32,  0x1f,  0xfe,  0xda,  0x03,  0x01,  0x4c,  0xcb,  0xfe,  0xea,  0x03,
-  0x6b,  0x92,  0xcf,  0xfe,  0xaa,  0x06,  0x02,  0x28,  0x04,  0x78,  0x29,  0x18,  0xfe,  0x1c,  0x05,  0x17,
-  0x85,  0x01,  0x44,  0x01,  0x97,  0x01,  0x9a,  0x34,  0xfe,  0x5c,  0x02,  0x02,  0xee,  0xe9,  0x2b,  0x51,
-  0x19,  0xfe,  0x67,  0x1b,  0xfb,  0xf0,  0xfe,  0x48,  0x1c,  0x8c,  0x01,  0xfa,  0xac,  0xfe,  0x96,  0xf0,
-  0xfe,  0x24,  0x04,  0x2e,  0xfe,  0x28,  0x04,  0x34,  0x26,  0x0e,  0x3d,  0x01,  0x15,  0x05,  0x10,  0x18,
-  0xfe,  0x08,  0x05,  0x3e,  0x90,  0x9f,  0x2f,  0x82,  0x6e,  0x22,  0x32,  0x1f,  0x28,  0x04,  0x78,  0x29,
-  0xfe,  0x10,  0x12,  0x17,  0x85,  0x01,  0x44,  0x34,  0xfe,  0x5c,  0x02,  0x02,  0xee,  0x31,  0xfe,  0xa0,
-  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x5e,  0x12,  0x0a,  0x07,  0x06,  0xfe,  0x56,  0x12,  0x23,  0x24,  0x91,
-  0x01,  0x0b,  0x82,  0x6e,  0x1f,  0xfe,  0xd8,  0x04,  0x23,  0x24,  0x91,  0x01,  0x0b,  0x1f,  0x28,  0x23,
-  0x24,  0xb3,  0xfe,  0x4c,  0x44,  0xfe,  0x32,  0x12,  0x57,  0xfe,  0x44,  0x48,  0x08,  0xd6,  0xfe,  0x4c,
-  0x54,  0x74,  0xfe,  0x08,  0x05,  0x7f,  0x9f,  0x2f,  0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x48,
-  0x13,  0x3f,  0x05,  0xfe,  0xcc,  0x00,  0xfe,  0x40,  0x13,  0x0a,  0x07,  0x06,  0xe5,  0xfe,  0x06,  0x10,
-  0x23,  0x24,  0xb3,  0x0a,  0x07,  0x37,  0xda,  0x17,  0xa4,  0x0a,  0x07,  0x06,  0x4b,  0x17,  0xfe,  0x0d,
-  0x00,  0x01,  0x44,  0x34,  0xfe,  0xc0,  0x0c,  0x02,  0x28,  0x39,  0x11,  0xfe,  0xe6,  0x00,  0xfe,  0x1c,
-  0x90,  0xb0,  0x03,  0x17,  0xa4,  0x01,  0x44,  0x34,  0x26,  0x22,  0x26,  0x02,  0xfe,  0x10,  0x05,  0xfe,
-  0x42,  0x5b,  0x51,  0x19,  0xfe,  0x46,  0x59,  0xfb,  0xf0,  0x17,  0x45,  0xfe,  0x07,  0x80,  0xfe,  0x31,
-  0x44,  0x0a,  0x07,  0x0c,  0xfe,  0x78,  0x13,  0xfe,  0x20,  0x80,  0x05,  0x19,  0xfe,  0x70,  0x12,  0x6d,
-  0x07,  0x06,  0xfe,  0x60,  0x13,  0x04,  0xfe,  0xa2,  0x00,  0x29,  0x18,  0xfe,  0xa8,  0x05,  0xfe,  0x31,
-  0xe4,  0x70,  0x6d,  0x07,  0x0c,  0xfe,  0x4a,  0x13,  0x04,  0xfe,  0xa0,  0x00,  0x29,  0xfe,  0x42,  0x12,
-  0x5a,  0x2e,  0xfe,  0x68,  0x05,  0x22,  0x32,  0xf1,  0x01,  0x0b,  0x25,  0xfe,  0xc0,  0x05,  0x11,  0xfe,
-  0xe3,  0x00,  0x2d,  0x6d,  0xfe,  0x4a,  0xf0,  0xfe,  0x92,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0x8c,  0x05,
-  0xa8,  0x20,  0xfe,  0x21,  0x00,  0xa6,  0x20,  0xfe,  0x22,  0x00,  0x9e,  0x20,  0x89,  0xfe,  0x09,  0x48,
-  0x01,  0x0b,  0x25,  0xfe,  0xc0,  0x05,  0xfe,  0xe2,  0x08,  0x6d,  0x07,  0xd9,  0x4b,  0x01,  0x96,  0x20,
-  0x06,  0x16,  0xe0,  0x4a,  0xfe,  0x27,  0x01,  0x0a,  0x07,  0x37,  0xe1,  0x4e,  0x01,  0xb9,  0x17,  0xa4,
-  0x0a,  0x07,  0x06,  0x4b,  0x17,  0xfe,  0x0d,  0x00,  0x01,  0x44,  0x01,  0x97,  0x01,  0x9a,  0x34,  0xfe,
-  0xc0,  0x0c,  0x02,  0x28,  0x04,  0xfe,  0x9c,  0x00,  0x29,  0xfe,  0x3e,  0x12,  0x04,  0x53,  0x29,  0xfe,
-  0x36,  0x13,  0x4e,  0x01,  0xb9,  0x25,  0xfe,  0x38,  0x06,  0x0e,  0x06,  0x6d,  0x07,  0x1a,  0xfe,  0x02,
-  0x12,  0x77,  0x01,  0xfe,  0x26,  0x14,  0x1f,  0xfe,  0x2e,  0x06,  0x11,  0xc2,  0x01,  0x4c,  0x11,  0xfe,
-  0xe5,  0x00,  0x04,  0x53,  0xbc,  0x0f,  0x53,  0x04,  0xf6,  0x29,  0xfe,  0x62,  0x12,  0x04,  0x4d,  0x29,
-  0xfe,  0x5a,  0x13,  0x01,  0xfe,  0x9e,  0x18,  0x01,  0xfe,  0xf0,  0x18,  0xe7,  0xa3,  0x1a,  0x08,  0x63,
-  0xff,  0x02,  0x00,  0x57,  0x66,  0x7e,  0x1b,  0x50,  0xc9,  0xa3,  0x6c,  0x4e,  0x01,  0xb9,  0x25,  0xfe,
-  0xa2,  0x06,  0x6d,  0x07,  0x1e,  0xa5,  0x95,  0x0e,  0x55,  0x01,  0xfe,  0x54,  0x14,  0x1f,  0xfe,  0x98,
-  0x06,  0x11,  0xc2,  0x01,  0x4c,  0x11,  0xfe,  0xe5,  0x00,  0x04,  0x4d,  0xbc,  0x0f,  0x4d,  0x09,  0x06,
-  0x01,  0xb9,  0xf5,  0x73,  0x8c,  0x01,  0xfa,  0xac,  0x11,  0xfe,  0xe2,  0x00,  0x2e,  0xf9,  0x22,  0x32,
-  0xcf,  0xfe,  0xd6,  0x06,  0x81,  0xfe,  0x74,  0x07,  0xcb,  0xfe,  0x7c,  0x07,  0x6b,  0x92,  0x02,  0x28,
-  0x0a,  0x07,  0x0c,  0xfe,  0x2e,  0x12,  0x14,  0x19,  0x01,  0x0b,  0x14,  0x00,  0x01,  0x0b,  0x14,  0x00,
-  0x01,  0x0b,  0x14,  0x00,  0x01,  0x0b,  0xfe,  0x99,  0xa4,  0x01,  0x0b,  0x14,  0x00,  0x02,  0xfe,  0x4c,
-  0x08,  0x68,  0x07,  0x1e,  0xe5,  0x0a,  0x07,  0x1e,  0xfe,  0x30,  0x13,  0x14,  0xfe,  0x1b,  0x00,  0x01,
-  0x0b,  0x14,  0x00,  0x01,  0x0b,  0x14,  0x00,  0x01,  0x0b,  0x14,  0x00,  0x01,  0x0b,  0x14,  0x06,  0x01,
-  0x0b,  0x14,  0x00,  0x02,  0xfe,  0x2a,  0x0b,  0x77,  0xfe,  0x9a,  0x81,  0x67,  0x89,  0xfe,  0x09,  0x6f,
-  0xfe,  0x93,  0x45,  0x18,  0xfe,  0x84,  0x07,  0x2e,  0xfe,  0x5c,  0x07,  0x22,  0x32,  0xcf,  0xfe,  0x54,
-  0x07,  0x6b,  0x92,  0x81,  0xfe,  0x74,  0x07,  0x02,  0x28,  0x01,  0x4c,  0x02,  0xf9,  0x14,  0x1a,  0x02,
-  0xf9,  0xfe,  0x9c,  0xf7,  0xfe,  0xec,  0x07,  0xfe,  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x75,  0xfe,  0xd2,
-  0x07,  0x0f,  0x5d,  0x12,  0x5e,  0x0a,  0x41,  0x70,  0x38,  0x01,  0xfe,  0x34,  0x18,  0x05,  0x10,  0x83,
-  0xfe,  0x83,  0xe7,  0x88,  0xa6,  0xfe,  0x03,  0x40,  0x0a,  0x41,  0x45,  0x38,  0x01,  0xc1,  0xaf,  0xfe,
-  0x1f,  0x40,  0x16,  0x61,  0x01,  0xfe,  0xde,  0x12,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0xfe,  0x34,
-  0x51,  0xfe,  0xb6,  0x51,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,  0x0f,  0x5b,  0x12,  0x5c,  0xd2,  0xf2,
-  0x0f,  0x3a,  0x12,  0x3b,  0xfe,  0x60,  0x10,  0x0a,  0x07,  0x70,  0xe1,  0xfe,  0x2c,  0x90,  0xfe,  0xae,
-  0x90,  0x0f,  0x5d,  0x12,  0x5e,  0x0a,  0x07,  0x45,  0xc9,  0x01,  0xc1,  0xfe,  0x1f,  0x80,  0x16,  0x61,
-  0xfe,  0x34,  0x90,  0xfe,  0xb6,  0x90,  0x0f,  0x5f,  0x12,  0x60,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,
-  0x0f,  0x5b,  0x12,  0x5c,  0xa2,  0x07,  0x45,  0x2c,  0xd2,  0xf2,  0x0f,  0x3a,  0x12,  0x3b,  0xa8,  0xfe,
-  0x28,  0x90,  0xfe,  0xaa,  0x90,  0x0f,  0x3a,  0x12,  0x3b,  0x0f,  0x42,  0x12,  0x58,  0x0a,  0x41,  0x1a,
-  0x38,  0x2b,  0x08,  0x80,  0x2e,  0xfe,  0x62,  0x08,  0xfe,  0x9e,  0xf0,  0xfe,  0x76,  0x08,  0x9b,  0x18,
-  0x32,  0x2b,  0x52,  0xfe,  0xed,  0x10,  0xa7,  0xfe,  0x9a,  0x08,  0xa9,  0xfe,  0xb6,  0x08,  0x81,  0xfe,
-  0x8e,  0x08,  0xcb,  0xfe,  0x94,  0x08,  0x6b,  0x92,  0x02,  0x28,  0x01,  0x4c,  0xfe,  0xc9,  0x10,  0x14,
-  0x1a,  0xfe,  0xc9,  0x10,  0x68,  0x07,  0x06,  0xfe,  0x10,  0x12,  0x68,  0x07,  0x0c,  0x40,  0x0a,  0x07,
-  0x0c,  0xfe,  0x7e,  0x12,  0xfe,  0x2e,  0x1c,  0xaa,  0x68,  0x07,  0x06,  0x40,  0x68,  0x07,  0x0c,  0xfe,
-  0x6a,  0x12,  0xfe,  0x2c,  0x1c,  0xa2,  0x07,  0x45,  0xd4,  0xa2,  0x41,  0x45,  0xfe,  0x05,  0x40,  0xd2,
-  0xf2,  0xfe,  0x28,  0x50,  0xfe,  0xaa,  0x50,  0xfe,  0xaa,  0xf0,  0xfe,  0x4e,  0x09,  0xfe,  0xac,  0xf0,
-  0xfe,  0xee,  0x08,  0xfe,  0x92,  0x10,  0xe3,  0xfe,  0xf3,  0x10,  0xfe,  0xad,  0xf0,  0xfe,  0xfa,  0x08,
-  0x02,  0xfe,  0x5c,  0x0a,  0xe4,  0xfe,  0xe7,  0x10,  0xfe,  0x2b,  0xf0,  0xb8,  0xfe,  0x6b,  0x18,  0x1b,
-  0xfe,  0x00,  0xfe,  0xda,  0xc5,  0xfe,  0xd2,  0xf0,  0xb8,  0xfe,  0x76,  0x18,  0x1b,  0x19,  0x18,  0xb8,
-  0x04,  0xdf,  0x1b,  0x06,  0x18,  0xb8,  0xa7,  0x7a,  0xa9,  0x7a,  0xe3,  0xe4,  0xfe,  0xb1,  0x10,  0x8c,
-  0x5a,  0x39,  0x17,  0xa4,  0x01,  0x44,  0x13,  0xfe,  0x35,  0x00,  0x34,  0x62,  0x13,  0x8d,  0x02,  0x62,
-  0xfe,  0x74,  0x18,  0x1b,  0xfe,  0x00,  0xf8,  0x18,  0x7a,  0x51,  0x1e,  0x01,  0xfe,  0x7c,  0x0d,  0xd1,
-  0x08,  0x1c,  0x09,  0x43,  0x01,  0x71,  0x21,  0x2f,  0x3e,  0x51,  0x19,  0x02,  0x7a,  0xfe,  0x98,  0x80,
-  0xd7,  0x0c,  0x27,  0xfe,  0x3e,  0x0a,  0x0a,  0x07,  0x70,  0xfe,  0x82,  0x12,  0x0a,  0x07,  0x1a,  0xfe,
-  0x66,  0x13,  0x21,  0x61,  0x6a,  0xc8,  0xfe,  0x83,  0x80,  0xfe,  0xc8,  0x44,  0xfe,  0x2e,  0x13,  0xfe,
-  0x04,  0x91,  0xfe,  0x86,  0x91,  0x64,  0x2f,  0xfe,  0x40,  0x59,  0xfe,  0xc1,  0x59,  0x75,  0xfe,  0xea,
-  0x08,  0x04,  0x5d,  0x30,  0x5e,  0x0f,  0xae,  0x12,  0x8d,  0x9c,  0x5d,  0x9d,  0x5e,  0x01,  0xc1,  0xaf,
-  0x64,  0x2f,  0x16,  0x61,  0xa1,  0x42,  0x69,  0x58,  0x65,  0x5f,  0x31,  0x60,  0xe8,  0xfe,  0xe5,  0x55,
-  0xfe,  0x04,  0xfa,  0x42,  0xfe,  0x05,  0xfa,  0x58,  0x01,  0xfe,  0xde,  0x12,  0xfe,  0x36,  0x10,  0x2d,
-  0x0f,  0xae,  0x0f,  0x8d,  0x65,  0x5f,  0x31,  0x60,  0xaa,  0x0a,  0x07,  0x1a,  0x18,  0xfe,  0xea,  0x08,
-  0x65,  0x3a,  0x31,  0x3b,  0x0a,  0x07,  0xfe,  0xf7,  0x00,  0x38,  0x04,  0x5b,  0x30,  0x5c,  0xfe,  0x10,
-  0x58,  0xfe,  0x91,  0x58,  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0x02,  0x7a,  0x0a,  0x07,  0x1a,  0x18,
-  0xfe,  0xea,  0x08,  0x0a,  0x07,  0xfe,  0xf7,  0x00,  0x38,  0xfe,  0x3a,  0x55,  0xfe,  0x19,  0x81,  0x77,
-  0xfe,  0x10,  0x90,  0xfe,  0x92,  0x90,  0xfe,  0xd7,  0x10,  0x3f,  0x05,  0xc3,  0x18,  0xfe,  0xf6,  0x08,
-  0x11,  0xc3,  0xfe,  0x98,  0x80,  0xd7,  0x0c,  0xfe,  0x14,  0x13,  0x04,  0x3a,  0x30,  0x3b,  0x75,  0xfe,
-  0xf6,  0x08,  0xfe,  0x0c,  0x58,  0xfe,  0x8d,  0x58,  0x02,  0x7a,  0x2d,  0x4e,  0xfe,  0x19,  0x80,  0xfe,
-  0xf1,  0x10,  0x0a,  0x07,  0x0c,  0xa5,  0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,  0xfe,  0x8e,  0x10,  0xfe,
-  0x6c,  0x19,  0x9c,  0x3a,  0xfe,  0xed,  0x19,  0x9d,  0x3b,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0xfe,
-  0x6b,  0x18,  0x1b,  0xfe,  0x00,  0xff,  0x35,  0xfe,  0x74,  0x10,  0xc5,  0xfe,  0xd2,  0xf0,  0xfe,  0xd6,
-  0x0a,  0xfe,  0x76,  0x18,  0x1b,  0x19,  0xce,  0x04,  0xdf,  0x1b,  0x06,  0x84,  0x13,  0xfe,  0x16,  0x00,
-  0x02,  0x62,  0xfe,  0xd1,  0xf0,  0xfe,  0xe8,  0x0a,  0x17,  0x80,  0x01,  0x44,  0x13,  0xd6,  0xfe,  0x42,
-  0x10,  0xfe,  0xce,  0xf0,  0xfe,  0xee,  0x0a,  0xfe,  0x3c,  0x10,  0xfe,  0xcd,  0xf0,  0xfe,  0xfa,  0x0a,
-  0x13,  0xfe,  0x22,  0x00,  0x02,  0x62,  0xfe,  0xcb,  0xf0,  0xfe,  0x06,  0x0b,  0x13,  0xfe,  0x24,  0x00,
-  0x02,  0x62,  0xfe,  0xd0,  0xf0,  0xfe,  0x10,  0x0b,  0x13,  0x88,  0xd8,  0xfe,  0xcf,  0xf0,  0xfe,  0x1a,
-  0x0b,  0x13,  0x89,  0xd3,  0xfe,  0xcc,  0xf0,  0xfe,  0x2a,  0x0b,  0xfe,  0x84,  0x80,  0xd7,  0x1a,  0x4b,
-  0x13,  0xfe,  0x12,  0x00,  0x2b,  0x08,  0x80,  0x2e,  0xfe,  0x30,  0x0b,  0xfe,  0x9e,  0xf0,  0xfe,  0x44,
-  0x0b,  0x9b,  0x18,  0x32,  0x2b,  0x52,  0xfe,  0xed,  0x10,  0xa7,  0x28,  0xa9,  0x28,  0x2b,  0xf5,  0x2e,
-  0xfe,  0x50,  0x0b,  0x22,  0x32,  0x81,  0xfe,  0x6c,  0x0b,  0x6b,  0x92,  0xa7,  0xfe,  0xec,  0x07,  0xa9,
-  0xfe,  0xec,  0x07,  0x02,  0x28,  0x01,  0x4c,  0xfe,  0xdb,  0x10,  0x11,  0xfe,  0xe8,  0x00,  0xe3,  0xe4,
-  0x8c,  0x82,  0x6e,  0xfe,  0x89,  0xf0,  0x28,  0x23,  0x24,  0xfe,  0xe9,  0x09,  0x01,  0x0b,  0x82,  0x6e,
-  0x1f,  0x28,  0x23,  0x24,  0x91,  0x34,  0xfe,  0xa8,  0x0b,  0x22,  0x32,  0x02,  0xfe,  0x9c,  0x0b,  0x9b,
-  0x40,  0x13,  0xfe,  0x42,  0x00,  0x02,  0x62,  0xa0,  0x06,  0xfe,  0x81,  0x49,  0x96,  0x0a,  0x07,  0x0c,
-  0xfe,  0x5a,  0x13,  0x13,  0x00,  0x59,  0x0c,  0xfe,  0x6a,  0x12,  0x59,  0xfe,  0x28,  0x00,  0x27,  0xfe,
-  0xee,  0x0c,  0x0e,  0x79,  0x01,  0x15,  0x05,  0x00,  0x84,  0x36,  0xfe,  0x28,  0x00,  0x02,  0xfe,  0xee,
-  0x0c,  0x01,  0x97,  0x01,  0x9a,  0x0e,  0xc0,  0x01,  0xfe,  0x44,  0x0e,  0xb2,  0x08,  0x3d,  0x09,  0x99,
-  0x01,  0x46,  0x11,  0x47,  0x08,  0x1c,  0x09,  0x43,  0x01,  0x7b,  0x02,  0x26,  0x13,  0xfe,  0x44,  0x00,
-  0x59,  0x0c,  0xa5,  0x36,  0x0c,  0xfe,  0xc0,  0x10,  0x01,  0x96,  0x36,  0x0c,  0xfe,  0xb6,  0x10,  0x01,
-  0x96,  0xfe,  0x19,  0x82,  0xfe,  0x34,  0x46,  0xfe,  0x0a,  0x13,  0x36,  0x0c,  0x13,  0xfe,  0x43,  0x00,
-  0xfe,  0xa2,  0x10,  0x0a,  0x41,  0x0c,  0x38,  0x01,  0x97,  0x01,  0x9a,  0xb2,  0x08,  0x3d,  0x09,  0x99,
-  0x01,  0x46,  0x11,  0x47,  0x08,  0x1c,  0x09,  0x43,  0x01,  0x7b,  0x51,  0x0c,  0xb2,  0x1d,  0xca,  0x02,
-  0xfe,  0x48,  0x03,  0x0a,  0x07,  0x0c,  0xce,  0x36,  0x0c,  0x13,  0x00,  0xfe,  0x54,  0x10,  0x68,  0x07,
-  0x1e,  0xfe,  0x50,  0x12,  0x0a,  0x07,  0x1e,  0xfe,  0x48,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,
-  0xfe,  0xac,  0x0c,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0xb2,  0x0c,  0x0a,  0x41,  0x1e,  0x38,
-  0xfe,  0x95,  0x10,  0x13,  0xfe,  0x15,  0x00,  0xfe,  0x04,  0xe6,  0x0c,  0x77,  0xfe,  0x26,  0x10,  0x13,
-  0xfe,  0x13,  0x00,  0xd3,  0x13,  0xfe,  0x47,  0x00,  0xa6,  0x13,  0xfe,  0x41,  0x00,  0x9e,  0x13,  0xfe,
-  0x24,  0x00,  0x04,  0x78,  0x29,  0x27,  0xee,  0x77,  0xfe,  0x04,  0xe6,  0x1e,  0xfe,  0x9d,  0x41,  0xfe,
-  0x1c,  0x42,  0xb2,  0x01,  0xea,  0x02,  0x26,  0xd5,  0x17,  0x0c,  0x4a,  0xf4,  0xdd,  0x17,  0xfe,  0x31,
-  0x00,  0x4a,  0xbd,  0x01,  0xfe,  0x50,  0x0f,  0x02,  0xfe,  0xc2,  0x01,  0x1d,  0xfe,  0x06,  0xec,  0xf8,
-  0x86,  0x36,  0x37,  0xbf,  0x35,  0x1d,  0xfe,  0x06,  0xea,  0xf8,  0xfe,  0x47,  0x4b,  0x95,  0xfe,  0x75,
-  0x57,  0x04,  0x56,  0xfe,  0x98,  0x56,  0xfe,  0x28,  0x12,  0x0e,  0x79,  0xfe,  0xf4,  0x14,  0x4e,  0xe6,
-  0x0e,  0xc0,  0xfe,  0xea,  0x14,  0xfe,  0x49,  0x54,  0x8f,  0xfe,  0x62,  0x0d,  0x0e,  0x1c,  0xfe,  0xde,
-  0x14,  0xfe,  0x44,  0x48,  0x02,  0xfe,  0x48,  0x03,  0x0e,  0x56,  0xfe,  0xc8,  0x14,  0x86,  0x36,  0x37,
-  0xbf,  0x35,  0x1d,  0xfe,  0xce,  0x47,  0xfe,  0xbd,  0x13,  0x02,  0x26,  0x21,  0x2a,  0x05,  0x10,  0xfe,
-  0x78,  0x12,  0x2d,  0x16,  0x55,  0x16,  0xad,  0x21,  0x47,  0x4e,  0x4a,  0x47,  0x9b,  0xfe,  0x0c,  0x13,
-  0xfe,  0xbc,  0xf0,  0xfe,  0xfe,  0x0d,  0x08,  0x06,  0x16,  0x55,  0x01,  0xfe,  0x06,  0x16,  0x04,  0xfe,
-  0x38,  0x01,  0x30,  0xfe,  0x3a,  0x01,  0x75,  0xfe,  0x02,  0x0e,  0x04,  0xfe,  0x38,  0x01,  0x1b,  0xfe,
-  0xf0,  0xff,  0x0f,  0xfe,  0x60,  0x01,  0x04,  0xfe,  0x3a,  0x01,  0x0f,  0xfe,  0x62,  0x01,  0x20,  0x06,
-  0x16,  0x47,  0xfe,  0x04,  0xec,  0x2a,  0x08,  0x2a,  0x09,  0x3c,  0x1d,  0x01,  0x46,  0x7f,  0xfe,  0x05,
-  0xf6,  0xfe,  0x34,  0x01,  0x01,  0xfe,  0x76,  0x16,  0x11,  0x47,  0xca,  0x08,  0x06,  0x03,  0x2d,  0x03,
-  0x21,  0x55,  0xfe,  0xf7,  0x12,  0x21,  0xad,  0x6a,  0x16,  0xad,  0x05,  0x80,  0xfe,  0x93,  0x13,  0xfe,
-  0x24,  0x1c,  0x17,  0x19,  0x4a,  0xf4,  0xdd,  0xfe,  0xd9,  0x10,  0x93,  0xfe,  0x03,  0xdc,  0xfe,  0x73,
-  0x57,  0xfe,  0x80,  0x5d,  0x03,  0x93,  0xfe,  0x03,  0xdc,  0xfe,  0x5b,  0x57,  0xfe,  0x80,  0x5d,  0x03,
-  0xfe,  0x03,  0x57,  0x93,  0x2d,  0xfe,  0x00,  0xcc,  0x03,  0xfe,  0x03,  0x57,  0x93,  0x7d,  0x03,  0x01,
-  0xfe,  0xae,  0x16,  0x3f,  0x05,  0x47,  0xfe,  0x0a,  0x13,  0x08,  0x1c,  0x09,  0x43,  0xd3,  0x01,  0x97,
-  0x01,  0x9a,  0x08,  0x3d,  0x09,  0x99,  0x01,  0x46,  0x11,  0xfe,  0xe9,  0x00,  0x0a,  0x07,  0x89,  0xfe,
-  0x52,  0x13,  0x01,  0xfe,  0x38,  0x16,  0xfe,  0x1e,  0x1c,  0xfe,  0x14,  0x90,  0x0f,  0xfe,  0x64,  0x01,
-  0xfe,  0x16,  0x90,  0x0f,  0xfe,  0x66,  0x01,  0x0a,  0x07,  0x45,  0xe5,  0xfe,  0x03,  0x80,  0x52,  0x3e,
-  0x11,  0x76,  0x08,  0x2a,  0x09,  0x3c,  0x1d,  0x90,  0x01,  0x71,  0xfe,  0x62,  0x08,  0x6a,  0x3e,  0x11,
-  0x76,  0x08,  0x2a,  0x09,  0x3c,  0x1d,  0x90,  0x01,  0x71,  0x64,  0x2f,  0x11,  0x76,  0x08,  0x2a,  0x09,
-  0x3c,  0x1d,  0x90,  0x01,  0x7b,  0x03,  0xfe,  0x08,  0x1c,  0x04,  0xfe,  0xac,  0x00,  0xfe,  0x06,  0x58,
-  0x04,  0xfe,  0xae,  0x00,  0xfe,  0x07,  0x58,  0x04,  0xfe,  0xb0,  0x00,  0xfe,  0x08,  0x58,  0x04,  0xfe,
-  0xb2,  0x00,  0xfe,  0x09,  0x58,  0xfe,  0x0a,  0x1c,  0x20,  0x6c,  0x16,  0xf8,  0x2d,  0x0f,  0x53,  0x0f,
-  0x4d,  0x20,  0x10,  0x16,  0x2a,  0x16,  0x3c,  0x57,  0xa0,  0xd6,  0x08,  0x2a,  0x09,  0x3c,  0x1d,  0x01,
-  0x7b,  0x7f,  0x11,  0x76,  0xfe,  0x14,  0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0x2a,  0x0f,  0xd5,  0x8c,  0xfe,
-  0x14,  0x1c,  0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x03,  0x1d,  0xfe,  0x0c,  0x14,  0x86,  0xfe,  0x07,
-  0xe6,  0x37,  0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x03,  0x01,  0x96,  0x0e,  0x3d,  0x01,  0x15,  0x05,
-  0x10,  0x2c,  0x0e,  0x1c,  0x01,  0x15,  0x05,  0x10,  0xda,  0xfe,  0x44,  0x58,  0x3e,  0xfe,  0x01,  0xec,
-  0xbd,  0xfe,  0x9e,  0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x1e,  0x9f,  0x2f,  0x01,  0xea,
-  0xfe,  0xc9,  0x10,  0x03,  0x2b,  0x82,  0x6e,  0x23,  0x24,  0xb3,  0x05,  0x1e,  0xfe,  0x48,  0x12,  0x05,
-  0x0c,  0xfe,  0x4c,  0x12,  0x05,  0x19,  0xfe,  0x30,  0x12,  0x05,  0xcc,  0x18,  0xfe,  0xf4,  0x10,  0x05,
-  0xfe,  0x23,  0x00,  0x18,  0xfe,  0x00,  0x11,  0x05,  0x06,  0x18,  0xfe,  0x5e,  0x11,  0x05,  0x1a,  0xfe,
-  0x12,  0x12,  0x05,  0x00,  0x18,  0x28,  0x17,  0xcc,  0x01,  0x44,  0xc6,  0x39,  0x01,  0x0b,  0x81,  0x4c,
-  0x03,  0x39,  0x11,  0xfe,  0xcc,  0x00,  0x02,  0x26,  0x39,  0x3f,  0x05,  0xc3,  0xfe,  0xe3,  0x13,  0x65,
-  0x3a,  0x31,  0x3b,  0x75,  0xfe,  0xb2,  0x10,  0x0a,  0x07,  0x70,  0xfe,  0x72,  0x12,  0xa1,  0x42,  0x69,
-  0x58,  0xe8,  0xfe,  0xe5,  0x55,  0x8f,  0xfe,  0x7c,  0x10,  0x21,  0x61,  0xfe,  0x26,  0x13,  0x04,  0xae,
-  0x30,  0x8d,  0x75,  0xfe,  0xd2,  0x0c,  0x0f,  0x5d,  0x12,  0x5e,  0x2d,  0x0f,  0xae,  0x0f,  0x8d,  0x01,
-  0xc1,  0x20,  0x6c,  0x52,  0x16,  0x61,  0x01,  0xfe,  0xde,  0x12,  0xa1,  0x42,  0x69,  0x58,  0xfe,  0x04,
-  0x55,  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,  0x42,  0xfe,  0x05,  0xfa,  0x58,  0xfe,  0x91,  0x10,  0x04,
-  0x5f,  0x30,  0x60,  0xfe,  0x40,  0x56,  0xfe,  0xe1,  0x56,  0x0f,  0x5f,  0x12,  0x60,  0xa8,  0xa1,  0x42,
-  0x69,  0x58,  0xe8,  0xfe,  0xe5,  0x55,  0x04,  0x5b,  0x30,  0x5c,  0xfe,  0x00,  0x56,  0xfe,  0xa1,  0x56,
-  0x0f,  0x5b,  0x12,  0x5c,  0x0a,  0x07,  0x70,  0xfe,  0x1e,  0x12,  0x21,  0x61,  0xfe,  0x1f,  0x40,  0x04,
-  0x5d,  0x30,  0x5e,  0xfe,  0x2c,  0x50,  0xfe,  0xae,  0x50,  0x04,  0x5f,  0x30,  0x60,  0xfe,  0x34,  0x50,
-  0xfe,  0xb6,  0x50,  0x04,  0x5b,  0x30,  0x5c,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x04,  0x3a,  0x30,
-  0x3b,  0xfe,  0x28,  0x50,  0xfe,  0xaa,  0x50,  0x02,  0x98,  0x20,  0x06,  0x16,  0xf3,  0x02,  0x7c,  0x39,
-  0x01,  0x0b,  0x1f,  0x4f,  0x23,  0x24,  0xb3,  0x05,  0x06,  0x27,  0x4f,  0x3f,  0x05,  0xc3,  0x27,  0x7c,
-  0x01,  0xfa,  0x1b,  0x50,  0x18,  0x4f,  0x0a,  0x07,  0x0c,  0xdc,  0x65,  0x3a,  0x31,  0x3b,  0xfe,  0x0a,
-  0x55,  0x35,  0xfe,  0x8b,  0x55,  0x9c,  0x3a,  0x9d,  0x3b,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0x02,
-  0x7c,  0xfe,  0x19,  0x81,  0xfe,  0x0a,  0x45,  0xfe,  0x19,  0x41,  0x02,  0x7c,  0x39,  0x01,  0x0b,  0x1f,
-  0xfe,  0xf6,  0x0f,  0x23,  0x24,  0xfe,  0xe9,  0x09,  0x59,  0x19,  0xfe,  0x94,  0x12,  0x59,  0x0c,  0x4b,
-  0x02,  0x4f,  0x2e,  0xfe,  0x7e,  0x11,  0x22,  0x32,  0x1f,  0xfe,  0xf6,  0x0f,  0x23,  0x24,  0x91,  0x05,
-  0x19,  0x27,  0x4f,  0x01,  0x0b,  0x1f,  0xfe,  0xf6,  0x0f,  0x23,  0x24,  0xfe,  0xe8,  0x09,  0x57,  0x04,
-  0xfe,  0x9c,  0x00,  0x29,  0x35,  0xfe,  0xbb,  0x45,  0x59,  0x00,  0x40,  0x36,  0x06,  0xa0,  0x50,  0xfe,
-  0xc0,  0x14,  0xfe,  0xf8,  0x14,  0xac,  0x3f,  0x05,  0xc2,  0xfe,  0x16,  0x13,  0x04,  0xf6,  0x29,  0xce,
-  0x04,  0x4d,  0x29,  0x35,  0x5a,  0x02,  0x7c,  0xfe,  0xc0,  0x5d,  0xfe,  0xe4,  0x14,  0xfe,  0x03,  0x17,
-  0x04,  0x53,  0xbc,  0x0f,  0x53,  0x5a,  0x39,  0x01,  0x0b,  0x25,  0x98,  0x01,  0xfe,  0x26,  0x14,  0x02,
-  0x98,  0x2e,  0x40,  0x22,  0x32,  0x1f,  0x4f,  0x23,  0x24,  0x91,  0x05,  0x06,  0x27,  0x4f,  0xfe,  0xf6,
-  0x14,  0xfe,  0x42,  0x58,  0xfe,  0x70,  0x14,  0xfe,  0x92,  0x14,  0xac,  0xfe,  0x4a,  0xf4,  0x0c,  0x18,
-  0x4f,  0xfe,  0x4a,  0xf4,  0x06,  0xd1,  0x3f,  0x05,  0xc2,  0xc9,  0x02,  0x7c,  0x04,  0x4d,  0xbc,  0x0f,
-  0x4d,  0x5a,  0x39,  0x01,  0x0b,  0x25,  0x98,  0x01,  0xfe,  0x54,  0x14,  0x02,  0x98,  0x25,  0xfe,  0x70,
-  0x12,  0x73,  0xf1,  0x73,  0x03,  0x34,  0xfe,  0x6c,  0x12,  0x6b,  0xfe,  0x6c,  0x12,  0x5a,  0x39,  0x01,
-  0x0b,  0xfe,  0xe3,  0x10,  0x08,  0x63,  0xff,  0x02,  0x00,  0x57,  0x66,  0x7e,  0x1b,  0xfe,  0xff,  0x7f,
-  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x08,  0x63,  0xff,  0x02,  0x00,  0x57,  0x66,  0x7e,  0x1b,
-  0x50,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x08,  0x63,  0xff,  0x02,  0x00,  0x57,  0x66,  0x7e,
-  0x03,  0x08,  0x63,  0xff,  0x02,  0x00,  0x57,  0x66,  0x7e,  0xfe,  0x0b,  0x58,  0x03,  0x0e,  0x53,  0x01,
-  0x8b,  0x0e,  0x4d,  0x01,  0x8b,  0x03,  0xc8,  0x1b,  0x10,  0xff,  0x03,  0x00,  0x54,  0xfe,  0x00,  0xf4,
-  0x1a,  0x66,  0xfe,  0x00,  0x7d,  0xfe,  0x01,  0x7d,  0xfe,  0x02,  0x7d,  0xfe,  0x03,  0x7c,  0x64,  0x2f,
-  0x0f,  0x5b,  0x12,  0x5c,  0x9c,  0x5f,  0x9d,  0x60,  0x03,  0xfe,  0x62,  0x18,  0xfe,  0x82,  0x5a,  0xfe,
-  0xe1,  0x1a,  0xb6,  0xfe,  0x02,  0x58,  0x03,  0x01,  0xfe,  0x9e,  0x18,  0xfe,  0x42,  0x48,  0x77,  0x57,
-  0x95,  0x01,  0x0b,  0x1f,  0xfe,  0x1e,  0x14,  0x23,  0x24,  0xfe,  0xe9,  0x09,  0xfe,  0xc1,  0x59,  0x01,
-  0x0b,  0x1f,  0xfe,  0x1e,  0x14,  0x23,  0x24,  0xfe,  0xe8,  0x0a,  0x04,  0xf6,  0x29,  0xfe,  0xc4,  0x12,
-  0x2d,  0xb1,  0x1e,  0xdc,  0x59,  0xcd,  0x74,  0xfe,  0x6c,  0x13,  0x4b,  0x08,  0x06,  0x09,  0xcd,  0xa0,
-  0xfe,  0x00,  0x10,  0xfe,  0x78,  0x10,  0xff,  0x02,  0x83,  0x55,  0xa6,  0xff,  0x02,  0x83,  0x55,  0xb1,
-  0x19,  0xfe,  0x12,  0x13,  0x72,  0xfe,  0x30,  0x00,  0x8f,  0xfe,  0xc6,  0x13,  0x09,  0x85,  0x08,  0x06,
-  0xfe,  0x56,  0x10,  0xb1,  0x0c,  0xfe,  0x16,  0x13,  0x72,  0xfe,  0x64,  0x00,  0x8f,  0xfe,  0xc6,  0x13,
-  0x0e,  0xfe,  0x64,  0x00,  0x09,  0x88,  0x08,  0x06,  0xfe,  0x28,  0x10,  0xb1,  0x06,  0xfe,  0x60,  0x13,
-  0x72,  0xfe,  0xc8,  0x00,  0x8f,  0xfe,  0xc6,  0x13,  0x0e,  0xfe,  0xc8,  0x00,  0x09,  0x55,  0x08,  0x06,
-  0xa8,  0x72,  0xfe,  0x90,  0x01,  0xed,  0xfe,  0xd2,  0x13,  0x95,  0xaa,  0xfe,  0x43,  0xf4,  0xad,  0xfe,
-  0x56,  0xf0,  0xfe,  0xe4,  0x13,  0xfe,  0x04,  0xf4,  0x63,  0xfe,  0x43,  0xf4,  0x88,  0xfe,  0xf3,  0x10,
-  0xb0,  0x01,  0xfe,  0xae,  0x12,  0x1b,  0x50,  0xd4,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x6c,  0xed,
-  0xfe,  0x18,  0x14,  0xa3,  0x6c,  0xfe,  0x14,  0x10,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x1a,  0xed,
-  0xfe,  0x18,  0x14,  0xa3,  0x1a,  0x9e,  0x57,  0x95,  0x08,  0x06,  0xfe,  0xb4,  0x56,  0xfe,  0xc3,  0x58,
-  0x03,  0x57,  0x08,  0x0c,  0x03,  0x14,  0x06,  0x01,  0x0b,  0x25,  0xec,  0x14,  0x0c,  0x01,  0x0b,  0x25,
-  0xec,  0x14,  0x19,  0x01,  0x0b,  0x25,  0xec,  0x73,  0xfe,  0x89,  0x49,  0x01,  0x0b,  0x03,  0x14,  0x06,
-  0x01,  0x0b,  0x25,  0xb7,  0x14,  0x19,  0x01,  0x0b,  0x25,  0xb7,  0x14,  0x06,  0x01,  0x0b,  0x25,  0xb7,
-  0xfe,  0x89,  0x49,  0x01,  0x0b,  0x25,  0xb7,  0x73,  0xfe,  0x89,  0x4a,  0x01,  0x0b,  0x03,  0x57,  0x03,
-  0x21,  0xe0,  0x05,  0x06,  0xfe,  0x44,  0x13,  0xaf,  0x16,  0xe0,  0xfe,  0x49,  0xf4,  0x00,  0x4b,  0x73,
-  0xc6,  0x5a,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,  0xf1,  0x01,  0x0b,  0x3f,  0x05,  0xfe,  0xe3,  0x00,
-  0xfe,  0x20,  0x13,  0x1f,  0xfe,  0xd6,  0x14,  0x2d,  0x16,  0xf3,  0x01,  0x4c,  0x21,  0xf3,  0x05,  0x06,
-  0x40,  0x0a,  0x41,  0x06,  0x38,  0x03,  0x0f,  0x54,  0x12,  0x8a,  0xfe,  0x43,  0x58,  0x01,  0x15,  0x05,
-  0x10,  0xfe,  0x1e,  0x12,  0x48,  0xe7,  0x8e,  0x01,  0x2c,  0xfe,  0x90,  0x4d,  0xde,  0x10,  0xfe,  0xc5,
-  0x59,  0x01,  0x2c,  0xfe,  0x8d,  0x56,  0xb6,  0x48,  0x03,  0x48,  0x31,  0x8a,  0x01,  0x15,  0x48,  0x8e,
-  0x01,  0x2c,  0xe2,  0x10,  0xde,  0x10,  0x31,  0x54,  0x72,  0x1c,  0x84,  0x0e,  0x56,  0x01,  0xab,  0x03,
-  0x0f,  0x54,  0x12,  0x8a,  0xfe,  0xc3,  0x58,  0x01,  0x15,  0x05,  0x10,  0xfe,  0x1a,  0x12,  0x48,  0xe7,
-  0x8e,  0x01,  0x2c,  0xe2,  0x10,  0xfe,  0x80,  0x4d,  0xfe,  0xc5,  0x59,  0x01,  0x2c,  0x48,  0x03,  0x48,
-  0x31,  0x54,  0x01,  0x15,  0x48,  0x8e,  0x01,  0x2c,  0xe2,  0x10,  0xde,  0x10,  0x31,  0x54,  0x72,  0x1c,
-  0x84,  0x0e,  0x56,  0x01,  0xab,  0x03,  0x0f,  0x54,  0x12,  0x8a,  0xfe,  0x43,  0x58,  0x01,  0x15,  0xfe,
-  0x42,  0x48,  0x8e,  0x01,  0x2c,  0xfe,  0xc0,  0x5a,  0xb0,  0xfe,  0x00,  0xcd,  0xfe,  0x01,  0xcc,  0xfe,
-  0x4a,  0x46,  0xdc,  0x93,  0x7d,  0x05,  0x10,  0xfe,  0x2e,  0x13,  0x69,  0x54,  0xfe,  0x4d,  0xf4,  0x1c,
-  0xfe,  0x1c,  0x13,  0x0e,  0x56,  0x01,  0x8b,  0xaa,  0xfe,  0x40,  0x4c,  0xfe,  0xc5,  0x58,  0x01,  0x2c,
-  0xfe,  0x00,  0x07,  0x7d,  0x05,  0x10,  0x84,  0x69,  0x8a,  0xfe,  0x05,  0x57,  0xfe,  0x08,  0x10,  0xfe,
-  0x45,  0x58,  0x01,  0x2c,  0xfe,  0x8d,  0x56,  0xb6,  0xfe,  0x80,  0x4c,  0xfe,  0x05,  0x17,  0x03,  0x09,
-  0x10,  0x6f,  0x67,  0xfe,  0x60,  0x01,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x24,  0x1c,  0xdb,
-  0x37,  0x94,  0xfe,  0x1a,  0x16,  0x01,  0xfe,  0x28,  0x17,  0xfe,  0x0c,  0x13,  0x87,  0x37,  0x67,  0xfe,
-  0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x03,  0xba,  0x27,  0xfe,  0x0a,  0x16,  0xfe,  0xe2,  0x10,  0x09,  0x10,
-  0x6f,  0x04,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x1a,  0xfe,  0x18,  0x58,  0x04,  0xfe,  0x66,  0x01,
-  0xfe,  0x19,  0x58,  0x87,  0x1a,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x06,  0xfe,  0x3c,  0x50,  0x67,
-  0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x1a,  0x94,  0xfe,  0x64,  0x16,  0xfe,  0xbe,
-  0x14,  0x35,  0x03,  0xba,  0x27,  0xfe,  0x3c,  0x16,  0xfe,  0xa4,  0x10,  0x09,  0x10,  0x6f,  0xb6,  0xfe,
-  0x18,  0xdf,  0xfe,  0x19,  0xdf,  0xdb,  0x42,  0x94,  0xfe,  0x86,  0x16,  0xfe,  0x9c,  0x14,  0xfe,  0x18,
-  0x13,  0x87,  0x42,  0x67,  0x1e,  0xfe,  0xaf,  0x19,  0xfe,  0x98,  0xe7,  0x00,  0xa2,  0x07,  0xfe,  0x7f,
-  0x00,  0xfe,  0x05,  0x40,  0x03,  0xba,  0x27,  0xfe,  0x7a,  0x16,  0xfe,  0x6c,  0x10,  0x09,  0x10,  0x6f,
-  0xfe,  0x30,  0xbc,  0xfe,  0xb2,  0xbc,  0x87,  0xd9,  0x67,  0x1e,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,
-  0xd9,  0x94,  0xfe,  0xc6,  0x16,  0xfe,  0x5c,  0x14,  0x35,  0x03,  0xba,  0x27,  0xfe,  0xb2,  0x16,  0xfe,
-  0x42,  0x10,  0xfe,  0x02,  0xf6,  0x10,  0x6f,  0xfe,  0x18,  0xfe,  0x5d,  0xfe,  0x19,  0xfe,  0x5e,  0xc8,
-  0xdb,  0x45,  0x94,  0xfe,  0xec,  0x16,  0xfe,  0x36,  0x14,  0xfe,  0x1c,  0x13,  0x87,  0x45,  0x4e,  0xfe,
-  0x83,  0x58,  0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x10,  0xfe,  0x81,  0xe7,  0x10,  0x11,  0xfe,  0xdd,
-  0x00,  0x64,  0x2f,  0x03,  0x64,  0x2f,  0xfe,  0x12,  0x45,  0x27,  0xfe,  0xdc,  0x16,  0x17,  0x06,  0x4a,
-  0xf4,  0xdd,  0x02,  0x26,  0xfe,  0x39,  0xf0,  0xfe,  0x30,  0x17,  0x2d,  0x03,  0xfe,  0x7e,  0x18,  0x1b,
-  0x19,  0x83,  0x08,  0x0d,  0x03,  0x6f,  0x04,  0xdf,  0x1b,  0x06,  0xfe,  0xef,  0x12,  0xfe,  0xe1,  0x10,
-  0x1d,  0x0e,  0x1c,  0x01,  0x15,  0x05,  0x10,  0x40,  0x3e,  0xfe,  0x78,  0x14,  0xfe,  0x34,  0x12,  0x50,
-  0x86,  0x36,  0x37,  0xbf,  0xfe,  0xe9,  0x13,  0x1d,  0x0e,  0x3d,  0x01,  0x15,  0x05,  0x10,  0x40,  0x3e,
-  0xfe,  0x56,  0x14,  0xe1,  0x50,  0x86,  0x36,  0x37,  0xbf,  0xfe,  0xe9,  0x13,  0x09,  0x0c,  0x03,  0xfe,
-  0x9c,  0xe7,  0x0c,  0x13,  0xfe,  0x15,  0x00,  0x90,  0x9f,  0x2f,  0x01,  0xea,  0x09,  0x06,  0x03,  0x0a,
-  0x41,  0x37,  0x38,  0x08,  0x3d,  0x09,  0x99,  0x01,  0x46,  0x11,  0x47,  0x08,  0x1c,  0x09,  0x43,  0x01,
-  0x7b,  0x09,  0x06,  0x03,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,  0x65,  0xf7,  0x31,  0x76,  0xfe,  0x48,
-  0x55,  0x35,  0xfe,  0xc9,  0x55,  0x03,  0x21,  0xbe,  0x52,  0x16,  0xbe,  0x03,  0x0e,  0xc0,  0x01,  0x15,
-  0xe6,  0x0e,  0x79,  0x01,  0x15,  0xfe,  0x49,  0x44,  0x27,  0xfe,  0x26,  0x18,  0x0e,  0x1c,  0x01,  0x15,
-  0x05,  0x10,  0x40,  0x0e,  0x56,  0x01,  0xab,  0x0e,  0x79,  0x01,  0x15,  0x52,  0x7d,  0x03,  0xfe,  0x40,
-  0x5e,  0xfe,  0xe2,  0x08,  0xfe,  0xc0,  0x4c,  0x21,  0x3c,  0x05,  0x10,  0xfe,  0x52,  0x12,  0x3e,  0x05,
-  0x00,  0xfe,  0x18,  0x12,  0xfe,  0xe1,  0x18,  0xfe,  0x19,  0xf4,  0xfe,  0x7f,  0x00,  0xd4,  0xfe,  0xe2,
-  0x08,  0x52,  0x3e,  0x3f,  0x05,  0x76,  0xa5,  0xfe,  0x82,  0x48,  0xfe,  0x01,  0x80,  0xfe,  0xd7,  0x10,
-  0xfe,  0xc4,  0x48,  0x08,  0x2a,  0x09,  0x3c,  0xfe,  0x40,  0x5f,  0x1d,  0x01,  0x46,  0x11,  0xfe,  0xdd,
-  0x00,  0xfe,  0x14,  0x46,  0x08,  0x2a,  0x09,  0x3c,  0x01,  0x46,  0x11,  0xfe,  0xdd,  0x00,  0xfe,  0x40,
-  0x4a,  0x6a,  0xfe,  0x06,  0x17,  0xfe,  0x01,  0x07,  0xfe,  0x82,  0x48,  0xfe,  0x04,  0x17,  0x03,  0xeb,
-  0x19,  0x74,  0xfe,  0xae,  0x18,  0x04,  0xfe,  0x90,  0x00,  0xfe,  0x3a,  0x45,  0xfe,  0x2c,  0x10,  0xeb,
-  0xcc,  0x74,  0xfe,  0xc0,  0x18,  0x04,  0xfe,  0x92,  0x00,  0xc7,  0x1e,  0xd8,  0xeb,  0xfe,  0x0b,  0x00,
-  0x74,  0xfe,  0xd2,  0x18,  0x04,  0xfe,  0x94,  0x00,  0xc7,  0x1a,  0xfe,  0x08,  0x10,  0x04,  0xfe,  0x96,
-  0x00,  0xc7,  0x85,  0xfe,  0x4e,  0x45,  0xd1,  0xfe,  0x0a,  0x45,  0xff,  0x04,  0x68,  0x54,  0xfe,  0xf1,
-  0x10,  0x1b,  0x6c,  0x03,  0x05,  0x80,  0xfe,  0x5a,  0xf0,  0xfe,  0xfe,  0x18,  0x20,  0xfe,  0x09,  0x00,
-  0xfe,  0x34,  0x10,  0x05,  0x1e,  0xfe,  0x5a,  0xf0,  0xfe,  0x0c,  0x19,  0x20,  0xcd,  0xfe,  0x26,  0x10,
-  0x05,  0x19,  0x83,  0x20,  0x85,  0xd8,  0x05,  0x0c,  0x83,  0x20,  0x88,  0xfe,  0x0e,  0x10,  0x05,  0x06,
-  0x83,  0x20,  0x55,  0xc6,  0xaf,  0x03,  0x17,  0xfe,  0x09,  0x00,  0x01,  0x44,  0x2e,  0xfe,  0x3c,  0x19,
-  0x04,  0x6e,  0xb0,  0x03,  0x22,  0xfe,  0x54,  0x19,  0xfe,  0x14,  0xf0,  0x0b,  0x2e,  0xfe,  0x50,  0x19,
-  0x03,  0xff,  0x15,  0x00,  0x00,
+  0x00,  0x00,  0x00,  0xf2,  0x00,  0xf0,  0x00,  0x16,  0x18,  0xe4,  0x00,  0xfc,  0x01,  0x00,  0x48,  0xe4,
+  0xbe,  0x18,  0x18,  0x80,  0x03,  0xf6,  0x02,  0x00,  0x00,  0xfa,  0xff,  0xff,  0x28,  0x0e,  0x9e,  0xe7,
+  0xff,  0x00,  0x82,  0xe7,  0x00,  0xea,  0x00,  0xf6,  0x01,  0xe6,  0x09,  0xe7,  0x55,  0xf0,  0x01,  0xf6,
+  0x01,  0xfa,  0x08,  0x00,  0x03,  0x00,  0x04,  0x00,  0x18,  0xf4,  0x10,  0x00,  0x00,  0xec,  0x85,  0xf0,
+  0xbc,  0x00,  0xd5,  0xf0,  0x8e,  0x0c,  0x38,  0x54,  0x00,  0xe6,  0x1e,  0xf0,  0x86,  0xf0,  0xb4,  0x00,
+  0x98,  0x57,  0xd0,  0x01,  0x0c,  0x1c,  0x3e,  0x1c,  0x0c,  0x00,  0xbb,  0x00,  0xaa,  0x18,  0x02,  0x80,
+  0x32,  0xf0,  0x01,  0xfc,  0x88,  0x0c,  0xc6,  0x12,  0x02,  0x13,  0x18,  0x40,  0x00,  0x57,  0x01,  0xea,
+  0x3c,  0x00,  0x6c,  0x01,  0x6e,  0x01,  0x04,  0x12,  0x3e,  0x57,  0x00,  0x80,  0x03,  0xe6,  0xb6,  0x00,
+  0xc0,  0x00,  0x01,  0x01,  0x3e,  0x01,  0xda,  0x0f,  0x22,  0x10,  0x08,  0x12,  0x02,  0x4a,  0xb9,  0x54,
+  0x03,  0x58,  0x1b,  0x80,  0x30,  0xe4,  0x4b,  0xe4,  0x20,  0x00,  0x32,  0x00,  0x3e,  0x00,  0x80,  0x00,
+  0x24,  0x01,  0x3c,  0x01,  0x68,  0x01,  0x6a,  0x01,  0x70,  0x01,  0x72,  0x01,  0x74,  0x01,  0x76,  0x01,
+  0x78,  0x01,  0x62,  0x0a,  0x92,  0x0c,  0x2c,  0x10,  0x2e,  0x10,  0x06,  0x13,  0x4c,  0x1c,  0xbb,  0x55,
+  0x3c,  0x56,  0x04,  0x80,  0x4a,  0xe4,  0x02,  0xee,  0x5b,  0xf0,  0xb1,  0xf0,  0x03,  0xf7,  0x06,  0xf7,
+  0x03,  0xfc,  0x0f,  0x00,  0x40,  0x00,  0xbe,  0x00,  0x00,  0x01,  0xb0,  0x08,  0x30,  0x13,  0x64,  0x15,
+  0x32,  0x1c,  0x38,  0x1c,  0x4e,  0x1c,  0x10,  0x44,  0x02,  0x48,  0x00,  0x4c,  0x04,  0xea,  0x5d,  0xf0,
+  0x04,  0xf6,  0x02,  0xfc,  0x05,  0x00,  0x34,  0x00,  0x36,  0x00,  0x98,  0x00,  0xcc,  0x00,  0x20,  0x01,
+  0x4e,  0x01,  0x4e,  0x0b,  0x1e,  0x0e,  0x0c,  0x10,  0x0a,  0x12,  0x04,  0x13,  0x40,  0x13,  0x30,  0x1c,
+  0x00,  0x4e,  0xbd,  0x56,  0x06,  0x83,  0x00,  0xdc,  0x05,  0xf0,  0x09,  0xf0,  0x59,  0xf0,  0xa7,  0xf0,
+  0xb8,  0xf0,  0x0e,  0xf7,  0x06,  0x00,  0x19,  0x00,  0x33,  0x00,  0x9b,  0x00,  0xa4,  0x00,  0xb5,  0x00,
+  0xba,  0x00,  0xd0,  0x00,  0xe1,  0x00,  0xe7,  0x00,  0xde,  0x03,  0x56,  0x0a,  0x14,  0x0e,  0x02,  0x10,
+  0x04,  0x10,  0x0a,  0x10,  0x36,  0x10,  0x0a,  0x13,  0x12,  0x13,  0x52,  0x13,  0x10,  0x15,  0x14,  0x15,
+  0xac,  0x16,  0x20,  0x1c,  0x34,  0x1c,  0x36,  0x1c,  0x08,  0x44,  0x38,  0x44,  0x91,  0x44,  0x0a,  0x45,
+  0x48,  0x46,  0x01,  0x48,  0x68,  0x54,  0x83,  0x55,  0xb0,  0x57,  0x01,  0x58,  0x83,  0x59,  0x05,  0xe6,
+  0x0b,  0xf0,  0x0c,  0xf0,  0x5c,  0xf0,  0x4b,  0xf4,  0x04,  0xf8,  0x05,  0xf8,  0x02,  0xfa,  0x03,  0xfa,
+  0x04,  0xfc,  0x05,  0xfc,  0x07,  0x00,  0x0a,  0x00,  0x0d,  0x00,  0x1c,  0x00,  0x9e,  0x00,  0xa8,  0x00,
+  0xaa,  0x00,  0xb9,  0x00,  0xe0,  0x00,  0x22,  0x01,  0x26,  0x01,  0x79,  0x01,  0x7a,  0x01,  0xc0,  0x01,
+  0xc2,  0x01,  0x7c,  0x02,  0x5a,  0x03,  0xea,  0x04,  0xe8,  0x07,  0x68,  0x08,  0x69,  0x08,  0xba,  0x08,
+  0xe9,  0x09,  0x06,  0x0b,  0x3a,  0x0e,  0x00,  0x10,  0x1a,  0x10,  0xed,  0x10,  0xf1,  0x10,  0x06,  0x12,
+  0x0c,  0x13,  0x16,  0x13,  0x1e,  0x13,  0x82,  0x13,  0x42,  0x14,  0xd6,  0x14,  0x8a,  0x15,  0xc6,  0x17,
+  0xd2,  0x17,  0x6b,  0x18,  0x12,  0x1c,  0x46,  0x1c,  0x9c,  0x32,  0x00,  0x40,  0x0e,  0x47,  0x48,  0x47,
+  0x41,  0x48,  0x89,  0x48,  0x80,  0x4c,  0x00,  0x54,  0x44,  0x55,  0xe5,  0x55,  0x14,  0x56,  0x77,  0x57,
+  0xbf,  0x57,  0x40,  0x5c,  0x06,  0x80,  0x08,  0x90,  0x03,  0xa1,  0xfe,  0x9c,  0xf0,  0x29,  0x02,  0xfe,
+  0xb8,  0x0c,  0xff,  0x10,  0x00,  0x00,  0xd0,  0xfe,  0xcc,  0x18,  0x00,  0xcf,  0xfe,  0x80,  0x01,  0xff,
+  0x03,  0x00,  0x00,  0xfe,  0x93,  0x15,  0xfe,  0x0f,  0x05,  0xff,  0x38,  0x00,  0x00,  0xfe,  0x57,  0x24,
+  0x00,  0xfe,  0x48,  0x00,  0x4f,  0xff,  0x04,  0x00,  0x00,  0x10,  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,
+  0x01,  0x01,  0xff,  0x08,  0xff,  0xff,  0xff,  0x27,  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,  0xff,  0x0f,
+  0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xcf,
+  0x2a,  0x67,  0x0b,  0x01,  0xfe,  0xce,  0x0e,  0xfe,  0x04,  0xf7,  0xcf,  0x67,  0x0b,  0x3c,  0x2a,  0xfe,
+  0x3d,  0xf0,  0xfe,  0x02,  0x02,  0xfe,  0x20,  0xf0,  0x9c,  0xfe,  0x91,  0xf0,  0xfe,  0xf0,  0x01,  0xfe,
+  0x90,  0xf0,  0xfe,  0xf0,  0x01,  0xfe,  0x8f,  0xf0,  0x9c,  0x05,  0x51,  0x3b,  0x02,  0xfe,  0xd4,  0x0c,
+  0x01,  0xfe,  0x44,  0x0d,  0xfe,  0xdd,  0x12,  0xfe,  0xfc,  0x10,  0xfe,  0x28,  0x1c,  0x05,  0xfe,  0xa6,
+  0x00,  0xfe,  0xd3,  0x12,  0x47,  0x18,  0xfe,  0xa6,  0x00,  0xb5,  0xfe,  0x48,  0xf0,  0xfe,  0x86,  0x02,
+  0xfe,  0x49,  0xf0,  0xfe,  0xa0,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xbe,  0x02,  0xfe,  0x46,  0xf0,  0xfe,
+  0x50,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x56,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x44,  0x02,  0xfe,  0x44,
+  0xf0,  0xfe,  0x48,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x4c,  0x02,  0x17,  0x0b,  0xa0,  0x17,  0x06,  0x18,
+  0x96,  0x02,  0x29,  0xfe,  0x00,  0x1c,  0xde,  0xfe,  0x02,  0x1c,  0xdd,  0xfe,  0x1e,  0x1c,  0xfe,  0xe9,
+  0x10,  0x01,  0xfe,  0x20,  0x17,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xc7,  0x0a,  0x6b,  0x01,  0x9e,
+  0x02,  0x29,  0x14,  0x4d,  0x37,  0x97,  0x01,  0xfe,  0x64,  0x0f,  0x0a,  0x6b,  0x01,  0x82,  0xfe,  0xbd,
+  0x10,  0x0a,  0x6b,  0x01,  0x82,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x17,  0x06,
+  0x18,  0x96,  0x2a,  0x25,  0x29,  0xfe,  0x3d,  0xf0,  0xfe,  0x02,  0x02,  0x21,  0xfe,  0x94,  0x02,  0xfe,
+  0x5a,  0x1c,  0xea,  0xfe,  0x14,  0x1c,  0x14,  0xfe,  0x30,  0x00,  0x37,  0x97,  0x01,  0xfe,  0x54,  0x0f,
+  0x17,  0x06,  0x18,  0x96,  0x02,  0xd0,  0x1e,  0x20,  0x07,  0x10,  0x34,  0xfe,  0x69,  0x10,  0x17,  0x06,
+  0x18,  0x96,  0xfe,  0x04,  0xec,  0x20,  0x46,  0x3d,  0x12,  0x20,  0xfe,  0x05,  0xf6,  0xc7,  0x01,  0xfe,
+  0x52,  0x16,  0x09,  0x4a,  0x4c,  0x35,  0x11,  0x2d,  0x3c,  0x8a,  0x01,  0xe6,  0x02,  0x29,  0x0a,  0x40,
+  0x01,  0x0e,  0x07,  0x00,  0x5d,  0x01,  0x6f,  0xfe,  0x18,  0x10,  0xfe,  0x41,  0x58,  0x0a,  0x99,  0x01,
+  0x0e,  0xfe,  0xc8,  0x54,  0x64,  0xfe,  0x0c,  0x03,  0x01,  0xe6,  0x02,  0x29,  0x2a,  0x46,  0xfe,  0x02,
+  0xe8,  0x27,  0xf8,  0xfe,  0x9e,  0x43,  0xf7,  0xfe,  0x27,  0xf0,  0xfe,  0xdc,  0x01,  0xfe,  0x07,  0x4b,
+  0xfe,  0x20,  0xf0,  0x9c,  0xfe,  0x40,  0x1c,  0x25,  0xd2,  0xfe,  0x26,  0xf0,  0xfe,  0x56,  0x03,  0xfe,
+  0xa0,  0xf0,  0xfe,  0x44,  0x03,  0xfe,  0x11,  0xf0,  0x9c,  0xfe,  0xef,  0x10,  0xfe,  0x9f,  0xf0,  0xfe,
+  0x64,  0x03,  0xeb,  0x0f,  0xfe,  0x11,  0x00,  0x02,  0x5a,  0x2a,  0xfe,  0x48,  0x1c,  0xeb,  0x09,  0x04,
+  0x1d,  0xfe,  0x18,  0x13,  0x23,  0x1e,  0x98,  0xac,  0x12,  0x98,  0x0a,  0x40,  0x01,  0x0e,  0xac,  0x75,
+  0x01,  0xfe,  0xbc,  0x15,  0x11,  0xca,  0x25,  0xd2,  0xfe,  0x01,  0xf0,  0xd2,  0xfe,  0x82,  0xf0,  0xfe,
+  0x92,  0x03,  0xec,  0x11,  0xfe,  0xe4,  0x00,  0x65,  0xfe,  0xa4,  0x03,  0x25,  0x32,  0x1f,  0xfe,  0xb4,
+  0x03,  0x01,  0x43,  0xfe,  0x06,  0xf0,  0xfe,  0xc4,  0x03,  0x8d,  0x81,  0xfe,  0x0a,  0xf0,  0xfe,  0x7a,
+  0x06,  0x02,  0x22,  0x05,  0x6b,  0x28,  0x16,  0xfe,  0xf6,  0x04,  0x14,  0x2c,  0x01,  0x33,  0x8f,  0xfe,
+  0x66,  0x02,  0x02,  0xd1,  0xeb,  0x2a,  0x67,  0x1a,  0xfe,  0x67,  0x1b,  0xf8,  0xf7,  0xfe,  0x48,  0x1c,
+  0x70,  0x01,  0x6e,  0x87,  0x0a,  0x40,  0x01,  0x0e,  0x07,  0x00,  0x16,  0xd3,  0x0a,  0xca,  0x01,  0x0e,
+  0x74,  0x60,  0x59,  0x76,  0x27,  0x05,  0x6b,  0x28,  0xfe,  0x10,  0x12,  0x14,  0x2c,  0x01,  0x33,  0x8f,
+  0xfe,  0x66,  0x02,  0x02,  0xd1,  0xbc,  0x7d,  0xbd,  0x7f,  0x25,  0x22,  0x65,  0xfe,  0x3c,  0x04,  0x1f,
+  0xfe,  0x38,  0x04,  0x68,  0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x4e,  0x12,  0x2b,  0xff,  0x02,
+  0x00,  0x10,  0x01,  0x08,  0x1f,  0xfe,  0xe0,  0x04,  0x2b,  0x01,  0x08,  0x1f,  0x22,  0x30,  0x2e,  0xd5,
+  0xfe,  0x4c,  0x44,  0xfe,  0x4c,  0x12,  0x60,  0xfe,  0x44,  0x48,  0x13,  0x2c,  0xfe,  0x4c,  0x54,  0x64,
+  0xd3,  0x46,  0x76,  0x27,  0xfa,  0xef,  0xfe,  0x62,  0x13,  0x09,  0x04,  0x1d,  0xfe,  0x2a,  0x13,  0x2f,
+  0x07,  0x7e,  0xa5,  0xfe,  0x20,  0x10,  0x13,  0x2c,  0xfe,  0x4c,  0x54,  0x64,  0xd3,  0xfa,  0xef,  0x86,
+  0x09,  0x04,  0x1d,  0xfe,  0x08,  0x13,  0x2f,  0x07,  0x7e,  0x6e,  0x09,  0x04,  0x1d,  0xfe,  0x1c,  0x12,
+  0x14,  0x92,  0x09,  0x04,  0x06,  0x3b,  0x14,  0xc4,  0x01,  0x33,  0x8f,  0xfe,  0x70,  0x0c,  0x02,  0x22,
+  0x2b,  0x11,  0xfe,  0xe6,  0x00,  0xfe,  0x1c,  0x90,  0xf9,  0x03,  0x14,  0x92,  0x01,  0x33,  0x02,  0x29,
+  0xfe,  0x42,  0x5b,  0x67,  0x1a,  0xfe,  0x46,  0x59,  0xf8,  0xf7,  0xfe,  0x87,  0x80,  0xfe,  0x31,  0xe4,
+  0x4f,  0x09,  0x04,  0x0b,  0xfe,  0x78,  0x13,  0xfe,  0x20,  0x80,  0x07,  0x1a,  0xfe,  0x70,  0x12,  0x49,
+  0x04,  0x06,  0xfe,  0x60,  0x13,  0x05,  0xfe,  0xa2,  0x00,  0x28,  0x16,  0xfe,  0x80,  0x05,  0xfe,  0x31,
+  0xe4,  0x6a,  0x49,  0x04,  0x0b,  0xfe,  0x4a,  0x13,  0x05,  0xfe,  0xa0,  0x00,  0x28,  0xfe,  0x42,  0x12,
+  0x5e,  0x01,  0x08,  0x25,  0x32,  0xf1,  0x01,  0x08,  0x26,  0xfe,  0x98,  0x05,  0x11,  0xfe,  0xe3,  0x00,
+  0x23,  0x49,  0xfe,  0x4a,  0xf0,  0xfe,  0x6a,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0x64,  0x05,  0x83,  0x24,
+  0xfe,  0x21,  0x00,  0xa1,  0x24,  0xfe,  0x22,  0x00,  0xa0,  0x24,  0x4c,  0xfe,  0x09,  0x48,  0x01,  0x08,
+  0x26,  0xfe,  0x98,  0x05,  0xfe,  0xe2,  0x08,  0x49,  0x04,  0xc5,  0x3b,  0x01,  0x86,  0x24,  0x06,  0x12,
+  0xcc,  0x37,  0xfe,  0x27,  0x01,  0x09,  0x04,  0x1d,  0xfe,  0x22,  0x12,  0x47,  0x01,  0xa7,  0x14,  0x92,
+  0x09,  0x04,  0x06,  0x3b,  0x14,  0xc4,  0x01,  0x33,  0x8f,  0xfe,  0x70,  0x0c,  0x02,  0x22,  0x05,  0xfe,
+  0x9c,  0x00,  0x28,  0xfe,  0x3e,  0x12,  0x05,  0x50,  0x28,  0xfe,  0x36,  0x13,  0x47,  0x01,  0xa7,  0x26,
+  0xfe,  0x08,  0x06,  0x0a,  0x06,  0x49,  0x04,  0x19,  0xfe,  0x02,  0x12,  0x5f,  0x01,  0xfe,  0xaa,  0x14,
+  0x1f,  0xfe,  0xfe,  0x05,  0x11,  0x9a,  0x01,  0x43,  0x11,  0xfe,  0xe5,  0x00,  0x05,  0x50,  0xb4,  0x0c,
+  0x50,  0x05,  0xc6,  0x28,  0xfe,  0x62,  0x12,  0x05,  0x3f,  0x28,  0xfe,  0x5a,  0x13,  0x01,  0xfe,  0x14,
+  0x18,  0x01,  0xfe,  0x66,  0x18,  0xfe,  0x43,  0x48,  0xb7,  0x19,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,
+  0x48,  0x8b,  0x1c,  0x3d,  0x85,  0xb7,  0x69,  0x47,  0x01,  0xa7,  0x26,  0xfe,  0x72,  0x06,  0x49,  0x04,
+  0x1b,  0xdf,  0x89,  0x0a,  0x4d,  0x01,  0xfe,  0xd8,  0x14,  0x1f,  0xfe,  0x68,  0x06,  0x11,  0x9a,  0x01,
+  0x43,  0x11,  0xfe,  0xe5,  0x00,  0x05,  0x3f,  0xb4,  0x0c,  0x3f,  0x17,  0x06,  0x01,  0xa7,  0xec,  0x72,
+  0x70,  0x01,  0x6e,  0x87,  0x11,  0xfe,  0xe2,  0x00,  0x01,  0x08,  0x25,  0x32,  0xfe,  0x0a,  0xf0,  0xfe,
+  0xa6,  0x06,  0x8c,  0xfe,  0x5c,  0x07,  0xfe,  0x06,  0xf0,  0xfe,  0x64,  0x07,  0x8d,  0x81,  0x02,  0x22,
+  0x09,  0x04,  0x0b,  0xfe,  0x2e,  0x12,  0x15,  0x1a,  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x00,
+  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0xfe,  0x99,  0xa4,  0x01,  0x08,  0x15,  0x00,  0x02,  0xfe,  0x32,
+  0x08,  0x61,  0x04,  0x1b,  0xfe,  0x38,  0x12,  0x09,  0x04,  0x1b,  0x6e,  0x15,  0xfe,  0x1b,  0x00,  0x01,
+  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x06,  0x01,
+  0x08,  0x15,  0x00,  0x02,  0xd9,  0x66,  0x4c,  0xfe,  0x3a,  0x55,  0x5f,  0xfe,  0x9a,  0x81,  0x4b,  0x1d,
+  0xba,  0xfe,  0x32,  0x07,  0x0a,  0x1d,  0xfe,  0x09,  0x6f,  0xaf,  0xfe,  0xca,  0x45,  0xfe,  0x32,  0x12,
+  0x62,  0x2c,  0x85,  0x66,  0x7b,  0x01,  0x08,  0x25,  0x32,  0xfe,  0x0a,  0xf0,  0xfe,  0x32,  0x07,  0x8d,
+  0x81,  0x8c,  0xfe,  0x5c,  0x07,  0x02,  0x22,  0x01,  0x43,  0x02,  0xfe,  0x8a,  0x06,  0x15,  0x19,  0x02,
+  0xfe,  0x8a,  0x06,  0xfe,  0x9c,  0xf7,  0xd4,  0xfe,  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x77,  0xfe,  0xca,
+  0x07,  0x0c,  0x54,  0x18,  0x55,  0x09,  0x4a,  0x6a,  0x35,  0x1e,  0x20,  0x07,  0x10,  0xfe,  0x0e,  0x12,
+  0x74,  0xfe,  0x80,  0x80,  0x37,  0x20,  0x63,  0x27,  0xfe,  0x06,  0x10,  0xfe,  0x83,  0xe7,  0xc4,  0xa1,
+  0xfe,  0x03,  0x40,  0x09,  0x4a,  0x4f,  0x35,  0x01,  0xa8,  0xad,  0xfe,  0x1f,  0x40,  0x12,  0x58,  0x01,
+  0xa5,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0xfe,  0x44,  0x51,  0xfe,  0xc6,  0x51,  0x83,  0xfb,  0xfe,
+  0x8a,  0x90,  0x0c,  0x52,  0x18,  0x53,  0xfe,  0x0c,  0x90,  0xfe,  0x8e,  0x90,  0xfe,  0x40,  0x50,  0xfe,
+  0xc2,  0x50,  0x0c,  0x39,  0x18,  0x3a,  0xfe,  0x4a,  0x10,  0x09,  0x04,  0x6a,  0xfe,  0x2a,  0x12,  0xfe,
+  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x0c,  0x54,  0x18,  0x55,  0x09,  0x04,  0x4f,  0x85,  0x01,  0xa8,  0xfe,
+  0x1f,  0x80,  0x12,  0x58,  0xfe,  0x44,  0x90,  0xfe,  0xc6,  0x90,  0x0c,  0x56,  0x18,  0x57,  0xfb,  0xfe,
+  0x8a,  0x90,  0x0c,  0x52,  0x18,  0x53,  0xfe,  0x40,  0x90,  0xfe,  0xc2,  0x90,  0x0c,  0x39,  0x18,  0x3a,
+  0x0c,  0x38,  0x18,  0x4e,  0x09,  0x4a,  0x19,  0x35,  0x2a,  0x13,  0xfe,  0x4e,  0x11,  0x65,  0xfe,  0x48,
+  0x08,  0xfe,  0x9e,  0xf0,  0xfe,  0x5c,  0x08,  0xb1,  0x16,  0x32,  0x2a,  0x73,  0xdd,  0xb8,  0xfe,  0x80,
+  0x08,  0xb9,  0xfe,  0x9e,  0x08,  0x8c,  0xfe,  0x74,  0x08,  0xfe,  0x06,  0xf0,  0xfe,  0x7a,  0x08,  0x8d,
+  0x81,  0x02,  0x22,  0x01,  0x43,  0xfe,  0xc9,  0x10,  0x15,  0x19,  0xfe,  0xc9,  0x10,  0x61,  0x04,  0x06,
+  0xfe,  0x10,  0x12,  0x61,  0x04,  0x0b,  0x45,  0x09,  0x04,  0x0b,  0xfe,  0x68,  0x12,  0xfe,  0x2e,  0x1c,
+  0x02,  0xfe,  0x24,  0x0a,  0x61,  0x04,  0x06,  0x45,  0x61,  0x04,  0x0b,  0xfe,  0x52,  0x12,  0xfe,  0x2c,
+  0x1c,  0xfe,  0xaa,  0xf0,  0xfe,  0x1e,  0x09,  0xfe,  0xac,  0xf0,  0xfe,  0xbe,  0x08,  0xfe,  0x8a,  0x10,
+  0xaa,  0xfe,  0xf3,  0x10,  0xfe,  0xad,  0xf0,  0xfe,  0xca,  0x08,  0x02,  0xfe,  0x24,  0x0a,  0xab,  0xfe,
+  0xe7,  0x10,  0xfe,  0x2b,  0xf0,  0x9d,  0xe9,  0x1c,  0xfe,  0x00,  0xfe,  0xfe,  0x1c,  0x12,  0xb5,  0xfe,
+  0xd2,  0xf0,  0x9d,  0xfe,  0x76,  0x18,  0x1c,  0x1a,  0x16,  0x9d,  0x05,  0xcb,  0x1c,  0x06,  0x16,  0x9d,
+  0xb8,  0x6d,  0xb9,  0x6d,  0xaa,  0xab,  0xfe,  0xb1,  0x10,  0x70,  0x5e,  0x2b,  0x14,  0x92,  0x01,  0x33,
+  0x0f,  0xfe,  0x35,  0x00,  0xfe,  0x01,  0xf0,  0x5a,  0x0f,  0x7c,  0x02,  0x5a,  0xfe,  0x74,  0x18,  0x1c,
+  0xfe,  0x00,  0xf8,  0x16,  0x6d,  0x67,  0x1b,  0x01,  0xfe,  0x44,  0x0d,  0x3b,  0x01,  0xe6,  0x1e,  0x27,
+  0x74,  0x67,  0x1a,  0x02,  0x6d,  0x09,  0x04,  0x0b,  0x21,  0xfe,  0x06,  0x0a,  0x09,  0x04,  0x6a,  0xfe,
+  0x82,  0x12,  0x09,  0x04,  0x19,  0xfe,  0x66,  0x13,  0x1e,  0x58,  0xac,  0xfc,  0xfe,  0x83,  0x80,  0xfe,
+  0xc8,  0x44,  0xfe,  0x2e,  0x13,  0xfe,  0x04,  0x91,  0xfe,  0x86,  0x91,  0x63,  0x27,  0xfe,  0x40,  0x59,
+  0xfe,  0xc1,  0x59,  0x77,  0xd7,  0x05,  0x54,  0x31,  0x55,  0x0c,  0x7b,  0x18,  0x7c,  0xbe,  0x54,  0xbf,
+  0x55,  0x01,  0xa8,  0xad,  0x63,  0x27,  0x12,  0x58,  0xc0,  0x38,  0xc1,  0x4e,  0x79,  0x56,  0x68,  0x57,
+  0xf4,  0xf5,  0xfe,  0x04,  0xfa,  0x38,  0xfe,  0x05,  0xfa,  0x4e,  0x01,  0xa5,  0xa2,  0x23,  0x0c,  0x7b,
+  0x0c,  0x7c,  0x79,  0x56,  0x68,  0x57,  0xfe,  0x12,  0x10,  0x09,  0x04,  0x19,  0x16,  0xd7,  0x79,  0x39,
+  0x68,  0x3a,  0x09,  0x04,  0xfe,  0xf7,  0x00,  0x35,  0x05,  0x52,  0x31,  0x53,  0xfe,  0x10,  0x58,  0xfe,
+  0x91,  0x58,  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0x02,  0x6d,  0x09,  0x04,  0x19,  0x16,  0xd7,  0x09,
+  0x04,  0xfe,  0xf7,  0x00,  0x35,  0xfe,  0x3a,  0x55,  0xfe,  0x19,  0x81,  0x5f,  0xfe,  0x10,  0x90,  0xfe,
+  0x92,  0x90,  0xfe,  0xd7,  0x10,  0x2f,  0x07,  0x9b,  0x16,  0xfe,  0xc6,  0x08,  0x11,  0x9b,  0x09,  0x04,
+  0x0b,  0xfe,  0x14,  0x13,  0x05,  0x39,  0x31,  0x3a,  0x77,  0xfe,  0xc6,  0x08,  0xfe,  0x0c,  0x58,  0xfe,
+  0x8d,  0x58,  0x02,  0x6d,  0x23,  0x47,  0xfe,  0x19,  0x80,  0xde,  0x09,  0x04,  0x0b,  0xfe,  0x1a,  0x12,
+  0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,  0xe9,  0xb5,  0xfe,  0xd1,  0xf0,  0xd9,  0x14,  0x7a,  0x01,  0x33,
+  0x0f,  0xfe,  0x44,  0x00,  0xfe,  0x8e,  0x10,  0xfe,  0x6c,  0x19,  0xbe,  0x39,  0xfe,  0xed,  0x19,  0xbf,
+  0x3a,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0xe9,  0x1c,  0xfe,  0x00,  0xff,  0x34,  0xfe,  0x74,  0x10,
+  0xb5,  0xfe,  0xd2,  0xf0,  0xfe,  0xb2,  0x0a,  0xfe,  0x76,  0x18,  0x1c,  0x1a,  0x84,  0x05,  0xcb,  0x1c,
+  0x06,  0xfe,  0x08,  0x13,  0x0f,  0xfe,  0x16,  0x00,  0x02,  0x5a,  0xfe,  0xd1,  0xf0,  0xfe,  0xc4,  0x0a,
+  0x14,  0x7a,  0x01,  0x33,  0x0f,  0xfe,  0x17,  0x00,  0xfe,  0x42,  0x10,  0xfe,  0xce,  0xf0,  0xfe,  0xca,
+  0x0a,  0xfe,  0x3c,  0x10,  0xfe,  0xcd,  0xf0,  0xfe,  0xd6,  0x0a,  0x0f,  0xfe,  0x22,  0x00,  0x02,  0x5a,
+  0xfe,  0xcb,  0xf0,  0xfe,  0xe2,  0x0a,  0x0f,  0xfe,  0x24,  0x00,  0x02,  0x5a,  0xfe,  0xd0,  0xf0,  0xfe,
+  0xec,  0x0a,  0x0f,  0x93,  0xdc,  0xfe,  0xcf,  0xf0,  0xfe,  0xf6,  0x0a,  0x0f,  0x4c,  0xfe,  0x10,  0x10,
+  0xfe,  0xcc,  0xf0,  0xd9,  0x61,  0x04,  0x19,  0x3b,  0x0f,  0xfe,  0x12,  0x00,  0x2a,  0x13,  0xfe,  0x4e,
+  0x11,  0x65,  0xfe,  0x0c,  0x0b,  0xfe,  0x9e,  0xf0,  0xfe,  0x20,  0x0b,  0xb1,  0x16,  0x32,  0x2a,  0x73,
+  0xdd,  0xb8,  0x22,  0xb9,  0x22,  0x2a,  0xec,  0x65,  0xfe,  0x2c,  0x0b,  0x25,  0x32,  0x8c,  0xfe,  0x48,
+  0x0b,  0x8d,  0x81,  0xb8,  0xd4,  0xb9,  0xd4,  0x02,  0x22,  0x01,  0x43,  0xfe,  0xdb,  0x10,  0x11,  0xfe,
+  0xe8,  0x00,  0xaa,  0xab,  0x70,  0xbc,  0x7d,  0xbd,  0x7f,  0xfe,  0x89,  0xf0,  0x22,  0x30,  0x2e,  0xd8,
+  0xbc,  0x7d,  0xbd,  0x7f,  0x01,  0x08,  0x1f,  0x22,  0x30,  0x2e,  0xd6,  0xb1,  0x45,  0x0f,  0xfe,  0x42,
+  0x00,  0x02,  0x5a,  0x78,  0x06,  0xfe,  0x81,  0x49,  0x16,  0xfe,  0x38,  0x0c,  0x09,  0x04,  0x0b,  0xfe,
+  0x44,  0x13,  0x0f,  0x00,  0x4b,  0x0b,  0xfe,  0x54,  0x12,  0x4b,  0xfe,  0x28,  0x00,  0x21,  0xfe,  0xa6,
+  0x0c,  0x0a,  0x40,  0x01,  0x0e,  0x07,  0x00,  0x5d,  0x3e,  0xfe,  0x28,  0x00,  0xfe,  0xe2,  0x10,  0x01,
+  0xe7,  0x01,  0xe8,  0x0a,  0x99,  0x01,  0xfe,  0x32,  0x0e,  0x59,  0x11,  0x2d,  0x01,  0x6f,  0x02,  0x29,
+  0x0f,  0xfe,  0x44,  0x00,  0x4b,  0x0b,  0xdf,  0x3e,  0x0b,  0xfe,  0xb4,  0x10,  0x01,  0x86,  0x3e,  0x0b,
+  0xfe,  0xaa,  0x10,  0x01,  0x86,  0xfe,  0x19,  0x82,  0xfe,  0x34,  0x46,  0xa3,  0x3e,  0x0b,  0x0f,  0xfe,
+  0x43,  0x00,  0xfe,  0x96,  0x10,  0x09,  0x4a,  0x0b,  0x35,  0x01,  0xe7,  0x01,  0xe8,  0x59,  0x11,  0x2d,
+  0x01,  0x6f,  0x67,  0x0b,  0x59,  0x3c,  0x8a,  0x02,  0xfe,  0x2a,  0x03,  0x09,  0x04,  0x0b,  0x84,  0x3e,
+  0x0b,  0x0f,  0x00,  0xfe,  0x5c,  0x10,  0x61,  0x04,  0x1b,  0xfe,  0x58,  0x12,  0x09,  0x04,  0x1b,  0xfe,
+  0x50,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x5c,  0x0c,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,
+  0xf0,  0xfe,  0x62,  0x0c,  0x09,  0x4a,  0x1b,  0x35,  0xfe,  0xa9,  0x10,  0x0f,  0xfe,  0x15,  0x00,  0xfe,
+  0x04,  0xe6,  0x0b,  0x5f,  0x5c,  0x0f,  0xfe,  0x13,  0x00,  0xfe,  0x10,  0x10,  0x0f,  0xfe,  0x47,  0x00,
+  0xa1,  0x0f,  0xfe,  0x41,  0x00,  0xa0,  0x0f,  0xfe,  0x24,  0x00,  0x87,  0xaa,  0xab,  0x70,  0x05,  0x6b,
+  0x28,  0x21,  0xd1,  0x5f,  0xfe,  0x04,  0xe6,  0x1b,  0xfe,  0x9d,  0x41,  0xfe,  0x1c,  0x42,  0x59,  0x01,
+  0xda,  0x02,  0x29,  0xea,  0x14,  0x0b,  0x37,  0x95,  0xa9,  0x14,  0xfe,  0x31,  0x00,  0x37,  0x97,  0x01,
+  0xfe,  0x54,  0x0f,  0x02,  0xd0,  0x3c,  0xfe,  0x06,  0xec,  0xc9,  0xee,  0x3e,  0x1d,  0xfe,  0xce,  0x45,
+  0x34,  0x3c,  0xfe,  0x06,  0xea,  0xc9,  0xfe,  0x47,  0x4b,  0x89,  0xfe,  0x75,  0x57,  0x05,  0x51,  0xfe,
+  0x98,  0x56,  0xfe,  0x38,  0x12,  0x0a,  0x42,  0x01,  0x0e,  0xfe,  0x44,  0x48,  0x46,  0x09,  0x04,  0x1d,
+  0xfe,  0x1a,  0x13,  0x0a,  0x40,  0x01,  0x0e,  0x47,  0xfe,  0x41,  0x58,  0x0a,  0x99,  0x01,  0x0e,  0xfe,
+  0x49,  0x54,  0x8e,  0xfe,  0x2a,  0x0d,  0x02,  0xfe,  0x2a,  0x03,  0x0a,  0x51,  0xfe,  0xee,  0x14,  0xee,
+  0x3e,  0x1d,  0xfe,  0xce,  0x45,  0x34,  0x3c,  0xfe,  0xce,  0x47,  0xfe,  0xad,  0x13,  0x02,  0x29,  0x1e,
+  0x20,  0x07,  0x10,  0xfe,  0x9e,  0x12,  0x23,  0x12,  0x4d,  0x12,  0x94,  0x12,  0xce,  0x1e,  0x2d,  0x47,
+  0x37,  0x2d,  0xb1,  0xe0,  0xfe,  0xbc,  0xf0,  0xfe,  0xec,  0x0d,  0x13,  0x06,  0x12,  0x4d,  0x01,  0xfe,
+  0xe2,  0x15,  0x05,  0xfe,  0x38,  0x01,  0x31,  0xfe,  0x3a,  0x01,  0x77,  0xfe,  0xf0,  0x0d,  0xfe,  0x02,
+  0xec,  0xce,  0x62,  0x00,  0x5d,  0xfe,  0x04,  0xec,  0x20,  0x46,  0xfe,  0x05,  0xf6,  0xfe,  0x34,  0x01,
+  0x01,  0xfe,  0x52,  0x16,  0xfb,  0xfe,  0x48,  0xf4,  0x0d,  0xfe,  0x18,  0x13,  0xaf,  0xfe,  0x02,  0xea,
+  0xce,  0x62,  0x7a,  0xfe,  0xc5,  0x13,  0x14,  0x1b,  0x37,  0x95,  0xa9,  0x5c,  0x05,  0xfe,  0x38,  0x01,
+  0x1c,  0xfe,  0xf0,  0xff,  0x0c,  0xfe,  0x60,  0x01,  0x05,  0xfe,  0x3a,  0x01,  0x0c,  0xfe,  0x62,  0x01,
+  0x3d,  0x12,  0x20,  0x24,  0x06,  0x12,  0x2d,  0x11,  0x2d,  0x8a,  0x13,  0x06,  0x03,  0x23,  0x03,  0x1e,
+  0x4d,  0xfe,  0xf7,  0x12,  0x1e,  0x94,  0xac,  0x12,  0x94,  0x07,  0x7a,  0xfe,  0x71,  0x13,  0xfe,  0x24,
+  0x1c,  0x14,  0x1a,  0x37,  0x95,  0xa9,  0xfe,  0xd9,  0x10,  0xb6,  0xfe,  0x03,  0xdc,  0xfe,  0x73,  0x57,
+  0xfe,  0x80,  0x5d,  0x03,  0xb6,  0xfe,  0x03,  0xdc,  0xfe,  0x5b,  0x57,  0xfe,  0x80,  0x5d,  0x03,  0xfe,
+  0x03,  0x57,  0xb6,  0x23,  0xfe,  0x00,  0xcc,  0x03,  0xfe,  0x03,  0x57,  0xb6,  0x75,  0x03,  0x09,  0x04,
+  0x4c,  0xfe,  0x22,  0x13,  0xfe,  0x1c,  0x80,  0x07,  0x06,  0xfe,  0x1a,  0x13,  0xfe,  0x1e,  0x80,  0xe1,
+  0xfe,  0x1d,  0x80,  0xa4,  0xfe,  0x0c,  0x90,  0xfe,  0x0e,  0x13,  0xfe,  0x0e,  0x90,  0xa3,  0xfe,  0x3c,
+  0x90,  0xfe,  0x30,  0xf4,  0x0b,  0xfe,  0x3c,  0x50,  0xa0,  0x01,  0xfe,  0x82,  0x16,  0x2f,  0x07,  0x2d,
+  0xe0,  0x01,  0xfe,  0xbc,  0x15,  0x09,  0x04,  0x1d,  0x45,  0x01,  0xe7,  0x01,  0xe8,  0x11,  0xfe,  0xe9,
+  0x00,  0x09,  0x04,  0x4c,  0xfe,  0x2c,  0x13,  0x01,  0xfe,  0x14,  0x16,  0xfe,  0x1e,  0x1c,  0xfe,  0x14,
+  0x90,  0xfe,  0x96,  0x90,  0x0c,  0xfe,  0x64,  0x01,  0x18,  0xfe,  0x66,  0x01,  0x09,  0x04,  0x4f,  0xfe,
+  0x12,  0x12,  0xfe,  0x03,  0x80,  0x74,  0xfe,  0x01,  0xec,  0x20,  0xfe,  0x80,  0x40,  0x12,  0x20,  0x63,
+  0x27,  0x11,  0xc8,  0x59,  0x1e,  0x20,  0xed,  0x76,  0x20,  0x03,  0xfe,  0x08,  0x1c,  0x05,  0xfe,  0xac,
+  0x00,  0xfe,  0x06,  0x58,  0x05,  0xfe,  0xae,  0x00,  0xfe,  0x07,  0x58,  0x05,  0xfe,  0xb0,  0x00,  0xfe,
+  0x08,  0x58,  0x05,  0xfe,  0xb2,  0x00,  0xfe,  0x09,  0x58,  0xfe,  0x0a,  0x1c,  0x24,  0x69,  0x12,  0xc9,
+  0x23,  0x0c,  0x50,  0x0c,  0x3f,  0x13,  0x40,  0x48,  0x5f,  0x17,  0x1d,  0xfe,  0x90,  0x4d,  0xfe,  0x91,
+  0x54,  0x21,  0xfe,  0x08,  0x0f,  0x3e,  0x10,  0x13,  0x42,  0x48,  0x17,  0x4c,  0xfe,  0x90,  0x4d,  0xfe,
+  0x91,  0x54,  0x21,  0xfe,  0x1e,  0x0f,  0x24,  0x10,  0x12,  0x20,  0x78,  0x2c,  0x46,  0x1e,  0x20,  0xed,
+  0x76,  0x20,  0x11,  0xc8,  0xf6,  0xfe,  0xd6,  0xf0,  0xfe,  0x32,  0x0f,  0xea,  0x70,  0xfe,  0x14,  0x1c,
+  0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x03,  0x3c,  0xfe,  0x0c,  0x14,  0xee,  0xfe,  0x07,  0xe6,  0x1d,
+  0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x03,  0x01,  0x86,  0x78,  0x2c,  0x46,  0xfa,  0xef,  0xfe,  0x42,
+  0x13,  0x2f,  0x07,  0x2d,  0xfe,  0x34,  0x13,  0x0a,  0x42,  0x01,  0x0e,  0xb0,  0xfe,  0x36,  0x12,  0xf0,
+  0xfe,  0x45,  0x48,  0x01,  0xe3,  0xfe,  0x00,  0xcc,  0xb0,  0xfe,  0xf3,  0x13,  0x3d,  0x75,  0x07,  0x10,
+  0xa3,  0x0a,  0x80,  0x01,  0x0e,  0xfe,  0x80,  0x5c,  0x01,  0x6f,  0xfe,  0x0e,  0x10,  0x07,  0x7e,  0x45,
+  0xf6,  0xfe,  0xd6,  0xf0,  0xfe,  0x6c,  0x0f,  0x03,  0xfe,  0x44,  0x58,  0x74,  0xfe,  0x01,  0xec,  0x97,
+  0xfe,  0x9e,  0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x1b,  0x76,  0x27,  0x01,  0xda,  0xfe,
+  0xdd,  0x10,  0x2a,  0xbc,  0x7d,  0xbd,  0x7f,  0x30,  0x2e,  0xd5,  0x07,  0x1b,  0xfe,  0x48,  0x12,  0x07,
+  0x0b,  0xfe,  0x56,  0x12,  0x07,  0x1a,  0xfe,  0x30,  0x12,  0x07,  0xc2,  0x16,  0xfe,  0x3e,  0x11,  0x07,
+  0xfe,  0x23,  0x00,  0x16,  0xfe,  0x4a,  0x11,  0x07,  0x06,  0x16,  0xfe,  0xa8,  0x11,  0x07,  0x19,  0xfe,
+  0x12,  0x12,  0x07,  0x00,  0x16,  0x22,  0x14,  0xc2,  0x01,  0x33,  0x9f,  0x2b,  0x01,  0x08,  0x8c,  0x43,
+  0x03,  0x2b,  0xfe,  0x62,  0x08,  0x0a,  0xca,  0x01,  0xfe,  0x32,  0x0e,  0x11,  0x7e,  0x02,  0x29,  0x2b,
+  0x2f,  0x07,  0x9b,  0xfe,  0xd9,  0x13,  0x79,  0x39,  0x68,  0x3a,  0x77,  0xfe,  0xfc,  0x10,  0x09,  0x04,
+  0x6a,  0xfe,  0x72,  0x12,  0xc0,  0x38,  0xc1,  0x4e,  0xf4,  0xf5,  0x8e,  0xfe,  0xc6,  0x10,  0x1e,  0x58,
+  0xfe,  0x26,  0x13,  0x05,  0x7b,  0x31,  0x7c,  0x77,  0xfe,  0x82,  0x0c,  0x0c,  0x54,  0x18,  0x55,  0x23,
+  0x0c,  0x7b,  0x0c,  0x7c,  0x01,  0xa8,  0x24,  0x69,  0x73,  0x12,  0x58,  0x01,  0xa5,  0xc0,  0x38,  0xc1,
+  0x4e,  0xfe,  0x04,  0x55,  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,  0x38,  0xfe,  0x05,  0xfa,  0x4e,  0xfe,
+  0x91,  0x10,  0x05,  0x56,  0x31,  0x57,  0xfe,  0x40,  0x56,  0xfe,  0xe1,  0x56,  0x0c,  0x56,  0x18,  0x57,
+  0x83,  0xc0,  0x38,  0xc1,  0x4e,  0xf4,  0xf5,  0x05,  0x52,  0x31,  0x53,  0xfe,  0x00,  0x56,  0xfe,  0xa1,
+  0x56,  0x0c,  0x52,  0x18,  0x53,  0x09,  0x04,  0x6a,  0xfe,  0x1e,  0x12,  0x1e,  0x58,  0xfe,  0x1f,  0x40,
+  0x05,  0x54,  0x31,  0x55,  0xfe,  0x2c,  0x50,  0xfe,  0xae,  0x50,  0x05,  0x56,  0x31,  0x57,  0xfe,  0x44,
+  0x50,  0xfe,  0xc6,  0x50,  0x05,  0x52,  0x31,  0x53,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x05,  0x39,
+  0x31,  0x3a,  0xfe,  0x40,  0x50,  0xfe,  0xc2,  0x50,  0x02,  0x5c,  0x24,  0x06,  0x12,  0xcd,  0x02,  0x5b,
+  0x2b,  0x01,  0x08,  0x1f,  0x44,  0x30,  0x2e,  0xd5,  0x07,  0x06,  0x21,  0x44,  0x2f,  0x07,  0x9b,  0x21,
+  0x5b,  0x01,  0x6e,  0x1c,  0x3d,  0x16,  0x44,  0x09,  0x04,  0x0b,  0xe2,  0x79,  0x39,  0x68,  0x3a,  0xfe,
+  0x0a,  0x55,  0x34,  0xfe,  0x8b,  0x55,  0xbe,  0x39,  0xbf,  0x3a,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,
+  0x02,  0x5b,  0xfe,  0x19,  0x81,  0xaf,  0xfe,  0x19,  0x41,  0x02,  0x5b,  0x2b,  0x01,  0x08,  0x25,  0x32,
+  0x1f,  0xa2,  0x30,  0x2e,  0xd8,  0x4b,  0x1a,  0xfe,  0xa6,  0x12,  0x4b,  0x0b,  0x3b,  0x02,  0x44,  0x01,
+  0x08,  0x25,  0x32,  0x1f,  0xa2,  0x30,  0x2e,  0xd6,  0x07,  0x1a,  0x21,  0x44,  0x01,  0x08,  0x1f,  0xa2,
+  0x30,  0x2e,  0xfe,  0xe8,  0x09,  0xfe,  0xc2,  0x49,  0x60,  0x05,  0xfe,  0x9c,  0x00,  0x28,  0x84,  0x49,
+  0x04,  0x19,  0x34,  0x9f,  0xfe,  0xbb,  0x45,  0x4b,  0x00,  0x45,  0x3e,  0x06,  0x78,  0x3d,  0xfe,  0xda,
+  0x14,  0x01,  0x6e,  0x87,  0xfe,  0x4b,  0x45,  0xe2,  0x2f,  0x07,  0x9a,  0xe1,  0x05,  0xc6,  0x28,  0x84,
+  0x05,  0x3f,  0x28,  0x34,  0x5e,  0x02,  0x5b,  0xfe,  0xc0,  0x5d,  0xfe,  0xf8,  0x14,  0xfe,  0x03,  0x17,
+  0x05,  0x50,  0xb4,  0x0c,  0x50,  0x5e,  0x2b,  0x01,  0x08,  0x26,  0x5c,  0x01,  0xfe,  0xaa,  0x14,  0x02,
+  0x5c,  0x01,  0x08,  0x25,  0x32,  0x1f,  0x44,  0x30,  0x2e,  0xd6,  0x07,  0x06,  0x21,  0x44,  0x01,  0xfe,
+  0x8e,  0x13,  0xfe,  0x42,  0x58,  0xfe,  0x82,  0x14,  0xfe,  0xa4,  0x14,  0x87,  0xfe,  0x4a,  0xf4,  0x0b,
+  0x16,  0x44,  0xfe,  0x4a,  0xf4,  0x06,  0xfe,  0x0c,  0x12,  0x2f,  0x07,  0x9a,  0x85,  0x02,  0x5b,  0x05,
+  0x3f,  0xb4,  0x0c,  0x3f,  0x5e,  0x2b,  0x01,  0x08,  0x26,  0x5c,  0x01,  0xfe,  0xd8,  0x14,  0x02,  0x5c,
+  0x13,  0x06,  0x65,  0xfe,  0xca,  0x12,  0x26,  0xfe,  0xe0,  0x12,  0x72,  0xf1,  0x01,  0x08,  0x23,  0x72,
+  0x03,  0x8f,  0xfe,  0xdc,  0x12,  0x25,  0xfe,  0xdc,  0x12,  0x1f,  0xfe,  0xca,  0x12,  0x5e,  0x2b,  0x01,
+  0x08,  0xfe,  0xd5,  0x10,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,  0x1c,  0xfe,  0xff,  0x7f,
+  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,  0x1c,
+  0x3d,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,
+  0x03,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,  0xfe,  0x0b,  0x58,  0x03,  0x0a,  0x50,  0x01,
+  0x82,  0x0a,  0x3f,  0x01,  0x82,  0x03,  0xfc,  0x1c,  0x10,  0xff,  0x03,  0x00,  0x54,  0xfe,  0x00,  0xf4,
+  0x19,  0x48,  0xfe,  0x00,  0x7d,  0xfe,  0x01,  0x7d,  0xfe,  0x02,  0x7d,  0xfe,  0x03,  0x7c,  0x63,  0x27,
+  0x0c,  0x52,  0x18,  0x53,  0xbe,  0x56,  0xbf,  0x57,  0x03,  0xfe,  0x62,  0x08,  0xfe,  0x82,  0x4a,  0xfe,
+  0xe1,  0x1a,  0xfe,  0x83,  0x5a,  0x74,  0x03,  0x01,  0xfe,  0x14,  0x18,  0xfe,  0x42,  0x48,  0x5f,  0x60,
+  0x89,  0x01,  0x08,  0x1f,  0xfe,  0xa2,  0x14,  0x30,  0x2e,  0xd8,  0x01,  0x08,  0x1f,  0xfe,  0xa2,  0x14,
+  0x30,  0x2e,  0xfe,  0xe8,  0x0a,  0xfe,  0xc1,  0x59,  0x05,  0xc6,  0x28,  0xfe,  0xcc,  0x12,  0x49,  0x04,
+  0x1b,  0xfe,  0xc4,  0x13,  0x23,  0x62,  0x1b,  0xe2,  0x4b,  0xc3,  0x64,  0xfe,  0xe8,  0x13,  0x3b,  0x13,
+  0x06,  0x17,  0xc3,  0x78,  0xdb,  0xfe,  0x78,  0x10,  0xff,  0x02,  0x83,  0x55,  0xa1,  0xff,  0x02,  0x83,
+  0x55,  0x62,  0x1a,  0xa4,  0xbb,  0xfe,  0x30,  0x00,  0x8e,  0xe4,  0x17,  0x2c,  0x13,  0x06,  0xfe,  0x56,
+  0x10,  0x62,  0x0b,  0xe1,  0xbb,  0xfe,  0x64,  0x00,  0x8e,  0xe4,  0x0a,  0xfe,  0x64,  0x00,  0x17,  0x93,
+  0x13,  0x06,  0xfe,  0x28,  0x10,  0x62,  0x06,  0xfe,  0x60,  0x13,  0xbb,  0xfe,  0xc8,  0x00,  0x8e,  0xe4,
+  0x0a,  0xfe,  0xc8,  0x00,  0x17,  0x4d,  0x13,  0x06,  0x83,  0xbb,  0xfe,  0x90,  0x01,  0xba,  0xfe,  0x4e,
+  0x14,  0x89,  0xfe,  0x12,  0x10,  0xfe,  0x43,  0xf4,  0x94,  0xfe,  0x56,  0xf0,  0xfe,  0x60,  0x14,  0xfe,
+  0x04,  0xf4,  0x6c,  0xfe,  0x43,  0xf4,  0x93,  0xfe,  0xf3,  0x10,  0xf9,  0x01,  0xfe,  0x22,  0x13,  0x1c,
+  0x3d,  0xfe,  0x10,  0x13,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x69,  0xba,  0xfe,  0x9c,  0x14,  0xb7,
+  0x69,  0xfe,  0x1c,  0x10,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x19,  0xba,  0xfe,  0x9c,  0x14,  0xb7,
+  0x19,  0x83,  0x60,  0x23,  0xfe,  0x4d,  0xf4,  0x00,  0xdf,  0x89,  0x13,  0x06,  0xfe,  0xb4,  0x56,  0xfe,
+  0xc3,  0x58,  0x03,  0x60,  0x13,  0x0b,  0x03,  0x15,  0x06,  0x01,  0x08,  0x26,  0xe5,  0x15,  0x0b,  0x01,
+  0x08,  0x26,  0xe5,  0x15,  0x1a,  0x01,  0x08,  0x26,  0xe5,  0x72,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x03,
+  0x15,  0x06,  0x01,  0x08,  0x26,  0xa6,  0x15,  0x1a,  0x01,  0x08,  0x26,  0xa6,  0x15,  0x06,  0x01,  0x08,
+  0x26,  0xa6,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x26,  0xa6,  0x72,  0xfe,  0x89,  0x4a,  0x01,  0x08,  0x03,
+  0x60,  0x03,  0x1e,  0xcc,  0x07,  0x06,  0xfe,  0x44,  0x13,  0xad,  0x12,  0xcc,  0xfe,  0x49,  0xf4,  0x00,
+  0x3b,  0x72,  0x9f,  0x5e,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,  0xf1,  0x01,  0x08,  0x2f,  0x07,  0xfe,
+  0xe3,  0x00,  0xfe,  0x20,  0x13,  0x1f,  0xfe,  0x5a,  0x15,  0x23,  0x12,  0xcd,  0x01,  0x43,  0x1e,  0xcd,
+  0x07,  0x06,  0x45,  0x09,  0x4a,  0x06,  0x35,  0x03,  0x0a,  0x42,  0x01,  0x0e,  0xed,  0x88,  0x07,  0x10,
+  0xa4,  0x0a,  0x80,  0x01,  0x0e,  0x88,  0x0a,  0x51,  0x01,  0x9e,  0x03,  0x0a,  0x80,  0x01,  0x0e,  0x88,
+  0xfe,  0x80,  0xe7,  0x10,  0x07,  0x10,  0x84,  0xfe,  0x45,  0x58,  0x01,  0xe3,  0x88,  0x03,  0x0a,  0x42,
+  0x01,  0x0e,  0x88,  0x0a,  0x51,  0x01,  0x9e,  0x03,  0x0a,  0x42,  0x01,  0x0e,  0xfe,  0x80,  0x80,  0xf2,
+  0xfe,  0x49,  0xe4,  0x10,  0xa4,  0x0a,  0x80,  0x01,  0x0e,  0xf2,  0x0a,  0x51,  0x01,  0x82,  0x03,  0x17,
+  0x10,  0x71,  0x66,  0xfe,  0x60,  0x01,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x24,  0x1c,  0xfe,
+  0x1d,  0xf7,  0x1d,  0x90,  0xfe,  0xf6,  0x15,  0x01,  0xfe,  0xfc,  0x16,  0xe0,  0x91,  0x1d,  0x66,  0xfe,
+  0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x03,  0xae,  0x21,  0xfe,  0xe6,  0x15,  0xfe,  0xda,  0x10,  0x17,  0x10,
+  0x71,  0x05,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x19,  0xfe,  0x18,  0x58,  0x05,  0xfe,  0x66,  0x01,
+  0xfe,  0x19,  0x58,  0x91,  0x19,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x06,  0xfe,  0x3c,  0x50,  0x66,
+  0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x19,  0x90,  0xfe,  0x40,  0x16,  0xfe,  0xb6,
+  0x14,  0x34,  0x03,  0xae,  0x21,  0xfe,  0x18,  0x16,  0xfe,  0x9c,  0x10,  0x17,  0x10,  0x71,  0xfe,  0x83,
+  0x5a,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x1d,  0xf7,  0x38,  0x90,  0xfe,  0x62,  0x16,  0xfe,
+  0x94,  0x14,  0xfe,  0x10,  0x13,  0x91,  0x38,  0x66,  0x1b,  0xfe,  0xaf,  0x19,  0xfe,  0x98,  0xe7,  0x00,
+  0x03,  0xae,  0x21,  0xfe,  0x56,  0x16,  0xfe,  0x6c,  0x10,  0x17,  0x10,  0x71,  0xfe,  0x30,  0xbc,  0xfe,
+  0xb2,  0xbc,  0x91,  0xc5,  0x66,  0x1b,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0xc5,  0x90,  0xfe,  0x9a,
+  0x16,  0xfe,  0x5c,  0x14,  0x34,  0x03,  0xae,  0x21,  0xfe,  0x86,  0x16,  0xfe,  0x42,  0x10,  0xfe,  0x02,
+  0xf6,  0x10,  0x71,  0xfe,  0x18,  0xfe,  0x54,  0xfe,  0x19,  0xfe,  0x55,  0xfc,  0xfe,  0x1d,  0xf7,  0x4f,
+  0x90,  0xfe,  0xc0,  0x16,  0xfe,  0x36,  0x14,  0xfe,  0x1c,  0x13,  0x91,  0x4f,  0x47,  0xfe,  0x83,  0x58,
+  0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x10,  0xfe,  0x81,  0xe7,  0x10,  0x11,  0xfe,  0xdd,  0x00,  0x63,
+  0x27,  0x03,  0x63,  0x27,  0xfe,  0x12,  0x45,  0x21,  0xfe,  0xb0,  0x16,  0x14,  0x06,  0x37,  0x95,  0xa9,
+  0x02,  0x29,  0xfe,  0x39,  0xf0,  0xfe,  0x04,  0x17,  0x23,  0x03,  0xfe,  0x7e,  0x18,  0x1c,  0x1a,  0x5d,
+  0x13,  0x0d,  0x03,  0x71,  0x05,  0xcb,  0x1c,  0x06,  0xfe,  0xef,  0x12,  0xfe,  0xe1,  0x10,  0x78,  0x2c,
+  0x46,  0x2f,  0x07,  0x2d,  0xfe,  0x3c,  0x13,  0xfe,  0x82,  0x14,  0xfe,  0x42,  0x13,  0x3c,  0x8a,  0x0a,
+  0x42,  0x01,  0x0e,  0xb0,  0xfe,  0x3e,  0x12,  0xf0,  0xfe,  0x45,  0x48,  0x01,  0xe3,  0xfe,  0x00,  0xcc,
+  0xb0,  0xfe,  0xf3,  0x13,  0x3d,  0x75,  0x07,  0x10,  0xa3,  0x0a,  0x80,  0x01,  0x0e,  0xf2,  0x01,  0x6f,
+  0xfe,  0x16,  0x10,  0x07,  0x7e,  0x85,  0xfe,  0x40,  0x14,  0xfe,  0x24,  0x12,  0xf6,  0xfe,  0xd6,  0xf0,
+  0xfe,  0x24,  0x17,  0x17,  0x0b,  0x03,  0xfe,  0x9c,  0xe7,  0x0b,  0x0f,  0xfe,  0x15,  0x00,  0x59,  0x76,
+  0x27,  0x01,  0xda,  0x17,  0x06,  0x03,  0x3c,  0x8a,  0x09,  0x4a,  0x1d,  0x35,  0x11,  0x2d,  0x01,  0x6f,
+  0x17,  0x06,  0x03,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,  0x79,  0xc7,  0x68,  0xc8,  0xfe,  0x48,  0x55,
+  0x34,  0xfe,  0xc9,  0x55,  0x03,  0x1e,  0x98,  0x73,  0x12,  0x98,  0x03,  0x0a,  0x99,  0x01,  0x0e,  0xf0,
+  0x0a,  0x40,  0x01,  0x0e,  0xfe,  0x49,  0x44,  0x16,  0xfe,  0xf0,  0x17,  0x73,  0x75,  0x03,  0x0a,  0x42,
+  0x01,  0x0e,  0x07,  0x10,  0x45,  0x0a,  0x51,  0x01,  0x9e,  0x0a,  0x40,  0x01,  0x0e,  0x73,  0x75,  0x03,
+  0xfe,  0x4e,  0xe4,  0x1a,  0x64,  0xfe,  0x24,  0x18,  0x05,  0xfe,  0x90,  0x00,  0xfe,  0x3a,  0x45,  0x5b,
+  0xfe,  0x4e,  0xe4,  0xc2,  0x64,  0xfe,  0x36,  0x18,  0x05,  0xfe,  0x92,  0x00,  0xfe,  0x02,  0xe6,  0x1b,
+  0xdc,  0xfe,  0x4e,  0xe4,  0xfe,  0x0b,  0x00,  0x64,  0xfe,  0x48,  0x18,  0x05,  0xfe,  0x94,  0x00,  0xfe,
+  0x02,  0xe6,  0x19,  0xfe,  0x08,  0x10,  0x05,  0xfe,  0x96,  0x00,  0xfe,  0x02,  0xe6,  0x2c,  0xfe,  0x4e,
+  0x45,  0xfe,  0x0c,  0x12,  0xaf,  0xff,  0x04,  0x68,  0x54,  0xde,  0x1c,  0x69,  0x03,  0x07,  0x7a,  0xfe,
+  0x5a,  0xf0,  0xfe,  0x74,  0x18,  0x24,  0xfe,  0x09,  0x00,  0xfe,  0x34,  0x10,  0x07,  0x1b,  0xfe,  0x5a,
+  0xf0,  0xfe,  0x82,  0x18,  0x24,  0xc3,  0xfe,  0x26,  0x10,  0x07,  0x1a,  0x5d,  0x24,  0x2c,  0xdc,  0x07,
+  0x0b,  0x5d,  0x24,  0x93,  0xfe,  0x0e,  0x10,  0x07,  0x06,  0x5d,  0x24,  0x4d,  0x9f,  0xad,  0x03,  0x14,
+  0xfe,  0x09,  0x00,  0x01,  0x33,  0xfe,  0x04,  0xfe,  0x7d,  0x05,  0x7f,  0xf9,  0x03,  0x25,  0xfe,  0xca,
+  0x18,  0xfe,  0x14,  0xf0,  0x08,  0x65,  0xfe,  0xc6,  0x18,  0x03,  0xff,  0x1a,  0x00,  0x00,
 };
 
 STATIC unsigned short _adv_asc3550_size =
-    sizeof(_adv_asc3550_buf); /* 0x13E5 */
+        sizeof(_adv_asc3550_buf); /* 0x13AD */
 STATIC ADV_DCNT _adv_asc3550_chksum =
-    0x04FFFF0E; /* Expanded checksum. */
+        0x04D52DDDUL; /* Expanded little-endian checksum. */
 
+/* Microcode buffer is kept after initialization for error recovery. */
 STATIC unsigned char _adv_asc38C0800_buf[] = {
-  0x00,  0x00,  0x00,  0xf2,  0x00,  0xf0,  0x00,  0x16,  0x00,  0xfc,  0x48,  0xe4,  0x01,  0x00,  0x18,  0xe4,
-  0x00,  0xf6,  0x01,  0xf6,  0x18,  0x80,  0x02,  0x00,  0x40,  0x1a,  0x00,  0xfa,  0xff,  0xff,  0x03,  0xf6,
-  0xff,  0x00,  0x82,  0xe7,  0x01,  0xfa,  0x9e,  0xe7,  0x09,  0xe7,  0x1a,  0x0f,  0x00,  0xea,  0x01,  0xe6,
-  0x03,  0x00,  0x55,  0xf0,  0x18,  0xf4,  0x1e,  0xf0,  0x3e,  0x57,  0x04,  0x00,  0x3e,  0x01,  0x85,  0xf0,
-  0x00,  0xe6,  0x03,  0xfc,  0x08,  0x00,  0x2c,  0x1a,  0x32,  0xf0,  0x86,  0xf0,  0xbe,  0x0d,  0xd4,  0x01,
-  0xd5,  0xf0,  0x00,  0xec,  0x01,  0xfc,  0x38,  0x54,  0x98,  0x57,  0xbc,  0x00,  0x0c,  0x1c,  0xb1,  0xf0,
-  0x3c,  0x00,  0xb4,  0x00,  0xb8,  0x0d,  0x00,  0x57,  0x01,  0xf0,  0x02,  0x13,  0x02,  0xfc,  0x03,  0xe6,
-  0x10,  0x00,  0x18,  0x40,  0x3e,  0x1c,  0x44,  0x13,  0x6c,  0x01,  0x6e,  0x01,  0xbd,  0x00,  0xe0,  0x00,
-  0x02,  0x80,  0x30,  0xe4,  0x3e,  0x00,  0x74,  0x01,  0x76,  0x01,  0x7c,  0x16,  0x80,  0x00,  0xb9,  0x54,
-  0xbb,  0x00,  0xee,  0x13,  0x00,  0x4e,  0x01,  0x01,  0x01,  0xea,  0x02,  0x48,  0x02,  0xfa,  0x04,  0x12,
-  0x08,  0x12,  0x3c,  0x56,  0x4e,  0x01,  0x5d,  0xf0,  0x7a,  0x01,  0x7e,  0x10,  0xb6,  0x00,  0xc2,  0x10,
-  0xee,  0x08,  0x00,  0x80,  0x05,  0xfc,  0x10,  0x44,  0x24,  0x01,  0x28,  0x01,  0x32,  0x00,  0x3c,  0x01,
-  0x40,  0x00,  0x4b,  0xe4,  0x4b,  0xf4,  0x4c,  0x1c,  0x68,  0x01,  0x6a,  0x01,  0x70,  0x01,  0x72,  0x01,
-  0x78,  0x01,  0x7c,  0x01,  0xbb,  0x55,  0xc2,  0x0d,  0x00,  0x01,  0x02,  0xee,  0x03,  0x58,  0x03,  0xf7,
-  0x03,  0xfa,  0x04,  0x80,  0x08,  0x44,  0x09,  0xf0,  0x0f,  0x00,  0x1b,  0x80,  0x20,  0x01,  0x38,  0x1c,
-  0x4e,  0x1c,  0x5b,  0xf0,  0x62,  0x0a,  0xaa,  0x00,  0xbe,  0x00,  0xc0,  0x00,  0xc0,  0x15,  0xcc,  0x10,
-  0x00,  0x4c,  0x00,  0xdc,  0x02,  0x4a,  0x04,  0xfc,  0x05,  0x00,  0x05,  0xf0,  0x05,  0xf8,  0x06,  0x13,
-  0x06,  0xf7,  0x08,  0x13,  0x0a,  0x10,  0x0c,  0x00,  0x0e,  0x47,  0x0e,  0xf7,  0x10,  0x0f,  0x20,  0x00,
-  0x20,  0x16,  0x2a,  0x01,  0x32,  0x1c,  0x36,  0x00,  0x42,  0x54,  0x44,  0x55,  0x45,  0x5a,  0x52,  0x0c,
-  0x59,  0xf0,  0x5c,  0xf0,  0x69,  0x08,  0x6e,  0x0b,  0x83,  0x59,  0xb8,  0xf0,  0xbd,  0x56,  0xcc,  0x18,
-  0xce,  0x10,  0xd8,  0x18,  0xf0,  0x00,  0x01,  0x48,  0x04,  0x10,  0x04,  0xea,  0x04,  0xf6,  0x05,  0x80,
-  0x05,  0xe6,  0x06,  0x00,  0x06,  0x0f,  0x06,  0x12,  0x0b,  0xf0,  0x0c,  0x10,  0x0c,  0xf0,  0x10,  0x13,
-  0x12,  0x10,  0x19,  0x00,  0x19,  0xe4,  0x30,  0x1c,  0x33,  0x00,  0x34,  0x00,  0x38,  0x44,  0x40,  0x5c,
-  0x4a,  0xe4,  0x62,  0x1a,  0x68,  0x08,  0x68,  0x54,  0x6c,  0x15,  0x70,  0x15,  0x83,  0x55,  0x83,  0x5a,
-  0x91,  0x44,  0xa4,  0x00,  0xac,  0x13,  0xb0,  0x57,  0xb5,  0x00,  0xb8,  0x17,  0xba,  0x00,  0xce,  0x45,
-  0xd0,  0x00,  0xe1,  0x00,  0xe5,  0x55,  0xe7,  0x00,  0x00,  0x54,  0x01,  0x58,  0x02,  0x10,  0x02,  0xe6,
-  0x03,  0xa1,  0x04,  0x13,  0x06,  0x83,  0x06,  0xf0,  0x07,  0x00,  0x0a,  0x00,  0x0a,  0x12,  0x0a,  0xf0,
-  0x0c,  0x12,  0x0c,  0x13,  0x0c,  0x90,  0x0e,  0x13,  0x10,  0x04,  0x10,  0x10,  0x12,  0x1c,  0x19,  0x81,
-  0x1a,  0x10,  0x1c,  0x00,  0x1c,  0x12,  0x1d,  0xf7,  0x1e,  0x13,  0x20,  0x1c,  0x20,  0xe7,  0x22,  0x01,
-  0x26,  0x01,  0x2a,  0x12,  0x2c,  0x0f,  0x30,  0xe7,  0x32,  0x15,  0x34,  0x1c,  0x36,  0x1c,  0x38,  0x12,
-  0x3a,  0x55,  0x3f,  0x00,  0x41,  0x58,  0x43,  0x48,  0x46,  0x1c,  0x4e,  0xe4,  0x76,  0x02,  0x77,  0x57,
-  0x78,  0x03,  0x89,  0x48,  0x8e,  0x90,  0x98,  0x80,  0x99,  0x00,  0xfe,  0x9c,  0xf0,  0x27,  0x02,  0xfe,
-  0xe0,  0x0d,  0xff,  0x10,  0x00,  0x00,  0xfe,  0xc6,  0x01,  0xfe,  0x56,  0x1a,  0x00,  0xfe,  0xc4,  0x01,
-  0xfe,  0x84,  0x01,  0xff,  0x03,  0x00,  0x00,  0xfe,  0x6a,  0x13,  0xfe,  0x05,  0x05,  0xff,  0x40,  0x00,
-  0x00,  0x0e,  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,  0x01,  0x01,  0xff,  0x10,  0xff,  0xff,  0xff,  0x1f,
-  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,  0xff,  0x11,  0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,
-  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xfe,  0xc4,  0x01,  0x2e,  0x88,  0x0b,  0x01,  0xfe,  0xca,
-  0x0f,  0xfe,  0x04,  0xf7,  0xfe,  0xc4,  0x01,  0x88,  0x0b,  0x1c,  0x2e,  0xfe,  0x3d,  0xf0,  0xfe,  0xfc,
-  0x01,  0xfe,  0x20,  0xf0,  0xdc,  0x04,  0x5f,  0x4f,  0x02,  0xfe,  0xfc,  0x0d,  0x01,  0xfe,  0x5c,  0x0e,
-  0xfe,  0xe9,  0x12,  0x02,  0xfe,  0x08,  0x03,  0xfe,  0x28,  0x1c,  0x04,  0xfe,  0xa6,  0x00,  0xfe,  0xdd,
-  0x12,  0x47,  0x12,  0xfe,  0xa6,  0x00,  0xcd,  0xfe,  0x48,  0xf0,  0xfe,  0x80,  0x02,  0xfe,  0x49,  0xf0,
-  0xfe,  0x9a,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xb8,  0x02,  0xfe,  0x46,  0xf0,  0xfe,  0x4a,  0x02,  0xfe,
-  0x47,  0xf0,  0xfe,  0x50,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x3e,  0x02,  0xfe,  0x44,  0xf0,  0xfe,  0x42,
-  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x46,  0x02,  0x09,  0x0b,  0xa4,  0x09,  0x06,  0x12,  0xc1,  0x02,  0x27,
-  0xfe,  0x00,  0x1c,  0xfe,  0xf1,  0x10,  0xfe,  0x02,  0x1c,  0xfe,  0xed,  0x10,  0xfe,  0x1e,  0x1c,  0xfe,
-  0xe9,  0x10,  0x01,  0xfe,  0x2c,  0x18,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xfe,  0xa8,  0x00,  0x0f,
-  0x7c,  0x01,  0xaa,  0x02,  0x27,  0x17,  0x5e,  0x4c,  0xc4,  0x01,  0xfe,  0x40,  0x10,  0x0f,  0x7c,  0x01,
-  0x8e,  0xfe,  0xbd,  0x10,  0x0f,  0x7c,  0x01,  0x8e,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,
-  0x1c,  0x09,  0x06,  0x12,  0xc1,  0x2e,  0x1b,  0x27,  0xfe,  0x3d,  0xf0,  0xfe,  0xfc,  0x01,  0x28,  0xfe,
-  0x8e,  0x02,  0xfe,  0x5a,  0x1c,  0xde,  0xfe,  0x14,  0x1c,  0x17,  0xfe,  0x30,  0x00,  0x4c,  0xc4,  0x01,
-  0xfe,  0x30,  0x10,  0x09,  0x06,  0x12,  0xc1,  0x02,  0xfe,  0xc6,  0x01,  0x29,  0x2d,  0x05,  0x10,  0x35,
-  0xfe,  0x69,  0x10,  0x09,  0x06,  0x12,  0xc1,  0xfe,  0x04,  0xec,  0x2d,  0x08,  0x2d,  0x09,  0x3e,  0x1c,
-  0x01,  0x45,  0x82,  0xfe,  0x05,  0xf6,  0xfe,  0xa8,  0x00,  0x01,  0xfe,  0x56,  0x17,  0x0a,  0x41,  0x8f,
-  0x39,  0x11,  0x48,  0x1c,  0xd2,  0x08,  0x1e,  0x09,  0x52,  0x01,  0x90,  0x02,  0x27,  0x0f,  0x3f,  0x01,
-  0x15,  0x05,  0x10,  0xdb,  0x08,  0x1e,  0x09,  0x52,  0x01,  0x7e,  0xfe,  0x28,  0x10,  0x0f,  0xc8,  0x01,
-  0x15,  0xf2,  0x0f,  0x7d,  0x01,  0x15,  0xfe,  0x49,  0x54,  0x79,  0xfe,  0x16,  0x03,  0x08,  0x1e,  0x09,
-  0x52,  0x01,  0x90,  0x02,  0x27,  0x2e,  0x82,  0xfe,  0x02,  0xe8,  0x31,  0xfe,  0xbf,  0x57,  0xfe,  0x9e,
-  0x43,  0xf7,  0xfe,  0x07,  0x4b,  0xfe,  0x20,  0xf0,  0xdc,  0xfe,  0x40,  0x1c,  0x1b,  0xf8,  0xfe,  0x26,
-  0xf0,  0xfe,  0x74,  0x03,  0xfe,  0xa0,  0xf0,  0xfe,  0x62,  0x03,  0xfe,  0x11,  0xf0,  0xdc,  0xfe,  0x0e,
-  0x10,  0xfe,  0x9f,  0xf0,  0xfe,  0x82,  0x03,  0xf4,  0x13,  0xfe,  0x11,  0x00,  0x02,  0x6b,  0x2e,  0xfe,
-  0x48,  0x1c,  0xf4,  0x1b,  0xf8,  0x34,  0xf8,  0xfe,  0x82,  0xf0,  0xfe,  0x88,  0x03,  0x2b,  0x29,  0xc6,
-  0x72,  0x16,  0xc6,  0x0f,  0x7d,  0x01,  0x15,  0x72,  0x80,  0x08,  0x1e,  0x09,  0x52,  0x01,  0x45,  0x11,
-  0x3f,  0x08,  0x3f,  0x09,  0xa2,  0x01,  0x90,  0xfe,  0x9c,  0x32,  0x11,  0xfe,  0xe4,  0x00,  0x2f,  0xfe,
-  0xce,  0x03,  0x1b,  0x32,  0x1f,  0xfe,  0xde,  0x03,  0x01,  0x55,  0xd3,  0xfe,  0xee,  0x03,  0x73,  0x97,
-  0xd7,  0xfe,  0xae,  0x06,  0x02,  0x26,  0x04,  0x7c,  0x2c,  0x19,  0xfe,  0x20,  0x05,  0x17,  0x8b,  0x01,
-  0x3b,  0x01,  0x9f,  0x01,  0xa1,  0x34,  0xfe,  0x60,  0x02,  0x02,  0xf6,  0xf4,  0x2e,  0x88,  0x18,  0xfe,
-  0x67,  0x1b,  0xfe,  0xbf,  0x57,  0xf7,  0xfe,  0x48,  0x1c,  0x92,  0x01,  0xfe,  0x9c,  0x13,  0xb3,  0xfe,
-  0x96,  0xf0,  0xfe,  0x28,  0x04,  0x2f,  0xfe,  0x2c,  0x04,  0x34,  0x27,  0x0f,  0x3f,  0x01,  0x15,  0x05,
-  0x10,  0x19,  0xfe,  0x0c,  0x05,  0x4d,  0x7a,  0xa5,  0x31,  0x86,  0x76,  0x1b,  0x32,  0x1f,  0x26,  0x04,
-  0x7c,  0x2c,  0xfe,  0x10,  0x12,  0x17,  0x8b,  0x01,  0x3b,  0x34,  0xfe,  0x60,  0x02,  0x02,  0xf6,  0x21,
-  0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x5e,  0x12,  0x0a,  0x07,  0x06,  0xfe,  0x56,  0x12,  0x24,
-  0x23,  0x9a,  0x01,  0x0c,  0x86,  0x76,  0x1f,  0xfe,  0xdc,  0x04,  0x24,  0x23,  0x9a,  0x01,  0x0c,  0x1f,
-  0x26,  0x24,  0x23,  0xba,  0xfe,  0x4c,  0x44,  0xfe,  0x32,  0x12,  0x51,  0xfe,  0x44,  0x48,  0x08,  0xfe,
-  0x93,  0x00,  0xfe,  0x4c,  0x54,  0x79,  0xfe,  0x0c,  0x05,  0x82,  0xa5,  0x31,  0xfe,  0x06,  0x80,  0xfe,
-  0x48,  0x47,  0xfe,  0x48,  0x13,  0x40,  0x05,  0xfe,  0xcc,  0x00,  0xfe,  0x40,  0x13,  0x0a,  0x07,  0x06,
-  0xef,  0xfe,  0x06,  0x10,  0x24,  0x23,  0xba,  0x0a,  0x07,  0x38,  0xe2,  0x17,  0xa9,  0x0a,  0x07,  0x06,
-  0x4f,  0x17,  0xfe,  0x0d,  0x00,  0x01,  0x3b,  0x34,  0xfe,  0xa0,  0x0d,  0x02,  0x26,  0x3a,  0x11,  0xfe,
-  0xe6,  0x00,  0xfe,  0x1c,  0x90,  0xb7,  0x03,  0x17,  0xa9,  0x01,  0x3b,  0x34,  0x27,  0x1b,  0x27,  0x02,
-  0xfe,  0x14,  0x05,  0xfe,  0x42,  0x5b,  0x88,  0x18,  0xfe,  0x46,  0x59,  0xfe,  0xbf,  0x57,  0xf7,  0x17,
-  0x46,  0xfe,  0x07,  0x80,  0xfe,  0x31,  0x44,  0x0a,  0x07,  0x0b,  0xfe,  0x78,  0x13,  0xfe,  0x20,  0x80,
-  0x05,  0x18,  0xfe,  0x70,  0x12,  0x75,  0x07,  0x06,  0xfe,  0x60,  0x13,  0x04,  0xfe,  0xa2,  0x00,  0x2c,
-  0x19,  0xfe,  0xac,  0x05,  0xfe,  0x31,  0xe4,  0x60,  0x75,  0x07,  0x0b,  0xfe,  0x4a,  0x13,  0x04,  0xfe,
-  0xa0,  0x00,  0x2c,  0xfe,  0x42,  0x12,  0x63,  0x2f,  0xfe,  0x6c,  0x05,  0x1b,  0x32,  0xf9,  0x01,  0x0c,
-  0x25,  0xfe,  0xc4,  0x05,  0x11,  0xfe,  0xe3,  0x00,  0x2b,  0x75,  0xfe,  0x4a,  0xf0,  0xfe,  0x96,  0x05,
-  0xfe,  0x49,  0xf0,  0xfe,  0x90,  0x05,  0xad,  0x20,  0xfe,  0x21,  0x00,  0x8a,  0x20,  0xfe,  0x22,  0x00,
-  0xa4,  0x20,  0x8f,  0xfe,  0x09,  0x48,  0x01,  0x0c,  0x25,  0xfe,  0xc4,  0x05,  0xfe,  0xe2,  0x08,  0x75,
-  0x07,  0xe1,  0x4f,  0x01,  0xc2,  0x20,  0x06,  0x16,  0xe8,  0x4c,  0xfe,  0x27,  0x01,  0x0a,  0x07,  0x38,
-  0xe9,  0x47,  0x01,  0xbd,  0x17,  0xa9,  0x0a,  0x07,  0x06,  0x4f,  0x17,  0xfe,  0x0d,  0x00,  0x01,  0x3b,
-  0x01,  0x9f,  0x01,  0xa1,  0x34,  0xfe,  0xa0,  0x0d,  0x02,  0x26,  0x04,  0xfe,  0x9c,  0x00,  0x2c,  0xfe,
-  0x3e,  0x12,  0x04,  0x5c,  0x2c,  0xfe,  0x36,  0x13,  0x47,  0x01,  0xbd,  0x25,  0xfe,  0x3c,  0x06,  0x0f,
-  0x06,  0x75,  0x07,  0x22,  0xfe,  0x02,  0x12,  0x6a,  0x01,  0xfe,  0x06,  0x15,  0x1f,  0xfe,  0x32,  0x06,
-  0x11,  0xc9,  0x01,  0x55,  0x11,  0xfe,  0xe5,  0x00,  0x04,  0x5c,  0xc3,  0x0d,  0x5c,  0x04,  0xfe,  0x9e,
-  0x00,  0x2c,  0xfe,  0x62,  0x12,  0x04,  0x56,  0x2c,  0xfe,  0x5a,  0x13,  0x01,  0xfe,  0x7e,  0x19,  0x01,
-  0xfe,  0xe8,  0x19,  0xf3,  0xa8,  0xf1,  0x08,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x6e,  0x81,  0x1a,  0x59,
-  0xd1,  0xa8,  0x74,  0x47,  0x01,  0xbd,  0x25,  0xfe,  0xa6,  0x06,  0x75,  0x07,  0x1d,  0xab,  0x9e,  0x0f,
-  0x5e,  0x01,  0xfe,  0x34,  0x15,  0x1f,  0xfe,  0x9c,  0x06,  0x11,  0xc9,  0x01,  0x55,  0x11,  0xfe,  0xe5,
-  0x00,  0x04,  0x56,  0xc3,  0x0d,  0x56,  0x09,  0x06,  0x01,  0xbd,  0xfe,  0x9c,  0x32,  0x78,  0x92,  0x01,
-  0xfe,  0x9c,  0x13,  0xb3,  0x11,  0xfe,  0xe2,  0x00,  0x2f,  0xfe,  0xbe,  0x06,  0x1b,  0x32,  0xd7,  0xfe,
-  0xda,  0x06,  0x85,  0xfe,  0x78,  0x07,  0xd3,  0xfe,  0x80,  0x07,  0x73,  0x97,  0x02,  0x26,  0x0a,  0x07,
-  0x0b,  0xfe,  0x2e,  0x12,  0x14,  0x18,  0x01,  0x0c,  0x14,  0x00,  0x01,  0x0c,  0x14,  0x00,  0x01,  0x0c,
-  0x14,  0x00,  0x01,  0x0c,  0xfe,  0x99,  0xa4,  0x01,  0x0c,  0x14,  0x00,  0x02,  0xfe,  0x50,  0x08,  0x71,
-  0x07,  0x1d,  0xef,  0x0a,  0x07,  0x1d,  0xfe,  0x30,  0x13,  0x14,  0xfe,  0x1b,  0x00,  0x01,  0x0c,  0x14,
-  0x00,  0x01,  0x0c,  0x14,  0x00,  0x01,  0x0c,  0x14,  0x00,  0x01,  0x0c,  0x14,  0x06,  0x01,  0x0c,  0x14,
-  0x00,  0x02,  0xfe,  0x0a,  0x0c,  0x6a,  0xfe,  0x9a,  0x81,  0x6f,  0x8f,  0xfe,  0x09,  0x6f,  0xfe,  0x93,
-  0x45,  0x19,  0xfe,  0x88,  0x07,  0x2f,  0xfe,  0x60,  0x07,  0x1b,  0x32,  0xd7,  0xfe,  0x58,  0x07,  0x73,
-  0x97,  0x85,  0xfe,  0x78,  0x07,  0x02,  0x26,  0x01,  0x55,  0x02,  0xfe,  0xbe,  0x06,  0x14,  0x22,  0x02,
-  0xfe,  0xbe,  0x06,  0xfe,  0x9c,  0xf7,  0xfe,  0xf0,  0x07,  0xfe,  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x53,
-  0xfe,  0xd6,  0x07,  0x0d,  0x66,  0x12,  0x67,  0x0a,  0x41,  0x60,  0x39,  0x01,  0xfe,  0x14,  0x19,  0x05,
-  0x10,  0x87,  0xfe,  0x83,  0xe7,  0xfe,  0x95,  0x00,  0x8a,  0xfe,  0x03,  0x40,  0x0a,  0x41,  0x46,  0x39,
-  0x01,  0xc5,  0xb6,  0xfe,  0x1f,  0x40,  0x16,  0x68,  0x01,  0xfe,  0xbe,  0x13,  0xfe,  0x08,  0x50,  0xfe,
-  0x8a,  0x50,  0xfe,  0x34,  0x51,  0xfe,  0xb6,  0x51,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,  0x0d,  0x64,
-  0x12,  0x65,  0xda,  0xfa,  0x0d,  0x3c,  0x12,  0x3d,  0xfe,  0x60,  0x10,  0x0a,  0x07,  0x60,  0xe9,  0xfe,
-  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x0d,  0x66,  0x12,  0x67,  0x0a,  0x07,  0x46,  0xd1,  0x01,  0xc5,  0xfe,
-  0x1f,  0x80,  0x16,  0x68,  0xfe,  0x34,  0x90,  0xfe,  0xb6,  0x90,  0x0d,  0x43,  0x12,  0x44,  0xfe,  0x08,
-  0x90,  0xfe,  0x8a,  0x90,  0x0d,  0x64,  0x12,  0x65,  0xa7,  0x07,  0x46,  0xdb,  0xda,  0xfa,  0x0d,  0x3c,
-  0x12,  0x3d,  0xad,  0xfe,  0x28,  0x90,  0xfe,  0xaa,  0x90,  0x0d,  0x3c,  0x12,  0x3d,  0x0d,  0x30,  0x12,
-  0x42,  0x2b,  0x0d,  0x54,  0x0d,  0x69,  0x0a,  0x41,  0x22,  0x39,  0x2e,  0x08,  0x84,  0x2f,  0xfe,  0x70,
-  0x08,  0xfe,  0x9e,  0xf0,  0xfe,  0x84,  0x08,  0xa3,  0x19,  0x32,  0x2e,  0x5b,  0xfe,  0xed,  0x10,  0xac,
-  0xfe,  0xa8,  0x08,  0xae,  0xfe,  0xc4,  0x08,  0x85,  0xfe,  0x9c,  0x08,  0xd3,  0xfe,  0xa2,  0x08,  0x73,
-  0x97,  0x02,  0x26,  0x01,  0x55,  0xfe,  0xc9,  0x10,  0x14,  0x22,  0xfe,  0xc9,  0x10,  0x71,  0x07,  0x06,
-  0xfe,  0x10,  0x12,  0x71,  0x07,  0x0b,  0x50,  0x0a,  0x07,  0x0b,  0xfe,  0xa6,  0x12,  0xfe,  0x2e,  0x1c,
-  0xb0,  0x71,  0x07,  0x06,  0x50,  0x71,  0x07,  0x0b,  0xfe,  0x92,  0x12,  0xfe,  0x2c,  0x1c,  0xa7,  0x07,
-  0x46,  0xaf,  0xa7,  0x41,  0x46,  0xfe,  0x05,  0x40,  0xda,  0xfa,  0xfe,  0x28,  0x50,  0xfe,  0xaa,  0x50,
-  0xfe,  0xaa,  0xf0,  0xfe,  0xf6,  0x09,  0xfe,  0xac,  0xf0,  0xfe,  0x24,  0x09,  0x02,  0xfe,  0x02,  0x0a,
-  0xfe,  0xb7,  0xf0,  0xfe,  0x20,  0x09,  0xfe,  0x02,  0xf6,  0x1d,  0x6a,  0xfe,  0x70,  0x18,  0xfe,  0xf1,
-  0x18,  0xfe,  0x40,  0x55,  0xfe,  0xe1,  0x55,  0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,  0xfe,  0x14,  0x59,
-  0xfe,  0x95,  0x59,  0x1b,  0x9b,  0xfe,  0x8c,  0xf0,  0xfe,  0x20,  0x09,  0xfe,  0xac,  0xf0,  0xfe,  0x14,
-  0x09,  0xed,  0xfe,  0xcb,  0x10,  0xfe,  0xad,  0xf0,  0xfe,  0x30,  0x09,  0x02,  0xfe,  0x3c,  0x0b,  0xee,
-  0xfe,  0xbf,  0x10,  0xfe,  0x2b,  0xf0,  0x9b,  0xfe,  0x6b,  0x18,  0x1a,  0xfe,  0x00,  0xfe,  0xe2,  0xcd,
-  0xfe,  0xd2,  0xf0,  0x9b,  0xfe,  0x76,  0x18,  0x1a,  0x18,  0x19,  0x9b,  0x04,  0xe7,  0x1a,  0x06,  0x19,
-  0x9b,  0xac,  0x58,  0xae,  0x58,  0xed,  0xee,  0xfe,  0x89,  0x10,  0x92,  0x63,  0x3a,  0x17,  0xa9,  0x01,
-  0x3b,  0x13,  0xfe,  0x35,  0x00,  0x34,  0x6b,  0x13,  0x93,  0x02,  0x6b,  0xfb,  0xb2,  0x0b,  0xfe,  0x1a,
-  0x12,  0x51,  0xfe,  0x19,  0x82,  0xfe,  0x6c,  0x18,  0xfe,  0x44,  0x54,  0xf0,  0xdf,  0xfe,  0x74,  0x18,
-  0x94,  0x95,  0x19,  0xfe,  0xf2,  0x08,  0x02,  0x58,  0x0a,  0x07,  0x60,  0xaf,  0x04,  0x30,  0x2a,  0x42,
-  0x0d,  0x43,  0x12,  0x44,  0x83,  0x30,  0x5a,  0x42,  0xfe,  0x6c,  0x18,  0xfe,  0xed,  0x18,  0xfe,  0x44,
-  0x54,  0xfe,  0xe5,  0x54,  0x36,  0x43,  0x21,  0x44,  0x04,  0x54,  0x2a,  0x69,  0x94,  0xfe,  0xe3,  0x54,
-  0xfe,  0x74,  0x18,  0xfe,  0xf5,  0x18,  0x94,  0xfe,  0xe3,  0x54,  0x95,  0xca,  0x53,  0xfe,  0xf2,  0x08,
-  0x02,  0x58,  0xfe,  0x37,  0xf0,  0xfe,  0xfe,  0x09,  0xfe,  0x8b,  0xf0,  0xfe,  0x84,  0x09,  0x02,  0x58,
-  0xfb,  0xb2,  0x0b,  0x28,  0xfe,  0x1e,  0x0b,  0x36,  0x54,  0x21,  0x69,  0x53,  0x7a,  0x08,  0xfe,  0xc0,
-  0x07,  0x47,  0x62,  0x00,  0xd9,  0xfe,  0x01,  0x59,  0xfe,  0x52,  0xf0,  0xfe,  0x30,  0x0a,  0x94,  0x99,
-  0xfe,  0x48,  0x0a,  0x36,  0x54,  0x94,  0xfe,  0xe3,  0x54,  0x4e,  0x54,  0x70,  0x69,  0xfe,  0x14,  0x58,
-  0xfe,  0x95,  0x58,  0x02,  0x58,  0x36,  0x54,  0x21,  0x69,  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0xf0,
-  0x4e,  0x54,  0x4e,  0x69,  0x02,  0x58,  0x0a,  0x07,  0x60,  0xfe,  0x82,  0x12,  0x0a,  0x07,  0x22,  0xfe,
-  0x66,  0x13,  0x29,  0x68,  0x72,  0xd0,  0xfe,  0x83,  0x80,  0xfe,  0xc8,  0x44,  0xfe,  0x2e,  0x13,  0xfe,
-  0x04,  0x91,  0xfe,  0x86,  0x91,  0x6d,  0x31,  0xfe,  0x40,  0x59,  0xfe,  0xc1,  0x59,  0x53,  0xfe,  0xfa,
-  0x08,  0x04,  0x66,  0x2a,  0x67,  0x0d,  0xb5,  0x12,  0x93,  0x4e,  0x66,  0x70,  0x67,  0x01,  0xc5,  0xb6,
-  0x6d,  0x31,  0x16,  0x68,  0x83,  0x30,  0x5a,  0x42,  0x36,  0x43,  0x21,  0x44,  0x95,  0xca,  0xfe,  0x04,
-  0xfa,  0x30,  0xfe,  0x05,  0xfa,  0x42,  0x01,  0xfe,  0xbe,  0x13,  0xfe,  0x36,  0x10,  0x2b,  0x0d,  0xb5,
-  0x0d,  0x93,  0x36,  0x43,  0x21,  0x44,  0xb0,  0x0a,  0x07,  0x22,  0x19,  0xfe,  0xfa,  0x08,  0x36,  0x3c,
-  0x21,  0x3d,  0x0a,  0x07,  0xfe,  0xf7,  0x00,  0x39,  0x04,  0x64,  0x2a,  0x65,  0xfe,  0x10,  0x58,  0xfe,
-  0x91,  0x58,  0x4e,  0x54,  0x70,  0x69,  0x02,  0xfe,  0x18,  0x0a,  0x0a,  0x07,  0x22,  0x19,  0xfe,  0xfa,
-  0x08,  0x0a,  0x07,  0xfe,  0xf7,  0x00,  0x39,  0xf0,  0xdf,  0x6a,  0xfe,  0x10,  0x90,  0xfe,  0x92,  0x90,
-  0xfe,  0xd3,  0x10,  0x40,  0x05,  0xcb,  0x19,  0xfe,  0x2c,  0x09,  0x11,  0xcb,  0xfb,  0xb2,  0x0b,  0xfe,
-  0x14,  0x13,  0x04,  0x3c,  0x2a,  0x3d,  0x53,  0xfe,  0x2c,  0x09,  0xfe,  0x0c,  0x58,  0xfe,  0x8d,  0x58,
-  0x02,  0x58,  0x2b,  0x47,  0xfe,  0x19,  0x80,  0xfe,  0xf1,  0x10,  0x0a,  0x07,  0x0b,  0xab,  0xfe,  0x6c,
-  0x19,  0xfe,  0x19,  0x41,  0xfe,  0x8e,  0x10,  0xfe,  0x6c,  0x19,  0x4e,  0x3c,  0xfe,  0xed,  0x19,  0x70,
-  0x3d,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0xfe,  0x6b,  0x18,  0x1a,  0xfe,  0x00,  0xff,  0x35,  0xfe,
-  0x74,  0x10,  0xcd,  0xfe,  0xd2,  0xf0,  0xfe,  0xb6,  0x0b,  0xfe,  0x76,  0x18,  0x1a,  0x18,  0xd6,  0x04,
-  0xe7,  0x1a,  0x06,  0x89,  0x13,  0xfe,  0x16,  0x00,  0x02,  0x6b,  0xfe,  0xd1,  0xf0,  0xfe,  0xc8,  0x0b,
-  0x17,  0x84,  0x01,  0x3b,  0x13,  0xfe,  0x17,  0x00,  0xfe,  0x42,  0x10,  0xfe,  0xce,  0xf0,  0xfe,  0xce,
-  0x0b,  0xfe,  0x3c,  0x10,  0xfe,  0xcd,  0xf0,  0xfe,  0xda,  0x0b,  0x13,  0xfe,  0x22,  0x00,  0x02,  0x6b,
-  0xfe,  0xcb,  0xf0,  0xfe,  0xe6,  0x0b,  0x13,  0xfe,  0x24,  0x00,  0x02,  0x6b,  0xfe,  0xd0,  0xf0,  0xfe,
-  0xf0,  0x0b,  0x13,  0xb1,  0xe0,  0xfe,  0xcf,  0xf0,  0xfe,  0xfa,  0x0b,  0x13,  0x8f,  0xdd,  0xfe,  0xcc,
-  0xf0,  0xfe,  0x0a,  0x0c,  0xfe,  0x84,  0x80,  0xb2,  0x22,  0x4f,  0x13,  0xfe,  0x12,  0x00,  0x2e,  0x08,
-  0x84,  0x2f,  0xfe,  0x10,  0x0c,  0xfe,  0x9e,  0xf0,  0xfe,  0x24,  0x0c,  0xa3,  0x19,  0x32,  0x2e,  0x5b,
-  0xfe,  0xed,  0x10,  0xac,  0x26,  0xae,  0x26,  0x2e,  0xfe,  0x9c,  0x32,  0x2f,  0xfe,  0x30,  0x0c,  0x1b,
-  0x32,  0x85,  0xfe,  0x4c,  0x0c,  0x73,  0x97,  0xac,  0xfe,  0xf0,  0x07,  0xae,  0xfe,  0xf0,  0x07,  0x02,
-  0x26,  0x01,  0x55,  0xfe,  0xdb,  0x10,  0x11,  0xfe,  0xe8,  0x00,  0xed,  0xee,  0x92,  0x86,  0x76,  0xfe,
-  0x89,  0xf0,  0x26,  0x24,  0x23,  0xfe,  0xe9,  0x09,  0x01,  0x0c,  0x86,  0x76,  0x1f,  0x26,  0x24,  0x23,
-  0x9a,  0x34,  0xfe,  0x88,  0x0c,  0x1b,  0x32,  0x02,  0xfe,  0x7c,  0x0c,  0xa3,  0x50,  0x13,  0xfe,  0x42,
-  0x00,  0x02,  0x6b,  0xa6,  0x06,  0xfe,  0x81,  0x49,  0xfe,  0xcc,  0x12,  0x0a,  0x07,  0x0b,  0xfe,  0x5a,
-  0x13,  0x13,  0x00,  0x61,  0x0b,  0xfe,  0x6a,  0x12,  0x61,  0xfe,  0x28,  0x00,  0x28,  0xfe,  0xce,  0x0d,
-  0x0f,  0x7d,  0x01,  0x15,  0x05,  0x00,  0x89,  0x37,  0xfe,  0x28,  0x00,  0x02,  0xfe,  0xce,  0x0d,  0x01,
-  0x9f,  0x01,  0xa1,  0x0f,  0xc8,  0x01,  0xfe,  0x24,  0x0f,  0xb9,  0x08,  0x3f,  0x09,  0xa2,  0x01,  0x45,
-  0x11,  0x48,  0x08,  0x1e,  0x09,  0x52,  0x01,  0x7e,  0x02,  0x27,  0x13,  0xfe,  0x44,  0x00,  0x61,  0x0b,
-  0xab,  0x37,  0x0b,  0xfe,  0xc0,  0x10,  0x01,  0xc2,  0x37,  0x0b,  0xfe,  0xb6,  0x10,  0x01,  0xc2,  0xfe,
-  0x19,  0x82,  0xfe,  0x34,  0x46,  0xfe,  0x0a,  0x13,  0x37,  0x0b,  0x13,  0xfe,  0x43,  0x00,  0xfe,  0xa2,
-  0x10,  0x0a,  0x41,  0x0b,  0x39,  0x01,  0x9f,  0x01,  0xa1,  0xb9,  0x08,  0x3f,  0x09,  0xa2,  0x01,  0x45,
-  0x11,  0x48,  0x08,  0x1e,  0x09,  0x52,  0x01,  0x7e,  0x88,  0x0b,  0xb9,  0x1c,  0xd2,  0x02,  0xfe,  0x4c,
-  0x03,  0x0a,  0x07,  0x0b,  0xd6,  0x37,  0x0b,  0x13,  0x00,  0xfe,  0x54,  0x10,  0x71,  0x07,  0x1d,  0xfe,
-  0x50,  0x12,  0x0a,  0x07,  0x1d,  0xfe,  0x48,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x8c,
-  0x0d,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x92,  0x0d,  0x0a,  0x41,  0x1d,  0x39,  0xfe,  0x95,
-  0x10,  0x13,  0xfe,  0x15,  0x00,  0xfe,  0x04,  0xe6,  0x0b,  0x6a,  0xfe,  0x26,  0x10,  0x13,  0xfe,  0x13,
-  0x00,  0xdd,  0x13,  0xfe,  0x47,  0x00,  0x8a,  0x13,  0xfe,  0x41,  0x00,  0xa4,  0x13,  0xfe,  0x24,  0x00,
-  0x04,  0x7c,  0x2c,  0x28,  0xf6,  0x6a,  0xfe,  0x04,  0xe6,  0x1d,  0xfe,  0x9d,  0x41,  0xfe,  0x1c,  0x42,
-  0xb9,  0x01,  0xea,  0x02,  0x27,  0xde,  0x17,  0x0b,  0x4c,  0xfe,  0x9b,  0x00,  0xe5,  0x17,  0xfe,  0x31,
-  0x00,  0x4c,  0xc4,  0x01,  0xfe,  0x30,  0x10,  0x02,  0xfe,  0xc6,  0x01,  0x1c,  0xfe,  0x06,  0xec,  0xfe,
-  0xb9,  0x00,  0x8c,  0x37,  0x38,  0xc7,  0x35,  0x1c,  0xfe,  0x06,  0xea,  0xfe,  0xb9,  0x00,  0xfe,  0x47,
-  0x4b,  0x9e,  0xfe,  0x75,  0x57,  0x04,  0x5f,  0xfe,  0x98,  0x56,  0xfe,  0x28,  0x12,  0x0f,  0x7d,  0xfe,
-  0xf4,  0x14,  0x47,  0xf2,  0x0f,  0xc8,  0xfe,  0xea,  0x14,  0xfe,  0x49,  0x54,  0x98,  0xfe,  0x42,  0x0e,
-  0x0f,  0x1e,  0xfe,  0xde,  0x14,  0xfe,  0x44,  0x48,  0x02,  0xfe,  0x4c,  0x03,  0x0f,  0x5f,  0xfe,  0xc8,
-  0x14,  0x8c,  0x37,  0x38,  0xc7,  0x35,  0x1c,  0xfe,  0xce,  0x47,  0xfe,  0xbd,  0x13,  0x02,  0x27,  0x29,
-  0x2d,  0x05,  0x10,  0xfe,  0x78,  0x12,  0x2b,  0x16,  0x5e,  0x16,  0xb4,  0x29,  0x48,  0x47,  0x4c,  0x48,
-  0xa3,  0xd9,  0xfe,  0xbc,  0xf0,  0xfe,  0xde,  0x0e,  0x08,  0x06,  0x16,  0x5e,  0x01,  0xfe,  0xe6,  0x16,
-  0x04,  0xfe,  0x38,  0x01,  0x2a,  0xfe,  0x3a,  0x01,  0x53,  0xfe,  0xe2,  0x0e,  0x04,  0xfe,  0x38,  0x01,
-  0x1a,  0xfe,  0xf0,  0xff,  0x0d,  0xfe,  0x60,  0x01,  0x04,  0xfe,  0x3a,  0x01,  0x0d,  0xfe,  0x62,  0x01,
-  0x20,  0x06,  0x16,  0x48,  0xfe,  0x04,  0xec,  0x2d,  0x08,  0x2d,  0x09,  0x3e,  0x1c,  0x01,  0x45,  0x82,
-  0xfe,  0x05,  0xf6,  0xfe,  0x34,  0x01,  0x01,  0xfe,  0x56,  0x17,  0x11,  0x48,  0xd2,  0x08,  0x06,  0x03,
-  0x2b,  0x03,  0x29,  0x5e,  0xfe,  0xf7,  0x12,  0x29,  0xb4,  0x72,  0x16,  0xb4,  0x05,  0x84,  0xfe,  0x93,
-  0x13,  0xfe,  0x24,  0x1c,  0x17,  0x18,  0x4c,  0xfe,  0x9b,  0x00,  0xe5,  0xfe,  0xd9,  0x10,  0x9c,  0xfe,
-  0x03,  0xdc,  0xfe,  0x73,  0x57,  0xfe,  0x80,  0x5d,  0x03,  0x9c,  0xfe,  0x03,  0xdc,  0xfe,  0x5b,  0x57,
-  0xfe,  0x80,  0x5d,  0x03,  0xfe,  0x03,  0x57,  0x9c,  0x2b,  0xfe,  0x00,  0xcc,  0x03,  0xfe,  0x03,  0x57,
-  0x9c,  0x80,  0x03,  0x01,  0xfe,  0x8e,  0x17,  0x40,  0x05,  0x48,  0xfe,  0x0a,  0x13,  0x08,  0x1e,  0x09,
-  0x52,  0xdd,  0x01,  0x9f,  0x01,  0xa1,  0x08,  0x3f,  0x09,  0xa2,  0x01,  0x45,  0x11,  0xfe,  0xe9,  0x00,
-  0x0a,  0x07,  0x8f,  0xfe,  0x52,  0x13,  0x01,  0xfe,  0x18,  0x17,  0xfe,  0x1e,  0x1c,  0xfe,  0x14,  0x90,
-  0x0d,  0xfe,  0x64,  0x01,  0xfe,  0x16,  0x90,  0x0d,  0xfe,  0x66,  0x01,  0x0a,  0x07,  0x46,  0xef,  0xfe,
-  0x03,  0x80,  0x5b,  0x4d,  0x11,  0x7b,  0x08,  0x2d,  0x09,  0x3e,  0x1c,  0x7a,  0x01,  0x90,  0xfe,  0x62,
-  0x08,  0x72,  0x4d,  0x11,  0x7b,  0x08,  0x2d,  0x09,  0x3e,  0x1c,  0x7a,  0x01,  0x90,  0x6d,  0x31,  0x11,
-  0x7b,  0x08,  0x2d,  0x09,  0x3e,  0x1c,  0x7a,  0x01,  0x7e,  0x03,  0xfe,  0x08,  0x1c,  0x04,  0xfe,  0xac,
-  0x00,  0xfe,  0x06,  0x58,  0x04,  0xfe,  0xae,  0x00,  0xfe,  0x07,  0x58,  0x04,  0xfe,  0xb0,  0x00,  0xfe,
-  0x08,  0x58,  0x04,  0xfe,  0xb2,  0x00,  0xfe,  0x09,  0x58,  0xfe,  0x0a,  0x1c,  0x20,  0x74,  0x16,  0xfe,
-  0xb9,  0x00,  0x2b,  0x0d,  0x5c,  0x0d,  0x56,  0x20,  0x10,  0x16,  0x2d,  0x16,  0x3e,  0x51,  0xa6,  0xfe,
-  0x93,  0x00,  0x08,  0x2d,  0x09,  0x3e,  0x1c,  0x01,  0x7e,  0x82,  0x11,  0x7b,  0xfe,  0x14,  0x56,  0xfe,
-  0xd6,  0xf0,  0x8a,  0xde,  0x92,  0xfe,  0x14,  0x1c,  0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x03,  0x1c,
-  0xfe,  0x0c,  0x14,  0x8c,  0xfe,  0x07,  0xe6,  0x38,  0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x03,  0x01,
-  0xc2,  0x0f,  0x3f,  0x01,  0x15,  0x05,  0x10,  0xdb,  0x0f,  0x1e,  0x01,  0x15,  0x05,  0x10,  0xe2,  0xfe,
-  0x44,  0x58,  0x4d,  0xfe,  0x01,  0xec,  0xc4,  0xfe,  0x9e,  0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,
-  0xe7,  0x1d,  0xa5,  0x31,  0x01,  0xea,  0xfe,  0xc9,  0x10,  0x03,  0x2e,  0x86,  0x76,  0x24,  0x23,  0xba,
-  0x05,  0x1d,  0xfe,  0x48,  0x12,  0x05,  0x0b,  0xfe,  0x4c,  0x12,  0x05,  0x18,  0xfe,  0x30,  0x12,  0x05,
-  0xd4,  0x19,  0xfe,  0xd4,  0x11,  0x05,  0xfe,  0x23,  0x00,  0x19,  0xfe,  0xe0,  0x11,  0x05,  0x06,  0x19,
-  0xfe,  0x3e,  0x12,  0x05,  0x22,  0xfe,  0x12,  0x12,  0x05,  0x00,  0x19,  0x26,  0x17,  0xd4,  0x01,  0x3b,
-  0xce,  0x3a,  0x01,  0x0c,  0x85,  0x55,  0x03,  0x3a,  0x11,  0xfe,  0xcc,  0x00,  0x02,  0x27,  0x3a,  0x40,
-  0x05,  0xcb,  0xfe,  0xe3,  0x13,  0x36,  0x3c,  0x21,  0x3d,  0x53,  0xfe,  0x92,  0x11,  0x0a,  0x07,  0x60,
-  0xfe,  0x72,  0x12,  0x83,  0x30,  0x5a,  0x42,  0x95,  0xca,  0x98,  0xfe,  0x5c,  0x11,  0x29,  0x68,  0xfe,
-  0x26,  0x13,  0x04,  0xb5,  0x2a,  0x93,  0x53,  0xfe,  0xb2,  0x0d,  0x0d,  0x66,  0x12,  0x67,  0x2b,  0x0d,
-  0xb5,  0x0d,  0x93,  0x01,  0xc5,  0x20,  0x74,  0x5b,  0x16,  0x68,  0x01,  0xfe,  0xbe,  0x13,  0x83,  0x30,
-  0x5a,  0x42,  0xfe,  0x04,  0x55,  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,  0x30,  0xfe,  0x05,  0xfa,  0x42,
-  0xfe,  0x91,  0x10,  0x04,  0x43,  0x2a,  0x44,  0xfe,  0x40,  0x56,  0xfe,  0xe1,  0x56,  0x0d,  0x43,  0x12,
-  0x44,  0xad,  0x83,  0x30,  0x5a,  0x42,  0x95,  0xca,  0x04,  0x64,  0x2a,  0x65,  0xfe,  0x00,  0x56,  0xfe,
-  0xa1,  0x56,  0x0d,  0x64,  0x12,  0x65,  0x0a,  0x07,  0x60,  0xfe,  0x1e,  0x12,  0x29,  0x68,  0xfe,  0x1f,
-  0x40,  0x04,  0x66,  0x2a,  0x67,  0xfe,  0x2c,  0x50,  0xfe,  0xae,  0x50,  0x04,  0x43,  0x2a,  0x44,  0xfe,
-  0x34,  0x50,  0xfe,  0xb6,  0x50,  0x04,  0x64,  0x2a,  0x65,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x04,
-  0x3c,  0x2a,  0x3d,  0xfe,  0x28,  0x50,  0xfe,  0xaa,  0x50,  0x02,  0xa0,  0x20,  0x06,  0x16,  0xfc,  0x02,
-  0x7f,  0x3a,  0x01,  0x0c,  0x1f,  0x57,  0x24,  0x23,  0xba,  0x05,  0x06,  0x28,  0x57,  0x40,  0x05,  0xcb,
-  0x28,  0x7f,  0x01,  0xfe,  0x9c,  0x13,  0x1a,  0x59,  0x19,  0x57,  0x0a,  0x07,  0x0b,  0xe4,  0x36,  0x3c,
-  0x21,  0x3d,  0xfe,  0x0a,  0x55,  0x35,  0xfe,  0x8b,  0x55,  0x4e,  0x3c,  0x70,  0x3d,  0xfe,  0x0c,  0x51,
-  0xfe,  0x8e,  0x51,  0x02,  0x7f,  0xdf,  0xfe,  0x0a,  0x45,  0xfe,  0x19,  0x41,  0x02,  0x7f,  0x3a,  0x01,
-  0x0c,  0x1f,  0xfe,  0xd6,  0x10,  0x24,  0x23,  0xfe,  0xe9,  0x09,  0x61,  0x18,  0xfe,  0x94,  0x12,  0x61,
-  0x0b,  0x4f,  0x02,  0x57,  0x2f,  0xfe,  0x5e,  0x12,  0x1b,  0x32,  0x1f,  0xfe,  0xd6,  0x10,  0x24,  0x23,
-  0x9a,  0x05,  0x18,  0x28,  0x57,  0x01,  0x0c,  0x1f,  0xfe,  0xd6,  0x10,  0x24,  0x23,  0xfe,  0xe8,  0x09,
-  0x51,  0x04,  0xfe,  0x9c,  0x00,  0x2c,  0x35,  0xfe,  0xbb,  0x45,  0x61,  0x00,  0x50,  0x37,  0x06,  0xa6,
-  0x59,  0xfe,  0xc0,  0x14,  0xfe,  0xf8,  0x14,  0xb3,  0x40,  0x05,  0xc9,  0xfe,  0x16,  0x13,  0x04,  0xfe,
-  0x9e,  0x00,  0x2c,  0xd6,  0x04,  0x56,  0x2c,  0x35,  0x63,  0x02,  0x7f,  0xfe,  0xc0,  0x5d,  0xfe,  0xe4,
-  0x14,  0xfe,  0x03,  0x17,  0x04,  0x5c,  0xc3,  0x0d,  0x5c,  0x63,  0x3a,  0x01,  0x0c,  0x25,  0xa0,  0x01,
-  0xfe,  0x06,  0x15,  0x02,  0xa0,  0x2f,  0xfe,  0xe8,  0x12,  0x1b,  0x32,  0x1f,  0x57,  0x24,  0x23,  0x9a,
-  0x05,  0x06,  0x28,  0x57,  0xfe,  0xf6,  0x14,  0xfe,  0x42,  0x58,  0xfe,  0x70,  0x14,  0xfe,  0x92,  0x14,
-  0xb3,  0xfe,  0x4a,  0xf4,  0x0b,  0x19,  0x57,  0xfe,  0x4a,  0xf4,  0x06,  0xd8,  0x40,  0x05,  0xc9,  0xd1,
-  0x02,  0x7f,  0x04,  0x56,  0xc3,  0x0d,  0x56,  0x63,  0x3a,  0x01,  0x0c,  0x25,  0xa0,  0x01,  0xfe,  0x34,
-  0x15,  0x02,  0xa0,  0x25,  0xfe,  0x50,  0x13,  0x78,  0xf9,  0x78,  0x03,  0x34,  0xfe,  0x4c,  0x13,  0x73,
-  0xfe,  0x4c,  0x13,  0x63,  0x3a,  0x01,  0x0c,  0xfe,  0xe3,  0x10,  0x08,  0x6c,  0xff,  0x02,  0x00,  0x57,
-  0x6e,  0x81,  0x1a,  0xfe,  0xff,  0x7f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x08,  0x6c,  0xff,
-  0x02,  0x00,  0x57,  0x6e,  0x81,  0x1a,  0x59,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x08,  0x6c,
-  0xff,  0x02,  0x00,  0x57,  0x6e,  0x81,  0x03,  0x08,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x6e,  0x81,  0xfe,
-  0x0b,  0x58,  0x03,  0x0f,  0x5c,  0x01,  0x8e,  0x0f,  0x56,  0x01,  0x8e,  0x03,  0xd0,  0x1a,  0x10,  0xff,
-  0x03,  0x00,  0x54,  0xfe,  0x00,  0xf4,  0x22,  0x6e,  0xfe,  0x00,  0x7d,  0xfe,  0x01,  0x7d,  0xfe,  0x02,
-  0x7d,  0xfe,  0x03,  0x7c,  0x6d,  0x31,  0x0d,  0x64,  0x12,  0x65,  0x4e,  0x43,  0x70,  0x44,  0x03,  0xfe,
-  0x62,  0x18,  0xfe,  0x82,  0x5a,  0xfe,  0xe1,  0x1a,  0xbf,  0xfe,  0x02,  0x58,  0x03,  0x01,  0xfe,  0x7e,
-  0x19,  0xfe,  0x42,  0x48,  0x6a,  0x51,  0x9e,  0x01,  0x0c,  0x1f,  0xfe,  0xfe,  0x14,  0x24,  0x23,  0xfe,
-  0xe9,  0x09,  0xfe,  0xc1,  0x59,  0x01,  0x0c,  0x1f,  0xfe,  0xfe,  0x14,  0x24,  0x23,  0xfe,  0xe8,  0x0a,
-  0x04,  0xfe,  0x9e,  0x00,  0x2c,  0xfe,  0xc4,  0x12,  0x2b,  0xb8,  0x1d,  0xe4,  0x61,  0xd5,  0x79,  0xfe,
-  0x4c,  0x14,  0x4f,  0x08,  0x06,  0x09,  0xd5,  0xa6,  0xfe,  0x00,  0x10,  0xfe,  0x78,  0x10,  0xff,  0x02,
-  0x83,  0x55,  0x8a,  0xff,  0x02,  0x83,  0x55,  0xb8,  0x18,  0xfe,  0x12,  0x13,  0x62,  0xfe,  0x30,  0x00,
-  0x98,  0xfe,  0xa6,  0x14,  0x09,  0x8b,  0x08,  0x06,  0xfe,  0x56,  0x10,  0xb8,  0x0b,  0xfe,  0x16,  0x13,
-  0x62,  0xfe,  0x64,  0x00,  0x98,  0xfe,  0xa6,  0x14,  0x0f,  0xfe,  0x64,  0x00,  0x09,  0xb1,  0x08,  0x06,
-  0xfe,  0x28,  0x10,  0xb8,  0x06,  0xfe,  0x60,  0x13,  0x62,  0xfe,  0xc8,  0x00,  0x98,  0xfe,  0xa6,  0x14,
-  0x0f,  0xfe,  0xc8,  0x00,  0x09,  0x5e,  0x08,  0x06,  0xad,  0x62,  0xfe,  0x90,  0x01,  0x99,  0xfe,  0xb2,
-  0x14,  0x9e,  0xb0,  0xfe,  0x43,  0xf4,  0xb4,  0xfe,  0x56,  0xf0,  0xfe,  0xc4,  0x14,  0xfe,  0x04,  0xf4,
-  0x6c,  0xfe,  0x43,  0xf4,  0xb1,  0xfe,  0xf3,  0x10,  0xb7,  0x01,  0xfe,  0x8e,  0x13,  0x1a,  0x59,  0xaf,
-  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x74,  0x99,  0xfe,  0xf8,  0x14,  0xa8,  0x74,  0xfe,  0x14,  0x10,
-  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0xf1,  0x99,  0xfe,  0xf8,  0x14,  0xa8,  0xf1,  0xa4,  0x51,  0x9e,
-  0x08,  0x06,  0xfe,  0xb4,  0x56,  0xfe,  0xc3,  0x58,  0x03,  0x51,  0x08,  0x0b,  0x03,  0x14,  0x06,  0x01,
-  0x0c,  0x25,  0xec,  0x14,  0x0b,  0x01,  0x0c,  0x25,  0xec,  0x14,  0x18,  0x01,  0x0c,  0x25,  0xec,  0x78,
-  0xfe,  0x89,  0x49,  0x01,  0x0c,  0x03,  0x14,  0x06,  0x01,  0x0c,  0x25,  0xbc,  0x14,  0x18,  0x01,  0x0c,
-  0x25,  0xbc,  0x14,  0x06,  0x01,  0x0c,  0x25,  0xbc,  0xfe,  0x89,  0x49,  0x01,  0x0c,  0x25,  0xbc,  0x78,
-  0xfe,  0x89,  0x4a,  0x01,  0x0c,  0x03,  0x51,  0x03,  0x29,  0xe8,  0x05,  0x06,  0x3b,  0xb6,  0x16,  0xe8,
-  0xfe,  0x49,  0xf4,  0x00,  0x4f,  0x78,  0xce,  0x63,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,  0xf9,  0x01,
-  0x0c,  0x40,  0x05,  0xfe,  0xe3,  0x00,  0xfe,  0x20,  0x13,  0x1f,  0xfe,  0xb6,  0x15,  0x2b,  0x16,  0xfc,
-  0x01,  0x55,  0x29,  0xfc,  0x05,  0x06,  0x50,  0x0a,  0x41,  0x06,  0x39,  0x03,  0x0d,  0x5d,  0x12,  0x91,
-  0xfe,  0x43,  0x58,  0x01,  0x15,  0x05,  0x10,  0xfe,  0x1e,  0x12,  0x4a,  0xf3,  0x96,  0x01,  0x49,  0xfe,
-  0x90,  0x4d,  0xe6,  0x10,  0xfe,  0xc5,  0x59,  0x01,  0x49,  0xfe,  0x8d,  0x56,  0xbf,  0x4a,  0x03,  0x4a,
-  0x21,  0x91,  0x01,  0x15,  0x4a,  0x96,  0x01,  0x49,  0xeb,  0x10,  0xe6,  0x10,  0x21,  0x5d,  0x62,  0x1e,
-  0x89,  0x0f,  0x5f,  0x01,  0xaa,  0x03,  0x0d,  0x5d,  0x12,  0x91,  0xfe,  0xc3,  0x58,  0x01,  0x15,  0x05,
-  0x10,  0xfe,  0x1a,  0x12,  0x4a,  0xf3,  0x96,  0x01,  0x49,  0xeb,  0x10,  0xfe,  0x80,  0x4d,  0xfe,  0xc5,
-  0x59,  0x01,  0x49,  0x4a,  0x03,  0x4a,  0x21,  0x5d,  0x01,  0x15,  0x4a,  0x96,  0x01,  0x49,  0xeb,  0x10,
-  0xe6,  0x10,  0x21,  0x5d,  0x62,  0x1e,  0x89,  0x0f,  0x5f,  0x01,  0xaa,  0x03,  0x0d,  0x5d,  0x12,  0x91,
-  0xfe,  0x43,  0x58,  0x01,  0x15,  0xfe,  0x42,  0x48,  0x96,  0x01,  0x49,  0xfe,  0xc0,  0x5a,  0xb7,  0xfe,
-  0x00,  0xcd,  0xfe,  0x01,  0xcc,  0xfe,  0x4a,  0x46,  0xe4,  0x9c,  0x80,  0x05,  0x10,  0xfe,  0x2e,  0x13,
-  0x5a,  0x5d,  0xfe,  0x4d,  0xf4,  0x1e,  0xfe,  0x1c,  0x13,  0x0f,  0x5f,  0x01,  0x8e,  0xb0,  0xfe,  0x40,
-  0x4c,  0xfe,  0xc5,  0x58,  0x01,  0x49,  0xfe,  0x00,  0x07,  0x80,  0x05,  0x10,  0x89,  0x5a,  0x91,  0xfe,
-  0x05,  0x57,  0xfe,  0x08,  0x10,  0xfe,  0x45,  0x58,  0x01,  0x49,  0xfe,  0x8d,  0x56,  0xbf,  0xfe,  0x80,
-  0x4c,  0xfe,  0x05,  0x17,  0x03,  0x09,  0x10,  0x77,  0x6f,  0xfe,  0x60,  0x01,  0xfe,  0x18,  0xdf,  0xfe,
-  0x19,  0xde,  0xfe,  0x24,  0x1c,  0xe3,  0x38,  0x9d,  0xfe,  0xfa,  0x16,  0x01,  0xfe,  0x08,  0x18,  0xd9,
-  0x8d,  0x38,  0x6f,  0xfe,  0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x03,  0xc0,  0x28,  0xfe,  0xea,  0x16,  0xfe,
-  0xe2,  0x10,  0x09,  0x10,  0x77,  0x04,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x22,  0xfe,  0x18,  0x58,
-  0x04,  0xfe,  0x66,  0x01,  0xfe,  0x19,  0x58,  0x8d,  0x22,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x06,
-  0xfe,  0x3c,  0x50,  0x6f,  0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x22,  0x9d,  0xfe,
-  0x44,  0x17,  0xfe,  0xbe,  0x14,  0x35,  0x03,  0xc0,  0x28,  0xfe,  0x1c,  0x17,  0xfe,  0xa4,  0x10,  0x09,
-  0x10,  0x77,  0xbf,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xdf,  0xe3,  0x30,  0x9d,  0xfe,  0x66,  0x17,  0xfe,
-  0x9c,  0x14,  0xfe,  0x18,  0x13,  0x8d,  0x30,  0x6f,  0x1d,  0xfe,  0xaf,  0x19,  0xfe,  0x98,  0xe7,  0x00,
-  0xa7,  0x07,  0xfe,  0x7f,  0x00,  0xfe,  0x05,  0x40,  0x03,  0xc0,  0x28,  0xfe,  0x5a,  0x17,  0xfe,  0x6c,
-  0x10,  0x09,  0x10,  0x77,  0xfe,  0x30,  0xbc,  0xfe,  0xb2,  0xbc,  0x8d,  0xe1,  0x6f,  0x1d,  0xfe,  0x0f,
-  0x79,  0xfe,  0x1c,  0xf7,  0xe1,  0x9d,  0xfe,  0xa6,  0x17,  0xfe,  0x5c,  0x14,  0x35,  0x03,  0xc0,  0x28,
-  0xfe,  0x92,  0x17,  0xfe,  0x42,  0x10,  0xfe,  0x02,  0xf6,  0x10,  0x77,  0xfe,  0x18,  0xfe,  0x66,  0xfe,
-  0x19,  0xfe,  0x67,  0xd0,  0xe3,  0x46,  0x9d,  0xfe,  0xcc,  0x17,  0xfe,  0x36,  0x14,  0xfe,  0x1c,  0x13,
-  0x8d,  0x46,  0x47,  0xfe,  0x83,  0x58,  0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x10,  0xfe,  0x81,  0xe7,
-  0x10,  0x11,  0xfe,  0xdd,  0x00,  0x6d,  0x31,  0x03,  0x6d,  0x31,  0xfe,  0x12,  0x45,  0x28,  0xfe,  0xbc,
-  0x17,  0x17,  0x06,  0x4c,  0xfe,  0x9b,  0x00,  0xe5,  0x02,  0x27,  0xfe,  0x39,  0xf0,  0xfe,  0x10,  0x18,
-  0x2b,  0x03,  0xfe,  0x7e,  0x18,  0x1a,  0x18,  0x87,  0x08,  0x0e,  0x03,  0x77,  0x04,  0xe7,  0x1a,  0x06,
-  0xfe,  0xef,  0x12,  0xfe,  0xe1,  0x10,  0x1c,  0x0f,  0x1e,  0x01,  0x15,  0x05,  0x10,  0x50,  0x4d,  0xfe,
-  0x78,  0x14,  0xfe,  0x34,  0x12,  0x59,  0x8c,  0x37,  0x38,  0xc7,  0xfe,  0xe9,  0x13,  0x1c,  0x0f,  0x3f,
-  0x01,  0x15,  0x05,  0x10,  0x50,  0x4d,  0xfe,  0x56,  0x14,  0xe9,  0x59,  0x8c,  0x37,  0x38,  0xc7,  0xfe,
-  0xe9,  0x13,  0x09,  0x0b,  0x03,  0xfe,  0x9c,  0xe7,  0x0b,  0x13,  0xfe,  0x15,  0x00,  0x7a,  0xa5,  0x31,
-  0x01,  0xea,  0x09,  0x06,  0x03,  0x0a,  0x41,  0x38,  0x39,  0x08,  0x3f,  0x09,  0xa2,  0x01,  0x45,  0x11,
-  0x48,  0x08,  0x1e,  0x09,  0x52,  0x01,  0x7e,  0x09,  0x06,  0x03,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,
-  0x36,  0xfe,  0xa8,  0x00,  0x21,  0x7b,  0xfe,  0x48,  0x55,  0x35,  0xfe,  0xc9,  0x55,  0x03,  0x29,  0xc6,
-  0x5b,  0x16,  0xc6,  0x03,  0x0f,  0xc8,  0x01,  0x15,  0xf2,  0x0f,  0x7d,  0x01,  0x15,  0xfe,  0x49,  0x44,
-  0x28,  0xfe,  0x06,  0x19,  0x0f,  0x1e,  0x01,  0x15,  0x05,  0x10,  0x50,  0x0f,  0x5f,  0x01,  0xaa,  0x0f,
-  0x7d,  0x01,  0x15,  0x5b,  0x80,  0x03,  0xfe,  0x40,  0x5e,  0xfe,  0xe2,  0x08,  0xfe,  0xc0,  0x4c,  0x29,
-  0x3e,  0x05,  0x10,  0xfe,  0x52,  0x12,  0x4d,  0x05,  0x00,  0xfe,  0x18,  0x12,  0xfe,  0xe1,  0x18,  0xfe,
-  0x19,  0xf4,  0xfe,  0x7f,  0x00,  0xaf,  0xfe,  0xe2,  0x08,  0x5b,  0x4d,  0x40,  0x05,  0x7b,  0xab,  0xfe,
-  0x82,  0x48,  0xfe,  0x01,  0x80,  0xfe,  0xd7,  0x10,  0xfe,  0xc4,  0x48,  0x08,  0x2d,  0x09,  0x3e,  0xfe,
-  0x40,  0x5f,  0x1c,  0x01,  0x45,  0x11,  0xfe,  0xdd,  0x00,  0xfe,  0x14,  0x46,  0x08,  0x2d,  0x09,  0x3e,
-  0x01,  0x45,  0x11,  0xfe,  0xdd,  0x00,  0xfe,  0x40,  0x4a,  0x72,  0xfe,  0x06,  0x17,  0xfe,  0x01,  0x07,
-  0xfe,  0x82,  0x48,  0xfe,  0x04,  0x17,  0x03,  0xf5,  0x18,  0x79,  0xfe,  0x8e,  0x19,  0x04,  0xfe,  0x90,
-  0x00,  0xfe,  0x3a,  0x45,  0xfe,  0x2c,  0x10,  0xf5,  0xd4,  0x79,  0xfe,  0xa0,  0x19,  0x04,  0xfe,  0x92,
-  0x00,  0xcf,  0x1d,  0xe0,  0xf5,  0xfe,  0x0b,  0x00,  0x79,  0xfe,  0xb2,  0x19,  0x04,  0xfe,  0x94,  0x00,
-  0xcf,  0x22,  0xfe,  0x08,  0x10,  0x04,  0xfe,  0x96,  0x00,  0xcf,  0x8b,  0xfe,  0x4e,  0x45,  0xd8,  0xfe,
-  0x0a,  0x45,  0xff,  0x04,  0x68,  0x54,  0xfe,  0xf1,  0x10,  0x1a,  0x74,  0xfe,  0x08,  0x1c,  0xfe,  0x67,
-  0x19,  0xfe,  0x0a,  0x1c,  0xfe,  0x1a,  0xf4,  0xfe,  0x00,  0x04,  0xd8,  0xfe,  0x48,  0xf4,  0x18,  0x99,
-  0xfe,  0xe6,  0x19,  0x08,  0x18,  0x03,  0x05,  0x84,  0xfe,  0x5a,  0xf0,  0xfe,  0xf6,  0x19,  0x20,  0xfe,
-  0x09,  0x00,  0xfe,  0x34,  0x10,  0x05,  0x1d,  0xfe,  0x5a,  0xf0,  0xfe,  0x04,  0x1a,  0x20,  0xd5,  0xfe,
-  0x26,  0x10,  0x05,  0x18,  0x87,  0x20,  0x8b,  0xe0,  0x05,  0x0b,  0x87,  0x20,  0xb1,  0xfe,  0x0e,  0x10,
-  0x05,  0x06,  0x87,  0x20,  0x5e,  0xce,  0xb6,  0x03,  0x17,  0xfe,  0x09,  0x00,  0x01,  0x3b,  0x2f,  0xfe,
-  0x34,  0x1a,  0x04,  0x76,  0xb7,  0x03,  0x1b,  0xfe,  0x54,  0x1a,  0xfe,  0x14,  0xf0,  0x0c,  0x2f,  0xfe,
-  0x48,  0x1a,  0x1b,  0xfe,  0x54,  0x1a,  0xfe,  0x82,  0xf0,  0xfe,  0x4c,  0x1a,  0x03,  0xff,  0x15,  0x00,
-  0x00,
+  0x00,  0x00,  0x00,  0xf2,  0x00,  0xf0,  0x00,  0xfc,  0x00,  0x16,  0x18,  0xe4,  0x01,  0x00,  0x48,  0xe4,
+  0x18,  0x80,  0x03,  0xf6,  0x02,  0x00,  0xce,  0x19,  0x00,  0xfa,  0xff,  0xff,  0x1c,  0x0f,  0x00,  0xf6,
+  0x9e,  0xe7,  0xff,  0x00,  0x82,  0xe7,  0x00,  0xea,  0x01,  0xfa,  0x01,  0xe6,  0x09,  0xe7,  0x55,  0xf0,
+  0x01,  0xf6,  0x03,  0x00,  0x04,  0x00,  0x10,  0x00,  0x1e,  0xf0,  0x85,  0xf0,  0x18,  0xf4,  0x08,  0x00,
+  0xbc,  0x00,  0x38,  0x54,  0x00,  0xec,  0xd5,  0xf0,  0x82,  0x0d,  0x00,  0xe6,  0x86,  0xf0,  0xb1,  0xf0,
+  0x98,  0x57,  0x01,  0xfc,  0xb4,  0x00,  0xd4,  0x01,  0x0c,  0x1c,  0x3e,  0x1c,  0x3c,  0x00,  0xbb,  0x00,
+  0x00,  0x10,  0xba,  0x19,  0x02,  0x80,  0x32,  0xf0,  0x7c,  0x0d,  0x02,  0x13,  0xba,  0x13,  0x18,  0x40,
+  0x00,  0x57,  0x01,  0xea,  0x02,  0xfc,  0x03,  0xfc,  0x3e,  0x00,  0x6c,  0x01,  0x6e,  0x01,  0x74,  0x01,
+  0x76,  0x01,  0xb9,  0x54,  0x3e,  0x57,  0x00,  0x80,  0x03,  0xe6,  0xb6,  0x00,  0xc0,  0x00,  0x01,  0x01,
+  0x3e,  0x01,  0x7a,  0x01,  0xca,  0x08,  0xce,  0x10,  0x16,  0x11,  0x04,  0x12,  0x08,  0x12,  0x02,  0x4a,
+  0xbb,  0x55,  0x3c,  0x56,  0x03,  0x58,  0x1b,  0x80,  0x30,  0xe4,  0x4b,  0xe4,  0x5d,  0xf0,  0x02,  0xfa,
+  0x20,  0x00,  0x32,  0x00,  0x40,  0x00,  0x80,  0x00,  0x24,  0x01,  0x3c,  0x01,  0x68,  0x01,  0x6a,  0x01,
+  0x70,  0x01,  0x72,  0x01,  0x78,  0x01,  0x7c,  0x01,  0x62,  0x0a,  0x86,  0x0d,  0x06,  0x13,  0x4c,  0x1c,
+  0x04,  0x80,  0x4a,  0xe4,  0x02,  0xee,  0x5b,  0xf0,  0x03,  0xf7,  0x0c,  0x00,  0x0f,  0x00,  0x47,  0x00,
+  0xbe,  0x00,  0x00,  0x01,  0x20,  0x11,  0x5c,  0x16,  0x32,  0x1c,  0x38,  0x1c,  0x4e,  0x1c,  0x10,  0x44,
+  0x00,  0x4c,  0x04,  0xea,  0x5c,  0xf0,  0xa7,  0xf0,  0x04,  0xf6,  0x03,  0xfa,  0x05,  0x00,  0x34,  0x00,
+  0x36,  0x00,  0x98,  0x00,  0xcc,  0x00,  0x20,  0x01,  0x4e,  0x01,  0x4a,  0x0b,  0x42,  0x0c,  0x12,  0x0f,
+  0x0c,  0x10,  0x22,  0x11,  0x0a,  0x12,  0x04,  0x13,  0x30,  0x1c,  0x02,  0x48,  0x00,  0x4e,  0x42,  0x54,
+  0x44,  0x55,  0xbd,  0x56,  0x06,  0x83,  0x00,  0xdc,  0x05,  0xf0,  0x09,  0xf0,  0x59,  0xf0,  0xb8,  0xf0,
+  0x4b,  0xf4,  0x06,  0xf7,  0x0e,  0xf7,  0x04,  0xfc,  0x05,  0xfc,  0x06,  0x00,  0x19,  0x00,  0x33,  0x00,
+  0x9b,  0x00,  0xa4,  0x00,  0xb5,  0x00,  0xba,  0x00,  0xd0,  0x00,  0xe1,  0x00,  0xe7,  0x00,  0xe2,  0x03,
+  0x08,  0x0f,  0x02,  0x10,  0x04,  0x10,  0x0a,  0x10,  0x0a,  0x13,  0x0c,  0x13,  0x12,  0x13,  0x24,  0x14,
+  0x34,  0x14,  0x04,  0x16,  0x08,  0x16,  0xa4,  0x17,  0x20,  0x1c,  0x34,  0x1c,  0x36,  0x1c,  0x08,  0x44,
+  0x38,  0x44,  0x91,  0x44,  0x0a,  0x45,  0x48,  0x46,  0x01,  0x48,  0x68,  0x54,  0x3a,  0x55,  0x83,  0x55,
+  0xe5,  0x55,  0xb0,  0x57,  0x01,  0x58,  0x83,  0x59,  0x05,  0xe6,  0x0b,  0xf0,  0x0c,  0xf0,  0x04,  0xf8,
+  0x05,  0xf8,  0x07,  0x00,  0x0a,  0x00,  0x1c,  0x00,  0x1e,  0x00,  0x9e,  0x00,  0xa8,  0x00,  0xaa,  0x00,
+  0xb9,  0x00,  0xe0,  0x00,  0x22,  0x01,  0x26,  0x01,  0x79,  0x01,  0x7e,  0x01,  0xc4,  0x01,  0xc6,  0x01,
+  0x80,  0x02,  0x5e,  0x03,  0xee,  0x04,  0x9a,  0x06,  0xf8,  0x07,  0x62,  0x08,  0x68,  0x08,  0x69,  0x08,
+  0xd6,  0x08,  0xe9,  0x09,  0xfa,  0x0b,  0x2e,  0x0f,  0x12,  0x10,  0x1a,  0x10,  0xed,  0x10,  0xf1,  0x10,
+  0x2a,  0x11,  0x06,  0x12,  0x0c,  0x12,  0x3e,  0x12,  0x10,  0x13,  0x16,  0x13,  0x1e,  0x13,  0x46,  0x14,
+  0x76,  0x14,  0x82,  0x14,  0x36,  0x15,  0xca,  0x15,  0x6b,  0x18,  0xbe,  0x18,  0xca,  0x18,  0xe6,  0x19,
+  0x12,  0x1c,  0x46,  0x1c,  0x9c,  0x32,  0x00,  0x40,  0x0e,  0x47,  0xfe,  0x9c,  0xf0,  0x2b,  0x02,  0xfe,
+  0xac,  0x0d,  0xff,  0x10,  0x00,  0x00,  0xd7,  0xfe,  0xe8,  0x19,  0x00,  0xd6,  0xfe,  0x84,  0x01,  0xff,
+  0x03,  0x00,  0x00,  0xfe,  0x93,  0x15,  0xfe,  0x0f,  0x05,  0xff,  0x38,  0x00,  0x00,  0xfe,  0x57,  0x24,
+  0x00,  0xfe,  0x4c,  0x00,  0x5b,  0xff,  0x04,  0x00,  0x00,  0x11,  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,
+  0x01,  0x01,  0xff,  0x08,  0xff,  0xff,  0xff,  0x27,  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,  0xff,  0x11,
+  0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xd6,
+  0x2c,  0x99,  0x0a,  0x01,  0xfe,  0xc2,  0x0f,  0xfe,  0x04,  0xf7,  0xd6,  0x99,  0x0a,  0x42,  0x2c,  0xfe,
+  0x3d,  0xf0,  0xfe,  0x06,  0x02,  0xfe,  0x20,  0xf0,  0xa7,  0xfe,  0x91,  0xf0,  0xfe,  0xf4,  0x01,  0xfe,
+  0x90,  0xf0,  0xfe,  0xf4,  0x01,  0xfe,  0x8f,  0xf0,  0xa7,  0x03,  0x5d,  0x4d,  0x02,  0xfe,  0xc8,  0x0d,
+  0x01,  0xfe,  0x38,  0x0e,  0xfe,  0xdd,  0x12,  0xfe,  0xfc,  0x10,  0xfe,  0x28,  0x1c,  0x03,  0xfe,  0xa6,
+  0x00,  0xfe,  0xd3,  0x12,  0x41,  0x14,  0xfe,  0xa6,  0x00,  0xc2,  0xfe,  0x48,  0xf0,  0xfe,  0x8a,  0x02,
+  0xfe,  0x49,  0xf0,  0xfe,  0xa4,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xc2,  0x02,  0xfe,  0x46,  0xf0,  0xfe,
+  0x54,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x5a,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x48,  0x02,  0xfe,  0x44,
+  0xf0,  0xfe,  0x4c,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x50,  0x02,  0x18,  0x0a,  0xaa,  0x18,  0x06,  0x14,
+  0xa1,  0x02,  0x2b,  0xfe,  0x00,  0x1c,  0xe7,  0xfe,  0x02,  0x1c,  0xe6,  0xfe,  0x1e,  0x1c,  0xfe,  0xe9,
+  0x10,  0x01,  0xfe,  0x18,  0x18,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xce,  0x09,  0x70,  0x01,  0xa8,
+  0x02,  0x2b,  0x15,  0x59,  0x39,  0xa2,  0x01,  0xfe,  0x58,  0x10,  0x09,  0x70,  0x01,  0x87,  0xfe,  0xbd,
+  0x10,  0x09,  0x70,  0x01,  0x87,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x18,  0x06,
+  0x14,  0xa1,  0x2c,  0x1c,  0x2b,  0xfe,  0x3d,  0xf0,  0xfe,  0x06,  0x02,  0x23,  0xfe,  0x98,  0x02,  0xfe,
+  0x5a,  0x1c,  0xf8,  0xfe,  0x14,  0x1c,  0x15,  0xfe,  0x30,  0x00,  0x39,  0xa2,  0x01,  0xfe,  0x48,  0x10,
+  0x18,  0x06,  0x14,  0xa1,  0x02,  0xd7,  0x22,  0x20,  0x07,  0x11,  0x35,  0xfe,  0x69,  0x10,  0x18,  0x06,
+  0x14,  0xa1,  0xfe,  0x04,  0xec,  0x20,  0x4f,  0x43,  0x13,  0x20,  0xfe,  0x05,  0xf6,  0xce,  0x01,  0xfe,
+  0x4a,  0x17,  0x08,  0x54,  0x58,  0x37,  0x12,  0x2f,  0x42,  0x92,  0x01,  0xfe,  0x82,  0x16,  0x02,  0x2b,
+  0x09,  0x46,  0x01,  0x0e,  0x07,  0x00,  0x66,  0x01,  0x73,  0xfe,  0x18,  0x10,  0xfe,  0x41,  0x58,  0x09,
+  0xa4,  0x01,  0x0e,  0xfe,  0xc8,  0x54,  0x6b,  0xfe,  0x10,  0x03,  0x01,  0xfe,  0x82,  0x16,  0x02,  0x2b,
+  0x2c,  0x4f,  0xfe,  0x02,  0xe8,  0x2a,  0xfe,  0xbf,  0x57,  0xfe,  0x9e,  0x43,  0xfe,  0x77,  0x57,  0xfe,
+  0x27,  0xf0,  0xfe,  0xe0,  0x01,  0xfe,  0x07,  0x4b,  0xfe,  0x20,  0xf0,  0xa7,  0xfe,  0x40,  0x1c,  0x1c,
+  0xd9,  0xfe,  0x26,  0xf0,  0xfe,  0x5a,  0x03,  0xfe,  0xa0,  0xf0,  0xfe,  0x48,  0x03,  0xfe,  0x11,  0xf0,
+  0xa7,  0xfe,  0xef,  0x10,  0xfe,  0x9f,  0xf0,  0xfe,  0x68,  0x03,  0xf9,  0x10,  0xfe,  0x11,  0x00,  0x02,
+  0x65,  0x2c,  0xfe,  0x48,  0x1c,  0xf9,  0x08,  0x05,  0x1b,  0xfe,  0x18,  0x13,  0x21,  0x22,  0xa3,  0xb7,
+  0x13,  0xa3,  0x09,  0x46,  0x01,  0x0e,  0xb7,  0x78,  0x01,  0xfe,  0xb4,  0x16,  0x12,  0xd1,  0x1c,  0xd9,
+  0xfe,  0x01,  0xf0,  0xd9,  0xfe,  0x82,  0xf0,  0xfe,  0x96,  0x03,  0xfa,  0x12,  0xfe,  0xe4,  0x00,  0x27,
+  0xfe,  0xa8,  0x03,  0x1c,  0x34,  0x1d,  0xfe,  0xb8,  0x03,  0x01,  0x4b,  0xfe,  0x06,  0xf0,  0xfe,  0xc8,
+  0x03,  0x95,  0x86,  0xfe,  0x0a,  0xf0,  0xfe,  0x8a,  0x06,  0x02,  0x24,  0x03,  0x70,  0x28,  0x17,  0xfe,
+  0xfa,  0x04,  0x15,  0x6d,  0x01,  0x36,  0x7b,  0xfe,  0x6a,  0x02,  0x02,  0xd8,  0xf9,  0x2c,  0x99,  0x19,
+  0xfe,  0x67,  0x1b,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0xfe,  0x48,  0x1c,  0x74,  0x01,  0xaf,  0x8c,
+  0x09,  0x46,  0x01,  0x0e,  0x07,  0x00,  0x17,  0xda,  0x09,  0xd1,  0x01,  0x0e,  0x8d,  0x51,  0x64,  0x79,
+  0x2a,  0x03,  0x70,  0x28,  0xfe,  0x10,  0x12,  0x15,  0x6d,  0x01,  0x36,  0x7b,  0xfe,  0x6a,  0x02,  0x02,
+  0xd8,  0xc7,  0x81,  0xc8,  0x83,  0x1c,  0x24,  0x27,  0xfe,  0x40,  0x04,  0x1d,  0xfe,  0x3c,  0x04,  0x3b,
+  0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x4e,  0x12,  0x2d,  0xff,  0x02,  0x00,  0x10,  0x01,  0x0b,
+  0x1d,  0xfe,  0xe4,  0x04,  0x2d,  0x01,  0x0b,  0x1d,  0x24,  0x33,  0x31,  0xde,  0xfe,  0x4c,  0x44,  0xfe,
+  0x4c,  0x12,  0x51,  0xfe,  0x44,  0x48,  0x0f,  0x6f,  0xfe,  0x4c,  0x54,  0x6b,  0xda,  0x4f,  0x79,  0x2a,
+  0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x62,  0x13,  0x08,  0x05,  0x1b,  0xfe,  0x2a,  0x13,  0x32,
+  0x07,  0x82,  0xfe,  0x52,  0x13,  0xfe,  0x20,  0x10,  0x0f,  0x6f,  0xfe,  0x4c,  0x54,  0x6b,  0xda,  0xfe,
+  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x40,  0x13,  0x08,  0x05,  0x1b,  0xfe,  0x08,  0x13,  0x32,  0x07,
+  0x82,  0xfe,  0x30,  0x13,  0x08,  0x05,  0x1b,  0xfe,  0x1c,  0x12,  0x15,  0x9d,  0x08,  0x05,  0x06,  0x4d,
+  0x15,  0xfe,  0x0d,  0x00,  0x01,  0x36,  0x7b,  0xfe,  0x64,  0x0d,  0x02,  0x24,  0x2d,  0x12,  0xfe,  0xe6,
+  0x00,  0xfe,  0x1c,  0x90,  0xfe,  0x40,  0x5c,  0x04,  0x15,  0x9d,  0x01,  0x36,  0x02,  0x2b,  0xfe,  0x42,
+  0x5b,  0x99,  0x19,  0xfe,  0x46,  0x59,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0xfe,  0x87,  0x80,  0xfe,
+  0x31,  0xe4,  0x5b,  0x08,  0x05,  0x0a,  0xfe,  0x84,  0x13,  0xfe,  0x20,  0x80,  0x07,  0x19,  0xfe,  0x7c,
+  0x12,  0x53,  0x05,  0x06,  0xfe,  0x6c,  0x13,  0x03,  0xfe,  0xa2,  0x00,  0x28,  0x17,  0xfe,  0x90,  0x05,
+  0xfe,  0x31,  0xe4,  0x5a,  0x53,  0x05,  0x0a,  0xfe,  0x56,  0x13,  0x03,  0xfe,  0xa0,  0x00,  0x28,  0xfe,
+  0x4e,  0x12,  0x67,  0xff,  0x02,  0x00,  0x10,  0x27,  0xfe,  0x48,  0x05,  0x1c,  0x34,  0xfe,  0x89,  0x48,
+  0xff,  0x02,  0x00,  0x10,  0x27,  0xfe,  0x56,  0x05,  0x26,  0xfe,  0xa8,  0x05,  0x12,  0xfe,  0xe3,  0x00,
+  0x21,  0x53,  0xfe,  0x4a,  0xf0,  0xfe,  0x76,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0x70,  0x05,  0x88,  0x25,
+  0xfe,  0x21,  0x00,  0xab,  0x25,  0xfe,  0x22,  0x00,  0xaa,  0x25,  0x58,  0xfe,  0x09,  0x48,  0xff,  0x02,
+  0x00,  0x10,  0x27,  0xfe,  0x86,  0x05,  0x26,  0xfe,  0xa8,  0x05,  0xfe,  0xe2,  0x08,  0x53,  0x05,  0xcb,
+  0x4d,  0x01,  0xb0,  0x25,  0x06,  0x13,  0xd3,  0x39,  0xfe,  0x27,  0x01,  0x08,  0x05,  0x1b,  0xfe,  0x22,
+  0x12,  0x41,  0x01,  0xb2,  0x15,  0x9d,  0x08,  0x05,  0x06,  0x4d,  0x15,  0xfe,  0x0d,  0x00,  0x01,  0x36,
+  0x7b,  0xfe,  0x64,  0x0d,  0x02,  0x24,  0x03,  0xfe,  0x9c,  0x00,  0x28,  0xeb,  0x03,  0x5c,  0x28,  0xfe,
+  0x36,  0x13,  0x41,  0x01,  0xb2,  0x26,  0xfe,  0x18,  0x06,  0x09,  0x06,  0x53,  0x05,  0x1f,  0xfe,  0x02,
+  0x12,  0x50,  0x01,  0xfe,  0x9e,  0x15,  0x1d,  0xfe,  0x0e,  0x06,  0x12,  0xa5,  0x01,  0x4b,  0x12,  0xfe,
+  0xe5,  0x00,  0x03,  0x5c,  0xc1,  0x0c,  0x5c,  0x03,  0xcd,  0x28,  0xfe,  0x62,  0x12,  0x03,  0x45,  0x28,
+  0xfe,  0x5a,  0x13,  0x01,  0xfe,  0x0c,  0x19,  0x01,  0xfe,  0x76,  0x19,  0xfe,  0x43,  0x48,  0xc4,  0xcc,
+  0x0f,  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,  0x93,  0x1e,  0x43,  0x8b,  0xc4,  0x6e,  0x41,  0x01,  0xb2,
+  0x26,  0xfe,  0x82,  0x06,  0x53,  0x05,  0x1a,  0xe9,  0x91,  0x09,  0x59,  0x01,  0xfe,  0xcc,  0x15,  0x1d,
+  0xfe,  0x78,  0x06,  0x12,  0xa5,  0x01,  0x4b,  0x12,  0xfe,  0xe5,  0x00,  0x03,  0x45,  0xc1,  0x0c,  0x45,
+  0x18,  0x06,  0x01,  0xb2,  0xfa,  0x76,  0x74,  0x01,  0xaf,  0x8c,  0x12,  0xfe,  0xe2,  0x00,  0x27,  0xdb,
+  0x1c,  0x34,  0xfe,  0x0a,  0xf0,  0xfe,  0xb6,  0x06,  0x94,  0xfe,  0x6c,  0x07,  0xfe,  0x06,  0xf0,  0xfe,
+  0x74,  0x07,  0x95,  0x86,  0x02,  0x24,  0x08,  0x05,  0x0a,  0xfe,  0x2e,  0x12,  0x16,  0x19,  0x01,  0x0b,
+  0x16,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,  0x0b,  0xfe,  0x99,  0xa4,  0x01,
+  0x0b,  0x16,  0x00,  0x02,  0xfe,  0x42,  0x08,  0x68,  0x05,  0x1a,  0xfe,  0x38,  0x12,  0x08,  0x05,  0x1a,
+  0xfe,  0x30,  0x13,  0x16,  0xfe,  0x1b,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,
+  0x0b,  0x16,  0x00,  0x01,  0x0b,  0x16,  0x06,  0x01,  0x0b,  0x16,  0x00,  0x02,  0xe2,  0x6c,  0x58,  0xbe,
+  0x50,  0xfe,  0x9a,  0x81,  0x55,  0x1b,  0x7a,  0xfe,  0x42,  0x07,  0x09,  0x1b,  0xfe,  0x09,  0x6f,  0xba,
+  0xfe,  0xca,  0x45,  0xfe,  0x32,  0x12,  0x69,  0x6d,  0x8b,  0x6c,  0x7f,  0x27,  0xfe,  0x54,  0x07,  0x1c,
+  0x34,  0xfe,  0x0a,  0xf0,  0xfe,  0x42,  0x07,  0x95,  0x86,  0x94,  0xfe,  0x6c,  0x07,  0x02,  0x24,  0x01,
+  0x4b,  0x02,  0xdb,  0x16,  0x1f,  0x02,  0xdb,  0xfe,  0x9c,  0xf7,  0xdc,  0xfe,  0x2c,  0x90,  0xfe,  0xae,
+  0x90,  0x56,  0xfe,  0xda,  0x07,  0x0c,  0x60,  0x14,  0x61,  0x08,  0x54,  0x5a,  0x37,  0x22,  0x20,  0x07,
+  0x11,  0xfe,  0x0e,  0x12,  0x8d,  0xfe,  0x80,  0x80,  0x39,  0x20,  0x6a,  0x2a,  0xfe,  0x06,  0x10,  0xfe,
+  0x83,  0xe7,  0xfe,  0x48,  0x00,  0xab,  0xfe,  0x03,  0x40,  0x08,  0x54,  0x5b,  0x37,  0x01,  0xb3,  0xb8,
+  0xfe,  0x1f,  0x40,  0x13,  0x62,  0x01,  0xef,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0xfe,  0x44,  0x51,
+  0xfe,  0xc6,  0x51,  0x88,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,  0x0c,  0x5e,  0x14,  0x5f,  0xfe,  0x0c,
+  0x90,  0xfe,  0x8e,  0x90,  0xfe,  0x40,  0x50,  0xfe,  0xc2,  0x50,  0x0c,  0x3d,  0x14,  0x3e,  0xfe,  0x4a,
+  0x10,  0x08,  0x05,  0x5a,  0xfe,  0x2a,  0x12,  0xfe,  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x0c,  0x60,  0x14,
+  0x61,  0x08,  0x05,  0x5b,  0x8b,  0x01,  0xb3,  0xfe,  0x1f,  0x80,  0x13,  0x62,  0xfe,  0x44,  0x90,  0xfe,
+  0xc6,  0x90,  0x0c,  0x3f,  0x14,  0x40,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,  0x0c,  0x5e,  0x14,  0x5f,
+  0xfe,  0x40,  0x90,  0xfe,  0xc2,  0x90,  0x0c,  0x3d,  0x14,  0x3e,  0x0c,  0x2e,  0x14,  0x3c,  0x21,  0x0c,
+  0x49,  0x0c,  0x63,  0x08,  0x54,  0x1f,  0x37,  0x2c,  0x0f,  0xfe,  0x4e,  0x11,  0x27,  0xdd,  0xfe,  0x9e,
+  0xf0,  0xfe,  0x76,  0x08,  0xbc,  0x17,  0x34,  0x2c,  0x77,  0xe6,  0xc5,  0xfe,  0x9a,  0x08,  0xc6,  0xfe,
+  0xb8,  0x08,  0x94,  0xfe,  0x8e,  0x08,  0xfe,  0x06,  0xf0,  0xfe,  0x94,  0x08,  0x95,  0x86,  0x02,  0x24,
+  0x01,  0x4b,  0xfe,  0xc9,  0x10,  0x16,  0x1f,  0xfe,  0xc9,  0x10,  0x68,  0x05,  0x06,  0xfe,  0x10,  0x12,
+  0x68,  0x05,  0x0a,  0x4e,  0x08,  0x05,  0x0a,  0xfe,  0x90,  0x12,  0xfe,  0x2e,  0x1c,  0x02,  0xfe,  0x18,
+  0x0b,  0x68,  0x05,  0x06,  0x4e,  0x68,  0x05,  0x0a,  0xfe,  0x7a,  0x12,  0xfe,  0x2c,  0x1c,  0xfe,  0xaa,
+  0xf0,  0xfe,  0xd2,  0x09,  0xfe,  0xac,  0xf0,  0xfe,  0x00,  0x09,  0x02,  0xfe,  0xde,  0x09,  0xfe,  0xb7,
+  0xf0,  0xfe,  0xfc,  0x08,  0xfe,  0x02,  0xf6,  0x1a,  0x50,  0xfe,  0x70,  0x18,  0xfe,  0xf1,  0x18,  0xfe,
+  0x40,  0x55,  0xfe,  0xe1,  0x55,  0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,  0xfe,  0x14,  0x59,  0xfe,  0x95,
+  0x59,  0x1c,  0x85,  0xfe,  0x8c,  0xf0,  0xfe,  0xfc,  0x08,  0xfe,  0xac,  0xf0,  0xfe,  0xf0,  0x08,  0xb5,
+  0xfe,  0xcb,  0x10,  0xfe,  0xad,  0xf0,  0xfe,  0x0c,  0x09,  0x02,  0xfe,  0x18,  0x0b,  0xb6,  0xfe,  0xbf,
+  0x10,  0xfe,  0x2b,  0xf0,  0x85,  0xf4,  0x1e,  0xfe,  0x00,  0xfe,  0xfe,  0x1c,  0x12,  0xc2,  0xfe,  0xd2,
+  0xf0,  0x85,  0xfe,  0x76,  0x18,  0x1e,  0x19,  0x17,  0x85,  0x03,  0xd2,  0x1e,  0x06,  0x17,  0x85,  0xc5,
+  0x4a,  0xc6,  0x4a,  0xb5,  0xb6,  0xfe,  0x89,  0x10,  0x74,  0x67,  0x2d,  0x15,  0x9d,  0x01,  0x36,  0x10,
+  0xfe,  0x35,  0x00,  0xfe,  0x01,  0xf0,  0x65,  0x10,  0x80,  0x02,  0x65,  0xfe,  0x98,  0x80,  0xfe,  0x19,
+  0xe4,  0x0a,  0xfe,  0x1a,  0x12,  0x51,  0xfe,  0x19,  0x82,  0xfe,  0x6c,  0x18,  0xfe,  0x44,  0x54,  0xbe,
+  0xfe,  0x19,  0x81,  0xfe,  0x74,  0x18,  0x8f,  0x90,  0x17,  0xfe,  0xce,  0x08,  0x02,  0x4a,  0x08,  0x05,
+  0x5a,  0xec,  0x03,  0x2e,  0x29,  0x3c,  0x0c,  0x3f,  0x14,  0x40,  0x9b,  0x2e,  0x9c,  0x3c,  0xfe,  0x6c,
+  0x18,  0xfe,  0xed,  0x18,  0xfe,  0x44,  0x54,  0xfe,  0xe5,  0x54,  0x3a,  0x3f,  0x3b,  0x40,  0x03,  0x49,
+  0x29,  0x63,  0x8f,  0xfe,  0xe3,  0x54,  0xfe,  0x74,  0x18,  0xfe,  0xf5,  0x18,  0x8f,  0xfe,  0xe3,  0x54,
+  0x90,  0xc0,  0x56,  0xfe,  0xce,  0x08,  0x02,  0x4a,  0xfe,  0x37,  0xf0,  0xfe,  0xda,  0x09,  0xfe,  0x8b,
+  0xf0,  0xfe,  0x60,  0x09,  0x02,  0x4a,  0x08,  0x05,  0x0a,  0x23,  0xfe,  0xfa,  0x0a,  0x3a,  0x49,  0x3b,
+  0x63,  0x56,  0xfe,  0x3e,  0x0a,  0x0f,  0xfe,  0xc0,  0x07,  0x41,  0x98,  0x00,  0xad,  0xfe,  0x01,  0x59,
+  0xfe,  0x52,  0xf0,  0xfe,  0x0c,  0x0a,  0x8f,  0x7a,  0xfe,  0x24,  0x0a,  0x3a,  0x49,  0x8f,  0xfe,  0xe3,
+  0x54,  0x57,  0x49,  0x7d,  0x63,  0xfe,  0x14,  0x58,  0xfe,  0x95,  0x58,  0x02,  0x4a,  0x3a,  0x49,  0x3b,
+  0x63,  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0xbe,  0x57,  0x49,  0x57,  0x63,  0x02,  0x4a,  0x08,  0x05,
+  0x5a,  0xfe,  0x82,  0x12,  0x08,  0x05,  0x1f,  0xfe,  0x66,  0x13,  0x22,  0x62,  0xb7,  0xfe,  0x03,  0xa1,
+  0xfe,  0x83,  0x80,  0xfe,  0xc8,  0x44,  0xfe,  0x2e,  0x13,  0xfe,  0x04,  0x91,  0xfe,  0x86,  0x91,  0x6a,
+  0x2a,  0xfe,  0x40,  0x59,  0xfe,  0xc1,  0x59,  0x56,  0xe0,  0x03,  0x60,  0x29,  0x61,  0x0c,  0x7f,  0x14,
+  0x80,  0x57,  0x60,  0x7d,  0x61,  0x01,  0xb3,  0xb8,  0x6a,  0x2a,  0x13,  0x62,  0x9b,  0x2e,  0x9c,  0x3c,
+  0x3a,  0x3f,  0x3b,  0x40,  0x90,  0xc0,  0xfe,  0x04,  0xfa,  0x2e,  0xfe,  0x05,  0xfa,  0x3c,  0x01,  0xef,
+  0xfe,  0x36,  0x10,  0x21,  0x0c,  0x7f,  0x0c,  0x80,  0x3a,  0x3f,  0x3b,  0x40,  0xe4,  0x08,  0x05,  0x1f,
+  0x17,  0xe0,  0x3a,  0x3d,  0x3b,  0x3e,  0x08,  0x05,  0xfe,  0xf7,  0x00,  0x37,  0x03,  0x5e,  0x29,  0x5f,
+  0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,  0x57,  0x49,  0x7d,  0x63,  0x02,  0xfe,  0xf4,  0x09,  0x08,  0x05,
+  0x1f,  0x17,  0xe0,  0x08,  0x05,  0xfe,  0xf7,  0x00,  0x37,  0xbe,  0xfe,  0x19,  0x81,  0x50,  0xfe,  0x10,
+  0x90,  0xfe,  0x92,  0x90,  0xfe,  0xd3,  0x10,  0x32,  0x07,  0xa6,  0x17,  0xfe,  0x08,  0x09,  0x12,  0xa6,
+  0x08,  0x05,  0x0a,  0xfe,  0x14,  0x13,  0x03,  0x3d,  0x29,  0x3e,  0x56,  0xfe,  0x08,  0x09,  0xfe,  0x0c,
+  0x58,  0xfe,  0x8d,  0x58,  0x02,  0x4a,  0x21,  0x41,  0xfe,  0x19,  0x80,  0xe7,  0x08,  0x05,  0x0a,  0xfe,
+  0x1a,  0x12,  0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,  0xf4,  0xc2,  0xfe,  0xd1,  0xf0,  0xe2,  0x15,  0x7e,
+  0x01,  0x36,  0x10,  0xfe,  0x44,  0x00,  0xfe,  0x8e,  0x10,  0xfe,  0x6c,  0x19,  0x57,  0x3d,  0xfe,  0xed,
+  0x19,  0x7d,  0x3e,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0xf4,  0x1e,  0xfe,  0x00,  0xff,  0x35,  0xfe,
+  0x74,  0x10,  0xc2,  0xfe,  0xd2,  0xf0,  0xfe,  0xa6,  0x0b,  0xfe,  0x76,  0x18,  0x1e,  0x19,  0x8a,  0x03,
+  0xd2,  0x1e,  0x06,  0xfe,  0x08,  0x13,  0x10,  0xfe,  0x16,  0x00,  0x02,  0x65,  0xfe,  0xd1,  0xf0,  0xfe,
+  0xb8,  0x0b,  0x15,  0x7e,  0x01,  0x36,  0x10,  0xfe,  0x17,  0x00,  0xfe,  0x42,  0x10,  0xfe,  0xce,  0xf0,
+  0xfe,  0xbe,  0x0b,  0xfe,  0x3c,  0x10,  0xfe,  0xcd,  0xf0,  0xfe,  0xca,  0x0b,  0x10,  0xfe,  0x22,  0x00,
+  0x02,  0x65,  0xfe,  0xcb,  0xf0,  0xfe,  0xd6,  0x0b,  0x10,  0xfe,  0x24,  0x00,  0x02,  0x65,  0xfe,  0xd0,
+  0xf0,  0xfe,  0xe0,  0x0b,  0x10,  0x9e,  0xe5,  0xfe,  0xcf,  0xf0,  0xfe,  0xea,  0x0b,  0x10,  0x58,  0xfe,
+  0x10,  0x10,  0xfe,  0xcc,  0xf0,  0xe2,  0x68,  0x05,  0x1f,  0x4d,  0x10,  0xfe,  0x12,  0x00,  0x2c,  0x0f,
+  0xfe,  0x4e,  0x11,  0x27,  0xfe,  0x00,  0x0c,  0xfe,  0x9e,  0xf0,  0xfe,  0x14,  0x0c,  0xbc,  0x17,  0x34,
+  0x2c,  0x77,  0xe6,  0xc5,  0x24,  0xc6,  0x24,  0x2c,  0xfa,  0x27,  0xfe,  0x20,  0x0c,  0x1c,  0x34,  0x94,
+  0xfe,  0x3c,  0x0c,  0x95,  0x86,  0xc5,  0xdc,  0xc6,  0xdc,  0x02,  0x24,  0x01,  0x4b,  0xfe,  0xdb,  0x10,
+  0x12,  0xfe,  0xe8,  0x00,  0xb5,  0xb6,  0x74,  0xc7,  0x81,  0xc8,  0x83,  0xfe,  0x89,  0xf0,  0x24,  0x33,
+  0x31,  0xe1,  0xc7,  0x81,  0xc8,  0x83,  0x27,  0xfe,  0x66,  0x0c,  0x1d,  0x24,  0x33,  0x31,  0xdf,  0xbc,
+  0x4e,  0x10,  0xfe,  0x42,  0x00,  0x02,  0x65,  0x7c,  0x06,  0xfe,  0x81,  0x49,  0x17,  0xfe,  0x2c,  0x0d,
+  0x08,  0x05,  0x0a,  0xfe,  0x44,  0x13,  0x10,  0x00,  0x55,  0x0a,  0xfe,  0x54,  0x12,  0x55,  0xfe,  0x28,
+  0x00,  0x23,  0xfe,  0x9a,  0x0d,  0x09,  0x46,  0x01,  0x0e,  0x07,  0x00,  0x66,  0x44,  0xfe,  0x28,  0x00,
+  0xfe,  0xe2,  0x10,  0x01,  0xf5,  0x01,  0xf6,  0x09,  0xa4,  0x01,  0xfe,  0x26,  0x0f,  0x64,  0x12,  0x2f,
+  0x01,  0x73,  0x02,  0x2b,  0x10,  0xfe,  0x44,  0x00,  0x55,  0x0a,  0xe9,  0x44,  0x0a,  0xfe,  0xb4,  0x10,
+  0x01,  0xb0,  0x44,  0x0a,  0xfe,  0xaa,  0x10,  0x01,  0xb0,  0xfe,  0x19,  0x82,  0xfe,  0x34,  0x46,  0xac,
+  0x44,  0x0a,  0x10,  0xfe,  0x43,  0x00,  0xfe,  0x96,  0x10,  0x08,  0x54,  0x0a,  0x37,  0x01,  0xf5,  0x01,
+  0xf6,  0x64,  0x12,  0x2f,  0x01,  0x73,  0x99,  0x0a,  0x64,  0x42,  0x92,  0x02,  0xfe,  0x2e,  0x03,  0x08,
+  0x05,  0x0a,  0x8a,  0x44,  0x0a,  0x10,  0x00,  0xfe,  0x5c,  0x10,  0x68,  0x05,  0x1a,  0xfe,  0x58,  0x12,
+  0x08,  0x05,  0x1a,  0xfe,  0x50,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x50,  0x0d,  0xfe,
+  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x56,  0x0d,  0x08,  0x54,  0x1a,  0x37,  0xfe,  0xa9,  0x10,  0x10,
+  0xfe,  0x15,  0x00,  0xfe,  0x04,  0xe6,  0x0a,  0x50,  0xfe,  0x2e,  0x10,  0x10,  0xfe,  0x13,  0x00,  0xfe,
+  0x10,  0x10,  0x10,  0x6f,  0xab,  0x10,  0xfe,  0x41,  0x00,  0xaa,  0x10,  0xfe,  0x24,  0x00,  0x8c,  0xb5,
+  0xb6,  0x74,  0x03,  0x70,  0x28,  0x23,  0xd8,  0x50,  0xfe,  0x04,  0xe6,  0x1a,  0xfe,  0x9d,  0x41,  0xfe,
+  0x1c,  0x42,  0x64,  0x01,  0xe3,  0x02,  0x2b,  0xf8,  0x15,  0x0a,  0x39,  0xa0,  0xb4,  0x15,  0xfe,  0x31,
+  0x00,  0x39,  0xa2,  0x01,  0xfe,  0x48,  0x10,  0x02,  0xd7,  0x42,  0xfe,  0x06,  0xec,  0xd0,  0xfc,  0x44,
+  0x1b,  0xfe,  0xce,  0x45,  0x35,  0x42,  0xfe,  0x06,  0xea,  0xd0,  0xfe,  0x47,  0x4b,  0x91,  0xfe,  0x75,
+  0x57,  0x03,  0x5d,  0xfe,  0x98,  0x56,  0xfe,  0x38,  0x12,  0x09,  0x48,  0x01,  0x0e,  0xfe,  0x44,  0x48,
+  0x4f,  0x08,  0x05,  0x1b,  0xfe,  0x1a,  0x13,  0x09,  0x46,  0x01,  0x0e,  0x41,  0xfe,  0x41,  0x58,  0x09,
+  0xa4,  0x01,  0x0e,  0xfe,  0x49,  0x54,  0x96,  0xfe,  0x1e,  0x0e,  0x02,  0xfe,  0x2e,  0x03,  0x09,  0x5d,
+  0xfe,  0xee,  0x14,  0xfc,  0x44,  0x1b,  0xfe,  0xce,  0x45,  0x35,  0x42,  0xfe,  0xce,  0x47,  0xfe,  0xad,
+  0x13,  0x02,  0x2b,  0x22,  0x20,  0x07,  0x11,  0xfe,  0x9e,  0x12,  0x21,  0x13,  0x59,  0x13,  0x9f,  0x13,
+  0xd5,  0x22,  0x2f,  0x41,  0x39,  0x2f,  0xbc,  0xad,  0xfe,  0xbc,  0xf0,  0xfe,  0xe0,  0x0e,  0x0f,  0x06,
+  0x13,  0x59,  0x01,  0xfe,  0xda,  0x16,  0x03,  0xfe,  0x38,  0x01,  0x29,  0xfe,  0x3a,  0x01,  0x56,  0xfe,
+  0xe4,  0x0e,  0xfe,  0x02,  0xec,  0xd5,  0x69,  0x00,  0x66,  0xfe,  0x04,  0xec,  0x20,  0x4f,  0xfe,  0x05,
+  0xf6,  0xfe,  0x34,  0x01,  0x01,  0xfe,  0x4a,  0x17,  0xfe,  0x08,  0x90,  0xfe,  0x48,  0xf4,  0x0d,  0xfe,
+  0x18,  0x13,  0xba,  0xfe,  0x02,  0xea,  0xd5,  0x69,  0x7e,  0xfe,  0xc5,  0x13,  0x15,  0x1a,  0x39,  0xa0,
+  0xb4,  0xfe,  0x2e,  0x10,  0x03,  0xfe,  0x38,  0x01,  0x1e,  0xfe,  0xf0,  0xff,  0x0c,  0xfe,  0x60,  0x01,
+  0x03,  0xfe,  0x3a,  0x01,  0x0c,  0xfe,  0x62,  0x01,  0x43,  0x13,  0x20,  0x25,  0x06,  0x13,  0x2f,  0x12,
+  0x2f,  0x92,  0x0f,  0x06,  0x04,  0x21,  0x04,  0x22,  0x59,  0xfe,  0xf7,  0x12,  0x22,  0x9f,  0xb7,  0x13,
+  0x9f,  0x07,  0x7e,  0xfe,  0x71,  0x13,  0xfe,  0x24,  0x1c,  0x15,  0x19,  0x39,  0xa0,  0xb4,  0xfe,  0xd9,
+  0x10,  0xc3,  0xfe,  0x03,  0xdc,  0xfe,  0x73,  0x57,  0xfe,  0x80,  0x5d,  0x04,  0xc3,  0xfe,  0x03,  0xdc,
+  0xfe,  0x5b,  0x57,  0xfe,  0x80,  0x5d,  0x04,  0xfe,  0x03,  0x57,  0xc3,  0x21,  0xfe,  0x00,  0xcc,  0x04,
+  0xfe,  0x03,  0x57,  0xc3,  0x78,  0x04,  0x08,  0x05,  0x58,  0xfe,  0x22,  0x13,  0xfe,  0x1c,  0x80,  0x07,
+  0x06,  0xfe,  0x1a,  0x13,  0xfe,  0x1e,  0x80,  0xed,  0xfe,  0x1d,  0x80,  0xae,  0xfe,  0x0c,  0x90,  0xfe,
+  0x0e,  0x13,  0xfe,  0x0e,  0x90,  0xac,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x0a,  0xfe,  0x3c,  0x50,
+  0xaa,  0x01,  0xfe,  0x7a,  0x17,  0x32,  0x07,  0x2f,  0xad,  0x01,  0xfe,  0xb4,  0x16,  0x08,  0x05,  0x1b,
+  0x4e,  0x01,  0xf5,  0x01,  0xf6,  0x12,  0xfe,  0xe9,  0x00,  0x08,  0x05,  0x58,  0xfe,  0x2c,  0x13,  0x01,
+  0xfe,  0x0c,  0x17,  0xfe,  0x1e,  0x1c,  0xfe,  0x14,  0x90,  0xfe,  0x96,  0x90,  0x0c,  0xfe,  0x64,  0x01,
+  0x14,  0xfe,  0x66,  0x01,  0x08,  0x05,  0x5b,  0xfe,  0x12,  0x12,  0xfe,  0x03,  0x80,  0x8d,  0xfe,  0x01,
+  0xec,  0x20,  0xfe,  0x80,  0x40,  0x13,  0x20,  0x6a,  0x2a,  0x12,  0xcf,  0x64,  0x22,  0x20,  0xfb,  0x79,
+  0x20,  0x04,  0xfe,  0x08,  0x1c,  0x03,  0xfe,  0xac,  0x00,  0xfe,  0x06,  0x58,  0x03,  0xfe,  0xae,  0x00,
+
+  0xfe,  0x07,  0x58,  0x03,  0xfe,  0xb0,  0x00,  0xfe,  0x08,  0x58,  0x03,  0xfe,  0xb2,  0x00,  0xfe,  0x09,
+  0x58,  0xfe,  0x0a,  0x1c,  0x25,  0x6e,  0x13,  0xd0,  0x21,  0x0c,  0x5c,  0x0c,  0x45,  0x0f,  0x46,  0x52,
+  0x50,  0x18,  0x1b,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x23,  0xfe,  0xfc,  0x0f,  0x44,  0x11,  0x0f,
+  0x48,  0x52,  0x18,  0x58,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x23,  0xe4,  0x25,  0x11,  0x13,  0x20,
+  0x7c,  0x6f,  0x4f,  0x22,  0x20,  0xfb,  0x79,  0x20,  0x12,  0xcf,  0xfe,  0x14,  0x56,  0xfe,  0xd6,  0xf0,
+  0xfe,  0x26,  0x10,  0xf8,  0x74,  0xfe,  0x14,  0x1c,  0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x04,  0x42,
+  0xfe,  0x0c,  0x14,  0xfc,  0xfe,  0x07,  0xe6,  0x1b,  0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x04,  0x01,
+  0xb0,  0x7c,  0x6f,  0x4f,  0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x42,  0x13,  0x32,  0x07,  0x2f,
+  0xfe,  0x34,  0x13,  0x09,  0x48,  0x01,  0x0e,  0xbb,  0xfe,  0x36,  0x12,  0xfe,  0x41,  0x48,  0xfe,  0x45,
+  0x48,  0x01,  0xf0,  0xfe,  0x00,  0xcc,  0xbb,  0xfe,  0xf3,  0x13,  0x43,  0x78,  0x07,  0x11,  0xac,  0x09,
+  0x84,  0x01,  0x0e,  0xfe,  0x80,  0x5c,  0x01,  0x73,  0xfe,  0x0e,  0x10,  0x07,  0x82,  0x4e,  0xfe,  0x14,
+  0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0x60,  0x10,  0x04,  0xfe,  0x44,  0x58,  0x8d,  0xfe,  0x01,  0xec,  0xa2,
+  0xfe,  0x9e,  0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x1a,  0x79,  0x2a,  0x01,  0xe3,  0xfe,
+  0xdd,  0x10,  0x2c,  0xc7,  0x81,  0xc8,  0x83,  0x33,  0x31,  0xde,  0x07,  0x1a,  0xfe,  0x48,  0x12,  0x07,
+  0x0a,  0xfe,  0x56,  0x12,  0x07,  0x19,  0xfe,  0x30,  0x12,  0x07,  0xc9,  0x17,  0xfe,  0x32,  0x12,  0x07,
+  0xfe,  0x23,  0x00,  0x17,  0xeb,  0x07,  0x06,  0x17,  0xfe,  0x9c,  0x12,  0x07,  0x1f,  0xfe,  0x12,  0x12,
+  0x07,  0x00,  0x17,  0x24,  0x15,  0xc9,  0x01,  0x36,  0xa9,  0x2d,  0x01,  0x0b,  0x94,  0x4b,  0x04,  0x2d,
+  0xdd,  0x09,  0xd1,  0x01,  0xfe,  0x26,  0x0f,  0x12,  0x82,  0x02,  0x2b,  0x2d,  0x32,  0x07,  0xa6,  0xfe,
+  0xd9,  0x13,  0x3a,  0x3d,  0x3b,  0x3e,  0x56,  0xfe,  0xf0,  0x11,  0x08,  0x05,  0x5a,  0xfe,  0x72,  0x12,
+  0x9b,  0x2e,  0x9c,  0x3c,  0x90,  0xc0,  0x96,  0xfe,  0xba,  0x11,  0x22,  0x62,  0xfe,  0x26,  0x13,  0x03,
+  0x7f,  0x29,  0x80,  0x56,  0xfe,  0x76,  0x0d,  0x0c,  0x60,  0x14,  0x61,  0x21,  0x0c,  0x7f,  0x0c,  0x80,
+  0x01,  0xb3,  0x25,  0x6e,  0x77,  0x13,  0x62,  0x01,  0xef,  0x9b,  0x2e,  0x9c,  0x3c,  0xfe,  0x04,  0x55,
+  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,  0x2e,  0xfe,  0x05,  0xfa,  0x3c,  0xfe,  0x91,  0x10,  0x03,  0x3f,
+  0x29,  0x40,  0xfe,  0x40,  0x56,  0xfe,  0xe1,  0x56,  0x0c,  0x3f,  0x14,  0x40,  0x88,  0x9b,  0x2e,  0x9c,
+  0x3c,  0x90,  0xc0,  0x03,  0x5e,  0x29,  0x5f,  0xfe,  0x00,  0x56,  0xfe,  0xa1,  0x56,  0x0c,  0x5e,  0x14,
+  0x5f,  0x08,  0x05,  0x5a,  0xfe,  0x1e,  0x12,  0x22,  0x62,  0xfe,  0x1f,  0x40,  0x03,  0x60,  0x29,  0x61,
+  0xfe,  0x2c,  0x50,  0xfe,  0xae,  0x50,  0x03,  0x3f,  0x29,  0x40,  0xfe,  0x44,  0x50,  0xfe,  0xc6,  0x50,
+  0x03,  0x5e,  0x29,  0x5f,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x03,  0x3d,  0x29,  0x3e,  0xfe,  0x40,
+  0x50,  0xfe,  0xc2,  0x50,  0x02,  0x89,  0x25,  0x06,  0x13,  0xd4,  0x02,  0x72,  0x2d,  0x01,  0x0b,  0x1d,
+  0x4c,  0x33,  0x31,  0xde,  0x07,  0x06,  0x23,  0x4c,  0x32,  0x07,  0xa6,  0x23,  0x72,  0x01,  0xaf,  0x1e,
+  0x43,  0x17,  0x4c,  0x08,  0x05,  0x0a,  0xee,  0x3a,  0x3d,  0x3b,  0x3e,  0xfe,  0x0a,  0x55,  0x35,  0xfe,
+  0x8b,  0x55,  0x57,  0x3d,  0x7d,  0x3e,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0x02,  0x72,  0xfe,  0x19,
+  0x81,  0xba,  0xfe,  0x19,  0x41,  0x02,  0x72,  0x2d,  0x01,  0x0b,  0x1c,  0x34,  0x1d,  0xe8,  0x33,  0x31,
+  0xe1,  0x55,  0x19,  0xfe,  0xa6,  0x12,  0x55,  0x0a,  0x4d,  0x02,  0x4c,  0x01,  0x0b,  0x1c,  0x34,  0x1d,
+  0xe8,  0x33,  0x31,  0xdf,  0x07,  0x19,  0x23,  0x4c,  0x01,  0x0b,  0x1d,  0xe8,  0x33,  0x31,  0xfe,  0xe8,
+  0x09,  0xfe,  0xc2,  0x49,  0x51,  0x03,  0xfe,  0x9c,  0x00,  0x28,  0x8a,  0x53,  0x05,  0x1f,  0x35,  0xa9,
+  0xfe,  0xbb,  0x45,  0x55,  0x00,  0x4e,  0x44,  0x06,  0x7c,  0x43,  0xfe,  0xda,  0x14,  0x01,  0xaf,  0x8c,
+  0xfe,  0x4b,  0x45,  0xee,  0x32,  0x07,  0xa5,  0xed,  0x03,  0xcd,  0x28,  0x8a,  0x03,  0x45,  0x28,  0x35,
+  0x67,  0x02,  0x72,  0xfe,  0xc0,  0x5d,  0xfe,  0xf8,  0x14,  0xfe,  0x03,  0x17,  0x03,  0x5c,  0xc1,  0x0c,
+  0x5c,  0x67,  0x2d,  0x01,  0x0b,  0x26,  0x89,  0x01,  0xfe,  0x9e,  0x15,  0x02,  0x89,  0x01,  0x0b,  0x1c,
+  0x34,  0x1d,  0x4c,  0x33,  0x31,  0xdf,  0x07,  0x06,  0x23,  0x4c,  0x01,  0xf1,  0xfe,  0x42,  0x58,  0xf1,
+  0xfe,  0xa4,  0x14,  0x8c,  0xfe,  0x4a,  0xf4,  0x0a,  0x17,  0x4c,  0xfe,  0x4a,  0xf4,  0x06,  0xea,  0x32,
+  0x07,  0xa5,  0x8b,  0x02,  0x72,  0x03,  0x45,  0xc1,  0x0c,  0x45,  0x67,  0x2d,  0x01,  0x0b,  0x26,  0x89,
+  0x01,  0xfe,  0xcc,  0x15,  0x02,  0x89,  0x0f,  0x06,  0x27,  0xfe,  0xbe,  0x13,  0x26,  0xfe,  0xd4,  0x13,
+  0x76,  0xfe,  0x89,  0x48,  0x01,  0x0b,  0x21,  0x76,  0x04,  0x7b,  0xfe,  0xd0,  0x13,  0x1c,  0xfe,  0xd0,
+  0x13,  0x1d,  0xfe,  0xbe,  0x13,  0x67,  0x2d,  0x01,  0x0b,  0xfe,  0xd5,  0x10,  0x0f,  0x71,  0xff,  0x02,
+  0x00,  0x57,  0x52,  0x93,  0x1e,  0xfe,  0xff,  0x7f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x04,  0x0f,
+  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,  0x93,  0x1e,  0x43,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x04,
+  0x0f,  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,  0x93,  0x04,  0x0f,  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,
+  0x93,  0xfe,  0x0b,  0x58,  0x04,  0x09,  0x5c,  0x01,  0x87,  0x09,  0x45,  0x01,  0x87,  0x04,  0xfe,  0x03,
+  0xa1,  0x1e,  0x11,  0xff,  0x03,  0x00,  0x54,  0xfe,  0x00,  0xf4,  0x1f,  0x52,  0xfe,  0x00,  0x7d,  0xfe,
+  0x01,  0x7d,  0xfe,  0x02,  0x7d,  0xfe,  0x03,  0x7c,  0x6a,  0x2a,  0x0c,  0x5e,  0x14,  0x5f,  0x57,  0x3f,
+  0x7d,  0x40,  0x04,  0xdd,  0xfe,  0x82,  0x4a,  0xfe,  0xe1,  0x1a,  0xfe,  0x83,  0x5a,  0x8d,  0x04,  0x01,
+  0xfe,  0x0c,  0x19,  0xfe,  0x42,  0x48,  0x50,  0x51,  0x91,  0x01,  0x0b,  0x1d,  0xfe,  0x96,  0x15,  0x33,
+  0x31,  0xe1,  0x01,  0x0b,  0x1d,  0xfe,  0x96,  0x15,  0x33,  0x31,  0xfe,  0xe8,  0x0a,  0xfe,  0xc1,  0x59,
+  0x03,  0xcd,  0x28,  0xfe,  0xcc,  0x12,  0x53,  0x05,  0x1a,  0xfe,  0xc4,  0x13,  0x21,  0x69,  0x1a,  0xee,
+  0x55,  0xca,  0x6b,  0xfe,  0xdc,  0x14,  0x4d,  0x0f,  0x06,  0x18,  0xca,  0x7c,  0x30,  0xfe,  0x78,  0x10,
+  0xff,  0x02,  0x83,  0x55,  0xab,  0xff,  0x02,  0x83,  0x55,  0x69,  0x19,  0xae,  0x98,  0xfe,  0x30,  0x00,
+  0x96,  0xf2,  0x18,  0x6d,  0x0f,  0x06,  0xfe,  0x56,  0x10,  0x69,  0x0a,  0xed,  0x98,  0xfe,  0x64,  0x00,
+  0x96,  0xf2,  0x09,  0xfe,  0x64,  0x00,  0x18,  0x9e,  0x0f,  0x06,  0xfe,  0x28,  0x10,  0x69,  0x06,  0xfe,
+  0x60,  0x13,  0x98,  0xfe,  0xc8,  0x00,  0x96,  0xf2,  0x09,  0xfe,  0xc8,  0x00,  0x18,  0x59,  0x0f,  0x06,
+  0x88,  0x98,  0xfe,  0x90,  0x01,  0x7a,  0xfe,  0x42,  0x15,  0x91,  0xe4,  0xfe,  0x43,  0xf4,  0x9f,  0xfe,
+  0x56,  0xf0,  0xfe,  0x54,  0x15,  0xfe,  0x04,  0xf4,  0x71,  0xfe,  0x43,  0xf4,  0x9e,  0xfe,  0xf3,  0x10,
+  0xfe,  0x40,  0x5c,  0x01,  0xfe,  0x16,  0x14,  0x1e,  0x43,  0xec,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,
+  0x6e,  0x7a,  0xfe,  0x90,  0x15,  0xc4,  0x6e,  0xfe,  0x1c,  0x10,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,
+  0xcc,  0x7a,  0xfe,  0x90,  0x15,  0xc4,  0xcc,  0x88,  0x51,  0x21,  0xfe,  0x4d,  0xf4,  0x00,  0xe9,  0x91,
+  0x0f,  0x06,  0xfe,  0xb4,  0x56,  0xfe,  0xc3,  0x58,  0x04,  0x51,  0x0f,  0x0a,  0x04,  0x16,  0x06,  0x01,
+  0x0b,  0x26,  0xf3,  0x16,  0x0a,  0x01,  0x0b,  0x26,  0xf3,  0x16,  0x19,  0x01,  0x0b,  0x26,  0xf3,  0x76,
+  0xfe,  0x89,  0x49,  0x01,  0x0b,  0x04,  0x16,  0x06,  0x01,  0x0b,  0x26,  0xb1,  0x16,  0x19,  0x01,  0x0b,
+  0x26,  0xb1,  0x16,  0x06,  0x01,  0x0b,  0x26,  0xb1,  0xfe,  0x89,  0x49,  0x01,  0x0b,  0x26,  0xb1,  0x76,
+  0xfe,  0x89,  0x4a,  0x01,  0x0b,  0x04,  0x51,  0x04,  0x22,  0xd3,  0x07,  0x06,  0xfe,  0x48,  0x13,  0xb8,
+  0x13,  0xd3,  0xfe,  0x49,  0xf4,  0x00,  0x4d,  0x76,  0xa9,  0x67,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,
+  0xfe,  0x89,  0x48,  0xff,  0x02,  0x00,  0x10,  0x27,  0xfe,  0x2e,  0x16,  0x32,  0x07,  0xfe,  0xe3,  0x00,
+  0xfe,  0x20,  0x13,  0x1d,  0xfe,  0x52,  0x16,  0x21,  0x13,  0xd4,  0x01,  0x4b,  0x22,  0xd4,  0x07,  0x06,
+  0x4e,  0x08,  0x54,  0x06,  0x37,  0x04,  0x09,  0x48,  0x01,  0x0e,  0xfb,  0x8e,  0x07,  0x11,  0xae,  0x09,
+  0x84,  0x01,  0x0e,  0x8e,  0x09,  0x5d,  0x01,  0xa8,  0x04,  0x09,  0x84,  0x01,  0x0e,  0x8e,  0xfe,  0x80,
+  0xe7,  0x11,  0x07,  0x11,  0x8a,  0xfe,  0x45,  0x58,  0x01,  0xf0,  0x8e,  0x04,  0x09,  0x48,  0x01,  0x0e,
+  0x8e,  0x09,  0x5d,  0x01,  0xa8,  0x04,  0x09,  0x48,  0x01,  0x0e,  0xfe,  0x80,  0x80,  0xfe,  0x80,  0x4c,
+  0xfe,  0x49,  0xe4,  0x11,  0xae,  0x09,  0x84,  0x01,  0x0e,  0xfe,  0x80,  0x4c,  0x09,  0x5d,  0x01,  0x87,
+  0x04,  0x18,  0x11,  0x75,  0x6c,  0xfe,  0x60,  0x01,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x24,
+  0x1c,  0xfe,  0x1d,  0xf7,  0x1b,  0x97,  0xfe,  0xee,  0x16,  0x01,  0xfe,  0xf4,  0x17,  0xad,  0x9a,  0x1b,
+  0x6c,  0xfe,  0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x04,  0xb9,  0x23,  0xfe,  0xde,  0x16,  0xfe,  0xda,  0x10,
+  0x18,  0x11,  0x75,  0x03,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x1f,  0xfe,  0x18,  0x58,  0x03,  0xfe,
+  0x66,  0x01,  0xfe,  0x19,  0x58,  0x9a,  0x1f,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x06,  0xfe,  0x3c,
+  0x50,  0x6c,  0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x1f,  0x97,  0xfe,  0x38,  0x17,
+  0xfe,  0xb6,  0x14,  0x35,  0x04,  0xb9,  0x23,  0xfe,  0x10,  0x17,  0xfe,  0x9c,  0x10,  0x18,  0x11,  0x75,
+  0xfe,  0x83,  0x5a,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x1d,  0xf7,  0x2e,  0x97,  0xfe,  0x5a,
+  0x17,  0xfe,  0x94,  0x14,  0xec,  0x9a,  0x2e,  0x6c,  0x1a,  0xfe,  0xaf,  0x19,  0xfe,  0x98,  0xe7,  0x00,
+  0x04,  0xb9,  0x23,  0xfe,  0x4e,  0x17,  0xfe,  0x6c,  0x10,  0x18,  0x11,  0x75,  0xfe,  0x30,  0xbc,  0xfe,
+  0xb2,  0xbc,  0x9a,  0xcb,  0x6c,  0x1a,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0xcb,  0x97,  0xfe,  0x92,
+  0x17,  0xfe,  0x5c,  0x14,  0x35,  0x04,  0xb9,  0x23,  0xfe,  0x7e,  0x17,  0xfe,  0x42,  0x10,  0xfe,  0x02,
+  0xf6,  0x11,  0x75,  0xfe,  0x18,  0xfe,  0x60,  0xfe,  0x19,  0xfe,  0x61,  0xfe,  0x03,  0xa1,  0xfe,  0x1d,
+  0xf7,  0x5b,  0x97,  0xfe,  0xb8,  0x17,  0xfe,  0x36,  0x14,  0xfe,  0x1c,  0x13,  0x9a,  0x5b,  0x41,  0xfe,
+  0x83,  0x58,  0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x11,  0xfe,  0x81,  0xe7,  0x11,  0x12,  0xfe,  0xdd,
+  0x00,  0x6a,  0x2a,  0x04,  0x6a,  0x2a,  0xfe,  0x12,  0x45,  0x23,  0xfe,  0xa8,  0x17,  0x15,  0x06,  0x39,
+  0xa0,  0xb4,  0x02,  0x2b,  0xfe,  0x39,  0xf0,  0xfe,  0xfc,  0x17,  0x21,  0x04,  0xfe,  0x7e,  0x18,  0x1e,
+  0x19,  0x66,  0x0f,  0x0d,  0x04,  0x75,  0x03,  0xd2,  0x1e,  0x06,  0xfe,  0xef,  0x12,  0xfe,  0xe1,  0x10,
+  0x7c,  0x6f,  0x4f,  0x32,  0x07,  0x2f,  0xfe,  0x3c,  0x13,  0xf1,  0xfe,  0x42,  0x13,  0x42,  0x92,  0x09,
+  0x48,  0x01,  0x0e,  0xbb,  0xeb,  0xfe,  0x41,  0x48,  0xfe,  0x45,  0x48,  0x01,  0xf0,  0xfe,  0x00,  0xcc,
+  0xbb,  0xfe,  0xf3,  0x13,  0x43,  0x78,  0x07,  0x11,  0xac,  0x09,  0x84,  0x01,  0x0e,  0xfe,  0x80,  0x4c,
+  0x01,  0x73,  0xfe,  0x16,  0x10,  0x07,  0x82,  0x8b,  0xfe,  0x40,  0x14,  0xfe,  0x24,  0x12,  0xfe,  0x14,
+  0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0x1c,  0x18,  0x18,  0x0a,  0x04,  0xfe,  0x9c,  0xe7,  0x0a,  0x10,  0xfe,
+  0x15,  0x00,  0x64,  0x79,  0x2a,  0x01,  0xe3,  0x18,  0x06,  0x04,  0x42,  0x92,  0x08,  0x54,  0x1b,  0x37,
+  0x12,  0x2f,  0x01,  0x73,  0x18,  0x06,  0x04,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,  0x3a,  0xce,  0x3b,
+  0xcf,  0xfe,  0x48,  0x55,  0x35,  0xfe,  0xc9,  0x55,  0x04,  0x22,  0xa3,  0x77,  0x13,  0xa3,  0x04,  0x09,
+  0xa4,  0x01,  0x0e,  0xfe,  0x41,  0x48,  0x09,  0x46,  0x01,  0x0e,  0xfe,  0x49,  0x44,  0x17,  0xfe,  0xe8,
+  0x18,  0x77,  0x78,  0x04,  0x09,  0x48,  0x01,  0x0e,  0x07,  0x11,  0x4e,  0x09,  0x5d,  0x01,  0xa8,  0x09,
+  0x46,  0x01,  0x0e,  0x77,  0x78,  0x04,  0xfe,  0x4e,  0xe4,  0x19,  0x6b,  0xfe,  0x1c,  0x19,  0x03,  0xfe,
+  0x90,  0x00,  0xfe,  0x3a,  0x45,  0xfe,  0x2c,  0x10,  0xfe,  0x4e,  0xe4,  0xc9,  0x6b,  0xfe,  0x2e,  0x19,
+  0x03,  0xfe,  0x92,  0x00,  0xfe,  0x02,  0xe6,  0x1a,  0xe5,  0xfe,  0x4e,  0xe4,  0xfe,  0x0b,  0x00,  0x6b,
+  0xfe,  0x40,  0x19,  0x03,  0xfe,  0x94,  0x00,  0xfe,  0x02,  0xe6,  0x1f,  0xfe,  0x08,  0x10,  0x03,  0xfe,
+  0x96,  0x00,  0xfe,  0x02,  0xe6,  0x6d,  0xfe,  0x4e,  0x45,  0xea,  0xba,  0xff,  0x04,  0x68,  0x54,  0xe7,
+  0x1e,  0x6e,  0xfe,  0x08,  0x1c,  0xfe,  0x67,  0x19,  0xfe,  0x0a,  0x1c,  0xfe,  0x1a,  0xf4,  0xfe,  0x00,
+  0x04,  0xea,  0xfe,  0x48,  0xf4,  0x19,  0x7a,  0xfe,  0x74,  0x19,  0x0f,  0x19,  0x04,  0x07,  0x7e,  0xfe,
+  0x5a,  0xf0,  0xfe,  0x84,  0x19,  0x25,  0xfe,  0x09,  0x00,  0xfe,  0x34,  0x10,  0x07,  0x1a,  0xfe,  0x5a,
+  0xf0,  0xfe,  0x92,  0x19,  0x25,  0xca,  0xfe,  0x26,  0x10,  0x07,  0x19,  0x66,  0x25,  0x6d,  0xe5,  0x07,
+  0x0a,  0x66,  0x25,  0x9e,  0xfe,  0x0e,  0x10,  0x07,  0x06,  0x66,  0x25,  0x59,  0xa9,  0xb8,  0x04,  0x15,
+  0xfe,  0x09,  0x00,  0x01,  0x36,  0xfe,  0x04,  0xfe,  0x81,  0x03,  0x83,  0xfe,  0x40,  0x5c,  0x04,  0x1c,
+  0xf7,  0xfe,  0x14,  0xf0,  0x0b,  0x27,  0xfe,  0xd6,  0x19,  0x1c,  0xf7,  0x7b,  0xf7,  0xfe,  0x82,  0xf0,
+  0xfe,  0xda,  0x19,  0x04,  0xff,  0xcc,  0x00,  0x00,
 };
 
 STATIC unsigned short _adv_asc38C0800_size =
-    sizeof(_adv_asc38C0800_buf); /* 0x14F1 */
+        sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
 STATIC ADV_DCNT _adv_asc38C0800_chksum =
-    0x053503A5; /* Expanded checksum. */
+        0x050D3FD8UL; /* Expanded little-endian checksum. */
+
+/* Microcode buffer is kept after initialization for error recovery. */
+STATIC unsigned char _adv_asc38C1600_buf[] = {
+  0x00,  0x00,  0x00,  0xf2,  0x00,  0x16,  0x00,  0xfc,  0x00,  0x10,  0x00,  0xf0,  0x18,  0xe4,  0x01,  0x00,
+  0x04,  0x1e,  0x48,  0xe4,  0x03,  0xf6,  0xf7,  0x13,  0x2e,  0x1e,  0x02,  0x00,  0x07,  0x17,  0xc0,  0x5f,
+  0x00,  0xfa,  0xff,  0xff,  0x04,  0x00,  0x00,  0xf6,  0x09,  0xe7,  0x82,  0xe7,  0x85,  0xf0,  0x86,  0xf0,
+  0x4e,  0x10,  0x9e,  0xe7,  0xff,  0x00,  0x55,  0xf0,  0x01,  0xf6,  0x03,  0x00,  0x98,  0x57,  0x01,  0xe6,
+  0x00,  0xea,  0x00,  0xec,  0x01,  0xfa,  0x18,  0xf4,  0x08,  0x00,  0xf0,  0x1d,  0x38,  0x54,  0x32,  0xf0,
+  0x10,  0x00,  0xc2,  0x0e,  0x1e,  0xf0,  0xd5,  0xf0,  0xbc,  0x00,  0x4b,  0xe4,  0x00,  0xe6,  0xb1,  0xf0,
+  0xb4,  0x00,  0x02,  0x13,  0x3e,  0x1c,  0xc8,  0x47,  0x3e,  0x00,  0xd8,  0x01,  0x06,  0x13,  0x0c,  0x1c,
+  0x5e,  0x1e,  0x00,  0x57,  0xc8,  0x57,  0x01,  0xfc,  0xbc,  0x0e,  0xa2,  0x12,  0xb9,  0x54,  0x00,  0x80,
+  0x62,  0x0a,  0x5a,  0x12,  0xc8,  0x15,  0x3e,  0x1e,  0x18,  0x40,  0xbd,  0x56,  0x03,  0xe6,  0x01,  0xea,
+  0x5c,  0xf0,  0x0f,  0x00,  0x20,  0x00,  0x6c,  0x01,  0x6e,  0x01,  0x04,  0x12,  0x04,  0x13,  0xbb,  0x55,
+  0x3c,  0x56,  0x3e,  0x57,  0x03,  0x58,  0x4a,  0xe4,  0x40,  0x00,  0xb6,  0x00,  0xbb,  0x00,  0xc0,  0x00,
+  0x00,  0x01,  0x01,  0x01,  0x3e,  0x01,  0x58,  0x0a,  0x44,  0x10,  0x0a,  0x12,  0x4c,  0x1c,  0x4e,  0x1c,
+  0x02,  0x4a,  0x30,  0xe4,  0x05,  0xe6,  0x0c,  0x00,  0x3c,  0x00,  0x80,  0x00,  0x24,  0x01,  0x3c,  0x01,
+  0x68,  0x01,  0x6a,  0x01,  0x70,  0x01,  0x72,  0x01,  0x74,  0x01,  0x76,  0x01,  0x78,  0x01,  0x7c,  0x01,
+  0xc6,  0x0e,  0x0c,  0x10,  0xac,  0x12,  0xae,  0x12,  0x16,  0x1a,  0x32,  0x1c,  0x6e,  0x1e,  0x02,  0x48,
+  0x3a,  0x55,  0xc9,  0x57,  0x02,  0xee,  0x5b,  0xf0,  0x03,  0xf7,  0x06,  0xf7,  0x03,  0xfc,  0x06,  0x00,
+  0x1e,  0x00,  0xbe,  0x00,  0xe1,  0x00,  0x0c,  0x12,  0x18,  0x1a,  0x70,  0x1a,  0x30,  0x1c,  0x38,  0x1c,
+  0x10,  0x44,  0x00,  0x4c,  0xb0,  0x57,  0x40,  0x5c,  0x4d,  0xe4,  0x04,  0xea,  0x5d,  0xf0,  0xa7,  0xf0,
+  0x04,  0xf6,  0x02,  0xfc,  0x05,  0x00,  0x09,  0x00,  0x19,  0x00,  0x32,  0x00,  0x33,  0x00,  0x34,  0x00,
+  0x36,  0x00,  0x98,  0x00,  0x9e,  0x00,  0xcc,  0x00,  0x20,  0x01,  0x4e,  0x01,  0x79,  0x01,  0x3c,  0x09,
+  0x68,  0x0d,  0x02,  0x10,  0x04,  0x10,  0x3a,  0x10,  0x08,  0x12,  0x0a,  0x13,  0x40,  0x16,  0x50,  0x16,
+  0x00,  0x17,  0x4a,  0x19,  0x00,  0x4e,  0x00,  0x54,  0x01,  0x58,  0x00,  0xdc,  0x05,  0xf0,  0x09,  0xf0,
+  0x59,  0xf0,  0xb8,  0xf0,  0x48,  0xf4,  0x0e,  0xf7,  0x0a,  0x00,  0x9b,  0x00,  0x9c,  0x00,  0xa4,  0x00,
+  0xb5,  0x00,  0xba,  0x00,  0xd0,  0x00,  0xe7,  0x00,  0xf0,  0x03,  0x69,  0x08,  0xe9,  0x09,  0x5c,  0x0c,
+  0xb6,  0x12,  0xbc,  0x19,  0xd8,  0x1b,  0x20,  0x1c,  0x34,  0x1c,  0x36,  0x1c,  0x42,  0x1d,  0x08,  0x44,
+  0x38,  0x44,  0x91,  0x44,  0x0a,  0x45,  0x48,  0x46,  0x89,  0x48,  0x68,  0x54,  0x83,  0x55,  0x83,  0x59,
+  0x31,  0xe4,  0x02,  0xe6,  0x07,  0xf0,  0x08,  0xf0,  0x0b,  0xf0,  0x0c,  0xf0,  0x4b,  0xf4,  0x04,  0xf8,
+  0x05,  0xf8,  0x02,  0xfa,  0x03,  0xfa,  0x04,  0xfc,  0x05,  0xfc,  0x07,  0x00,  0xa8,  0x00,  0xaa,  0x00,
+  0xb9,  0x00,  0xe0,  0x00,  0xe5,  0x00,  0x22,  0x01,  0x26,  0x01,  0x60,  0x01,  0x7a,  0x01,  0x82,  0x01,
+  0xc8,  0x01,  0xca,  0x01,  0x86,  0x02,  0x6a,  0x03,  0x18,  0x05,  0xb2,  0x07,  0x68,  0x08,  0x10,  0x0d,
+  0x06,  0x10,  0x0a,  0x10,  0x0e,  0x10,  0x12,  0x10,  0x60,  0x10,  0xed,  0x10,  0xf3,  0x10,  0x06,  0x12,
+  0x10,  0x12,  0x1e,  0x12,  0x0c,  0x13,  0x0e,  0x13,  0x10,  0x13,  0xfe,  0x9c,  0xf0,  0x35,  0x05,  0xfe,
+  0xec,  0x0e,  0xff,  0x10,  0x00,  0x00,  0xe9,  0xfe,  0x34,  0x1f,  0x00,  0xe8,  0xfe,  0x88,  0x01,  0xff,
+  0x03,  0x00,  0x00,  0xfe,  0x93,  0x15,  0xfe,  0x0f,  0x05,  0xff,  0x38,  0x00,  0x00,  0xfe,  0x57,  0x24,
+  0x00,  0xfe,  0x4c,  0x00,  0x65,  0xff,  0x04,  0x00,  0x00,  0x1a,  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,
+  0x01,  0x01,  0xff,  0x08,  0xff,  0xff,  0xff,  0x27,  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,  0xff,  0x13,
+  0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xe8,
+  0x37,  0x7d,  0x0d,  0x01,  0xfe,  0x4a,  0x11,  0xfe,  0x04,  0xf7,  0xe8,  0x7d,  0x0d,  0x51,  0x37,  0xfe,
+  0x3d,  0xf0,  0xfe,  0x0c,  0x02,  0xfe,  0x20,  0xf0,  0xbc,  0xfe,  0x91,  0xf0,  0xfe,  0xf8,  0x01,  0xfe,
+  0x90,  0xf0,  0xfe,  0xf8,  0x01,  0xfe,  0x8f,  0xf0,  0xbc,  0x03,  0x67,  0x4d,  0x05,  0xfe,  0x08,  0x0f,
+  0x01,  0xfe,  0x78,  0x0f,  0xfe,  0xdd,  0x12,  0x05,  0xfe,  0x0e,  0x03,  0xfe,  0x28,  0x1c,  0x03,  0xfe,
+  0xa6,  0x00,  0xfe,  0xd1,  0x12,  0x3e,  0x22,  0xfe,  0xa6,  0x00,  0xac,  0xfe,  0x48,  0xf0,  0xfe,  0x90,
+  0x02,  0xfe,  0x49,  0xf0,  0xfe,  0xaa,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xc8,  0x02,  0xfe,  0x46,  0xf0,
+  0xfe,  0x5a,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x60,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x4e,  0x02,  0xfe,
+  0x44,  0xf0,  0xfe,  0x52,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x56,  0x02,  0x1c,  0x0d,  0xa2,  0x1c,  0x07,
+  0x22,  0xb7,  0x05,  0x35,  0xfe,  0x00,  0x1c,  0xfe,  0xf1,  0x10,  0xfe,  0x02,  0x1c,  0xf5,  0xfe,  0x1e,
+  0x1c,  0xfe,  0xe9,  0x10,  0x01,  0x5f,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xde,  0x0a,  0x81,  0x01,
+  0xa3,  0x05,  0x35,  0x1f,  0x95,  0x47,  0xb8,  0x01,  0xfe,  0xe4,  0x11,  0x0a,  0x81,  0x01,  0x5c,  0xfe,
+  0xbd,  0x10,  0x0a,  0x81,  0x01,  0x5c,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x1c,
+  0x07,  0x22,  0xb7,  0x37,  0x2a,  0x35,  0xfe,  0x3d,  0xf0,  0xfe,  0x0c,  0x02,  0x2b,  0xfe,  0x9e,  0x02,
+  0xfe,  0x5a,  0x1c,  0xfe,  0x12,  0x1c,  0xfe,  0x14,  0x1c,  0x1f,  0xfe,  0x30,  0x00,  0x47,  0xb8,  0x01,
+  0xfe,  0xd4,  0x11,  0x1c,  0x07,  0x22,  0xb7,  0x05,  0xe9,  0x21,  0x2c,  0x09,  0x1a,  0x31,  0xfe,  0x69,
+  0x10,  0x1c,  0x07,  0x22,  0xb7,  0xfe,  0x04,  0xec,  0x2c,  0x60,  0x01,  0xfe,  0x1e,  0x1e,  0x20,  0x2c,
+  0xfe,  0x05,  0xf6,  0xde,  0x01,  0xfe,  0x62,  0x1b,  0x01,  0x0c,  0x61,  0x4a,  0x44,  0x15,  0x56,  0x51,
+  0x01,  0xfe,  0x9e,  0x1e,  0x01,  0xfe,  0x96,  0x1a,  0x05,  0x35,  0x0a,  0x57,  0x01,  0x18,  0x09,  0x00,
+  0x36,  0x01,  0x85,  0xfe,  0x18,  0x10,  0xfe,  0x41,  0x58,  0x0a,  0xba,  0x01,  0x18,  0xfe,  0xc8,  0x54,
+  0x7b,  0xfe,  0x1c,  0x03,  0x01,  0xfe,  0x96,  0x1a,  0x05,  0x35,  0x37,  0x60,  0xfe,  0x02,  0xe8,  0x30,
+  0xfe,  0xbf,  0x57,  0xfe,  0x9e,  0x43,  0xfe,  0x77,  0x57,  0xfe,  0x27,  0xf0,  0xfe,  0xe4,  0x01,  0xfe,
+  0x07,  0x4b,  0xfe,  0x20,  0xf0,  0xbc,  0xfe,  0x40,  0x1c,  0x2a,  0xeb,  0xfe,  0x26,  0xf0,  0xfe,  0x66,
+  0x03,  0xfe,  0xa0,  0xf0,  0xfe,  0x54,  0x03,  0xfe,  0x11,  0xf0,  0xbc,  0xfe,  0xef,  0x10,  0xfe,  0x9f,
+  0xf0,  0xfe,  0x74,  0x03,  0xfe,  0x46,  0x1c,  0x19,  0xfe,  0x11,  0x00,  0x05,  0x70,  0x37,  0xfe,  0x48,
+  0x1c,  0xfe,  0x46,  0x1c,  0x01,  0x0c,  0x06,  0x28,  0xfe,  0x18,  0x13,  0x26,  0x21,  0xb9,  0xc7,  0x20,
+  0xb9,  0x0a,  0x57,  0x01,  0x18,  0xc7,  0x89,  0x01,  0xfe,  0xc8,  0x1a,  0x15,  0xe1,  0x2a,  0xeb,  0xfe,
+  0x01,  0xf0,  0xeb,  0xfe,  0x82,  0xf0,  0xfe,  0xa4,  0x03,  0xfe,  0x9c,  0x32,  0x15,  0xfe,  0xe4,  0x00,
+  0x2f,  0xfe,  0xb6,  0x03,  0x2a,  0x3c,  0x16,  0xfe,  0xc6,  0x03,  0x01,  0x41,  0xfe,  0x06,  0xf0,  0xfe,
+  0xd6,  0x03,  0xaf,  0xa0,  0xfe,  0x0a,  0xf0,  0xfe,  0xa2,  0x07,  0x05,  0x29,  0x03,  0x81,  0x1e,  0x1b,
+  0xfe,  0x24,  0x05,  0x1f,  0x63,  0x01,  0x42,  0x8f,  0xfe,  0x70,  0x02,  0x05,  0xea,  0xfe,  0x46,  0x1c,
+  0x37,  0x7d,  0x1d,  0xfe,  0x67,  0x1b,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0xfe,  0x48,  0x1c,  0x75,
+  0x01,  0xa6,  0x86,  0x0a,  0x57,  0x01,  0x18,  0x09,  0x00,  0x1b,  0xec,  0x0a,  0xe1,  0x01,  0x18,  0x77,
+  0x50,  0x40,  0x8d,  0x30,  0x03,  0x81,  0x1e,  0xf8,  0x1f,  0x63,  0x01,  0x42,  0x8f,  0xfe,  0x70,  0x02,
+  0x05,  0xea,  0xd7,  0x99,  0xd8,  0x9c,  0x2a,  0x29,  0x2f,  0xfe,  0x4e,  0x04,  0x16,  0xfe,  0x4a,  0x04,
+  0x7e,  0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x54,  0x12,  0x32,  0xff,  0x02,  0x00,  0x10,  0x01,
+  0x08,  0x16,  0xfe,  0x02,  0x05,  0x32,  0x01,  0x08,  0x16,  0x29,  0x27,  0x25,  0xee,  0xfe,  0x4c,  0x44,
+  0xfe,  0x58,  0x12,  0x50,  0xfe,  0x44,  0x48,  0x13,  0x34,  0xfe,  0x4c,  0x54,  0x7b,  0xec,  0x60,  0x8d,
+  0x30,  0x01,  0xfe,  0x4e,  0x1e,  0xfe,  0x48,  0x47,  0xfe,  0x7c,  0x13,  0x01,  0x0c,  0x06,  0x28,  0xfe,
+  0x32,  0x13,  0x01,  0x43,  0x09,  0x9b,  0xfe,  0x68,  0x13,  0xfe,  0x26,  0x10,  0x13,  0x34,  0xfe,  0x4c,
+  0x54,  0x7b,  0xec,  0x01,  0xfe,  0x4e,  0x1e,  0xfe,  0x48,  0x47,  0xfe,  0x54,  0x13,  0x01,  0x0c,  0x06,
+  0x28,  0xa5,  0x01,  0x43,  0x09,  0x9b,  0xfe,  0x40,  0x13,  0x01,  0x0c,  0x06,  0x28,  0xf9,  0x1f,  0x7f,
+  0x01,  0x0c,  0x06,  0x07,  0x4d,  0x1f,  0xfe,  0x0d,  0x00,  0x01,  0x42,  0x8f,  0xfe,  0xa4,  0x0e,  0x05,
+  0x29,  0x32,  0x15,  0xfe,  0xe6,  0x00,  0x0f,  0xfe,  0x1c,  0x90,  0x04,  0xfe,  0x9c,  0x93,  0x3a,  0x0b,
+  0x0e,  0x8b,  0x02,  0x1f,  0x7f,  0x01,  0x42,  0x05,  0x35,  0xfe,  0x42,  0x5b,  0x7d,  0x1d,  0xfe,  0x46,
+  0x59,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0x0f,  0xfe,  0x87,  0x80,  0x04,  0xfe,  0x87,  0x83,  0xfe,
+  0xc9,  0x47,  0x0b,  0x0e,  0xd0,  0x65,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x98,  0x13,  0x0f,  0xfe,  0x20,
+  0x80,  0x04,  0xfe,  0xa0,  0x83,  0x33,  0x0b,  0x0e,  0x09,  0x1d,  0xfe,  0x84,  0x12,  0x01,  0x38,  0x06,
+  0x07,  0xfe,  0x70,  0x13,  0x03,  0xfe,  0xa2,  0x00,  0x1e,  0x1b,  0xfe,  0xda,  0x05,  0xd0,  0x54,  0x01,
+  0x38,  0x06,  0x0d,  0xfe,  0x58,  0x13,  0x03,  0xfe,  0xa0,  0x00,  0x1e,  0xfe,  0x50,  0x12,  0x5e,  0xff,
+  0x02,  0x00,  0x10,  0x2f,  0xfe,  0x90,  0x05,  0x2a,  0x3c,  0xcc,  0xff,  0x02,  0x00,  0x10,  0x2f,  0xfe,
+  0x9e,  0x05,  0x17,  0xfe,  0xf4,  0x05,  0x15,  0xfe,  0xe3,  0x00,  0x26,  0x01,  0x38,  0xfe,  0x4a,  0xf0,
+  0xfe,  0xc0,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0xba,  0x05,  0x71,  0x2e,  0xfe,  0x21,  0x00,  0xf1,  0x2e,
+  0xfe,  0x22,  0x00,  0xa2,  0x2e,  0x4a,  0xfe,  0x09,  0x48,  0xff,  0x02,  0x00,  0x10,  0x2f,  0xfe,  0xd0,
+  0x05,  0x17,  0xfe,  0xf4,  0x05,  0xfe,  0xe2,  0x08,  0x01,  0x38,  0x06,  0xfe,  0x1c,  0x00,  0x4d,  0x01,
+  0xa7,  0x2e,  0x07,  0x20,  0xe4,  0x47,  0xfe,  0x27,  0x01,  0x01,  0x0c,  0x06,  0x28,  0xfe,  0x24,  0x12,
+  0x3e,  0x01,  0x84,  0x1f,  0x7f,  0x01,  0x0c,  0x06,  0x07,  0x4d,  0x1f,  0xfe,  0x0d,  0x00,  0x01,  0x42,
+  0x8f,  0xfe,  0xa4,  0x0e,  0x05,  0x29,  0x03,  0xe6,  0x1e,  0xfe,  0xca,  0x13,  0x03,  0xb6,  0x1e,  0xfe,
+  0x40,  0x12,  0x03,  0x66,  0x1e,  0xfe,  0x38,  0x13,  0x3e,  0x01,  0x84,  0x17,  0xfe,  0x72,  0x06,  0x0a,
+  0x07,  0x01,  0x38,  0x06,  0x24,  0xfe,  0x02,  0x12,  0x4f,  0x01,  0xfe,  0x56,  0x19,  0x16,  0xfe,  0x68,
+  0x06,  0x15,  0x82,  0x01,  0x41,  0x15,  0xe2,  0x03,  0x66,  0x8a,  0x10,  0x66,  0x03,  0x9a,  0x1e,  0xfe,
+  0x70,  0x12,  0x03,  0x55,  0x1e,  0xfe,  0x68,  0x13,  0x01,  0xc6,  0x09,  0x12,  0x48,  0xfe,  0x92,  0x06,
+  0x2e,  0x12,  0x01,  0xfe,  0xac,  0x1d,  0xfe,  0x43,  0x48,  0x62,  0x80,  0x13,  0x58,  0xff,  0x02,  0x00,
+  0x57,  0x52,  0xad,  0x23,  0x3f,  0x4e,  0x62,  0x49,  0x3e,  0x01,  0x84,  0x17,  0xfe,  0xea,  0x06,  0x01,
+  0x38,  0x06,  0x12,  0xf7,  0x45,  0x0a,  0x95,  0x01,  0xfe,  0x84,  0x19,  0x16,  0xfe,  0xe0,  0x06,  0x15,
+  0x82,  0x01,  0x41,  0x15,  0xe2,  0x03,  0x55,  0x8a,  0x10,  0x55,  0x1c,  0x07,  0x01,  0x84,  0xfe,  0xae,
+  0x10,  0x03,  0x6f,  0x1e,  0xfe,  0x9e,  0x13,  0x3e,  0x01,  0x84,  0x03,  0x9a,  0x1e,  0xfe,  0x1a,  0x12,
+  0x01,  0x38,  0x06,  0x12,  0xfc,  0x01,  0xc6,  0x01,  0xfe,  0xac,  0x1d,  0xfe,  0x43,  0x48,  0x62,  0x80,
+  0xf0,  0x45,  0x0a,  0x95,  0x03,  0xb6,  0x1e,  0xf8,  0x01,  0x38,  0x06,  0x24,  0x36,  0xfe,  0x02,  0xf6,
+  0x07,  0x71,  0x78,  0x8c,  0x00,  0x4d,  0x62,  0x49,  0x3e,  0x2d,  0x93,  0x4e,  0xd0,  0x0d,  0x17,  0xfe,
+  0x9a,  0x07,  0x01,  0xfe,  0xc0,  0x19,  0x16,  0xfe,  0x90,  0x07,  0x26,  0x20,  0x9e,  0x15,  0x82,  0x01,
+  0x41,  0x15,  0xe2,  0x21,  0x9e,  0x09,  0x07,  0xfb,  0x03,  0xe6,  0xfe,  0x58,  0x57,  0x10,  0xe6,  0x05,
+  0xfe,  0x2a,  0x06,  0x03,  0x6f,  0x8a,  0x10,  0x6f,  0x1c,  0x07,  0x01,  0x84,  0xfe,  0x9c,  0x32,  0x5f,
+  0x75,  0x01,  0xa6,  0x86,  0x15,  0xfe,  0xe2,  0x00,  0x2f,  0xed,  0x2a,  0x3c,  0xfe,  0x0a,  0xf0,  0xfe,
+  0xce,  0x07,  0xae,  0xfe,  0x96,  0x08,  0xfe,  0x06,  0xf0,  0xfe,  0x9e,  0x08,  0xaf,  0xa0,  0x05,  0x29,
+  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x2e,  0x12,  0x14,  0x1d,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0x14,
+  0x00,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0xfe,  0x99,  0xa4,  0x01,  0x08,  0x14,  0x00,  0x05,  0xfe,
+  0xc6,  0x09,  0x01,  0x76,  0x06,  0x12,  0xfe,  0x3a,  0x12,  0x01,  0x0c,  0x06,  0x12,  0xfe,  0x30,  0x13,
+  0x14,  0xfe,  0x1b,  0x00,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0x14,  0x00,
+  0x01,  0x08,  0x14,  0x07,  0x01,  0x08,  0x14,  0x00,  0x05,  0xef,  0x7c,  0x4a,  0x78,  0x4f,  0x0f,  0xfe,
+  0x9a,  0x81,  0x04,  0xfe,  0x9a,  0x83,  0xfe,  0xcb,  0x47,  0x0b,  0x0e,  0x2d,  0x28,  0x48,  0xfe,  0x6c,
+  0x08,  0x0a,  0x28,  0xfe,  0x09,  0x6f,  0xca,  0xfe,  0xca,  0x45,  0xfe,  0x32,  0x12,  0x53,  0x63,  0x4e,
+  0x7c,  0x97,  0x2f,  0xfe,  0x7e,  0x08,  0x2a,  0x3c,  0xfe,  0x0a,  0xf0,  0xfe,  0x6c,  0x08,  0xaf,  0xa0,
+  0xae,  0xfe,  0x96,  0x08,  0x05,  0x29,  0x01,  0x41,  0x05,  0xed,  0x14,  0x24,  0x05,  0xed,  0xfe,  0x9c,
+  0xf7,  0x9f,  0x01,  0xfe,  0xae,  0x1e,  0xfe,  0x18,  0x58,  0x01,  0xfe,  0xbe,  0x1e,  0xfe,  0x99,  0x58,
+  0xfe,  0x78,  0x18,  0xfe,  0xf9,  0x18,  0x8e,  0xfe,  0x16,  0x09,  0x10,  0x6a,  0x22,  0x6b,  0x01,  0x0c,
+  0x61,  0x54,  0x44,  0x21,  0x2c,  0x09,  0x1a,  0xf8,  0x77,  0x01,  0xfe,  0x7e,  0x1e,  0x47,  0x2c,  0x7a,
+  0x30,  0xf0,  0xfe,  0x83,  0xe7,  0xfe,  0x3f,  0x00,  0x71,  0xfe,  0x03,  0x40,  0x01,  0x0c,  0x61,  0x65,
+  0x44,  0x01,  0xc2,  0xc8,  0xfe,  0x1f,  0x40,  0x20,  0x6e,  0x01,  0xfe,  0x6a,  0x16,  0xfe,  0x08,  0x50,
+  0xfe,  0x8a,  0x50,  0xfe,  0x44,  0x51,  0xfe,  0xc6,  0x51,  0xfe,  0x10,  0x10,  0x01,  0xfe,  0xce,  0x1e,
+  0x01,  0xfe,  0xde,  0x1e,  0x10,  0x68,  0x22,  0x69,  0x01,  0xfe,  0xee,  0x1e,  0x01,  0xfe,  0xfe,  0x1e,
+  0xfe,  0x40,  0x50,  0xfe,  0xc2,  0x50,  0x10,  0x4b,  0x22,  0x4c,  0xfe,  0x8a,  0x10,  0x01,  0x0c,  0x06,
+  0x54,  0xfe,  0x50,  0x12,  0x01,  0xfe,  0xae,  0x1e,  0x01,  0xfe,  0xbe,  0x1e,  0x10,  0x6a,  0x22,  0x6b,
+  0x01,  0x0c,  0x06,  0x65,  0x4e,  0x01,  0xc2,  0x0f,  0xfe,  0x1f,  0x80,  0x04,  0xfe,  0x9f,  0x83,  0x33,
+  0x0b,  0x0e,  0x20,  0x6e,  0x0f,  0xfe,  0x44,  0x90,  0x04,  0xfe,  0xc4,  0x93,  0x3a,  0x0b,  0xfe,  0xc6,
+  0x90,  0x04,  0xfe,  0xc6,  0x93,  0x79,  0x0b,  0x0e,  0x10,  0x6c,  0x22,  0x6d,  0x01,  0xfe,  0xce,  0x1e,
+  0x01,  0xfe,  0xde,  0x1e,  0x10,  0x68,  0x22,  0x69,  0x0f,  0xfe,  0x40,  0x90,  0x04,  0xfe,  0xc0,  0x93,
+  0x3a,  0x0b,  0xfe,  0xc2,  0x90,  0x04,  0xfe,  0xc2,  0x93,  0x79,  0x0b,  0x0e,  0x10,  0x4b,  0x22,  0x4c,
+  0x10,  0x64,  0x22,  0x34,  0x01,  0x0c,  0x61,  0x24,  0x44,  0x37,  0x13,  0xfe,  0x4e,  0x11,  0x2f,  0xfe,
+  0xde,  0x09,  0xfe,  0x9e,  0xf0,  0xfe,  0xf2,  0x09,  0xfe,  0x01,  0x48,  0x1b,  0x3c,  0x37,  0x88,  0xf5,
+  0xd4,  0xfe,  0x1e,  0x0a,  0xd5,  0xfe,  0x42,  0x0a,  0xd2,  0xfe,  0x1e,  0x0a,  0xd3,  0xfe,  0x42,  0x0a,
+  0xae,  0xfe,  0x12,  0x0a,  0xfe,  0x06,  0xf0,  0xfe,  0x18,  0x0a,  0xaf,  0xa0,  0x05,  0x29,  0x01,  0x41,
+  0xfe,  0xc1,  0x10,  0x14,  0x24,  0xfe,  0xc1,  0x10,  0x01,  0x76,  0x06,  0x07,  0xfe,  0x14,  0x12,  0x01,
+  0x76,  0x06,  0x0d,  0x5d,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x74,  0x12,  0xfe,  0x2e,  0x1c,  0x05,  0xfe,
+  0x1a,  0x0c,  0x01,  0x76,  0x06,  0x07,  0x5d,  0x01,  0x76,  0x06,  0x0d,  0x41,  0xfe,  0x2c,  0x1c,  0xfe,
+  0xaa,  0xf0,  0xfe,  0xce,  0x0a,  0xfe,  0xac,  0xf0,  0xfe,  0x66,  0x0a,  0xfe,  0x92,  0x10,  0xc4,  0xf6,
+  0xfe,  0xad,  0xf0,  0xfe,  0x72,  0x0a,  0x05,  0xfe,  0x1a,  0x0c,  0xc5,  0xfe,  0xe7,  0x10,  0xfe,  0x2b,
+  0xf0,  0xbf,  0xfe,  0x6b,  0x18,  0x23,  0xfe,  0x00,  0xfe,  0xfe,  0x1c,  0x12,  0xac,  0xfe,  0xd2,  0xf0,
+  0xbf,  0xfe,  0x76,  0x18,  0x23,  0x1d,  0x1b,  0xbf,  0x03,  0xe3,  0x23,  0x07,  0x1b,  0xbf,  0xd4,  0x5b,
+  0xd5,  0x5b,  0xd2,  0x5b,  0xd3,  0x5b,  0xc4,  0xc5,  0xfe,  0xa9,  0x10,  0x75,  0x5e,  0x32,  0x1f,  0x7f,
+  0x01,  0x42,  0x19,  0xfe,  0x35,  0x00,  0xfe,  0x01,  0xf0,  0x70,  0x19,  0x98,  0x05,  0x70,  0xfe,  0x74,
+  0x18,  0x23,  0xfe,  0x00,  0xf8,  0x1b,  0x5b,  0x7d,  0x12,  0x01,  0xfe,  0x78,  0x0f,  0x4d,  0x01,  0xfe,
+  0x96,  0x1a,  0x21,  0x30,  0x77,  0x7d,  0x1d,  0x05,  0x5b,  0x01,  0x0c,  0x06,  0x0d,  0x2b,  0xfe,  0xe2,
+  0x0b,  0x01,  0x0c,  0x06,  0x54,  0xfe,  0xa6,  0x12,  0x01,  0x0c,  0x06,  0x24,  0xfe,  0x88,  0x13,  0x21,
+  0x6e,  0xc7,  0x01,  0xfe,  0x1e,  0x1f,  0x0f,  0xfe,  0x83,  0x80,  0x04,  0xfe,  0x83,  0x83,  0xfe,  0xc9,
+  0x47,  0x0b,  0x0e,  0xfe,  0xc8,  0x44,  0xfe,  0x42,  0x13,  0x0f,  0xfe,  0x04,  0x91,  0x04,  0xfe,  0x84,
+  0x93,  0xfe,  0xca,  0x57,  0x0b,  0xfe,  0x86,  0x91,  0x04,  0xfe,  0x86,  0x93,  0xfe,  0xcb,  0x57,  0x0b,
+  0x0e,  0x7a,  0x30,  0xfe,  0x40,  0x59,  0xfe,  0xc1,  0x59,  0x8e,  0x40,  0x03,  0x6a,  0x3b,  0x6b,  0x10,
+  0x97,  0x22,  0x98,  0xd9,  0x6a,  0xda,  0x6b,  0x01,  0xc2,  0xc8,  0x7a,  0x30,  0x20,  0x6e,  0xdb,  0x64,
+  0xdc,  0x34,  0x91,  0x6c,  0x7e,  0x6d,  0xfe,  0x44,  0x55,  0xfe,  0xe5,  0x55,  0xfe,  0x04,  0xfa,  0x64,
+  0xfe,  0x05,  0xfa,  0x34,  0x01,  0xfe,  0x6a,  0x16,  0xa3,  0x26,  0x10,  0x97,  0x10,  0x98,  0x91,  0x6c,
+  0x7e,  0x6d,  0xfe,  0x14,  0x10,  0x01,  0x0c,  0x06,  0x24,  0x1b,  0x40,  0x91,  0x4b,  0x7e,  0x4c,  0x01,
+  0x0c,  0x06,  0xfe,  0xf7,  0x00,  0x44,  0x03,  0x68,  0x3b,  0x69,  0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,
+  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0x05,  0x5b,  0x01,  0x0c,  0x06,  0x24,  0x1b,  0x40,  0x01,  0x0c,
+  0x06,  0xfe,  0xf7,  0x00,  0x44,  0x78,  0x01,  0xfe,  0x8e,  0x1e,  0x4f,  0x0f,  0xfe,  0x10,  0x90,  0x04,
+  0xfe,  0x90,  0x93,  0x3a,  0x0b,  0xfe,  0x92,  0x90,  0x04,  0xfe,  0x92,  0x93,  0x79,  0x0b,  0x0e,  0xfe,
+  0xbd,  0x10,  0x01,  0x43,  0x09,  0xbb,  0x1b,  0xfe,  0x6e,  0x0a,  0x15,  0xbb,  0x01,  0x0c,  0x06,  0x0d,
+  0xfe,  0x14,  0x13,  0x03,  0x4b,  0x3b,  0x4c,  0x8e,  0xfe,  0x6e,  0x0a,  0xfe,  0x0c,  0x58,  0xfe,  0x8d,
+  0x58,  0x05,  0x5b,  0x26,  0x3e,  0x0f,  0xfe,  0x19,  0x80,  0x04,  0xfe,  0x99,  0x83,  0x33,  0x0b,  0x0e,
+  0xfe,  0xe5,  0x10,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x1a,  0x12,  0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,
+  0xfe,  0x6b,  0x18,  0xac,  0xfe,  0xd1,  0xf0,  0xef,  0x1f,  0x92,  0x01,  0x42,  0x19,  0xfe,  0x44,  0x00,
+  0xfe,  0x90,  0x10,  0xfe,  0x6c,  0x19,  0xd9,  0x4b,  0xfe,  0xed,  0x19,  0xda,  0x4c,  0xfe,  0x0c,  0x51,
+  0xfe,  0x8e,  0x51,  0xfe,  0x6b,  0x18,  0x23,  0xfe,  0x00,  0xff,  0x31,  0xfe,  0x76,  0x10,  0xac,  0xfe,
+  0xd2,  0xf0,  0xfe,  0xba,  0x0c,  0xfe,  0x76,  0x18,  0x23,  0x1d,  0x5d,  0x03,  0xe3,  0x23,  0x07,  0xfe,
+  0x08,  0x13,  0x19,  0xfe,  0x16,  0x00,  0x05,  0x70,  0xfe,  0xd1,  0xf0,  0xfe,  0xcc,  0x0c,  0x1f,  0x92,
+  0x01,  0x42,  0x19,  0xfe,  0x17,  0x00,  0x5c,  0xfe,  0xce,  0xf0,  0xfe,  0xd2,  0x0c,  0xfe,  0x3e,  0x10,
+  0xfe,  0xcd,  0xf0,  0xfe,  0xde,  0x0c,  0x19,  0xfe,  0x22,  0x00,  0x05,  0x70,  0xfe,  0xcb,  0xf0,  0xfe,
+  0xea,  0x0c,  0x19,  0xfe,  0x24,  0x00,  0x05,  0x70,  0xfe,  0xd0,  0xf0,  0xfe,  0xf4,  0x0c,  0x19,  0x94,
+  0xfe,  0x1c,  0x10,  0xfe,  0xcf,  0xf0,  0xfe,  0xfe,  0x0c,  0x19,  0x4a,  0xf3,  0xfe,  0xcc,  0xf0,  0xef,
+  0x01,  0x76,  0x06,  0x24,  0x4d,  0x19,  0xfe,  0x12,  0x00,  0x37,  0x13,  0xfe,  0x4e,  0x11,  0x2f,  0xfe,
+  0x16,  0x0d,  0xfe,  0x9e,  0xf0,  0xfe,  0x2a,  0x0d,  0xfe,  0x01,  0x48,  0x1b,  0x3c,  0x37,  0x88,  0xf5,
+  0xd4,  0x29,  0xd5,  0x29,  0xd2,  0x29,  0xd3,  0x29,  0x37,  0xfe,  0x9c,  0x32,  0x2f,  0xfe,  0x3e,  0x0d,
+  0x2a,  0x3c,  0xae,  0xfe,  0x62,  0x0d,  0xaf,  0xa0,  0xd4,  0x9f,  0xd5,  0x9f,  0xd2,  0x9f,  0xd3,  0x9f,
+  0x05,  0x29,  0x01,  0x41,  0xfe,  0xd3,  0x10,  0x15,  0xfe,  0xe8,  0x00,  0xc4,  0xc5,  0x75,  0xd7,  0x99,
+  0xd8,  0x9c,  0xfe,  0x89,  0xf0,  0x29,  0x27,  0x25,  0xbe,  0xd7,  0x99,  0xd8,  0x9c,  0x2f,  0xfe,  0x8c,
+  0x0d,  0x16,  0x29,  0x27,  0x25,  0xbd,  0xfe,  0x01,  0x48,  0xa4,  0x19,  0xfe,  0x42,  0x00,  0x05,  0x70,
+  0x90,  0x07,  0xfe,  0x81,  0x49,  0x1b,  0xfe,  0x64,  0x0e,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x44,  0x13,
+  0x19,  0x00,  0x2d,  0x0d,  0xfe,  0x54,  0x12,  0x2d,  0xfe,  0x28,  0x00,  0x2b,  0xfe,  0xda,  0x0e,  0x0a,
+  0x57,  0x01,  0x18,  0x09,  0x00,  0x36,  0x46,  0xfe,  0x28,  0x00,  0xfe,  0xfa,  0x10,  0x01,  0xfe,  0xf4,
+  0x1c,  0x01,  0xfe,  0x00,  0x1d,  0x0a,  0xba,  0x01,  0xfe,  0x58,  0x10,  0x40,  0x15,  0x56,  0x01,  0x85,
+  0x05,  0x35,  0x19,  0xfe,  0x44,  0x00,  0x2d,  0x0d,  0xf7,  0x46,  0x0d,  0xfe,  0xcc,  0x10,  0x01,  0xa7,
+  0x46,  0x0d,  0xfe,  0xc2,  0x10,  0x01,  0xa7,  0x0f,  0xfe,  0x19,  0x82,  0x04,  0xfe,  0x99,  0x83,  0xfe,
+  0xcc,  0x47,  0x0b,  0x0e,  0xfe,  0x34,  0x46,  0xa5,  0x46,  0x0d,  0x19,  0xfe,  0x43,  0x00,  0xfe,  0xa2,
+  0x10,  0x01,  0x0c,  0x61,  0x0d,  0x44,  0x01,  0xfe,  0xf4,  0x1c,  0x01,  0xfe,  0x00,  0x1d,  0x40,  0x15,
+  0x56,  0x01,  0x85,  0x7d,  0x0d,  0x40,  0x51,  0x01,  0xfe,  0x9e,  0x1e,  0x05,  0xfe,  0x3a,  0x03,  0x01,
+  0x0c,  0x06,  0x0d,  0x5d,  0x46,  0x0d,  0x19,  0x00,  0xfe,  0x62,  0x10,  0x01,  0x76,  0x06,  0x12,  0xfe,
+  0x5c,  0x12,  0x01,  0x0c,  0x06,  0x12,  0xfe,  0x52,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,
+  0x8e,  0x0e,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x94,  0x0e,  0x01,  0x0c,  0x61,  0x12,  0x44,
+  0xfe,  0x9f,  0x10,  0x19,  0xfe,  0x15,  0x00,  0xfe,  0x04,  0xe6,  0x0d,  0x4f,  0xfe,  0x2e,  0x10,  0x19,
+  0xfe,  0x13,  0x00,  0xfe,  0x10,  0x10,  0x19,  0xfe,  0x47,  0x00,  0xf1,  0x19,  0xfe,  0x41,  0x00,  0xa2,
+  0x19,  0xfe,  0x24,  0x00,  0x86,  0xc4,  0xc5,  0x75,  0x03,  0x81,  0x1e,  0x2b,  0xea,  0x4f,  0xfe,  0x04,
+  0xe6,  0x12,  0xfe,  0x9d,  0x41,  0xfe,  0x1c,  0x42,  0x40,  0x01,  0xf4,  0x05,  0x35,  0xfe,  0x12,  0x1c,
+  0x1f,  0x0d,  0x47,  0xb5,  0xc3,  0x1f,  0xfe,  0x31,  0x00,  0x47,  0xb8,  0x01,  0xfe,  0xd4,  0x11,  0x05,
+  0xe9,  0x51,  0xfe,  0x06,  0xec,  0xe0,  0xfe,  0x0e,  0x47,  0x46,  0x28,  0xfe,  0xce,  0x45,  0x31,  0x51,
+  0xfe,  0x06,  0xea,  0xe0,  0xfe,  0x47,  0x4b,  0x45,  0xfe,  0x75,  0x57,  0x03,  0x67,  0xfe,  0x98,  0x56,
+  0xfe,  0x38,  0x12,  0x0a,  0x5a,  0x01,  0x18,  0xfe,  0x44,  0x48,  0x60,  0x01,  0x0c,  0x06,  0x28,  0xfe,
+  0x18,  0x13,  0x0a,  0x57,  0x01,  0x18,  0x3e,  0xfe,  0x41,  0x58,  0x0a,  0xba,  0xfe,  0xfa,  0x14,  0xfe,
+  0x49,  0x54,  0xb0,  0xfe,  0x5e,  0x0f,  0x05,  0xfe,  0x3a,  0x03,  0x0a,  0x67,  0xfe,  0xe0,  0x14,  0xfe,
+  0x0e,  0x47,  0x46,  0x28,  0xfe,  0xce,  0x45,  0x31,  0x51,  0xfe,  0xce,  0x47,  0xfe,  0xad,  0x13,  0x05,
+  0x35,  0x21,  0x2c,  0x09,  0x1a,  0xfe,  0x98,  0x12,  0x26,  0x20,  0x96,  0x20,  0xe7,  0xfe,  0x08,  0x1c,
+  0xfe,  0x7c,  0x19,  0xfe,  0xfd,  0x19,  0xfe,  0x0a,  0x1c,  0x03,  0xe5,  0xfe,  0x48,  0x55,  0xa5,  0x3b,
+  0xfe,  0x62,  0x01,  0xfe,  0xc9,  0x55,  0x31,  0xfe,  0x74,  0x10,  0x01,  0xfe,  0xf0,  0x1a,  0x03,  0xfe,
+  0x38,  0x01,  0x3b,  0xfe,  0x3a,  0x01,  0x8e,  0xfe,  0x1e,  0x10,  0xfe,  0x02,  0xec,  0xe7,  0x53,  0x00,
+  0x36,  0xfe,  0x04,  0xec,  0x2c,  0x60,  0xfe,  0x05,  0xf6,  0xfe,  0x34,  0x01,  0x01,  0xfe,  0x62,  0x1b,
+  0x01,  0xfe,  0xce,  0x1e,  0xb2,  0x11,  0xfe,  0x18,  0x13,  0xca,  0xfe,  0x02,  0xea,  0xe7,  0x53,  0x92,
+  0xfe,  0xc3,  0x13,  0x1f,  0x12,  0x47,  0xb5,  0xc3,  0xfe,  0x2a,  0x10,  0x03,  0xfe,  0x38,  0x01,  0x23,
+  0xfe,  0xf0,  0xff,  0x10,  0xe5,  0x03,  0xfe,  0x3a,  0x01,  0x10,  0xfe,  0x62,  0x01,  0x01,  0xfe,  0x1e,
+  0x1e,  0x20,  0x2c,  0x15,  0x56,  0x01,  0xfe,  0x9e,  0x1e,  0x13,  0x07,  0x02,  0x26,  0x02,  0x21,  0x96,
+  0xc7,  0x20,  0x96,  0x09,  0x92,  0xfe,  0x79,  0x13,  0x1f,  0x1d,  0x47,  0xb5,  0xc3,  0xfe,  0xe1,  0x10,
+  0xcf,  0xfe,  0x03,  0xdc,  0xfe,  0x73,  0x57,  0xfe,  0x80,  0x5d,  0x02,  0xcf,  0xfe,  0x03,  0xdc,  0xfe,
+  0x5b,  0x57,  0xfe,  0x80,  0x5d,  0x02,  0xfe,  0x03,  0x57,  0xcf,  0x26,  0xfe,  0x00,  0xcc,  0x02,  0xfe,
+  0x03,  0x57,  0xcf,  0x89,  0x02,  0x01,  0x0c,  0x06,  0x4a,  0xfe,  0x4e,  0x13,  0x0f,  0xfe,  0x1c,  0x80,
+  0x04,  0xfe,  0x9c,  0x83,  0x33,  0x0b,  0x0e,  0x09,  0x07,  0xfe,  0x3a,  0x13,  0x0f,  0xfe,  0x1e,  0x80,
+  0x04,  0xfe,  0x9e,  0x83,  0x33,  0x0b,  0x0e,  0xfe,  0x2a,  0x13,  0x0f,  0xfe,  0x1d,  0x80,  0x04,  0xfe,
+  0x9d,  0x83,  0xfe,  0xf9,  0x13,  0x0e,  0xfe,  0x1c,  0x13,  0x01,  0xfe,  0xee,  0x1e,  0xac,  0xfe,  0x14,
+  0x13,  0x01,  0xfe,  0xfe,  0x1e,  0xfe,  0x81,  0x58,  0xfa,  0x01,  0xfe,  0x0e,  0x1f,  0xfe,  0x30,  0xf4,
+  0x0d,  0xfe,  0x3c,  0x50,  0xa2,  0x01,  0xfe,  0x92,  0x1b,  0x01,  0x43,  0x09,  0x56,  0xfb,  0x01,  0xfe,
+  0xc8,  0x1a,  0x01,  0x0c,  0x06,  0x28,  0xa4,  0x01,  0xfe,  0xf4,  0x1c,  0x01,  0xfe,  0x00,  0x1d,  0x15,
+  0xfe,  0xe9,  0x00,  0x01,  0x0c,  0x06,  0x4a,  0xfe,  0x4e,  0x13,  0x01,  0xfe,  0x22,  0x1b,  0xfe,  0x1e,
+  0x1c,  0x0f,  0xfe,  0x14,  0x90,  0x04,  0xfe,  0x94,  0x93,  0x3a,  0x0b,  0xfe,  0x96,  0x90,  0x04,  0xfe,
+  0x96,  0x93,  0x79,  0x0b,  0x0e,  0x10,  0xfe,  0x64,  0x01,  0x22,  0xfe,  0x66,  0x01,  0x01,  0x0c,  0x06,
+  0x65,  0xf9,  0x0f,  0xfe,  0x03,  0x80,  0x04,  0xfe,  0x83,  0x83,  0x33,  0x0b,  0x0e,  0x77,  0xfe,  0x01,
+  0xec,  0x2c,  0xfe,  0x80,  0x40,  0x20,  0x2c,  0x7a,  0x30,  0x15,  0xdf,  0x40,  0x21,  0x2c,  0xfe,  0x00,
+  0x40,  0x8d,  0x2c,  0x02,  0xfe,  0x08,  0x1c,  0x03,  0xfe,  0xac,  0x00,  0xfe,  0x06,  0x58,  0x03,  0xfe,
+  0xae,  0x00,  0xfe,  0x07,  0x58,  0x03,  0xfe,  0xb0,  0x00,  0xfe,  0x08,  0x58,  0x03,  0xfe,  0xb2,  0x00,
+  0xfe,  0x09,  0x58,  0xfe,  0x0a,  0x1c,  0x2e,  0x49,  0x20,  0xe0,  0x26,  0x10,  0x66,  0x10,  0x55,  0x10,
+  0x6f,  0x13,  0x57,  0x52,  0x4f,  0x1c,  0x28,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x2b,  0xfe,  0x88,
+  0x11,  0x46,  0x1a,  0x13,  0x5a,  0x52,  0x1c,  0x4a,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x2b,  0xfe,
+  0x9e,  0x11,  0x2e,  0x1a,  0x20,  0x2c,  0x90,  0x34,  0x60,  0x21,  0x2c,  0xfe,  0x00,  0x40,  0x8d,  0x2c,
+  0x15,  0xdf,  0xfe,  0x14,  0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0xb2,  0x11,  0xfe,  0x12,  0x1c,  0x75,  0xfe,
+  0x14,  0x1c,  0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x02,  0x51,  0xfe,  0x0c,  0x14,  0xfe,  0x0e,  0x47,
+  0xfe,  0x07,  0xe6,  0x28,  0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x02,  0x01,  0xa7,  0x90,  0x34,  0x60,
+  0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x42,  0x13,  0xfe,  0x02,  0x80,  0x09,  0x56,  0xfe,  0x34,
+  0x13,  0x0a,  0x5a,  0x01,  0x18,  0xcb,  0xfe,  0x36,  0x12,  0xfe,  0x41,  0x48,  0xfe,  0x45,  0x48,  0x01,
+  0xfe,  0xb2,  0x16,  0xfe,  0x00,  0xcc,  0xcb,  0xfe,  0xf3,  0x13,  0x3f,  0x89,  0x09,  0x1a,  0xa5,  0x0a,
+  0x9d,  0x01,  0x18,  0xfe,  0x80,  0x5c,  0x01,  0x85,  0xf2,  0x09,  0x9b,  0xa4,  0xfe,  0x14,  0x56,  0xfe,
+  0xd6,  0xf0,  0xfe,  0xec,  0x11,  0x02,  0xfe,  0x44,  0x58,  0x77,  0xfe,  0x01,  0xec,  0xb8,  0xfe,  0x9e,
+  0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x12,  0x8d,  0x30,  0x01,  0xf4,  0xfe,  0xdd,  0x10,
+  0x37,  0xd7,  0x99,  0xd8,  0x9c,  0x27,  0x25,  0xee,  0x09,  0x12,  0xfe,  0x48,  0x12,  0x09,  0x0d,  0xfe,
+  0x56,  0x12,  0x09,  0x1d,  0xfe,  0x30,  0x12,  0x09,  0xdd,  0x1b,  0xfe,  0xc4,  0x13,  0x09,  0xfe,  0x23,
+  0x00,  0x1b,  0xfe,  0xd0,  0x13,  0x09,  0x07,  0x1b,  0xfe,  0x34,  0x14,  0x09,  0x24,  0xfe,  0x12,  0x12,
+  0x09,  0x00,  0x1b,  0x29,  0x1f,  0xdd,  0x01,  0x42,  0xa1,  0x32,  0x01,  0x08,  0xae,  0x41,  0x02,  0x32,
+  0xfe,  0x62,  0x08,  0x0a,  0xe1,  0x01,  0xfe,  0x58,  0x10,  0x15,  0x9b,  0x05,  0x35,  0x32,  0x01,  0x43,
+  0x09,  0xbb,  0xfe,  0xd7,  0x13,  0x91,  0x4b,  0x7e,  0x4c,  0x8e,  0xfe,  0x80,  0x13,  0x01,  0x0c,  0x06,
+  0x54,  0xfe,  0x72,  0x12,  0xdb,  0x64,  0xdc,  0x34,  0xfe,  0x44,  0x55,  0xfe,  0xe5,  0x55,  0xb0,  0xfe,
+  0x4a,  0x13,  0x21,  0x6e,  0xfe,  0x26,  0x13,  0x03,  0x97,  0x3b,  0x98,  0x8e,  0xfe,  0xb6,  0x0e,  0x10,
+  0x6a,  0x22,  0x6b,  0x26,  0x10,  0x97,  0x10,  0x98,  0x01,  0xc2,  0x2e,  0x49,  0x88,  0x20,  0x6e,  0x01,
+  0xfe,  0x6a,  0x16,  0xdb,  0x64,  0xdc,  0x34,  0xfe,  0x04,  0x55,  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,
+  0x64,  0xfe,  0x05,  0xfa,  0x34,  0xfe,  0x8f,  0x10,  0x03,  0x6c,  0x3b,  0x6d,  0xfe,  0x40,  0x56,  0xfe,
+  0xe1,  0x56,  0x10,  0x6c,  0x22,  0x6d,  0x71,  0xdb,  0x64,  0xdc,  0x34,  0xfe,  0x44,  0x55,  0xfe,  0xe5,
+  0x55,  0x03,  0x68,  0x3b,  0x69,  0xfe,  0x00,  0x56,  0xfe,  0xa1,  0x56,  0x10,  0x68,  0x22,  0x69,  0x01,
+  0x0c,  0x06,  0x54,  0xf9,  0x21,  0x6e,  0xfe,  0x1f,  0x40,  0x03,  0x6a,  0x3b,  0x6b,  0xfe,  0x2c,  0x50,
+  0xfe,  0xae,  0x50,  0x03,  0x6c,  0x3b,  0x6d,  0xfe,  0x44,  0x50,  0xfe,  0xc6,  0x50,  0x03,  0x68,  0x3b,
+  0x69,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x03,  0x4b,  0x3b,  0x4c,  0xfe,  0x40,  0x50,  0xfe,  0xc2,
+  0x50,  0x05,  0x73,  0x2e,  0x07,  0x20,  0x9e,  0x05,  0x72,  0x32,  0x01,  0x08,  0x16,  0x3d,  0x27,  0x25,
+  0xee,  0x09,  0x07,  0x2b,  0x3d,  0x01,  0x43,  0x09,  0xbb,  0x2b,  0x72,  0x01,  0xa6,  0x23,  0x3f,  0x1b,
+  0x3d,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x1e,  0x13,  0x91,  0x4b,  0x7e,  0x4c,  0xfe,  0x0a,  0x55,  0x31,
+  0xfe,  0x8b,  0x55,  0xd9,  0x4b,  0xda,  0x4c,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0x05,  0x72,  0x01,
+  0xfe,  0x8e,  0x1e,  0xca,  0xfe,  0x19,  0x41,  0x05,  0x72,  0x32,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0xc0,
+  0x27,  0x25,  0xbe,  0x2d,  0x1d,  0xc0,  0x2d,  0x0d,  0x83,  0x2d,  0x7f,  0x1b,  0xfe,  0x66,  0x15,  0x05,
+  0x3d,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0xc0,  0x27,  0x25,  0xbd,  0x09,  0x1d,  0x2b,  0x3d,  0x01,  0x08,
+  0x16,  0xc0,  0x27,  0x25,  0xfe,  0xe8,  0x09,  0xfe,  0xc2,  0x49,  0x50,  0x03,  0xb6,  0x1e,  0x83,  0x01,
+  0x38,  0x06,  0x24,  0x31,  0xa1,  0xfe,  0xbb,  0x45,  0x2d,  0x00,  0xa4,  0x46,  0x07,  0x90,  0x3f,  0x01,
+  0xfe,  0xf8,  0x15,  0x01,  0xa6,  0x86,  0xfe,  0x4b,  0x45,  0xfe,  0x20,  0x13,  0x01,  0x43,  0x09,  0x82,
+  0xfe,  0x16,  0x13,  0x03,  0x9a,  0x1e,  0x5d,  0x03,  0x55,  0x1e,  0x31,  0x5e,  0x05,  0x72,  0xfe,  0xc0,
+  0x5d,  0x01,  0xa7,  0xfe,  0x03,  0x17,  0x03,  0x66,  0x8a,  0x10,  0x66,  0x5e,  0x32,  0x01,  0x08,  0x17,
+  0x73,  0x01,  0xfe,  0x56,  0x19,  0x05,  0x73,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0x3d,  0x27,  0x25,  0xbd,
+  0x09,  0x07,  0x2b,  0x3d,  0x01,  0xfe,  0xbe,  0x16,  0xfe,  0x42,  0x58,  0xfe,  0xe8,  0x14,  0x01,  0xa6,
+  0x86,  0xfe,  0x4a,  0xf4,  0x0d,  0x1b,  0x3d,  0xfe,  0x4a,  0xf4,  0x07,  0xfe,  0x0e,  0x12,  0x01,  0x43,
+  0x09,  0x82,  0x4e,  0x05,  0x72,  0x03,  0x55,  0x8a,  0x10,  0x55,  0x5e,  0x32,  0x01,  0x08,  0x17,  0x73,
+  0x01,  0xfe,  0x84,  0x19,  0x05,  0x73,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0x3d,  0x27,  0x25,  0xbd,  0x09,
+  0x12,  0x2b,  0x3d,  0x01,  0xfe,  0xe8,  0x17,  0x8b,  0xfe,  0xaa,  0x14,  0xfe,  0xb6,  0x14,  0x86,  0xa8,
+  0xb2,  0x0d,  0x1b,  0x3d,  0xb2,  0x07,  0xfe,  0x0e,  0x12,  0x01,  0x43,  0x09,  0x82,  0x4e,  0x05,  0x72,
+  0x03,  0x6f,  0x8a,  0x10,  0x6f,  0x5e,  0x32,  0x01,  0x08,  0x17,  0x73,  0x01,  0xfe,  0xc0,  0x19,  0x05,
+  0x73,  0x13,  0x07,  0x2f,  0xfe,  0xcc,  0x15,  0x17,  0xfe,  0xe2,  0x15,  0x5f,  0xcc,  0x01,  0x08,  0x26,
+  0x5f,  0x02,  0x8f,  0xfe,  0xde,  0x15,  0x2a,  0xfe,  0xde,  0x15,  0x16,  0xfe,  0xcc,  0x15,  0x5e,  0x32,
+  0x01,  0x08,  0xfe,  0xd5,  0x10,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,  0xad,  0x23,  0xfe,  0xff,
+  0x7f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x02,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,  0xad,
+  0x23,  0x3f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x02,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,
+  0xad,  0x02,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,  0xfe,  0x00,  0x5e,  0x02,  0x13,  0x58,  0xff,
+  0x02,  0x00,  0x57,  0x52,  0xad,  0xfe,  0x0b,  0x58,  0x02,  0x0a,  0x66,  0x01,  0x5c,  0x0a,  0x55,  0x01,
+  0x5c,  0x0a,  0x6f,  0x01,  0x5c,  0x02,  0x01,  0xfe,  0x1e,  0x1f,  0x23,  0x1a,  0xff,  0x03,  0x00,  0x54,
+  0xfe,  0x00,  0xf4,  0x24,  0x52,  0x0f,  0xfe,  0x00,  0x7c,  0x04,  0xfe,  0x07,  0x7c,  0x3a,  0x0b,  0x0e,
+  0xfe,  0x00,  0x71,  0xfe,  0xf9,  0x18,  0xfe,  0x7a,  0x19,  0xfe,  0xfb,  0x19,  0xfe,  0x1a,  0xf7,  0x00,
+  0xfe,  0x1b,  0xf7,  0x00,  0x7a,  0x30,  0x10,  0x68,  0x22,  0x69,  0xd9,  0x6c,  0xda,  0x6d,  0x02,  0xfe,
+  0x62,  0x08,  0xfe,  0x82,  0x4a,  0xfe,  0xe1,  0x1a,  0xfe,  0x83,  0x5a,  0x77,  0x02,  0x01,  0xc6,  0xfe,
+  0x42,  0x48,  0x4f,  0x50,  0x45,  0x01,  0x08,  0x16,  0xfe,  0xe0,  0x17,  0x27,  0x25,  0xbe,  0x01,  0x08,
+  0x16,  0xfe,  0xe0,  0x17,  0x27,  0x25,  0xfe,  0xe8,  0x0a,  0xfe,  0xc1,  0x59,  0x03,  0x9a,  0x1e,  0xfe,
+  0xda,  0x12,  0x01,  0x38,  0x06,  0x12,  0xfe,  0xd0,  0x13,  0x26,  0x53,  0x12,  0x48,  0xfe,  0x08,  0x17,
+  0xd1,  0x12,  0x53,  0x12,  0xfe,  0x1e,  0x13,  0x2d,  0xb4,  0x7b,  0xfe,  0x26,  0x17,  0x4d,  0x13,  0x07,
+  0x1c,  0xb4,  0x90,  0x04,  0xfe,  0x78,  0x10,  0xff,  0x02,  0x83,  0x55,  0xf1,  0xff,  0x02,  0x83,  0x55,
+  0x53,  0x1d,  0xfe,  0x12,  0x13,  0xd6,  0xfe,  0x30,  0x00,  0xb0,  0xfe,  0x80,  0x17,  0x1c,  0x63,  0x13,
+  0x07,  0xfe,  0x56,  0x10,  0x53,  0x0d,  0xfe,  0x16,  0x13,  0xd6,  0xfe,  0x64,  0x00,  0xb0,  0xfe,  0x80,
+  0x17,  0x0a,  0xfe,  0x64,  0x00,  0x1c,  0x94,  0x13,  0x07,  0xfe,  0x28,  0x10,  0x53,  0x07,  0xfe,  0x60,
+  0x13,  0xd6,  0xfe,  0xc8,  0x00,  0xb0,  0xfe,  0x80,  0x17,  0x0a,  0xfe,  0xc8,  0x00,  0x1c,  0x95,  0x13,
+  0x07,  0x71,  0xd6,  0xfe,  0x90,  0x01,  0x48,  0xfe,  0x8c,  0x17,  0x45,  0xf3,  0xfe,  0x43,  0xf4,  0x96,
+  0xfe,  0x56,  0xf0,  0xfe,  0x9e,  0x17,  0xfe,  0x04,  0xf4,  0x58,  0xfe,  0x43,  0xf4,  0x94,  0xf6,  0x8b,
+  0x01,  0xfe,  0x24,  0x16,  0x23,  0x3f,  0xfc,  0xa8,  0x8c,  0x49,  0x48,  0xfe,  0xda,  0x17,  0x62,  0x49,
+  0xfe,  0x1c,  0x10,  0xa8,  0x8c,  0x80,  0x48,  0xfe,  0xda,  0x17,  0x62,  0x80,  0x71,  0x50,  0x26,  0xfe,
+  0x4d,  0xf4,  0x00,  0xf7,  0x45,  0x13,  0x07,  0xfe,  0xb4,  0x56,  0xfe,  0xc3,  0x58,  0x02,  0x50,  0x13,
+  0x0d,  0x02,  0x50,  0x3e,  0x78,  0x4f,  0x45,  0x01,  0x08,  0x16,  0xa9,  0x27,  0x25,  0xbe,  0xfe,  0x03,
+  0xea,  0xfe,  0x7e,  0x01,  0x01,  0x08,  0x16,  0xa9,  0x27,  0x25,  0xfe,  0xe9,  0x0a,  0x01,  0x08,  0x16,
+  0xa9,  0x27,  0x25,  0xfe,  0xe9,  0x0a,  0xfe,  0x05,  0xea,  0xfe,  0x7f,  0x01,  0x01,  0x08,  0x16,  0xa9,
+  0x27,  0x25,  0xfe,  0x69,  0x09,  0xfe,  0x02,  0xea,  0xfe,  0x80,  0x01,  0x01,  0x08,  0x16,  0xa9,  0x27,
+  0x25,  0xfe,  0xe8,  0x08,  0x47,  0xfe,  0x81,  0x01,  0x03,  0xb6,  0x1e,  0x83,  0x01,  0x38,  0x06,  0x24,
+  0x31,  0xa2,  0x78,  0xf2,  0x53,  0x07,  0x36,  0xfe,  0x34,  0xf4,  0x3f,  0xa1,  0x78,  0x03,  0x9a,  0x1e,
+  0x83,  0x01,  0x38,  0x06,  0x12,  0x31,  0xf0,  0x4f,  0x45,  0xfe,  0x90,  0x10,  0xfe,  0x40,  0x5a,  0x23,
+  0x3f,  0xfb,  0x8c,  0x49,  0x48,  0xfe,  0xaa,  0x18,  0x62,  0x49,  0x71,  0x8c,  0x80,  0x48,  0xfe,  0xaa,
+  0x18,  0x62,  0x80,  0xfe,  0xb4,  0x56,  0xfe,  0x40,  0x5d,  0x01,  0xc6,  0x01,  0xfe,  0xac,  0x1d,  0xfe,
+  0x02,  0x17,  0xfe,  0xc8,  0x45,  0xfe,  0x5a,  0xf0,  0xfe,  0xc0,  0x18,  0xfe,  0x43,  0x48,  0x2d,  0x93,
+  0x36,  0xfe,  0x34,  0xf4,  0xfe,  0x00,  0x11,  0xfe,  0x40,  0x10,  0x2d,  0xb4,  0x36,  0xfe,  0x34,  0xf4,
+  0x04,  0xfe,  0x34,  0x10,  0x2d,  0xfe,  0x0b,  0x00,  0x36,  0x46,  0x63,  0xfe,  0x28,  0x10,  0xfe,  0xc0,
+  0x49,  0xff,  0x02,  0x00,  0x54,  0xb2,  0xfe,  0x90,  0x01,  0x48,  0xfe,  0xfa,  0x18,  0x45,  0xfe,  0x1c,
+  0xf4,  0x3f,  0xf3,  0xfe,  0x40,  0xf4,  0x96,  0xfe,  0x56,  0xf0,  0xfe,  0x0c,  0x19,  0xfe,  0x04,  0xf4,
+  0x58,  0xfe,  0x40,  0xf4,  0x94,  0xf6,  0x3e,  0x2d,  0x93,  0x4e,  0xd0,  0x0d,  0x21,  0xfe,  0x7f,  0x01,
+  0xfe,  0xc8,  0x46,  0xfe,  0x24,  0x13,  0x8c,  0x00,  0x5d,  0x26,  0x21,  0xfe,  0x7e,  0x01,  0xfe,  0xc8,
+  0x45,  0xfe,  0x14,  0x13,  0x21,  0xfe,  0x80,  0x01,  0xfe,  0x48,  0x45,  0xfa,  0x21,  0xfe,  0x81,  0x01,
+  0xfe,  0xc8,  0x44,  0x4e,  0x26,  0x02,  0x13,  0x07,  0x02,  0x78,  0x45,  0x50,  0x13,  0x0d,  0x02,  0x14,
+  0x07,  0x01,  0x08,  0x17,  0xfe,  0x82,  0x19,  0x14,  0x0d,  0x01,  0x08,  0x17,  0xfe,  0x82,  0x19,  0x14,
+  0x1d,  0x01,  0x08,  0x17,  0xfe,  0x82,  0x19,  0x5f,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x02,  0x14,  0x07,
+  0x01,  0x08,  0x17,  0xc1,  0x14,  0x1d,  0x01,  0x08,  0x17,  0xc1,  0x14,  0x07,  0x01,  0x08,  0x17,  0xc1,
+  0xfe,  0x89,  0x49,  0x01,  0x08,  0x17,  0xc1,  0x5f,  0xfe,  0x89,  0x4a,  0x01,  0x08,  0x02,  0x50,  0x02,
+  0x14,  0x07,  0x01,  0x08,  0x17,  0x74,  0x14,  0x7f,  0x01,  0x08,  0x17,  0x74,  0x14,  0x12,  0x01,  0x08,
+  0x17,  0x74,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x17,  0x74,  0x14,  0x00,  0x01,  0x08,  0x17,  0x74,  0xfe,
+  0x89,  0x4a,  0x01,  0x08,  0x17,  0x74,  0xfe,  0x09,  0x49,  0x01,  0x08,  0x17,  0x74,  0x5f,  0xcc,  0x01,
+  0x08,  0x02,  0x21,  0xe4,  0x09,  0x07,  0xfe,  0x4c,  0x13,  0xc8,  0x20,  0xe4,  0xfe,  0x49,  0xf4,  0x00,
+  0x4d,  0x5f,  0xa1,  0x5e,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,  0xcc,  0xff,  0x02,  0x00,  0x10,  0x2f,
+  0xfe,  0x3e,  0x1a,  0x01,  0x43,  0x09,  0xfe,  0xe3,  0x00,  0xfe,  0x22,  0x13,  0x16,  0xfe,  0x64,  0x1a,
+  0x26,  0x20,  0x9e,  0x01,  0x41,  0x21,  0x9e,  0x09,  0x07,  0x5d,  0x01,  0x0c,  0x61,  0x07,  0x44,  0x02,
+  0x0a,  0x5a,  0x01,  0x18,  0xfe,  0x00,  0x40,  0xaa,  0x09,  0x1a,  0xfe,  0x12,  0x13,  0x0a,  0x9d,  0x01,
+  0x18,  0xaa,  0x0a,  0x67,  0x01,  0xa3,  0x02,  0x0a,  0x9d,  0x01,  0x18,  0xaa,  0xfe,  0x80,  0xe7,  0x1a,
+  0x09,  0x1a,  0x5d,  0xfe,  0x45,  0x58,  0x01,  0xfe,  0xb2,  0x16,  0xaa,  0x02,  0x0a,  0x5a,  0x01,  0x18,
+  0xaa,  0x0a,  0x67,  0x01,  0xa3,  0x02,  0x0a,  0x5a,  0x01,  0x18,  0x01,  0xfe,  0x7e,  0x1e,  0xfe,  0x80,
+  0x4c,  0xfe,  0x49,  0xe4,  0x1a,  0xfe,  0x12,  0x13,  0x0a,  0x9d,  0x01,  0x18,  0xfe,  0x80,  0x4c,  0x0a,
+  0x67,  0x01,  0x5c,  0x02,  0x1c,  0x1a,  0x87,  0x7c,  0xe5,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,
+  0x24,  0x1c,  0xfe,  0x1d,  0xf7,  0x28,  0xb1,  0xfe,  0x04,  0x1b,  0x01,  0xfe,  0x2a,  0x1c,  0xfa,  0xb3,
+  0x28,  0x7c,  0xfe,  0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x02,  0xc9,  0x2b,  0xfe,  0xf4,  0x1a,  0xfe,  0xfa,
+  0x10,  0x1c,  0x1a,  0x87,  0x03,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x24,  0xfe,  0x18,  0x58,  0x03,
+  0xfe,  0x66,  0x01,  0xfe,  0x19,  0x58,  0xb3,  0x24,  0x01,  0xfe,  0x0e,  0x1f,  0xfe,  0x30,  0xf4,  0x07,
+  0xfe,  0x3c,  0x50,  0x7c,  0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x24,  0xb1,  0xfe,
+  0x50,  0x1b,  0xfe,  0xd4,  0x14,  0x31,  0x02,  0xc9,  0x2b,  0xfe,  0x26,  0x1b,  0xfe,  0xba,  0x10,  0x1c,
+  0x1a,  0x87,  0xfe,  0x83,  0x5a,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x1d,  0xf7,  0x54,  0xb1,
+  0xfe,  0x72,  0x1b,  0xfe,  0xb2,  0x14,  0xfc,  0xb3,  0x54,  0x7c,  0x12,  0xfe,  0xaf,  0x19,  0xfe,  0x98,
+  0xe7,  0x00,  0x02,  0xc9,  0x2b,  0xfe,  0x66,  0x1b,  0xfe,  0x8a,  0x10,  0x1c,  0x1a,  0x87,  0x8b,  0x0f,
+  0xfe,  0x30,  0x90,  0x04,  0xfe,  0xb0,  0x93,  0x3a,  0x0b,  0xfe,  0x18,  0x58,  0xfe,  0x32,  0x90,  0x04,
+  0xfe,  0xb2,  0x93,  0x3a,  0x0b,  0xfe,  0x19,  0x58,  0x0e,  0xa8,  0xb3,  0x4a,  0x7c,  0x12,  0xfe,  0x0f,
+  0x79,  0xfe,  0x1c,  0xf7,  0x4a,  0xb1,  0xfe,  0xc6,  0x1b,  0xfe,  0x5e,  0x14,  0x31,  0x02,  0xc9,  0x2b,
+  0xfe,  0x96,  0x1b,  0x5c,  0xfe,  0x02,  0xf6,  0x1a,  0x87,  0xfe,  0x18,  0xfe,  0x6a,  0xfe,  0x19,  0xfe,
+  0x6b,  0x01,  0xfe,  0x1e,  0x1f,  0xfe,  0x1d,  0xf7,  0x65,  0xb1,  0xfe,  0xee,  0x1b,  0xfe,  0x36,  0x14,
+  0xfe,  0x1c,  0x13,  0xb3,  0x65,  0x3e,  0xfe,  0x83,  0x58,  0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x1a,
+  0xfe,  0x81,  0xe7,  0x1a,  0x15,  0xfe,  0xdd,  0x00,  0x7a,  0x30,  0x02,  0x7a,  0x30,  0xfe,  0x12,  0x45,
+  0x2b,  0xfe,  0xdc,  0x1b,  0x1f,  0x07,  0x47,  0xb5,  0xc3,  0x05,  0x35,  0xfe,  0x39,  0xf0,  0x75,  0x26,
+  0x02,  0xfe,  0x7e,  0x18,  0x23,  0x1d,  0x36,  0x13,  0x11,  0x02,  0x87,  0x03,  0xe3,  0x23,  0x07,  0xfe,
+  0xef,  0x12,  0xfe,  0xe1,  0x10,  0x90,  0x34,  0x60,  0xfe,  0x02,  0x80,  0x09,  0x56,  0xfe,  0x3c,  0x13,
+  0xfe,  0x82,  0x14,  0xfe,  0x42,  0x13,  0x51,  0xfe,  0x06,  0x83,  0x0a,  0x5a,  0x01,  0x18,  0xcb,  0xfe,
+  0x3e,  0x12,  0xfe,  0x41,  0x48,  0xfe,  0x45,  0x48,  0x01,  0xfe,  0xb2,  0x16,  0xfe,  0x00,  0xcc,  0xcb,
+  0xfe,  0xf3,  0x13,  0x3f,  0x89,  0x09,  0x1a,  0xa5,  0x0a,  0x9d,  0x01,  0x18,  0xfe,  0x80,  0x4c,  0x01,
+  0x85,  0xfe,  0x16,  0x10,  0x09,  0x9b,  0x4e,  0xfe,  0x40,  0x14,  0xfe,  0x24,  0x12,  0xfe,  0x14,  0x56,
+  0xfe,  0xd6,  0xf0,  0xfe,  0x52,  0x1c,  0x1c,  0x0d,  0x02,  0xfe,  0x9c,  0xe7,  0x0d,  0x19,  0xfe,  0x15,
+  0x00,  0x40,  0x8d,  0x30,  0x01,  0xf4,  0x1c,  0x07,  0x02,  0x51,  0xfe,  0x06,  0x83,  0xfe,  0x18,  0x80,
+  0x61,  0x28,  0x44,  0x15,  0x56,  0x01,  0x85,  0x1c,  0x07,  0x02,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,
+  0x91,  0xde,  0x7e,  0xdf,  0xfe,  0x48,  0x55,  0x31,  0xfe,  0xc9,  0x55,  0x02,  0x21,  0xb9,  0x88,  0x20,
+  0xb9,  0x02,  0x0a,  0xba,  0x01,  0x18,  0xfe,  0x41,  0x48,  0x0a,  0x57,  0x01,  0x18,  0xfe,  0x49,  0x44,
+  0x1b,  0xfe,  0x1e,  0x1d,  0x88,  0x89,  0x02,  0x0a,  0x5a,  0x01,  0x18,  0x09,  0x1a,  0xa4,  0x0a,  0x67,
+  0x01,  0xa3,  0x0a,  0x57,  0x01,  0x18,  0x88,  0x89,  0x02,  0xfe,  0x4e,  0xe4,  0x1d,  0x7b,  0xfe,  0x52,
+  0x1d,  0x03,  0xfe,  0x90,  0x00,  0xfe,  0x3a,  0x45,  0xfe,  0x2c,  0x10,  0xfe,  0x4e,  0xe4,  0xdd,  0x7b,
+  0xfe,  0x64,  0x1d,  0x03,  0xfe,  0x92,  0x00,  0xd1,  0x12,  0xfe,  0x1a,  0x10,  0xfe,  0x4e,  0xe4,  0xfe,
+  0x0b,  0x00,  0x7b,  0xfe,  0x76,  0x1d,  0x03,  0xfe,  0x94,  0x00,  0xd1,  0x24,  0xfe,  0x08,  0x10,  0x03,
+  0xfe,  0x96,  0x00,  0xd1,  0x63,  0xfe,  0x4e,  0x45,  0x83,  0xca,  0xff,  0x04,  0x68,  0x54,  0xfe,  0xf1,
+  0x10,  0x23,  0x49,  0xfe,  0x08,  0x1c,  0xfe,  0x67,  0x19,  0xfe,  0x0a,  0x1c,  0xfe,  0x1a,  0xf4,  0xfe,
+  0x00,  0x04,  0x83,  0xb2,  0x1d,  0x48,  0xfe,  0xaa,  0x1d,  0x13,  0x1d,  0x02,  0x09,  0x92,  0xfe,  0x5a,
+  0xf0,  0xfe,  0xba,  0x1d,  0x2e,  0x93,  0xfe,  0x34,  0x10,  0x09,  0x12,  0xfe,  0x5a,  0xf0,  0xfe,  0xc8,
+  0x1d,  0x2e,  0xb4,  0xfe,  0x26,  0x10,  0x09,  0x1d,  0x36,  0x2e,  0x63,  0xfe,  0x1a,  0x10,  0x09,  0x0d,
+  0x36,  0x2e,  0x94,  0xf2,  0x09,  0x07,  0x36,  0x2e,  0x95,  0xa1,  0xc8,  0x02,  0x1f,  0x93,  0x01,  0x42,
+  0xfe,  0x04,  0xfe,  0x99,  0x03,  0x9c,  0x8b,  0x02,  0x2a,  0xfe,  0x1c,  0x1e,  0xfe,  0x14,  0xf0,  0x08,
+  0x2f,  0xfe,  0x0c,  0x1e,  0x2a,  0xfe,  0x1c,  0x1e,  0x8f,  0xfe,  0x1c,  0x1e,  0xfe,  0x82,  0xf0,  0xfe,
+  0x10,  0x1e,  0x02,  0x0f,  0x3f,  0x04,  0xfe,  0x80,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x18,
+  0x80,  0x04,  0xfe,  0x98,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x02,  0x80,  0x04,  0xfe,  0x82,
+  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x06,  0x80,  0x04,  0xfe,  0x86,  0x83,  0x33,  0x0b,  0x0e,
+  0x02,  0x0f,  0xfe,  0x1b,  0x80,  0x04,  0xfe,  0x9b,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x04,
+  0x80,  0x04,  0xfe,  0x84,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x80,  0x80,  0x04,  0xfe,  0x80,
+  0x83,  0xfe,  0xc9,  0x47,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x19,  0x81,  0x04,  0xfe,  0x99,  0x83,  0xfe,
+  0xca,  0x47,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x06,  0x83,  0x04,  0xfe,  0x86,  0x83,  0xfe,  0xce,  0x47,
+  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x2c,  0x90,  0x04,  0xfe,  0xac,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x0f,
+  0xfe,  0xae,  0x90,  0x04,  0xfe,  0xae,  0x93,  0x79,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x08,  0x90,  0x04,
+  0xfe,  0x88,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x8a,  0x90,  0x04,  0xfe,  0x8a,  0x93,  0x79,
+  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x0c,  0x90,  0x04,  0xfe,  0x8c,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x0f,
+  0xfe,  0x8e,  0x90,  0x04,  0xfe,  0x8e,  0x93,  0x79,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x3c,  0x90,  0x04,
+  0xfe,  0xbc,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x8b,  0x0f,  0xfe,  0x03,  0x80,  0x04,  0xfe,  0x83,  0x83,
+  0x33,  0x0b,  0x77,  0x0e,  0xa8,  0x02,  0xff,  0x66,  0x00,  0x00,
+};
+
+STATIC unsigned short _adv_asc38C1600_size =
+        sizeof(_adv_asc38C1600_buf); /* 0x1673 */
+STATIC ADV_DCNT _adv_asc38C1600_chksum =
+        0x0604EF77UL; /* Expanded little-endian checksum. */
 
 /* a_init.c */
 /*
@@ -15455,6 +14572,14 @@
  * configuration. The BIOS now uses this structure when it is built.
  * Additional structure information can be found in a_condor.h where
  * the structure is defined.
+ *
+ * The *_Field_IsChar structs are needed to correct for endianness.
+ * These values are read from the board 16 bits at a time directly
+ * into the structs. Because some fields are char, the values will be
+ * in the wrong order. The *_Field_IsChar tells when to flip the
+ * bytes. Data read and written to PCI memory is automatically swapped
+ * on big-endian platforms so char fields read as words are actually being
+ * unswapped on big-endian platforms.
  */
 STATIC ADVEEP_3550_CONFIG
 Default_3550_EEPROM_Config ASC_INITDATA = {
@@ -15494,6 +14619,44 @@
     0                           /* num_of_err */
 };
 
+STATIC ADVEEP_3550_CONFIG
+ADVEEP_3550_Config_Field_IsChar ASC_INITDATA = {
+    0,                          /* cfg_lsw */
+    0,                          /* cfg_msw */
+    0,                          /* -disc_enable */
+    0,                          /* wdtr_able */
+    0,                          /* sdtr_able */
+    0,                          /* start_motor */
+    0,                          /* tagqng_able */
+    0,                          /* bios_scan */
+    0,                          /* scam_tolerant */
+    1,                          /* adapter_scsi_id */
+    1,                          /* bios_boot_delay */
+    1,                          /* scsi_reset_delay */
+    1,                          /* bios_id_lun */
+    1,                          /* termination */
+    1,                          /* reserved1 */
+    0,                          /* bios_ctrl */
+    0,                          /* ultra_able */
+    0,                          /* reserved2 */
+    1,                          /* max_host_qng */
+    1,                          /* max_dvc_qng */
+    0,                          /* dvc_cntl */
+    0,                          /* bug_fix */
+    0,                          /* serial_number_word1 */
+    0,                          /* serial_number_word2 */
+    0,                          /* serial_number_word3 */
+    0,                          /* check_sum */
+    { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* oem_name[16] */
+    0,                          /* dvc_err_code */
+    0,                          /* adv_err_code */
+    0,                          /* adv_err_addr */
+    0,                          /* saved_dvc_err_code */
+    0,                          /* saved_adv_err_code */
+    0,                          /* saved_adv_err_addr */
+    0                           /* num_of_err */
+};
+
 STATIC ADVEEP_38C0800_CONFIG
 Default_38C0800_EEPROM_Config ASC_INITDATA = {
     ADV_EEPROM_BIOS_ENABLE,     /* 00 cfg_lsw */
@@ -15559,6 +14722,201 @@
     0                           /* 63 reserved */
 };
 
+STATIC ADVEEP_38C0800_CONFIG
+ADVEEP_38C0800_Config_Field_IsChar ASC_INITDATA = {
+    0,                          /* 00 cfg_lsw */
+    0,                          /* 01 cfg_msw */
+    0,                          /* 02 disc_enable */
+    0,                          /* 03 wdtr_able */
+    0,                          /* 04 sdtr_speed1 */
+    0,                          /* 05 start_motor */
+    0,                          /* 06 tagqng_able */
+    0,                          /* 07 bios_scan */
+    0,                          /* 08 scam_tolerant */
+    1,                          /* 09 adapter_scsi_id */
+    1,                          /*    bios_boot_delay */
+    1,                          /* 10 scsi_reset_delay */
+    1,                          /*    bios_id_lun */
+    1,                          /* 11 termination_se */
+    1,                          /*    termination_lvd */
+    0,                          /* 12 bios_ctrl */
+    0,                          /* 13 sdtr_speed2 */
+    0,                          /* 14 sdtr_speed3 */
+    1,                          /* 15 max_host_qng */
+    1,                          /*    max_dvc_qng */
+    0,                          /* 16 dvc_cntl */
+    0,                          /* 17 sdtr_speed4 */
+    0,                          /* 18 serial_number_word1 */
+    0,                          /* 19 serial_number_word2 */
+    0,                          /* 20 serial_number_word3 */
+    0,                          /* 21 check_sum */
+    { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
+    0,                          /* 30 dvc_err_code */
+    0,                          /* 31 adv_err_code */
+    0,                          /* 32 adv_err_addr */
+    0,                          /* 33 saved_dvc_err_code */
+    0,                          /* 34 saved_adv_err_code */
+    0,                          /* 35 saved_adv_err_addr */
+    0,                          /* 36 reserved */
+    0,                          /* 37 reserved */
+    0,                          /* 38 reserved */
+    0,                          /* 39 reserved */
+    0,                          /* 40 reserved */
+    0,                          /* 41 reserved */
+    0,                          /* 42 reserved */
+    0,                          /* 43 reserved */
+    0,                          /* 44 reserved */
+    0,                          /* 45 reserved */
+    0,                          /* 46 reserved */
+    0,                          /* 47 reserved */
+    0,                          /* 48 reserved */
+    0,                          /* 49 reserved */
+    0,                          /* 50 reserved */
+    0,                          /* 51 reserved */
+    0,                          /* 52 reserved */
+    0,                          /* 53 reserved */
+    0,                          /* 54 reserved */
+    0,                          /* 55 reserved */
+    0,                          /* 56 cisptr_lsw */
+    0,                          /* 57 cisprt_msw */
+    0,                          /* 58 subsysvid */
+    0,                          /* 59 subsysid */
+    0,                          /* 60 reserved */
+    0,                          /* 61 reserved */
+    0,                          /* 62 reserved */
+    0                           /* 63 reserved */
+};
+
+STATIC ADVEEP_38C1600_CONFIG
+Default_38C1600_EEPROM_Config ASC_INITDATA = {
+    ADV_EEPROM_BIOS_ENABLE,     /* 00 cfg_lsw */
+    0x0000,                     /* 01 cfg_msw */
+    0xFFFF,                     /* 02 disc_enable */
+    0xFFFF,                     /* 03 wdtr_able */
+    0x5555,                     /* 04 sdtr_speed1 */
+    0xFFFF,                     /* 05 start_motor */
+    0xFFFF,                     /* 06 tagqng_able */
+    0xFFFF,                     /* 07 bios_scan */
+    0,                          /* 08 scam_tolerant */
+    7,                          /* 09 adapter_scsi_id */
+    0,                          /*    bios_boot_delay */
+    3,                          /* 10 scsi_reset_delay */
+    0,                          /*    bios_id_lun */
+    0,                          /* 11 termination_se */
+    0,                          /*    termination_lvd */
+    0xFFE7,                     /* 12 bios_ctrl */
+    0x5555,                     /* 13 sdtr_speed2 */
+    0x5555,                     /* 14 sdtr_speed3 */
+    ASC_DEF_MAX_HOST_QNG,       /* 15 max_host_qng */
+    ASC_DEF_MAX_DVC_QNG,        /*    max_dvc_qng */
+    0,                          /* 16 dvc_cntl */
+    0x5555,                     /* 17 sdtr_speed4 */
+    0,                          /* 18 serial_number_word1 */
+    0,                          /* 19 serial_number_word2 */
+    0,                          /* 20 serial_number_word3 */
+    0,                          /* 21 check_sum */
+    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
+    0,                          /* 30 dvc_err_code */
+    0,                          /* 31 adv_err_code */
+    0,                          /* 32 adv_err_addr */
+    0,                          /* 33 saved_dvc_err_code */
+    0,                          /* 34 saved_adv_err_code */
+    0,                          /* 35 saved_adv_err_addr */
+    0,                          /* 36 reserved */
+    0,                          /* 37 reserved */
+    0,                          /* 38 reserved */
+    0,                          /* 39 reserved */
+    0,                          /* 40 reserved */
+    0,                          /* 41 reserved */
+    0,                          /* 42 reserved */
+    0,                          /* 43 reserved */
+    0,                          /* 44 reserved */
+    0,                          /* 45 reserved */
+    0,                          /* 46 reserved */
+    0,                          /* 47 reserved */
+    0,                          /* 48 reserved */
+    0,                          /* 49 reserved */
+    0,                          /* 50 reserved */
+    0,                          /* 51 reserved */
+    0,                          /* 52 reserved */
+    0,                          /* 53 reserved */
+    0,                          /* 54 reserved */
+    0,                          /* 55 reserved */
+    0,                          /* 56 cisptr_lsw */
+    0,                          /* 57 cisprt_msw */
+    ADV_PCI_VENDOR_ID,          /* 58 subsysvid */
+    ADV_PCI_DEVID_38C1600_REV1, /* 59 subsysid */
+    0,                          /* 60 reserved */
+    0,                          /* 61 reserved */
+    0,                          /* 62 reserved */
+    0                           /* 63 reserved */
+};
+
+STATIC ADVEEP_38C1600_CONFIG
+ADVEEP_38C1600_Config_Field_IsChar ASC_INITDATA = {
+    0,                          /* 00 cfg_lsw */
+    0,                          /* 01 cfg_msw */
+    0,                          /* 02 disc_enable */
+    0,                          /* 03 wdtr_able */
+    0,                          /* 04 sdtr_speed1 */
+    0,                          /* 05 start_motor */
+    0,                          /* 06 tagqng_able */
+    0,                          /* 07 bios_scan */
+    0,                          /* 08 scam_tolerant */
+    1,                          /* 09 adapter_scsi_id */
+    1,                          /*    bios_boot_delay */
+    1,                          /* 10 scsi_reset_delay */
+    1,                          /*    bios_id_lun */
+    1,                          /* 11 termination_se */
+    1,                          /*    termination_lvd */
+    0,                          /* 12 bios_ctrl */
+    0,                          /* 13 sdtr_speed2 */
+    0,                          /* 14 sdtr_speed3 */
+    1,                          /* 15 max_host_qng */
+    1,                          /*    max_dvc_qng */
+    0,                          /* 16 dvc_cntl */
+    0,                          /* 17 sdtr_speed4 */
+    0,                          /* 18 serial_number_word1 */
+    0,                          /* 19 serial_number_word2 */
+    0,                          /* 20 serial_number_word3 */
+    0,                          /* 21 check_sum */
+    { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
+    0,                          /* 30 dvc_err_code */
+    0,                          /* 31 adv_err_code */
+    0,                          /* 32 adv_err_addr */
+    0,                          /* 33 saved_dvc_err_code */
+    0,                          /* 34 saved_adv_err_code */
+    0,                          /* 35 saved_adv_err_addr */
+    0,                          /* 36 reserved */
+    0,                          /* 37 reserved */
+    0,                          /* 38 reserved */
+    0,                          /* 39 reserved */
+    0,                          /* 40 reserved */
+    0,                          /* 41 reserved */
+    0,                          /* 42 reserved */
+    0,                          /* 43 reserved */
+    0,                          /* 44 reserved */
+    0,                          /* 45 reserved */
+    0,                          /* 46 reserved */
+    0,                          /* 47 reserved */
+    0,                          /* 48 reserved */
+    0,                          /* 49 reserved */
+    0,                          /* 50 reserved */
+    0,                          /* 51 reserved */
+    0,                          /* 52 reserved */
+    0,                          /* 53 reserved */
+    0,                          /* 54 reserved */
+    0,                          /* 55 reserved */
+    0,                          /* 56 cisptr_lsw */
+    0,                          /* 57 cisprt_msw */
+    0,                          /* 58 subsysvid */
+    0,                          /* 59 subsysid */
+    0,                          /* 60 reserved */
+    0,                          /* 61 reserved */
+    0,                          /* 62 reserved */
+    0                           /* 63 reserved */
+};
+
 /*
  * Initialize the ADV_DVC_VAR structure.
  *
@@ -15639,11 +14997,11 @@
     asc_dvc->cfg->chip_version =
       AdvGetChipVersion(iop_base, asc_dvc->bus_type);
 
-    ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: %x %x\n",
+    ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
         (ushort) AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
         (ushort) ADV_CHIP_ID_BYTE);
 
-    ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: %x %x\n",
+    ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
         (ushort) AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
         (ushort) ADV_CHIP_ID_WORD);
 
@@ -15676,7 +15034,13 @@
         AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
             ADV_CTRL_REG_CMD_WR_IO_REG);
 
-        if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
+        if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
+        {
+            if ((status = AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR)
+            {
+                return ADV_ERROR;
+            }
+        } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
         {
             if ((status = AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR)
             {
@@ -15702,6 +15066,8 @@
  *
  * For a non-fatal error return a warning code. If there are no warnings
  * then 0 is returned.
+ *
+ * Needed after initialization for error recovery.
  */
 STATIC int
 AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
@@ -15814,22 +15180,662 @@
             {
                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
                     _adv_asc3550_buf[i + 3] << 8) |
-                    _adv_asc3550_buf[i + 2]));
+                _adv_asc3550_buf[i + 2]));
                 word++;
             }
             i += 3;
         } else if (_adv_asc3550_buf[i] == 0xfe)
         {
             AdvWriteWordAutoIncLram(iop_base, (((ushort)
-                _adv_asc3550_buf[i + 2] << 8) |
-                _adv_asc3550_buf[i + 1]));
+                _adv_asc3550_buf[i + 2] << 8) |
+                _adv_asc3550_buf[i + 1]));
+            i += 2;
+            word++;
+        } else
+        {
+            AdvWriteWordAutoIncLram(iop_base, (((ushort)
+                _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) |
+                _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
+            word++;
+        }
+    }
+
+    /*
+     * Set 'word' for later use to clear the rest of memory and save
+     * the expanded mcode size.
+     */
+    word *= 2;
+    adv_asc3550_expanded_size = word;
+
+    /*
+     * Clear the rest of ASC-3550 Internal RAM (8KB).
+     */
+    for (; word < ADV_3550_MEMSIZE; word += 2)
+    {
+        AdvWriteWordAutoIncLram(iop_base, 0);
+    }
+
+    /*
+     * Verify the microcode checksum.
+     */
+    sum = 0;
+    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
+
+    for (word = 0; word < adv_asc3550_expanded_size; word += 2)
+    {
+        sum += AdvReadWordAutoIncLram(iop_base);
+    }
+
+    if (sum != _adv_asc3550_chksum)
+    {
+        asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
+        return ADV_ERROR;
+    }
+
+    /*
+     * Restore the RISC memory BIOS region.
+     */
+    for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
+    {
+        AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
+    }
+
+    /*
+     * Calculate and write the microcode code checksum to the microcode
+     * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
+     */
+    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
+    AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
+    code_sum = 0;
+    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
+    for (word = begin_addr; word < end_addr; word += 2)
+    {
+        code_sum += AdvReadWordAutoIncLram(iop_base);
+    }
+    AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
+
+    /*
+     * Read and save microcode version and date.
+     */
+    AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
+    AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
+
+    /*
+     * Set the chip type to indicate the ASC3550.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
+
+    /*
+     * If the PCI Configuration Command Register "Parity Error Response
+     * Control" Bit was clear (0), then set the microcode variable
+     * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
+     * to ignore DMA parity errors.
+     */
+    if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
+    {
+        AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
+        word |= CONTROL_FLAG_IGNORE_PERR;
+        AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
+    }
+
+    /*
+     * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
+     * threshold of 128 bytes. This register is only accessible to the host.
+     */
+    AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
+        START_CTL_EMFU | READ_CMD_MRM);
+
+    /*
+     * Microcode operating variables for WDTR, SDTR, and command tag
+     * queuing will be set in AdvInquiryHandling() based on what a
+     * device reports it is capable of in Inquiry byte 7.
+     *
+     * If SCSI Bus Resets have been disabled, then directly set
+     * SDTR and WDTR from the EEPROM configuration. This will allow
+     * the BIOS and warm boot to work without a SCSI bus hang on
+     * the Inquiry caused by host and target mismatched DTR values.
+     * Without the SCSI Bus Reset, before an Inquiry a device can't
+     * be assumed to be in Asynchronous, Narrow mode.
+     */
+    if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
+    {
+        AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
+        AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
+    }
+
+    /*
+     * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
+     * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
+     * bitmask. These values determine the maximum SDTR speed negotiated
+     * with a device.
+     *
+     * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
+     * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
+     * without determining here whether the device supports SDTR.
+     *
+     * 4-bit speed  SDTR speed name
+     * ===========  ===============
+     * 0000b (0x0)  SDTR disabled
+     * 0001b (0x1)  5 Mhz
+     * 0010b (0x2)  10 Mhz
+     * 0011b (0x3)  20 Mhz (Ultra)
+     * 0100b (0x4)  40 Mhz (LVD/Ultra2)
+     * 0101b (0x5)  80 Mhz (LVD2/Ultra3)
+     * 0110b (0x6)  Undefined
+     * .
+     * 1111b (0xF)  Undefined
+     */
+    word = 0;
+    for (tid = 0; tid <= ADV_MAX_TID; tid++)
+    {
+        if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able)
+        {
+            /* Set Ultra speed for TID 'tid'. */
+            word |= (0x3 << (4 * (tid % 4)));
+        } else
+        {
+            /* Set Fast speed for TID 'tid'. */
+            word |= (0x2 << (4 * (tid % 4)));
+        }
+        if (tid == 3) /* Check if done with sdtr_speed1. */
+        {
+            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
+            word = 0;
+        } else if (tid == 7) /* Check if done with sdtr_speed2. */
+        {
+            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
+            word = 0;
+        } else if (tid == 11) /* Check if done with sdtr_speed3. */
+        {
+            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
+            word = 0;
+        } else if (tid == 15) /* Check if done with sdtr_speed4. */
+        {
+            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
+            /* End of loop. */
+        }
+    }
+
+    /*
+     * Set microcode operating variable for the disconnect per TID bitmask.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
+
+    /*
+     * Set SCSI_CFG0 Microcode Default Value.
+     *
+     * The microcode will set the SCSI_CFG0 register using this value
+     * after it is started below.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
+        PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
+        asc_dvc->chip_scsi_id);
+
+    /*
+     * Determine SCSI_CFG1 Microcode Default Value.
+     *
+     * The microcode will set the SCSI_CFG1 register using this value
+     * after it is started below.
+     */
+
+    /* Read current SCSI_CFG1 Register value. */
+    scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
+
+    /*
+     * If all three connectors are in use, return an error.
+     */
+    if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
+        (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
+    {
+            asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
+            return ADV_ERROR;
+    }
+
+    /*
+     * If the internal narrow cable is reversed all of the SCSI_CTRL
+     * register signals will be set. Check for and return an error if
+     * this condition is found.
+     */
+    if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
+    {
+        asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
+        return ADV_ERROR;
+    }
+
+    /*
+     * If this is a differential board and a single-ended device
+     * is attached to one of the connectors, return an error.
+     */
+    if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
+    {
+        asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
+        return ADV_ERROR;
+    }
+
+    /*
+     * If automatic termination control is enabled, then set the
+     * termination value based on a table listed in a_condor.h.
+     *
+     * If manual termination was specified with an EEPROM setting
+     * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
+     * is ready to be 'ored' into SCSI_CFG1.
+     */
+    if (asc_dvc->cfg->termination == 0)
+    {
+        /*
+         * The software always controls termination by setting TERM_CTL_SEL.
+         * If TERM_CTL_SEL were set to 0, the hardware would set termination.
+         */
+        asc_dvc->cfg->termination |= TERM_CTL_SEL;
+
+        switch(scsi_cfg1 & CABLE_DETECT)
+        {
+            /* TERM_CTL_H: on, TERM_CTL_L: on */
+            case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
+                asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
+                break;
+
+            /* TERM_CTL_H: on, TERM_CTL_L: off */
+            case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
+                asc_dvc->cfg->termination |= TERM_CTL_H;
+                break;
+
+            /* TERM_CTL_H: off, TERM_CTL_L: off */
+            case 0x2: case 0x6:
+                break;
+        }
+    }
+
+    /*
+     * Clear any set TERM_CTL_H and TERM_CTL_L bits.
+     */
+    scsi_cfg1 &= ~TERM_CTL;
+
+    /*
+     * Invert the TERM_CTL_H and TERM_CTL_L bits and then
+     * set 'scsi_cfg1'. The TERM_POL bit does not need to be
+     * referenced, because the hardware internally inverts
+     * the Termination High and Low bits if TERM_POL is set.
+     */
+    scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
+
+    /*
+     * Set SCSI_CFG1 Microcode Default Value
+     *
+     * Set filter value and possibly modified termination control
+     * bits in the Microcode SCSI_CFG1 Register Value.
+     *
+     * The microcode will set the SCSI_CFG1 register using this value
+     * after it is started below.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
+        FLTR_DISABLE | scsi_cfg1);
+
+    /*
+     * Set MEM_CFG Microcode Default Value
+     *
+     * The microcode will set the MEM_CFG register using this value
+     * after it is started below.
+     *
+     * MEM_CFG may be accessed as a word or byte, but only bits 0-7
+     * are defined.
+     *
+     * ASC-3550 has 8KB internal memory.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
+        BIOS_EN | RAM_SZ_8KB);
+
+    /*
+     * Set SEL_MASK Microcode Default Value
+     *
+     * The microcode will set the SEL_MASK register using this value
+     * after it is started below.
+     */
+    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
+        ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
+
+    /*
+     * Build carrier freelist.
+     *
+     * Driver must have already allocated memory and set 'carrier_buf'.
+     */
+    ASC_ASSERT(asc_dvc->carrier_buf != NULL);
+
+    carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
+    asc_dvc->carr_freelist = NULL;
+    if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
+    {
+        buf_size = ADV_CARRIER_BUFSIZE;
+    } else
+    {
+        buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
+    }
+
+    do {
+        /*
+         * Get physical address of the carrier 'carrp'.
+         */
+        contig_len = sizeof(ADV_CARR_T);
+        carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
+            (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
+
+        buf_size -= sizeof(ADV_CARR_T);
+
+        /*
+         * If the current carrier is not physically contiguous, then
+         * maybe there was a page crossing. Try the next carrier aligned
+         * start address.
+         */
+        if (contig_len < sizeof(ADV_CARR_T))
+        {
+            carrp++;
+            continue;
+        }
+
+        carrp->carr_pa = carr_paddr;
+        carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
+
+        /*
+         * Insert the carrier at the beginning of the freelist.
+         */
+        carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
+        asc_dvc->carr_freelist = carrp;
+
+        carrp++;
+    }
+    while (buf_size > 0);
+
+    /*
+     * Set-up the Host->RISC Initiator Command Queue (ICQ).
+     */
+
+    if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
+    {
+        asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
+        return ADV_ERROR;
+    }
+    asc_dvc->carr_freelist = (ADV_CARR_T *)
+        ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
+
+    /*
+     * The first command issued will be placed in the stopper carrier.
+     */
+    asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
+
+    /*
+     * Set RISC ICQ physical address start value.
+     */
+    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
+
+    /*
+     * Set-up the RISC->Host Initiator Response Queue (IRQ).
+     */
+    if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
+    {
+        asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
+        return ADV_ERROR;
+    }
+    asc_dvc->carr_freelist = (ADV_CARR_T *)
+         ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
+
+    /*
+     * The first command completed by the RISC will be placed in
+     * the stopper.
+     *
+     * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
+     * completed the RISC will set the ASC_RQ_STOPPER bit.
+     */
+    asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
+
+    /*
+     * Set RISC IRQ physical address start value.
+     */
+    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
+    asc_dvc->carr_pending_cnt = 0;
+
+    AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
+        (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
+
+    AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
+    AdvWriteWordRegister(iop_base, IOPW_PC, word);
+
+    /* finally, finally, gentlemen, start your engine */
+    AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
+
+    /*
+     * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
+     * Resets should be performed. The RISC has to be running
+     * to issue a SCSI Bus Reset.
+     */
+    if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
+    {
+        /*
+         * If the BIOS Signature is present in memory, restore the
+         * BIOS Handshake Configuration Table and do not perform
+         * a SCSI Bus Reset.
+         */
+        if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
+        {
+            /*
+             * Restore per TID negotiated values.
+             */
+            AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
+            AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
+            AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
+            for (tid = 0; tid <= ADV_MAX_TID; tid++)
+            {
+                AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
+                    max_cmd[tid]);
+            }
+        } else
+        {
+            if (AdvResetSB(asc_dvc) != ADV_TRUE)
+            {
+                warn_code = ASC_WARN_BUSRESET_ERROR;
+            }
+        }
+    }
+
+    return warn_code;
+}
+
+/*
+ * Initialize the ASC-38C0800.
+ *
+ * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
+ *
+ * For a non-fatal error return a warning code. If there are no warnings
+ * then 0 is returned.
+ *
+ * Needed after initialization for error recovery.
+ */
+STATIC int
+AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
+{
+    AdvPortAddr iop_base;
+    ushort      warn_code;
+    ADV_DCNT    sum;
+    int         begin_addr;
+    int         end_addr;
+    ushort      code_sum;
+    int         word;
+    int         j;
+    int         adv_asc38C0800_expanded_size;
+    ADV_CARR_T  *carrp;
+    ADV_DCNT    contig_len;
+    ADV_SDCNT   buf_size;
+    ADV_PADDR   carr_paddr;
+    int         i;
+    ushort      scsi_cfg1;
+    uchar       byte;
+    uchar       tid;
+    ushort      bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
+    ushort      wdtr_able, sdtr_able, tagqng_able;
+    uchar       max_cmd[ADV_MAX_TID + 1];
+
+    /* If there is already an error, don't continue. */
+    if (asc_dvc->err_code != 0)
+    {
+        return ADV_ERROR;
+    }
+
+    /*
+     * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
+     */
+    if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800)
+    {
+        asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
+        return ADV_ERROR;
+    }
+
+    warn_code = 0;
+    iop_base = asc_dvc->iop_base;
+
+    /*
+     * Save the RISC memory BIOS region before writing the microcode.
+     * The BIOS may already be loaded and using its RISC LRAM region
+     * so its region must be saved and restored.
+     *
+     * Note: This code makes the assumption, which is currently true,
+     * that a chip reset does not clear RISC LRAM.
+     */
+    for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
+    {
+        AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
+    }
+
+    /*
+     * Save current per TID negotiated values.
+     */
+    AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
+    AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
+    AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
+    for (tid = 0; tid <= ADV_MAX_TID; tid++)
+    {
+        AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
+            max_cmd[tid]);
+    }
+
+    /*
+     * RAM BIST (RAM Built-In Self Test)
+     *
+     * Address : I/O base + offset 0x38h register (byte).
+     * Function: Bit 7-6(RW) : RAM mode
+     *                          Normal Mode   : 0x00
+     *                          Pre-test Mode : 0x40
+     *                          RAM Test Mode : 0x80
+     *           Bit 5       : unused
+     *           Bit 4(RO)   : Done bit
+     *           Bit 3-0(RO) : Status
+     *                          Host Error    : 0x08
+     *                          Int_RAM Error : 0x04
+     *                          RISC Error    : 0x02
+     *                          SCSI Error    : 0x01
+     *                          No Error      : 0x00
+     *
+     * Note: RAM BIST code should be put right here, before loading the
+     * microcode and after saving the RISC memory BIOS region.
+     */
+
+    /*
+     * LRAM Pre-test
+     *
+     * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
+     * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
+     * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
+     * to NORMAL_MODE, return an error too.
+     */
+    for (i = 0; i < 2; i++)
+    {
+        AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
+        DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
+        byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
+        if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
+        {
+            asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
+            return ADV_ERROR;
+        }
+
+        AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
+        DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
+        if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
+            != NORMAL_VALUE)
+        {
+            asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
+            return ADV_ERROR;
+        }
+    }
+
+    /*
+     * LRAM Test - It takes about 1.5 ms to run through the test.
+     *
+     * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
+     * If Done bit not set or Status not 0, save register byte, set the
+     * err_code, and return an error.
+     */
+    AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
+    DvcSleepMilliSecond(10);  /* Wait for 10ms before checking status. */
+
+    byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
+    if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
+    {
+        /* Get here if Done bit not set or Status not 0. */
+        asc_dvc->bist_err_code = byte;  /* for BIOS display message */
+        asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
+        return ADV_ERROR;
+    }
+
+    /* We need to reset back to normal mode after LRAM test passes. */
+    AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
+
+    /*
+     * Load the Microcode
+     *
+     * Write the microcode image to RISC memory starting at address 0.
+     *
+     */
+    AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
+
+    /* Assume the following compressed format of the microcode buffer:
+     *
+     *  254 word (508 byte) table indexed by byte code followed
+     *  by the following byte codes:
+     *
+     *    1-Byte Code:
+     *      00: Emit word 0 in table.
+     *      01: Emit word 1 in table.
+     *      .
+     *      FD: Emit word 253 in table.
+     *
+     *    Multi-Byte Code:
+     *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
+     *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
+     */
+    word = 0;
+    for (i = 253 * 2; i < _adv_asc38C0800_size; i++)
+    {
+        if (_adv_asc38C0800_buf[i] == 0xff)
+        {
+            for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++)
+            {
+                AdvWriteWordAutoIncLram(iop_base, (((ushort)
+                    _adv_asc38C0800_buf[i + 3] << 8) |
+                    _adv_asc38C0800_buf[i + 2]));
+                word++;
+            }
+            i += 3;
+        } else if (_adv_asc38C0800_buf[i] == 0xfe)
+        {
+            AdvWriteWordAutoIncLram(iop_base, (((ushort)
+                _adv_asc38C0800_buf[i + 2] << 8) |
+                _adv_asc38C0800_buf[i + 1]));
             i += 2;
             word++;
         } else
         {
             AdvWriteWordAutoIncLram(iop_base, (((ushort)
-                _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) |
-                _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
+                _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) |
+                _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
             word++;
         }
     }
@@ -15839,12 +15845,12 @@
      * the expanded mcode size.
      */
     word *= 2;
-    adv_asc3550_expanded_size = word;
+    adv_asc38C0800_expanded_size = word;
 
     /*
-     * Clear the rest of ASC-3550 Internal RAM (8KB).
+     * Clear the rest of ASC-38C0800 Internal RAM (16KB).
      */
-    for (; word < ADV_3550_MEMSIZE; word += 2)
+    for (; word < ADV_38C0800_MEMSIZE; word += 2)
     {
         AdvWriteWordAutoIncLram(iop_base, 0);
     }
@@ -15855,12 +15861,17 @@
     sum = 0;
     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
 
-    for (word = 0; word < adv_asc3550_expanded_size; word += 2)
+    for (word = 0; word < adv_asc38C0800_expanded_size; word += 2)
     {
         sum += AdvReadWordAutoIncLram(iop_base);
     }
+    ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
 
-    if (sum != _adv_asc3550_chksum)
+    ASC_DBG2(1,
+        "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
+        (ulong) sum, (ulong) _adv_asc38C0800_chksum);
+
+    if (sum != _adv_asc38C0800_chksum)
     {
         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
         return ADV_ERROR;
@@ -15871,7 +15882,7 @@
      */
     for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
     {
-        AdvWriteByteLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
+        AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
     }
 
     /*
@@ -15889,15 +15900,26 @@
     AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
 
     /*
-     * Read and save microcode version and date.
+     * Read microcode version and date.
      */
     AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
     AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
 
     /*
-     * Set the chip type to indicate the ASC3550.
+     * Set the chip type to indicate the ASC38C0800.
      */
-    AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
+    AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
+
+    /*
+     * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
+     * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
+     * cable detection and then we are able to read C_DET[3:0].
+     *
+     * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
+     * Microcode Default Value' section below.
+     */
+    scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
+    AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
 
     /*
      * If the PCI Configuration Command Register "Parity Error Response
@@ -15907,22 +15929,21 @@
      */
     if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
     {
-        /*
-         * Note: Don't remove the use of a temporary variable in
-         * the following code, otherwise the Microsoft C compiler
-         * will turn the following lines into a no-op.
-         */
         AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
         word |= CONTROL_FLAG_IGNORE_PERR;
         AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
     }
 
     /*
-     * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
-     * threshold of 128 bytes. This register is only accessible to the host.
+     * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
+     * bits for the default FIFO threshold.
+     *
+     * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
+     *
+     * For DMA Errata #4 set the BC_THRESH_ENB bit.
      */
     AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
-        START_CTL_EMFU | READ_CMD_MRM);
+        BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
 
     /*
      * Microcode operating variables for WDTR, SDTR, and command tag
@@ -15943,63 +15964,19 @@
     }
 
     /*
-     * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
-     * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
-     * bitmask. These values determine the maximum SDTR speed negotiated
-     * with a device.
+     * Set microcode operating variables for DISC and SDTR_SPEED1,
+     * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
+     * configuration values.
      *
      * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
      * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
      * without determining here whether the device supports SDTR.
-     *
-     * 4-bit speed  SDTR speed name
-     * ===========  ===============
-     * 0000b (0x0)  SDTR disabled
-     * 0001b (0x1)  5 Mhz
-     * 0010b (0x2)  10 Mhz
-     * 0011b (0x3)  20 Mhz (Ultra)
-     * 0100b (0x4)  40 Mhz (LVD/Ultra2)
-     * 0101b (0x5)  80 Mhz (LVD2/Ultra3)
-     * 0110b (0x6)  Undefined
-     * .
-     * 1111b (0xF)  Undefined
-     */
-    word = 0;
-    for (tid = 0; tid <= ADV_MAX_TID; tid++)
-    {
-        if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able)
-        {
-            /* Set Ultra speed for TID 'tid'. */
-            word |= (0x3 << (4 * (tid % 4)));
-        } else
-        {
-            /* Set Fast speed for TID 'tid'. */
-            word |= (0x2 << (4 * (tid % 4)));
-        }
-        if (tid == 3) /* Check if done with sdtr_speed1. */
-        {
-            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
-            word = 0;
-        } else if (tid == 7) /* Check if done with sdtr_speed2. */
-        {
-            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
-            word = 0;
-        } else if (tid == 11) /* Check if done with sdtr_speed3. */
-        {
-            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
-            word = 0;
-        } else if (tid == 15) /* Check if done with sdtr_speed4. */
-        {
-            AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
-            /* End of loop. */
-        }
-    }
-
-    /*
-     * Set microcode operating variable for the disconnect per TID bitmask.
      */
     AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
-
+    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
+    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
+    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
+    AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
 
     /*
      * Set SCSI_CFG0 Microcode Default Value.
@@ -16008,7 +15985,8 @@
      * after it is started below.
      */
     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
-        PARITY_EN | SEL_TMO_LONG | OUR_ID_EN | asc_dvc->chip_scsi_id);
+        PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
+        asc_dvc->chip_scsi_id);
 
     /*
      * Determine SCSI_CFG1 Microcode Default Value.
@@ -16021,16 +15999,6 @@
     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
 
     /*
-     * If all three connectors are in use, return an error.
-     */
-    if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
-        (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
-    {
-            asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
-            return ADV_ERROR;
-    }
-
-    /*
      * If the internal narrow cable is reversed all of the SCSI_CTRL
      * register signals will be set. Check for and return an error if
      * this condition is found.
@@ -16042,73 +16010,88 @@
     }
 
     /*
-     * If this is a differential board and a single-ended device
-     * is attached to one of the connectors, return an error.
+     * All kind of combinations of devices attached to one of four connectors
+     * are acceptable except HVD device attached. For example, LVD device can
+     * be attached to SE connector while SE device attached to LVD connector.
+     * If LVD device attached to SE connector, it only runs up to Ultra speed.
+     *
+     * If an HVD device is attached to one of LVD connectors, return an error.
+     * However, there is no way to detect HVD device attached to SE connectors.
      */
-    if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
+    if (scsi_cfg1 & HVD)
     {
-        asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
+        asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
         return ADV_ERROR;
     }
 
     /*
-     * If automatic termination control is enabled, then set the
-     * termination value based on a table listed in a_condor.h.
+     * If either SE or LVD automatic termination control is enabled, then
+     * set the termination value based on a table listed in a_condor.h.
      *
-     * If manual termination was specified with an EEPROM setting
-     * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
-     * is ready to be 'ored' into SCSI_CFG1.
+     * If manual termination was specified with an EEPROM setting then
+     * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
+     * be 'ored' into SCSI_CFG1.
      */
-    if (asc_dvc->cfg->termination == 0)
+    if ((asc_dvc->cfg->termination & TERM_SE) == 0)
     {
-        /*
-         * The software always controls termination by setting TERM_CTL_SEL.
-         * If TERM_CTL_SEL were set to 0, the hardware would set termination.
-         */
-        asc_dvc->cfg->termination |= TERM_CTL_SEL;
-
-        switch(scsi_cfg1 & CABLE_DETECT)
+        /* SE automatic termination control is enabled. */
+        switch(scsi_cfg1 & C_DET_SE)
         {
-            /* TERM_CTL_H: on, TERM_CTL_L: on */
-            case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
-                asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
+            /* TERM_SE_HI: on, TERM_SE_LO: on */
+            case 0x1: case 0x2: case 0x3:
+                asc_dvc->cfg->termination |= TERM_SE;
                 break;
 
-            /* TERM_CTL_H: on, TERM_CTL_L: off */
-            case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
-                asc_dvc->cfg->termination |= TERM_CTL_H;
+            /* TERM_SE_HI: on, TERM_SE_LO: off */
+            case 0x0:
+                asc_dvc->cfg->termination |= TERM_SE_HI;
                 break;
+        }
+    }
 
-            /* TERM_CTL_H: off, TERM_CTL_L: off */
-            case 0x2: case 0x6:
+    if ((asc_dvc->cfg->termination & TERM_LVD) == 0)
+    {
+        /* LVD automatic termination control is enabled. */
+        switch(scsi_cfg1 & C_DET_LVD)
+        {
+            /* TERM_LVD_HI: on, TERM_LVD_LO: on */
+            case 0x4: case 0x8: case 0xC:
+                asc_dvc->cfg->termination |= TERM_LVD;
+                break;
+
+            /* TERM_LVD_HI: off, TERM_LVD_LO: off */
+            case 0x0:
                 break;
         }
     }
 
     /*
-     * Clear any set TERM_CTL_H and TERM_CTL_L bits.
+     * Clear any set TERM_SE and TERM_LVD bits.
      */
-    scsi_cfg1 &= ~TERM_CTL;
+    scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
 
     /*
-     * Invert the TERM_CTL_H and TERM_CTL_L bits and then
-     * set 'scsi_cfg1'. The TERM_POL bit does not need to be
-     * referenced, because the hardware internally inverts
-     * the Termination High and Low bits if TERM_POL is set.
+     * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
      */
-    scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
+    scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
+
+    /*
+     * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
+     * and set possibly modified termination control bits in the Microcode
+     * SCSI_CFG1 Register Value.
+     */
+    scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
 
     /*
      * Set SCSI_CFG1 Microcode Default Value
      *
-     * Set filter value and possibly modified termination control
+     * Set possibly modified termination control and reset DIS_TERM_DRV
      * bits in the Microcode SCSI_CFG1 Register Value.
      *
      * The microcode will set the SCSI_CFG1 register using this value
      * after it is started below.
      */
-    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
-        FLTR_DISABLE | scsi_cfg1);
+    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
 
     /*
      * Set MEM_CFG Microcode Default Value
@@ -16119,10 +16102,10 @@
      * MEM_CFG may be accessed as a word or byte, but only bits 0-7
      * are defined.
      *
-     * ASC-3550 has 8KB internal memory.
+     * ASC-38C0800 has 16KB internal memory.
      */
     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
-        BIOS_EN | RAM_SZ_8KB);
+        BIOS_EN | RAM_SZ_16KB);
 
     /*
      * Set SEL_MASK Microcode Default Value
@@ -16134,7 +16117,7 @@
         ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
 
     /*
-     * Build carrier freelist.
+     * Build the carrier freelist.
      *
      * Driver must have already allocated memory and set 'carrier_buf'.
      */
@@ -16152,7 +16135,7 @@
 
     do {
         /*
-         * Get physical address of the carrier 'carrp'.
+         * Get physical address for the carrier 'carrp'.
          */
         contig_len = sizeof(ADV_CARR_T);
         carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
@@ -16172,12 +16155,12 @@
         }
 
         carrp->carr_pa = carr_paddr;
-        carrp->carr_va = ADV_VADDR_TO_U32(carrp);
+        carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
 
         /*
          * Insert the carrier at the beginning of the freelist.
          */
-        carrp->next_vpa = ADV_VADDR_TO_U32(asc_dvc->carr_freelist);
+        carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
         asc_dvc->carr_freelist = carrp;
 
         carrp++;
@@ -16193,19 +16176,19 @@
         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
         return ADV_ERROR;
     }
-    asc_dvc->carr_freelist =
-        (ADV_CARR_T *) ADV_U32_TO_VADDR(asc_dvc->icq_sp->next_vpa);
+    asc_dvc->carr_freelist = (ADV_CARR_T *)
+        ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
 
     /*
      * The first command issued will be placed in the stopper carrier.
      */
-    asc_dvc->icq_sp->next_vpa = ASC_CQ_STOPPER;
+    asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
 
     /*
      * Set RISC ICQ physical address start value.
+     * carr_pa is LE, must be native before write
      */
-    AdvWriteDWordLram(iop_base, ASC_MC_ICQ,
-        cpu_to_le32(asc_dvc->icq_sp->carr_pa));
+    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
 
     /*
      * Set-up the RISC->Host Initiator Response Queue (IRQ).
@@ -16215,8 +16198,8 @@
         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
         return ADV_ERROR;
     }
-    asc_dvc->carr_freelist =
-        (ADV_CARR_T *) ADV_U32_TO_VADDR(asc_dvc->irq_sp->next_vpa);
+    asc_dvc->carr_freelist = (ADV_CARR_T *)
+        ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
 
     /*
      * The first command completed by the RISC will be placed in
@@ -16225,23 +16208,19 @@
      * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
      * completed the RISC will set the ASC_RQ_STOPPER bit.
      */
-    asc_dvc->irq_sp->next_vpa = ASC_CQ_STOPPER;
+    asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
 
     /*
      * Set RISC IRQ physical address start value.
+     *
+     * carr_pa is LE, must be native before write *
      */
-    AdvWriteDWordLram(iop_base, ASC_MC_IRQ,
-        cpu_to_le32(asc_dvc->irq_sp->carr_pa));
+    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
     asc_dvc->carr_pending_cnt = 0;
 
     AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
         (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
 
-    /*
-     * Note: Don't remove the use of a temporary variable in
-     * the following code, otherwise the Microsoft C compiler
-     * will turn the following lines into a no-op.
-     */
     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
     AdvWriteWordRegister(iop_base, IOPW_PC, word);
 
@@ -16286,15 +16265,17 @@
 }
 
 /*
- * Initialize the ASC-38C0800.
+ * Initialize the ASC-38C1600.
  *
- * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
+ * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
  *
  * For a non-fatal error return a warning code. If there are no warnings
  * then 0 is returned.
+ *
+ * Needed after initialization for error recovery.
  */
 STATIC int
-AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
+AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
 {
     AdvPortAddr iop_base;
     ushort      warn_code;
@@ -16302,9 +16283,9 @@
     int         begin_addr;
     int         end_addr;
     ushort      code_sum;
-    int         word;
+    long        word;
     int         j;
-    int         adv_asc38C0800_expanded_size;
+    int         adv_asc38C1600_expanded_size;
     ADV_CARR_T  *carrp;
     ADV_DCNT    contig_len;
     ADV_SDCNT   buf_size;
@@ -16314,8 +16295,8 @@
     uchar       byte;
     uchar       tid;
     ushort      bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
-    ushort      wdtr_able, sdtr_able, tagqng_able;
-    uchar       max_cmd[ADV_MAX_TID + 1];
+    ushort      wdtr_able, sdtr_able, ppr_able, tagqng_able;
+    uchar       max_cmd[ASC_MAX_TID + 1];
 
     /* If there is already an error, don't continue. */
     if (asc_dvc->err_code != 0)
@@ -16324,9 +16305,9 @@
     }
 
     /*
-     * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
+     * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
      */
-    if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800)
+    if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
     {
         asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
         return ADV_ERROR;
@@ -16353,15 +16334,16 @@
      */
     AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
+    AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
-    for (tid = 0; tid <= ADV_MAX_TID; tid++)
+    for (tid = 0; tid <= ASC_MAX_TID; tid++)
     {
         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
             max_cmd[tid]);
     }
 
     /*
-     * RAM BIST (RAM Built-In Self Test)
+     * RAM BIST (Built-In Self Test)
      *
      * Address : I/O base + offset 0x38h register (byte).
      * Function: Bit 7-6(RW) : RAM mode
@@ -16440,7 +16422,8 @@
      */
     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
 
-    /* Assume the following compressed format of the microcode buffer:
+    /*
+     * Assume the following compressed format of the microcode buffer:
      *
      *  254 word (508 byte) table indexed by byte code followed
      *  by the following byte codes:
@@ -16456,30 +16439,30 @@
      *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
      */
     word = 0;
-    for (i = 253 * 2; i < _adv_asc38C0800_size; i++)
+    for (i = 253 * 2; i < _adv_asc38C1600_size; i++)
     {
-        if (_adv_asc38C0800_buf[i] == 0xff)
+        if (_adv_asc38C1600_buf[i] == 0xff)
         {
-            for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++)
+            for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++)
             {
                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
-                    _adv_asc38C0800_buf[i + 3] << 8) |
-                    _adv_asc38C0800_buf[i + 2]));
+                     _adv_asc38C1600_buf[i + 3] << 8) |
+                     _adv_asc38C1600_buf[i + 2]));
                 word++;
             }
-            i += 3;
-        } else if (_adv_asc38C0800_buf[i] == 0xfe)
+           i += 3;
+        } else if (_adv_asc38C1600_buf[i] == 0xfe)
         {
-            AdvWriteWordAutoIncLram(iop_base, (((ushort)
-                _adv_asc38C0800_buf[i + 2] << 8) |
-                _adv_asc38C0800_buf[i + 1]));
+                AdvWriteWordAutoIncLram(iop_base, (((ushort)
+                     _adv_asc38C1600_buf[i + 2] << 8) |
+                     _adv_asc38C1600_buf[i + 1]));
             i += 2;
             word++;
         } else
         {
             AdvWriteWordAutoIncLram(iop_base, (((ushort)
-                _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) |
-                _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
+                 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) |
+                 _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
             word++;
         }
     }
@@ -16489,12 +16472,12 @@
      * the expanded mcode size.
      */
     word *= 2;
-    adv_asc38C0800_expanded_size = word;
+    adv_asc38C1600_expanded_size = word;
 
     /*
-     * Clear the rest of ASC-38C0800 Internal RAM (16KB).
+     * Clear the rest of ASC-38C1600 Internal RAM (32KB).
      */
-    for (; word < ADV_38C0800_MEMSIZE; word += 2)
+    for (; word < ADV_38C1600_MEMSIZE; word += 2)
     {
         AdvWriteWordAutoIncLram(iop_base, 0);
     }
@@ -16505,17 +16488,12 @@
     sum = 0;
     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
 
-    for (word = 0; word < adv_asc38C0800_expanded_size; word += 2)
+    for (word = 0; word < adv_asc38C1600_expanded_size; word += 2)
     {
         sum += AdvReadWordAutoIncLram(iop_base);
     }
-    ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
-
-    ASC_DBG2(1,
-        "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
-        (ulong) sum, (ulong) _adv_asc38C0800_chksum);
 
-    if (sum != _adv_asc38C0800_chksum)
+    if (sum != _adv_asc38C1600_chksum)
     {
         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
         return ADV_ERROR;
@@ -16550,9 +16528,9 @@
     AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
 
     /*
-     * Set the chip type to indicate the ASC38C0800.
+     * Set the chip type to indicate the ASC38C1600.
      */
-    AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
+    AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
 
     /*
      * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
@@ -16573,26 +16551,30 @@
      */
     if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
     {
-        /*
-         * Note: Don't remove the use of a temporary variable in
-         * the following code, otherwise the Microsoft C compiler
-         * will turn the following lines into a no-op.
-         */
         AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
         word |= CONTROL_FLAG_IGNORE_PERR;
         AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
     }
 
     /*
-     * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
-     * bits for the default FIFO threshold.
-     *
-     * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
-     *
-     * For DMA Errata #4 set the BC_THRESH_ENB bit.
+     * If the BIOS control flag AIPP (Asynchronous Information
+     * Phase Protection) disable bit is not set, then set the firmware
+     * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
+     * AIPP checking and encoding.
+     */
+    if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0)
+    {
+        AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
+        word |= CONTROL_FLAG_ENABLE_AIPP;
+        AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
+    }
+
+    /*
+     * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
+     * and START_CTL_TH [3:2].
      */
     AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
-        BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
+        FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
 
     /*
      * Microcode operating variables for WDTR, SDTR, and command tag
@@ -16634,22 +16616,24 @@
      * after it is started below.
      */
     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
-        PARITY_EN | SEL_TMO_LONG | OUR_ID_EN | asc_dvc->chip_scsi_id);
+        PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
+        asc_dvc->chip_scsi_id);
 
     /*
-     * Determine SCSI_CFG1 Microcode Default Value.
+     * Calculate SCSI_CFG1 Microcode Default Value.
      *
      * The microcode will set the SCSI_CFG1 register using this value
      * after it is started below.
+     *
+     * Each ASC-38C1600 function has only two cable detect bits.
+     * The bus mode override bits are in IOPB_SOFT_OVER_WR.
      */
-
-    /* Read current SCSI_CFG1 Register value. */
     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
 
     /*
-     * If the internal narrow cable is reversed all of the SCSI_CTRL
-     * register signals will be set. Check for and return an error if
-     * this condition is found.
+     * If the cable is reversed all of the SCSI_CTRL register signals
+     * will be set. Check for and return an error if this condition is
+     * found.
      */
     if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
     {
@@ -16658,13 +16642,12 @@
     }
 
     /*
-     * All kind of combinations of devices attached to one of four connectors
-     * are acceptable except HVD device attached. For example, LVD device can
-     * be attached to SE connector while SE device attached to LVD connector.
-     * If LVD device attached to SE connector, it only runs up to Ultra speed.
+     * Each ASC-38C1600 function has two connectors. Only an HVD device
+     * can not be connected to either connector. An LVD device or SE device
+     * may be connected to either connecor. If an SE device is connected,
+     * then at most Ultra speed (20 Mhz) can be used on both connectors.
      *
-     * If an HVD device is attached to one of LVD connectors, return an error.
-     * However, there is no way to detect HVD device attached to SE connectors.
+     * If an HVD device is attached, return an error.
      */
     if (scsi_cfg1 & HVD)
     {
@@ -16673,12 +16656,17 @@
     }
 
     /*
-     * If either SE or LVD automatic termination control is enabled, then
-     * set the termination value based on a table listed in a_condor.h.
+     * Each function in the ASC-38C1600 uses only the SE cable detect and
+     * termination because there are two connectors for each function. Each
+     * function may use either LVD or SE mode. Corresponding the SE automatic
+     * termination control EEPROM bits are used for each function. Each
+     * function has its own EEPROM. If SE automatic control is enabled for
+     * the function, then set the termination value based on a table listed
+     * in a_condor.h.
      *
-     * If manual termination was specified with an EEPROM setting then
-     * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
-     * be 'ored' into SCSI_CFG1.
+     * If manual termination is specified in the EEPROM for the function,
+     * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
+     * ready to be 'ored' into SCSI_CFG1.
      */
     if ((asc_dvc->cfg->termination & TERM_SE) == 0)
     {
@@ -16690,51 +16678,44 @@
                 asc_dvc->cfg->termination |= TERM_SE;
                 break;
 
-            /* TERM_SE_HI: on, TERM_SE_LO: off */
-            case 0x0:
-                asc_dvc->cfg->termination |= TERM_SE_HI;
-                break;
-        }
-    }
-
-    if ((asc_dvc->cfg->termination & TERM_LVD) == 0)
-    {
-        /* LVD automatic termination control is enabled. */
-        switch(scsi_cfg1 & C_DET_LVD)
-        {
-            /* TERM_LVD_HI: on, TERM_LVD_LO: on */
-            case 0x4: case 0x8: case 0xC:
-                asc_dvc->cfg->termination |= TERM_LVD;
-                break;
-
-            /* TERM_LVD_HI: off, TERM_LVD_LO: off */
             case 0x0:
+                if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0)
+                {
+                    /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
+                }
+                else
+                {
+                    /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
+                    asc_dvc->cfg->termination |= TERM_SE_HI;
+                }
                 break;
         }
     }
 
     /*
-     * Clear any set TERM_SE and TERM_LVD bits.
+     * Clear any set TERM_SE bits.
      */
-    scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
+    scsi_cfg1 &= ~TERM_SE;
 
     /*
-     * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
+     * Invert the TERM_SE bits and then set 'scsi_cfg1'.
      */
-    scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
+    scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
 
     /*
-     * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
-     * and set possibly modified termination control bits in the Microcode
-     * SCSI_CFG1 Register Value.
+     * Clear Big Endian and Terminator Polarity bits and set possibly
+     * modified termination control bits in the Microcode SCSI_CFG1
+     * Register Value.
+     *
+     * Big Endian bit is not used even on big endian machines.
      */
-    scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
+    scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
 
     /*
      * Set SCSI_CFG1 Microcode Default Value
      *
-     * Set possibly modified termination control and reset DIS_TERM_DRV
-     * bits in the Microcode SCSI_CFG1 Register Value.
+     * Set possibly modified termination control bits in the Microcode
+     * SCSI_CFG1 Register Value.
      *
      * The microcode will set the SCSI_CFG1 register using this value
      * after it is started below.
@@ -16750,10 +16731,17 @@
      * MEM_CFG may be accessed as a word or byte, but only bits 0-7
      * are defined.
      *
-     * ASC-38C0800 has 16KB internal memory.
+     * ASC-38C1600 has 32KB internal memory.
+     *
+     * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
+     * out a special 16K Adv Library and Microcode version. After the issue
+     * resolved, we should turn back to the 32K support. Both a_condor.h and
+     * mcode.sas files also need to be updated.
+     *
+     * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
+     *  BIOS_EN | RAM_SZ_32KB);
      */
-    AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
-        BIOS_EN | RAM_SZ_16KB);
+     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, BIOS_EN | RAM_SZ_16KB);
 
     /*
      * Set SEL_MASK Microcode Default Value
@@ -16769,6 +16757,7 @@
      *
      * Driver must have already allocated memory and set 'carrier_buf'.
      */
+
     ASC_ASSERT(asc_dvc->carrier_buf != NULL);
 
     carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
@@ -16803,12 +16792,12 @@
         }
 
         carrp->carr_pa = carr_paddr;
-        carrp->carr_va = ADV_VADDR_TO_U32(carrp);
+        carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
 
         /*
          * Insert the carrier at the beginning of the freelist.
          */
-        carrp->next_vpa = ADV_VADDR_TO_U32(asc_dvc->carr_freelist);
+        carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
         asc_dvc->carr_freelist = carrp;
 
         carrp++;
@@ -16818,25 +16807,27 @@
     /*
      * Set-up the Host->RISC Initiator Command Queue (ICQ).
      */
-
     if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
     {
         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
         return ADV_ERROR;
     }
-    asc_dvc->carr_freelist =
-        (ADV_CARR_T *) ADV_U32_TO_VADDR(asc_dvc->icq_sp->next_vpa);
+    asc_dvc->carr_freelist = (ADV_CARR_T *)
+        ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
 
     /*
      * The first command issued will be placed in the stopper carrier.
      */
-    asc_dvc->icq_sp->next_vpa = ASC_CQ_STOPPER;
+    asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
 
     /*
-     * Set RISC ICQ physical address start value.
+     * Set RISC ICQ physical address start value. Initialize the
+     * COMMA register to the same value otherwise the RISC will
+     * prematurely detect a command is available.
      */
-    AdvWriteDWordLram(iop_base, ASC_MC_ICQ,
-        cpu_to_le32(asc_dvc->icq_sp->carr_pa));
+    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
+    AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
+        le32_to_cpu(asc_dvc->icq_sp->carr_pa));
 
     /*
      * Set-up the RISC->Host Initiator Response Queue (IRQ).
@@ -16846,8 +16837,8 @@
         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
         return ADV_ERROR;
     }
-    asc_dvc->carr_freelist =
-        (ADV_CARR_T *) ADV_U32_TO_VADDR(asc_dvc->irq_sp->next_vpa);
+    asc_dvc->carr_freelist = (ADV_CARR_T *)
+        ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
 
     /*
      * The first command completed by the RISC will be placed in
@@ -16856,22 +16847,16 @@
      * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
      * completed the RISC will set the ASC_RQ_STOPPER bit.
      */
-    asc_dvc->irq_sp->next_vpa = ASC_CQ_STOPPER;
+    asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
 
     /*
      * Set RISC IRQ physical address start value.
      */
-    AdvWriteDWordLram(iop_base, ASC_MC_IRQ,
-        cpu_to_le32(asc_dvc->irq_sp->carr_pa));
+    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
     asc_dvc->carr_pending_cnt = 0;
 
     AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
         (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
-    /*
-     * Note: Don't remove the use of a temporary variable in
-     * the following code, otherwise the Microsoft C compiler
-     * will turn the following lines into a no-op.
-     */
     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
     AdvWriteWordRegister(iop_base, IOPW_PC, word);
 
@@ -16887,8 +16872,7 @@
     {
         /*
          * If the BIOS Signature is present in memory, restore the
-         * BIOS Handshake Configuration Table and do not perform
-         * a SCSI Bus Reset.
+         * per TID microcode operating variables.
          */
         if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
         {
@@ -16897,8 +16881,9 @@
              */
             AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
             AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
+            AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
             AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
-            for (tid = 0; tid <= ADV_MAX_TID; tid++)
+            for (tid = 0; tid <= ASC_MAX_TID; tid++)
             {
                 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
                     max_cmd[tid]);
@@ -16945,8 +16930,6 @@
      * Read the board's EEPROM configuration.
      *
      * Set default values if a bad checksum is found.
-     *
-     * XXX - Don't handle big-endian access to EEPROM yet.
      */
     if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
     {
@@ -16967,13 +16950,13 @@
          * failed.
          */
         eep_config.serial_number_word3 =
-            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 1);
+            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
 
         eep_config.serial_number_word2 =
-            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 2);
+            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
 
         eep_config.serial_number_word1 =
-            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 3);
+            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
 
         AdvSet3550EEPConfig(iop_base, &eep_config);
     }
@@ -17049,7 +17032,211 @@
     asc_dvc->max_host_qng = eep_config.max_host_qng;
     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
 
-
+
+    /*
+     * If the EEPROM 'termination' field is set to automatic (0), then set
+     * the ADV_DVC_CFG 'termination' field to automatic also.
+     *
+     * If the termination is specified with a non-zero 'termination'
+     * value check that a legal value is set and set the ADV_DVC_CFG
+     * 'termination' field appropriately.
+     */
+    if (eep_config.termination == 0)
+    {
+        asc_dvc->cfg->termination = 0;    /* auto termination */
+    } else
+    {
+        /* Enable manual control with low off / high off. */
+        if (eep_config.termination == 1)
+        {
+            asc_dvc->cfg->termination = TERM_CTL_SEL;
+
+        /* Enable manual control with low off / high on. */
+        } else if (eep_config.termination == 2)
+        {
+            asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
+
+        /* Enable manual control with low on / high on. */
+        } else if (eep_config.termination == 3)
+        {
+            asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
+        } else
+        {
+            /*
+             * The EEPROM 'termination' field contains a bad value. Use
+             * automatic termination instead.
+             */
+            asc_dvc->cfg->termination = 0;
+            warn_code |= ASC_WARN_EEPROM_TERMINATION;
+        }
+    }
+
+    return warn_code;
+}
+
+/*
+ * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
+ * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
+ * all of this is done.
+ *
+ * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
+ *
+ * For a non-fatal error return a warning code. If there are no warnings
+ * then 0 is returned.
+ *
+ * Note: Chip is stopped on entry.
+ */
+ASC_INITFUNC(
+STATIC int,
+AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
+)
+{
+    AdvPortAddr              iop_base;
+    ushort                   warn_code;
+    ADVEEP_38C0800_CONFIG    eep_config;
+    int                      i;
+    uchar                    tid, termination;
+    ushort                   sdtr_speed = 0;
+
+    iop_base = asc_dvc->iop_base;
+
+    warn_code = 0;
+
+    /*
+     * Read the board's EEPROM configuration.
+     *
+     * Set default values if a bad checksum is found.
+     */
+    if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
+    {
+        warn_code |= ASC_WARN_EEPROM_CHKSUM;
+
+        /*
+         * Set EEPROM default values.
+         */
+        for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++)
+        {
+            *((uchar *) &eep_config + i) =
+                *((uchar *) &Default_38C0800_EEPROM_Config + i);
+        }
+
+        /*
+         * Assume the 6 byte board serial number that was read
+         * from EEPROM is correct even if the EEPROM checksum
+         * failed.
+         */
+        eep_config.serial_number_word3 =
+            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
+
+        eep_config.serial_number_word2 =
+            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
+
+        eep_config.serial_number_word1 =
+            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
+
+        AdvSet38C0800EEPConfig(iop_base, &eep_config);
+    }
+    /*
+     * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
+     * EEPROM configuration that was read.
+     *
+     * This is the mapping of EEPROM fields to Adv Library fields.
+     */
+    asc_dvc->wdtr_able = eep_config.wdtr_able;
+    asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
+    asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
+    asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
+    asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
+    asc_dvc->tagqng_able = eep_config.tagqng_able;
+    asc_dvc->cfg->disc_enable = eep_config.disc_enable;
+    asc_dvc->max_host_qng = eep_config.max_host_qng;
+    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
+    asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
+    asc_dvc->start_motor = eep_config.start_motor;
+    asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
+    asc_dvc->bios_ctrl = eep_config.bios_ctrl;
+    asc_dvc->no_scam = eep_config.scam_tolerant;
+    asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
+    asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
+    asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
+
+    /*
+     * For every Target ID if any of its 'sdtr_speed[1234]' bits
+     * are set, then set an 'sdtr_able' bit for it.
+     */
+    asc_dvc->sdtr_able = 0;
+    for (tid = 0; tid <= ADV_MAX_TID; tid++)
+    {
+        if (tid == 0)
+        {
+            sdtr_speed = asc_dvc->sdtr_speed1;
+        } else if (tid == 4)
+        {
+            sdtr_speed = asc_dvc->sdtr_speed2;
+        } else if (tid == 8)
+        {
+            sdtr_speed = asc_dvc->sdtr_speed3;
+        } else if (tid == 12)
+        {
+            sdtr_speed = asc_dvc->sdtr_speed4;
+        }
+        if (sdtr_speed & ADV_MAX_TID)
+        {
+            asc_dvc->sdtr_able |= (1 << tid);
+        }
+        sdtr_speed >>= 4;
+    }
+
+    /*
+     * Set the host maximum queuing (max. 253, min. 16) and the per device
+     * maximum queuing (max. 63, min. 4).
+     */
+    if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
+    {
+        eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
+    } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
+    {
+        /* If the value is zero, assume it is uninitialized. */
+        if (eep_config.max_host_qng == 0)
+        {
+            eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
+        } else
+        {
+            eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
+        }
+    }
+
+    if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
+    {
+        eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
+    } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
+    {
+        /* If the value is zero, assume it is uninitialized. */
+        if (eep_config.max_dvc_qng == 0)
+        {
+            eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
+        } else
+        {
+            eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
+        }
+    }
+
+    /*
+     * If 'max_dvc_qng' is greater than 'max_host_qng', then
+     * set 'max_dvc_qng' to 'max_host_qng'.
+     */
+    if (eep_config.max_dvc_qng > eep_config.max_host_qng)
+    {
+        eep_config.max_dvc_qng = eep_config.max_host_qng;
+    }
+
+    /*
+     * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
+     * values based on possibly adjusted EEPROM values.
+     */
+    asc_dvc->max_host_qng = eep_config.max_host_qng;
+    asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
+
     /*
      * If the EEPROM 'termination' field is set to automatic (0), then set
      * the ADV_DVC_CFG 'termination' field to automatic also.
@@ -17058,32 +17245,63 @@
      * value check that a legal value is set and set the ADV_DVC_CFG
      * 'termination' field appropriately.
      */
-    if (eep_config.termination == 0)
+    if (eep_config.termination_se == 0)
     {
-        asc_dvc->cfg->termination = 0;    /* auto termination */
+        termination = 0;                         /* auto termination for SE */
     } else
     {
         /* Enable manual control with low off / high off. */
-        if (eep_config.termination == 1)
+        if (eep_config.termination_se == 1)
         {
-            asc_dvc->cfg->termination = TERM_CTL_SEL;
+            termination = 0;
 
         /* Enable manual control with low off / high on. */
-        } else if (eep_config.termination == 2)
+        } else if (eep_config.termination_se == 2)
         {
-            asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
+            termination = TERM_SE_HI;
 
         /* Enable manual control with low on / high on. */
-        } else if (eep_config.termination == 3)
+        } else if (eep_config.termination_se == 3)
         {
-            asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
+            termination = TERM_SE;
         } else
         {
             /*
-             * The EEPROM 'termination' field contains a bad value. Use
-             * automatic termination instead.
+             * The EEPROM 'termination_se' field contains a bad value.
+             * Use automatic termination instead.
              */
-            asc_dvc->cfg->termination = 0;
+            termination = 0;
+            warn_code |= ASC_WARN_EEPROM_TERMINATION;
+        }
+    }
+
+    if (eep_config.termination_lvd == 0)
+    {
+        asc_dvc->cfg->termination = termination; /* auto termination for LVD */
+    } else
+    {
+        /* Enable manual control with low off / high off. */
+        if (eep_config.termination_lvd == 1)
+        {
+            asc_dvc->cfg->termination = termination;
+
+        /* Enable manual control with low off / high on. */
+        } else if (eep_config.termination_lvd == 2)
+        {
+            asc_dvc->cfg->termination = termination | TERM_LVD_HI;
+
+        /* Enable manual control with low on / high on. */
+        } else if (eep_config.termination_lvd == 3)
+        {
+            asc_dvc->cfg->termination =
+                termination | TERM_LVD;
+        } else
+        {
+            /*
+             * The EEPROM 'termination_lvd' field contains a bad value.
+             * Use automatic termination instead.
+             */
+            asc_dvc->cfg->termination = termination;
             warn_code |= ASC_WARN_EEPROM_TERMINATION;
         }
     }
@@ -17092,11 +17310,11 @@
 }
 
 /*
- * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
- * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
+ * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
+ * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
  * all of this is done.
  *
- * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
+ * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
  *
  * For a non-fatal error return a warning code. If there are no warnings
  * then 0 is returned.
@@ -17105,12 +17323,12 @@
  */
 ASC_INITFUNC(
 STATIC int,
-AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
+AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
 )
 {
     AdvPortAddr              iop_base;
     ushort                   warn_code;
-    ADVEEP_38C0800_CONFIG    eep_config;
+    ADVEEP_38C1600_CONFIG    eep_config;
     int                      i;
     uchar                    tid, termination;
     ushort                   sdtr_speed = 0;
@@ -17123,20 +17341,59 @@
      * Read the board's EEPROM configuration.
      *
      * Set default values if a bad checksum is found.
-     *
-     * XXX - Don't handle big-endian access to EEPROM yet.
      */
-    if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
+    if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
     {
         warn_code |= ASC_WARN_EEPROM_CHKSUM;
 
         /*
          * Set EEPROM default values.
          */
-        for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++)
+        for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++)
         {
-            *((uchar *) &eep_config + i) =
-                *((uchar *) &Default_38C0800_EEPROM_Config + i);
+            if (i == 1 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) != 0)
+            {
+                /*
+                 * Set Function 1 EEPROM Word 0 MSB
+                 *
+                 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
+                 * EEPROM bits.
+                 *
+                 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
+                 * old Mac system booting problem. The Expansion ROM must
+                 * be disabled in Function 1 for these systems.
+                 *
+                 */
+                *((uchar *) &eep_config + i) =
+                ((*((uchar *) &Default_38C1600_EEPROM_Config + i)) &
+                    (~(((ADV_EEPROM_BIOS_ENABLE | ADV_EEPROM_INTAB) >> 8) &
+                     0xFF)));
+
+                /*
+                 * Set the INTAB (bit 11) if the GPIO 0 input indicates
+                 * the Function 1 interrupt line is wired to INTA.
+                 *
+                 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
+                 *   1 - Function 1 interrupt line wired to INT A.
+                 *   0 - Function 1 interrupt line wired to INT B.
+                 *
+                 * Note: Adapter boards always have Function 0 wired to INTA.
+                 * Put all 5 GPIO bits in input mode and then read
+                 * their input values.
+                 */
+                AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
+                if (AdvReadByteRegister(iop_base, IOPB_GPIO_DATA) & 0x01)
+                {
+                    /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
+                *((uchar *) &eep_config + i) |=
+                    ((ADV_EEPROM_INTAB >> 8) & 0xFF);
+                }
+            }
+            else
+            {
+                *((uchar *) &eep_config + i) =
+                *((uchar *) &Default_38C1600_EEPROM_Config + i);
+            }
         }
 
         /*
@@ -17145,18 +17402,19 @@
          * failed.
          */
         eep_config.serial_number_word3 =
-            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 1);
+            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
 
         eep_config.serial_number_word2 =
-            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 2);
+            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
 
         eep_config.serial_number_word1 =
-            AdvReadEEPWord(iop_base, ASC_EEP_DVC_CFG_END - 3);
+            AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
 
-        AdvSet38C0800EEPConfig(iop_base, &eep_config);
+        AdvSet38C1600EEPConfig(iop_base, &eep_config);
     }
+
     /*
-     * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
+     * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
      * EEPROM configuration that was read.
      *
      * This is the mapping of EEPROM fields to Adv Library fields.
@@ -17166,25 +17424,23 @@
     asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
     asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
     asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
+    asc_dvc->ppr_able = 0;
     asc_dvc->tagqng_able = eep_config.tagqng_able;
     asc_dvc->cfg->disc_enable = eep_config.disc_enable;
     asc_dvc->max_host_qng = eep_config.max_host_qng;
     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
-    asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
+    asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
     asc_dvc->start_motor = eep_config.start_motor;
     asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
     asc_dvc->bios_ctrl = eep_config.bios_ctrl;
     asc_dvc->no_scam = eep_config.scam_tolerant;
-    asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
-    asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
-    asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
 
     /*
      * For every Target ID if any of its 'sdtr_speed[1234]' bits
      * are set, then set an 'sdtr_able' bit for it.
      */
     asc_dvc->sdtr_able = 0;
-    for (tid = 0; tid <= ADV_MAX_TID; tid++)
+    for (tid = 0; tid <= ASC_MAX_TID; tid++)
     {
         if (tid == 0)
         {
@@ -17199,7 +17455,7 @@
         {
             sdtr_speed = asc_dvc->sdtr_speed4;
         }
-        if (sdtr_speed & ADV_MAX_TID)
+        if (sdtr_speed & ASC_MAX_TID)
         {
             asc_dvc->sdtr_able |= (1 << tid);
         }
@@ -17250,7 +17506,7 @@
     }
 
     /*
-     * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
+     * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
      * values based on possibly adjusted EEPROM values.
      */
     asc_dvc->max_host_qng = eep_config.max_host_qng;
@@ -17258,10 +17514,10 @@
 
     /*
      * If the EEPROM 'termination' field is set to automatic (0), then set
-     * the ADV_DVC_CFG 'termination' field to automatic also.
+     * the ASC_DVC_CFG 'termination' field to automatic also.
      *
      * If the termination is specified with a non-zero 'termination'
-     * value check that a legal value is set and set the ADV_DVC_CFG
+     * value check that a legal value is set and set the ASC_DVC_CFG
      * 'termination' field appropriately.
      */
     if (eep_config.termination_se == 0)
@@ -17341,25 +17597,37 @@
     ushort              wval, chksum;
     ushort              *wbuf;
     int                 eep_addr;
+    ushort              *charfields;
 
+    charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
     wbuf = (ushort *) cfg_buf;
     chksum = 0;
 
-    for (eep_addr = ASC_EEP_DVC_CFG_BEGIN;
-         eep_addr < ASC_EEP_DVC_CFG_END;
+    for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
+         eep_addr < ADV_EEP_DVC_CFG_END;
          eep_addr++, wbuf++)
     {
         wval = AdvReadEEPWord(iop_base, eep_addr);
-        chksum += wval;
-        *wbuf = wval;
+        chksum += wval; /* Checksum is calculated from word values. */
+        if (*charfields++) {
+            *wbuf = le16_to_cpu(wval);
+        } else {
+            *wbuf = wval;
+        }
     }
+    /* Read checksum word. */
     *wbuf = AdvReadEEPWord(iop_base, eep_addr);
-    wbuf++;
-    for (eep_addr = ASC_EEP_DVC_CTL_BEGIN;
-         eep_addr < ASC_EEP_MAX_WORD_ADDR;
+    wbuf++; charfields++;
+
+    /* Read rest of EEPROM not covered by the checksum. */
+    for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
+         eep_addr < ADV_EEP_MAX_WORD_ADDR;
          eep_addr++, wbuf++)
     {
         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
+        if (*charfields++) {
+            *wbuf = le16_to_cpu(*wbuf);
+        }
     }
     return chksum;
 }
@@ -17378,29 +17646,89 @@
     ushort              wval, chksum;
     ushort              *wbuf;
     int                 eep_addr;
+    ushort              *charfields;
 
+    charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
     wbuf = (ushort *) cfg_buf;
     chksum = 0;
 
-    for (eep_addr = ASC_EEP_DVC_CFG_BEGIN;
-         eep_addr < ASC_EEP_DVC_CFG_END;
+    for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
+         eep_addr < ADV_EEP_DVC_CFG_END;
          eep_addr++, wbuf++)
     {
         wval = AdvReadEEPWord(iop_base, eep_addr);
-        chksum += wval;
-        *wbuf = wval;
+        chksum += wval; /* Checksum is calculated from word values. */
+        if (*charfields++) {
+            *wbuf = le16_to_cpu(wval);
+        } else {
+            *wbuf = wval;
+        }
     }
+    /* Read checksum word. */
     *wbuf = AdvReadEEPWord(iop_base, eep_addr);
-    wbuf++;
-    for (eep_addr = ASC_EEP_DVC_CTL_BEGIN;
-         eep_addr < ASC_EEP_MAX_WORD_ADDR;
+    wbuf++; charfields++;
+
+    /* Read rest of EEPROM not covered by the checksum. */
+    for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
+         eep_addr < ADV_EEP_MAX_WORD_ADDR;
          eep_addr++, wbuf++)
     {
         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
+        if (*charfields++) {
+            *wbuf = le16_to_cpu(*wbuf);
+        }
     }
     return chksum;
 }
 
+/*
+ * Read EEPROM configuration into the specified buffer.
+ *
+ * Return a checksum based on the EEPROM configuration read.
+ */
+ASC_INITFUNC(
+STATIC ushort,
+AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
+                       ADVEEP_38C1600_CONFIG *cfg_buf)
+)
+{
+    ushort              wval, chksum;
+    ushort              *wbuf;
+    int                 eep_addr;
+    ushort              *charfields;
+
+    charfields = (ushort*) &ADVEEP_38C1600_Config_Field_IsChar;
+    wbuf = (ushort *) cfg_buf;
+    chksum = 0;
+
+    for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
+         eep_addr < ADV_EEP_DVC_CFG_END;
+         eep_addr++, wbuf++)
+    {
+        wval = AdvReadEEPWord(iop_base, eep_addr);
+        chksum += wval; /* Checksum is calculated from word values. */
+        if (*charfields++) {
+            *wbuf = le16_to_cpu(wval);
+        } else {
+            *wbuf = wval;
+        }
+    }
+    /* Read checksum word. */
+    *wbuf = AdvReadEEPWord(iop_base, eep_addr);
+    wbuf++; charfields++;
+
+    /* Read rest of EEPROM not covered by the checksum. */
+    for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
+         eep_addr < ADV_EEP_MAX_WORD_ADDR;
+         eep_addr++, wbuf++)
+    {
+        *wbuf = AdvReadEEPWord(iop_base, eep_addr);
+        if (*charfields++) {
+            *wbuf = le16_to_cpu(*wbuf);
+        }
+    }
+    return chksum;
+}
 
 /*
  * Read the EEPROM from specified location
@@ -17426,7 +17754,7 @@
 {
     int eep_delay_ms;
 
-    for (eep_delay_ms = 0; eep_delay_ms < ASC_EEP_DELAY_MS; eep_delay_ms++)
+    for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++)
     {
         if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
         {
@@ -17449,41 +17777,57 @@
 {
     ushort *wbuf;
     ushort addr, chksum;
+    ushort *charfields;
 
     wbuf = (ushort *) cfg_buf;
+    charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
     chksum = 0;
 
     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
     AdvWaitEEPCmd(iop_base);
 
     /*
-     * Write EEPROM from word 0 to word 20
+     * Write EEPROM from word 0 to word 20.
      */
-    for (addr = ASC_EEP_DVC_CFG_BEGIN;
-         addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++)
+    for (addr = ADV_EEP_DVC_CFG_BEGIN;
+         addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
     {
-        chksum += *wbuf;
-        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
+        ushort word;
+
+        if (*charfields++) {
+            word = cpu_to_le16(*wbuf);
+        } else {
+            word = *wbuf;
+        }
+        chksum += *wbuf; /* Checksum is calculated from word values. */
+        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
         AdvWaitEEPCmd(iop_base);
-        DvcSleepMilliSecond(ASC_EEP_DELAY_MS);
+        DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
     }
 
     /*
-     * Write EEPROM checksum at word 21
+     * Write EEPROM checksum at word 21.
      */
     AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
     AdvWaitEEPCmd(iop_base);
-    wbuf++;        /* skip over check_sum */
+    wbuf++; charfields++;
 
     /*
-     * Write EEPROM OEM name at words 22 to 29
+     * Write EEPROM OEM name at words 22 to 29.
      */
-    for (addr = ASC_EEP_DVC_CTL_BEGIN;
-         addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++)
+    for (addr = ADV_EEP_DVC_CTL_BEGIN;
+         addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
     {
-        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
+        ushort word;
+
+        if (*charfields++) {
+            word = cpu_to_le16(*wbuf);
+        } else {
+            word = *wbuf;
+        }
+        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
         AdvWaitEEPCmd(iop_base);
     }
@@ -17500,42 +17844,126 @@
                        ADVEEP_38C0800_CONFIG *cfg_buf)
 {
     ushort *wbuf;
+    ushort *charfields;
     ushort addr, chksum;
 
     wbuf = (ushort *) cfg_buf;
+    charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
+    chksum = 0;
+
+    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
+    AdvWaitEEPCmd(iop_base);
+
+    /*
+     * Write EEPROM from word 0 to word 20.
+     */
+    for (addr = ADV_EEP_DVC_CFG_BEGIN;
+         addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
+    {
+        ushort word;
+
+        if (*charfields++) {
+            word = cpu_to_le16(*wbuf);
+        } else {
+            word = *wbuf;
+        }
+        chksum += *wbuf; /* Checksum is calculated from word values. */
+        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
+        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
+        AdvWaitEEPCmd(iop_base);
+        DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
+    }
+
+    /*
+     * Write EEPROM checksum at word 21.
+     */
+    AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
+    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
+    AdvWaitEEPCmd(iop_base);
+    wbuf++; charfields++;
+
+    /*
+     * Write EEPROM OEM name at words 22 to 29.
+     */
+    for (addr = ADV_EEP_DVC_CTL_BEGIN;
+         addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
+    {
+        ushort word;
+
+        if (*charfields++) {
+            word = cpu_to_le16(*wbuf);
+        } else {
+            word = *wbuf;
+        }
+        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
+        AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
+        AdvWaitEEPCmd(iop_base);
+    }
+    AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
+    AdvWaitEEPCmd(iop_base);
+    return;
+}
+
+/*
+ * Write the EEPROM from 'cfg_buf'.
+ */
+void
+AdvSet38C1600EEPConfig(AdvPortAddr iop_base,
+                       ADVEEP_38C1600_CONFIG *cfg_buf)
+{
+    ushort              *wbuf;
+    ushort              *charfields;
+    ushort              addr, chksum;
+
+    wbuf = (ushort *) cfg_buf;
+    charfields = (ushort *) &ADVEEP_38C1600_Config_Field_IsChar;
     chksum = 0;
 
     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
     AdvWaitEEPCmd(iop_base);
 
     /*
-     * Write EEPROM from word 0 to word 20
+     * Write EEPROM from word 0 to word 20.
      */
-    for (addr = ASC_EEP_DVC_CFG_BEGIN;
-         addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++)
+    for (addr = ADV_EEP_DVC_CFG_BEGIN;
+         addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
     {
-        chksum += *wbuf;
-        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
+        ushort word;
+
+        if (*charfields++) {
+            word = cpu_to_le16(*wbuf);
+        } else {
+            word = *wbuf;
+        }
+        chksum += *wbuf; /* Checksum is calculated from word values. */
+        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
         AdvWaitEEPCmd(iop_base);
-        DvcSleepMilliSecond(ASC_EEP_DELAY_MS);
+        DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
     }
 
     /*
-     * Write EEPROM checksum at word 21
+     * Write EEPROM checksum at word 21.
      */
     AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
     AdvWaitEEPCmd(iop_base);
-    wbuf++;        /* skip over check_sum */
+    wbuf++; charfields++;
 
     /*
-     * Write EEPROM OEM name at words 22 to 29
+     * Write EEPROM OEM name at words 22 to 29.
      */
-    for (addr = ASC_EEP_DVC_CTL_BEGIN;
-         addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++)
+    for (addr = ADV_EEP_DVC_CTL_BEGIN;
+         addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
     {
-        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, *wbuf);
+        ushort word;
+
+        if (*charfields++) {
+            word = cpu_to_le16(*wbuf);
+        } else {
+            word = *wbuf;
+        }
+        AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
         AdvWaitEEPCmd(iop_base);
     }
@@ -17570,7 +17998,7 @@
 AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
                 ADV_SCSI_REQ_Q *scsiq)
 {
-    int                    last_int_level;
+    ulong                  last_int_level;
     AdvPortAddr            iop_base;
     ADV_DCNT               req_size;
     ADV_PADDR              req_paddr;
@@ -17598,10 +18026,11 @@
      */
     if ((new_carrp = asc_dvc->carr_freelist) == NULL)
     {
+       DvcLeaveCritical(last_int_level);
        return ADV_BUSY;
     }
-    asc_dvc->carr_freelist =
-        (ADV_CARR_T *) ADV_U32_TO_VADDR(new_carrp->next_vpa);
+    asc_dvc->carr_freelist = (ADV_CARR_T *)
+        ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
     asc_dvc->carr_pending_cnt++;
 
     /*
@@ -17609,7 +18038,7 @@
      * to the stopper value. The current stopper will be changed
      * below to point to the new stopper.
      */
-    new_carrp->next_vpa = ASC_CQ_STOPPER;
+    new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
 
     /*
      * Clear the ADV_SCSI_REQ_Q done flag.
@@ -17617,17 +18046,20 @@
     scsiq->a_flag &= ~ADV_SCSIQ_DONE;
 
     req_size = sizeof(ADV_SCSI_REQ_Q);
-    req_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, scsiq, (uchar *) scsiq,
-        (ADV_SDCNT *) &req_size, ADV_IS_SCSIQ_FLAG));
+    req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *) scsiq,
+        (ADV_SDCNT *) &req_size, ADV_IS_SCSIQ_FLAG);
 
-    ASC_ASSERT(ADV_DWALIGN(req_paddr) == req_paddr);
+    ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
     ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
 
+    /* Wait for assertion before making little-endian */
+    req_paddr = cpu_to_le32(req_paddr);
+
     /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
-    scsiq->scsiq_ptr = ADV_VADDR_TO_U32(scsiq);
+    scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
     scsiq->scsiq_rptr = req_paddr;
 
-    scsiq->carr_va = ADV_VADDR_TO_U32(asc_dvc->icq_sp);
+    scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
     /*
      * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
      * order during initialization.
@@ -17653,18 +18085,30 @@
      */
     asc_dvc->icq_sp = new_carrp;
 
-    /*
-     * Tickle the RISC to tell it to read its Command Queue Head pointer.
-     */
-    AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
-    if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
+    if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
+        asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
     {
         /*
-         * Clear the tickle value. In the ASC-3550 the RISC flag
-         * command 'clr_tickle_a' does not work unless the host
-         * value is cleared.
+         * Tickle the RISC to tell it to read its Command Queue Head pointer.
          */
-        AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
+        AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
+        if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
+        {
+            /*
+             * Clear the tickle value. In the ASC-3550 the RISC flag
+             * command 'clr_tickle_a' does not work unless the host
+             * value is cleared.
+             */
+            AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
+        }
+    } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
+    {
+        /*
+         * Notify the RISC a carrier is ready by writing the physical
+         * address of the new carrier stopper to the COMMA register.
+         */
+        AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
+                le32_to_cpu(new_carrp->carr_pa));
     }
 
     DvcLeaveCritical(last_int_level);
@@ -17731,6 +18175,7 @@
 {
     int         status;
     ushort      wdtr_able, sdtr_able, tagqng_able;
+    ushort      ppr_able = 0;
     uchar       tid, max_cmd[ADV_MAX_TID + 1];
     AdvPortAddr iop_base;
     ushort      bios_sig;
@@ -17742,6 +18187,10 @@
      */
     AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
+    if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
+    {
+        AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
+    }
     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
     for (tid = 0; tid <= ADV_MAX_TID; tid++)
     {
@@ -17771,7 +18220,11 @@
      * re-initializing the chip.
      */
     asc_dvc->err_code = 0;
-    if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
+    if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
+    {
+        status = AdvInitAsc38C1600Driver(asc_dvc);
+    }
+    else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
     {
         status = AdvInitAsc38C0800Driver(asc_dvc);
     } else
@@ -17798,6 +18251,10 @@
      */
     AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
     AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
+    if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
+    {
+        AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
+    }
     AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
     for (tid = 0; tid <= ADV_MAX_TID; tid++)
     {
@@ -17848,6 +18305,7 @@
     if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
          ADV_INTR_STATUS_INTRC)) == 0)
     {
+        DvcLeaveCritical(flags);
         return ADV_FALSE;
     }
 
@@ -17861,13 +18319,18 @@
         uchar intrb_code;
 
         AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
-        if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
-            asc_dvc->carr_pending_cnt != 0)
+
+        if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
+            asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
         {
-            AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
-            if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
+            if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
+                asc_dvc->carr_pending_cnt != 0)
             {
-                AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
+                AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
+                if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
+                {
+                    AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
+                }
             }
         }
 
@@ -17880,7 +18343,8 @@
     /*
      * Check if the IRQ stopper carrier contains a completed request.
      */
-    while (((irq_next_vpa = asc_dvc->irq_sp->next_vpa) & ASC_RQ_DONE) != 0)
+    while (((irq_next_vpa =
+             le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0)
     {
         /*
          * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
@@ -17891,7 +18355,20 @@
          * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
          * in AdvExeScsiQueue().
          */
-        scsiq = (ADV_SCSI_REQ_Q *) ADV_U32_TO_VADDR(asc_dvc->irq_sp->areq_vpa);
+        scsiq = (ADV_SCSI_REQ_Q *)
+            ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
+
+        /*
+         * Request finished with good status and the queue was not
+         * DMAed to host memory by the firmware. Set all status fields
+         * to indicate good status.
+         */
+        if ((irq_next_vpa & ASC_RQ_GOOD) != 0)
+        {
+            scsiq->done_status = QD_NO_ERROR;
+            scsiq->host_status = scsiq->scsi_status = 0;
+            scsiq->data_cnt = 0L;
+        }
 
         /*
          * Advance the stopper pointer to the next carrier
@@ -17902,7 +18379,8 @@
         asc_dvc->irq_sp = (ADV_CARR_T *)
             ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
 
-        free_carrp->next_vpa = ADV_VADDR_TO_U32(asc_dvc->carr_freelist);
+        free_carrp->next_vpa =
+                cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
         asc_dvc->carr_freelist = free_carrp;
         asc_dvc->carr_pending_cnt--;
 
@@ -17914,23 +18392,20 @@
          */
         scsiq->cntl = 0;
 
-#if __BIG_ENDIAN
-        /*
-         * After the request completes the only field in the ASC_SCSI_REQ_Q
-         * structure needs to be byte swapped from little endian order to
-         * big endian order is the residual data count.
-         */
-        scsiqp->data_cnt = le32_to_cpu(scsiqp->data_cnt);
-#endif /* __BIG_ENDIAN */
-
         /*
          * If the command that completed was a SCSI INQUIRY and
          * LUN 0 was sent the command, then process the INQUIRY
          * command information for the device.
+         *
+         * Note: If data returned were either VPD or CmdDt data,
+         * don't process the INQUIRY command information for
+         * the device, otherwise may erroneously set *_able bits.
          */
         if (scsiq->done_status == QD_NO_ERROR &&
             scsiq->cdb[0] == SCSICMD_Inquiry &&
-            scsiq->target_lun == 0)
+            scsiq->target_lun == 0 &&
+            (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
+                == ADV_INQ_RTN_STD_INQUIRY_DATA)
         {
             AdvInquiryHandling(asc_dvc, scsiq);
         }
@@ -17982,7 +18457,7 @@
                ushort idle_cmd,
                ADV_DCNT idle_cmd_parameter)
 {
-    int         last_int_level;
+    ulong       last_int_level;
     int         result;
     ADV_DCNT    i, j;
     AdvPortAddr iop_base;
@@ -18005,8 +18480,8 @@
      * followed, the microcode may process the idle command before the
      * parameters have been written to LRAM.
      */
-    AdvWriteDWordLram(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
-        idle_cmd_parameter);
+    AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
+        cpu_to_le32(idle_cmd_parameter));
     AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
 
     /*
@@ -18072,7 +18547,8 @@
      * microcode to the transfer residual count.
      */
 
-    if (scsiq->cdb[4] < 8 || (scsiq->cdb[4] - scsiq->data_cnt) < 8)
+    if (scsiq->cdb[4] < 8 ||
+        (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8)
     {
         return;
     }
@@ -18085,7 +18561,7 @@
     /*
      * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
      */
-    if (inq->rsp_data_fmt < 2 && inq->ansi_apr_ver < 2)
+    if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2)
     {
         return;
     } else
@@ -18109,7 +18585,7 @@
          * device's 'wdtr_able' bit and write the new value to the
          * microcode.
          */
-        if ((asc_dvc->wdtr_able & tidmask) && inq->WBus16)
+        if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq))
         {
             AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
             if ((cfg_word & tidmask) == 0)
@@ -18140,7 +18616,7 @@
          * supports synchronous transfers, then turn on the device's
          * 'sdtr_able' bit. Write the new value to the microcode.
          */
-        if ((asc_dvc->sdtr_able & tidmask) && inq->Sync)
+        if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq))
         {
             AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
             if ((cfg_word & tidmask) == 0)
@@ -18158,6 +18634,29 @@
                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
             }
         }
+        /*
+         * If the Inquiry data included enough space for the SPI-3
+         * Clocking field, then check if DT mode is supported.
+         */
+        if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
+            (scsiq->cdb[4] >= 57 ||
+            (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57))
+        {
+            /*
+             * PPR (Parallel Protocol Request) Capable
+             *
+             * If the device supports DT mode, then it must be PPR capable.
+             * The PPR message will be used in place of the SDTR and WDTR
+             * messages to negotiate synchronous speed and offset, transfer
+             * width, and protocol options.
+             */
+            if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY)
+            {
+                AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
+                asc_dvc->ppr_able |= tidmask;
+                AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
+            }
+        }
 
         /*
          * If the EEPROM enabled Tag Queuing for the device and the
@@ -18171,7 +18670,7 @@
          * disabling Tag Queuing in the BIOS devices with Tag Queuing
          * bugs will at least work with the BIOS.
          */
-        if ((asc_dvc->tagqng_able & tidmask) && inq->CmdQue)
+        if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq))
         {
             AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
             cfg_word |= tidmask;
diff -u --recursive --new-file v2.4.3/linux/drivers/scsi/advansys.h linux/drivers/scsi/advansys.h
--- v2.4.3/linux/drivers/scsi/advansys.h	Mon Dec 11 13:18:51 2000
+++ linux/drivers/scsi/advansys.h	Fri Apr  6 10:51:19 2001
@@ -1,9 +1,8 @@
-/* $Id: advansys.h,v 1.18 1999/11/29 21:47:16 bobf Exp bobf $ */
-
 /*
  * advansys.h - Linux Host Driver for AdvanSys SCSI Adapters
  * 
- * Copyright (c) 1995-1998 Advanced System Products, Inc.
+ * Copyright (c) 1995-2000 Advanced System Products, Inc.
+ * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
  * All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -11,49 +10,56 @@
  * code retain the above copyright notice and this comment without
  * modification.
  *
+ * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
+ * changed its name to ConnectCom Solutions, Inc.
+ *
  * There is an AdvanSys Linux WWW page at:
+ *  http://www.connectcom.net/downloads/software/os/linux.html
  *  http://www.advansys.com/linux.html
  *
- * The latest version of the AdvanSys driver is available at:
- *  ftp://ftp.advansys.com/pub/linux
+ * The latest released version of the AdvanSys driver is available at:
+ *  ftp://ftp.advansys.com/pub/linux/linux.tgz
+ *  ftp://ftp.connectcom.net/pub/linux/linux.tgz
  *
  * Please send questions, comments, bug reports to:
- *  bobf@advansys.com (Bob Frey)
+ *  linux@connectcom.net or bfrey@turbolinux.com.cn
  */
 
 #ifndef _ADVANSYS_H
 #define _ADVANSYS_H
 
-/* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
-#define ASC_LINUX_VERSION(V, P, S)    (((V) * 65536) + ((P) * 256) + (S))
-
 #ifndef LINUX_VERSION_CODE
 #include <linux/version.h>
 #endif /* LINUX_VERSION_CODE */
 
+/* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
+#define ASC_LINUX_VERSION(V, P, S)    (((V) * 65536) + ((P) * 256) + (S))
+/* Driver supported only in version 2.2 and version >= 2.4. */
+#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,2,0) || \
+    (LINUX_VERSION_CODE > ASC_LINUX_VERSION(2,3,0) && \
+     LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
+#error "AdvanSys driver supported only in 2.2 and 2.4 or greater kernels."
+#endif
+#define ASC_LINUX_KERNEL22 (LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
+#define ASC_LINUX_KERNEL24 (LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,4,0))
+
 /*
  * Scsi_Host_Template function prototypes.
  */
 int advansys_detect(Scsi_Host_Template *);
 int advansys_release(struct Scsi_Host *);
 const char *advansys_info(struct Scsi_Host *);
-int advansys_command(Scsi_Cmnd *);
 int advansys_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
-int advansys_abort(Scsi_Cmnd *);
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89)
 int advansys_reset(Scsi_Cmnd *);
-#else /* version >= v1.3.89 */
-int advansys_reset(Scsi_Cmnd *, unsigned int);
-#endif /* version >= v1.3.89 */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
-int advansys_biosparam(Disk *, int, int[]);
-#else /* version >= v1.3.0 */
 int advansys_biosparam(Disk *, kdev_t, int[]);
+#ifdef CONFIG_PROC_FS
 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,28)
 extern struct proc_dir_entry proc_scsi_advansys;
 #endif /* version < v2.3.28 */
 int advansys_proc_info(char *, char **, off_t, int, int, int);
-#endif /* version >= v1.3.0 */
+#else /* !defined(CONFIG_PROC_FS) */
+#define advansys_proc_info      NULL
+#endif /* !defined(CONFIG_PROC_FS) */
 
 /* init/main.c setup function */
 void advansys_setup(char *, int *);
@@ -61,108 +67,24 @@
 /*
  * AdvanSys Host Driver Scsi_Host_Template (struct SHT) from hosts.h.
  */
-#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0)
-#define ADVANSYS { \
-    NULL,                     /* struct SHT *next */ \
-    NULL,                     /* int *usage_count */ \
-    "advansys",               /* char *name */ \
-    advansys_detect,          /* int (*detect)(struct SHT *) */ \
-    advansys_release,         /* int (*release)(struct Scsi_Host *) */ \
-    advansys_info,            /* const char *(*info)(struct Scsi_Host *) */ \
-    advansys_command,         /* int (*command)(Scsi_Cmnd *) */ \
-    advansys_queuecommand, \
-            /* int (*queuecommand)(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)) */ \
-    advansys_abort,           /* int (*abort)(Scsi_Cmnd *) */ \
-    advansys_reset,           /* int (*reset)(Scsi_Cmnd *) */ \
-    NULL,                     /* int (*slave_attach)(int, int) */ \
-    advansys_biosparam,       /* int (* bios_param)(Disk *, int, int []) */ \
-    /* \
-     * The following fields are set per adapter in advansys_detect(). \
-     */ \
-    0,                        /* int can_queue */ \
-    0,                        /* int this_id */ \
-    0,                        /* short unsigned int sg_tablesize */ \
-    0,                        /* short cmd_per_lun */ \
-    0,                        /* unsigned char present */    \
-    /* \
-     * Because the driver may control an ISA adapter 'unchecked_isa_dma' \
-     * must be set. The flag will be cleared in advansys_detect for non-ISA \
-     * adapters. Refer to the comment in scsi_module.c for more information. \
-     */ \
-    1,                        /* unsigned unchecked_isa_dma:1 */ \
-    /* \
-     * All adapters controlled by this driver are capable of large \
-     * scatter-gather lists. According to the mid-level SCSI documentation \
-     * this obviates any performance gain provided by setting \
-     * 'use_clustering'. But empirically while CPU utilization is increased \
-     * by enabling clustering, I/O throughput increases as well. \
-     */ \
-    ENABLE_CLUSTERING,        /* unsigned use_clustering:1 */ \
-}
-#elif LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,75)
-#define ADVANSYS { \
-    NULL,                    /* struct SHT *next */ \
-    NULL, \
-        /* version < v2.1.23 long *usage_count */ \
-        /* version >= v2.1.23 struct module * */ \
-    &proc_scsi_advansys,     /* struct proc_dir_entry *proc_dir */ \
-    advansys_proc_info,    \
-        /* int (*proc_info)(char *, char **, off_t, int, int, int) */ \
-    "advansys",              /* const char *name */ \
-    advansys_detect,         /* int (*detect)(struct SHT *) */ \
-    advansys_release,        /* int (*release)(struct Scsi_Host *) */ \
-    advansys_info,           /* const char *(*info)(struct Scsi_Host *) */ \
-    advansys_command,        /* int (*command)(Scsi_Cmnd *) */ \
-    advansys_queuecommand, \
-        /* int (*queuecommand)(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)) */ \
-    advansys_abort,          /* int (*abort)(Scsi_Cmnd *) */ \
-    advansys_reset, \
-        /* version < v1.3.89 int (*reset)(Scsi_Cmnd *) */ \
-        /* version >= v1.3.89 int (*reset)(Scsi_Cmnd *, unsigned int) */ \
-    NULL,                    /* int (*slave_attach)(int, int) */ \
-    advansys_biosparam,      /* int (* bios_param)(Disk *, kdev_t, int []) */ \
-    /* \
-     * The following fields are set per adapter in advansys_detect(). \
-     */ \
-    0,                        /* int can_queue */ \
-    0,                        /* int this_id */ \
-    0,                        /* short unsigned int sg_tablesize */ \
-    0,                        /* short cmd_per_lun */ \
-    0,                        /* unsigned char present */    \
-    /* \
-     * Because the driver may control an ISA adapter 'unchecked_isa_dma' \
-     * must be set. The flag will be cleared in advansys_detect for non-ISA \
-     * adapters. Refer to the comment in scsi_module.c for more information. \
-     */ \
-    1,                        /* unsigned unchecked_isa_dma:1 */ \
-    /* \
-     * All adapters controlled by this driver are capable of large \
-     * scatter-gather lists. According to the mid-level SCSI documentation \
-     * this obviates any performance gain provided by setting \
-     * 'use_clustering'. But empirically while CPU utilization is increased \
-     * by enabling clustering, I/O throughput increases as well. \
-     */ \
-    ENABLE_CLUSTERING,        /* unsigned use_clustering:1 */ \
-}
-#elif LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,3,28)
+#if ASC_LINUX_KERNEL24
 #define ADVANSYS { \
-    proc_dir:     &proc_scsi_advansys, \
-    proc_info:    advansys_proc_info, \
-    name:         "advansys", \
-    detect:       advansys_detect, \
-    release:      advansys_release, \
-    info:         advansys_info, \
-    command:      advansys_command, \
-    queuecommand: advansys_queuecommand, \
-    abort:        advansys_abort, \
-    reset:        advansys_reset, \
-    bios_param:   advansys_biosparam, \
+    proc_name:                  "advansys", \
+    proc_info:                  advansys_proc_info, \
+    name:                       "advansys", \
+    detect:                     advansys_detect, \
+    release:                    advansys_release, \
+    info:                       advansys_info, \
+    queuecommand:               advansys_queuecommand, \
+    use_new_eh_code:		1, \
+    eh_bus_reset_handler:	advansys_reset, \
+    bios_param:                 advansys_biosparam, \
     /* \
      * Because the driver may control an ISA adapter 'unchecked_isa_dma' \
      * must be set. The flag will be cleared in advansys_detect for non-ISA \
      * adapters. Refer to the comment in scsi_module.c for more information. \
      */ \
-    unchecked_isa_dma: 1, \
+    unchecked_isa_dma:          1, \
     /* \
      * All adapters controlled by this driver are capable of large \
      * scatter-gather lists. According to the mid-level SCSI documentation \
@@ -170,27 +92,25 @@
      * 'use_clustering'. But empirically while CPU utilization is increased \
      * by enabling clustering, I/O throughput increases as well. \
      */ \
-    use_clustering: ENABLE_CLUSTERING, \
+    use_clustering:             ENABLE_CLUSTERING, \
 }
-#else /* version >= v2.3.28 */
+#elif ASC_LINUX_KERNEL22
 #define ADVANSYS { \
-    proc_name:    "advansys", \
-    proc_info:    advansys_proc_info, \
-    name:         "advansys", \
-    detect:       advansys_detect, \
-    release:      advansys_release, \
-    info:         advansys_info, \
-    command:      advansys_command, \
-    queuecommand: advansys_queuecommand, \
-    abort:        advansys_abort, \
-    reset:        advansys_reset, \
-    bios_param:   advansys_biosparam, \
+    proc_info:                  advansys_proc_info, \
+    name:                       "advansys", \
+    detect:                     advansys_detect, \
+    release:                    advansys_release, \
+    info:                       advansys_info, \
+    queuecommand:               advansys_queuecommand, \
+    use_new_eh_code:		1, \
+    eh_bus_reset_handler:	advansys_reset, \
+    bios_param:                 advansys_biosparam, \
     /* \
      * Because the driver may control an ISA adapter 'unchecked_isa_dma' \
      * must be set. The flag will be cleared in advansys_detect for non-ISA \
      * adapters. Refer to the comment in scsi_module.c for more information. \
      */ \
-    unchecked_isa_dma: 1, \
+    unchecked_isa_dma:          1, \
     /* \
      * All adapters controlled by this driver are capable of large \
      * scatter-gather lists. According to the mid-level SCSI documentation \
@@ -198,7 +118,7 @@
      * 'use_clustering'. But empirically while CPU utilization is increased \
      * by enabling clustering, I/O throughput increases as well. \
      */ \
-    use_clustering: ENABLE_CLUSTERING, \
+    use_clustering:             ENABLE_CLUSTERING, \
 }
-#endif /* version >= v2.3.28 */
+#endif
 #endif /* _ADVANSYS_H */
diff -u --recursive --new-file v2.4.3/linux/drivers/scsi/aic7xxx_old/aic7xxx.reg linux/drivers/scsi/aic7xxx_old/aic7xxx.reg
--- v2.4.3/linux/drivers/scsi/aic7xxx_old/aic7xxx.reg	Sun Mar  4 14:30:19 2001
+++ linux/drivers/scsi/aic7xxx_old/aic7xxx.reg	Fri Apr  6 10:51:19 2001
@@ -14,7 +14,7 @@
  *    derived from this software without specific prior written permission.
  *
  * Where this Software is combined with software released under the terms of 
- * the GNU Public License ("GPL") and the terms of the GPL would require the 
+ * the GNU General Public License ("GPL") and the terms of the GPL would require the 
  * combined work to also be released under the terms of the GPL, the terms
  * and conditions of this License will apply in addition to those of the
  * GPL with the exception of any terms or conditions of this License that
diff -u --recursive --new-file v2.4.3/linux/drivers/scsi/aic7xxx_old/aic7xxx.seq linux/drivers/scsi/aic7xxx_old/aic7xxx.seq
--- v2.4.3/linux/drivers/scsi/aic7xxx_old/aic7xxx.seq	Sun Mar  4 14:30:19 2001
+++ linux/drivers/scsi/aic7xxx_old/aic7xxx.seq	Fri Apr  6 10:51:19 2001
@@ -14,7 +14,7 @@
  *    derived from this software without specific prior written permission.
  *
  * Where this Software is combined with software released under the terms of 
- * the GNU Public License (GPL) and the terms of the GPL would require the 
+ * the GNU General Public License (GPL) and the terms of the GPL would require the 
  * combined work to also be released under the terms of the GPL, the terms
  * and conditions of this License will apply in addition to those of the
  * GPL with the exception of any terms or conditions of this License that
diff -u --recursive --new-file v2.4.3/linux/drivers/scsi/aic7xxx_old/sequencer.h linux/drivers/scsi/aic7xxx_old/sequencer.h
--- v2.4.3/linux/drivers/scsi/aic7xxx_old/sequencer.h	Sun Mar  4 14:30:19 2001
+++ linux/drivers/scsi/aic7xxx_old/sequencer.h	Fri Apr  6 10:51:19 2001
@@ -15,7 +15,7 @@
  *    derived from this software without specific prior written permission.
  *
  * Where this Software is combined with software released under the terms of 
- * the GNU Public License ("GPL") and the terms of the GPL would require the 
+ * the GNU General Public License ("GPL") and the terms of the GPL would require the 
  * combined work to also be released under the terms of the GPL, the terms
  * and conditions of this License will apply in addition to those of the
  * GPL with the exception of any terms or conditions of this License that
diff -u --recursive --new-file v2.4.3/linux/drivers/scsi/aic7xxx_old.c linux/drivers/scsi/aic7xxx_old.c
--- v2.4.3/linux/drivers/scsi/aic7xxx_old.c	Sun Mar  4 14:30:19 2001
+++ linux/drivers/scsi/aic7xxx_old.c	Fri Apr  6 10:51:19 2001
@@ -55,7 +55,7 @@
  *    derived from this software without specific prior written permission.
  *
  * Where this Software is combined with software released under the terms of 
- * the GNU Public License ("GPL") and the terms of the GPL would require the 
+ * the GNU General Public License ("GPL") and the terms of the GPL would require the 
  * combined work to also be released under the terms of the GPL, the terms
  * and conditions of this License will apply in addition to those of the
  * GPL with the exception of any terms or conditions of this License that
diff -u --recursive --new-file v2.4.3/linux/drivers/scsi/qlogicfas.c linux/drivers/scsi/qlogicfas.c
--- v2.4.3/linux/drivers/scsi/qlogicfas.c	Mon Sep 18 13:36:25 2000
+++ linux/drivers/scsi/qlogicfas.c	Fri Apr  6 10:51:19 2001
@@ -23,7 +23,7 @@
    Functions as standalone, loadable, and PCMCIA driver, the latter from
    Dave Hinds' PCMCIA package.
 
-   Redistributable under terms of the GNU Public License
+   Redistributable under terms of the GNU General Public License
 
 */
 /*----------------------------------------------------------------*/
diff -u --recursive --new-file v2.4.3/linux/drivers/sound/ac97_codec.c linux/drivers/sound/ac97_codec.c
--- v2.4.3/linux/drivers/sound/ac97_codec.c	Thu Dec  7 00:21:37 2000
+++ linux/drivers/sound/ac97_codec.c	Fri Apr  6 10:51:19 2001
@@ -20,6 +20,16 @@
  *	along with this program; if not, write to the Free Software
  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
+ **************************************************************************
+ *
+ * The Intel Audio Codec '97 specification is available at the Intel
+ * audio homepage: http://developer.intel.com/ial/scalableplatforms/audio/
+ *
+ * The specification itself is currently available at:
+ * ftp://download.intel.com/ial/scalableplatforms/ac97r22.pdf
+ *
+ **************************************************************************
+ *
  * History
  * v0.4 Mar 15 2000 Ollie Lho
  *	dual codecs support verified with 4 channels output
@@ -49,41 +59,61 @@
 
 static int ac97_init_mixer(struct ac97_codec *codec);
 
-static int sigmatel_init(struct ac97_codec *codec);
+static int wolfson_init(struct ac97_codec * codec);
+static int tritech_init(struct ac97_codec * codec);
+static int tritech_maestro_init(struct ac97_codec * codec);
+static int sigmatel_9708_init(struct ac97_codec *codec);
+static int sigmatel_9721_init(struct ac97_codec *codec);
+static int sigmatel_9744_init(struct ac97_codec *codec);
 static int enable_eapd(struct ac97_codec *codec);
 
-#define arraysize(x)   (sizeof(x)/sizeof((x)[0]))
-
-static struct {
-	unsigned int id;
+/* sorted by vendor/device id */
+static const struct {
+	u32 id;
 	char *name;
 	int  (*init)  (struct ac97_codec *codec);
 } ac97_codec_ids[] = {
-	{0x414B4D00, "Asahi Kasei AK4540 rev 0", NULL},
-	{0x414B4D01, "Asahi Kasei AK4540 rev 1", NULL},
-	{0x41445340, "Analog Devices AD1881"  , NULL},
-	{0x41445360, "Analog Devices AD1885"  , enable_eapd},
-	{0x43525900, "Cirrus Logic CS4297"    , NULL},
-	{0x43525903, "Cirrus Logic CS4297"  ,	NULL},
-	{0x43525913, "Cirrus Logic CS4297A"   , NULL},
-	{0x43525923, "Cirrus Logic CS4298"    , NULL},
-	{0x4352592B, "Cirrus Logic CS4294"    , NULL},
-	{0x43525931, "Cirrus Logic CS4299"    , NULL},
-	{0x43525934, "Cirrus Logic CS4299"    , NULL},
-	{0x4e534331, "National Semiconductor LM4549" ,	NULL},
-	{0x53494c22, "Silicon Laboratory Si3036"     ,	NULL},
-	{0x53494c23, "Silicon Laboratory Si3038"     ,  NULL},
-	{0x83847600, "SigmaTel STAC????"      , NULL},
+	{0x41445303, "Analog Devices AD1819",	NULL},
+	{0x41445340, "Analog Devices AD1881",	NULL},
+	{0x41445348, "Analog Devices AD1881A",	NULL},
+	{0x41445460, "Analog Devices AD1885",	enable_eapd},
+	{0x414B4D00, "Asahi Kasei AK4540",	NULL},
+	{0x414B4D01, "Asahi Kasei AK4542",	NULL},
+	{0x414B4D02, "Asahi Kasei AK4543",	NULL},
+	{0x414C4710, "ALC200/200P",		NULL},
+	{0x43525900, "Cirrus Logic CS4297",	enable_eapd},
+	{0x43525903, "Cirrus Logic CS4297",	enable_eapd},
+	{0x43525913, "Cirrus Logic CS4297A rev A", enable_eapd},
+	{0x43525914, "Cirrus Logic CS4297A rev B", NULL},
+	{0x43525923, "Cirrus Logic CS4298",	NULL},
+	{0x4352592B, "Cirrus Logic CS4294",	NULL},
+	{0x4352592D, "Cirrus Logic CS4294",	NULL},
+	{0x43525931, "Cirrus Logic CS4299 rev A", NULL},
+	{0x43525933, "Cirrus Logic CS4299 rev C", NULL},
+	{0x43525934, "Cirrus Logic CS4299 rev D", NULL},
+	{0x45838308, "ESS Allegro ES1988",	NULL},
+	{0x49434511, "ICE1232",			NULL}, /* I hope --jk */
+	{0x4e534331, "National Semiconductor LM4549", NULL},
+	{0x53494c22, "Silicon Laboratory Si3036", NULL},
+	{0x53494c23, "Silicon Laboratory Si3038", NULL},
+	{0x545200FF, "TriTech TR?????",		tritech_maestro_init},
+	{0x54524102, "TriTech TR28022",		NULL},
+	{0x54524103, "TriTech TR28023",		NULL},
+	{0x54524106, "TriTech TR28026",		NULL},
+	{0x54524108, "TriTech TR28028",		tritech_init},
+	{0x54524123, "TriTech TR?????",		NULL},
+	{0x574D4C00, "Wolfson WM9704",		wolfson_init},
+	{0x574D4C03, "Wolfson WM9703/9704",	wolfson_init},
+	{0x574D4C04, "Wolfson WM9704 (quad)",	wolfson_init},
+	{0x83847600, "SigmaTel STAC????",	NULL},
 	{0x83847604, "SigmaTel STAC9701/3/4/5", NULL},
-	{0x83847605, "SigmaTel STAC9704"      , NULL},
-	{0x83847608, "SigmaTel STAC9708"      , NULL},
-	{0x83847609, "SigmaTel STAC9721/23"   , sigmatel_init},
-	{0x54524103, "TriTech TR?????"	      , NULL},
-	{0x54524106, "TriTech TR28026"        , NULL},
-	{0x54524108, "TriTech TR28028"        , NULL},
-	{0x54524123, "TriTech TR?????"	      , NULL},	
-	{0x574D4C00, "Wolfson WM9704"         , NULL},
-	{0x00000000, NULL, NULL}
+	{0x83847605, "SigmaTel STAC9704",	NULL},
+	{0x83847608, "SigmaTel STAC9708",	sigmatel_9708_init},
+	{0x83847609, "SigmaTel STAC9721/23",	sigmatel_9721_init},
+	{0x83847644, "SigmaTel STAC9744/45",	sigmatel_9744_init},
+	{0x83847656, "SigmaTel STAC9756/57",	sigmatel_9744_init},
+	{0x83847684, "SigmaTel STAC9783/84?",	NULL},
+	{0,}
 };
 
 static const char *ac97_stereo_enhancements[] =
@@ -175,10 +205,10 @@
 	AC97_REC_LINE,
 	AC97_REC_STEREO, /* combination of all enabled outputs..  */
 	AC97_REC_MONO,	      /*.. or the mono equivalent */
-	AC97_REC_PHONE	      
+	AC97_REC_PHONE
 };
 
-static unsigned int ac97_rm2oss[] = {
+static const unsigned int ac97_rm2oss[] = {
 	[AC97_REC_MIC] 	 = SOUND_MIXER_MIC,
 	[AC97_REC_CD] 	 = SOUND_MIXER_CD,
 	[AC97_REC_VIDEO] = SOUND_MIXER_VIDEO,
@@ -189,7 +219,7 @@
 };
 
 /* indexed by bit position */
-static unsigned int ac97_oss_rm[] = {
+static const unsigned int ac97_oss_rm[] = {
 	[SOUND_MIXER_MIC] 	= AC97_REC_MIC,
 	[SOUND_MIXER_CD] 	= AC97_REC_CD,
 	[SOUND_MIXER_VIDEO] 	= AC97_REC_VIDEO,
@@ -431,13 +461,13 @@
 		return 0;
 	}
 
-	if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
+	if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
 		return -EINVAL;
 
 	if (cmd == OSS_GETVERSION)
 		return put_user(SOUND_VERSION, (int *)arg);
 
-	if (_IOC_DIR(cmd) == _IOC_READ) {
+	if (_SIOC_DIR(cmd) == _SIOC_READ) {
 		switch (_IOC_NR(cmd)) {
 		case SOUND_MIXER_RECSRC: /* give them the current record source */
 			if (!codec->recmask_io) {
@@ -477,7 +507,7 @@
 		return put_user(val, (int *)arg);
 	}
 
-	if (_IOC_DIR(cmd) == (_IOC_WRITE|_IOC_READ)) {
+	if (_SIOC_DIR(cmd) == (_SIOC_WRITE|_SIOC_READ)) {
 		codec->modcnt++;
 		if (get_user(val, (int *)arg))
 			return -EFAULT;
@@ -640,7 +670,7 @@
 
 	id1 = codec->codec_read(codec, AC97_VENDOR_ID1);
 	id2 = codec->codec_read(codec, AC97_VENDOR_ID2);
-	for (i = 0; i < arraysize(ac97_codec_ids); i++) {
+	for (i = 0; i < ARRAY_SIZE(ac97_codec_ids); i++) {
 		if (ac97_codec_ids[i].id == ((id1 << 16) | id2)) {
 			codec->type = ac97_codec_ids[i].id;
 			codec->name = ac97_codec_ids[i].name;
@@ -691,7 +721,7 @@
 		codec->codec_init(codec);
 	}
 
-	/* initilize mixer channel volumes */
+	/* initialize mixer channel volumes */
 	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
 		struct mixer_defaults *md = &mixer_defaults[i];
 		if (md->mixer == -1) 
@@ -704,40 +734,151 @@
 	return 1;
 }
 
-static int sigmatel_init(struct ac97_codec * codec)
+#define AC97_SIGMATEL_ANALOG    0x6c	/* Analog Special */
+#define AC97_SIGMATEL_DAC2INVERT 0x6e
+#define AC97_SIGMATEL_BIAS1     0x70
+#define AC97_SIGMATEL_BIAS2     0x72
+#define AC97_SIGMATEL_MULTICHN  0x74	/* Multi-Channel programming */
+#define AC97_SIGMATEL_CIC1      0x76
+#define AC97_SIGMATEL_CIC2      0x78
+
+
+static int sigmatel_9708_init(struct ac97_codec * codec)
+{
+	u16 codec72, codec6c;
+
+	codec72 = codec->codec_read(codec, AC97_SIGMATEL_BIAS2) & 0x8000;
+	codec6c = codec->codec_read(codec, AC97_SIGMATEL_ANALOG);
+
+	if ((codec72==0) && (codec6c==0)) {
+		codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);
+		codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x1000);
+		codec->codec_write(codec, AC97_SIGMATEL_BIAS1, 0xabba);
+		codec->codec_write(codec, AC97_SIGMATEL_BIAS2, 0x0007);
+	} else if ((codec72==0x8000) && (codec6c==0)) {
+		codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);
+		codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x1001);
+		codec->codec_write(codec, AC97_SIGMATEL_DAC2INVERT, 0x0008);
+	} else if ((codec72==0x8000) && (codec6c==0x0080)) {
+		/* nothing */
+	}
+	codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x0000);
+	return 0;
+}
+
+
+static int sigmatel_9721_init(struct ac97_codec * codec)
 {
 	/* Only set up secondary codec */
 	if (codec->id == 0)
-		return 1;
+		return 0;
 
 	codec->codec_write(codec, AC97_SURROUND_MASTER, 0L);
 
 	/* initialize SigmaTel STAC9721/23 as secondary codec, decoding AC link
 	   sloc 3,4 = 0x01, slot 7,8 = 0x00, */
-	codec->codec_write(codec, 0x74, 0x00);
+	codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x00);
 
 	/* we don't have the crystal when we are on an AMR card, so use
 	   BIT_CLK as our clock source. Write the magic word ABBA and read
 	   back to enable register 0x78 */
-	codec->codec_write(codec, 0x76, 0xabba);
-	codec->codec_read(codec, 0x76);
+	codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);
+	codec->codec_read(codec, AC97_SIGMATEL_CIC1);
 
 	/* sync all the clocks*/
-	codec->codec_write(codec, 0x78, 0x3802);
+	codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x3802);
 
-	return 1;
+	return 0;
+}
+
+
+static int sigmatel_9744_init(struct ac97_codec * codec)
+{
+	// patch for SigmaTel
+	codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba);
+	codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x0000); // is this correct? --jk
+	codec->codec_write(codec, AC97_SIGMATEL_BIAS1, 0xabba);
+	codec->codec_write(codec, AC97_SIGMATEL_BIAS2, 0x0002);
+	codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x0000);
+	return 0;
+}
+
+
+static int wolfson_init(struct ac97_codec * codec)
+{
+	codec->codec_write(codec, 0x72, 0x0808);
+	codec->codec_write(codec, 0x74, 0x0808);
+
+	// patch for DVD noise
+	codec->codec_write(codec, 0x5a, 0x0200);
+
+	// init vol as PCM vol
+	codec->codec_write(codec, 0x70,
+		codec->codec_read(codec, AC97_PCMOUT_VOL));
+
+	codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000);
+	return 0;
+}
+
+
+static int tritech_init(struct ac97_codec * codec)
+{
+	codec->codec_write(codec, 0x26, 0x0300);
+	codec->codec_write(codec, 0x26, 0x0000);
+	codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000);
+	codec->codec_write(codec, AC97_RESERVED_3A, 0x0000);
+	return 0;
+}
+
+
+/* copied from drivers/sound/maestro.c */
+static int tritech_maestro_init(struct ac97_codec * codec)
+{
+	/* no idea what this does */
+	codec->codec_write(codec, 0x2A, 0x0001);
+	codec->codec_write(codec, 0x2C, 0x0000);
+	codec->codec_write(codec, 0x2C, 0XFFFF);
+	return 0;
 }
 
+
 /*
- *	Bring up an AD1885
+ *	External AMP management for EAPD using codecs
+ *	(CS4279A, AD1885, ...)
  */
- 
+
 static int enable_eapd(struct ac97_codec * codec)
 {
 	codec->codec_write(codec, AC97_POWER_CONTROL,
 		codec->codec_read(codec, AC97_POWER_CONTROL)|0x8000);
 	return 0;
 }
+
+
+/* copied from drivers/sound/maestro.c */
+#if 0  /* there has been 1 person on the planet with a pt101 that we
+        know of.  If they care, they can put this back in :) */
+static int pt101_init(struct ac97_codec * codec)
+{
+	printk(KERN_INFO "ac97_codec: PT101 Codec detected, initializing but _not_ installing mixer device.\n");
+	/* who knows.. */
+	codec->codec_write(codec, 0x2A, 0x0001);
+	codec->codec_write(codec, 0x2C, 0x0000);
+	codec->codec_write(codec, 0x2C, 0xFFFF);
+	codec->codec_write(codec, 0x10, 0x9F1F);
+	codec->codec_write(codec, 0x12, 0x0808);
+	codec->codec_write(codec, 0x14, 0x9F1F);
+	codec->codec_write(codec, 0x16, 0x9F1F);
+	codec->codec_write(codec, 0x18, 0x0404);
+	codec->codec_write(codec, 0x1A, 0x0000);
+	codec->codec_write(codec, 0x1C, 0x0000);
+	codec->codec_write(codec, 0x02, 0x0404);
+	codec->codec_write(codec, 0x04, 0x0808);
+	codec->codec_write(codec, 0x0C, 0x801F);
+	codec->codec_write(codec, 0x0E, 0x801F);
+	return 0;
+}
+#endif
 	
 
 EXPORT_SYMBOL(ac97_read_proc);
diff -u --recursive --new-file v2.4.3/linux/drivers/sound/cs4281/cs4281m.c linux/drivers/sound/cs4281/cs4281m.c
--- v2.4.3/linux/drivers/sound/cs4281/cs4281m.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/sound/cs4281/cs4281m.c	Fri Apr  6 10:51:19 2001
@@ -4289,6 +4289,11 @@
 	CS_DBGOUT(CS_FUNCTION | CS_INIT, 2,
 		  printk(KERN_INFO "cs4281: probe()+\n"));
 
+	if (pci_enable_device(pcidev)) {
+		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
+			 "cs4281: pci_enable_device() failed\n"));
+		return -1;
+	}
 	if (!RSRCISMEMORYREGION(pcidev, 0) ||
 	    !RSRCISMEMORYREGION(pcidev, 1)) {
 		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
@@ -4366,11 +4371,6 @@
 	s->magic = CS4281_MAGIC;
 	s->pcidev = pcidev;
 	s->irq = pcidev->irq;
-	if (pci_enable_device(pcidev)) {
-		CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
-			 "cs4281: pci_enable_device() failed\n"));
-		goto err_irq;
-	}
 	if (request_irq
 	    (s->irq, cs4281_interrupt, SA_SHIRQ, "Crystal CS4281", s)) {
 		CS_DBGOUT(CS_INIT | CS_ERROR, 1,
diff -u --recursive --new-file v2.4.3/linux/drivers/sound/i810_audio.c linux/drivers/sound/i810_audio.c
--- v2.4.3/linux/drivers/sound/i810_audio.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/sound/i810_audio.c	Fri Apr  6 10:51:19 2001
@@ -101,8 +101,11 @@
 #endif
 
 static int ftsodell=0;
+static int strict_clocking=0;
 static unsigned int clocking=48000;
 
+//#define DEBUG
+//#define DEBUG2
 
 #define ADC_RUNNING	1
 #define DAC_RUNNING	2
@@ -169,6 +172,7 @@
 #define DMA_INT_COMPLETE	(1<<3)  /* buffer read/write complete and ioc set */
 #define DMA_INT_LVI		(1<<2)  /* last valid done */
 #define DMA_INT_CELV		(1<<1)  /* last valid is current */
+#define DMA_INT_DCH		(1)	/* DMA Controller Halted (happens on LVI interrupts) */
 #define DMA_INT_MASK (DMA_INT_FIFO|DMA_INT_COMPLETE|DMA_INT_LVI)
 
 /* interrupts for the whole chip */
@@ -183,7 +187,7 @@
 #define INT_MASK (INT_SEC|INT_PRI|INT_MC|INT_PO|INT_PI|INT_MO|INT_NI|INT_GPI)
 
 
-#define DRIVER_VERSION "0.01"
+#define DRIVER_VERSION "0.02"
 
 /* magic numbers to protect our data structures */
 #define I810_CARD_MAGIC		0x5072696E /* "Prin" */
@@ -247,7 +251,7 @@
 	struct dmabuf {
 		/* wave sample stuff */
 		unsigned int rate;
-		unsigned char fmt, enable;
+		unsigned char fmt, enable, trigger;
 
 		/* hardware channel */
 		struct i810_channel *read_channel;
@@ -277,10 +281,9 @@
 		/* OSS stuff */
 		unsigned mapped:1;
 		unsigned ready:1;
-		unsigned endcleared:1;
 		unsigned update_flag;
-		unsigned ossfragshift;
-		int ossmaxfrags;
+		unsigned ossfragsize;
+		unsigned ossmaxfrags;
 		unsigned subdivision;
 	} dmabuf;
 };
@@ -408,8 +411,11 @@
 	/*
 	 *	Adjust for misclocked crap
 	 */
-	 
 	rate = ( rate * clocking)/48000;
+	if(strict_clocking && rate < 8000) {
+		rate = 8000;
+		dmabuf->rate = (rate * 48000)/clocking;
+	}
 	
 	if(rate != i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE))
 	{
@@ -456,6 +462,10 @@
 	 */
 	 
 	rate = ( rate * clocking)/48000;
+	if(strict_clocking && rate < 8000) {
+		rate = 8000;
+		dmabuf->rate = (rate * 48000)/clocking;
+	}
 	
 	if(rate != i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE))
 	{
@@ -478,34 +488,10 @@
 	return dmabuf->rate;
 }
 
-/* prepare channel attributes for playback */ 
-static void i810_play_setup(struct i810_state *state)
-{
-//	struct dmabuf *dmabuf = &state->dmabuf;
-//	struct i810_channel *channel = dmabuf->channel;
-	/* Fixed format. .. */
-	//if (dmabuf->fmt & I810_FMT_16BIT)
-	//if (dmabuf->fmt & I810_FMT_STEREO)
-}
-
-/* prepare channel attributes for recording */
-static void i810_rec_setup(struct i810_state *state)
-{
-//	u16 w;
-//	struct i810_card *card = state->card;
-//	struct dmabuf *dmabuf = &state->dmabuf;
-//	struct i810_channel *channel = dmabuf->channel;
-
-	/* Enable AC-97 ADC (capture) */
-//	if (dmabuf->fmt & I810_FMT_16BIT) {
-//	if (dmabuf->fmt & I810_FMT_STEREO)
-}
-
-
 /* get current playback/recording dma buffer pointer (byte offset from LBA),
    called with spinlock held! */
    
-extern __inline__ unsigned i810_get_dma_addr(struct i810_state *state)
+extern __inline__ unsigned i810_get_dma_addr(struct i810_state *state, int rec)
 {
 	struct dmabuf *dmabuf = &state->dmabuf;
 	unsigned int civ, offset;
@@ -513,17 +499,13 @@
 	
 	if (!dmabuf->enable)
 		return 0;
-	if (dmabuf->enable & DAC_RUNNING)
-		c = dmabuf->write_channel;
-	else if (dmabuf->enable & ADC_RUNNING)
+	if (rec)
 		c = dmabuf->read_channel;
-	else {
-		printk("i810_audio: invalid dmabuf->enable state in get_dma_addr\n");
-		return 0;
-	}
+	else
+		c = dmabuf->write_channel;
 	do {
 		civ = inb(state->card->iobase+c->port+OFF_CIV);
-		offset = (civ + 1) * (dmabuf->dmasize/SG_LEN) -
+		offset = (civ + 1) * dmabuf->fragsize -
 			      2 * inw(state->card->iobase+c->port+OFF_PICB);
 		/* CIV changed before we read PICB (very seldom) ?
 		 * then PICB was rubbish, so try again */
@@ -532,22 +514,26 @@
 	return offset;
 }
 
-static void resync_dma_ptrs(struct i810_state *state, int rec)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	struct i810_channel *c;
-	int offset;
-
-	if(rec) {
-		c = dmabuf->read_channel;
-	} else {
-		c = dmabuf->write_channel;
-	}
-	offset = inb(state->card->iobase+c->port+OFF_CIV);
-	offset *= (dmabuf->dmasize/SG_LEN);
-	
-	dmabuf->hwptr=dmabuf->swptr = offset;
-}
+//static void resync_dma_ptrs(struct i810_state *state, int rec)
+//{
+//	struct dmabuf *dmabuf = &state->dmabuf;
+//	struct i810_channel *c;
+//	int offset;
+//
+//	if(rec) {
+//		c = dmabuf->read_channel;
+//	} else {
+//		c = dmabuf->write_channel;
+//	}
+//	if(c==NULL)
+//		return;
+//	offset = inb(state->card->iobase+c->port+OFF_CIV);
+//	if(offset == inb(state->card->iobase+c->port+OFF_LVI))
+//		offset++;
+//	offset *= dmabuf->fragsize;
+//	
+//	dmabuf->hwptr=dmabuf->swptr = offset;
+//}
 	
 /* Stop recording (lock held) */
 extern __inline__ void __stop_adc(struct i810_state *state)
@@ -575,12 +561,13 @@
 	struct i810_card *card = state->card;
 	unsigned long flags;
 
-	spin_lock_irqsave(&card->lock, flags);
-	if ((dmabuf->mapped || dmabuf->count < (signed)dmabuf->dmasize) && dmabuf->ready) {
+	if (dmabuf->count < dmabuf->dmasize && dmabuf->ready && !dmabuf->enable &&
+	    (dmabuf->trigger & PCM_ENABLE_INPUT)) {
+		spin_lock_irqsave(&card->lock, flags);
 		dmabuf->enable |= ADC_RUNNING;
-		outb((1<<4) | 1<<2 | 1, card->iobase + PI_CR);
+		outb((1<<4) | (1<<2) | 1, card->iobase + PI_CR);
+		spin_unlock_irqrestore(&card->lock, flags);
 	}
-	spin_unlock_irqrestore(&card->lock, flags);
 }
 
 /* stop playback (lock held) */
@@ -609,12 +596,13 @@
 	struct i810_card *card = state->card;
 	unsigned long flags;
 
-	spin_lock_irqsave(&card->lock, flags);
-	if ((dmabuf->mapped || dmabuf->count > 0) && dmabuf->ready) {
+	if (dmabuf->count > 0 && dmabuf->ready && !dmabuf->enable &&
+	    (dmabuf->trigger & PCM_ENABLE_OUTPUT)) {
+		spin_lock_irqsave(&card->lock, flags);
 		dmabuf->enable |= DAC_RUNNING;
-		outb((1<<4) | 1<<2 | 1, card->iobase + PO_CR);
+		outb((1<<4) | (1<<2) | 1, card->iobase + PO_CR);
+		spin_unlock_irqrestore(&card->lock, flags);
 	}
-	spin_unlock_irqrestore(&card->lock, flags);
 }
 
 #define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
@@ -625,18 +613,29 @@
 {
 	struct dmabuf *dmabuf = &state->dmabuf;
 	void *rawbuf= NULL;
-	int order;
+	int order, size;
 	struct page *page, *pend;
 
-	/* alloc as big a chunk as we can, FIXME: is this necessary ?? */
-	for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
+	/* If we don't have any oss frag params, then use our default ones */
+	if(dmabuf->ossmaxfrags == 0)
+		dmabuf->ossmaxfrags = 4;
+	if(dmabuf->ossfragsize == 0)
+		dmabuf->ossfragsize = (PAGE_SIZE<<DMABUF_DEFAULTORDER)/dmabuf->ossmaxfrags;
+	size = dmabuf->ossfragsize * dmabuf->ossmaxfrags;
+
+	/* alloc enough to satisfy the oss params */
+	for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) {
+		if ( (PAGE_SIZE<<order) > size )
+			continue;
 		if ((rawbuf = pci_alloc_consistent(state->card->pci_dev,
 						   PAGE_SIZE << order,
 						   &dmabuf->dma_handle)))
 			break;
+	}
 	if (!rawbuf)
 		return -ENOMEM;
 
+
 #ifdef DEBUG
 	printk("i810_audio: allocated %ld (order = %d) bytes at %p\n",
 	       PAGE_SIZE << order, order, rawbuf);
@@ -677,52 +676,53 @@
 	struct dmabuf *dmabuf = &state->dmabuf;
 	struct i810_channel *c;
 	struct sg_item *sg;
-	unsigned bytepersec;
-	unsigned bufsize;
 	unsigned long flags;
 	int ret;
-	unsigned fragsize;
+	unsigned fragint;
 	int i;
 
 	spin_lock_irqsave(&state->card->lock, flags);
-	resync_dma_ptrs(state, rec);
+	if(dmabuf->enable & DAC_RUNNING)
+		__stop_dac(state);
+	if(dmabuf->enable & ADC_RUNNING)
+		__stop_adc(state);
 	dmabuf->total_bytes = 0;
 	dmabuf->count = dmabuf->error = 0;
+	dmabuf->swptr = dmabuf->hwptr = 0;
 	spin_unlock_irqrestore(&state->card->lock, flags);
 
 	/* allocate DMA buffer if not allocated yet */
-	if (!dmabuf->rawbuf)
-		if ((ret = alloc_dmabuf(state)))
-			return ret;
+	if (dmabuf->rawbuf)
+		dealloc_dmabuf(state);
+	if ((ret = alloc_dmabuf(state)))
+		return ret;
 
 	/* FIXME: figure out all this OSS fragment stuff */
-	/* sample_shift is for 16 byte samples, add an extra shift for bytes */
-	bytepersec = dmabuf->rate << (sample_shift[dmabuf->fmt] + 1);
-	bufsize = PAGE_SIZE << dmabuf->buforder;
-	if (dmabuf->ossfragshift) {
-		if ((1000 << dmabuf->ossfragshift) < bytepersec)
-			dmabuf->fragshift = ld2(bytepersec/1000);
-		else
-			dmabuf->fragshift = dmabuf->ossfragshift;
+	/* I did, it now does what it should according to the OSS API.  DL */
+	dmabuf->dmasize = PAGE_SIZE << dmabuf->buforder;
+	dmabuf->numfrag = SG_LEN;
+	dmabuf->fragsize = dmabuf->dmasize/dmabuf->numfrag;
+	dmabuf->fragsamples = dmabuf->fragsize >> 1;
+
+	memset(dmabuf->rawbuf, 0, dmabuf->dmasize);
+
+	if(dmabuf->ossmaxfrags == 4) {
+		fragint = 8;
+		dmabuf->ossfragsize = dmabuf->dmasize>>2;
+		dmabuf->fragshift = 2;
+	} else if (dmabuf->ossmaxfrags == 8) {
+		fragint = 4;
+		dmabuf->ossfragsize = dmabuf->dmasize>>3;
+		dmabuf->fragshift = 3;
+	} else if (dmabuf->ossmaxfrags == 16) {
+		fragint = 2;
+		dmabuf->ossfragsize = dmabuf->dmasize>>4;
+		dmabuf->fragshift = 4;
 	} else {
-		/* lets hand out reasonable big ass buffers by default */
-		dmabuf->fragshift = (dmabuf->buforder + PAGE_SHIFT -2);
+		fragint = 1;
+		dmabuf->ossfragsize = dmabuf->dmasize>>5;
+		dmabuf->fragshift = 5;
 	}
-	dmabuf->numfrag = bufsize >> dmabuf->fragshift;
-	while (dmabuf->numfrag < 4 && dmabuf->fragshift > 3) {
-		dmabuf->fragshift--;
-		dmabuf->numfrag = bufsize >> dmabuf->fragshift;
-	}
-	dmabuf->fragsize = 1 << dmabuf->fragshift;
-	if (dmabuf->ossmaxfrags >= 4 && dmabuf->ossmaxfrags < dmabuf->numfrag)
-		dmabuf->numfrag = dmabuf->ossmaxfrags;
-	dmabuf->fragsamples = dmabuf->fragsize >> sample_shift[dmabuf->fmt];
-	dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
-
-	memset(dmabuf->rawbuf, (dmabuf->fmt & I810_FMT_16BIT) ? 0 : 0x80,
-	       dmabuf->dmasize);
-
-	fragsize = bufsize / SG_LEN;
 	/*
 	 *	Now set up the ring 
 	 */
@@ -737,24 +737,26 @@
 		 *	way (we might want more interrupts later..) 
 		 */
 	  
-		for(i=0;i<32;i++)
+		for(i=0;i<dmabuf->numfrag;i++)
 		{
-			sg->busaddr=virt_to_bus(dmabuf->rawbuf+fragsize*i);
-			sg->control=(fragsize>>sample_shift[dmabuf->fmt]);
-			sg->control|=CON_IOC;
+			sg->busaddr=virt_to_bus(dmabuf->rawbuf+dmabuf->fragsize*i);
+			// the card will always be doing 16bit stereo
+			sg->control=dmabuf->fragsamples;
+			sg->control|=CON_BUFPAD;
+			// set us up to get IOC interrupts as often as needed to
+			// satisfy numfrag requirements, no more
+			if( ((i+1) % fragint) == 0) {
+				sg->control|=CON_IOC;
+			}
 			sg++;
 		}
 		spin_lock_irqsave(&state->card->lock, flags);
 		outb(2, state->card->iobase+c->port+OFF_CR);   /* reset DMA machine */
 		outl(virt_to_bus(&c->sg[0]), state->card->iobase+c->port+OFF_BDBAR);
-		outb(31, state->card->iobase+c->port+OFF_LVI);
 		outb(0, state->card->iobase+c->port+OFF_CIV);
+		outb(0, state->card->iobase+c->port+OFF_LVI);
+		dmabuf->count = 0;
 
-		if (c == dmabuf->read_channel) {
-			i810_rec_setup(state);
-		} else {
-			i810_play_setup(state);
-		}
 		spin_unlock_irqrestore(&state->card->lock, flags);
 
 		if(c != dmabuf->write_channel)
@@ -775,36 +777,115 @@
 
 	return 0;
 }
-/*
- * Clear the rest of the last i810 dma buffer, normally there is no rest
- * because the OSS fragment size is the same as the size of this buffer.
- */
-static void i810_clear_tail(struct i810_state *state)
+
+static void __i810_update_lvi(struct i810_state *state, int rec)
 {
 	struct dmabuf *dmabuf = &state->dmabuf;
-	unsigned swptr;
-	unsigned char silence = (dmabuf->fmt & I810_FMT_16BIT) ? 0 : 0x80;
-	unsigned int len;
-	unsigned long flags;
+	int x, port;
+	
+	port = state->card->iobase;
+	if(rec)
+		port += dmabuf->read_channel->port;
+	else
+		port += dmabuf->write_channel->port;
 
-	spin_lock_irqsave(&state->card->lock, flags);
-	swptr = dmabuf->swptr;
-	spin_unlock_irqrestore(&state->card->lock, flags);
+	if(dmabuf->mapped) {
+		if(rec)
+			dmabuf->swptr = (dmabuf->hwptr + dmabuf->dmasize
+				       	- dmabuf->count) % dmabuf->dmasize;
+		else
+			dmabuf->swptr = (dmabuf->hwptr + dmabuf->count)
+			       		% dmabuf->dmasize;
+	}
+	/*
+	 * two special cases, count == 0 on write
+	 * means no data, and count == dmasize
+	 * means no data on read, handle appropriately
+	 */
+	if(!rec && dmabuf->count == 0) {
+		outb(inb(port+OFF_CIV),port+OFF_LVI);
+		return;
+	}
+	if(rec && dmabuf->count == dmabuf->dmasize) {
+		outb(inb(port+OFF_CIV),port+OFF_LVI);
+		return;
+	}
+	/* swptr - 1 is the tail of our transfer */
+	x = (dmabuf->dmasize + dmabuf->swptr - 1) % dmabuf->dmasize;
+	x /= dmabuf->fragsize;
+	outb(x&31, port+OFF_LVI);
+}
 
-	if(dmabuf->dmasize)
-		len = swptr % (dmabuf->dmasize/SG_LEN);
-	else
-		len = 0;
-	
-	memset(dmabuf->rawbuf + swptr, silence, len);
+static void i810_update_lvi(struct i810_state *state, int rec)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	unsigned long flags;
 
+	if(!dmabuf->ready)
+		return;
 	spin_lock_irqsave(&state->card->lock, flags);
-	dmabuf->swptr += len;
-	dmabuf->count += len;
+	__i810_update_lvi(state, rec);
 	spin_unlock_irqrestore(&state->card->lock, flags);
+}
 
-	/* restart the dma machine in case it is halted */
-	start_dac(state);
+/* update buffer manangement pointers, especially, dmabuf->count and dmabuf->hwptr */
+static void i810_update_ptr(struct i810_state *state)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	unsigned hwptr;
+	int diff;
+
+	/* error handling and process wake up for DAC */
+	if (dmabuf->enable == ADC_RUNNING) {
+		/* update hardware pointer */
+		hwptr = i810_get_dma_addr(state, 1);
+		diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
+//		printk("HWP %d,%d,%d\n", hwptr, dmabuf->hwptr, diff);
+		dmabuf->hwptr = hwptr;
+		dmabuf->total_bytes += diff;
+		dmabuf->count += diff;
+		if (dmabuf->count > dmabuf->dmasize) {
+			/* buffer underrun or buffer overrun */
+			/* this is normal for the end of a read */
+			/* only give an error if we went past the */
+			/* last valid sg entry */
+			if(inb(state->card->iobase + PI_CIV) !=
+			   inb(state->card->iobase + PI_LVI)) {
+				printk(KERN_WARNING "i810_audio: DMA overrun on read\n");
+				dmabuf->error++;
+			}
+		}
+		if (dmabuf->count > dmabuf->ossfragsize)
+			wake_up(&dmabuf->wait);
+	}
+	/* error handling and process wake up for DAC */
+	if (dmabuf->enable == DAC_RUNNING) {
+		/* update hardware pointer */
+		hwptr = i810_get_dma_addr(state, 0);
+		diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
+//		printk("HWP %d,%d,%d\n", hwptr, dmabuf->hwptr, diff);
+		dmabuf->hwptr = hwptr;
+		dmabuf->total_bytes += diff;
+		dmabuf->count -= diff;
+		if (dmabuf->count < 0) {
+			/* buffer underrun or buffer overrun */
+			/* this is normal for the end of a write */
+			/* only give an error if we went past the */
+			/* last valid sg entry */
+			if(inb(state->card->iobase + PO_CIV) !=
+			   inb(state->card->iobase + PO_LVI)) {
+				printk(KERN_WARNING "i810_audio: DMA overrun on write\n");
+				printk("i810_audio: CIV %d, LVI %d, hwptr %x, "
+					"count %d\n",
+					inb(state->card->iobase + PO_CIV),
+					inb(state->card->iobase + PO_LVI),
+					dmabuf->hwptr, dmabuf->count);
+				dmabuf->error++;
+			}
+		}
+		if (dmabuf->count < (dmabuf->dmasize-dmabuf->ossfragsize))
+			wake_up(&dmabuf->wait);
+	}
 }
 
 static int drain_dac(struct i810_state *state, int nonblock)
@@ -815,7 +896,7 @@
 	unsigned long tmo;
 	int count;
 
-	if (dmabuf->mapped || !dmabuf->ready)
+	if (!dmabuf->ready)
 		return 0;
 
 	add_wait_queue(&dmabuf->wait, &wait);
@@ -825,6 +906,7 @@
 		current->state = TASK_INTERRUPTIBLE;
 
 		spin_lock_irqsave(&state->card->lock, flags);
+		i810_update_ptr(state);
 		count = dmabuf->count;
 		spin_unlock_irqrestore(&state->card->lock, flags);
 
@@ -834,6 +916,10 @@
 		if (signal_pending(current))
 			break;
 
+		i810_update_lvi(state,0);
+		if (dmabuf->enable != DAC_RUNNING)
+			start_dac(state);
+
 		if (nonblock) {
 			remove_wait_queue(&dmabuf->wait, &wait);
 			current->state = TASK_RUNNING;
@@ -841,7 +927,7 @@
 		}
 
 		tmo = (dmabuf->dmasize * HZ) / dmabuf->rate;
-		tmo >>= sample_shift[dmabuf->fmt];
+		tmo >>= 1;
 		if (!schedule_timeout(tmo ? tmo : 1) && tmo){
 			printk(KERN_ERR "i810_audio: drain_dac, dma timeout?\n");
 			break;
@@ -855,88 +941,18 @@
 	return 0;
 }
 
-/* update buffer manangement pointers, especially, dmabuf->count and dmabuf->hwptr */
-static void i810_update_ptr(struct i810_state *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	unsigned hwptr, swptr;
-	int clear_cnt = 0;
-	int diff;
-	unsigned char silence;
-//	unsigned half_dmasize;
-
-	/* update hardware pointer */
-	hwptr = i810_get_dma_addr(state);
-	diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
-//	printk("HWP %d,%d,%d\n", hwptr, dmabuf->hwptr, diff);
-	dmabuf->hwptr = hwptr;
-	dmabuf->total_bytes += diff;
-
-	/* error handling and process wake up for DAC */
-	if (dmabuf->enable == ADC_RUNNING) {
-		if (dmabuf->mapped) {
-			dmabuf->count -= diff;
-			if (dmabuf->count >= (signed)dmabuf->fragsize)
-				wake_up(&dmabuf->wait);
-		} else {
-			dmabuf->count += diff;
-
-			if (dmabuf->count < 0 || dmabuf->count > dmabuf->dmasize) {
-				/* buffer underrun or buffer overrun, we have no way to recover
-				   it here, just stop the machine and let the process force hwptr
-				   and swptr to sync */
-				__stop_adc(state);
-				dmabuf->error++;
-			}
-			else if (!dmabuf->endcleared) {
-				swptr = dmabuf->swptr;
-				silence = (dmabuf->fmt & I810_FMT_16BIT ? 0 : 0x80);
-				if (dmabuf->count < (signed) dmabuf->fragsize) 
-				{
-					clear_cnt = dmabuf->fragsize;
-					if ((swptr + clear_cnt) > dmabuf->dmasize)
-						clear_cnt = dmabuf->dmasize - swptr;
-					memset (dmabuf->rawbuf + swptr, silence, clear_cnt);
-					dmabuf->endcleared = 1;
-				}
-			}			
-			if (dmabuf->count < (signed)dmabuf->dmasize/2) {
-				wake_up(&dmabuf->wait);
-			}
-		}
-	}
-	/* error handling and process wake up for DAC */
-	if (dmabuf->enable == DAC_RUNNING) {
-		if (dmabuf->mapped) {
-			dmabuf->count += diff;
-			if (dmabuf->count >= (signed)dmabuf->fragsize)
-				wake_up(&dmabuf->wait);
-		} else {
-			dmabuf->count -= diff;
-
-			if (dmabuf->count < 0 || dmabuf->count > dmabuf->dmasize) {
-				/* buffer underrun or buffer overrun, we have no way to recover
-				   it here, just stop the machine and let the process force hwptr
-				   and swptr to sync */
-				__stop_dac(state);
-				printk(KERN_WARNING "i810_audio: DMA overrun on send\n");
-				dmabuf->error++;
-			}
-			if (dmabuf->count < (signed)dmabuf->dmasize/2) {
-				wake_up(&dmabuf->wait);
-			}
-		}
-	}
-}
-
 static void i810_channel_interrupt(struct i810_card *card)
 {
-	int i;
-
+	int i, count;
+	
+#ifdef DEBUG_INTERRUPTS
+	printk("CHANNEL ");
+#endif
 	for(i=0;i<NR_HW_CH;i++)
 	{
 		struct i810_state *state = card->states[i];
 		struct i810_channel *c;
+		struct dmabuf *dmabuf;
 		unsigned long port = card->iobase;
 		u16 status;
 		
@@ -944,35 +960,56 @@
 			continue;
 		if(!state->dmabuf.ready)
 			continue;
-		if(state->dmabuf.enable & DAC_RUNNING)
-			c=state->dmabuf.write_channel;
+		dmabuf = &state->dmabuf;
+		if(dmabuf->enable & DAC_RUNNING)
+			c=dmabuf->write_channel;
 		else
-			c=state->dmabuf.read_channel;
+			c=dmabuf->read_channel;
 		
 		port+=c->port;
 		
 		status = inw(port + OFF_SR);
-		
+#ifdef DEBUG_INTERRUPTS
+		printk("NUM %d PORT %lX IRQ ( ST%d ", c->num, c->port, status);
+#endif
 		if(status & DMA_INT_COMPLETE)
 		{
-			int x;
-			/* Keep the card chasing its tail */
-			outb(x=((inb(port+OFF_CIV)-1)&31), port+OFF_LVI);
 			i810_update_ptr(state);
+#ifdef DEBUG_INTERRUPTS
+			printk("COMP%d ",x);
+#endif
 		}
 		if(status & DMA_INT_LVI)
 		{
-			/* Back to the start */
 			i810_update_ptr(state);
-			outb(0, port + OFF_CR);
+			wake_up(&dmabuf->wait);
+#ifdef DEBUG_INTERRUPTS
+			printk("LVI ");
+#endif
+		}
+		if(status & DMA_INT_DCH)
+		{
+			i810_update_ptr(state);
+			if(dmabuf->enable & DAC_RUNNING)
+				count = dmabuf->count;
+			else
+				count = dmabuf->dmasize - dmabuf->count;
+			if(count > 0) {
+				outb(inb(port+OFF_CR) | 1, port+OFF_CR);
+			} else {
+				wake_up(&dmabuf->wait);
+#ifdef DEBUG_INTERRUPTS
+				printk("DCH - STOP ");
+#endif
+			}
 		}
 		outw(status & DMA_INT_MASK, port + OFF_SR);
 	}
+#ifdef DEBUG_INTERRUPTS
+	printk(")\n");
+#endif
 }
 
-static u32 jiff = 0;
-static u32 jiff_count = 0;
-
 static void i810_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct i810_card *card = (struct i810_card *)dev_id;
@@ -1009,10 +1046,10 @@
 	struct dmabuf *dmabuf = &state->dmabuf;
 	ssize_t ret;
 	unsigned long flags;
-	unsigned swptr;
+	unsigned int swptr;
 	int cnt;
 
-#ifdef DEBUG
+#ifdef DEBUG2
 	printk("i810_audio: i810_read called, count = %d\n", count);
 #endif
 
@@ -1026,43 +1063,45 @@
 		dmabuf->ready = 0;
 		dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card);
 		if (!dmabuf->read_channel) {
-			return -ENODEV;
+			return -EBUSY;
 		}
 	}
 	if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
 		return ret;
 	if (!access_ok(VERIFY_WRITE, buffer, count))
 		return -EFAULT;
+	dmabuf->trigger &= ~PCM_ENABLE_OUTPUT;
 	ret = 0;
 
 	while (count > 0) {
 		spin_lock_irqsave(&state->card->lock, flags);
-		if (dmabuf->count > (signed) dmabuf->dmasize) {
-			/* buffer overrun, we are recovering from sleep_on_timeout,
-			   resync hwptr and swptr, make process flush the buffer */
-			dmabuf->count = dmabuf->dmasize;
-			dmabuf->swptr = dmabuf->hwptr;
-		}
 		swptr = dmabuf->swptr;
-		cnt = dmabuf->dmasize - swptr;
-		if (dmabuf->count < cnt)
-			cnt = dmabuf->count;
+		if (dmabuf->count > dmabuf->dmasize) {
+			dmabuf->count = 0;
+		}
+		cnt = dmabuf->count;
+		if(cnt > (dmabuf->dmasize - swptr))
+			cnt = dmabuf->dmasize - swptr;
 		spin_unlock_irqrestore(&state->card->lock, flags);
 
 		if (cnt > count)
 			cnt = count;
 		if (cnt <= 0) {
 			unsigned long tmo;
-			/* buffer is empty, start the dma machine and wait for data to be
-			   recorded */
-			start_adc(state);
+			// are we already running?  only start us if we aren't running
+			// currently
+			i810_update_lvi(state,1);
+			if(!dmabuf->enable) {
+				dmabuf->trigger |= PCM_ENABLE_INPUT;
+				start_adc(state);
+			}
 			if (file->f_flags & O_NONBLOCK) {
 				if (!ret) ret = -EAGAIN;
 				return ret;
 			}
 			/* This isnt strictly right for the 810  but it'll do */
 			tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
-			tmo >>= sample_shift[dmabuf->fmt];
+			tmo >>= 1;
 			/* There are two situations when sleep_on_timeout returns, one is when
 			   the interrupt is serviced correctly and the process is waked up by
 			   ISR ON TIME. Another is when timeout is expired, which means that
@@ -1102,8 +1141,9 @@
 		count -= cnt;
 		buffer += cnt;
 		ret += cnt;
-		start_adc(state);
 	}
+	i810_update_lvi(state,1);
+	start_adc(state);
 	return ret;
 }
 
@@ -1115,10 +1155,10 @@
 	struct dmabuf *dmabuf = &state->dmabuf;
 	ssize_t ret;
 	unsigned long flags;
-	unsigned swptr;
-	int cnt;
+	unsigned int swptr = 0;
+	int cnt, x;
 
-#ifdef DEBUG
+#ifdef DEBUG2
 	printk("i810_audio: i810_write called, count = %d\n", count);
 #endif
 
@@ -1132,25 +1172,23 @@
 		dmabuf->ready = 0;
 		dmabuf->write_channel = state->card->alloc_pcm_channel(state->card);
 		if(!dmabuf->write_channel)
-			return -ENODEV;
+			return -EBUSY;
 	}
 	if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
 		return ret;
 	if (!access_ok(VERIFY_READ, buffer, count))
 		return -EFAULT;
+	dmabuf->trigger &= ~PCM_ENABLE_INPUT;
 	ret = 0;
 
 	while (count > 0) {
 		spin_lock_irqsave(&state->card->lock, flags);
+		swptr = dmabuf->swptr;
 		if (dmabuf->count < 0) {
-			/* buffer underrun, we are recovering from sleep_on_timeout,
-			   resync hwptr and swptr */
 			dmabuf->count = 0;
-			dmabuf->swptr = dmabuf->hwptr;
 		}
-		swptr = dmabuf->swptr;
 		cnt = dmabuf->dmasize - swptr;
-		if (dmabuf->count + cnt > dmabuf->dmasize)
+		if(cnt > (dmabuf->dmasize - dmabuf->count))
 			cnt = dmabuf->dmasize - dmabuf->count;
 		spin_unlock_irqrestore(&state->card->lock, flags);
 
@@ -1158,16 +1196,20 @@
 			cnt = count;
 		if (cnt <= 0) {
 			unsigned long tmo;
-			/* buffer is full, start the dma machine and wait for data to be
-			   played */
-			start_dac(state);
+			// There is data waiting to be played
+			i810_update_lvi(state,0);
+			if(!dmabuf->enable && dmabuf->count) {
+				/* force the starting incase SETTRIGGER has been used */
+				/* to stop it, otherwise this is a deadlock situation */
+				dmabuf->trigger |= PCM_ENABLE_OUTPUT;
+				start_dac(state);
+			}
 			if (file->f_flags & O_NONBLOCK) {
 				if (!ret) ret = -EAGAIN;
 				return ret;
 			}
 			/* Not strictly correct but works */
-			tmo = dmabuf->rate << (sample_shift[dmabuf->fmt] + 1);
-			tmo = dmabuf->dmasize * HZ / tmo;
+			tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 4);
 			/* There are two situations when sleep_on_timeout returns, one is when
 			   the interrupt is serviced correctly and the process is waked up by
 			   ISR ON TIME. Another is when timeout is expired, which means that
@@ -1184,6 +1226,7 @@
 #endif
 				/* a buffer underrun, we delay the recovery until next time the
 				   while loop begin and we REALLY have data to play */
+				//return ret;
 			}
 			if (signal_pending(current)) {
 				if (!ret) ret = -ERESTARTSYS;
@@ -1191,7 +1234,7 @@
 			}
 			continue;
 		}
-		if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) {
+		if (copy_from_user(dmabuf->rawbuf+swptr,buffer,cnt)) {
 			if (!ret) ret = -EFAULT;
 			return ret;
 		}
@@ -1201,14 +1244,21 @@
 		spin_lock_irqsave(&state->card->lock, flags);
 		dmabuf->swptr = swptr;
 		dmabuf->count += cnt;
-		dmabuf->endcleared = 0;
 		spin_unlock_irqrestore(&state->card->lock, flags);
 
 		count -= cnt;
 		buffer += cnt;
 		ret += cnt;
-		start_dac(state);
 	}
+	if (swptr % dmabuf->fragsize) {
+		x = dmabuf->fragsize - (swptr % dmabuf->fragsize);
+		if((x + dmabuf->count) < dmabuf->dmasize)
+			memset(dmabuf->rawbuf + swptr, '\0', x);
+	}
+	i810_update_lvi(state,0);
+	if (!dmabuf->enable && dmabuf->count >= dmabuf->ossfragsize)
+		start_dac(state);
+
 	return ret;
 }
 
@@ -1220,21 +1270,9 @@
 	unsigned long flags;
 	unsigned int mask = 0;
 
-	if (file->f_mode & FMODE_WRITE) {
-		if (!dmabuf->write_channel)
-			return 0;
-		if (!dmabuf->ready && prog_dmabuf(state, 0))
-			return 0;
-		poll_wait(file, &dmabuf->wait, wait);
-	} else { 
-	// don't do both read and write paths or we won't get woke up properly
-	// when we have a file with both permissions
-		if (!dmabuf->read_channel)
-			return 0;
-		if (!dmabuf->ready && prog_dmabuf(state, 1))
-			return 0;
-		poll_wait(file, &dmabuf->wait, wait);
-	}
+	if(!dmabuf->ready)
+		return 0;
+	poll_wait(file, &dmabuf->wait, wait);
 	spin_lock_irqsave(&state->card->lock, flags);
 	i810_update_ptr(state);
 	if (file->f_mode & FMODE_READ && dmabuf->enable & ADC_RUNNING) {
@@ -1262,22 +1300,24 @@
 	int ret = -EINVAL;
 	unsigned long size;
 
-	/* 
-	 *	Until we figure out a few problems
-	 */
-	 
 	lock_kernel();
 	if (vma->vm_flags & VM_WRITE) {
-		if (!dmabuf->write_channel && (dmabuf->write_channel = state->card->alloc_pcm_channel(state->card)) == NULL)
-			goto out;
-		if ((ret = prog_dmabuf(state, 0)) != 0)
-			goto out;
-	} else if (vma->vm_flags & VM_READ) {
-		if (!dmabuf->read_channel && (dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card)) == NULL)
+		if (!dmabuf->write_channel &&
+		    (dmabuf->write_channel =
+		     state->card->alloc_pcm_channel(state->card)) == NULL) {
+			ret = -EBUSY;
 			goto out;
-		if ((ret = prog_dmabuf(state, 1)) != 0)
+		}
+	}
+	if (vma->vm_flags & VM_READ) {
+		if (!dmabuf->read_channel &&
+		    (dmabuf->read_channel = 
+		     state->card->alloc_rec_pcm_channel(state->card)) == NULL) {
+			ret = -EBUSY;
 			goto out;
-	} else 
+		}
+	}
+	if ((ret = prog_dmabuf(state, 0)) != 0)
 		goto out;
 
 	ret = -EINVAL;
@@ -1291,9 +1331,13 @@
 			     size, vma->vm_page_prot))
 		goto out;
 	dmabuf->mapped = 1;
+	if(vma->vm_flags & VM_WRITE)
+		dmabuf->count = dmabuf->dmasize;
+	else
+		dmabuf->count = 0;
 	ret = 0;
 #ifdef DEBUG
-	printk("i810_audio: mmap'ed %d bytes of data space\n", size);
+	printk("i810_audio: mmap'ed %ld bytes of data space\n", size);
 #endif
 out:
 	unlock_kernel();
@@ -1312,41 +1356,52 @@
 	mapped = ((file->f_mode & FMODE_WRITE) && dmabuf->mapped) ||
 		((file->f_mode & FMODE_READ) && dmabuf->mapped);
 #ifdef DEBUG
-	printk("i810_audio: i810_ioctl, command = %2d, arg = 0x%08x\n",
-	       _IOC_NR(cmd), arg ? *(int *)arg : 0);
+	printk("i810_audio: i810_ioctl, arg=0x%x, cmd=", arg ? *(int *)arg : 0);
 #endif
 
 	switch (cmd) 
 	{
 	case OSS_GETVERSION:
+#ifdef DEBUG
+		printk("OSS_GETVERSION\n");
+#endif
 		return put_user(SOUND_VERSION, (int *)arg);
 
 	case SNDCTL_DSP_RESET:
+#ifdef DEBUG
+		printk("SNDCTL_DSP_RESET\n");
+#endif
 		/* FIXME: spin_lock ? */
-		if (file->f_mode & FMODE_WRITE) {
+		if (dmabuf->enable == DAC_RUNNING) {
 			stop_dac(state);
-			synchronize_irq();
-			dmabuf->ready = 0;
-			resync_dma_ptrs(state, 0);
-			dmabuf->swptr = dmabuf->hwptr = 0;
-			dmabuf->count = dmabuf->total_bytes = 0;
 		}
-		if (file->f_mode & FMODE_READ) {
+		if (dmabuf->enable == ADC_RUNNING) {
 			stop_adc(state);
-			synchronize_irq();
-			resync_dma_ptrs(state, 1);
-			dmabuf->ready = 0;
-			dmabuf->swptr = dmabuf->hwptr = 0;
-			dmabuf->count = dmabuf->total_bytes = 0;
 		}
+		synchronize_irq();
+		dmabuf->ready = 0;
+		dmabuf->swptr = dmabuf->hwptr = 0;
+		dmabuf->count = dmabuf->total_bytes = 0;
 		return 0;
 
 	case SNDCTL_DSP_SYNC:
-		if (file->f_mode & FMODE_WRITE)
-			return drain_dac(state, file->f_flags & O_NONBLOCK);
+#ifdef DEBUG
+		printk("SNDCTL_DSP_SYNC\n");
+#endif
+		if (dmabuf->enable != DAC_RUNNING || file->f_flags & O_NONBLOCK)
+			return 0;
+		drain_dac(state, 0);
+		stop_dac(state);
+		synchronize_irq();
+		dmabuf->ready = 0;
+		dmabuf->swptr = dmabuf->hwptr = 0;
+		dmabuf->count = dmabuf->total_bytes = 0;
 		return 0;
 
 	case SNDCTL_DSP_SPEED: /* set smaple rate */
+#ifdef DEBUG
+		printk("SNDCTL_DSP_SPEED\n");
+#endif
 		if (get_user(val, (int *)arg))
 			return -EFAULT;
 		if (val >= 0) {
@@ -1368,71 +1423,68 @@
 		return put_user(dmabuf->rate, (int *)arg);
 
 	case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
+#ifdef DEBUG
+		printk("SNDCTL_DSP_STEREO\n");
+#endif
 		if (get_user(val, (int *)arg))
 			return -EFAULT;
-		if(val==0)
-			return -EINVAL;
-		if (file->f_mode & FMODE_WRITE) {
+		if(val==0) {
+			ret = -EINVAL;
+		} else {
+			ret = 1;
+		}
+		if (dmabuf->enable & DAC_RUNNING) {
 			stop_dac(state);
-			dmabuf->ready = 0;
-			dmabuf->fmt |= I810_FMT_STEREO;
 		}
-		if (file->f_mode & FMODE_READ) {
+		if (dmabuf->enable & ADC_RUNNING) {
 			stop_adc(state);
-			dmabuf->ready = 0;
-			dmabuf->fmt |= I810_FMT_STEREO;
 		}
-		return 0;
+		return ret;
 
 	case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
 			if (!dmabuf->ready && (val = prog_dmabuf(state, 0)))
 				return val;
-			return put_user(dmabuf->fragsize, (int *)arg);
 		}
 		if (file->f_mode & FMODE_READ) {
 			if (!dmabuf->ready && (val = prog_dmabuf(state, 1)))
 				return val;
-			return put_user(dmabuf->fragsize, (int *)arg);
 		}
+#ifdef DEBUG
+		printk("SNDCTL_DSP_GETBLKSIZE %d\n", dmabuf->ossfragsize);
+#endif
+		return put_user(dmabuf->ossfragsize, (int *)arg);
 
 	case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format*/
+#ifdef DEBUG
+		printk("SNDCTL_DSP_GETFMTS\n");
+#endif
 		return put_user(AFMT_S16_LE, (int *)arg);
 
 	case SNDCTL_DSP_SETFMT: /* Select sample format */
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		if (val != AFMT_QUERY) {
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(state);
-				dmabuf->ready = 0;
-				dmabuf->fmt |= I810_FMT_16BIT;
-			}
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(state);
-				dmabuf->ready = 0;
-				dmabuf->fmt |= I810_FMT_16BIT;
-			}
-		}
+#ifdef DEBUG
+		printk("SNDCTL_DSP_SETFMT\n");
+#endif
 		return put_user(AFMT_S16_LE, (int *)arg);
 
 	case SNDCTL_DSP_CHANNELS:
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		if (val != 0) {
-			if (file->f_mode & FMODE_WRITE) {
-				stop_dac(state);
-				dmabuf->ready = 0;
-			}
-			if (file->f_mode & FMODE_READ) {
-				stop_adc(state);
-				dmabuf->ready = 0;
-			}
-		}
+#ifdef DEBUG
+		printk("SNDCTL_DSP_CHANNELS\n");
+#endif
 		return put_user(2, (int *)arg);
 
-	case SNDCTL_DSP_POST:
-		/* FIXME: the same as RESET ?? */
+	case SNDCTL_DSP_POST: /* the user has sent all data and is notifying us */
+		/* we update the swptr to the end of the last sg segment then return */
+#ifdef DEBUG
+		printk("SNDCTL_DSP_POST\n");
+#endif
+		if(!dmabuf->ready || (dmabuf->enable != DAC_RUNNING))
+			return 0;
+		if((dmabuf->swptr % dmabuf->fragsize) != 0) {
+			val = dmabuf->fragsize - (dmabuf->swptr % dmabuf->fragsize);
+			dmabuf->swptr += val;
+			dmabuf->count += val;
+		}
 		return 0;
 
 	case SNDCTL_DSP_SUBDIVIDE:
@@ -1442,6 +1494,9 @@
 			return -EFAULT;
 		if (val != 1 && val != 2 && val != 4)
 			return -EINVAL;
+#ifdef DEBUG
+		printk("SNDCTL_DSP_SUBDIVIDE %d\n", val);
+#endif
 		dmabuf->subdivision = val;
 		dmabuf->ready = 0;
 		return 0;
@@ -1450,15 +1505,27 @@
 		if (get_user(val, (int *)arg))
 			return -EFAULT;
 
-		dmabuf->ossfragshift = val & 0xffff;
+		dmabuf->ossfragsize = 1<<(val & 0xffff);
 		dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
-		if (dmabuf->ossfragshift < 4)
-			dmabuf->ossfragshift = 4;
-		if (dmabuf->ossfragshift > 15)
-			dmabuf->ossfragshift = 15;
-		if (dmabuf->ossmaxfrags < 4)
+		if (dmabuf->ossmaxfrags <= 4)
 			dmabuf->ossmaxfrags = 4;
+		else if (dmabuf->ossmaxfrags <= 8)
+			dmabuf->ossmaxfrags = 8;
+		else if (dmabuf->ossmaxfrags <= 16)
+			dmabuf->ossmaxfrags = 16;
+		else
+			dmabuf->ossmaxfrags = 32;
+		val = dmabuf->ossfragsize * dmabuf->ossmaxfrags;
+		if (val < 16384)
+			val = 16384;
+		if (val > 65536)
+			val = 65536;
+		dmabuf->ossfragsize = val/dmabuf->ossmaxfrags;
 		dmabuf->ready = 0;
+#ifdef DEBUG
+		printk("SNDCTL_DSP_SETFRAGMENT 0x%x, %d, %d\n", val,
+			dmabuf->ossfragsize, dmabuf->ossmaxfrags);
+#endif
 
 		return 0;
 
@@ -1469,13 +1536,42 @@
 			return val;
 		spin_lock_irqsave(&state->card->lock, flags);
 		i810_update_ptr(state);
-		abinfo.fragsize = dmabuf->fragsize;
-		abinfo.bytes = dmabuf->dmasize - dmabuf->count;
-		abinfo.fragstotal = dmabuf->numfrag;
-		abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
+		abinfo.fragsize = dmabuf->ossfragsize;
+		abinfo.fragstotal = dmabuf->ossmaxfrags;
+		if(dmabuf->mapped)
+			abinfo.bytes = dmabuf->count;
+		else
+			abinfo.bytes = dmabuf->dmasize - dmabuf->count;
+		abinfo.fragments = abinfo.bytes / dmabuf->ossfragsize;
 		spin_unlock_irqrestore(&state->card->lock, flags);
+#ifdef DEBUG
+		printk("SNDCTL_DSP_GETOSPACE %d, %d, %d, %d\n", abinfo.bytes,
+			abinfo.fragsize, abinfo.fragments, abinfo.fragstotal);
+#endif
 		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
+	case SNDCTL_DSP_GETOPTR:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
+			return val;
+		spin_lock_irqsave(&state->card->lock, flags);
+		i810_update_ptr(state);
+		cinfo.bytes = dmabuf->total_bytes;
+		cinfo.ptr = dmabuf->hwptr;
+		cinfo.blocks = (dmabuf->dmasize - dmabuf->count)/dmabuf->ossfragsize;
+		if (dmabuf->mapped) {
+			dmabuf->count = (dmabuf->dmasize - 
+					 (dmabuf->count & (dmabuf->ossfragsize-1)));
+			__i810_update_lvi(state, 0);
+		}
+		spin_unlock_irqrestore(&state->card->lock, flags);
+#ifdef DEBUG
+		printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes,
+			cinfo.blocks, cinfo.ptr, dmabuf->count);
+#endif
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
 			return -EINVAL;
@@ -1483,87 +1579,111 @@
 			return val;
 		spin_lock_irqsave(&state->card->lock, flags);
 		i810_update_ptr(state);
-		abinfo.fragsize = dmabuf->fragsize;
-		abinfo.bytes = dmabuf->count;
-		abinfo.fragstotal = dmabuf->numfrag;
-		abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
+		abinfo.fragsize = dmabuf->ossfragsize;
+		abinfo.fragstotal = dmabuf->ossmaxfrags;
+		abinfo.bytes = dmabuf->dmasize - dmabuf->count;
+		abinfo.fragments = abinfo.bytes / dmabuf->ossfragsize;
 		spin_unlock_irqrestore(&state->card->lock, flags);
+#ifdef DEBUG
+		printk("SNDCTL_DSP_GETISPACE %d, %d, %d, %d\n", abinfo.bytes,
+			abinfo.fragsize, abinfo.fragments, abinfo.fragstotal);
+#endif
 		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
+	case SNDCTL_DSP_GETIPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
+			return val;
+		spin_lock_irqsave(&state->card->lock, flags);
+		i810_update_ptr(state);
+		cinfo.bytes = dmabuf->total_bytes;
+		cinfo.blocks = dmabuf->count/dmabuf->ossfragsize;
+		cinfo.ptr = dmabuf->hwptr;
+		if (dmabuf->mapped) {
+			dmabuf->count &= dmabuf->ossfragsize-1;
+			__i810_update_lvi(state, 1);
+		}
+		spin_unlock_irqrestore(&state->card->lock, flags);
+#ifdef DEBUG
+		printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes,
+			cinfo.blocks, cinfo.ptr, dmabuf->count);
+#endif
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
 	case SNDCTL_DSP_NONBLOCK:
+#ifdef DEBUG
+		printk("SNDCTL_DSP_NONBLOCK\n");
+#endif
 		file->f_flags |= O_NONBLOCK;
 		return 0;
 
 	case SNDCTL_DSP_GETCAPS:
+#ifdef DEBUG
+		printk("SNDCTL_DSP_GETCAPS\n");
+#endif
 	    return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP|DSP_CAP_BIND,
 			    (int *)arg);
 
 	case SNDCTL_DSP_GETTRIGGER:
 		val = 0;
-		if (file->f_mode & FMODE_READ && dmabuf->enable & ADC_RUNNING)
-			val |= PCM_ENABLE_INPUT;
-		if (file->f_mode & FMODE_WRITE && dmabuf->enable & DAC_RUNNING)
-			val |= PCM_ENABLE_OUTPUT;
-		return put_user(val, (int *)arg);
+#ifdef DEBUG
+		printk("SNDCTL_DSP_GETTRIGGER 0x%x\n", dmabuf->trigger);
+#endif
+		return put_user(dmabuf->trigger, (int *)arg);
 
 	case SNDCTL_DSP_SETTRIGGER:
 		if (get_user(val, (int *)arg))
 			return -EFAULT;
-		if (file->f_mode & FMODE_READ && val & PCM_ENABLE_INPUT) {
-			if (dmabuf->enable & DAC_RUNNING)
-				return -ENODEV;
-			if (!dmabuf->read_channel) {
-				dmabuf->ready = 0;
-				dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card);
-				if (!dmabuf->read_channel)
-					return -ENODEV;
-			}
-			if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
-				return ret;
-			start_adc(state);
+#ifdef DEBUG
+		printk("SNDCTL_DSP_SETTRIGGER 0x%x\n", val);
+#endif
+		if( !(val & PCM_ENABLE_INPUT) && dmabuf->enable == ADC_RUNNING) {
+			stop_adc(state);
+		}
+		if( !(val & PCM_ENABLE_OUTPUT) && dmabuf->enable == DAC_RUNNING) {
+			stop_dac(state);
 		}
-		if (file->f_mode & FMODE_WRITE && val & PCM_ENABLE_OUTPUT) {
-			if (dmabuf->enable & ADC_RUNNING)
-				return -ENODEV;
+		dmabuf->trigger = val;
+		if(val & PCM_ENABLE_OUTPUT) {
 			if (!dmabuf->write_channel) {
 				dmabuf->ready = 0;
 				dmabuf->write_channel = state->card->alloc_pcm_channel(state->card);
 				if (!dmabuf->write_channel)
-					return -ENODEV;
+					return -EBUSY;
 			}
 			if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
 				return ret;
-			start_dac(state);
+			if (dmabuf->mapped) {
+				dmabuf->count = dmabuf->dmasize;
+				i810_update_lvi(state,0);
+			}
+			if (!dmabuf->enable && dmabuf->count > dmabuf->fragsize)
+				start_dac(state);
+		}
+		if(val & PCM_ENABLE_INPUT) {
+			if (!dmabuf->read_channel) {
+				dmabuf->ready = 0;
+				dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card);
+				if (!dmabuf->read_channel)
+					return -EBUSY;
+			}
+			if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
+				return ret;
+			if (dmabuf->mapped) {
+				dmabuf->count = 0;
+				i810_update_lvi(state,1);
+			}
+			if (!dmabuf->enable && dmabuf->count <
+			    (dmabuf->dmasize - dmabuf->fragsize))
+				start_adc(state);
 		}
 		return 0;
 
-	case SNDCTL_DSP_GETIPTR:
-		if (!(file->f_mode & FMODE_READ))
-			return -EINVAL;
-		spin_lock_irqsave(&state->card->lock, flags);
-		i810_update_ptr(state);
-		cinfo.bytes = dmabuf->total_bytes;
-		cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
-		cinfo.ptr = dmabuf->hwptr;
-		if (dmabuf->mapped)
-			dmabuf->count &= dmabuf->fragsize-1;
-		spin_unlock_irqrestore(&state->card->lock, flags);
-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
-
-	case SNDCTL_DSP_GETOPTR:
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		spin_lock_irqsave(&state->card->lock, flags);
-		i810_update_ptr(state);
-		cinfo.bytes = dmabuf->total_bytes;
-		cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
-		cinfo.ptr = dmabuf->hwptr;
-		if (dmabuf->mapped)
-			dmabuf->count &= dmabuf->fragsize-1;
-		spin_unlock_irqrestore(&state->card->lock, flags);
-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
-
 	case SNDCTL_DSP_SETDUPLEX:
+#ifdef DEBUG
+		printk("SNDCTL_DSP_SETDUPLEX\n");
+#endif
 		return -EINVAL;
 
 	case SNDCTL_DSP_GETODELAY:
@@ -1573,16 +1693,27 @@
 		i810_update_ptr(state);
 		val = dmabuf->count;
 		spin_unlock_irqrestore(&state->card->lock, flags);
+#ifdef DEBUG
+		printk("SNDCTL_DSP_GETODELAY %d\n", dmabuf->count);
+#endif
 		return put_user(val, (int *)arg);
 
 	case SOUND_PCM_READ_RATE:
+#ifdef DEBUG
+		printk("SOUND_PCM_READ_RATE %d\n", dmabuf->rate);
+#endif
 		return put_user(dmabuf->rate, (int *)arg);
 
 	case SOUND_PCM_READ_CHANNELS:
-		return put_user((dmabuf->fmt & I810_FMT_STEREO) ? 2 : 1,
-				(int *)arg);
+#ifdef DEBUG
+		printk("SOUND_PCM_READ_CHANNELS\n");
+#endif
+		return put_user(2, (int *)arg);
 
 	case SOUND_PCM_READ_BITS:
+#ifdef DEBUG
+		printk("SOUND_PCM_READ_BITS\n");
+#endif
 		return put_user(AFMT_S16_LE, (int *)arg);
 
 	case SNDCTL_DSP_MAPINBUF:
@@ -1590,6 +1721,9 @@
 	case SNDCTL_DSP_SETSYNCRO:
 	case SOUND_PCM_WRITE_FILTER:
 	case SOUND_PCM_READ_FILTER:
+#ifdef DEBUG
+		printk("SNDCTL_* -EINVAL\n");
+#endif
 		return -EINVAL;
 	}
 	return -EINVAL;
@@ -1621,7 +1755,7 @@
 	if (!state)
 		return -ENODEV;
 
- found_virt:
+found_virt:
 	/* initialize the virtual channel */
 	state->virt = i;
 	state->card = card;
@@ -1629,33 +1763,36 @@
 	init_waitqueue_head(&dmabuf->wait);
 	init_MUTEX(&state->open_sem);
 	file->private_data = state;
+	dmabuf->trigger = 0;
 
 	/* allocate hardware channels */
 	if(file->f_mode & FMODE_READ) {
 		if((dmabuf->read_channel = card->alloc_rec_pcm_channel(card)) == NULL) {
 			kfree (card->states[i]);
 			card->states[i] = NULL;;
-			return -ENODEV;
+			return -EBUSY;
 		}
-		i810_set_adc_rate(state, 48000);
+		i810_set_adc_rate(state, 8000);
+		dmabuf->trigger |= PCM_ENABLE_INPUT;
 	}
 	if(file->f_mode & FMODE_WRITE) {
 		if((dmabuf->write_channel = card->alloc_pcm_channel(card)) == NULL) {
 			kfree (card->states[i]);
 			card->states[i] = NULL;;
-			return -ENODEV;
+			return -EBUSY;
 		}
-		i810_set_dac_rate(state, 48000);
+		i810_set_dac_rate(state, 8000);
+		dmabuf->trigger |= PCM_ENABLE_OUTPUT;
 	}
 		
 	down(&state->open_sem);
 
 	/* set default sample format. According to OSS Programmer's Guide  /dev/dsp
 	   should be default to unsigned 8-bits, mono, with sample rate 8kHz and
-	   /dev/dspW will accept 16-bits sample */
-	dmabuf->fmt &= ~I810_FMT_MASK;
-	dmabuf->fmt |= I810_FMT_16BIT;
-	dmabuf->ossfragshift = 0;
+	   /dev/dspW will accept 16-bits sample, but we don't support those so we
+	   set it immediately to stereo and 16bit, which is all we do support */
+	dmabuf->fmt |= I810_FMT_16BIT | I810_FMT_STEREO;
+	dmabuf->ossfragsize = 0;
 	dmabuf->ossmaxfrags  = 0;
 	dmabuf->subdivision  = 0;
 
@@ -1671,22 +1808,23 @@
 	struct dmabuf *dmabuf = &state->dmabuf;
 
 	lock_kernel();
-	if (file->f_mode & FMODE_WRITE) {
-	}
 
-	/* stop DMA state machine and free DMA buffers/channels */
 	down(&state->open_sem);
 
-	if (dmabuf->enable & DAC_RUNNING) {
-		i810_clear_tail(state);
-		drain_dac(state, file->f_flags & O_NONBLOCK);
+	/* stop DMA state machine and free DMA buffers/channels */
+	if(dmabuf->enable == DAC_RUNNING ||
+	   (dmabuf->count && (dmabuf->trigger & PCM_ENABLE_OUTPUT))) {
+		if(drain_dac(state,file->f_mode & O_NDELAY)) {
+			up(&state->open_sem);
+			unlock_kernel();
+			return -EBUSY;
+		}
 		stop_dac(state);
-		dealloc_dmabuf(state);
 	}
 	if(dmabuf->enable & ADC_RUNNING) {
 		stop_adc(state);
-		dealloc_dmabuf(state);
 	}
+	dealloc_dmabuf(state);
 	if (file->f_mode & FMODE_WRITE) {
 		state->card->free_pcm_channel(state->card, dmabuf->write_channel->num);
 	}
@@ -1827,6 +1965,19 @@
 		if (ac97_probe_codec(codec) == 0)
 			break;
 
+		/* power up everything, modify this when implementing power saving */
+		i810_ac97_set(codec, AC97_POWER_CONTROL,
+			i810_ac97_get(codec, AC97_POWER_CONTROL) & ~0x7f00);
+		/* wait for analog ready */
+	        for (i=10;
+		     i && ((i810_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf);
+		     i--)
+		{
+			current->state = TASK_UNINTERRUPTIBLE;
+			schedule_timeout(HZ/20);
+		}
+
+		/* Don't attempt to get eid until powerup is complete */
 		eid = i810_ac97_get(codec, AC97_EXTENDED_ID);
 		
 		if(eid==0xFFFFFF)
@@ -1845,18 +1996,6 @@
 			printk(KERN_WARNING "i810_audio: only 48Khz playback available.\n");
 		else
 		{
-			/* power up everything, modify this when implementing power saving */
-			i810_ac97_set(codec, AC97_POWER_CONTROL,
-				i810_ac97_get(codec, AC97_POWER_CONTROL) & ~0x7f00);
-			/* wait for analog ready */
-		        for (i=10;
-			     i && ((i810_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf);
-			     i--)
-			{
-				current->state = TASK_UNINTERRUPTIBLE;
-				schedule_timeout(HZ/20);
-			}
-
 			/* Enable variable rate mode */
 			i810_ac97_set(codec, AC97_EXTENDED_STATUS, 9);
 			i810_ac97_set(codec,AC97_EXTENDED_STATUS,
@@ -1996,6 +2135,7 @@
 MODULE_DESCRIPTION("Intel 810 audio support");
 MODULE_PARM(ftsodell, "i");
 MODULE_PARM(clocking, "i");
+MODULE_PARM(strict_clocking, "i");
 
 #define I810_MODULE_NAME "intel810_audio"
 
@@ -2036,6 +2176,7 @@
 		init_waitqueue_head(&dmabuf->wait);
 		init_MUTEX(&state->open_sem);
 		dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT;
+		dmabuf->trigger = PCM_ENABLE_OUTPUT;
 		i810_set_dac_rate(state, 48000);
 		if(prog_dmabuf(state, 0) != 0) {
 			goto config_out_nodmabuf;
@@ -2044,25 +2185,30 @@
 			goto config_out;
 		}
 		dmabuf->count = dmabuf->dmasize;
+		outb(31,card->iobase+dmabuf->write_channel->port+OFF_LVI);
 		save_flags(flags);
 		cli();
 		start_dac(state);
-		offset = i810_get_dma_addr(state);
+		offset = i810_get_dma_addr(state, 0);
 		mdelay(50);
-		new_offset = i810_get_dma_addr(state);
+		new_offset = i810_get_dma_addr(state, 0);
 		stop_dac(state);
 		outb(2,card->iobase+dmabuf->write_channel->port+OFF_CR);
 		restore_flags(flags);
 		i = new_offset - offset;
+#ifdef DEBUG
 		printk("i810_audio: %d bytes in 50 milliseconds\n", i);
+#endif
+		if(i == 0)
+			goto config_out;
 		i = i / 4 * 20;
 		if (i > 48500 || i < 47500) {
 			clocking = clocking * clocking / i;
-			printk("i810_audio: setting clocking to %d to compensate\n", clocking);
+			printk("i810_audio: setting clocking to %d\n", clocking);
 		}
-config_out_nodmabuf:
-		dealloc_dmabuf(state);
 config_out:
+		dealloc_dmabuf(state);
+config_out_nodmabuf:
 		state->card->free_pcm_channel(state->card,state->dmabuf.write_channel->num);
 		kfree(state);
 		card->states[0] = NULL;
diff -u --recursive --new-file v2.4.3/linux/drivers/sound/mad16.c linux/drivers/sound/mad16.c
--- v2.4.3/linux/drivers/sound/mad16.c	Sat Dec 30 11:23:14 2000
+++ linux/drivers/sound/mad16.c	Fri Apr  6 10:51:19 2001
@@ -423,72 +423,80 @@
 
 	DDB(printk("Detect using password = 0xE5\n"));
 	
-	if (!detect_mad16())	/* No luck. Try different model */
-	{
-		board_type = C928;
+	if (detect_mad16()) {
+		return 1;
+	}
+	
+	board_type = C928;
 
-		DDB(printk("Detect using password = 0xE2\n"));
+	DDB(printk("Detect using password = 0xE2\n"));
 
-		if (!detect_mad16())
-		{
-			board_type = C929;
-
-			DDB(printk("Detect using password = 0xE3\n"));
-
-			if (!detect_mad16())
-			{
-				if (inb(PASSWD_REG) != 0xff)
-					return 0;
-
-				/*
-				 * First relocate MC# registers to 0xe0e/0xe0f, disable password 
-				 */
-
-				outb((0xE4), PASSWD_REG);
-				outb((0x80), PASSWD_REG);
-
-				board_type = C930;
-
-				DDB(printk("Detect using password = 0xE4\n"));
-
-				for (i = 0xf8d; i <= 0xf93; i++)
-					DDB(printk("port %03x = %02x\n", i, mad_read(i)));
-                                if(!detect_mad16()) {
-
-				  /* The C931 has the password reg at F8D */
-				  outb((0xE4), 0xF8D);
-				  outb((0x80), 0xF8D);
-				  DDB(printk("Detect using password = 0xE4 for C931\n"));
-
-				  if (!detect_mad16()) {
-				    board_type = C924;
-				    c924pnp++;
-				    DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n"));
-				    if (!detect_mad16()) {
-				      c924pnp=0;
-				      return 0;
-				    }
-				  
-				    DDB(printk("mad16.c: 82C924 PnP detected\n"));
-				  }
-				}
-				else
-				  DDB(printk("mad16.c: 82C930 detected\n"));
-			} else
-				DDB(printk("mad16.c: 82C929 detected\n"));
-		} else {
-			unsigned char model;
+	if (detect_mad16())
+	{
+		unsigned char model;
 
-			if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) {
-				DDB(printk("mad16.c: Mozart detected\n"));
-				board_type = MOZART;
-			} else {
-				DDB(printk("mad16.c: 82C928 detected???\n"));
-				board_type = C928;
-			}
+		if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) {
+			DDB(printk("mad16.c: Mozart detected\n"));
+			board_type = MOZART;
+		} else {
+			DDB(printk("mad16.c: 82C928 detected???\n"));
+			board_type = C928;
 		}
+		return 1;
+	}
+
+	board_type = C929;
+
+	DDB(printk("Detect using password = 0xE3\n"));
+
+	if (detect_mad16())
+	{
+		DDB(printk("mad16.c: 82C929 detected\n"));
+		return 1;
+	}
+
+	if (inb(PASSWD_REG) != 0xff)
+		return 0;
+
+	/*
+	 * First relocate MC# registers to 0xe0e/0xe0f, disable password 
+	 */
+
+	outb((0xE4), PASSWD_REG);
+	outb((0x80), PASSWD_REG);
+
+	board_type = C930;
+
+	DDB(printk("Detect using password = 0xE4\n"));
+
+	for (i = 0xf8d; i <= 0xf93; i++)
+		DDB(printk("port %03x = %02x\n", i, mad_read(i)));
+
+        if(detect_mad16()) {
+		DDB(printk("mad16.c: 82C930 detected\n"));
+		return 1;
 	}
-	return 1;
+
+	/* The C931 has the password reg at F8D */
+	outb((0xE4), 0xF8D);
+	outb((0x80), 0xF8D);
+	DDB(printk("Detect using password = 0xE4 for C931\n"));
+
+	if (detect_mad16()) {
+		return 1;
+	}
+
+	board_type = C924;
+	c924pnp++;
+	DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n"));
+	if (detect_mad16()) {
+		DDB(printk("mad16.c: 82C924 PnP detected\n"));
+		return 1;
+	}
+	
+	c924pnp=0;
+
+	return 0;
 }
 
 static int __init probe_mad16(struct address_info *hw_config)
diff -u --recursive --new-file v2.4.3/linux/drivers/sound/sound_core.c linux/drivers/sound/sound_core.c
--- v2.4.3/linux/drivers/sound/sound_core.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/sound/sound_core.c	Fri Apr  6 10:51:19 2001
@@ -168,7 +168,11 @@
 	spin_unlock(&sound_loader_lock);
 	
 	if(r<0)
+	{
 		kfree(s);
+		return r;
+	}
+	
 	if (r == low)
 		sprintf (name_buf, "%s", name);
 	else
diff -u --recursive --new-file v2.4.3/linux/drivers/sound/trident.c linux/drivers/sound/trident.c
--- v2.4.3/linux/drivers/sound/trident.c	Tue Mar 20 12:04:59 2001
+++ linux/drivers/sound/trident.c	Fri Apr  6 10:51:19 2001
@@ -2890,7 +2890,7 @@
 	{	
 		if ((i*4 == T4D_MISCINT) || (i*4 == T4D_STOP_A) || (i*4 == T4D_START_A))
 			continue;
-		ali_registers.global_regs[i] = inl(TRID_REG(card, i*4));
+		outl(ali_registers.global_regs[i], TRID_REG(card, i*4));
 	}
 	
 	//start HW channel
diff -u --recursive --new-file v2.4.3/linux/drivers/sound/ymfpci.c linux/drivers/sound/ymfpci.c
--- v2.4.3/linux/drivers/sound/ymfpci.c	Tue Mar 20 11:29:01 2001
+++ linux/drivers/sound/ymfpci.c	Fri Apr  6 10:51:19 2001
@@ -1853,6 +1853,7 @@
 		return -ENXIO;
 	}
 
+	unit = NULL;	/* gcc warns */
 	for (list = ymf_devs.next; list != &ymf_devs; list = list->next) {
 		unit = list_entry(list, ymfpci_t, ymf_devs);
 		if (((unit->dev_audio ^ minor) & ~0x0F) == 0)
@@ -2147,8 +2148,8 @@
 	ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
 
 	/* setup DSP instruction code */
-	for (i = 0; i < YDSXG_DSPLENGTH; i++)
-		ymfpci_writel(codec, YDSXGR_DSPINSTRAM + i, DspInst[i >> 2]);
+	for (i = 0; i < YDSXG_DSPLENGTH / 4; i++)
+		ymfpci_writel(codec, YDSXGR_DSPINSTRAM + (i << 2), DspInst[i]);
 
 	switch (codec->pci->device) {
 	case PCI_DEVICE_ID_YAMAHA_724F:
@@ -2163,11 +2164,11 @@
 
 	if (ver_1e) {
 		/* setup control instruction code */
-		for (i = 0; i < YDSXG_CTRLLENGTH; i++)
-			ymfpci_writel(codec, YDSXGR_CTRLINSTRAM + i, CntrlInst1E[i >> 2]);
+		for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
+			ymfpci_writel(codec, YDSXGR_CTRLINSTRAM + (i << 2), CntrlInst1E[i]);
 	} else {
-		for (i = 0; i < YDSXG_CTRLLENGTH; i++)
-			ymfpci_writel(codec, YDSXGR_CTRLINSTRAM + i, CntrlInst[i >> 2]);
+		for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
+			ymfpci_writel(codec, YDSXGR_CTRLINSTRAM + (i << 2), CntrlInst[i]);
 	}
 
 	ymfpci_enable_dsp(codec);
diff -u --recursive --new-file v2.4.3/linux/drivers/sound/ymfpci_image.h linux/drivers/sound/ymfpci_image.h
--- v2.4.3/linux/drivers/sound/ymfpci_image.h	Sun Dec  3 23:58:10 2000
+++ linux/drivers/sound/ymfpci_image.h	Fri Apr  6 10:51:19 2001
@@ -1,7 +1,7 @@
 #ifndef _HWMCODE_
 #define _HWMCODE_
 
-static unsigned long int	DspInst[] = {
+static u32 DspInst[YDSXG_DSPLENGTH / 4] = {
 	0x00000081, 0x000001a4, 0x0000000a, 0x0000002f,
 	0x00080253, 0x01800317, 0x0000407b, 0x0000843f,
 	0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c,
@@ -12,7 +12,7 @@
 	0x00000000, 0x00000000, 0x00000000, 0x00000000
 };
 
-static unsigned long int	CntrlInst[] = {
+static u32 CntrlInst[YDSXG_CTRLLENGTH / 4] = {
 	0x000007, 0x240007, 0x0C0007, 0x1C0007,
 	0x060007, 0x700002, 0x000020, 0x030040,
 	0x007104, 0x004286, 0x030040, 0x000F0D,
@@ -791,7 +791,7 @@
 // 04/09  creat
 // 04/12  stop nise fix
 // 06/21  WorkingOff timming
-static unsigned long int	CntrlInst1E[] = {
+static u32 CntrlInst1E[YDSXG_CTRLLENGTH / 4] = {
 	0x000007, 0x240007, 0x0C0007, 0x1C0007,
 	0x060007, 0x700002, 0x000020, 0x030040,
 	0x007104, 0x004286, 0x030040, 0x000F0D,
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/devio.c linux/drivers/usb/devio.c
--- v2.4.3/linux/drivers/usb/devio.c	Fri Mar 23 11:50:01 2001
+++ linux/drivers/usb/devio.c	Fri Apr  6 15:51:50 2001
@@ -175,6 +175,7 @@
                 return NULL;
         memset(as, 0, assize);
         as->urb.number_of_packets = numisoframes;
+        spin_lock_init(&as->urb.lock);
         return as;
 }
 
@@ -250,10 +251,6 @@
         struct dev_state *ps = as->ps;
 	struct siginfo sinfo;
 
-#if 1
-	printk(KERN_DEBUG "usbdevfs: async_completed: status %d errcount %d actlen %d pipe 0x%x\n", 
-	       urb->status, urb->error_count, urb->actual_length, urb->pipe);
-#endif
         spin_lock(&ps->lock);
         list_del(&as->asynclist);
         list_add_tail(&as->asynclist, &ps->async_completed);
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/Config.in linux/drivers/usb/serial/Config.in
--- v2.4.3/linux/drivers/usb/serial/Config.in	Mon Mar 19 17:21:54 2001
+++ linux/drivers/usb/serial/Config.in	Fri Apr  6 15:51:50 2001
@@ -6,7 +6,9 @@
 
 tristate 'USB Serial Converter support' CONFIG_USB_SERIAL $CONFIG_USB
 if [ "$CONFIG_USB_SERIAL" != "n" ]; then
-  bool '  USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG
+  if [ "$CONFIG_USB_SERIAL" = "y" ]; then
+     bool '  USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG
+  fi
   bool '  USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC
   dep_tristate '  USB Belkin and Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
   dep_tristate '  USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/belkin_sa.c linux/drivers/usb/serial/belkin_sa.c
--- v2.4.3/linux/drivers/usb/serial/belkin_sa.c	Fri Mar 23 11:50:01 2001
+++ linux/drivers/usb/serial/belkin_sa.c	Fri Apr  6 15:51:50 2001
@@ -68,13 +68,13 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/usb.h>
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
- 	#define DEBUG
+ 	static int debug = 1;
 #else
- 	#undef DEBUG
+ 	static int debug;
 #endif
-#include <linux/usb.h>
 
 #include "usb-serial.h"
 #include "belkin_sa.h"
@@ -607,3 +607,7 @@
 module_exit (belkin_sa_exit);
 
 MODULE_DESCRIPTION("USB Belkin Serial converter driver");
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/belkin_sa.h linux/drivers/usb/serial/belkin_sa.h
--- v2.4.3/linux/drivers/usb/serial/belkin_sa.h	Tue Mar 20 14:02:46 2001
+++ linux/drivers/usb/serial/belkin_sa.h	Fri Apr  6 15:51:52 2001
@@ -43,7 +43,7 @@
 #define PERACOM_PID	0x0001	/* Peracom's single port serial converter's id */
 
 #define GOHUBS_VID	0x0921	/* GoHubs vendor id */
-#define GOHUBS_PID	0x0100	/* GoHubs single port serial converter's id (identical to the Peracom device) */
+#define GOHUBS_PID	0x1000	/* GoHubs single port serial converter's id (identical to the Peracom device) */
 
 /* Vendor Request Interface */
 #define BELKIN_SA_SET_BAUDRATE_REQUEST	0  /* Set baud rate */
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/digi_acceleport.c linux/drivers/usb/serial/digi_acceleport.c
--- v2.4.3/linux/drivers/usb/serial/digi_acceleport.c	Tue Mar 20 14:02:46 2001
+++ linux/drivers/usb/serial/digi_acceleport.c	Fri Apr  6 15:51:50 2001
@@ -241,14 +241,14 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/tqueue.h>
+#include <linux/usb.h>
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
-	#define DEBUG
+	static int debug = 1;
 #else
-	#undef DEBUG
+	static int debug;
 #endif
 
-#include <linux/usb.h>
 #include "usb-serial.h"
 
 
@@ -2085,4 +2085,7 @@
 
 MODULE_AUTHOR("Peter Berger <pberger@brimson.com>, Al Borchers <borchers@steinerpoint.com>");
 MODULE_DESCRIPTION("Digi AccelePort USB-2/USB-4 Serial Converter driver");
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
 
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/empeg.c linux/drivers/usb/serial/empeg.c
--- v2.4.3/linux/drivers/usb/serial/empeg.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/usb/serial/empeg.c	Fri Apr  6 15:51:51 2001
@@ -55,12 +55,13 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/usb.h>
+
 #ifdef CONFIG_USB_SERIAL_DEBUG
-	#define DEBUG
+	static int debug = 1;
 #else
-	#undef DEBUG
+	static int debug;
 #endif
-#include <linux/usb.h>
 
 #include "usb-serial.h"
 
@@ -705,3 +706,7 @@
 
 MODULE_AUTHOR("Gary Brubaker <xavyer@ix.netcom.com>");
 MODULE_DESCRIPTION("USB Empeg Mark I/II Driver");
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/ftdi_sio.c linux/drivers/usb/serial/ftdi_sio.c
--- v2.4.3/linux/drivers/usb/serial/ftdi_sio.c	Sun Mar 25 18:14:21 2001
+++ linux/drivers/usb/serial/ftdi_sio.c	Fri Apr  6 15:51:51 2001
@@ -78,16 +78,15 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/usb.h>
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
-	#define DEBUG
+	static int debug = 1;
 #else
-	#undef DEBUG
+	static int debug;
 #endif
-#include <linux/usb.h>
 
 #include "usb-serial.h"
-
 #include "ftdi_sio.h"
 
 
@@ -881,3 +880,7 @@
 
 MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>");
 MODULE_DESCRIPTION("USB FTDI RS232 converters driver");
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/io_edgeport.c linux/drivers/usb/serial/io_edgeport.c
--- v2.4.3/linux/drivers/usb/serial/io_edgeport.c	Sun Mar 25 18:24:31 2001
+++ linux/drivers/usb/serial/io_edgeport.c	Fri Apr  6 15:51:51 2001
@@ -239,15 +239,14 @@
 #include <linux/serial.h>
 #include <linux/ioctl.h>
 #include <linux/proc_fs.h>
+#include <linux/usb.h>
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
-	#define DEBUG
+	static int debug = 1;
 #else
-	#undef DEBUG
+	static int debug;
 #endif
 
-#include <linux/usb.h>
-
 #include "usb-serial.h"
 
 #include "io_edgeport.h"
@@ -279,6 +278,9 @@
 MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com> and David Iacovelli");
 MODULE_DESCRIPTION("Edgeport USB Serial Driver");
 
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
 #define MAX_NAME_LEN		64
 
 
@@ -474,47 +476,6 @@
 
 
 
-
-#ifdef DEBUG
-
-/* Dump a buffer in HEX and Ascii */
-void DbgDisplayBuffer( void *pBuffer, __u32 Len )
-{
-	char    DisplayBuf[80];
-	char *  pStr = DisplayBuf;
-	__u8 *pBuf = pBuffer; 
-	__u32   i;
-	__u8   d;
-
-	while (Len) {
-		// Init for new line
-		memset( DisplayBuf, ' ', sizeof( DisplayBuf ));
-		DisplayBuf[79]=0;
-		pStr = DisplayBuf;
-		pStr[54] = '[';
-		pStr[71] = ']';
-
-		for ( i = 0; i < MIN(16, Len) ; i++ ) {
-			d = (__u8)(*pBuf >> 4);
-			pStr[(i*3)+0] = (char)((d < 10) ? d+'0' : d -10 + 'A');
-			d = (__u8)(*pBuf & 0xf);
-			pStr[(i*3)+1] = (char)((d < 10) ? d+'0' : d -10 + 'A');
-
-			if (*pBuf > 31 && *pBuf < 127)
-				pStr[i+55]=*pBuf;
-			else
-				pStr[i+55]='.';
-
-			pBuf++;
-		}
-		Len -= i;
-		dbg("%s", DisplayBuf );
-	}
-}
-#endif
-
-
-
 // ************************************************************************
 // ************************************************************************
 // ************************************************************************
@@ -745,7 +706,6 @@
 			break;
 	}
 
-#ifdef DEBUG
 	// Dump Product Info structure
 	dbg("**Product Information:");
 	dbg("  ProductId             %x", product_info->ProductId );
@@ -770,7 +730,6 @@
 	    product_info->ManufactureDescDate[2]+1900);
 	dbg("  iDownloadFile         0x%x",     product_info->iDownloadFile);
 
-#endif
 }
 
 
@@ -812,14 +771,7 @@
 
 	// process this interrupt-read even if there are no ports open
 	if (length) {
-#ifdef DEBUG
-		int i;
-		printk (KERN_DEBUG __FILE__ ": "__FUNCTION__" - length = %d, data = ", length);
-		for (i = 0; i < length; ++i) {
-			printk ("%.2x ", data[i]);
-		}
-		printk ("\n");
-#endif
+		usb_serial_debug_data (__FILE__, __FUNCTION__, length, data);
 
 		if (length > 1) {
 			bytes_avail = data[0] | (data[1] << 8);
@@ -894,13 +846,7 @@
 	if (urb->actual_length) {
 		raw_data_length = urb->actual_length;
 
-#ifdef DEBUG
-		{
-//			int i;
-			dbg (__FUNCTION__" - length = %d, data = ", raw_data_length);
-//			DbgDisplayBuffer((void *)data, raw_data_length);
-		}
-#endif
+		usb_serial_debug_data (__FILE__, __FUNCTION__, raw_data_length, data);
 
 		/* decrement our rxBytes available by the number that we just got */
 		edge_serial->rxBytesAvail -= raw_data_length;
@@ -976,10 +922,8 @@
 
 	dbg(__FUNCTION__);
 
-#ifdef DEBUG	
 	CmdUrbs--;
 	dbg(__FUNCTION__" - FREE URB %p (outstanding %d)", urb, CmdUrbs);
-#endif
 
 
 	/* if this urb had a transfer buffer already (old transfer) free it */
@@ -1412,12 +1356,9 @@
 		// No need to check for wrap since we can not get to end of fifo in this part
 	}
 
-#ifdef DEBUG
 	if (copySize) {
-		dbg (__FUNCTION__" - length = %d, data = ", copySize);
-		DbgDisplayBuffer((void *)data, copySize);
+		usb_serial_debug_data (__FILE__, __FUNCTION__, copySize, data);
 	}
-#endif
 
 	send_more_port_data((struct edgeport_serial *)port->serial->private, edge_port);
 
@@ -1519,12 +1460,9 @@
 		fifo->count -= secondhalf;
 	}
 
-#ifdef DEBUG
 	if (count) {
-		dbg (__FUNCTION__" - length = %d, data = ", count);
-		DbgDisplayBuffer((void *)&buffer[2], count);
+		usb_serial_debug_data (__FILE__, __FUNCTION__, count, &buffer[2]);
 	}
-#endif
 
 	/* fill up the urb with all of our data and submit it */
 	FILL_BULK_URB (urb, edge_serial->serial->dev, 
@@ -2498,16 +2436,7 @@
 	urb_t *urb;
 	int timeout;
 
-#ifdef DEBUG
-	if (length) {
-		int i;
-		printk (KERN_DEBUG __FILE__ ": "__FUNCTION__" - length = %d, buffer = ", length);
-		for (i = 0; i < length; ++i) {
-			printk ("%.2x ", buffer[i]);
-		}
-		printk ("\n");
-	}
-#endif
+	usb_serial_debug_data (__FILE__, __FUNCTION__, length, buffer);
 
 	/* Allocate our next urb */
 	urb = usb_alloc_urb (0);
@@ -2857,7 +2786,6 @@
 	if (response < 1) {
 		err("error in getting manufacturer descriptor");
 	} else {
-#ifdef DEBUG
 		char string[30];
 		dbg("**Manufacturer Descriptor");
 		dbg("  RomSize:        %dK", edge_serial->manuf_descriptor.RomSize);
@@ -2875,7 +2803,6 @@
 		dbg("  UartType:       %d", edge_serial->manuf_descriptor.UartType);
 		dbg("  IonPid:         %d", edge_serial->manuf_descriptor.IonPid);
 		dbg("  IonConfig:      %d", edge_serial->manuf_descriptor.IonConfig);
-#endif
 	}
 }
 
@@ -3138,6 +3065,4 @@
 
 module_init(edgeport_init);
 module_exit(edgeport_exit);
-
-
 
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/keyspan.c linux/drivers/usb/serial/keyspan.c
--- v2.4.3/linux/drivers/usb/serial/keyspan.c	Fri Mar  2 17:50:22 2001
+++ linux/drivers/usb/serial/keyspan.c	Fri Apr  6 15:51:51 2001
@@ -62,13 +62,14 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-
-#define DEBUG
-/*  #ifdef CONFIG_USB_SERIAL_DEBUG */
-	#define DEBUG
-/*  #endif */
 #include <linux/usb.h>
 
+#ifdef CONFIG_USB_SERIAL_DEBUG
+	static int debug = 1;
+#else
+	static int debug;
+#endif
+
 #include "usb-serial.h"
 #include "keyspan.h"
 
@@ -1671,3 +1672,7 @@
 		kfree(port->private);
 	}
 }
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/keyspan_pda.c linux/drivers/usb/serial/keyspan_pda.c
--- v2.4.3/linux/drivers/usb/serial/keyspan_pda.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/usb/serial/keyspan_pda.c	Fri Apr  6 15:51:51 2001
@@ -67,13 +67,14 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/tqueue.h>
+#include <linux/usb.h>
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
-	#define DEBUG
+	static int debug = 1;
 #else
-	#undef DEBUG
+	static int debug;
 #endif
-#include <linux/usb.h>
+
 
 struct ezusb_hex_record {
 	__u16 address;
@@ -82,7 +83,6 @@
 };
 
 #include "keyspan_pda_fw.h"
-
 #include "usb-serial.h"
 
 struct keyspan_pda_private {
@@ -823,3 +823,7 @@
 
 MODULE_AUTHOR("Brian Warner <warner@lothar.com>");
 MODULE_DESCRIPTION("USB Keyspan PDA Converter driver");
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/mct_u232.c linux/drivers/usb/serial/mct_u232.c
--- v2.4.3/linux/drivers/usb/serial/mct_u232.c	Fri Mar 23 11:50:01 2001
+++ linux/drivers/usb/serial/mct_u232.c	Fri Apr  6 15:51:52 2001
@@ -53,13 +53,13 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/usb.h>
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
- 	#define DEBUG
+ 	static int debug = 1;
 #else
- 	#undef DEBUG
+ 	static int debug;
 #endif
-#include <linux/usb.h>
 
 #include "usb-serial.h"
 #include "mct_u232.h"
@@ -848,3 +848,7 @@
 MODULE_PARM_DESC(write_blocking, 
 		 "The write function will block to write out all data");
 #endif
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/omninet.c linux/drivers/usb/serial/omninet.c
--- v2.4.3/linux/drivers/usb/serial/omninet.c	Sun Mar 25 18:14:21 2001
+++ linux/drivers/usb/serial/omninet.c	Fri Apr  6 15:51:52 2001
@@ -43,17 +43,14 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
-
+#include <linux/usb.h>
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
-	#define isalpha(x) ( ( x > 96 && x < 123) || ( x > 64 && x < 91) || (x > 47 && x < 58) )
-	#define DEBUG
+	static int debug = 1;
 #else
-	#undef DEBUG
+	static int debug;
 #endif
 
-#include <linux/usb.h>
-
 #include "usb-serial.h"
 
 
@@ -252,8 +249,7 @@
 		return;
 	}
 
-#ifdef DEBUG
-	if(header->oh_xxx != 0x30) {
+	if ((debug) && (header->oh_xxx != 0x30)) {
 		if (urb->actual_length) {
 			printk (KERN_DEBUG __FILE__ ": omninet_read %d: ", header->oh_len);
 			for (i = 0; i < (header->oh_len + OMNINET_HEADERLEN); i++) {
@@ -262,7 +258,6 @@
 			printk ("\n");
 		}
 	}
-#endif
 
 	if (urb->actual_length && header->oh_len) {
 		for (i = 0; i < header->oh_len; i++) {
@@ -413,4 +408,7 @@
 
 module_init(omninet_init);
 module_exit(omninet_exit);
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
 
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/usb-serial.h linux/drivers/usb/serial/usb-serial.h
--- v2.4.3/linux/drivers/usb/serial/usb-serial.h	Mon Dec 11 13:17:29 2000
+++ linux/drivers/usb/serial/usb-serial.h	Fri Apr  6 15:51:52 2001
@@ -219,15 +219,24 @@
 
 static inline void usb_serial_debug_data (const char *file, const char *function, int size, const unsigned char *data)
 {
-#ifdef CONFIG_USB_SERIAL_DEBUG
 	int i;
+
+	if (!debug)
+		return;
+	
 	printk (KERN_DEBUG "%s: %s - length = %d, data = ", file, function, size);
 	for (i = 0; i < size; ++i) {
 		printk ("%.2x ", data[i]);
 	}
 	printk ("\n");
-#endif
 }
+
+
+/* Use our own dbg macro */
+#undef dbg
+#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0)
+
+
 
 #endif	/* ifdef __LINUX_USB_SERIAL_H */
 
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/usbserial.c linux/drivers/usb/serial/usbserial.c
--- v2.4.3/linux/drivers/usb/serial/usbserial.c	Fri Mar 23 11:50:01 2001
+++ linux/drivers/usb/serial/usbserial.c	Fri Apr  6 15:51:52 2001
@@ -272,19 +272,24 @@
 #include <linux/spinlock.h>
 #include <linux/list.h>
 #include <linux/smp_lock.h>
+#include <linux/usb.h>
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
-	#define DEBUG
+	static int debug = 1;
 #else
-	#undef DEBUG
+	static int debug;
 #endif
-#include <linux/usb.h>
+
+#include "usb-serial.h"
+
 
 /* Module information */
 MODULE_AUTHOR("Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux-usb/");
 MODULE_DESCRIPTION("USB Serial Driver");
 
-#include "usb-serial.h"
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
 
 #define MAX(a,b)	(((a)>(b))?(a):(b))
 
@@ -364,6 +369,7 @@
 static struct termios *		serial_termios[SERIAL_TTY_MINORS];
 static struct termios *		serial_termios_locked[SERIAL_TTY_MINORS];
 static struct usb_serial	*serial_table[SERIAL_TTY_MINORS];	/* initially all NULL */
+
 
 LIST_HEAD(usb_serial_driver_list);
 
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/visor.c linux/drivers/usb/serial/visor.c
--- v2.4.3/linux/drivers/usb/serial/visor.c	Mon Mar 19 17:21:54 2001
+++ linux/drivers/usb/serial/visor.c	Fri Apr  6 15:51:52 2001
@@ -92,16 +92,15 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/usb.h>
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
-	#define DEBUG
+	static int debug = 1;
 #else
-	#undef DEBUG
+	static int debug;
 #endif
-#include <linux/usb.h>
 
 #include "usb-serial.h"
-
 #include "visor.h"
 
 #define MIN(a,b)                (((a)<(b))?(a):(b))
@@ -689,3 +688,7 @@
 
 MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>");
 MODULE_DESCRIPTION("USB HandSpring Visor driver");
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/serial/whiteheat.c linux/drivers/usb/serial/whiteheat.c
--- v2.4.3/linux/drivers/usb/serial/whiteheat.c	Fri Mar 23 11:50:01 2001
+++ linux/drivers/usb/serial/whiteheat.c	Fri Apr  6 15:51:52 2001
@@ -67,18 +67,16 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/usb.h>
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
-	#define DEBUG
+	static int debug = 1;
 #else
-	#undef DEBUG
+	static int debug;
 #endif
-#include <linux/usb.h>
 
 #include "usb-serial.h"
-
 #include "whiteheat_fw.h"		/* firmware for the ConnectTech WhiteHEAT device */
-
 #include "whiteheat.h"			/* WhiteHEAT specific commands */
 
 #define CONNECT_TECH_VENDOR_ID		0x0710
@@ -634,3 +632,7 @@
 
 MODULE_AUTHOR("Greg Kroah-Hartman <greg@kroah.com>");
 MODULE_DESCRIPTION("USB ConnectTech WhiteHEAT driver");
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
diff -u --recursive --new-file v2.4.3/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- v2.4.3/linux/fs/binfmt_elf.c	Mon Mar 19 17:05:16 2001
+++ linux/fs/binfmt_elf.c	Thu Apr  5 17:13:23 2001
@@ -140,7 +140,7 @@
 	 */
 	sp = (elf_addr_t *)((~15UL & (unsigned long)(u_platform)) - 16UL);
 	csp = sp;
-	csp -= ((exec ? DLINFO_ITEMS*2 : 4) + (k_platform ? 2 : 0));
+	csp -= DLINFO_ITEMS*2 + (k_platform ? 2 : 0);
 	csp -= envc+1;
 	csp -= argc+1;
 	csp -= (!ibcs ? 3 : 1);	/* argc itself */
@@ -160,25 +160,20 @@
 		sp -= 2;
 		NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform);
 	}
-	sp -= 3*2;
-	NEW_AUX_ENT(0, AT_HWCAP, hwcap);
-	NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE);
-	NEW_AUX_ENT(2, AT_CLKTCK, CLOCKS_PER_SEC);
-
-	if (exec) {
-		sp -= 10*2;
-
-		NEW_AUX_ENT(0, AT_PHDR, load_addr + exec->e_phoff);
-		NEW_AUX_ENT(1, AT_PHENT, sizeof (struct elf_phdr));
-		NEW_AUX_ENT(2, AT_PHNUM, exec->e_phnum);
-		NEW_AUX_ENT(3, AT_BASE, interp_load_addr);
-		NEW_AUX_ENT(4, AT_FLAGS, 0);
-		NEW_AUX_ENT(5, AT_ENTRY, load_bias + exec->e_entry);
-		NEW_AUX_ENT(6, AT_UID, (elf_addr_t) current->uid);
-		NEW_AUX_ENT(7, AT_EUID, (elf_addr_t) current->euid);
-		NEW_AUX_ENT(8, AT_GID, (elf_addr_t) current->gid);
-		NEW_AUX_ENT(9, AT_EGID, (elf_addr_t) current->egid);
-	}
+	sp -= DLINFO_ITEMS*2;
+	NEW_AUX_ENT( 0, AT_HWCAP, hwcap);
+	NEW_AUX_ENT( 1, AT_PAGESZ, ELF_EXEC_PAGESIZE);
+	NEW_AUX_ENT( 2, AT_CLKTCK, CLOCKS_PER_SEC);
+	NEW_AUX_ENT( 3, AT_PHDR, load_addr + exec->e_phoff);
+	NEW_AUX_ENT( 4, AT_PHENT, sizeof (struct elf_phdr));
+	NEW_AUX_ENT( 5, AT_PHNUM, exec->e_phnum);
+	NEW_AUX_ENT( 6, AT_BASE, interp_load_addr);
+	NEW_AUX_ENT( 7, AT_FLAGS, 0);
+	NEW_AUX_ENT( 8, AT_ENTRY, load_bias + exec->e_entry);
+	NEW_AUX_ENT( 9, AT_UID, (elf_addr_t) current->uid);
+	NEW_AUX_ENT(10, AT_EUID, (elf_addr_t) current->euid);
+	NEW_AUX_ENT(11, AT_GID, (elf_addr_t) current->gid);
+	NEW_AUX_ENT(12, AT_EGID, (elf_addr_t) current->egid);
 #undef NEW_AUX_ENT
 
 	sp -= envc+1;
@@ -694,7 +689,7 @@
 	  create_elf_tables((char *)bprm->p,
 			bprm->argc,
 			bprm->envc,
-			(interpreter_type == INTERPRETER_ELF ? &elf_ex : NULL),
+			&elf_ex,
 			load_addr, load_bias,
 			interp_load_addr,
 			(interpreter_type == INTERPRETER_AOUT ? 0 : 1));
diff -u --recursive --new-file v2.4.3/linux/fs/coda/dir.c linux/fs/coda/dir.c
--- v2.4.3/linux/fs/coda/dir.c	Fri Dec 29 14:07:57 2000
+++ linux/fs/coda/dir.c	Fri Apr  6 10:51:19 2001
@@ -92,7 +92,7 @@
 
 
 /* inode operations for directories */
-/* acces routines: lookup, readlink, permission */
+/* access routines: lookup, readlink, permission */
 static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
 {
 	struct inode *res_inode = NULL;
diff -u --recursive --new-file v2.4.3/linux/fs/coda/psdev.c linux/fs/coda/psdev.c
--- v2.4.3/linux/fs/coda/psdev.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/coda/psdev.c	Fri Apr  6 10:51:19 2001
@@ -195,7 +195,7 @@
 		goto out;
 	}
 
-	/* adjust outsize. is this usefull ?? */
+	/* adjust outsize. is this useful ?? */
         req->uc_outSize = nbytes;	
         req->uc_flags |= REQ_WRITE;
 	count = nbytes;
diff -u --recursive --new-file v2.4.3/linux/fs/nfs/flushd.c linux/fs/nfs/flushd.c
--- v2.4.3/linux/fs/nfs/flushd.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/nfs/flushd.c	Tue Apr  3 13:45:37 2001
@@ -177,14 +177,14 @@
  out:
 }
 
+/* Protect me using the BKL */
 void inode_remove_flushd(struct inode *inode)
 {
 	struct nfs_reqlist	*cache = NFS_REQUESTLIST(inode);
 	struct inode		**q;
 
-	lock_kernel();
 	if (!(NFS_FLAGS(inode) & NFS_INO_FLUSH))
-		goto out;
+		return;
 
 	q = &cache->inodes;
 	while (*q && *q != inode)
@@ -194,8 +194,6 @@
 		NFS_FLAGS(inode) &= ~NFS_INO_FLUSH;
 		iput(inode);
 	}
- out:
-	unlock_kernel();
 }
 
 void inode_schedule_scan(struct inode *inode, unsigned long time)
diff -u --recursive --new-file v2.4.3/linux/fs/nfs/read.c linux/fs/nfs/read.c
--- v2.4.3/linux/fs/nfs/read.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/nfs/read.c	Tue Apr  3 13:45:37 2001
@@ -335,7 +335,9 @@
 
 	rpc_clnt_sigmask(clnt, &oldset);
 	rpc_call_setup(task, &msg, 0);
+	lock_kernel();
 	rpc_execute(task);
+	unlock_kernel();
 	rpc_clnt_sigunmask(clnt, &oldset);
 	return 0;
 out_bad:
diff -u --recursive --new-file v2.4.3/linux/fs/nfs/write.c linux/fs/nfs/write.c
--- v2.4.3/linux/fs/nfs/write.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/nfs/write.c	Tue Apr  3 13:45:37 2001
@@ -183,7 +183,6 @@
 	if (file)
 		cred = nfs_file_cred(file);
 
-	lock_kernel();
 	dprintk("NFS:      nfs_writepage_sync(%x/%Ld %d@%Ld)\n",
 		inode->i_dev, (long long)NFS_FILEID(inode),
 		count, (long long)(page_offset(page) + offset));
@@ -228,7 +227,6 @@
 io_error:
 	kunmap(page);
 
-	unlock_kernel();
 	return written? written : result;
 }
 
@@ -282,16 +280,17 @@
 	if (page->index >= end_index+1 || !offset)
 		goto out;
 do_it:
-	if (!PageError(page) && NFS_SERVER(inode)->rsize >= PAGE_CACHE_SIZE) {
+	lock_kernel();
+	if (NFS_SERVER(inode)->rsize >= PAGE_CACHE_SIZE) {
 		err = nfs_writepage_async(NULL, inode, page, 0, offset);
 		if (err >= 0)
-			goto out_ok;
-	}
-	err = nfs_writepage_sync(NULL, inode, page, 0, offset); 
-	if ( err == offset) {
-out_ok:
-		err = 0;
+			err = 0;
+	} else {
+		err = nfs_writepage_sync(NULL, inode, page, 0, offset); 
+		if (err == offset)
+			err = 0;
 	}
+	unlock_kernel();
 out:
 	UnlockPage(page);
 	return err; 
@@ -1172,7 +1171,9 @@
 
 	rpc_clnt_sigmask(clnt, &oldset);
 	rpc_call_setup(task, &msg, 0);
+	lock_kernel();
 	rpc_execute(task);
+	unlock_kernel();
 	rpc_clnt_sigunmask(clnt, &oldset);
 	return 0;
  out_bad:
@@ -1394,7 +1395,9 @@
 	dprintk("NFS: %4d initiated commit call\n", task->tk_pid);
 	rpc_clnt_sigmask(clnt, &oldset);
 	rpc_call_setup(task, &msg, 0);
+	lock_kernel();
 	rpc_execute(task);
+	unlock_kernel();
 	rpc_clnt_sigunmask(clnt, &oldset);
 	return 0;
  out_bad:
diff -u --recursive --new-file v2.4.3/linux/fs/nls/Config.in linux/fs/nls/Config.in
--- v2.4.3/linux/fs/nls/Config.in	Fri Dec 29 14:35:47 2000
+++ linux/fs/nls/Config.in	Fri Apr  6 10:51:19 2001
@@ -37,23 +37,26 @@
   tristate 'Codepage 865 (Norwegian, Danish)'      CONFIG_NLS_CODEPAGE_865
   tristate 'Codepage 866 (Cyrillic/Russian)'       CONFIG_NLS_CODEPAGE_866
   tristate 'Codepage 869 (Greek)'                  CONFIG_NLS_CODEPAGE_869
-  tristate 'Codepage 874 (Thai)'                   CONFIG_NLS_CODEPAGE_874
-  tristate 'Codepage 932 (Shift-JIS, EUC-JP)'      CONFIG_NLS_CODEPAGE_932
-  tristate 'Codepage 936 (GBK)'                    CONFIG_NLS_CODEPAGE_936
-  tristate 'Codepage 949 (UnifiedHangul)'          CONFIG_NLS_CODEPAGE_949
-  tristate 'Codepage 950 (Big5)'                   CONFIG_NLS_CODEPAGE_950
+  tristate 'Simplified Chinese charset (CP936, GB2312)' CONFIG_NLS_CODEPAGE_936
+  tristate 'Traditional Chinese charset (Big5)'    CONFIG_NLS_CODEPAGE_950
+  tristate 'Japanese charsets (Shift-JIS, EUC-JP)' CONFIG_NLS_CODEPAGE_932
+  tristate 'Korean charset (CP949, EUC-KR)'        CONFIG_NLS_CODEPAGE_949
+  tristate 'Thai charset (CP874, TIS-620)'         CONFIG_NLS_CODEPAGE_874
+  tristate 'Hebrew charsets (ISO-8859-8, CP1255)'  CONFIG_NLS_ISO8859_8
+  tristate 'Windows CP1251 (Bulgarian, Belarussian)' CONFIG_NLS_CODEPAGE_1251
   tristate 'NLS ISO 8859-1  (Latin 1; Western European Languages)' CONFIG_NLS_ISO8859_1
   tristate 'NLS ISO 8859-2  (Latin 2; Slavic/Central European Languages)' CONFIG_NLS_ISO8859_2
   tristate 'NLS ISO 8859-3  (Latin 3; Esperanto, Galician, Maltese, Turkish)' CONFIG_NLS_ISO8859_3
-  tristate 'NLS ISO 8859-4  (Latin 4; Estonian, Latvian, Lithuanian)' CONFIG_NLS_ISO8859_4
+  tristate 'NLS ISO 8859-4  (Latin 4; old Baltic charset)' CONFIG_NLS_ISO8859_4
   tristate 'NLS ISO 8859-5  (Cyrillic)'             CONFIG_NLS_ISO8859_5
   tristate 'NLS ISO 8859-6  (Arabic)'               CONFIG_NLS_ISO8859_6
   tristate 'NLS ISO 8859-7  (Modern Greek)'         CONFIG_NLS_ISO8859_7
-  tristate 'NLS ISO 8859-8  (Hebrew)'               CONFIG_NLS_ISO8859_8
   tristate 'NLS ISO 8859-9  (Latin 5; Turkish)'     CONFIG_NLS_ISO8859_9
+  tristate 'NLS ISO 8859-13 (Latin 7; Baltic)'      CONFIG_NLS_ISO8859_13
   tristate 'NLS ISO 8859-14 (Latin 8; Celtic)'      CONFIG_NLS_ISO8859_14
   tristate 'NLS ISO 8859-15 (Latin 9; Western European Languages with Euro)' CONFIG_NLS_ISO8859_15
   tristate 'NLS KOI8-R (Russian)'                   CONFIG_NLS_KOI8_R
+  tristate 'NLS KOI8-U (Ukrainian)'                 CONFIG_NLS_KOI8_U
   tristate 'NLS UTF8'                               CONFIG_NLS_UTF8
   endmenu
 fi
diff -u --recursive --new-file v2.4.3/linux/fs/nls/Makefile linux/fs/nls/Makefile
--- v2.4.3/linux/fs/nls/Makefile	Fri Dec 29 14:07:23 2000
+++ linux/fs/nls/Makefile	Fri Apr  6 10:51:19 2001
@@ -22,7 +22,7 @@
 obj-$(CONFIG_NLS_CODEPAGE_865)	+= nls_cp865.o
 obj-$(CONFIG_NLS_CODEPAGE_866)	+= nls_cp866.o
 obj-$(CONFIG_NLS_CODEPAGE_869)	+= nls_cp869.o
-obj-$(CONFIG_NLS_CODEPAGE_874)	+= nls_cp874.o
+obj-$(CONFIG_NLS_CODEPAGE_874)	+= nls_cp874.o nls_tis-620.o
 obj-$(CONFIG_NLS_CODEPAGE_932)	+= nls_cp932.o nls_sjis.o nls_euc-jp.o
 obj-$(CONFIG_NLS_CODEPAGE_936)	+= nls_cp936.o nls_gb2312.o
 obj-$(CONFIG_NLS_CODEPAGE_949)	+= nls_cp949.o nls_euc-kr.o
@@ -32,7 +32,6 @@
 obj-$(CONFIG_NLS_CODEPAGE_1252)	+= nls_cp1252.o
 obj-$(CONFIG_NLS_CODEPAGE_1253)	+= nls_cp1253.o
 obj-$(CONFIG_NLS_CODEPAGE_1254)	+= nls_cp1254.o
-obj-$(CONFIG_NLS_CODEPAGE_1255)	+= nls_cp1255.o
 obj-$(CONFIG_NLS_CODEPAGE_1256)	+= nls_cp1256.o
 obj-$(CONFIG_NLS_CODEPAGE_1257)	+= nls_cp1257.o
 obj-$(CONFIG_NLS_CODEPAGE_1258)	+= nls_cp1258.o
@@ -43,12 +42,14 @@
 obj-$(CONFIG_NLS_ISO8859_5)	+= nls_iso8859-5.o
 obj-$(CONFIG_NLS_ISO8859_6)	+= nls_iso8859-6.o
 obj-$(CONFIG_NLS_ISO8859_7)	+= nls_iso8859-7.o
-obj-$(CONFIG_NLS_ISO8859_8)	+= nls_iso8859-8.o
+obj-$(CONFIG_NLS_ISO8859_8)	+= nls_cp1255.o nls_iso8859-8.o
 obj-$(CONFIG_NLS_ISO8859_9)	+= nls_iso8859-9.o
 obj-$(CONFIG_NLS_ISO8859_10)	+= nls_iso8859-10.o
+obj-$(CONFIG_NLS_ISO8859_13)	+= nls_iso8859-13.o
 obj-$(CONFIG_NLS_ISO8859_14)	+= nls_iso8859-14.o
 obj-$(CONFIG_NLS_ISO8859_15)	+= nls_iso8859-15.o
 obj-$(CONFIG_NLS_KOI8_R)	+= nls_koi8-r.o
+obj-$(CONFIG_NLS_KOI8_U)	+= nls_koi8-u.o
 obj-$(CONFIG_NLS_ABC)		+= nls_abc.o
 obj-$(CONFIG_NLS_UTF8)		+= nls_utf8.o
 
diff -u --recursive --new-file v2.4.3/linux/fs/nls/nls_cp1251.c linux/fs/nls/nls_cp1251.c
--- v2.4.3/linux/fs/nls/nls_cp1251.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/nls/nls_cp1251.c	Fri Apr  6 10:51:19 2001
@@ -0,0 +1,317 @@
+/*
+ * linux/fs/nls_cp1251.c
+ *
+ * Charset cp1251 translation tables.
+ * Generated automatically from the Unicode and charset
+ * tables from the Unicode Organization (www.unicode.org).
+ * The Unicode to charset table has only exact mappings.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/nls.h>
+#include <linux/errno.h>
+
+static wchar_t charset2uni[256] = {
+	/* 0x00*/
+	0x0000, 0x0001, 0x0002, 0x0003, 
+	0x0004, 0x0005, 0x0006, 0x0007, 
+	0x0008, 0x0009, 0x000a, 0x000b, 
+	0x000c, 0x000d, 0x000e, 0x000f, 
+	/* 0x10*/
+	0x0010, 0x0011, 0x0012, 0x0013, 
+	0x0014, 0x0015, 0x0016, 0x0017, 
+	0x0018, 0x0019, 0x001a, 0x001b, 
+	0x001c, 0x001d, 0x001e, 0x001f, 
+	/* 0x20*/
+	0x0020, 0x0021, 0x0022, 0x0023, 
+	0x0024, 0x0025, 0x0026, 0x0027, 
+	0x0028, 0x0029, 0x002a, 0x002b, 
+	0x002c, 0x002d, 0x002e, 0x002f, 
+	/* 0x30*/
+	0x0030, 0x0031, 0x0032, 0x0033, 
+	0x0034, 0x0035, 0x0036, 0x0037, 
+	0x0038, 0x0039, 0x003a, 0x003b, 
+	0x003c, 0x003d, 0x003e, 0x003f, 
+	/* 0x40*/
+	0x0040, 0x0041, 0x0042, 0x0043, 
+	0x0044, 0x0045, 0x0046, 0x0047, 
+	0x0048, 0x0049, 0x004a, 0x004b, 
+	0x004c, 0x004d, 0x004e, 0x004f, 
+	/* 0x50*/
+	0x0050, 0x0051, 0x0052, 0x0053, 
+	0x0054, 0x0055, 0x0056, 0x0057, 
+	0x0058, 0x0059, 0x005a, 0x005b, 
+	0x005c, 0x005d, 0x005e, 0x005f, 
+	/* 0x60*/
+	0x0060, 0x0061, 0x0062, 0x0063, 
+	0x0064, 0x0065, 0x0066, 0x0067, 
+	0x0068, 0x0069, 0x006a, 0x006b, 
+	0x006c, 0x006d, 0x006e, 0x006f, 
+	/* 0x70*/
+	0x0070, 0x0071, 0x0072, 0x0073, 
+	0x0074, 0x0075, 0x0076, 0x0077, 
+	0x0078, 0x0079, 0x007a, 0x007b, 
+	0x007c, 0x007d, 0x007e, 0x007f, 
+	/* 0x80*/
+	0x0402, 0x0403, 0x201a, 0x0453, 
+	0x201e, 0x2026, 0x2020, 0x2021, 
+	0x20ac, 0x2030, 0x0409, 0x2039, 
+	0x040a, 0x040c, 0x040b, 0x040f, 
+	/* 0x90*/
+	0x0452, 0x2018, 0x2019, 0x201c, 
+	0x201d, 0x2022, 0x2013, 0x2014, 
+	0x0000, 0x2122, 0x0459, 0x203a, 
+	0x045a, 0x045c, 0x045b, 0x045f, 
+	/* 0xa0*/
+	0x00a0, 0x040e, 0x045e, 0x0408, 
+	0x00a4, 0x0490, 0x00a6, 0x00a7, 
+	0x0401, 0x00a9, 0x0404, 0x00ab, 
+	0x00ac, 0x00ad, 0x00ae, 0x0407, 
+	/* 0xb0*/
+	0x00b0, 0x00b1, 0x0406, 0x0456, 
+	0x0491, 0x00b5, 0x00b6, 0x00b7, 
+	0x0451, 0x2116, 0x0454, 0x00bb, 
+	0x0458, 0x0405, 0x0455, 0x0457, 
+	/* 0xc0*/
+	0x0410, 0x0411, 0x0412, 0x0413, 
+	0x0414, 0x0415, 0x0416, 0x0417, 
+	0x0418, 0x0419, 0x041a, 0x041b, 
+	0x041c, 0x041d, 0x041e, 0x041f, 
+	/* 0xd0*/
+	0x0420, 0x0421, 0x0422, 0x0423, 
+	0x0424, 0x0425, 0x0426, 0x0427, 
+	0x0428, 0x0429, 0x042a, 0x042b, 
+	0x042c, 0x042d, 0x042e, 0x042f, 
+	/* 0xe0*/
+	0x0430, 0x0431, 0x0432, 0x0433, 
+	0x0434, 0x0435, 0x0436, 0x0437, 
+	0x0438, 0x0439, 0x043a, 0x043b, 
+	0x043c, 0x043d, 0x043e, 0x043f, 
+	/* 0xf0*/
+	0x0440, 0x0441, 0x0442, 0x0443, 
+	0x0444, 0x0445, 0x0446, 0x0447, 
+	0x0448, 0x0449, 0x044a, 0x044b, 
+	0x044c, 0x044d, 0x044e, 0x044f, 
+};
+
+static unsigned char page00[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
+	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
+	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
+	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */
+	0x00, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */
+	0xb0, 0xb1, 0x00, 0x00, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
+	0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
+	0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
+	0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+	0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
+	0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
+	0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */
+	0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
+	0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */
+	0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
+};
+
+static unsigned char page04[256] = {
+	0x00, 0xa8, 0x80, 0x81, 0xaa, 0xbd, 0xb2, 0xaf, /* 0x00-0x07 */
+	0xa3, 0x8a, 0x8c, 0x8e, 0x8d, 0x00, 0xa1, 0x8f, /* 0x08-0x0f */
+	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x10-0x17 */
+	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x18-0x1f */
+	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x20-0x27 */
+	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0x28-0x2f */
+	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x30-0x37 */
+	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x38-0x3f */
+	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x40-0x47 */
+	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0x48-0x4f */
+	0x00, 0xb8, 0x90, 0x83, 0xba, 0xbe, 0xb3, 0xbf, /* 0x50-0x57 */
+	0xbc, 0x9a, 0x9c, 0x9e, 0x9d, 0x00, 0xa2, 0x9f, /* 0x58-0x5f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0xa5, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+};
+
+static unsigned char page20[256] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+	0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */
+	0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+	0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+	0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+};
+
+static unsigned char page21[256] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x00, /* 0x10-0x17 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
+	0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+};
+
+static unsigned char *page_uni2charset[256] = {
+	page00, NULL,   NULL,   NULL,   page04, NULL,   NULL,   NULL,   
+	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	page20, page21, NULL,	NULL,   NULL,   NULL,   NULL,   NULL,   
+};
+
+static unsigned char charset2lower[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */
+	0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+	0x90, 0x83, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */
+	0x88, 0x89, 0x9a, 0x8b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x88-0x8f */
+	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */
+	0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */
+	0xa0, 0xa2, 0xa2, 0xbc, 0xa4, 0xb4, 0xa6, 0xa7, /* 0xa0-0xa7 */
+	0xb8, 0xa9, 0xba, 0xab, 0xac, 0xad, 0xae, 0xbf, /* 0xa8-0xaf */
+	0xb0, 0xb1, 0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
+	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbe, 0xbe, 0xbf, /* 0xb8-0xbf */
+	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xc0-0xc7 */
+	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xc8-0xcf */
+	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xd0-0xd7 */
+	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xd8-0xdf */
+	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */
+	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */
+	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */
+	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
+};
+
+static unsigned char charset2upper[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */
+	0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+	0x80, 0x81, 0x82, 0x81, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */
+	0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */
+	0x80, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */
+	0x98, 0x99, 0x8a, 0x9b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x98-0x9f */
+	0xa0, 0xa1, 0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
+	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
+	0xb0, 0xb1, 0xb2, 0xb2, 0xa5, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
+	0xa8, 0xb9, 0xaa, 0xbb, 0xa3, 0xbd, 0xbd, 0xaf, /* 0xb8-0xbf */
+	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */
+	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */
+	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */
+	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */
+	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xe0-0xe7 */
+	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xe8-0xef */
+	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xf0-0xf7 */
+	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xf8-0xff */
+};
+
+static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
+{
+	unsigned char *uni2charset;
+	unsigned char cl = uni & 0x00ff;
+	unsigned char ch = (uni & 0xff00) >> 8;
+
+	if (boundlen <= 0)
+		return -ENAMETOOLONG;
+
+	uni2charset = page_uni2charset[ch];
+	if (uni2charset && uni2charset[cl])
+		out[0] = uni2charset[cl];
+	else
+		return -EINVAL;
+	return 1;
+}
+
+static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
+{
+	*uni = charset2uni[*rawstring];
+	if (*uni == 0x0000)
+		return -EINVAL;
+	return 1;
+}
+
+static struct nls_table table = {
+	"cp1251",
+	uni2char,
+	char2uni,
+	charset2lower,
+	charset2upper,
+	THIS_MODULE,
+};
+
+static int __init init_nls_cp1251(void)
+{
+	return register_nls(&table);
+}
+
+static void __exit exit_nls_cp1251(void)
+{
+	unregister_nls(&table);
+}
+
+module_init(init_nls_cp1251)
+module_exit(exit_nls_cp1251)
+
+/*
+ * 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
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v2.4.3/linux/fs/nls/nls_cp1255.c linux/fs/nls/nls_cp1255.c
--- v2.4.3/linux/fs/nls/nls_cp1255.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/nls/nls_cp1255.c	Fri Apr  6 10:51:19 2001
@@ -0,0 +1,398 @@
+/*
+ * linux/fs/nls_cp1255.c
+ *
+ * Charset cp1255 translation tables.
+ * The Unicode to charset table has only exact mappings.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/nls.h>
+#include <linux/errno.h>
+
+static wchar_t charset2uni[256] = {
+	/* 0x00*/
+	0x0000, 0x0001, 0x0002, 0x0003,
+	0x0004, 0x0005, 0x0006, 0x0007,
+	0x0008, 0x0009, 0x000a, 0x000b,
+	0x000c, 0x000d, 0x000e, 0x000f,
+	/* 0x10*/
+	0x0010, 0x0011, 0x0012, 0x0013,
+	0x0014, 0x0015, 0x0016, 0x0017,
+	0x0018, 0x0019, 0x001a, 0x001b,
+	0x001c, 0x001d, 0x001e, 0x001f,
+	/* 0x20*/
+	0x0020, 0x0021, 0x0022, 0x0023,
+	0x0024, 0x0025, 0x0026, 0x0027,
+	0x0028, 0x0029, 0x002a, 0x002b,
+	0x002c, 0x002d, 0x002e, 0x002f,
+	/* 0x30*/
+	0x0030, 0x0031, 0x0032, 0x0033,
+	0x0034, 0x0035, 0x0036, 0x0037,
+	0x0038, 0x0039, 0x003a, 0x003b,
+	0x003c, 0x003d, 0x003e, 0x003f,
+	/* 0x40*/
+	0x0040, 0x0041, 0x0042, 0x0043,
+	0x0044, 0x0045, 0x0046, 0x0047,
+	0x0048, 0x0049, 0x004a, 0x004b,
+	0x004c, 0x004d, 0x004e, 0x004f,
+	/* 0x50*/
+	0x0050, 0x0051, 0x0052, 0x0053,
+	0x0054, 0x0055, 0x0056, 0x0057,
+	0x0058, 0x0059, 0x005a, 0x005b,
+	0x005c, 0x005d, 0x005e, 0x005f,
+	/* 0x60*/
+	0x0060, 0x0061, 0x0062, 0x0063,
+	0x0064, 0x0065, 0x0066, 0x0067,
+	0x0068, 0x0069, 0x006a, 0x006b,
+	0x006c, 0x006d, 0x006e, 0x006f,
+	/* 0x70*/
+	0x0070, 0x0071, 0x0072, 0x0073,
+	0x0074, 0x0075, 0x0076, 0x0077,
+	0x0078, 0x0079, 0x007a, 0x007b,
+	0x007c, 0x007d, 0x007e, 0x007f,
+	/* 0x80*/
+	0x20ac, 0x0000, 0x201a, 0x0192,
+	0x201e, 0x2026, 0x2020, 0x2021,
+	0x02c6, 0x2030, 0x0000, 0x2039,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	/* 0x90*/
+	0x0000, 0x2018, 0x2019, 0x201c,
+	0x201d, 0x2022, 0x2013, 0x2014,
+	0x02dc, 0x2122, 0x0000, 0x203a,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	/* 0xa0*/
+	0x00a0, 0x00a1, 0x00a2, 0x00a3,
+	0x20aa, 0x00a5, 0x00a6, 0x00a7,
+	0x00a8, 0x00a9, 0x00d7, 0x00ab,
+	0x00ac, 0x00ad, 0x00ae, 0x203e,
+	/* 0xb0*/
+	0x00b0, 0x00b1, 0x00b2, 0x00b3,
+	0x00b4, 0x00b5, 0x00b6, 0x00b7,
+	0x00b8, 0x00b9, 0x00f7, 0x00bb,
+	0x00bc, 0x00bd, 0x00be, 0x00bf,
+	/* 0xc0*/
+	0x05b0, 0x05b1, 0x05b2, 0x05b3,
+	0x05b4, 0x05b5, 0x05b6, 0x05b7,
+	0x05b8, 0x05b9, 0x0000, 0x05bb,
+	0x05bc, 0x05bd, 0x05be, 0x05bf,
+	/* 0xd0*/
+	0x05c0, 0x05c1, 0x05c2, 0x05c3,
+	0x05f0, 0x05f1, 0x05f2, 0x05f3,
+	0x05f4, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x2017,
+	/* 0xe0*/
+	0x05d0, 0x05d1, 0x05d2, 0x05d3,
+	0x05d4, 0x05d5, 0x05d6, 0x05d7,
+	0x05d8, 0x05d9, 0x05da, 0x05db,
+	0x05dc, 0x05dd, 0x05de, 0x05df,
+	/* 0xf0*/
+	0x05e0, 0x05e1, 0x05e2, 0x05e3,
+	0x05e4, 0x05e5, 0x05e6, 0x05e7,
+	0x05e8, 0x05e9, 0x05ea, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned char page00[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
+	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
+	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
+	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0xa0, 0x00, 0xa2, 0xa3, 0x00, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
+	0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */
+	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
+	0xb8, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, /* 0xd0-0xd7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, /* 0xf0-0xf7 */
+};
+
+static unsigned char page01[256] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+};
+
+static unsigned char page02[256] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, /* 0xc0-0xc7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
+	0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
+};
+
+static unsigned char page05[256] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
+	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xb0-0xb7 */
+	0xc8, 0xc9, 0x00, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xb8-0xbf */
+	0xd0, 0xd1, 0xd2, 0xd3, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xd0-0xd7 */
+	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xd8-0xdf */
+	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xe0-0xe7 */
+	0xf8, 0xf9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
+	0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */
+};
+
+static unsigned char page20[256] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xfe, /* 0x08-0x0f */
+	0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+	0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */
+	0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+	0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+	0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
+	0x00, 0x00, 0xa4, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
+};
+
+static unsigned char page21[256] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x00, /* 0x10-0x17 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
+	0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+};
+
+static unsigned char *page_uni2charset[256] = {
+	page00, NULL,   NULL,   NULL,   NULL,   page05, NULL,   NULL,   
+	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	page20, page21, NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+};
+
+static unsigned char charset2lower[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x40-0x47 */
+	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x48-0x4f */
+	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x50-0x57 */
+	0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
+	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
+	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
+	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
+	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
+	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
+	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */
+	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */
+	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */
+	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */
+	0xf8, 0xf9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
+};
+
+static unsigned char charset2upper[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */
+	0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
+	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
+	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0x00, 0xb6, 0xb7, /* 0xb0-0xb7 */
+	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */
+	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */
+	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */
+	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */
+	0xf8, 0xf9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
+};
+
+static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
+{
+	unsigned char *uni2charset;
+	unsigned char cl = uni & 0x00ff;
+	unsigned char ch = (uni & 0xff00) >> 8;
+
+	if (boundlen <= 0)
+		return -ENAMETOOLONG;
+
+	uni2charset = page_uni2charset[ch];
+	if (uni2charset && uni2charset[cl])
+		out[0] = uni2charset[cl];
+	else
+		return -EINVAL;
+	return 1;
+}
+
+static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
+{
+	*uni = charset2uni[*rawstring];
+	if (*uni == 0x0000)
+		return -EINVAL;
+	return 1;
+}
+
+static struct nls_table table = {
+	"cp1255",
+	uni2char,
+	char2uni,
+	charset2lower,
+	charset2upper,
+	THIS_MODULE,
+};
+
+static int __init init_nls_cp1255(void)
+{
+	return register_nls(&table);
+}
+
+static void __exit exit_nls_cp1255(void)
+{
+	unregister_nls(&table);
+}
+
+module_init(init_nls_cp1255)
+module_exit(exit_nls_cp1255)
+
+/*
+ * 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
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v2.4.3/linux/fs/nls/nls_cp932.c linux/fs/nls/nls_cp932.c
--- v2.4.3/linux/fs/nls/nls_cp932.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_cp932.c	Fri Apr  6 10:51:19 2001
@@ -7819,73 +7819,68 @@
 };
 
 static int uni2char(const wchar_t uni,
-			unsigned char *out, int boundlen)
+		    unsigned char *out, int boundlen)
 {
 	unsigned char *uni2charset;
 	unsigned char cl = uni&0xFF;
 	unsigned char ch = (uni>>8)&0xFF;
-	int n;
 
 	if (boundlen <= 0)
 		return -ENAMETOOLONG;
 
 	if (ch == 0xFF && 0x61 <= cl && cl <= 0x9F) {
 		out[0] = cl + 0x40;
-		n = 1;
-		return n;
+		return 1;
 	}
 	uni2charset = page_uni2charset[ch];
 	if (uni2charset) {
-		if (boundlen <= 1)
+		if (boundlen < 2)
 			return -ENAMETOOLONG;
+
 		out[0] = uni2charset[cl*2];
 		out[1] = uni2charset[cl*2+1];
 		if (out[0] == 0x00 && out[1] == 0x00)
 			return -EINVAL;
-		n = 2;
-	} else if (ch==0 && cl) {
+		return 2;
+	} else if ((ch == 0) && (cl <= 0x7F)) {
 		out[0] = cl;
-		n = 1;
+		return 1;
 	}
 	else
 		return -EINVAL;
-
-	return n;
 }
 
 static int char2uni(const unsigned char *rawstring, int boundlen,
-			wchar_t *uni)
+		    wchar_t *uni)
 {
 	unsigned char ch, cl;
 	wchar_t *charset2uni;
-	int n;
 
 	if (boundlen <= 0)
 		return -ENAMETOOLONG;
 
-	if (boundlen == 1) {
+	if (rawstring[0] <= 0x7F) {
 		*uni = rawstring[0];
 		return 1;
 	}
+	if (0xA1 <= rawstring[0] && rawstring[0] <= 0xDF) {
+		*uni = 0xFF00 | (rawstring[0] - 0x40);
+		return 1;
+	}
 
+	if (boundlen < 2)
+		return -ENAMETOOLONG;
 	ch = rawstring[0];
 	cl = rawstring[1];
-	if (0xA1 <= ch && ch <= 0xDF) {
-		*uni = 0xFF00 | (ch - 0x40);
-		n = 1;
-		return n;
-	}
 	charset2uni = page_charset2uni[ch];
 	if (charset2uni && cl) {
 		*uni = charset2uni[cl];
 		if (*uni == 0x0000)
 			return -EINVAL;
-		n = 2;
-	} else{
-		*uni = ch;
-		n = 1;
+		return 2;
 	}
-	return n;
+	else
+		return -EINVAL;
 }
 
 static struct nls_table table = {
diff -u --recursive --new-file v2.4.3/linux/fs/nls/nls_euc-jp.c linux/fs/nls/nls_euc-jp.c
--- v2.4.3/linux/fs/nls/nls_euc-jp.c	Mon Oct 16 12:58:51 2000
+++ linux/fs/nls/nls_euc-jp.c	Fri Apr  6 10:51:19 2001
@@ -1,5 +1,9 @@
 /*
  * linux/fs/nls_euc-jp.c
+ *
+ * Added `OSF/JVC Recommended Code Set Conversion Specification
+ * between Japanese EUC and Shift-JIS' support: <hirofumi@mail.parknet.co.jp>
+ * (http://www.opengroup.or.jp/jvc/cde/sjis-euc-e.html)
  */
 
 #include <linux/module.h>
@@ -10,49 +14,463 @@
 
 static struct nls_table *p_nls;
 
+#define IS_SJIS_LOW_BYTE(l)	((0x40 <= (l)) && ((l) <= 0xFC) && ((l) != 0x7F))
+/* JIS X 0208 (include NEC spesial characters) */
+#define IS_SJIS_JISX0208(h, l)	((((0x81 <= (h)) && ((h) <= 0x9F))	\
+				 || ((0xE0 <= (h)) && ((h) <= 0xEA)))	\
+				 && IS_SJIS_LOW_BYTE(l))
+#define IS_SJIS_JISX0201KANA(c)	((0xA1 <= (c)) && ((c) <= 0xDF))
+#define IS_SJIS_UDC_LOW(h, l)	(((0xF0 <= (h)) && ((h) <= 0xF4))	\
+				 && IS_SJIS_LOW_BYTE(l))
+#define IS_SJIS_UDC_HI(h, l)	(((0xF5 <= (h)) && ((h) <= 0xF9))	\
+				 && IS_SJIS_LOW_BYTE(l))
+#define IS_SJIS_IBM(h, l)	(((0xFA <= (h)) && ((h) <= 0xFC))	\
+				 && IS_SJIS_LOW_BYTE(l))
+#define IS_SJIS_NECIBM(h, l)	(((0xED <= (h)) && ((h) <= 0xEE))	\
+				 && IS_SJIS_LOW_BYTE(l))
+#define MAP_SJIS2EUC(sjis_hi, sjis_lo, sjis_p, euc_hi, euc_lo, euc_p) {		\
+	if ((sjis_lo) >= 0x9F) {						\
+		(euc_hi) = (sjis_hi) * 2 - (((sjis_p) * 2 - (euc_p)) - 1);	\
+		(euc_lo) = (sjis_lo) + 2;					\
+	} else {								\
+		(euc_hi) = (sjis_hi) * 2 - ((sjis_p) * 2 - (euc_p));		\
+		(euc_lo) = (sjis_lo) + ((sjis_lo) >= 0x7F ? 0x60 : 0x61);	\
+	}									\
+} while(0)
 
 #define SS2		(0x8E)		/* Single Shift 2 */
 #define SS3		(0x8F)		/* Single Shift 3 */
+#define IS_EUC_BYTE(c)		((0xA1 <= (c)) && ((c) <= 0xFE))
+#define IS_EUC_JISX0208(h, l)	(IS_EUC_BYTE(h) && IS_EUC_BYTE(l))
+#define IS_EUC_JISX0201KANA(h, l)	(((h) == SS2) && (0xA1 <= (l) && (l) <= 0xDF))
+#define IS_EUC_UDC_LOW(h, l)	(((0xF5 <= (h)) && ((h) <= 0xFE))	\
+				 && IS_EUC_BYTE(l))
+#define IS_EUC_UDC_HI(h, l)	IS_EUC_UDC_LOW(h, l) /* G3 block */
+#define MAP_EUC2SJIS(euc_hi, euc_lo, euc_p, sjis_hi, sjis_lo, sjis_p) {		\
+	if ((euc_hi) & 1) {							\
+		(sjis_hi) = (euc_hi) / 2 + ((sjis_p) - (euc_p) / 2);		\
+		(sjis_lo) = (euc_lo) - ((euc_lo) >= 0xE0 ? 0x60 : 0x61);	\
+	} else {								\
+		(sjis_hi) = (euc_hi) / 2 + (((sjis_p) - (euc_p) / 2) - 1);	\
+		(sjis_lo) = (euc_lo) - 2;					\
+	}									\
+} while(0)
+
+/* SJIS IBM extended characters to EUC map */
+static unsigned char sjisibm2euc_map[][2] = {
+	{0xF3, 0xF3}, {0xF3, 0xF4}, {0xF3, 0xF5}, {0xF3, 0xF6}, {0xF3, 0xF7},
+	{0xF3, 0xF8}, {0xF3, 0xF9}, {0xF3, 0xFA}, {0xF3, 0xFB}, {0xF3, 0xFC},
+	{0xF3, 0xFD}, {0xF3, 0xFE}, {0xF4, 0xA1}, {0xF4, 0xA2}, {0xF4, 0xA3},
+	{0xF4, 0xA4}, {0xF4, 0xA5}, {0xF4, 0xA6}, {0xF4, 0xA7}, {0xF4, 0xA8},
+	{0xA2, 0xCC}, {0xA2, 0xC3}, {0xF4, 0xA9}, {0xF4, 0xAA}, {0xF4, 0xAB},
+	{0xF4, 0xAC}, {0xF4, 0xAD}, {0xA2, 0xE8}, {0xD4, 0xE3}, {0xDC, 0xDF},
+	{0xE4, 0xE9}, {0xE3, 0xF8}, {0xD9, 0xA1}, {0xB1, 0xBB}, {0xF4, 0xAE},
+	{0xC2, 0xAD}, {0xC3, 0xFC}, {0xE4, 0xD0}, {0xC2, 0xBF}, {0xBC, 0xF4},
+	{0xB0, 0xA9}, {0xB0, 0xC8}, {0xF4, 0xAF}, {0xB0, 0xD2}, {0xB0, 0xD4},
+	{0xB0, 0xE3}, {0xB0, 0xEE}, {0xB1, 0xA7}, {0xB1, 0xA3}, {0xB1, 0xAC},
+	{0xB1, 0xA9}, {0xB1, 0xBE}, {0xB1, 0xDF}, {0xB1, 0xD8}, {0xB1, 0xC8},
+	{0xB1, 0xD7}, {0xB1, 0xE3}, {0xB1, 0xF4}, {0xB1, 0xE1}, {0xB2, 0xA3},
+	{0xF4, 0xB0}, {0xB2, 0xBB}, {0xB2, 0xE6}, {0x00, 0x00}, {0xB2, 0xED},
+	{0xB2, 0xF5}, {0xB2, 0xFC}, {0xF4, 0xB1}, {0xB3, 0xB5}, {0xB3, 0xD8},
+	{0xB3, 0xDB}, {0xB3, 0xE5}, {0xB3, 0xEE}, {0xB3, 0xFB}, {0xF4, 0xB2},
+	{0xF4, 0xB3}, {0xB4, 0xC0}, {0xB4, 0xC7}, {0xB4, 0xD0}, {0xB4, 0xDE},
+	{0xF4, 0xB4}, {0xB5, 0xAA}, {0xF4, 0xB5}, {0xB5, 0xAF}, {0xB5, 0xC4},
+	{0xB5, 0xE8}, {0xF4, 0xB6}, {0xB7, 0xC2}, {0xB7, 0xE4}, {0xB7, 0xE8},
+	{0xB7, 0xE7}, {0xF4, 0xB7}, {0xF4, 0xB8}, {0xF4, 0xB9}, {0xB8, 0xCE},
+	{0xB8, 0xE1}, {0xB8, 0xF5}, {0xB8, 0xF7}, {0xB8, 0xF8}, {0xB8, 0xFC},
+	{0xB9, 0xAF}, {0xB9, 0xB7}, {0xBA, 0xBE}, {0xBA, 0xDB}, {0xCD, 0xAA},
+	{0xBA, 0xE1}, {0xF4, 0xBA}, {0xBA, 0xEB}, {0xBB, 0xB3}, {0xBB, 0xB8},
+	{0xF4, 0xBB}, {0xBB, 0xCA}, {0xF4, 0xBC}, {0xF4, 0xBD}, {0xBB, 0xD0},
+	{0xBB, 0xDE}, {0xBB, 0xF4}, {0xBB, 0xF5}, {0xBB, 0xF9}, {0xBC, 0xE4},
+	{0xBC, 0xED}, {0xBC, 0xFE}, {0xF4, 0xBE}, {0xBD, 0xC2}, {0xBD, 0xE7},
+	{0xF4, 0xBF}, {0xBD, 0xF0}, {0xBE, 0xB0}, {0xBE, 0xAC}, {0xF4, 0xC0},
+	{0xBE, 0xB3}, {0xBE, 0xBD}, {0xBE, 0xCD}, {0xBE, 0xC9}, {0xBE, 0xE4},
+	{0xBF, 0xA8}, {0xBF, 0xC9}, {0xC0, 0xC4}, {0xC0, 0xE4}, {0xC0, 0xF4},
+	{0xC1, 0xA6}, {0xF4, 0xC1}, {0xC1, 0xF5}, {0xC1, 0xFC}, {0xF4, 0xC2},
+	{0xC1, 0xF8}, {0xC2, 0xAB}, {0xC2, 0xA1}, {0xC2, 0xA5}, {0xF4, 0xC3},
+	{0xC2, 0xB8}, {0xC2, 0xBA}, {0xF4, 0xC4}, {0xC2, 0xC4}, {0xC2, 0xD2},
+	{0xC2, 0xD7}, {0xC2, 0xDB}, {0xC2, 0xDE}, {0xC2, 0xED}, {0xC2, 0xF0},
+	{0xF4, 0xC5}, {0xC3, 0xA1}, {0xC3, 0xB5}, {0xC3, 0xC9}, {0xC3, 0xB9},
+	{0xF4, 0xC6}, {0xC3, 0xD8}, {0xC3, 0xFE}, {0xF4, 0xC7}, {0xC4, 0xCC},
+	{0xF4, 0xC8}, {0xC4, 0xD9}, {0xC4, 0xEA}, {0xC4, 0xFD}, {0xF4, 0xC9},
+	{0xC5, 0xA7}, {0xC5, 0xB5}, {0xC5, 0xB6}, {0xF4, 0xCA}, {0xC5, 0xD5},
+	{0xC6, 0xB8}, {0xC6, 0xD7}, {0xC6, 0xE0}, {0xC6, 0xEA}, {0xC6, 0xE3},
+	{0xC7, 0xA1}, {0xC7, 0xAB}, {0xC7, 0xC7}, {0xC7, 0xC3}, {0xC7, 0xCB},
+	{0xC7, 0xCF}, {0xC7, 0xD9}, {0xF4, 0xCB}, {0xF4, 0xCC}, {0xC7, 0xE6},
+	{0xC7, 0xEE}, {0xC7, 0xFC}, {0xC7, 0xEB}, {0xC7, 0xF0}, {0xC8, 0xB1},
+	{0xC8, 0xE5}, {0xC8, 0xF8}, {0xC9, 0xA6}, {0xC9, 0xAB}, {0xC9, 0xAD},
+	{0xF4, 0xCD}, {0xC9, 0xCA}, {0xC9, 0xD3}, {0xC9, 0xE9}, {0xC9, 0xE3},
+	{0xC9, 0xFC}, {0xC9, 0xF4}, {0xC9, 0xF5}, {0xF4, 0xCE}, {0xCA, 0xB3},
+	{0xCA, 0xBD}, {0xCA, 0xEF}, {0xCA, 0xF1}, {0xCB, 0xAE}, {0xF4, 0xCF},
+	{0xCB, 0xCA}, {0xCB, 0xE6}, {0xCB, 0xEA}, {0xCB, 0xF0}, {0xCB, 0xF4},
+	{0xCB, 0xEE}, {0xCC, 0xA5}, {0xCB, 0xF9}, {0xCC, 0xAB}, {0xCC, 0xAE},
+	{0xCC, 0xAD}, {0xCC, 0xB2}, {0xCC, 0xC2}, {0xCC, 0xD0}, {0xCC, 0xD9},
+	{0xF4, 0xD0}, {0xCD, 0xBB}, {0xF4, 0xD1}, {0xCE, 0xBB}, {0xF4, 0xD2},
+	{0xCE, 0xBA}, {0xCE, 0xC3}, {0xF4, 0xD3}, {0xCE, 0xF2}, {0xB3, 0xDD},
+	{0xCF, 0xD5}, {0xCF, 0xE2}, {0xCF, 0xE9}, {0xCF, 0xED}, {0xF4, 0xD4},
+	{0xF4, 0xD5}, {0xF4, 0xD6}, {0x00, 0x00}, {0xF4, 0xD7}, {0xD0, 0xE5},
+	{0xF4, 0xD8}, {0xD0, 0xE9}, {0xD1, 0xE8}, {0xF4, 0xD9}, {0xF4, 0xDA},
+	{0xD1, 0xEC}, {0xD2, 0xBB}, {0xF4, 0xDB}, {0xD3, 0xE1}, {0xD3, 0xE8},
+	{0xD4, 0xA7}, {0xF4, 0xDC}, {0xF4, 0xDD}, {0xD4, 0xD4}, {0xD4, 0xF2},
+	{0xD5, 0xAE}, {0xF4, 0xDE}, {0xD7, 0xDE}, {0xF4, 0xDF}, {0xD8, 0xA2},
+	{0xD8, 0xB7}, {0xD8, 0xC1}, {0xD8, 0xD1}, {0xD8, 0xF4}, {0xD9, 0xC6},
+	{0xD9, 0xC8}, {0xD9, 0xD1}, {0xF4, 0xE0}, {0xF4, 0xE1}, {0xF4, 0xE2},
+	{0xF4, 0xE3}, {0xF4, 0xE4}, {0xDC, 0xD3}, {0xDD, 0xC8}, {0xDD, 0xD4},
+	{0xDD, 0xEA}, {0xDD, 0xFA}, {0xDE, 0xA4}, {0xDE, 0xB0}, {0xF4, 0xE5},
+	{0xDE, 0xB5}, {0xDE, 0xCB}, {0xF4, 0xE6}, {0xDF, 0xB9}, {0xF4, 0xE7},
+	{0xDF, 0xC3}, {0xF4, 0xE8}, {0xF4, 0xE9}, {0xE0, 0xD9}, {0xF4, 0xEA},
+	{0xF4, 0xEB}, {0xE1, 0xE2}, {0xF4, 0xEC}, {0xF4, 0xED}, {0xF4, 0xEE},
+	{0xE2, 0xC7}, {0xE3, 0xA8}, {0xE3, 0xA6}, {0xE3, 0xA9}, {0xE3, 0xAF},
+	{0xE3, 0xB0}, {0xE3, 0xAA}, {0xE3, 0xAB}, {0xE3, 0xBC}, {0xE3, 0xC1},
+	{0xE3, 0xBF}, {0xE3, 0xD5}, {0xE3, 0xD8}, {0xE3, 0xD6}, {0xE3, 0xDF},
+	{0xE3, 0xE3}, {0xE3, 0xE1}, {0xE3, 0xD4}, {0xE3, 0xE9}, {0xE4, 0xA6},
+	{0xE3, 0xF1}, {0xE3, 0xF2}, {0xE4, 0xCB}, {0xE4, 0xC1}, {0xE4, 0xC3},
+	{0xE4, 0xBE}, {0xF4, 0xEF}, {0xE4, 0xC0}, {0xE4, 0xC7}, {0xE4, 0xBF},
+	{0xE4, 0xE0}, {0xE4, 0xDE}, {0xE4, 0xD1}, {0xF4, 0xF0}, {0xE4, 0xDC},
+	{0xE4, 0xD2}, {0xE4, 0xDB}, {0xE4, 0xD4}, {0xE4, 0xFA}, {0xE4, 0xEF},
+	{0xE5, 0xB3}, {0xE5, 0xBF}, {0xE5, 0xC9}, {0xE5, 0xD0}, {0xE5, 0xE2},
+	{0xE5, 0xEA}, {0xE5, 0xEB}, {0xF4, 0xF1}, {0xF4, 0xF2}, {0xF4, 0xF3},
+	{0xE6, 0xE8}, {0xE6, 0xEF}, {0xE7, 0xAC}, {0xF4, 0xF4}, {0xE7, 0xAE},
+	{0xF4, 0xF5}, {0xE7, 0xB1}, {0xF4, 0xF6}, {0xE7, 0xB2}, {0xE8, 0xB1},
+	{0xE8, 0xB6}, {0xF4, 0xF7}, {0xF4, 0xF8}, {0xE8, 0xDD}, {0xF4, 0xF9},
+	{0xF4, 0xFA}, {0xE9, 0xD1}, {0xF4, 0xFB}, {0xE9, 0xED}, {0xEA, 0xCD},
+	{0xF4, 0xFC}, {0xEA, 0xDB}, {0xEA, 0xE6}, {0xEA, 0xEA}, {0xEB, 0xA5},
+	{0xEB, 0xFB}, {0xEB, 0xFA}, {0xF4, 0xFD}, {0xEC, 0xD6}, {0xF4, 0xFE},
+};
+
+#define IS_EUC_IBM2JISX0208(h, l) \
+		(((h) == 0xA2 && (l) == 0xCC) || ((h) == 0xA2 && (l) == 0xE8))
+
+/* EUC to SJIS IBM extended characters map (G3 JIS X 0212 block) */
+static struct {
+	unsigned short euc;
+	unsigned char sjis[2];
+} euc2sjisibm_jisx0212_map[] = {
+	{0xA2C3, {0xFA, 0x55}}, {0xB0A9, {0xFA, 0x68}}, {0xB0C8, {0xFA, 0x69}},
+	{0xB0D2, {0xFA, 0x6B}}, {0xB0D4, {0xFA, 0x6C}}, {0xB0E3, {0xFA, 0x6D}},
+	{0xB0EE, {0xFA, 0x6E}}, {0xB1A3, {0xFA, 0x70}}, {0xB1A7, {0xFA, 0x6F}},
+	{0xB1A9, {0xFA, 0x72}}, {0xB1AC, {0xFA, 0x71}}, {0xB1BB, {0xFA, 0x61}},
+	{0xB1BE, {0xFA, 0x73}}, {0xB1C8, {0xFA, 0x76}}, {0xB1D7, {0xFA, 0x77}},
+	{0xB1D8, {0xFA, 0x75}}, {0xB1DF, {0xFA, 0x74}}, {0xB1E1, {0xFA, 0x7A}},
+	{0xB1E3, {0xFA, 0x78}}, {0xB1F4, {0xFA, 0x79}}, {0xB2A3, {0xFA, 0x7B}},
+	{0xB2BB, {0xFA, 0x7D}}, {0xB2E6, {0xFA, 0x7E}}, {0xB2ED, {0xFA, 0x80}},
+	{0xB2F5, {0xFA, 0x81}}, {0xB2FC, {0xFA, 0x82}}, {0xB3B5, {0xFA, 0x84}},
+	{0xB3D8, {0xFA, 0x85}}, {0xB3DB, {0xFA, 0x86}}, {0xB3DD, {0xFB, 0x77}},
+	{0xB3E5, {0xFA, 0x87}}, {0xB3EE, {0xFA, 0x88}}, {0xB3FB, {0xFA, 0x89}},
+	{0xB4C0, {0xFA, 0x8C}}, {0xB4C7, {0xFA, 0x8D}}, {0xB4D0, {0xFA, 0x8E}},
+	{0xB4DE, {0xFA, 0x8F}}, {0xB5AA, {0xFA, 0x91}}, {0xB5AF, {0xFA, 0x93}},
+	{0xB5C4, {0xFA, 0x94}}, {0xB5E8, {0xFA, 0x95}}, {0xB7C2, {0xFA, 0x97}},
+	{0xB7E4, {0xFA, 0x98}}, {0xB7E7, {0xFA, 0x9A}}, {0xB7E8, {0xFA, 0x99}},
+	{0xB8CE, {0xFA, 0x9E}}, {0xB8E1, {0xFA, 0x9F}}, {0xB8F5, {0xFA, 0xA0}},
+	{0xB8F7, {0xFA, 0xA1}}, {0xB8F8, {0xFA, 0xA2}}, {0xB8FC, {0xFA, 0xA3}},
+	{0xB9AF, {0xFA, 0xA4}}, {0xB9B7, {0xFA, 0xA5}}, {0xBABE, {0xFA, 0xA6}},
+	{0xBADB, {0xFA, 0xA7}}, {0xBAE1, {0xFA, 0xA9}}, {0xBAEB, {0xFA, 0xAB}},
+	{0xBBB3, {0xFA, 0xAC}}, {0xBBB8, {0xFA, 0xAD}}, {0xBBCA, {0xFA, 0xAF}},
+	{0xBBD0, {0xFA, 0xB2}}, {0xBBDE, {0xFA, 0xB3}}, {0xBBF4, {0xFA, 0xB4}},
+	{0xBBF5, {0xFA, 0xB5}}, {0xBBF9, {0xFA, 0xB6}}, {0xBCE4, {0xFA, 0xB7}},
+	{0xBCED, {0xFA, 0xB8}}, {0xBCF4, {0xFA, 0x67}}, {0xBCFE, {0xFA, 0xB9}},
+	{0xBDC2, {0xFA, 0xBB}}, {0xBDE7, {0xFA, 0xBC}}, {0xBDF0, {0xFA, 0xBE}},
+	{0xBEAC, {0xFA, 0xC0}}, {0xBEB0, {0xFA, 0xBF}}, {0xBEB3, {0xFA, 0xC2}},
+	{0xBEBD, {0xFA, 0xC3}}, {0xBEC9, {0xFA, 0xC5}}, {0xBECD, {0xFA, 0xC4}},
+	{0xBEE4, {0xFA, 0xC6}}, {0xBFA8, {0xFA, 0xC7}}, {0xBFC9, {0xFA, 0xC8}},
+	{0xC0C4, {0xFA, 0xC9}}, {0xC0E4, {0xFA, 0xCA}}, {0xC0F4, {0xFA, 0xCB}},
+	{0xC1A6, {0xFA, 0xCC}}, {0xC1F5, {0xFA, 0xCE}}, {0xC1F8, {0xFA, 0xD1}},
+	{0xC1FC, {0xFA, 0xCF}}, {0xC2A1, {0xFA, 0xD3}}, {0xC2A5, {0xFA, 0xD4}},
+	{0xC2AB, {0xFA, 0xD2}}, {0xC2AD, {0xFA, 0x63}}, {0xC2B8, {0xFA, 0xD6}},
+	{0xC2BA, {0xFA, 0xD7}}, {0xC2BF, {0xFA, 0x66}}, {0xC2C4, {0xFA, 0xD9}},
+	{0xC2D2, {0xFA, 0xDA}}, {0xC2D7, {0xFA, 0xDB}}, {0xC2DB, {0xFA, 0xDC}},
+	{0xC2DE, {0xFA, 0xDD}}, {0xC2ED, {0xFA, 0xDE}}, {0xC2F0, {0xFA, 0xDF}},
+	{0xC3A1, {0xFA, 0xE1}}, {0xC3B5, {0xFA, 0xE2}}, {0xC3B9, {0xFA, 0xE4}},
+	{0xC3C9, {0xFA, 0xE3}}, {0xC3D8, {0xFA, 0xE6}}, {0xC3FC, {0xFA, 0x64}},
+	{0xC3FE, {0xFA, 0xE7}}, {0xC4CC, {0xFA, 0xE9}}, {0xC4D9, {0xFA, 0xEB}},
+	{0xC4EA, {0xFA, 0xEC}}, {0xC4FD, {0xFA, 0xED}}, {0xC5A7, {0xFA, 0xEF}},
+	{0xC5B5, {0xFA, 0xF0}}, {0xC5B6, {0xFA, 0xF1}}, {0xC5D5, {0xFA, 0xF3}},
+	{0xC6B8, {0xFA, 0xF4}}, {0xC6D7, {0xFA, 0xF5}}, {0xC6E0, {0xFA, 0xF6}},
+	{0xC6E3, {0xFA, 0xF8}}, {0xC6EA, {0xFA, 0xF7}}, {0xC7A1, {0xFA, 0xF9}},
+	{0xC7AB, {0xFA, 0xFA}}, {0xC7C3, {0xFA, 0xFC}}, {0xC7C7, {0xFA, 0xFB}},
+	{0xC7CB, {0xFB, 0x40}}, {0xC7CF, {0xFB, 0x41}}, {0xC7D9, {0xFB, 0x42}},
+	{0xC7E6, {0xFB, 0x45}}, {0xC7EB, {0xFB, 0x48}}, {0xC7EE, {0xFB, 0x46}},
+	{0xC7F0, {0xFB, 0x49}}, {0xC7FC, {0xFB, 0x47}}, {0xC8B1, {0xFB, 0x4A}},
+	{0xC8E5, {0xFB, 0x4B}}, {0xC8F8, {0xFB, 0x4C}}, {0xC9A6, {0xFB, 0x4D}},
+	{0xC9AB, {0xFB, 0x4E}}, {0xC9AD, {0xFB, 0x4F}}, {0xC9CA, {0xFB, 0x51}},
+	{0xC9D3, {0xFB, 0x52}}, {0xC9E3, {0xFB, 0x54}}, {0xC9E9, {0xFB, 0x53}},
+	{0xC9F4, {0xFB, 0x56}}, {0xC9F5, {0xFB, 0x57}}, {0xC9FC, {0xFB, 0x55}},
+	{0xCAB3, {0xFB, 0x59}}, {0xCABD, {0xFB, 0x5A}}, {0xCAEF, {0xFB, 0x5B}},
+	{0xCAF1, {0xFB, 0x5C}}, {0xCBAE, {0xFB, 0x5D}}, {0xCBCA, {0xFB, 0x5F}},
+	{0xCBE6, {0xFB, 0x60}}, {0xCBEA, {0xFB, 0x61}}, {0xCBEE, {0xFB, 0x64}},
+	{0xCBF0, {0xFB, 0x62}}, {0xCBF4, {0xFB, 0x63}}, {0xCBF9, {0xFB, 0x66}},
+	{0xCCA5, {0xFB, 0x65}}, {0xCCAB, {0xFB, 0x67}}, {0xCCAD, {0xFB, 0x69}},
+	{0xCCAE, {0xFB, 0x68}}, {0xCCB2, {0xFB, 0x6A}}, {0xCCC2, {0xFB, 0x6B}},
+	{0xCCD0, {0xFB, 0x6C}}, {0xCCD9, {0xFB, 0x6D}}, {0xCDAA, {0xFA, 0xA8}},
+	{0xCDBB, {0xFB, 0x6F}}, {0xCEBA, {0xFB, 0x73}}, {0xCEBB, {0xFB, 0x71}},
+	{0xCEC3, {0xFB, 0x74}}, {0xCEF2, {0xFB, 0x76}}, {0xCFD5, {0xFB, 0x78}},
+	{0xCFE2, {0xFB, 0x79}}, {0xCFE9, {0xFB, 0x7A}}, {0xCFED, {0xFB, 0x7B}},
+	{0xD0E5, {0xFB, 0x81}}, {0xD0E9, {0xFB, 0x83}}, {0xD1E8, {0xFB, 0x84}},
+	{0xD1EC, {0xFB, 0x87}}, {0xD2BB, {0xFB, 0x88}}, {0xD3E1, {0xFB, 0x8A}},
+	{0xD3E8, {0xFB, 0x8B}}, {0xD4A7, {0xFB, 0x8C}}, {0xD4D4, {0xFB, 0x8F}},
+	{0xD4E3, {0xFA, 0x5C}}, {0xD4F2, {0xFB, 0x90}}, {0xD5AE, {0xFB, 0x91}},
+	{0xD7DE, {0xFB, 0x93}}, {0xD8A2, {0xFB, 0x95}}, {0xD8B7, {0xFB, 0x96}},
+	{0xD8C1, {0xFB, 0x97}}, {0xD8D1, {0xFB, 0x98}}, {0xD8F4, {0xFB, 0x99}},
+	{0xD9A1, {0xFA, 0x60}}, {0xD9C6, {0xFB, 0x9A}}, {0xD9C8, {0xFB, 0x9B}},
+	{0xD9D1, {0xFB, 0x9C}}, {0xDCD3, {0xFB, 0xA2}}, {0xDCDF, {0xFA, 0x5D}},
+	{0xDDC8, {0xFB, 0xA3}}, {0xDDD4, {0xFB, 0xA4}}, {0xDDEA, {0xFB, 0xA5}},
+	{0xDDFA, {0xFB, 0xA6}}, {0xDEA4, {0xFB, 0xA7}}, {0xDEB0, {0xFB, 0xA8}},
+	{0xDEB5, {0xFB, 0xAA}}, {0xDECB, {0xFB, 0xAB}}, {0xDFB9, {0xFB, 0xAD}},
+	{0xDFC3, {0xFB, 0xAF}}, {0xE0D9, {0xFB, 0xB2}}, {0xE1E2, {0xFB, 0xB5}},
+	{0xE2C7, {0xFB, 0xB9}}, {0xE3A6, {0xFB, 0xBB}}, {0xE3A8, {0xFB, 0xBA}},
+	{0xE3A9, {0xFB, 0xBC}}, {0xE3AA, {0xFB, 0xBF}}, {0xE3AB, {0xFB, 0xC0}},
+	{0xE3AF, {0xFB, 0xBD}}, {0xE3B0, {0xFB, 0xBE}}, {0xE3BC, {0xFB, 0xC1}},
+	{0xE3BF, {0xFB, 0xC3}}, {0xE3C1, {0xFB, 0xC2}}, {0xE3D4, {0xFB, 0xCA}},
+	{0xE3D5, {0xFB, 0xC4}}, {0xE3D6, {0xFB, 0xC6}}, {0xE3D8, {0xFB, 0xC5}},
+	{0xE3DF, {0xFB, 0xC7}}, {0xE3E1, {0xFB, 0xC9}}, {0xE3E3, {0xFB, 0xC8}},
+	{0xE3E9, {0xFB, 0xCB}}, {0xE3F1, {0xFB, 0xCD}}, {0xE3F2, {0xFB, 0xCE}},
+	{0xE3F8, {0xFA, 0x5F}}, {0xE4A6, {0xFB, 0xCC}}, {0xE4BE, {0xFB, 0xD2}},
+	{0xE4BF, {0xFB, 0xD6}}, {0xE4C0, {0xFB, 0xD4}}, {0xE4C1, {0xFB, 0xD0}},
+	{0xE4C3, {0xFB, 0xD1}}, {0xE4C7, {0xFB, 0xD5}}, {0xE4CB, {0xFB, 0xCF}},
+	{0xE4D0, {0xFA, 0x65}}, {0xE4D1, {0xFB, 0xD9}}, {0xE4D2, {0xFB, 0xDC}},
+	{0xE4D4, {0xFB, 0xDE}}, {0xE4DB, {0xFB, 0xDD}}, {0xE4DC, {0xFB, 0xDB}},
+	{0xE4DE, {0xFB, 0xD8}}, {0xE4E0, {0xFB, 0xD7}}, {0xE4E9, {0xFA, 0x5E}},
+	{0xE4EF, {0xFB, 0xE0}}, {0xE4FA, {0xFB, 0xDF}}, {0xE5B3, {0xFB, 0xE1}},
+	{0xE5BF, {0xFB, 0xE2}}, {0xE5C9, {0xFB, 0xE3}}, {0xE5D0, {0xFB, 0xE4}},
+	{0xE5E2, {0xFB, 0xE5}}, {0xE5EA, {0xFB, 0xE6}}, {0xE5EB, {0xFB, 0xE7}},
+	{0xE6E8, {0xFB, 0xEB}}, {0xE6EF, {0xFB, 0xEC}}, {0xE7AC, {0xFB, 0xED}},
+	{0xE7AE, {0xFB, 0xEF}}, {0xE7B1, {0xFB, 0xF1}}, {0xE7B2, {0xFB, 0xF3}},
+	{0xE8B1, {0xFB, 0xF4}}, {0xE8B6, {0xFB, 0xF5}}, {0xE8DD, {0xFB, 0xF8}},
+	{0xE9D1, {0xFB, 0xFB}}, {0xE9ED, {0xFC, 0x40}}, {0xEACD, {0xFC, 0x41}},
+	{0xEADB, {0xFC, 0x43}}, {0xEAE6, {0xFC, 0x44}}, {0xEAEA, {0xFC, 0x45}},
+	{0xEBA5, {0xFC, 0x46}}, {0xEBFA, {0xFC, 0x48}}, {0xEBFB, {0xFC, 0x47}},
+	{0xECD6, {0xFC, 0x4A}},
+};
+
+/* EUC to SJIS IBM extended characters map (G3 Upper block) */
+static unsigned char euc2sjisibm_g3upper_map[][2] = {
+	{0xFA, 0x40}, {0xFA, 0x41}, {0xFA, 0x42}, {0xFA, 0x43}, {0xFA, 0x44},
+	{0xFA, 0x45}, {0xFA, 0x46}, {0xFA, 0x47}, {0xFA, 0x48}, {0xFA, 0x49},
+	{0xFA, 0x4A}, {0xFA, 0x4B}, {0xFA, 0x4C}, {0xFA, 0x4D}, {0xFA, 0x4E},
+	{0xFA, 0x4F}, {0xFA, 0x50}, {0xFA, 0x51}, {0xFA, 0x52}, {0xFA, 0x53},
+	{0xFA, 0x56}, {0xFA, 0x57}, {0xFA, 0x58}, {0xFA, 0x59}, {0xFA, 0x5A},
+	{0xFA, 0x62}, {0xFA, 0x6A}, {0xFA, 0x7C}, {0xFA, 0x83}, {0xFA, 0x8A},
+	{0xFA, 0x8B}, {0xFA, 0x90}, {0xFA, 0x92}, {0xFA, 0x96}, {0xFA, 0x9B},
+	{0xFA, 0x9C}, {0xFA, 0x9D}, {0xFA, 0xAA}, {0xFA, 0xAE}, {0xFA, 0xB0},
+	{0xFA, 0xB1}, {0xFA, 0xBA}, {0xFA, 0xBD}, {0xFA, 0xC1}, {0xFA, 0xCD},
+	{0xFA, 0xD0}, {0xFA, 0xD5}, {0xFA, 0xD8}, {0xFA, 0xE0}, {0xFA, 0xE5},
+	{0xFA, 0xE8}, {0xFA, 0xEA}, {0xFA, 0xEE}, {0xFA, 0xF2}, {0xFB, 0x43},
+	{0xFB, 0x44}, {0xFB, 0x50}, {0xFB, 0x58}, {0xFB, 0x5E}, {0xFB, 0x6E},
+	{0xFB, 0x70}, {0xFB, 0x72}, {0xFB, 0x75}, {0xFB, 0x7C}, {0xFB, 0x7D},
+	{0xFB, 0x7E}, {0xFB, 0x80}, {0xFB, 0x82}, {0xFB, 0x85}, {0xFB, 0x86},
+	{0xFB, 0x89}, {0xFB, 0x8D}, {0xFB, 0x8E}, {0xFB, 0x92}, {0xFB, 0x94},
+	{0xFB, 0x9D}, {0xFB, 0x9E}, {0xFB, 0x9F}, {0xFB, 0xA0}, {0xFB, 0xA1},
+	{0xFB, 0xA9}, {0xFB, 0xAC}, {0xFB, 0xAE}, {0xFB, 0xB0}, {0xFB, 0xB1},
+	{0xFB, 0xB3}, {0xFB, 0xB4}, {0xFB, 0xB6}, {0xFB, 0xB7}, {0xFB, 0xB8},
+	{0xFB, 0xD3}, {0xFB, 0xDA}, {0xFB, 0xE8}, {0xFB, 0xE9}, {0xFB, 0xEA},
+	{0xFB, 0xEE}, {0xFB, 0xF0}, {0xFB, 0xF2}, {0xFB, 0xF6}, {0xFB, 0xF7},
+	{0xFB, 0xF9}, {0xFB, 0xFA}, {0xFB, 0xFC}, {0xFC, 0x42}, {0xFC, 0x49},
+	{0xFC, 0x4B},
+};
+
+#define MAP_ELEMENT_OF(map)	(sizeof(map) / sizeof(map[0]))
+
+static inline int sjisibm2euc(unsigned char *euc, const unsigned char sjis_hi,
+			      const unsigned char sjis_lo);
+static inline int euc2sjisibm_jisx0212(unsigned char *sjis, const unsigned char euc_hi,
+				       const unsigned char euc_lo);
+static inline int euc2sjisibm_g3upper(unsigned char *sjis, const unsigned char euc_hi,
+				      const unsigned char euc_lo);
+static inline int euc2sjisibm(unsigned char *sjis, const unsigned char euc_hi,
+			      const unsigned char euc_lo);
+static inline int sjisnec2sjisibm(unsigned char *sjisibm,
+				  const unsigned char sjisnec_hi,
+				  const unsigned char sjisnec_lo);
+
+/* SJIS IBM extended characters to EUC */
+static inline int sjisibm2euc(unsigned char *euc, const unsigned char sjis_hi,
+			      const unsigned char sjis_lo)
+{
+	int index;
+
+	index = ((sjis_hi - 0xFA) * (0xFD - 0x40)) + (sjis_lo - 0x40);
+	if (IS_EUC_IBM2JISX0208(sjisibm2euc_map[index][0],
+				sjisibm2euc_map[index][1])) {
+		euc[0] = sjisibm2euc_map[index][0];
+		euc[1] = sjisibm2euc_map[index][1];
+		return 2;
+	} else {
+		euc[0] = SS3;
+		euc[1] = sjisibm2euc_map[index][0];
+		euc[2] = sjisibm2euc_map[index][1];
+		return 3;
+	}
+}
+
+/* EUC to SJIS IBM extended characters (G3 JIS X 0212 block) */
+static inline int euc2sjisibm_jisx0212(unsigned char *sjis, const unsigned char euc_hi,
+				       const unsigned char euc_lo)
+{
+	int index, min_index, max_index;
+	unsigned short euc;
+
+	min_index = 0;
+	max_index = MAP_ELEMENT_OF(euc2sjisibm_jisx0212_map) - 1;
+	euc = (euc_hi << 8) | euc_lo;
+
+	while (min_index <= max_index) {
+		index = (min_index + max_index) / 2;
+		if (euc < euc2sjisibm_jisx0212_map[index].euc)
+			max_index = index - 1;
+		else
+			min_index = index + 1;
+		if (euc == euc2sjisibm_jisx0212_map[index].euc) {
+			sjis[0] = euc2sjisibm_jisx0212_map[index].sjis[0];
+			sjis[1] = euc2sjisibm_jisx0212_map[index].sjis[1];
+			return 3;
+		}
+	}
+	return 0;
+}
+
+/* EUC to SJIS IBM extended characters (G3 Upper block) */
+static inline int euc2sjisibm_g3upper(unsigned char *sjis, const unsigned char euc_hi,
+				      const unsigned char euc_lo)
+{
+	int index;
+
+	if (euc_hi == 0xF3)
+		index = ((euc_hi << 8) | euc_lo) - 0xF3F3;
+	else
+		index = ((euc_hi << 8) | euc_lo) - 0xF4A1 + 12;
+
+	if ((index < 0) || (index >= MAP_ELEMENT_OF(euc2sjisibm_g3upper_map)))
+		return 0;
+
+	sjis[0] = euc2sjisibm_g3upper_map[index][0];
+	sjis[1] = euc2sjisibm_g3upper_map[index][1];
+
+	return 3;
+}
+
+/* EUC to SJIS IBM extended characters (G3 block) */
+static inline int euc2sjisibm(unsigned char *sjis, const unsigned char euc_hi,
+			      const unsigned char euc_lo)
+{
+	int n;
+
+#if 0
+	if ((euc_hi == 0xA2) && (euc_lo == 0xCC)) {
+		sjis[0] = 0xFA;
+		sjis[1] = 0x54;
+		return 2;
+	} else if ((euc_hi == 0xA2) && (euc_lo == 0xE8)) {
+		sjis[0] = 0xFA;
+		sjis[1] = 0x5B;
+		return 2;
+	}
+#endif
+	if ((n = euc2sjisibm_g3upper(sjis, euc_hi, euc_lo))) {
+		return n;
+	} else if ((n = euc2sjisibm_jisx0212(sjis, euc_hi, euc_lo))) {
+		return n;
+	}
+
+	return 0;
+}
+
+/* NEC/IBM extended characters to IBM extended characters */
+static inline int sjisnec2sjisibm(unsigned char *sjisibm,
+				  const unsigned char sjisnec_hi,
+				  const unsigned char sjisnec_lo)
+{
+	int count;
+
+	if (! IS_SJIS_NECIBM(sjisnec_hi, sjisnec_lo))
+		return 0;
+
+	if ((sjisnec_hi == 0xEE) && (sjisnec_lo == 0xF9)) {
+		sjisibm[0] = 0x81;
+		sjisibm[1] = 0xCA;
+		return 2;
+	}
+
+	if ((sjisnec_hi == 0xEE) && (sjisnec_lo >= 0xEF)) {
+		count = (sjisnec_hi << 8 | sjisnec_lo)
+			- (sjisnec_lo <= 0xF9 ? 0xEEEF : (0xEEEF - 10));
+	} else {
+		count = (sjisnec_hi - 0xED) * (0xFC - 0x40)
+			+ (sjisnec_lo - 0x40) + (0x5C - 0x40);
+		if (sjisnec_lo >= 0x7F)
+			count--;
+	}
+
+	sjisibm[0] = 0xFA + (count / (0xFC - 0x40));
+	sjisibm[1] = 0x40 + (count % (0xFC - 0x40));
+	if (sjisibm[1] >= 0x7F)
+		sjisibm[1]++;
+
+	return 2;
+}
 
 static int uni2char(const wchar_t uni,
-			unsigned char *out, int boundlen)
+		    unsigned char *out, int boundlen)
 {
 	int n;
 
-	if ( !p_nls )
- 		return -EINVAL;
-	if ( (n = p_nls->uni2char(uni, out, boundlen)) < 0)
+	if (!p_nls)
+		return -EINVAL;
+	if ((n = p_nls->uni2char(uni, out, boundlen)) < 0)
 		return n;
-	
+
 	/* translate SJIS into EUC-JP */
 	if (n == 1) {
-		/* JIS X 201 KANA */
-		if (0xA1 <= out[0] && out[0] <= 0xDF) {
-			if (boundlen <= 1)
+		if (IS_SJIS_JISX0201KANA(out[0])) {
+			/* JIS X 0201 KANA */
+			if (boundlen < 2)
 				return -ENAMETOOLONG;
+
 			out[1] = out[0];
 			out[0] = SS2;
-			n = 2;    
+			return 2;
 		}
-	} else if (n == 2) { 
-		/* JIS X 208 */
+	} else if (n == 2) {
+		/* NEC/IBM extended characters to IBM extended characters */
+		sjisnec2sjisibm(out, out[0], out[1]);
+
+		if (IS_SJIS_UDC_LOW(out[0], out[1])) {
+			/* User defined characters half low */
+			MAP_SJIS2EUC(out[0], out[1], 0xF0, out[0], out[1], 0xF5);
+		} else if (IS_SJIS_UDC_HI(out[0], out[1])) {
+			/* User defined characters half high */
+			unsigned char ch, cl;
 
-		/* SJIS codes 0xF0xx to 0xFFxx are machine-dependent codes and user-defining characters */
-		if (out[0] >= 0xF0) {
-			out[0] = 0x81;  /* 'GETA' with SJIS coding */
-			out[1] = 0xAC;
-		}
+			if (boundlen < 3)
+				return -ENAMETOOLONG;
 
-		out[0] = (out[0]^0xA0)*2 + 0x5F;
-		if (out[1] > 0x9E)
-			out[0]++; 
-		
-		if (out[1] < 0x7F)
-			out[1] = out[1] + 0x61;
-		else if (out[1] < 0x9F)
-			out[1] = out[1] + 0x60;
-		else
-			out[1] = out[1] + 0x02;
+			n = 3; ch = out[0]; cl = out[1];
+			out[0] = SS3;
+			MAP_SJIS2EUC(ch, cl, 0xF5, out[1], out[2], 0xF5);
+		} else if (IS_SJIS_IBM(out[0], out[1])) {
+			/* IBM extended characters */
+			unsigned char euc[3], i;
+
+			n = sjisibm2euc(euc, out[0], out[1]);
+			if (boundlen < n)
+				return -ENAMETOOLONG;
+			for (i = 0; i < n; i++)
+				out[i] = euc[i];
+		} else if (IS_SJIS_JISX0208(out[0], out[1])) {
+			/* JIS X 0208 (include NEC special characters) */
+			out[0] = (out[0]^0xA0)*2 + 0x5F;
+			if (out[1] > 0x9E)
+				out[0]++;
+
+			if (out[1] < 0x7F)
+				out[1] = out[1] + 0x61;
+			else if (out[1] < 0x9F)
+				out[1] = out[1] + 0x60;
+			else
+				out[1] = out[1] + 0x02;
+		} else {
+			/* Invalid characters */
+			return -EINVAL;
+		}
 	}
 	else
 		return -EINVAL;
@@ -61,52 +479,73 @@
 }
 
 static int char2uni(const unsigned char *rawstring, int boundlen,
-				wchar_t *uni)
+		    wchar_t *uni)
 {
 	unsigned char sjis_temp[2];
 	int euc_offset, n;
-	
+
 	if ( !p_nls )
 		return -EINVAL;
 	if (boundlen <= 0)
 		return -ENAMETOOLONG;
 
-	if (boundlen == 1) {
-		*uni = rawstring[0];
-		return 1;
-	}
-
 	/* translate EUC-JP into SJIS */
 	if (rawstring[0] > 0x7F) {
-		if (rawstring[0] == SS2) {
-			/* JIS X 201 KANA */
-			sjis_temp[0] = rawstring[1];
-			sjis_temp[1] = 0x00;
-			euc_offset = 2;
-		} else if (rawstring[0] == SS3) {
-			/* JIS X 212 */
-			sjis_temp[0] = 0x81; /* 'GETA' with SJIS coding */
-			sjis_temp[1] = 0xAC;
+		if (rawstring[0] == SS3) {
+			if (boundlen < 3)
+				return -EINVAL;
 			euc_offset = 3;
-		} else { 
-			/* JIS X 208 */
-			sjis_temp[0] = ((rawstring[0]-0x5f)/2) ^ 0xA0;
-			if (!(rawstring[0]&1))
-				sjis_temp[1] = rawstring[1] - 0x02;
-			else if (rawstring[1] < 0xE0)
-				sjis_temp[1] = rawstring[1] - 0x61;
-			else
-				sjis_temp[1] = rawstring[1] - 0x60;
+
+			if (IS_EUC_UDC_HI(rawstring[1], rawstring[2])) {
+				/* User defined characters half high */
+				MAP_EUC2SJIS(rawstring[1], rawstring[2], 0xF5,
+					     sjis_temp[0], sjis_temp[1], 0xF5);
+			} else if (euc2sjisibm(sjis_temp,rawstring[1],rawstring[2])) {
+				/* IBM extended characters */
+			} else {
+				/* JIS X 0212 and Invalid characters*/
+				return -EINVAL;
+
+				/* 'GETA' with SJIS coding */
+				/* sjis_temp[0] = 0x81; */
+				/* sjis_temp[1] = 0xAC; */
+			}
+		} else {
+			if (boundlen < 2)
+				return -EINVAL;
 			euc_offset = 2;
+
+			if (IS_EUC_JISX0201KANA(rawstring[0], rawstring[1])) {
+				/* JIS X 0201 KANA */
+				sjis_temp[0] = rawstring[1];
+				sjis_temp[1] = 0x00;
+			} else if (IS_EUC_UDC_LOW(rawstring[0], rawstring[1])) {
+				/* User defined characters half low */
+				MAP_EUC2SJIS(rawstring[0], rawstring[1], 0xF5,
+					     sjis_temp[0], sjis_temp[1], 0xF0);
+			} else if (IS_EUC_JISX0208(rawstring[0], rawstring[1])) {
+				/* JIS X 0208 (include NEC spesial characters) */
+				sjis_temp[0] = ((rawstring[0]-0x5f)/2) ^ 0xA0;
+				if (!(rawstring[0] & 1))
+					sjis_temp[1] = rawstring[1] - 0x02;
+				else if (rawstring[1] < 0xE0)
+					sjis_temp[1] = rawstring[1] - 0x61;
+				else
+					sjis_temp[1] = rawstring[1] - 0x60;
+			} else {
+				/* Invalid characters */
+				return -EINVAL;
+			}
 		}
-	} else { 
-		/* JIS X 201 ROMAJI */
-		sjis_temp[0] = rawstring[0];
-		sjis_temp[1] = rawstring[1];
+	} else {
 		euc_offset = 1;
+
+		/* JIS X 0201 ROMAJI */
+		sjis_temp[0] = rawstring[0];
+		sjis_temp[1] = 0x00;
 	}
 
-	if ( (n = p_nls->char2uni(sjis_temp, boundlen, uni)) < 0)
+	if ( (n = p_nls->char2uni(sjis_temp, sizeof(sjis_temp), uni)) < 0)
 		return n;
 
 	return euc_offset;
diff -u --recursive --new-file v2.4.3/linux/fs/nls/nls_iso8859-13.c linux/fs/nls/nls_iso8859-13.c
--- v2.4.3/linux/fs/nls/nls_iso8859-13.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/nls/nls_iso8859-13.c	Fri Apr  6 10:51:19 2001
@@ -0,0 +1,330 @@
+/*
+ * linux/fs/nls_iso8859-13.c
+ *
+ * Charset iso8859-13 translation tables.
+ * The Unicode to charset table has only exact mappings.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/nls.h>
+#include <linux/errno.h>
+
+static wchar_t charset2uni[256] = {
+	/* 0x00*/
+	0x0000, 0x0001, 0x0002, 0x0003,
+	0x0004, 0x0005, 0x0006, 0x0007,
+	0x0008, 0x0009, 0x000a, 0x000b,
+	0x000c, 0x000d, 0x000e, 0x000f,
+	/* 0x10*/
+	0x0010, 0x0011, 0x0012, 0x0013,
+	0x0014, 0x0015, 0x0016, 0x0017,
+	0x0018, 0x0019, 0x001a, 0x001b,
+	0x001c, 0x001d, 0x001e, 0x001f,
+	/* 0x20*/
+	0x0020, 0x0021, 0x0022, 0x0023,
+	0x0024, 0x0025, 0x0026, 0x0027,
+	0x0028, 0x0029, 0x002a, 0x002b,
+	0x002c, 0x002d, 0x002e, 0x002f,
+	/* 0x30*/
+	0x0030, 0x0031, 0x0032, 0x0033,
+	0x0034, 0x0035, 0x0036, 0x0037,
+	0x0038, 0x0039, 0x003a, 0x003b,
+	0x003c, 0x003d, 0x003e, 0x003f,
+	/* 0x40*/
+	0x0040, 0x0041, 0x0042, 0x0043,
+	0x0044, 0x0045, 0x0046, 0x0047,
+	0x0048, 0x0049, 0x004a, 0x004b,
+	0x004c, 0x004d, 0x004e, 0x004f,
+	/* 0x50*/
+	0x0050, 0x0051, 0x0052, 0x0053,
+	0x0054, 0x0055, 0x0056, 0x0057,
+	0x0058, 0x0059, 0x005a, 0x005b,
+	0x005c, 0x005d, 0x005e, 0x005f,
+	/* 0x60*/
+	0x0060, 0x0061, 0x0062, 0x0063,
+	0x0064, 0x0065, 0x0066, 0x0067,
+	0x0068, 0x0069, 0x006a, 0x006b,
+	0x006c, 0x006d, 0x006e, 0x006f,
+	/* 0x70*/
+	0x0070, 0x0071, 0x0072, 0x0073,
+	0x0074, 0x0075, 0x0076, 0x0077,
+	0x0078, 0x0079, 0x007a, 0x007b,
+	0x007c, 0x007d, 0x007e, 0x007f,
+	/* 0x80*/
+	0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	/* 0x90*/
+	0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	/* 0xa0*/
+	0x00a0, 0x201d, 0x00a2, 0x00a3,
+	0x00a4, 0x201e, 0x00a6, 0x00a7,
+	0x00d8, 0x00a9, 0x0156, 0x00ab,
+	0x00ac, 0x00ad, 0x00ae, 0x00c6,
+	/* 0xb0*/
+	0x00b0, 0x00b1, 0x00b2, 0x00b3,
+	0x201c, 0x00b5, 0x00b6, 0x00b7,
+	0x00f8, 0x00b9, 0x0157, 0x00bb,
+	0x00bc, 0x00bd, 0x00be, 0x00e6,
+	/* 0xc0*/
+	0x0104, 0x012e, 0x0100, 0x0106,
+	0x00c4, 0x00c5, 0x0118, 0x0112,
+	0x010c, 0x00c9, 0x0179, 0x0116,
+	0x0122, 0x0136, 0x012a, 0x013b,
+	/* 0xd0*/
+	0x0160, 0x0143, 0x0145, 0x00d3,
+	0x014c, 0x00d5, 0x00d6, 0x00d7,
+	0x0172, 0x0141, 0x015a, 0x016a,
+	0x00dc, 0x017b, 0x017d, 0x00df,
+	/* 0xe0*/
+	0x0105, 0x012f, 0x0101, 0x0107,
+	0x00e4, 0x00e5, 0x0119, 0x0113,
+	0x010d, 0x00e9, 0x017a, 0x0117,
+	0x0123, 0x0137, 0x012b, 0x013c,
+	/* 0xf0*/
+	0x0161, 0x0144, 0x0146, 0x00f3,
+	0x014d, 0x00f5, 0x00f6, 0x00f7,
+	0x0173, 0x0142, 0x015b, 0x016b,
+	0x00fc, 0x017c, 0x017e, 0x2019,
+};
+
+static unsigned char page00[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
+	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
+	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
+	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */
+	0x00, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */
+	0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
+	0x00, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */
+	0x00, 0x00, 0x00, 0x00, 0xc4, 0xc5, 0xaf, 0x00, /* 0xc0-0xc7 */
+	0x00, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+	0x00, 0x00, 0x00, 0xd3, 0x00, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */
+	0xa8, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */
+	0x00, 0x00, 0x00, 0x00, 0xe4, 0xe5, 0xbf, 0x00, /* 0xe0-0xe7 */
+	0x00, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
+	0x00, 0x00, 0x00, 0xf3, 0x00, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */
+	0xb8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */
+};
+
+static unsigned char page01[256] = {
+	0xc2, 0xe2, 0x00, 0x00, 0xc0, 0xe0, 0xc3, 0xe3, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00, /* 0x08-0x0f */
+	0x00, 0x00, 0xc7, 0xe7, 0x00, 0x00, 0xcb, 0xeb, /* 0x10-0x17 */
+	0xc6, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
+	0x00, 0x00, 0xcc, 0xec, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+	0x00, 0x00, 0xce, 0xee, 0x00, 0x00, 0xc1, 0xe1, /* 0x28-0x2f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xed, /* 0x30-0x37 */
+	0x00, 0x00, 0x00, 0xcf, 0xef, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+	0x00, 0xd9, 0xf9, 0xd1, 0xf1, 0xd2, 0xf2, 0x00, /* 0x40-0x47 */
+	0x00, 0x00, 0x00, 0x00, 0xd4, 0xf4, 0x00, 0x00, /* 0x48-0x4f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xba, /* 0x50-0x57 */
+	0x00, 0x00, 0xda, 0xfa, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+	0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+	0x00, 0x00, 0xdb, 0xfb, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+	0x00, 0x00, 0xd8, 0xf8, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+	0x00, 0xca, 0xea, 0xdd, 0xfd, 0xde, 0xfe, 0x00, /* 0x78-0x7f */
+};
+
+static unsigned char page02[256] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+	0x00, 0xff, 0x00, 0x00, 0xb4, 0xa1, 0xa5, 0x00, /* 0x18-0x1f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+	
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
+};
+
+static unsigned char page20[256] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+	0x00, 0xff, 0x00, 0x00, 0xb4, 0xa1, 0xa5, 0x00, /* 0x18-0x1f */
+};
+
+static unsigned char *page_uni2charset[256] = {
+	page00, page01,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	  NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	  NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	  NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	page20,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+};
+
+static unsigned char charset2lower[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x40-0x47 */
+	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x48-0x4f */
+	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x50-0x57 */
+	0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
+	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
+	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
+	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0xa0, 0xb1, 0xa2, 0xb3, 0xa4, 0xb5, 0xb6, 0xa7, /* 0xa0-0xa7 */
+	0xa8, 0xb9, 0xba, 0xbb, 0xbc, 0xad, 0xbe, 0xaf, /* 0xa8-0xaf */
+	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
+	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbf, 0xbe, 0xbf, /* 0xb8-0xbf */
+	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xc0-0xc7 */
+	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xc8-0xcf */
+	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xd7, /* 0xd0-0xd7 */
+	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf, /* 0xd8-0xdf */
+	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */
+	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */
+	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */
+	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
+};
+
+static unsigned char charset2upper[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */
+	0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
+	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
+	0xb0, 0xa1, 0xb2, 0xa3, 0xb4, 0xa5, 0xa6, 0xb7, /* 0xb0-0xb7 */
+	0xb8, 0xa9, 0xaa, 0xab, 0xac, 0xbd, 0xae, 0xbd, /* 0xb8-0xbf */
+	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */
+	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */
+	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */
+	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */
+	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xe0-0xe7 */
+	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xe8-0xef */
+	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xf7, /* 0xf0-0xf7 */
+	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xff, /* 0xf8-0xff */
+};
+
+static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
+{
+	unsigned char *uni2charset;
+	unsigned char cl = uni & 0x00ff;
+	unsigned char ch = (uni & 0xff00) >> 8;
+
+	if (boundlen <= 0)
+		return -ENAMETOOLONG;
+
+	uni2charset = page_uni2charset[ch];
+	if (uni2charset && uni2charset[cl])
+		out[0] = uni2charset[cl];
+	else
+		return -EINVAL;
+	return 1;
+}
+
+static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
+{
+	*uni = charset2uni[*rawstring];
+	if (*uni == 0x0000)
+		return -EINVAL;
+	return 1;
+}
+
+static struct nls_table table = {
+	"iso8859-13",
+	uni2char,
+	char2uni,
+	charset2lower,
+	charset2upper,
+	THIS_MODULE,
+};
+
+static int __init init_nls_iso8859_13(void)
+{
+	return register_nls(&table);
+}
+
+static void __exit exit_nls_iso8859_13(void)
+{
+	unregister_nls(&table);
+}
+
+module_init(init_nls_iso8859_13)
+module_exit(exit_nls_iso8859_13)
+
+/*
+ * 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
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v2.4.3/linux/fs/nls/nls_iso8859-8.c linux/fs/nls/nls_iso8859-8.c
--- v2.4.3/linux/fs/nls/nls_iso8859-8.c	Fri Jul 21 15:19:51 2000
+++ linux/fs/nls/nls_iso8859-8.c	Fri Apr  6 10:51:19 2001
@@ -1,10 +1,5 @@
 /*
  * linux/fs/nls_iso8859-8.c
- *
- * Charset iso8859-8 translation tables.
- * Generated automatically from the Unicode and charset
- * tables from the Unicode Organization (www.unicode.org).
- * The Unicode to charset table has only exact mappings.
  */
 
 #include <linux/module.h>
@@ -13,291 +8,36 @@
 #include <linux/nls.h>
 #include <linux/errno.h>
 
-static wchar_t charset2uni[256] = {
-	/* 0x00*/
-	0x0000, 0x0001, 0x0002, 0x0003,
-	0x0004, 0x0005, 0x0006, 0x0007,
-	0x0008, 0x0009, 0x000a, 0x000b,
-	0x000c, 0x000d, 0x000e, 0x000f,
-	/* 0x10*/
-	0x0010, 0x0011, 0x0012, 0x0013,
-	0x0014, 0x0015, 0x0016, 0x0017,
-	0x0018, 0x0019, 0x001a, 0x001b,
-	0x001c, 0x001d, 0x001e, 0x001f,
-	/* 0x20*/
-	0x0020, 0x0021, 0x0022, 0x0023,
-	0x0024, 0x0025, 0x0026, 0x0027,
-	0x0028, 0x0029, 0x002a, 0x002b,
-	0x002c, 0x002d, 0x002e, 0x002f,
-	/* 0x30*/
-	0x0030, 0x0031, 0x0032, 0x0033,
-	0x0034, 0x0035, 0x0036, 0x0037,
-	0x0038, 0x0039, 0x003a, 0x003b,
-	0x003c, 0x003d, 0x003e, 0x003f,
-	/* 0x40*/
-	0x0040, 0x0041, 0x0042, 0x0043,
-	0x0044, 0x0045, 0x0046, 0x0047,
-	0x0048, 0x0049, 0x004a, 0x004b,
-	0x004c, 0x004d, 0x004e, 0x004f,
-	/* 0x50*/
-	0x0050, 0x0051, 0x0052, 0x0053,
-	0x0054, 0x0055, 0x0056, 0x0057,
-	0x0058, 0x0059, 0x005a, 0x005b,
-	0x005c, 0x005d, 0x005e, 0x005f,
-	/* 0x60*/
-	0x0060, 0x0061, 0x0062, 0x0063,
-	0x0064, 0x0065, 0x0066, 0x0067,
-	0x0068, 0x0069, 0x006a, 0x006b,
-	0x006c, 0x006d, 0x006e, 0x006f,
-	/* 0x70*/
-	0x0070, 0x0071, 0x0072, 0x0073,
-	0x0074, 0x0075, 0x0076, 0x0077,
-	0x0078, 0x0079, 0x007a, 0x007b,
-	0x007c, 0x007d, 0x007e, 0x007f,
-	/* 0x80*/
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	/* 0x90*/
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	/* 0xa0*/
-	0x00a0, 0x0000, 0x00a2, 0x00a3,
-	0x00a4, 0x00a5, 0x00a6, 0x00a7,
-	0x00a8, 0x00a9, 0x00d7, 0x00ab,
-	0x00ac, 0x00ad, 0x00ae, 0x203e,
-	/* 0xb0*/
-	0x00b0, 0x00b1, 0x00b2, 0x00b3,
-	0x00b4, 0x00b5, 0x00b6, 0x00b7,
-	0x00b8, 0x00b9, 0x00f7, 0x00bb,
-	0x00bc, 0x00bd, 0x00be, 0x0000,
-	/* 0xc0*/
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	/* 0xd0*/
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x2017,
-	/* 0xe0*/
-	0x05d0, 0x05d1, 0x05d2, 0x05d3,
-	0x05d4, 0x05d5, 0x05d6, 0x05d7,
-	0x05d8, 0x05d9, 0x05da, 0x05db,
-	0x05dc, 0x05dd, 0x05de, 0x05df,
-	/* 0xf0*/
-	0x05e0, 0x05e1, 0x05e2, 0x05e3,
-	0x05e4, 0x05e5, 0x05e6, 0x05e7,
-	0x05e8, 0x05e9, 0x05ea, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-};
-
-static unsigned char page00[256] = {
-	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
-	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
-	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
-	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
-	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
-	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
-	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
-	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
-	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
-	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
-	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
-	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
-	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
-	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
-	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
-	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
-
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
-	0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
-	0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */
-	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
-	0xb8, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, /* 0xd0-0xd7 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, /* 0xf0-0xf7 */
-};
-
-static unsigned char page05[256] = {
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
-
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
-	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xd0-0xd7 */
-	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xd8-0xdf */
-	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xe0-0xe7 */
-	0xf8, 0xf9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
-};
-
-static unsigned char page20[256] = {
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, /* 0x10-0x17 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x00, /* 0x38-0x3f */
-};
-
-static unsigned char *page_uni2charset[256] = {
-	page00, NULL,   NULL,   NULL,   NULL,   page05, NULL,   NULL,   
-	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
-	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
-	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
-	page20, NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
-};
-
-static unsigned char charset2lower[256] = {
-	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
-	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
-	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
-	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
-	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
-	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
-	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
-	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
-	0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x40-0x47 */
-	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x48-0x4f */
-	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x50-0x57 */
-	0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
-	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
-	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
-	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
-	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
-
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
-	0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
-	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
-	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
-	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */
-	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */
-	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */
-	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */
-	0xf8, 0xf9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
-};
-
-static unsigned char charset2upper[256] = {
-	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
-	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
-	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
-	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
-	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
-	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
-	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
-	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
-	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
-	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
-	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
-	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
-	0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */
-	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */
-	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */
-	0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
-
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
-	0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
-	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
-	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0x00, 0xb6, 0xb7, /* 0xb0-0xb7 */
-	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */
-	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */
-	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */
-	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */
-	0xf8, 0xf9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
-};
-
-static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
-{
-	unsigned char *uni2charset;
-	unsigned char cl = uni & 0x00ff;
-	unsigned char ch = (uni & 0xff00) >> 8;
-
-	if (boundlen <= 0)
-		return -ENAMETOOLONG;
-
-	uni2charset = page_uni2charset[ch];
-	if (uni2charset && uni2charset[cl])
-		out[0] = uni2charset[cl];
-	else
-		return -EINVAL;
-	return 1;
-}
-
-static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
-{
-	*uni = charset2uni[*rawstring];
-	if (*uni == 0x0000)
-		return -EINVAL;
-	return 1;
-}
+static struct nls_table *p_nls;
 
 static struct nls_table table = {
 	"iso8859-8",
-	uni2char,
-	char2uni,
-	charset2lower,
-	charset2upper,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
 	THIS_MODULE,
 };
 
 static int __init init_nls_iso8859_8(void)
 {
-	return register_nls(&table);
+	p_nls = load_nls("cp1255");
+
+	if (p_nls) {
+		table.uni2char = p_nls->uni2char;
+		table.char2uni = p_nls->char2uni;
+		table.charset2upper = p_nls->charset2upper;
+		table.charset2lower = p_nls->charset2lower;
+		return register_nls(&table);
+	}
+
+	return -EINVAL;
 }
 
 static void __exit exit_nls_iso8859_8(void)
 {
 	unregister_nls(&table);
+	unload_nls(p_nls);
 }
 
 module_init(init_nls_iso8859_8)
@@ -308,7 +48,8 @@
  * 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
  * of the file.
- * ---------------------------------------------------------------------------
+ *
+---------------------------------------------------------------------------
  * Local variables:
  * c-indent-level: 8
  * c-brace-imaginary-offset: 0
diff -u --recursive --new-file v2.4.3/linux/fs/nls/nls_koi8-u.c linux/fs/nls/nls_koi8-u.c
--- v2.4.3/linux/fs/nls/nls_koi8-u.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/nls/nls_koi8-u.c	Fri Apr  6 10:51:19 2001
@@ -0,0 +1,345 @@
+/*
+ * linux/fs/nls_koi8-u.c
+ *
+ * Charset koi8-u translation tables.
+ * The Unicode to charset table has only exact mappings.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/nls.h>
+#include <linux/errno.h>
+
+static wchar_t charset2uni[256] = {
+	/* 0x00*/
+	0x0000, 0x0001, 0x0002, 0x0003,
+	0x0004, 0x0005, 0x0006, 0x0007,
+	0x0008, 0x0009, 0x000a, 0x000b,
+	0x000c, 0x000d, 0x000e, 0x000f,
+	/* 0x10*/
+	0x0010, 0x0011, 0x0012, 0x0013,
+	0x0014, 0x0015, 0x0016, 0x0017,
+	0x0018, 0x0019, 0x001a, 0x001b,
+	0x001c, 0x001d, 0x001e, 0x001f,
+	/* 0x20*/
+	0x0020, 0x0021, 0x0022, 0x0023,
+	0x0024, 0x0025, 0x0026, 0x0027,
+	0x0028, 0x0029, 0x002a, 0x002b,
+	0x002c, 0x002d, 0x002e, 0x002f,
+	/* 0x30*/
+	0x0030, 0x0031, 0x0032, 0x0033,
+	0x0034, 0x0035, 0x0036, 0x0037,
+	0x0038, 0x0039, 0x003a, 0x003b,
+	0x003c, 0x003d, 0x003e, 0x003f,
+	/* 0x40*/
+	0x0040, 0x0041, 0x0042, 0x0043,
+	0x0044, 0x0045, 0x0046, 0x0047,
+	0x0048, 0x0049, 0x004a, 0x004b,
+	0x004c, 0x004d, 0x004e, 0x004f,
+	/* 0x50*/
+	0x0050, 0x0051, 0x0052, 0x0053,
+	0x0054, 0x0055, 0x0056, 0x0057,
+	0x0058, 0x0059, 0x005a, 0x005b,
+	0x005c, 0x005d, 0x005e, 0x005f,
+	/* 0x60*/
+	0x0060, 0x0061, 0x0062, 0x0063,
+	0x0064, 0x0065, 0x0066, 0x0067,
+	0x0068, 0x0069, 0x006a, 0x006b,
+	0x006c, 0x006d, 0x006e, 0x006f,
+	/* 0x70*/
+	0x0070, 0x0071, 0x0072, 0x0073,
+	0x0074, 0x0075, 0x0076, 0x0077,
+	0x0078, 0x0079, 0x007a, 0x007b,
+	0x007c, 0x007d, 0x007e, 0x007f,
+	/* 0x80*/
+	0x2500, 0x2502, 0x250c, 0x2510,
+	0x2514, 0x2518, 0x251c, 0x2524,
+	0x252c, 0x2534, 0x253c, 0x2580,
+	0x2584, 0x2588, 0x258c, 0x2590,
+	/* 0x90*/
+	0x2591, 0x2592, 0x2593, 0x2320,
+	0x25a0, 0x2219, 0x221a, 0x2248,
+	0x2264, 0x2265, 0x00a0, 0x2321,
+	0x00b0, 0x00b2, 0x00b7, 0x00f7,
+	/* 0xa0*/
+	0x2550, 0x2551, 0x2552, 0x0451,
+	0x0454, 0x2554, 0x0456, 0x0457,
+	0x2557, 0x2558, 0x2559, 0x255a,
+	0x255b, 0x0491, 0x255d, 0x255e,
+	/* 0xb0*/
+	0x255f, 0x2560, 0x2561, 0x0401,
+	0x0404, 0x2563, 0x0406, 0x0407,
+	0x2566, 0x2567, 0x2568, 0x2569,
+	0x256a, 0x0490, 0x256c, 0x00a9,
+	/* 0xc0*/
+	0x044e, 0x0430, 0x0431, 0x0446,
+	0x0434, 0x0435, 0x0444, 0x0433,
+	0x0445, 0x0438, 0x0439, 0x043a,
+	0x043b, 0x043c, 0x043d, 0x043e,
+	/* 0xd0*/
+	0x043f, 0x044f, 0x0440, 0x0441,
+	0x0442, 0x0443, 0x0436, 0x0432,
+	0x044c, 0x044b, 0x0437, 0x0448,
+	0x044d, 0x0449, 0x0447, 0x044a,
+	/* 0xe0*/
+	0x042e, 0x0410, 0x0411, 0x0426,
+	0x0414, 0x0415, 0x0424, 0x0413,
+	0x0425, 0x0418, 0x0419, 0x041a,
+	0x041b, 0x041c, 0x041d, 0x041e,
+	/* 0xf0*/
+	0x041f, 0x042f, 0x0420, 0x0421,
+	0x0422, 0x0423, 0x0416, 0x0412,
+	0x042c, 0x042b, 0x0417, 0x0428,
+	0x042d, 0x0429, 0x0427, 0x042a,
+};
+
+static unsigned char page00[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
+	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
+	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
+	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
+	0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
+	0x9c, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xb0-0xb7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, /* 0xf0-0xf7 */
+};
+
+static unsigned char page04[256] = {
+	0x00, 0xb3, 0x00, 0x00, 0xb4, 0x00, 0xb6, 0xb7, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa, /* 0x10-0x17 */
+	0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, /* 0x18-0x1f */
+	0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe, /* 0x20-0x27 */
+	0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1, /* 0x28-0x2f */
+	0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda, /* 0x30-0x37 */
+	0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, /* 0x38-0x3f */
+	0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde, /* 0x40-0x47 */
+	0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1, /* 0x48-0x4f */
+	0x00, 0xa3, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0x50-0x57 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+
+	0xbd, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+};
+
+static unsigned char page22[256] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+	0x00, 0x95, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+	0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+	0x00, 0x00, 0x00, 0x00, 0x98, 0x99, 0x00, 0x00, /* 0x60-0x67 */
+};
+
+static unsigned char page23[256] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
+	0x93, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+};
+
+static unsigned char page25[256] = {
+	0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+	0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+	0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+	0x85, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, /* 0x18-0x1f */
+	0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+	0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+	0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+	0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+	0xa0, 0xa1, 0xa2, 0x00, 0xa5, 0x00, 0x00, 0xa8, /* 0x50-0x57 */
+	0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf, 0xb0, /* 0x58-0x5f */
+	0xb1, 0xb2, 0x00, 0xb5, 0x00, 0x00, 0xb8, 0xb9, /* 0x60-0x67 */
+	0xba, 0xbb, 0xbc, 0x00, 0xbe, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+
+	0x8b, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+	0x8d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+	0x8f, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+	0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
+};
+
+static unsigned char *page_uni2charset[256] = {
+	page00, NULL,   NULL,   NULL,   page04, NULL,   NULL,   NULL,   
+	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	NULL,   NULL,   page22, page23, NULL,   page25, NULL,   NULL,   
+};
+
+static unsigned char charset2lower[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x40-0x47 */
+	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x48-0x4f */
+	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x50-0x57 */
+	0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
+	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
+	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
+	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+
+	0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */
+	0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */
+	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */
+	0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */
+	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */
+	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
+	0xb0, 0xb1, 0xb2, 0xa3, 0xa4, 0xb5, 0xa6, 0xa7, /* 0xb0-0xb7 */
+	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xad, 0xbe, 0xbf, /* 0xb8-0xbf */
+	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */
+	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */
+	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */
+	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */
+	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xe0-0xe7 */
+	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xe8-0xef */
+	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xf0-0xf7 */
+	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xf8-0xff */
+};
+
+static unsigned char charset2upper[256] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+	0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x60-0x67 */
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x68-0x6f */
+	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x70-0x77 */
+	0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+
+	0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x80-0x87 */
+	0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */
+	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x90-0x97 */
+	0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x98-0x9f */
+	0xa0, 0xa1, 0xa2, 0xb3, 0xb4, 0xa5, 0xb6, 0xb7, /* 0xa0-0xa7 */
+	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xbd, 0xae, 0xaf, /* 0xa8-0xaf */
+	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
+	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */
+	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xc0-0xc7 */
+	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xc8-0xcf */
+	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xd0-0xd7 */
+	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xd8-0xdf */
+	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */
+	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */
+	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */
+	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
+};
+
+static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
+{
+	unsigned char *uni2charset;
+	unsigned char cl = uni & 0x00ff;
+	unsigned char ch = (uni & 0xff00) >> 8;
+
+	if (boundlen <= 0)
+		return -ENAMETOOLONG;
+
+	uni2charset = page_uni2charset[ch];
+	if (uni2charset && uni2charset[cl])
+		out[0] = uni2charset[cl];
+	else
+		return -EINVAL;
+	return 1;
+}
+
+static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
+{
+	*uni = charset2uni[*rawstring];
+	if (*uni == 0x0000)
+		return -EINVAL;
+	return 1;
+}
+
+static struct nls_table table = {
+	"koi8-u",
+	uni2char,
+	char2uni,
+	charset2lower,
+	charset2upper,
+	THIS_MODULE,
+};
+
+static int __init init_nls_koi8_u(void)
+{
+	return register_nls(&table);
+}
+
+static void __exit exit_nls_koi8_u(void)
+{
+	unregister_nls(&table);
+}
+
+module_init(init_nls_koi8_u)
+module_exit(exit_nls_koi8_u)
+
+/*
+ * 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
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v2.4.3/linux/fs/nls/nls_tis-620.c linux/fs/nls/nls_tis-620.c
--- v2.4.3/linux/fs/nls/nls_tis-620.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/nls/nls_tis-620.c	Fri Apr  6 10:51:19 2001
@@ -0,0 +1,62 @@
+/*
+ * linux/fs/nls_tis-620.c
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/nls.h>
+#include <linux/errno.h>
+
+static struct nls_table *p_nls;
+
+static struct nls_table table = {
+	"tis-620",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	THIS_MODULE,
+};
+
+static int __init init_nls_tis_620(void)
+{
+	p_nls = load_nls("cp874");
+
+	if (p_nls) {
+		table.uni2char = p_nls->uni2char;
+		table.char2uni = p_nls->char2uni;
+		table.charset2upper = p_nls->charset2upper;
+		table.charset2lower = p_nls->charset2lower;
+		return register_nls(&table);
+	}
+
+	return -EINVAL;
+}
+
+static void __exit exit_nls_tis_620(void)
+{
+	unregister_nls(&table);
+	unload_nls(p_nls);
+}
+
+module_init(init_nls_tis_620)
+module_exit(exit_nls_tis_620)
+
+/*
+ * 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
+ * of the file.
+ *
+---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -u --recursive --new-file v2.4.3/linux/fs/proc/array.c linux/fs/proc/array.c
--- v2.4.3/linux/fs/proc/array.c	Mon Mar 19 12:34:55 2001
+++ linux/fs/proc/array.c	Fri Apr  6 10:51:19 2001
@@ -273,9 +273,6 @@
 {
 	char * orig = buffer;
 	struct mm_struct *mm;
-#if defined(CONFIG_ARCH_S390)
-	int line,len;
-#endif
 
 	buffer = task_name(task, buffer);
 	buffer = task_state(task, buffer);
@@ -291,8 +288,7 @@
 	buffer = task_sig(task, buffer);
 	buffer = task_cap(task, buffer);
 #if defined(CONFIG_ARCH_S390)
-	for(line=0;(len=sprintf_regs(line,buffer,task,NULL,NULL))!=0;line++)
-		buffer+=len;
+	buffer = task_show_regs(task, buffer);
 #endif
 	return buffer - orig;
 }
diff -u --recursive --new-file v2.4.3/linux/fs/vfat/namei.c linux/fs/vfat/namei.c
--- v2.4.3/linux/fs/vfat/namei.c	Fri Feb  9 11:29:44 2001
+++ linux/fs/vfat/namei.c	Fri Apr  6 10:51:19 2001
@@ -10,6 +10,9 @@
  *    the problem, send a script that demonstrates it.
  *
  *  Short name translation 1999 by Wolfram Pienkoss <wp@bszh.de>
+ *
+ *  Support Multibyte character and cleanup by
+ *  				OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
  */
 
 #define __NO_VERSION__
@@ -154,7 +157,7 @@
 	}
 	return 1;
 }
-
+#if 0 /* not used functions */
 static inline unsigned char
 vfat_getlower(struct nls_table *t, unsigned char c)
 {
@@ -162,62 +165,185 @@
 }
 
 static inline unsigned char
-vfat_tolower(struct nls_table *t, unsigned char c)
-{
-	unsigned char nc = t->charset2lower[c];
-
-	return nc ? nc : c;
-}
-
-static inline unsigned char
 vfat_getupper(struct nls_table *t, unsigned char c)
 {
 	return t->charset2upper[c];
 }
 
-static inline unsigned char
-vfat_toupper(struct nls_table *t, unsigned char c)
+static inline int
+vfat_uni2short(struct nls_table *t, wchar_t uc, unsigned char *op, int bound)
 {
-	unsigned char nc = t->charset2upper[c];
+	int charlen;
 
-	return nc ? nc : c;
+	if ( (charlen = t->uni2char(uc, op, bound)) < 0)
+		charlen = 0;
+
+	return charlen;
 }
 
-static int
-vfat_strnicmp(struct nls_table *t, const unsigned char *s1,
-					const unsigned char *s2, int len)
+static int vfat_valid_shortname(struct nls_table *nls, wchar_t *name, int len)
 {
-	while(len--)
-		if (vfat_tolower(t, *s1++) != vfat_tolower(t, *s2++))
-			return 1;
+	wchar_t *walk;
+	unsigned char c, charbuf[NLS_MAX_CHARSET_SIZE];
+	int chl, chi;
+	int space;
+
+	if (vfat_uni2upper_short(nls, *name, charbuf, NLS_MAX_CHARSET_SIZE) == 0)
+		return -EINVAL;
+
+	if (IS_FREE(charbuf))
+		return -EINVAL;
+
+	chl = 0;
+	c = 0;
+	space = 1; /* disallow names starting with a dot */
+	for (walk = name; len && walk-name < 8;) {
+		len--;
+		chl = nls->uni2char(*walk++, charbuf, NLS_MAX_CHARSET_SIZE);
+		if (chl < 0)
+			return -EINVAL;
+
+		for (chi = 0; chi < chl; chi++) {
+			c = vfat_getupper(nls, charbuf[chi]);
+			if (!c) return -EINVAL;
+			if (charbuf[chi] != vfat_tolower(nls, c)) return -EINVAL;
+			if (strchr(replace_chars,c)) return -EINVAL;
+			if (c < ' '|| c==':') return -EINVAL;
+			if (c == '.') goto dot;
+			space = c == ' ';
+		}
+	}
+dot:;
+	if (space) return -EINVAL;
+	if (len && c != '.') {
+		len--;
+		if (vfat_uni2upper_short(nls, *walk++, charbuf, NLS_MAX_CHARSET_SIZE) == 1) {
+			if (charbuf[0] != '.') return -EINVAL;
+		} else
+			return -EINVAL;
+		c = '.';
+	}
+	if (c == '.') {
+		if (len >= 4) return -EINVAL;
+		while (len > 0) {
+			len--;
+			chl = nls->uni2char(*walk++, charbuf, NLS_MAX_CHARSET_SIZE);
+			if (chl < 0)
+				return -EINVAL;
+			for (chi = 0; chi < chl; chi++) {
+				c = vfat_getupper(nls, charbuf[chi]);
+				if (!c) return -EINVAL;
+				if (charbuf[chi] != vfat_tolower(nls, c)) return -EINVAL;
+				if (strchr(replace_chars,c))
+					return -EINVAL;
+				if (c < ' ' || c == '.'|| c==':')
+					return -EINVAL;
+				space = c == ' ';
+			}
+		}
+		if (space) return -EINVAL;
+	}
 
 	return 0;
 }
 
-static inline int
-vfat_uni2short(struct nls_table *t, wchar_t uc, unsigned char *op, int bound)
+static int vfat_format_name(struct nls_table *nls, wchar_t *name,
+				int len, char *res)
 {
-	int charlen;
+	char *walk;
+	unsigned char charbuf[NLS_MAX_CHARSET_SIZE];
+	int chi, chl;
+	int space;
 
-	if ( (charlen = t->uni2char(uc, op, bound)) < 0)
-		charlen = 0;
+	if (vfat_uni2upper_short(nls, *name, charbuf, NLS_MAX_CHARSET_SIZE) == 0)
+		return -EINVAL;
 
-	return charlen;
+	if (IS_FREE(charbuf))
+		return -EINVAL;
+
+	space = 1; /* disallow names starting with a dot */
+	for (walk = res; len--; ) {
+		chl = vfat_uni2upper_short(nls, *name++, charbuf, NLS_MAX_CHARSET_SIZE);
+		if (chl == 0)
+			return -EINVAL;
+		for (chi = 0; chi < chl; chi++){
+			if (charbuf[chi] == '.') goto dot;
+			if (!charbuf[chi]) return -EINVAL;
+			if (walk-res == 8) return -EINVAL;
+			if (strchr(replace_chars,charbuf[chi])) return -EINVAL;
+			if (charbuf[chi] < ' '|| charbuf[chi]==':') return -EINVAL;
+			space = charbuf[chi] == ' ';
+			*walk = charbuf[chi];
+			walk++;
+		}
+	}
+dot:;
+	if (space) return -EINVAL;
+	if (len >= 0) {
+		while (walk-res < 8) *walk++ = ' ';
+		while (len > 0 && walk-res < MSDOS_NAME) {
+			chl = vfat_uni2upper_short(nls, *name++, charbuf, NLS_MAX_CHARSET_SIZE);
+			if (len < chl)
+				chl = len;
+			len -= chl;
+			for (chi = 0; chi < chl; chi++){
+				if (!charbuf[chi]) return -EINVAL;
+				if (strchr(replace_chars,charbuf[chi]))
+					return -EINVAL;
+				if (charbuf[chi] < ' ' || charbuf[chi] == '.'|| charbuf[chi]==':')
+					return -EINVAL;
+				space = charbuf[chi] == ' ';
+				*walk++ = charbuf[chi];
+			}
+		}
+		if (space) return -EINVAL;
+		if (len) return -EINVAL;
+	}
+	while (walk-res < MSDOS_NAME) *walk++ = ' ';
+
+	return 0;
 }
 
 static inline int
 vfat_uni2upper_short(struct nls_table *t, wchar_t uc, char *op, int bound)
 {
-	int chi, chl;
+	int chl;
 
 	if ( (chl = t->uni2char(uc, op, bound)) < 0)
 		chl = 0;
 
-	for (chi = 0; chi < chl; chi++)
-		op[chi] = vfat_toupper(t, op[chi]);
+	if (chl == 1)
+		op[0] = vfat_toupper(t, op[0]);
 
 	return chl;
 }
+#endif
+static inline unsigned char
+vfat_tolower(struct nls_table *t, unsigned char c)
+{
+	unsigned char nc = t->charset2lower[c];
+
+	return nc ? nc : c;
+}
+
+static inline unsigned char
+vfat_toupper(struct nls_table *t, unsigned char c)
+{
+	unsigned char nc = t->charset2upper[c];
+
+	return nc ? nc : c;
+}
+
+static int
+vfat_strnicmp(struct nls_table *t, const unsigned char *s1,
+					const unsigned char *s2, int len)
+{
+	while(len--)
+		if (vfat_tolower(t, *s1++) != vfat_tolower(t, *s2++))
+			return 1;
+
+	return 0;
+}
 
 /*
  * Compute the hash for the vfat name corresponding to the dentry.
@@ -383,8 +509,35 @@
 
 /* Characters that are undesirable in an MS-DOS file name */
 
-static char bad_chars[] = "*?<>|\":/\\";
-static char replace_chars[] = "[];,+=";
+static wchar_t bad_chars[] = {
+	/*  `*'     `?'     `<'    `>'      `|'     `"'     `:'     `/'     `\' */
+	0x002A, 0x003F, 0x003C, 0x003E, 0x007C, 0x0022, 0x003A, 0x002F, 0x005C, 0,
+};
+#define IS_BADCHAR(uni)	(vfat_unistrchr(bad_chars, (uni)) != NULL)
+
+static wchar_t replace_chars[] = {
+	/*  `['     `]'    `;'     `,'     `+'      `=' */
+	0x005B, 0x005D, 0x003B, 0x002C, 0x002B, 0x003D, 0,
+};
+#define IS_REPLACECHAR(uni)	(vfat_unistrchr(replace_chars, (uni)) != NULL)
+
+static inline wchar_t *vfat_unistrchr(const wchar_t *s, const wchar_t c)
+{
+	for(; *s != c; ++s)
+		if (*s == 0)
+			return NULL;
+	return (wchar_t *) s;
+}
+
+static inline int vfat_is_used_badchars(const wchar_t *s, int len)
+{
+	int i;
+	
+	for (i = 0; i < len; i++)
+		if (s[i] < 0x0020 || IS_BADCHAR(s[i]))
+			return -EINVAL;
+	return 0;
+}
 
 /* Checks the validity of a long MS-DOS filename */
 /* Returns negative number on error, 0 for a normal
@@ -393,18 +546,10 @@
 static int vfat_valid_longname(const char *name, int len, int xlate)
 {
 	const char **reserved, *walk;
-	unsigned char c;
-	int i, baselen;
+	int baselen;
 
 	if (len && name[len-1] == ' ') return -EINVAL;
 	if (len >= 256) return -EINVAL;
-	for (i = 0; i < len; i++) {
-		c = name[i];
-		if (xlate && c == ':') continue;
-		if (strchr(bad_chars,c)) {
-			return -EINVAL;
-		}
-	}
  	if (len < 3) return 0;
 
 	for (walk = name; *walk != 0 && *walk != '.'; walk++);
@@ -424,72 +569,6 @@
 	return 0;
 }
 
-static int vfat_valid_shortname(struct nls_table *nls, wchar_t *name, int len)
-{
-	wchar_t *walk;
-	unsigned char c, charbuf[NLS_MAX_CHARSET_SIZE];
-	int chl, chi;
-	int space;
-
-	if (vfat_uni2upper_short(nls, *name, charbuf, NLS_MAX_CHARSET_SIZE) == 0)
-		return -EINVAL;
-
-	if (IS_FREE(charbuf))
-		return -EINVAL;
-
-	chl = 0;
-	c = 0;
-	space = 1; /* disallow names starting with a dot */
-	for (walk = name; len && walk-name < 8;) {
-		len--;
-		chl = nls->uni2char(*walk++, charbuf, NLS_MAX_CHARSET_SIZE);
-		if (chl < 0)
-			return -EINVAL;
-
-		for (chi = 0; chi < chl; chi++) {
-			c = vfat_getupper(nls, charbuf[chi]);
-			if (!c) return -EINVAL;
-			if (charbuf[chi] != vfat_tolower(nls, c)) return -EINVAL;
-			if (strchr(replace_chars,c)) return -EINVAL;
-			if (c < ' '|| c==':') return -EINVAL;
-			if (c == '.') goto dot;
-			space = c == ' ';
-		}
-	}
-dot:;
-	if (space) return -EINVAL;
-	if (len && c != '.') {
-		len--;
-		if (vfat_uni2upper_short(nls, *walk++, charbuf, NLS_MAX_CHARSET_SIZE) == 1) {
-			if (charbuf[0] != '.') return -EINVAL;
-		} else
-			return -EINVAL;
-		c = '.';
-	}
-	if (c == '.') {
-		if (len >= 4) return -EINVAL;
-		while (len > 0) {
-			len--;
-			chl = nls->uni2char(*walk++, charbuf, NLS_MAX_CHARSET_SIZE);
-			if (chl < 0)
-				return -EINVAL;
-			for (chi = 0; chi < chl; chi++) {
-				c = vfat_getupper(nls, charbuf[chi]);
-				if (!c) return -EINVAL;
-				if (charbuf[chi] != vfat_tolower(nls, c)) return -EINVAL;
-				if (strchr(replace_chars,c))
-					return -EINVAL;
-				if (c < ' ' || c == '.'|| c==':')
-					return -EINVAL;
-				space = c == ' ';
-			}
-		}
-		if (space) return -EINVAL;
-	}
-
-	return 0;
-}
-
 static int vfat_find_form(struct inode *dir,char *name)
 {
 	struct msdos_dir_entry *de;
@@ -503,127 +582,62 @@
 	return 0;
 }
 
-static int vfat_format_name(struct nls_table *nls, wchar_t *name,
-				int len, char *res)
-{
-	char *walk;
-	unsigned char charbuf[NLS_MAX_CHARSET_SIZE];
-	int chi, chl;
-	int space;
-
-	if (vfat_uni2upper_short(nls, *name, charbuf, NLS_MAX_CHARSET_SIZE) == 0)
-		return -EINVAL;
-
-	if (IS_FREE(charbuf))
-		return -EINVAL;
-
-	space = 1; /* disallow names starting with a dot */
-	for (walk = res; len--; ) {
-		chl = vfat_uni2upper_short(nls, *name++, charbuf, NLS_MAX_CHARSET_SIZE);
-		if (chl == 0)
-			return -EINVAL;
-		for (chi = 0; chi < chl; chi++){
-			if (charbuf[chi] == '.') goto dot;
-			if (!charbuf[chi]) return -EINVAL;
-			if (walk-res == 8) return -EINVAL;
-			if (strchr(replace_chars,charbuf[chi])) return -EINVAL;
-			if (charbuf[chi] < ' '|| charbuf[chi]==':') return -EINVAL;
-			space = charbuf[chi] == ' ';
-			*walk = charbuf[chi];
-			walk++;
-		}
-	}
-dot:;
-	if (space) return -EINVAL;
-	if (len >= 0) {
-		while (walk-res < 8) *walk++ = ' ';
-		while (len > 0 && walk-res < MSDOS_NAME) {
-			chl = vfat_uni2upper_short(nls, *name++, charbuf, NLS_MAX_CHARSET_SIZE);
-			if (len < chl)
-				chl = len;
-			len -= chl;
-			for (chi = 0; chi < chl; chi++){
-				if (!charbuf[chi]) return -EINVAL;
-				if (strchr(replace_chars,charbuf[chi]))
-					return -EINVAL;
-				if (charbuf[chi] < ' ' || charbuf[chi] == '.'|| charbuf[chi]==':')
-					return -EINVAL;
-				space = charbuf[chi] == ' ';
-				*walk++ = charbuf[chi];
-			}
-		}
-		if (space) return -EINVAL;
-		if (len) return -EINVAL;
-	}
-	while (walk-res < MSDOS_NAME) *walk++ = ' ';
-
-	return 0;
-}
-
-static char skip_chars[] = ".:\"?<>| ";
+static wchar_t skip_chars[] = {
+	/*  `.'     ` ' */
+	0x002E, 0x0020, 0,
+};
+#define IS_SKIPCHAR(uni) \
+	((wchar_t)(uni) == skip_chars[0] || (wchar_t)(uni) == skip_chars[1])
 
 /* Given a valid longname, create a unique shortname.  Make sure the
  * shortname does not exist
+ * Returns negative number on error, 0 for a normal
+ * return, and 1 for valid shortname
  */
 static int vfat_create_shortname(struct inode *dir, struct nls_table *nls,
-					wchar_t *name, int len,
-					char *name_res)
+				 wchar_t *uname, int ulen,
+				 char *name_res)
 {
-	wchar_t *ip, *op, *ext_start, *end, *name_start;
-	wchar_t msdos_name[13];
-	char base[9], ext[4], buf[8], *p;
+	wchar_t *ip, *ext_start, *end, *name_start;
+	unsigned char base[9], ext[4], buf[8], *p;
 	unsigned char charbuf[NLS_MAX_CHARSET_SIZE];
 	int chl, chi;
-	int sz, extlen, baselen, i;
-
-	PRINTK2(("Entering vfat_create_shortname\n"));
-	chl = 0;
-	sz = 0;			/* Make compiler happy */
-	if (len <= 12) {
-		/* Do a case insensitive search if the name would be a valid
-		 * shortname if is were all capitalized.  However, do not
-		 * allow spaces in short names because Win95 scandisk does
-		 * not like that */
-		for (i = 0, op = &msdos_name[0], ip = name; ; i++, ip++, op++) {
-			if (i == len) {
-				if (vfat_format_name(nls, &msdos_name[0], len,
-							name_res) < 0)
-					break;
-				PRINTK3(("vfat_create_shortname 1\n"));
-				if (vfat_find_form(dir, name_res) < 0)
-					return 0;
-				return -EEXIST;
-			}
-			chl = vfat_uni2upper_short(nls, *ip, charbuf, NLS_MAX_CHARSET_SIZE);
-			for (chi = 0; chi < chl; chi++){
-				if (charbuf[chi] == ' ')
-					break;
-			}
-			if (chi < chl)
-				break;
+	int sz = 0, extlen, baselen, i, numtail_baselen, numtail2_baselen;
+	int is_uppercase, is_shortname;
 
-			*op = *ip;
-		}
-	}
+	/* 
+	 * 1) Valid characters for the 8.3 format alias are any
+	 * combination of letters, uppercase alphabets, digits, any of
+	 * the following special characters:
+	 *     $ % ' ` - @ { } ~ ! # ( ) & _ ^
+	 * In this case Longfilename is not stored in disk.
+	 *     
+	 * 2) File name is 8.3 format, but it contain the lowercase
+	 * alphabet etc. In this case numtail is not added, but
+	 * Longfilename is stored.
+	 * 
+	 * 3) When the one except for the above, or the following special
+	 * character are contained:
+	 *        .   [ ] ; , + =
+	 * numtail is added, and Longfilename must be stored in disk .
+	 */
+	is_uppercase = 1;
+	is_shortname = 1;
 
-	PRINTK3(("vfat_create_shortname 3\n"));
 	/* Now, we need to create a shortname from the long name */
-	ext_start = end = &name[len];
-	while (--ext_start >= name) {
-		chl = vfat_uni2upper_short(nls, *ext_start, charbuf, NLS_MAX_CHARSET_SIZE);
-		for (chi = 0; chi < chl; chi++) {
-			if (charbuf[chi] == '.') {
-				if (ext_start == end - 1) {
-					sz = len;
-					ext_start = NULL;
-				}
-				goto stop0;
+	ext_start = end = &uname[ulen];
+	while (--ext_start >= uname) {
+		if (*ext_start == 0x002E) { /* is `.' */
+			if (ext_start == end - 1) {
+				sz = ulen;
+				ext_start = NULL;
 			}
+			break;
 		}
 	}
-stop0:;	
-	if (ext_start == name - 1) {
-		sz = len;
+
+	if (ext_start == uname - 1) {
+		sz = ulen;
 		ext_start = NULL;
 	} else if (ext_start) {
 		/*
@@ -631,45 +645,63 @@
 		 * an extension eg. "...test".  In this case Win95
 		 * uses the extension as the name and sets no extension.
 		 */
-		name_start = &name[0];
-		while (name_start < ext_start)
-		{
-			chl = vfat_uni2upper_short(nls, *name_start, charbuf, NLS_MAX_CHARSET_SIZE);
-			if (chl == 0)
+		name_start = &uname[0];
+		while (name_start < ext_start) {
+			if (!IS_SKIPCHAR(*name_start))
 				break;
-			for (chi = 0; chi < chl; chi++)
-				if (!strchr(skip_chars, charbuf[chi])) {
-					goto stop1;
-				}
 			name_start++;
 		}
-stop1:;		
 		if (name_start != ext_start) {
-			sz = ext_start - name;
+			sz = ext_start - uname;
 			ext_start++;
 		} else {
-			sz = len;
+			sz = ulen;
 			ext_start=NULL;
 		}
 	}
 
-	for (baselen = i = 0, p = base, ip = name; i < sz && baselen < 8; i++, ip++)
+	numtail_baselen = 6;
+	numtail2_baselen = 2;
+	for (baselen = i = 0, p = base, ip = uname; i < sz; i++, ip++)
 	{
-		chl = vfat_uni2upper_short(nls, *ip, charbuf, NLS_MAX_CHARSET_SIZE);
-		if (chl == 0){
-			*p++ = '_';
-			baselen++;
+		if (IS_SKIPCHAR(*ip)) {
+			is_shortname = 0;
 			continue;
 		}
+		if (IS_REPLACECHAR(*ip)) {
+			is_shortname = 0;
+			charbuf[0] = '_';
+			chl = 1;
+		} else {
+			chl = nls->uni2char(*ip, charbuf, sizeof(charbuf));
+			if (chl <= 0) {
+				is_shortname = 0;
+				charbuf[0]  = '_';
+				chl = 1;
+			} else if (chl == 1) {
+				unsigned char c = charbuf[0];
+				charbuf[0] = vfat_toupper(nls, charbuf[0]);
+				if (c >= 0x7F || charbuf[0] != c)
+					is_uppercase = 0;
+			} else {
+				is_uppercase = 0;
+			}
+		}
 
+		if (baselen < 2 && (baselen + chl) > 2)
+			numtail2_baselen = baselen;
+		if (baselen < 6 && (baselen + chl) > 6)
+			numtail_baselen = baselen;
 		for (chi = 0; chi < chl; chi++){
-			if (!strchr(skip_chars, charbuf[chi])){
-				if (strchr(replace_chars, charbuf[chi]))
-					*p = '_';
-				else
-					*p = charbuf[chi];
-				p++; baselen++;
-			}
+			*p++ = charbuf[chi];
+			baselen++;
+			if (baselen >= 8)
+				break;
+		}
+		if (baselen >= 8) {
+			if ((chi < chl - 1) || (ip + 1) - uname < sz)
+				is_shortname = 0;
+			break;
 		}
 	}
 	if (baselen == 0) {
@@ -679,30 +711,51 @@
 	extlen = 0;
 	if (ext_start) {
 		for (p = ext, ip = ext_start; extlen < 3 && ip < end; ip++) {
-			chl = vfat_uni2upper_short(nls, *ip, charbuf, NLS_MAX_CHARSET_SIZE);
-			if (chl == 0) {
-				*p++ = '_';
-				extlen++;
+			if (IS_SKIPCHAR(*ip)) {
+				is_shortname = 0;
 				continue;
 			}
-
-			for (chi = 0; chi < chl; chi++) {
-				if (!strchr(skip_chars, charbuf[chi])) {
-					if (strchr(replace_chars, charbuf[chi]))
-						*p = '_';
-					else
-						*p = charbuf[chi];
-					p++; extlen++;
+			if (IS_REPLACECHAR(*ip)) {
+				is_shortname = 0;
+				charbuf[0] = '_';
+				chl = 1;
+			} else {
+				chl = nls->uni2char(*ip, charbuf, sizeof(charbuf));
+				if (chl <= 0) {
+					is_shortname = 0;
+					charbuf[0] = '_';
+					chl = 1;
+				} else if (chl == 1) {
+					unsigned char c = charbuf[0];
+					charbuf[0] = vfat_toupper(nls, charbuf[0]);
+					if (c >= 0x7F || charbuf[0] != c)
+						is_uppercase = 0;
+				} else {
+					is_uppercase = 0;
 				}
 			}
+				
+			if ((extlen + chl) > 3) {
+				is_shortname = 0;
+				break;
+			}
+			for (chi = 0; chi < chl; chi++) {
+				*p++ = charbuf[chi];
+				extlen++;
+			}
+			if (extlen >= 3) {
+				if (ip + 1 != end)
+					is_shortname = 0;
+				break;
+			}
 		}
 	}
 	ext[extlen] = '\0';
 	base[baselen] = '\0';
 
 	/* Yes, it can happen. ".\xe5" would do it. */
-	if (IS_FREE(base))
-		base[0]='_';
+	if (base[0] == DELETED_FLAG)
+		base[0] = 0x05;
 
 	/* OK, at this point we know that base is not longer than 8 symbols,
 	 * ext is not longer than 3, base is nonempty, both don't contain
@@ -712,6 +765,14 @@
 	memset(name_res, ' ', MSDOS_NAME);
 	memcpy(name_res,base,baselen);
 	memcpy(name_res+8,ext,extlen);
+
+	if (is_shortname) {
+		if (vfat_find_form(dir, name_res) < 0)
+			return is_uppercase;
+		else
+			return -EEXIST;
+	}
+	
 	if (MSDOS_SB(dir->i_sb)->options.numtail == 0)
 		if (vfat_find_form(dir, name_res) < 0)
 			return 0;
@@ -724,8 +785,10 @@
 	 * values for part of the base.
 	 */
 
-	if (baselen>6)
-		baselen = 6;
+	if (baselen>6) {
+		baselen = numtail_baselen;
+		name_res[7] = ' ';
+	}
 	name_res[baselen] = '~';
 	for (i = 1; i < 10; i++) {
 		name_res[baselen+1] = i + '0';
@@ -735,8 +798,10 @@
 
 	i = jiffies & 0xffff;
 	sz = (jiffies >> 16) & 0x7;
-	if (baselen>2)
-		baselen = 2;
+	if (baselen>2) {
+		baselen = numtail2_baselen;
+		name_res[7] = ' ';
+	}
 	name_res[baselen+4] = '~';
 	name_res[baselen+5] = '1' + sz;
 	while (1) {
@@ -868,15 +933,18 @@
 		goto out_free;
 
 	uname = (wchar_t *) page;
-	if (vfat_valid_shortname(nls_disk, uname, ulen) >= 0) {
-		res = vfat_format_name(nls_disk, uname, ulen, de->name);
-		if (!res)
-			goto out_free;
-	}
+	res = vfat_is_used_badchars(uname, ulen);
+	if (res < 0)
+		goto out_free;
 
 	res = vfat_create_shortname(dir, nls_disk, uname, ulen, msdos_name);
-	if (res)
+	if (res < 0)
+		goto out_free;
+	else if (res == 1) {
+		strncpy(de->name, msdos_name, MSDOS_NAME);
+		res = 0;
 		goto out_free;
+	}
 
 	*slots = unilen / 13;
 	for (cksum = i = 0; i < 11; i++) {
@@ -956,7 +1024,8 @@
 		goto cleanup;
 
 	res = vfat_build_slots(dir, qname->name, len, ds, &slots);
-	if (res < 0) goto cleanup;
+	if (res < 0)
+		goto cleanup;
 
 	offset = fat_add_entries(dir, slots, &bh1, &de1, &ino);
 	if (offset < 0) {
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/bitops.h linux/include/asm-cris/bitops.h
--- v2.4.3/linux/include/asm-cris/bitops.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/bitops.h	Fri Apr  6 10:51:19 2001
@@ -1,9 +1,12 @@
-/* $Id: bitops.h,v 1.3 2000/10/17 14:56:27 bjornw Exp $ */
+/* $Id: bitops.h,v 1.4 2001/02/28 04:26:11 hp Exp $ */
 /* all of these should probably be rewritten in assembler for speed. */
 
 #ifndef _CRIS_BITOPS_H
 #define _CRIS_BITOPS_H
 
+/* Currently this is unsuitable for consumption outside the kernel.  */
+#ifdef __KERNEL__ 
+
 #include <asm/system.h>
 
 /*
@@ -163,8 +166,6 @@
 
 #define find_first_zero_bit(addr, size) \
         find_next_zero_bit((addr), (size), 0)
-
-#ifdef __KERNEL__ 
 
 #define ext2_set_bit                 test_and_set_bit
 #define ext2_clear_bit               test_and_clear_bit
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/delay.h linux/include/asm-cris/delay.h
--- v2.4.3/linux/include/asm-cris/delay.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/delay.h	Fri Apr  6 10:51:19 2001
@@ -1,4 +1,4 @@
-/* $Id: delay.h,v 1.2 2000/08/08 16:36:41 bjornw Exp $ */
+/* $Id: delay.h,v 1.3 2001/02/23 13:47:33 bjornw Exp $ */
 
 #ifndef _CRIS_DELAY_H
 #define _CRIS_DELAY_H
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/eshlibld.h linux/include/asm-cris/eshlibld.h
--- v2.4.3/linux/include/asm-cris/eshlibld.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/eshlibld.h	Fri Apr  6 10:51:19 2001
@@ -12,7 +12,7 @@
 *! (C) Copyright 1998, 1999 Axis Communications AB, LUND, SWEDEN
 *!
 *!**************************************************************************/
-/* $Id: eshlibld.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $ */
+/* $Id: eshlibld.h,v 1.2 2001/02/23 13:47:33 bjornw Exp $ */
 
 #ifndef _cris_relocate_h
 #define _cris_relocate_h
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/etraxgpio.h linux/include/asm-cris/etraxgpio.h
--- v2.4.3/linux/include/asm-cris/etraxgpio.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/etraxgpio.h	Fri Apr  6 10:51:19 2001
@@ -0,0 +1,32 @@
+#ifndef _ASM_ETRAXGPIO_H
+#define _ASM_ETRAXGPIO_H
+
+/* etraxgpio _IOC_TYPE, bits 8 to 15 in ioctl cmd */
+
+#define ETRAXGPIO_IOCTYPE 43
+
+/* supported ioctl _IOC_NR's */
+
+#define IO_READBITS  0x1  /* read and return current port bits */
+#define IO_SETBITS   0x2  /* set the bits marked by 1 in the argument */
+#define IO_CLRBITS   0x3  /* clear the bits marked by 1 in the argument */
+
+/* the alarm is waited for by select() */
+
+#define IO_HIGHALARM 0x4  /* set alarm on high for bits marked by 1 */
+#define IO_LOWALARM  0x5  /* set alarm on low for bits marked by 1 */
+#define IO_CLRALARM  0x6  /* clear alarm for bits marked by 1 */
+
+/* LED ioctl */
+#define IO_LEDACTIVE_SET 0x7 /* set active led
+                              * 0=off, 1=green, 2=red, 3=yellow */
+
+/* GPIO direction ioctl's */
+#define IO_READDIR    0x8  /* Read direction 0=input 1=output */
+#define IO_SETINPUT   0x9  /* Set direction 0=unchanged 1=input, 
+                              returns current dir */
+#define IO_SETOUTPUT  0xA  /* Set direction 0=unchanged 1=output,
+                              returns current dir */
+
+#endif
+
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/etraxi2c.h linux/include/asm-cris/etraxi2c.h
--- v2.4.3/linux/include/asm-cris/etraxi2c.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/etraxi2c.h	Fri Apr  6 10:51:19 2001
@@ -0,0 +1,36 @@
+/* $Id: etraxi2c.h,v 1.1 2001/01/18 15:49:57 bjornw Exp $ */
+
+#ifndef _LINUX_ETRAXI2C_H
+#define _LINUX_ETRAXI2C_H
+
+/* etraxi2c _IOC_TYPE, bits 8 to 15 in ioctl cmd */
+
+#define ETRAXI2C_IOCTYPE 44
+
+/* supported ioctl _IOC_NR's */
+
+/* in write operations, the argument contains both i2c
+ * slave, register and value.
+ */
+
+#define I2C_WRITEARG(slave, reg, value) (((slave) << 16) | ((reg) << 8) | (value))
+#define I2C_READARG(slave, reg) (((slave) << 16) | ((reg) << 8))
+
+#define I2C_ARGSLAVE(arg) ((arg) >> 16)
+#define I2C_ARGREG(arg) (((arg) >> 8) & 0xff)
+#define I2C_ARGVALUE(arg) ((arg) & 0xff)
+
+#define I2C_WRITEREG 0x1   /* write to an i2c register */
+#define I2C_READREG  0x2   /* read from an i2c register */
+
+/*
+EXAMPLE usage:
+
+    i2c_arg = I2C_WRITEARG(STA013_WRITE_ADDR, reg, val);
+    ioctl(fd, _IO(ETRAXI2C_IOCTYPE, I2C_WRITEREG), i2c_arg);
+
+    i2c_arg = I2C_READARG(STA013_READ_ADDR, reg);
+    val = ioctl(fd, _IO(ETRAXI2C_IOCTYPE, I2C_READREG), i2c_arg);
+
+*/
+#endif
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/io.h linux/include/asm-cris/io.h
--- v2.4.3/linux/include/asm-cris/io.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/io.h	Fri Apr  6 10:51:19 2001
@@ -9,9 +9,9 @@
    use will be evident. */
 #ifdef CONFIG_SVINTO_SIM
   /* Let's use the ucsim interface since it lets us do write(2, ...) */
-#define SIMCOUT(s,len) asm ("moveq 4,r1\n\tmoveq 2,r10\n\tmove.d %0,r11\n\tmove.d %1,r12\
+#define SIMCOUT(s,len) asm ("moveq 4,r9\n\tmoveq 2,r10\n\tmove.d %0,r11\n\tmove.d %1,r12\
 \n\tpush irp\n\t.word 0xae3f\n\t.dword 0f\n\tjump -6809\n0:\n\tpop irp" \
-       : : "rm" (s), "rm" (len) : "r1","r10","r11","r12","memory")
+       : : "rm" (s), "rm" (len) : "r9","r10","r11","r12","memory")
 #define TRACE_ON() __extension__ \
  ({ int _Foofoo; __asm__ volatile ("bmod [%0],%0" : "=r" (_Foofoo) : "0" \
 			       (255)); _Foofoo; })
@@ -127,6 +127,13 @@
 static inline void * phys_to_virt(unsigned long address)
 {
 	return __va(address);
+}
+
+extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+
+extern inline void * ioremap (unsigned long offset, unsigned long size)
+{
+	return __ioremap(offset, size, 0);
 }
 
 /*
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/irq.h linux/include/asm-cris/irq.h
--- v2.4.3/linux/include/asm-cris/irq.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/irq.h	Fri Apr  6 10:51:19 2001
@@ -19,7 +19,7 @@
 
 #include <asm/sv_addr_ag.h>
 
-#define NR_IRQS 26     /* TODO: what is this for Etrax100/LX ? */
+#define NR_IRQS 32
 
 extern void disable_irq(unsigned int);
 extern void enable_irq(unsigned int);
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/processor.h linux/include/asm-cris/processor.h
--- v2.4.3/linux/include/asm-cris/processor.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/processor.h	Fri Apr  6 10:51:19 2001
@@ -1,7 +1,7 @@
 /*
  * include/asm-cris/processor.h
  *
- * Copyright (C) 2000 Axis Communications AB
+ * Copyright (C) 2000, 2001 Axis Communications AB
  *
  * Authors:         Bjorn Wesen        Initial version
  *
@@ -57,9 +57,6 @@
 /* saved stack-frame upon syscall entry, points to registers */
 
 #define current_regs() (current->thread.esp0)
-
-/* this lives in process.c */
-asmlinkage void set_esp0(unsigned long ssp);
 
 /* INIT_MMAP is the kernels map of memory, between KSEG_C and KSEG_D */
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/ptrace.h linux/include/asm-cris/ptrace.h
--- v2.4.3/linux/include/asm-cris/ptrace.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/ptrace.h	Fri Apr  6 10:51:19 2001
@@ -23,9 +23,8 @@
 #define PT_DCCR      17
 #define PT_SRP       18
 #define PT_IRP       19
-#define PT_MAX       19
-
-#define PT_USP       42    /* special case - USP is not in the pt_regs */
+#define PT_USP       20    /* special case - USP is not in the pt_regs */
+#define PT_MAX       20
 
 /* Frame types */
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/socket.h linux/include/asm-cris/socket.h
--- v2.4.3/linux/include/asm-cris/socket.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/socket.h	Fri Apr  6 10:51:19 2001
@@ -45,6 +45,8 @@
 #define SO_TIMESTAMP           29
 #define SCM_TIMESTAMP          SO_TIMESTAMP
 
+#define SO_ACCEPTCONN          30
+
 #if defined(__KERNEL__)
 /* Socket types. */
 #define SOCK_STREAM     1               /* stream (connection) socket   */
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/sv_addr.agh linux/include/asm-cris/sv_addr.agh
--- v2.4.3/linux/include/asm-cris/sv_addr.agh	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/sv_addr.agh	Fri Apr  6 10:51:19 2001
@@ -1,8 +1,8 @@
 /*
 !* This file was automatically generated by /n/asic/bin/reg_macro_gen
-!* from the file `etrax_ng_regs.rd'.
+!* from the file `/n/asic/projects/etrax_ng/doc/work/etrax_ng_regs.rd'.
 !* Editing within this file is thus not recommended,
-!* make the changes in `etrax_ng_regs.rd' instead.
+!* make the changes in `/n/asic/projects/etrax_ng/doc/work/etrax_ng_regs.rd' instead.
 !*/
 
 
@@ -103,6 +103,10 @@
 #define R_BUS_STATUS__flashw__bw16 0
 
 #define R_DRAM_TIMING (IO_TYPECAST_UDWORD 0xb0000008)
+#define R_DRAM_TIMING__sdram__BITNR 31
+#define R_DRAM_TIMING__sdram__WIDTH 1
+#define R_DRAM_TIMING__sdram__enable 1
+#define R_DRAM_TIMING__sdram__disable 0
 #define R_DRAM_TIMING__ref__BITNR 14
 #define R_DRAM_TIMING__ref__WIDTH 2
 #define R_DRAM_TIMING__ref__e52us 0
@@ -683,10 +687,6 @@
 #define R_GEN_CONFIG__usb1__WIDTH 1
 #define R_GEN_CONFIG__usb1__select 1
 #define R_GEN_CONFIG__usb1__disable 0
-#define R_GEN_CONFIG__p21__BITNR 28
-#define R_GEN_CONFIG__p21__WIDTH 1
-#define R_GEN_CONFIG__p21__select 1
-#define R_GEN_CONFIG__p21__disable 0
 #define R_GEN_CONFIG__g24dir__BITNR 27
 #define R_GEN_CONFIG__g24dir__WIDTH 1
 #define R_GEN_CONFIG__g24dir__in 0
@@ -2331,6 +2331,10 @@
 #define R_NETWORK_GA_1__ga_high__WIDTH 32
 
 #define R_NETWORK_REC_CONFIG (IO_TYPECAST_UDWORD 0xb0000094)
+#define R_NETWORK_REC_CONFIG__max_size__BITNR 10
+#define R_NETWORK_REC_CONFIG__max_size__WIDTH 1
+#define R_NETWORK_REC_CONFIG__max_size__size1518 0
+#define R_NETWORK_REC_CONFIG__max_size__size1522 1
 #define R_NETWORK_REC_CONFIG__duplex__BITNR 9
 #define R_NETWORK_REC_CONFIG__duplex__WIDTH 1
 #define R_NETWORK_REC_CONFIG__duplex__full 1
@@ -2535,6 +2539,10 @@
 #define R_PAR0_STATUS_DATA__mode__ecp_fwd 5
 #define R_PAR0_STATUS_DATA__mode__ecp_rev 6
 #define R_PAR0_STATUS_DATA__mode__off 7
+#define R_PAR0_STATUS_DATA__mode__epp_wr1 5
+#define R_PAR0_STATUS_DATA__mode__epp_wr2 6
+#define R_PAR0_STATUS_DATA__mode__epp_wr3 7
+#define R_PAR0_STATUS_DATA__mode__epp_rd 0
 #define R_PAR0_STATUS_DATA__perr__BITNR 28
 #define R_PAR0_STATUS_DATA__perr__WIDTH 1
 #define R_PAR0_STATUS_DATA__perr__active 1
@@ -2555,6 +2563,14 @@
 #define R_PAR0_STATUS_DATA__sel__WIDTH 1
 #define R_PAR0_STATUS_DATA__sel__active 1
 #define R_PAR0_STATUS_DATA__sel__inactive 0
+#define R_PAR0_STATUS_DATA__ext_mode__BITNR 23
+#define R_PAR0_STATUS_DATA__ext_mode__WIDTH 1
+#define R_PAR0_STATUS_DATA__ext_mode__enable 1
+#define R_PAR0_STATUS_DATA__ext_mode__disable 0
+#define R_PAR0_STATUS_DATA__ecp_16__BITNR 22
+#define R_PAR0_STATUS_DATA__ecp_16__WIDTH 1
+#define R_PAR0_STATUS_DATA__ecp_16__active 1
+#define R_PAR0_STATUS_DATA__ecp_16__inactive 0
 #define R_PAR0_STATUS_DATA__tr_rdy__BITNR 17
 #define R_PAR0_STATUS_DATA__tr_rdy__WIDTH 1
 #define R_PAR0_STATUS_DATA__tr_rdy__ready 1
@@ -2570,7 +2586,59 @@
 #define R_PAR0_STATUS_DATA__data__BITNR 0
 #define R_PAR0_STATUS_DATA__data__WIDTH 8
 
-#define R_PAR_ECP16_DATA (IO_TYPECAST_RO_UWORD 0xb0000040)
+#define R_PAR0_STATUS (IO_TYPECAST_RO_UWORD 0xb0000042)
+#define R_PAR0_STATUS__mode__BITNR 13
+#define R_PAR0_STATUS__mode__WIDTH 3
+#define R_PAR0_STATUS__mode__manual 0
+#define R_PAR0_STATUS__mode__centronics 1
+#define R_PAR0_STATUS__mode__fastbyte 2
+#define R_PAR0_STATUS__mode__nibble 3
+#define R_PAR0_STATUS__mode__byte 4
+#define R_PAR0_STATUS__mode__ecp_fwd 5
+#define R_PAR0_STATUS__mode__ecp_rev 6
+#define R_PAR0_STATUS__mode__off 7
+#define R_PAR0_STATUS__mode__epp_wr1 5
+#define R_PAR0_STATUS__mode__epp_wr2 6
+#define R_PAR0_STATUS__mode__epp_wr3 7
+#define R_PAR0_STATUS__mode__epp_rd 0
+#define R_PAR0_STATUS__perr__BITNR 12
+#define R_PAR0_STATUS__perr__WIDTH 1
+#define R_PAR0_STATUS__perr__active 1
+#define R_PAR0_STATUS__perr__inactive 0
+#define R_PAR0_STATUS__ack__BITNR 11
+#define R_PAR0_STATUS__ack__WIDTH 1
+#define R_PAR0_STATUS__ack__active 0
+#define R_PAR0_STATUS__ack__inactive 1
+#define R_PAR0_STATUS__busy__BITNR 10
+#define R_PAR0_STATUS__busy__WIDTH 1
+#define R_PAR0_STATUS__busy__active 1
+#define R_PAR0_STATUS__busy__inactive 0
+#define R_PAR0_STATUS__fault__BITNR 9
+#define R_PAR0_STATUS__fault__WIDTH 1
+#define R_PAR0_STATUS__fault__active 0
+#define R_PAR0_STATUS__fault__inactive 1
+#define R_PAR0_STATUS__sel__BITNR 8
+#define R_PAR0_STATUS__sel__WIDTH 1
+#define R_PAR0_STATUS__sel__active 1
+#define R_PAR0_STATUS__sel__inactive 0
+#define R_PAR0_STATUS__ext_mode__BITNR 7
+#define R_PAR0_STATUS__ext_mode__WIDTH 1
+#define R_PAR0_STATUS__ext_mode__enable 1
+#define R_PAR0_STATUS__ext_mode__disable 0
+#define R_PAR0_STATUS__ecp_16__BITNR 6
+#define R_PAR0_STATUS__ecp_16__WIDTH 1
+#define R_PAR0_STATUS__ecp_16__active 1
+#define R_PAR0_STATUS__ecp_16__inactive 0
+#define R_PAR0_STATUS__tr_rdy__BITNR 1
+#define R_PAR0_STATUS__tr_rdy__WIDTH 1
+#define R_PAR0_STATUS__tr_rdy__ready 1
+#define R_PAR0_STATUS__tr_rdy__busy 0
+#define R_PAR0_STATUS__dav__BITNR 0
+#define R_PAR0_STATUS__dav__WIDTH 1
+#define R_PAR0_STATUS__dav__data 1
+#define R_PAR0_STATUS__dav__nodata 0
+
+#define R_PAR_ECP16_DATA (IO_TYPECAST_UWORD 0xb0000040)
 #define R_PAR_ECP16_DATA__data__BITNR 0
 #define R_PAR_ECP16_DATA__data__WIDTH 16
 
@@ -2669,6 +2737,10 @@
 #define R_PAR0_CONFIG__mode__ecp_fwd 5
 #define R_PAR0_CONFIG__mode__ecp_rev 6
 #define R_PAR0_CONFIG__mode__off 7
+#define R_PAR0_CONFIG__mode__epp_wr1 5
+#define R_PAR0_CONFIG__mode__epp_wr2 6
+#define R_PAR0_CONFIG__mode__epp_wr3 7
+#define R_PAR0_CONFIG__mode__epp_rd 0
 
 #define R_PAR0_DELAY (IO_TYPECAST_UDWORD 0xb0000048)
 #define R_PAR0_DELAY__fine_hold__BITNR 21
@@ -2731,6 +2803,10 @@
 #define R_PAR1_STATUS_DATA__mode__ecp_fwd 5
 #define R_PAR1_STATUS_DATA__mode__ecp_rev 6
 #define R_PAR1_STATUS_DATA__mode__off 7
+#define R_PAR1_STATUS_DATA__mode__epp_wr1 5
+#define R_PAR1_STATUS_DATA__mode__epp_wr2 6
+#define R_PAR1_STATUS_DATA__mode__epp_wr3 7
+#define R_PAR1_STATUS_DATA__mode__epp_rd 0
 #define R_PAR1_STATUS_DATA__perr__BITNR 28
 #define R_PAR1_STATUS_DATA__perr__WIDTH 1
 #define R_PAR1_STATUS_DATA__perr__active 1
@@ -2751,6 +2827,10 @@
 #define R_PAR1_STATUS_DATA__sel__WIDTH 1
 #define R_PAR1_STATUS_DATA__sel__active 1
 #define R_PAR1_STATUS_DATA__sel__inactive 0
+#define R_PAR1_STATUS_DATA__ext_mode__BITNR 23
+#define R_PAR1_STATUS_DATA__ext_mode__WIDTH 1
+#define R_PAR1_STATUS_DATA__ext_mode__enable 1
+#define R_PAR1_STATUS_DATA__ext_mode__disable 0
 #define R_PAR1_STATUS_DATA__tr_rdy__BITNR 17
 #define R_PAR1_STATUS_DATA__tr_rdy__WIDTH 1
 #define R_PAR1_STATUS_DATA__tr_rdy__ready 1
@@ -2766,6 +2846,54 @@
 #define R_PAR1_STATUS_DATA__data__BITNR 0
 #define R_PAR1_STATUS_DATA__data__WIDTH 8
 
+#define R_PAR1_STATUS (IO_TYPECAST_RO_UWORD 0xb0000052)
+#define R_PAR1_STATUS__mode__BITNR 13
+#define R_PAR1_STATUS__mode__WIDTH 3
+#define R_PAR1_STATUS__mode__manual 0
+#define R_PAR1_STATUS__mode__centronics 1
+#define R_PAR1_STATUS__mode__fastbyte 2
+#define R_PAR1_STATUS__mode__nibble 3
+#define R_PAR1_STATUS__mode__byte 4
+#define R_PAR1_STATUS__mode__ecp_fwd 5
+#define R_PAR1_STATUS__mode__ecp_rev 6
+#define R_PAR1_STATUS__mode__off 7
+#define R_PAR1_STATUS__mode__epp_wr1 5
+#define R_PAR1_STATUS__mode__epp_wr2 6
+#define R_PAR1_STATUS__mode__epp_wr3 7
+#define R_PAR1_STATUS__mode__epp_rd 0
+#define R_PAR1_STATUS__perr__BITNR 12
+#define R_PAR1_STATUS__perr__WIDTH 1
+#define R_PAR1_STATUS__perr__active 1
+#define R_PAR1_STATUS__perr__inactive 0
+#define R_PAR1_STATUS__ack__BITNR 11
+#define R_PAR1_STATUS__ack__WIDTH 1
+#define R_PAR1_STATUS__ack__active 0
+#define R_PAR1_STATUS__ack__inactive 1
+#define R_PAR1_STATUS__busy__BITNR 10
+#define R_PAR1_STATUS__busy__WIDTH 1
+#define R_PAR1_STATUS__busy__active 1
+#define R_PAR1_STATUS__busy__inactive 0
+#define R_PAR1_STATUS__fault__BITNR 9
+#define R_PAR1_STATUS__fault__WIDTH 1
+#define R_PAR1_STATUS__fault__active 0
+#define R_PAR1_STATUS__fault__inactive 1
+#define R_PAR1_STATUS__sel__BITNR 8
+#define R_PAR1_STATUS__sel__WIDTH 1
+#define R_PAR1_STATUS__sel__active 1
+#define R_PAR1_STATUS__sel__inactive 0
+#define R_PAR1_STATUS__ext_mode__BITNR 7
+#define R_PAR1_STATUS__ext_mode__WIDTH 1
+#define R_PAR1_STATUS__ext_mode__enable 1
+#define R_PAR1_STATUS__ext_mode__disable 0
+#define R_PAR1_STATUS__tr_rdy__BITNR 1
+#define R_PAR1_STATUS__tr_rdy__WIDTH 1
+#define R_PAR1_STATUS__tr_rdy__ready 1
+#define R_PAR1_STATUS__tr_rdy__busy 0
+#define R_PAR1_STATUS__dav__BITNR 0
+#define R_PAR1_STATUS__dav__WIDTH 1
+#define R_PAR1_STATUS__dav__data 1
+#define R_PAR1_STATUS__dav__nodata 0
+
 #define R_PAR1_CONFIG (IO_TYPECAST_UDWORD 0xb0000054)
 #define R_PAR1_CONFIG__ioe__BITNR 25
 #define R_PAR1_CONFIG__ioe__WIDTH 1
@@ -2857,6 +2985,10 @@
 #define R_PAR1_CONFIG__mode__ecp_fwd 5
 #define R_PAR1_CONFIG__mode__ecp_rev 6
 #define R_PAR1_CONFIG__mode__off 7
+#define R_PAR1_CONFIG__mode__epp_wr1 5
+#define R_PAR1_CONFIG__mode__epp_wr2 6
+#define R_PAR1_CONFIG__mode__epp_wr3 7
+#define R_PAR1_CONFIG__mode__epp_rd 0
 
 #define R_PAR1_DELAY (IO_TYPECAST_UDWORD 0xb0000058)
 #define R_PAR1_DELAY__fine_hold__BITNR 21
@@ -3437,10 +3569,6 @@
 #define R_IRQ_MASK0_RD__ata_irq2__WIDTH 1
 #define R_IRQ_MASK0_RD__ata_irq2__active 1
 #define R_IRQ_MASK0_RD__ata_irq2__inactive 0
-#define R_IRQ_MASK0_RD__p21_irq2__BITNR 10
-#define R_IRQ_MASK0_RD__p21_irq2__WIDTH 1
-#define R_IRQ_MASK0_RD__p21_irq2__active 1
-#define R_IRQ_MASK0_RD__p21_irq2__inactive 0
 #define R_IRQ_MASK0_RD__par0_data__BITNR 9
 #define R_IRQ_MASK0_RD__par0_data__WIDTH 1
 #define R_IRQ_MASK0_RD__par0_data__active 1
@@ -3449,10 +3577,6 @@
 #define R_IRQ_MASK0_RD__ata_irq1__WIDTH 1
 #define R_IRQ_MASK0_RD__ata_irq1__active 1
 #define R_IRQ_MASK0_RD__ata_irq1__inactive 0
-#define R_IRQ_MASK0_RD__p21_irq1__BITNR 9
-#define R_IRQ_MASK0_RD__p21_irq1__WIDTH 1
-#define R_IRQ_MASK0_RD__p21_irq1__active 1
-#define R_IRQ_MASK0_RD__p21_irq1__inactive 0
 #define R_IRQ_MASK0_RD__par0_ready__BITNR 8
 #define R_IRQ_MASK0_RD__par0_ready__WIDTH 1
 #define R_IRQ_MASK0_RD__par0_ready__active 1
@@ -3469,10 +3593,6 @@
 #define R_IRQ_MASK0_RD__scsi0__WIDTH 1
 #define R_IRQ_MASK0_RD__scsi0__active 1
 #define R_IRQ_MASK0_RD__scsi0__inactive 0
-#define R_IRQ_MASK0_RD__p21_irq0__BITNR 8
-#define R_IRQ_MASK0_RD__p21_irq0__WIDTH 1
-#define R_IRQ_MASK0_RD__p21_irq0__active 1
-#define R_IRQ_MASK0_RD__p21_irq0__inactive 0
 #define R_IRQ_MASK0_RD__ata_dmaend__BITNR 7
 #define R_IRQ_MASK0_RD__ata_dmaend__WIDTH 1
 #define R_IRQ_MASK0_RD__ata_dmaend__active 1
@@ -3599,10 +3719,6 @@
 #define R_IRQ_MASK0_CLR__ata_irq2__WIDTH 1
 #define R_IRQ_MASK0_CLR__ata_irq2__clr 1
 #define R_IRQ_MASK0_CLR__ata_irq2__nop 0
-#define R_IRQ_MASK0_CLR__p21_irq2__BITNR 10
-#define R_IRQ_MASK0_CLR__p21_irq2__WIDTH 1
-#define R_IRQ_MASK0_CLR__p21_irq2__clr 1
-#define R_IRQ_MASK0_CLR__p21_irq2__nop 0
 #define R_IRQ_MASK0_CLR__par0_data__BITNR 9
 #define R_IRQ_MASK0_CLR__par0_data__WIDTH 1
 #define R_IRQ_MASK0_CLR__par0_data__clr 1
@@ -3611,10 +3727,6 @@
 #define R_IRQ_MASK0_CLR__ata_irq1__WIDTH 1
 #define R_IRQ_MASK0_CLR__ata_irq1__clr 1
 #define R_IRQ_MASK0_CLR__ata_irq1__nop 0
-#define R_IRQ_MASK0_CLR__p21_irq1__BITNR 9
-#define R_IRQ_MASK0_CLR__p21_irq1__WIDTH 1
-#define R_IRQ_MASK0_CLR__p21_irq1__clr 1
-#define R_IRQ_MASK0_CLR__p21_irq1__nop 0
 #define R_IRQ_MASK0_CLR__par0_ready__BITNR 8
 #define R_IRQ_MASK0_CLR__par0_ready__WIDTH 1
 #define R_IRQ_MASK0_CLR__par0_ready__clr 1
@@ -3631,10 +3743,6 @@
 #define R_IRQ_MASK0_CLR__scsi0__WIDTH 1
 #define R_IRQ_MASK0_CLR__scsi0__clr 1
 #define R_IRQ_MASK0_CLR__scsi0__nop 0
-#define R_IRQ_MASK0_CLR__p21_irq0__BITNR 8
-#define R_IRQ_MASK0_CLR__p21_irq0__WIDTH 1
-#define R_IRQ_MASK0_CLR__p21_irq0__clr 1
-#define R_IRQ_MASK0_CLR__p21_irq0__nop 0
 #define R_IRQ_MASK0_CLR__ata_dmaend__BITNR 7
 #define R_IRQ_MASK0_CLR__ata_dmaend__WIDTH 1
 #define R_IRQ_MASK0_CLR__ata_dmaend__clr 1
@@ -3761,10 +3869,6 @@
 #define R_IRQ_READ0__ata_irq2__WIDTH 1
 #define R_IRQ_READ0__ata_irq2__active 1
 #define R_IRQ_READ0__ata_irq2__inactive 0
-#define R_IRQ_READ0__p21_irq2__BITNR 10
-#define R_IRQ_READ0__p21_irq2__WIDTH 1
-#define R_IRQ_READ0__p21_irq2__active 1
-#define R_IRQ_READ0__p21_irq2__inactive 0
 #define R_IRQ_READ0__par0_data__BITNR 9
 #define R_IRQ_READ0__par0_data__WIDTH 1
 #define R_IRQ_READ0__par0_data__active 1
@@ -3773,10 +3877,6 @@
 #define R_IRQ_READ0__ata_irq1__WIDTH 1
 #define R_IRQ_READ0__ata_irq1__active 1
 #define R_IRQ_READ0__ata_irq1__inactive 0
-#define R_IRQ_READ0__p21_irq1__BITNR 9
-#define R_IRQ_READ0__p21_irq1__WIDTH 1
-#define R_IRQ_READ0__p21_irq1__active 1
-#define R_IRQ_READ0__p21_irq1__inactive 0
 #define R_IRQ_READ0__par0_ready__BITNR 8
 #define R_IRQ_READ0__par0_ready__WIDTH 1
 #define R_IRQ_READ0__par0_ready__active 1
@@ -3793,10 +3893,6 @@
 #define R_IRQ_READ0__scsi0__WIDTH 1
 #define R_IRQ_READ0__scsi0__active 1
 #define R_IRQ_READ0__scsi0__inactive 0
-#define R_IRQ_READ0__p21_irq0__BITNR 8
-#define R_IRQ_READ0__p21_irq0__WIDTH 1
-#define R_IRQ_READ0__p21_irq0__active 1
-#define R_IRQ_READ0__p21_irq0__inactive 0
 #define R_IRQ_READ0__ata_dmaend__BITNR 7
 #define R_IRQ_READ0__ata_dmaend__WIDTH 1
 #define R_IRQ_READ0__ata_dmaend__active 1
@@ -3923,10 +4019,6 @@
 #define R_IRQ_MASK0_SET__ata_irq2__WIDTH 1
 #define R_IRQ_MASK0_SET__ata_irq2__set 1
 #define R_IRQ_MASK0_SET__ata_irq2__nop 0
-#define R_IRQ_MASK0_SET__p21_irq2__BITNR 10
-#define R_IRQ_MASK0_SET__p21_irq2__WIDTH 1
-#define R_IRQ_MASK0_SET__p21_irq2__set 1
-#define R_IRQ_MASK0_SET__p21_irq2__nop 0
 #define R_IRQ_MASK0_SET__par0_data__BITNR 9
 #define R_IRQ_MASK0_SET__par0_data__WIDTH 1
 #define R_IRQ_MASK0_SET__par0_data__set 1
@@ -3935,10 +4027,6 @@
 #define R_IRQ_MASK0_SET__ata_irq1__WIDTH 1
 #define R_IRQ_MASK0_SET__ata_irq1__set 1
 #define R_IRQ_MASK0_SET__ata_irq1__nop 0
-#define R_IRQ_MASK0_SET__p21_irq1__BITNR 9
-#define R_IRQ_MASK0_SET__p21_irq1__WIDTH 1
-#define R_IRQ_MASK0_SET__p21_irq1__set 1
-#define R_IRQ_MASK0_SET__p21_irq1__nop 0
 #define R_IRQ_MASK0_SET__par0_ready__BITNR 8
 #define R_IRQ_MASK0_SET__par0_ready__WIDTH 1
 #define R_IRQ_MASK0_SET__par0_ready__set 1
@@ -3955,10 +4043,6 @@
 #define R_IRQ_MASK0_SET__scsi0__WIDTH 1
 #define R_IRQ_MASK0_SET__scsi0__set 1
 #define R_IRQ_MASK0_SET__scsi0__nop 0
-#define R_IRQ_MASK0_SET__p21_irq0__BITNR 8
-#define R_IRQ_MASK0_SET__p21_irq0__WIDTH 1
-#define R_IRQ_MASK0_SET__p21_irq0__set 1
-#define R_IRQ_MASK0_SET__p21_irq0__nop 0
 #define R_IRQ_MASK0_SET__ata_dmaend__BITNR 7
 #define R_IRQ_MASK0_SET__ata_dmaend__WIDTH 1
 #define R_IRQ_MASK0_SET__ata_dmaend__set 1
@@ -4953,10 +5037,6 @@
 #define R_VECT_MASK_RD__mio__WIDTH 1
 #define R_VECT_MASK_RD__mio__active 1
 #define R_VECT_MASK_RD__mio__inactive 0
-#define R_VECT_MASK_RD__p21__BITNR 4
-#define R_VECT_MASK_RD__p21__WIDTH 1
-#define R_VECT_MASK_RD__p21__active 1
-#define R_VECT_MASK_RD__p21__inactive 0
 #define R_VECT_MASK_RD__timer1__BITNR 3
 #define R_VECT_MASK_RD__timer1__WIDTH 1
 #define R_VECT_MASK_RD__timer1__active 1
@@ -5075,10 +5155,6 @@
 #define R_VECT_MASK_CLR__mio__WIDTH 1
 #define R_VECT_MASK_CLR__mio__clr 1
 #define R_VECT_MASK_CLR__mio__nop 0
-#define R_VECT_MASK_CLR__p21__BITNR 4
-#define R_VECT_MASK_CLR__p21__WIDTH 1
-#define R_VECT_MASK_CLR__p21__clr 1
-#define R_VECT_MASK_CLR__p21__nop 0
 #define R_VECT_MASK_CLR__timer1__BITNR 3
 #define R_VECT_MASK_CLR__timer1__WIDTH 1
 #define R_VECT_MASK_CLR__timer1__clr 1
@@ -5197,10 +5273,6 @@
 #define R_VECT_READ__mio__WIDTH 1
 #define R_VECT_READ__mio__active 1
 #define R_VECT_READ__mio__inactive 0
-#define R_VECT_READ__p21__BITNR 4
-#define R_VECT_READ__p21__WIDTH 1
-#define R_VECT_READ__p21__active 1
-#define R_VECT_READ__p21__inactive 0
 #define R_VECT_READ__timer1__BITNR 3
 #define R_VECT_READ__timer1__WIDTH 1
 #define R_VECT_READ__timer1__active 1
@@ -5319,10 +5391,6 @@
 #define R_VECT_MASK_SET__mio__WIDTH 1
 #define R_VECT_MASK_SET__mio__set 1
 #define R_VECT_MASK_SET__mio__nop 0
-#define R_VECT_MASK_SET__p21__BITNR 4
-#define R_VECT_MASK_SET__p21__WIDTH 1
-#define R_VECT_MASK_SET__p21__set 1
-#define R_VECT_MASK_SET__p21__nop 0
 #define R_VECT_MASK_SET__timer1__BITNR 3
 #define R_VECT_MASK_SET__timer1__WIDTH 1
 #define R_VECT_MASK_SET__timer1__set 1
@@ -5997,6 +6065,10 @@
 #define R_USB_COMMAND__port_cmd__disable 1
 #define R_USB_COMMAND__port_cmd__suspend 2
 #define R_USB_COMMAND__port_cmd__resume 3
+#define R_USB_COMMAND__busy__BITNR 3
+#define R_USB_COMMAND__busy__WIDTH 1
+#define R_USB_COMMAND__busy__no 0
+#define R_USB_COMMAND__busy__yes 1
 #define R_USB_COMMAND__ctrl_cmd__BITNR 0
 #define R_USB_COMMAND__ctrl_cmd__WIDTH 3
 #define R_USB_COMMAND__ctrl_cmd__nop 0
@@ -6004,15 +6076,47 @@
 #define R_USB_COMMAND__ctrl_cmd__deconfig 2
 #define R_USB_COMMAND__ctrl_cmd__host_config 3
 #define R_USB_COMMAND__ctrl_cmd__dev_config 4
-#define R_USB_COMMAND__ctrl_cmd__host_reset 5
+#define R_USB_COMMAND__ctrl_cmd__host_nop 5
 #define R_USB_COMMAND__ctrl_cmd__host_run 6
 #define R_USB_COMMAND__ctrl_cmd__host_stop 7
 
+#define R_USB_COMMAND_DEV (IO_TYPECAST_BYTE 0xb0000201)
+#define R_USB_COMMAND_DEV__port_sel__BITNR 6
+#define R_USB_COMMAND_DEV__port_sel__WIDTH 2
+#define R_USB_COMMAND_DEV__port_sel__nop 0
+#define R_USB_COMMAND_DEV__port_sel__dummy1 1
+#define R_USB_COMMAND_DEV__port_sel__dummy2 2
+#define R_USB_COMMAND_DEV__port_sel__any 3
+#define R_USB_COMMAND_DEV__port_cmd__BITNR 4
+#define R_USB_COMMAND_DEV__port_cmd__WIDTH 2
+#define R_USB_COMMAND_DEV__port_cmd__active 0
+#define R_USB_COMMAND_DEV__port_cmd__passive 1
+#define R_USB_COMMAND_DEV__port_cmd__nop 2
+#define R_USB_COMMAND_DEV__port_cmd__wakeup 3
+#define R_USB_COMMAND_DEV__busy__BITNR 3
+#define R_USB_COMMAND_DEV__busy__WIDTH 1
+#define R_USB_COMMAND_DEV__busy__no 0
+#define R_USB_COMMAND_DEV__busy__yes 1
+#define R_USB_COMMAND_DEV__ctrl_cmd__BITNR 0
+#define R_USB_COMMAND_DEV__ctrl_cmd__WIDTH 3
+#define R_USB_COMMAND_DEV__ctrl_cmd__nop 0
+#define R_USB_COMMAND_DEV__ctrl_cmd__reset 1
+#define R_USB_COMMAND_DEV__ctrl_cmd__deconfig 2
+#define R_USB_COMMAND_DEV__ctrl_cmd__host_config 3
+#define R_USB_COMMAND_DEV__ctrl_cmd__dev_config 4
+#define R_USB_COMMAND_DEV__ctrl_cmd__dev_active 5
+#define R_USB_COMMAND_DEV__ctrl_cmd__dev_passive 6
+#define R_USB_COMMAND_DEV__ctrl_cmd__dev_nop 7
+
 #define R_USB_STATUS (IO_TYPECAST_RO_BYTE 0xb0000202)
-#define R_USB_STATUS__busy__BITNR 7
-#define R_USB_STATUS__busy__WIDTH 1
-#define R_USB_STATUS__busy__no 0
-#define R_USB_STATUS__busy__yes 1
+#define R_USB_STATUS__ourun__BITNR 5
+#define R_USB_STATUS__ourun__WIDTH 1
+#define R_USB_STATUS__ourun__no 0
+#define R_USB_STATUS__ourun__yes 1
+#define R_USB_STATUS__perror__BITNR 4
+#define R_USB_STATUS__perror__WIDTH 1
+#define R_USB_STATUS__perror__no 0
+#define R_USB_STATUS__perror__yes 1
 #define R_USB_STATUS__device_mode__BITNR 3
 #define R_USB_STATUS__device_mode__WIDTH 1
 #define R_USB_STATUS__device_mode__no 0
@@ -6031,30 +6135,34 @@
 #define R_USB_STATUS__running__yes 1
 
 #define R_USB_IRQ_MASK_SET (IO_TYPECAST_UWORD 0xb0000204)
-#define R_USB_IRQ_MASK_SET__intr_eof__BITNR 13
-#define R_USB_IRQ_MASK_SET__intr_eof__WIDTH 1
-#define R_USB_IRQ_MASK_SET__intr_eof__nop 0
-#define R_USB_IRQ_MASK_SET__intr_eof__set 1
-#define R_USB_IRQ_MASK_SET__iso_eof__BITNR 12
+#define R_USB_IRQ_MASK_SET__iso_eof__BITNR 13
 #define R_USB_IRQ_MASK_SET__iso_eof__WIDTH 1
 #define R_USB_IRQ_MASK_SET__iso_eof__nop 0
 #define R_USB_IRQ_MASK_SET__iso_eof__set 1
-#define R_USB_IRQ_MASK_SET__bulk_eot__BITNR 11
-#define R_USB_IRQ_MASK_SET__bulk_eot__WIDTH 1
-#define R_USB_IRQ_MASK_SET__bulk_eot__nop 0
-#define R_USB_IRQ_MASK_SET__bulk_eot__set 1
-#define R_USB_IRQ_MASK_SET__ctl_eot__BITNR 10
-#define R_USB_IRQ_MASK_SET__ctl_eot__WIDTH 1
-#define R_USB_IRQ_MASK_SET__ctl_eot__nop 0
-#define R_USB_IRQ_MASK_SET__ctl_eot__set 1
-#define R_USB_IRQ_MASK_SET__intr_eot__BITNR 9
-#define R_USB_IRQ_MASK_SET__intr_eot__WIDTH 1
-#define R_USB_IRQ_MASK_SET__intr_eot__nop 0
-#define R_USB_IRQ_MASK_SET__intr_eot__set 1
-#define R_USB_IRQ_MASK_SET__iso_eot__BITNR 8
+#define R_USB_IRQ_MASK_SET__intr_eof__BITNR 12
+#define R_USB_IRQ_MASK_SET__intr_eof__WIDTH 1
+#define R_USB_IRQ_MASK_SET__intr_eof__nop 0
+#define R_USB_IRQ_MASK_SET__intr_eof__set 1
+#define R_USB_IRQ_MASK_SET__iso_eot__BITNR 11
 #define R_USB_IRQ_MASK_SET__iso_eot__WIDTH 1
 #define R_USB_IRQ_MASK_SET__iso_eot__nop 0
 #define R_USB_IRQ_MASK_SET__iso_eot__set 1
+#define R_USB_IRQ_MASK_SET__intr_eot__BITNR 10
+#define R_USB_IRQ_MASK_SET__intr_eot__WIDTH 1
+#define R_USB_IRQ_MASK_SET__intr_eot__nop 0
+#define R_USB_IRQ_MASK_SET__intr_eot__set 1
+#define R_USB_IRQ_MASK_SET__ctl_eot__BITNR 9
+#define R_USB_IRQ_MASK_SET__ctl_eot__WIDTH 1
+#define R_USB_IRQ_MASK_SET__ctl_eot__nop 0
+#define R_USB_IRQ_MASK_SET__ctl_eot__set 1
+#define R_USB_IRQ_MASK_SET__bulk_eot__BITNR 8
+#define R_USB_IRQ_MASK_SET__bulk_eot__WIDTH 1
+#define R_USB_IRQ_MASK_SET__bulk_eot__nop 0
+#define R_USB_IRQ_MASK_SET__bulk_eot__set 1
+#define R_USB_IRQ_MASK_SET__epid_attn__BITNR 3
+#define R_USB_IRQ_MASK_SET__epid_attn__WIDTH 1
+#define R_USB_IRQ_MASK_SET__epid_attn__nop 0
+#define R_USB_IRQ_MASK_SET__epid_attn__set 1
 #define R_USB_IRQ_MASK_SET__sof__BITNR 2
 #define R_USB_IRQ_MASK_SET__sof__WIDTH 1
 #define R_USB_IRQ_MASK_SET__sof__nop 0
@@ -6069,30 +6177,34 @@
 #define R_USB_IRQ_MASK_SET__ctl_status__set 1
 
 #define R_USB_IRQ_MASK_READ (IO_TYPECAST_RO_UWORD 0xb0000204)
-#define R_USB_IRQ_MASK_READ__intr_eof__BITNR 13
-#define R_USB_IRQ_MASK_READ__intr_eof__WIDTH 1
-#define R_USB_IRQ_MASK_READ__intr_eof__no_pend 0
-#define R_USB_IRQ_MASK_READ__intr_eof__pend 1
-#define R_USB_IRQ_MASK_READ__iso_eof__BITNR 12
+#define R_USB_IRQ_MASK_READ__iso_eof__BITNR 13
 #define R_USB_IRQ_MASK_READ__iso_eof__WIDTH 1
 #define R_USB_IRQ_MASK_READ__iso_eof__no_pend 0
 #define R_USB_IRQ_MASK_READ__iso_eof__pend 1
-#define R_USB_IRQ_MASK_READ__bulk_eot__BITNR 11
-#define R_USB_IRQ_MASK_READ__bulk_eot__WIDTH 1
-#define R_USB_IRQ_MASK_READ__bulk_eot__no_pend 0
-#define R_USB_IRQ_MASK_READ__bulk_eot__pend 1
-#define R_USB_IRQ_MASK_READ__ctl_eot__BITNR 10
-#define R_USB_IRQ_MASK_READ__ctl_eot__WIDTH 1
-#define R_USB_IRQ_MASK_READ__ctl_eot__no_pend 0
-#define R_USB_IRQ_MASK_READ__ctl_eot__pend 1
-#define R_USB_IRQ_MASK_READ__intr_eot__BITNR 9
-#define R_USB_IRQ_MASK_READ__intr_eot__WIDTH 1
-#define R_USB_IRQ_MASK_READ__intr_eot__no_pend 0
-#define R_USB_IRQ_MASK_READ__intr_eot__pend 1
-#define R_USB_IRQ_MASK_READ__iso_eot__BITNR 8
+#define R_USB_IRQ_MASK_READ__intr_eof__BITNR 12
+#define R_USB_IRQ_MASK_READ__intr_eof__WIDTH 1
+#define R_USB_IRQ_MASK_READ__intr_eof__no_pend 0
+#define R_USB_IRQ_MASK_READ__intr_eof__pend 1
+#define R_USB_IRQ_MASK_READ__iso_eot__BITNR 11
 #define R_USB_IRQ_MASK_READ__iso_eot__WIDTH 1
 #define R_USB_IRQ_MASK_READ__iso_eot__no_pend 0
 #define R_USB_IRQ_MASK_READ__iso_eot__pend 1
+#define R_USB_IRQ_MASK_READ__intr_eot__BITNR 10
+#define R_USB_IRQ_MASK_READ__intr_eot__WIDTH 1
+#define R_USB_IRQ_MASK_READ__intr_eot__no_pend 0
+#define R_USB_IRQ_MASK_READ__intr_eot__pend 1
+#define R_USB_IRQ_MASK_READ__ctl_eot__BITNR 9
+#define R_USB_IRQ_MASK_READ__ctl_eot__WIDTH 1
+#define R_USB_IRQ_MASK_READ__ctl_eot__no_pend 0
+#define R_USB_IRQ_MASK_READ__ctl_eot__pend 1
+#define R_USB_IRQ_MASK_READ__bulk_eot__BITNR 8
+#define R_USB_IRQ_MASK_READ__bulk_eot__WIDTH 1
+#define R_USB_IRQ_MASK_READ__bulk_eot__no_pend 0
+#define R_USB_IRQ_MASK_READ__bulk_eot__pend 1
+#define R_USB_IRQ_MASK_READ__epid_attn__BITNR 3
+#define R_USB_IRQ_MASK_READ__epid_attn__WIDTH 1
+#define R_USB_IRQ_MASK_READ__epid_attn__no_pend 0
+#define R_USB_IRQ_MASK_READ__epid_attn__pend 1
 #define R_USB_IRQ_MASK_READ__sof__BITNR 2
 #define R_USB_IRQ_MASK_READ__sof__WIDTH 1
 #define R_USB_IRQ_MASK_READ__sof__no_pend 0
@@ -6107,30 +6219,34 @@
 #define R_USB_IRQ_MASK_READ__ctl_status__pend 1
 
 #define R_USB_IRQ_MASK_CLR (IO_TYPECAST_UWORD 0xb0000206)
-#define R_USB_IRQ_MASK_CLR__intr_eof__BITNR 13
-#define R_USB_IRQ_MASK_CLR__intr_eof__WIDTH 1
-#define R_USB_IRQ_MASK_CLR__intr_eof__nop 0
-#define R_USB_IRQ_MASK_CLR__intr_eof__clr 1
-#define R_USB_IRQ_MASK_CLR__iso_eof__BITNR 12
+#define R_USB_IRQ_MASK_CLR__iso_eof__BITNR 13
 #define R_USB_IRQ_MASK_CLR__iso_eof__WIDTH 1
 #define R_USB_IRQ_MASK_CLR__iso_eof__nop 0
 #define R_USB_IRQ_MASK_CLR__iso_eof__clr 1
-#define R_USB_IRQ_MASK_CLR__bulk_eot__BITNR 11
-#define R_USB_IRQ_MASK_CLR__bulk_eot__WIDTH 1
-#define R_USB_IRQ_MASK_CLR__bulk_eot__nop 0
-#define R_USB_IRQ_MASK_CLR__bulk_eot__clr 1
-#define R_USB_IRQ_MASK_CLR__ctl_eot__BITNR 10
-#define R_USB_IRQ_MASK_CLR__ctl_eot__WIDTH 1
-#define R_USB_IRQ_MASK_CLR__ctl_eot__nop 0
-#define R_USB_IRQ_MASK_CLR__ctl_eot__clr 1
-#define R_USB_IRQ_MASK_CLR__intr_eot__BITNR 9
-#define R_USB_IRQ_MASK_CLR__intr_eot__WIDTH 1
-#define R_USB_IRQ_MASK_CLR__intr_eot__nop 0
-#define R_USB_IRQ_MASK_CLR__intr_eot__clr 1
-#define R_USB_IRQ_MASK_CLR__iso_eot__BITNR 8
+#define R_USB_IRQ_MASK_CLR__intr_eof__BITNR 12
+#define R_USB_IRQ_MASK_CLR__intr_eof__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__intr_eof__nop 0
+#define R_USB_IRQ_MASK_CLR__intr_eof__clr 1
+#define R_USB_IRQ_MASK_CLR__iso_eot__BITNR 11
 #define R_USB_IRQ_MASK_CLR__iso_eot__WIDTH 1
 #define R_USB_IRQ_MASK_CLR__iso_eot__nop 0
 #define R_USB_IRQ_MASK_CLR__iso_eot__clr 1
+#define R_USB_IRQ_MASK_CLR__intr_eot__BITNR 10
+#define R_USB_IRQ_MASK_CLR__intr_eot__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__intr_eot__nop 0
+#define R_USB_IRQ_MASK_CLR__intr_eot__clr 1
+#define R_USB_IRQ_MASK_CLR__ctl_eot__BITNR 9
+#define R_USB_IRQ_MASK_CLR__ctl_eot__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__ctl_eot__nop 0
+#define R_USB_IRQ_MASK_CLR__ctl_eot__clr 1
+#define R_USB_IRQ_MASK_CLR__bulk_eot__BITNR 8
+#define R_USB_IRQ_MASK_CLR__bulk_eot__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__bulk_eot__nop 0
+#define R_USB_IRQ_MASK_CLR__bulk_eot__clr 1
+#define R_USB_IRQ_MASK_CLR__epid_attn__BITNR 3
+#define R_USB_IRQ_MASK_CLR__epid_attn__WIDTH 1
+#define R_USB_IRQ_MASK_CLR__epid_attn__nop 0
+#define R_USB_IRQ_MASK_CLR__epid_attn__clr 1
 #define R_USB_IRQ_MASK_CLR__sof__BITNR 2
 #define R_USB_IRQ_MASK_CLR__sof__WIDTH 1
 #define R_USB_IRQ_MASK_CLR__sof__nop 0
@@ -6145,30 +6261,34 @@
 #define R_USB_IRQ_MASK_CLR__ctl_status__clr 1
 
 #define R_USB_IRQ_READ (IO_TYPECAST_RO_UWORD 0xb0000206)
-#define R_USB_IRQ_READ__intr_eof__BITNR 13
-#define R_USB_IRQ_READ__intr_eof__WIDTH 1
-#define R_USB_IRQ_READ__intr_eof__no_pend 0
-#define R_USB_IRQ_READ__intr_eof__pend 1
-#define R_USB_IRQ_READ__iso_eof__BITNR 12
+#define R_USB_IRQ_READ__iso_eof__BITNR 13
 #define R_USB_IRQ_READ__iso_eof__WIDTH 1
 #define R_USB_IRQ_READ__iso_eof__no_pend 0
 #define R_USB_IRQ_READ__iso_eof__pend 1
-#define R_USB_IRQ_READ__bulk_eot__BITNR 11
-#define R_USB_IRQ_READ__bulk_eot__WIDTH 1
-#define R_USB_IRQ_READ__bulk_eot__no_pend 0
-#define R_USB_IRQ_READ__bulk_eot__pend 1
-#define R_USB_IRQ_READ__ctl_eot__BITNR 10
-#define R_USB_IRQ_READ__ctl_eot__WIDTH 1
-#define R_USB_IRQ_READ__ctl_eot__no_pend 0
-#define R_USB_IRQ_READ__ctl_eot__pend 1
-#define R_USB_IRQ_READ__intr_eot__BITNR 9
-#define R_USB_IRQ_READ__intr_eot__WIDTH 1
-#define R_USB_IRQ_READ__intr_eot__no_pend 0
-#define R_USB_IRQ_READ__intr_eot__pend 1
-#define R_USB_IRQ_READ__iso_eot__BITNR 8
+#define R_USB_IRQ_READ__intr_eof__BITNR 12
+#define R_USB_IRQ_READ__intr_eof__WIDTH 1
+#define R_USB_IRQ_READ__intr_eof__no_pend 0
+#define R_USB_IRQ_READ__intr_eof__pend 1
+#define R_USB_IRQ_READ__iso_eot__BITNR 11
 #define R_USB_IRQ_READ__iso_eot__WIDTH 1
 #define R_USB_IRQ_READ__iso_eot__no_pend 0
 #define R_USB_IRQ_READ__iso_eot__pend 1
+#define R_USB_IRQ_READ__intr_eot__BITNR 10
+#define R_USB_IRQ_READ__intr_eot__WIDTH 1
+#define R_USB_IRQ_READ__intr_eot__no_pend 0
+#define R_USB_IRQ_READ__intr_eot__pend 1
+#define R_USB_IRQ_READ__ctl_eot__BITNR 9
+#define R_USB_IRQ_READ__ctl_eot__WIDTH 1
+#define R_USB_IRQ_READ__ctl_eot__no_pend 0
+#define R_USB_IRQ_READ__ctl_eot__pend 1
+#define R_USB_IRQ_READ__bulk_eot__BITNR 8
+#define R_USB_IRQ_READ__bulk_eot__WIDTH 1
+#define R_USB_IRQ_READ__bulk_eot__no_pend 0
+#define R_USB_IRQ_READ__bulk_eot__pend 1
+#define R_USB_IRQ_READ__epid_attn__BITNR 3
+#define R_USB_IRQ_READ__epid_attn__WIDTH 1
+#define R_USB_IRQ_READ__epid_attn__no_pend 0
+#define R_USB_IRQ_READ__epid_attn__pend 1
 #define R_USB_IRQ_READ__sof__BITNR 2
 #define R_USB_IRQ_READ__sof__WIDTH 1
 #define R_USB_IRQ_READ__sof__no_pend 0
@@ -6182,7 +6302,159 @@
 #define R_USB_IRQ_READ__ctl_status__no_pend 0
 #define R_USB_IRQ_READ__ctl_status__pend 1
 
-#define R_USB_FM_NUMBER (IO_TYPECAST_RO_UDWORD 0xb000020c)
+#define R_USB_IRQ_MASK_SET_DEV (IO_TYPECAST_UWORD 0xb0000204)
+#define R_USB_IRQ_MASK_SET_DEV__out_eot__BITNR 12
+#define R_USB_IRQ_MASK_SET_DEV__out_eot__WIDTH 1
+#define R_USB_IRQ_MASK_SET_DEV__out_eot__nop 0
+#define R_USB_IRQ_MASK_SET_DEV__out_eot__set 1
+#define R_USB_IRQ_MASK_SET_DEV__ep3_in_eot__BITNR 11
+#define R_USB_IRQ_MASK_SET_DEV__ep3_in_eot__WIDTH 1
+#define R_USB_IRQ_MASK_SET_DEV__ep3_in_eot__nop 0
+#define R_USB_IRQ_MASK_SET_DEV__ep3_in_eot__set 1
+#define R_USB_IRQ_MASK_SET_DEV__ep2_in_eot__BITNR 10
+#define R_USB_IRQ_MASK_SET_DEV__ep2_in_eot__WIDTH 1
+#define R_USB_IRQ_MASK_SET_DEV__ep2_in_eot__nop 0
+#define R_USB_IRQ_MASK_SET_DEV__ep2_in_eot__set 1
+#define R_USB_IRQ_MASK_SET_DEV__ep1_in_eot__BITNR 9
+#define R_USB_IRQ_MASK_SET_DEV__ep1_in_eot__WIDTH 1
+#define R_USB_IRQ_MASK_SET_DEV__ep1_in_eot__nop 0
+#define R_USB_IRQ_MASK_SET_DEV__ep1_in_eot__set 1
+#define R_USB_IRQ_MASK_SET_DEV__ep0_in_eot__BITNR 8
+#define R_USB_IRQ_MASK_SET_DEV__ep0_in_eot__WIDTH 1
+#define R_USB_IRQ_MASK_SET_DEV__ep0_in_eot__nop 0
+#define R_USB_IRQ_MASK_SET_DEV__ep0_in_eot__set 1
+#define R_USB_IRQ_MASK_SET_DEV__epid_attn__BITNR 3
+#define R_USB_IRQ_MASK_SET_DEV__epid_attn__WIDTH 1
+#define R_USB_IRQ_MASK_SET_DEV__epid_attn__nop 0
+#define R_USB_IRQ_MASK_SET_DEV__epid_attn__set 1
+#define R_USB_IRQ_MASK_SET_DEV__sof__BITNR 2
+#define R_USB_IRQ_MASK_SET_DEV__sof__WIDTH 1
+#define R_USB_IRQ_MASK_SET_DEV__sof__nop 0
+#define R_USB_IRQ_MASK_SET_DEV__sof__set 1
+#define R_USB_IRQ_MASK_SET_DEV__port_status__BITNR 1
+#define R_USB_IRQ_MASK_SET_DEV__port_status__WIDTH 1
+#define R_USB_IRQ_MASK_SET_DEV__port_status__nop 0
+#define R_USB_IRQ_MASK_SET_DEV__port_status__set 1
+#define R_USB_IRQ_MASK_SET_DEV__ctl_status__BITNR 0
+#define R_USB_IRQ_MASK_SET_DEV__ctl_status__WIDTH 1
+#define R_USB_IRQ_MASK_SET_DEV__ctl_status__nop 0
+#define R_USB_IRQ_MASK_SET_DEV__ctl_status__set 1
+
+#define R_USB_IRQ_MASK_READ_DEV (IO_TYPECAST_RO_UWORD 0xb0000204)
+#define R_USB_IRQ_MASK_READ_DEV__out_eot__BITNR 12
+#define R_USB_IRQ_MASK_READ_DEV__out_eot__WIDTH 1
+#define R_USB_IRQ_MASK_READ_DEV__out_eot__no_pend 0
+#define R_USB_IRQ_MASK_READ_DEV__out_eot__pend 1
+#define R_USB_IRQ_MASK_READ_DEV__ep3_in_eot__BITNR 11
+#define R_USB_IRQ_MASK_READ_DEV__ep3_in_eot__WIDTH 1
+#define R_USB_IRQ_MASK_READ_DEV__ep3_in_eot__no_pend 0
+#define R_USB_IRQ_MASK_READ_DEV__ep3_in_eot__pend 1
+#define R_USB_IRQ_MASK_READ_DEV__ep2_in_eot__BITNR 10
+#define R_USB_IRQ_MASK_READ_DEV__ep2_in_eot__WIDTH 1
+#define R_USB_IRQ_MASK_READ_DEV__ep2_in_eot__no_pend 0
+#define R_USB_IRQ_MASK_READ_DEV__ep2_in_eot__pend 1
+#define R_USB_IRQ_MASK_READ_DEV__ep1_in_eot__BITNR 9
+#define R_USB_IRQ_MASK_READ_DEV__ep1_in_eot__WIDTH 1
+#define R_USB_IRQ_MASK_READ_DEV__ep1_in_eot__no_pend 0
+#define R_USB_IRQ_MASK_READ_DEV__ep1_in_eot__pend 1
+#define R_USB_IRQ_MASK_READ_DEV__ep0_in_eot__BITNR 8
+#define R_USB_IRQ_MASK_READ_DEV__ep0_in_eot__WIDTH 1
+#define R_USB_IRQ_MASK_READ_DEV__ep0_in_eot__no_pend 0
+#define R_USB_IRQ_MASK_READ_DEV__ep0_in_eot__pend 1
+#define R_USB_IRQ_MASK_READ_DEV__epid_attn__BITNR 3
+#define R_USB_IRQ_MASK_READ_DEV__epid_attn__WIDTH 1
+#define R_USB_IRQ_MASK_READ_DEV__epid_attn__no_pend 0
+#define R_USB_IRQ_MASK_READ_DEV__epid_attn__pend 1
+#define R_USB_IRQ_MASK_READ_DEV__sof__BITNR 2
+#define R_USB_IRQ_MASK_READ_DEV__sof__WIDTH 1
+#define R_USB_IRQ_MASK_READ_DEV__sof__no_pend 0
+#define R_USB_IRQ_MASK_READ_DEV__sof__pend 1
+#define R_USB_IRQ_MASK_READ_DEV__port_status__BITNR 1
+#define R_USB_IRQ_MASK_READ_DEV__port_status__WIDTH 1
+#define R_USB_IRQ_MASK_READ_DEV__port_status__no_pend 0
+#define R_USB_IRQ_MASK_READ_DEV__port_status__pend 1
+#define R_USB_IRQ_MASK_READ_DEV__ctl_status__BITNR 0
+#define R_USB_IRQ_MASK_READ_DEV__ctl_status__WIDTH 1
+#define R_USB_IRQ_MASK_READ_DEV__ctl_status__no_pend 0
+#define R_USB_IRQ_MASK_READ_DEV__ctl_status__pend 1
+
+#define R_USB_IRQ_MASK_CLR_DEV (IO_TYPECAST_UWORD 0xb0000206)
+#define R_USB_IRQ_MASK_CLR_DEV__out_eot__BITNR 12
+#define R_USB_IRQ_MASK_CLR_DEV__out_eot__WIDTH 1
+#define R_USB_IRQ_MASK_CLR_DEV__out_eot__nop 0
+#define R_USB_IRQ_MASK_CLR_DEV__out_eot__clr 1
+#define R_USB_IRQ_MASK_CLR_DEV__ep3_in_eot__BITNR 11
+#define R_USB_IRQ_MASK_CLR_DEV__ep3_in_eot__WIDTH 1
+#define R_USB_IRQ_MASK_CLR_DEV__ep3_in_eot__nop 0
+#define R_USB_IRQ_MASK_CLR_DEV__ep3_in_eot__clr 1
+#define R_USB_IRQ_MASK_CLR_DEV__ep2_in_eot__BITNR 10
+#define R_USB_IRQ_MASK_CLR_DEV__ep2_in_eot__WIDTH 1
+#define R_USB_IRQ_MASK_CLR_DEV__ep2_in_eot__nop 0
+#define R_USB_IRQ_MASK_CLR_DEV__ep2_in_eot__clr 1
+#define R_USB_IRQ_MASK_CLR_DEV__ep1_in_eot__BITNR 9
+#define R_USB_IRQ_MASK_CLR_DEV__ep1_in_eot__WIDTH 1
+#define R_USB_IRQ_MASK_CLR_DEV__ep1_in_eot__nop 0
+#define R_USB_IRQ_MASK_CLR_DEV__ep1_in_eot__clr 1
+#define R_USB_IRQ_MASK_CLR_DEV__ep0_in_eot__BITNR 8
+#define R_USB_IRQ_MASK_CLR_DEV__ep0_in_eot__WIDTH 1
+#define R_USB_IRQ_MASK_CLR_DEV__ep0_in_eot__nop 0
+#define R_USB_IRQ_MASK_CLR_DEV__ep0_in_eot__clr 1
+#define R_USB_IRQ_MASK_CLR_DEV__epid_attn__BITNR 3
+#define R_USB_IRQ_MASK_CLR_DEV__epid_attn__WIDTH 1
+#define R_USB_IRQ_MASK_CLR_DEV__epid_attn__nop 0
+#define R_USB_IRQ_MASK_CLR_DEV__epid_attn__clr 1
+#define R_USB_IRQ_MASK_CLR_DEV__sof__BITNR 2
+#define R_USB_IRQ_MASK_CLR_DEV__sof__WIDTH 1
+#define R_USB_IRQ_MASK_CLR_DEV__sof__nop 0
+#define R_USB_IRQ_MASK_CLR_DEV__sof__clr 1
+#define R_USB_IRQ_MASK_CLR_DEV__port_status__BITNR 1
+#define R_USB_IRQ_MASK_CLR_DEV__port_status__WIDTH 1
+#define R_USB_IRQ_MASK_CLR_DEV__port_status__nop 0
+#define R_USB_IRQ_MASK_CLR_DEV__port_status__clr 1
+#define R_USB_IRQ_MASK_CLR_DEV__ctl_status__BITNR 0
+#define R_USB_IRQ_MASK_CLR_DEV__ctl_status__WIDTH 1
+#define R_USB_IRQ_MASK_CLR_DEV__ctl_status__nop 0
+#define R_USB_IRQ_MASK_CLR_DEV__ctl_status__clr 1
+
+#define R_USB_IRQ_READ_DEV (IO_TYPECAST_RO_UWORD 0xb0000206)
+#define R_USB_IRQ_READ_DEV__out_eot__BITNR 12
+#define R_USB_IRQ_READ_DEV__out_eot__WIDTH 1
+#define R_USB_IRQ_READ_DEV__out_eot__no_pend 0
+#define R_USB_IRQ_READ_DEV__out_eot__pend 1
+#define R_USB_IRQ_READ_DEV__ep3_in_eot__BITNR 11
+#define R_USB_IRQ_READ_DEV__ep3_in_eot__WIDTH 1
+#define R_USB_IRQ_READ_DEV__ep3_in_eot__no_pend 0
+#define R_USB_IRQ_READ_DEV__ep3_in_eot__pend 1
+#define R_USB_IRQ_READ_DEV__ep2_in_eot__BITNR 10
+#define R_USB_IRQ_READ_DEV__ep2_in_eot__WIDTH 1
+#define R_USB_IRQ_READ_DEV__ep2_in_eot__no_pend 0
+#define R_USB_IRQ_READ_DEV__ep2_in_eot__pend 1
+#define R_USB_IRQ_READ_DEV__ep1_in_eot__BITNR 9
+#define R_USB_IRQ_READ_DEV__ep1_in_eot__WIDTH 1
+#define R_USB_IRQ_READ_DEV__ep1_in_eot__no_pend 0
+#define R_USB_IRQ_READ_DEV__ep1_in_eot__pend 1
+#define R_USB_IRQ_READ_DEV__ep0_in_eot__BITNR 8
+#define R_USB_IRQ_READ_DEV__ep0_in_eot__WIDTH 1
+#define R_USB_IRQ_READ_DEV__ep0_in_eot__no_pend 0
+#define R_USB_IRQ_READ_DEV__ep0_in_eot__pend 1
+#define R_USB_IRQ_READ_DEV__epid_attn__BITNR 3
+#define R_USB_IRQ_READ_DEV__epid_attn__WIDTH 1
+#define R_USB_IRQ_READ_DEV__epid_attn__no_pend 0
+#define R_USB_IRQ_READ_DEV__epid_attn__pend 1
+#define R_USB_IRQ_READ_DEV__sof__BITNR 2
+#define R_USB_IRQ_READ_DEV__sof__WIDTH 1
+#define R_USB_IRQ_READ_DEV__sof__no_pend 0
+#define R_USB_IRQ_READ_DEV__sof__pend 1
+#define R_USB_IRQ_READ_DEV__port_status__BITNR 1
+#define R_USB_IRQ_READ_DEV__port_status__WIDTH 1
+#define R_USB_IRQ_READ_DEV__port_status__no_pend 0
+#define R_USB_IRQ_READ_DEV__port_status__pend 1
+#define R_USB_IRQ_READ_DEV__ctl_status__BITNR 0
+#define R_USB_IRQ_READ_DEV__ctl_status__WIDTH 1
+#define R_USB_IRQ_READ_DEV__ctl_status__no_pend 0
+#define R_USB_IRQ_READ_DEV__ctl_status__pend 1
+
+#define R_USB_FM_NUMBER (IO_TYPECAST_UDWORD 0xb000020c)
 #define R_USB_FM_NUMBER__value__BITNR 0
 #define R_USB_FM_NUMBER__value__WIDTH 32
 
@@ -6200,22 +6472,26 @@
 #define R_USB_FM_PSTART__value__BITNR 0
 #define R_USB_FM_PSTART__value__WIDTH 14
 
-#define R_USB_LS_THRESHOLD (IO_TYPECAST_UWORD 0xb0000216)
-#define R_USB_LS_THRESHOLD__value__BITNR 0
-#define R_USB_LS_THRESHOLD__value__WIDTH 14
-
 #define R_USB_RH_STATUS (IO_TYPECAST_RO_BYTE 0xb0000203)
+#define R_USB_RH_STATUS__babble2__BITNR 7
+#define R_USB_RH_STATUS__babble2__WIDTH 1
+#define R_USB_RH_STATUS__babble2__no 0
+#define R_USB_RH_STATUS__babble2__yes 1
+#define R_USB_RH_STATUS__babble1__BITNR 6
+#define R_USB_RH_STATUS__babble1__WIDTH 1
+#define R_USB_RH_STATUS__babble1__no 0
+#define R_USB_RH_STATUS__babble1__yes 1
 #define R_USB_RH_STATUS__bus1__BITNR 4
 #define R_USB_RH_STATUS__bus1__WIDTH 2
 #define R_USB_RH_STATUS__bus1__SE0 0
 #define R_USB_RH_STATUS__bus1__Diff0 1
-#define R_USB_RH_STATUS__bus1__Diff1 1
+#define R_USB_RH_STATUS__bus1__Diff1 2
 #define R_USB_RH_STATUS__bus1__SE1 3
 #define R_USB_RH_STATUS__bus2__BITNR 2
 #define R_USB_RH_STATUS__bus2__WIDTH 2
 #define R_USB_RH_STATUS__bus2__SE0 0
 #define R_USB_RH_STATUS__bus2__Diff0 1
-#define R_USB_RH_STATUS__bus2__Diff1 1
+#define R_USB_RH_STATUS__bus2__Diff1 2
 #define R_USB_RH_STATUS__bus2__SE1 3
 #define R_USB_RH_STATUS__nports__BITNR 0
 #define R_USB_RH_STATUS__nports__WIDTH 2
@@ -6231,10 +6507,10 @@
 #define R_USB_RH_PORT_STATUS_1__reset__WIDTH 1
 #define R_USB_RH_PORT_STATUS_1__reset__no 0
 #define R_USB_RH_PORT_STATUS_1__reset__yes 1
-#define R_USB_RH_PORT_STATUS_1__overcurent__BITNR 3
-#define R_USB_RH_PORT_STATUS_1__overcurent__WIDTH 1
-#define R_USB_RH_PORT_STATUS_1__overcurent__no 0
-#define R_USB_RH_PORT_STATUS_1__overcurent__yes 1
+#define R_USB_RH_PORT_STATUS_1__overcurrent__BITNR 3
+#define R_USB_RH_PORT_STATUS_1__overcurrent__WIDTH 1
+#define R_USB_RH_PORT_STATUS_1__overcurrent__no 0
+#define R_USB_RH_PORT_STATUS_1__overcurrent__yes 1
 #define R_USB_RH_PORT_STATUS_1__suspended__BITNR 2
 #define R_USB_RH_PORT_STATUS_1__suspended__WIDTH 1
 #define R_USB_RH_PORT_STATUS_1__suspended__no 0
@@ -6259,10 +6535,10 @@
 #define R_USB_RH_PORT_STATUS_2__reset__WIDTH 1
 #define R_USB_RH_PORT_STATUS_2__reset__no 0
 #define R_USB_RH_PORT_STATUS_2__reset__yes 1
-#define R_USB_RH_PORT_STATUS_2__overcurent__BITNR 3
-#define R_USB_RH_PORT_STATUS_2__overcurent__WIDTH 1
-#define R_USB_RH_PORT_STATUS_2__overcurent__no 0
-#define R_USB_RH_PORT_STATUS_2__overcurent__yes 1
+#define R_USB_RH_PORT_STATUS_2__overcurrent__BITNR 3
+#define R_USB_RH_PORT_STATUS_2__overcurrent__WIDTH 1
+#define R_USB_RH_PORT_STATUS_2__overcurrent__no 0
+#define R_USB_RH_PORT_STATUS_2__overcurrent__yes 1
 #define R_USB_RH_PORT_STATUS_2__suspended__BITNR 2
 #define R_USB_RH_PORT_STATUS_2__suspended__WIDTH 1
 #define R_USB_RH_PORT_STATUS_2__suspended__no 0
@@ -6308,7 +6584,7 @@
 #define R_USB_EPT_DATA__error_code__no_error 0
 #define R_USB_EPT_DATA__error_code__stall 1
 #define R_USB_EPT_DATA__error_code__bus_error 2
-#define R_USB_EPT_DATA__error_code__TBD3 3
+#define R_USB_EPT_DATA__error_code__buffer_error 3
 #define R_USB_EPT_DATA__t_out__BITNR 21
 #define R_USB_EPT_DATA__t_out__WIDTH 1
 #define R_USB_EPT_DATA__error_count_out__BITNR 19
@@ -6357,10 +6633,10 @@
 #define R_USB_EPT_DATA_DEV__stall__WIDTH 1
 #define R_USB_EPT_DATA_DEV__stall__no 0
 #define R_USB_EPT_DATA_DEV__stall__yes 1
-#define R_USB_EPT_DATA_DEV__quiet__BITNR 28
-#define R_USB_EPT_DATA_DEV__quiet__WIDTH 1
-#define R_USB_EPT_DATA_DEV__quiet__no 0
-#define R_USB_EPT_DATA_DEV__quiet__yes 1
+#define R_USB_EPT_DATA_DEV__iso_resp__BITNR 28
+#define R_USB_EPT_DATA_DEV__iso_resp__WIDTH 1
+#define R_USB_EPT_DATA_DEV__iso_resp__quiet 0
+#define R_USB_EPT_DATA_DEV__iso_resp__yes 1
 #define R_USB_EPT_DATA_DEV__ctrl__BITNR 27
 #define R_USB_EPT_DATA_DEV__ctrl__WIDTH 1
 #define R_USB_EPT_DATA_DEV__ctrl__no 0
@@ -6371,6 +6647,8 @@
 #define R_USB_EPT_DATA_DEV__iso__yes 1
 #define R_USB_EPT_DATA_DEV__port__BITNR 24
 #define R_USB_EPT_DATA_DEV__port__WIDTH 2
+#define R_USB_EPT_DATA_DEV__control_phase__BITNR 22
+#define R_USB_EPT_DATA_DEV__control_phase__WIDTH 1
 #define R_USB_EPT_DATA_DEV__t__BITNR 21
 #define R_USB_EPT_DATA_DEV__t__WIDTH 1
 #define R_USB_EPT_DATA_DEV__max_len__BITNR 11
@@ -6384,6 +6662,22 @@
 #define R_USB_SNMP_TERROR__value__BITNR 0
 #define R_USB_SNMP_TERROR__value__WIDTH 32
 
+#define R_USB_EPID_ATTN (IO_TYPECAST_RO_UDWORD 0xb0000224)
+#define R_USB_EPID_ATTN__value__BITNR 0
+#define R_USB_EPID_ATTN__value__WIDTH 32
+
+#define R_USB_PORT1_DISABLE (IO_TYPECAST_BYTE 0xb000006a)
+#define R_USB_PORT1_DISABLE__disable__BITNR 0
+#define R_USB_PORT1_DISABLE__disable__WIDTH 1
+#define R_USB_PORT1_DISABLE__disable__yes 0
+#define R_USB_PORT1_DISABLE__disable__no 1
+
+#define R_USB_PORT2_DISABLE (IO_TYPECAST_BYTE 0xb0000052)
+#define R_USB_PORT2_DISABLE__disable__BITNR 0
+#define R_USB_PORT2_DISABLE__disable__WIDTH 1
+#define R_USB_PORT2_DISABLE__disable__yes 0
+#define R_USB_PORT2_DISABLE__disable__no 1
+
 /*
 !* MMU registers
 !*/
@@ -6615,6 +6909,10 @@
 #define R_MMU_CAUSE__we_excp__WIDTH 1
 #define R_MMU_CAUSE__we_excp__yes 1
 #define R_MMU_CAUSE__we_excp__no 0
+#define R_MMU_CAUSE__wr_rd__BITNR 8
+#define R_MMU_CAUSE__wr_rd__WIDTH 1
+#define R_MMU_CAUSE__wr_rd__write 1
+#define R_MMU_CAUSE__wr_rd__read 0
 #define R_MMU_CAUSE__page_id__BITNR 0
 #define R_MMU_CAUSE__page_id__WIDTH 6
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/sync_serial.h linux/include/asm-cris/sync_serial.h
--- v2.4.3/linux/include/asm-cris/sync_serial.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-cris/sync_serial.h	Fri Apr  6 10:51:19 2001
@@ -0,0 +1,97 @@
+/*  
+ * ioctl defines for synchrnous serial port driver
+ *
+ * Copyright (c) 2001 Axis Communications AB
+ * 
+ * Author: Mikael Starvik 
+ *
+ */
+
+#ifndef SYNC_SERIAL_H
+#define SYNC_SERIAL_H
+
+#include <linux/ioctl.h>
+
+#define SSP_SPEED      _IOR('S', 0, unsigned int)
+#define SSP_MODE       _IOR('S', 1, unsigned int)
+#define SSP_FRAME_SYNC _IOR('S', 2, unsigned int)
+#define SSP_IPOLARITY  _IOR('S', 3, unsigned int)
+#define SSP_OPOLARITY  _IOR('S', 4, unsigned int)
+#define SSP_SPI        _IOR('S', 5, unsigned int)
+
+/* Values for SSP_SPEED */
+#define SSP150        0
+#define SSP300        1
+#define SSP600        2
+#define SSP1200       3  
+#define SSP2400       4
+#define SSP4800       5
+#define SSP9600       6
+#define SSP19200      7
+#define SSP28800      8
+#define SSP57600      9
+#define SSP115200    10
+#define SSP230400    11
+#define SSP460800    12
+#define SSP921600    13
+#define SSP3125000   14
+#define CODEC        15
+
+#define FREQ_4MHz   0
+#define FREQ_2MHz   1
+#define FREQ_1MHz   2
+#define FREQ_512kHz 3
+#define FREQ_256kHz 4
+#define FREQ_128kHz 5
+#define FREQ_64kHz  6
+#define FREQ_32kHz  7
+
+/* Used by application to set CODEC divider, word rate and frame rate */
+#define CODEC_VAL(freq, word, frame) (CODEC | (freq << 8) | (word << 16) | (frame << 28))
+
+/* Used by driver to extract speed */
+#define GET_SPEED(x) (x & 0xff)
+#define GET_FREQ(x) ((x & 0xff00) >> 8)
+#define GET_WORD_RATE(x) (((x & 0x0fff0000) >> 16) - 1)
+#define GET_FRAME_RATE(x) (((x & 0xf0000000) >> 28) - 1)
+
+/* Values for SSP_MODE */
+#define MASTER_OUTPUT 0
+#define SLAVE_OUTPUT  1
+#define MASTER_INPUT  2
+#define SLAVE_INPUT   3
+#define MASTER_BIDIR  4
+#define SLAVE_BIDIR   5
+
+/* Values for SSP_FRAME_SYNC */
+#define NORMAL_SYNC                1
+#define EARLY_SYNC                 2
+#define BIT_SYNC                   4
+#define WORD_SYNC                  8
+#define EXTENDED_SYNC           0x10
+#define SYNC_OFF                0x20
+#define SYNC_ON                 0x40
+#define WORD_SIZE_8             0x80
+#define WORD_SIZE_12           0x100
+#define WORD_SIZE_16           0x200
+#define WORD_SIZE_24           0x300
+#define WORD_SIZE_32           0x800
+#define BIT_ORDER_LSB         0x1000
+#define BIT_ORDER_MSB         0x2000
+#define FLOW_CONTROL_ENABLE   0x4000
+#define FLOW_CONTROL_DISABLE  0x8000
+#define CLOCK_GATED          0x10000
+#define CLOCK_NOT_GATED      0x20000
+
+/* Values for SSP_IPOLARITY and SSP_OPOLARITY */
+#define CLOCK_NORMAL         1
+#define CLOCK_INVERT         2
+#define FRAME_NORMAL         4
+#define FRAME_INVERT         8
+#define STATUS_NORMAL      0x10
+#define STATUS_INVERT      0x20
+
+/* Values for SSP_SPI */
+#define SPI_MASTER           0
+#define SPI_SLAVE            1  
+#endif
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/termios.h linux/include/asm-cris/termios.h
--- v2.4.3/linux/include/asm-cris/termios.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/termios.h	Fri Apr  6 10:51:19 2001
@@ -51,7 +51,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_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
 #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	/* synchronous PPP */
diff -u --recursive --new-file v2.4.3/linux/include/asm-cris/unistd.h linux/include/asm-cris/unistd.h
--- v2.4.3/linux/include/asm-cris/unistd.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/unistd.h	Fri Apr  6 10:51:19 2001
@@ -233,28 +233,28 @@
 type name(void) \
 { \
   register long __a __asm__ ("r10"); \
-  __asm__ __volatile__ ("move.d %1,r1\n\tbreak 13" \
+  __asm__ __volatile__ ("movu.w %1,$r9\n\tbreak 13" \
 			: "=r" (__a) \
 			: "g" (__NR_##name) \
-			: "r10", "r1"); \
+			: "r10", "r9"); \
   if(__a >= 0) \
      return (type) __a; \
   errno = -__a; \
-  return -1; \
+  return (type) -1; \
 }
 
 #define _syscall1(type,name,type1,arg1) \
 type name(type1 arg1) \
 { \
   register long __a __asm__ ("r10") = (long) arg1; \
-  __asm__ __volatile__ ("move.d %1,r1\n\tbreak 13" \
+  __asm__ __volatile__ ("movu.w %1,$r9\n\tbreak 13" \
 			: "=r" (__a) \
 			: "g" (__NR_##name), "0" (__a) \
-			: "r10", "r1"); \
+			: "r10", "r9"); \
   if(__a >= 0) \
      return (type) __a; \
   errno = -__a; \
-  return -1; \
+  return (type) -1; \
 }
 
 #define _syscall2(type,name,type1,arg1,type2,arg2) \
@@ -262,14 +262,14 @@
 { \
   register long __a __asm__ ("r10") = (long) arg1; \
   register long __b __asm__ ("r11") = (long) arg2; \
-  __asm__ __volatile__ ("move.d %1,r1\n\tbreak 13" \
+  __asm__ __volatile__ ("movu.w %1,$r9\n\tbreak 13" \
 			: "=r" (__a) \
 			: "g" (__NR_##name), "0" (__a), "r" (__b) \
-			: "r10", "r1"); \
+			: "r10", "r9"); \
   if(__a >= 0) \
      return (type) __a; \
   errno = -__a; \
-  return -1; \
+  return (type) -1; \
 }
 
 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
@@ -278,14 +278,14 @@
   register long __a __asm__ ("r10") = (long) arg1; \
   register long __b __asm__ ("r11") = (long) arg2; \
   register long __c __asm__ ("r12") = (long) arg3; \
-  __asm__ __volatile__ ("move.d %1,r1\n\tbreak 13" \
+  __asm__ __volatile__ ("movu.w %1,$r9\n\tbreak 13" \
 			: "=r" (__a) \
 			: "g" (__NR_##name), "0" (__a), "r" (__b), "r" (__c) \
-			: "r10", "r1"); \
+			: "r10", "r9"); \
   if(__a >= 0) \
      return (type) __a; \
   errno = -__a; \
-  return -1; \
+  return (type) -1; \
 }
 
 #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
@@ -295,15 +295,15 @@
   register long __b __asm__ ("r11") = (long) arg2; \
   register long __c __asm__ ("r12") = (long) arg3; \
   register long __d __asm__ ("r13") = (long) arg4; \
-  __asm__ __volatile__ ("move.d %1,r1\n\tbreak 13" \
+  __asm__ __volatile__ ("movu.w %1,$r9\n\tbreak 13" \
 			: "=r" (__a) \
 			: "g" (__NR_##name), "0" (__a), "r" (__b), \
 			  "r" (__c), "r" (__d) \
-			: "r10", "r1"); \
+			: "r10", "r9"); \
   if(__a >= 0) \
      return (type) __a; \
   errno = -__a; \
-  return -1; \
+  return (type) -1; \
 } 
 
 #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
@@ -314,16 +314,36 @@
   register long __b __asm__ ("r11") = (long) arg2; \
   register long __c __asm__ ("r12") = (long) arg3; \
   register long __d __asm__ ("r13") = (long) arg4; \
-  register long __e __asm__ ("r0") = (long) arg5; \
-  __asm__ __volatile__ ("move.d %1,r1\n\tbreak 13" \
+  __asm__ __volatile__ ("move %6,$mof\n\t" \
+			"movu.w %1,$r9\n\tbreak 13" \
 			: "=r" (__a) \
 			: "g" (__NR_##name), "0" (__a), "r" (__b), \
-			  "r" (__c), "r" (__d), "r" (__e) \
-			: "r10", "r1"); \
+			  "r" (__c), "r" (__d), "g" (arg5) \
+			: "r10", "r9"); \
   if(__a >= 0) \
      return (type) __a; \
   errno = -__a; \
-  return -1; \
+  return (type) -1; \
+}
+
+#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 __a __asm__ ("r10") = (long) arg1; \
+  register long __b __asm__ ("r11") = (long) arg2; \
+  register long __c __asm__ ("r12") = (long) arg3; \
+  register long __d __asm__ ("r13") = (long) arg4; \
+  __asm__ __volatile__ ("move %6,$mof\n\tmove %7,$srp\n\t" \
+			"movu.w %1,$r9\n\tbreak 13" \
+			: "=r" (__a) \
+			: "g" (__NR_##name), "0" (__a), "r" (__b), \
+			  "r" (__c), "r" (__d), "g" (arg5), "g" (arg6)\
+			: "r10", "r9", "srp"); \
+  if(__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return (type) -1; \
 }
 
 #ifdef __KERNEL_SYSCALLS__
diff -u --recursive --new-file v2.4.3/linux/include/asm-i386/atomic.h linux/include/asm-i386/atomic.h
--- v2.4.3/linux/include/asm-i386/atomic.h	Mon Mar 26 15:48:10 2001
+++ linux/include/asm-i386/atomic.h	Fri Apr  6 16:05:27 2001
@@ -75,7 +75,7 @@
 }
 
 /**
- * atomic_sub_and_test - test variable then subtract 
+ * atomic_sub_and_test - subtract value from variable and test result
  * @i: integer value to subtract
  * @v: pointer of type atomic_t
  * 
@@ -111,7 +111,7 @@
 }
 
 /**
- * atomic_dec - decrement the atomic variable
+ * atomic_dec - decrement atomic variable
  * @v: pointer of type atomic_t
  * 
  * Atomically decrements @v by 1.  Note that the guaranteed
@@ -126,7 +126,7 @@
 }
 
 /**
- * atomic_dec_and_test - decrement by 1 and test
+ * atomic_dec_and_test - decrement and test
  * @v: pointer of type atomic_t
  * 
  * Atomically decrements @v by 1 and
@@ -146,7 +146,7 @@
 }
 
 /**
- * atomic_inc_and_test - increment by 1 and test 
+ * atomic_inc_and_test - increment and test 
  * @v: pointer of type atomic_t
  * 
  * Atomically increments @v by 1
diff -u --recursive --new-file v2.4.3/linux/include/asm-i386/bitops.h linux/include/asm-i386/bitops.h
--- v2.4.3/linux/include/asm-i386/bitops.h	Mon Mar 26 15:48:10 2001
+++ linux/include/asm-i386/bitops.h	Fri Apr  6 16:05:27 2001
@@ -23,6 +23,16 @@
 
 #define ADDR (*(volatile long *) addr)
 
+/**
+ * set_bit - Atomically set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This function is atomic and may not be reordered.  See __set_bit()
+ * if you do not require the atomic guarantees.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
 static __inline__ void set_bit(int nr, volatile void * addr)
 {
 	__asm__ __volatile__( LOCK_PREFIX
@@ -31,7 +41,15 @@
 		:"Ir" (nr));
 }
 
-/* WARNING: non atomic and it can be reordered! */
+/**
+ * __set_bit - Set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * Unlike set_bit(), this function is non-atomic and may be reordered.
+ * If it's called on the same region of memory simultaneously, the effect
+ * may be that only one operation succeeds.
+ */
 static __inline__ void __set_bit(int nr, volatile void * addr)
 {
 	__asm__(
@@ -40,11 +58,16 @@
 		:"Ir" (nr));
 }
 
-/*
- * clear_bit() doesn't provide any barrier for the compiler.
+/**
+ * clear_bit - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit() is atomic and may not be reordered.  However, it does
+ * not contain a memory barrier, so if it is used for locking purposes,
+ * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
+ * in order to ensure changes are visible on other processors.
  */
-#define smp_mb__before_clear_bit()	barrier()
-#define smp_mb__after_clear_bit()	barrier()
 static __inline__ void clear_bit(int nr, volatile void * addr)
 {
 	__asm__ __volatile__( LOCK_PREFIX
@@ -52,7 +75,18 @@
 		:"=m" (ADDR)
 		:"Ir" (nr));
 }
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
 
+/**
+ * change_bit - Toggle a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * change_bit() is atomic and may not be reordered.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
 static __inline__ void change_bit(int nr, volatile void * addr)
 {
 	__asm__ __volatile__( LOCK_PREFIX
@@ -61,10 +95,13 @@
 		:"Ir" (nr));
 }
 
-/*
- * It will also imply a memory barrier, thus it must clobber memory
- * to make sure to reload anything that was cached into registers
- * outside _this_ critical section.
+/**
+ * test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.  
+ * It also implies a memory barrier.
  */
 static __inline__ int test_and_set_bit(int nr, volatile void * addr)
 {
@@ -77,7 +114,15 @@
 	return oldbit;
 }
 
-/* WARNING: non atomic and it can be reordered! */
+/**
+ * __test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.  
+ * If two examples of this operation race, one can appear to succeed
+ * but actually fail.  You must protect multiple accesses with a lock.
+ */
 static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
 {
 	int oldbit;
@@ -89,6 +134,14 @@
 	return oldbit;
 }
 
+/**
+ * test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.  
+ * It also implies a memory barrier.
+ */
 static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
 {
 	int oldbit;
@@ -100,7 +153,15 @@
 	return oldbit;
 }
 
-/* WARNING: non atomic and it can be reordered! */
+/**
+ * __test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is non-atomic and can be reordered.  
+ * If two examples of this operation race, one can appear to succeed
+ * but actually fail.  You must protect multiple accesses with a lock.
+ */
 static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
 {
 	int oldbit;
@@ -112,6 +173,14 @@
 	return oldbit;
 }
 
+/**
+ * test_and_change_bit - Change a bit and return its new value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.  
+ * It also implies a memory barrier.
+ */
 static __inline__ int test_and_change_bit(int nr, volatile void * addr)
 {
 	int oldbit;
@@ -123,9 +192,15 @@
 	return oldbit;
 }
 
-/*
- * This routine doesn't need to be atomic.
+#if 0 /* Fool kernel-doc since it doesn't do macros yet */
+/**
+ * test_bit - Determine whether a bit is set
+ * @nr: bit number to test
+ * @addr: Address to start counting from
  */
+static int test_bit(int nr, const volatile void * addr);
+#endif
+
 static __inline__ int constant_test_bit(int nr, const volatile void * addr)
 {
 	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
@@ -147,8 +222,13 @@
  constant_test_bit((nr),(addr)) : \
  variable_test_bit((nr),(addr)))
 
-/*
- * Find-bit routines..
+/**
+ * find_first_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit-number of the first zero bit, not the number of the byte
+ * containing a bit.
  */
 static __inline__ int find_first_zero_bit(void * addr, unsigned size)
 {
@@ -174,6 +254,12 @@
 	return res;
 }
 
+/**
+ * find_next_zero_bit - find the first zero bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
 static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
 {
 	unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
@@ -201,9 +287,11 @@
 	return (offset + set + res);
 }
 
-/*
- * ffz = Find First Zero in word. Undefined if no zero exists,
- * so code should check against ~0UL first..
+/**
+ * ffz - find first zero in word.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
  */
 static __inline__ unsigned long ffz(unsigned long word)
 {
@@ -215,12 +303,14 @@
 
 #ifdef __KERNEL__
 
-/*
- * ffs: find first bit set. This is defined the same way as
+/**
+ * ffs - find first bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as
  * the libc and compiler builtin ffs routines, therefore
  * differs in spirit from the above ffz (man ffs).
  */
-
 static __inline__ int ffs(int x)
 {
 	int r;
@@ -232,9 +322,11 @@
 	return r+1;
 }
 
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
+/**
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
  */
 
 #define hweight32(x) generic_hweight32(x)
diff -u --recursive --new-file v2.4.3/linux/include/asm-i386/io.h linux/include/asm-i386/io.h
--- v2.4.3/linux/include/asm-i386/io.h	Mon Mar 26 15:48:21 2001
+++ linux/include/asm-i386/io.h	Fri Apr  6 16:05:48 2001
@@ -111,7 +111,7 @@
  * Temporary debugging check to catch old code using
  * unmapped ISA addresses. Will be removed in 2.4.
  */
-#if 1
+#if 0
   extern void *__io_virt_debug(unsigned long x, const char *file, int line);
   extern unsigned long __io_phys_debug(unsigned long x, const char *file, int line);
   #define __io_virt(x) __io_virt_debug((unsigned long)(x), __FILE__, __LINE__)
diff -u --recursive --new-file v2.4.3/linux/include/asm-i386/string.h linux/include/asm-i386/string.h
--- v2.4.3/linux/include/asm-i386/string.h	Mon Mar 26 15:48:10 2001
+++ linux/include/asm-i386/string.h	Fri Apr  6 16:05:28 2001
@@ -446,34 +446,8 @@
 /* end of additional stuff */
 
 #define __HAVE_ARCH_STRSTR
-static inline char * strstr(const char * cs,const char * ct)
-{
-int	d0, d1;
-register char * __res;
-__asm__ __volatile__(
-	"movl %6,%%edi\n\t"
-	"repne\n\t"
-	"scasb\n\t"
-	"notl %%ecx\n\t"
-	"decl %%ecx\n\t"	/* NOTE! This also sets Z if searchstring='' */
-	"movl %%ecx,%%edx\n"
-	"1:\tmovl %6,%%edi\n\t"
-	"movl %%esi,%%eax\n\t"
-	"movl %%edx,%%ecx\n\t"
-	"repe\n\t"
-	"cmpsb\n\t"
-	"je 2f\n\t"		/* also works for empty string, see above */
-	"xchgl %%eax,%%esi\n\t"
-	"incl %%esi\n\t"
-	"cmpb $0,-1(%%eax)\n\t"
-	"jne 1b\n\t"
-	"xorl %%eax,%%eax\n\t"
-	"2:"
-	:"=a" (__res), "=&c" (d0), "=&S" (d1)
-	:"0" (0), "1" (0xffffffff), "2" (cs), "g" (ct)
-	:"dx", "di");
-return __res;
-}
+
+extern char *strstr(const char *cs, const char *ct);
 
 /*
  * This looks horribly ugly, but the compiler can optimize it totally,
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/a.out.h linux/include/asm-ia64/a.out.h
--- v2.4.3/linux/include/asm-ia64/a.out.h	Thu Jan  4 12:50:17 2001
+++ linux/include/asm-ia64/a.out.h	Thu Apr  5 12:51:47 2001
@@ -30,7 +30,8 @@
 #define N_TXTOFF(x)	0
 
 #ifdef __KERNEL__
-# define STACK_TOP	(0x8000000000000000UL + (1UL << (4*PAGE_SHIFT - 12)))
+# include <asm/page.h>
+# define STACK_TOP	(0x8000000000000000UL + (1UL << (4*PAGE_SHIFT - 12)) - PAGE_SIZE)
 # define IA64_RBS_BOT	(STACK_TOP - 0x80000000L)	/* bottom of register backing store */
 #endif
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/acpikcfg.h linux/include/asm-ia64/acpikcfg.h
--- v2.4.3/linux/include/asm-ia64/acpikcfg.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/acpikcfg.h	Thu Apr  5 12:51:47 2001
@@ -1,4 +1,5 @@
 #include <linux/config.h>
+
 #ifdef	CONFIG_ACPI_KERNEL_CONFIG
 /*
  *  acpikcfg.h - ACPI based Kernel Configuration Manager External Interfaces
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/asmmacro.h linux/include/asm-ia64/asmmacro.h
--- v2.4.3/linux/include/asm-ia64/asmmacro.h	Fri Aug 11 19:09:06 2000
+++ linux/include/asm-ia64/asmmacro.h	Thu Apr  5 12:51:47 2001
@@ -2,26 +2,10 @@
 #define _ASM_IA64_ASMMACRO_H
 
 /*
- * Copyright (C) 2000 Hewlett-Packard Co
- * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 2000-2001 Hewlett-Packard Co
+ * Copyright (C) 2000-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
-#if 1
-
-/*
- * This is a hack that's necessary as long as we support old versions
- * of gas, that have no unwind support.
- */
-#include <linux/config.h>
-
-#ifdef CONFIG_IA64_NEW_UNWIND
-# define UNW(args...)	args
-#else
-# define UNW(args...)
-#endif
-
-#endif
-
 #define ENTRY(name)				\
 	.align 32;				\
 	.proc name;				\
@@ -44,5 +28,28 @@
 #define ASM_UNW_PRLG_PSP		0x2
 #define ASM_UNW_PRLG_PR			0x1
 #define ASM_UNW_PRLG_GRSAVE(ninputs)	(32+(ninputs))
+
+/*
+ * Helper macros for accessing user memory.
+ */
+
+	.section "__ex_table", "a"		// declare section & section attributes
+	.previous
+
+#if __GNUC__ >= 3
+# define EX(y,x...)					\
+	.xdata4 "__ex_table", @gprel(99f), @gprel(y);	\
+  [99:]	x
+# define EXCLR(y,x...)					\
+	.xdata4 "__ex_table", @gprel(99f), @gprel(y)+4;	\
+  [99:]	x
+#else
+# define EX(y,x...)					\
+	.xdata4 "__ex_table", @gprel(99f), @gprel(y);	\
+  99:	x
+# define EXCLR(y,x...)					\
+	.xdata4 "__ex_table", @gprel(99f), @gprel(y)+4;	\
+  99:	x
+#endif
 
 #endif /* _ASM_IA64_ASMMACRO_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/bitops.h linux/include/asm-ia64/bitops.h
--- v2.4.3/linux/include/asm-ia64/bitops.h	Mon Oct  9 17:54:57 2000
+++ linux/include/asm-ia64/bitops.h	Thu Apr  5 12:51:47 2001
@@ -158,6 +158,7 @@
 	__asm__ ("getf.exp %0=%1" : "=r"(exp) : "f"(d));
 	return exp - 0xffff;
 }
+
 /*
  * ffs: find first bit set. This is defined the same way as
  * the libc and compiler builtin ffs routines, therefore
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/byteorder.h linux/include/asm-ia64/byteorder.h
--- v2.4.3/linux/include/asm-ia64/byteorder.h	Sun Feb  6 18:42:40 2000
+++ linux/include/asm-ia64/byteorder.h	Thu Apr  5 12:51:47 2001
@@ -20,18 +20,18 @@
 static __inline__ __const__ __u32
 __ia64_swab32 (__u32 x)
 {
-	return __ia64_swab64 (x) >> 32;
+	return __ia64_swab64(x) >> 32;
 }
 
 static __inline__ __const__ __u16
 __ia64_swab16(__u16 x)
 {
-	return __ia64_swab64 (x) >> 48;
+	return __ia64_swab64(x) >> 48;
 }
 
-#define __arch__swab64(x) __ia64_swab64 (x)
-#define __arch__swab32(x) __ia64_swab32 (x)
-#define __arch__swab16(x) __ia64_swab16 (x)
+#define __arch__swab64(x) __ia64_swab64(x)
+#define __arch__swab32(x) __ia64_swab32(x)
+#define __arch__swab16(x) __ia64_swab16(x)
 
 #define __BYTEORDER_HAS_U64__
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/cache.h linux/include/asm-ia64/cache.h
--- v2.4.3/linux/include/asm-ia64/cache.h	Thu Jan  4 12:50:17 2001
+++ linux/include/asm-ia64/cache.h	Thu Apr  5 12:51:47 2001
@@ -9,7 +9,7 @@
  */
 
 /* Bytes per L1 (data) cache line.  */
-#define L1_CACHE_SHIFT		6
+#define L1_CACHE_SHIFT		CONFIG_IA64_L1_CACHE_SHIFT
 #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
 #ifdef CONFIG_SMP
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/delay.h linux/include/asm-ia64/delay.h
--- v2.4.3/linux/include/asm-ia64/delay.h	Thu Jan  4 12:50:17 2001
+++ linux/include/asm-ia64/delay.h	Thu Apr  5 12:51:47 2001
@@ -34,13 +34,9 @@
 }
 
 static __inline__ void
-ia64_set_itv (unsigned char vector, unsigned char masked)
+ia64_set_itv (unsigned long val)
 {
-	if (masked > 1)
-		masked = 1;
-
-	__asm__ __volatile__("mov cr.itv=%0;; srlz.d;;"
-			     :: "r"((masked << 16) | vector) : "memory");
+	__asm__ __volatile__("mov cr.itv=%0;; srlz.d;;" :: "r"(val) : "memory");
 }
 
 static __inline__ void
@@ -79,16 +75,11 @@
 static __inline__ void
 udelay (unsigned long usecs)
 {
-#ifdef CONFIG_IA64_SOFTSDV_HACKS
-	while (usecs--)
-		;
-#else
 	unsigned long start = ia64_get_itc();
-	unsigned long cycles = usecs*my_cpu_data.cyc_per_usec;
+	unsigned long cycles = usecs*local_cpu_data->cyc_per_usec;
 
 	while (ia64_get_itc() - start < cycles)
 		/* skip */;
-#endif	/* CONFIG_IA64_SOFTSDV_HACKS */
 }
 
 #endif /* _ASM_IA64_DELAY_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/dma.h linux/include/asm-ia64/dma.h
--- v2.4.3/linux/include/asm-ia64/dma.h	Thu Jun 22 07:09:45 2000
+++ linux/include/asm-ia64/dma.h	Thu Apr  5 12:51:47 2001
@@ -2,35 +2,20 @@
 #define _ASM_IA64_DMA_H
 
 /*
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <linux/config.h>
-#include <linux/spinlock.h>	/* And spinlocks */
-#include <linux/delay.h>
 
 #include <asm/io.h>		/* need byte IO */
 
-#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
-#define dma_outb	outb_p
-#else
-#define dma_outb	outb
-#endif
-
-#define dma_inb		inb
-
-#define MAX_DMA_CHANNELS	8
-#define MAX_DMA_ADDRESS		0xffffffffUL
-
-extern spinlock_t  dma_spin_lock;
-
-/* From PCI */
+extern unsigned long MAX_DMA_ADDRESS;
 
 #ifdef CONFIG_PCI
-extern int isa_dma_bridge_buggy;
+  extern int isa_dma_bridge_buggy;
 #else
-#define isa_dma_bridge_buggy 	(0)
+# define isa_dma_bridge_buggy 	(0)
 #endif
 
 #endif /* _ASM_IA64_DMA_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/efi.h linux/include/asm-ia64/efi.h
--- v2.4.3/linux/include/asm-ia64/efi.h	Thu Jan  4 12:50:17 2001
+++ linux/include/asm-ia64/efi.h	Thu Apr  5 12:51:47 2001
@@ -4,7 +4,7 @@
 /*
  * Extensible Firmware Interface
  * Based on 'Extensible Firmware Interface Specification' version 0.9, April 30, 1999
- * 
+ *
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  * Copyright (C) 1999 Hewlett-Packard Co.
@@ -20,9 +20,12 @@
 #include <asm/system.h>
 
 #define EFI_SUCCESS		0
-#define EFI_INVALID_PARAMETER	2
-#define EFI_UNSUPPORTED		3
-#define EFI_BUFFER_TOO_SMALL	4
+#define EFI_LOAD_ERROR          (1L | (1L << 63))
+#define EFI_INVALID_PARAMETER	(2L | (1L << 63))
+#define EFI_UNSUPPORTED		(3L | (1L << 63))
+#define EFI_BAD_BUFFER_SIZE     (4L | (1L << 63))
+#define EFI_BUFFER_TOO_SMALL	(5L | (1L << 63))
+#define EFI_NOT_FOUND          (14L | (1L << 63))
 
 typedef unsigned long efi_status_t;
 typedef u8 efi_bool_t;
@@ -173,7 +176,7 @@
 
 #define SMBIOS_TABLE_GUID    \
     ((efi_guid_t) { 0xeb9d2d31, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }})
-	
+
 #define SAL_SYSTEM_TABLE_GUID    \
     ((efi_guid_t) { 0xeb9d2d32, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }})
 
@@ -183,7 +186,7 @@
 } efi_config_table_t;
 
 #define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249
-#define EFI_SYSTEM_TABLE_REVISION  ((0 << 16) | (92))
+#define EFI_SYSTEM_TABLE_REVISION  ((1 << 16) | 00)
 
 typedef struct {
 	efi_table_hdr_t hdr;
@@ -234,5 +237,13 @@
 extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
 extern void efi_gettimeofday (struct timeval *tv);
 extern void efi_enter_virtual_mode (void);	/* switch EFI to virtual mode, if possible */
+
+
+/*
+ * Variable Attributes
+ */
+#define EFI_VARIABLE_NON_VOLATILE       0x0000000000000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
+#define EFI_VARIABLE_RUNTIME_ACCESS     0x0000000000000004
 
 #endif /* _ASM_IA64_EFI_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/errno.h linux/include/asm-ia64/errno.h
--- v2.4.3/linux/include/asm-ia64/errno.h	Sun Feb  6 18:42:40 2000
+++ linux/include/asm-ia64/errno.h	Thu Apr  5 12:51:47 2001
@@ -135,5 +135,5 @@
 
 #define	ENOMEDIUM	123	/* No medium found */
 #define	EMEDIUMTYPE	124	/* Wrong medium type */
-
+#define	EHASHCOLLISION	125	/* Number of hash collisons exceeds max. generation value */
 #endif /* _ASM_IA64_ERRNO_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/hardirq.h linux/include/asm-ia64/hardirq.h
--- v2.4.3/linux/include/asm-ia64/hardirq.h	Sun Dec  3 17:45:23 2000
+++ linux/include/asm-ia64/hardirq.h	Thu Apr  5 12:51:47 2001
@@ -2,8 +2,8 @@
 #define _ASM_IA64_HARDIRQ_H
 
 /*
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <linux/config.h>
@@ -11,36 +11,38 @@
 #include <linux/threads.h>
 #include <linux/irq.h>
 
-/* entry.S is sensitive to the offsets of these fields */
-typedef struct {
-	unsigned int __softirq_active;
-	unsigned int __softirq_mask;
-	unsigned int __local_irq_count;
-	unsigned int __local_bh_count;
-	unsigned int __syscall_count;
-	unsigned int __nmi_count;	/* arch dependent */
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+#include <asm/processor.h>
 
 /*
- * Are we in an interrupt context? Either doing bottom half
- * or hardware interrupt processing?
+ * No irq_cpustat_t for IA-64.  The data is held in the per-CPU data structure.
  */
-#define in_interrupt()						\
-({								\
-	int __cpu = smp_processor_id();				\
-	(local_irq_count(__cpu) + local_bh_count(__cpu)) != 0;	\
-})
+#define softirq_active(cpu)		(cpu_data[cpu].softirq.active)
+#define softirq_mask(cpu)		(cpu_data[cpu].softirq.mask)
+#define irq_count(cpu)			(cpu_data[cpu].irq_stat.f.irq_count)
+#define bh_count(cpu)			(cpu_data[cpu].irq_stat.f.bh_count)
+#define syscall_count(cpu)		/* unused on IA-64 */
+#define nmi_count(cpu)			0
+
+#define local_softirq_active()		(local_cpu_data->softirq.active)
+#define local_softirq_mask()		(local_cpu_data->softirq.mask)
+#define local_irq_count()		(local_cpu_data->irq_stat.f.irq_count)
+#define local_bh_count()		(local_cpu_data->irq_stat.f.bh_count)
+#define local_syscall_count()		/* unused on IA-64 */
+#define local_nmi_count()		0
 
-#define in_irq() (local_irq_count(smp_processor_id()) != 0)
+/*
+ * Are we in an interrupt context? Either doing bottom half or hardware interrupt
+ * processing?
+ */
+#define in_interrupt()			(local_cpu_data->irq_stat.irq_and_bh_counts != 0)
+#define in_irq()			(local_cpu_data->irq_stat.f.irq_count != 0)
 
 #ifndef CONFIG_SMP
-# define hardirq_trylock(cpu)		(local_irq_count(cpu) == 0)
-# define hardirq_endlock(cpu)		do { } while (0)
+# define local_hardirq_trylock()	(local_irq_count() == 0)
+# define local_hardirq_endlock()	do { } while (0)
 
-# define irq_enter(cpu, irq)		(local_irq_count(cpu)++)
-# define irq_exit(cpu, irq)		(local_irq_count(cpu)--)
+# define local_irq_enter(irq)		(local_irq_count()++)
+# define local_irq_exit(irq)		(local_irq_count()--)
 
 # define synchronize_irq()		barrier()
 #else
@@ -51,17 +53,19 @@
 extern unsigned int global_irq_holder;
 extern volatile unsigned long global_irq_lock;
 
-static inline int irqs_running (void)
+static inline int
+irqs_running (void)
 {
 	int i;
 
 	for (i = 0; i < smp_num_cpus; i++)
-		if (local_irq_count(i))
+		if (irq_count(i))
 			return 1;
 	return 0;
 }
 
-static inline void release_irqlock(int cpu)
+static inline void
+release_irqlock (int cpu)
 {
 	/* if we didn't own the irq lock, just ignore.. */
 	if (global_irq_holder == cpu) {
@@ -70,28 +74,31 @@
         }
 }
 
-static inline void irq_enter(int cpu, int irq)
+static inline void
+local_irq_enter (int irq)
 {
-	local_irq_count(cpu)++;
+	local_irq_count()++;
 
 	while (test_bit(0,&global_irq_lock)) {
 		/* nothing */;
 	}
 }
 
-static inline void irq_exit(int cpu, int irq)
+static inline void
+local_irq_exit (int irq)
 {
-	local_irq_count(cpu)--;
+	local_irq_count()--;
 }
 
-static inline int hardirq_trylock(int cpu)
+static inline int
+local_hardirq_trylock (void)
 {
-	return !local_irq_count(cpu) && !test_bit(0,&global_irq_lock);
+	return !local_irq_count() && !test_bit(0,&global_irq_lock);
 }
 
-#define hardirq_endlock(cpu)	do { } while (0)
+#define local_hardirq_endlock()		do { } while (0)
 
-extern void synchronize_irq(void);
+extern void synchronize_irq (void);
 
 #endif /* CONFIG_SMP */
 #endif /* _ASM_IA64_HARDIRQ_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/hw_irq.h linux/include/asm-ia64/hw_irq.h
--- v2.4.3/linux/include/asm-ia64/hw_irq.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/hw_irq.h	Thu Apr  5 12:51:47 2001
@@ -2,8 +2,8 @@
 #define _ASM_IA64_HW_IRQ_H
 
 /*
- * Copyright (C) 2000 Hewlett-Packard Co
- * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 2001 Hewlett-Packard Co
+ * Copyright (C) 2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <linux/sched.h>
@@ -13,6 +13,8 @@
 #include <asm/ptrace.h>
 #include <asm/smp.h>
 
+typedef u8 ia64_vector;
+
 /*
  * 0 special
  *
@@ -26,31 +28,32 @@
  *
  * 15 classes of 16 interrupts each.
  */
-#define IA64_MIN_VECTORED_IRQ	 16
-#define IA64_MAX_VECTORED_IRQ	255
+#define IA64_MIN_VECTORED_IRQ		 16
+#define IA64_MAX_VECTORED_IRQ		255
+#define IA64_NUM_VECTORS		256
 
-#define IA64_SPURIOUS_INT	0x0f
+#define IA64_SPURIOUS_INT_VECTOR	0x0f
 
 /*
  * Vectors 0x10-0x1f are used for low priority interrupts, e.g. CMCI.
  */
-#define PCE_IRQ			0x1e	/* platform corrected error interrupt vector */
-#define CMC_IRQ			0x1f	/* correctable machine-check interrupt vector */
+#define IA64_PCE_VECTOR			0x1e	/* platform corrected error interrupt vector */
+#define IA64_CMC_VECTOR			0x1f	/* correctable machine-check interrupt vector */
 /*
  * Vectors 0x20-0x2f are reserved for legacy ISA IRQs.
  */
-#define FIRST_DEVICE_IRQ	0x30
-#define LAST_DEVICE_IRQ		0xe7
+#define IA64_FIRST_DEVICE_VECTOR	0x30
+#define IA64_LAST_DEVICE_VECTOR		0xe7
 
-#define MCA_RENDEZ_IRQ		0xe8	/* MCA rendez interrupt */
-#define PERFMON_IRQ		0xee	/* performanc monitor interrupt vector */
-#define TIMER_IRQ		0xef	/* use highest-prio group 15 interrupt for timer */
-#define	MCA_WAKEUP_IRQ		0xf0	/* MCA wakeup interrupt (must be higher than MCA_RENDEZ_IRQ) */
-#define IPI_IRQ			0xfe	/* inter-processor interrupt vector */
+#define IA64_MCA_RENDEZ_VECTOR		0xe8	/* MCA rendez interrupt */
+#define IA64_PERFMON_VECTOR		0xee	/* performanc monitor interrupt vector */
+#define IA64_TIMER_VECTOR		0xef	/* use highest-prio group 15 interrupt for timer */
+#define	IA64_MCA_WAKEUP_VECTOR		0xf0	/* MCA wakeup (must be >MCA_RENDEZ_VECTOR) */
+#define IA64_IPI_VECTOR			0xfe	/* inter-processor interrupt vector */
 
 /* IA64 inter-cpu interrupt related definitions */
 
-#define IPI_DEFAULT_BASE_ADDR	0xfee00000
+#define IA64_IPI_DEFAULT_BASE_ADDR	0xfee00000
 
 /* Delivery modes for inter-cpu interrupts */
 enum {
@@ -61,9 +64,6 @@
         IA64_IPI_DM_EXTINT =    0x7,    /* pend an 8259-compatible interrupt. */
 };
 
-#define IA64_BUS_ID(cpu)        (cpu >> 8)
-#define IA64_LOCAL_ID(cpu)      (cpu & 0xff)
-
 extern __u8 isa_irq_to_vector_map[16];
 #define isa_irq_to_vector(x)	isa_irq_to_vector_map[(x)]
 
@@ -73,11 +73,71 @@
 
 extern int ia64_alloc_irq (void);	/* allocate a free irq */
 extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
+extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
 
 static inline void
 hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector)
 {
 	platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
+}
+
+/*
+ * Default implementations for the irq-descriptor API:
+ */
+
+extern struct irq_desc _irq_desc[NR_IRQS];
+
+static inline struct irq_desc *
+__ia64_irq_desc (unsigned int irq)
+{
+	return _irq_desc + irq;
+}
+
+static inline ia64_vector
+__ia64_irq_to_vector (unsigned int irq)
+{
+	return (ia64_vector) irq;
+}
+
+static inline unsigned int
+__ia64_local_vector_to_irq (ia64_vector vec)
+{
+	return (unsigned int) vec;
+}
+
+/*
+ * Next follows the irq descriptor interface.  On IA-64, each CPU supports 256 interrupt
+ * vectors.  On smaller systems, there is a one-to-one correspondence between interrupt
+ * vectors and the Linux irq numbers.  However, larger systems may have multiple interrupt
+ * domains meaning that the translation from vector number to irq number depends on the
+ * interrupt domain that a CPU belongs to.  This API abstracts such platform-dependent
+ * differences and provides a uniform means to translate between vector and irq numbers
+ * and to obtain the irq descriptor for a given irq number.
+ */
+
+/* Return a pointer to the irq descriptor for IRQ.  */
+static inline struct irq_desc *
+irq_desc (int irq)
+{
+	return platform_irq_desc(irq);
+}
+
+/* Extract the IA-64 vector that corresponds to IRQ.  */
+static inline ia64_vector
+irq_to_vector (int irq)
+{
+	return platform_irq_to_vector(irq);
+}
+
+/*
+ * Convert the local IA-64 vector to the corresponding irq number.  This translation is
+ * done in the context of the interrupt domain that the currently executing CPU belongs
+ * to.
+ */
+static inline unsigned int
+local_vector_to_irq (ia64_vector vec)
+{
+	return platform_local_vector_to_irq(vec);
 }
 
 #endif /* _ASM_IA64_HW_IRQ_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/ia32.h linux/include/asm-ia64/ia32.h
--- v2.4.3/linux/include/asm-ia64/ia32.h	Thu Jan  4 12:50:17 2001
+++ linux/include/asm-ia64/ia32.h	Thu Apr  5 12:51:47 2001
@@ -378,9 +378,10 @@
 	ia64_psr(regs)->ri = 0;		/* clear return slot number */		\
 	ia64_psr(regs)->is = 1;		/* IA-32 instruction set */		\
 	regs->cr_iip = new_ip;							\
-	regs->r12 = new_sp;							\
+	regs->ar_rsc = 0xc;		/* enforced lazy mode, priv. level 3 */	\
 	regs->ar_rnat = 0;							\
 	regs->loadrs = 0;							\
+	regs->r12 = new_sp;							\
 } while (0)
 
 extern void ia32_gdt_init (void);
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/io.h linux/include/asm-ia64/io.h
--- v2.4.3/linux/include/asm-ia64/io.h	Thu Jan  4 12:50:17 2001
+++ linux/include/asm-ia64/io.h	Thu Apr  5 12:51:47 2001
@@ -13,8 +13,8 @@
  * over and over again with slight variations and possibly making a
  * mistake somewhere.
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
  */
@@ -82,21 +82,11 @@
 }
 
 /*
- * For the in/out instructions, we need to do:
- *
- *	o "mf" _before_ doing the I/O access to ensure that all prior
- *	  accesses to memory occur before the I/O access
- *	o "mf.a" _after_ doing the I/O access to ensure that the access
- *	  has completed before we're doing any other I/O accesses
- *
- * The former is necessary because we might be doing normal (cached) memory
- * accesses, e.g., to set up a DMA descriptor table and then do an "outX()"
- * to tell the DMA controller to start the DMA operation.  The "mf" ahead
- * of the I/O operation ensures that the DMA table is correct when the I/O
- * access occurs.
- *
- * The mf.a is necessary to ensure that all I/O access occur in program
- * order. --davidm 99/12/07 
+ * For the in/out routines, we need to do "mf.a" _after_ doing the I/O access to ensure
+ * that the access has completed before executing other I/O accesses.  Since we're doing
+ * the accesses through an uncachable (UC) translation, the CPU will execute them in
+ * program order.  However, we still need to tell the compiler not to shuffle them around
+ * during optimization, which is why we use "volatile" pointers.
  */
 
 static inline unsigned int
@@ -378,17 +368,16 @@
 #endif
 
 /*
- * An "address" in IO memory space is not clearly either an integer
- * or a pointer. We will accept both, thus the casts.
+ * An "address" in IO memory space is not clearly either an integer or a pointer. We will
+ * accept both, thus the casts.
  *
- * On ia-64, we access the physical I/O memory space through the
- * uncached kernel region.
+ * On ia-64, we access the physical I/O memory space through the uncached kernel region.
  */
 static inline void *
 ioremap (unsigned long offset, unsigned long size)
 {
 	return (void *) (__IA64_UNCACHED_OFFSET | (offset));
-} 
+}
 
 static inline void
 iounmap (void *addr)
@@ -412,75 +401,6 @@
   __ia64_memcpy_toio((unsigned long)(to),(from),(len))
 #define memset_io(addr,c,len) \
   __ia64_memset_c_io((unsigned long)(addr),0x0101010101010101UL*(u8)(c),(len))
-
-#define __HAVE_ARCH_MEMSETW_IO
-#define memsetw_io(addr,c,len) \
-  _memset_c_io((unsigned long)(addr),0x0001000100010001UL*(u16)(c),(len))
-
-/*
- * XXX - We don't have csum_partial_copy_fromio() yet, so we cheat here and 
- * just copy it. The net code will then do the checksum later. Presently 
- * only used by some shared memory 8390 Ethernet cards anyway.
- */
-
-#define eth_io_copy_and_sum(skb,src,len,unused)		memcpy_fromio((skb)->data,(src),(len))
-
-#if 0
-
-/*
- * XXX this is the kind of legacy stuff we want to get rid of with IA-64... --davidm 99/12/02
- */
-
-/*
- * This is used for checking BIOS signatures.  It's not clear at all
- * why this is here.  This implementation seems to be the same on
- * all architectures.  Strange.
- */
-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;
-}
-
-#define RTC_PORT(x)		(0x70 + (x))
-#define RTC_ALWAYS_BCD		0
-
-#endif
-
-/*
- * The caches on some architectures aren't DMA-coherent and have need
- * to handle this in software.  There are two types of operations that
- * can be applied to dma buffers.
- *
- * - 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) makes caches and memory coherent
- *   by writing the content of the caches back to memory, if necessary
- *   (cache flush).
- *
- * - dma_cache_wback_inv(start, size) Like dma_cache_wback() but the
- *   function also invalidates the affected part of the caches as
- *   necessary before DMA transfers from outside to memory.
- *
- * Fortunately, the IA-64 architecture mandates cache-coherent DMA, so
- * these functions can be implemented as no-ops.
- */
-#define dma_cache_inv(_start,_size)		do { } while (0)
-#define dma_cache_wback(_start,_size)		do { } while (0)
-#define dma_cache_wback_inv(_start,_size)	do { } while (0)
 
 # endif /* __KERNEL__ */
 #endif /* _ASM_IA64_IO_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/kregs.h linux/include/asm-ia64/kregs.h
--- v2.4.3/linux/include/asm-ia64/kregs.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ia64/kregs.h	Thu Apr  5 12:51:47 2001
@@ -0,0 +1,33 @@
+#ifndef _ASM_IA64_KREGS_H
+#define _ASM_IA64_KREGS_H
+
+/*
+ * Copyright (C) 2001 Hewlett-Packard Co
+ * Copyright (C) 2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+/*
+ * This file defines the kernel register usage convention used by Linux/ia64.
+ */
+
+/*
+ * Kernel registers:
+ */
+#define IA64_KR_IO_BASE		0	/* ar.k0: legacy I/O base address */
+#define IA64_KR_CURRENT_STACK	4	/* ar.k4: what's mapped in IA64_TR_CURRENT_STACK */
+#define IA64_KR_FPU_OWNER	5	/* ar.k5: fpu-owner (UP only, at the moment) */
+#define IA64_KR_CURRENT		6	/* ar.k6: "current" task pointer */
+#define IA64_KR_PT_BASE		7	/* ar.k7: page table base address (physical) */
+
+#define _IA64_KR_PASTE(x,y)	x##y
+#define _IA64_KR_PREFIX(n)	_IA64_KR_PASTE(ar.k, n)
+#define IA64_KR(n)		_IA64_KR_PREFIX(IA64_KR_##n)
+
+/*
+ * Translation registers:
+ */
+#define IA64_TR_KERNEL		0	/* itr0, dtr0: maps kernel image (code & data) */
+#define IA64_TR_PALCODE		1	/* itr1: maps PALcode as required by EFI */
+#define IA64_TR_PERCPU_DATA	1	/* dtr1: percpu data */
+#define IA64_TR_CURRENT_STACK	2	/* dtr2: maps kernel memory & register stacks */
+
+#endif /* _ASM_IA64_kREGS_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/machvec.h linux/include/asm-ia64/machvec.h
--- v2.4.3/linux/include/asm-ia64/machvec.h	Thu Jan  4 12:50:17 2001
+++ linux/include/asm-ia64/machvec.h	Thu Apr  5 12:51:47 2001
@@ -4,8 +4,8 @@
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) Srinivasa Thirumalachar <sprasad@engr.sgi.com>
  * Copyright (C) Vijay Chander <vijay@engr.sgi.com>
- * Copyright (C) 1999-2000 Hewlett-Packard Co.
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2001 Hewlett-Packard Co.
+ * Copyright (C) 1999-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #ifndef _ASM_IA64_MACHVEC_H
 #define _ASM_IA64_MACHVEC_H
@@ -17,6 +17,7 @@
 struct pci_dev;
 struct pt_regs;
 struct scatterlist;
+struct irq_desc;
 
 typedef void ia64_mv_setup_t (char **);
 typedef void ia64_mv_irq_init_t (void);
@@ -27,6 +28,9 @@
 typedef void ia64_mv_cmci_handler_t (int, void *, struct pt_regs *);
 typedef void ia64_mv_log_print_t (void);
 typedef void ia64_mv_send_ipi_t (int, int, int, int);
+typedef struct irq_desc *ia64_mv_irq_desc (unsigned int);
+typedef u8 ia64_mv_irq_to_vector (u8);
+typedef unsigned int ia64_mv_local_vector_to_irq (u8 vector);
 
 /* PCI-DMA interface: */
 typedef void ia64_mv_pci_dma_init (void);
@@ -88,6 +92,9 @@
 #  define platform_pci_dma_sync_single	ia64_mv.sync_single
 #  define platform_pci_dma_sync_sg	ia64_mv.sync_sg
 #  define platform_pci_dma_address	ia64_mv.dma_address
+#  define platform_irq_desc		ia64_mv.irq_desc
+#  define platform_irq_to_vector	ia64_mv.irq_to_vector
+#  define platform_local_vector_to_irq	ia64_mv.local_vector_to_irq
 #  define platform_inb		ia64_mv.inb
 #  define platform_inw		ia64_mv.inw
 #  define platform_inl		ia64_mv.inl
@@ -117,6 +124,9 @@
 	ia64_mv_pci_dma_sync_single *sync_single;
 	ia64_mv_pci_dma_sync_sg *sync_sg;
 	ia64_mv_pci_dma_address *dma_address;
+	ia64_mv_irq_desc *irq_desc;
+	ia64_mv_irq_to_vector *irq_to_vector;
+	ia64_mv_local_vector_to_irq *local_vector_to_irq;
 	ia64_mv_inb_t *inb;
 	ia64_mv_inw_t *inw;
 	ia64_mv_inl_t *inl;
@@ -147,6 +157,9 @@
 	platform_pci_dma_sync_single,		\
 	platform_pci_dma_sync_sg,		\
 	platform_pci_dma_address,		\
+	platform_irq_desc,			\
+	platform_irq_to_vector,			\
+	platform_local_vector_to_irq,		\
 	platform_inb,				\
 	platform_inw,				\
 	platform_inl,				\
@@ -233,6 +246,15 @@
 #endif
 #ifndef platform_pci_dma_address
 # define  platform_pci_dma_address	swiotlb_dma_address
+#endif
+#ifndef platform_irq_desc
+# define platform_irq_desc		__ia64_irq_desc
+#endif
+#ifndef platform_irq_to_vector
+# define platform_irq_to_vector		__ia64_irq_to_vector
+#endif
+#ifndef platform_local_vector_to_irq
+# define platform_local_vector_to_irq	__ia64_local_vector_to_irq
 #endif
 #ifndef platform_inb
 # define platform_inb		__ia64_inb
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/machvec_sn1.h linux/include/asm-ia64/machvec_sn1.h
--- v2.4.3/linux/include/asm-ia64/machvec_sn1.h	Thu Jan  4 12:50:17 2001
+++ linux/include/asm-ia64/machvec_sn1.h	Thu Apr  5 12:51:47 2001
@@ -41,6 +41,7 @@
 #define platform_outb		sn1_outb
 #define platform_outw		sn1_outw
 #define platform_outl		sn1_outl
+#define platform_pci_dma_init	machvec_noop
 #define platform_pci_alloc_consistent	sn1_pci_alloc_consistent
 #define platform_pci_free_consistent	sn1_pci_free_consistent
 #define platform_pci_map_single		sn1_pci_map_single
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/mca.h linux/include/asm-ia64/mca.h
--- v2.4.3/linux/include/asm-ia64/mca.h	Thu Jan  4 12:50:17 2001
+++ linux/include/asm-ia64/mca.h	Thu Apr  5 12:51:47 2001
@@ -1,6 +1,6 @@
 /*
- * File: 	mca.h
- * Purpose: 	Machine check handling specific defines
+ * File:	mca.h
+ * Purpose:	Machine check handling specific defines
  *
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) Vijay Chander (vijay@engr.sgi.com)
@@ -18,7 +18,6 @@
 #include <asm/param.h>
 #include <asm/sal.h>
 #include <asm/processor.h>
-#include <asm/hw_irq.h>
 
 /* These are the return codes from all the IA64_MCA specific interfaces */
 typedef	int ia64_mca_return_code_t;
@@ -30,11 +29,6 @@
 
 #define IA64_MCA_RENDEZ_TIMEOUT		(100 * HZ)	/* 1000 milliseconds */
 
-/* Interrupt vectors reserved for MC handling. */
-#define IA64_MCA_RENDEZ_INT_VECTOR	MCA_RENDEZ_IRQ	/* Rendez interrupt */
-#define IA64_MCA_WAKEUP_INT_VECTOR	MCA_WAKEUP_IRQ	/* Wakeup interrupt */
-#define IA64_MCA_CMC_INT_VECTOR		CMC_IRQ	/* Correctable machine check interrupt */
-
 #define IA64_CMC_INT_DISABLE		0
 #define IA64_CMC_INT_ENABLE		1
 
@@ -45,7 +39,7 @@
 typedef union cmcv_reg_u {
 	u64	cmcv_regval;
 	struct	{
-		u64  	cmcr_vector		: 8;
+		u64	cmcr_vector		: 8;
 		u64	cmcr_reserved1		: 4;
 		u64	cmcr_ignored1		: 1;
 		u64	cmcr_reserved2		: 3;
@@ -63,15 +57,15 @@
 #define IA64_INIT_HANDLER_SIZE		0x10
 
 enum {
-	IA64_MCA_RENDEZ_CHECKIN_NOTDONE	= 	0x0,
-	IA64_MCA_RENDEZ_CHECKIN_DONE 	= 	0x1
+	IA64_MCA_RENDEZ_CHECKIN_NOTDONE	=	0x0,
+	IA64_MCA_RENDEZ_CHECKIN_DONE	=	0x1
 };
 
 #define IA64_MAXCPUS	64	/* Need to do something about this */
 
 /* Information maintained by the MC infrastructure */
 typedef struct ia64_mc_info_s {
-	u64		imi_mca_handler;		
+	u64		imi_mca_handler;
 	size_t		imi_mca_handler_size;
 	u64		imi_monarch_init_handler;
 	size_t		imi_monarch_init_handler_size;
@@ -85,7 +79,7 @@
  * handoff
  */
 enum {
-	IA64_MCA_RENDEZ_NOT_RQD 		= 	0x0,
+	IA64_MCA_RENDEZ_NOT_RQD		=	0x0,
 	IA64_MCA_RENDEZ_DONE_WITHOUT_INIT	=	0x1,
 	IA64_MCA_RENDEZ_DONE_WITH_INIT		=	0x2,
 	IA64_MCA_RENDEZ_FAILURE			=	-1
@@ -103,12 +97,12 @@
 } ia64_mca_sal_to_os_state_t;
 
 enum {
-	IA64_MCA_CORRECTED 	= 	0x0,	/* Error has been corrected by OS_MCA */
+	IA64_MCA_CORRECTED	=	0x0,	/* Error has been corrected by OS_MCA */
 	IA64_MCA_WARM_BOOT	=	-1,	/* Warm boot of the system need from SAL */
 	IA64_MCA_COLD_BOOT	=	-2,	/* Cold boot of the system need from SAL */
 	IA64_MCA_HALT		=	-3	/* System to be halted by SAL */
 };
-	
+
 typedef struct ia64_mca_os_to_sal_state_s {
 	u64		imots_os_status;	/*   OS status to SAL as to what happened
 						 *   with the MCA handling.
@@ -138,7 +132,7 @@
 
 #define PLATFORM_CALL(fn, args)	printk("Platform call TBD\n")
 
-#undef 	MCA_TEST
+#undef	MCA_TEST
 
 #define IA64_MCA_DEBUG_INFO 1
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/mca_asm.h linux/include/asm-ia64/mca_asm.h
--- v2.4.3/linux/include/asm-ia64/mca_asm.h	Fri Apr 21 15:21:24 2000
+++ linux/include/asm-ia64/mca_asm.h	Thu Apr  5 12:51:47 2001
@@ -72,7 +72,7 @@
 	;;										\
 	dep	old_psr = 0, old_psr, 32, 32;						\
 	                                                                                \
-	mov	ar.rsc = r0 ;								\
+	mov	ar.rsc = 0 ;								\
 	;;										\
 	mov	temp2 = ar.bspstore;							\
 	;;										\
@@ -148,7 +148,7 @@
 	dep	temp2 = 0, temp2, PSR_IC, 2;						\
 	;;										\
 	mov	psr.l = temp2;								\
-	mov	ar.rsc = r0;								\
+	mov	ar.rsc = 0;								\
 	;;										\
 	srlz.d;										\
 	mov	temp2 = ar.bspstore;							\
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/mmu_context.h linux/include/asm-ia64/mmu_context.h
--- v2.4.3/linux/include/asm-ia64/mmu_context.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/mmu_context.h	Thu Apr  5 12:51:47 2001
@@ -2,35 +2,32 @@
 #define _ASM_IA64_MMU_CONTEXT_H
 
 /*
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-
-#include <asm/processor.h>
-
 /*
- * Routines to manage the allocation of task context numbers.  Task
- * context numbers are used to reduce or eliminate the need to perform
- * TLB flushes due to context switches.  Context numbers are
- * implemented using ia-64 region ids.  Since ia-64 TLBs do not
- * guarantee that the region number is checked 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.  On processors where the region number is checked
- * in TLB lookups, we can get back those two bits by defining
- * CONFIG_IA64_TLB_CHECKS_REGION_NUMBER.  The macro
- * IA64_REGION_ID_BITS gives the number of bits in a region id.  The
- * architecture manual guarantees this number to be in the range
- * 18-24.
+ * Routines to manage the allocation of task context numbers.  Task context numbers are
+ * used to reduce or eliminate the need to perform TLB flushes due to context switches.
+ * Context numbers are implemented using ia-64 region ids.  Since the IA-64 TLB does not
+ * 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 David Mosberger-Tang <davidm@hpl.hp.com>
+ * 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) */
 
+#define ia64_rid(ctx,addr)	(((ctx) << 3) | (addr >> 61))
+
+# ifndef __ASSEMBLY__
+
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+
+#include <asm/processor.h>
+
 struct ia64_ctx {
 	spinlock_t lock;
 	unsigned int next;	/* next context number to use */
@@ -47,12 +44,6 @@
 {
 }
 
-static inline unsigned long
-ia64_rid (unsigned long context, unsigned long region_addr)
-{
-	return context << 3 | (region_addr >> 61);
-}
-
 static inline void
 get_new_mmu_context (struct mm_struct *mm)
 {
@@ -123,11 +114,12 @@
 	 * We may get interrupts here, but that's OK because interrupt
 	 * handlers cannot touch user-space.
 	 */
-	__asm__ __volatile__ ("mov ar.k7=%0" :: "r"(__pa(next->pgd)));
+	ia64_set_kr(IA64_KR_PT_BASE, __pa(next->pgd));
 	get_mmu_context(next);
 	reload_context(next);
 }
 
 #define switch_mm(prev_mm,next_mm,next_task,cpu)	activate_mm(prev_mm, next_mm)
 
+# endif /* ! __ASSEMBLY__ */
 #endif /* _ASM_IA64_MMU_CONTEXT_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/module.h linux/include/asm-ia64/module.h
--- v2.4.3/linux/include/asm-ia64/module.h	Thu Jan  4 12:50:17 2001
+++ linux/include/asm-ia64/module.h	Thu Apr  5 12:51:47 2001
@@ -35,7 +35,6 @@
 static inline int
 ia64_module_init(struct module *mod)
 {
-#ifdef CONFIG_IA64_NEW_UNWIND
 	struct archdata *archdata;
 
 	if (!mod_member_present(mod, archdata_start) || !mod->archdata_start)
@@ -79,14 +78,12 @@
 						   (unsigned long) archdata->segment_base,
 						   (unsigned long) archdata->gp,
 						   archdata->unw_start, archdata->unw_end);
-#endif /* CONFIG_IA64_NEW_UNWIND */
 	return 0;
 }
 
 static inline void
 ia64_module_unmap(void * addr)
 {
-#ifdef CONFIG_IA64_NEW_UNWIND
 	struct module *mod = (struct module *) addr;
 	struct archdata *archdata;
 
@@ -100,7 +97,6 @@
 		if (archdata->unw_table != NULL)
 			unw_remove_unwind_table((void *) archdata->unw_table);
 	}
-#endif /* CONFIG_IA64_NEW_UNWIND */
 
 	vfree(addr);
 }
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/offsets.h linux/include/asm-ia64/offsets.h
--- v2.4.3/linux/include/asm-ia64/offsets.h	Thu Jan  4 12:50:18 2001
+++ linux/include/asm-ia64/offsets.h	Thu Apr  5 12:51:47 2001
@@ -11,10 +11,11 @@
 #define PT_PTRACED_BIT			0
 #define PT_TRACESYS_BIT			1
 
-#define IA64_TASK_SIZE			3376	/* 0xd30 */
+#define IA64_TASK_SIZE			3904	/* 0xf40 */
 #define IA64_PT_REGS_SIZE		400	/* 0x190 */
 #define IA64_SWITCH_STACK_SIZE		560	/* 0x230 */
 #define IA64_SIGINFO_SIZE		128	/* 0x80 */
+#define IA64_CPU_SIZE			16384	/* 0x4000 */
 #define UNW_FRAME_INFO_SIZE		448	/* 0x1c0 */
 
 #define IA64_TASK_PTRACE_OFFSET		48	/* 0x30 */
@@ -23,7 +24,8 @@
 #define IA64_TASK_PROCESSOR_OFFSET	100	/* 0x64 */
 #define IA64_TASK_THREAD_OFFSET		1456	/* 0x5b0 */
 #define IA64_TASK_THREAD_KSP_OFFSET	1456	/* 0x5b0 */
-#define IA64_TASK_THREAD_SIGMASK_OFFSET	3224	/* 0xc98 */
+#define IA64_TASK_THREAD_SIGMASK_OFFSET	3752	/* 0xea8 */
+#define IA64_TASK_PFM_NOTIFY_OFFSET	3648	/* 0xe40 */
 #define IA64_TASK_PID_OFFSET		196	/* 0xc4 */
 #define IA64_TASK_MM_OFFSET		88	/* 0x58 */
 #define IA64_PT_REGS_CR_IPSR_OFFSET	0	/* 0x0 */
@@ -123,5 +125,10 @@
 #define IA64_SIGCONTEXT_FR6_OFFSET	560	/* 0x230 */
 #define IA64_CLONE_VFORK			16384	/* 0x4000 */
 #define IA64_CLONE_VM			256	/* 0x100 */
+#define IA64_CPU_IRQ_COUNT_OFFSET	8	/* 0x8 */
+#define IA64_CPU_BH_COUNT_OFFSET		12	/* 0xc */
+#define IA64_CPU_SOFTIRQ_ACTIVE_OFFSET	0	/* 0x0 */
+#define IA64_CPU_SOFTIRQ_MASK_OFFSET	4	/* 0x4 */
+#define IA64_CPU_PHYS_STACKED_SIZE_P8_OFFSET 16	/* 0x10 */
 
 #endif /* _ASM_IA64_OFFSETS_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/page.h linux/include/asm-ia64/page.h
--- v2.4.3/linux/include/asm-ia64/page.h	Thu Jan  4 12:50:18 2001
+++ linux/include/asm-ia64/page.h	Thu Apr  5 12:51:47 2001
@@ -40,43 +40,6 @@
 extern void clear_page (void *page);
 extern void copy_page (void *to, void *from);
 
-#  ifdef STRICT_MM_TYPECHECKS
-/*
- * These are used to make use of C type-checking..
- */
-typedef struct { unsigned 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 __pgprot(x)	((pgprot_t) { (x) } )
-
-#  else /* !STRICT_MM_TYPECHECKS */
-/*
- * .. while these make it easier on the compiler
- */
-typedef unsigned long pte_t;
-typedef unsigned long pmd_t;
-typedef unsigned long pgd_t;
-typedef unsigned long pgprot_t;
-
-#define pte_val(x)	(x)
-#define pmd_val(x)	(x)
-#define pgd_val(x)	(x)
-#define pgprot_val(x)	(x)
-
-#define __pte(x)	(x)
-#define __pgd(x)	(x)
-#define __pgprot(x)	(x)
-
-#  endif /* !STRICT_MM_TYPECHECKS */
-
 /*
  * Note: the MAP_NR_*() macro can't use __pa() because MAP_NR_*(X) MUST
  * map to something >= max_mapnr if X is outside the identity mapped
@@ -133,7 +96,7 @@
 {
 	double d = size - 1;
 	long order;
-                
+
 	__asm__ ("getf.exp %0=%1" : "=r"(order) : "f"(d));
 	order = order - PAGE_SHIFT - 0xffff + 1;
 	if (order < 0)
@@ -142,7 +105,45 @@
 }
 
 # endif /* __KERNEL__ */
-#endif /* !ASSEMBLY */
+#endif /* !__ASSEMBLY__ */
+
+#ifdef STRICT_MM_TYPECHECKS
+  /*
+   * These are used to make use of C type-checking..
+   */
+  typedef struct { unsigned 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 __pgprot(x)	((pgprot_t) { (x) } )
+
+#else /* !STRICT_MM_TYPECHECKS */
+  /*
+   * .. while these make it easier on the compiler
+   */
+# ifndef __ASSEMBLY__
+    typedef unsigned long pte_t;
+    typedef unsigned long pmd_t;
+    typedef unsigned long pgd_t;
+    typedef unsigned long pgprot_t;
+# endif
+
+# define pte_val(x)	(x)
+# define pmd_val(x)	(x)
+# define pgd_val(x)	(x)
+# define pgprot_val(x)	(x)
+
+# define __pte(x)	(x)
+# define __pgd(x)	(x)
+# define __pgprot(x)	(x)
+#endif /* !STRICT_MM_TYPECHECKS */
 
 #define PAGE_OFFSET		0xe000000000000000
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/pal.h linux/include/asm-ia64/pal.h
--- v2.4.3/linux/include/asm-ia64/pal.h	Mon Oct  9 17:54:59 2000
+++ linux/include/asm-ia64/pal.h	Thu Apr  5 12:51:47 2001
@@ -1267,7 +1267,7 @@
 ia64_pal_version (pal_version_u_t *pal_min_version, pal_version_u_t *pal_cur_version) 
 {	
 	struct ia64_pal_retval iprv;
-	PAL_CALL(iprv, PAL_VERSION, 0, 0, 0);
+	PAL_CALL_PHYS(iprv, PAL_VERSION, 0, 0, 0);
 	if (pal_min_version)
 		pal_min_version->pal_version_val = iprv.v0;
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/param.h linux/include/asm-ia64/param.h
--- v2.4.3/linux/include/asm-ia64/param.h	Fri Oct 27 11:04:43 2000
+++ linux/include/asm-ia64/param.h	Thu Apr  5 12:51:47 2001
@@ -10,7 +10,7 @@
 
 #include <linux/config.h>
 
-#if defined(CONFIG_IA64_HP_SIM) || defined(CONFIG_IA64_SOFTSDV_HACKS)
+#ifdef CONFIG_IA64_HP_SIM
 /*
  * Yeah, simulating stuff is slow, so let us catch some breath between
  * timer interrupts...
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/perfmon.h linux/include/asm-ia64/perfmon.h
--- v2.4.3/linux/include/asm-ia64/perfmon.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ia64/perfmon.h	Thu Apr  5 12:51:47 2001
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2001 Hewlett-Packard Co
+ * Copyright (C) 2001 Stephane Eranian <eranian@hpl.hp.com>
+ */
+
+#ifndef _ASM_IA64_PERFMON_H
+#define _ASM_IA64_PERFMON_H
+
+#include <linux/types.h>
+
+/*
+ * Structure used to define a context
+ */
+typedef struct {
+	unsigned long smpl_entries;	/* how many entries in sampling buffer */
+	unsigned long smpl_regs;	/* which pmds to record on overflow */
+	void	      *smpl_vaddr;	/* returns address of BTB buffer */
+
+	pid_t	      notify_pid;	/* which process to notify on overflow */
+	int	      notify_sig; 	/* XXX: not used anymore */
+
+	int	      flags;		/* NOBLOCK/BLOCK/ INHERIT flags (will replace API flags) */
+} pfreq_context_t;
+
+/*
+ * Structure used to configure a PMC or PMD
+ */
+typedef struct {
+	unsigned long	reg_num;	/* which register */
+	unsigned long	reg_value;	/* configuration (PMC) or initial value (PMD) */
+	unsigned long	reg_smpl_reset;	/* reset of sampling buffer overflow (large) */
+	unsigned long	reg_ovfl_reset;	/* reset on counter overflow (small) */
+	int		reg_flags;	/* (PMD): notify/don't notify */
+} pfreq_reg_t;
+
+/*
+ * main request structure passed by user
+ */
+typedef union {
+	pfreq_context_t	pfr_ctx;	/* request to configure a context */
+	pfreq_reg_t	pfr_reg;	/* request to configure a PMD/PMC */
+} perfmon_req_t;
+
+extern void pfm_save_regs (struct task_struct *);
+extern void pfm_load_regs (struct task_struct *);
+
+extern int pfm_inherit (struct task_struct *);
+extern void pfm_context_exit (struct task_struct *);
+extern void pfm_flush_regs (struct task_struct *);
+
+#endif /* _ASM_IA64_PERFMON_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/pgalloc.h linux/include/asm-ia64/pgalloc.h
--- v2.4.3/linux/include/asm-ia64/pgalloc.h	Thu Jan  4 12:50:18 2001
+++ linux/include/asm-ia64/pgalloc.h	Thu Apr  5 12:51:47 2001
@@ -8,8 +8,8 @@
  * This hopefully works with any (fixed) ia-64 page-size, as defined
  * in <asm/page.h> (currently 8192).
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 2000, Goutham Rao <goutham.rao@intel.com>
  */
 
@@ -28,68 +28,60 @@
  * a lot of work and caused unnecessary memory traffic.  How broken...
  * We fix this by caching them.
  */
-#define pgd_quicklist		(my_cpu_data.pgd_quick)
-#define pmd_quicklist		(my_cpu_data.pmd_quick)
-#define pte_quicklist		(my_cpu_data.pte_quick)
-#define pgtable_cache_size	(my_cpu_data.pgtable_cache_sz)
-
-static __inline__ pgd_t*
-get_pgd_slow (void)
-{
-	pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL);
-	if (ret)
-		clear_page(ret);
-	return ret;
-}
+#define pgd_quicklist		(local_cpu_data->pgd_quick)
+#define pmd_quicklist		(local_cpu_data->pmd_quick)
+#define pte_quicklist		(local_cpu_data->pte_quick)
+#define pgtable_cache_size	(local_cpu_data->pgtable_cache_sz)
 
-static __inline__ pgd_t*
-get_pgd_fast (void)
+static inline pgd_t*
+pgd_alloc_one_fast (void)
 {
 	unsigned long *ret = pgd_quicklist;
 
-	if (ret != NULL) {
+	if (__builtin_expect(ret != NULL, 1)) {
 		pgd_quicklist = (unsigned long *)(*ret);
 		ret[0] = 0;
 		--pgtable_cache_size;
-	}
-	return (pgd_t *)ret;
+	} else
+		ret = NULL;
+	return (pgd_t *) ret;
 }
 
-static __inline__ pgd_t*
+static inline pgd_t*
 pgd_alloc (void)
 {
-	pgd_t *pgd;
+	/* the VM system never calls pgd_alloc_one_fast(), so we do it here. */
+	pgd_t *pgd = pgd_alloc_one_fast();
 
-	pgd = get_pgd_fast();
-	if (!pgd)
-		pgd = get_pgd_slow();
+	if (__builtin_expect(pgd == NULL, 0)) {
+		pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
+		if (__builtin_expect(pgd != NULL, 1))
+			clear_page(pgd);
+	}
 	return pgd;
 }
 
-static __inline__ void
-free_pgd_fast (pgd_t *pgd)
+static inline void
+pgd_free (pgd_t *pgd)
 {
 	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
 	pgd_quicklist = (unsigned long *) pgd;
 	++pgtable_cache_size;
 }
 
-static __inline__ pmd_t *
-get_pmd_slow (void)
+static inline void
+pgd_populate (struct mm_struct *mm, pgd_t *pgd_entry, pmd_t *pmd)
 {
-	pmd_t *pmd = (pmd_t *) __get_free_page(GFP_KERNEL);
-
-	if (pmd)
-		clear_page(pmd);
-	return pmd;
+	pgd_val(*pgd_entry) = __pa(pmd);
 }
 
-static __inline__ pmd_t *
-get_pmd_fast (void)
+
+static inline pmd_t*
+pmd_alloc_one_fast (struct mm_struct *mm, unsigned long addr)
 {
 	unsigned long *ret = (unsigned long *)pmd_quicklist;
 
-	if (ret != NULL) {
+	if (__builtin_expect(ret != NULL, 1)) {
 		pmd_quicklist = (unsigned long *)(*ret);
 		ret[0] = 0;
 		--pgtable_cache_size;
@@ -97,28 +89,36 @@
 	return (pmd_t *)ret;
 }
 
-static __inline__ void
-free_pmd_fast (pmd_t *pmd)
+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 (__builtin_expect(pmd != NULL, 1))
+		clear_page(pmd);
+	return pmd;
+}
+
+static inline void
+pmd_free (pmd_t *pmd)
 {
 	*(unsigned long *)pmd = (unsigned long) pmd_quicklist;
 	pmd_quicklist = (unsigned long *) pmd;
 	++pgtable_cache_size;
 }
 
-static __inline__ void
-free_pmd_slow (pmd_t *pmd)
+static inline void
+pmd_populate (struct mm_struct *mm, pmd_t *pmd_entry, pte_t *pte)
 {
-	free_page((unsigned long)pmd);
+	pmd_val(*pmd_entry) = __pa(pte);
 }
 
-extern pte_t *get_pte_slow (pmd_t *pmd, unsigned long address_preadjusted);
-
-static __inline__ pte_t *
-get_pte_fast (void)
+static inline pte_t*
+pte_alloc_one_fast (struct mm_struct *mm, unsigned long addr)
 {
 	unsigned long *ret = (unsigned long *)pte_quicklist;
 
-	if (ret != NULL) {
+	if (__builtin_expect(ret != NULL, 1)) {
 		pte_quicklist = (unsigned long *)(*ret);
 		ret[0] = 0;
 		--pgtable_cache_size;
@@ -126,71 +126,25 @@
 	return (pte_t *)ret;
 }
 
-static __inline__ void
-free_pte_fast (pte_t *pte)
+
+static inline pte_t*
+pte_alloc_one (struct mm_struct *mm, unsigned long addr)
 {
-	*(unsigned long *)pte = (unsigned long) pte_quicklist;
-	pte_quicklist = (unsigned long *) pte;
-	++pgtable_cache_size;
-}
+	pte_t *pte = (pte_t *) __get_free_page(GFP_KERNEL);
 
-#define pte_free_kernel(pte)	free_pte_fast(pte)
-#define pte_free(pte)		free_pte_fast(pte)
-#define pmd_free_kernel(pmd)	free_pmd_fast(pmd)
-#define pmd_free(pmd)		free_pmd_fast(pmd)
-#define pgd_free(pgd)		free_pgd_fast(pgd)
-
-extern void __handle_bad_pgd (pgd_t *pgd);
-extern void __handle_bad_pmd (pmd_t *pmd);
-
-static __inline__ pte_t*
-pte_alloc (pmd_t *pmd, unsigned long vmaddr)
-{
-	unsigned long offset;
-
-	offset = (vmaddr >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
-	if (pmd_none(*pmd)) {
-		pte_t *pte_page = get_pte_fast();
-
-		if (!pte_page)
-			return get_pte_slow(pmd, offset);
-		pmd_set(pmd, pte_page);
-		return pte_page + offset;
-	}
-	if (pmd_bad(*pmd)) {
-		__handle_bad_pmd(pmd);
-		return NULL;
-	}
-	return (pte_t *) pmd_page(*pmd) + offset;
+	if (__builtin_expect(pte != NULL, 1))
+		clear_page(pte);
+	return pte;
 }
 
-static __inline__ pmd_t*
-pmd_alloc (pgd_t *pgd, unsigned long vmaddr)
+static inline void
+pte_free (pte_t *pte)
 {
-	unsigned long offset;
-
-	offset = (vmaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
-	if (pgd_none(*pgd)) {
-		pmd_t *pmd_page = get_pmd_fast();
-
-		if (!pmd_page)
-			pmd_page = get_pmd_slow();
-		if (pmd_page) {
-			pgd_set(pgd, pmd_page);
-			return pmd_page + offset;
-		} else
-			return NULL;
-	}
-	if (pgd_bad(*pgd)) {
-		__handle_bad_pgd(pgd);
-		return NULL;
-	}
-	return (pmd_t *) pgd_page(*pgd) + offset;
+	*(unsigned long *)pte = (unsigned long) pte_quicklist;
+	pte_quicklist = (unsigned long *) pte;
+	++pgtable_cache_size;
 }
 
-#define pte_alloc_kernel(pmd, addr)	pte_alloc(pmd, addr)
-#define pmd_alloc_kernel(pgd, addr)	pmd_alloc(pgd, addr)
-
 extern int do_check_pgt_cache (int, int);
 
 /*
@@ -219,7 +173,7 @@
 /*
  * Flush a specified user mapping
  */
-static __inline__ void
+static inline void
 flush_tlb_mm (struct mm_struct *mm)
 {
 	if (mm) {
@@ -237,7 +191,7 @@
 /*
  * Page-granular tlb flush.
  */
-static __inline__ void
+static inline void
 flush_tlb_page (struct vm_area_struct *vma, unsigned long addr)
 {
 #ifdef CONFIG_SMP
@@ -300,20 +254,22 @@
  * that may be necessary.
  */
 static inline void
-update_mmu_cache (struct vm_area_struct *vma, unsigned long address, pte_t pte)
+update_mmu_cache (struct vm_area_struct *vma, unsigned long vaddr, pte_t pte)
 {
+	unsigned long addr;
 	struct page *page;
 
 	if (!pte_exec(pte))
 		return;				/* not an executable page... */
 
 	page = pte_page(pte);
-	address &= PAGE_MASK;
+	/* don't use VADDR: it may not be mapped on this CPU (or may have just been flushed): */
+	addr = (unsigned long) page_address(page);
 
 	if (test_bit(PG_arch_1, &page->flags))
 		return;				/* i-cache is already coherent with d-cache */
 
-	flush_icache_range(address, address + PAGE_SIZE);
+	flush_icache_range(addr, addr + PAGE_SIZE);
 	set_bit(PG_arch_1, &page->flags);	/* mark page as clean */
 }
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/pgtable.h linux/include/asm-ia64/pgtable.h
--- v2.4.3/linux/include/asm-ia64/pgtable.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/pgtable.h	Thu Apr  5 12:51:47 2001
@@ -8,11 +8,12 @@
  * This hopefully works with any (fixed) IA-64 page-size, as defined
  * in <asm/page.h> (currently 8192).
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <linux/config.h>
+
 #include <asm/mman.h>
 #include <asm/page.h>
 #include <asm/processor.h>
@@ -103,12 +104,6 @@
  */
 #define PTRS_PER_PTE	(__IA64_UL(1) << (PAGE_SHIFT-3))
 
-# ifndef __ASSEMBLY__
-
-#include <asm/bitops.h>
-#include <asm/mmu_context.h>
-#include <asm/system.h>
-
 /*
  * All the normal masks have the "page accessed" bits on, as any time
  * they are used, the page is accessed. They are cleared only by the
@@ -126,6 +121,13 @@
 #define PAGE_GATE	__pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
 #define PAGE_KERNEL	__pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
 
+# ifndef __ASSEMBLY__
+
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+
 /*
  * Next come the mappings that determine how mmap() protection bits
  * (PROT_EXEC, PROT_READ, PROT_WRITE, PROT_NONE) get implemented.  The
@@ -173,7 +175,7 @@
 static inline long
 ia64_phys_addr_valid (unsigned long addr)
 {
-	return (addr & (my_cpu_data.unimpl_pa_mask)) == 0;
+	return (addr & (local_cpu_data->unimpl_pa_mask)) == 0;
 }
 
 /*
@@ -203,25 +205,12 @@
 #define set_pte(ptep, pteval)	(*(ptep) = (pteval))
 
 #define RGN_SIZE	(1UL << 61)
-#define RGN_MAP_LIMIT	(1UL << (4*PAGE_SHIFT - 12))	/* limit of mappable area in region */
+#define RGN_MAP_LIMIT	((1UL << (4*PAGE_SHIFT - 12)) - PAGE_SIZE)	/* per region addr limit */
 #define RGN_KERNEL	7
 
-#define VMALLOC_START		(0xa000000000000000 + 2*PAGE_SIZE)
+#define VMALLOC_START		(0xa000000000000000 + 3*PAGE_SIZE)
 #define VMALLOC_VMADDR(x)	((unsigned long)(x))
-#define VMALLOC_END		(0xa000000000000000 + RGN_MAP_LIMIT)
-
-/*
- * BAD_PAGETABLE is used when we need a bogus page-table, while
- * BAD_PAGE is used for a bogus page.
- *
- * ZERO_PAGE is a global shared page that is always zero:  used
- * for zero-mapped memory areas etc..
- */
-extern pte_t ia64_bad_page (void);
-extern pmd_t *ia64_bad_pagetable (void);
-
-#define BAD_PAGETABLE	ia64_bad_pagetable()
-#define BAD_PAGE	ia64_bad_page()
+#define VMALLOC_END		(0xa000000000000000 + (1UL << (4*PAGE_SHIFT - 9)))
 
 /*
  * Conversion functions: convert a page and protection to a page entry,
@@ -251,14 +240,12 @@
 /* pte_page() returns the "struct page *" corresponding to the PTE: */
 #define pte_page(pte)			(mem_map + (unsigned long) ((pte_val(pte) & _PFN_MASK) >> PAGE_SHIFT))
 
-#define pmd_set(pmdp, ptep) 		(pmd_val(*(pmdp)) = __pa(ptep))
 #define pmd_none(pmd)			(!pmd_val(pmd))
 #define pmd_bad(pmd)			(!ia64_phys_addr_valid(pmd_val(pmd)))
 #define pmd_present(pmd)		(pmd_val(pmd) != 0UL)
 #define pmd_clear(pmdp)			(pmd_val(*(pmdp)) = 0UL)
 #define pmd_page(pmd)			((unsigned long) __va(pmd_val(pmd) & _PFN_MASK))
 
-#define pgd_set(pgdp, pmdp)		(pgd_val(*(pgdp)) = __pa(pmdp))
 #define pgd_none(pgd)			(!pgd_val(pgd))
 #define pgd_bad(pgd)			(!ia64_phys_addr_valid(pgd_val(pgd)))
 #define pgd_present(pgd)		(pgd_val(pgd) != 0UL)
@@ -301,7 +288,11 @@
  * works bypasses the caches, but does allow for consecutive writes to
  * be combined into single (but larger) write transactions.
  */
-#define pgprot_writecombine(prot)	__pgprot((pgprot_val(prot) & ~_PAGE_MA_MASK) | _PAGE_MA_WC)
+#ifdef CONFIG_MCKINLEY_A0_SPECIFIC
+# define pgprot_writecombine(prot)	prot
+#else
+# define pgprot_writecombine(prot)	__pgprot((pgprot_val(prot) & ~_PAGE_MA_MASK) | _PAGE_MA_WC)
+#endif
 
 /*
  * Return the region index for virtual address ADDRESS.
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/processor.h linux/include/asm-ia64/processor.h
--- v2.4.3/linux/include/asm-ia64/processor.h	Thu Jan  4 12:50:18 2001
+++ linux/include/asm-ia64/processor.h	Thu Apr  5 12:51:47 2001
@@ -2,9 +2,9 @@
 #define _ASM_IA64_PROCESSOR_H
 
 /*
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1998-2000 Stephane Eranian <eranian@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Stephane Eranian <eranian@hpl.hp.com>
  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
  *
@@ -16,6 +16,8 @@
 #include <linux/config.h>
 
 #include <asm/ptrace.h>
+#include <asm/kregs.h>
+#include <asm/system.h>
 #include <asm/types.h>
 
 #define IA64_NUM_DBG_REGS	8
@@ -27,6 +29,9 @@
 #define IA64_NUM_PMD_REGS	32
 #define IA64_NUM_PMD_COUNTERS	4
 
+#define DEFAULT_MAP_BASE	0x2000000000000000
+#define DEFAULT_TASK_SIZE	0xa000000000000000
+
 /*
  * TASK_SIZE really is a mis-named.  It really is the maximum user
  * space address (plus one).  On IA-64, there are five regions of 2TB
@@ -169,9 +174,16 @@
 #define IA64_THREAD_UAC_SHIFT	3
 #define IA64_THREAD_UAC_MASK	(IA64_THREAD_UAC_NOPRINT | IA64_THREAD_UAC_SIGBUS)
 
+
+/*
+ * This shift should be large enough to be able to represent
+ * 1000000/itc_freq with good accuracy while being small enough to fit
+ * 1000000<<IA64_USEC_PER_CYC_SHIFT in 64 bits.
+ */
+#define IA64_USEC_PER_CYC_SHIFT	41
+
 #ifndef __ASSEMBLY__
 
-#include <linux/smp.h>
 #include <linux/threads.h>
 
 #include <asm/fpu.h>
@@ -220,16 +232,26 @@
 };
 
 /*
- * This shift should be large enough to be able to represent
- * 1000000/itc_freq with good accuracy while being small enough to fit
- * 1000000<<IA64_USEC_PER_CYC_SHIFT in 64 bits.
- */
-#define IA64_USEC_PER_CYC_SHIFT	41
-
-/*
- * CPU type, hardware bug flags, and per-CPU state.
+ * CPU type, hardware bug flags, and per-CPU state.  Frequently used
+ * state comes earlier:
  */
 struct cpuinfo_ia64 {
+	/* irq_stat and softirq should be 64-bit aligned */
+	struct {
+		__u32 active;
+		__u32 mask;
+	} softirq;
+	union {
+		struct {
+			__u32 irq_count;
+			__u32 bh_count;
+		} f;
+		__u64 irq_and_bh_counts;
+	} irq_stat;
+	__u32 phys_stacked_size_p8;	/* size of physical stacked registers + 8 */
+	__u32 pad0;
+	__u64 itm_delta;	/* # of clock cycles between clock ticks */
+	__u64 itm_next;		/* interval timer mask value to use for next clock tick */
 	__u64 *pgd_quick;
 	__u64 *pmd_quick;
 	__u64 *pte_quick;
@@ -257,10 +279,15 @@
 	__u64 ipi_count;
 	__u64 prof_counter;
 	__u64 prof_multiplier;
+	__u64 ipi_operation;
 #endif
-};
+} __attribute__ ((aligned (PAGE_SIZE))) ;
 
-#define my_cpu_data		cpu_data[smp_processor_id()]
+/*
+ * The "local" data pointer.  It points to the per-CPU data of the currently executing
+ * CPU, much like "current" points to the per-task data of the currently executing task.
+ */
+#define local_cpu_data		((struct cpuinfo_ia64 *) PERCPU_ADDR)
 
 extern struct cpuinfo_ia64 cpu_data[NR_CPUS];
 
@@ -294,13 +321,9 @@
 #ifdef CONFIG_PERFMON
 	__u64 pmc[IA64_NUM_PMC_REGS];
 	__u64 pmd[IA64_NUM_PMD_REGS];
-	struct {
-		__u64		val;	/* virtual 64bit counter */
-		__u64		rval;	/* reset value on overflow */
-		int		sig;	/* signal used to notify */
-		int		pid;	/* process to notify */
-	} pmu_counters[IA64_NUM_PMD_COUNTERS];
-# define INIT_THREAD_PM		{0, }, {0, }, {{ 0, 0, 0, 0}, },
+	unsigned long pfm_pend_notify;	/* non-zero if we need to notify and block */
+	void *pfm_context;		/* pointer to detailed PMU context */
+# define INIT_THREAD_PM		{0, }, {0, }, 0, 0,
 #else
 # define INIT_THREAD_PM
 #endif
@@ -338,25 +361,53 @@
 	{0, },				/* dbr */	\
 	{0, },				/* ibr */	\
 	INIT_THREAD_PM					\
-	0x2000000000000000,		/* map_base */	\
-	0xa000000000000000,		/* task_size */	\
+	DEFAULT_MAP_BASE,		/* map_base */	\
+	DEFAULT_TASK_SIZE,		/* task_size */	\
 	INIT_THREAD_IA32				\
 	0				/* siginfo */	\
 }
 
-#define start_thread(regs,new_ip,new_sp) do {					\
-	set_fs(USER_DS);							\
-	ia64_psr(regs)->dfh = 1;	/* disable fph */			\
-	ia64_psr(regs)->mfh = 0;	/* clear mfh */				\
-	ia64_psr(regs)->cpl = 3;	/* set user mode */			\
-	ia64_psr(regs)->ri = 0;		/* clear return slot number */		\
-	ia64_psr(regs)->is = 0;		/* IA-64 instruction set */		\
-	regs->cr_iip = new_ip;							\
-	regs->ar_rsc = 0xf;		/* eager mode, privilege level 3 */	\
-	regs->r12 = new_sp - 16;	/* allocate 16 byte scratch area */	\
-	regs->ar_bspstore = IA64_RBS_BOT;					\
-	regs->ar_rnat = 0;							\
-	regs->loadrs = 0;							\
+#define start_thread(regs,new_ip,new_sp) do {							\
+	set_fs(USER_DS);									\
+	ia64_psr(regs)->dfh = 1;	/* disable fph */					\
+	ia64_psr(regs)->mfh = 0;	/* clear mfh */						\
+	ia64_psr(regs)->cpl = 3;	/* set user mode */					\
+	ia64_psr(regs)->ri = 0;		/* clear return slot number */				\
+	ia64_psr(regs)->is = 0;		/* IA-64 instruction set */				\
+	regs->cr_iip = new_ip;									\
+	regs->ar_rsc = 0xf;		/* eager mode, privilege level 3 */			\
+	regs->ar_rnat = 0;									\
+	regs->ar_bspstore = IA64_RBS_BOT;							\
+	regs->ar_fpsr = FPSR_DEFAULT;								\
+	regs->loadrs = 0;									\
+	regs->r8 = current->dumpable;	/* set "don't zap registers" flag */			\
+	regs->r12 = new_sp - 16;	/* allocate 16 byte scratch area */			\
+	if (!__builtin_expect (current->dumpable, 1)) {						\
+		/*										\
+		 * Zap scratch regs to avoid leaking bits between processes with different	\
+		 * uid/privileges.								\
+		 */										\
+		regs->ar_pfs = 0;								\
+		regs->pr = 0;									\
+		/*										\
+		 * XXX fix me: everything below can go away once we stop preserving scratch	\
+		 * regs on a system call.							\
+		 */										\
+		regs->b6 = 0;									\
+		regs->r1 = 0; regs->r2 = 0; regs->r3 = 0;					\
+		regs->r13 = 0; regs->r14 = 0; regs->r15 = 0;					\
+		regs->r9  = 0; regs->r11 = 0;							\
+		regs->r16 = 0; regs->r17 = 0; regs->r18 = 0; regs->r19 = 0;			\
+		regs->r20 = 0; regs->r21 = 0; regs->r22 = 0; regs->r23 = 0;			\
+		regs->r24 = 0; regs->r25 = 0; regs->r26 = 0; regs->r27 = 0;			\
+		regs->r28 = 0; regs->r29 = 0; regs->r30 = 0; regs->r31 = 0;			\
+		regs->ar_ccv = 0;								\
+		regs->b0 = 0; regs->b7 = 0;							\
+		regs->f6.u.bits[0] = 0; regs->f6.u.bits[1] = 0;					\
+		regs->f7.u.bits[0] = 0; regs->f7.u.bits[1] = 0;					\
+		regs->f8.u.bits[0] = 0; regs->f8.u.bits[1] = 0;					\
+		regs->f9.u.bits[0] = 0; regs->f9.u.bits[1] = 0;					\
+	}											\
 } while (0)
 
 /* Forward declarations, a strange C thing... */
@@ -368,7 +419,11 @@
  * parent of DEAD_TASK has collected the exist status of the task via
  * wait().  This is a no-op on IA-64.
  */
-#define release_thread(dead_task)
+#ifdef CONFIG_PERFMON
+  extern void release_thread (struct task_struct *task);
+#else
+# define release_thread(dead_task)
+#endif
 
 /*
  * This is the mechanism for creating a new kernel thread.
@@ -403,20 +458,51 @@
 /* Return stack pointer of blocked task TSK.  */
 #define KSTK_ESP(tsk)  ((tsk)->thread.ksp)
 
+static inline unsigned long
+ia64_get_kr (unsigned long regnum)
+{
+	unsigned long r;
+
+	switch (regnum) {
+	      case 0: asm volatile ("mov %0=ar.k0" : "=r"(r)); break;
+	      case 1: asm volatile ("mov %0=ar.k1" : "=r"(r)); break;
+	      case 2: asm volatile ("mov %0=ar.k2" : "=r"(r)); break;
+	      case 3: asm volatile ("mov %0=ar.k3" : "=r"(r)); break;
+	      case 4: asm volatile ("mov %0=ar.k4" : "=r"(r)); break;
+	      case 5: asm volatile ("mov %0=ar.k5" : "=r"(r)); break;
+	      case 6: asm volatile ("mov %0=ar.k6" : "=r"(r)); break;
+	      case 7: asm volatile ("mov %0=ar.k7" : "=r"(r)); break;
+	}
+	return r;
+}
+
+static inline void
+ia64_set_kr (unsigned long regnum, unsigned long r)
+{
+	switch (regnum) {
+	      case 0: asm volatile ("mov ar.k0=%0" :: "r"(r)); break;
+	      case 1: asm volatile ("mov ar.k1=%0" :: "r"(r)); break;
+	      case 2: asm volatile ("mov ar.k2=%0" :: "r"(r)); break;
+	      case 3: asm volatile ("mov ar.k3=%0" :: "r"(r)); break;
+	      case 4: asm volatile ("mov ar.k4=%0" :: "r"(r)); break;
+	      case 5: asm volatile ("mov ar.k5=%0" :: "r"(r)); break;
+	      case 6: asm volatile ("mov ar.k6=%0" :: "r"(r)); break;
+	      case 7: asm volatile ("mov ar.k7=%0" :: "r"(r)); break;
+	}
+}
+
 #ifndef CONFIG_SMP
 
 static inline struct task_struct *
 ia64_get_fpu_owner (void)
 {
-	struct task_struct *t;
-	__asm__ ("mov %0=ar.k5" : "=r"(t));
-	return t;
+	return (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER);
 }
 
 static inline void
 ia64_set_fpu_owner (struct task_struct *t)
 {
-	__asm__ __volatile__ ("mov ar.k5=%0" :: "r"(t));
+	ia64_set_kr(IA64_KR_FPU_OWNER, (unsigned long) t);
 }
 
 #endif /* !CONFIG_SMP */
@@ -437,8 +523,8 @@
 extern void ia64_load_pm_regs (struct task_struct *task);
 #endif
 
-#define ia64_fph_enable()	__asm__ __volatile__ (";; rsm psr.dfh;; srlz.d;;" ::: "memory");
-#define ia64_fph_disable()	__asm__ __volatile__ (";; ssm psr.dfh;; srlz.d;;" ::: "memory");
+#define ia64_fph_enable()	asm volatile (";; rsm psr.dfh;; srlz.d;;" ::: "memory");
+#define ia64_fph_disable()	asm volatile (";; ssm psr.dfh;; srlz.d;;" ::: "memory");
 
 /* load fp 0.0 into fph */
 static inline void
@@ -467,53 +553,53 @@
 static inline void
 ia64_fc (void *addr)
 {
-	__asm__ __volatile__ ("fc %0" :: "r"(addr) : "memory");
+	asm volatile ("fc %0" :: "r"(addr) : "memory");
 }
 
 static inline void
 ia64_sync_i (void)
 {
-	__asm__ __volatile__ (";; sync.i" ::: "memory");
+	asm volatile (";; sync.i" ::: "memory");
 }
 
 static inline void
 ia64_srlz_i (void)
 {
-	__asm__ __volatile__ (";; srlz.i ;;" ::: "memory");
+	asm volatile (";; srlz.i ;;" ::: "memory");
 }
 
 static inline void
 ia64_srlz_d (void)
 {
-	__asm__ __volatile__ (";; srlz.d" ::: "memory");
+	asm volatile (";; srlz.d" ::: "memory");
 }
 
 static inline __u64
 ia64_get_rr (__u64 reg_bits)
 {
 	__u64 r;
-	__asm__ __volatile__ ("mov %0=rr[%1]" : "=r"(r) : "r"(reg_bits) : "memory");
+	asm volatile ("mov %0=rr[%1]" : "=r"(r) : "r"(reg_bits) : "memory");
 	return r;
 }
 
 static inline void
 ia64_set_rr (__u64 reg_bits, __u64 rr_val)
 {
-	__asm__ __volatile__ ("mov rr[%0]=%1" :: "r"(reg_bits), "r"(rr_val) : "memory");
+	asm volatile ("mov rr[%0]=%1" :: "r"(reg_bits), "r"(rr_val) : "memory");
 }
 
 static inline __u64
 ia64_get_dcr (void)
 {
 	__u64 r;
-	__asm__ ("mov %0=cr.dcr" : "=r"(r));
+	asm volatile ("mov %0=cr.dcr" : "=r"(r));
 	return r;
 }
 
 static inline void
 ia64_set_dcr (__u64 val)
 {
-	__asm__ __volatile__ ("mov cr.dcr=%0;;" :: "r"(val) : "memory");
+	asm volatile ("mov cr.dcr=%0;;" :: "r"(val) : "memory");
 	ia64_srlz_d();
 }
 
@@ -521,14 +607,14 @@
 ia64_get_lid (void)
 {
 	__u64 r;
-	__asm__ ("mov %0=cr.lid" : "=r"(r));
+	asm volatile ("mov %0=cr.lid" : "=r"(r));
 	return r;
 }
 
 static inline void
 ia64_invala (void)
 {
-	__asm__ __volatile__ ("invala" ::: "memory");
+	asm volatile ("invala" ::: "memory");
 }
 
 /*
@@ -536,7 +622,7 @@
  * interrupt collection and interrupt enable bits.
  */
 #define ia64_clear_ic(flags)							\
-	__asm__ __volatile__ ("mov %0=psr;; rsm psr.i | psr.ic;; srlz.i;;"	\
+	asm volatile ("mov %0=psr;; rsm psr.i | psr.ic;; srlz.i;;"	\
 			      : "=r"(flags) :: "memory");
 
 /*
@@ -548,13 +634,13 @@
 	  __u64 vmaddr, __u64 pte,
 	  __u64 log_page_size)
 {
-	__asm__ __volatile__ ("mov cr.itir=%0" :: "r"(log_page_size << 2) : "memory");
-	__asm__ __volatile__ ("mov cr.ifa=%0;;" :: "r"(vmaddr) : "memory");
+	asm volatile ("mov cr.itir=%0" :: "r"(log_page_size << 2) : "memory");
+	asm volatile ("mov cr.ifa=%0;;" :: "r"(vmaddr) : "memory");
 	if (target_mask & 0x1)
-		__asm__ __volatile__ ("itr.i itr[%0]=%1"
+		asm volatile ("itr.i itr[%0]=%1"
 				      :: "r"(tr_num), "r"(pte) : "memory");
 	if (target_mask & 0x2)
-		__asm__ __volatile__ (";;itr.d dtr[%0]=%1"
+		asm volatile (";;itr.d dtr[%0]=%1"
 				      :: "r"(tr_num), "r"(pte) : "memory");
 }
 
@@ -566,13 +652,13 @@
 ia64_itc (__u64 target_mask, __u64 vmaddr, __u64 pte,
 	  __u64 log_page_size)
 {
-	__asm__ __volatile__ ("mov cr.itir=%0" :: "r"(log_page_size << 2) : "memory");
-	__asm__ __volatile__ ("mov cr.ifa=%0;;" :: "r"(vmaddr) : "memory");
+	asm volatile ("mov cr.itir=%0" :: "r"(log_page_size << 2) : "memory");
+	asm volatile ("mov cr.ifa=%0;;" :: "r"(vmaddr) : "memory");
 	/* as per EAS2.6, itc must be the last instruction in an instruction group */
 	if (target_mask & 0x1)
-		__asm__ __volatile__ ("itc.i %0;;" :: "r"(pte) : "memory");
+		asm volatile ("itc.i %0;;" :: "r"(pte) : "memory");
 	if (target_mask & 0x2)
-		__asm__ __volatile__ (";;itc.d %0;;" :: "r"(pte) : "memory");
+		asm volatile (";;itc.d %0;;" :: "r"(pte) : "memory");
 }
 
 /*
@@ -583,16 +669,16 @@
 ia64_ptr (__u64 target_mask, __u64 vmaddr, __u64 log_size)
 {
 	if (target_mask & 0x1)
-		__asm__ __volatile__ ("ptr.i %0,%1" :: "r"(vmaddr), "r"(log_size << 2));
+		asm volatile ("ptr.i %0,%1" :: "r"(vmaddr), "r"(log_size << 2));
 	if (target_mask & 0x2)
-		__asm__ __volatile__ ("ptr.d %0,%1" :: "r"(vmaddr), "r"(log_size << 2));
+		asm volatile ("ptr.d %0,%1" :: "r"(vmaddr), "r"(log_size << 2));
 }
 
 /* Set the interrupt vector address.  The address must be suitably aligned (32KB).  */
 static inline void
 ia64_set_iva (void *ivt_addr)
 {
-	__asm__ __volatile__ ("mov cr.iva=%0;; srlz.i;;" :: "r"(ivt_addr) : "memory");
+	asm volatile ("mov cr.iva=%0;; srlz.i;;" :: "r"(ivt_addr) : "memory");
 }
 
 /* Set the page table address and control bits.  */
@@ -600,7 +686,7 @@
 ia64_set_pta (__u64 pta)
 {
 	/* Note: srlz.i implies srlz.d */
-	__asm__ __volatile__ ("mov cr.pta=%0;; srlz.i;;" :: "r"(pta) : "memory");
+	asm volatile ("mov cr.pta=%0;; srlz.i;;" :: "r"(pta) : "memory");
 }
 
 static inline __u64
@@ -608,41 +694,33 @@
 {
 	__u64 r;
 
-	__asm__ ("mov %0=cpuid[%r1]" : "=r"(r) : "rO"(regnum));
+	asm ("mov %0=cpuid[%r1]" : "=r"(r) : "rO"(regnum));
 	return r;
 }
 
 static inline void
 ia64_eoi (void)
 {
-	__asm__ ("mov cr.eoi=r0;; srlz.d;;" ::: "memory");
+	asm ("mov cr.eoi=r0;; srlz.d;;" ::: "memory");
 }
 
 static inline void
-ia64_set_lrr0 (__u8 vector, __u8 masked)
+ia64_set_lrr0 (unsigned long val)
 {
-	if (masked > 1)
-		masked = 1;
-
-	__asm__ __volatile__ ("mov cr.lrr0=%0;; srlz.d"
-			      :: "r"((masked << 16) | vector) : "memory");
+	asm volatile ("mov cr.lrr0=%0;; srlz.d" :: "r"(val) : "memory");
 }
 
 
 static inline void
-ia64_set_lrr1 (__u8 vector, __u8 masked)
+ia64_set_lrr1 (unsigned long val)
 {
-	if (masked > 1)
-		masked = 1;
-
-	__asm__ __volatile__ ("mov cr.lrr1=%0;; srlz.d"
-			      :: "r"((masked << 16) | vector) : "memory");
+	asm volatile ("mov cr.lrr1=%0;; srlz.d" :: "r"(val) : "memory");
 }
 
 static inline void
 ia64_set_pmv (__u64 val)
 {
-	__asm__ __volatile__ ("mov cr.pmv=%0" :: "r"(val) : "memory");
+	asm volatile ("mov cr.pmv=%0" :: "r"(val) : "memory");
 }
 
 static inline __u64
@@ -650,14 +728,14 @@
 {
 	__u64 retval;
 
-	__asm__ __volatile__ ("mov %0=pmc[%1]" : "=r"(retval) : "r"(regnum));
+	asm volatile ("mov %0=pmc[%1]" : "=r"(retval) : "r"(regnum));
 	return retval;
 }
 
 static inline void
 ia64_set_pmc (__u64 regnum, __u64 value)
 {
-	__asm__ __volatile__ ("mov pmc[%0]=%1" :: "r"(regnum), "r"(value));
+	asm volatile ("mov pmc[%0]=%1" :: "r"(regnum), "r"(value));
 }
 
 static inline __u64
@@ -665,14 +743,14 @@
 {
 	__u64 retval;
 
-	__asm__ __volatile__ ("mov %0=pmd[%1]" : "=r"(retval) : "r"(regnum));
+	asm volatile ("mov %0=pmd[%1]" : "=r"(retval) : "r"(regnum));
 	return retval;
 }
 
 static inline void
 ia64_set_pmd (__u64 regnum, __u64 value)
 {
-	__asm__ __volatile__ ("mov pmd[%0]=%1" :: "r"(regnum), "r"(value));
+	asm volatile ("mov pmd[%0]=%1" :: "r"(regnum), "r"(value));
 }
 
 /*
@@ -722,7 +800,7 @@
  * Get the current instruction/program counter value.
  */
 #define current_text_addr() \
-	({ void *_pc; __asm__ ("mov %0=ip" : "=r" (_pc)); _pc; })
+	({ void *_pc; asm volatile ("mov %0=ip" : "=r" (_pc)); _pc; })
 
 #define THREAD_SIZE	IA64_STK_OFFSET
 /* NOTE: The task struct and the stacks are allocated together.  */
@@ -740,7 +818,7 @@
 static inline void
 ia64_set_cmcv (__u64 val)
 {
-	__asm__ __volatile__ ("mov cr.cmcv=%0" :: "r"(val) : "memory");
+	asm volatile ("mov cr.cmcv=%0" :: "r"(val) : "memory");
 }
 
 /*
@@ -751,7 +829,7 @@
 {
 	__u64 val;
 
-	__asm__ ("mov %0=cr.cmcv" : "=r"(val) :: "memory");
+	asm volatile ("mov %0=cr.cmcv" : "=r"(val) :: "memory");
 	return val;
 }
 
@@ -759,28 +837,28 @@
 ia64_get_ivr (void)
 {
 	__u64 r;
-	__asm__ __volatile__ ("srlz.d;; mov %0=cr.ivr;; srlz.d;;" : "=r"(r));
+	asm volatile ("srlz.d;; mov %0=cr.ivr;; srlz.d;;" : "=r"(r));
 	return r;
 }
 
 static inline void
 ia64_set_tpr (__u64 val)
 {
-	__asm__ __volatile__ ("mov cr.tpr=%0" :: "r"(val));
+	asm volatile ("mov cr.tpr=%0" :: "r"(val));
 }
 
 static inline __u64
 ia64_get_tpr (void)
 {
 	__u64 r;
-	__asm__ ("mov %0=cr.tpr" : "=r"(r));
+	asm volatile ("mov %0=cr.tpr" : "=r"(r));
 	return r;
 }
 
 static inline void
 ia64_set_irr0 (__u64 val)
 {
-	__asm__ __volatile__("mov cr.irr0=%0;;" :: "r"(val) : "memory");
+	asm volatile("mov cr.irr0=%0;;" :: "r"(val) : "memory");
 	ia64_srlz_d();
 }
 
@@ -790,14 +868,14 @@
 	__u64 val;
 
 	/* this is volatile because irr may change unbeknownst to gcc... */
-	__asm__ __volatile__("mov %0=cr.irr0" : "=r"(val));
+	asm volatile("mov %0=cr.irr0" : "=r"(val));
 	return val;
 }
 
 static inline void
 ia64_set_irr1 (__u64 val)
 {
-	__asm__ __volatile__("mov cr.irr1=%0;;" :: "r"(val) : "memory");
+	asm volatile("mov cr.irr1=%0;;" :: "r"(val) : "memory");
 	ia64_srlz_d();
 }
 
@@ -807,14 +885,14 @@
 	__u64 val;
 
 	/* this is volatile because irr may change unbeknownst to gcc... */
-	__asm__ __volatile__("mov %0=cr.irr1" : "=r"(val));
+	asm volatile("mov %0=cr.irr1" : "=r"(val));
 	return val;
 }
 
 static inline void
 ia64_set_irr2 (__u64 val)
 {
-	__asm__ __volatile__("mov cr.irr2=%0;;" :: "r"(val) : "memory");
+	asm volatile("mov cr.irr2=%0;;" :: "r"(val) : "memory");
 	ia64_srlz_d();
 }
 
@@ -824,14 +902,14 @@
 	__u64 val;
 
 	/* this is volatile because irr may change unbeknownst to gcc... */
-	__asm__ __volatile__("mov %0=cr.irr2" : "=r"(val));
+	asm volatile("mov %0=cr.irr2" : "=r"(val));
 	return val;
 }
 
 static inline void
 ia64_set_irr3 (__u64 val)
 {
-	__asm__ __volatile__("mov cr.irr3=%0;;" :: "r"(val) : "memory");
+	asm volatile("mov cr.irr3=%0;;" :: "r"(val) : "memory");
 	ia64_srlz_d();
 }
 
@@ -841,7 +919,7 @@
 	__u64 val;
 
 	/* this is volatile because irr may change unbeknownst to gcc... */
-	__asm__ __volatile__("mov %0=cr.irr3" : "=r"(val));
+	asm volatile ("mov %0=cr.irr3" : "=r"(val));
 	return val;
 }
 
@@ -850,7 +928,7 @@
 {
 	__u64 val;
 
-	__asm__ ("mov %0=gp" : "=r"(val));
+	asm ("mov %0=gp" : "=r"(val));
 	return val;
 }
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/ptrace.h linux/include/asm-ia64/ptrace.h
--- v2.4.3/linux/include/asm-ia64/ptrace.h	Thu Jan  4 12:50:18 2001
+++ linux/include/asm-ia64/ptrace.h	Thu Apr  5 12:51:47 2001
@@ -2,8 +2,8 @@
 #define _ASM_IA64_PTRACE_H
 
 /*
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1998, 1999 Stephane Eranian <eranian@hpl.hp.com>
  *
  * 12/07/98	S. Eranian	added pt_regs & switch_stack
@@ -67,7 +67,7 @@
 # define IA64_TASK_STRUCT_LOG_NUM_PAGES		0
 #endif
 
-#define IA64_RBS_OFFSET			((IA64_TASK_SIZE + 15) & ~15) 
+#define IA64_RBS_OFFSET			((IA64_TASK_SIZE + 15) & ~15)
 #define IA64_STK_OFFSET			((1 << IA64_TASK_STRUCT_LOG_NUM_PAGES)*PAGE_SIZE)
 
 #define INIT_TASK_SIZE			IA64_STK_OFFSET
@@ -96,11 +96,11 @@
 	unsigned long cr_iip;		/* interrupted task's instruction pointer */
 	unsigned long cr_ifs;		/* interrupted task's function state */
 
-	unsigned long ar_unat;		/* interrupted task's NaT register (preserved) */ 
+	unsigned long ar_unat;		/* interrupted task's NaT register (preserved) */
 	unsigned long ar_pfs;		/* prev function state  */
 	unsigned long ar_rsc;		/* RSE configuration */
 	/* The following two are valid only if cr_ipsr.cpl > 0: */
-	unsigned long ar_rnat;		/* RSE NaT */ 
+	unsigned long ar_rnat;		/* RSE NaT */
 	unsigned long ar_bspstore;	/* RSE bspstore */
 
 	unsigned long pr;		/* 64 predicate registers (1 bit each) */
@@ -160,7 +160,7 @@
  * "preserved" registers.
  */
 struct switch_stack {
-	unsigned long caller_unat;	/* user NaT collection register (preserved) */ 
+	unsigned long caller_unat;	/* user NaT collection register (preserved) */
 	unsigned long ar_fpsr;		/* floating-point status register */
 
 	struct ia64_fpreg f2;		/* preserved */
@@ -206,7 +206,7 @@
 	unsigned long ar_pfs;		/* previous function state */
 	unsigned long ar_lc;		/* loop counter (preserved) */
 	unsigned long ar_unat;		/* NaT bits for r4-r7 */
-	unsigned long ar_rnat;		/* RSE NaT collection register */ 
+	unsigned long ar_rnat;		/* RSE NaT collection register */
 	unsigned long ar_bspstore;	/* RSE dirty base (preserved) */
 	unsigned long pr;		/* 64 predicate registers (1 bit each) */
 };
@@ -220,22 +220,16 @@
   struct task_struct;			/* forward decl */
 
   extern void show_regs (struct pt_regs *);
-  extern long ia64_peek (struct pt_regs *, struct task_struct *, unsigned long addr, long *val);
-  extern long ia64_poke (struct pt_regs *, struct task_struct *, unsigned long addr, long val);
-  extern void ia64_flush_fph (struct task_struct *t);
-  extern void ia64_sync_fph (struct task_struct *t);
+  extern unsigned long ia64_get_user_bsp (struct task_struct *, struct pt_regs *);
+  extern long ia64_peek (struct task_struct *, unsigned long, unsigned long, long *);
+  extern long ia64_poke (struct task_struct *, unsigned long, unsigned long, long);
+  extern void ia64_flush_fph (struct task_struct *);
+  extern void ia64_sync_fph (struct task_struct *);
 
-#ifdef CONFIG_IA64_NEW_UNWIND
   /* get nat bits for scratch registers such that bit N==1 iff scratch register rN is a NaT */
   extern unsigned long ia64_get_scratch_nat_bits (struct pt_regs *pt, unsigned long scratch_unat);
   /* put nat bits for scratch registers such that scratch register rN is a NaT iff bit N==1 */
   extern unsigned long ia64_put_scratch_nat_bits (struct pt_regs *pt, unsigned long nat);
-#else
-  /* get nat bits for r1-r31 such that bit N==1 iff rN is a NaT */
-  extern long ia64_get_nat_bits (struct pt_regs *pt, struct switch_stack *sw);
-  /* put nat bits for r1-r31 such that rN is a NaT iff bit N==1 */
-  extern void ia64_put_nat_bits (struct pt_regs *pt, struct switch_stack *sw, unsigned long nat);
-#endif
 
   extern void ia64_increment_ip (struct pt_regs *pt);
   extern void ia64_decrement_ip (struct pt_regs *pt);
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sal.h linux/include/asm-ia64/sal.h
--- v2.4.3/linux/include/asm-ia64/sal.h	Thu Jan  4 12:50:18 2001
+++ linux/include/asm-ia64/sal.h	Thu Apr  5 12:51:47 2001
@@ -28,15 +28,12 @@
 #define __SAL_CALL(result,a0,a1,a2,a3,a4,a5,a6,a7)	\
 	result = (*ia64_sal)(a0,a1,a2,a3,a4,a5,a6,a7)
 
-#ifdef CONFIG_SMP
-# define SAL_CALL(result,args...) do {		\
-	  spin_lock(&sal_lock);			\
-	  __SAL_CALL(result,args);		\
-	  spin_unlock(&sal_lock);		\
+# define SAL_CALL(result,args...) do {			\
+	unsigned long flags;				\
+	spin_lock_irqsave(&sal_lock, flags);		\
+	__SAL_CALL(result,args);			\
+	spin_unlock_irqrestore(&sal_lock, flags);	\
 } while (0)
-#else
-# define SAL_CALL(result,args...)	__SAL_CALL(result,args)
-#endif
 
 #define SAL_SET_VECTORS			0x01000000
 #define SAL_GET_STATE_INFO		0x01000001
@@ -440,11 +437,10 @@
  * machine state at the time of MCA's, INITs or CMCs 
  */
 static inline s64
-ia64_sal_clear_state_info (u64 sal_info_type, u64 sal_info_sub_type)
+ia64_sal_clear_state_info (u64 sal_info_type)
 {
 	struct ia64_sal_retval isrv;
-	SAL_CALL(isrv, SAL_CLEAR_STATE_INFO, sal_info_type, sal_info_sub_type,
-	         0, 0, 0, 0, 0);
+	SAL_CALL(isrv, SAL_CLEAR_STATE_INFO, sal_info_type, 0, 0, 0, 0, 0, 0);
 	return isrv.status;
 }
 
@@ -453,10 +449,10 @@
  * state at the time of the MCAs, INITs or CMCs.
  */
 static inline u64
-ia64_sal_get_state_info (u64 sal_info_type, u64 sal_info_sub_type, u64 *sal_info)
+ia64_sal_get_state_info (u64 sal_info_type, u64 *sal_info)
 {
 	struct ia64_sal_retval isrv;
-	SAL_CALL(isrv, SAL_GET_STATE_INFO, sal_info_type, sal_info_sub_type,
+	SAL_CALL(isrv, SAL_GET_STATE_INFO, sal_info_type, 0,
 	         sal_info, 0, 0, 0, 0);
 	if (isrv.status)
 		return 0;
@@ -466,11 +462,10 @@
  * state at the time of MCAs, INITs or CMCs
  */
 static inline u64
-ia64_sal_get_state_info_size (u64 sal_info_type, u64 sal_info_sub_type)
+ia64_sal_get_state_info_size (u64 sal_info_type)
 {
 	struct ia64_sal_retval isrv;
-	SAL_CALL(isrv, SAL_GET_STATE_INFO_SIZE, sal_info_type, sal_info_sub_type,
-	         0, 0, 0, 0, 0);
+	SAL_CALL(isrv, SAL_GET_STATE_INFO_SIZE, sal_info_type, 0, 0, 0, 0, 0, 0);
 	if (isrv.status)
 		return 0;
 	return isrv.v0;
@@ -492,11 +487,10 @@
  * non-monarch processor at the end of machine check processing.
  */
 static inline s64
-ia64_sal_mc_set_params (u64 param_type, u64 i_or_m, u64 i_or_m_val, u64 timeout)
+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,
-	         0, 0, 0);
+	SAL_CALL(isrv, SAL_MC_SET_PARAMS, param_type, i_or_m, i_or_m_val, timeout, rz_always, 0, 0);
 	return isrv.status;
 }
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/segment.h linux/include/asm-ia64/segment.h
--- v2.4.3/linux/include/asm-ia64/segment.h	Sun Feb  6 18:42:40 2000
+++ linux/include/asm-ia64/segment.h	Thu Apr  5 12:51:47 2001
@@ -3,4 +3,4 @@
 
 /* Only here because we have some old header files that expect it.. */
 
-#endif /* __ALPHA_SEGMENT_H */
+#endif /* _ASM_IA64_SEGMENT_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/semaphore.h linux/include/asm-ia64/semaphore.h
--- v2.4.3/linux/include/asm-ia64/semaphore.h	Mon Oct  9 17:55:00 2000
+++ linux/include/asm-ia64/semaphore.h	Thu Apr  5 12:51:47 2001
@@ -116,7 +116,7 @@
 #endif
 	if (atomic_inc_return(&sem->count) <= 0)
 		__up(sem);
-}	
+}
 
 /*
  * rw mutexes (should that be mutices? =) -- throw rw spinlocks and
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sigcontext.h linux/include/asm-ia64/sigcontext.h
--- v2.4.3/linux/include/asm-ia64/sigcontext.h	Sun Feb  6 18:42:40 2000
+++ linux/include/asm-ia64/sigcontext.h	Thu Apr  5 12:51:47 2001
@@ -36,6 +36,7 @@
 	unsigned long		sc_ar_lc;	/* loop count register */
 	unsigned long		sc_pr;		/* predicate registers */
 	unsigned long		sc_br[8];	/* branch registers */
+	/* Note: sc_gr[0] is used as the "uc_link" member of ucontext_t */
 	unsigned long		sc_gr[32];	/* general registers (static partition) */
 	struct ia64_fpreg	sc_fr[128];	/* floating-point registers */
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/siginfo.h linux/include/asm-ia64/siginfo.h
--- v2.4.3/linux/include/asm-ia64/siginfo.h	Mon Oct  9 17:55:00 2000
+++ linux/include/asm-ia64/siginfo.h	Thu Apr  5 12:51:47 2001
@@ -2,8 +2,8 @@
 #define _ASM_IA64_SIGINFO_H
 
 /*
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <linux/types.h>
@@ -66,6 +66,12 @@
 			long _band;	/* POLL_IN, POLL_OUT, POLL_MSG (XPG requires a "long") */
 			int _fd;
 		} _sigpoll;
+		/* SIGPROF */
+		struct {
+			pid_t _pid;		/* which child */
+			uid_t _uid;		/* sender's uid */
+			unsigned long _pfm_ovfl_counters; /* which PMU counter overflowed */
+		} _sigprof;
 	} _sifields;
 } siginfo_t;
 
@@ -85,6 +91,7 @@
 #define si_isr		_sifields._sigfault._isr	/* valid if si_code==FPE_FLTxxx */
 #define si_band		_sifields._sigpoll._band
 #define si_fd		_sifields._sigpoll._fd
+#define si_pfm_ovfl	_sifields._sigprof._pfm_ovfl_counters
 
 /*
  * si_code values
@@ -98,6 +105,7 @@
 #define __SI_FAULT	(3 << 16)
 #define __SI_CHLD	(4 << 16)
 #define __SI_RT		(5 << 16)
+#define __SI_PROF	(6 << 16)
 #define __SI_CODE(T,N)	((T) << 16 | ((N) & 0xffff))
 #else
 #define __SI_KILL	0
@@ -201,12 +209,16 @@
 #define NSIGPOLL	6
 
 /*
+ * SIGPROF si_codes
+ */
+#define PROF_OVFL	(__SI_PROF|1)  /* some counters overflowed */
+
+/*
  * 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.
+ *
+ * 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 */
@@ -246,6 +258,7 @@
 }
 
 extern int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from);
+extern int copy_siginfo_from_user(siginfo_t *to, siginfo_t *from);
 
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/smp.h linux/include/asm-ia64/smp.h
--- v2.4.3/linux/include/asm-ia64/smp.h	Mon Oct  9 17:55:00 2000
+++ linux/include/asm-ia64/smp.h	Thu Apr  5 12:51:47 2001
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 1999 VA Linux Systems 
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
+ * Copyright (C) 2001 Hewlett-Packard Co
+ * Copyright (C) 2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #ifndef _ASM_IA64_SMP_H
 #define _ASM_IA64_SMP_H
@@ -15,13 +17,14 @@
 #include <linux/threads.h>
 #include <linux/kernel.h>
 
-#include <asm/ptrace.h>
 #include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
 
 #define XTP_OFFSET		0x1e0008
 
-#define SMP_IRQ_REDIRECTION     (1 << 0)
-#define SMP_IPI_REDIRECTION     (1 << 1)
+#define SMP_IRQ_REDIRECTION	(1 << 0)
+#define SMP_IPI_REDIRECTION	(1 << 1)
 
 #define smp_processor_id()	(current->processor)
 
@@ -30,15 +33,15 @@
 	int cpu_phys_id[NR_CPUS];
 } smp_boot_data __initdata;
 
+extern char no_int_routing __initdata;
+
 extern unsigned long cpu_present_map;
 extern unsigned long cpu_online_map;
 extern unsigned long ipi_base_addr;
-extern int bootstrap_processor;
-extern volatile int __cpu_physical_id[NR_CPUS];
+extern int __cpu_physical_id[NR_CPUS];
 extern unsigned char smp_int_redirect;
-extern char no_int_routing;
 extern int smp_num_cpus;
-  
+
 #define cpu_physical_id(i)	__cpu_physical_id[i]
 #define cpu_number_map(i)	(i)
 #define cpu_logical_map(i)	(i)
@@ -54,54 +57,55 @@
 {
 	int i;
 
-	for (i=0; i<smp_num_cpus; i++) {
-		if (cpu_physical_id(i) == cpuid)
+	for (i = 0; i < smp_num_cpus; ++i)
+		if (cpu_physical_id(i) == (__u32) cpuid)
 			break;
-	}
 	return i;
 }
 
 /*
  * XTP control functions:
- *    min_xtp   :  route all interrupts to this CPU
- *    normal_xtp:  nominal XTP value
- *    max_xtp   :  never deliver interrupts to this CPU.
+ *	min_xtp   : route all interrupts to this CPU
+ *	normal_xtp: nominal XTP value
+ *	max_xtp   : never deliver interrupts to this CPU.
  */
 
 static inline void 
-min_xtp(void)
+min_xtp (void)
 {
 	if (smp_int_redirect & SMP_IRQ_REDIRECTION)
 		writeb(0x00, ipi_base_addr | XTP_OFFSET); /* XTP to min */
 }
 
 static inline void
-normal_xtp(void)
+normal_xtp (void)
 {
 	if (smp_int_redirect & SMP_IRQ_REDIRECTION)
 		writeb(0x08, ipi_base_addr | XTP_OFFSET); /* XTP normal */
 }
 
 static inline void
-max_xtp(void) 
+max_xtp (void) 
 {
 	if (smp_int_redirect & SMP_IRQ_REDIRECTION)
 		writeb(0x0f, ipi_base_addr | XTP_OFFSET); /* Set XTP to max */
 }
 
 static inline unsigned int 
-hard_smp_processor_id(void)
+hard_smp_processor_id (void)
 {
-	struct {
-		unsigned long reserved : 16;
-		unsigned long eid : 8;
-		unsigned long id  : 8;
-		unsigned long ignored : 32;
+	union {
+		struct {
+			unsigned long reserved : 16;
+			unsigned long eid : 8;
+			unsigned long id : 8;
+			unsigned long ignored : 32;
+		} f;
+		unsigned long bits;
 	} lid;
 
-	__asm__ ("mov %0=cr.lid" : "=r" (lid));
-
-	return lid.id << 8 | lid.eid;
+	lid.bits = ia64_get_lid();
+	return lid.f.id << 8 | lid.f.eid;
 }
 
 #define NO_PROC_ID		(-1)
@@ -111,7 +115,7 @@
 extern void smp_do_timer (struct pt_regs *regs);
 
 extern int smp_call_function_single (int cpuid, void (*func) (void *info), void *info,
-			      int retry, int wait);
+				     int retry, int wait);
 
 
 #endif /* CONFIG_SMP */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/smplock.h linux/include/asm-ia64/smplock.h
--- v2.4.3/linux/include/asm-ia64/smplock.h	Thu Mar 23 12:50:09 2000
+++ linux/include/asm-ia64/smplock.h	Thu Apr  5 12:51:47 2001
@@ -3,10 +3,12 @@
  *
  * Default SMP lock implementation
  */
-#include <linux/sched.h>
 #include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
 
-#include <asm/spinlock.h>
+#include <asm/current.h>
+#include <asm/hardirq.h>
 
 extern spinlock_t kernel_flag;
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/addrs.h linux/include/asm-ia64/sn/addrs.h
--- v2.4.3/linux/include/asm-ia64/sn/addrs.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/addrs.h	Thu Apr  5 12:51:47 2001
@@ -11,6 +11,7 @@
 #define _ASM_SN_ADDRS_H
 
 #include <linux/config.h>
+
 #if _LANGUAGE_C
 #include <linux/types.h>
 #endif /* _LANGUAGE_C */
@@ -21,22 +22,15 @@
 #include <asm/sn/kldir.h>
 #endif	/* CONFIG_IA64_SGI_SN1 */
 
-#if defined(CONFIG_IA64_SGI_IO)
 #if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 #include <asm/sn/sn1/addrs.h>
 #endif
-#endif	/* CONFIG_IA64_SGI_IO */
 
 
 #if _LANGUAGE_C
 
-#if defined(CONFIG_IA64_SGI_IO)	/* FIXME */
 #define PS_UINT_CAST		(__psunsigned_t)
 #define UINT64_CAST		(uint64_t)
-#else	/* CONFIG_IA64_SGI_IO */
-#define PS_UINT_CAST		(unsigned long)
-#define UINT64_CAST		(unsigned long)
-#endif	/* CONFIG_IA64_SGI_IO */
 
 #define HUBREG_CAST		(volatile hubreg_t *)
 
@@ -138,6 +132,8 @@
 
 #define UALIAS_BASE		HSPEC_BASE
 #define UALIAS_SIZE		0x10000000	/* 256 Megabytes */
+#define CPU_UALIAS		0x20000		/* 128 Kilobytes */
+#define UALIAS_CPU_SIZE		(CPU_UALIAS / CPUS_PER_NODE)
 #define UALIAS_LIMIT		(UALIAS_BASE + UALIAS_SIZE)
 
 /*
@@ -408,24 +404,19 @@
 #define PHYS_RAMBASE		0x0
 #define K0_RAMBASE		PHYS_TO_K0(PHYS_RAMBASE)
 
-#define EX_HANDLER_OFFSET(slice) ((slice) << 16)
-#define EX_HANDLER_ADDR(nasid, slice)					\
-	PHYS_TO_K0(NODE_OFFSET(nasid) | EX_HANDLER_OFFSET(slice))
-#define EX_HANDLER_SIZE		0x0400
-
-#define EX_FRAME_OFFSET(slice)	((slice) << 16 | 0x400)
-#define EX_FRAME_ADDR(nasid, slice)					\
-	PHYS_TO_K0(NODE_OFFSET(nasid) | EX_FRAME_OFFSET(slice))
-#define EX_FRAME_SIZE		0x0c00
-
 #define ARCS_SPB_OFFSET		0x1000
 #define ARCS_SPB_ADDR(nasid)						\
 	PHYS_TO_K0(NODE_OFFSET(nasid) | ARCS_SPB_OFFSET)
 #define ARCS_SPB_SIZE		0x0400
 
 #define KLDIR_OFFSET		0x2000
+#ifndef __ia64
 #define KLDIR_ADDR(nasid)						\
 	TO_NODE_UNCAC((nasid), KLDIR_OFFSET)
+#else
+#define KLDIR_ADDR(nasid)                                               \
+        TO_NODE_CAC((nasid), KLDIR_OFFSET)
+#endif
 #define KLDIR_SIZE		0x0400
 
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/agent.h linux/include/asm-ia64/sn/agent.h
--- v2.4.3/linux/include/asm-ia64/sn/agent.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/agent.h	Thu Apr  5 12:51:47 2001
@@ -13,6 +13,7 @@
 #define _ASM_SGI_SN_AGENT_H
 
 #include <linux/config.h>
+
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 //#include <asm/sn/io.h>
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/arc/hinv.h linux/include/asm-ia64/sn/arc/hinv.h
--- v2.4.3/linux/include/asm-ia64/sn/arc/hinv.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/arc/hinv.h	Thu Apr  5 12:51:47 2001
@@ -89,7 +89,7 @@
 	PCIAdapter,
 	GIOAdapter,
 	TPUAdapter,
-
+	TernaryCache,
 	Anonymous
 } CONFIGTYPE;
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/arc/types.h linux/include/asm-ia64/sn/arc/types.h
--- v2.4.3/linux/include/asm-ia64/sn/arc/types.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/arc/types.h	Thu Apr  5 12:51:47 2001
@@ -9,6 +9,8 @@
 #ifndef _ASM_SN_ARC_TYPES_H
 #define _ASM_SN_ARC_TYPES_H
 
+#include <linux/config.h>
+
 typedef char		CHAR;
 typedef short		SHORT;
 typedef long		LARGE_INTEGER __attribute__ ((__mode__ (__DI__)));
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/arch.h linux/include/asm-ia64/sn/arch.h
--- v2.4.3/linux/include/asm-ia64/sn/arch.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/arch.h	Thu Apr  5 12:51:47 2001
@@ -15,12 +15,10 @@
 #include <linux/types.h>
 #include <linux/config.h>
 
-#if defined(CONFIG_IA64_SGI_IO)
 #include <asm/sn/types.h>
 #if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_SGI_IP37) || defined(CONFIG_IA64_GENERIC)
 #include <asm/sn/sn1/arch.h>
 #endif
-#endif	/* CONFIG_IA64_SGI_IO */
 
 
 #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
@@ -68,7 +66,7 @@
  *	cputolocalslice - returns a number 0..1 that identifies the local slice of
  *			the cpu within it's PI interface.
  */
-#ifdef notyet
+#ifdef LATER
 	/* These are dummied up for now ..... */
 #define cputocnode(cpu)				\
                (pdaindr[(cpu)].p_nodeid)
@@ -86,7 +84,7 @@
 #define cputoslice(cpu) 0
 #define cputolocalslice(cpu) 0
 #define cputosubnode(cpu) 0
-#endif	/* notyet */
+#endif	/* LATER */
 #endif	/* CONFIG_SGI_IP35 */
 
 #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
@@ -131,6 +129,7 @@
     ((nnode) >> \
      (is_fine_dirmode() ? NASID_TO_FINEREG_SHFT : NASID_TO_COARSEREG_SHFT))
 
+#ifndef __ia64
 extern cnodeid_t nasid_to_compact_node[MAX_NASIDS];
 extern nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
 extern cnodeid_t cpuid_to_compact_node[MAXCPUS];
@@ -153,6 +152,17 @@
 #define COMPACT_TO_NASID_NODEID(cnode)	compact_to_nasid_nodeid(cnode)
 #define CPUID_TO_COMPACT_NODEID(cpu)	(cpuid_to_compact_node[(cpu)])
 #endif
+
+#else
+
+/*
+ * IA64 specific nasid and cnode ids.
+ */
+#define NASID_TO_COMPACT_NODEID(nasid)  (nasid_to_cnodeid(nasid))
+#define COMPACT_TO_NASID_NODEID(cnode)  (cnodeid_to_nasid(cnode))
+#define CPUID_TO_COMPACT_NODEID(cpu)    (cpuid_to_cnodeid(cpu))
+
+#endif /* #ifndef __ia64 */
 
 extern int node_getlastslot(cnodeid_t);
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/cdl.h linux/include/asm-ia64/sn/cdl.h
--- v2.4.3/linux/include/asm-ia64/sn/cdl.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/cdl.h	Thu Apr  5 12:51:47 2001
@@ -30,6 +30,15 @@
 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
@@ -73,8 +82,10 @@
  *
  *	Calls the driver's attach routine with all
  *	connection points on the list that have the same
- *	key information as the driver; then places the
- *	driver on the list so that any connection points
+ *	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.
@@ -86,14 +97,17 @@
 				       int key1,
 				       int key2,
 				       char *prefix,
-				       int flags);
+				       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; then forgets about the driver. Future
+ *	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.
@@ -107,7 +121,8 @@
  *	was successful.
  */
 extern void		cdl_del_driver(cdl_p reg, 
-				       char *prefix);
+				       char *prefix,
+				       cdl_drv_f *func);
 
 /*
  *	cdl_add_connpt: add a connection point
@@ -124,7 +139,8 @@
 extern int		cdl_add_connpt(cdl_p reg,
 				       int key1,
 				       int key2,
-				       devfs_handle_t conn);
+				       devfs_handle_t conn,
+				       int drv_flags);
 
 /*
  *	cdl_del_connpt: delete a connection point
@@ -138,10 +154,11 @@
  *	NOTE: Same caveat here about the detach calls as
  *	in the cdl_del_driver() comment above.
  */
-extern void		cdl_del_connpt(cdl_p reg,
+extern int		cdl_del_connpt(cdl_p reg,
 				       int key1,
 				       int key2,
-				       devfs_handle_t conn);
+				       devfs_handle_t conn,
+				       int drv_flags);
 
 /*
  *	cdl_iterate: find all verticies in the registry
@@ -162,7 +179,7 @@
  */
 
 struct async_attach_s {
-	sema_t async_sema;
+	struct semaphore async_sema;
 	int    async_count;
 };
 typedef struct async_attach_s *async_attach_t;
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/cmn_err.h linux/include/asm-ia64/sn/cmn_err.h
--- v2.4.3/linux/include/asm-ia64/sn/cmn_err.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/cmn_err.h	Wed Dec 31 16:00:00 1969
@@ -1,120 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-#ifndef _ASM_SN_CMN_ERR_H
-#define _ASM_SN_CMN_ERR_H
-
-/*
-** Common error handling severity levels.  Converted to be
-** represented by the associated 4.3BSD syslog priorities.
-*/
-
-#define CE_DEBUG	KERN_DEBUG	/* debug	*/
-#define CE_CONT		KERN_INFO	/* continuation	*/
-#define CE_NOTE		KERN_NOTICE	/* notice	*/
-#define CE_WARN		KERN_WARNING	/* warning	*/
-#define CE_ALERT	KERN_ALERT	/* alert	*/
-#define CE_PANIC	KERN_EMERG	/* panic	*/
-
-#define	CE_LEVELMASK	LOG_PRIMASK	/* mask for severity level	*/
-#define	CE_CPUID	0x8		/* prepend CPU id to output	*/
-#define CE_PHYSID	0x10		/* prepend CPU phys location    */
-#define CE_SYNC		0x20		/* wait for uart to drain before returning */
-
-/* Flags for Availmon Monitoring
- * When a developer or's these bits into the cmn_err flags above,
- * and they have availmon installed, certain "actions" will take
- * place depending upon how they have the availmon software configured.
- */
-#define CE_TOOKACTIONS   0x0100            /* Actions taken by some error   */
-#define CE_RUNNINGPOOR   0x0200            /* System running degraded       */
-#define CE_MAINTENANCE   0x0400            /* System needs maintenance      */
-#define CE_CONFIGERROR   0x0800            /* System configured incorrectly */
-
-/* Bitmasks for separating subtasks from priority levels */
-#define CE_PRIOLEVELMASK 0x00ff  /* bitmask for severity levels of cmn_err */
-#define CE_SUBTASKMASK   0xff00  /* bitmask for availmon actions of cmn_err */
-#define CE_AVAILMONALL   (CE_TOOKACTIONS|CE_RUNNINGPOOR| \
-                                 CE_MAINTENANCE|CE_CONFIGERROR)
-
-#ifdef __KERNEL__
-
-#define CE_PBPANIC	KERN_CRIT	/* Special define used to manipulate
-					 * putbufndx in kernel */
-
-/* Console output flushing flag and routine */
-
-extern int constrlen;		/* Length of current console string, if zero,
-				   there are no characters to flush */
-#define	CONBUF_LOCKED	0	/* conbuf is already locked */
-#define	CONBUF_UNLOCKED	1	/* need to reacquire lock */
-#define CONBUF_DRAIN	2	/* ensure output before returning */
-
-/*
- * bit field descriptions for printf %r and %R formats
- *
- * printf("%r %R", val, reg_descp);
- * struct reg_desc *reg_descp;
- *
- * the %r and %R formats allow formatted print of bit fields.  individual
- * bit fields are described by a struct reg_desc, multiple bit fields within
- * a single word can be described by multiple reg_desc structures.
- * %r outputs a string of the format "<bit field descriptions>"
- * %R outputs a string of the format "0x%x<bit field descriptions>"
- *
- * The fields in a reg_desc are:
- *	__psunsigned_t rd_mask;	An appropriate mask to isolate the bit field
- *				within a word, and'ed with val
- *
- *	int rd_shift;		A shift amount to be done to the isolated
- *				bit field.  done before printing the isolate
- *				bit field with rd_format and before searching
- *				for symbolic value names in rd_values
- *
- *	char *rd_name;		If non-null, a bit field name to label any
- *				out from rd_format or searching rd_values.
- *				if neither rd_format or rd_values is non-null
- *				rd_name is printed only if the isolated
- *				bit field is non-null.
- *
- *	char *rd_format;	If non-null, the shifted bit field value
- *				is printed using this format.
- *
- *	struct reg_values *rd_values;	If non-null, a pointer to a table
- *				matching numeric values with symbolic names.
- *				rd_values are searched and the symbolic
- *				value is printed if a match is found, if no
- *				match is found "???" is printed.
- *				
- */
-
-
-/*
- * register values
- * map between numeric values and symbolic values
- */
-struct reg_values {
-	__psunsigned_t rv_value;
-	char *rv_name;
-};
-
-/*
- * register descriptors are used for formatted prints of register values
- * rd_mask and rd_shift must be defined, other entries may be null
- */
-struct reg_desc {
-	k_machreg_t rd_mask;	/* mask to extract field */
-	int rd_shift;		/* shift for extracted value, - >>, + << */
-	char *rd_name;		/* field name */
-	char *rd_format;	/* format to print field */
-	struct reg_values *rd_values;	/* symbolic names of values */
-};
-
-#endif	/* __KERNEL__ */
-#endif	/* _ASM_SN_CMN_ERR_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/dmamap.h linux/include/asm-ia64/sn/dmamap.h
--- v2.4.3/linux/include/asm-ia64/sn/dmamap.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/dmamap.h	Thu Apr  5 12:51:47 2001
@@ -10,6 +10,8 @@
 #ifndef _ASM_SN_DMAMAP_H
 #define _ASM_SN_DMAMAP_H
 
+#include <asm/sn/sv.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -53,7 +55,7 @@
 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 IRIX
+#ifdef LATER
 extern int	dma_mapbp(dmamap_t *, buf_t *, int);
 #endif
 extern int	dma_map_alenlist(dmamap_t *, struct alenlist_s *, size_t);
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/eeprom.h linux/include/asm-ia64/sn/eeprom.h
--- v2.4.3/linux/include/asm-ia64/sn/eeprom.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/eeprom.h	Thu Apr  5 12:51:47 2001
@@ -349,7 +349,7 @@
  * is ignored.
  */
 
-#ifdef IRIX
+#ifdef LATER
 char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v,
 			      net_vec_t path );
 #endif
@@ -363,7 +363,7 @@
  * if the part and mfg numbers stored there indicate that this widget
  * is an XBridge (and so must be part of a brick).
  */
-#ifdef IRIX
+#ifdef LATER
 int is_iobrick( int nasid, int widget_num );
 #endif
 
@@ -371,11 +371,7 @@
  * address passed to it and uses is_iobrick to determine whether
  * the widget in question is part of an SN1 IO brick.
  */
-#ifdef IRIX
 #define IS_IOBRICK(rg)	is_iobrick( NASID_GET((rg)), SWIN_WIDGETNUM((rg)) )
-#else
-#define IS_IOBRICK(rg)	1
-#endif
 
 
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/gda.h linux/include/asm-ia64/sn/gda.h
--- v2.4.3/linux/include/asm-ia64/sn/gda.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/gda.h	Thu Apr  5 12:51:47 2001
@@ -61,7 +61,7 @@
 				/* 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]; /* NASID of each node,
+	nasid_t	g_nasidtable[MAX_COMPACT_NODES+1]; /* NASID of each node,
 						  * indexed by cnodeid.
 						  */
 } gda_t;
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/hack.h linux/include/asm-ia64/sn/hack.h
--- v2.4.3/linux/include/asm-ia64/sn/hack.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/hack.h	Thu Apr  5 12:51:47 2001
@@ -22,6 +22,10 @@
 typedef int cred_t;	/* This is for compilation reasons */
 struct cred { int x; };
 
+
+#define mrlock(_s, _t, _u)
+#define mrunlock(_s)
+
 /*
  * Hardware Graph routines that are currently stubbed!
  */
@@ -34,50 +38,26 @@
  * 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) printk("FIXME: [ %s ] in %s at %s:%d\n", s, __FUNCTION__, __FILE__, __LINE__) */
 
-#define sv_init(a,b,c)          FIXME("Fixme: sv_init : no-op")
-#define sv_wait(a,b,c,d)        FIXME("Fixme: sv_wait : no-op")
-#define sv_broadcast(a)  	FIXME("Fixme: sv_broadcast : no-op")
-#define sv_destroy(a)		FIXME("Fixme: sv_destroy : no-op")
+#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"); }
-static inline int sv_signal(sv_t *a) {FIXME("sv_signal : return 0"); return (0); }
-
-#define cmn_err(x,y...)         { FIXME("cmn_err : use printk"); printk(x y); }
 
 typedef int (*splfunc_t)(void);
-extern int badaddr_val(volatile void *, int , volatile void *);
-
-extern int cap_able_cred(uint64_t a, uint64_t b);
-
-#define _CAP_CRABLE(cr,c)	(cap_able_cred(cr,c))
-#define CAP_MEMORY_MGT          (0x01LL << 25)
-#define CAP_DEVICE_MGT          (0x01LL << 37)
-
-#define io_splock(l) l
-#define io_spunlock(l,s)
 
 /* move to stubs.c yet */
-#define spinlock_destroy(a)     /* needed by pcibr_detach() */
-#define mutex_spinlock(a) 0
-#define mutex_spinunlock(a,b)
-#define mutex_spinlock_spl(x,y) y
-#define mutex_init(a,b,c)               ;
-#define mutex_lock(a,b)                 ;
-#define mutex_unlock(a)                 ;
 #define dev_to_vhdl(dev) 0
 #define get_timestamp() 0
 #define us_delay(a)
-#define v_mapphys(a,b,c) printk("Fixme: v_mapphys - soft->base 0x%p\n", b);
+#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)
-#define spinlock_init(x,name) mutex_init(x, MUTEX_DEFAULT, name);
 
 extern void * kmem_alloc_node(register size_t, register int, cnodeid_t);
 extern void * kmem_zalloc(size_t, int);
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/hcl.h linux/include/asm-ia64/sn/hcl.h
--- v2.4.3/linux/include/asm-ia64/sn/hcl.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/hcl.h	Thu Apr  5 12:51:47 2001
@@ -13,6 +13,7 @@
 extern spinlock_t hcl_spinlock;
 extern devfs_handle_t hcl_handle; /* HCL driver */
 extern devfs_handle_t hwgraph_root;
+extern devfs_handle_t linux_busnum;
 
 
 typedef long            labelcl_info_place_t;
@@ -22,7 +23,6 @@
 /* Support for INVENTORY */
 struct inventory_s;
 struct invplace_s;
-extern struct invplace_s invplace_none;
 
 
 /* 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/hwcntrs.h linux/include/asm-ia64/sn/hwcntrs.h
--- v2.4.3/linux/include/asm-ia64/sn/hwcntrs.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/hwcntrs.h	Thu Apr  5 12:51:47 2001
@@ -73,7 +73,6 @@
 } rcb_slot_t;
 
 #if defined(__KERNEL__)
-// #include <sys/immu.h>
 typedef struct sn0_refcnt_args_32 {
 	uint64_t    vaddr;
 	uint64_t    len;
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/intr.h linux/include/asm-ia64/sn/intr.h
--- v2.4.3/linux/include/asm-ia64/sn/intr.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/intr.h	Thu Apr  5 12:51:47 2001
@@ -10,6 +10,9 @@
 #ifndef _ASM_SN_INTR_H
 #define _ASM_SN_INTR_H
 
+/* Subnode wildcard */
+#define SUBNODE_ANY		-1
+
 /* Number of interrupt levels associated with each interrupt register. */
 #define N_INTPEND_BITS		64
 
@@ -24,8 +27,6 @@
 
 #if LANGUAGE_C
 
-#if defined(CONFIG_IA64_SGI_IO)
-
 #define II_NAMELEN	24
 
 /*
@@ -36,7 +37,7 @@
 	intr_func_t	iv_func;	/* Interrupt handler function */
 	intr_func_t	iv_prefunc;	/* Interrupt handler prologue func */
 	void		*iv_arg;	/* Argument to pass to handler */
-#ifdef IRIX
+#ifdef LATER
 	thd_int_t		iv_tinfo;	/* Thread info */
 #endif
 	cpuid_t			iv_mustruncpu;	/* Where we must run. */
@@ -93,7 +94,7 @@
 						     call an intr routine. */
 	intr_info_t	info[N_INTPEND_BITS];	  /* information needed only
 						     to maintain interrupts. */
-	lock_t		vector_lock;		  /* Lock for this and the
+	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.
@@ -122,15 +123,12 @@
 #define hub_intrinfo0	private.p_intmasks.dispatch0->info
 #define hub_intrinfo1	private.p_intmasks.dispatch1->info
 
-#endif	/* CONFIG_IA64_SGI_IO */
-
 /*
  * 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)))
-#if defined(CONFIG_IA64_SGI_IO)
 #define REMOTE_HUB_PI_SEND_INTR(_hub, _sn, _level) \
 		REMOTE_HUB_PI_S((_hub), _sn, PI_INT_PEND_MOD, (0x100|(_level)))
 
@@ -138,7 +136,6 @@
 		REMOTE_HUB_PI_S(cputonasid(_cpuid),				\
 			SUBNODE(cputoslice(_cpuid)),				\
 			PI_INT_PEND_MOD, (0x100|(_level)))
-#endif	/* CONFIG_IA64_SGI_IO*/
 
 /*
  * When clearing the interrupt, make sure this clear does make it 
@@ -153,7 +150,6 @@
 		REMOTE_HUB_PI_S((_hub), (_sn), PI_INT_PEND_MOD, (_level)),	\
                 REMOTE_HUB_PI_L((_hub), (_sn), PI_INT_PEND0)
 
-#if defined(CONFIG_IA64_SGI_IO)
 /* 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);
 
@@ -164,7 +160,6 @@
  */
 extern void intr_block_bit(cpuid_t cpu, int bit);
 extern void intr_unblock_bit(cpuid_t cpu, int bit);
-#endif	/* CONFIG_IA64_SGI_IO */
 
 #endif /* LANGUAGE_C */
 
@@ -246,6 +241,13 @@
 # define IO_ERROR_INTR	38	/* set up by prom */
 # define DEBUG_INTR_B	37	/* used by symmon to stop all cpus */
 # define DEBUG_INTR_A	36
+#endif
+
+#ifdef CONFIG_IA64_SGI_SN1
+// These aren't strictly accurate or complete.  See the
+// Synergy Spec. for details.
+#define SGI_UART_IRQ	(65)
+#define SGI_HUB_ERROR_IRQ	(182)
 #endif
 
 #endif /* _ASM_SN_INTR_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/intr_public.h linux/include/asm-ia64/sn/intr_public.h
--- v2.4.3/linux/include/asm-ia64/sn/intr_public.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/intr_public.h	Thu Apr  5 12:51:47 2001
@@ -7,9 +7,10 @@
  * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
  * Copyright (C) 2000 by Colin Ngam
  */
-#ifndef __SYS_SN_INTR_PUBLIC_H__
-#define __SYS_SN_INTR_PUBLIC_H__
+#ifndef _ASM_SN_INTR_PUBLIC_H__
+#define _ASM_SN_INTR_PUBLIC_H__
 
+#include <linux/config.h>
 
 /* REMEMBER: If you change these, the whole world needs to be recompiled.
  * It would also require changing the hubspl.s code and SN0/intr.c
@@ -22,7 +23,6 @@
 #define INTPEND0_MAXMASK	(N_INTPEND0_MASKS - 1)
 #define INTPEND1_MAXMASK	(N_INTPEND1_MASKS - 1)
 
-#include <linux/config.h>
 #if _LANGUAGE_C
 #if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 #include <asm/sn/sn1/arch.h>
@@ -56,5 +56,4 @@
 } hub_intmasks_t;
 
 #endif /* _LANGUAGE_C */
-#endif /* __SYS_SN_INTR_PUBLIC_H__ */
-
+#endif /* _ASM_SN_INTR_PUBLIC_H__ */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/invent.h linux/include/asm-ia64/sn/invent.h
--- v2.4.3/linux/include/asm-ia64/sn/invent.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/invent.h	Thu Apr  5 12:51:47 2001
@@ -30,6 +30,10 @@
 #define app32_ptr_t unsigned long
 #define graph_vertex_place_t long
 #define GRAPH_VERTEX_NONE ((devfs_handle_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)
+
 
 typedef struct inventory_s {
 	struct	inventory_s *inv_next;	/* next inventory record in list */
@@ -105,6 +109,8 @@
 #define INV_RPS		23      /* redundant power source */
 #define INV_TPU		24	/* Tensor Processing Unit */
 #define INV_FCNODE	25	/* Helper class for SCSI classes, not in classes[] */
+#define INV_USB		26	/* Universal Serial Bus */
+#define INV_1394NODE    27      /* helper class for 1394/SPB2 classes, not in classes[] */
 
 /* types for class processor */
 #define INV_CPUBOARD	1
@@ -187,8 +193,11 @@
 #define INV_QL_12160    17      /* qlogic 12160 */
 #define INV_QL_2100	18	/* qLogic 2100 Fibrechannel */
 #define INV_QL_2200	19	/* qLogic 2200 Fibrechannel */
-#define INV_SBP2	20	/* SBP2 protocol over OHCI on 1394 */
-
+#define INV_PR_HIO_D	20	/* Prisa HIO Dual channel */
+#define INV_PR_PCI64_D	21	/* Prisa PCI-64 Dual channel */
+#define INV_QL_2200A	22	/* qLogic 2200A Fibrechannel */
+#define INV_SBP2        23      /* SBP2 protocol over OHCI on 1394 */
+#define INV_QL_2300	24	/* qLogic 2300 Fibrechannel */
 
 
 /* states for INV_SCSIDRIVE type of class disk */
@@ -215,6 +224,7 @@
 #define INV_SIDCACHE	8
 #define INV_MAIN_MB	9
 #define INV_HUBSPC      10      /* HUBSPC */
+#define INV_TIDCACHE	11
 
 /* types for class serial */
 #define INV_CDSIO	1	/* Central Data serial board */
@@ -405,6 +415,7 @@
 #define INV_NET_ISDN_PRI	8	/* PRI ISDN */
 #define INV_NET_HIPPIS		9	/* HIPPI-Serial */
 #define	INV_NET_GSN		10	/* GSN (aka HIPPI-6400) */
+#define INV_NET_MYRINET		11	/* Myricom PCI network */
 
 /* controllers for network types, unique within class network */
 #define INV_ETHER_EC	0	/* IP6 integral controller */
@@ -463,6 +474,7 @@
 #define INV_OPTICAL	7	/* optical disks (read-write) */
 #define INV_CHANGER	8	/* jukebox's for CDROMS, for example */
 #define INV_COMM	9	/* Communications device */
+#define INV_STARCTLR	12	/* Storage Array Controller */
 #define INV_RAIDCTLR	32	/* RAID ctlr actually gives type 0 */
 
 /* bit definitions for state field for class INV_SCSI */
@@ -495,6 +507,7 @@
 #define	INV_VIDEO_RACER		11	/* SpeedRacer Pro Video */
 #define	INV_VIDEO_EVO		12	/* EVO Personal Video */
 #define INV_VIDEO_XTHD		13	/* XIO XT-HDTV video */
+#define INV_VIDEO_XTDIGVID      14      /* XIO XT-HDDIGVID video */
 
 /* states for video class INV_VIDEO_EXPRESS */
 
@@ -568,10 +581,7 @@
 #define INV_7of9_PANEL          5       /* 7of9 flatpanel board and panel */
 
 /* types for class INV_IEEE1394 */
-#define INV_OHCI		0	/* Ohci IEEE1394 pci card */
-#define INV_RAWISO1394   	10	/* Raw Isochronous IEEE 1394 protocol driver */
-#define INV_RAWASYNC1394 	11	/* Raw Asynchronous IEEE 1394 protocol driver */
-#define INV_AVC1394     	12	/* Audio, Video & Control (AV/C) IEEE 1394 protocol driver */
+#define INV_OHCI	0	/* Ohci IEEE1394 pci card */
 
 /* state for class INV_IEEE1394 & type INV_OHCI */
 #define INV_IEEE1394_STATE_TI_REV_1 0
@@ -583,6 +593,51 @@
 #define	INV_TPU_EXT		0	/* External XIO Tensor Processing Unit */
 #define	INV_TPU_XIO		1	/* Internal XIO Tensor Processing Unit */
 
+/*
+ * USB Types.  The upper 8 bits contain general usb device class and are used to
+ * qualify the lower 8 bits which contain device type within a usb class.
+ * Use USB_INV_DEVCLASS and USB_INV_DEVTYPE to to decode an i_type, and
+ * USB_INV_TYPE to set it.
+ */
+
+#define USB_INV_DEVCLASS(invtype)	((invtype) >> 8)
+#define USB_INV_DEVTYPE(invtype)	((invtype) & 0xf)
+#define USB_INV_TYPE(usbclass, usbtype)	(((usbclass) << 8) | (usbtype))
+
+/*
+ * USB device classes.  These classes might not match the classes as defined
+ * by the usb spec, but where possible we will try.
+ */
+
+#define USB_INV_CLASS_RH	0x00	/* root hub (ie. controller) */
+#define USB_INV_CLASS_HID	0x03	/* human interface device */
+#define USB_INV_CLASS_HUB	0x09	/* hub device */
+
+/*
+ * USB device types within a class.  These will not match USB device types,
+ * as the usb is not consistent on how specific types are defined (sometimes
+ * they are found in the interface subclass, sometimes (as in HID devices) they
+ * are found within data generated by the device (hid report descriptors for
+ * example).
+ */
+
+/*
+ * RH types
+ */
+
+#define USB_INV_RH_OHCI		0x01	/* ohci root hub */
+
+/*
+ * HID types
+ */
+
+#define USB_INV_HID_KEYBOARD	0x01	/* kbd (HID class) */
+#define USB_INV_HID_MOUSE	0x02	/* mouse (HID class) */
+
+/*
+ * HUB types - none yet
+ */
+
 typedef struct invent_generic_s {
 	unsigned short	ig_module;
 	unsigned short	ig_slot;
@@ -618,6 +673,8 @@
 	cpu_inv_t     ic_cpu_info;
 	unsigned short	ic_cpuid;
 	unsigned short	ic_slice;
+	unsigned short  ic_cpumode;
+
 } invent_cpuinfo_t;
 
 typedef struct invent_rpsinfo {
@@ -659,9 +716,14 @@
 	inventory_t		*invplace_inv;		/* place in inv list on vertex */
 } invplace_t; /* Magic cookie placeholder in inventory list */
 
+extern invplace_t invplace_none;
+#define INVPLACE_NONE invplace_none
+
 extern void	    add_to_inventory(int, int, int, int, int);
 extern void	    replace_in_inventory(inventory_t *, int, int, int, int, int);
+extern void         start_scan_inventory(invplace_t *);
 extern inventory_t  *get_next_inventory(invplace_t *);
+extern void         end_scan_inventory(invplace_t *);
 extern inventory_t  *find_inventory(inventory_t *, int, int, int, int, int);
 extern int	    scaninvent(int (*)(inventory_t *, void *), void *);
 extern int	    get_sizeof_inventory(int);
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/io.h linux/include/asm-ia64/sn/io.h
--- v2.4.3/linux/include/asm-ia64/sn/io.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/io.h	Thu Apr  5 12:51:47 2001
@@ -12,20 +12,12 @@
 #define _ASM_SN_IO_H
 
 #include <linux/config.h>
+
 #if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 #include <asm/sn/sn1/addrs.h>
 #endif
 
-#define IO_SPACE_BASE IO_BASE
-
 /* Because we only have PCI I/O ports.  */
-#if !defined(CONFIG_IA64_SGI_IO)
-#define IO_SPACE_LIMIT 0xffffffff
-
-/* No isa_* versions, the Origin doesn't have ISA / EISA bridges.  */
-
-#else	/* CONFIG_IA64_SGI_IO */
-
 #define IIO_ITTE_BASE	0x400160	/* base of translation table entries */
 #define IIO_ITTE(bigwin)	(IIO_ITTE_BASE + 8*(bigwin))
 
@@ -71,7 +63,5 @@
 #if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 #include <asm/sn/sn1/hubio.h>
 #endif
-
-#endif	/* CONFIG_IA64_SGI_IO */
 
 #endif /* _ASM_SN_IO_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/ioerror.h linux/include/asm-ia64/sn/ioerror.h
--- v2.4.3/linux/include/asm-ia64/sn/ioerror.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/ioerror.h	Thu Apr  5 12:51:47 2001
@@ -10,6 +10,7 @@
 #ifndef _ASM_SN_IOERROR_H
 #define _ASM_SN_IOERROR_H
 
+#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
 
 /*
  * Macros defining the various Errors to be handled as part of
@@ -177,6 +178,7 @@
     MODE_DEVREENABLE		/* Reenable pass                */
 } ioerror_mode_t;
 
+#endif				/* C || C++ */
 
 typedef int             error_handler_f(void *, int, ioerror_mode_t, ioerror_t *);
 typedef void           *error_handler_arg_t;
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/ioerror_handling.h linux/include/asm-ia64/sn/ioerror_handling.h
--- v2.4.3/linux/include/asm-ia64/sn/ioerror_handling.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/ioerror_handling.h	Thu Apr  5 12:51:47 2001
@@ -12,7 +12,7 @@
 
 #include <linux/config.h>
 
-#ifdef __KERNEL__
+#if __KERNEL__
 
 /*
  * Basic types required for io error handling interfaces.
@@ -255,7 +255,7 @@
 	int		code = 0;		
 
 	/* Check if we have a valid hwgraph vertex */
-#ifdef IRIX
+#ifdef	LATER
 	if (!dev_is_vertex(v))
 		return(code);
 #endif
@@ -276,18 +276,6 @@
 	}								   
 	ASSERT(v_error_skip_env_get(v, error_env) == GRAPH_SUCCESS);
 	code = setjmp(*error_env);					   
-#ifdef IRIX
-	/* NOTE: It might be OK to leave the allocated jump buffer on the
-	 * vertex. This can be used for later purposes.
-	 */
-	if (code) {							   
-		/* This is the case where a long jump has been taken from one
-		 * one of the error handling interfaces.		     
-		 */							     
-		if (v_error_skip_env_clear(v, error_env) == GRAPH_SUCCESS)   
-			kfree(error_env);
-	}								     
-#endif
 	return(code);							     
 }
 #endif	/* CONFIG_SGI_IO_ERROR_HANDLING */
@@ -309,8 +297,6 @@
  * thru the calls the io error handling layer.
  */
 #if defined(CONFIG_SGI_IO_ERROR_HANDLING)
-#define IS_DEVICE_SHUTDOWN(_d) 	(error_state_get(_d) == ERROR_STATE_SHUTDOWN)
-#else
 extern boolean_t		is_device_shutdown(devfs_handle_t);
 #define IS_DEVICE_SHUTDOWN(_d) 	(is_device_shutdown(_d))
 #endif
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/iograph.h linux/include/asm-ia64/sn/iograph.h
--- v2.4.3/linux/include/asm-ia64/sn/iograph.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/iograph.h	Thu Apr  5 12:51:47 2001
@@ -90,6 +90,7 @@
 #define EDGE_LBL_PROM			"prom"
 #define EDGE_LBL_RACK			"rack"
 #define EDGE_LBL_RDISK			"rdisk"
+#define EDGE_LBL_REPEATER_ROUTER	"repeaterrouter"
 #define EDGE_LBL_ROUTER			"router"
 #define EDGE_LBL_RPOS			"bay"		/* Position in rack */
 #define EDGE_LBL_SCSI			"scsi"
@@ -117,9 +118,9 @@
 #define EDGE_LBL_RPS                    "rps"           /* redundant power supply */ 
 #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_IBRICK			"ibrick"
-#define EDGE_LBL_XBRICK			"xbrick"
+#define EDGE_LBL_PBRICK			"Pbrick"
+#define EDGE_LBL_IBRICK			"Ibrick"
+#define EDGE_LBL_XBRICK			"Xbrick"
 #define EDGE_LBL_CPUBUS			"cpubus"	/* CPU Interfaces (SysAd) */
 
 /* vertex info labels in hwgraph */
@@ -134,6 +135,8 @@
 #define INFO_LBL_DKIOTIME		"_dkiotime"
 #define INFO_LBL_DRIVER			"_driver"	/* points to attached device_driver_t */
 #define INFO_LBL_ELSC			"_elsc"
+#define	INFO_LBL_SUBCH			"_subch"	/* system controller subchannel */
+#define INFO_LBL_L1SCP			"_l1scp"	/* points to l1sc_t */
 #define INFO_LBL_FC_PORTNAME		"_fc_portname"
 #define INFO_LBL_GIOIO			"_gioio"
 #define INFO_LBL_GFUNCS			"_gioio_ops"	/* ops vector for gio providers */
@@ -196,5 +199,21 @@
 #if defined(__KERNEL__)
 void init_all_devices(void);
 #endif /* __KERNEL__ */
+
+#include <asm/sn/xtalk/xbow.h>	/* For get MAX_PORT_NUM */
+
+int io_brick_map_widget(char, int);
+int io_path_map_widget(devfs_handle_t);
+
+/*
+ * Map a brick's widget number to a meaningful int
+ */
+
+struct io_brick_map_s {
+    char                ibm_type;                  /* brick type, e.g. */
+                                                   /* 'I' for Ibrick   */
+    int                 ibm_map_wid[MAX_PORT_NUM]; /* wid to int map */
+};
+
 
 #endif /* _ASM_SN_IOGRAPH_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/klconfig.h linux/include/asm-ia64/sn/klconfig.h
--- v2.4.3/linux/include/asm-ia64/sn/klconfig.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/klconfig.h	Thu Apr  5 12:51:47 2001
@@ -12,6 +12,8 @@
 #ifndef	_ASM_SN_KLCONFIG_H
 #define	_ASM_SN_KLCONFIG_H
 
+#include <linux/config.h>
+
 /*
  * klconfig.h
  */
@@ -32,7 +34,6 @@
  *      that offsets of existing fields do not change.
  */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <asm/sn/types.h>
 #include <asm/sn/slotnum.h>
@@ -60,11 +61,10 @@
 #define SIZE_PAD		4096 /* 4k padding for structures */
 #if (defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)) && defined(BRINGUP) /* MAX_SLOTS_PER_NODE??? */
 /* 
- * 1 NODE brick, 2 Router bricks (1 local, 1 meta), 6 XIO Widgets, 
- * 1 Midplane (midplane will likely become IO brick when Bruce cleans
- * up IP35 klconfig)
+ * 1 NODE brick, 3 Router bricks (1 local, 1 meta, 1 repeater),
+ * 6 XIO Widgets, 1 Xbow, 1 gfx
  */
-#define MAX_SLOTS_PER_NODE	(1 + 2 + 6 + 1) 
+#define MAX_SLOTS_PER_NODE	(1 + 3 + 6 + 1 + 1) 
 #else
 /* 
  * 1 NODE brd, 2 Router brd (1 8p, 1 meta), 6 Widgets, 
@@ -88,7 +88,7 @@
 #define VISITED_BOARD		0x08	/* Used for compact hub numbering. */
 #define LOCAL_MASTER_IO6	0x10 	/* master io6 for that node */
 #define GLOBAL_MASTER_IO6	0x20
-#define THIRD_NIC_PRESENT 	0x40  	/* for future use */
+#define GLOBAL_MASTER_EXT 	0x40  	/* extend master io6 to other bus on ibrick */
 #define SECOND_NIC_PRESENT 	0x80 	/* addons like MIO are present */
 
 /* klinfo->flags fields */
@@ -119,15 +119,9 @@
 
 
 typedef struct console_s {
-#if defined(CONFIG_IA64_SGI_IO)	/* FIXME */
 	__psunsigned_t 	uart_base;
 	__psunsigned_t 	config_base;
 	__psunsigned_t 	memory_base;
-#else
-	unsigned long 	uart_base;
-	unsigned long 	config_base;
-	unsigned long 	memory_base;
-#endif
 	short		baud;
 	short		flag;
 	int		type;
@@ -164,18 +158,20 @@
 #define KL_CONFIG_INFO_SET_OFFSET(_nasid, _off)				\
         (KL_CONFIG_HDR(_nasid)->ch_board_info = (_off))
 
-#if !defined(SIMULATED_KLGRAPH)
+#ifndef __ia64
 #define KL_CONFIG_INFO(_nasid) 						\
         (lboard_t *)((KL_CONFIG_HDR(_nasid)->ch_board_info) ?		\
 	 NODE_OFFSET_TO_K0((_nasid), KL_CONFIG_HDR(_nasid)->ch_board_info) : \
 	 0)
 #else
-/*
- * For Fake klgraph info.
- */
-extern kl_config_hdr_t *linux_klcfg;
-#define KL_CONFIG_INFO(_nasid) (lboard_t *)((ulong)linux_klcfg->ch_board_info | 0xe000000000000000)
-#endif	/* CONFIG_IA64_SGI_IO */
+#define NODE_OFFSET_TO_LBOARD(nasid,off)        (lboard_t*)(NODE_CAC_BASE(nasid) + (off))
+
+#define KL_CONFIG_INFO(_nasid)                                          \
+	(lboard_t *)((KL_CONFIG_HDR(_nasid)->ch_board_info) ?           \
+	 NODE_OFFSET_TO_LBOARD((_nasid), KL_CONFIG_HDR(_nasid)->ch_board_info) : \
+	 NULL)
+
+#endif	/* __ia64 */
 
 #define KL_CONFIG_MAGIC(_nasid)		(KL_CONFIG_HDR(_nasid)->ch_magic)
 
@@ -187,23 +183,13 @@
 
 /* --- New Macros for the changed kl_config_hdr_t structure --- */
 
-#if defined(CONFIG_IA64_SGI_IO)
 #define PTR_CH_MALLOC_HDR(_k)   ((klc_malloc_hdr_t *)\
 			((__psunsigned_t)_k + (_k->ch_malloc_hdr_off)))
-#else
-#define PTR_CH_MALLOC_HDR(_k)   ((klc_malloc_hdr_t *)\
-			(unsigned long)_k + (_k->ch_malloc_hdr_off)))
-#endif
 
 #define KL_CONFIG_CH_MALLOC_HDR(_n)   PTR_CH_MALLOC_HDR(KL_CONFIG_HDR(_n))
 
-#if defined(CONFIG_IA64_SGI_IO)
 #define PTR_CH_CONS_INFO(_k)	((console_t *)\
 			((__psunsigned_t)_k + (_k->ch_cons_off)))
-#else
-#define PTR_CH_CONS_INFO(_k)	((console_t *)\
-			((unsigned long)_k + (_k->ch_cons_off)))
-#endif
 
 #define KL_CONFIG_CH_CONS_INFO(_n)   PTR_CH_CONS_INFO(KL_CONFIG_HDR(_n))
 
@@ -374,6 +360,7 @@
 #define KLTYPE_IP27	(KLCLASS_CPU | 0x1) /* 2 CPUs(R10K) per board */
 #if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 #define KLTYPE_IP35	KLTYPE_IP27
+#define KLTYPE_IP37	KLTYPE_IP35
 #endif
 
 #define KLTYPE_WEIRDIO	(KLCLASS_IO  | 0x0)
@@ -394,6 +381,8 @@
 #define KLTYPE_TPU    	(KLCLASS_IO  | 0xB) /* Tensor Processing Unit */
 #define KLTYPE_GSN_A   	(KLCLASS_IO  | 0xC) /* Main GSN board */
 #define KLTYPE_GSN_B   	(KLCLASS_IO  | 0xD) /* Auxiliary GSN board */
+#define KLTYPE_SHOEHORN (KLCLASS_IO  | 0xE)
+#define KLTYPE_SERIAL_HIPPI (KLCLASS_IO  | 0xF)
 
 #define KLTYPE_GFX	(KLCLASS_GFX | 0x0) /* unknown graphics type */
 #define KLTYPE_GFX_KONA (KLCLASS_GFX | 0x1) /* KONA graphics on IP27 */
@@ -404,11 +393,12 @@
 #define KLTYPE_ROUTER2    KLTYPE_ROUTER		/* Obsolete! */
 #define KLTYPE_NULL_ROUTER (KLCLASS_ROUTER | 0x2)
 #define KLTYPE_META_ROUTER (KLCLASS_ROUTER | 0x3)
+#define KLTYPE_REPEATER_ROUTER (KLCLASS_ROUTER | 0x4)
 
 #define KLTYPE_WEIRDMIDPLANE (KLCLASS_MIDPLANE | 0x0)
 #define KLTYPE_MIDPLANE8  (KLCLASS_MIDPLANE | 0x1) /* 8 slot backplane */
 #define KLTYPE_MIDPLANE    KLTYPE_MIDPLANE8
-#define KLTYPE_PBRICK_XBOW	(KLCLASS_MIDPLANE | 0x2)
+#define KLTYPE_IOBRICK_XBOW	(KLCLASS_MIDPLANE | 0x2)
 
 #define KLTYPE_IOBRICK		(KLCLASS_IOBRICK | 0x0)
 #define KLTYPE_IBRICK		(KLCLASS_IOBRICK | 0x1)
@@ -485,7 +475,7 @@
 #define KLCF_NUM_COMPS(_brd)	((_brd)->brd_numcompts)
 #define KLCF_MODULE_ID(_brd)	((_brd)->brd_module)
 
-#ifndef SIMULATED_KLGRAPH
+#ifndef __ia64
 #define KLCF_NEXT(_brd) 		((_brd)->brd_next ? (lboard_t *)((_brd)->brd_next):  NULL)
 #define KLCF_COMP(_brd, _ndx)   \
 		(klinfo_t *)(NODE_OFFSET_TO_K0(NASID_GET(_brd), \
@@ -494,14 +484,18 @@
 		(NODE_OFFSET_TO_K0(NASID_GET(_brd), (_comp)->errinfo))
 
 #else
-/*
- * For fake klgraph info.
- */
-#define KLCF_COMP(_brd, _ndx)           (klinfo_t *)((ulong) 0xe000000000000000 |((_brd)->brd_compts[(_ndx)]))
-#define KLCF_NEXT(_brd)	((_brd)->brd_next ? (lboard_t *)((ulong) 0xe000000000000000 | (_brd->brd_next)) : NULL)
-#define KLCF_COMP_ERROR(_brd, _comp)    (_brd = _brd , (_comp)->errinfo)
 
-#endif	/* SIMULATED_KLGRAPH */
+#define NODE_OFFSET_TO_KLINFO(n,off)    ((klinfo_t*) TO_NODE_CAC(n,off))
+#define KLCF_NEXT(_brd)         \
+        ((_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)]))
+
+#define KLCF_COMP_ERROR(_brd, _comp)    \
+                (NODE_OFFSET_TO_K0(NASID_GET(_brd), (_comp)->errinfo))
+
+#endif /* __ia64 */
 
 #define KLCF_COMP_TYPE(_comp)	((_comp)->struct_type)
 #define KLCF_BRIDGE_W_ID(_comp)	((_comp)->physid)	/* Widget ID */
@@ -581,6 +575,11 @@
 #define KLSTRUCT_GSN_A          29
 #define KLSTRUCT_GSN_B          30
 #define KLSTRUCT_XTHD           31
+#define KLSTRUCT_QLFIBRE        32
+#define KLSTRUCT_1394           33
+#define KLSTRUCT_USB		34
+#define KLSTRUCT_USBKBD		35
+#define KLSTRUCT_USBMS		36
 
 /*
  * These are the indices of various components within a lboard structure.
@@ -845,6 +844,15 @@
     	mio_t       	mio_specific   ; 
 } klmio_t ;
 
+/*
+ * USB info
+ */
+
+typedef struct klusb_s {
+	klinfo_t	usb_info;	/* controller info */
+	void		*usb_bus;	/* handle to usb_bus_t */
+	uint64_t	usb_controller;	/* ptr to controller info */
+} klusb_t ; 
 
 typedef union klcomp_s {
 	klcpu_t		kc_cpu;
@@ -862,6 +870,7 @@
 	klfddi_t	kc_fddi;
 	klmio_t		kc_mio;
 	klmod_serial_num_t kc_snum ;
+	klusb_t		kc_usb;
 } klcomp_t;
 
 typedef union kldev_s {      /* for device structure allocation */
@@ -925,7 +934,6 @@
 extern klcpu_t *nasid_slice_to_cpuinfo(nasid_t, int);
 
 
-#if defined(CONFIG_IA64_SGI_IO)
 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);
@@ -954,8 +962,5 @@
 extern int	is_master_baseio(nasid_t,moduleid_t,slotid_t);
 extern nasid_t	get_actual_nasid(lboard_t *brd) ;
 extern net_vec_t klcfg_discover_route(lboard_t *, lboard_t *, int);
-#else	/* CONFIG_IA64_SGI_IO */
-extern klcpu_t *sn_get_cpuinfo(cpuid_t cpu);
-#endif	/* CONFIG_IA64_SGI_IO */
 
 #endif /* _ASM_SN_KLCONFIG_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/kldir.h linux/include/asm-ia64/sn/kldir.h
--- v2.4.3/linux/include/asm-ia64/sn/kldir.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/kldir.h	Thu Apr  5 12:51:47 2001
@@ -13,9 +13,7 @@
 #define _ASM_SN_KLDIR_H
 
 #include <linux/config.h>
-#if defined(CONFIG_IA64_SGI_IO)
 #include <asm/sn/sgi.h>
-#endif
 
 /*
  * The kldir memory area resides at a fixed place in each node's memory and
@@ -136,88 +134,11 @@
 #define KLDIR_OFF_STRIDE		0x28
 #endif /* LANGUAGE_ASSEMBLY */
 
-#if !defined(CONFIG_IA64_SGI_IO)
-
-/*
- * This is defined here because IP27_SYMMON_STK_SIZE must be at least what
- * we define here.  Since it's set up in the prom.  We can't redefine it later
- * and expect more space to be allocated.  The way to find out the true size
- * of the symmon stacks is to divide SYMMON_STK_SIZE by SYMMON_STK_STRIDE
- * for a particular node.
- */
-#define SYMMON_STACK_SIZE		0x8000
-
-#if defined (PROM) || defined (SABLE)
-
-/*
- * These defines are prom version dependent.  No code other than the IP27
- * prom should attempt to use these values.
- */
-#define IP27_LAUNCH_OFFSET		0x2400
-#define IP27_LAUNCH_SIZE		0x400
-#define IP27_LAUNCH_COUNT		2
-#define IP27_LAUNCH_STRIDE		0x200
-
-#define IP27_KLCONFIG_OFFSET		0x4000
-#define IP27_KLCONFIG_SIZE		0xc000
-#define IP27_KLCONFIG_COUNT		1
-#define IP27_KLCONFIG_STRIDE		0
-
-#define IP27_NMI_OFFSET			0x3000
-#define IP27_NMI_SIZE			0x40
-#define IP27_NMI_COUNT			2
-#define IP27_NMI_STRIDE			0x40
-
-#define IP27_PI_ERROR_OFFSET		0x12000
-#define IP27_PI_ERROR_SIZE		0x4000
-#define IP27_PI_ERROR_COUNT		1
-#define IP27_PI_ERROR_STRIDE		0
-
-#define IP27_SYMMON_STK_OFFSET		0x25000
-#define IP27_SYMMON_STK_SIZE		0xe000
-#define IP27_SYMMON_STK_COUNT		2
-/* IP27_SYMMON_STK_STRIDE must be >= SYMMON_STACK_SIZE */
-#define IP27_SYMMON_STK_STRIDE		0x7000
-
-#define IP27_FREEMEM_OFFSET		0x19000
-#define IP27_FREEMEM_SIZE		-1
-#define IP27_FREEMEM_COUNT		1
-#define IP27_FREEMEM_STRIDE		0
-
-#endif /* PROM || SABLE*/
-/*
- * There will be only one of these in a partition so the IO6 must set it up.
- */
-#define IO6_GDA_OFFSET			0x11000
-#define IO6_GDA_SIZE			0x400
-#define IO6_GDA_COUNT			1
-#define IO6_GDA_STRIDE			0
-
-/*
- * save area of kernel nmi regs in the prom format
- */
-#define IP27_NMI_KREGS_OFFSET		0x11400
-#define IP27_NMI_KREGS_CPU_SIZE		0x200
-/*
- * save area of kernel nmi regs in eframe format 
- */
-#define IP27_NMI_EFRAME_OFFSET		0x11800
-#define IP27_NMI_EFRAME_SIZE		0x200
-
-#define KLDIR_ENT_SIZE			0x40
-#define KLDIR_MAX_ENTRIES		(0x400 / 0x40)
-
-#endif	/* !CONFIG_IA64_SGI_IO */
-
 #ifdef _LANGUAGE_C
 typedef struct kldir_ent_s {
 	u64		magic;		/* Indicates validity of entry      */
 	off_t		offset;		/* Offset from start of node space  */
-#if defined(CONFIG_IA64_SGI_IO)	/* FIXME */
 	__psunsigned_t	pointer;	/* Pointer to area in some cases    */
-#else
-	unsigned long	pointer;	/* Pointer to area in some cases    */
-#endif
 	size_t		size;		/* Size in bytes 		    */
 	u64		count;		/* Repeat count if array, 1 if not  */
 	size_t		stride;		/* Stride if array, 0 if not        */
@@ -227,7 +148,6 @@
 } kldir_ent_t;
 #endif /* _LANGUAGE_C */
 
-#if defined(CONFIG_IA64_SGI_IO)
 
 #define KLDIR_ENT_SIZE			0x40
 #define KLDIR_MAX_ENTRIES		(0x400 / 0x40)
@@ -240,7 +160,5 @@
 #else
 #error "kldir.h is currently defined for IP27 and IP35 platforms only"
 #endif
-
-#endif	/* CONFIG_IA64_SGI_IO */
 
 #endif /* _ASM_SN_KLDIR_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/ksys/elsc.h linux/include/asm-ia64/sn/ksys/elsc.h
--- v2.4.3/linux/include/asm-ia64/sn/ksys/elsc.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/ksys/elsc.h	Thu Apr  5 12:51:47 2001
@@ -11,6 +11,7 @@
 #define _ASM_SN_KSYS_ELSC_H
 
 #include <linux/config.h>
+
 #if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 #include <asm/sn/ksys/l1.h>
 #endif
@@ -48,7 +49,7 @@
 int	elsc_msg_callback(elsc_t *e,
 			  void (*callback)(void *callback_data, char *msg),
 			  void *callback_data);
-#if 0
+#ifdef LATER
 char   *elsc_errmsg(int code);
 
 int	elsc_nvram_write(elsc_t *e, int addr, char *buf, int len);
@@ -68,7 +69,7 @@
  */
 
 int	elsc_version(elsc_t *e, char *result);
-#if 0
+#ifdef LATER
 int	elsc_debug_set(elsc_t *e, u_char byte1, u_char byte2);
 int	elsc_debug_get(elsc_t *e, u_char *byte1, u_char *byte2);
 #endif
@@ -90,7 +91,7 @@
 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);
-#if 0
+#ifdef LATER
 int	elsc_display_mesg(elsc_t *e, char *chr);	/* 8-char input */
 int	elsc_password_set(elsc_t *e, char *password);	/* 4-char input */
 int	elsc_password_get(elsc_t *e, char *password);	/* 4-char output */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/ksys/l1.h linux/include/asm-ia64/sn/ksys/l1.h
--- v2.4.3/linux/include/asm-ia64/sn/ksys/l1.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/ksys/l1.h	Thu Apr  5 12:51:47 2001
@@ -80,11 +80,11 @@
 				 * use == BRL1_SUBCH_FREE */
     uint	target;		/* type, rack and slot of component to
 				 * which this subchannel is directed */
-    int		packet_arrived; /* true if packet arrived on
+    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 */
-    lock_t	data_lock;	/* synchronize access to input queues and
+    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 */
@@ -118,9 +118,7 @@
     brl1_uartf_t putc_f;	/* pointer to UART putc function */
     brl1_uartf_t getc_f;	/* pointer to UART getc function */
 
-    lock_t	 send_lock;	/* arbitrates send synchronization */
-    lock_t	 recv_lock;	/* arbitrates uart receive access */
-    lock_t	 subch_lock;	/* arbitrates subchannel allocation */
+    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
@@ -223,6 +221,7 @@
 #define L1_RESP_REQC	(-101)	/* bad request code	        */
 #define L1_RESP_NAVAIL	(-104)	/* requested data not available */
 #define L1_RESP_ARGVAL	(-105)  /* arg value out of range       */
+#define L1_RESP_INVAL   (-107)  /* requested data invalid       */
 
 /* L1 general requests */
 
@@ -239,16 +238,19 @@
 #define L1_REQ_PORTSPEED	0x000a	/* get ioport speed */
 
 #define L1_REQ_CONS_SUBCH	0x1002  /* select this node's console 
-					 * subchannel */
+					   subchannel */
 #define L1_REQ_CONS_NODE	0x1003  /* volunteer to be the master 
-					 * (console-hosting) node */
+					   (console-hosting) node */
 #define L1_REQ_DISP1		0x1004  /* write line 1 of L1 display */
 #define L1_REQ_DISP2		0x1005  /* write line 2 of L1 display */
 #define L1_REQ_PARTITION_SET	0x1006	/* set partition id */
 #define L1_REQ_EVENT_SUBCH	0x1007	/* set the subchannel for system
 					   controller event transmission */
 
-#define L1_REQ_RESET		0x2001	/* request a full system reset */
+#define L1_REQ_RESET		0x2000	/* request a full system reset */
+#define L1_REQ_PCI_UP		0x2001  /* power up pci slot or bus */
+#define L1_REQ_PCI_DOWN		0x2002  /* power down pci slot or bus */
+#define L1_REQ_PCI_RESET	0x2003  /* reset pci bus or slot */
 
 /* L1 command interpreter requests */
 
@@ -325,18 +327,6 @@
 void	sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart );
 void	sc_intr_enable( l1sc_t *sc );
 
-#if 0
-int	sc_portspeed_get( l1sc_t *sc );
-#endif
-
-int	l1_cons_poll( l1sc_t *sc );
-int	l1_cons_getc( l1sc_t *sc );
-void	l1_cons_init( l1sc_t *sc );
-int	l1_cons_read( l1sc_t *sc, char *buf, int avail );
-int	l1_cons_write( l1sc_t *sc, char *msg, int len, int wait );
-void	l1_cons_tx_notif( l1sc_t *sc, brl1_notif_t func );
-void	l1_cons_rx_notif( l1sc_t *sc, brl1_notif_t func );
-
 int	_elscuart_putc( l1sc_t *sc, int c );
 int	_elscuart_getc( l1sc_t *sc );
 int	_elscuart_poll( l1sc_t *sc );
@@ -354,11 +344,7 @@
 int	elsc_display_line(l1sc_t *e, char *line, int lnum);
 
 extern l1sc_t *get_elsc( void );
-extern void    set_elsc( l1sc_t *e );
-
 #define get_l1sc	get_elsc
-#define set_l1sc(e)	set_elsc(e)
-
 #define get_master_l1sc get_l1sc
 
 int	router_module_get( nasid_t nasid, net_vec_t path );
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/mmzone.h linux/include/asm-ia64/sn/mmzone.h
--- v2.4.3/linux/include/asm-ia64/sn/mmzone.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/mmzone.h	Thu Apr  5 12:51:47 2001
@@ -6,6 +6,7 @@
 #define _LINUX_ASM_SN_MMZONE_H
 
 #include <linux/config.h>
+
 #include <asm/sn/mmzone_sn1.h>
 #include <asm/sn/sn_cpuid.h>
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/mmzone_sn1.h linux/include/asm-ia64/sn/mmzone_sn1.h
--- v2.4.3/linux/include/asm-ia64/sn/mmzone_sn1.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/mmzone_sn1.h	Thu Apr  5 12:51:47 2001
@@ -1,12 +1,11 @@
 #ifndef _ASM_IA64_MMZONE_SN1_H
 #define _ASM_IA64_MMZONE_SN1_H
 
+#include <linux/config.h>
+
 /*
  * Copyright, 2000, Silicon Graphics, sprasad@engr.sgi.com
  */
-
-#include <linux/config.h>
-
 /* Maximum configuration supported by SNIA hardware. There are other
  * restrictions that may limit us to a smaller max configuration.
  */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/module.h linux/include/asm-ia64/sn/module.h
--- v2.4.3/linux/include/asm-ia64/sn/module.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/module.h	Thu Apr  5 12:51:47 2001
@@ -15,6 +15,7 @@
 #endif
 
 #include <linux/config.h>
+
 #include <asm/sn/systeminfo.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/ksys/elsc.h>
@@ -178,22 +179,24 @@
 
     int			disable_alert;
     int			count_down;
+
+    /* System serial number info (used by SN1) */
+    char		sys_snum[MAX_SERIAL_NUM_SIZE];
+    int			sys_snum_valid;
 };
 
 /* module.c */
 extern module_t	       *modules[MODULE_MAX];	/* Indexed by cmoduleid_t   */
 extern int		nummodules;
 
-#ifndef CONFIG_IA64_SGI_IO
-/* Clashes with LINUX stuff */
-extern void		module_init(void);
-#endif
 extern module_t	       *module_lookup(moduleid_t id);
 
 extern elsc_t	       *get_elsc(void);
 
 extern int		get_kmod_info(cmoduleid_t cmod,
 				      module_info_t *mod_info);
+extern int		get_kmod_sys_snum(cmoduleid_t cmod,
+					  char *snum);
 
 extern void		format_module_id(char *buffer, moduleid_t m, int fmt);
 extern int		parse_module_id(char *buffer);
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/nodemask.h linux/include/asm-ia64/sn/nodemask.h
--- v2.4.3/linux/include/asm-ia64/sn/nodemask.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/nodemask.h	Thu Apr  5 12:51:47 2001
@@ -13,6 +13,7 @@
 #if defined(__KERNEL__) || defined(_KMEMUSER)
 
 #include <linux/config.h>
+
 #if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
 #include <asm/sn/sn1/arch.h>    /* needed for MAX_COMPACT_NODES */
 #endif
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/nodepda.h linux/include/asm-ia64/sn/nodepda.h
--- v2.4.3/linux/include/asm-ia64/sn/nodepda.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/nodepda.h	Thu Apr  5 12:51:47 2001
@@ -15,11 +15,13 @@
 #endif
 
 #include <linux/config.h>
+
 #include <asm/sn/agent.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/router.h>
+#include <asm/sn/synergy.h>
 /* #include <SN/klkernvars.h> */
-#ifdef IRIX
+#ifdef LATER
 typedef struct module_s module_t;       /* Avoids sys/SN/module.h */
 #else
 #include <asm/sn/module.h>
@@ -54,6 +56,10 @@
 
 struct ptpool_s;
 
+#if defined(CONFIG_IA64_SGI_SYNERGY_PERF)
+struct synergy_perf_s;
+#endif
+
 
 /*
  * Node-specific data structure.
@@ -67,7 +73,8 @@
  */
 
 
-#ifndef CONFIG_IA64_SGI_IO
+
+#ifdef LATER
 /*
  * The following structure is contained in the nodepda & contains
  * a lock & queue-head for sanon pages that belong to the node.
@@ -78,9 +85,6 @@
 	plist_t sal_listhead;
 } sanon_list_head_t;
 #endif
-
-
-
 struct nodepda_s {
 
 #ifdef	NUMA_BASE
@@ -133,7 +137,7 @@
 	 * Each node gets its own syswait counter to remove contention
 	 * on the global one.
 	 */
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	struct syswait syswait;
 #endif
 
@@ -141,7 +145,7 @@
 	/*
 	 * Node-specific Zone structures.
 	 */
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef LATER
 	zoneset_element_t	node_zones;
 	pg_data_t	node_pg_data;	/* VM page data structures */ 
 	plist_t	error_discard_plist;
@@ -154,7 +158,7 @@
 	/* Information needed for SN Hub chip interrupt handling. */
 	subnode_pda_t	snpda[NUM_SUBNODES];
 	/* Distributed kernel support */
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	kern_vars_t	kern_vars;
 #endif
 	/* Vector operation support */
@@ -173,6 +177,17 @@
 	nodepda_router_info_t	*npda_rip_first;
 	nodepda_router_info_t	**npda_rip_last;
 	int		dependent_routers;
+
+#if defined(CONFIG_IA64_SGI_SYNERGY_PERF)
+	int			synergy_perf_enabled;
+        int       		synergy_perf_freq;
+	spinlock_t		synergy_perf_lock;
+        uint64_t       		synergy_inactive_intervals;
+        uint64_t       		synergy_active_intervals;
+        struct synergy_perf_s	*synergy_perf_data;
+        struct synergy_perf_s	*synergy_perf_first; /* reporting consistency .. */
+#endif /* CONFIG_IA64_SGI_SYNERGY_PERF */
+
 	devfs_handle_t 	xbow_vhdl;
 	nasid_t		xbow_peer;	/* NASID of our peer hub on xbow */
 	struct semaphore xbow_sema;	/* Sema for xbow synchronization */
@@ -189,13 +204,13 @@
 	char		ni_error_print; /* For printing ni error state
 					 * only once during system panic
 					 */
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	md_perf_monitor_t node_md_perfmon;
 	hubstat_t	hubstats;
 	int		hubticks;
-	int		huberror_ticks;
 	sbe_info_t	*sbe_info;	/* ECC single-bit error statistics */
-#endif	/* !CONFIG_IA64_SGI_IO */
+#endif	/* LATER */
+	int		huberror_ticks;
 
 	router_queue_t  *visited_router_q;
 	router_queue_t	*bfs_router_q; 
@@ -218,11 +233,9 @@
 	void 		*pdinfo;	/* Platform-dependent per-node info */
 	uint64_t	*dump_stack;	/* Dump stack during nmi handling */
 	int		dump_count;	/* To allow only one cpu-per-node */
-#if defined BRINGUP
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	io_perf_monitor_t node_io_perfmon;
 #endif
-#endif
 
 	/*
 	 * Each node gets its own pdcount counter to remove contention
@@ -235,7 +248,7 @@
 	void		*cached_global_pool;	/* pointer to cached vmpool */
 #endif /* NUMA_BASE */
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	sanon_list_head_t sanon_list_head;	/* head for sanon pages */	
 #endif
 #ifdef	NUMA_BASE
@@ -246,7 +259,7 @@
 	 * The BTEs on this node are shared by the local cpus
 	 */
 #if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	bteinfo_t	*node_bte_info[BTES_PER_NODE];
 #endif
 #endif
@@ -273,7 +286,7 @@
  *	SUBNODEPDA(x,s)	-> to access subnode PDA for cnodeid/slice 'x'
  */
 
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 #define	nodepda		private.p_nodepda	/* Ptr to this node's PDA */
 #if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
 #define subnodepda	private.p_subnodepda	/* Ptr to this node's subnode PDA */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/pci/pci_bus_cvlink.h linux/include/asm-ia64/sn/pci/pci_bus_cvlink.h
--- v2.4.3/linux/include/asm-ia64/sn/pci/pci_bus_cvlink.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/pci/pci_bus_cvlink.h	Thu Apr  5 12:51:47 2001
@@ -26,4 +26,23 @@
 	int		isa64;
 };
 
+struct sn1_dma_maps_s{
+	struct pcibr_dmamap_s dma_map;
+        dma_addr_t      dma_addr;
+};
+
+struct ioports_to_tlbs_s {
+	unsigned long	p:1,
+			rv_1:1,
+			ma:3,
+			a:1,
+			d:1,
+			pl:2,
+			ar:3,
+			ppn:38,
+			rv_2:2,
+			ed:1,
+			ig:11;
+};
+
 #endif				/* _ASM_SN_PCI_CVLINK_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/pci/pciba.h linux/include/asm-ia64/sn/pci/pciba.h
--- v2.4.3/linux/include/asm-ia64/sn/pci/pciba.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ia64/sn/pci/pciba.h	Thu Apr  5 12:51:47 2001
@@ -0,0 +1,103 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2000 by Colin Ngam
+ */
+#ifndef _ASM_SN_PCI_PCIBA_H
+#define _ASM_SN_PCI_PCIBA_H
+
+/*
+ * These are all the HACKS from ioccom.h ..
+ */
+#define IOCPARM_MASK    0xff            /* parameters must be < 256 bytes */
+#define IOC_VOID        0x20000000      /* no parameters */
+
+/*
+ * The above needs to be modified and follow LINUX ...
+ */
+
+/* /hw/.../pci/[slot]/config accepts ioctls to read
+ * and write specific registers as follows:
+ *
+ * "t" is the native type (char, short, uint32, uint64)
+ * to read from CFG space; results will be arranged in
+ * byte significance (ie. first byte from PCI is lowest
+ * or last byte in result).
+ *
+ * "r" is the byte offset in PCI CFG space of the first
+ * byte of the register (it's least significant byte,
+ * in the little-endian PCI numbering). This can actually
+ * be as much as 16 bits wide, and is intended to match
+ * the layout of a "Type 1 Configuration Space" address:
+ * the register number in the low eight bits, then three
+ * bits for the function number and five bits for the
+ * slot number.
+ */
+#define	PCIIOCCFGRD(t,r)	_IOR(0,(r),t)
+#define	PCIIOCCFGWR(t,r)	_IOW(0,(r),t)
+
+/* Some common config register access commands.
+ * Use these as examples of how to construct
+ * values for other registers you want to access.
+ */
+
+/* PCIIOCGETID: arg is ptr to 32-bit int,
+ * returns the 32-bit ID value with VENDOR
+ * in the bottom 16 bits and DEVICE in the top.
+ */
+#define	PCIIOCGETID		PCIIOCCFGRD(uint32_t,PCI_CFG_VENDOR_ID)
+
+/* PCIIOCSETCMD: arg is ptr to a 16-bit short,
+ * which will be written to the CMD register.
+ */
+#define	PCIIOCSETCMD		PCIIOCCFGWR(uint16_t,PCI_CFG_COMMAND)
+
+/* PCIIOCGETREV: arg is ptr to an 8-bit char,
+ * which will get the 8-bit revision number.
+ */
+#define	PCIIOCGETREV		PCIIOCCFGRD(uint8_t,PCI_CFG_REV_ID)
+
+/* PCIIOCGETHTYPE: arg is ptr to an 8-bit char,
+ * which will get the 8-bit header type.
+ */
+#define	PCIIOCGETHTYPE		PCIIOCCFGRD(uint8_t,PCI_CFG_HEADER_TYPE)
+
+/* PCIIOCGETBASE(n): arg is ptr to a 32-bit int,
+ * which will get the value of the BASE<n> register.
+ */
+#define	PCIIOCGETBASE(n)	PCIIOCCFGRD(uint32_t,PCI_CFG_BASE_ADDR(n))
+
+/* /hw/.../pci/[slot]/intr accepts an ioctl to
+ * set up user level interrupt handling as follows:
+ *
+ * "n" is a bitmap of which of the four PCI interrupt
+ * lines are of interest, using PCIIO_INTR_LINE_[ABCD].
+ */
+#define	PCIIOCSETULI(n)		_IOWR(1,n,struct uliargs)
+#if _KERNEL
+#define PCIIOCSETULI32(n)	_IOWR(1,n,struct uliargs32)
+#endif
+
+/* /hw/.../pci/[slot]/dma accepts ioctls to allocate
+ * and free physical memory for use in user-triggered
+ * DMA operations.
+ */
+#define	PCIIOCDMAALLOC		_IOWR(0,1,uint64_t)
+#define	PCIIOCDMAFREE		_IOW(0,1,uint64_t)
+
+/* The parameter for PCIIOCDMAALLOC needs to contain
+ * both the size of the request and the flag values
+ * to be used in setting up the DMA.
+ *
+ * Any flags normally useful in pciio_dmamap
+ * or pciio_dmatrans function calls can6 be used here.
+ */
+#define	PCIIOCDMAALLOC_REQUEST_PACK(flags,size)		\
+	((((uint64_t)(flags))<<32)|			\
+	 (((uint64_t)(size))&0xFFFFFFFF))
+
+#endif	/* _ASM_SN_PCI_PCIBA_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/pci/pcibr.h linux/include/asm-ia64/sn/pci/pcibr.h
--- v2.4.3/linux/include/asm-ia64/sn/pci/pcibr.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/pci/pcibr.h	Thu Apr  5 12:51:47 2001
@@ -143,6 +143,14 @@
 
 extern void		pcibr_dmamap_done(pcibr_dmamap_t dmamap);
 
+/*
+ * pcibr_get_dmatrans_node() will return the compact node id to which  
+ * all 32-bit Direct Mapping memory accesses will be directed.
+ * (This node id can be different for each PCI bus.) 
+ */
+
+extern cnodeid_t	pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl);
+
 extern iopaddr_t	pcibr_dmatrans_addr(devfs_handle_t dev,
 					    device_desc_t dev_desc,
 					    paddr_t paddr,
@@ -215,10 +223,6 @@
 					    pciio_space_t *spacep,
 					    iopaddr_t *addrp);
 
-extern int		pcibr_rrb_alloc(devfs_handle_t pconn_vhdl,
-					int *count_vchan0,
-					int *count_vchan1);
-
 extern int		pcibr_wrb_flush(devfs_handle_t pconn_vhdl);
 extern int		pcibr_rrb_check(devfs_handle_t pconn_vhdl,
 					int *count_vchan0,
@@ -241,7 +245,7 @@
 void			pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl,
 					       rrb_alloc_funct_f *func);
 
-extern void		pcibr_device_unregister(devfs_handle_t);
+extern int		pcibr_device_unregister(devfs_handle_t);
 extern int		pcibr_dma_enabled(devfs_handle_t);
 /*
  * Bridge-specific flags that can be set via pcibr_device_flags_set
@@ -337,7 +341,7 @@
 
 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, uint64_t);
+extern void		pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, ulong);
 extern void		pcibr_hints_handsoff(devfs_handle_t);
 
 typedef unsigned	pcibr_intr_bits_f(pciio_info_t, pciio_intr_line_t);
@@ -353,8 +357,104 @@
 #define PCIBR			'p'
 #define _PCIBR(x)		((PCIBR << 8) | (x))
 
-#define PCIBR_SLOT_POWERUP	_PCIBR(1)
-#define PCIBR_SLOT_SHUTDOWN	_PCIBR(2)
-#define PCIBR_SLOT_INQUIRY	_PCIBR(3)
+#define PCIBR_SLOT_STARTUP	_PCIBR(1)
+#define PCIBR_SLOT_SHUTDOWN     _PCIBR(2)
+#define PCIBR_SLOT_QUERY	_PCIBR(3)
+
+/*
+ * Bit defintions for variable slot_status in struct
+ * pcibr_soft_slot_s.  They are here so that both
+ * the pcibr driver and the pciconfig command can
+ * reference them.
+ */
+#define SLOT_STARTUP_CMPLT      0x01
+#define SLOT_STARTUP_INCMPLT    0x02
+#define SLOT_SHUTDOWN_CMPLT     0x04
+#define SLOT_SHUTDOWN_INCMPLT   0x08
+#define SLOT_POWER_UP           0x10
+#define SLOT_POWER_DOWN         0x20
+#define SLOT_IS_SYS_CRITICAL    0x40
+
+#define SLOT_STATUS_MASK        (SLOT_STARTUP_CMPLT | SLOT_STARTUP_INCMPLT | \
+                                 SLOT_SHUTDOWN_CMPLT | SLOT_SHUTDOWN_INCMPLT)
+#define SLOT_POWER_MASK         (SLOT_POWER_UP | SLOT_POWER_DOWN)
+
+/*
+ * Bit definitions for variable resp_f_staus.
+ * They are here so that both the pcibr driver
+ * and the pciconfig command can reference them.
+ */
+#define FUNC_IS_VALID           0x01
+#define FUNC_IS_SYS_CRITICAL    0x02
+
+/*
+ * Structures for requesting PCI bridge information and receiving a response
+ */
+typedef struct pcibr_slot_info_req_s *pcibr_slot_info_req_t;
+typedef struct pcibr_slot_info_resp_s *pcibr_slot_info_resp_t;
+typedef struct pcibr_slot_func_info_resp_s *pcibr_slot_func_info_resp_t;
+
+struct pcibr_slot_info_req_s {
+   int                      req_slot;
+   pcibr_slot_info_resp_t   req_respp;
+   int                      req_size;
+};
+
+struct pcibr_slot_info_resp_s {
+    int                     resp_has_host;
+    char                    resp_host_slot;
+    devfs_handle_t            resp_slot_conn;
+    char                    resp_slot_conn_name[MAXDEVNAME];
+    int                     resp_slot_status;
+    int                     resp_l1_bus_num;
+    int                     resp_bss_ninfo;
+    char                    resp_bss_devio_bssd_space[16];
+    iopaddr_t               resp_bss_devio_bssd_base; 
+    bridgereg_t             resp_bss_device;
+    int                     resp_bss_pmu_uctr;
+    int                     resp_bss_d32_uctr;
+    int                     resp_bss_d64_uctr;
+    iopaddr_t               resp_bss_d64_base;
+    unsigned                resp_bss_d64_flags;
+    iopaddr_t               resp_bss_d32_base;
+    unsigned                resp_bss_d32_flags;
+    int                     resp_bss_ext_ates_active;
+    volatile unsigned      *resp_bss_cmd_pointer;
+    unsigned                resp_bss_cmd_shadow;
+    int                     resp_bs_rrb_valid;
+    int                     resp_bs_rrb_valid_v;
+    int                     resp_bs_rrb_res;
+    bridgereg_t             resp_b_resp;
+    bridgereg_t             resp_b_int_device;
+    bridgereg_t             resp_b_int_enable;
+    bridgereg_t             resp_b_int_host;
+
+    struct pcibr_slot_func_info_resp_s {
+        int                     resp_f_status;
+        char                    resp_f_slot_name[MAXDEVNAME];
+        char                    resp_f_bus;
+        char                    resp_f_slot;
+        char                    resp_f_func;
+        char                    resp_f_master_name[MAXDEVNAME];
+        void                   *resp_f_pops;
+        error_handler_f        *resp_f_efunc;
+        error_handler_arg_t     resp_f_einfo;
+        int                     resp_f_vendor;
+        int                     resp_f_device;
+
+        struct {
+            char                    resp_w_space[16];
+            iopaddr_t               resp_w_base;
+            size_t                  resp_w_size;
+        } resp_f_window[6];
+
+        unsigned                resp_f_rbase;
+        unsigned                resp_f_rsize;
+        int                     resp_f_ibit[4];
+        int                     resp_f_att_det_error;
+
+    } resp_func[8];
+
+};
 
 #endif				/* _ASM_SN_PCI_PCIBR_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/pci/pcibr_private.h linux/include/asm-ia64/sn/pci/pcibr_private.h
--- v2.4.3/linux/include/asm-ia64/sn/pci/pcibr_private.h	Tue Mar  6 19:44:34 2001
+++ linux/include/asm-ia64/sn/pci/pcibr_private.h	Thu Apr  5 12:51:47 2001
@@ -17,6 +17,7 @@
  */
 
 #include <asm/sn/pci/pciio_private.h>
+#include <asm/sn/ksys/l1.h>
 
 /*
  * convenience typedefs
@@ -31,6 +32,7 @@
 typedef struct pcibr_hints_s *pcibr_hints_t;
 typedef struct pcibr_intr_list_s *pcibr_intr_list_t;
 typedef struct pcibr_intr_wrap_s *pcibr_intr_wrap_t;
+typedef struct pcibr_intr_cbuf_s *pcibr_intr_cbuf_t;
 
 /*
  * Bridge sets up PIO using this information.
@@ -50,7 +52,7 @@
     xtalk_piomap_t          bp_xtalk_pio;	/* corresponding xtalk resource */
     pcibr_piomap_t	    bp_next;	/* Next piomap on the list */
     pcibr_soft_t	    bp_soft;	/* backpointer to bridge soft data */
-    int			    bp_toc[1];	/* PCI timeout counter */
+    atomic_t		    bp_toc[1];	/* PCI timeout counter */
 
 };
 
@@ -77,6 +79,18 @@
     bridge_ate_t            bd_ate_prime;	/* value of 1st ATE written */
 };
 
+#define	IBUFSIZE	5		/* size of circular buffer (holds 4) */
+
+/*
+ * Circular buffer used for interrupt processing
+ */
+struct pcibr_intr_cbuf_s {
+    spinlock_t		ib_lock;		/* cbuf 'put' lock */
+    int			ib_in;			/* index of next free entry */
+    int			ib_out;			/* index of next full entry */
+    pcibr_intr_wrap_t   ib_cbuf[IBUFSIZE];	/* circular buffer of wrap  */
+};
+
 /*
  * Bridge sets up interrupts using this information.
  */
@@ -94,6 +108,7 @@
 #define bi_cpu		bi_pi.pi_cpu	/* cpu assigned. */
     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 */
 };
 
 /*
@@ -121,6 +136,7 @@
     /* pcibr-specific connection state */
     int			    f_ibit[4];	/* Bridge bit for each INTx */
     pcibr_piomap_t	    f_piomap;
+    int                     f_att_det_error;
 };
 
 /* =====================================================================
@@ -139,8 +155,11 @@
 struct pcibr_intr_wrap_s {
     pcibr_soft_t            iw_soft;	/* which bridge */
     volatile bridgereg_t   *iw_stat;	/* ptr to b_int_status */
-    bridgereg_t             iw_intr;	/* bits in b_int_status */
+    bridgereg_t             iw_intr;	/* bit in b_int_status */
     pcibr_intr_list_t       iw_list;	/* ghostbusters! */
+    int			    iw_hdlrcnt;	/* running handler count */
+    int			    iw_shared;  /* if Bridge bit is shared */
+    int			    iw_connected; /* if already connected */
 };
 
 #define	PCIBR_ISR_ERR_START	8
@@ -175,11 +194,14 @@
 
     unsigned                bs_dma_flags;	/* revision-implied DMA flags */
 
+    l1sc_t                 *bs_l1sc;            /* io brick l1 system cntr */
+    moduleid_t		    bs_moduleid;	/* io brick moduleid */
+
     /*
      * Lock used primarily to get mutual exclusion while managing any
      * bridge resources..
      */
-    lock_t                  bs_lock;
+    spinlock_t              bs_lock;
     
     devfs_handle_t	    bs_noslot_conn;	/* NO-SLOT connection point */
     pcibr_info_t	    bs_noslot_info;
@@ -199,6 +221,9 @@
 	int                     has_host;
 	pciio_slot_t            host_slot;
 	devfs_handle_t		slot_conn;
+
+	int			slot_status;
+
 	/* Potentially several connection points
 	 * for this slot. bss_ninfo is how many,
 	 * and bss_infos is a pointer to
@@ -265,7 +290,7 @@
 	/* Shadow information used for implementing
 	 * Bridge Hardware WAR #484930
 	 */
-	int			bss_ext_ates_active;
+	atomic_t		bss_ext_ates_active;
         volatile unsigned      *bss_cmd_pointer;
 	unsigned		bss_cmd_shadow;
 
@@ -295,13 +320,10 @@
 	 */
 	xtalk_intr_t            bsi_xtalk_intr;
 	/*
-	 * We do not like sharing PCI interrrupt lines
-	 * between devices, but the Origin 200 PCI
-	 * layout forces us to do so.
+	 * A wrapper structure is associated with each
+	 * Bridge interrupt bit.
 	 */
-	pcibr_intr_list_t       bsi_pcibr_intr_list;
-	pcibr_intr_wrap_t       bsi_pcibr_intr_wrap;
-	int                     bsi_pcibr_wrap_set;
+	struct pcibr_intr_wrap_s  bsi_pcibr_intr_wrap;
 
     } bs_intr[8];
 
@@ -325,7 +347,7 @@
      */
     struct br_errintr_info {
 	int                     bserr_toutcnt;
-#ifdef IRIX
+#ifdef LATER
 	toid_t                  bserr_toutid;	/* Timeout started by errintr */
 #endif
 	iopaddr_t               bserr_addr;	/* Address where error occurred */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/pci/pciio.h linux/include/asm-ia64/sn/pci/pciio.h
--- v2.4.3/linux/include/asm-ia64/sn/pci/pciio.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/pci/pciio.h	Thu Apr  5 12:51:47 2001
@@ -35,15 +35,9 @@
 
 #define PCIIO_DEVICE_ID_NONE	-1
 
-#ifdef colin
-typedef char pciio_bus_t;	/* PCI bus number (0..255) */
-typedef char pciio_slot_t;	/* PCI slot number (0..31, 255) */
-typedef char pciio_function_t;	/* PCI func number (0..7, 255) */
-#else
 typedef uint8_t pciio_bus_t;       /* PCI bus number (0..255) */
 typedef uint8_t pciio_slot_t;      /* PCI slot number (0..31, 255) */
 typedef uint8_t pciio_function_t;  /* PCI func number (0..7, 255) */
-#endif
 
 #define	PCIIO_SLOTS		((pciio_slot_t)32)
 #define	PCIIO_FUNCS		((pciio_function_t)8)
@@ -446,6 +440,24 @@
 			 pciio_space_t *spacep,
 			 iopaddr_t *addrp);
 
+typedef void
+pciio_driver_reg_callback_f	(devfs_handle_t conn,
+				int key1,
+				int key2,
+				int error);
+
+typedef void
+pciio_driver_unreg_callback_f	(devfs_handle_t conn, /* pci connection point */
+				 int key1,
+				 int key2,
+				 int error);
+
+typedef int
+pciio_device_unregister_f	(devfs_handle_t conn);
+
+typedef int
+pciio_dma_enabled_f		(devfs_handle_t conn);
+
 /*
  * Adapters that provide a PCI interface adhere to this software interface.
  */
@@ -491,6 +503,12 @@
     /* Error handling interface */
     pciio_error_devenable_f *error_devenable;
     pciio_error_extract_f *error_extract;
+
+    /* Callback support */
+    pciio_driver_reg_callback_f *driver_reg_callback;
+    pciio_driver_unreg_callback_f *driver_unreg_callback;
+    pciio_device_unregister_f 	*device_unregister;
+    pciio_dma_enabled_f		*dma_enabled;
 } pciio_provider_t;
 
 /* PCI devices use these standard PCI provider interfaces */
@@ -540,13 +558,8 @@
 #define PCIIO_WIDGETDEV_SLOT_MASK		0x1f
 #define PCIIO_WIDGETDEV_FUNC_MASK		0x7
 
-#ifdef IRIX
-#define pciio_widgetdev_create(slot,func)	\
-	((slot) << PCIIO_WIDGETDEV_SLOT_SHFT + (func))
-#else
 #define pciio_widgetdev_create(slot,func)       \
         (((slot) << PCIIO_WIDGETDEV_SLOT_SHFT) + (func))
-#endif
 
 #define pciio_widgetdev_slot_get(wdev)		\
 	(((wdev) >> PCIIO_WIDGETDEV_SLOT_SHFT) & PCIIO_WIDGETDEV_SLOT_MASK)
@@ -612,8 +625,14 @@
 			pciio_info_t pciio_info);	/* details about conn point */
 
 
-extern int              pciio_device_attach(devfs_handle_t pcicard);	/* vertex created by pciio_device_register */
-extern int             pciio_device_detach(devfs_handle_t pcicard);	/* vertex created by pciio_device_register */
+extern int              
+pciio_device_attach(
+			devfs_handle_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 */
+                        int drv_flags);
 
 /*
  * Generic PCI interface, for use with all PCI providers
@@ -632,7 +651,7 @@
 extern ulong            pciio_pio_mapsz_get(pciio_piomap_t pciio_piomap);
 extern caddr_t          pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap);
 
-#ifdef IRIX
+#ifdef LATER
 #ifdef USE_PCI_PIO
 extern uint8_t 		pciio_pio_read8(volatile uint8_t *addr);
 extern uint16_t 	pciio_pio_read16(volatile uint16_t *addr);
@@ -676,7 +695,7 @@
 	*addr = val;
 }
 #endif /* USE_PCI_PIO */
-#endif
+#endif	/* LATER */
 
 /* Generic PCI dma interfaces */
 extern devfs_handle_t     pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap);
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/pci/pciio_private.h linux/include/asm-ia64/sn/pci/pciio_private.h
--- v2.4.3/linux/include/asm-ia64/sn/pci/pciio_private.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/pci/pciio_private.h	Thu Apr  5 12:51:47 2001
@@ -10,10 +10,6 @@
 #ifndef _ASM_SN_PCI_PCIIO_PRIVATE_H
 #define _ASM_SN_PCI_PCIIO_PRIVATE_H
 
-#ifdef colin
-#include <ksys/xthread.h>
-#endif
-
 /*
  * pciio_private.h -- private definitions for pciio
  * PCI drivers should NOT include this file.
@@ -54,12 +50,12 @@
     pciio_intr_line_t       pi_lines;	/* which interrupt line(s) */
     intr_func_t             pi_func;	/* handler function (when connected) */
     intr_arg_t              pi_arg;	/* handler parameter (when connected) */
-#ifdef IRIX
+#ifdef LATER
     thd_int_t               pi_tinfo;	/* Thread info (when connected) */
 #endif
     cpuid_t                 pi_mustruncpu; /* Where we must run. */
-    int			    pi_irq;	/* IRQ assigned */
-    int			    pi_cpu;	/* cpu assigned */
+    int                     pi_irq;     /* IRQ assigned */
+    int                     pi_cpu;     /* cpu assigned */
 };
 
 /* PCIIO_INTR (pi_flags) flags */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/pio.h linux/include/asm-ia64/sn/pio.h
--- v2.4.3/linux/include/asm-ia64/sn/pio.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/pio.h	Thu Apr  5 12:51:47 2001
@@ -33,7 +33,7 @@
 typedef struct piomap {
 	uint		pio_bus;
 	uint		pio_adap;
-#ifdef IRIX
+#ifdef LATER
 	iospace_t	pio_iospace;
 #endif
 	int		pio_flag;
@@ -41,7 +41,7 @@
 	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 IRIX
+#ifdef LATER
 	void		(*pio_errfunc)(); /* Pointer to an error function */
 					  /* Used only for piomaps allocated
 					   * in user level vme driver     */
@@ -50,6 +50,10 @@
 	iobush_t	pio_bushandle;	/* bus-level handle */
 } piomap_t;
 
+#define pio_type	pio_iospace.ios_type
+#define pio_iopaddr	pio_iospace.ios_iopaddr
+#define pio_size	pio_iospace.ios_size
+#define pio_vaddr	pio_iospace.ios_vaddr
 
 /* Macro to get/set PIO error function */
 #define	pio_seterrf(p,f)	(p)->pio_errfunc = (f)
@@ -64,7 +68,7 @@
  * 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 IRIX
+#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);
@@ -101,7 +105,7 @@
 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	/* IRIX */
+#endif	/* LATER */
 
 
 /*
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/router.h linux/include/asm-ia64/sn/router.h
--- v2.4.3/linux/include/asm-ia64/sn/router.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/router.h	Thu Apr  5 12:51:47 2001
@@ -11,6 +11,7 @@
 #define _ASM_SN_ROUTER_H
 
 #include <linux/config.h>
+
 #if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
 #include <asm/sn/sn1/router.h>
 #endif
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sgi.h linux/include/asm-ia64/sn/sgi.h
--- v2.4.3/linux/include/asm-ia64/sn/sgi.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/sgi.h	Thu Apr  5 12:51:47 2001
@@ -13,6 +13,7 @@
 #define _ASM_SN_SGI_H
 
 #include <linux/config.h>
+
 #include <asm/sn/types.h>
 #include <asm/uaccess.h>		/* for copy_??_user */
 #include <linux/mm.h>
@@ -121,18 +122,6 @@
 	GRAPH_IN_USE		/* 7 */
 } graph_error_t;
 
-#define SV_FIFO         0x0             /* sv_t is FIFO type */
-#define SV_LIFO         0x2             /* sv_t is LIFO type */
-#define SV_PRIO         0x4             /* sv_t is PRIO type */
-#define SV_KEYED        0x6             /* sv_t is KEYED type */
-#define SV_DEFAULT      SV_FIFO
-
-
-#define MUTEX_DEFAULT	0x0		/* needed by mutex_init() calls */
-#define PZERO		25		/* needed by mutex_lock(), sv_wait()
-					 * psema() calls */
-
-#define sema_t  uint64_t		/* FIXME */
 #define KM_SLEEP   0x0000
 #define KM_NOSLEEP 0x0001		/* needed by kmem_alloc_node(), kmem_zalloc()
 					 * calls */
@@ -140,10 +129,6 @@
 					 * calls */
 #define XG_WIDGET_PART_NUM      0xC102          /* KONA/xt_regs.h     XG_XT_PART_NUM_VALUE */
 
-#ifndef K1BASE
-#define K1BASE 0xA0000000
-#endif
-
 #ifndef TO_PHYS_MASK
 #define TO_PHYS_MASK 0x0000000fffffffff
 #endif
@@ -171,8 +156,6 @@
 #define _PAGESZ 4096
 #endif
 
-typedef uint64_t k_machreg_t;	/* needed by cmn_err.h */
-
 typedef uint64_t mrlock_t;	/* needed by devsupport.c */
 
 #define HUB_PIO_CONVEYOR 0x1
@@ -188,44 +171,64 @@
 #define POFFMASK		(NBPP - 1)
 #define poff(X)			((__psunsigned_t)(X) & POFFMASK)
 
-#define initnsema(a,b,c) 	sema_init(a,b)
-
 #define BZERO(a,b)		memset(a, 0, b)
 
-#define kern_malloc(x)	kmalloc(x, GFP_KERNEL)
-#define kern_free(x)	kfree(x)
+#define kern_malloc(x)		kmalloc(x, GFP_KERNEL)
+#define kern_free(x)		kfree(x)
 
 typedef cpuid_t cpu_cookie_t;
 #define CPU_NONE		-1
 
+/*
+ * mutext support mapping
+ */
+
+#define mutex_spinlock_init(s)	spin_lock_init(s)
+inline static unsigned long
+mutex_spinlock(spinlock_t *sem) {
+	unsigned long flags = 0;
+//	spin_lock_irqsave(sem, flags);
+	spin_lock(sem);
+	return(flags);
+}
+// #define mutex_spinunlock(s,t)	spin_unlock_irqrestore(s,t)
+#define mutex_spinunlock(s,t)	spin_unlock(s)
+
+
+#define mutex_t			struct semaphore
+#define mutex_init(s)		init_MUTEX(s)
+#define mutex_init_locked(s)	init_MUTEX_LOCKED(s)
+#define mutex_lock(s)		down(s)
+#define mutex_unlock(s)		up(s)
+
+#define io_splock(s)		mutex_spinlock(s)
+#define io_spunlock(s,t)	spin_unlock(s)
+
+#define spin_lock_destroy(s)
 
 #if defined(DISABLE_ASSERT)
 #define ASSERT(expr)
 #define ASSERT_ALWAYS(expr)
 #else
-#define ASSERT(expr)	\
+#define ASSERT(expr)  do {	\
         if(!(expr)) { \
 		printk( "Assertion [%s] failed! %s:%s(line=%d)\n",\
 			#expr,__FILE__,__FUNCTION__,__LINE__); \
 		panic("Assertion panic\n"); 	\
-        }
+        } } while(0)
 
-#define ASSERT_ALWAYS(expr)	\
+#define ASSERT_ALWAYS(expr)	do {\
         if(!(expr)) { \
 		printk( "Assertion [%s] failed! %s:%s(line=%d)\n",\
 			#expr,__FILE__,__FUNCTION__,__LINE__); \
 		panic("Assertion always panic\n"); 	\
-        }
+        } } while(0)
 #endif	/* DISABLE_ASSERT */
 
-/* These are defined as cmn_err() replacements */
-#define PRINT_WARNING(x...)	{ printk("WARNING : "); printk(x); }
-#define PRINT_NOTICE(x...)	{ printk("NOTICE : "); printk(x); }
-#define PRINT_ALERT(x...)	{ printk("ALERT : "); printk(x); }
+#define PRINT_WARNING(x...)	do { printk("WARNING : "); printk(x); } while(0)
+#define PRINT_NOTICE(x...)	do { printk("NOTICE : "); printk(x); } while(0)
+#define PRINT_ALERT(x...)	do { printk("ALERT : "); printk(x); } while(0)
 #define PRINT_PANIC		panic
-
-#define mutex_t int
-#define spinlock_init(x,name) mutex_init(x, MUTEX_DEFAULT, name);
 
 #ifdef CONFIG_SMP
 #define cpu_enabled(cpu)        (test_bit(cpu, &cpu_online_map))
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/slotnum.h linux/include/asm-ia64/sn/slotnum.h
--- v2.4.3/linux/include/asm-ia64/sn/slotnum.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/slotnum.h	Thu Apr  5 12:51:47 2001
@@ -10,9 +10,10 @@
 #ifndef _ASM_SN_SLOTNUM_H
 #define _ASM_SN_SLOTNUM_H
 
+#include <linux/config.h>
+
 typedef	unsigned char slotid_t;
 
-#include <linux/config.h>
 #if defined (CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 #include <asm/sn/sn1/slotnum.h>
 #else
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn1/addrs.h linux/include/asm-ia64/sn/sn1/addrs.h
--- v2.4.3/linux/include/asm-ia64/sn/sn1/addrs.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/sn1/addrs.h	Thu Apr  5 12:51:47 2001
@@ -43,22 +43,19 @@
 #if defined(_RUN_UNCACHED)
 #define CAC_BASE		0x9600000000000000
 #else
+#ifndef __ia64
 #define CAC_BASE		0xa800000000000000
+#else
+#define CAC_BASE                0xe000000000000000
+#endif
 #endif
 
-#ifdef Colin
-#define HSPEC_BASE		0x9000000000000000
-#define IO_BASE			0x9200000000000000
-#define MSPEC_BASE		0x9400000000000000
-#define UNCAC_BASE		0x9600000000000000
-#else
 #define HSPEC_BASE              0xc0000b0000000000
 #define HSPEC_SWIZ_BASE         0xc000030000000000
 #define IO_BASE                 0xc0000a0000000000
 #define IO_SWIZ_BASE            0xc000020000000000
 #define MSPEC_BASE              0xc000000000000000
 #define UNCAC_BASE              0xc000000000000000
-#endif
 
 #define TO_PHYS(x)		(	      ((x) & TO_PHYS_MASK))
 #define TO_CAC(x)		(CAC_BASE   | ((x) & TO_PHYS_MASK))
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn1/bedrock.h linux/include/asm-ia64/sn/sn1/bedrock.h
--- v2.4.3/linux/include/asm-ia64/sn/sn1/bedrock.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/sn1/bedrock.h	Thu Apr  5 12:51:47 2001
@@ -11,6 +11,8 @@
 #ifndef _ASM_SN_SN1_BEDROCK_H
 #define _ASM_SN_SN1_BEDROCK_H
 
+#include <linux/config.h>
+
 /* The secret password; used to release protection */
 #define HUB_PASSWORD		0x53474972756c6573ull
 
@@ -22,7 +24,6 @@
 
 #define MAX_HUB_PATH		80
 
-#include <linux/config.h>
 #if defined(CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
 #include <asm/sn/arch.h>
 #include <asm/sn/sn1/addrs.h>
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn1/hubio_next.h linux/include/asm-ia64/sn/sn1/hubio_next.h
--- v2.4.3/linux/include/asm-ia64/sn/sn1/hubio_next.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/sn1/hubio_next.h	Thu Apr  5 12:51:47 2001
@@ -43,6 +43,8 @@
 #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
@@ -192,6 +194,21 @@
 #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.
@@ -245,6 +262,29 @@
 #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 */
@@ -363,6 +403,10 @@
 /* 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
@@ -385,7 +429,6 @@
 
 #define IO_PERF_SETS	32
 
-#ifdef BRINGUP
 #if __KERNEL__
 #if _LANGUAGE_C
 /* XXX moved over from SN/SN0/hubio.h -- each should be checked for SN1 */
@@ -646,6 +689,11 @@
                 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);
 
@@ -710,5 +758,4 @@
 
 #endif /* _LANGUAGE_C */
 #endif /* _KERNEL */
-#endif /* BRINGUP */
 #endif  /* _ASM_SN_SN1_HUBIO_NEXT_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn1/hubpi_next.h linux/include/asm-ia64/sn/sn1/hubpi_next.h
--- v2.4.3/linux/include/asm-ia64/sn/sn1/hubpi_next.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/sn1/hubpi_next.h	Thu Apr  5 12:51:47 2001
@@ -274,7 +274,9 @@
  * The following three macros define all possible error int pends. 
  */
 
-#define PI_FATAL_ERR_CPU_A	(PI_ERR_SYSAD_BAD_DATA_A | \
+#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 	| \
@@ -283,17 +285,17 @@
 				 PI_ERR_SYSAD_DATA_A	| \
 				 PI_ERR_SYSSTATE_A)
 
-#define PI_MISC_ERR_CPU_A	(PI_ERR_IRB_TIMEOUT_A   | \
-				 PI_ERR_IRB_ERR_A       | \
-				 PI_ERR_PKT_LEN_ERR_A   | \
-				 PI_ERR_UE_CACHED_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_SYSAD_BAD_DATA_B | \
+#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 	| \
@@ -302,11 +304,9 @@
 				 PI_ERR_SYSAD_DATA_B	| \
 				 PI_ERR_SYSSTATE_B)
 
-#define PI_MISC_ERR_CPU_B 	(PI_ERR_IRB_TIMEOUT_B   | \
-				 PI_ERR_IRB_ERR_B       | \
-				 PI_ERR_PKT_LEN_ERR_B   | \
-				 PI_ERR_UE_CACHED_B     | \
-				 PI_ERR_UNCAC_UNCORR_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 	| \
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn1/hubxb_next.h linux/include/asm-ia64/sn/sn1/hubxb_next.h
--- v2.4.3/linux/include/asm-ia64/sn/sn1/hubxb_next.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/sn1/hubxb_next.h	Thu Apr  5 12:51:47 2001
@@ -28,5 +28,6 @@
 
 /* XB_PARMS fields */
 #define XBP_RESET_DEFAULTS	0x0008000080000021LL
+#define XBP_ACTIVE_DEFAULTS	0x00080000fffff021LL
 
 #endif	/* _ASM_SN_SN1_HUBXB_NEXT_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn1/ip27config.h linux/include/asm-ia64/sn/sn1/ip27config.h
--- v2.4.3/linux/include/asm-ia64/sn/sn1/ip27config.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/sn1/ip27config.h	Thu Apr  5 12:51:47 2001
@@ -188,6 +188,10 @@
 #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)
@@ -375,6 +379,7 @@
 	 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)	 + \
@@ -503,12 +508,7 @@
  * for building hex images (as required by start.s)
  */
 #ifdef IP27_CONFIG_SN00_4MB_100_200_133
-#ifdef IRIX
-/* Set PrcReqMax to 0 to reduce memory problems */
-#define	BRINGUP_PRM_VAL	0
-#else
 #define	BRINGUP_PRM_VAL	3
-#endif
 #define CONFIG_CPU_MODE \
 	(IP27C_R10000_KSEG0CA(5) + \
 	 IP27C_R10000_DEVNUM(0)	 + \
@@ -593,6 +593,7 @@
 	 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)	 + \
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn1/leds.h linux/include/asm-ia64/sn/sn1/leds.h
--- v2.4.3/linux/include/asm-ia64/sn/sn1/leds.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/sn1/leds.h	Thu Apr  5 12:51:47 2001
@@ -25,7 +25,7 @@
 	long	*ledp;
 	int	eid;
 
-	eid = hard_processor_sapicid() & 3;
+	eid = hard_smp_processor_id() & 3;
 	ledp = (long*) (LED0 + (eid<<3));
 	*ledp = val;
 }
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn1/router.h linux/include/asm-ia64/sn/sn1/router.h
--- v2.4.3/linux/include/asm-ia64/sn/sn1/router.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/sn1/router.h	Thu Apr  5 12:51:47 2001
@@ -513,7 +513,7 @@
 #ifdef DEBUG
 	int64_t	ri_deltatime;	/* Time it took to sample	    */
 #endif
-	lock_t		ri_lock;	/* Lock for access to router info   */
+	spinlock_t	ri_lock;	/* Lock for access to router info   */
 	net_vec_t	*ri_vecarray;	/* Pointer to array of vectors	    */
 	struct lboard_s	*ri_brd;	/* Pointer to board structure	    */
 	char *		ri_name;	/* This board's hwg path 	    */
@@ -566,6 +566,7 @@
 #define NORMAL_ROUTER_NAME	"normal_router"
 #define NULL_ROUTER_NAME	"null_router"
 #define META_ROUTER_NAME	"meta_router"
+#define REPEATER_ROUTER_NAME	"repeater_router"
 #define UNKNOWN_ROUTER_NAME	"unknown_router" 
 
 /* The following definitions are needed by the router traversing
@@ -630,7 +631,7 @@
  */
 
 #define RRM_RESETOK(_L)		(UINT64_CAST 1 << ((_L) - 1))
-#define RRM_RESETOK_ALL		(UINT64_CAST 0x3f)
+#define RRM_RESETOK_ALL		ALL_PORTS
 
 /*
  * RR_META_TABLE(_x) and RR_LOCAL_TABLE(_x) mask and shift definitions
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn1/slotnum.h linux/include/asm-ia64/sn/sn1/slotnum.h
--- v2.4.3/linux/include/asm-ia64/sn/sn1/slotnum.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/sn1/slotnum.h	Thu Apr  5 12:51:47 2001
@@ -14,8 +14,7 @@
 #define SLOTNUM_MAXLENGTH	16
 
 /*
- * This file attempts to define a slot number space across all slots
- * a IP27 module.  Here, we deal with the top level slots.
+ * This file attempts to define a slot number space across all slots.
  *
  *	Node slots
  *	Router slots
@@ -24,16 +23,20 @@
  *	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.
  */
-// #include <slotnum.h>
 
-// #ifdef NOTDEF	/* moved to sys/slotnum.h */
 #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
@@ -41,7 +44,6 @@
 
 #define SLOTNUM_GETCLASS(_sn)	((_sn) & SLOTNUM_CLASS_MASK)
 #define SLOTNUM_GETSLOT(_sn)	((_sn) & SLOTNUM_SLOT_MASK)
-// #endif	/* NOTDEF */
 
 /* This determines module to pnode mapping. */
 /* NODESLOTS_PER_MODULE has changed from 4 to 6
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn1/uart16550.h linux/include/asm-ia64/sn/sn1/uart16550.h
--- v2.4.3/linux/include/asm-ia64/sn/sn1/uart16550.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/sn1/uart16550.h	Thu Apr  5 12:51:47 2001
@@ -1,3 +1,16 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2000 by Colin Ngam
+ */
+
+#ifndef _ASM_SN_SN1_UART16550_H
+#define _ASM_SN_SN1_UART16550_H
+
 
 /*
  * Definitions for 16550  chip
@@ -212,3 +225,4 @@
 #define INC_RING_POINTER(x) \
 	( ((x & 0xffe0) < 4064) ? (x += 32) : 0 )
 
+#endif /* _ASM_SN_SN1_UART16550_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn1/war.h linux/include/asm-ia64/sn/sn1/war.h
--- v2.4.3/linux/include/asm-ia64/sn/sn1/war.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/sn1/war.h	Wed Dec 31 16:00:00 1969
@@ -1,25 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-#ifndef _ASM_SN_SN1_WAR_H
-#define _ASM_SN_SN1_WAR_H
-
-/****************************************************************************
- * Support macros and defitions for hardware workarounds in		    *
- * early chip versions.                                                     *
- ****************************************************************************/
-
-/*
- * This is the bitmap of runtime-switched workarounds.
- */
-typedef short warbits_t;
-
-extern int warbits_override;
-
-#endif /*  _ASM_SN_SN1_WAR_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn_cpuid.h linux/include/asm-ia64/sn/sn_cpuid.h
--- v2.4.3/linux/include/asm-ia64/sn/sn_cpuid.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/sn_cpuid.h	Thu Apr  5 12:51:47 2001
@@ -13,6 +13,7 @@
 #define _ASM_IA64_SN_SN_CPUID_H
 
 #include <linux/config.h>
+#include <asm/processor.h>
 #include <asm/sn/mmzone_sn1.h>
 
 /*
@@ -26,18 +27,35 @@
 
 
 /*
- * The following assumes the following mappings for LID register values:
+ *  Definitions of terms (these definitions are for IA64 ONLY. Other architectures
+ *  use cpuid/cpunum quite defferently):
+ *
+ *	   CPUID - a number in range of 0..NR_CPUS-1 that uniquely identifies
+ *		the cpu. The value cpuid has no significance on IA64 other than
+ *		the boot cpu is 0.
+ *			smp_processor_id() returns the cpuid of the current cpu.
+ *
+ *	   CPUNUM - On IA64, a cpunum and cpuid are the same. This is NOT true
+ *		on other architectures like IA32.
+ *
+ * 	   CPU_PHYSICAL_ID (also known as HARD_PROCESSOR_ID)
+ *		This is the same as 31:24 of the processor LID register
+ *			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
  *
- *         LID
+ *         LID - processor defined register (see PRM V2).
  *		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 number 
+ *				bit 16 - FSB slot number 
+ *
  *
- * 	   SAPICID
- *		This is the same as 31:24 of LID
  *
- * The macros convert between cpuid & slice/fsb/synergy/nasid/cnodeid.
+ * The following assumes the following mappings for LID register values:
+ *
+ * The macros convert between cpu physical ids & slice/fsb/synergy/nasid/cnodeid.
  * These terms are described below:
  *
  *
@@ -46,7 +64,7 @@
  *          -----   -----           -----   -----
  *            |       |               |       |
  *            |       |               |       |
- *          0 |       | 1           0 |       | 1       FSB
+ *          0 |       | 1           0 |       | 1       FSB SLOT
  *             -------                 -------  
  *                |                       |
  *                |                       |
@@ -68,25 +86,27 @@
  *
  */
 
+#ifndef CONFIG_SMP
+#define cpu_logical_id(cpu)				0
+#define cpu_physical_id(cpuid)			((ia64_get_lid() >> 16) & 0xffff)
+#endif
 
-
-#define sapicid_to_nasid(sid)		((sid) >> 8)
-#define sapicid_to_synergy(sid)		(((sid) >> 1) & 1)
-#define sapicid_to_fsb(sid)		((sid) & 1)
-#define sapicid_to_slice(sid)		((sid) & 3)
+#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)
 
 /*
  * NOTE: id & eid refer to Intels definitions of the LID register
  *	(id = NASID, eid = slice)
  * NOTE: on non-MP systems, only cpuid 0 exists
  */
-#define id_eid_to_sapicid(id,eid)       (((id)<<8) | (eid))
-#define id_eid_to_cpuid(id,eid)         ((NASID_TO_CNODEID(id)<<2) | (eid))
+#define id_eid_to_cpu_physical_id(id,eid)       (((id)<<8) | (eid))
+#define id_eid_to_cpuid(id,eid)         	(cpu_logical_id(id_eid_to_cpu_physical_id((id),(eid))))
 
 
 /*
- * The following table/struct is for translating between sapicid and cpuids.
- * It is also used for managing PTC coherency domains.
+ * The following table/struct  is used for managing PTC coherency domains.
  */
 typedef struct {
 	u8	domain;
@@ -99,28 +119,13 @@
 
 
 /*
- * cpuid_to_spaicid  - Convert a cpuid to a SAPIC id of the cpu. 
- * The SAPIC id is the same as bits 31:16 of the LID register.
- */
-static __inline__ int
-cpuid_to_spaicid(int cpuid)
-{
-#ifdef CONFIG_SMP
-	return cpu_physical_id(cpuid);
-#else
-	return ((ia64_get_lid() >> 16) & 0xffff);
-#endif
-}
-
-
-/*
  * cpuid_to_fsb_slot  - convert a cpuid to the fsb slot number that it is in.
  *   (there are 2 cpus per FSB. This function returns 0 or 1)
  */
 static __inline__ int
 cpuid_to_fsb_slot(int cpuid)
 {
-	return sapicid_to_fsb(cpuid_to_spaicid(cpuid));
+	return cpu_physical_id_to_fsb_slot(cpu_physical_id(cpuid));
 }
 
 
@@ -132,7 +137,7 @@
 static __inline__ int
 cpuid_to_synergy(int cpuid)
 {
-	return sapicid_to_synergy(cpuid_to_spaicid(cpuid));
+	return cpu_physical_id_to_synergy(cpu_physical_id(cpuid));
 }
 
 
@@ -143,7 +148,7 @@
 static __inline__ int
 cpuid_to_slice(int cpuid)
 {
-	return sapicid_to_slice(cpuid_to_spaicid(cpuid));
+	return cpu_physical_id_to_slice(cpu_physical_id(cpuid));
 }
 
 
@@ -153,7 +158,7 @@
 static __inline__ int
 cpuid_to_nasid(int cpuid)
 {
-	return sapicid_to_nasid(cpuid_to_spaicid(cpuid));
+	return cpu_physical_id_to_nasid(cpu_physical_id(cpuid));
 }
 
 
@@ -166,23 +171,42 @@
 	return nasid_map[cpuid_to_nasid(cpuid)];
 }
 
+/*
+ * cnodeid_to_nasid - convert a cnodeid to a NASID
+ */
 static __inline__ int
 cnodeid_to_nasid(int cnodeid)
 {
-	int i;
-	for (i = 0; i < MAXNASIDS; i++) {
-		if (nasid_map[i] == cnodeid) {
-			return(i);
-		}
-	}
-	return(-1);
+	if (nasid_map[cnodeid_map[cnodeid]] != cnodeid)
+		panic("cnodeid_to_nasid, cnode = %d", cnodeid);
+	return cnodeid_map[cnodeid];
 }
 
+/*
+ * nasid_to_cnodeid - convert a NASID to a cnodeid
+ */
+static __inline__ int
+nasid_to_cnodeid(int nasid)
+{
+	if (cnodeid_map[nasid_map[nasid]] != nasid)
+		panic("nasid_to_cnodeid");
+	return nasid_map[nasid];
+}
+
+
+/*
+ * cnode_slice_to_cpuid - convert a codeid & slice to a cpuid
+ */
 static __inline__ int
 cnode_slice_to_cpuid(int cnodeid, int slice) {
 	return(id_eid_to_cpuid(cnodeid_to_nasid(cnodeid),slice));
 }
 
+/*
+ * cpuid_to_subnode - convert a cpuid to the subnode it resides on.
+ *   slice 0 & 1 are on subnode 0
+ *   slice 2 & 3 are on subnode 1.
+ */
 static __inline__ int
 cpuid_to_subnode(int cpuid) {
 	int ret = cpuid_to_slice(cpuid);
@@ -190,9 +214,27 @@
 	else return 1;
 }
 
+/*
+ * cpuid_to_localslice - convert a cpuid to a local slice
+ *    slice 0 & 2 are local slice 0
+ *    slice 1 & 3 are local slice 1
+ */
 static __inline__ int
 cpuid_to_localslice(int cpuid) {
 	return(cpuid_to_slice(cpuid) & 1);
+}
+
+static __inline__ int
+cnodeid_to_cpuid(int cnode) {
+	int cpu;
+
+	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
+		if (cpuid_to_cnodeid(cpu) == cnode) {
+			break;
+		}
+	}
+	if (cpu == smp_num_cpus) cpu = -1;
+	return cpu;
 }
 
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn_fru.h linux/include/asm-ia64/sn/sn_fru.h
--- v2.4.3/linux/include/asm-ia64/sn/sn_fru.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/sn_fru.h	Thu Apr  5 12:51:47 2001
@@ -1,16 +1,14 @@
-/**************************************************************************
- *									  *
- *		 Copyright (C) 1992-1997, Silicon Graphics, Inc.	  *
- *									  *
- *  These coded instructions, statements, and computer programs	 contain  *
- *  unpublished	 proprietary  information of Silicon Graphics, Inc., and  *
- *  are protected by Federal copyright law.  They  may	not be disclosed  *
- *  to	third  parties	or copied or duplicated in any form, in whole or  *
- *  in part, without the prior written consent of Silicon Graphics, Inc.  *
- *									  *
- **************************************************************************/
-#ifndef __SYS_SN_SN0_FRU_H__
-#define __SYS_SN_SN0_FRU_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, 1999-2000 Silicon Graphics, Inc.
+ * Copyright (C) 2000 by Patrick Gefre
+ */
+#ifndef _ASM_SN_SN_FRU_H
+#define _ASM_SN_SN_FRU_H
 
 #define MAX_DIMMS			8	 /* max # of dimm banks */
 #define MAX_PCIDEV			8	 /* max # of pci devices on a pci bus */
@@ -44,6 +42,5 @@
 } kf_pci_bus_t;
 
 
-
-#endif /* #ifdef __SYS_SN_SN0_FRU_H__ */
+#endif	/* _ASM_SN_SN_FRU_H */
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn_private.h linux/include/asm-ia64/sn/sn_private.h
--- v2.4.3/linux/include/asm-ia64/sn/sn_private.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/sn_private.h	Thu Apr  5 12:51:47 2001
@@ -10,7 +10,6 @@
 #ifndef _ASM_SN_PRIVATE_H
 #define _ASM_SN_PRIVATE_H
 
-#include <linux/config.h>
 #include <asm/sn/nodepda.h>
 #include <asm/sn/xtalk/xwidget.h>
 #include <asm/sn/xtalk/xtalk_private.h>
@@ -20,12 +19,12 @@
 extern hubreg_t get_region(cnodeid_t);
 extern hubreg_t	nasid_to_region(nasid_t);
 /* promif.c */
-#ifndef CONFIG_IA64_SGI_IO
+#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);
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 extern int cpu_enabled(cpuid_t);
 #endif
 extern void cpu_unenable(cpuid_t);
@@ -35,7 +34,7 @@
 extern int check_nasid_equiv(nasid_t, nasid_t);
 extern nasid_t get_console_nasid(void);
 extern char get_console_pcislot(void);
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
 #endif
 
@@ -112,19 +111,19 @@
 
 /* init.c */
 extern cnodeid_t get_compact_nodeid(void);	/* get compact node id */
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 extern void init_platform_nodepda(nodepda_t *npda, cnodeid_t node);
 extern void init_platform_pda(pda_t *ppda, cpuid_t cpu);
 #endif
 extern void per_cpu_init(void);
 extern void per_hub_init(cnodeid_t);
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 extern cpumask_t boot_cpumask;
 #endif
 extern int is_fine_dirmode(void);
 extern void update_node_information(cnodeid_t);
  
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 /* clksupport.c */
 extern void early_counter_intr(eframe_t *);
 #endif
@@ -251,7 +250,7 @@
 /* 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 {
-#ifndef CONFIG_IA64_SGI_IO
+#ifdef	LATER
 	pda_t		*ci_cpupda;	/* pointer to CPU's private data area */
 #endif
 	cpuid_t		ci_cpuid;	/* CPU ID */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sn_sal.h linux/include/asm-ia64/sn/sn_sal.h
--- v2.4.3/linux/include/asm-ia64/sn/sn_sal.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ia64/sn/sn_sal.h	Thu Apr  5 12:51:47 2001
@@ -0,0 +1,25 @@
+#ifndef _ASM_IA64_SN_SAL_H
+#define _ASM_IA64_SN_SAL_H
+
+/*
+ * System Abstraction Layer definitions for IA64
+ *
+ *
+ * Copyright (C) 2000, Silicon Graphics.
+ * Copyright (C) 2000. Jack Steiner (steiner@sgi.com)
+ */
+
+
+#include <asm/sal.h>
+
+
+// SGI Specific Calls
+#define  SN_SAL_POD_MODE                           0x02000001
+#define  SN_SAL_SYSTEM_RESET                       0x02000002
+#define  SN_SAL_PROBE                              0x02000003
+
+
+u64 ia64_sn_probe_io_slot(long paddr, long size, void *data_ptr);
+
+
+#endif /* _ASM_IA64_SN_SN1_SAL_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/sv.h linux/include/asm-ia64/sn/sv.h
--- v2.4.3/linux/include/asm-ia64/sn/sv.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ia64/sn/sv.h	Thu Apr  5 12:51:47 2001
@@ -0,0 +1,153 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Silicon Graphics, Inc.  All rights reserved
+ *
+ * This implemenation of synchronization variables is heavily based on
+ * one done by Steve Lord <lord@sgi.com>
+ *
+ * Paul Cassella <pwc@sgi.com>
+ */
+
+#ifndef SV_H
+#define SV_H
+
+#include <linux/spinlock.h>
+#include <asm/semaphore.h>
+
+#ifndef ASSERT
+
+#define ASSERT(x) do {							  \
+                    if(!(x)) {						  \
+		      printk(KERN_ERR "%s\n", "Assertion failed: " # x);  \
+		      BUG();						  \
+		    }							  \
+                  } while(0)
+#define _SV_ASSERT
+#endif
+
+typedef void sv_mon_lock_t;
+typedef void (*sv_mon_unlock_func_t)(sv_mon_lock_t *lock);
+
+/* sv_flags values: */
+
+#define SV_ORDER_FIFO        0x001
+#define SV_ORDER_FILO        0x002
+#define SV_ORDER_LIFO        SV_ORDER_FILO
+
+/* If at some point one order becomes preferable to others, we can
+   switch to it if the caller of sv_init doesn't specify. */
+#define SV_ORDER_DEFAULT     SV_ORDER_FIFO
+
+#define SV_ORDER_MASK        0x00f
+
+
+#define SV_MON_SEMA          0x010
+#define SV_MON_SPIN          0x020
+
+#define SV_MON_MASK          0x0f0
+
+
+/*
+   If the monitor lock can be aquired from interrupts.  Note that this
+   is a superset of the cases in which the sv can be touched from
+   interrupts.
+
+   This is currently only valid when the monitor lock is a spinlock.
+
+   If this is used, sv_wait, sv_signal, and sv_broadcast must all be
+   called with interrupts disabled, which has to happen anyway to have
+   acquired the monitor spinlock. 
+ */
+#define SV_INTS              0x100
+
+/* ditto for bottom halves */
+#define SV_BHS               0x200
+
+
+
+/* sv_wait_flag values: */
+#define SV_WAIT_SIG          0x001 /* Allow sv_wait to be interrupted by a signal */
+
+typedef struct sv_s {
+	wait_queue_head_t sv_waiters;
+	sv_mon_lock_t *sv_mon_lock;   /* Lock held for exclusive access to monitor. */
+	sv_mon_unlock_func_t sv_mon_unlock_func;
+	spinlock_t sv_lock;  /* Spinlock protecting the sv itself. */
+	int sv_flags;
+} sv_t;
+
+#define DECLARE_SYNC_VARIABLE(sv, l, f) sv_t sv = sv_init(&sv, l, f)
+
+/* 
+ * @sv the sync variable to initialize
+ * @monitor_lock the lock enforcing exclusive running in the monitor
+ * @flags one of
+ *   SV_MON_SEMA monitor_lock is a semaphore
+ *   SV_MON_SPIN monitor_lock is a spinlock
+ * and a bitwise or of some subset of
+ *   SV_INTS - the monitor lock can be acquired from interrupts (and
+ *             hence, whenever we hold it, interrupts are disabled or
+ *             we're in an interrupt.)  This is only valid when
+ *             SV_MON_SPIN is set.
+ */
+void sv_init(sv_t *sv, sv_mon_lock_t *monitor_lock, int flags);
+
+/*
+ * 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.
+ *
+ * The associated lock must be locked on entry.  It is unlocked on return.
+ *
+ * Return values:
+ *
+ * n < 0 : interrupted,  -n jiffies remaining on timeout, or -1 if timeout == 0
+ * n = 0 : timeout expired
+ * n > 0 : sv_signal()'d, n jiffies remaining on timeout, or 1 if timeout == 0
+ */
+extern signed long sv_wait(sv_t *sv, int sv_wait_flags,
+			   unsigned long timeout /* relative jiffies */);
+
+static inline int sv_wait_compat(sv_t *sv, sv_mon_lock_t *lock, int sv_wait_flags,
+				 unsigned long timeout, int sv_mon_type)
+{
+	ASSERT(sv_mon_type == (sv->sv_flags & SV_MON_MASK));
+	if(sv->sv_mon_lock)
+		ASSERT(lock == sv->sv_mon_lock);
+	else
+		sv->sv_mon_lock = lock;
+
+	return sv_wait(sv, sv_wait_flags, timeout);
+}
+
+
+/* These work like Irix's sv_wait() and sv_wait_sig(), except the
+   caller must call the one correpsonding to the type of the monitor
+   lock. */
+#define sv_spin_wait(sv, lock)                              \
+        sv_wait_compat(sv, lock, 0, 0, SV_MON_SPIN)
+#define sv_spin_wait_sig(sv, lock)                          \
+        sv_wait_compat(sv, lock, SV_WAIT_SIG, 0, SV_MON_SPIN)
+
+#define sv_sema_wait(sv, lock)                              \
+        sv_wait_compat(sv, lock, 0, 0, SV_MON_SEMA)
+#define sv_sema_wait_sig(sv, lock)                          \
+        sv_wait_compat(sv, lock, SV_WAIT_SIG, 0, SV_MON_SEMA)
+
+/* These work as in Irix. */
+void sv_signal(sv_t *sv);
+void sv_broadcast(sv_t *sv);
+
+/* This works as in Irix. */
+void sv_destroy(sv_t *sv);
+
+#ifdef _SV_ASSERT
+#undef ASSERT
+#undef _SV_ASSERT
+#endif
+
+#endif
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/synergy.h linux/include/asm-ia64/sn/synergy.h
--- v2.4.3/linux/include/asm-ia64/sn/synergy.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/synergy.h	Thu Apr  5 12:51:47 2001
@@ -2,6 +2,7 @@
 #define ASM_IA64_SN_SYNERGY_H
 
 #include "asm/io.h"
+#include "asm/sn/nodepda.h"
 #include "asm/sn/intr_public.h"
 
 
@@ -41,47 +42,52 @@
 #define WRITE_LOCAL_SYNERGY_REG(addr, value)	__synergy_out(addr, value)
 
 #define HUBREG_CAST             (volatile hubreg_t *)
-#define NODE_OFFSET(_n)         (UINT64_CAST (_n) << NODE_SIZE_BITS)
-#define SYN_UNCACHED_SPACE      0xc000000000000000
-#define NODE_HSPEC_BASE(_n)     (HSPEC_BASE + NODE_OFFSET(_n))
-#define NODE_LREG_BASE(_n)      (NODE_HSPEC_BASE(_n) + 0x30000000)
-#define RREG_BASE(_n)           (NODE_LREG_BASE(_n))
+#define HUB_L(_a)               *(_a)
+#define HUB_S(_a, _d)           *(_a) = (_d)
+
+#define HSPEC_SYNERGY0_0        0x04000000    /* Synergy0 Registers     */
+#define HSPEC_SYNERGY1_0        0x05000000    /* Synergy1 Registers     */
+#define HS_SYNERGY_STRIDE       (HSPEC_SYNERGY1_0 - HSPEC_SYNERGY0_0)
 #define REMOTE_HSPEC(_n, _x)    (HUBREG_CAST (RREG_BASE(_n) + (_x)))
-#define    HSPEC_SYNERGY0_0          0x04000000    /* Synergy0 Registers     */
-#define    HSPEC_SYNERGY1_0          0x05000000    /* Synergy1 Registers     */
-#define HS_SYNERGY_STRIDE               (HSPEC_SYNERGY1_0 - HSPEC_SYNERGY0_0)
 
+#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 HUB_L(_a)                       *(_a)
-#define HUB_S(_a, _d)                   *(_a) = (_d)
 
+#define RSYN_REG_OFFSET(fsb, reg) (((fsb) ? HSPEC_SYNERGY1_0 : HSPEC_SYNERGY0_0) | (reg))
 
 #define REMOTE_SYNERGY_LOAD(nasid, fsb, reg)  __remote_synergy_in(nasid, fsb, reg)
 #define REMOTE_SYNERGY_STORE(nasid, fsb, reg, val) __remote_synergy_out(nasid, fsb, reg, val)
 
-extern inline void
-__remote_synergy_out(int nasid, int fsb, unsigned long reg, unsigned long val) {
-	unsigned long addr = ((RREG_BASE(nasid)) + 
-		((HSPEC_SYNERGY0_0 | (fsb)*HS_SYNERGY_STRIDE) | ((reg) << 2)));
-
-	HUB_S((unsigned long *)(addr),      (val) >> 48);
-	HUB_S((unsigned long *)(addr+0x08), (val) >> 32);
-	HUB_S((unsigned long *)(addr+0x10), (val) >> 16);
-	HUB_S((unsigned long *)(addr+0x18), (val)      );
-	__ia64_mf_a();
+extern inline uint64_t
+__remote_synergy_in(int nasid, int fsb, uint64_t reg) {
+	volatile uint64_t *addr;
+
+	addr = (uint64_t *)(RREG_BASE(nasid) + RSYN_REG_OFFSET(fsb, reg));
+	return (*addr);
 }
 
-extern inline unsigned long
-__remote_synergy_in(int nasid, int fsb, unsigned long reg) {
-	volatile unsigned long *addr = (unsigned long *) ((RREG_BASE(nasid)) + 
-		((HSPEC_SYNERGY0_0 | (fsb)*HS_SYNERGY_STRIDE) | (reg)));
-	unsigned long ret;
+extern inline void
+__remote_synergy_out(int nasid, int fsb, uint64_t reg, uint64_t value) {
+	volatile uint64_t *addr;
 
-	ret = *addr;
-	__ia64_mf_a();
-	return ret;
+        addr = (uint64_t *)(RREG_BASE(nasid) + RSYN_REG_OFFSET(fsb, (reg<<2)));
+        *(addr+0) = value >> 48;
+        *(addr+1) = value >> 32;
+        *(addr+2) = value >> 16;
+        *(addr+3) = value;
+        __ia64_mf_a();
 }
 
+/* XX this doesn't make a lot of sense. Which fsb?  */
 extern inline void
 __synergy_out(unsigned long addr, unsigned long value)
 {
@@ -94,6 +100,7 @@
 
 #define READ_LOCAL_SYNERGY_REG(addr)	__synergy_in(addr)
 
+/* XX this doesn't make a lot of sense. Which fsb? */
 extern inline unsigned long
 __synergy_in(unsigned long addr)
 {
@@ -120,7 +127,39 @@
 	spinlock_t action_list_lock;
 	struct sn1_intr_action *action_list;
 };
-	
+
+#if defined(CONFIG_IA64_SGI_SYNERGY_PERF)
+
+/* multiplex the counters every 10 timer interrupts */ 
+#define SYNERGY_PERF_FREQ_DEFAULT 10
+
+/* synergy perf control registers */
+#define PERF_CNTL0_A            0xab0UL /* control A on FSB0 */
+#define PERF_CNTL0_B            0xab8UL /* control B on FSB0 */
+#define PERF_CNTL1_A            0xac0UL /* control A on FSB1 */
+#define PERF_CNTL1_B            0xac8UL /* control B on FSB1 */
+
+/* synergy perf counters */
+#define PERF_CNTR0_A            0xad0UL /* counter A on FSB0 */
+#define PERF_CNTR0_B            0xad8UL /* counter B on FSB0 */
+#define PERF_CNTR1_A            0xaf0UL /* counter A on FSB1 */
+#define PERF_CNTR1_B            0xaf8UL /* counter B on FSB1 */
+
+/* Synergy perf data. Each nodepda keeps a list of these */
+struct synergy_perf_s {
+        uint64_t        intervals;      /* count of active intervals for this event */
+        uint64_t        modesel;        /* mode and sel bits, both A and B registers */
+        struct synergy_perf_s *next;	/* next in circular linked list */
+        uint64_t        counts[2];      /* [0] is synergy-A counter, [1] synergy-B counter */
+};
+
+typedef struct synergy_perf_s synergy_perf_t;
+
+extern void synergy_perf_init(void);
+extern void synergy_perf_update(int);
+
+#endif /* CONFIG_IA64_SGI_SYNERGY_PERF */
+
 
 /* Temporary defintions for testing: */
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/types.h linux/include/asm-ia64/sn/types.h
--- v2.4.3/linux/include/asm-ia64/sn/types.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/types.h	Thu Apr  5 12:51:47 2001
@@ -9,7 +9,6 @@
 #ifndef _ASM_SN_TYPES_H
 #define _ASM_SN_TYPES_H
 
-#include <linux/config.h>
 #include <linux/types.h>
 
 typedef unsigned long 	cpuid_t;
@@ -22,15 +21,12 @@
 typedef signed short	cmoduleid_t;	/* kernel compact module id type */
 typedef unsigned char	clusterid_t;	/* Clusterid of the cell */
 
-#if defined(CONFIG_IA64_SGI_IO)
 #define __psunsigned_t uint64_t
 #define lock_t uint64_t
-#define sv_t uint64_t
 
 typedef unsigned long iopaddr_t;
 typedef unsigned char uchar_t;
 typedef unsigned long paddr_t;
 typedef unsigned long pfn_t;
-#endif        /* CONFIG_IA64_SGI_IO */
 
 #endif /* _ASM_SN_TYPES_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/war.h linux/include/asm-ia64/sn/war.h
--- v2.4.3/linux/include/asm-ia64/sn/war.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/war.h	Wed Dec 31 16:00:00 1969
@@ -1,18 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
- */
-#ifndef _ASM_SN_WAR_H
-#define _ASM_SN_WAR_H
-
-#include <linux/config.h>
-#if defined (CONFIG_SGI_IP35) || defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#include <asm/sn/sn1/war.h>
-#endif
-
-#endif /* _ASM_SN_WAR_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/xtalk/xtalk.h linux/include/asm-ia64/sn/xtalk/xtalk.h
--- v2.4.3/linux/include/asm-ia64/sn/xtalk/xtalk.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/xtalk/xtalk.h	Thu Apr  5 12:51:47 2001
@@ -278,6 +278,7 @@
 
     /* INTERRUPT MANAGEMENT */
     xtalk_intr_alloc_f     *intr_alloc;
+    xtalk_intr_alloc_f     *intr_alloc_nothd;
     xtalk_intr_free_f      *intr_free;
     xtalk_intr_connect_f   *intr_connect;
     xtalk_intr_disconnect_f *intr_disconnect;
@@ -308,6 +309,7 @@
 extern xtalk_dmaaddr_drain_f xtalk_dmaaddr_drain;
 extern xtalk_dmalist_drain_f xtalk_dmalist_drain;
 extern xtalk_intr_alloc_f xtalk_intr_alloc;
+extern xtalk_intr_alloc_f xtalk_intr_alloc_nothd;
 extern xtalk_intr_free_f xtalk_intr_free;
 extern xtalk_intr_connect_f xtalk_intr_connect;
 extern xtalk_intr_disconnect_f xtalk_intr_disconnect;
@@ -342,10 +344,6 @@
 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 void            *xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr);
-
-extern int		xtalk_intr_flags_get(xtalk_intr_t xtalk_intr);
-/* XTALK_INTR flags */
-#define XTALK_INTR_NOTHREAD	1	/* interrupt handler wants to be called at interrupt level */
 
 /* Generic crosstalk pio interfaces */
 extern devfs_handle_t     xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap);
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/xtalk/xtalk_private.h linux/include/asm-ia64/sn/xtalk/xtalk_private.h
--- v2.4.3/linux/include/asm-ia64/sn/xtalk/xtalk_private.h	Thu Jan  4 13:00:15 2001
+++ linux/include/asm-ia64/sn/xtalk/xtalk_private.h	Thu Apr  5 12:51:47 2001
@@ -10,11 +10,7 @@
 #ifndef _ASM_SN_XTALK_XTALK_PRIVATE_H
 #define _ASM_SN_XTALK_XTALK_PRIVATE_H
 
-#ifdef IRIX
-#include <sys/ioerror.h>	/* for error function and arg types */
-#else
 #include <asm/sn/ioerror.h>        /* for error function and arg types */
-#endif
 
 /*
  * xtalk_private.h -- private definitions for xtalk
@@ -44,7 +40,6 @@
  * All Crosstalk providers set up interrupts using this information.
  */
 struct xtalk_intr_s {
-    int                     xi_flags;	/* XTALK_INTR flags */
     devfs_handle_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 */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/sn/xtalk/xtalkaddrs.h linux/include/asm-ia64/sn/xtalk/xtalkaddrs.h
--- v2.4.3/linux/include/asm-ia64/sn/xtalk/xtalkaddrs.h	Thu Jan  4 15:25:55 2001
+++ linux/include/asm-ia64/sn/xtalk/xtalkaddrs.h	Thu Apr  5 12:51:47 2001
@@ -10,6 +10,8 @@
 #ifndef _ASM_SN_XTALK_XTALKADDRS_H
 #define _ASM_SN_XTALK_XTALKADDRS_H
 
+#include <linux/config.h>
+
 /*
  * CrossTalk to SN0 Hub addressing support
  *
@@ -58,8 +60,6 @@
  * This looks very much like a REMOTE_HUB access, except the nodeID
  * is in a different place, and the highest xtalk bit is set.
  */
-
-#include <linux/config.h>
 
 /* Hub-specific xtalk definitions */
 
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/softirq.h linux/include/asm-ia64/softirq.h
--- v2.4.3/linux/include/asm-ia64/softirq.h	Fri Mar 10 15:24:02 2000
+++ linux/include/asm-ia64/softirq.h	Thu Apr  5 12:51:47 2001
@@ -2,17 +2,14 @@
 #define _ASM_IA64_SOFTIRQ_H
 
 /*
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #include <asm/hardirq.h>
 
-#define cpu_bh_disable(cpu)	do { local_bh_count(cpu)++; barrier(); } while (0)
-#define cpu_bh_enable(cpu)	do { barrier(); local_bh_count(cpu)--; } while (0)
+#define local_bh_disable()	do { local_bh_count()++; barrier(); } while (0)
+#define local_bh_enable()	do { barrier(); local_bh_count()--; } while (0)
 
-#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
-#define local_bh_enable()	cpu_bh_enable(smp_processor_id())
-
-#define in_softirq()		(local_bh_count(smp_processor_id()) != 0)
+#define in_softirq()		(local_bh_count() != 0)
 
 #endif /* _ASM_IA64_SOFTIRQ_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/system.h linux/include/asm-ia64/system.h
--- v2.4.3/linux/include/asm-ia64/system.h	Tue Mar  6 19:44:34 2001
+++ linux/include/asm-ia64/system.h	Thu Apr  5 12:51:47 2001
@@ -7,8 +7,8 @@
  * on information published in the Processor Abstraction Layer
  * and the System Abstraction Layer manual.
  *
- * Copyright (C) 1998-2000 Hewlett-Packard Co
- * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
  */
@@ -16,16 +16,18 @@
 
 #include <asm/page.h>
 
-#define KERNEL_START		(PAGE_OFFSET + 0x500000)
+#define KERNEL_START		(PAGE_OFFSET + 68*1024*1024)
 
 /*
  * The following #defines must match with vmlinux.lds.S:
  */
+#define IVT_ADDR		(KERNEL_START)
 #define IVT_END_ADDR		(KERNEL_START + 0x8000)
-#define ZERO_PAGE_ADDR		(IVT_END_ADDR + 0*PAGE_SIZE)
-#define SWAPPER_PGD_ADDR	(IVT_END_ADDR + 1*PAGE_SIZE)
+#define ZERO_PAGE_ADDR		PAGE_ALIGN(IVT_END_ADDR)
+#define SWAPPER_PGD_ADDR	(ZERO_PAGE_ADDR + 1*PAGE_SIZE)
 
 #define GATE_ADDR		(0xa000000000000000 + PAGE_SIZE)
+#define PERCPU_ADDR		(0xa000000000000000 + 2*PAGE_SIZE)
 
 #if defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) \
     || defined(CONFIG_ITANIUM_B0_SPECIFIC) || defined(CONFIG_ITANIUM_B1_SPECIFIC)
@@ -62,12 +64,10 @@
 		__u16 orig_x;	/* cursor's x position */
 		__u16 orig_y;	/* cursor's y position */
 	} console_info;
-	__u16 num_pci_vectors;	/* number of ACPI derived PCI IRQ's*/
-	__u64 pci_vectors;	/* physical address of PCI data (pci_vector_struct)*/
 	__u64 fpswa;		/* physical address of the fpswa interface */
 	__u64 initrd_start;
 	__u64 initrd_size;
-} ia64_boot_param;
+} *ia64_boot_param;
 
 static inline void
 ia64_insn_group_barrier (void)
@@ -181,50 +181,9 @@
 #define __save_flags(flags)	__asm__ __volatile__ ("mov %0=psr" : "=r" (flags) :: "memory")
 #define __save_and_cli(flags)	local_irq_save(flags)
 #define save_and_cli(flags)	__save_and_cli(flags)
-
-
-#ifdef CONFIG_IA64_SOFTSDV_HACKS
-/*
- * Yech.  SoftSDV has a slight probem with psr.i and itc/itm.  If
- * PSR.i = 0 and ITC == ITM, you don't get the timer tick posted.  So,
- * I'll check if ITC is larger than ITM here and reset if neccessary.
- * I may miss a tick to two.
- * 
- * Don't include asm/delay.h; it causes include loops that are
- * mind-numbingly hard to follow.
- */
-
-#define get_itc(x) __asm__ __volatile__("mov %0=ar.itc" : "=r"((x)) :: "memory")
-#define get_itm(x) __asm__ __volatile__("mov %0=cr.itm" : "=r"((x)) :: "memory")
-#define set_itm(x) __asm__ __volatile__("mov cr.itm=%0" :: "r"((x)) : "memory")
-
-#define __restore_flags(x)			\
-do {						\
-        unsigned long itc, itm;			\
-	local_irq_restore(x);			\
-        get_itc(itc);				\
-        get_itm(itm);				\
-        if (itc > itm)				\
-		set_itm(itc + 10);		\
-} while (0)
-
-#define __sti()					\
-do {						\
-	unsigned long itc, itm;			\
-	local_irq_enable();			\
-	get_itc(itc);				\
-	get_itm(itm);				\
-	if (itc > itm)				\
-		set_itm(itc + 10);		\
-} while (0)
-
-#else /* !CONFIG_IA64_SOFTSDV_HACKS */
-
 #define __sti()			local_irq_enable ()
 #define __restore_flags(flags)	local_irq_restore(flags)
 
-#endif /* !CONFIG_IA64_SOFTSDV_HACKS */
-
 #ifdef CONFIG_SMP
   extern void __global_cli (void);
   extern void __global_sti (void);
@@ -325,7 +284,7 @@
 #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.
@@ -350,7 +309,7 @@
 	      case 2: _o_ = (__u16) (long) (old); break;				\
 	      case 4: _o_ = (__u32) (long) (old); break;				\
 	      case 8: _o_ = (__u64) (long) (old); break;				\
-	      default:									\
+	      default: break;								\
 	}										\
 	 __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO"(_o_));				\
 	switch (size) {									\
@@ -439,7 +398,7 @@
 	(last) = ia64_switch_to((next));						\
 } while (0)
 
-#ifdef CONFIG_SMP 
+#ifdef CONFIG_SMP
   /*
    * In the SMP case, we save the fph state when context-switching
    * away from a thread that modified fph.  This way, when the thread
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/timex.h linux/include/asm-ia64/timex.h
--- v2.4.3/linux/include/asm-ia64/timex.h	Sun Feb  6 18:42:40 2000
+++ linux/include/asm-ia64/timex.h	Thu Apr  5 12:51:47 2001
@@ -2,14 +2,15 @@
 #define _ASM_IA64_TIMEX_H
 
 /*
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+/*
+ * 2001/01/18 davidm	Removed CLOCK_TICK_RATE.  It makes no sense on IA-64.
+ *			Also removed cacheflush_time as it's entirely unused.
  */
-
-#define CLOCK_TICK_RATE		1193180	/* Underlying HZ XXX fix me! */
 
 typedef unsigned long cycles_t;
-extern cycles_t cacheflush_time;
 
 static inline cycles_t
 get_cycles (void)
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/uaccess.h linux/include/asm-ia64/uaccess.h
--- v2.4.3/linux/include/asm-ia64/uaccess.h	Thu Jan  4 12:50:18 2001
+++ linux/include/asm-ia64/uaccess.h	Thu Apr  5 12:51:47 2001
@@ -25,14 +25,16 @@
  * handler checks to see whether the faulting instruction has a fixup
  * associated and, if so, sets r8 to -EFAULT and clears r9 to 0 and
  * then resumes execution at the continuation point.
- * 
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <linux/errno.h>
 #include <linux/sched.h>
 
+#include <asm/pgtable.h>
+
 /*
  * For historical reasons, the following macros are grossly misnamed:
  */
@@ -49,16 +51,13 @@
 #define segment_eq(a,b)	((a).seg == (b).seg)
 
 /*
- * When accessing user memory, we need to make sure the entire area
- * really is in user-level space.  In order to do this efficiently, we
- * make sure that the page at address TASK_SIZE is never valid (we do
- * this by selecting VMALLOC_START as TASK_SIZE+PAGE_SIZE).  This way,
- * we can simply check whether the starting address is < TASK_SIZE
- * and, if so, start accessing the memory.  If the user specified bad
- * length, we will fault on the NaT page and then return the
- * appropriate error.
+ * When accessing user memory, we need to make sure the entire area really is in
+ * user-level space.  In order to do this efficiently, we make sure that the page at
+ * address TASK_SIZE is never valid.  We also need to make sure that the address doesn't
+ * point inside the virtually mapped linear page table.
  */
-#define __access_ok(addr,size,segment)	(((unsigned long) (addr)) <= (segment).seg)
+#define __access_ok(addr,size,segment)	(((unsigned long) (addr)) <= (segment).seg		\
+	 && ((segment).seg == KERNEL_DS.seg || rgn_offset((unsigned long) (addr)) < RGN_MAP_LIMIT))
 #define access_ok(type,addr,size)	__access_ok((addr),(size),get_fs())
 
 static inline int
@@ -85,28 +84,28 @@
  */
 #define __put_user(x,ptr)	__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
 #define __get_user(x,ptr)	__get_user_nocheck((x),(ptr),sizeof(*(ptr)))
-  
+
 extern void __get_user_unknown (void);
 
-#define __get_user_nocheck(x,ptr,size)				\
-({								\
-	register long __gu_err __asm__ ("r8") = 0;		\
-	register long __gu_val __asm__ ("r9") = 0;		\
-	switch (size) {						\
-	  case 1: __get_user_8(ptr); break;			\
-	  case 2: __get_user_16(ptr); break;			\
-	  case 4: __get_user_32(ptr); break;			\
-	  case 8: __get_user_64(ptr); break;			\
-	  default: __get_user_unknown(); break;			\
-	}							\
-	(x) = (__typeof__(*(ptr))) __gu_val;			\
-	__gu_err;						\
+#define __get_user_nocheck(x,ptr,size)		\
+({						\
+	register long __gu_err asm ("r8") = 0;	\
+	register long __gu_val asm ("r9") = 0;	\
+	switch (size) {				\
+	  case 1: __get_user_8(ptr); break;	\
+	  case 2: __get_user_16(ptr); break;	\
+	  case 4: __get_user_32(ptr); break;	\
+	  case 8: __get_user_64(ptr); break;	\
+	  default: __get_user_unknown(); break;	\
+	}					\
+	(x) = (__typeof__(*(ptr))) __gu_val;	\
+	__gu_err;				\
 })
 
 #define __get_user_check(x,ptr,size,segment)			\
 ({								\
-	register long __gu_err __asm__ ("r8") = -EFAULT;	\
-	register long __gu_val __asm__ ("r9") = 0;		\
+	register long __gu_err asm ("r8") = -EFAULT;		\
+	register long __gu_val asm ("r9") = 0;			\
 	const __typeof__(*(ptr)) *__gu_addr = (ptr);		\
 	if (__access_ok((long)__gu_addr,size,segment)) {	\
 		__gu_err = 0;					\
@@ -126,46 +125,60 @@
 #define __m(x) (*(struct __large_struct *)(x))
 
 /* We need to declare the __ex_table section before we can use it in .xdata.  */
-__asm__ (".section \"__ex_table\", \"a\"\n\t.previous");
+asm (".section \"__ex_table\", \"a\"\n\t.previous");
+
+#if __GNUC__ >= 3
+#  define GAS_HAS_LOCAL_TAGS	/* define if gas supports local tags a la [1:] */
+#endif
+
+#ifdef GAS_HAS_LOCAL_TAGS
+# define _LL	"[1:]"
+#else
+# define _LL	"1:"
+#endif
 
 #define __get_user_64(addr)									\
-	__asm__ ("\n1:\tld8 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
-		 "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)|1\n"			\
-		: "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err));
+	asm ("\n"_LL"\tld8 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
+	     "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)+4\n"				\
+	     _LL										\
+	     : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err));
 
 #define __get_user_32(addr)									\
-	__asm__ ("\n1:\tld4 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
-		 "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)|1\n"			\
-		: "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err));
+	asm ("\n"_LL"\tld4 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
+	     "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)+4\n"				\
+	     _LL										\
+	     : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err));
 
 #define __get_user_16(addr)									\
-	__asm__ ("\n1:\tld2 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
-		 "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)|1\n"			\
-		: "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err));
+	asm ("\n"_LL"\tld2 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
+	     "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)+4\n"				\
+	     _LL										\
+	     : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err));
 
 #define __get_user_8(addr)									\
-	__asm__ ("\n1:\tld1 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
-		 "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)|1\n"			\
-		: "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err));
+	asm ("\n"_LL"\tld1 %0=%2%P2\t// %0 and %1 get overwritten by exception handler\n"	\
+	     "\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)+4\n"				\
+	     _LL										\
+	     : "=r"(__gu_val), "=r"(__gu_err) : "m"(__m(addr)), "1"(__gu_err));
 
 extern void __put_user_unknown (void);
 
-#define __put_user_nocheck(x,ptr,size)				\
-({								\
-	register long __pu_err __asm__ ("r8") = 0;		\
-	switch (size) {						\
-	  case 1: __put_user_8(x,ptr); break;			\
-	  case 2: __put_user_16(x,ptr); break;			\
-	  case 4: __put_user_32(x,ptr); break;			\
-	  case 8: __put_user_64(x,ptr); break;			\
-	  default: __put_user_unknown(); break;			\
-	}							\
-	__pu_err;						\
+#define __put_user_nocheck(x,ptr,size)		\
+({						\
+	register long __pu_err asm ("r8") = 0;	\
+	switch (size) {				\
+	  case 1: __put_user_8(x,ptr); break;	\
+	  case 2: __put_user_16(x,ptr); break;	\
+	  case 4: __put_user_32(x,ptr); break;	\
+	  case 8: __put_user_64(x,ptr); break;	\
+	  default: __put_user_unknown(); break;	\
+	}					\
+	__pu_err;				\
 })
 
 #define __put_user_check(x,ptr,size,segment)			\
 ({								\
-	register long __pu_err __asm__ ("r8") = -EFAULT;	\
+	register long __pu_err asm ("r8") = -EFAULT;		\
 	__typeof__(*(ptr)) *__pu_addr = (ptr);			\
 	if (__access_ok((long)__pu_addr,size,segment)) {	\
 		__pu_err = 0;					\
@@ -186,27 +199,31 @@
  * any memory gcc knows about, so there are no aliasing issues
  */
 #define __put_user_64(x,addr)								\
-	__asm__ __volatile__ (								\
-		 "\n1:\tst8 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
-		 "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)\n"			\
+	asm volatile (									\
+		"\n"_LL"\tst8 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
+		"\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)\n"			\
+		_LL									\
 		: "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err))
 
 #define __put_user_32(x,addr)								\
-	__asm__ __volatile__ (								\
-		 "\n1:\tst4 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
-		 "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)\n"			\
+	asm volatile (									\
+		"\n"_LL"\tst4 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
+		"\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)\n"			\
+		_LL									\
 		: "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err))
 
 #define __put_user_16(x,addr)								\
-	__asm__ __volatile__ (								\
-		 "\n1:\tst2 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
-		 "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)\n"			\
+	asm volatile (									\
+		"\n"_LL"\tst2 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
+		"\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)\n"			\
+		_LL									\
 		: "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err))
 
 #define __put_user_8(x,addr)								\
-	__asm__ __volatile__ (								\
-		 "\n1:\tst1 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
-		 "2:\n\t.xdata4 \"__ex_table\", @gprel(1b), (2b-1b)\n"			\
+	asm volatile (									\
+		"\n"_LL"\tst1 %1=%r2%P1\t// %0 gets overwritten by exception handler\n"	\
+		"\t.xdata4 \"__ex_table\", @gprel(1b), @gprel(1f)\n"			\
+		_LL									\
 		: "=r"(__pu_err) : "m"(__m(addr)), "rO"(x), "0"(__pu_err))
 
 /*
@@ -215,7 +232,7 @@
 extern unsigned long __copy_user (void *to, const void *from, unsigned long count);
 
 #define __copy_to_user(to,from,n)	__copy_user((to), (from), (n))
-#define __copy_from_user(to,from,n) 	__copy_user((to), (from), (n))
+#define __copy_from_user(to,from,n)	__copy_user((to), (from), (n))
 
 #define copy_to_user(to,from,n)   __copy_tofrom_user((to), (from), (n), 1)
 #define copy_from_user(to,from,n) __copy_tofrom_user((to), (from), (n), 0)
@@ -293,10 +310,14 @@
 
 struct exception_table_entry {
 	int addr;	/* gp-relative address of insn this fixup is for */
-	int skip;	/* number of bytes to skip to get to the continuation point.
-			   Bit 0 tells us if r9 should be cleared to 0*/
+	int cont;	/* gp-relative continuation address; if bit 2 is set, r9 is set to 0 */
+};
+
+struct exception_fixup {
+	unsigned long cont;	/* continuation point (bit 2: clear r9 if set) */
 };
 
-extern const struct exception_table_entry *search_exception_table (unsigned long addr);
+extern struct exception_fixup search_exception_table (unsigned long addr);
+extern void handle_exception (struct pt_regs *regs, struct exception_fixup fixup);
 
 #endif /* _ASM_IA64_UACCESS_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/ucontext.h linux/include/asm-ia64/ucontext.h
--- v2.4.3/linux/include/asm-ia64/ucontext.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ia64/ucontext.h	Thu Apr  5 12:51:47 2001
@@ -0,0 +1,12 @@
+#ifndef _ASM_IA64_UCONTEXT_H
+#define _ASM_IA64_UCONTEXT_H
+
+struct ucontext {
+	struct sigcontext uc_mcontext;
+};
+
+#define uc_link		uc_mcontext.sc_gr[0]	/* wrong type; nobody cares */
+#define uc_sigmask	uc_mcontext.sc_sigmask
+#define uc_stack	uc_mcontext.sc_stack
+
+#endif /* _ASM_IA64_UCONTEXT_H */
diff -u --recursive --new-file v2.4.3/linux/include/asm-ia64/unwind.h linux/include/asm-ia64/unwind.h
--- v2.4.3/linux/include/asm-ia64/unwind.h	Mon Oct  9 17:55:01 2000
+++ linux/include/asm-ia64/unwind.h	Thu Apr  5 12:51:47 2001
@@ -109,22 +109,6 @@
 				 struct switch_stack *sw);
 
 /*
- * Prepare to unwind the current task.  For this to work, the kernel
- * stack identified by REGS must look like this:
- *
- *	//		      //
- *	|		      |
- *	|   kernel stack      |
- *	|		      |
- *	+=====================+
- *	|   struct pt_regs    |
- *	+---------------------+ <--- REGS
- *	| struct switch_stack |
- *	+---------------------+
- */
-extern void unw_init_from_current (struct unw_frame_info *info, struct pt_regs *regs);
-
-/*
  * Prepare to unwind the currently running thread.
  */
 extern void unw_init_running (void (*callback)(struct unw_frame_info *info, void *arg), void *arg);
@@ -144,42 +128,42 @@
 
 #define unw_is_intr_frame(info)	(((info)->flags & UNW_FLAG_INTERRUPT_FRAME) != 0)
 
-static inline unsigned long
+static inline int
 unw_get_ip (struct unw_frame_info *info, unsigned long *valp)
 {
 	*valp = (info)->ip;
 	return 0;
 }
 
-static inline unsigned long
+static inline int
 unw_get_sp (struct unw_frame_info *info, unsigned long *valp)
 {
 	*valp = (info)->sp;
 	return 0;
 }
 
-static inline unsigned long
+static inline int
 unw_get_psp (struct unw_frame_info *info, unsigned long *valp)
 {
 	*valp = (info)->psp;
 	return 0;
 }
 
-static inline unsigned long
+static inline int
 unw_get_bsp (struct unw_frame_info *info, unsigned long *valp)
 {
 	*valp = (info)->bsp;
 	return 0;
 }
 
-static inline unsigned long
+static inline int
 unw_get_cfm (struct unw_frame_info *info, unsigned long *valp)
 {
 	*valp = *(info)->cfm_loc;
 	return 0;
 }
 
-static inline unsigned long
+static inline int
 unw_set_cfm (struct unw_frame_info *info, unsigned long val)
 {
 	*(info)->cfm_loc = val;
diff -u --recursive --new-file v2.4.3/linux/include/linux/ac97_codec.h linux/include/linux/ac97_codec.h
--- v2.4.3/linux/include/linux/ac97_codec.h	Mon Mar 26 15:49:49 2001
+++ linux/include/linux/ac97_codec.h	Fri Apr  6 16:06:36 2001
@@ -133,7 +133,15 @@
 	SOUND_MASK_LINE1| SOUND_MASK_LINE|\
 	SOUND_MASK_PHONEIN)
 
-#define supported_mixer(CODEC,FOO) ((CODEC)->supported_mixers & (1<<FOO) )
+/* original check is not good enough in case FOO is greater than
+ * SOUND_MIXER_NRDEVICES because the supported_mixers has exactly
+ * SOUND_MIXER_NRDEVICES elements.
+ * before matching the given mixer against the bitmask in supported_mixers we
+ * check if mixer number exceeds maximum allowed size which is as mentioned
+ * above SOUND_MIXER_NRDEVICES */
+#define supported_mixer(CODEC,FOO) ((FOO >= 0) && \
+                                    (FOO < SOUND_MIXER_NRDEVICES) && \
+                                    (CODEC)->supported_mixers & (1<<FOO) )
 
 struct ac97_codec {
 	/* AC97 controller connected with */
diff -u --recursive --new-file v2.4.3/linux/include/linux/apm_bios.h linux/include/linux/apm_bios.h
--- v2.4.3/linux/include/linux/apm_bios.h	Wed Dec  6 21:00:13 2000
+++ linux/include/linux/apm_bios.h	Fri Apr  6 10:51:19 2001
@@ -3,7 +3,7 @@
 
 /*
  * Include file for the interface to an APM BIOS
- * Copyright 1994-2000 Stephen Rothwell (sfr@linuxcare.com)
+ * Copyright 1994-2001 Stephen Rothwell (sfr@canb.auug.org.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
diff -u --recursive --new-file v2.4.3/linux/include/linux/coff.h linux/include/linux/coff.h
--- v2.4.3/linux/include/linux/coff.h	Wed Aug 10 09:26:42 1994
+++ linux/include/linux/coff.h	Fri Apr  6 10:51:19 2001
@@ -1,5 +1,5 @@
 /* This file is derived from the GAS 2.1.4 assembler control file.
-   The GAS product is under the GNU Public License, version 2 or later.
+   The GAS product is under the GNU General Public License, version 2 or later.
    As such, this file is also under that license.
 
    If the file format changes in the COFF object, this file should be
diff -u --recursive --new-file v2.4.3/linux/include/linux/com20020.h linux/include/linux/com20020.h
--- v2.4.3/linux/include/linux/com20020.h	Tue May  2 12:36:09 2000
+++ linux/include/linux/com20020.h	Fri Apr  6 10:51:19 2001
@@ -15,7 +15,7 @@
  * skeleton.c Written 1993 by Donald Becker.
  * Copyright 1993 United States Government as represented by the
  * Director, National Security Agency.  This software may only be used
- * and distributed according to the terms of the GNU Public License as
+ * and distributed according to the terms of the GNU General Public License as
  * modified by SRC, incorporated herein by reference.
  *
  * **********************
diff -u --recursive --new-file v2.4.3/linux/include/linux/swap.h linux/include/linux/swap.h
--- v2.4.3/linux/include/linux/swap.h	Mon Mar 26 15:48:11 2001
+++ linux/include/linux/swap.h	Fri Apr  6 16:06:21 2001
@@ -134,7 +134,6 @@
 extern void __delete_from_swap_cache(struct page *page);
 extern void delete_from_swap_cache(struct page *page);
 extern void delete_from_swap_cache_nolock(struct page *page);
-extern void free_page_and_swap_cache(struct page *page);
 
 /* linux/mm/swapfile.c */
 extern unsigned int nr_swapfiles;
@@ -166,23 +165,6 @@
 extern unsigned long swap_cache_find_total;
 extern unsigned long swap_cache_find_success;
 #endif
-
-/*
- * Work out if there are any other processes sharing this page, ignoring
- * any page reference coming from the swap cache, or from outstanding
- * swap IO on this page.  (The page cache _does_ count as another valid
- * reference to the page, however.)
- */
-static inline int is_page_shared(struct page *page)
-{
-	unsigned int count;
-	if (PageReserved(page))
-		return 1;
-	count = page_count(page);
-	if (PageSwapCache(page))
-		count += swap_count(page) - 2 - !!page->buffers;
-	return  count > 1;
-}
 
 extern spinlock_t pagemap_lru_lock;
 
diff -u --recursive --new-file v2.4.3/linux/kernel/pm.c linux/kernel/pm.c
--- v2.4.3/linux/kernel/pm.c	Tue Mar  6 19:44:37 2001
+++ linux/kernel/pm.c	Fri Apr  6 10:51:19 2001
@@ -22,6 +22,7 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/pm.h>
+#include <linux/interrupt.h>
 
 int pm_active;
 
@@ -49,6 +50,9 @@
  *	Add a device to the list of devices that wish to be notified about
  *	power management events. A &pm_dev structure is returned on success,
  *	on failure the return is %NULL.
+ *
+ *      The callback function will be called in process context and
+ *      it may sleep.
  */
  
 struct pm_dev *pm_register(pm_dev_t type,
@@ -150,6 +154,10 @@
 {
 	int status = 0;
 	int prev_state, next_state;
+
+	if (in_interrupt())
+		BUG();
+
 	switch (rqst) {
 	case PM_SUSPEND:
 	case PM_RESUME:
diff -u --recursive --new-file v2.4.3/linux/lib/string.c linux/lib/string.c
--- v2.4.3/linux/lib/string.c	Tue Mar  6 19:44:37 2001
+++ linux/lib/string.c	Fri Apr  6 10:51:19 2001
@@ -350,6 +350,8 @@
  * @s: Pointer to the start of the area.
  * @c: The byte to fill the area with
  * @count: The size of the area.
+ *
+ * Do not use memset() to access IO space, use memset_io() instead.
  */
 void * memset(void * s,int c,size_t count)
 {
@@ -369,11 +371,11 @@
  * @dest: Where to copy to
  * @count: The size of the area.
  *
- * When using copies for I/O remember that bcopy and memcpy are entitled
- * to do out of order writes and may well exactly that.
+ * Note that this is the same as memcpy(), with the arguments reversed.
+ * memcpy() is the standard, bcopy() is a legacy BSD function.
  *
- * Note that this is the same as memcpy, with the arguments reversed. memcpy
- * is the standard, bcopy is a legacy BSD function.
+ * You should not use this function to access IO space, use memcpy_toio()
+ * or memcpy_fromio() instead.
  */
 char * bcopy(const char * src, char * dest, int count)
 {
@@ -393,8 +395,8 @@
  * @src: Where to copy from
  * @count: The size of the area.
  *
- * When using copies for I/O remember that bcopy and memcpy are entitled
- * to do out of order writes and may well exactly that.
+ * You should not use this function to access IO space, use memcpy_toio()
+ * or memcpy_fromio() instead.
  */
 void * memcpy(void * dest,const void *src,size_t count)
 {
@@ -414,7 +416,7 @@
  * @src: Where to copy from
  * @count: The size of the area.
  *
- * memmove copes with overlapping areas.
+ * Unlike memcpy(), memmove() copes with overlapping areas.
  */
 void * memmove(void * dest,const void *src,size_t count)
 {
@@ -439,7 +441,7 @@
 
 #ifndef __HAVE_ARCH_MEMCMP
 /**
- * memmove - Compare two areas of memory
+ * memcmp - Compare two areas of memory
  * @cs: One area of memory
  * @ct: Another area of memory
  * @count: The size of the area.
diff -u --recursive --new-file v2.4.3/linux/mm/filemap.c linux/mm/filemap.c
--- v2.4.3/linux/mm/filemap.c	Fri Mar 23 14:38:48 2001
+++ linux/mm/filemap.c	Fri Apr  6 10:22:31 2001
@@ -108,7 +108,6 @@
 	if (PageDirty(page)) BUG();
 	remove_page_from_inode_queue(page);
 	remove_page_from_hash_queue(page);
-	page->mapping = NULL;
 }
 
 void remove_inode_page(struct page *page)
diff -u --recursive --new-file v2.4.3/linux/mm/memory.c linux/mm/memory.c
--- v2.4.3/linux/mm/memory.c	Mon Mar 26 11:02:24 2001
+++ linux/mm/memory.c	Thu Apr  5 16:41:17 2001
@@ -274,7 +274,7 @@
 		 */
 		if (pte_dirty(pte) && page->mapping)
 			set_page_dirty(page);
-		free_page_and_swap_cache(page);
+		page_cache_release(page);
 		return 1;
 	}
 	swap_free(pte_to_swp_entry(pte));
@@ -815,6 +815,24 @@
 }
 
 /*
+ * Work out if there are any other processes sharing this
+ * swap cache page. Never mind the buffers.
+ */
+static inline int exclusive_swap_page(struct page *page)
+{
+	unsigned int count;
+
+	if (!PageLocked(page))
+		BUG();
+	if (!PageSwapCache(page))
+		return 0;
+	count = page_count(page) - !!page->buffers;	/*  2: us + swap cache */
+	count += swap_count(page);			/* +1: just swap cache */
+	return count == 3;				/* =3: total */
+}
+
+
+/*
  * This routine handles present pages, when users try to write
  * to a shared page. It is done by copying the page to a new address
  * and decrementing the shared-page counter for the old page.
@@ -853,19 +871,21 @@
 	 *   marked dirty).
 	 */
 	switch (page_count(old_page)) {
+	int can_reuse;
+	case 3:
+		if (!old_page->buffers)
+			break;
+		/* FallThrough */
 	case 2:
-		/*
-		 * Lock the page so that no one can look it up from
-		 * the swap cache, grab a reference and start using it.
-		 * Can not do lock_page, holding page_table_lock.
-		 */
-		if (!PageSwapCache(old_page) || TryLockPage(old_page))
+		if (!PageSwapCache(old_page))
 			break;
-		if (is_page_shared(old_page)) {
-			UnlockPage(old_page);
+		if (TryLockPage(old_page))
 			break;
-		}
+		/* Recheck swapcachedness once the page is locked */
+		can_reuse = exclusive_swap_page(old_page);
 		UnlockPage(old_page);
+		if (!can_reuse)
+			break;
 		/* FallThrough */
 	case 1:
 		if (PageReserved(old_page))
@@ -903,8 +923,7 @@
 	return -1;
 }
 
-static void vmtruncate_list(struct vm_area_struct *mpnt,
-			    unsigned long pgoff, unsigned long partial)
+static void vmtruncate_list(struct vm_area_struct *mpnt, unsigned long pgoff)
 {
 	do {
 		struct mm_struct *mm = mpnt->vm_mm;
@@ -947,7 +966,7 @@
  */
 void vmtruncate(struct inode * inode, loff_t offset)
 {
-	unsigned long partial, pgoff;
+	unsigned long pgoff;
 	struct address_space *mapping = inode->i_mapping;
 	unsigned long limit;
 
@@ -959,19 +978,15 @@
 		goto out_unlock;
 
 	pgoff = (offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-	partial = (unsigned long)offset & (PAGE_CACHE_SIZE - 1);
-
 	if (mapping->i_mmap != NULL)
-		vmtruncate_list(mapping->i_mmap, pgoff, partial);
+		vmtruncate_list(mapping->i_mmap, pgoff);
 	if (mapping->i_mmap_shared != NULL)
-		vmtruncate_list(mapping->i_mmap_shared, pgoff, partial);
+		vmtruncate_list(mapping->i_mmap_shared, pgoff);
 
 out_unlock:
 	spin_unlock(&mapping->i_shared_lock);
 	truncate_inode_pages(mapping, offset);
-	if (inode->i_op && inode->i_op->truncate)
-		inode->i_op->truncate(inode);
-	return;
+	goto out_truncate;
 
 do_expand:
 	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
@@ -986,8 +1001,13 @@
 		}
 	}
 	inode->i_size = offset;
-	if (inode->i_op && inode->i_op->truncate)
+
+out_truncate:
+	if (inode->i_op && inode->i_op->truncate) {
+		lock_kernel();
 		inode->i_op->truncate(inode);
+		unlock_kernel();
+	}
 out:
 	return;
 }
@@ -1077,7 +1097,7 @@
 	pte = mk_pte(page, vma->vm_page_prot);
 
 	swap_free(entry);
-	if (write_access && !is_page_shared(page))
+	if (write_access && exclusive_swap_page(page))
 		pte = pte_mkwrite(pte_mkdirty(pte));
 	UnlockPage(page);
 
diff -u --recursive --new-file v2.4.3/linux/mm/mmap.c linux/mm/mmap.c
--- v2.4.3/linux/mm/mmap.c	Wed Mar 28 12:55:34 2001
+++ linux/mm/mmap.c	Fri Apr  6 12:45:20 2001
@@ -64,6 +64,15 @@
 	free += atomic_read(&page_cache_size);
 	free += nr_free_pages();
 	free += nr_swap_pages;
+
+	/*
+	 * This double-counts: the nrpages are both in the page-cache
+	 * and in the swapper space. At the same time, this compensates
+	 * for the swap-space over-allocation (ie "nr_swap_pages" being
+	 * too small. 
+	 */
+	free += swapper_space.nrpages;
+
 	/*
 	 * The code below doesn't account for free space in the inode
 	 * and dentry slab cache, slab cache fragmentation, inodes and
diff -u --recursive --new-file v2.4.3/linux/mm/swap_state.c linux/mm/swap_state.c
--- v2.4.3/linux/mm/swap_state.c	Fri Dec 29 15:04:27 2000
+++ linux/mm/swap_state.c	Fri Apr  6 16:35:06 2001
@@ -17,8 +17,23 @@
 
 #include <asm/pgtable.h>
 
+/*
+ * We may have stale swap cache pages in memory: notice
+ * them here and get rid of the unnecessary final write.
+ */
 static int swap_writepage(struct page *page)
 {
+	/* One for the page cache, one for this user, one for page->buffers */
+	if (page_count(page) > 2 + !!page->buffers)
+		goto in_use;
+	if (swap_count(page) > 1)
+		goto in_use;
+
+	/* We could remove it here, but page_launder will do it anyway */
+	UnlockPage(page);
+	return 0;
+
+in_use:
 	rw_swap_page(WRITE, page, 0);
 	return 0;
 }
@@ -129,26 +144,6 @@
 	delete_from_swap_cache_nolock(page);
 	UnlockPage(page);
 }
-
-/* 
- * Perform a free_page(), also freeing any swap cache associated with
- * this page if it is the last user of the page. Can not do a lock_page,
- * as we are holding the page_table_lock spinlock.
- */
-void free_page_and_swap_cache(struct page *page)
-{
-	/* 
-	 * If we are the only user, then try to free up the swap cache. 
-	 */
-	if (PageSwapCache(page) && !TryLockPage(page)) {
-		if (!is_page_shared(page)) {
-			delete_from_swap_cache_nolock(page);
-		}
-		UnlockPage(page);
-	}
-	page_cache_release(page);
-}
-
 
 /*
  * Lookup a swap entry in the swap cache. A found page will be returned
diff -u --recursive --new-file v2.4.3/linux/net/802/TODO linux/net/802/TODO
--- v2.4.3/linux/net/802/TODO	Thu Dec 12 06:54:22 1996
+++ linux/net/802/TODO	Fri Apr  6 10:51:19 2001
@@ -9,7 +9,7 @@
 2. The code is currently able to handle one connection only,
 there is more work in register_cl2llc_client() to make a chain
 of llc structures and in mac_data_indicate() to find back
-the llc structure addressed by an incomming frame.
+the llc structure addressed by an incoming frame.
 According to IEEE, connections are identified by (remote mac + local mac
 + dsap + ssap). dsap and ssap do not seem important: existing applications
 always use the same dsap/ssap. Its probably sufficient to index on 
diff -u --recursive --new-file v2.4.3/linux/net/802/cl2llc.c linux/net/802/cl2llc.c
--- v2.4.3/linux/net/802/cl2llc.c	Fri Feb  9 11:34:13 2001
+++ linux/net/802/cl2llc.c	Fri Apr  6 10:51:19 2001
@@ -162,7 +162,7 @@
  *	Interpret_pseudo_code() executes the actions in the connection component
  *	state transition table. Table 4 in document on p88.
  *
- *	If this function is called to handle an incomming pdu, skb will point
+ *	If this function is called to handle an incoming pdu, skb will point
  *	to the buffer with the pdu and type will contain the decoded pdu type.
  *
  *	If called by data_request skb points to an skb that was skb_alloc-ed by 
diff -u --recursive --new-file v2.4.3/linux/net/802/cl2llc.pre linux/net/802/cl2llc.pre
--- v2.4.3/linux/net/802/cl2llc.pre	Sat Nov 29 10:41:10 1997
+++ linux/net/802/cl2llc.pre	Fri Apr  6 10:51:19 2001
@@ -162,7 +162,7 @@
  *	Interpret_pseudo_code() executes the actions in the connection component
  *	state transition table. Table 4 in document on p88.
  *
- *	If this function is called to handle an incomming pdu, skb will point
+ *	If this function is called to handle an incoming pdu, skb will point
  *	to the buffer with the pdu and type will contain the decoded pdu type.
  *
  *	If called by data_request skb points to an skb that was skb_alloc-ed by 
diff -u --recursive --new-file v2.4.3/linux/net/802/llc_sendpdu.c linux/net/802/llc_sendpdu.c
--- v2.4.3/linux/net/802/llc_sendpdu.c	Fri Feb  9 11:29:44 2001
+++ linux/net/802/llc_sendpdu.c	Fri Apr  6 10:51:19 2001
@@ -98,7 +98,7 @@
 
 /*
  *	Sendpdu() constructs an output frame in a new skb and
- *	gives it to the MAC layer for transmision.
+ *	gives it to the MAC layer for transmission.
  *	This function is not used to send I pdus.
  *	No queues are updated here, nothing is saved for retransmission.
  *
@@ -186,7 +186,7 @@
 
 /*
  *	llc_sendipdu() Completes an I pdu in an existing skb and gives it
- *	to the MAC layer for transmision.
+ *	to the MAC layer for transmission.
  *	Parameter "type" must be either I_CMD or I_RSP.
  *	The skb is not freed after xmit, it is kept in case a retransmission
  *	is requested. If needed it can be picked up again from the rtq.
diff -u --recursive --new-file v2.4.3/linux/net/802/pseudo/pseudocode linux/net/802/pseudo/pseudocode
--- v2.4.3/linux/net/802/pseudo/pseudocode	Thu Dec 12 06:54:22 1996
+++ linux/net/802/pseudo/pseudocode	Fri Apr  6 10:51:19 2001
@@ -246,7 +246,7 @@
 		START_REJ_TIMER
 ;
 ; the order of opcodes in NORMAL8 is changed.
-; the transition table will execute NORMAL8A for incomming pdus
+; the transition table will execute NORMAL8A for incoming pdus
 ; with p/f 1, pdus with pf 0 are treated in NORMAL8B.
 ;   
 NORMAL8A	V(R):=V(R)+1
diff -u --recursive --new-file v2.4.3/linux/net/802/transit/pdutr.pre linux/net/802/transit/pdutr.pre
--- v2.4.3/linux/net/802/transit/pdutr.pre	Thu Dec 12 06:54:22 1996
+++ linux/net/802/transit/pdutr.pre	Fri Apr  6 10:51:19 2001
@@ -1,6 +1,6 @@
 COMPILE pdutr INDEX
 ;
-; Transition tables for incomming pdu events.
+; Transition tables for incoming pdu events.
 ; translate this thing into C with
 ;  	awk -f ./compile.awk pdu.trans > pdutr.h
 ;
diff -u --recursive --new-file v2.4.3/linux/net/atm/addr.c linux/net/atm/addr.c
--- v2.4.3/linux/net/atm/addr.c	Fri Dec 29 14:35:47 2000
+++ linux/net/atm/addr.c	Fri Apr  6 10:51:19 2001
@@ -52,25 +52,26 @@
 	sigd_enq(NULL,as_itf_notify,NULL,&pvc,NULL);
 }
 
+/*
+ *	This is called from atm_ioctl only. You must hold the lock as a caller
+ */
 
-void reset_addr(struct atm_dev *dev)
+void atm_reset_addr(struct atm_dev *dev)
 {
 	struct atm_dev_addr *this;
 
 	down(&local_lock);
-	spin_lock (&atm_dev_lock);		
 	while (dev->local) {
 		this = dev->local;
 		dev->local = this->next;
 		kfree(this);
 	}
 	up(&local_lock);
-	spin_unlock (&atm_dev_lock);
 	notify_sigd(dev);
 }
 
 
-int add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr)
+int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr)
 {
 	struct atm_dev_addr **walk;
 	int error;
@@ -96,7 +97,7 @@
 }
 
 
-int del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr)
+int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr)
 {
 	struct atm_dev_addr **walk,*this;
 	int error;
@@ -119,7 +120,7 @@
 }
 
 
-int get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size)
+int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size)
 {
 	struct atm_dev_addr *walk;
 	int total;
diff -u --recursive --new-file v2.4.3/linux/net/atm/addr.h linux/net/atm/addr.h
--- v2.4.3/linux/net/atm/addr.h	Mon Dec 11 13:33:43 2000
+++ linux/net/atm/addr.h	Fri Apr  6 10:51:19 2001
@@ -10,9 +10,9 @@
 #include <linux/atmdev.h>
 
 
-void reset_addr(struct atm_dev *dev);
-int add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
-int del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
-int get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size);
+void atm_reset_addr(struct atm_dev *dev);
+int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
+int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr);
+int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size);
 
 #endif
diff -u --recursive --new-file v2.4.3/linux/net/atm/common.c linux/net/atm/common.c
--- v2.4.3/linux/net/atm/common.c	Fri Feb  9 11:34:13 2001
+++ linux/net/atm/common.c	Fri Apr  6 10:51:19 2001
@@ -867,7 +867,7 @@
 				ret_val = -EPERM;
 				goto done;
 			}
-			reset_addr(dev);
+			atm_reset_addr(dev);
 			break;
 		case ATM_ADDADDR:
 		case ATM_DELADDR:
@@ -883,13 +883,13 @@
 					goto done;
 				}
 				if (cmd == ATM_ADDADDR)
-					ret_val = add_addr(dev,&addr);
+					ret_val = atm_add_addr(dev,&addr);
 				else
-					ret_val = del_addr(dev,&addr);
+					ret_val = atm_del_addr(dev,&addr);
 				goto done;
 			}
 		case ATM_GETADDR:
-			size = get_addr(dev,buf,len);
+			size = atm_get_addr(dev,buf,len);
 			if (size < 0)
 				ret_val = size;
 			else
diff -u --recursive --new-file v2.4.3/linux/net/sunrpc/sched.c linux/net/sunrpc/sched.c
--- v2.4.3/linux/net/sunrpc/sched.c	Fri Feb  9 11:29:44 2001
+++ linux/net/sunrpc/sched.c	Tue Apr  3 13:45:37 2001
@@ -1072,6 +1072,8 @@
 	current->pgrp = 1;
 	strcpy(current->comm, "rpciod");
 
+	current->flags |= PF_MEMALLOC;
+
 	dprintk("RPC: rpciod starting (pid %d)\n", rpciod_pid);
 	while (rpciod_users) {
 		if (signalled()) {
diff -u --recursive --new-file v2.4.3/linux/scripts/lxdialog/checklist.c linux/scripts/lxdialog/checklist.c
--- v2.4.3/linux/scripts/lxdialog/checklist.c	Sun Feb  4 10:05:30 2001
+++ linux/scripts/lxdialog/checklist.c	Fri Apr  6 10:42:55 2001
@@ -211,13 +211,15 @@
 		    status[i+scroll], i, i == choice);
     }
 
-    wnoutrefresh (list);
-
     print_arrows(dialog, choice, item_no, scroll,
 			box_y, box_x + check_x + 5, list_height);
 
     print_buttons(dialog, height, width, 0);
 
+    wnoutrefresh (list);
+    wnoutrefresh (dialog);
+    doupdate ();
+
     while (key != ESC) {
 	key = wgetch (dialog);
 
@@ -355,7 +357,11 @@
 	case ESC:
 	    break;
 	}
+
+	/* Now, update everything... */
+	doupdate ();
     }
+    
 
     delwin (dialog);
     free (status);
diff -u --recursive --new-file v2.4.3/linux/scripts/tkgen.c linux/scripts/tkgen.c
--- v2.4.3/linux/scripts/tkgen.c	Mon Jun 19 13:45:52 2000
+++ linux/scripts/tkgen.c	Fri Apr  6 10:42:55 2001
@@ -155,7 +155,7 @@
     printf("\"catch {focus $oldFocus}; " );
     /* 
      * We are checking which windows should be destroyed and which are 
-     * common parrents with the next one. Remember that menu_num field
+     * common parents with the next one. Remember that menu_num field
      * in mainmenu_option record reports number of its *parent* menu.
      */
     if ( menu_num < tot_menu_num
