diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/CREDITS linux-2.4.23-pre8/CREDITS
--- linux-2.4.22/CREDITS	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/CREDITS	2003-10-22 22:47:54.000000000 +0000
@@ -1238,14 +1238,13 @@
 
 N: Christoph Hellwig
 E: hch@infradead.org
-E: hch@sgi.com
 D: all kinds of driver, filesystem & core kernel hacking
 D: freevxfs driver
 D: sysvfs maintainer
 D: chief codingstyle nitpicker
-S: Auweg 38
-S: 85748 Garching
-S: Germany
+S: Ampferstr. 50 / 4
+S: 6020 Innsbruck
+S: Austria
 
 N: Richard Henderson
 E: rth@twiddle.net
@@ -2208,6 +2207,15 @@
 E: wolfgang@iksw-muees.de
 D: Auerswald USB driver
 
+N: Paul Mundt
+E: lethal@linux-sh.org
+P: 1024D/917167DC 563C FC60 83BB A3EE D816  E60D D4AF AD78 9171 67DC
+D: Linux/SH and Linux/sh64
+D: Occasional MIPS hacker
+D: fbdev hacker
+S: Hamilton, Ontario
+S: Canada
+
 N: Ian A. Murdock
 E: imurdock@gnu.ai.mit.edu
 D: Creator of Debian distribution
@@ -2711,7 +2719,7 @@
 D: Dosemu
 
 N: Duncan Sands
-E: duncan.sands@wanadoo.fr
+E: duncan.sands@free.fr
 W: http://topo.math.u-psud.fr/~sands
 D: Alcatel SpeedTouch USB driver
 S: 69 rue Dunois
@@ -2967,12 +2975,11 @@
 S: USA
 
 N: Marcelo W. Tosatti
-E: marcelo@conectiva.com.br
-W: http://bazar.conectiva.com.br/~marcelo/
+E: marcelo.tosatti@cyclades.com
 D: Miscellaneous kernel hacker (mostly VM/MM work)
-S: Conectiva S.A.
-S: R. Tocantins, 89 - Cristo Rei
-S: 80050-430 - Curitiba - Paraná
+D: 2.4 maintainer
+S: Av Cristovao Colombo, 462. Floresta.
+S: Porto Alegre
 S: Brazil
 
 N: Stefan Traby
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/Configure.help linux-2.4.23-pre8/Documentation/Configure.help
--- linux-2.4.22/Documentation/Configure.help	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/Configure.help	2003-10-22 22:49:39.000000000 +0000
@@ -2,8 +2,6 @@
 #	Eric S. Raymond <mailto:esr@thyrsus.com>
 #	Steven Cole <mailto:elenstev@mesatop.com>
 #
-# Version 3.01: current with 2.4.19+
-#
 # Translations of this file available on the WWW:
 #
 #   - Japanese, maintained by the JF Project <mailto:JF@linux.or.jp>, at
@@ -19,13 +17,6 @@
 #   - Catalan, by Antoni Bella <mailto:bella5@teleline.es>, at
 #     <http://www.terra.es/personal7/bella5/traduccions.htm>
 #
-# To access a document on the WWW, you need to have a direct Internet
-# connection and a browser program such as netscape or lynx. If you
-# only have email access, you can still use FTP and WWW servers: send
-# an email to <mailto:mail-server@rtfm.mit.edu> with the text
-#   send usenet/news.answers/internet-services/access-via-email
-# in the body of the message.
-#
 # Information about what a kernel is, what it does, how to patch and
 # compile it and much more is contained in the Kernel-HOWTO, available
 # at <http://www.tldp.org/docs.html#howto>. Before you start
@@ -109,6 +100,15 @@
   like MGA monitors that you are very unlikely to see on today's
   systems.
 
+Prompt for advanced kernel configuration options
+CONFIG_ADVANCED_OPTIONS
+  This option will enable prompting for a variety of advanced kernel
+  configuration options.  These options can cause the kernel to not
+  work if they are set incorrectly, but can be used to optimize certain
+  aspects of kernel memory management.
+
+  Unless you know what you are doing you *should not* enable this option.
+
 Symmetric Multi-Processing support
 CONFIG_SMP
   This enables support for systems with more than one CPU. If you have
@@ -137,6 +137,15 @@
 
   If you don't know what to do here, say N.
 
+Maximum number of CPUs
+CONFIG_NR_CPUS
+  This allows you to specify the maximum number of CPUs which this
+  kernel will support.  The maximum supported value is 32 and the
+  mimimum value which makes sense is 2.
+
+  This is purely to save memory - each supported CPU adds
+  approximately eight kilobytes to the kernel image.
+
 Intel or compatible 80x86 processor
 CONFIG_X86
   This is Linux's home port.  Linux was originally native to the Intel
@@ -1141,6 +1150,15 @@
   Say Y here if you have an IDE controller which uses any of these
   chipsets: CMD643, CMD646 and CMD648.
 
+Compaq Triflex IDE support
+CONFIG_BLK_DEV_TRIFLEX
+  Say Y here if you have a Compaq Triflex IDE controller, such
+  as those commonly found on Compaq Pentium-Pro systems
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The module will be called
+  triflex.o.
+
 CY82C693 chipset support
 CONFIG_BLK_DEV_CY82C693
   This driver adds detection and support for the CY82C693 chipset
@@ -1210,11 +1228,26 @@
   This is a driver for the OPTi 82C621 EIDE controller.
   Please read the comments at the top of <file:drivers/ide/pci/opti621.c>.
 
+National SCx200 chipset support
+CONFIG_BLK_DEV_SC1200
+  This driver adds support for the built in IDE on the National
+  SCx200 series of embedded x86 "Geode" systems
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The module will be called
+  sc1200.o.
+
 ServerWorks OSB4/CSB5 chipset support
 CONFIG_BLK_DEV_SVWKS
   This driver adds PIO/(U)DMA support for the ServerWorks OSB4/CSB5
   chipsets.
 
+SGI IOC4 chipset support
+CONFIG_BLK_DEV_SGIIOC4
+  This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4
+  chipset.  Please say Y here, if you have an Altix System from
+  Silicon Graphics Inc.
+
 Intel PIIXn chipsets support
 CONFIG_BLK_DEV_PIIX
   This driver adds PIO mode setting and tuning for all PIIX IDE
@@ -1264,6 +1297,29 @@
 
   If unsure, say N.
 
+PROMISE PDC202{68|69|70|71|75|76|77} support
+CONFIG_BLK_DEV_PDC202XX_NEW
+  Promise Ultra 100 TX2 [PDC20268]
+  Promise Ultra 133 PTX2 [PDC20269]
+  Promise FastTrak LP/TX2/TX4 [PDC20270]
+  Promise FastTrak TX2000 [PDC20271]
+  Promise MB Ultra 133 [PDC20275]
+  Promise MB FastTrak 133 [PDC20276]
+  Promise FastTrak 133 [PDC20277]
+
+  This driver adds up to 4 more EIDE devices sharing a single
+  interrupt. This device is a bootable PCI UDMA controller. Since
+  multiple cards can be installed and there are BIOS ROM problems that
+  happen if the BIOS revisions of all installed cards (max of five) do
+  not match, the driver attempts to do dynamic tuning of the chipset
+  at boot-time for max speed.  Ultra33 BIOS 1.25 or newer is required
+  for more than one card.
+
+  If you say Y here, you need to say Y to "Use DMA by default when
+  available" as well.
+
+  If unsure, say N.
+
 Special UDMA Feature
 CONFIG_PDC202XX_BURST
   This option causes the pdc202xx driver to enable UDMA modes on the
@@ -2031,6 +2087,17 @@
   The board uses the R4300 and a R5230 CPUs.  For more information
   about this board see <http://www.algor.co.uk/>.
 
+SGI SN2 L1 serial port support
+CONFIG_SGI_L1_SERIAL
+  If you have an SGI SN2 and you want to use the serial port connected
+  to the system controller (you want this!), say Y.  Otherwise, say N.
+
+SGI SN2 L1 serial console support
+CONFIG_SGI_L1_SERIAL_CONSOLE
+  If you have an SGI SN2 and you would like to use the system
+  controller serial port as your console (you want this!), say Y.
+  Otherwise, say N.
+
 Support for BAGET MIPS series
 CONFIG_BAGET_MIPS
   This enables support for the Baget, a Russian embedded system.  For
@@ -3217,6 +3284,255 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+IP: virtual server support
+CONFIG_IP_VS
+  IP Virtual Server support will let you build a high-performance
+  virtual server based on cluster of two or more real servers. This
+  option must be enabled for at least one of the clustered computers
+  that will take care of intercepting incomming connections to a
+  single IP address and scheduling them to real servers.
+
+  Three request dispatching techniques are implemented, they are
+  virtual server via NAT, virtual server via tunneling and virtual
+  server via direct routing. The several scheduling algorithms can
+  be used to choose which server the connection is directed to,
+  thus load balancing can be achieved among the servers.  For more
+  information and its administration program, please visit the
+  following URL:
+	http://www.linuxvirtualserver.org/
+
+  If you want to compile it in kernel, say Y. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt. If
+  unsure, say N.
+
+IP virtual server debugging
+CONFIG_IP_VS_DEBUG
+  Say Y here if you want to get additional messages useful in
+  debugging the IP virtual server code. You can change the debug
+  level in /proc/sys/net/ipv4/vs/debug_level
+
+IPVS connection hash table size (the Nth power of 2)
+CONFIG_IP_VS_TAB_BITS
+  The IPVS connection hash table uses the chaining scheme to handle
+  hash collisions. Using a big IPVS connection hash table will greatly
+  reduce conflicts when there are hundreds of thousands of connections
+  in the hash table.
+
+  Note the table size must be power of 2. The table size will be the
+  value of 2 to the your input number power. The number to choose is
+  from 8 to 20, the default number is 12, which means the table size
+  is 4096. Don't input the number too small, otherwise you will lose
+  performance on it. You can adapt the table size yourself, according
+  to your virtual server application. It is good to set the table size
+  not far less than the number of connections per second multiplying
+  average lasting time of connection in the table.  For example, your
+  virtual server gets 200 connections per second, the connection lasts
+  for 200 seconds in average in the connection table, the table size
+  should be not far less than 200x200, it is good to set the table
+  size 32768 (2**15).
+
+  Another note that each connection occupies 128 bytes effectively and
+  each hash entry uses 8 bytes, so you can estimate how much memory is
+  needed for your box.
+
+IPVS: round-robin scheduling
+CONFIG_IP_VS_RR
+  The robin-robin scheduling algorithm simply directs network
+  connections to different real servers in a round-robin manner.
+
+  If you want to compile it in kernel, say Y. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt. If
+  unsure, say N.
+
+IPVS: weighted round-robin scheduling
+CONFIG_IP_VS_WRR
+  The weighted robin-robin scheduling algorithm directs network
+  connections to different real servers based on server weights
+  in a round-robin manner. Servers with higher weights receive
+  new connections first than those with less weights, and servers
+  with higher weights get more connections than those with less
+  weights and servers with equal weights get equal connections.
+
+  If you want to compile it in kernel, say Y. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt. If
+  unsure, say N.
+
+IPVS: least-connection scheduling
+CONFIG_IP_VS_LC
+  The least-connection scheduling algorithm directs network
+  connections to the server with the least number of active 
+  connections.
+
+  If you want to compile it in kernel, say Y. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt. If
+  unsure, say N.
+
+IPVS: weighted least-connection scheduling
+CONFIG_IP_VS_WLC
+  The weighted least-connection scheduling algorithm directs network
+  connections to the server with the least active connections
+  normalized by the server weight.
+
+  If you want to compile it in kernel, say Y. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt. If
+  unsure, say N.
+
+IPVS: locality-based least-connection scheduling
+CONFIG_IP_VS_LBLC
+  The locality-based least-connection scheduling algorithm is for
+  destination IP load balancing. It is usually used in cache cluster.
+  This algorithm usually directs packet destined for an IP address to
+  its server if the server is alive and under load. If the server is
+  overloaded (its active connection numbers is larger than its weight)
+  and there is a server in its half load, then allocate the weighted
+  least-connection server to this IP address.
+
+  If you want to compile it in kernel, say Y. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt. If
+  unsure, say N.
+
+IPVS: locality-based least-connection with replication scheduling
+CONFIG_IP_VS_LBLCR
+  The locality-based least-connection with replication scheduling
+  algorithm is also for destination IP load balancing. It is 
+  usually used in cache cluster. It differs from the LBLC scheduling
+  as follows: the load balancer maintains mappings from a target
+  to a set of server nodes that can serve the target. Requests for
+  a target are assigned to the least-connection node in the target's
+  server set. If all the node in the server set are over loaded,
+  it picks up a least-connection node in the cluster and adds it
+  in the sever set for the target. If the server set has not been
+  modified for the specified time, the most loaded node is removed
+  from the server set, in order to avoid high degree of replication.
+
+  If you want to compile it in kernel, say Y. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt. If
+  unsure, say N.
+
+IPVS: destination hashing scheduling
+CONFIG_IP_VS_DH
+  The destination hashing scheduling algorithm assigns network
+  connections to the servers through looking up a statically assigned
+  hash table by their destination IP addresses.
+
+  If you want to compile it in kernel, say Y. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt. If
+  unsure, say N.
+
+IPVS: source hashing scheduling
+CONFIG_IP_VS_SH
+  The source hashing scheduling algorithm assigns network
+  connections to the servers through looking up a statically assigned
+  hash table by their source IP addresses.
+
+  If you want to compile it in kernel, say Y. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt. If
+  unsure, say N.
+
+IPVS: shortest expected delay scheduling
+CONFIG_IP_VS_SED
+  The shortest expected delay scheduling algorithm assigns network
+  connections to the server with the shortest expected delay. The 
+  expected delay that the job will experience is (Ci + 1) / Ui if 
+  sent to the ith server, in which Ci is the number of connections
+  on the the ith server and Ui is the fixed service rate (weight)
+  of the ith server.
+
+  If you want to compile it in kernel, say Y. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt. If
+  unsure, say N.
+
+IPVS: never queue scheduling
+CONFIG_IP_VS_NQ
+  The never queue scheduling algorithm adopts a two-speed model.
+  When there is an idle server available, the job will be sent to
+  the idle server, instead of waiting for a fast one. When there
+  is no idle server available, the job will be sent to the server
+  that minimize its expected delay (The Shortest Expected Delay
+  scheduling algorithm).
+
+  If you want to compile it in kernel, say Y. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt. If
+  unsure, say N.
+
+IPVS: FTP protocol helper
+CONFIG_IP_VS_FTP
+  FTP is a protocol that transfers IP address and/or port number in
+  the payload. In the virtual server via Network Address Translation,
+  the IP address and port number of real servers cannot be sent to
+  clients in ftp connections directly, so FTP protocol helper is
+  required for tracking the connection and mangling it back to that of
+  virtual service.
+
+  If you want to compile it in kernel, say Y. If you want to compile
+  it as a module, say M here and read Documentation/modules.txt. If
+  unsure, say N.
+
+AH/ESP match support (EXPERIMENTAL)
+CONFIG_IP6_NF_MATCH_AHESP
+  This module allows one to match AH and ESP packets.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The modules will be called
+  ip6t_ah.o and ip6t_esp.o.
+
+  If unsure, say 'N'.
+
+Routing header match support
+CONFIG_IP6_NF_MATCH_RT
+  rt matching allows you to match packets based on the routing
+  header of the packet.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The module will be called
+  ip6t_rt.o.
+
+  If unsure, say 'N'.
+
+Hop-by-hop and Dst opts header match support
+CONFIG_IP6_NF_MATCH_OPTS
+  This allows one to match packets based on the hop-by-hop
+  and destination options headers of a packet.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The modules will be called
+  ip6t_hbh.o and ip6t_dst.o.
+
+  If unsure, say 'N'.
+
+Fragmentation header match support
+CONFIG_IP6_NF_MATCH_FRAG
+  frag matching allows you to match packets based on the fragmentation
+  header of the packet.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The module will be called
+  ip6t_frag.o.
+
+  If unsure, say 'N'.
+
+HL match support
+CONFIG_IP6_NF_MATCH_HL
+  HL matching allows you to match packets based on the hop
+  limit of the packet.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The module will be called
+  ip6t_hl.o.
+
+  If unsure, say 'N'.
+
+IPv6 Extension Headers Match (EXPERIMENTAL)
+CONFIG_IP6_NF_MATCH_IPV6HEADER
+  This module allows one to match packets based upon
+  the ipv6 extension headers.
+
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The module will be called
+  ip6t_ipv6header.o.
+
+  If unsure, say 'N'.
+
 SYN flood protection
 CONFIG_SYN_COOKIES
   Normal TCP/IP networking is open to an attack known as "SYN
@@ -3699,25 +4015,25 @@
 
 CONFIG_AGP_AMD_8151
   This option gives you AGP support for the GLX component of
-  XFree86 on AMD K8 with an AGP 8151 chipset.
+  XFree86 on an AMD Opteron/Athlon64 using the on-CPU GART.
 
   You should say Y here if you use XFree86 3.3.6 or 4.x and want to
   use GLX or DRI.  If unsure, say N.
 
 Generic SiS support
 CONFIG_AGP_SIS
-  This option gives you AGP support for the GLX component of the "soon
-  to be released" XFree86 4.x on Silicon Integrated Systems [SiS]
-  chipsets.
+  This option gives you AGP support for the GLX component of
+  XFree86 4.x on Silicon Integrated Systems [SiS] chipsets.
 
-  Note that 5591/5592 AGP chipsets are NOT supported.
+  Note that 5591/5592 AGP chipsets are NOT specifically supported;
+  However, the driver works well on these, too.
 
   You should say Y here if you use XFree86 3.3.6 or 4.x and want to
   use GLX or DRI.  If unsure, say N.
 
 Serverworks LE/HE support
 CONFIG_AGP_SWORKS
-  Say Y here to support the Serverworks AGP card.  See 
+  Say Y here to support the Serverworks AGP card.  See
   <http://www.serverworks.com/> for product descriptions and images.
 
 NVIDIA chipset support
@@ -3748,6 +4064,13 @@
   This option gives you AGP GART support for the HP ZX1 chipset
   for IA64 processors.
 
+CONFIG_AGP_ATI
+  This option gives you AGP support for the GLX component of
+  XFree86 4.x on the ATI RadeonIGP family of chipsets.
+
+  You should say Y here if you use XFree86 3.3.6 or 4.x and want to
+  use GLX or DRI.  If unsure, say N.
+
 Support for ISA-bus hardware
 CONFIG_ISA
   Find out whether you have ISA slots on your motherboard.  ISA is the
@@ -5107,21 +5430,23 @@
   This is the frame buffer device driver for the Hitachi HD64461 LCD
   frame buffer card.
 
-SIS acceleration
+SIS display support
 CONFIG_FB_SIS
-  This is the frame buffer device driver for the SiS 630 and 640 Super
-  Socket 7 UMA cards.  Specs available at <http://www.sis.com.tw/>.
+  This is the frame buffer device driver for the SiS 300, 315 and 330
+  series chipsets.  Documentation available at the maintainer's site
+  at <http://www.winischhofer.net/linuxsisvga.shtml>.
 
-SIS 630/540/730 support
+SIS 300 series support
 CONFIG_FB_SIS_300
-  This is the frame buffer device driver for the SiS 630 and related
-  Super Socket 7 UMA cards.  Specs available at
-  <http://www.sis.com.tw/>.
+  This enables support for SiS 300 series chipsets (300/305, 540, 630,
+  730).  Documentation available at the maintainer's website at
+   <http://www.winischhofer.net/linuxsisvga.shtml>.
 
-SIS 315H/315 support
+SIS 315/330 series support
 CONFIG_FB_SIS_315
-  This is the frame buffer device driver for the SiS 315 graphics
-  card.  Specs available at <http://www.sis.com.tw/>.
+  This enables support for SiS 315/330 series chipsets (315, 550, 650,
+  M650, 651, 661FX, M661FX, 740, 741, 330). Documentation available at
+  the maintainer's site <http://www.winischhofer.net/linuxsisvga.shtml>.
 
 IMS Twin Turbo display support
 CONFIG_FB_IMSTT
@@ -5177,6 +5502,17 @@
   is at
   <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
 
+Mach64 Generic LCD support
+CONFIG_FB_ATY_GENERIC_LCD
+  Enabling this option enables the Atyfb driver to drive LCD panels. It
+  will autodetect the resulution and format of your display and emulate
+  other resolutions using the hardware stretcher on the chip.
+  Say Y here if you have computer with a Rage LT Pro, Rage Mobility M1,
+  Rage XC or Rage XL chip and a laptop LCD display or any other LCD display
+  that needs to be digitally driven. It is not necessary to enable this
+  option if you are using an LCD display with a normal VGA connector,
+  but it won't hurt if you do.
+
 ATI Radeon display support
 CONFIG_FB_RADEON
   Choose this option if you want to use an ATI Radeon graphics card as
@@ -5781,6 +6117,61 @@
 
   It is safe to say N here for now.
 
+The SCTP Protocol (EXPERIMENTAL)
+CONFIG_IP_SCTP
+  Stream Control Transmission Protocol
+
+  From RFC 2960 (http://www.ietf.org/rfc/rfc2960.txt)
+
+  "SCTP is a reliable transport protocol operating on top of a
+  connectionless packet network such as IP.  It offers the following
+  services to its users:
+
+  -- acknowledged error-free non-duplicated transfer of user data,
+  -- data fragmentation to conform to discovered path MTU size,
+  -- sequenced delivery of user messages within multiple streams,
+  with an option for order-of-arrival delivery of individual user
+  messages,
+  -- optional bundling of multiple user messages into a single SCTP
+  packet, and
+  -- network-level fault tolerance through supporting of multi-
+  homing at either or both ends of an association."
+
+  This protocol support is also available as a module ( = code which
+  can be inserted in and removed from the running kernel whenever you
+  want). The module will be called sctp. If you want to compile it
+  as a module, say M here and read <file:Documentation/modules.txt>.
+
+  If in doubt, say N.
+
+SCTP: Use old checksum (Adler-32)
+CONFIG_SCTP_ADLER32
+  RCF2960 currently specifies the Adler-32 checksum algorithm for SCTP.
+  This has been deprecated and replaced by an algorithm now referred
+  to as crc32c.
+
+  If you say Y, this will use the Adler-32 algorithm, this might be 
+  useful for interoperation with downlevel peers. 
+
+  If unsure, say N.  
+
+SCTP: Debug messages
+CONFIG_SCTP_DBG_MSG
+  If you say Y, this will enable verbose debugging messages. 
+
+  If unsure, say N.  However, if you are running into problems, use 
+  this option to gather detailed trace information
+
+SCTP: Debug object counts
+CONFIG_SCTP_DBG_OBJCNT
+  If you say Y, this will enable debugging support for counting the 
+  type of objects that are currently allocated.  This is useful for 
+  identifying memory leaks.   If the /proc filesystem is enabled this 
+  debug information can be viewed by 
+  'cat /proc/net/sctp/sctp_dbg_objcnt'
+
+  If unsure, say N
+
 Kernel httpd acceleration
 CONFIG_KHTTPD
   The kernel httpd acceleration daemon (kHTTPd) is a (limited) web
@@ -6915,7 +7306,7 @@
 CONFIG_CISS_SCSI_TAPE
   When enabled (Y), this option allows SCSI tape drives and SCSI medium
   changers (tape robots) to be accessed via a Compaq 5xxx array
-  controller.  (See Documentation/cciss.txt for more details.)
+  controller.  (See <file:Documentation/cciss.txt> for more details.)
 
   "SCSI support" and "SCSI tape support" must also be enabled for this
   option to work.
@@ -6923,6 +7314,15 @@
   When this option is disabled (N), the SCSI portion of the driver
   is not compiled.
 
+Enable monitor thread
+CONFIG_CISS_MONITOR_THREAD
+  Intended for use with multipath configurations (see the md driver).
+  This option allows a per-adapter monitoring thread to periodically
+  poll the adapter to detect failure modes in which the processor
+  is unable to receive interrupts from the adapter, thus enabling 
+  fail-over to an alternate adapter in such situations.  See 
+  <file:Documentation/cciss.txt> for more details.
+
 QuickNet Internet LineJack/PhoneJack support
 CONFIG_PHONE_IXJ
   Say M if you have a telephony card manufactured by Quicknet
@@ -7087,6 +7487,16 @@
   architecture is based on LSI Logic's Message Passing Interface (MPI)
   specification.
 
+Maximum number of scatter gather entries
+CONFIG_FUSION_MAX_SGE
+  This option allows you to specify the maximum number of scatter-
+  gather entries per I/O. The driver defaults to 40, a reasonable number
+  for most systems. However, the user may increase this up to 128.
+  Increasing this parameter will require significantly more memory
+  on a per controller instance. Increasing the parameter is not
+  necessary (or recommended) unless the user will be running
+  large I/O's via the raw interface.
+
 Fusion MPT enhanced SCSI error reporting [optional] module
 CONFIG_FUSION_ISENSE
   The isense module (roughly stands for Interpret SENSE data) is
@@ -7354,6 +7764,27 @@
   there should be no noticeable performance impact as long as you have
   logging turned off.
 
+QDIO base support for IBM S/390 and zSeries
+CONFIG_QDIO
+  This driver provides the Queued Direct I/O base support for the
+  IBM S/390 (G5 and G6) and eServer zSeries (z800 and z900).
+
+  For details please refer to the documentation provided by IBM at
+  <http://www10.software.ibm.com/developerworks/opensource/linux390>
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called qdio.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
+  If unsure, say Y.
+
+Performance statistics for QDIO base support
+CONFIG_QDIO_PERF_STATS
+  Say Y here to get performance statistics in /proc/qdio_perf
+
+  If unsure, say N.
+
 SGI WD93C93 SCSI Driver
 CONFIG_SCSI_SGIWD93
   Say Y here to support the on-board WD93C93 SCSI controller found (a)
@@ -7964,7 +8395,7 @@
   If you want to compile the driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
   say M here and read <file:Documentation/modules.txt>.  The module
-  will be called sym53c8xx.o.
+  will be called sym53c8xx_2.o.
 
 PCI DMA addressing mode
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE
@@ -8627,16 +9058,31 @@
   say M here and read <file:Documentation/modules.txt>.  The module
   will be called AM53C974.o.
 
-AMI MegaRAID support
+AMI MegaRAID support (old driver)
 CONFIG_SCSI_MEGARAID
-  This driver supports the AMI MegaRAID 418, 428, 438, 466, 762, 490
-  and 467 SCSI host adapters.
+  This driver supports the AMI MegaRAID 418, 428, 438, 466, 762, 490,
+  467, 471 and 493 SCSI host adapters. 
+
+  This is the old and very heavily tested driver but lacks features
+  like clustering.
 
   If you want to compile this driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
   say M here and read <file:Documentation/modules.txt>.  The module
   will be called megaraid.o.
 
+AMI MegaRAID support (new driver)
+CONFIG_SCSI_MEGARAID2
+  This driver supports the AMI MegaRAID 418, 428, 438, 466, 762, 490,
+  467, 471, 493 and new Ultra320(518, 520, 531, 532) SCSI host adapters.
+
+  This is the newer less tested but more featureful driver.
+
+  If you want to compile this driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called megaraid2.o.
+
 Intel/ICP (former GDT SCSI Disk Array) RAID Controller support
 CONFIG_SCSI_GDTH
   Formerly called GDT SCSI Disk Array Controller Support.
@@ -8979,6 +9425,17 @@
   Say Y if you really want or need the debugging output, everyone else
   says N.
 
+CONFIG_IEEE1394_OUI_DB
+  If you say Y here, then an OUI list (vendor unique ID's) will be
+  compiled into the ieee1394 module. This doesn't really do much
+  except being able to display the vendor of a hardware node. The
+  downside is that it adds about 300k to the size of the module,
+  or kernel (depending on whether you compile ieee1394 as a
+  module, or static in the kernel).
+
+  This option is not needed for userspace programs like gscanbus
+  to show this information.
+
 Network device support
 CONFIG_NETDEVICES
   You can say N here if you don't intend to connect your Linux box to
@@ -9637,6 +10094,17 @@
   Support for these adaptors is so far still incomplete and buggy.
   You have been warned.
 
+Hermes 802.11b in TMD7160/NCP130 based PCI adaptor support
+CONFIG_TMD_HERMES
+  Enable support for PCMCIA cards supported by the "Hermes" (aka
+  orinoco) driver when used in TMD7160 based PCI adaptors.  These
+  adaptors are not a full PCMCIA controller but act as a more limited
+  PCI <-> PCMCIA bridge.  Several vendors sell such adaptors so that
+  802.11b PCMCIA cards can be used in desktop machines.
+
+  Support for these adaptors is so far still incomplete and buggy.
+  You have been warned.
+
 Prism 2.5 PCI 802.11b adaptor support
 CONFIG_PCI_HERMES
   Enable support for PCI and mini-PCI 802.11b wireless NICs based on
@@ -9902,36 +10370,17 @@
   This driver supports the FarSync T-Series X.21 (and V.35/V.24) cards
   from FarSite Communications Ltd.
   Synchronous communication is supported on all ports at speeds up to
-  8Mb/s (128K on V.24) using synchronous PPP or Cisco HDLC.
+  8Mb/s (128K on V.24) using synchronous PPP, Cisco HDLC, raw HDLC,
+  Frame Relay or X.25/LAPB.
 
   If you want to compile this driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want)
   say M here and read <file:Documentation/modules.txt>.
   The module will be called farsync.o and if you want the module to be
   automatically loaded when the interface is referenced then you
-  should add "alias syncX farsync" to /etc/modules.conf for each
+  should add "alias hdlcX farsync" to /etc/modules.conf for each
   interface, where X is 0, 1, 2, ...
 
-CONFIG_HDLC_DEBUG_PKT
-  This option is for developers only - do NOT use on production
-  systems.
-
-CONFIG_HDLC_DEBUG_HARD_HEADER
-  This option is for developers only - do NOT use on production
-  systems.
-
-CONFIG_HDLC_DEBUG_ECN
-  This option is for developers only - do NOT use on production
-  systems.
-
-CONFIG_HDLC_DEBUG_RINGS
-  If you answer Y here you will be able to get a diagnostic dump of
-  port's TX and RX packet rings, using "sethdlc hdlcX private"
-  command. It does not affect normal operations.
-
-  If unsure, say Y here.
-
-
 Frame Relay (DLCI) support
 CONFIG_DLCI
   This is support for the frame relay protocol; frame relay is a fast
@@ -10456,6 +10905,26 @@
   The module will be called dscc4.o. For general information about
   modules read <file:Documentation/modules.txt>.
 
+PCISYNC feature
+CONFIG_DSCC4_PCISYNC
+  Due to Etinc's design choice for its PCISYNC cards, some operations
+  are only allowed on specific ports of the DSCC4. This option is the
+  only way for the driver to know that it shouldn't return a success
+  code for these operations.
+
+  Please say Y if your card is an Etinc's PCISYNC.
+
+Hard reset support
+CONFIG_DSCC4_PCI_RST
+  Various DSCC4 bug forbid any reliable software reset of the asic.
+  As a replacement, some vendors provide a way to assert the PCI #RST
+  pin of DSCC4 through the GPIO port of the card. If you choose Y, the
+  driver will make use of this feature before module removal (i.e. rmmod).
+  This feature is known to exist on Commtech's cards.
+  Contact your manufacturer for details.
+
+  Say Y if yout card supports this feature.
+
 LanMedia Corp. serial boards (SSI/V.35, T1/E1, HSSI, T3)
 CONFIG_LANMEDIA
   This is a driver for the following Lan Media family of serial
@@ -10804,6 +11273,15 @@
 
   If unsure, say N here.
 
+Raw HDLC Ethernet device support
+CONFIG_HDLC_RAW_ETH
+  Say Y to this option if you want generic HDLC driver to support
+  raw HDLC Ethernet device emulation over WAN (Wide Area Network)
+  connections.
+  You will need it for Ethernet over HDLC bridges.
+
+  If unsure, say N here.
+
 Cisco HDLC support
 CONFIG_HDLC_CISCO
   Say Y to this option if you want generic HDLC driver to support
@@ -10818,13 +11296,6 @@
 
   If unsure, say N here.
 
-Frame-Relay bridging support
-CONFIG_HDLC_FR_BRIDGE
-  Say Y to this option if you want generic HDLC driver to support
-  bridging LAN frames over Frame-Relay links.
-
-  If unsure, say N here.
-
 Synchronous Point-to-Point Protocol (PPP) support
 CONFIG_HDLC_PPP
   Say Y to this option if you want generic HDLC driver to support
@@ -10867,6 +11338,25 @@
 
   If unsure, say N here.
 
+CONFIG_HDLC_DEBUG_PKT
+  This option is for developers only - do NOT use on production
+  systems.
+
+CONFIG_HDLC_DEBUG_HARD_HEADER
+  This option is for developers only - do NOT use on production
+  systems.
+
+CONFIG_HDLC_DEBUG_ECN
+  This option is for developers only - do NOT use on production
+  systems.
+
+CONFIG_HDLC_DEBUG_RINGS
+  If you answer Y here you will be able to get a diagnostic dump of
+  port's TX and RX packet rings, using "sethdlc hdlcX private"
+  command. It does not affect normal operations.
+
+  If unsure, say Y here.
+
 Ethernet (10 or 100Mbit)
 CONFIG_NET_ETHERNET
   Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
@@ -11195,33 +11685,69 @@
 
   The safe and default value for this is N.
 
-SysKonnect SK-98xx and SK-95xx Gigabit Ethernet Adapter family support
+Marvell Yukon / SysKonnect SK-98xx and SK-95xx Gigabit Ethernet Adapter family support
 CONFIG_SK98LIN
-  Say Y here if you have a SysKonnect SK-98xx or SK-95xx Gigabit 
-  Ethernet Server Adapter. The following adapters are supported by 
-  this driver:
-  - SK-9521 10/100/1000Base-T Adapter
-  - SK-9821 Gigabit Ethernet 1000Base-T Server Adapter
-  - SK-9822 Gigabit Ethernet 1000Base-T Dual Port Server Adapter
-  - SK-9841 Gigabit Ethernet 1000Base-LX Server Adapter
-  - SK-9842 Gigabit Ethernet 1000Base-LX Dual Port Server Adapter
-  - SK-9843 Gigabit Ethernet 1000Base-SX Server Adapter
-  - SK-9844 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter
-  - SK-9861 Gigabit Ethernet 1000Base-SX Server Adapter
-  - SK-9862 Gigabit Ethernet 1000Base-SX Dual Port Server Adapter
-  - SK-9871 Gigabit Ethernet 1000Base-ZX Server Adapter
-  - SK-9872 Gigabit Ethernet 1000Base-ZX Dual Port Server Adapter
-  - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
-  - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
-  - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-  - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-  - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-  - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
+  Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx
+  compliant Gigabit Ethernet Adapter. The following adapters are supported
+  by this driver:
+	    - 3Com 3C940 Gigabit LOM Ethernet Adapter
+	    - 3Com 3C941 Gigabit LOM Ethernet Adapter
+	    - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2971T Gigabit Ethernet Adapter
+	    - DGE-530T Gigabit Ethernet Adapter
+	    - EG1032 v2 Instant Gigabit Network Adapter
+	    - EG1064 v2 Instant Gigabit Network Adapter
+	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
+	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
+	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
+	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
+	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
+	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
+	    - Marvell RDK-8001 Adapter
+	    - Marvell RDK-8002 Adapter
+	    - Marvell RDK-8003 Adapter
+	    - Marvell RDK-8004 Adapter
+	    - Marvell RDK-8006 Adapter
+	    - Marvell RDK-8007 Adapter
+	    - Marvell RDK-8008 Adapter
+	    - Marvell RDK-8009 Adapter
+	    - Marvell RDK-8010 Adapter
+	    - Marvell RDK-8011 Adapter
+	    - Marvell RDK-8012 Adapter
+	    - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
+	    - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
+	    - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
+	    - SK-9521 10/100/1000Base-T Adapter
+	    - SK-9521 V2.0 10/100/1000Base-T Adapter
+	    - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
+	    - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
+	    - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
+	    - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
+	    - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
+	    - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
+	    - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
+	    - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+	    - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
+	    - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+	    - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
+	    - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+	    - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
+	    - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
+	    - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
+	    - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
+	    - SMC EZ Card 1000 (SMC9452TXV.2)
 
   The adapters support Jumbo Frames.
   The dual link adapters support link-failover and dual port features.
-  The V2.0 adapters support the scatter-gather functionality with
-  sendfile(). Read Documentation/networking/sk98lin.txt for information about
+  Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support 
+  the scatter-gather functionality with sendfile(). Please refer to 
+  Documentation/networking/sk98lin.txt for more information about
   optional driver parameters.
   Questions concerning this driver may be addressed to:
     linux@syskonnect.de
@@ -11231,6 +11757,7 @@
   say M here and read Documentation/modules.txt. This is recommended.
   The module will be called sk98lin.o.
 
+
 Sun GEM support
 CONFIG_SUNGEM
   Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0.  See also
@@ -13126,6 +13653,15 @@
 
   If unsure, say 'N'.
 
+MTD concatenating support
+CONFIG_MTD_CONCAT
+  Support for concatenating several MTD devices into a single
+  (virtual) one. This allows you to have -for example- a JFFS(2)
+  file system spanning multiple physical flash chips. If unsure,
+  say 'Y'.
+
+  If compiled as a module, it will be called mtdconcat.o.
+
 ARM Firmware Suite flash layout / partition parsing
 CONFIG_MTD_AFS_PARTS
   The ARM Firmware Suite allows the user to divide flash devices into
@@ -13532,6 +14068,14 @@
   D-Box 2 board. If you have one of these boards and would like to use
   the flash chips on it, say 'Y'.
 
+CFI Flash devices mapped on IBM Redwood
+CONFIG_MTD_REDWOOD
+  This enables access routines for the flash chips on the IBM
+  Redwood board. If you have one of these boards and would like to
+  use the flash chips on it, say 'Y'.
+
+  If compiled as a module, it will be called redwood.o.
+
 CFI Flash device mapped on the XScale IQ80310 board
 CONFIG_MTD_IQ80310
   This enables access routines for the flash chips on the Intel XScale
@@ -13664,6 +14208,20 @@
 CONFIG_MTD_NAND_SPIA
   If you had to ask, you don't have one. Say 'N'.
 
+SmartMediaCard on autronix autcpu12 board
+CONFIG_MTD_NAND_AUTCPU12
+  This enables the driver for the autronix autcpu12 board to
+  access the SmartMediaCard.
+
+  If compiled as a module, it will be called autcpu12.o.
+
+Support for Cirrus Logic EBD7312 evaluation board
+CONFIG_MTD_NAND_EDB7312
+  This enables the driver for the Cirrus Logic EBD7312 evaluation
+  board to access the onboard NAND Flash.
+
+  If compiled as a module, it will be called edb7312.o.
+
 M-Systems Disk-On-Chip 1000 support
 CONFIG_MTD_DOC1000
   This provides an MTD device driver for the M-Systems DiskOnChip
@@ -14162,8 +14720,8 @@
 USB HIDBP Mouse (basic) support
 CONFIG_USB_MOUSE
   Say Y here only if you are absolutely sure that you don't want
-  to use the generic HID driver for your USB keyboard and prefer
-  to use the keyboard in its limited Boot Protocol mode instead.
+  to use the generic HID driver for your USB mouse and prefer
+  to use the mouse in its limited Boot Protocol mode instead.
 
   This is almost certainly not what you want.
 
@@ -14523,6 +15081,9 @@
 CONFIG_USB_SERIAL_KEYSPAN_USA49W
   Say Y here to include firmware for the USA-49W converter.
 
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC
+  Say Y here to include firmware for the USA-49WLC converter.
+
 USB ZyXEL omni.net LCD Plus Driver
 CONFIG_USB_SERIAL_OMNINET
   Say Y here if you want to use a ZyXEL omni.net LCD ISDN TA.
@@ -15529,21 +16090,15 @@
   architectural foundations.
 
   In general, ReiserFS is as fast as ext2, but is very efficient with
-  large directories and small files.  Additional patches are needed
-  for NFS and quotas, please see <http://www.reiserfs.org/> for links.
-
-  It is more easily extended to have features currently found in
-  database and keyword search systems than block allocation based file
-  systems are.  The next version will be so extended, and will support
-  plugins consistent with our motto ``It takes more than a license to
-  make source code open.''
+  large directories and small files.  It is much faster for writes,
+  and slightly slower for reads than ext2.  It is much faster than
+  ext3.  It will be obsoleted by Reiser4 in not too long, so keep
+  an eye on our website for when Reiser4 ships.
 
-  Read <http://www.reiserfs.org/> to learn more about reiserfs.
+  Mount with the notail option if performance matters more to you than
+  saving space (the design flaw underlying this is fixed in reiser4).
 
-  Sponsored by Threshold Networks, Emusic.com, and Bigstorage.com.
-
-  If you like it, you can pay us to add new features to it that you
-  need, buy a support contract, or pay us to port it to another OS.
+  Read <http://www.namesys.com> to learn more about reiserfs.
 
 Enable extra Reiserfs consistency checks
 CONFIG_REISERFS_CHECK
@@ -17494,6 +18049,24 @@
 
   Enable this option if you intend to use a HIL keyboard.
 
+HP System Device Controller support
+CONFIG_HP_SDC
+  This option enables supports for the the "System Device Controller",
+  an i8042 carrying microcode to manage a few miscellanous devices
+  on some Hewlett Packard systems.  The SDC itself contains a 10ms
+  resolution timer/clock capable of delivering interrupts on periodic
+  and one-shot basis.  The SDC may also be connected to a battery-backed
+  real-time clock, a basic audio waveform generator, and an HP-HIL
+  Master Link Controller serving up to seven input devices.
+
+  By itself this option is rather useless, but enabling it will
+  enable selection of drivers for the abovementioned devices.
+  It is, however, incompatible with the old, reliable HIL keyboard
+  driver, and the new HIL driver is experimental, so if you plan to
+  use a HIL keyboard as your primary keyboard, you may wish to
+  keep using that driver until the new HIL drivers have had more
+  testing.
+
 Include IOP (IIfx/Quadra 9x0) ADB driver
 CONFIG_ADB_IOP
   The I/O Processor (IOP) is an Apple custom IC designed to provide
@@ -17809,6 +18382,19 @@
   read <file:Documentation/modules.txt>. The module will be called
   istallion.o.
 
+PDC software console support
+CONFIG_PDC_CONSOLE
+  Saying Y here will enable the software based PDC console to be
+  used as the system console.  This is useful for machines in
+  which the hardware based console has not been written yet.  The
+  following steps must be competed to use the PDC console:
+
+    1. create the device entry (mknod /dev/ttyB0 c 60 0)
+    2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0
+    3. Add device ttyB0 to /etc/securetty (if you want to log on as
+         root on this console.)
+    4. Change the kernel command console parameter to: console=ttyB0
+
 Microgate SyncLink adapter support
 CONFIG_SYNCLINK
   Provides support for the SyncLink ISA and PCI multiprotocol serial
@@ -18259,6 +18845,15 @@
   it as a module, say M here and read <file:Documentation/modules.txt>.
   The module will be called i2c-proc.o.
 
+Powermac Keywest I2C interface
+CONFIG_I2C_KEYWEST
+  This supports the use of the I2C interface in the combo-I/O
+  chip on recent Apple machines.  Say Y if you have such a machine.
+
+  This driver is also available as a module.  If you want to compile
+  it as a module, say M here and read Documentation/modules.txt.
+  The module will be called i2c-keywest.o.
+
 Bus Mouse Support
 CONFIG_BUSMOUSE
   Say Y here if your machine has a bus mouse as opposed to a serial
@@ -18768,6 +19363,13 @@
   selected, the module will be called i810.o.  AGP support is required
   for this driver to work.
 
+Intel 830M, 845G, 852GM, 855GM, 865G
+CONFIG_DRM_I830
+  Choose this option if you have a system that has Intel 830M, 845G,
+  852GM, 855GM or 865G integrated graphics.  If M is selected, the
+  module will be called i830.o.  AGP support is required for this driver
+  to work.
+
 Matrox G200/G400/G450
 CONFIG_DRM_MGA
   Choose this option if you have a Matrox G200, G400 or G450 graphics
@@ -18921,6 +19523,21 @@
 
   If unsure, say N.
 
+Intel/AMD/VIA HW Random Number Generator support
+CONFIG_HW_RANDOM
+  This driver provides kernel-side support for the
+  Random Number Generator hardware found on Intel i8xx-based motherboards,
+  AMD 76x-based motherboards, and Via Nehemiah CPUs.
+
+  Provides a character driver, used to read() entropy data.
+
+  To compile this driver as a module ( = code which can be inserted in
+  and removed from the running kernel whenever you want), say M here
+  and read <file:Documentation/modules.txt>. The module will be called
+  hw_random.
+
+  If unsure, say N.
+
 Power Management support
 CONFIG_PM
   "Power Management" means that parts of your computer are shut
@@ -18970,30 +19587,8 @@
   The ACPI Sourceforge project may also be of interest:
   <http://sf.net/projects/acpi/>
 
-ACPI Processor Enumeration for HT
-CONFIG_ACPI_HT_ONLY
-  ACPI enumerates both logical (a.k.a. Hyper-Threaded -- HT)
-  and physical processors.  It is designed to obsolete several older
-  specifications, including the MultiProcessor Specification (MPS),
-  which supported only physical processors.
-
-  CONFIG_ACPI_HT_ONLY includes just the minimal ACPI boot-time code
-  necessary to enumerate logical processors and enable HT.
-
-  CONFIG_ACPI includes this code, plus IO APIC enumeration,
-  and the hooks to run the ACPI AML interpreter for run-time events.
-
-  When CONFIG_ACPI is selected, the command-line option "acpi=ht"
-  is available to run just the ACPI boot-time code -- just as if
-  only CONFIG_ACPI_HT_ONLY were selected.
-
   Note that "acpi=off" can be used to disable all ACPI code in the kernel.
 
-Enable ACPI 2.0 with errata 1.3
-CONFIG_ACPI20
-  Enable support for the 2.0 version of the ACPI interpreter.  See the
-  help for ACPI for caveats and discussion.
-
 ACPI kernel configuration manager
 CONFIG_ACPI_KERNEL_CONFIG
   If you say `Y' here, Linux's ACPI support will use the
@@ -19013,23 +19608,6 @@
   particular, many Toshiba laptops require this for correct operation
   of the AC module.
 
-ACPI Bus Manager
-CONFIG_ACPI_BUSMGR
-  The ACPI Bus Manager enumerates devices in the ACPI namespace, and
-  handles PnP messages.  All ACPI devices use its services, so using
-  them requires saying Y here.
-
-ACPI System Driver
-CONFIG_ACPI_SYS
-  This driver will enable your system to shut down using ACPI, and
-  dump your ACPI DSDT table using /proc/acpi/dsdt.
-
-ACPI Processor Driver
-CONFIG_ACPI_CPU
-  This driver installs ACPI as the idle handler for Linux, and uses
-  ACPI C2 and C3 processor states to save power, on systems that
-  support it.
-
 ACPI Button
 CONFIG_ACPI_BUTTON
   This driver registers for events based on buttons, such as the
@@ -19064,11 +19642,6 @@
   the battery and thermal drivers.  If you are compiling for a laptop,
   say Y.
 
-ACPI Control Method Battery
-CONFIG_ACPI_CMBATT
-  This driver adds support for battery information through
-  /proc/acpi/battery. If you have a laptop with a battery, say Y.
-
 ACPI Thermal
 CONFIG_ACPI_THERMAL
   This driver handles overheating conditions on laptops. It is HIGHLY
@@ -19084,6 +19657,9 @@
   display brightness and output, switching the LCD backlight on and off,
   and most importantly, allows you to blink those fancy LEDs intended
   for reporting mail and wireless status.
+
+  Note: the display switching code is currently considered EXPERIMENTAL,
+  toying with these values may even lock your machine.
   
   All settings are changed via /proc/acpi/asus directory entries. Owner
   and group for these entries can be set with asus_uid and asus_gid
@@ -19561,6 +20137,15 @@
   <file:Documentation/modules.txt>. The module will be called
   cpuid.o
 
+x86 BIOS Enhanced Disk Drive support
+CONFIG_EDD
+  Say Y or M here if you want to enable BIOS Enhanced Disk Drive
+  Services real mode BIOS calls to determine which disk
+  BIOS tries boot from.  This information is then exported via /proc.
+
+  This option is experimental, but believed to be safe,
+  and most disk controller BIOS vendors do not yet implement this feature.
+
 SBC-60XX Watchdog Timer
 CONFIG_60XX_WDT
  This driver can be used with the watchdog timer found on some
@@ -21540,6 +22125,11 @@
   This enables HiSax support for the HFC-S+, HFC-SP and HFC-PCMCIA
   cards. This code is not finished yet.
 
+Formula-n enter:now PCI card (EXPERIMENTAL)
+CONFIG_HISAX_ENTERNOW_PCI
+  This enables HiSax support for the Formula-n enter:now PCI
+  ISDN card.
+
 Am7930
 CONFIG_HISAX_AMD7930
   This enables HiSax support for the AMD7930 chips on some SPARCs.
@@ -22687,15 +23277,16 @@
   want). The module is called ariadne.o. If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
-Ariadne II and X-Surf support
-CONFIG_ARIADNE2
-  This driver is for the Village Tronic Ariadne II and the Individual
+Zorro NS8390-based Ethernet support
+CONFIG_ZORRO8390
+  This driver is for Zorro Ethernet cards using an NS8390-compatible
+  chipset, like the Village Tronic Ariadne II and the Individual
   Computers X-Surf Ethernet cards. If you have such a card, say Y.
   Otherwise, say N.
 
   This driver is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
-  The module will be called ariadne2.o. If you want to compile it as
+  The module is called zorro8390.o. If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
 A2065 support
@@ -23468,6 +24059,38 @@
       /proc/sys/dev/mac_hid/mouse_button2_keycode
       /proc/sys/dev/mac_hid/mouse_button3_keycode
 
+Set high memory pool address
+CONFIG_HIGHMEM_START_BOOL
+  Unless you know what you are doing you *should not* set this option.
+
+  It can be used to override the default PKMAP_BASE address which
+  is the location of the high memory pool.  This can be useful in
+  optimizing virtual memory usage in a system.
+
+Set maximum low memory
+CONFIG_LOWMEM_SIZE_BOOL
+  Unless you know what you are doing you *should not* set this option.
+
+  It can be used to override the standard calculated value of
+  MAX_LOW_MEM. This can be useful in optimizing virtual memory usage
+  in a system.
+
+Set custom kernel base address
+CONFIG_KERNEL_START_BOOL
+  Unless you know what you are doing you *should not* set this option.
+
+  It can be used to override the standard PAGE_OFFSET/KERNELBASE
+  value used by the kernel.  This can be useful in controlling
+  amount of virtual address space available to the kernel.
+
+Set custom user task size
+CONFIG_TASK_SIZE_BOOL
+  Unless you know what you are doing you *should not* set this option.
+
+  It can be used to override the standard TASK_SIZE value used
+  by the kernel.  This can be useful in controlling amount of
+  virtual address space available to user tasks.
+
 Enhanced Real Time Clock Support (/dev/rtc)
 CONFIG_PPC_RTC
   If you say Y here and create a character special file /dev/rtc with
@@ -24735,6 +25358,46 @@
   Say Y if you want support for the ARM1020 processor.
   Otherwise, say N.
 
+Disable I-Cache
+CONFIG_CPU_ICACHE_DISABLE
+  Say Y here to disable the processor instruction cache. Unless
+  you have a reason not to or are unsure, say N.
+
+Disable D-Cache
+CONFIG_CPU_DCACHE_DISABLE
+  Say Y here to disable the processor data cache. Unless
+  you have a reason not to or are unsure, say N.
+
+Force write through D-cache
+CONFIG_CPU_DCACHE_WRITETHROUGH
+  Say Y here to use the data cache in write-through mode. Unless you
+  specifically require this or are unsure, say N.
+
+Round robin I and D cache replacement algorithm
+CONFIG_CPU_CACHE_ROUND_ROBIN
+  Say Y here to use the predictable round-robin cache replacement
+  policy.  Unless you specifically require this or are unsure, say N.
+
+Disable branch prediction
+CONFIG_CPU_BPREDICT_DISABLE
+  Say Y here to disable branch prediction.  If unsure, say N.
+
+Compressed boot loader in ROM/flash
+CONFIG_ZBOOT_ROM
+  Say Y here if you intend to execute your compressed kernel image (zImage)
+  directly from ROM or flash.  If unsure, say N.
+
+Compressed ROM boot loader base address
+CONFIG_ZBOOT_ROM_TEXT
+  The base address for zImage.  Unless you have special requirements, you
+  should not change this value.
+
+Compressed ROM boot loader BSS address
+CONFIG_ZBOOT_ROM_BSS
+  The base address of 64KiB of read/write memory, which must be available
+  while the decompressor is running.  Unless you have special requirements,
+  you should not change this value.
+
 Support StrongARM SA-110 processor
 CONFIG_CPU_SA110
   The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and
@@ -24894,6 +25557,19 @@
   output to the second serial port on these devices.  Saying N will
   cause the debug messages to appear on the first serial port.
 
+Kernel log buffer length shift
+CONFIG_LOG_BUF_SHIFT
+  The kernel log buffer has a fixed size of :
+      64 kB (2^16) on MULTIQUAD and IA64,
+     128 kB (2^17) on S390
+      32 kB (2^15) on SMP systems
+      16 kB (2^14) on UP systems
+
+  You have the ability to change this size with this paramter which
+  fixes the bit shift of to get the buffer length (which must be a
+  power of 2). Eg: a value of 16 sets the buffer to 64 kB (2^16).
+  The default value of 0 uses standard values above.
+
 Disable pgtable cache
 CONFIG_NO_PGT_CACHE
   Normally the kernel maintains a `quicklist' of preallocated
@@ -25250,6 +25926,44 @@
   brave people.  System crashes and other bad things are likely to occur if
   you use this driver.  If in doubt, select N.
 
+Tieman Voyager USB Braille display support (EXPERIMENTAL)
+CONFIG_USB_BRLVGER
+  Say Y here if you want to use the Voyager USB Braille display from
+  Tieman. See <file:Documentation/usb/brlvger.txt> for more
+  information.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called brlvger.o. If you want to compile it as
+  a module, say M here and read <file:Documentation/modules.txt>.
+
+KB Gear JamStudio tablet support
+CONFIG_USB_KBTAB
+  Say Y here if you want to use the USB version of the KB Gear
+  JamStudio tablet.  Make sure to say Y to "Mouse support"
+  (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+  (CONFIG_INPUT_EVDEV) as well.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called kbtab.o.  If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
+USB Inside Out Edgeport Serial Driver (TI devices)
+CONFIG_USB_SERIAL_EDGEPORT_TI
+  Say Y here if you want to use any of the devices from Inside Out
+  Networks (Digi) that are not supported by the io_edgeport driver.
+  This includes the Edgeport/1 device.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called io_ti.o.  If you want to compile it
+  as a module, say M here and read <file:Documentation/modules.txt>.
+
+USB Keyspan MPR Firmware
+CONFIG_USB_SERIAL_KEYSPAN_MPR
+  Say Y here to include firmware for the Keyspan MPR converter.
+
 Winbond W83977AF IrDA Device Driver
 CONFIG_WINBOND_FIR
   Say Y here if you want to build IrDA support for the Winbond
@@ -26294,11 +27008,13 @@
 # Choice: ia64type
 Itanium
 CONFIG_ITANIUM
-  Select your IA64 processor type.  The default is Intel Itanium.
+  Select your IA-64 processor type.  The default is Intel Itanium.
+  This choice is safe for all IA-64 systems, but may not perform
+  optimally on systems with, say, Itanium 2 or newer processors.
 
-McKinley
+Itanium 2
 CONFIG_MCKINLEY
-  Select this to configure for a McKinley processor.
+  Select this to configure for an Itanium 2 (McKinley) processor.
 
 # Choice: ia64system
 IA-64 system type
@@ -26355,6 +27071,14 @@
   Say Y here to enable machine check support for IA-64.  If you're
   unsure, answer Y.
 
+Use PAL_HALT_LIGHT in idle loop
+CONFIG_IA64_PAL_IDLE
+  Say Y here to enable use of PAL_HALT_LIGHT in the cpu_idle loop.
+  This allows the CPU to enter a low power state when idle.  You
+  can enable CONFIG_IA64_PALINFO and check /proc/pal/cpu0/power_info
+  to see the power consumption and latency for this state.  If you're
+  unsure your firmware supports it, answer N.
+
 Disable IA-64 Virtual Hash Page Table
 CONFIG_DISABLE_VHPT
   The Virtual Hash Page Table (VHPT) enhances virtual address
@@ -26375,12 +27099,31 @@
   and restore instructions.  It's useful for tracking down spinlock
   problems, but slow!  If you're unsure, select N.
 
-Early printk support (requires VGA!)
+Early printk support
 CONFIG_IA64_EARLY_PRINTK
-  Selecting this option uses the VGA screen for printk() output before
-  the consoles are initialised.  It is useful for debugging problems
-  early in the boot process, but only if you have a VGA screen
-  attached.  If you're unsure, select N.
+  Selecting this option uses a UART or VGA screen (or both) for
+  printk() output before the consoles are initialised.  It is useful
+  for debugging problems early in the boot process, but only if you
+  have a serial terminal or a VGA screen attached.  If you're unsure,
+  select N.
+
+Early printk on serial port
+CONFIG_IA64_EARLY_PRINTK_UART
+  Select this option to use a serial port for early printk() output.
+  You must also select either CONFIG_IA64_EARLY_PRINTK_UART_BASE or
+  CONFIG_SERIAL_HCDP.  If you select CONFIG_SERIAL_HCDP, early
+  printk() output will appear on the first console device described by
+  the HCDP.  If you set CONFIG_IA64_EARLY_PRINTK_UART_BASE, the HCDP
+  will be ignored.
+
+UART base address
+CONFIG_IA64_EARLY_PRINTK_UART_BASE
+  The physical MMIO address of the UART to use for early printk().
+  This overrides any UART located using the EFI HCDP table.
+
+Early printk on VGA
+CONFIG_IA64_EARLY_PRINTK_VGA
+  Select this option to use VGA for early printk() output.
 
 Print possible IA64 hazards to console
 CONFIG_IA64_PRINT_HAZARDS
@@ -26405,6 +27148,58 @@
   To use this option, you have to check that the "/proc file system
   support" (CONFIG_PROC_FS) is enabled, too.
 
+PPC4xx DMA controller support
+CONFIG_PPC4xx_DMA
+  Select this to enable support for the PPC4xx general purpose DMA
+  controller.
+
+ttyS0 device
+CONFIG_UART0_TTYS0
+  This option reverses the mapping between the hardware UART and software
+  device.  Selecting UART0 gives the normal mapping of UART0=ttyS0 and
+  UART1=ttyS1.  Selecting UART1 gives the reverse mapping of UART0=ttyS1
+  and UART1=ttyS0.  Most people will use UART0.
+
+PowerPC 405 on-chip ethernet
+CONFIG_IBM_OCP_ENET
+  If you want to use the 405 built-in ethernet select this.
+
+CONFIG_IBM_OCP_ENET_ERROR_MSG
+  Enable this option to print verbose debug messages for troubleshooting.
+
+PowerPC 405 on-chip ethernet -- Number of receive buffers
+CONFIG_IBM_OCP_ENET_RX_BUFF
+  Number of ethernet receive (read) buffers.  Unless you know what you
+  are doing the default should be fine.
+
+PowerPC 405 on-chip ethernet -- Number of transmit buffers
+CONFIG_IBM_OCP_ENET_TX_BUFF
+  Number of ethernet transmit (write) buffers.  Unless you know what
+  you are doing the default should be fine.
+
+PowerPC 405 on-chip ethernet -- Amount of bytes to Reserve on a skb
+CONFIG_IBM_OCP_ENET_SKB_RES
+  Many standard ethernet drivers need to reserve 2 bytes of data
+  on the skb before giving the data ptr to the hardware. This is
+  so the IP data will be 16-byte aligned when it goes up the stack.
+  This is a requirement for some processors and it can cause major
+  slow downs on others. The 405GP dose not have problems with the 
+  misaligned data so the default is 0. If you need to route the
+  incoming ethernet packets to another device that has alignment
+  requirements this can help remove a data copy. A value of 2 can
+  help at getting 16-byte aligned IP data for another device. A
+  larger value can be used when routing to a IP tunnel device.
+  Make sure XXX_DESC_SIZE - XXX_SKB_RES >= 1514, or larger if VLANS
+  are used.
+
+PPC 405 I2C Algorithm
+CONFIG_PPC405_I2C_ALGO
+  Enable this option to use the built-in I2C on your 405.
+
+PPC 405 I2C Adapter
+CONFIG_PPC405_I2C_ADAP
+  Enable this option to use the built-in I2C on your 405.
+
 /proc/efi/vars support
 CONFIG_EFI_VARS
   If you say Y here, you are able to get EFI (Extensible Firmware
@@ -26497,6 +27292,11 @@
   best used in conjunction with the NMI watchdog so that spinlock
   deadlocks are also debuggable.
 
+Additional run-time checks
+CONFIG_CHECKING
+  Enables some internal consistency checks for kernel debugging.
+  You should normally say N.
+
 Read-write spinlock debugging
 CONFIG_DEBUG_RWLOCK
   If you say Y here then read-write lock processing will count how many
@@ -27170,6 +27970,12 @@
 
   If unsure, say N.
 
+Hotplug firmware loading support (EXPERIMENTAL)
+CONFIG_FW_LOADER
+  This option is provided for the case where no in-kernel-tree modules require
+  hotplug firmware loading support, but a module built outside the kernel tree
+  does.
+
 NatSemi SCx200 support
 CONFIG_SCx200
   This provides basic support for the National Semiconductor SCx200
@@ -27395,6 +28201,82 @@
   kernel tree does. Such modules that use library CRC32 functions
   require that you say M or Y here.
 
+Chassis LCD and LED support
+CONFIG_CHASSIS_LCD_LED
+  Say Y here if you want to enable support for the Heartbeat,
+  Disk/Network activities LEDs on some PA-RISC machines,
+  or support for the LCD that can be found on recent material.
+
+  This has nothing to do with LED State support for A, J and E class.
+
+  If unsure, say Y.
+
+VSC/GSC/HSC bus support
+CONFIG_GSC
+  The VSC, GSC and HSC busses were used from the earliest 700-series
+  workstations up to and including the C360/J2240 workstations.  They
+  were also used in servers from the E-class to the K-class.  They
+  are not found in B1000, C3000, J5000, A500, L1000, N4000 and upwards.
+  If in doubt, say "Y".
+
+Wax I/O support
+CONFIG_GSC_WAX
+  Say Y here to support the Wax multifunction chip found in some
+  older systems, including B/C/D/R class and 715/64, 715/80 and
+  715/100.  Wax includes an EISA adapter, a serial port (not always
+  used), a HIL interface chip and is also known to be used as the
+  GSC bridge for an X.25 GSC card.
+
+GSCtoPCI/Dino PCI support
+CONFIG_GSC_DINO
+  Say Y here to support the Dino & Cujo GSC to PCI bridges found in
+  machines from the B132 to the C360, the J2240 and the A180.  Some
+  GSC/HSC cards (eg gigabit & dual 100 Mbit Ethernet) have a Dino on
+  the card, and you also need to say Y here if you have such a card.
+  Note that Dino also supplies one of the serial ports on certain
+  machines.  If in doubt, say Y.
+
+HPET timers
+CONFIG_HPET_TIMER
+  Use the IA-PC HPET (High Precision Event Timer) to manage
+  time in preference to the PIT and RTC, if a HPET is
+  present.  The HPET provides a stable time base on SMP
+  systems, unlike the RTC, but it is more expensive to access,
+  as it is off-chip.  You can find the HPET spec at
+  <http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>.
+
+  If unsure, say Y.
+
+IOMMU support
+CONFIG_GART_IOMMU
+  Support the K8 IOMMU. Needed to run systems with more than 4GB of memory
+  properly with 32-bit PCI devices that do not support DAC (Double Address
+  Cycle). The IOMMU can be turned off at runtime with the iommu=off parameter.
+  Normally the kernel will take the right choice by itself.
+  If unsure say Y
+
+Debug __init statements
+CONFIG_INIT_DEBUG
+  Fill __init and __initdata at the end of boot. This helps debugging
+  invalid uses of __init and __initdata after initialization.	
+
+Force IOMMU to on
+CONFIG_IOMMU_DEBUG
+  Force the IOMMU to on even when you have less than 4GB of memory and add
+  debugging code.
+  Can be disabled at boot time with iommu=noforce.
+
+IOMMU leak tracing
+CONFIG_IOMMU_LEAK
+  Add a simple leak tracer to the IOMMU code. This is useful when you
+  are debugging a buggy device driver that leaks IOMMU mappings.
+
+pSeries Hypervisor Virtual Console support
+CONFIG_HVC_CONSOLE
+  pSeries machines when partitioned support a hypervisor virtual
+  console. This driver allows each pSeries partition to have a console
+  which is accessed via the HMC.
+
 CONFIG_CRYPTO
   This option provides the core Cryptographic API.
 
@@ -27478,6 +28360,12 @@
 
   See http://csrc.nist.gov/encryption/aes/ for more information.
 
+CONFIG_CRYPTO_CAST5
+  CAST5 (CAST-128) cipher algorithm.
+
+  The CAST5 encryption algorithm (synonymous with CAST-128) is
+  described in RFC2144.
+
 CONFIG_CRYPTO_DEFLATE
   This is the Deflate algorithm (RFC1951), specified for use in
   IPSec with the IPCOMP protocol (RFC3173, RFC2394).
@@ -27486,6 +28374,28 @@
 
 CONFIG_CRYPTO_TEST
   Quick & dirty crypto test module.
+  
+CONFIG_SOUND_WM97XX
+  Say Y here to support the Wolfson WM9705 and WM9712 touchscreen
+  controllers. These controllers are mainly found in PDA's 
+  i.e. Dell Axim and Toshiba e740
+
+  This is experimental code.
+  Please see Documentation/wolfson-touchscreen.txt for
+  a complete list of parameters.
+  
+  In order to use this driver, a char device called wm97xx with a major
+  number of 10 and minor number 16 will have to be created under 
+  /dev/touchscreen.
+  
+  e.g.
+  mknod /dev/touchscreen/wm97xx c 10 16
+
+  If you want to compile this as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here.  The module will be called ac97_plugin_wm97xx.o.
+  
+  If unsure, say N.
 
 #
 # A couple of things I keep forgetting:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/README.nsp32_cb.eng linux-2.4.23-pre8/Documentation/README.nsp32_cb.eng
--- linux-2.4.22/Documentation/README.nsp32_cb.eng	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/README.nsp32_cb.eng	2003-10-22 22:49:10.000000000 +0000
@@ -0,0 +1,57 @@
+	<<NinjaSCSI-32Bi/UDE CardBus/PCI card driver for Linux>>
+
+
+1. What's this?
+
+ This is Workbit corp.'s(http://www.workbit.co.jp/) NinjaSCSI-32Bi
+(http://www.workbit.co.jp/ts/z_njsc32bi.html) PCMCIA card and NinjaSCSI-32UDE
+PCI card driver module for Linux.
+
+
+
+2. Install
+
+[1] This driver requires Kernel 2.4.x/2.6.x or later.
+    And you want to load the module when Ninja card was inserted, you also
+    install "hotplug" (http://linux-hotplug.sourceforge.net/) utility.
+
+[2] Insert Ninja card to your PC, and check your card is NinjaSCSI-32Bi/UDE
+    card.
+
+# lspci
+....
+01:00.0 SCSI storage controller: I-O Data Device, Inc. CBSC-II duo SCSI PCMCIA card (rev 01)
+
+[3] This driver requires Kernel 2.4/2.6's source code. Please install cernel
+    source code.
+
+[4] Please check your kernel have PCI, CardBus, PCMCIA and SCSI support.
+    If not, rebuild your kernel. And also requires PCMCIA-CS if you use
+    CardBus card.
+
+[5] Extract this archive somewhere.
+
+[6] Edit "Makefile" and type "make" to compile the driver.
+
+[7] Copy "nsp32.o" to /lib/modules/<kernel version>/kernel/driver/scsi/pcmcia/ .
+
+[8] Type "depmod -ae" to re-made "/lib/modules/<kernel version>/modules.pcimap"
+
+[9] Ok. Now you can use Ninja card in CardBus mode. Check your Ninja card is in
+    CardBus mode, and insert the card to PC card slot.
+
+
+
+3. Caution
+ If you eject card when doing some operation for your SCSI device or suspend
+your computer, you encount some *BAD* error like disk crash.
+ It works good when I using this driver right way. But I'm not guarantee
+your data. Please backup your data when you use this driver.
+
+
+4. Copyright.
+
+ No, no, this is Copyleft software. See GPL.
+
+
+YOKOTA Hiroshi
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/README.nsp_cs.eng linux-2.4.23-pre8/Documentation/README.nsp_cs.eng
--- linux-2.4.22/Documentation/README.nsp_cs.eng	2001-10-11 18:17:22.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/README.nsp_cs.eng	2003-10-22 22:49:16.000000000 +0000
@@ -8,8 +8,8 @@
 for Linux.
 
 2. My Linux environment
-Linux kernel: 2.4.7 / 2.2.19
-pcmcia-cs:    3.1.27
+Linux kernel: 2.4.20 / 2.5.63
+pcmcia-cs:    3.1.33
 gcc:          gcc-2.95.4
 PC card:      I-O data PCSC-F (NinjaSCSI-3)
               I-O data CBSC-II in 16 bit mode (NinjaSCSI-32Bi)
@@ -46,22 +46,16 @@
 $ make config
 ...
 
-[3] If you use this driver with Kernel 2.2, Unpack pcmcia-cs in some directory
-    and make & install. This driver requies pcmcia-cs header file.
-$ cd /usr/src
-$ tar zxvf cs-pcmcia-cs-3.x.x.tar.gz
-...
-
-[4] Extract this driver's archive somewhere, and edit Makefile, then do make.
+[3] Extract this driver's archive somewhere, and edit Makefile, then do make.
 $ tar -zxvf nsp_cs-x.x.tar.gz
 $ cd nsp_cs-x.x
 $ emacs Makefile
 ...
 $ make
 
-[5] Copy nsp_cs.o to suitable plase, like /lib/modules/<Kernel version>/pcmcia/ .
+[4] Copy nsp_cs.o to suitable plase, like /lib/modules/<Kernel version>/pcmcia/ .
 
-[6] Add these lines to /etc/pcmcia/config .
+[5] Add these lines to /etc/pcmcia/config .
     If you yse pcmcia-cs-3.1.8 or later, we can use "nsp_cs.conf" file.
     So, you don't need to edit file. Just copy to /etc/pcmcia/ .
 
@@ -97,7 +91,7 @@
   bind "nsp_cs"
 -------------------------------------
 
-[7] Start (or restart) pcmcia-cs.
+[6] Start (or restart) pcmcia-cs.
 # /etc/rc.d/rc.pcmcia start        (BSD style)
 or
 # /etc/init.d/pcmcia start         (SYSV style)
@@ -113,8 +107,7 @@
 your data. Please backup your data when you use this driver.
 
 6. Known Bugs
- In 2.4 kernel, you can't use 640MB Optical disk. This error comes from
-high level SCSI driver.
+ Many bugs in this driver. Be careful!
 
 7. Testing
  Please send me some reports(bug reports etc..) of this software.
@@ -127,4 +120,4 @@
  See GPL.
 
 
-2001/08/08 yokota@netlab.is.tsukuba.ac.jp <YOKOTA Hiroshi>
+2002/01/17 yokota@netlab.is.tsukuba.ac.jp <YOKOTA Hiroshi>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/SubmittingDrivers linux-2.4.23-pre8/Documentation/SubmittingDrivers
--- linux-2.4.22/Documentation/SubmittingDrivers	2002-11-28 23:53:08.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/SubmittingDrivers	2003-10-22 22:49:12.000000000 +0000
@@ -35,12 +35,12 @@
 
 Linux 2.4:
 	The same rules apply as 2.2. The final contact point for Linux 2.4 
-	submissions is Marcelo Tosatti <marcelo@conectiva.com.br>.
+	submissions is Marcelo Tosatti <marcelo@cyclades.com>.
 
 Linux 2.5:
 	The same rules apply as 2.4 except that you should follow linux-kernel
 	to track changes in API's. The final contact point for Linux 2.5
-	submissions is Linus Torvalds <torvalds@transmeta.com>.
+	submissions is Linus Torvalds <torvalds@osdl.org>.
 
 What Criteria Determine Acceptance
 ----------------------------------
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/cciss.txt linux-2.4.23-pre8/Documentation/cciss.txt
--- linux-2.4.22/Documentation/cciss.txt	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/cciss.txt	2003-10-22 22:47:47.000000000 +0000
@@ -13,6 +13,7 @@
 	* SA 642
 	* SA 6400
 	* SA 6400 U320 Expansion Module
+	* SA 6i
 
 If nodes are not already created in the /dev/cciss directory
 
@@ -53,6 +54,56 @@
 /dev/cciss/c1d1p2		Controller 1, disk 1, partition 2
 /dev/cciss/c1d1p3		Controller 1, disk 1, partition 3
 
+Support for more than 8 controllers
+-----------------------------------
+Originally the driver only supports 8 controllers in the system,
+and this is due to the major numbers assigned to the driver
+(104 thru 111).
+
+The driver can now support up to 32 controllers in the system.
+
+For the ninth controller and beyond, the major numbers will be
+assigned dynamically by the kernel when it is discovered,
+and there is no guarantee what the major number you will get,
+but most likely it will start from 254 and goes down from there.
+
+You can check the assigned major numbers by typing
+	cat /proc/devices
+And look for cciss controllers
+
+Once you have this, you need to create device nodes in
+/dev/cciss directory. The nodes for the first 8 controllers
+should already be created by mkdev.cciss script or
+/etc/makedev.d/cciss script. You can add the major number(s)
+in those scripts, or create the nodes manually by using
+the mknod command.
+
+You can also use mknod_dyn.cciss and rmnod_dyn.cciss scripts
+to create or remove nodes easily. These scripts can be found
+in the Documentation directory.
+
+Then you can mount the devices and create partitions
+(You also need to make nodes for these partitions).
+
+As for the minor number, the disk device will have a minor
+number divisible by 16 (e.g: 0, 16, 32 etc), and the 
+partitions on those disk devices will have the minor number
+of the disk device plus the partition number (1-15).
+For example, disk d2 will have minor number 32, and its
+partitions 1 and 2 will have minor numbers 33 and 34.
+
+Look at the mkdev.cciss script for example.
+ 
+Note:
+ In 2.4 kernel, partition names are hard coded in
+ /usr/src/linux/fs/partitions/check.c
+ and only for the first 8 cciss controllers. The rest
+ will be reported as ccissXX. This should not affect 
+ I/O operation or performance. Please apply the 
+ cciss_2.4_partition_name.patch to address this. This 
+ will not be an issue under 2.5 kernel, since partition
+ names will be handled by the driver.
+
 SCSI tape drive and medium changer support
 ------------------------------------------
 
@@ -127,3 +178,55 @@
 access these devices too, as if the array controller were merely a SCSI 
 controller in the same way that we are allowing it to access SCSI tape drives.
 
+Monitor Threads
+---------------
+
+For multipath configurations (acheived via a higher level driver, such
+as the "md" driver) it is important that failure of a controller is detected.
+Ordinarily, the driver is entirely interrupt driven.  If a failure occurs
+in such a way that the processor cannot receive interrupts from an adapter,
+the driver will wait forever for i/o's to complete.  In a multipath
+configuration this is undesirable, as the md driver relies on i/o's being
+reported as failed by the low level driver to trigger failing over to an 
+alternate controller.  The monitor threads allow the driver to detect such 
+situations and report outstanding i/o's as having failed so that recovery 
+actions such switching to an alternate controller can occur.  The monitor 
+threads periodically sends a trivial "no-operation" command down to 
+the controllers and expect them to complete within a a reasonable (short)
+time period.  The firmware on the adapter is designed such that no matter
+how busy the adapter is serving i/o, it can respond quickly to a
+"no-operation" command.  In the event that a deadline elapses before a no 
+operation command completes, all outstanding commands on that controller 
+are reported back to the upper layers as having failed, and any new commands 
+sent to the controller are immediately reported back as failed. 
+
+To enable the monitor threads, the compile time option must be enabled
+(via the usual linux kernel configuration) and the monitor thread must
+be enabled at runtime as well.  A system may have many adapters, but 
+perhaps only a single pair operating in a multipath configuration.  
+In this way, it is possible to run monitoring threads only for those 
+adapters which require it.
+
+To start a monitoring thread on the first cciss adapter, "cciss0" with
+a polling interval of 30 seconds, execute the following command:
+
+	echo "monitor 30" > /proc/driver/cciss/cciss0
+
+To change the polling interval, to say, 60 seconds:
+
+	echo "monitor 60" > /proc/driver/cciss/cciss0
+
+(Note, the change will not take effect until the previous polling 
+interval elapses.)
+
+To disable the monitoring thread, set the polling interval to 0 seconds:
+
+	echo "monitor 0" > /proc/driver/cciss/cciss0
+
+(Again, the monitoring thread will not exit until the previous polling
+interval elapses.)
+
+The minimum monitoring period is 10 seconds, and the maximum monitoring
+period is 3600 seconds (1 hour).  The no-operation command must complete
+with 5 seconds of submission in all cases or the controller will be presumed
+failed.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/crypto/api-intro.txt linux-2.4.23-pre8/Documentation/crypto/api-intro.txt
--- linux-2.4.22/Documentation/crypto/api-intro.txt	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/crypto/api-intro.txt	2003-10-22 22:49:53.000000000 +0000
@@ -186,7 +186,6 @@
   Dag Arne Osvik (Serpent)
   Brian Gladman (AES)
 
-
 SHA1 algorithm contributors:
   Jean-Francois Dive
   
@@ -214,6 +213,9 @@
   Kyle McMartin
   Adam J. Richter
 
+CAST5 algorithm contributors:
+  Kartikey Mahendra Bhatt (original developers unknown, FSF copyright).
+
 Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>
 
 Please send any credits updates or corrections to:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/filesystems/jfs.txt linux-2.4.23-pre8/Documentation/filesystems/jfs.txt
--- linux-2.4.22/Documentation/filesystems/jfs.txt	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/filesystems/jfs.txt	2003-10-22 22:49:03.000000000 +0000
@@ -23,6 +23,15 @@
 		read-write.  The resize keyword with no value will grow
 		the volume to the full size of the partition.
 
+nointegrity	Do not write to the journal.  The primary use of this option
+		is to allow for higher performance when restoring a volume
+		from backup media.  The integrity of the volume is not
+		guaranteed if the system abnormally abends.
+
+integrity	Default.  Commit metadata changes to the journal.  Use this
+		option to remount a volume where the nointegrity option was
+		previously specified in order to restore normal behavior.
+
 JFS TODO list:
 
 Plans for our near term development items
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/firmware_class/README linux-2.4.23-pre8/Documentation/firmware_class/README
--- linux-2.4.22/Documentation/firmware_class/README	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/firmware_class/README	2003-10-22 22:48:21.000000000 +0000
@@ -0,0 +1,58 @@
+
+ request_firmware() hotplug interface:
+ ------------------------------------
+	Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org>
+
+ Why:
+ ---
+
+ Today, the most extended way to use firmware in the Linux kernel is linking
+ it statically in a header file. Which has political and technical issues:
+
+  1) Some firmware is not legal to redistribute.
+  2) The firmware occupies memory permanently, even though it often is just
+     used once.
+  3) Some people, like the Debian crowd, don't consider some firmware free
+     enough and remove entire drivers (e.g.: keyspan).
+
+ about in-kernel persistence:
+ ---------------------------
+ Under some circumstances, as explained below, it would be interesting to keep
+ firmware images in non-swappable kernel memory or even in the kernel image
+ (probably within initramfs).
+
+ Note that this functionality has not been implemented.
+
+ - Why OPTIONAL in-kernel persistence may be a good idea sometimes:
+ 
+	- If the device that needs the firmware is needed to access the
+	  filesystem. When upon some error the device has to be reset and the
+	  firmware reloaded, it won't be possible to get it from userspace.
+	  e.g.:
+		- A diskless client with a network card that needs firmware.
+		- The filesystem is stored in a disk behind an scsi device
+		  that needs firmware.
+	- Replacing buggy DSDT/SSDT ACPI tables on boot.
+	  Note: this would require the persistent objects to be included
+	  within the kernel image, probably within initramfs.
+	  
+   And the same device can be needed to access the filesystem or not depending
+   on the setup, so I think that the choice on what firmware to make
+   persistent should be left to userspace.
+
+ - Why register_firmware()+__init can be useful:
+ 	- For boot devices needing firmware.
+	- To make the transition easier:
+		The firmware can be declared __init and register_firmware()
+		called on module_init. Then the firmware is warranted to be
+		there even if "firmware hotplug userspace" is not there yet or
+		it doesn't yet provide the needed firmware.
+		Once the firmware is widely available in userspace, it can be
+		removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE).
+
+	In either case, if firmware hotplug support is there, it can move the
+	firmware out of kernel memory into the real filesystem for later
+	usage.
+
+	Note: If persistence is implemented on top of initramfs,
+	register_firmware() may not be appropriate.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/firmware_class/firmware_sample_driver.c linux-2.4.23-pre8/Documentation/firmware_class/firmware_sample_driver.c
--- linux-2.4.22/Documentation/firmware_class/firmware_sample_driver.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/firmware_class/firmware_sample_driver.c	2003-10-22 22:48:41.000000000 +0000
@@ -0,0 +1,121 @@
+/*
+ * firmware_sample_driver.c -
+ *
+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
+ *
+ * Sample code on how to use request_firmware() from drivers.
+ *
+ * Note that register_firmware() is currently useless.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include "linux/firmware.h"
+
+#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
+char __init inkernel_firmware[] = "let's say that this is firmware\n";
+#endif
+
+static char ghost_device[] = "ghost0";
+
+static void sample_firmware_load(char *firmware, int size)
+{
+	u8 buf[size+1];
+	memcpy(buf, firmware, size);
+	buf[size] = '\0';
+	printk("firmware_sample_driver: firmware: %s\n", buf);
+}
+
+static void sample_probe_default(void)
+{
+	/* uses the default method to get the firmware */
+        const struct firmware *fw_entry;
+	printk("firmware_sample_driver: a ghost device got inserted :)\n");
+
+        if(request_firmware(&fw_entry, "sample_driver_fw", ghost_device)!=0)
+	{
+		printk(KERN_ERR
+		       "firmware_sample_driver: Firmware not available\n");
+		return;
+	}
+	
+	sample_firmware_load(fw_entry->data, fw_entry->size);
+
+	release_firmware(fw_entry);
+
+	/* finish setting up the device */
+}
+static void sample_probe_specific(void)
+{
+	/* Uses some specific hotplug support to get the firmware from
+	 * userspace  directly into the hardware, or via some sysfs file */
+
+	/* NOTE: This currently doesn't work */
+
+	printk("firmware_sample_driver: a ghost device got inserted :)\n");
+
+        if(request_firmware(NULL, "sample_driver_fw", ghost_device)!=0)
+	{
+		printk(KERN_ERR
+		       "firmware_sample_driver: Firmware load failed\n");
+		return;
+	}
+	
+	/* request_firmware blocks until userspace finished, so at
+	 * this point the firmware should be already in the device */
+
+	/* finish setting up the device */
+}
+static void sample_probe_async_cont(const struct firmware *fw, void *context)
+{
+	if(!fw){
+		printk(KERN_ERR
+		       "firmware_sample_driver: firmware load failed\n");
+		return;
+	}
+
+	printk("firmware_sample_driver: device pointer \"%s\"\n",
+	       (char *)context);
+	sample_firmware_load(fw->data, fw->size);
+}
+static void sample_probe_async(void)
+{
+	/* Let's say that I can't sleep */
+	int error;
+	error = request_firmware_nowait (THIS_MODULE,
+					 "sample_driver_fw", ghost_device,
+					 "my device pointer",
+					 sample_probe_async_cont);
+	if(error){
+		printk(KERN_ERR 
+		       "firmware_sample_driver:"
+		       " request_firmware_nowait failed\n");
+	}
+}
+
+static int sample_init(void)
+{
+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
+	register_firmware("sample_driver_fw", inkernel_firmware,
+			  sizeof(inkernel_firmware));
+#endif
+	/* since there is no real hardware insertion I just call the
+	 * sample probe functions here */
+	sample_probe_specific();
+	sample_probe_default();
+	sample_probe_async();
+	return 0;
+}
+static void __exit sample_exit(void)
+{
+}
+
+module_init (sample_init);
+module_exit (sample_exit);
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/firmware_class/hotplug-script linux-2.4.23-pre8/Documentation/firmware_class/hotplug-script
--- linux-2.4.22/Documentation/firmware_class/hotplug-script	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/firmware_class/hotplug-script	2003-10-22 22:47:39.000000000 +0000
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+# Simple hotplug script sample:
+# 
+# Both $DEVPATH and $FIRMWARE are already provided in the environment.
+
+HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/
+
+echo 1 > /sysfs/$DEVPATH/loading
+cat $HOTPLUG_FW_DIR/$FIRMWARE > /sysfs/$DEVPATH/data
+echo 0 > /sysfs/$DEVPATH/loading
+
+# To cancel the load in case of error:
+#
+#	echo -1 > /sysfs/$DEVPATH/loading
+#
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/hw_random.txt linux-2.4.23-pre8/Documentation/hw_random.txt
--- linux-2.4.22/Documentation/hw_random.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/hw_random.txt	2003-10-22 22:49:18.000000000 +0000
@@ -0,0 +1,138 @@
+	Hardware driver for Intel/AMD/VIA Random Number Generators (RNG)
+	Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
+	Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
+
+Introduction:
+
+	The hw_random device driver is software that makes use of a
+	special hardware feature on your CPU or motherboard,
+	a Random Number Generator (RNG).
+
+	In order to make effective use of this device driver, you
+	should download the support software as well.  Download the
+	latest version of the "rng-tools" package from the
+	hw_random driver's official Web site:
+
+		http://sourceforge.net/projects/gkernel/
+
+About the Intel RNG hardware, from the firmware hub datasheet:
+
+	The Firmware Hub integrates a Random Number Generator (RNG)
+	using thermal noise generated from inherently random quantum
+	mechanical properties of silicon. When not generating new random
+	bits the RNG circuitry will enter a low power state. Intel will
+	provide a binary software driver to give third party software
+	access to our RNG for use as a security feature. At this time,
+	the RNG is only to be used with a system in an OS-present state.
+
+Theory of operation:
+
+	Character driver.  Using the standard open()
+	and read() system calls, you can read random data from
+	the hardware RNG device.  This data is NOT CHECKED by any
+	fitness tests, and could potentially be bogus (if the
+	hardware is faulty or has been tampered with).  Data is only
+	output if the hardware "has-data" flag is set, but nevertheless
+	a security-conscious person would run fitness tests on the
+	data before assuming it is truly random.
+
+	/dev/hwrandom is char device major 10, minor 183.
+
+Driver notes:
+
+	* FIXME: support poll(2)
+
+	NOTE: request_mem_region was removed, for two reasons:
+	1) Only one RNG is supported by this driver, 2) The location
+	used by the RNG is a fixed location in MMIO-addressable memory,
+	3) users with properly working BIOS e820 handling will always
+	have the region in which the RNG is located reserved, so
+	request_mem_region calls always fail for proper setups.
+	However, for people who use mem=XX, BIOS e820 information is
+	-not- in /proc/iomem, and request_mem_region(RNG_ADDR) can
+	succeed.
+
+Driver details:
+
+	Based on:
+	Intel 82802AB/82802AC Firmware Hub (FWH) Datasheet
+		May 1999 Order Number: 290658-002 R
+
+	Intel 82802 Firmware Hub: Random Number Generator
+	Programmer's Reference Manual
+		December 1999 Order Number: 298029-001 R
+
+	Intel 82802 Firmware HUB Random Number Generator Driver
+	Copyright (c) 2000 Matt Sottek <msottek@quiknet.com>
+
+	Special thanks to Matt Sottek.  I did the "guts", he
+	did the "brains" and all the testing.
+
+Change history:
+
+	Version 1.0.0:
+	* Merge Intel, AMD, VIA RNG drivers into one.
+	  Further changelog in BitKeeper.
+
+	Version 0.9.8:
+	* Support other i8xx chipsets by adding 82801E detection
+	* 82801DB detection is the same as for 82801CA.
+
+	Version 0.9.7:
+	* Support other i8xx chipsets too (by adding 82801BA(M) and
+	  82801CA(M) detection)
+
+	Version 0.9.6:
+	* Internal driver cleanups, prep for 1.0.0 release.
+
+	Version 0.9.5:
+	* Rip out entropy injection via timer.  It never ever worked,
+	  and a better solution (rngd) is now available.
+
+	Version 0.9.4:
+	* Fix: Remove request_mem_region
+	* Fix: Horrible bugs in FIPS calculation and test execution
+
+	Version 0.9.3:
+	* Clean up rng_read a bit.
+	* Update i810_rng driver Web site URL.
+	* Increase default timer interval to 4 samples per second.
+	* Abort if mem region is not available.
+	* BSS zero-initialization cleanup.
+	* Call misc_register() from rng_init_one.
+	* Fix O_NONBLOCK to occur before we schedule.
+
+	Version 0.9.2:
+	* Simplify open blocking logic
+
+	Version 0.9.1:
+	* Support i815 chipsets too (Matt Sottek)
+	* Fix reference counting when statically compiled (prumpf)
+	* Rewrite rng_dev_read (prumpf)
+	* Make module races less likely (prumpf)
+	* Small miscellaneous bug fixes (prumpf)
+	* Use pci table for PCI id list
+
+	Version 0.9.0:
+	* Don't register a pci_driver, because we are really
+	  using PCI bridge vendor/device ids, and someone
+	  may want to register a driver for the bridge. (bug fix)
+	* Don't let the usage count go negative (bug fix)
+	* Clean up spinlocks (bug fix)
+	* Enable PCI device, if necessary (bug fix)
+	* iounmap on module unload (bug fix)
+	* If RNG chrdev is already in use when open(2) is called,
+	  sleep until it is available.
+	* Remove redundant globals rng_allocated, rng_use_count
+	* Convert numeric globals to unsigned
+	* Module unload cleanup
+
+	Version 0.6.2:
+	* Clean up spinlocks.  Since we don't have any interrupts
+	  to worry about, but we do have a timer to worry about,
+	  we use spin_lock_bh everywhere except the timer function
+	  itself.
+	* Fix module load/unload.
+	* Fix timer function and h/w enable/disable logic
+	* New timer interval sysctl
+	* Clean up sysctl names
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/i386/zero-page.txt linux-2.4.23-pre8/Documentation/i386/zero-page.txt
--- linux-2.4.22/Documentation/i386/zero-page.txt	1999-08-30 17:47:02.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/i386/zero-page.txt	2003-10-22 22:48:28.000000000 +0000
@@ -31,6 +31,7 @@
 
 0x1e0	unsigned long	ALT_MEM_K, alternative mem check, in Kb
 0x1e8	char		number of entries in E820MAP (below)
+0x1e9	unsigned char	number of entries in EDDBUF (below)
 0x1f1	char		size of setup.S, number of sectors
 0x1f2	unsigned short	MOUNT_ROOT_RDONLY (if !=0)
 0x1f4	unsigned short	size of compressed kernel-part in the
@@ -66,6 +67,7 @@
 0x220	4 bytes		(setup.S)
 0x224	unsigned short	setup.S heap end pointer
 0x2d0 - 0x600		E820MAP
+0x600 - 0x7D4		EDDBUF (setup.S)
 
 0x800	string, 2K max	COMMAND_LINE, the kernel commandline as
 			copied using CL_OFFSET.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/ioctl-number.txt linux-2.4.23-pre8/Documentation/ioctl-number.txt
--- linux-2.4.22/Documentation/ioctl-number.txt	2001-07-11 23:35:37.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/ioctl-number.txt	2003-10-22 22:49:41.000000000 +0000
@@ -171,10 +171,6 @@
 					<mailto:buk@buks.ipn.de>
 0xA0	all	linux/sdp/sdp.h		Industrial Device Project
 					<mailto:kenji@bitgate.com>
-0xA2    00-0F   DVD decoder driver      in development:
-                                        <http://linuxtv.org/dvd/api/>
-0xA3	00-1F	Philips SAA7146 dirver	in development:
-					<mailto:Andreas.Beckmann@hamburg.sc.philips.com>
 0xA3	80-8F	Port ACL		in development:
 					<mailto:tlewis@mindspring.com>
 0xA3	90-9F	linux/dtlk.h
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/kernel-parameters.txt linux-2.4.23-pre8/Documentation/kernel-parameters.txt
--- linux-2.4.22/Documentation/kernel-parameters.txt	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/kernel-parameters.txt	2003-10-22 22:48:57.000000000 +0000
@@ -278,6 +278,8 @@
 
 	keepinitrd	[HW, ARM]
 
+	lapic		[IA-32,APIC] Enable the local APIC even if BIOS disabled it.
+
 	load_ramdisk=	[RAM] List of ramdisks to load from floppy.
 
 	lockd.udpport=	[NFS]
@@ -414,6 +416,8 @@
 
 	nointroute	[IA-64]
  
+	nolapic		[IA-32,APIC] Do not enable or use the local APIC.
+
 	no-scroll	[VGA]
 
 	nosmp		[SMP] Tells an SMP kernel to act as a UP kernel.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/laptop-mode.txt linux-2.4.23-pre8/Documentation/laptop-mode.txt
--- linux-2.4.22/Documentation/laptop-mode.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/laptop-mode.txt	2003-10-22 22:47:37.000000000 +0000
@@ -0,0 +1,72 @@
+Laptop mode
+===========
+
+This small doc describes the 2.4 laptop mode patch.
+
+Last updated 2003-05-25, Jens Axboe <axboe@suse.de>
+
+Introduction
+------------
+
+A few properties of the Linux vm makes it virtually impossible to attempt
+to spin down the hard drive in a laptop for a longer period of time (more
+than a handful of seconds). This means you are lucky if you can even reach
+the break even point with regards to power consumption, let alone expect any
+decrease.
+
+One problem is the age time of dirty buffers. Linux uses 30 seconds per
+default, so if you dirty any data then flusing of that data will commence
+at most 30 seconds from then. Another is the journal commit interval of
+journalled file systems such as ext3, which is 5 seconds on a stock kernel.
+Both of these are tweakable either from proc/sysctl or as mount options
+though, and thus partly solvable from user space.
+
+The kernel update daemon (kupdated) also runs at specific intervals, flushing
+old dirty data out. Default is every 5 seconds, this too can be tweaked
+from sysctl.
+
+So what does the laptop mode patch do? It attempts to fully utilize the
+hard drive once it has been spun up, flushing the old dirty data out to
+disk. Instead of flushing just the expired data, it will clean everything.
+When a read causes the disk to spin up, we kick off this flushing after
+a few seconds. This means that once the disk spins down again, everything
+is up to date. That allows longer dirty data and journal expire times.
+
+It follows that you have to set long expire times to get long spin downs.
+This means you could potentially loose 10 minutes worth of data, if you
+set a 10 minute expire count instead of just 30 seconds worth. The biggest
+risk here is undoubtedly running out of battery.
+
+Settings
+--------
+
+The main knob is /proc/sys/vm/laptop_mode. Setting that to 1 switches the
+vm (and block layer) to laptop mode. Leaving it to 0 makes the kernel work
+like before. When in laptop mode, you also want to extend the intervals
+desribed above. See the laptop-mode.sh script for how to do that.
+
+It can happen that the disk still keeps spinning up and you don't quite
+know why or what causes it. The laptop mode patch has a little helper for
+that as well, /proc/sys/vm/block_dump. When set to 1, it will dump info to
+the kernel message buffer about what process caused the io. Be very careful
+when playing with this setting, it is advisable to shut down syslog first!
+
+Result
+------
+
+Using the laptop-mode.sh script with its default settings, I get the full
+10 minutes worth of drive spin down. Provided your work load is cached,
+the disk will only spin up every 10 minutes (well actually, 9 minutes and 55
+seconds due to the 5 second delay in flushing dirty data after the last read
+completes). I can't tell you exactly how much extra battery life you will
+gain in laptop mode, it will vary greatly on the laptop and workload in
+question. The only way to know for sure is to try it out. Getting 10% extra
+battery life is not unrealistic.
+
+Notes
+-----
+
+Patch only changes journal expire time for ext3. reiserfs uses a hardwire
+value, should be trivial to adapt though (basically just make it call
+get_buffer_flushtime() and uses that). I have not looked at other
+journalling file systems, I'll happily accept patches to rectify that!
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/mkdev_dyn.cciss linux-2.4.23-pre8/Documentation/mkdev_dyn.cciss
--- linux-2.4.22/Documentation/mkdev_dyn.cciss	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/mkdev_dyn.cciss	2003-10-22 22:48:38.000000000 +0000
@@ -0,0 +1,171 @@
+#!/bin/sh
+#
+# Author: Francis Wiran <Francis.Wiran@hp.com>
+#
+# Script to create device nodes for SMART Array controllers, idea from
+# mkdev.cciss found in Documentation. The argument syntax is different,
+# hence, the name change.
+#
+# Usage:
+# 	mkdev_dyn.cciss [ctlr num] [major num] [num log vol] [num partitions]
+#
+# With no arguments, the script will check to see if there are any cciss
+# nodes already created in the /dev directory. If so, then it will assume
+# that the nodes for the first 8 controllers are already created by
+# /etc/makedev.d, which is likely. If not, then the script will create 
+# them, using the major numbers reserved for cciss controllers (104 thru 111).
+#
+# After that, it will start creating nodes for the controllers which major
+# numbers are dynamically allocated by the kernel. It will check 
+# /proc/devices for any cciss controllers with major numbers other than
+# 104 thru 111 and creates the nodes.
+#
+# Note that it is a good idea to run rmdev_dyn.cciss script if you remove
+# those controllers (the ones which major numbers were dynamically allocated)
+# This will unclutter /dev, as well as preventing possible problems due to 
+# referenced devices and major numbers no longer available or taken by
+# other non-cciss drivers.
+#
+# With no arguments, the script assumes 16 logical volumes per controller
+# and 16 partitions per volume; 
+#
+# Passing arguments:
+# If you know that one of your controllers, say cciss8, has been dynamically 
+# assigned major number 254, and were planning on no more than 2 logical 
+# volumes, using a maximum of 4 partitions per volume, you could do:
+#
+# mkdev_dyn.cciss 8 254 2 4
+#
+# Of course, this has no real benefit over "mkdev_dyn.cciss 8 254" except 
+# that it doesn't create as many device nodes in /dev/cciss.
+#
+
+# Inputs
+NR_CTLR=${1-8}
+NR_MAJOR=${2-254}
+NR_VOL=${3-16}
+NR_PART=${4-16}
+
+echo_usage()
+{
+	echo "Usage: mkdev_dyn.cciss [ctlr num] [maj] [volumes] [partitions]"
+	echo "The script assumes that ctlr 0 thru 7 is statically created"
+	echo "Therefore, if you want to pass arguments make sure that"
+	echo "ctlr num is equal or greater than 8, and the major number"
+	echo "is not one that's statically assigned for cciss controller."
+	echo "Check the correct major number in /proc/devices"
+
+	# Hmm... we don't support volumes and partitions greater than 16
+	# either.
+}
+
+echo_create()
+{
+	echo "created /dev/cciss/c${1}* nodes using major number ${2}"
+}
+
+
+# Function: do_mknod()
+#           Creates devices nodes under /dev/cciss
+# Inputs: $1 - ctlr number
+#	  $2 - major number
+#	  $3 - number of devices on controller
+#	  $4 - number of partitions per device
+do_mknod()
+{
+	D=0;
+	while [ $D -lt $3 ]; do
+		P=0;
+		while [ $P -lt $4 ]; do
+			MIN=`expr $D \* 16 + $P`;
+			if [ $P -eq 0 ]; then
+				mknod /dev/cciss/c${1}d${D} b $2 $MIN
+			else
+				mknod /dev/cciss/c${1}d${D}p${P} b $2 $MIN
+			fi
+			P=`expr $P + 1`;
+		done
+		D=`expr $D + 1`;
+	done
+}
+
+# Function: do_dyn
+#           Search and create cciss nodes for the controllers which
+#           major numbers are allocated dynamically by the kernel
+#           instead of using kernel.org 's value of 104 to 111.
+#
+# Input: $1 - ctlr num - will create nodes /dev/cciss/c${1}
+#	 $2 - major num - the major number to assign to the nodes
+#	 $3 - volumes - max number of volumes per controller
+#	 $4 - partitions - max number of partitions per volume
+#
+# Note: Without input, this function will start creating nodes
+#       for controller c8 and above, making assumption that 
+#       c0 thru c7 are already made, and the name c8 and above 
+#       are not already taken.
+do_dyn()
+{
+	if [ $# -eq 0 ]; then
+		C=0;
+		for MAJ in `cat /proc/devices |\
+			grep cciss |\
+			awk '/cciss[0-9]$/ { sub("cciss", "cciss0") }; {print}' |\
+			sort -k 2,2 |\
+			awk '{print $1-i}'`;
+		do
+			if [ `ls -l /dev/cciss/c* |\
+				awk '{print $5-i}' |\
+				uniq |\
+				grep $MAJ |\
+				wc -l` -gt 0 ]; then
+				:
+			else
+				do_mknod $C $MAJ $NR_VOL $NR_PART;
+				echo_create $C $MAJ;
+			fi
+			C=`expr $C + 1`;
+		done
+	else
+		do_mknod $1 $2 $3 $4;
+		echo_create $1 $2;
+	fi
+	
+	exit
+}
+
+# Start here
+
+# Check the input values
+if [ $NR_CTLR -lt 8 ]; then
+	echo_usage;
+	exit
+fi
+
+if [ $NR_CTLR -ge 8 ]; then
+	if [ \( $NR_MAJOR -ge 104 \) -a \( $NR_MAJOR -le 111 \) ]; then
+		echo_usage;
+		exit
+	fi
+fi
+
+if [ ! -d /dev/cciss ]; then
+        mkdir -p /dev/cciss
+fi
+
+# Assume that if c0d0p1 node already exist, then all nodes from c0d0p1
+# to c7d15p15 have been created for us.
+if [ ! -b /dev/cciss/c0d0p1 ]; then
+	C=0; 
+	while [ $C -lt 8 ]; do
+		MAJ=`expr $C + 104`;
+		do_mknod $C $MAJ $NR_VOL $NR_PART;
+		echo_create $C $MAJ;
+		C=`expr $C + 1`;
+	done
+fi
+
+if [ $# -gt 0 ]; then
+	do_dyn $NR_CTLR $NR_MAJOR $NR_VOL $NR_PART;
+else
+	do_dyn;
+fi
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/networking/00-INDEX linux-2.4.23-pre8/Documentation/networking/00-INDEX
--- linux-2.4.22/Documentation/networking/00-INDEX	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/networking/00-INDEX	2003-10-22 22:49:16.000000000 +0000
@@ -97,8 +97,8 @@
 sis900.txt
 	- SiS 900/7016 Fast Ethernet device driver info.
 sk98lin.txt
-	- SysKonnect SK-98xx and SK-98xx Gigabit Ethernet Adapter family 
-	  driver info.
+	- Marvell Yukon Chipset / SysKonnect SK-98xx compliant Gigabit
+	  Ethernet Adapter family driver info
 skfp.txt
 	- SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
 smc9.txt
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/networking/atm.txt linux-2.4.23-pre8/Documentation/networking/atm.txt
--- linux-2.4.22/Documentation/networking/atm.txt	2000-02-09 02:23:13.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/networking/atm.txt	2003-10-22 22:49:54.000000000 +0000
@@ -1,8 +1,8 @@
 In order to use anything but the most primitive functions of ATM,
 several user-mode programs are required to assist the kernel. These
 programs and related material can be found via the ATM on Linux Web
-page at http://icawww1.epfl.ch/linux-atm/
+page at http://linux-atm.sourceforge.net/
 
 If you encounter problems with ATM, please report them on the ATM
 on Linux mailing list. Subscription information, archives, etc.,
-can be found on http://icawww1.epfl.ch/linux-atm/
+can be found on http://linux-atm.sourceforge.net/
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/networking/bonding.txt linux-2.4.23-pre8/Documentation/networking/bonding.txt
--- linux-2.4.22/Documentation/networking/bonding.txt	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/networking/bonding.txt	2003-10-22 22:48:16.000000000 +0000
@@ -527,9 +527,9 @@
 
 1) Bonding information files
 ----------------------------
-The bonding driver information files reside in the /proc/net/bond* directories.
+The bonding driver information files reside in the /proc/net/bonding directory.
 
-Sample contents of /proc/net/bond0/info after the driver is loaded with 
+Sample contents of /proc/net/bonding/bond0 after the driver is loaded with 
 parameters of mode=0 and miimon=1000 is shown below.
  
         Bonding Mode: load balancing (round-robin)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/networking/generic-hdlc.txt linux-2.4.23-pre8/Documentation/networking/generic-hdlc.txt
--- linux-2.4.22/Documentation/networking/generic-hdlc.txt	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/networking/generic-hdlc.txt	2003-10-22 22:49:45.000000000 +0000
@@ -1,11 +1,13 @@
-Generic HDLC layer for Linux kernel 2.4/2.5
+Generic HDLC layer
 Krzysztof Halasa <khc@pm.waw.pl>
-May, 2001
+January, 2003
 
 
 Generic HDLC layer currently supports:
-- Frame Relay (ANSI, CCITT and no LMI), with ARP support (no InARP),
-- raw HDLC (IPv4 only),
+- Frame Relay (ANSI, CCITT and no LMI), with ARP support (no InARP).
+  Normal (routed) and Ethernet-bridged (Ethernet device emulation)
+  interfaces can share a single PVC.
+- raw HDLC - either IP (IPv4) interface or Ethernet device emulation.
 - Cisco HDLC,
 - PPP (uses syncppp.c),
 - X.25 (uses X.25 routines).
@@ -15,6 +17,10 @@
 - RISCom/N2 by SDL Communications Inc.
 - and others, some not in the official kernel.
 
+Ethernet device emulation (using HDLC or Frame-Relay PVC) is compatible
+with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging).
+
+
 Make sure the hdlc.o and the hardware driver are loaded. It should
 create a number of "hdlc" (hdlc0 etc) network devices, one for each
 WAN port. You'll need the "sethdlc" utility, get it from:
@@ -32,8 +38,10 @@
 	sethdlc hdlc0 cisco interval 10 timeout 25
 or
 	sethdlc hdlc0 rs232 clock ext
-	sethdlc fr lmi ansi
-	sethdlc create 99
+	sethdlc hdlc0 fr lmi ansi
+	sethdlc hdlc0 create 99
+	ifconfig hdlc0 up
+	ifconfig pvc0 localIP pointopoint remoteIP
 
 In Frame Relay mode, ifconfig master hdlc device up (without assigning
 any IP address to it) before using pvc devices.
@@ -58,6 +66,9 @@
   no-parity / crc16 / crc16-pr0 (CRC16 with preset zeros) / crc32-itu
   crc16-itu (CRC16 with ITU-T polynomial) / crc16-itu-pr0 - sets parity
 
+* hdlc-eth - Ethernet device emulation using HDLC. Parity and encoding
+  as above.
+
 * cisco - sets Cisco HDLC mode (IP, IPv6 and IPX supported)
   interval - time in seconds between keepalive packets
   timeout - time in seconds after last received keepalive packet before
@@ -77,7 +88,12 @@
   n392 - error threshold - both user and network
   n393 - monitored events count - both user and network
 
-* create | delete n - FR only - adds / deletes PVC interface with DLCI #n.
+Frame-Relay only:
+* create n | delete n - adds / deletes PVC interface with DLCI #n.
+  Newly created interface will be named pvc0, pvc1 etc.
+
+* create ether n | delete ether n - adds a device for Ethernet-bridged
+  frames. The device will be named pvceth0, pvceth1 etc.
 
 
 
@@ -104,11 +120,11 @@
 
 
 If you have a problem with N2 or C101 card, you can issue the "private"
-command to see port's packet descriptor rings:
+command to see port's packet descriptor rings (in kernel logs):
 
 	sethdlc hdlc0 private
 
-The hardware driver have to be build with CONFIG_HDLC_DEBUG_RINGS.
+The hardware driver has to be build with CONFIG_HDLC_DEBUG_RINGS.
 Attaching this info to bug reports would be helpful. Anyway, let me know
 if you have problems using this.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/networking/ifenslave.c linux-2.4.23-pre8/Documentation/networking/ifenslave.c
--- linux-2.4.22/Documentation/networking/ifenslave.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/networking/ifenslave.c	2003-10-22 22:47:56.000000000 +0000
@@ -140,6 +140,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
+#include <linux/if.h>
 #include <net/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/if_bonding.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/networking/sk98lin.txt linux-2.4.23-pre8/Documentation/networking/sk98lin.txt
--- linux-2.4.22/Documentation/networking/sk98lin.txt	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/networking/sk98lin.txt	2003-10-22 22:49:09.000000000 +0000
@@ -1,11 +1,11 @@
-(C)Copyright 1999-2002 SysKonnect GmbH.
+(C)Copyright 1999-2003 Marvell(R).
 All rights reserved
 ===========================================================================
 
-sk98lin.txt created 19-Dec-2002
+sk98lin.txt created 23-Sep-2003
 
-Readme File for sk98lin v6.02
-SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
+Readme File for sk98lin v6.18
+Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
 
 This file contains
  1  Overview
@@ -19,7 +19,6 @@
  5  Large Frame Support
  6  VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
  7  Troubleshooting
- 8  History
 
 ===========================================================================
 
@@ -27,8 +26,9 @@
 1  Overview
 ===========
 
-The sk98lin driver supports the SysKonnect SK-98xx and SK-95xx family 
-on Linux. It has been tested with Linux on Intel/x86 machines.
+The sk98lin driver supports the Marvell Yukon and SysKonnect 
+SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. It has 
+been tested with Linux on Intel/x86 machines.
 ***
 
 
@@ -75,8 +75,8 @@
 To integrate the driver permanently into the kernel, proceed as follows:
 
 1. Select the menu "Network device support" and then "Ethernet(1000Mbit)"
-2. Mark "SysKonnect SK-98xx and SK-95xx Gigabit Ethernet Adapter
-   family support" with (*) 
+2. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support" 
+   with (*) 
 3. Build a new kernel when the configuration of the above options is 
    finished.
 4. Install the new kernel.
@@ -87,8 +87,8 @@
 1. Enable 'loadable module support' in the kernel.
 2. For automatic driver start, enable the 'Kernel module loader'.
 3. Select the menu "Network device support" and then "Ethernet(1000Mbit)"
-4. Mark "SysKonnect SK-98xx and SK-95xx Gigabit Ethernet Adapter
-   family support" with (M)
+4. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support" 
+   with (M)
 5. Execute the command "make modules".
 6. Execute the command "make modules_install".
    The appropiate modules will be installed.
@@ -100,21 +100,23 @@
 To load the module manually, proceed as follows:
 
 1. Enter "modprobe sk98lin".
-2. If the SysKonnect SK-98xx adapter is installed in your computer and you
-   have a /proc file system, execute the command:
+2. If a Marvell Yukon or SysKonnect SK-98xx adapter is installed in 
+   your computer and you have a /proc file system, execute the command:
    "ls /proc/net/sk98lin/" 
    This should produce an output containing a line with the following 
    format:
    eth0   eth1  ...
    which indicates that your adapter has been found and initialized.
    
-   NOTE 1: If you have more than one SysKonnect SK-98xx adapter installed,
-           the adapters will be listed as 'eth0', 'eth1', 'eth2', etc.
-           For each adapter, repeat steps 3 and 4 below.
-
-   NOTE 2: If you have other Ethernet adapters installed, your SysKonnect
-           SK-98xx adapter will be mapped to the next available number, 
-           e.g. 'eth1'. The mapping is executed automatically.
+   NOTE 1: If you have more than one Marvell Yukon or SysKonnect SK-98xx 
+           adapter installed, the adapters will be listed as 'eth0', 
+                   'eth1', 'eth2', etc.
+                   For each adapter, repeat steps 3 and 4 below.
+
+   NOTE 2: If you have other Ethernet adapters installed, your Marvell
+           Yukon or SysKonnect SK-98xx adapter will be mapped to the 
+                   next available number, e.g. 'eth1'. The mapping is executed 
+                   automatically.
            The module installation message (displayed either in a system
            log file or on the console) prints a line for each adapter 
            found containing the corresponding 'ethX'.
@@ -141,7 +143,7 @@
    Use 'ping <otherstation>' to verify the connection to other computers 
    on your network.
 5. To check the adapter configuration view /proc/net/sk98lin/[devicename].
-   For example by executing:	
+   For example by executing:    
    "cat /proc/net/sk98lin/eth0" 
 
 Unload the module
@@ -184,7 +186,7 @@
    unload and reload the driver.
    The syntax of the driver parameters is:
 
- 	modprobe sk98lin parameter=value1[,value2[,value3...]]
+        modprobe sk98lin parameter=value1[,value2[,value3...]]
 
    where value1 refers to the first adapter, value2 to the second etc.
 
@@ -198,7 +200,7 @@
 to FULL, and on the second adapter to HALF.
 Then, you must enter:
 
- 	modprobe sk98lin AutoNeg=On,Off DupCap=Full,Half
+        modprobe sk98lin AutoNeg_A=On,Off DupCap_A=Full,Half
 
 NOTE: The number of adapters that can be configured this way is
       limited in the driver (file skge.c, constant SK_MAX_CARD_PARAM).
@@ -256,9 +258,9 @@
 port reports during auto-negotiation. It can be set for each port 
 individually.
 Possible modes:
-   -- Sym      = Symetric: both link partners are allowed to send 
+   -- Sym      = Symmetric: both link partners are allowed to send 
                   PAUSE frames
-   -- SymOrRem = SymetricOrRemote: both or only remote partner 
+   -- SymOrRem = SymmetricOrRemote: both or only remote partner 
                   are allowed to send PAUSE frames
    -- LocSend  = LocalSend: only local link partner is allowed 
                   to send PAUSE frames
@@ -283,6 +285,101 @@
 4.2  Adapter Parameters
 -----------------------
 
+Connection Type (SK-98xx V2.0 copper adapters only)
+---------------
+Parameter:    ConType
+Values:       Auto, 100FD, 100HD, 10FD, 10HD
+Default:      Auto
+
+The parameter 'ConType' is a combination of all five per-port parameters
+within one single parameter. This simplifies the configuration of both ports
+of an adapter card! The different values of this variable reflect the most 
+meaningful combinations of port parameters.
+
+The following table shows the values of 'ConType' and the corresponding
+combinations of the per-port parameters:
+
+    ConType   |  DupCap   AutoNeg   FlowCtrl   Role             Speed
+    ----------+------------------------------------------------------
+    Auto      |  Both     On        SymOrRem   Auto             Auto
+    100FD     |  Full     Off       None       Auto (ignored)   100
+    100HD     |  Half     Off       None       Auto (ignored)   100
+    10FD      |  Full     Off       None       Auto (ignored)   10
+    10HD      |  Half     Off       None       Auto (ignored)   10
+
+Stating any other port parameter together with this 'ConType' variable
+will result in a merged configuration of those settings. This due to 
+the fact, that the per-port parameters (e.g. Speed_? ) have a higher
+priority than the combined variable 'ConType'.
+
+NOTE: This parameter is always used on both ports of the adapter card.
+
+Interrupt Moderation
+--------------------
+Parameter:    Moderation
+Values:       None, Static, Dynamic
+Default:      None
+
+Interrupt moderation is employed to limit the maxmimum number of interrupts
+the driver has to serve. That is, one or more interrupts (which indicate any
+transmit or receive packet to be processed) are queued until the driver 
+processes them. When queued interrupts are to be served, is determined by the
+'IntsPerSec' parameter, which is explained later below.
+
+Possible modes:
+
+   -- None - No interrupt moderation is applied on the adapter card. 
+      Therefore, each transmit or receive interrupt is served immediately
+      as soon as it appears on the interrupt line of the adapter card.
+
+   -- Static - Interrupt moderation is applied on the adapter card. 
+      All transmit and receive interrupts are queued until a complete
+      moderation interval ends. If such a moderation interval ends, all
+      queued interrupts are processed in one big bunch without any delay.
+      The term 'static' reflects the fact, that interrupt moderation is
+      always enabled, regardless how much network load is currently 
+      passing via a particular interface. In addition, the duration of
+      the moderation interval has a fixed length that never changes while
+      the driver is operational.
+
+   -- Dynamic - Interrupt moderation might be applied on the adapter card,
+      depending on the load of the system. If the driver detects that the
+      system load is too high, the driver tries to shield the system against 
+      too much network load by enabling interrupt moderation. If - at a later
+      time - the CPU utilizaton decreases again (or if the network load is 
+      negligible) the interrupt moderation will automatically be disabled.
+
+Interrupt moderation should be used when the driver has to handle one or more
+interfaces with a high network load, which - as a consequence - leads also to a
+high CPU utilization. When moderation is applied in such high network load 
+situations, CPU load might be reduced by 20-30%.
+
+NOTE: The drawback of using interrupt moderation is an increase of the round-
+trip-time (RTT), due to the queueing and serving of interrupts at dedicated
+moderation times.
+
+Interrupts per second
+---------------------
+Parameter:    IntsPerSec
+Values:       30...40000 (interrupts per second)
+Default:      2000
+
+This parameter is only used, if either static or dynamic interrupt moderation
+is used on a network adapter card. Using this paramter if no moderation is
+applied, will lead to no action performed.
+
+This parameter determines the length of any interrupt moderation interval. 
+Assuming that static interrupt moderation is to be used, an 'IntsPerSec' 
+parameter value of 2000 will lead to an interrupt moderation interval of
+500 microseconds. 
+
+NOTE: The duration of the moderation interval is to be chosen with care.
+At first glance, selecting a very long duration (e.g. only 100 interrupts per 
+second) seems to be meaningful, but the increase of packet-processing delay 
+is tremendous. On the other hand, selecting a very short moderation time might
+compensate the use of any moderation being applied.
+
+
 Preferred Port
 --------------
 Parameter:    PrefPort
@@ -365,10 +462,10 @@
 6  VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
 ==================================================================
 
-The SysKonnect Linux drivers are able to support VLAN and Link Aggregation
-according to IEEE standards 802.1, 802.1q, and 802.3ad. These features are
-only available after installation of open source modules available on the 
-Internet:
+The Marvell Yukon/SysKonnect Linux drivers are able to support VLAN and 
+Link Aggregation according to IEEE standards 802.1, 802.1q, and 802.3ad. 
+These features are only available after installation of open source 
+modules available on the Internet:
 For VLAN go to: http://scry.wanfear.com/~greear/vlan.html
 For Link Aggregation go to: http://www.st.rim.or.jp/~yumo
 
@@ -448,7 +545,7 @@
           Nr:    0xcc
           Msg:   SkGeInitPort() cannot init running ports"
 Reason:   You are using a driver compiled for single processor machines 
-          on a multiprocessor machine with SMP (Symetric MultiProcessor) 
+          on a multiprocessor machine with SMP (Symmetric MultiProcessor) 
           kernel.
 Solution: Configure your kernel appropriately and recompile the kernel or
           the modules.
@@ -459,208 +556,13 @@
 support for help (linux@syskonnect.de).
 When contacting our technical support, please ensure that the following 
 information is available:
-- System Manufacturer and Model
-- Boards in your system
+- System Manufacturer and HW Informations (CPU, Memory... )
+- PCI-Boards in your system
 - Distribution
 - Kernel version
 - Driver version
 ***
 
-8  History
-==========
 
-VERSION 6.00 (In-Kernel version)
-New Features:
-- Support for SK-98xx V2.0 adapters
-- Support for gmac
-- Support for kernel 2.4.x and kernel 2.2.x
-- Zerocopy support for kernel 2.4.x with sendfile()
-- Support for scatter-gather functionality with sendfile()
-- Speed support for SK-98xx V2.0 adapters
-- New ProcFs entries
-- New module parameters
-Problems fixed:
-- ProcFS initialization
-- csum packet error
-- Ierror/crc counter error (#10767)
-- rx_too_long counter error (#10751)
-Known limitations:
-- None
-
-VERSION 4.11
-New Features:
-- none
-Problems fixed:
-- Error statistic counter fix (#10620)
-- RLMT-Fixes (#10659, #10639, #10650)
-- LM80 sensor initialization fix (#10623)
-- SK-CSUM memory fixes (#10610).
-Known limitations:
-- None
-
-VERSION 4.10
-New Features:
-- New ProcFs entries
-Problems fixed:
-- Corrected some printk's
-Known limitations:
-- None
-
-VERSION 4.09
-New Features:
-- IFF_RUNNING support (link status)
-- New ProcFs entries
-Problems fixed:
-- too long counters
-- too short counters
-- Kernel error compilation
-Known limitations:
-- None
- 
-VERSION 4.06 (In-Kernel version)
-Problems fixed:
-- MTU init problems
- 
-VERSION 4.04
-Problems fixed:
-- removed VLAN error messages
-
-VERSION 4.02 (In-Kernel version)
-New Features:
-- Add Kernel 2.4 changes
-Known limitations:
-- None
-
-VERSION 4.01 (In-Kernel version)
-Problems fixed:
-- Full statistics support for DualNet mode
-Known limitations:
-- None
-
-VERSION 4.00 (In-Kernel version)
-Problems fixed:
-- Memory leak found 
-New Features:
-- Proc filesystem integration
-- DualNet functionality integrated
-- Rlmt networks added
-Known limitations:
-- statistics partially incorrect in DualNet mode
-
-VERSION 3.04 (In-Kernel version)
-Problems fixed:
-- Driver start failed on UltraSPARC
-- Rx checksum calculation for big endian machines did not work
-- Jumbo frames were counted as input-errors in netstat
-
-VERSION 3.03 (Standalone version)
-Problems fixed:
-- Compilation did not find script "printver.sh" if "." not in PATH
-Known limitations:
-- None
-
-VERSION 3.02 (In-Kernel version)
-Problems fixed:
-- None
-New Features:
-- Integration in Linux kernel source (2.2.14 and 2.3.29) 
-Known limitations:
-- None
-
-VERSION 3.01
-Problems fixed:
-- None
-New Features:
-- Full source release
-Known limitations:
-- None
-
-VERSION 3.00
-Problems fixed:
-- None
-New Features:
-- Support for 1000Base-T adapters (SK-9821 and SK-9822)
-Known limitations:
-- None
-
-VERSION 1.07
-Problems fixed:
-- RlmtMode parameter value strings were wrong (#10437)
-- Driver sent too many RLMT frames (#10439)
-- Driver did not recognize network segmentation (#10440)
-- RLMT switched too often on segmented network (#10441)
-Known limitations:
-- None
-
-VERSION 1.06
-Problems fixed:
-- System panic'ed after some time when running with 
-  RlmtMode=CheckOtherLink or RlmtMode=CheckSeg (#10421)
-  Panic message: "Kernel panic: skput: over ... dev: eth0"
-- Driver did not switch back to default port when connected
-  back-to-back (#10422).
-Changes:
-- RlmtMode parameter names have changed
-New features:
-- There is now a version for ALPHA processors
-Known limitations:
-- None
-
-VERSION 1.05
-Problems fixed:
-- Driver failed to load on kernels with version information
-  for module symbols enabled
-Known limitations:
-- None
-
-VERSION 1.04
-Problems fixed:
-- Large frame support does work now (no autonegotiation
-  support for large frames, just manually selectable)
-New Features:
-- Receive checksumming in hardware
-- Performance optimizations
-  Some numbers (on two PII-400 machines, back-to-back):
-  netpipe: 300 MBit/sec, with large frames: 470 MBit/sec
-  ttcp:  38 MByte/sec, with large frames: 60 MByte/sec
-  ttcp (UDP send): 66 MByte/sec, with large frames: 106 MByte/sec
-Known limitations:
-- None
-
-VERSION 1.03
-Problems fixed:
-- Unloading with "rmmod" caused segmentation fault (#10415)
-- The link LED flickered from time to time, if no link was
-  established (#10402)
-- Installation problems with RedHat 6.0 (#10409)
-New Features:
-- Connection state ouput at "network connection up"
-Known limitations:
-- None
-
-VERSION 1.02
-Problems fixed:
-- Failed with multiple adapters
-- Failed with Single Port adapters
-- Startup string was only displayed if adapter found
-- No link could be established on certain switches when the switches were
-  rebooted. (#10377)
-Known limitations:
-- Segmentation fault at "rmmod" with kernel 2.2.3 on some machines
-
-VERSION 1.01
-Problems fixed:
-- Sensor status was not set back to 'ok' after 'warning/error'. (#10386)
-Changes:
-- improved parallelism in driver
-
-VERSION 1.00
-Known limitations:
-- not tested with all kernel versions (I don't have that much time :-)
-- only x86 version available (if you need others, ask for it)
-- source code not completely available
 
 ***End of Readme File***
-
-
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/rmdev_dyn.cciss linux-2.4.23-pre8/Documentation/rmdev_dyn.cciss
--- linux-2.4.22/Documentation/rmdev_dyn.cciss	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/rmdev_dyn.cciss	2003-10-22 22:48:53.000000000 +0000
@@ -0,0 +1,87 @@
+#!/bin/sh 
+#
+# Author: Francis Wiran <Francis.Wiran@hp.com>
+#
+# Script to remove device nodes for SMART Array controllers. This will
+# be the device nodes with major numbers which are dynamically allocated
+# by the kernel. This script will not attempt to remove the device
+# nodes with major number 104 thru 111 (c0 thru c7), which are 
+# the major numbers that's allocated for cciss controllers by kernel.org.
+#
+# Usage:
+# rmdev_dyn.cciss [ctlr num]
+#
+# With no arguments, the script will check to see if there are any nodes
+# under /dev/cciss, whose major number no longer shows in /proc/partitions,
+# or to be exact, no longer shows to be owned by cciss driver.
+# If there is, then it will be removed.
+#
+# Note that it is a good idea to run rmdev_dyn.cciss script if you remove
+# those controllers (the ones which major numbers were dynamically allocated)
+# This will unclutter /dev, as well as preventing possible problems due to
+# referenced devices and major numbers no longer available or taken by
+# other non-cciss drivers.
+#
+# Passing arguments:
+# If you know that one of your controllers, say cciss8, has been removed
+# and the nodes are no longer valid, you could do
+#
+# rmdev_dyn.cciss 8 
+#
+# This is the same as doing `rm -f /dev/cciss/c8*` 
+
+# Inputs
+NR_CTLR=${1}
+
+echo_usage()
+{
+	echo "Usage: rmdev_dyn.cciss [ctlr num]"
+	echo "The script will not attempt to remove nodes for controllers"
+	echo "0 thru 7, therefore if you want to pass an argument,"
+	echo "make sure that ctlr num is equal or greater than 8"
+}
+
+rm_nod1()
+{
+	if [ $1 -lt 8 ]; then
+		echo_usage;
+		exit
+	else
+		rm -f /dev/cciss/c${1}*
+		echo "removed /dev/cciss/c${1}*"
+	fi
+}
+
+rm_nod2()
+{
+	for X in `ls -l /dev/cciss/c* |\
+		awk '{print $5-i}' |\
+		uniq`; do
+		if [ \( $X -ge 104 \) -a \( $X -le 111 \) ]; then
+			:
+		elif [ `cat /proc/devices |\
+			grep cciss |\
+			grep $X |\
+			wc -l` -eq 0 ]; then
+
+			Y=`ls -l /dev/cciss/ |\
+				awk '{print $5-i ":"  $10}'|\
+				tr d ':' |\
+				grep $X |\
+				awk -F: '{print $2}' |\
+				uniq`
+
+			Z="/dev/cciss/${Y}*"
+
+			rm -f $Z
+			echo "removed $Z"
+		fi
+	done
+}
+
+# Start here
+if [ $# -gt 0 ]; then
+	rm_nod1 $NR_CTLR;
+else
+	rm_nod2;
+fi
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/sonypi.txt linux-2.4.23-pre8/Documentation/sonypi.txt
--- linux-2.4.22/Documentation/sonypi.txt	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/sonypi.txt	2003-10-22 22:47:30.000000000 +0000
@@ -8,7 +8,9 @@
 	Copyright (C) 2000 Andrew Tridgell <tridge@samba.org>
 
 This driver enables access to the Sony Programmable I/O Control Device which
-can be found in many (all ?) Sony Vaio laptops.
+can be found in many Sony Vaio laptops. Some newer Sony laptops (seems to be
+limited to new FX series laptops, at least the FX501 and the FX702) lack a
+sonypi device and are not supported at all by this driver.
 
 It will give access (through a user space utility) to some events those laptops
 generate, like:
@@ -96,6 +98,7 @@
 				SONYPI_THUMBPHRASE_MASK 	0x0200
 				SONYPI_MEYE_MASK		0x0400
 				SONYPI_MEMORYSTICK_MASK		0x0800
+				SONYPI_BATTERY_MASK		0x1000
 
 	useinput:	if set (which is the default) jogdial events are
 			forwarded to the input subsystem as mouse wheel
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/usb/usb-serial.txt linux-2.4.23-pre8/Documentation/usb/usb-serial.txt
--- linux-2.4.22/Documentation/usb/usb-serial.txt	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/usb/usb-serial.txt	2003-10-22 22:47:39.000000000 +0000
@@ -88,6 +88,9 @@
   necessary.  Some devices need this before they can talk to the USB port
   properly.
   
+  Devices that are not compiled into the kernel can be specified with module
+  parameters.  e.g. modprobe visor vendor=0x54c product=0x66
+  
   There is a webpage and mailing lists for this portion of the driver at:
   http://usbvisor.sourceforge.net/
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/video4linux/bttv/CARDLIST linux-2.4.23-pre8/Documentation/video4linux/bttv/CARDLIST
--- linux-2.4.22/Documentation/video4linux/bttv/CARDLIST	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/video4linux/bttv/CARDLIST	2003-10-22 22:47:44.000000000 +0000
@@ -7,7 +7,7 @@
   card=5 - Diamond DTV2000
   card=6 - AVerMedia TVPhone
   card=7 - MATRIX-Vision MV-Delta
-  card=8 - Lifeview FlyVideo II (Bt848) LR26
+  card=8 - Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26
   card=9 - IMS/IXmicro TurboTV
   card=10 - Hauppauge (bt878)
   card=11 - MIRO PCTV pro
@@ -104,6 +104,11 @@
   card=102 - IVC-200
   card=103 - Grand X-Guard / Trust 814PCI
   card=104 - Nebula Electronics DigiTV
+  card=105 - ProVideo PV143
+  card=106 - PHYTEC VD-009-X1 MiniDIN (bt878)
+  card=107 - PHYTEC VD-009-X1 Combi (bt878)
+  card=108 - PHYTEC VD-009 MiniDIN (bt878)
+  card=109 - PHYTEC VD-009 Combi (bt878)
 
 tuner.o
   type=0 - Temic PAL (4002 FH5)
@@ -147,3 +152,4 @@
   type=38 - Philips PAL/SECAM multi (FM1216ME MK3)
   type=39 - LG NTSC (newer TAPC series)
   type=40 - HITACHI V7-J180AT
+  type=41 - Philips PAL_MK (FI1216 MK)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/video4linux/meye.txt linux-2.4.23-pre8/Documentation/video4linux/meye.txt
--- linux-2.4.22/Documentation/video4linux/meye.txt	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/video4linux/meye.txt	2003-10-22 22:48:01.000000000 +0000
@@ -16,6 +16,23 @@
 
 MJPEG hardware grabbing is supported via a private API (see below).
 
+Hardware supported:
+-------------------
+
+This driver supports the 'second' version of the MotionEye camera :)
+
+The first version was connected directly on the video bus of the Neomagic
+video card and is unsupported.
+
+The second one, made by Kawasaki Steel is fully supported by this 
+driver (PCI vendor/device is 0x136b/0xff01)
+
+The third one, present in recent (more or less last year) Picturebooks
+(C1M* models), is not supported. The manufacturer has given the specs
+to the developers under a NDA (which allows the develoment of a GPL
+driver however), but things are not moving very fast (see
+http://r-engine.sourceforge.net/) (PCI vendor/device is 0x10cf/0x2011).
+
 Driver options:
 ---------------
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/wolfson-touchscreen.txt linux-2.4.23-pre8/Documentation/wolfson-touchscreen.txt
--- linux-2.4.22/Documentation/wolfson-touchscreen.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/wolfson-touchscreen.txt	2003-10-22 22:49:02.000000000 +0000
@@ -0,0 +1,178 @@
+
+Wolfson Microelectronics WM9705 and WM9712 Touchscreen Controllers
+===================================================================
+
+The WM9705 and WM9712 are high performance AC97 audio codecs with built
+in touchscreen controllers that are mainly found in portable devices.
+i.e. Dell Axim and Toshiba e740. 
+
+This driver uses the AC97 link controller for all communication with the 
+codec and can be either built into the kernel or built as a module. 
+
+Build Instructions
+==================
+
+The driver will be built into the kernel if "sound card support" = y and
+"wolfson AC97 touchscreen support" = y in the kernel sound configuration.
+
+To build as a module, "wolfson AC97 touchscreen support" = m
+in the kernel sound configuration.
+
+
+Driver Features
+===============
+
+ * supports WM9705, WM9712
+ * polling mode
+ * coordinate polling
+ * adjustable rpu/dpp settings
+ * adjustable pressure current
+ * adjustable sample settle delay
+ * 4 and 5 wire touchscreens (5 wire is WM9712 only)
+ * pen down detection
+ * power management
+ * AUX ADC sampling
+
+
+Driver Usage
+============
+
+In order to use this driver, a char device called wm97xx with a major
+number of 10 and minor number 16 will have to be created under 
+/dev/touchscreen.
+  
+e.g.
+mknod /dev/touchscreen/wm97xx c 10 16
+
+
+Driver Parameters
+=================
+The driver can accept several parameters for fine tuning the touchscreen. 
+However, the syntax is different between module options and passing the 
+options in the kernel command line.
+
+e.g.
+
+rpu=1   (module)
+rpu:1   (kernel command line)
+
+
+1. Codec sample mode. (mode)
+ 
+   The WM9712 can sample touchscreen data in 3 different operating
+   modes. i.e. polling, coordinate and continous.
+  
+   Polling:-     The driver polls the codec and issues 3 seperate commands
+                 over the AC97 link to read X,Y and pressure.
+   
+   Coordinate: - The driver polls the codec and only issues 1 command over
+                 the AC97 link to read X,Y and pressure. This mode has
+                 strict timing requirements and may drop samples if 
+                 interrupted. However, it is less demanding on the AC97
+                 link. Note: this mode requires a larger delay than polling
+                 mode.
+  
+   Continuous:-  The codec automatically samples X,Y and pressure and then
+                 sends the data over the AC97 link in slots. This is then
+                 same method used by the codec when recording audio.
+ 
+   Set mode = 0 for polling, 1 for coordinate and 2 for continuous.
+             
+   Default mode = 0
+   
+   
+
+2. WM9712 Internal pull up for pen detect. (rpu) 
+  
+   Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive)
+   i.e. pull up resistance = 64k Ohms / rpu.
+   
+   Adjust this value if you are having problems with pen detect not 
+   detecting any down events.
+   
+   Set rpu = value
+
+   Default rpu = 1
+   
+   
+
+3. WM9705 Pen detect comparator threshold. (pdd) 
+   
+   0 to Vmid in 15 steps, 0 = use zero power comparator with Vmid threshold
+   i.e. 1 =  Vmid/15 threshold
+        15 =  Vmid/1 threshold
+   
+   Adjust this value if you are having problems with pen detect not 
+   detecting any down events.
+   
+   Set pdd = value
+
+   Default pdd = 0
+
+
+ 
+4. Set current used for pressure measurement. (pil)
+ 
+   Set pil = 2 to use 400uA 
+       pil = 1 to use 200uA and
+       pil = 0 to disable pressure measurement.
+  
+   This is used to increase the range of values returned by the adc
+   when measureing touchpanel pressure. 
+   
+   Default pil = 0
+  
+
+
+5. WM9712 Set 5 wire touchscreen mode. (five_wire)
+
+   Set five_wire = 1 to enable 5 wire mode on the WM9712.
+   
+   Default five_wire = 0
+   
+   NOTE: Five wire mode does not allow for readback of pressure.
+
+
+
+6. ADC sample delay. (delay)
+  
+   For accurate touchpanel measurements, some settling time may be
+   required between the switch matrix applying a voltage across the
+   touchpanel plate and the ADC sampling the signal.
+  
+   This delay can be set by setting delay = n, where n is the array
+   position of the delay in the array delay_table below.
+   Long delays > 1ms are supported for completeness, but are not
+   recommended.
+   
+   Default delay = 4
+ 
+    wm_delay     uS     AC97 link frames
+    ====================================
+       0	      21          1
+       1	      42          2
+       2          84          4
+       3         167          8
+       4         333         16
+       5         667         32
+       6        1000         48
+       7        1333         64
+       8        2000         96
+       9        2667        128
+      10        3333        160
+      11        4000        192
+      12        4667        224
+      13        5333        256
+      14        6000        288
+      15           0          0 (No delay, switch matrix always on)
+
+
+
+Contact
+=======
+
+Further information about the WM9705 and WM9712 can be found on the 
+Wolfson Website. http://www.wolfsonmicro.com
+
+Please report bugs to liam.girdwood@wolfsonmicro.com or 
+                      linux@wolfsonmicro.com
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/x86_64/boot-options.txt linux-2.4.23-pre8/Documentation/x86_64/boot-options.txt
--- linux-2.4.22/Documentation/x86_64/boot-options.txt	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/x86_64/boot-options.txt	2003-10-22 22:48:59.000000000 +0000
@@ -65,13 +65,14 @@
   0 don't use an NMI watchdog
   1 use the IO-APIC timer for the NMI watchdog
   2 use the local APIC for the NMI watchdog using a performance counter. Note
-  This will use one performance counter.
+  This will use one performance counter and the local APIC's performance
+  counter vector.
 
 Idle loop
 
   idle=poll
   Don't do power saving in the idle loop using HLT, but poll for rescheduling 
-  event. This will make the CPUs eat a lot more power, but may be useful 
+  events. This will make the CPUs burn a lot more power, but may be useful 
   to get slightly better performance in multiprocessor benchmarks. It also
   makes some profiling using performance counters more accurate.
 
@@ -145,7 +146,7 @@
    off   don't use the IOMMU
    leak  turn on simple iommu leak tracing (only when CONFIG_IOMMU_LEAK is on)
    memaper[=order] allocate an own aperture over RAM with size 32MB^order.
-   noforce don't force IOMMU usage. Should be fastest.
-   force  Force IOMMU and turn on unmap debugging.  
+   noforce don't force IOMMU usage. Default.
+   force  Force IOMMU for all devices.
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Documentation/zorro.txt linux-2.4.23-pre8/Documentation/zorro.txt
--- linux-2.4.22/Documentation/zorro.txt	2000-10-16 19:51:16.000000000 +0000
+++ linux-2.4.23-pre8/Documentation/zorro.txt	2003-10-22 22:49:19.000000000 +0000
@@ -2,7 +2,7 @@
 		----------------------------------------
 
 Written by Geert Uytterhoeven <geert@linux-m68k.org>
-Last revised: February 27, 2000
+Last revised: September 5, 2003
 
 
 1. Introduction
@@ -77,7 +77,7 @@
 The treatment of these regions depends on the type of Zorro space:
 
   - Zorro II address space is always mapped and does not have to be mapped
-    explicitly using ioremap().
+    explicitly using z_ioremap().
     
     Conversion from bus/physical Zorro II addresses to kernel virtual addresses
     and vice versa is done using:
@@ -85,22 +85,20 @@
 	virt_addr = ZTWO_VADDR(bus_addr);
 	bus_addr = ZTWO_PADDR(virt_addr);
 
-  - Zorro III address space must be mapped explicitly using ioremap() first
+  - Zorro III address space must be mapped explicitly using z_ioremap() first
     before it can be accessed:
  
-	virt_addr = ioremap(bus_addr, size);
+	virt_addr = z_ioremap(bus_addr, size);
 	...
-	iounmap(virt_addr);
+	z_iounmap(virt_addr);
 
 
 5. References
 -------------
 
 linux/include/linux/zorro.h
-linux/include/linux/ioport.h
-linux/include/asm-m68k/io.h
-linux/include/asm-m68k/amigahw.h
-linux/include/asm-ppc/io.h
+linux/include/asm-{m68k,ppc}/zorro.h
+linux/include/linux/zorro_ids.h
 linux/drivers/zorro
 /proc/bus/zorro
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/MAINTAINERS linux-2.4.23-pre8/MAINTAINERS
--- linux-2.4.22/MAINTAINERS	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/MAINTAINERS	2003-10-22 22:49:05.000000000 +0000
@@ -202,7 +202,7 @@
 
 ALCATEL SPEEDTOUCH USB DRIVER
 P:	Duncan Sands
-M:	duncan.sands@wanadoo.fr
+M:	duncan.sands@free.fr
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 W:	http://www.linux-usb.org/SpeedTouch/
@@ -266,6 +266,16 @@
 L:	linux-net@vger.kernel.org
 S:	Maintained
 
+ASUS ACPI EXTRAS DRIVER
+P:	Karol Kozimor
+M:	sziwan@users.sourceforge.net
+P:	Julien Lerouge
+M:	julien.lerouge@free.fr
+L:	acpi4asus-user@lists.sourceforge.net
+W:	http://sourceforge.net/projects/acpi4asus
+W:	http://julien.lerouge.free.fr
+S:	Maintained
+
 ATM
 P:	Chas Williams
 M:	chas@cmf.nrl.navy.mil
@@ -504,6 +514,14 @@
 M:	jmorris@intercode.com.au
 P:	David S. Miller
 M:	davem@redhat.com
+MARVELL YUKON / SYSKONNECT DRIVER
+P:	Mirko Lindner
+M: 	mlindner@syskonnect.de
+P:	Ralph Roesler
+M: 	rroesler@syskonnect.de
+W: 	http://www.syskonnect.com
+S: 	Supported
+M:	davem@redhat.com
 W	http://samba.org/~jamesm/crypto/
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
@@ -670,7 +688,7 @@
 ETHERNET BRIDGE
 P:	Stephen Hemminger
 M:	shemminger@osdl.org
-L:	bridge@math.leidenuniv.nl
+L:	bridge@osdl.org
 W:	http://bridge.sourceforge.net/
 S:	Maintained
 
@@ -944,6 +962,11 @@
 L:	linux-mips@linux-mips.org
 S:	Maintained
 
+IOC4 IDE DRIVER
+P:	Jeremy Higdon
+M:	jeremy@sgi.com
+S:	Maintained
+
 IP MASQUERADING:
 P:	Juanjo Ciarlante
 M:	jjciarla@raiz.uncu.edu.ar
@@ -1745,12 +1768,6 @@
 L:	linux-video@atrey.karlin.mff.cuni.cz
 S:	Maintained
 
-SYSKONNECT DRIVER
-P: Mirko Lindner
-M: mlindner@syskonnect.de
-W: http://www.syskonnect.com
-S: Supported
-
 SYSV FILESYSTEM
 P:	Christoph Hellwig
 M:	hch@infradead.org
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/Makefile linux-2.4.23-pre8/Makefile
--- linux-2.4.22/Makefile	2003-08-25 11:44:44.000000000 +0000
+++ linux-2.4.23-pre8/Makefile	2003-10-22 22:47:44.000000000 +0000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 22
-EXTRAVERSION =
+SUBLEVEL = 23
+EXTRAVERSION = -pre8
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -28,7 +28,7 @@
 AS		= $(CROSS_COMPILE)as
 LD		= $(CROSS_COMPILE)ld
 CC		= $(CROSS_COMPILE)gcc
-CPP		= $(CC) -E
+PP		= $(CC) -E
 AR		= $(CROSS_COMPILE)ar
 NM		= $(CROSS_COMPILE)nm
 STRIP		= $(CROSS_COMPILE)strip
@@ -181,6 +181,7 @@
 DRIVERS-$(CONFIG_HAMRADIO) += drivers/net/hamradio/hamradio.o
 DRIVERS-$(CONFIG_TC) += drivers/tc/tc.a
 DRIVERS-$(CONFIG_USB) += drivers/usb/usbdrv.o
+DRIVERS-$(CONFIG_USB_GADGET) += drivers/usb/gadget/built-in.o
 DRIVERS-y +=drivers/media/media.o
 DRIVERS-$(CONFIG_INPUT) += drivers/input/inputdrv.o
 DRIVERS-$(CONFIG_HIL) += drivers/hil/hil.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/alpha/Makefile linux-2.4.23-pre8/arch/alpha/Makefile
--- linux-2.4.22/arch/alpha/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.23-pre8/arch/alpha/Makefile	2003-10-22 22:49:06.000000000 +0000
@@ -131,3 +131,6 @@
 
 bootpfile:
 	@$(MAKEBOOT) bootpfile
+
+bootpzfile:
+	@$(MAKEBOOT) bootpzfile
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/alpha/boot/Makefile linux-2.4.23-pre8/arch/alpha/boot/Makefile
--- linux-2.4.22/arch/alpha/boot/Makefile	2001-10-05 01:47:08.000000000 +0000
+++ linux-2.4.23-pre8/arch/alpha/boot/Makefile	2003-10-22 22:47:56.000000000 +0000
@@ -7,6 +7,21 @@
 #
 # Copyright (C) 1994 by Linus Torvalds
 #
+# Creating a compressed kernel image (arch/alpha/boot/vmlinux.gz)
+# is done via:
+#
+#	make boot
+#
+# Creating a BOOTP image (arch/alpha/boot/bootpfile or bootpzfile)
+# is done via:
+#
+#	make bootpfile		# using an uncompressed kernel
+#	make bootpzfile		# using a compressed kernel
+#
+# Adding an INITRD image to a BOOTP file (arch/alpha/boot/bootpzfile)
+# can be done, e.g, via:
+#
+# INITRD=`pwd`/initrd.img make bootpzfile
 
 LINKFLAGS = -static -T bootloader.lds #-N -relax
 
@@ -17,6 +32,7 @@
 
 OBJECTS = head.o main.o
 BPOBJECTS = head.o bootp.o
+BPZOBJECTS = head.o bootpz.o misc.o
 TARGETS = vmlinux.gz tools/objstrip # also needed by aboot & milo
 VMLINUX = $(TOPDIR)/vmlinux
 OBJSTRIP = tools/objstrip
@@ -41,6 +57,12 @@
 	cat $(INITRD) >> bootpfile
 endif
 
+bootpzfile:	tools/bootpzh vmlinux.nh.gz
+	cat tools/bootpzh vmlinux.nh.gz > bootpzfile
+ifdef INITRD
+	cat $(INITRD) >> bootpzfile
+endif
+
 srmboot:	bootdevice bootimage
 	dd if=bootimage of=$(BOOTDEV) bs=512 seek=1 skip=1
 	tools/mkbb $(BOOTDEV) tools/lxboot
@@ -48,16 +70,31 @@
 bootdevice:
 	@test "$(BOOTDEV)" != ""  || (echo You must specify BOOTDEV ; exit -1)
 
-vmlinux.gz: vmlinux
-	gzip -fv9 vmlinux
+vmlinux.gz: $(TOPDIR)/vmlinux
+	gzip -fv9c $(TOPDIR)/vmlinux > vmlinux.gz
+
+vmlinux.nh.gz: vmlinux.nh
+	gzip -fv9c vmlinux.nh > vmlinux.nh.gz
 
 main.o: ksize.h
 
 bootp.o: ksize.h
 
+bootpz.o: kzsize.h
+
 ksize.h: vmlinux.nh dummy
 	echo "#define KERNEL_SIZE `ls -l vmlinux.nh | awk '{print $$5}'`" > $@T
 ifdef INITRD
+	[ ! \( -f $(INITRD) \) ] || exit 1
+	echo "#define INITRD_IMAGE_SIZE `ls -l $(INITRD) | awk '{print $$5}'`" >> $@T
+endif
+	cmp -s $@T $@ || mv -f $@T $@
+	rm -f $@T
+
+kzsize.h: vmlinux.nh.gz dummy
+	echo "#define KERNEL_SIZE `ls -l vmlinux.nh | awk '{print $$5}'`" > $@T
+	echo "#define KERNEL_Z_SIZE `ls -l vmlinux.nh.gz | awk '{print $$5}'`" >> $@T
+ifdef INITRD
 	[ -f $(INITRD) ] || exit 1
 	echo "#define INITRD_IMAGE_SIZE `ls -l $(INITRD) | awk '{print $$5}'`" >> $@T
 endif
@@ -67,7 +104,7 @@
 vmlinux.nh: $(VMLINUX) $(OBJSTRIP)
 	$(OBJSTRIP) -v $(VMLINUX) vmlinux.nh
 
-vmlinux: $(TOPDIR)/vmlinux
+vmlinux: $(VMLINUX)
 	$(STRIP) -o vmlinux $(VMLINUX)
 
 tools/lxboot: $(OBJSTRIP) bootloader
@@ -79,6 +116,9 @@
 tools/bootph: bootpheader $(OBJSTRIP)
 	$(OBJSTRIP) -vb bootpheader tools/bootph
 
+tools/bootpzh: bootpzheader $(OBJSTRIP)
+	$(OBJSTRIP) -vb bootpzheader tools/bootpzh
+
 $(OBJSTRIP): $(OBJSTRIP).c
 	$(HOSTCC) $(HOSTCFLAGS) -I$(HPATH) $(OBJSTRIP).c -o $(OBJSTRIP)
 
@@ -91,6 +131,11 @@
 bootpheader: $(BPOBJECTS)
 	$(LD) $(LINKFLAGS) $(BPOBJECTS) $(LIBS) -o bootpheader
 
+bootpzheader: $(BPZOBJECTS)
+	$(LD) $(LINKFLAGS) $(BPZOBJECTS) $(LIBS) -o bootpzheader
+
+misc.o: misc.c $(TOPDIR)/lib/inflate.c
+
 clean:
 	rm -f $(TARGETS) bootloader bootimage bootpfile bootpheader
 	rm -f tools/mkbb tools/bootlx tools/lxboot tools/bootph
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/alpha/boot/bootpz.c linux-2.4.23-pre8/arch/alpha/boot/bootpz.c
--- linux-2.4.22/arch/alpha/boot/bootpz.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/alpha/boot/bootpz.c	2003-10-22 22:48:39.000000000 +0000
@@ -0,0 +1,447 @@
+/*
+ * arch/alpha/boot/bootpz.c
+ *
+ * Copyright (C) 1997 Jay Estabrook
+ *
+ * This file is used for creating a compressed BOOTP file for the
+ * Linux/AXP kernel
+ *
+ * based significantly on the arch/alpha/boot/main.c of Linus Torvalds
+ * and the decompression code from MILO.
+ */
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/mm.h>
+
+#include <asm/system.h>
+#include <asm/console.h>
+#include <asm/hwrpb.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+
+#include <stdarg.h>
+
+#include "kzsize.h"
+
+/* FIXME FIXME FIXME */
+#define MALLOC_AREA_SIZE 0x200000 /* 2MB for now */
+/* FIXME FIXME FIXME */
+
+
+#undef DEBUG_CHECK_RANGE
+#define DEBUG_ADDRESSES
+
+#define DEBUG_SP(x) \
+    {register long sp asm("30"); srm_printk("%s (sp=%lx)\n", x, sp);}
+
+extern unsigned long switch_to_osf_pal(unsigned long nr,
+	struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
+	unsigned long *vptb);
+
+extern int decompress_kernel(void* destination, void *source,
+			     size_t ksize, size_t kzsize);
+
+struct hwrpb_struct *hwrpb = INIT_HWRPB;
+static struct pcb_struct pcb_va[1];
+
+/*
+ * Find a physical address of a virtual object..
+ *
+ * This is easy using the virtual page table address.
+ */
+#define VPTB	((unsigned long *) 0x200000000)
+
+static inline unsigned long
+find_pa(unsigned long address)
+{
+	unsigned long result;
+
+	result = VPTB[address >> 13];
+	result >>= 32;
+	result <<= 13;
+	result |= address & 0x1fff;
+	return result;
+}	
+
+int
+check_range(unsigned long vstart, unsigned long vend,
+	    unsigned long kstart, unsigned long kend)
+{
+	unsigned long vaddr, kaddr;
+
+#ifdef DEBUG_CHECK_RANGE
+	srm_printk("check_range: V[0x%lx:0x%lx] K[0x%lx:0x%lx]\n",
+		   vstart, vend, kstart, kend);
+#endif
+	/* do some range checking for detecting an overlap... */
+	for (vaddr = vstart; vaddr <= vend; vaddr += PAGE_SIZE)
+	{
+		kaddr = (find_pa(vaddr) | PAGE_OFFSET);
+		if (kaddr >= kstart && kaddr <= kend)
+		{
+#ifdef DEBUG_CHECK_RANGE
+			srm_printk("OVERLAP: vaddr 0x%lx kaddr 0x%lx"
+				   " [0x%lx:0x%lx]\n",
+				   vaddr, kaddr, kstart, kend);
+#endif
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * This function moves into OSF/1 pal-code, and has a temporary
+ * PCB for that. The kernel proper should replace this PCB with
+ * the real one as soon as possible.
+ *
+ * The page table muckery in here depends on the fact that the boot
+ * code has the L1 page table identity-map itself in the second PTE
+ * in the L1 page table. Thus the L1-page is virtually addressable
+ * itself (through three levels) at virtual address 0x200802000.
+ */
+
+#define L1	((unsigned long *) 0x200802000)
+
+void
+pal_init(void)
+{
+	unsigned long i, rev;
+	struct percpu_struct * percpu;
+	struct pcb_struct * pcb_pa;
+
+	/* Create the dummy PCB.  */
+	pcb_va->ksp = 0;
+	pcb_va->usp = 0;
+	pcb_va->ptbr = L1[1] >> 32;
+	pcb_va->asn = 0;
+	pcb_va->pcc = 0;
+	pcb_va->unique = 0;
+	pcb_va->flags = 1;
+	pcb_va->res1 = 0;
+	pcb_va->res2 = 0;
+	pcb_pa = (struct pcb_struct *)find_pa((unsigned long)pcb_va);
+
+	/*
+	 * a0 = 2 (OSF)
+	 * a1 = return address, but we give the asm the vaddr of the PCB
+	 * a2 = physical addr of PCB
+	 * a3 = new virtual page table pointer
+	 * a4 = KSP (but the asm sets it)
+	 */
+	srm_printk("Switching to OSF PAL-code... ");
+
+	i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB);
+	if (i) {
+		srm_printk("failed, code %ld\n", i);
+		__halt();
+	}
+
+	percpu = (struct percpu_struct *)
+		(INIT_HWRPB->processor_offset + (unsigned long) INIT_HWRPB);
+	rev = percpu->pal_revision = percpu->palcode_avail[2];
+
+	srm_printk("OK (rev %lx)\n", rev);
+
+	tbia(); /* do it directly in case we are SMP */
+}
+
+/*
+ * Start the kernel.
+ */
+static inline void
+runkernel(void)
+{
+	__asm__ __volatile__(
+		"bis %1,%1,$30\n\t"
+		"bis %0,%0,$27\n\t"
+		"jmp ($27)"
+		: /* no outputs: it doesn't even return */
+		: "r" (START_ADDR),
+		  "r" (PAGE_SIZE + INIT_STACK));
+}
+
+/* Must record the SP (it is virtual) on entry, so we can make sure
+   not to overwrite it during movement or decompression. */
+unsigned long SP_on_entry;
+
+/* Calculate the kernel image address based on the end of the BOOTP
+   bootstrapper (ie this program).
+*/
+extern char _end;
+#define KERNEL_ORIGIN \
+	((((unsigned long)&_end) + 511) & ~511)
+
+/* Round address to next higher page boundary. */
+#define NEXT_PAGE(a)	(((a) | (PAGE_SIZE - 1)) + 1)
+
+#ifdef INITRD_IMAGE_SIZE
+# define REAL_INITRD_SIZE INITRD_IMAGE_SIZE
+#else
+# define REAL_INITRD_SIZE 0
+#endif
+
+/* Defines from include/asm-alpha/system.h
+
+	BOOT_ADDR	Virtual address at which the consoles loads
+			the BOOTP image.
+
+	KERNEL_START    KSEG address at which the kernel is built to run,
+			which includes some initial data pages before the
+			code.
+
+	START_ADDR	KSEG address of the entry point of kernel code.
+
+	ZERO_PGE	KSEG address of page full of zeroes, but 
+			upon entry to kerne cvan be expected
+			to hold the parameter list and possible
+			INTRD information.
+
+   These are used in the local defines below.
+*/
+  
+
+/* Virtual addresses for the BOOTP image. Note that this includes the
+   bootstrapper code as well as the compressed kernel image, and
+   possibly the INITRD image.
+
+   Oh, and do NOT forget the STACK, which appears to be placed virtually
+   beyond the end of the loaded image.
+*/
+#define V_BOOT_IMAGE_START	BOOT_ADDR
+#define V_BOOT_IMAGE_END	SP_on_entry
+
+/* Virtual addresses for just the bootstrapper part of the BOOTP image. */
+#define V_BOOTSTRAPPER_START	BOOT_ADDR
+#define V_BOOTSTRAPPER_END	KERNEL_ORIGIN
+
+/* Virtual addresses for just the data part of the BOOTP
+   image. This may also include the INITRD image, but always
+   includes the STACK.
+*/
+#define V_DATA_START		KERNEL_ORIGIN
+#define V_INITRD_START		(KERNEL_ORIGIN + KERNEL_Z_SIZE)
+#define V_INTRD_END		(V_INITRD_START + REAL_INITRD_SIZE)
+#define V_DATA_END	 	V_BOOT_IMAGE_END
+
+/* KSEG addresses for the uncompressed kernel.
+
+   Note that the end address includes workspace for the decompression.
+   Note also that the DATA_START address is ZERO_PGE, to which we write
+   just before jumping to the kernel image at START_ADDR.
+ */
+#define K_KERNEL_DATA_START	ZERO_PGE
+#define K_KERNEL_IMAGE_START	START_ADDR
+#define K_KERNEL_IMAGE_END	(START_ADDR + KERNEL_SIZE)
+
+/* Define to where we may have to decompress the kernel image, before
+   we move it to the final position, in case of overlap. This will be
+   above the final position of the kernel.
+
+   Regardless of overlap, we move the INITRD image to the end of this
+   copy area, because there needs to be a buffer area after the kernel
+   for "bootmem" anyway.
+*/
+#define K_COPY_IMAGE_START	NEXT_PAGE(K_KERNEL_IMAGE_END)
+#define K_INITRD_START		NEXT_PAGE(K_COPY_IMAGE_START + KERNEL_SIZE)
+#define K_COPY_IMAGE_END \
+    (K_INITRD_START + REAL_INITRD_SIZE + MALLOC_AREA_SIZE)
+#define K_COPY_IMAGE_SIZE \
+    NEXT_PAGE(K_COPY_IMAGE_END - K_COPY_IMAGE_START)
+
+void
+start_kernel(void)
+{
+	int must_move = 0;
+
+	/* Initialize these for the decompression-in-place situation,
+	   which is the smallest amount of work and most likely to
+	   occur when using the normal START_ADDR of the kernel
+	   (currently set to 16MB, to clear all console code.
+	*/
+	unsigned long uncompressed_image_start = K_KERNEL_IMAGE_START;
+	unsigned long uncompressed_image_end = K_KERNEL_IMAGE_END;
+
+	unsigned long initrd_image_start = K_INITRD_START;
+
+	/*
+	 * Note that this crufty stuff with static and envval
+	 * and envbuf is because:
+	 *
+	 * 1. Frequently, the stack is short, and we don't want to overrun;
+	 * 2. Frequently the stack is where we are going to copy the kernel to;
+	 * 3. A certain SRM console required the GET_ENV output to stack.
+	 *    ??? A comment in the aboot sources indicates that the GET_ENV
+	 *    destination must be quadword aligned.  Might this explain the
+	 *    behaviour, rather than requiring output to the stack, which
+	 *    seems rather far-fetched.
+	 */
+	static long nbytes;
+	static char envval[256] __attribute__((aligned(8)));
+	register unsigned long asm_sp asm("30");
+
+	SP_on_entry = asm_sp;
+
+	srm_printk("Linux/Alpha BOOTPZ Loader for Linux " UTS_RELEASE "\n");
+
+	/* Validity check the HWRPB. */
+	if (INIT_HWRPB->pagesize != 8192) {
+		srm_printk("Expected 8kB pages, got %ldkB\n",
+		           INIT_HWRPB->pagesize >> 10);
+		return;
+	}
+	if (INIT_HWRPB->vptb != (unsigned long) VPTB) {
+		srm_printk("Expected vptb at %p, got %p\n",
+			   VPTB, (void *)INIT_HWRPB->vptb);
+		return;
+	}
+
+	/* PALcode (re)initialization. */
+	pal_init();
+
+	/* Get the parameter list from the console environment variable. */
+	nbytes = callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));
+	if (nbytes < 0 || nbytes >= sizeof(envval)) {
+		nbytes = 0;
+	}
+	envval[nbytes] = '\0';
+
+#ifdef DEBUG_ADDRESSES
+	srm_printk("START_ADDR 0x%lx\n", START_ADDR);
+	srm_printk("KERNEL_ORIGIN 0x%lx\n", KERNEL_ORIGIN);
+	srm_printk("KERNEL_SIZE 0x%x\n", KERNEL_SIZE);
+	srm_printk("KERNEL_Z_SIZE 0x%x\n", KERNEL_Z_SIZE);
+#endif
+
+	/* Since all the SRM consoles load the BOOTP image at virtual
+	 * 0x20000000, we have to ensure that the physical memory
+	 * pages occupied by that image do NOT overlap the physical
+	 * address range where the kernel wants to be run.  This
+	 * causes real problems when attempting to cdecompress the
+	 * former into the latter... :-(
+	 *
+	 * So, we may have to decompress/move the kernel/INITRD image
+	 * virtual-to-physical someplace else first before moving
+	 * kernel /INITRD to their final resting places... ;-}
+	 *
+	 * Sigh...
+	 */
+
+	/* First, check to see if the range of addresses occupied by
+	   the bootstrapper part of the BOOTP image include any of the
+	   physical pages into which the kernel will be placed for
+	   execution.
+
+	   We only need check on the final kernel image range, since we
+	   will put the INITRD someplace that we can be sure is not
+	   in conflict.
+	 */
+	if (check_range(V_BOOTSTRAPPER_START, V_BOOTSTRAPPER_END,
+			K_KERNEL_DATA_START, K_KERNEL_IMAGE_END))
+	{
+		srm_printk("FATAL ERROR: overlap of bootstrapper code\n");
+		__halt();
+	}
+
+	/* Next, check to see if the range of addresses occupied by
+	   the compressed kernel/INITRD/stack portion of the BOOTP
+	   image include any of the physical pages into which the
+	   decompressed kernel or the INITRD will be placed for
+	   execution.
+	 */
+	if (check_range(V_DATA_START, V_DATA_END,
+			K_KERNEL_IMAGE_START, K_COPY_IMAGE_END))
+	{
+#ifdef DEBUG_ADDRESSES
+		srm_printk("OVERLAP: cannot decompress in place\n");
+#endif
+		uncompressed_image_start = K_COPY_IMAGE_START;
+		uncompressed_image_end = K_COPY_IMAGE_END;
+		must_move = 1;
+
+		/* Finally, check to see if the range of addresses
+		   occupied by the compressed kernel/INITRD part of
+		   the BOOTP image include any of the physical pages
+		   into which that part is to be copied for
+		   decompression.
+		*/
+		while (check_range(V_DATA_START, V_DATA_END,
+				   uncompressed_image_start,
+				   uncompressed_image_end))
+		{
+#if 0
+			uncompressed_image_start += K_COPY_IMAGE_SIZE;
+			uncompressed_image_end += K_COPY_IMAGE_SIZE;
+			initrd_image_start += K_COPY_IMAGE_SIZE;
+#else
+			/* Keep as close as possible to end of BOOTP image. */
+			uncompressed_image_start += PAGE_SIZE;
+			uncompressed_image_end += PAGE_SIZE;
+			initrd_image_start += PAGE_SIZE;
+#endif
+		}
+	}
+
+	srm_printk("Starting to load the kernel with args '%s'\n", envval);
+
+#ifdef DEBUG_ADDRESSES
+	srm_printk("Decompressing the kernel...\n"
+		   "...from 0x%lx to 0x%lx size 0x%x\n",
+		   V_DATA_START,
+		   uncompressed_image_start,
+		   KERNEL_SIZE);
+#endif
+        decompress_kernel((void *)uncompressed_image_start,
+			  (void *)V_DATA_START,
+			  KERNEL_SIZE, KERNEL_Z_SIZE);
+
+	/*
+	 * Now, move things to their final positions, if/as required.
+	 */
+
+#ifdef INITRD_IMAGE_SIZE
+
+	/* First, we always move the INITRD image, if present. */
+#ifdef DEBUG_ADDRESSES
+	srm_printk("Moving the INITRD image...\n"
+		   " from 0x%lx to 0x%lx size 0x%x\n",
+		   V_INITRD_START,
+		   initrd_image_start,
+		   INITRD_IMAGE_SIZE);
+#endif
+	memcpy((void *)initrd_image_start,
+	       (void *)V_INITRD_START,
+	       INITRD_IMAGE_SIZE);
+
+#endif /* INITRD_IMAGE_SIZE */
+
+	/* Next, we may have to move the uncompressed kernel to the
+	   final destination.
+	 */
+	if (must_move) {
+#ifdef DEBUG_ADDRESSES
+		srm_printk("Moving the uncompressed kernel...\n"
+			   "...from 0x%lx to 0x%lx size 0x%x\n",
+			   uncompressed_image_start,
+			   K_KERNEL_IMAGE_START,
+			   (unsigned)KERNEL_SIZE);
+#endif
+		memcpy((void *)K_KERNEL_IMAGE_START,
+		       (void *)uncompressed_image_start,
+		       KERNEL_SIZE);
+	}
+	
+	/* Clear the zero page, then move the argument list in. */
+	memset((char*)ZERO_PGE, 0, PAGE_SIZE);
+	strcpy((char*)ZERO_PGE, envval);
+
+#ifdef INITRD_IMAGE_SIZE
+	/* Finally, set the INITRD paramenters for the kernel. */
+	((long *)(ZERO_PGE+256))[0] = initrd_image_start;
+	((long *)(ZERO_PGE+256))[1] = INITRD_IMAGE_SIZE;
+
+#endif /* INITRD_IMAGE_SIZE */
+
+	runkernel();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/alpha/boot/misc.c linux-2.4.23-pre8/arch/alpha/boot/misc.c
--- linux-2.4.22/arch/alpha/boot/misc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/alpha/boot/misc.c	2003-10-22 22:47:59.000000000 +0000
@@ -0,0 +1,207 @@
+/*
+ * misc.c
+ * 
+ * This is a collection of several routines from gzip-1.0.3 
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Modified for ARM Linux by Russell King
+ *
+ * Nicolas Pitre <nico@visuaide.com>  1999/04/14 :
+ *  For this code to run directly from Flash, all constant variables must
+ *  be marked with 'const' and all other variables initialized at run-time 
+ *  only.  This way all non constant variables will end up in the bss segment,
+ *  which should point to addresses in RAM and cleared to 0 on start.
+ *  This allows for a much quicker boot time.
+ *
+ * Modified for Alpha, from the ARM version, by Jay Estabrook 2003.
+ */
+
+#include <linux/kernel.h>
+
+#include <asm/uaccess.h>
+
+#define memzero(s,n)	memset ((s),0,(n))
+#define puts		srm_printk
+extern long srm_printk(const char *, ...)
+     __attribute__ ((format (printf, 1, 2)));;
+
+/*
+ * gzip delarations
+ */
+#define OF(args)  args
+#define STATIC static
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define WSIZE 0x8000		/* Window size must be at least 32k, */
+				/* and a power of two */
+
+static uch *inbuf;		/* input buffer */
+static uch *window;		/* Sliding window buffer */
+
+static unsigned insize;		/* valid bytes in inbuf */
+static unsigned inptr;		/* index of next byte to be processed in inbuf */
+static unsigned outcnt;		/* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
+#define RESERVED     0xC0 /* bit 6,7:   reserved */
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) {if(!(cond)) error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+static int  fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+static char *input_data;
+static int  input_data_size;
+
+static uch *output_data;
+static ulg output_ptr;
+static ulg bytes_out;
+
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+extern int end;
+static ulg free_mem_ptr;
+static ulg free_mem_ptr_end;
+
+#define HEAP_SIZE 0x2000
+
+#include "../../../lib/inflate.c"
+
+static void *malloc(int size)
+{
+	void *p;
+
+	if (size <0) error("Malloc error\n");
+	if (free_mem_ptr <= 0) error("Memory error\n");
+
+	free_mem_ptr = (free_mem_ptr + 3) & ~3;	/* Align */
+
+	p = (void *)free_mem_ptr;
+	free_mem_ptr += size;
+
+	if (free_mem_ptr >= free_mem_ptr_end)
+		error("Out of memory");
+	return p;
+}
+
+static void free(void *where)
+{ /* gzip_mark & gzip_release do the free */
+}
+
+static void gzip_mark(void **ptr)
+{
+	*ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+	free_mem_ptr = (long) *ptr;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+int fill_inbuf(void)
+{
+	if (insize != 0)
+		error("ran out of input data\n");
+
+	inbuf = input_data;
+	insize = input_data_size;
+
+	inptr = 1;
+	return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+void flush_window(void)
+{
+	ulg c = crc;
+	unsigned n;
+	uch *in, *out, ch;
+
+	in = window;
+	out = &output_data[output_ptr];
+	for (n = 0; n < outcnt; n++) {
+		ch = *out++ = *in++;
+		c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+	}
+	crc = c;
+	bytes_out += (ulg)outcnt;
+	output_ptr += (ulg)outcnt;
+	outcnt = 0;
+/*	puts("."); */
+}
+
+static void error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	while(1);	/* Halt */
+}
+
+unsigned int
+decompress_kernel(void *output_start,
+		  void *input_start,
+		  size_t ksize,
+		  size_t kzsize)
+{
+	output_data		= (uch *)output_start;
+	input_data		= (uch *)input_start;
+	input_data_size		= kzsize; /* use compressed size */
+
+	/* FIXME FIXME FIXME */
+	free_mem_ptr		= (ulg)output_start + ksize;
+	free_mem_ptr_end	= (ulg)output_start + ksize + 0x200000;
+	/* FIXME FIXME FIXME */
+
+	/* put in temp area to reduce initial footprint */
+	window = malloc(WSIZE);
+
+	makecrc();
+/*	puts("Uncompressing Linux..."); */
+	gunzip();
+/*	puts(" done, booting the kernel.\n"); */
+	return output_ptr;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/alpha/boot/tools/objstrip.c linux-2.4.23-pre8/arch/alpha/boot/tools/objstrip.c
--- linux-2.4.22/arch/alpha/boot/tools/objstrip.c	2001-05-21 20:41:40.000000000 +0000
+++ linux-2.4.23-pre8/arch/alpha/boot/tools/objstrip.c	2003-10-22 22:49:56.000000000 +0000
@@ -27,7 +27,6 @@
 #include <linux/param.h>
 #include <linux/string.h>
 #ifdef __ELF__
-# include <asm/elf.h>
 # include <linux/elf.h>
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/alpha/config.in linux-2.4.23-pre8/arch/alpha/config.in
--- linux-2.4.22/arch/alpha/config.in	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/alpha/config.in	2003-10-22 22:48:12.000000000 +0000
@@ -269,6 +269,7 @@
 
 if [ "$CONFIG_SMP" = "y" ]; then
    define_bool CONFIG_HAVE_DEC_LOCK y
+   int  'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32
 fi
 
 if [ "$CONFIG_ALPHA_GENERIC" = "y" -o "$CONFIG_ALPHA_SRM" = "y" ]; then
@@ -439,7 +440,16 @@
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
-bool 'Legacy kernel start address' CONFIG_ALPHA_LEGACY_START_ADDRESS
+if [ "$CONFIG_ALPHA_TITAN" = "y" -o "$CONFIG_ALPHA_WILDFIRE" = "y" -o \
+     "$CONFIG_ALPHA_MARVEL" = "y" ]; then
+   define_bool CONFIG_ALPHA_LEGACY_START_ADDRESS n
+else
+   if [ "$CONFIG_ALPHA_GENERIC" = "y" ]; then
+      bool 'Legacy kernel start address' CONFIG_ALPHA_LEGACY_START_ADDRESS
+   else
+      define_bool CONFIG_ALPHA_LEGACY_START_ADDRESS y
+   fi
+fi
 
 bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
 if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
@@ -453,6 +463,8 @@
    define_tristate CONFIG_MATHEMU y
 fi
 
+int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
+
 endmenu
 
 source crypto/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/alpha/kernel/Makefile linux-2.4.23-pre8/arch/alpha/kernel/Makefile
--- linux-2.4.22/arch/alpha/kernel/Makefile	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/alpha/kernel/Makefile	2003-10-22 22:48:39.000000000 +0000
@@ -37,17 +37,21 @@
 ifdef CONFIG_ALPHA_GENERIC
 
 obj-y 	 += core_apecs.o core_cia.o core_irongate.o core_lca.o core_mcpcia.o \
-	    core_polaris.o core_t2.o core_tsunami.o core_titan.o \
-	    core_wildfire.o core_marvel.o \
+	    core_polaris.o core_t2.o core_tsunami.o \
 	    sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o sys_eiger.o \
-	    sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o sys_titan.o \
+	    sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o \
 	    sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \
 	    sys_sable.o sys_sio.o sys_sx164.o sys_takara.o sys_rx164.o \
-	    sys_wildfire.o sys_marvel.o \
-	    err_titan.o err_marvel.o \
 	    irq_pyxis.o srmcons.o gct.o \
 	    es1888.o smc37c669.o smc37c93x.o ns87312.o
 
+ifndef CONFIG_ALPHA_LEGACY_START_ADDRESS
+obj-y 	 += core_titan.o core_wildfire.o core_marvel.o \
+	    sys_titan.o sys_wildfire.o sys_marvel.o \
+	    err_titan.o err_marvel.o
+
+endif
+
 else
 
 # Misc support
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/alpha/kernel/irq.c linux-2.4.23-pre8/arch/alpha/kernel/irq.c
--- linux-2.4.22/arch/alpha/kernel/irq.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/arch/alpha/kernel/irq.c	2003-10-22 22:49:16.000000000 +0000
@@ -214,7 +214,7 @@
 
 	if (!shared) {
 		desc->depth = 0;
-		desc->status &= ~IRQ_DISABLED;
+		desc->status &= ~(IRQ_DISABLED | IRQ_INPROGRESS);
 		desc->handler->startup(irq);
 	}
 	spin_unlock_irqrestore(&desc->lock,flags);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/alpha/kernel/setup.c linux-2.4.23-pre8/arch/alpha/kernel/setup.c
--- linux-2.4.22/arch/alpha/kernel/setup.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/alpha/kernel/setup.c	2003-10-22 22:47:56.000000000 +0000
@@ -583,6 +583,35 @@
 	       var_name, alpha_mv.vector_name,
 	       (alpha_using_srm ? "SRM" : "MILO"));
 
+	printk("Major Options: "
+#ifdef CONFIG_SMP
+	       "SMP "
+#endif
+#ifdef CONFIG_ALPHA_EV56
+	       "EV56 "
+#endif
+#ifdef CONFIG_ALPHA_EV67
+	       "EV67 "
+#endif
+#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS
+	       "LEGACY_START "
+#endif
+
+#ifdef CONFIG_DISCONTIGMEM
+	       "DISCONTIGMEM "
+#ifdef CONFIG_NUMA
+	       "NUMA "
+#endif
+#endif
+
+#ifdef CONFIG_DEBUG_SPINLOCK
+	       "DEBUG_SPINLOCK "
+#endif
+#ifdef CONFIG_MAGIC_SYSRQ
+	       "MAGIC_SYSRQ "
+#endif
+	       "\n");
+
 	printk("Command line: %s\n", command_line);
 
 	/* 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/alpha/kernel/sys_nautilus.c linux-2.4.23-pre8/arch/alpha/kernel/sys_nautilus.c
--- linux-2.4.22/arch/alpha/kernel/sys_nautilus.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/alpha/kernel/sys_nautilus.c	2003-10-22 22:48:31.000000000 +0000
@@ -226,11 +226,13 @@
 	if (request_resource(&iomem_resource, bus->resource[1]) < 0)
 		printk(KERN_ERR "Failed to request MEM on hose 0\n");
 
-	if (pci_mem < memtop && pci_mem > alpha_mv.min_mem_address) {
+	if (pci_mem < memtop)
+		memtop = pci_mem;
+	if (memtop > alpha_mv.min_mem_address) {
 		free_reserved_mem(__va(alpha_mv.min_mem_address),
-				  __va(pci_mem));
+				  __va(memtop));
 		printk("nautilus_init_pci: %ldk freed\n",
-			(pci_mem - alpha_mv.min_mem_address) >> 10);
+			(memtop - alpha_mv.min_mem_address) >> 10);
 	}
 
 	if ((IRONGATE0->dev_vendor >> 16) > 0x7006)	/* Albacore? */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/alpha/mm/init.c linux-2.4.23-pre8/arch/alpha/mm/init.c
--- linux-2.4.22/arch/alpha/mm/init.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/arch/alpha/mm/init.c	2003-10-22 22:48:29.000000000 +0000
@@ -234,7 +234,8 @@
 	/* Allocate one PGD and one PMD.  In the case of SRM, we'll need
 	   these to actually remap the console.  There is an assumption
 	   here that only one of each is needed, and this allows for 8MB.
-	   Currently (late 1999), big consoles are still under 4MB.
+	   On systems with larger consoles, additional pages will be
+	   allocated as needed during the mapping process.
 
 	   In the case of not SRM, but not CONFIG_ALPHA_LARGE_VMALLOC,
 	   we need to allocate the PGD we use for vmalloc before we start
@@ -261,6 +262,15 @@
 			unsigned long paddr = crb->map[i].pa;
 			crb->map[i].va = vaddr;
 			for (j = 0; j < crb->map[i].count; ++j) {
+				/* Newer console's (especially on larger
+				   systems) may require more pages of
+				   PTEs. Grab additional pages as needed. */
+				if (pmd != pmd_offset(pgd, vaddr)) {
+					memset(kernel_end, 0, PAGE_SIZE);
+					pmd = pmd_offset(pgd, vaddr);
+					pmd_set(pmd, (pte_t *)kernel_end);
+					kernel_end += PAGE_SIZE;
+				}
 				set_pte(pte_offset(pmd, vaddr),
 					mk_pte_phys(paddr, PAGE_KERNEL));
 				paddr += PAGE_SIZE;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/arm/config.in linux-2.4.23-pre8/arch/arm/config.in
--- linux-2.4.22/arch/arm/config.in	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/arm/config.in	2003-10-22 22:47:59.000000000 +0000
@@ -730,6 +730,9 @@
 dep_bool '  Kernel low-level debugging functions' CONFIG_DEBUG_LL $CONFIG_DEBUG_KERNEL
 dep_bool '    Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
 dep_bool '    Kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
+
+int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
+
 endmenu
 
 source crypto/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/arm/mm/mm-armo.c linux-2.4.23-pre8/arch/arm/mm/mm-armo.c
--- linux-2.4.22/arch/arm/mm/mm-armo.c	2001-04-12 19:20:31.000000000 +0000
+++ linux-2.4.23-pre8/arch/arm/mm/mm-armo.c	2003-10-22 22:48:39.000000000 +0000
@@ -104,6 +104,7 @@
 no_pte:
 	spin_unlock(&mm->page_table_lock);
 	pmd_free(new_pmd);
+	check_pgt_cache();
 	free_pgd_slow(new_pgd);
 	return NULL;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/arm/mm/mm-armv.c linux-2.4.23-pre8/arch/arm/mm/mm-armv.c
--- linux-2.4.22/arch/arm/mm/mm-armv.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/arm/mm/mm-armv.c	2003-10-22 22:49:08.000000000 +0000
@@ -123,6 +123,7 @@
 no_pte:
 	spin_unlock(&mm->page_table_lock);
 	pmd_free(new_pmd);
+	check_pgt_cache();
 	free_pages((unsigned long)new_pgd, 2);
 	return NULL;
 
@@ -157,6 +158,7 @@
 	pmd_clear(pmd);
 	pte_free(pte);
 	pmd_free(pmd);
+	check_pgt_cache();
 free:
 	free_pages((unsigned long) pgd, 2);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/cris/config.in linux-2.4.23-pre8/arch/cris/config.in
--- linux-2.4.22/arch/cris/config.in	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/cris/config.in	2003-10-22 22:49:01.000000000 +0000
@@ -272,6 +272,8 @@
   int '  Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
 
+int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
+
 source crypto/Config.in
 source lib/Config.in
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/boot/setup.S linux-2.4.23-pre8/arch/i386/boot/setup.S
--- linux-2.4.22/arch/i386/boot/setup.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/boot/setup.S	2003-10-22 22:47:30.000000000 +0000
@@ -45,6 +45,10 @@
  * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes
  * by Robert Schwebel, December 2001 <robert@schwebel.de>
  *
+ * BIOS Enhanced Disk Drive support
+ * by Matt Domsch <Matt_Domsch@dell.com> October 2002
+ * conformant to T13 Committee www.t13.org
+ *   projects 1572D, 1484D, 1386D, 1226DT
  */
 
 #include <linux/config.h>
@@ -53,6 +57,7 @@
 #include <linux/compile.h>
 #include <asm/boot.h>
 #include <asm/e820.h>
+#include <asm/edd.h>
 #include <asm/page.h>
 	
 /* Signature words to ensure LILO loaded us right */
@@ -543,6 +548,70 @@
 done_apm_bios:
 #endif
 
+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+# Do the BIOS Enhanced Disk Drive calls
+# This consists of two calls:
+#    int 13h ah=41h "Check Extensions Present"
+#    int 13h ah=48h "Get Device Parameters"
+#
+# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use
+# in the empty_zero_page at EDDBUF.  The first four bytes of which are
+# used to store the device number, interface support map and version
+# results from fn41.  The following 74 bytes are used to store
+# the results from fn48.  Starting from device 80h, fn41, then fn48
+# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE).
+# Then the pointer is incremented to store the data for the next call.
+# This repeats until either a device doesn't exist, or until EDDMAXNR
+# devices have been stored.
+# The one tricky part is that ds:si always points four bytes into
+# the structure, and the fn41 results are stored at offsets
+# from there.  This removes the need to increment the pointer for
+# every store, and leaves it ready for the fn48 call.
+# A second one-byte buffer, EDDNR, in the empty_zero_page stores
+# the number of BIOS devices which exist, up to EDDMAXNR.
+# In setup.c, copy_edd() stores both empty_zero_page buffers away
+# for later use, as they would get overwritten otherwise.
+# This code is sensitive to the size of the structs in edd.h
+edd_start:
+						# %ds points to the bootsector
+       						# result buffer for fn48
+    	movw	$EDDBUF+EDDEXTSIZE, %si		# in ds:si, fn41 results
+						# kept just before that
+	movb	$0, (EDDNR)			# zero value at EDDNR
+    	movb	$0x80, %dl			# BIOS device 0x80
+
+edd_check_ext:
+	movb	$CHECKEXTENSIONSPRESENT, %ah    # Function 41
+	movw	$EDDMAGIC1, %bx			# magic
+	int	$0x13				# make the call
+	jc	edd_done			# no more BIOS devices
+
+    	cmpw	$EDDMAGIC2, %bx			# is magic right?
+	jne	edd_next			# nope, next...
+
+    	movb	%dl, %ds:-4(%si)		# store device number
+    	movb	%ah, %ds:-3(%si)		# store version
+	movw	%cx, %ds:-2(%si)		# store extensions
+	incb	(EDDNR)				# note that we stored something
+
+edd_get_device_params:
+	movw	$EDDPARMSIZE, %ds:(%si)		# put size
+    	movb	$GETDEVICEPARAMETERS, %ah	# Function 48
+	int	$0x13				# make the call
+						# Don't check for fail return
+						# it doesn't matter.
+	movw	%si, %ax			# increment si
+	addw	$EDDPARMSIZE+EDDEXTSIZE, %ax
+	movw	%ax, %si
+
+edd_next:
+        incb	%dl				# increment to next device
+       	cmpb	$EDDMAXNR, (EDDNR) 		# Out of space?
+	jb	edd_check_ext			# keep looping
+
+edd_done:
+#endif
+
 # Now we want to move to protected mode ...
 	cmpw	$0, %cs:realmode_swtch
 	jz	rmodeswtch_normal
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/config.in linux-2.4.23-pre8/arch/i386/config.in
--- linux-2.4.22/arch/i386/config.in	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/config.in	2003-10-22 22:48:24.000000000 +0000
@@ -201,6 +201,10 @@
 tristate '/dev/cpu/*/msr - Model-specific register support' CONFIG_X86_MSR
 tristate '/dev/cpu/*/cpuid - CPU information support' CONFIG_X86_CPUID
 
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   tristate 'BIOS Enhanced Disk Drive calls determine boot disk (EXPERIMENTAL)' CONFIG_EDD
+fi
+
 choice 'High Memory Support' \
 	"off    CONFIG_NOHIGHMEM \
 	 4GB    CONFIG_HIGHMEM4G \
@@ -231,6 +235,7 @@
       define_bool CONFIG_X86_IO_APIC y
    fi
 else
+   int  'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32
    bool 'Multi-node NUMA system support' CONFIG_X86_NUMA
    if [ "$CONFIG_X86_NUMA" = "y" ]; then
       #Platform Choices
@@ -476,6 +481,8 @@
    bool '  Compile the kernel with frame pointers' CONFIG_FRAME_POINTER
 fi
 
+int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
+
 endmenu
 
 source crypto/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/defconfig linux-2.4.23-pre8/arch/i386/defconfig
--- linux-2.4.22/arch/i386/defconfig	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/defconfig	2003-10-22 22:47:46.000000000 +0000
@@ -56,6 +56,7 @@
 # CONFIG_MICROCODE is not set
 # CONFIG_X86_MSR is not set
 # CONFIG_X86_CPUID is not set
+# CONFIG_EDD is not set
 CONFIG_NOHIGHMEM=y
 # CONFIG_HIGHMEM4G is not set
 # CONFIG_HIGHMEM64G is not set
@@ -64,6 +65,7 @@
 CONFIG_SMP=y
 # CONFIG_MULTIQUAD is not set
 CONFIG_HAVE_DEC_LOCK=y
+CONFIG_NR_CPUS=32
 
 #
 # General setup
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/Makefile linux-2.4.23-pre8/arch/i386/kernel/Makefile
--- linux-2.4.22/arch/i386/kernel/Makefile	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/Makefile	2003-10-22 22:47:56.000000000 +0000
@@ -38,10 +38,10 @@
 obj-$(CONFIG_APM)		+= apm.o
 obj-$(CONFIG_ACPI_BOOT)		+= acpi.o
 obj-$(CONFIG_ACPI_SLEEP)	+= acpi_wakeup.o
-obj-$(CONFIG_ACPI_HT_ONLY)	+= acpitable.o
 obj-$(CONFIG_SMP)		+= smp.o smpboot.o trampoline.o
 obj-$(CONFIG_X86_LOCAL_APIC)	+= mpparse.o apic.o nmi.o
 obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
 obj-$(CONFIG_X86_VISWS_APIC)	+= visws_apic.o
+obj-$(CONFIG_EDD)             	+= edd.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/acpi.c linux-2.4.23-pre8/arch/i386/kernel/acpi.c
--- linux-2.4.22/arch/i386/kernel/acpi.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/acpi.c	2003-10-22 22:49:19.000000000 +0000
@@ -355,7 +355,6 @@
 
 	result = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
 	if (!result) {
-		printk(KERN_WARNING PREFIX "MADT not present\n");
 		return 0;
 	}
 	else if (result < 0) {
@@ -471,6 +470,34 @@
 
 #endif /*CONFIG_ACPI_BOOT*/
 
+#ifdef	CONFIG_ACPI_BUS
+/*
+ * Set specified PIC IRQ to level triggered mode.
+ *
+ * Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers
+ * for the 8259 PIC.  bit[n] = 1 means irq[n] is Level, otherwise Edge.
+ * ECLR1 is IRQ's 0-7 (IRQ 0, 1, 2 must be 0)
+ * ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0)
+ *
+ * As the BIOS should have done this for us,
+ * print a warning if the IRQ wasn't already set to level.
+ */
+
+void acpi_pic_set_level_irq(unsigned int irq)
+{
+	unsigned char mask = 1 << (irq & 7);
+	unsigned int port = 0x4d0 + (irq >> 3);
+	unsigned char val = inb(port);
+
+	if (!(val & mask)) {
+		printk(KERN_WARNING PREFIX "IRQ %d was Edge Triggered, "
+			"setting to Level Triggerd\n", irq);
+		outb(val | mask, port);
+	}
+}
+#endif /* CONFIG_ACPI_BUS */
+
+
 
 /* --------------------------------------------------------------------------
                               Low-Level Sleep Support
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/acpitable.c linux-2.4.23-pre8/arch/i386/kernel/acpitable.c
--- linux-2.4.22/arch/i386/kernel/acpitable.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/acpitable.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,553 +0,0 @@
-/*
- *  acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1)
- *
- *  Copyright (C) 1999 Andrew Henroid
- *  Copyright (C) 2001 Richard Schaal
- *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
- *  Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * $Id: acpitable.c,v 1.7 2001/11/04 12:21:18 fenrus Exp $
- */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/stddef.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <asm/mpspec.h>
-#include <asm/io.h>
-#include <asm/apic.h>
-#include <asm/apicdef.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-#include "acpitable.h"
-
-static acpi_table_handler acpi_boot_ops[ACPI_TABLE_COUNT];
-
-int acpi_lapic;
-
-static unsigned char __init
-acpi_checksum(void *buffer, int length)
-{
-	int i;
-	unsigned char *bytebuffer;
-	unsigned char sum = 0;
-
-	if (!buffer || length <= 0)
-		return 0;
-
-	bytebuffer = (unsigned char *) buffer;
-
-	for (i = 0; i < length; i++)
-		sum += *(bytebuffer++);
-
-	return sum;
-}
-
-static void __init
-acpi_print_table_header(acpi_table_header * header)
-{
-	if (!header)
-		return;
-
-	printk(KERN_INFO "ACPI table found: %.4s v%d [%.6s %.8s %d.%d]\n",
-	       header->signature, header->revision, header->oem_id,
-	       header->oem_table_id, header->oem_revision >> 16,
-	       header->oem_revision & 0xffff);
-
-	return;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_scan_memory_for_rsdp
- *
- * PARAMETERS:  address       - Starting pointer for search
- *              length        - Maximum length to search
- *
- * RETURN:      Pointer to the RSDP if found and valid, otherwise NULL.
- *
- * DESCRIPTION: Search a block of memory for the RSDP signature
- *
- ******************************************************************************/
-
-static void *__init
-acpi_tb_scan_memory_for_rsdp(void *address, int length)
-{
-	int offset;
-
-	if (length <= 0)
-		return NULL;
-
-	/* Search from given start addr for the requested length  */
-
-	offset = 0;
-
-	while (offset < length) {
-		/* The signature must match and the checksum must be correct */
-		if (strncmp(address, RSDP_SIG, sizeof(RSDP_SIG) - 1) == 0 &&
-		    acpi_checksum(address, RSDP_CHECKSUM_LENGTH) == 0) {
-			/* If so, we have found the RSDP */
-			printk(KERN_INFO "ACPI: RSDP located at physical address %p\n",
-			       address);
-			return address;
-		}
-		offset += RSDP_SCAN_STEP;
-		address += RSDP_SCAN_STEP;
-	}
-
-	/* Searched entire block, no RSDP was found */
-	dprintk(KERN_INFO "ACPI: Searched entire block 0x%x:0x%x, no RSDP was found.\n",
-		(int)address, (int)address + length);
-	return NULL;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_find_root_pointer
- *
- * PARAMETERS:  none
- *
- * RETURN:      physical address of the RSDP 
- *
- * DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor
- *              pointer structure.  If it is found, set *RSDP to point to it.
- *
- *              NOTE: The RSDP must be either in the first 1_k of the Extended
- *              BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section
- *              5.2.2; assertion #421).
- *
- ******************************************************************************/
-
-static struct acpi_table_rsdp * __init
-acpi_find_root_pointer(void)
-{
-	struct acpi_table_rsdp * rsdp;
-
-	/*
-	 * Physical address is given
-	 */
-	/*
-	 * Region 1) Search EBDA (low memory) paragraphs
-	 */
-	rsdp = acpi_tb_scan_memory_for_rsdp(__va(LO_RSDP_WINDOW_BASE),
-					 LO_RSDP_WINDOW_SIZE);
-
-	if (rsdp)
-		return rsdp;
-
-	/*
-	 * Region 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
-	 */
-	rsdp = acpi_tb_scan_memory_for_rsdp(__va(HI_RSDP_WINDOW_BASE),
-					       HI_RSDP_WINDOW_SIZE);
-
-	
-					     
-	if (rsdp)
-		return rsdp;
-
-	printk(KERN_ERR "ACPI: System description tables not found\n");
-	return NULL;
-}
-
-
-/*
- * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
- * to map the target physical address. The problem is that set_fixmap()
- * provides a single page, and it is possible that the page is not
- * sufficient.
- * By using this area, we can map up to MAX_IO_APICS pages temporarily,
- * i.e. until the next __va_range() call.
- *
- * Important Safety Note:  The fixed I/O APIC page numbers are *subtracted*
- * from the fixed base.  That's why we start at FIX_IO_APIC_BASE_END and
- * count idx down while incrementing the phys address.
- */
-static __init char *
-__va_range(unsigned long phys, unsigned long size)
-{
-	unsigned long base, offset, mapped_size;
-	int idx;
-
-	offset = phys & (PAGE_SIZE - 1);
-	mapped_size = PAGE_SIZE - offset;
-	set_fixmap(FIX_IO_APIC_BASE_END, phys);
-	base = fix_to_virt(FIX_IO_APIC_BASE_END);
-	dprintk("__va_range(0x%lx, 0x%lx): idx=%d mapped at %lx\n", phys, size,
-		FIX_IO_APIC_BASE_END, base);
-
-	/*
-	 * Most cases can be covered by the below.
-	 */
-	idx = FIX_IO_APIC_BASE_END;
-	while (mapped_size < size) {
-		if (--idx < FIX_IO_APIC_BASE_0)
-			return 0;	/* cannot handle this */
-		phys += PAGE_SIZE;
-		set_fixmap(idx, phys);
-		mapped_size += PAGE_SIZE;
-	}
-
-	return ((unsigned char *) base + offset);
-}
-
-static int __init acpi_tables_init(void)
-{
-	int result = -ENODEV;
-	acpi_table_header *header = NULL;
-	struct acpi_table_rsdp *rsdp = NULL;
-	struct acpi_table_rsdt *rsdt = NULL;
-	struct acpi_table_rsdt saved_rsdt;
-	int tables = 0;
-	int type = 0;
-	int i = 0;
-
-
-	rsdp = (struct acpi_table_rsdp *) acpi_find_root_pointer();
-
-	if (!rsdp)
-		return -ENODEV;
-		
-	printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision,
-	       rsdp->oem_id);
-	       
-	if (strncmp(rsdp->signature, RSDP_SIG,strlen(RSDP_SIG))) {
-		printk(KERN_WARNING "RSDP table signature incorrect\n");
-		return -EINVAL;
-	}
-
-	rsdt = (struct acpi_table_rsdt *)
-	    __va_range(rsdp->rsdt_address, sizeof(struct acpi_table_rsdt));
-
-	if (!rsdt) {
-		printk(KERN_WARNING "ACPI: Invalid root system description tables (RSDT)\n");
-		return -ENODEV;
-	}
-	
-	header = & rsdt->header;
-	acpi_print_table_header(header);
-	
-	if (strncmp(header->signature, RSDT_SIG, strlen(RSDT_SIG))) {
-		printk(KERN_WARNING "ACPI: RSDT signature incorrect\n");
-		return -ENODEV;
-	}
-		
-	/* 
-	 * The number of tables is computed by taking the 
-	 * size of all entries (header size minus total 
-	 * size of RSDT) divided by the size of each entry
-	 * (4-byte table pointers).
-	 */
-	tables = (header->length - sizeof(acpi_table_header)) / 4;
-		    
-	memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt));
-
-	if (saved_rsdt.header.length > sizeof(saved_rsdt)) {
-		printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n", saved_rsdt.header.length);
-		return -ENODEV;
-	}
-
-	for (i = 0; i < tables; i++) {
-		/* Map in header, then map in full table length. */
-		header = (acpi_table_header *)
-			    __va_range(saved_rsdt.entry[i],
-				       sizeof(acpi_table_header));
-		if (!header)
-			break;
-		header = (acpi_table_header *)
-			    __va_range(saved_rsdt.entry[i], header->length);
-		if (!header)
-			break;
-
-		acpi_print_table_header(header);
-		
-		if (acpi_checksum(header,header->length)) {
-			printk(KERN_WARNING "ACPI %s has invalid checksum\n", 
-				acpi_table_signatures[i]);
-			continue;
-		}
-		
-		for (type = 0; type < ACPI_TABLE_COUNT; type++)
-			if (!strncmp((char *) &header->signature,
-			     acpi_table_signatures[type],strlen(acpi_table_signatures[type])))
-				break;
-
-		if (type >= ACPI_TABLE_COUNT) {
-			printk(KERN_WARNING "ACPI: Unsupported table %.4s\n",
-			       header->signature);
-			continue;
-		}
-
-
-		if (!acpi_boot_ops[type])
-			continue;
-			
-		result = acpi_boot_ops[type] (header,
-						 (unsigned long) saved_rsdt.
-						 entry[i]);
-	}
-
-	return result;
-}
-
-static int total_cpus __initdata = 0;
-int have_acpi_tables;
-
-extern void __init MP_processor_info(struct mpc_config_processor *);
-
-static void __init
-acpi_parse_lapic(struct acpi_table_lapic *local_apic)
-{
-	struct mpc_config_processor proc_entry;
-	int ix = 0;
-
-	if (!local_apic)
-		return;
-
-	printk(KERN_INFO "LAPIC (acpi_id[0x%04x] id[0x%x] enabled[%d])\n",
-		local_apic->acpi_id, local_apic->id, local_apic->flags.enabled);
-
-	printk(KERN_INFO "CPU %d (0x%02x00)", total_cpus, local_apic->id);
-
-	if (local_apic->flags.enabled) {
-		printk(" enabled\n");
-		ix = local_apic->id;
-		if (ix >= MAX_APICS) {
-			printk(KERN_WARNING
-			       "Processor #%d INVALID - (Max ID: %d).\n", ix,
-			       MAX_APICS);
-			return;
-		}
-		/* 
-		 * Fill in the info we want to save.  Not concerned about 
-		 * the processor ID.  Processor features aren't present in 
-		 * the table.
-		 */
-		proc_entry.mpc_type = MP_PROCESSOR;
-		proc_entry.mpc_apicid = local_apic->id;
-		proc_entry.mpc_cpuflag = CPU_ENABLED;
-		if (proc_entry.mpc_apicid == boot_cpu_physical_apicid) {
-			printk(" (BSP)");
-			proc_entry.mpc_cpuflag |= CPU_BOOTPROCESSOR;
-		}
-		proc_entry.mpc_cpufeature =
-		    (boot_cpu_data.x86 << 8) | 
-		    (boot_cpu_data.x86_model << 4) | 
-		     boot_cpu_data.x86_mask;
-		proc_entry.mpc_featureflag = boot_cpu_data.x86_capability[0];
-		proc_entry.mpc_reserved[0] = 0;
-		proc_entry.mpc_reserved[1] = 0;
-		proc_entry.mpc_apicver = 0x10;	/* integrated APIC */
-		MP_processor_info(&proc_entry);
-	} else {
-		printk(" disabled\n");
-	}
-
-	total_cpus++;
-	return;
-}
-
-static void __init
-acpi_parse_ioapic(struct acpi_table_ioapic *ioapic)
-{
-
-	if (!ioapic)
-		return;
-
-	printk(KERN_INFO
-	       "IOAPIC (id[0x%x] address[0x%x] global_irq_base[0x%x])\n",
-	       ioapic->id, ioapic->address, ioapic->global_irq_base);
-
-	if (nr_ioapics >= MAX_IO_APICS) {
-		printk(KERN_WARNING
-		       "Max # of I/O APICs (%d) exceeded (found %d).\n",
-		       MAX_IO_APICS, nr_ioapics);
-/*		panic("Recompile kernel with bigger MAX_IO_APICS!\n");   */
-	}
-}
-
-
-/* Interrupt source overrides inform the machine about exceptions
-   to the normal "PIC" mode interrupt routing */
-   
-static void __init
-acpi_parse_int_src_ovr(struct acpi_table_int_src_ovr *intsrc)
-{
-	if (!intsrc)
-		return;
-
-	printk(KERN_INFO
-	       "INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])\n",
-	       intsrc->bus, intsrc->bus_irq, intsrc->global_irq,
-	       intsrc->flags.polarity, intsrc->flags.trigger);
-}
-
-/*
- * At this point, we look at the interrupt assignment entries in the MPS
- * table.
- */ 
- 
-static void __init acpi_parse_nmi_src(struct acpi_table_nmi_src *nmisrc)
-{
-	if (!nmisrc)
-		return;
-
-	printk(KERN_INFO
-	       "NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])\n",
-	       nmisrc->flags.polarity, nmisrc->flags.trigger,
-	       nmisrc->global_irq);
-
-}
-static void __init
-acpi_parse_lapic_nmi(struct acpi_table_lapic_nmi *localnmi)
-{
-	if (!localnmi)
-		return;
-
-	printk(KERN_INFO
-	       "LAPIC_NMI (acpi_id[0x%04x] polarity[0x%x] trigger[0x%x] lint[0x%x])\n",
-	       localnmi->acpi_id, localnmi->flags.polarity,
-	       localnmi->flags.trigger, localnmi->lint);
-}
-static void __init
-acpi_parse_lapic_addr_ovr(struct acpi_table_lapic_addr_ovr *lapic_addr_ovr)
-{
-	if (!lapic_addr_ovr)
-		return;
-
-	printk(KERN_INFO "LAPIC_ADDR_OVR (address[0x%lx])\n",
-	       (unsigned long) lapic_addr_ovr->address);
-
-}
-
-static void __init
-acpi_parse_plat_int_src(struct acpi_table_plat_int_src *plintsrc)
-{
-	if (!plintsrc)
-		return;
-
-	printk(KERN_INFO
-	       "PLAT_INT_SRC (polarity[0x%x] trigger[0x%x] type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
-	       plintsrc->flags.polarity, plintsrc->flags.trigger,
-	       plintsrc->type, plintsrc->id, plintsrc->eid,
-	       plintsrc->iosapic_vector, plintsrc->global_irq);
-}
-static int __init
-acpi_parse_madt(acpi_table_header * header, unsigned long phys)
-{
-
-	struct acpi_table_madt *madt;	    
-	acpi_madt_entry_header *entry_header;
-	int table_size;
-	
-	madt = (struct acpi_table_madt *) __va_range(phys, header->length);
-
-	if (!madt)
-		return -EINVAL;
-
-	table_size = (int) (header->length - sizeof(*madt));
-	entry_header =
-	    (acpi_madt_entry_header *) ((void *) madt + sizeof(*madt));
-
-	while (entry_header && (table_size > 0)) {
-		switch (entry_header->type) {
-		case ACPI_MADT_LAPIC:
-			acpi_parse_lapic((struct acpi_table_lapic *)
-					 entry_header);
-			break;
-		case ACPI_MADT_IOAPIC:
-			acpi_parse_ioapic((struct acpi_table_ioapic *)
-					  entry_header);
-			break;
-		case ACPI_MADT_INT_SRC_OVR:
-			acpi_parse_int_src_ovr((struct acpi_table_int_src_ovr *)
-					       entry_header);
-			break;
-		case ACPI_MADT_NMI_SRC:
-			acpi_parse_nmi_src((struct acpi_table_nmi_src *)
-					   entry_header);
-			break;
-		case ACPI_MADT_LAPIC_NMI:
-			acpi_parse_lapic_nmi((struct acpi_table_lapic_nmi *)
-					     entry_header);
-			break;
-		case ACPI_MADT_LAPIC_ADDR_OVR:
-			acpi_parse_lapic_addr_ovr((struct
-						   acpi_table_lapic_addr_ovr *)
-						  entry_header);
-			break;
-		case ACPI_MADT_PLAT_INT_SRC:
-			acpi_parse_plat_int_src((struct acpi_table_plat_int_src
-						 *) entry_header);
-			break;
-		default:
-			printk(KERN_WARNING
-			       "Unsupported MADT entry type 0x%x\n",
-			       entry_header->type);
-			break;
-		}
-		table_size -= entry_header->length;
-		entry_header =
-		    (acpi_madt_entry_header *) ((void *) entry_header +
-						entry_header->length);
-	}
-
-	if (!total_cpus) {
-		printk("ACPI: No Processors found in the APCI table.\n");
-		return -EINVAL;
-	}
-
-	printk(KERN_INFO "%d CPUs total\n", total_cpus);
-
-	if (madt->lapic_address)
-		mp_lapic_addr = madt->lapic_address;
-	else
-		mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-
-	printk(KERN_INFO "Local APIC address %x\n", madt->lapic_address);
-
-	return 0;
-}
-
-
-/*
- * Configure the processor info using MADT in the ACPI tables. If we fail to
- * configure that, then we use the MPS tables.
- */
-void __init
-acpi_boot_init(void)
-{
-
-	memset(&acpi_boot_ops, 0, sizeof(acpi_boot_ops));
-	acpi_boot_ops[ACPI_APIC] = acpi_parse_madt;
-
-	/*
-	 * Only do this when requested, either because of CPU/Bios type or from the command line
-	 */
-
-	if (!acpi_tables_init())
-		acpi_lapic = 1;
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/acpitable.h linux-2.4.23-pre8/arch/i386/kernel/acpitable.h
--- linux-2.4.22/arch/i386/kernel/acpitable.h	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/acpitable.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,262 +0,0 @@
-/*
- *  acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1)
- *
- *  Copyright (C) 1999 Andrew Henroid
- *  Copyright (C) 2001 Richard Schaal
- *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
- *  Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * $Id: acpitable.h,v 1.3 2001/11/03 22:41:34 fenrus Exp $
- */
-
-/*
- * The following codes are cut&pasted from drivers/acpi. Part of the code
- * there can be not updated or delivered yet.
- * To avoid conflicts when CONFIG_ACPI is defined, the following codes are
- * modified so that they are self-contained in this file.
- * -- jun
- */
- 
-#ifndef _HEADER_ACPITABLE_H_
-#define _HEADER_ACPITABLE_H_
-
-//#define dprintk(s, args...) printk(s, ## args)
-#define dprintk(s, args...)
-
-typedef unsigned int ACPI_TBLPTR;
-
-typedef struct {		/* ACPI common table header */
-	char signature[4];	/* identifies type of table */
-	u32 length;		/* length of table,
-				   in bytes, * including header */
-	u8 revision;		/* specification minor version # */
-	u8 checksum;		/* to make sum of entire table == 0 */
-	char oem_id[6];		/* OEM identification */
-	char oem_table_id[8];	/* OEM table identification */
-	u32 oem_revision;	/* OEM revision number */
-	char asl_compiler_id[4];	/* ASL compiler vendor ID */
-	u32 asl_compiler_revision;	/* ASL compiler revision number */
-} acpi_table_header __attribute__ ((packed));;
-
-enum {
-	ACPI_APIC = 0,
-	ACPI_BOOT,
-	ACPI_DBGP,
-	ACPI_DSDT,
-	ACPI_ECDT,
-	ACPI_ETDT,
-	ACPI_FACP,
-	ACPI_FACS,
-	ACPI_OEMX,
-	ACPI_PSDT,
-	ACPI_SBST,
-	ACPI_SLIT,
-	ACPI_SPCR,
-	ACPI_SRAT,
-	ACPI_SSDT,
-	ACPI_SPMI,
-	ACPI_XSDT,
-	ACPI_TABLE_COUNT
-};
-
-static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
-	"APIC",
-	"BOOT",
-	"DBGP",
-	"DSDT",
-	"ECDT",
-	"ETDT",
-	"FACP",
-	"FACS",
-	"OEM",
-	"PSDT",
-	"SBST",
-	"SLIT",
-	"SPCR",
-	"SRAT",
-	"SSDT",
-	"SPMI",
-	"XSDT"
-};
-
-struct acpi_table_madt {
-	acpi_table_header header;
-	u32 lapic_address;
-	struct {
-		u32 pcat_compat:1;
-		u32 reserved:31;
-	} flags __attribute__ ((packed));
-} __attribute__ ((packed));;
-
-enum {
-	ACPI_MADT_LAPIC = 0,
-	ACPI_MADT_IOAPIC,
-	ACPI_MADT_INT_SRC_OVR,
-	ACPI_MADT_NMI_SRC,
-	ACPI_MADT_LAPIC_NMI,
-	ACPI_MADT_LAPIC_ADDR_OVR,
-	ACPI_MADT_IOSAPIC,
-	ACPI_MADT_LSAPIC,
-	ACPI_MADT_PLAT_INT_SRC,
-	ACPI_MADT_ENTRY_COUNT
-};
-
-#define RSDP_SIG			"RSD PTR "
-#define RSDT_SIG 			"RSDT"
-
-#define ACPI_DEBUG_PRINT(pl)
-
-#define ACPI_MEMORY_MODE                0x01
-#define ACPI_LOGICAL_ADDRESSING         0x00
-#define ACPI_PHYSICAL_ADDRESSING        0x01
-
-#define LO_RSDP_WINDOW_BASE         	0	/* Physical Address */
-#define HI_RSDP_WINDOW_BASE         	0xE0000	/* Physical Address */
-#define LO_RSDP_WINDOW_SIZE         	0x400
-#define HI_RSDP_WINDOW_SIZE         	0x20000
-#define RSDP_SCAN_STEP			16
-#define RSDP_CHECKSUM_LENGTH		20
-
-typedef int (*acpi_table_handler) (acpi_table_header * header, unsigned long);
-
-struct acpi_table_rsdp {
-	char signature[8];
-	u8 checksum;
-	char oem_id[6];
-	u8 revision;
-	u32 rsdt_address;
-} __attribute__ ((packed));
-
-struct acpi_table_rsdt {
-	acpi_table_header header;
-	u32 entry[ACPI_TABLE_COUNT];
-} __attribute__ ((packed));
-
-typedef struct {
-	u8 type;
-	u8 length;
-} acpi_madt_entry_header __attribute__ ((packed));
-
-typedef struct {
-	u16 polarity:2;
-	u16 trigger:2;
-	u16 reserved:12;
-} acpi_madt_int_flags __attribute__ ((packed));
-
-struct acpi_table_lapic {
-	acpi_madt_entry_header header;
-	u8 acpi_id;
-	u8 id;
-	struct {
-		u32 enabled:1;
-		u32 reserved:31;
-	} flags __attribute__ ((packed));
-} __attribute__ ((packed));
-
-struct acpi_table_ioapic {
-	acpi_madt_entry_header header;
-	u8 id;
-	u8 reserved;
-	u32 address;
-	u32 global_irq_base;
-} __attribute__ ((packed));
-
-struct acpi_table_int_src_ovr {
-	acpi_madt_entry_header header;
-	u8 bus;
-	u8 bus_irq;
-	u32 global_irq;
-	acpi_madt_int_flags flags;
-} __attribute__ ((packed));
-
-struct acpi_table_nmi_src {
-	acpi_madt_entry_header header;
-	acpi_madt_int_flags flags;
-	u32 global_irq;
-} __attribute__ ((packed));
-
-struct acpi_table_lapic_nmi {
-	acpi_madt_entry_header header;
-	u8 acpi_id;
-	acpi_madt_int_flags flags;
-	u8 lint;
-} __attribute__ ((packed));
-
-struct acpi_table_lapic_addr_ovr {
-	acpi_madt_entry_header header;
-	u8 reserved[2];
-	u64 address;
-} __attribute__ ((packed));
-
-struct acpi_table_iosapic {
-	acpi_madt_entry_header header;
-	u8 id;
-	u8 reserved;
-	u32 global_irq_base;
-	u64 address;
-} __attribute__ ((packed));
-
-struct acpi_table_lsapic {
-	acpi_madt_entry_header header;
-	u8 acpi_id;
-	u8 id;
-	u8 eid;
-	u8 reserved[3];
-	struct {
-		u32 enabled:1;
-		u32 reserved:31;
-	} flags;
-} __attribute__ ((packed));
-
-struct acpi_table_plat_int_src {
-	acpi_madt_entry_header header;
-	acpi_madt_int_flags flags;
-	u8 type;
-	u8 id;
-	u8 eid;
-	u8 iosapic_vector;
-	u32 global_irq;
-	u32 reserved;
-} __attribute__ ((packed));
-
-/*
- * ACPI Table Descriptor.  One per ACPI table
- */
-typedef struct acpi_table_desc {
-	struct acpi_table_desc *prev;
-	struct acpi_table_desc *next;
-	struct acpi_table_desc *installed_desc;
-	acpi_table_header *pointer;
-	void *base_pointer;
-	u8 *aml_pointer;
-	u64 physical_address;
-	u32 aml_length;
-	u32 length;
-	u32 count;
-	u16 table_id;
-	u8 type;
-	u8 allocation;
-	u8 loaded_into_namespace;
-
-} acpi_table_desc __attribute__ ((packed));;
-
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/apic.c linux-2.4.23-pre8/arch/i386/kernel/apic.c
--- linux-2.4.22/arch/i386/kernel/apic.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/apic.c	2003-10-22 22:49:54.000000000 +0000
@@ -38,6 +38,8 @@
 int prof_old_multiplier[NR_CPUS] = { 1, };
 int prof_counter[NR_CPUS] = { 1, };
 
+static int enabled_via_apicbase;
+
 int get_maxlvt(void)
 {
 	unsigned int v, ver, maxlvt;
@@ -142,6 +144,13 @@
 	value = apic_read(APIC_SPIV);
 	value &= ~APIC_SPIV_APIC_ENABLED;
 	apic_write_around(APIC_SPIV, value);
+
+	if (enabled_via_apicbase) {
+		unsigned int l, h;
+		rdmsr(MSR_IA32_APICBASE, l, h);
+		l &= ~MSR_IA32_APICBASE_ENABLE;
+		wrmsr(MSR_IA32_APICBASE, l, h);
+	}
 }
 
 /*
@@ -464,7 +473,6 @@
 
 static void apic_pm_suspend(void *data)
 {
-	unsigned int l, h;
 	unsigned long flags;
 
 	if (apic_pm_state.perfctr_pmdev)
@@ -484,9 +492,6 @@
 	__save_flags(flags);
 	__cli();
 	disable_local_APIC();
-	rdmsr(MSR_IA32_APICBASE, l, h);
-	l &= ~MSR_IA32_APICBASE_ENABLE;
-	wrmsr(MSR_IA32_APICBASE, l, h);
 	__restore_flags(flags);
 }
 
@@ -497,10 +502,18 @@
 
 	__save_flags(flags);
 	__cli();
+
+	/*
+	 * Make sure the APICBASE points to the right address
+	 *
+	 * FIXME! This will be wrong if we ever support suspend on
+	 * SMP! We'll need to do this as part of the CPU restore!
+	 */
 	rdmsr(MSR_IA32_APICBASE, l, h);
 	l &= ~MSR_IA32_APICBASE_BASE;
-	l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
+	l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr;
 	wrmsr(MSR_IA32_APICBASE, l, h);
+
 	apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
 	apic_write(APIC_ID, apic_pm_state.apic_id);
 	apic_write(APIC_DFR, apic_pm_state.apic_dfr);
@@ -593,7 +606,26 @@
  * Detect and enable local APICs on non-SMP boards.
  * Original code written by Keir Fraser.
  */
-int dont_enable_local_apic __initdata = 0;
+
+/*
+ * Knob to control our willingness to enable the local APIC.
+ */
+int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
+
+static int __init lapic_disable(char *str)
+{
+	enable_local_apic = -1;
+	clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+	return 0;
+}
+__setup("nolapic", lapic_disable);
+
+static int __init lapic_enable(char *str)
+{
+	enable_local_apic = 1;
+	return 0;
+}
+__setup("lapic", lapic_enable);
 
 static int __init detect_init_APIC (void)
 {
@@ -601,7 +633,7 @@
 	extern void get_cpu_vendor(struct cpuinfo_x86*);
 
 	/* Disabled by DMI scan or kernel option? */
-	if (dont_enable_local_apic)
+	if (enable_local_apic < 0)
 		return -1;
 
 	/* Workaround for us being called before identify_cpu(). */
@@ -616,7 +648,7 @@
 		goto no_apic;
 	case X86_VENDOR_INTEL:
 		if (boot_cpu_data.x86 == 6 ||
-		    (boot_cpu_data.x86 == 15 && cpu_has_apic) ||
+		    (boot_cpu_data.x86 == 15 && (cpu_has_apic || enable_local_apic > 0)) ||
 		    (boot_cpu_data.x86 == 5 && cpu_has_apic))
 			break;
 		goto no_apic;
@@ -636,6 +668,7 @@
 			l &= ~MSR_IA32_APICBASE_BASE;
 			l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
 			wrmsr(MSR_IA32_APICBASE, l, h);
+			enabled_via_apicbase = 1;
 		}
 	}
 	/*
@@ -649,6 +682,12 @@
 	}
 	set_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability);
 	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
+
+	/* The BIOS may have set up the APIC at some other address */
+	rdmsr(MSR_IA32_APICBASE, l, h);
+	if (l & MSR_IA32_APICBASE_ENABLE)
+		mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
+
 	if (nmi_watchdog != NMI_NONE)
 		nmi_watchdog = NMI_LOCAL_APIC;
 
@@ -928,14 +967,8 @@
 
 static unsigned int calibration_result;
 
-int dont_use_local_apic_timer __initdata = 0;
-
 void __init setup_APIC_clocks (void)
 {
-	/* Disabled by DMI scan or kernel option? */
-	if (dont_use_local_apic_timer)
-		return;
-
 	printk("Using local APIC timer interrupts.\n");
 	using_apic_timer = 1;
 
@@ -1152,6 +1185,9 @@
  */
 int __init APIC_init_uniprocessor (void)
 {
+	if (enable_local_apic < 0)
+		clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+
 	if (!smp_found_config && !cpu_has_apic)
 		return -1;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/dmi_scan.c linux-2.4.23-pre8/arch/i386/kernel/dmi_scan.c
--- linux-2.4.22/arch/i386/kernel/dmi_scan.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/dmi_scan.c	2003-10-22 22:48:31.000000000 +0000
@@ -335,9 +335,9 @@
 static int __init local_apic_kills_bios(struct dmi_blacklist *d)
 {
 #ifdef CONFIG_X86_LOCAL_APIC
-	extern int dont_enable_local_apic;
-	if (!dont_enable_local_apic) {
-		dont_enable_local_apic = 1;
+	extern int enable_local_apic;
+	if (enable_local_apic == 0) {
+		enable_local_apic = -1;
 		printk(KERN_WARNING "%s with broken BIOS detected. "
 		       "Refusing to enable the local APIC.\n",
 		       d->ident);
@@ -347,43 +347,6 @@
 }
 
 /*
- * The Microstar 6163-2 (a.k.a Pro) mainboard will hang shortly after
- * resumes, and also at what appears to be asynchronous APM events,
- * if the local APIC is enabled.
- */
-static int __init apm_kills_local_apic(struct dmi_blacklist *d)
-{
-#ifdef CONFIG_X86_LOCAL_APIC
-	extern int dont_enable_local_apic;
-	if (apm_info.bios.version && !dont_enable_local_apic) {
-		dont_enable_local_apic = 1;
-		printk(KERN_WARNING "%s with broken BIOS detected. "
-		       "Refusing to enable the local APIC.\n",
-		       d->ident);
-	}
-#endif
-	return 0;
-}
-
-/*
- * The Intel AL440LX mainboard will hang randomly if the local APIC
- * timer is running and the APM BIOS hasn't been disabled.
- */
-static int __init apm_kills_local_apic_timer(struct dmi_blacklist *d)
-{
-#ifdef CONFIG_X86_LOCAL_APIC
-	extern int dont_use_local_apic_timer;
-	if (apm_info.bios.version && !dont_use_local_apic_timer) {
-		dont_use_local_apic_timer = 1;
-		printk(KERN_WARNING "%s with broken BIOS detected. "
-		       "The local APIC timer will not be used.\n",
-		       d->ident);
-	}
-#endif
-	return 0;
-}
-
-/*
  *  Check for clue free BIOS implementations who use
  *  the following QA technique
  *
@@ -437,37 +400,6 @@
 }
 
 /*
- * The Intel 440GX hall of shame. 
- *
- * On many (all we have checked) of these boxes the $PIRQ table is wrong.
- * The MP1.4 table is right however and so SMP kernels tend to work. 
- */
- 
-#ifdef CONFIG_PCI
-extern int broken_440gx_bios;
-extern unsigned int pci_probe;
-#endif
-static __init int broken_pirq(struct dmi_blacklist *d)
-{
-	printk(KERN_INFO " *** Possibly defective BIOS detected (irqtable)\n");
-	printk(KERN_INFO " *** Many BIOSes matching this signature have incorrect IRQ routing tables.\n");
-	printk(KERN_INFO " *** If you see IRQ problems, in paticular SCSI resets and hangs at boot\n");
-	printk(KERN_INFO " *** contact your hardware vendor and ask about updates.\n");
-	printk(KERN_INFO " *** Building an SMP kernel may evade the bug some of the time.\n");
-#ifdef CONFIG_X86_IO_APIC
-	{
-		extern int skip_ioapic_setup; 
-		skip_ioapic_setup = 0;
-	}
-#endif
-#ifdef CONFIG_PCI
-	broken_440gx_bios = 1;
-	pci_probe |= PCI_BIOS_IRQ_SCAN;
-#endif
-	return 0;
-}
-
-/*
  * ASUS K7V-RM has broken ACPI table defining sleep modes
  */
 
@@ -549,7 +481,7 @@
 
 
 #ifdef	CONFIG_ACPI_BOOT
-extern int acpi_disabled, use_acpi_pci, acpi_force, acpi_ht;
+extern int acpi_disabled, acpi_force, acpi_ht;
 
 static __init __attribute__((unused)) int acpi_disable(struct dmi_blacklist *d) 
 { 
@@ -579,14 +511,18 @@
 	}
 	return 0;
 } 
+#endif	/* CONFIG_ACPI_BOOT */
 
+#ifdef	CONFIG_ACPI_PCI
 static __init int disable_acpi_pci(struct dmi_blacklist *d) 
 { 
-	printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident); 	
-	use_acpi_pci = 0; 
+	extern __init void pci_disable_acpi(void) ;
+
+	printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident);
+	pci_disable_acpi();
 	return 0;
 } 
-#endif
+#endif	/* CONFIG_ACPI_PCI */
 
 /*
  *	Process the DMI blacklists
@@ -861,87 +797,17 @@
 			NO_MATCH, NO_MATCH
 			} },
 
-	{ apm_kills_local_apic, "Microstar 6163", {
-			MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
-			MATCH(DMI_BOARD_NAME, "MS-6163"),
-			NO_MATCH, NO_MATCH } },
-
-	{ apm_kills_local_apic_timer, "Intel AL440LX", {
-			MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BOARD_NAME, "AL440LX"),
-			NO_MATCH, NO_MATCH } },
-
-	/* Problem Intel 440GX bioses */
-
-	{ broken_pirq, "SABR1 Bios", {			/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"SABR1"),
-			NO_MATCH, NO_MATCH
-			} },
-	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0066.P07"),
-			NO_MATCH, NO_MATCH
-                        } },
-	{ broken_pirq, "IBM xseries 370", {        		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "IBM"),
-			MATCH(DMI_BIOS_VERSION,"MMKT33AUS"),
-			NO_MATCH, NO_MATCH
-                        } },
-	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0094.P10"),
-			NO_MATCH, NO_MATCH
-                        } },
-	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0115.P12"),
-			NO_MATCH, NO_MATCH
-                        } },
-	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0120.P12"),
-			NO_MATCH, NO_MATCH
-                        } },
-	{ broken_pirq, "l44GX Bios", {		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0125.P13"),
-			NO_MATCH, NO_MATCH
-			} },
-	{ broken_pirq, "l44GX Bios", {		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"C440GX0.86B"),
-			NO_MATCH, NO_MATCH
-			} },
-	{ broken_pirq, "l44GX Bios", {		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0133.P14"),
-			NO_MATCH, NO_MATCH
-			} },
-	{ broken_pirq, "l44GX Bios", {		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0"),
-			NO_MATCH, NO_MATCH
-			} },
-                        
-	/* Intel in disgiuse - In this case they can't hide and they don't run
-	   too well either... */
-	{ broken_pirq, "Dell PowerEdge 8450", {		/* Bad $PIR */
-			MATCH(DMI_PRODUCT_NAME, "Dell PowerEdge 8450"),
+	{ init_ints_after_s1, "Toshiba Satellite 4030cdt", { /* Reinitialization of 8259 is needed after S1 resume */
+			MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
 			NO_MATCH, NO_MATCH, NO_MATCH
 			} },
-			
+
 	{ broken_acpi_Sx, "ASUS K7V-RM", {		/* Bad ACPI Sx table */
 			MATCH(DMI_BIOS_VERSION,"ASUS K7V-RM ACPI BIOS Revision 1003A"),
 			MATCH(DMI_BOARD_NAME, "<K7V-RM>"),
 			NO_MATCH, NO_MATCH
 			} },
 			
-	{ init_ints_after_s1, "Toshiba Satellite 4030cdt", { /* Reinitialization of 8259 is needed after S1 resume */
-			MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
-			NO_MATCH, NO_MATCH, NO_MATCH
-			} },
-
 	{ print_if_true, KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.", {
 			MATCH(DMI_SYS_VENDOR, "IBM"),
 			MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"),
@@ -1033,11 +899,6 @@
 			MATCH(DMI_BOARD_NAME, "CUR-DLS"),
 			NO_MATCH, NO_MATCH }},
 
-	{ force_acpi_ht, "ASUS A7V", {
-			MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
-			MATCH(DMI_BOARD_NAME, "<A7V>"),
-			MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1011"), NO_MATCH }},
-
 	{ force_acpi_ht, "ABIT i440BX-W83977", {
 			MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
 			MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
@@ -1063,6 +924,8 @@
 			MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
 			NO_MATCH, NO_MATCH }},
 
+#endif	/* CONFIG_ACPI_BOOT */
+#ifdef	CONFIG_ACPI_PCI
 	/*
 	 *	Boxes that need ACPI PCI IRQ routing disabled
 	 */
@@ -1070,8 +933,10 @@
 	{ disable_acpi_pci, "ASUS A7V", {
 			MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
 			MATCH(DMI_BOARD_NAME, "<A7V>"),
-			MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"), NO_MATCH }},
-#endif	// CONFIG_ACPI_BOOT
+			/* newer BIOS, Revision 1011, does work */
+			MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
+			NO_MATCH }},
+#endif	/* CONFIG_ACPI_PCI */
 
 	{ NULL, }
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/edd.c linux-2.4.23-pre8/arch/i386/kernel/edd.c
--- linux-2.4.22/arch/i386/kernel/edd.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/edd.c	2003-10-22 22:47:59.000000000 +0000
@@ -0,0 +1,672 @@
+/*
+ * linux/arch/i386/kernel/edd.c
+ *  Copyright (C) 2002 Dell Computer Corporation
+ *  by Matt Domsch <Matt_Domsch@dell.com>
+ *
+ * BIOS Enhanced Disk Drive Services (EDD)
+ * conformant to T13 Committee www.t13.org
+ *   projects 1572D, 1484D, 1386D, 1226DT
+ *
+ * This code takes information provided by BIOS EDD calls
+ * fn41 - Check Extensions Present and
+ * fn48 - Get Device Parametes with EDD extensions
+ * made in setup.S, copied to safe structures in setup.c,
+ * and presents it in /proc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2.0 as published by
+ * the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*
+ * TODO:
+ * - move edd.[ch] to better locations if/when one is decided
+ * - keep current with 2.5 EDD code changes
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/stat.h>
+#include <linux/ctype.h>
+#include <linux/slab.h>
+#include <linux/limits.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <asm/edd.h>
+
+MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
+MODULE_DESCRIPTION("proc interface to BIOS EDD information");
+MODULE_LICENSE("GPL");
+
+#define EDD_VERSION "0.09 2003-Jan-21"
+#define EDD_DEVICE_NAME_SIZE 16
+#define REPORT_URL "http://domsch.com/linux/edd30/results.html"
+
+#define left (count - (p - page) - 1)
+
+static struct proc_dir_entry *bios_dir;
+
+struct attr_entry {
+	struct proc_dir_entry *entry;
+	struct list_head node;
+};
+
+struct edd_device {
+	char name[EDD_DEVICE_NAME_SIZE];
+	struct edd_info *info;
+	struct proc_dir_entry *dir;
+	struct list_head attr_list;
+};
+
+static struct edd_device *edd_devices[EDDMAXNR];
+
+struct edd_attribute {
+	char *name;
+	int (*show)(char *page, char **start, off_t off,
+		    int count, int *eof, void *data);
+	int (*test) (struct edd_device * edev);
+};
+
+#define EDD_DEVICE_ATTR(_name,_show,_test) \
+struct edd_attribute edd_attr_##_name = { 	\
+	.name = __stringify(_name), \
+	.show	= _show,	    \
+        .test   = _test,            \
+};
+
+static inline struct edd_info *
+edd_dev_get_info(struct edd_device *edev)
+{
+	return edev->info;
+}
+
+static inline void
+edd_dev_set_info(struct edd_device *edev, struct edd_info *info)
+{
+	edev->info = info;
+}
+
+static int
+proc_calc_metrics(char *page, char **start, off_t off,
+		  int count, int *eof, int len)
+{
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+	return len;
+}
+
+static int
+edd_dump_raw_data(char *b, int count, void *data, int length)
+{
+	char *orig_b = b;
+	char hexbuf[80], ascbuf[20], *h, *a, c;
+	unsigned char *p = data;
+	unsigned long column = 0;
+	int length_printed = 0, d;
+	const char maxcolumn = 16;
+	while (length_printed < length && count > 0) {
+		h = hexbuf;
+		a = ascbuf;
+		for (column = 0;
+		     column < maxcolumn && length_printed < length; column++) {
+			h += sprintf(h, "%02x ", (unsigned char) *p);
+			if (!isprint(*p))
+				c = '.';
+			else
+				c = *p;
+			a += sprintf(a, "%c", c);
+			p++;
+			length_printed++;
+		}
+		/* pad out the line */
+		for (; column < maxcolumn; column++) {
+			h += sprintf(h, "   ");
+			a += sprintf(a, " ");
+		}
+		d = snprintf(b, count, "%s\t%s\n", hexbuf, ascbuf);
+		b += d;
+		count -= d;
+	}
+	return (b - orig_b);
+}
+
+static int
+edd_show_host_bus(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	int i;
+
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	for (i = 0; i < 4; i++) {
+		if (isprint(info->params.host_bus_type[i])) {
+			p += snprintf(p, left, "%c", info->params.host_bus_type[i]);
+		} else {
+			p += snprintf(p, left, " ");
+		}
+	}
+
+	if (!strncmp(info->params.host_bus_type, "ISA", 3)) {
+		p += snprintf(p, left, "\tbase_address: %x\n",
+			     info->params.interface_path.isa.base_address);
+	} else if (!strncmp(info->params.host_bus_type, "PCIX", 4) ||
+		   !strncmp(info->params.host_bus_type, "PCI", 3)) {
+		p += snprintf(p, left,
+			     "\t%02x:%02x.%d  channel: %u\n",
+			     info->params.interface_path.pci.bus,
+			     info->params.interface_path.pci.slot,
+			     info->params.interface_path.pci.function,
+			     info->params.interface_path.pci.channel);
+	} else if (!strncmp(info->params.host_bus_type, "IBND", 4) ||
+		   !strncmp(info->params.host_bus_type, "XPRS", 4) ||
+		   !strncmp(info->params.host_bus_type, "HTPT", 4)) {
+		p += snprintf(p, left,
+			     "\tTBD: %llx\n",
+			     info->params.interface_path.ibnd.reserved);
+
+	} else {
+		p += snprintf(p, left, "\tunknown: %llx\n",
+			     info->params.interface_path.unknown.reserved);
+	}
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_interface(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	int i;
+
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	for (i = 0; i < 8; i++) {
+		if (isprint(info->params.interface_type[i])) {
+			p += snprintf(p, left, "%c", info->params.interface_type[i]);
+		} else {
+			p += snprintf(p, left, " ");
+		}
+	}
+	if (!strncmp(info->params.interface_type, "ATAPI", 5)) {
+		p += snprintf(p, left, "\tdevice: %u  lun: %u\n",
+			     info->params.device_path.atapi.device,
+			     info->params.device_path.atapi.lun);
+	} else if (!strncmp(info->params.interface_type, "ATA", 3)) {
+		p += snprintf(p, left, "\tdevice: %u\n",
+			     info->params.device_path.ata.device);
+	} else if (!strncmp(info->params.interface_type, "SCSI", 4)) {
+		p += snprintf(p, left, "\tid: %u  lun: %llu\n",
+			     info->params.device_path.scsi.id,
+			     info->params.device_path.scsi.lun);
+	} else if (!strncmp(info->params.interface_type, "USB", 3)) {
+		p += snprintf(p, left, "\tserial_number: %llx\n",
+			     info->params.device_path.usb.serial_number);
+	} else if (!strncmp(info->params.interface_type, "1394", 4)) {
+		p += snprintf(p, left, "\teui: %llx\n",
+			     info->params.device_path.i1394.eui);
+	} else if (!strncmp(info->params.interface_type, "FIBRE", 5)) {
+		p += snprintf(p, left, "\twwid: %llx lun: %llx\n",
+			     info->params.device_path.fibre.wwid,
+			     info->params.device_path.fibre.lun);
+	} else if (!strncmp(info->params.interface_type, "I2O", 3)) {
+		p += snprintf(p, left, "\tidentity_tag: %llx\n",
+			     info->params.device_path.i2o.identity_tag);
+	} else if (!strncmp(info->params.interface_type, "RAID", 4)) {
+		p += snprintf(p, left, "\tidentity_tag: %x\n",
+			     info->params.device_path.raid.array_number);
+	} else if (!strncmp(info->params.interface_type, "SATA", 4)) {
+		p += snprintf(p, left, "\tdevice: %u\n",
+			     info->params.device_path.sata.device);
+	} else {
+		p += snprintf(p, left, "\tunknown: %llx %llx\n",
+			     info->params.device_path.unknown.reserved1,
+			     info->params.device_path.unknown.reserved2);
+	}
+
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+/**
+ * edd_show_raw_data() - unparses EDD information, returned to user-space
+ *
+ * Returns: number of bytes written, or 0 on failure
+ */
+static int
+edd_show_raw_data(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	int i, warn_padding = 0, nonzero_path = 0,
+		len = sizeof (*info) - 4;
+	uint8_t checksum = 0, c = 0;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE))
+		len = info->params.length;
+
+	p += snprintf(p, left, "int13 fn48 returned data:\n\n");
+	p += edd_dump_raw_data(p, left, ((char *) info) + 4, len);
+
+	/* Spec violation.  Adaptec AIC7899 returns 0xDDBE
+	   here, when it should be 0xBEDD.
+	 */
+	p += snprintf(p, left, "\n");
+	if (info->params.key == 0xDDBE) {
+		p += snprintf(p, left,
+			     "Warning: Spec violation.  Key should be 0xBEDD, is 0xDDBE\n");
+	}
+
+	if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) {
+		goto out;
+	}
+
+	for (i = 30; i <= 73; i++) {
+		c = *(((uint8_t *) info) + i + 4);
+		if (c)
+			nonzero_path++;
+		checksum += c;
+	}
+
+	if (checksum) {
+		p += snprintf(p, left,
+			     "Warning: Spec violation.  Device Path checksum invalid.\n");
+	}
+
+	if (!nonzero_path) {
+		p += snprintf(p, left, "Error: Spec violation.  Empty device path.\n");
+		goto out;
+	}
+
+	for (i = 0; i < 4; i++) {
+		if (!isprint(info->params.host_bus_type[i])) {
+			warn_padding++;
+		}
+	}
+	for (i = 0; i < 8; i++) {
+		if (!isprint(info->params.interface_type[i])) {
+			warn_padding++;
+		}
+	}
+
+	if (warn_padding) {
+		p += snprintf(p, left,
+			     "Warning: Spec violation.  Padding should be 0x20.\n");
+	}
+
+out:
+	p += snprintf(p, left, "\nPlease check %s\n", REPORT_URL);
+	p += snprintf(p, left, "to see if this device has been reported.  If not,\n");
+	p += snprintf(p, left, "please send the information requested there.\n");
+
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_version(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	p += snprintf(p, left, "0x%02x\n", info->version);
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_extensions(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	if (info->interface_support & EDD_EXT_FIXED_DISK_ACCESS) {
+		p += snprintf(p, left, "Fixed disk access\n");
+	}
+	if (info->interface_support & EDD_EXT_DEVICE_LOCKING_AND_EJECTING) {
+		p += snprintf(p, left, "Device locking and ejecting\n");
+	}
+	if (info->interface_support & EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT) {
+		p += snprintf(p, left, "Enhanced Disk Drive support\n");
+	}
+	if (info->interface_support & EDD_EXT_64BIT_EXTENSIONS) {
+		p += snprintf(p, left, "64-bit extensions\n");
+	}
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_info_flags(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	if (info->params.info_flags & EDD_INFO_DMA_BOUNDRY_ERROR_TRANSPARENT)
+		p += snprintf(p, left, "DMA boundry error transparent\n");
+	if (info->params.info_flags & EDD_INFO_GEOMETRY_VALID)
+		p += snprintf(p, left, "geometry valid\n");
+	if (info->params.info_flags & EDD_INFO_REMOVABLE)
+		p += snprintf(p, left, "removable\n");
+	if (info->params.info_flags & EDD_INFO_WRITE_VERIFY)
+		p += snprintf(p, left, "write verify\n");
+	if (info->params.info_flags & EDD_INFO_MEDIA_CHANGE_NOTIFICATION)
+		p += snprintf(p, left, "media change notification\n");
+	if (info->params.info_flags & EDD_INFO_LOCKABLE)
+		p += snprintf(p, left, "lockable\n");
+	if (info->params.info_flags & EDD_INFO_NO_MEDIA_PRESENT)
+		p += snprintf(p, left, "no media present\n");
+	if (info->params.info_flags & EDD_INFO_USE_INT13_FN50)
+		p += snprintf(p, left, "use int13 fn50\n");
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_default_cylinders(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	p += snprintf(p, left, "0x%x\n", info->params.num_default_cylinders);
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_default_heads(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	p += snprintf(p, left, "0x%x\n", info->params.num_default_heads);
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_default_sectors_per_track(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	p += snprintf(p, left, "0x%x\n", info->params.sectors_per_track);
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_sectors(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	p += snprintf(p, left, "0x%llx\n", info->params.number_of_sectors);
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_has_default_cylinders(struct edd_device *edev)
+{
+	struct edd_info *info = edd_dev_get_info(edev);
+	if (!edev || !info)
+		return 0;
+	return info->params.num_default_cylinders > 0;
+}
+
+static int
+edd_has_default_heads(struct edd_device *edev)
+{
+	struct edd_info *info = edd_dev_get_info(edev);
+	if (!edev || !info)
+		return 0;
+	return info->params.num_default_heads > 0;
+}
+
+static int
+edd_has_default_sectors_per_track(struct edd_device *edev)
+{
+	struct edd_info *info = edd_dev_get_info(edev);
+	if (!edev || !info)
+		return 0;
+	return info->params.sectors_per_track > 0;
+}
+
+static int
+edd_has_edd30(struct edd_device *edev)
+{
+	struct edd_info *info = edd_dev_get_info(edev);
+	int i, nonzero_path = 0;
+	char c;
+
+	if (!edev || !info)
+		return 0;
+
+	if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) {
+		return 0;
+	}
+
+	for (i = 30; i <= 73; i++) {
+		c = *(((uint8_t *) info) + i + 4);
+		if (c) {
+			nonzero_path++;
+			break;
+		}
+	}
+	if (!nonzero_path) {
+		return 0;
+	}
+
+	return 1;
+}
+
+static EDD_DEVICE_ATTR(raw_data, edd_show_raw_data, NULL);
+static EDD_DEVICE_ATTR(version, edd_show_version, NULL);
+static EDD_DEVICE_ATTR(extensions, edd_show_extensions, NULL);
+static EDD_DEVICE_ATTR(info_flags, edd_show_info_flags, NULL);
+static EDD_DEVICE_ATTR(sectors, edd_show_sectors, NULL);
+static EDD_DEVICE_ATTR(default_cylinders, edd_show_default_cylinders,
+		       edd_has_default_cylinders);
+static EDD_DEVICE_ATTR(default_heads, edd_show_default_heads,
+		       edd_has_default_heads);
+static EDD_DEVICE_ATTR(default_sectors_per_track,
+		       edd_show_default_sectors_per_track,
+		       edd_has_default_sectors_per_track);
+static EDD_DEVICE_ATTR(interface, edd_show_interface,edd_has_edd30);
+static EDD_DEVICE_ATTR(host_bus, edd_show_host_bus, edd_has_edd30);
+
+static struct edd_attribute *def_attrs[] = {
+	&edd_attr_raw_data,
+	&edd_attr_version,
+	&edd_attr_extensions,
+	&edd_attr_info_flags,
+	&edd_attr_sectors,
+	&edd_attr_default_cylinders,
+	&edd_attr_default_heads,
+	&edd_attr_default_sectors_per_track,
+	&edd_attr_interface,
+	&edd_attr_host_bus,
+	NULL,
+};
+
+static inline void
+edd_device_unregister(struct edd_device *edev)
+{
+	struct list_head *pos, *next;
+	struct attr_entry *ae;
+
+	list_for_each_safe(pos, next, &edev->attr_list) {
+		ae = list_entry(pos, struct attr_entry, node);
+		remove_proc_entry(ae->entry->name, edev->dir);
+		list_del(&ae->node);
+		kfree(ae);
+	}
+
+	remove_proc_entry(edev->dir->name, bios_dir);
+}
+
+static int
+edd_populate_dir(struct edd_device *edev)
+{
+	struct edd_attribute *attr;
+	struct attr_entry *ae;
+	int i;
+	int error = 0;
+
+	for (i = 0; (attr=def_attrs[i]); i++) {
+		if (!attr->test || (attr->test && attr->test(edev))) {
+			ae = kmalloc(sizeof (*ae), GFP_KERNEL);
+			if (ae == NULL) {
+				error = 1;
+				break;
+			}
+			INIT_LIST_HEAD(&ae->node);
+			ae->entry =
+				create_proc_read_entry(attr->name, 0444,
+						       edev->dir, attr->show,
+						       edd_dev_get_info(edev));
+			if (ae->entry == NULL) {
+				error = 1;
+				break;
+			}
+			list_add(&ae->node, &edev->attr_list);
+		}
+	}
+
+	if (error)
+		return error;
+
+	return 0;
+}
+
+static int
+edd_make_dir(struct edd_device *edev)
+{
+	int error=1;
+
+	edev->dir = proc_mkdir(edev->name, bios_dir);
+	if (edev->dir != NULL) {
+		edev->dir->mode = (S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
+		error = edd_populate_dir(edev);
+	}
+	return error;
+}
+
+static int
+edd_device_register(struct edd_device *edev, int i)
+{
+	int error;
+
+	if (!edev)
+		return 1;
+	memset(edev, 0, sizeof (*edev));
+	INIT_LIST_HEAD(&edev->attr_list);
+	edd_dev_set_info(edev, &edd[i]);
+	snprintf(edev->name, EDD_DEVICE_NAME_SIZE, "int13_dev%02x",
+		 edd[i].device);
+	error = edd_make_dir(edev);
+	return error;
+}
+
+/**
+ * edd_init() - creates /proc/bios tree of EDD data
+ *
+ * This assumes that eddnr and edd were
+ * assigned in setup.c already.
+ */
+static int __init
+edd_init(void)
+{
+	unsigned int i;
+	int rc = 0;
+	struct edd_device *edev;
+
+	printk(KERN_INFO "BIOS EDD facility v%s, %d devices found\n",
+	       EDD_VERSION, eddnr);
+
+	if (!eddnr) {
+		printk(KERN_INFO "EDD information not available.\n");
+		return 1;
+	}
+
+	bios_dir = proc_mkdir("bios", NULL);
+	if (bios_dir == NULL)
+		return 1;
+
+	for (i = 0; i < eddnr && i < EDDMAXNR && !rc; i++) {
+		edev = kmalloc(sizeof (*edev), GFP_KERNEL);
+		if (!edev) {
+			rc = 1;
+			break;
+		}
+
+		rc = edd_device_register(edev, i);
+		if (rc) {
+			break;
+		}
+		edd_devices[i] = edev;
+	}
+
+	if (rc) {
+		for (i = 0; i < eddnr && i < EDDMAXNR; i++) {
+			if ((edev = edd_devices[i])) {
+				edd_device_unregister(edev);
+				kfree(edev);
+			}
+		}
+
+		remove_proc_entry(bios_dir->name, NULL);
+	}
+
+	return rc;
+}
+
+static void __exit
+edd_exit(void)
+{
+	int i;
+	struct edd_device *edev;
+
+	for (i = 0; i < eddnr && i < EDDMAXNR; i++) {
+		if ((edev = edd_devices[i])) {
+			edd_device_unregister(edev);
+			kfree(edev);
+		}
+	}
+
+	remove_proc_entry(bios_dir->name, NULL);
+}
+
+module_init(edd_init);
+module_exit(edd_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/head.S linux-2.4.23-pre8/arch/i386/kernel/head.S
--- linux-2.4.22/arch/i386/kernel/head.S	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/head.S	2003-10-22 22:47:41.000000000 +0000
@@ -34,7 +34,7 @@
 #define X86_HARD_MATH	CPU_PARAMS+6
 #define X86_CPUID	CPU_PARAMS+8
 #define X86_CAPABILITY	CPU_PARAMS+12
-#define X86_VENDOR_ID	CPU_PARAMS+28
+#define X86_VENDOR_ID	CPU_PARAMS+36	/* tied to NCAPINTS in cpufeature.h */
 
 /*
  * swapper_pg_dir is the main page directory, address 0x00101000
@@ -113,7 +113,7 @@
 	popfl
 	jmp checkCPUtype
 1:
-#endif CONFIG_SMP
+#endif /* CONFIG_SMP */
 
 /*
  * Clear BSS first so that there are no surprises...
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/i386_ksyms.c linux-2.4.23-pre8/arch/i386/kernel/i386_ksyms.c
--- linux-2.4.22/arch/i386/kernel/i386_ksyms.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/i386_ksyms.c	2003-10-22 22:48:54.000000000 +0000
@@ -28,6 +28,7 @@
 #include <asm/desc.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
+#include <asm/edd.h>
 
 extern void dump_thread(struct pt_regs *, struct user *);
 extern spinlock_t rtc_lock;
@@ -180,3 +181,8 @@
 #ifdef CONFIG_MULTIQUAD
 EXPORT_SYMBOL(xquad_portio);
 #endif
+
+#ifdef CONFIG_EDD_MODULE
+EXPORT_SYMBOL(edd);
+EXPORT_SYMBOL(eddnr);
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/io_apic.c linux-2.4.23-pre8/arch/i386/kernel/io_apic.c
--- linux-2.4.22/arch/i386/kernel/io_apic.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/io_apic.c	2003-10-22 22:48:26.000000000 +0000
@@ -169,6 +169,14 @@
 {
 	struct IO_APIC_route_entry entry;
 	unsigned long flags;
+	
+	/* Check delivery_mode to be sure we're not clearing an SMI pin */
+	spin_lock_irqsave(&ioapic_lock, flags);
+	*(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
+	*(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+	if (entry.delivery_mode == dest_SMI)
+		return;
 
 	/*
 	 * Disable it in the IO-APIC irq-routing table:
@@ -1365,6 +1373,13 @@
 static void set_ioapic_affinity (unsigned int irq, unsigned long mask)
 {
 	unsigned long flags;
+
+	/* pick a single cpu for clustered xapics */
+	if(clustered_apic_mode == CLUSTERED_APIC_XAPIC){
+		int cpu = ffs(mask)-1;
+		mask = cpu_to_physical_apicid(cpu);
+	}
+
 	/*
 	 * Only the first 8 bits are valid.
 	 */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/irq.c linux-2.4.23-pre8/arch/i386/kernel/irq.c
--- linux-2.4.22/arch/i386/kernel/irq.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/irq.c	2003-10-22 22:47:39.000000000 +0000
@@ -32,6 +32,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/irq.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 #include <asm/atomic.h>
 #include <asm/io.h>
@@ -131,55 +132,55 @@
  * Generic, controller-independent functions:
  */
 
-int get_irq_list(char *buf)
+int show_interrupts(struct seq_file *p, void *v)
 {
 	int i, j;
 	struct irqaction * action;
-	char *p = buf;
 
-	p += sprintf(p, "           ");
+	seq_printf(p, "           ");
 	for (j=0; j<smp_num_cpus; j++)
-		p += sprintf(p, "CPU%d       ",j);
-	*p++ = '\n';
+		seq_printf(p, "CPU%d       ",j);
+	seq_putc(p,'\n');
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
 		action = irq_desc[i].action;
 		if (!action) 
 			continue;
-		p += sprintf(p, "%3d: ",i);
+		seq_printf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
-		p += sprintf(p, "%10u ", kstat_irqs(i));
+		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 		for (j = 0; j < smp_num_cpus; j++)
-			p += sprintf(p, "%10u ",
+			seq_printf(p, "%10u ",
 				kstat.irqs[cpu_logical_map(j)][i]);
 #endif
-		p += sprintf(p, " %14s", irq_desc[i].handler->typename);
-		p += sprintf(p, "  %s", action->name);
+		seq_printf(p, " %14s", irq_desc[i].handler->typename);
+		seq_printf(p, "  %s", action->name);
 
 		for (action=action->next; action; action = action->next)
-			p += sprintf(p, ", %s", action->name);
-		*p++ = '\n';
+			seq_printf(p, ", %s", action->name);
+		seq_putc(p,'\n');
 	}
-	p += sprintf(p, "NMI: ");
+	seq_printf(p, "NMI: ");
 	for (j = 0; j < smp_num_cpus; j++)
-		p += sprintf(p, "%10u ",
+		seq_printf(p, "%10u ",
 			nmi_count(cpu_logical_map(j)));
-	p += sprintf(p, "\n");
+	seq_printf(p, "\n");
 #if CONFIG_X86_LOCAL_APIC
-	p += sprintf(p, "LOC: ");
+	seq_printf(p, "LOC: ");
 	for (j = 0; j < smp_num_cpus; j++)
-		p += sprintf(p, "%10u ",
+		seq_printf(p, "%10u ",
 			apic_timer_irqs[cpu_logical_map(j)]);
-	p += sprintf(p, "\n");
+	seq_printf(p, "\n");
 #endif
-	p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+	seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
 #ifdef CONFIG_X86_IO_APIC
 #ifdef APIC_MISMATCH_DEBUG
-	p += sprintf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
+	seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
 #endif
 #endif
-	return p - buf;
+
+	return 0;
 }
 
 
@@ -1035,7 +1036,7 @@
 
 	if (!shared) {
 		desc->depth = 0;
-		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING);
+		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
 		desc->handler->startup(irq);
 	}
 	spin_unlock_irqrestore(&desc->lock,flags);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/mpparse.c linux-2.4.23-pre8/arch/i386/kernel/mpparse.c
--- linux-2.4.22/arch/i386/kernel/mpparse.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/mpparse.c	2003-10-22 22:48:24.000000000 +0000
@@ -229,6 +229,11 @@
 		boot_cpu_logical_apicid = logical_apicid;
 	}
 
+	if (num_processors >= NR_CPUS){
+		printk(KERN_WARNING "NR_CPUS limit of %i reached. Cannot "
+			"boot CPU(apicid 0x%x).\n", NR_CPUS, m->mpc_apicid);
+		return;
+	}
 	num_processors++;
 
 	if (m->mpc_apicid > MAX_APICS) {
@@ -683,6 +688,24 @@
 	struct mpc_config_lintsrc lintsrc;
 	int linttypes[2] = { mp_ExtINT, mp_NMI };
 	int i;
+	struct {
+		int mp_bus_id_to_type[MAX_MP_BUSSES];
+		int mp_bus_id_to_node[MAX_MP_BUSSES];
+		int mp_bus_id_to_local[MAX_MP_BUSSES];
+		int mp_bus_id_to_pci_bus[MAX_MP_BUSSES];
+		struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
+	} *bus_data;
+
+	bus_data = alloc_bootmem(sizeof(*bus_data));
+	if (!bus_data)
+		panic("SMP mptable: out of memory!\n");
+	mp_bus_id_to_type = bus_data->mp_bus_id_to_type;
+	mp_bus_id_to_node = bus_data->mp_bus_id_to_node;
+	mp_bus_id_to_local = bus_data->mp_bus_id_to_local;
+	mp_bus_id_to_pci_bus = bus_data->mp_bus_id_to_pci_bus;
+	mp_irqs = bus_data->mp_irqs;
+	for (i = 0; i < MAX_MP_BUSSES; ++i)
+		mp_bus_id_to_pci_bus[i] = -1;
 
 	/*
 	 * local APIC has default address
@@ -977,7 +1000,14 @@
 
 	processor.mpc_type = MP_PROCESSOR;
 	processor.mpc_apicid = id;
-	processor.mpc_apicver = 0x10; /* TBD: lapic version */
+
+	/*
+	 * mp_register_lapic_address() which is called before the
+	 * current function does the fixmap of FIX_APIC_BASE.
+	 * Read in the correct APIC version from there
+	 */
+	processor.mpc_apicver = apic_read(APIC_LVR);
+
 	processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0);
 	processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0);
 	processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | 
@@ -1014,7 +1044,7 @@
 			return i;
 	}
 
-	printk(KERN_ERR "ERROR: Unable to locate IOAPIC for IRQ %d/n", irq);
+	printk(KERN_ERR "ERROR: Unable to locate IOAPIC for IRQ %d\n", irq);
 
 	return -1;
 }
@@ -1199,8 +1229,6 @@
 	}
 }
 
-/* Ensure the ACPI SCI interrupt level is active low, edge-triggered */
-
 extern FADT_DESCRIPTOR acpi_fadt;
 
 void __init mp_config_ioapic_for_sci(int irq)
@@ -1209,6 +1237,7 @@
 	int ioapic_pin;
 	struct acpi_table_madt* madt;
 	struct acpi_table_int_src_ovr *entry = NULL;
+	acpi_interrupt_flags flags;
 	void *madt_end;
 	acpi_status status;
 
@@ -1227,30 +1256,36 @@
 
 		while ((void *) entry < madt_end) {
                 	if (entry->header.type == ACPI_MADT_INT_SRC_OVR &&
-			    acpi_fadt.sci_int == entry->bus_irq) {
-				/*
-				 * See the note at the end of ACPI 2.0b section
-				 * 5.2.10.8 for what this is about.
-				 */
-				if (entry->bus_irq != entry->global_irq) {
-					acpi_fadt.sci_int = entry->global_irq;
-					irq = entry->global_irq;
-					break;
-				}
-				else
-                			return;
-			}
-
+			    acpi_fadt.sci_int == entry->bus_irq)
+				goto found;
+			
                 	entry = (struct acpi_table_int_src_ovr *)
                 	        ((unsigned long) entry + entry->header.length);
         	}
 	}
+	/*
+	 * Although the ACPI spec says that the SCI should be level/low
+	 * don't reprogram it unless there is an explicit MADT OVR entry
+	 * instructing us to do so -- otherwise we break Tyan boards which
+	 * have the SCI wired edge/high but no MADT OVR.
+	 */
+	return;
 
+found:
+	/*
+	 * See the note at the end of ACPI 2.0b section
+	 * 5.2.10.8 for what this is about.
+	 */
+	flags = entry->flags;
+	acpi_fadt.sci_int = entry->global_irq;
+	irq = entry->global_irq;
+	
 	ioapic = mp_find_ioapic(irq);
 
 	ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
 
-	io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 1, 1); // Active low, level triggered
+	io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 
+				(flags.trigger >> 1) , (flags.polarity >> 1));
 }
 
 
@@ -1288,8 +1323,10 @@
 		}
 
 		/* Don't set up the ACPI SCI because it's already set up */
-		if (acpi_fadt.sci_int == irq)
+                if (acpi_fadt.sci_int == irq) {
+                        entry->irq = irq; /*we still need to set entry's irq*/
 			continue;
+                }
 	
 		ioapic = mp_find_ioapic(irq);
 		if (ioapic < 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/pci-i386.c linux-2.4.23-pre8/arch/i386/kernel/pci-i386.c
--- linux-2.4.22/arch/i386/kernel/pci-i386.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/pci-i386.c	2003-10-22 22:48:14.000000000 +0000
@@ -295,6 +295,17 @@
 	}
 }
 
+void __init pcibios_set_cacheline_size(void)
+{
+	struct cpuinfo_x86 *c = &boot_cpu_data;
+
+	pci_cache_line_size = 32 >> 2;
+	if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD)
+		pci_cache_line_size = 64 >> 2;	/* K7 & K8 */
+	else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL)
+		pci_cache_line_size = 128 >> 2;	/* P4 */
+}
+
 void __init pcibios_resource_survey(void)
 {
 	DBG("PCI: Allocating resources\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/pci-i386.h linux-2.4.23-pre8/arch/i386/kernel/pci-i386.h
--- linux-2.4.22/arch/i386/kernel/pci-i386.h	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/pci-i386.h	2003-10-22 22:49:02.000000000 +0000
@@ -27,8 +27,10 @@
 /* pci-i386.c */
 
 extern unsigned int pcibios_max_latency;
+extern u8 pci_cache_line_size;
 
 void pcibios_resource_survey(void);
+void pcibios_set_cacheline_size(void);
 int pcibios_enable_resources(struct pci_dev *, int);
 
 /* pci-pc.c */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/pci-irq.c linux-2.4.23-pre8/arch/i386/kernel/pci-irq.c
--- linux-2.4.22/arch/i386/kernel/pci-irq.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/pci-irq.c	2003-10-22 22:49:52.000000000 +0000
@@ -23,7 +23,6 @@
 #define PIRQ_VERSION 0x0100
 
 int broken_hp_bios_irq9;
-int broken_440gx_bios;
 
 static struct irq_routing_table *pirq_table;
 
@@ -46,6 +45,11 @@
 	int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new);
 };
 
+struct irq_router_handler {
+	u16 vendor;
+	int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device);
+};
+
 /*
  *  Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
  */
@@ -257,111 +261,221 @@
 }
 
 /*
- *	PIRQ routing for SiS 85C503 router used in several SiS chipsets
- *	According to the SiS 5595 datasheet (preliminary V1.0, 12/24/1997)
- *	the related registers work as follows:
- *	
- *	general: one byte per re-routable IRQ,
+ *	PIRQ routing for SiS 85C503 router used in several SiS chipsets.
+ *	We have to deal with the following issues here:
+ *	- vendors have different ideas about the meaning of link values
+ *	- some onboard devices (integrated in the chipset) have special
+ *	  links and are thus routed differently (i.e. not via PCI INTA-INTD)
+ *	- different revision of the router have a different layout for
+ *	  the routing registers, particularly for the onchip devices
+ *
+ *	For all routing registers the common thing is we have one byte
+ *	per routeable link which is defined as:
  *		 bit 7      IRQ mapping enabled (0) or disabled (1)
- *		 bits [6:4] reserved
+ *		 bits [6:4] reserved (sometimes used for onchip devices)
  *		 bits [3:0] IRQ to map to
  *		     allowed: 3-7, 9-12, 14-15
  *		     reserved: 0, 1, 2, 8, 13
  *
- *	individual registers in device config space:
+ *	The config-space registers located at 0x41/0x42/0x43/0x44 are
+ *	always used to route the normal PCI INT A/B/C/D respectively.
+ *	Apparently there are systems implementing PCI routing table using
+ *	link values 0x01-0x04 and others using 0x41-0x44 for PCI INTA..D.
+ *	We try our best to handle both link mappings.
+ *	
+ *	Currently (2003-05-21) it appears most SiS chipsets follow the
+ *	definition of routing registers from the SiS-5595 southbridge.
+ *	According to the SiS 5595 datasheets the revision id's of the
+ *	router (ISA-bridge) should be 0x01 or 0xb0.
  *
- *	0x41/0x42/0x43/0x44:	PCI INT A/B/C/D - bits as in general case
+ *	Furthermore we've also seen lspci dumps with revision 0x00 and 0xb1.
+ *	Looks like these are used in a number of SiS 5xx/6xx/7xx chipsets.
+ *	They seem to work with the current routing code. However there is
+ *	some concern because of the two USB-OHCI HCs (original SiS 5595
+ *	had only one). YMMV.
  *
- *	0x61:			IDEIRQ: bits as in general case - but:
- *				bits [6:5] must be written 01
- *				bit 4 channel-select primary (0), secondary (1)
+ *	Onchip routing for router rev-id 0x01/0xb0 and probably 0x00/0xb1:
  *
- *	0x62:			USBIRQ: bits as in general case - but:
- *				bit 4 OHCI function disabled (0), enabled (1)
+ *	0x61:	IDEIRQ:
+ *		bits [6:5] must be written 01
+ *		bit 4 channel-select primary (0), secondary (1)
+ *
+ *	0x62:	USBIRQ:
+ *		bit 6 OHCI function disabled (0), enabled (1)
  *	
- *	0x6a:			ACPI/SCI IRQ - bits as in general case
+ *	0x6a:	ACPI/SCI IRQ: bits 4-6 reserved
+ *
+ *	0x7e:	Data Acq. Module IRQ - bits 4-6 reserved
+ *
+ *	We support USBIRQ (in addition to INTA-INTD) and keep the
+ *	IDE, ACPI and DAQ routing untouched as set by the BIOS.
+ *
+ *	Currently the only reported exception is the new SiS 65x chipset
+ *	which includes the SiS 69x southbridge. Here we have the 85C503
+ *	router revision 0x04 and there are changes in the register layout
+ *	mostly related to the different USB HCs with USB 2.0 support.
  *
- *	0x7e:			Data Acq. Module IRQ - bits as in general case
+ *	Onchip routing for router rev-id 0x04 (try-and-error observation)
  *
- *	Apparently there are systems implementing PCI routing table using both
- *	link values 0x01-0x04 and 0x41-0x44 for PCI INTA..D, but register offsets
- *	like 0x62 as link values for USBIRQ e.g. So there is no simple
- *	"register = offset + pirq" relation.
- *	Currently we support PCI INTA..D and USBIRQ and try our best to handle
- *	both link mappings.
- *	IDE/ACPI/DAQ mapping is currently unsupported (left untouched as set by BIOS).
+ *	0x60/0x61/0x62/0x63:	1xEHCI and 3xOHCI (companion) USB-HCs
+ *				bit 6-4 are probably unused, not like 5595
  */
 
-static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+#define PIRQ_SIS_IRQ_MASK	0x0f
+#define PIRQ_SIS_IRQ_DISABLE	0x80
+#define PIRQ_SIS_USB_ENABLE	0x40
+#define PIRQ_SIS_DETECT_REGISTER 0x40
+
+/* return value:
+ * -1 on error
+ * 0 for PCI INTA-INTD
+ * 0 or enable bit mask to check or set for onchip functions
+ */
+static inline int pirq_sis5595_onchip(int pirq, int *reg)
 {
-	u8 x;
-	int reg = pirq;
+	int ret = -1;
 
+	*reg = pirq;
 	switch(pirq) {
-		case 0x01:
-		case 0x02:
-		case 0x03:
-		case 0x04:
-			reg += 0x40;
-		case 0x41:
-		case 0x42:
-		case 0x43:
-		case 0x44:
-		case 0x62:
-			pci_read_config_byte(router, reg, &x);
-			if (reg != 0x62)
-				break;
-			if (!(x & 0x40))
-				return 0;
-			break;
-		case 0x61:
-		case 0x6a:
-		case 0x7e:
-			printk(KERN_INFO "SiS pirq: advanced IDE/ACPI/DAQ mapping not yet implemented\n");
-			return 0;
-		default:			
-			printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
-			return 0;
+	case 0x01:
+	case 0x02:
+	case 0x03:
+	case 0x04:
+		*reg += 0x40;
+	case 0x41:
+	case 0x42:
+	case 0x43:
+	case 0x44:
+		ret = 0;
+		break;
+
+	case 0x62:
+		ret = PIRQ_SIS_USB_ENABLE;	/* documented for 5595 */
+		break;
+
+	case 0x61:
+	case 0x6a:
+	case 0x7e:
+		printk(KERN_INFO "SiS pirq: IDE/ACPI/DAQ mapping not implemented: (%u)\n",
+		       (unsigned) pirq);
+		/* fall thru */
+	default:
+		printk(KERN_INFO "SiS router unknown request: (%u)\n",
+		       (unsigned) pirq);
+		break;
+	}
+	return ret;
+}		
+
+/* return value:
+ * -1 on error
+ * 0 for PCI INTA-INTD
+ * 0 or enable bit mask to check or set for onchip functions
+ */
+static inline int pirq_sis96x_onchip(int pirq, int *reg)
+{
+	int ret = -1;
+
+	*reg = pirq;
+	switch(pirq) {
+	case 0x01:
+	case 0x02:
+	case 0x03:
+	case 0x04:
+		*reg += 0x40;
+	case 0x41:
+	case 0x42:
+	case 0x43:
+	case 0x44:
+	case 0x60:
+	case 0x61:
+	case 0x62:
+	case 0x63:
+		ret = 0;
+		break;
+
+	default:
+		printk(KERN_INFO "SiS router unknown request: (%u)\n",
+		       (unsigned) pirq);
+		break;
 	}
-	return (x & 0x80) ? 0 : (x & 0x0f);
+	return ret;
+}		
+
+
+static int pirq_sis5595_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+	u8 x;
+	int reg, check;
+
+	check = pirq_sis5595_onchip(pirq, &reg);
+	if (check < 0)
+		return 0;
+
+	pci_read_config_byte(router, reg, &x);
+	if (check != 0  &&  !(x & check))
+		return 0;
+
+	return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK);
 }
 
-static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+static int pirq_sis96x_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
 {
 	u8 x;
-	int reg = pirq;
+	int reg, check;
+
+	check = pirq_sis96x_onchip(pirq, &reg);
+	if (check < 0)
+		return 0;
+
+	pci_read_config_byte(router, reg, &x);
+	if (check != 0  &&  !(x & check))
+		return 0;
+
+	return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK);
+}
+
+static int pirq_sis5595_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	u8 x;
+	int reg, set;
+
+	set = pirq_sis5595_onchip(pirq, &reg);
+	if (set < 0)
+		return 0;
+
+	x = (irq & PIRQ_SIS_IRQ_MASK);
+	if (x == 0)
+		x = PIRQ_SIS_IRQ_DISABLE;
+	else
+		x |= set;
 
-	switch(pirq) {
-		case 0x01:
-		case 0x02:
-		case 0x03:
-		case 0x04:
-			reg += 0x40;
-		case 0x41:
-		case 0x42:
-		case 0x43:
-		case 0x44:
-		case 0x62:
-			x = (irq&0x0f) ? (irq&0x0f) : 0x80;
-			if (reg != 0x62)
-				break;
-			/* always mark OHCI enabled, as nothing else knows about this */
-			x |= 0x40;
-			break;
-		case 0x61:
-		case 0x6a:
-		case 0x7e:
-			printk(KERN_INFO "advanced SiS pirq mapping not yet implemented\n");
-			return 0;
-		default:			
-			printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
-			return 0;
-	}
 	pci_write_config_byte(router, reg, x);
 
 	return 1;
 }
 
+static int pirq_sis96x_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	u8 x;
+	int reg, set;
+
+	set = pirq_sis96x_onchip(pirq, &reg);
+	if (set < 0)
+		return 0;
+
+	x = (irq & PIRQ_SIS_IRQ_MASK);
+	if (x == 0)
+		x = PIRQ_SIS_IRQ_DISABLE;
+	else
+		x |= set;
+
+	pci_write_config_byte(router, reg, x);
+
+	return 1;
+}
+
+
 /*
  * VLSI: nibble offset 0x74 - educated guess due to routing table and
  *       config space of VLSI 82C534 PCI-bridge/router (1004:0102)
@@ -454,96 +568,263 @@
 	return pcibios_set_irq_routing(bridge, pin, irq);
 }
 
-static struct irq_router pirq_bios_router =
-	{ "BIOS", 0, 0, NULL, pirq_bios_set };
-
 #endif
 
-static struct irq_router pirq_routers[] = {
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX,   pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_0, pirq_piix_get, pirq_piix_set },
-
-	{ "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set },
-
-	{ "ITE", PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8330G_0, pirq_ite_get, pirq_ite_set },
-
-	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set },
-	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, pirq_via_get, pirq_via_set },
-	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, pirq_via_get, pirq_via_set },
-
-	{ "OPTI", PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C700, pirq_opti_get, pirq_opti_set },
-
-	{ "NatSemi", PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, pirq_cyrix_get, pirq_cyrix_set },
-	{ "SIS", PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, pirq_sis_get, pirq_sis_set },
-	{ "VLSI 82C534", PCI_VENDOR_ID_VLSI, PCI_DEVICE_ID_VLSI_82C534, pirq_vlsi_get, pirq_vlsi_set },
-	{ "ServerWorks", PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4,
-	  pirq_serverworks_get, pirq_serverworks_set },
-	{ "ServerWorks", PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5,
-	  pirq_serverworks_get, pirq_serverworks_set },
-	{ "AMD756 VIPER", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B,
-		pirq_amd756_get, pirq_amd756_set },
-	{ "AMD766", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413,
-		pirq_amd756_get, pirq_amd756_set },
-	{ "AMD768", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7443,
-		pirq_amd756_get, pirq_amd756_set },
 
-	{ "default", 0, 0, NULL, NULL }
-};
+static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	/* We must not touch 440GX even if we have tables. 440GX has
+	   different IRQ routing weirdness */
+	if(pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82450GX, NULL))
+		return 0;
+	switch(device)
+	{
+		case PCI_DEVICE_ID_INTEL_82371FB_0:
+		case PCI_DEVICE_ID_INTEL_82371SB_0:
+		case PCI_DEVICE_ID_INTEL_82371AB_0:
+		case PCI_DEVICE_ID_INTEL_82371MX:
+		case PCI_DEVICE_ID_INTEL_82443MX_0:
+		case PCI_DEVICE_ID_INTEL_82801AA_0:
+		case PCI_DEVICE_ID_INTEL_82801AB_0:
+		case PCI_DEVICE_ID_INTEL_82801BA_0:
+		case PCI_DEVICE_ID_INTEL_82801BA_10:
+		case PCI_DEVICE_ID_INTEL_82801CA_0:
+		case PCI_DEVICE_ID_INTEL_82801CA_12:
+		case PCI_DEVICE_ID_INTEL_82801DB_0:
+		case PCI_DEVICE_ID_INTEL_82801E_0:
+		case PCI_DEVICE_ID_INTEL_82801EB_0:
+		case PCI_DEVICE_ID_INTEL_ESB_0:
+			r->name = "PIIX/ICH";
+			r->get = pirq_piix_get;
+			r->set = pirq_piix_set;
+			return 1;
+	}
+	return 0;
+}
 
-static struct irq_router *pirq_router;
+static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	/* FIXME: We should move some of the quirk fixup stuff here */
+	switch(device)
+	{
+		case PCI_DEVICE_ID_VIA_82C586_0:
+		case PCI_DEVICE_ID_VIA_82C596:
+		case PCI_DEVICE_ID_VIA_82C686:
+		case PCI_DEVICE_ID_VIA_8231:
+		/* FIXME: add new ones for 8233/5 */
+			r->name = "VIA";
+			r->get = pirq_via_get;
+			r->set = pirq_via_set;
+			return 1;
+	}
+	return 0;
+}
+
+static __init int vlsi_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_VLSI_82C534:
+			r->name = "VLSI 82C534";
+			r->get = pirq_vlsi_get;
+			r->set = pirq_vlsi_set;
+			return 1;
+	}
+	return 0;
+}
+
+
+static __init int serverworks_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_SERVERWORKS_OSB4:
+		case PCI_DEVICE_ID_SERVERWORKS_CSB5:
+			r->name = "ServerWorks";
+			r->get = pirq_serverworks_get;
+			r->set = pirq_serverworks_set;
+			return 1;
+	}
+	return 0;
+}
+
+static __init int sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	u8 reg;
+	u16 devid;
+
+	if (device != PCI_DEVICE_ID_SI_503)
+		return 0;
+		
+	/*
+	 * In case of SiS south bridge, we need to detect the two
+	 * kinds of routing tables we have seen so far (5595 and 96x). 
+	 * Since the maintain the same device ID, we need to do poke 
+	 * the PCI configuration space to find the router type we are
+	 * dealing with.
+	 */
+
+	/*
+	 * Factoid: writing bit6 of register 0x40 of the router config space
+	 * will make the SB to show up 0x096x inside the device id. Note,
+	 * we need to restore register 0x40 after the device id poke.
+	 */
+
+	pci_read_config_byte(router, PIRQ_SIS_DETECT_REGISTER, &reg);
+	pci_write_config_byte(router, PIRQ_SIS_DETECT_REGISTER, reg | (1 << 6));
+	pci_read_config_word(router, PCI_DEVICE_ID, &devid);
+	pci_write_config_byte(router, PIRQ_SIS_DETECT_REGISTER, reg);
+
+	if ((devid & 0xfff0) == 0x0960) {
+		r->name = "SIS96x";
+		r->get = pirq_sis96x_get;
+		r->set = pirq_sis96x_set;
+		DBG("PCI: Detecting SiS router at %02x:%02x : SiS096x detected\n",
+		    rt->rtr_bus, rt->rtr_devfn);
+	} else {
+		r->name = "SIS5595";
+		r->get = pirq_sis5595_get;
+		r->set = pirq_sis5595_set;
+		DBG("PCI: Detecting SiS router at %02x:%02x : SiS5595 detected\n",
+		    rt->rtr_bus, rt->rtr_devfn);
+	}
+	return 1;
+}
+
+static __init int cyrix_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_CYRIX_5520:
+			r->name = "NatSemi";
+			r->get = pirq_cyrix_get;
+			r->set = pirq_cyrix_set;
+			return 1;
+	}
+	return 0;
+}
+
+static __init int opti_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_OPTI_82C700:
+			r->name = "OPTI";
+			r->get = pirq_opti_get;
+			r->set = pirq_opti_set;
+			return 1;
+	}
+	return 0;
+}
+
+static __init int ite_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_ITE_IT8330G_0:
+			r->name = "ITE";
+			r->get = pirq_ite_get;
+			r->set = pirq_ite_set;
+			return 1;
+	}
+	return 0;
+}
+
+static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_AL_M1533:
+			r->name = "ALI";
+			r->get = pirq_ali_get;
+			r->set = pirq_ali_set;
+			return 1;
+		/* Should add 156x some day */
+	}
+	return 0;
+}
+
+static __init int amd_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_AMD_VIPER_740B:
+			r->name = "AMD756";
+			break;
+		case PCI_DEVICE_ID_AMD_VIPER_7413:
+			r->name = "AMD766";
+			break;
+		case PCI_DEVICE_ID_AMD_VIPER_7443:
+			r->name = "AMD768";
+			break;
+		default:
+			return 0;
+	}
+	r->get = pirq_amd756_get;
+	r->set = pirq_amd756_set;
+	return 1;
+}
+		
+static __initdata struct irq_router_handler pirq_routers[] = {
+	{ PCI_VENDOR_ID_INTEL, intel_router_probe },
+	{ PCI_VENDOR_ID_AL, ali_router_probe },
+	{ PCI_VENDOR_ID_ITE, ite_router_probe },
+	{ PCI_VENDOR_ID_VIA, via_router_probe },
+	{ PCI_VENDOR_ID_OPTI, opti_router_probe },
+	{ PCI_VENDOR_ID_SI, sis_router_probe },
+	{ PCI_VENDOR_ID_CYRIX, cyrix_router_probe },
+	{ PCI_VENDOR_ID_VLSI, vlsi_router_probe },
+	{ PCI_VENDOR_ID_SERVERWORKS, serverworks_router_probe },
+	{ PCI_VENDOR_ID_AMD, amd_router_probe },
+	/* Someone with docs needs to add the ATI Radeon IGP */
+	{ 0, NULL }
+};
+static struct irq_router pirq_router;
 static struct pci_dev *pirq_router_dev;
 
-static void __init pirq_find_router(void)
+/*
+ *	FIXME: should we have an option to say "generic for
+ *	chipset" ?
+ */
+ 
+static void __init pirq_find_router(struct irq_router *r)
 {
 	struct irq_routing_table *rt = pirq_table;
-	struct irq_router *r;
+	struct irq_router_handler *h;
 
 #ifdef CONFIG_PCI_BIOS
 	if (!rt->signature) {
 		printk(KERN_INFO "PCI: Using BIOS for IRQ routing\n");
-		pirq_router = &pirq_bios_router;
+		r->set = pirq_bios_set;
+		r->name = "BIOS";
 		return;
 	}
 #endif
 
+	/* Default unless a driver reloads it */
+	r->name = "default";
+	r->get = NULL;
+	r->set = NULL;
+	
 	DBG("PCI: Attempting to find IRQ router for %04x:%04x\n",
 	    rt->rtr_vendor, rt->rtr_device);
 
-	/* fall back to default router if nothing else found */
-	pirq_router = &pirq_routers[ARRAY_SIZE(pirq_routers) - 1];
-
 	pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn);
 	if (!pirq_router_dev) {
 		DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn);
 		return;
 	}
 
-	for(r=pirq_routers; r->vendor; r++) {
-		/* Exact match against router table entry? Use it! */
-		if (r->vendor == rt->rtr_vendor && r->device == rt->rtr_device) {
-			pirq_router = r;
+	for( h = pirq_routers; h->vendor; h++) {
+		/* First look for a router match */
+		if (rt->rtr_vendor == h->vendor && h->probe(r, pirq_router_dev, rt->rtr_device))
+			break;
+		/* Fall back to a device match */
+		if (pirq_router_dev->vendor == h->vendor && h->probe(r, pirq_router_dev, pirq_router_dev->device))
 			break;
-		}
-		/* Match against router device entry? Use it as a fallback */
-		if (r->vendor == pirq_router_dev->vendor && r->device == pirq_router_dev->device) {
-			pirq_router = r;
-		}
 	}
 	printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n",
-		pirq_router->name,
+		pirq_router.name,
 		pirq_router_dev->vendor,
 		pirq_router_dev->device,
 		pirq_router_dev->slot_name);
@@ -572,7 +853,7 @@
 	int i, pirq, newirq;
 	int irq = 0;
 	u32 mask;
-	struct irq_router *r = pirq_router;
+	struct irq_router *r = &pirq_router;
 	struct pci_dev *dev2;
 	char *msg = NULL;
 
@@ -685,17 +966,14 @@
 void __init pcibios_irq_init(void)
 {
 	DBG("PCI: IRQ init\n");
-	if (broken_440gx_bios)
- 		pirq_table = NULL;	
- 	else
-		pirq_table = pirq_find_routing_table();
+	pirq_table = pirq_find_routing_table();
 #ifdef CONFIG_PCI_BIOS
 	if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN))
 		pirq_table = pcibios_get_irq_routing_table();
 #endif
 	if (pirq_table) {
 		pirq_peer_trick();
-		pirq_find_router();
+		pirq_find_router(&pirq_router);
 		if (pirq_table->exclusive_irqs) {
 			int i;
 			for (i=0; i<16; i++)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/pci-pc.c linux-2.4.23-pre8/arch/i386/kernel/pci-pc.c
--- linux-2.4.22/arch/i386/kernel/pci-pc.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/pci-pc.c	2003-10-22 22:48:38.000000000 +0000
@@ -1016,7 +1016,8 @@
 		"xor %%ah, %%ah\n"
 		"1:"
 		: "=a" (ret),
-		  "=b" (map)
+		  "=b" (map),
+		  "+m" (opt)
 		: "0" (PCIBIOS_GET_ROUTING_OPTIONS),
 		  "1" (0),
 		  "D" ((long) &opt),
@@ -1414,7 +1415,13 @@
 	return;
 }
 
-int use_acpi_pci __initdata = 1;
+static int use_acpi_pci __initdata = 1;
+
+__init void pci_disable_acpi(void)
+{
+	use_acpi_pci = 0;
+	return;
+}
 
 void __init pcibios_init(void)
 {
@@ -1427,6 +1434,8 @@
 		return;
 	}
 
+	pcibios_set_cacheline_size();
+
 	printk(KERN_INFO "PCI: Probing PCI hardware\n");
 #ifdef CONFIG_ACPI_PCI
 	if (use_acpi_pci && !acpi_pci_irq_init()) {
@@ -1502,7 +1511,7 @@
 		pcibios_last_bus = simple_strtol(str+8, NULL, 0);
 		return NULL;
 	} else if (!strncmp(str, "noacpi", 6)) {
-		use_acpi_pci = 0;
+		pci_disable_acpi();
 		return NULL;
 	}
 	return str;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/pci-visws.c linux-2.4.23-pre8/arch/i386/kernel/pci-visws.c
--- linux-2.4.22/arch/i386/kernel/pci-visws.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/pci-visws.c	2003-10-22 22:47:59.000000000 +0000
@@ -119,6 +119,7 @@
 {
 	unsigned int sec_bus = li_pcib_read16(LI_PCI_BUSNUM) & 0xff;
 
+	pcibios_set_cacheline_size();
 	printk("PCI: Probing PCI hardware on host buses 00 and %02x\n", sec_bus);
 	pci_scan_bus(0, &visws_pci_ops, NULL);
 	pci_scan_bus(sec_bus, &visws_pci_ops, NULL);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/process.c linux-2.4.23-pre8/arch/i386/kernel/process.c
--- linux-2.4.22/arch/i386/kernel/process.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/process.c	2003-10-22 22:47:27.000000000 +0000
@@ -47,6 +47,7 @@
 #ifdef CONFIG_MATH_EMULATION
 #include <asm/math_emu.h>
 #endif
+#include <asm/apic.h>
 
 #include <linux/irq.h>
 
@@ -399,6 +400,14 @@
 	 * other OSs see a clean IRQ state.
 	 */
 	smp_send_stop();
+#elif CONFIG_X86_LOCAL_APIC
+	if (cpu_has_apic) {
+		__cli();
+		disable_local_APIC();
+		__sti();
+	}
+#endif
+#ifdef CONFIG_X86_IO_APIC
 	disable_IO_APIC();
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/setup.c linux-2.4.23-pre8/arch/i386/kernel/setup.c
--- linux-2.4.22/arch/i386/kernel/setup.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/setup.c	2003-10-22 22:48:54.000000000 +0000
@@ -120,6 +120,7 @@
 #include <asm/dma.h>
 #include <asm/mpspec.h>
 #include <asm/mmu_context.h>
+#include <asm/edd.h>
 /*
  * Machine setup..
  */
@@ -176,9 +177,9 @@
 static u32 disabled_x86_caps[NCAPINTS] __initdata = { 0 };
 
 #ifdef	CONFIG_ACPI_INTERPRETER
-	int acpi_disabled __initdata = 0;
+	int acpi_disabled = 0;
 #else
-	int acpi_disabled __initdata = 1;
+	int acpi_disabled = 1;
 #endif
 EXPORT_SYMBOL(acpi_disabled);
 
@@ -211,6 +212,8 @@
 #define KERNEL_START (*(unsigned long *) (PARAM+0x214))
 #define INITRD_START (*(unsigned long *) (PARAM+0x218))
 #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
+#define EDD_NR     (*(unsigned char *) (PARAM+EDDNR))
+#define EDD_BUF     ((struct edd_info *) (PARAM+EDDBUF))
 #define COMMAND_LINE ((char *) (PARAM+2048))
 #define COMMAND_LINE_SIZE 256
 
@@ -715,6 +718,23 @@
 	return 0;
 }
 
+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+unsigned char eddnr;
+struct edd_info edd[EDDMAXNR];
+/**
+ * copy_edd() - Copy the BIOS EDD information
+ *              from empty_zero_page into a safe place.
+ *
+ */
+static inline void copy_edd(void)
+{
+     eddnr = EDD_NR;
+     memcpy(edd, EDD_BUF, sizeof(edd));
+}
+#else
+static inline void copy_edd(void) {}
+#endif
+
 /*
  * Do NOT EVER look at the BIOS memory size location.
  * It does not work on many machines.
@@ -1151,6 +1171,7 @@
 	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
 #endif
 	setup_memory_region();
+	copy_edd();
 
 	if (!MOUNT_ROOT_RDONLY)
 		root_mountflags &= ~MS_RDONLY;
@@ -1976,6 +1997,37 @@
 	
 #endif
 
+static void __init init_c3(struct cpuinfo_x86 *c)
+{
+	u32  lo, hi;
+
+	/* Test for Centaur Extended Feature Flags presence */
+	if (cpuid_eax(0xC0000000) >= 0xC0000001) {
+		/* store Centaur Extended Feature Flags as
+		 * word 5 of the CPU capability bit array
+		 */
+		c->x86_capability[5] = cpuid_edx(0xC0000001);
+	}
+
+	switch (c->x86_model) {
+		case 6 ... 8:		/* Cyrix III family */
+			rdmsr (MSR_VIA_FCR, lo, hi);
+			lo |= (1<<1 | 1<<7);	/* Report CX8 & enable PGE */
+			wrmsr (MSR_VIA_FCR, lo, hi);
+
+			set_bit(X86_FEATURE_CX8, c->x86_capability);
+			set_bit(X86_FEATURE_3DNOW, c->x86_capability);
+
+			/* fall through */
+
+		case 9:	/* Nehemiah */
+		default:
+			get_model_name(c);
+			display_cacheinfo(c);
+			break;
+	}
+}
+
 static void __init init_centaur(struct cpuinfo_x86 *c)
 {
 	enum {
@@ -2114,23 +2166,7 @@
 			break;
 
 		case 6:
-			switch (c->x86_model) {
-				case 6 ... 8:		/* Cyrix III family */
-					rdmsr (MSR_VIA_FCR, lo, hi);
-					lo |= (1<<1 | 1<<7);	/* Report CX8 & enable PGE */
-					wrmsr (MSR_VIA_FCR, lo, hi);
-
-					set_bit(X86_FEATURE_CX8, &c->x86_capability);
-					set_bit(X86_FEATURE_3DNOW, &c->x86_capability);
-
-					/* fall through */
-
-				case 9: /* Nehemiah */
-				default:
-					get_model_name(c);
-					display_cacheinfo(c);
-					break;
-			}
+			init_c3(c);
 			break;
 	}
 }
@@ -2254,6 +2290,8 @@
 	{ 0x23, LVL_3,      1024 },
 	{ 0x25, LVL_3,      2048 },
 	{ 0x29, LVL_3,      4096 },
+	{ 0x2c, LVL_1_DATA, 32 },
+	{ 0x30, LVL_1_INST, 32 },
 	{ 0x39, LVL_2,      128 },
 	{ 0x3b, LVL_2,      128 },
 	{ 0x3C, LVL_2,      256 },
@@ -2276,6 +2314,8 @@
 	{ 0x83, LVL_2,      512 },
 	{ 0x84, LVL_2,      1024 },
 	{ 0x85, LVL_2,      2048 },
+	{ 0x86, LVL_2,      512 },
+	{ 0x87, LVL_2,      1024 },
 	{ 0x00, 0, 0}
 };
 
@@ -2765,10 +2805,16 @@
 
 		/* Intel-defined flags: level 0x00000001 */
 		if ( c->cpuid_level >= 0x00000001 ) {
-			cpuid(0x00000001, &tfms, &junk, &junk,
-			      &c->x86_capability[0]);
+			u32 capability, excap;
+			cpuid(0x00000001, &tfms, &junk, &excap, &capability);
+			c->x86_capability[0] = capability;
+			c->x86_capability[4] = excap;
 			c->x86 = (tfms >> 8) & 15;
 			c->x86_model = (tfms >> 4) & 15;
+			if (c->x86 == 0xf) {
+				c->x86 += (tfms >> 20) & 0xff;
+				c->x86_model += ((tfms >> 16) & 0xF) << 4;
+			} 
 			c->x86_mask = tfms & 15;
 		} else {
 			/* Have CPUID level 0 only - unheard of */
@@ -2972,12 +3018,12 @@
 	        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
 	        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
 	        "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
-	        "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
+	        "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
 
 		/* AMD-defined */
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 		NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
-		NULL, NULL, NULL, NULL, NULL, NULL, "mmxext", NULL,
+		NULL, NULL, NULL, "mp", NULL, NULL, "mmxext", NULL,
 		NULL, NULL, NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
 
 		/* Transmeta-defined */
@@ -2987,7 +3033,20 @@
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
 		/* Other (Linux-defined) */
-		"cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr", NULL, NULL, NULL, NULL,
+		"cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
+		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,
+
+		/* Intel-defined (#2) */
+		"pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "tm2",
+		"est", NULL, "cid", NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+		/* VIA/Cyrix/Centaur-defined */
+		NULL, NULL, "xstore", 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,
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/kernel/smpboot.c linux-2.4.23-pre8/arch/i386/kernel/smpboot.c
--- linux-2.4.22/arch/i386/kernel/smpboot.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/kernel/smpboot.c	2003-10-22 22:48:54.000000000 +0000
@@ -51,7 +51,7 @@
 static int smp_b_stepping;
 
 /* Setup configured maximum number of CPUs to activate */
-static int max_cpus = -1;
+static int max_cpus = NR_CPUS;
 
 /* Total count of live CPUs */
 int smp_num_cpus = 1;
@@ -1116,7 +1116,7 @@
 
 		if (!(phys_cpu_present_map & (1ul << bit)))
 			continue;
-		if ((max_cpus >= 0) && (max_cpus <= cpucount+1))
+		if (max_cpus <= cpucount+1)
 			continue;
 
 		do_boot_cpu(apicid);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/i386/mm/ioremap.c linux-2.4.23-pre8/arch/i386/mm/ioremap.c
--- linux-2.4.22/arch/i386/mm/ioremap.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.23-pre8/arch/i386/mm/ioremap.c	2003-10-22 22:48:15.000000000 +0000
@@ -140,7 +140,7 @@
 	 */
 	offset = phys_addr & ~PAGE_MASK;
 	phys_addr &= PAGE_MASK;
-	size = PAGE_ALIGN(last_addr) - phys_addr;
+	size = PAGE_ALIGN(last_addr+1) - phys_addr;
 
 	/*
 	 * Ok, go for it..
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/Makefile linux-2.4.23-pre8/arch/ia64/Makefile
--- linux-2.4.22/arch/ia64/Makefile	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/Makefile	2003-10-22 22:47:36.000000000 +0000
@@ -17,13 +17,31 @@
 AFLAGS_KERNEL := -mconstant-gp
 EXTRA	=
 
-CFLAGS := $(CFLAGS) -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f10-f15,f32-f127 \
+CFLAGS := $(CFLAGS) -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f12-f15,f32-f127 \
 	  -falign-functions=32
 # -ffunction-sections
 CFLAGS_KERNEL := -mconstant-gp
 
 GCC_VERSION=$(shell $(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.')
 
+CHECK_GAS_FOR_HINT=arch/ia64/scripts/check_gas_for_hint.o
+MAKE_GAS_HINT_TEST=arch/ia64/scripts/make_gas_hint_test
+
+ifneq (, $(shell ls $(CHECK_GAS_FOR_HINT)))
+$(shell rm $(CHECK_GAS_FOR_HINT))
+endif
+
+CHECK_GAS_CMD:=($(CC) $(MAKE_GAS_HINT_TEST).c -o $(MAKE_GAS_HINT_TEST) && $(MAKE_GAS_HINT_TEST) | $(CC) -c -o $(CHECK_GAS_FOR_HINT) -x assembler -; rm -f $(MAKE_GAS_HINT_TEST))>&/dev/null
+$(shell $(CHECK_GAS_CMD))
+ifneq (, $(shell ls $(CHECK_GAS_FOR_HINT)))
+#Newer version of binutil is detected and "hint" instruction is in the kernel
+$(warning Warning: Found binutils that supports hint instruction)
+FLAGS := $(AFLAGS) -DGAS_HAS_HINT_INSN
+CFLAGS := $(CFLAGS) -DGAS_HAS_HINT_INSN
+else
+$(warning Warning: Please use binutil version 2.14.90.0.4.1 or higher to get the support of hint instruction in kernel.) 
+endif
+
 ifneq ($(GCC_VERSION),2)
 	CFLAGS += -frename-registers --param max-inline-insns=5000
 endif
@@ -44,9 +62,11 @@
 
 ifdef CONFIG_IA64_HP_SIM
         SUBDIRS         :=      arch/$(ARCH)/hp		\
+                                arch/$(ARCH)/drivers	\
                                 $(SUBDIRS)
         CORE_FILES      :=      arch/$(ARCH)/hp/hp.o	\
                                 $(CORE_FILES)
+        DRIVERS         +=      arch/$(ARCH)/drivers/drivers.o
 endif
 
 ifdef CONFIG_IA64_HP_ZX1
@@ -136,7 +156,7 @@
 	arch/ia64/scripts/unwcheck.sh vmlinux
 
 archmrproper:
-	rm -f arch/$(ARCH)/vmlinux.lds
+	rm -f arch/$(ARCH)/vmlinux.lds vmlinux-tmp vmlinux.gz
 	@$(MAKE) -C arch/$(ARCH)/tools mrproper
 
 archdep:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/config.in linux-2.4.23-pre8/arch/ia64/config.in
--- linux-2.4.22/arch/ia64/config.in	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/config.in	2003-10-22 22:48:57.000000000 +0000
@@ -35,7 +35,6 @@
 	 DIG-compliant		CONFIG_IA64_DIG			\
 	 HP-simulator		CONFIG_IA64_HP_SIM		\
 	 HP-zx1			CONFIG_IA64_HP_ZX1		\
-	 SGI-SN1		CONFIG_IA64_SGI_SN1		\
 	 SGI-SN2		CONFIG_IA64_SGI_SN2" generic
 
 if [ "$CONFIG_ITANIUM" = "y" ]; then
@@ -54,11 +53,7 @@
 if [ "$CONFIG_ITANIUM" = "y" ]; then
 	define_bool CONFIG_IA64_BRL_EMU y
 	bool '  Enable Itanium B-step specific code' CONFIG_ITANIUM_BSTEP_SPECIFIC
-	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
+	define_int CONFIG_IA64_L1_CACHE_SHIFT 6 # align cache-sensitive data to 64 bytes
 fi
 
 if [ "$CONFIG_MCKINLEY" = "y" ]; then
@@ -66,17 +61,20 @@
 fi
 
 if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_DIG" = "y" -o "$CONFIG_IA64_HP_ZX1" = "y" ]; then
+	bool '  Enable NUMA support' CONFIG_NUMA
+	if [ "$CONFIG_NUMA" = "y" ]; then
+	  define_bool CONFIG_DISCONTIGMEM y
+	fi
 	bool '  Enable IA-64 Machine Check Abort' CONFIG_IA64_MCA
 	define_bool CONFIG_PM y
 fi
 
-if [ "$CONFIG_IA64_SGI_SN1" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ]; then
+if [ "$CONFIG_IA64_SGI_SN2" = "y" ]; then
 	define_bool CONFIG_IA64_SGI_SN y
 	bool '  Enable extra debugging code' CONFIG_IA64_SGI_SN_DEBUG
 	bool '  Enable SGI Medusa Simulator Support' CONFIG_IA64_SGI_SN_SIM
-	bool '  Enable autotest (llsc). Option to run cache test instead of booting' \
-			CONFIG_IA64_SGI_AUTOTEST
 	bool '  Enable protocol mode for the L1 console' CONFIG_SERIAL_SGI_L1_PROTOCOL
+	define_bool CONFIG_HWGFS_FS y
 	define_bool CONFIG_DISCONTIGMEM y
 	define_bool CONFIG_IA64_MCA y
 	define_bool CONFIG_NUMA y
@@ -86,7 +84,12 @@
 
 define_bool CONFIG_KCORE_ELF y	# On IA-64, we always want an ELF /proc/kcore.
 
+bool 'Use PAL_HALT_LIGHT in idle loop' CONFIG_IA64_PAL_IDLE
 bool 'SMP support' CONFIG_SMP
+if [ "$CONFIG_SMP" = "y" ]; then
+   int  'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32
+fi
+
 tristate 'Support running of Linux/x86 binaries' CONFIG_IA32_SUPPORT
 bool 'Performance monitor support' CONFIG_PERFMON
 tristate '/proc/pal support' CONFIG_IA64_PALINFO
@@ -290,4 +293,6 @@
    bool '  Turn on irq debug checks (slow!)' CONFIG_IA64_DEBUG_IRQ
 fi
 
+int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
+
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/configs/dig linux-2.4.23-pre8/arch/ia64/configs/dig
--- linux-2.4.22/arch/ia64/configs/dig	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/configs/dig	2003-10-22 22:49:06.000000000 +0000
@@ -38,6 +38,7 @@
 CONFIG_IA64_BRL_EMU=y
 # CONFIG_ITANIUM_BSTEP_SPECIFIC is not set
 CONFIG_IA64_L1_CACHE_SHIFT=6
+# CONFIG_NUMA is not set
 CONFIG_IA64_MCA=y
 CONFIG_PM=y
 CONFIG_KCORE_ELF=y
@@ -49,6 +50,7 @@
 # CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
+# CONFIG_IA64_PAL_IDLE is not set
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -270,7 +272,6 @@
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_PDC202XX_BURST is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_PDC202XX_FORCE is not set
 # CONFIG_BLK_DEV_RZ1000 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_SVWKS is not set
@@ -329,6 +330,9 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
@@ -406,6 +410,7 @@
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=y
 # CONFIG_TULIP_MWI is not set
@@ -445,6 +450,7 @@
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -656,6 +662,7 @@
 # File systems
 #
 # CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
@@ -665,6 +672,7 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
@@ -715,6 +723,7 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
@@ -916,6 +925,7 @@
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
+# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
@@ -939,8 +949,14 @@
 # CONFIG_USB_LCD is not set
 
 #
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
 # Library routines
 #
+# CONFIG_CRC32 is not set
 # CONFIG_ZLIB_INFLATE is not set
 # CONFIG_ZLIB_DEFLATE is not set
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/configs/generic linux-2.4.23-pre8/arch/ia64/configs/generic
--- linux-2.4.22/arch/ia64/configs/generic	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/configs/generic	2003-10-22 22:47:39.000000000 +0000
@@ -38,6 +38,7 @@
 CONFIG_IA64_BRL_EMU=y
 # CONFIG_ITANIUM_BSTEP_SPECIFIC is not set
 CONFIG_IA64_L1_CACHE_SHIFT=6
+# CONFIG_NUMA is not set
 CONFIG_IA64_MCA=y
 CONFIG_PM=y
 CONFIG_KCORE_ELF=y
@@ -49,6 +50,7 @@
 # CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
+# CONFIG_IA64_PAL_IDLE is not set
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -270,7 +272,6 @@
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_PDC202XX_BURST is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_PDC202XX_FORCE is not set
 # CONFIG_BLK_DEV_RZ1000 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_SVWKS is not set
@@ -329,6 +330,9 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
@@ -411,6 +415,7 @@
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=y
 # CONFIG_TULIP_MWI is not set
@@ -450,6 +455,7 @@
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -661,6 +667,7 @@
 # File systems
 #
 # CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
@@ -670,6 +677,7 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
@@ -720,6 +728,7 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
@@ -921,6 +930,7 @@
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
+# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
@@ -944,8 +954,14 @@
 # CONFIG_USB_LCD is not set
 
 #
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
 # Library routines
 #
+# CONFIG_CRC32 is not set
 # CONFIG_ZLIB_INFLATE is not set
 # CONFIG_ZLIB_DEFLATE is not set
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/configs/numa linux-2.4.23-pre8/arch/ia64/configs/numa
--- linux-2.4.22/arch/ia64/configs/numa	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/configs/numa	2003-10-22 22:49:03.000000000 +0000
@@ -0,0 +1,998 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+# CONFIG_KMOD is not set
+
+#
+# General setup
+#
+CONFIG_IA64=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ITANIUM=y
+# CONFIG_MCKINLEY is not set
+CONFIG_IA64_GENERIC=y
+# CONFIG_IA64_DIG is not set
+# CONFIG_IA64_HP_SIM is not set
+# CONFIG_IA64_HP_ZX1 is not set
+# CONFIG_IA64_SGI_SN1 is not set
+# CONFIG_IA64_SGI_SN2 is not set
+# CONFIG_IA64_PAGE_SIZE_4KB is not set
+# CONFIG_IA64_PAGE_SIZE_8KB is not set
+CONFIG_IA64_PAGE_SIZE_16KB=y
+CONFIG_IA64_BRL_EMU=y
+# CONFIG_ITANIUM_BSTEP_SPECIFIC is not set
+CONFIG_IA64_L1_CACHE_SHIFT=6
+CONFIG_NUMA=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_IA64_MCA=y
+CONFIG_PM=y
+CONFIG_KCORE_ELF=y
+CONFIG_FORCE_MAX_ZONEORDER=19
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_16MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
+CONFIG_IA64_PAL_IDLE=y
+CONFIG_SMP=y
+CONFIG_IA32_SUPPORT=y
+CONFIG_PERFMON=y
+CONFIG_IA64_PALINFO=y
+CONFIG_EFI_VARS=y
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_KERNEL_CONFIG=y
+
+#
+# ACPI Support
+#
+CONFIG_ACPI_PCI=y
+CONFIG_ACPI=y
+CONFIG_ACPI_EFI=y
+CONFIG_ACPI_BOOT=y
+CONFIG_ACPI_BUS=y
+CONFIG_ACPI_INTERPRETER=y
+CONFIG_ACPI_POWER=y
+CONFIG_ACPI_SYSTEM=y
+# CONFIG_ACPI_BUTTON is not set
+# CONFIG_ACPI_FAN is not set
+# CONFIG_ACPI_PROCESSOR is not set
+# CONFIG_ACPI_THERMAL is not set
+CONFIG_ACPI_NUMA=y
+# CONFIG_ACPI_DEBUG is not set
+CONFIG_PCI=y
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Fusion MPT device support
+#
+CONFIG_FUSION=y
+CONFIG_FUSION_BOOT=y
+CONFIG_FUSION_MAX_SGE=40
+# CONFIG_FUSION_ISENSE is not set
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LAN is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=y
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_BLK_DEV_GENERIC is not set
+CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_ADMA100 is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_SII is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_SR_EXTRA_DEVS=2
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_DEBUG_QUEUES=y
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
+CONFIG_SCSI_AIC7XXX=y
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_PROBE_EISA_VL is not set
+# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+CONFIG_SCSI_SYM53C8XX=y
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+CONFIG_SCSI_NCR53C8XX_SYNC=20
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
+# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+CONFIG_SCSI_QLOGIC_1280=y
+# CONFIG_SCSI_QLOGIC_QLA2100 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_CS89x0 is not set
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=y
+# CONFIG_EEPRO100_PIO is not set
+# CONFIG_E100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_SUNDANCE_MMIO is not set
+# CONFIG_TLAN is not set
+# CONFIG_TC35815 is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+CONFIG_TIGON3=y
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+CONFIG_SERIAL_HCDP=y
+CONFIG_SERIAL_ACPI=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+CONFIG_INPUT_SERIO=y
+CONFIG_INPUT_SERPORT=y
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_EFI_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+CONFIG_AGP=y
+# CONFIG_AGP_INTEL is not set
+# CONFIG_AGP_I810 is not set
+# CONFIG_AGP_VIA is not set
+# CONFIG_AGP_AMD is not set
+# CONFIG_AGP_AMD_8151 is not set
+# CONFIG_AGP_SIS is not set
+# CONFIG_AGP_ALI is not set
+# CONFIG_AGP_SWORKS is not set
+CONFIG_AGP_I460=y
+CONFIG_AGP_HP_ZX1=y
+CONFIG_DRM=y
+# CONFIG_DRM_OLD is not set
+
+#
+# DRM 4.1 drivers
+#
+CONFIG_DRM_NEW=y
+# CONFIG_DRM_TDFX is not set
+CONFIG_DRM_R128=y
+CONFIG_DRM_RADEON=y
+# CONFIG_DRM_I810 is not set
+# CONFIG_DRM_I810_XFREE_41 is not set
+# CONFIG_DRM_I830 is not set
+# CONFIG_DRM_MGA is not set
+# CONFIG_DRM_SIS is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=y
+
+#
+# Video For Linux
+#
+CONFIG_VIDEO_PROC_FS=y
+# CONFIG_I2C_PARPORT is not set
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_ZORAN_BUZ is not set
+# CONFIG_VIDEO_ZORAN_DC10 is not set
+# CONFIG_VIDEO_ZORAN_LML33 is not set
+# CONFIG_VIDEO_ZR36120 is not set
+# CONFIG_VIDEO_MEYE is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_RADIO_MIROPCM20 is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
+CONFIG_JBD_DEBUG=y
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+CONFIG_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+CONFIG_SOUND_CS4281=y
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_UHCI=y
+# CONFIG_USB_UHCI_ALT is not set
+CONFIG_USB_OHCI=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_MIDI is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_AX8817X is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_TIGL is not set
+# CONFIG_USB_BRLVGER is not set
+# CONFIG_USB_LCD is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Simulated drivers
+#
+# CONFIG_HP_SIMETH is not set
+# CONFIG_HP_SIMSERIAL is not set
+# CONFIG_HP_SIMSCSI is not set
+
+#
+# Kernel hacking
+#
+CONFIG_IA64_GRANULE_16MB=y
+# CONFIG_IA64_GRANULE_64MB is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_IA64_PRINT_HAZARDS=y
+# CONFIG_DISABLE_VHPT is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_IA64_EARLY_PRINTK=y
+CONFIG_IA64_EARLY_PRINTK_UART=y
+CONFIG_IA64_EARLY_PRINTK_UART_BASE=0
+# CONFIG_IA64_EARLY_PRINTK_VGA is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_IA64_DEBUG_CMPXCHG is not set
+# CONFIG_IA64_DEBUG_IRQ is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/configs/ski linux-2.4.23-pre8/arch/ia64/configs/ski
--- linux-2.4.22/arch/ia64/configs/ski	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/configs/ski	2003-10-22 22:48:13.000000000 +0000
@@ -47,6 +47,7 @@
 # CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
+CONFIG_IA64_PAL_IDLE=y
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -152,12 +153,9 @@
 # CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AACRAID is not set
-CONFIG_SCSI_AIC7XXX=y
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
-CONFIG_AIC7XXX_RESET_DELAY_MS=15000
-# CONFIG_AIC7XXX_PROBE_EISA_VL is not set
-# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -311,6 +309,7 @@
 # File systems
 #
 # CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
@@ -320,6 +319,7 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
@@ -370,6 +370,7 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/configs/zx1 linux-2.4.23-pre8/arch/ia64/configs/zx1
--- linux-2.4.22/arch/ia64/configs/zx1	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/configs/zx1	2003-10-22 22:49:22.000000000 +0000
@@ -37,6 +37,7 @@
 CONFIG_IA64_PAGE_SIZE_16KB=y
 # CONFIG_IA64_PAGE_SIZE_64KB is not set
 CONFIG_IA64_L1_CACHE_SHIFT=7
+# CONFIG_NUMA is not set
 CONFIG_IA64_MCA=y
 CONFIG_PM=y
 CONFIG_KCORE_ELF=y
@@ -50,6 +51,7 @@
 # CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
+CONFIG_IA64_PAL_IDLE=y
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -271,7 +273,6 @@
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_PDC202XX_BURST is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_PDC202XX_FORCE is not set
 # CONFIG_BLK_DEV_RZ1000 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_SVWKS is not set
@@ -330,6 +331,9 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
@@ -407,6 +411,7 @@
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=y
 # CONFIG_TULIP_MWI is not set
@@ -446,6 +451,7 @@
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -657,6 +663,7 @@
 # File systems
 #
 # CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
@@ -666,6 +673,7 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
@@ -716,6 +724,7 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
@@ -917,6 +926,7 @@
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
+# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
@@ -940,8 +950,14 @@
 # CONFIG_USB_LCD is not set
 
 #
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
 # Library routines
 #
+# CONFIG_CRC32 is not set
 # CONFIG_ZLIB_INFLATE is not set
 # CONFIG_ZLIB_DEFLATE is not set
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/defconfig linux-2.4.23-pre8/arch/ia64/defconfig
--- linux-2.4.22/arch/ia64/defconfig	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/defconfig	2003-10-22 22:47:41.000000000 +0000
@@ -38,6 +38,7 @@
 CONFIG_IA64_BRL_EMU=y
 # CONFIG_ITANIUM_BSTEP_SPECIFIC is not set
 CONFIG_IA64_L1_CACHE_SHIFT=6
+# CONFIG_NUMA is not set
 CONFIG_IA64_MCA=y
 CONFIG_PM=y
 CONFIG_KCORE_ELF=y
@@ -49,7 +50,9 @@
 # CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
+# CONFIG_IA64_PAL_IDLE is not set
 CONFIG_SMP=y
+CONFIG_NR_CPUS=32
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
@@ -270,7 +273,6 @@
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_PDC202XX_BURST is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_PDC202XX_FORCE is not set
 # CONFIG_BLK_DEV_RZ1000 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_SVWKS is not set
@@ -329,6 +331,9 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
@@ -411,6 +416,7 @@
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
 # CONFIG_CS89x0 is not set
 CONFIG_TULIP=y
 # CONFIG_TULIP_MWI is not set
@@ -450,6 +456,7 @@
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -661,6 +668,7 @@
 # File systems
 #
 # CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
@@ -670,6 +678,7 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
@@ -720,6 +729,7 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
@@ -921,6 +931,7 @@
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
+# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
@@ -944,8 +955,14 @@
 # CONFIG_USB_LCD is not set
 
 #
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
 # Library routines
 #
+# CONFIG_CRC32 is not set
 # CONFIG_ZLIB_INFLATE is not set
 # CONFIG_ZLIB_DEFLATE is not set
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/drivers/Makefile linux-2.4.23-pre8/arch/ia64/drivers/Makefile
--- linux-2.4.22/arch/ia64/drivers/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/drivers/Makefile	2003-10-22 22:49:10.000000000 +0000
@@ -0,0 +1,13 @@
+#
+# ia64/drivers/Makefile
+#
+# Copyright (C) 2003 Hewlett-Packard Co.
+#	Bjorn Helgaas <bjorn.helgaas@hp.com>
+
+O_TARGET := drivers.o
+
+obj-$(CONFIG_HP_SIMETH) += simeth.o
+obj-$(CONFIG_HP_SIMSERIAL) += simserial.o
+obj-$(CONFIG_HP_SIMSCSI) += simscsi.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/drivers/simeth.c linux-2.4.23-pre8/arch/ia64/drivers/simeth.c
--- linux-2.4.22/arch/ia64/drivers/simeth.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/drivers/simeth.c	2003-10-22 22:47:27.000000000 +0000
@@ -0,0 +1,537 @@
+/*
+ * Simulated Ethernet Driver
+ *
+ * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/in.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <linux/skbuff.h>
+#include <linux/notifier.h>
+#include <asm/bitops.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+
+#define SIMETH_RECV_MAX	10
+
+/*
+ * Maximum possible received frame for Ethernet.
+ * We preallocate an sk_buff of that size to avoid costly
+ * memcpy for temporary buffer into sk_buff. We do basically
+ * what's done in other drivers, like eepro with a ring.
+ * The difference is, of course, that we don't have real DMA !!!
+ */
+#define SIMETH_FRAME_SIZE	ETH_FRAME_LEN
+
+
+#define SSC_NETDEV_PROBE		100
+#define SSC_NETDEV_SEND			101
+#define SSC_NETDEV_RECV			102
+#define SSC_NETDEV_ATTACH		103
+#define SSC_NETDEV_DETACH		104
+
+#define NETWORK_INTR			8
+
+struct simeth_local {
+	struct net_device_stats stats;
+	int 			simfd;	 /* descriptor in the simulator */
+};
+
+static int simeth_probe1(void);
+static int simeth_open(struct net_device *dev);
+static int simeth_close(struct net_device *dev);
+static int simeth_tx(struct sk_buff *skb, struct net_device *dev);
+static int simeth_rx(struct net_device *dev);
+static struct net_device_stats *simeth_get_stats(struct net_device *dev);
+static void simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static void set_multicast_list(struct net_device *dev);
+static int simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr);
+
+static char *simeth_version="0.3";
+
+/*
+ * This variable is used to establish a mapping between the Linux/ia64 kernel
+ * and the host linux kernel.
+ *
+ * As of today, we support only one card, even though most of the code
+ * is ready for many more. The mapping is then:
+ *	linux/ia64 -> linux/x86
+ * 	   eth0    -> eth1
+ *
+ * In the future, we some string operations, we could easily support up
+ * to 10 cards (0-9).
+ *
+ * The default mapping can be changed on the kernel command line by
+ * specifying simeth=ethX (or whatever string you want).
+ */
+static char *simeth_device="eth0";	 /* default host interface to use */
+
+
+
+static volatile unsigned int card_count; /* how many cards "found" so far */
+static int simeth_debug;		/* set to 1 to get debug information */
+
+/*
+ * Used to catch IFF_UP & IFF_DOWN events
+ */
+static struct notifier_block simeth_dev_notifier = {
+	simeth_device_event,
+	0
+};
+
+
+/*
+ * Function used when using a kernel command line option.
+ *
+ * Format: simeth=interface_name (like eth0)
+ */
+static int __init
+simeth_setup(char *str)
+{
+	simeth_device = str;
+	return 1;
+}
+
+__setup("simeth=", simeth_setup);
+
+/*
+ * Function used to probe for simeth devices when not installed
+ * as a loadable module
+ */
+
+int __init
+simeth_probe (void)
+{
+	int r;
+
+	printk(KERN_INFO "simeth: v%s\n", simeth_version);
+
+	r = simeth_probe1();
+
+	if (r == 0) register_netdevice_notifier(&simeth_dev_notifier);
+
+	return r;
+}
+
+extern long ia64_ssc (long, long, long, long, int);
+extern void ia64_ssc_connect_irq (long intr, long irq);
+
+static inline int
+netdev_probe(char *name, unsigned char *ether)
+{
+	return ia64_ssc(__pa(name), __pa(ether), 0,0, SSC_NETDEV_PROBE);
+}
+
+
+static inline int
+netdev_connect(int irq)
+{
+	/* XXX Fix me
+	 * this does not support multiple cards
+	 * also no return value
+	 */
+	ia64_ssc_connect_irq(NETWORK_INTR, irq);
+	return 0;
+}
+
+static inline int
+netdev_attach(int fd, int irq, unsigned int ipaddr)
+{
+	/* this puts the host interface in the right mode (start interrupting) */
+	return ia64_ssc(fd, ipaddr, 0,0, SSC_NETDEV_ATTACH);
+}
+
+
+static inline int
+netdev_detach(int fd)
+{
+	/*
+	 * inactivate the host interface (don't interrupt anymore) */
+	return ia64_ssc(fd, 0,0,0, SSC_NETDEV_DETACH);
+}
+
+static inline int
+netdev_send(int fd, unsigned char *buf, unsigned int len)
+{
+	return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_SEND);
+}
+
+static inline int
+netdev_read(int fd, unsigned char *buf, unsigned int len)
+{
+	return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_RECV);
+}
+
+/*
+ * Function shared with module code, so cannot be in init section
+ *
+ * So far this function "detects" only one card (test_&_set) but could
+ * be extended easily.
+ *
+ * Return:
+ * 	- -ENODEV is no device found
+ *	- -ENOMEM is no more memory
+ *	- 0 otherwise
+ */
+static int
+simeth_probe1(void)
+{
+	unsigned char mac_addr[ETH_ALEN];
+	struct simeth_local *local;
+	struct net_device *dev;
+	int fd, i;
+
+	/*
+	 * XXX Fix me
+	 * let's support just one card for now
+	 */
+	if (test_and_set_bit(0, &card_count))
+		return -ENODEV;
+
+	/*
+	 * check with the simulator for the device
+	 */
+	fd = netdev_probe(simeth_device, mac_addr);
+	if (fd == -1)
+		return -ENODEV;
+
+	dev = init_etherdev(NULL, sizeof(struct simeth_local));
+	if (!dev)
+		return -ENOMEM;
+
+	memcpy(dev->dev_addr, mac_addr, sizeof(mac_addr));
+
+	dev->irq = ia64_alloc_vector();
+
+	/*
+	 * attach the interrupt in the simulator, this does enable interrupts
+	 * until a netdev_attach() is called
+	 */
+	netdev_connect(dev->irq);
+
+	memset(dev->priv, 0, sizeof(struct simeth_local));
+
+	local = dev->priv;
+	local->simfd = fd; /* keep track of underlying file descriptor */
+
+	dev->open		= simeth_open;
+	dev->stop		= simeth_close;
+	dev->hard_start_xmit	= simeth_tx;
+	dev->get_stats		= simeth_get_stats;
+	dev->set_multicast_list = set_multicast_list; /* no yet used */
+
+	/* Fill in the fields of the device structure with ethernet-generic values. */
+	ether_setup(dev);
+
+	printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr",
+	       dev->name, simeth_device, local->simfd);
+	for(i = 0; i < ETH_ALEN; i++) {
+		printk(" %2.2x", dev->dev_addr[i]);
+	}
+	printk(", IRQ %d\n", dev->irq);
+
+	return 0;
+}
+
+/*
+ * actually binds the device to an interrupt vector
+ */
+static int
+simeth_open(struct net_device *dev)
+{
+	if (request_irq(dev->irq, simeth_interrupt, 0, "simeth", dev)) {
+		printk(KERN_WARNING "simeth: unable to get IRQ %d.\n", dev->irq);
+		return -EAGAIN;
+	}
+
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+/* copied from lapbether.c */
+static __inline__ int dev_is_ethdev(struct net_device *dev)
+{
+       return ( dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5));
+}
+
+
+/*
+ * Handler for IFF_UP or IFF_DOWN
+ *
+ * The reason for that is that we don't want to be interrupted when the
+ * interface is down. There is no way to unconnect in the simualtor. Instead
+ * we use this function to shutdown packet processing in the frame filter
+ * in the simulator. Thus no interrupts are generated
+ *
+ *
+ * That's also the place where we pass the IP address of this device to the
+ * simulator so that that we can start filtering packets for it
+ *
+ * There may be a better way of doing this, but I don't know which yet.
+ */
+static int
+simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
+{
+	struct net_device *dev = (struct net_device *)ptr;
+	struct simeth_local *local;
+	struct in_device *in_dev;
+	struct in_ifaddr **ifap = NULL;
+	struct in_ifaddr *ifa = NULL;
+	int r;
+
+
+	if ( ! dev ) {
+		printk(KERN_WARNING "simeth_device_event dev=0\n");
+		return NOTIFY_DONE;
+	}
+
+	if ( event != NETDEV_UP && event != NETDEV_DOWN ) return NOTIFY_DONE;
+
+	/*
+	 * Check whether or not it's for an ethernet device
+	 *
+	 * XXX Fixme: This works only as long as we support one
+	 * type of ethernet device.
+	 */
+	if ( !dev_is_ethdev(dev) ) return NOTIFY_DONE;
+
+	if ((in_dev=dev->ip_ptr) != NULL) {
+		for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
+			if (strcmp(dev->name, ifa->ifa_label) == 0) break;
+	}
+	if ( ifa == NULL ) {
+		printk(KERN_ERR "simeth_open: can't find device %s's ifa\n", dev->name);
+		return NOTIFY_DONE;
+	}
+
+	printk(KERN_INFO "simeth_device_event: %s ipaddr=0x%x\n",
+	       dev->name, htonl(ifa->ifa_local));
+
+	/*
+	 * XXX Fix me
+	 * if the device was up, and we're simply reconfiguring it, not sure
+	 * we get DOWN then UP.
+	 */
+
+	local = dev->priv;
+	/* now do it for real */
+	r = event == NETDEV_UP ?
+		netdev_attach(local->simfd, dev->irq, htonl(ifa->ifa_local)):
+		netdev_detach(local->simfd);
+
+	printk(KERN_INFO "simeth: netdev_attach/detach: event=%s ->%d\n",
+	       event == NETDEV_UP ? "attach":"detach", r);
+
+	return NOTIFY_DONE;
+}
+
+static int
+simeth_close(struct net_device *dev)
+{
+	netif_stop_queue(dev);
+
+	free_irq(dev->irq, dev);
+
+	return 0;
+}
+
+/*
+ * Only used for debug
+ */
+static void
+frame_print(unsigned char *from, unsigned char *frame, int len)
+{
+	int i;
+
+	printk("%s: (%d) %02x", from, len, frame[0] & 0xff);
+	for(i=1; i < 6; i++ ) {
+		printk(":%02x", frame[i] &0xff);
+	}
+	printk(" %2x", frame[6] &0xff);
+	for(i=7; i < 12; i++ ) {
+		printk(":%02x", frame[i] &0xff);
+	}
+	printk(" [%02x%02x]\n", frame[12], frame[13]);
+
+	for(i=14; i < len; i++ ) {
+		printk("%02x ", frame[i] &0xff);
+		if ( (i%10)==0) printk("\n");
+	}
+	printk("\n");
+}
+
+
+/*
+ * Function used to transmit of frame, very last one on the path before
+ * going to the simulator.
+ */
+static int
+simeth_tx(struct sk_buff *skb, struct net_device *dev)
+{
+	struct simeth_local *local = (struct simeth_local *)dev->priv;
+
+#if 0
+	/* ensure we have at least ETH_ZLEN bytes (min frame size) */
+	unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+	/* Where do the extra padding bytes comes from inthe skbuff ? */
+#else
+	/* the real driver in the host system is going to take care of that
+	 * or maybe it's the NIC itself.
+	 */
+	unsigned int length = skb->len;
+#endif
+
+	local->stats.tx_bytes += skb->len;
+	local->stats.tx_packets++;
+
+
+	if (simeth_debug > 5) frame_print("simeth_tx", skb->data, length);
+
+	netdev_send(local->simfd, skb->data, length);
+
+	/*
+	 * we are synchronous on write, so we don't simulate a
+	 * trasnmit complete interrupt, thus we don't need to arm a tx
+	 */
+
+	dev_kfree_skb(skb);
+	return 0;
+}
+
+static inline struct sk_buff *
+make_new_skb(struct net_device *dev)
+{
+	struct sk_buff *nskb;
+
+	/*
+	 * The +2 is used to make sure that the IP header is nicely
+	 * aligned (on 4byte boundary I assume 14+2=16)
+	 */
+	nskb = dev_alloc_skb(SIMETH_FRAME_SIZE + 2);
+	if ( nskb == NULL ) {
+		printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name);
+		return NULL;
+	}
+	nskb->dev = dev;
+
+	skb_reserve(nskb, 2);	/* Align IP on 16 byte boundaries */
+
+	skb_put(nskb,SIMETH_FRAME_SIZE);
+
+	return nskb;
+}
+
+/*
+ * called from interrupt handler to process a received frame
+ */
+static int
+simeth_rx(struct net_device *dev)
+{
+	struct simeth_local	*local;
+	struct sk_buff		*skb;
+	int			len;
+	int			rcv_count = SIMETH_RECV_MAX;
+
+	local = (struct simeth_local *)dev->priv;
+	/*
+	 * the loop concept has been borrowed from other drivers
+	 * looks to me like it's a throttling thing to avoid pushing to many
+	 * packets at one time into the stack. Making sure we can process them
+	 * upstream and make forward progress overall
+	 */
+	do {
+		if ( (skb=make_new_skb(dev)) == NULL ) {
+			printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name);
+			local->stats.rx_dropped++;
+			return 0;
+		}
+		/*
+		 * Read only one frame at a time
+		 */
+		len = netdev_read(local->simfd, skb->data, SIMETH_FRAME_SIZE);
+		if ( len == 0 ) {
+			if ( simeth_debug > 0 ) printk(KERN_WARNING "%s: count=%d netdev_read=0\n",
+						       dev->name, SIMETH_RECV_MAX-rcv_count);
+			break;
+		}
+#if 0
+		/*
+		 * XXX Fix me
+		 * Should really do a csum+copy here
+		 */
+		memcpy(skb->data, frame, len);
+#endif
+		skb->protocol = eth_type_trans(skb, dev);
+
+		if ( simeth_debug > 6 ) frame_print("simeth_rx", skb->data, len);
+
+		/*
+		 * push the packet up & trigger software interrupt
+		 */
+		netif_rx(skb);
+
+		local->stats.rx_packets++;
+		local->stats.rx_bytes += len;
+
+	} while ( --rcv_count );
+
+	return len; /* 0 = nothing left to read, otherwise, we can try again */
+}
+
+/*
+ * Interrupt handler (Yes, we can do it too !!!)
+ */
+static void
+simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev = dev_id;
+
+	if ( dev == NULL ) {
+		printk(KERN_WARNING "simeth: irq %d for unknown device\n", irq);
+		return;
+	}
+
+	/*
+	 * very simple loop because we get interrupts only when receiving
+	 */
+	while (simeth_rx(dev));
+}
+
+static struct net_device_stats *
+simeth_get_stats(struct net_device *dev)
+{
+	struct simeth_local  *local = (struct simeth_local *) dev->priv;
+
+	return &local->stats;
+}
+
+/* fake multicast ability */
+static void
+set_multicast_list(struct net_device *dev)
+{
+	printk(KERN_WARNING "%s: set_multicast_list called\n", dev->name);
+}
+
+#ifdef CONFIG_NET_FASTROUTE
+static int
+simeth_accept_fastpath(struct net_device *dev, struct dst_entry *dst)
+{
+	printk(KERN_WARNING "%s: simeth_accept_fastpath called\n", dev->name);
+	return -1;
+}
+#endif
+
+__initcall(simeth_probe);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/drivers/simscsi.c linux-2.4.23-pre8/arch/ia64/drivers/simscsi.c
--- linux-2.4.22/arch/ia64/drivers/simscsi.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/drivers/simscsi.c	2003-10-22 22:48:57.000000000 +0000
@@ -0,0 +1,396 @@
+/*
+ * Simulated SCSI driver.
+ *
+ * Copyright (C) 1999, 2001-2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ *
+ * 02/01/15 David Mosberger	Updated for v2.5.1
+ * 99/12/18 David Mosberger	Added support for READ10/WRITE10 needed by linux v2.3.33
+ */
+#include <linux/config.h>
+#include <linux/blk.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+
+#include <scsi/scsi.h>
+
+#include <asm/irq.h>
+
+#include "../drivers/scsi/scsi.h"
+#include "../drivers/scsi/sd.h"
+#include "../drivers/scsi/hosts.h"
+#include "simscsi.h"
+
+#define DEBUG_SIMSCSI	1
+
+/* Simulator system calls: */
+
+#define SSC_OPEN			50
+#define SSC_CLOSE			51
+#define SSC_READ			52
+#define SSC_WRITE			53
+#define SSC_GET_COMPLETION		54
+#define SSC_WAIT_COMPLETION		55
+
+#define SSC_WRITE_ACCESS		2
+#define SSC_READ_ACCESS			1
+
+#if DEBUG_SIMSCSI
+  int simscsi_debug;
+# define DBG	simscsi_debug
+#else
+# define DBG	0
+#endif
+
+static void simscsi_interrupt (unsigned long val);
+DECLARE_TASKLET(simscsi_tasklet, simscsi_interrupt, 0);
+
+struct disk_req {
+	unsigned long addr;
+	unsigned len;
+};
+
+struct disk_stat {
+	int fd;
+	unsigned count;
+};
+
+extern long ia64_ssc (long arg0, long arg1, long arg2, long arg3, int nr);
+
+static int desc[16] = {
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+static struct queue_entry {
+	Scsi_Cmnd *sc;
+} queue[SIMSCSI_REQ_QUEUE_LEN];
+
+static int rd, wr;
+static atomic_t num_reqs = ATOMIC_INIT(0);
+
+/* base name for default disks */
+static char *simscsi_root = DEFAULT_SIMSCSI_ROOT;
+
+#define MAX_ROOT_LEN	128
+
+/*
+ * used to setup a new base for disk images
+ * to use /foo/bar/disk[a-z] as disk images
+ * you have to specify simscsi=/foo/bar/disk on the command line
+ */
+static int __init
+simscsi_setup (char *s)
+{
+	/* XXX Fix me we may need to strcpy() ? */
+	if (strlen(s) > MAX_ROOT_LEN) {
+		printk(KERN_ERR "simscsi_setup: prefix too long---using default %s\n",
+		       simscsi_root);
+	}
+	simscsi_root = s;
+	return 1;
+}
+
+__setup("simscsi=", simscsi_setup);
+
+static void
+simscsi_interrupt (unsigned long val)
+{
+	unsigned long flags;
+	Scsi_Cmnd *sc;
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	{
+		while ((sc = queue[rd].sc) != 0) {
+			atomic_dec(&num_reqs);
+			queue[rd].sc = 0;
+			if (DBG)
+				printk("simscsi_interrupt: done with %ld\n", sc->serial_number);
+			(*sc->scsi_done)(sc);
+			rd = (rd + 1) % SIMSCSI_REQ_QUEUE_LEN;
+		}
+	}
+	spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
+int
+simscsi_detect (Scsi_Host_Template *templ)
+{
+	templ->proc_name = "simscsi";
+	return 1;	/* fake one SCSI host adapter */
+}
+
+int
+simscsi_release (struct Scsi_Host *host)
+{
+	return 0;	/* this is easy...  */
+}
+
+const char *
+simscsi_info (struct Scsi_Host *host)
+{
+	return "simulated SCSI host adapter";
+}
+
+int
+simscsi_biosparam (Disk *disk, kdev_t n, int ip[])
+{
+	unsigned capacity = disk->capacity;
+
+	ip[0] = 64;		/* heads */
+	ip[1] = 32;		/* sectors */
+	ip[2] = capacity >> 11;	/* cylinders */
+	return 0;
+}
+
+static void
+simscsi_readwrite (Scsi_Cmnd *sc, int mode, unsigned long offset, unsigned long len)
+{
+	struct disk_stat stat;
+	struct disk_req req;
+
+	req.addr = __pa(sc->request_buffer);
+	req.len  = len;			/* # of bytes to transfer */
+
+	if (sc->request_bufflen < req.len)
+		return;
+
+	stat.fd = desc[sc->target];
+	if (DBG)
+		printk("simscsi_%s @ %lx (off %lx)\n",
+		       mode == SSC_READ ? "read":"write", req.addr, offset);
+	ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
+	ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
+
+	if (stat.count == req.len) {
+		sc->result = GOOD;
+	} else {
+		sc->result = DID_ERROR << 16;
+	}
+}
+
+static void
+simscsi_sg_readwrite (Scsi_Cmnd *sc, int mode, unsigned long offset)
+{
+	int list_len = sc->use_sg;
+	struct scatterlist *sl = (struct scatterlist *)sc->buffer;
+	struct disk_stat stat;
+	struct disk_req req;
+
+	stat.fd = desc[sc->target];
+
+	while (list_len) {
+		req.addr = __pa(sl->address);
+		req.len  = sl->length;
+		if (DBG)
+			printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
+			       mode == SSC_READ ? "read":"write", req.addr, offset,
+			       list_len, sl->length);
+		ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
+		ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
+
+		/* should not happen in our case */
+		if (stat.count != req.len) {
+			sc->result = DID_ERROR << 16;
+			return;
+		}
+		offset +=  sl->length;
+		sl++;
+		list_len--;
+	}
+	sc->result = GOOD;
+}
+
+/*
+ * function handling both READ_6/WRITE_6 (non-scatter/gather mode)
+ * commands.
+ * Added 02/26/99 S.Eranian
+ */
+static void
+simscsi_readwrite6 (Scsi_Cmnd *sc, int mode)
+{
+	unsigned long offset;
+
+	offset = (((sc->cmnd[1] & 0x1f) << 16) | (sc->cmnd[2] << 8) | sc->cmnd[3])*512;
+	if (sc->use_sg > 0)
+		simscsi_sg_readwrite(sc, mode, offset);
+	else
+		simscsi_readwrite(sc, mode, offset, sc->cmnd[4]*512);
+}
+
+static size_t
+simscsi_get_disk_size (int fd)
+{
+	struct disk_stat stat;
+	size_t bit, sectors = 0;
+	struct disk_req req;
+	char buf[512];
+
+	/*
+	 * This is a bit kludgey: the simulator doesn't provide a direct way of determining
+	 * the disk size, so we do a binary search, assuming a maximum disk size of 4GB.
+	 */
+	for (bit = (4UL << 30)/512; bit != 0; bit >>= 1) {
+		req.addr = __pa(&buf);
+		req.len = sizeof(buf);
+		ia64_ssc(fd, 1, __pa(&req), ((sectors | bit) - 1)*512, SSC_READ);
+		stat.fd = fd;
+		ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
+		if (stat.count == sizeof(buf))
+			sectors |= bit;
+	}
+	return sectors - 1;	/* return last valid sector number */
+}
+
+static void
+simscsi_readwrite10 (Scsi_Cmnd *sc, int mode)
+{
+	unsigned long offset;
+
+	offset = (  (sc->cmnd[2] << 24) | (sc->cmnd[3] << 16)
+		  | (sc->cmnd[4] <<  8) | (sc->cmnd[5] <<  0))*512;
+	if (sc->use_sg > 0)
+		simscsi_sg_readwrite(sc, mode, offset);
+	else
+		simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512);
+}
+
+int
+simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *))
+{
+	char fname[MAX_ROOT_LEN+16];
+	size_t disk_size;
+	char *buf;
+#if DEBUG_SIMSCSI
+	register long sp asm ("sp");
+
+	if (DBG)
+		printk("simscsi_queuecommand: target=%d,cmnd=%u,sc=%lu,sp=%lx,done=%p\n",
+		       sc->target, sc->cmnd[0], sc->serial_number, sp, done);
+#endif
+
+	sc->result = DID_BAD_TARGET << 16;
+	sc->scsi_done = done;
+	if (sc->target <= 15 && sc->lun == 0) {
+		switch (sc->cmnd[0]) {
+		      case INQUIRY:
+			if (sc->request_bufflen < 35) {
+				break;
+			}
+			sprintf (fname, "%s%c", simscsi_root, 'a' + sc->target);
+			desc[sc->target] = ia64_ssc(__pa(fname), SSC_READ_ACCESS|SSC_WRITE_ACCESS,
+						    0, 0, SSC_OPEN);
+			if (desc[sc->target] < 0) {
+				/* disk doesn't exist... */
+				break;
+			}
+			buf = sc->request_buffer;
+			buf[0] = 0;	/* magnetic disk */
+			buf[1] = 0;	/* not a removable medium */
+			buf[2] = 2;	/* SCSI-2 compliant device */
+			buf[3] = 2;	/* SCSI-2 response data format */
+			buf[4] = 31;	/* additional length (bytes) */
+			buf[5] = 0;	/* reserved */
+			buf[6] = 0;	/* reserved */
+			buf[7] = 0;	/* various flags */
+			memcpy(buf + 8, "HP      SIMULATED DISK  0.00",  28);
+			sc->result = GOOD;
+			break;
+
+		      case TEST_UNIT_READY:
+			sc->result = GOOD;
+			break;
+
+		      case READ_6:
+			if (desc[sc->target] < 0 )
+				break;
+			simscsi_readwrite6(sc, SSC_READ);
+			break;
+
+		      case READ_10:
+			if (desc[sc->target] < 0 )
+				break;
+			simscsi_readwrite10(sc, SSC_READ);
+			break;
+
+		      case WRITE_6:
+			if (desc[sc->target] < 0)
+				break;
+			simscsi_readwrite6(sc, SSC_WRITE);
+			break;
+
+		      case WRITE_10:
+			if (desc[sc->target] < 0)
+				break;
+			simscsi_readwrite10(sc, SSC_WRITE);
+			break;
+
+
+		      case READ_CAPACITY:
+			if (desc[sc->target] < 0 || sc->request_bufflen < 8) {
+				break;
+			}
+			buf = sc->request_buffer;
+
+			disk_size = simscsi_get_disk_size(desc[sc->target]);
+			buf[0] = (disk_size >> 24) & 0xff;
+			buf[1] = (disk_size >> 16) & 0xff;
+			buf[2] = (disk_size >>  8) & 0xff;
+			buf[3] = (disk_size >>  0) & 0xff;
+			/* set block size of 512 bytes: */
+			buf[4] = 0;
+			buf[5] = 0;
+			buf[6] = 2;
+			buf[7] = 0;
+			sc->result = GOOD;
+			break;
+
+		      case MODE_SENSE:
+			/* sd.c uses this to determine whether disk does write-caching. */
+			memset(sc->request_buffer, 0, 128);
+			sc->result = GOOD;
+			break;
+
+		      case START_STOP:
+			printk(KERN_ERR "START_STOP\n");
+			break;
+
+		      default:
+			panic("simscsi: unknown SCSI command %u\n", sc->cmnd[0]);
+		}
+	}
+	if (sc->result == DID_BAD_TARGET) {
+		sc->result |= DRIVER_SENSE << 24;
+		sc->sense_buffer[0] = 0x70;
+		sc->sense_buffer[2] = 0x00;
+	}
+	if (atomic_read(&num_reqs) >= SIMSCSI_REQ_QUEUE_LEN) {
+		panic("Attempt to queue command while command is pending!!");
+	}
+	atomic_inc(&num_reqs);
+	queue[wr].sc = sc;
+	wr = (wr + 1) % SIMSCSI_REQ_QUEUE_LEN;
+
+	tasklet_schedule(&simscsi_tasklet);
+	return 0;
+}
+
+int
+simscsi_reset (Scsi_Cmnd *cmd, unsigned int reset_flags)
+{
+	printk(KERN_ERR "simscsi_reset: unimplemented\n");
+	return SCSI_RESET_SUCCESS;
+}
+
+int
+simscsi_abort (Scsi_Cmnd *cmd)
+{
+	printk(KERN_ERR "simscsi_abort: unimplemented\n");
+	return SCSI_ABORT_SUCCESS;
+}
+
+static Scsi_Host_Template driver_template = SIMSCSI;
+
+#include "../drivers/scsi/scsi_module.c"
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/drivers/simscsi.h linux-2.4.23-pre8/arch/ia64/drivers/simscsi.h
--- linux-2.4.22/arch/ia64/drivers/simscsi.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/drivers/simscsi.h	2003-10-22 22:49:00.000000000 +0000
@@ -0,0 +1,39 @@
+/*
+ * Simulated SCSI driver.
+ *
+ * Copyright (C) 1999, 2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+#ifndef SIMSCSI_H
+#define SIMSCSI_H
+
+#define SIMSCSI_REQ_QUEUE_LEN	64
+
+#define DEFAULT_SIMSCSI_ROOT	"/var/ski-disks/sd"
+
+extern int simscsi_detect (Scsi_Host_Template *);
+extern int simscsi_release (struct Scsi_Host *);
+extern const char *simscsi_info (struct Scsi_Host *);
+extern int simscsi_queuecommand (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+extern int simscsi_abort (Scsi_Cmnd *);
+extern int simscsi_reset (Scsi_Cmnd *, unsigned int);
+extern int simscsi_biosparam (Disk *, kdev_t, int[]);
+
+#define SIMSCSI {						\
+	.detect			= simscsi_detect,		\
+	.release		= simscsi_release,		\
+	.info			= simscsi_info,			\
+	.queuecommand		= simscsi_queuecommand,		\
+	.abort			= simscsi_abort,		\
+	.reset			= simscsi_reset,		\
+	.bios_param		= simscsi_biosparam,		\
+	.can_queue		= SIMSCSI_REQ_QUEUE_LEN,	\
+	.this_id		= -1,				\
+	.sg_tablesize		= SG_ALL,			\
+	.cmd_per_lun		= SIMSCSI_REQ_QUEUE_LEN,	\
+	.present		= 0,				\
+	.unchecked_isa_dma	= 0,				\
+	.use_clustering		= DISABLE_CLUSTERING		\
+}
+
+#endif /* SIMSCSI_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/drivers/simserial.c linux-2.4.23-pre8/arch/ia64/drivers/simserial.c
--- linux-2.4.22/arch/ia64/drivers/simserial.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/drivers/simserial.c	2003-10-22 22:48:13.000000000 +0000
@@ -0,0 +1,1094 @@
+/*
+ * Simulated Serial Driver (fake serial)
+ *
+ * This driver is mostly used for bringup purposes and will go away.
+ * It has a strong dependency on the system console. All outputs
+ * are rerouted to the same facility as the one used by printk which, in our
+ * case means sys_sim.c console (goes via the simulator). The code hereafter
+ * is completely leveraged from the serial.c driver.
+ *
+ * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * 02/04/00 D. Mosberger	Merged in serial.c bug fixes in rs_close().
+ * 02/25/00 D. Mosberger	Synced up with 2.3.99pre-5 version of serial.c.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/console.h>
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#undef SIMSERIAL_DEBUG	/* define this to get some debug information */
+
+#define KEYBOARD_INTR	3	/* must match with simulator! */
+
+#define NR_PORTS	1	/* only one port for now */
+#define SERIAL_INLINE	1
+
+#ifdef SERIAL_INLINE
+#define _INLINE_ inline
+#endif
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
+
+#define SSC_GETCHAR	21
+
+extern long ia64_ssc (long, long, long, long, int);
+extern void ia64_ssc_connect_irq (long intr, long irq);
+
+static char *serial_name = "SimSerial driver";
+static char *serial_version = "0.6";
+
+/*
+ * This has been extracted from asm/serial.h. We need one eventually but
+ * I don't know exactly what we're going to put in it so just fake one
+ * for now.
+ */
+#define BASE_BAUD ( 1843200 / 16 )
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+/*
+ * Most of the values here are meaningless to this particular driver.
+ * However some values must be preserved for the code (leveraged from serial.c
+ * to work correctly).
+ * port must not be 0
+ * type must not be UNKNOWN
+ * So I picked arbitrary (guess from where?) values instead
+ */
+static struct serial_state rs_table[NR_PORTS]={
+  /* UART CLK   PORT IRQ     FLAGS        */
+  { 0, BASE_BAUD, 0x3F8, 0, STD_COM_FLAGS,0,PORT_16550 }  /* ttyS0 */
+};
+
+/*
+ * Just for the fun of it !
+ */
+static struct serial_uart_config uart_config[] = {
+	{ "unknown", 1, 0 },
+	{ "8250", 1, 0 },
+	{ "16450", 1, 0 },
+	{ "16550", 1, 0 },
+	{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "cirrus", 1, 0 },
+	{ "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH },
+	{ "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |
+		  UART_STARTECH },
+	{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
+	{ 0, 0}
+};
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+static struct async_struct *IRQ_ports[NR_IRQS];
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+static struct console *console;
+
+static unsigned char *tmp_buf;
+static DECLARE_MUTEX(tmp_buf_sem);
+
+extern struct console *console_drivers; /* from kernel/printk.c */
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_stop: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n",
+		tty->stopped, tty->hw_stopped, tty->flow_stopped);
+#endif
+
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+#if SIMSERIAL_DEBUG
+	printk("rs_start: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n",
+		tty->stopped, tty->hw_stopped, tty->flow_stopped);
+#endif
+}
+
+static  void receive_chars(struct tty_struct *tty, struct pt_regs *regs)
+{
+	unsigned char ch;
+	static unsigned char seen_esc = 0;
+
+	while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) {
+		if ( ch == 27 && seen_esc == 0 ) {
+			seen_esc = 1;
+			continue;
+		} else {
+			if ( seen_esc==1 && ch == 'O' ) {
+				seen_esc = 2;
+				continue;
+			} else if ( seen_esc == 2 ) {
+				if ( ch == 'P' ) show_state();		/* F1 key */
+				if ( ch == 'Q' ) show_buffers();	/* F2 key */
+				seen_esc = 0;
+				continue;
+			}
+		}
+		seen_esc = 0;
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) break;
+
+		*tty->flip.char_buf_ptr = ch;
+
+		*tty->flip.flag_buf_ptr = 0;
+
+		tty->flip.flag_buf_ptr++;
+		tty->flip.char_buf_ptr++;
+		tty->flip.count++;
+	}
+	tty_flip_buffer_push(tty);
+}
+
+/*
+ * This is the serial driver's interrupt routine for a single port
+ */
+static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct async_struct * info;
+
+	/*
+	 * I don't know exactly why they don't use the dev_id opaque data
+	 * pointer instead of this extra lookup table
+	 */
+	info = IRQ_ports[irq];
+	if (!info || !info->tty) {
+		printk(KERN_INFO "simrs_interrupt_single: info|tty=0 info=%p problem\n", info);
+		return;
+	}
+	/*
+	 * pretty simple in our case, because we only get interrupts
+	 * on inbound traffic
+	 */
+	receive_chars(info->tty, regs);
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+#if 0
+/*
+ * not really used in our situation so keep them commented out for now
+ */
+static DECLARE_TASK_QUEUE(tq_serial); /* used to be at the top of the file */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+	printk(KERN_ERR "do_serial_bh: called\n");
+}
+#endif
+
+static void do_softint(void *private_)
+{
+	printk(KERN_ERR "simserial: do_softint called\n");
+}
+
+static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (!tty || !info->xmit.buf) return;
+
+	save_flags(flags); cli();
+	if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) == 0) {
+		restore_flags(flags);
+		return;
+	}
+	info->xmit.buf[info->xmit.head] = ch;
+	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
+	restore_flags(flags);
+}
+
+static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
+{
+	int count;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+
+	if (info->x_char) {
+		char c = info->x_char;
+
+		console->write(console, &c, 1);
+
+		info->state->icount.tx++;
+		info->x_char = 0;
+
+		goto out;
+	}
+
+	if (info->xmit.head == info->xmit.tail || info->tty->stopped || info->tty->hw_stopped) {
+#ifdef SIMSERIAL_DEBUG
+		printk("transmit_chars: head=%d, tail=%d, stopped=%d\n",
+		       info->xmit.head, info->xmit.tail, info->tty->stopped);
+#endif
+		goto out;
+	}
+	/*
+	 * We removed the loop and try to do it in to chunks. We need
+	 * 2 operations maximum because it's a ring buffer.
+	 *
+	 * First from current to tail if possible.
+	 * Then from the beginning of the buffer until necessary
+	 */
+
+	count = MIN(CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE),
+		    SERIAL_XMIT_SIZE - info->xmit.tail);
+	console->write(console, info->xmit.buf+info->xmit.tail, count);
+
+	info->xmit.tail = (info->xmit.tail+count) & (SERIAL_XMIT_SIZE-1);
+
+	/*
+	 * We have more at the beginning of the buffer
+	 */
+	count = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+	if (count) {
+		console->write(console, info->xmit.buf, count);
+		info->xmit.tail += count;
+	}
+out:
+	restore_flags(flags);
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	if (info->xmit.head == info->xmit.tail || tty->stopped || tty->hw_stopped ||
+	    !info->xmit.buf)
+		return;
+
+	transmit_chars(info, NULL);
+}
+
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, ret = 0;
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (!tty || !info->xmit.buf || !tmp_buf) return 0;
+
+	save_flags(flags);
+	if (from_user) {
+		down(&tmp_buf_sem);
+		while (1) {
+			int c1;
+			c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+			cli();
+			c1 = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+			if (c1 < c)
+				c = c1;
+			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		cli();
+		while (1) {
+			c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0) {
+				break;
+			}
+			memcpy(info->xmit.buf + info->xmit.head, buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		restore_flags(flags);
+	}
+	/*
+	 * Hey, we transmit directly from here in our case
+	 */
+	if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE)
+	    && !tty->stopped && !tty->hw_stopped) {
+		transmit_chars(info, NULL);
+	}
+	return ret;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	info->xmit.head = info->xmit.tail = 0;
+	restore_flags(flags);
+
+	wake_up_interruptible(&tty->write_wait);
+
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	info->x_char = ch;
+	if (ch) {
+		/*
+		 * I guess we could call console->write() directly but
+		 * let's do that for now.
+		 */
+		transmit_chars(info, NULL);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ *
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+	if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty));
+
+	printk(KERN_INFO "simrs_throttle called\n");
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			rs_send_xchar(tty, START_CHAR(tty));
+	}
+	printk(KERN_INFO "simrs_unthrottle called\n");
+}
+
+/*
+ * rs_break() --- routine which turns the break handling on or off
+ */
+static void rs_break(struct tty_struct *tty, int break_state)
+{
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+
+	switch (cmd) {
+		case TIOCMGET:
+			printk(KERN_INFO "rs_ioctl: TIOCMGET called\n");
+			return -EINVAL;
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			printk(KERN_INFO "rs_ioctl: TIOCMBIS/BIC/SET called\n");
+			return -EINVAL;
+		case TIOCGSERIAL:
+			printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n");
+			return 0;
+		case TIOCSSERIAL:
+			printk(KERN_INFO "simrs_ioctl TIOCSSERIAL called\n");
+			return 0;
+		case TIOCSERCONFIG:
+			printk(KERN_INFO "rs_ioctl: TIOCSERCONFIG called\n");
+			return -EINVAL;
+
+		case TIOCSERGETLSR: /* Get line status register */
+			printk(KERN_INFO "rs_ioctl: TIOCSERGETLSR called\n");
+			return  -EINVAL;
+
+		case TIOCSERGSTRUCT:
+			printk(KERN_INFO "rs_ioctl: TIOCSERGSTRUCT called\n");
+#if 0
+			if (copy_to_user((struct async_struct *) arg,
+					 info, sizeof(struct async_struct)))
+				return -EFAULT;
+#endif
+			return 0;
+
+		/*
+		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		 * - mask passed in arg for lines of interest
+		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		 * Caller should use TIOCGICOUNT to see which one it was
+		 */
+		case TIOCMIWAIT:
+			printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n");
+			return 0;
+		/*
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+		case TIOCGICOUNT:
+			printk(KERN_INFO "rs_ioctl: TIOCGICOUNT called\n");
+			return 0;
+
+		case TIOCSERGWILD:
+		case TIOCSERSWILD:
+			/* "setserial -W" is called in Debian boot */
+			printk (KERN_INFO "TIOCSER?WILD ioctl obsolete, ignored.\n");
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	unsigned int cflag = tty->termios->c_cflag;
+
+	if (   (cflag == old_termios->c_cflag)
+	    && (   RELEVANT_IFLAG(tty->termios->c_iflag)
+		== RELEVANT_IFLAG(old_termios->c_iflag)))
+	  return;
+
+
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+}
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct async_struct * info)
+{
+	unsigned long	flags;
+	struct serial_state *state;
+	int		retval;
+
+	if (!(info->flags & ASYNC_INITIALIZED)) return;
+
+	state = info->state;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("Shutting down serial port %d (irq %d)....", info->line,
+	       state->irq);
+#endif
+
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	/*
+	 * First unlink the serial port from the IRQ chain...
+	 */
+	if (info->next_port)
+		info->next_port->prev_port = info->prev_port;
+	if (info->prev_port)
+		info->prev_port->next_port = info->next_port;
+	else
+		IRQ_ports[state->irq] = info->next_port;
+
+	/*
+	 * Free the IRQ, if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			free_irq(state->irq, NULL);
+			retval = request_irq(state->irq, rs_interrupt_single,
+					     IRQ_T(info), "serial", NULL);
+
+			if (retval)
+				printk(KERN_ERR "serial shutdown: request_irq: error %d"
+				       "  Couldn't reacquire IRQ.\n", retval);
+		} else
+			free_irq(state->irq, NULL);
+	}
+
+	if (info->xmit.buf) {
+		free_page((unsigned long) info->xmit.buf);
+		info->xmit.buf = 0;
+	}
+
+	if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ *
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state;
+	unsigned long flags;
+
+	if (!info ) return;
+
+	state = info->state;
+
+	save_flags(flags); cli();
+
+	if (tty_hung_up_p(filp)) {
+#ifdef SIMSERIAL_DEBUG
+		printk("rs_close: hung_up\n");
+#endif
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
+#endif
+	if ((tty->count == 1) && (state->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  state->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, "
+		       "state->count is %d\n", state->count);
+		state->count = 1;
+	}
+	if (--state->count < 0) {
+		printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n",
+		       info->line, state->count);
+		state->count = 0;
+	}
+	if (state->count) {
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+	restore_flags(flags);
+
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	shutdown(info);
+	if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty);
+	info->event = 0;
+	info->tty = 0;
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	MOD_DEC_USE_COUNT;
+}
+
+/*
+ * rs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+}
+
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state = info->state;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_hangup: called\n");
+#endif
+
+	state = info->state;
+
+	rs_flush_buffer(tty);
+	if (info->flags & ASYNC_CLOSING)
+		return;
+	shutdown(info);
+
+	info->event = 0;
+	state->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+
+static int get_async_struct(int line, struct async_struct **ret_info)
+{
+	struct async_struct *info;
+	struct serial_state *sstate;
+
+	sstate = rs_table + line;
+	sstate->count++;
+	if (sstate->info) {
+		*ret_info = sstate->info;
+		return 0;
+	}
+	info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
+	if (!info) {
+		sstate->count--;
+		return -ENOMEM;
+	}
+	memset(info, 0, sizeof(struct async_struct));
+	init_waitqueue_head(&info->open_wait);
+	init_waitqueue_head(&info->close_wait);
+	init_waitqueue_head(&info->delta_msr_wait);
+	info->magic = SERIAL_MAGIC;
+	info->port = sstate->port;
+	info->flags = sstate->flags;
+	info->xmit_fifo_size = sstate->xmit_fifo_size;
+	info->line = line;
+	info->tqueue.routine = do_softint;
+	info->tqueue.data = info;
+	info->state = sstate;
+	if (sstate->info) {
+		kfree(info);
+		*ret_info = sstate->info;
+		return 0;
+	}
+	*ret_info = sstate->info = info;
+	return 0;
+}
+
+static int
+startup(struct async_struct *info)
+{
+	unsigned long flags;
+	int	retval=0;
+	void (*handler)(int, void *, struct pt_regs *);
+	struct serial_state *state= info->state;
+	unsigned long page;
+
+	page = get_free_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	save_flags(flags); cli();
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		goto errout;
+	}
+
+	if (!state->port || !state->type) {
+		if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
+		free_page(page);
+		goto errout;
+	}
+	if (info->xmit.buf)
+		free_page(page);
+	else
+		info->xmit.buf = (unsigned char *) page;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("startup: ttys%d (irq %d)...", info->line, state->irq);
+#endif
+
+	/*
+	 * Allocate the IRQ if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			retval = -EBUSY;
+			goto errout;
+		} else
+			handler = rs_interrupt_single;
+
+		retval = request_irq(state->irq, handler, IRQ_T(info), "simserial", NULL);
+		if (retval) {
+			if (capable(CAP_SYS_ADMIN)) {
+				if (info->tty)
+					set_bit(TTY_IO_ERROR,
+						&info->tty->flags);
+				retval = 0;
+			}
+			goto errout;
+		}
+	}
+
+	/*
+	 * Insert serial port into IRQ chain.
+	 */
+	info->prev_port = 0;
+	info->next_port = IRQ_ports[state->irq];
+	if (info->next_port)
+		info->next_port->prev_port = info;
+	IRQ_ports[state->irq] = info;
+
+	if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->xmit.head = info->xmit.tail = 0;
+
+#if 0
+	/*
+	 * Set up serial timers...
+	 */
+	timer_table[RS_TIMER].expires = jiffies + 2*HZ/100;
+	timer_active |= 1 << RS_TIMER;
+#endif
+
+	/*
+	 * Set up the tty->alt_speed kludge
+	 */
+	if (info->tty) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			info->tty->alt_speed = 57600;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			info->tty->alt_speed = 115200;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+			info->tty->alt_speed = 230400;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+			info->tty->alt_speed = 460800;
+	}
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+
+errout:
+	restore_flags(flags);
+	return retval;
+}
+
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+static int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct	*info;
+	int			retval, line;
+	unsigned long		page;
+
+	MOD_INC_USE_COUNT;
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if ((line < 0) || (line >= NR_PORTS)) {
+		MOD_DEC_USE_COUNT;
+		return -ENODEV;
+	}
+	retval = get_async_struct(line, &info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+	tty->driver_data = info;
+	info->tty = tty;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+	       info->state->count);
+#endif
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+
+	if (!tmp_buf) {
+		page = get_free_page(GFP_KERNEL);
+		if (!page) {
+			/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
+			return -ENOMEM;
+		}
+		if (tmp_buf)
+			free_page(page);
+		else
+			tmp_buf = (unsigned char *) page;
+	}
+
+	/*
+	 * If the port is the middle of closing, bail out now
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+		/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval) {
+		/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
+		return retval;
+	}
+
+	if ((info->state->count == 1) &&
+	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->state->normal_termios;
+		else
+			*tty->termios = info->state->callout_termios;
+	}
+
+	/*
+	 * figure out which console to use (should be one already)
+	 */
+	console = console_drivers;
+	while (console) {
+		if ((console->flags & CON_ENABLED) && console->write) break;
+		console = console->next;
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_open ttys%d successful\n", info->line);
+#endif
+	return 0;
+}
+
+/*
+ * /proc fs routines....
+ */
+
+static inline int line_info(char *buf, struct serial_state *state)
+{
+	return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n",
+		       state->line, uart_config[state->type].name,
+		       state->port, state->irq);
+}
+
+static int rs_read_proc(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	int i, len = 0, l;
+	off_t	begin = 0;
+
+	len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version);
+	for (i = 0; i < NR_PORTS && len < 4000; i++) {
+		l = line_info(page + len, &rs_table[i]);
+		len += l;
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (begin-off);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * rs_init() and friends
+ *
+ * rs_init() is called at boot-time to initialize the serial driver.
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * This routine prints out the appropriate serial driver version
+ * number, and identifies which options were configured into this
+ * driver.
+ */
+static inline void show_serial_version(void)
+{
+	printk(KERN_INFO "%s version %s with", serial_name, serial_version);
+	printk(KERN_INFO " no serial options enabled\n");
+}
+
+/*
+ * The serial driver boot-time initialization code!
+ */
+static int __init
+simrs_init (void)
+{
+	int			i;
+	struct serial_state	*state;
+
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+	serial_driver.driver_name = "simserial";
+	serial_driver.name = "ttyS";
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64;
+	serial_driver.num = 1;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.put_char = rs_put_char;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.send_xchar = rs_send_xchar;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+	serial_driver.break_ctl = rs_break;
+	serial_driver.wait_until_sent = rs_wait_until_sent;
+	serial_driver.read_proc = rs_read_proc;
+
+	/*
+	 * Let's have a little bit of fun !
+	 */
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+
+		if (state->type == PORT_UNKNOWN) continue;
+
+		if (!state->irq) {
+			state->irq = ia64_alloc_vector();
+			ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq);
+		}
+
+		printk(KERN_INFO "ttyS%02d at 0x%04lx (irq = %d) is a %s\n",
+		       state->line,
+		       state->port, state->irq,
+		       uart_config[state->type].name);
+	}
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+	callout_driver.name = "cua";
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	callout_driver.read_proc = 0;
+	callout_driver.proc_entry = 0;
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register simserial driver\n");
+
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+
+	return 0;
+}
+
+#ifndef MODULE
+__initcall(simrs_init);
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/hp/common/sba_iommu.c linux-2.4.23-pre8/arch/ia64/hp/common/sba_iommu.c
--- linux-2.4.22/arch/ia64/hp/common/sba_iommu.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/hp/common/sba_iommu.c	2003-10-22 22:49:05.000000000 +0000
@@ -1895,22 +1895,26 @@
 	struct ioc *ioc;
 	acpi_status status;
 	u64 hpa, length;
-	acpi_device_info dev_info;
+	struct acpi_buffer buffer;
+	struct acpi_device_info *dev_info;
 
 	status = acpi_hp_csr_space(device->handle, &hpa, &length);
 	if (ACPI_FAILURE(status))
 		return 1;
 
-	status = acpi_get_object_info(device->handle, &dev_info);
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	status = acpi_get_object_info(device->handle, &buffer);
 	if (ACPI_FAILURE(status))
 		return 1;
+	dev_info = buffer.pointer;
 
 	/*
 	 * For HWP0001, only SBA appears in ACPI namespace.  It encloses the PCI
 	 * root bridges, and its CSR space includes the IOC function.
 	 */
-	if (strncmp("HWP0001", dev_info.hardware_id, 7) == 0)
+	if (strncmp("HWP0001", dev_info->hardware_id.value, 7) == 0)
 		hpa += ZX1_IOC_OFFSET;
+	ACPI_MEM_FREE(dev_info);
 
 	ioc = ioc_init(hpa, device->handle);
 	if (!ioc)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/hp/zx1/hpzx1_misc.c linux-2.4.23-pre8/arch/ia64/hp/zx1/hpzx1_misc.c
--- linux-2.4.22/arch/ia64/hp/zx1/hpzx1_misc.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/hp/zx1/hpzx1_misc.c	2003-10-22 22:49:10.000000000 +0000
@@ -210,7 +210,7 @@
 {
 	u64 csr_base = 0, csr_length = 0;
 	acpi_status status;
-	NATIVE_UINT busnum;
+	acpi_native_uint busnum;
 	char *name = context;
 	char fullname[32];
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/ia32/ia32_signal.c linux-2.4.23-pre8/arch/ia64/ia32/ia32_signal.c
--- linux-2.4.22/arch/ia64/ia32/ia32_signal.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/ia32/ia32_signal.c	2003-10-22 22:47:31.000000000 +0000
@@ -171,8 +171,10 @@
  *    datasel    ar.fdr(32:47)
  *
  *    _st[(0+TOS)%8]   f8
- *    _st[(1+TOS)%8]   f9                    (f8, f9 from ptregs)
- *      : :            :                     (f10..f15 from live reg)
+ *    _st[(1+TOS)%8]   f9
+ *    _st[(2+TOS)%8]   f10
+ *    _st[(3+TOS)%8]   f11                   (f8..f11 from ptregs)
+ *      : :            :                     (f12..f15 from live reg)
  *      : :            :
  *    _st[(7+TOS)%8]   f15                   TOS=sw.top(bits11:13)
  *
@@ -254,8 +256,8 @@
 	__put_user( 0, &save->magic); //#define X86_FXSR_MAGIC   0x0000
 
 	/*
-	 * save f8 and f9  from pt_regs
-	 * save f10..f15 from live register set
+	 * save f8..f11  from pt_regs
+	 * save f12..f15 from live register set
 	 */
 	/*
 	 *  Find the location where f8 has to go in fp reg stack.  This depends on
@@ -270,11 +272,11 @@
 	copy_to_user(&save->_st[(0+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
 	ia64f2ia32f(fpregp, &ptp->f9);
 	copy_to_user(&save->_st[(1+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
-
-	__stfe(fpregp, 10);
+	ia64f2ia32f(fpregp, &ptp->f10);
 	copy_to_user(&save->_st[(2+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
-	__stfe(fpregp, 11);
+	ia64f2ia32f(fpregp, &ptp->f11);
 	copy_to_user(&save->_st[(3+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
+
 	__stfe(fpregp, 12);
 	copy_to_user(&save->_st[(4+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
 	__stfe(fpregp, 13);
@@ -386,8 +388,8 @@
 	asm volatile ( "mov ar.fdr=%0;" :: "r"(fdr));
 
 	/*
-	 * restore f8, f9 onto pt_regs
-	 * restore f10..f15 onto live registers
+	 * restore f8..f11 onto pt_regs
+	 * restore f12..f15 onto live registers
 	 */
 	/*
 	 *  Find the location where f8 has to go in fp reg stack.  This depends on
@@ -403,11 +405,11 @@
 	ia32f2ia64f(&ptp->f8, fpregp);
 	copy_from_user(fpregp, &save->_st[(1+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
 	ia32f2ia64f(&ptp->f9, fpregp);
-
 	copy_from_user(fpregp, &save->_st[(2+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
-	__ldfe(10, fpregp);
+	ia32f2ia64f(&ptp->f10, fpregp);
 	copy_from_user(fpregp, &save->_st[(3+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
-	__ldfe(11, fpregp);
+	ia32f2ia64f(&ptp->f11, fpregp);
+
 	copy_from_user(fpregp, &save->_st[(4+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
 	__ldfe(12, fpregp);
 	copy_from_user(fpregp, &save->_st[(5+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
@@ -739,11 +741,11 @@
 
 #define COPY(ia64x, ia32x)	err |= __get_user(regs->ia64x, &sc->ia32x)
 
-#define copyseg_gs(tmp)		(regs->r16 |= (unsigned long) tmp << 48)
-#define copyseg_fs(tmp)		(regs->r16 |= (unsigned long) tmp << 32)
+#define copyseg_gs(tmp)		(regs->r16 |= (unsigned long) (tmp) << 48)
+#define copyseg_fs(tmp)		(regs->r16 |= (unsigned long) (tmp) << 32)
 #define copyseg_cs(tmp)		(regs->r17 |= tmp)
-#define copyseg_ss(tmp)		(regs->r17 |= (unsigned long) tmp << 16)
-#define copyseg_es(tmp)		(regs->r16 |= (unsigned long) tmp << 16)
+#define copyseg_ss(tmp)		(regs->r17 |= (unsigned long) (tmp) << 16)
+#define copyseg_es(tmp)		(regs->r16 |= (unsigned long) (tmp) << 16)
 #define copyseg_ds(tmp)		(regs->r16 |= tmp)
 
 #define COPY_SEG(seg)					\
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/ia32/ia32_support.c linux-2.4.23-pre8/arch/ia64/ia32/ia32_support.c
--- linux-2.4.22/arch/ia64/ia32/ia32_support.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/ia32/ia32_support.c	2003-10-22 22:47:39.000000000 +0000
@@ -60,30 +60,26 @@
 	regs->r27 = load_desc(regs->r16 >>  0);		/* DSD */
 	regs->r28 = load_desc(regs->r16 >> 32);		/* FSD */
 	regs->r29 = load_desc(regs->r16 >> 48);		/* GSD */
-	task->thread.csd = load_desc(regs->r17 >>  0);	/* CSD */
-	task->thread.ssd = load_desc(regs->r17 >> 16);	/* SSD */
+	regs->ar_csd = load_desc(regs->r17 >>  0);	/* CSD */
+	regs->ar_ssd = load_desc(regs->r17 >> 16);	/* SSD */
 }
 
 void
 ia32_save_state (struct task_struct *t)
 {
-	unsigned long eflag, fsr, fcr, fir, fdr, csd, ssd;
+	unsigned long eflag, fsr, fcr, fir, fdr;
 
 	asm ("mov %0=ar.eflag;"
 	     "mov %1=ar.fsr;"
 	     "mov %2=ar.fcr;"
 	     "mov %3=ar.fir;"
 	     "mov %4=ar.fdr;"
-	     "mov %5=ar.csd;"
-	     "mov %6=ar.ssd;"
-	     : "=r"(eflag), "=r"(fsr), "=r"(fcr), "=r"(fir), "=r"(fdr), "=r"(csd), "=r"(ssd));
+	     : "=r"(eflag), "=r"(fsr), "=r"(fcr), "=r"(fir), "=r"(fdr));
 	t->thread.eflag = eflag;
 	t->thread.fsr = fsr;
 	t->thread.fcr = fcr;
 	t->thread.fir = fir;
 	t->thread.fdr = fdr;
-	t->thread.csd = csd;
-	t->thread.ssd = ssd;
 	ia64_set_kr(IA64_KR_IO_BASE, t->thread.old_iob);
 	ia64_set_kr(IA64_KR_TSSD, t->thread.old_k1);
 }
@@ -91,7 +87,7 @@
 void
 ia32_load_state (struct task_struct *t)
 {
-	unsigned long eflag, fsr, fcr, fir, fdr, csd, ssd, tssd;
+	unsigned long eflag, fsr, fcr, fir, fdr, tssd;
 	struct pt_regs *regs = ia64_task_regs(t);
 	int nr = smp_processor_id();	/* LDT and TSS depend on CPU number: */
 
@@ -100,8 +96,6 @@
 	fcr = t->thread.fcr;
 	fir = t->thread.fir;
 	fdr = t->thread.fdr;
-	csd = t->thread.csd;
-	ssd = t->thread.ssd;
 	tssd = load_desc(_TSS(nr));					/* TSSD */
 
 	asm volatile ("mov ar.eflag=%0;"
@@ -109,9 +103,7 @@
 		      "mov ar.fcr=%2;"
 		      "mov ar.fir=%3;"
 		      "mov ar.fdr=%4;"
-		      "mov ar.csd=%5;"
-		      "mov ar.ssd=%6;"
-		      :: "r"(eflag), "r"(fsr), "r"(fcr), "r"(fir), "r"(fdr), "r"(csd), "r"(ssd));
+		      :: "r"(eflag), "r"(fsr), "r"(fcr), "r"(fir), "r"(fdr));
 	current->thread.old_iob = ia64_get_kr(IA64_KR_IO_BASE);
 	current->thread.old_k1 = ia64_get_kr(IA64_KR_TSSD);
 	ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/ia32/sys_ia32.c linux-2.4.23-pre8/arch/ia64/ia32/sys_ia32.c
--- linux-2.4.22/arch/ia64/ia32/sys_ia32.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/ia32/sys_ia32.c	2003-10-22 22:49:05.000000000 +0000
@@ -38,6 +38,7 @@
 #include <linux/smb_mount.h>
 #include <linux/ncp_fs.h>
 #include <linux/quota.h>
+#include <linux/quotacompat.h>
 #include <linux/module.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
@@ -165,9 +166,9 @@
 		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);
 	}
+  out:
+	kfree(av);
 	return r;
 }
 
@@ -2147,7 +2148,6 @@
 #define SEMOP		 1
 #define SEMGET		 2
 #define SEMCTL		 3
-#define SEMTIMEDOP	 4
 #define MSGSND		11
 #define MSGRCV		12
 #define MSGGET		13
@@ -2579,17 +2579,6 @@
 	return err;
 }
 
-static long
-semtimedop32(int semid, struct sembuf *tsems, int nsems,
-	     const struct timespec32 *timeout32)
-{
-	struct timespec t;
-	if (get_user (t.tv_sec, &timeout32->tv_sec) ||
-	    get_user (t.tv_nsec, &timeout32->tv_nsec))
-		return -EFAULT;
-	return sys_semtimedop(semid, tsems, nsems, &t);
-}
-
 asmlinkage long
 sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
 {
@@ -2601,11 +2590,7 @@
 	switch (call) {
 	      case SEMOP:
 		/* struct sembuf is the same on 32 and 64bit :)) */
-		return sys_semtimedop(first, (struct sembuf *)AA(ptr), second,
-				      NULL);
-	      case SEMTIMEDOP:
-		return semtimedop32(first, (struct sembuf *)AA(ptr), second, 
-				    (const struct timespec32 *)AA(fifth));
+		return sys_semop(first, (struct sembuf *)AA(ptr), second);
 	      case SEMGET:
 		return sys_semget(first, second, third);
 	      case SEMCTL:
@@ -2903,12 +2888,16 @@
 		ia64f2ia32f(f, &ptp->f9);
 		break;
 	      case 2:
+		ia64f2ia32f(f, &ptp->f10);
+		break;
 	      case 3:
+		ia64f2ia32f(f, &ptp->f11);
+		break;
 	      case 4:
 	      case 5:
 	      case 6:
 	      case 7:
-		ia64f2ia32f(f, &swp->f10 + (regno - 2));
+		ia64f2ia32f(f, &swp->f12 + (regno - 4));
 		break;
 	}
 	copy_to_user(reg, f, sizeof(*reg));
@@ -2929,12 +2918,16 @@
 		copy_from_user(&ptp->f9, reg, sizeof(*reg));
 		break;
 	      case 2:
+		copy_from_user(&ptp->f10, reg, sizeof(*reg));
+		break;
 	      case 3:
+		copy_from_user(&ptp->f11, reg, sizeof(*reg));
+		break;
 	      case 4:
 	      case 5:
 	      case 6:
 	      case 7:
-		copy_from_user(&swp->f10 + (regno - 2), reg, sizeof(*reg));
+		copy_from_user(&swp->f12 + (regno - 4), reg, sizeof(*reg));
 		break;
 	}
 	return;
@@ -3635,9 +3628,11 @@
 			return -EFAULT;
 		old_fs = get_fs();
 		set_fs(KERNEL_DS);
-		ret = sys_fcntl(fd, cmd, (unsigned long) &f);
+		ret = sys_fcntl(fd, (cmd == F_GETLK64) ? F_GETLK :
+			((cmd == F_SETLK64) ? F_SETLK : F_SETLKW),
+			(unsigned long) &f);
 		set_fs(old_fs);
-		if (cmd == F_GETLK && ia32_put_flock(&f, arg))
+		if (cmd == F_GETLK64 && ia32_put_flock(&f, arg))
 			return -EFAULT;
 		break;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/Makefile linux-2.4.23-pre8/arch/ia64/kernel/Makefile
--- linux-2.4.22/arch/ia64/kernel/Makefile	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/Makefile	2003-10-22 22:48:54.000000000 +0000
@@ -17,6 +17,7 @@
 	 machvec.o pal.o process.o perfmon.o ptrace.o sal.o salinfo.o semaphore.o setup.o	 \
 	 signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o
 obj-$(CONFIG_IA64_GENERIC) += iosapic.o
+obj-$(CONFIG_IA64_SGI_SN2) += iosapic.o
 obj-$(CONFIG_IA64_HP_ZX1) += iosapic.o
 obj-$(CONFIG_IA64_DIG) += iosapic.o
 obj-$(CONFIG_IA64_PALINFO) += palinfo.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/acpi.c linux-2.4.23-pre8/arch/ia64/kernel/acpi.c
--- linux-2.4.22/arch/ia64/kernel/acpi.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/acpi.c	2003-10-22 22:48:55.000000000 +0000
@@ -8,6 +8,9 @@
  *  Copyright (C) 2000 Intel Corp.
  *  Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
  *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2001 Jenna Hall <jenna.s.hall@intel.com>
+ *  Copyright (C) 2001 Takayoshi Kochi <t-kouchi@cq.jp.nec.com>
+ *  Copyright (C) 2002 Erich Focht <efocht@ess.nec.de>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
@@ -38,11 +41,14 @@
 #include <linux/irq.h>
 #include <linux/acpi.h>
 #include <linux/efi.h>
+#include <linux/mm.h>
+#include <linux/mmzone.h>
 #include <asm/io.h>
 #include <asm/iosapic.h>
 #include <asm/machvec.h>
 #include <asm/page.h>
 #include <asm/system.h>
+#include <asm/numa.h>
 
 
 #define PREFIX			"ACPI: "
@@ -59,6 +65,8 @@
 
 unsigned char acpi_kbd_controller_present = 1;
 
+int acpi_disabled __initdata;	/* XXX this shouldn't be needed---we can't boot without ACPI! */
+
 const char *
 acpi_get_sysname (void)
 {
@@ -90,6 +98,9 @@
 	if (!strcmp(hdr->oem_id, "HP")) {
 		return "hpzx1";
 	}
+	else if (!strcmp(hdr->oem_id, "SGI")) {
+		return "sn2";
+	}
 
 	return "dig";
 #else
@@ -97,8 +108,6 @@
 	return "hpsim";
 # elif defined (CONFIG_IA64_HP_ZX1)
 	return "hpzx1";
-# elif defined (CONFIG_IA64_SGI_SN1)
-	return "sn1";
 # elif defined (CONFIG_IA64_SGI_SN2)
 	return "sn2";
 # elif defined (CONFIG_IA64_DIG)
@@ -123,17 +132,17 @@
 };
 
 acpi_status
-acpi_vendor_resource_match(acpi_resource *resource, void *context)
+acpi_vendor_resource_match (struct acpi_resource *resource, void *context)
 {
 	struct acpi_vendor_info *info = (struct acpi_vendor_info *) context;
-	acpi_resource_vendor *vendor;
+	struct acpi_resource_vendor *vendor;
 	struct acpi_vendor_descriptor *descriptor;
 	u32 length;
 
 	if (resource->id != ACPI_RSTYPE_VENDOR)
 		return AE_OK;
 
-	vendor = (acpi_resource_vendor *) &resource->data;
+	vendor = (struct acpi_resource_vendor *) &resource->data;
 	descriptor = (struct acpi_vendor_descriptor *) vendor->reserved;
 	if (vendor->length <= sizeof(*info->descriptor) ||
 	    descriptor->guid_id != info->descriptor->guid_id ||
@@ -151,7 +160,7 @@
 }
 
 acpi_status
-acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor *id,
+acpi_find_vendor_resource (acpi_handle obj, struct acpi_vendor_descriptor *id,
 		u8 **data, u32 *length)
 {
 	struct acpi_vendor_info info;
@@ -174,12 +183,11 @@
 };
 
 acpi_status
-acpi_hp_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length)
+acpi_hp_csr_space (acpi_handle obj, u64 *csr_base, u64 *csr_length)
 {
 	acpi_status status;
 	u8 *data;
 	u32 length;
-	int i;
 
 	status = acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length);
 
@@ -200,7 +208,9 @@
 #define ACPI_MAX_PLATFORM_INTERRUPTS	256
 
 /* Array to record platform interrupt vectors for generic interrupt routing. */
-int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = { [0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1 };
+int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = {
+	[0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1
+};
 
 enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC;
 
@@ -214,7 +224,7 @@
 	int vector = -1;
 
 	if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) {
-		/* correctable platform error interrupt */
+		/* corrected platform error interrupt */
 		vector = platform_intr_list[int_type];
 	} else
 		printk(KERN_ERR "acpi_request_vector(): invalid interrupt type\n");
@@ -252,7 +262,6 @@
 		iounmap((void *) ipi_base_addr);
 		ipi_base_addr = (unsigned long) ioremap(lapic->address, 0);
 	}
-
 	return 0;
 }
 
@@ -261,7 +270,6 @@
 acpi_parse_lsapic (acpi_table_entry_header *header)
 {
 	struct acpi_table_lsapic *lsapic;
-	int phys_id;
 
 	lsapic = (struct acpi_table_lsapic *) header;
 	if (!lsapic)
@@ -269,30 +277,21 @@
 
 	acpi_table_print_madt_entry(header);
 
-	phys_id = (lsapic->id << 8) | lsapic->eid;
-
-	if (total_cpus == NR_CPUS) {
-		printk(KERN_ERR PREFIX "Ignoring CPU (0x%04x) (NR_CPUS == %d)\n",
-			phys_id, NR_CPUS);
-		return 0;
-	}
-
-	printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, phys_id);
+	printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid);
 
-	if (lsapic->flags.enabled) {
-		available_cpus++;
+	if (!lsapic->flags.enabled)
+		printk(" disabled");
+	else if (available_cpus >= NR_CPUS)
+		printk(" ignored (increase NR_CPUS)");
+	else {
 		printk(" enabled");
 #ifdef CONFIG_SMP
-		smp_boot_data.cpu_phys_id[total_cpus] = phys_id;
-		if (hard_smp_processor_id() == smp_boot_data.cpu_phys_id[total_cpus])
+		smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid;
+		if (hard_smp_processor_id()
+		    == (unsigned int) smp_boot_data.cpu_phys_id[available_cpus])
 			printk(" (BSP)");
 #endif
-	}
-	else {
-		printk(" disabled");
-#ifdef CONFIG_SMP
-		smp_boot_data.cpu_phys_id[total_cpus] = -1;
-#endif
+		++available_cpus;
 	}
 
 	printk("\n");
@@ -314,7 +313,6 @@
 	acpi_table_print_madt_entry(header);
 
 	/* TBD: Support lapic_nmi entries */
-
 	return 0;
 }
 
@@ -405,7 +403,6 @@
 	acpi_table_print_madt_entry(header);
 
 	/* TBD: Support nimsrc entries */
-
 	return 0;
 }
 
@@ -437,22 +434,209 @@
 }
 
 
+#ifdef CONFIG_ACPI_NUMA
+
+#define PXM_FLAG_LEN ((MAX_PXM_DOMAINS + 1)/32)
+
+static int __initdata srat_num_cpus;			/* number of cpus */
+static u32 __initdata pxm_flag[PXM_FLAG_LEN];
+#define pxm_bit_set(bit)	(set_bit(bit,(void *)pxm_flag))
+#define pxm_bit_test(bit)	(test_bit(bit,(void *)pxm_flag))
+/* maps to convert between proximity domain and logical node ID */
+int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS];
+int __initdata nid_to_pxm_map[NR_NODES];
+struct acpi_table_slit __initdata *slit_table;
+
+/*
+ * ACPI 2.0 SLIT (System Locality Information Table)
+ * http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf
+ */
+void __init
+acpi_numa_slit_init (struct acpi_table_slit *slit)
+{
+	u32 len;
+
+	len = sizeof(struct acpi_table_header) + 8
+		+ slit->localities * slit->localities;
+	if (slit->header.length != len) {
+		printk("KERN_INFO ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n",
+		      len, slit->header.length);
+		memset(numa_slit, 10, sizeof(numa_slit));
+		return;
+	}
+	slit_table = slit;
+}
+
+void __init
+acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa)
+{
+	/* record this node in proximity bitmap */
+	pxm_bit_set(pa->proximity_domain);
+
+	node_cpuid[srat_num_cpus].phys_id = (pa->apic_id << 8) | (pa->lsapic_eid);
+	/* nid should be overridden as logical node id later */
+	node_cpuid[srat_num_cpus].nid = pa->proximity_domain;
+	srat_num_cpus++;
+}
+
+void __init
+acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma)
+{
+	unsigned long paddr, size, hole_size, min_hole_size;
+	u8 pxm;
+	struct node_memblk_s *p, *q, *pend;
+
+	pxm = ma->proximity_domain;
+
+	/* fill node memory chunk structure */
+	paddr = ma->base_addr_hi;
+	paddr = (paddr << 32) | ma->base_addr_lo;
+	size = ma->length_hi;
+	size = (size << 32) | ma->length_lo;
+
+	if (num_memblks >= NR_MEMBLKS) {
+		printk(KERN_ERR "Too many mem chunks in SRAT. Ignoring %ld MBytes at %lx\n",
+			size/(1024*1024), paddr);
+		return;
+	}
+
+	/* Ignore disabled entries */
+	if (!ma->flags.enabled)
+		return;
+
+	/*
+	 * When the chunk is not the first one in the node, check distance
+	 * from the other chunks. When the hole is too huge ignore the chunk.
+	 * This restriction should be removed when multiple chunks per node
+	 * is supported.
+	 */
+	pend = &node_memblk[num_memblks];
+	min_hole_size = 0;
+	for (p = &node_memblk[0]; p < pend; p++) {
+		if (p->nid != pxm)
+			continue;
+		if (p->start_paddr < paddr)
+			hole_size = paddr - (p->start_paddr + p->size);
+		else
+			hole_size = p->start_paddr - (paddr + size);
+
+		if (!min_hole_size || hole_size < min_hole_size)
+			min_hole_size = hole_size;
+	}
+
+#if 0	/* test */
+	if (min_hole_size) {
+		if (min_hole_size > size) {
+			printk(KERN_ERR "Too huge memory hole. Ignoring %ld MBytes at %lx\n",
+				size/(1024*1024), paddr);
+			return;
+		}
+	}
+#endif
+
+	/* record this node in proximity bitmap */
+	pxm_bit_set(pxm);
+
+	/* Insertion sort based on base address */
+	pend = &node_memblk[num_memblks];
+	for (p = &node_memblk[0]; p < pend; p++) {
+		if (paddr < p->start_paddr)
+			break;
+	}
+	if (p < pend) {
+		for (q = pend; q >= p; q--)
+			*(q + 1) = *q;
+	}
+	p->start_paddr = paddr;
+	p->size = size;
+	p->nid = pxm;
+	num_memblks++;
+}
+
+void __init
+acpi_numa_arch_fixup(void)
+{
+	int i, j, node_from, node_to;
+
+	if (srat_num_cpus == 0) {
+		node_cpuid[0].phys_id = hard_smp_processor_id();
+		return;
+	}
+
+	/* calculate total number of nodes in system from PXM bitmap */
+	numnodes = 0;		/* init total nodes in system */
+
+	memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map));
+	memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map));
+	for (i = 0; i < MAX_PXM_DOMAINS; i++) {
+		if (pxm_bit_test(i)) {
+			pxm_to_nid_map[i] = numnodes;
+			nid_to_pxm_map[numnodes++] = i;
+		}
+	}
+
+	/* set logical node id in memory chunk structure */
+	for (i = 0; i < num_memblks; i++)
+		node_memblk[i].nid = pxm_to_nid_map[node_memblk[i].nid];
+
+	/* assign memory bank numbers for each chunk on each node */
+	for (i = 0; i < numnodes; i++) {
+		int bank;
+
+		bank = 0;
+		for (j = 0; j < num_memblks; j++)
+			if (node_memblk[j].nid == i)
+				node_memblk[j].bank = bank++;
+	}
+
+	/* set logical node id in cpu structure */
+	for (i = 0; i < srat_num_cpus; i++)
+		node_cpuid[i].nid = pxm_to_nid_map[node_cpuid[i].nid];
+
+	printk(KERN_INFO "Number of logical nodes in system = %d\n", numnodes);
+	printk(KERN_INFO "Number of memory chunks in system = %d\n", num_memblks);
+
+	if (!slit_table) return;
+	memset(numa_slit, -1, sizeof(numa_slit));
+	for (i=0; i<slit_table->localities; i++) {
+		if (!pxm_bit_test(i))
+			continue;
+		node_from = pxm_to_nid_map[i];
+		for (j=0; j<slit_table->localities; j++) {
+			if (!pxm_bit_test(j))
+				continue;
+			node_to = pxm_to_nid_map[j];
+			node_distance(node_from, node_to) = 
+				slit_table->entry[i*slit_table->localities + j];
+		}
+	}
+
+#ifdef SLIT_DEBUG
+	printk(KERN_DEBUG "ACPI 2.0 SLIT locality table:\n");
+	for (i = 0; i < numnodes; i++) {
+		for (j = 0; j < numnodes; j++)
+			printk(KERN_DEBUG "%03d ", node_distance(i,j));
+		printk("\n");
+	}
+#endif
+}
+#endif /* CONFIG_ACPI_NUMA */
+
 static int __init
 acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
 {
 	struct acpi_table_header *fadt_header;
-	fadt_descriptor_rev2 *fadt;
+	struct fadt_descriptor_rev2 *fadt;
 	u32 sci_irq;
 
 	if (!phys_addr || !size)
 		return -EINVAL;
 
 	fadt_header = (struct acpi_table_header *) __va(phys_addr);
-
 	if (fadt_header->revision != 3)
 		return -ENODEV;		/* Only deal with ACPI 2.0 FADT */
 
-	fadt = (fadt_descriptor_rev2 *) fadt_header;
+	fadt = (struct fadt_descriptor_rev2 *) fadt_header;
 
 	if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER))
 		acpi_kbd_controller_present = 0;
@@ -479,20 +663,13 @@
 		rsdp_phys = __pa(efi.acpi20);
 	else if (efi.acpi)
 		printk(KERN_WARNING PREFIX "v1.0/r0.71 tables no longer supported\n");
-
 	return rsdp_phys;
 }
 
 
 int __init
-acpi_boot_init (char *cmdline)
+acpi_boot_init (void)
 {
-	int result;
-
-	/* Initialize the ACPI boot-time table parser */
-	result = acpi_table_init(cmdline);
-	if (result)
-		return result;
 
 	/*
 	 * MADT
@@ -509,65 +686,76 @@
 
 	/* Local APIC */
 
-	if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR,
-				  acpi_parse_lapic_addr_ovr) < 0)
+	if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr) < 0)
 		printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
 
-	if (acpi_table_parse_madt(ACPI_MADT_LSAPIC,
-				  acpi_parse_lsapic) < 1)
+	if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic) < 1)
 		printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n");
 
-	if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI,
-				  acpi_parse_lapic_nmi) < 0)
+	if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi) < 0)
 		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
 
 	/* I/O APIC */
 
-	if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC,
-				  acpi_parse_iosapic) < 1)
-		printk(KERN_ERR PREFIX "Error parsing MADT - no IOAPIC entries\n");
+	if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, acpi_parse_iosapic) < 1)
+		printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n");
 
 	/* System-Level Interrupt Routing */
 
-	if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC,
-				  acpi_parse_plat_int_src) < 0)
+	if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src) < 0)
 		printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n");
 
-	if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR,
-				  acpi_parse_int_src_ovr) < 0)
+	if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr) < 0)
 		printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
 
-	if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC,
-				  acpi_parse_nmi_src) < 0)
+	if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src) < 0)
 		printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
-skip_madt:
+  skip_madt:
 
 	/*
-	 * The FADT table contains an SCI_INT line, by which the system
+	 * FADT says whether a legacy keyboard controller is present.
+	 * The FADT also contains an SCI_INT line, by which the system
 	 * gets interrupts such as power and sleep buttons.  If it's not
 	 * on a Legacy interrupt, it needs to be setup.
 	 */
-	if (acpi_table_parse(ACPI_FACP, acpi_parse_fadt) < 1)
+	if (acpi_table_parse(ACPI_FADT, acpi_parse_fadt) < 1)
 		printk(KERN_ERR PREFIX "Can't find FADT\n");
 
 #ifdef CONFIG_SMP
 	if (available_cpus == 0) {
 		printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
+		printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id());
+		smp_boot_data.cpu_phys_id[available_cpus] = hard_smp_processor_id();
 		available_cpus = 1; /* We've got at least one of these, no? */
 	}
-	smp_boot_data.cpu_count = total_cpus;
+	smp_boot_data.cpu_count = available_cpus;
+
+	smp_build_cpu_map();
+# ifdef CONFIG_NUMA
+	/* If the platform did not have an SRAT table, initialize the
+	 * node_cpuid table from the smp_boot_data array. All cpus
+	 * will be on node 0.
+	 */
+	if (srat_num_cpus == 0) {
+		int cpu, i=1;
+		for (cpu=0; cpu<smp_boot_data.cpu_count; cpu++)
+			if (smp_boot_data.cpu_phys_id[cpu] != hard_smp_processor_id())
+				node_cpuid[i++].phys_id = smp_boot_data.cpu_phys_id[cpu];
+	}
+	build_cpu_to_node_map();
+# endif
+
 #endif
 	/* Make boot-up look pretty */
 	printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
 	return 0;
 }
 
+/*
+ * PCI Interrupt Routing
+ */
 
-/* --------------------------------------------------------------------------
-                             PCI Interrupt Routing
-   -------------------------------------------------------------------------- */
 #ifdef CONFIG_PCI
-
 int __init
 acpi_get_prt (struct pci_vector_struct **vectors, int *count)
 {
@@ -609,7 +797,8 @@
 	*count = acpi_prt.count;
 	return 0;
 }
-#endif
+#endif /* CONFIG_PCI */
+
 /* Assume IA64 always use I/O SAPIC */
 
 int __init
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/efi.c linux-2.4.23-pre8/arch/ia64/kernel/efi.c
--- linux-2.4.22/arch/ia64/kernel/efi.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/efi.c	2003-10-22 22:47:36.000000000 +0000
@@ -46,7 +46,7 @@
  * prior to creating their own entries under /proc/efi.
  */
 #ifdef CONFIG_PROC_FS
-struct proc_dir_entry *efi_dir = NULL;
+struct proc_dir_entry *efi_dir;
 #endif
 
 static unsigned long mem_limit = ~0UL;
@@ -324,7 +324,7 @@
 				check_md = q;
 
 				if (check_md->attribute & EFI_MEMORY_WB)
-					trim_bottom(md, granule_addr);
+					trim_bottom(check_md, granule_addr);
 
 				if (check_md->phys_addr < granule_addr)
 					continue;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/efi_stub.S linux-2.4.23-pre8/arch/ia64/kernel/efi_stub.S
--- linux-2.4.22/arch/ia64/kernel/efi_stub.S	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/efi_stub.S	2003-10-22 22:47:28.000000000 +0000
@@ -62,7 +62,7 @@
 	mov b6=r2
 	;;
 	andcm r16=loc3,r16		// get psr with IT, DT, and RT bits cleared
-	br.call.sptk.many rp=ia64_switch_mode
+	br.call.sptk.many rp=ia64_switch_mode_phys
 .ret0:	mov out4=in5
 	mov out0=in1
 	mov out1=in2
@@ -73,7 +73,7 @@
 	br.call.sptk.many rp=b6		// call the EFI function
 .ret1:	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	mov r16=loc3
-	br.call.sptk.many rp=ia64_switch_mode // return to virtual mode
+	br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
 .ret2:	mov ar.rsc=loc4			// restore RSE configuration
 	mov ar.pfs=loc1
 	mov rp=loc0
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/efivars.c linux-2.4.23-pre8/arch/ia64/kernel/efivars.c
--- linux-2.4.22/arch/ia64/kernel/efivars.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/efivars.c	2003-10-22 22:48:53.000000000 +0000
@@ -119,7 +119,7 @@
 */
 static spinlock_t efivars_lock = SPIN_LOCK_UNLOCKED;
 static LIST_HEAD(efivar_list);
-static struct proc_dir_entry *efi_vars_dir = NULL;
+static struct proc_dir_entry *efi_vars_dir;
 
 #define efivar_entry(n) list_entry(n, efivar_entry_t, list)
 
@@ -138,8 +138,7 @@
 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);
+	return utf8_strlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t);
 }
 
 
@@ -169,8 +168,7 @@
 			 efi_char16_t *variable_name,
 			 efi_guid_t *vendor_guid)
 {
-	int i, short_name_size = variable_name_size /
-		sizeof(efi_char16_t) + 38;
+	int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38;
 	char *short_name;
 	efivar_entry_t *new_efivar;
 
@@ -191,7 +189,7 @@
 
 	/* 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++) {
+	for (i=0; i< (int) (variable_name_size / sizeof(efi_char16_t)); i++) {
 		short_name[i] = variable_name[i] & 0xFF;
 	}
 
@@ -290,7 +288,7 @@
 	}
 	if (copy_from_user(var_data, buffer, size)) {
 		MOD_DEC_USE_COUNT;
-                kfree(var_data);
+		kfree(var_data);
 		return -EFAULT;
 	}
 
@@ -433,7 +431,7 @@
 	   to do this.
 	*/
 	if (!efi_dir)
-                efi_dir = proc_mkdir("efi", NULL);
+		efi_dir = proc_mkdir("efi", NULL);
 
 	efi_systab_entry = create_proc_entry("systab", S_IRUSR | S_IRGRP, efi_dir);
 	if (efi_systab_entry)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/entry.S linux-2.4.23-pre8/arch/ia64/kernel/entry.S
--- linux-2.4.22/arch/ia64/kernel/entry.S	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/entry.S	2003-10-22 22:48:15.000000000 +0000
@@ -3,6 +3,9 @@
  *
  * Kernel entry points.
  *
+ * Copyright (C) 2002-2003 
+ * 	Suresh Siddha <suresh.b.siddha@intel.com> 
+ *	Fenghua Yu <fenghua.yu@intel.com>
  * Copyright (C) 1998-2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
@@ -48,7 +51,10 @@
 ENTRY(ia64_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
+	/* Leave from kernel and restore all pt_regs to correspending registers. This is special 
+	 * because ia32 application needs scratch registers after return from execve.
+	 */
+	movl loc0=ia64_ret_from_execve_syscall 
 	.body
 	mov out0=in0			// filename
 	;;				// stop bit between alloc and call
@@ -72,19 +78,18 @@
 	 * 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
+	mov ar.unat=0; 		mov ar.lc=0;
+	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
+	ldf.fill f12=[sp];      mov f13=f0;             mov b5=r0
+	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
 	br.ret.sptk.many rp
 END(ia64_execve)
 
@@ -251,8 +256,6 @@
 	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 r26=b5
 	;;
 	st8 [r14]=r23,16	// save b2
@@ -351,9 +354,6 @@
 	ldf.fill f4=[r14],32
 	ldf.fill f5=[r15],32
 	;;
-	ldf.fill f10=[r14],32
-	ldf.fill f11=[r15],32
-	;;
 	ldf.fill f12=[r14],32
 	ldf.fill f13=[r15],32
 	;;
@@ -475,7 +475,7 @@
 .mem.offset 8,0;	st8.spill [r3]=r10	// clear error indication in slot for r10
 ia64_strace_leave_kernel:
 	br.call.sptk.many rp=invoke_syscall_trace // give parent a chance to catch return value
-.rety:	br.cond.sptk ia64_leave_kernel
+.rety:	br.cond.sptk ia64_leave_syscall
 
 strace_error:
 	ld8 r3=[r2]				// load pt_regs.r8
@@ -528,12 +528,186 @@
 (p7)	br.cond.spnt handle_syscall_error	// handle potential syscall failure
 END(ia64_ret_from_syscall)
 	// fall through
+/*
+ * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
+ *	need to switch to bank 0 and doesn't restore the scratch registers.
+ *	To avoid leaking kernel bits, the scratch registers are set to
+ *	the following known-to-be-safe values:
+ *
+ *		  r1: restored (global pointer)
+ *		  r2: cleared
+ *		  r3: cleared
+ *	      r8-r11: restored (syscall return value(s))
+ *		 r12: restored (user-level stack pointer)
+ *		 r13: restored (user-level thread pointer)
+ *		 r14: cleared
+ *		 r15: restored (syscall #)
+ *	     r16-r19: cleared
+ *		 r20: user-level ar.fpsr
+ *		 r21: user-level b0
+ *		 r22: cleared
+ *		 r23: user-level ar.bspstore
+ *		 r24: user-level ar.rnat
+ *		 r25: user-level ar.unat
+ *		 r26: user-level ar.pfs
+ *		 r27: user-level ar.rsc
+ *		 r28: user-level ip
+ *		 r29: user-level psr
+ *		 r30: user-level cfm
+ *		 r31: user-level pr
+ *	      f6-f11: cleared
+ *		  pr: restored (user-level pr)
+ *		  b0: restored (user-level rp)
+ *	          b6: cleared
+ *		  b7: cleared
+ *	     ar.unat: restored (user-level ar.unat)
+ *	      ar.pfs: restored (user-level ar.pfs)
+ *	      ar.rsc: restored (user-level ar.rsc)
+ *	     ar.rnat: restored (user-level ar.rnat)
+ *	 ar.bspstore: restored (user-level ar.bspstore)
+ *	     ar.fpsr: restored (user-level ar.fpsr)
+ *	      ar.ccv: cleared
+ *	      ar.csd: cleared
+ *	      ar.ssd: cleared
+ */
+GLOBAL_ENTRY(ia64_leave_syscall)
+	PT_REGS_UNWIND_INFO(0)
+	lfetch.fault [sp]
+	movl r14=.restart1
+	;;
+	mov.ret.sptk rp=r14,.restart1
+	cmp.eq pLvSys,p0=r0,r0			// pLvSys=1: leave from syscall
+.restart1:
+	// need_resched and signals atomic test
+(pUser)	rsm psr.i
+	adds r17=IA64_TASK_NEED_RESCHED_OFFSET,r13
+	adds r18=IA64_TASK_SIGPENDING_OFFSET,r13
+#ifdef CONFIG_PERFMON
+	adds r19=IA64_TASK_PFM_OVFL_BLOCK_RESET_OFFSET,r13
+#endif
+	;;
+#ifdef CONFIG_PERFMON
+(pUser)	ld8 r19=[r19]				// load current->thread.pfm_ovfl_block_reset
+#endif
+(pUser)	ld8 r17=[r17]				// load current->need_resched
+(pUser)	ld4 r18=[r18]				// load current->sigpending
+	;;
+#ifdef CONFIG_PERFMON
+(pUser)	cmp.ne.unc p9,p0=r19,r0			// current->thread.pfm_ovfl_block_reset != 0?
+#endif
+(pUser)	cmp.ne.unc p7,p0=r17,r0			// current->need_resched != 0?
+(pUser)	cmp.ne.unc p8,p0=r18,r0			// current->sigpending != 0?
+	;;
+#ifdef CONFIG_PERFMON
+(p9)	br.call.spnt.many b7=pfm_ovfl_block_reset
+#endif
+#if __GNUC__ < 3
+(p7)	br.call.spnt.many b7=invoke_schedule
+#else
+(p7)	br.call.spnt.many b7=schedule
+#endif
+(p8)	br.call.spnt.many rp=handle_signal_delivery	// check & deliver pending signals (once)
+
+	mov  ar.csd=r0
+	mov  ar.ssd=r0
+	adds r16=PT(LOADRS)+16,r12
+	adds r17=PT(AR_BSPSTORE)+16, r12
+	mov  f6=f0		// clear f6
+	;;
+	ld8 r19=[r16],PT(R8)-PT(LOADRS)        		// load ar.rsc value for "loadrs"
+	ld8 r23=[r17],PT(R9)-PT(AR_BSPSTORE)	// load ar.bspstore (may be garbage)
+	mov r22=r0		// clear r22
+	;;
+	// start restoring the state saved on the kernel stack (struct pt_regs):
+	ld8.fill r8=[r16],16
+	ld8.fill r9=[r17],16
+	mov  f7=f0		// clear f7
+	;;
+	ld8.fill r10=[r16],16
+	ld8.fill r11=[r17],16
+	mov  f8=f0		// clear f8
+	;;
+	ld8 r29=[r16],16	// load cr.ipsr
+	ld8 r28=[r17],16	// load cr.iip
+	mov b7=r0		// clear b7
+	;;
+	ld8 r30=[r16],16	// load cr.ifs
+	ld8 r25=[r17],16	// load ar.unat
+	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
+	;;
+	rsm psr.i | psr.ic	// initiate turning off of interrupt and interruption collection
+	invala			// invalidate ALAT
+	mov  f9=f0		// clear f9
+	;;
+	ld8 r26=[r16],16 	// load ar.pfs
+	ld8 r27=[r17],PT(PR)-PT(AR_RSC)// load ar.rsc
+	mov  f10=f0		// clear f10
+	;;
+	ld8 r24=[r16],PT(B0)-PT(AR_RNAT)// load ar.rnat (may be garbage)
+	ld8 r31=[r17],PT(R1)-PT(PR)	    // load predicates
+	mov  f11=f0		// clear f11
+	;;
+	ld8 r21=[r16],PT(R12)-PT(B0)// load b0
+	ld8.fill r1=[r17],16	// load r1
+	mov r3=r0		// clear r3
+	;;
+	ld8.fill r12=[r16],16
+	ld8.fill r13=[r17],16
+	mov r2=r0		// clear r2
+	;;
+	ld8 r20=[r16]		// ar.fpsr
+	ld8.fill r15=[r17]	// load r15
+	adds r18=16,r16
+	;;
+	mov r16=ar.bsp		// get existing backing store pointer
+	movl r17=PERCPU_ADDR+IA64_CPU_PHYS_STACKED_SIZE_P8_OFFSET
+	srlz.i			// ensure interruption collection is off
+	mov ar.ccv=r0		// clear ar.ccv
+	mov b6=r0		// clear b6
+	;;
+	ld4 r17=[r17]		// r17 = cpu_data->phys_stacked_size_p8
+	mov r14=r0		// clear r14
+(pKern)	br.cond.dpnt skip_rbs_switch
+	/*
+	 * Restore user backing store.
+	 *
+	 * NOTE: alloc, loadrs, and cover can't be predicated.
+	 */
+	cover				// add current frame into dirty partition
+	shr.u r18=r19,16	// get byte size of existing "dirty" partition
+	;;
+	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
+	;;
+	sub r19=r19,r16			// calculate total byte size of dirty partition
+	add r18=64,r18			// don't force in0-in7 into memory...
+	;;
+	shl r19=r19,16			// shift size of dirty partition into loadrs position
+	br.few dont_preserve_current_frame
+	;;
+END(ia64_leave_syscall)
+
+GLOBAL_ENTRY(ia64_ret_from_execve_syscall)
+	PT_REGS_UNWIND_INFO(0)
+	cmp.ge p6,p7=r8,r0			// syscall executed successfully?
+	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
+	.mem.offset 8,0
+(p6)	st8.spill [r3]=r0	// clear error indication in slot for r10 and set unat bit
+(p7)	br.cond.spnt handle_syscall_error	// handle potential syscall failure
+END(ia64_ret_from_execve_syscall)
+	// fall through
 GLOBAL_ENTRY(ia64_leave_kernel)
 	PT_REGS_UNWIND_INFO(0)
 	lfetch.fault [sp]
 	movl r14=.restart
 	;;
 	mov.ret.sptk rp=r14,.restart
+	cmp.eq p0,pLvSys=r0,r0			// pLvSys=0: leave from kernel
 .restart:
 	// need_resched and signals atomic test
 (pUser)	rsm psr.i
@@ -564,18 +738,35 @@
 (p7)	br.call.spnt.many b7=schedule
 #endif
 (p8)	br.call.spnt.many rp=handle_signal_delivery	// check & deliver pending signals (once)
+
+	adds r20=PT(CR_IPSR)+16,r12
+	adds r21=PT(PR)+16,r12
 	;;
-.ret9:	adds r2=PT(R8)+16,r12
-	adds r3=PT(R9)+16,r12
+	lfetch.fault.excl [r20]
+	lfetch.fault.excl [r21]
+	adds r2=PT(B6)+16,r12
+	adds r3=PT(R16)+16,r12
+	mov r29=PT(R24)-PT(B6)
+	mov r30=PT(B7)-PT(R24)
 	;;
 	// start restoring the state saved on the kernel stack (struct pt_regs):
-	ld8.fill r8=[r2],16
-	ld8.fill r9=[r3],16
+	ld8 r28=[r2],r29	// b6
+	ld8.fill r16=[r3],128
+	mov r31=PT(AR_CSD)-PT(AR_CCV)
+	;;
+	ld8.fill r24=[r2],r30
+	ld8 r15=[r3],r31
+	;; 
+	ld8 r29=[r2],16		// b7
+	ld8 r30=[r3],16		// ar.csd
 	;;
-	ld8.fill r10=[r2],16
-	ld8.fill r11=[r3],16
+	ld8 r31=[r2],16		// ar.ssd
+	ld8.fill r8=[r3],16
 	;;
-	ld8.fill r16=[r2],16
+	ld8.fill r9=[r2],16
+	ld8.fill r10=[r3],PT(R17)-PT(R10)
+	;;
+	ld8.fill r11=[r2],PT(R18)-PT(R11)
 	ld8.fill r17=[r3],16
 	;;
 	ld8.fill r18=[r2],16
@@ -583,82 +774,78 @@
 	;;
 	ld8.fill r20=[r2],16
 	ld8.fill r21=[r3],16
-	;;
-	ld8.fill r22=[r2],16
-	ld8.fill r23=[r3],16
-	;;
-	ld8.fill r24=[r2],16
-	ld8.fill r25=[r3],16
-	;;
-	ld8.fill r26=[r2],16
-	ld8.fill r27=[r3],16
-	;;
-	ld8.fill r28=[r2],16
-	ld8.fill r29=[r3],16
-	;;
-	ld8.fill r30=[r2],16
-	ld8.fill r31=[r3],16
+	mov ar.csd=r30
+	mov ar.ssd=r31
 	;;
 	rsm psr.i | psr.ic	// initiate turning off of interrupt and interruption collection
 	invala			// invalidate ALAT
 	;;
-	ld8 r1=[r2],16		// ar.ccv
-	ld8 r13=[r3],16		// ar.fpsr
+	ld8.fill r22=[r2],24
+	ld8.fill r23=[r3],24
+	mov b6=r28
+	;;
+	ld8.fill r25=[r2],16
+	ld8.fill r26=[r3],16
+	mov b7=r29
 	;;
-	ld8 r14=[r2],16		// b0
-	ld8 r15=[r3],16+8	// b7
+	ld8.fill r27=[r2],16
+	ld8.fill r28=[r3],16
 	;;
-	ldf.fill f6=[r2],32
-	ldf.fill f7=[r3],32
+	ld8.fill r29=[r2],16
+	ld8.fill r30=[r3],24
 	;;
-	ldf.fill f8=[r2],32
-	ldf.fill f9=[r3],32
+	ld8.fill r31=[r2],32
+	ldf.fill f6=[r3],32
 	;;
-	mov ar.ccv=r1
-	mov ar.fpsr=r13
-	mov b0=r14
+	ldf.fill f7=[r2],32
+	ldf.fill f8=[r3],32
 	;;
 	srlz.i			// ensure interruption collection is off
-	mov b7=r15
+	mov ar.ccv=r15
 	;;
+	ldf.fill f9=[r2],32
+	ldf.fill f10=[r3],32
 	bsw.0			// switch back to bank 0
 	;;
-	adds r16=16,r12
-	adds r17=24,r12
+	ldf.fill f11=[r2]
+	adds r16=PT(CR_IPSR)+16,r12
+	adds r17=PT(CR_IIP)+16,r12
 	;;
-	ld8 rCRIPSR=[r16],16	// load cr.ipsr
-	ld8 rCRIIP=[r17],16	// load cr.iip
+	ld8 r29=[r16],16	// load cr.ipsr
+	ld8 r28=[r17],16	// load cr.iip
 	;;
-	ld8 rCRIFS=[r16],16	// load cr.ifs
-	ld8 rARUNAT=[r17],16	// load ar.unat
+	ld8 r30=[r16],16	// load cr.ifs
+	ld8 r25=[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 r26=[r16],16	// load ar.pfs
+	ld8 r27=[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 r24=[r16],16	// load ar.rnat (may be garbage)
+	ld8 r23=[r17],16 // load ar.bspstore (may be garbage)
 	;;
-	ld8 rARPR=[r16],16	// load predicates
-	ld8 rB6=[r17],16	// load b6
+	ld8 r31=[r16],16	// load predicates
+	ld8 r21=[r17],16	// load b0
 	;;
 	ld8 r19=[r16],16	// load ar.rsc value for "loadrs"
 	ld8.fill r1=[r17],16	// load r1
 	;;
-	ld8.fill r2=[r16],16
-	ld8.fill r3=[r17],16
-	;;
 	ld8.fill r12=[r16],16
 	ld8.fill r13=[r17],16
 	;;
+	ld8 r20=[r16],16
+	ld8.fill r15=[r17],16
+	;;
 	ld8.fill r14=[r16]
-	ld8.fill r15=[r17]
-	shr.u r18=r19,16	// get byte size of existing "dirty" partition
+	ld8.fill r2=[r17],16
+	adds r18=16,r16
 	;;
 	mov r16=ar.bsp		// get existing backing store pointer
 	movl r17=PERCPU_ADDR+IA64_CPU_PHYS_STACKED_SIZE_P8_OFFSET
 	;;
+	ld8.fill r3=[r18]
 	ld4 r17=[r17]		// r17 = cpu_data->phys_stacked_size_p8
+	shr.u r18=r19,16	// get byte size of existing "dirty" partition
 (pKern)	br.cond.dpnt skip_rbs_switch
 	/*
 	 * Restore user backing store.
@@ -718,7 +905,7 @@
 }{ .mib
 	mov loc3=0
 	mov loc4=0
-(pRecurse) br.call.sptk.many b6=rse_clear_invalid
+(pRecurse) br.call.sptk.many b0=rse_clear_invalid
 
 }{ .mfi	// cycle 2
 	mov loc5=0
@@ -727,7 +914,7 @@
 }{ .mib
 	mov loc6=0
 	mov loc7=0
-(pReturn) br.ret.sptk.many b6
+(pReturn) br.ret.sptk.many b0
 }
 #else /* !CONFIG_ITANIUM */
 	alloc loc0=ar.pfs,2,Nregs-2,2,0
@@ -742,14 +929,14 @@
 	mov loc5=0
 	mov loc6=0
 	mov loc7=0
-(pRecurse) br.call.sptk.many b6=rse_clear_invalid
+(pRecurse) br.call.sptk.many b0=rse_clear_invalid
 	;;
 	mov loc8=0
 	mov loc9=0
 	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
 	mov loc10=0
 	mov loc11=0
-(pReturn) br.ret.sptk.many b6
+(pReturn) br.ret.sptk.many b0
 #endif /* !CONFIG_ITANIUM */
 #	undef pRecurse
 #	undef pReturn
@@ -759,17 +946,22 @@
 	loadrs
 	;;
 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 pr=rARPR,-1
+(pLvSys)mov r19=r0		// clear r19 for leave_syscall, no-op otherwise
+	mov b0=r21
+	mov ar.pfs=r26
+(pUser)	mov ar.bspstore=r23
+(p9)	mov cr.ifs=r30
+(pLvSys)mov r16=r0		// clear r16 for leave_syscall, no-op otherwise
+	mov cr.ipsr=r29
+	mov ar.fpsr=r20
+(pLvSys)mov r17=r0		// clear r17 for leave_syscall, no-op otherwise
+	mov cr.iip=r28
+	;;
+(pUser)	mov ar.rnat=r24		// must happen with RSE in lazy mode
+(pLvSys)mov r18=r0		// clear r18 for leave_syscall, no-op otherwise
+	mov ar.rsc=r27
+	mov ar.unat=r25
+	mov pr=r31,-1
 	rfi
 END(ia64_leave_kernel)
 
@@ -795,7 +987,7 @@
 	;;
 .mem.offset 0,0; st8.spill [r2]=r9	// store errno in pt_regs.r8 and set unat bit
 .mem.offset 8,0; st8.spill [r3]=r10	// store error indication in pt_regs.r10 and set unat bit
-	br.cond.sptk ia64_leave_kernel
+	br.cond.sptk ia64_leave_syscall
 END(handle_syscall_error)
 
 	/*
@@ -906,6 +1098,22 @@
 	.body
 	cmp.eq pNonSys,pSys=r0,r0		// sigreturn isn't a normal syscall...
 	;;
+	/* After signal handler, live registers f6-f11 are restored to the previous
+	 * executing context values for synchronized signals(from exceptions); or they 
+	 * are cleared to 0 for asynchronized signals(from syscalls). These live registers 
+	 * will be put into pt_regs to return back to user space.
+	 */
+	adds r16=PT(F6)+32,sp
+	adds r17=PT(F7)+32,sp
+	;;
+ 	stf.spill [r16]=f6,32	
+ 	stf.spill [r17]=f7,32	
+	;;
+ 	stf.spill [r16]=f8,32	
+ 	stf.spill [r17]=f9,32	
+	;;
+ 	stf.spill [r16]=f10	
+ 	stf.spill [r17]=f11	
 	adds out0=16,sp				// out0 = &sigscratch
 	br.call.sptk.many rp=ia64_rt_sigreturn
 .ret19:	.restore sp 0
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/entry.h linux-2.4.23-pre8/arch/ia64/kernel/entry.h
--- linux-2.4.22/arch/ia64/kernel/entry.h	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/entry.h	2003-10-22 22:48:34.000000000 +0000
@@ -4,6 +4,7 @@
  * Preserved registers that are shared between code in ivt.S and entry.S.  Be
  * careful not to step on these!
  */
+#define pLvSys		p1	/* set 1 if leave from syscall; otherwise, set 0*/
 #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? */
@@ -13,7 +14,7 @@
 #define SW(f)		(IA64_SWITCH_STACK_##f##_OFFSET)
 
 #define PT_REGS_SAVES(off)			\
-	.unwabi @svr4, 'i';			\
+	.unwabi 3, 'i';				\
 	.fframe IA64_PT_REGS_SIZE+16+(off);	\
 	.spillsp rp, PT(CR_IIP)+16+(off);	\
 	.spillsp ar.pfs, PT(CR_IFS)+16+(off);	\
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/head.S linux-2.4.23-pre8/arch/ia64/kernel/head.S
--- linux-2.4.22/arch/ia64/kernel/head.S	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/head.S	2003-10-22 22:49:10.000000000 +0000
@@ -5,7 +5,7 @@
  * to set up the kernel's global pointer and jump to the kernel
  * entry point.
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
@@ -15,6 +15,7 @@
  * Copyright (C) 1999 Don Dugger <Don.Dugger@intel.com>
  * Copyright (C) 2002 Fenghua Yu <fenghua.yu@intel.com>
  *   -Optimize __ia64_save_fpu() and __ia64_load_fpu() for Itanium 2.
+ * Copyright (C) 2003 Silicon Graphics, Inc.
  */
 
 #include <linux/config.h>
@@ -65,17 +66,29 @@
 	 * that maps the kernel's text and data:
 	 */
 	rsm psr.i | psr.ic
-	mov r16=((ia64_rid(IA64_REGION_ID_KERNEL, PAGE_OFFSET) << 8) | (IA64_GRANULE_SHIFT << 2))
 	;;
 	srlz.i
+	;;
+	mov r20=((ia64_rid(IA64_REGION_ID_KERNEL, (7<<61)) << 8) | (IA64_GRANULE_SHIFT << 2))
+	movl r21=(7<<61)
+	;;
+	mov rr[r21]=r20
+	;;
+	/*
+	 * Now pin mappings into the TLB for kernel text and data
+	 */
 	mov r18=KERNEL_TR_PAGE_SHIFT<<2
 	movl r17=KERNEL_START
 	;;
-	mov rr[r17]=r16
 	mov cr.itir=r18
 	mov cr.ifa=r17
 	mov r16=IA64_TR_KERNEL
-	movl r18=((1 << KERNEL_TR_PAGE_SHIFT) | PAGE_KERNEL)
+	mov r3=ip
+	movl r18=PAGE_KERNEL
+	;;
+	dep r2=0,r3,0,KERNEL_TR_PAGE_SHIFT
+	;;
+	or r18=r2,r18
 	;;
 	srlz.i
 	;;
@@ -134,28 +147,63 @@
 	movl r3=cpucount
  	;;
 	ld4 r3=[r3]		// r3 <- smp_processor_id()
-	movl r2=init_tasks
-	;;
-	shladd r2=r3,3,r2
-	;;
-	ld8 r2=[r2]
 #else
 	mov r3=0
-	movl r2=init_task_union
-	;;
 #endif
+	;;
 	cmp4.ne isAP,isBP=r3,r0
-	;;			// RAW on r2
-	extr r3=r2,0,61		// r3 == phys addr of task struct
-	mov r16=KERNEL_TR_PAGE_NUM
+
+	/*
+	 * Make task struct pointer in init_tasks an identity mapped pointer.
+	 * The value that is compiled into the array may not be identity mapped.
+	 */
+	movl r18=init_tasks
+	;;
+	shladd r18=r3,3,r18
+	;;
+	ld8 r8=[r18]
+	;;
+	tpa r3=r8		// r3 == phys addr of task struct
+	;;
+	dep r2=-1,r3,61,3	// IMVA of task
+	;;
+	st8 [r18]=r2		// and save it back in init_tasks[thiscpu]
+
+	// load mapping for stack (virtaddr in r2, physaddr in r3)
+	// load dtr[2] only if the va for current (r2) isn't covered by the dtr[0] 
+	shr.u r18=r2,KERNEL_TR_PAGE_SHIFT               /* va of current in units of kernel-pages */
+	movl r17=KERNEL_START>>KERNEL_TR_PAGE_SHIFT     /* va of kernel-start in units of kernel-pages */
+	;;
+	cmp.eq p0,p6=r17,r18
+	rsm psr.ic
+	movl r17=PAGE_KERNEL
+	;;
+	srlz.d
+	dep r18=0,r3,0,12
+	;;
+	or r18=r17,r18
+	;;
+	mov r17=rr[r2]
+	shr.u r16=r3,IA64_GRANULE_SHIFT
+	;;
+	dep r17=0,r17,8,24
+	;;
+	mov cr.itir=r17
+	mov cr.ifa=r2
+
+	mov r19=IA64_TR_CURRENT_STACK
+	;;
+(p6)	itr.d dtr[r19]=r18
+	;;
+	ssm psr.ic
+	srlz.d
 	;;
 
 	// load the "current" pointer (r13) and ar.k6 with the current task
-	mov r13=r2
 	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)=r16
+	mov r13=r2
+
 	/*
 	 * 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
@@ -670,14 +718,14 @@
 END(__ia64_init_fpu)
 
 /*
- * Switch execution mode from virtual to physical or vice versa.
+ * Switch execution mode from virtual to physical
  *
  * Inputs:
  *	r16 = new psr to establish
  *
  * Note: RSE must already be in enforced lazy mode
  */
-GLOBAL_ENTRY(ia64_switch_mode)
+GLOBAL_ENTRY(ia64_switch_mode_phys)
  {
 	alloc r2=ar.pfs,0,0,0,0
 	rsm psr.i | psr.ic		// disable interrupts and interrupt collection
@@ -687,35 +735,86 @@
  {
 	flushrs				// must be first insn in group
 	srlz.i
-	shr.u r19=r15,61		// r19 <- top 3 bits of current IP
  }
 	;;
 	mov cr.ipsr=r16			// set new PSR
-	add r3=1f-ia64_switch_mode,r15
-	xor r15=0x7,r19			// flip the region bits
+	add r3=1f-ia64_switch_mode_phys,r15
 
 	mov r17=ar.bsp
 	mov r14=rp			// get return address into a general register
+	;;
 
-	// switch RSE backing store:
+	// going to physical mode, use tpa to translate virt->phys
+	tpa r17=r17
+	tpa r3=r3
+	tpa sp=sp
+	tpa r14=r14
 	;;
-	dep r17=r15,r17,61,3		// make ar.bsp physical or virtual
+
 	mov r18=ar.rnat			// save ar.rnat
-	;;
 	mov ar.bspstore=r17		// this steps on ar.rnat
-	dep r3=r15,r3,61,3		// make rfi return address physical or virtual
+	mov cr.iip=r3
+	mov cr.ifs=r0
+	;;
+	mov ar.rnat=r18			// restore ar.rnat
+	rfi				// must be last insn in group
+	;;
+1:	mov rp=r14
+	br.ret.sptk.many rp
+END(ia64_switch_mode_phys)
+
+/*
+ * Switch execution mode from physical to virtual
+ *
+ * Inputs:
+ *	r16 = new psr to establish
+ *
+ * Note: RSE must already be in enforced lazy mode
+ */
+GLOBAL_ENTRY(ia64_switch_mode_virt)
+ {
+	alloc r2=ar.pfs,0,0,0,0
+	rsm psr.i | psr.ic		// disable interrupts and interrupt collection
+	mov r15=ip
+ }
+	;;
+ {
+	flushrs				// must be first insn in group
+	srlz.i
+ }
 	;;
+	mov cr.ipsr=r16			// set new PSR
+	add r3=1f-ia64_switch_mode_virt,r15
+
+	mov r17=ar.bsp
+	mov r14=rp			// get return address into a general register
+	;;
+
+	// going to virtual
+	//   - for code addresses, set upper bits of addr to KERNEL_START
+	//   - for stack addresses, set upper 3 bits to 0xe.... Dont change any of the
+	//     lower bits since we want it to stay identity mapped
+	movl r18=KERNEL_START
+	dep r3=0,r3,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
+	dep r14=0,r14,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
+	dep r17=-1,r17,61,3
+	dep sp=-1,sp,61,3
+	;;
+	or r3=r3,r18
+	or r14=r14,r18
+	;;
+
+	mov r18=ar.rnat			// save ar.rnat
+	mov ar.bspstore=r17		// this steps on ar.rnat
 	mov cr.iip=r3
 	mov cr.ifs=r0
-	dep sp=r15,sp,61,3		// make stack pointer physical or virtual
 	;;
 	mov ar.rnat=r18			// restore ar.rnat
-	dep r14=r15,r14,61,3		// make function return address physical or virtual
 	rfi				// must be last insn in group
 	;;
 1:	mov rp=r14
 	br.ret.sptk.many rp
-END(ia64_switch_mode)
+END(ia64_switch_mode_virt)
 
 #ifdef CONFIG_IA64_BRL_EMU
 
@@ -782,6 +881,9 @@
 	;;
 	// delay a little...
 .wait:	sub tmp=tmp,timeout
+#ifdef GAS_HAS_HINT_INSN
+	hint @pause
+#endif
 	or delay=0xf,delay	// make sure delay is non-zero (otherwise we get stuck with 0)
 	;;
 	cmp.lt p15,p0=tmp,r0
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/iosapic.c linux-2.4.23-pre8/arch/ia64/kernel/iosapic.c
--- linux-2.4.22/arch/ia64/kernel/iosapic.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/iosapic.c	2003-10-22 22:48:54.000000000 +0000
@@ -530,7 +530,7 @@
 		delivery = IOSAPIC_INIT;
 		break;
 	      case ACPI_INTERRUPT_CPEI:
-		vector = IA64_PCE_VECTOR;
+		vector = IA64_CPE_VECTOR;
 		delivery = IOSAPIC_LOWEST_PRIORITY;
 		break;
 	      default:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/ivt.S linux-2.4.23-pre8/arch/ia64/kernel/ivt.S
--- linux-2.4.22/arch/ia64/kernel/ivt.S	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/ivt.S	2003-10-22 22:47:51.000000000 +0000
@@ -1,6 +1,10 @@
 /*
  * arch/ia64/kernel/ivt.S
  *
+ * Copyright (C) 2002-2003 Intel Co
+ *      Suresh Siddha <suresh.b.siddha@intel.com>
+ *      Kenneth Chen <kenneth.w.chen@intel.com>
+ *      Fenghua Yu <fenghua.yu@intel.com>
  * Copyright (C) 1998-2001 Hewlett-Packard Co
  *	Stephane Eranian <eranian@hpl.hp.com>
  *	David Mosberger <davidm@hpl.hp.com>
@@ -621,6 +625,23 @@
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x2c00 Entry 11 (size 64 bundles) Break instruction (33)
 ENTRY(break_fault)
+
+/* System call entry/exit only saves/restores part of pt_regs, i.e. no scratch registers 
+ * are saved/restored except r15 which contains syscall number and needs to be saved in the
+ * entry. This optimization is based on the assumption that applications only call glibc 
+ * system call interface which doesn't use scratch registers after break into kernel.
+ * Registers saved/restored during system call entry/exit are listed as follows:
+ *
+ *   Registers to be saved & restored:
+ *	CR registers: cr_ipsr, cr_iip, cr_ifs
+ *	AR registers: ar_unat, ar_pfs, ar_rsc, ar_rnat, ar_bspstore, ar_fpsr	
+ * 	others: pr, b0, loadrs, r1, r12, r13, r15
+ *   Registers to be restored only:
+ * 	r8~r11: output value from the system call.
+ *
+ * During system call exit, scratch registers (including r15) are modified/cleared to 
+ * prevent leaking bits from kernel to user level.
+ */
 	DBG_FAULT(11)
 	mov r16=cr.iim
 	mov r17=__IA64_BREAK_SYSCALL
@@ -629,22 +650,25 @@
 	cmp.eq p0,p7=r16,r17	// is this a system call? (p7 <- false, if so)
 (p7)	br.cond.spnt non_syscall
 
-	SAVE_MIN				// uses r31; defines r2:
-
-	ssm psr.ic | PSR_DEFAULT_BITS
+	mov r21=ar.fpsr; 
+	mov r29=cr.ipsr;
+	mov r20=r1;
+	mov r25=ar.unat;
+	mov r27=ar.rsc;
+	mov r26=ar.pfs;
+	mov r28=cr.iip;
+	mov r1=IA64_KR(CURRENT);		/* r1 = current (physical) */
+	;;
+	invala;
+	extr.u r16=r29,32,2;			/* extract psr.cpl */
+	;;
+	cmp.eq pKern,pUser=r0,r16;		/* are we in kernel mode already? (psr.cpl==0) */
+	/* switch from user to kernel RBS: */
+	;;
+	mov r30=r0
+	MINSTATE_START_SAVE_MIN_VIRT
+	br.call.sptk.many b7=ia64_syscall_setup
 	;;
-	srlz.i					// guarantee that interruption collection is on
-	cmp.eq pSys,pNonSys=r0,r0		// set pSys=1, pNonSys=0
-	;;
-(p15)	ssm psr.i		// restore psr.i
-	adds r8=(IA64_PT_REGS_R8_OFFSET-IA64_PT_REGS_R16_OFFSET),r2
-	;;
-	stf8 [r8]=f1		// ensure pt_regs.r8 != 0 (see handle_syscall_error)
-	adds r3=8,r2		// set up second base pointer for SAVE_REST
-	;;
-	SAVE_REST
-	br.call.sptk.many rp=demine_args	// clear NaT bits in (potential) syscall args
-
 	mov r3=255
 	adds r15=-1024,r15			// r15 contains the syscall number---subtract 1024
 	adds r2=IA64_TASK_PTRACE_OFFSET,r13	// r2 = &current->ptrace
@@ -664,8 +688,8 @@
 
 	// arrange things so we skip over break instruction when returning:
 
-	adds r16=16,sp				// get pointer to cr_ipsr
-	adds r17=24,sp				// get pointer to cr_iip
+	adds r16=PT(CR_IPSR)+16,sp			// get pointer to cr_ipsr
+	adds r17=PT(CR_IIP)+16,sp			// get pointer to cr_iip
 	;;
 	ld8 r18=[r16]				// fetch cr_ipsr
 	tbit.z p8,p0=r2,PT_TRACESYS_BIT		// (current->ptrace & PF_TRACESYS) == 0?
@@ -685,38 +709,11 @@
 	st8 [r16]=r18				// store new value for cr.isr
 
 (p8)	br.call.sptk.many b6=b6			// ignore this return addr
+
 	br.cond.sptk ia64_trace_syscall
 	// NOT REACHED
 END(break_fault)
 
-ENTRY(demine_args)
-	alloc r2=ar.pfs,8,0,0,0
-	tnat.nz p8,p0=in0
-	tnat.nz p9,p0=in1
-	;;
-(p8)	mov in0=-1
-	tnat.nz p10,p0=in2
-	tnat.nz p11,p0=in3
-
-(p9)	mov in1=-1
-	tnat.nz p12,p0=in4
-	tnat.nz p13,p0=in5
-	;;
-(p10)	mov in2=-1
-	tnat.nz p14,p0=in6
-	tnat.nz p15,p0=in7
-
-(p11)	mov in3=-1
-	tnat.nz p8,p0=r15	// demining r15 is not a must, but it is safer
-
-(p12)	mov in4=-1
-(p13)	mov in5=-1
-	;;
-(p14)	mov in6=-1
-(p15)	mov in7=-1
-(p8)	mov r15=-1
-	br.ret.sptk.many rp
-END(demine_args)
 
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -725,7 +722,6 @@
 	DBG_FAULT(12)
 	mov r31=pr		// prepare to save predicates
 	;;
-
 	SAVE_MIN_WITH_COVER	// uses r31; defines r2 and r3
 	ssm psr.ic | PSR_DEFAULT_BITS
 	;;
@@ -757,6 +753,125 @@
 	DBG_FAULT(14)
 	FAULT(14)
 
+	/*
+	 * 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...
+	 *
+	 * ia64_syscall_setup() is a separate subroutine so that it can
+	 *	allocate stacked registers so it can safely demine any
+	 *	potential NaT values from the input registers.
+	 *
+	 * On entry:
+	 *	- executing on bank 0 or bank 1 register set (doesn't matter)
+	 *	-  r1: stack pointer
+	 *	-  r2: current task pointer
+	 *	-  r3: preserved
+	 *	- r12: original contents (sp to be saved)
+	 *	- r13: original contents (tp to be saved)
+	 *	- r15: original contents (syscall # to be saved)
+	 *	- r18: saved bsp (after switching to kernel stack)
+	 *	- r20: saved r1 (gp)
+	 *	- r21: saved ar.fpsr
+	 *	- r22: kernel's register backing store base (krbs_base)
+	 *	- r23: saved ar.bspstore
+	 *	- r24: saved ar.rnat
+	 *	- r25: saved ar.unat
+	 *	- r26: saved ar.pfs
+	 *	- r27: saved ar.rsc
+	 *	- r28: saved cr.iip
+	 *	- r29: saved cr.ipsr
+	 *	- r31: saved pr
+	 *	-  b0: original contents (to be saved)
+	 * On exit:
+	 *	- executing on bank 1 registers
+	 *	- psr.ic enabled, interrupts restored
+	 *	-  r1: kernel's gp
+	 *	-  r3: preserved (same as on entry)
+	 *	- r12: points to kernel stack
+	 *	- r13: points to current task
+	 *	- p15: TRUE if interrupts need to be re-enabled
+	 *	- ar.fpsr: set to kernel settings
+	 */
+ENTRY(ia64_syscall_setup)
+	alloc r19=ar.pfs,8,0,0,0
+	tnat.nz p8,p0=in0
+	add r16=PT(CR_IPSR),r1  /* initialize first base pointer */
+	;;
+	st8 [r16]=r29,16;   	/* save cr.ipsr */
+	adds r17=PT(CR_IIP),r1; /* initialize second base pointer */
+	;;
+(p8)	mov in0=-1
+	tnat.nz p9,p0=in1
+	st8 [r17]=r28,16;	/* save cr.iip */
+	mov r28=b0;                   
+(pKern) mov r18=r0;             /* make sure r18 isn't NaT */
+	;;
+(p9)	mov in1=-1
+	tnat.nz p10,p0=in2
+	st8 [r16]=r30,16;	/* save cr.ifs */
+	st8 [r17]=r25,16;	/* save ar.unat */
+(pUser) sub r18=r18,r22;	/* r18=RSE.ndirty*8 */
+	;;
+	st8 [r16]=r26,16;	/* save ar.pfs */
+	st8 [r17]=r27,16;	/* save ar.rsc */
+	tbit.nz p15,p0=r29,IA64_PSR_I_BIT
+	;;                      /* avoid RAW on r16 & r17 */
+(p10)	mov in2=-1
+	nop.f 0
+	tnat.nz p11,p0=in3
+(pKern) adds r16=16,r16;        /* skip over ar_rnat field */
+(pKern) adds r17=16,r17;        /* skip over ar_bspstore field */
+	shl r18=r18,16;         /* compute ar.rsc to be used for "loadrs" */
+	;;
+(p11)	mov in3=-1
+	tnat.nz p12,p0=in4
+(pUser) st8 [r16]=r24,16;	/* save ar.rnat */
+(pUser) st8 [r17]=r23,16;	/* save ar.bspstore */
+	;;
+(p12)	mov in4=-1
+	tnat.nz p13,p0=in5
+	st8 [r16]=r31,16;	/* save predicates */
+	st8 [r17]=r28,16;	/* save b0 */
+	dep r14=-1,r0,61,3;
+	;;                                                          
+	st8 [r16]=r18,16;       /* save ar.rsc value for "loadrs" */ 
+	st8.spill [r17]=r20,16;	/* save original r1 */
+	adds r2=IA64_PT_REGS_R16_OFFSET,r1;
+	;;
+(p13)	mov in5=-1
+	tnat.nz p14,p0=in6
+.mem.offset 0,0;                st8.spill [r16]=r12,16;
+.mem.offset 8,0;                st8.spill [r17]=r13,16;
+	cmp.eq pNonSys,pSys=r0,r0       /* initialize pSys=0, pNonSys=1 */
+	;;
+(p14)	mov in6=-1
+	tnat.nz p8,p0=in7
+.mem.offset 0,0;                st8 [r16]=r21,16;    /* ar.fpsr */
+.mem.offset 8,0;                st8.spill [r17]=r15,16;
+	adds r12=-16,r1;        /* switch to kernel memory stack (with 16 bytes of scratch) */
+	;;
+	mov r13=IA64_KR(CURRENT);       /* establish `current' */
+	movl r1=__gp;           /* establish kernel global pointer */
+	;;
+	MINSTATE_END_SAVE_MIN_VIRT
+
+	tnat.nz p9,p0=r15
+(p8)	mov in7=-1
+	ssm psr.ic | PSR_DEFAULT_BITS
+	movl r17=FPSR_DEFAULT
+	adds r8=(IA64_PT_REGS_R8_OFFSET-IA64_PT_REGS_R16_OFFSET),r2
+	;;
+	srlz.i					// guarantee that interruption collection is on
+	cmp.eq pSys,pNonSys=r0,r0		// set pSys=1, pNonSys=0
+(p9)	mov r15=-1
+(p15)	ssm psr.i		// restore psr.i
+	mov.m ar.fpsr=r17
+	stf8 [r8]=f1            // ensure pt_regs.r8 != 0 (see handle_syscall_error)
+	br.ret.sptk.many b7
+END(ia64_syscall_setup)
+
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x3c00 Entry 15 (size 64 bundles) Reserved
@@ -808,90 +923,6 @@
 	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...
-	 */
-
-	// IA32 interrupt entry point
-
-ENTRY(dispatch_to_ia32_handler)
-	SAVE_MIN
-	;;
-	mov r14=cr.isr
-	ssm psr.ic | PSR_DEFAULT_BITS
-	;;
-	srlz.i					// guarantee that interruption collection is on
-	;;
-(p15)	ssm psr.i
-	adds r3=8,r2            // Base pointer for SAVE_REST
-	;;
-	SAVE_REST
-	;;
-	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
-
-	adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp	// 16 byte hole per SW conventions
-	adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp
-	;;
-	cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
-	st8 [r15]=r8		// save original 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=230		// number of entries in ia32 system call table
-	;;
-	cmp.ltu.unc p6,p7=r8,r15
-	ld4 out1=[r14],8	// r9 == ecx
-	;;
-	ld4 out2=[r14],8	// r10 == edx
-	;;
-	ld4 out0=[r14]		// r11 == ebx
-	adds r14=(IA64_PT_REGS_R8_OFFSET-(8*3)) + 16,sp
-	;;
-	ld4 out5=[r14],8	// r13 == ebp
-	;;
-	ld4 out3=[r14],8	// r14 == esi
-	adds r2=IA64_TASK_PTRACE_OFFSET,r13	// r2 = &current->ptrace
-	;;
-	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?
-	;;
-	mov b6=r16
-	movl r15=ia32_ret_from_syscall
-	;;
-	mov rp=r15
-(p8)	br.call.sptk.many b6=b6
-	br.cond.sptk ia32_trace_syscall
-
-non_ia32_syscall:
-	alloc r15=ar.pfs,0,0,2,0
-	mov out0=r14				// interrupt #
-	add out1=16,sp				// pointer to pt_regs
-	;;			// avoid WAW on CFM
-	br.call.sptk.many rp=ia32_bad_interrupt
-.ret1:	movl r15=ia64_leave_kernel
-	;;
-	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
@@ -1415,3 +1446,89 @@
 // 0x7f00 Entry 67 (size 16 bundles) Reserved
 	DBG_FAULT(67)
 	FAULT(67)
+
+#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...
+	 */
+
+	// IA32 interrupt entry point
+
+ENTRY(dispatch_to_ia32_handler)
+	SAVE_MIN
+	;;
+	mov r14=cr.isr
+	ssm psr.ic | PSR_DEFAULT_BITS
+	;;
+	srlz.i					// guarantee that interruption collection is on
+	;;
+(p15)	ssm psr.i
+	adds r3=8,r2            // Base pointer for SAVE_REST
+	;;
+	SAVE_REST
+	;;
+	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
+
+	adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp	// 16 byte hole per SW conventions
+	adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp
+	;;
+	cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
+	ld8 r8=[r14]		// get r8
+	;;
+	st8 [r15]=r8		// save original 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=230		// number of entries in ia32 system call table
+	;;
+	cmp.ltu.unc p6,p7=r8,r15
+	ld4 out1=[r14],8	// r9 == ecx
+	;;
+	ld4 out2=[r14],8	// r10 == edx
+	;;
+	ld4 out0=[r14]		// r11 == ebx
+	adds r14=(IA64_PT_REGS_R13_OFFSET) + 16,sp
+	;;
+	ld4 out5=[r14],PT(R14)-PT(R13)	// r13 == ebp
+	;;
+	ld4 out3=[r14],PT(R15)-PT(R14)	// r14 == esi
+	adds r2=IA64_TASK_PTRACE_OFFSET,r13	// r2 = &current->ptrace
+	;;
+	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?
+	;;
+	mov b6=r16
+	movl r15=ia32_ret_from_syscall
+	;;
+	mov rp=r15
+(p8)	br.call.sptk.many b6=b6
+	br.cond.sptk ia32_trace_syscall
+
+non_ia32_syscall:
+	alloc r15=ar.pfs,0,0,2,0
+	mov out0=r14				// interrupt #
+	add out1=16,sp				// pointer to pt_regs
+	;;			// avoid WAW on CFM
+	br.call.sptk.many rp=ia32_bad_interrupt
+.ret1:	movl r15=ia64_leave_kernel
+	;;
+	mov rp=r15
+	br.ret.sptk.many rp
+END(dispatch_to_ia32_handler)
+
+#endif /* CONFIG_IA32_SUPPORT */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/mca.c linux-2.4.23-pre8/arch/ia64/kernel/mca.c
--- linux-2.4.22/arch/ia64/kernel/mca.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/mca.c	2003-10-22 22:48:54.000000000 +0000
@@ -59,13 +59,13 @@
 #include <asm/sal.h>
 #include <asm/mca.h>
 
-#include <asm/processor.h>
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
 
 #undef MCA_PRT_XTRA_DATA
 
-#define print_symbol(fmt, addr)	printk(fmt, "");
+#define print_symbol(fmt, addr)	printk(fmt, "(no symbol)");
+extern void show_stack(struct task_struct *);
 
 typedef struct ia64_fptr {
 	unsigned long fp;
@@ -99,6 +99,12 @@
 	.name =		"cmc_hndlr"
 };
 
+static struct irqaction cmcp_irqaction = {
+	.handler =	ia64_mca_cmc_int_caller,
+	.flags =	SA_INTERRUPT,
+	.name =		"cmc_poll"
+};
+
 static struct irqaction mca_rdzv_irqaction = {
 	.handler =	ia64_mca_rendez_int_handler,
 	.flags =	SA_INTERRUPT,
@@ -117,6 +123,12 @@
 	.name =		"cpe_hndlr"
 };
 
+static struct irqaction mca_cpep_irqaction = {
+	.handler =	ia64_mca_cpe_int_caller,
+	.flags =	SA_INTERRUPT,
+	.name =		"cpe_poll"
+};
+
 #define MAX_CPE_POLL_INTERVAL (15*60*HZ) /* 15 minutes */
 #define MIN_CPE_POLL_INTERVAL (2*60*HZ)  /* 2 minutes */
 #define CMC_POLL_INTERVAL     (1*60*HZ)  /* 1 minute */
@@ -125,11 +137,20 @@
 static struct timer_list cpe_poll_timer;
 static struct timer_list cmc_poll_timer;
 /*
+ * This variable tells whether we are currently in polling mode.
  * Start with this in the wrong state so we won't play w/ timers
  * before the system is ready.
  */
 static int cmc_polling_enabled = 1;
 
+/*
+ * Clearing this variable prevents CPE polling from getting activated
+ * in mca_late_init.  Use it if your system doesn't provide a CPEI,
+ * but encounters problems retrieving CPE logs.  This should only be
+ * necessary for debugging.
+ */
+static int cpe_poll_enabled = 1;
+
 extern void salinfo_log_wakeup(int);
 
 /*
@@ -179,6 +200,9 @@
 	IA64_MCA_DEBUG("ia64_mca_cpe_int_handler: received interrupt. CPU:%d vector = %#x\n",
 		       smp_processor_id(), cpe_irq);
 
+	/* SAL spec states this should run w/ interrupts enabled */
+	local_irq_enable();
+
 	/* Get the CMC error record and log it */
 	ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE, 0);
 }
@@ -322,7 +346,7 @@
 }
 
 void
-init_handler_platform (sal_log_processor_info_t *proc_ptr,
+init_handler_platform (pal_min_state_area_t *ms,
 		       struct pt_regs *pt, struct switch_stack *sw)
 {
 	struct unw_frame_info info;
@@ -337,12 +361,33 @@
 	 */
 	printk("Delaying for 5 seconds...\n");
 	udelay(5*1000000);
-	show_min_state(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area);
+	show_min_state(ms);
 
-	fetch_min_state(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area, pt, sw);
+	printk("Backtrace of current task (pid %d, %s)\n", current->pid, current->comm);
+	fetch_min_state(ms, pt, sw);
 	unw_init_from_interruption(&info, current, pt, sw);
 	ia64_do_show_stack(&info, NULL);
 
+#ifdef CONFIG_SMP
+	/* read_trylock() would be handy... */
+	if (!tasklist_lock.write_lock)
+		read_lock(&tasklist_lock);
+#endif
+	{
+		struct task_struct *t;
+		for_each_task(t) {
+			if (t == current)
+				continue;
+
+			printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
+			show_stack(t);
+		}
+	}
+#ifdef CONFIG_SMP
+	if (!tasklist_lock.write_lock)
+		read_unlock(&tasklist_lock);
+#endif
+
 	printk("\nINIT dump complete.  Please reboot now.\n");
 	while (1);			/* hang city if no debugger */
 }
@@ -653,17 +698,17 @@
 
 	IA64_MCA_DEBUG("ia64_mca_init: registered mca rendezvous spinloop and wakeup mech.\n");
 
-	ia64_mc_info.imi_mca_handler        = __pa(mca_hldlr_ptr->fp);
+	ia64_mc_info.imi_mca_handler        = ia64_tpa(mca_hldlr_ptr->fp);
 	/*
 	 * XXX - disable SAL checksum by setting size to 0; should be
-	 *	__pa(ia64_os_mca_dispatch_end) - __pa(ia64_os_mca_dispatch);
+	 *	ia64_tpa(ia64_os_mca_dispatch_end) - ia64_tpa(ia64_os_mca_dispatch);
 	 */
 	ia64_mc_info.imi_mca_handler_size	= 0;
 
 	/* Register the os mca handler with SAL */
 	if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_MCA,
 				       ia64_mc_info.imi_mca_handler,
-				       mca_hldlr_ptr->gp,
+				       ia64_tpa(mca_hldlr_ptr->gp),
 				       ia64_mc_info.imi_mca_handler_size,
 				       0, 0, 0)))
 	{
@@ -673,15 +718,15 @@
 	}
 
 	IA64_MCA_DEBUG("ia64_mca_init: registered os mca handler with SAL at 0x%lx, gp = 0x%lx\n",
-		       ia64_mc_info.imi_mca_handler, mca_hldlr_ptr->gp);
+		       ia64_mc_info.imi_mca_handler, ia64_tpa(mca_hldlr_ptr->gp));
 
 	/*
 	 * XXX - disable SAL checksum by setting size to 0, should be
 	 * IA64_INIT_HANDLER_SIZE
 	 */
-	ia64_mc_info.imi_monarch_init_handler		= __pa(mon_init_ptr->fp);
+	ia64_mc_info.imi_monarch_init_handler		= ia64_tpa(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		= ia64_tpa(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",
@@ -690,10 +735,10 @@
 	/* Register the os init handler with SAL */
 	if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_INIT,
 				       ia64_mc_info.imi_monarch_init_handler,
-				       __pa(ia64_get_gp()),
+				       ia64_tpa(ia64_get_gp()),
 				       ia64_mc_info.imi_monarch_init_handler_size,
 				       ia64_mc_info.imi_slave_init_handler,
-				       __pa(ia64_get_gp()),
+				       ia64_tpa(ia64_get_gp()),
 				       ia64_mc_info.imi_slave_init_handler_size)))
 	{
 		printk(KERN_ERR "ia64_mca_init: Failed to register m/s init handlers with SAL. "
@@ -704,10 +749,11 @@
 	IA64_MCA_DEBUG("ia64_mca_init: registered os init handler with SAL\n");
 
 	/*
-	 *  Configure the CMCI vector and handler. Interrupts for CMC are
+	 *  Configure the CMCI/P vector and handler. Interrupts for CMC are
 	 *  per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c).
 	 */
 	register_percpu_irq(IA64_CMC_VECTOR, &cmci_irqaction);
+	register_percpu_irq(IA64_CMCP_VECTOR, &cmcp_irqaction);
 	ia64_mca_cmc_vector_setup();       /* Setup vector on BSP & enable */
 
 	/* Setup the MCA rendezvous interrupt vector */
@@ -822,9 +868,12 @@
 	int cpu;
 
 	/* Clear the Rendez checkin flag for all cpus */
-	for(cpu = 0; cpu < smp_num_cpus; cpu++)
+	for(cpu = 0; cpu < NR_CPUS; cpu++) {
+		if (!cpu_online(cpu))
+			continue;
 		if (ia64_mc_info.imi_rendez_checkin[cpu] == IA64_MCA_RENDEZ_CHECKIN_DONE)
 			ia64_mca_wakeup(cpu);
+	}
 
 }
 
@@ -841,11 +890,11 @@
 void
 ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
 {
-	int flags;
+	unsigned long flags;
 	int cpu = smp_processor_id();
 
 	/* Mask all interrupts */
-	save_and_cli(flags);
+	local_irq_save(flags);
 
 	ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
 	/* Register with the SAL monarch that the slave has
@@ -860,7 +909,7 @@
 	ia64_mca_wakeup_ipi_wait();
 
 	/* Enable all interrupts */
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 
@@ -882,7 +931,6 @@
 void
 ia64_mca_wakeup_int_handler(int wakeup_irq, void *arg, struct pt_regs *ptregs)
 {
-
 }
 
 /*
@@ -987,6 +1035,9 @@
 	IA64_MCA_DEBUG("ia64_mca_cmc_int_handler: received interrupt vector = %#x on CPU %d\n",
 		       cmc_irq, smp_processor_id());
 
+	/* SAL spec states this should run w/ interrupts enabled */
+	local_irq_enable();
+
 	/* Get the CMC error record and log it */
 	ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC, 0);
 
@@ -994,7 +1045,7 @@
 	if (!cmc_polling_enabled) {
 		int i, count = 1; /* we know 1 happened now */
 		unsigned long now = jiffies;
-		
+
 		for (i = 0; i < CMC_HISTORY_LENGTH; i++) {
 			if (now - cmc_history[i] <= HZ)
 				count++;
@@ -1002,34 +1053,24 @@
 
 		IA64_MCA_DEBUG(KERN_INFO "CMC threshold %d/%d\n", count, CMC_HISTORY_LENGTH);
 		if (count >= CMC_HISTORY_LENGTH) {
-			/*
-			 * CMC threshold exceeded, clear the history
-			 * so we have a fresh start when we return
-			 */
-			for (index = 0 ; index < CMC_HISTORY_LENGTH; index++)
-				cmc_history[index] = 0;
-			index = 0;
 
-			/* Switch to polling mode */
 			cmc_polling_enabled = 1;
+			spin_unlock(&cmc_history_lock);
 
 			/*
-			 * Unlock & enable interrupts  before
-			 * smp_call_function or risk deadlock
+			 * We rely on the local_irq_enable() above so
+			 * that this can't deadlock.
 			 */
-			spin_unlock(&cmc_history_lock);
 			ia64_mca_cmc_vector_disable(NULL);
 
-			local_irq_enable();
-			smp_call_function(ia64_mca_cmc_vector_disable, NULL, 1, 1);
+			smp_call_function(ia64_mca_cmc_vector_disable, NULL, 1, 0);
 
 			/*
 			 * Corrected errors will still be corrected, but
 			 * make sure there's a log somewhere that indicates
 			 * something is generating more than we can handle.
 			 */
-			printk(KERN_WARNING "ia64_mca_cmc_int_handler: WARNING: Switching to polling CMC handler, error records may be lost\n");
-			
+			printk(KERN_WARNING "%s: WARNING: Switching to polling CMC handler, error records may be lost\n", __FUNCTION__);
 
 			mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
 
@@ -1082,16 +1123,62 @@
 /*
  *  ia64_mca_cmc_int_caller
  *
- * 	Call CMC interrupt handler, only purpose is to have a
- * 	smp_call_function callable entry.
+ * 	Triggered by sw interrupt from CMC polling routine.  Calls
+ * 	real interrupt handler and either triggers a sw interrupt
+ * 	on the next cpu or does cleanup at the end.
  *
- * Inputs   :	dummy(unused)
- * Outputs  :	None
- * */
-static void
-ia64_mca_cmc_int_caller(void *dummy)
+ * Inputs
+ *	interrupt number
+ *	client data arg ptr
+ *	saved registers ptr
+ * Outputs
+ *	None
+ */
+void
+ia64_mca_cmc_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs)
 {
-	ia64_mca_cmc_int_handler(0, NULL, NULL);
+	static int start_count = -1;
+	unsigned int cpuid;
+
+	cpuid = smp_processor_id();
+
+	/* If first cpu, update count */
+	if (start_count == -1)
+		start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CMC);
+
+	ia64_mca_cmc_int_handler(cpe_irq, arg, ptregs);
+
+	for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++);
+		
+	if (cpuid < NR_CPUS) {
+		platform_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
+	} else {
+		/* If no log recored, switch out of polling mode */
+		if (start_count == IA64_LOG_COUNT(SAL_INFO_TYPE_CMC)) {
+
+			printk(KERN_WARNING "%s: Returning to interrupt driven CMC handler\n", __FUNCTION__);
+
+			/*
+			 * The cmc interrupt handler enabled irqs, so
+			 * this can't deadlock.
+			 */
+			smp_call_function(ia64_mca_cmc_vector_enable, NULL, 1, 0);
+
+			/*
+			 * Turn off interrupts before re-enabling the
+			 * cmc vector locally.  Make sure we get out.
+			 */
+			local_irq_disable();
+			ia64_mca_cmc_vector_enable(NULL);
+			cmc_polling_enabled = 0;
+
+		} else {
+
+			mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
+		}
+
+		start_count = -1;
+	}
 }
 
 /*
@@ -1106,49 +1193,63 @@
 static void
 ia64_mca_cmc_poll (unsigned long dummy)
 {
-	int start_count;
-
-	start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CMC);
-
-	/* Call the interrupt handler */
-	smp_call_function(ia64_mca_cmc_int_caller, NULL, 1, 1);
-	local_irq_disable();
-	ia64_mca_cmc_int_caller(NULL);
-	local_irq_enable();
-
-	/*
-	 * If no log recored, switch out of polling mode.
-	 */
-	if (start_count == IA64_LOG_COUNT(SAL_INFO_TYPE_CMC)) {
-		printk(KERN_WARNING "ia64_mca_cmc_poll: Returning to interrupt driven CMC handler\n");
-		cmc_polling_enabled = 0;
-		smp_call_function(ia64_mca_cmc_vector_enable, NULL, 1, 1);
-		ia64_mca_cmc_vector_enable(NULL);
-	} else {
-		mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
-	}
+	/* Trigger a CMC interrupt cascade  */
+	platform_send_ipi(__ffs(cpu_online_map), IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
 }
 
 /*
  *  ia64_mca_cpe_int_caller
  *
- * 	Call CPE interrupt handler, only purpose is to have a
- * 	smp_call_function callable entry.
+ * 	Triggered by sw interrupt from CPE polling routine.  Calls
+ * 	real interrupt handler and either triggers a sw interrupt
+ * 	on the next cpu or does cleanup at the end.
  *
- * Inputs   :	dummy(unused)
- * Outputs  :	None
- * */
-static void
-ia64_mca_cpe_int_caller(void *dummy)
+ * Inputs
+ *	interrupt number
+ *	client data arg ptr
+ *	saved registers ptr
+ * Outputs
+ *	None
+ */
+void
+ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs)
 {
-	ia64_mca_cpe_int_handler(0, NULL, NULL);
+	static int start_count = -1;
+	static int poll_time = MAX_CPE_POLL_INTERVAL;
+	unsigned int cpuid;
+
+	cpuid = smp_processor_id();
+
+	/* If first cpu, update count */
+	if (start_count == -1)
+		start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CPE);
+
+	ia64_mca_cpe_int_handler(cpe_irq, arg, ptregs);
+
+	for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++);
+
+	if (cpuid < NR_CPUS) {
+		platform_send_ipi(cpuid, IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
+	} else {
+		/*
+		 * If a log was recorded, increase our polling frequency,
+		 * otherwise, backoff.
+		 */
+		if (start_count != IA64_LOG_COUNT(SAL_INFO_TYPE_CPE)) {
+			poll_time = max(MIN_CPE_POLL_INTERVAL, poll_time / 2);
+		} else {
+			poll_time = min(MAX_CPE_POLL_INTERVAL, poll_time * 2);
+		}
+		start_count = -1;
+		mod_timer(&cpe_poll_timer, jiffies + poll_time);
+	}
 }
 
 /*
  *  ia64_mca_cpe_poll
  *
- *	Poll for Corrected Platform Errors (CPEs), dynamically adjust
- *	polling interval based on occurance of an event.
+ *	Poll for Corrected Platform Errors (CPEs), trigger interrupt
+ *	on first cpu, from there it will trickle through all the cpus.
  *
  * Inputs   :   dummy(unused)
  * Outputs  :   None
@@ -1157,27 +1258,8 @@
 static void
 ia64_mca_cpe_poll (unsigned long dummy)
 {
-	int start_count;
-	static int poll_time = MAX_CPE_POLL_INTERVAL;
-
-	start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CPE);
-
-	/* Call the interrupt handler */
-	smp_call_function(ia64_mca_cpe_int_caller, NULL, 1, 1);
-	local_irq_disable();
-	ia64_mca_cpe_int_caller(NULL);
-	local_irq_enable();
-
-	/*
-	 * If a log was recorded, increase our polling frequency,
-	 * otherwise, backoff.
-	 */
-	if (start_count != IA64_LOG_COUNT(SAL_INFO_TYPE_CPE)) {
-		poll_time = max(MIN_CPE_POLL_INTERVAL, poll_time/2);
-	} else {
-		poll_time = min(MAX_CPE_POLL_INTERVAL, poll_time * 2);
-	}
-	mod_timer(&cpe_poll_timer, jiffies + poll_time);
+	/* Trigger a CPE interrupt cascade  */
+	platform_send_ipi(__ffs(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
 }
 
 /*
@@ -1203,8 +1285,10 @@
 	cpe_poll_timer.function = ia64_mca_cpe_poll;
 
 	/* If platform doesn't support CPEI, get the timer going. */
-	if (acpi_request_vector(ACPI_INTERRUPT_CPEI) < 0)
+	if (acpi_request_vector(ACPI_INTERRUPT_CPEI) < 0 && cpe_poll_enabled) {
+		register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
 		ia64_mca_cpe_poll(0UL);
+	}
 
 	return 0;
 }
@@ -1226,29 +1310,19 @@
 void
 ia64_init_handler (struct pt_regs *pt, struct switch_stack *sw)
 {
-	sal_log_processor_info_t *proc_ptr;
-	ia64_err_rec_t *plog_ptr;
+	pal_min_state_area_t *ms;
 
-	printk(KERN_INFO "Entered OS INIT handler\n");
-
-	/* Get the INIT processor log */
-	if (!ia64_log_get(SAL_INFO_TYPE_INIT, (prfunc_t)printk))
-		return;                 // no record retrieved
-
-#ifdef IA64_DUMP_ALL_PROC_INFO
-	ia64_log_print(SAL_INFO_TYPE_INIT, (prfunc_t)printk);
-#endif
+	printk(KERN_INFO "Entered OS INIT handler. PSP=%lx\n",
+		ia64_sal_to_os_handoff_state.proc_state_param);
 
 	/*
-	 * get pointer to min state save area
-	 *
+	 * Address of minstate area provided by PAL is physical,
+	 * uncacheable (bit 63 set). Convert to Linux virtual
+	 * address in region 6.
 	 */
-	plog_ptr=(ia64_err_rec_t *)IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_INIT);
-	proc_ptr = &plog_ptr->proc_err;
+	ms = (pal_min_state_area_t *)(ia64_sal_to_os_handoff_state.pal_min_state | (6ul<<61));
 
-	ia64_process_min_state_save(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area);
-
-	init_handler_platform(proc_ptr, pt, sw);	/* call platform specific routines */
+	init_handler_platform(ms, pt, sw);	/* call platform specific routines */
 }
 
 /*
@@ -1271,7 +1345,8 @@
 static void
 ia64_log_hexdump(unsigned char *p, unsigned long n_ch, prfunc_t prfunc)
 {
-	int i, j;
+	unsigned long i;
+	int j;
 
 	if (!p)
 		return;
@@ -1912,9 +1987,9 @@
 		ia64_log_prt_guid(&psei->guid, prfunc);
 	}
 	if (psei->valid.oem_data) {
-		platform_plat_specific_err_print((int)psei->header.len,
-				      (int)sizeof(sal_log_plat_specific_err_info_t) - 1,
-				      &(psei->oem_data[0]), prfunc);
+		platform_plat_specific_err_print((int) psei->header.len,
+				      (char *) psei->oem_data - (char *) psei,
+				      &psei->oem_data[0], prfunc);
 	}
 	prfunc("\n");
 }
@@ -2119,7 +2194,7 @@
 {
 	sal_log_section_hdr_t       *slsh;
 	int                         n_sects;
-	int                         ercd_pos;
+	u32                         ercd_pos;
 
 	if (!lh)
 		return;
@@ -2181,7 +2256,7 @@
 {
 	sal_log_section_hdr_t	*slsh;
 	int			n_sects;
-	int			ercd_pos;
+	u32			ercd_pos;
 	int			platform_err = 0;
 
 	if (!lh)
@@ -2319,3 +2394,12 @@
 	}
 	return platform_err;
 }
+
+static int __init
+ia64_mca_disable_cpe_polling(char *str)
+{
+	cpe_poll_enabled = 0;
+	return 1;
+}
+
+__setup("disable_cpe_poll", ia64_mca_disable_cpe_polling);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/mca_asm.S linux-2.4.23-pre8/arch/ia64/kernel/mca_asm.S
--- linux-2.4.22/arch/ia64/kernel/mca_asm.S	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/mca_asm.S	2003-10-22 22:48:24.000000000 +0000
@@ -57,7 +57,9 @@
 	st8	[_tmp]=r9,0x08;;			\
 	st8	[_tmp]=r10,0x08;;			\
 	st8	[_tmp]=r11,0x08;;			\
-	st8	[_tmp]=r12,0x08
+	st8	[_tmp]=r12,0x08;;			\
+	st8	[_tmp]=r17,0x08;;			\
+	st8	[_tmp]=r18,0x08
 
 /*
  * OS_MCA_TO_SAL_HANDOFF_STATE (SAL 3.0 spec)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/minstate.h linux-2.4.23-pre8/arch/ia64/kernel/minstate.h
--- linux-2.4.22/arch/ia64/kernel/minstate.h	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/minstate.h	2003-10-22 22:49:21.000000000 +0000
@@ -3,43 +3,25 @@
 #include "entry.h"
 
 /*
- * A couple of convenience macros that make writing and reading
- * SAVE_MIN and SAVE_REST easier.
- */
-#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
-#define rR1		r20
-
-/*
- * Here start the source dependent macros.
- */
-
-/*
- * For ivt.s we want to access the stack virtually so we dont have to disable translation
+ * For ivt.s we want to access the stack virtually so we don't have to disable translation
  * on interrupts.
+ *
+ *  On entry:
+ *	r1:	pointer to current task (ar.k6)
  */
 #define MINSTATE_START_SAVE_MIN_VIRT								\
 	dep r1=-1,r1,61,3;				/* r1 = current (virtual) */		\
 (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 RBS */		\
-(pUser)	mov rARRNAT=ar.rnat;									\
+(pUser)	addl r22=IA64_RBS_OFFSET,r1;			/* compute base of RBS */		\
+(pUser)	mov r24=ar.rnat;									\
 (pKern) mov r1=sp;					/* get sp  */				\
 	;;											\
 (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)	mov r23=ar.bspstore;				/* save ar.bspstore */			\
 	;;											\
 (pKern) addl r1=-IA64_PT_REGS_SIZE,r1;			/* if in kernel mode, use sp (r12) */	\
-(pUser)	mov ar.bspstore=rKRBS;				/* switch to kernel RBS */		\
+(pUser)	mov ar.bspstore=r22;				/* switch to kernel RBS */		\
 	;;											\
 (pUser)	mov r18=ar.bsp;										\
 (pUser)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
@@ -51,21 +33,21 @@
 
 /*
  * For mca_asm.S we want to access the stack physically since the state is saved before we
- * go virtual and dont want to destroy the iip or ipsr.
+ * go virtual and don't want to destroy the iip or ipsr.
  */
 #define MINSTATE_START_SAVE_MIN_PHYS								\
 (pKern) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE;				\
 (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 */	\
+(pUser)	addl r22=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
 	;;											\
-(pUser)	mov rARRNAT=ar.rnat;									\
+(pUser)	mov r24=ar.rnat;									\
 (pKern) dep r1=0,sp,61,3;				/* compute physical addr of sp	*/	\
 (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 */\
+(pUser)	mov r23=ar.bspstore;				/* save ar.bspstore */			\
+(pUser)	dep r22=-1,r22,61,3;				/* compute kernel virtual addr of RBS */\
 	;;											\
 (pKern) addl r1=-IA64_PT_REGS_SIZE,r1;		/* if in kernel mode, use sp (r12) */		\
-(pUser)	mov ar.bspstore=rKRBS;			/* switch to kernel RBS */			\
+(pUser)	mov ar.bspstore=r22;			/* switch to kernel RBS */			\
 	;;											\
 (pUser)	mov r18=ar.bsp;										\
 (pUser)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
@@ -96,143 +78,168 @@
  *
  * Upon exit, the state is as follows:
  *	psr.ic: off
- *	r2 = points to &pt_regs.r16
+ *	 r2 = points to &pt_regs.r16
+ *	 r8 = contents of ar.ccv
+ *	 r9 = contents of ar.csd
+ *	r10 = contents of ar.ssd
+ *	r11 = FPSR_DEFAULT
  *	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 p2, p3, and p15), b6, r3, r8, r9, r10, r11, r14, r15:
+ *	predicate registers (other than p2, p3, and p15), b6, r3, 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,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 rCRIIP=cr.iip;									  \
-	mov r1=IA64_KR(CURRENT);		/* r1 = current (physical) */			  \
-	COVER;											  \
-	;;											  \
-	invala;											  \
-	extr.u r16=rCRIPSR,32,2;		/* extract psr.cpl */				  \
-	;;											  \
-	cmp.eq pKern,pUser=r0,r16;		/* are we in kernel mode already? (psr.cpl==0) */ \
-	/* switch from user to kernel RBS: */							  \
-	;;											  \
-	SAVE_IFS;										  \
-	MINSTATE_START_SAVE_MIN									  \
-	;;											  \
-	mov r16=r1;					/* initialize first base pointer */	  \
-	adds r17=8,r1;					/* initialize second base pointer */	  \
-	;;											  \
-	st8 [r16]=rCRIPSR,16;	/* save cr.ipsr */						  \
-	st8 [r17]=rCRIIP,16;	/* save cr.iip */						  \
-(pKern)	mov r18=r0;		/* make sure r18 isn't NaT */					  \
-	;;											  \
-	st8 [r16]=rCRIFS,16;	/* save cr.ifs */						  \
-	st8 [r17]=rARUNAT,16;	/* save ar.unat */						  \
-(pUser)	sub r18=r18,rKRBS;	/* r18=RSE.ndirty*8 */						  \
-	;;											  \
-	st8 [r16]=rARPFS,16;	/* save ar.pfs */						  \
-	st8 [r17]=rARRSC,16;	/* save ar.rsc */						  \
-	tbit.nz p15,p0=rCRIPSR,IA64_PSR_I_BIT							  \
-	;;			/* 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 */				  \
-(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 */							  \
-	shl r18=r18,16;		/* compute ar.rsc to be used for "loadrs" */			  \
-	;;											  \
-	st8 [r16]=r18,16;	/* save ar.rsc value for "loadrs" */				  \
-	st8.spill [r17]=rR1,16;	/* save original r1 */						  \
-	;;											  \
-.mem.offset 0,0;	st8.spill [r16]=r2,16;							  \
-.mem.offset 8,0;	st8.spill [r17]=r3,16;							  \
-	adds r2=IA64_PT_REGS_R16_OFFSET,r1;							  \
-	;;											  \
-.mem.offset 0,0;		st8.spill [r16]=r12,16;						  \
-.mem.offset 8,0;		st8.spill [r17]=r13,16;						  \
-	cmp.eq pNonSys,pSys=r0,r0	/* initialize pSys=0, pNonSys=1 */			  \
-	;;											  \
-.mem.offset 0,0;		st8.spill [r16]=r14,16;						  \
-.mem.offset 8,0;		st8.spill [r17]=r15,16;						  \
-	dep r14=-1,r0,61,3;									  \
-	;;											  \
-.mem.offset 0,0;		st8.spill [r16]=r8,16;						  \
-.mem.offset 8,0;		st8.spill [r17]=r9,16;						  \
-	adds r12=-16,r1;	/* switch to kernel memory stack (with 16 bytes of scratch) */	  \
-	;;											  \
-.mem.offset 0,0;		st8.spill [r16]=r10,16;						  \
-.mem.offset 8,0;		st8.spill [r17]=r11,16;						  \
-	mov r13=IA64_KR(CURRENT);	/* establish `current' */				  \
-	;;											  \
-	EXTRA;											  \
-	movl r1=__gp;		/* establish kernel global pointer */				  \
-	;;											  \
+#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA)							\
+	mov r29=cr.ipsr;									\
+	mov r17=IA64_KR(CURRENT);		/* r1 = current (physical) */			\
+	mov r20=r1;										\
+	mov r27=ar.rsc;										\
+	mov r25=ar.unat;									\
+	mov r26=ar.pfs;										\
+	mov r21=ar.fpsr;									\
+	mov r28=cr.iip;										\
+	COVER;											\
+	;;											\
+	invala;											\
+	extr.u r16=r29,32,2;		/* extract psr.cpl */					\
+	;;											\
+	cmp.eq pKern,pUser=r0,r16;	/* are we in kernel mode already? (psr.cpl==0) */	\
+	mov r1=r17; 										\
+	/* switch from user to kernel RBS: */							\
+	;;											\
+	SAVE_IFS;										\
+	MINSTATE_START_SAVE_MIN									\
+	adds r17=2*L1_CACHE_BYTES,r1;		/* really: biggest cache-line size */		\
+	adds r16=PT(CR_IPSR),r1;								\
+	;;											\
+	lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES;						\
+	st8 [r16]=r29;		/* save cr.ipsr */						\
+	;;											\
+	lfetch.fault.excl.nt1 [r17];								\
+	;;											\
+	adds r16=PT(R8),r1;	/* initialize first base pointer */				\
+	adds r17=PT(R9),r1;	/* initialize second base pointer */				\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r8,16;								\
+.mem.offset 8,0; st8.spill [r17]=r9,16;								\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r10,24;							\
+.mem.offset 8,0; st8.spill [r17]=r11,32;							\
+	;;											\
+	st8 [r16]=r28,8;	/* save cr.iip */						\
+	mov r28=b0;          	/* rCRIIP=branch reg b0 */					\
+(pKern)	mov r18=r0;		/* make sure r18 isn't NaT */					\
+	mov r8=ar.ccv;                                                                          \
+	mov r9=ar.csd;                                                                          \
+	mov r10=ar.ssd;                                                                         \
+	movl r11=FPSR_DEFAULT;   /* L-unit */                                                   \
+	;;											\
+	st8 [r16]=r30,16;	/* save cr.ifs */						\
+	st8 [r17]=r25,16;	/* save ar.unat */						\
+(pUser)	sub r18=r18,r22;	/* r18=RSE.ndirty*8 */						\
+	;;											\
+	st8 [r16]=r26,16;	/* save ar.pfs */						\
+	st8 [r17]=r27,16;	/* save ar.rsc */						\
+	tbit.nz p15,p0=r29,IA64_PSR_I_BIT							\
+	;;			/* 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 */				\
+(pUser)	st8 [r16]=r24,16;	/* save ar.rnat */						\
+(pUser)	st8 [r17]=r23,16;	/* save ar.bspstore */					  	\
+	;;											\
+	st8 [r16]=r31,16;	/* save predicates */						\
+	st8 [r17]=r28,16;	/* save b0 */							\
+	shl r18=r18,16;		/* compute ar.rsc to be used for "loadrs" */			\
+	;;											\
+	st8 [r16]=r18,16;	/* save ar.rsc value for "loadrs" */				\
+	st8.spill [r17]=r20,16;	/* save original r1 */						\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r12,16;							\
+.mem.offset 8,0; st8.spill [r17]=r13,16;							\
+	cmp.eq pNonSys,pSys=r0,r0	/* initialize pSys=0, pNonSys=1 */			\
+	;;											\
+.mem.offset 0,0; st8 [r16]=r21,PT(R14)-PT(AR_FPSR); 	/* ar.fpsr */				\
+.mem.offset 8,0; st8.spill [r17]=r15,PT(R3)-PT(R15);						\
+	adds r12=-16,r1;	/* switch to kernel memory stack (with 16 bytes of scratch) */	\
+	;;											\
+	mov r13=IA64_KR(CURRENT);	/* establish `current' */				\
+.mem.offset 0,0; st8.spill [r16]=r14,8;								\
+	dep r14=-1,r0,61,3;									\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r2,16;								\
+.mem.offset 8,0; st8.spill [r17]=r3,16;								\
+	adds r2=IA64_PT_REGS_R16_OFFSET,r1;							\
+	;;											\
+	EXTRA;											\
+	movl r1=__gp;		/* establish kernel global pointer */				\
+	;;											\
 	MINSTATE_END_SAVE_MIN
 
 /*
- * SAVE_REST saves the remainder of pt_regs (with psr.ic on).  This
- * macro guarantees to preserve all predicate registers, r8, r9, r10,
- * r11, r14, and r15.
+ * SAVE_REST saves the remainder of pt_regs (with psr.ic on).
  *
  * Assumed state upon entry:
  *	psr.ic: on
  *	r2:	points to &pt_regs.r16
  *	r3:	points to &pt_regs.r17
+ *	r8:	contents of ar.ccv
+ *	r9:	contents of ar.csd
+ *	r10:	contents of ar.ssd
+ *	r11:	FPSR_DEFAULT
+ *
+ * Registers r14 and r15 are guaranteed not to be touched by SAVE_REST.
  */
 #define SAVE_REST				\
-.mem.offset 0,0;	st8.spill [r2]=r16,16;	\
-.mem.offset 8,0;	st8.spill [r3]=r17,16;	\
-	;;					\
-.mem.offset 0,0;	st8.spill [r2]=r18,16;	\
-.mem.offset 8,0;	st8.spill [r3]=r19,16;	\
+.mem.offset 0,0; st8.spill [r2]=r16,16;		\
+.mem.offset 8,0; st8.spill [r3]=r17,16;		\
 	;;					\
-	mov r16=ar.ccv;		/* M-unit */	\
-	movl r18=FPSR_DEFAULT	/* L-unit */	\
+.mem.offset 0,0; st8.spill [r2]=r18,16;		\
+.mem.offset 8,0; st8.spill [r3]=r19,16;		\
 	;;					\
-	mov r17=ar.fpsr;	/* M-unit */	\
-	mov ar.fpsr=r18;	/* M-unit */	\
+.mem.offset 0,0; st8.spill [r2]=r20,16;		\
+.mem.offset 8,0; st8.spill [r3]=r21,16;		\
+	mov r18=b6;				\
 	;;					\
-.mem.offset 0,0;	st8.spill [r2]=r20,16;	\
-.mem.offset 8,0;	st8.spill [r3]=r21,16;	\
-	mov r18=b0;				\
-	;;					\
-.mem.offset 0,0;	st8.spill [r2]=r22,16;	\
-.mem.offset 8,0;	st8.spill [r3]=r23,16;	\
+.mem.offset 0,0; st8.spill [r2]=r22,16;		\
+.mem.offset 8,0; st8.spill [r3]=r23,16;		\
 	mov r19=b7;				\
 	;;					\
-.mem.offset 0,0;	st8.spill [r2]=r24,16;	\
-.mem.offset 8,0;	st8.spill [r3]=r25,16;	\
-	;;					\
-.mem.offset 0,0;	st8.spill [r2]=r26,16;	\
-.mem.offset 8,0;	st8.spill [r3]=r27,16;	\
+.mem.offset 0,0; st8.spill [r2]=r24,16;		\
+.mem.offset 8,0; st8.spill [r3]=r25,16;		\
 	;;					\
-.mem.offset 0,0;	st8.spill [r2]=r28,16;	\
-.mem.offset 8,0;	st8.spill [r3]=r29,16;	\
+.mem.offset 0,0; st8.spill [r2]=r26,16;		\
+.mem.offset 8,0; st8.spill [r3]=r27,16;		\
 	;;					\
-.mem.offset 0,0;	st8.spill [r2]=r30,16;	\
-.mem.offset 8,0;	st8.spill [r3]=r31,16;	\
+.mem.offset 0,0; st8.spill [r2]=r28,16;		\
+.mem.offset 8,0; st8.spill [r3]=r29,16;		\
 	;;					\
-	st8 [r2]=r16,16;	/* ar.ccv */	\
-	st8 [r3]=r17,16;	/* ar.fpsr */	\
+.mem.offset 0,0; st8.spill [r2]=r30,16;		\
+.mem.offset 8,0; st8.spill [r3]=r31,32;		\
 	;;					\
-	st8 [r2]=r18,16;	/* b0 */	\
-	st8 [r3]=r19,16+8;	/* b7 */	\
+	mov ar.fpsr=r11;	/* M-unit */	\
+	st8 [r2]=r8,8;		/* ar.ccv */	\
+	adds r24=PT(B6)-PT(F7),r3;		\
 	;;					\
 	stf.spill [r2]=f6,32;			\
 	stf.spill [r3]=f7,32;			\
 	;;					\
 	stf.spill [r2]=f8,32;			\
-	stf.spill [r3]=f9,32
+	stf.spill [r3]=f9,32;			\
+	;;					\
+	stf.spill [r2]=f10;			\
+	stf.spill [r3]=f11;			\
+	adds r25=PT(B7)-PT(F11),r3;		\
+	;;					\
+	st8 [r24]=r18,16;	/* b6 */	\
+	st8 [r25]=r19,16;	/* b7 */	\
+	;;					\
+	st8 [r24]=r9;		/* ar.csd */	\
+	st8 [r25]=r10;		/* ar.ssd */	\
+	;;
 
-#define SAVE_MIN_WITH_COVER	DO_SAVE_MIN(cover, mov rCRIFS=cr.ifs,)
-#define SAVE_MIN_WITH_COVER_R19	DO_SAVE_MIN(cover, mov rCRIFS=cr.ifs, mov r15=r19)
-#define SAVE_MIN		DO_SAVE_MIN(     , mov rCRIFS=r0, )
+#define SAVE_MIN_WITH_COVER	DO_SAVE_MIN(cover, mov r30=cr.ifs,)
+#define SAVE_MIN_WITH_COVER_R19	DO_SAVE_MIN(cover, mov r30=cr.ifs, mov r15=r19)
+#define SAVE_MIN		DO_SAVE_MIN(     , mov r30=r0, )
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/pal.S linux-2.4.23-pre8/arch/ia64/kernel/pal.S
--- linux-2.4.22/arch/ia64/kernel/pal.S	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/pal.S	2003-10-22 22:49:48.000000000 +0000
@@ -164,7 +164,7 @@
 	;;
 	mov loc4=ar.rsc			// save RSE configuration
 	dep.z loc2=loc2,0,61		// convert pal entry point to physical
-	dep.z r8=r8,0,61		// convert rp to physical
+	tpa r8=r8			// convert rp to physical
 	;;
 	mov b7 = loc2			// install target to branch reg
 	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
@@ -174,13 +174,13 @@
 	or loc3=loc3,r17		// add in psr the bits to set
 	;;
 	andcm r16=loc3,r16		// removes bits to clear from psr
-	br.call.sptk.many rp=ia64_switch_mode
+	br.call.sptk.many rp=ia64_switch_mode_phys
 .ret1:	mov rp = r8			// install return address (physical)
 	br.cond.sptk.many b7
 1:
 	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	mov r16=loc3			// r16= original psr
-	br.call.sptk.many rp=ia64_switch_mode // return to virtual mode
+	br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
 .ret2:
 	mov psr.l = loc3		// restore init PSR
 
@@ -228,13 +228,13 @@
 	mov b7 = loc2			// install target to branch reg
 	;;
 	andcm r16=loc3,r16		// removes bits to clear from psr
-	br.call.sptk.many rp=ia64_switch_mode
+	br.call.sptk.many rp=ia64_switch_mode_phys
 .ret6:
 	br.call.sptk.many rp=b7		// now make the call
 .ret7:
 	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	mov r16=loc3			// r16= original psr
-	br.call.sptk.many rp=ia64_switch_mode	// return to virtual mode
+	br.call.sptk.many rp=ia64_switch_mode_virt	// return to virtual mode
 
 .ret8:	mov psr.l  = loc3		// restore init PSR
 	mov ar.pfs = loc1
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/palinfo.c linux-2.4.23-pre8/arch/ia64/kernel/palinfo.c
--- linux-2.4.22/arch/ia64/kernel/palinfo.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/palinfo.c	2003-10-22 22:47:30.000000000 +0000
@@ -91,7 +91,7 @@
 	"eager loads and stores"
 };
 
-#define RSE_HINTS_COUNT (sizeof(rse_hints)/sizeof(const char *))
+#define RSE_HINTS_COUNT ARRAY_SIZE(rse_hints)
 
 static const char *mem_attrib[]={
 	"WB",		/* 000 */
@@ -192,15 +192,15 @@
 
 	for (i=0; i < 8 ; i++ ) {
 		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" \
-					"\tpower consumption   : %d mW\n" \
-					"\tCache+TLB coherency : %s\n", i,
-				halt_info[i].pal_power_mgmt_info_s.entry_latency,
-				halt_info[i].pal_power_mgmt_info_s.exit_latency,
-				halt_info[i].pal_power_mgmt_info_s.power_consumption,
-				halt_info[i].pal_power_mgmt_info_s.co ? "Yes" : "No");
+			p += sprintf(p,	"Power level %d:\n"
+				     "\tentry_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,
+				     halt_info[i].pal_power_mgmt_info_s.exit_latency,
+				     halt_info[i].pal_power_mgmt_info_s.power_consumption,
+				     halt_info[i].pal_power_mgmt_info_s.co ? "Yes" : "No");
 		} else {
 			p += sprintf(p,"Power level %d: not implemented\n",i);
 		}
@@ -212,9 +212,9 @@
 cache_info(char *page)
 {
 	char *p = page;
-	u64 levels, unique_caches;
+	u64 i, levels, unique_caches;
 	pal_cache_config_info_t cci;
-	int i,j, k;
+	int j, k;
 	s64 status;
 
 	if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) {
@@ -232,48 +232,50 @@
 			if ((status=ia64_pal_cache_config_info(i,j, &cci)) != 0) {
 				continue;
 			}
-			p += sprintf(p, "%s Cache level %d:\n" \
-					"\tSize           : %ld bytes\n" \
-					"\tAttributes     : ",
-					cache_types[j+cci.pcci_unified], i+1,
-					cci.pcci_cache_size);
+			p += sprintf(p,
+				     "%s Cache level %lu:\n"
+				     "\tSize           : %lu bytes\n"
+				     "\tAttributes     : ",
+				     cache_types[j+cci.pcci_unified], i+1,
+				     cci.pcci_cache_size);
 
 			if (cci.pcci_unified) p += sprintf(p, "Unified ");
 
 			p += sprintf(p, "%s\n", cache_mattrib[cci.pcci_cache_attr]);
 
-			p += sprintf(p, "\tAssociativity  : %d\n" \
-					"\tLine size      : %d bytes\n" \
-					"\tStride         : %d bytes\n",
-					cci.pcci_assoc,
-					1<<cci.pcci_line_size,
-					1<<cci.pcci_stride);
+			p += sprintf(p,
+				     "\tAssociativity  : %d\n"
+				     "\tLine size      : %d bytes\n"
+				     "\tStride         : %d bytes\n",
+				     cci.pcci_assoc, 1<<cci.pcci_line_size, 1<<cci.pcci_stride);
 			if (j == 1)
 				p += sprintf(p, "\tStore latency  : N/A\n");
 			else
 				p += sprintf(p, "\tStore latency  : %d cycle(s)\n",
 						cci.pcci_st_latency);
 
-			p += sprintf(p, "\tLoad latency   : %d cycle(s)\n" \
-					"\tStore hints    : ",
-					cci.pcci_ld_latency);
+			p += sprintf(p,
+				     "\tLoad latency   : %d cycle(s)\n"
+				     "\tStore hints    : ", cci.pcci_ld_latency);
 
 			for(k=0; k < 8; k++ ) {
-				if ( cci.pcci_st_hints & 0x1) p += sprintf(p, "[%s]", cache_st_hints[k]);
+				if ( cci.pcci_st_hints & 0x1)
+					p += sprintf(p, "[%s]", cache_st_hints[k]);
 				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]);
+				if (cci.pcci_ld_hints & 0x1)
+					p += sprintf(p, "[%s]", cache_ld_hints[k]);
 				cci.pcci_ld_hints >>=1;
 			}
-			p += sprintf(p, "\n\tAlias boundary : %d byte(s)\n" \
-					"\tTag LSB        : %d\n" \
-					"\tTag MSB        : %d\n",
-					1<<cci.pcci_alias_boundary,
-					cci.pcci_tag_lsb,
-					cci.pcci_tag_msb);
+			p += sprintf(p,
+				     "\n\tAlias boundary : %d byte(s)\n"
+				     "\tTag LSB        : %d\n"
+				     "\tTag MSB        : %d\n",
+				     1<<cci.pcci_alias_boundary, cci.pcci_tag_lsb,
+				     cci.pcci_tag_msb);
 
 			/* when unified, data(j=2) is enough */
 			if (cci.pcci_unified) break;
@@ -303,20 +305,20 @@
 	}
 
 
-	p += sprintf(p, "Physical Address Space         : %d bits\n" \
-			"Virtual Address Space          : %d bits\n" \
-			"Protection Key Registers(PKR)  : %d\n" \
-			"Implemented bits in PKR.key    : %d\n" \
-			"Hash Tag ID                    : 0x%x\n" \
-			"Size of RR.rid                 : %d\n",
-			vm_info_1.pal_vm_info_1_s.phys_add_size,
-			vm_info_2.pal_vm_info_2_s.impl_va_msb+1,
-			vm_info_1.pal_vm_info_1_s.max_pkr+1,
-			vm_info_1.pal_vm_info_1_s.key_size,
-			vm_info_1.pal_vm_info_1_s.hash_tag_id,
-			vm_info_2.pal_vm_info_2_s.rid_size);
+	p += sprintf(p,
+		     "Physical Address Space         : %d bits\n"
+		     "Virtual Address Space          : %d bits\n"
+		     "Protection Key Registers(PKR)  : %d\n"
+		     "Implemented bits in PKR.key    : %d\n"
+		     "Hash Tag ID                    : 0x%x\n"
+		     "Size of RR.rid                 : %d\n",
+		     vm_info_1.pal_vm_info_1_s.phys_add_size,
+		     vm_info_2.pal_vm_info_2_s.impl_va_msb+1, vm_info_1.pal_vm_info_1_s.max_pkr+1,
+		     vm_info_1.pal_vm_info_1_s.key_size, vm_info_1.pal_vm_info_1_s.hash_tag_id,
+		     vm_info_2.pal_vm_info_2_s.rid_size);
 
-	if (ia64_pal_mem_attrib(&attrib) != 0) return 0;
+	if (ia64_pal_mem_attrib(&attrib) != 0)
+		return 0;
 
 	p += sprintf(p, "Supported memory attributes    : ");
 	sep = "";
@@ -333,13 +335,14 @@
 		return 0;
 	}
 
-	p += sprintf(p, "\nTLB walker                     : %simplemented\n" \
-			"Number of DTR                  : %d\n" \
-			"Number of ITR                  : %d\n" \
-			"TLB insertable page sizes      : ",
-			vm_info_1.pal_vm_info_1_s.vw ? "" : "not ",
-			vm_info_1.pal_vm_info_1_s.max_dtr_entry+1,
-			vm_info_1.pal_vm_info_1_s.max_itr_entry+1);
+	p += sprintf(p,
+		     "\nTLB walker                     : %simplemented\n"
+		     "Number of DTR                  : %d\n"
+		     "Number of ITR                  : %d\n"
+		     "TLB insertable page sizes      : ",
+		     vm_info_1.pal_vm_info_1_s.vw ? "" : "not ",
+		     vm_info_1.pal_vm_info_1_s.max_dtr_entry+1,
+		     vm_info_1.pal_vm_info_1_s.max_itr_entry+1);
 
 
 	p = bitvector_process(p, tr_pages);
@@ -353,21 +356,19 @@
 		return 0;
 	}
 
-	p += sprintf(p, "\nPurge base address             : 0x%016lx\n" \
-			"Purge outer loop count         : %d\n" \
-			"Purge inner loop count         : %d\n" \
-			"Purge outer loop stride        : %d\n" \
-			"Purge inner loop stride        : %d\n",
-			ptce.base,
-			ptce.count[0],
-			ptce.count[1],
-			ptce.stride[0],
-			ptce.stride[1]);
-
-	p += sprintf(p, "TC Levels                      : %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);
+	p += sprintf(p,
+		     "\nPurge base address             : 0x%016lx\n"
+		     "Purge outer loop count         : %d\n"
+		     "Purge inner loop count         : %d\n"
+		     "Purge outer loop stride        : %d\n"
+		     "Purge inner loop stride        : %d\n",
+		     ptce.base, ptce.count[0], ptce.count[1], ptce.stride[0], ptce.stride[1]);
+
+	p += sprintf(p,
+		     "TC Levels                      : %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);
 
 	for(i=0; i < vm_info_1.pal_vm_info_1_s.num_tc_levels; i++) {
 		for (j=2; j>0 ; j--) {
@@ -379,15 +380,14 @@
 				continue;
 			}
 
-			p += sprintf(p, "\n%s Translation Cache Level %d:\n" \
-					"\tHash sets           : %d\n" \
-					"\tAssociativity       : %d\n" \
-					"\tNumber of entries   : %d\n" \
-					"\tFlags               : ",
-					cache_types[j+tc_info.tc_unified], i+1,
-					tc_info.tc_num_sets,
-					tc_info.tc_associativity,
-					tc_info.tc_num_entries);
+			p += sprintf(p,
+				     "\n%s Translation Cache Level %d:\n"
+				     "\tHash sets           : %d\n"
+				     "\tAssociativity       : %d\n"
+				     "\tNumber of entries   : %d\n"
+				     "\tFlags               : ",
+				     cache_types[j+tc_info.tc_unified], i+1, tc_info.tc_num_sets,
+				     tc_info.tc_associativity, tc_info.tc_num_entries);
 
 			if (tc_info.tc_pf) p += sprintf(p, "PreferredPageSizeOptimized ");
 			if (tc_info.tc_unified) p += sprintf(p, "Unified ");
@@ -436,17 +436,18 @@
 
 	if (ia64_pal_rse_info(&phys_stacked, &hints) != 0) return 0;
 
-	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]: "(\?\?)");
-
-	if (ia64_pal_debug_info(&iregs, &dregs)) return 0;
-
-	p += sprintf(p, "Instruction debug register pairs : %ld\n" \
-			"Data debug register pairs        : %ld\n",
-			iregs, dregs);
+	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]: "(\?\?)");
+
+	if (ia64_pal_debug_info(&iregs, &dregs))
+		return 0;
+
+	p += sprintf(p,
+		     "Instruction debug register pairs : %ld\n"
+		     "Data debug register pairs        : %ld\n", iregs, dregs);
 
 	return p - page;
 }
@@ -563,26 +564,21 @@
 	 */
 	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_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);
-
+	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_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;
 }
 
@@ -595,26 +591,20 @@
 
 	if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0) return 0;
 
-	p += sprintf(p, "PMC/PMD pairs                 : %d\n" \
-			"Counter width                 : %d bits\n" \
-			"Cycle event number            : %d\n" \
-			"Retired event number          : %d\n" \
-			"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,
-			pm_info.pal_perf_mon_info_s.retired);
+	p += sprintf(p,
+		     "PMC/PMD pairs                 : %d\n"
+		     "Counter width                 : %d bits\n"
+		     "Cycle event number            : %d\n"
+		     "Retired event number          : %d\n"
+		     "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, pm_info.pal_perf_mon_info_s.retired);
 
 	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 : ");
 
 #ifdef CONFIG_ITANIUM
@@ -646,12 +636,11 @@
 
 	if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0;
 
-	p += sprintf(p, "Processor/Clock ratio   : %ld/%ld\n" \
-			"Bus/Clock ratio         : %ld/%ld\n" \
-			"ITC/Clock ratio         : %ld/%ld\n",
-			proc.num, proc.den,
-			bus.num, bus.den,
-			itc.num, itc.den);
+	p += sprintf(p,
+		     "Processor/Clock ratio   : %ld/%ld\n"
+		     "Bus/Clock ratio         : %ld/%ld\n"
+		     "ITC/Clock ratio         : %ld/%ld\n",
+		     proc.num, proc.den, bus.num, bus.den, itc.num, itc.den);
 
 	return p - page;
 }
@@ -665,7 +654,7 @@
 	u64 tr_buffer[4];
 	pal_vm_info_1_u_t vm_info_1;
 	pal_vm_info_2_u_t vm_info_2;
-	int i, j;
+	u64 i, j;
 	u64 max[3], pgm;
 	struct ifa_reg {
 		u64 valid:1;
@@ -711,7 +700,7 @@
 
 		status = ia64_pal_tr_read(j, i, tr_buffer, &tr_valid);
 		if (status != 0) {
-			printk(KERN_ERR "palinfo: pal call failed on tr[%d:%d]=%ld\n",
+			printk(KERN_ERR "palinfo: pal call failed on tr[%lu:%lu]=%ld\n",
 			       i, j, status);
 			continue;
 		}
@@ -725,34 +714,29 @@
 		rid_reg  = (struct rid_reg *)&tr_buffer[3];
 
 		pgm	 = -1 << (itir_reg->ps - 12);
-		p += sprintf(p, "%cTR%d: av=%d pv=%d dv=%d mv=%d\n" \
-				"\tppn  : 0x%lx\n" \
-				"\tvpn  : 0x%lx\n" \
-				"\tps   : ",
-
-				"ID"[i],
-				j,
-				tr_valid.pal_tr_valid_s.access_rights_valid,
-				tr_valid.pal_tr_valid_s.priv_level_valid,
-				tr_valid.pal_tr_valid_s.dirty_bit_valid,
-				tr_valid.pal_tr_valid_s.mem_attr_valid,
-				(gr_reg->ppn & pgm)<< 12,
-				(ifa_reg->vpn & pgm)<< 12);
+		p += sprintf(p,
+			     "%cTR%lu: av=%d pv=%d dv=%d mv=%d\n"
+			     "\tppn  : 0x%lx\n"
+			     "\tvpn  : 0x%lx\n"
+			     "\tps   : ",
+			     "ID"[i], j,
+			     tr_valid.pal_tr_valid_s.access_rights_valid,
+			     tr_valid.pal_tr_valid_s.priv_level_valid,
+			     tr_valid.pal_tr_valid_s.dirty_bit_valid,
+			     tr_valid.pal_tr_valid_s.mem_attr_valid,
+			     (gr_reg->ppn & pgm)<< 12, (ifa_reg->vpn & pgm)<< 12);
 
 		p = bitvector_process(p, 1<< itir_reg->ps);
 
-		p += sprintf(p, "\n\tpl   : %d\n" \
-				"\tar   : %d\n" \
-				"\trid  : %x\n" \
-				"\tp    : %d\n" \
-				"\tma   : %d\n" \
-				"\td    : %d\n",
-				gr_reg->pl,
-				gr_reg->ar,
-				rid_reg->rid,
-				gr_reg->p,
-				gr_reg->ma,
-				gr_reg->d);
+		p += sprintf(p,
+			     "\n\tpl   : %d\n"
+			     "\tar   : %d\n"
+			     "\trid  : %x\n"
+			     "\tp    : %d\n"
+			     "\tma   : %d\n"
+			     "\td    : %d\n",
+			     gr_reg->pl, gr_reg->ar, rid_reg->rid, gr_reg->p, gr_reg->ma,
+			     gr_reg->d);
 		}
 	}
 	return p - page;
@@ -776,7 +760,7 @@
 	{ "tr_info",		tr_info, }
 };
 
-#define NR_PALINFO_ENTRIES	(sizeof(palinfo_entries)/sizeof(palinfo_entry_t))
+#define NR_PALINFO_ENTRIES	(int) ARRAY_SIZE(palinfo_entries)
 
 /*
  * this array is used to keep track of the proc entries we create. This is
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/pci.c linux-2.4.23-pre8/arch/ia64/kernel/pci.c
--- linux-2.4.22/arch/ia64/kernel/pci.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/pci.c	2003-10-22 22:48:42.000000000 +0000
@@ -235,7 +235,7 @@
 }
 
 static u64
-add_io_space (acpi_resource_address64 *addr)
+add_io_space (struct acpi_resource_address64 *addr)
 {
 	u64 offset;
 	int sparse = 0;
@@ -266,10 +266,10 @@
 }
 
 static acpi_status
-count_window (acpi_resource *resource, void *data)
+count_window (struct acpi_resource *resource, void *data)
 {
 	unsigned int *windows = (unsigned int *) data;
-	acpi_resource_address64 addr;
+	struct acpi_resource_address64 addr;
 	acpi_status status;
 
 	status = acpi_resource_to_address64(resource, &addr);
@@ -287,11 +287,11 @@
 };
 
 static acpi_status
-add_window (acpi_resource *res, void *data)
+add_window (struct acpi_resource *res, void *data)
 {
 	struct pci_root_info *info = (struct pci_root_info *) data;
 	struct pci_window *window;
-	acpi_resource_address64 addr;
+	struct acpi_resource_address64 addr;
 	acpi_status status;
 	unsigned long flags, offset = 0;
 	struct resource *root;
@@ -390,9 +390,6 @@
 void __init
 pcibios_init (void)
 {
-	int i = 0;
-	struct pci_controller *controller;
-
 #ifdef CONFIG_IA64_MCA
 	ia64_mca_check_errors();    /* For post-failure MCA error logging */
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/perfmon.c linux-2.4.23-pre8/arch/ia64/kernel/perfmon.c
--- linux-2.4.22/arch/ia64/kernel/perfmon.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/perfmon.c	2003-10-22 22:49:39.000000000 +0000
@@ -447,7 +447,9 @@
  * forward declarations
  */
 static void pfm_reset_pmu(struct task_struct *);
+#ifndef CONFIG_SMP
 static unsigned long pfm_lazy_save_regs (struct task_struct *ta);
+#endif
 
 #if   defined(CONFIG_ITANIUM)
 #include "perfmon_itanium.h"
@@ -472,13 +474,13 @@
 static inline void
 pfm_clear_psr_up(void)
 {
-	__asm__ __volatile__ ("rum psr.up;; srlz.i;;"::: "memory");
+	__asm__ __volatile__ ("rsm psr.up;; srlz.i;;"::: "memory");
 }
 
 static inline void
 pfm_set_psr_up(void)
 {
-	__asm__ __volatile__ ("sum psr.up;; srlz.i;;"::: "memory");
+	__asm__ __volatile__ ("ssm psr.up;; srlz.i;;"::: "memory");
 }
 
 static inline unsigned long
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/process.c linux-2.4.23-pre8/arch/ia64/kernel/process.c
--- linux-2.4.22/arch/ia64/kernel/process.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/process.c	2003-10-22 22:48:54.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Architecture-specific setup.
  *
- * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #define __KERNEL_SYSCALLS__	/* see <asm/unistd.h> */
@@ -33,15 +33,15 @@
 #include <asm/sn/idle.h>
 #endif
 
-#define print_symbol(fmt, addr)	printk(fmt, "");
+#define print_symbol(fmt, addr)	printk(fmt, "(no symbol)");
 
 void
 ia64_do_show_stack (struct unw_frame_info *info, void *arg)
 {
 	unsigned long ip, sp, bsp;
-	char buf[80];			/* don't make it so big that it overflows the stack! */
+	char buf[128];			/* don't make it so big that it overflows the stack! */
 
-	printk("\nCall Trace: ");
+	printk("\nCall Trace:\n");
 	do {
 		unw_get_ip(info, &ip);
 		if (ip == 0)
@@ -49,19 +49,15 @@
 
 		unw_get_sp(info, &sp);
 		unw_get_bsp(info, &bsp);
-		snprintf(buf, sizeof(buf), " [<%016lx>] %%s\n\t\t\t\tsp=%016lx bsp=%016lx\n",
+		snprintf(buf, sizeof(buf),
+			 " [<%016lx>] %%s\n"
+			 "                                sp=%016lx bsp=%016lx\n",
 			 ip, sp, bsp);
 		print_symbol(buf, ip);
 	} while (unw_unwind(info) >= 0);
 }
 
 void
-show_trace_task (struct task_struct *task)
-{
-	show_stack(task);
-}
-
-void
 show_stack (struct task_struct *task)
 {
 	if (!task)
@@ -75,19 +71,27 @@
 }
 
 void
+show_trace_task (struct task_struct *task)
+{
+	show_stack(task);
+}
+
+void
 show_regs (struct pt_regs *regs)
 {
 	unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
 
-	printk("\nPid: %d, comm: %20s\n", current->pid, current->comm);
+	printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm);
 	printk("psr : %016lx ifs : %016lx ip  : [<%016lx>]    %s\n",
 	       regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
+	print_symbol("ip is at %s\n", ip);
 	printk("unat: %016lx pfs : %016lx rsc : %016lx\n",
 	       regs->ar_unat, regs->ar_pfs, regs->ar_rsc);
 	printk("rnat: %016lx bsps: %016lx pr  : %016lx\n",
 	       regs->ar_rnat, regs->ar_bspstore, regs->pr);
 	printk("ldrs: %016lx ccv : %016lx fpsr: %016lx\n",
 	       regs->loadrs, regs->ar_ccv, regs->ar_fpsr);
+	printk("csd : %016lx ssd : %016lx\n", regs->ar_csd, regs->ar_ssd);
 	printk("b0  : %016lx b6  : %016lx b7  : %016lx\n", regs->b0, regs->b6, regs->b7);
 	printk("f6  : %05lx%016lx f7  : %05lx%016lx\n",
 	       regs->f6.u.bits[1], regs->f6.u.bits[0],
@@ -95,6 +99,9 @@
 	printk("f8  : %05lx%016lx f9  : %05lx%016lx\n",
 	       regs->f8.u.bits[1], regs->f8.u.bits[0],
 	       regs->f9.u.bits[1], regs->f9.u.bits[0]);
+	printk("f10 : %05lx%016lx f11 : %05lx%016lx\n",
+	       regs->f10.u.bits[1], regs->f10.u.bits[0],
+	       regs->f11.u.bits[1], regs->f11.u.bits[0]);
 
 	printk("r1  : %016lx r2  : %016lx r3  : %016lx\n", regs->r1, regs->r2, regs->r3);
 	printk("r8  : %016lx r9  : %016lx r10 : %016lx\n", regs->r8, regs->r9, regs->r10);
@@ -124,16 +131,32 @@
 		show_stack(NULL);
 }
 
+/*
+ * We use this if we don't have any better idle routine..
+ */
+void
+default_idle (void)
+{
+#ifdef CONFIG_IA64_PAL_IDLE
+	if (!current->need_resched)
+		safe_halt();
+#endif
+}
+
 void __attribute__((noreturn))
 cpu_idle (void *unused)
 {
-	/* endless idle loop with no priority at all */
 	init_idle();
 	current->nice = 20;
 	current->counter = -100;
 
 
+	/* endless idle loop with no priority at all */
 	while (1) {
+		void (*idle)(void) = pm_idle;
+		if (!idle)
+			idle = default_idle;
+
 #ifdef CONFIG_SMP
 		if (!current->need_resched)
 			min_xtp();
@@ -143,7 +166,7 @@
 #ifdef CONFIG_IA64_SGI_SN
 			snidle();
 #endif
-			continue;
+			(*idle)();
 		}
 
 #ifdef CONFIG_IA64_SGI_SN
@@ -155,8 +178,6 @@
 #endif
 		schedule();
 		check_pgt_cache();
-		if (pm_idle)
-			(*pm_idle)();
 	}
 }
 
@@ -426,6 +447,8 @@
 	dst[52] = pt->ar_pfs;	/* UNW_AR_PFS is == to pt->cr_ifs for interrupt frames */
 	unw_get_ar(info, UNW_AR_LC, &dst[53]);
 	unw_get_ar(info, UNW_AR_EC, &dst[54]);
+	unw_get_ar(info, UNW_AR_CSD, &dst[55]);
+	unw_get_ar(info, UNW_AR_SSD, &dst[56]);
 }
 
 void
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/ptrace.c linux-2.4.23-pre8/arch/ia64/kernel/ptrace.c
--- linux-2.4.22/arch/ia64/kernel/ptrace.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/ptrace.c	2003-10-22 22:49:48.000000000 +0000
@@ -28,6 +28,8 @@
 #include <asm/perfmon.h>
 #endif
 
+#define offsetof(type,field)    ((unsigned long) &((type *) 0)->field)
+
 /*
  * Bits in the PSR that we allow ptrace() to change:
  *	be, up, ac, mfl, mfh (the user mask; five bits total)
@@ -690,9 +692,12 @@
 		else
 			ia64_flush_fph(child);
 		ptr = (unsigned long *) ((unsigned long) &child->thread.fph + addr);
-	} else if (addr >= PT_F10 && addr < PT_F15 + 16) {
+	} else if ((addr >= PT_F10) && (addr < PT_F11 + 16)) {
+		/* scratch registers untouched by kernel (saved in pt_regs) */
+		ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, f10) + addr - PT_F10);
+	} else if (addr >= PT_F12 && addr < PT_F15 + 16) {
 		/* scratch registers untouched by kernel (saved in switch_stack) */
-		ptr = (unsigned long *) ((long) sw + addr - PT_NAT_BITS);
+		ptr = (unsigned long *) ((long) sw + (addr - PT_NAT_BITS - 32));
 	} else if (addr < PT_AR_LC + 8) {
 		/* preserved state: */
 		unsigned long nat_bits, scratch_unat, dummy = 0;
@@ -828,22 +833,69 @@
 			else
 				return ia64_peek(child, sw, urbs_end, rnat_addr, data);
 
-				   case PT_R1:  case PT_R2:  case PT_R3:
+		      case PT_R1:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r1));
+			break;
+		       
+		       case PT_R2:  case PT_R3:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r2) + addr - PT_R2);
+			break;
 		      case PT_R8:  case PT_R9:  case PT_R10: case PT_R11:
-		      case PT_R12: case PT_R13: case PT_R14: case PT_R15:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r8)+  addr - PT_R8);
+			break;
+		      case PT_R12: case PT_R13: 
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r12)+  addr - PT_R12);
+			break;
+		      case PT_R14: 
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r14));
+			break;
+		      case PT_R15:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r15));
+			break;
 		      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_B6:  case PT_B7:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r16) + addr - PT_R16);
+			break;
+		      case PT_B0:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, b0));
+			break;
+		      case PT_B6:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, b6));
+			break;
+		      case PT_B7:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, b7));
+			break;
 		      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:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, f6) + addr - PT_F6);
+			break;
 		      case PT_AR_BSPSTORE:
-		      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);
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_bspstore));
+			break;
+		      case PT_AR_RSC: 
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_rsc));
+			break;
+		      case PT_AR_UNAT: 
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_unat));
+			break;
+		      case PT_AR_PFS:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_pfs));
 			break;
+		      case PT_AR_CCV: 
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_ccv));
+			break;
+		      case PT_AR_FPSR: 
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_fpsr));
+			break;
+		      case PT_CR_IIP: 
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, cr_iip));
+			break;
+		      case PT_PR:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, pr));
+			break;
+			/* scratch register */
 
 		      default:
 			/* disallow accessing anything else... */
@@ -851,6 +903,8 @@
 				addr);
 			return -1;
 		}
+	} else if (addr <= PT_AR_SSD) {
+		ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_csd) + addr - PT_AR_CSD);
 	} else {
 		/* access debug registers */
 
@@ -957,7 +1011,8 @@
 
 	/* gr1-gr3 */
 
-	retval |= __copy_to_user(&ppr->gr[1], &pt->r1, sizeof(long) * 3);
+	retval |= __copy_to_user(&ppr->gr[1], &pt->r1, sizeof(long));
+	retval |= __copy_to_user(&ppr->gr[2], &pt->r2, sizeof(long) *2);
 
 	/* gr4-gr7 */
 
@@ -971,7 +1026,9 @@
 
 	/* gr12-gr15 */
 
-	retval |= __copy_to_user(&ppr->gr[12], &pt->r12, sizeof(long) * 4);
+	retval |= __copy_to_user(&ppr->gr[12], &pt->r12, sizeof(long) * 2);
+	retval |= __copy_to_user(&ppr->gr[14], &pt->r14, sizeof(long));
+	retval |= __copy_to_user(&ppr->gr[15], &pt->r15, sizeof(long));
 
 	/* gr16-gr31 */
 
@@ -999,13 +1056,13 @@
 		retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 0);
 	}
 
-	/* fr6-fr9 */
+	/* fr6-fr11 */
 
-	retval |= __copy_to_user(&ppr->fr[6], &pt->f6, sizeof(struct ia64_fpreg) * 4);
+	retval |= __copy_to_user(&ppr->fr[6], &pt->f6, sizeof(struct ia64_fpreg) * 6);
 
-	/* fp scratch regs(10-15) */
+	/* fp scratch regs(12-15) */
 
-	retval |= __copy_to_user(&ppr->fr[10], &sw->f10, sizeof(struct ia64_fpreg) * 6);
+	retval |= __copy_to_user(&ppr->fr[12], &sw->f12, sizeof(struct ia64_fpreg) * 4);
 
 	/* fr16-fr31 */
 
@@ -1082,7 +1139,8 @@
 
 	/* gr1-gr3 */
 
-	retval |= __copy_from_user(&pt->r1, &ppr->gr[1], sizeof(long) * 3);
+	retval |= __copy_from_user(&pt->r1, &ppr->gr[1], sizeof(long));
+	retval |= __copy_from_user(&pt->r2, &ppr->gr[2], sizeof(long) * 2);
 
 	/* gr4-gr7 */
 
@@ -1100,7 +1158,9 @@
 
 	/* gr12-gr15 */
 
-	retval |= __copy_from_user(&pt->r12, &ppr->gr[12], sizeof(long) * 4);
+	retval |= __copy_from_user(&pt->r12, &ppr->gr[12], sizeof(long) * 2);
+	retval |= __copy_from_user(&pt->r14, &ppr->gr[14], sizeof(long));
+	retval |= __copy_from_user(&pt->r15, &ppr->gr[15], sizeof(long));
 
 	/* gr16-gr31 */
 
@@ -1128,13 +1188,13 @@
 		retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 1);
 	}
 
-	/* fr6-fr9 */
+	/* fr6-fr11 */
 
-	retval |= __copy_from_user(&pt->f6, &ppr->fr[6], sizeof(ppr->fr[6]) * 4);
+	retval |= __copy_from_user(&pt->f6, &ppr->fr[6], sizeof(ppr->fr[6]) * 6);
 
-	/* fp scratch regs(10-15) */
+	/* fp scratch regs(12-15) */
 
-	retval |= __copy_from_user(&sw->f10, &ppr->fr[10], sizeof(ppr->fr[10]) * 6);
+	retval |= __copy_from_user(&sw->f12, &ppr->fr[12], sizeof(ppr->fr[12]) * 4);
 
 	/* fr16-fr31 */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/salinfo.c linux-2.4.23-pre8/arch/ia64/kernel/salinfo.c
--- linux-2.4.22/arch/ia64/kernel/salinfo.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/salinfo.c	2003-10-22 22:48:42.000000000 +0000
@@ -42,7 +42,7 @@
 	{ "itc_drift",		IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT, },
 };
 
-#define NR_SALINFO_ENTRIES (sizeof(salinfo_entries)/sizeof(salinfo_entry_t))
+#define NR_SALINFO_ENTRIES ARRAY_SIZE(salinfo_entries)
 
 static char *salinfo_log_name[] = {
 	"mca",
@@ -98,9 +98,6 @@
 static int
 salinfo_event_open(struct inode *inode, struct file *file)
 {
-	struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
-	struct salinfo_event *event = entry->data;
-
 	if (!suser())
 		return -EPERM;
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/setup.c linux-2.4.23-pre8/arch/ia64/kernel/setup.c
--- linux-2.4.22/arch/ia64/kernel/setup.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/setup.c	2003-10-22 22:47:49.000000000 +0000
@@ -32,6 +32,10 @@
 #include <linux/ioport.h>
 #include <linux/efi.h>
 
+#ifdef CONFIG_BLK_DEV_RAM
+# include <linux/blk.h>
+#endif
+
 #include <asm/ia32.h>
 #include <asm/page.h>
 #include <asm/machvec.h>
@@ -39,6 +43,8 @@
 #include <asm/sal.h>
 #include <asm/system.h>
 #include <asm/mca.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/smp.h>
 
 #ifdef CONFIG_BLK_DEV_RAM
@@ -55,7 +61,7 @@
 extern char _end;
 
 #ifdef CONFIG_NUMA
- struct cpuinfo_ia64 *boot_cpu_data;
+ struct cpuinfo_ia64 *_cpu_data[NR_CPUS];
 #else
  struct cpuinfo_ia64 _cpu_data[NR_CPUS] __attribute__ ((section ("__special_page_section")));
 #endif
@@ -97,6 +103,7 @@
 static struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1];
 static int num_rsvd_regions;
 
+#ifndef CONFIG_DISCONTIGMEM
 static unsigned long bootmap_start; /* physical address where the bootmem map is located */
 
 static int
@@ -109,18 +116,74 @@
 		*max_pfn = pfn;
 	return 0;
 }
+#endif /* !CONFIG_DISCONTIGMEM */
 
 #define IGNORE_PFN0	1	/* XXX fix me: ignore pfn 0 until TLB miss handler is updated... */
 
+#ifdef CONFIG_DISCONTIGMEM
 /*
- * Free available memory based on the primitive map created from
- * the boot parameters. This routine does not assume the incoming
- * segments are sorted.
+ * efi_memmap_walk() knows nothing about layout of memory across nodes. Find
+ * out to which node a block of memory belongs.  Ignore memory that we cannot
+ * identify, and split blocks that run across multiple nodes.
+ *
+ * Take this opportunity to round the start address up and the end address
+ * down to page boundaries.
  */
+void
+call_pernode_memory (unsigned long start, unsigned long end, void *arg)
+{
+	unsigned long rs, re;
+	void (*func)(unsigned long, unsigned long, int);
+	int i;
+
+	start = PAGE_ALIGN(start);
+	end &= PAGE_MASK;
+	if (start >= end)
+		return;
+
+	func = arg;
+
+	if (!num_memblks) {
+		/* this machine doesn't have SRAT, */
+		/* so call func with nid=0, bank=0 */
+		if (start < end)
+			(*func)(start, end, 0);
+		return;
+	}
+
+	for (i = 0; i < num_memblks; i++) {
+		rs = MAX(__pa(start), node_memblk[i].start_paddr);
+		re = MIN(__pa(end), node_memblk[i].start_paddr+node_memblk[i].size);
+
+		if (rs < re)
+			(*func)((unsigned long)__va(rs), (unsigned long)__va(re), node_memblk[i].nid);
+		if ((unsigned long)__va(re) == end)
+			break;
+	}
+}
+
+#else /* CONFIG_DISCONTIGMEM */
+
 static int
 free_available_memory (unsigned long start, unsigned long end, void *arg)
 {
+	free_bootmem(__pa(start), end - start);
+	return 0;
+}
+#endif /* CONFIG_DISCONTIGMEM */
+
+/*
+ * Filter incoming memory segments based on the primitive map created from
+ * the boot parameters. Segments contained in the map are removed from the
+ * memory ranges. A caller-specified function is called with the memory
+ * ranges that remain after filtering.
+ * This routine does not assume the incoming segments are sorted.
+ */
+int
+filter_rsvd_memory (unsigned long start, unsigned long end, void *arg)
+{
 	unsigned long range_start, range_end, prev_start;
+	void (*func)(unsigned long, unsigned long, int);
 	int i;
 
 #if IGNORE_PFN0
@@ -134,13 +197,18 @@
 	 * lowest possible address(walker uses virtual)
 	 */
 	prev_start = PAGE_OFFSET;
+	func = arg;
 
 	for (i = 0; i < num_rsvd_regions; ++i) {
 		range_start = MAX(start, prev_start);
 		range_end   = MIN(end, rsvd_region[i].start);
 
 		if (range_start < range_end)
-			free_bootmem(__pa(range_start), range_end - range_start);
+#ifdef CONFIG_DISCONTIGMEM
+			call_pernode_memory(range_start, range_end, func);
+#else
+			(*func)(range_start, range_end, 0);
+#endif
 
 		/* nothing more available in this segment */
 		if (range_end == end) return 0;
@@ -152,6 +220,7 @@
 }
 
 
+#ifndef CONFIG_DISCONTIGMEM
 /*
  * Find a place to put the bootmap and return its starting address in bootmap_start.
  * This address must be page-aligned.
@@ -190,6 +259,7 @@
 	}
 	return 0;
 }
+#endif /* CONFIG_DISCONTIGMEM */
 
 static void
 sort_regions (struct rsvd_region *rsvd_region, int max)
@@ -233,8 +303,8 @@
 				+ strlen(__va(ia64_boot_param->command_line)) + 1);
 	n++;
 
-	rsvd_region[n].start = KERNEL_START;
-	rsvd_region[n].end   = KERNEL_END;
+	rsvd_region[n].start = ia64_imva(KERNEL_START);
+	rsvd_region[n].end   = ia64_imva(KERNEL_END);
 	n++;
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -254,6 +324,14 @@
 
 	sort_regions(rsvd_region, num_rsvd_regions);
 
+#ifdef CONFIG_DISCONTIGMEM
+	{
+		extern void discontig_mem_init(void);
+		bootmap_size = max_pfn = 0;     /* stop gcc warnings */
+		discontig_mem_init();
+	}
+#else /* !CONFIG_DISCONTIGMEM */
+
 	/* first find highest page frame number */
 	max_pfn = 0;
 	efi_memmap_walk(find_max_pfn, &max_pfn);
@@ -270,8 +348,9 @@
 	bootmap_size = init_bootmem(bootmap_start >> PAGE_SHIFT, max_pfn);
 
 	/* Free all available memory, then mark bootmem-map as being in use.  */
-	efi_memmap_walk(free_available_memory, 0);
+	efi_memmap_walk(filter_rsvd_memory, free_available_memory);
 	reserve_bootmem(bootmap_start, bootmap_size);
+#endif /* !CONFIG_DISCONTIGMEM */
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (ia64_boot_param->initrd_start) {
@@ -297,9 +376,22 @@
 	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';		/* for safety */
 
 	efi_init();
+	find_memory();
+
+#ifdef CONFIG_ACPI_BOOT
+	/* Initialize the ACPI boot-time table parser */
+	acpi_table_init();
+
+# ifdef CONFIG_ACPI_NUMA
+	acpi_numa_init();
+# endif
+#else
+# ifdef CONFIG_SMP
+	smp_build_cpu_map();	/* happens, e.g., with the Ski simulator */
+# endif
+#endif /* CONFIG_APCI_BOOT */
 
 	iomem_resource.end = ~0UL;	/* FIXME probably belongs elsewhere */
-	find_memory();
 
 #if 0
 	/* XXX fix me */
@@ -353,7 +445,7 @@
 	cpu_init();	/* initialize the bootstrap CPU */
 
 #ifdef CONFIG_ACPI_BOOT
-	acpi_boot_init(*cmdline_p);
+	acpi_boot_init();
 #endif
 #ifdef CONFIG_SERIAL_HCDP
 	if (efi.hcdp) {
@@ -446,6 +538,8 @@
 		   c->itc_freq / 1000000, c->itc_freq % 1000000,
 		   lpj*HZ/500000, (lpj*HZ/5000) % 100);
 	return 0;
+#undef lpj
+#undef cpu
 }
 
 static void *
@@ -546,7 +640,7 @@
 	unsigned int max_ctx;
 	struct cpuinfo_ia64 *my_cpu_data;
 #ifdef CONFIG_NUMA
-	int cpu, order;
+	int cpu;
 
 	/*
 	 * If NUMA is configured, the cpu_data array is not preallocated. The boot cpu
@@ -555,28 +649,14 @@
 	 * is required because some boot code references all cpu_data structures
 	 * before the cpus are actually started.
 	 */
-	if (!boot_cpu_data) {
-		my_cpu_data = alloc_bootmem_pages_node(NODE_DATA(numa_node_id()),
-						       sizeof(struct cpuinfo_ia64));
-		boot_cpu_data = my_cpu_data;
-		my_cpu_data->cpu_data[0] = my_cpu_data;
-		for (cpu = 1; cpu < NR_CPUS; ++cpu)
-			my_cpu_data->cpu_data[cpu]
-				= alloc_bootmem_pages_node(NODE_DATA(numa_node_id()),
-							   sizeof(struct cpuinfo_ia64));
-		for (cpu = 1; cpu < NR_CPUS; ++cpu)
-			memcpy(my_cpu_data->cpu_data[cpu]->cpu_data,
-			       my_cpu_data->cpu_data, sizeof(my_cpu_data->cpu_data));
-	} else {
-		order = get_order(sizeof(struct cpuinfo_ia64));
-		my_cpu_data = page_address(alloc_pages_node(numa_node_id(), GFP_KERNEL, order));
-		memcpy(my_cpu_data, boot_cpu_data->cpu_data[smp_processor_id()],
-		       sizeof(struct cpuinfo_ia64));
-		__free_pages(virt_to_page(boot_cpu_data->cpu_data[smp_processor_id()]),
-			     order);
-		for (cpu = 0; cpu < NR_CPUS; ++cpu)
-			boot_cpu_data->cpu_data[cpu]->cpu_data[smp_processor_id()] = my_cpu_data;
-	}
+	for (cpu=0; cpu < NR_CPUS; cpu++)
+		if (node_cpuid[cpu].phys_id == hard_smp_processor_id())
+			break;
+	my_cpu_data = _cpu_data[cpu];
+	my_cpu_data->node_data->active_cpu_count++;
+
+	for (cpu=0; cpu<NR_CPUS; cpu++)
+		_cpu_data[cpu]->cpu_data[smp_processor_id()] = my_cpu_data;
 #else
 	my_cpu_data = cpu_data(smp_processor_id());
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/signal.c linux-2.4.23-pre8/arch/ia64/kernel/signal.c
--- linux-2.4.22/arch/ia64/kernel/signal.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/signal.c	2003-10-22 22:49:03.000000000 +0000
@@ -115,18 +115,28 @@
 	err |= __get_user(cfm, &sc->sc_cfm);
 	err |= __get_user(um, &sc->sc_um);			/* user mask */
 	err |= __get_user(scr->pt.ar_rsc, &sc->sc_ar_rsc);
-	err |= __get_user(scr->pt.ar_ccv, &sc->sc_ar_ccv);
 	err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat);
 	err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr);
 	err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs);
 	err |= __get_user(scr->pt.pr, &sc->sc_pr);		/* predicates */
 	err |= __get_user(scr->pt.b0, &sc->sc_br[0]);		/* b0 (rp) */
-	err |= __get_user(scr->pt.b6, &sc->sc_br[6]);		/* b6 */
-	err |= __get_user(scr->pt.b7, &sc->sc_br[7]);		/* b7 */
-	err |= __copy_from_user(&scr->pt.r1, &sc->sc_gr[1], 3*8);	/* r1-r3 */
+	err |= __copy_from_user(&scr->pt.r1, &sc->sc_gr[1], 8);	/* r1 */
 	err |= __copy_from_user(&scr->pt.r8, &sc->sc_gr[8], 4*8);	/* r8-r11 */
-	err |= __copy_from_user(&scr->pt.r12, &sc->sc_gr[12], 4*8);	/* r12-r15 */
-	err |= __copy_from_user(&scr->pt.r16, &sc->sc_gr[16], 16*8);	/* r16-r31 */
+	err |= __copy_from_user(&scr->pt.r12, &sc->sc_gr[12], 2*8);	/* r12-r13 */
+	err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8);	/* r15 */
+	
+	if ((flags & IA64_SC_FLAG_IN_SYSCALL)==0)
+	{
+		// Only get user sig context when not in syscall. 
+		err |= __get_user(scr->pt.ar_ccv, &sc->sc_ar_ccv);
+		err |= __get_user(scr->pt.ar_csd, &sc->sc_ar25);	/* ar.csd */
+		err |= __get_user(scr->pt.ar_ssd, &sc->sc_ar26);	/* ar.ssd */
+		err |= __get_user(scr->pt.b6, &sc->sc_br[6]);		/* b6 */
+		err |= __get_user(scr->pt.b7, &sc->sc_br[7]);		/* b7 */
+		err |= __copy_from_user(&scr->pt.r2, &sc->sc_gr[2], 2*8);	/* r2-r3 */
+		err |= __copy_from_user(&scr->pt.r14, &sc->sc_gr[14], 8);	/* r14 */
+		err |= __copy_from_user(&scr->pt.r16, &sc->sc_gr[16], 16*8);	/* r16-r31 */
+	}
 
 	scr->pt.cr_ifs = cfm | (1UL << 63);
 
@@ -354,21 +364,42 @@
 	err |= __put_user(cfm, &sc->sc_cfm);
 	err |= __put_user(scr->pt.cr_ipsr & IA64_PSR_UM, &sc->sc_um);
 	err |= __put_user(scr->pt.ar_rsc, &sc->sc_ar_rsc);
-	err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv);
 	err |= __put_user(scr->pt.ar_unat, &sc->sc_ar_unat);		/* ar.unat */
 	err |= __put_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr);		/* ar.fpsr */
 	err |= __put_user(scr->pt.ar_pfs, &sc->sc_ar_pfs);
 	err |= __put_user(scr->pt.pr, &sc->sc_pr);			/* predicates */
 	err |= __put_user(scr->pt.b0, &sc->sc_br[0]);			/* b0 (rp) */
-	err |= __put_user(scr->pt.b6, &sc->sc_br[6]);			/* b6 */
-	err |= __put_user(scr->pt.b7, &sc->sc_br[7]);			/* b7 */
-
-	err |= __copy_to_user(&sc->sc_gr[1], &scr->pt.r1, 3*8);		/* r1-r3 */
+	err |= __copy_to_user(&sc->sc_gr[1], &scr->pt.r1, 8);		/* r1 */
 	err |= __copy_to_user(&sc->sc_gr[8], &scr->pt.r8, 4*8);		/* r8-r11 */
-	err |= __copy_to_user(&sc->sc_gr[12], &scr->pt.r12, 4*8);	/* r12-r15 */
-	err |= __copy_to_user(&sc->sc_gr[16], &scr->pt.r16, 16*8);	/* r16-r31 */
-
+	err |= __copy_to_user(&sc->sc_gr[12], &scr->pt.r12, 2*8);	/* r12-r13 */
+	err |= __copy_to_user(&sc->sc_gr[15], &scr->pt.r15, 8);		/* r15 */
 	err |= __put_user(scr->pt.cr_iip + ia64_psr(&scr->pt)->ri, &sc->sc_ip);
+
+	if (flags & IA64_SC_FLAG_IN_SYSCALL)
+	{
+		// Clear scratch registers in sig context for asynchronized signal.
+		err |= __clear_user(&sc->sc_ar_ccv, 8);
+		err |= __clear_user(&sc->sc_ar25,8);				/* ar.csd */
+		err |= __clear_user(&sc->sc_ar26,8);				/* ar.ssd */
+		err |= __clear_user(&sc->sc_br[6],8);				/* b6 */
+		err |= __clear_user(&sc->sc_br[7],8);				/* b7 */
+
+		err |= __clear_user(&sc->sc_gr[2], 2*8);			/* r2-r3 */
+		err |= __clear_user(&sc->sc_gr[14],8);				/* r14 */
+		err |= __clear_user(&sc->sc_gr[16],16*8);			/* r16-r31 */
+	} else
+	{
+		// Copy scratch registers in sig context from pt_regs for synchronized signal.
+		err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv);
+		err |= __put_user(scr->pt.ar_csd, &sc->sc_ar25);		/* ar.csd */
+		err |= __put_user(scr->pt.ar_ssd, &sc->sc_ar26);		/* ar.ssd */
+		err |= __put_user(scr->pt.b6, &sc->sc_br[6]);			/* b6 */
+		err |= __put_user(scr->pt.b7, &sc->sc_br[7]);			/* b7 */
+
+		err |= __copy_to_user(&sc->sc_gr[2], &scr->pt.r2, 2*8);		/* r2-r3 */
+		err |= __copy_to_user(&sc->sc_gr[14], &scr->pt.r14, 8);		/* r14 */
+		err |= __copy_to_user(&sc->sc_gr[16], &scr->pt.r16, 16*8);	/* r16-r31 */
+	}
 	return err;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/smpboot.c linux-2.4.23-pre8/arch/ia64/kernel/smpboot.c
--- linux-2.4.22/arch/ia64/kernel/smpboot.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/smpboot.c	2003-10-22 22:48:13.000000000 +0000
@@ -320,6 +320,7 @@
 {
 	int cpuid, phys_id;
 	extern void ia64_init_itm(void);
+	extern void ia64_cpu_local_tick(void);
 
 #ifdef CONFIG_PERFMON
 	extern void pfm_init_percpu(void);
@@ -576,7 +577,7 @@
 	/* 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);
+				      ia64_tpa(ap_startup->fp), ia64_tpa(ap_startup->gp), 0, 0, 0, 0);
 	if (sal_ret < 0) {
 		printk(KERN_ERR "SMP: Can't set SAL AP Boot Rendezvous: %s\n     Forcing UP mode\n",
 		       ia64_sal_strerror(sal_ret));
@@ -584,3 +585,27 @@
 		smp_num_cpus = 1;
 	}
 }
+
+/*
+ * Initialize the logical CPU number to SAPICID mapping
+ */
+void __init
+smp_build_cpu_map (void)
+{
+	int sapicid, cpu, i;
+	int boot_cpu_id = hard_smp_processor_id();
+
+	for (cpu = 0; cpu < NR_CPUS; cpu++)
+		ia64_cpu_to_sapicid[cpu] = -1;
+
+	ia64_cpu_to_sapicid[0] = boot_cpu_id;
+
+	for (cpu = 1, i = 0; i < smp_boot_data.cpu_count; i++) {
+		sapicid = smp_boot_data.cpu_phys_id[i];
+		if (sapicid == boot_cpu_id)
+			continue;
+		ia64_cpu_to_sapicid[cpu] = sapicid;
+		cpu++;
+	}
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/traps.c linux-2.4.23-pre8/arch/ia64/kernel/traps.c
--- linux-2.4.22/arch/ia64/kernel/traps.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/traps.c	2003-10-22 22:49:45.000000000 +0000
@@ -273,7 +273,6 @@
 fp_emulate (int fp_fault, void *bundle, long *ipsr, long *fpsr, long *isr, long *pr, long *ifs,
 	    struct pt_regs *regs)
 {
-	struct ia64_fpreg f6_11[6];
 	fp_state_t fp_state;
 	fpswa_ret_t ret;
 
@@ -288,11 +287,8 @@
 	 * pointer to point to these registers.
 	 */
 	fp_state.bitmask_low64 = 0xfc0;  /* bit6..bit11 */
-	f6_11[0] = regs->f6; f6_11[1] = regs->f7;
-	f6_11[2] = regs->f8; f6_11[3] = regs->f9;
-	__asm__ ("stf.spill %0=f10%P0" : "=m"(f6_11[4]));
-	__asm__ ("stf.spill %0=f11%P0" : "=m"(f6_11[5]));
-	fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) f6_11;
+
+	fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) &regs->f6;
 	/*
 	 * unsigned long (*EFI_FPSWA) (
 	 *      unsigned long    trap_type,
@@ -308,10 +304,7 @@
 					(unsigned long *) ipsr, (unsigned long *) fpsr,
 					(unsigned long *) isr, (unsigned long *) pr,
 					(unsigned long *) ifs, &fp_state);
-	regs->f6 = f6_11[0]; regs->f7 = f6_11[1];
-	regs->f8 = f6_11[2]; regs->f9 = f6_11[3];
-	__asm__ ("ldf.fill f10=%0%P0" :: "m"(f6_11[4]));
-	__asm__ ("ldf.fill f11=%0%P0" :: "m"(f6_11[5]));
+
 	return ret.status;
 }
 
@@ -335,8 +328,9 @@
 
 	if (jiffies - last_time > 5*HZ)
 		fpu_swa_count = 0;
-	if ((++fpu_swa_count < 5) && !(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) {
+	if ((fpu_swa_count < 4) && !(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) {
 		last_time = jiffies;
+		++fpu_swa_count;
 		printk(KERN_WARNING "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
 		       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
 	}
@@ -361,6 +355,10 @@
 			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
 			if (isr & 0x11) {
 				siginfo.si_code = FPE_FLTINV;
+			} else if (isr & 0x22) {
+				/* denormal operand gets the same si_code as underflow 
+				* see arch/i386/kernel/traps.c:math_error()  */
+				siginfo.si_code = FPE_FLTUND;
 			} else if (isr & 0x44) {
 				siginfo.si_code = FPE_FLTDIV;
 			}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/unaligned.c linux-2.4.23-pre8/arch/ia64/kernel/unaligned.c
--- linux-2.4.22/arch/ia64/kernel/unaligned.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/unaligned.c	2003-10-22 22:49:35.000000000 +0000
@@ -217,8 +217,9 @@
 	RSW(f2), RSW(f3), RSW(f4), RSW(f5),
 
 	RPT(f6), RPT(f7), RPT(f8), RPT(f9),
+	RPT(f10), RPT(f11),
 
-	RSW(f10), RSW(f11), RSW(f12), RSW(f13), RSW(f14),
+	RSW(f12), RSW(f13), RSW(f14),
 	RSW(f15), RSW(f16), RSW(f17), RSW(f18), RSW(f19),
 	RSW(f20), RSW(f21), RSW(f22), RSW(f23), RSW(f24),
 	RSW(f25), RSW(f26), RSW(f27), RSW(f28), RSW(f29),
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/kernel/unwind.c linux-2.4.23-pre8/arch/ia64/kernel/unwind.c
--- linux-2.4.22/arch/ia64/kernel/unwind.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/kernel/unwind.c	2003-10-22 22:48:57.000000000 +0000
@@ -1,4 +1,7 @@
 /*
+ * Copyright (C) 2003 Fenghua Yu <fenghua.yu@intel.com>
+ * 	- Change pt_regs_off() to make it less dependant on pt_regs structure.
+ *
  * Copyright (C) 1999-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
@@ -209,7 +212,11 @@
 #endif
 };
 
-
+#define OFF_CASE(reg, reg_num) 					\
+	case reg:						\
+		off=struct_offset(struct pt_regs, reg_num);	\
+		break;
+
 /* Unwind accessors.  */
 
 /*
@@ -220,16 +227,40 @@
 {
 	unsigned long off =0;
 
-	if (reg >= 1 && reg <= 3)
-		off = struct_offset(struct pt_regs, r1) + 8*(reg - 1);
-	else if (reg <= 11)
-		off = struct_offset(struct pt_regs, r8) + 8*(reg - 8);
-	else if (reg <= 15)
-		off = struct_offset(struct pt_regs, r12) + 8*(reg - 12);
-	else if (reg <= 31)
-		off = struct_offset(struct pt_regs, r16) + 8*(reg - 16);
-	else
-		UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __FUNCTION__, reg);
+	switch (reg)
+	{
+		OFF_CASE(1,r1)
+		OFF_CASE(2,r2)
+		OFF_CASE(3,r3)
+		OFF_CASE(8,r8)
+		OFF_CASE(9,r9)
+		OFF_CASE(10,r10)
+		OFF_CASE(11,r11)
+		OFF_CASE(12,r12)
+		OFF_CASE(13,r13)
+		OFF_CASE(14,r14)
+		OFF_CASE(15,r15)
+		OFF_CASE(16,r16)
+		OFF_CASE(17,r17)
+		OFF_CASE(18,r18)
+		OFF_CASE(19,r19)
+		OFF_CASE(20,r20)
+		OFF_CASE(21,r21)
+		OFF_CASE(22,r22)
+		OFF_CASE(23,r23)
+		OFF_CASE(24,r24)
+		OFF_CASE(25,r25)
+		OFF_CASE(26,r26)
+		OFF_CASE(27,r27)
+		OFF_CASE(28,r28)
+		OFF_CASE(29,r29)
+		OFF_CASE(30,r30)
+		OFF_CASE(31,r31)
+		default:
+			UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __FUNCTION__, reg);
+			break;
+	}
+
 	return off;
 }
 
@@ -416,12 +447,12 @@
 		if (!addr)
 			addr = &info->sw->f2 + (regnum - 2);
 	} else if (regnum <= 15) {
-		if (regnum <= 9) {
+		if (regnum <= 11) {
 			pt = get_scratch_regs(info);
 			addr = &pt->f6  + (regnum - 6);
 		}
 		else
-			addr = &info->sw->f10 + (regnum - 10);
+			addr = &info->sw->f12 + (regnum - 12);
 	} else if (regnum <= 31) {
 		addr = info->fr_loc[regnum - 16];
 		if (!addr)
@@ -512,6 +543,16 @@
 		addr = &pt->ar_ccv;
 		break;
 
+	      case UNW_AR_CSD:
+		pt = get_scratch_regs(info);
+		addr = &pt->ar_csd;
+		break;
+
+	      case UNW_AR_SSD:
+		pt = get_scratch_regs(info);
+		addr = &pt->ar_ssd;
+		break;
+
 	      default:
 		UNW_DPRINT(0, "unwind.%s: trying to access non-existent ar%u\n",
 			   __FUNCTION__, regnum);
@@ -685,7 +726,7 @@
 	 * First, resolve implicit register save locations (see Section "11.4.2.3 Rules
 	 * for Using Unwind Descriptors", rule 3):
 	 */
-	for (i = 0; i < (int) sizeof(unw.save_order)/sizeof(unw.save_order[0]); ++i) {
+	for (i = 0; i < (int) ARRAY_SIZE(unw.save_order); ++i) {
 		reg = sr->curr.reg + unw.save_order[i];
 		if (reg->where == UNW_WHERE_GR_SAVE) {
 			reg->where = UNW_WHERE_GR;
@@ -701,7 +742,7 @@
 	 */
 	if (sr->imask) {
 		unsigned char kind, mask = 0, *cp = sr->imask;
-		unsigned long t;
+		int t;
 		static const unsigned char limit[3] = {
 			UNW_REG_F31, UNW_REG_R7, UNW_REG_B5
 		};
@@ -1379,7 +1420,7 @@
 			val = unw.preg_index[UNW_REG_F16 + (rval - 16)];
 		else {
 			opc = UNW_INSN_MOVE_SCRATCH;
-			if (rval <= 9)
+			if (rval <= 11)
 				val = struct_offset(struct pt_regs, f6) + 16*(rval - 6);
 			else
 				UNW_DPRINT(0, "unwind.%s: kernel may not touch f%lu\n",
@@ -1731,8 +1772,7 @@
   lazy_init:
 	off = unw.sw_off[val];
 	s[val] = (unsigned long) state->sw + off;
-	if (off >= struct_offset(struct switch_stack, r4)
-	    && off <= struct_offset(struct switch_stack, r7))
+	if (off >= struct_offset(struct switch_stack, r4) && off <= struct_offset(struct switch_stack, r7))
 		/*
 		 * We're initializing a general register: init NaT info, too.  Note that
 		 * the offset is a multiple of 8 which gives us the 3 bits needed for
@@ -1934,7 +1974,7 @@
 		   "  pr     0x%lx\n"
 		   "  sw     0x%lx\n"
 		   "  sp     0x%lx\n",
-		   __FUNCTION__, (unsigned long) task, rbslimit, rbstop, stktop, stklimit,
+		   __FUNCTION__, (unsigned long) t, rbslimit, rbstop, stktop, stklimit,
 		   info->pr, (unsigned long) info->sw, info->sp);
 	STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags));
 }
@@ -1955,7 +1995,7 @@
 		   "  bsp    0x%lx\n"
 		   "  sof    0x%lx\n"
 		   "  ip     0x%lx\n",
-		   info->bsp, sof, info->ip);
+		   __FUNCTION__, info->bsp, sof, info->ip);
 	find_save_locs(info);
 }
 
@@ -1973,7 +2013,7 @@
 		   "  bsp    0x%lx\n"
 		   "  sol    0x%lx\n"
 		   "  ip     0x%lx\n",
-		   info->bsp, sol, info->ip);
+		   __FUNCTION__, info->bsp, sol, info->ip);
 	find_save_locs(info);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/lib/idiv64.S linux-2.4.23-pre8/arch/ia64/lib/idiv64.S
--- linux-2.4.22/arch/ia64/lib/idiv64.S	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/lib/idiv64.S	2003-10-22 22:47:39.000000000 +0000
@@ -37,57 +37,44 @@
 #define NAME		PASTE(PASTE(__,SGN),PASTE(OP,di3))
 
 GLOBAL_ENTRY(NAME)
-	.prologue
 	.regstk 2,0,0,0
 	// Transfer inputs to FP registers.
 	setf.sig f8 = in0
 	setf.sig f9 = in1
 	;;
-	.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)
-	;;
-
-	.save.f 0x10
-	stf.spill [sp] = f16
-	.body
 	INT_TO_FP(f9, f9)
 	;;
-	frcpa.s1 f17, p6 = f8, f9	// y0 = frcpa(b)
+	frcpa.s1 f11, 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)	fmpy.s1 f7 = f8, f11		// q0 = a*y0
+(p6)	fnma.s1 f6 = f9, f11, f1	// e0 = -b*y0 + 1
 	;;
-(p6)	fma.s1 f16 = f7, f6, f7		// q1 = q0*e0 + q0
+(p6)	fma.s1 f10 = f7, f6, f7		// q1 = q0*e0 + q0
 (p6)	fmpy.s1 f7 = f6, f6		// e1 = e0*e0
 	;;
 #ifdef MODULO
 	sub in1 = r0, in1		// in1 = -b
 #endif
-(p6)	fma.s1 f16 = f16, f7, f16	// q2 = q1*e1 + q1
-(p6)	fma.s1 f6 = f17, f6, f17	// y1 = y0*e0 + y0
+(p6)	fma.s1 f10 = f10, f7, f10	// q2 = q1*e1 + q1
+(p6)	fma.s1 f6 = f11, f6, f11	// 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, f10, f8	// r = -b*q2 + a
 	;;
 #ifdef MODULO
 	setf.sig f8 = in0		// f8 = a
 	setf.sig f9 = in1		// f9 = -b
 #endif
-(p6)	fma.s1 f17 = f7, f6, f16	// q3 = r*y2 + q2
+(p6)	fma.s1 f11 = f7, f6, f10	// q3 = r*y2 + q2
 	;;
-	.restore sp
-	ldf.fill f16 = [sp], 16
-	FP_TO_INT(f17, f17)		// q = trunc(q3)
+	FP_TO_INT(f11, f11)		// q = trunc(q3)
 	;;
 #ifdef MODULO
-	xma.l f17 = f17, f9, f8		// r = q*(-b) + a
+	xma.l f11 = f11, f9, f8		// r = q*(-b) + a
 	;;
 #endif
-	getf.sig r8 = f17		// transfer result to result register
-	ldf.fill f17 = [sp]
+	getf.sig r8 = f11		// transfer result to result register
 	br.ret.sptk.many rp
 END(NAME)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/mm/Makefile linux-2.4.23-pre8/arch/ia64/mm/Makefile
--- linux-2.4.22/arch/ia64/mm/Makefile	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/mm/Makefile	2003-10-22 22:48:22.000000000 +0000
@@ -12,5 +12,7 @@
 export-objs := init.o
 
 obj-y	 := init.o fault.o tlb.o extable.o
+obj-$(CONFIG_NUMA) += numa.o
+obj-$(CONFIG_DISCONTIGMEM) += discontig.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/mm/discontig.c linux-2.4.23-pre8/arch/ia64/mm/discontig.c
--- linux-2.4.22/arch/ia64/mm/discontig.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/mm/discontig.c	2003-10-22 22:49:55.000000000 +0000
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2000, 2003 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001 Tony Luck <tony.luck@intel.com>
+ * Copyright (c) 2002 NEC Corp.
+ * Copyright (c) 2002 Kimio Suganuma <k-suganuma@da.jp.nec.com>
+ */
+
+/*
+ * Platform initialization for Discontig Memory
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/mmzone.h>
+#include <linux/acpi.h>
+#include <linux/efi.h>
+#include <asm/pgalloc.h>
+#include <asm/tlb.h>
+
+
+/*
+ * Round an address upward to the next multiple of GRANULE size.
+ */
+#define GRANULEROUNDDOWN(n) ((n) & ~(IA64_GRANULE_SIZE-1))
+#define GRANULEROUNDUP(n) (((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1))
+
+/*
+ * Used to locate BOOT_DATA prior to initializing the node data area.
+ */
+#define BOOT_NODE_DATA(node)	pg_data_ptr[node]
+
+/*
+ * To prevent cache aliasing effects, align per-node structures so that they 
+ * start at addresses that are strided by node number.
+ */
+#define NODEDATA_ALIGN(addr, node)	((((addr) + 1024*1024-1) & ~(1024*1024-1)) + (node)*PAGE_SIZE)
+
+
+static struct ia64_node_data	*boot_node_data[NR_NODES] __initdata;
+static pg_data_t		*pg_data_ptr[NR_NODES] __initdata;
+static bootmem_data_t		bdata[NR_NODES] __initdata;
+static unsigned long		boot_pernode[NR_NODES] __initdata;
+static unsigned long		boot_pernodesize[NR_NODES] __initdata;
+
+extern int  filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
+extern struct cpuinfo_ia64 *_cpu_data[NR_CPUS];
+
+
+
+/*
+ * We allocate one of the bootmem_data_t structs for each piece of memory
+ * that we wish to treat as a contiguous block.  Each such block must start
+ * on a GRANULE boundary.  Multiple banks per node is not supported.
+ *   (Note: on SN2, all memory on a node is trated as a single bank.
+ *   Holes within the bank are supported. This works because memory
+ *   from different banks is not interleaved. The bootmap bitmap
+ *   for the node is somewhat large but not too large).
+ */
+static int __init
+build_maps(unsigned long start, unsigned long end, int node)
+{
+	bootmem_data_t	*bdp;
+	unsigned long cstart, epfn;
+
+	bdp = &bdata[node];
+	epfn = GRANULEROUNDUP(__pa(end)) >> PAGE_SHIFT;
+	cstart = GRANULEROUNDDOWN(__pa(start));
+
+	if (!bdp->node_low_pfn) {
+		bdp->node_boot_start = cstart;
+		bdp->node_low_pfn = epfn;
+	} else {
+		bdp->node_boot_start = min(cstart, bdp->node_boot_start);
+		bdp->node_low_pfn = max(epfn, bdp->node_low_pfn);
+	}
+
+	min_low_pfn = min(min_low_pfn, bdp->node_boot_start>>PAGE_SHIFT);
+	max_low_pfn = max(max_low_pfn, bdp->node_low_pfn);
+
+	return 0;
+}
+
+
+/*
+ * Count the number of cpus on the node
+ */
+static __inline__ int
+count_cpus(int node)
+{
+	int cpu, n=0;
+
+	for (cpu=0; cpu < NR_CPUS; cpu++)
+		if (node == node_cpuid[cpu].nid)
+			n++;
+	return n;
+}
+
+
+/*
+ * Find space on each node for the bootmem map & other per-node data structures.
+ *
+ * Called by efi_memmap_walk to find boot memory on each node. Note that
+ * only blocks that are free are passed to this routine (currently filtered by
+ * free_available_memory).
+ */
+static int __init
+find_pernode_space(unsigned long start, unsigned long end, int node)
+{
+	unsigned long	mapsize, pages, epfn, map=0, cpu, cpus;
+	unsigned long	pernodesize=0, pernode;
+	unsigned long	cpu_data, mmu_gathers;
+	unsigned long	pstart, length;
+	bootmem_data_t	*bdp;
+
+	pstart = __pa(start);
+	length = end - start;
+	epfn = (pstart + length) >> PAGE_SHIFT;
+	bdp = &bdata[node];
+
+	if (pstart < bdp->node_boot_start || epfn > bdp->node_low_pfn)
+		return 0;
+
+	if (!boot_pernode[node]) {
+		cpus = count_cpus(node);
+		pernodesize += PAGE_ALIGN(sizeof(struct cpuinfo_ia64)) * cpus;
+		pernodesize += L1_CACHE_ALIGN(sizeof(mmu_gather_t)) * cpus;
+		pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t));
+		pernodesize += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
+		pernodesize = PAGE_ALIGN(pernodesize);
+		pernode = NODEDATA_ALIGN(pstart, node);
+	
+		if (pstart + length > (pernode + pernodesize)) {
+			boot_pernode[node] = pernode;
+			boot_pernodesize[node] = pernodesize;
+			memset(__va(pernode), 0, pernodesize);
+
+			cpu_data = pernode;
+			pernode += PAGE_ALIGN(sizeof(struct cpuinfo_ia64)) * cpus;
+
+			mmu_gathers = pernode;
+			pernode += L1_CACHE_ALIGN(sizeof(mmu_gather_t)) * cpus;
+
+			pg_data_ptr[node] = __va(pernode);
+			pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
+
+			boot_node_data[node] = __va(pernode);
+			pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
+
+			pg_data_ptr[node]->bdata = &bdata[node];
+			pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
+
+			for (cpu=0; cpu < NR_CPUS; cpu++) {
+				if (node == node_cpuid[cpu].nid) {
+					_cpu_data[cpu] = __va(cpu_data);
+					_cpu_data[cpu]->node_data = boot_node_data[node];
+					_cpu_data[cpu]->nodeid = node;
+					_cpu_data[cpu]->mmu_gathers = __va(mmu_gathers);
+					cpu_data +=  PAGE_ALIGN(sizeof(struct cpuinfo_ia64));
+					mmu_gathers += L1_CACHE_ALIGN(sizeof(mmu_gather_t));
+				}
+			}
+
+		}
+	}
+
+	pernode = boot_pernode[node];
+	pernodesize = boot_pernodesize[node];
+	if (pernode && !bdp->node_bootmem_map) {
+		pages = bdp->node_low_pfn - (bdp->node_boot_start>>PAGE_SHIFT);
+		mapsize = bootmem_bootmap_pages(pages) << PAGE_SHIFT;
+
+		if (pernode - pstart > mapsize)
+			map = pstart;
+		else if (pstart + length - pernode - pernodesize > mapsize)
+			map = pernode + pernodesize;
+
+		if (map) {
+			init_bootmem_node(
+				BOOT_NODE_DATA(node),
+				map>>PAGE_SHIFT, 
+				bdp->node_boot_start>>PAGE_SHIFT,
+				bdp->node_low_pfn);
+		}
+
+	}
+
+	return 0;
+}
+
+
+/*
+ * Free available memory to the bootmem allocator.
+ *
+ * Note that only blocks that are free are passed to this routine (currently 
+ * filtered by free_available_memory).
+ *
+ */
+static int __init
+discontig_free_bootmem_node(unsigned long start, unsigned long end, int node)
+{
+	free_bootmem_node(BOOT_NODE_DATA(node), __pa(start), end - start);
+
+	return 0;
+}
+
+
+/*
+ * Reserve the space used by the bootmem maps.
+ */
+static void __init
+discontig_reserve_bootmem(void)
+{
+	int		node;
+	unsigned long	base, size, pages;
+	bootmem_data_t	*bdp;
+
+	for (node = 0; node < numnodes; node++) {
+		bdp = BOOT_NODE_DATA(node)->bdata;
+
+		pages = bdp->node_low_pfn - (bdp->node_boot_start>>PAGE_SHIFT);
+		size = bootmem_bootmap_pages(pages) << PAGE_SHIFT;
+		base = __pa(bdp->node_bootmem_map);
+		reserve_bootmem_node(BOOT_NODE_DATA(node), base, size);
+
+		size = boot_pernodesize[node];
+		base = __pa(boot_pernode[node]);
+		reserve_bootmem_node(BOOT_NODE_DATA(node), base, size);
+	}
+}
+
+/*
+ * Initialize per-node data
+ *
+ * Finish setting up the node data for this node, then copy it to the other nodes.
+ *
+ */
+static void __init
+initialize_pernode_data(void)
+{
+	int	cpu, node;
+
+	memcpy(boot_node_data[0]->pg_data_ptrs, pg_data_ptr, sizeof(pg_data_ptr));
+	memcpy(boot_node_data[0]->node_data_ptrs, boot_node_data, sizeof(boot_node_data));
+
+	for (node=1; node < numnodes; node++) {
+		memcpy(boot_node_data[node], boot_node_data[0], sizeof(struct ia64_node_data));
+		boot_node_data[node]->node = node;
+	}
+
+	for (cpu=0; cpu < NR_CPUS; cpu++) {
+		node = node_cpuid[cpu].nid;
+		_cpu_data[cpu]->node_data = boot_node_data[node];
+		_cpu_data[cpu]->nodeid = node;
+	}
+}
+
+
+/*
+ * Called early in boot to setup the boot memory allocator, and to
+ * allocate the node-local pg_data & node-directory data structures..
+ */
+void __init
+discontig_mem_init(void)
+{
+	if (numnodes == 0) {
+		printk("node info missing!\n");
+		numnodes = 1;
+	}
+
+	min_low_pfn = -1;
+	max_low_pfn = 0;
+
+        efi_memmap_walk(filter_rsvd_memory, build_maps);
+        efi_memmap_walk(filter_rsvd_memory, find_pernode_space);
+        efi_memmap_walk(filter_rsvd_memory, discontig_free_bootmem_node);
+
+	discontig_reserve_bootmem();
+	initialize_pernode_data();
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/mm/init.c linux-2.4.23-pre8/arch/ia64/mm/init.c
--- linux-2.4.22/arch/ia64/mm/init.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/mm/init.c	2003-10-22 22:48:39.000000000 +0000
@@ -16,12 +16,14 @@
 #include <linux/slab.h>
 #include <linux/swap.h>
 #include <linux/efi.h>
+#include <linux/mmzone.h>
 
 #include <asm/bitops.h>
 #include <asm/dma.h>
 #include <asm/ia32.h>
 #include <asm/io.h>
 #include <asm/machvec.h>
+#include <asm/numa.h>
 #include <asm/pgalloc.h>
 #include <asm/sal.h>
 #include <asm/system.h>
@@ -34,11 +36,14 @@
 extern char _stext, _etext, _edata, __init_begin, __init_end;
 
 extern void ia64_tlb_init (void);
+extern int  filter_rsvd_memory (unsigned long, unsigned long, void *);
 
+/* Note - may be changed by platform_setup */
 unsigned long MAX_DMA_ADDRESS = PAGE_OFFSET + 0x100000000UL;
 #define LARGE_GAP 0x40000000 /* Use virtual mem map if a hole is > than this */
 
-static unsigned long totalram_pages;
+static unsigned long totalram_pages, reserved_pages;
+struct page *zero_page_memmap_ptr;		/* map entry for zero page */
 
 unsigned long vmalloc_end = VMALLOC_END_INIT;
 
@@ -63,6 +68,16 @@
 	return freed;
 }
 
+inline void
+ia64_set_rbs_bot (void)
+{
+	unsigned long stack_size = current->rlim[RLIMIT_STACK].rlim_max & -16;
+
+	if (stack_size > MAX_USER_STACK_SIZE)
+		stack_size = MAX_USER_STACK_SIZE;
+	current->thread.rbs_bot = STACK_TOP - stack_size;
+}
+
 /*
  * This performs some platform-dependent address space initialization.
  * On IA-64, we want to setup the VM area for the register backing
@@ -74,6 +89,8 @@
 {
 	struct vm_area_struct *vma;
 
+	ia64_set_rbs_bot();
+
 	/*
 	 * If we're out of memory and kmem_cache_alloc() returns NULL, we simply ignore
 	 * the problem.  When the process attempts to write to the register backing store
@@ -82,7 +99,7 @@
 	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 	if (vma) {
 		vma->vm_mm = current->mm;
-		vma->vm_start = IA64_RBS_BOT;
+		vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
 		vma->vm_end = vma->vm_start + PAGE_SIZE;
 		vma->vm_page_prot = PAGE_COPY;
 		vma->vm_flags = VM_READ|VM_WRITE|VM_MAYREAD|VM_MAYWRITE|VM_GROWSUP;
@@ -110,10 +127,11 @@
 void
 free_initmem (void)
 {
-	unsigned long addr;
+	unsigned long addr, eaddr;
 
-	addr = (unsigned long) &__init_begin;
-	for (; addr < (unsigned long) &__init_end; addr += PAGE_SIZE) {
+	addr = (unsigned long) ia64_imva(&__init_begin);
+	eaddr = (unsigned long) ia64_imva(&__init_end);
+	for (; addr < eaddr; addr += PAGE_SIZE) {
 		clear_bit(PG_reserved, &virt_to_page((void *)addr)->flags);
 		set_page_count(virt_to_page((void *)addr), 1);
 		free_page(addr);
@@ -189,58 +207,39 @@
 void
 show_mem(void)
 {
-	int i, total = 0, reserved = 0;
-	int shared = 0, cached = 0;
+	int i, reserved;
+	int shared, cached;
+	pg_data_t *pgdat;
+	char *tchar = (numnodes > 1) ? "\t" : "";
 
 	printk("Mem-info:\n");
 	show_free_areas();
 
-#ifdef CONFIG_DISCONTIGMEM
-	{
-		pg_data_t *pgdat = pgdat_list;
-
-		printk("Free swap:       %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
-		do {
-			printk("Node ID: %d\n", pgdat->node_id);
-			for(i = 0; i < pgdat->node_size; i++) {
-				if (PageReserved(pgdat->node_mem_map+i))
-					reserved++;
-				else if (PageSwapCache(pgdat->node_mem_map+i))
-					cached++;
-				else if (page_count(pgdat->node_mem_map + i))
-					shared += page_count(pgdat->node_mem_map + i) - 1;
-			}
-			printk("\t%d pages of RAM\n", pgdat->node_size);
-			printk("\t%d reserved pages\n", reserved);
-			printk("\t%d pages shared\n", shared);
-			printk("\t%d pages swap cached\n", cached);
-			pgdat = pgdat->node_next;
-		} while (pgdat);
-		printk("Total of %ld pages in page table cache\n", pgtable_cache_size);
-		show_buffers();
-		printk("%d free buffer pages\n", nr_free_buffer_pages());
-	}
-#else /* !CONFIG_DISCONTIGMEM */
 	printk("Free swap:       %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
-	i = max_mapnr;
-	while (i-- > 0) {
-		if (!VALID_PAGE(mem_map + i))
-			continue;
-		total++;
-		if (PageReserved(mem_map+i))
-			reserved++;
-		else if (PageSwapCache(mem_map+i))
-			cached++;
-		else if (page_count(mem_map + i))
-			shared += page_count(mem_map + i) - 1;
+	for_each_pgdat(pgdat) {
+		reserved=0;
+		cached=0;
+		shared=0;
+		if (numnodes > 1)
+			printk("Node ID: %d\n", pgdat->node_id);
+		for(i = 0; i < pgdat->node_size; i++) {
+			if (!VALID_PAGE(pgdat->node_mem_map+i))
+				continue;
+			if (PageReserved(pgdat->node_mem_map+i))
+				reserved++;
+			else if (PageSwapCache(pgdat->node_mem_map+i))
+				cached++;
+			else if (page_count(pgdat->node_mem_map + i))
+				shared += page_count(pgdat->node_mem_map + i) - 1;
+		}
+		printk("%s%ld pages of RAM\n", tchar, pgdat->node_size);
+		printk("%s%d reserved pages\n", tchar, reserved);
+		printk("%s%d pages shared\n", tchar, shared);
+		printk("%s%d pages swap cached\n", tchar, cached);
 	}
-	printk("%d pages of RAM\n", total);
-	printk("%d reserved pages\n", reserved);
-	printk("%d pages shared\n", shared);
-	printk("%d pages swap cached\n", cached);
-	printk("%ld pages in page table cache\n", pgtable_cache_size);
+	printk("Total of %ld pages in page table cache\n", pgtable_cache_size);
 	show_buffers();
-#endif /* !CONFIG_DISCONTIGMEM */
+	printk("%d free buffer pages\n", nr_free_buffer_pages());
 }
 
 /*
@@ -360,8 +359,10 @@
 static int
 create_mem_map_page_table (u64 start, u64 end, void *arg)
 {
-	unsigned long address, start_page, end_page;
+	unsigned long address, start_page, end_page, next_blk_page;
+	unsigned long blk_start;
 	struct page *map_start, *map_end;
+	int node=0;
 	pgd_t *pgd;
 	pmd_t *pmd;
 	pte_t *pte;
@@ -374,18 +375,35 @@
 	start_page = (unsigned long) map_start & PAGE_MASK;
 	end_page = PAGE_ALIGN((unsigned long) map_end);
 
+	/* force the first iteration to get node id */
+	blk_start = start;
+	next_blk_page = 0;
+
 	for (address = start_page; address < end_page; address += PAGE_SIZE) {
+
+		/* if we went across a node boundary, get new nid */
+		if (address >= next_blk_page) {
+			struct page *map_next_blk;
+
+			node = paddr_to_nid(__pa(blk_start));
+
+			/* get end addr of this memblk as next blk_start */
+			blk_start = (unsigned long) __va(min(end, memblk_endpaddr(__pa(blk_start))));
+			map_next_blk = vmem_map + MAP_NR_DENSE(blk_start);
+			next_blk_page = PAGE_ALIGN((unsigned long) map_next_blk);
+		}
+
 		pgd = pgd_offset_k(address);
 		if (pgd_none(*pgd))
-			pgd_populate(&init_mm, pgd, alloc_bootmem_pages(PAGE_SIZE));
+			pgd_populate(&init_mm, pgd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE));
 		pmd = pmd_offset(pgd, address);
 
 		if (pmd_none(*pmd))
-			pmd_populate(&init_mm, pmd, alloc_bootmem_pages(PAGE_SIZE));
+			pmd_populate(&init_mm, pmd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE));
 		pte = pte_offset(pmd, address);
 
 		if (pte_none(*pte))
-			set_pte(pte, mk_pte_phys(__pa(alloc_bootmem_pages(PAGE_SIZE)),
+			set_pte(pte, mk_pte_phys(__pa(alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE)),
 						 PAGE_KERNEL));
  	}
  	return 0;
@@ -399,6 +417,14 @@
 	int highmem;
 };
 
+struct memmap_count_callback_data {
+	int node;
+	unsigned long num_physpages;
+	unsigned long num_dma_physpages;
+	unsigned long min_pfn;
+	unsigned long max_pfn;
+} cdata;
+
 static int
 virtual_memmap_init (u64 start, u64 end, void *arg)
 {
@@ -454,17 +480,7 @@
 		efi_memmap_walk(virtual_memmap_init, &args);
 	}
 
-	return page_to_phys(end);
-}
-
-static int
-count_dma_pages (u64 start, u64 end, void *arg)
-{
-	unsigned long *count = arg;
-
-	if (end <= MAX_DMA_ADDRESS)
-		*count += (end - start) >> PAGE_SHIFT;
-	return 0;
+	return page_to_phys(end-1) + PAGE_SIZE;;
 }
 
 int
@@ -475,16 +491,27 @@
 	return __get_user(byte, (char *) page) == 0;
 }
 
+#define GRANULEROUNDDOWN(n) ((n) & ~(IA64_GRANULE_SIZE-1))
+#define GRANULEROUNDUP(n) (((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1))
+#define ORDERROUNDDOWN(n) ((n) & ~((PAGE_SIZE<<MAX_ORDER)-1))
 static int
-count_pages (u64 start, u64 end, void *arg)
+count_pages (u64 start, u64 end, int node)
 {
-	unsigned long *count = arg;
-
-	*count += (end - start) >> PAGE_SHIFT;
+	start = __pa(start);
+	end = __pa(end);
+	if (node == cdata.node) {
+		cdata.num_physpages += (end - start) >> PAGE_SHIFT;
+		if (start <= __pa(MAX_DMA_ADDRESS))
+			cdata.num_dma_physpages += (min(end, __pa(MAX_DMA_ADDRESS)) - start) >> PAGE_SHIFT;
+		start = GRANULEROUNDDOWN(__pa(start));
+		start = ORDERROUNDDOWN(start);
+		end = GRANULEROUNDUP(__pa(end));
+		cdata.max_pfn = max(cdata.max_pfn, end >> PAGE_SHIFT);
+		cdata.min_pfn = min(cdata.min_pfn, start >> PAGE_SHIFT);
+	}
 	return 0;
 }
 
-#ifndef CONFIG_DISCONTIGMEM
 static int
 find_largest_hole(u64 start, u64 end, void *arg)
 {
@@ -498,7 +525,6 @@
 	last_end = end;
 	return 0;
 }
-#endif
 
 /*
  * Set up the page tables.
@@ -509,73 +535,76 @@
 	unsigned long max_dma;
 	unsigned long zones_size[MAX_NR_ZONES];
 	unsigned long zholes_size[MAX_NR_ZONES];
-#ifndef CONFIG_DISCONTIGMEM
 	unsigned long max_gap;
-#endif
+	int node;
 
 	/* initialize mem_map[] */
 
-	memset(zones_size, 0, sizeof(zones_size));
-	memset(zholes_size, 0, sizeof(zholes_size));
-
-	num_physpages = 0;
-	efi_memmap_walk(count_pages, &num_physpages);
-
-	num_dma_physpages = 0;
-	efi_memmap_walk(count_dma_pages, &num_dma_physpages);
-
 	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-
-	if (max_low_pfn < max_dma) {
-		zones_size[ZONE_DMA] = max_low_pfn;
-		zholes_size[ZONE_DMA] = max_low_pfn - num_dma_physpages;
-	} else {
-		zones_size[ZONE_DMA] = max_dma;
-		zholes_size[ZONE_DMA] = max_dma - num_dma_physpages;
-		if (num_physpages > num_dma_physpages) {
-			zones_size[ZONE_NORMAL] = max_low_pfn - max_dma;
-			zholes_size[ZONE_NORMAL] = (max_low_pfn - max_dma)
-					- (num_physpages - num_dma_physpages);
-		}
-	}
-
-#ifdef CONFIG_DISCONTIGMEM
-	free_area_init_node(0, NULL, NULL, zones_size, 0, zholes_size);
-#else
 	max_gap = 0;
 	efi_memmap_walk(find_largest_hole, (u64 *)&max_gap);
 
-	if (max_gap < LARGE_GAP) {
-		vmem_map = (struct page *)0;
-		free_area_init_node(0, NULL, NULL, zones_size, 0, zholes_size);
+	for (node=0; node < numnodes; node++) {
+		memset(zones_size, 0, sizeof(zones_size));
+		memset(zholes_size, 0, sizeof(zholes_size));
+		memset(&cdata, 0, sizeof(cdata));
+
+		cdata.node = node;
+		cdata.min_pfn = ~0;
+
+		efi_memmap_walk(filter_rsvd_memory, count_pages);
+		num_dma_physpages += cdata.num_dma_physpages;
+		num_physpages += cdata.num_physpages;
+
+		if (cdata.min_pfn >= max_dma) {
+			zones_size[ZONE_NORMAL] = cdata.max_pfn - cdata.min_pfn;
+			zholes_size[ZONE_NORMAL] = cdata.max_pfn - cdata.min_pfn - cdata.num_physpages;
+		} else if (cdata.max_pfn < max_dma) {
+			zones_size[ZONE_DMA] = cdata.max_pfn - cdata.min_pfn;
+			zholes_size[ZONE_DMA] = cdata.max_pfn - cdata.min_pfn - cdata.num_dma_physpages;
+		} else {
+			zones_size[ZONE_DMA] = max_dma - cdata.min_pfn;
+			zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] - cdata.num_dma_physpages;
+			zones_size[ZONE_NORMAL] = cdata.max_pfn - max_dma;
+			zholes_size[ZONE_NORMAL] = zones_size[ZONE_NORMAL] - (cdata.num_physpages - cdata.num_dma_physpages);
+		}
+	
+		if (numnodes == 1 && max_gap < LARGE_GAP) {
+			vmem_map = (struct page *)0;
+			zones_size[ZONE_DMA] += cdata.min_pfn;
+			zholes_size[ZONE_DMA] += cdata.min_pfn;
+			free_area_init_core(0, NODE_DATA(node), &mem_map, zones_size, 0, zholes_size, NULL);
+		} else {
+	
+			/* allocate virtual mem_map */
+	
+			if (node == 0) {
+				unsigned long map_size;
+				map_size = PAGE_ALIGN(max_low_pfn*sizeof(struct page));
+				vmalloc_end -= map_size;
+				mem_map = vmem_map = (struct page *) vmalloc_end;
+				efi_memmap_walk(create_mem_map_page_table, 0);
+				printk(KERN_INFO "Virtual mem_map starts at 0x%p\n", mem_map);
+			}
+	
+			free_area_init_node(node, NODE_DATA(node), vmem_map+cdata.min_pfn, zones_size, 
+				cdata.min_pfn<<PAGE_SHIFT, zholes_size);
+		}
 	}
-	else {
-		unsigned long map_size;
 
-		/* allocate virtual mem_map */
-
-		map_size = PAGE_ALIGN(max_low_pfn*sizeof(struct page));
-		vmalloc_end -= map_size;
-		vmem_map = (struct page *) vmalloc_end;
-		efi_memmap_walk(create_mem_map_page_table, 0);
-
-		free_area_init_node(0, NULL, vmem_map, zones_size, 0, zholes_size);
-		printk(KERN_INFO "Virtual mem_map starts at 0x%p\n", mem_map);
-	}
-#endif
+	zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
 }
 
 static int
 count_reserved_pages (u64 start, u64 end, void *arg)
 {
 	unsigned long num_reserved = 0;
-	unsigned long *count = arg;
 	struct page *pg;
 
 	for (pg = virt_to_page((void *)start); pg < virt_to_page((void *)end); ++pg)
 		if (PageReserved(pg))
 			++num_reserved;
-	*count += num_reserved;
+	reserved_pages += num_reserved;
 	return 0;
 }
 
@@ -583,8 +612,10 @@
 mem_init (void)
 {
 	extern char __start_gate_section[];
-	long reserved_pages, codesize, datasize, initsize;
+	long codesize, datasize, initsize;
 	unsigned long num_pgt_pages;
+	pg_data_t *pgdat;
+
 
 #ifdef CONFIG_PCI
 	/*
@@ -601,10 +632,11 @@
 	max_mapnr = max_low_pfn;
 	high_memory = __va(max_low_pfn * PAGE_SIZE);
 
-	totalram_pages += free_all_bootmem();
+	for_each_pgdat(pgdat)
+		totalram_pages += free_all_bootmem_node(pgdat);
 
 	reserved_pages = 0;
-	efi_memmap_walk(count_reserved_pages, &reserved_pages);
+	efi_memmap_walk(filter_rsvd_memory, count_reserved_pages);
 
 	codesize =  (unsigned long) &_etext - (unsigned long) &_stext;
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
@@ -629,7 +661,7 @@
 		pgt_cache_water[1] = num_pgt_pages;
 
 	/* install the gate page in the global page table: */
-	put_gate_page(virt_to_page(__start_gate_section), GATE_ADDR);
+	put_gate_page(virt_to_page(ia64_imva(__start_gate_section)), GATE_ADDR);
 
 #ifdef CONFIG_IA32_SUPPORT
 	ia32_gdt_init();
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/mm/numa.c linux-2.4.23-pre8/arch/ia64/mm/numa.c
--- linux-2.4.22/arch/ia64/mm/numa.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/mm/numa.c	2003-10-22 22:48:56.000000000 +0000
@@ -0,0 +1,104 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * This file contains NUMA specific variables and functions which can
+ * be split away from DISCONTIGMEM and are used on NUMA machines with
+ * contiguous memory.
+ * 
+ *                         2002/08/07 Erich Focht <efocht@ess.nec.de>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mmzone.h>
+#include <linux/smp.h>
+#include <asm/numa.h>
+
+/*
+ * The following structures are usually initialized by ACPI or
+ * similar mechanisms and describe the NUMA characteristics of the machine.
+ */
+int num_memblks = 0;
+struct node_memblk_s node_memblk[NR_MEMBLKS];
+struct node_cpuid_s node_cpuid[NR_CPUS];
+/*
+ * This is a matrix with "distances" between nodes, they should be
+ * proportional to the memory access latency ratios.
+ */
+u8 numa_slit[NR_NODES * NR_NODES];
+
+/* Identify which cnode a physical address resides on */
+int
+paddr_to_nid(unsigned long paddr)
+{
+	int	i;
+
+	for (i = 0; i < num_memblks; i++)
+		if (paddr >= node_memblk[i].start_paddr &&
+		    paddr < node_memblk[i].start_paddr + node_memblk[i].size)
+			break;
+
+	return (i < num_memblks) ? node_memblk[i].nid : (num_memblks ? -1 : 0);
+}
+
+/* return end addr of a memblk */
+unsigned long
+memblk_endpaddr(unsigned long paddr)
+{
+	int	i;
+
+	for (i = 0; i < num_memblks; i++)
+		if (paddr >= node_memblk[i].start_paddr &&
+		    paddr < node_memblk[i].start_paddr + node_memblk[i].size)
+			return node_memblk[i].start_paddr + node_memblk[i].size;
+
+	return 0;
+}
+
+
+/* on which node is each logical CPU (one cacheline even for 64 CPUs) */
+volatile char cpu_to_node_map[NR_CPUS] __cacheline_aligned;
+
+/* which logical CPUs are on which nodes */
+volatile unsigned long node_to_cpu_mask[NR_NODES]  __cacheline_aligned;
+
+/*
+ * Build cpu to node mapping and initialize the per node cpu masks.
+ */
+void __init
+build_cpu_to_node_map (void)
+{
+	int cpu, i, node;
+
+	for(cpu = 0; cpu < NR_CPUS; ++cpu) {
+		/*
+		 * All Itanium NUMA platforms I know use ACPI, so maybe we
+		 * can drop this ifdef completely.                    [EF]
+		 */
+#ifdef CONFIG_SMP
+# ifdef CONFIG_ACPI_NUMA
+		node = -1;
+		for (i = 0; i < NR_CPUS; ++i) {
+			extern volatile int ia64_cpu_to_sapicid[];
+			if (ia64_cpu_to_sapicid[cpu] == node_cpuid[i].phys_id) {
+				node = node_cpuid[i].nid;
+				break;
+			}
+		}
+# else
+#		error Fixme: Dunno how to build CPU-to-node map.
+# endif
+		cpu_to_node_map[cpu] = node;
+		if (node >= 0)
+			__set_bit(cpu, &node_to_cpu_mask[node]);
+#else
+			__set_bit(0, &node_to_cpu_mask[0]);
+#endif
+	}
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/mm/tlb.c linux-2.4.23-pre8/arch/ia64/mm/tlb.c
--- linux-2.4.22/arch/ia64/mm/tlb.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/mm/tlb.c	2003-10-22 22:49:12.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * TLB support routines.
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * 08/02/00 A. Mallick <asit.k.mallick@intel.com>
@@ -16,28 +16,21 @@
 #include <linux/smp.h>
 #include <linux/mm.h>
 
+#include <asm/delay.h>
 #include <asm/mmu_context.h>
 #include <asm/pgalloc.h>
 #include <asm/pal.h>
-#include <asm/delay.h>
 
-#define SUPPORTED_PGBITS (			\
-		1 << _PAGE_SIZE_256M |		\
-		1 << _PAGE_SIZE_64M  |		\
-		1 << _PAGE_SIZE_16M  |		\
-		1 << _PAGE_SIZE_4M   |		\
-		1 << _PAGE_SIZE_1M   |		\
-		1 << _PAGE_SIZE_256K |		\
-		1 << _PAGE_SIZE_64K  |		\
-		1 << _PAGE_SIZE_16K  |		\
-		1 << _PAGE_SIZE_8K   |		\
-		1 << _PAGE_SIZE_4K )
+static struct {
+	unsigned long mask;	/* mask of supported purge page-sizes */
+	unsigned long max_bits;	/* log2() of largest supported purge page-size */
+} purge;
 
 struct ia64_ctx ia64_ctx = {
-	.lock =	SPIN_LOCK_UNLOCKED,
-	.next =	1,
-	.limit =(1 << 15) - 1,		/* start out with the safe (architected) limit */
-	.max_ctx = ~0U
+	.lock =		SPIN_LOCK_UNLOCKED,
+	.next =		1,
+	.limit =	(1 << 15) - 1,		/* start out with the safe (architected) limit */
+	.max_ctx =	~0U
 };
 
 /*
@@ -149,22 +142,10 @@
 	}
 
 	nbits = ia64_fls(size + 0xfff);
-	if (((1UL << nbits) & SUPPORTED_PGBITS) == 0) {
-		if (nbits > _PAGE_SIZE_256M)
-			nbits = _PAGE_SIZE_256M;
-		else
-			/*
-			 * Some page sizes are not implemented in the
-			 * IA-64 arch, so if we get asked to clear an
-			 * unsupported page size, round up to the
-			 * nearest page size.  Note that we depend on
-			 * the fact that if page size N is not
-			 * implemented, 2*N _is_ implemented.
-			 */
-			++nbits;
-		if (((1UL << nbits) & SUPPORTED_PGBITS) == 0)
-			panic("flush_tlb_range: BUG: nbits=%lu\n", nbits);
-	}
+	while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits))
+		++nbits;
+	if (nbits > purge.max_bits)
+		nbits = purge.max_bits;
 	start &= ~((1UL << nbits) - 1);
 
 # ifdef CONFIG_SMP
@@ -185,6 +166,15 @@
 ia64_tlb_init (void)
 {
 	ia64_ptce_info_t ptce_info;
+	unsigned long tr_pgbits;
+	long status;
+
+	if ((status = ia64_pal_vm_page_size(&tr_pgbits, &purge.mask)) != 0) {
+		printk(KERN_ERR "PAL_VM_PAGE_SIZE failed with status=%ld;"
+		       "defaulting to architected purge page-sizes.\n", status);
+		purge.mask = 0x115557000;
+	}
+	purge.max_bits = ia64_fls(purge.mask);
 
 	ia64_get_ptce(&ptce_info);
 	local_cpu_data->ptce_base = ptce_info.base;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/scripts/make_gas_hint_test.c linux-2.4.23-pre8/arch/ia64/scripts/make_gas_hint_test.c
--- linux-2.4.22/arch/ia64/scripts/make_gas_hint_test.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/scripts/make_gas_hint_test.c	2003-10-22 22:47:37.000000000 +0000
@@ -0,0 +1,15 @@
+// The code generates a test case which is used
+// to detect whether Binutil supports hint
+// instruction correctly or not.
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+	char str[32766];
+	memset(str,'\n',32765);
+	str[32765]=0;
+	printf("%s(p7) hint @pause\n",str);
+
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/fakeprom/fpmem.c linux-2.4.23-pre8/arch/ia64/sn/fakeprom/fpmem.c
--- linux-2.4.22/arch/ia64/sn/fakeprom/fpmem.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/fakeprom/fpmem.c	2003-10-22 22:48:31.000000000 +0000
@@ -17,8 +17,58 @@
  * 	  klconfig to efi_memmap
  */
 
+
+/*
+ * Sometimes it is useful to build a fake prom with a memmap that matches another
+ * platform. There are restrictions on how successful you will be, but here
+ * are the instructions for what I have used in the past & had good luck:
+ *
+ * 	- compile a kernel for the target platform (like zx1) with the following
+ * 	  set: 
+ * 	  	#define EFI_DEBUG 1		# in arch/ia64/kernel/efi.c
+ * 	  	#define SRAT_DEBUG		# in drivers/acpi/numa.c
+ *
+ *	- this causes the kernel to dump the memmap & SRAT during boot.
+ *
+ *	- copy the console output to a file.
+ *
+ *	- run the following script with the file as input:
+ *		
+ *			#!/bin/sh
+ *			
+ *			awk '
+ *			/^mem/ {
+ *			        printf "\t{%s, %sUL, %sUL, %sUL},\n", $4, $7, $11, $12
+ *			} 
+ *			/SRAT Memory/ {
+ *			        if (srat != 1) print "SRAT"
+ *			        srat = 1
+ *			        for (i=1; i<=0;i++)
+ *			                printf "%4d |%s|\n", i, $i
+ *			        printf "\t{%s, %sUL, %sUL, %sUL},\n", $4, $6, $8, $13
+ *			}
+ *			BEGIN {
+ *			        FS="[ \[\)\(\t:=,-]"
+ *			} '
+ *			
+ * 	- this converts the memmap & SRAT info into C code array initilization statements.
+ *
+ * 	- copy & paste the initialization statements into the arrays below. Look for
+ * 	  comments "PASTE xxx HERE". In general, on the MEMMAP is present on most other
+ * 	  systems. If you have an SRAT, you may need to hack the number of nodes in fw-emu.
+ * 	  Good luck...
+ *
+ * 	- set "#define FAKE_MEMMAP 1
+ *
+ * 	- When running medusa, make sure you set the node1_memory_config to cover the
+ * 	  amount of memory that you are going to use. Also note that you can run the
+ * 	  kernel in "alias" space (starts at phy adr 0). This is kinda tricky, though
+ */
+
+
 #include <linux/config.h>
 #include <linux/efi.h>
+#include <linux/acpi.h>
 #include "fpmem.h"
 
 /*
@@ -77,9 +127,9 @@
 /* For SN, get the index th nasid */
 
 int
-GetNasid(int index)
+GetNasid(int cnode)
 {
-	return sn_memmap[index].nasid ;
+	return sn_memmap[cnode].nasid ;
 }
 
 node_memmap_t
@@ -94,6 +144,21 @@
 	return  sn_memmap[cnode].cpuconfig & (1UL<<cpu);
 }
 
+void
+GetLogicalCpu(int bsp, int *nasidp, int *cpup)
+{
+	int cnode, cpu;
+
+	for (cnode=0; cnode<GetNumNodes(); cnode++) {
+		for (cpu=0; cpu<MAX_CPUS_NODE; cpu++)
+			if (IsCpuPresent(cnode,cpu)) {
+				*nasidp = GetNasid(cnode);
+				*cpup = cpu;
+				if (bsp-- == 0)
+					return;
+			}
+	}
+}
 
 /*
  * Made this into an explicit case statement so that
@@ -102,31 +167,41 @@
  */
 
 #ifdef SGI_SN2
-int
-IsBankPresent(int index, node_memmap_t nmemmap)
-{
-	switch (index) {
-		case 0:return BankPresent(nmemmap.b0size);
-		case 1:return BankPresent(nmemmap.b1size);
-		case 2:return BankPresent(nmemmap.b2size);
-		case 3:return BankPresent(nmemmap.b3size);
-		default:return -1 ;
-	}
-}
-
-int
+long
 GetBankSize(int index, node_memmap_t nmemmap)
 {
+	int bsize, bdou, hack;
 	/*
 	 * Add 2 because there are 4 dimms per bank.
 	 */
         switch (index) {
-                case 0:return 2 + ((long)nmemmap.b0size + nmemmap.b0dou);
-                case 1:return 2 + ((long)nmemmap.b1size + nmemmap.b1dou);
-                case 2:return 2 + ((long)nmemmap.b2size + nmemmap.b2dou);
-                case 3:return 2 + ((long)nmemmap.b3size + nmemmap.b3dou);
+                case 0:
+			bsize = nmemmap.b0size;
+			bdou = nmemmap.b0dou;
+			hack = nmemmap.hack0;
+			break;
+                case 1:
+			bsize = nmemmap.b1size;
+			bdou = nmemmap.b1dou;
+			hack = nmemmap.hack1;
+			break;
+                case 2:
+			bsize = nmemmap.b2size;
+			bdou = nmemmap.b2dou;
+			hack = nmemmap.hack2;
+			break;
+                case 3:
+			bsize = nmemmap.b3size;
+			bdou = nmemmap.b3dou;
+			hack = nmemmap.hack3;
+			break;
                 default:return -1 ;
         }
+
+	if (bsize < 6 && hack == 0)
+		return (1UL<<((2+bsize+bdou)+SN2_BANK_SIZE_SHIFT))*31/32;
+	else 
+		return (16*MB)*hack;
 }
 
 #endif
@@ -141,6 +216,99 @@
         md->attribute = attr;
 }
 
+
+//#define FAKE_MEMMAP 1
+#ifdef FAKE_MEMMAP
+
+#define OFF 0x3000000000UL
+struct {
+	unsigned long	type;
+	unsigned long	attr;
+	unsigned long	start;
+	unsigned long	end;
+} mdx[] = {
+	/* PASTE SRAT HERE */
+};
+
+struct srat {
+	unsigned long	start;
+	unsigned long	len;
+	unsigned long	type;
+	unsigned long	pxm;
+} srat[] = {
+
+	/* PASTE SRAT HERE */
+
+};
+
+
+
+void *
+build_memory_srat(struct acpi_table_memory_affinity *ptr)
+{
+	int i;
+	int n = sizeof(srat)/sizeof(struct srat);
+
+        for (i=0; i<n; i++)
+		srat[i].start += OFF;
+        for (i=0; i<n; i++) {
+                ptr->header.type = ACPI_SRAT_MEMORY_AFFINITY;
+                ptr->header.length = sizeof(struct acpi_table_memory_affinity);
+                ptr->proximity_domain = srat[i].pxm;
+                ptr->base_addr_lo = srat[i].start & 0xffffffff;
+                ptr->length_lo = srat[i].len & 0xffffffff;
+                ptr->base_addr_hi = srat[i].start >> 32;
+                ptr->length_hi = srat[i].len >> 32;
+                ptr->memory_type = ACPI_ADDRESS_RANGE_MEMORY;
+                ptr->flags.enabled = 1;
+		ptr++;
+        }
+	return ptr;
+}
+
+int
+build_efi_memmap(void *md, int mdsize)
+{
+	int		i;
+
+	for (i=0; i<sizeof(mdx)/32; i++) {
+		mdx[i].start += OFF;
+		mdx[i].end += OFF;
+	}
+	for (i=0; i<sizeof(mdx)/32; i++) {
+			build_mem_desc(md, mdx[i].type, mdx[i].start, mdx[i].end-mdx[i].start, mdx[i].attr);
+			md += mdsize;
+	}
+	return i;
+
+}
+
+#else /* ! FAKE_MEMMAP */
+
+void *
+build_memory_srat(struct acpi_table_memory_affinity *ptr)
+{
+	int	cnode, nasid;
+
+	for (cnode=0; cnode<GetNumNodes(); cnode++) {
+		nasid = GetNasid(cnode);
+		ptr->header.type = ACPI_SRAT_MEMORY_AFFINITY;
+		ptr->header.length = sizeof(struct acpi_table_memory_affinity);
+		ptr->proximity_domain = PROXIMITY_DOMAIN(nasid);
+		ptr->base_addr_lo = 0;
+		ptr->length_lo = 0;
+#if defined(SGI_SN2)
+		ptr->base_addr_hi = (nasid<<6) | (3<<4);
+		ptr->length_hi = (MD_BANKSIZE*MD_BANKS_PER_NODE)>>32;
+#endif
+		ptr->memory_type = ACPI_ADDRESS_RANGE_MEMORY;
+		ptr->flags.enabled = 1;
+		ptr++;
+	}
+	return ptr;
+}
+
+
 int
 build_efi_memmap(void *md, int mdsize)
 {
@@ -148,7 +316,6 @@
 	int		cnode,bank ;
 	int		nasid ;
 	node_memmap_t	membank_info ;
-	int		bsize;
 	int		count = 0 ;
 	long		paddr, hole, numbytes;
 
@@ -157,18 +324,9 @@
 		nasid = GetNasid(cnode) ;
 		membank_info = GetMemBankInfo(cnode) ;
 		for (bank=0;bank<MD_BANKS_PER_NODE;bank++) {
-			if (IsBankPresent(bank, membank_info)) {
-				bsize = GetBankSize(bank, membank_info) ;
+			numbytes = GetBankSize(bank, membank_info);
+			if (numbytes) {
                                 paddr = PHYS_ADDRESS(nasid, (long)bank<<MD_BANK_SHFT);
-                                numbytes = BankSizeBytes(bsize);
-#ifdef SGI_SN2
-				/* 
-				 * Ignore directory.
-				 * Shorten memory chunk by 1 page - makes a better
-				 * testcase & is more like the real PROM.
-				 */
-				numbytes = numbytes * 31 / 32;
-#endif
 				/*
 				 * Only emulate the memory prom grabs
 				 * if we have lots of memory, to allow
@@ -242,6 +400,7 @@
 	}
 	return count ;
 }
+#endif /* FAKE_MEMMAP */
 
 void
 build_init(unsigned long args)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/fakeprom/fpmem.h linux-2.4.23-pre8/arch/ia64/sn/fakeprom/fpmem.h
--- linux-2.4.22/arch/ia64/sn/fakeprom/fpmem.h	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/fakeprom/fpmem.h	2003-10-22 22:49:01.000000000 +0000
@@ -29,29 +29,35 @@
 {
         unsigned int    b0size  :3,     /* 0-2   bank 0 size */
                         b0dou   :1,     /* 3     bank 0 is 2-sided */
-                        ena0    :1,     /* 4     bank 0 enabled */
-                        r0      :3,     /* 5-7   reserved */
+                        hack0   :4,     /* 4-7   bank 0 hack */
         		b1size  :3,     /* 8-10  bank 1 size */
                         b1dou   :1,     /* 11    bank 1 is 2-sided */
-                        ena1    :1,     /* 12    bank 1 enabled */
-                        r1      :3,     /* 13-15 reserved */
+                        hack1   :4,     /* 12-15 bank 1 hack */
         		b2size  :3,     /* 16-18 bank 2 size */
                         b2dou   :1,     /* 19    bank 1 is 2-sided */
-                        ena2    :1,     /* 20    bank 2 enabled */
-                        r2      :3,     /* 21-23 reserved */
+                        hack2   :4,     /* 20-23 bank 2 hack */
         		b3size  :3,     /* 24-26 bank 3 size */
                         b3dou   :1,     /* 27    bank 3 is 2-sided */
-                        ena3    :1,     /* 28    bank 3 enabled */
-                        r3      :3;     /* 29-31 reserved */
+                        hack3   :4;     /* 28-31 bank 3 hack */
 } node_memmap_t ;
 
+#define PROXIMITY_DOMAIN(nasid) (((nasid)>>1) & 255)
 #define SN2_BANK_SIZE_SHIFT		(MBSHIFT+6)     /* 64 MB */
-#define BankPresent(bsize)		(bsize<6)
-#define BankSizeBytes(bsize)            (BankPresent(bsize) ? 1UL<<((bsize)+SN2_BANK_SIZE_SHIFT) : 0)
 #define MD_BANKS_PER_NODE 4
 #define MD_BANKSIZE			(1UL << 34)
+
+#define MAX_SN_NODES            256
+#define MAX_LSAPICS             512
+#define MAX_CPUS_NODE           4
+#define MAX_CPUS                (MAX_CPUS_NODE*MAX_SN_NODES)
+#define CPUS_PER_FSB            2
+#define CPUS_PER_FSB_MASK       (CPUS_PER_FSB-1)
+#define MAX_NASID               2048
+
 #endif
 
+#define FPROM_BUG()             do {while (1);} while (0)
+
 typedef struct sn_memmap_s
 {
 	short		nasid ;
@@ -66,7 +72,9 @@
 	sn_memmap_t	memmap[1];		/* start of array */
 } sn_config_t;
 
+struct acpi_table_memory_affinity;
 
+extern long base_nasid;
 
 extern void build_init(unsigned long);
 extern int build_efi_memmap(void *, int);
@@ -74,3 +82,5 @@
 extern int GetNumCpus(void);
 extern int IsCpuPresent(int, int);
 extern int GetNasid(int);
+extern void* build_memory_srat(struct acpi_table_memory_affinity *);
+extern void GetLogicalCpu(int, int *, int *);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/fakeprom/fpromasm.S linux-2.4.23-pre8/arch/ia64/sn/fakeprom/fpromasm.S
--- linux-2.4.22/arch/ia64/sn/fakeprom/fpromasm.S	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/fakeprom/fpromasm.S	2003-10-22 22:48:15.000000000 +0000
@@ -253,9 +253,10 @@
 //	Note: should verify that the interrupt we got was really the ap_wakeup
 //	      interrupt but this should not be an issue on medusa
 slave:
-	nop.i		0x8beef				// Medusa - put cpu to sleep til interrupt occurs
 	mov		r8=cr.irr0;;			// Check for interrupt pending.
 	cmp.eq		p6,p0=r8,r0
+	;;
+(p6)	nop.i		0x8beef				// Medusa - put cpu to sleep til interrupt occurs
 (p6)	br.cond.sptk	slave;;
 
 	mov		r8=cr.ivr;;			// Got one. Must read ivr to accept it
@@ -361,6 +362,13 @@
 	st8	[r3]=r2
 	;;
 
+1:	cmp.eq	p6,p7=34,r28		/* PAL_VM_PAGE_SIZE */
+(p7)	br.cond.sptk.few 1f
+	movl	r8=0				/* status = 0 */
+	movl	r9=0x015557000			/* insertable page sizes */
+	movl	r10=0x115557000			/* purgeable page sizes */
+	movl	r11=0
+
 1:	cmp.eq	p6,p7=19,r28		/* PAL_RSE_INFO */
 (p7)	br.cond.sptk.few 1f
 	movl	r8=0				/* status = 0 */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/fakeprom/fw-emu.c linux-2.4.23-pre8/arch/ia64/sn/fakeprom/fw-emu.c
--- linux-2.4.22/arch/ia64/sn/fakeprom/fw-emu.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/fakeprom/fw-emu.c	2003-10-22 22:49:15.000000000 +0000
@@ -47,6 +47,8 @@
 #include <asm/sn/sn2/shub_mmr.h>
 #endif
 #include <linux/acpi.h>
+#include <acpi/acpi.h>
+#include <acpi/actbl.h>
 #include "fpmem.h"
 
 #define RSDP_NAME               "RSDP"
@@ -66,11 +68,12 @@
 #define BOOT_SIG                "BOOT"      /* Boot table */
 #define ACPI_SRAT_REVISION 1
 #define ACPI_SLIT_REVISION 1
+#define ACPI_FADT_REVISION 3
+#define ACPI_DSDT_REVISION 1
 
 #define OEMID			"SGI"
 #ifdef SGI_SN2
 #define PRODUCT			"SN2"
-#define PROXIMITY_DOMAIN(nasid)	(((nasid)>>1) & 255)
 #endif
 
 #define MB	(1024*1024UL)
@@ -81,15 +84,6 @@
 #define ABS(i)			((i) > 0   ? (i) : -(i))
 #define ALIGN8(p)		(((long)(p) +7) & ~7)
 
-#define FPROM_BUG()		do {while (1);} while (0)
-#define MAX_SN_NODES		128
-#define MAX_LSAPICS		512
-#define MAX_CPUS		512
-#define MAX_CPUS_NODE		4
-#define CPUS_PER_NODE		4
-#define CPUS_PER_FSB		2
-#define CPUS_PER_FSB_MASK	(CPUS_PER_FSB-1)
-
 #define NUM_EFI_DESCS		2
 
 #define RSDP_CHECKSUM_LENGTH	20
@@ -126,11 +120,10 @@
  */
 long		base_nasid;
 long		num_cpus;
-long		bsp_entry_pc=0;
+long		bsp_entry_pc;
 long		num_nodes;
-long		app_entry_pc;
-int		bsp_lid;
 func_ptr_t	ap_entry;
+char		nasid_present[MAX_NASID];
 
 
 extern void pal_emulator(void);
@@ -141,8 +134,11 @@
 		    + sizeof(struct ia64_sal_systab)
 		    + sizeof(struct ia64_sal_desc_entry_point)
 		    + sizeof(struct ia64_sal_desc_ap_wakeup)
+		    + sizeof(struct ia64_sal_desc_platform_feature)
 		    + sizeof(struct acpi20_table_rsdp)
 		    + sizeof(struct acpi_table_xsdt)
+		    + sizeof(struct acpi_table_header) /* dummy DSDT */
+		    + sizeof(struct fadt_descriptor_rev2)
 		    + sizeof(struct acpi_table_slit)
 		    +   MAX_SN_NODES*MAX_SN_NODES+8
 		    + sizeof(struct acpi_table_madt)
@@ -242,7 +238,11 @@
 	if (index == SAL_FREQ_BASE) {
 		switch (in1) {
 		      case SAL_FREQ_BASE_PLATFORM:
-			r9 = 500000000;
+			     /* slow down the clock on large systems to reduce the interrupt rate */
+			if (num_cpus < 32)
+				r9 = 500000000UL;
+			else
+				r9 = 5000000000UL;
 			break;
 
 		      case SAL_FREQ_BASE_INTERVAL_TIMER:
@@ -446,7 +446,7 @@
 }
 
 int
-nasid_present(int nasid)
+is_nasid_present(int nasid)
 {
 	int	cnode;
 	for (cnode=0; cnode<num_nodes; cnode++)
@@ -456,7 +456,7 @@
 }
 
 void
-sys_fw_init (const char *args, int arglen, int bsp)
+sys_fw_init (const char *args, int arglen)
 {
 	/*
 	 * Use static variables to keep from overflowing the RSE stack
@@ -472,33 +472,30 @@
 	static struct acpi_table_slit *acpi_slit;
 	static struct acpi_table_madt *acpi_madt;
 	static struct acpi_table_lsapic *lsapic20;
+	static struct acpi_table_header *acpi_dsdt;
+	static struct fadt_descriptor_rev2 *acpi_fadt;
 	static struct ia64_sal_systab *sal_systab;
 	static struct acpi_table_srat *acpi_srat;
 	static struct acpi_table_processor_affinity *srat_cpu_affinity;
-	static struct acpi_table_memory_affinity *srat_memory_affinity;
 	static efi_memory_desc_t *efi_memmap, *md;
 	static unsigned long *pal_desc, *sal_desc;
 	static struct ia64_sal_desc_entry_point *sal_ed;
 	static struct ia64_boot_param *bp;
 	static struct ia64_sal_desc_ap_wakeup *sal_apwake;
+	static struct ia64_sal_desc_platform_feature *sal_feature;
 	static unsigned char checksum;
 	static char *cp, *cmd_line, *vendor;
 	static void *ptr;
 	static int mdsize, domain, last_domain ;
 	static int i, j, cnode, max_nasid, nasid, cpu, num_memmd, cpus_found;
 
-	/*
-	 * Pass the parameter base address to the build_efi_xxx routines.
-	 */
-#if defined(SGI_SN2)
-	build_init(0x3000000000UL | ((long)base_nasid<<38));
-#endif
-
 	num_nodes = GetNumNodes();
 	num_cpus = GetNumCpus();
 	for (max_nasid=0, cnode=0; cnode<num_nodes; cnode++)
 		max_nasid = MAX(max_nasid, GetNasid(cnode));
 
+	//max_nasid = 0;
+	//num_nodes = 1;
 
 	memset(fw_mem, 0, sizeof(fw_mem));
 
@@ -518,10 +515,13 @@
 	sal_ed      = (void *) cp; cp += ALIGN8(sizeof(*sal_ed));
 	sal_ptc     = (void *) cp; cp += ALIGN8(sizeof(*sal_ptc));
 	sal_apwake  = (void *) cp; cp += ALIGN8(sizeof(*sal_apwake));
+	sal_feature = (void *) cp; cp += ALIGN8(sizeof(*sal_feature));
 	acpi20_rsdp = (void *) cp; cp += ALIGN8(sizeof(*acpi20_rsdp));
-	acpi_xsdt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_xsdt) + 64); 
+	acpi_xsdt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_xsdt) + 64);
 			/* save space for more OS defined table pointers. */
 
+	acpi_dsdt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_dsdt));
+	acpi_fadt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_fadt));
 	acpi_slit   = (void *) cp; cp += ALIGN8(sizeof(*acpi_slit) + 8 + (max_nasid+1)*(max_nasid+1));
 	acpi_madt   = (void *) cp; cp += ALIGN8(sizeof(*acpi_madt) + sizeof(struct acpi_table_lsapic) * (num_cpus+1));
 	acpi_srat   = (void *) cp; cp += ALIGN8(sizeof(struct acpi_table_srat));
@@ -546,7 +546,7 @@
 	 * You can also edit this line to pass other arguments to the kernel.
 	 *    Note: disable kernel text replication.
 	 */
-	strcpy(cmd_line, "init=/bin/bash ktreplicate=0");
+	strcpy(cmd_line, "init=/bin/bash console=ttyS0");
 
 	memset(efi_systab, 0, sizeof(efi_systab));
 	efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
@@ -598,7 +598,9 @@
 	acpi_xsdt->entry[0] = __fwtab_pa(base_nasid, acpi_madt);
 	acpi_xsdt->entry[1] = __fwtab_pa(base_nasid, acpi_slit);
 	acpi_xsdt->entry[2] = __fwtab_pa(base_nasid, acpi_srat);
-	acpi_checksum(&acpi_xsdt->header, sizeof(struct acpi_table_xsdt) + 16);
+	acpi_xsdt->entry[3] = __fwtab_pa(base_nasid, acpi_fadt);
+	acpi_xsdt->entry[4] = __fwtab_pa(base_nasid, acpi_dsdt);
+	acpi_checksum(&acpi_xsdt->header, sizeof(struct acpi_table_xsdt) + 32);
 
 	/* Set up the APIC table */
 	acpi_table_initx(&acpi_madt->header, APIC_SIG, 4, 1, 1);
@@ -614,7 +616,7 @@
 			lsapic20->flags.enabled = 1;
 #if defined(SGI_SN2)
 			lsapic20->eid = nasid&0xffff;
-			lsapic20->id = (cpu<<4) | (nasid>>16);
+			lsapic20->id = (cpu<<4) | (nasid>>8);
 #endif
 			lsapic20 = (struct acpi_table_lsapic*) ((long)lsapic20+sizeof(struct acpi_table_lsapic));
 		}
@@ -624,23 +626,10 @@
 	/* Set up the SRAT table */
 	acpi_table_initx(&acpi_srat->header, SRAT_SIG, 4, ACPI_SRAT_REVISION, 1);
 	ptr = acpi_srat+1;
-	for (cnode=0; cnode<num_nodes; cnode++) {
-		nasid = GetNasid(cnode);
-		srat_memory_affinity = ptr;
-		ptr = srat_memory_affinity+1;
-		srat_memory_affinity->header.type = ACPI_SRAT_MEMORY_AFFINITY;
-		srat_memory_affinity->header.length = sizeof(struct acpi_table_memory_affinity);
-		srat_memory_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
-		srat_memory_affinity->base_addr_lo = 0;
-		srat_memory_affinity->length_lo = 0;
-#if defined(SGI_SN2)
-		srat_memory_affinity->base_addr_hi = (nasid<<6) | (3<<4);
-		srat_memory_affinity->length_hi = (MD_BANKSIZE*MD_BANKS_PER_NODE)>>32;
-#endif
-		srat_memory_affinity->memory_type = ACPI_ADDRESS_RANGE_MEMORY;
-		srat_memory_affinity->flags.enabled = 1;
-	}
 
+	ptr = build_memory_srat(ptr);
+
+	/* Build processor SRAT */
 	for (cnode=0; cnode<num_nodes; cnode++) {
 		nasid = GetNasid(cnode);
 		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
@@ -654,12 +643,24 @@
 			srat_cpu_affinity->flags.enabled = 1;
 #if defined(SGI_SN2)
 			srat_cpu_affinity->lsapic_eid = nasid&0xffff;
-			srat_cpu_affinity->apic_id = (cpu<<4) | (nasid>>16);
+			srat_cpu_affinity->apic_id = (cpu<<4) | (nasid>>8);
 #endif
 		}
 	}
 	acpi_checksum(&acpi_srat->header, (char*)ptr - (char*)acpi_srat);
 
+	acpi_table_initx(acpi_dsdt, DSDT_SIG, 4, ACPI_DSDT_REVISION, 1);
+	acpi_checksum(acpi_dsdt, sizeof(*acpi_dsdt));
+
+	/* Set up the FADT table */
+	acpi_table_initx((struct acpi_table_header *)&acpi_fadt->header, FADT_SIG, 4, ACPI_FADT_REVISION, 1);
+	/*
+	 * We don't have legacy PC keyboard support etc.
+	 */
+	acpi_fadt->iapc_boot_arch = 0;
+	acpi_fadt->Xdsdt = (u64)__fwtab_pa(base_nasid, acpi_dsdt);
+	acpi_checksum((struct acpi_table_header *)&acpi_fadt->header,
+		      sizeof(*acpi_fadt));
 
 	/* Set up the SLIT table */
 	acpi_table_initx(&acpi_slit->header, SLIT_SIG, 4, ACPI_SLIT_REVISION, 1);
@@ -668,8 +669,10 @@
 	memset(cp, 255, acpi_slit->localities*acpi_slit->localities);
 
 	for (i=0; i<=max_nasid; i++)
+		nasid_present[i] = is_nasid_present(i);
+	for (i=0; i<=max_nasid; i++)
 		for (j=0; j<=max_nasid; j++)
-			if (nasid_present(i) && nasid_present(j))
+			if (nasid_present[i] && nasid_present[j])
 				*(cp+PROXIMITY_DOMAIN(i)*acpi_slit->localities+PROXIMITY_DOMAIN(j)) = 10 + MIN(254, 5*ABS(i-j));
 
 	cp = acpi_slit->entry + acpi_slit->localities*acpi_slit->localities;
@@ -681,7 +684,7 @@
 	sal_systab->size = sizeof(*sal_systab);
 	sal_systab->sal_rev_minor = 1;
 	sal_systab->sal_rev_major = 0;
-	sal_systab->entry_count = 3;
+	sal_systab->entry_count = 4;
 	sal_systab->sal_b_rev_major = 0x1; /* set the SN SAL rev to */
 	sal_systab->sal_b_rev_minor = 0x0; /* 1.00 */
 
@@ -730,6 +733,10 @@
 	sal_apwake->mechanism = IA64_SAL_AP_EXTERNAL_INT;
 	sal_apwake->vector = 18;
 
+	/* Setup the SAL feature descriptor */
+	sal_feature->type = SAL_DESC_PLATFORM_FEATURE;
+	sal_feature->feature_mask = IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT;
+
 	for (checksum=0, cp=(char*)sal_systab; cp < (char *)efi_memmap; ++cp)
 		checksum += *cp;
 	sal_systab->checksum = -checksum;
@@ -754,22 +761,4 @@
 	bp->console_info.orig_x = 0;
 	bp->console_info.orig_y = 24;
 	bp->fpswa = 0;
-
-	/*
-	 * Now pick the BSP & store it LID value in
-	 * a global variable. Note if BSP is greater than last cpu,
-	 * pick the last cpu.
-	 */
-	for (cnode=0; cnode<num_nodes; cnode++) {
-		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
-			if (!IsCpuPresent(cnode, cpu))
-				continue;
-#ifdef SGI_SN2
-			bsp_lid = (GetNasid(cnode)<<16) | (cpu<<28);
-#endif
-			if (bsp-- > 0)
-				continue;
-			return;
-		}
-	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/fakeprom/main.c linux-2.4.23-pre8/arch/ia64/sn/fakeprom/main.c
--- linux-2.4.22/arch/ia64/sn/fakeprom/main.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/fakeprom/main.c	2003-10-22 22:48:59.000000000 +0000
@@ -12,90 +12,60 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <asm/bitops.h>
+#include <asm/sn/simulator.h>
+#include "fpmem.h"
 
 extern void klgraph_init(void);
-void bedrock_init(int);
-void synergy_init(int, int);
-void sys_fw_init (const char *args, int arglen, int bsp);
-
-volatile int	bootmaster=0;		/* Used to pick bootmaster */
-volatile int	nasidmaster[128]={0};	/* Used to pick node/synergy masters */
-int		init_done=0;
-extern int	bsp_lid;
-
-#define get_bit(b,p)	(((*p)>>(b))&1)
+void sys_fw_init (const char *args, int arglen);
 
 int
 fmain(int lid, int bsp) {
-	int	syn, nasid, cpu;
+	int	nasid, cpu, mynasid, mycpu, bootmaster;
+
+	/*
+	 * * Pass the parameter base address to the build_efi_xxx routines.
+	 */
+#if defined(SGI_SN2)
+	build_init(0x3000000000UL | ((long)base_nasid<<38));
+#endif
 
 	/*
 	 * First lets figure out who we are. This is done from the
 	 * LID passed to us.
 	 */
-	nasid = (lid>>16)&0xfff;
-	cpu = (lid>>28)&3;
-	syn = 0;
-	
+	mynasid = (lid>>16)&0xfff;
+	mycpu = (lid>>28)&3;
+
 	/*
-	 * Now pick a nasid master to initialize Bedrock registers.
+	 * Determine if THIS cpu is the bootmaster. The <bsp> parameter
+	 * is the logical cpu of the bootmaster. Cpus are numbered
+	 * low-to-high nasid/lid.
 	 */
-	if (test_and_set_bit(8, &nasidmaster[nasid]) == 0) {
-		bedrock_init(nasid);
-		test_and_set_bit(9, &nasidmaster[nasid]);
-	} else
-		while (get_bit(9, &nasidmaster[nasid]) == 0);
+	GetLogicalCpu(bsp, &nasid, &cpu);
+	bootmaster = (mynasid == nasid) && (mycpu == cpu);
 	
-
 	/*
-	 * Now pick a BSP & finish init.
+	 * Initialize SAL & EFI tables.
+	 *   Note: non-bootmaster cpus will return to the slave loop 
+	 *   in fpromasm.S. They spin there until they receive an
+	 *   external interrupt from the master cpu.
 	 */
-	if (test_and_set_bit(0, &bootmaster) == 0) {
-		sys_fw_init(0, 0, bsp);
-		test_and_set_bit(1, &bootmaster);
-	} else
-		while (get_bit(1, &bootmaster) == 0);
-
-	return (lid == bsp_lid);
-}
-
-
-void
-bedrock_init(int nasid)
-{
-	nasid = nasid;		/* to quiet gcc */
+	if (bootmaster) {
 #if 0
-	/*
-	 * Undef if you need fprom to generate a 1 node klgraph
-	 * information .. only works for 1 node for nasid 0.
-	 */
-	klgraph_init();
+		/*
+		 * Undef if you need fprom to generate a 1 node klgraph
+		 * information .. only works for 1 node for nasid 0.
+		 */
+		klgraph_init();
 #endif
-}
-
-
-void
-synergy_init(int nasid, int syn)
-{
-	long	*base;
-	long	off;
+		sys_fw_init(0, 0);
+	}
 
-	/*
-	 * Enable all FSB flashed interrupts.
-	 * I'd really like defines for this......
-	 */
-	base = (long*)0x80000e0000000000LL;		/* base of synergy regs */
-	for (off = 0x2a0; off < 0x2e0; off+=8)		/* offset for VEC_MASK_{0-3}_A/B */
-		*(base+off/8) = -1LL;
-
-	/*
-	 * Set the NASID in the FSB_CONFIG register.
-	 */
-	base = (long*)0x80000e0000000450LL;
-	*base = (long)((nasid<<16)|(syn<<9));
+	return (bootmaster);
 }
 
 
+
 /* Why isnt there a bcopy/memcpy in lib64.a */
 
 void* 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/fakeprom/make_textsym linux-2.4.23-pre8/arch/ia64/sn/fakeprom/make_textsym
--- linux-2.4.22/arch/ia64/sn/fakeprom/make_textsym	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/fakeprom/make_textsym	2003-10-22 22:48:57.000000000 +0000
@@ -0,0 +1,168 @@
+#!/bin/sh
+#
+# Build a textsym file for use in the Arium ITP probe.
+#
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
+#
+
+help() {
+cat <<END
+Build a WinDD "symtxt" file for use with the Arium ECM-30 probe.
+
+	Usage: $0 [<vmlinux file> [<output file>]]
+		If no input file is specified, it defaults to vmlinux.
+		If no output file name is specified, it defaults to "textsym".
+END
+exit 1
+}
+
+err () {
+	echo "ERROR - $*" >&2
+	exit 1
+}
+
+
+OPTS="H"
+while getopts "$OPTS" c ; do
+	case $c in
+		H)  help;;
+		\?) help;;
+	esac
+
+done
+shift `expr $OPTIND - 1`
+
+if [ -f /usr/bin/ia64-linux-objdump ] ; then
+	OBJDUMP=${OBJDUMP:-/usr/bin/ia64-linux-objdump}
+else
+	OBJDUMP=${OBJDUMP:-objdump}
+fi
+
+LINUX=${1:-vmlinux}
+TEXTSYM=${2:-${LINUX}.sym}
+TMPSYM=${2:-${LINUX}.sym.tmp}
+trap "/bin/rm -f $TMPSYM" 0
+
+[ -f $VMLINUX ] || help
+
+$OBJDUMP -t $LINUX | egrep -v '__ks' | sort > $TMPSYM
+
+# pipe everything thru sort
+echo "TEXTSYM V1.0" >$TEXTSYM
+(cat <<END 
+GLOBAL | e000000004400000 | CODE | VEC_VHPT_Translation_0000
+GLOBAL | e000000004400400 | CODE | VEC_ITLB_0400
+GLOBAL | e000000004400800 | CODE | VEC_DTLB_0800
+GLOBAL | e000000004400c00 | CODE | VEC_Alt_ITLB_0c00
+GLOBAL | e000000004401000 | CODE | VEC_Alt_DTLB_1000
+GLOBAL | e000000004401400 | CODE | VEC_Data_nested_TLB_1400
+GLOBAL | e000000004401800 | CODE | VEC_Instruction_Key_Miss_1800
+GLOBAL | e000000004401c00 | CODE | VEC_Data_Key_Miss_1c00
+GLOBAL | e000000004402000 | CODE | VEC_Dirty-bit_2000
+GLOBAL | e000000004402400 | CODE | VEC_Instruction_Access-bit_2400
+GLOBAL | e000000004402800 | CODE | VEC_Data_Access-bit_2800
+GLOBAL | e000000004402c00 | CODE | VEC_Break_instruction_2c00
+GLOBAL | e000000004403000 | CODE | VEC_External_Interrupt_3000
+GLOBAL | e000000004403400 | CODE | VEC_Reserved_3400
+GLOBAL | e000000004403800 | CODE | VEC_Reserved_3800
+GLOBAL | e000000004403c00 | CODE | VEC_Reserved_3c00
+GLOBAL | e000000004404000 | CODE | VEC_Reserved_4000
+GLOBAL | e000000004404400 | CODE | VEC_Reserved_4400
+GLOBAL | e000000004404800 | CODE | VEC_Reserved_4800
+GLOBAL | e000000004404c00 | CODE | VEC_Reserved_4c00
+GLOBAL | e000000004405000 | CODE | VEC_Page_Not_Present_5000
+GLOBAL | e000000004405100 | CODE | VEC_Key_Permission_5100
+GLOBAL | e000000004405200 | CODE | VEC_Instruction_Access_Rights_5200
+GLOBAL | e000000004405300 | CODE | VEC_Data_Access_Rights_5300
+GLOBAL | e000000004405400 | CODE | VEC_General_Exception_5400
+GLOBAL | e000000004405500 | CODE | VEC_Disabled_FP-Register_5500
+GLOBAL | e000000004405600 | CODE | VEC_Nat_Consumption_5600
+GLOBAL | e000000004405700 | CODE | VEC_Speculation_5700
+GLOBAL | e000000004405800 | CODE | VEC_Reserved_5800
+GLOBAL | e000000004405900 | CODE | VEC_Debug_5900
+GLOBAL | e000000004405a00 | CODE | VEC_Unaligned_Reference_5a00
+GLOBAL | e000000004405b00 | CODE | VEC_Unsupported_Data_Reference_5b00
+GLOBAL | e000000004405c00 | CODE | VEC_Floating-Point_Fault_5c00
+GLOBAL | e000000004405d00 | CODE | VEC_Floating_Point_Trap_5d00
+GLOBAL | e000000004405e00 | CODE | VEC_Lower_Privilege_Tranfer_Trap_5e00
+GLOBAL | e000000004405f00 | CODE | VEC_Taken_Branch_Trap_5f00
+GLOBAL | e000000004406000 | CODE | VEC_Single_Step_Trap_6000
+GLOBAL | e000000004406100 | CODE | VEC_Reserved_6100
+GLOBAL | e000000004406200 | CODE | VEC_Reserved_6200
+GLOBAL | e000000004406300 | CODE | VEC_Reserved_6300
+GLOBAL | e000000004406400 | CODE | VEC_Reserved_6400
+GLOBAL | e000000004406500 | CODE | VEC_Reserved_6500
+GLOBAL | e000000004406600 | CODE | VEC_Reserved_6600
+GLOBAL | e000000004406700 | CODE | VEC_Reserved_6700
+GLOBAL | e000000004406800 | CODE | VEC_Reserved_6800
+GLOBAL | e000000004406900 | CODE | VEC_IA-32_Exeception_6900
+GLOBAL | e000000004406a00 | CODE | VEC_IA-32_Intercept_6a00
+GLOBAL | e000000004406b00 | CODE | VEC_IA-32_Interrupt_6b00
+GLOBAL | e000000004406c00 | CODE | VEC_Reserved_6c00
+GLOBAL | e000000004406d00 | CODE | VEC_Reserved_6d00
+GLOBAL | e000000004406e00 | CODE | VEC_Reserved_6e00
+GLOBAL | e000000004406f00 | CODE | VEC_Reserved_6f00
+GLOBAL | e000000004407000 | CODE | VEC_Reserved_7000
+GLOBAL | e000000004407100 | CODE | VEC_Reserved_7100
+GLOBAL | e000000004407200 | CODE | VEC_Reserved_7200
+GLOBAL | e000000004407300 | CODE | VEC_Reserved_7300
+GLOBAL | e000000004407400 | CODE | VEC_Reserved_7400
+GLOBAL | e000000004407500 | CODE | VEC_Reserved_7500
+GLOBAL | e000000004407600 | CODE | VEC_Reserved_7600
+GLOBAL | e000000004407700 | CODE | VEC_Reserved_7700
+GLOBAL | e000000004407800 | CODE | VEC_Reserved_7800
+GLOBAL | e000000004407900 | CODE | VEC_Reserved_7900
+GLOBAL | e000000004407a00 | CODE | VEC_Reserved_7a00
+GLOBAL | e000000004407b00 | CODE | VEC_Reserved_7b00
+GLOBAL | e000000004407c00 | CODE | VEC_Reserved_7c00
+GLOBAL | e000000004407d00 | CODE | VEC_Reserved_7d00
+GLOBAL | e000000004407e00 | CODE | VEC_Reserved_7e00
+GLOBAL | e000000004407f00 | CODE | VEC_Reserved_7f00
+END
+
+
+awk '
+/ _start$/ {start=1}
+/ start_ap$/ {start=1}
+/__start_gate_section/ {start=1}
+/^e0000000/ {
+	if ($4 == ".kdb")
+		next
+	if (start && substr($NF,1,1) != "0") {
+		type = substr($0,26,5)
+		if (type == ".text")
+			printf "GLOBAL | %s | CODE | %s\n", $1, $NF
+		else {
+			n = 0
+			s = $(NF-1)
+			while (length(s) > 0) {
+				n = n*16 + (index("0123456789abcdef", substr(s,1,1)) - 1)
+				s = substr(s,2)
+			}
+			printf "GLOBAL | %s | DATA | %s | %d\n", $1, $NF, n
+		}
+	}
+	if($NF == "_end") 
+		exit
+
+}
+' $TMPSYM ) | egrep -v " __device| __vendor" | awk '
+/GLOBAL/ {
+	print $0
+	/* 38 bits of sn2 physical addrs, need addr space bits */
+	if (substr($0,19,1) == "4")
+		print substr($0,1,9) "3004" substr($0,20,16) "Phy_" substr($0,36)
+	else
+		print substr($0,1,9) "3005" substr($0,20,16) "Phy_" substr($0,36)
+
+} ' | sort -k3 >>$TEXTSYM
+
+N=`wc -l $TEXTSYM|awk '{print $1}'`
+echo "Generated TEXTSYM file" >&2
+echo "  $LINUX --> $TEXTSYM" >&2
+echo "  Found $N symbols" >&2
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/Makefile linux-2.4.23-pre8/arch/ia64/sn/io/Makefile
--- linux-2.4.22/arch/ia64/sn/io/Makefile	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/Makefile	2003-10-22 22:48:14.000000000 +0000
@@ -13,8 +13,9 @@
 
 O_TARGET := sgiio.o
  
-obj-y :=	sgi_if.o xswitch.o sgi_io_sim.o \
-		cdl.o io.o
+export-objs := snia_if.o
+
+obj-y :=	sgi_if.o xswitch.o cdl.o io.o snia_if.o
 
 obj-y		+= sn2/snio.o machvec/snio.o \
 	           drivers/snio.o platform_init/snio.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/drivers/Makefile linux-2.4.23-pre8/arch/ia64/sn/io/drivers/Makefile
--- linux-2.4.22/arch/ia64/sn/io/drivers/Makefile	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/drivers/Makefile	2003-10-22 22:48:53.000000000 +0000
@@ -11,7 +11,7 @@
 
 O_TARGET := snio.o
 
-obj-y				+= hubdev.o ioconfig_bus.o ifconfig_net.o
+obj-y				+= ioconfig_bus.o ifconfig_net.o
 
 obj-$(CONFIG_PCIBA)		+= pciba.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/drivers/ifconfig_net.c linux-2.4.23-pre8/arch/ia64/sn/io/drivers/ifconfig_net.c
--- linux-2.4.22/arch/ia64/sn/io/drivers/ifconfig_net.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/drivers/ifconfig_net.c	2003-10-22 22:47:29.000000000 +0000
@@ -22,6 +22,7 @@
 #include <linux/skbuff.h>
 
 #include <asm/sn/sgi.h>
+#include <asm/uaccess.h>
 #include <linux/devfs_fs.h>
 #include <linux/devfs_fs_kernel.h>
 #include <asm/io.h>
@@ -37,8 +38,11 @@
 /*
  * Some Global definitions.
  */
-static devfs_handle_t ifconfig_net_handle;
+static vertex_hdl_t ifconfig_net_handle;
 static unsigned long ifconfig_net_debug;
+static struct ifname_MAC *new_devices;
+static struct ifname_num *ifname_num;
+
 
 /*
  * ifconfig_net_open - Opens the special device node "/devhw/.ifconfig_net".
@@ -189,8 +193,7 @@
 	char temp[64];
 #endif
 	struct ifname_MAC *ifname_MAC;
-	struct ifname_MAC *new_devices, *temp_new_devices;
-	struct ifname_num *ifname_num;
+	struct ifname_MAC *temp_new_devices;
 	unsigned long size;
 
 
@@ -204,14 +207,24 @@
 	 */
 	ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num), 
 			GFP_KERNEL);
-	copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num));
+	if (copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num)))
+		return -EFAULT;
 	size = ifname_num->size;
 	kfree(ifname_num);
 	ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL);
+	if (ifname_num <= 0)
+		return -ENOMEM;
 	ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) );
 
-	copy_from_user( ifname_num, (char *) arg, size);
+	if (copy_from_user( ifname_num, (char *) arg, size)){
+		kfree(ifname_num);
+		return -EFAULT;
+	}
 	new_devices =  kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL);
+	if (new_devices <= 0){
+		kfree(ifname_num);
+		return -ENOMEM;
+	}
 	temp_new_devices = new_devices;
 
 	memset(new_devices, 0, size - sizeof(struct ifname_num));
@@ -257,10 +270,10 @@
 	/*
 	 * Copy back to the User Buffer area any new devices encountered.
 	 */
-	copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, 
-			size - sizeof(struct ifname_num));
+	kfree(new_devices);
+	return copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, 
+			size - sizeof(struct ifname_num))?-EFAULT:0;
 
-	return(0);
 
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/drivers/ioconfig_bus.c linux-2.4.23-pre8/arch/ia64/sn/io/drivers/ioconfig_bus.c
--- linux-2.4.22/arch/ia64/sn/io/drivers/ioconfig_bus.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/drivers/ioconfig_bus.c	2003-10-22 22:48:30.000000000 +0000
@@ -17,6 +17,8 @@
 #include <linux/pci.h>
 
 #include <asm/sn/sgi.h>
+#include <asm/uaccess.h>
+
 #include <linux/devfs_fs.h>
 #include <linux/devfs_fs_kernel.h>
 #include <asm/io.h>
@@ -36,6 +38,7 @@
  */
 static vertex_hdl_t ioconfig_bus_handle;
 static unsigned long ioconfig_bus_debug;
+static struct ioconfig_parm parm;
 
 #ifdef IOCONFIG_BUS_DEBUG
 #define DBG(x...)	printk(x)
@@ -162,8 +165,13 @@
 	struct ascii_moduleid *moduleid;
 
 	line = kmalloc(256, GFP_KERNEL);
+	if (line <= 0)
+		BUG(); /* Do not want to continue system boot .. */
 	memset(line, 0,256);
 	name = kmalloc(125, GFP_KERNEL);
+	if (name <= 0){
+		BUG(); /* Do not want to continue system boot .. */
+	}
 	memset(name, 0, 125);
 	moduleid = table;
 	current = file_contents;
@@ -252,6 +260,9 @@
 		ret_stuff.v0, (void *)ioconfig_file, (int)ioconfig_file_size);
 
 	ioconfig_bus_table = kmalloc( 512, GFP_KERNEL );
+	if (ioconfig_bus_table <= 0)
+		BUG(); /* Seriously, we should not be out of memory at init */
+
 	memset(ioconfig_bus_table, 0, 512);
 
 	/*
@@ -264,7 +275,6 @@
 		DBG("ioconfig_bus_init: Kernel Options given.\n");
 		(void) build_moduleid_table((char *)ioconfig_kernopts, ioconfig_bus_table);
 		(void) dump_ioconfig_table();
-		return;
 	}
 
 	if (ioconfig_activated) {
@@ -305,16 +315,20 @@
         unsigned int cmd, unsigned long arg)
 {
 
-	struct ioconfig_parm parm;
-
+	int length;
 	/*
 	 * Copy in the parameters.
 	 */
-	copy_from_user(&parm, (char *)arg, sizeof(struct ioconfig_parm));
+	length = copy_from_user(&parm, (char *)arg, sizeof(struct ioconfig_parm));
+	if (length <= 0)
+		return -EFAULT;
 	parm.number = free_entry - new_entry;
 	parm.ioconfig_activated = ioconfig_activated;
-	copy_to_user((char *)arg, &parm, sizeof(struct ioconfig_parm));
-	copy_to_user((char *)parm.buffer, &ioconfig_bus_table[new_entry], sizeof(struct  ascii_moduleid) * (free_entry - new_entry));
+	if (copy_to_user((char *)arg, &parm, sizeof(struct ioconfig_parm)))
+		return -EFAULT;
+
+	if (copy_to_user((char *)parm.buffer, &ioconfig_bus_table[new_entry], sizeof(struct  ascii_moduleid) * (free_entry - new_entry)))
+		return -EFAULT;
 
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/drivers/pciba.c linux-2.4.23-pre8/arch/ia64/sn/io/drivers/pciba.c
--- linux-2.4.22/arch/ia64/sn/io/drivers/pciba.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/drivers/pciba.c	2003-10-22 22:47:37.000000000 +0000
@@ -341,8 +341,8 @@
 	TRACE();
 	
 	node = kmalloc(sizeof(struct node_data), GFP_KERNEL);
-	if (node == NULL)
-		return NULL;
+	if (node <= 0)
+		return node;
 	list_add(&node->global_node_list, &global_node_list);
 	return node;
 }
@@ -455,7 +455,7 @@
            if present */
 	if (pci_resource_len(dev, PCI_ROM_RESOURCE) != 0) {
 		nd = new_node();
-		if (nd == NULL)
+		if (nd <= 0)
 			return failure;
 		node_devfs_handle = hwgraph_register(device_dir_handle, "rom",
 						   0, DEVFS_FL_NONE, 0, 0,
@@ -478,7 +478,7 @@
            and free DMA buffers, as well as memory map those
            buffers. */
 	nd = new_node();
-	if (nd == NULL)
+	if (nd <= 0)
 		return failure;
 	node_devfs_handle =
 		hwgraph_register(device_dir_handle, "dma", 0, DEVFS_FL_NONE,
@@ -763,7 +763,7 @@
 
 		dma_alloc = (struct dma_allocation *)
 			kmalloc(sizeof(struct dma_allocation), GFP_KERNEL);
-		if (dma_alloc == NULL)
+		if (dma_alloc <= 0)
 			return -ENOMEM;
 
 		dma_alloc->size = (size_t)argv;
@@ -899,7 +899,7 @@
 	/* the __pa macro is intended for region 7 on IA64, so it
 	   doesn't work for region 6 */
   	/* pci_pa = __pa(pci_va); */
-	/* should be replaced by __tpa or equivalent (preferably a
+	/* should be replaced by ia64_tpa or equivalent (preferably a
 	   generic equivalent) */
 	pci_pa = pci_va & ~0xe000000000000000ul;
 	DPRINTF("PCI base at physical address %lx\n", pci_pa);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/hwgdfs/hcl.c linux-2.4.23-pre8/arch/ia64/sn/io/hwgdfs/hcl.c
--- linux-2.4.22/arch/ia64/sn/io/hwgdfs/hcl.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/hwgdfs/hcl.c	2003-10-22 22:48:15.000000000 +0000
@@ -233,6 +233,15 @@
 __setup("hcl=", hcl_setup);
 
 
+int
+hwgraph_generate_path(
+        vertex_hdl_t		de,
+        char                    *path,
+        int                     buflen)
+{
+	return (devfs_generate_path(de, path, buflen));
+}
+
 /*
  * Set device specific "fast information".
  *
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/hwgdfs/hcl_util.c linux-2.4.23-pre8/arch/ia64/sn/io/hwgdfs/hcl_util.c
--- linux-2.4.22/arch/ia64/sn/io/hwgdfs/hcl_util.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/hwgdfs/hcl_util.c	2003-10-22 22:49:04.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: hcl_util.c,v 1.3 2003/04/24 13:59:39 pfg Exp $
+/* $Id: hcl_util.c,v 1.4 2003/07/31 12:24:27 edwardsg Exp $
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/hwgfs/hcl.c linux-2.4.23-pre8/arch/ia64/sn/io/hwgfs/hcl.c
--- linux-2.4.22/arch/ia64/sn/io/hwgfs/hcl.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/hwgfs/hcl.c	2003-10-22 22:49:21.000000000 +0000
@@ -28,16 +28,12 @@
 #include <asm/sn/labelcl.h>
 #include <asm/sn/simulator.h>
 
-#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER"
-#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE"
-#define HCL_TEMP_NAME_LEN 44 
-#define HCL_VERSION "1.0"
-
 #define vertex_hdl_t hwgfs_handle_t
+
 vertex_hdl_t hwgraph_root;
 vertex_hdl_t linux_busnum;
-
 extern void pci_bus_cvlink_init(void);
+unsigned long hwgraph_debug_mask = 0;
 
 /*
  * Debug flag definition.
@@ -157,7 +153,7 @@
 	 */
 	rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
 	if (rv)
-		printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
+		panic("init_hcl: Failed to create hwgraph_root.\n");
 
 	/*
 	 * Create the hcl driver to support inventory entry manipulations.
@@ -235,6 +231,15 @@
 __setup("hcl=", hcl_setup);
 
 
+int
+hwgraph_generate_path(
+        vertex_hdl_t            de,
+        char                    *path,
+        int                     buflen)
+{
+        return (hwgfs_generate_path(de, path, buflen));
+}
+
 /*
  * Set device specific "fast information".
  *
@@ -492,39 +497,6 @@
 	return(0);
 }
 
-#if 0
-/*
- * hwgraph_edge_add - This routines has changed from the original conext.
- * All it does now is to create a symbolic link from "from" to "to".
- */
-/* ARGSUSED */
-int
-hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
-{
-
-	char *path, *link;
-	vertex_hdl_t handle = NULL;
-	int rv, i;
-
-	handle = hwgfs_find_handle(from, name, 0, 0, 0, 1);
-	if (handle) {
-		return(0);
-	}
-
-	path = kmalloc(1024, GFP_KERNEL);
-	memset(path, 0x0, 1024);
-	link = kmalloc(1024, GFP_KERNEL);
-	memset(path, 0x0, 1024);
-	i = hwgfs_generate_path (to, link, 1024);
-	rv = hwgfs_mk_symlink (from, (const char *)name, 
-			       DEVFS_FL_DEFAULT, link,
-			       &handle, NULL);
-	return(0);
-
-
-}
-#endif
-
 int
 hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
 {
@@ -916,6 +888,43 @@
 	return(GRAPH_ILLEGAL_REQUEST);
 }
 
+void
+hwgraph_debug(char *file, char * function, int line, vertex_hdl_t vhdl1, vertex_hdl_t vhdl2, char *format, ...)
+{
+
+	int pos;
+	char *hwpath;
+	va_list ap;
+
+	if ( !hwgraph_debug_mask )
+		return;
+
+	hwpath = kmalloc(MAXDEVNAME, GFP_KERNEL);
+	if (!hwpath)
+		BUG();
+
+	printk("HWGRAPH_DEBUG %s %s %d : ", file, function, line);
+
+	if (vhdl1){
+		memset(hwpath, 0, MAXDEVNAME);
+		pos = hwgfs_generate_path(vhdl1, hwpath, MAXDEVNAME);
+		printk("vhdl1 = %s : ", &hwpath[pos]);
+	}
+
+	if (vhdl2){
+		memset(hwpath, 0, MAXDEVNAME);
+		pos = hwgfs_generate_path(vhdl2, hwpath, MAXDEVNAME);
+		printk("vhdl2 = %s :", &hwpath[pos]);
+	}
+
+	memset(hwpath, 0, MAXDEVNAME);
+        va_start(ap, format);
+        vsnprintf(hwpath, 500, format, ap);
+        va_end(ap);
+	hwpath[MAXDEVNAME -1] = (char)0; /* Just in case. */
+        printk(" %s", hwpath);
+	kfree(hwpath);
+}
 
 EXPORT_SYMBOL(hwgraph_mk_dir);
 EXPORT_SYMBOL(hwgraph_path_add);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/hwgfs/hcl_util.c linux-2.4.23-pre8/arch/ia64/sn/io/hwgfs/hcl_util.c
--- linux-2.4.22/arch/ia64/sn/io/hwgfs/hcl_util.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/hwgfs/hcl_util.c	2003-10-22 22:49:45.000000000 +0000
@@ -22,7 +22,10 @@
 #include <asm/sn/nodepda.h>
 
 static vertex_hdl_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE;
+static vertex_hdl_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE;
 extern vertex_hdl_t hwgraph_root;
+extern int maxcpus;
+
 
 
 /*
@@ -96,9 +99,6 @@
 	}
 }
 
-static vertex_hdl_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE;
-extern int maxcpus;
-
 void
 mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid)
 {
@@ -161,6 +161,7 @@
 		(void)hwgraph_edge_add( hwgraph_all_cnodes,
 					vhdl,
 					cnodeid_buffer);
+		HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, hwgraph_all_cnodes, NULL, "Creating path vhdl1\n"));
 	}
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/hwgfs/interface.c linux-2.4.23-pre8/arch/ia64/sn/io/hwgfs/interface.c
--- linux-2.4.22/arch/ia64/sn/io/hwgfs/interface.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/hwgfs/interface.c	2003-10-22 22:49:14.000000000 +0000
@@ -38,7 +38,7 @@
 		memcpy(buf, *path, len);
 		buf[len] = '\0';
 
-		error = link_path_walk(buf, nd); 
+		error = path_walk(buf, nd); 
 		if (unlikely(error))
 			return error;
 
@@ -84,7 +84,7 @@
 	if (unlikely(error))
 		return error;
 
-	error = link_path_walk(name, &nd);
+	error = path_walk(name, &nd);
 	if (unlikely(error))
 		return error;
 
@@ -275,7 +275,7 @@
 	nd.dentry = dget(base ? base : hwgfs_vfsmount->mnt_sb->s_root);
 	nd.flags = LOOKUP_POSITIVE | (traverse_symlinks ? LOOKUP_FOLLOW : 0);
 
-	error = link_path_walk(name, &nd);
+	error = path_walk(name, &nd);
 	if (likely(!error)) {
 		dentry = nd.dentry;
 		path_release(&nd);		/* stale data from here! */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/io.c linux-2.4.23-pre8/arch/ia64/sn/io/io.c
--- linux-2.4.22/arch/ia64/sn/io/io.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/io.c	2003-10-22 22:48:41.000000000 +0000
@@ -86,7 +86,7 @@
 	}
 	hub_set_piomode(nasid, HUB_PIO_CONVEYOR);
 
-	mutex_spinlock_init(&hubinfo->h_bwlock);
+	spin_lock_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.
@@ -123,7 +123,6 @@
 	int bigwin, free_bw_index;
 	nasid_t nasid;
 	volatile hubreg_t junk;
-	unsigned long s;
 	caddr_t kvaddr;
 #ifdef PIOMAP_UNC_ACC_SPACE
 	uint64_t addr;
@@ -171,7 +170,7 @@
 	 */
 tryagain:
 	free_bw_index = -1;
-	s = mutex_spinlock(&hubinfo->h_bwlock);
+	spin_lock(&hubinfo->h_bwlock);
 	for (bigwin=0; bigwin < HUB_NUM_BIG_WINDOW; bigwin++) {
 		bw_piomap = hubinfo_bwin_piomap_get(hubinfo, bigwin);
 
@@ -191,7 +190,7 @@
 		if ( xtalk_addr == bw_piomap->hpio_xtalk_info.xp_xtalk_addr &&
 		     widget == bw_piomap->hpio_xtalk_info.xp_target) {
 			bw_piomap->hpio_holdcnt++;
-			mutex_spinunlock(&hubinfo->h_bwlock, s);
+			spin_unlock(&hubinfo->h_bwlock);
 			return(bw_piomap);
 		}
 	}
@@ -265,7 +264,7 @@
 		bw_piomap->hpio_flags |= HUB_PIOMAP_IS_VALID;
 
 done:
-	mutex_spinunlock(&hubinfo->h_bwlock, s);
+	spin_unlock(&hubinfo->h_bwlock);
 	return(bw_piomap);
 }
 
@@ -285,7 +284,6 @@
 	vertex_hdl_t hubv;
 	hubinfo_t hubinfo;
 	nasid_t nasid;
-	unsigned long s;
 
 	/* 
 	 * Small windows are permanently mapped to corresponding widgets,
@@ -301,7 +299,7 @@
 	hubinfo_get(hubv, &hubinfo);
 	nasid = hubinfo->h_nasid;
 
-	s = mutex_spinlock(&hubinfo->h_bwlock);
+	spin_lock(&hubinfo->h_bwlock);
 
 	/*
 	 * If this is the last hold on this mapping, free it.
@@ -319,7 +317,7 @@
 		(void)sv_signal(&hubinfo->h_bwwait);
 	}
 
-	mutex_spinunlock(&hubinfo->h_bwlock, s);
+	spin_unlock(&hubinfo->h_bwlock);
 }
 
 /*
@@ -440,7 +438,7 @@
 hub_dmamap_free(hub_dmamap_t hub_dmamap)
 {
 	hub_dmamap->hdma_flags &= ~HUB_DMAMAP_IS_VALID;
-	kern_free(hub_dmamap);
+	kfree(hub_dmamap);
 }
 
 /*
@@ -461,12 +459,9 @@
 	if (dmamap->hdma_flags & HUB_DMAMAP_USED) {
 	    /* If the map is FIXED, re-use is OK. */
 	    if (!(dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
+		char name[MAXDEVNAME];
 		vhdl = dmamap->hdma_xtalk_info.xd_dev;
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		printk(KERN_WARNING  "%v: hub_dmamap_addr re-uses dmamap.\n",vhdl);
-#else
-		printk(KERN_WARNING  "%p: hub_dmamap_addr re-uses dmamap.\n", (void *)vhdl);
-#endif
+		printk(KERN_WARNING  "%s: hub_dmamap_addr re-uses dmamap.\n", vertex_to_name(vhdl, name, MAXDEVNAME));
 	    }
 	} else {
 		dmamap->hdma_flags |= HUB_DMAMAP_USED;
@@ -494,12 +489,9 @@
 	if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) {
 	    /* If the map is FIXED, re-use is OK. */
 	    if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
+		char name[MAXDEVNAME];
 		vhdl = hub_dmamap->hdma_xtalk_info.xd_dev;
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		printk(KERN_WARNING  "%v: hub_dmamap_list re-uses dmamap\n",vhdl);
-#else
-		printk(KERN_WARNING  "%p: hub_dmamap_list re-uses dmamap\n", (void *)vhdl);
-#endif
+		printk(KERN_WARNING  "%s: hub_dmamap_list re-uses dmamap\n", vertex_to_name(vhdl, name, MAXDEVNAME));
 	    }
 	} else {
 		hub_dmamap->hdma_flags |= HUB_DMAMAP_USED;
@@ -523,12 +515,9 @@
 	} else {
 	    /* If the map is FIXED, re-done is OK. */
 	    if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
+		char name[MAXDEVNAME];
 		vhdl = hub_dmamap->hdma_xtalk_info.xd_dev;
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		printk(KERN_WARNING  "%v: hub_dmamap_done already done with dmamap\n",vhdl);
-#else
-		printk(KERN_WARNING  "%p: hub_dmamap_done already done with dmamap\n", (void *)vhdl);
-#endif
+		printk(KERN_WARNING  "%s: hub_dmamap_done already done with dmamap\n", vertex_to_name(vhdl, name, MAXDEVNAME));
 	    }
 	}
 }
@@ -589,6 +578,18 @@
 }
 
 
+int
+hub_dma_enabled(vertex_hdl_t xconn_vhdl)
+{
+	return(0);
+}
+
+int
+hub_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code)
+{
+	return(0);
+}
+
 
 /* CONFIGURATION MANAGEMENT */
 
@@ -807,3 +808,80 @@
 	(xtalk_provider_shutdown_f *)	hub_provider_shutdown,
 };
 
+/*
+ * per_ice_init
+ *
+ *      This code is executed once for each Ice chip.
+ */
+void
+per_ice_init(cnodeid_t cnode)
+{
+
+        /* Initialize error interrupts for this ice. */
+	printk("per_ice_init: We need to init ice here ....!\n");
+        /* ice_error_init(cnode); */
+
+}
+/*
+ * per_hub_init
+ *
+ *	This code is executed once for each Hub chip.
+ */
+void
+per_hub_init(cnodeid_t cnode)
+{
+	nasid_t		nasid;
+	nodepda_t	*npdap;
+	ii_icmr_u_t	ii_icmr;
+	ii_ibcr_u_t	ii_ibcr;
+	ii_ilcsr_u_t	ii_ilcsr;
+
+	nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+	ASSERT(nasid != INVALID_NASID);
+	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
+
+	npdap = NODEPDA(cnode);
+
+	/* Disable the request and reply errors. */
+	REMOTE_HUB_S(nasid, IIO_IWEIM, 0xC000);
+
+	/*
+	 * Set the total number of CRBs that can be used.
+	 */
+	ii_icmr.ii_icmr_regval= 0x0;
+	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xf;
+	if (enable_shub_wars_1_1() ) {
+		// Set bit one of ICMR to prevent II from sending interrupt for II bug.
+		ii_icmr.ii_icmr_regval |= 0x1;
+	}
+	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
+
+	/*
+	 * Set the number of CRBs that both of the BTEs combined
+	 * can use minus 1.
+	 */
+	ii_ibcr.ii_ibcr_regval= 0x0;
+	ii_ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
+	if (ii_ilcsr.ii_ilcsr_fld_s.i_llp_stat & LNK_STAT_WORKING) {
+	    ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
+	} else {
+	    /*
+	     * if the LLP is down, there is no attached I/O, so
+	    * give BTE all the CRBs.
+	    */
+	    ii_ibcr.ii_ibcr_fld_s.i_count = 0x14;
+	}
+	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
+
+	/*
+	 * Set CRB timeout to be 10ms.
+	 */
+	REMOTE_HUB_S(nasid, IIO_ICTP, 0xffffff );
+	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
+
+	/* Initialize error interrupts for this hub. */
+	hub_error_init(cnode);
+}
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/machvec/iomv.c linux-2.4.23-pre8/arch/ia64/sn/io/machvec/iomv.c
--- linux-2.4.22/arch/ia64/sn/io/machvec/iomv.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/machvec/iomv.c	2003-10-22 22:48:54.000000000 +0000
@@ -32,7 +32,6 @@
 		return( (void *)  (port | __IA64_UNCACHED_OFFSET));
 	} else {
 		/* but the simulator uses them... */
-		unsigned long io_base;
 		unsigned long addr;
  
 		/*
@@ -40,13 +39,9 @@
  		 * for accessing registers in bedrock local block
  		 * (so we don't do port&0xfff)
  		 */
-		if ((port >= 0x1f0 && port <= 0x1f7) ||
-			port == 0x3f6 || port == 0x3f7) {
-			io_base = (0xc000000fcc000000 | ((unsigned long)get_nasid() << 38));
-			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
-		} else {
-			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
-		}
+		addr = 0xc0000087cc000000 | ((port >> 2) << 12);
+		if ((port >= 0x1f0 && port <= 0x1f7) || port == 0x3f6 || port == 0x3f7)
+			addr |= port;
 		return(void *) addr;
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/machvec/pci.c linux-2.4.23-pre8/arch/ia64/sn/io/machvec/pci.c
--- linux-2.4.22/arch/ia64/sn/io/machvec/pci.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/machvec/pci.c	2003-10-22 22:48:17.000000000 +0000
@@ -130,13 +130,6 @@
 	if ( dev == (struct pci_dev *)0 ) {
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	}
-	/* 
-	 * if it's an IOC3 then we bail out, we special
-	 * case them with pci_fixup_ioc3
-	 */
-	if (dev->vendor == PCI_VENDOR_ID_SGI && 
-	    dev->device == PCI_DEVICE_ID_SGI_IOC3 )
-		return PCIBIOS_SUCCESSFUL;
 
 	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
 	if (!device_vertex) {
@@ -163,13 +156,6 @@
 	if ( dev == (struct pci_dev *)0 ) {
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	}
-	/* 
-	 * if it's an IOC3 then we bail out, we special
-	 * case them with pci_fixup_ioc3
-	 */
-	if (dev->vendor == PCI_VENDOR_ID_SGI && 
-	    dev->device == PCI_DEVICE_ID_SGI_IOC3)
-		return PCIBIOS_SUCCESSFUL;
 
 	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
 	if (!device_vertex) {
@@ -196,13 +182,6 @@
 	if ( dev == (struct pci_dev *)0 ) {
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	}
-	/* 
-	 * if it's an IOC3 then we bail out, we special
-	 * case them with pci_fixup_ioc3
-	 */
-	if (dev->vendor == PCI_VENDOR_ID_SGI && 
-	    dev->device == PCI_DEVICE_ID_SGI_IOC3)
-		return PCIBIOS_SUCCESSFUL;
 
 	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
 	if (!device_vertex) {
@@ -241,49 +220,8 @@
 	/* sn_io_infrastructure_init(); */
 	pci_root_ops = &snia64_pci_ops;
 }
-
-void
-pci_fixup_ioc3(struct pci_dev *d)
-{
-        int 		i;
-	unsigned int 	size;
-
-        /* IOC3 only decodes 0x20 bytes of the config space, reading
-	 * beyond that is relatively benign but writing beyond that
-	 * (especially the base address registers) will shut down the
-	 * pci bus...so avoid doing so.
-	 * NOTE: this means we can't program the intr_pin into the device,
-	 *       currently we hack this with special code in 
-	 *	 sgi_pci_intr_support()
-	 */
-        DBG("pci_fixup_ioc3: Fixing base addresses for ioc3 device %s\n", d->slot_name);
-
-	/* I happen to know from the spec that the ioc3 needs only 0xfffff 
-	 * The standard pci trick of writing ~0 to the baddr and seeing
-	 * what comes back doesn't work with the ioc3
-	 */
-	size = 0xfffff;
-	d->resource[0].end = (unsigned long) d->resource[0].start + (unsigned long) size;
-
-	/*
-	 * Zero out the resource structure .. because we did not go through 
-	 * the normal PCI Infrastructure Init, garbbage are left in these 
-	 * fileds.
-	 */
-        for (i = 1; i <= PCI_ROM_RESOURCE; i++) {
-                d->resource[i].start = 0UL;
-                d->resource[i].end = 0UL;
-                d->resource[i].flags = 0UL;
-        }
-
-        d->subsystem_vendor = 0;
-        d->subsystem_device = 0;
-
-}
-
 #else
 void sn_pci_find_bios(void) {}
-void pci_fixup_ioc3(struct pci_dev *d) {}
 struct list_head pci_root_buses;
 struct list_head pci_root_buses;
 struct list_head pci_devices;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/machvec/pci_bus_cvlink.c linux-2.4.23-pre8/arch/ia64/sn/io/machvec/pci_bus_cvlink.c
--- linux-2.4.22/arch/ia64/sn/io/machvec/pci_bus_cvlink.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/machvec/pci_bus_cvlink.c	2003-10-22 22:49:16.000000000 +0000
@@ -47,14 +47,13 @@
 static int done_probing;
 extern irqpda_t *irqpdaindr;
 
-static int pci_bus_map_create(vertex_hdl_t xtalk, char * io_moduleid);
+static int pci_bus_map_create(vertex_hdl_t xtalk, int brick_type, char * io_moduleid);
 vertex_hdl_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
 
 extern void register_pcibr_intr(int irq, pcibr_intr_t intr);
 
 void sn_dma_flush_init(unsigned long start, unsigned long end, int idx, int pin, int slot);
 
-
 /*
  * For the given device, initialize whether it is a PIC device.
  */
@@ -148,8 +147,7 @@
 	 */
 	if (func == 0) {
         	sprintf(name, "%d", slot);
-		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
-			GRAPH_SUCCESS) {
+		if (hwgraph_traverse(pci_bus, name, &device_vertex) == GRAPH_SUCCESS) {
 			if (device_vertex) {
 				return(device_vertex);
 			}
@@ -170,54 +168,6 @@
 	return(device_vertex);
 }
 
-/*
- * For the given device, initialize the addresses for both the Device(x) Flush 
- * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
- * is connected.
- */
-static void
-set_flush_addresses(struct pci_dev *device_dev, 
-	struct sn_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    	bridge_t               *bridge = pcibr_soft->bs_base;
-	nasid_t			nasid;
-
-	/*
-	 * Get the nasid from the bridge.
-	 */
-	nasid = NASID_GET(device_sysdata->dma_buf_sync);
-	if (IS_PIC_DEVICE(device_dev)) {
-		device_sysdata->dma_buf_sync = (volatile unsigned int *)
-			&bridge->b_wr_req_buf[pciio_slot].reg;
-		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
-			XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(nasid, 0),
-			pcibr_soft->bs_xid);
-	} else {
-		/*
-		 * Accessing Xbridge and Xbow register when SHUB swapoper is on!.
-		 */
-		device_sysdata->dma_buf_sync = (volatile unsigned int *)
-			((uint64_t)&(bridge->b_wr_req_buf[pciio_slot].reg)^4);
-		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
-			((uint64_t)(XBOW_PRIO_LINKREGS_PTR(
-			NODE_SWIN_BASE(nasid, 0), pcibr_soft->bs_xid)) ^ 4);
-	}
-
-#ifdef DEBUG
-	printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
-		device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
-
-printk("set_flush_addresses: dma_buf_sync\n");
-	while((volatile unsigned int )*device_sysdata->dma_buf_sync);
-printk("set_flush_addresses: xbow_buf_sync\n");
-	while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
-#endif
-
-}
-
 struct sn_flush_nasid_entry flush_nasid_list[MAX_NASIDS];
 
 // Initialize the data structures for flushing write buffers after a PIO read.
@@ -247,6 +197,9 @@
 	if (flush_nasid_list[nasid].widget_p == NULL) {
 		flush_nasid_list[nasid].widget_p = (struct sn_flush_device_list **)kmalloc((HUB_WIDGET_ID_MAX+1) *
 			sizeof(struct sn_flush_device_list *), GFP_KERNEL);
+		if (flush_nasid_list[nasid].widget_p <= 0)
+			BUG(); /* Cannot afford to run out of memory. */
+
 		memset(flush_nasid_list[nasid].widget_p, 0, (HUB_WIDGET_ID_MAX+1) * sizeof(struct sn_flush_device_list *));
 	}
 	if (bwin > 0) {
@@ -326,6 +279,9 @@
 	if (flush_nasid_list[nasid].widget_p[wid_num] == NULL) {
 		flush_nasid_list[nasid].widget_p[wid_num] = (struct sn_flush_device_list *)kmalloc(
 			DEV_PER_WIDGET * sizeof (struct sn_flush_device_list), GFP_KERNEL);
+		if (flush_nasid_list[nasid].widget_p[wid_num] <= 0)
+			BUG(); /* Cannot afford to run out of memory. */
+
 		memset(flush_nasid_list[nasid].widget_p[wid_num], 0, 
 			DEV_PER_WIDGET * sizeof (struct sn_flush_device_list));
 		p = &flush_nasid_list[nasid].widget_p[wid_num][0];
@@ -430,13 +386,6 @@
 		}
 	}
 
-	if (vendor == PCI_VENDOR_ID_SGI) {
-		if (device == PCI_DEVICE_ID_SGI_IOC3) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
 }
 
 /*
@@ -455,7 +404,7 @@
 	struct sn_widget_sysdata *widget_sysdata;
 	struct sn_device_sysdata *device_sysdata;
 	pciio_intr_t intr_handle;
-	int cpuid, bit;
+	int cpuid;
 	vertex_hdl_t device_vertex;
 	pciio_intr_line_t lines;
 	extern void sn_pci_find_bios(void);
@@ -488,6 +437,9 @@
 		pci_bus = pci_bus_b(ln);
 		widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), 
 					GFP_KERNEL);
+		if (widget_sysdata <= 0)
+			BUG(); /* Cannot afford to run out of memory */
+
 		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
 		pci_bus->sysdata = (void *)widget_sysdata;
 	}
@@ -516,24 +468,15 @@
 		unsigned long size;
 		extern int bit_pos_to_irq(int);
 
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
-			extern void pci_fixup_ioc3(struct pci_dev *d);
-			pci_fixup_ioc3(device_dev);
-		}
-
 		/* Set the device vertex */
 
 		device_sysdata = kmalloc(sizeof(struct sn_device_sysdata),
 					GFP_KERNEL);
+		if (device_sysdata <= 0)
+			BUG(); /* Cannot afford to run out of memory */
+
 		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
 		device_sysdata->isa64 = 0;
-		/*
-		 * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
-		 * register addresses.
-		 */
-		(void) set_flush_addresses(device_dev, device_sysdata);
-
 		device_dev->sysdata = (void *) device_sysdata;
 		set_sn_pci64(device_dev);
 		set_isPIC(device_sysdata);
@@ -552,7 +495,7 @@
 			size = device_dev->resource[idx].end -
 				device_dev->resource[idx].start;
 			if (size) {
-				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
+				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, 0);
 				device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
 			}
 			else
@@ -583,7 +526,7 @@
 		if (size) {
 			device_dev->resource[PCI_ROM_RESOURCE].start =
 			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
-				size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
+				size, 0, 0);
 			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
 			device_dev->resource[PCI_ROM_RESOURCE].end =
 			device_dev->resource[PCI_ROM_RESOURCE].start + size;
@@ -598,11 +541,6 @@
 		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
 
 		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-				lines = 1;
-		}
- 
 		device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;
 		device_vertex = device_sysdata->vhdl;
  
@@ -703,13 +641,11 @@
  *	
  */
 static int 
-pci_bus_map_create(vertex_hdl_t xtalk, char * io_moduleid)
+pci_bus_map_create(vertex_hdl_t xtalk, int brick_type, char * io_moduleid)
 {
 
-	vertex_hdl_t master_node_vertex = NULL;
 	vertex_hdl_t xwidget = NULL;
 	vertex_hdl_t pci_bus = NULL;
-	hubinfo_t hubinfo = NULL;
 	xwidgetnum_t widgetnum;
 	char pathname[128];
 	graph_error_t rv;
@@ -720,73 +656,6 @@
 	int bus_number;
 
 	/*
-	 * Loop throught this vertex and get the Xwidgets ..
-	 */
-
-
-	/* PCI devices */
-
-	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
-		sprintf(pathname, "%d", widgetnum);
-		xwidget = NULL;
-		
-		/*
-		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
-		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
-		 */
-		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
-		if ( (rv != GRAPH_SUCCESS) ) {
-			if (!xwidget) {
-				continue;
-			}
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		pci_bus = NULL;
-		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
-			if (!pci_bus) {
-				continue;
-}
-
-		/*
-		 * Assign the correct bus number and also the nasid of this 
-		 * pci Xwidget.
-		 * 
-		 * Should not be any race here ...
-		 */
-		num_bridges++;
-		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
-
-		/*
-		 * Get the master node and from there get the NASID.
-		 */
-		master_node_vertex = device_master_get(xwidget);
-		if (!master_node_vertex) {
-			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
-		}
-	
-		hubinfo_get(master_node_vertex, &hubinfo);
-		if (!hubinfo) {
-			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
-			return(1);
-		} else {
-			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
-		}
-
-		/*
-		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
-		 */
-		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
-		if (!busnum_to_atedmamaps[num_bridges - 1])
-			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
-
-		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
-
-	}
-
-	/*
 	 * PCIX devices
 	 * We number busses differently for PCI-X devices.
 	 * We start from Lowest Widget on up ..
@@ -829,11 +698,11 @@
 			 * 
 			 * Should not be any race here ...
 			 */
-			bus_number = basebus_num + bus + io_brick_map_widget(MODULE_PXBRICK, widgetnum);
+			bus_number = basebus_num + bus + io_brick_map_widget(brick_type, widgetnum);
 #ifdef DEBUG
-			printk("bus_number %d basebus_num %d bus %d io %d\n", 
+			printk("bus_number %d basebus_num %d bus %d io %d pci_bus 0x%x brick_type %d \n", 
 				bus_number, basebus_num, bus, 
-				io_brick_map_widget(MODULE_PXBRICK, widgetnum));
+				io_brick_map_widget(brick_type, widgetnum), pci_bus, brick_type);
 #endif
 			busnum_to_pcibr_vhdl[bus_number] = pci_bus;
 	
@@ -842,14 +711,71 @@
 			 */
 			busnum_to_atedmamaps[bus_number] = (void *) kmalloc(
 				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
-			if (!busnum_to_atedmamaps[bus_number])
-				printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
+			if (busnum_to_atedmamaps[bus_number] <= 0)
+				BUG(); /* Cannot afford to run out of memory. */
 	
 			memset(busnum_to_atedmamaps[bus_number], 0x0, 
 				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
 		}
 	}
 
+	/* AGP/CGbrick */
+
+	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
+
+		/* Do both buses */
+		for ( bus = 0; bus < 2; bus++ ) {
+			sprintf(pathname, "%d", widgetnum);
+			xwidget = NULL;
+			
+			/*
+			 * Example - /hw/module/001c16/slab/0/CGbrick/xtalk/15 is the xwidget
+			 *	     /hw/module/001c16/slab/0/CGbrick/xtalk/15/agp/0 is the bus
+			 *	     /hw/module/001c16/slab/0/CGbrick/xtalk/15/agp/0/1a is device
+			 */
+			rv = hwgraph_traverse(xtalk, pathname, &xwidget);
+			if ( (rv != GRAPH_SUCCESS) ) {
+				if (!xwidget) {
+					continue;
+				}
+			}
+	
+			if ( bus == 0 )
+				sprintf(pathname, "%d/"EDGE_LBL_AGP_0, widgetnum);
+			else
+				sprintf(pathname, "%d/"EDGE_LBL_AGP_1, widgetnum);
+			pci_bus = NULL;
+			if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
+				if (!pci_bus) {
+					continue;
+				}
+	
+			/*
+			 * Assign the correct bus number and also the nasid of this 
+			 * pci Xwidget.
+			 * 
+			 * Should not be any race here ...
+			 */
+			bus_number = basebus_num + bus + io_brick_map_widget(brick_type, widgetnum);
+#ifdef DEBUG
+			printk("bus_number %d basebus_num %d bus %d io %d pci_bus 0x%x\n", 
+				bus_number, basebus_num, bus, 
+				io_brick_map_widget(brick_type, widgetnum), pci_bus);
+#endif
+			busnum_to_pcibr_vhdl[bus_number] = pci_bus;
+
+			/*
+			 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
+			 */
+			busnum_to_atedmamaps[bus_number] = (void *) kmalloc(
+				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
+			if (busnum_to_atedmamaps[bus_number] <= 0)
+				BUG(); /* Cannot afford to run out of memory */
+	
+			memset(busnum_to_atedmamaps[bus_number], 0x0, 
+				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
+		}
+	}
         return(0);
 }
 
@@ -868,11 +794,20 @@
 	vertex_hdl_t devfs_hdl = NULL;
 	vertex_hdl_t xtalk = NULL;
 	int rv = 0;
-	char name[256];
-	char tmp_name[256];
+	char *name;
+	char *tmp_name;
 	int i, ii, j;
 	char *brick_name;
 	extern void ioconfig_bus_new_entries(void);
+	extern int iobrick_type_get_nasid(nasid_t);
+
+	name = kmalloc(256, GFP_KERNEL);
+	if (!name)
+		BUG();
+
+	tmp_name = kmalloc(256, GFP_KERNEL);
+	if (!name)
+		 BUG();
 
 	/*
 	 * Figure out which IO Brick is connected to the Compute Bricks.
@@ -881,32 +816,39 @@
 		extern int iomoduleid_get(nasid_t);
 		moduleid_t iobrick_id;
 		nasid_t nasid = -1;
-		int nodecnt;
 		int n = 0;
 
-		nodecnt = modules[i]->nodecnt;
-		for ( n = 0; n < nodecnt; n++ ) {
+		for ( n = 0; n <= MAX_SLABS; n++ ) {
+			if (modules[i]->nodes[n] == -1)
+				continue; /* node is not alive in module */
+
 			nasid = cnodeid_to_nasid(modules[i]->nodes[n]);
 			iobrick_id = iomoduleid_get(nasid);
 			if ((int)iobrick_id > 0) { /* Valid module id */
 				char name[12];
 				memset(name, 0, 12);
 				format_module_id((char *)&(modules[i]->io[n].moduleid), iobrick_id, MODULE_FORMAT_BRIEF);
+				modules[i]->io[n].iobrick_type = (uint64_t)iobrick_type_get_nasid(nasid);
 			}
 		}
 	}
 				
 	devfs_hdl = hwgraph_path_to_vertex("hw/module");
 	for (i = 0; i < nummodules ; i++) {
-	    for ( j = 0; j < 3; j++ ) {
+	    for ( j = 0; j < 4; j++ ) {
 		if ( j == 0 )
-			brick_name = EDGE_LBL_PBRICK;
+			brick_name = EDGE_LBL_IXBRICK;
 		else if ( j == 1 )
 			brick_name = EDGE_LBL_PXBRICK;
-		else
-			brick_name = EDGE_LBL_IXBRICK;
+		else if ( j == 2 )
+			brick_name = EDGE_LBL_OPUSBRICK;
+		else	/* 3 */
+			brick_name = EDGE_LBL_CGBRICK;
+
+		for ( ii = 0; ii <= MAX_SLABS ; ii++ ) {
+			if (modules[i]->nodes[ii] == -1)
+				continue; /* Missing slab */
 
-		for ( ii = 0; ii < 2 ; ii++ ) {
 			memset(name, 0, 256);
 			memset(tmp_name, 0, 256);
 			format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
@@ -915,11 +857,14 @@
 			xtalk = NULL;
 			rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
 			if ( rv == 0 ) 
-				pci_bus_map_create(xtalk, (char *)&(modules[i]->io[ii].moduleid));
+				pci_bus_map_create(xtalk, (int)modules[i]->io[ii].iobrick_type, (char *)&(modules[i]->io[ii].moduleid));
 		}
 	    }
 	}
 
+	kfree(name);
+	kfree(tmp_name);
+
 	/*
 	 * Create the Linux PCI bus number vertex link.
 	 */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/machvec/pci_dma.c linux-2.4.23-pre8/arch/ia64/sn/io/machvec/pci_dma.c
--- linux-2.4.22/arch/ia64/sn/io/machvec/pci_dma.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/machvec/pci_dma.c	2003-10-22 22:48:20.000000000 +0000
@@ -182,7 +182,6 @@
 	 * attributes or to a different memory region.
 	 */
 	*dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
 					  PCIIO_DMA_CMD);
 
         /*
@@ -201,7 +200,6 @@
 	 */
 	if (!(*dma_handle)) {
 		dma_map = pciio_dmamap_alloc(vhdl, NULL, size,
-				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
 					     PCIIO_DMA_CMD);
 		if (!dma_map) {
 			printk(KERN_ERR "sn_pci_alloc_consistent: Unable to "
@@ -295,10 +293,7 @@
 		 */
 		if (IS_PCIA64(hwdev)) {
 			sg->dma_address = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
-						       sg->length,
-			       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-						       PCIIO_DMA_DATA |
-						       PCIIO_DMA_A64);
+						       sg->length, PCIIO_DMA_DATA | PCIIO_DMA_A64);
 			sg->dma_length = sg->length;
 			continue;
 		}
@@ -308,9 +303,7 @@
 		 */
 		if (IS_PCI32G(hwdev)) {
 			sg->dma_address = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
-						       sg->length,
-					((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-						       PCIIO_DMA_DATA);
+						       sg->length, PCIIO_DMA_DATA);
 			sg->dma_length = sg->length;
 			/*
 			 * See if we got a direct map entry
@@ -325,9 +318,7 @@
 		 * It is a 32 bit card and we cannot do direct mapping,
 		 * so we use an ATE.
 		 */
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length,
-				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					     PCIIO_DMA_DATA);
+		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length, PCIIO_DMA_DATA);
 		if (!dma_map) {
 			printk(KERN_ERR "sn_pci_map_sg: Unable to allocate "
 			       "anymore 32 bit page map entries.\n");
@@ -440,9 +431,7 @@
 	if (IS_PCIA64(hwdev)) {
 		/* This device supports 64 bit DMA addresses. */
 		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-		       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					       PCIIO_DMA_DATA |
-					       PCIIO_DMA_A64);
+					       PCIIO_DMA_DATA | PCIIO_DMA_A64);
 		return dma_addr;
 	}
 
@@ -454,7 +443,6 @@
 	 */
 	if (IS_PCI32G(hwdev)) {
 		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
 					       PCIIO_DMA_DATA);
 		if (dma_addr)
 			return dma_addr;
@@ -465,9 +453,7 @@
 	 * let's use the PMU instead.
 	 */
 	dma_map = NULL;
-	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, 
-			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-			PCIIO_DMA_DATA);
+	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, PCIIO_DMA_DATA);
 
 	if (!dma_map) {
 		printk(KERN_ERR "pci_map_single: Unable to allocate anymore "
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/platform_init/Makefile linux-2.4.23-pre8/arch/ia64/sn/io/platform_init/Makefile
--- linux-2.4.22/arch/ia64/sn/io/platform_init/Makefile	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/platform_init/Makefile	2003-10-22 22:49:48.000000000 +0000
@@ -11,6 +11,6 @@
 
 O_TARGET := snio.o
 
-obj-y				+=  sgi_io_init.o irix_io_init.o
+obj-y				+=  irix_io_init.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/platform_init/irix_io_init.c linux-2.4.23-pre8/arch/ia64/sn/io/platform_init/irix_io_init.c
--- linux-2.4.22/arch/ia64/sn/io/platform_init/irix_io_init.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/platform_init/irix_io_init.c	2003-10-22 22:49:55.000000000 +0000
@@ -23,17 +23,55 @@
 extern void klhwg_add_all_modules(vertex_hdl_t);
 extern void klhwg_add_all_nodes(vertex_hdl_t);
 
+extern int init_hcl(void);
 extern vertex_hdl_t hwgraph_root;
 extern void io_module_init(void);
 extern int pci_bus_to_hcl_cvlink(void);
-extern void mlreset(void);
 
-/* #define DEBUG_IO_INIT 1 */
-#ifdef DEBUG_IO_INIT
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_IO_INIT */
+char arg_maxnodes[4];
+char master_baseio_wid;
+nasid_t master_baseio_nasid;
+nasid_t master_nasid = INVALID_NASID;           /* This is the partition master nasid */
+nasid_t console_nasid = (nasid_t)-1;
+
+/*
+ * Return non-zero if the given variable was specified
+ */
+int
+is_specified(char *s)
+{
+	return (strlen(s) != 0);
+}
+
+int
+check_nasid_equiv(nasid_t nasida, nasid_t nasidb)
+{
+	if ((nasida == nasidb) || (nasida == NODEPDA(NASID_TO_COMPACT_NODEID(nasidb))->xbow_peer))
+		return 1;
+	else
+		return 0;
+}
+
+int
+is_master_baseio_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid)
+{
+
+	/*
+	 * If the widget numbers are different, we're not the master.
+	 */
+	if (test_wid != (xwidgetnum_t)master_baseio_wid) {
+		return 0;
+	}
+
+	/*
+	 * If the NASIDs are the same or equivalent, we're the master.
+	 */
+	if (check_nasid_equiv(test_nasid, master_baseio_nasid)) {
+		return 1;
+	} else {
+		return 0;
+	}
+}
 
 /*
  * This routine is responsible for the setup of all the IRIX hwgraph style
@@ -46,14 +84,11 @@
  */
 
 void
-irix_io_init(void)
+sgi_master_io_infr_init(void)
 {
 	cnodeid_t cnode;
 
-	/*
-	 * This is the Master CPU.  Emulate mlsetup and main.c in Irix.
-	 */
-	mlreset();
+	init_hcl(); /* Sets up the hwgraph compatibility layer */
 
         /*
          * Initialize platform-dependent vertices in the hwgraph:
@@ -78,6 +113,12 @@
 
 	/* We can do headless hub cnodes here .. */
 
+	/* Initialize ICE for TIO Nodes. */
+	for (cnode = numnodes; cnode < numionodes; cnode++) {
+		extern void per_ice_init(cnodeid_t);
+		per_ice_init(cnode);
+	}
+
 	/*
 	 *
 	 * Our IO Infrastructure drivers are in place .. 
@@ -86,4 +127,12 @@
 	 */
 	init_all_devices();
 	pci_bus_to_hcl_cvlink();
+
+#ifdef  CONFIG_KDB
+        {
+                extern void kdba_io_init(void);
+                kdba_io_init();
+        }
+#endif
+
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/sgi_if.c linux-2.4.23-pre8/arch/ia64/sn/io/sgi_if.c
--- linux-2.4.22/arch/ia64/sn/io/sgi_if.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/sgi_if.c	2003-10-22 22:48:55.000000000 +0000
@@ -21,11 +21,11 @@
 #include <asm/sn/slotnum.h>
 
 void *
-snia_kmem_zalloc(size_t size, int flag)
+snia_kmem_zalloc(size_t size)
 {
         void *ptr = kmalloc(size, GFP_KERNEL);
 	if ( ptr )
-        	BZERO(ptr, size);
+        	memset(ptr, 0, size);
         return(ptr);
 }
 
@@ -39,21 +39,12 @@
  * the alloc/free_node routines do a simple kmalloc for now ..
  */
 void *
-snia_kmem_alloc_node(register size_t size, register int flags, cnodeid_t node)
+snia_kmem_alloc_node(register size_t size, cnodeid_t node)
 {
 	/* someday will Allocate on node 'node' */
 	return(kmalloc(size, GFP_KERNEL));
 }
 
-void *
-snia_kmem_zalloc_node(register size_t size, register int flags, cnodeid_t node)
-{
-	void *ptr = kmalloc(size, GFP_KERNEL);
-	if ( ptr )
-		BZERO(ptr, size);
-        return(ptr);
-}
-
 
 /*
  * print_register() allows formatted printing of bit fields.  individual
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/sn2/Makefile linux-2.4.23-pre8/arch/ia64/sn/io/sn2/Makefile
--- linux-2.4.22/arch/ia64/sn/io/sn2/Makefile	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/sn2/Makefile	2003-10-22 22:49:18.000000000 +0000
@@ -11,15 +11,14 @@
 
 O_TARGET := snio.o
 
-export-objs := pciio.o 
-
 obj-y				+= ml_SN_intr.o shub_intr.o shuberror.o shub.o \
 				   bte_error.o pcibr/pcibr.o pic.o geo_op.o \
 				   l1_command.o klconflib.o klgraph.o \
 				   ml_SN_init.o ml_iograph.o module.o pciio.o \
-				   xbow.o xtalk.o shubio.o
+				   xbow.o xtalk.o shubio.o ioc4/ioc4_if.o
+
 obj-$(CONFIG_KDB)		+= kdba_io.o
 
-subdir-y			+= pcibr
+subdir-y			+= pcibr ioc4
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/sn2/ioc4/Makefile linux-2.4.23-pre8/arch/ia64/sn/io/sn2/ioc4/Makefile
--- linux-2.4.22/arch/ia64/sn/io/sn2/ioc4/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/sn2/ioc4/Makefile	2003-10-22 22:49:08.000000000 +0000
@@ -0,0 +1,22 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io ioc4 routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+ifdef CONFIG_IA64_SGI_SN2
+EXTRA_CFLAGS    += -DSHUB_SWAP_WAR
+endif
+
+O_TARGET := ioc4_if.o
+export-objs := ioc4.o  sio_ioc4.o
+
+
+obj-$(CONFIG_IA64_SGI_SN2)	+= sio_ioc4.o ioc4.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/sn2/ioc4/ioc4.c linux-2.4.23-pre8/arch/ia64/sn/io/sn2/ioc4/ioc4.c
--- linux-2.4.22/arch/ia64/sn/io/sn2/ioc4/ioc4.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/sn2/ioc4/ioc4.c	2003-10-22 22:49:44.000000000 +0000
@@ -0,0 +1,641 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+
+/* This is the top level IOC4 device driver.  It does very little, farming
+ * out actual tasks to the various slave IOC4 drivers (serial, keyboard/mouse,
+ * and real-time interrupt).
+ */
+
+#include <linux/config.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/iograph.h>
+#include <asm/atomic.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/pci/pciio.h>
+#include <linux/pci.h>
+#include <asm/sn/ioc4.h>
+#include <asm/sn/pci/pci_bus_cvlink.h>
+
+/* #define DEBUG_INTERRUPTS */
+#define SUPPORT_ATOMICS
+
+#ifdef SUPPORT_ATOMICS
+
+/*
+ * support routines for local atomic operations.
+ */
+
+static spinlock_t local_lock;
+
+static inline unsigned int
+atomicSetInt(atomic_t *a, unsigned int b)
+{
+	unsigned long s;
+	unsigned int ret, new;
+
+	spin_lock_irqsave(&local_lock, s);
+	new = ret = atomic_read(a);
+	new |= b;
+	atomic_set(a, new);
+	spin_unlock_irqrestore(&local_lock, s);
+
+	return ret;
+}
+
+static unsigned int
+atomicClearInt(atomic_t *a, unsigned int b)
+{
+	unsigned long s;
+	unsigned int ret, new;
+
+	spin_lock_irqsave(&local_lock, s);
+	new = ret = atomic_read(a);
+	new &= ~b;
+	atomic_set(a, new);
+	spin_unlock_irqrestore(&local_lock, s);
+
+	return ret;
+}
+
+#else
+
+#define atomicAddInt(a,b)	*(a) += ((unsigned int)(b))
+
+static inline unsigned int
+atomicSetInt(unsigned int *a, unsigned int b)
+{
+	unsigned int ret = *a;
+
+	*a |= b;
+	return ret;
+}
+
+#define atomicSetUint64(a,b)	*(a) |= ((unsigned long long )(b))
+
+static inline unsigned int
+atomicClearInt(unsigned int *a, unsigned int b)
+{
+	unsigned int ret = *a;
+
+	*a &= ~b;
+	return ret;
+}
+
+#define atomicClearUint64(a,b)	*(a) &= ~((unsigned long long)(b))
+#endif	/* SUPPORT_ATOMICS */
+
+
+/* pci device struct */
+static const struct pci_device_id __devinitdata ioc4_s_id_table[] =
+{
+        { IOC4_VENDOR_ID_NUM, IOC4_DEVICE_ID_NUM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+        {              0,           0,          0,          0, 0, 0, 0 }
+};
+
+int __devinit ioc4_attach(struct pci_dev *, const struct pci_device_id *);
+
+struct pci_driver ioc4_s_driver =
+{
+	name : "IOC4 Serial",
+	id_table: ioc4_s_id_table,
+	probe: ioc4_attach,
+};
+
+int __init
+ioc4_serial_detect(void)
+{
+	int rc;
+
+	rc = pci_register_driver(&ioc4_s_driver);
+	return 0;
+}
+module_init(ioc4_serial_detect);
+
+
+/*
+ * Some external functions we still need.
+ */
+extern int		ioc4_serial_attach(vertex_hdl_t conn, void *mem);
+extern cpuid_t		cpuvertex_to_cpuid(vertex_hdl_t vhdl);
+
+
+/*
+ * per-IOC4 data structure
+ */
+typedef struct ioc4_soft_s {
+    vertex_hdl_t	    is_ioc4_vhdl;
+    vertex_hdl_t            is_conn_vhdl;
+
+    struct pci_dev	   *is_pci_dev;
+    ioc4_mem_t		   *is_ioc4_mem;
+
+    /* Each interrupt type has an entry in the array */
+    struct ioc4_intr_type {
+
+        /*
+         * Each in-use entry in this array contains at least
+         * one nonzero bit in sd_bits; no two entries in this
+         * array have overlapping sd_bits values.
+         */
+#define MAX_IOC4_INTR_ENTS	(8 * sizeof(ioc4reg_t))
+        struct ioc4_intr_info {
+	    ioc4reg_t		sd_bits;
+	    ioc4_intr_func_f   *sd_intr;
+	    intr_arg_t		sd_info;
+	    vertex_hdl_t	sd_vhdl;
+	    struct ioc4_soft_s *sd_soft;
+        } is_intr_info[MAX_IOC4_INTR_ENTS];
+
+        /* Number of entries active in the above array */
+        atomic_t	 is_num_intrs;
+        atomic_t	 is_intr_bits_busy;	/* Bits assigned */
+        atomic_t         is_intr_ents_free;	/* Free active entries mask*/
+    } is_intr_type[ioc4_num_intr_types];
+
+    /* is_ir_lock must be held while
+     * modifying sio_ie values, so
+     * we can be sure that sio_ie is
+     * not changing when we read it
+     * along with sio_ir.
+     */
+    spinlock_t		    is_ir_lock;		/* SIO_IE[SC] mod lock */
+} ioc4_soft_t;
+
+#define ioc4_soft_set(v,i)	hwgraph_fastinfo_set((v), (arbitrary_info_t)(i))
+#define ioc4_soft_get(v)	((ioc4_soft_t *)hwgraph_fastinfo_get(v))
+
+
+/* =====================================================================
+ *    Function Table of Contents
+ */
+
+
+/* The IOC4 hardware provides no atomic way to determine if interrupts
+ * are pending since two reads are required to do so.  The handler must
+ * read the SIO_IR and the SIO_IES, and take the logical and of the
+ * two.  When this value is zero, all interrupts have been serviced and
+ * the handler may return.
+ *
+ * This has the unfortunate "hole" that, if some other CPU or
+ * some other thread or some higher level interrupt manages to
+ * modify SIO_IE between our reads of SIO_IR and SIO_IE, we may
+ * think we have observed SIO_IR&SIO_IE==0 when in fact this
+ * condition never really occurred.
+ *
+ * To solve this, we use a simple spinlock that must be held
+ * whenever modifying SIO_IE; holding this lock while observing
+ * both SIO_IR and SIO_IE guarantees that we do not falsely
+ * conclude that no enabled interrupts are pending.
+ */
+
+void
+ioc4_write_ireg(void *ioc4_soft, ioc4reg_t val, int which, ioc4_intr_type_t type)
+{
+    ioc4_mem_t		   *mem = ((ioc4_soft_t *) ioc4_soft)->is_ioc4_mem;
+    spinlock_t		   *lp = &((ioc4_soft_t *) ioc4_soft)->is_ir_lock;
+    unsigned long	    s;
+
+
+    spin_lock_irqsave(lp, s);
+
+    switch (type) {
+      case ioc4_sio_intr_type:
+        switch (which) {
+          case IOC4_W_IES:
+	    mem->sio_ies_ro = val;
+	    break;
+
+          case IOC4_W_IEC:
+	    mem->sio_iec_ro = val;
+	    break;
+        }
+	break;
+
+      case ioc4_other_intr_type:
+        switch (which) {
+          case IOC4_W_IES:
+	    mem->other_ies_ro = val;
+	    break;
+
+          case IOC4_W_IEC:
+	    mem->other_iec_ro = val;
+	    break;
+        }
+	break;
+
+      case ioc4_num_intr_types:
+	break;
+    }
+    spin_unlock_irqrestore(lp, s);
+}
+
+
+static inline ioc4reg_t
+ioc4_pending_intrs(ioc4_soft_t * ioc4_soft, ioc4_intr_type_t type)
+{
+    ioc4_mem_t	*mem = ioc4_soft->is_ioc4_mem;
+    spinlock_t	*lp = &ioc4_soft->is_ir_lock;
+    unsigned long	    s;
+    ioc4reg_t	intrs = (ioc4reg_t)0;
+
+    ASSERT((type == ioc4_sio_intr_type) || (type == ioc4_other_intr_type));
+
+    spin_lock_irqsave(lp, s);
+
+    switch (type) {
+      case ioc4_sio_intr_type:
+        intrs = mem->sio_ir & mem->sio_ies_ro;
+        break;
+
+      case ioc4_other_intr_type:
+        intrs = mem->other_ir & mem->other_ies_ro;
+
+        /* Don't process any ATA interrupte, leave them for the ATA driver */
+        intrs &= ~(IOC4_OTHER_IR_ATA_INT | IOC4_OTHER_IR_ATA_MEMERR); 
+        break;
+
+      case ioc4_num_intr_types:
+	break;
+    }
+
+    spin_unlock_irqrestore(lp, s);
+    return intrs;
+}
+
+
+int __devinit
+ioc4_attach(struct pci_dev *pci_handle, const struct pci_device_id *pci_id)
+{
+    ioc4_mem_t		   *mem;
+/*REFERENCED*/
+    graph_error_t	    rc;
+    vertex_hdl_t	    ioc4_vhdl;
+    ioc4_soft_t		   *soft;
+    vertex_hdl_t	    conn_vhdl = PCIDEV_VERTEX(pci_handle);
+    int                     tmp;
+    extern void ioc4_ss_connect_interrupt(int, void *, void *);
+    extern void ioc4_intr(int, void *, struct pt_regs *);
+
+    if ( pci_enable_device(pci_handle) ) {
+	    printk("ioc4_attach: Failed to enable device with pci_dev 0x%p... returning\n", (void *)pci_handle);
+	    return(-1);
+    }
+
+    pci_set_master(pci_handle);
+    snia_pciio_endian_set(pci_handle, PCIDMA_ENDIAN_LITTLE, PCIDMA_ENDIAN_BIG);
+
+    /*
+     * Get PIO mappings through our "primary"
+     * connection point to the IOC4's CFG and
+     * MEM spaces.
+     */
+
+    /*
+     * Map in the ioc4 memory - we'll do config accesses thru the pci_????() interfaces.
+     */
+
+    mem = (ioc4_mem_t *)pci_resource_start(pci_handle, 0);
+    if ( !mem ) {
+	printk(KERN_ALERT "%p/" EDGE_LBL_IOC4
+		": unable to get PIO mapping for my MEM space\n", (void *)pci_handle);
+	return -1;
+    }
+
+    if ( !request_region((unsigned long)mem, sizeof(*mem), "sioc4_mem")) {
+	printk(KERN_ALERT
+		"%p/" EDGE_LBL_IOC4
+		": unable to get request region for my MEM space\n",
+		(void *)pci_handle);
+	return -1;
+    }		
+
+    /*
+     * Create the "ioc4" vertex which hangs off of
+     * the connect points.
+     * This code is slightly paranoid.
+     */
+    rc = hwgraph_path_add(conn_vhdl, EDGE_LBL_IOC4, &ioc4_vhdl);
+    ASSERT(rc == GRAPH_SUCCESS);
+
+    /*
+     * Allocate the soft structure, fill it in a bit,
+     * and attach it to the ioc4 vertex.
+     */
+    NEW(soft);
+
+    spin_lock_init(&soft->is_ir_lock);
+    soft->is_ioc4_vhdl = ioc4_vhdl;
+    soft->is_conn_vhdl = conn_vhdl;
+    soft->is_ioc4_mem = mem;
+    soft->is_pci_dev = pci_handle;
+
+    ioc4_soft_set(ioc4_vhdl, soft);
+
+    /* Init the IOC4 */
+
+    /* SN boot PROMs allocate the PCI
+     * space and set up the pci_addr fields.
+     * Other systems need to set the base address.
+     * This is handled automatically if the PCI infrastructure
+     * is used.
+     *
+     * No need to set the latency timer since the PCI
+     * infrastructure sets it to 1 us.
+     */
+
+    pci_read_config_dword(pci_handle, IOC4_PCI_SCR, &tmp);
+
+    pci_write_config_dword(pci_handle, IOC4_PCI_SCR, 
+	     tmp | PCI_CMD_BUS_MASTER | PCI_CMD_MEM_SPACE |
+	     PCI_CMD_PAR_ERR_RESP | PCI_CMD_SERR_ENABLE);
+
+    PCI_OUTW(&mem->sio_cr, (0xf << IOC4_SIO_CR_CMD_PULSE_SHIFT));
+
+    /* Enable serial port mode select generic PIO pins as outputs */
+    PCI_OUTW(&mem->gpcr_s, IOC4_GPCR_UART0_MODESEL | IOC4_GPCR_UART1_MODESEL);
+
+    /* Clear and disable all interrupts */
+    IOC4_WRITE_IEC(soft, ~0, ioc4_sio_intr_type);
+    PCI_OUTW(&mem->sio_ir, ~0);
+
+    IOC4_WRITE_IEC(soft, ~0, ioc4_other_intr_type);
+    PCI_OUTW(&mem->other_ir, ~0);
+
+    /*
+     * Alloc the IOC4 intr before attaching the subdevs, so the
+     * cpu handling the IOC4 intr is known (for setmustrun on
+     * the ioc4 ithreads).
+     */
+
+	/* attach interrupt handler */
+
+	ioc4_ss_connect_interrupt(pci_handle->irq, (void *)ioc4_intr, (void *)soft);
+
+    /* =============================================================
+     *				  Attach Sub-devices
+     *
+     * NB: As subdevs start calling pciio_driver_register(),
+     * we can stop explicitly calling subdev drivers.
+     *
+     * The drivers attached here have not been converted
+     * to stand on their own.  However, they *do* know
+     * to call ioc4_subdev_enabled() to decide whether
+     * to actually attach themselves.
+     *
+     * It would be nice if we could convert these
+     * few remaining drivers over so they would
+     * register as proper PCI device drivers ...
+     */
+
+    ioc4_serial_attach(conn_vhdl, (void *)soft->is_ioc4_mem);	/* DMA serial ports */
+
+    /* Normally we'd return 0 - but we need to get the ide driver init'd too. 
+     * Returning an error will keep the IOC4 on the pci list */
+    return -1;
+}
+
+
+/*
+ * ioc4_intr_connect:
+ * Arrange for interrupts for a sub-device
+ * to be delivered to the right bit of
+ * code with the right parameter.
+ *
+ * XXX- returning an error instead of panicing
+ * might be a good idea (think bugs in loadable
+ * ioc4 sub-devices).
+ */
+
+
+
+void
+ioc4_intr_connect(vertex_hdl_t conn_vhdl,
+		  ioc4_intr_type_t type,
+		  ioc4reg_t intrbits,
+		  ioc4_intr_func_f *intr,
+		  intr_arg_t info,
+		  vertex_hdl_t owner_vhdl,
+		  vertex_hdl_t intr_dev_vhdl)
+{
+    graph_error_t	    rc;
+    vertex_hdl_t	    ioc4_vhdl;
+    ioc4_soft_t		   *soft;
+    ioc4reg_t		    old, bits;
+    int			    i;
+
+    ASSERT((type == ioc4_sio_intr_type) || (type == ioc4_other_intr_type));
+
+    rc = hwgraph_traverse(conn_vhdl, EDGE_LBL_IOC4, &ioc4_vhdl);
+    if (rc != GRAPH_SUCCESS) {
+	printk(KERN_ALERT "ioc4_intr_connect(%p): ioc4_attach not yet called", (void *)owner_vhdl);
+	return;
+    }
+
+    soft = ioc4_soft_get(ioc4_vhdl);
+    ASSERT(soft != NULL);
+
+    /*
+     * Try to allocate a slot in the array
+     * that has been marked free; if there
+     * are none, extend the high water mark.
+     */
+    while (1) {
+	bits = atomic_read(&soft->is_intr_type[type].is_intr_ents_free);
+	if (bits == 0) {
+	    i = atomic_inc(&soft->is_intr_type[type].is_num_intrs) - 1;
+	    ASSERT(i < MAX_IOC4_INTR_ENTS || (printk("i %d\n", i), 0));
+	    break;
+	}
+	bits &= ~(bits - 1);	/* keep only the ls bit */
+	old = atomicClearInt(&soft->is_intr_type[type].is_intr_ents_free, bits);
+	if (bits & old) {
+		ioc4reg_t		shf;
+
+		i = 31;
+		if ((shf = (bits >> 16)))
+		    bits = shf;
+		else
+		    i -= 16;
+		if ((shf = (bits >> 8)))
+		    bits = shf;
+		else
+		    i -= 8;
+		if ((shf = (bits >> 4)))
+		    bits = shf;
+		else
+		    i -= 4;
+		if ((shf = (bits >> 2)))
+		    bits = shf;
+		else
+		    i -= 2;
+		if ((shf = (bits >> 1)))
+		    bits = shf;
+		else
+		    i -= 1;
+	    ASSERT(i < MAX_IOC4_INTR_ENTS || (printk("i %d\n", i), 0));
+	    break;
+	}
+    }
+
+    soft->is_intr_type[type].is_intr_info[i].sd_bits = intrbits;
+    soft->is_intr_type[type].is_intr_info[i].sd_intr = intr;
+    soft->is_intr_type[type].is_intr_info[i].sd_info = info;
+    soft->is_intr_type[type].is_intr_info[i].sd_vhdl = owner_vhdl;
+    soft->is_intr_type[type].is_intr_info[i].sd_soft = soft;
+
+    /* Make sure there are no bitmask overlaps */
+    {
+	ioc4reg_t		old;
+
+	old = atomicSetInt(&soft->is_intr_type[type].is_intr_bits_busy, intrbits);
+	if (old & intrbits) {
+	    printk("%p: trying to share ioc4 intr bits 0x%X\n",
+		    (void *)owner_vhdl, old & intrbits);
+
+#if DEBUG && IOC4_DEBUG
+	    {
+		int			x;
+
+		for (x = 0; x < i; x++)
+		    if (intrbits & soft->is_intr_type[type].is_intr_info[x].sd_bits) {
+			printk("%p: ioc4 intr bits 0x%X already call "
+				"0x%X(0x%X, ...)\n",
+				(void *)soft->is_intr_type[type].is_intr_info[x].sd_vhdl,
+				soft->is_intr_type[type].is_intr_info[i].sd_bits,
+				soft->is_intr_type[type].is_intr_info[i].sd_intr,
+				soft->is_intr_type[type].is_intr_info[i].sd_info);
+		    }
+	    }
+#endif
+	    panic("ioc4_intr_connect: no IOC4 interrupt source sharing allowed");
+	}
+    }
+}
+
+/*
+ * ioc4_intr_disconnect:
+ * Turn off interrupt request service for a
+ * specific service function and argument.
+ * Scans the array for connections to the specified
+ * function with the specified info and owner; turns off
+ * the bits specified in intrbits.  If this results in
+ * an empty entry, logs it in the free entry map.
+ */
+void
+ioc4_intr_disconnect(vertex_hdl_t conn_vhdl,
+		     ioc4_intr_type_t type,
+		     ioc4reg_t intrbits,
+		     ioc4_intr_func_f *intr,
+		     intr_arg_t info,
+		     vertex_hdl_t owner_vhdl)
+{
+    graph_error_t	    rc;
+    vertex_hdl_t	    ioc4_vhdl;
+    ioc4_soft_t		   *soft;
+    ioc4reg_t		    bits;
+    int			    i, num_intrs;
+
+    ASSERT((type == ioc4_sio_intr_type) || (type == ioc4_other_intr_type));
+
+    rc = hwgraph_traverse(conn_vhdl, EDGE_LBL_IOC4, &ioc4_vhdl);
+    if (rc != GRAPH_SUCCESS) {
+	printk(KERN_ALERT "%p: ioc4_intr_disconnect: ioc4_attach not yet called", (void *)owner_vhdl);
+	return;
+    }
+
+    soft = ioc4_soft_get(ioc4_vhdl);
+    ASSERT(soft != NULL);
+
+    num_intrs = (int)atomic_read(&soft->is_intr_type[type].is_num_intrs);
+    for (i = 0; i < num_intrs; ++i) {
+	if ((soft->is_intr_type[type].is_intr_info[i].sd_intr == intr) &&
+	    	(soft->is_intr_type[type].is_intr_info[i].sd_info == info) &&
+	    	(soft->is_intr_type[type].is_intr_info[i].sd_vhdl == owner_vhdl) &&
+	    	(bits = soft->is_intr_type[type].is_intr_info[i].sd_bits & intrbits)) {
+	    soft->is_intr_type[type].is_intr_info[i].sd_bits &= ~bits;
+	    atomicClearInt(&soft->is_intr_type[type].is_intr_bits_busy, bits);
+	    if (!(soft->is_intr_type[type].is_intr_info[i].sd_bits)) {
+		soft->is_intr_type[type].is_intr_info[i].sd_intr = NULL;
+		soft->is_intr_type[type].is_intr_info[i].sd_info = NULL;
+		soft->is_intr_type[type].is_intr_info[i].sd_vhdl = GRAPH_VERTEX_NONE;
+		atomicSetInt(&soft->is_intr_type[type].is_intr_ents_free, 1 << i);
+	    }
+	}
+    }
+}
+
+/* Top level IOC4 interrupt handler.  Farms out the interrupt to
+ * the various IOC4 device drivers.
+ */
+
+void
+ioc4_intr(int irq, void *arg, struct pt_regs *regs)
+{
+    ioc4_soft_t		   *soft;
+    ioc4reg_t		    this_ir;
+    ioc4reg_t		    this_mir;
+    int			    x, num_intrs = 0;
+    ioc4_intr_type_t        t;
+
+    soft = (ioc4_soft_t *)arg;
+
+    if (!soft)
+	return;			/* Polled but no console ioc4 registered */
+
+    for (t = ioc4_first_intr_type; t < ioc4_num_intr_types; t++) {
+        num_intrs = (int)atomic_read(&soft->is_intr_type[t].is_num_intrs);
+
+        this_mir = this_ir = ioc4_pending_intrs(soft, t);
+#ifdef DEBUG_INTERRUPTS
+	printk("%s : %d : this_mir 0x%x num_intrs %d\n", __FUNCTION__, __LINE__, this_mir, num_intrs);
+#endif
+
+        /* Farm out the interrupt to the various drivers depending on
+         * which interrupt bits are set.
+	 */
+        for (x = 0; x < num_intrs; x++) {
+		struct ioc4_intr_info  *ii = &soft->is_intr_type[t].is_intr_info[x];
+		if ((this_mir = this_ir & ii->sd_bits)) {
+			/* Disable owned interrupts, and call the interrupt handler */
+			IOC4_WRITE_IEC(soft, ii->sd_bits, t);
+			ii->sd_intr(ii->sd_info, this_mir);
+			this_ir &= ~this_mir;
+		}
+	}
+
+	if (this_ir)
+		printk(KERN_ALERT "unknown IOC4 %s interrupt 0x%x, sio_ir = 0x%x, sio_ies = 0x%x, other_ir = 0x%x, other_ies = 0x%x\n",
+				(t == ioc4_sio_intr_type) ? "sio" : "other",
+				this_ir,
+				soft->is_ioc4_mem->sio_ir,
+				soft->is_ioc4_mem->sio_ies_ro,
+				soft->is_ioc4_mem->other_ir,
+				soft->is_ioc4_mem->other_ies_ro);
+    }
+#ifdef DEBUG_INTERRUPTS
+    {
+	ioc4_mem_t  *mem = soft->is_ioc4_mem;
+	spinlock_t  *lp = &soft->is_ir_lock;
+	unsigned long           s;
+
+	spin_lock_irqsave(lp, s);
+	printk("%s : %d : sio_ir 0x%x sio_ies_ro 0x%x other_ir 0x%x other_ies_ro 0x%x mask 0x%x\n",
+			__FUNCTION__, __LINE__,
+			mem->sio_ir,
+			mem->sio_ies_ro,
+			mem->other_ir,
+			mem->other_ies_ro,
+			IOC4_OTHER_IR_ATA_INT | IOC4_OTHER_IR_ATA_MEMERR);
+
+	spin_unlock_irqrestore(lp, s);
+    }
+#endif
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/sn2/ioc4/sio_ioc4.c linux-2.4.23-pre8/arch/ia64/sn/io/sn2/ioc4/sio_ioc4.c
--- linux-2.4.22/arch/ia64/sn/io/sn2/ioc4/sio_ioc4.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/sn2/ioc4/sio_ioc4.c	2003-10-22 22:48:39.000000000 +0000
@@ -0,0 +1,2266 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+/*
+ * This is a lower level module for the modular serial I/O driver. This
+ * module implements all hardware dependent functions for doing serial
+ * I/O on the IOC4 serial ports.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/iograph.h>
+#include <asm/param.h>
+#include <asm/atomic.h>
+#include <asm/delay.h>
+#include <asm/semaphore.h>
+#include <asm/sn/pio.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/io.h>
+#include <asm/sn/pci/pci_defs.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/ioc4.h>
+#include <asm/sn/serialio.h>
+#include <asm/sn/uart16550.h>
+
+/* #define IOC4_SIO_DEBUG */
+/* define USE_64BIT_DMA */
+
+#define PENDING(port) (PCI_INW(&(port)->ip_ioc4->sio_ir) & port->ip_ienb)
+
+/* Default to 4k buffers */
+#ifdef IOC4_1K_BUFFERS
+#define RING_BUF_SIZE 1024
+#define IOC4_BUF_SIZE_BIT 0
+#define PROD_CONS_MASK IOC4_PROD_CONS_PTR_1K
+#else
+#define RING_BUF_SIZE 4096
+#define IOC4_BUF_SIZE_BIT IOC4_SBBR_L_SIZE
+#define PROD_CONS_MASK IOC4_PROD_CONS_PTR_4K
+#endif
+
+#define TOTAL_RING_BUF_SIZE (RING_BUF_SIZE * 4)
+
+#if PAGE_SIZE < TOTAL_RING_BUF_SIZE
+#include <sys/pfdat.h>
+#endif
+
+
+#ifdef DPRINTF
+#define dprintf(x) printk x
+#else
+#define dprintf(x)
+#endif
+
+#define	NEWA(ptr,n)	(ptr = snia_kmem_zalloc((n)*sizeof (*(ptr))))
+
+#define	contig_memalloc(a,b,c)	kmem_zalloc(PAGE_SIZE * (a))
+#define sio_port_islocked(a)	0	// FIXME: ?????
+
+#define KM_PHYSCONTIG   0x0008
+#define VM_DIRECT       KM_PHYSCONTIG
+#define VM_PHYSCONTIG   KM_PHYSCONTIG
+
+#ifdef DEBUG
+#define PROGRESS()	printk("%s : %d\n", __FUNCTION__, __LINE__)
+#define NOT_PROGRESS()	printk("%s : %d - Error\n", __FUNCTION__, __LINE__)
+#else
+#define PROGRESS()	;
+#define NOT_PROGRESS()	;
+#endif
+
+static __inline__ void *
+kvpalloc(size_t size, int flags, int colour)
+{
+        if (flags & (VM_DIRECT|VM_PHYSCONTIG)) {
+                int order = 0;
+                while ((PAGE_SIZE << order) < (size << PAGE_SHIFT))
+                        order++;
+                return (void *) __get_free_pages(GFP_KERNEL, order);
+        } else
+                return vmalloc(size << PAGE_SHIFT);
+}
+
+/* Local port info for the IOC4 serial ports.  This contains as its
+ * first member the global sio port private data.
+ */
+typedef struct ioc4port {
+    sioport_t		ip_sioport;	/* Must be first struct entry! */
+
+    vertex_hdl_t	ip_conn_vhdl;	/* vhdl to use for pciio requests */
+    vertex_hdl_t	ip_port_vhdl;	/* vhdl for the serial port */
+
+    /* Base piomap addr of the ioc4 board this port is on
+     * and associated serial map;  serial map includes uart registers.
+     */
+    ioc4_mem_t	       *ip_ioc4;
+    ioc4_sregs_t       *ip_serial;
+    ioc4_uart_t        *ip_uart;
+
+    /* Ring buffer page for this port */
+    caddr_t		ip_ring_buf_k0;	/* Ring buffer location in K0 space */
+
+    /* Rings for this port */
+    struct ring	       *ip_inring;
+    struct ring	       *ip_outring;
+
+    /* Hook to port specific values for this port */
+    struct hooks       *ip_hooks;
+
+    int			ip_flags;
+
+    /* Cache of DCD/CTS bits last received */
+    char                ip_modem_bits;
+
+    /* Various rx/tx parameters */
+    int                 ip_baud;
+    int                 ip_tx_lowat;
+    int                 ip_rx_timeout;
+
+    /* Copy of notification bits */
+    int                 ip_notify;
+
+    /* Shadow copies of various registers so we don't need to PIO
+     * read them constantly
+     */
+    ioc4reg_t           ip_ienb;          /* Enabled interrupts */
+
+    ioc4reg_t           ip_sscr;
+
+    ioc4reg_t           ip_tx_prod;
+    ioc4reg_t           ip_rx_cons;
+
+    /* Back pointer to ioc4 soft area */
+    void               *ip_ioc4_soft;
+} ioc4port_t;
+
+#if DEBUG
+#define     MAXSAVEPORT 256
+static int         next_saveport = 0;
+static ioc4port_t *saveport[MAXSAVEPORT];
+#endif
+
+/* TX low water mark.  We need to notify the driver whenever TX is getting
+ * close to empty so it can refill the TX buffer and keep things going.
+ * Let's assume that if we interrupt 1 ms before the TX goes idle, we'll
+ * have no trouble getting in more chars in time (I certainly hope so).
+ */
+#define TX_LOWAT_LATENCY      1000
+#define TX_LOWAT_HZ          (1000000 / TX_LOWAT_LATENCY)
+#define TX_LOWAT_CHARS(baud) (baud / 10 / TX_LOWAT_HZ)
+
+/* Flags per port */
+#define INPUT_HIGH	0x01
+#define DCD_ON		0x02
+#define LOWAT_WRITTEN	0x04
+#define READ_ABORTED	0x08
+#define TX_DISABLED	0x10
+
+/* Get local port type from global sio port type */
+#define LPORT(port) ((ioc4port_t *) (port))
+
+/* Get global port from local port type */
+#define GPORT(port) ((sioport_t *) (port))
+
+/* Since each port has different register offsets and bitmasks
+ * for everything, we'll store those that we need in tables so we
+ * don't have to be constantly checking the port we are dealing with.
+ */
+struct hooks {
+    ioc4reg_t intr_delta_dcd;
+    ioc4reg_t intr_delta_cts;
+    ioc4reg_t intr_tx_mt;
+    ioc4reg_t intr_rx_timer;
+    ioc4reg_t intr_rx_high;
+    ioc4reg_t intr_tx_explicit;
+    ioc4reg_t intr_dma_error;
+    ioc4reg_t intr_clear;
+    ioc4reg_t intr_all;
+    char      rs422_select_pin;
+};
+
+static struct hooks hooks_array[4] =
+{
+    /* Values for port 0 */
+    {
+	IOC4_SIO_IR_S0_DELTA_DCD,
+	IOC4_SIO_IR_S0_DELTA_CTS,
+	IOC4_SIO_IR_S0_TX_MT,
+	IOC4_SIO_IR_S0_RX_TIMER,
+	IOC4_SIO_IR_S0_RX_HIGH,
+	IOC4_SIO_IR_S0_TX_EXPLICIT,
+	IOC4_OTHER_IR_S0_MEMERR,
+	(IOC4_SIO_IR_S0_TX_MT | IOC4_SIO_IR_S0_RX_FULL |
+         IOC4_SIO_IR_S0_RX_HIGH | IOC4_SIO_IR_S0_RX_TIMER |
+         IOC4_SIO_IR_S0_DELTA_DCD | IOC4_SIO_IR_S0_DELTA_CTS |
+	 IOC4_SIO_IR_S0_INT | IOC4_SIO_IR_S0_TX_EXPLICIT),
+	IOC4_SIO_IR_S0,
+	IOC4_GPPR_UART0_MODESEL_PIN,
+    },
+
+    /* Values for port 1 */
+    {
+	IOC4_SIO_IR_S1_DELTA_DCD,
+	IOC4_SIO_IR_S1_DELTA_CTS,
+	IOC4_SIO_IR_S1_TX_MT,
+	IOC4_SIO_IR_S1_RX_TIMER,
+	IOC4_SIO_IR_S1_RX_HIGH,
+	IOC4_SIO_IR_S1_TX_EXPLICIT,
+	IOC4_OTHER_IR_S1_MEMERR,
+	(IOC4_SIO_IR_S1_TX_MT | IOC4_SIO_IR_S1_RX_FULL |
+         IOC4_SIO_IR_S1_RX_HIGH | IOC4_SIO_IR_S1_RX_TIMER |
+         IOC4_SIO_IR_S1_DELTA_DCD | IOC4_SIO_IR_S1_DELTA_CTS |
+	 IOC4_SIO_IR_S1_INT | IOC4_SIO_IR_S1_TX_EXPLICIT),
+	IOC4_SIO_IR_S1,
+	IOC4_GPPR_UART1_MODESEL_PIN,
+    },
+
+    /* Values for port 2 */
+    {
+	IOC4_SIO_IR_S2_DELTA_DCD,
+	IOC4_SIO_IR_S2_DELTA_CTS,
+	IOC4_SIO_IR_S2_TX_MT,
+	IOC4_SIO_IR_S2_RX_TIMER,
+	IOC4_SIO_IR_S2_RX_HIGH,
+	IOC4_SIO_IR_S2_TX_EXPLICIT,
+	IOC4_OTHER_IR_S2_MEMERR,
+	(IOC4_SIO_IR_S2_TX_MT | IOC4_SIO_IR_S2_RX_FULL |
+         IOC4_SIO_IR_S2_RX_HIGH | IOC4_SIO_IR_S2_RX_TIMER |
+         IOC4_SIO_IR_S2_DELTA_DCD | IOC4_SIO_IR_S2_DELTA_CTS |
+	 IOC4_SIO_IR_S2_INT | IOC4_SIO_IR_S2_TX_EXPLICIT),
+	IOC4_SIO_IR_S2,
+	IOC4_GPPR_UART2_MODESEL_PIN,
+    },
+
+    /* Values for port 3 */
+    {
+	IOC4_SIO_IR_S3_DELTA_DCD,
+	IOC4_SIO_IR_S3_DELTA_CTS,
+	IOC4_SIO_IR_S3_TX_MT,
+	IOC4_SIO_IR_S3_RX_TIMER,
+	IOC4_SIO_IR_S3_RX_HIGH,
+	IOC4_SIO_IR_S3_TX_EXPLICIT,
+	IOC4_OTHER_IR_S3_MEMERR,
+	(IOC4_SIO_IR_S3_TX_MT | IOC4_SIO_IR_S3_RX_FULL |
+         IOC4_SIO_IR_S3_RX_HIGH | IOC4_SIO_IR_S3_RX_TIMER |
+         IOC4_SIO_IR_S3_DELTA_DCD | IOC4_SIO_IR_S3_DELTA_CTS |
+	 IOC4_SIO_IR_S3_INT | IOC4_SIO_IR_S3_TX_EXPLICIT),
+	IOC4_SIO_IR_S3,
+	IOC4_GPPR_UART3_MODESEL_PIN,
+    }
+};
+
+/* Macros to get into the port hooks.  Require a variable called
+ * hooks set to port->hooks
+ */
+#define H_INTR_TX_MT	   hooks->intr_tx_mt
+#define H_INTR_RX_TIMER    hooks->intr_rx_timer
+#define H_INTR_RX_HIGH	   hooks->intr_rx_high
+#define H_INTR_TX_EXPLICIT hooks->intr_tx_explicit
+#define H_INTR_DMA_ERROR   hooks->intr_dma_error
+#define H_INTR_CLEAR	   hooks->intr_clear
+#define H_INTR_DELTA_DCD   hooks->intr_delta_dcd
+#define H_INTR_DELTA_CTS   hooks->intr_delta_cts
+#define H_INTR_ALL	   hooks->intr_all
+#define H_RS422		   hooks->rs422_select_pin
+
+/* A ring buffer entry */
+struct ring_entry {
+    union {
+	struct {
+	    uint32_t alldata;
+	    uint32_t allsc;
+	} all;
+	struct {
+	    char data[4];	/* data bytes */
+	    char sc[4];		/* status/control */
+	} s;
+    } u;
+};
+
+/* Test the valid bits in any of the 4 sc chars using "allsc" member */
+#define RING_ANY_VALID \
+	((uint32_t) (IOC4_RXSB_MODEM_VALID | IOC4_RXSB_DATA_VALID) * 0x01010101)
+
+#define ring_sc     u.s.sc
+#define ring_data   u.s.data
+#define ring_allsc  u.all.allsc
+
+/* Number of entries per ring buffer. */
+#define ENTRIES_PER_RING (RING_BUF_SIZE / (int) sizeof(struct ring_entry))
+
+/* An individual ring */
+struct ring {
+    struct ring_entry entries[ENTRIES_PER_RING];
+};
+
+/* The whole enchilada */
+struct ring_buffer {
+        struct ring TX_0_OR_2;
+        struct ring RX_0_OR_2;
+        struct ring TX_1_OR_3;
+        struct ring RX_1_OR_3;
+};
+
+/* Get a ring from a port struct */
+#define RING(port, which) \
+    &(((struct ring_buffer *) ((port)->ip_ring_buf_k0))->which)
+
+/* Local functions: */
+static int ioc4_open		(sioport_t *port);
+static int ioc4_config		(sioport_t *port, int baud, int byte_size,
+				 int stop_bits, int parenb, int parodd);
+static int ioc4_enable_hfc	(sioport_t *port, int enable);
+static int ioc4_set_extclk	(sioport_t *port, int clock_factor);
+
+/* Data transmission */
+static int do_ioc4_write	(sioport_t *port, char *buf, int len);
+static int ioc4_write		(sioport_t *port, char *buf, int len);
+static int ioc4_sync_write	(sioport_t *port, char *buf, int len);
+static void ioc4_wrflush	(sioport_t *port);
+static int ioc4_break		(sioport_t *port, int brk);
+static int ioc4_enable_tx	(sioport_t *port, int enb);
+
+/* Data reception */
+static int ioc4_read		(sioport_t *port, char *buf, int len);
+
+/* Event notification */
+static int ioc4_notification	(sioport_t *port, int mask, int on);
+static int ioc4_rx_timeout	(sioport_t *port, int timeout);
+
+/* Modem control */
+static int ioc4_set_DTR		(sioport_t *port, int dtr);
+static int ioc4_set_RTS		(sioport_t *port, int rts);
+static int ioc4_query_DCD	(sioport_t *port);
+static int ioc4_query_CTS	(sioport_t *port);
+
+/* Output mode */
+static int ioc4_set_proto	(sioport_t *port, enum sio_proto proto);
+
+/* User mapped driver support */
+static int ioc4_get_mapid	(sioport_t *port, void *arg);
+static int ioc4_set_sscr	(sioport_t *port, int arg, int flag);
+
+static struct serial_calldown ioc4_calldown = {
+    ioc4_open,
+    ioc4_config,
+    ioc4_enable_hfc,
+    ioc4_set_extclk,
+    ioc4_write,
+    ioc4_sync_write,
+    ioc4_wrflush,	/* du flush */
+    ioc4_break,
+    ioc4_enable_tx,
+    ioc4_read,
+    ioc4_notification,
+    ioc4_rx_timeout,
+    ioc4_set_DTR,
+    ioc4_set_RTS,
+    ioc4_query_DCD,
+    ioc4_query_CTS,
+    ioc4_set_proto,
+    ioc4_get_mapid,
+    0,
+    0,
+    ioc4_set_sscr
+};
+
+/* Baud rate stuff */
+#define SET_BAUD(p, b) set_baud_ti(p, b)
+static int set_baud_ti(ioc4port_t *, int);
+
+#ifdef DEBUG
+/* Performance characterization logging */
+#define DEBUGINC(x,i) stats.x += i
+
+static struct {
+
+    /* Ports present */
+    uint ports;
+
+    /* Ports killed */
+    uint killed;
+
+    /* Interrupt counts */
+    uint total_intr;
+    uint port_0_intr;
+    uint port_1_intr;
+    uint ddcd_intr;
+    uint dcts_intr;
+    uint rx_timer_intr;
+    uint rx_high_intr;
+    uint explicit_intr;
+    uint mt_intr;
+    uint mt_lowat_intr;
+
+    /* Write characteristics */
+    uint write_bytes;
+    uint write_cnt;
+    uint wrote_bytes;
+    uint tx_buf_used;
+    uint tx_buf_cnt;
+    uint tx_pio_cnt;691
+
+    /* Read characteristics */
+    uint read_bytes;
+    uint read_cnt;
+    uint drain;
+    uint drainwait;
+    uint resetdma;
+    uint read_ddcd;
+    uint rx_overrun;
+    uint parity;
+    uint framing;
+    uint brk;
+    uint red_bytes;
+    uint rx_buf_used;
+    uint rx_buf_cnt;
+
+    /* Errors */
+    uint dma_lost;
+    uint read_aborted;
+    uint read_aborted_detected;
+} stats;
+
+#else
+#define DEBUGINC(x,i)
+#endif
+
+/* Infinite loop detection.
+ */
+#define MAXITER 1000000
+#define SPIN(cond, success) \
+{ \
+	 int spiniter = 0; \
+	 success = 1; \
+	 while(cond) { \
+		 spiniter++; \
+		 if (spiniter > MAXITER) { \
+			 success = 0; \
+			 break; \
+		 } \
+	 } \
+}
+
+
+static iopaddr_t
+ring_dmatrans(vertex_hdl_t conn_vhdl, caddr_t vaddr)
+{
+    extern iopaddr_t pciio_dma_addr (vertex_hdl_t, device_desc_t, paddr_t,
+                                     size_t, pciio_dmamap_t *, unsigned);
+    iopaddr_t	paddr = (iopaddr_t)vaddr;
+
+    if (conn_vhdl != GRAPH_VERTEX_NONE)
+#ifdef	USE_64BIT_DMA
+        /* Use 64-bit DMA address when the IOC4 supports it */
+        return pciio_dmatrans_addr (conn_vhdl, 0, paddr, TOTAL_RING_BUF_SIZE, PCIIO_DMA_A64 | PCIIO_BYTE_STREAM);
+
+#else
+        /* Use 32-bit DMA address for current IOC4 */ 
+	return pciio_dma_addr (conn_vhdl, 0, paddr, TOTAL_RING_BUF_SIZE, NULL, PCIIO_BYTE_STREAM);
+#endif
+
+    return paddr;
+}
+
+
+/* If interrupt routine called enable_intrs, then would need to write
+ * mask_enable_intrs() routine.
+ */
+static inline void
+mask_disable_intrs(ioc4port_t *port, ioc4reg_t mask)
+{
+    port->ip_ienb &= ~mask;
+}
+
+
+static void
+enable_intrs(ioc4port_t *port, ioc4reg_t mask)
+{
+    struct hooks *hooks = port->ip_hooks;
+ 
+    if ((port->ip_ienb & mask) != mask) {
+	IOC4_WRITE_IES(port->ip_ioc4_soft, mask, ioc4_sio_intr_type);
+	port->ip_ienb |= mask;
+    }
+
+    if (port->ip_ienb)
+        IOC4_WRITE_IES(port->ip_ioc4_soft, H_INTR_DMA_ERROR, ioc4_other_intr_type);
+}
+
+
+static void
+disable_intrs(ioc4port_t *port, ioc4reg_t mask)
+{
+    struct hooks *hooks = port->ip_hooks;
+
+    if (port->ip_ienb & mask) {
+	IOC4_WRITE_IEC(port->ip_ioc4_soft, mask, ioc4_sio_intr_type);
+	port->ip_ienb &= ~mask;
+    }
+
+    if (!port->ip_ienb)
+        IOC4_WRITE_IEC(port->ip_ioc4_soft, H_INTR_DMA_ERROR, ioc4_other_intr_type);
+}
+
+
+/* Service any pending interrupts on the given port */
+static void
+ioc4_serial_intr(intr_arg_t arg, ioc4reg_t sio_ir)
+{
+    ioc4port_t   *port = (ioc4port_t *) arg;
+    sioport_t    *gp = GPORT(port);
+    struct hooks *hooks = port->ip_hooks;
+    unsigned      rx_high_rd_aborted = 0;
+    unsigned int  flags;
+
+    PROGRESS();
+#ifdef NOT_YET
+    ASSERT(sio_port_islocked(gp) == 0);
+#endif
+
+    /* Possible race condition here: The TX_MT interrupt bit may be
+     * cleared without the intervention of the interrupt handler,
+     * e.g. by a write.  If the top level interrupt handler reads a
+     * TX_MT, then some other processor does a write, starting up
+     * output, then we come in here, see the TX_MT and stop DMA, the
+     * output started by the other processor will hang.  Thus we can
+     * only rely on TX_MT being legitimate if it is read while the
+     * port lock is held.  Therefore this bit must be ignored in the
+     * passed in interrupt mask which was read by the top level
+     * interrupt handler since the port lock was not held at the time
+     * it was read.  We can only rely on this bit being accurate if it
+     * is read while the port lock is held.  So we'll clear it for now,
+     * and reload it later once we have the port lock.
+     */
+    sio_ir &= ~(H_INTR_TX_MT);
+
+    SIO_LOCK_PORT(gp, flags);
+
+    dprintf(("interrupt: sio_ir 0x%x\n", sio_ir));
+
+    do {
+	ioc4reg_t shadow;
+
+	/* Handle a DCD change */
+	if (sio_ir & H_INTR_DELTA_DCD) {
+	    DEBUGINC(ddcd_intr, 1);
+
+	    PROGRESS();
+	    /* ACK the interrupt */
+	    PCI_OUTW(&port->ip_ioc4->sio_ir, H_INTR_DELTA_DCD);
+
+	    /* If DCD has raised, notify upper layer.  Otherwise
+	     * wait for a record to be posted to notify of a dropped DCD.
+	     */
+	    shadow = PCI_INW(&port->ip_serial->shadow);
+	    
+            if (port->ip_notify & N_DDCD) {
+		PROGRESS();
+                if (shadow & IOC4_SHADOW_DCD)   /* Notify upper layer of DCD */
+                        UP_DDCD(gp, 1);
+                else
+                        port->ip_flags |= DCD_ON;  /* Flag delta DCD/no DCD */
+	    }
+	}
+
+	/* Handle a CTS change */
+	if (sio_ir & H_INTR_DELTA_CTS) {
+	    DEBUGINC(dcts_intr, 1);
+	    PROGRESS();
+
+	    /* ACK the interrupt */
+	    PCI_OUTW(&port->ip_ioc4->sio_ir, H_INTR_DELTA_CTS);
+
+	    shadow = PCI_INW(&port->ip_serial->shadow);
+
+	    /* Notify upper layer */
+	    if (port->ip_notify & N_DCTS) {
+		if (shadow & IOC4_SHADOW_CTS)
+		    UP_DCTS(gp, 1);
+		else
+		    UP_DCTS(gp, 0);
+	    }
+	}
+
+	/* RX timeout interrupt.  Must be some data available.  Put this
+	 * before the check for RX_HIGH since servicing this condition
+	 * may cause that condition to clear.
+	 */
+	if (sio_ir & H_INTR_RX_TIMER) {
+	    PROGRESS();
+	    DEBUGINC(rx_timer_intr, 1);
+
+	    /* ACK the interrupt */
+	    PCI_OUTW(&port->ip_ioc4->sio_ir, H_INTR_RX_TIMER);
+
+	    if (port->ip_notify & N_DATA_READY)
+		UP_DATA_READY(gp);
+	}
+
+	/* RX high interrupt. Must be after RX_TIMER.
+	 */
+	else if (sio_ir & H_INTR_RX_HIGH) {
+	    DEBUGINC(rx_high_intr, 1);
+
+	    PROGRESS();
+	    /* Data available, notify upper layer */
+	    if (port->ip_notify & N_DATA_READY)
+		UP_DATA_READY(gp);
+
+	    /* We can't ACK this interrupt.  If up_data_ready didn't
+	     * cause the condition to clear, we'll have to disable
+	     * the interrupt until the data is drained by the upper layer.
+	     * If the read was aborted, don't disable the interrupt as
+	     * this may cause us to hang indefinitely.  An aborted read
+	     * generally means that this interrupt hasn't been delivered
+	     * to the cpu yet anyway, even though we see it as asserted 
+	     * when we read the sio_ir.
+	     */
+	    if ((sio_ir = PENDING(port)) & H_INTR_RX_HIGH) {
+		PROGRESS();
+		if ((port->ip_flags & READ_ABORTED) == 0) {
+		    mask_disable_intrs(port, H_INTR_RX_HIGH);
+		    port->ip_flags |= INPUT_HIGH;
+		}
+		else {
+		    DEBUGINC(read_aborted_detected, 1);
+		    /* We will be stuck in this loop forever,
+		     * higher level will never get time to finish
+		     */
+		    rx_high_rd_aborted++;
+		}
+	    }
+	}
+
+	/* We got a low water interrupt: notify upper layer to
+	 * send more data.  Must come before TX_MT since servicing
+	 * this condition may cause that condition to clear.
+	 */
+	if (sio_ir & H_INTR_TX_EXPLICIT) {
+	    DEBUGINC(explicit_intr, 1);
+	    PROGRESS();
+
+	    port->ip_flags &= ~LOWAT_WRITTEN;
+
+	    /* ACK the interrupt */
+	    PCI_OUTW(&port->ip_ioc4->sio_ir, H_INTR_TX_EXPLICIT);
+
+	    if (port->ip_notify & N_OUTPUT_LOWAT)
+		UP_OUTPUT_LOWAT(gp);
+	}
+
+	/* Handle TX_MT.  Must come after TX_EXPLICIT.
+	 */
+	else if (sio_ir & H_INTR_TX_MT) {
+	    DEBUGINC(mt_intr, 1);
+	    PROGRESS();
+
+	    /* If the upper layer is expecting a lowat notification
+	     * and we get to this point it probably means that for
+	     * some reason the TX_EXPLICIT didn't work as expected
+	     * (that can legitimately happen if the output buffer is
+	     * filled up in just the right way).  So sent the notification
+	     * now.
+	     */
+	    if (port->ip_notify & N_OUTPUT_LOWAT) {
+		DEBUGINC(mt_lowat_intr, 1);
+		PROGRESS();
+
+		if (port->ip_notify & N_OUTPUT_LOWAT)
+		    UP_OUTPUT_LOWAT(gp);
+
+		/* We need to reload the sio_ir since the upcall may
+		 * have caused another write to occur, clearing
+		 * the TX_MT condition.
+		 */
+		sio_ir = PENDING(port);
+	    }
+
+	    /* If the TX_MT condition still persists even after the upcall,
+	     * we've got some work to do.
+	     */
+	    if (sio_ir & H_INTR_TX_MT) {
+
+		PROGRESS();
+
+		/* If we are not currently expecting DMA input, and the
+		 * transmitter has just gone idle, there is no longer any
+		 * reason for DMA, so disable it.
+		 */
+		if (!(port->ip_notify & (N_DATA_READY | N_DDCD))) {
+		    ASSERT(port->ip_sscr & IOC4_SSCR_DMA_EN);
+		    port->ip_sscr &= ~IOC4_SSCR_DMA_EN;
+		    PCI_OUTW(&port->ip_serial->sscr, port->ip_sscr);
+		}
+
+		/* Prevent infinite TX_MT interrupt */
+		mask_disable_intrs(port, H_INTR_TX_MT);
+	    }
+	}
+
+	sio_ir = PENDING(port);
+
+	/* if the read was aborted and only H_INTR_RX_HIGH,
+	 * clear H_INTR_RX_HIGH, so we do not loop forever.
+	 */
+
+	if ( rx_high_rd_aborted && (sio_ir == H_INTR_RX_HIGH) ) {
+	    sio_ir &= ~H_INTR_RX_HIGH;
+	}
+    } while (sio_ir & H_INTR_ALL);
+
+    SIO_UNLOCK_PORT(gp, flags);
+
+    /* Re-enable interrupts before returning from interrupt handler.
+     * Getting interrupted here is okay.  It'll just v() our semaphore, and
+     * we'll come through the loop again.
+     */
+
+    IOC4_WRITE_IES(port->ip_ioc4_soft, port->ip_ienb, ioc4_sio_intr_type);
+}
+
+
+/*ARGSUSED*/
+
+/* Service any pending DMA error interrupts on the given port */
+static void
+ioc4_dma_error_intr(intr_arg_t arg, ioc4reg_t other_ir)
+{
+    ioc4port_t   *port = (ioc4port_t *) arg;
+    sioport_t    *gp = GPORT(port);
+    struct hooks *hooks = port->ip_hooks;
+    unsigned int flags;
+
+    SIO_LOCK_PORT(gp, flags);
+
+    dprintf(("interrupt: other_ir 0x%x\n", other_ir));
+
+    /* ACK the interrupt */
+    PCI_OUTW(&port->ip_ioc4->other_ir, H_INTR_DMA_ERROR);
+
+    printk( "DMA error on serial port %p\n", (void *)port->ip_port_vhdl);
+
+    if (port->ip_ioc4->pci_err_addr_l & IOC4_PCI_ERR_ADDR_VLD) {
+        printk( "PCI error address is 0x%lx, master is serial port %c %s\n", 
+                ((uint64_t) port->ip_ioc4->pci_err_addr_h << 32) |
+                (port->ip_ioc4->pci_err_addr_l & IOC4_PCI_ERR_ADDR_ADDR_MSK),
+                '1' + (char) ((port->ip_ioc4->pci_err_addr_l &
+                                         IOC4_PCI_ERR_ADDR_MST_NUM_MSK) >> 1),
+                (port->ip_ioc4->pci_err_addr_l & IOC4_PCI_ERR_ADDR_MST_TYP_MSK) 
+                                                               ? "RX" : "TX");
+
+        if (port->ip_ioc4->pci_err_addr_l & IOC4_PCI_ERR_ADDR_MUL_ERR)
+            printk( "Multiple errors occurred\n"); 
+    }
+
+    SIO_UNLOCK_PORT(gp, flags);
+
+    /* Re-enable DMA error interrupts */
+    IOC4_WRITE_IES(port->ip_ioc4_soft, H_INTR_DMA_ERROR, ioc4_other_intr_type);
+}
+
+
+/* Baud rate setting code */
+static int
+set_baud_ti(ioc4port_t *port, int baud)
+{
+    int            actual_baud;
+    int            diff;
+    int            lcr;
+    unsigned short divisor;
+
+    divisor = SER_DIVISOR(baud, IOC4_SER_XIN_CLK);
+    if (!divisor)
+        return(1);
+    actual_baud = DIVISOR_TO_BAUD(divisor, IOC4_SER_XIN_CLK);
+
+    diff = actual_baud - baud;
+    if (diff < 0)
+        diff = -diff;
+
+    /* If we're within 1%, we've found a match */
+    if (diff * 100 > actual_baud)
+        return(1);
+
+    lcr = PCI_INB(&port->ip_uart->i4u_lcr);
+
+    PCI_OUTB(&port->ip_uart->i4u_lcr, lcr | LCR_DLAB);
+
+    PCI_OUTB(&port->ip_uart->i4u_dll, (char) divisor); 
+
+    PCI_OUTB(&port->ip_uart->i4u_dlm, (char) (divisor >> 8));
+
+    PCI_OUTB(&port->ip_uart->i4u_lcr, lcr);
+
+    return(0);
+}
+
+
+/* Initialize the sio and ioc4 hardware for a given port */
+static int
+hardware_init(ioc4port_t *port)
+{
+    ioc4reg_t     sio_cr;
+    struct hooks *hooks = port->ip_hooks;
+
+    DEBUGINC(ports, 1);
+
+    /* Idle the IOC4 serial interface */
+    PCI_OUTW(&port->ip_serial->sscr, IOC4_SSCR_RESET);
+
+    /* Wait until any pending bus activity for this port has ceased */
+    do sio_cr = PCI_INW(&port->ip_ioc4->sio_cr);
+    while(!(sio_cr & IOC4_SIO_CR_SIO_DIAG_IDLE));
+
+    /* Finish reset sequence */
+    PCI_OUTW(&port->ip_serial->sscr, 0);
+
+    /* Once RESET is done, reload cached tx_prod and rx_cons values
+     * and set rings to empty by making prod == cons
+     */
+    port->ip_tx_prod = PCI_INW(&port->ip_serial->stcir) & PROD_CONS_MASK;
+    PCI_OUTW(&port->ip_serial->stpir, port->ip_tx_prod);
+
+    port->ip_rx_cons = PCI_INW(&port->ip_serial->srpir) & PROD_CONS_MASK;
+    PCI_OUTW(&port->ip_serial->srcir, port->ip_rx_cons);
+
+    /* Disable interrupts for this 16550 */
+    PCI_OUTB(&port->ip_uart->i4u_lcr, 0); /* clear DLAB */
+    PCI_OUTB(&port->ip_uart->i4u_ier, 0);
+
+    /* Set the default baud */
+    SET_BAUD(port, port->ip_baud);
+
+    /* Set line control to 8 bits no parity */
+    PCI_OUTB(&port->ip_uart->i4u_lcr, LCR_BITS8 | LCR_1_STOP_BITS);
+   
+    /* Enable the FIFOs */ 
+    PCI_OUTB(&port->ip_uart->i4u_fcr, FCR_FIFOEN);
+    /* then reset 16550 FIFOs */
+    PCI_OUTB(&port->ip_uart->i4u_fcr,
+             FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO);
+
+    /* Clear modem control register */
+    PCI_OUTB(&port->ip_uart->i4u_mcr, 0);
+
+    /* Clear deltas in modem status register */
+    PCI_INB(&port->ip_uart->i4u_msr);
+
+    /* Only do this once per port pair */
+    if (port->ip_hooks == &hooks_array[0] || port->ip_hooks == &hooks_array[2]) {
+	iopaddr_t             ring_pci_addr;
+        volatile ioc4reg_t   *sbbr_l;
+        volatile ioc4reg_t   *sbbr_h;
+
+        if(port->ip_hooks == &hooks_array[0]) {
+		sbbr_l = &port->ip_ioc4->sbbr01_l;
+		sbbr_h = &port->ip_ioc4->sbbr01_h;
+        }
+	else {
+		sbbr_l = &port->ip_ioc4->sbbr23_l;
+		sbbr_h = &port->ip_ioc4->sbbr23_h;
+	}
+
+	/* Set the DMA address */
+	ring_pci_addr = ring_dmatrans(port->ip_conn_vhdl,
+				      port->ip_ring_buf_k0);
+
+	PCI_OUTW(sbbr_h,
+		 (ioc4reg_t) ((__psunsigned_t) ring_pci_addr >> 32));
+
+	PCI_OUTW(sbbr_l,
+		 ((ioc4reg_t) (int64_t) ring_pci_addr | IOC4_BUF_SIZE_BIT));
+
+#ifdef IOC4_SIO_DEBUG
+	{
+		unsigned int tmp1, tmp2;
+
+		tmp1 = PCI_INW(sbbr_l);
+		tmp2 = PCI_INW(sbbr_h);
+		printk("========== %s : sbbr_l [%p]/0x%x sbbr_h [%p]/0x%x\n",
+				__FUNCTION__, (void *)sbbr_l, tmp1, (void *)sbbr_h, tmp2);
+	}
+#endif
+    }
+
+    /* Set the receive timeout value to 10 msec */
+    PCI_OUTW(&port->ip_serial->srtr, IOC4_SRTR_HZ / 100);
+
+    /* Set RX threshold, enable DMA */
+    /* Set high water mark at 3/4 of full ring */
+    port->ip_sscr = (ENTRIES_PER_RING * 3 / 4);
+
+    PCI_OUTW(&port->ip_serial->sscr, port->ip_sscr);
+
+    /* Disable and clear all serial related interrupt bits */
+    IOC4_WRITE_IEC(port->ip_ioc4_soft, H_INTR_CLEAR, ioc4_sio_intr_type);
+    port->ip_ienb &= ~H_INTR_CLEAR;
+    PCI_OUTW(&port->ip_ioc4->sio_ir, H_INTR_CLEAR);
+
+    return(0);
+}
+
+
+/*
+ * Device initialization.
+ * Called at *_attach() time for each
+ * IOC4 with serial ports in the system.
+ * If vhdl is GRAPH_VERTEX_NONE, do not do
+ * any graph related work; otherwise, it
+ * is the IOC4 vertex that should be used
+ * for requesting pciio services.
+ */
+int
+ioc4_serial_attach(vertex_hdl_t conn_vhdl, void *ioc4)
+{
+    /*REFERENCED*/
+    graph_error_t	rc;
+    ioc4_mem_t	       *ioc4_mem;
+    vertex_hdl_t	port_vhdl, ioc4_vhdl;
+    vertex_hdl_t	intr_dev_vhdl;
+    ioc4port_t	       *port;
+    ioc4port_t	       *ports[4];
+    static char	       *names[] = { "tty/1", "tty/2", "tty/3", "tty/4" };
+    int			x, first_port = -1, last_port = -1;
+    void	       *ioc4_soft;
+    unsigned int        ioc4_revid_min = 62;
+    unsigned int        ioc4_revid;
+
+
+    /* IOC4 firmware must be at least rev 62 */
+    ioc4_revid = pciio_config_get(conn_vhdl, PCI_CFG_REV_ID, 1); 
+
+    if (ioc4_revid < ioc4_revid_min) {
+        printk( "IOC4 serial ports not supported on firmware rev %d, please upgrade to rev %d or higher\n", ioc4_revid, ioc4_revid_min);
+        return -1;
+    }
+
+    first_port = 0;
+    last_port = 3;
+
+    /* Get back pointer to the ioc4 soft area */
+    rc = hwgraph_traverse(conn_vhdl, EDGE_LBL_IOC4, &ioc4_vhdl);
+    ASSERT(rc == GRAPH_SUCCESS);
+    ioc4_soft = (void *)hwgraph_fastinfo_get(ioc4_vhdl);
+
+    /* grab the PIO address */
+    ioc4_mem = (ioc4_mem_t *)ioc4;
+    ASSERT(ioc4_mem != NULL);
+
+    /*
+     * Create port structures for each port
+     */
+    NEWA(port, 4);
+#ifdef IOC4_SIO_DEBUG
+    printk("%s : [addr 0x%p]\n", __FUNCTION__, (void *)port);
+#endif
+    ports[0] = port++;
+    ports[1] = port++;
+    ports[2] = port++;
+    ports[3] = port++;
+
+#if DEBUG
+    {
+	int slot = atomicAddInt(&next_saveport, 4) - 4;
+	saveport[slot] = ports[0];
+	saveport[slot + 1] = ports[1];
+	saveport[slot + 2] = ports[2];
+	saveport[slot + 3] = ports[3];
+	ASSERT(slot < MAXSAVEPORT);
+    }
+#endif
+
+#ifdef DEBUG
+    if ((caddr_t) port != (caddr_t) &(port->ip_sioport))
+	panic("sioport is not first member of ioc4port struct\n");
+#endif
+
+    /* Allocate buffers and jumpstart the hardware.
+     */
+    for (x = first_port; x < (last_port + 1); x++) {
+
+	port = ports[x];
+#ifdef IOC4_SIO_DEBUG
+	printk("%s : initialize port %d [addr 0x%p/0x%p]\n", __FUNCTION__, x, (void *)port,
+								(void *)GPORT(port));
+#endif
+	port->ip_ioc4_soft = ioc4_soft;
+	rc = hwgraph_path_add(conn_vhdl, names[x], &port_vhdl);
+	ASSERT(rc == GRAPH_SUCCESS);
+	port->ip_conn_vhdl = conn_vhdl;
+	port->ip_port_vhdl = port_vhdl;
+	port->ip_ienb	= 0;
+	hwgraph_fastinfo_set(port_vhdl, (arbitrary_info_t) port);
+
+	/* Perform upper layer initialization. Create all device node
+	 * types including rs422 ports.
+	 */
+	ioc4_serial_initport(GPORT(port), x);
+	port->ip_baud = 9600;
+
+	/* Attach the calldown hooks so upper layer can call our
+	 * routines.
+	 */
+	port->ip_sioport.sio_calldown = &ioc4_calldown;
+
+	/* Map in the IOC4 register area */
+	port->ip_ioc4 = ioc4_mem;
+    }
+
+    {
+	/* Port 0 */
+	port = ports[0];
+	port->ip_hooks = &hooks_array[0];
+
+	/* Get direct hooks to the serial regs and uart regs
+	 * for this port
+	 */
+	port->ip_serial = &(port->ip_ioc4->port_0);
+	port->ip_uart = &(port->ip_ioc4->uart_0);
+#ifdef IOC4_SIO_DEBUG
+	printk("==== %s : serial port 0 address 0x%p uart address 0x%p\n",
+				__FUNCTION__, (void *)port->ip_serial, (void *)port->ip_uart);
+#endif
+
+	/* If we don't already have a ring buffer,
+	 * set one up.
+	 */
+	if (port->ip_ring_buf_k0 == 0) {
+
+#if PAGE_SIZE >= TOTAL_RING_BUF_SIZE
+	    if ((port->ip_ring_buf_k0 = kvpalloc(1, VM_DIRECT, 0)) == 0)
+		panic("ioc4_uart driver cannot allocate page\n");
+#else
+	    /* We need to allocate a chunk of memory on a
+	     * TOTAL_RING_BUF_SIZE boundary.
+	     */
+	    {
+		pgno_t pfn;
+		caddr_t vaddr;
+		if ((pfn = contig_memalloc(TOTAL_RING_BUF_SIZE / PAGE_SIZE,
+					   TOTAL_RING_BUF_SIZE / PAGE_SIZE,
+					   VM_DIRECT)) == 0)
+		    panic("ioc4_uart driver cannot allocate page\n");
+		ASSERT(small_pfn(pfn));
+		vaddr = small_pfntova_K0(pfn);
+		(void) COLOR_VALIDATION(pfdat + pfn,
+					colorof(vaddr),
+					0, VM_DIRECT);
+		port->ip_ring_buf_k0 = vaddr;
+	    }
+#endif
+	}
+	ASSERT((((int64_t)port->ip_ring_buf_k0) &
+		(TOTAL_RING_BUF_SIZE - 1)) == 0);
+	memset(port->ip_ring_buf_k0, 0, TOTAL_RING_BUF_SIZE);
+	port->ip_inring = RING(port, RX_0_OR_2);
+	port->ip_outring = RING(port, TX_0_OR_2);
+
+	/* Initialize the hardware for IOC4 */
+	hardware_init(port);
+
+	if (hwgraph_edge_get(ports[0]->ip_port_vhdl, "d", &intr_dev_vhdl) !=
+							GRAPH_SUCCESS) {
+	    intr_dev_vhdl = ports[0]->ip_port_vhdl;
+	}
+
+	/* Attach interrupt handlers */
+	ioc4_intr_connect(conn_vhdl,
+			  ioc4_sio_intr_type,
+			  IOC4_SIO_IR_S0,
+			  ioc4_serial_intr,
+			  ports[0],
+			  ports[0]->ip_port_vhdl,
+			  intr_dev_vhdl);
+
+	ioc4_intr_connect(conn_vhdl,
+			  ioc4_other_intr_type,
+			  IOC4_OTHER_IR_S0_MEMERR,
+			  ioc4_dma_error_intr,
+			  ports[0],
+			  ports[0]->ip_port_vhdl,
+			  intr_dev_vhdl);
+    }
+
+    {
+
+	/* Port 1 */
+	port = ports[1];
+	port->ip_hooks = &hooks_array[1];
+
+	port->ip_serial = &(port->ip_ioc4->port_1);
+	port->ip_uart = &(port->ip_ioc4->uart_1);
+#ifdef IOC4_SIO_DEBUG
+	printk("==== %s : serial port 1 address 0x%p uart address 0x%p\n",
+				__FUNCTION__, (void *)port->ip_serial, (void *)port->ip_uart);
+#endif
+
+	port->ip_ring_buf_k0 = ports[0]->ip_ring_buf_k0;
+	port->ip_inring = RING(port, RX_1_OR_3);
+	port->ip_outring = RING(port, TX_1_OR_3);
+
+	/* Initialize the hardware for IOC4 */
+	hardware_init(port);
+
+	if (hwgraph_edge_get(ports[1]->ip_port_vhdl, "d", &intr_dev_vhdl) !=
+							GRAPH_SUCCESS) {
+	    intr_dev_vhdl = ports[1]->ip_port_vhdl;
+	}
+
+	/* Attach interrupt handler */
+	ioc4_intr_connect(conn_vhdl,
+		          ioc4_sio_intr_type,
+		          IOC4_SIO_IR_S1,
+		          ioc4_serial_intr,
+		          ports[1],
+		          ports[1]->ip_port_vhdl,
+		          intr_dev_vhdl);
+
+	ioc4_intr_connect(conn_vhdl,
+			  ioc4_other_intr_type,
+			  IOC4_OTHER_IR_S1_MEMERR,
+			  ioc4_dma_error_intr,
+			  ports[1],
+			  ports[1]->ip_port_vhdl,
+			  intr_dev_vhdl);
+    }
+
+    {
+
+	/* Port 2 */
+	port = ports[2];
+	port->ip_hooks = &hooks_array[2];
+
+	/* Get direct hooks to the serial regs and uart regs
+	 * for this port
+	 */
+	port->ip_serial = &(port->ip_ioc4->port_2);
+	port->ip_uart = &(port->ip_ioc4->uart_2);
+#ifdef IOC4_SIO_DEBUG
+	printk("==== %s : serial port 2 address 0x%p uart address 0x%p\n",
+				__FUNCTION__, (void *)port->ip_serial, (void *)port->ip_uart);
+#endif
+
+	/* If we don't already have a ring buffer,
+	 * set one up.
+	 */
+	if (port->ip_ring_buf_k0 == 0) {
+
+#if PAGE_SIZE >= TOTAL_RING_BUF_SIZE
+	    if ((port->ip_ring_buf_k0 = kvpalloc(1, VM_DIRECT, 0)) == 0)
+		panic("ioc4_uart driver cannot allocate page\n");
+#else
+
+	    /* We need to allocate a chunk of memory on a
+	     * TOTAL_RING_BUF_SIZE boundary.
+	     */
+	    {
+		pgno_t pfn;
+		caddr_t vaddr;
+		if ((pfn = contig_memalloc(TOTAL_RING_BUF_SIZE / PAGE_SIZE,
+					   TOTAL_RING_BUF_SIZE / PAGE_SIZE,
+					   VM_DIRECT)) == 0)
+		    panic("ioc4_uart driver cannot allocate page\n");
+		ASSERT(small_pfn(pfn));
+		vaddr = small_pfntova_K0(pfn);
+		(void) COLOR_VALIDATION(pfdat + pfn,
+					colorof(vaddr),
+					0, VM_DIRECT);
+		port->ip_ring_buf_k0 = vaddr;
+	    }
+#endif
+
+	}
+	ASSERT((((int64_t)port->ip_ring_buf_k0) &
+		(TOTAL_RING_BUF_SIZE - 1)) == 0);
+	memset(port->ip_ring_buf_k0, 0, TOTAL_RING_BUF_SIZE);
+	port->ip_inring = RING(port, RX_0_OR_2);
+	port->ip_outring = RING(port, TX_0_OR_2);
+
+	/* Initialize the hardware for IOC4 */
+	hardware_init(port);
+
+	if (hwgraph_edge_get(ports[0]->ip_port_vhdl, "d", &intr_dev_vhdl) !=
+							GRAPH_SUCCESS) {
+	    intr_dev_vhdl = ports[2]->ip_port_vhdl;
+	}
+
+	/* Attach interrupt handler */
+	ioc4_intr_connect(conn_vhdl,
+			  ioc4_sio_intr_type,
+			  IOC4_SIO_IR_S2,
+			  ioc4_serial_intr,
+			  ports[2],
+			  ports[2]->ip_port_vhdl,
+			  intr_dev_vhdl);
+
+	ioc4_intr_connect(conn_vhdl,
+			  ioc4_other_intr_type,
+			  IOC4_OTHER_IR_S2_MEMERR,
+			  ioc4_dma_error_intr,
+			  ports[2],
+			  ports[2]->ip_port_vhdl,
+			  intr_dev_vhdl);
+    }
+
+    {
+
+	/* Port 3 */
+	port = ports[3];
+	port->ip_hooks = &hooks_array[3];
+
+	port->ip_serial = &(port->ip_ioc4->port_3);
+	port->ip_uart = &(port->ip_ioc4->uart_3);
+#ifdef IOC4_SIO_DEBUG
+	printk("==== %s : serial port 3 address 0x%p uart address 0x%p\n",
+				__FUNCTION__, (void *)port->ip_serial, (void *)port->ip_uart);
+#endif
+
+	port->ip_ring_buf_k0 = ports[2]->ip_ring_buf_k0;
+	port->ip_inring = RING(port, RX_1_OR_3);
+	port->ip_outring = RING(port, TX_1_OR_3);
+
+	/* Initialize the hardware for IOC4 */
+	hardware_init(port);
+
+	if (hwgraph_edge_get(ports[3]->ip_port_vhdl, "d", &intr_dev_vhdl) !=
+							GRAPH_SUCCESS) {
+	    intr_dev_vhdl = ports[3]->ip_port_vhdl;
+	}
+
+	/* Attach interrupt handler */
+	ioc4_intr_connect(conn_vhdl,
+		          ioc4_sio_intr_type,
+		          IOC4_SIO_IR_S3,
+		          ioc4_serial_intr,
+		          ports[3],
+		          ports[3]->ip_port_vhdl,
+		          intr_dev_vhdl);
+
+	ioc4_intr_connect(conn_vhdl,
+			  ioc4_other_intr_type,
+			  IOC4_OTHER_IR_S3_MEMERR,
+			  ioc4_dma_error_intr,
+			  ports[3],
+			  ports[3]->ip_port_vhdl,
+			  intr_dev_vhdl);
+    }
+
+#ifdef	DEBUG
+    idbg_addfunc( "ioc4dump", idbg_ioc4dump );
+#endif
+
+    return 0;
+}
+
+
+/* Shut down an IOC4 */
+/* ARGSUSED1 */
+void
+ioc4_serial_kill(ioc4port_t *port)
+{
+    DEBUGINC(killed, 1);
+
+    /* Notify upper layer that this port is no longer usable */
+    UP_DETACH(GPORT(port));
+
+    /* Clear everything in the sscr */
+    PCI_OUTW(&port->ip_serial->sscr, 0);
+    port->ip_sscr = 0;
+
+#ifdef DEBUG
+    /* Make sure nobody gets past the lock and accesses the hardware */
+    port->ip_ioc4 = 0;
+    port->ip_serial = 0;
+#endif
+
+}
+
+
+/*
+ * Open a port
+ */
+static int
+ioc4_open(sioport_t *port)
+{
+    ioc4port_t *p = LPORT(port);
+    int         spin_success;
+
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_OPEN));
+#endif
+
+    p->ip_flags = 0;
+    p->ip_modem_bits = 0;
+
+    /* Pause the DMA interface if necessary */
+    if (p->ip_sscr & IOC4_SSCR_DMA_EN) {
+	PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr | IOC4_SSCR_DMA_PAUSE);
+	SPIN((PCI_INW(&p->ip_serial->sscr) & IOC4_SSCR_PAUSE_STATE) == 0,
+             spin_success);
+	if (!spin_success) {
+		NOT_PROGRESS();
+		return(-1);
+	}
+    }
+
+    /* Reset the input fifo.  If the uart received chars while the port
+     * was closed and DMA is not enabled, the uart may have a bunch of
+     * chars hanging around in its RX fifo which will not be discarded
+     * by rclr in the upper layer. We must get rid of them here.
+     */
+    PCI_OUTB(&p->ip_uart->i4u_fcr, FCR_FIFOEN | FCR_RxFIFO);
+
+    /* Set defaults */
+    SET_BAUD(p, 9600);
+
+    PCI_OUTB(&p->ip_uart->i4u_lcr, LCR_BITS8 | LCR_1_STOP_BITS);
+
+    /* Re-enable DMA, set default threshold to intr whenever there is
+     * data available.
+     */
+    p->ip_sscr &= ~IOC4_SSCR_RX_THRESHOLD;
+    p->ip_sscr |= 1; /* default threshold */
+
+    /* Plug in the new sscr.  This implicitly clears the DMA_PAUSE
+     * flag if it was set above
+     */
+    PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr);
+
+    PCI_OUTW(&p->ip_serial->srtr, 0);
+
+    p->ip_tx_lowat = 1;
+
+    dprintf(("ioc4 open successful\n"));
+
+    return(0);
+}
+
+
+/*
+ * Config hardware
+ */
+static int
+ioc4_config(sioport_t *port,
+	    int baud,
+	    int byte_size,
+	    int stop_bits,
+	    int parenb,
+	    int parodd)
+{
+    ioc4port_t *p = LPORT(port);
+    char        lcr, sizebits;
+    int         spin_success;
+
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_CONFIG));
+#endif
+
+    if (SET_BAUD(p, baud))
+	return(1);
+
+    switch(byte_size) {
+      case 5:
+	sizebits = LCR_BITS5;
+	break;
+      case 6:
+	sizebits = LCR_BITS6;
+	break;
+      case 7:
+	sizebits = LCR_BITS7;
+	break;
+      case 8:
+	sizebits = LCR_BITS8;
+	break;
+      default:
+	dprintf(("invalid byte size port 0x%x size %d\n", port, byte_size));
+	return(1);
+    }
+
+    /* Pause the DMA interface if necessary */
+    if (p->ip_sscr & IOC4_SSCR_DMA_EN) {
+	PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr | IOC4_SSCR_DMA_PAUSE);
+	SPIN((PCI_INW(&p->ip_serial->sscr) & IOC4_SSCR_PAUSE_STATE) == 0,
+             spin_success);
+	if (!spin_success) 
+		return(-1);
+    }
+
+    /* Clear relevant fields in lcr */
+    lcr = PCI_INB(&p->ip_uart->i4u_lcr);
+    lcr &= ~(LCR_MASK_BITS_CHAR | LCR_EPS |
+             LCR_PEN | LCR_MASK_STOP_BITS);
+
+    /* Set byte size in lcr */
+    lcr |= sizebits;
+
+    /* Set parity */
+    if (parenb) {
+	lcr |= LCR_PEN;
+	if (!parodd)
+	    lcr |= LCR_EPS;
+    }
+
+    /* Set stop bits */
+    if (stop_bits)
+	lcr |= LCR_2_STOP_BITS;
+
+    PCI_OUTB(&p->ip_uart->i4u_lcr, lcr);
+
+    dprintf(("ioc4_config: lcr bits 0x%x\n", lcr));
+
+    /* Re-enable the DMA interface if necessary */
+    if (p->ip_sscr & IOC4_SSCR_DMA_EN) {
+	PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr);
+    }
+
+    p->ip_baud = baud;
+
+    /* When we get within this number of ring entries of filling the
+     * entire ring on TX, place an EXPLICIT intr to generate a lowat
+     * notification when output has drained.
+     */
+    p->ip_tx_lowat = (TX_LOWAT_CHARS(baud) + 3) / 4;
+    if (p->ip_tx_lowat == 0)
+	p->ip_tx_lowat = 1;
+
+    ioc4_rx_timeout(port, p->ip_rx_timeout);
+
+    return(0);
+}
+
+
+/*
+ * Enable hardware flow control
+ */
+static int
+ioc4_enable_hfc(sioport_t *port, int enable)
+{
+    ioc4port_t *p = LPORT(port);
+
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_ENABLE_HFC));
+#endif
+
+    dprintf(("enable hfc port 0x%p, enb %d\n", (void *)port, enable));
+
+    if (enable)
+	p->ip_sscr |= IOC4_SSCR_HFC_EN;
+    else
+	p->ip_sscr &= ~IOC4_SSCR_HFC_EN;
+
+    PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr);
+
+    return(0);
+}
+
+
+/*
+ * Set external clock
+ */
+/*ARGSUSED*/
+static int
+ioc4_set_extclk(sioport_t *port, int clock_factor)
+{
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_SET_EXTCLK));
+    /* XXX still todo */
+#endif
+
+    /* only support 0 (no external clock) */
+    return(clock_factor);
+}
+
+
+/*
+ * Write bytes to the hardware.  Returns the number of bytes
+ * actually written.
+ */
+static int
+do_ioc4_write(sioport_t *port, char *buf, int len)
+{
+    int                prod_ptr, cons_ptr, total;
+    struct ring       *outring;
+    struct ring_entry *entry;
+    ioc4port_t        *p = LPORT(port);
+    struct hooks      *hooks = p->ip_hooks;
+
+    DEBUGINC(write_bytes, len);
+    DEBUGINC(write_cnt, 1);
+
+    dprintf(("write port 0x%p, len %d\n", (void *)port, len));
+
+    ASSERT(len >= 0);
+
+    prod_ptr = p->ip_tx_prod;
+    cons_ptr = PCI_INW(&p->ip_serial->stcir) & PROD_CONS_MASK;
+    outring = p->ip_outring;
+
+    /* Maintain a 1-entry red-zone.  The ring buffer is full when
+     * (cons - prod) % ring_size is 1.  Rather than do this subtraction
+     * in the body of the loop, I'll do it now.
+     */
+    cons_ptr = (cons_ptr - (int) sizeof(struct ring_entry)) & PROD_CONS_MASK;
+
+    total = 0;
+    /* Stuff the bytes into the output */
+    while ((prod_ptr != cons_ptr) && (len > 0)) {
+	int x;
+
+	/* Go 4 bytes (one ring entry) at a time */
+	entry = (struct ring_entry*) ((caddr_t)outring + prod_ptr);
+
+	/* Invalidate all entries */
+	entry->ring_allsc = 0;
+
+	/* Copy in some bytes */
+	for(x = 0; (x < 4) && (len > 0); x++) {
+	    entry->ring_data[x] = *buf++;
+	    entry->ring_sc[x] = IOC4_TXCB_VALID;
+	    len--;
+	    total++;
+	}
+
+	DEBUGINC(tx_buf_used, x);
+	DEBUGINC(tx_buf_cnt, 1);
+
+	/* If we are within some small threshold of filling up the entire
+	 * ring buffer, we must place an EXPLICIT intr here to generate
+	 * a lowat interrupt in case we subsequently really do fill up
+	 * the ring and the caller goes to sleep.  No need to place
+	 * more than one though.
+	 */
+	if (!(p->ip_flags & LOWAT_WRITTEN) &&
+	    ((cons_ptr - prod_ptr) & PROD_CONS_MASK) <=
+	    p->ip_tx_lowat * (int)sizeof(struct ring_entry)) {
+	    p->ip_flags |= LOWAT_WRITTEN;
+	    entry->ring_sc[0] |= IOC4_TXCB_INT_WHEN_DONE;
+	    dprintf(("write placing TX_EXPLICIT\n"));
+	}
+
+	/* Go on to next entry */
+	prod_ptr = (prod_ptr + (int) sizeof(struct ring_entry)) & PROD_CONS_MASK;
+    }
+
+    /* If we sent something, start DMA if necessary */
+    if (total > 0 && !(p->ip_sscr & IOC4_SSCR_DMA_EN)) {
+	p->ip_sscr |= IOC4_SSCR_DMA_EN;
+	PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr);
+    }
+
+    /* Store the new producer pointer.  If TX is disabled, we stuff the
+     * data into the ring buffer, but we don't actually start TX.
+     */
+    if (!(p->ip_flags & TX_DISABLED)) {
+	PCI_OUTW(&p->ip_serial->stpir, prod_ptr);
+
+	/* If we are now transmitting, enable TX_MT interrupt so we
+	 * can disable DMA if necessary when the TX finishes.
+	 */
+	if (total > 0)
+	    enable_intrs(p, H_INTR_TX_MT);
+    }
+    p->ip_tx_prod = prod_ptr;
+
+    dprintf(("write port 0x%p, wrote %d\n", (void *)port, total));
+    DEBUGINC(wrote_bytes, total);
+    return(total);
+}
+
+
+/* Asynchronous write */
+static int
+ioc4_write(sioport_t *port, char *buf, int len)
+{
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_WRITE));
+#endif
+    return(do_ioc4_write(port, buf, len));
+}
+
+
+/* Synchronous write */
+static int
+ioc4_sync_write(sioport_t *port, char *buf, int len)
+{
+    int bytes;
+
+    ASSERT(sio_port_islocked(port));
+    bytes = do_ioc4_write(port, buf, len);
+
+    /* Don't allow the system to hang if XOFF is in force */
+    if (len > 0 && bytes == 0 && (LPORT(port)->ip_flags & TX_DISABLED))
+	ioc4_enable_tx(port, 1);
+
+    return(bytes);
+}
+
+
+/* Write flush */
+static void
+ioc4_wrflush(sioport_t *port)
+{
+    ioc4port_t *p = LPORT(port);
+
+    ASSERT(sio_port_islocked(port));
+
+    /* We can't flush if TX is disabled due to XOFF. */
+    if (!(PCI_INW(&p->ip_ioc4->sio_ir) & IOC4_SIO_IR_S0_TX_MT) &&
+	(p->ip_flags & TX_DISABLED))
+	ioc4_enable_tx(port, 1);
+
+    /* Spin waiting for TX_MT to assert only if DMA is enabled.  If we
+     * are panicking and one of the other processors is already in
+     * symmon, DMA will be disabled and TX_MT will never be asserted.
+     * There may also be legitimate cases in the kernel where DMA is
+     * disabled and we won't flush correctly here.
+     */
+
+    while ((PCI_INW(&p->ip_serial->sscr) & (IOC4_SSCR_DMA_EN |
+           IOC4_SSCR_PAUSE_STATE)) == IOC4_SSCR_DMA_EN &&
+	   !(PCI_INW(&p->ip_ioc4->sio_ir) & IOC4_SIO_IR_S0_TX_MT)) {
+	udelay(5);
+    }
+}
+
+
+/*
+ * Set or clear break condition on output
+ */
+static int
+ioc4_break(sioport_t *port, int brk)
+{
+    ioc4port_t *p = LPORT(port);
+    char        lcr;
+    int         spin_success;
+
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_BREAK));
+#endif
+
+    /* Pause the DMA interface if necessary */
+    if (p->ip_sscr & IOC4_SSCR_DMA_EN) {
+	PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr | IOC4_SSCR_DMA_PAUSE);
+	SPIN((PCI_INW(&p->ip_serial->sscr) & IOC4_SSCR_PAUSE_STATE) == 0,
+             spin_success);
+	if (!spin_success)
+		return(-1);
+    }
+
+    lcr = PCI_INB(&p->ip_uart->i4u_lcr);
+    if (brk) {
+	/* Set break */
+        PCI_OUTB(&p->ip_uart->i4u_lcr, lcr | LCR_SNDBRK);
+    }
+    else {
+	/* Clear break */
+        PCI_OUTB(&p->ip_uart->i4u_lcr, lcr & ~LCR_SNDBRK);
+    }
+
+    /* Re-enable the DMA interface if necessary */
+    if (p->ip_sscr & IOC4_SSCR_DMA_EN) {
+	PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr);
+    }
+
+    dprintf(("break port 0x%p, brk %d\n", (void *)port, brk));
+
+    return(0);
+}
+
+
+static int
+ioc4_enable_tx(sioport_t *port, int enb)
+{
+    ioc4port_t   *p = LPORT(port);
+    struct hooks *hooks = p->ip_hooks;
+    int           spin_success;
+
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_ENABLE_TX));
+#endif
+
+    /* If we're already in the desired state, we're done */
+    if ((enb && !(p->ip_flags & TX_DISABLED)) ||
+	(!enb && (p->ip_flags & TX_DISABLED)))
+	return(0);
+
+    /* Pause DMA */
+    if (p->ip_sscr & IOC4_SSCR_DMA_EN) {
+	PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr | IOC4_SSCR_DMA_PAUSE);
+	SPIN((PCI_INW(&p->ip_serial->sscr) & IOC4_SSCR_PAUSE_STATE) == 0,
+             spin_success);
+	if (!spin_success)
+		return(-1);
+    }
+
+    if (enb) {
+	p->ip_flags &= ~TX_DISABLED;
+	PCI_OUTW(&p->ip_serial->stpir, p->ip_tx_prod);
+	enable_intrs(p, H_INTR_TX_MT);
+    }
+    else {
+	ioc4reg_t txcons = PCI_INW(&p->ip_serial->stcir) & PROD_CONS_MASK;
+	p->ip_flags |= TX_DISABLED;
+	disable_intrs(p, H_INTR_TX_MT);
+
+	/* Only move the transmit producer pointer back if the
+	 * transmitter is not already empty, otherwise we'll be
+	 * generating a bogus entry.
+	 */
+	if (txcons != p->ip_tx_prod)
+	    PCI_OUTW(&p->ip_serial->stpir,
+		     (txcons + (int) sizeof(struct ring_entry)) & PROD_CONS_MASK);
+    }
+
+    /* Re-enable the DMA interface if necessary */
+    if (p->ip_sscr & IOC4_SSCR_DMA_EN) 
+	PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr);
+
+    return(0);
+}
+
+
+/*
+ * Read in bytes from the hardware.  Return the number of bytes
+ * actually read.
+ */
+static int
+ioc4_read(sioport_t *port, char *buf, int len)
+{
+    int           prod_ptr, cons_ptr, total, x, spin_success;
+    struct ring  *inring;
+    ioc4port_t   *p = LPORT(port);
+    struct hooks *hooks = p->ip_hooks;
+
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_READ));
+#endif
+
+    dprintf(("read port 0x%p, len %d\n", (void *)port, len));
+
+    DEBUGINC(read_bytes, len);
+    DEBUGINC(read_cnt, 1);
+
+    ASSERT(len >= 0);
+
+    /* There is a nasty timing issue in the IOC4. When the RX_TIMER
+     * expires or the RX_HIGH condition arises, we take an interrupt.
+     * At some point while servicing the interrupt, we read bytes from
+     * the ring buffer and re-arm the RX_TIMER.  However the RX_TIMER is
+     * not started until the first byte is received *after* it is armed,
+     * and any bytes pending in the RX construction buffers are not drained
+     * to memory until either there are 4 bytes available or the RX_TIMER
+     * expires.  This leads to a potential situation where data is left
+     * in the construction buffers forever because 1 to 3 bytes were received
+     * after the interrupt was generated but before the RX_TIMER was re-armed.
+     * At that point as long as no subsequent bytes are received the
+     * timer will never be started and the bytes will remain in the
+     * construction buffer forever.  The solution is to execute a DRAIN
+     * command after rearming the timer.  This way any bytes received before
+     * the DRAIN will be drained to memory, and any bytes received after
+     * the DRAIN will start the TIMER and be drained when it expires.
+     * Luckily, this only needs to be done when the DMA buffer is empty
+     * since there is no requirement that this function return all
+     * available data as long as it returns some.
+     */
+    /* Re-arm the timer */
+    PCI_OUTW(&p->ip_serial->srcir, p->ip_rx_cons | IOC4_SRCIR_ARM);
+
+    prod_ptr = PCI_INW(&p->ip_serial->srpir) & PROD_CONS_MASK;
+    cons_ptr = p->ip_rx_cons;
+
+    if (prod_ptr == cons_ptr) {
+	int reset_dma = 0;
+
+	/* Input buffer appears empty, do a flush. */
+
+	/* DMA must be enabled for this to work. */
+	if (!(p->ip_sscr & IOC4_SSCR_DMA_EN)) {
+	    p->ip_sscr |= IOC4_SSCR_DMA_EN;
+	    reset_dma = 1;
+	}
+
+	/* Potential race condition: we must reload the srpir after
+	 * issuing the drain command, otherwise we could think the RX
+	 * buffer is empty, then take a very long interrupt, and when
+	 * we come back it's full and we wait forever for the drain to
+	 * complete.
+	 */
+	PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr | IOC4_SSCR_RX_DRAIN);
+	prod_ptr = PCI_INW(&p->ip_serial->srpir) & PROD_CONS_MASK;
+
+	DEBUGINC(drain, 1);
+
+	/* We must not wait for the DRAIN to complete unless there are
+	 * at least 8 bytes (2 ring entries) available to receive the data
+	 * otherwise the DRAIN will never complete and we'll deadlock here.
+	 * In fact, to make things easier, I'll just ignore the flush if
+	 * there is any data at all now available.
+	 */
+	if (prod_ptr == cons_ptr) {
+	    DEBUGINC(drainwait, 1);
+	    SPIN(PCI_INW(&p->ip_serial->sscr) & IOC4_SSCR_RX_DRAIN, spin_success);
+	    if (!spin_success)
+		    return(-1);
+
+	    /* SIGH. We have to reload the prod_ptr *again* since
+	     * the drain may have caused it to change
+	     */
+	    prod_ptr = PCI_INW(&p->ip_serial->srpir) & PROD_CONS_MASK;
+	}
+
+	if (reset_dma) {
+	    DEBUGINC(resetdma, 1);
+	    p->ip_sscr &= ~IOC4_SSCR_DMA_EN;
+	    PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr);
+	}
+    }
+    inring = p->ip_inring;
+
+    p->ip_flags &= ~READ_ABORTED;
+
+    total = 0;
+    /* Grab bytes from the hardware */
+    while(prod_ptr != cons_ptr && len > 0) {
+	struct ring_entry *entry;
+
+	entry = (struct ring_entry *) ((caddr_t)inring + cons_ptr);
+
+	/* According to the producer pointer, this ring entry
+	 * must contain some data.  But if the PIO happened faster
+	 * than the DMA, the data may not be available yet, so let's
+	 * wait until it arrives.
+	 */
+	if ((((volatile struct ring_entry *) entry)->ring_allsc &
+	     RING_ANY_VALID) == 0) {
+
+	    /* Indicate the read is aborted so we don't disable
+	     * the interrupt thinking that the consumer is
+	     * congested.
+	     */
+	    p->ip_flags |= READ_ABORTED;
+		
+	    DEBUGINC(read_aborted, 1);
+	    len = 0;
+	    break;
+
+	}
+
+	/* Load the bytes/status out of the ring entry */
+	for(x = 0; x < 4 && len > 0; x++) {
+	    char *sc = &(entry->ring_sc[x]);
+
+	    /* Check for change in modem state or overrun */
+	    if (*sc & IOC4_RXSB_MODEM_VALID) {
+		if (p->ip_notify & N_DDCD) {
+
+		    /* Notify upper layer if DCD dropped */
+		    if ((p->ip_flags & DCD_ON) && !(*sc & IOC4_RXSB_DCD)) {
+
+			/* If we have already copied some data, return
+			 * it.  We'll pick up the carrier drop on the next
+			 * pass.  That way we don't throw away the data
+			 * that has already been copied back to the caller's
+			 * buffer.
+			 */
+			if (total > 0) {
+			    len = 0;
+			    break;
+			}
+
+			p->ip_flags &= ~DCD_ON;
+
+			/* Turn off this notification so the carrier
+			 * drop protocol won't see it again when it
+			 * does a read.
+			 */
+			*sc &= ~IOC4_RXSB_MODEM_VALID;
+
+			/* To keep things consistent, we need to update
+			 * the consumer pointer so the next reader won't
+			 * come in and try to read the same ring entries
+			 * again.  This must be done here before the call
+			 * to UP_DDCD since UP_DDCD may do a recursive
+			 * read!
+			 */
+			if ((entry->ring_allsc & RING_ANY_VALID) == 0)
+			    cons_ptr =
+				(cons_ptr + (int) sizeof(struct ring_entry)) &
+				    PROD_CONS_MASK;
+
+			PCI_OUTW(&p->ip_serial->srcir, cons_ptr);
+			p->ip_rx_cons = cons_ptr;
+
+			/* Notify upper layer of carrier drop */
+			if (p->ip_notify & N_DDCD)
+			    UP_DDCD(port, 0);
+
+			DEBUGINC(read_ddcd, 1);
+
+			/* If we had any data to return, we would have
+			 * returned it above.
+			 */
+			return(0);
+		    }
+		}
+
+		/* Notify upper layer that an input overrun occurred */
+		if ((*sc & IOC4_RXSB_OVERRUN) && (p->ip_notify & N_OVERRUN_ERROR)) {
+		    DEBUGINC(rx_overrun, 1);
+		    UP_NCS(port, NCS_OVERRUN);
+		}
+
+		/* Don't look at this byte again */
+		*sc &= ~IOC4_RXSB_MODEM_VALID;
+	    }
+
+	    /* Check for valid data or RX errors */
+	    if (*sc & IOC4_RXSB_DATA_VALID) {
+		if ((*sc & (IOC4_RXSB_PAR_ERR | IOC4_RXSB_FRAME_ERR |
+                            IOC4_RXSB_BREAK)) &&
+		    (p->ip_notify & (N_PARITY_ERROR | N_FRAMING_ERROR | N_BREAK))) {
+
+		    /* There is an error condition on the next byte.  If
+		     * we have already transferred some bytes, we'll stop
+		     * here.  Otherwise if this is the first byte to be read,
+		     * we'll just transfer it alone after notifying the
+		     * upper layer of its status.
+		     */
+		    if (total > 0) {
+			len = 0;
+			break;
+		    }
+		    else {
+			if ((*sc & IOC4_RXSB_PAR_ERR) &&
+			    (p->ip_notify & N_PARITY_ERROR)) {
+			    DEBUGINC(parity, 1);
+			    UP_NCS(port, NCS_PARITY);
+			}
+
+			if ((*sc & IOC4_RXSB_FRAME_ERR) &&
+			    (p->ip_notify & N_FRAMING_ERROR)) {
+			    DEBUGINC(framing, 1);
+			    UP_NCS(port, NCS_FRAMING);
+			}
+
+			if ((*sc & IOC4_RXSB_BREAK) &&
+			    (p->ip_notify & N_BREAK)) {
+			    DEBUGINC(brk, 1);
+			    UP_NCS(port, NCS_BREAK);
+			}
+			len = 1;
+		    }
+		}
+
+		*sc &= ~IOC4_RXSB_DATA_VALID;
+		*buf++ = entry->ring_data[x];
+		len--;
+		total++;
+	    }
+	}
+
+	DEBUGINC(rx_buf_used, x);
+	DEBUGINC(rx_buf_cnt, 1);
+
+	/* If we used up this entry entirely, go on to the next one,
+	 * otherwise we must have run out of buffer space, so
+	 * leave the consumer pointer here for the next read in case
+	 * there are still unread bytes in this entry.
+	 */
+	if ((entry->ring_allsc & RING_ANY_VALID) == 0)
+	    cons_ptr = (cons_ptr + (int) sizeof(struct ring_entry)) &
+		PROD_CONS_MASK;
+    }
+
+    /* Update consumer pointer and re-arm RX timer interrupt */
+    PCI_OUTW(&p->ip_serial->srcir, cons_ptr);
+    p->ip_rx_cons = cons_ptr;
+
+    /* If we have now dipped below the RX high water mark and we have
+     * RX_HIGH interrupt turned off, we can now turn it back on again.
+     */
+    if ((p->ip_flags & INPUT_HIGH) &&
+	(((prod_ptr - cons_ptr) & PROD_CONS_MASK) <
+	 ((p->ip_sscr & IOC4_SSCR_RX_THRESHOLD) << IOC4_PROD_CONS_PTR_OFF))) {
+	p->ip_flags &= ~INPUT_HIGH;
+	enable_intrs(p, H_INTR_RX_HIGH);
+    }
+
+    DEBUGINC(red_bytes, total);
+
+    return(total);
+}
+
+
+/*
+ * Modify event notification
+ */
+static int
+ioc4_notification(sioport_t *port, int mask, int on)
+{
+    ioc4port_t   *p = LPORT(port);
+    struct hooks *hooks = p->ip_hooks;
+    ioc4reg_t     intrbits, sscrbits;
+
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_NOTIFICATION));
+#endif
+    ASSERT(mask);
+
+    intrbits = sscrbits = 0;
+
+    if (mask & N_DATA_READY)
+	intrbits |= (H_INTR_RX_TIMER | H_INTR_RX_HIGH);
+    if (mask & N_OUTPUT_LOWAT)
+	intrbits |= H_INTR_TX_EXPLICIT;
+    if (mask & N_DDCD) {
+	intrbits |= H_INTR_DELTA_DCD;
+	sscrbits |= IOC4_SSCR_RX_RING_DCD;
+    }
+    if (mask & N_DCTS)
+	intrbits |= H_INTR_DELTA_CTS;
+
+    if (on) {
+	enable_intrs(p, intrbits);
+	p->ip_notify |= mask;
+	p->ip_sscr |= sscrbits;
+    }
+    else {
+	disable_intrs(p, intrbits);
+	p->ip_notify &= ~mask;
+	p->ip_sscr &= ~sscrbits;
+    }
+
+    /* We require DMA if either DATA_READY or DDCD notification is
+     * currently requested.  If neither of these is requested and
+     * there is currently no TX in progress, DMA may be disabled.
+     */
+    if (p->ip_notify & (N_DATA_READY | N_DDCD)) 
+	p->ip_sscr |= IOC4_SSCR_DMA_EN;
+    else if (!(p->ip_ienb & H_INTR_TX_MT)) 
+	p->ip_sscr &= ~IOC4_SSCR_DMA_EN;
+
+    PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr);
+    return(0);
+}
+
+
+/*
+ * Set RX timeout and threshold values.  The upper layer passes in a
+ * timeout value.  In all cases it would like to be notified at least this
+ * often when there are RX chars coming in.  We set the RX timeout and
+ * RX threshold (based on baud) to ensure that the upper layer is called
+ * at roughly this interval during normal RX.
+ * The input timeout value is in ticks.
+ */
+static int
+ioc4_rx_timeout(sioport_t *port, int timeout)
+{
+    int         threshold;
+    ioc4port_t *p = LPORT(port);
+
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_RX_TIMEOUT));
+#endif
+
+    p->ip_rx_timeout = timeout;
+
+    /* Timeout is in ticks.  Let's figure out how many chars we
+     * can receive at the current baud rate in that interval
+     * and set the RX threshold to that amount.  There are 4 chars
+     * per ring entry, so we'll divide the number of chars that will
+     * arrive in timeout by 4.
+     */
+    threshold = timeout * p->ip_baud / 10 / HZ / 4;
+    if (threshold == 0)
+	threshold = 1; /* otherwise we'll intr all the time! */
+
+    if ((unsigned) threshold > (unsigned) IOC4_SSCR_RX_THRESHOLD)
+	    return(1);
+
+    p->ip_sscr &= ~IOC4_SSCR_RX_THRESHOLD;
+    p->ip_sscr |= threshold;
+
+    PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr);
+
+    /* Now set the RX timeout to the given value */
+    timeout = timeout * IOC4_SRTR_HZ / HZ;
+    if (timeout > IOC4_SRTR_CNT)
+	timeout = IOC4_SRTR_CNT;
+
+    PCI_OUTW(&p->ip_serial->srtr, timeout);
+
+    return(0);
+}
+
+
+static int
+set_DTRRTS(sioport_t *port, int val, int mask1, int mask2)
+{
+    ioc4port_t *p = LPORT(port);
+    ioc4reg_t   shadow;
+    int         spin_success;
+    char        mcr;
+
+    /* XXX need lock for pretty much this entire routine.  Makes
+     * me nervous to hold it for so long.  If we crash or hit
+     * a breakpoint in here, we're hosed.
+     */
+
+    /* Pause the DMA interface if necessary */
+    if (p->ip_sscr & IOC4_SSCR_DMA_EN) {
+	PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr | IOC4_SSCR_DMA_PAUSE);
+	SPIN((PCI_INW(&p->ip_serial->sscr) & IOC4_SSCR_PAUSE_STATE) == 0,
+             spin_success);
+	if (!spin_success)
+		return(-1);
+    }
+
+    shadow = PCI_INW(&p->ip_serial->shadow);
+    mcr = (shadow & 0xff000000) >> 24;
+
+    /* Set new value */
+    if (val) {
+	mcr |= mask1;
+        shadow |= mask2;
+    }
+    else {
+	mcr &= ~mask1;
+        shadow &= ~mask2;
+    }
+
+    PCI_OUTB(&p->ip_uart->i4u_mcr, mcr);
+
+    PCI_OUTW(&p->ip_serial->shadow, shadow);
+
+    /* Re-enable the DMA interface if necessary */
+    if (p->ip_sscr & IOC4_SSCR_DMA_EN) 
+	PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr);
+
+    return(0);
+}
+
+
+static int
+ioc4_set_DTR(sioport_t *port, int dtr)
+{
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_SET_DTR));
+#endif
+
+    dprintf(("set dtr port 0x%p, dtr %d\n", (void *)port, dtr));
+    return(set_DTRRTS(port, dtr, MCR_DTR, IOC4_SHADOW_DTR));
+}
+
+
+static int
+ioc4_set_RTS(sioport_t *port, int rts)
+{
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_SET_RTS));
+#endif
+
+    dprintf(("set rts port 0x%p, rts %d\n", (void *)port, rts));
+    return(set_DTRRTS(port, rts, MCR_RTS, IOC4_SHADOW_RTS));
+}
+
+
+static int
+ioc4_query_DCD(sioport_t *port)
+{
+    ioc4port_t *p = LPORT(port);
+    ioc4reg_t   shadow;
+
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_QUERY_DCD));
+#endif
+
+    dprintf(("get dcd port 0x%p\n", (void *)port));
+
+    shadow = PCI_INW(&p->ip_serial->shadow);
+
+    return(shadow & IOC4_SHADOW_DCD);
+}
+
+
+static int
+ioc4_query_CTS(sioport_t *port)
+{
+    ioc4port_t *p = LPORT(port);
+    ioc4reg_t   shadow;
+
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_QUERY_CTS));
+#endif
+
+    dprintf(("get cts port 0x%p\n", (void *)port));
+
+    shadow = PCI_INW(&p->ip_serial->shadow);
+
+    return(shadow & IOC4_SHADOW_CTS);
+}
+
+
+static int
+ioc4_set_proto(sioport_t *port, enum sio_proto proto)
+{
+    ioc4port_t   *p = LPORT(port);
+    struct hooks *hooks = p->ip_hooks;
+
+#ifdef NOT_YET
+    ASSERT(L_LOCKED(port, L_SET_PROTOCOL));
+#endif
+
+    switch(proto) {
+      case PROTO_RS232:
+	/* Clear the appropriate GIO pin */
+	PCI_OUTW((&p->ip_ioc4->gppr_0 + H_RS422), 0);
+	break;
+
+      case PROTO_RS422:
+	/* Set the appropriate GIO pin */
+	PCI_OUTW((&p->ip_ioc4->gppr_0 + H_RS422), 1);
+	break;
+
+      default:
+	return(1);
+    }
+
+    return(0);
+}
+
+
+// #define IS_PORT_0(p) ((p)->ip_hooks == &hooks_array[0])
+
+static int
+ioc4_get_mapid(sioport_t *port, void *arg)
+{
+    return(0);
+}
+
+
+static int
+ioc4_set_sscr(sioport_t *port, int arg, int flag)
+{
+    ioc4port_t *p = LPORT(port);
+
+    if ( flag ) {             /* reset arg bits in p->ip_sscr */
+	p->ip_sscr &= ~arg;
+    } else {                  /* set bits in p->ip_sscr */
+	p->ip_sscr |= arg;
+    }
+    PCI_OUTW(&p->ip_serial->sscr, p->ip_sscr);
+    return(p->ip_sscr);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/sn2/klconflib.c linux-2.4.23-pre8/arch/ia64/sn/io/sn2/klconflib.c
--- linux-2.4.22/arch/ia64/sn/io/sn2/klconflib.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/sn2/klconflib.c	2003-10-22 22:49:21.000000000 +0000
@@ -39,7 +39,7 @@
 static int hasmetarouter;
 
 
-char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#=012345";
+char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#=vo2345";
 
 lboard_t *
 find_lboard(lboard_t *start, unsigned char brd_type)
@@ -278,6 +278,8 @@
 				board_name = EDGE_LBL_XBRICK;
 			else if (brd->brd_type == KLTYPE_PEBRICK)
 				board_name = EDGE_LBL_PEBRICK;
+			else if (brd->brd_type == KLTYPE_OPUSBRICK)
+				board_name = EDGE_LBL_OPUSBRICK;
 			else if (brd->brd_type == KLTYPE_CGBRICK)
 				board_name = EDGE_LBL_CGBRICK;
 			else
@@ -293,23 +295,6 @@
 	sprintf(path, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d/%s", buffer, geo_slab(brd->brd_geoid), board_name);
 }
 
-/*
- * Get the module number for a NASID.
- */
-moduleid_t
-get_module_id(nasid_t nasid)
-{
-	lboard_t *brd;
-
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-
-	if (!brd)
-		return INVALID_MODULE;
-	else
-		return geo_module(brd->brd_geoid);
-}
-
-
 #define MHZ	1000000
 
 
@@ -419,7 +404,13 @@
 	strcpy(serial_number,"");
 	switch(KLCLASS(board->brd_type)) {
 	case KLCLASS_CPU: {	/* Node board */
-		klhub_t	*hub;
+		klhub_t *hub;
+
+		if (board->brd_type == KLTYPE_TIO) {
+			printk("*****board_serial_number_get: Need to support TIO.*****\n");
+			strcpy(serial_number,"");
+			return(0);
+		}
 		
 		/* Get the hub component information */
 		hub = (klhub_t *)find_first_component(board,
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/sn2/klgraph.c linux-2.4.23-pre8/arch/ia64/sn/io/sn2/klgraph.c
--- linux-2.4.22/arch/ia64/sn/io/sn2/klgraph.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/sn2/klgraph.c	2003-10-22 22:47:34.000000000 +0000
@@ -42,6 +42,7 @@
 extern char arg_maxnodes[];
 extern u64 klgraph_addr[];
 void mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid);
+extern int is_specified(char *);
 
 
 /*
@@ -54,7 +55,7 @@
 {
 	invent_generic_t *invent;
 
-	invent = kern_malloc(size);
+	invent = kmalloc(size, GFP_KERNEL);
 	if (!invent) return NULL;
 	
 	invent->ig_module = NODE_MODULEID(cnode);
@@ -205,6 +206,30 @@
 
 /* ARGSUSED */
 void
+klhwg_add_ice(vertex_hdl_t node_vertex, klhub_t *hub, cnodeid_t cnode)
+{
+	vertex_hdl_t myicev;
+	vertex_hdl_t ice_mon;
+	int rc;
+	extern struct file_operations shub_mon_fops;
+
+	(void) hwgraph_path_add(node_vertex, EDGE_LBL_ICE, &myicev);
+
+	HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, myicev, NULL, "Created path for ice vertex for TIO node.\n"));
+
+	rc = device_master_set(myicev, node_vertex);
+	if (rc)
+		panic("klhwg_add_ice: Unable to create ice vertex.\n");
+
+	ice_mon = hwgraph_register(myicev, EDGE_LBL_PERFMON,
+		0, DEVFS_FL_AUTO_DEVNUM,
+		0, 0,
+		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+		&shub_mon_fops, (void *)(long)cnode);
+}
+
+/* ARGSUSED */
+void
 klhwg_add_hub(vertex_hdl_t node_vertex, klhub_t *hub, cnodeid_t cnode)
 {
 	vertex_hdl_t myhubv;
@@ -214,7 +239,13 @@
 
 	GRPRINTF(("klhwg_add_hub: adding %s\n", EDGE_LBL_HUB));
 	(void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv);
+
+	HWGRAPH_DEBUG((__FILE__, __FUNCTION__,__LINE__, myhubv, NULL, "Created path for hub vertex for Shub node.\n"));
+
 	rc = device_master_set(myhubv, node_vertex);
+	if (rc)
+		panic("klhwg_add_hub: Unable to create hub vertex.\n");
+
 	hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON,
 		0, DEVFS_FL_AUTO_DEVNUM,
 		0, 0,
@@ -237,6 +268,8 @@
 		sprintf(name, "%s/%s/%c", EDGE_LBL_DISABLED, EDGE_LBL_CPU, 'a' + cpu->cpu_info.physid);
 		(void) hwgraph_path_add(node_vertex, name, &my_cpu);
 
+		HWGRAPH_DEBUG((__FILE__, __FUNCTION__,__LINE__, my_cpu, NULL, "Created path for disabled cpu slice.\n"));
+
 		mark_cpuvertex_as_cpu(my_cpu, cpu_id);
 		device_master_set(my_cpu, node_vertex);
 
@@ -264,6 +297,9 @@
 
         GRPRINTF(("klhwg_add_cpu: adding %s to vertex 0x%p\n", name, node_vertex));
         (void) hwgraph_path_add(node_vertex, name, &my_cpu);
+
+	HWGRAPH_DEBUG((__FILE__, __FUNCTION__,__LINE__, my_cpu, NULL, "Created path for active cpu slice.\n"));
+
         mark_cpuvertex_as_cpu(my_cpu, cpu_id);
         device_master_set(my_cpu, node_vertex);
 
@@ -271,6 +307,7 @@
         if (hwgraph_edge_get(node_vertex, EDGE_LBL_CPU, &cpu_dir) == GRAPH_SUCCESS) {
                 sprintf(name, "%c", 'a' + cpu->cpu_info.physid);
                 (void) hwgraph_edge_add(cpu_dir, my_cpu, name);
+		HWGRAPH_DEBUG((__FILE__, __FUNCTION__,__LINE__, cpu_dir, my_cpu, "Created % from vhdl1 to vhdl2.\n", name));
         }
 
         klhwg_cpu_invent_info(my_cpu, cnode, cpu);
@@ -278,6 +315,41 @@
 
 
 void
+klhwg_add_coretalk(cnodeid_t cnode, nasid_t tio_nasid)
+{
+	lboard_t *brd;
+	vertex_hdl_t coretalk_v, icev;
+	/*REFERENCED*/
+	graph_error_t err;
+
+	if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(tio_nasid), KLTYPE_IOBRICK_XBOW)) == NULL)
+			return;
+
+	if (KL_CONFIG_DUPLICATE_BOARD(brd))
+	    return;
+
+	icev = cnodeid_to_vertex(cnode);
+
+	err = hwgraph_path_add(icev, EDGE_LBL_CORETALK, &coretalk_v);
+	if (err != GRAPH_SUCCESS) {
+		if (err == GRAPH_DUP)
+			printk(KERN_WARNING  "klhwg_add_coretalk: Check for "
+                                        "working routers and router links!");
+
+                 panic("klhwg_add_coretalkk: Failed to add "
+                             "edge: vertex 0x%p to vertex 0x%p,"
+                             "error %d\n",
+                              (void *)icev, (void *)coretalk_v, err);
+        }
+
+	HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, coretalk_v, NULL, "Created coretalk path for TIO node.\n"));
+
+        NODEPDA(cnode)->xbow_vhdl = coretalk_v;
+
+}
+
+
+void
 klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid)
 {
 	lboard_t *brd;
@@ -295,9 +367,6 @@
 	if (KL_CONFIG_DUPLICATE_BOARD(brd))
 	    return;
 
-	GRPRINTF(("klhwg_add_xbow: adding cnode %d nasid %d xbow edges\n",
-			cnode, nasid));
-
 	if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW))
 	    == NULL)
 	    return;
@@ -326,11 +395,14 @@
                                 printk(KERN_WARNING  "klhwg_add_xbow: Check for "
                                         "working routers and router links!");
 
-                        PRINT_PANIC("klhwg_add_xbow: Failed to add "
+                        panic("klhwg_add_xbow: Failed to add "
                                 "edge: vertex 0x%p to vertex 0x%p,"
                                 "error %d\n",
                                 (void *)hubv, (void *)xbow_v, err);
                 }
+
+		HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, xbow_v, NULL, "Created path for xtalk.\n"));
+
 		xswitch_vertex_init(xbow_v); 
 
 		NODEPDA(hub_cnode)->xbow_vhdl = xbow_v;
@@ -345,14 +417,71 @@
 				hub_nasid;
 		}
 
-		GRPRINTF(("klhwg_add_xbow: adding port nasid %d %s to vertex 0x%p\n",
-			hub_nasid, EDGE_LBL_XTALK, hubv));
 	}
 }
 
 
 /* ARGSUSED */
 void
+klhwg_add_tionode(vertex_hdl_t hwgraph_root, cnodeid_t cnode)
+{
+	nasid_t tio_nasid;
+	lboard_t *brd;
+	klhub_t *hub;
+	vertex_hdl_t node_vertex = NULL;
+	char path_buffer[100];
+	int rv;
+	char *s;
+	int board_disabled = 0;
+
+	tio_nasid = COMPACT_TO_NASID_NODEID(cnode);
+	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(tio_nasid), KLTYPE_TIO);
+	ASSERT(brd);
+
+	/* Generate a hardware graph path for this board. */
+	board_to_path(brd, path_buffer);
+	rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
+	if (rv != GRAPH_SUCCESS)
+		panic("TIO Node vertex creation failed.  "
+					  "Path == %s", path_buffer);
+
+	HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, node_vertex, NULL, "Created path for TIO node.\n"));
+	hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
+	ASSERT(hub);
+	if(hub->hub_info.flags & KLINFO_ENABLE)
+		board_disabled = 0;
+	else
+		board_disabled = 1;
+
+	if(!board_disabled) {
+		mark_nodevertex_as_node(node_vertex,
+				    cnode + board_disabled * numionodes);
+
+		s = dev_to_name(node_vertex, path_buffer, sizeof(path_buffer));
+		NODEPDA(cnode)->hwg_node_name =
+					kmalloc(strlen(s) + 1,
+					GFP_KERNEL);
+		ASSERT_ALWAYS(NODEPDA(cnode)->hwg_node_name != NULL);
+		strcpy(NODEPDA(cnode)->hwg_node_name, s);
+
+		hubinfo_set(node_vertex, NODEPDA(cnode)->pdinfo);
+
+		/* Set up node board's slot */
+		NODEPDA(cnode)->slotdesc = brd->brd_slot;
+
+		/* Set up the module we're in */
+		NODEPDA(cnode)->geoid = brd->brd_geoid;
+		NODEPDA(cnode)->module = module_lookup(geo_module(brd->brd_geoid));
+	}
+
+        if(!board_disabled)
+                klhwg_add_ice(node_vertex, hub, cnode);
+
+}
+
+
+/* ARGSUSED */
+void
 klhwg_add_node(vertex_hdl_t hwgraph_root, cnodeid_t cnode)
 {
 	nasid_t nasid;
@@ -367,8 +496,6 @@
 
 	nasid = COMPACT_TO_NASID_NODEID(cnode);
 	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-	GRPRINTF(("klhwg_add_node: Adding cnode %d, nasid %d, brd 0x%p\n",
-                cnode, nasid, brd));
 	ASSERT(brd);
 
 	do {
@@ -376,16 +503,11 @@
 
 		/* Generate a hardware graph path for this board. */
 		board_to_path(brd, path_buffer);
-
-		GRPRINTF(("klhwg_add_node: adding %s to vertex 0x%p\n",
-			path_buffer, hwgraph_root));
 		rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
-
 		if (rv != GRAPH_SUCCESS)
-			PRINT_PANIC("Node vertex creation failed.  "
-					  "Path == %s",
-				path_buffer);
+			panic("Node vertex creation failed.  Path == %s", path_buffer);
 
+		HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, node_vertex, NULL, "Created path for SHUB node.\n"));
 		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
 		ASSERT(hub);
 		if(hub->hub_info.flags & KLINFO_ENABLE)
@@ -427,6 +549,8 @@
 			rv = hwgraph_path_add(node_vertex, EDGE_LBL_CPU, &cpu_dir);
 			if (rv != GRAPH_SUCCESS)
 				panic("klhwg_add_node: Cannot create CPU directory\n");
+			HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, cpu_dir, NULL, "Created cpu directiry on SHUB node.\n"));
+
 		}
 
 		/* Add each CPU */
@@ -467,48 +591,34 @@
 
 	for (cnode = 0; cnode < numnodes; cnode++) {
 		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_add_all_routers: adding router on cnode %d\n",
-			cnode));
-
 		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
 				KLTYPE_ROUTER);
-
 		if (!brd)
 			/* No routers stored in this node's memory */
 			continue;
 
 		do {
 			ASSERT(brd);
-			GRPRINTF(("Router board struct is %p\n", brd));
 
 			/* Don't add duplicate boards. */
 			if (brd->brd_flags & DUPLICATE_BOARD)
 				continue;
 
-			GRPRINTF(("Router 0x%p module number is %d\n", brd, brd->brd_geoid));
 			/* Generate a hardware graph path for this board. */
 			board_to_path(brd, path_buffer);
 
-			GRPRINTF(("Router path is %s\n", path_buffer));
-
 			/* Add the router */
-			GRPRINTF(("klhwg_add_all_routers: adding %s to vertex 0x%p\n",
-				path_buffer, hwgraph_root));
 			rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
-
 			if (rv != GRAPH_SUCCESS)
-				PRINT_PANIC("Router vertex creation "
+				panic("Router vertex creation "
 						  "failed.  Path == %s",
 					path_buffer);
 
-			GRPRINTF(("klhwg_add_all_routers: get next board from 0x%p\n",
-					brd));
+			HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, node_vertex, NULL, "Created router path.\n"));
+
 		/* Find the rest of the routers stored on this node. */
 		} while ( (brd = find_lboard_class(KLCF_NEXT(brd),
 			 KLTYPE_ROUTER)) );
-
-		GRPRINTF(("klhwg_add_all_routers: Done.\n"));
 	}
 
 }
@@ -527,13 +637,8 @@
 	int port;
 	lboard_t *dest_brd;
 
-	GRPRINTF(("klhwg_connect_one_router: Connecting router on cnode %d\n",
-			cnode));
-
 	/* Don't add duplicate boards. */
 	if (brd->brd_flags & DUPLICATE_BOARD) {
-		GRPRINTF(("klhwg_connect_one_router: Duplicate router 0x%p on cnode %d\n",
-			brd, cnode));
 		return;
 	}
 
@@ -550,7 +655,7 @@
 
 	/* We don't know what to do with multiple router components */
 	if (brd->brd_numcompts != 1) {
-		PRINT_PANIC("klhwg_connect_one_router: %d cmpts on router\n",
+		panic("klhwg_connect_one_router: %d cmpts on router\n",
 			brd->brd_numcompts);
 		return;
 	}
@@ -584,15 +689,12 @@
 		if (rc != GRAPH_SUCCESS) {
 			if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
 				continue;
-			PRINT_PANIC("Can't find router: %s", dest_path);
+			panic("Can't find router: %s", dest_path);
 		}
-		GRPRINTF(("klhwg_connect_one_router: Link from %s/%d to %s\n",
-			  path_buffer, port, dest_path));
 
 		sprintf(dest_path, "%d", port);
 
 		rc = hwgraph_edge_add(router_hndl, dest_hndl, dest_path);
-
 		if (rc == GRAPH_DUP) {
 			GRPRINTF(("Skipping port %d. nasid %d %s/%s\n",
 				  port, router->rou_port[port].port_nasid,
@@ -601,8 +703,10 @@
 		}
 
 		if (rc != GRAPH_SUCCESS && !is_specified(arg_maxnodes))
-			PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n",
+			panic("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n",
 				path_buffer, dest_path, (void *)dest_hndl, rc);
+
+		HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, router_hndl, dest_hndl, "Created edge %s from vhdl1 to vhdl2.\n", dest_path));
 		
 	}
 }
@@ -656,14 +760,16 @@
 	graph_error_t rc;
 	int port;
 
-	for (cnode = 0; cnode < numnodes; cnode++) {
+	for (cnode = 0; cnode < numionodes; cnode++) {
 		nasid = COMPACT_TO_NASID_NODEID(cnode);
 
-		GRPRINTF(("klhwg_connect_hubs: Connecting hubs on cnode %d\n",
-			cnode));
-
-		brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-		ASSERT(brd);
+		if (!(nasid & 1)) {
+			brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
+			ASSERT(brd);
+		} else {
+			brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_TIO);
+			ASSERT(brd);
+		}
 
 		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
 		ASSERT(hub);
@@ -680,10 +786,7 @@
 
 			/* Generate a hardware graph path for this board. */
 			board_to_path(brd, path_buffer);
-
-			GRPRINTF(("klhwg_connect_hubs: Hub path is %s.\n", path_buffer));
 			rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl);
-
 			if (rc != GRAPH_SUCCESS)
 				printk(KERN_WARNING  "Can't find hub: %s", path_buffer);
 
@@ -699,7 +802,7 @@
 			if (rc != GRAPH_SUCCESS) {
 				if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
 					continue;
-				PRINT_PANIC("Can't find board: %s", dest_path);
+				panic("Can't find board: %s", dest_path);
 			} else {
 				char buf[1024];
 		
@@ -708,13 +811,18 @@
 			  	path_buffer, dest_path));
 
 				rc = hwgraph_path_add(hub_hndl, EDGE_LBL_INTERCONNECT, &hub_hndl);
+
+				HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, hub_hndl, NULL, "Created link path.\n"));
+
 				sprintf(buf,"%s/%s",path_buffer,EDGE_LBL_INTERCONNECT);
 				rc = hwgraph_traverse(hwgraph_root, buf, &hub_hndl);
 				sprintf(buf,"%d",port);
 				rc = hwgraph_edge_add(hub_hndl, dest_hndl, buf);
 
+				HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, hub_hndl, dest_hndl, "Created edge %s from vhdl1 to vhdl2.\n", buf));
+
 				if (rc != GRAPH_SUCCESS)
-					PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n",
+					panic("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n",
 					path_buffer, dest_path, (void *)dest_hndl, rc);
 
 			}
@@ -806,7 +914,8 @@
 
 		rc = hwgraph_path_add(hwgraph_root, name, &module_vhdl);
 		ASSERT(rc == GRAPH_SUCCESS);
-		rc = rc;
+		rc = rc; /* Shut the compiler up */
+		HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, module_vhdl, NULL, "Created module path.\n"));
 
 		hwgraph_fastinfo_set(module_vhdl, (arbitrary_info_t) modules[cm]);
 
@@ -816,12 +925,13 @@
 			buffer);
 
 		rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
-		ASSERT_ALWAYS(rc == GRAPH_SUCCESS); 
-		rc = rc;
+		ASSERT_ALWAYS(rc == GRAPH_SUCCESS);
+		rc = rc; /* Shut the compiler up */
+		HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, vhdl, NULL, "Created L1 path.\n"));
 
 		hwgraph_info_add_LBL(vhdl,
 				     INFO_LBL_ELSC,
-				     (arbitrary_info_t) (__psint_t) 1);
+				     (arbitrary_info_t) (int64_t) 1);
 
 	}
 }
@@ -835,10 +945,18 @@
 		klhwg_add_node(hwgraph_root, cnode);
 	}
 
+	for (cnode = numnodes; cnode < numionodes; cnode++) {
+		klhwg_add_tionode(hwgraph_root, cnode);
+	}
+
 	for (cnode = 0; cnode < numnodes; cnode++) {
 		klhwg_add_xbow(cnode, cnodeid_to_nasid(cnode));
 	}
 
+	for (cnode = numnodes; cnode < numionodes; cnode++) {
+		klhwg_add_coretalk(cnode, cnodeid_to_nasid(cnode));
+	}
+
 	/*
 	 * As for router hardware inventory information, we set this
 	 * up in router.c. 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/sn2/l1_command.c linux-2.4.23-pre8/arch/ia64/sn/io/sn2/l1_command.c
--- linux-2.4.22/arch/ia64/sn/io/sn2/l1_command.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/sn2/l1_command.c	2003-10-22 22:48:00.000000000 +0000
@@ -60,8 +60,6 @@
 	*rack = (result & MODULE_RACK_MASK) >> MODULE_RACK_SHFT;
 	*bay = (result & MODULE_BPOS_MASK) >> MODULE_BPOS_SHFT;
 	*brick_type = (result & MODULE_BTYPE_MASK) >> MODULE_BTYPE_SHFT;
-	*brick_type = toupper(*brick_type);
-
 	return 0;
 }
 
@@ -113,12 +111,16 @@
 	brick_type = MODULE_IXBRICK; break;
       case L1_BRICKTYPE_PX: 
 	brick_type = MODULE_PXBRICK; break;
+      case L1_BRICKTYPE_OPUS: 
+	brick_type = MODULE_OPUSBRICK; break;
       case L1_BRICKTYPE_I: 
 	brick_type = MODULE_IBRICK; break;
       case L1_BRICKTYPE_P:
 	brick_type = MODULE_PBRICK; break;
       case L1_BRICKTYPE_X:
 	brick_type = MODULE_XBRICK; break;
+      case L1_BRICKTYPE_CHI_CG:
+	brick_type = MODULE_CGBRICK; break;
     }
 
     ret = RBT_TO_MODULE(rack, bay, brick_type);
@@ -179,25 +181,31 @@
         return("Unknown");
 
     case L1_BRICKTYPE_X:
-        return("Xbrick");
+        return(EDGE_LBL_XBRICK);
 
     case L1_BRICKTYPE_I:
-        return("Ibrick");
+        return(EDGE_LBL_IBRICK);
 
     case L1_BRICKTYPE_P:
-        return("Pbrick");
+        return(EDGE_LBL_PBRICK);
 
     case L1_BRICKTYPE_PX:
-        return("PXbrick");
+        return(EDGE_LBL_PXBRICK);
+
+    case L1_BRICKTYPE_OPUS:
+        return(EDGE_LBL_OPUSBRICK);
 
     case L1_BRICKTYPE_IX:
-        return("IXbrick");
+        return(EDGE_LBL_IXBRICK);
 
     case L1_BRICKTYPE_C:
         return("Cbrick");
 
     case L1_BRICKTYPE_R:
         return("Rbrick");
+
+    case L1_BRICKTYPE_CHI_CG:
+        return(EDGE_LBL_CGBRICK);
     }
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/sn2/ml_SN_init.c linux-2.4.23-pre8/arch/ia64/sn/io/sn2/ml_SN_init.c
--- linux-2.4.22/arch/ia64/sn/io/sn2/ml_SN_init.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/sn2/ml_SN_init.c	2003-10-22 22:49:19.000000000 +0000
@@ -25,49 +25,6 @@
 
 extern xwidgetnum_t hub_widget_id(nasid_t);
 
-extern void iograph_early_init(void);
-
-nasid_t master_nasid = INVALID_NASID;		/* This is the partition master nasid */
-nasid_t master_baseio_nasid = INVALID_NASID;	/* This is the master base I/O nasid */
-
-
-/*
- * mlreset(void)
- * 	very early machine reset - at this point NO interrupts have been
- * 	enabled; nor is memory, tlb, p0, etc setup.
- *
- * 	slave is zero when mlreset is called for the master processor and
- *	is nonzero thereafter.
- */
-
-
-void
-mlreset(int slave)
-{
-	/*
-	 * We are the master cpu and node.
-	 */ 
-	master_nasid = get_nasid();
-	set_master_bridge_base();
-
-	/* We're the master processor */
-	master_procid = smp_processor_id();
-	master_nasid = cpuid_to_nasid(master_procid);
-
-	/*
-	 * master_nasid we get back better be same as one from
-	 * get_nasid()
-	 */
-	ASSERT_ALWAYS(master_nasid == get_nasid());
-
-	/* early initialization of iograph */
-	iograph_early_init();
-
-	/* Initialize Hub Pseudodriver Management */
-	hubdev_init();
-}
-
-
 /* XXX - Move the meat of this to intr.c ? */
 /*
  * Set up the platform-dependent fields in the nodepda.
@@ -86,11 +43,9 @@
 	npda->pdinfo = (void *)hubinfo;
 	hubinfo->h_nodepda = npda;
 	hubinfo->h_cnodeid = node;
-	hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(node);
 
 	spin_lock_init(&hubinfo->h_crblock);
 
-	hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid);
 	npda->xbow_peer = INVALID_NASID;
 
 	/* 
@@ -107,7 +62,22 @@
 	npda->npda_rip_last = &npda->npda_rip_first;
 	npda->geoid.any.type = GEO_TYPE_INVALID;
 
-	mutex_init_locked(&npda->xbow_sema); /* init it locked? */
+	init_MUTEX_LOCKED(&npda->xbow_sema); /* init it locked? */
+}
+
+void
+init_platform_hubinfo(nodepda_t **nodepdaindr) {
+	cnodeid_t       cnode;
+	hubinfo_t hubinfo;
+	nodepda_t *npda;
+
+	for (cnode = 0; cnode < numionodes; cnode++) {
+		npda = nodepdaindr[cnode];
+		hubinfo = (hubinfo_t)npda->pdinfo;
+		hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(cnode);
+		/* For TIO the following returns -1 */
+		hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid);
+	}
 }
 
 void
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/sn2/ml_SN_intr.c linux-2.4.23-pre8/arch/ia64/sn/io/sn2/ml_SN_intr.c
--- linux-2.4.22/arch/ia64/sn/io/sn2/ml_SN_intr.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/sn2/ml_SN_intr.c	2003-10-22 22:47:51.000000000 +0000
@@ -102,7 +102,7 @@
 
 	local5_config.sh_local_int5_config_regval = 0;
 	local5_config.sh_local_int5_config_s.idx = SGI_UART_VECTOR;
-	local5_config.sh_local_int5_config_s.pid = cpu0;
+	local5_config.sh_local_int5_config_s.pid = cpu;
 	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_CONFIG),
 		local5_config.sh_local_int5_config_regval);
 
@@ -366,6 +366,7 @@
 	vertex_hdl_t	pconn_vhdl;
 	pcibr_soft_t	pcibr_soft;
 	int 		bit;
+	static cnodeid_t last_node = 0;
 
 /* SN2 + pcibr addressing limitation */
 /* Due to this limitation, all interrupts from a given bridge must go to the name node.*/
@@ -413,18 +414,20 @@
 
 	if (candidate  != CPU_NONE) {
 		printk("Cannot target interrupt to target node (%ld).\n",candidate);
-		return CPU_NONE; } else {
-		/* printk("Cannot target interrupt to closest node (%d) 0x%p\n",
-			master_node_get(dev), (void *)owner_dev); */
+		return CPU_NONE; 
+	} else {
+		printk("Cannot target interrupt to closest node (0x%x) 0x%p\n",
+			master_node_get(dev), (void *)owner_dev);
 	}
 
 	// We couldn't put it on the closest node.  Try to find another one.
 	// Do a stupid round-robin assignment of the node.
 
 	{
-		static cnodeid_t last_node = -1;
+		int i;
+
 		if (last_node >= numnodes) last_node = 0;
-		for (candidate_node = last_node + 1; candidate_node != last_node; candidate_node++) {
+		for (i = 0, candidate_node = last_node; i < numnodes; candidate_node++,i++) {
 			if (candidate_node == numnodes) candidate_node = 0;
 			cpuid = intr_bit_reserve_test(CPU_NONE,
 							0,
@@ -435,6 +438,7 @@
 							name,
 							resp_bit);
 			if (cpuid != CPU_NONE) {
+				last_node = candidate_node + 1;
 				return cpuid;
 			}
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/sn2/ml_iograph.c linux-2.4.23-pre8/arch/ia64/sn/io/sn2/ml_iograph.c
--- linux-2.4.22/arch/ia64/sn/io/sn2/ml_iograph.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/sn2/ml_iograph.c	2003-10-22 22:49:14.000000000 +0000
@@ -49,20 +49,20 @@
  * xswitch vertex is created.
  */
 typedef struct xswitch_vol_s {
-	mutex_t xswitch_volunteer_mutex;
+	struct semaphore xswitch_volunteer_mutex;
 	int		xswitch_volunteer_count;
 	vertex_hdl_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];
 } *xswitch_vol_t;
 
+
 void
 xswitch_vertex_init(vertex_hdl_t xswitch)
 {
 	xswitch_vol_t xvolinfo;
 	int rc;
-	extern void * snia_kmem_zalloc(size_t size, int flag);
 
-	xvolinfo = snia_kmem_zalloc(sizeof(struct xswitch_vol_s), GFP_KERNEL);
-	mutex_init(&xvolinfo->xswitch_volunteer_mutex);
+	xvolinfo = snia_kmem_zalloc(sizeof(struct xswitch_vol_s));
+	init_MUTEX(&xvolinfo->xswitch_volunteer_mutex);
 	rc = hwgraph_info_add_LBL(xswitch, 
 			INFO_LBL_XSWITCH_VOL,
 			(arbitrary_info_t)xvolinfo);
@@ -108,7 +108,7 @@
 	    return;
 	}
 
-	mutex_lock(&xvolinfo->xswitch_volunteer_mutex);
+	down(&xvolinfo->xswitch_volunteer_mutex);
 	ASSERT(xvolinfo->xswitch_volunteer_count < NUM_XSWITCH_VOLUNTEER);
 	xvolinfo->xswitch_volunteer[xvolinfo->xswitch_volunteer_count] = master;
 	xvolinfo->xswitch_volunteer_count++;
@@ -126,7 +126,7 @@
 			xvolinfo->xswitch_volunteer[1] = hubv;
 		}
 	}
-	mutex_unlock(&xvolinfo->xswitch_volunteer_mutex);
+	up(&xvolinfo->xswitch_volunteer_mutex);
 }
 
 extern int xbow_port_io_enabled(nasid_t nasid, int widgetnum);
@@ -193,16 +193,16 @@
 		 * hub that owned it in the prom.
 		 */
 		if (is_master_baseio_nasid_widget(nasid, widgetnum)) {
-			extern nasid_t get_master_baseio_nasid(void);
+			extern nasid_t snia_get_master_baseio_nasid(void);
 			for (i=0; i<num_volunteer; i++) {
 				hubv = xvolinfo->xswitch_volunteer[i];
 				hubinfo_get(hubv, &hubinfo);
 				nasid = hubinfo->h_nasid;
-				if (nasid == get_master_baseio_nasid())
+				if (nasid == snia_get_master_baseio_nasid())
 					goto do_assignment;
 			}
-			PRINT_PANIC("Nasid == %d, console nasid == %d",
-				nasid, get_master_baseio_nasid());
+			panic("Nasid == %d, console nasid == %d",
+				nasid, snia_get_master_baseio_nasid());
 		}
 
 		/*
@@ -237,44 +237,12 @@
 }
 
 /*
- * Early iograph initialization.  Called by master CPU in mlreset().
- * Useful for including iograph.o in kernel.o.
- */
-void
-iograph_early_init(void)
-{
-/*
- * Need new way to get this information ..
- */
-	cnodeid_t cnode;
-	nasid_t nasid;
-	lboard_t *board;
-	
-	/*
-	 * Init. the board-to-hwgraph link early, so FRU analyzer
-	 * doesn't trip on leftover values if we panic early on.
-	 */
-	for(cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-		board = (lboard_t *)KL_CONFIG_INFO(nasid);
-		DBG("iograph_early_init: Found board 0x%p\n", board);
-
-		/* Check out all the board info stored on a node */
-		while(board) {
-			board->brd_graph_link = GRAPH_VERTEX_NONE;
-			board = KLCF_NEXT(board);
-			DBG("iograph_early_init: Found board 0x%p\n", board);
-		}
-	}
-}
-
-/*
  * Let boot processor know that we're done initializing our node's IO
  * and then exit.
  */
 /* ARGSUSED */
 static void
-io_init_done(cnodeid_t cnodeid,cpu_cookie_t c)
+io_init_done(cnodeid_t cnodeid,cpuid_t c)
 {
 	/* Let boot processor know that we're done. */
 }
@@ -414,8 +382,8 @@
 		 * If the current hub is not supposed to be the master 
 		 * for this widgetnum, then skip this widget.
 		 */
-		if (xswitch_info_master_assignment_get(xswitch_info,
-						       widgetnum) != hubv) {
+
+		if (xswitch_info_master_assignment_get(xswitch_info, widgetnum) != hubv) {
 			return;
 		}
 
@@ -461,6 +429,8 @@
 			(board->brd_type == KLTYPE_PBRICK) ? EDGE_LBL_PBRICK :
 			(board->brd_type == KLTYPE_PXBRICK) ? EDGE_LBL_PXBRICK :
 			(board->brd_type == KLTYPE_IXBRICK) ? EDGE_LBL_IXBRICK :
+			(board->brd_type == KLTYPE_CGBRICK) ? EDGE_LBL_CGBRICK :
+			(board->brd_type == KLTYPE_OPUSBRICK) ? EDGE_LBL_OPUSBRICK :
 			(board->brd_type == KLTYPE_XBRICK) ? EDGE_LBL_XBRICK : "?brick",
 			EDGE_LBL_XTALK, widgetnum);
 		
@@ -503,7 +473,6 @@
 				       hubv, hub_widgetid);
 
 		ia64_sn_sysctl_iobrick_module_get(nasid, &io_module);
-
 		if (io_module >= 0) {
 			char			buffer[16];
 			vertex_hdl_t		to, from;
@@ -514,8 +483,8 @@
 			memset(buffer, 0, 16);
 			format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF);
 
-			if ( islower(MODULE_GET_BTCHAR(io_module)) ) {
-				bt = toupper(MODULE_GET_BTCHAR(io_module));
+			if ( isupper(MODULE_GET_BTCHAR(io_module)) ) {
+				bt = tolower(MODULE_GET_BTCHAR(io_module));
 			}
 			else {
 				bt = MODULE_GET_BTCHAR(io_module);
@@ -534,13 +503,16 @@
 				EDGE_LBL_NODE "/" EDGE_LBL_XTALK "/"
 				"0",
 				buffer, geo_slab(board->brd_geoid));
+			DBG("io_xswitch_widget_init: FROM path '%s'\n", pathname);
+
 			from = hwgraph_path_to_vertex(pathname);
 			ASSERT_ALWAYS(from);
+
 			sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/"
 				EDGE_LBL_SLAB "/%d/"
 				"%s",
 				buffer, geo_slab(board->brd_geoid), brick_name);
-
+			DBG("io_xswitch_widget_init: TO path '%s'\n", pathname);
 			to = hwgraph_path_to_vertex(pathname);
 			ASSERT_ALWAYS(to);
 			rc = hwgraph_edge_add(from, to,
@@ -568,11 +540,8 @@
 	
 	DBG("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode);
 
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; 
-	     widgetnum++) {
-		io_xswitch_widget_init(xswitchv,
-				       cnodeid_to_vertex(cnode),
-				       widgetnum);
+	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
+		io_xswitch_widget_init(xswitchv, cnodeid_to_vertex(cnode), widgetnum);
 	}
 }
 
@@ -654,8 +623,7 @@
 	nodepda_t	*npdap;
 	struct semaphore *peer_sema = 0;
 	uint32_t	widget_partnum;
-	cpu_cookie_t	c = 0;
-	extern int hubdev_docallouts(vertex_hdl_t);
+	cpuid_t	c = 0;
 
 	npdap = NODEPDA(cnodeid);
 
@@ -671,8 +639,6 @@
 
 	ASSERT(hubv != GRAPH_VERTEX_NONE);
 
-	hubdev_docallouts(hubv);
-
 	/*
 	 * Read mfg info on this hub
 	 */
@@ -817,12 +783,15 @@
 		 *	5) Initialize all xwidgets on the xswitch
 		 */
 
+		DBG("call volunteer_for_widgets\n");
+
 		volunteer_for_widgets(switchv, hubv);
 
 		/* If there's someone else on this crossbow, recognize him */
 		if (npdap->xbow_peer != INVALID_NASID) {
 			nodepda_t *peer_npdap = NODEPDA(NASID_TO_COMPACT_NODEID(npdap->xbow_peer));
 			peer_sema = &peer_npdap->xbow_sema;
+			DBG("call volunteer_for_widgets again\n");
 			volunteer_for_widgets(switchv, peer_npdap->node_vertex);
 		}
 
@@ -830,13 +799,13 @@
 
 		/* Signal that we're done */
 		if (peer_sema) {
-			mutex_unlock(peer_sema);
+			up(peer_sema);
 		}
 		
 	}
 	else {
 	    /* Wait 'til master is done assigning widgets. */
-	    mutex_lock(&npdap->xbow_sema);
+	    down(&npdap->xbow_sema);
 	}
 
 #ifdef PROBE_TEST
@@ -961,7 +930,7 @@
 		else
 			DBG("none found!\n");
 
-		DELAY(15000000);
+		udelay(15000000);
 		//prom_reboot();
 		panic("FIXME: devnamefromarcs: should call prom_reboot here.\n");
 		/* NOTREACHED */
@@ -1013,10 +982,10 @@
         2,                                      /* 0x8            */
         1,                                      /* 0x9            */
         0, 0,                                   /* 0xa - 0xb      */
-        4,                                      /* 0xc            */
+        5,                                      /* 0xc            */
         6,                                      /* 0xd            */
-        3,                                      /* 0xe            */
-        5                                       /* 0xf            */
+        4,                                      /* 0xe            */
+        3                                       /* 0xf            */
     }
  },
 
@@ -1034,6 +1003,20 @@
     }
  },
 
+/* OPUSbrick widget number to PCI bus number map */
+ {      MODULE_OPUSBRICK,                       /* OPUSbrick 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            */
+        0,                                      /* 0xe            */
+        1                                       /* 0xf            */
+    }
+ },
+
 /* IXbrick widget number to PCI bus number map */
  {      MODULE_IXBRICK,                         /* IXbrick type   */ 
     /*  PCI Bus #                                  Widget #       */
@@ -1060,6 +1043,19 @@
         0,                                      /* 0xe            */
         0                                       /* 0xf            */
     }
+ },
+/* CG brick widget number to PCI bus number map */
+ {      MODULE_CGBRICK,                    /* CG brick       */
+    /*  PCI Bus #                                  Widget #       */
+    {   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
+        0,                                      /* 0x8            */
+        0,                                      /* 0x9            */
+        0, 1,                                   /* 0xa - 0xb      */
+        0,                                      /* 0xc            */
+        0,                                      /* 0xd            */
+        0,                                      /* 0xe            */
+        0                                       /* 0xf            */
+     }
  }
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/sn2/module.c linux-2.4.23-pre8/arch/ia64/sn/io/sn2/module.c
--- linux-2.4.22/arch/ia64/sn/io/sn2/module.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/sn2/module.c	2003-10-22 22:47:29.000000000 +0000
@@ -128,21 +128,26 @@
     int			i;
     char		buffer[16];
     moduleid_t		moduleid;
+    slabid_t		slab_number;
 
     memset(buffer, 0, 16);
     moduleid = geo_module(geoid);
     format_module_id(buffer, moduleid, MODULE_FORMAT_BRIEF);
-    DPRINTF("module_add_node: moduleid=%s node=%d\n", buffer, cnodeid);
+    DPRINTF("module_add_node: moduleid=%s node=%d ", buffer, cnodeid);
 
     if ((m = module_lookup(moduleid)) == 0) {
 	m = kmalloc(sizeof (module_t), GFP_KERNEL);
-	memset(m, 0 , sizeof(module_t));
 	ASSERT_ALWAYS(m);
+	memset(m, 0 , sizeof(module_t));
+
+	for (slab_number = 0; slab_number <= MAX_SLABS; slab_number++) {
+		m->nodes[slab_number] = -1;
+	}
 
 	m->id = moduleid;
 	spin_lock_init(&m->lock);
 
-	mutex_init_locked(&m->thdcnt);
+	init_MUTEX_LOCKED(&m->thdcnt);
 
 	/* Insert in sorted order by module number */
 
@@ -153,16 +158,23 @@
 	nummodules++;
     }
 
-    m->nodes[m->nodecnt] = cnodeid;
-    m->geoid[m->nodecnt] = geoid;
-    m->nodecnt++;
+    /*
+     * Save this information in the correct slab number of the node in the 
+     * module.
+     */
+    slab_number = geo_slab(geoid);
+    DPRINTF("slab number added 0x%x\n", slab_number);
 
-    DPRINTF("module_add_node: module %s now has %d nodes\n", buffer, m->nodecnt);
+    if (m->nodes[slab_number] != -1)
+	panic("module_add_node .. slab previously found\n");
+
+    m->nodes[slab_number] = cnodeid;
+    m->geoid[slab_number] = geoid;
 
     return m;
 }
 
-int module_probe_snum(module_t *m, nasid_t nasid)
+int module_probe_snum(module_t *m, nasid_t host_nasid, nasid_t nasid)
 {
     lboard_t	       *board;
     klmod_serial_num_t *comp;
@@ -172,7 +184,7 @@
     /*
      * record brick serial number
      */
-    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
+    board = find_lboard((lboard_t *) KL_CONFIG_INFO(host_nasid), KLTYPE_SNIA);
 
     if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
     {
@@ -244,21 +256,47 @@
 
     nserial = 0;
 
+    /*
+     * First pass just scan for compute node boards KLTYPE_SNIA.
+     * We do not support memoryless compute nodes.
+     */
     for (node = 0; node < numnodes; node++) {
 	nasid = COMPACT_TO_NASID_NODEID(node);
-
 	board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
 	ASSERT(board);
 
-	m = module_add_node(board->brd_geoid, node);
+	HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, NULL, NULL, "Found Shub lboard 0x%lx nasid 0x%x cnode 0x%x \n", (unsigned long)board, (int)nasid, (int)node));
 
-	if (! m->snum_valid && module_probe_snum(m, nasid))
+	m = module_add_node(board->brd_geoid, node);
+	if (! m->snum_valid && module_probe_snum(m, nasid, nasid))
 	    nserial++;
     }
 
-    DPRINTF("********found total of %d serial numbers in the system\n",
-	    nserial);
+    /*
+     * Second scan, look for TIO's board hosted by compute nodes.
+     */
+    for (node = numnodes; node < numionodes; node++) {
+	nasid_t		tio_nasid;
+	cnodeid_t	tio_node;
+	char		serial_number[16];
 
-    if (nserial == 0)
-	DPRINTF(KERN_WARNING  "io_module_init: No serial number found.\n");
+        tio_nasid = COMPACT_TO_NASID_NODEID(node);
+        board = find_lboard((lboard_t *) KL_CONFIG_INFO(tio_nasid), KLTYPE_TIO);
+	ASSERT(board);
+	tio_node = NASID_TO_COMPACT_NODEID(tio_nasid);
+
+	HWGRAPH_DEBUG((__FILE__, __FUNCTION__, __LINE__, NULL, NULL, "Found TIO lboard 0x%lx tio nasid %d tio cnode %d\n", (unsigned long)board, (int)tio_nasid, (int)tio_node));
+
+        m = module_add_node(board->brd_geoid, tio_node);
+
+	/*
+	 * Get and initialize the serial number of TIO.
+	 */
+	board_serial_number_get( board, serial_number );
+    	if( serial_number[0] != '\0' ) {
+        	encode_str_serial( serial_number, m->snum.snum_str );
+        	m->snum_valid = 1;
+		nserial++;
+	}
+    }
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c linux-2.4.23-pre8/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c
--- linux-2.4.22/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.23-pre8/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c	2003-10-22 22:49:19.000000000 +0000
@@ -86,7 +86,6 @@
     int                     num_entries, entry;
     int                     i, j;
     bridgereg_t             old_enable, new_enable;
-    int                     s;
 
     /* Probe SSRAM to determine its size. */
     old_enable = bridge->b_int_enable;
@@ -113,12 +112,10 @@
      * The read following the write is required for the Bridge war
      */
 
-    s = splhi();
     bridge->b_wid_control = (bridge->b_wid_control
 			& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
 			| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
     bridge->b_wid_control;		/* inval addr bug war */
-    splx(s);
 
     num_entries = ATE_NUM_ENTRIES(largest_working_size);
 
@@ -382,25 +379,9 @@
 	  int ate_count,
 	  bridge_ate_t ate)
 {
-	if (IS_PIC_SOFT(pcibr_soft) ) {
-    		while (ate_count-- > 0) {
-			*ate_ptr++ = ate;
-			ate += IOPGSIZE;
-		}
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(ate_ptr))) {
-    			while (ate_count-- > 0) {
-				*ate_ptr++ = __swab64(ate);
-				ate += IOPGSIZE;
-			}
-		}
-		else {
-    			while (ate_count-- > 0) {
-				*ate_ptr++ = ate;
-				ate += IOPGSIZE;
-			}
-		}
+    	while (ate_count-- > 0) {
+		*ate_ptr++ = ate;
d-				*ate9,9 @@
 	- unt-- > 0) {
o_t)xvolinfo);
@@ -108,7 +108,7 @@

+		*ate_ptr++ = ate;
d-				*ate9,9 @@
 	- u 
 	br	br	ia64/sn/i hw_random.txt	2003-10-22 22;
+		pe,7 @@he connection bd long           s;
+
+	spin_lock_irqsave(lp, s);
+	printk("%s : %d : sio_ir 0x%x sio_ies_ro 0x%x other_ir 0x%x other_ies_ro 0x%x mask 0x%x\n",
+			__FUNCTION__, __LINE__,
+			mem->sio_ir,
+			CPU: {	/* Node box mask 0x%x\n",(+			__CUNCTIONI_, __LCNE__,isplay t_get(x