diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/CREDITS linux-2.4.22-pre10/CREDITS
--- linux-2.4.21/CREDITS	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/CREDITS	2003-08-01 13:31:30.000000000 +0000
@@ -1348,7 +1348,9 @@
 N: Marcel Holtmann
 E: marcel@holtmann.org
 W: http://www.holtmann.org
-D: Author of the Linux Bluetooth Subsystem PC Card drivers
+D: Author and maintainer of the various Bluetooth HCI drivers
+D: Author and maintainer of the CAPI message transport protocol driver
+D: Various other Bluetooth related patches, cleanups and fixes
 S: Germany
 
 N: Rob W. W. Hooft
@@ -1512,6 +1514,18 @@
 S: 8103 Rein
 S: Austria
 
+N: Mitsuru Kanda
+E: mk@linux-ipv6.org
+E: mk@isl.rdc.toshiba.co.jp
+E: mk@karaba.org
+W: http://www.karaba.org/~mk/
+P: 1024D/2EC7E30D 9A35 D378 F084 9EA4 EFBA  925B 1C93 B376 F0EF BE59
+D: IPsec, IPv6
+D: USAGI/WIDE Project, TOSHIBA CORPORATION
+S: 2-47-8, Takinogawa,
+S: Kita, Tokyo 114-0023
+S: Japan
+
 N: Jan Kara
 E: jack@atrey.karlin.mff.cuni.cz
 E: jack@suse.cz
@@ -2148,6 +2162,17 @@
 S: Richardson, Texas 75081
 S: USA
 
+N: Kazunori Miyazawa
+E: miyazawa@linux-ipv6.org
+E: Kazunori.Miyazawa@jp.yokogawa.com
+E: kazunori@miyazawa.org
+W: http://www.miyazawa.org/~kazunori/
+D: IPsec, IPv6
+D: USAGI/WIDE Project, Yokogawa Electric Corporation
+S: 2-20-4-203, Nakacho,
+S: Musashino, Tokyo 180-0006
+S: Japan
+
 N: Patrick Mochel
 E: pat@osdl.org
 E: mochelp@infinity.powertie.org
@@ -2687,6 +2712,14 @@
 E: gt8134b@prism.gatech.edu
 D: Dosemu
 
+N: Duncan Sands
+E: duncan.sands@wanadoo.fr
+W: http://topo.math.u-psud.fr/~sands
+D: Alcatel SpeedTouch USB driver
+S: 69 rue Dunois
+S: 75013 Paris
+S: France
+
 N: Hannu Savolainen
 E: hannu@opensound.com
 D: Maintainer of the sound drivers until 2.1.x days.
@@ -3327,6 +3360,17 @@
 D: Workbit NinjaSCSI-32Bi/UDE driver
 S: Japan
 
+N: Hideaki YOSHIFUJI
+E: hideaki@yoshifuji.org
+E: yoshfuji@linux-ipv6.org
+W: http://www.yoshifuji.org/~hideaki/
+P: 1024D/E0620EEA 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA
+D: IPv6 and other networking related stuff
+D: USAGI/WIDE Project, The University of Tokyo
+S: Green House #102, 1-15-5, Nishikata, 
+S: Bunkyo, Tokyo 113-0024
+S: Japan
+
 N: Eric Youngdale
 E: eric@andante.org
 W: http://www.andante.org
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/Configure.help linux-2.4.22-pre10/Documentation/Configure.help
--- linux-2.4.21/Documentation/Configure.help	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/Configure.help	2003-08-01 13:34:34.000000000 +0000
@@ -12,8 +12,8 @@
 #     <http://nevod.perm.su/service/linux/doc/kernel/Configure.help>
 #   - French, by Pierre Tane <mailto:tanep@bigfoot.com>, at
 #     <http://www.traduc.org/kernelfr/>
-#   - Polish, by Dominik Mierzejewski <mailto:dmierzej@elka.pw.edu.pl>, at
-#     <http://home.elka.pw.edu.pl/~dmierzej/linux/kernel/>
+#   - Polish, by Dominik Mierzejewski <mailto:dominik@piorunek.pl>, at
+#     <http://www.piorunek.pl/~dominik/linux/kernel/>
 #   - German, by SuSE, at <http://www.suse.de/~ke/kernel/>. This patch
 #     also includes infrastructure to support different languages.
 #   - Catalan, by Antoni Bella <mailto:bella5@teleline.es>, at
@@ -2589,6 +2589,17 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+recent match support
+CONFIG_IP_NF_MATCH_RECENT
+  This match is used for creating one or many lists of recently
+  used addresses and then matching against that/those list(s).
+
+  Short options are available by using 'iptables -m recent -h'
+  Official Website: <http://snowman.net/projects/ipt_recent/>
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
 limit match support
 CONFIG_IP_NF_MATCH_LIMIT
   limit matching allows you to control the rate at which a rule can be
@@ -3052,6 +3063,11 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+ARP payload mangling
+CONFIG_IP_NF_ARP_MANGLE
+  Allows altering the ARP packet payload: source and destination
+  hardware and network addresses.
+
 TCP Explicit Congestion Notification support
 CONFIG_INET_ECN
   Explicit Congestion Notification (ECN) allows routers to notify
@@ -3606,6 +3622,14 @@
   Say Y here to support the Serverworks AGP card.  See 
   <http://www.serverworks.com/> for product descriptions and images.
 
+NVIDIA chipset support
+CONFIG_AGP_NVIDIA
+  This option gives you AGP support for the GLX component of the
+  XFree86 4.x on NVIDIA nForce/nForce2 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.
+
 ALI chipset support
 CONFIG_AGP_ALI
   This option gives you AGP support for the GLX component of the
@@ -4792,27 +4816,46 @@
   packed pixel and 32 bpp packed pixel. You can also use font widths
   different from 8.
 
-Matrox G100/G200/G400/G450/G550 support
-CONFIG_FB_MATROX_G100
-  Say Y here if you have a Matrox G100, G200, G400, G450, or G550
-  based video card. If you select "Advanced lowlevel driver options",
-  you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp
-  packed pixel and 32 bpp packed pixel. You can also use font widths
+CONFIG_FB_MATROX_G450
+  Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based
+  video card. If you select "Advanced lowlevel driver options", you
+  should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed
+  pixel and 32 bpp packed pixel. You can also use font widths
   different from 8.
 
   If you need support for G400 secondary head, you must first say Y to
   "I2C support" and "I2C bit-banging support" in the character devices
   section, and then to "Matrox I2C support" and "G400 second head
-  support" here in the framebuffer section.
+  support" here in the framebuffer section. G450/G550 secondary head
+  and digital output are supported without additional modules.
+  
+  The driver starts in monitor mode. You must use the matroxset tool 
+  (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to 
+  swap primary and secondary head outputs, or to change output mode.  
+  Secondary head driver always start in 640x480 resolution and you 
+  must use fbset to change it.
+
+  Do not forget that second head supports only 16 and 32 bpp
+  packed pixels, so it is a good idea to compile them into the kernel
+  too. You can use only some font widths, as the driver uses generic
+  painting procedures (the secondary head does not use acceleration
+  engine).
   
-  If you have G550, you must also compile support for G450/G550 secondary
-  head into kernel, otherwise picture will be shown only on the output you
-  are probably not using...
+  G450/G550 hardware can display TV picture only from secondary CRTC,
+  and it performs no scaling, so picture must have 525 or 625 lines.
 
-  If you need support for G450 or G550 secondary head, say Y to
-  "Matrox G450/G550 second head support" below.
+CONFIG_FB_MATROX_G100A
+  Say Y here if you have a Matrox G100, G200 or G400 based
+  video card. If you select "Advanced lowlevel driver options", you
+  should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed
+  pixel and 32 bpp packed pixel. You can also use font widths
+  different from 8.
+
+  If you need support for G400 secondary head, you must first say Y to
+  "I2C support" and "I2C bit-banging support" in the character devices
+  section, and then to "Matrox I2C support" and "G400 second head
+  support" here in the framebuffer section.
 
-Matrox I2C support
 CONFIG_FB_MATROX_I2C
   This drivers creates I2C buses which are needed for accessing the
   DDC (I2C) bus present on all Matroxes, an I2C bus which
@@ -4855,32 +4898,14 @@
   painting procedures (the secondary head does not use acceleration
   engine).
 
-Matrox G450 second head support
-CONFIG_FB_MATROX_G450
-  Say Y or M here if you want to use a secondary head (meaning two
-  monitors in parallel) on G450, or if you are using analog output
-  of G550.
-
-  If you compile it as module, two modules are created,
-  matroxfb_crtc2.o and matroxfb_g450.o. Both modules are needed if you
-  want two independent display devices.
-
-  The driver starts in monitor mode and currently does not support
-  output in TV modes.  You must use the matroxset tool (available
-  at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to swap
-  primary and secondary head outputs.  Secondary head driver always
-  start in 640x480 resolution and you must use fbset to change it.
-
-  Note on most G550 cards the analog output is the secondary head,
-  so you will need to say Y here to use it.
-
-  Also do not forget that second head supports only 16 and 32 bpp
-  packed pixels, so it is a good idea to compile them into the kernel
-  too. You can use only some font widths, as the driver uses generic
-  painting procedures (the secondary head does not use acceleration
-  engine).
-
-Matrox unified driver multihead support
+CONFIG_FB_MATROX_PROC
+  Say Y or M here if you want to access some informations about driver
+  state through /proc interface.
+  
+  You should download matrox_pins tool (available at
+  <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to get human
+  readable output.
+  
 CONFIG_FB_MATROX_MULTIHEAD
   Say Y here if you have more than one (supported) Matrox device in
   your computer and you want to use all of them for different monitors
@@ -5476,11 +5501,6 @@
   handled by the klogd daemon which is responsible for kernel messages
   ("man klogd").
 
-Large routing tables
-CONFIG_IP_ROUTE_LARGE_TABLES
-  If you have routing zones that grow to more than about 64 entries,
-  you may want to say Y here to speed up the routing process.
-
 Fast network address translation
 CONFIG_IP_ROUTE_NAT
   If you say Y here, your router will be able to modify source and
@@ -6904,6 +6924,15 @@
   the performances of the driver, and the size of your syslog files!
   Keep the debugging level to 0 during normal operations.
 
+ForeRunner HE Series
+CONFIG_ATM_HE
+  This is a driver for the Marconi ForeRunner HE-series ATM adapter
+  cards. It simultaneously supports the 155 and 622 versions.
+
+Use S/UNI PHY driver
+  Support for the S/UNI-Ultra and S/UNI-622 found in the ForeRunner
+  HE cards.  This driver provides carrier detection some statistics.
+
 PPP over ATM
 CONFIG_PPPOATM
   Support PPP (Point to Point Protocol) encapsulated in ATM frames.
@@ -7290,47 +7319,40 @@
 
 Adaptec AIC7xxx support
 CONFIG_SCSI_AIC7XXX
-  This driver supports all of Adaptec's PCI based SCSI controllers
-  (not the hardware RAID controllers though) as well as the aic7770
-  based EISA and VLB SCSI controllers (the 274x and 284x series).
-  This is an Adaptec sponsored driver written by Justin Gibbs.  It is
-  intended to replace the previous aic7xxx driver maintained by Doug
-  Ledford since Doug is no longer maintaining that driver.
+  This driver supports all of Adaptec's Fast through Ultra 160 PCI
+  based SCSI controllers as well as the aic7770 based EISA and VLB
+  SCSI controllers (the 274x and 284x series).  For AAA and ARO based
+  configurations, only SCSI functionality is provided.
 
   If you want to compile the driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
   say M here and read <file:Documentation/modules.txt>.  The module
   will be called aic7xxx.o.
 
-Adaptec I2O RAID support
-CONFIG_SCSI_DPT_I2O
-  This driver supports all of Adaptec's I2O based RAID controllers as 
-  well as the DPT SmartRaid V cards.  This is an Adaptec maintained
-  driver by Deanna Bonds.  See <file:drivers/scsi/README.dpti>.
-
-  This driver is also available as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you want).
-  If you want to compile it as a module, say M here and read
-  <file:Documentation/modules.txt>.  The module will be called
-  dpt_i2o.o.
-
-Default number of TCQ commands per device
+Maximum number of TCQ commands per device
 CONFIG_AIC7XXX_CMDS_PER_DEVICE
   Specify the number of commands you would like to allocate per SCSI
   device when Tagged Command Queueing (TCQ) is enabled on that device.
 
   This is an upper bound value for the number of tagged transactions
   to be used for any device.  The aic7xxx driver will automatically
-  vary this number based on device behaviour.  For devices with a
+  vary this number based on device behavior.  For devices with a
   fixed maximum, the driver will eventually lock to this maximum
   and display a console message indicating this value.
 
-  Note: Unless you experience some type of device failure, the default
-	value, no enforced limit, should work for you.
+  Due to resource allocation issues in the Linux SCSI mid-layer, using
+  a high number of commands per device may result in memory allocation
+  failures when many devices are attached to the system.  For this reason,
+  the default is set to 32.  Higher values may result in higer performance
+  on some devices.  The upper bound is 253. 0 disables tagged queueing.
 
-  Default: 253
+  Per device tag depth can be controlled via the kernel command line
+  "tag_info" option.  See drivers/scsi/aic7xxx/README.aic7xxx
+  for details.
 
-Delay in seconds after SCSI bus reset
+  Default: 32
+
+Initial bus reset delay in milli-seconds
 CONFIG_AIC7XXX_RESET_DELAY_MS
   The number of milliseconds to delay after an initial bus reset.
   The bus settle delay following all error recovery actions is
@@ -7338,16 +7360,43 @@
 
   Default: 15000 (15 seconds)
 
-Build Adapter Firmware with Kernel Build
+Probe for EISA and VL AIC7XXX Adapters
+CONFIG_AIC7XXX_PROBE_EISA_VL
+   Probe for EISA and VLB Aic7xxx controllers.  In many newer systems,
+   the invasive probes necessary to detect these controllers can cause
+   other devices to fail.  For this reason, the non-PCI probe code is
+   disabled by default.  The current value of this option can be "toggled"
+   via the no_probe kernel command line option.
+
 CONFIG_AIC7XXX_BUILD_FIRMWARE
   This option should only be enabled if you are modifying the firmware
   source to the aic7xxx driver and wish to have the generated firmware
   include files updated during a normal kernel build.  The assembler
   for the firmware requires lex and yacc or their equivalents, as well
   as the db v1 library.  You may have to install additional packages
-  or modify the assembler make file or the files it includes if your
+  or modify the assembler Makefile or the files it includes if your
   build environment is different than that of the author.
 
+Compile in Debugging Code
+CONFIG_AIC7XXX_DEBUG_ENABLE
+  Compile in aic7xxx debugging code that can be useful in diagnosing
+  driver errors.
+
+Debug code enable mask (2048 for all debugging)
+CONFIG_AIC7XXX_DEBUG_MASK
+  Bit mask of debug options that is only valid if the
+  CONFIG_AIC7XXX_DEBUG_ENBLE option is enabled.  The bits in this mask
+  are defined in the drivers/scsi/aic7xxx/aic7xxx.h - search for the
+  variable ahc_debug in that file to find them.
+
+  Default: 0
+
+Decode registers during diagnostics
+CONFIG_AIC7XXX_REG_PRETTY_PRINT
+  Compile in register value tables for the output of expanded register
+  contents in diagnostics.  This make it much easier to understand debug
+  output without having to refer to a data book and/or the aic7xxx.reg file.
+
 Old Adaptec AIC7xxx support
 CONFIG_SCSI_AIC7XXX_OLD
   WARNING This driver is an older aic7xxx driver and is no longer
@@ -7456,6 +7505,83 @@
 
   If unsure, say N.
 
+CONFIG_SCSI_AIC79XX
+  This driver supports all of Adaptec's Ultra 320 PCI-X based SCSI controllers.
+
+CONFIG_AIC79XX_CMDS_PER_DEVICE 32
+  Specify the number of commands you would like to allocate per SCSI
+  device when Tagged Command Queueing (TCQ) is enabled on that device.
+
+  This is an upper bound value for the number of tagged transactions
+  to be used for any device.  The aic7xxx driver will automatically
+  vary this number based on device behavior.  For devices with a
+  fixed maximum, the driver will eventually lock to this maximum
+  and display a console message indicating this value.
+
+  Due to resource allocation issues in the Linux SCSI mid-layer, using
+  a high number of commands per device may result in memory allocation
+  failures when many devices are attached to the system.  For this reason,
+  the default is set to 32.  Higher values may result in higer performance
+  on some devices.  The upper bound is 253.
+
+  Per device tag depth can be controlled via the kernel command line
+  "tag_info" option.  See drivers/scsi/aic7xxx/README.aic79xx
+  for details.
+
+  Default: 32
+
+CONFIG_AIC79XX_RESET_DELAY_MS 15000
+  The number of milliseconds to delay after an initial bus reset.
+  The bus settle delay following all error recovery actions is
+  dictated by the SCSI layer and is not affected by this value.
+
+  Default: 15000 (15 seconds)
+
+CONFIG_AIC79XX_BUILD_FIRMWARE
+  This option should only be enabled if you are modifying the firmware
+  source to the aic7xxx driver and wish to have the generated firmware
+  include files updated during a normal kernel build.  The assembler
+  for the firmware requires lex and yacc or their equivalents, as well
+  as the db v1 library.  You may have to install additional packages
+  or modify the assembler Makefile or the files it includes if your
+  build environment is different than that of the author.
+
+CONFIG_AIC79XX_ENABLE_RD_STRM
+  Read Streaming is a U320 protocol option that should enhance performance.
+  Early U320 drive firmware actually performs slower with read streaming
+  enabled so it is disabled by default.  Read Streaming can be configured
+  in much the same way as tagged queueing using the "rd_strm" command line
+  option.  See drivers/scsi/aic7xxx/README.aic79xx for details.
+
+CONFIG_AIC79XX_DEBUG_ENABLE
+  Compile in aic79xx debugging code that can be useful in diagnosing
+  driver errors.
+
+CONFIG_AIC79XX_DEBUG_MASK
+  Bit mask of debug options that is only valid if the
+  CONFIG_AIC79XX_DEBUG_ENBLE option is enabled.  The bits in this mask
+  are defined in the drivers/scsi/aic7xxx/aic79xx.h - search for the
+  variable ahd_debug in that file to find them.
+
+  Default: 0
+
+CONFIG_AIC79XX_REG_PRETTY_PRINT
+  Compile in register value tables for the output of expanded register
+  contents in diagnostics.  This make it much easier to understand debug
+  output without having to refer to a data book and/or the aic7xxx.reg file.
+
+Adaptec I2O RAID support
+CONFIG_SCSI_DPT_I2O
+  This driver supports all of Adaptec's I2O based RAID controllers as 
+  well as the DPT SmartRaid V cards.  This is an Adaptec maintained
+  driver by Deanna Bonds.  See <file:drivers/scsi/README.dpti>.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>.  The module will be called
+  dpt_i2o.o.
+
 IBM ServeRAID support
 CONFIG_SCSI_IPS
   This is support for the IBM ServeRAID hardware RAID controllers.
@@ -11489,6 +11615,18 @@
   module, say M here and read <file:Documentation/modules.txt> as well
   as <file:Documentation/networking/net-modules.txt>.
 
+Broadcom 4400 ethernet support (EXPERIMENTAL)
+CONFIG_B44
+  If you have a network (Ethernet) controller of this type, say Y and
+  read the Ethernet-HOWTO, available from
+  <http://www.tldp.org/docs.html#howto>.
+
+  If you want to compile this as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt> as well as
+  <file:Documentation/networking/net-modules.txt>.  The module will be
+  called b44.
+
 CS89x0 support (Daynaport CS and LC cards)
 CONFIG_CS89x0
   Support for CS89x0 chipset based Ethernet cards. If you have a
@@ -11861,15 +11999,6 @@
   module, say M here and read <file:Documentation/modules.txt> as well
   as <file:Documentation/networking/net-modules.txt>.
 
-New Tulip bus configuration
-CONFIG_TULIP_MWI 
-  This configures your Tulip card specifically for the card and
-  system cache line size type you are using.
-
-  This is experimental code, not yet tested on many boards.
-
-  If unsure, say N.
-
 Use PCI shared memory for NIC registers
 CONFIG_TULIP_MMIO
   Use PCI shared memory for the NIC registers, rather than going through 
@@ -12789,10 +12918,18 @@
   If you say Y here, you will be able to set per user limits for disk
   usage (also called disk quotas). Currently, it works only for the
   ext2 file system. You need additional software in order to use quota
-  support; for details, read the Quota mini-HOWTO, available from
+  support (you can download sources from
+  <http://www.sf.net/projects/linuxquota/>). For further details, read
+  the Quota mini-HOWTO, available from
   <http://www.tldp.org/docs.html#howto>. Probably the quota
   support is only useful for multi user systems. If unsure, say N.
 
+VFS v0 quota format support
+CONFIG_QFMT_V2
+  This quota format allows using quotas with 32-bit UIDs/GIDs. If you
+  need this functionality say Y here. Note that you will need latest
+  quota utilities for new quota format with this kernel.
+
 Memory Technology Device (MTD) support
 CONFIG_MTD
   Memory Technology Devices are flash, RAM and similar chips, often
@@ -12853,22 +12990,40 @@
   <file:Documentation/modules.txt>. The module will be called
   redboot.o
 
-Compaq bootldr partition table parsing
-CONFIG_MTD_BOOTLDR_PARTS
-  The Compaq bootldr deals with multiple 'images' in flash devices
-  by putting a table in one of the first erase blocks of the device,
-  similar to a partition table, which gives the offsets, lengths and
-  names of all the images stored in the flash.
-
-  If you need code which can detect and parse this table, and register
-  MTD 'partitions' corresponding to each image in the table, enable
-  this option.
+CONFIG_MTD_CMDLINE_PARTS
+  Allow generic configuration of the MTD paritition tables via the kernel
+  command line. Multiple flash resources are supported for hardware where
+  different kinds of flash memory are available. 
 
   You will still need the parsing functions to be called by the driver
   for your particular device. It won't happen automatically. The 
   SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for 
   example.
 
+  The format for the command line is as follows:
+
+  mtdparts=<mtddef>[;<mtddef]
+  <mtddef>  := <mtd-id>:<partdef>[,<partdef>]
+  <partdef> := <size>[@offset][<name>][ro]
+  <mtd-id>  := unique id used in mapping driver/device
+  <size>    := standard linux memsize OR "-" to denote all 
+  remaining space
+  <name>    := (NAME)
+
+  Due to the way Linux handles the command line, no spaces are 
+  allowed in the partition definition, including mtd id's and partition 
+  names.
+
+  Examples:
+
+  1 flash resource (mtd-id "sa1100"), with 1 single writable partition:
+  mtdparts=sa1100:-
+
+  Same flash, but 2 named partitions, the first one being read-only:
+  mtdparts=sa1100:256k(ARMboot)ro,-(root)
+
+  If unsure, say 'N'.
+
 ARM Firmware Suite flash layout / partition parsing
 CONFIG_MTD_AFS_PARTS
   The ARM Firmware Suite allows the user to divide flash devices into
@@ -13036,6 +13191,10 @@
   If you wish to support CFI devices on a physical bus which is
   32 bits wide, say 'Y'.
 
+CONFIG_MTD_CFI_B8
+  If you wish to support CFI devices on a physical bus which is
+  64 bits wide, say 'Y'.
+
 Support 1-chip flash interleave
 CONFIG_MTD_CFI_I1
   If your flash chips are not interleaved - i.e. you only have one
@@ -13051,6 +13210,10 @@
   If your flash chips are interleaved in fours - i.e. you have four
   flash chips addressed by each bus cycle, then say 'Y'.
 
+CONFIG_MTD_CFI_I8
+  If your flash chips are interleaved in eights - i.e. you have eight
+  flash chips addressed by each bus cycle, then say 'Y'.
+
 # Choice: mtd_data_swap
 Flash cmd/query data swapping
 CONFIG_MTD_CFI_NOSWAP
@@ -13115,6 +13278,11 @@
   <file:Documentation/modules.txt>. The module will be called
   amd_flash.o
 
+CONFIG_MTD_CFI_STAA
+  The Common Flash Interface defines a number of different command
+  sets which a CFI-compliant chip may claim to implement. This code
+  provides support for one of those command sets.
+
 Support for RAM chips in bus mapping
 CONFIG_MTD_RAM
   This option enables basic support for RAM chips accessed through 
@@ -13919,11 +14087,12 @@
   The module will be called powermate.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-Aiptek 6000U/8000U tablet support
+Aiptek HyperPen tablet support
 CONFIG_USB_AIPTEK
-  Say Y here if you want to use the USB version of the Aiptek 6000U/8000U
-  tablet.  Make sure to say Y to "Event interface support"
-  (CONFIG_INPUT_EVDEV) as well.
+  Say Y here if you want to use the USB version of the Aiptek HyperPen
+  Digital Tablet (models 4000U, 5000U, 6000U, 8000U, and 12000U.)
+  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).
@@ -14620,6 +14789,24 @@
   The module will be called catc.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
+USB ASIX AX88172 based ethernet device support
+CONFIG_USB_AX8817X
+  Say Y if you want to use one of the following 10/100 USB2 Ethernet
+  devices based on the ASIX AX88172 chip.  Supported devices are:
+    Linksys USB200M
+    Netgear FA120
+    D-Link DUB-E100
+    Hawking UF200
+
+  This driver makes the adapter appear as a normal Ethernet interface,
+  typically on eth0, if it is the only ethernet device, or perhaps on
+  eth1, if you have a PCI or ISA ethernet card installed.
+
+  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 ax8817x.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
 USB Kodak DC-2xx Camera support
 CONFIG_USB_DC2XX
   Say Y here if you want to connect this type of still camera to your
@@ -14903,6 +15090,17 @@
   The module will be called dsbr100.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
+Alcatel Speedtouch USB support
+CONFIG_USB_SPEEDTOUCH
+  Say Y here if you have an Alcatel SpeedTouch USB or SpeedTouch 330
+  modem.  In order to use your modem you will need to install some user
+  space tools, see <http://www.linux-usb.org/SpeedTouch/> for details.
+
+  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 speedtch.o. If you want to compile it as
+  a module, say M here and read <file:Documentation/modules.txt>.
+
 Always do synchronous disk IO for UBD
 CONFIG_BLK_DEV_UBD_SYNC
   The User-Mode Linux port includes a driver called UBD which will let
@@ -15803,6 +16001,30 @@
 
   If unsure, say N.
 
+Allow direct I/O on files in NFS
+CONFIG_NFS_DIRECTIO
+  There are important applications whose performance or correctness
+  depends on uncached access to file data.  Database clusters (multiple
+  copies of the same instance running on separate hosts) implement their
+  own cache coherency protocol that subsumes the NFS cache protocols.
+  Applications that process datasets considerably larger than the client's
+  memory do not always benefit from a local cache.  A streaming video
+  server, for instance, has no need to cache the contents of a file.
+
+  This option enables applications to perform direct I/O on files in NFS
+  file systems using the O_DIRECT open() flag.  When O_DIRECT is set for
+  files, their data is not cached in the system's page cache.  Direct
+  read and write operations are aligned to block boundaries.  Data is
+  moved to and from user-level application buffers directly.
+
+  Unless your program is designed to use O_DIRECT properly, you are much
+  better off allowing the NFS client to manage caching for you.  Misusing
+  O_DIRECT can cause poor server performance or network storms.  This
+  kernel build option defaults OFF to avoid exposing system administrators
+  unwittingly to a potentially hazardous feature.
+
+  If unsure, say N.
+
 Root file system on NFS
 CONFIG_ROOT_NFS
   If you want your Linux box to mount its whole root file system (the
@@ -15959,7 +16181,7 @@
   say M here and read <file:Documentation/modules.txt>.  If unsure,
   say N.
 
-Apple Macintosh file system support
+Apple HFS file system support
 CONFIG_HFS_FS
   If you say Y here, you will be able to mount Macintosh-formatted
   floppy disks and hard drive partitions with full read-write access.
@@ -15972,6 +16194,21 @@
   compile it as a module, say M here and read
   <file:Documentation/modules.txt>.
 
+Apple HFS+ (Extended HFS) file system support
+CONFIG_HFSPLUS_FS
+  If you say Y here, you will be able to mount extended format
+  Macintosh-formatted hard drive partitions with full read-write access.
+
+  This file system is often called HFS+ and was introduced with
+  MacOS 8. It includes all Mac specific filesystem data such as
+  data forks and creator codes, but it also has several UNIX
+  style features such as file ownership and permissions.
+
+  This file system is also available as a module ( = code which can
+  be inserted in and removed from the running kernel whenever you
+  want). The module is called hfsplus.o. If you want to compile it
+  as a module, say M here and read Documentation/modules.txt.
+
 ROM file system support
 CONFIG_ROMFS_FS
   This is a very small read-only file system mainly intended for
@@ -17287,6 +17524,13 @@
 
   If unsure, say N.
 
+Support for serial port described by EFI HCDP table
+CONFIG_SERIAL_HCDP
+  If you wish to make the serial console port described by the EFI
+  HCDP table available for use as serial console or general
+  purpose port, say Y here. See
+  <http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf>.
+
 Support for PowerMac serial ports
 CONFIG_MAC_SERIAL
   If you have Macintosh style serial ports (8 pin mini-DIN), say Y
@@ -18602,6 +18846,20 @@
   The ACPI Sourceforge project may also be of interest:
   <http://sf.net/projects/acpi/>
 
+ACPI Processor Enumeration Only
+CONFIG_ACPI_HT_ONLY
+  This option enables limited ACPI support -- just enough to
+  enumerate processors from the ACPI Multiple APIC Description
+  Table (MADT).  Note that ACPI supports both logical (e.g. Hyper-
+  Threading) and physical processors, where the MultiProcessor
+  Specification (MPS) table only supports physical processors.
+
+  Full ACPI support (CONFIG_ACPI) is preferred.  Use this option
+  only if you wish to limit ACPI's role to processor enumeration.
+
+  In this configuration, ACPI defaults to off. It must be enabled
+  on the command-line with the "acpismp=force" option.
+
 Enable ACPI 2.0 with errata 1.3
 CONFIG_ACPI20
   Enable support for the 2.0 version of the ACPI interpreter.  See the
@@ -18618,6 +18876,14 @@
   of verbosity. Saying Y enables these statements. This will increase
   your kernel size by around 50K.
 
+ACPI Relaxed AML Checking
+CONFIG_ACPI_RELAXED_AML
+  If you say `Y' here, the ACPI interpreter will relax its checking
+  for valid AML and will ignore some AML mistakes, such as off-by-one
+  errors in region sizes.  Some laptops may require this option.  In
+  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
@@ -18643,6 +18909,20 @@
   down the system.  Until then, you can cat it, and see output when
   a button is pressed.
 
+CONFIG_ACPI_BATTERY
+  This driver adds support for battery information through
+  /proc/acpi/battery. If you have a mobile system with a battery, 
+  say Y.
+
+CONFIG_ACPI_FAN
+  This driver adds support for ACPI fan devices, allowing user-mode 
+  applications to perform basic fan control (on, off, status).
+
+CONFIG_ACPI_PROCESSOR
+  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 AC Adapter
 CONFIG_ACPI_AC
   This driver adds support for the AC Adapter object, which indicates
@@ -18665,6 +18945,53 @@
   This driver handles overheating conditions on laptops. It is HIGHLY
   recommended, as your laptop CPU may be damaged without it.
 
+ACPI ASUS/Medion Laptop Extras
+CONFIG_ACPI_ASUS
+  This driver provides support for extra features of ACPI-compatible
+  ASUS laptops. As some of Medion laptops are made by ASUS, it may also
+  support some Medion laptops (such as 9675 for example).  It makes all
+  the extra buttons generate standard ACPI events that go through
+  /proc/acpi/events, and (on some models) adds support for changing the
+  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.
+  
+  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
+  parameters.
+  
+  More information and a userspace daemon for handling the extra buttons
+  at <http://sourceforge.net/projects/acpi4asus/>.
+  
+  If you have an ACPI-compatible ASUS laptop, say Y or M here. This
+  driver is still under development, so if your laptop is unsupported or
+  something works not quite as expected, please use the mailing list
+  available on the above page (acpi4asus-user@lists.sourceforge.net)
+  
+ACPI Toshiba Laptop Extras
+CONFIG_ACPI_TOSHIBA
+  This driver adds support for access to certain system settings
+  on "legacy free" Toshiba laptops.  These laptops can be recognized by
+  their lack of a BIOS setup menu and APM support.
+
+  On these machines, all system configuration is handled through the
+  ACPI.  This driver is required for access to controls not covered
+  by the general ACPI drivers, such as LCD brightness, video output,
+  etc.
+
+  This driver differs from the non-ACPI Toshiba laptop driver (located
+  under "Processor type and features") in several aspects.
+  Configuration is accessed by reading and writing text files in the
+  /proc tree instead of by program interface to /dev.  Furthermore, no
+  power management functions are exposed, as those are handled by the
+  general ACPI drivers.
+
+  More information about this driver is available at
+  <http://memebeam.org/toys/ToshibaAcpiDriver>.
+
+  If you have a legacy free Toshiba laptop (such as the Libretto L1
+  series), say Y.
+
 Advanced Power Management BIOS support
 CONFIG_APM
   APM is a BIOS specification for saving power using several different
@@ -20673,6 +21000,17 @@
   feature. See <file:Documentation/isdn/README.syncppp> and
   <file:Documentation/isdn/syncPPP.FAQ> for more information.
 
+PPP filtering for ISDN
+CONFIG_IPPP_FILTER
+  Say Y here if you want to be able to filter the packets passing over
+  IPPP interfaces.  This allows you to control which packets count as
+  activity (i.e. which packets will reset the idle timer or bring up
+  a demand-dialled link) and which packets are to be dropped entirely.
+  You need to say Y here if you wish to use the pass-filter and
+  active-filter options to ipppd.
+
+  If unsure, say N.
+
 Support generic MP (RFC 1717)
 CONFIG_ISDN_MPP
   With synchronous PPP enabled, it is possible to increase throughput
@@ -21521,6 +21859,7 @@
                SCO Module (SCO links)
                RFCOMM Module (RFCOMM protocol)
                BNEP Module (BNEP protocol)
+               CMTP Module (CMTP protocol)
 
   Say Y here to enable Linux Bluetooth support and to build BlueZ Core
   layer.
@@ -21575,6 +21914,15 @@
   Say Y here to compile BNEP support into the kernel or say M to
   compile it as module (bnep.o).
 
+CMTP protocol support
+CONFIG_BLUEZ_CMTP
+  CMTP (CAPI Message Transport Protocol) is a transport layer
+  for CAPI messages. CMTP is required for the Bluetooth Common
+  ISDN Access Profile.
+
+  Say Y here to compile CMTP support into the kernel or say M to
+  compile it as module (cmtp.o).
+
 BNEP multicast filter support
 CONFIG_BLUEZ_BNEP_MC_FILTER
   This option enables the multicast filter support for BNEP.
@@ -21651,6 +21999,16 @@
   Say Y here to compile support for virtual HCI devices into the
   kernel or say M to compile it as module (hci_vhci.o).
 
+HCI BFUSB device driver
+CONFIG_BLUEZ_HCIBFUSB
+  Bluetooth HCI BlueFRITZ! USB driver.
+  This driver provides support for Bluetooth USB devices with AVM
+  interface:
+     AVM BlueFRITZ! USB
+
+  Say Y here to compile support for HCI BFUSB devices into the
+  kernel or say M to compile it as module (bfusb.o).
+
 HCI DTL1 (PC Card) device driver
 CONFIG_BLUEZ_HCIDTL1
   Bluetooth HCI DTL1 (PC Card) driver.
@@ -21711,6 +22069,24 @@
 
   If unsure, say N.
 
+SuperH peripheral clock frequency
+CONFIG_SH_PCLK_FREQ
+  Set this value or add "sh_pclk=" command line option to tell
+  peripheral clock frequency to kernel, if your system has no RTC.
+  Otherwise leave it 0, and kernel measures peripheral clock frequency
+  using TMU and RTC while system startup.
+
+  If unsure, set 0.
+
+Wakeup UBC on startup
+CONFIG_UBC_WAKEUP
+  Selecting this option will wakeup the User Break Controller (UBC) on
+  startup. Although the UBC is left in an awake state when the processor
+  comes up, some boot loaders misbehave by putting the UBC to sleep in a
+  power saving state, which causes issues with things like ptrace().
+
+  If unsure, say N.
+
 SuperH DMAC support
 CONFIG_SH_DMA
   Selecting this option will provide same API as PC's Direct Memory
@@ -23811,6 +24187,20 @@
   enabled, you'll be able to toggle chpids logically offline and online. Even
   if you don't understand what this means, you should say "Y".
 
+Process warning machine checks
+CONFIG_MACHCHK_WARNING
+  Select this option if you want the machine check handler on IBM S/390 or 
+  zSeries to process warning machine checks (e.g. on power failures). 
+  If unsure, say "Y".
+
+Use chscs for Common I/O
+CONFIG_CHSC
+  Select this option if you want the s390 common I/O layer to use information
+  obtained by channel subsystem calls. This will enable Linux to process link
+  failures and resource accessibility events. Moreover, if you have procfs
+  enabled, you'll be able to toggle chpids logically offline and online. Even
+  if you don't understand what this means, you should say "Y".
+
 Kernel support for 31 bit ELF binaries
 CONFIG_S390_SUPPORT
   Select this option if you want to enable your system kernel to
@@ -26078,6 +26468,9 @@
   Select SolutionEngine if configuring for a Hitachi SH7709
   or SH7750/7750S evaluation board.
 
+  Select SHMobileSolutionEngine if configuring for SH-Mobile Solution
+  Engine.
+
   Select Overdrive if configuring for a ST407750 Overdrive board.
   More information at
   <http://linuxsh.sourceforge.net/docs/7750overdrive.php3>.
@@ -26131,6 +26524,11 @@
   Select 7751 SolutionEngine if configuring for a Hitachi SH7751
   evaluation board.
 
+SHMobileSolutionEngine
+CONFIG_SH_MOBILE_SOLUTION_ENGINE
+  Select SHMobileSolutionEngine if configuring for SH-Mobile Solution
+  Engine.
+
 Overdrive
 CONFIG_SH_OVERDRIVE
   Select Overdrive if configuring for a ST407750 Overdrive board.
@@ -26178,6 +26576,14 @@
   <http://www.m17n.org/linux-sh/dreamcast/>.  There is a
   Dreamcast project is at <http://linuxdc.sourceforge.net/>.
 
+SH-2000
+CONFIG_SH_SH2000
+  SH-2000 is a single-board computer based around SH7709A chip
+  intended for embedded applications.
+  It has an Ethernet interface (CS8900A), direct connected
+  Compact Flash socket, three serial ports and PC-104 bus.
+  More information at <http://sh2000.sh-linux.org>.
+
 BareCPU
 CONFIG_SH_UNKNOWN
   "Bare CPU" aka "unknown" means an SH-based system which is not one
@@ -26207,6 +26613,12 @@
   Select SH7751 if you have a SH7751
 
   Select ST40STB1 if you have a ST40STB1
+  Select ST40RA/ST40STB1 if you have a ST40RA
+                         (previously known as ST40STB1).
+
+  Select ST40GX1 if you have an ST40GX1.
+
+  Select SH7300 if you have a HD6417300 CPU.
 
 SH7708
 CONFIG_CPU_SUBTYPE_SH7708
@@ -26221,6 +26633,35 @@
 CONFIG_CPU_SUBTYPE_SH7750
   Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU.
 
+SH7751
+CONFIG_CPU_SUBTYPE_SH7751
+  Select SH7750 if you have a 166 Mhz SH-4 HD6417751 CPU.
+
+ST40RA/ST40STB1
+CONFIG_CPU_SUBTYPE_ST40STB1
+  Select ST40RA/ST40STB1 if you have a ST40RA. This chip was
+  previously called the ST40STB1. Early versions were also
+  erronously labelled ST40AR166.
+
+ST40GX1
+CONFIG_CPU_SUBTYPE_ST40GX1
+  Select ST40GX1 if you have a ST40GX1 CPU.
+
+SH7300
+CONFIG_CPU_SUBTYPE_SH7300
+  Select SH7300 if you have a HD6417300 CPU.
+
+Memory on LMI
+CONFIG_ST40_LMI_MEMORY
+  Currently all ST40 CPUs have two external buses the
+  'Local Memory Interface' (LMI) which supports SDRAM and
+  DDR SDRAM, and the 'Enhanced flash Memory Interface' (EMI),
+  which supports SDRAM, Flash, peripherials and MPX. Linux
+  can support memory on either of these buses, it is simply
+  necessary to specify its base address. This option is simply
+  a shortcut method of specifying that RAM starts from the
+  bottom of the LMI.
+
 Physical memory start address
 CONFIG_MEMORY_START
   Computers built with Hitachi SuperH processors always
@@ -26591,6 +27032,140 @@
 
   If compiled as a module, it will be called scx200_docflash.o.
 
+BIOS flash chip on AMD76x southbridge
+CONFIG_MTD_AMD76XROM
+  Support for treating the BIOS flash chip on AMD76x motherboards
+  as an MTD device - with this you can reprogram your BIOS.
+
+  BE VERY CAREFUL.
+
+  If compiled as a module, it will be called amd76xrom.o.
+
+BIOS flash chip on Intel Hub Controller 2
+CONFIG_MTD_ICH2ROM
+  Support for treating the BIOS flash chip on ICH2 motherboards
+  as an MTD device - with this you can reprogram your BIOS.
+
+  BE VERY CAREFUL.
+
+  If compiled as a module, it will be called ich2rom.o.
+
+BIOS flash chip on Intel SCB2 boards
+CONFIG_MTD_SCB2_FLASH
+  Support for treating the BIOS flash chip on Intel SCB2 boards
+  as an MTD device - with this you can reprogram your BIOS.
+
+  BE VERY CAREFUL.
+
+  If compiled as a module, it will be called scb2_flash.o.
+
+Flash chips on Tsunami TIG bus
+CONFIG_MTD_TSUNAMI
+  Support for the flash chip on Tsunami TIG bus.
+
+  If compiled as a module, it will be called tsunami_flash.o.
+
+Flash chips on LASAT board
+CONFIG_MTD_LASAT
+  Support for the flash chips on the Lasat 100 and 200 boards.
+
+  If compiled as a module, it will be called lasat.o.
+
+CFI flash device on SnapGear/SecureEdge
+CONFIG_MTD_NETtel
+  Support for flash chips on NETtel/SecureEdge/SnapGear boards.
+
+  If compiled as a module, it will be called nettel.o.
+
+CFI Flash device mapped on DIL/Net PC
+CONFIG_MTD_DILNETPC
+  MTD map driver for SSV DIL/Net PC Boards "DNP" and "ADNP".
+  For details, see <http://www.ssv-embedded.de/ssv/pc104/p169.htm>
+   and <http://www.ssv-embedded.de/ssv/pc104/p170.htm>
+
+  If compiled as a module, it will be called dilnetpc.o.
+
+Size of DIL/Net PC flash boot partition
+CONFIG_MTD_DILNETPC_BOOTSIZE
+  The amount of space taken up by the kernel or Etherboot
+  on the DIL/Net PC flash chips.
+
+CFI Flash device mapped on Epxa10db
+CONFIG_MTD_EPXA10DB
+  This enables support for the flash devices on the Altera
+  Excalibur XA10 Development Board. If you are building a kernel
+  for on of these boards then you should say 'Y' otherwise say 'N'.
+
+  If compiled as a module, it will be called epxa10db-flash.o.
+
+CFI Flash device mapped on the FortuNet board
+CONFIG_MTD_FORTUNET
+  This enables access to the Flash on the FortuNet board.  If you
+  have such a board, say 'Y'.
+
+  If compiled as a module, it will be called fortunet.o.
+
+NV-RAM mapping AUTCPU12 board
+CONFIG_MTD_AUTCPU12
+  This enables access to the NV-RAM on autronix autcpu12 board.
+  If you have such a board, say 'Y'.
+
+  If compiled as a module, it will be called autcpu12-nvram.o.
+
+CFI Flash device mapped on EDB7312
+CONFIG_MTD_EDB7312
+  This enables access to the CFI Flash on the Cogent EDB7312 board.
+  If you have such a board, say 'Y' here.
+
+  If compiled as a module, it will be called edb7312.o.
+
+JEDEC Flash device mapped on impA7
+CONFIG_MTD_IMPA7
+  This enables access to the NOR Flash on the impA7 board of
+  implementa GmbH. If you have such a board, say 'Y' here.
+
+  If compiled as a module, it will be called impa7.o.
+
+JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame
+CONFIG_MTD_CEIVA
+  This enables access to the flash chips on the Ceiva/Polaroid
+  PhotoMax Digital Picture Frame.
+  If you have such a device, say 'Y'.
+
+  If compiled as a module, it will be called ceiva.o.
+
+System flash on MBX860 board
+CONFIG_MTD_MBX860
+  This enables access routines for the flash chips on the Motorola
+  MBX860 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 mbx860.o.
+
+PCI MTD driver
+CONFIG_MTD_PCI
+  Mapping for accessing flash devices on add-in cards like the Intel XScale
+  IQ80310 card, and the Intel EBSA285 card in blank ROM programming mode
+  (please see the manual for the link settings).
+
+  If compiled as a module, it will be called pci.o.
+
+  If you are not sure, say N.
+
+PCMCIA MTD driver
+CONFIG_MTD_PCMCIA
+  Map driver for accessing PCMCIA linear flash memory cards. These
+  cards are usually around 4-16MiB in size. This does not include
+  Compact Flash cards which are treated as IDE devices.
+
+  If compiled as a module, it will be called pcmciamtd.o.
+
+Generic uClinux RAM/ROM filesystem support
+CONFIG_MTD_UCLINUX
+  Map driver to support image based filesystems for uClinux.
+
+  If compiled as a module, it will be called uclinux.o.
+
 NatSemi SCx200 I2C using GPIO pins
 CONFIG_SCx200_GPIO
   Enable the use of two GPIO pins of a SCx200 processor as an I2C bus.
@@ -26649,6 +27224,105 @@
 CONFIG_IPMI_WATCHDOG
   This enables the IPMI watchdog timer.
 
+CRC32 functions
+CONFIG_CRC32
+  This option is provided for the case where no in-kernel-tree
+  modules require CRC32 functions, but a module built outside the
+  kernel tree does. Such modules that use library CRC32 functions
+  require that you say M or Y here.
+
+CONFIG_CRYPTO
+  This option provides the core Cryptographic API.
+
+CONFIG_CRYPTO_HMAC
+  HMAC: Keyed-Hashing for Message Authentication (RFC2104).
+  This is required for IPSec.
+
+CONFIG_CRYPTO_NULL
+  These are 'Null' algorithms, used by IPsec, which do nothing.
+
+CONFIG_CRYPTO_MD4
+  MD4 message digest algorithm (RFC1320).
+  
+CONFIG_CRYPTO_MD5
+  MD5 message digest algorithm (RFC1321).
+
+CONFIG_CRYPTO_SHA1
+  SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
+
+CONFIG_CRYPTO_SHA256
+  SHA256 secure hash standard (DFIPS 180-2).
+
+  This version of SHA implements a 256 bit hash with 128 bits of
+  security against collision attacks.
+
+CONFIG_CRYPTO_SHA512
+  SHA512 secure hash standard (DFIPS 180-2).
+
+  This version of SHA implements a 512 bit hash with 256 bits of
+  security against collision attacks.
+
+  This code also includes SHA-384, a 384 bit hash with 192 bits
+  of security against collision attacks.
+
+CONFIG_CRYPTO_DES
+  DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
+
+CONFIG_CRYPTO_BLOWFISH
+  Blowfish cipher algorithm, by Bruce Schneier.
+
+  This is a variable key length cipher which can use keys from 32
+  bits to 448 bits in length.  It's fast, simple and specifically
+  designed for use on "large microprocessors".
+
+  See also <http://www.counterpane.com/blowfish.html>.
+
+CONFIG_CRYPTO_TWOFISH
+  Twofish cipher algorithm.
+
+  Twofish was submitted as an AES (Advanced Encryption Standard)
+  candidate cipher by researchers at CounterPane Systems.  It is a
+  16 round block cipher supporting key sizes of 128, 192, and 256
+  bits.
+
+  See also:
+  http://www.counterpane.com/twofish.html
+
+CONFIG_CRYPTO_SERPENT
+  Serpent cipher algorithm, by Anderson, Biham & Knudsen.
+
+  Keys are allowed to be from 0 to 256 bits in length, in steps
+  of 8 bits.
+
+  See also:
+  http://www.cl.cam.ac.uk/~rja14/serpent.html
+
+CONFIG_CRYPTO_AES
+  AES cipher algorithms (FIPS-197). AES uses the Rijndael 
+  algorithm.
+
+  Rijndael appears to be consistently a very good performer in
+  both hardware and software across a wide range of computing 
+  environments regardless of its use in feedback or non-feedback 
+  modes. Its key setup time is excellent, and its key agility is 
+  good. Rijndael's very low memory requirements make it very well 
+  suited for restricted-space environments, in which it also 
+  demonstrates excellent performance. Rijndael's operations are 
+  among the easiest to defend against power and timing attacks.	
+
+  The AES specifies three key sizes: 128, 192 and 256 bits	  
+
+  See http://csrc.nist.gov/encryption/aes/ for more information.
+
+CONFIG_CRYPTO_DEFLATE
+  This is the Deflate algorithm (RFC1951), specified for use in
+  IPSec with the IPCOMP protocol (RFC3173, RFC2394).
+
+  You will most probably want this if using IPSec.
+
+CONFIG_CRYPTO_TEST
+  Quick & dirty crypto test module.
+
 #
 # A couple of things I keep forgetting:
 #   capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/arm/SA1100/CERF linux-2.4.22-pre10/Documentation/arm/SA1100/CERF
--- linux-2.4.21/Documentation/arm/SA1100/CERF	2000-08-13 16:58:24.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/arm/SA1100/CERF	2003-08-01 13:30:53.000000000 +0000
@@ -1,23 +1,28 @@
-The Intrinsyc CerfBoard is a StrongARM 1110-based computer on a board that measures 
-approximately 2" square. It includes an Ethernet controller, an RS232-compatible serial port, a
-USB function port, and one CompactFlash+ slot on the back. Pictures can be found at the
+The Intrinsyc CerfBoard is a StrongARM 1110-based computer on a board
+that measures approximately 2" square. It includes an Ethernet
+controller, an RS232-compatible serial port, a USB function port, and
+one CompactFlash+ slot on the back. Pictures can be found at the
 Intrinsyc website, http://www.intrinsyc.com.
 
-This document describes the support in the Linux kernel for the Intrinsyc CerfBoard as of
-version 2.4.0-test4-np1.
+This document describes the support in the Linux kernel for the
+Intrinsyc CerfBoard as of version 2.4.0-test4-np1.
 
 Supported in this version:
-   - CompactFlash+ slot (select PCMCIA in General Setup and any options that may be required)
-   - Onboard Crystal CS8900 Ethernet controller (Cerf CS8900A support in Network Devices)
+   - CompactFlash+ slot (select PCMCIA in General Setup and any options
+     that may be required)
+   - Onboard Crystal CS8900 Ethernet controller (Cerf CS8900A support in
+     Network Devices)
    - Serial ports with a serial console (hardcoded to 38400 8N1)
 
 Not supported in this version (yet):
    - LCD driver/touchscreen interface
-   - UDC (a driver exists right now, but is unstable and slow and only works with the Linux USB)
+   - UDC (a driver exists right now, but is unstable and slow and only
+     works with the Linux USB)
 
-In order to get this kernel onto your Cerf, you need a server that runs both BOOTP and
-TFTP. Detailed instructions should have come with your evaluation kit on how to use the
-bootloader. This series of commands will suffice:
+In order to get this kernel onto your Cerf, you need a server that runs
+both BOOTP and TFTP. Detailed instructions should have come with your
+evaluation kit on how to use the bootloader. This series of commands
+will suffice:
 
    make cerf_config
    make xconfig
@@ -25,10 +30,9 @@
    make zImage
    cp arch/arm/boot/zImage <TFTP directory>
 
-The default config uses a 4MB RAM disk located at 0xc0500000 as root. Setting the board to
-mount root from a NFS partition works, too.
+The default config uses a 4MB RAM disk located at 0xc0500000 as root.
+Setting the board to mount root from a NFS partition works, too.
 
 
 I-Gene Leong, Intrinsyc Software Inc.
 ileong@intrinsyc.com
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/cciss.txt linux-2.4.22-pre10/Documentation/cciss.txt
--- linux-2.4.21/Documentation/cciss.txt	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/cciss.txt	2003-08-01 13:31:20.000000000 +0000
@@ -12,6 +12,7 @@
 	* SA 641
 	* SA 642
 	* SA 6400
+	* SA 6400 U320 Expansion Module
 
 If nodes are not already created in the /dev/cciss directory
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/crypto/api-intro.txt linux-2.4.22-pre10/Documentation/crypto/api-intro.txt
--- linux-2.4.21/Documentation/crypto/api-intro.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/crypto/api-intro.txt	2003-08-01 13:34:59.000000000 +0000
@@ -0,0 +1,221 @@
+
+                    Scatterlist Cryptographic API
+                   
+INTRODUCTION
+
+The Scatterlist Crypto API takes page vectors (scatterlists) as
+arguments, and works directly on pages.  In some cases (e.g. ECB
+mode ciphers), this will allow for pages to be encrypted in-place
+with no copying.
+
+One of the initial goals of this design was to readily support IPsec,
+so that processing can be applied to paged skb's without the need
+for linearization.
+
+
+DETAILS
+
+At the lowest level are algorithms, which register dynamically with the
+API.
+
+'Transforms' are user-instantiated objects, which maintain state, handle all
+of the implementation logic (e.g. manipulating page vectors), provide an 
+abstraction to the underlying algorithms, and handle common logical 
+operations (e.g. cipher modes, HMAC for digests).  However, at the user 
+level they are very simple.
+
+Conceptually, the API layering looks like this:
+
+  [transform api]  (user interface)
+  [transform ops]  (per-type logic glue e.g. cipher.c, digest.c)
+  [algorithm api]  (for registering algorithms)
+  
+The idea is to make the user interface and algorithm registration API
+very simple, while hiding the core logic from both.  Many good ideas
+from existing APIs such as Cryptoapi and Nettle have been adapted for this.
+
+The API currently supports three types of transforms: Ciphers, Digests and
+Compressors.  The compression algorithms especially seem to be performing
+very well so far.
+
+Support for hardware crypto devices via an asynchronous interface is
+under development.
+
+Here's an example of how to use the API:
+
+	#include <linux/crypto.h>
+	
+	struct scatterlist sg[2];
+	char result[128];
+	struct crypto_tfm *tfm;
+	
+	tfm = crypto_alloc_tfm("md5", 0);
+	if (tfm == NULL)
+		fail();
+		
+	/* ... set up the scatterlists ... */
+	
+	crypto_digest_init(tfm);
+	crypto_digest_update(tfm, &sg, 2);
+	crypto_digest_final(tfm, result);
+	
+	crypto_free_tfm(tfm);
+
+    
+Many real examples are available in the regression test module (tcrypt.c).
+
+
+CONFIGURATION NOTES
+
+As Triple DES is part of the DES module, for those using modular builds,
+add the following line to /etc/modules.conf:
+
+  alias des3_ede des
+
+The Null algorithms reside in the crypto_null module, so these lines
+should also be added:
+
+  alias cipher_null crypto_null
+  alias digest_null crypto_null
+  alias compress_null crypto_null
+
+The SHA384 algorithm shares code within the SHA512 module, so you'll
+also need:
+  alias sha384 sha512
+
+
+DEVELOPER NOTES
+
+Transforms may only be allocated in user context, and cryptographic
+methods may only be called from softirq and user contexts.
+
+When using the API for ciphers, performance will be optimal if each
+scatterlist contains data which is a multiple of the cipher's block
+size (typically 8 bytes).  This prevents having to do any copying
+across non-aligned page fragment boundaries.
+
+
+ADDING NEW ALGORITHMS
+
+When submitting a new algorithm for inclusion, a mandatory requirement
+is that at least a few test vectors from known sources (preferably
+standards) be included.
+
+Converting existing well known code is preferred, as it is more likely
+to have been reviewed and widely tested.  If submitting code from LGPL
+sources, please consider changing the license to GPL (see section 3 of
+the LGPL).
+
+Algorithms submitted must also be generally patent-free (e.g. IDEA
+will not be included in the mainline until around 2011), and be based
+on a recognized standard and/or have been subjected to appropriate
+peer review.
+
+Also check for any RFCs which may relate to the use of specific algorithms,
+as well as general application notes such as RFC2451 ("The ESP CBC-Mode
+Cipher Algorithms").
+
+It's a good idea to avoid using lots of macros and use inlined functions
+instead, as gcc does a good job with inlining, while excessive use of
+macros can cause compilation problems on some platforms.
+
+Also check the TODO list at the web site listed below to see what people
+might already be working on.
+
+
+BUGS
+
+Send bug reports to:
+James Morris <jmorris@intercode.com.au>
+Cc: David S. Miller <davem@redhat.com>
+
+
+FURTHER INFORMATION
+
+For further patches and various updates, including the current TODO
+list, see:
+http://samba.org/~jamesm/crypto/
+
+
+AUTHORS
+
+James Morris
+David S. Miller
+
+
+CREDITS
+
+The following people provided invaluable feedback during the development
+of the API:
+
+  Alexey Kuznetzov
+  Rusty Russell
+  Herbert Valerio Riedel
+  Jeff Garzik
+  Michael Richardson
+  Andrew Morton
+  Ingo Oeser
+  Christoph Hellwig
+
+Portions of this API were derived from the following projects:
+  
+  Kerneli Cryptoapi (http://www.kerneli.org/)
+    Alexander Kjeldaas
+    Herbert Valerio Riedel
+    Kyle McMartin
+    Jean-Luc Cooke
+    David Bryson
+    Clemens Fruhwirth
+    Tobias Ringstrom
+    Harald Welte
+
+and;
+  
+  Nettle (http://www.lysator.liu.se/~nisse/nettle/)
+    Niels Möller
+
+Original developers of the crypto algorithms:
+
+  Dana L. How (DES)
+  Andrew Tridgell and Steve French (MD4)
+  Colin Plumb (MD5)
+  Steve Reid (SHA1)
+  Jean-Luc Cooke (SHA256, SHA384, SHA512)
+  Kazunori Miyazawa / USAGI (HMAC)
+  Matthew Skala (Twofish)
+  Dag Arne Osvik (Serpent)
+  Brian Gladman (AES)
+
+
+SHA1 algorithm contributors:
+  Jean-Francois Dive
+  
+DES algorithm contributors:
+  Raimar Falke
+  Gisle Sælensminde
+  Niels Möller
+
+Blowfish algorithm contributors:
+  Herbert Valerio Riedel
+  Kyle McMartin
+
+Twofish algorithm contributors:
+  Werner Koch
+  Marc Mutz
+
+SHA256/384/512 algorithm contributors:
+  Andrew McDonald
+  Kyle McMartin
+  Herbert Valerio Riedel
+  
+AES algorithm contributors:
+  Alexander Kjeldaas
+  Herbert Valerio Riedel
+  Kyle McMartin
+  Adam J. Richter
+
+Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>
+
+Please send any credits updates or corrections to:
+James Morris <jmorris@intercode.com.au>
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/crypto/descore-readme.txt linux-2.4.22-pre10/Documentation/crypto/descore-readme.txt
--- linux-2.4.21/Documentation/crypto/descore-readme.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/crypto/descore-readme.txt	2003-08-01 13:33:58.000000000 +0000
@@ -0,0 +1,352 @@
+Below is the orginal README file from the descore.shar package.
+------------------------------------------------------------------------------
+
+des - fast & portable DES encryption & decryption.
+Copyright (C) 1992  Dana L. How
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Library General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Author's address: how@isl.stanford.edu
+
+$Id: README,v 1.15 1992/05/20 00:25:32 how E $
+
+
+==>> To compile after untarring/unsharring, just `make' <<==
+
+
+This package was designed with the following goals:
+1.	Highest possible encryption/decryption PERFORMANCE.
+2.	PORTABILITY to any byte-addressable host with a 32bit unsigned C type
+3.	Plug-compatible replacement for KERBEROS's low-level routines.
+
+This second release includes a number of performance enhancements for
+register-starved machines.  My discussions with Richard Outerbridge,
+71755.204@compuserve.com, sparked a number of these enhancements.
+
+To more rapidly understand the code in this package, inspect desSmallFips.i
+(created by typing `make') BEFORE you tackle desCode.h.  The latter is set
+up in a parameterized fashion so it can easily be modified by speed-daemon
+hackers in pursuit of that last microsecond.  You will find it more
+illuminating to inspect one specific implementation,
+and then move on to the common abstract skeleton with this one in mind.
+
+
+performance comparison to other available des code which i could
+compile on a SPARCStation 1 (cc -O4, gcc -O2):
+
+this code (byte-order independent):
+   30us per encryption (options: 64k tables, no IP/FP)
+   33us per encryption (options: 64k tables, FIPS standard bit ordering)
+   45us per encryption (options:  2k tables, no IP/FP)
+   48us per encryption (options:  2k tables, FIPS standard bit ordering)
+  275us to set a new key (uses 1k of key tables)
+	this has the quickest encryption/decryption routines i've seen.
+	since i was interested in fast des filters rather than crypt(3)
+	and password cracking, i haven't really bothered yet to speed up
+	the key setting routine. also, i have no interest in re-implementing
+	all the other junk in the mit kerberos des library, so i've just
+	provided my routines with little stub interfaces so they can be
+	used as drop-in replacements with mit's code or any of the mit-
+	compatible packages below. (note that the first two timings above
+	are highly variable because of cache effects).
+
+kerberos des replacement from australia (version 1.95):
+   53us per encryption (uses 2k of tables)
+   96us to set a new key (uses 2.25k of key tables)
+	so despite the author's inclusion of some of the performance
+	improvements i had suggested to him, this package's
+	encryption/decryption is still slower on the sparc and 68000.
+	more specifically, 19-40% slower on the 68020 and 11-35% slower
+	on the sparc,  depending on the compiler;
+	in full gory detail (ALT_ECB is a libdes variant):
+	compiler   	machine		desCore	libdes	ALT_ECB	slower by
+	gcc 2.1 -O2	Sun 3/110	304  uS	369.5uS	461.8uS	 22%
+	cc      -O1	Sun 3/110	336  uS	436.6uS	399.3uS	 19%
+	cc      -O2	Sun 3/110	360  uS	532.4uS	505.1uS	 40%
+	cc      -O4	Sun 3/110	365  uS	532.3uS	505.3uS	 38%
+	gcc 2.1 -O2	Sun 4/50	 48  uS	 53.4uS	 57.5uS	 11%
+	cc      -O2	Sun 4/50	 48  uS	 64.6uS	 64.7uS	 35%
+	cc      -O4	Sun 4/50	 48  uS	 64.7uS	 64.9uS	 35%
+	(my time measurements are not as accurate as his).
+   the comments in my first release of desCore on version 1.92:
+   68us per encryption (uses 2k of tables)
+   96us to set a new key (uses 2.25k of key tables)
+	this is a very nice package which implements the most important
+	of the optimizations which i did in my encryption routines.
+	it's a bit weak on common low-level optimizations which is why
+	it's 39%-106% slower.  because he was interested in fast crypt(3) and
+	password-cracking applications,  he also used the same ideas to
+	speed up the key-setting routines with impressive results.
+	(at some point i may do the same in my package).  he also implements
+	the rest of the mit des library.
+	(code from eay@psych.psy.uq.oz.au via comp.sources.misc)
+
+fast crypt(3) package from denmark:
+	the des routine here is buried inside a loop to do the
+	crypt function and i didn't feel like ripping it out and measuring
+	performance. his code takes 26 sparc instructions to compute one
+	des iteration; above, Quick (64k) takes 21 and Small (2k) takes 37.
+	he claims to use 280k of tables but the iteration calculation seems
+	to use only 128k.  his tables and code are machine independent.
+	(code from glad@daimi.aau.dk via alt.sources or comp.sources.misc)
+
+swedish reimplementation of Kerberos des library
+  108us per encryption (uses 34k worth of tables)
+  134us to set a new key (uses 32k of key tables to get this speed!)
+	the tables used seem to be machine-independent;
+	he seems to have included a lot of special case code
+	so that, e.g., `long' loads can be used instead of 4 `char' loads
+	when the machine's architecture allows it.
+	(code obtained from chalmers.se:pub/des)
+
+crack 3.3c package from england:
+	as in crypt above, the des routine is buried in a loop. it's
+	also very modified for crypt.  his iteration code uses 16k
+	of tables and appears to be slow.
+	(code obtained from aem@aber.ac.uk via alt.sources or comp.sources.misc)
+
+``highly optimized'' and tweaked Kerberos/Athena code (byte-order dependent):
+  165us per encryption (uses 6k worth of tables)
+  478us to set a new key (uses <1k of key tables)
+	so despite the comments in this code, it was possible to get
+	faster code AND smaller tables, as well as making the tables
+	machine-independent.
+	(code obtained from prep.ai.mit.edu)
+
+UC Berkeley code (depends on machine-endedness):
+  226us per encryption
+10848us to set a new key
+	table sizes are unclear, but they don't look very small
+	(code obtained from wuarchive.wustl.edu)
+
+
+motivation and history
+
+a while ago i wanted some des routines and the routines documented on sun's
+man pages either didn't exist or dumped core.  i had heard of kerberos,
+and knew that it used des,  so i figured i'd use its routines.  but once
+i got it and looked at the code,  it really set off a lot of pet peeves -
+it was too convoluted, the code had been written without taking
+advantage of the regular structure of operations such as IP, E, and FP
+(i.e. the author didn't sit down and think before coding),
+it was excessively slow,  the author had attempted to clarify the code
+by adding MORE statements to make the data movement more `consistent'
+instead of simplifying his implementation and cutting down on all data
+movement (in particular, his use of L1, R1, L2, R2), and it was full of
+idiotic `tweaks' for particular machines which failed to deliver significant
+speedups but which did obfuscate everything.  so i took the test data
+from his verification program and rewrote everything else.
+
+a while later i ran across the great crypt(3) package mentioned above.
+the fact that this guy was computing 2 sboxes per table lookup rather
+than one (and using a MUCH larger table in the process) emboldened me to
+do the same - it was a trivial change from which i had been scared away
+by the larger table size.  in his case he didn't realize you don't need to keep
+the working data in TWO forms, one for easy use of half the sboxes in
+indexing, the other for easy use of the other half; instead you can keep
+it in the form for the first half and use a simple rotate to get the other
+half.  this means i have (almost) half the data manipulation and half
+the table size.  in fairness though he might be encoding something particular
+to crypt(3) in his tables - i didn't check.
+
+i'm glad that i implemented it the way i did, because this C version is
+portable (the ifdef's are performance enhancements) and it is faster
+than versions hand-written in assembly for the sparc!
+
+
+porting notes
+
+one thing i did not want to do was write an enormous mess
+which depended on endedness and other machine quirks,
+and which necessarily produced different code and different lookup tables
+for different machines.  see the kerberos code for an example
+of what i didn't want to do; all their endedness-specific `optimizations'
+obfuscate the code and in the end were slower than a simpler machine
+independent approach.  however, there are always some portability
+considerations of some kind, and i have included some options
+for varying numbers of register variables.
+perhaps some will still regard the result as a mess!
+
+1) i assume everything is byte addressable, although i don't actually
+   depend on the byte order, and that bytes are 8 bits.
+   i assume word pointers can be freely cast to and from char pointers.
+   note that 99% of C programs make these assumptions.
+   i always use unsigned char's if the high bit could be set.
+2) the typedef `word' means a 32 bit unsigned integral type.
+   if `unsigned long' is not 32 bits, change the typedef in desCore.h.
+   i assume sizeof(word) == 4 EVERYWHERE.
+
+the (worst-case) cost of my NOT doing endedness-specific optimizations
+in the data loading and storing code surrounding the key iterations
+is less than 12%.  also, there is the added benefit that
+the input and output work areas do not need to be word-aligned.
+
+
+OPTIONAL performance optimizations
+
+1) you should define one of `i386,' `vax,' `mc68000,' or `sparc,'
+   whichever one is closest to the capabilities of your machine.
+   see the start of desCode.h to see exactly what this selection implies.
+   note that if you select the wrong one, the des code will still work;
+   these are just performance tweaks.
+2) for those with functional `asm' keywords: you should change the
+   ROR and ROL macros to use machine rotate instructions if you have them.
+   this will save 2 instructions and a temporary per use,
+   or about 32 to 40 instructions per en/decryption.
+   note that gcc is smart enough to translate the ROL/R macros into
+   machine rotates!
+
+these optimizations are all rather persnickety, yet with them you should
+be able to get performance equal to assembly-coding, except that:
+1) with the lack of a bit rotate operator in C, rotates have to be synthesized
+   from shifts.  so access to `asm' will speed things up if your machine
+   has rotates, as explained above in (3) (not necessary if you use gcc).
+2) if your machine has less than 12 32-bit registers i doubt your compiler will
+   generate good code.
+   `i386' tries to configure the code for a 386 by only declaring 3 registers
+   (it appears that gcc can use ebx, esi and edi to hold register variables).
+   however, if you like assembly coding, the 386 does have 7 32-bit registers,
+   and if you use ALL of them, use `scaled by 8' address modes with displacement
+   and other tricks, you can get reasonable routines for DesQuickCore... with
+   about 250 instructions apiece.  For DesSmall... it will help to rearrange
+   des_keymap, i.e., now the sbox # is the high part of the index and
+   the 6 bits of data is the low part; it helps to exchange these.
+   since i have no way to conveniently test it i have not provided my
+   shoehorned 386 version.  note that with this release of desCore, gcc is able
+   to put everything in registers(!), and generate about 370 instructions apiece
+   for the DesQuickCore... routines!
+
+coding notes
+
+the en/decryption routines each use 6 necessary register variables,
+with 4 being actively used at once during the inner iterations.
+if you don't have 4 register variables get a new machine.
+up to 8 more registers are used to hold constants in some configurations.
+
+i assume that the use of a constant is more expensive than using a register:
+a) additionally, i have tried to put the larger constants in registers.
+   registering priority was by the following:
+	anything more than 12 bits (bad for RISC and CISC)
+	greater than 127 in value (can't use movq or byte immediate on CISC)
+	9-127 (may not be able to use CISC shift immediate or add/sub quick),
+	1-8 were never registered, being the cheapest constants.
+b) the compiler may be too stupid to realize table and table+256 should
+   be assigned to different constant registers and instead repetitively
+   do the arithmetic, so i assign these to explicit `m' register variables
+   when possible and helpful.
+
+i assume that indexing is cheaper or equivalent to auto increment/decrement,
+where the index is 7 bits unsigned or smaller.
+this assumption is reversed for 68k and vax.
+
+i assume that addresses can be cheaply formed from two registers,
+or from a register and a small constant.
+for the 68000, the `two registers and small offset' form is used sparingly.
+all index scaling is done explicitly - no hidden shifts by log2(sizeof).
+
+the code is written so that even a dumb compiler
+should never need more than one hidden temporary,
+increasing the chance that everything will fit in the registers.
+KEEP THIS MORE SUBTLE POINT IN MIND IF YOU REWRITE ANYTHING.
+(actually, there are some code fragments now which do require two temps,
+but fixing it would either break the structure of the macros or
+require declaring another temporary).
+
+
+special efficient data format
+
+bits are manipulated in this arrangement most of the time (S7 S5 S3 S1):
+	003130292827xxxx242322212019xxxx161514131211xxxx080706050403xxxx
+(the x bits are still there, i'm just emphasizing where the S boxes are).
+bits are rotated left 4 when computing S6 S4 S2 S0:
+	282726252423xxxx201918171615xxxx121110090807xxxx040302010031xxxx
+the rightmost two bits are usually cleared so the lower byte can be used
+as an index into an sbox mapping table. the next two x'd bits are set
+to various values to access different parts of the tables.
+
+
+how to use the routines
+
+datatypes:
+	pointer to 8 byte area of type DesData
+	used to hold keys and input/output blocks to des.
+
+	pointer to 128 byte area of type DesKeys
+	used to hold full 768-bit key.
+	must be long-aligned.
+
+DesQuickInit()
+	call this before using any other routine with `Quick' in its name.
+	it generates the special 64k table these routines need.
+DesQuickDone()
+	frees this table
+
+DesMethod(m, k)
+	m points to a 128byte block, k points to an 8 byte des key
+	which must have odd parity (or -1 is returned) and which must
+	not be a (semi-)weak key (or -2 is returned).
+	normally DesMethod() returns 0.
+	m is filled in from k so that when one of the routines below
+	is called with m, the routine will act like standard des
+	en/decryption with the key k. if you use DesMethod,
+	you supply a standard 56bit key; however, if you fill in
+	m yourself, you will get a 768bit key - but then it won't
+	be standard.  it's 768bits not 1024 because the least significant
+	two bits of each byte are not used.  note that these two bits
+	will be set to magic constants which speed up the encryption/decryption
+	on some machines.  and yes, each byte controls
+	a specific sbox during a specific iteration.
+	you really shouldn't use the 768bit format directly;  i should
+	provide a routine that converts 128 6-bit bytes (specified in
+	S-box mapping order or something) into the right format for you.
+	this would entail some byte concatenation and rotation.
+
+Des{Small|Quick}{Fips|Core}{Encrypt|Decrypt}(d, m, s)
+	performs des on the 8 bytes at s into the 8 bytes at d. (d,s: char *).
+	uses m as a 768bit key as explained above.
+	the Encrypt|Decrypt choice is obvious.
+	Fips|Core determines whether a completely standard FIPS initial
+	and final permutation is done; if not, then the data is loaded
+	and stored in a nonstandard bit order (FIPS w/o IP/FP).
+	Fips slows down Quick by 10%, Small by 9%.
+	Small|Quick determines whether you use the normal routine
+	or the crazy quick one which gobbles up 64k more of memory.
+	Small is 50% slower then Quick, but Quick needs 32 times as much
+	memory.  Quick is included for programs that do nothing but DES,
+	e.g., encryption filters, etc.
+
+
+Getting it to compile on your machine
+
+there are no machine-dependencies in the code (see porting),
+except perhaps the `now()' macro in desTest.c.
+ALL generated tables are machine independent.
+you should edit the Makefile with the appropriate optimization flags
+for your compiler (MAX optimization).
+
+
+Speeding up kerberos (and/or its des library)
+
+note that i have included a kerberos-compatible interface in desUtil.c
+through the functions des_key_sched() and des_ecb_encrypt().
+to use these with kerberos or kerberos-compatible code put desCore.a
+ahead of the kerberos-compatible library on your linker's command line.
+you should not need to #include desCore.h;  just include the header
+file provided with the kerberos library.
+
+Other uses
+
+the macros in desCode.h would be very useful for putting inline des
+functions in more complicated encryption routines.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/devices.txt linux-2.4.22-pre10/Documentation/devices.txt
--- linux-2.4.21/Documentation/devices.txt	2001-11-07 22:46:01.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/devices.txt	2003-08-01 13:32:47.000000000 +0000
@@ -2531,17 +2531,17 @@
 		  1 = /dev/dri/card1		Second graphics card
 		    ...
 
-227 char	IBM 3270 terminal block-mode access
+227 char	IBM 3270 terminal Unix tty access
+		  1 = /dev/3270/tty1		First 3270 terminal
+		  2 = /dev/3270/tty2		Seconds 3270 terminal
+		    ...
+
+228 char	IBM 3270 terminal block-mode access
 		  0 = /dev/3270/tub		Controlling interface
 		  1 = /dev/3270/tub1		First 3270 terminal
 		  2 = /dev/3270/tub2		Second 3270 terminal
 		    ...
 
-228 char	IBM 3270 terminal Unix tty access
-		  1 = /dev/3270/tty1		First 3270 terminal
-		  2 = /dev/3270/tty2		Seconds 3270 terminal
-		    ...
-
 229 char	IBM iSeries virtual console
 		  0 = /dev/iseries/vtty0	First console port
 		  1 = /dev/iseries/vtty1	Second console port
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/fb/vesafb.txt linux-2.4.22-pre10/Documentation/fb/vesafb.txt
--- linux-2.4.21/Documentation/fb/vesafb.txt	2000-07-28 19:50:51.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/fb/vesafb.txt	2003-08-01 13:31:32.000000000 +0000
@@ -139,13 +139,17 @@
 redraw	scroll by redrawing the affected part of the screen, this
 	is the safe (and slow) default.
 
-
 vgapal	Use the standard vga registers for palette changes.
 	This is the default.
 pmipal	Use the protected mode interface for palette changes.
 
 mtrr	setup memory type range registers for the vesafb framebuffer.
 
+vram:n  remap 'n' MiB of video RAM. If 0 or not specified, remap memory
+        according to video mode. (2.5.66 patch/idea by Antonino Daplas
+	reversed to give override possibility (allocate more fb memory
+	than the kernel would) to 2.4 by tmb@iki.fi)
+  
 
 Have fun!
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/filesystems/befs.txt linux-2.4.22-pre10/Documentation/filesystems/befs.txt
--- linux-2.4.21/Documentation/filesystems/befs.txt	2002-11-28 23:53:08.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/filesystems/befs.txt	2003-08-01 13:31:43.000000000 +0000
@@ -18,32 +18,35 @@
 AUTHOR
 =====
 Current maintainer: Will Dyson <will_dyson@pobox.com>
-Has been working on the code since Aug 13, 2001. See the changelog for details.
+Has been working on the code since Aug 13, 2001. See the changelog for
+details.
 
 Original Author: Makoto Kato <m_kato@ga2.so-net.ne.jp>
-His orriginal code can still be found at: <http://hp.vector.co.jp/authors/VA008030/bfs/>
-Does anyone know of a more current email address for Makoto? He doesn't respond
-to the address given above...
+His orriginal code can still be found at:
+<http://hp.vector.co.jp/authors/VA008030/bfs/>
+Does anyone know of a more current email address for Makoto? He doesn't
+respond to the address given above...
 
 WHAT IS THIS DRIVER?
 ==================
 This module implements the native filesystem of BeOS <http://www.be.com/>
-for the linux 2.4.1 and later kernels. Currently it is a read-only implementation.
+for the linux 2.4.1 and later kernels. Currently it is a read-only
+implementation.
 
 Which is it, BFS or BEFS?
 ================
 Be, Inc said, "BeOS Filesystem is officially called BFS, not BeFS". 
-But Unixware Boot Filesystem is called bfs, too. And they are already in the
-kernel.
-Because of this nameing conflict, on Linux the BeOS filesystem is called befs.
+But Unixware Boot Filesystem is called bfs, too. And they are already in
+the kernel. Because of this nameing conflict, on Linux the BeOS
+filesystem is called befs.
 
 HOW TO INSTALL
 ==============
 step 1.  Install the BeFS  patch into the source code tree of linux.
 
 Apply the patchfile to your kernel source tree.
-Assuming that your kernel source is in /foo/bar/linux and the patchfile is called
-patch-befs-xxx, you would do the following:
+Assuming that your kernel source is in /foo/bar/linux and the patchfile
+is called patch-befs-xxx, you would do the following:
 
 	cd /foo/bar/linux
 	patch -p1 < /path/to/patch-befs-xxx
@@ -66,8 +69,9 @@
 The BeFS module is not a standard part of the linux kernel, so you must first
 enable support for experimental code under the "Code maturity level" menu.
 
-Then, under the "Filesystems" menu will be an option called "BeFS filesystem (experimental)",
-or something like that. Enable that option (it is fine to make it a module).
+Then, under the "Filesystems" menu will be an option called "BeFS
+filesystem (experimental)", or something like that. Enable that option
+(it is fine to make it a module).
 
 Save your kernel configuration and then build your kernel.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/filesystems/jfs.txt linux-2.4.22-pre10/Documentation/filesystems/jfs.txt
--- linux-2.4.21/Documentation/filesystems/jfs.txt	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/filesystems/jfs.txt	2003-08-01 13:33:39.000000000 +0000
@@ -4,10 +4,10 @@
 
 Team members
 ------------
-Steve Best         sbest@us.ibm.com
 Dave Kleikamp      shaggy@austin.ibm.com  
+Dave Blaschke      blaschke@us.ibm.com
+Steve Best         sbest@us.ibm.com
 Barry Arndt        barndt@us.ibm.com
-Christoph Hellwig  hch@infradead.org
 
 The following mount options are supported:
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/filesystems/sysv-fs.txt linux-2.4.22-pre10/Documentation/filesystems/sysv-fs.txt
--- linux-2.4.21/Documentation/filesystems/sysv-fs.txt	1997-12-16 17:43:36.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/filesystems/sysv-fs.txt	2003-08-01 13:30:38.000000000 +0000
@@ -23,8 +23,9 @@
   - Only file systems with no filesystem name and no pack name are recognized.
   (See Coherent "man mkfs" for a description of these features.)
 - SystemV Release 2 FS:
-  The superblock is only searched in the blocks 9, 15, 18, which corresponds to the
-  beginning of track 1 on floppy disks. No support for this FS on hard disk yet.
+  The superblock is only searched in the blocks 9, 15, 18, which
+  corresponds to the beginning of track 1 on floppy disks. No support
+  for this FS on hard disk yet.
 
 
 Please report any bugs and suggestions to
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/filesystems/tmpfs.txt linux-2.4.22-pre10/Documentation/filesystems/tmpfs.txt
--- linux-2.4.21/Documentation/filesystems/tmpfs.txt	2001-12-21 17:41:53.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/filesystems/tmpfs.txt	2003-08-01 13:32:00.000000000 +0000
@@ -47,26 +47,28 @@
    shared memory)
 
 3) Some people (including me) find it very convenient to mount it
-   e.g. on /tmp and /var/tmp and have a big swap partition. But be
-   aware: loop mounts of tmpfs files do not work due to the internal
-   design. So mkinitrd shipped by most distributions will fail with a
-   tmpfs /tmp.
+   e.g. on /tmp and /var/tmp and have a big swap partition. And now
+   loop mounts of tmpfs files do work, so mkinitrd shipped by most
+   distributions should succeed with a tmpfs /tmp.
 
 4) And probably a lot more I do not know about :-)
 
 
-tmpfs has a couple of mount options:
+tmpfs has three mount options for sizing:
 
-size:	   The limit of allocated bytes for this tmpfs instance. The 
+size:      The limit of allocated bytes for this tmpfs instance. The 
            default is half of your physical RAM without swap. If you
-	   oversize your tmpfs instances the machine will deadlock
-	   since the OOM handler will not be able to free that memory.
-nr_blocks: The same as size, but in blocks of PAGECACHE_SIZE.
+           oversize your tmpfs instances the machine will deadlock
+           since the OOM handler will not be able to free that memory.
+nr_blocks: The same as size, but in blocks of PAGE_CACHE_SIZE.
 nr_inodes: The maximum number of inodes for this instance. The default
            is half of the number of your physical RAM pages.
 
 These parameters accept a suffix k, m or g for kilo, mega and giga and
-can be changed on remount.
+can be changed on remount.  The size parameter also accepts a suffix %
+to limit this tmpfs instance to that percentage of your physical RAM:
+the default, when neither size nor nr_blocks is specified, is size=50%
+
 
 To specify the initial root directory you can use the following mount
 options:
@@ -84,19 +86,7 @@
 RAM/SWAP in 10240 inodes and it is only accessible by root.
 
 
-TODOs:
-
-1) give the size option a percent semantic: If you give a mount option
-   size=50% the tmpfs instance should be able to grow to 50 percent of
-   RAM + swap. So the instance should adapt automatically if you add
-   or remove swap space.
-2) loop mounts: This is difficult since loop.c relies on the readpage
-   operation. This operation gets a page from the caller to be filled
-   with the content of the file at that position. But tmpfs always has
-   the page and thus cannot copy the content to the given page. So it
-   cannot provide this operation. The VM had to be changed seriously
-   to achieve this.
-3) Show the number of tmpfs RAM pages. (As shared?)
-
 Author:
    Christoph Rohland <cr@sap.com>, 1.12.01
+Updated:
+   Hugh Dickins <hugh@veritas.com>, 01 April 2003
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/ia64/efirtc.txt linux-2.4.22-pre10/Documentation/ia64/efirtc.txt
--- linux-2.4.21/Documentation/ia64/efirtc.txt	2001-02-09 00:32:44.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/ia64/efirtc.txt	2003-08-01 13:33:40.000000000 +0000
@@ -12,13 +12,13 @@
 to get access to the Time Service offered by EFI version 0.92.
 
 EFI provides 4 calls one can make once the OS is booted: GetTime(),
-SetTime(), GetWakeupTime(), SetWakeupTime() which are all supported by this driver.
-We describe those calls as well the design of the driver in the following
-sections.
+SetTime(), GetWakeupTime(), SetWakeupTime() which are all supported by this
+driver. We describe those calls as well the design of the driver in the
+following sections.
 
 II/ Design Decisions
 
-The original ideas was to provide a very simple  driver to get access to, 
+The original ideas was to provide a very simple driver to get access to, 
 at first, the time of day service. This is required in order to access, in a 
 portable way, the CMOS clock. A program like /sbin/hwclock uses such a clock 
 to initialize the system view of the time during boot.
@@ -39,8 +39,8 @@
 without necessarily impacting any of the user applications. The decoupling
 enables flexibility and permits writing wrapper code is ncase things change.
 
-The driver exposes two interfaces, one via the device file and a set of ioctl()s.
-The other is read-only via the /proc filesystem. 
+The driver exposes two interfaces, one via the device file and a set of
+ioctl()s. The other is read-only via the /proc filesystem. 
 
 As of today we don't offer a /proc/sys interface.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/kernel-parameters.txt linux-2.4.22-pre10/Documentation/kernel-parameters.txt
--- linux-2.4.21/Documentation/kernel-parameters.txt	2002-11-28 23:53:08.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/kernel-parameters.txt	2003-08-01 13:33:23.000000000 +0000
@@ -341,6 +341,18 @@
 			memory; to be used when the kernel is not able
 			to see the whole system memory or for test.
 
+	mem=nn[KMG]@ss[KMG]
+			[KNL,BOOT] Force usage of a specific region of memory
+			Region of memory to be used, from ss to ss+nn.
+
+	mem=nn[KMG]#ss[KMG]
+			[KNL,BOOT,ACPI] Mark specific memory as ACPI data.
+			Region of memory to be used, from ss to ss+nn.
+
+	mem=nn[KMG]$ss[KMG]
+			[KNL,BOOT,ACPI] Mark specific memory as reserved.
+			Region of memory to be used, from ss to ss+nn.
+
 	memfrac=	[KNL]
 
 	mga=		[HW,DRM]
@@ -491,7 +503,7 @@
 	plip=		[PPT,NET] Parallel port network link.
 
 	profile=	[KNL] enable kernel profiling via /proc/profile
-			(param:log level).
+			(param: profile step/bucket size as a power of 2)
 
 	prompt_ramdisk=	[RAM] List of RAM disks to prompt for floppy disk
 			before loading.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/networking/bonding.txt linux-2.4.22-pre10/Documentation/networking/bonding.txt
--- linux-2.4.21/Documentation/networking/bonding.txt	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/networking/bonding.txt	2003-08-01 13:32:02.000000000 +0000
@@ -43,10 +43,10 @@
 For the latest version of the bonding driver, use kernel 2.4.12 or above
 (otherwise you will need to apply a patch).
 
-Configure kernel with `make menuconfig/xconfig/config', and select
-"Bonding driver support" in the "Network device support" section. It is
-recommended to configure the driver as module since it is currently the only way
-to pass parameters to the driver and configure more than one bonding device.
+Configure kernel with `make menuconfig/xconfig/config', and select "Bonding
+driver support" in the "Network device support" section. It is recommended
+to configure the driver as module since it is currently the only way to
+pass parameters to the driver and configure more than one bonding device.
 
 Build and install the new kernel and modules.
 
@@ -108,17 +108,17 @@
 SLAVE=yes
 BOOTPROTO=none
 
-Use DEVICE=eth1 in the ifcfg-eth1 config file. If you configure a second bonding
-interface (bond1), use MASTER=bond1 in the config file to make the network
-interface be a slave of bond1.
+Use DEVICE=eth1 in the ifcfg-eth1 config file. If you configure a second
+bonding interface (bond1), use MASTER=bond1 in the config file to make the
+network interface be a slave of bond1.
 
 Restart the networking subsystem or just bring up the bonding device if your
 administration tools allow it. Otherwise, reboot. On Red Hat distros you can 
 issue `ifup bond0' or `/etc/rc.d/init.d/network restart'.
 
-If the administration tools of your distribution do not support master/slave
-notation in configuring network interfaces, you will need to manually configure 
-the bonding device with the following commands:
+If the administration tools of your distribution do not support
+master/slave notation in configuring network interfaces, you will need to
+manually configure the bonding device with the following commands:
 
     # /sbin/ifconfig bond0 192.168.1.1 netmask 255.255.255.0 \
       broadcast 192.168.1.255 up
@@ -166,8 +166,9 @@
      ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.127.0.0.1 = 1
 
 This problem is avoided by loading the bonding driver before any network
-drivers participating in a bond. Below is an example of loading the bonding 
-driver first, the IP address 192.168.1.1 is correctly associated with ifDescr.2.
+drivers participating in a bond. Below is an example of loading the bonding
+driver first, the IP address 192.168.1.1 is correctly associated with
+ifDescr.2.
 
      interfaces.ifTable.ifEntry.ifDescr.1 = lo
      interfaces.ifTable.ifEntry.ifDescr.2 = bond0
@@ -200,6 +201,44 @@
 parameters be specified, otherwise serious network degradation will occur
 during link failures.
 
+arp_interval
+ 
+        Specifies the ARP monitoring frequency in milli-seconds. 
+        If ARP monitoring is used in a load-balancing mode (mode 0 or 2), the 
+        switch should be configured in a mode that evenly distributes packets 
+        across all links - such as round-robin. If the switch is configured to 
+        distribute the packets in an XOR fashion, all replies from the ARP 
+        targets will be received on the same link which could cause the other 
+        team members to fail. ARP monitoring should not be used in conjunction
+        with miimon. A value of 0 disables ARP monitoring. The default value 
+        is 0.
+ 
+arp_ip_target
+ 
+	Specifies the ip addresses to use when arp_interval is > 0. These
+	are the targets of the ARP request sent to determine the health of
+	the link to the targets. Specify these values in ddd.ddd.ddd.ddd
+	format. Multiple ip adresses must be seperated by a comma. At least
+	one ip address needs to be given for ARP monitoring to work. The
+	maximum number of targets that can be specified is set at 16.
+
+downdelay
+ 
+        Specifies the delay time in milli-seconds to disable a link after a 
+        link failure has been detected. This should be a multiple of miimon
+        value, otherwise the value will be rounded. The default value is 0.
+
+lacp_rate
+
+        Option specifying the rate in which we'll ask our link partner to
+	transmit LACPDU packets in 802.3ad mode.  Possible values are:
+
+	slow or 0
+		Request partner to transmit LACPDUs every 30 seconds (default)
+
+	fast or 1
+		Request partner to transmit LACPDUs every 1 second
+
 max_bonds
 
 	Specifies the number of bonding devices to create for this
@@ -207,18 +246,27 @@
 	the bonding driver is not already loaded, then bond0, bond1
 	and bond2 will be created.  The default value is 1.
 
+miimon
+ 
+        Specifies the frequency in milli-seconds that MII link monitoring
+        will occur. A value of zero disables MII link monitoring. A value
+        of 100 is a good starting point. See High Availability section for
+        additional information. The default value is 0.
+
 mode
 
-	Specifies one of four bonding policies. The default is
-round-robin (balance-rr).  Possible values are (you can use either the
-text or numeric option):
+	Specifies one of the bonding policies. The default is
+	round-robin (balance-rr).  Possible values are (you can use
+	either the text or numeric option):
  
 	balance-rr or 0
+
 		Round-robin policy: Transmit in a sequential order
 		from the first available slave through the last. This
 		mode provides load balancing and fault tolerance.
 
 	active-backup or 1
+
 		Active-backup policy: Only one slave in the bond is
 		active. A different slave becomes active if, and only
 		if, the active slave fails. The bond's MAC address is
@@ -226,7 +274,8 @@
 		to avoid confusing the switch.  This mode provides
 		fault tolerance.
  
-        balance-xor or 2
+	balance-xor or 2
+
 		XOR policy: Transmit based on [(source MAC address
 		XOR'd with destination MAC address) modula slave
 		count]. This selects the same slave for each
@@ -234,16 +283,125 @@
 		balancing and fault tolerance.
 
 	broadcast or 3
+
 		Broadcast policy: transmits everything on all slave
 		interfaces. This mode provides fault tolerance.
 
-miimon
- 
-        Specifies the frequency in milli-seconds that MII link monitoring will 
-        occur. A value of zero disables MII link monitoring. A value of 
-        100 is a good starting point. See High Availability section for 
-        additional information. The default value is 0.
+	802.3ad or 4
+
+		IEEE 802.3ad Dynamic link aggregation. Creates aggregation
+		groups that share the same speed and duplex settings.
+		Transmits and receives on all slaves in the active
+		aggregator.
+ 
+		Pre-requisites:
+
+		1. Ethtool support in the base drivers for retrieving the
+		speed and duplex of each slave.
+
+		2. A switch that supports IEEE 802.3ad Dynamic link
+		aggregation.
+
+	balance-tlb or 5
+
+		Adaptive transmit load balancing: channel bonding that does
+		not require any special switch support. The outgoing
+		traffic is distributed according to the current load
+		(computed relative to the speed) on each slave. Incoming
+		traffic is received by the current slave. If the receiving
+		slave fails, another slave takes over the MAC address of
+		the failed receiving slave.
+
+		Prerequisite:
+
+		Ethtool support in the base drivers for retrieving the
+		speed of each slave.
+
+	balance-alb or 6 
+
+		Adaptive load balancing: includes balance-tlb + receive
+		load balancing (rlb) for IPV4 traffic and does not require
+		any special switch support. The receive load balancing is
+		achieved by ARP negotiation. The bonding driver intercepts
+		the ARP Replies sent by the server on their way out and
+		overwrites the src hw address with the unique hw address of
+		one of the slaves in the bond such that different clients
+		use different hw addresses for the server.
+		
+		Receive traffic from connections created by the server is
+		also balanced. When the server sends an ARP Request the
+		bonding driver copies and saves the client's IP information
+		from the ARP. When the ARP Reply arrives from the client,
+		its hw address is retrieved and the bonding driver
+		initiates an ARP reply to this client assigning it to one
+		of the slaves in the bond. A problematic outcome of using
+		ARP negotiation for balancing is that each time that an ARP
+		request is broadcasted it uses the hw address of the
+		bond. Hence, clients learn the hw address of the bond and
+		the balancing of receive traffic collapses to the current
+		salve. This is handled by sending updates (ARP Replies) to
+		all the clients with their assigned hw address such that
+		the traffic is redistributed. Receive traffic is also
+		redistributed when a new slave is added to the bond and
+		when an inactive slave is re-activated. The receive load is
+		distributed sequentially (round robin) among the group of
+		highest speed slaves in the bond.
+
+		When a link is reconnected or a new slave joins the bond
+		the receive traffic is redistributed among all active
+		slaves in the bond by intiating ARP Replies with the
+		selected mac address to each of the clients. The updelay
+		modeprobe parameter must be set to a value equal or greater
+		than the switch's forwarding delay so that the ARP Replies
+		sent to the clients will not be blocked by the switch.
+
+		Prerequisites:
+
+		1. Ethtool support in the base drivers for retrieving the
+		speed of each slave.
+
+		2. Base driver support for setting the hw address of a
+		device also when it is open. This is required so that there
+		will always be one slave in the team using the bond hw
+		address (the current_slave) while having a unique hw
+		address for each slave in the bond. If the current_slave
+		fails it's hw address is swapped with the new current_slave
+		that was chosen.
+
+multicast
+
+        Option specifying the mode of operation for multicast support.
+        Possible values are:
+
+	disabled or 0
+		Disabled (no multicast support)
+
+        active or 1
+		Enabled on active slave only, useful in active-backup mode
+
+	all or 2
+		Enabled on all slaves, this is the default
+
+primary
+
+        A string (eth0, eth2, etc) to equate to a primary device. If this
+        value is entered, and the device is on-line, it will be used first
+        as the output media. Only when this device is off-line, will
+        alternate devices be used. Otherwise, once a failover is detected
+        and a new default output is chosen, it will remain the output media
+        until it too fails. This is useful when one slave was preferred
+        over another, i.e. when one slave is 1000Mbps and another is
+        100Mbps. If the 1000Mbps slave fails and is later restored, it may
+        be preferred the faster slave gracefully become the active slave -
+        without deliberately failing the 100Mbps slave. Specifying a
+        primary is only valid in active-backup mode.
 
+updelay
+ 
+        Specifies the delay time in milli-seconds to enable a link after a 
+        link up status has been detected. This should be a multiple of miimon
+        value, otherwise the value will be rounded. The default value is 0.
+ 
 use_carrier
 
         Specifies whether or not miimon should use MII or ETHTOOL
@@ -265,89 +423,37 @@
         0 will use the deprecated MII / ETHTOOL ioctls.  The default
         value is 1.
 
-downdelay
- 
-        Specifies the delay time in milli-seconds to disable a link after a 
-        link failure has been detected. This should be a multiple of miimon
-        value, otherwise the value will be rounded. The default value is 0.
-
-updelay
- 
-        Specifies the delay time in milli-seconds to enable a link after a 
-        link up status has been detected. This should be a multiple of miimon
-        value, otherwise the value will be rounded. The default value is 0.
- 
-arp_interval
- 
-        Specifies the ARP monitoring frequency in milli-seconds. 
-        If ARP monitoring is used in a load-balancing mode (mode 0 or 2), the 
-        switch should be configured in a mode that evenly distributes packets 
-        across all links - such as round-robin. If the switch is configured to 
-        distribute the packets in an XOR fashion, all replies from the ARP 
-        targets will be received on the same link which could cause the other 
-        team members to fail. ARP monitoring should not be used in conjunction
-        with miimon. A value of 0 disables ARP monitoring. The default value 
-        is 0.
- 
-arp_ip_target
- 
-        Specifies the ip addresses to use when arp_interval is > 0. These are
-        the targets of the ARP request sent to determine the health of the link
-        to the targets. Specify these values in ddd.ddd.ddd.ddd format.
-        Multiple ip adresses must be seperated by a comma. At least one ip
-        address needs to be given for ARP monitoring to work. The maximum number
-        of targets that can be specified is set at 16.
-
-primary
-
-        A string (eth0, eth2, etc) to equate to a primary device. If this 
-        value is entered, and the device is on-line, it will be used first as 
-        the output media. Only when this device is off-line, will alternate 
-        devices be used. Otherwise, once a failover is detected and a new 
-        default output is chosen, it will remain the output media until it too 
-        fails. This is useful when one slave was preferred over another, i.e. 
-        when one slave is 1000Mbps and another is 100Mbps. If the 1000Mbps 
-        slave fails and is later restored, it may be preferred the faster slave
-        gracefully become the active slave - without deliberately failing the
-        100Mbps slave. Specifying a primary is only valid in active-backup mode.
-
-multicast
-
-        Option specifying the mode of operation for multicast support.
-        Possible values are:
-
-	disabled or 0
-		Disabled (no multicast support)
-
-        active or 1
-		Enabled on active slave only, useful in active-backup mode
-
-	all or 2
-		Enabled on all slaves, this is the default
-
 
 Configuring Multiple Bonds
 ==========================
 
-If several bonding interfaces are required, the driver must be loaded
-multiple times. For example, to configure two bonding interfaces with link 
-monitoring performed every 100 milli-seconds, the /etc/conf.modules should
+If several bonding interfaces are required, either specify the max_bonds
+parameter (described above), or load the driver multiple times.  Using
+the max_bonds parameter is less complicated, but has the limitation that
+all bonding instances created will have the same options.  Loading the
+driver multiple times allows each instance of the driver to have differing
+options.
+
+For example, to configure two bonding interfaces, one with mii link
+monitoring performed every 100 milliseconds, and one with ARP link
+monitoring performed every 200 milliseconds, the /etc/conf.modules should
 resemble the following:
 
 alias bond0 bonding
 alias bond1 bonding
 
 options bond0 miimon=100
-options bond1 -o bonding1 miimon=100
+options bond1 -o bonding1 arp_interval=200 arp_ip_target=10.0.0.1
 
 Configuring Multiple ARP Targets
 ================================
 
-While ARP monitoring can be done with just one target, it can be usefull
+While ARP monitoring can be done with just one target, it can be useful
 in a High Availability setup to have several targets to monitor. In the
 case of just one target,  the target itself may go down or have a problem
 making it unresponsive to ARP requests. Having an additional target (or
-several) would increase the reliability of the ARP monitoring.
+several) increases the reliability of the ARP monitoring.
+
 Multiple ARP targets must be seperated by commas as follows:
 
 # example options for ARP monitoring with three targets
@@ -410,9 +516,10 @@
 Switch Configuration
 ====================
 
-While the switch does not need to be configured when the active-backup
-policy is used (mode=1), it does need to be configured for the round-robin, 
-XOR, and broadcast policies (mode=0, mode=2, and mode=3). 
+While the switch does not need to be configured when the active-backup,
+balance-tlb or balance-alb policies (mode=1,5,6) are used, it does need to
+be configured for the round-robin, XOR, broadcast, or 802.3ad policies
+(mode=0,2,3,4).
 
 
 Verifying Bond Configuration
@@ -420,7 +527,7 @@
 
 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/bond* directories.
 
 Sample contents of /proc/net/bond0/info after the driver is loaded with 
 parameters of mode=0 and miimon=1000 is shown below.
@@ -445,7 +552,8 @@
 The network configuration can be verified using the ifconfig command. In
 the example below, the bond0 interface is the master (MASTER) while eth0 and 
 eth1 are slaves (SLAVE). Notice all slaves of bond0 have the same MAC address 
-(HWaddr) as bond0.
+(HWaddr) as bond0 for all modes except TLB and ALB that require a unique MAC
+address for each slave.
 
 [root]# /sbin/ifconfig
 bond0     Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4  
@@ -488,8 +596,7 @@
 
 3.  How many bonding devices can I have?
 
-	One for each module you load. See section on Module Parameters for how
-	to accomplish this.
+	There is no limit.
 
 4.  How many slaves can a bonding device have?
 
@@ -508,10 +615,11 @@
 	For ethernet cards not supporting MII status, the arp_interval and
         arp_ip_target parameters must be specified for bonding to work
         correctly. If packets have not been sent or received during the
-        specified arp_interval durration, an ARP request is sent to the targets 
-        to generate send and receive traffic. If after this interval, either 
-        the successful send and/or receive count has not incremented, the next 
-        slave in the sequence will become the active slave.
+        specified arp_interval durration, an ARP request is sent to the
+        targets to generate send and receive traffic. If after this
+        interval, either the successful send and/or receive count has not
+        incremented, the next slave in the sequence will become the active
+        slave.
 
 	If neither mii_monitor and arp_interval is configured, the bonding
 	driver will not handle this situation very well. The driver will 
@@ -522,15 +630,16 @@
 
 6.  Can bonding be used for High Availability?
 
-	Yes, if you use MII monitoring and ALL your cards support MII link
-	status reporting. See section on High Availability for more information.
+        Yes, if you use MII monitoring and ALL your cards support MII link
+        status reporting. See section on High Availability for more
+        information.
 
 7.  Which switches/systems does it work with?
 
 	In round-robin and XOR mode, it works with systems that support 
 	trunking:
 	
-	* Cisco 5500 series (look for EtherChannel support).
+	* Many Cisco switches and routers (look for EtherChannel support).
 	* SunTrunking software.
 	* Alteon AceDirector switches / WebOS (use Trunks).
 	* BayStack Switches (trunks must be explicitly configured). Stackable
@@ -538,7 +647,17 @@
 	  units.
 	* Linux bonding, of course !
 	
-	In active-backup mode, it should work with any Layer-II switche.
+	In 802.3ad mode, it works with with systems that support IEEE 802.3ad
+	Dynamic Link Aggregation:
+
+	* Extreme networks Summit 7i (look for link-aggregation).
+	* Many Cisco switches and routers (look for LACP support; this may
+	  require an upgrade to your IOS software; LACP support was added
+	  by Cisco in late 2002).
+	* Foundry Big Iron 4000
+
+        In active-backup, balance-tlb and balance-alb modes, it should work
+        with any Layer-II switch.
 
 
 8.  Where does a bonding device get its MAC address from?
@@ -591,6 +710,20 @@
 
 	Broadcast policy transmits everything on all slave interfaces.
 
+	802.3ad, based on XOR but distributes traffic among all interfaces
+	in the active aggregator.
+
+	Transmit load balancing (balance-tlb) balances the traffic
+	according to the current load on each slave. The balancing is
+	clients based and the least loaded slave is selected for each new
+	client. The load of each slave is calculated relative to its speed
+	and enables load balancing in mixed speed teams.
+
+	Adaptive load balancing (balance-alb) uses the Transmit load
+	balancing for the transmit load. The receive load is balanced only
+	among the group of highest speed active slaves in the bond. The
+	load is distributed with round-robin i.e. next available slave in
+	the high speed group of active slaves.
 
 High Availability
 =================
@@ -826,10 +959,6 @@
     Use the arp_interval/arp_ip_target parameters to count incoming/outgoing
     frames.  
 
-  - A Transmit Load Balancing policy is not currently available. This mode 
-    allows every slave in the bond to transmit while only one receives. If 
-    the "receiving" slave fails, another slave takes over the MAC address of 
-    the failed receiving slave.
 
 
 Resources and Links
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/networking/ifenslave.c linux-2.4.22-pre10/Documentation/networking/ifenslave.c
--- linux-2.4.21/Documentation/networking/ifenslave.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/networking/ifenslave.c	2003-08-01 13:31:33.000000000 +0000
@@ -27,7 +27,7 @@
  *    - 2001/02/16 Chad N. Tindel <ctindel at ieee dot org> :
  *       - Master is now brought down before setting the MAC address.  In
  *         the 2.4 kernel you can't change the MAC address while the device is
- *         up because you get EBUSY.  
+ *         up because you get EBUSY.
  *
  *    - 2001/09/13 Takao Indoh <indou dot takao at jp dot fujitsu dot com>
  *       - Added the ability to change the active interface on a mode 1 bond
@@ -44,17 +44,60 @@
  *
  *    - 2002/10/31 Tony Cureington <tony.cureington * hp_com> :
  *       - If the master does not have a hardware address when the first slave
- *         is enslaved, the master is assigned the hardware address of that 
- *         slave - there is a comment in bonding.c stating "ifenslave takes 
- *         care of this now." This corrects the problem of slaves having 
- *         different hardware addresses in active-backup mode when 
+ *         is enslaved, the master is assigned the hardware address of that
+ *         slave - there is a comment in bonding.c stating "ifenslave takes
+ *         care of this now." This corrects the problem of slaves having
+ *         different hardware addresses in active-backup mode when
  *         multiple interfaces are specified on a single ifenslave command
  *         (ifenslave bond0 eth0 eth1).
  *
+ *    - 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
+ *                   Shmulik Hen <shmulik.hen at intel dot com>
+ *       - Moved setting the slave's mac address and openning it, from
+ *         the application to the driver. This enables support of modes
+ *         that need to use the unique mac address of each slave.
+ *         The driver also takes care of closing the slave and restoring its
+ *         original mac address upon release.
+ *         In addition, block possibility of enslaving before the master is up.
+ *         This prevents putting the system in an undefined state.
+ *
+ *    - 2003/05/01 - Amir Noam <amir.noam at intel dot com>
+ *       - Added ABI version control to restore compatibility between
+ *         new/old ifenslave and new/old bonding.
+ *       - Prevent adding an adapter that is already a slave.
+ *         Fixes the problem of stalling the transmission and leaving
+ *         the slave in a down state.
+ *
+ *    - 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
+ *       - Prevent enslaving if the bond device is down.
+ *         Fixes the problem of leaving the system in unstable state and
+ *         halting when trying to remove the module.
+ *       - Close socket on all abnormal exists.
+ *       - Add versioning scheme that follows that of the bonding driver.
+ *         current version is 1.0.0 as a base line.
+ *
+ *    - 2003/05/22 - Jay Vosburgh <fubar at us dot ibm dot com>
+ *	 - ifenslave -c was broken; it's now fixed
+ *	 - Fixed problem with routes vanishing from master during enslave
+ *	   processing.
+ *
+ *    - 2003/05/27 - Amir Noam <amir.noam at intel dot com>
+ *	 - Fix backward compatibility issues:
+ *	   For drivers not using ABI versions, slave was set down while
+ *	   it should be left up before enslaving.
+ *	   Also, master was not set down and the default set_mac_address()
+ *	   would fail and generate an error message in the system log.
+ * 	 - For opt_c: slave should not be set to the master's setting
+ *	   while it is running. It was already set during enslave. To
+ *	   simplify things, it is now handeled separately.
  */
 
+#define APP_VERSION	"1.0.12"
+#define APP_RELDATE	"June 30, 2003"
+#define APP_NAME	"ifenslave"
+
 static char *version =
-"ifenslave.c:v0.07 9/9/97  Donald Becker (becker@cesdis.gsfc.nasa.gov).\n"
+APP_NAME ".c:v" APP_VERSION " (" APP_RELDATE ") "  "\nDonald Becker (becker@cesdis.gsfc.nasa.gov).\n"
 "detach support added on 2000/10/02 by Willy Tarreau (willy at meta-x.org).\n"
 "2.4 kernel support added on 2001/02/16 by Chad N. Tindel (ctindel at ieee dot org.\n";
 
@@ -97,12 +140,17 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
-#include <linux/if.h>
-#include <linux/if_arp.h>
+#include <net/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/if_bonding.h>
 #include <linux/sockios.h>
 
+typedef unsigned long long u64;	/* hack, so we may include kernel's ethtool.h */
+typedef __uint32_t u32;		/* ditto */
+typedef __uint16_t u16;		/* ditto */
+typedef __uint8_t u8;		/* ditto */
+#include <linux/ethtool.h>
+
 struct option longopts[] = {
  /* { name  has_arg  *flag  val } */
     {"all-interfaces", 0, 0, 'a'},	/* Show all interfaces. */
@@ -130,18 +178,19 @@
 int skfd = -1;					/* AF_INET socket for ioctl() calls.	*/
 
 static void if_print(char *ifname);
+static int get_abi_ver(char *master_ifname);
 
 int
 main(int argc, char **argv)
 {
 	struct ifreq  ifr2, if_hwaddr, if_ipaddr, if_metric, if_mtu, if_dstaddr;
 	struct ifreq  if_netmask, if_brdaddr, if_flags;
-	int goterr = 0;
+	int rv, goterr = 0;
 	int c, errflag = 0;
 	sa_family_t master_family;
 	char **spp, *master_ifname, *slave_ifname;
 	int hwaddr_notset;
-	int master_up;
+	int abi_ver = 0;
 
 	while ((c = getopt_long(argc, argv, "acdfrvV?h", longopts, 0)) != EOF)
 		switch (c) {
@@ -207,6 +256,7 @@
 		char **tempp = spp;
 		if ((master_ifname == NULL)||(slave_ifname == NULL)||(*tempp++ != NULL)) {
 			fprintf(stderr, usage_msg);
+			(void) close(skfd);
 			return 2;
 		}
 	}
@@ -218,6 +268,13 @@
 		exit(0);
 	}
 
+	/* exchange abi version with bonding driver */
+	abi_ver = get_abi_ver(master_ifname);
+	if (abi_ver < 0) {
+		(void) close(skfd);
+		exit(1);
+	}
+
 	/* Get the vitals from the master interface. */
 	{
 		struct ifreq *ifra[7] = { &if_ipaddr, &if_mtu, &if_dstaddr,
@@ -242,6 +299,13 @@
 			}
 		}
 
+		/* check if master is up; if not then fail any operation */
+		if (!(if_flags.ifr_flags & IFF_UP)) {
+			fprintf(stderr, "Illegal operation; the specified master interface '%s' is not up.\n", master_ifname);
+			(void) close(skfd);
+			exit (1);
+		}
+
 		hwaddr_notset = 1; /* assume master's address not set yet */
 		for (i = 0; hwaddr_notset && (i < 6); i++) {
 			hwaddr_notset &= ((unsigned char *)if_hwaddr.ifr_hwaddr.sa_data)[i] == 0;
@@ -254,7 +318,7 @@
 					" with ethernet-like network interfaces.\n"
 					" Use the '-f' option to force the operation.\n",
 					master_ifname);
-
+			(void) close(skfd);
 			exit (1);
 		}
 		master_family = if_hwaddr.ifr_hwaddr.sa_family;
@@ -278,143 +342,153 @@
 					fprintf(stderr,	"SIOCBONDRELEASE: cannot detach %s from %s. errno=%s.\n",
 							slave_ifname, master_ifname, strerror(errno));
 			}
-			else {  /* we'll set the interface down to avoid any conflicts due to
-					   same IP/MAC */
+			else if (abi_ver < 1) {
+			      	/* The driver is using an old ABI, so we'll set the interface
+				 * down to avoid any conflicts due to same IP/MAC
+				 */
 				strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ);
 				if (ioctl(skfd, SIOCGIFFLAGS, &ifr2) < 0) {
 					int saved_errno = errno;
 					fprintf(stderr, "SIOCGIFFLAGS on %s failed: %s\n", slave_ifname,
-							strerror(saved_errno));
+						strerror(saved_errno));
 				}
 				else {
 					ifr2.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
 					if (ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
 						int saved_errno = errno;
 						fprintf(stderr, "Shutting down interface %s failed: %s\n",
-								slave_ifname, strerror(saved_errno));
+							slave_ifname, strerror(saved_errno));
 					}
 				}
 			}
-		}
-		else {  /* attach a slave interface to the master */
-			/* two possibilities :
-			   - if hwaddr_notset, do nothing.  The bond will assign the
-			     hwaddr from it's first slave.
-			   - if !hwaddr_notset, assign the master's hwaddr to each slave
-			*/
+		} else if (opt_c) { /* change primary slave */
+			strncpy(if_flags.ifr_name, master_ifname, IFNAMSIZ);
+			strncpy(if_flags.ifr_slave, slave_ifname, IFNAMSIZ);
+			if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &if_flags) < 0) &&
+			    (ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &if_flags) < 0)) {
+				fprintf(stderr,	"SIOCBONDCHANGEACTIVE: %s.\n", strerror(errno));
+			}
+		} else {  /* attach a slave interface to the master */
 
 			strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ);
 			if (ioctl(skfd, SIOCGIFFLAGS, &ifr2) < 0) {
 				int saved_errno = errno;
 				fprintf(stderr, "SIOCGIFFLAGS on %s failed: %s\n", slave_ifname,
 						strerror(saved_errno));
+				(void) close(skfd);
 				return 1;
 			}
 
+			if ((ifr2.ifr_flags & IFF_SLAVE) && !opt_r) {
+				fprintf(stderr, "%s is already a slave\n", slave_ifname);
+				(void) close(skfd);
+				return 1;
+			}
+
+			/* if hwaddr_notset, assign the slave hw address to the master */
 			if (hwaddr_notset) {
-				/* assign the slave hw address to the 
-				 * master since it currently does not 
+				/* assign the slave hw address to the
+				 * master since it currently does not
 				 * have one; otherwise, slaves may
-				 * have different hw addresses in 
-				 * active-backup mode as seen when enslaving 
+				 * have different hw addresses in
+				 * active-backup mode as seen when enslaving
 				 * using "ifenslave bond0 eth0 eth1" because
 				 * hwaddr_notset is set outside this loop.
 				 * TODO: put this and the "else" portion in
 				 *       a function.
 				 */
-				goterr = 0;
-				master_up = 0;
-				if (if_flags.ifr_flags & IFF_UP) {
-					if_flags.ifr_flags &= ~IFF_UP;
-					if (ioctl(skfd, SIOCSIFFLAGS, 
-							&if_flags) < 0) {
-						goterr = 1;
-						fprintf(stderr, 
-							"Shutting down "
-							"interface %s failed: "
-							"%s\n",
-							master_ifname, 
-							strerror(errno));
-					} else {
-						/* we took the master down, 
-						 * so we must bring it up 
-						 */
-						master_up = 1; 
-					}
+				/* get the slaves MAC address */
+				strncpy(if_hwaddr.ifr_name, slave_ifname,
+					IFNAMSIZ);
+				rv = ioctl(skfd, SIOCGIFHWADDR, &if_hwaddr);
+				if (-1 == rv) {
+					fprintf(stderr, "Could not get MAC "
+						"address of %s: %s\n",
+						slave_ifname,
+						strerror(errno));
+					strncpy(if_hwaddr.ifr_name,
+						master_ifname, IFNAMSIZ);
+					goterr = 1;
 				}
 
 				if (!goterr) {
-					/* get the slaves MAC address */
-					strncpy(if_hwaddr.ifr_name, 
-							slave_ifname, IFNAMSIZ);
-					if (ioctl(skfd, SIOCGIFHWADDR, 
-							&if_hwaddr) < 0) {
-						fprintf(stderr, 
-							"Could not get MAC "
-							"address of %s: %s\n",
-							slave_ifname, 
-							strerror(errno));
-						strncpy(if_hwaddr.ifr_name, 
-							master_ifname, 
-							IFNAMSIZ);
-						goterr=1;
+					if (abi_ver < 1) {
+						/* In ABI versions older than 1, the
+						 * master's set_mac routine couldn't
+						 * work if it was up, because it
+						 * used the default ethernet set_mac
+						 * function.
+						 */
+						/* bring master down */
+						if_flags.ifr_flags &= ~IFF_UP;
+						if (ioctl(skfd, SIOCSIFFLAGS,
+								&if_flags) < 0) {
+							goterr = 1;
+							fprintf(stderr,
+								"Shutting down "
+								"interface %s failed: "
+								"%s\n",
+								master_ifname,
+								strerror(errno));
+						}
 					}
-				}
 
-				if (!goterr) {
-					strncpy(if_hwaddr.ifr_name, 
+					strncpy(if_hwaddr.ifr_name,
 						master_ifname, IFNAMSIZ);
-					if (ioctl(skfd, SIOCSIFHWADDR, 
+					if (ioctl(skfd, SIOCSIFHWADDR,
 							&if_hwaddr) < 0) {
-						fprintf(stderr, 
+						fprintf(stderr,
 							"Could not set MAC "
 							"address of %s: %s\n",
-							master_ifname, 
+							master_ifname,
 							strerror(errno));
 						goterr=1;
 					} else {
 						hwaddr_notset = 0;
 					}
-				}
 
-				if (master_up) {
-					if_flags.ifr_flags |= IFF_UP;
-					if (ioctl(skfd, SIOCSIFFLAGS, 
-							&if_flags) < 0) {
-						fprintf(stderr, 
-							"Bringing up interface "
-							"%s failed: %s\n",
-							master_ifname, 
-							strerror(errno));
+					if (abi_ver < 1) {
+						/* bring master back up */
+						if_flags.ifr_flags |= IFF_UP;
+						if (ioctl(skfd, SIOCSIFFLAGS,
+							  &if_flags) < 0) {
+							fprintf(stderr,
+								"Bringing up interface "
+								"%s failed: %s\n",
+								master_ifname,
+								strerror(errno));
+						}
 					}
 				}
+			} else if (abi_ver < 1) { /* if (hwaddr_notset) */
 
-			} else {  
-				/* we'll assign master's hwaddr to this slave */
+			      	/* The driver is using an old ABI, so we'll set the interface
+				 * down and assign the master's hwaddr to it
+				 */
 				if (ifr2.ifr_flags & IFF_UP) {
 					ifr2.ifr_flags &= ~IFF_UP;
 					if (ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
 						int saved_errno = errno;
 						fprintf(stderr, "Shutting down interface %s failed: %s\n",
-								slave_ifname, strerror(saved_errno));
+							slave_ifname, strerror(saved_errno));
 					}
 				}
-	
+
 				strncpy(if_hwaddr.ifr_name, slave_ifname, IFNAMSIZ);
 				if (ioctl(skfd, SIOCSIFHWADDR, &if_hwaddr) < 0) {
 					int saved_errno = errno;
 					fprintf(stderr, "SIOCSIFHWADDR on %s failed: %s\n", if_hwaddr.ifr_name,
-							strerror(saved_errno));
+						strerror(saved_errno));
 					if (saved_errno == EBUSY)
 						fprintf(stderr, "  The slave device %s is busy: it must be"
-								" idle before running this command.\n", slave_ifname);
+							" idle before running this command.\n", slave_ifname);
 					else if (saved_errno == EOPNOTSUPP)
 						fprintf(stderr, "  The slave device you specified does not support"
-								" setting the MAC address.\n  Your kernel likely does not"
-								" support slave devices.\n");
+							" setting the MAC address.\n  Your kernel likely does not"
+							" support slave devices.\n");
 					else if (saved_errno == EINVAL)
 						fprintf(stderr, "  The slave device's address type does not match"
-								" the master's address type.\n");
+							" the master's address type.\n");
 				} else {
 					if (verbose) {
 						unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data;
@@ -424,10 +498,11 @@
 					}
 				}
 			}
-	
+
 			if (*spp  &&  !strcmp(*spp, "metric")) {
 				if (*++spp == NULL) {
 					fprintf(stderr, usage_msg);
+					(void) close(skfd);
 					exit(2);
 				}
 				if_metric.ifr_metric = atoi(*spp);
@@ -439,7 +514,7 @@
 				}
 				spp++;
 			}
-	
+
 			if (strncpy(if_ipaddr.ifr_name, slave_ifname, IFNAMSIZ) <= 0
 				|| ioctl(skfd, SIOCSIFADDR, &if_ipaddr) < 0) {
 				fprintf(stderr,
@@ -452,16 +527,16 @@
 						   slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
 				}
 			}
-	
+
 			if (strncpy(if_mtu.ifr_name, slave_ifname, IFNAMSIZ) <= 0
-				|| ioctl(skfd, SIOCSIFMTU, &if_mtu) < 0) { 
+				|| ioctl(skfd, SIOCSIFMTU, &if_mtu) < 0) {
 				fprintf(stderr, "Something broke setting the slave MTU: %s.\n",
 						strerror(errno));
 			} else {
 				if (verbose)
 					printf("Set the slave's (%s) MTU to %d.\n", slave_ifname, if_mtu.ifr_mtu);
 			}
-	
+
 			if (strncpy(if_dstaddr.ifr_name, slave_ifname, IFNAMSIZ) <= 0
 				|| ioctl(skfd, SIOCSIFDSTADDR, &if_dstaddr) < 0) {
 				fprintf(stderr, "Error setting the slave (%s) with SIOCSIFDSTADDR: %s.\n",
@@ -473,7 +548,7 @@
 						   slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
 				}
 			}
-	
+
 			if (strncpy(if_brdaddr.ifr_name, slave_ifname, IFNAMSIZ) <= 0
 				|| ioctl(skfd, SIOCSIFBRDADDR, &if_brdaddr) < 0) {
 				fprintf(stderr,
@@ -486,7 +561,7 @@
 						   slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
 				}
 			}
-			
+
 			if (strncpy(if_netmask.ifr_name, slave_ifname, IFNAMSIZ) <= 0
 				|| ioctl(skfd, SIOCSIFNETMASK, &if_netmask) < 0) {
 				fprintf(stderr,
@@ -499,34 +574,45 @@
 						   slave_ifname, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
 				}
 			}
-			
-			ifr2.ifr_flags |= IFF_UP; /* the interface will need to be up to be bonded */
-			if ((ifr2.ifr_flags &= ~(IFF_SLAVE | IFF_MASTER)) == 0
-				|| strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ) <= 0
-				|| ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
-				fprintf(stderr,
-						"Something broke setting the slave (%s) flags: %s.\n",
-						slave_ifname, strerror(errno));
+
+			if (abi_ver < 1) {
+
+			      	/* The driver is using an old ABI, so we'll set the interface
+				 * up before enslaving it
+				 */
+				ifr2.ifr_flags |= IFF_UP;
+				if ((ifr2.ifr_flags &= ~(IFF_SLAVE | IFF_MASTER)) == 0
+					|| strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ) <= 0
+					|| ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
+						fprintf(stderr,
+							"Something broke setting the slave (%s) flags: %s.\n",
+							slave_ifname, strerror(errno));
+				} else {
+					if (verbose)
+						printf("Set the slave's (%s) flags %4.4x.\n",
+							slave_ifname, if_flags.ifr_flags);
+				}
 			} else {
-				if (verbose)
-					printf("Set the slave's (%s) flags %4.4x.\n", slave_ifname, if_flags.ifr_flags);
+				/* the bonding module takes care of setting the slave's mac address
+			 	 * and opening its interface
+			 	 */
+				if (ifr2.ifr_flags & IFF_UP) { /* the interface will need to be down */
+					ifr2.ifr_flags &= ~IFF_UP;
+					if (ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
+						int saved_errno = errno;
+						fprintf(stderr, "Shutting down interface %s failed: %s\n",
+							slave_ifname, strerror(saved_errno));
+					}
+				}
 			}
-	
+
 			/* Do the real thing */
-			if ( ! opt_r) {
+			if (!opt_r) {
 				strncpy(if_flags.ifr_name, master_ifname, IFNAMSIZ);
 				strncpy(if_flags.ifr_slave, slave_ifname, IFNAMSIZ);
-				if (!opt_c) {
-					if ((ioctl(skfd, SIOCBONDENSLAVE, &if_flags) < 0) &&
-					    (ioctl(skfd, BOND_ENSLAVE_OLD, &if_flags) < 0)) {
-						fprintf(stderr,	"SIOCBONDENSLAVE: %s.\n", strerror(errno));
-					}
-				}
-				else {
-					if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &if_flags) < 0) &&
-					    (ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &if_flags) < 0)) {
-						fprintf(stderr,	"SIOCBONDCHANGEACTIVE: %s.\n", strerror(errno));
-					}
+				if ((ioctl(skfd, SIOCBONDENSLAVE, &if_flags) < 0) &&
+				    (ioctl(skfd, BOND_ENSLAVE_OLD, &if_flags) < 0)) {
+					fprintf(stderr,	"SIOCBONDENSLAVE: %s.\n", strerror(errno));
 				}
 			}
 		}
@@ -639,7 +725,38 @@
 	}
 }
 
-
+static int get_abi_ver(char *master_ifname)
+{
+	struct ifreq ifr;
+	struct ethtool_drvinfo info;
+	int abi_ver = 0;
+
+	memset(&ifr, 0, sizeof(ifr));
+	strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);
+	ifr.ifr_data = (caddr_t)&info;
+
+	info.cmd = ETHTOOL_GDRVINFO;
+	strncpy(info.driver, "ifenslave", 32);
+	snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION);
+	if (ioctl(skfd, SIOCETHTOOL, &ifr) >= 0) {
+		char *endptr;
+
+		abi_ver = strtoul(info.fw_version, &endptr, 0);
+		if (*endptr) {
+			fprintf(stderr, "Error: got invalid string as an ABI "
+				"version from the bonding module\n");
+			return -1;
+		}
+	}
+
+	if (verbose) {
+        	printf("ABI ver is %d\n", abi_ver);
+	}
+	return abi_ver;
+}
+
+
+
 /*
  * Local variables:
  *  version-control: t
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/nmi_watchdog.txt linux-2.4.22-pre10/Documentation/nmi_watchdog.txt
--- linux-2.4.21/Documentation/nmi_watchdog.txt	2001-09-18 06:03:09.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/nmi_watchdog.txt	2003-08-01 13:31:49.000000000 +0000
@@ -1,16 +1,38 @@
 
-Is your ix86 system locking up unpredictably? No keyboard activity, just
+[NMI watchdog is available for x86 and x86-64 architectures]
+
+Is your system locking up unpredictably? No keyboard activity, just
 a frustrating complete hard lockup? Do you want to help us debugging
 such lockups? If all yes then this document is definitely for you.
 
-On Intel and similar ix86 type hardware there is a feature that enables
+On many x86/x86-64 type hardware there is a feature that enables
 us to generate 'watchdog NMI interrupts'.  (NMI: Non Maskable Interrupt
 which get executed even if the system is otherwise locked up hard).
 This can be used to debug hard kernel lockups.  By executing periodic
 NMI interrupts, the kernel can monitor whether any CPU has locked up,
-and print out debugging messages if so.  You must enable the NMI
-watchdog at boot time with the 'nmi_watchdog=n' boot parameter.  Eg.
-the relevant lilo.conf entry:
+and print out debugging messages if so.  
+
+In order to use the NMI watchdoc, you need to have APIC support in your
+kernel. For SMP kernels, APIC support gets compiled in automatically. For
+UP, enable either CONFIG_X86_UP_APIC (Processor type and features -> Local
+APIC support on uniprocessors) or CONFIG_X86_UP_IOAPIC (Processor type and
+features -> IO-APIC support on uniprocessors) in your kernel config.
+CONFIG_X86_UP_APIC is for uniprocessor machines without an IO-APIC.
+CONFIG_X86_UP_IOAPIC is for uniprocessor with an IO-APIC. [Note: certain
+kernel debugging options, such as Kernel Stack Meter or Kernel Tracer,
+may implicitly disable the NMI watchdog.]
+
+For x86-64, the needed APIC is always compiled in, and the NMI watchdog is
+always enabled with I/O-APIC mode (nmi_watchdog=1). Currently, local APIC
+mode (nmi_watchdog=2) does not work on x86-64.
+
+Using local APIC (nmi_watchdog=2) needs the first performance register, so
+you can't use it for other purposes (such as high precision performance
+profiling.) However, at least oprofile and the perfctr driver disable the
+local APIC NMI watchdog automatically.
+
+To actually enable the NMI watchdog, use the 'nmi_watchdog=N' boot
+parameter.  Eg. the relevant lilo.conf entry:
 
         append="nmi_watchdog=1"
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/pci.txt linux-2.4.22-pre10/Documentation/pci.txt
--- linux-2.4.21/Documentation/pci.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/pci.txt	2003-08-01 13:33:13.000000000 +0000
@@ -51,21 +51,24 @@
 			execution of pci_register_driver for already existing
 			devices or later if a new device gets inserted) for all
 			PCI devices which match the ID table and are not handled
-			by the other drivers yet. This function gets passed a pointer
-			to the pci_dev structure representing the device and also
-			which entry in the ID table did the device match. It returns
-			zero when the driver has accepted the device or an error
-			code (negative number) otherwise. This function always gets
-			called from process context, so it can sleep.
-	remove		Pointer to a function which gets called whenever a device
-			being handled by this driver is removed (either during
-			deregistration of the driver or when it's manually pulled
-			out of a hot-pluggable slot). This function always gets
-			called from process context, so it can sleep.
+			by the other drivers yet. This function gets passed a
+			pointer to the pci_dev structure representing the device
+			and also which entry in the ID table did the device
+			match. It returns zero when the driver has accepted the
+			device or an error code (negative number) otherwise.
+			This function always gets called from process context,
+			so it can sleep.
+	remove		Pointer to a function which gets called whenever a
+			device being handled by this driver is removed (either
+			during deregistration of the driver or when it's
+			manually pulled out of a hot-pluggable slot). This
+			function always gets called from process context, so it
+			can sleep.
 	save_state	Save a device's state before it's suspend.
 	suspend		Put device into low power state.
 	resume		Wake device from low power state.
-	enable_wake	Enable device to generate wake events from a low power state.
+	enable_wake	Enable device to generate wake events from a low power
+			state.
 
 			(Please see Documentation/power/pci.txt for descriptions
 			of PCI Power Management and the related functions)
@@ -186,8 +189,9 @@
 
    See Documentation/IO-mapping.txt for how to access device memory.
 
-   You still need to call request_region() for I/O regions and request_mem_region()
-for memory regions to make sure nobody else is using the same device.
+   You still need to call request_region() for I/O regions and
+request_mem_region() for memory regions to make sure nobody else is using the
+same device.
 
    All interrupt handlers should be registered with SA_SHIRQ and use the devid
 to map IRQs to devices (remember that all PCI interrupts are shared).
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/power/pci.txt linux-2.4.22-pre10/Documentation/power/pci.txt
--- linux-2.4.21/Documentation/power/pci.txt	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/power/pci.txt	2003-08-01 13:34:21.000000000 +0000
@@ -22,7 +22,7 @@
 power management operations.
 
 Implementation of the PCI PM Spec is optional, as are several sub-components of
-it. If a device supports the PCI PM Spec, the device will have an 8 byte 
+it. If a device supports the PCI PM Spec, the device will have an 8 byte
 capability field in its PCI configuration space. This field is used to describe
 and control the standard PCI power management features.
 
@@ -50,33 +50,35 @@
 | D1, D2, D3    | D0        |
 +---------------------------+
 
-Note that when the system is entering a global suspend state, all devices will be 
-placed into D3 and when resuming, all devices will be placed into D0. However, 
-when the system is running, other state transitions are possible.
+Note that when the system is entering a global suspend state, all devices will
+be placed into D3 and when resuming, all devices will be placed into D0.
+However, when the system is running, other state transitions are possible.
 
 2. How The PCI Subsystem Handles Power Management
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The PCI suspend/resume functionality is accessed indirectly via the Power Management 
-subsystem. At boot, the PCI driver registers a power management callback with that layer.
-Upon entering a suspend state, the PM layer iterates through all of its registered 
-callbacks. This currently takes place only during APM state transitions.
-
-Upon going to sleep, the PCI subsystem walks its device tree twice. Both times, it does
-a depth first walk of the device tree. The first walk saves each of the device's state 
-and checks for devices that will prevent the system from entering a global power state. 
-The next walk then places the devices in a low power state.
-
-The first walk allows a graceful recovery in the event of a failure, since none of the 
-devices have actually been powered down.
-
-In both walks, in particular the second, all children of a bridge are touched before the
-actual bridge itself. This allows the bridge to retain power while its children are being
-accessed.
-
-Upon resuming from sleep, just the opposite must be true: all bridges must be powered on
-and restored before their children are powered on. This is easily accomplished with a
-breadth-first walk of the PCI device tree.
+The PCI suspend/resume functionality is accessed indirectly via the Power
+Management subsystem. At boot, the PCI driver registers a power management
+callback with that layer. Upon entering a suspend state, the PM layer iterates
+through all of its registered callbacks. This currently takes place only during
+APM state transitions.
+
+Upon going to sleep, the PCI subsystem walks its device tree twice. Both times,
+it does a depth first walk of the device tree. The first walk saves each of the
+device's state and checks for devices that will prevent the system from entering
+a global power state. The next walk then places the devices in a low power
+state.
+
+The first walk allows a graceful recovery in the event of a failure, since none
+of the devices have actually been powered down.
+
+In both walks, in particular the second, all children of a bridge are touched
+before the actual bridge itself. This allows the bridge to retain power while
+its children are being accessed.
+
+Upon resuming from sleep, just the opposite must be true: all bridges must be
+powered on and restored before their children are powered on. This is easily
+accomplished with a breadth-first walk of the PCI device tree.
 
 
 3. PCI Utility Functions
@@ -86,8 +88,8 @@
 Assuming that a device behaves as advertised, these should be applicable in most
 cases. However, results may vary.
 
-Note that these functions are never implicitly called for the driver. The driver is always
-responsible for deciding when and if to call these.
+Note that these functions are never implicitly called for the driver. The driver
+is always responsible for deciding when and if to call these.
 
 
 pci_save_state
@@ -97,7 +99,8 @@
 	pci_save_state(dev, buffer);
 
 Description:
-	Save first 64 bytes of PCI config space. Buffer must be allocated by caller.
+	Save first 64 bytes of PCI config space. Buffer must be allocated by
+	caller.
 
 
 pci_restore_state
@@ -109,8 +112,8 @@
 Description:
 	Restore previously saved config space. (First 64 bytes only);
 
-	If buffer is NULL, then restore what information we know about the device
-	from bootup: BARs and interrupt line.
+	If buffer is NULL, then restore what information we know about the
+	device from bootup: BARs and interrupt line.
 
 
 pci_set_power_state
@@ -120,7 +123,8 @@
 	pci_set_power_state(dev, state);
 
 Description:
-	Transition device to low power state using PCI PM Capabilities registers.
+	Transition device to low power state using PCI PM Capabilities
+	registers.
 
 	Will fail under one of the following conditions:
 	- If state is less than current state, but not D0 (illegal transition)
@@ -138,14 +142,15 @@
 	Enable device to generate PME# during low power state using PCI PM 
 	Capabilities.
 
-	Checks whether if device supports generating PME# from requested state and fail
-	if it does not, unless enable == 0 (request is to disable wake events, which
-	is implicit if it doesn't even support it in the first place).
-
-	Note that the PMC Register in the device's PM Capabilties has a bitmask of
-	the states it supports generating PME# from. D3hot is bit 3 and D3cold is bit
-	4. So, while a value of 4 as the state may not seem semantically correct, it
-	is. 
+	Checks whether if device supports generating PME# from requested state
+	and fail if it does not, unless enable == 0 (request is to disable wake
+	events, which is implicit if it doesn't even support it in the first
+	place).
+
+	Note that the PMC Register in the device's PM Capabilties has a bitmask
+	of the states it supports generating PME# from. D3hot is bit 3 and
+	D3cold is bit 4. So, while a value of 4 as the state may not seem
+	semantically correct, it is. 
 
 
 4. PCI Device Drivers
@@ -168,25 +173,26 @@
 if (dev->driver && dev->driver->save_state)
 	dev->driver->save_state(dev,state);
 
-The driver should use this callback to save device state. It should take into 
-account the current state of the device and the requested state in order to avoid
-any unnecessary operations.
-
-For example, a video card that supports all 4 states (D0-D3), all controller context
-is preserved when entering D1, but the screen is placed into a low power state
-(blanked). 
-
-The driver can also interpret this function as a notification that it may be entering
-a sleep state in the near future. If it knows that the device cannot enter the 
-requested state, either because of lack of support for it, or because the device is 
-middle of some critical operation, then it should fail.
-
-This function should not be used to set any state in the device or the driver because
-the device may not actually enter the sleep state (e.g. another driver later causes
-causes a global state transition to fail).
-
-Note that in intermediate low power states, a device's I/O and memory spaces may be
-disabled and may not be available in subsequent transitions to lower power states.
+The driver should use this callback to save device state. It should take into
+account the current state of the device and the requested state in order to
+avoid any unnecessary operations.
+
+For example, a video card that supports all 4 states (D0-D3), all controller
+context is preserved when entering D1, but the screen is placed into a low power
+state (blanked). 
+
+The driver can also interpret this function as a notification that it may be
+entering a sleep state in the near future. If it knows that the device cannot
+enter the requested state, either because of lack of support for it, or because
+the device is middle of some critical operation, then it should fail.
+
+This function should not be used to set any state in the device or the driver
+because the device may not actually enter the sleep state (e.g. another driver
+later causes causes a global state transition to fail).
+
+Note that in intermediate low power states, a device's I/O and memory spaces may
+be disabled and may not be available in subsequent transitions to lower power
+states.
 
 
 suspend
@@ -197,27 +203,27 @@
 if (dev->driver && dev->driver->suspend)
 	dev->driver->suspend(dev,state);
 
-A driver uses this function to actually transition the device into a low power 
-state. This may include disabling I/O, memory and bus-mastering, as well as physically
-transitioning the device to a lower power state.
+A driver uses this function to actually transition the device into a low power
+state. This may include disabling I/O, memory and bus-mastering, as well as
+physically transitioning the device to a lower power state.
 
 Bus mastering may be disabled by doing:
 
 pci_disable_device(dev);
 
-For devices that support the PCI PM Spec, this may be used to set the device's power 
-state:
+For devices that support the PCI PM Spec, this may be used to set the device's
+power state:
 
 pci_set_power_state(dev,state);
 
 The driver is also responsible for disabling any other device-specific features
 (e.g blanking screen, turning off on-card memory, etc).
 
-The driver should be sure to track the current state of the device, as it may obviate
-the need for some operations.
+The driver should be sure to track the current state of the device, as it may
+obviate the need for some operations.
 
-The driver should update the current_state field in its pci_dev structure in this 
-function.
+The driver should update the current_state field in its pci_dev structure in
+this function.
 
 resume
 ------
@@ -227,36 +233,37 @@
 if (dev->driver && dev->driver->suspend)
 	dev->driver->resume(dev)
 
-The resume callback may be called from any power state, and is always meant to 
+The resume callback may be called from any power state, and is always meant to
 transition the device to the D0 state. 
 
-The driver is responsible for reenabling any features of the device that had 
-been disabled during previous suspend calls and restoring all state that was saved
-in previous save_state calls.
-
-If the device is currently in D3, it must be completely reinitialized, as it must be
-assumed that the device has lost all of its context (even that of its PCI config 
-space). For almost all current drivers, this means that the initialization code that
-the driver does at boot must be separated out and called again from the resume
-callback. Note that some values for the device may not have to be probed for this
-time around if they are saved before entering the low power state.
+The driver is responsible for reenabling any features of the device that had
+been disabled during previous suspend calls and restoring all state that was
+saved in previous save_state calls.
+
+If the device is currently in D3, it must be completely reinitialized, as it
+must be assumed that the device has lost all of its context (even that of its
+PCI config space). For almost all current drivers, this means that the
+initialization code that the driver does at boot must be separated out and
+called again from the resume callback. Note that some values for the device may
+not have to be probed for this time around if they are saved before entering the
+low power state.
 
-If the device supports the PCI PM Spec, it can use this to physically transition the
-device to D0:
+If the device supports the PCI PM Spec, it can use this to physically transition
+the device to D0:
 
 pci_set_power_state(dev,0);
 
-Note that if the entire system is transitioning out of a global sleep state, all 
-devices will be placed in the D0 state, so this is not necessary. However, in the
-event that the device is placed in the D3 state during normal operation, this call
-is necessary. It is impossible to determine which of the two events is taking place
-in the driver, so it is always a good idea to make that call.
+Note that if the entire system is transitioning out of a global sleep state, all
+devices will be placed in the D0 state, so this is not necessary. However, in
+the event that the device is placed in the D3 state during normal operation,
+this call is necessary. It is impossible to determine which of the two events is
+taking place in the driver, so it is always a good idea to make that call.
 
-The driver should take note of the state that it is resuming from in order to ensure
-correct (and speedy) operation.
+The driver should take note of the state that it is resuming from in order to
+ensure correct (and speedy) operation.
 
-The driver should update the current_state field in its pci_dev structure in this 
-function.
+The driver should update the current_state field in its pci_dev structure in
+this function.
 
 
 enable_wake
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/s390/CommonIO linux-2.4.22-pre10/Documentation/s390/CommonIO
--- linux-2.4.21/Documentation/s390/CommonIO	2001-10-11 16:04:57.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/s390/CommonIO	2003-08-01 13:34:40.000000000 +0000
@@ -21,7 +21,8 @@
   Default is on.
 
 
-* cio_ignore = <range of device numbers>, <range of device numbers>, ...
+* cio_ignore = <device number> | <range of device numbers>, 
+	       <device number> | <range of device numbers>, ...
 
   The given device numbers will be ignored by the common I/O-layer; no detection
   and device sensing will be done on any of those devices. The subchannel to 
@@ -55,14 +56,22 @@
 
 * /proc/subchannels
 
-  Shows for each subchannel
-  - device number
-  - device type/model and if applicable control unit type/model
-  - whether the device is in use
-  - path installed mask, path available mask, path operational mask and last 
-    path used mask
-  - the channel path IDs (chpids)
+  This entry shows information on a per-subchannel basis.
 
+  The data is ordered in the following way:
+
+  - device number 
+  - subchannel number 
+  - device type/model (if applicable; if not, this is empty) and control unit 
+    type/model
+  - whether the device is in use (i. e. a device driver has requested ownership 
+    and registered an interrupt handler)
+  - path installed mask (PIM), as reflected by last store subchannel
+  - path available mask (PAM), as reflected by last store subchannel
+  - path operational mask (POM), as reflected by last store subchannel
+  - the channel path IDs (CHPIDs)
+
+  All fields are separated by spaces, the chpids are in blocks of four chpids.
 
 * /proc/deviceinfo/
 
@@ -137,3 +146,26 @@
 
   This entry counts how many times s390_process_IRQ has been called for each 
   CPU. This info is in /proc/interrupts on other architectures.
+
+* /proc/chpids
+
+  This entry will only show up if you specified CONFIG_CHSC=y during kernel
+  config.
+
+  This entry serves a dual purpose:
+ 
+  - show which chpids are currently known to Linux and their status (online,
+    logically offline),
+
+  - toggling known chpids logically online/offline.
+
+  To toggle a known chpid logically offline, do an
+	echo off <chpid> > /proc/chpids
+  <chpid> is interpreted as hex, even if you omit the '0x'.
+  The chpid will be treated by Linux as if it were not online, which can mean 
+  some devices will become unavailable.
+
+  You can toggle a logically offline chpid online again by
+	echo on <chpid> > /proc/chpids
+  If devices became unavailable by toggling the chpid logically offline, they 
+  will become available again after you toggle the chpid online again.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/s390/Debugging390.txt linux-2.4.22-pre10/Documentation/s390/Debugging390.txt
--- linux-2.4.21/Documentation/s390/Debugging390.txt	2002-02-25 19:37:51.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/s390/Debugging390.txt	2003-08-01 13:31:45.000000000 +0000
@@ -238,7 +238,7 @@
 
 On 390 our limitations & strengths make us slightly different.
 For backward compatibility ( because of the psw address hi bit which
-indicates whether we are in 31 or 64 bit mode ) we are only allowed 
+indicates whether we are in 31 or 24 bit mode ) we are only allowed 
 use 31 bits (2GB) of our 32 bit addresses. However, 
 we use entirely separate address  spaces for the user & kernel.
 
@@ -1475,6 +1475,12 @@
 D 00014CB4.20
 V00014CB4  2F646576 2F636F6E 736F6C65 00001BF5
 V00014CC4  FC00014C B4001001 E0001000 B8070707
+
+Alternatively you can do the more elegant
+D 0.20;BASE2
+BASE2 telling VM to use GPR2 as the base register.
+
+
 Now copy the text till the first 00 hex ( which is the end of the string
 to an xterm & do hex2ascii on it.
 hex2ascii 2F646576 2F636F6E 736F6C65 00 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/s390/c7000.txt linux-2.4.22-pre10/Documentation/s390/c7000.txt
--- linux-2.4.21/Documentation/s390/c7000.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/s390/c7000.txt	2003-08-01 13:33:06.000000000 +0000
@@ -0,0 +1,92 @@
+Cisco 7000 (CLAW) support
+
+The c7000 module provides support for a channel attached Cisco 7xxx
+family router on Linux/390.  The parameters for the module are as follows:
+
+	base0=0xYYYY	This parameter defines the base unit address of the
+			channel attached router.
+
+	lhost0=s1    	This parameter defines the local host name and
+			must match the claw directive "host-name" field
+			(first string).  The default value is "UTS".
+
+	uhost0=s2	This parameter defines the unit's name and must
+			match the claw directive "device-name" field
+			(second string).  The default value is "C7011".
+
+	lappl0=s3	This parameter defines the local application name
+			and must match the claw directive "host-app" field
+			(third string).  The default value is "TCPIP".
+
+	uappl0=s4	This parameter defines the unit application name and
+			must match the claw directive "device-app" field
+			(fourth string).  The default value is "TCPIP".
+
+	dbg=x		This parameter defines the message level.  Higher
+			numbers will result in additional diagnostic messages.
+			The default value is 0.
+
+	noauto=z	This parameter controls the automatic detection of
+			the unit base address (base0).  When set to a non
+			zero value, automatic detection of unit base addresses
+			is not done.  The default value is 0.
+
+Note that the values coded in strings s1 - s4 are case sensitive.
+
+For example, assume that the following claw directive has been coded in
+the Cisco router:
+
+claw 0100 6C 129.212.61.101 UTS C7011 TCPIP TCPIP
+
+The module can be loaded using the following command:
+
+insmod c7000 base0=0x336c lhost0="UTS" uhost0="C7011" lappl0="TCPIP" \
+uappl0="TCPIP" dbg=0 noauto=1
+
+Additional interfaces can be defined via parameters base1 - base3,
+lhost1 - lhost3, lappl1 - lappl3, uhost1 - uhost3, uappl1 - uappl3.
+The interfaces are named "ci0" - "ci3".  After loading the module, the
+ifconfig command is used to configure the interface.  For example:
+
+ifconfig ci0 129.212.61.101
+ifconfig ci0 netmask 255.255.255.0 broadcast 129.212.61.0
+ifconfig ci0
+
+The route command is used to specify the router as the default route:
+
+route add default gw 129.212.61.200
+
+The interface can be automatically activated at boot time by following this
+procedure:
+
+1) Add the following two lines to file "/etc/conf.modules":
+
+alias ci0 c7000
+options c7000 base0=0xYYYY lhost0=s1 uhost0=s2 lappl0=s3 uappl0=s4
+
+2) Edit file "/etc/sysconfig/network" as follows:
+
+NETWORKING=yes
+FORWARD_IPV4=no
+HOSTNAME=your-hostname
+GATEWAYDEV=ci0
+GATEWAY=your-gateway-ip-address
+
+Substitute your own host name and gateway IP address.
+
+3) Create a file in directory "/etc/sysconfig/network-scripts" called
+"ifcfg-ci0".  The contents are as follows:
+
+DEVICE=ci0
+USERCTL=no
+ONBOOT=yes
+BOOTPROTO=none
+BROADCAST=your-broadcast-ip-address
+NETWORK=your-network-address
+NETMASK=your-netmask
+IPADDR=your-ip-address
+
+Substitute your IP address, broadcast IP address, network address and
+network mask.
+
+4) chmod +x ifcfg-ci0
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/s390/cds.txt linux-2.4.22-pre10/Documentation/s390/cds.txt
--- linux-2.4.21/Documentation/s390/cds.txt	2001-03-02 19:12:06.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/s390/cds.txt	2003-08-01 13:34:18.000000000 +0000
@@ -5,12 +5,14 @@
 
 Author : Ingo Adlung
 
-Copyright, IBM Corp. 1999
+Copyright, IBM Corp. 1999-2002
+
+ChangeLog: 02/01/2002   Cornelia Huck    brought up-to-date
 
 Introduction
 
 This document describes the common device support routines for Linux/390.
-Different than other hardware architectures, ESA/390 hasdefined a unified
+Different than other hardware architectures, ESA/390 has defined a unified
 I/O access method. This gives relief to the device drivers as they don't
 have to deal with different bus types, polling versus interrupt
 processing, shared versus non-shared interrupt processing, DMA versus port
@@ -26,14 +28,11 @@
 
 In order to build common device support for ESA/390 I/O interfaces, a
 functional layer was introduced that provides generic I/O access methods to
-the hardware. The following figure shows the usage of the common device support
-of Linux/390 using a TbCP/IP driven device access an example. Similar figures
-could be drawn for other access methods, e.g. file system access to disk
-devices.
-
-The common device support layer shown above comprises the I/O support routines
-defined below. Some of them implement common Linux device driver interfaces,
-while some of them are ESA/390 platform specific.
+the hardware. 
+
+The common device support layer comprises the I/O support routines defined 
+below. Some of them implement common Linux device driver interfaces, while 
+some of them are ESA/390 platform specific.
 
 get_dev_info_by_irq() / get_dev_info_by_devno()	
    allow a device driver to determine the devices attached (visible) to the
@@ -44,10 +43,17 @@
 
 read_dev_chars()	
    read device characteristics
+   
+read_conf_data()
+   read configuration data.
 
 request_irq()	
    obtain ownership for a specific device.
 
+s390_request_irq_special()
+   obtain ownership for a specific device. Similar to request_irq(), but
+   allows for device not operational notification too.
+
 free_irq()	
    release ownership for a specific device.
 
@@ -60,6 +66,9 @@
 do_IO()	
    initiate an I/O request.
 
+resume_IO()
+   resume channel program execution.
+
 halt_IO()	
    terminate the current I/O request processed on the device.
 
@@ -70,12 +79,14 @@
    interrupt handler according to the rules (flags) defined during I/O request
    initiation with do_IO().
 
-The next chapters describe the functions, other than do_IRQ() in more details.
+The next chapters describe the functions other than do_IRQ() in more details.
 The do_IRQ() interface is not described, as it is called from the Linux/390
 first level interrupt handler only and does not comprise a device driver
 callable interface. Instead, the functional description of do_IO() also
 describes the input to the device specific interrupt handler.
 
+Note: All explanations apply also to the 64 bit architecture s390x.
+
 
 Common Device Support (CDS) for Linux/390 Device Drivers
 
@@ -90,7 +101,7 @@
 of them can be found on other Linux platforms implementations too.
 Miscellaneous function prototypes, data declarations, and macro definitions
 can be found in the architecture specific C header file
-linux/arch/s390/kernel/irq.h.
+linux/include/asm-s390/irq.h.
 
 Overview of CDS interface concepts
 
@@ -106,7 +117,7 @@
 single device is uniquely identified to the system by a so called subchannel,
 where the ESA/390 architecture allows for 64k devices be attached.
 
-Linux, however was first built on the Intel PC architecture, with its two
+Linux, however, was first built on the Intel PC architecture, with its two
 cascaded 8259 programmable interrupt controllers (PICs), that allow for a
 maximum of 15 different interrupt lines. All devices attached to such a system
 share those 15 interrupt levels. Devices attached to the ISA bus system must
@@ -117,7 +128,7 @@
 has to call every single device driver registered on this IRQ in order to
 determine the device driver owning the device that raised the interrupt.
 
-In order to not introduce a new I/O concept to the common Linux code,
+In order not to introduce a new I/O concept to the common Linux code,
 Linux/390 preserves the IRQ concept and semantically maps the ESA/390
 subchannels to Linux as IRQs. This allows Linux/390 to support up to 64k
 different IRQs, uniquely representig a single device each.
@@ -126,7 +137,7 @@
 of those devices is uniquely defined by a so called subchannel by the ESA/390
 channel subsystem. While the subchannel numbers are system generated, each
 subchannel also takes a user defined attribute, the so called device number.
-Both, subchannel number and device number can not exceed 65535. The
+Both subchannel number and device number can not exceed 65535. The
 init_IRQ() routine gathers the information about control unit type and device
 types that imply specific I/O commands (channel command words - CCWs) in
 order to operate the device. Device drivers can retrieve this set of hardware
@@ -141,7 +152,7 @@
 When a device driver has recognized a device it wants to claim ownership for,
 it calls request_irq() with the device's subchannel id serving as pseudo irq
 line. One of the required parameters it has to specify is dev_id, defining a
-device status block, the CDS layer will use to notify the device driver's
+device status block which the CDS layer will use to notify the device driver's
 interrupt handler about interrupt information observed. It depends on the
 device driver to properly handle those interrupts.
 
@@ -169,6 +180,41 @@
 
 
 
+get_irq_first() / get_irq_next() - Retrieve Information about available IRQs 
+
+A device driver can use those interface routines to retrieve information for 
+those IRQs only that have valid device information available. As 
+Linux for S/390 supports a maximum of 65535 subchannels (devices), it might 
+be a waste of CPU to scan for the max number of  devices while a fraction is 
+available/usable only. get_irq_first() will retrieve the first usable IRQ. 
+Using this as input get_irq_next() will retrieve the next IRQ available, etc..
+
+int get_irq_first( void );
+int get_irq_next( int irq );
+
+irq - defines the subchannel to start scanning with. This must be
+      a valid subchannel or an error is returned. 
+
+The get_irq_first() / get_irq_next() functions return:
+
+non-negative value - next available IRQ
+          -ENODEV  - no more IRQs available
+
+Example : 
+
+ irq = get_irq_first();
+ while ( irq != -ENODEV) 
+ {
+  get_dev_info_by_irq( irq, &dinfo);
+  if (    dinfo.devno == devno_to_look_for 
+       || dinfo.sid_data.cu_type == cu_type_to_look_for )
+  {
+   do_some_action( irq, &dinfo ); 
+  } /* endif */
+    
+  irq = get_irq_next(irq);
+ }
+
 get_dev_info_by_irq() / get_dev_info_by_devno() - Retrieve Device Information
 
 During system startup - init_IRQ() processing - the generic I/O device support
@@ -176,60 +222,69 @@
 SenseID information. For those devices supporting the command it also obtains
 extended SenseID information.
 
-int get_dev_info_by_irq( int         irq,
-                         dev_info_t *devinfo);
+int get_dev_info_by_irq( int             irq,
+                         s390_dev_info_t *pdi);
 
-int get_dev_info_by_devno( unsigned int  irq,
-                           dev_info_t   *devinfo);
+int get_dev_info_by_devno( __u16           devno,
+                           s390_dev_info_t *pdi);
 
-irq     - defines the subchannel, status information is to be
+irq     - defines the subchannel status information is to be
           returned for.
 devno   - device number.
-devinfo - pointer to a user buffer of type dev_info_t that should
+pdi     - pointer to a user buffer of type s390_dev_info_t that should
           be filled with device specific information.
 
 typedef struct {
-     unsigned int devno;     /* device number */
-     unsigned int status;    /* device status */
-     senseid_t    sid_data;  /* senseID data  */
-} dev_info_t;
+     int          irq;                  /* irq, aka. subchannel */
+     __u16        devno;                /* device number */
+     unsigned int status;               /* device status */
+     senseid_t    sid_data;             /* senseID data */
+} s390_dev_info_t;			
 
+irq       - subchannel.
 devno     - device number as configured in the IOCDS.
 status    - device status
 sid_data  - data obtained by a SenseID call
 
 Possible status values are :
 
-DEVSTAT_NOT_OPER - device was found not-operational. In this case
-                   the caller should disregard the sid_data
-                   buffer content.
+DEVSTAT_NOT_OPER -       device was found not-operational. In this case
+                         the caller should disregard the sid_data
+                         buffer content.
+DEVSTAT_UNFRIENDLY_DEV - device is locked by someone else. The sid_data buffer
+		         doesn't contain valid data.
+DEVSTAT_UNKNOWN_DEV -    The device is unknown, and the sid_data buffer doesn't
+		         contain valid data.
+DEVSTAT_DEVICE_OWNED -   An interrupt handler is registered.
 
 //
-// SenseID response buffer layout
+// sense-id response buffer layout
 //
 typedef struct {
   /* common part */
-      unsigned char  reserved;     /* always 0x'FF' */
-      unsigned short cu_type;      /* control unit type */
-      unsigned char  cu_model;     /* control unit model */
-      unsigned short dev_type;     /* device type */
-      unsigned char  dev_model;    /* device model */
-      unsigned char  unused;       /* padding byte */
+      __u8           reserved;     /* always 0x'FF' */
+      __u16          cu_type;      /* control unit type */
+      __u8           cu_model;     /* control unit model */
+      __u16          dev_type;     /* device type */
+      __u8           dev_model;    /* device model */
+      __u8           unused;       /* padding byte */
   /* extended part */
-      ciw_t    ciw[62];            /* variable # of CIWs */
-} senseid_t;
+      ciw_t    ciw[MAX_CIWS];      /* variable # of CIWs */
+}  __attribute__ ((packed,aligned(4))) senseid_t;
+
+MAX_CIWS is currently defined as 8.
 
 The ESA/390 I/O architecture defines certain device specific I/O functions.
 The device returns the device specific command code together with the SenseID
 data in so called Command Information Words (CIW) :
 
 typedef struct _ciw {
-   unsigned int et       :  2;    // entry type
-   unsigned int reserved :  2;    // reserved
-   unsigned int ct       :  4;    // command type
-   unsigned int cmd      :  8;    // command
-   unsigned int count    : 16;    // count
-} ciw_t;
+   __u32        et       :  2; // entry type
+   __u32        reserved :  2; // reserved
+   __u32        ct       :  4; // command type
+   __u32        cmd      :  8; // command
+   __u32        count    : 16; // count
+} __attribute__ ((packed)) ciw_t;
 
 Possible CIW entry types are :
 
@@ -245,6 +300,7 @@
 -ENODEV - irq or devno don't specify a known subchannel or device
           number.
 -EINVAL - invalid devinfo value.
+-EUSERS - device is locked by someone else.
 
 Usage Notes :
 
@@ -252,7 +308,7 @@
 calling     get_dev_info() until it returns -ENODEV as there aren't any more
 available devices.
 
-If a device driver wants to request ownership for a specific device it must
+If a device driver wants to request ownership for a specific device, it must
 call request_irq() prior to be able to issue any I/O request for it, including
 above mentioned   device dependent commands.
 
@@ -269,7 +325,7 @@
 numbers configured in the IOCDS. The following routines serve the purpose to
 convert irq values into device numbers and vice versa.
 
-int get_irq_by_devno( unsigned int devno );
+int get_irq_by_devno( __u16 devno );
 
 unsigned int get_devno_by_irq( int irq );
 
@@ -336,6 +392,41 @@
 he specifies, or the buffer he wants to be allocated.
 
 
+read_conf_data() - Read Configuration Data
+
+Retrieve the device dependent configuration data. Please have a look at your 
+device dependent I/O commands for the device specific layout of the node 
+descriptor elements. 
+
+The function is meant to be called without an irq handler be in place. However,
+the irq for the requested device must not be locked or this will cause a 
+deadlock situation ! 
+
+The function may be called enabled or disabled.
+
+int read_conf_data( int irq, void **buffer, int *length, __u8 lpm);
+
+irq    - Specifies the subchannel the configuration data is to be
+         retrieved for.
+buffer - Pointer to a buffer pointer. The read_conf_data() routine
+         will allocate a buffer and initialize the buffer pointer
+         accordingly. It's the device driver's responsability to
+         release the kernel memory if no longer needed. 
+length - Length of the buffer allocated and retrieved.
+lpm    - Logical path mask to be used for retrieving the data. If
+         zero the data is retrieved on the next path available.
+
+The read_conf_data() function returns :
+          0 - Successful completion
+-ENODEV     - irq doesn't specify a valid subchannel number
+-EINVAL     - An invalid parameter was detected
+-EIO        - An irrecoverable I/O error occured or the device is
+              not operational.
+-ENOMEM     - The read_conf_data() routine couldn't obtain storage.
+-EOPNOTSUPP - The device doesn't support the read configuration 
+              data command.
+
+
 request_irq() - Request Device Ownership
 
 As previously discussed a device driver will scan for the devices its supports
@@ -343,6 +434,9 @@
 request_irq() to request ownership for it. This call causes the subchannel to
 be enabled for interrupts if it was found operational.
 
+Note: This function is obsolete and provided for compatibility purposes only. 
+Device drivers should use s390_request_irq_special() instead. 
+
 int request_irq( unsigned int   irq,
                  int          (*handler)( int,
                                           void *,
@@ -354,27 +448,28 @@
 irq      : specifies the subchannel the ownership is requested for
 handler  : specifies the device driver's interrupt handler to be
            called for interrupt processing
-irqflags : IRQ flags, must be 0 (zero) or SA_SAMPLE_RANDOM
+irqflags : IRQ flags, currently ignored
 devname  : device name
 dev_id   : required pointer to a device specific buffer of type
            devstat_t
 
 typedef struct {
-     unsigned int  devno;   /* device number from irb */
-     unsigned int  intparm; /* interrupt parameter */
-     unsigned char cstat;   /* channel status - accumulated */
-     unsigned char dstat;   /* device status - accumulated */
-     unsigned char lpum;    /* last path used mask from irb */
-     unsigned char unused;  /* not used - reserved */
-     unsigned int  flag;    /* flag : see below */
-     unsigned long cpa;     /* CCW addr from irb at prim. status */
-     unsigned int  rescnt;  /* count from irb at primary status */
-     unsigned int  scnt;    /* sense count, if available */
+     __u16         devno;    /* device number, aka. "cuu" from irb */
+     unsigned long intparm;  /* interrupt parameter */
+     __u8          cstat;    /* channel status - accumulated */
+     __u8          dstat;    /* device status - accumulated */
+     __u8          lpum;     /* last path used mask from irb */
+     __u8          unused;   /* not used - reserved */
+     unsigned int  flag;     /* flag : see below */
+     __u32         cpa;      /* CCW address from irb at primary status */
+     __u32         rescnt;   /* res. count from irb at primary status */
+     __u32         scnt;     /* sense count, if DEVSTAT_FLAG_SENSE_AVAIL */
      union {
-        irb_t   irb;        /* interruption response block */
-        sense_t sense;      /* sense information */
-        } ii;               /* interrupt information */
-  } devstat_t;
+        irb_t   irb;         /* interruption response block */
+        sense_t sense;       /* sense information */
+     } ii;                /* interrupt information */
+} devstat_t;
+
 
 During request_irq() processing, the devstat_t layout does not matter as it
 won't be used during request_irq() processing. See do_IO() for a functional
@@ -396,9 +491,9 @@
 layer, and the device specific driver. The value passed to request_irq()
 must therefore point to a valid devstat_t type buffer area the device driver
 must preserve for later usage. I.e. it must not be released prior to a call
-to free_irq()
+to free_irq().
 
-The only value parameter irqflags supports is SA_SAMPLE_RANDOM if appropriate.
+Irqflags are currently ignored by the cds layer.
 The Linux/390 kernel does neither know about "fast" interrupt handlers, nor
 does it allow for interrupt sharing. Remember, the term interrupt level (irq),
 device, and subchannel are used interchangeably in Linux/390.
@@ -416,6 +511,126 @@
 therefore not rely on this parameter on function entry.
 
 
+s390_request_irq_special() - Request Device Ownership 
+
+As previously discussed a device driver will scan for the devices its supports 
+by calling get_dev_info(). Once it has found a device it will call 
+request_irq() to request ownership.
+
+Note:  This function replaces request_irq() described previously.
+
+int s390_request_irq_special( 
+                     int                      irq,
+                     io_handler_func_t        io_handler,
+                     not_oper_handler_func_t  not_oper_handler,
+                     unsigned long            irqflags,
+                     const char              *devname,
+                     void                    *dev_id);
+
+irq              : specifies the subchannel the ownership is
+                    requested for
+io_handler       : specifies the device driver's interrupt handler
+                    to be called for interrupt processing
+not_oper_handler : specifies a device driver "not operational" handler
+irqflags         : IRQ flags, currently ignored
+devname          : device name
+dev_id           : required pointer to a device specific buffer of
+                    type devstat_t
+
+
+typedef struct {
+     __u16         devno;    /* device number, aka. "cuu" from irb */
+     unsigned long intparm;  /* interrupt parameter */
+     __u8          cstat;    /* channel status - accumulated */
+     __u8          dstat;    /* device status - accumulated */
+     __u8          lpum;     /* last path used mask from irb */
+     __u8          unused;   /* not used - reserved */
+     unsigned int  flag;     /* flag : see below */
+     __u32         cpa;      /* CCW address from irb at primary status */
+     __u32         rescnt;   /* res. count from irb at primary status */
+     __u32         scnt;     /* sense count, if DEVSTAT_FLAG_SENSE_AVAIL */
+     union {
+        irb_t   irb;         /* interruption response block */
+        sense_t sense;       /* sense information */
+     } ii;                   /* interrupt information */
+} devstat_t;
+
+During request_irq() processing, the devstat_t layout does not matter as it 
+won't be used during request_irq() processing. See do_IO() for a functional 
+description of its usage.
+
+typedef  void (* io_handler_func_t) ( int             irq,
+                                      void           *devstat,
+                                      struct pt_regs *rgs);
+
+irq     : IRQ the interrupt handler is called for
+devstat : device status block
+rgs     : obsolete
+
+typedef (void)(* not_oper_handler_func_t)( int irq, 
+                                           int status );
+
+irq    : IRQ the not operational status has been encountered for
+status : device status
+         DEVSTAT_NOT_OPER    - device is not operational
+         DEVSTAT_REVALIDATE  - revalidate device number
+         DEVSTAT_DEVICE_GONE - no such device (irq)  
+
+Note: Revalidate indicates that running under VM the device number has been 
+modified by means of a DEFINE xxxx [as] yyyy command. Therewith device number 
+xxxx was altered to yyyy. It's the device drivers responsibility to decide 
+whether device ownership can be retained.
+
+Gone indicates that the device was detached under VM, or the device number 
+became invalid (native, LPAR). In order to prevent further I/O the IRQ was 
+implicitly freed on behalf of the device driver. The driver must not call 
+free_irq itself.
+
+Not Oper indicates the device became not operational. It's the device driver's 
+responsibility whether it wants to maintain ownership for the IRQ, or not. 
+
+The s390_request_irq_special() function returns :
+      0 - successful completion
+-EINVAL - an invalid parameter was detected
+-EBUSY  - device (subchannel) already owned 
+-ENODEV - the device is not-operational
+-ENOMEM - not enough kernel memory to process request
+
+Usage Notes :
+ 
+While Linux for Intel defines dev_id as a unique identifier for shared 
+interrupt lines, it has a totally different purpose on Linux for S/390. Here 
+it serves as a shared interrupt status area between the generic device support 
+layer and the device specific driver. The value passed to request_irq() must 
+therefore point to a valid devstat_t type buffer area the device driver must 
+preserve for later usage. I.e. it must not be released prior to a call to 
+free_irq().
+ 
+Currently, the value of irqflags is ignored. The Linux for S/390 kernel does 
+neither know about "fast" interrupt handlers, nor does it allow for interrupt 
+sharing. Remember, the term interrupt level (irq), device, and subchannel are 
+used interchangeably in Linux for S/390.
+ 
+Other than request_irq(), this function does allow for a not operational 
+handler to be defined. This handler is called when a device either became not 
+operational, the last path to a device became not operational, or the device 
+was detached from the system. A detach could be a "detach" under VM or that 
+the device became unassigned by the Support Element (SE) or Hardware Management 
+Console (HMC). 
+ 
+If s390_request_irq_special() was called in enabled state, or if multiple CPUs 
+are present, the device may present an interrupt to the specified handler prior 
+to request_irq() return to the caller already ! This includes the possibility 
+of unsolicited interrupts or a pending interrupt status from an earlier 
+solicited I/O request. The device driver must be able to handle this situation 
+properly or the device may become unoperational otherwise !
+
+Although the interrupt handler is defined to be called with a pointer to a 
+struct pt_regs buffer area, this is not implemented by the Linux for S/390 
+platform specific common I/O support layer. The device driver's interrupt 
+handler must therefore not rely on this parameter on function entry.
+
+
 free_irq() - Release Device Ownership
 
 A device driver may call free_irq() to release ownership of a previously
@@ -523,19 +738,19 @@
 
 int do_IO( int            irq,
            ccw1_t        *cpa,
-           unsigned long  intparm,
+           unsigned long  user_intparm,
            unsigned int   lpm,
            unsigned long  flag);
 
-irq     : irq (subchannel) the I/O request is destined for
-cpa     : logical start address of channel program
-intparm : user specific interrupt information; will be presented
-          back to the device driver's interrupt handler. Allows a
-          device driver to associate the interrupt with a
-          particular I/O request.
-lpm     : defines the channel path to be used for a specific I/O
-          request. Valid with flag value DOIO_VALID_LPM only.
-flag    : defines the action to e parformed for I/O processing
+irq          : irq (subchannel) the I/O request is destined for
+cpa          : logical start address of channel program
+user_intparm : user specific interrupt information; will be presented
+	       back to the device driver's interrupt handler. Allows a
+               device driver to associate the interrupt with a
+               particular I/O request.
+lpm          : defines the channel path to be used for a specific I/O
+               request. Valid with flag value DOIO_VALID_LPM only.
+flag         : defines the action to e parformed for I/O processing
 
 Possible flag values are :
 
@@ -543,16 +758,25 @@
 DOIO_VALID_LPM           - LPM input parameter is valid (see usage
                            notes below for details)
 DOIO_WAIT_FOR_INTERRUPT  - wait synchronously for final status
+DOIO_TIMEOUT             - perform a loop while waiting for final status
+			   and fail after a timeout
 DOIO_REPORT_ALL          - report all interrupt conditions
+DOIO_ALLOW_SUSPEND       - channel program may become suspended
+DOIO_DENY_PREFETCH       - don't allow for CCW prefetch; usually
+                           this implies the channel program might
+                           become modified 
+DOIO_CANCEL_ON_TIMEOUT   - do a cancel_IO if there is a timeout waiting
+			   for the channel program to finish (see usage
+                           notes below for details)
 
 The cpa parameter points to the first format 1 CCW of a channel program :
 
 typedef struct {
-   char            cmd_code; /* command code */
-   char            flags;    /* flags, like IDA addressing, etc. */
-   unsigned short  count;    /* byte count */
-   void           *cda;      /* data address */
-} ccw1_t __attribute__ ((aligned(8)));
+      __u8  cmd_code;/* command code */
+      __u8  flags;   /* flags, like IDA adressing, etc. */
+      __u16 count;   /* byte count */
+      __u32 cda;     /* data address */
+} __attribute__ ((packed,aligned(8))) ccw1_t;
 
 with the following CCW flags values defined :
 
@@ -605,6 +829,9 @@
                            successfully be started previously.
 DEVSTAT_FINAL_STATUS     - This is a final interrupt status for the
                            I/O requst identified by intparm.
+DEVSTAT_PCI              - A PCI was received. 
+DEVSTAT_SUSPENDED        - A "suspended" intermediate status was
+                           received.  
 
 If device status DEVSTAT_FLAG_SENSE_AVAIL is indicated in field dev_id->flag,
 field dev_id->scnt describes the numer of device specific sense bytes
@@ -612,9 +839,9 @@
 driver itself is required.
 
 typedef struct {
-   unsigned char res[32];       /* reserved   */
-   unsigned char data[32];      /* sense data */
-} sense_t;
+      __u8          res[32];   /* reserved   */
+      __u8          data[32];  /* sense data */
+   } __attribute__ ((packed)) sense_t;
 
 The device interrupt handler can use the following definitions to investigate
 the primary unit check source coded in sense byte 0 :
@@ -625,6 +852,7 @@
 SNS0_EQUIPMENT_CHECK    0x10
 SNS0_DATA_CHECK         0x08
 SNS0_OVERRUN            0x04
+SNS0_INCOMPL_DOMAIN     0x01
 
 Depending on the device status, multiple of those values may be set together.
 Please refer to the device specific documentation for details.
@@ -661,12 +889,10 @@
 
 Usage Notes :
 
-Prior to call do_IO() the device driver must
-
-assure disabled state, i.e. the I/O mask value in the PSW must be disabled.
-This can be accomplished by calling __save_flags( flags). The current PSW
-flags are preserved and can be restored by __restore_flags( flags) at a
-later time.
+Prior to call do_IO() the device driver must assure disabled state, i.e. the 
+I/O mask value in the PSW must be disabled. This can be accomplished by calling 
+__save_flags( flags). The current PSW flags are preserved and can be restored 
+by __restore_flags( flags) at a later time.
 
 If the device driver violates this rule while running in a uni-processor
 environment an interrupt might be presented prior to the do_IO() routine
@@ -674,7 +900,7 @@
 deadlock situation as the interrupt handler will try to obtain the irq
 lock the device driver still owns (see below) !
 
-the driver must assure to hold the device specific lock. This can be
+The driver must assure to hold the device specific lock. This can be
 accomplished by
 
 (i)  s390irq_spin_lock( irq), or
@@ -705,6 +931,10 @@
 is therewith primarily meant to be used during device driver initialization
 for ease of device setup.
 
+If the device driver is using the DOIO_TIMEOUT parameter, it is a good idea
+also to specify DOIO_CANCEL_ON_TIMEOUT. Otherwise, the failing channel program
+may prevent the execution of any other channel program at the subchannel.
+
 The lpm input parameter might be used for multipath devices shared among
 multiple systems as the Linux/390 CDS isn't grouping channel paths. Therefore
 its use might be required if multiple access paths to a device are available
@@ -757,6 +987,34 @@
 and dev_id->dstat that represent the accumulated subchannel and device status
 information gathered since do_IO() request initiation.
 
+Channel programs that intend to set the suspend flag on a channel command word 
+(CCW)  must start the I/O operation with the DOIO_ALLOW_SUSPEND option or the 
+suspend flag will cause a channel program check. At the time the channel program 
+becomes suspended an intermediate interrupt will be generated by the channel 
+subsystem.
+
+resume_IO() - Resume Channel Program Execution 
+
+If a device driver chooses to suspend the current channel program execution by 
+setting the CCW suspend flag on a particular CCW, the channel program execution 
+is suspended. In order to resume channel program execution the CIO layer 
+provides the resume_IO() routine. 
+
+int resume_IO( int irq);
+
+irq     : irq (subchannel) the halt operation is requested for
+
+The resume_IO() function returns:
+
+        0  - suspended channel program is resumed
+-EBUSY     - status pending
+-ENODEV    - invalid or not-operational subchannel 
+-EINVAL    - resume function not applicable  
+-ENOTCONN  - there is no I/O request pending for completion 
+
+Usage Notes:
+Please have a look at the do_IO()  usage notes for more details on suspended 
+channel programs.
 
 halt_IO() - Halt I/O Request Processing
 
@@ -765,9 +1023,9 @@
 a halt subchannel (HSCH) I/O command. For those purposes the halt_IO() command
 is provided.
 
-int halt_IO( int          irq,     /* subchannel number */
-             int          intparm, /* dummy intparm */
-             unsigned int flag);   /* operation mode */
+int halt_IO( int           irq,     /* subchannel number */
+             unsigned long intparm, /* dummy intparm */
+             unsigned long flag);   /* operation mode */
 
 irq     : irq (subchannel) the halt operation is requested for
 intparm : interruption parameter; value is only used if no I/O
@@ -867,7 +1125,7 @@
 reset_cons_dev - Reset Console Device
 
 This routine allows for resetting the console device specification. See
-set_cons_dev() for details.
+wait_cons_dev() for details.
 
 int reset_cons_dev( int irq);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/sonypi.txt linux-2.4.22-pre10/Documentation/sonypi.txt
--- linux-2.4.21/Documentation/sonypi.txt	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/sonypi.txt	2003-08-01 13:30:40.000000000 +0000
@@ -130,7 +130,7 @@
 	  tested) when using the driver with the fnkeyinit parameter. I cannot
 	  reproduce it on my laptop and not all users have this problem.
 	  This happens because the fnkeyinit parameter enables the ACPI 
-	  mode (but without additionnal ACPI control, like processor 
+	  mode (but without additional ACPI control, like processor 
 	  speed handling etc). Use ACPI instead of APM if it works on your
 	  laptop.
 	
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/sound/Introduction linux-2.4.22-pre10/Documentation/sound/Introduction
--- linux-2.4.21/Documentation/sound/Introduction	2001-02-16 23:53:08.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/sound/Introduction	2003-08-01 13:35:08.000000000 +0000
@@ -80,7 +80,7 @@
     additional features.
 
 2.  The commercial OSS driver may be obtained from the site:
-    http://www/opensound.com.  This may be used for cards that
+    http://www.opensound.com.  This may be used for cards that
     are unsupported by the kernel driver, or may be used
     by other operating systems.  
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/sound/OPL3-SA linux-2.4.22-pre10/Documentation/sound/OPL3-SA
--- linux-2.4.21/Documentation/sound/OPL3-SA	2000-03-08 19:37:03.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/sound/OPL3-SA	2003-08-01 13:33:30.000000000 +0000
@@ -34,7 +34,7 @@
 	mpu_irq: This is the MPU401's IRQ.
 
 If you'd like to use the OPL3 FM Synthesizer, make sure you enable
-CONFIG_YM3812 (in 'make config'). That'll build the opl3.o module.
+CONFIG_SOUND_YM3812 (in 'make config'). That'll build the opl3.o module.
 
 Then a simple 'insmod opl3 io=0x388', and you now have FM Synth.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/sound/VIBRA16 linux-2.4.22-pre10/Documentation/sound/VIBRA16
--- linux-2.4.21/Documentation/sound/VIBRA16	1999-03-07 23:22:06.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/sound/VIBRA16	2003-08-01 13:31:50.000000000 +0000
@@ -62,7 +62,7 @@
 
 	Or, take the hard way:
 
-insmod souncore
+insmod soundcore
 insmod sound
 insmod uart401
 insmod sb io=0x220 irq=5 dma=1 dma16=3
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/video4linux/bttv/CARDLIST linux-2.4.22-pre10/Documentation/video4linux/bttv/CARDLIST
--- linux-2.4.21/Documentation/video4linux/bttv/CARDLIST	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/video4linux/bttv/CARDLIST	2003-08-01 13:31:10.000000000 +0000
@@ -30,7 +30,7 @@
   card=28 - Terratec TerraTV+ Version 1.1 (bt878)
   card=29 - Imagenation PXC200
   card=30 - Lifeview FlyVideo 98 LR50
-  card=31 - Formac iProTV
+  card=31 - Formac iProTV, Formac ProTV I (bt848)
   card=32 - Intel Create and Share PCI/ Smart Video Recorder III
   card=33 - Terratec TerraTValue Version Bt878
   card=34 - Leadtek WinFast 2000/ WinFast 2000 XP
@@ -94,9 +94,16 @@
   card=92 - Osprey 2000
   card=93 - IDS Eagle
   card=94 - Pinnacle PCTV Sat
-  card=95 - Formac ProTV II
+  card=95 - Formac ProTV II (bt878)
   card=96 - MachTV
   card=97 - Euresys Picolo
+  card=98 - ProVideo PV150
+  card=99 - AD-TVK503
+  card=100 - Hercules Smart TV Stereo
+  card=101 - Pace TV & Radio Card
+  card=102 - IVC-200
+  card=103 - Grand X-Guard / Trust 814PCI
+  card=104 - Nebula Electronics DigiTV
 
 tuner.o
   type=0 - Temic PAL (4002 FH5)
@@ -139,3 +146,4 @@
   type=37 - LG PAL (newer TAPC series)
   type=38 - Philips PAL/SECAM multi (FM1216ME MK3)
   type=39 - LG NTSC (newer TAPC series)
+  type=40 - HITACHI V7-J180AT
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/video4linux/bttv/Sound-FAQ linux-2.4.22-pre10/Documentation/video4linux/bttv/Sound-FAQ
--- linux-2.4.21/Documentation/video4linux/bttv/Sound-FAQ	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/video4linux/bttv/Sound-FAQ	2003-08-01 13:35:08.000000000 +0000
@@ -15,18 +15,18 @@
 
 	bttv0: model: BT848(Hauppauge old) [autodetected]
 
-You should verify this is correct.  If it is'nt, you have to pass the
+You should verify this is correct.  If it isn't, you have to pass the
 correct board type as insmod argument, "insmod bttv card=2" for
 example.  The file CARDLIST has a list of valid arguments for card.
-If your card is'nt listed there, you might check the source code for
-new entries which are not listed yet.  If there is'nt one for your
+If your card isn't listed there, you might check the source code for
+new entries which are not listed yet.  If there isn't one for your
 card, you can check if one of the existing entries does work for you
 (just trial and error...).
 
 Some boards have an extra processor for sound to do stereo decoding
 and other nice features.  The msp34xx chips are used by Hauppauge for
 example.  If your board has one, you might have to load a helper
-module like msp3400.o to make sound work.  If there is'nt one for the
+module like msp3400.o to make sound work.  If there isn't one for the
 chip used on your board:  Bad luck.  Start writing a new one.  Well,
 you might want to check the video4linux mailing list archive first...
 
@@ -121,7 +121,7 @@
 video_inputs    - # of video inputs the card has
 audio_inputs    - historical cruft, not used any more.
 tuner           - which input is the tuner
-svhs            - which input is svhs (all others are labled composite)
+svhs            - which input is svhs (all others are labeled composite)
 muxsel          - video mux, input->registervalue mapping
 pll             - same as pll= insmod option
 tuner_type      - same as tuner= insmod option
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Documentation/x86_64/boot-options.txt linux-2.4.22-pre10/Documentation/x86_64/boot-options.txt
--- linux-2.4.21/Documentation/x86_64/boot-options.txt	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/Documentation/x86_64/boot-options.txt	2003-08-01 13:33:32.000000000 +0000
@@ -0,0 +1,151 @@
+AMD64 specific boot options
+
+There are many others (usually documented in driver documentation), but 
+only the AMD64 specific ones are listed here.
+
+Machine check
+
+(see the Opteron BIOS&Kernel manual for more details on the banks etc.)
+
+   mce=off disable machine check
+   mce=nok8 disable k8 specific features
+   mce=disable<NUMBER> disable bank NUMBER
+   mce=enable<NUMBER> enable bank number
+   mce=device	Enable more machine check options in Northbridge. 
+		Can be useful for device driver debugging.
+   mce=NUMBER mcheck timer interval number seconds. 
+   Can be also comma separated in a single mce=
+
+   nomce (for compatibility with i386): same as mce=off
+
+APICs
+
+   nolocalapic   Don't use a local or IO-APIC. This should only
+   		 be needed if you have a buggy BIOS. The newer
+		 kernels already turn it off by default if the
+		 BIOS didn't enable the local APIC, so it will
+		 be hopefully not needed.
+		 Note this code path is not very well tested, you are on
+		 your own.
+		
+   apic		 Use IO-APIC. Default
+
+   noapic	 Don't use the IO-APIC. 
+		 Also only lightly tested. 
+
+   pirq=...	 See Documentation/i386/IO-APIC.txt		 
+    
+Early Console
+
+   syntax: earlyprintk=vga
+           earlyprintk=serial[,ttySn[,baudrate]] 
+
+   The early console is useful when the kernel crashes before the
+   normal console is initialized. It is not enabled by 
+   default because it has some cosmetic problems.	   
+   Append ,keep to not disable it when the real console takes over.
+   Only vga or serial at a time, not both.
+   Currently only ttyS0 and ttyS1 are supported. 
+   Interaction with the standard serial driver is not very good. 
+   The VGA output is eventually overwritten by the real console.		 
+
+Timing
+
+  notsc
+  Don't use the CPU time stamp counter to read the wall time. 
+  This can be used to work around timing problems on multiprocessor systems 
+  with not properly synchronized CPUs. Only useful with a SMP kernel
+
+  report_lost_ticks
+  Report when timer interrupts are lost because some code turned off
+  interrupts for too long. 
+
+  nmi_watchdog=NUMBER
+  NUMBER can be: 
+  0 don't use an NMI watchdog
+  1 use the IO-APIC timer for the NMI watchdog
+  2 use the local APIC for the NMI watchdog using a performance counter. Note
+  This will use one performance counter.
+
+Idle loop
+
+  idle=poll
+  Don't do power saving in the idle loop using HLT, but poll for rescheduling 
+  event. This will make the CPUs eat a lot more power, but may be useful 
+  to get slightly better performance in multiprocessor benchmarks. It also
+  makes some profiling using performance counters more accurate.
+
+Rebooting
+
+   reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old]
+   bios	  Use the CPU reboto vector for warm reset
+   warm   Don't set the cold reboot flag
+   cold   Set the cold reboto flag
+   triple Force a triple fault (init)
+   kbd    Use the keyboard controller. cold reset (default)
+
+   Using warm reset will be much faster especially on big memory
+   systems because the BIOS will not go through the memory check.
+   Disadvantage is that not all hardware will be completely reinitialized
+   on reboot so there may be boot problems on some systems.
+   
+Non Executable Mappings
+
+  noexec=on|off
+
+  on      Enable
+  off     Disable
+  noforce (default) Don't enable by default for heap/stack/data,
+          but allow PROT_EXEC to be effective
+
+  noexec32=opt{,opt} 
+
+  Control the no exec default for 32bit processes. 
+  Requires noexec=on or noexec=noforce to be effective.
+
+  Valid options: 
+     all,on    Heap,stack,data is non executable. 	
+     off       (default) Heap,stack,data is executable
+     stack     Stack is non executable, heap/data is.
+     force     Don't imply PROT_EXEC for PROT_READ 
+     compat    (default) Imply PROT_EXEC for PROT_READ
+ 
+SMP 
+
+  nosmp	Only use a single CPU
+
+  maxcpus=NUMBER only use upto NUMBER CPUs
+
+  cpumask=MASK   only use cpus with bits set in mask
+
+NUMA
+
+  numa=off	Only set up a single NUMA node spanning all memory.
+
+
+ACPI 
+
+  acpi=off	Don't enable ACPI
+  
+PCI
+
+  pci=off	Don't use PCI
+  pci=conf1	Use conf1 access.
+  pci=conf2	Use conf2 access.
+  pci=rom	Assign ROMs.
+  pci=assign-busses    Assign busses
+  pci=irqmask=MASK	       Set PCI interrupt mask to MASK
+  pci=lastbus=NUMBER	       Scan upto NUMBER busses, no matter what the mptable says.
+
+IOMMU
+
+  iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]]
+   size  set size of iommu (in bytes) 
+   noagp don't initialize the AGP driver and use full aperture.
+   off   don't use the IOMMU
+   leak  turn on simple iommu leak tracing (only when CONFIG_IOMMU_LEAK is on)
+   memaper[=order] allocate an own aperture over RAM with size 32MB^order.
+   noforce don't force IOMMU usage. Should be fastest.
+   force  Force IOMMU and turn on unmap debugging.  
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/MAINTAINERS linux-2.4.22-pre10/MAINTAINERS
--- linux-2.4.21/MAINTAINERS	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/MAINTAINERS	2003-08-01 13:33:42.000000000 +0000
@@ -206,6 +206,21 @@
 L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
+ALCATEL SPEEDTOUCH USB DRIVER
+P:	Duncan Sands
+M:	duncan.sands@wanadoo.fr
+L:	linux-usb-users@lists.sourceforge.net
+L:	linux-usb-devel@lists.sourceforge.net
+W:	http://www.linux-usb.org/SpeedTouch/
+S:	Maintained
+
+AIPTEK USB TABLET DRIVER
+P:	Bryan W. Headley
+M:	Bryan W. Headley <bwheadley@earthlink.net>
+W:	http://aiptektablet.sourceforge.net
+L:	aiptektablet-users@sourceforge.net
+S:	Maintained
+
 ALTERA EPXA1/EPXA10 DEVELOPMENT BOARD PORT
 P:	Clive Davies
 M:	cdavies@altera.com
@@ -302,18 +317,78 @@
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
-BLUETOOTH SUBSYSTEM (BlueZ)
+BLUETOOTH SUBSYSTEM
 P:	Maxim Krasnyansky
 M:	maxk@qualcomm.com
 W:	http://bluez.sf.net
 S:	Maintained
 
-BLUETOOTH SUBSYSTEM (PC Card Drivers)
+BLUETOOTH RFCOMM LAYER
+P:	Maxim Krasnyansky
+M:	maxk@qualcomm.com
+W:	http://bluez.sf.net
+S:	Maintained
+
+BLUETOOTH BNEP LAYER
+P:	Maxim Krasnyansky
+M:	maxk@qualcomm.com
+W:	http://bluez.sf.net
+S:	Maintained
+
+BLUETOOTH CMTP LAYER
 P:	Marcel Holtmann
 M:	marcel@holtmann.org
 W:	http://www.holtmann.org/linux/bluetooth/
 S:	Maintained
 
+BLUETOOTH HCI USB DRIVER
+P:	Maxim Krasnyansky
+M:	maxk@qualcomm.com
+W:	http://bluez.sf.net
+S:	Maintained
+
+BLUETOOTH HCI UART DRIVER
+P:	Maxim Krasnyansky
+M:	maxk@qualcomm.com
+W:	http://bluez.sf.net
+S:	Maintained
+
+BLUETOOTH HCI BFUSB DRIVER
+P:	Marcel Holtmann
+M:	marcel@holtmann.org
+W:	http://www.holtmann.org/linux/bluetooth/
+S:	Maintained
+
+BLUETOOTH HCI DTL1 DRIVER
+P:	Marcel Holtmann
+M:	marcel@holtmann.org
+W:	http://www.holtmann.org/linux/bluetooth/
+S:	Maintained
+
+BLUETOOTH HCI BLUECARD DRIVER
+P:	Marcel Holtmann
+M:	marcel@holtmann.org
+W:	http://www.holtmann.org/linux/bluetooth/
+S:	Maintained
+
+BLUETOOTH HCI BT3C DRIVER
+P:	Marcel Holtmann
+M:	marcel@holtmann.org
+W:	http://www.holtmann.org/linux/bluetooth/
+S:	Maintained
+
+BLUETOOTH HCI BTUART DRIVER
+P:	Marcel Holtmann
+M:	marcel@holtmann.org
+W:	http://www.holtmann.org/linux/bluetooth/
+S:	Maintained
+
+BLUETOOTH HCI VHCI DRIVER
+P:	Maxim Krasnyansky
+M:	maxk@qualcomm.com
+W:	http://bluez.sf.net
+S:	Maintained
+
 BONDING DRIVER
 P:   Chad Tindel
 M:   ctindel@users.sourceforge.net
@@ -381,8 +456,8 @@
 S:     Supported
 
 COMX/MULTIGATE SYNC SERIAL DRIVERS
-P:	Gergely Madarasz
-M:	Gergely Madarasz <gorgo@itc.hu>
+P:	Pasztor Szilard
+M:	Pasztor Szilard <don@itc.hu>
 S:	Supported
 
 CONFIGURE, MENUCONFIG, XCONFIG
@@ -430,6 +505,15 @@
 W:	http://developer.axis.com
 S:	Maintained
 
+CRYPTO API
+P:	James Morris
+M:	jmorris@intercode.com.au
+P:	David S. Miller
+M:	davem@redhat.com
+W	http://samba.org/~jamesm/crypto/
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 CYBERPRO FB DRIVER
 P:	Russell King
 M:	rmk@arm.linux.org.uk
@@ -825,7 +909,7 @@
 
 IMS TWINTURBO FRAMEBUFFER DRIVER
 P:	Paul Mundt
-M:	lethal@chaoticdreams.org
+M:	lethal@linux-sh.org
 L:	linux-fbdev-devel@lists.sourceforge.net
 S:	Maintained
 
@@ -1183,6 +1267,8 @@
 M:	pekkas@netcore.fi
 P:	James Morris
 M:	jmorris@intercode.com.au
+P:	Hideaki YOSHIFUJI
+M:	yoshfuji@linux-ipv6.org
 L:	netdev@oss.sgi.com
 S:	Maintained
 
@@ -1364,9 +1450,9 @@
 P:	M. R. Brown
 M:	mrbrown@0xd6.org
 P:	Paul Mundt
-M:	lethal@0xd6.org
+M:	lethal@linux-sh.org
 L:	linux-fbdev-devel@lists.sourceforge.net
-W:	http://www.linuxdc.org
+L:	linuxsh-dev@lists.sourceforge.net
 S:	Maintained
 
 PPP PROTOCOL DRIVERS AND COMPRESSORS
@@ -1400,13 +1486,13 @@
 
 RADEON FRAMEBUFFER DISPLAY DRIVER
 P:	Ani Joshi
-M:	ajoshi@shell.unixbox.com
+M:	ajoshi@kernel.crashing.org
 L:      linux-fbdev-devel@lists.sourceforge.net
 S:      Maintained
 
 RAGE128 FRAMEBUFFER DISPLAY DRIVER
 P:	Ani Joshi
-M:	ajoshi@shell.unixbox.com
+M:	ajoshi@kernel.crashing.org
 L:	linux-fbdev-devel@lists.sourceforge.net
 S:	Maintained
 
@@ -1631,19 +1717,35 @@
 W:	http://www.stradis.com/
 S:	Maintained
 
-SUPERH
+SUPERH (sh)
+P:	Paul Mundt
+M:	lethal@linux-sh.org
 P:	Niibe Yutaka
 M:	gniibe@m17n.org
 P:	Kazumoto Kojima
 M:	kkojima@rr.iij4u.or.jp
+L:	linuxsh-dev@lists.sourceforge.net
 L:	linux-sh@m17n.org
+W:	http://www.linux-sh.org
 W:	http://www.m17n.org/linux-sh/
 W:	http://www.rr.iij4u.or.jp/~kkojima/linux-sh4.html
 S:	Maintained
 
+SUPERH64 (sh64)
+P:	Paul Mundt
+M:	lethal@linux-sh.org
+P:	Richard Curnow
+M:	richard.curnow@superh.com
+P:	Benedict Gaster
+M:	benedict.gaster@superh.com
+L:	linuxsh-shmedia-dev@lists.sourceforge.net
+W:	http://www.linux-sh.org
+W:	http://linux-shmedia.bkbits.net
+S:	Maintained
+
 SUPERH WATCHDOG
 P:	Paul Mundt
-M:	lethal@0xd6.org
+M:	lethal@linux-sh.org
 L:	linuxsh-dev@lists.sourceforge.net
 W:	http://www.linuxsh.org
 S:	Maintained
@@ -1706,6 +1808,12 @@
 W:	http://www.linuxtr.net
 S:	Maintained
 
+TOSHIBA ACPI EXTRAS DRIVER
+P:	John Belmonte
+M:	toshiba_acpi@memebeam.org
+W:	http://memebeam.org/toys/ToshibaAcpiDriver
+S:	Maintained
+
 TOSHIBA SMM DRIVER
 P:	Jonathan Buzzard
 M:	jonathan@buzzard.org.uk
@@ -1783,7 +1891,7 @@
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
-USB BLUETOOTH DRIVER
+USB BLUETOOTH TTY CONVERTER DRIVER
 P:	Greg Kroah-Hartman
 M:	greg@kroah.com
 L:	linux-usb-users@lists.sourceforge.net
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/Makefile linux-2.4.22-pre10/Makefile
--- linux-2.4.21/Makefile	2003-06-13 14:51:39.000000000 +0000
+++ linux-2.4.22-pre10/Makefile	2003-08-01 13:31:10.000000000 +0000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 21
-EXTRAVERSION =
+SUBLEVEL = 22
+EXTRAVERSION = -pre10
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -40,10 +40,13 @@
 MODFLAGS	= -DMODULE
 CFLAGS_KERNEL	=
 PERL		= perl
+AWK		= awk
+RPM 		:= $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
+		    	else echo rpm; fi)
 
 export	VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION KERNELRELEASE ARCH \
 	CONFIG_SHELL TOPDIR HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
-	CPP AR NM STRIP OBJCOPY OBJDUMP MAKE MAKEFILES GENKSYMS MODFLAGS PERL
+	CPP AR NM STRIP OBJCOPY OBJDUMP MAKE MAKEFILES GENKSYMS MODFLAGS PERL AWK
 
 all:	do-it-all
 
@@ -125,7 +128,7 @@
 NETWORKS	=net/network.o
 
 LIBS		=$(TOPDIR)/lib/lib.a
-SUBDIRS		=kernel drivers mm fs net ipc lib
+SUBDIRS		=kernel drivers mm fs net ipc lib crypto
 
 DRIVERS-n :=
 DRIVERS-y :=
@@ -190,6 +193,7 @@
 DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o
 DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o
 DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o
+DRIVERS-$(CONFIG_CRYPTO) += crypto/crypto.o
 
 DRIVERS := $(DRIVERS-y)
 
@@ -226,6 +230,7 @@
 # files removed with 'make mrproper'
 MRPROPER_FILES = \
 	include/linux/autoconf.h include/linux/version.h \
+	lib/crc32table.h lib/gen_crc32table \
 	drivers/net/hamradio/soundmodem/sm_tbl_{afsk1200,afsk2666,fsk9600}.h \
 	drivers/net/hamradio/soundmodem/sm_tbl_{hapn4800,psk4800}.h \
 	drivers/net/hamradio/soundmodem/sm_tbl_{afsk2400_7,afsk2400_8}.h \
@@ -570,5 +575,5 @@
 	rm $(KERNELPATH) ; \
 	cd $(TOPDIR) ; \
 	. scripts/mkversion > .version ; \
-	rpm -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
+	$(RPM) -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
 	rm $(TOPDIR)/../$(KERNELPATH).tar.gz
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/README linux-2.4.22-pre10/README
--- linux-2.4.21/README	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/README	2003-08-01 13:32:24.000000000 +0000
@@ -64,12 +64,12 @@
  - You can also upgrade between 2.4.xx releases by patching.  Patches are
    distributed in the traditional gzip and the new bzip2 format.  To
    install by patching, get all the newer patch files, enter the
-   directory in which you unpacked the kernel source and execute:
+   top level directory of the kernel source (linux-2.4.xx) and execute:
 
-		gzip -cd patchXX.gz | patch -p0
+               gzip -cd ../patch-2.4.xx.gz | patch -p1
 
    or
-		bzip2 -dc patchXX.bz2 | patch -p0
+               bzip2 -dc ../patch-2.4.xx.bz2 | patch -p1
 
    (repeat xx for all versions bigger than the version of your current
    source tree, _in_order_) and you should be ok.  You may want to remove
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/alpha/config.in linux-2.4.22-pre10/arch/alpha/config.in
--- linux-2.4.21/arch/alpha/config.in	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/alpha/config.in	2003-08-01 13:31:53.000000000 +0000
@@ -42,6 +42,7 @@
 	 Eiger			CONFIG_ALPHA_EIGER		\
 	 Jensen			CONFIG_ALPHA_JENSEN		\
 	 LX164			CONFIG_ALPHA_LX164		\
+	 Lynx			CONFIG_ALPHA_LYNX		\
 	 Marvel			CONFIG_ALPHA_MARVEL		\
 	 Miata			CONFIG_ALPHA_MIATA		\
 	 Mikasa			CONFIG_ALPHA_MIKASA		\
@@ -157,6 +158,16 @@
 	fi
 	define_bool CONFIG_ALPHA_T2 y
 fi
+if [ "$CONFIG_ALPHA_LYNX" = "y" ]
+then
+	bool 'EV5 CPU(s) (model 5/xxx)?' CONFIG_ALPHA_EV5
+	if [ "$CONFIG_ALPHA_EV5" != "y" ]
+	then
+		define_bool CONFIG_ALPHA_EV4 y
+	fi
+	define_bool CONFIG_ALPHA_GAMMA y
+	define_bool CONFIG_ALPHA_T2 y
+fi
 if [ "$CONFIG_ALPHA_MIATA" = "y" -o "$CONFIG_ALPHA_LX164" = "y" \
 	-o "$CONFIG_ALPHA_SX164" = "y" -o "$CONFIG_ALPHA_RUFFIAN" = "y" ]
 then
@@ -216,7 +227,7 @@
 	-o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \
 	-o "$CONFIG_ALPHA_EIGER" = "y" -o "$CONFIG_ALPHA_WILDFIRE" = "y" \
 	-o "$CONFIG_ALPHA_TITAN" = "y" -o "$CONFIG_ALPHA_SHARK" = "y" \
-	-o "$CONFIG_ALPHA_MARVEL" = "y" ]
+	-o "$CONFIG_ALPHA_MARVEL" = "y" -o "$CONFIG_ALPHA_LYNX" = "y" ]
 then
 	define_bool CONFIG_ALPHA_SRM y
 fi
@@ -234,7 +245,7 @@
 
 if [ "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \
 	-o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" \
-	-o "$CONFIG_ALPHA_RAWHIDE" = "y" ]
+	-o "$CONFIG_ALPHA_RAWHIDE" = "y" -o "$CONFIG_ALPHA_LYNX" = "y" ]
 then
 	define_bool CONFIG_ALPHA_EISA y
 fi
@@ -250,7 +261,8 @@
 if [ "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \
 	-o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_WILDFIRE" = "y" \
 	-o "$CONFIG_ALPHA_TITAN" = "y" -o "$CONFIG_ALPHA_GENERIC" = "y" \
-	-o "$CONFIG_ALPHA_SHARK" = "y" -o "$CONFIG_ALPHA_MARVEL" = "y" ]
+	-o "$CONFIG_ALPHA_SHARK" = "y" -o "$CONFIG_ALPHA_MARVEL" = "y" \
+	-o "$CONFIG_ALPHA_LYNX" = "y" ]
 then
 	bool 'Symmetric multi-processing support' CONFIG_SMP
 fi
@@ -355,7 +367,7 @@
   bool 'Network device support' CONFIG_NETDEVICES
   if [ "$CONFIG_NETDEVICES" = "y" ]; then
     source drivers/net/Config.in
-    if [ "$CONFIG_ATM" = "y" ]; then
+    if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
       source drivers/atm/Config.in
     fi
   fi
@@ -443,4 +455,5 @@
 
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/alpha/kernel/Makefile linux-2.4.22-pre10/arch/alpha/kernel/Makefile
--- linux-2.4.21/arch/alpha/kernel/Makefile	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/alpha/kernel/Makefile	2003-08-01 13:33:00.000000000 +0000
@@ -24,8 +24,7 @@
 # FIXME!
 # These should be made conditional on the stuff that needs them!
 #
-obj-y	 += irq_i8259.o irq_srm.o \
-	    es1888.o smc37c669.o smc37c93x.o ns87312.o
+obj-y	 += irq_i8259.o irq_srm.o
 
 ifdef CONFIG_VGA_HOSE
 obj-y	 += console.o
@@ -46,7 +45,8 @@
 	    sys_sable.o sys_sio.o sys_sx164.o sys_takara.o sys_rx164.o \
 	    sys_wildfire.o sys_marvel.o \
 	    err_titan.o err_marvel.o \
-	    irq_pyxis.o srmcons.o gct.o
+	    irq_pyxis.o srmcons.o gct.o \
+	    es1888.o smc37c669.o smc37c93x.o ns87312.o
 
 else
 
@@ -93,7 +93,10 @@
 obj-$(CONFIG_ALPHA_RAWHIDE) += sys_rawhide.o
 obj-$(CONFIG_ALPHA_RUFFIAN) += sys_ruffian.o
 obj-$(CONFIG_ALPHA_RX164) += sys_rx164.o
-obj-$(CONFIG_ALPHA_SABLE) += sys_sable.o
+
+ifneq ($(CONFIG_ALPHA_SABLE)$(CONFIG_ALPHA_LYNX),)
+obj-y    += sys_sable.o
+endif
 
 ifneq ($(CONFIG_ALPHA_BOOK1)$(CONFIG_ALPHA_AVANTI)$(CONFIG_ALPHA_NONAME)$(CONFIG_ALPHA_P2K)$(CONFIG_ALPHA_XL),)
 obj-y    += sys_sio.o
@@ -107,6 +110,22 @@
 obj-y    += irq_pyxis.o
 endif
 
+ifneq ($(CONFIG_ALPHA_MIATA)$(CONFIG_ALPHA_DP264),)
+obj-y    += es1888.o
+endif
+
+ifneq ($(CONFIG_ALPHA_DP264)$(CONFIG_ALPHA_MIATA)$(CONFIG_ALPHA_SX164)$(CONFIG_ALPHA_TITAN),)
+obj-y    += smc37c669.o
+endif
+
+ifneq ($(CONFIG_ALPHA_PC164)$(CONFIG_ALPHA_LX164),)
+obj-y    += smc37c93x.o
+endif
+
+ifneq ($(CONFIG_ALPHA_NONAME)$(CONFIG_ALPHA_EB164)$(CONFIG_ALPHA_AVANTI)$(CONFIG_ALPHA_P2K)$(CONFIG_ALPHA_XL)$(CONFIG_ALPHA_TAKARA),)
+obj-y    += ns87312.o
+endif
+
 endif # GENERIC
 
 all: kernel.o head.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/alpha/kernel/core_t2.c linux-2.4.22-pre10/arch/alpha/kernel/core_t2.c
--- linux-2.4.21/arch/alpha/kernel/core_t2.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/alpha/kernel/core_t2.c	2003-08-01 13:30:42.000000000 +0000
@@ -17,6 +17,7 @@
 
 #include <asm/ptrace.h>
 #include <asm/system.h>
+#include <asm/delay.h>
 
 #define __EXTERN_INLINE
 #include <asm/io.h>
@@ -26,6 +27,12 @@
 #include "proto.h"
 #include "pci_impl.h"
 
+/* For dumping initial DMA window settings. */
+#define DEBUG_PRINT_INITIAL_SETTINGS 0
+
+/* For dumping final DMA window settings. */
+#define DEBUG_PRINT_FINAL_SETTINGS 0
+
 /*
  * By default, we direct-map starting at 2GB, in order to allow the
  * maximum size direct-map window (2GB) to match the maximum amount of
@@ -34,11 +41,23 @@
  * ISA DMA, since the maximum ISA DMA address is 2GB-1.
  *
  * For now, this seems a reasonable trade-off: even though most SABLEs
- * have far less than even 1GB of memory, floppy usage/performance will
- * not really be affected by forcing it to go via scatter/gather...
+ * have less than 1GB of memory, floppy usage/performance will not
+ * really be affected by forcing it to go via scatter/gather...
  */
 #define T2_DIRECTMAP_2G 1
 
+#if T2_DIRECTMAP_2G
+# define T2_DIRECTMAP_START	0x80000000UL
+# define T2_DIRECTMAP_LENGTH	0x80000000UL
+#else
+# define T2_DIRECTMAP_START	0x40000000UL
+# define T2_DIRECTMAP_LENGTH	0x40000000UL
+#endif
+
+/* The ISA scatter/gather window settings. */
+#define T2_ISA_SG_START		0x00800000UL
+#define T2_ISA_SG_LENGTH	0x00800000UL
+
 /*
  * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
  * One plausible explanation is that the i/o controller does not properly
@@ -57,6 +76,24 @@
 # define DBG(args)
 #endif
 
+static volatile unsigned int t2_mcheck_any_expected;
+static volatile unsigned int t2_mcheck_last_taken;
+
+/* Place to save the DMA Window registers as set up by SRM
+   for restoration during shutdown. */
+static struct
+{
+	struct {
+		unsigned long wbase;
+		unsigned long wmask;
+		unsigned long tbase;
+	} window[2];
+	unsigned long hae_1;
+  	unsigned long hae_2;
+	unsigned long hae_3;
+	unsigned long hae_4;
+	unsigned long hbase;
+} t2_saved_config __attribute((common));
 
 /*
  * Given a bus, device, and function number, compute resulting
@@ -135,42 +172,34 @@
 	return 0;
 }
 
+/*
+ * NOTE: both conf_read() and conf_write() may set HAE_3 when needing
+ *       to do type1 access. This is protected by the use of spinlock IRQ
+ *       primitives in the wrapper functions pci_{read,write}_config_*()
+ *       defined in drivers/pci/pci.c.
+ */
 static unsigned int
 conf_read(unsigned long addr, unsigned char type1)
 {
-	unsigned long flags;
-	unsigned int value, cpu;
+	unsigned int value, cpu, taken;
 	unsigned long t2_cfg = 0;
 
 	cpu = smp_processor_id();
 
-	__save_and_cli(flags);	/* avoid getting hit by machine check */
-
 	DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
 
-#if 0
-	{
-	  unsigned long stat0;
-	  /* Reset status register to avoid losing errors.  */
-	  stat0 = *(vulp)T2_IOCSR;
-	  *(vulp)T2_IOCSR = stat0;
-	  mb();
-	  DBG(("conf_read: T2 IOCSR was 0x%x\n", stat0));
-	}
-#endif
-
 	/* If Type1 access, must set T2 CFG.  */
 	if (type1) {
 		t2_cfg = *(vulp)T2_HAE_3 & ~0xc0000000UL;
 		*(vulp)T2_HAE_3 = 0x40000000UL | t2_cfg;
 		mb();
-		DBG(("conf_read: TYPE1 access\n"));
 	}
 	mb();
 	draina();
 
 	mcheck_expected(cpu) = 1;
 	mcheck_taken(cpu) = 0;
+	t2_mcheck_any_expected |= (1 << cpu);
 	mb();
 
 	/* Access configuration space. */
@@ -178,12 +207,20 @@
 	mb();
 	mb();  /* magic */
 
-	if (mcheck_taken(cpu)) {
+	/* Wait for possible mcheck. Also, this lets other CPUs clear
+	   their mchecks as well, as they can reliably tell when
+	   another CPU is in the midst of handling a real mcheck via
+	   the "taken" function. */
+	udelay(100);
+
+	if ((taken = mcheck_taken(cpu))) {
 		mcheck_taken(cpu) = 0;
+		t2_mcheck_last_taken |= (1 << cpu);
 		value = 0xffffffffU;
 		mb();
 	}
 	mcheck_expected(cpu) = 0;
+	t2_mcheck_any_expected = 0;
 	mb();
 
 	/* If Type1 access, must reset T2 CFG so normal IO space ops work.  */
@@ -191,45 +228,30 @@
 		*(vulp)T2_HAE_3 = t2_cfg;
 		mb();
 	}
-	DBG(("conf_read(): finished\n"));
 
-	__restore_flags(flags);
 	return value;
 }
 
 static void
 conf_write(unsigned long addr, unsigned int value, unsigned char type1)
 {
-	unsigned long flags;
-	unsigned int cpu;
+	unsigned int cpu, taken;
 	unsigned long t2_cfg = 0;
 
 	cpu = smp_processor_id();
 
-	__save_and_cli(flags);	/* avoid getting hit by machine check */
-
-#if 0
-	{
-	  unsigned long stat0;
-	  /* Reset status register to avoid losing errors.  */
-	  stat0 = *(vulp)T2_IOCSR;
-	  *(vulp)T2_IOCSR = stat0;
-	  mb();
-	  DBG(("conf_write: T2 ERR was 0x%x\n", stat0));
-	}
-#endif
-
 	/* If Type1 access, must set T2 CFG.  */
 	if (type1) {
 		t2_cfg = *(vulp)T2_HAE_3 & ~0xc0000000UL;
 		*(vulp)T2_HAE_3 = t2_cfg | 0x40000000UL;
 		mb();
-		DBG(("conf_write: TYPE1 access\n"));
 	}
 	mb();
 	draina();
 
 	mcheck_expected(cpu) = 1;
+	mcheck_taken(cpu) = 0;
+	t2_mcheck_any_expected |= (1 << cpu);
 	mb();
 
 	/* Access configuration space.  */
@@ -237,7 +259,19 @@
 	mb();
 	mb();  /* magic */
 
+	/* Wait for possible mcheck. Also, this lets other CPUs clear
+	   their mchecks as well, as they can reliably tell when
+	   this CPU is in the midst of handling a real mcheck via
+	   the "taken" function. */
+	udelay(100);
+
+	if ((taken = mcheck_taken(cpu))) {
+		mcheck_taken(cpu) = 0;
+		t2_mcheck_last_taken |= (1 << cpu);
+		mb();
+	}
 	mcheck_expected(cpu) = 0;
+	t2_mcheck_any_expected = 0;
 	mb();
 
 	/* If Type1 access, must reset T2 CFG so normal IO space ops work.  */
@@ -245,8 +279,6 @@
 		*(vulp)T2_HAE_3 = t2_cfg;
 		mb();
 	}
-	DBG(("conf_write(): finished\n"));
-	__restore_flags(flags);
 }
 
 static int
@@ -333,48 +365,121 @@
 	write_dword:	t2_write_config_dword
 };
 
+static void __init
+t2_direct_map_window1(unsigned long base, unsigned long length)
+{
+	unsigned long temp;
+
+	__direct_map_base = base;
+	__direct_map_size = length;
+
+	temp = (base & 0xfff00000UL) | ((base + length - 1) >> 20);
+	*(vulp)T2_WBASE1 = temp | 0x80000UL; /* OR in ENABLE bit */
+	temp = (length - 1) & 0xfff00000UL;
+	*(vulp)T2_WMASK1 = temp;
+	*(vulp)T2_TBASE1 = 0;
+
+#if DEBUG_PRINT_FINAL_SETTINGS
+	printk("%s: setting WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n",
+	       __FUNCTION__,
+	       *(vulp)T2_WBASE1,
+	       *(vulp)T2_WMASK1,
+	       *(vulp)T2_TBASE1);
+#endif
+}
+
+static void __init
+t2_sg_map_window2(struct pci_controller *hose,
+		  unsigned long base,
+		  unsigned long length)
+{
+	unsigned long temp;
+
+	/* Note we can only do 1 SG window, as the other is for direct, so
+	   do an ISA SG area, especially for the floppy. */
+	hose->sg_isa = iommu_arena_new(hose, base, length, 0);
+	hose->sg_pci = NULL;
+
+	temp = (base & 0xfff00000UL) | ((base + length - 1) >> 20);
+	*(vulp)T2_WBASE2 = temp | 0xc0000UL; /* OR in ENABLE/SG bits */
+	temp = (length - 1) & 0xfff00000UL;
+	*(vulp)T2_WMASK2 = temp;
+	*(vulp)T2_TBASE2 = virt_to_phys(hose->sg_isa->ptes) >> 1;
+	mb();
+
+	t2_pci_tbi(hose, 0, -1); /* flush TLB all */
+
+#if DEBUG_PRINT_FINAL_SETTINGS
+	printk("%s: setting WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n",
+	       __FUNCTION__,
+	       *(vulp)T2_WBASE2,
+	       *(vulp)T2_WMASK2,
+	       *(vulp)T2_TBASE2);
+#endif
+}
+
+static void __init
+t2_save_configuration(void)
+{
+#if DEBUG_PRINT_INITIAL_SETTINGS
+	printk("%s: HAE_1 was 0x%lx\n", __FUNCTION__, srm_hae); /* HW is 0 */
+	printk("%s: HAE_2 was 0x%lx\n", __FUNCTION__, *(vulp)T2_HAE_2);
+	printk("%s: HAE_3 was 0x%lx\n", __FUNCTION__, *(vulp)T2_HAE_3);
+	printk("%s: HAE_4 was 0x%lx\n", __FUNCTION__, *(vulp)T2_HAE_4);
+	printk("%s: HBASE was 0x%lx\n", __FUNCTION__, *(vulp)T2_HBASE);
+
+	printk("%s: WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n", __FUNCTION__, 
+	       *(vulp)T2_WBASE1, *(vulp)T2_WMASK1, *(vulp)T2_TBASE1);
+	printk("%s: WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n", __FUNCTION__, 
+	       *(vulp)T2_WBASE2, *(vulp)T2_WMASK2, *(vulp)T2_TBASE2);
+#endif
+
+	/*
+	 * Save the DMA Window registers.
+	 */
+	t2_saved_config.window[0].wbase = *(vulp)T2_WBASE1;
+	t2_saved_config.window[0].wmask = *(vulp)T2_WMASK1;
+	t2_saved_config.window[0].tbase = *(vulp)T2_TBASE1;
+	t2_saved_config.window[1].wbase = *(vulp)T2_WBASE2;
+	t2_saved_config.window[1].wmask = *(vulp)T2_WMASK2;
+	t2_saved_config.window[1].tbase = *(vulp)T2_TBASE2;
+
+	t2_saved_config.hae_1 = srm_hae; /* HW is already set to 0 */
+	t2_saved_config.hae_2 = *(vulp)T2_HAE_2;
+	t2_saved_config.hae_3 = *(vulp)T2_HAE_3;
+	t2_saved_config.hae_4 = *(vulp)T2_HAE_4;
+	t2_saved_config.hbase = *(vulp)T2_HBASE;
+}
+
 void __init
 t2_init_arch(void)
 {
 	struct pci_controller *hose;
-	unsigned long t2_iocsr;
+	unsigned long temp;
 	unsigned int i;
 
 	for (i = 0; i < NR_CPUS; i++) {
 		mcheck_expected(i) = 0;
 		mcheck_taken(i) = 0;
 	}
-
-#if 0
-	/* Set up error reporting.  */
-	t2_iocsr = *(vulp)T2_IOCSR;
-	*(vulp)T2_IOCSR = t2_iocsr | (0x1UL << 7); /* TLB error check */
-	mb();
-	*(vulp)T2_IOCSR; /* read it back to make sure */
-#endif
+	t2_mcheck_any_expected = 0;
+	t2_mcheck_last_taken = 0;
 
 	/* Enable scatter/gather TLB use.  */
-	t2_iocsr = *(vulp)T2_IOCSR;
-	if (!(t2_iocsr & (0x1UL << 26))) {
+	temp = *(vulp)T2_IOCSR;
+	if (!(temp & (0x1UL << 26))) {
 		printk("t2_init_arch: enabling SG TLB, IOCSR was 0x%lx\n",
-		       t2_iocsr);
-		*(vulp)T2_IOCSR = t2_iocsr | (0x1UL << 26);
+		       temp);
+		*(vulp)T2_IOCSR = temp | (0x1UL << 26);
 		mb();	
 		*(vulp)T2_IOCSR; /* read it back to make sure */
 	}
 
-#if 0
-	printk("t2_init_arch: HBASE was 0x%lx\n", *(vulp)T2_HBASE);
-	printk("t2_init_arch: WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n",
-	       *(vulp)T2_WBASE1, *(vulp)T2_WMASK1, *(vulp)T2_TBASE1);
-	printk("t2_init_arch: WBASE2=0x%lx WMASK2=0x%lx TBASE2=0x%lx\n",
-	       *(vulp)T2_WBASE2, *(vulp)T2_WMASK2, *(vulp)T2_TBASE2);
-#endif
+	t2_save_configuration();
 
 	/*
 	 * Create our single hose.
 	 */
-
 	pci_isa_hose = hose = alloc_pci_controller();
 	hose->io_space = &ioport_resource;
 	hose->mem_space = &iomem_resource;
@@ -385,52 +490,58 @@
 	hose->sparse_io_base = T2_IO - IDENT_ADDR;
 	hose->dense_io_base = 0;
 
-	/* Note we can only do 1 SG window, as the other is for direct, so
-	   do an ISA SG area, especially for the floppy. */
-	hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
-	hose->sg_pci = NULL;
-
 	/*
 	 * Set up the PCI->physical memory translation windows.
 	 *
-	 * Window 1 goes at ? GB and is ?GB large, direct mapped.
-	 * Window 2 goes at 8 MB and is 8MB large, scatter/gather (for ISA).
+	 * Window 1 is direct mapped.
+	 * Window 2 is scatter/gather (for ISA).
 	 */
 
-#if T2_DIRECTMAP_2G
-	__direct_map_base = 0x80000000UL;
-	__direct_map_size = 0x80000000UL;
-
-	/* WARNING!! must correspond to the direct map window params!!! */
-	*(vulp)T2_WBASE1 = 0x80080fffU;
-	*(vulp)T2_WMASK1 = 0x7ff00000U;
-	*(vulp)T2_TBASE1 = 0;
-#else /* T2_DIRECTMAP_2G */
-	__direct_map_base = 0x40000000UL;
-	__direct_map_size = 0x40000000UL;
-
-	/* WARNING!! must correspond to the direct map window params!!! */
-	*(vulp)T2_WBASE1 = 0x400807ffU;
-	*(vulp)T2_WMASK1 = 0x3ff00000U;
-	*(vulp)T2_TBASE1 = 0;
-#endif /* T2_DIRECTMAP_2G */
+	t2_direct_map_window1(T2_DIRECTMAP_START, T2_DIRECTMAP_LENGTH);
 
-	/* WARNING!! must correspond to the SG arena/window params!!! */
-	*(vulp)T2_WBASE2 = 0x008c000fU;
-	*(vulp)T2_WMASK2 = 0x00700000U;
-	*(vulp)T2_TBASE2 = virt_to_phys(hose->sg_isa->ptes) >> 1;
+	/* Always make an ISA DMA window. */
+	t2_sg_map_window2(hose, T2_ISA_SG_START, T2_ISA_SG_LENGTH);
 
-	*(vulp)T2_HBASE = 0x0;
+	*(vulp)T2_HBASE = 0x0; /* Disable HOLES. */
 
 	/* Zero HAE.  */
-	*(vulp)T2_HAE_1 = 0; mb();
-	*(vulp)T2_HAE_2 = 0; mb();
-	*(vulp)T2_HAE_3 = 0; mb();
-#if 0
-	*(vulp)T2_HAE_4 = 0; mb(); /* DO NOT TOUCH THIS!!! */
-#endif
+	*(vulp)T2_HAE_1 = 0; mb(); /* Sparse MEM HAE */
+	*(vulp)T2_HAE_2 = 0; mb(); /* Sparse I/O HAE */
+	*(vulp)T2_HAE_3 = 0; mb(); /* Config Space HAE */
 
-	t2_pci_tbi(hose, 0, -1); /* flush TLB all */
+	/*
+	 * We also now zero out HAE_4, the dense memory HAE, so that
+	 * we need not account for its "offset" when accessing dense
+	 * memory resources which we allocated in our normal way. This
+	 * HAE would need to stay untouched were we to keep the SRM
+	 * resource settings.
+	 *
+	 * Thus we can now run standard X servers on SABLE/LYNX. :-)
+	 */
+	*(vulp)T2_HAE_4 = 0; mb();
+}
+
+void
+t2_kill_arch(int mode)
+{
+	/*
+	 * Restore the DMA Window registers.
+	 */
+	*(vulp)T2_WBASE1 = t2_saved_config.window[0].wbase;
+	*(vulp)T2_WMASK1 = t2_saved_config.window[0].wmask;
+	*(vulp)T2_TBASE1 = t2_saved_config.window[0].tbase;
+	*(vulp)T2_WBASE2 = t2_saved_config.window[1].wbase;
+	*(vulp)T2_WMASK2 = t2_saved_config.window[1].wmask;
+	*(vulp)T2_TBASE2 = t2_saved_config.window[1].tbase;
+	mb();
+
+	*(vulp)T2_HAE_1 = srm_hae;
+	*(vulp)T2_HAE_2 = t2_saved_config.hae_2;
+	*(vulp)T2_HAE_3 = t2_saved_config.hae_3;
+	*(vulp)T2_HAE_4 = t2_saved_config.hae_4;
+	*(vulp)T2_HBASE = t2_saved_config.hbase;
+	mb();
+	*(vulp)T2_HBASE; /* READ it back to ensure WRITE occurred. */
 }
 
 void
@@ -458,13 +569,7 @@
 {
 	struct sable_cpu_csr *cpu_regs;
 
-	cpu_regs = (struct sable_cpu_csr *)T2_CPU0_BASE;
-	if (cpu == 1)
-		cpu_regs = (struct sable_cpu_csr *)T2_CPU1_BASE;
-	if (cpu == 2)
-		cpu_regs = (struct sable_cpu_csr *)T2_CPU2_BASE;
-	if (cpu == 3)
-		cpu_regs = (struct sable_cpu_csr *)T2_CPU3_BASE;
+	cpu_regs = (struct sable_cpu_csr *)T2_CPUn_BASE(cpu);
 		
 	cpu_regs->sic &= ~SIC_SEIC;
 
@@ -481,19 +586,74 @@
 	mb();  /* magic */
 }
 
+/*
+ * SABLE seems to have a "broadcast" style machine check, in that all
+ * CPUs receive it. And, the issuing CPU, in the case of PCI Config
+ * space read/write faults, will also receive a second mcheck, upon
+ * lowering IPL during completion processing in pci_read_config_byte()
+ * et al.
+ *
+ * Hence all the taken/expected/any_expected/last_taken stuff...
+ */
 void
 t2_machine_check(unsigned long vector, unsigned long la_ptr,
 		 struct pt_regs * regs)
 {
 	int cpu = smp_processor_id();
+	struct el_common *mchk_header = (struct el_common *)la_ptr;
 
 	/* Clear the error before any reporting.  */
 	mb();
 	mb();  /* magic */
 	draina();
 	t2_clear_errors(cpu);
-	wrmces(rdmces()|1);	/* ??? */
-	mb();
+
+	/* This should not actually be done until the logout frame is
+	   examined, but, since we don't do that, go on and do this... */
+	wrmces(0x7);
+	mb();
+
+	/* Now, do testing for the anomalous conditions. */
+	if (!mcheck_expected(cpu) && t2_mcheck_any_expected) {
+		/*
+		 * FUNKY: Received mcheck on a CPU and not
+		 * expecting it, but another CPU is expecting one.
+		 *
+		 * Just dismiss it for now on this CPU...
+		 */
+#if DEBUG_MCHECK > 0
+		printk("t2_machine_check(cpu%d): any_expected 0x%x -"
+		       " (assumed) spurious -"
+		       " code 0x%x\n", cpu, t2_mcheck_any_expected,
+		       (unsigned int)mchk_header->code);
+#endif /* DEBUG_MCHECK */
+		return;
+	}
+
+	if (!mcheck_expected(cpu) && !t2_mcheck_any_expected) {
+		if (t2_mcheck_last_taken & (1 << cpu)) {
+#if DEBUG_MCHECK > 0
+			printk("t2_machine_check(cpu%d): last_taken 0x%x -"
+			       " unexpected mcheck -"
+			       " code 0x%x\n", cpu, t2_mcheck_last_taken,
+			       (unsigned int)mchk_header->code);
+#endif /* DEBUG_MCHECK */
+			t2_mcheck_last_taken = 0;
+			mb();
+			return;
+		} else {
+			t2_mcheck_last_taken = 0;
+			mb();
+		}
+	}
+
+#if DEBUG_MCHECK > 0
+	printk("%s t2_mcheck(cpu%d): last_taken 0x%x -"
+	       " any_expected 0x%x - code 0x%x\n",
+	       (mcheck_expected(cpu) ? "EX" : "UN"),
+	       cpu, t2_mcheck_last_taken, t2_mcheck_any_expected,
+	       (unsigned int)mchk_header->code);
+#endif /* DEBUG_MCHECK */
 
 	process_mcheck_info(vector, la_ptr, regs, "T2", mcheck_expected(cpu));
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/alpha/kernel/proto.h linux-2.4.22-pre10/arch/alpha/kernel/proto.h
--- linux-2.4.21/arch/alpha/kernel/proto.h	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/alpha/kernel/proto.h	2003-08-01 13:31:51.000000000 +0000
@@ -76,6 +76,7 @@
 /* core_t2.c */
 extern struct pci_ops t2_pci_ops;
 extern void t2_init_arch(void);
+extern void t2_kill_arch(int);
 extern void t2_machine_check(u64, u64, struct pt_regs *);
 extern void t2_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/alpha/kernel/setup.c linux-2.4.22-pre10/arch/alpha/kernel/setup.c
--- linux-2.4.21/arch/alpha/kernel/setup.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/alpha/kernel/setup.c	2003-08-01 13:31:33.000000000 +0000
@@ -154,6 +154,7 @@
 WEAK(eiger_mv);
 WEAK(jensen_mv);
 WEAK(lx164_mv);
+WEAK(lynx_mv);
 WEAK(marvel_ev7_mv);
 WEAK(miata_mv);
 WEAK(mikasa_mv);
@@ -260,7 +261,7 @@
 	unsigned long size;
 
 	size = initrd_end - initrd_start;
-	start = __alloc_bootmem(size, PAGE_SIZE, 0);
+	start = __alloc_bootmem(PAGE_ALIGN(size), PAGE_SIZE, 0);
 	if (!start || __pa(start) + size > mem_limit) {
 		initrd_start = initrd_end = 0;
 		return NULL;
@@ -720,7 +721,7 @@
 		NULL,		/* Turbolaser */
 		&avanti_mv,
 		NULL,		/* Mustang */
-		&alcor_mv,	/* Alcor, Bret, Maverick.  */
+		NULL,		/* Alcor, Bret, Maverick. HWRPB inaccurate? */
 		NULL,		/* Tradewind */
 		NULL,		/* Mikasa -- see below.  */
 		NULL,		/* EB64 */
@@ -729,7 +730,7 @@
 		&alphabook1_mv,
 		&rawhide_mv,
 		NULL,		/* K2 */
-		NULL,		/* Lynx */
+		&lynx_mv,	/* Lynx */
 		&xl_mv,
 		NULL,		/* EB164 -- see variation.  */
 		NULL,		/* Noritake -- see below.  */
@@ -915,6 +916,7 @@
 		&eiger_mv,
 		&jensen_mv,
 		&lx164_mv,
+		&lynx_mv,
 		&miata_mv,
 		&mikasa_mv,
 		&mikasa_primo_mv,
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/alpha/kernel/sys_nautilus.c linux-2.4.22-pre10/arch/alpha/kernel/sys_nautilus.c
--- linux-2.4.21/arch/alpha/kernel/sys_nautilus.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/alpha/kernel/sys_nautilus.c	2003-08-01 13:32:46.000000000 +0000
@@ -76,6 +76,9 @@
 void
 nautilus_kill_arch(int mode)
 {
+	u32 pmuport;
+	int off;
+
 	switch (mode) {
 	case LINUX_REBOOT_CMD_RESTART:
 		if (! alpha_using_srm) {
@@ -89,14 +92,18 @@
 		break;
 
 	case LINUX_REBOOT_CMD_POWER_OFF:
-		{
-			u32 pmuport;
-			pcibios_read_config_dword(0, 0x88, 0x10, &pmuport);
-			pmuport &= 0xfffe;
-			outl(0xffff, pmuport); /* clear pending events */
-			outw(0x2000, pmuport+4); /* power off */
-			/* NOTREACHED */
+		/* Assume M1543C */
+		off = 0x2000;		/* SLP_TYPE = 0, SLP_EN = 1 */
+		pcibios_read_config_dword(0, 0x88, 0x10, &pmuport);
+		if (!pmuport) {
+			/* M1535D/D+ */
+			off = 0x3400;	/* SLP_TYPE = 5, SLP_EN = 1 */
+			pcibios_read_config_dword(0, 0x88, 0xe0, &pmuport);
 		}
+		pmuport &= 0xfffe;
+		outw(0xffff, pmuport);	/* Clear pending events. */
+		outw(off, pmuport + 4);
+		/* NOTREACHED */
 		break;
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/alpha/kernel/sys_sable.c linux-2.4.22-pre10/arch/alpha/kernel/sys_sable.c
--- linux-2.4.21/arch/alpha/kernel/sys_sable.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/alpha/kernel/sys_sable.c	2003-08-01 13:31:05.000000000 +0000
@@ -5,7 +5,7 @@
  *	Copyright (C) 1996 Jay A Estabrook
  *	Copyright (C) 1998, 1999 Richard Henderson
  *
- * Code supporting the Sable and Sable-Gamma systems.
+ * Code supporting the Sable, Sable-Gamma, and Lynx systems.
  */
 
 #include <linux/config.h>
@@ -30,8 +30,28 @@
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
-spinlock_t sable_irq_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t sable_lynx_irq_lock = SPIN_LOCK_UNLOCKED;
 
+typedef struct irq_swizzle_struct
+{
+	char irq_to_mask[64];
+	char mask_to_irq[64];
+
+	/* Note mask bit is true for DISABLED irqs.  */
+	unsigned long shadow_mask;
+
+	void (*update_irq_hw)(unsigned long bit, unsigned long mask);
+	void (*ack_irq_hw)(unsigned long bit);
+
+} irq_swizzle_t;
+
+static irq_swizzle_t *sable_lynx_irq_swizzle;
+
+static void sable_lynx_init_irq(int nr_irqs);
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE)
+
+/***********************************************************************/
 /*
  *   For SABLE, which is really baroque, we manage 40 IRQ's, but the
  *   hardware really only supports 24, not via normal ISA PIC,
@@ -70,30 +90,7 @@
  *23        IIC				-
  */
 
-static struct 
-{
-	char irq_to_mask[40];
-	char mask_to_irq[40];
-
-	/* Note mask bit is true for DISABLED irqs.  */
-	unsigned long shadow_mask;
-} sable_irq_swizzle = {
-	{
-		-1,  6, -1,  8, 15, 12,  7,  9,	/* pseudo PIC  0-7  */
-		-1, 16, 17, 18,  3, -1, 21, 22,	/* pseudo PIC  8-15 */
-		-1, -1, -1, -1, -1, -1, -1, -1,	/* pseudo EISA 0-7  */
-		-1, -1, -1, -1, -1, -1, -1, -1,	/* pseudo EISA 8-15 */
-		 2,  1,  0,  4,  5, -1, -1, -1,	/* pseudo PCI */
-	},
-	{
-		34, 33, 32, 12, 35, 36,  1,  6,	/* mask 0-7  */
-		 3,  7, -1, -1,  5, -1, -1,  4,	/* mask 8-15  */
-		 9, 10, 11, -1, -1, 14, 15, -1,	/* mask 16-23  */
-	},
-	-1
-};
-
-static inline void
+static void
 sable_update_irq_hw(unsigned long bit, unsigned long mask)
 {
 	int port = 0x537;
@@ -109,7 +106,7 @@
 	outb(mask, port);
 }
 
-static inline void
+static void
 sable_ack_irq_hw(unsigned long bit)
 {
 	int port, val1, val2;
@@ -132,102 +129,46 @@
 	outb(val2, 0x534);	/* ack the master */
 }
 
-static inline void
-sable_enable_irq(unsigned int irq)
-{
-	unsigned long bit, mask;
-
-	bit = sable_irq_swizzle.irq_to_mask[irq];
-	spin_lock(&sable_irq_lock);
-	mask = sable_irq_swizzle.shadow_mask &= ~(1UL << bit);
-	sable_update_irq_hw(bit, mask);
-	spin_unlock(&sable_irq_lock);
-}
-
-static void
-sable_disable_irq(unsigned int irq)
-{
-	unsigned long bit, mask;
-
-	bit = sable_irq_swizzle.irq_to_mask[irq];
-	spin_lock(&sable_irq_lock);
-	mask = sable_irq_swizzle.shadow_mask |= 1UL << bit;
-	sable_update_irq_hw(bit, mask);
-	spin_unlock(&sable_irq_lock);
-}
-
-static unsigned int
-sable_startup_irq(unsigned int irq)
-{
-	sable_enable_irq(irq);
-	return 0;
-}
-
-static void
-sable_end_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		sable_enable_irq(irq);
-}
-
-static void
-sable_mask_and_ack_irq(unsigned int irq)
-{
-	unsigned long bit, mask;
-
-	bit = sable_irq_swizzle.irq_to_mask[irq];
-	spin_lock(&sable_irq_lock);
-	mask = sable_irq_swizzle.shadow_mask |= 1UL << bit;
-	sable_update_irq_hw(bit, mask);
-	sable_ack_irq_hw(bit);
-	spin_unlock(&sable_irq_lock);
-}
-
-static struct hw_interrupt_type sable_irq_type = {
-	typename:	"SABLE",
-	startup:	sable_startup_irq,
-	shutdown:	sable_disable_irq,
-	enable:		sable_enable_irq,
-	disable:	sable_disable_irq,
-	ack:		sable_mask_and_ack_irq,
-	end:		sable_end_irq,
+static irq_swizzle_t sable_irq_swizzle = {
+	{
+		-1,  6, -1,  8, 15, 12,  7,  9,	/* pseudo PIC  0-7  */
+		-1, 16, 17, 18,  3, -1, 21, 22,	/* pseudo PIC  8-15 */
+		-1, -1, -1, -1, -1, -1, -1, -1,	/* pseudo EISA 0-7  */
+		-1, -1, -1, -1, -1, -1, -1, -1,	/* pseudo EISA 8-15  */
+		 2,  1,  0,  4,  5, -1, -1, -1,	/* pseudo PCI */
+		-1, -1, -1, -1, -1, -1, -1, -1,	/*  */
+		-1, -1, -1, -1, -1, -1, -1, -1,	/*  */
+		-1, -1, -1, -1, -1, -1, -1, -1 	/*  */
+	},
+	{
+		34, 33, 32, 12, 35, 36,  1,  6,	/* mask 0-7  */
+		 3,  7, -1, -1,  5, -1, -1,  4,	/* mask 8-15  */
+		 9, 10, 11, -1, -1, 14, 15, -1,	/* mask 16-23  */
+		-1, -1, -1, -1, -1, -1, -1, -1,	/*  */
+		-1, -1, -1, -1, -1, -1, -1, -1,	/*  */
+		-1, -1, -1, -1, -1, -1, -1, -1,	/*  */
+		-1, -1, -1, -1, -1, -1, -1, -1,	/*  */
+		-1, -1, -1, -1, -1, -1, -1, -1	/*  */
+	},
+	-1,
+	sable_update_irq_hw,
+	sable_ack_irq_hw
 };
 
-static void 
-sable_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
-{
-	/* Note that the vector reported by the SRM PALcode corresponds
-	   to the interrupt mask bits, but we have to manage via more
-	   normal IRQs.  */
-
-	int bit, irq;
-
-	bit = (vector - 0x800) >> 4;
-	irq = sable_irq_swizzle.mask_to_irq[bit];
-	handle_irq(irq, regs);
-}
-
 static void __init
 sable_init_irq(void)
 {
-	long i;
-
 	outb(-1, 0x537);	/* slave 0 */
 	outb(-1, 0x53b);	/* slave 1 */
 	outb(-1, 0x53d);	/* slave 2 */
 	outb(0x44, 0x535);	/* enable cascades in master */
 
-	for (i = 0; i < 40; ++i) {
-		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
-		irq_desc[i].handler = &sable_irq_type;
-	}
-	
-	common_init_isa_dma();
+	sable_lynx_irq_swizzle = &sable_irq_swizzle;
+	sable_lynx_init_irq(40);
 }
 
-
 /*
- * PCI Fixup configuration for ALPHA SABLE (2100) - 2100A is different ??
+ * PCI Fixup configuration for ALPHA SABLE (2100).
  *
  * The device to slot mapping looks like:
  *
@@ -255,7 +196,7 @@
 static int __init
 sable_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-        static char irq_tab[9][5] __initdata = {
+	static char irq_tab[9][5] __initdata = {
 		/*INT    INTA   INTB   INTC   INTD */
 		{ 32+0,  32+0,  32+0,  32+0,  32+0},  /* IdSel 0,  TULIP  */
 		{ 32+1,  32+1,  32+1,  32+1,  32+1},  /* IdSel 1,  SCSI   */
@@ -265,13 +206,349 @@
 		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 5,  none   */
 		{ 32+2,  32+2,  32+2,  32+2,  32+2},  /* IdSel 6,  slot 0 */
 		{ 32+3,  32+3,  32+3,  32+3,  32+3},  /* IdSel 7,  slot 1 */
-		{ 32+4,  32+4,  32+4,  32+4,  32+4},  /* IdSel 8,  slot 2 */
-        };
+		{ 32+4,  32+4,  32+4,  32+4,  32+4}   /* IdSel 8,  slot 2 */
+	};
 	const long min_idsel = 0, max_idsel = 8, irqs_per_slot = 5;
 	return COMMON_TABLE_LOOKUP;
 }
+#endif /* defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE) */
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX)
+
+/***********************************************************************/
+/* LYNX hardware specifics
+ */
+/*
+ *   For LYNX, which is also baroque, we manage 64 IRQs, via a custom IC.
+ *
+ * Bit      Meaning               Kernel IRQ
+ *------------------------------------------
+ * 0        
+ * 1        
+ * 2        
+ * 3        mouse			12
+ * 4        
+ * 5        
+ * 6        keyboard			1
+ * 7        floppy			6
+ * 8        COM2			3
+ * 9        parallel port		7
+ *10        EISA irq 3			-
+ *11        EISA irq 4			-
+ *12        EISA irq 5			5
+ *13        EISA irq 6			-
+ *14        EISA irq 7			-
+ *15        COM1			4
+ *16        EISA irq 9			9
+ *17        EISA irq 10			10
+ *18        EISA irq 11			11
+ *19        EISA irq 12			-
+ *20        
+ *21        EISA irq 14			14
+ *22        EISA irq 15			15
+ *23        IIC				-
+ *24        VGA (builtin)               -
+ *25
+ *26
+ *27
+ *28        NCR810 (builtin)		28
+ *29
+ *30
+ *31
+ *32        PCI 0 slot 4 A primary bus  32
+ *33        PCI 0 slot 4 B primary bus  33
+ *34        PCI 0 slot 4 C primary bus  34
+ *35        PCI 0 slot 4 D primary bus
+ *36        PCI 0 slot 5 A primary bus
+ *37        PCI 0 slot 5 B primary bus
+ *38        PCI 0 slot 5 C primary bus
+ *39        PCI 0 slot 5 D primary bus
+ *40        PCI 0 slot 6 A primary bus
+ *41        PCI 0 slot 6 B primary bus
+ *42        PCI 0 slot 6 C primary bus
+ *43        PCI 0 slot 6 D primary bus
+ *44        PCI 0 slot 7 A primary bus
+ *45        PCI 0 slot 7 B primary bus
+ *46        PCI 0 slot 7 C primary bus
+ *47        PCI 0 slot 7 D primary bus
+ *48        PCI 0 slot 0 A secondary bus
+ *49        PCI 0 slot 0 B secondary bus
+ *50        PCI 0 slot 0 C secondary bus
+ *51        PCI 0 slot 0 D secondary bus
+ *52        PCI 0 slot 1 A secondary bus
+ *53        PCI 0 slot 1 B secondary bus
+ *54        PCI 0 slot 1 C secondary bus
+ *55        PCI 0 slot 1 D secondary bus
+ *56        PCI 0 slot 2 A secondary bus
+ *57        PCI 0 slot 2 B secondary bus
+ *58        PCI 0 slot 2 C secondary bus
+ *59        PCI 0 slot 2 D secondary bus
+ *60        PCI 0 slot 3 A secondary bus
+ *61        PCI 0 slot 3 B secondary bus
+ *62        PCI 0 slot 3 C secondary bus
+ *63        PCI 0 slot 3 D secondary bus
+ */
+
+static void
+lynx_update_irq_hw(unsigned long bit, unsigned long mask)
+{
+	/*
+	 * Write the AIR register on the T3/T4 with the
+	 * address of the IC mask register (offset 0x40)
+	 */
+	*(vulp)T2_AIR = 0x40;
+	mb();
+	*(vulp)T2_AIR; /* re-read to force write */
+	mb();
+	*(vulp)T2_DIR = mask;    
+	mb();
+	mb();
+}
+
+static void
+lynx_ack_irq_hw(unsigned long bit)
+{
+	*(vulp)T2_VAR = (u_long) bit;
+	mb();
+	mb();
+}
+
+static irq_swizzle_t lynx_irq_swizzle = {
+	{ /* irq_to_mask */
+		-1,  6, -1,  8, 15, 12,  7,  9,	/* pseudo PIC  0-7  */
+		-1, 16, 17, 18,  3, -1, 21, 22,	/* pseudo PIC  8-15 */
+		-1, -1, -1, -1, -1, -1, -1, -1,	/* pseudo */
+		-1, -1, -1, -1, 28, -1, -1, -1,	/* pseudo */
+		32, 33, 34, 35, 36, 37, 38, 39,	/* mask 32-39 */
+		40, 41, 42, 43, 44, 45, 46, 47,	/* mask 40-47 */
+		48, 49, 50, 51, 52, 53, 54, 55,	/* mask 48-55 */
+		56, 57, 58, 59, 60, 61, 62, 63	/* mask 56-63 */
+	},
+	{ /* mask_to_irq */
+		-1, -1, -1, 12, -1, -1,  1,  6,	/* mask 0-7   */
+		 3,  7, -1, -1,  5, -1, -1,  4,	/* mask 8-15  */
+		 9, 10, 11, -1, -1, 14, 15, -1,	/* mask 16-23 */
+		-1, -1, -1, -1, 28, -1, -1, -1,	/* mask 24-31 */
+		32, 33, 34, 35, 36, 37, 38, 39,	/* mask 32-39 */
+		40, 41, 42, 43, 44, 45, 46, 47,	/* mask 40-47 */
+		48, 49, 50, 51, 52, 53, 54, 55,	/* mask 48-55 */
+		56, 57, 58, 59, 60, 61, 62, 63	/* mask 56-63 */
+	},
+	-1,
+	lynx_update_irq_hw,
+	lynx_ack_irq_hw
+};
+
+static void __init
+lynx_init_irq(void)
+{
+	sable_lynx_irq_swizzle = &lynx_irq_swizzle;
+	sable_lynx_init_irq(64);
+}
+
+/*
+ * PCI Fixup configuration for ALPHA LYNX (2100A)
+ *
+ * The device to slot mapping looks like:
+ *
+ * Slot     Device
+ *  0       none
+ *  1       none
+ *  2       PCI-EISA bridge
+ *  3       PCI-PCI bridge
+ *  4       NCR 810 (Demi-Lynx only)
+ *  5       none
+ *  6       PCI on board slot 4
+ *  7       PCI on board slot 5
+ *  8       PCI on board slot 6
+ *  9       PCI on board slot 7
+ *
+ * And behind the PPB we have:
+ *
+ * 11       PCI on board slot 0
+ * 12       PCI on board slot 1
+ * 13       PCI on board slot 2
+ * 14       PCI on board slot 3
+ */
+/*
+ * NOTE: the IRQ assignments below are arbitrary, but need to be consistent
+ * with the values in the irq swizzling tables above.
+ */
+
+static int __init
+lynx_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	static char irq_tab[19][5] __initdata = {
+		/*INT    INTA   INTB   INTC   INTD */
+		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 13,  PCEB   */
+		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 14,  PPB    */
+		{   28,    28,    28,    28,    28},  /* IdSel 15,  NCR demi */
+		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 16,  none   */
+		{   32,    32,    33,    34,    35},  /* IdSel 17,  slot 4 */
+		{   36,    36,    37,    38,    39},  /* IdSel 18,  slot 5 */
+		{   40,    40,    41,    42,    43},  /* IdSel 19,  slot 6 */
+		{   44,    44,    45,    46,    47},  /* IdSel 20,  slot 7 */
+		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 22,  none   */
+		/* The following are actually behind the PPB. */
+		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 16   none */
+		{   28,    28,    28,    28,    28},  /* IdSel 17   NCR lynx */
+		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 18   none */
+		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 19   none */
+		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 20   none */
+		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 21   none */
+		{   48,    48,    49,    50,    51},  /* IdSel 22   slot 0 */
+		{   52,    52,    53,    54,    55},  /* IdSel 23   slot 1 */
+		{   56,    56,    57,    58,    59},  /* IdSel 24   slot 2 */
+		{   60,    60,    61,    62,    63}   /* IdSel 25   slot 3 */
+	};
+	const long min_idsel = 2, max_idsel = 20, irqs_per_slot = 5;
+	return COMMON_TABLE_LOOKUP;
+}
+
+static u8 __init
+lynx_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	int slot, pin = *pinp;
+
+	if (dev->bus->number == 0) {
+		slot = PCI_SLOT(dev->devfn);
+	}
+	/* Check for the built-in bridge */
+	else if (PCI_SLOT(dev->bus->self->devfn) == 3) {
+		slot = PCI_SLOT(dev->devfn) + 11;
+	}
+	else
+	{
+		/* Must be a card-based bridge.  */
+		do {
+			if (PCI_SLOT(dev->bus->self->devfn) == 3) {
+				slot = PCI_SLOT(dev->devfn) + 11;
+				break;
+			}
+			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)) ;
+
+			/* Move up the chain of bridges.  */
+			dev = dev->bus->self;
+			/* Slot of the next bridge.  */
+			slot = PCI_SLOT(dev->devfn);
+		} while (dev->bus->self);
+	}
+	*pinp = pin;
+	return slot;
+}
+
+#endif /* defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX) */
+
+/***********************************************************************/
+/* GENERIC irq routines */
+
+static inline void
+sable_lynx_enable_irq(unsigned int irq)
+{
+	unsigned long bit, mask;
+
+	bit = sable_lynx_irq_swizzle->irq_to_mask[irq];
+	spin_lock(&sable_lynx_irq_lock);
+	mask = sable_lynx_irq_swizzle->shadow_mask &= ~(1UL << bit);
+	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
+	spin_unlock(&sable_lynx_irq_lock);
+#if 0
+	printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n",
+	       __FUNCTION__, mask, bit, irq);
+#endif
+}
 
+static void
+sable_lynx_disable_irq(unsigned int irq)
+{
+	unsigned long bit, mask;
 
+	bit = sable_lynx_irq_swizzle->irq_to_mask[irq];
+	spin_lock(&sable_lynx_irq_lock);
+	mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit;
+	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
+	spin_unlock(&sable_lynx_irq_lock);
+#if 0
+	printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n",
+	       __FUNCTION__, mask, bit, irq);
+#endif
+}
+
+static unsigned int
+sable_lynx_startup_irq(unsigned int irq)
+{
+	sable_lynx_enable_irq(irq);
+	return 0;
+}
+
+static void
+sable_lynx_end_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		sable_lynx_enable_irq(irq);
+}
+
+static void
+sable_lynx_mask_and_ack_irq(unsigned int irq)
+{
+	unsigned long bit, mask;
+
+	bit = sable_lynx_irq_swizzle->irq_to_mask[irq];
+	spin_lock(&sable_lynx_irq_lock);
+	mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit;
+	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
+	sable_lynx_irq_swizzle->ack_irq_hw(bit);
+	spin_unlock(&sable_lynx_irq_lock);
+}
+
+static struct hw_interrupt_type sable_lynx_irq_type = {
+	typename:	"SABLE/LYNX",
+	startup:	sable_lynx_startup_irq,
+	shutdown:	sable_lynx_disable_irq,
+	enable:		sable_lynx_enable_irq,
+	disable:	sable_lynx_disable_irq,
+	ack:		sable_lynx_mask_and_ack_irq,
+	end:		sable_lynx_end_irq,
+};
+
+static void 
+sable_lynx_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+	/* Note that the vector reported by the SRM PALcode corresponds
+	   to the interrupt mask bits, but we have to manage via the
+	   so-called legacy IRQs for many common devices.  */
+
+	int bit, irq;
+
+	bit = (vector - 0x800) >> 4;
+	irq = sable_lynx_irq_swizzle->mask_to_irq[bit];
+#if 0
+	printk("%s: vector 0x%lx bit 0x%x irq 0x%x\n",
+	       __FUNCTION__, vector, bit, irq);
+#endif
+	handle_irq(irq, regs);
+}
+
+static void __init
+sable_lynx_init_irq(int nr_irqs)
+{
+	long i;
+
+	for (i = 0; i < nr_irqs; ++i) {
+		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
+		irq_desc[i].handler = &sable_lynx_irq_type;
+	}
+	
+	common_init_isa_dma();
+}
+
+static void __init
+sable_lynx_init_pci(void)
+{
+	common_init_pci();
+}
+
+/*****************************************************************/
 /*
  * The System Vectors
  *
@@ -279,7 +556,8 @@
  * these games with GAMMA_BIAS.
  */
 
-#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_GAMMA)
+#if defined(CONFIG_ALPHA_GENERIC) || \
+    (defined(CONFIG_ALPHA_SABLE) && !defined(CONFIG_ALPHA_GAMMA))
 #undef GAMMA_BIAS
 #define GAMMA_BIAS 0
 struct alpha_machine_vector sable_mv __initmv = {
@@ -294,13 +572,13 @@
 	min_mem_address:	T2_DEFAULT_MEM_BASE,
 
 	nr_irqs:		40,
-	device_interrupt:	sable_srm_device_interrupt,
+	device_interrupt:	sable_lynx_srm_device_interrupt,
 
 	init_arch:		t2_init_arch,
 	init_irq:		sable_init_irq,
 	init_rtc:		common_init_rtc,
-	init_pci:		common_init_pci,
-	kill_arch:		NULL,
+	init_pci:		sable_lynx_init_pci,
+	kill_arch:		t2_kill_arch,
 	pci_map_irq:		sable_map_irq,
 	pci_swizzle:		common_swizzle,
 
@@ -309,9 +587,10 @@
 	} }
 };
 ALIAS_MV(sable)
-#endif
+#endif /* GENERIC || (SABLE && !GAMMA) */
 
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_GAMMA)
+#if defined(CONFIG_ALPHA_GENERIC) || \
+    (defined(CONFIG_ALPHA_SABLE) && defined(CONFIG_ALPHA_GAMMA))
 #undef GAMMA_BIAS
 #define GAMMA_BIAS _GAMMA_BIAS
 struct alpha_machine_vector sable_gamma_mv __initmv = {
@@ -326,12 +605,13 @@
 	min_mem_address:	T2_DEFAULT_MEM_BASE,
 
 	nr_irqs:		40,
-	device_interrupt:	sable_srm_device_interrupt,
+	device_interrupt:	sable_lynx_srm_device_interrupt,
 
 	init_arch:		t2_init_arch,
 	init_irq:		sable_init_irq,
 	init_rtc:		common_init_rtc,
-	init_pci:		common_init_pci,
+	init_pci:		sable_lynx_init_pci,
+	kill_arch:		t2_kill_arch,
 	pci_map_irq:		sable_map_irq,
 	pci_swizzle:		common_swizzle,
 
@@ -340,4 +620,36 @@
 	} }
 };
 ALIAS_MV(sable_gamma)
-#endif
+#endif /* GENERIC || (SABLE && GAMMA) */
+
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX)
+#undef GAMMA_BIAS
+#define GAMMA_BIAS _GAMMA_BIAS
+struct alpha_machine_vector lynx_mv __initmv = {
+	vector_name:		"Lynx",
+	DO_EV4_MMU,
+	DO_DEFAULT_RTC,
+	DO_T2_IO,
+	DO_T2_BUS,
+	machine_check:		t2_machine_check,
+	max_dma_address:	ALPHA_SABLE_MAX_DMA_ADDRESS,
+	min_io_address:		EISA_DEFAULT_IO_BASE,
+	min_mem_address:	T2_DEFAULT_MEM_BASE,
+
+	nr_irqs:		64,
+	device_interrupt:	sable_lynx_srm_device_interrupt,
+
+	init_arch:		t2_init_arch,
+	init_irq:		lynx_init_irq,
+	init_rtc:		common_init_rtc,
+	init_pci:		sable_lynx_init_pci,
+	kill_arch:		t2_kill_arch,
+	pci_map_irq:		lynx_map_irq,
+	pci_swizzle:		lynx_swizzle,
+
+	sys: { t2: {
+	    gamma_bias:		_GAMMA_BIAS
+	} }
+};
+ALIAS_MV(lynx)
+#endif /* GENERIC || LYNX */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/Makefile linux-2.4.22-pre10/arch/arm/Makefile
--- linux-2.4.21/arch/arm/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/Makefile	2003-08-01 13:32:41.000000000 +0000
@@ -8,8 +8,15 @@
 # Copyright (C) 1995-2001 by Russell King
 
 LINKFLAGS	:=-p -X -T arch/arm/vmlinux.lds
+OBJCOPYFLAGS	:=-O binary -R .note -R .comment -S
 GZFLAGS		:=-9
-CFLAGS		+=-fno-common -pipe
+CFLAGS		+=-Uarm -fno-common -pipe
+
+ifeq ($(CONFIG_FRAME_POINTER),y)
+CFLAGS		:=$(CFLAGS:-fomit-frame-pointer=-mapcs -mno-sched-prolog)
+endif
+
+CFLAGS		:=$(CFLAGS:-O2=-Os)
 
 ifeq ($(CONFIG_DEBUG_INFO),y)
 CFLAGS		+=-g
@@ -24,10 +31,13 @@
 apcs-$(CONFIG_CPU_26)		:=-mapcs-26 -mcpu=arm3 -Os
 
 # This selects which instruction set is used.
+# Note that GCC is lame - it doesn't numerically define an
+# architecture version macro, but instead defines a whole
+# series of macros.
 arch-y				:=
-arch-$(CONFIG_CPU_32v3)		:=-march=armv3
-arch-$(CONFIG_CPU_32v4)		:=-march=armv4
-arch-$(CONFIG_CPU_32v5)		:=-march=armv5
+arch-$(CONFIG_CPU_32v3)		:=-D__LINUX_ARM_ARCH__=3 -march=armv3
+arch-$(CONFIG_CPU_32v4)		:=-D__LINUX_ARM_ARCH__=4 -march=armv4
+arch-$(CONFIG_CPU_32v5)		:=-D__LINUX_ARM_ARCH__=5 -march=armv5
 
 # This selects how we optimise for the processor.
 tune-y				:=
@@ -40,12 +50,12 @@
 tune-$(CONFIG_CPU_SA110)	:=-mtune=strongarm110
 tune-$(CONFIG_CPU_SA1100)	:=-mtune=strongarm1100
 
-CFLAGS_BOOT	:=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float
-CFLAGS		+=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float
+CFLAGS_BOOT	:=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
+CFLAGS		+=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
 AFLAGS		+=$(apcs-y) $(arch-y) -mno-fpu -msoft-float
 
 ifeq ($(CONFIG_CPU_26),y)
-PROCESSOR	 = armo
+PROCESSOR	:= armo
   ifeq ($(CONFIG_ROM_KERNEL),y)
     DATAADDR	 = 0x02080000
     TEXTADDR	 = 0x03800000
@@ -81,6 +91,10 @@
 INCDIR		 = cl7500
 endif
 
+ifeq ($(CONFIG_ARCH_RISCSTATION),y)
+MACHINE		 = riscstation
+endif
+
 ifeq ($(CONFIG_FOOTBRIDGE),y)
 MACHINE		 = footbridge
 INCDIR		 = ebsa285
@@ -121,12 +135,16 @@
 MACHINE		 = integrator
 endif
 
+ifeq ($(CONFIG_ARCH_AT91RM9200),y)
+MACHINE		 = at91rm9200
+endif
+
 ifeq ($(CONFIG_ARCH_MX1ADS),y)
 MACHINE		 = mx1ads
 endif
 
 ifeq ($(CONFIG_ARCH_CAMELOT),y)
-MACHINE          = epxa10db
+MACHINE          = epxa
 endif
 
 ifeq ($(CONFIG_ARCH_CLPS711X),y)
@@ -135,19 +153,23 @@
 endif
 
 ifeq ($(CONFIG_ARCH_FORTUNET),y)
-TEXTADDR	 = 0xc0008000
+TEXTADDR	 = 0xc0208000
 endif
 
 ifeq ($(CONFIG_ARCH_ANAKIN),y)
 MACHINE		 = anakin
 endif
 
-export	MACHINE PROCESSOR TEXTADDR GZFLAGS CFLAGS_BOOT
+ifeq ($(CONFIG_ARCH_OMAHA),y)
+MACHINE                = omaha
+endif
+
+export	MACHINE PROCESSOR TEXTADDR GZFLAGS CFLAGS_BOOT OBJCOPYFLAGS
 
 # Only set INCDIR if its not already defined above
 # Grr, ?= doesn't work as all the other assignment operators do.  Make bug?
 ifeq ($(origin INCDIR), undefined)
-INCDIR		:= $(MACHINE)
+INCDIR		:=$(MACHINE)
 endif
 
 ifeq ($(origin DATAADDR), undefined)
@@ -161,32 +183,42 @@
 CORE_FILES	:= $(MACHDIR)/$(MACHINE).o $(CORE_FILES)
 endif
 
-HEAD		:= arch/arm/kernel/head-$(PROCESSOR).o \
-		   arch/arm/kernel/init_task.o
-SUBDIRS		+= arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe
-CORE_FILES	:= arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
-LIBS		:= arch/arm/lib/lib.a $(LIBS)
+HEAD		:=arch/arm/kernel/head-$(PROCESSOR).o \
+		  arch/arm/kernel/init_task.o
+SUBDIRS		+=arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwfpe
+CORE_FILES	:=arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
+LIBS		:=arch/arm/lib/lib.a $(LIBS)
 
 ifeq ($(CONFIG_FPE_NWFPE),y)
-LIBS		:= arch/arm/nwfpe/math-emu.o $(LIBS)
+LIBS		:=arch/arm/nwfpe/math-emu.o $(LIBS)
 endif
 
 # Only include fastfpe if it is part of the kernel tree.
-FASTFPE		:= arch/arm/fastfpe
+FASTFPE		:=arch/arm/fastfpe
 ifeq ($(FASTFPE),$(wildcard $(FASTFPE)))
-SUBDIRS		+= $(FASTFPE)
+SUBDIRS		+=$(FASTFPE)
 ifeq ($(CONFIG_FPE_FASTFPE),y)
-LIBS		:= arch/arm/fastfpe/fast-math-emu.o $(LIBS)
+LIBS		:=arch/arm/fastfpe/fast-math-emu.o $(LIBS)
+endif
 endif
+
+ifeq ($(findstring y,$(CONFIG_USB_OHCI_SA1111) $(CONFIG_USB_OHCI_AT91)),y)
+   SUBDIRS	+=arch/arm/common
+   CORE_FILES	+=arch/arm/common/nopci.o
 endif
 
 ifeq ($(findstring y,$(CONFIG_ARCH_CLPS7500) $(CONFIG_ARCH_L7200)),y)
-SUBDIRS		+= drivers/acorn/char
-DRIVERS		+= drivers/acorn/char/acorn-char.o
+SUBDIRS		+=drivers/acorn/char
+DRIVERS		+=drivers/acorn/char/acorn-char.o
+endif
+
+ifeq ($(CONFIG_ARCH_RISCSTATION),y)
+SUBDIRS		+=drivers/acorn/char
+DRIVERS		+=drivers/acorn/char/acorn-char.o
 endif
 
-MAKEBOOT	 = $(MAKE) -C arch/$(ARCH)/boot
-MAKETOOLS	 = $(MAKE) -C arch/$(ARCH)/tools
+MAKEBOOT	 =$(MAKE) -C arch/$(ARCH)/boot
+MAKETOOLS	 =$(MAKE) -C arch/$(ARCH)/tools
 
 # The following is a hack to get 'constants.h' up
 # to date before starting compilation
@@ -194,15 +226,44 @@
 $(patsubst %,_dir_%, $(SUBDIRS)): maketools
 $(patsubst %,_modsubdir_%,$(MOD_DIRS)): maketools
 
-symlinks: archsymlinks
+symlinks: include/asm-arm/.arch include/asm-arm/.proc
 
-archsymlinks:
-	$(RM) include/asm-arm/arch include/asm-arm/proc
-	(cd include/asm-arm; ln -sf arch-$(INCDIR) arch; ln -sf proc-$(PROCESSOR) proc)
+#	Update machine arch and proc symlinks if something which affects
+#	them changed.  We use .arch and .proc to indicate when they were
+#	updated last, otherwise make uses the target directory mtime.
+
+include/asm-arm/.arch: $(wildcard include/config/arch/*.h)
+ifneq ("$(INCDIR)","")
+	@echo '  Making asm-arm/arch -> asm-arm/arch-$(INCDIR) symlink'
+	@rm -f include/asm-arm/arch
+	@ln -sf arch-$(INCDIR) include/asm-arm/arch
+	@touch $@
+else
+	@echo '  No architecture defined.  You may want to use a pre-packaged config.  make a5k_config, ebsa110_config, footbridge_config, etc.'
+endif
+
+include/asm-arm/.proc: $(wildcard include/config/cpu/32.h) $(wildcard include/config/cpu/26.h)
+ifneq ("$(INCDIR)","")
+	@echo '  Making asm-arm/proc -> asm-arm/proc-$(PROCESSOR) symlink'
+	@rm -f include/asm-arm/proc
+	@ln -sf proc-$(PROCESSOR) include/asm-arm/proc
+	@touch $@
+else
+	@echo '  No architecture defined.  You may want to use a pre-packaged config.  make a5k_config, ebsa110_config, footbridge_config, etc.'
+endif
+
+.PHONY: maketools
+maketools: include/asm-arm/.arch include/asm-arm/.proc \
+        include/asm-arm/constants.h include/linux/version.h checkbin
+	@$(MAKETOOLS)
 
 vmlinux: arch/arm/vmlinux.lds
 
-arch/arm/vmlinux.lds: $(LDSCRIPT) dummy
+arch/arm/vmlinux.lds: arch/arm/Makefile $(LDSCRIPT) \
+	$(wildcard include/config/cpu/32.h) \
+	$(wildcard include/config/cpu/26.h) \
+	$(wildcard include/config/arch/*.h)
+	@echo '  Generating $@'
 	@sed 's/TEXTADDR/$(TEXTADDR)/;s/DATAADDR/$(DATAADDR)/' $(LDSCRIPT) >$@
 
 arch/arm/kernel arch/arm/mm arch/arm/lib: dummy
@@ -216,39 +277,37 @@
 
 MRPROPER_FILES	+= \
 	arch/arm/tools/constants.h* \
-	include/asm-arm/arch \
-	include/asm-arm/proc \
+	include/asm-arm/arch include/asm-arm/.arch \
+	include/asm-arm/proc include/asm-arm/.proc \
 	include/asm-arm/constants.h* \
 	include/asm-arm/mach-types.h
 
 # We use MRPROPER_FILES and CLEAN_FILES now
-archmrproper:
+archmrproper: FORCE
 	@/bin/true
 
-archclean:
+archclean: FORCE
 	@$(MAKEBOOT) clean
 
-archdep: scripts/mkdep archsymlinks
+archdep: scripts/mkdep symlinks
 	@$(MAKETOOLS) dep
 	@$(MAKEBOOT) dep
 
-# we need version.h
-maketools: checkbin include/linux/version.h
-	@$(MAKETOOLS) all
-
-# Ensure this is ld "2.9.4" or later
+# Ensure this is ld "2.9.5" or later
 NEW_LINKER	:= $(shell $(LD) --gc-sections --version >/dev/null 2>&1; echo $$?)
 
 ifneq ($(NEW_LINKER),0)
-checkbin:
+checkbin: FORCE
 	@echo '*** ${VERSION}.${PATCHLEVEL} kernels no longer build correctly with old versions of binutils.'
 	@echo '*** Please upgrade your binutils to 2.9.5.'
 	@false
 else
-checkbin:
+checkbin: FORCE
 	@true
 endif
 
+.PHONY: FORCE
+
 # My testing targets (that short circuit a few dependencies)
 zImg:;	@$(MAKEBOOT) zImage
 Img:;	@$(MAKEBOOT) Image
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/Makefile linux-2.4.22-pre10/arch/arm/boot/Makefile
--- linux-2.4.21/arch/arm/boot/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/Makefile	2003-08-01 13:31:13.000000000 +0000
@@ -5,34 +5,42 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 1995-2000 Russell King
+# Copyright (C) 1995-2002 Russell King
 #
 
 SYSTEM	=$(TOPDIR)/vmlinux
 
+# Note: the following conditions must always be true:
+#  ZRELADDR == virt_to_phys(TEXTADDR)
+#   PARAMS_PHYS must be with 4MB of ZRELADDR
+#   INITRD_PHYS must be in RAM
+
 ifeq ($(CONFIG_CPU_26),y)
-ZTEXTADDR	 = 0x02080000
+ZRELADDR	 = 0x02080000
 PARAMS_PHYS	 = 0x0207c000
 INITRD_PHYS	 = 0x02180000
-INITRD_VIRT	 = 0x02180000
 endif
 
 ifeq ($(CONFIG_ARCH_RPC),y)
-ZTEXTADDR	 = 0x10008000
+ZRELADDR	 = 0x10008000
+PARAMS_PHYS	 = 0x10000100
+INITRD_PHYS	 = 0x18000000
+endif
+
+ifeq ($(CONFIG_ARCH_RISCSTATION),y)
+ZRELADDR	 = 0x10008000
 PARAMS_PHYS	 = 0x10000100
 INITRD_PHYS	 = 0x18000000
-INITRD_VIRT	 = 0xc8000000
 endif
 
 ifeq ($(CONFIG_ARCH_CLPS7500),y)
-ZTEXTADDR	 = 0x10008000
+ZRELADDR	 = 0x10008000
 endif
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
-ZTEXTADDR	 = 0x00008000
+ZRELADDR	 = 0x00008000
 PARAMS_PHYS	 = 0x00000400
 INITRD_PHYS	 = 0x00800000
-INITRD_VIRT	 = 0xc0800000
 endif
 
 ifeq ($(CONFIG_ARCH_SHARK),y)
@@ -41,126 +49,114 @@
 endif
 
 ifeq ($(CONFIG_FOOTBRIDGE),y)
-ZTEXTADDR	 = 0x00008000
+ZRELADDR	 = 0x00008000
 PARAMS_PHYS	 = 0x00000100
 INITRD_PHYS	 = 0x00800000
-INITRD_VIRT	 = 0xc0800000
 endif
 
 ifeq ($(CONFIG_ARCH_INTEGRATOR),y)
-ZTEXTADDR	 = 0x00008000
+ZRELADDR	 = 0x00008000
 PARAMS_PHYS	 = 0x00000100
 INITRD_PHYS	 = 0x00800000
-INITRD_VIRT	 = 0xc0800000
+endif
+
+ifeq ($(CONFIG_ARCH_AT91RM9200),y)
+ZRELADDR	 = 0x20008000
 endif
 
 ifeq ($(CONFIG_ARCH_MX1ADS),y)
-ZTEXTADDR	 = 0x08008000
+ZRELADDR	 = 0x08008000
 endif
 
 ifeq ($(CONFIG_ARCH_CAMELOT),y)
-ZTEXTADDR	 = 0x00008000
+ZRELADDR	 = 0x00008000
 endif
 
 ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
-ZTEXTADDR	 = 0x40008000
+ZRELADDR	 = 0x40008000
 endif
 
 ifeq ($(CONFIG_ARCH_L7200),y)
-# RAM based kernel
-#ZTEXTADDR	 = 0xf0400000
-#ZRELADDR	 = 0xf0008000
-
-# FLASH based kernel
-ZTEXTADDR	 = 0x00010000
 ZRELADDR	 = 0xf0008000
-ZBSSADDR	 = 0xf03e0000
 endif
 
 # The standard locations for stuff on CLPS711x type processors
 ifeq ($(CONFIG_ARCH_CLPS711X),y)
-ZTEXTADDR	 = 0xc0028000
+ZRELADDR	 = 0xc0028000
 PARAMS_PHYS	 = 0xc0000100
 endif
 
 # Should probably have some agreement on these...
 ifeq ($(CONFIG_ARCH_P720T),y)
 INITRD_PHYS	 = 0xc0400000
-INITRD_VIRT	 = 0xc0400000
 endif
 ifeq ($(CONFIG_ARCH_CDB89712),y)
 INITRD_PHYS	 = 0x00700000
-INITRD_VIRT	 = 0xc0300000
+endif
+
+ifeq ($(CONFIG_ARCH_OMAHA),y)
+ZTEXTADDR	 = 0x0c008000
+PARAMS_PHYS	 = 0x0C000100
+INITRD_PHYS	 = 0x0C800000
+INITRD_VIRT	 = 0x0C800000
 endif
 
 ifeq ($(CONFIG_ARCH_SA1100),y)
-ZTEXTADDR	 = 0xc0008000
 ZRELADDR	 = 0xc0008000
-ifeq ($(CONFIG_SA1100_VICTOR),y)
-  ZTEXTADDR	 = 0x00002000
-  ZBSSADDR	 = 0xc0200000
-endif
-ifeq ($(CONFIG_SA1100_SHERMAN),y)
-  ZTEXTADDR      = 0x00050000   
-  ZBSSADDR       = 0xc0200000
-endif
-ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y)
-  ZTEXTADDR	 = 0xC0200000
-endif
-ifeq ($(CONFIG_SA1100_GRAPHICSMASTER),y)
-  ZTEXTADDR	 = 0xC0400000
-endif
-ifeq ($(CONFIG_SA1100_ADSBITSY),y)
-  ZTEXTADDR	 = 0xC0400000
-endif
-ifeq ($(CONFIG_SA1100_YOPY),y)
-  ZTEXTADDR      = 0x00080000
-  ZBSSADDR       = 0xc0200000
-endif
+# No defconfig file to move this into...
+#ifeq ($(CONFIG_SA1100_YOPY),y)
+#  ZTEXTADDR      = 0x00080000
+#  ZBSSADDR       = 0xc0200000
+#endif
 ifeq ($(CONFIG_SA1111),y)
   ZRELADDR	 = 0xc0208000
 endif
 endif
 
 ifeq ($(CONFIG_ARCH_ANAKIN),y)
-ZTEXTADDR	 = 0x20008000
+ZRELADDR	 = 0x20008000
 endif
 
 #
-# If you don't define ZRELADDR above,
-# then it defaults to ZTEXTADDR
+# We now have a PIC decompressor implementation.  Decompressors running
+# from RAM should not define ZTEXTADDR.  Decompressors running directly
+# from ROM or Flash must define ZTEXTADDR (preferably via the config)
 #
-ifeq ($(ZRELADDR),)
-ZRELADDR	= $(ZTEXTADDR)
+ifeq ($(CONFIG_ZBOOT_ROM),y)
+ZTEXTADDR	=0x$(CONFIG_ZBOOT_ROM_TEXT)
+ZBSSADDR	=0x$(CONFIG_ZBOOT_ROM_BSS)
+else
+ZTEXTADDR	=0
+ZBSSADDR	=ALIGN(4)
 endif
 
-export	SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS INITRD_VIRT PARAMS_PHYS
+export	SYSTEM ZTEXTADDR ZBSSADDR ZRELADDR INITRD_PHYS PARAMS_PHYS
 
-Image:	$(CONFIGURE) $(SYSTEM)
-	$(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) $@
+Image:	$(SYSTEM)
+	$(OBJCOPY) $(OBJCOPYFLAGS) $< $@
 
 bzImage: zImage
 
-zImage:	$(CONFIGURE) compressed/vmlinux
-	$(OBJCOPY) -O binary -R .note -R .comment -S compressed/vmlinux $@
+zImage:	compressed/vmlinux
+	$(OBJCOPY) $(OBJCOPYFLAGS) $< $@
 
 bootpImage: bootp/bootp
-	$(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@
+	$(OBJCOPY) $(OBJCOPYFLAGS) $< $@
 
-compressed/vmlinux: $(TOPDIR)/vmlinux dep
+compressed/vmlinux: $(TOPDIR)/vmlinux FORCE
 	@$(MAKE) -C compressed vmlinux
 
-bootp/bootp: zImage initrd
+bootp/bootp: zImage initrd FORCE
 	@$(MAKE) -C bootp bootp
 
 initrd:
-	@test "$(INITRD_VIRT)" != "" || (echo This architecture does not support INITRD; exit -1)
+	@test "$(INITRD_PHYS)" != "" || (echo This machine does not support INITRD; exit -1)
 	@test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1)
 
-install: $(CONFIGURE) Image
+install: Image
 	sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
 
-zinstall: $(CONFIGURE) zImage
+zinstall: zImage
 	sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
 
 clean:
@@ -169,3 +165,5 @@
 	@$(MAKE) -C bootp clean
 
 dep:
+
+FORCE:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/bootp/Makefile linux-2.4.22-pre10/arch/arm/boot/bootp/Makefile
--- linux-2.4.21/arch/arm/boot/bootp/Makefile	2001-10-11 16:04:57.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/bootp/Makefile	2003-08-01 13:34:11.000000000 +0000
@@ -5,9 +5,7 @@
 ZSYSTEM		=$(TOPDIR)/arch/arm/boot/zImage
 ZLDFLAGS	=-p -X -T bootp.lds \
 		 --defsym initrd_addr=$(INITRD_PHYS) \
-		 --defsym initrd_virt=$(INITRD_VIRT) \
-		 --defsym params=$(PARAMS_PHYS) \
-		 --defsym kernel_addr=$(ZTEXTADDR)
+		 --defsym params=$(PARAMS_PHYS)
 
 all:		bootp
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/bootp/bootp.lds linux-2.4.22-pre10/arch/arm/boot/bootp/bootp.lds
--- linux-2.4.21/arch/arm/boot/bootp/bootp.lds	2000-09-18 22:15:24.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/bootp/bootp.lds	2003-08-01 13:30:57.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/boot/bootp/bootp.lds
  *
- *  Copyright (C) 2000 Russell King
+ *  Copyright (C) 2000-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -15,13 +15,9 @@
   _text = .;
   .text : {
    _stext = .;
-   _start = .;
-   init.o(.start)
-   kernel_start = .;
+   *(.start)
    kernel.o
-   kernel_len = . - kernel_start;
    . = ALIGN(32);
-   *(.text)
    initrd_start = .;
    initrd.o
    initrd_len = . - initrd_start;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/bootp/init.S linux-2.4.22-pre10/arch/arm/boot/bootp/init.S
--- linux-2.4.21/arch/arm/boot/bootp/init.S	2001-10-11 16:04:57.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/bootp/init.S	2003-08-01 13:33:49.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/boot/bootp/init.S
  *
- *  Copyright (C) 2000 Russell King
+ *  Copyright (C) 2000-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -11,8 +11,9 @@
  *  r0 through to r3 straight through.
  */
 		.section .start,#alloc,#execinstr
-		.type	_entry, #function
-_entry:		adr	r10, initdata
+		.type	_start, #function
+		.globl	_start
+_start:		adr	r10, initdata
 		ldr	r11, initdata
 		sub	r11, r10, r11		@ work out exec offset
 		b	splitify
@@ -22,17 +23,11 @@
 initdata:	.word	initdata		@ compiled address of this
 		.size	initdata,. - initdata
 
-		.text
 splitify:	adr	r13, data
 		ldmia	r13!, {r4-r6}		@ move the initrd
 		add	r4, r4, r11		@ correction
 		bl	move
 
-		ldmia	r13!, {r4-r6}		@ then the kernel
-		mov	r12, r5
-		add	r4, r4, r11		@ correction
-		bl	move
-
 /*
  * Setup the initrd parameters to pass to the kernel.  This can either be
  * passed in via a param_struct or a tag list.  We spot the param_struct
@@ -52,17 +47,16 @@
 
 		ldr	r9, [r8, #4]		@ get first tag
 		teq	r9, r4
-		bne	taglist			@ ok, we have a tag list
+		beq	taglist			@ ok, we have a tag list
 
 /*
  * We didn't find a valid tag list - create one.
  */
 		str	r4, [r8, #4]
-		mov	r4, #8
+		mov	r4, #(8 >> 2)
 		str	r4, [r8, #0]
 		mov	r4, #0
 		str	r4, [r8, #8]
-
 /*
  * find the end of the tag list, and then add an INITRD tag on the end.
  * If there is already an INITRD tag, then we ignore it; the last INITRD
@@ -70,12 +64,12 @@
  */
 taglist:	ldr	r9, [r8, #0]		@ tag length
 		teq	r9, #0			@ last tag?
-		addne	r8, r8, r9
+		addne	r8, r8, r9, lsl #2
 		bne	taglist
-
-		mov	r4, #16			@ length of initrd tag
+		mov	r4, #(16 >> 2)		@ length of initrd tag
 		mov	r9, #0			@ end of tag list terminator
 		stmia	r8, {r4, r5, r6, r7, r9}
+		adr	r12, kernel_start
 		mov	pc, r12			@ call kernel
 
 /*
@@ -83,6 +77,7 @@
  */
 param_struct:	add	r8, r8, #16*4
 		stmia	r8, {r6,r7}		@ save in param_struct
+		adr	r12, kernel_start
 		mov	pc, r12			@ call kernel
 
 move:		ldmia	r4!, {r7 - r10}		@ move 32-bytes at a time
@@ -97,15 +92,12 @@
 		.word	initrd_addr
 		.word	initrd_len
 
-		.word	kernel_start
-		.word	kernel_addr
-		.word	kernel_len
-
 		.word	0x54410001		@ r4 = ATAG_CORE
-		.word	0x54410005		@ r5 = ATAG_INITRD
-		.word	initrd_virt		@ r6
+		.word	0x54420005		@ r5 = ATAG_INITRD
+		.word	initrd_addr		@ r6
 		.word	initrd_len		@ r7
 		.word	params			@ r8
 
-		.type	kernel_start,#object
 		.type	initrd_start,#object
+
+kernel_start:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/Makefile linux-2.4.22-pre10/arch/arm/boot/compressed/Makefile
--- linux-2.4.21/arch/arm/boot/compressed/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/Makefile	2003-08-01 13:31:21.000000000 +0000
@@ -9,7 +9,7 @@
 
 HEAD		 = head.o
 OBJS		 = misc.o
-CFLAGS		 = $(CPPFLAGS) -O2 -DSTDC_HEADERS $(CFLAGS_BOOT)
+CFLAGS		 = $(CPPFLAGS) -O2 -DSTDC_HEADERS $(CFLAGS_BOOT) -fpic -Uarm
 FONTC		 = $(TOPDIR)/drivers/video/font_acorn_8x8.c
 ZLDFLAGS	 = -p -X -T vmlinux.lds
 
@@ -18,7 +18,12 @@
 #
 ifeq ($(CONFIG_ARCH_ACORN),y)
 OBJS		+= ll_char_wr.o font.o
-ZLDFLAGS	+= -defsym params=$(PARAMS_PHYS)
+CFLAGS		+= -DPARAMS_PHYS=$(PARAMS_PHYS)
+endif
+
+ifeq ($(CONFIG_ARCH_RISCSTATION),y)
+OBJS		+= ll_char_wr.o font.o
+CFLAGS		+= -DPARAMS_PHYS=$(PARAMS_PHYS)
 endif
 
 ifeq ($(CONFIG_ARCH_NETWINDER),y)
@@ -33,6 +38,10 @@
 OBJS		+= head-integrator.o
 endif
 
+ifeq ($(CONFIG_ARCH_AT91RM9200),y)
+OBJS		+= head-at91rm9200.o
+endif
+
 ifeq ($(CONFIG_ARCH_MX1ADS),y)
 OBJS		+= head-mx1ads.o
 endif
@@ -60,18 +69,9 @@
 
 ifeq ($(CONFIG_ARCH_SA1100),y)
 OBJS		+= head-sa1100.o
-ifeq ($(CONFIG_SA1100_NANOENGINE),y)
-  OBJS += hw-bse.o
-endif
 endif
 
-SEDFLAGS	= s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;
-
-ifneq ($(ZBSSADDR),)
-SEDFLAGS	+= s/BSS_START/$(ZBSSADDR)/
-else
-SEDFLAGS	+= s/BSS_START/ALIGN(4)/
-endif
+SEDFLAGS	= s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;s/BSS_START/$(ZBSSADDR)/
 
 LIBGCC		:= $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
 
@@ -80,11 +80,14 @@
 vmlinux:	$(HEAD) $(OBJS) piggy.o vmlinux.lds
 		$(LD) $(ZLDFLAGS) $(HEAD) $(OBJS) piggy.o $(LIBGCC) -o vmlinux
 
-$(HEAD): 	$(HEAD:.o=.S)
+$(HEAD): 	$(HEAD:.o=.S) \
+			$(wildcard $(TOPDIR)/include/config/zboot/rom.h) \
+			$(wildcard $(TOPDIR)/include/config/cpu/32.h) \
+			$(wildcard $(TOPDIR)/include/config/cpu/26.h)
 		$(CC) $(AFLAGS) -traditional -c $(HEAD:.o=.S)
 
 piggy.o:	$(SYSTEM)
-		$(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) piggy
+		$(OBJCOPY) $(OBJCOPYFLAGS) $(SYSTEM) piggy
 		gzip $(GZFLAGS) < piggy > piggy.gz
 		$(LD) -r -o $@ -b binary piggy.gz
 		rm -f piggy piggy.gz
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/head-at91rm9200.S linux-2.4.22-pre10/arch/arm/boot/compressed/head-at91rm9200.S
--- linux-2.4.21/arch/arm/boot/compressed/head-at91rm9200.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/head-at91rm9200.S	2003-08-01 13:31:50.000000000 +0000
@@ -0,0 +1,15 @@
+/*
+ * linux/arch/arm/boot/compressed/head-at91rm9200.S
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <asm/mach-types.h>
+
+		.section	".start", "ax"
+		mov	r7, #MACH_TYPE_AT91RM9200
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/head-clps7500.S linux-2.4.22-pre10/arch/arm/boot/compressed/head-clps7500.S
--- linux-2.4.21/arch/arm/boot/compressed/head-clps7500.S	2001-04-12 19:03:50.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/head-clps7500.S	2003-08-01 13:34:50.000000000 +0000
@@ -13,7 +13,7 @@
 		/* This branch is taken if the CPU memory width matches the
 		   actual device in use.  The default at power on is 16 bits
 		   so we must be prepared for a mismatch. */
-		.section ".start", #alloc, #execinstr
+		.section ".start", "ax"
 2:
 		b	1f
 		.word	0xffff
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/head-epxa10db.S linux-2.4.22-pre10/arch/arm/boot/compressed/head-epxa10db.S
--- linux-2.4.21/arch/arm/boot/compressed/head-epxa10db.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/head-epxa10db.S	2003-08-01 13:33:36.000000000 +0000
@@ -1,5 +1,5 @@
 #include <asm/mach-types.h>
 #include <asm/arch/excalibur.h>
 
-		.section	".start", #alloc, #execinstr
+		.section	".start", "ax"
 		mov	r7, #MACH_TYPE_CAMELOT
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/head-ftvpci.S linux-2.4.22-pre10/arch/arm/boot/compressed/head-ftvpci.S
--- linux-2.4.21/arch/arm/boot/compressed/head-ftvpci.S	2001-02-09 00:32:44.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/head-ftvpci.S	2003-08-01 13:32:24.000000000 +0000
@@ -13,7 +13,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-	.section        ".start", #alloc, #execinstr
+	.section        ".start", "ax"
 ftv_start:
 	mcr	p15, 0, r0, c7, c5, 0		@ flush I cache
 	mrc	p15, 0, r0, c1, c0
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/head-integrator.S linux-2.4.22-pre10/arch/arm/boot/compressed/head-integrator.S
--- linux-2.4.21/arch/arm/boot/compressed/head-integrator.S	2001-06-27 21:12:04.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/head-integrator.S	2003-08-01 13:30:57.000000000 +0000
@@ -1,4 +1,4 @@
 #include <asm/mach-types.h>
 
-		.section	".start", #alloc, #execinstr
+		.section	".start", "ax"
 		mov	r7, #MACH_TYPE_INTEGRATOR
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/head-l7200.S linux-2.4.22-pre10/arch/arm/boot/compressed/head-l7200.S
--- linux-2.4.21/arch/arm/boot/compressed/head-l7200.S	2001-02-09 00:32:44.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/head-l7200.S	2003-08-01 13:33:51.000000000 +0000
@@ -8,12 +8,13 @@
  */
 
 #include <linux/config.h>
+#include <asm/mach-types.h>
 
 #ifndef CONFIG_ARCH_L7200
 #error What am I doing here...
 #endif
 
-		.section        ".start", #alloc, #execinstr
+		.section        ".start", "ax"
 
 __L7200_start:
 		mov	r0, #0x00100000		@ FLASH address of initrd
@@ -26,4 +27,4 @@
 		ble	1b
 
 		mov	r8, #0			@ Zero it out
-		mov	r7, #19			@ Set architecture ID
+		mov	r7, #MACH_TYPE_L7200	@ Set architecture ID
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/head-netwinder.S linux-2.4.22-pre10/arch/arm/boot/compressed/head-netwinder.S
--- linux-2.4.21/arch/arm/boot/compressed/head-netwinder.S	2000-09-18 22:15:24.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/head-netwinder.S	2003-08-01 13:31:32.000000000 +0000
@@ -1,50 +1,13 @@
 /*
  *  linux/arch/arm/boot/compressed/head-netwinder.S
  *
- *  Copyright (C) 2000 Russell King
+ *  Copyright (C) 2000-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define K(a,b,c)	((a) << 24 | (b) << 12 | (c))
+		.section	".start", "ax"
 
-		.section	".start", #alloc, #execinstr
-
-		/*
-		 * check to see if we are running from the correct address.
-		 * If not, we move ourselves in a two stage process.  Firstly,
-		 * we copy the start of the kernel (which includes this code)
-		 * to 0x8000, and then jump to this code to continue with the
-		 * rest (since this code will get overwritten).
-		 */
-		adr	r2, 1f
-		ldmdb	r2, {r9, r10}
-		and	r3, r2, #0xc000
-		teq	r3, #0x8000	@ correctly located?
-		beq	2f		@ skip this code
-		bic	r3, r2, #0xc000
-		orr	r3, r3, #0x8000
-		mov	r0, r3		@ new address if '1'
-		mov	r4, #64		@ number of bytes to copy
-		sub	r5, r10, r9	@ total number of bytes to copy
-		b	1f
-
-		.word	_start
-		.word	__bss_start
-
-1:
-		.rept	4
-		ldmia	r2!, {r6, r9, r10, r11}
-		stmia	r3!, {r6, r9, r10, r11}
-		.endr
-		subs	r4, r4, #64
-		bcs	1b
-		movs	r4, r5		@ remaining length
-		mov	r5, #0		@ no more to copy
-		movne	pc, r0		@ jump back to 1 (in the newly copied
-					@ code)
-		mov	r7, #5		@ only here to fix NeTTroms which dont
-		mov	r8, #2 << 24		@ scheduled for removal in 2.5.xx
-		orr	r8, r8, #5 << 12
-2:
+/*		mov	r7, #5*/
+/*		mov	r8, #0*/
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/head-sa1100.S linux-2.4.22-pre10/arch/arm/boot/compressed/head-sa1100.S
--- linux-2.4.21/arch/arm/boot/compressed/head-sa1100.S	2001-10-11 16:04:57.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/head-sa1100.S	2003-08-01 13:31:07.000000000 +0000
@@ -11,7 +11,7 @@
 #include <linux/linkage.h>
 #include <asm/mach-types.h>
 
-		.section        ".start", #alloc, #execinstr
+		.section        ".start", "ax"
 
 __SA1100_start:
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/head-shark.S linux-2.4.22-pre10/arch/arm/boot/compressed/head-shark.S
--- linux-2.4.21/arch/arm/boot/compressed/head-shark.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/head-shark.S	2003-08-01 13:34:21.000000000 +0000
@@ -16,7 +16,7 @@
 
 #include <asm/assembler.h>
 	
-		.section	".start", #alloc, #execinstr
+		.section	".start", "ax"
 
 		b	__beginning
 	
@@ -38,7 +38,7 @@
 		adr	r1, __ofw_data
 		add	r2, r1, #4
 		mov	lr, pc
-		b	SYMBOL_NAME(ofw_init)
+		b	ofw_init
 		mov	r1, #0
 
 		adr	r2, __mmu_off			@ calculate physical address
@@ -109,7 +109,7 @@
 		add	sp, sp, #128
 		adr	r0, __ofw_data
 		mov	lr, pc
-		b	SYMBOL_NAME(create_params)
+		b	create_params
 	
 		mov	r8, #0
 		mov	r7, #15
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/head.S linux-2.4.22-pre10/arch/arm/boot/compressed/head.S
--- linux-2.4.21/arch/arm/boot/compressed/head.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/head.S	2003-08-01 13:34:30.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/boot/compressed/head.S
  *
- *  Copyright (C) 1996-1999 Russell King
+ *  Copyright (C) 1996-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -19,6 +19,13 @@
  */
 #ifdef DEBUG
 #if defined(CONFIG_DEBUG_DC21285_PORT)
+		.macro	loadsp, rb
+		mov	\rb, #0x42000000
+		.endm
+		.macro	writeb, rb
+		str	\rb, [r3, #0x160]
+		.endm
+#elif defined(CONFIG_FOOTBRIDGE)
 		.macro	loadsp,	rb
 		mov	\rb, #0x7c000000
 		.endm
@@ -40,6 +47,15 @@
 		.macro	writeb, rb
 		strb	\rb, [r3, #0]
 		.endm
+#elif defined(CONFIG_ARCH_AT91RM9200)
+		.macro	loadsp, rb
+		mov	\rb, #0xFF000000	@ BASE_DBGU (we cannot use ldr \reg, =AT91_DBGU_BASE)
+		add	\rb, \rb, #0x00FF0000
+		add	\rb, \rb, #0x0000F200
+		.endm
+		.macro	writeb, rb
+		strb	\rb, [r3, #0x1C]	@ DBGU_THR (Transmitter Holding Register)
+		.endm
 #elif defined(CONFIG_ARCH_SA1100)
 		.macro	loadsp, rb
 		mov	\rb, #0x80000000	@ physical base address
@@ -50,6 +66,11 @@
 #  endif
 		.endm
 		.macro	writeb, rb
+/*
+ * "The ARM peripheral bus does not support byte or half-word operations.
+ * All reads and writes of the UART by the CPU should be wordwide."
+ *   - SA-1100 Developer's Manual, August 1999
+ */
 		str	\rb, [r3, #0x14]	@ UTDR
 		.endm
 #else
@@ -144,33 +165,98 @@
 		 */
 
 		.text
-1:		adr	r2, LC0
-		ldmia	r2, {r2, r3, r4, r5, sp}
+		adr	r0, LC0
+		ldmia	r0, {r1, r2, r3, r4, r5, r6, ip, sp}
+		subs	r0, r0, r1		@ calculate the delta offset
+
+		teq	r0, #0			@ if delta is zero, we're
+		beq	not_relocated		@ running at the address we
+						@ were linked at.
 
-		mov	r0, #0
+		/*
+		 * We're running at a different address.  We need to fix
+		 * up various pointers:
+		 *   r5 - zImage base address
+		 *   r6 - GOT start
+		 *   ip - GOT end
+		 */
+		add	r5, r5, r0
+		add	r6, r6, r0
+		add	ip, ip, r0
+
+#ifndef CONFIG_ZBOOT_ROM
+		/*
+		 * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
+		 * we need to fix up pointers into the BSS region.
+		 *   r2 - BSS start
+		 *   r3 - BSS end
+		 *   sp - stack pointer
+		 */
+		add	r2, r2, r0
+		add	r3, r3, r0
+		add	sp, sp, r0
+
+		/*
+		 * Relocate all entries in the GOT table.
+		 */
+1:		ldr	r1, [r6, #0]
+		add	r1, r1, r0
+		str	r1, [r6], #4
+		cmp	r6, ip
+		blo	1b
+#else
+
+		/*
+		 * Relocate entries in the GOT table.  We only relocate
+		 * the entries that are outside the (relocated) BSS region.
+		 */
+1:		ldr	r1, [r6, #0]
+		cmp	r1, r2			@ entry < bss_start ||
+		cmphs	r3, r1			@ _end < entry
+		addlo	r1, r1, r0
+		str	r1, [r6], #4
+		cmp	r6, ip
+		blo	1b
+
+#endif
+
+not_relocated:	mov	r0, #0
 1:		str	r0, [r2], #4		@ clear bss
 		str	r0, [r2], #4
 		str	r0, [r2], #4
 		str	r0, [r2], #4
 		cmp	r2, r3
-		blt	1b
+		blo	1b
 
-		mrc	p15, 0, r6, c0, c0	@ get processor ID
+		/*
+		 * The C runtime environment should now be setup
+		 * sufficiently.  Turn the cache on, set up some
+		 * pointers, and start decompressing.
+		 */
 		bl	cache_on
 
 		mov	r1, sp			@ malloc space above stack
 		add	r2, sp, #0x10000	@ 64k max
 
-		teq	r4, r5			@ will we overwrite ourselves?
-		moveq	r5, r2			@ decompress after image
-		movne	r5, r4			@ decompress to final location
+/*
+ * Check to see if we will overwrite ourselves.
+ *   r4 = final kernel address
+ *   r5 = start of this image
+ *   r2 = end of malloc space (and therefore this image)
+ * We basically want:
+ *   r4 >= r2 -> OK
+ *   r4 + image length <= r5 -> OK
+ */
+		cmp	r4, r2
+		bhs	wont_overwrite
+		add	r0, r4, #4096*1024	@ 4MB largest kernel size
+		cmp	r0, r5
+		bls	wont_overwrite
 
+		mov	r5, r2			@ decompress after malloc space
 		mov	r0, r5
 		mov	r3, r7
-		bl	SYMBOL_NAME(decompress_kernel)
-
-		teq	r4, r5			@ do we need to relocate
-		beq	call_kernel		@ the kernel?
+		bl	decompress_kernel
 
 		add	r0, r0, #127
 		bic	r0, r0, #127		@ align the kernel length
@@ -185,23 +271,39 @@
  */
 		add	r1, r5, r0		@ end of decompressed kernel
 		adr	r2, reloc_start
-		adr	r3, reloc_end
+		ldr	r3, LC1
+		add	r3, r2, r3
 1:		ldmia	r2!, {r8 - r13}		@ copy relocation code
 		stmia	r1!, {r8 - r13}
 		ldmia	r2!, {r8 - r13}
 		stmia	r1!, {r8 - r13}
 		cmp	r2, r3
-		blt	1b
+		blo	1b
 
 		bl	cache_clean_flush
 		add	pc, r5, r0		@ call relocation code
 
+/*
+ * We're not in danger of overwriting ourselves.  Do this the simple way.
+ *
+ * r4     = kernel execution address
+ * r7     = architecture ID
+ */
+wont_overwrite:	mov	r0, r4
+		mov	r3, r7
+		bl	decompress_kernel
+		b	call_kernel
+
 		.type	LC0, #object
-LC0:		.word	__bss_start
-		.word	_end
-		.word	_load_addr
-		.word	_start
-		.word	user_stack+4096
+LC0:		.word	LC0			@ r1
+		.word	__bss_start		@ r2
+		.word	_end			@ r3
+		.word	_load_addr		@ r4
+		.word	_start			@ r5
+		.word	_got_start		@ r6
+		.word	_got_end		@ ip
+		.word	user_stack+4096		@ sp
+LC1:		.word	reloc_end - reloc_start
 		.size	LC0, . - LC0
 
 /*
@@ -218,22 +320,15 @@
  *  r7 = architecture number
  *  r8 = run-time address of "start"
  * On exit,
- *  r0, r1, r2, r3, r8, r9 corrupted
+ *  r1, r2, r3, r8, r9, r12 corrupted
  * This routine must preserve:
  *  r4, r5, r6, r7
  */
 		.align	5
-cache_on:	ldr	r1, proc_sa110_type
-		eor	r1, r1, r6
-		movs	r1, r1, lsr #5		@ catch SA110 and SA1100
-		beq	1f
-		ldr     r1, proc_sa1110_type
-		eor	r1, r1, r6
-		movs	r1, r1, lsr #4
-@		movne	pc, lr
-		bne	cache_off
-1:
-		sub	r3, r4, #16384		@ Page directory size
+cache_on:	mov	r3, #8			@ cache_on function
+		b	call_cache_fn
+
+__setup_mmu:	sub	r3, r4, #16384		@ Page directory size
 		bic	r3, r3, #0xff		@ Align the pointer
 		bic	r3, r3, #0x3f00
 /*
@@ -248,9 +343,9 @@
 		orr	r1, r1, #3 << 10
 		add	r2, r3, #16384
 1:		cmp	r1, r8			@ if virt > start of RAM
-		orrge	r1, r1, #0x0c		@ set cacheable, bufferable
+		orrhs	r1, r1, #0x0c		@ set cacheable, bufferable
 		cmp	r1, r9			@ if virt > end of RAM
-		bicge	r1, r1, #0x0c		@ clear cacheable, bufferable
+		bichs	r1, r1, #0x0c		@ clear cacheable, bufferable
 		str	r1, [r0], #4		@ 1:1 mapping
 		add	r1, r1, #1048576
 		teq	r0, r2
@@ -269,24 +364,42 @@
 		str	r1, [r0], #4
 		add	r1, r1, #1048576
 		str	r1, [r0]
+		mov	pc, lr
 
+__armv4_cache_on:
+		mov	r12, lr
+		bl	__setup_mmu
 		mov	r0, #0
 		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
-		mcr	p15, 0, r0, c8, c7	@ flush I,D TLBs
-		mcr	p15, 0, r3, c2, c0	@ load page table pointer
+		mcr	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs
+		mcr	p15, 0, r3, c2, c0, 0	@ load page table pointer
 		mov	r0, #-1
-		mcr	p15, 0, r0, c3, c0	@ load domain access register
-		mrc	p15, 0, r0, c1, c0
+		mcr	p15, 0, r0, c3, c0, 0	@ load domain access register
+		mrc	p15, 0, r0, c1, c0, 0
 		orr	r0, r0, #0x1000		@ I-cache enable
 #ifndef DEBUG
 		orr	r0, r0, #0x003d		@ Write buffer, mmu
 #endif
-		mcr	p15, 0, r0, c1, c0
-		mov	pc, lr
+		mcr	p15, 0, r0, c1, c0, 0
+		mov	pc, r12
+
+__arm6_cache_on:
+		mov	r12, lr
+		bl	__setup_mmu
+		mov	r0, #0
+		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
+		mcr	p15, 0, r0, c5, c0, 0	@ invalidate whole TLB v3
+		mcr	p15, 0, r3, c2, c0, 0	@ load page table pointer
+		mov	r0, #-1
+		mcr	p15, 0, r0, c3, c0, 0	@ load domain access control
+		mov	r0, #0x3d
+		mcr	p15, 0, r0, c1, c0, 0	@ load control register
+		mov	pc, r12
 
 /*
- * This code is relocatable.  It is relocated by the above code to the end
- * of the kernel and executed there.  During this time, we have no stacks.
+ * All code following this line is relocatable.  It is relocated by
+ * the above code to the end of the decompressed kernel image and
+ * executed there.  During this time, we have no stacks.
  *
  * r0     = decompressed kernel length
  * r1-r3  = unused
@@ -307,7 +420,7 @@
 		.endr
 
 		cmp	r5, r8
-		blt	1b
+		blo	1b
 		debug_reloc_end
 
 call_kernel:	bl	cache_clean_flush
@@ -317,47 +430,117 @@
 		mov	pc, r4			@ call kernel
 
 /*
- * Here follow the relocatable cache support functions for
- * the various processors.
+ * Here follow the relocatable cache support functions for the
+ * various processors.  This is a generic hook for locating an
+ * entry and jumping to an instruction at the specified offset
+ * from the start of the block.  Please note this is all position
+ * independent code.
+ *
+ *  r1  = corrupted
+ *  r2  = corrupted
+ *  r3  = block offset
+ *  r6  = corrupted
+ *  r12 = corrupted
  */
 
-		.type	proc_sa110_type,#object
-proc_sa110_type:
-		.word	0x4401a100
-		.size	proc_sa110_type, . - proc_sa110_type
-
-		.type	proc_sa1110_type,#object
-proc_sa1110_type:
-		.word	0x6901b110
-		.size	proc_sa1110_type, . - proc_sa1110_type
+call_cache_fn:	adr	r12, proc_types
+		mrc	p15, 0, r6, c0, c0	@ get processor ID
+1:		ldr	r1, [r12, #0]		@ get value
+		ldr	r2, [r12, #4]		@ get mask
+		eor	r1, r1, r6		@ (real ^ match)
+		tst	r1, r2			@       & mask
+		addeq	pc, r12, r3		@ call cache function
+		add	r12, r12, #4*5
+		b	1b
+
+/*
+ * Table for cache operations.  This is basically:
+ *   - CPU ID match
+ *   - CPU ID mask
+ *   - 'cache on' method instruction
+ *   - 'cache off' method instruction
+ *   - 'cache flush' method instruction
+ *
+ * We match an entry using: ((real_id ^ match) & mask) == 0
+ *
+ * Writethrough caches generally only need 'on' and 'off'
+ * methods.  Writeback caches _must_ have the flush method
+ * defined.
+ */
+		.type	proc_types,#object
+proc_types:
+		.word	0x41560600		@ ARM6/610
+		.word	0xffffffe0
+		b	__arm6_cache_off	@ works, but slow
+		b	__arm6_cache_off
+		mov	pc, lr
+@		b	__arm6_cache_on		@ untested
+@		b	__arm6_cache_off
+@		b	__armv3_cache_flush
+
+		.word	0x41007000		@ ARM7/710
+		.word	0xfff8fe00
+		b	__arm7_cache_off
+		b	__arm7_cache_off
+		mov	pc, lr
+
+		.word	0x41807200		@ ARM720T (writethrough)
+		.word	0xffffff00
+		b	__armv4_cache_on
+		b	__armv4_cache_off
+		mov	pc, lr
+
+		.word	0x41129200		@ ARM920T
+		.word	0xff00fff0
+		b	__armv4_cache_on
+		b	__armv4_cache_off
+		b	__armv4_cache_flush
+
+		.word	0x41029220		@ ARM922T
+		.word	0xff00fff0
+		b	__armv4_cache_on
+		b	__armv4_cache_off
+		b	__armv4_cache_flush
+
+		.word	0x4401a100		@ sa110 / sa1100
+		.word	0xffffffe0
+		b	__armv4_cache_on
+		b	__armv4_cache_off
+		b	__armv4_cache_flush
+
+		.word	0x6901b110		@ sa1110
+		.word	0xfffffff0
+		b	__armv4_cache_on
+		b	__armv4_cache_off
+		b	__armv4_cache_flush
+
+		.word	0x69050000		@ xscale
+		.word	0xffff0000
+		b	__armv4_cache_on
+		b	__armv4_cache_off
+		b	__armv4_cache_flush
+
+		.word	0			@ unrecognised type
+		.word	0
+		mov	pc, lr
+		mov	pc, lr
+		mov	pc, lr
+
+		.size	proc_types, . - proc_types
 
 /*
  * Turn off the Cache and MMU.  ARMv3 does not support
  * reading the control register, but ARMv4 does.
  *
  * On entry,  r6 = processor ID
- * On exit,   r0, r1 corrupted
+ * On exit,   r0, r1, r2, r3, r12 corrupted
  * This routine must preserve: r4, r6, r7
  */
 		.align	5
-cache_off:
-#ifdef CONFIG_CPU_ARM610
-		eor	r1, r6, #0x41000000
-		eor	r1, r1, #0x00560000
-		bic	r1, r1, #0x0000001f
-		teq	r1, #0x00000600
-		mov	r0, #0x00000060		@ ARM6 control reg.
-		beq	__armv3_cache_off
-#endif
-#ifdef CONFIG_CPU_ARM710
-		eor	r1, r6, #0x41000000
-		bic	r1, r1, #0x00070000
-		bic	r1, r1, #0x000000ff
-		teq	r1, #0x00007000		@ ARM7
-		teqne	r1, #0x00007100		@ ARM710
-		mov	r0, #0x00000070		@ ARM7 control reg.
-		beq	__armv3_cache_off
-#endif
+cache_off:	mov	r3, #12			@ cache_off function
+		b	call_cache_fn
+
+__armv4_cache_off:
 		mrc	p15, 0, r0, c1, c0
 		bic	r0, r0, #0x000d
 		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
@@ -366,11 +549,19 @@
 		mcr	p15, 0, r0, c8, c7	@ invalidate whole TLB v4
 		mov	pc, lr
 
+__arm6_cache_off:
+		mov	r0, #0x00000030		@ ARM6 control reg.
+		b	__armv3_cache_off
+
+__arm7_cache_off:
+		mov	r0, #0x00000070		@ ARM7 control reg.
+		b	__armv3_cache_off
+
 __armv3_cache_off:
-		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
+		mcr	p15, 0, r0, c1, c0, 0	@ turn MMU and cache off
 		mov	r0, #0
-		mcr	p15, 0, r0, c7, c0	@ invalidate whole cache v3
-		mcr	p15, 0, r0, c5, c0	@ invalidate whole TLB v3
+		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
+		mcr	p15, 0, r0, c5, c0, 0	@ invalidate whole TLB v3
 		mov	pc, lr
 
 /*
@@ -379,23 +570,18 @@
  * On entry,
  *  r6 = processor ID
  * On exit,
- *  r1, r2, r12 corrupted
+ *  r1, r2, r3, r12 corrupted
  * This routine must preserve:
- *  r4, r6, r7
+ *  r0, r4, r5, r6, r7
  */
 		.align	5
 cache_clean_flush:
-		ldr	r1, proc_sa110_type
-		eor	r1, r1, r6
-		movs	r1, r1, lsr #5		@ catch SA110 and SA1100
-		beq	1f
-		ldr	r1, proc_sa1110_type
-		eor	r1, r1, r6
-		movs	r1, r1, lsr #4
-		movne	pc, lr
-1:
+		mov	r3, #16
+		b	call_cache_fn
+
+__armv4_cache_flush:
 		bic	r1, pc, #31
-		add	r2, r1, #32768
+		add	r2, r1, #65536		@ 2x the largest dcache size
 1:		ldr	r12, [r1], #32		@ s/w flush D cache
 		teq	r1, r2
 		bne	1b
@@ -404,6 +590,11 @@
 		mcr	p15, 0, r1, c7, c10, 4	@ drain WB
 		mov	pc, lr
 
+__armv3_cache_flush:
+		mov	r1, #0
+		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
+		mov	pc, lr
+
 /*
  * Various debugging routines for printing hex characters and
  * memory, which again must be relocatable.
@@ -479,5 +670,5 @@
 reloc_end:
 
 		.align
-		.section	".stack"
+		.section ".stack", "w"
 user_stack:	.space	4096
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/hw-bse.c linux-2.4.22-pre10/arch/arm/boot/compressed/hw-bse.c
--- linux-2.4.21/arch/arm/boot/compressed/hw-bse.c	2000-08-13 16:54:15.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/hw-bse.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,74 +0,0 @@
-/*
- * Bright Star Engineering Inc.
- *
- * code for readng parameters from the
- * parameter blocks of the boot block
- * flash memory
- *
- */
-
-static int strcmp(const char *s1, const char *s2)
-{
-  while (*s1 != '\0' && *s1 == *s2)
-    {
-      s1++;
-      s2++;
-    }
-
-  return (*(unsigned char *) s1) - (*(unsigned char *) s2);
-}
-
-struct pblk_t {
-  char type;
-  unsigned short size;
-};
-
-static char *bse_getflashparam(char *name) {
-  unsigned int esize;
-  char *q,*r;
-  unsigned char *p,*e;
-  struct pblk_t *thepb = (struct pblk_t *) 0x00004000;
-  struct pblk_t *altpb = (struct pblk_t *) 0x00006000;  
-  if (thepb->type&1) {
-    if (altpb->type&1) {
-      /* no valid param block */ 
-      return (char*)0;
-    } else {
-      /* altpb is valid */
-      struct pblk_t *tmp;
-      tmp = thepb;
-      thepb = altpb;
-      altpb = tmp;
-    }
-  }
-  p = (char*)thepb + sizeof(struct pblk_t);
-  e = p + thepb->size; 
-  while (p < e) {
-    q = p;
-    esize = *p;
-    if (esize == 0xFF) break;
-    if (esize == 0) break;
-    if (esize > 127) {
-      esize = (esize&0x7F)<<8 | p[1];
-      q++;
-    }
-    q++;
-    r=q;
-    if (*r && ((name == 0) || (!strcmp(name,r)))) {
-      while (*q++) ;
-      return q;
-    }
-    p+=esize;
-  }
-  return (char*)0;
-}
-
-void bse_setup(void) {
-  /* extract the linux cmdline from flash */
-  char *name=bse_getflashparam("linuxboot");
-  char *x = (char *)0xc0000100;
-  if (name) { 
-    while (*name) *x++=*name++;
-  }
-  *x=0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/ll_char_wr.S linux-2.4.22-pre10/arch/arm/boot/compressed/ll_char_wr.S
--- linux-2.4.21/arch/arm/boot/compressed/ll_char_wr.S	2001-04-12 19:03:50.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/ll_char_wr.S	2003-08-01 13:32:01.000000000 +0000
@@ -19,144 +19,116 @@
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-		.text
+	.text
 
-#define BOLD            0x01
-#define ITALIC          0x02
-#define UNDERLINE       0x04
-#define FLASH           0x08
-#define INVERSE         0x10
-
-LC0:		.word	SYMBOL_NAME(bytes_per_char_h)
-		.word	SYMBOL_NAME(video_size_row)
-		.word	SYMBOL_NAME(acorndata_8x8)
-		.word	SYMBOL_NAME(con_charconvtable)
+LC0:	.word	LC0
+	.word	bytes_per_char_h
+	.word	video_size_row
+	.word	acorndata_8x8
+	.word	con_charconvtable
 
+/*
+ * r0 = ptr
+ * r1 = char
+ * r2 = white
+ */
 ENTRY(ll_write_char)
-		stmfd	sp!, {r4 - r7, lr}
+	stmfd	sp!, {r4 - r7, lr}
 @
 @ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc)
 @
-		eor	ip, r1, #UNDERLINE << 9
-/*
- * calculate colours
- */
-		tst	r1, #INVERSE << 9
-		moveq	r2, r1, lsr #16
-		moveq	r3, r1, lsr #24
-		movne	r2, r1, lsr #24
-		movne	r3, r1, lsr #16
-		and	r3, r3, #255
-		and	r2, r2, #255
-/*
- * calculate offset into character table
- */
-		mov	r1, r1, lsl #23
-		mov	r1, r1, lsr #20
-/*
- * calculate offset required for each row [maybe I should make this an argument to this fn.
- * Have to see what the register usage is like in the calling routines.
- */
-		adr	r4, LC0
-		ldmia	r4, {r4, r5, r6, lr}
-		ldr	r4, [r4]
-		ldr	r5, [r5]
-/*
- * Go to resolution-dependent routine...
- */
-		cmp	r4, #4
-		blt	Lrow1bpp
-		eor	r2, r3, r2			@ Create eor mask to change colour from bg
-		orr	r3, r3, r3, lsl #8		@ to fg.
-		orr	r3, r3, r3, lsl #16
-		add	r0, r0, r5, lsl #3		@ Move to bottom of character
-		add	r1, r1, #7
-		ldrb	r7, [r6, r1]
-		tst	ip, #UNDERLINE << 9
-		eoreq	r7, r7, #255
-		teq	r4, #8
-		beq	Lrow8bpplp
+	/*
+	 * calculate offset into character table
+	 */
+	mov	r1, r1, lsl #3
+	/*
+	 * calculate offset required for each row.
+	 */
+	adr	ip, LC0
+	ldmia	ip, {r3, r4, r5, r6, lr}
+	sub	ip, ip, r3
+	add	r6, r6, ip
+	add	lr, lr, ip
+	ldr	r4, [r4, ip]
+	ldr	r5, [r5, ip]
+	/*
+	 * Go to resolution-dependent routine...
+	 */
+	cmp	r4, #4
+	blt	Lrow1bpp
+	add	r0, r0, r5, lsl #3		@ Move to bottom of character
+	orr	r1, r1, #7
+	ldrb	r7, [r6, r1]
+	teq	r4, #8
+	beq	Lrow8bpplp
 @
 @ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
 @
-		orr	r3, r3, r3, lsl #4
-Lrow4bpplp:	ldr	r7, [lr, r7, lsl #2]
-		mul	r7, r2, r7
-		tst	r1, #7				@ avoid using r7 directly after
-		eor	ip, r3, r7
-		str	ip, [r0, -r5]!
-		LOADREGS(eqfd, sp!, {r4 - r7, pc})
-		sub	r1, r1, #1
-		ldrb	r7, [r6, r1]
-		ldr	r7, [lr, r7, lsl #2]
-		mul	r7, r2, r7
-		tst	r1, #7				@ avoid using r7 directly after
-		eor	ip, r3, r7
-		str	ip, [r0, -r5]!
-		subne	r1, r1, #1
-		ldrneb	r7, [r6, r1]
-		bne	Lrow4bpplp
-		LOADREGS(fd, sp!, {r4 - r7, pc})
+Lrow4bpplp:
+	ldr	r7, [lr, r7, lsl #2]
+	mul	r7, r2, r7
+	sub	r1, r1, #1			@ avoid using r7 directly after
+	str	r7, [r0, -r5]!
+	ldrb	r7, [r6, r1]
+	ldr	r7, [lr, r7, lsl #2]
+	mul	r7, r2, r7
+	tst	r1, #7				@ avoid using r7 directly after
+	str	r7, [r0, -r5]!
+	subne	r1, r1, #1
+	ldrneb	r7, [r6, r1]
+	bne	Lrow4bpplp
+	LOADREGS(fd, sp!, {r4 - r7, pc})
 
 @
 @ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
 @
-Lrow8bpplp:	mov	ip, r7, lsr #4
-		ldr	ip, [lr, ip, lsl #2]
-		mul	r4, r2, ip
-		and	ip, r7, #15			@ avoid r4
-		ldr	ip, [lr, ip, lsl #2]		@ avoid r4
-		mul	ip, r2, ip			@ avoid r4
-		eor	r4, r3, r4			@ avoid ip
-		tst	r1, #7				@ avoid ip
-		sub	r0, r0, r5			@ avoid ip
-		eor	ip, r3, ip
-		stmia	r0, {r4, ip}
-		LOADREGS(eqfd, sp!, {r4 - r7, pc})
-		sub	r1, r1, #1
-		ldrb	r7, [r6, r1]
-		mov	ip, r7, lsr #4
-		ldr	ip, [lr, ip, lsl #2]
-		mul	r4, r2, ip
-		and	ip, r7, #15			@ avoid r4
-		ldr	ip, [lr, ip, lsl #2]		@ avoid r4
-		mul	ip, r2, ip			@ avoid r4
-		eor	r4, r3, r4			@ avoid ip
-		tst	r1, #7				@ avoid ip
-		sub	r0, r0, r5			@ avoid ip
-		eor	ip, r3, ip
-		stmia	r0, {r4, ip}
-		subne	r1, r1, #1
-		ldrneb	r7, [r6, r1]
-		bne	Lrow8bpplp
-		LOADREGS(fd, sp!, {r4 - r7, pc})
+Lrow8bpplp:
+	mov	ip, r7, lsr #4
+	ldr	ip, [lr, ip, lsl #2]
+	mul	r4, r2, ip
+	and	ip, r7, #15			@ avoid r4
+	ldr	ip, [lr, ip, lsl #2]		@ avoid r4
+	mul	ip, r2, ip			@ avoid r4
+	sub	r1, r1, #1			@ avoid ip
+	sub	r0, r0, r5			@ avoid ip
+	stmia	r0, {r4, ip}
+	ldrb	r7, [r6, r1]
+	mov	ip, r7, lsr #4
+	ldr	ip, [lr, ip, lsl #2]
+	mul	r4, r2, ip
+	and	ip, r7, #15			@ avoid r4
+	ldr	ip, [lr, ip, lsl #2]		@ avoid r4
+	mul	ip, r2, ip			@ avoid r4
+	tst	r1, #7				@ avoid ip
+	sub	r0, r0, r5			@ avoid ip
+	stmia	r0, {r4, ip}
+	subne	r1, r1, #1
+	ldrneb	r7, [r6, r1]
+	bne	Lrow8bpplp
+	LOADREGS(fd, sp!, {r4 - r7, pc})
 
 @
 @ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc)
 @
-Lrow1bpp:	add	r6, r6, r1
-		ldmia	r6, {r4, r7}
-		tst	ip, #INVERSE << 9
-		mvnne	r4, r4
-		mvnne	r7, r7
-		strb	r4, [r0], r5
-		mov	r4, r4, lsr #8
-		strb	r4, [r0], r5
-		mov	r4, r4, lsr #8
-		strb	r4, [r0], r5
-		mov	r4, r4, lsr #8
-		strb	r4, [r0], r5
-		strb	r7, [r0], r5
-		mov	r7, r7, lsr #8
-		strb	r7, [r0], r5
-		mov	r7, r7, lsr #8
-		strb	r7, [r0], r5
-		mov	r7, r7, lsr #8
-		tst	ip, #UNDERLINE << 9
-		mvneq	r7, r7
-		strb	r7, [r0], r5
-		LOADREGS(fd, sp!, {r4 - r7, pc})
+Lrow1bpp:
+	add	r6, r6, r1
+	ldmia	r6, {r4, r7}
+	strb	r4, [r0], r5
+	mov	r4, r4, lsr #8
+	strb	r4, [r0], r5
+	mov	r4, r4, lsr #8
+	strb	r4, [r0], r5
+	mov	r4, r4, lsr #8
+	strb	r4, [r0], r5
+	strb	r7, [r0], r5
+	mov	r7, r7, lsr #8
+	strb	r7, [r0], r5
+	mov	r7, r7, lsr #8
+	strb	r7, [r0], r5
+	mov	r7, r7, lsr #8
+	strb	r7, [r0], r5
+	LOADREGS(fd, sp!, {r4 - r7, pc})
 
-		.bss
+	.bss
 ENTRY(con_charconvtable)
-		.space	1024
+	.space	1024
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/misc.c linux-2.4.22-pre10/arch/arm/boot/compressed/misc.c
--- linux-2.4.21/arch/arm/boot/compressed/misc.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/misc.c	2003-08-01 13:31:26.000000000 +0000
@@ -22,7 +22,6 @@
 
 #include <asm/uaccess.h>
 #include <asm/arch/uncompress.h>
-#include <asm/proc/uncompress.h>
 
 #ifdef STANDALONE_DEBUG
 #define puts printf
@@ -291,7 +290,6 @@
 	free_mem_ptr_end	= free_mem_ptr_end_p;
 	__machine_arch_type	= arch_id;
 
-	proc_decomp_setup();
 	arch_decomp_setup();
 
 	makecrc();
@@ -315,4 +313,3 @@
 	return 0;
 }
 #endif
-	
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/boot/compressed/vmlinux.lds.in linux-2.4.22-pre10/arch/arm/boot/compressed/vmlinux.lds.in
--- linux-2.4.21/arch/arm/boot/compressed/vmlinux.lds.in	2001-07-02 21:40:14.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/boot/compressed/vmlinux.lds.in	2003-08-01 13:33:07.000000000 +0000
@@ -35,29 +35,26 @@
 
   _etext = .;
 
-  .data : {
-    *(.data)
-  }
-
+  _got_start = .;
+  .got			: { *(.got) }
+  _got_end = .;
+  .got.plt		: { *(.got.plt) }
+  .data			: { *(.data) }
   _edata = .;
 
   . = BSS_START;
   __bss_start = .;
-  .bss : {
-    *(.bss)
-  }
+  .bss			: { *(.bss) }
   _end = .;
 
-  .stack : {
-    *(.stack)
-  }
-
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  .comment 0 : { *(.comment) }
+  .stack (NOLOAD)	: { *(.stack) }
+
+  .stab 0		: { *(.stab) }
+  .stabstr 0		: { *(.stabstr) }
+  .stab.excl 0		: { *(.stab.excl) }
+  .stab.exclstr 0	: { *(.stab.exclstr) }
+  .stab.index 0		: { *(.stab.index) }
+  .stab.indexstr 0	: { *(.stab.indexstr) }
+  .comment 0		: { *(.comment) }
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/common/Makefile linux-2.4.22-pre10/arch/arm/common/Makefile
--- linux-2.4.21/arch/arm/common/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/common/Makefile	2003-08-01 13:33:01.000000000 +0000
@@ -0,0 +1,17 @@
+#
+# Makefile for the linux kernel.
+#
+
+O_TARGET := nopci.o
+
+export-objs := pcipool.o
+
+obj-y   :=
+obj-m   :=
+obj-n   :=
+obj-	:=
+
+obj-$(CONFIG_USB_OHCI_SA1111)   += pcipool.o
+obj-$(CONFIG_USB_OHCI_AT91)	+= pcipool.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/common/pcipool.c linux-2.4.22-pre10/arch/arm/common/pcipool.c
--- linux-2.4.21/arch/arm/common/pcipool.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/common/pcipool.c	2003-08-01 13:34:28.000000000 +0000
@@ -0,0 +1,391 @@
+/*
+  NOTE:
+
+  this code was lifted straight out of drivers/pci/pci.c;
+  when compiling for the Intel StrongARM SA-1110/SA-1111 the
+  usb-ohci.c driver needs these routines even when the architecture
+  has no pci bus...
+*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+
+#include <asm/page.h>
+
+/*
+ * Pool allocator ... wraps the pci_alloc_consistent page allocator, so
+ * small blocks are easily used by drivers for bus mastering controllers.
+ * This should probably be sharing the guts of the slab allocator.
+ */
+
+struct pci_pool {	/* the pool */
+	struct list_head	page_list;
+	spinlock_t		lock;
+	size_t			blocks_per_page;
+	size_t			size;
+	struct pci_dev		*dev;
+	size_t			allocation;
+	char			name [32];
+	wait_queue_head_t	waitq;
+};
+
+struct pci_page {	/* cacheable header for 'allocation' bytes */
+	struct list_head	page_list;
+	void			*vaddr;
+	dma_addr_t		dma;
+	unsigned long		bitmap [0];
+};
+
+#define	POOL_TIMEOUT_JIFFIES	((100 /* msec */ * HZ) / 1000)
+#define	POOL_POISON_BYTE	0xa7
+
+// #define CONFIG_PCIPOOL_DEBUG
+
+static inline const char *slot_name(const struct pci_pool *pool)
+{
+	const struct pci_dev *pdev = pool->dev;
+
+	if (pdev == 0)
+		return "[0]";
+
+	else if (dev_is_sa1111(pdev))
+		return "[SA-1111]";
+	else
+		return pdev->slot_name;
+}
+
+
+/**
+ * pci_pool_create - Creates a pool of pci consistent memory blocks, for dma.
+ * @name: name of pool, for diagnostics
+ * @pdev: pci device that will be doing the DMA
+ * @size: size of the blocks in this pool.
+ * @align: alignment requirement for blocks; must be a power of two
+ * @allocation: returned blocks won't cross this boundary (or zero)
+ * @mem_flags: SLAB_* flags.
+ *
+ * Returns a pci allocation pool with the requested characteristics, or
+ * null if one can't be created.  Given one of these pools, pci_pool_alloc()
+ * may be used to allocate memory.  Such memory will all have "consistent"
+ * DMA mappings, accessible by the device and its driver without using
+ * cache flushing primitives.  The actual size of blocks allocated may be
+ * larger than requested because of alignment.
+ *
+ * If allocation is nonzero, objects returned from pci_pool_alloc() won't
+ * cross that size boundary.  This is useful for devices which have
+ * addressing restrictions on individual DMA transfers, such as not crossing
+ * boundaries of 4KBytes.
+ */
+struct pci_pool *
+pci_pool_create (const char *name, struct pci_dev *pdev,
+	size_t size, size_t align, size_t allocation, int mem_flags)
+{
+	struct pci_pool		*retval;
+
+	if (align == 0)
+		align = 1;
+	if (size == 0)
+		return 0;
+	else if (size < align)
+		size = align;
+	else if ((size % align) != 0) {
+		size += align + 1;
+		size &= ~(align - 1);
+	}
+
+	if (allocation == 0) {
+		if (PAGE_SIZE < size)
+			allocation = size;
+		else
+			allocation = PAGE_SIZE;
+		// FIXME: round up for less fragmentation
+	} else if (allocation < size)
+		return 0;
+
+	if (!(retval = kmalloc (sizeof *retval, mem_flags)))
+		return retval;
+
+	strncpy (retval->name, name, sizeof retval->name);
+	retval->name [sizeof retval->name - 1] = 0;
+
+	retval->dev = pdev;
+	INIT_LIST_HEAD (&retval->page_list);
+	spin_lock_init (&retval->lock);
+	retval->size = size;
+	retval->allocation = allocation;
+	retval->blocks_per_page = allocation / size;
+	init_waitqueue_head (&retval->waitq);
+
+#ifdef CONFIG_PCIPOOL_DEBUG
+	printk (KERN_DEBUG "pcipool create %s/%s size %d, %d/page (%d alloc)\n",
+		slot_name(retval), retval->name, size,
+		retval->blocks_per_page, allocation);
+#endif
+
+	return retval;
+}
+
+
+static struct pci_page *
+pool_alloc_page (struct pci_pool *pool, int mem_flags)
+{
+	struct pci_page	*page;
+	int		mapsize;
+
+	mapsize = pool->blocks_per_page;
+	mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
+	mapsize *= sizeof (long);
+
+	page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags);
+	if (!page)
+		return 0;
+	page->vaddr = pci_alloc_consistent (pool->dev,
+					    pool->allocation,
+					    &page->dma);
+	if (page->vaddr) {
+		memset (page->bitmap, 0xff, mapsize);	// bit set == free
+#ifdef	CONFIG_DEBUG_SLAB
+		memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
+#endif
+		list_add (&page->page_list, &pool->page_list);
+	} else {
+		kfree (page);
+		page = 0;
+	}
+	return page;
+}
+
+
+static inline int
+is_page_busy (int blocks, unsigned long *bitmap)
+{
+	while (blocks > 0) {
+		if (*bitmap++ != ~0UL)
+			return 1;
+		blocks -= BITS_PER_LONG;
+	}
+	return 0;
+}
+
+static void
+pool_free_page (struct pci_pool *pool, struct pci_page *page)
+{
+	dma_addr_t	dma = page->dma;
+
+#ifdef	CONFIG_DEBUG_SLAB
+	memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
+#endif
+	pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma);
+	list_del (&page->page_list);
+	kfree (page);
+}
+
+
+/**
+ * pci_pool_destroy - destroys a pool of pci memory blocks.
+ * @pool: pci pool that will be destroyed
+ *
+ * Caller guarantees that no more memory from the pool is in use,
+ * and that nothing will try to use the pool after this call.
+ */
+void
+pci_pool_destroy (struct pci_pool *pool)
+{
+	unsigned long		flags;
+
+#ifdef CONFIG_PCIPOOL_DEBUG
+	printk (KERN_DEBUG "pcipool destroy %s/%s\n",
+		slot_name(pool), pool->name);
+#endif
+
+	spin_lock_irqsave (&pool->lock, flags);
+	while (!list_empty (&pool->page_list)) {
+		struct pci_page		*page;
+		page = list_entry (pool->page_list.next,
+				struct pci_page, page_list);
+		if (is_page_busy (pool->blocks_per_page, page->bitmap)) {
+			printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n",
+				slot_name(pool), pool->name, page->vaddr);
+			/* leak the still-in-use consistent memory */
+			list_del (&page->page_list);
+			kfree (page);
+		} else
+			pool_free_page (pool, page);
+	}
+	spin_unlock_irqrestore (&pool->lock, flags);
+	kfree (pool);
+}
+
+
+/**
+ * pci_pool_alloc - get a block of consistent memory
+ * @pool: pci pool that will produce the block
+ * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC
+ * @handle: pointer to dma address of block
+ *
+ * This returns the kernel virtual address of a currently unused block,
+ * and reports its dma address through the handle.
+ * If such a memory block can't be allocated, null is returned.
+ */
+void *
+pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
+{
+	unsigned long		flags;
+	struct list_head	*entry;
+	struct pci_page		*page;
+	int			map, block;
+	size_t			offset;
+	void			*retval;
+
+restart:
+	spin_lock_irqsave (&pool->lock, flags);
+	list_for_each (entry, &pool->page_list) {
+		int		i;
+		page = list_entry (entry, struct pci_page, page_list);
+		/* only cachable accesses here ... */
+		for (map = 0, i = 0;
+				i < pool->blocks_per_page;
+				i += BITS_PER_LONG, map++) {
+			if (page->bitmap [map] == 0)
+				continue;
+			block = ffz (~ page->bitmap [map]);
+			if ((i + block) < pool->blocks_per_page) {
+				clear_bit (block, &page->bitmap [map]);
+				offset = (BITS_PER_LONG * map) + block;
+				offset *= pool->size;
+				goto ready;
+			}
+		}
+	}
+	if (!(page = pool_alloc_page (pool, mem_flags))) {
+		if (mem_flags == SLAB_KERNEL) {
+			DECLARE_WAITQUEUE (wait, current);
+
+			current->state = TASK_INTERRUPTIBLE;
+			add_wait_queue (&pool->waitq, &wait);
+			spin_unlock_irqrestore (&pool->lock, flags);
+
+			schedule_timeout (POOL_TIMEOUT_JIFFIES);
+
+			current->state = TASK_RUNNING;
+			remove_wait_queue (&pool->waitq, &wait);
+			goto restart;
+		}
+		retval = 0;
+		goto done;
+	}
+
+	clear_bit (0, &page->bitmap [0]);
+	offset = 0;
+ready:
+	retval = offset + page->vaddr;
+	*handle = offset + page->dma;
+done:
+	spin_unlock_irqrestore (&pool->lock, flags);
+	return retval;
+}
+
+
+static struct pci_page *
+pool_find_page (struct pci_pool *pool, dma_addr_t dma)
+{
+	unsigned long		flags;
+	struct list_head	*entry;
+	struct pci_page		*page;
+
+	spin_lock_irqsave (&pool->lock, flags);
+	list_for_each (entry, &pool->page_list) {
+		page = list_entry (entry, struct pci_page, page_list);
+		if (dma < page->dma)
+			continue;
+		if (dma < (page->dma + pool->allocation))
+			goto done;
+	}
+	page = 0;
+done:
+	spin_unlock_irqrestore (&pool->lock, flags);
+	return page;
+}
+
+
+/**
+ * pci_pool_free - put block back into pci pool
+ * @pool: the pci pool holding the block
+ * @vaddr: virtual address of block
+ * @dma: dma address of block
+ *
+ * Caller promises neither device nor driver will again touch this block
+ * unless it is first re-allocated.
+ */
+void
+pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma)
+{
+	struct pci_page		*page;
+	unsigned long		flags;
+	int			map, block;
+
+	if ((page = pool_find_page (pool, dma)) == 0) {
+		printk (KERN_ERR "pci_pool_free %s/%s, %p/%lx (bad dma)\n",
+			pool->dev ? pool->dev->slot_name : NULL,
+			pool->name, vaddr, (unsigned long) dma);
+		return;
+	}
+
+	block = dma - page->dma;
+	block /= pool->size;
+	map = block / BITS_PER_LONG;
+	block %= BITS_PER_LONG;
+
+#ifdef	CONFIG_DEBUG_SLAB
+	if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
+		printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%lx\n",
+			pool->dev ? pool->dev->slot_name : NULL,
+			pool->name, vaddr, (unsigned long) dma);
+		return;
+	}
+	if (page->bitmap [map] & (1UL << block)) {
+		printk (KERN_ERR "pci_pool_free %s/%s, dma %x already free\n",
+			pool->dev ? pool->dev->slot_name : NULL,
+			pool->name, dma);
+		return;
+	}
+	memset (vaddr, POOL_POISON_BYTE, pool->size);
+#endif
+
+	spin_lock_irqsave (&pool->lock, flags);
+	set_bit (block, &page->bitmap [map]);
+	if (waitqueue_active (&pool->waitq))
+		wake_up (&pool->waitq);
+	/*
+	 * Resist a temptation to do
+	 *    if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page);
+	 * it is not interrupt safe. Better have empty pages hang around.
+	 */
+	spin_unlock_irqrestore (&pool->lock, flags);
+}
+
+
+EXPORT_SYMBOL (pci_pool_create);
+EXPORT_SYMBOL (pci_pool_destroy);
+EXPORT_SYMBOL (pci_pool_alloc);
+EXPORT_SYMBOL (pci_pool_free);
+
+/* **************************************** */
+
+static int __init pcipool_init(void)
+{
+	MOD_INC_USE_COUNT;	/* never unload */
+
+	return 0;
+}
+module_init(pcipool_init);
+
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/config.in linux-2.4.22-pre10/arch/arm/config.in
--- linux-2.4.21/arch/arm/config.in	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/config.in	2003-08-01 13:31:47.000000000 +0000
@@ -2,7 +2,7 @@
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
-mainmenu_name "Linux Kernel Configuration"
+mainmenu_name "ARM Linux Kernel Configuration"
 
 define_bool CONFIG_ARM y
 define_bool CONFIG_EISA n
@@ -39,14 +39,17 @@
  	 CLPS711x/EP721x-based	CONFIG_ARCH_CLPS711X \
 	 Co-EBSA285		CONFIG_ARCH_CO285 \
 	 EBSA-110		CONFIG_ARCH_EBSA110 \
- 	 Epxa10db               CONFIG_ARCH_CAMELOT \
+ 	 Excalibur-ARM          CONFIG_ARCH_CAMELOT \
 	 FootBridge		CONFIG_ARCH_FOOTBRIDGE \
 	 Integrator		CONFIG_ARCH_INTEGRATOR \
+	 Omaha			CONFIG_ARCH_OMAHA \
 	 LinkUp-L7200		CONFIG_ARCH_L7200 \
 	 Motorola-MX1ADS        CONFIG_ARCH_MX1ADS \
 	 RiscPC			CONFIG_ARCH_RPC \
- 	 SA1100-based		CONFIG_ARCH_SA1100 \
-	 Shark			CONFIG_ARCH_SHARK" RiscPC
+	 RiscStation		CONFIG_ARCH_RISCSTATION \
+	 SA1100-based		CONFIG_ARCH_SA1100 \
+	 Shark			CONFIG_ARCH_SHARK \
+	 AT91RM9200-based	CONFIG_ARCH_AT91RM9200 " RiscPC
 
 mainmenu_option next_comment
 comment 'Archimedes/A5000 Implementations'
@@ -69,10 +72,14 @@
 
 mainmenu_option next_comment
 comment 'SA11x0 Implementations'
+dep_bool '  ACCELENT DevBoard' CONFIG_SA1100_ACCELENT $CONFIG_ARCH_SA1100
 dep_bool '  Assabet' CONFIG_SA1100_ASSABET $CONFIG_ARCH_SA1100
 dep_bool '    Include support for Neponset' CONFIG_ASSABET_NEPONSET $CONFIG_SA1100_ASSABET
+dep_bool '  ADS Advanced Graphics Client' CONFIG_SA1100_ADSAGC $CONFIG_ARCH_SA1100
 dep_bool '  ADS Bitsy' CONFIG_SA1100_ADSBITSY $CONFIG_ARCH_SA1100
+dep_bool '  ADS Bitsy Plus' CONFIG_SA1100_ADSBITSYPLUS $CONFIG_ARCH_SA1100
 dep_bool '  Brutus' CONFIG_SA1100_BRUTUS $CONFIG_ARCH_SA1100
+dep_bool '  Cep' CONFIG_SA1100_CEP $CONFIG_ARCH_SA1100
 dep_bool '  CerfBoard' CONFIG_SA1100_CERF $CONFIG_ARCH_SA1100
 if [ "$CONFIG_SA1100_CERF" = "y" ]; then
    choice 'Cerf RAM available' \
@@ -94,6 +101,8 @@
 else
   define_bool CONFIG_SA1100_H3XXX n
 fi
+dep_tristate 'Compaq iPAQ Handheld sleeve support' CONFIG_H3600_SLEEVE $CONFIG_SA1100_H3600
+#dep_bool '  Consus' CONFIG_SA1100_CONSUS $CONFIG_ARCH_SA1100
 #dep_bool '  Empeg' CONFIG_SA1100_EMPEG $CONFIG_ARCH_SA1100
 dep_bool '  Extenex HandHeld Theater (Squashtail)' CONFIG_SA1100_EXTENEX1 $CONFIG_ARCH_SA1100
 if [ "$CONFIG_SA1100_EXTENEX1" = "y" ]; then
@@ -104,6 +113,7 @@
 dep_bool '  Frodo' CONFIG_SA1100_FRODO $CONFIG_ARCH_SA1100
 dep_bool '  GraphicsClient Plus' CONFIG_SA1100_GRAPHICSCLIENT $CONFIG_ARCH_SA1100
 dep_bool '  GraphicsMaster' CONFIG_SA1100_GRAPHICSMASTER $CONFIG_ARCH_SA1100
+dep_bool '  HackKit Core Board' CONFIG_SA1100_HACKKIT $CONFIG_ARCH_SA1100
 dep_bool '  HP Labs BadgePAD 4' CONFIG_SA1100_BADGE4 $CONFIG_ARCH_SA1100
 dep_bool '  HP Jornada 720' CONFIG_SA1100_JORNADA720 $CONFIG_ARCH_SA1100
 dep_bool '  HuW WebPanel' CONFIG_SA1100_HUW_WEBPANEL $CONFIG_ARCH_SA1100
@@ -117,29 +127,23 @@
 dep_bool '  Shannon' CONFIG_SA1100_SHANNON $CONFIG_ARCH_SA1100
 dep_bool '  Sherman' CONFIG_SA1100_SHERMAN $CONFIG_ARCH_SA1100
 dep_bool '  Simpad' CONFIG_SA1100_SIMPAD $CONFIG_ARCH_SA1100
+dep_bool '  Simputer' CONFIG_SA1100_SIMPUTER $CONFIG_ARCH_SA1100
 dep_bool '  Tulsa' CONFIG_SA1100_PFS168 $CONFIG_ARCH_SA1100
 dep_bool '  Victor' CONFIG_SA1100_VICTOR $CONFIG_ARCH_SA1100
 dep_bool '  XP860' CONFIG_SA1100_XP860 $CONFIG_ARCH_SA1100
 dep_bool '  Yopy' CONFIG_SA1100_YOPY $CONFIG_ARCH_SA1100
 
-# Determine if SA1111 support is required
-if [ "$CONFIG_ASSABET_NEPONSET" = "y" -o \
-     "$CONFIG_SA1100_JORNADA720" = "y" -o \
-     "$CONFIG_SA1100_PFS168" = "y" -o \
-     "$CONFIG_SA1100_XP860" = "y" -o \
-     "$CONFIG_SA1100_GRAPHICSMASTER" = "y" -o \
-     "$CONFIG_SA1100_PT_SYSTEM3" = "y" -o \
-     "$CONFIG_SA1100_ADSBITSY" = "y" -o \
-     "$CONFIG_SA1100_BADGE4" = "y" ]; then
-   define_bool CONFIG_SA1111 y
-   define_int CONFIG_FORCE_MAX_ZONEORDER 9
-fi
+dep_tristate 'SA1100 USB function support' CONFIG_SA1100_USB $CONFIG_ARCH_SA1100
+dep_tristate '  Support for SA11x0 USB network link function' CONFIG_SA1100_USB_NETLINK $CONFIG_SA1100_USB
+dep_tristate '  Support for SA11x0 USB character device emulation' CONFIG_SA1100_USB_CHAR $CONFIG_SA1100_USB
 
-#dep_tristate 'SA1100 USB function support' CONFIG_SA1100_USB $CONFIG_ARCH_SA1100
-#dep_tristate '  Support for SA11x0 USB network link function' CONFIG_SA1100_USB_NETLINK $CONFIG_SA1100_USB
-#dep_tristate '  Support for SA11x0 USB character device emulation' CONFIG_SA1100_USB_CHAR $CONFIG_SA1100_USB
+dep_tristate 'SA1100 Generic PIO SSP support' CONFIG_SA1100_SSP $CONFIG_ARCH_SA1100
 
-dep_tristate 'Compaq iPAQ Handheld sleeve support' CONFIG_H3600_SLEEVE $CONFIG_SA1100_H3600
+endmenu
+
+mainmenu_option next_comment
+comment 'AT91RM9200 Implementations'
+dep_bool '  Atmel AT91RM9200 Development Board' CONFIG_ARCH_AT91RM9200DK $CONFIG_ARCH_AT91RM9200
 endmenu
 
 mainmenu_option next_comment
@@ -148,8 +152,10 @@
 dep_bool '  CDB89712' CONFIG_ARCH_CDB89712 $CONFIG_ARCH_CLPS711X
 dep_bool '  CLEP7312' CONFIG_ARCH_CLEP7312 $CONFIG_ARCH_CLPS711X
 dep_bool '  EDB7211' CONFIG_ARCH_EDB7211 $CONFIG_ARCH_CLPS711X
-dep_bool '  P720T' CONFIG_ARCH_P720T $CONFIG_ARCH_CLPS711X
 dep_bool '  FORTUNET' CONFIG_ARCH_FORTUNET $CONFIG_ARCH_CLPS711X
+dep_bool '  GUIDEA07' CONFIG_ARCH_GUIDEA07 $CONFIG_ARCH_CLPS711X
+dep_bool '  P720T' CONFIG_ARCH_P720T $CONFIG_ARCH_CLPS711X
+
 
 # XXX Maybe these should indicate register compatibility
 # instead of being mutually exclusive.
@@ -168,6 +174,11 @@
      "$CONFIG_ARCH_EP7212" = "y" ]; then
    bool '  EP72xx ROM boot' CONFIG_EP72XX_ROM_BOOT
 fi
+
+if [ "$CONFIG_ARCH_GUIDEA07" = "y" ]; then
+   define_bool CONFIG_ARCH_CDB89712 y
+fi
+
 endmenu
 
 # Definitions to make life easier
@@ -178,7 +189,8 @@
    define_bool CONFIG_ARCH_ACORN n
 fi
 
-# see Documentation/arm/ConfigVars for a description of these
+#####################################################################
+# Footbridge support
 if [ "$CONFIG_ARCH_CO285" = "y" -o \
      "$CONFIG_ARCH_FOOTBRIDGE" = "y" ]; then
    define_bool CONFIG_FOOTBRIDGE y
@@ -204,6 +216,42 @@
    define_bool CONFIG_ARCH_EBSA285 y
 fi
 
+#####################################################################
+# SA1111 support
+if [ "$CONFIG_ASSABET_NEPONSET" = "y" -o \
+     "$CONFIG_SA1100_ACCELENT" = "y" -o \
+     "$CONFIG_SA1100_ADSAGC" = "y" -o \
+     "$CONFIG_SA1100_ADSBITSY" = "y" -o \
+     "$CONFIG_SA1100_ADSBITSYPLUS" = "y" -o \
+     "$CONFIG_SA1100_BADGE4" = "y" -o \
+     "$CONFIG_SA1100_CONSUS" = "y" -o \
+     "$CONFIG_SA1100_GRAPHICSMASTER" = "y" -o \
+     "$CONFIG_SA1100_JORNADA720" = "y" -o \
+     "$CONFIG_SA1100_PFS168" = "y" -o \
+     "$CONFIG_SA1100_PT_SYSTEM3" = "y" -o \
+     "$CONFIG_SA1100_XP860" = "y" ]; then
+   define_bool CONFIG_SA1111 y
+   define_int CONFIG_FORCE_MAX_ZONEORDER 9
+fi
+
+if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then
+  choice 'EPXA system type' \
+         "EPXA10DB CONFIG_EPXA10DB \
+          EPXA1DB  CONFIG_EPXA1DB" EPXA10DB
+
+if [ "$CONFIG_EPXA10DB" = "y" ]; then
+  choice 'EPXA10B version' \
+         "SDR CONFIG_EPXA10DB_R2 \
+          DDR CONFIG_EPXA10DB_R3" DDR
+fi
+
+   comment 'PLD hotswap support'
+   define_bool CONFIG_PLD y
+   dep_bool 'Support for PLD device hotplugging' CONFIG_PLD_HOTSWAP $CONFIG_EXPERIMENTAL
+fi
+
+comment 'Processor Type'
+
 # Figure out whether this system uses 26-bit or 32-bit CPUs.
 if [ "$CONFIG_ARCH_ARCA5K" = "y" ]; then
    define_bool CONFIG_CPU_32 n
@@ -214,28 +262,9 @@
    define_bool CONFIG_CPU_26 n
 fi
 
-comment 'Processor Type'
-
-# Firstly, figure out what processor architecture version we should be using.
-if [ "$CONFIG_ARCH_RPC"        = "y" -o "$CONFIG_ARCH_CLPS7500" = "y" ]; then
-   define_bool CONFIG_CPU_32v3 y
-else
-   define_bool CONFIG_CPU_32v3 n
-fi
-if [ "$CONFIG_ARCH_EBSA110"    = "y" -o "$CONFIG_FOOTBRIDGE"    = "y" -o \
-     "$CONFIG_ARCH_TBOX"       = "y" -o "$CONFIG_ARCH_SHARK"    = "y" -o \
-     "$CONFIG_ARCH_NEXUSPCI"   = "y" -o "$CONFIG_ARCH_CLPS711X" = "y" -o \
-     "$CONFIG_ARCH_INTEGRATOR" = "y" -o "$CONFIG_ARCH_SA1100"   = "y" -o \
-     "$CONFIG_ARCH_L7200"      = "y" -o "$CONFIG_ARCH_ANAKIN"	= "y" -o \
-     "$CONFIG_ARCH_CAMELOT"    = "y" -o "$CONFIG_ARCH_MX1ADS"   = "y" ]; then
-   define_bool CONFIG_CPU_32v4 y
-else
-   define_bool CONFIG_CPU_32v4 n
-fi
-
-# Select CPU types depending on the architecture selected.
-# We use this to select which CPUs are supported, and to select
-# the compiler tuning options.
+# Select CPU types depending on the architecture selected.  This selects
+# which CPUs we support in the kernel image, and the compiler instruction
+# optimiser behaviour.
 
 # ARM610
 if [ "$CONFIG_ARCH_RPC" = "y" ]; then
@@ -245,7 +274,8 @@
 fi
 
 # ARM710
-if [ "$CONFIG_ARCH_CLPS7500" = "y" ]; then
+if [ "$CONFIG_ARCH_CLPS7500" = "y" -o \
+     "$CONFIG_ARCH_RISCSTATION" = "y" ]; then
    define_bool CONFIG_CPU_ARM710 y
 else
    if [ "$CONFIG_ARCH_RPC" = "y" ]; then
@@ -269,10 +299,12 @@
 fi
 
 # ARM920T
-if [ "$CONFIG_ARCH_MX1ADS" = "y" ]; then
+if [ "$CONFIG_ARCH_MX1ADS" = "y" -o \
+     "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
    define_bool CONFIG_CPU_ARM920T y
 else
-   if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
+   if [ "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
+	"$CONFIG_ARCH_OMAHA" = "y" ]; then
       bool 'Support ARM920T processor' CONFIG_CPU_ARM920T
    else
       define_bool CONFIG_CPU_ARM920T n
@@ -280,28 +312,13 @@
 fi
 
 
-if [ "$CONFIG_CPU_ARM920T" = "y" ]; then
-   bool '  ARM920T CPU idle' CONFIG_CPU_ARM920_CPU_IDLE
-   bool '  ARM920T I-Cache on' CONFIG_CPU_ARM920_I_CACHE_ON
-   bool '  ARM920T D-Cache on' CONFIG_CPU_ARM920_D_CACHE_ON
-   if [ "$CONFIG_CPU_ARM920_D_CACHE_ON" = "y" ] ; then
-      bool '  Force write through caches on ARM920T' CONFIG_CPU_ARM920_WRITETHROUGH
-   fi
-fi
-
 # ARM922T
 if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then
-         define_bool CONFIG_CPU_ARM922T y
+   define_bool CONFIG_CPU_ARM922T y
+   define_bool CONFIG_PLD y
 else
-         define_bool CONFIG_CPU_ARM922T n
-fi
-if [ "$CONFIG_CPU_ARM922T" = "y" ]; then
-   bool '  ARM922T CPU idle' CONFIG_CPU_ARM922_CPU_IDLE
-   bool '  ARM922T I-Cache on' CONFIG_CPU_ARM922_I_CACHE_ON
-   bool '  ARM922T D-Cache on' CONFIG_CPU_ARM922_D_CACHE_ON
-   if [ "$CONFIG_CPU_ARM922_D_CACHE_ON" = "y" ] ; then
-      bool '  Force write through caches on ARM922T' CONFIG_CPU_ARM922_WRITETHROUGH
-   fi
+   define_bool CONFIG_CPU_ARM922T n
+   define_bool CONFIG_PLD n
 fi
 
 # ARM926T
@@ -310,18 +327,6 @@
 else
    define_bool CONFIG_CPU_ARM926T n
 fi
-if [ "$CONFIG_CPU_ARM926T" = "y" ]; then
-   bool '  ARM926T CPU idle' CONFIG_CPU_ARM926_CPU_IDLE
-   bool '  ARM926T I-Cache on' CONFIG_CPU_ARM926_I_CACHE_ON
-   bool '  ARM926T D-Cache on' CONFIG_CPU_ARM926_D_CACHE_ON
-   if [ "$CONFIG_CPU_ARM926_D_CACHE_ON" = "y" ] ; then
-      bool '  Force write through caches on ARM926T' CONFIG_CPU_ARM926_WRITETHROUGH
-   fi
-   if [ "$CONFIG_CPU_ARM926_I_CACHE_ON" = "y" -o \
-        "$CONFIG_CPU_ARM926_D_CACHE_ON" = "y" ]; then
-      bool '  Round robin I and D cache replacement algorithm' CONFIG_CPU_ARM926_ROUND_ROBIN
-   fi
-fi
 
 # ARM1020
 if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
@@ -329,16 +334,12 @@
 else
     define_bool CONFIG_CPU_ARM1020 n
 fi
-if [ "$CONFIG_CPU_ARM1020" = "y" ]; then
-   bool '  ARM1020 I-Cache on' CONFIG_CPU_ARM1020_I_CACHE_ON
-   bool '  ARM10 D-Cache on' CONFIG_CPU_ARM1020_D_CACHE_ON
-   if [ "$CONFIG_CPU_ARM1020_D_CACHE_ON" = "y" ] ; then
-      bool '  Force write through caches on ARM1020' CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH
-   fi
-   if [ "$CONFIG_CPU_ARM1020_I_CACHE_ON" = "y" -o \
-        "$CONFIG_CPU_ARM1020_D_CACHE_ON" = "y" ]; then
-      bool '  Round robin I and D cache replacement algorithm' CONFIG_CPU_ARM1020_ROUND_ROBIN
-   fi
+
+# ARM1026EJ-S
+if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
+   bool 'Support ARM1026EJ-S processor' CONFIG_CPU_ARM1026
+else
+   define_bool CONFIG_CPU_ARM1026 n
 fi
 
 # SA110
@@ -361,13 +362,59 @@
    define_bool CONFIG_CPU_SA1100 n
 fi
 
-if [ "$CONFIG_CPU_32" = "y" ]; then
-   dep_bool 'Support Thumb instructions (experimental)' CONFIG_ARM_THUMB $CONFIG_EXPERIMENTAL
+# Figure out what processor architecture version we should be using.
+# This defines the compiler instruction set which depends on the machine type.
+
+if [ "$CONFIG_ARCH_RPC"         = "y" -o \
+     "$CONFIG_ARCH_RISCSTATION" = "y" -o \
+     "$CONFIG_ARCH_CLPS7500"    = "y" ]; then
+   define_bool CONFIG_CPU_32v3 y
+else
+   define_bool CONFIG_CPU_32v3 n
+fi
+if [ "$CONFIG_ARCH_EBSA110"    = "y" -o "$CONFIG_FOOTBRIDGE"    = "y" -o \
+     "$CONFIG_ARCH_TBOX"       = "y" -o "$CONFIG_ARCH_SHARK"    = "y" -o \
+     "$CONFIG_ARCH_NEXUSPCI"   = "y" -o "$CONFIG_ARCH_CLPS711X" = "y" -o \
+     "$CONFIG_ARCH_INTEGRATOR" = "y" -o "$CONFIG_ARCH_SA1100"   = "y" -o \
+     "$CONFIG_ARCH_L7200"      = "y" -o "$CONFIG_ARCH_ANAKIN"	= "y" -o \
+     "$CONFIG_ARCH_CAMELOT"    = "y" -o "$CONFIG_ARCH_MX1ADS"   = "y" -o \
+     "$CONFIG_ARCH_OMAHA"      = "y" -o "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
+   define_bool CONFIG_CPU_32v4 y
+else
+   define_bool CONFIG_CPU_32v4 n
+fi
+
+comment 'Processor Features'
+
+if [ "$CONFIG_CPU_ARM720T" = "y" -o "$CONFIG_CPU_ARM920T" = "y" -o \
+     "$CONFIG_CPU_ARM922T" = "y" -o "$CONFIG_CPU_ARM926T" = "y" -o \
+     "$CONFIG_CPU_ARM1020" = "y" -o "$CONFIG_CPU_ARM1026" = "y" ]; then
+   dep_bool 'Support Thumb instructions (EXPERIMENTAL)' CONFIG_ARM_THUMB $CONFIG_EXPERIMENTAL
+fi
+if [ "$CONFIG_CPU_ARM920T" = "y" -o "$CONFIG_CPU_ARM922T" = "y" -o \
+     "$CONFIG_CPU_ARM926T" = "y" -o "$CONFIG_CPU_ARM1020" = "y" -o \
+     "$CONFIG_CPU_ARM1026" = "y" ]; then
+   bool 'Disable I-Cache' CONFIG_CPU_ICACHE_DISABLE
+   bool 'Disable D-Cache' CONFIG_CPU_DCACHE_DISABLE
+   if [ "$CONFIG_CPU_DISABLE_DCACHE" = "n" ]; then
+      bool 'Force write through D-cache' CONFIG_CPU_DCACHE_WRITETHROUGH
+   fi
+fi
+if [ "$CONFIG_CPU_ARM926T" = "y" -o "$CONFIG_CPU_ARM1020" = "y" -o \
+     "$CONFIG_CPU_ARM1026" = "y" ]; then
+   if [ "$CONFIG_CPU_ICACHE_DISABLE" = "n" -o "$CONFIG_CPU_DCACHE_DISABLE" = "n" ]; then
+      bool 'Round robin I and D cache replacement algorithm' CONFIG_CPU_CACHE_ROUND_ROBIN
+   fi
 fi
+if [ "$CONFIG_CPU_ARM1020" = "y" -o "$CONFIG_CPU_ARM1026" = "y" ]; then
+   bool 'Disable branch prediction' CONFIG_CPU_BPREDICT_DISABLE
+fi
+
 
 # Select various configuration options depending on the machine type
 if [ "$CONFIG_ARCH_EDB7211" = "y" -o \
-     "$CONFIG_ARCH_SA1100" = "y" ]; then
+     "$CONFIG_ARCH_SA1100" = "y" -o \
+     "$CONFIG_ARCH_RISCSTATION" = "y" ]; then
    define_bool CONFIG_DISCONTIGMEM y
 else
    define_bool CONFIG_DISCONTIGMEM n
@@ -395,6 +442,7 @@
 if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" -o \
      "$CONFIG_ARCH_SHARK" = "y" -o \
      "$CONFIG_ARCH_CLPS7500" = "y" -o \
+     "$CONFIG_ARCH_RISCSTATION" = "y" -o \
      "$CONFIG_ARCH_EBSA110" = "y" -o \
      "$CONFIG_ARCH_CDB89712" = "y" -o \
      "$CONFIG_ARCH_EDB7211" = "y" -o \
@@ -411,6 +459,12 @@
    define_bool CONFIG_ISA_DMA n
 fi
 
+# Compressed boot loader in ROM.  Yes, we really want to ask about
+# TEXT and BSS so we preserve their values in the config files.
+bool 'Compressed boot loader in ROM/flash' CONFIG_ZBOOT_ROM
+hex 'Compressed ROM boot loader base address' CONFIG_ZBOOT_ROM_TEXT 0
+hex 'Compressed ROM boot loader BSS address' CONFIG_ZBOOT_ROM_BSS 0
+
 if [ "$CONFIG_ARCH_SA1100" = "y" -o \
      "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
    dep_bool 'Support CPU clock change (EXPERIMENTAL)' CONFIG_CPU_FREQ $CONFIG_EXPERIMENTAL
@@ -423,13 +477,23 @@
 else
    define_bool CONFIG_PCMCIA n
 fi
+if [ "$CONFIG_SA1100_ACCELENT" = "y" ]; then
+   if [ "$CONFIG_PCMCIA" != "n" ]; then
+      bool '  Use second PCMCIA/CF slot (disables on-board IDE)' CONFIG_SA_PCMCIA_SLOT_1 y
+   fi
+fi
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
 comment 'At least one math emulation must be selected'
 tristate 'NWFPE math emulation' CONFIG_FPE_NWFPE
-dep_tristate 'FastFPE math emulation (experimental)' CONFIG_FPE_FASTFPE $CONFIG_EXPERIMENTAL
+if [ "$CONFIG_FPE_NWFPE" != "n" ]; then
+  bool '  Support extended precision' CONFIG_FPE_NWFPE_XP
+fi
+if [ "$CONFIG_CPU_26" = "n" -a "$CONFIG_CPU_32v3" = "n" ]; then
+   dep_tristate 'FastFPE math emulation (EXPERIMENTAL)' CONFIG_FPE_FASTFPE $CONFIG_EXPERIMENTAL
+fi
 choice 'Kernel core (/proc/kcore) format' \
 	"ELF		CONFIG_KCORE_ELF	\
 	 A.OUT		CONFIG_KCORE_AOUT" ELF
@@ -438,19 +502,8 @@
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 dep_bool 'Power Management support (experimental)' CONFIG_PM $CONFIG_EXPERIMENTAL
 dep_tristate 'RISC OS personality' CONFIG_ARTHUR $CONFIG_CPU_32
+string 'Default kernel command string' CONFIG_CMDLINE ""
 
-if [ "$CONFIG_ARCH_EBSA110" = "y" -o         \
-     "$CONFIG_ARCH_SA1100" = "y" -o          \
-     "$CONFIG_ARCH_CLPS7500" = "y" -o        \
-     "$CONFIG_ARCH_PERSONAL_SERVER" = "y" -o \
-     "$CONFIG_ARCH_CATS" = "y" -o            \
-     "$CONFIG_ARCH_P720T" = "y" -o	     \
-     "$CONFIG_ARCH_CDB89712" = "y" -o	     \
-     "$CONFIG_ARCH_CAMELOT" = "y" -o	     \
-     "$CONFIG_ARCH_ANAKIN" = "y"  -o         \
-     "$CONFIG_ARCH_MX1ADS" = "y" ]; then
-   string 'Default kernel command string' CONFIG_CMDLINE ""
-fi
 if [ "$CONFIG_ARCH_NETWINDER" = "y" -o  \
      "$CONFIG_ARCH_EBSA110" = "y" -o    \
      "$CONFIG_ARCH_EBSA285" = "y" -o    \
@@ -460,7 +513,8 @@
      "$CONFIG_ARCH_SA1100" = "y" -o     \
      "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
      "$CONFIG_ARCH_CDB89712" = "y" -o   \
-     "$CONFIG_ARCH_P720T" = "y" ]; then
+     "$CONFIG_ARCH_P720T" = "y" -o	\
+     "$CONFIG_ARCH_OMAHA" = "y" ]; then
    bool 'Timer and CPU usage LEDs' CONFIG_LEDS
    if [ "$CONFIG_LEDS" = "y" ]; then
       if [ "$CONFIG_ARCH_NETWINDER" = "y" -o  \
@@ -469,17 +523,24 @@
 	   "$CONFIG_ARCH_CO285" = "y" -o      \
 	   "$CONFIG_ARCH_SA1100" = "y" -o     \
            "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
-	   "$CONFIG_ARCH_P720T" = "y" ]; then
+	   "$CONFIG_ARCH_P720T" = "y" -o      \
+	   "$CONFIG_ARCH_OMAHA" = "y" ]; then
          bool '  Timer LED' CONFIG_LEDS_TIMER
          bool '  CPU usage LED' CONFIG_LEDS_CPU
       fi
-   fi
-   if [ "$CONFIG_ARCH_EBSA110" = "y" ]; then
-      define_bool CONFIG_LEDS_TIMER y
+      if [ "$CONFIG_ARCH_EBSA110" = "y" ]; then
+         define_bool CONFIG_LEDS_TIMER y
+      fi
    fi
 fi
-if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
-   bool 'Kernel-mode alignment trap handler' CONFIG_ALIGNMENT_TRAP
+if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
+   define_bool CONFIG_ALIGNMENT_TRAP y
+else
+   if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
+      bool 'Kernel-mode alignment trap handler' CONFIG_ALIGNMENT_TRAP
+   else
+      define_bool CONFIG_ALIGNMENT_TRAP n
+   fi
 fi
 endmenu
 
@@ -487,6 +548,8 @@
 
 if [ "$CONFIG_ALIGNMENT_TRAP" = "y" ]; then
   source drivers/mtd/Config.in
+else
+  define_bool CONFIG_MTD n
 fi
 
 source drivers/pnp/Config.in
@@ -515,9 +578,9 @@
 fi
 
 mainmenu_option next_comment
-comment 'ATA/IDE/MFM/RLL support'
+comment 'ATA/ATAPI/MFM/RLL support'
 
-tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+tristate 'ATA/ATAPI/MFM/RLL support' CONFIG_IDE
 
 if [ "$CONFIG_IDE" != "n" ]; then
   source drivers/ide/Config.in
@@ -538,7 +601,8 @@
 endmenu
 
 if [ "$CONFIG_ARCH_CLPS711X" = "y" ]; then
-   source drivers/scsi/Config.in
+   # This is _meant_ to be ssi _not_ scsi.  It is not a spelling error.
+   source drivers/ssi/Config.in
 fi
 
 source drivers/ieee1394/Config.in
@@ -602,7 +666,7 @@
 	"$CONFIG_ARCH_MX1ADS" = "y" ]; then
       define_bool CONFIG_PC_KEYMAP y
    fi
-   if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
+   if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" -a "$CONFIG_ARCH_RISCSTATION" != "y" ]; then
       bool 'VGA text console' CONFIG_VGA_CONSOLE
    fi
    source drivers/video/Config.in
@@ -611,6 +675,7 @@
 
 if [ "$CONFIG_ARCH_ACORN" = "y" -o \
      "$CONFIG_ARCH_CLPS7500" = "y" -o \
+     "$CONFIG_ARCH_RISCSTATION" = "y" -o \
      "$CONFIG_ARCH_TBOX" = "y" -o \
      "$CONFIG_ARCH_SHARK" = "y" -o \
      "$CONFIG_ARCH_SA1100" = "y" -o \
@@ -618,7 +683,7 @@
    mainmenu_option next_comment
    comment 'Sound'
 
-   tristate 'Sound card support' CONFIG_SOUND
+   tristate 'Sound support' CONFIG_SOUND
    if [ "$CONFIG_SOUND" != "n" ]; then
       source drivers/sound/Config.in
    fi
@@ -629,7 +694,9 @@
 
 source drivers/usb/Config.in
 
-source net/bluetooth/Config.in
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   source net/bluetooth/Config.in
+fi
 
 mainmenu_option next_comment
 comment 'Kernel hacking'
@@ -638,7 +705,16 @@
 # you know what you are doing and are willing to live without stack traces, you
 # can get a slightly smaller kernel by setting this option to n, but then RMK
 # will have to kill you ;).
-define_bool CONFIG_FRAME_POINTER y
+if [ "$CONFIG_ARCH_OMAHA" = "y" ]; then
+    # 
+    # Note: We want all the performance we can get, so this means
+    # we accept the debugging limitations of setting CONFIG_FRAME_POINTER=n
+    # -- ahaigh@arm.com (23 August 2002)
+    define_bool CONFIG_FRAME_POINTER n
+else
+    define_bool CONFIG_FRAME_POINTER y
+fi
+
 bool 'Verbose user fault messages' CONFIG_DEBUG_USER
 bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO
 dep_bool 'Disable pgtable cache' CONFIG_NO_PGT_CACHE $CONFIG_CPU_26
@@ -650,10 +726,11 @@
 dep_bool '  Wait queue debugging' CONFIG_DEBUG_WAITQ $CONFIG_DEBUG_KERNEL
 dep_bool '  Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE $CONFIG_DEBUG_KERNEL
 dep_bool '  Verbose kernel error messages' CONFIG_DEBUG_ERRORS $CONFIG_DEBUG_KERNEL
-# These options are only for real kernel hackers who want to get their hands dirty. 
+# These options are only for real kernel hackers who want to get their hands dirty.
 dep_bool '  Kernel low-level debugging functions' CONFIG_DEBUG_LL $CONFIG_DEBUG_KERNEL
 dep_bool '    Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
 dep_bool '    Kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/accelent_sa linux-2.4.22-pre10/arch/arm/def-configs/accelent_sa
--- linux-2.4.21/arch/arm/def-configs/accelent_sa	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/accelent_sa	2003-08-01 13:31:48.000000000 +0000
@@ -0,0 +1,1099 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+CONFIG_SA1100_ACCELENT=y
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+CONFIG_SA1111=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+CONFIG_SA1100_USB=m
+CONFIG_SA1100_USB_NETLINK=m
+CONFIG_SA1100_USB_CHAR=m
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+
+#
+# Processor Type
+#
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=C0400000
+CONFIG_ZBOOT_ROM_BSS=C0200000
+CONFIG_CPU_FREQ=y
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
+CONFIG_PCMCIA_SA1100=m
+# CONFIG_SA_PCMCIA_SLOT_1 is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PM=y
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=1f02"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+# CONFIG_PARPORT_PC is not set
+CONFIG_PARPORT_IDP=m
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_1284 is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_B1 is not set
+# CONFIG_MTD_CFI_B2 is not set
+CONFIG_MTD_CFI_B4=y
+# CONFIG_MTD_CFI_B8 is not set
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+CONFIG_CS89x0=y
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=m
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+# CONFIG_NET_PCMCIA_RADIO is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+# CONFIG_IRNET is not set
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+CONFIG_IRPORT_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_NSC_FIR is not set
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
+CONFIG_SA1100_FIR=m
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_SCSI_PCMCIA is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=115200
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SA1111_PS2_KEYB=y
+CONFIG_ASI_KEYBOARD=y
+# CONFIG_RTC_ASI is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+CONFIG_L3=y
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+CONFIG_L3_SA1111=y
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=m
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_21285_WATCHDOG is not set
+# CONFIG_977_WATCHDOG is not set
+CONFIG_SA1100_WATCHDOG=m
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_SA1100_RTC=m
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_PCMCIA_SERIAL_CS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=m
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=m
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_CRAMFS=m
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=m
+# CONFIG_SYSV_FS is not set
+CONFIG_UDF_FS=m
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=m
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=m
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_SMB_NLS=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+CONFIG_PC_KEYMAP=y
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+CONFIG_FB_SA1100=y
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_SA1100=y
+CONFIG_SOUND_UDA1341=y
+# CONFIG_SOUND_ASSABET_UDA1341 is not set
+# CONFIG_SOUND_H3600_UDA1341 is not set
+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
+CONFIG_SOUND_SA1111_UDA1341=y
+# CONFIG_SOUND_SA1100SSP is not set
+# CONFIG_SOUND_SA1111_AC97 is not set
+# CONFIG_SOUND_SA1111_AC97_RATE_CONVERSION is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+CONFIG_MCP=y
+CONFIG_MCP_SA1100=y
+CONFIG_MCP_UCB1200=y
+CONFIG_MCP_UCB1200_AUDIO=m
+CONFIG_MCP_UCB1200_TS=m
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+CONFIG_USB_OHCI_SA1111=m
+CONFIG_USB_SL811HS=m
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=m
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+CONFIG_USB_USBNET=m
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_WAITQ=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/adsagc linux-2.4.22-pre10/arch/arm/def-configs/adsagc
--- linux-2.4.21/arch/arm/def-configs/adsagc	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/adsagc	2003-08-01 13:34:42.000000000 +0000
@@ -0,0 +1,1101 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+CONFIG_SA1100_ADSAGC=y
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_SA1111=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_CPU_FREQ is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
+CONFIG_PCMCIA_SA1100=y
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PM=y
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttySA0 mem=16m@0xC0000000 mem=16m@0xC8000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=8000000
+CONFIG_MTD_PHYSMAP_LEN=4000000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=4
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+# CONFIG_ULTRAMCA is not set
+# CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
+# CONFIG_SMC9194 is not set
+CONFIG_SMC91111=y
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_HERMES is not set
+
+#
+# Wireless Pcmcia cards support
+#
+# CONFIG_PCMCIA_HERMES is not set
+# CONFIG_AIRO_CS is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+# CONFIG_NET_PCMCIA_RADIO is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+CONFIG_BLK_DEV_IDECS=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_KEYBDEV is not set
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=38400
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_TOUCHSCREEN_ADS784X=y
+# CONFIG_UCB1200 is not set
+# CONFIG_TOUCHSCREEN_UCB1200 is not set
+# CONFIG_AUDIO_UCB1200 is not set
+# CONFIG_ADC_UCB1200 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_ADSSIO_I2C_ALGO=y
+# CONFIG_I2C_CHARDEV is not set
+# CONFIG_I2C_PROC is not set
+CONFIG_I2C_DS1307=y
+CONFIG_I2C_DS1307_ADS=y
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_SA1100_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_CRAMFS=y
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=y
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+CONFIG_PC_KEYMAP=y
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+# CONFIG_FB_SA1100 is not set
+# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_E13806=y
+CONFIG_E13806_REG_BASE=48000000
+CONFIG_E13806_FB_BASE=48200000
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+CONFIG_FBCON_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_SA1100=y
+# CONFIG_SOUND_UDA1341 is not set
+# CONFIG_SOUND_ASSABET_UDA1341 is not set
+# CONFIG_SOUND_H3600_UDA1341 is not set
+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
+# CONFIG_SOUND_SA1111_UDA1341 is not set
+CONFIG_SOUND_SA1111_AC97=y
+# CONFIG_SOUND_SA1100SSP is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMFPCI is not set
+# CONFIG_SOUND_YMFPCI_LEGACY is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+CONFIG_USB_OHCI_SA1111=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/adsbitsy linux-2.4.22-pre10/arch/arm/def-configs/adsbitsy
--- linux-2.4.21/arch/arm/def-configs/adsbitsy	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/adsbitsy	2003-08-01 13:34:01.000000000 +0000
@@ -1,5 +1,5 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
 #
 CONFIG_ARM=y
 # CONFIG_EISA is not set
@@ -8,6 +8,8 @@
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
 
 #
 # Code maturity level options
@@ -31,16 +33,25 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
 # CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
 CONFIG_ARCH_SA1100=y
 # CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
 
 #
 # Archimedes/A5000 Implementations
 #
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
 # CONFIG_ARCH_ARC is not set
 # CONFIG_ARCH_A5K is not set
 
@@ -56,15 +67,27 @@
 #
 # SA11x0 Implementations
 #
+# CONFIG_SA1100_ACCELENT is not set
 # CONFIG_SA1100_ASSABET is not set
 # CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+CONFIG_SA1100_ADSBITSY=y
+# CONFIG_SA1100_ADSBITSYPLUS is not set
 # CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
 # CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_BITSY is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
 # CONFIG_SA1100_EXTENEX1 is not set
 # CONFIG_SA1100_FLEXANET is not set
 # CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
 # CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HUW_WEBPANEL is not set
 # CONFIG_SA1100_ITSY is not set
@@ -73,40 +96,61 @@
 # CONFIG_SA1100_OMNIMETER is not set
 # CONFIG_SA1100_PANGOLIN is not set
 # CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
 # CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
 # CONFIG_SA1100_XP860 is not set
 # CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-CONFIG_SA1100_ADSBITSY=y
-CONFIG_SA1111=y
 # CONFIG_SA1100_USB is not set
 # CONFIG_SA1100_USB_NETLINK is not set
 # CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
 
 #
 # CLPS711X/EP721X Implementations
 #
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
 # CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
 # CONFIG_ARCH_ACORN is not set
 # CONFIG_FOOTBRIDGE is not set
 # CONFIG_FOOTBRIDGE_HOST is not set
 # CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_SA1111=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+
+#
+# Processor Type
+#
 CONFIG_CPU_32=y
 # CONFIG_CPU_26 is not set
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
 # CONFIG_CPU_ARM610 is not set
 # CONFIG_CPU_ARM710 is not set
 # CONFIG_CPU_ARM720T is not set
 # CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
 # CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
 # CONFIG_CPU_SA110 is not set
 CONFIG_CPU_SA1100=y
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
 CONFIG_DISCONTIGMEM=y
-# CONFIG_CPU_BIG_ENDIAN is not set
 
 #
 # General setup
@@ -114,6 +158,9 @@
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
 # CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
 # CONFIG_CPU_FREQ is not set
 CONFIG_HOTPLUG=y
 
@@ -121,6 +168,8 @@
 # PCMCIA/CardBus support
 #
 CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 # CONFIG_TCIC is not set
 # CONFIG_PCMCIA_CLPS6700 is not set
@@ -129,6 +178,10 @@
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
 CONFIG_FPE_NWFPE=y
 # CONFIG_FPE_FASTFPE is not set
 CONFIG_KCORE_ELF=y
@@ -136,12 +189,12 @@
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_PM is not set
-# CONFIG_APM is not set
+CONFIG_PM=y
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="ip=off"
-# CONFIG_PFS168_CMDLINE is not set
-# CONFIG_LEDS is not set
+CONFIG_CMDLINE="console=ttySA0 mem=32m@0xC0000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+# CONFIG_LEDS_CPU is not set
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -152,7 +205,79 @@
 #
 # Memory Technology Devices (MTD)
 #
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=8000000
+CONFIG_MTD_PHYSMAP_LEN=4000000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=4
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
 
 #
 # Plug and Play configuration
@@ -168,7 +293,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -184,6 +311,7 @@
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_BLK_DEV_LVM is not set
 
 #
@@ -191,7 +319,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -204,13 +332,24 @@
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -228,6 +367,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -240,19 +384,27 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+# CONFIG_ULTRAMCA is not set
+# CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
+# CONFIG_SMC9194 is not set
+CONFIG_SMC91111=y
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_NET_ISA is not set
 # CONFIG_NET_PCI is not set
@@ -262,21 +414,44 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
 # CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
-# CONFIG_PPP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
 
 #
 # Wireless LAN (non-hamradio)
 #
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_HERMES is not set
+
+#
+# Wireless Pcmcia cards support
+#
+# CONFIG_PCMCIA_HERMES is not set
+# CONFIG_AIRO_CS is not set
+CONFIG_NET_WIRELESS=y
 
 #
 # Token Ring devices
@@ -299,6 +474,7 @@
 # CONFIG_PCMCIA_3C574 is not set
 # CONFIG_PCMCIA_FMVJ18X is not set
 CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_AXNET is not set
 # CONFIG_PCMCIA_NMCLAN is not set
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
@@ -317,7 +493,7 @@
 # CONFIG_IRDA is not set
 
 #
-# ATA/IDE/MFM/RLL support
+# ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
 
@@ -325,10 +501,15 @@
 # IDE, ATA and ATAPI Block devices
 #
 CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
 # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
 # CONFIG_BLK_DEV_IDEDISK_IBM is not set
@@ -343,6 +524,11 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
@@ -350,6 +536,9 @@
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_DMA_NONPCI is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
 
 #
 # SCSI support
@@ -385,35 +574,47 @@
 # Character devices
 #
 CONFIG_VT=y
-# CONFIG_VT_CONSOLE is not set
+CONFIG_VT_CONSOLE=y
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
 # CONFIG_SERIAL_AMBA is not set
 # CONFIG_SERIAL_AMBA_CONSOLE is not set
 # CONFIG_SERIAL_CLPS711X is not set
 # CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
 CONFIG_SERIAL_SA1100=y
 CONFIG_SERIAL_SA1100_CONSOLE=y
 CONFIG_SA1100_DEFAULT_BAUDRATE=38400
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
 # CONFIG_SERIAL_8250 is not set
 # CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
+# CONFIG_TOUCHSCREEN_ADS784X is not set
 CONFIG_UCB1200=y
 CONFIG_TOUCHSCREEN_UCB1200=y
 CONFIG_AUDIO_UCB1200=y
 CONFIG_ADC_UCB1200=y
-# CONFIG_TOUCHSCREEN_BITSY is not set
-# CONFIG_PROFILER is not set
-# CONFIG_PFS168_SPI is not set
-# CONFIG_PFS168_DTMF is not set
-# CONFIG_PFS168_MISC is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
 
 #
 # I2C support
@@ -421,6 +622,19 @@
 # CONFIG_I2C is not set
 
 #
+# L3 serial bus support
+#
+CONFIG_L3=y
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+CONFIG_L3_SA1111=y
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
 # Mice
 #
 # CONFIG_BUSMOUSE is not set
@@ -429,14 +643,43 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
 # CONFIG_QIC02_TAPE is not set
 
 #
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_SA1100_RTC is not set
@@ -468,23 +711,29 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
 CONFIG_FAT_FS=y
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
 CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_CRAMFS=y
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -509,6 +758,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
@@ -526,6 +776,8 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=y
 
 #
 # Partition Types
@@ -560,6 +812,7 @@
 # CONFIG_NLS_CODEPAGE_949 is not set
 # CONFIG_NLS_CODEPAGE_874 is not set
 # CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
 # CONFIG_NLS_ISO8859_1 is not set
 # CONFIG_NLS_ISO8859_2 is not set
@@ -588,11 +841,11 @@
 CONFIG_FB=y
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
 # CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_CYBER2000 is not set
 CONFIG_FB_SA1100=y
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_E1355 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_E13806 is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB2=y
@@ -610,50 +863,169 @@
 #
 # Sound
 #
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_SA1100=y
+CONFIG_SOUND_UDA1341=y
+# CONFIG_SOUND_ASSABET_UDA1341 is not set
+# CONFIG_SOUND_H3600_UDA1341 is not set
+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
+CONFIG_SOUND_SA1111_UDA1341=y
+# CONFIG_SOUND_SA1111_AC97 is not set
+# CONFIG_SOUND_SA1100SSP is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
 
 #
 # USB support
 #
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_UHCI is not set
 # CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=y
-CONFIG_USB_OHCI_NOPCI=y
+# CONFIG_USB_OHCI is not set
+CONFIG_USB_OHCI_SA1111=y
+
+#
+# USB Device Class drivers
+#
 # CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
-# CONFIG_USB_HID is not set
-# CONFIG_USB_KBD is not set
-CONFIG_USB_MOUSE=y
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDDEV is not set
 # CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
 # CONFIG_USB_DC2XX is not set
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_SCANNER is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
 # CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_NET1080 is not set
+# CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
 # CONFIG_USB_USS720 is not set
 
 #
 # USB Serial Converter support
 #
 # CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
 # CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
 
 #
 # Bluetooth support
@@ -664,11 +1036,16 @@
 # Kernel hacking
 #
 CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_LL is not set
 # CONFIG_DEBUG_DC21285_PORT is not set
 # CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/adsbitsyplus linux-2.4.22-pre10/arch/arm/def-configs/adsbitsyplus
--- linux-2.4.21/arch/arm/def-configs/adsbitsyplus	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/adsbitsyplus	2003-08-01 13:33:32.000000000 +0000
@@ -0,0 +1,1087 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+CONFIG_SA1100_ADSBITSYPLUS=y
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_SA1111=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_CPU_FREQ is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
+CONFIG_PCMCIA_SA1100=y
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PM=y
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttySA0 mem=32m@0xC0000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+# CONFIG_LEDS_CPU is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=8000000
+CONFIG_MTD_PHYSMAP_LEN=4000000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=4
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+# CONFIG_ULTRAMCA is not set
+# CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
+# CONFIG_SMC9194 is not set
+CONFIG_SMC91111=y
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_HERMES is not set
+
+#
+# Wireless Pcmcia cards support
+#
+# CONFIG_PCMCIA_HERMES is not set
+# CONFIG_AIRO_CS is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+# CONFIG_NET_PCMCIA_RADIO is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+CONFIG_BLK_DEV_IDECS=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_KEYBDEV is not set
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=38400
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_TOUCHSCREEN_ADS784X=y
+# CONFIG_UCB1200 is not set
+# CONFIG_TOUCHSCREEN_UCB1200 is not set
+# CONFIG_AUDIO_UCB1200 is not set
+# CONFIG_ADC_UCB1200 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_ADSSIO_I2C_ALGO=y
+# CONFIG_I2C_CHARDEV is not set
+# CONFIG_I2C_PROC is not set
+CONFIG_I2C_DS1307=y
+CONFIG_I2C_DS1307_ADS=y
+
+#
+# L3 serial bus support
+#
+CONFIG_L3=y
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+CONFIG_L3_SA1111=y
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_SA1100_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_CRAMFS=y
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=y
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+CONFIG_PC_KEYMAP=y
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+CONFIG_FB_SA1100=y
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_E13806 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+CONFIG_FBCON_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_SA1100=y
+# CONFIG_SOUND_UDA1341 is not set
+# CONFIG_SOUND_ASSABET_UDA1341 is not set
+# CONFIG_SOUND_H3600_UDA1341 is not set
+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
+# CONFIG_SOUND_SA1111_UDA1341 is not set
+CONFIG_SOUND_SA1111_AC97=y
+# CONFIG_SOUND_SA1100SSP is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMFPCI is not set
+# CONFIG_SOUND_YMFPCI_LEGACY is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+CONFIG_USB_OHCI_SA1111=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/at91rm9200dk linux-2.4.22-pre10/arch/arm/def-configs/at91rm9200dk
--- linux-2.4.21/arch/arm/def-configs/at91rm9200dk	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/at91rm9200dk	2003-08-01 13:33:16.000000000 +0000
@@ -0,0 +1,773 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+CONFIG_ARCH_AT91RM9200=y
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ACCELENT is not set
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_H3600_SLEEVE is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_SA1100_SSP is not set
+
+#
+# AT91RM9200 Implementations
+#
+CONFIG_ARCH_AT91RM9200DK=y
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_GUIDEA07 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+CONFIG_CPU_ARM920T=y
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20210000,3145728 root=/dev/ram rw"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=10000000
+CONFIG_MTD_PHYSMAP_LEN=200000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=2
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+CONFIG_MTD_AT91_DATAFLASH=y
+# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_AT91_SMARTMEDIA=y
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
+CONFIG_AT91_ETHER=y
+CONFIG_AT91_ETHER_RMII=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_AT91_SPIDEV=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+CONFIG_SERIAL_AT91=y
+CONFIG_SERIAL_AT91_CONSOLE=y
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_AT91=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PROC=y
+# CONFIG_I2C_DS1307 is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_21285_WATCHDOG is not set
+# CONFIG_977_WATCHDOG is not set
+# CONFIG_SA1100_WATCHDOG is not set
+# CONFIG_OMAHA_WATCHDOG is not set
+CONFIG_AT91_WATCHDOG=y
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_WAFER_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_AT91_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+CONFIG_USB_OHCI_AT91=y
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_HID is not set
+# CONFIG_USB_HIDINPUT is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/cep linux-2.4.22-pre10/arch/arm/def-configs/cep
--- linux-2.4.21/arch/arm/def-configs/cep	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/cep	2003-08-01 13:34:28.000000000 +0000
@@ -0,0 +1,615 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+CONFIG_SA1100_CEP=y
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttySA0,9600 root=/dev/ram"
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=9600
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_SA1100_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Console drivers
+#
+CONFIG_PC_KEYMAP=y
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_RIO500 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/epxa10db linux-2.4.22-pre10/arch/arm/def-configs/epxa10db
--- linux-2.4.21/arch/arm/def-configs/epxa10db	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/epxa10db	2003-08-01 13:32:14.000000000 +0000
@@ -8,6 +8,8 @@
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
 
 #
 # Code maturity level options
@@ -34,10 +36,14 @@
 CONFIG_ARCH_CAMELOT=y
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
 # CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
 
 #
 # Archimedes/A5000 Implementations
@@ -57,17 +63,25 @@
 #
 # SA11x0 Implementations
 #
+# CONFIG_SA1100_ACCELENT is not set
 # CONFIG_SA1100_ASSABET is not set
 # CONFIG_ASSABET_NEPONSET is not set
 # CONFIG_SA1100_ADSBITSY is not set
 # CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
 # CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
 # CONFIG_SA1100_EXTENEX1 is not set
 # CONFIG_SA1100_FLEXANET is not set
 # CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
 # CONFIG_SA1100_GRAPHICSCLIENT is not set
 # CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HUW_WEBPANEL is not set
 # CONFIG_SA1100_ITSY is not set
@@ -76,42 +90,59 @@
 # CONFIG_SA1100_OMNIMETER is not set
 # CONFIG_SA1100_PANGOLIN is not set
 # CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
 # CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
 # CONFIG_SA1100_XP860 is not set
 # CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
 
 #
 # CLPS711X/EP721X Implementations
 #
+# CONFIG_ARCH_AUTCPU12 is not set
 # CONFIG_ARCH_CDB89712 is not set
 # CONFIG_ARCH_CLEP7312 is not set
 # CONFIG_ARCH_EDB7211 is not set
 # CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
 # CONFIG_ARCH_EP7211 is not set
 # CONFIG_ARCH_EP7212 is not set
 # CONFIG_ARCH_ACORN is not set
 # CONFIG_FOOTBRIDGE is not set
 # CONFIG_FOOTBRIDGE_HOST is not set
 # CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_EPXA10DB=y
+# CONFIG_EPXA1DB is not set
+# CONFIG_EPXA10DB_R2 is not set
+CONFIG_EPXA10DB_R3=y
+CONFIG_PLD=y
+# CONFIG_PLD_HOTSWAP is not set
 CONFIG_CPU_32=y
 # CONFIG_CPU_26 is not set
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
 # CONFIG_CPU_ARM610 is not set
 # CONFIG_CPU_ARM710 is not set
 # CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
 CONFIG_CPU_ARM922T=y
-CONFIG_CPU_ARM92X_CPU_IDLE=y
-CONFIG_CPU_ARM92X_I_CACHE_ON=y
-CONFIG_CPU_ARM92X_D_CACHE_ON=y
-# CONFIG_CPU_ARM92X_WRITETHROUGH is not set
+CONFIG_PLD=y
+# CONFIG_CPU_ARM926T is not set
 # CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
 # CONFIG_CPU_SA110 is not set
 # CONFIG_CPU_SA1100 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
 # CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_DISCONTIGMEM is not set
 
 #
@@ -120,6 +151,9 @@
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
 # CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
 CONFIG_NET=y
@@ -130,7 +164,7 @@
 # CONFIG_FPE_FASTFPE is not set
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
@@ -150,8 +184,9 @@
 CONFIG_MTD_DEBUG=y
 CONFIG_MTD_DEBUG_VERBOSE=0
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_BOOTLDR_PARTS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AFS_PARTS is not set
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
@@ -171,42 +206,32 @@
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
 # CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_SUN_UFLASH is not set
 # CONFIG_MTD_NORA is not set
-# CONFIG_MTD_PNC2000 is not set
-# CONFIG_MTD_RPXLITE is not set
-# CONFIG_MTD_TQM8XXL is not set
-# CONFIG_MTD_SC520CDP is not set
-# CONFIG_MTD_NETSC520 is not set
-# CONFIG_MTD_SBC_GXX is not set
-# CONFIG_MTD_ELAN_104NC is not set
-# CONFIG_MTD_DBOX2 is not set
-# CONFIG_MTD_CSTM_MIPS_IXX is not set
-CONFIG_MTD_EPXA10DB=y
-# CONFIG_MTD_CFI_FLAGADM is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
-# CONFIG_MTD_MIXMEM is not set
-# CONFIG_MTD_OCTAGON is not set
-# CONFIG_MTD_VMAX is not set
-# CONFIG_MTD_OCELOT is not set
-# CONFIG_MTD_L440GX is not set
 # CONFIG_MTD_ARM_INTEGRATOR is not set
 # CONFIG_MTD_CDB89712 is not set
 # CONFIG_MTD_SA1100 is not set
 # CONFIG_MTD_DC21285 is not set
 # CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+CONFIG_MTD_EPXA=y
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
 
 #
 # Self-contained MTD device drivers
 #
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_LART is not set
 # CONFIG_MTD_MTDRAM is not set
 # CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_DOC1000 is not set
@@ -224,7 +249,6 @@
 #
 # CONFIG_PNP is not set
 # CONFIG_ISAPNP is not set
-# CONFIG_PNPBIOS is not set
 
 #
 # Block devices
@@ -234,7 +258,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -250,6 +276,7 @@
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_BLK_DEV_LVM is not set
 
 #
@@ -257,7 +284,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -270,13 +297,20 @@
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -294,6 +328,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -306,16 +345,18 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
 CONFIG_ETHER00=y
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -335,6 +376,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -343,8 +385,8 @@
 # CONFIG_PPP_FILTER is not set
 CONFIG_PPP_ASYNC=y
 CONFIG_PPP_SYNC_TTY=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
 # CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
 
@@ -377,7 +419,7 @@
 # CONFIG_IRDA is not set
 
 #
-# ATA/IDE/MFM/RLL support
+# ATA/ATAPI/MFM/RLL support
 #
 # CONFIG_IDE is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
@@ -435,6 +477,8 @@
 CONFIG_SERIAL_UART00_CONSOLE=y
 # CONFIG_SERIAL_SA1100 is not set
 # CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
 # CONFIG_SERIAL_8250 is not set
 # CONFIG_SERIAL_8250_CONSOLE is not set
 # CONFIG_SERIAL_8250_EXTENDED is not set
@@ -460,7 +504,6 @@
 # CONFIG_L3_ALGOBIT is not set
 # CONFIG_L3_BIT_SA1100_GPIO is not set
 # CONFIG_L3_SA1111 is not set
-# CONFIG_L3_DRV_UDA1341 is not set
 # CONFIG_BIT_SA1100_GPIO is not set
 
 #
@@ -479,13 +522,11 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -513,7 +554,6 @@
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
-# CONFIG_CMS_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
 # CONFIG_JBD_DEBUG is not set
@@ -522,16 +562,17 @@
 # CONFIG_UMSDOS_FS is not set
 # CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_JFFS_FS=y
-CONFIG_JFFS_FS_VERBOSE=0
-# CONFIG_JFFS2_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
 # CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
-# CONFIG_FREEVXFS_FS is not set
+# CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -557,7 +598,7 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
-# CONFIG_ROOT_NFS is not set
+CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
 CONFIG_SUNRPC=y
@@ -572,6 +613,8 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -582,66 +625,18 @@
 # CONFIG_NLS is not set
 
 #
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
 # USB support
 #
 # CONFIG_USB is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_OHCI_SA1111 is not set
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_PLUSB is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
 
 #
 # Bluetooth support
@@ -652,11 +647,16 @@
 # Kernel hacking
 #
 CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
-CONFIG_MAGIC_SYSRQ=y
 # CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_WAITQ=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_LL=y
 # CONFIG_DEBUG_DC21285_PORT is not set
 # CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/epxa1db linux-2.4.22-pre10/arch/arm/def-configs/epxa1db
--- linux-2.4.21/arch/arm/def-configs/epxa1db	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/epxa1db	2003-08-01 13:34:10.000000000 +0000
@@ -0,0 +1,703 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+CONFIG_ARCH_CAMELOT=y
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_EPXA10DB is not set
+CONFIG_EPXA1DB=y
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+CONFIG_CPU_ARM922T=y
+CONFIG_PLD=y
+CONFIG_CPU_ARM922_CPU_IDLE=y
+CONFIG_CPU_ARM922_I_CACHE_ON=y
+CONFIG_CPU_ARM922_D_CACHE_ON=y
+# CONFIG_CPU_ARM922_WRITETHROUGH is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_ARM_THUMB is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttyUA0,38400 root=/dev/mtdblock0 rw"
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=0
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+CONFIG_MTD_EPXA10DB=y
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ETHER00 is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+# CONFIG_ULTRAMCA is not set
+# CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
+# CONFIG_SMC9194 is not set
+CONFIG_SMC91111=y
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+CONFIG_SERIAL_UART00=y
+CONFIG_SERIAL_UART00_CONSOLE=y
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_WAITQ=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/frodo linux-2.4.22-pre10/arch/arm/def-configs/frodo
--- linux-2.4.21/arch/arm/def-configs/frodo	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/frodo	2003-08-01 13:34:38.000000000 +0000
@@ -37,6 +37,7 @@
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
 # CONFIG_ARCH_RPC is not set
 CONFIG_ARCH_SA1100=y
 # CONFIG_ARCH_SHARK is not set
@@ -59,10 +60,12 @@
 #
 # SA11x0 Implementations
 #
+# CONFIG_SA1100_ACCELENT is not set
 # CONFIG_SA1100_ASSABET is not set
 # CONFIG_ASSABET_NEPONSET is not set
 # CONFIG_SA1100_ADSBITSY is not set
 # CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
 # CONFIG_SA1100_CERF is not set
 # CONFIG_SA1100_H3100 is not set
 # CONFIG_SA1100_H3600 is not set
@@ -71,6 +74,7 @@
 # CONFIG_SA1100_EXTENEX1 is not set
 # CONFIG_SA1100_FLEXANET is not set
 # CONFIG_SA1100_FREEBIRD is not set
+CONFIG_SA1100_FRODO=y
 # CONFIG_SA1100_GRAPHICSCLIENT is not set
 # CONFIG_SA1100_GRAPHICSMASTER is not set
 # CONFIG_SA1100_BADGE4 is not set
@@ -86,11 +90,11 @@
 # CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
 # CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
 # CONFIG_SA1100_XP860 is not set
 # CONFIG_SA1100_YOPY is not set
-CONFIG_SA1100_FRODO=y
 # CONFIG_SA1100_USB is not set
 # CONFIG_SA1100_USB_NETLINK is not set
 # CONFIG_SA1100_USB_CHAR is not set
@@ -113,18 +117,18 @@
 # CONFIG_FOOTBRIDGE_ADDIN is not set
 CONFIG_CPU_32=y
 # CONFIG_CPU_26 is not set
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
 # CONFIG_CPU_ARM610 is not set
 # CONFIG_CPU_ARM710 is not set
 # CONFIG_CPU_ARM720T is not set
 # CONFIG_CPU_ARM920T is not set
 # CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
 # CONFIG_CPU_ARM926T is not set
 # CONFIG_CPU_ARM1020 is not set
 # CONFIG_CPU_SA110 is not set
 CONFIG_CPU_SA1100=y
-# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
 CONFIG_DISCONTIGMEM=y
 
 #
@@ -133,15 +137,28 @@
 # CONFIG_PCI is not set
 CONFIG_ISA=y
 # CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
 # CONFIG_CPU_FREQ is not set
-# CONFIG_HOTPLUG is not set
-# CONFIG_PCMCIA is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
+CONFIG_PCMCIA_SA1100=y
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-# CONFIG_FPE_NWFPE is not set
-CONFIG_FPE_FASTFPE=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
@@ -149,7 +166,7 @@
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="console=ttySA0,9600 ramdisk_size=4096 root=/dev/ram idebus=33"
+CONFIG_CMDLINE="console=ttySA0,115200 ramdisk_size=12288 root=/dev/ram idebus=33 mem=63M"
 CONFIG_LEDS=y
 CONFIG_LEDS_TIMER=y
 CONFIG_LEDS_CPU=y
@@ -163,7 +180,68 @@
 #
 # Memory Technology Devices (MTD)
 #
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
 
 #
 # Plug and Play configuration
@@ -179,11 +257,13 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_SIZE=12288
 CONFIG_BLK_DEV_INITRD=y
 
 #
@@ -201,7 +281,8 @@
 #
 # Networking options
 #
-# CONFIG_PACKET is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -221,6 +302,11 @@
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -238,9 +324,98 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Network device support
 #
-# CONFIG_NETDEVICES is not set
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_CIRRUS=y
+# CONFIG_CIRRUS_DEBUG is not set
+# CONFIG_CIRRUS_DUPLEX is not set
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=y
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+# CONFIG_PCMCIA_PCNET is not set
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+# CONFIG_NET_PCMCIA_RADIO is not set
 
 #
 # Amateur Radio support
@@ -253,7 +428,7 @@
 # CONFIG_IRDA is not set
 
 #
-# ATA/IDE/MFM/RLL support
+# ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
 
@@ -265,6 +440,7 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
 # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
 # CONFIG_BLK_DEV_IDEDISK_IBM is not set
@@ -274,11 +450,12 @@
 # CONFIG_BLK_DEV_IDEDISK_WD is not set
 # CONFIG_BLK_DEV_COMMERIAL is not set
 # CONFIG_BLK_DEV_TIVO is not set
-# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECS=y
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
@@ -312,11 +489,13 @@
 #
 # Input core support
 #
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+CONFIG_INPUT_EVDEV=y
 
 #
 # Character devices
@@ -343,7 +522,7 @@
 # CONFIG_SERIAL_UART00_CONSOLE is not set
 CONFIG_SERIAL_SA1100=y
 CONFIG_SERIAL_SA1100_CONSOLE=y
-CONFIG_SA1100_DEFAULT_BAUDRATE=9600
+CONFIG_SA1100_DEFAULT_BAUDRATE=115200
 # CONFIG_SERIAL_8250 is not set
 # CONFIG_SERIAL_8250_CONSOLE is not set
 # CONFIG_SERIAL_8250_EXTENDED is not set
@@ -355,12 +534,22 @@
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=16
+CONFIG_UNIX98_PTY_COUNT=64
 
 #
 # I2C support
 #
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_PHILIPSPAR is not set
+# CONFIG_I2C_ELV is not set
+# CONFIG_I2C_VELLEMAN is not set
+CONFIG_I2C_FRODO=y
+# CONFIG_I2C_BIT_SA1100_GPIO is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PROC=y
+CONFIG_I2C_DS1307=y
 
 #
 # L3 serial bus support
@@ -381,16 +570,61 @@
 # Joysticks
 #
 # CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
 # CONFIG_QIC02_TAPE is not set
 
 #
 # Watchdog Cards
 #
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_SA1100_RTC=y
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_21285_WATCHDOG is not set
+# CONFIG_977_WATCHDOG is not set
+CONFIG_SA1100_WATCHDOG=y
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_WAFER_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_MACHZ_WDT is not set
+CONFIG_DS1307_RTC=y
+CONFIG_DS1307_NVRAM=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -403,9 +637,50 @@
 # CONFIG_DRM is not set
 
 #
+# PCMCIA character devices
+#
+
+#
 # Multimedia devices
 #
-# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_DEV=y
+
+#
+# Video For Linux
+#
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_ZORAN_BUZ is not set
+# CONFIG_VIDEO_ZORAN_DC10 is not set
+# CONFIG_VIDEO_ZORAN_LML33 is not set
+# CONFIG_VIDEO_ZR36120 is not set
+# CONFIG_VIDEO_MEYE is not set
+# CONFIG_VIDEO_CYBERPRO is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_RADIO_MIROPCM20 is not set
+# CONFIG_RADIO_MIROPCM20_RDS is not set
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
 
 #
 # File systems
@@ -424,32 +699,33 @@
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
 # CONFIG_JBD_DEBUG is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
 # CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
+CONFIG_RAMFS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
 # CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
-CONFIG_ROMFS_FS=y
+# CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UDF_FS is not set
@@ -479,8 +755,8 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
+CONFIG_ZISOFS_FS=y
+CONFIG_ZLIB_FS_INFLATE=y
 
 #
 # Partition Types
@@ -488,11 +764,54 @@
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 
 #
 # Console drivers
 #
+CONFIG_PC_KEYB=y
 CONFIG_PC_KEYMAP=y
 # CONFIG_VGA_CONSOLE is not set
 
@@ -507,15 +826,32 @@
 CONFIG_FB_SA1100=y
 # CONFIG_FB_CYBER2000 is not set
 # CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
-CONFIG_FBCON_CFB2=y
-CONFIG_FBCON_CFB4=y
-CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+# CONFIG_FBCON_CFB8 is not set
 CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
 # CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-# CONFIG_FBCON_FONTS is not set
-CONFIG_FONT_8x8=y
+CONFIG_FBCON_FONTS=y
+# CONFIG_FONT_8x8 is not set
 CONFIG_FONT_8x16=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
 
 #
 # Sound
@@ -534,12 +870,19 @@
 #
 # USB support
 #
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+# CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_UHCI is not set
 # CONFIG_USB_UHCI_ALT is not set
 # CONFIG_USB_OHCI is not set
 # CONFIG_USB_OHCI_SA1111 is not set
+CONFIG_USB_1161=y
 # CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
 # CONFIG_USB_BLUETOOTH is not set
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -552,12 +895,25 @@
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_WACOM is not set
 # CONFIG_USB_DC2XX is not set
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_SCANNER is not set
 # CONFIG_USB_MICROTEK is not set
 # CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_DABUSB is not set
 # CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_CDCETHER is not set
@@ -575,6 +931,7 @@
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
 # CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
 # CONFIG_USB_SERIAL_IR is not set
 # CONFIG_USB_SERIAL_EDGEPORT is not set
 # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
@@ -588,11 +945,14 @@
 # CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
 # CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
 
 #
 # Bluetooth support
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/graphicsclient linux-2.4.22-pre10/arch/arm/def-configs/graphicsclient
--- linux-2.4.21/arch/arm/def-configs/graphicsclient	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/graphicsclient	2003-08-01 13:35:03.000000000 +0000
@@ -8,6 +8,8 @@
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
 
 #
 # Code maturity level options
@@ -31,12 +33,17 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
 # CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
 CONFIG_ARCH_SA1100=y
 # CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
 
 #
 # Archimedes/A5000 Implementations
@@ -60,15 +67,27 @@
 #
 # SA11x0 Implementations
 #
+# CONFIG_SA1100_ACCELENT is not set
 # CONFIG_SA1100_ASSABET is not set
 # CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
 # CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
 # CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_BITSY is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
 # CONFIG_SA1100_EXTENEX1 is not set
 # CONFIG_SA1100_FLEXANET is not set
 # CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
 CONFIG_SA1100_GRAPHICSCLIENT=y
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HUW_WEBPANEL is not set
 # CONFIG_SA1100_ITSY is not set
@@ -77,43 +96,59 @@
 # CONFIG_SA1100_OMNIMETER is not set
 # CONFIG_SA1100_PANGOLIN is not set
 # CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
 # CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
 # CONFIG_SA1100_XP860 is not set
 # CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_ADSBITSY is not set
 # CONFIG_SA1100_USB is not set
 # CONFIG_SA1100_USB_NETLINK is not set
 # CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
 
 #
 # CLPS711X/EP721X Implementations
 #
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
 # CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
 # CONFIG_ARCH_ACORN is not set
 # CONFIG_FOOTBRIDGE is not set
 # CONFIG_FOOTBRIDGE_HOST is not set
 # CONFIG_FOOTBRIDGE_ADDIN is not set
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
 
 #
 # Processor Type
 #
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
 # CONFIG_CPU_ARM610 is not set
 # CONFIG_CPU_ARM710 is not set
 # CONFIG_CPU_ARM720T is not set
 # CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
 # CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
 # CONFIG_CPU_SA110 is not set
 CONFIG_CPU_SA1100=y
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
 CONFIG_DISCONTIGMEM=y
-# CONFIG_CPU_BIG_ENDIAN is not set
 
 #
 # General setup
@@ -121,6 +156,9 @@
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
 # CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
 # CONFIG_CPU_FREQ is not set
 CONFIG_HOTPLUG=y
 
@@ -128,6 +166,8 @@
 # PCMCIA/CardBus support
 #
 CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 # CONFIG_TCIC is not set
 # CONFIG_PCMCIA_CLPS6700 is not set
@@ -136,6 +176,10 @@
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
 CONFIG_FPE_NWFPE=y
 # CONFIG_FPE_FASTFPE is not set
 CONFIG_KCORE_ELF=y
@@ -143,11 +187,9 @@
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_PM is not set
-# CONFIG_APM is not set
+CONFIG_PM=y
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="ip=off"
-# CONFIG_PFS168_CMDLINE is not set
+CONFIG_CMDLINE="console=ttySA0 mem=16m@0xC0000000 mem=16m@0xC8000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram"
 CONFIG_LEDS=y
 CONFIG_LEDS_TIMER=y
 CONFIG_LEDS_CPU=y
@@ -164,8 +206,9 @@
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_BOOTLDR_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AFS_PARTS is not set
 
 #
@@ -180,53 +223,44 @@
 # RAM/ROM/Flash chip drivers
 #
 CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
 # CONFIG_MTD_CFI_ADV_OPTIONS is not set
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_JEDEC is not set
 
 #
 # Mapping drivers for chip access
 #
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=800000
-CONFIG_MTD_PHYSMAP_LEN=1000000
+CONFIG_MTD_PHYSMAP_START=8000000
+CONFIG_MTD_PHYSMAP_LEN=2000000
 CONFIG_MTD_PHYSMAP_BUSWIDTH=4
-# CONFIG_MTD_SUN_UFLASH is not set
 # CONFIG_MTD_NORA is not set
-# CONFIG_MTD_PNC2000 is not set
-# CONFIG_MTD_RPXLITE is not set
-# CONFIG_MTD_TQM8XXL is not set
-# CONFIG_MTD_SC520CDP is not set
-# CONFIG_MTD_NETSC520 is not set
-# CONFIG_MTD_SBC_GXX is not set
-# CONFIG_MTD_ELAN_104NC is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
 CONFIG_MTD_SA1100=y
-# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
-# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
 # CONFIG_MTD_DC21285 is not set
 # CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_DBOX2 is not set
-# CONFIG_MTD_CSTM_MIPS_IXX is not set
-# CONFIG_MTD_CFI_FLAGADM is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
-# CONFIG_MTD_MIXMEM is not set
-# CONFIG_MTD_OCTAGON is not set
-# CONFIG_MTD_VMAX is not set
-# CONFIG_MTD_OCELOT is not set
-# CONFIG_MTD_L440GX is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
 
 #
 # Self-contained MTD device drivers
 #
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_LART is not set
 # CONFIG_MTD_MTDRAM is not set
 # CONFIG_MTD_BLKMTD is not set
 
@@ -257,8 +291,10 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
@@ -273,6 +309,7 @@
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_BLK_DEV_LVM is not set
 
 #
@@ -280,7 +317,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -293,17 +330,24 @@
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
 
 #
-#  
+#
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -321,6 +365,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -333,15 +382,17 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -351,6 +402,7 @@
 # CONFIG_ULTRA is not set
 # CONFIG_ULTRA32 is not set
 CONFIG_SMC9194=y
+# CONFIG_SMC91111 is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_NET_ISA is not set
 # CONFIG_NET_PCI is not set
@@ -360,21 +412,44 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
 # CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
-# CONFIG_PPP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
 
 #
 # Wireless LAN (non-hamradio)
 #
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_HERMES is not set
+
+#
+# Wireless Pcmcia cards support
+#
+# CONFIG_PCMCIA_HERMES is not set
+# CONFIG_AIRO_CS is not set
+CONFIG_NET_WIRELESS=y
 
 #
 # Token Ring devices
@@ -397,6 +472,7 @@
 # CONFIG_PCMCIA_3C574 is not set
 # CONFIG_PCMCIA_FMVJ18X is not set
 CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_AXNET is not set
 # CONFIG_PCMCIA_NMCLAN is not set
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
@@ -415,7 +491,7 @@
 # CONFIG_IRDA is not set
 
 #
-# ATA/IDE/MFM/RLL support
+# ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
 
@@ -431,6 +507,7 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
 # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
 # CONFIG_BLK_DEV_IDEDISK_IBM is not set
@@ -445,6 +522,7 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
 
 #
 # IDE chipset support/bugfixes
@@ -456,6 +534,9 @@
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_DMA_NONPCI is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
 
 #
 # SCSI support
@@ -479,46 +560,84 @@
 #
 # Input core support
 #
-# CONFIG_INPUT is not set
+CONFIG_INPUT=y
+# CONFIG_INPUT_KEYBDEV is not set
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Character devices
 #
 CONFIG_VT=y
-# CONFIG_VT_CONSOLE is not set
+CONFIG_VT_CONSOLE=y
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
 # CONFIG_SERIAL_AMBA is not set
 # CONFIG_SERIAL_AMBA_CONSOLE is not set
 # CONFIG_SERIAL_CLPS711X is not set
 # CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
 CONFIG_SERIAL_SA1100=y
 CONFIG_SERIAL_SA1100_CONSOLE=y
 CONFIG_SA1100_DEFAULT_BAUDRATE=38400
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
 # CONFIG_SERIAL_8250 is not set
 # CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
+# CONFIG_TOUCHSCREEN_ADS784X is not set
 CONFIG_UCB1200=y
 CONFIG_TOUCHSCREEN_UCB1200=y
 CONFIG_AUDIO_UCB1200=y
 CONFIG_ADC_UCB1200=y
-# CONFIG_TOUCHSCREEN_BITSY is not set
-# CONFIG_PROFILER is not set
-# CONFIG_PFS168_SPI is not set
-# CONFIG_PFS168_DTMF is not set
-# CONFIG_PFS168_MISC is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
 
 #
 # I2C support
 #
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_ADSSIO_I2C_ALGO=y
+# CONFIG_I2C_CHARDEV is not set
+# CONFIG_I2C_PROC is not set
+CONFIG_I2C_DS1307=y
+CONFIG_I2C_DS1307_ADS=y
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
 
 #
 # Mice
@@ -529,18 +648,43 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
 
 #
-# Input core support is needed for joysticks
+# Joysticks
 #
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
 # CONFIG_QIC02_TAPE is not set
 
 #
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_SA1100_RTC is not set
@@ -572,18 +716,21 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
 CONFIG_FAT_FS=y
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
 CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
-CONFIG_JFFS_FS=y
-CONFIG_JFFS_FS_VERBOSE=0
+# CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_CRAMFS=y
@@ -591,6 +738,7 @@
 CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -615,6 +763,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
@@ -632,6 +781,8 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=y
 
 #
 # Partition Types
@@ -666,6 +817,7 @@
 # CONFIG_NLS_CODEPAGE_949 is not set
 # CONFIG_NLS_CODEPAGE_874 is not set
 # CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
 # CONFIG_NLS_ISO8859_1 is not set
 # CONFIG_NLS_ISO8859_2 is not set
@@ -694,11 +846,11 @@
 CONFIG_FB=y
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
 # CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_CYBER2000 is not set
 CONFIG_FB_SA1100=y
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_E1355 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_E13806 is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB2=y
@@ -719,6 +871,15 @@
 # CONFIG_SOUND is not set
 
 #
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
 # USB support
 #
 # CONFIG_USB is not set
@@ -732,11 +893,16 @@
 # Kernel hacking
 #
 CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_LL is not set
 # CONFIG_DEBUG_DC21285_PORT is not set
 # CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/graphicsmaster linux-2.4.22-pre10/arch/arm/def-configs/graphicsmaster
--- linux-2.4.21/arch/arm/def-configs/graphicsmaster	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/graphicsmaster	2003-08-01 13:30:31.000000000 +0000
@@ -1,5 +1,5 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
 #
 CONFIG_ARM=y
 # CONFIG_EISA is not set
@@ -8,6 +8,8 @@
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
 
 #
 # Code maturity level options
@@ -31,16 +33,25 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_OMAHA is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
 # CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_RISCSTATION is not set
 CONFIG_ARCH_SA1100=y
 # CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
 
 #
 # Archimedes/A5000 Implementations
 #
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
 # CONFIG_ARCH_ARC is not set
 # CONFIG_ARCH_A5K is not set
 
@@ -56,15 +67,27 @@
 #
 # SA11x0 Implementations
 #
+# CONFIG_SA1100_ACCELENT is not set
 # CONFIG_SA1100_ASSABET is not set
 # CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSAGC is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_ADSBITSYPLUS is not set
 # CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CEP is not set
 # CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_BITSY is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
 # CONFIG_SA1100_EXTENEX1 is not set
 # CONFIG_SA1100_FLEXANET is not set
 # CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
 # CONFIG_SA1100_GRAPHICSCLIENT is not set
+CONFIG_SA1100_GRAPHICSMASTER=y
+# CONFIG_SA1100_HACKKIT is not set
+# CONFIG_SA1100_BADGE4 is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HUW_WEBPANEL is not set
 # CONFIG_SA1100_ITSY is not set
@@ -73,40 +96,61 @@
 # CONFIG_SA1100_OMNIMETER is not set
 # CONFIG_SA1100_PANGOLIN is not set
 # CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
 # CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_SIMPUTER is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
 # CONFIG_SA1100_XP860 is not set
 # CONFIG_SA1100_YOPY is not set
-CONFIG_SA1100_GRAPHICSMASTER=y
-# CONFIG_SA1100_ADSBITSY is not set
-CONFIG_SA1111=y
 # CONFIG_SA1100_USB is not set
 # CONFIG_SA1100_USB_NETLINK is not set
 # CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
 
 #
 # CLPS711X/EP721X Implementations
 #
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
 # CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
 # CONFIG_ARCH_ACORN is not set
 # CONFIG_FOOTBRIDGE is not set
 # CONFIG_FOOTBRIDGE_HOST is not set
 # CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_SA1111=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+
+#
+# Processor Type
+#
 CONFIG_CPU_32=y
 # CONFIG_CPU_26 is not set
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
 # CONFIG_CPU_ARM610 is not set
 # CONFIG_CPU_ARM710 is not set
 # CONFIG_CPU_ARM720T is not set
 # CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_PLD is not set
+# CONFIG_CPU_ARM926T is not set
 # CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_ARM1026 is not set
 # CONFIG_CPU_SA110 is not set
 CONFIG_CPU_SA1100=y
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+
+#
+# Processor Features
+#
 CONFIG_DISCONTIGMEM=y
-# CONFIG_CPU_BIG_ENDIAN is not set
 
 #
 # General setup
@@ -114,6 +158,9 @@
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
 # CONFIG_ISA_DMA is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
 # CONFIG_CPU_FREQ is not set
 CONFIG_HOTPLUG=y
 
@@ -121,6 +168,8 @@
 # PCMCIA/CardBus support
 #
 CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 # CONFIG_TCIC is not set
 # CONFIG_PCMCIA_CLPS6700 is not set
@@ -129,6 +178,10 @@
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
 CONFIG_FPE_NWFPE=y
 # CONFIG_FPE_FASTFPE is not set
 CONFIG_KCORE_ELF=y
@@ -136,11 +189,9 @@
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_PM is not set
-# CONFIG_APM is not set
+CONFIG_PM=y
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="ip=off"
-# CONFIG_PFS168_CMDLINE is not set
+CONFIG_CMDLINE="console=ttySA0 mem=16m@0xC0000000 mem=16m@0xC8000000 rw ramdisk_size=8192 initrd=0xC0800000,3m root=/dev/ram"
 CONFIG_LEDS=y
 CONFIG_LEDS_TIMER=y
 CONFIG_LEDS_CPU=y
@@ -157,9 +208,14 @@
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_BOOTLDR_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
@@ -169,55 +225,50 @@
 # RAM/ROM/Flash chip drivers
 #
 CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
 # CONFIG_MTD_CFI_ADV_OPTIONS is not set
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_JEDEC is not set
 
 #
 # Mapping drivers for chip access
 #
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=800000
-CONFIG_MTD_PHYSMAP_LEN=1000000
+CONFIG_MTD_PHYSMAP_START=8000000
+CONFIG_MTD_PHYSMAP_LEN=4000000
 CONFIG_MTD_PHYSMAP_BUSWIDTH=4
-# CONFIG_MTD_SUN_UFLASH is not set
 # CONFIG_MTD_NORA is not set
-# CONFIG_MTD_PNC2000 is not set
-# CONFIG_MTD_RPXLITE is not set
-# CONFIG_MTD_TQM8XXL is not set
-# CONFIG_MTD_SC520CDP is not set
-# CONFIG_MTD_NETSC520 is not set
-# CONFIG_MTD_SBC_GXX is not set
-# CONFIG_MTD_ELAN_104NC is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
 CONFIG_MTD_SA1100=y
-# CONFIG_MTD_SA1100_REDBOOT_PARTITIONS is not set
-# CONFIG_MTD_SA1100_BOOTLDR_PARTITIONS is not set
 # CONFIG_MTD_DC21285 is not set
 # CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_DBOX2 is not set
-# CONFIG_MTD_CSTM_MIPS_IXX is not set
-# CONFIG_MTD_CFI_FLAGADM is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_SOLUTIONENGINE is not set
-# CONFIG_MTD_MIXMEM is not set
-# CONFIG_MTD_OCTAGON is not set
-# CONFIG_MTD_VMAX is not set
-# CONFIG_MTD_OCELOT is not set
-# CONFIG_MTD_L440GX is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_EDB7312 is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PCI is not set
 
 #
 # Self-contained MTD device drivers
 #
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_LART is not set
 # CONFIG_MTD_MTDRAM is not set
 # CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
 # CONFIG_MTD_DOC1000 is not set
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
@@ -242,8 +293,10 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
@@ -258,6 +311,7 @@
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_BLK_DEV_LVM is not set
 
 #
@@ -265,7 +319,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -278,13 +332,24 @@
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -302,6 +367,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -314,15 +384,17 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_CIRRUS is not set
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -332,6 +404,7 @@
 # CONFIG_ULTRA is not set
 # CONFIG_ULTRA32 is not set
 CONFIG_SMC9194=y
+# CONFIG_SMC91111 is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_NET_ISA is not set
 # CONFIG_NET_PCI is not set
@@ -341,21 +414,44 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
 # CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
-# CONFIG_PPP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
 
 #
 # Wireless LAN (non-hamradio)
 #
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_HERMES is not set
+
+#
+# Wireless Pcmcia cards support
+#
+# CONFIG_PCMCIA_HERMES is not set
+# CONFIG_AIRO_CS is not set
+CONFIG_NET_WIRELESS=y
 
 #
 # Token Ring devices
@@ -378,6 +474,7 @@
 # CONFIG_PCMCIA_3C574 is not set
 # CONFIG_PCMCIA_FMVJ18X is not set
 CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_AXNET is not set
 # CONFIG_PCMCIA_NMCLAN is not set
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
@@ -396,7 +493,7 @@
 # CONFIG_IRDA is not set
 
 #
-# ATA/IDE/MFM/RLL support
+# ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
 
@@ -404,10 +501,15 @@
 # IDE, ATA and ATAPI Block devices
 #
 CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
 # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
 # CONFIG_BLK_DEV_IDEDISK_IBM is not set
@@ -422,6 +524,11 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
@@ -429,6 +536,9 @@
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_DMA_NONPCI is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
 
 #
 # SCSI support
@@ -464,35 +574,47 @@
 # Character devices
 #
 CONFIG_VT=y
-# CONFIG_VT_CONSOLE is not set
+CONFIG_VT_CONSOLE=y
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
 # CONFIG_SERIAL_AMBA is not set
 # CONFIG_SERIAL_AMBA_CONSOLE is not set
 # CONFIG_SERIAL_CLPS711X is not set
 # CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
 CONFIG_SERIAL_SA1100=y
 CONFIG_SERIAL_SA1100_CONSOLE=y
 CONFIG_SA1100_DEFAULT_BAUDRATE=38400
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
+# CONFIG_TOUCHSCREEN_ADS784X is not set
 CONFIG_UCB1200=y
 CONFIG_TOUCHSCREEN_UCB1200=y
 CONFIG_AUDIO_UCB1200=y
 CONFIG_ADC_UCB1200=y
-# CONFIG_TOUCHSCREEN_BITSY is not set
-# CONFIG_PROFILER is not set
-# CONFIG_PFS168_SPI is not set
-# CONFIG_PFS168_DTMF is not set
-# CONFIG_PFS168_MISC is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
 
 #
 # I2C support
@@ -500,6 +622,19 @@
 # CONFIG_I2C is not set
 
 #
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
 # Mice
 #
 # CONFIG_BUSMOUSE is not set
@@ -508,14 +643,43 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
 # CONFIG_QIC02_TAPE is not set
 
 #
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_SA1100_RTC is not set
@@ -533,6 +697,7 @@
 #
 # PCMCIA character devices
 #
+# CONFIG_PCMCIA_SERIAL_CS is not set
 
 #
 # Multimedia devices
@@ -547,18 +712,21 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
 CONFIG_FAT_FS=y
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
 CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
-CONFIG_JFFS_FS=y
-CONFIG_JFFS_FS_VERBOSE=0
+# CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_CRAMFS=y
@@ -566,6 +734,7 @@
 CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -590,6 +759,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
@@ -607,6 +777,8 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=y
 
 #
 # Partition Types
@@ -641,6 +813,7 @@
 # CONFIG_NLS_CODEPAGE_949 is not set
 # CONFIG_NLS_CODEPAGE_874 is not set
 # CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
 # CONFIG_NLS_ISO8859_1 is not set
 # CONFIG_NLS_ISO8859_2 is not set
@@ -669,11 +842,11 @@
 CONFIG_FB=y
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
 # CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_CYBER2000 is not set
 CONFIG_FB_SA1100=y
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_E1355 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_E13806 is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB2=y
@@ -691,50 +864,169 @@
 #
 # Sound
 #
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_SA1100=y
+# CONFIG_SOUND_UDA1341 is not set
+# CONFIG_SOUND_ASSABET_UDA1341 is not set
+# CONFIG_SOUND_H3600_UDA1341 is not set
+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
+# CONFIG_SOUND_SA1111_UDA1341 is not set
+# CONFIG_SOUND_SA1111_AC97 is not set
+# CONFIG_SOUND_SA1100SSP is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
 
 #
 # USB support
 #
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_UHCI is not set
 # CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=y
-CONFIG_USB_OHCI_NOPCI=y
+# CONFIG_USB_OHCI is not set
+CONFIG_USB_OHCI_SA1111=y
+
+#
+# USB Device Class drivers
+#
 # CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
 # CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
-# CONFIG_USB_HID is not set
-# CONFIG_USB_KBD is not set
-CONFIG_USB_MOUSE=y
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDDEV is not set
 # CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
 # CONFIG_USB_DC2XX is not set
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_SCANNER is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
 # CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_NET1080 is not set
+# CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
 # CONFIG_USB_USS720 is not set
 
 #
 # USB Serial Converter support
 #
 # CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
 # CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_BRLVGER is not set
 
 #
 # Bluetooth support
@@ -745,11 +1037,16 @@
 # Kernel hacking
 #
 CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_LL is not set
 # CONFIG_DEBUG_DC21285_PORT is not set
 # CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/lusl7200 linux-2.4.22-pre10/arch/arm/def-configs/lusl7200
--- linux-2.4.21/arch/arm/def-configs/lusl7200	2000-06-20 00:59:33.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/lusl7200	2003-08-01 13:31:30.000000000 +0000
@@ -23,6 +23,9 @@
 # CONFIG_CPU_26 is not set
 CONFIG_CPU_32v4=y
 CONFIG_CPU_ARM720=y
+CONFIG_ZBOOT_ROM=y
+CONFIG_ZBOOT_ROM_TEXT=0x00010000
+CONFIG_ZBOOT_ROM_BSS=0xf03e0000
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
 # CONFIG_ISA_DMA is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/nanoengine linux-2.4.22-pre10/arch/arm/def-configs/nanoengine
--- linux-2.4.21/arch/arm/def-configs/nanoengine	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/nanoengine	2003-08-01 13:32:15.000000000 +0000
@@ -0,0 +1,775 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+CONFIG_SA1100_NANOENGINE=y
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+
+#
+# Processor Type
+#
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+CONFIG_ZBOOT_ROM=y
+CONFIG_ZBOOT_ROM_TEXT=11000
+CONFIG_ZBOOT_ROM_BSS=c1fc0000
+# CONFIG_CPU_FREQ is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=/dev/ram"
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=1
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_BOOTLDR_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_AUTCPU12 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+CONFIG_MTD_MTDRAM=y
+CONFIG_MTDRAM_TOTAL_SIZE=2048
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTDRAM_ABS_POS=0
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=9600
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=64
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_SA1100_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=1
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/omaha linux-2.4.22-pre10/arch/arm/def-configs/omaha
--- linux-2.4.21/arch/arm/def-configs/omaha	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/omaha	2003-08-01 13:31:44.000000000 +0000
@@ -0,0 +1,798 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+CONFIG_ARCH_OMAHA=y
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+
+#
+# Processor Type
+#
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_ARM920_CPU_IDLE=y
+CONFIG_CPU_ARM920_I_CACHE_ON=y
+CONFIG_CPU_ARM920_D_CACHE_ON=y
+# CONFIG_CPU_ARM920_WRITETHROUGH is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_ARM_THUMB is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+CONFIG_SMC91C111=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_ARM_DCC is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_OMAHA is not set
+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_PHILIPSPAR is not set
+# CONFIG_I2C_ELV is not set
+# CONFIG_I2C_VELLEMAN is not set
+CONFIG_I2C_OMAHA=y
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PROC=y
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_21285_WATCHDOG is not set
+# CONFIG_977_WATCHDOG is not set
+# CONFIG_SA1100_WATCHDOG is not set
+CONFIG_OMAHA_WATCHDOG=y
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_OMAHA_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_UMSDOS_FS=y
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# Omaha /proc drivers
+#
+CONFIG_OMAHA_MISC=y
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/riscstation linux-2.4.22-pre10/arch/arm/def-configs/riscstation
--- linux-2.4.21/arch/arm/def-configs/riscstation	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/riscstation	2003-08-01 13:31:07.000000000 +0000
@@ -0,0 +1,766 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_MX1ADS is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_RISCSTATION=y
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_FRODO is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+CONFIG_CPU_32v3=y
+# CONFIG_CPU_32v4 is not set
+# CONFIG_CPU_ARM610 is not set
+CONFIG_CPU_ARM710=y
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_ARM_THUMB is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="ip=dhcp"
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_ARM_ETHER1 is not set
+# CONFIG_ARM_ETHER3 is not set
+# CONFIG_ARM_ETHERH is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+CONFIG_BLK_DEV_IDE_RISCSTATION=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+# CONFIG_PSMOUSE is not set
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+CONFIG_7K5MOUSE=y
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_ADFS_FS=y
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=y
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+CONFIG_ACORN_PARTITION_EESOX=y
+CONFIG_ACORN_PARTITION_ICS=y
+CONFIG_ACORN_PARTITION_ADFS=y
+CONFIG_ACORN_PARTITION_POWERTEC=y
+CONFIG_ACORN_PARTITION_RISCIX=y
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB_ACORN=y
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+# CONFIG_FB_SA1100 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_MFB=y
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_ACORN_8x8=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/sherman linux-2.4.22-pre10/arch/arm/def-configs/sherman
--- linux-2.4.21/arch/arm/def-configs/sherman	2001-08-12 18:13:59.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/sherman	2003-08-01 13:30:57.000000000 +0000
@@ -47,6 +47,9 @@
 #
 # General setup
 #
+CONFIG_ZBOOT_ROM=y
+CONFIG_ZBOOT_ROM_TEXT=0x00050000
+CONFIG_ZBOOT_ROM_BSS=0xc0200000
 # CONFIG_NET is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/def-configs/victor linux-2.4.22-pre10/arch/arm/def-configs/victor
--- linux-2.4.21/arch/arm/def-configs/victor	2000-06-20 00:59:33.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/def-configs/victor	2003-08-01 13:30:30.000000000 +0000
@@ -46,6 +46,9 @@
 #
 # General setup
 #
+CONFIG_ZBOOT_ROM=y
+CONFIG_ZBOOT_ROM_TEXT=0x00002000
+CONFIG_ZBOOT_ROM_BSS=0xc0200000
 # CONFIG_NET is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/Makefile linux-2.4.22-pre10/arch/arm/kernel/Makefile
--- linux-2.4.21/arch/arm/kernel/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/Makefile	2003-08-01 13:34:30.000000000 +0000
@@ -18,6 +18,7 @@
 O_OBJS_rpc        = dma-rpc.o
 O_OBJS_footbridge = dma-footbridge.o isa.o
 O_OBJS_l7200      = fiq.o
+O_OBJS_riscstation = fiq.o dma-riscstation.o
 
 pci-ftvpci	  = plx90x0.o
 pci-footbridge	  = dec21285.o
@@ -43,7 +44,8 @@
 no-irq-arch	:= $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \
 		   $(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
 		   $(CONFIG_ARCH_SA1100) $(CONFIG_ARCH_CAMELOT) \
-		   $(CONFIG_ARCH_MX1ADS)
+		   $(CONFIG_ARCH_MX1ADS) $(CONFIG_ARCH_OMAHA) \
+		   $(CONFIG_ARCH_AT91RM9200)
 
 ifneq ($(findstring y,$(no-irq-arch)),y)
   obj-y		+= irq-arch.o
@@ -51,6 +53,7 @@
 
 obj-$(CONFIG_ARCH_ACORN) += ecard.o fiq.o time-acorn.o
 obj-$(CONFIG_ARCH_CLPS7500) += time-acorn.o
+obj-$(CONFIG_ARCH_RISCSTATION) += time-acorn.o
 obj-$(CONFIG_DEBUG_LL)	+= debug-$(PROCESSOR).o
 obj-$(CONFIG_MODULES)	+= armksyms.o
 obj-$(CONFIG_ARTHUR)	+= arthur.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/arch.c linux-2.4.22-pre10/arch/arm/kernel/arch.c
--- linux-2.4.21/arch/arm/kernel/arch.c	2001-08-12 18:13:59.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/arch.c	2003-08-01 13:31:22.000000000 +0000
@@ -20,7 +20,7 @@
 
 unsigned int vram_size;
 
-#ifdef CONFIG_ARCH_ACORN
+#if defined(CONFIG_ARCH_ACORN) || defined(CONFIG_ARCH_RISCSTATION)
 
 unsigned int memc_ctrl_reg;
 unsigned int number_mfm_drives;
@@ -49,7 +49,8 @@
 
 __tagtable(ATAG_ACORN, parse_tag_acorn);
 
-#ifdef CONFIG_ARCH_RPC
+
+#if defined(CONFIG_ARCH_RPC) || defined(CONFIG_ARCH_RISCSTATION)
 static void __init
 fixup_riscpc(struct machine_desc *desc, struct param_struct *unusd,
 	    char **cmdline, struct meminfo *mi)
@@ -61,7 +62,9 @@
 }
 
 extern void __init rpc_map_io(void);
+extern void __init riscstation_map_io(void);
 
+#ifdef CONFIG_ARCH_RPC
 MACHINE_START(RISCPC, "Acorn-RiscPC")
 	MAINTAINER("Russell King")
 	BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
@@ -73,6 +76,20 @@
 	INITIRQ(genarch_init_irq)
 MACHINE_END
 #endif
+
+#ifdef CONFIG_ARCH_RISCSTATION
+/* TODO = check all parameters */
+MACHINE_START(RISCSTATION, "RiscStation-RS7500")
+	MAINTAINER("Ben Dooks, Vincent Sanders")
+	BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
+	BOOT_PARAMS(0x10000100)
+	FIXUP(fixup_riscpc)
+	MAPIO(riscstation_map_io)
+	INITIRQ(genarch_init_irq)
+MACHINE_END
+#endif
+
+#endif /* CONFIG_ARCH_RPC | CONFIG_ARCH_RISCSTATION */
 #ifdef CONFIG_ARCH_ARC
 MACHINE_START(ARCHIMEDES, "Acorn-Archimedes")
 	MAINTAINER("Dave Gilbert")
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/armksyms.c linux-2.4.22-pre10/arch/arm/kernel/armksyms.c
--- linux-2.4.21/arch/arm/kernel/armksyms.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/armksyms.c	2003-08-01 13:32:31.000000000 +0000
@@ -62,9 +62,11 @@
 extern void __muldi3(void);
 extern void __ucmpdi2(void);
 extern void __udivdi3(void);
+extern void __umoddi3(void);
 extern void __udivmoddi4(void);
 extern void __udivsi3(void);
 extern void __umodsi3(void);
+extern void abort(void);
 
 extern void ret_from_exception(void);
 extern void fpundefinstr(void);
@@ -106,7 +108,9 @@
 	/* platform dependent support */
 EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(udelay);
+EXPORT_SYMBOL(__udelay);
+EXPORT_SYMBOL(__ndelay);
+EXPORT_SYMBOL(__const_delay);
 #ifdef CONFIG_CPU_32
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(__iounmap);
@@ -189,6 +193,7 @@
 EXPORT_SYMBOL_NOVERS(memmove);
 EXPORT_SYMBOL_NOVERS(memcmp);
 EXPORT_SYMBOL_NOVERS(memscan);
+EXPORT_SYMBOL_NOVERS(memchr);
 EXPORT_SYMBOL_NOVERS(__memzero);
 
 	/* user mem (segment) */
@@ -228,6 +233,7 @@
 EXPORT_SYMBOL_NOVERS(__muldi3);
 EXPORT_SYMBOL_NOVERS(__ucmpdi2);
 EXPORT_SYMBOL_NOVERS(__udivdi3);
+EXPORT_SYMBOL_NOVERS(__umoddi3);
 EXPORT_SYMBOL_NOVERS(__udivmoddi4);
 EXPORT_SYMBOL_NOVERS(__udivsi3);
 EXPORT_SYMBOL_NOVERS(__umodsi3);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/arthur.c linux-2.4.22-pre10/arch/arm/kernel/arthur.c
--- linux-2.4.21/arch/arm/kernel/arthur.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/arthur.c	2003-08-01 13:31:54.000000000 +0000
@@ -46,7 +46,7 @@
 /*
  * Linux to Arthur signal map.
  */
-static unsigned long linux_to_arthur_signals[32] = {
+static unsigned long arthur_invmap[32] = {
 	[0]		= 0,
 	[SIGHUP]	= -1,
 	[SIGINT]	= ARTHUR_SIGINT,
@@ -97,7 +97,7 @@
 	.pers_low	= PER_RISCOS,
 	.pers_high	= PER_RISCOS,
 	.signal_map	= arthur_to_linux_signals,
-	.signal_invmap	= linux_to_arthur_signals,
+	.signal_invmap	= arthur_invmap,
 	.module		= THIS_MODULE,
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/bios32.c linux-2.4.22-pre10/arch/arm/kernel/bios32.c
--- linux-2.4.21/arch/arm/kernel/bios32.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/bios32.c	2003-08-01 13:32:48.000000000 +0000
@@ -584,7 +584,7 @@
  * pcibios_enable_device - Enable I/O and memory.
  * @dev: PCI device to be enabled
  */
-int pcibios_enable_device(struct pci_dev *dev)
+int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	u16 cmd, old_cmd;
 	int idx;
@@ -593,6 +593,10 @@
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	old_cmd = cmd;
 	for (idx = 0; idx < 6; idx++) {
+		/* Only set up the requested stuff */
+		if (!(mask & (1 << idx)))
+			continue;
+
 		r = dev->resource + idx;
 		if (!r->start && r->end) {
 			printk(KERN_ERR "PCI: Device %s not available because"
@@ -604,6 +608,13 @@
 		if (r->flags & IORESOURCE_MEM)
 			cmd |= PCI_COMMAND_MEMORY;
 	}
+
+	/*
+	 * Bridges (eg, cardbus bridges) need to be fully enabled
+	 */
+	if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
+		cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+
 	if (cmd != old_cmd) {
 		printk("PCI: enabling device %s (%04x -> %04x)\n",
 		       dev->slot_name, old_cmd, cmd);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/calls.S linux-2.4.22-pre10/arch/arm/kernel/calls.S
--- linux-2.4.21/arch/arm/kernel/calls.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/calls.S	2003-08-01 13:35:07.000000000 +0000
@@ -1,7 +1,7 @@
 /*
- *  linux/arch/arm/lib/calls.h
+ *  linux/arch/arm/kernel/calls.S
  *
- *  Copyright (C) 1995-1998 Russell King
+ *  Copyright (C) 1995-2003 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -10,7 +10,7 @@
  *  This file is included twice in entry-common.S
  */
 #ifndef NR_syscalls
-#define NR_syscalls 256
+#define NR_syscalls 288
 #else
 
 __syscall_start:
@@ -21,13 +21,13 @@
 		.long	SYMBOL_NAME(sys_write)
 /* 5 */		.long	SYMBOL_NAME(sys_open)
 		.long	SYMBOL_NAME(sys_close)
-		.long	SYMBOL_NAME(sys_waitpid)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_waitpid */
 		.long	SYMBOL_NAME(sys_creat)
 		.long	SYMBOL_NAME(sys_link)
 /* 10 */	.long	SYMBOL_NAME(sys_unlink)
 		.long	SYMBOL_NAME(sys_execve_wrapper)
 		.long	SYMBOL_NAME(sys_chdir)
-		.long	SYMBOL_NAME(sys_time)
+		.long	SYMBOL_NAME(sys_time)			/* used by libc4 */
 		.long	SYMBOL_NAME(sys_mknod)
 /* 15 */	.long	SYMBOL_NAME(sys_chmod)
 		.long	SYMBOL_NAME(sys_lchown16)
@@ -36,15 +36,15 @@
 		.long	SYMBOL_NAME(sys_lseek)
 /* 20 */	.long	SYMBOL_NAME(sys_getpid)
 		.long	SYMBOL_NAME(sys_mount)
-		.long	SYMBOL_NAME(sys_oldumount)
+		.long	SYMBOL_NAME(sys_oldumount)		/* used by libc4 */
 		.long	SYMBOL_NAME(sys_setuid16)
 		.long	SYMBOL_NAME(sys_getuid16)
 /* 25 */	.long	SYMBOL_NAME(sys_stime)
 		.long	SYMBOL_NAME(sys_ptrace)
-		.long	SYMBOL_NAME(sys_alarm)
+		.long	SYMBOL_NAME(sys_alarm)			/* used by libc4 */
 		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_fstat */
 		.long	SYMBOL_NAME(sys_pause)
-/* 30 */	.long	SYMBOL_NAME(sys_utime)
+/* 30 */	.long	SYMBOL_NAME(sys_utime)			/* used by libc4 */
 		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_stty */
 		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_getty */
 		.long	SYMBOL_NAME(sys_access)
@@ -62,7 +62,7 @@
 /* 45 */	.long	SYMBOL_NAME(sys_brk)
 		.long	SYMBOL_NAME(sys_setgid16)
 		.long	SYMBOL_NAME(sys_getgid16)
-		.long	SYMBOL_NAME(sys_signal)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_signal */
 		.long	SYMBOL_NAME(sys_geteuid16)
 /* 50 */	.long	SYMBOL_NAME(sys_getegid16)
 		.long	SYMBOL_NAME(sys_acct)
@@ -82,29 +82,29 @@
 /* 65 */	.long	SYMBOL_NAME(sys_getpgrp)
 		.long	SYMBOL_NAME(sys_setsid)
 		.long	SYMBOL_NAME(sys_sigaction)
-		.long	SYMBOL_NAME(sys_sgetmask)
-		.long	SYMBOL_NAME(sys_ssetmask)
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_sgetmask */
+		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_ssetmask */
 /* 70 */	.long	SYMBOL_NAME(sys_setreuid16)
 		.long	SYMBOL_NAME(sys_setregid16)
 		.long	SYMBOL_NAME(sys_sigsuspend_wrapper)
 		.long	SYMBOL_NAME(sys_sigpending)
 		.long	SYMBOL_NAME(sys_sethostname)
 /* 75 */	.long	SYMBOL_NAME(sys_setrlimit)
-		.long	SYMBOL_NAME(sys_old_getrlimit)
+		.long	SYMBOL_NAME(sys_old_getrlimit)		/* used by libc4 */
 		.long	SYMBOL_NAME(sys_getrusage)
 		.long	SYMBOL_NAME(sys_gettimeofday)
 		.long	SYMBOL_NAME(sys_settimeofday)
 /* 80 */	.long	SYMBOL_NAME(sys_getgroups16)
 		.long	SYMBOL_NAME(sys_setgroups16)
-		.long	SYMBOL_NAME(old_select)
+		.long	SYMBOL_NAME(old_select)			/* used by libc4 */
 		.long	SYMBOL_NAME(sys_symlink)
 		.long	SYMBOL_NAME(sys_ni_syscall)		/* was sys_lstat */
 /* 85 */	.long	SYMBOL_NAME(sys_readlink)
 		.long	SYMBOL_NAME(sys_uselib)
 		.long	SYMBOL_NAME(sys_swapon)
 		.long	SYMBOL_NAME(sys_reboot)
-		.long	SYMBOL_NAME(old_readdir)
-/* 90 */	.long	SYMBOL_NAME(old_mmap)
+		.long	SYMBOL_NAME(old_readdir)		/* used by libc4 */
+/* 90 */	.long	SYMBOL_NAME(old_mmap)			/* used by libc4 */
 		.long	SYMBOL_NAME(sys_munmap)
 		.long	SYMBOL_NAME(sys_truncate)
 		.long	SYMBOL_NAME(sys_ftruncate)
@@ -240,23 +240,37 @@
 		.long	SYMBOL_NAME(sys_ni_syscall) /* Security */
 		.long	SYMBOL_NAME(sys_gettid)
 /* 225 */	.long	SYMBOL_NAME(sys_readahead)
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_setxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lsetxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fsetxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_getxattr */
-/* 230 */	.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lgetxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fgetxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_listxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_llistxattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_flistxattr */
-/* 235 */	.long	SYMBOL_NAME(sys_ni_syscall) /* sys_removexattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lremovexattr */
-		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fremovexattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* setxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* lsetxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* fsetxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* getxattr */
+/* 230 */	.long	SYMBOL_NAME(sys_ni_syscall) /* lgetxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* fgetxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* listxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* llistxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* flistxattr */
+/* 235 */	.long	SYMBOL_NAME(sys_ni_syscall) /* removexattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* lremovexattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* fremovexattr */
 		.long	SYMBOL_NAME(sys_tkill)
-		/*
-		 * Please check 2.5 _before_ adding calls here,
-		 * and copy changes to rmk@arm.linux.org.uk.  Thanks.
-		 */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sendfile64 */
+/* 240 */	.long	SYMBOL_NAME(sys_ni_syscall) /* futex */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sched_setaffinity */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sched_getaffinity */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* io_setup */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* io_destroy */
+/* 245 */	.long	SYMBOL_NAME(sys_ni_syscall) /* io_getevents */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* io_submit */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* io_cancel */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* exit_group */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* lookup_dcookie */
+/* 250 */	.long	SYMBOL_NAME(sys_ni_syscall) /* epoll_create */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* epoll_ctl */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* epoll_wait */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* remap_file_pages */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* set_thread_area */
+/* 255 */	.long	SYMBOL_NAME(sys_ni_syscall) /* get_thread_area */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* set_tid_address */
 __syscall_end:
 
 		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/compat.c linux-2.4.22-pre10/arch/arm/kernel/compat.c
--- linux-2.4.21/arch/arm/kernel/compat.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/compat.c	2003-08-01 13:30:45.000000000 +0000
@@ -33,18 +33,35 @@
 	return tag;
 }
 
-static void __init build_tag_list(struct param_struct *params, void *taglist, int mem_init)
+static void __init build_tag_list(struct param_struct *params, void *taglist)
 {
 	struct tag *tag = taglist;
 
-	printk(KERN_DEBUG "Converting old-style param struct to taglist\n");
-
 	if (params->u1.s.page_size != PAGE_SIZE) {
 		printk(KERN_WARNING "Warning: bad configuration page, "
 		       "trying to continue\n");
 		return;
 	}
 
+	printk(KERN_DEBUG "Converting old-style param struct to taglist\n");
+
+#ifdef CONFIG_ARCH_NETWINDER
+	if (params->u1.s.nr_pages != 0x02000 &&
+	    params->u1.s.nr_pages != 0x04000 &&
+	    params->u1.s.nr_pages != 0x08000 &&
+	    params->u1.s.nr_pages != 0x10000) {
+		printk(KERN_WARNING "Warning: bad NeTTrom parameters "
+		       "detected, using defaults\n");
+
+		params->u1.s.nr_pages = 0x1000;	/* 16MB */
+		params->u1.s.ramdisk_size = 0;
+		params->u1.s.flags = FLAG_READONLY;
+		params->u1.s.initrd_start = 0;
+		params->u1.s.initrd_size = 0;
+		params->u1.s.rd_start = 0;
+	}
+#endif
+
 	tag->hdr.tag  = ATAG_CORE;
 	tag->hdr.size = tag_size(tag_core);
 	tag->u.core.flags = params->u1.s.flags & FLAG_READONLY;
@@ -76,17 +93,15 @@
 	tag->hdr.size = tag_size(tag_revision);
 	tag->u.revision.rev = params->u1.s.system_rev;
 
-	if (mem_init) {
 #ifdef CONFIG_ARCH_ACORN
-		if (machine_is_riscpc()) {
-			int i;
-			for (i = 0; i < 4; i++)
-				tag = memtag(tag, PHYS_OFFSET + (i << 26),
-					 params->u1.s.pages_in_bank[i] * PAGE_SIZE);
-		} else
+	if (machine_is_riscpc()) {
+		int i;
+		for (i = 0; i < 4; i++)
+			tag = memtag(tag, PHYS_OFFSET + (i << 26),
+				 params->u1.s.pages_in_bank[i] * PAGE_SIZE);
+	} else
 #endif
-		tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE);
-	}
+	tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE);
 
 #ifdef CONFIG_FOOTBRIDGE
 	if (params->u1.s.mem_fclk_21285) {
@@ -97,6 +112,23 @@
 	}
 #endif
 
+#ifdef CONFIG_ARCH_EBSA285
+	if (machine_is_ebsa285()) {
+		tag = tag_next(tag);
+		tag->hdr.tag = ATAG_VIDEOTEXT;
+		tag->hdr.size = tag_size(tag_videotext);
+		tag->u.videotext.x	      = params->u1.s.video_x;
+		tag->u.videotext.y	      = params->u1.s.video_y;
+		tag->u.videotext.video_page   = 0;
+		tag->u.videotext.video_mode   = 0;
+		tag->u.videotext.video_cols   = params->u1.s.video_num_cols;
+		tag->u.videotext.video_ega_bx = 0;
+		tag->u.videotext.video_lines  = params->u1.s.video_num_rows;
+		tag->u.videotext.video_isvga  = 1;
+		tag->u.videotext.video_points = 8;
+	}
+#endif
+
 #ifdef CONFIG_ARCH_ACORN
 	tag = tag_next(tag);
 	tag->hdr.tag = ATAG_ACORN;
@@ -114,14 +146,22 @@
 	strcpy(tag->u.cmdline.cmdline, params->commandline);
 
 	tag = tag_next(tag);
-	tag->hdr.tag = 0;
+	tag->hdr.tag = ATAG_NONE;
 	tag->hdr.size = 0;
 
 	memmove(params, taglist, ((int)tag) - ((int)taglist) +
 				 sizeof(struct tag_header));
 }
 
-void __init convert_to_tag_list(struct param_struct *params, int mem_init)
+void __init convert_to_tag_list(struct tag *tags)
+{
+	struct param_struct *params = (struct param_struct *)tags;
+	build_tag_list(params, &params->u2);
+}
+
+void __init squash_mem_tags(struct tag *tag)
 {
-	build_tag_list(params, &params->u2, mem_init);
+	for (; tag->hdr.size; tag = tag_next(tag))
+		if (tag->hdr.tag == ATAG_MEM)
+			tag->hdr.tag = ATAG_NONE;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/debug-armv.S linux-2.4.22-pre10/arch/arm/kernel/debug-armv.S
--- linux-2.4.21/arch/arm/kernel/debug-armv.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/debug-armv.S	2003-08-01 13:32:26.000000000 +0000
@@ -20,9 +20,20 @@
  * printk isn't working).  For DEBUGGING ONLY!!!  Do not leave
  * references to these in a production kernel!
  */
-#if defined(CONFIG_ARCH_RPC)
+#if defined(CONFIG_ARCH_RPC) || defined(CONFIG_ARCH_RISCSTATION)
 		.macro	addruart,rx
-		mov	\rx, #0xe0000000
+
+/* note, errors can occur in the head code BEFORE the memory map has been
+ * setup (and therefore the mapping for the IO) so the #if statement allows
+ * the address of the uart to be changed to the physical address instead of
+ * the logical
+ *
+ * (bjd)
+ */
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		movne	\rx, #0xe0000000
+		moveq	\rx, #0x03000000
 		orr	\rx, \rx, #0x00010000
 		orr	\rx, \rx, #0x00000fe0
 		.endm
@@ -66,7 +77,7 @@
 		tst	\rd, #0x10
 		beq	1001b
 		.endm
- 	
+
 #elif defined(CONFIG_ARCH_SHARK)
 		.macro	addruart,rx
 		mov	\rx, #0xe0000000
@@ -287,6 +298,30 @@
 		tst	\rd, #1 << 3		@ UARTFLGUBUSY - 1 when busy
 		bne	1001b
 		.endm
+#elif defined(CONFIG_ARCH_AT91RM9200)
+
+		.macro  addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1				@ MMU enabled?
+		ldreq	\rx, =AT91C_BASE_SYS		@ System peripherals (phys address)
+		ldrne	\rx, =AT91C_VA_BASE_SYS		@ System peripherals (virt address)
+		.endm
+
+		.macro  senduart,rd,rx
+		strb    \rd, [\rx, #DBGU_THR]		@ DBGU_THR
+		.endm
+
+		.macro  waituart,rd,rx
+1001:		ldr     \rd, [\rx, #DBGU_CSR]		@ DBGU_CSR
+		tst	\rd, #AT91C_DBGU_TXRDY		@ DBGU_TXRDY = 1 when ready to transmit
+		beq	1001b
+		.endm
+
+		.macro  busyuart,rd,rx
+1001:		ldr	\rd, [\rx, #DBGU_CSR]		@ DBGU_CSR
+		tst	\rd, #AT91C_DBGU_TXEMPTY	@ DBGU_TXEMPTY = 1 when transmission complete
+		beq	1001b
+		.endm
 
 #elif defined(CONFIG_ARCH_CLPS711X)
 
@@ -322,6 +357,21 @@
 		bne	1001b
 1002:
 		.endm
+#elif defined(CONFIG_ARCH_OMAHA)
+
+#include <asm/hardware/serial_omaha.h>
+
+		.macro	addruart,rx
+		.endm
+
+		.macro	senduart,rd,rx
+		.endm
+
+		.macro	waituart,rd,rx
+		.endm
+
+		.macro	busyuart,rd,rx
+		.endm
 
 #elif defined(CONFIG_ARCH_ANAKIN)
 
@@ -365,7 +415,7 @@
 		tst	\rx, #1			@ MMU enabled?
 		ldr	\rx, =EXC_UART00_BASE	@ physical base address
 		orrne	\rx, \rx, #0xff000000	@ virtual base
-		orrne	\rx, \rx, #0x00f00000	
+		orrne	\rx, \rx, #0x00f00000
 		.endm
 
 		.macro	senduart,rd,rx
@@ -385,6 +435,41 @@
 		bne	1001b
 		.endm
 
+#elif defined(CONFIG_ARCH_MX1ADS)
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x00000000	@ physical
+		movne	\rx, #0xf0000000	@ virtual
+		orr	\rx, \rx, #0x00200000
+		orr	\rx, \rx, #0x00006000	@ UART1 offset
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0x40]	@ TXDATA
+		.endm
+
+		.macro	waituart,rd,rx
+#if	0
+/* REVISIT: This isn't right. I believe we should be checking CTS here instead
+ * to see if the user has entered <CTRL><S> to pause console output.
+ * gdavis@mvista.com 28apr03
+ */
+1001:		ldr	\rd, [\rx, #0x94]	@ SR1
+		tst	\rd, #1 << 13		@ TRDY
+		bne	1001b			@ wait until TX FIFO ready
+#endif
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldr	\rd, [\rx, #0x98]	@ SR2
+		tst	\rd, #1 << 3		@ TXDC
+		beq	1002b			@ wait until transmit done
+		.endm
+
+
+
 #else
 #error Unknown architecture
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/dma-arc.c linux-2.4.22-pre10/arch/arm/kernel/dma-arc.c
--- linux-2.4.21/arch/arm/kernel/dma-arc.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/dma-arc.c	2003-08-01 13:34:03.000000000 +0000
@@ -34,14 +34,14 @@
 		extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
 		unsigned long flags;
 		DPRINTK("enable_dma fdc1772 data read\n");
-		save_flags(flags);
-		clf();
+		local_save_flags(flags);
+		__clf();
 			
 		memcpy ((void *)0x1c, (void *)&fdc1772_dma_read,
 			&fdc1772_dma_read_end - &fdc1772_dma_read);
 		fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */
 		enable_fiq(FIQ_FLOPPYDATA);
-		restore_flags(flags);
+		local_irq_restore(flags);
 	   }
 	   break;
 
@@ -50,14 +50,14 @@
 		extern void fdc1772_setupdma(unsigned int count,unsigned int addr);
 		unsigned long flags;
 		DPRINTK("enable_dma fdc1772 data write\n");
-		save_flags(flags);
-		clf();
+		local_save_flags(flags);
+		__clf();
 		memcpy ((void *)0x1c, (void *)&fdc1772_dma_write,
 			&fdc1772_dma_write_end - &fdc1772_dma_write);
 		fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */
 		enable_fiq(FIQ_FLOPPYDATA;
 
-		restore_flags(flags);
+		local_irq_restore(flags);
 	    }
 	    break;
 	default:
@@ -81,14 +81,14 @@
 
 	DPRINTK("arc_floppy_cmdend_enable_dma\n");
 	/*printk("enable_dma fdc1772 command end FIQ\n");*/
-	save_flags(flags);
-	clf();
+	local_save_flags(flags);
+	__clf();
 	
 	/* B fdc1772_comendhandler */
 	*((unsigned int *)0x1c)=0xea000000 |
 			(((unsigned int)fdc1772_comendhandler-(0x1c+8))/4);
 
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
 
 static int arc_floppy_cmdend_get_dma_residue(dmach_t channel, dma_t *dma)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/dma-riscstation.c linux-2.4.22-pre10/arch/arm/kernel/dma-riscstation.c
--- linux-2.4.21/arch/arm/kernel/dma-riscstation.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/dma-riscstation.c	2003-08-01 13:34:29.000000000 +0000
@@ -0,0 +1,113 @@
+/*
+ *  linux/arch/arm/kernel/dma-riscstation.c
+ *
+ *  Copyright (C) 1998 Russell King
+ *  Copyright (C) 2002 Ben Dooks / Simtec Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  DMA functions specific to RiscStatiun architecture
+ *
+ * sliced down version of the RiscPC DMA code by RMK
+ */
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/page.h>
+#include <asm/dma.h>
+#include <asm/fiq.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/uaccess.h>
+
+#include <asm/mach/dma.h>
+#include <asm/hardware/iomd.h>
+
+static struct fiq_handler fh = {
+	name: "floppydma"
+};
+
+static void floppy_enable_dma(dmach_t channel, dma_t *dma)
+{
+	void *fiqhandler_start;
+	unsigned int fiqhandler_length;
+	struct pt_regs regs;
+
+	if (dma->dma_mode == DMA_MODE_READ) {
+		extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
+		fiqhandler_start = &floppy_fiqin_start;
+		fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
+	} else {
+		extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
+		fiqhandler_start = &floppy_fiqout_start;
+		fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
+	}
+
+	regs.ARM_r9  = dma->buf.length;
+	regs.ARM_r10 = (unsigned long)dma->buf.address;
+	regs.ARM_fp  = FLOPPYDMA_BASE;
+
+	if (claim_fiq(&fh)) {
+		printk("floppydma: couldn't claim FIQ.\n");
+		return;
+	}
+
+	set_fiq_handler(fiqhandler_start, fiqhandler_length);
+	set_fiq_regs(&regs);
+	enable_fiq(dma->dma_irq);
+}
+
+static void floppy_disable_dma(dmach_t channel, dma_t *dma)
+{
+	disable_fiq(dma->dma_irq);
+	release_fiq(&fh);
+}
+
+static int floppy_get_residue(dmach_t channel, dma_t *dma)
+{
+	struct pt_regs regs;
+	get_fiq_regs(&regs);
+	return regs.ARM_r9;
+}
+
+static struct dma_ops floppy_dma_ops = {
+	type:		"FIQDMA",
+	enable:		floppy_enable_dma,
+	disable:	floppy_disable_dma,
+	residue:	floppy_get_residue,
+};
+
+/*
+ * This is virtual DMA - we don't need anything here.
+ */
+static void sound_enable_disable_dma(dmach_t channel, dma_t *dma)
+{
+}
+
+static struct dma_ops sound_dma_ops = {
+	type:		"VIRTUAL",
+	enable:		sound_enable_disable_dma,
+	disable:	sound_enable_disable_dma,
+};
+
+void __init arch_dma_init(dma_t *dma)
+{
+#if 0
+	iomd_writeb(0, IOMD_IO0CR);
+	iomd_writeb(0, IOMD_IO1CR);
+	iomd_writeb(0, IOMD_IO2CR);
+	iomd_writeb(0, IOMD_IO3CR);
+
+	iomd_writeb(0xa0, IOMD_DMATCR);
+#endif
+
+	dma[DMA_VIRTUAL_FLOPPY].dma_irq	= FIQ_FLOPPYDATA;
+	dma[DMA_VIRTUAL_FLOPPY].d_ops	= &floppy_dma_ops;
+	dma[DMA_VIRTUAL_SOUND].d_ops	= &sound_dma_ops;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/dma-rpc.c linux-2.4.22-pre10/arch/arm/kernel/dma-rpc.c
--- linux-2.4.21/arch/arm/kernel/dma-rpc.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/dma-rpc.c	2003-08-01 13:33:12.000000000 +0000
@@ -91,76 +91,40 @@
 	sg->length |= flags;
 }
 
-static inline void iomd_setup_dma_a(struct scatterlist *sg, dma_t *dma)
-{
-	iomd_writel(sg->dma_address, dma->dma_base + CURA);
-	iomd_writel(sg->length, dma->dma_base + ENDA);
-}
-
-static inline void iomd_setup_dma_b(struct scatterlist *sg, dma_t *dma)
-{
-	iomd_writel(sg->dma_address, dma->dma_base + CURB);
-	iomd_writel(sg->length, dma->dma_base + ENDB);
-}
-
 static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
 {
 	dma_t *dma = (dma_t *)dev_id;
-	unsigned int status = 0, no_buffer = dma->sg == NULL;
+	unsigned long base = dma->dma_base;
 
 	do {
-		switch (dma->state) {
-		case state_prog_a:
-			iomd_get_next_sg(&dma->cur_sg, dma);
-			iomd_setup_dma_a(&dma->cur_sg, dma);
-			dma->state = state_wait_a;
-
-		case state_wait_a:
-			status = iomd_readb(dma->dma_base + ST);
-			switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) {
-			case DMA_ST_OFL|DMA_ST_INT:
-				iomd_get_next_sg(&dma->cur_sg, dma);
-				iomd_setup_dma_a(&dma->cur_sg, dma);
-				break;
-
-			case DMA_ST_INT:
-				iomd_get_next_sg(&dma->cur_sg, dma);
-				iomd_setup_dma_b(&dma->cur_sg, dma);
-				dma->state = state_wait_b;
-				break;
-
-			case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB:
-				iomd_setup_dma_b(&dma->cur_sg, dma);
-				dma->state = state_wait_b;
-				break;
-			}
+		unsigned int status;
+
+		status = iomd_readb(base + ST);
+		if (!(status & DMA_ST_INT))
+			return;
+
+		if (status & DMA_ST_OFL && !dma->sg)
+			break;
+
+		iomd_get_next_sg(&dma->cur_sg, dma);
+
+		switch (status & (DMA_ST_OFL | DMA_ST_AB)) {
+		case DMA_ST_OFL:			/* OIA */
+		case DMA_ST_AB:				/* .IB */
+			iomd_writel(dma->cur_sg.dma_address, base + CURA);
+			iomd_writel(dma->cur_sg.length, base + ENDA);
 			break;
 
-		case state_wait_b:
-			status = iomd_readb(dma->dma_base + ST);
-			switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) {
-			case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB:
-				iomd_get_next_sg(&dma->cur_sg, dma);
-				iomd_setup_dma_b(&dma->cur_sg, dma);
-				break;
-
-			case DMA_ST_INT|DMA_ST_AB:
-				iomd_get_next_sg(&dma->cur_sg, dma);
-				iomd_setup_dma_a(&dma->cur_sg, dma);
-				dma->state = state_wait_a;
-				break;
-
-			case DMA_ST_OFL|DMA_ST_INT:
-				iomd_setup_dma_a(&dma->cur_sg, dma);
-				dma->state = state_wait_a;
-				break;
-			}
+		case DMA_ST_OFL | DMA_ST_AB:		/* OIB */
+		case 0:					/* .IA */
+			iomd_writel(dma->cur_sg.dma_address, base + CURB);
+			iomd_writel(dma->cur_sg.length, base + ENDB);
 			break;
 		}
-	} while (dma->sg && (status & DMA_ST_INT));
+	} while (1);
 
-	if (no_buffer)
-		disable_irq(irq);
+	iomd_writeb(0, base + CR);
+	disable_irq(irq);
 }
 
 static int iomd_request_dma(dmach_t channel, dma_t *dma)
@@ -194,7 +158,6 @@
 		}
 
 		iomd_writeb(DMA_CR_C, dma_base + CR);
-		dma->state = state_prog_a;
 	}
 		
 	if (dma->dma_mode == DMA_MODE_READ)
@@ -207,11 +170,15 @@
 static void iomd_disable_dma(dmach_t channel, dma_t *dma)
 {
 	unsigned long dma_base = dma->dma_base;
+	unsigned long flags;
 	unsigned int ctrl;
 
-	disable_irq(dma->dma_irq);
+	local_irq_save(flags);
 	ctrl = iomd_readb(dma_base + CR);
+	if (ctrl & DMA_CR_E)
+		disable_irq(dma->dma_irq);
 	iomd_writeb(ctrl & ~DMA_CR_E, dma_base + CR);
+	local_irq_restore(flags);
 }
 
 static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/dma.c linux-2.4.22-pre10/arch/arm/kernel/dma.c
--- linux-2.4.21/arch/arm/kernel/dma.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/dma.c	2003-08-01 13:34:06.000000000 +0000
@@ -119,6 +119,10 @@
 {
 	dma_t *dma = dma_chan + channel;
 
+	if (dma->active)
+		printk(KERN_ERR "dma%d: altering DMA SG while "
+		       "DMA active\n", channel);
+
 	dma->sg = sg;
 	dma->sgcount = nr_sg;
 	dma->using_sg = 1;
@@ -217,6 +221,14 @@
 	BUG();
 }
 
+/*
+ * Is the specified DMA channel active?
+ */
+int dma_channel_active(dmach_t channel)
+{
+	return dma_chan[channel].active;
+}
+
 void set_dma_page(dmach_t channel, char pagenr)
 {
 	printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel);
@@ -272,6 +284,7 @@
 GLOBAL_ALIAS(set_dma_sg, get_dma_residue);
 GLOBAL_ALIAS(set_dma_speed, get_dma_residue);
 GLOBAL_ALIAS(init_dma, get_dma_residue);
+GLOBAL_ALIAS(dma_channel_active, get_dma_residue);
 
 #endif
 
@@ -286,3 +299,6 @@
 EXPORT_SYMBOL(get_dma_residue);
 EXPORT_SYMBOL(set_dma_sg);
 EXPORT_SYMBOL(set_dma_speed);
+EXPORT_SYMBOL(dma_channel_active);
+
+EXPORT_SYMBOL(dma_spin_lock);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/ecard.c linux-2.4.22-pre10/arch/arm/kernel/ecard.c
--- linux-2.4.21/arch/arm/kernel/ecard.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/ecard.c	2003-08-01 13:34:10.000000000 +0000
@@ -38,7 +38,10 @@
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/notifier.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/ioport.h>
 
 #include <asm/dma.h>
 #include <asm/ecard.h>
@@ -55,7 +58,7 @@
 
 enum req {
 	req_readbytes,
-	req_reset_all
+	req_reset
 };
 
 struct ecard_request {
@@ -136,14 +139,11 @@
 #define POD_INT_ADDR(x)	((volatile unsigned char *)\
 			 ((BUS_ADDR((x)) - IO_BASE) + IO_START))
 
-static inline void ecard_task_reset(void)
+static inline void ecard_task_reset(struct ecard_request *req)
 {
-	ecard_t *ec;
-
-	for (ec = cards; ec; ec = ec->next)
-		if (ec->loader)
-			ecard_loader_reset(POD_INT_ADDR(ec->podaddr),
-					   ec->loader);
+	struct expansion_card *ec = req->ec;
+	if (ec->loader)
+		ecard_loader_reset(POD_INT_ADDR(ec->podaddr), ec->loader);
 }
 
 static void
@@ -223,8 +223,8 @@
 		ecard_task_readbytes(req);
 		break;
 
-	case req_reset_all:
-		ecard_task_reset();
+	case req_reset:
+		ecard_task_reset(req);
 		break;
 	}
 }
@@ -371,60 +371,6 @@
 
 /* ======================= Mid-level card control ===================== */
 
-/*
- * This function is responsible for resetting the expansion cards to a
- * sensible state immediately prior to rebooting the system.  This function
- * has process state (keventd), so we can sleep.
- *
- * Possible "val" values here:
- *  SYS_RESTART   -  restarting system
- *  SYS_HALT      - halting system
- *  SYS_POWER_OFF - powering down system
- *
- * We ignore all calls, unless it is a SYS_RESTART call - power down/halts
- * will be followed by a SYS_RESTART if ctrl-alt-del is pressed again.
- */
-static int ecard_reboot(struct notifier_block *me, unsigned long val, void *v)
-{
-	struct ecard_request req;
-
-	if (val != SYS_RESTART)
-		return 0;
-
-	/*
-	 * Disable the expansion card interrupt
-	 */
-	disable_irq(IRQ_EXPANSIONCARD);
-
-	/*
-	 * If we have any expansion card loader code which will handle
-	 * the reset for us, call it now.
-	 */
-	req.req = req_reset_all;
-	ecard_call(&req);
-
-	/*
-	 * Disable the expansion card interrupt again, just to be sure.
-	 */
-	disable_irq(IRQ_EXPANSIONCARD);
-
-	/*
-	 * Finally, reset the expansion card interrupt mask to
-	 * all enable (RISC OS doesn't set this)
-	 */
-#ifdef HAS_EXPMASK
-	have_expmask = ~0;
-	__raw_writeb(have_expmask, EXPMASK_ENABLE);
-#endif
-	return 0;
-}
-
-static struct notifier_block ecard_reboot_notifier = {
-	.notifier_call	= ecard_reboot,
-};
-
-
-
 static void
 ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld)
 {
@@ -628,8 +574,7 @@
 		       ec->irqaddr, ec->irqmask, *ec->irqaddr);
 }
 
-static void
-ecard_check_lockup(void)
+static void ecard_check_lockup(void)
 {
 	static int last, lockup;
 	ecard_t *ec;
@@ -757,8 +702,7 @@
 		printk(KERN_WARNING "Wild interrupt from backplane (masks)\n");
 }
 
-static void __init
-ecard_probeirqhw(void)
+static void __init ecard_probeirqhw(void)
 {
 	ecard_t *ec;
 	int found;
@@ -785,7 +729,7 @@
 	__raw_writeb(have_expmask, EXPMASK_ENABLE);
 }
 #else
-#define ecard_probeirqhw()
+#define ecard_probeirqhw() do { } while (0)
 #endif
 
 #ifndef IO_EC_MEMC8_BASE
@@ -896,6 +840,57 @@
 		get_ecard_dev_info);
 }
 
+#define ec_set_resource(ec,nr,st,sz,flg)			\
+	do {							\
+		(ec)->resource[nr].name = ec->name;	 	\
+		(ec)->resource[nr].start = st;			\
+		(ec)->resource[nr].end = (st) + (sz) - 1;	\
+		(ec)->resource[nr].flags = flg;			\
+	} while (0)
+
+static void __init ecard_init_resources(struct expansion_card *ec)
+{
+	unsigned long base = PODSLOT_IOC4_BASE;
+	unsigned int slot = ec->slot_no;
+	int i;
+
+	if (slot < 4) {
+		ec_set_resource(ec, ECARD_RES_MEMC,
+				PODSLOT_MEMC_BASE + (slot << 14),
+				PODSLOT_MEMC_SIZE, IORESOURCE_MEM);
+		base = PODSLOT_IOC0_BASE;
+	}
+
+#ifdef CONFIG_ARCH_RPC
+	if (slot < 8) {
+		ec_set_resource(ec, ECARD_RES_EASI,
+				PODSLOT_EASI_BASE + (slot << 24),
+				PODSLOT_EASI_SIZE, IORESOURCE_MEM);
+	}
+
+	if (slot == 8) {
+		ec_set_resource(ec, ECARD_RES_MEMC, NETSLOT_BASE,
+				NETSLOT_SIZE, IORESOURCE_MEM);
+	} else
+#endif
+
+	for (i = 0; i < ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++) {
+		ec_set_resource(ec, i + ECARD_RES_IOCSLOW,
+				base + (slot << 14) + (i << 19),
+				PODSLOT_IOC_SIZE, IORESOURCE_MEM);
+	}
+
+	for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
+		if (ec->resource[i].start &&
+		    request_resource(&iomem_resource, &ec->resource[i])) {
+			printk(KERN_ERR "ecard%d: resource(s) not available\n",
+				ec->slot_no);
+			ec->resource[i].end -= ec->resource[i].start;
+			ec->resource[i].start = 0;
+		}
+	}
+}
+
 /*
  * Probe for an expansion card.
  *
@@ -964,21 +959,26 @@
 			break;
 		}
 
-	ec->irq = 32 + slot;
-#ifdef IO_EC_MEMC8_BASE
-	if (slot == 8)
-		ec->irq = 11;
-#endif
+	snprintf(ec->name, sizeof(ec->name), "ecard %04x:%04x",
+		 ec->cid.manufacturer, ec->cid.product);
+
+	ecard_init_resources(ec);
+
 	/*
 	 * hook the interrupt handlers
 	 */
-	if (ec->irq != 0 && ec->irq >= 32) {
+	if (slot < 8) {
+		ec->irq = 32 + slot;
 		irq_desc[ec->irq].mask_ack = ecard_disableirq;
 		irq_desc[ec->irq].mask     = ecard_disableirq;
 		irq_desc[ec->irq].unmask   = ecard_enableirq;
 		irq_desc[ec->irq].valid    = 1;
 	}
 
+#ifdef IO_EC_MEMC8_BASE
+	if (slot == 8)
+		ec->irq = 11;
+#endif
 #ifdef CONFIG_ARCH_RPC
 	/* On RiscPC, only first two slots have DMA capability */
 	if (slot < 2)
@@ -1012,7 +1012,7 @@
 		finding_pos = finding_pos->next;
 
 	for (; finding_pos; finding_pos = finding_pos->next) {
-		if (finding_pos->claimed)
+		if (finding_pos->claimed || finding_pos->driver)
 			continue;
 
 		if (!cids) {
@@ -1062,11 +1062,6 @@
 {
 	int slot;
 
-	/*
-	 * Register our reboot notifier
-	 */
-	register_reboot_notifier(&ecard_reboot_notifier);
-
 #ifdef CONFIG_CPU_32
 	init_waitqueue_head(&ecard_wait);
 #endif
@@ -1093,7 +1088,162 @@
 	ecard_proc_init();
 }
 
+/*
+ *	ECARD driver functions
+ */
+static const struct ecard_id *
+ecard_match_device(const struct ecard_id *ids, struct expansion_card *ec)
+{
+	int i;
+
+	for (i = 0; ids[i].manufacturer != 65535; i++)
+		if (ec->cid.manufacturer == ids[i].manufacturer &&
+		    ec->cid.product == ids[i].product)
+			return ids + i;
+
+	return NULL;
+}
+
+static int ecard_drv_probe(struct expansion_card *ec, const struct ecard_id *id)
+{
+	struct ecard_driver *drv = ec->driver;
+	int ret;
+
+	ecard_claim(ec);
+	ret = drv->probe(ec, id);
+	if (ret)
+		ecard_release(ec);
+	return ret;
+}
+
+static int ecard_drv_remove(struct expansion_card *ec)
+{
+	struct ecard_driver *drv = ec->driver;
+
+	drv->remove(ec);
+	ecard_release(ec);
+
+	return 0;
+}
+
+/*
+ * Before rebooting, we must make sure that the expansion card is in a
+ * sensible state, so it can be re-detected.  This means that the first
+ * page of the ROM must be visible.  We call the expansion cards reset
+ * handler, if any.
+ */
+static void ecard_drv_shutdown(struct expansion_card *ec)
+{
+	struct ecard_driver *drv = ec->driver;
+	struct ecard_request req;
+
+	if (drv && drv->shutdown)
+		drv->shutdown(ec);
+	ecard_release(ec);
+	req.req = req_reset;
+	req.ec = ec;
+	ecard_call(&req);
+}
+
+int ecard_register_driver(struct ecard_driver *drv)
+{
+	struct expansion_card *ec;
+	int ret, found = 0;
+
+	for (ec = cards; ec; ec = ec->next) {
+		const struct ecard_id *id;
+
+		if (ec->driver || ec->claimed)
+			continue;
+
+		if (drv->id_table) {
+			id = ecard_match_device(drv->id_table, ec);
+			ret = id != NULL;
+		} else {
+			id = NULL;
+			ret = ec->cid.id == drv->id;
+		}
+
+		if (ret) {
+			ec->driver = drv;
+			ret = ecard_drv_probe(ec, id);
+			if (ret) {
+				ec->driver = NULL;
+			} else {
+				found++;
+			}
+		}
+	}
+
+	return found ? 0 : -ENODEV;
+}
+
+void ecard_remove_driver(struct ecard_driver *drv)
+{
+	struct expansion_card *ec;
+
+	for (ec = cards; ec; ec = ec->next)
+		if (ec->driver == drv) {
+			ecard_drv_remove(ec);
+			ec->driver = NULL;
+		}
+}
+
+/*
+ * This function is responsible for resetting the expansion cards to a
+ * sensible state immediately prior to rebooting the system.  This function
+ * has process state (keventd), so we can sleep.
+ *
+ * Possible "val" values here:
+ *  SYS_RESTART   -  restarting system
+ *  SYS_HALT      - halting system
+ *  SYS_POWER_OFF - powering down system
+ *
+ * We ignore all calls, unless it is a SYS_RESTART call - power down/halts
+ * will be followed by a SYS_RESTART if ctrl-alt-del is pressed again.
+ */
+static int ecard_reboot(struct notifier_block *me, unsigned long val, void *v)
+{
+	struct expansion_card *ec;
+
+	if (val != SYS_RESTART)
+		return 0;
+
+	for (ec = cards; ec; ec = ec->next)
+		if (ec->driver || ec->claimed)
+			ecard_drv_shutdown(ec);
+
+	/*
+	 * Disable the expansion card interrupt
+	 */
+	disable_irq(IRQ_EXPANSIONCARD);
+
+	/*
+	 * Finally, reset the expansion card interrupt mask to
+	 * all enable (RISC OS doesn't set this)
+	 */
+#ifdef HAS_EXPMASK
+	have_expmask = ~0;
+	__raw_writeb(have_expmask, EXPMASK_ENABLE);
+#endif
+	return 0;
+}
+
+static struct notifier_block ecard_reboot_notifier = {
+	.notifier_call	= ecard_reboot,
+};
+
+static int ecard_bus_init(void)
+{
+	register_reboot_notifier(&ecard_reboot_notifier);
+	return 0;
+}
+
+__initcall(ecard_bus_init);
+
 EXPORT_SYMBOL(ecard_startfind);
 EXPORT_SYMBOL(ecard_find);
 EXPORT_SYMBOL(ecard_readchunk);
 EXPORT_SYMBOL(ecard_address);
+EXPORT_SYMBOL(ecard_register_driver);
+EXPORT_SYMBOL(ecard_remove_driver);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/entry-armv.S linux-2.4.22-pre10/arch/arm/kernel/entry-armv.S
--- linux-2.4.21/arch/arm/kernel/entry-armv.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/entry-armv.S	2003-08-01 13:32:17.000000000 +0000
@@ -187,11 +187,10 @@
 
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
 		mov	r4, #0xe0000000
-		orr	r4, r4, #0x20
 
 		mov	\irqstat, #0x0C
-		strb	\irqstat, [r4]			@outb(0x0C, 0x20) /* Poll command */
-		ldrb	\irqnr, [r4]			@irq = inb(0x20) & 7
+		strb	\irqstat, [r4, #0x20]		@outb(0x0C, 0x20) /* Poll command */
+		ldrb	\irqnr, [r4, #0x20]		@irq = inb(0x20) & 7
 		and	\irqstat, \irqnr, #0x80
 		teq	\irqstat, #0
 		beq	43f
@@ -199,8 +198,8 @@
 		teq	\irqnr, #2
 		bne	44f
 43:		mov	\irqstat, #0x0C
-		strb	\irqstat, [r4, #0x80]		@outb(0x0C, 0xA0) /* Poll command */
-		ldrb	\irqnr, [r4, #0x80]		@irq = (inb(0xA0) & 7) + 8
+		strb	\irqstat, [r4, #0xa0]		@outb(0x0C, 0xA0) /* Poll command */
+		ldrb	\irqnr, [r4, #0xa0]		@irq = (inb(0xA0) & 7) + 8
 		and	\irqstat, \irqnr, #0x80
 		teq	\irqstat, #0
 		beq	44f
@@ -454,6 +453,23 @@
 		.macro	irq_prio_table
 		.endm
 
+#elif defined(CONFIG_ARCH_AT91RM9200)
+#include <asm/hardware.h>
+
+		.macro  disable_fiq
+		.endm
+
+		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =(AT91C_VA_BASE_SYS)	@ base virtual address of SYS peripherals
+		ldr	\irqnr, [\base, #AIC_IVR]	@ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt)
+		ldr	\irqstat, [\base, #AIC_ISR]	@ read interrupt source number
+		teq	\irqstat, #0			@ ISR is 0 when no current interrupt, or spurious interrupt
+		streq   \tmp, [\base, #AIC_EOICR]	@ not going to be handled further, then ACK it now.
+		.endm
+
+		.macro  irq_prio_table
+		.endm
+
 #elif defined(CONFIG_ARCH_MX1ADS)
 
 		.macro	disable_fiq
@@ -479,6 +495,32 @@
 		.macro	irq_prio_table
 		.endm
 
+#elif defined(CONFIG_ARCH_OMAHA)
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		
+		/* Read all interrupts pending... */
+		ldr	\irqnr, =IO_ADDRESS(PLAT_PERIPHERAL_BASE) + OMAHA_INTPND
+		ldr	\irqstat, [\irqnr]		/* INTPND */
+
+		/* All pending irqs are now in \irqstat */
+		mov	\irqnr, #0
+1001:		tst	\irqstat, #1
+		bne	1002f
+		add	\irqnr, \irqnr, #1
+		mov	\irqstat, \irqstat, lsr #1
+		cmp	\irqnr, #MAXIRQNUM
+		bcc	1001b
+1002:		/* EQ will be set if we reach MAXIRQNUM */
+
+		.endm
+
+		.macro	irq_prio_table
+		.endm    
+
 #elif defined(CONFIG_ARCH_CLPS711X)
 
 #include <asm/hardware/clps7111.h>
@@ -611,16 +653,6 @@
 		and	r2, r6, #31			@ int mode
 		b	SYMBOL_NAME(bad_mode)
 
-#if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE
-		/* The FPE is always present */
-		.equ	fpe_not_present, 0
-#else
-wfs_mask_data:	.word	0x0e200110			@ WFS/RFS
-		.word	0x0fef0fff
-		.word	0x0d000100			@ LDF [sp]/STF [sp]
-		.word	0x0d000100			@ LDF [fp]/STF [fp]
-		.word	0x0f000f00
-
 /* We get here if an undefined instruction happens and the floating
  * point emulator is not present.  If the offending instruction was
  * a WFS, we just perform a normal return as if we had emulated the
@@ -628,30 +660,7 @@
  * to run so that the emulator module proper can be loaded. --philb
  */
 fpe_not_present:
-		adr	r10, wfs_mask_data
-		ldmia	r10, {r4, r5, r6, r7, r8}
-		ldr	r10, [sp, #S_PC]		@ Load PC
-		sub	r10, r10, #4
-		mask_pc	r10, r10
-		ldrt	r10, [r10]			@ get instruction
-		and	r5, r10, r5
-		teq	r5, r4				@ Is it WFS?
-		moveq	pc, r9
-		and	r5, r10, r8
-		teq	r5, r6				@ Is it LDF/STF on sp or fp?
-		teqne	r5, r7
-		movne	pc, lr
-		tst	r10, #0x00200000		@ Does it have WB
-		moveq	pc, r9
-		and	r4, r10, #255			@ get offset
-		and	r6, r10, #0x000f0000
-		tst	r10, #0x00800000		@ +/-
-		ldr	r5, [sp, r6, lsr #14]		@ Load reg
-		rsbeq	r4, r4, #0
-		add	r5, r5, r4, lsl #2
-		str	r5, [sp, r6, lsr #14]		@ Save reg
-		mov	pc, r9
-#endif
+		mov	pc, lr
 
 /*
  * SVC mode handlers
@@ -703,11 +712,13 @@
 		@ routine called with r0 = irq number, r1 = struct pt_regs *
 		@
 		adrsvc	ne, lr, 1b
-		bne	do_IRQ
+		bne	asm_do_IRQ
 		ldr	r0, [sp, #S_PSR]		@ irqs are already disabled
 		msr	spsr, r0
 		ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
 
+		.ltorg
+
 		.align	5
 __und_svc:	sub	sp, sp, #S_FRAME_SIZE
 		stmia	sp, {r0 - r12}			@ save r0 - r12
@@ -807,11 +818,13 @@
 		@
 		@ routine called with r0 = irq number, r1 = struct pt_regs *
 		@
-		bne	do_IRQ
+		bne	asm_do_IRQ
 		mov	why, #0
 		get_current_task tsk
 		b	ret_to_user
 
+		.ltorg
+
 		.align	5
 __und_usr:	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
 		stmia	sp, {r0 - r12}			@ Save r0 - r12
@@ -822,6 +835,8 @@
 		stmdb	r8, {sp, lr}^			@ Save user sp, lr
 		alignment_trap r4, r7, __temp_und
 		zero_fp
+		tst	r6, #T_BIT			@ Thumb mode
+		bne	fpundefinstr
 		adrsvc	al, r9, ret_from_exception	@ r9  = normal FP return
 		adrsvc	al, lr, fpundefinstr		@ lr  = undefined instr return
 
@@ -859,8 +874,9 @@
  * This is the return code to user mode for abort handlers
  */
 ENTRY(ret_from_exception)
-		get_current_task tsk
+		disable_irq r1
 		mov	why, #0
+		get_current_task tsk
 		b	ret_to_user
 
 		.data
@@ -909,7 +925,9 @@
 		@
 		@ now branch to the relevent MODE handling routine
 		@
-		mov	r13, #I_BIT | MODE_SVC
+		mrs	r13, cpsr
+		bic	r13, r13, #MODE_MASK
+		orr	r13, r13, #I_BIT | MODE_SVC
 		msr	spsr_c, r13			@ switch to SVC_32 mode
 
 		and	lr, lr, #15
@@ -950,7 +968,9 @@
 		@
 		@ now branch to the relevent MODE handling routine
 		@
-		mov	r13, #I_BIT | MODE_SVC
+		mrs	r13, cpsr
+		bic	r13, r13, #MODE_MASK
+		orr	r13, r13, #I_BIT | MODE_SVC
 		msr	spsr_c, r13			@ switch to SVC_32 mode
 
 		and	lr, lr, #15
@@ -992,7 +1012,9 @@
 		@
 		@ now branch to the relevent MODE handling routine
 		@
-		mov	r13, #I_BIT | MODE_SVC
+		mrs	r13, cpsr
+		bic	r13, r13, #MODE_MASK
+		orr	r13, r13, #I_BIT | MODE_SVC
 		msr	spsr_c, r13			@ switch to SVC_32 mode
 
 		ands	lr, lr, #15
@@ -1033,7 +1055,9 @@
 		@
 		@ now branch to the relevent MODE handling routine
 		@
-		mov	r13, #I_BIT | MODE_SVC
+		mrs	r13, cpsr
+		bic	r13, r13, #MODE_MASK
+		orr	r13, r13, #I_BIT | MODE_SVC
 		msr	spsr_c, r13			@ switch to SVC_32 mode
 
 		and	lr, lr, #15
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/entry-common.S linux-2.4.22-pre10/arch/arm/kernel/entry-common.S
--- linux-2.4.21/arch/arm/kernel/entry-common.S	2002-02-25 19:37:52.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/entry-common.S	2003-08-01 13:30:40.000000000 +0000
@@ -34,6 +34,7 @@
  * stack.
  */
 ret_fast_syscall:
+	disable_irq r1				@ ensure IRQs are disabled
 	ldr	r1, [tsk, #TSK_NEED_RESCHED]
 	ldr	r2, [tsk, #TSK_SIGPENDING]
 	teq	r1, #0				@ need_resched || sigpending
@@ -45,28 +46,35 @@
  * Ok, we need to do extra processing, enter the slow path.
  */
 slow:	str	r0, [sp, #S_R0+S_OFF]!	@ returned r0
-	b	1f
+	teq	r1, #0
+	beq	1f
 
 /*
  * "slow" syscall return path.  "why" tells us if this was a real syscall.
  */
 reschedule:
 	bl	SYMBOL_NAME(schedule)
+ret_disable_irq:
+	disable_irq r1				@ ensure IRQs are disabled
 ENTRY(ret_to_user)
 ret_slow_syscall:
 	ldr	r1, [tsk, #TSK_NEED_RESCHED]
 	ldr	r2, [tsk, #TSK_SIGPENDING]
-1:	teq	r1, #0				@ need_resched => schedule()
+	teq	r1, #0				@ need_resched => schedule()
 	bne	reschedule
-	teq	r2, #0				@ sigpending => do_signal()
-	blne	__do_signal
+1:	teq	r2, #0				@ sigpending => do_signal()
+	bne	__do_signal
+restore:
 	restore_user_regs
 
 __do_signal:
+	enable_irq r1
 	mov	r0, #0				@ NULL 'oldset'
 	mov	r1, sp				@ 'regs'
 	mov	r2, why				@ 'syscall'
-	b	SYMBOL_NAME(do_signal)		@ note the bl above sets lr
+	bl	SYMBOL_NAME(do_signal)		@ note the bl above sets lr
+	disable_irq r1				@ ensure IRQs are disabled
+	b	restore
 
 /*
  * This is how we return from a fork.  __switch_to will be calling us
@@ -79,11 +87,11 @@
 	ldr	ip, [tsk, #TSK_PTRACE]		@ check for syscall tracing
 	mov	why, #1
 	tst	ip, #PT_TRACESYS		@ are we tracing syscalls?
-	beq	ret_slow_syscall
+	beq	ret_disable_irq
 	mov	r1, sp
 	mov	r0, #1				@ trace exit [IP = 1]
 	bl	SYMBOL_NAME(syscall_trace)
-	b	ret_slow_syscall
+	b	ret_disable_irq
 	
 
 #include "calls.S"
@@ -130,7 +138,7 @@
 	ldr	ip, [ip]
 	mcr	p15, 0, ip, c1, c0		@ update control register
 #endif
-	enable_irqs ip
+	enable_irq ip
 
 	str	r4, [sp, #-S_OFF]!		@ push fifth arg
 
@@ -174,7 +182,7 @@
 	mov	r1, sp
 	mov	r0, #1				@ trace exit [IP = 1]
 	bl	SYMBOL_NAME(syscall_trace)
-	b	ret_slow_syscall
+	b	ret_disable_irq
 
 	.align	5
 #ifdef CONFIG_ALIGNMENT_TRAP
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/entry-header.S linux-2.4.22-pre10/arch/arm/kernel/entry-header.S
--- linux-2.4.21/arch/arm/kernel/entry-header.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/entry-header.S	2003-08-01 13:33:01.000000000 +0000
@@ -41,14 +41,14 @@
 @
 @ Stack format (ensured by USER_* and SVC_*)
 @
-#define S_FRAME_SIZE	72
 #ifdef CONFIG_CPU_32
+#define S_FRAME_SIZE	72
 #define S_OLD_R0	68
 #define S_PSR		64
 #else
+#define S_FRAME_SIZE	68
 #define S_OLD_R0	64
 #define S_PSR		60
-#define S_PC		60
 #endif
 
 #define S_PC		60
@@ -70,6 +70,24 @@
 #define S_OFF		8
 
 #ifdef CONFIG_CPU_32
+	.macro	set_cpsr_c, reg, mode
+#if 1
+	/* broken binutils */
+	mov	\reg, \mode
+	msr	cpsr_c, \reg
+#else
+	msr	cpsr_c, \mode
+#endif
+	.endm
+
+	.macro	disable_irq, temp
+	set_cpsr_c \temp, #I_BIT | MODE_SVC
+	.endm
+
+	.macro	enable_irq, temp
+	set_cpsr_c \temp, #MODE_SVC
+	.endm
+
 		.macro	save_user_regs
 		sub	sp, sp, #S_FRAME_SIZE
 		stmia	sp, {r0 - r12}			@ Calling r0 - r12
@@ -81,21 +99,23 @@
 		str	r0, [sp, #S_OLD_R0]		@ Save OLD_R0
 		.endm
 
+/*
+ * Must be called with IRQs already disabled.
+ */
 		.macro	restore_user_regs
-		ldr	r0, [sp, #S_PSR]		@ Get calling cpsr
-		mov	ip, #I_BIT | MODE_SVC
-		msr	cpsr_c, ip			@ disable IRQs
-		msr	spsr, r0			@ save in spsr_svc
-		ldr	lr, [sp, #S_PC]			@ Get PC
-		ldmia	sp, {r0 - lr}^			@ Get calling r0 - lr
+		ldr	r1, [sp, #S_PSR]		@ Get calling cpsr
+		ldr	lr, [sp, #S_PC]!		@ Get PC
+		msr	spsr, r1			@ save in spsr_svc
+		ldmdb	sp, {r0 - lr}^			@ Get calling r0 - lr
 		mov	r0, r0
-		add	sp, sp, #S_FRAME_SIZE
+		add	sp, sp, #S_FRAME_SIZE - S_PC
 		movs	pc, lr				@ return & move spsr_svc into cpsr
 		.endm
 
+/*
+ * Must be called with IRQs already disabled.
+ */
 		.macro	fast_restore_user_regs
-		mov	ip, #I_BIT | MODE_SVC
-		msr	cpsr_c, ip			@ disable IRQs
 		ldr	r1, [sp, #S_OFF + S_PSR]	@ get calling cpsr
 		ldr	lr, [sp, #S_OFF + S_PC]!	@ get pc
  		msr	spsr, r1			@ save in spsr_svc
@@ -108,11 +128,6 @@
 		.macro	mask_pc, rd, rm
 		.endm
 
-		.macro	enable_irqs, temp
-		mov	\temp, #MODE_SVC
-		msr	cpsr_c, \temp
-		.endm
-
 		.macro	get_current_task, rd
 		mov	\rd, sp, lsr #13
 		mov	\rd, \rd, lsl #13
@@ -136,9 +151,9 @@
 
 #else
 		.macro	save_user_regs
-		str	r0, [sp, #-4]!
-		str	lr, [sp, #-4]!
-		sub	sp, sp, #15*4
+		sub	sp, sp, #S_FRAME_SIZE
+		str	r0, [sp, #S_OLD_R0]
+		str	lr, [sp, #S_PC]
 		stmia	sp, {r0 - lr}^
 		mov	r0, r0
 		.endm
@@ -146,17 +161,16 @@
 		.macro	restore_user_regs
 		ldmia	sp, {r0 - lr}^
 		mov	r0, r0
-		ldr	lr, [sp, #15*4]
-		add	sp, sp, #15*4+8
+		ldr	lr, [sp, #S_PC]
+		add	sp, sp, #S_FRAME_SIZE
 		movs	pc, lr
 		.endm
 
 		.macro	fast_restore_user_regs
-		add	sp, sp, #S_OFF
-		ldmib	sp, {r1 - lr}^
+		add	sp, sp, #S_OFF + S_PC
+		ldmdb	sp, {r1 - lr}^
 		mov	r0, r0
-		ldr	lr, [sp, #15*4]
-		add	sp, sp, #15*4+8
+		ldr	lr, [sp], #S_FRAME_SIZE - S_PC
 		movs	pc, lr
 		.endm
 
@@ -164,7 +178,11 @@
 		bic	\rd, \rm, #PCMASK
 		.endm
 
-		.macro	enable_irqs, temp
+		.macro	disable_irq, temp
+		teqp	pc, #0x08000003
+		.endm
+
+		.macro	enable_irq, temp
 		teqp	pc, #0x00000003
 		.endm
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/head-armv.S linux-2.4.22-pre10/arch/arm/kernel/head-armv.S
--- linux-2.4.21/arch/arm/kernel/head-armv.S	2001-10-11 16:04:57.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/head-armv.S	2003-08-01 13:30:35.000000000 +0000
@@ -52,17 +52,22 @@
 		.endm
 
 /*
- *  Kernel startup entry point.
+ * Kernel startup entry point.
+ * ---------------------------
  *
- * The rules are:
- *  r0      - should be 0
- *  r1      - unique architecture number
- *  MMU     - off
- *  I-cache - on or off
- *  D-cache - off
+ * This is normally called from the decompressor code.  The requirements
+ * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
+ * r1 = machine nr.
  *
- * See linux/arch/arm/tools/mach-types for the complete list of numbers
- * for r1.
+ * This code is mostly position independent, so if you link the kernel at
+ * 0xc0008000, you call this at __pa(0xc0008000).
+ *
+ * See linux/arch/arm/tools/mach-types for the complete list of machine
+ * numbers for r1.
+ *
+ * We're trying to keep crap to a minimum; DO NOT add any machine specific
+ * crap here - that's what the boot loader (or in extreme, well justified
+ * circumstances, zImage) is for.
  */
 		.section ".text.init",#alloc,#execinstr
 		.type	stext, #function
@@ -143,7 +148,6 @@
 
 		.type	__switch_data, %object
 __switch_data:	.long	__mmap_switched
-		.long	SYMBOL_NAME(compat)
 		.long	SYMBOL_NAME(__bss_start)
 		.long	SYMBOL_NAME(_end)
 		.long	SYMBOL_NAME(processor_id)
@@ -151,28 +155,33 @@
 		.long	SYMBOL_NAME(cr_alignment)
 		.long	SYMBOL_NAME(init_task_union)+8192
 
+/*
+ * Enable the MMU.  This completely changes the structure of the visible
+ * memory space.  You will not be able to trace execution through this.
+ * If you have an enquiry about this, *please* check the linux-arm-kernel
+ * mailing list archives BEFORE sending another post to the list.
+ */
 		.type	__ret, %function
 __ret:		ldr	lr, __switch_data
 		mcr	p15, 0, r0, c1, c0
-		mov	r0, r0
+		mrc	p15, 0, r0, c1, c0, 0		@ read it back.
 		mov	r0, r0
 		mov	r0, r0
 		mov	pc, lr
 
-		/*
-		 * This code follows on after the page
-		 * table switch and jump above.
-		 *
-		 * r0  = processor control register
-		 * r1  = machine ID
-		 * r9  = processor ID
-		 */
+/*
+ * The following fragment of code is executed with the MMU on, and uses
+ * absolute addresses; this is not position independent.
+ *
+ *  r0  = processor control register
+ *  r1  = machine ID
+ *  r9  = processor ID
+ */
 		.align	5
 __mmap_switched:
 		adr	r3, __switch_data + 4
-		ldmia	r3, {r2, r4, r5, r6, r7, r8, sp}@ r2 = compat
+		ldmia	r3, {r4, r5, r6, r7, r8, sp}@ r2 = compat
 							@ sp = stack pointer
-		str	r12, [r2]
 
 		mov	fp, #0				@ Clear BSS (and zero fp)
 1:		cmp	r4, r5
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/irq-arch.c linux-2.4.22-pre10/arch/arm/kernel/irq-arch.c
--- linux-2.4.21/arch/arm/kernel/irq-arch.c	2001-08-12 18:13:59.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/irq-arch.c	2003-08-01 13:31:52.000000000 +0000
@@ -20,6 +20,8 @@
 #include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/smp.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/irq.c linux-2.4.22-pre10/arch/arm/kernel/irq.c
--- linux-2.4.21/arch/arm/kernel/irq.c	2001-07-04 21:56:44.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/irq.c	2003-08-01 13:30:29.000000000 +0000
@@ -27,6 +27,8 @@
 #include <linux/slab.h>
 #include <linux/random.h>
 #include <linux/smp.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 #include <linux/init.h>
 
 #include <asm/irq.h>
@@ -46,6 +48,7 @@
 
 static volatile unsigned long irq_err_count;
 static spinlock_t irq_controller_lock;
+static LIST_HEAD(irq_pending);
 
 struct irqdesc irq_desc[NR_IRQS];
 void (*init_arch_irq)(void) __initdata = NULL;
@@ -57,21 +60,32 @@
 {
 }
 
+/*
+ * No architecture-specific irq_finish function defined in arm/arch/irq.h.
+ */
+#ifndef irq_finish
+#define irq_finish(irq) do { } while (0)
+#endif
+
 /**
  *	disable_irq - disable an irq and wait for completion
  *	@irq: Interrupt to disable
  *
- *	Disable the selected interrupt line.
+ *	Disable the selected interrupt line.  We do this lazily.
  *
- *	This function may be called - with care - from IRQ context.
+ *	This function may be called from IRQ context.
  */
 void disable_irq(unsigned int irq)
 {
+	struct irqdesc *desc = irq_desc + irq;
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_controller_lock, flags);
-	irq_desc[irq].enabled = 0;
-	irq_desc[irq].mask(irq);
+	if (!desc->disable_depth++) {
+#ifndef CONFIG_CPU_SA1100
+		desc->mask(irq);
+#endif
+	}
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
 
@@ -79,19 +93,37 @@
  *	enable_irq - enable interrupt handling on an irq
  *	@irq: Interrupt to enable
  *
- *	Re-enables the processing of interrupts on this IRQ line
+ *	Re-enables the processing of interrupts on this IRQ line.
+ *	Note that this may call the interrupt handler, so you may
+ *	get unexpected results if you hold IRQs disabled.
  *
  *	This function may be called from IRQ context.
  */
 void enable_irq(unsigned int irq)
 {
+	struct irqdesc *desc = irq_desc + irq;
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_controller_lock, flags);
-	irq_desc[irq].probing = 0;
-	irq_desc[irq].triggered = 0;
-	irq_desc[irq].enabled = 1;
-	irq_desc[irq].unmask(irq);
+	if (!desc->disable_depth) {
+		printk("enable_irq(%u) unbalanced from %p\n", irq,
+			__builtin_return_address(0));
+	} else if (!--desc->disable_depth) {
+		desc->probing = 0;
+		desc->unmask(irq);
+
+		/*
+		 * If the interrupt is waiting to be processed,
+		 * try to re-run it.  We can't directly run it
+		 * from here since the caller might be in an
+		 * interrupt-protected region.
+		 */
+		if (desc->pending) {
+			desc->pending = 0;
+			if (list_empty(&desc->pend))
+				list_add(&desc->pend, &irq_pending);
+		}
+	}
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
 
@@ -128,7 +160,7 @@
  * a large number if IRQs to appear in the same jiffie with the
  * same instruction pointer (or within 2 instructions).
  */
-static void check_irq_lock(struct irqdesc *desc, int irq, struct pt_regs *regs)
+static int check_irq_lock(struct irqdesc *desc, int irq, struct pt_regs *regs)
 {
 	unsigned long instr_ptr = instruction_pointer(regs);
 
@@ -137,95 +169,202 @@
 		desc->lck_cnt += 1;
 
 		if (desc->lck_cnt > MAX_IRQ_CNT) {
-			printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq);
-			disable_irq(irq);
+			if (!desc->lck_warned++)
+				printk(KERN_ERR "IRQ LOCK: IRQ%d is locking the system, disabled\n", irq);
+			mod_timer(&desc->lck_timer, jiffies + 10*HZ);
+			return 1;
 		}
 	} else {
 		desc->lck_cnt = 0;
 		desc->lck_pc  = instruction_pointer(regs);
 		desc->lck_jif = jiffies;
+		if (desc->lck_warned < 0)
+			desc->lck_warned ++;
 	}
+	return 0;
+}
+
+static void
+__do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
+{
+	unsigned int status;
+
+	spin_unlock(&irq_controller_lock);
+
+	if (!(action->flags & SA_INTERRUPT))
+		local_irq_enable();
+
+	status = 0;
+	do {
+		status |= action->flags;
+		action->handler(irq, action->dev_id, regs);
+		action = action->next;
+	} while (action);
+
+	if (status & SA_SAMPLE_RANDOM)
+		add_interrupt_randomness(irq);
+
+	spin_lock_irq(&irq_controller_lock);
 }
 
 /*
  * do_IRQ handles all normal device IRQ's
  */
-asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
+void do_IRQ(int irq, struct pt_regs * regs)
 {
-	struct irqdesc * desc;
-	struct irqaction * action;
-	int cpu;
+	struct irqdesc *desc = irq_desc + irq;
 
-	irq = fixup_irq(irq);
+	desc->triggered = 1;
 
 	/*
-	 * Some hardware gives randomly wrong interrupts.  Rather
-	 * than crashing, do something sensible.
+	 * Acknowledge and clear the IRQ, but (if its
+	 * a level-based IRQ, don't mask it)
 	 */
-	if (irq >= NR_IRQS)
-		goto bad_irq;
+	desc->mask_ack(irq);
 
-	desc = irq_desc + irq;
+	/*
+	 * If we're currently running this IRQ, or its disabled,
+	 * we shouldn't process the IRQ.  Instead, turn on the
+	 * hardware masks.
+	 */
+	if (desc->running || desc->disable_depth)
+		goto running;
 
-	spin_lock(&irq_controller_lock);
-	desc->mask_ack(irq);
-	spin_unlock(&irq_controller_lock);
+	/*
+	 * Mark the IRQ currently in progress.
+	 */
+	desc->running = 1;
 
-	cpu = smp_processor_id();
-	irq_enter(cpu, irq);
-	kstat.irqs[cpu][irq]++;
-	desc->triggered = 1;
+	kstat.irqs[smp_processor_id()][irq]++;
 
-	/* Return with this interrupt masked if no action */
-	action = desc->action;
+	do {
+		struct irqaction *action;
 
-	if (action) {
-		int status = 0;
+		action = desc->action;
+		if (!action)
+			break;
 
-		if (desc->nomask) {
-			spin_lock(&irq_controller_lock);
+		if (desc->pending && desc->disable_depth == 0) {
+			desc->pending = 0;
 			desc->unmask(irq);
-			spin_unlock(&irq_controller_lock);
 		}
 
-		if (!(action->flags & SA_INTERRUPT))
-			__sti();
+		__do_irq(irq, action, regs);
+	} while (desc->pending && desc->disable_depth == 0);
 
-		do {
-			status |= action->flags;
-			action->handler(irq, action->dev_id, regs);
-			action = action->next;
-		} while (action);
+	desc->running = 0;
 
-		if (status & SA_SAMPLE_RANDOM)
-			add_interrupt_randomness(irq);
-		__cli();
+	/*
+	 * If we are disabled or freed, shut down the handler.
+	 */
+	if (desc->action && !check_irq_lock(desc, irq, regs))
+		desc->unmask(irq);
+	return;
 
-		if (!desc->nomask && desc->enabled) {
-			spin_lock(&irq_controller_lock);
-			desc->unmask(irq);
-			spin_unlock(&irq_controller_lock);
+ running:
+	/*
+	 * We got another IRQ while this one was masked or
+	 * currently running.  Delay it.
+	 */
+	desc->pending = 1;
+}
+
+static void do_pending_irqs(struct pt_regs *regs)
+{
+	struct list_head head, *l, *n;
+
+	do {
+		struct irqdesc *desc;
+
+		/*
+		 * First, take the pending interrupts off the list.
+		 * The act of calling the handlers may add some IRQs
+		 * back onto the list.
+		 */
+		head = irq_pending;
+		INIT_LIST_HEAD(&irq_pending);
+		head.next->prev = &head;
+		head.prev->next = &head;
+
+		/*
+		 * Now run each entry.  We must delete it from our
+		 * list before calling the handler.
+		 */
+		list_for_each_safe(l, n, &head) {
+			desc = list_entry(l, struct irqdesc, pend);
+			list_del_init(&desc->pend);
+			do_IRQ(desc - irq_desc, regs);
 		}
-	}
+
+		/*
+		 * The list must be empty.
+		 */
+		BUG_ON(!list_empty(&head));
+	} while (!list_empty(&irq_pending));
+}
+
+/*
+ * do_IRQ handles all hardware IRQ's.  Decoded IRQs should not
+ * come via this function.  Instead, they should provide their
+ * own 'handler'
+ */
+asmlinkage void asm_do_IRQ(int irq, struct pt_regs *regs)
+{
+	irq = fixup_irq(irq);
 
 	/*
-	 * Debug measure - hopefully we can continue if an
-	 * IRQ lockup problem occurs...
+	 * Some hardware gives randomly wrong interrupts.  Rather
+	 * than crashing, do something sensible.
 	 */
-	check_irq_lock(desc, irq, regs);
+	if (irq < NR_IRQS) {
+		int cpu = smp_processor_id();
 
-	irq_exit(cpu, irq);
+		irq_enter(cpu, irq);
+		spin_lock(&irq_controller_lock);
+		do_IRQ(irq, regs);
 
-	if (softirq_pending(cpu))
-		do_softirq();
-	return;
+		/*
+		 * Now re-run any pending interrupts.
+		 */
+		if (!list_empty(&irq_pending))
+			do_pending_irqs(regs);
+
+		spin_unlock(&irq_controller_lock);
+		irq_exit(cpu, irq);
+
+		if (softirq_pending(cpu))
+			do_softirq();
+
+		irq_finish(irq);
+		return;
+	}
 
-bad_irq:
 	irq_err_count += 1;
 	printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
+
+	irq_finish(irq);
 	return;
 }
 
+static void irqlck_timeout(unsigned long _data)
+{
+	struct irqdesc *desc = (struct irqdesc *)_data;
+
+	spin_lock(&irq_controller_lock);
+
+	del_timer(&desc->lck_timer);
+
+	desc->lck_cnt = 0;
+	desc->lck_pc  = 0;
+	desc->lck_jif = 0;
+	desc->lck_warned = -10;
+
+	if (desc->disable_depth == 0)
+		desc->unmask(desc - irq_desc);
+
+	spin_unlock(&irq_controller_lock);
+}
+
 #ifdef CONFIG_ARCH_ACORN
 void do_ecard_IRQ(int irq, struct pt_regs *regs)
 {
@@ -302,10 +441,12 @@
 	*p = new;
 
 	if (!shared) {
-		desc->nomask = (new->flags & SA_IRQNOMASK) ? 1 : 0;
 		desc->probing = 0;
+		desc->running = 0;
+		desc->pending = 0;
+		desc->disable_depth = 1;
 		if (!desc->noautoenable) {
-			desc->enabled = 1;
+			desc->disable_depth = 0;
 			desc->unmask(irq);
 		}
 	}
@@ -383,7 +524,7 @@
  *	On a shared IRQ the caller must ensure the interrupt is disabled
  *	on the card it drives before calling this function.
  *
- *	This function may be called from interrupt context.
+ *	This function must not be called from interrupt context.
  */
 void free_irq(unsigned int irq, void *dev_id)
 {
@@ -416,6 +557,8 @@
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
 
+static DECLARE_MUTEX(probe_sem);
+
 /* Start the interrupt probing.  Unlike other architectures,
  * we don't return a mask of interrupts from probe_irq_on,
  * but return the number of interrupts enabled for the probe.
@@ -427,15 +570,15 @@
 	unsigned int i, irqs = 0;
 	unsigned long delay;
 
+	down(&probe_sem);
+
 	/*
 	 * first snaffle up any unassigned but
 	 * probe-able interrupts
 	 */
 	spin_lock_irq(&irq_controller_lock);
 	for (i = 0; i < NR_IRQS; i++) {
-		if (!irq_desc[i].valid ||
-		    !irq_desc[i].probe_ok ||
-		    irq_desc[i].action)
+		if (!irq_desc[i].probe_ok || irq_desc[i].action)
 			continue;
 
 		irq_desc[i].probing = 1;
@@ -456,18 +599,31 @@
 	 */
 	spin_lock_irq(&irq_controller_lock);
 	for (i = 0; i < NR_IRQS; i++) {
-		if (irq_desc[i].probing &&
-		    irq_desc[i].triggered) {
+		if (irq_desc[i].probing && irq_desc[i].triggered) {
 			irq_desc[i].probing = 0;
 			irqs -= 1;
 		}
 	}
 	spin_unlock_irq(&irq_controller_lock);
 
-	/* now filter out any obviously spurious interrupts */
 	return irqs;
 }
 
+unsigned int probe_irq_mask(unsigned long irqs)
+{
+	unsigned int mask = 0, i;
+
+	spin_lock_irq(&irq_controller_lock);
+	for (i = 0; i < 16 && i < NR_IRQS; i++)
+		if (irq_desc[i].probing && irq_desc[i].triggered)
+			mask |= 1 << i;
+	spin_unlock_irq(&irq_controller_lock);
+
+	up(&probe_sem);
+
+	return mask;
+}
+
 /*
  * Possible return values:
  *  >= 0 - interrupt number
@@ -499,6 +655,8 @@
 out:
 	spin_unlock_irq(&irq_controller_lock);
 
+	up(&probe_sem);
+
 	return irq_found;
 }
 
@@ -512,12 +670,17 @@
 	int irq;
 
 	for (irq = 0; irq < NR_IRQS; irq++) {
+		irq_desc[irq].disable_depth = 1;
 		irq_desc[irq].probe_ok = 0;
 		irq_desc[irq].valid    = 0;
 		irq_desc[irq].noautoenable = 0;
 		irq_desc[irq].mask_ack = dummy_mask_unmask_irq;
 		irq_desc[irq].mask     = dummy_mask_unmask_irq;
 		irq_desc[irq].unmask   = dummy_mask_unmask_irq;
+		INIT_LIST_HEAD(&irq_desc[irq].pend);
+		init_timer(&irq_desc[irq].lck_timer);
+		irq_desc[irq].lck_timer.data = (unsigned long)&irq_desc[irq];
+		irq_desc[irq].lck_timer.function = irqlck_timeout;
 	}
 
 	init_arch_irq();
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/oldlatches.c linux-2.4.22-pre10/arch/arm/kernel/oldlatches.c
--- linux-2.4.21/arch/arm/kernel/oldlatches.c	2001-08-12 18:13:59.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/oldlatches.c	2003-08-01 13:31:02.000000000 +0000
@@ -29,10 +29,10 @@
 	if (machine_is_archimedes()) {
 		unsigned long flags;
 
-		local_save_flags(flags);
+		local_irq_save(flags);
 		latch_a_copy = (latch_a_copy & ~mask) | newdata;
 		__raw_writeb(latch_a_copy, LATCHA_BASE);
-		local_restore_flags(flags);
+		local_irq_restore(flags);
 
 		printk("Latch: A = 0x%02x\n", latch_a_copy);
 	} else
@@ -46,10 +46,10 @@
 	if (machine_is_archimedes()) {
 		unsigned long flags;
 
-		local_save_flags(flags);
+		local_irq_save(flags);
 		latch_b_copy = (latch_b_copy & ~mask) | newdata;
 		__raw_writeb(latch_b_copy, LATCHB_BASE);
-		local_restore_flags(flags);
+		local_irq_restore(flags);
 
 		printk("Latch: B = 0x%02x\n", latch_b_copy);
 	} else
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/process.c linux-2.4.22-pre10/arch/arm/kernel/process.c
--- linux-2.4.21/arch/arm/kernel/process.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/process.c	2003-08-01 13:32:33.000000000 +0000
@@ -24,18 +24,10 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 
-#include <asm/leds.h>
 #include <asm/system.h>
+#include <asm/leds.h>
 #include <asm/uaccess.h>
 
-/*
- * Values for cpu_do_idle()
- */
-#define IDLE_WAIT_SLOW	0
-#define IDLE_WAIT_FAST	1
-#define IDLE_CLOCK_SLOW	2
-#define IDLE_CLOCK_FAST	3
-
 extern const char *processor_modes[];
 extern void setup_mm_for_reboot(char mode);
 
@@ -75,6 +67,18 @@
 void (*pm_power_off)(void);
 
 /*
+ * This is our default idle handler.  We need to disable
+ * interrupts here to ensure we don't miss a wakeup call.
+ */
+void default_idle(void)
+{
+	local_irq_disable();
+	if (!current->need_resched && !hlt_counter)
+		arch_idle();
+	local_irq_enable();
+}
+
+/*
  * The idle thread.  We try to conserve power, while trying to keep
  * overall latency low.  The architecture specific idle is passed
  * a value to indicate the level of "idleness" of the system.
@@ -89,7 +93,7 @@
 	while (1) {
 		void (*idle)(void) = pm_idle;
 		if (!idle)
-			idle = arch_idle;
+			idle = default_idle;
 		leds_event(led_idle_start);
 		while (!current->need_resched)
 			idle();
@@ -176,15 +180,15 @@
 		flags & CC_Z_BIT ? 'Z' : 'z',
 		flags & CC_C_BIT ? 'C' : 'c',
 		flags & CC_V_BIT ? 'V' : 'v');
-	printk("  IRQs %s  FIQs %s  Mode %s%s  Segment %s\n",
-		interrupts_enabled(regs) ? "on" : "off",
-		fast_interrupts_enabled(regs) ? "on" : "off",
+	printk("  IRQs o%s  FIQs o%s  Mode %s%s  Segment %s\n",
+		interrupts_enabled(regs) ? "n" : "ff",
+		fast_interrupts_enabled(regs) ? "n" : "ff",
 		processor_modes[processor_mode(regs)],
 		thumb_mode(regs) ? " (T)" : "",
 		get_fs() == get_ds() ? "kernel" : "user");
 #if defined(CONFIG_CPU_32)
 	{
-		int ctrl, transbase, dac;
+		unsigned int ctrl, transbase, dac;
 		  __asm__ (
 		"	mrc p15, 0, %0, c1, c0\n"
 		"	mrc p15, 0, %1, c2, c0\n"
@@ -282,12 +286,22 @@
 {
 }
 
+static void default_fp_init(union fp_state *fp)
+{
+	memset(fp, 0, sizeof(union fp_state));
+}
+
+void (*fp_init)(union fp_state *) = default_fp_init;
+
 void flush_thread(void)
 {
-	memset(&current->thread.debug, 0, sizeof(struct debug_info));
-	memset(&current->thread.fpstate, 0, sizeof(union fp_state));
-	current->used_math = 0;
-	current->flags &= ~PF_USEDFPU;
+	struct task_struct *tsk = current;
+
+	tsk->flags &= ~PF_USEDFPU;
+	tsk->used_math = 0;
+
+	memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
+	fp_init(&tsk->thread.fpstate);
 }
 
 void release_thread(struct task_struct *dead_task)
@@ -296,16 +310,16 @@
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
-	unsigned long unused,
-	struct task_struct * p, struct pt_regs * regs)
+int
+copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
+	    unsigned long unused, struct task_struct * p, struct pt_regs * regs)
 {
-	struct pt_regs * childregs;
+	struct pt_regs *childregs;
 	struct context_save_struct * save;
 
 	atomic_set(&p->thread.refcount, 1);
 
-	childregs = ((struct pt_regs *)((unsigned long)p + 8192)) - 1;
+	childregs = ((struct pt_regs *)((unsigned long)p + 8192 - 8)) - 1;
 	*childregs = *regs;
 	childregs->ARM_r0 = 0;
 	childregs->ARM_sp = esp;
@@ -324,10 +338,12 @@
  */
 int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
 {
-	if (current->used_math)
+	int used_math = current->used_math;
+
+	if (used_math)
 		memcpy(fp, &current->thread.fpstate.soft, sizeof (*fp));
 
-	return current->used_math;
+	return used_math;
 }
 
 /*
@@ -347,8 +363,8 @@
 
 	dump->u_debugreg[0] = tsk->thread.debug.bp[0].address;
 	dump->u_debugreg[1] = tsk->thread.debug.bp[1].address;
-	dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn;
-	dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn;
+	dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn.arm;
+	dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn.arm;
 	dump->u_debugreg[4] = tsk->thread.debug.nsaved;
 
 	if (dump->start_stack < 0x04000000)
@@ -371,18 +387,18 @@
 	pid_t __ret;
 
 	__asm__ __volatile__(
-	"orr	r0, %1, %2	@ kernel_thread sys_clone
-	mov	r1, #0
-	"__syscall(clone)"
-	movs	%0, r0		@ if we are the child
-	bne	1f
-	mov	fp, #0		@ ensure that fp is zero
-	mov	r0, %4
-	mov	lr, pc
-	mov	pc, %3
-	b	sys_exit
+	"orr	r0, %1, %2	@ kernel_thread sys_clone	\n\
+	mov	r1, #0						\n\
+	"__syscall(clone)"					\n\
+	movs	%0, r0		@ if we are the child		\n\
+	bne	1f						\n\
+	mov	fp, #0		@ ensure that fp is zero	\n\
+	mov	r0, %4						\n\
+	mov	lr, pc						\n\
+	mov	pc, %3						\n\
+	b	sys_exit					\n\
 1:	"
-        : "=r" (__ret)
+        : "=&r" (__ret)
         : "Ir" (flags), "I" (CLONE_VM), "r" (fn), "r" (arg)
 	: "r0", "r1", "lr");
 	return __ret;
@@ -405,7 +421,7 @@
 		return 0;
 
 	stack_page = 4096 + (unsigned long)p;
-	fp = get_css_fp(&p->thread);
+	fp = thread_saved_fp(&p->thread);
 	do {
 		if (fp < stack_page || fp > 4092+stack_page)
 			return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/ptrace.c linux-2.4.22-pre10/arch/arm/kernel/ptrace.c
--- linux-2.4.21/arch/arm/kernel/ptrace.c	2001-09-19 00:03:51.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/ptrace.c	2003-08-01 13:31:08.000000000 +0000
@@ -9,6 +9,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -16,6 +17,7 @@
 #include <linux/smp_lock.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
+#include <linux/bitops.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -33,18 +35,24 @@
 /*
  * Breakpoint SWI instruction: SWI &9F0001
  */
-#define BREAKINST	0xef9f0001
+#define BREAKINST_ARM	0xef9f0001
+/* fill this in later */
+#define BREAKINST_THUMB	0xdf00
 
 /*
  * Get the address of the live pt_regs for the specified task.
  * These are saved onto the top kernel stack when the process
  * is not running.
+ *
+ * Note: if a user thread is execve'd from kernel space, the
+ * kernel stack will not be empty on entry to the kernel, so
+ * ptracing these tasks will fail.
  */
 static inline struct pt_regs *
 get_user_regs(struct task_struct *task)
 {
 	return (struct pt_regs *)
-		((unsigned long)task + 8192 - sizeof(struct pt_regs));
+		((unsigned long)task + 8192 - 8 - sizeof(struct pt_regs));
 }
 
 /*
@@ -53,7 +61,7 @@
  * this routine assumes that all the privileged stacks are in our
  * data space.
  */
-static inline long get_stack_long(struct task_struct *task, int offset)
+static inline long get_user_reg(struct task_struct *task, int offset)
 {
 	return get_user_regs(task)->uregs[offset];
 }
@@ -65,14 +73,14 @@
  * data space.
  */
 static inline int
-put_stack_long(struct task_struct *task, int offset, long data)
+put_user_reg(struct task_struct *task, int offset, long data)
 {
 	struct pt_regs newregs, *regs = get_user_regs(task);
 	int ret = -EINVAL;
 
 	newregs = *regs;
 	newregs.uregs[offset] = data;
-	
+
 	if (valid_user_regs(&newregs)) {
 		regs->uregs[offset] = data;
 		ret = 0;
@@ -82,23 +90,32 @@
 }
 
 static inline int
-read_tsk_long(struct task_struct *child, unsigned long addr, unsigned long *res)
+read_u32(struct task_struct *task, unsigned long addr, u32 *res)
 {
-	int copied;
+	int ret;
 
-	copied = access_process_vm(child, addr, res, sizeof(*res), 0);
+	ret = access_process_vm(task, addr, res, sizeof(*res), 0);
 
-	return copied != sizeof(*res) ? -EIO : 0;
+	return ret == sizeof(*res) ? 0 : -EIO;
 }
 
 static inline int
-write_tsk_long(struct task_struct *child, unsigned long addr, unsigned long val)
+read_instr(struct task_struct *task, unsigned long addr, u32 *res)
 {
-	int copied;
-
-	copied = access_process_vm(child, addr, &val, sizeof(val), 1);
+	int ret;
 
-	return copied != sizeof(val) ? -EIO : 0;
+	if (addr & 1) {
+		u16 val;
+		ret = access_process_vm(task, addr & ~1, &val, sizeof(val), 0);
+		ret = ret == sizeof(val) ? 0 : -EIO;
+		*res = val;
+	} else {
+		u32 val;
+		ret = access_process_vm(task, addr & ~3, &val, sizeof(val), 0);
+		ret = ret == sizeof(val) ? 0 : -EIO;
+		*res = val;
+	}
+	return ret;
 }
 
 /*
@@ -110,7 +127,7 @@
 	unsigned int reg = (insn >> 16) & 15;
 	unsigned long val;
 
-	val = get_stack_long(child, reg);
+	val = get_user_reg(child, reg);
 	if (reg == 15)
 		val = pc_pointer(val + 8);
 
@@ -132,10 +149,10 @@
 		shift = (insn >> 8) & 15;
 		type = 3;
 	} else {
-		val = get_stack_long (child, insn & 15);
+		val = get_user_reg (child, insn & 15);
 
 		if (insn & (1 << 4))
-			shift = (int)get_stack_long (child, (insn >> 8) & 15);
+			shift = (int)get_user_reg (child, (insn >> 8) & 15);
 		else
 			shift = (insn >> 7) & 31;
 
@@ -165,7 +182,7 @@
 	int shift;
 	int type;
 
-	val = get_stack_long(child, insn & 15);
+	val = get_user_reg(child, insn & 15);
 	shift = (insn >> 7) & 31;
 	type = (insn >> 5) & 3;
 
@@ -182,10 +199,24 @@
 	return val;
 }
 
+#define OP_MASK	0x01e00000
+#define OP_AND	0x00000000
+#define OP_EOR	0x00200000
+#define OP_SUB	0x00400000
+#define OP_RSB	0x00600000
+#define OP_ADD	0x00800000
+#define OP_ADC	0x00a00000
+#define OP_SBC	0x00c00000
+#define OP_RSC	0x00e00000
+#define OP_ORR	0x01800000
+#define OP_MOV	0x01a00000
+#define OP_BIC	0x01c00000
+#define OP_MVN	0x01e00000
+
 static unsigned long
 get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn)
 {
-	unsigned long alt = 0;
+	u32 alt = 0;
 
 	switch (insn & 0x0e000000) {
 	case 0x00000000:
@@ -200,21 +231,21 @@
 
 		aluop1 = ptrace_getrn(child, insn);
 		aluop2 = ptrace_getaluop2(child, insn);
-		ccbit  = get_stack_long(child, REG_PSR) & CC_C_BIT ? 1 : 0;
+		ccbit  = get_user_reg(child, REG_PSR) & CC_C_BIT ? 1 : 0;
 
-		switch (insn & 0x01e00000) {
-		case 0x00000000: alt = aluop1 & aluop2;		break;
-		case 0x00200000: alt = aluop1 ^ aluop2;		break;
-		case 0x00400000: alt = aluop1 - aluop2;		break;
-		case 0x00600000: alt = aluop2 - aluop1;		break;
-		case 0x00800000: alt = aluop1 + aluop2;		break;
-		case 0x00a00000: alt = aluop1 + aluop2 + ccbit;	break;
-		case 0x00c00000: alt = aluop1 - aluop2 + ccbit;	break;
-		case 0x00e00000: alt = aluop2 - aluop1 + ccbit;	break;
-		case 0x01800000: alt = aluop1 | aluop2;		break;
-		case 0x01a00000: alt = aluop2;			break;
-		case 0x01c00000: alt = aluop1 & ~aluop2;	break;
-		case 0x01e00000: alt = ~aluop2;			break;
+		switch (insn & OP_MASK) {
+		case OP_AND: alt = aluop1 & aluop2;		break;
+		case OP_EOR: alt = aluop1 ^ aluop2;		break;
+		case OP_SUB: alt = aluop1 - aluop2;		break;
+		case OP_RSB: alt = aluop2 - aluop1;		break;
+		case OP_ADD: alt = aluop1 + aluop2;		break;
+		case OP_ADC: alt = aluop1 + aluop2 + ccbit;	break;
+		case OP_SBC: alt = aluop1 - aluop2 + ccbit;	break;
+		case OP_RSC: alt = aluop2 - aluop1 + ccbit;	break;
+		case OP_ORR: alt = aluop1 | aluop2;		break;
+		case OP_MOV: alt = aluop2;			break;
+		case OP_BIC: alt = aluop1 & ~aluop2;		break;
+		case OP_MVN: alt = ~aluop2;			break;
 		}
 		break;
 	}
@@ -241,7 +272,7 @@
 				else
 					base -= aluop2;
 			}
-			if (read_tsk_long(child, base, &alt) == 0)
+			if (read_u32(child, base, &alt) == 0)
 				alt = pc_pointer(alt);
 		}
 		break;
@@ -255,13 +286,7 @@
 			unsigned int nr_regs;
 
 			if (insn & (1 << 23)) {
-				nr_regs = insn & 65535;
-
-				nr_regs = (nr_regs & 0x5555) + ((nr_regs & 0xaaaa) >> 1);
-				nr_regs = (nr_regs & 0x3333) + ((nr_regs & 0xcccc) >> 2);
-				nr_regs = (nr_regs & 0x0707) + ((nr_regs & 0x7070) >> 4);
-				nr_regs = (nr_regs & 0x000f) + ((nr_regs & 0x0f00) >> 8);
-				nr_regs <<= 2;
+				nr_regs = hweight16(insn & 65535) << 2;
 
 				if (!(insn & (1 << 24)))
 					nr_regs -= 4;
@@ -274,8 +299,8 @@
 
 			base = ptrace_getrn(child, insn);
 
-			if (read_tsk_long(child, base + nr_regs, &alt) == 0)
-				alt = pc_pointer (alt);
+			if (read_u32(child, base + nr_regs, &alt) == 0)
+				alt = pc_pointer(alt);
 			break;
 		}
 		break;
@@ -304,36 +329,82 @@
 }
 
 static int
-add_breakpoint(struct task_struct *child, struct debug_info *dbg, unsigned long addr)
+swap_insn(struct task_struct *task, unsigned long addr,
+	  void *old_insn, void *new_insn, int size)
+{
+	int ret;
+
+	ret = access_process_vm(task, addr, old_insn, size, 0);
+	if (ret == size)
+		ret = access_process_vm(task, addr, new_insn, size, 1);
+	return ret;
+}
+
+static void
+add_breakpoint(struct task_struct *task, struct debug_info *dbg, unsigned long addr)
 {
 	int nr = dbg->nsaved;
-	int res = -EINVAL;
 
 	if (nr < 2) {
-		res = read_tsk_long(child, addr, &dbg->bp[nr].insn);
-		if (res == 0)
-			res = write_tsk_long(child, addr, BREAKINST);
+		u32 new_insn = BREAKINST_ARM;
+		int res;
 
-		if (res == 0) {
+		res = swap_insn(task, addr, &dbg->bp[nr].insn, &new_insn, 4);
+
+		if (res == 4) {
 			dbg->bp[nr].address = addr;
 			dbg->nsaved += 1;
 		}
 	} else
 		printk(KERN_ERR "ptrace: too many breakpoints\n");
+}
+
+/*
+ * Clear one breakpoint in the user program.  We copy what the hardware
+ * does and use bit 0 of the address to indicate whether this is a Thumb
+ * breakpoint or an ARM breakpoint.
+ */
+static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp)
+{
+	unsigned long addr = bp->address;
+	union debug_insn old_insn;
+	int ret;
+
+	if (addr & 1) {
+		ret = swap_insn(task, addr & ~1, &old_insn.thumb,
+				&bp->insn.thumb, 2);
+
+		if (ret != 2 || old_insn.thumb != BREAKINST_THUMB)
+			printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at "
+				"0x%08lx (0x%04x)\n", task->comm, task->pid,
+				addr, old_insn.thumb);
+	} else {
+		ret = swap_insn(task, addr & ~3, &old_insn.thumb,
+				&bp->insn.thumb, 4);
 
-	return res;
+		if (ret != 4 || old_insn.arm != BREAKINST_ARM)
+			printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at "
+				"0x%08lx (0x%08x)\n", task->comm, task->pid,
+				addr, old_insn.arm);
+	}
 }
 
-int ptrace_set_bpt(struct task_struct *child)
+void ptrace_set_bpt(struct task_struct *child)
 {
 	struct pt_regs *regs;
-	unsigned long pc, insn;
+	unsigned long pc;
+	u32 insn;
 	int res;
 
 	regs = get_user_regs(child);
 	pc = instruction_pointer(regs);
 
-	res = read_tsk_long(child, pc, &insn);
+	if (thumb_mode(regs)) {
+		printk(KERN_WARNING "ptrace: can't handle thumb mode\n");
+		return;
+	}
+
+	res = read_instr(child, pc, &insn);
 	if (!res) {
 		struct debug_info *dbg = &child->thread.debug;
 		unsigned long alt;
@@ -342,7 +413,7 @@
 
 		alt = get_branch_address(child, pc, insn);
 		if (alt)
-			res = add_breakpoint(child, dbg, alt);
+			add_breakpoint(child, dbg, alt);
 
 		/*
 		 * Note that we ignore the result of setting the above
@@ -354,10 +425,8 @@
 		 * loose control of the thread during single stepping.
 		 */
 		if (!alt || predicate(insn) != PREDICATE_ALWAYS)
-			res = add_breakpoint(child, dbg, pc + 4);
+			add_breakpoint(child, dbg, pc + 4);
 	}
-
-	return res;
 }
 
 /*
@@ -366,24 +435,17 @@
  */
 void __ptrace_cancel_bpt(struct task_struct *child)
 {
-	struct debug_info *dbg = &child->thread.debug;
-	int i, nsaved = dbg->nsaved;
+	int i, nsaved = child->thread.debug.nsaved;
 
-	dbg->nsaved = 0;
+	child->thread.debug.nsaved = 0;
 
 	if (nsaved > 2) {
 		printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
 		nsaved = 2;
 	}
 
-	for (i = 0; i < nsaved; i++) {
-		unsigned long tmp;
-
-		read_tsk_long(child, dbg->bp[i].address, &tmp);
-		write_tsk_long(child, dbg->bp[i].address, dbg->bp[i].insn);
-		if (tmp != BREAKINST)
-			printk(KERN_ERR "ptrace_cancel_bpt: weirdness\n");
-	}
+	for (i = 0; i < nsaved; i++)
+		clear_breakpoint(child, &child->thread.debug.bp[i]);
 }
 
 /*
@@ -396,6 +458,114 @@
 	__ptrace_cancel_bpt(child);
 }
 
+/*
+ * Handle hitting a breakpoint.  regs points at the instruction.
+ */
+void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
+{
+	siginfo_t info;
+
+	/*
+	 * The PC is pointing at the next instruction.  Fix this.
+	 */
+	regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
+
+	__ptrace_cancel_bpt(tsk);
+
+	info.si_signo = SIGTRAP;
+	info.si_errno = 0;
+	info.si_code  = TRAP_BRKPT;
+	info.si_addr  = (void *)instruction_pointer(regs);
+
+	force_sig_info(SIGTRAP, &info, tsk);
+}
+
+/*
+ * Read the word at offset "off" into the "struct user".  We
+ * actually access the pt_regs stored on the kernel stack.
+ */
+static int ptrace_read_user(struct task_struct *tsk, unsigned long off,
+			    unsigned long *ret)
+{
+	unsigned long tmp;
+
+	if (off & 3 || off >= sizeof(struct user))
+		return -EIO;
+
+	tmp = 0;
+	if (off < sizeof(struct pt_regs))
+		tmp = get_user_reg(tsk, off >> 2);
+
+	return put_user(tmp, ret);
+}
+
+/*
+ * Write the word at offset "off" into "struct user".  We
+ * actually access the pt_regs stored on the kernel stack.
+ */
+static int ptrace_write_user(struct task_struct *tsk, unsigned long off,
+			     unsigned long val)
+{
+	if (off & 3 || off >= sizeof(struct user))
+		return -EIO;
+
+	if (off >= sizeof(struct pt_regs))
+		return 0;
+
+	return put_user_reg(tsk, off >> 2, val);
+}
+
+/*
+ * Get all user integer registers.
+ */
+static int ptrace_getregs(struct task_struct *tsk, void *uregs)
+{
+	struct pt_regs *regs = get_user_regs(tsk);
+
+	return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
+}
+
+/*
+ * Set all user integer registers.
+ */
+static int ptrace_setregs(struct task_struct *tsk, void *uregs)
+{
+	struct pt_regs newregs;
+	int ret;
+
+	ret = -EFAULT;
+	if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) {
+		struct pt_regs *regs = get_user_regs(tsk);
+
+		ret = -EINVAL;
+		if (valid_user_regs(&newregs)) {
+			*regs = newregs;
+			ret = 0;
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * Get the child FPU state.
+ */
+static int ptrace_getfpregs(struct task_struct *tsk, void *ufp)
+{
+	return copy_to_user(ufp, &tsk->thread.fpstate,
+			    sizeof(struct user_fp)) ? -EFAULT : 0;
+}
+
+/*
+ * Set the child FPU state.
+ */
+static int ptrace_setfpregs(struct task_struct *tsk, void *ufp)
+{
+	tsk->used_math = 1;
+	return copy_from_user(&tsk->thread.fpstate, ufp,
+			      sizeof(struct user_fp)) ? -EFAULT : 0;
+}
+
 static int do_ptrace(int request, struct task_struct *child, long addr, long data)
 {
 	unsigned long tmp;
@@ -407,23 +577,16 @@
 		 */
 		case PTRACE_PEEKTEXT:
 		case PTRACE_PEEKDATA:
-			ret = read_tsk_long(child, addr, &tmp);
-			if (!ret)
+			ret = access_process_vm(child, addr, &tmp,
+						sizeof(unsigned long), 0);
+			if (ret == sizeof(unsigned long))
 				ret = put_user(tmp, (unsigned long *) data);
+			else
+				ret = -EIO;
 			break;
 
-		/*
-		 * read the word at location "addr" in the user registers.
-		 */
 		case PTRACE_PEEKUSR:
-			ret = -EIO;
-			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
-				break;
-
-			tmp = 0;  /* Default return condition */
-			if (addr < sizeof(struct pt_regs))
-				tmp = get_stack_long(child, (int)addr >> 2);
-			ret = put_user(tmp, (unsigned long *)data);
+			ret = ptrace_read_user(child, addr, (unsigned long *)data);
 			break;
 
 		/*
@@ -431,19 +594,16 @@
 		 */
 		case PTRACE_POKETEXT:
 		case PTRACE_POKEDATA:
-			ret = write_tsk_long(child, addr, data);
+			ret = access_process_vm(child, addr, &data,
+						sizeof(unsigned long), 1);
+			if (ret == sizeof(unsigned long))
+				ret = 0;
+			else
+				ret = -EIO;
 			break;
 
-		/*
-		 * write the word at location addr in the user registers.
-		 */
 		case PTRACE_POKEUSR:
-			ret = -EIO;
-			if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
-				break;
-
-			if (addr < sizeof(struct pt_regs))
-				ret = put_stack_long(child, (int)addr >> 2, data);
+			ret = ptrace_write_user(child, addr, data);
 			break;
 
 		/*
@@ -471,14 +631,12 @@
 		 * exit.
 		 */
 		case PTRACE_KILL:
-			/* already dead */
-			ret = 0;
-			if (child->state == TASK_ZOMBIE)
-				break;
-			child->exit_code = SIGKILL;
 			/* make sure single-step breakpoint is gone. */
 			__ptrace_cancel_bpt(child);
-			wake_up_process(child);
+			if (child->state != TASK_ZOMBIE) {
+				child->exit_code = SIGKILL;
+				wake_up_process(child);
+			}
 			ret = 0;
 			break;
 
@@ -497,71 +655,32 @@
 			ret = 0;
 			break;
 
-		/*
-		 * detach a process that was attached.
-		 */
 		case PTRACE_DETACH:
 			ret = ptrace_detach(child, data);
 			break;
 
-		/*
-		 * Get all gp regs from the child.
-		 */
-		case PTRACE_GETREGS: {
-			struct pt_regs *regs = get_user_regs(child);
-
-			ret = 0;
-			if (copy_to_user((void *)data, regs,
-					 sizeof(struct pt_regs)))
-				ret = -EFAULT;
-
+		case PTRACE_GETREGS:
+			ret = ptrace_getregs(child, (void *)data);
 			break;
-		}
-
-		/*
-		 * Set all gp regs in the child.
-		 */
-		case PTRACE_SETREGS: {
-			struct pt_regs newregs;
 
-			ret = -EFAULT;
-			if (copy_from_user(&newregs, (void *)data,
-					   sizeof(struct pt_regs)) == 0) {
-				struct pt_regs *regs = get_user_regs(child);
-
-				ret = -EINVAL;
-				if (valid_user_regs(&newregs)) {
-					*regs = newregs;
-					ret = 0;
-				}
-			}
+		case PTRACE_SETREGS:
+			ret = ptrace_setregs(child, (void *)data);
 			break;
-		}
 
-		/*
-		 * Get the child FPU state.
-		 */
 		case PTRACE_GETFPREGS:
-			ret = -EIO;
-			if (!access_ok(VERIFY_WRITE, (void *)data, sizeof(struct user_fp)))
-				break;
-
-			/* we should check child->used_math here */
-			ret = __copy_to_user((void *)data, &child->thread.fpstate,
-					     sizeof(struct user_fp)) ? -EFAULT : 0;
+			ret = ptrace_getfpregs(child, (void *)data);
 			break;
 		
-		/*
-		 * Set the child FPU state.
-		 */
 		case PTRACE_SETFPREGS:
-			ret = -EIO;
-			if (!access_ok(VERIFY_READ, (void *)data, sizeof(struct user_fp)))
-				break;
+			ret = ptrace_setfpregs(child, (void *)data);
+			break;
 
-			child->used_math = 1;
-			ret = __copy_from_user(&child->thread.fpstate, (void *)data,
-					   sizeof(struct user_fp)) ? -EFAULT : 0;
+		case PTRACE_SETOPTIONS:
+			if (data & PTRACE_O_TRACESYSGOOD)
+				child->ptrace |= PT_TRACESYSGOOD;
+			else
+				child->ptrace &= ~PT_TRACESYSGOOD;
+			ret = 0;
 			break;
 
 		default:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/ptrace.h linux-2.4.22-pre10/arch/arm/kernel/ptrace.h
--- linux-2.4.21/arch/arm/kernel/ptrace.h	2000-09-18 22:15:25.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/ptrace.h	2003-08-01 13:33:16.000000000 +0000
@@ -1,14 +1,15 @@
 /*
  *  linux/arch/arm/kernel/ptrace.h
  *
- *  Copyright (C) 2000 Russell King
+ *  Copyright (C) 2000-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
 extern void __ptrace_cancel_bpt(struct task_struct *);
-extern int ptrace_set_bpt(struct task_struct *);
+extern void ptrace_set_bpt(struct task_struct *);
+extern void ptrace_break(struct task_struct *, struct pt_regs *);
 
 /*
  * Clear a breakpoint, if one exists.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/semaphore.c linux-2.4.22-pre10/arch/arm/kernel/semaphore.c
--- linux-2.4.21/arch/arm/kernel/semaphore.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/semaphore.c	2003-08-01 13:32:58.000000000 +0000
@@ -177,76 +177,76 @@
  * value in some cases..
  */
 #ifdef CONFIG_CPU_26
-asm("	.align	5
-	.globl	__down_failed
-__down_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__down
-	ldmfd	sp!, {r0 - r3, pc}^
-
-	.align	5
-	.globl	__down_interruptible_failed
-__down_interruptible_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__down_interruptible
-	mov	ip, r0
-	ldmfd	sp!, {r0 - r3, pc}^
-
-	.align	5
-	.globl	__down_trylock_failed
-__down_trylock_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__down_trylock
-	mov	ip, r0
-	ldmfd	sp!, {r0 - r3, pc}^
-
-	.align	5
-	.globl	__up_wakeup
-__up_wakeup:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__up
-	ldmfd	sp!, {r0 - r3, pc}^
+asm("	.align	5				\n\
+	.globl	__down_failed			\n\
+__down_failed:					\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__down				\n\
+	ldmfd	sp!, {r0 - r3, pc}^		\n\
+						\n\
+	.align	5				\n\
+	.globl	__down_interruptible_failed	\n\
+__down_interruptible_failed:			\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__down_interruptible		\n\
+	mov	ip, r0				\n\
+	ldmfd	sp!, {r0 - r3, pc}^		\n\
+
+	.align	5				\n\
+	.globl	__down_trylock_failed		\n\
+__down_trylock_failed:				\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__down_trylock			\n\
+	mov	ip, r0				\n\
+	ldmfd	sp!, {r0 - r3, pc}^		\n\
+						\n\
+	.align	5				\n\
+	.globl	__up_wakeup			\n\
+__up_wakeup:					\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__up				\n\
+	ldmfd	sp!, {r0 - r3, pc}^		\n\
 	");
 
 #else
 /* 32 bit version */
-asm("	.align	5
-	.globl	__down_failed
-__down_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__down
-	ldmfd	sp!, {r0 - r3, pc}
-
-	.align	5
-	.globl	__down_interruptible_failed
-__down_interruptible_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__down_interruptible
-	mov	ip, r0
-	ldmfd	sp!, {r0 - r3, pc}
-
-	.align	5
-	.globl	__down_trylock_failed
-__down_trylock_failed:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__down_trylock
-	mov	ip, r0
-	ldmfd	sp!, {r0 - r3, pc}
-
-	.align	5
-	.globl	__up_wakeup
-__up_wakeup:
-	stmfd	sp!, {r0 - r3, lr}
-	mov	r0, ip
-	bl	__up
-	ldmfd	sp!, {r0 - r3, pc}
+asm("	.align	5				\n\
+	.globl	__down_failed			\n\
+__down_failed:					\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__down				\n\
+	ldmfd	sp!, {r0 - r3, pc}		\n\
+						\n\
+	.align	5				\n\
+	.globl	__down_interruptible_failed	\n\
+__down_interruptible_failed:			\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__down_interruptible		\n\
+	mov	ip, r0				\n\
+	ldmfd	sp!, {r0 - r3, pc}		\n\
+						\n\
+	.align	5				\n\
+	.globl	__down_trylock_failed		\n\
+__down_trylock_failed:				\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__down_trylock			\n\
+	mov	ip, r0				\n\
+	ldmfd	sp!, {r0 - r3, pc}		\n\
+						\n\
+	.align	5				\n\
+	.globl	__up_wakeup			\n\
+__up_wakeup:					\n\
+	stmfd	sp!, {r0 - r3, lr}		\n\
+	mov	r0, ip				\n\
+	bl	__up				\n\
+	ldmfd	sp!, {r0 - r3, pc}		\n\
 	");
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/setup.c linux-2.4.22-pre10/arch/arm/kernel/setup.c
--- linux-2.4.21/arch/arm/kernel/setup.c	2001-11-16 18:07:47.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/setup.c	2003-08-01 13:30:33.000000000 +0000
@@ -17,6 +17,8 @@
 #include <linux/console.h>
 #include <linux/bootmem.h>
 #include <linux/seq_file.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 #include <linux/init.h>
 
 #include <asm/elf.h>
@@ -33,10 +35,6 @@
 #define MEM_SIZE	(16*1024*1024)
 #endif
 
-#ifndef CONFIG_CMDLINE
-#define CONFIG_CMDLINE ""
-#endif
-
 #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
 char fpe_type[8];
 
@@ -51,14 +49,14 @@
 
 extern unsigned int mem_fclk_21285;
 extern void paging_init(struct meminfo *, struct machine_desc *desc);
-extern void convert_to_tag_list(struct param_struct *params, int mem_init);
+extern void convert_to_tag_list(struct tag *tags);
+extern void squash_mem_tags(struct tag *tag);
 extern void bootmem_init(struct meminfo *);
 extern void reboot_setup(char *str);
 extern int root_mountflags;
 extern int _stext, _text, _etext, _edata, _end;
 
 unsigned int processor_id;
-unsigned int compat;
 unsigned int __machine_arch_type;
 unsigned int system_rev;
 unsigned int system_serial_low;
@@ -72,9 +70,11 @@
 unsigned char aux_device_present;
 char elf_platform[ELF_PLATFORM_SIZE];
 char saved_command_line[COMMAND_LINE_SIZE];
+unsigned long phys_initrd_start __initdata = 0;
+unsigned long phys_initrd_size __initdata = 0;
 
 static struct meminfo meminfo __initdata = { 0, };
-static struct proc_info_item proc_info;
+static const char *cpu_name;
 static const char *machine_name;
 static char command_line[COMMAND_LINE_SIZE];
 
@@ -129,15 +129,13 @@
 		while (1);
 	}
 
-	proc_info = *list->info;
+	cpu_name = list->info->cpu_name;
 
 #ifdef MULTI_CPU
 	processor = *list->proc;
 #endif
 
-	printk("Processor: %s %s revision %d\n",
-	       proc_info.manufacturer, proc_info.cpu_name,
-	       (int)processor_id & 15);
+	printk("CPU: %s revision %d\n", cpu_name, (int)processor_id & 15);
 
 	sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
 	sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
@@ -146,7 +144,7 @@
 	cpu_proc_init();
 }
 
-static struct machine_desc * __init setup_architecture(unsigned int nr)
+static struct machine_desc * __init setup_machine(unsigned int nr)
 {
 	extern struct machine_desc __arch_info_begin, __arch_info_end;
 	struct machine_desc *list;
@@ -168,12 +166,7 @@
 		while (1);
 	}
 
-	printk("Architecture: %s\n", list->name);
-	if (compat)
-		printk(KERN_WARNING "Using compatibility code "
-			"scheduled for removal in v%d.%d.%d\n",
-			compat >> 24, (compat >> 12) & 0x3ff,
-			compat & 0x3ff);
+	printk("Machine: %s\n", list->name);
 
 	return list;
 }
@@ -215,6 +208,22 @@
 			mi->bank[mi->nr_banks].size  = size;
 			mi->bank[mi->nr_banks].node  = PHYS_TO_NID(start);
 			mi->nr_banks += 1;
+		} else if (c == ' ' && !memcmp(from, "initrd=", 7)) {
+			unsigned long start, size;
+
+			/*
+			 * Remove space character
+			 */
+			if (to != command_line)
+				to -= 1;
+
+			start = memparse(from + 7, &from);
+			if (*from == ',') {
+				size = memparse(from + 1, &from);
+
+				phys_initrd_start = start;
+				phys_initrd_size = size;
+			}
 		}
 		c = *from++;
 		if (!c)
@@ -231,7 +240,7 @@
 setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
 {
 #ifdef CONFIG_BLK_DEV_RAM
-	extern int rd_size;
+	extern int rd_size, rd_image_start, rd_prompt, rd_doload;
 
 	rd_image_start = image_start;
 	rd_prompt = prompt;
@@ -250,8 +259,8 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (start == 0)
 		size = 0;
-	initrd_start = start;
-	initrd_end   = start + size;
+	phys_initrd_start = __virt_to_phys(start);
+	phys_initrd_size = size;
 #endif
 }
 
@@ -351,12 +360,12 @@
 
 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
 struct screen_info screen_info = {
- orig_video_lines:	30,
- orig_video_cols:	80,
- orig_video_mode:	0,
- orig_video_ega_bx:	0,
- orig_video_isVGA:	1,
- orig_video_points:	8
+ .orig_video_lines	= 30,
+ .orig_video_cols	= 80,
+ .orig_video_mode	= 0,
+ .orig_video_ega_bx	= 0,
+ .orig_video_isVGA	= 1,
+ .orig_video_points	= 8
 };
 
 static int __init parse_tag_videotext(const struct tag *tag)
@@ -388,12 +397,22 @@
 
 static int __init parse_tag_initrd(const struct tag *tag)
 {
-	setup_initrd(tag->u.initrd.start, tag->u.initrd.size);
+	phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
+	phys_initrd_size = tag->u.initrd.size;
 	return 0;
 }
 
 __tagtable(ATAG_INITRD, parse_tag_initrd);
 
+static int __init parse_tag_initrd2(const struct tag *tag)
+{
+	phys_initrd_start = tag->u.initrd.start;
+	phys_initrd_size = tag->u.initrd.size;
+	return 0;
+}
+
+__tagtable(ATAG_INITRD2, parse_tag_initrd2);
+
 static int __init parse_tag_serialnr(const struct tag *tag)
 {
 	system_serial_low = tag->u.serialnr.low;
@@ -452,16 +471,30 @@
 				t->hdr.tag);
 }
 
+static struct init_tags {
+	struct tag_header hdr1;
+	struct tag_core   core;
+	struct tag_header hdr2;
+	struct tag_mem32  mem;
+	struct tag_header hdr3;
+} init_tags __initdata = {
+	{ tag_size(tag_core), ATAG_CORE },
+	{ 1, PAGE_SIZE, 0xff },
+	{ tag_size(tag_mem32), ATAG_MEM },
+	{ MEM_SIZE, PHYS_OFFSET },
+	{ 0, ATAG_NONE }
+};
+
 void __init setup_arch(char **cmdline_p)
 {
-	struct tag *tags = NULL;
+	struct tag *tags = (struct tag *)&init_tags;
 	struct machine_desc *mdesc;
 	char *from = default_command_line;
 
 	ROOT_DEV = MKDEV(0, 255);
 
 	setup_processor();
-	mdesc = setup_architecture(machine_arch_type);
+	mdesc = setup_machine(machine_arch_type);
 	machine_name = mdesc->name;
 
 	if (mdesc->soft_reboot)
@@ -480,14 +513,16 @@
 
 	/*
 	 * If we have the old style parameters, convert them to
-	 * a tag list before.
+	 * a tag list.
 	 */
-	if (tags && tags->hdr.tag != ATAG_CORE)
-		convert_to_tag_list((struct param_struct *)tags,
-				    meminfo.nr_banks == 0);
+	if (tags->hdr.tag != ATAG_CORE)
+		convert_to_tag_list(tags);
 
-	if (tags && tags->hdr.tag == ATAG_CORE)
+	if (tags->hdr.tag == ATAG_CORE) {
+		if (meminfo.nr_banks != 0)
+			squash_mem_tags(tags);
 		parse_tags(tags);
+	}
 
 	if (meminfo.nr_banks == 0) {
 		meminfo.nr_banks      = 1;
@@ -537,9 +572,8 @@
 {
 	int i;
 
-	seq_printf(m, "Processor\t: %s %s rev %d (%s)\n",
-		   proc_info.manufacturer, proc_info.cpu_name,
-		   (int)processor_id & 15, elf_platform);
+	seq_printf(m, "Processor\t: %s rev %d (%s)\n",
+		   cpu_name, (int)processor_id & 15, elf_platform);
 
 	seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
 		   loops_per_jiffy / (500000/HZ),
@@ -578,8 +612,8 @@
 }
 
 struct seq_operations cpuinfo_op = {
-	start:	c_start,
-	next:	c_next,
-	stop:	c_stop,
-	show:	c_show
+	.start	= c_start,
+	.next	= c_next,
+	.stop	= c_stop,
+	.show	= c_show
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/signal.c linux-2.4.22-pre10/arch/arm/kernel/signal.c
--- linux-2.4.21/arch/arm/kernel/signal.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/signal.c	2003-08-01 13:30:41.000000000 +0000
@@ -405,7 +405,7 @@
 	regs->ARM_r0 = usig;
 	regs->ARM_sp = (unsigned long)frame;
 	regs->ARM_lr = retcode;
-	regs->ARM_pc = handler & (thumb ? ~1 : ~3);
+	regs->ARM_pc = handler;
 
 #ifdef CONFIG_CPU_32
 	regs->ARM_cpsr = cpsr;
@@ -466,8 +466,8 @@
 		 * arguments for the signal handler.
 		 *   -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
 		 */
-		regs->ARM_r1 = (unsigned long)frame->pinfo;
-		regs->ARM_r2 = (unsigned long)frame->puc;
+		regs->ARM_r1 = (unsigned long)&frame->info;
+		regs->ARM_r2 = (unsigned long)&frame->uc;
 	}
 
 	return err;
@@ -613,7 +613,7 @@
 				continue;
 
 			switch (signr) {
-			case SIGCONT: case SIGCHLD: case SIGWINCH:
+			case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
 				continue;
 
 			case SIGTSTP: case SIGTTIN: case SIGTTOU:
@@ -621,13 +621,17 @@
 					continue;
 				/* FALLTHRU */
 
-			case SIGSTOP:
+			case SIGSTOP: {
+				struct signal_struct *sig;
 				current->state = TASK_STOPPED;
 				current->exit_code = signr;
-				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
+				sig = current->p_pptr->sig;
+				if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
+				single_stepping |= ptrace_cancel_bpt(current);
 				continue;
+			}
 
 			case SIGQUIT: case SIGILL: case SIGTRAP:
 			case SIGABRT: case SIGFPE: case SIGSEGV:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/time.c linux-2.4.22-pre10/arch/arm/kernel/time.c
--- linux-2.4.21/arch/arm/kernel/time.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/time.c	2003-08-01 13:34:02.000000000 +0000
@@ -203,6 +203,7 @@
 
 static struct irqaction timer_irq = {
 	.name	= "timer",
+	.flags	= SA_INTERRUPT,
 };
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/kernel/traps.c linux-2.4.22-pre10/arch/arm/kernel/traps.c
--- linux-2.4.21/arch/arm/kernel/traps.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/kernel/traps.c	2003-08-01 13:32:59.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/kernel/traps.c
  *
- *  Copyright (C) 1995, 1996 Russell King
+ *  Copyright (C) 1995-2002 Russell King
  *  Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
  *
  * This program is free software; you can redistribute it and/or modify
@@ -63,8 +63,17 @@
 static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
 {
 	unsigned long p = bottom & ~31;
+	mm_segment_t fs;
 	int i;
 
+	/*
+	 * We need to switch to kernel mode so that we can use __get_user
+	 * to safely read from kernel space.  Note that we now dump the
+	 * code first, just in case the backtrace kills us.
+	 */
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+
 	printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
 
 	for (p = bottom & ~31; p < top;) {
@@ -82,6 +91,8 @@
 		}
 		printk ("\n");
 	}
+
+	set_fs(fs);
 }
 
 static void dump_instr(struct pt_regs *regs)
@@ -89,8 +100,17 @@
 	unsigned long addr = instruction_pointer(regs);
 	const int thumb = thumb_mode(regs);
 	const int width = thumb ? 4 : 8;
+	mm_segment_t fs;
 	int i;
 
+	/*
+	 * We need to switch to kernel mode so that we can use __get_user
+	 * to safely read from kernel space.  Note that we now dump the
+	 * code first, just in case the backtrace kills us.
+	 */
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+
 	printk("Code: ");
 	for (i = -4; i < 1; i++) {
 		unsigned int val, bad;
@@ -108,29 +128,36 @@
 		}
 	}
 	printk("\n");
+
+	set_fs(fs);
 }
 
-static void dump_stack(struct task_struct *tsk, unsigned long sp)
+static void I_really_mean_dump_stack_so_dont_mess_with_me(struct task_struct *tsk, unsigned long sp)
 {
-	dump_mem("Stack: ", sp - 16, 8192+(unsigned long)tsk);
+	dump_mem("Stack: ", sp, 8192+(unsigned long)tsk);
 }
 
 static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
 {
-	unsigned int fp;
+	unsigned int fp = regs->ARM_fp;
+	char *msg = "";
 	int ok = 1;
 
-	printk("Backtrace: ");
-	fp = regs->ARM_fp;
+#ifdef CONFIG_FRAME_POINTER
 	if (!fp) {
-		printk("no frame pointer");
+		msg = "no frame pointer";
 		ok = 0;
 	} else if (verify_stack(fp)) {
-		printk("invalid frame pointer 0x%08x", fp);
+		msg = "invalid frame pointer";
 		ok = 0;
 	} else if (fp < 4096+(unsigned long)tsk)
-		printk("frame pointer underflow");
-	printk("\n");
+		msg = "frame pointer underflow";
+#else
+	msg = "not available";
+	ok = 0;
+#endif
+
+	printk("Backtrace: %s\n", msg);
 
 	if (ok)
 		c_backtrace(fp, processor_mode(regs));
@@ -143,7 +170,7 @@
 void show_trace_task(struct task_struct *tsk)
 {
 	if (tsk != current) {
-		unsigned int fp = tsk->thread.save->fp;
+		unsigned int fp = thread_saved_fp(&tsk->thread);
 		c_backtrace(fp, 0x10);
 	}
 }
@@ -163,26 +190,13 @@
 	printk("Internal error: %s: %x\n", str, err);
 	printk("CPU: %d\n", smp_processor_id());
 	show_regs(regs);
-	printk("Process %s (pid: %d, stackpage=%08lx)\n",
-		current->comm, current->pid, 4096+(unsigned long)tsk);
+	printk("Process %s (pid: %d, stack limit = 0x%p)\n",
+		current->comm, current->pid, tsk + 1);
 
 	if (!user_mode(regs) || in_interrupt()) {
-		mm_segment_t fs;
-
-		/*
-		 * We need to switch to kernel mode so that we can
-		 * use __get_user to safely read from kernel space.
-		 * Note that we now dump the code first, just in case
-		 * the backtrace kills us.
-		 */
-		fs = get_fs();
-		set_fs(KERNEL_DS);
-
-		dump_stack(tsk, (unsigned long)(regs + 1));
+		I_really_mean_dump_stack_so_dont_mess_with_me(tsk, (unsigned long)(regs + 1));
 		dump_backtrace(regs, tsk);
 		dump_instr(regs);
-
-		set_fs(fs);
 	}
 
 	spin_unlock_irq(&die_lock);
@@ -270,7 +284,6 @@
 asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
 {
 	unsigned int vectors = vectors_base();
-	mm_segment_t fs;
 
 	console_verbose();
 
@@ -278,24 +291,14 @@
 		handler[reason], processor_modes[proc_mode]);
 
 	/*
-	 * We need to switch to kernel mode so that we can use __get_user
-	 * to safely read from kernel space.  Note that we now dump the
-	 * code first, just in case the backtrace kills us.
-	 */
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-
-	/*
 	 * Dump out the vectors and stub routines.  Maybe a better solution
 	 * would be to dump them out only if we detect that they are corrupted.
 	 */
 	dump_mem(KERN_CRIT "Vectors: ", vectors, vectors + 0x40);
 	dump_mem(KERN_CRIT "Stubs: ", vectors + 0x200, vectors + 0x4b8);
 
-	set_fs(fs);
-
 	die("Oops", regs, 0);
-	cli();
+	local_irq_disable();
 	panic("bad mode");
 }
 
@@ -356,20 +359,7 @@
 		return 0;
 
 	case NR(breakpoint): /* SWI BREAK_POINT */
-		/*
-		 * The PC is always left pointing at the next
-		 * instruction.  Fix this.
-		 */
-		regs->ARM_pc -= 4;
-		__ptrace_cancel_bpt(current);
-
-		info.si_signo = SIGTRAP;
-		info.si_errno = 0;
-		info.si_code  = TRAP_BRKPT;
-		info.si_addr  = (void *)instruction_pointer(regs) -
-				 (thumb_mode(regs) ? 2 : 4);
-
-		force_sig_info(SIGTRAP, &info, current);
+		ptrace_break(current, regs);
 		return regs->ARM_r0;
 
 #ifdef CONFIG_CPU_32
@@ -522,12 +512,13 @@
 
 void __init trap_init(void)
 {
-	extern void __trap_init(void *);
+	extern void __trap_init(unsigned long);
+	unsigned long base = vectors_base();
 
-	__trap_init((void *)vectors_base());
-	if (vectors_base() != 0)
-		printk(KERN_DEBUG "Relocating machine vectors to 0x%08x\n",
-			vectors_base());
+	__trap_init(base);
+	if (base != 0)
+		printk(KERN_DEBUG "Relocating machine vectors to 0x%08lx\n",
+			base);
 #ifdef CONFIG_CPU_32
 	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/lib/Makefile linux-2.4.22-pre10/arch/arm/lib/Makefile
--- linux-2.4.21/arch/arm/lib/Makefile	2001-10-11 16:04:57.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/lib/Makefile	2003-08-01 13:33:56.000000000 +0000
@@ -27,15 +27,16 @@
 obj-l7200     	:= io-acorn.o
 obj-shark	:= io-shark.o
 obj-edb7211	:= io-acorn.o
+obj-riscstation := io-acorn.o floppydma.o
 
 obj-y		+= $(obj-$(MACHINE))
 
-ifeq ($(CONFIG_CPU_32v4),y)
-  v3		:= n
-  v4		:= y
-else
+ifeq ($(CONFIG_CPU_32v3),y)
   v3		:= y
   v4		:= n
+else
+  v3		:= n
+  v4		:= y
 endif
 
 obj-y		+= io-readsb.o io-writesb.o
@@ -51,4 +52,3 @@
 
 csumpartialcopy.o: csumpartialcopygeneric.S
 csumpartialcopyuser.o: csumpartialcopygeneric.S
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/lib/backtrace.S linux-2.4.22-pre10/arch/arm/lib/backtrace.S
--- linux-2.4.21/arch/arm/lib/backtrace.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/lib/backtrace.S	2003-08-01 13:31:28.000000000 +0000
@@ -52,25 +52,32 @@
 3:		tst	frame, mask		@ Check for address exceptions...
 		bne	1b
 
-1001:		ldmda	frame, {r0, r1, r2, r3}	@ fp, sp, lr, pc
-		mov	next, r0
-
+1001:		ldr	next, [frame, #-12]	@ get fp
+1002:		ldr	r2, [frame, #-4]	@ get lr
+1003:		ldr	r3, [frame, #0]		@ get pc
 		sub	save, r3, offset	@ Correct PC for prefetching
 		bic	save, save, mask
+1004:		ldr	r1, [save, #0]		@ get instruction at function
+		mov	r1, r1, lsr #10
+		ldr	r3, .Ldsi+4
+		teq	r1, r3
+		subeq	save, save, #4
 		adr	r0, .Lfe
 		mov	r1, save
 		bic	r2, r2, mask
-		bl	SYMBOL_NAME(printk)	@ print pc and link register
+		bl	printk			@ print pc and link register
 
-		sub	r0, frame, #16
-1002:		ldr	r1, [save, #4]		@ get instruction at function+4
+		ldr	r0, [frame, #-8]	@ get sp
+		sub	r0, r0, #4
+1005:		ldr	r1, [save, #4]		@ get instruction at function+4
 		mov	r3, r1, lsr #10
 		ldr	r2, .Ldsi+4
 		teq	r3, r2			@ Check for stmia sp!, {args}
 		addeq	save, save, #4		@ next instruction
 		bleq	.Ldumpstm
 
-1003:		ldr	r1, [save, #4]		@ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
+		sub	r0, frame, #16
+1006:		ldr	r1, [save, #4]		@ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
 		mov	r3, r1, lsr #10
 		ldr	r2, .Ldsi
 		teq	r3, r2
@@ -87,18 +94,21 @@
  */
 		.section .fixup,"ax"
 		.align	0
-1004:		ldr	r0, =.Lbad
+1007:		ldr	r0, =.Lbad
 		mov	r1, frame
-		bl	SYMBOL_NAME(printk)
+		bl	printk
 		LOADREGS(fd, sp!, {r4 - r8, pc})
 		.ltorg
 		.previous
 		
 		.section __ex_table,"a"
 		.align	3
-		.long	1001b, 1004b
-		.long	1002b, 1004b
-		.long	1003b, 1004b
+		.long	1001b, 1007b
+		.long	1002b, 1007b
+		.long	1003b, 1007b
+		.long	1004b, 1007b
+		.long	1005b, 1007b
+		.long	1006b, 1007b
 		.previous
 
 #define instr r4
@@ -121,12 +131,12 @@
 		ldr	r2, [stack], #-4
 		mov	r1, reg
 		adr	r0, .Lfp
-		bl	SYMBOL_NAME(printk)
+		bl	printk
 2:		subs	reg, reg, #1
 		bpl	1b
 		teq	r7, #0
 		adrne	r0, .Lcr
-		blne	SYMBOL_NAME(printk)
+		blne	printk
 		mov	r0, stack
 		LOADREGS(fd, sp!, {instr, reg, stack, r7, pc})
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/lib/csumpartial.S linux-2.4.22-pre10/arch/arm/lib/csumpartial.S
--- linux-2.4.21/arch/arm/lib/csumpartial.S	2001-05-16 22:25:16.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/lib/csumpartial.S	2003-08-01 13:35:06.000000000 +0000
@@ -49,8 +49,9 @@
 		/* we are now half-word aligned */
 
 .less8_wordlp:
-#ifdef __ARM_ARCH_4__
-		ldrh	td0, [buf], #2
+#if __LINUX_ARM_ARCH__ >= 4
+		ldrh	td0, [buf]
+		add	buf, buf, #2
 		sub	len, len, #2
 #else
 		ldrb	td0, [buf], #1
@@ -79,8 +80,9 @@
 		adcnes	sum, sum, td0, lsl #8	@ update checksum
 
 		tst	buf, #2			@ 32-bit aligned?
-#ifdef __ARM_ARCH_4__
-		ldrneh	td0, [buf], #2		@ make 32-bit aligned
+#if __LINUX_ARM_ARCH__ >= 4
+		ldrneh	td0, [buf]		@ make 32-bit aligned
+		add	buf, buf, #2
 		subne	len, len, #2
 #else
 		ldrneb	td0, [buf], #1
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/lib/delay.S linux-2.4.22-pre10/arch/arm/lib/delay.S
--- linux-2.4.21/arch/arm/lib/delay.S	2001-04-12 19:20:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/lib/delay.S	2003-08-01 13:33:21.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/lib/delay.S
  *
- *  Copyright (C) 1995, 1996 Russell King
+ *  Copyright (C) 1995-2003 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -9,45 +9,52 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-		.text
+#include <asm/delay.h>
 
-LC0:		.word	SYMBOL_NAME(loops_per_jiffy)
+		.text
 
 /*
- * 0 <= r0 <= 2000
+ * See linux/include/asm-arm/delay.h for a description of the maths.
  */
-ENTRY(udelay)
-		mov	r2,     #0x6800
-		orr	r2, r2, #0x00db
+
+#if NDELAY_FACTOR > 255
+#error NDELAY_FACTOR out of range
+#endif
+#if UDELAY_FACTOR > 65535
+#error UDELAY_FACTOR out of range
+#endif
+
+LC0:		.word	SYMBOL_NAME(loops_per_jiffy)
+
+ENTRY(__const_delay)
+		ldr	r3, LC0
+		mov	r1, r0, lsr #11
+		ldr	r2, [r3, #0]
+		b	2f
+
+ENTRY(__ndelay)
+		mov	r2, #NDELAY_FACTOR
+		b	1f
+
+ENTRY(__udelay)
+		mov	r2,     #UDELAY_FACTOR & 0xff00
+		orr	r2, r2, #UDELAY_FACTOR & 0x00ff
+1:		ldr	r3, LC0
 		mul	r1, r0, r2
-		ldr	r2, LC0
-		ldr	r2, [r2]
+		ldr	r2, [r3, #0]
 		mov	r1, r1, lsr #11
-		mov	r2, r2, lsr #11
+2:		mov	r2, r2, lsr #12
 		mul	r0, r1, r2
-		movs	r0, r0, lsr #6
+		movs	r0, r0, lsr #5
 		RETINSTR(moveq,pc,lr)
 
 /*
- * loops = (r0 * 0x10c6 * 100 * loops_per_jiffie) / 2^32
+ * loops = (r0 * 0x10c6 * HZ * loops_per_jiffy) / 2^32
+ *
+ * Oh, if only we had a cycle counter...
  */
 
-@ Delay routine
 ENTRY(__delay)
 		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
-		RETINSTR(movcc,pc,lr)
-		subs	r0, r0, #1
 		bcs	SYMBOL_NAME(__delay)
 		RETINSTR(mov,pc,lr)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/lib/longlong.h linux-2.4.22-pre10/arch/arm/lib/longlong.h
--- linux-2.4.21/arch/arm/lib/longlong.h	2001-10-11 16:04:57.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/lib/longlong.h	2003-08-01 13:31:33.000000000 +0000
@@ -75,7 +75,7 @@
 
 #if defined (__arm__)
 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
-  __asm__ ("adds	%1, %4, %5
+  __asm__ ("adds	%1, %4, %5					\n\
 	adc	%0, %2, %3"						\
 	   : "=r" ((USItype) (sh)),					\
 	     "=&r" ((USItype) (sl))					\
@@ -84,7 +84,7 @@
 	     "%r" ((USItype) (al)),					\
 	     "rI" ((USItype) (bl)))
 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
-  __asm__ ("subs	%1, %4, %5
+  __asm__ ("subs	%1, %4, %5					\n\
 	sbc	%0, %2, %3"						\
 	   : "=r" ((USItype) (sh)),					\
 	     "=&r" ((USItype) (sl))					\
@@ -94,18 +94,18 @@
 	     "rI" ((USItype) (bl)))
 #define umul_ppmm(xh, xl, a, b) \
 {register USItype __t0, __t1, __t2;					\
-  __asm__ ("%@ Inlined umul_ppmm
-	mov	%2, %5, lsr #16
-	mov	%0, %6, lsr #16
-	bic	%3, %5, %2, lsl #16
-	bic	%4, %6, %0, lsl #16
-	mul	%1, %3, %4
-	mul	%4, %2, %4
-	mul	%3, %0, %3
-	mul	%0, %2, %0
-	adds	%3, %4, %3
-	addcs	%0, %0, #65536
-	adds	%1, %1, %3, lsl #16
+  __asm__ ("%@ Inlined umul_ppmm					\n\
+	mov	%2, %5, lsr #16						\n\
+	mov	%0, %6, lsr #16						\n\
+	bic	%3, %5, %2, lsl #16					\n\
+	bic	%4, %6, %0, lsl #16					\n\
+	mul	%1, %3, %4						\n\
+	mul	%4, %2, %4						\n\
+	mul	%3, %0, %3						\n\
+	mul	%0, %2, %0						\n\
+	adds	%3, %4, %3						\n\
+	addcs	%0, %0, #65536						\n\
+	adds	%1, %1, %3, lsl #16					\n\
 	adc	%0, %0, %3, lsr #16"					\
 	   : "=&r" ((USItype) (xh)),					\
 	     "=r" ((USItype) (xl)),					\
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/lib/memchr.S linux-2.4.22-pre10/arch/arm/lib/memchr.S
--- linux-2.4.21/arch/arm/lib/memchr.S	2000-09-18 22:15:25.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/lib/memchr.S	2003-08-01 13:34:01.000000000 +0000
@@ -15,11 +15,11 @@
 	.text
 	.align	5
 ENTRY(memchr)
-1:	ldrb	r3, [r0], #1
+1:	subs	r2, r2, #1
+	bmi	2f
+	ldrb	r3, [r0], #1
 	teq	r3, r1
-	beq	2f
-	subs	r2, r2, #1
-	bpl	1b
+	bne	1b
+	sub	r0, r0, #1
 2:	movne	r0, #0
-	subeq	r0, r0, #1
 	RETINSTR(mov,pc,lr)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/lib/muldi3.c linux-2.4.22-pre10/arch/arm/lib/muldi3.c
--- linux-2.4.21/arch/arm/lib/muldi3.c	2001-10-11 16:04:57.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/lib/muldi3.c	2003-08-01 13:31:14.000000000 +0000
@@ -33,18 +33,18 @@
 
 #define umul_ppmm(xh, xl, a, b) \
 {register USItype __t0, __t1, __t2;                                     \
-  __asm__ ("%@ Inlined umul_ppmm
-        mov     %2, %5, lsr #16
-        mov     %0, %6, lsr #16
-        bic     %3, %5, %2, lsl #16
-        bic     %4, %6, %0, lsl #16
-        mul     %1, %3, %4
-        mul     %4, %2, %4
-        mul     %3, %0, %3
-        mul     %0, %2, %0
-        adds    %3, %4, %3
-        addcs   %0, %0, #65536
-        adds    %1, %1, %3, lsl #16
+  __asm__ ("%@ Inlined umul_ppmm					\n\
+        mov     %2, %5, lsr #16						\n\
+        mov     %0, %6, lsr #16						\n\
+        bic     %3, %5, %2, lsl #16					\n\
+        bic     %4, %6, %0, lsl #16					\n\
+        mul     %1, %3, %4						\n\
+        mul     %4, %2, %4						\n\
+        mul     %3, %0, %3						\n\
+        mul     %0, %2, %0						\n\
+        adds    %3, %4, %3						\n\
+        addcs   %0, %0, #65536						\n\
+        adds    %1, %1, %3, lsl #16					\n\
         adc     %0, %0, %3, lsr #16"                                    \
            : "=&r" ((USItype) (xh)),                                    \
              "=r" ((USItype) (xl)),                                     \
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/lib/strchr.S linux-2.4.22-pre10/arch/arm/lib/strchr.S
--- linux-2.4.21/arch/arm/lib/strchr.S	2000-09-18 22:15:25.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/lib/strchr.S	2003-08-01 13:34:39.000000000 +0000
@@ -15,11 +15,12 @@
 		.text
 		.align	5
 ENTRY(strchr)
+		and	r1, r1, #0xff
 1:		ldrb	r2, [r0], #1
 		teq	r2, r1
 		teqne	r2, #0
 		bne	1b
-		teq	r2, #0
-		moveq	r0, #0
-		subne	r0, r0, #1
+		teq	r2, r1
+		movne	r0, #0
+		subeq	r0, r0, #1
 		RETINSTR(mov,pc,lr)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/lib/udivdi3.c linux-2.4.22-pre10/arch/arm/lib/udivdi3.c
--- linux-2.4.21/arch/arm/lib/udivdi3.c	2001-10-11 16:04:57.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/lib/udivdi3.c	2003-08-01 13:33:30.000000000 +0000
@@ -229,3 +229,14 @@
 {
   return __udivmoddi4 (n, d, (UDItype *) 0);
 }
+
+UDItype
+__umoddi3 (UDItype u, UDItype v)
+{
+  UDItype w;
+
+  (void) __udivmoddi4 (u ,v, &w);
+
+  return w;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-anakin/irq.c linux-2.4.22-pre10/arch/arm/mach-anakin/irq.c
--- linux-2.4.21/arch/arm/mach-anakin/irq.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-anakin/irq.c	2003-08-01 13:30:44.000000000 +0000
@@ -15,6 +15,8 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-at91rm9200/Makefile linux-2.4.22-pre10/arch/arm/mach-at91rm9200/Makefile
--- linux-2.4.21/arch/arm/mach-at91rm9200/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-at91rm9200/Makefile	2003-08-01 13:34:04.000000000 +0000
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= at91rm9200.o
+
+# Object file lists.
+
+obj-y			:= core.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:=
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-at91rm9200/core.c linux-2.4.22-pre10/arch/arm/mach-at91rm9200/core.c
--- linux-2.4.21/arch/arm/mach-at91rm9200/core.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-at91rm9200/core.c	2003-08-01 13:33:51.000000000 +0000
@@ -0,0 +1,183 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/core.c
+ *
+ *  Copyright (c) 2003 SAN People
+ *  Copyright (c) 2003 ATMEL
+ *  Copyright (c) Rick Bronson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/hardware.h>
+
+/*
+ * System peripheral registers mapped at virtual address.
+ */
+AT91PS_SYS AT91_SYS = (AT91PS_SYS) AT91C_VA_BASE_SYS;
+
+static struct map_desc at91rm9200_io_desc[] __initdata = {
+	/* virtual,             physical,          length,   domain,    r, w, c, b */
+	{ AT91C_VA_BASE_SYS,    AT91C_BASE_SYS,    SZ_4K,    DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_SPI,    AT91C_BASE_SPI,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_SSC2,   AT91C_BASE_SSC2,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_SSC1,   AT91C_BASE_SSC1,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_SSC0,   AT91C_BASE_SSC0,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_US3,    AT91C_BASE_US3,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_US2,    AT91C_BASE_US2,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_US1,    AT91C_BASE_US1,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_US0,    AT91C_BASE_US0,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_EMAC,   AT91C_BASE_EMAC,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_TWI,    AT91C_BASE_TWI,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_MCI,    AT91C_BASE_MCI,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_UDP,    AT91C_BASE_UDP,    SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_TCB1,   AT91C_BASE_TCB1,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	{ AT91C_VA_BASE_TCB0,   AT91C_BASE_TCB0,   SZ_16K,   DOMAIN_IO, 0, 1, 0, 0},
+	LAST_DESC
+};
+
+/* Interrupt configuration */
+static AT91_REG at91rm9200_irq_smr[] __initdata = {
+	(AT91_SMR_FIQ),		/* FIQ */
+	(AT91_SMR_SYS),		/* System Peripherals */
+	(AT91_SMR_PIOA),	/* PIO A */
+	(AT91_SMR_PIOB),	/* PIO B */
+	(AT91_SMR_PIOC),	/* PIO C */
+	(AT91_SMR_PIOD),	/* PIO D */
+	(AT91_SMR_US0),		/* USART 0 */
+	(AT91_SMR_US1),		/* USART 1 */
+	(AT91_SMR_US2),		/* USART 2 */
+	(AT91_SMR_US3),		/* USART 3 */
+	(AT91_SMR_MCI),		/* Multimedia Card */
+	(AT91_SMR_UDP),		/* USB Device */
+	(AT91_SMR_TWI),		/* Two-wire interface */
+	(AT91_SMR_SPI),		/* SPI */
+	(AT91_SMR_SSC0),	/* Sync Serial 0 */
+	(AT91_SMR_SSC1),	/* Sync Serial 1 */
+	(AT91_SMR_SSC2),	/* Sync Serial 2 */
+	(AT91_SMR_TC0),		/* TC 0 */
+	(AT91_SMR_TC1),		/* TC 1 */
+	(AT91_SMR_TC2),		/* TC 2 */
+	(AT91_SMR_TC3),		/* TC 3 */
+	(AT91_SMR_TC4),		/* TC 4 */
+	(AT91_SMR_TC5),		/* TC 5 */
+	(AT91_SMR_UHP),		/* USB Host */
+	(AT91_SMR_EMAC),	/* Ethernet */
+	(AT91_SMR_IRQ0),	/* IRQ 0 */
+	(AT91_SMR_IRQ1),	/* IRQ 1 */
+	(AT91_SMR_IRQ2),	/* IRQ 2 */
+	(AT91_SMR_IRQ3),	/* IRQ 3 */
+	(AT91_SMR_IRQ4),	/* IRQ 4 */
+	(AT91_SMR_IRQ5),	/* IRQ 5 */
+	(AT91_SMR_IRQ6)		/* IRQ 6 */
+};
+
+/* Architecture-specific fixups */
+static void __init at91rm9200_fixup(struct machine_desc *desc, struct param_struct *unused,
+		 char **cmdline, struct meminfo *mi)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	setup_ramdisk(1, 0, 0, CONFIG_BLK_DEV_RAM_SIZE);
+//	setup_initrd(0xc0100000, 3*1024*1024);
+#endif
+}
+
+extern void at91_register_uart(int idx, int port);
+
+void __init at91rm9200_map_io(void)
+{
+	int serial[AT91C_NR_UART] = AT91C_UART_MAP;
+	int i;
+
+	iotable_init(at91rm9200_io_desc);
+
+	/* Register UARTs */
+	for (i = 0; i < AT91C_NR_UART; i++) {
+		if (serial[i] >= 0)
+			at91_register_uart(i, serial[i]);
+	}
+}
+
+static void at91rm9200_mask_irq(unsigned int irq)
+{
+	/* Disable interrupt on AIC */
+	AT91_SYS->AIC_IDCR =  1 << irq;
+}
+
+static void at91rm9200_unmask_irq(unsigned int irq)
+{
+	/* Enable interrupt on AIC */
+	AT91_SYS->AIC_IECR =  1 << irq;
+}
+
+void __init at91rm9200_init_irq(void)
+{
+	unsigned int i;
+
+	/*
+	 * The IVR is used by macro get_irqnr_and_base to read and verify.
+	 * The irq number is NR_IRQS when a spurious interrupt has occured.
+	 */
+	for (i = 0; i < NR_IRQS; i++) {
+		/* Put irq number in Source Vector Register: */
+		AT91_SYS->AIC_SVR[i] = i;
+		/* Store the Source Mode Register as defined in table above */
+		AT91_SYS->AIC_SMR[i] = at91rm9200_irq_smr[i];
+
+		irq_desc[i].valid	= 1;
+		irq_desc[i].mask_ack	= at91rm9200_mask_irq;
+		irq_desc[i].mask	= at91rm9200_mask_irq;
+		irq_desc[i].unmask	= at91rm9200_unmask_irq;
+
+		/* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */
+		if (i < 8)
+			AT91_SYS->AIC_EOICR = AT91_SYS->AIC_EOICR;
+	}
+
+	/* Spurious Interrupt ID in Spurious Vector Register is NR_IRQS
+	 * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU
+	 */
+	AT91_SYS->AIC_SPU = NR_IRQS;
+
+	/* No debugging in AIC: Debug (Protect) Control Register */
+	AT91_SYS->AIC_DCR = 0;
+
+	/* Disable and clear all interrupts initially */
+	AT91_SYS->AIC_IDCR = 0xFFFFFFFF;
+	AT91_SYS->AIC_ICCR = 0xFFFFFFFF;
+}
+
+MACHINE_START(AT91RM9200, "ATMEL AT91RM9200")
+	MAINTAINER("SAN People / ATMEL")
+	BOOT_MEM(AT91_SDRAM_BASE, AT91C_BASE_SYS, AT91C_VA_BASE_SYS)
+	BOOT_PARAMS(AT91_SDRAM_BASE + 0x100)
+	FIXUP(at91rm9200_fixup)
+	MAPIO(at91rm9200_map_io)
+	INITIRQ(at91rm9200_init_irq)
+MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-clps711x/Makefile linux-2.4.22-pre10/arch/arm/mach-clps711x/Makefile
--- linux-2.4.21/arch/arm/mach-clps711x/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-clps711x/Makefile	2003-08-01 13:34:02.000000000 +0000
@@ -16,12 +16,13 @@
 obj-n			:=
 obj-			:=
 
-export-objs		:= leds-p720t.o
+export-objs		:= p720t-leds.o
 
 obj-$(CONFIG_ARCH_AUTCPU12) += autcpu12.o
 obj-$(CONFIG_ARCH_CDB89712) += cdb89712.o
 obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o
 obj-$(CONFIG_ARCH_EDB7211) += edb7211-arch.o edb7211-mm.o
+obj-$(CONFIG_ARCH_GUIDEA07) += guide-a07.o
 obj-$(CONFIG_ARCH_P720T) += p720t.o
 obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o
 leds-$(CONFIG_ARCH_P720T) += p720t-leds.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-clps711x/fortunet.c linux-2.4.22-pre10/arch/arm/mach-clps711x/fortunet.c
--- linux-2.4.21/arch/arm/mach-clps711x/fortunet.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-clps711x/fortunet.c	2003-08-01 13:33:59.000000000 +0000
@@ -31,6 +31,10 @@
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/amba_kmi.h>
 
@@ -48,9 +52,11 @@
 	int	extra_param_type;
 	int	extra_param_ptr;
 	int	command_line;
+	int	extra_ram_start;
+	int	extra_ram_size;
 } IMAGE_PARAMS;
 
-#define IMAGE_PARAMS_PHYS	0xC01F0000
+#define IMAGE_PARAMS_PHYS	0xC0200000
 
 static void __init
 fortunet_fixup(struct machine_desc *desc, struct param_struct *params,
@@ -67,14 +73,23 @@
 	}
 #endif
 	memmap.bank[0].size = ip->ram_size;
+	memmap.bank[0].node = PHYS_TO_NID(0xC0000000);
+	if(ip->extra_ram_size)
+	{
+		memmap.bank[1].start = ip->extra_ram_start;
+		memmap.bank[1].size = ip->extra_ram_size;
+		memmap.bank[1].node = PHYS_TO_NID(ip->extra_ram_start);
+		mi->nr_banks=2;
+	}
 	memmap.end = ip->ram_size+0xC0000000;
 	*mi = memmap;
 }
 
 MACHINE_START(FORTUNET, "ARM-FortuNet")
 	MAINTAINER("FortuNet Inc.")
-        BOOT_MEM(0xc0000000, 0x80000000, 0xf0000000)
+        BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
 	BOOT_PARAMS(0x00000000)
+	VIDEO(0xC0000000,0xC00020000)
 	FIXUP(fortunet_fixup)
 	MAPIO(clps711x_map_io)
 	INITIRQ(clps711x_init_irq)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-clps711x/guide-a07.c linux-2.4.22-pre10/arch/arm/mach-clps711x/guide-a07.c
--- linux-2.4.21/arch/arm/mach-clps711x/guide-a07.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-clps711x/guide-a07.c	2003-08-01 13:33:05.000000000 +0000
@@ -0,0 +1,92 @@
+/*
+ *  linux/arch/arm/mach-clps711x/guide-a07.c
+ *
+ *  Copyright (C) 2003 Iders Incorporated
+ *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/config.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+extern void clps711x_init_irq(void);
+extern void clps711x_map_io(void);
+
+#ifndef CONFIG_I2C_GUIDE
+#error Config error - The Guide A07 requires I2C Guide GPIO support. Please enable it.
+#endif
+
+/*
+ * Map the CS89712 Ethernet port.  That should be moved to the
+ * ethernet driver, perhaps.
+ * also map the Guide FPGA and persistance locations
+ */
+static struct map_desc guide_a07_io_desc[] __initdata = {
+	{              ETHER_BASE,              ETHER_START,              ETHER_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0 },
+	{        GD_A07_FPGA_BASE,        GD_A07_FPGA_START,        GD_A07_FPGA_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0 },
+	{ GD_A07_PERSISTANCE_BASE, GD_A07_PERSISTANCE_START, GD_A07_PERSISTANCE_SIZE,
+		DOMAIN_IO, 0, 1, 0, 0 },
+	LAST_DESC
+};
+
+static void __init
+fixup_guide_a07(struct machine_desc *desc, struct param_struct *params,
+	    char **cmdline, struct meminfo *mi)
+{
+}
+
+static void __init guide_a07_map_io(void)
+{
+	clps711x_map_io();
+	iotable_init(guide_a07_io_desc);
+}
+
+MACHINE_START(GUIDEA07, "Guide A07 (cs89712 core)")
+	MAINTAINER("Cam Mayor")
+	VIDEO(0x60000000, 0x6000bfff)
+	BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_guide_a07)
+	MAPIO(guide_a07_map_io)
+	INITIRQ(clps711x_init_irq)
+MACHINE_END
+
+static int guide_a07_hw_init(void)
+{
+	/* in cs[1] (the FPGA), set zero wait states, clkenb, and sqaen */
+	u32 memcfg1 = 0xfc << 8;
+	memcfg1 |= clps_readl(MEMCFG1);
+	clps_writel(memcfg1, MEMCFG1);
+
+	return 0;
+}
+
+__initcall(guide_a07_hw_init);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-clps711x/irq.c linux-2.4.22-pre10/arch/arm/mach-clps711x/irq.c
--- linux-2.4.21/arch/arm/mach-clps711x/irq.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-clps711x/irq.c	2003-08-01 13:31:01.000000000 +0000
@@ -18,6 +18,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
 
 #include <asm/mach/irq.h>
 #include <asm/hardware.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-ebsa110/irq.c linux-2.4.22-pre10/arch/arm/mach-ebsa110/irq.c
--- linux-2.4.21/arch/arm/mach-ebsa110/irq.c	2001-04-12 19:20:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-ebsa110/irq.c	2003-08-01 13:31:47.000000000 +0000
@@ -11,6 +11,9 @@
  *   22-08-1998	RMK	Restructured IRQ routines
  */
 #include <linux/init.h>
+#include <linux/stddef.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/mach/irq.h>
 #include <asm/hardware.h>
@@ -35,14 +38,14 @@
 	unsigned long flags;
 	int irq;
 
-	save_flags_cli (flags);
+	local_irq_save(flags);
 	__raw_writeb(0xff, IRQ_MCLR);
 	__raw_writeb(0x55, IRQ_MSET);
 	__raw_writeb(0x00, IRQ_MSET);
 	if (__raw_readb(IRQ_MASK) != 0x55)
 		while (1);
 	__raw_writeb(0xff, IRQ_MCLR);	/* clear all interrupt enables */
-	restore_flags (flags);
+	local_irq_restore(flags);
 
 	for (irq = 0; irq < NR_IRQS; irq++) {
 		irq_desc[irq].valid	= 1;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-epxa/Makefile linux-2.4.22-pre10/arch/arm/mach-epxa/Makefile
--- linux-2.4.21/arch/arm/mach-epxa/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-epxa/Makefile	2003-08-01 13:32:31.000000000 +0000
@@ -0,0 +1,24 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= epxa.o
+
+# Object file lists.
+
+obj-y			:=  irq.o mm.o time.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= 
+
+obj-$(CONFIG_EPXA1DB) += arch-epxa1db.o
+obj-$(CONFIG_EPXA10DB) += arch-epxa10db.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-epxa/arch-epxa10db.c linux-2.4.22-pre10/arch/arm/mach-epxa/arch-epxa10db.c
--- linux-2.4.21/arch/arm/mach-epxa/arch-epxa10db.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-epxa/arch-epxa10db.c	2003-08-01 13:32:48.000000000 +0000
@@ -0,0 +1,60 @@
+/*
+ *  linux/arch/arm/mach-epxa/arch-epxa10db.c
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+extern void epxa_map_io(void);
+extern void epxa_init_irq(void);
+
+
+static void __init
+epxa10db_fixup(struct machine_desc *desc, struct param_struct *params,
+		 char **cmdline, struct meminfo *mi)
+{
+
+        mi->nr_banks      = 1;
+        mi->bank[0].start = 0;
+        mi->bank[0].size  = (128*1024*1024);
+        mi->bank[0].node  = 0;
+
+/*
+        ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+        setup_ramdisk( 1, 0, 0, 8192 );
+        setup_initrd(0xc0200000, 6*1024*1024);
+*/
+}
+
+MACHINE_START(CAMELOT, "Altera Epxa10db")
+	MAINTAINER("Altera Corporation")
+	BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000)
+      	FIXUP(epxa10db_fixup)
+	MAPIO(epxa_map_io)
+	INITIRQ(epxa_init_irq)
+        BOOT_PARAMS(0x100)
+MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-epxa/arch-epxa1db.c linux-2.4.22-pre10/arch/arm/mach-epxa/arch-epxa1db.c
--- linux-2.4.21/arch/arm/mach-epxa/arch-epxa1db.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-epxa/arch-epxa1db.c	2003-08-01 13:34:17.000000000 +0000
@@ -0,0 +1,59 @@
+/*
+ *  linux/arch/arm/mach-epxa/arch-epxa10db.c
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+extern void epxa_map_io(void);
+extern void epxa_init_irq(void);
+
+static void __init
+epxa1db_fixup(struct machine_desc *desc, struct param_struct *params,
+		 char **cmdline, struct meminfo *mi)
+{
+
+        mi->nr_banks      = 1;
+        mi->bank[0].start = 0;
+        mi->bank[0].size  = (32*1024*1024);
+        mi->bank[0].node  = 0;
+
+/*
+        ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+        setup_ramdisk( 1, 0, 0, 8192 );
+        setup_initrd(0xc0200000, 6*1024*1024);
+*/
+}
+
+MACHINE_START(CAMELOT, "Altera Epxa1db")
+	MAINTAINER("Altera Corporation")
+	BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000)
+      	FIXUP(epxa1db_fixup)
+	MAPIO(epxa_map_io)
+	INITIRQ(epxa_init_irq)
+        BOOT_PARAMS(0x100)
+MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-epxa/dma.c linux-2.4.22-pre10/arch/arm/mach-epxa/dma.c
--- linux-2.4.21/arch/arm/mach-epxa/dma.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-epxa/dma.c	2003-08-01 13:32:02.000000000 +0000
@@ -0,0 +1,36 @@
+/*
+ *  linux/arch/arm/mach-epxa10db/dma.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/dma.h>
+
+void __init arch_dma_init(dma_t *dma)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-epxa/irq.c linux-2.4.22-pre10/arch/arm/mach-epxa/irq.c
--- linux-2.4.21/arch/arm/mach-epxa/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-epxa/irq.c	2003-08-01 13:33:20.000000000 +0000
@@ -0,0 +1,74 @@
+/*
+ *  linux/arch/arm/mach-epxa10db/irq.c
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/stddef.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/platform.h>
+#include <asm/arch/int_ctrl00.h>
+
+
+static void mask_irq(unsigned int irq)
+{
+        __raw_writel(1 << irq, INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
+}
+
+static void unmask_irq(unsigned int irq)
+{
+        __raw_writel(1 << irq, INT_MS(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
+}
+ 
+void __init epxa_init_irq(void)
+{
+	unsigned int i;
+	
+	/*
+	 * This bit sets up the interrupt controller using 
+	 * the 6 PLD interrupts mode (the default) each 
+	 * irqs is assigned a priority which is the same
+	 * as its interrupt number. This scheme is used because 
+	 * its easy, but you may want to change it depending
+	 * on the contents of your PLD
+	 */
+
+	__raw_writel(3,INT_MODE(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
+	for (i = 0; i < NR_IRQS; i++){
+		__raw_writel(i+1, INT_PRIORITY_P0(IO_ADDRESS(EXC_INT_CTRL00_BASE)) + (4*i));
+	}
+
+
+	for (i = 0; i < NR_IRQS; i++) {
+	       
+		irq_desc[i].valid	= 1;
+		irq_desc[i].probe_ok	= 1;
+		irq_desc[i].mask_ack	= mask_irq;
+		irq_desc[i].mask	= mask_irq;
+		irq_desc[i].unmask	= unmask_irq;
+	}
+
+	/* Disable all interrupt */
+	__raw_writel(-1,INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
+
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-epxa/mm.c linux-2.4.22-pre10/arch/arm/mach-epxa/mm.c
--- linux-2.4.21/arch/arm/mach-epxa/mm.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-epxa/mm.c	2003-08-01 13:34:12.000000000 +0000
@@ -0,0 +1,43 @@
+/*
+ *  linux/arch/arm/mach-epxa10db/mm.c
+ *
+ *  MM routines for Altera'a Epxa10db board
+ *
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/sizes.h>
+ 
+#include <asm/mach/map.h>
+
+/* Page table mapping for I/O region */
+ 
+static struct map_desc epxa_io_desc[] __initdata = {
+ { IO_ADDRESS(EXC_REGISTERS_BASE),   EXC_REGISTERS_BASE,   SZ_4K     , DOMAIN_IO, 0, 1},  LAST_DESC
+};
+
+void __init epxa_map_io(void)
+{
+	iotable_init(epxa_io_desc);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-epxa/time.c linux-2.4.22-pre10/arch/arm/mach-epxa/time.c
--- linux-2.4.21/arch/arm/mach-epxa/time.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-epxa/time.c	2003-08-01 13:32:52.000000000 +0000
@@ -0,0 +1,33 @@
+/*
+ *  linux/arch/arm/mach-epxa10db/time.c
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+
+
+
+extern int (*set_rtc)(void);
+
+static int epxa10db_set_rtc(void)
+{
+	return 1;
+}
+
+static int epxa10db_rtc_init(void)
+{
+	set_rtc = epxa10db_set_rtc;
+
+	return 0;
+}
+
+__initcall(epxa10db_rtc_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-epxa10db/Makefile linux-2.4.22-pre10/arch/arm/mach-epxa10db/Makefile
--- linux-2.4.21/arch/arm/mach-epxa10db/Makefile	2001-10-25 20:53:45.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-epxa10db/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,22 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-
-USE_STANDARD_AS_RULE := true
-
-O_TARGET		:= epxa10db.o
-
-# Object file lists.
-
-obj-y			:= arch.o irq.o mm.o time.o 
-obj-m			:=
-obj-n			:=
-obj-			:=
-
-export-objs		:= 
-
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-epxa10db/arch.c linux-2.4.22-pre10/arch/arm/mach-epxa10db/arch.c
--- linux-2.4.21/arch/arm/mach-epxa10db/arch.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-epxa10db/arch.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,61 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/arch.c
- *
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-
-extern void epxa10db_map_io(void);
-extern void epxa10db_init_irq(void);
-
-
-static void __init
-epxa10db_fixup(struct machine_desc *desc, struct param_struct *params,
-		 char **cmdline, struct meminfo *mi)
-{
-
-        mi->nr_banks      = 1;
-        mi->bank[0].start = 0;
-        mi->bank[0].size  = (32*1024*1024);
-        mi->bank[0].node  = 0;
-
-/*
-        ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-        setup_ramdisk( 1, 0, 0, 8192 );
-        setup_initrd(0xc0200000, 6*1024*1024);
-*/
-}
-
-MACHINE_START(CAMELOT, "Altera Epxa10db")
-	MAINTAINER("Altera Corporation")
-	BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000)
-      	FIXUP(epxa10db_fixup)
-	MAPIO(epxa10db_map_io)
-	INITIRQ(epxa10db_init_irq)
-
-MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-epxa10db/dma.c linux-2.4.22-pre10/arch/arm/mach-epxa10db/dma.c
--- linux-2.4.21/arch/arm/mach-epxa10db/dma.c	2001-11-22 18:41:14.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-epxa10db/dma.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,36 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/dma.c
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/mman.h>
-#include <linux/init.h>
-
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/hardware.h>
-
-#include <asm/mach/dma.h>
-
-void __init arch_dma_init(dma_t *dma)
-{
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-epxa10db/irq.c linux-2.4.22-pre10/arch/arm/mach-epxa10db/irq.c
--- linux-2.4.21/arch/arm/mach-epxa10db/irq.c	2001-10-25 20:53:45.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-epxa10db/irq.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,70 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/irq.c
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/init.h>
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/mach/irq.h>
-#include <asm/arch/platform.h>
-#include <asm/arch/int_ctrl00.h>
-
-
-static void mask_irq(unsigned int irq)
-{
-        __raw_writel(1 << irq, INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
-}
-
-static void unmask_irq(unsigned int irq)
-{
-        __raw_writel(1 << irq, INT_MS(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
-}
- 
-void __init epxa10db_init_irq(void)
-{
-	unsigned int i;
-	
-	/*
-	 * This bit sets up the interrupt controller using 
-	 * the 6 PLD interrupts mode (the default) each 
-	 * irqs is assigned a priority which is the same
-	 * as its interrupt number. This scheme is used because 
-	 * its easy, but you may want to change it depending
-	 * on the contents of your PLD
-	 */
-
-	__raw_writel(3,INT_MODE(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
-	for (i = 0; i < NR_IRQS; i++){
-		__raw_writel(i+1, INT_PRIORITY_P0(IO_ADDRESS(EXC_INT_CTRL00_BASE)) + (4*i));
-	}
-
-
-	for (i = 0; i < NR_IRQS; i++) {
-	       
-		irq_desc[i].valid	= 1;
-		irq_desc[i].probe_ok	= 1;
-		irq_desc[i].mask_ack	= mask_irq;
-		irq_desc[i].mask	= mask_irq;
-		irq_desc[i].unmask	= unmask_irq;
-	}
-
-	/* Disable all interrupt */
-	__raw_writel(-1,INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-epxa10db/mm.c linux-2.4.22-pre10/arch/arm/mach-epxa10db/mm.c
--- linux-2.4.21/arch/arm/mach-epxa10db/mm.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-epxa10db/mm.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,49 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/mm.c
- *
- *  MM routines for Altera'a Epxa10db board
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/sizes.h>
- 
-#include <asm/mach/map.h>
-
-/* Page table mapping for I/O region */
- 
-static struct map_desc epxa10db_io_desc[] __initdata = {
- { IO_ADDRESS(EXC_REGISTERS_BASE),   EXC_REGISTERS_BASE,   SZ_16K     , DOMAIN_IO, 0, 1}, 
-{IO_ADDRESS(EXC_PLD_BLOCK0_BASE),   EXC_PLD_BLOCK0_BASE,   SZ_16K     , DOMAIN_IO, 0, 1}, 
-{IO_ADDRESS(EXC_PLD_BLOCK1_BASE),   EXC_PLD_BLOCK1_BASE,   SZ_16K     , DOMAIN_IO, 0, 1}, 
-{IO_ADDRESS(EXC_PLD_BLOCK2_BASE),   EXC_PLD_BLOCK2_BASE,   SZ_16K     , DOMAIN_IO, 0, 1}, 
-{IO_ADDRESS(EXC_PLD_BLOCK3_BASE),   EXC_PLD_BLOCK3_BASE,   SZ_16K     , DOMAIN_IO, 0, 1}, 
-{ FLASH_VADDR(EXC_EBI_BLOCK0_BASE),   EXC_EBI_BLOCK0_BASE,   SZ_16M     , DOMAIN_IO, 0, 1},
- LAST_DESC
-};
-
-void __init epxa10db_map_io(void)
-{
-	iotable_init(epxa10db_io_desc);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-epxa10db/time.c linux-2.4.22-pre10/arch/arm/mach-epxa10db/time.c
--- linux-2.4.21/arch/arm/mach-epxa10db/time.c	2001-10-25 20:53:45.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-epxa10db/time.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,33 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/time.c
- *
- *  Copyright (C) 2000 Deep Blue Solutions
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-
-#include <asm/hardware.h>
-
-
-
-extern int (*set_rtc)(void);
-
-static int epxa10db_set_rtc(void)
-{
-	return 1;
-}
-
-static int epxa10db_rtc_init(void)
-{
-	set_rtc = epxa10db_set_rtc;
-
-	return 0;
-}
-
-__initcall(epxa10db_rtc_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-footbridge/arch.c linux-2.4.22-pre10/arch/arm/mach-footbridge/arch.c
--- linux-2.4.21/arch/arm/mach-footbridge/arch.c	2001-08-12 18:13:59.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-footbridge/arch.c	2003-08-01 13:32:13.000000000 +0000
@@ -41,10 +41,12 @@
 fixup_ebsa285(struct machine_desc *desc, struct param_struct *params,
 	      char **cmdline, struct meminfo *mi)
 {
+#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
 	ORIG_X		 = params->u1.s.video_x;
 	ORIG_Y		 = params->u1.s.video_y;
 	ORIG_VIDEO_COLS  = params->u1.s.video_num_cols;
 	ORIG_VIDEO_LINES = params->u1.s.video_num_rows;
+#endif
 }
 
 MACHINE_START(EBSA285, "EBSA285")
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-footbridge/irq.c linux-2.4.22-pre10/arch/arm/mach-footbridge/irq.c
--- linux-2.4.21/arch/arm/mach-footbridge/irq.c	2001-04-12 19:20:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-footbridge/irq.c	2003-08-01 13:35:00.000000000 +0000
@@ -18,6 +18,8 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/mach/irq.h>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-integrator/cpu.c linux-2.4.22-pre10/arch/arm/mach-integrator/cpu.c
--- linux-2.4.21/arch/arm/mach-integrator/cpu.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-integrator/cpu.c	2003-08-01 13:33:16.000000000 +0000
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2001 Deep Blue Solutions Ltd.
  *
- *  $Id: cpu.c,v 1.2 2001/09/22 12:11:17 rmk Exp $
+ *  $Id: cpu.c,v 1.2.2.1 2002/05/30 15:08:03 db Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-integrator/irq.c linux-2.4.22-pre10/arch/arm/mach-integrator/irq.c
--- linux-2.4.21/arch/arm/mach-integrator/irq.c	2001-03-03 02:38:39.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-integrator/irq.c	2003-08-01 13:34:59.000000000 +0000
@@ -18,6 +18,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
+#include <linux/stddef.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-mx1ads/irq.c linux-2.4.22-pre10/arch/arm/mach-mx1ads/irq.c
--- linux-2.4.21/arch/arm/mach-mx1ads/irq.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-mx1ads/irq.c	2003-08-01 13:33:53.000000000 +0000
@@ -19,6 +19,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/init.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-omaha/Makefile linux-2.4.22-pre10/arch/arm/mach-omaha/Makefile
--- linux-2.4.21/arch/arm/mach-omaha/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-omaha/Makefile	2003-08-01 13:33:55.000000000 +0000
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= omaha.o
+
+# Object file lists.
+
+obj-y			:= core.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+obj-$(CONFIG_LEDS)	+= leds.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-omaha/core.c linux-2.4.22-pre10/arch/arm/mach-omaha/core.c
--- linux-2.4.21/arch/arm/mach-omaha/core.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-omaha/core.c	2003-08-01 13:33:12.000000000 +0000
@@ -0,0 +1,130 @@
+/*
+ *  linux/arch/arm/mach-omaha/core.c
+ *
+ *  Copyright (C) ARM Limited 2002.
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+extern void omaha_map_io(void);
+
+/* 
+ * All IO addresses are mapped onto VA 0xExxx.xxxx, where x.xxxx
+ * is the (PA + 0xE0000000).
+ *
+ * Setup a VA for the Omaha interrupt controller.
+ */
+ 
+#define VA_IC_BASE              IO_ADDRESS(PLAT_PERIPHERAL_BASE) 
+
+static void sc_mask_and_ack_irq(unsigned int irq)
+{
+	unsigned int tmp;
+	
+	// Mask this interrupt
+	tmp = __raw_readl(VA_IC_BASE + OMAHA_INTMSK);
+	tmp = tmp | (1 << irq);	  	
+        __raw_writel(tmp, VA_IC_BASE + OMAHA_INTMSK);
+	
+	// Clear the source pending register
+	tmp = __raw_readl(VA_IC_BASE + OMAHA_SRCPND);
+	tmp = tmp | (1 << irq);	  	
+        __raw_writel(tmp, VA_IC_BASE + OMAHA_SRCPND);
+	
+	// Clear the interrupt pending register
+	tmp = __raw_readl(VA_IC_BASE + OMAHA_INTPND);
+	tmp = tmp | (1 << irq);	  	
+	__raw_writel(tmp, VA_IC_BASE + OMAHA_INTPND);
+
+}
+
+static void sc_mask_irq(unsigned int irq)
+{
+	unsigned int tmp;
+	
+	// Mask this interrupt
+	tmp = __raw_readl(VA_IC_BASE + OMAHA_INTMSK);
+	tmp = tmp | (1 << irq);	  	
+        __raw_writel(tmp, VA_IC_BASE + OMAHA_INTMSK);
+}
+
+static void sc_unmask_irq(unsigned int irq)
+{
+	unsigned int tmp;
+	
+	tmp = __raw_readl(VA_IC_BASE + OMAHA_INTMSK);
+	tmp = tmp & ~(1 << irq);	  	
+        __raw_writel(tmp, VA_IC_BASE + OMAHA_INTMSK);
+}
+ 
+static void __init omaha_init_irq(void)
+{
+	unsigned int i;
+
+	/* bootloader disables interrupt hardware,
+	 * so we just set up linux data structures...
+	 */
+
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].valid	= 1;
+		irq_desc[i].probe_ok	= 1;
+		irq_desc[i].mask_ack	= sc_mask_and_ack_irq;
+		irq_desc[i].mask	= sc_mask_irq;
+		irq_desc[i].unmask	= sc_unmask_irq;
+	}
+}
+
+/* Notes
+ *
+ * IO space has been mapped into the top of virtual memory at 0xExxx xxxx
+ * See IO_ACCESS macro for details.
+ */
+
+/* 		Logical		Physical
+ * Start	0xE0000000	0x00000000
+ * End		0xFAFFFFFC	0x1AFFFFFC
+ */
+
+/* Map the bottom 2Gb of IO space into the top of memory, but leave
+ * space for the high vector table.
+ */ 
+static struct map_desc omaha_io_desc[] __initdata = {
+ { IO_ADDRESS(0x00000000), 0x00000000, 0x1B000000, DOMAIN_IO, 0, 1 },
+ LAST_DESC
+};
+
+static void __init omaha_map_io(void)
+{
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-omaha/leds.c linux-2.4.22-pre10/arch/arm/mach-omaha/leds.c
--- linux-2.4.21/arch/arm/mach-omaha/leds.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-omaha/leds.c	2003-08-01 13:34:52.000000000 +0000
@@ -0,0 +1,89 @@
+/*
+ *  linux/arch/arm/mach-omaha/leds.c
+ *
+ *  Omaha LED control routines
+ *
+ *  Copyright (C) 1999-2002 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+static int saved_leds;
+
+static void omaha_leds_event(led_event_t ledevt)
+{
+	unsigned long flags;			      
+	unsigned int ctrl = IO_ADDRESS(PLAT_DBG_LEDS);
+	unsigned int leds;
+	
+	// yup, change the LEDs
+	local_irq_save(flags);
+
+	switch(ledevt) {
+	case led_idle_start:
+		leds = __raw_readl(ctrl);
+		leds |= GREEN_LED;
+		__raw_writel(leds,ctrl);
+		break;
+
+	case led_idle_end:
+		leds = __raw_readl(ctrl);
+		leds &= ~GREEN_LED;
+		__raw_writel(leds,ctrl);
+		break;
+
+	case led_timer:
+		leds = __raw_readl(ctrl);
+		leds ^= YELLOW_LED;
+		__raw_writel(leds,ctrl);
+		break;
+
+	case led_red_on:
+		leds = __raw_readl(ctrl);
+		leds |= RED_LED;
+		__raw_writel(leds,ctrl);
+		break;
+
+	case led_red_off:
+		leds = __raw_readl(ctrl);
+		leds &= ~RED_LED;
+		__raw_writel(leds,ctrl);
+		break;
+
+	default:
+		break;
+	}
+
+	local_irq_restore(flags);
+}
+
+static int __init leds_init(void)
+{
+	if (machine_is_omaha())
+		leds_event = omaha_leds_event;
+
+	return 0;
+}
+
+__initcall(leds_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/Makefile linux-2.4.22-pre10/arch/arm/mach-sa1100/Makefile
--- linux-2.4.21/arch/arm/mach-sa1100/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/Makefile	2003-08-01 13:35:06.000000000 +0000
@@ -15,10 +15,10 @@
 obj-n :=
 obj-  :=
 
-export-objs :=	assabet.o dma-sa1100.o dma-sa1111.o \
-		flexanet.o freebird.o generic.o h3600.o \
-		huw_webpanel.o irq.o pcipool.o sa1111.o sa1111-pcibuf.o \
-		system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o
+export-objs :=	assabet.o consus.o badge4.o dma-sa1100.o dma-sa1111.o \
+		flexanet.o freebird.o frodo.o generic.o h3600.o \
+		huw_webpanel.o irq.o sa1111.o sa1111-pcibuf.o \
+		system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o simputer.o ssp.o
 
 # These aren't present yet, and prevents a plain -ac kernel building.
 # hwtimer.o
@@ -29,22 +29,30 @@
 # We link the CPU support next, so that RAM timings can be tuned.
 ifeq ($(CONFIG_CPU_FREQ),y)
 obj-$(CONFIG_SA1100_ASSABET) += cpu-sa1110.o
+obj-$(CONFIG_SA1100_CEP) += cpu-sa1110.o
+obj-$(CONFIG_SA1100_CONSUS) += cpu-sa1110.o
 obj-$(CONFIG_SA1100_CERF) += cpu-sa1110.o
+obj-$(CONFIG_SA1100_HACKKIT) += cpu-sa1110.o
 obj-$(CONFIG_SA1100_PT_SYSTEM3) += cpu-sa1110.o
+obj-$(CONFIG_SA1100_SIMPUTER) += cpu-sa1110.o
 obj-$(CONFIG_SA1100_LART) += cpu-sa1100.o
 endif
 
 # Next, the SA1111 stuff.
 obj-$(CONFIG_SA1111) += sa1111.o dma-sa1111.o
-obj-$(CONFIG_USB_OHCI_SA1111) += sa1111-pcibuf.o pcipool.o
+obj-$(CONFIG_USB_OHCI_SA1111) += sa1111-pcibuf.o
 
 # Specific board support
+obj-$(CONFIG_SA1100_ADSAGC) += adsagc.o
 obj-$(CONFIG_SA1100_ADSBITSY) += adsbitsy.o
+obj-$(CONFIG_SA1100_ADSBITSYPLUS) += adsbitsyplus.o
 obj-$(CONFIG_SA1100_ASSABET) += assabet.o
 obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o
 obj-$(CONFIG_SA1100_BADGE4) +=  badge4.o
 obj-$(CONFIG_SA1100_BRUTUS) += brutus.o
+obj-$(CONFIG_SA1100_CEP) += cep.o
 obj-$(CONFIG_SA1100_CERF) += cerf.o
+obj-$(CONFIG_SA1100_CONSUS) += consus.o
 obj-$(CONFIG_SA1100_EMPEG) += empeg.o
 obj-$(CONFIG_SA1100_FLEXANET) += flexanet.o
 obj-$(CONFIG_SA1100_FREEBIRD) += freebird.o
@@ -52,6 +60,7 @@
 obj-$(CONFIG_SA1100_GRAPHICSCLIENT) += graphicsclient.o
 obj-$(CONFIG_SA1100_GRAPHICSMASTER) += graphicsmaster.o
 obj-$(CONFIG_SA1100_H3600) += h3600.o
+obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o
 obj-$(CONFIG_SA1100_HUW_WEBPANEL) += huw_webpanel.o
 obj-$(CONFIG_SA1100_ITSY) += itsy.o
 obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o
@@ -65,20 +74,25 @@
 obj-$(CONFIG_SA1100_SHANNON) += shannon.o
 obj-$(CONFIG_SA1100_SHERMAN) += sherman.o
 obj-$(CONFIG_SA1100_SIMPAD) += simpad.o
+obj-$(CONFIG_SA1100_SIMPUTER) += simputer.o
 obj-$(CONFIG_SA1100_VICTOR) += victor.o
 obj-$(CONFIG_SA1100_XP860) += xp860.o
 obj-$(CONFIG_SA1100_YOPY) += yopy.o
 
 # LEDs support
 leds-y := leds.o
+leds-$(CONFIG_SA1100_ADSAGC) += leds-adsagc.o
 leds-$(CONFIG_SA1100_ADSBITSY) += leds-adsbitsy.o
+leds-$(CONFIG_SA1100_ADSBITSYPLUS) += leds-adsbitsyplus.o
 leds-$(CONFIG_SA1100_ASSABET) += leds-assabet.o
 leds-$(CONFIG_SA1100_BRUTUS) += leds-brutus.o
 leds-$(CONFIG_SA1100_CERF) += leds-cerf.o
+leds-$(CONFIG_SA1100_CONSUS) += leds-consus.o
 leds-$(CONFIG_SA1100_FLEXANET) += leds-flexanet.o
 leds-$(CONFIG_SA1100_FRODO) += leds-frodo.o
 leds-$(CONFIG_SA1100_GRAPHICSCLIENT) += leds-graphicsclient.o
 leds-$(CONFIG_SA1100_GRAPHICSMASTER) += leds-graphicsmaster.o
+leds-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o
 leds-$(CONFIG_SA1100_LART) += leds-lart.o
 leds-$(CONFIG_SA1100_PFS168) += leds-pfs168.o
 leds-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o  
@@ -95,6 +109,8 @@
 # Miscelaneous functions
 obj-$(CONFIG_PM) += pm.o sleep.o
 
+obj-$(CONFIG_SA1100_SSP)		+= ssp.o
+
 include $(TOPDIR)/Rules.make
 
 sa1100usb_core.o: $(sa1100usb_core-objs)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/adsagc.c linux-2.4.22-pre10/arch/arm/mach-sa1100/adsagc.c
--- linux-2.4.21/arch/arm/mach-sa1100/adsagc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/adsagc.c	2003-08-01 13:30:54.000000000 +0000
@@ -0,0 +1,360 @@
+/*
+ * linux/arch/arm/mach-sa1100/adsagc.c
+ *
+ * Pieces specific to the ADS Advanced Graphics Client board
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/serial_core.h>
+#include <linux/delay.h>
+
+#include <asm/hardware.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/arch/irq.h>
+
+#include "generic.h"
+#include "sa1111.h"
+
+static int __init adsagc_init(void)
+{
+	int ret;
+
+	if (!machine_is_adsagc())
+		return -ENODEV;
+
+	/*
+	 * Ensure that the memory bus request/grant signals are setup,
+	 * and the grant is held in its inactive state
+	 */
+	sa1110_mb_disable();
+
+	/* Adsagc uses GPIO pins for SPI interface to AVR
+	 * AGC uses the standard pins instead.  AGC also has controls
+	 * SA1111 and Smartio reset with GPIO.
+	 */
+
+	// Set RTS low during sleep
+	PGSR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
+
+	// Reset SA1111
+	GPDR |= GPIO_GPIO12;
+	GPCR = GPIO_GPIO12;
+	udelay(1000);
+	GPSR = GPIO_GPIO12;
+
+	/* use the regular SSP pins */
+	PPAR &= ~PPAR_SSPGPIO;
+	/*
+	 * Probe for SA1111.
+	 */
+	ret = sa1111_probe(ADS_SA1111_BASE);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We found it.  Wake the chip up.
+	 */
+	sa1111_wake();
+
+	/*
+	 * The SDRAM configuration of the SA1110 and the SA1111 must
+	 * match.  This is very important to ensure that SA1111 accesses
+	 * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+	 * MBGNT signal, so we must have called sa1110_mb_disable()
+	 * beforehand.
+	 */
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+	/*
+	 * Enable PWM control for LCD
+	 */
+	SKPCR |= SKPCR_PWMCLKEN;
+	SACR1 &= ~SACR1_L3EN;
+	ADS_CR3 |= ADS_CR3_BLON;                // Enable the backlight
+	SKPWM1 = 0x7F;				// Backlight PWM
+	SKPEN1 = 1;
+	SKPWM0 = 0x7F;				// VEE
+	SKPEN0 = 1;
+
+	/*
+	 * We only need to turn on DCLK whenever we want to use the
+	 * DMA.  It can otherwise be held firmly in the off position.
+	 */
+	SKPCR |= SKPCR_DCLKEN;
+
+	/*
+	 * Enable the SA1110 memory bus request and grant signals.
+	 */
+	sa1110_mb_enable();
+
+	set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE);
+	sa1111_init_irq(IRQ_GPIO0);
+
+	return 0;
+}
+
+__initcall(adsagc_init);
+
+/*
+ * Handlers for Adsagc's external IRQ logic
+ */
+
+#define ADSAGC_N_IRQ (IRQ_ADSAGC_END - IRQ_ADSAGC_START)
+
+static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
+{
+	int i;
+
+	while( (irq = ADS_INT_ST1 ) ){
+		for( i = 0; i < ADSAGC_N_IRQ; i++ )
+			if( irq & (1<<i) ) {
+				do_IRQ( IRQ_ADSAGC_START + i, regs );
+			}
+	}
+}
+
+static struct irqaction ADS_ext_irq = {
+	.name		= "ADS_ext_IRQ",
+	.handler	= ADS_IRQ_demux,
+	.flags		= SA_INTERRUPT
+};
+
+static void ADS_mask_and_ack_irq0(unsigned int irq)
+{
+	int mask = (1 << (irq - IRQ_ADSAGC_START));
+	ADS_INT_EN1 &= ~mask;
+	ADS_INT_ST1 = mask;
+}
+
+static void ADS_mask_irq0(unsigned int irq)
+{
+	ADS_INT_ST1 = (1 << (irq - IRQ_ADSAGC_START));
+}
+
+static void ADS_unmask_irq0(unsigned int irq)
+{
+	ADS_INT_EN1 |= (1 << (irq - IRQ_ADSAGC_START));
+}
+
+static void __init adsagc_init_irq(void)
+{
+	int irq;
+
+	/* First the standard SA1100 IRQs */
+	sa1100_init_irq();
+
+
+	/* disable all IRQs */
+	ADS_INT_EN1 = 0;
+
+	/* clear all IRQs */
+	ADS_INT_ST1 = 0xff;
+
+	for (irq = IRQ_ADSAGC_START; irq < IRQ_ADSAGC_END; irq++) {
+		irq_desc[irq].valid	= 1;
+		irq_desc[irq].probe_ok	= 1;
+		irq_desc[irq].mask_ack	= ADS_mask_and_ack_irq0;
+		irq_desc[irq].mask	= ADS_mask_irq0;
+		irq_desc[irq].unmask	= ADS_unmask_irq0;
+	}
+
+	GPDR &= ~GPIO_GPIO10;
+	set_GPIO_IRQ_edge(GPIO_GPIO10, GPIO_RISING_EDGE);  // this may change with final HW spin
+	setup_arm_irq( IRQ_GPIO10, &ADS_ext_irq );
+}
+
+
+/*
+ * Resume SA1111 when system wakes up
+ */
+void adsagc_sa1111_wake(void)
+{
+	// Reset SA1111
+	GPDR |= GPIO_GPIO12;
+	GPCR = GPIO_GPIO12;
+	udelay(1000);
+	GPSR = GPIO_GPIO12;
+	sa1111_wake();
+
+	SKPCR |= SKPCR_PWMCLKEN;
+	SACR1 &= ~SACR1_L3EN;
+
+	SKPWM1 = 0x7F;				// Backlight PWM
+	SKPEN1 = 1;
+	SKPWM0 = 0x7F;				// VEE
+	SKPEN0 = 1;
+
+	GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
+	GPDR |= GPIO_MBGNT;
+	GPDR &= ~GPIO_MBREQ;
+	TUCR |= TUCR_MR;
+
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+	SKPCR |= SKPCR_DCLKEN;
+
+	// Reset PCMCIA
+	PCCR = 0xFF;
+	mdelay(100);
+	PA_DDR = 0x00;
+	PA_DWR = 0x05;
+	PCCR = ~(PCCR_S0_RST | PCCR_S1_RST);
+
+#ifdef CONFIG_USB_OHCI_SA1111
+	// Turn ON clock
+	SKPCR |= SKPCR_UCLKEN;
+	udelay(100);
+
+	// force a RESET
+	USB_RESET = 0x01;
+	USB_RESET |= 0x02;
+	udelay(100);
+
+	// Set Power Sense and Control Line
+	USB_RESET = 0;
+	USB_RESET = USB_RESET_PWRSENSELOW;
+	USB_STATUS = 0;
+	udelay(10);
+#endif
+}
+
+static struct map_desc adsagc_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xf2000000, 0x40000000, 0x00004000, DOMAIN_IO, 0, 1, 0, 0 }, /* 91C1111 */
+  { 0xf3000000, 0x48000000, 0x00340000, DOMAIN_IO, 0, 1, 0, 0 }, /* S1D13806 */
+  /* note: CPLD includes CAN in Advanced Graphics Client */
+  { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
+  { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA-1111 */
+  LAST_DESC
+};
+
+static int adsagc_uart_open(struct uart_port *port, struct uart_info *info)
+{
+	int	ret = 0;
+
+	if (port->mapbase == _Ser1UTCR0) {
+		Ser1SDCR0 |= SDCR0_UART;
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
+		Ser2UTCR4 = Ser2HSCR0 = 0;
+	}
+	return ret;
+}
+
+static u_int adsagc_get_mctrl(struct uart_port *port)
+{
+	u_int result = TIOCM_CD | TIOCM_DSR;
+
+	if (port->mapbase == _Ser1UTCR0) {
+		if (!(GPLR & GPIO_GPIO14))
+			result |= TIOCM_CTS;
+	} else if (port->mapbase == _Ser2UTCR0) {
+		if (!(GPLR & GPIO_GPIO16))
+			result |= TIOCM_CTS;
+	} else if (port->mapbase == _Ser3UTCR0) {
+		if (!(GPLR & GPIO_GPIO18))
+			result |= TIOCM_CTS;
+	} else {
+		result = TIOCM_CTS;
+	}
+
+	return result;
+}
+
+static void adsagc_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	if (port->mapbase == _Ser1UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			GPCR = GPIO_GPIO15;
+		else
+			GPSR = GPIO_GPIO15;
+	} else if (port->mapbase == _Ser2UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			GPCR = GPIO_GPIO17;
+		else
+			GPSR = GPIO_GPIO17;
+	} else if (port->mapbase == _Ser3UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			GPCR = GPIO_GPIO19;
+		else
+			GPSR = GPIO_GPIO19;
+	}
+}
+
+static void
+adsagc_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+	// state has ACPI D0-D3
+	// ACPI D0 	  : resume from suspend
+	// ACPI D1-D3 : enter to a suspend state
+	if (port->mapbase == _Ser1UTCR0) {
+		if (state) {
+                        // disable uart
+                        Ser1UTCR3 = 0;
+		}
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
+		if (state) {
+                        // disable uart
+                        Ser2UTCR3 = 0;
+                        Ser2HSCR0 = 0;
+		}
+	}
+	else if (port->mapbase == _Ser3UTCR0) {
+		if (state) {
+                        // disable uart
+                        Ser3UTCR3 = 0;
+		}
+	}
+}
+
+static struct sa1100_port_fns adsagc_port_fns __initdata = {
+	.open		= adsagc_uart_open,
+	.get_mctrl	= adsagc_get_mctrl,
+	.set_mctrl	= adsagc_set_mctrl,
+	.pm		= adsagc_uart_pm,
+};
+
+static void __init adsagc_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(adsagc_io_desc);
+
+	sa1100_register_uart_fns(&adsagc_port_fns);
+	sa1100_register_uart(0, 3);
+	sa1100_register_uart(1, 1);
+	// don't register if you want to use IRDA
+#ifndef CONFIG_SA1100_FIR
+	sa1100_register_uart(2, 2);
+#endif
+
+	/* set GPDR now */
+	GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
+       	GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO16 | GPIO_GPIO18);
+}
+
+MACHINE_START(ADSAGC, "ADS Advanced GraphicsClient")
+        BOOT_PARAMS(0xc000003c)
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	MAPIO(adsagc_map_io)
+	INITIRQ(adsagc_init_irq)
+MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/adsbitsy.c linux-2.4.22-pre10/arch/arm/mach-sa1100/adsbitsy.c
--- linux-2.4.21/arch/arm/mach-sa1100/adsbitsy.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/adsbitsy.c	2003-08-01 13:30:38.000000000 +0000
@@ -14,9 +14,13 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
+#include <linux/delay.h>
 #include <linux/serial_core.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
+#include <asm/hardware/sa1111.h>
 #include <asm/setup.h>
 #include <asm/irq.h>
 
@@ -30,6 +34,7 @@
 #include "generic.h"
 #include "sa1111.h"
 
+
 static int __init adsbitsy_init(void)
 {
 	int ret;
@@ -43,6 +48,13 @@
 	 */
 	sa1110_mb_disable();
 
+	/* Bitsy uses GPIO pins for SPI interface to AVR
+	 * Bitsy Plus uses the standard pins instead.
+	 * it also needs to reset the AVR when booting
+	 */
+
+	PPAR |= PPAR_SSPGPIO;
+
 	/*
 	 * Reset SA1111
 	 */
@@ -50,6 +62,19 @@
 	udelay(1000);
 	GPSR |= GPIO_GPIO26;
 
+
+#ifndef CONFIG_LEDS_TIMER
+	// Set Serial port 1 RTS and DTR Low during sleep
+	PGSR |= GPIO_GPIO15 | GPIO_GPIO20;
+#else
+	// only RTS (because DTR is also the LED
+	// which should be off during sleep);
+	PGSR |= GPIO_GPIO15;
+#endif
+
+	// Set Serial port 3RTS Low during sleep
+	PGSR |= GPIO_GPIO19;
+
 	/*
 	 * Probe for SA1111.
 	 */
@@ -74,15 +99,6 @@
 			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
 
 	/*
-	 * Enable PWM control for LCD
-	 */
-	SKPCR |= SKPCR_PWMCLKEN;
-	SKPWM0 = 0x7F;				// VEE
-	SKPEN0 = 1;
-	SKPWM1 = 0x01;				// Backlight
-	SKPEN1 = 1;
-
-	/*
 	 * We only need to turn on DCLK whenever we want to use the
 	 * DMA.  It can otherwise be held firmly in the off position.
 	 */
@@ -108,48 +124,135 @@
 }
 
 
-/*
- * Initialization fixup
- */
-
-static void __init
-fixup_adsbitsy(struct machine_desc *desc, struct param_struct *params,
-		     char **cmdline, struct meminfo *mi)
-{
-	SET_BANK( 0, 0xc0000000, 32*1024*1024 );
-	mi->nr_banks = 1;
-
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-	setup_ramdisk( 1, 0, 0, 8192 );
-	setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
-}
-
 static struct map_desc adsbitsy_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xf0000000, 0x3C000000, 0x00004000, DOMAIN_IO, 0, 1, 0, 0 }, /* 91C1111 */
   { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA1111 */
   LAST_DESC
 };
 
+/* Use this to see when all uarts are shutdown.  Or all are closed.
+ * We can only turn off RS232 chip if either of these are true.
+ */
+
+static int uart_wake_count[3] = {1, 1, 1};
+
+enum {UART_SHUTDOWN, UART_WAKEUP};
+
+static void update_uart_counts(int line, int state)
+{
+	switch (state) {
+	case UART_WAKEUP:
+		uart_wake_count[line]++;
+		break;
+	case UART_SHUTDOWN:
+		uart_wake_count[line]--;
+		break;
+	}
+}
+
 static int adsbitsy_uart_open(struct uart_port *port, struct uart_info *info)
 {
 	if (port->mapbase == _Ser1UTCR0) {
 		Ser1SDCR0 |= SDCR0_UART;
-#error Fixme	// Set RTS High (should be done in the set_mctrl fn)
-		GPCR = GPIO_GPIO15;
 	} else if (port->mapbase == _Ser2UTCR0) {
 		Ser2UTCR4 = Ser2HSCR0 = 0;
-#error Fixme	// Set RTS High (should be done in the set_mctrl fn)
-		GPCR = GPIO_GPIO17;
-	} else if (port->mapbase == _Ser2UTCR0) {
-#error Fixme	// Set RTS High (should be done in the set_mctrl fn)
-		GPCR = GPIO_GPIO19;
 	}
 	return 0;
 }
 
+void adsbitsy_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+	// state has ACPI D0-D3
+	// ACPI D0 	  : resume from suspend
+	// ACPI D1-D3 : enter to a suspend state
+	if (port->mapbase == _Ser1UTCR0) {
+		if (state) {
+			update_uart_counts(1, UART_SHUTDOWN);
+			// disable uart
+			Ser1UTCR3 = 0;
+		}
+		else {
+			update_uart_counts(1, UART_WAKEUP);
+		}
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
+		if (state) {
+			update_uart_counts(2, UART_SHUTDOWN);
+			// disable uart
+			Ser2UTCR3 = 0;
+			Ser2HSCR0 = 0;
+		}
+		else {
+			update_uart_counts(2, UART_WAKEUP);
+		}
+	}
+	else if (port->mapbase == _Ser3UTCR0) {
+		if (state) {
+			update_uart_counts(0, UART_SHUTDOWN);
+			// disable uart
+			Ser3UTCR3 = 0;
+		}
+		else {
+			update_uart_counts(0, UART_WAKEUP);
+		}
+	}
+}
+
+static void adsbitsy_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	// note: only ports 1 and 3 have modem control
+	if (port->mapbase == _Ser1UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			// Set RTS High
+			GPCR = GPIO_GPIO15;
+		else
+			// Set RTS LOW
+			GPSR = GPIO_GPIO15;
+		if (mctrl & TIOCM_DTR)
+			// Set DTR High
+			GPCR = GPIO_GPIO20;
+		else
+			// Set DTR Low
+			GPSR = GPIO_GPIO20;
+	} else if (port->mapbase == _Ser3UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			// Set RTS High
+			GPCR = GPIO_GPIO19;
+		else
+			// Set RTS LOW
+			GPSR = GPIO_GPIO19;
+	}
+}
+
+static u_int adsbitsy_get_mctrl(struct uart_port *port)
+{
+	u_int ret = 0;
+
+	// note: only ports 1 and 3 have modem control
+	if (port->mapbase == _Ser1UTCR0) {
+		if (!(GPLR & GPIO_GPIO14))
+			ret |= TIOCM_CTS;
+		if (!(GPLR & GPIO_GPIO24))
+			ret |= TIOCM_DSR;
+		if (!(GPLR & GPIO_GPIO16))
+			ret |= TIOCM_RI;
+		if (!(GPLR & GPIO_GPIO17))
+			ret |= TIOCM_CD;
+	} else if (port->mapbase == _Ser3UTCR0) {
+		if (!(GPLR & GPIO_GPIO18))
+			ret |= TIOCM_CTS;
+	}
+
+	return ret;
+}
+
 static struct sa1100_port_fns adsbitsy_port_fns __initdata = {
-	.open	= adsbitsy_uart_open,
+	.set_mctrl =    adsbitsy_set_mctrl,
+	.get_mctrl =    adsbitsy_get_mctrl,
+	.open =	        adsbitsy_uart_open,
+	.pm =           adsbitsy_uart_pm,
 };
 
 static void __init adsbitsy_map_io(void)
@@ -160,14 +263,27 @@
 	sa1100_register_uart_fns(&adsbitsy_port_fns);
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
+
+	// don't register if you want to use IRDA
+#ifndef CONFIG_SA1100_FIR
 	sa1100_register_uart(2, 2);
-	GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
-	GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO16 | GPIO_GPIO18);
+#endif
+
+	// COM1 Set RTS and DTR Output
+	GPDR |= GPIO_GPIO15 | GPIO_GPIO20;
+	// Set CTS, DSR, RI and CD Input
+	GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO24 | GPIO_GPIO16 | GPIO_GPIO17);
+
+	// COM3 Set RTS Output
+	GPDR |= GPIO_GPIO19;
+	// Set CTS Input
+	GPDR &= ~GPIO_GPIO18;
 }
 
+
 MACHINE_START(ADSBITSY, "ADS Bitsy")
+	BOOT_PARAMS(0xc000003c)
 	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	FIXUP(fixup_adsbitsy)
 	MAPIO(adsbitsy_map_io)
 	INITIRQ(adsbitsy_init_irq)
 MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/adsbitsyplus.c linux-2.4.22-pre10/arch/arm/mach-sa1100/adsbitsyplus.c
--- linux-2.4.21/arch/arm/mach-sa1100/adsbitsyplus.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/adsbitsyplus.c	2003-08-01 13:34:12.000000000 +0000
@@ -0,0 +1,395 @@
+/*
+ * linux/arch/arm/mach-sa1100/adsbitsyplus.c
+ *
+ * Author: Robert Whaley
+ *
+ * This file comes from adsbitsy.c of Woojung Huh <whuh@applieddata.net>
+ *
+ * Pieces specific to the ADS Bitsy Plus
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+
+#include <asm/hardware.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/arch/irq.h>
+
+#include "generic.h"
+#include "sa1111.h"
+
+/* unfortunately, we can't detect the difference between REV 2 and REV A
+   connector boards.  So by convention, the registers.txt file is used
+   to set a byte to either 0x02 or 0x0a to make this distinction.  The
+   bootloader must detect this by default we assume rev A since most boards
+   will be rev A */
+
+static int adsbitsyplus_connector_board_rev_number = 0xA;
+
+static int __init adsbitsyplus_connector_board_rev_setup(char *str)
+{
+	adsbitsyplus_connector_board_rev_number = simple_strtol(str,NULL,0);
+	return 1;
+}
+
+int adsbitsyplus_connector_board_rev(void)
+{
+	static int only_once = 1;
+	if (only_once) {
+		printk(KERN_INFO "Bitsy Connector Board REV: %#x\n", adsbitsyplus_connector_board_rev_number);
+		only_once = 0;
+	}
+	return adsbitsyplus_connector_board_rev_number;
+}
+
+static int __init adsbitsyplus_init(void)
+{
+	int ret;
+
+	if (!machine_is_adsbitsyplus())
+		return -ENODEV;
+
+	/*
+	 * Ensure that the memory bus request/grant signals are setup,
+	 * and the grant is held in its inactive state
+	 */
+	sa1110_mb_disable();
+
+	/* Bitsy uses GPIO pins for SPI interface to AVR
+	 * Bitsy Plus uses the standard pins instead.
+	 * it also needs to reset the AVR when booting
+	 */
+
+	PPAR &= ~PPAR_SSPGPIO;
+	ADS_CPLD_SUPPC |= ADS_SUPPC_AVR_WKP;
+	mdelay(100);
+	ADS_CPLD_SUPPC &= ~ADS_SUPPC_AVR_WKP;
+
+	/*
+	 * Reset SA1111
+	 */
+	GPCR |= GPIO_GPIO26;
+	udelay(1000);
+	GPSR |= GPIO_GPIO26;
+
+#ifndef CONFIG_LEDS_TIMER
+	// Set Serial port 1 RTS and DTR Low during sleep
+	PGSR |= GPIO_GPIO15 | GPIO_GPIO20;
+#else
+	// only RTS (because DTR is also the LED
+	// which should be off during sleep);
+	PGSR |= GPIO_GPIO15;
+#endif
+
+	// Set Serial port 3RTS Low during sleep
+	PGSR |= GPIO_GPIO19;
+
+	/*
+	 * Probe for SA1111.
+	 */
+	ret = sa1111_probe(ADSBITSYPLUS_SA1111_BASE);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We found it.  Wake the chip up.
+	 */
+	sa1111_wake();
+
+	/*
+	 * The SDRAM configuration of the SA1110 and the SA1111 must
+	 * match.  This is very important to ensure that SA1111 accesses
+	 * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+	 * MBGNT signal, so we must have called sa1110_mb_disable()
+	 * beforehand.
+	 */
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+	/*
+	 * We only need to turn on DCLK whenever we want to use the
+	 * DMA.  It can otherwise be held firmly in the off position.
+	 */
+	SKPCR |= SKPCR_DCLKEN;
+
+	/*
+	 * Enable the SA1110 memory bus request and grant signals.
+	 */
+	sa1110_mb_enable();
+
+	set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE);
+	sa1111_init_irq(IRQ_GPIO0);
+
+	return 0;
+}
+
+__initcall(adsbitsyplus_init);
+
+static void __init adsbitsyplus_init_irq(void)
+{
+	/* First the standard SA1100 IRQs */
+	sa1100_init_irq();
+}
+
+/*
+ * Resume SA1111 when system wakes up
+ */
+void adsbitsyplus_sa1111_wake(unsigned long pa_dwr)
+{
+	// Turn ON SA1111
+	GPCR |= GPIO_GPIO26;
+	mdelay(1);
+	GPSR |= GPIO_GPIO26;
+
+	GAFR |= GPIO_32_768kHz;
+	GPDR |= GPIO_32_768kHz;
+	TUCR = TUCR_3_6864MHz;
+
+	SBI_SKCR = SKCR_PLL_BYPASS | SKCR_RDYEN | SKCR_OE_EN;
+	udelay(100);
+	SBI_SKCR = SKCR_PLL_BYPASS | SKCR_RCLKEN | SKCR_RDYEN | SKCR_OE_EN;
+
+	GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
+	GPDR |= GPIO_MBGNT;
+	GPDR &= ~GPIO_MBREQ;
+	TUCR |= TUCR_MR;
+
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+	SKPCR |= SKPCR_DCLKEN;
+
+	// Reset PCMCIA
+	PCCR = 0xFF;
+	mdelay(100);
+	PA_DDR = 0x00;
+	// PA_DWR = GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
+	// PA_DWR = GPIO_GPIO0 | GPIO_GPIO2 | GPIO_GPIO3;
+	PA_DWR = pa_dwr;
+	PCCR = ~(PCCR_S0_RST | PCCR_S1_RST);
+
+#ifdef CONFIG_USB_OHCI_SA1111
+	// Turn ON clock
+	SKPCR |= SKPCR_UCLKEN;
+	udelay(100);
+
+	// force a RESET
+	USB_RESET = 0x01;
+	USB_RESET |= 0x02;
+	udelay(100);
+
+	// Set Power Sense and Control Line
+	USB_RESET = 0;
+	USB_RESET = USB_RESET_PWRSENSELOW;
+	USB_STATUS = 0;
+	udelay(10);
+#endif
+}
+
+
+static struct map_desc adsbitsyplus_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xf0000000, 0x3C000000, 0x00004000, DOMAIN_IO, 0, 1, 0, 0 }, /* 91C1111 */
+  { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA1111 */
+  { 0xf1000000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD Controller */
+  LAST_DESC
+};
+
+/* Use this to see when all uarts are shutdown.  Or all are closed.
+ * We can only turn off RS232 chip if either of these are true.
+ */
+
+static int uart_wake_count[3] = {1, 1, 1};
+
+enum {UART_SHUTDOWN, UART_WAKEUP};
+
+static void update_uart_counts(int line, int state)
+{
+	switch (state) {
+	case UART_WAKEUP:
+		uart_wake_count[line]++;
+		break;
+	case UART_SHUTDOWN:
+		uart_wake_count[line]--;
+		break;
+	}
+}
+
+static int adsbitsyplus_uart_open(struct uart_port *port, struct uart_info *info)
+{
+	if (port->mapbase == _Ser1UTCR0) {
+		Ser1SDCR0 |= SDCR0_UART;
+	} else if (port->mapbase == _Ser2UTCR0) {
+		Ser2UTCR4 = Ser2HSCR0 = 0;
+	}
+	return 0;
+}
+
+void adsbitsyplus_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+	// state has ACPI D0-D3
+	// ACPI D0 	  : resume from suspend
+	// ACPI D1-D3 : enter to a suspend state
+	if (port->mapbase == _Ser1UTCR0) {
+		if (state) {
+			update_uart_counts(1, UART_SHUTDOWN);
+                        // disable uart
+                        Ser1UTCR3 = 0;
+		}
+		else {
+			update_uart_counts(1, UART_WAKEUP);
+		}
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
+		if (state) {
+			update_uart_counts(2, UART_SHUTDOWN);
+                        // disable uart
+                        Ser2UTCR3 = 0;
+                        Ser2HSCR0 = 0;
+		}
+		else {
+			update_uart_counts(2, UART_WAKEUP);
+		}
+	}
+	else if (port->mapbase == _Ser3UTCR0) {
+		if (state) {
+			update_uart_counts(0, UART_SHUTDOWN);
+                        // disable uart
+                        Ser3UTCR3 = 0;
+		}
+		else {
+			update_uart_counts(0, UART_WAKEUP);
+		}
+	}
+        if (state == 0) {
+		// Turn power on if uarts are awake
+		if (uart_wake_count[0] + uart_wake_count[1] != 0) {
+			// make sure RS-232 is turned on if 1 or 3 are open
+			ADS_CPLD_PCON |= ADS_PCON_COM1_3_ON;
+		}
+		if (uart_wake_count[2] != 0) {
+			if (adsbitsyplus_connector_board_rev() >= 0x0a)
+				ADS_CPLD_PCON |= ADS_PCON_CONN_B_PE2;
+		}
+	}
+	else {
+		// Turn power off if uarts are asleep
+		if (uart_wake_count[0] + uart_wake_count[1] == 0) {
+			// save power if we are sleeping
+			ADS_CPLD_PCON &= ~ADS_PCON_COM1_3_ON;
+			GAFR &= ~(GPIO_GPIO15 | GPIO_GPIO19 | GPIO_GPIO20);
+			GPDR |= GPIO_GPIO15 | GPIO_GPIO19 | GPIO_GPIO20;
+		}
+		if (uart_wake_count[2] == 0) {
+			if (adsbitsyplus_connector_board_rev() >= 0x0a)
+				ADS_CPLD_PCON &= ~ADS_PCON_CONN_B_PE2;
+		}
+	}
+}
+
+static void adsbitsyplus_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	// note: only ports 1 and 3 have modem control
+	if (port->mapbase == _Ser1UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			// Set RTS High
+			GPCR = GPIO_GPIO15;
+		else
+			// Set RTS LOW
+			GPSR = GPIO_GPIO15;
+		if (mctrl & TIOCM_DTR)
+			// Set DTR High
+			GPCR = GPIO_GPIO20;
+		else
+			// Set DTR Low
+			GPSR = GPIO_GPIO20;
+	} else if (port->mapbase == _Ser3UTCR0) {
+		if (mctrl & TIOCM_RTS)
+			// Set RTS High
+			GPCR = GPIO_GPIO19;
+		else
+			// Set RTS LOW
+			GPSR = GPIO_GPIO19;
+	}
+}
+
+static u_int adsbitsyplus_get_mctrl(struct uart_port *port)
+{
+	u_int ret = 0;
+
+	// note: only ports 1 and 3 have modem control
+	if (port->mapbase == _Ser1UTCR0) {
+		if (!(GPLR & GPIO_GPIO14))
+			ret |= TIOCM_CTS;
+		if (!(GPLR & GPIO_GPIO24))
+			ret |= TIOCM_DSR;
+		if (!(GPLR & GPIO_GPIO16))
+			ret |= TIOCM_RI;
+		if (!(GPLR & GPIO_GPIO17))
+			ret |= TIOCM_CD;
+	} else if (port->mapbase == _Ser3UTCR0) {
+		if (!(GPLR & GPIO_GPIO18))
+			ret |= TIOCM_CTS;
+	}
+
+	return ret;
+}
+
+static struct sa1100_port_fns adsbitsyplus_port_fns __initdata = {
+	.set_mctrl =    adsbitsyplus_set_mctrl,
+	.get_mctrl =    adsbitsyplus_get_mctrl,
+	.open =	        adsbitsyplus_uart_open,
+	.pm =           adsbitsyplus_uart_pm,
+};
+
+static void __init adsbitsyplus_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(adsbitsyplus_io_desc);
+
+	sa1100_register_uart_fns(&adsbitsyplus_port_fns);
+	sa1100_register_uart(0, 3);
+	sa1100_register_uart(1, 1);
+
+	// don't register if you want to use IRDA
+#ifndef CONFIG_SA1100_FIR
+	sa1100_register_uart(2, 2);
+#endif
+
+	// COM1 Set RTS and DTR Output
+	GPDR |= GPIO_GPIO15 | GPIO_GPIO20;
+	// Set CTS, DSR, RI and CD Input
+	GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO24 | GPIO_GPIO16 | GPIO_GPIO17);
+
+	// COM3 Set RTS Output
+	GPDR |= GPIO_GPIO19;
+	// Set CTS Input
+	GPDR &= ~GPIO_GPIO18;
+}
+
+__setup("adsbitsyplus_conn_board_rev=", adsbitsyplus_connector_board_rev_setup);
+
+MACHINE_START(ADSBITSYPLUS, "ADS Bitsy Plus")
+        BOOT_PARAMS(0xc000003c)
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	MAPIO(adsbitsyplus_map_io)
+	INITIRQ(adsbitsyplus_init_irq)
+MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/assabet.c linux-2.4.22-pre10/arch/arm/mach-sa1100/assabet.c
--- linux-2.4.21/arch/arm/mach-sa1100/assabet.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/assabet.c	2003-08-01 13:30:37.000000000 +0000
@@ -42,7 +42,8 @@
 	 ASSABET_BCR_LED_GREEN  | ASSABET_BCR_LED_RED   | \
 	 ASSABET_BCR_RS232EN    | ASSABET_BCR_LCD_12RGB | \
 	 ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \
-	 ASSABET_BCR_IRDA_MD0   | ASSABET_BCR_CF_RST)
+	 ASSABET_BCR_IRDA_MD0   | ASSABET_BCR_CF_RST	| \
+	 ASSABET_BCR_CODEC_RST  )
 
 unsigned long SCR_value = ASSABET_SCR_INIT;
 EXPORT_SYMBOL(SCR_value);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/cep.c linux-2.4.22-pre10/arch/arm/mach-sa1100/cep.c
--- linux-2.4.21/arch/arm/mach-sa1100/cep.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/cep.c	2003-08-01 13:35:06.000000000 +0000
@@ -0,0 +1,123 @@
+/*
+ * linux/arch/arm/mach-sa1100/cep.c
+ *
+ * Author: Matthias Gorjup
+ *
+ * This file contains all Cep - specific tweaks.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/serial_core.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include "generic.h"
+
+
+extern void convert_to_tag_list(struct param_struct *params, int mem_init);
+
+static void __init
+fixup_cep(struct machine_desc *desc, struct param_struct *params,
+	      char **cmdline, struct meminfo *mi)
+{
+	struct tag *t = (struct tag *)params;
+
+
+	/*
+	 * Apparantly bootldr uses a param_struct.  Groan.
+	 */
+	if (t->hdr.tag != ATAG_CORE)
+		convert_to_tag_list(params, 1);
+
+	if (t->hdr.tag != ATAG_CORE) {
+		t->hdr.tag = ATAG_CORE;
+		t->hdr.size = tag_size(tag_core);
+		t->u.core.flags = 0;
+		t->u.core.pagesize = PAGE_SIZE;
+		t->u.core.rootdev = RAMDISK_MAJOR << 8 | 0;
+		t = tag_next(t);
+
+		t->hdr.tag = ATAG_MEM;
+		t->hdr.size = tag_size(tag_mem32);
+		t->u.mem.start = 0xc0000000;
+		t->u.mem.size  = 32 * 1024 * 1024;
+		t = tag_next(t);
+
+
+		t->hdr.tag = ATAG_RAMDISK;
+		t->hdr.size = tag_size(tag_ramdisk);
+		t->u.ramdisk.flags = 1;
+		t->u.ramdisk.size = 8192;
+		t->u.ramdisk.start = 0;
+		t = tag_next(t);
+
+		t->hdr.tag = ATAG_INITRD;
+		t->hdr.size = tag_size(tag_initrd);
+		t->u.initrd.start = 0xc0800000;
+		t->u.initrd.size = 3 * 1024 * 1024;
+		t = tag_next(t);
+
+		t->hdr.tag = ATAG_NONE;
+		t->hdr.size = 0;
+	}
+}
+
+
+static struct map_desc cep_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  LAST_DESC
+};
+
+static void __init cep_map_io(void)
+{
+
+	sa1100_map_io();
+	iotable_init(cep_io_desc);
+
+	sa1100_register_uart(0, 1);	/* com port */
+	sa1100_register_uart(2, 3);	/* radio module */
+
+	/*
+	 * Ensure that these pins are set as outputs and are driving
+	 * logic 0.  This ensures that we won't inadvertently toggle
+	 * the WS latch in the CPLD, and we don't float causing
+	 * excessive power drain.  --rmk
+	 */
+	GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+	GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+
+	/*
+	 * Set up registers for sleep mode.
+	 */
+	PWER = PWER_GPIO0;
+	PGSR = 0;
+	PCFR = 0;
+	PSDR = 0;
+}
+
+
+MACHINE_START(CEP, "Iskratel Cep")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_cep)
+	MAPIO(cep_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/cpu-sa1110.c linux-2.4.22-pre10/arch/arm/mach-sa1100/cpu-sa1110.c
--- linux-2.4.21/arch/arm/mach-sa1100/cpu-sa1110.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/cpu-sa1110.c	2003-08-01 13:30:40.000000000 +0000
@@ -49,33 +49,33 @@
 };
 
 static struct sdram_params tc59sm716_cl2_params __initdata = {
-	rows:		    12,
-	tck:		    10,
-	trcd:		    20,
-	trp:		    20,
-	twr:		    10,
-	refresh:	 64000,
-	cas_latency:	     2,
+	.rows		=    12,
+	.tck		=    10,
+	.trcd		=    20,
+	.trp		=    20,
+	.twr		=    10,
+	.refresh	= 64000,
+	.cas_latency	=     2,
 };
 
 static struct sdram_params tc59sm716_cl3_params __initdata = {
-	rows:		    12,
-	tck:		     8,
-	trcd:		    20,
-	trp:		    20,
-	twr:		     8,
-	refresh:	 64000,
-	cas_latency:	     3,
+	.rows		=    12,
+	.tck		=     8,
+	.trcd		=    20,
+	.trp		=    20,
+	.twr		=     8,
+	.refresh	= 64000,
+	.cas_latency	=     3,
 };
 
 static struct sdram_params samsung_k4s641632d_tc75 __initdata = {
-	rows:		    14,
-	tck:		     9,
-	trcd:		    27,
-	trp:		    20,
-	twr:		     9,
-	refresh:	 64000,
-	cas_latency:	     3,
+	.rows		=    14,
+	.tck		=     9,
+	.trcd		=    27,
+	.trp		=    20,
+	.twr		=     9,
+	.refresh	= 64000,
+	.cas_latency	=     3,
 };
 
 static struct sdram_params sdram_params;
@@ -235,21 +235,21 @@
 	 * the programming.
 	 */
 	local_irq_save(flags);
-	asm("mcr p15, 0, %0, c10, c4" : : "r" (0));
+	asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
 	udelay(10);
-	__asm__ __volatile__("
-		b	2f
-		.align	5
-1:		str	%3, [%1, #0]		@ MDCNFG
-		str	%4, [%1, #28]		@ MDREFR
-		str	%5, [%1, #4]		@ MDCAS0
-		str	%6, [%1, #8]		@ MDCAS1
-		str	%7, [%1, #12]		@ MDCAS2
-		str	%8, [%2, #0]		@ PPCR
-		ldr	%0, [%1, #0]
-		b	3f
-2:		b	1b
-3:		nop
+	__asm__ __volatile__("					\n\
+		b	2f					\n\
+		.align	5					\n\
+1:		str	%3, [%1, #0]		@ MDCNFG	\n\
+		str	%4, [%1, #28]		@ MDREFR	\n\
+		str	%5, [%1, #4]		@ MDCAS0	\n\
+		str	%6, [%1, #8]		@ MDCAS1	\n\
+		str	%7, [%1, #12]		@ MDCAS2	\n\
+		str	%8, [%2, #0]		@ PPCR		\n\
+		ldr	%0, [%1, #0]				\n\
+		b	3f					\n\
+2:		b	1b					\n\
+3:		nop						\n\
 		nop"
 		: "=&r" (unused)
 		: "r" (&MDCNFG), "r" (&PPCR), "0" (sd.mdcnfg),
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/dma-sa1100.c linux-2.4.22-pre10/arch/arm/mach-sa1100/dma-sa1100.c
--- linux-2.4.21/arch/arm/mach-sa1100/dma-sa1100.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/dma-sa1100.c	2003-08-01 13:31:28.000000000 +0000
@@ -477,11 +477,11 @@
 		return sa1111_dma_resume(channel);
 
 	if (dma->stopped) {
-		int flags;
-		save_flags_cli(flags);
+		unsigned long flags;
+		local_irq_save(flags);
 		dma->stopped = 0;
 		process_dma(dma);
-		restore_flags(flags);
+		local_irq_restore(flags);
 	}
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/dma-sa1111.c linux-2.4.22-pre10/arch/arm/mach-sa1100/dma-sa1111.c
--- linux-2.4.21/arch/arm/mach-sa1100/dma-sa1111.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/dma-sa1111.c	2003-08-01 13:31:23.000000000 +0000
@@ -305,7 +305,8 @@
 	 * SDRAM bank 1 on Neponset). The default configuration selects
 	 * Assabet, so any address in bank 1 is necessarily invalid.
 	 */
-	if((machine_is_assabet() || machine_is_pfs168()) && addr >= 0xc8000000)
+	if((machine_is_assabet() || machine_is_pfs168() ||
+            machine_is_graphicsmaster() || machine_is_adsagc()) && addr >= 0xc8000000)
 	  	return -1;
 
 	/* The bug only applies to buffers located more than one megabyte
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/flexanet.c linux-2.4.22-pre10/arch/arm/mach-sa1100/flexanet.c
--- linux-2.4.21/arch/arm/mach-sa1100/flexanet.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/flexanet.c	2003-08-01 13:32:51.000000000 +0000
@@ -26,6 +26,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/serial_sa1100.h>
 #include <linux/serial_core.h>
+#include <asm/arch/flexanet.h>
 
 #include "generic.h"
 
@@ -145,6 +146,11 @@
 
 static int __init flexanet_init(void)
 {
+	/* Set IRQ edges */
+	set_GPIO_IRQ_edge(GPIO_GUI_IRQ, GPIO_RISING_EDGE);
+
+	/* deassert the GUI reset */
+	FLEXANET_BCR_set(FHH_BCR_GUI_NRST);
 	return 0;
 }
 
@@ -155,10 +161,6 @@
 fixup_flexanet(struct machine_desc *desc, struct param_struct *params,
 	      char **cmdline, struct meminfo *mi)
 {
-	int				status;
-	unsigned long	now;
-
-
 	/* fixed RAM size, by now (64MB) */
 	SET_BANK( 0, 0xc0000000, 64*1024*1024 );
 	mi->nr_banks = 1;
@@ -175,7 +177,7 @@
   { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
   { 0xf0000000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* Board Control Register */
   { 0xf1000000, 0x18000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Ethernet controller */
-  { 0xD0000000, 0x40000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Instrument boards */
+  { 0xD0000000, 0x40000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Instrument boards */
   { 0xD8000000, 0x48000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* External peripherals */
   LAST_DESC
 };
@@ -198,13 +200,6 @@
 	 */
 	PCFR = PCFR_OPDE | PCFR_FP | PCFR_FS;
 
-	/* deassert the GUI reset */
-	FLEXANET_BCR_set(FHH_BCR_GUI_NRST);
-
-	/*
-	 * Set IRQ edges
-	 */
-	set_GPIO_IRQ_edge(GPIO_GUI_IRQ, GPIO_RISING_EDGE);
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/frodo.c linux-2.4.22-pre10/arch/arm/mach-sa1100/frodo.c
--- linux-2.4.21/arch/arm/mach-sa1100/frodo.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/frodo.c	2003-08-01 13:34:40.000000000 +0000
@@ -12,15 +12,22 @@
  *
  * History:
  *
+ *   2002/05/27   Setup GPIOs for all the onboard peripherals so
+ *                that we don't have to do it in each driver
+ *
  *   2002/01/31   Initial version
  */
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/tty.h>
+#include <linux/spinlock.h>
 
-#include <asm/hardware.h>
 #include <asm/setup.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -28,30 +35,108 @@
 
 #include "generic.h"
 
-static struct map_desc frodo_io_desc[] __initdata =
-{
-  /* virtual     physical    length      domain     r  w  c  b */
-   { 0xe8000000, 0x00000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 },	/* flash memory */
-   { 0xf0000000, 0x40000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 },	/* 16-bit on-board devices (including CPLDs) */
-   { 0xf1000000, 0x18000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 },	/* 32-bit daughter card */
-   LAST_DESC
+static struct map_desc frodo_io_desc[] __initdata = {
+	/* virtual     physical    length      domain     r  w  c  b */
+	{ 0xe8000000, 0x00000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 },	/* flash memory */
+	{ 0xf0000000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 },	/* 16-bit on-board devices (including CPLDs) */
+	{ 0xf1000000, 0x18000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 },	/* 32-bit daughter card */
+	LAST_DESC
 };
 
+static spinlock_t frodo_cpld_lock = SPIN_LOCK_UNLOCKED;
+static volatile u16 *frodo_cpld_memory = (u16 *) 0xf0000000;
+
 static void __init frodo_map_io (void)
 {
-   sa1100_map_io ();
-   iotable_init (frodo_io_desc);
+	sa1100_map_io ();
+	iotable_init (frodo_io_desc);
+
+	sa1100_register_uart (0,2);		/* UART2 (serial console) */
+	sa1100_register_uart (1,1);		/* UART1 (big kahuna flow control serial port) */
+
+	/*
+	 * Set SUS bit in SDCR0 so serial port 1 acts as a UART.
+	 * See Intel SA-1110 Developers Manual Section 11.9.2.1 (GPCLK/UART Select)
+	 */
+	Ser1SDCR0 |= SDCR0_SUS;
+}
+
+static int __init frodo_init_irq(void)
+{
+	int i,gpio[] = {
+		FRODO_IDE_GPIO,
+		FRODO_ETH_GPIO,
+		FRODO_USB_DC_GPIO,
+		FRODO_USB_HC_GPIO,
+		FRODO_RTC_GPIO,
+		FRODO_UART1_GPIO,
+		FRODO_UART2_GPIO,
+		FRODO_PCMCIA_STATUS_GPIO,
+		FRODO_PCMCIA_RDYBSY_GPIO
+	};
+
+	for (i = 0; i < sizeof (gpio) / sizeof (gpio[0]); i++)
+		set_GPIO_IRQ_edge (gpio[i],GPIO_RISING_EDGE);
+
+	return (0);
+}
+
+__initcall(frodo_init_irq);
+#if 0
+static int __init frodo_init_cpld(void)
+{
+	if ((frodo_cpld_memory = ioremap (FRODO_CPLD_BASE,FRODO_CPLD_LENGTH)) == NULL)
+		panic ("Couldn't map CPLD memory to a virtual address. We're screwed!\n");
+
+	return (0);
+}
+
+__initcall(frodo_init_cpld);
+#endif
+u16 frodo_cpld_read (u32 reg)
+{
+	unsigned long flags;
+	u16 value;
+
+	spin_lock_irqsave (&frodo_cpld_lock,flags);
+	value = frodo_cpld_memory[reg / 2];
+	spin_unlock_irqrestore (&frodo_cpld_lock,flags);
+
+	return (value);
+}
+
+void frodo_cpld_write (u32 reg,u16 value)
+{
+	unsigned long flags;
 
-   sa1100_register_uart (0,2);	/* UART2 (serial console) */
-   sa1100_register_uart (1,1);	/* UART1 (big kahuna flow control serial port) */
+	spin_lock_irqsave (&frodo_cpld_lock,flags);
+	frodo_cpld_memory[reg / 2] = value;
+	spin_unlock_irqrestore (&frodo_cpld_lock,flags);
+}
+
+void frodo_cpld_set (u32 reg,u16 mask)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave (&frodo_cpld_lock,flags);
+	frodo_cpld_memory[reg / 2] |= mask;
+	spin_unlock_irqrestore (&frodo_cpld_lock,flags);
+}
+
+void frodo_cpld_clear (u32 reg,u16 mask)
+{
+	unsigned long flags;
 
-   /*
-	* Set SUS bit in SDCR0 so serial port 1 acts as a UART.
-	* See Intel SA-1110 Developers Manual Section 11.9.2.1 (GPCLK/UART Select)
-	*/
-   Ser1SDCR0 |= SDCR0_SUS;
+	spin_lock_irqsave (&frodo_cpld_lock,flags);
+	frodo_cpld_memory[reg / 2] &= ~mask;
+	spin_unlock_irqrestore (&frodo_cpld_lock,flags);
 }
 
+EXPORT_SYMBOL (frodo_cpld_read);
+EXPORT_SYMBOL (frodo_cpld_write);
+EXPORT_SYMBOL (frodo_cpld_set);
+EXPORT_SYMBOL (frodo_cpld_clear);
+
 MACHINE_START (FRODO,"2d3D, Inc. SA-1110 Development Board")
 	BOOT_MEM (0xc0000000,0x80000000,0xf8000000)
 	BOOT_PARAMS (0xc0000100)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/generic.c linux-2.4.22-pre10/arch/arm/mach-sa1100/generic.c
--- linux-2.4.21/arch/arm/mach-sa1100/generic.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/generic.c	2003-08-01 13:32:04.000000000 +0000
@@ -86,7 +86,7 @@
 
 static int __init sa11x0_init_clock(void)
 {
-	cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100, 0, 0);
+	cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100, 59000, 287000);
 	return 0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/graphicsclient.c linux-2.4.22-pre10/arch/arm/mach-sa1100/graphicsclient.c
--- linux-2.4.21/arch/arm/mach-sa1100/graphicsclient.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/graphicsclient.c	2003-08-01 13:34:43.000000000 +0000
@@ -14,6 +14,8 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/setup.h>
@@ -34,55 +36,58 @@
  * Handlers for GraphicsClient's external IRQ logic
  */
 
+#define GRAPHICSCLIENT_N_IRQ     (IRQ_GRAPHICSCLIENT_END - IRQ_GRAPHICSCLIENT_START)
+#define GRAPHICSCLIENT_FIRST_IRQ (IRQ_GRAPHICSCLIENT_CAN - IRQ_GRAPHICSCLIENT_START)
+
 static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
 {
 	int i;
 
 	while( (irq = ADS_INT_ST1 | (ADS_INT_ST2 << 8)) ){
-		for( i = 0; i < 16; i++ )
+		for( i = GRAPHICSCLIENT_FIRST_IRQ; i < GRAPHICSCLIENT_N_IRQ; i++ )
 			if( irq & (1<<i) )
-				do_IRQ( ADS_EXT_IRQ(i), regs );
+				do_IRQ( IRQ_GRAPHICSCLIENT_START + i, regs );
 	}
 }
 
 static struct irqaction ADS_ext_irq = {
-	name:		"ADS_ext_IRQ",
-	handler:	ADS_IRQ_demux,
-	flags:		SA_INTERRUPT
+	.name		= "ADS_ext_IRQ",
+	.handler	= ADS_IRQ_demux,
+	.flags		= SA_INTERRUPT
 };
 
 static void ADS_mask_and_ack_irq0(unsigned int irq)
 {
-	int mask = (1 << (irq - ADS_EXT_IRQ(0)));
+	int mask = (1 << (irq - IRQ_GRAPHICSCLIENT_START));
 	ADS_INT_EN1 &= ~mask;
 	ADS_INT_ST1 = mask;
 }
 
 static void ADS_mask_irq0(unsigned int irq)
 {
-	ADS_INT_ST1 = (1 << (irq - ADS_EXT_IRQ(0)));
+	ADS_INT_ST1 = (1 << (irq - IRQ_GRAPHICSCLIENT_START));
 }
 
 static void ADS_unmask_irq0(unsigned int irq)
 {
-	ADS_INT_EN1 |= (1 << (irq - ADS_EXT_IRQ(0)));
+	ADS_INT_EN1 |= (1 << (irq - IRQ_GRAPHICSCLIENT_START));
 }
 
 static void ADS_mask_and_ack_irq1(unsigned int irq)
 {
-	int mask = (1 << (irq - ADS_EXT_IRQ(8)));
+	int mask = (1 << (irq - (IRQ_GRAPHICSCLIENT_UCB1200)));
 	ADS_INT_EN2 &= ~mask;
 	ADS_INT_ST2 = mask;
 }
 
 static void ADS_mask_irq1(unsigned int irq)
 {
-	ADS_INT_ST2 = (1 << (irq - ADS_EXT_IRQ(8)));
+	ADS_INT_ST2 = (1 << (irq - (IRQ_GRAPHICSCLIENT_UCB1200)));
 }
 
 static void ADS_unmask_irq1(unsigned int irq)
 {
-	ADS_INT_EN2 |= (1 << (irq - ADS_EXT_IRQ(8)));
+	ADS_INT_EN2 |= (1 << (irq - (IRQ_GRAPHICSCLIENT_UCB1200)));
 }
 
 static void __init graphicsclient_init_irq(void)
@@ -99,14 +104,17 @@
 	ADS_INT_ST1 = 0xff;
 	ADS_INT_ST2 = 0xff;
 
-	for (irq = ADS_EXT_IRQ(0); irq <= ADS_EXT_IRQ(7); irq++) {
+	// Set RTS low during sleep
+	PGSR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
+
+	for (irq = IRQ_GRAPHICSCLIENT_START; irq < IRQ_GRAPHICSCLIENT_UCB1200; irq++) {
 		irq_desc[irq].valid	= 1;
 		irq_desc[irq].probe_ok	= 1;
 		irq_desc[irq].mask_ack	= ADS_mask_and_ack_irq0;
 		irq_desc[irq].mask	= ADS_mask_irq0;
 		irq_desc[irq].unmask	= ADS_unmask_irq0;
 	}
-	for (irq = ADS_EXT_IRQ(8); irq <= ADS_EXT_IRQ(15); irq++) {
+	for (irq = IRQ_GRAPHICSCLIENT_UCB1200; irq < IRQ_GRAPHICSCLIENT_END; irq++) {
 		irq_desc[irq].valid	= 1;
 		irq_desc[irq].probe_ok	= 1;
 		irq_desc[irq].mask_ack	= ADS_mask_and_ack_irq1;
@@ -117,24 +125,6 @@
 	setup_arm_irq( IRQ_GPIO0, &ADS_ext_irq );
 }
 
-
-/*
- * Initialization fixup
- */
-
-static void __init
-fixup_graphicsclient(struct machine_desc *desc, struct param_struct *params,
-		     char **cmdline, struct meminfo *mi)
-{
-	SET_BANK( 0, 0xc0000000, 16*1024*1024 );
-	SET_BANK( 1, 0xc8000000, 16*1024*1024 );
-	mi->nr_banks = 2;
-
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-	setup_ramdisk( 1, 0, 0, 8192 );
-	setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
-}
-
 static struct map_desc graphicsclient_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
   { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
@@ -143,120 +133,31 @@
   LAST_DESC
 };
 
-static struct gc_uart_ctrl_data_t gc_uart_ctrl_data[] = {
-  { GPIO_GC_UART0_CTS, 0, NULL,NULL },
-  { GPIO_GC_UART1_CTS, 0, NULL,NULL },
-  { GPIO_GC_UART2_CTS, 0, NULL,NULL }
-};
-
-static void
-graphicsclient_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct gc_uart_ctrl_data_t * uart_data = (struct gc_uart_ctrl_data_t *)dev_id;
-	int cts = !(GPLR & uart_data->cts_gpio);
-
-	/* NOTE: I supose that we will no get any interrupt
-	   if the GPIO is not changed, so maybe
-	   the cts_prev_state can be removed ... */
-	if (cts != uart_data->cts_prev_state) {
-		uart_data->cts_prev_state = cts;
-
-		uart_handle_cts_change(uart_data->info, cts);
-	}
-}
-
-static int
-graphicsclient_register_cts_intr(int gpio, int irq,
-				 struct gc_uart_ctrl_data_t *uart_data)
-{
-	int ret = 0;
-
-	set_GPIO_IRQ_edge(gpio, GPIO_BOTH_EDGES);
-
-	ret = request_irq(irq, graphicsclient_cts_intr,
-			  0, "GC RS232 CTS", uart_data);
-	if (ret) {
-		printk(KERN_ERR "uart_open: failed to register CTS irq (%d)\n",
-		       ret);
-		free_irq(irq, uart_data);
-	}
-
-	return ret;
-}
-
-static int
-graphicsclient_uart_open(struct uart_port *port, struct uart_info *info)
+static int graphicsclient_uart_open(struct uart_port *port, struct uart_info *info)
 {
-	int ret = 0;
+	int	ret = 0;
 
 	if (port->mapbase == _Ser1UTCR0) {
 		Ser1SDCR0 |= SDCR0_UART;
-		/* Set RTS Output */
-		GPSR  = GPIO_GC_UART0_RTS;
-
-		gc_uart_ctrl_data[0].cts_prev_state = 0;
-		gc_uart_ctrl_data[0].info = info;
-		gc_uart_ctrl_data[0].port = port;
-
-		/* register uart0 CTS irq */
-		ret = graphicsclient_register_cts_intr(GPIO_GC_UART0_CTS,
-							IRQ_GC_UART0_CTS,
-							&gc_uart_ctrl_data[0]);
-	} else if (port->mapbase == _Ser2UTCR0) {
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
 		Ser2UTCR4 = Ser2HSCR0 = 0;
-		/* Set RTS Output */
-		GPSR  = GPIO_GC_UART1_RTS;
-
-		gc_uart_ctrl_data[1].cts_prev_state = 0;
-		gc_uart_ctrl_data[1].info = info;
-		gc_uart_ctrl_data[1].port = port;
-
-		/* register uart1 CTS irq */
-		ret = graphicsclient_register_cts_intr(GPIO_GC_UART1_CTS,
-							IRQ_GC_UART1_CTS,
-							&gc_uart_ctrl_data[1]);
-	} else if (port->mapbase == _Ser3UTCR0) {
-		/* Set RTS Output */
-		GPSR =	GPIO_GC_UART2_RTS;
-
-		gc_uart_ctrl_data[2].cts_prev_state = 0;
-		gc_uart_ctrl_data[2].info = info;
-		gc_uart_ctrl_data[2].port = port;
-
-		/* register uart2 CTS irq */
-		ret = graphicsclient_register_cts_intr(GPIO_GC_UART2_CTS,
-							IRQ_GC_UART2_CTS,
-							&gc_uart_ctrl_data[2]);
 	}
 	return ret;
 }
 
-static int
-graphicsclient_uart_close(struct uart_port *port, struct uart_info *info)
-{
-	if (port->mapbase == _Ser1UTCR0) {
-		free_irq(IRQ_GC_UART0_CTS, &gc_uart_ctrl_data[0]);
-	} else if (port->mapbase == _Ser2UTCR0) {
-		free_irq(IRQ_GC_UART1_CTS, &gc_uart_ctrl_data[1]);
-	} else if (port->mapbase == _Ser3UTCR0) {
-		free_irq(IRQ_GC_UART2_CTS, &gc_uart_ctrl_data[2]);
-	}
-
-	return 0;
-}
-
 static u_int graphicsclient_get_mctrl(struct uart_port *port)
 {
 	u_int result = TIOCM_CD | TIOCM_DSR;
 
 	if (port->mapbase == _Ser1UTCR0) {
-		if (!(GPLR & GPIO_GC_UART0_CTS))
+		if (!(GPLR & GPIO_GPIO14))
 			result |= TIOCM_CTS;
 	} else if (port->mapbase == _Ser2UTCR0) {
-		if (!(GPLR & GPIO_GC_UART1_CTS))
+		if (!(GPLR & GPIO_GPIO16))
 			result |= TIOCM_CTS;
 	} else if (port->mapbase == _Ser3UTCR0) {
-		if (!(GPLR & GPIO_GC_UART2_CTS))
+		if (!(GPLR & GPIO_GPIO18))
 			result |= TIOCM_CTS;
 	} else {
 		result = TIOCM_CTS;
@@ -269,39 +170,54 @@
 {
 	if (port->mapbase == _Ser1UTCR0) {
 		if (mctrl & TIOCM_RTS)
-			GPCR = GPIO_GC_UART0_RTS;
+			GPCR = GPIO_GPIO15;
 		else
-			GPSR = GPIO_GC_UART0_RTS;
+			GPSR = GPIO_GPIO15;
 	} else if (port->mapbase == _Ser2UTCR0) {
 		if (mctrl & TIOCM_RTS)
-			GPCR = GPIO_GC_UART1_RTS;
+			GPCR = GPIO_GPIO17;
 		else
-			GPSR = GPIO_GC_UART1_RTS;
+			GPSR = GPIO_GPIO17;
 	} else if (port->mapbase == _Ser3UTCR0) {
 		if (mctrl & TIOCM_RTS)
-			GPCR = GPIO_GC_UART2_RTS;
+			GPCR = GPIO_GPIO19;
 		else
-			GPSR = GPIO_GC_UART2_RTS;
+			GPSR = GPIO_GPIO19;
 	}
 }
 
 static void
 graphicsclient_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 {
-	if (!state) {
-		/* make serial ports work ... */
-		Ser2UTCR4 = 0;
-		Ser2HSCR0 = 0; 
-		Ser1SDCR0 |= SDCR0_UART;
+	// state has ACPI D0-D3
+	// ACPI D0 	  : resume from suspend
+	// ACPI D1-D3 : enter to a suspend state
+	if (port->mapbase == _Ser1UTCR0) {
+		if (state) {
+                        // disable uart
+                        Ser1UTCR3 = 0;
+		}
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
+		if (state) {
+                        // disable uart
+                        Ser2UTCR3 = 0;
+                        Ser2HSCR0 = 0;
+		}
+	}
+	else if (port->mapbase == _Ser3UTCR0) {
+		if (state) {
+                        // disable uart
+                        Ser3UTCR3 = 0;
+		}
 	}
 }
 
 static struct sa1100_port_fns graphicsclient_port_fns __initdata = {
-	open:		graphicsclient_uart_open,
-	close:		graphicsclient_uart_close,
-	get_mctrl:	graphicsclient_get_mctrl,
-	set_mctrl:	graphicsclient_set_mctrl,
-	pm:		graphicsclient_uart_pm,
+	.open		= graphicsclient_uart_open,
+	.get_mctrl	= graphicsclient_get_mctrl,
+	.set_mctrl	= graphicsclient_set_mctrl,
+	.pm		= graphicsclient_uart_pm,
 };
 
 static void __init graphicsclient_map_io(void)
@@ -312,14 +228,20 @@
 	sa1100_register_uart_fns(&graphicsclient_port_fns);
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
+
+	// don't register if you want to use IRDA
+#ifndef CONFIG_SA1100_FIR
 	sa1100_register_uart(2, 2);
-	GPDR |= GPIO_GC_UART0_RTS | GPIO_GC_UART1_RTS | GPIO_GC_UART2_RTS;
-	GPDR &= ~(GPIO_GC_UART0_CTS | GPIO_GC_UART1_RTS | GPIO_GC_UART2_RTS);
+#endif
+
+	/* set GPDR now */
+	GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
+       	GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO16 | GPIO_GPIO18);
 }
 
 MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient")
+        BOOT_PARAMS(0xc000003c)
 	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	FIXUP(fixup_graphicsclient)
 	MAPIO(graphicsclient_map_io)
 	INITIRQ(graphicsclient_init_irq)
 MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/graphicsmaster.c linux-2.4.22-pre10/arch/arm/mach-sa1100/graphicsmaster.c
--- linux-2.4.21/arch/arm/mach-sa1100/graphicsmaster.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/graphicsmaster.c	2003-08-01 13:32:58.000000000 +0000
@@ -12,8 +12,13 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
+#include <linux/serial_core.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
+#include <asm/hardware/sa1111.h>
 #include <asm/setup.h>
 #include <asm/irq.h>
 
@@ -40,6 +45,15 @@
 	 */
 	sa1110_mb_disable();
 
+	/* GraphicsMaster uses GPIO pins for SPI interface to AVR
+	 */
+
+	/* use the alternate SSP pins */
+	PPAR |= PPAR_SSPGPIO;
+
+	// Set RTS low during sleep
+	PGSR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
+
 	/*
 	 * Probe for SA1111.
 	 */
@@ -67,9 +81,11 @@
 	 * Enable PWM control for LCD
 	 */
 	SKPCR |= SKPCR_PWMCLKEN;
-	SKPWM0 = 0x7F;				// VEE
+	SACR1 &= ~SACR1_L3EN;
+	ADS_DCR |= DCR_BACKLITE_ON;
+	SKPWM0 = 0x01;				// Backlight
 	SKPEN0 = 1;
-	SKPWM1 = 0x01;				// Backlight
+	SKPWM1 = 0x7F;				// VEE
 	SKPEN1 = 1;
 
 	/*
@@ -83,7 +99,7 @@
 	 */
 	sa1110_mb_enable();
 
-	sa1111_init_irq(ADS_EXT_IRQ(0));
+	sa1111_init_irq(IRQ_GRAPHICSMASTER_SA1111);
 
 	return 0;
 }
@@ -94,56 +110,58 @@
  * Handlers for GraphicsMaster's external IRQ logic
  */
 
+#define GRAPHICSMASTER_N_IRQ (IRQ_GRAPHICSMASTER_END - IRQ_GRAPHICSMASTER_START)
+
 static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
 {
 	int i;
 
 	while( (irq = ADS_INT_ST1 | (ADS_INT_ST2 << 8)) ){
-		for( i = 0; i < 16; i++ )
+		for( i = 0; i < GRAPHICSMASTER_N_IRQ; i++ )
 			if( irq & (1<<i) ) {
-				do_IRQ( ADS_EXT_IRQ(i), regs );
+				do_IRQ( IRQ_GRAPHICSMASTER_START + i, regs );
 			}
 	}
 }
 
 static struct irqaction ADS_ext_irq = {
-	name:		"ADS_ext_IRQ",
-	handler:	ADS_IRQ_demux,
-	flags:		SA_INTERRUPT
+	.name		= "ADS_ext_IRQ",
+	.handler	= ADS_IRQ_demux,
+	.flags		= SA_INTERRUPT
 };
 
 static void ADS_mask_and_ack_irq0(unsigned int irq)
 {
-	int mask = (1 << (irq - ADS_EXT_IRQ(0)));
+	int mask = (1 << (irq - IRQ_GRAPHICSMASTER_START));
 	ADS_INT_EN1 &= ~mask;
 	ADS_INT_ST1 = mask;
 }
 
 static void ADS_mask_irq0(unsigned int irq)
 {
-	ADS_INT_ST1 = (1 << (irq - ADS_EXT_IRQ(0)));
+	ADS_INT_ST1 = (1 << (irq - IRQ_GRAPHICSMASTER_START));
 }
 
 static void ADS_unmask_irq0(unsigned int irq)
 {
-	ADS_INT_EN1 |= (1 << (irq - ADS_EXT_IRQ(0)));
+	ADS_INT_EN1 |= (1 << (irq - IRQ_GRAPHICSMASTER_START));
 }
 
 static void ADS_mask_and_ack_irq1(unsigned int irq)
 {
-	int mask = (1 << (irq - ADS_EXT_IRQ(8)));
+	int mask = (1 << (irq - (IRQ_GRAPHICSMASTER_UCB1200)));
 	ADS_INT_EN2 &= ~mask;
 	ADS_INT_ST2 = mask;
 }
 
 static void ADS_mask_irq1(unsigned int irq)
 {
-	ADS_INT_ST2 = (1 << (irq - ADS_EXT_IRQ(8)));
+	ADS_INT_ST2 = (1 << (irq - (IRQ_GRAPHICSMASTER_UCB1200)));
 }
 
 static void ADS_unmask_irq1(unsigned int irq)
 {
-	ADS_INT_EN2 |= (1 << (irq - ADS_EXT_IRQ(8)));
+	ADS_INT_EN2 |= (1 << (irq - (IRQ_GRAPHICSMASTER_UCB1200)));
 }
 
 static void __init graphicsmaster_init_irq(void)
@@ -160,43 +178,27 @@
 	ADS_INT_ST1 = 0xff;
 	ADS_INT_ST2 = 0xff;
 
-	for (irq = ADS_EXT_IRQ(0); irq <= ADS_EXT_IRQ(7); irq++) {
+	for (irq = IRQ_GRAPHICSMASTER_START; irq < IRQ_GRAPHICSMASTER_UCB1200; irq++) {
 		irq_desc[irq].valid	= 1;
 		irq_desc[irq].probe_ok	= 1;
 		irq_desc[irq].mask_ack	= ADS_mask_and_ack_irq0;
 		irq_desc[irq].mask	= ADS_mask_irq0;
 		irq_desc[irq].unmask	= ADS_unmask_irq0;
 	}
-	for (irq = ADS_EXT_IRQ(8); irq <= ADS_EXT_IRQ(15); irq++) {
+	for (irq = IRQ_GRAPHICSMASTER_UCB1200; irq < IRQ_GRAPHICSMASTER_END; irq++) {
 		irq_desc[irq].valid	= 1;
 		irq_desc[irq].probe_ok	= 1;
 		irq_desc[irq].mask_ack	= ADS_mask_and_ack_irq1;
 		irq_desc[irq].mask	= ADS_mask_irq1;
 		irq_desc[irq].unmask	= ADS_unmask_irq1;
 	}
+
+	GPDR &= ~GPIO_GPIO0;
 	set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_FALLING_EDGE);
 	setup_arm_irq( IRQ_GPIO0, &ADS_ext_irq );
 }
 
 
-/*
- * Initialization fixup
- */
-
-static void __init
-fixup_graphicsmaster(struct machine_desc *desc, struct param_struct *params,
-		     char **cmdline, struct meminfo *mi)
-{
-	SET_BANK( 0, 0xc0000000, 16*1024*1024 );
-	mi->nr_banks = 1;
-	SET_BANK( 1, 0xc8000000, 16*1024*1024 );
-	mi->nr_banks = 2;
-
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-	setup_ramdisk( 1, 0, 0, 8192 );
-	setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
-}
-
 static struct map_desc graphicsmaster_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
   { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
@@ -212,17 +214,9 @@
 
 	if (port->mapbase == _Ser1UTCR0) {
 		Ser1SDCR0 |= SDCR0_UART;
-		/* Set RTS Output */
-		GPSR = GPIO_GPIO15;
 	}
 	else if (port->mapbase == _Ser2UTCR0) {
 		Ser2UTCR4 = Ser2HSCR0 = 0;
-		/* Set RTS Output */
-		GPSR = GPIO_GPIO17;
-	}
-	else if (port->mapbase == _Ser3UTCR0) {
-	        /* Set RTS Output */
-		GPSR = GPIO_GPIO19;
 	}
 	return ret;
 }
@@ -238,7 +232,7 @@
 		if (!(GPLR & GPIO_GPIO16))
 			result |= TIOCM_CTS;
 	} else if (port->mapbase == _Ser3UTCR0) {
-		if (!(GPLR & GPIO_GPIO17))
+		if (!(GPLR & GPIO_GPIO18))
 			result |= TIOCM_CTS;
 	} else {
 		result = TIOCM_CTS;
@@ -270,19 +264,35 @@
 static void
 graphicsmaster_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 {
-	if (!state) {
-		/* make serial ports work ... */
-		Ser2UTCR4 = 0;
-		Ser2HSCR0 = 0; 
-		Ser1SDCR0 |= SDCR0_UART;
+	// state has ACPI D0-D3
+	// ACPI D0 	  : resume from suspend
+	// ACPI D1-D3 : enter to a suspend state
+	if (port->mapbase == _Ser1UTCR0) {
+		if (state) {
+			// disable uart
+			Ser1UTCR3 = 0;
+		}
+	}
+	else if (port->mapbase == _Ser2UTCR0) {
+		if (state) {
+			// disable uart
+			Ser2UTCR3 = 0;
+			Ser2HSCR0 = 0;
+		}
+	}
+	else if (port->mapbase == _Ser3UTCR0) {
+		if (state) {
+			// disable uart
+			Ser3UTCR3 = 0;
+		}
 	}
 }
 
 static struct sa1100_port_fns graphicsmaster_port_fns __initdata = {
-	open:		graphicsmaster_uart_open,
-	get_mctrl:	graphicsmaster_get_mctrl,
-	set_mctrl:	graphicsmaster_set_mctrl,
-	pm:		graphicsmaster_uart_pm,
+	.open		= graphicsmaster_uart_open,
+	.get_mctrl	= graphicsmaster_get_mctrl,
+	.set_mctrl	= graphicsmaster_set_mctrl,
+	.pm		= graphicsmaster_uart_pm,
 };
 
 static void __init graphicsmaster_map_io(void)
@@ -293,7 +303,10 @@
 	sa1100_register_uart_fns(&graphicsmaster_port_fns);
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
+	// don't register if you want to use IRDA
+#ifndef CONFIG_SA1100_FIR
 	sa1100_register_uart(2, 2);
+#endif
 
 	/* set GPDR now */
 	GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
@@ -301,8 +314,8 @@
 }
 
 MACHINE_START(GRAPHICSMASTER, "ADS GraphicsMaster")
+	BOOT_PARAMS(0xc000003c)
 	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	FIXUP(fixup_graphicsmaster)
 	MAPIO(graphicsmaster_map_io)
 	INITIRQ(graphicsmaster_init_irq)
 MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/h3600.c linux-2.4.22-pre10/arch/arm/mach-sa1100/h3600.c
--- linux-2.4.21/arch/arm/mach-sa1100/h3600.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/h3600.c	2003-08-01 13:31:51.000000000 +0000
@@ -394,16 +394,16 @@
 
 static void h3600_dcd_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct uart_info *info = dev_id;
+	struct uart_port *port = dev_id;
 	/* Note: should only call this if something has changed */
-	uart_handle_dcd_change(info, !(GPLR & GPIO_H3600_COM_DCD));
+	uart_handle_dcd_change(port, !(GPLR & GPIO_H3600_COM_DCD));
 }
 
 static void h3600_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct uart_info *info = dev_id;
+	struct uart_port *port = dev_id;
 	/* Note: should only call this if something has changed */
-	uart_handle_cts_change(info, !(GPLR & GPIO_H3600_COM_CTS));
+	uart_handle_cts_change(port, !(GPLR & GPIO_H3600_COM_CTS));
 }
 
 static void h3600_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
@@ -433,7 +433,7 @@
 	return err;
 }
 
-static int h3600_uart_open(struct uart_port *port, struct uart_info *info)
+static int h3600_uart_open(struct uart_port *port)
 {
 	int ret = 0;
 
@@ -447,23 +447,23 @@
 				  GPIO_BOTH_EDGES);
 
 		ret = request_irq(IRQ_GPIO_H3600_COM_DCD, h3600_dcd_intr,
-				  0, "RS232 DCD", info);
+				  0, "RS232 DCD", port);
 		if (ret)
 			return ret;
 
 		ret = request_irq(IRQ_GPIO_H3600_COM_CTS, h3600_cts_intr,
-				  0, "RS232 CTS", info);
+				  0, "RS232 CTS", port);
 		if (ret)
-			free_irq(IRQ_GPIO_H3600_COM_DCD, info);
+			free_irq(IRQ_GPIO_H3600_COM_DCD, port);
 	}
 	return ret;
 }
 
-static void h3600_uart_close(struct uart_port *port, struct uart_info *info)
+static void h3600_uart_close(struct uart_port *port)
 {
 	if (port->mapbase == _Ser3UTCR0) {
-		free_irq(IRQ_GPIO_H3600_COM_DCD, info);
-		free_irq(IRQ_GPIO_H3600_COM_CTS, info);
+		free_irq(IRQ_GPIO_H3600_COM_DCD, port);
+		free_irq(IRQ_GPIO_H3600_COM_CTS, port);
 	}
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/hackkit.c linux-2.4.22-pre10/arch/arm/mach-sa1100/hackkit.c
--- linux-2.4.21/arch/arm/mach-sa1100/hackkit.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/hackkit.c	2003-08-01 13:34:18.000000000 +0000
@@ -0,0 +1,221 @@
+/*
+ * linux/arch/arm/mach-sa1100/hackkit.c
+ *
+ * Copyright (C) 2002 Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>
+ *
+ * This file contains all HackKit tweaks. Based on original work from
+ * Nicolas Pitre's assabet fixes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/cpufreq.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/arch/irq.h>
+
+#include <linux/serial_core.h>
+
+#include "generic.h"
+
+#define DEBUG 1
+
+#ifdef DEBUG
+#	define DPRINTK( x, args... )	printk( "%s: line %d: "x, __FUNCTION__, __LINE__, ## args  );
+#else
+#	define DPRINTK( x, args... )	/* nix */
+#endif
+
+/**********************************************************************
+ *  prototypes
+ */
+
+/* init funcs */
+static void __init fixup_hackkit(struct machine_desc *desc,
+		struct param_struct *params, char **cmdline, struct meminfo *mi);
+static void __init get_hackkit_scr(void);
+static int __init hackkit_init(void);
+static void __init hackkit_init_irq(void);
+static void __init hackkit_map_io(void);
+
+static int hackkit_get_mctrl(struct uart_port *port);
+static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl);
+static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate);
+
+extern void convert_to_tag_list(struct param_struct *params, int mem_init);
+
+
+/**********************************************************************
+ *  global data
+ */
+
+/**********************************************************************
+ *  static data
+ */
+
+static struct map_desc hackkit_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  LAST_DESC
+};
+
+static struct sa1100_port_fns hackkit_port_fns __initdata = {
+	.set_mctrl	= hackkit_set_mctrl,
+	.get_mctrl	= hackkit_get_mctrl,
+	.pm		= hackkit_uart_pm,
+};
+
+/**********************************************************************
+ *  Static functions
+ */
+
+static void __init hackkit_map_io(void)
+{
+	DPRINTK( "%s\n", "START" );
+	sa1100_map_io();
+	iotable_init(hackkit_io_desc);
+
+	sa1100_register_uart_fns(&hackkit_port_fns);
+	sa1100_register_uart(0, 1);	/* com port */
+	sa1100_register_uart(1, 2);
+	sa1100_register_uart(2, 3);	/* radio module */
+
+	Ser1SDCR0 |= SDCR0_SUS;
+}
+
+static void __init hackkit_init_irq(void)
+{
+	/* none used yet */
+}
+
+/**
+ *	fixup_hackkit - fixup function for system 3 board
+ *	@desc:		machine description
+ *	@param:		kernel params
+ *	@cmdline:	kernel cmdline
+ *	@mi:		memory info struct
+ *
+ */
+static void __init fixup_hackkit(struct machine_desc *desc,
+		struct param_struct *params, char **cmdline, struct meminfo *mi)
+{
+	DPRINTK( "%s\n", "START" );
+
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+	setup_ramdisk( 1, 0, 0, 8192 );
+	setup_initrd( 0xc0800000, 8*1024*1024 );
+}
+
+
+/**
+ *	hackkit_uart_pm - powermgmt callback function for system 3 UART
+ *	@port: uart port structure
+ *	@state: pm state
+ *	@oldstate: old pm state
+ *
+ */
+static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+	/* TODO: switch on/off uart in powersave mode */
+}
+
+/*
+ * Note! this can be called from IRQ context.
+ * FIXME: No modem ctrl lines yet.
+ */
+static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+#if 0
+	if (port->mapbase == _Ser1UTCR0) {
+		u_int set = 0, clear = 0;
+
+		if (mctrl & TIOCM_RTS)
+			set |= PT_CTRL2_RS1_RTS;
+		else
+			clear |= PT_CTRL2_RS1_RTS;
+
+		if (mctrl & TIOCM_DTR)
+			set |= PT_CTRL2_RS1_DTR;
+		else
+			clear |= PT_CTRL2_RS1_DTR;
+
+		PTCTRL2_clear(clear);
+		PTCTRL2_set(set);
+	}
+#endif
+}
+
+static int hackkit_get_mctrl(struct uart_port *port)
+{
+	u_int ret = 0;
+#if 0
+	u_int irqsr = PT_IRQSR;
+
+	/* need 2 reads to read current value */
+	irqsr = PT_IRQSR;
+
+	/* TODO: check IRQ source register for modem/com
+	 status lines and set them correctly. */
+#endif
+
+	ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+
+	return ret;
+}
+
+static int __init hackkit_init(void)
+{
+	int ret = 0;
+	DPRINTK( "%s\n", "START" );
+
+	if ( !machine_is_hackkit() ) {
+		ret = -EINVAL;
+		goto DONE;
+	}
+
+	hackkit_init_irq();
+
+	ret = 0;
+DONE:
+	DPRINTK( "ret=%d\n", ret );
+	return ret;
+}
+
+/**********************************************************************
+ *  Exported Functions
+ */
+
+/**********************************************************************
+ *  kernel magic macros
+ */
+__initcall(hackkit_init);
+
+MACHINE_START(HACKKIT, "HackKit Cpu Board")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_hackkit)
+	MAPIO(hackkit_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/irq.c linux-2.4.22-pre10/arch/arm/mach-sa1100/irq.c
--- linux-2.4.21/arch/arm/mach-sa1100/irq.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/irq.c	2003-08-01 13:34:43.000000000 +0000
@@ -15,6 +15,8 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/ptrace.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
@@ -30,9 +32,9 @@
  * This must be called *before* the appropriate IRQ is registered.
  * Use this instead of directly setting GRER/GFER.
  */
-
 static int GPIO_IRQ_rising_edge;
 static int GPIO_IRQ_falling_edge;
+static int GPIO_IRQ_mask = (1 << 11) - 1;
 
 void set_GPIO_IRQ_edge(int gpio_mask, int edge)
 {
@@ -51,6 +53,8 @@
 		GPIO_IRQ_rising_edge &= ~gpio_mask;
 	GPDR &= ~gpio_mask;
 	GAFR &= ~gpio_mask;
+	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
+	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
 	while (gpio_mask) {
 		if (irq == 11)
 			irq = IRQ_GPIO11;
@@ -86,8 +90,10 @@
 
 static void sa1100_mask_and_ack_GPIO0_10_irq(unsigned int irq)
 {
-	ICMR &= ~(1 << irq);
-	GEDR = (1 << irq);
+	unsigned int mask = 1 << irq;
+
+	ICMR &= ~mask;
+	GEDR = mask;
 }
 
 static void sa1100_mask_GPIO0_10_irq(unsigned int irq)
@@ -97,16 +103,13 @@
 
 static void sa1100_unmask_GPIO0_10_irq(unsigned int irq)
 {
-	GRER = (GRER & ~(1 << irq)) | (GPIO_IRQ_rising_edge & (1 << irq));
-	GFER = (GFER & ~(1 << irq)) | (GPIO_IRQ_falling_edge & (1 << irq));
-	ICMR |= (1 << irq);
+	ICMR |= 1 << irq;
 }
 
 /*
  * Install handler for GPIO 11-27 edge detect interrupts
  */
 
-static int GPIO_11_27_enabled;		/* enabled i.e. unmasked GPIO IRQs */
 static int GPIO_11_27_spurious;		/* GPIOs that triggered when masked */
 
 static void sa1100_GPIO11_27_demux(int irq, void *dev_id,
@@ -124,7 +127,7 @@
 		 * enabled at this point are considered spurious.  Those
 		 * are cleared but only de-activated if they happen twice.
 		 */
-		spurious = irq & ~GPIO_11_27_enabled;
+		spurious = irq & ~GPIO_IRQ_mask;
 		if (spurious) {
 			GEDR = spurious;
 			GRER &= ~(spurious & GPIO_11_27_spurious);
@@ -143,29 +146,29 @@
 }
 
 static struct irqaction GPIO11_27_irq = {
-	name:		"GPIO 11-27",
-	handler:	sa1100_GPIO11_27_demux,
-	flags:		SA_INTERRUPT
+	.name		= "GPIO 11-27",
+	.handler	= sa1100_GPIO11_27_demux,
+	.flags		= SA_INTERRUPT
 };
 
 static void sa1100_mask_and_ack_GPIO11_27_irq(unsigned int irq)
 {
-	int mask = (1 << GPIO_11_27_IRQ(irq));
+	unsigned int mask = (1 << GPIO_11_27_IRQ(irq));
 	GPIO_11_27_spurious &= ~mask;
-	GPIO_11_27_enabled &= ~mask;
+	GPIO_IRQ_mask &= ~mask;
 	GEDR = mask;
 }
 
 static void sa1100_mask_GPIO11_27_irq(unsigned int irq)
 {
-	int mask = (1 << GPIO_11_27_IRQ(irq));
+	unsigned int mask = (1 << GPIO_11_27_IRQ(irq));
 	GPIO_11_27_spurious &= ~mask;
-	GPIO_11_27_enabled &= ~mask;
+	GPIO_IRQ_mask &= ~mask;
 }
 
 static void sa1100_unmask_GPIO11_27_irq(unsigned int irq)
 {
-	int mask = (1 << GPIO_11_27_IRQ(irq));
+	unsigned int mask = (1 << GPIO_11_27_IRQ(irq));
 	if (GPIO_11_27_spurious & mask) {
 		/*
 		 * We don't want to miss an interrupt that would have occurred
@@ -185,15 +188,17 @@
 			return;
 		}
 	}
-	GPIO_11_27_enabled |= mask;
-	GRER = (GRER & ~mask) | (GPIO_IRQ_rising_edge & mask);
-	GFER = (GFER & ~mask) | (GPIO_IRQ_falling_edge & mask);
+
+	GPIO_IRQ_mask |= mask;
+
+	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
+	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
 }
 
 static struct resource irq_resource = {
-	name:	"irqs",
-	start:	0x90050000,
-	end:	0x9005ffff,
+	.name	= "irqs",
+	.start	= 0x90050000,
+	.end	= 0x9005ffff,
 };
 
 void __init sa1100_init_irq(void)
@@ -248,10 +253,4 @@
 		irq_desc[irq].unmask	= sa1100_unmask_GPIO11_27_irq;
 	}
 	setup_arm_irq( IRQ_GPIO11_27, &GPIO11_27_irq );
-
-	/*
-	 * We generally don't want the LCD IRQ being
-	 * enabled as soon as we request it.
-	 */
-	irq_desc[IRQ_LCD].noautoenable = 1;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/jornada720.c linux-2.4.22-pre10/arch/arm/mach-sa1100/jornada720.c
--- linux-2.4.21/arch/arm/mach-sa1100/jornada720.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/jornada720.c	2003-08-01 13:35:07.000000000 +0000
@@ -8,6 +8,8 @@
 #include <linux/delay.h>
 
 #include <asm/hardware.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/irq.h>
 #include <asm/setup.h>
 
 #include <asm/mach/arch.h>
@@ -34,7 +36,7 @@
 	udelay(1);
 	GPSR = GPIO_GPIO20;
 	udelay(20);
-	SKCR = JORSKCR_INIT;	/* Turn on the PLL, enable Ready and enable nOE assertion from DC */
+	SBI_SKCR = JORSKCR_INIT;/* Turn on the PLL, enable Ready and enable nOE assertion from DC */
 	mdelay(100);
 
 	SBI_SKCR = JORSKCR_RCLK;/* turn on the RCLOCK */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/leds-adsagc.c linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-adsagc.c
--- linux-2.4.21/arch/arm/mach-sa1100/leds-adsagc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-adsagc.c	2003-08-01 13:35:03.000000000 +0000
@@ -0,0 +1,107 @@
+/*
+ *  linux/arch/arm/mach-sa1100/leds-adsagc.c
+ *
+ * ADS Advanced Graphics Client LEDs support
+ * Robert Whaley, Feb 7, 2003
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_TIMER       ADS_LED0  /* green heartbeat */
+#define LED_USER        ADS_LED1  /* amber, boots to on */
+#define LED_IDLE        ADS_LED2  /* red has the idle led, if any */
+
+#define LED_MASK	(ADS_LED0|ADS_LED1|ADS_LED2)
+
+void adsagc_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch (evt) {
+	case led_start:
+		hw_led_state = 0;        /* gc leds are positive logic */
+		led_state = LED_STATE_ENABLED;
+		break;
+
+	case led_stop:
+		led_state &= ~LED_STATE_ENABLED;
+		break;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		hw_led_state = LED_MASK;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		hw_led_state = LED_MASK;
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state ^= LED_TIMER;
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state &= ~LED_IDLE;
+		break;
+
+	case led_idle_end:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state |= LED_IDLE;
+		break;
+#endif
+
+	case led_green_on:
+		break;
+
+	case led_green_off:
+		break;
+
+	case led_amber_on:
+		hw_led_state |= LED_USER;
+		break;
+
+	case led_amber_off:
+		hw_led_state &= ~LED_USER;
+		break;
+
+	case led_red_on:
+		break;
+
+	case led_red_off:
+		break;
+
+	default:
+		break;
+	}
+
+	if  (led_state & LED_STATE_ENABLED) {
+
+	        unsigned char ads_cr3 = ADS_CR3;
+		ads_cr3 &= ~LED_MASK;
+		ads_cr3 |= hw_led_state;
+		ADS_CR3 = ads_cr3;
+	}
+
+	local_irq_restore(flags);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/leds-adsbitsy.c linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-adsbitsy.c
--- linux-2.4.21/arch/arm/mach-sa1100/leds-adsbitsy.c	2001-10-25 20:53:46.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-adsbitsy.c	2003-08-01 13:32:18.000000000 +0000
@@ -28,7 +28,7 @@
 {
 	unsigned long flags;
 
-	save_flags_cli(flags);
+	local_irq_save(flags);
 
 	switch (evt) {
 	case led_start:
@@ -92,5 +92,5 @@
 		GPCR = hw_led_state ^ LED_MASK;
 	}
 
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/leds-adsbitsyplus.c linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-adsbitsyplus.c
--- linux-2.4.21/arch/arm/mach-sa1100/leds-adsbitsyplus.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-adsbitsyplus.c	2003-08-01 13:33:15.000000000 +0000
@@ -0,0 +1,97 @@
+/*
+ *  linux/arch/arm/mach-sa1100/leds-adsbitsy.c
+ *
+ * ADS Bitsy LED
+ * 2/7/2003 Robert Whaley
+ * This file comes from leds-adsbitsy.c of Woojung Huh <whuh@applieddata.net>
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_TIMER       GPIO_GPIO20  /* green heartbeat */
+
+#define LED_MASK		(LED_TIMER)
+
+void adsbitsyplus_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch (evt) {
+	case led_start:
+		hw_led_state = 0;        /* gc leds are positive logic */
+		led_state = LED_STATE_ENABLED;
+		break;
+
+	case led_stop:
+		led_state &= ~LED_STATE_ENABLED;
+		break;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		hw_led_state = LED_MASK;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		hw_led_state = LED_MASK;
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state ^= LED_TIMER;
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:
+		break;
+
+	case led_idle_end:
+		break;
+#endif
+
+	case led_green_on:
+		break;
+
+	case led_green_off:
+		break;
+
+	case led_amber_on:
+		break;
+
+	case led_amber_off:
+		break;
+
+	case led_red_on:
+		break;
+
+	case led_red_off:
+		break;
+
+	default:
+		break;
+	}
+
+	if  (led_state & LED_STATE_ENABLED) {
+		GPSR = hw_led_state;
+		GPCR = hw_led_state ^ LED_MASK;
+	}
+
+	local_irq_restore(flags);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/leds-frodo.c linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-frodo.c
--- linux-2.4.21/arch/arm/mach-sa1100/leds-frodo.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-frodo.c	2003-08-01 13:30:35.000000000 +0000
@@ -22,22 +22,22 @@
 
 #include "leds.h"
 
-#define led6_on() FRODO_CPLD_GENERAL |= FRODO_LED2
-#define led6_off() FRODO_CPLD_GENERAL &= ~FRODO_LED2
-#define led6_invert() do {						\
-		if ((FRODO_CPLD_GENERAL & FRODO_LED2))	\
-			led6_off ();						\
-		else									\
-			led6_on ();							\
+#define led6_on() frodo_cpld_set (FRODO_CPLD_GENERAL,FRODO_LED2)
+#define led6_off() frodo_cpld_clear (FRODO_CPLD_GENERAL,FRODO_LED2)
+#define led6_invert() do {											\
+		if ((frodo_cpld_read (FRODO_CPLD_GENERAL) & FRODO_LED2))	\
+			led6_off ();											\
+		else														\
+			led6_on ();												\
 	} while (0)
 
-#define led7_on() FRODO_CPLD_GENERAL |= FRODO_LED1
-#define led7_off() FRODO_CPLD_GENERAL &= ~FRODO_LED1
+#define led7_on() frodo_cpld_set (FRODO_CPLD_GENERAL,FRODO_LED1)
+#define led7_off() frodo_cpld_clear (FRODO_CPLD_GENERAL,FRODO_LED1)
 #define led7_invert() do {						\
-		if ((FRODO_CPLD_GENERAL & FRODO_LED1))	\
-			led7_off ();						\
-		else									\
-			led7_on ();							\
+		if ((frodo_cpld_read (FRODO_CPLD_GENERAL) & FRODO_LED1))	\
+			led7_off ();											\
+		else														\
+			led7_on ();												\
 	} while (0)
 
 static int claimed;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/leds-graphicsclient.c linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-graphicsclient.c
--- linux-2.4.21/arch/arm/mach-sa1100/leds-graphicsclient.c	2001-08-12 18:13:59.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-graphicsclient.c	2003-08-01 13:30:36.000000000 +0000
@@ -30,7 +30,7 @@
 {
 	unsigned long flags;
 
-	save_flags_cli(flags);
+	local_irq_save(flags);
 
 	switch (evt) {
 	case led_start:
@@ -100,5 +100,5 @@
 		GPCR = hw_led_state ^ LED_MASK;
 	}
 
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/leds-graphicsmaster.c linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-graphicsmaster.c
--- linux-2.4.21/arch/arm/mach-sa1100/leds-graphicsmaster.c	2001-10-11 16:04:57.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-graphicsmaster.c	2003-08-01 13:33:51.000000000 +0000
@@ -30,7 +30,7 @@
 {
 	unsigned long flags;
 
-	save_flags_cli(flags);
+	local_irq_save(flags);
 
 	switch (evt) {
 	case led_start:
@@ -100,5 +100,5 @@
 		GPCR = hw_led_state ^ LED_MASK;
 	}
 
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/leds-hackkit.c linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-hackkit.c
--- linux-2.4.21/arch/arm/mach-sa1100/leds-hackkit.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/leds-hackkit.c	2003-08-01 13:32:24.000000000 +0000
@@ -0,0 +1,113 @@
+/*
+ * linux/arch/arm/mach-sa1100/leds-hackkit.c
+ *
+ * based on leds-lart.c
+ *
+ * (C) Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000
+ * (C) Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>, 2002
+ *
+ * The HackKit has two leds (GPIO 22/23). The red led (gpio 22) is used
+ * as cpu led, the green one is used as timer led.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_GREEN    GPIO_GPIO23
+#define LED_RED    GPIO_GPIO22
+#define LED_MASK  (LED_RED | LED_GREEN)
+
+void hackkit_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch(evt) {
+		case led_start:
+			/* pin 22/23 are outputs */
+			GPDR |= LED_MASK;
+			hw_led_state = LED_MASK;
+			led_state = LED_STATE_ENABLED;
+			break;
+
+		case led_stop:
+			led_state &= ~LED_STATE_ENABLED;
+			break;
+
+		case led_claim:
+			led_state |= LED_STATE_CLAIMED;
+			hw_led_state = LED_MASK;
+			break;
+
+		case led_release:
+			led_state &= ~LED_STATE_CLAIMED;
+			hw_led_state = LED_MASK;
+			break;
+
+#ifdef CONFIG_LEDS_TIMER
+		case led_timer:
+			if (!(led_state & LED_STATE_CLAIMED))
+				hw_led_state ^= LED_GREEN;
+			break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+		case led_idle_start:
+			/* The LART people like the LED to be off when the
+			   system is idle... */
+			if (!(led_state & LED_STATE_CLAIMED))
+				hw_led_state &= ~LED_RED;
+			break;
+
+		case led_idle_end:
+			/* ... and on if the system is not idle */
+			if (!(led_state & LED_STATE_CLAIMED))
+				hw_led_state |= LED_RED;
+			break;
+#endif
+
+		case led_red_on:
+			if (led_state & LED_STATE_CLAIMED)
+				hw_led_state &= ~LED_RED;
+			break;
+
+		case led_red_off:
+			if (led_state & LED_STATE_CLAIMED)
+				hw_led_state |= LED_RED;
+			break;
+
+		case led_green_on:
+			if (led_state & LED_STATE_CLAIMED)
+				hw_led_state &= ~LED_GREEN;
+			break;
+
+		case led_green_off:
+			if (led_state & LED_STATE_CLAIMED)
+				hw_led_state |= LED_GREEN;
+			break;
+
+		default:
+			break;
+	}
+
+	/* Now set the GPIO state, or nothing will happen at all */
+	if (led_state & LED_STATE_ENABLED) {
+		GPSR = hw_led_state;
+		GPCR = hw_led_state ^ LED_MASK;
+	}
+
+	local_irq_restore(flags);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/leds.c linux-2.4.22-pre10/arch/arm/mach-sa1100/leds.c
--- linux-2.4.21/arch/arm/mach-sa1100/leds.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/leds.c	2003-08-01 13:31:44.000000000 +0000
@@ -15,8 +15,12 @@
 static int __init
 sa1100_leds_init(void)
 {
+	if (machine_is_adsagc())
+		leds_event = adsagc_leds_event;
 	if (machine_is_adsbitsy())
 		leds_event = adsbitsy_leds_event;
+	if (machine_is_adsbitsyplus())
+		leds_event = adsbitsyplus_leds_event;
 	if (machine_is_assabet())
 		leds_event = assabet_leds_event;
  	if (machine_is_consus())
@@ -33,6 +37,8 @@
 		leds_event = graphicsclient_leds_event;
 	if (machine_is_graphicsmaster())
 		leds_event = graphicsmaster_leds_event;
+	if (machine_is_hackkit())
+		leds_event = hackkit_leds_event;
 	if (machine_is_lart())
 		leds_event = lart_leds_event;
 	if (machine_is_pfs168())
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/leds.h linux-2.4.22-pre10/arch/arm/mach-sa1100/leds.h
--- linux-2.4.21/arch/arm/mach-sa1100/leds.h	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/leds.h	2003-08-01 13:34:09.000000000 +0000
@@ -1,12 +1,15 @@
+extern void adsagc_leds_event(led_event_t evt);
+extern void adsbitsy_leds_event(led_event_t evt);
+extern void adsbitsyplus_leds_event(led_event_t evt);
 extern void assabet_leds_event(led_event_t evt);
 extern void consus_leds_event(led_event_t evt);
 extern void brutus_leds_event(led_event_t evt);
 extern void cerf_leds_event(led_event_t evt);
 extern void flexanet_leds_event(led_event_t evt);
+extern void frodo_leds_event(led_event_t evt);
 extern void graphicsclient_leds_event(led_event_t evt);
+extern void graphicsmaster_leds_event(led_event_t evt);
+extern void hackkit_leds_event(led_event_t evt);
 extern void lart_leds_event(led_event_t evt);
 extern void pfs168_leds_event(led_event_t evt);
-extern void graphicsmaster_leds_event(led_event_t evt);
-extern void adsbitsy_leds_event(led_event_t evt);
 extern void system3_leds_event(led_event_t evt);
-extern void frodo_leds_event(led_event_t evt);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/nanoengine.c linux-2.4.22-pre10/arch/arm/mach-sa1100/nanoengine.c
--- linux-2.4.21/arch/arm/mach-sa1100/nanoengine.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/nanoengine.c	2003-08-01 13:30:33.000000000 +0000
@@ -16,22 +16,6 @@
 #include "generic.h"
 
 
-static void __init
-fixup_nanoengine(struct machine_desc *desc, struct param_struct *params,
-		 char **cmdline, struct meminfo *mi)
-{
-	SET_BANK( 0, 0xc0000000, 32*1024*1024 );
-	mi->nr_banks = 1;
-
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-	setup_ramdisk( 1, 0, 0, 8192 );
-	setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
-
-	/* Get command line parameters passed from the loader (if any) */
-	if( *((char*)0xc0000100) )
-		*cmdline = ((char *)0xc0000100);
-}
-
 static struct map_desc nanoengine_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
   { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
@@ -56,7 +40,7 @@
 
 MACHINE_START(NANOENGINE, "BSE nanoEngine")
 	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	FIXUP(fixup_nanoengine)
+	BOOT_PARAMS(0xc0000100)
 	MAPIO(nanoengine_map_io)
 	INITIRQ(sa1100_init_irq)
 MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/neponset.c linux-2.4.22-pre10/arch/arm/mach-sa1100/neponset.c
--- linux-2.4.21/arch/arm/mach-sa1100/neponset.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/neponset.c	2003-08-01 13:33:15.000000000 +0000
@@ -10,6 +10,8 @@
 #include <linux/tty.h>
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/pcipool.c linux-2.4.22-pre10/arch/arm/mach-sa1100/pcipool.c
--- linux-2.4.21/arch/arm/mach-sa1100/pcipool.c	2001-08-12 18:13:59.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/pcipool.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,377 +0,0 @@
-/*
-  NOTE:
-
-  this code was lifted straight out of drivers/pci/pci.c;
-  when compiling for the Intel StrongARM SA-1110/SA-1111 the
-  usb-ohci.c driver needs these routines even when the architecture
-  has no pci bus...
-*/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/bitops.h>
-
-#include <asm/page.h>
-
-#include "pcipool.h"
-
-/*
- * Pool allocator ... wraps the pci_alloc_consistent page allocator, so
- * small blocks are easily used by drivers for bus mastering controllers.
- * This should probably be sharing the guts of the slab allocator.
- */
-
-struct pci_pool {	/* the pool */
-	struct list_head	page_list;
-	spinlock_t		lock;
-	size_t			blocks_per_page;
-	size_t			size;
-	int			flags;
-	struct pci_dev		*dev;
-	size_t			allocation;
-	char			name [32];
-	wait_queue_head_t	waitq;
-};
-
-struct pci_page {	/* cacheable header for 'allocation' bytes */
-	struct list_head	page_list;
-	void			*vaddr;
-	dma_addr_t		dma;
-	unsigned long		bitmap [0];
-};
-
-#define	POOL_TIMEOUT_JIFFIES	((100 /* msec */ * HZ) / 1000)
-#define	POOL_POISON_BYTE	0xa7
-
-// #define CONFIG_PCIPOOL_DEBUG
-
-
-/**
- * pci_pool_create - Creates a pool of pci consistent memory blocks, for dma.
- * @name: name of pool, for diagnostics
- * @pdev: pci device that will be doing the DMA
- * @size: size of the blocks in this pool.
- * @align: alignment requirement for blocks; must be a power of two
- * @allocation: returned blocks won't cross this boundary (or zero)
- * @flags: SLAB_* flags (not all are supported).
- *
- * Returns a pci allocation pool with the requested characteristics, or
- * null if one can't be created.  Given one of these pools, pci_pool_alloc()
- * may be used to allocate memory.  Such memory will all have "consistent"
- * DMA mappings, accessible by the device and its driver without using
- * cache flushing primitives.  The actual size of blocks allocated may be
- * larger than requested because of alignment.
- *
- * If allocation is nonzero, objects returned from pci_pool_alloc() won't
- * cross that size boundary.  This is useful for devices which have
- * addressing restrictions on individual DMA transfers, such as not crossing
- * boundaries of 4KBytes.
- */
-struct pci_pool *
-pci_pool_create (const char *name, struct pci_dev *pdev,
-	size_t size, size_t align, size_t allocation, int flags)
-{
-	struct pci_pool		*retval;
-
-	if (align == 0)
-		align = 1;
-	if (size == 0)
-		return 0;
-	else if (size < align)
-		size = align;
-	else if ((size % align) != 0) {
-		size += align + 1;
-		size &= ~(align - 1);
-	}
-
-	if (allocation == 0) {
-		if (PAGE_SIZE < size)
-			allocation = size;
-		else
-			allocation = PAGE_SIZE;
-		// FIXME: round up for less fragmentation
-	} else if (allocation < size)
-		return 0;
-
-	if (!(retval = kmalloc (sizeof *retval, flags)))
-		return retval;
-
-#ifdef	CONFIG_PCIPOOL_DEBUG
-	flags |= SLAB_POISON;
-#endif
-
-	strncpy (retval->name, name, sizeof retval->name);
-	retval->name [sizeof retval->name - 1] = 0;
-
-	retval->dev = pdev;
-	INIT_LIST_HEAD (&retval->page_list);
-	spin_lock_init (&retval->lock);
-	retval->size = size;
-	retval->flags = flags;
-	retval->allocation = allocation;
-	retval->blocks_per_page = allocation / size;
-	init_waitqueue_head (&retval->waitq);
-
-#ifdef CONFIG_PCIPOOL_DEBUG
-	printk (KERN_DEBUG "pcipool create %s/%s size %d, %d/page (%d alloc)\n",
-		pdev ? pdev->slot_name : NULL, retval->name, size,
-		retval->blocks_per_page, allocation);
-#endif
-
-	return retval;
-}
-
-
-static struct pci_page *
-pool_alloc_page (struct pci_pool *pool, int mem_flags)
-{
-	struct pci_page	*page;
-	int		mapsize;
-
-	mapsize = pool->blocks_per_page;
-	mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
-	mapsize *= sizeof (long);
-
-	page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags);
-	if (!page)
-		return 0;
-	page->vaddr = pci_alloc_consistent (pool->dev,
-				pool->allocation, &page->dma);
-	if (page->vaddr) {
-		memset (page->bitmap, 0xff, mapsize);	// bit set == free
-		if (pool->flags & SLAB_POISON)
-			memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
-		list_add (&page->page_list, &pool->page_list);
-	} else {
-		kfree (page);
-		page = 0;
-	}
-	return page;
-}
-
-
-static inline int
-is_page_busy (int blocks, unsigned long *bitmap)
-{
-	while (blocks > 0) {
-		if (*bitmap++ != ~0UL)
-			return 1;
-		blocks -= BITS_PER_LONG;
-	}
-	return 0;
-}
-
-static void
-pool_free_page (struct pci_pool *pool, struct pci_page *page)
-{
-	dma_addr_t	dma = page->dma;
-
-	if (pool->flags & SLAB_POISON)
-		memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
-	pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma);
-	list_del (&page->page_list);
-	kfree (page);
-}
-
-
-/**
- * pci_pool_destroy - destroys a pool of pci memory blocks.
- * @pool: pci pool that will be destroyed
- *
- * Caller guarantees that no more memory from the pool is in use,
- * and that nothing will try to use the pool after this call.
- */
-void
-pci_pool_destroy (struct pci_pool *pool)
-{
-	unsigned long		flags;
-
-#ifdef CONFIG_PCIPOOL_DEBUG
-	printk (KERN_DEBUG "pcipool destroy %s/%s\n",
-		pool->dev ? pool->dev->slot_name : NULL,
-		pool->name);
-#endif
-
-	spin_lock_irqsave (&pool->lock, flags);
-	while (!list_empty (&pool->page_list)) {
-		struct pci_page		*page;
-		page = list_entry (pool->page_list.next,
-				struct pci_page, page_list);
-		if (is_page_busy (pool->blocks_per_page, page->bitmap)) {
-			printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n",
-				pool->dev ? pool->dev->slot_name : NULL,
-				pool->name, page->vaddr);
-			/* leak the still-in-use consistent memory */
-			list_del (&page->page_list);
-			kfree (page);
-		} else
-			pool_free_page (pool, page);
-	}
-	spin_unlock_irqrestore (&pool->lock, flags);
-	kfree (pool);
-}
-
-
-/**
- * pci_pool_alloc - get a block of consistent memory
- * @pool: pci pool that will produce the block
- * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC
- * @handle: pointer to dma address of block
- *
- * This returns the kernel virtual address of a currently unused block,
- * and reports its dma address through the handle.
- * If such a memory block can't be allocated, null is returned.
- */
-void *
-pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
-{
-	unsigned long		flags;
-	struct list_head	*entry;
-	struct pci_page		*page;
-	int			map, block;
-	size_t			offset;
-	void			*retval;
-
-restart:
-	spin_lock_irqsave (&pool->lock, flags);
-	list_for_each (entry, &pool->page_list) {
-		int		i;
-		page = list_entry (entry, struct pci_page, page_list);
-		/* only cachable accesses here ... */
-		for (map = 0, i = 0;
-				i < pool->blocks_per_page;
-				i += BITS_PER_LONG, map++) {
-			if (page->bitmap [map] == 0)
-				continue;
-			block = ffz (~ page->bitmap [map]);
-			if ((i + block) < pool->blocks_per_page) {
-				clear_bit (block, &page->bitmap [map]);
-				offset = (BITS_PER_LONG * map) + block;
-				offset *= pool->size;
-				goto ready;
-			}
-		}
-	}
-	if (!(page = pool_alloc_page (pool, mem_flags))) {
-		if (mem_flags == SLAB_KERNEL) {
-			DECLARE_WAITQUEUE (wait, current);
-
-			current->state = TASK_INTERRUPTIBLE;
-			add_wait_queue (&pool->waitq, &wait);
-			spin_unlock_irqrestore (&pool->lock, flags);
-
-			schedule_timeout (POOL_TIMEOUT_JIFFIES);
-
-			current->state = TASK_RUNNING;
-			remove_wait_queue (&pool->waitq, &wait);
-			goto restart;
-		}
-		retval = 0;
-		goto done;
-	}
-
-	clear_bit (0, &page->bitmap [0]);
-	offset = 0;
-ready:
-	retval = offset + page->vaddr;
-	*handle = offset + page->dma;
-done:
-	spin_unlock_irqrestore (&pool->lock, flags);
-	return retval;
-}
-
-
-static struct pci_page *
-pool_find_page (struct pci_pool *pool, dma_addr_t dma)
-{
-	unsigned long		flags;
-	struct list_head	*entry;
-	struct pci_page		*page;
-
-	spin_lock_irqsave (&pool->lock, flags);
-	list_for_each (entry, &pool->page_list) {
-		page = list_entry (entry, struct pci_page, page_list);
-		if (dma < page->dma)
-			continue;
-		if (dma < (page->dma + pool->allocation))
-			goto done;
-	}
-	page = 0;
-done:
-	spin_unlock_irqrestore (&pool->lock, flags);
-	return page;
-}
-
-
-/**
- * pci_pool_free - put block back into pci pool
- * @pool: the pci pool holding the block
- * @vaddr: virtual address of block
- * @dma: dma address of block
- *
- * Caller promises neither device nor driver will again touch this block
- * unless it is first re-allocated.
- */
-void
-pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma)
-{
-	struct pci_page		*page;
-	unsigned long		flags;
-	int			map, block;
-
-	if ((page = pool_find_page (pool, dma)) == 0) {
-		printk (KERN_ERR "pci_pool_free %s/%s, %p/%x (bad dma)\n",
-			pool->dev ? pool->dev->slot_name : NULL,
-			pool->name, vaddr, dma);
-		return;
-	}
-#ifdef	CONFIG_PCIPOOL_DEBUG
-	if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
-		printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%x\n",
-			pool->dev ? pool->dev->slot_name : NULL,
-			pool->name, vaddr, dma);
-		return;
-	}
-#endif
-
-	block = dma - page->dma;
-	block /= pool->size;
-	map = block / BITS_PER_LONG;
-	block %= BITS_PER_LONG;
-
-#ifdef	CONFIG_PCIPOOL_DEBUG
-	if (page->bitmap [map] & (1UL << block)) {
-		printk (KERN_ERR "pci_pool_free %s/%s, dma %x already free\n",
-			pool->dev ? pool->dev->slot_name : NULL,
-			pool->name, dma);
-		return;
-	}
-#endif
-	if (pool->flags & SLAB_POISON)
-		memset (vaddr, POOL_POISON_BYTE, pool->size);
-
-	spin_lock_irqsave (&pool->lock, flags);
-	set_bit (block, &page->bitmap [map]);
-	if (waitqueue_active (&pool->waitq))
-		wake_up (&pool->waitq);
-	/*
-	 * Resist a temptation to do
-	 *    if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page);
-	 * it is not interrupt safe. Better have empty pages hang around.
-	 */
-	spin_unlock_irqrestore (&pool->lock, flags);
-}
-
-
-EXPORT_SYMBOL (pci_pool_create);
-EXPORT_SYMBOL (pci_pool_destroy);
-EXPORT_SYMBOL (pci_pool_alloc);
-EXPORT_SYMBOL (pci_pool_free);
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/pcipool.h linux-2.4.22-pre10/arch/arm/mach-sa1100/pcipool.h
--- linux-2.4.21/arch/arm/mach-sa1100/pcipool.h	2001-08-12 18:13:59.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/pcipool.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,8 +0,0 @@
-
-struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
-		size_t size, size_t align, size_t allocation, int flags);
-void pci_pool_destroy (struct pci_pool *pool);
-
-void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
-void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/pm.c linux-2.4.22-pre10/arch/arm/mach-sa1100/pm.c
--- linux-2.4.21/arch/arm/mach-sa1100/pm.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/pm.c	2003-08-01 13:31:54.000000000 +0000
@@ -18,11 +18,13 @@
  * 2001-08-29:	Nicolas Pitre <nico@cam.org>
  * 			Cleaned up, pushed platform dependent stuff
  * 			in the platform specific files.
+ *
+ * 2002-05-27:	Nicolas Pitre	Killed sleep.h and the kmalloced save array.
+ * 				Storage is local on the stack now.
  */
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/pm.h>
-#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/sysctl.h>
@@ -33,7 +35,6 @@
 #include <asm/system.h>
 #include <asm/leds.h>
 
-#include "sleep.h"
 
 /*
  * Debug macros
@@ -43,20 +44,32 @@
 extern void sa1100_cpu_suspend(void);
 extern void sa1100_cpu_resume(void);
 
-extern unsigned long *sleep_save;	/* virtual address */
-extern unsigned long  sleep_save_p;	/* physical address */
-
 #define SAVE(x)		sleep_save[SLEEP_SAVE_##x] = x
 #define RESTORE(x)	x = sleep_save[SLEEP_SAVE_##x]
 
+/*
+ * List of global SA11x0 peripheral registers to preserve.
+ * More ones like CP and general purpose register values are preserved
+ * with the stack location in sleep.S.
+ */
+enum {	SLEEP_SAVE_START = 0,
+
+	SLEEP_SAVE_OSCR, SLEEP_SAVE_OIER,
+	SLEEP_SAVE_OSMR0, SLEEP_SAVE_OSMR1, SLEEP_SAVE_OSMR2, SLEEP_SAVE_OSMR3,
+
+	SLEEP_SAVE_GPDR, SLEEP_SAVE_GRER, SLEEP_SAVE_GFER, SLEEP_SAVE_GAFR,
+	SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
+
+	SLEEP_SAVE_ICMR,
+	SLEEP_SAVE_Ser1SDCR0,
+
+	SLEEP_SAVE_SIZE
+};
+
+
 int pm_do_suspend(void)
 {
-	/* set up pointer to sleep parameters */
-	sleep_save = kmalloc(SLEEP_SAVE_SIZE*sizeof(long), GFP_ATOMIC);
-	if (!sleep_save)
-		return -ENOMEM;
-
-	sleep_save_p = virt_to_phys(sleep_save);
+	unsigned long sleep_save[SLEEP_SAVE_SIZE];
 
 	cli();
 
@@ -144,8 +157,6 @@
 
 	sti();
 
-	kfree (sleep_save);
-
 	/*
 	 * Restore the CPU frequency settings.
 	 */
@@ -156,6 +167,11 @@
 	return 0;
 }
 
+unsigned long sleep_phys_sp(void *sp)
+{
+	return virt_to_phys(sp);
+}
+
 #ifdef CONFIG_SYSCTL
 /*
  * ARGH!  ACPI people defined CTL_ACPI in linux/acpi.h rather than
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/sa1111-pcibuf.c linux-2.4.22-pre10/arch/arm/mach-sa1100/sa1111-pcibuf.c
--- linux-2.4.21/arch/arm/mach-sa1100/sa1111-pcibuf.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/sa1111-pcibuf.c	2003-08-01 13:30:31.000000000 +0000
@@ -1,272 +1,400 @@
 /*
  *  linux/arch/arm/mach-sa1100/pci-sa1111.c
  *
- *  Special pci_map/unmap_single routines for SA-1111.   These functions
- *  compensate for a bug in the SA-1111 hardware which don't allow DMA
- *  to/from addresses above 1MB.
+ *  Special pci_{map/unmap/dma_sync}_* routines for SA-1111.
  *
- *  Brad Parker (brad@heeltoe.com)
+ *  These functions utilize bouncer buffers to compensate for a bug in
+ *  the SA-1111 hardware which don't allow DMA to/from addresses
+ *  certain addresses above 1MB.
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
+ *  Re-written by Christopher Hoover <ch@murgatroid.com>
+ *  Original version by Brad Parker (brad@heeltoe.com)
  *
- *  06/13/2001 - created.
- */
+ *  Copyright (C) 2002 Hewlett Packard Company.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  version 2 as published by the Free Software Foundation.
+ * */
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
+#include <linux/list.h>
+#include <asm/hardware/sa1111.h>
+//#define DEBUG
+#ifdef DEBUG
+#define DPRINTK(...) do { printk(KERN_DEBUG __VA_ARGS__); } while (0)
+#else
+#define DPRINTK(...) do { } while (0)
+#endif
+
+struct safe_buffer {
+	struct list_head node;
+
+	/* original request */
+	void		*ptr;
+	size_t		size;
+	int		direction;
 
-#include "pcipool.h"
+	/* safe buffer info */
+	struct pci_pool *pool;
+	void		*safe;
+	dma_addr_t	safe_dma_addr;
+};
 
-/*
- * simple buffer allocator for copying of unsafe to safe buffers
- * uses __alloc/__free for actual buffers
- * keeps track of safe buffers we've allocated so we can recover the
- * unsafe buffers.
- */
+LIST_HEAD(safe_buffers);
 
-#define MAX_SAFE	32
 #define SIZE_SMALL	1024
 #define SIZE_LARGE	(16*1024)
 
-static long mapped_alloc_size;
-static char *safe_buffers[MAX_SAFE][2];
-
-
-static struct pci_pool *small_buffer_cache, *large_buffer_cache;
+static struct pci_pool *small_buffer_pool, *large_buffer_pool;
 
-static int
-init_safe_buffers(struct pci_dev *dev)
+static int __init
+create_safe_buffer_pools(void)
 {
-	small_buffer_cache = pci_pool_create("pci_small_buffer",
-					    dev,
+	small_buffer_pool = pci_pool_create("sa1111_small_dma_buffer",
+					    SA1111_FAKE_PCIDEV,
 					    SIZE_SMALL,
 					    0 /* byte alignment */,
 					    0 /* no page-crossing issues */,
-					    GFP_KERNEL | GFP_DMA);
-
-	if (small_buffer_cache == 0)
+					    SLAB_KERNEL);
+	if (0 == small_buffer_pool) {
+		printk(KERN_ERR
+		       "sa1111_pcibuf: could not allocate small pci pool\n");
 		return -1;
+	}
 
-	large_buffer_cache = pci_pool_create("pci_large_buffer",
-					    dev,
+	large_buffer_pool = pci_pool_create("sa1111_large_dma_buffer",
+					    SA1111_FAKE_PCIDEV,
 					    SIZE_LARGE,
 					    0 /* byte alignment */,
 					    0 /* no page-crossing issues */,
-					    GFP_KERNEL | GFP_DMA);
-	if (large_buffer_cache == 0)
+					    SLAB_KERNEL);
+	if (0 == large_buffer_pool) {
+		printk(KERN_ERR
+		       "sa1111_pcibuf: could not allocate large pci pool\n");
+		pci_pool_destroy(small_buffer_pool);
+		small_buffer_pool = 0;
 		return -1;
+	}
 
 	return 0;
 }
 
+static void __exit
+destroy_safe_buffer_pools(void)
+{
+	if (small_buffer_pool)
+		pci_pool_destroy(small_buffer_pool);
+	if (large_buffer_pool)
+		pci_pool_destroy(large_buffer_pool);
+
+	small_buffer_pool = large_buffer_pool = 0;
+}
+
+
 /* allocate a 'safe' buffer and keep track of it */
-static char *
-alloc_safe_buffer(char *unsafe, int size, dma_addr_t *pbus)
+static struct safe_buffer *
+alloc_safe_buffer(void *ptr, size_t size, int direction)
 {
-	char *safe;
-	dma_addr_t busptr;
+	struct safe_buffer *buf;
 	struct pci_pool *pool;
-	int i;
-
-	if (0) printk("alloc_safe_buffer(size=%d)\n", size);
+	void *safe;
+	dma_addr_t safe_dma_addr;
 
-	if (size <= SIZE_SMALL)
-		pool = small_buffer_cache;
-	else
-		if (size < SIZE_LARGE)
-			pool = large_buffer_cache;
-				else
-					return 0;
+	DPRINTK("%s(ptr=%p, size=%d, direction=%d)\n",
+		__func__, ptr, size, direction);
 
-	safe = pci_pool_alloc(pool, SLAB_ATOMIC, &busptr);
-	if (safe == 0)
+	buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
+	if (buf == 0) {
+		printk(KERN_WARNING "%s: kmalloc failed\n", __func__);
 		return 0;
+	}
 
-	for (i = 0; i < MAX_SAFE; i++)
-		if (safe_buffers[i][0] == 0) {
-			break;
-		}
-
-	if (i == MAX_SAFE) {
-		panic(__FILE__ ": exceeded MAX_SAFE buffers");
+	if (size <= SIZE_SMALL) {
+		pool = small_buffer_pool;
+		safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
+	} else if (size <= SIZE_LARGE) {
+		pool = large_buffer_pool;
+		safe = pci_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
+	} else {
+		printk(KERN_DEBUG
+		       "sa111_pcibuf: resorting to pci_alloc_consistent\n");
+		pool = 0;
+		safe = pci_alloc_consistent(SA1111_FAKE_PCIDEV, size,
+					    &safe_dma_addr);
 	}
 
-	/* place the size index and the old buffer ptr in the first 8 bytes
-	 * and return a ptr + 12 to caller
-	 */
-	((int *)safe)[0] = i;
-	((char **)safe)[1] = (char *)pool;
-	((char **)safe)[2] = unsafe;
+	if (safe == 0) {
+		printk(KERN_WARNING
+		       "%s: could not alloc dma memory (size=%d)\n",
+		       __func__, size);
+		kfree(buf);
+		return 0;
+	}
 
-	busptr += sizeof(int) + sizeof(char *) + sizeof(char *);
+	BUG_ON(sa1111_check_dma_bug(safe_dma_addr));	// paranoia
 
-	safe_buffers[i][0] = (void *)busptr;
-	safe_buffers[i][1] = (void *)safe;
+	buf->ptr = ptr;
+	buf->size = size;
+	buf->direction = direction;
+	buf->pool = pool;
+	buf->safe = safe;
+	buf->safe_dma_addr = safe_dma_addr;
 
-	safe += sizeof(int) + sizeof(char *) + sizeof(char *);
+	MOD_INC_USE_COUNT;
+	list_add(&buf->node, &safe_buffers);
 
-	*pbus = busptr;
-	return safe;
+	return buf;
 }
 
 /* determine if a buffer is from our "safe" pool */
-static char *
-find_safe_buffer(char *busptr, char **unsafe)
+static struct safe_buffer *
+find_safe_buffer(dma_addr_t safe_dma_addr)
 {
-	int i;
-	char *buf;
+	struct list_head *entry;
 
-	for (i = 0; i < MAX_SAFE; i++) {
-		if (safe_buffers[i][0] == busptr) {
-			if (0) printk("find_safe_buffer(%p) found @ %d\n", busptr, i);
-			buf = safe_buffers[i][1];
-			*unsafe = ((char **)buf)[2];
-			return buf + sizeof(int) + sizeof(char *) + sizeof(char *);
+	list_for_each(entry, &safe_buffers) {
+		struct safe_buffer *b =
+			list_entry(entry, struct safe_buffer, node);
+
+		if (b->safe_dma_addr == safe_dma_addr) {
+			return b;
 		}
 	}
 
-	return (char *)0;
+	return 0;
 }
 
 static void
-free_safe_buffer(char *buf)
+free_safe_buffer(struct safe_buffer *buf)
 {
-	int index;
-	struct pci_pool *pool;
-	char *dma;
+	DPRINTK("%s(buf=%p)\n", __func__, buf);
 
-	if (0) printk("free_safe_buffer(buf=%p)\n", buf);
+	list_del(&buf->node);
 
-	/* retrieve the buffer size index */
-	buf -= sizeof(int) + sizeof(char*) + sizeof(char*);
-	index = ((int *)buf)[0];
-	pool = (struct pci_pool *)((char **)buf)[1];
+	if (buf->pool)
+		pci_pool_free(buf->pool, buf->safe, buf->safe_dma_addr);
+	else
+		pci_free_consistent(SA1111_FAKE_PCIDEV, buf->size, buf->safe,
+				    buf->safe_dma_addr);
+	kfree(buf);
 
-	if (0) printk("free_safe_buffer(%p) index %d\n",
-		      buf, index);
+	MOD_DEC_USE_COUNT;
+}
 
-	if (index < 0 || index >= MAX_SAFE) {
-		printk(__FILE__ ": free_safe_buffer() corrupt buffer\n");
-		return;
-	}
+static inline int
+dma_range_is_safe(dma_addr_t addr, size_t size)
+{
+	unsigned int physaddr = SA1111_DMA_ADDR((unsigned int) addr);
 
-	dma = safe_buffers[index][0];
-	safe_buffers[index][0] = 0;
+	/* Any address within one megabyte of the start of the target
+         * bank will be OK.  This is an overly conservative test:
+         * other addresses can be OK depending on the dram
+         * configuration.  (See sa1111.c:sa1111_check_dma_bug() * for
+         * details.)
+	 *
+	 * We take care to ensure the entire dma region is within
+	 * the safe range.
+	 */
 
-	pci_pool_free(pool, buf, (u32)dma);
+	return ((physaddr + size - 1) < (1<<20));
 }
 
 /*
-  NOTE:
-  replace pci_map/unmap_single with local routines which will
-  do buffer copies if buffer is above 1mb...
-*/
-
-/*
  * see if a buffer address is in an 'unsafe' range.  if it is
  * allocate a 'safe' buffer and copy the unsafe buffer into it.
  * substitute the safe buffer for the unsafe one.
  * (basically move the buffer from an unsafe area to a safe one)
- *
- * we assume calls to map_single are symmetric with calls to unmap_single...
  */
 dma_addr_t
-sa1111_map_single(struct pci_dev *hwdev, void *virtptr,
-	       size_t size, int direction)
+sa1111_map_single(void *ptr, size_t size, int direction)
 {
-	dma_addr_t busptr;
+	unsigned long flags;
+	dma_addr_t dma_addr;
 
-	mapped_alloc_size += size;
+	DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
+	       __func__, ptr, size, direction);
 
-	if (0) printk("pci_map_single(hwdev=%p,ptr=%p,size=%d,dir=%x) "
-		      "alloced=%ld\n",
-		      hwdev, virtptr, size, direction, mapped_alloc_size);
+	BUG_ON(direction == PCI_DMA_NONE);
 
-	busptr = virt_to_bus(virtptr);
+	local_irq_save(flags);
 
-	/* we assume here that a buffer will never be >=64k */
-	if ( (((unsigned long)busptr) & 0x100000) ||
-	     ((((unsigned long)busptr)+size) & 0x100000) )
-	{
-		char *safe;
+	dma_addr = virt_to_bus(ptr);
 
-		safe = alloc_safe_buffer(virtptr, size, &busptr);
-		if (safe == 0) {
-			printk("unable to map unsafe buffer %p!\n", virtptr);
+	if (!dma_range_is_safe(dma_addr, size)) {
+		struct safe_buffer *buf;
+
+		buf = alloc_safe_buffer(ptr, size, direction);
+		if (buf == 0) {
+			printk(KERN_ERR
+			       "%s: unable to map unsafe buffer %p!\n",
+			       __func__, ptr);
+			local_irq_restore(flags);
 			return 0;
 		}
 
-		if (0) printk("unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
-			      virtptr, (void *)virt_to_bus(virtptr),
-			      safe, (void *)busptr);
-
-		memcpy(safe, virtptr, size);
-		consistent_sync(safe, size, direction);
+		DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
+			__func__,
+			buf->ptr, (void *) virt_to_bus(buf->ptr),
+			buf->safe, (void *) buf->safe_dma_addr);
+
+		if ((direction == PCI_DMA_TODEVICE) ||
+		    (direction == PCI_DMA_BIDIRECTIONAL)) {
+			DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n",
+				__func__, ptr, buf->safe, size);
+			memcpy(buf->safe, ptr, size);
+		}
+		consistent_sync(buf->safe, size, direction);
 
-		return busptr;
+		dma_addr = buf->safe_dma_addr;
+	} else {
+		consistent_sync(ptr, size, direction);
 	}
 
-	consistent_sync(virtptr, size, direction);
-	return busptr;
+	local_irq_restore(flags);
+	return dma_addr;
 }
 
 /*
- * see if a mapped address was really a "safe" buffer and if so,
- * copy the data from the safe buffer back to the unsafe buffer
- * and free up the safe buffer.
- * (basically return things back to the way they should be)
+ * see if a mapped address was really a "safe" buffer and if so, copy
+ * the data from the safe buffer back to the unsafe buffer and free up
+ * the safe buffer.  (basically return things back to the way they
+ * should be)
  */
+
 void
-sa1111_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
-		 size_t size, int direction)
+sa1111_unmap_single(dma_addr_t dma_addr, size_t size, int direction)
 {
-	char *safe, *unsafe;
-	void *buf;
+	unsigned long flags;
+	struct safe_buffer *buf;
 
-	/* hack; usb-ohci.c never sends hwdev==NULL, all others do */
-	if (hwdev == NULL) {
-		return;
+	DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
+		__func__, (void *) dma_addr, size, direction);
+
+	BUG_ON(direction == PCI_DMA_NONE);
+
+	local_irq_save(flags);
+
+	buf = find_safe_buffer(dma_addr);
+	if (buf) {
+		BUG_ON(buf->size != size);
+		BUG_ON(buf->direction != direction);
+
+		DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
+			__func__,
+			buf->ptr, (void *) virt_to_bus(buf->ptr),
+			buf->safe, (void *) buf->safe_dma_addr);
+
+		if ((direction == PCI_DMA_FROMDEVICE) ||
+		    (direction == PCI_DMA_BIDIRECTIONAL)) {
+			DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n",
+				__func__, buf->safe, buf->ptr, size);
+			memcpy(buf->ptr, buf->safe, size);
+		}
+		free_safe_buffer(buf);
 	}
 
-	mapped_alloc_size -= size;
+	local_irq_restore(flags);
+}
+
+int
+sa1111_map_sg(struct scatterlist *sg, int nents, int direction)
+{
+	BUG();			/* Not implemented. */
+
+	return -1;
+}
+
+void
+sa1111_unmap_sg(struct scatterlist *sg, int nents, int direction)
+{
+	BUG();			/* Not implemented. */
+}
+
+void
+sa1111_dma_sync_single(dma_addr_t dma_addr, size_t size, int direction)
+{
+	unsigned long flags;
+	struct safe_buffer *buf;
+
+	DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
+		__func__, (void *) dma_addr, size, direction);
 
-	if (0) printk("pci_unmap_single(hwdev=%p,ptr=%p,size=%d,dir=%x) "
-		      "alloced=%ld\n",
-		      hwdev, (void *)dma_addr, size, direction,
-		      mapped_alloc_size);
-
-	if ((safe = find_safe_buffer((void *)dma_addr, &unsafe))) {
-		if (0) printk("copyback unsafe %p, safe %p, size %d\n",
-			      unsafe, safe, size);
-
-		consistent_sync(safe, size, PCI_DMA_FROMDEVICE);
-		memcpy(unsafe, safe, size);
-		free_safe_buffer(safe);
+	local_irq_save(flags);
+
+	buf = find_safe_buffer(dma_addr);
+	if (buf) {
+		BUG_ON(buf->size != size);
+		BUG_ON(buf->direction != direction);
+
+		DPRINTK("%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
+			__func__,
+			buf->ptr, (void *) virt_to_bus(buf->ptr),
+			buf->safe, (void *) buf->safe_dma_addr);
+
+		switch (direction) {
+		case PCI_DMA_FROMDEVICE:
+			DPRINTK("%s: copy back from safe %p, to unsafe %p size %d\n",
+				__func__, buf->safe, buf->ptr, size);
+			memcpy(buf->ptr, buf->safe, size);
+			break;
+		case PCI_DMA_TODEVICE:
+			DPRINTK("%s: copy out from unsafe %p, to safe %p, size %d\n",
+				__func__,buf->ptr, buf->safe, size);
+			memcpy(buf->safe, buf->ptr, size);
+			break;
+		case PCI_DMA_BIDIRECTIONAL:
+			BUG();	/* is this allowed?  what does it mean? */
+		default:
+			BUG();
+		}
+		consistent_sync(buf->safe, size, direction);
 	} else {
-		/* assume this is normal memory */
-		buf = bus_to_virt(dma_addr);
-		consistent_sync(buf, size, PCI_DMA_FROMDEVICE);
+		consistent_sync(bus_to_virt(dma_addr), size, direction);
 	}
+
+	local_irq_restore(flags);
+}
+
+void
+sa1111_dma_sync_sg(struct scatterlist *sg, int nelems, int direction)
+{
+	BUG();			/* Not implemented. */
 }
 
 EXPORT_SYMBOL(sa1111_map_single);
 EXPORT_SYMBOL(sa1111_unmap_single);
+EXPORT_SYMBOL(sa1111_map_sg);
+EXPORT_SYMBOL(sa1111_unmap_sg);
+EXPORT_SYMBOL(sa1111_dma_sync_single);
+EXPORT_SYMBOL(sa1111_dma_sync_sg);
 
-static int __init sa1111_init_safe_buffers(void)
+/* **************************************** */
+
+static int __init sa1111_pcibuf_init(void)
 {
-	printk("Initializing SA1111 buffer pool for DMA workaround\n");
-	init_safe_buffers(NULL);
-	return 0;
+	int ret;
+
+	printk(KERN_DEBUG
+	       "sa1111_pcibuf: initializing SA-1111 DMA workaround\n");
+
+	ret = create_safe_buffer_pools();
+
+	return ret;
 }
+module_init(sa1111_pcibuf_init);
 
-static void free_safe_buffers(void)
+static void __exit sa1111_pcibuf_exit(void)
 {
-	pci_pool_destroy(small_buffer_cache);
-	pci_pool_destroy(large_buffer_cache);
+	BUG_ON(!list_empty(&safe_buffers));
+
+	destroy_safe_buffer_pools();
 }
+module_exit(sa1111_pcibuf_exit);
 
-module_init(sa1111_init_safe_buffers);
-module_exit(free_safe_buffers);
+MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>");
+MODULE_DESCRIPTION("Special pci_{map/unmap/dma_sync}_* routines for SA-1111.");
+MODULE_LICENSE("GPL");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/sa1111.c linux-2.4.22-pre10/arch/arm/mach-sa1100/sa1111.c
--- linux-2.4.21/arch/arm/mach-sa1100/sa1111.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/sa1111.c	2003-08-01 13:34:32.000000000 +0000
@@ -24,6 +24,8 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/simputer.c linux-2.4.22-pre10/arch/arm/mach-sa1100/simputer.c
--- linux-2.4.21/arch/arm/mach-sa1100/simputer.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/simputer.c	2003-08-01 13:32:47.000000000 +0000
@@ -0,0 +1,78 @@
+/*
+ * linux/arch/arm/mach-sa1100/simputer.c
+ *
+ * Author: Vivek K S (modified from Nicolas Pitre's Assabet file)
+ *
+ * This file contains all Simputer-specific tweaks.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/serial_core.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+#include <asm/arch/simputer.h>
+
+#include "generic.h"
+
+static void __init
+fixup_simputer(struct machine_desc *desc, struct param_struct *params,
+	      char **cmdline, struct meminfo *mi)
+{
+}
+
+
+static struct map_desc simputer_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf2800000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Simputer Modem */
+  { 0xf3800000, 0x48000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* USB */
+  LAST_DESC
+};
+
+static void __init simputer_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(simputer_io_desc);
+
+	sa1100_register_uart(1, 2);
+	sa1100_register_uart(0, 1);	/* com port */
+	sa1100_register_uart(2, 3);	/* radio module */
+
+	/*
+	 * Set up registers for sleep mode.
+	 */
+	PWER = PWER_GPIO0;
+	PGSR = 0;
+	PCFR = 0;
+
+	/*
+	 * Clear all possible wakeup reasons.
+	 */
+	RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
+}
+
+
+MACHINE_START(SIMPUTER, "Picopeta-Simputer")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_simputer)
+	MAPIO(simputer_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/sleep.S linux-2.4.22-pre10/arch/arm/mach-sa1100/sleep.S
--- linux-2.4.21/arch/arm/mach-sa1100/sleep.S	2001-10-25 20:53:46.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/sleep.S	2003-08-01 13:34:18.000000000 +0000
@@ -11,12 +11,17 @@
  * 2001-02-06: Cliff Brake         Initial code
  *
  * 2001-08-29:	Nicolas Pitre	Simplified.
+ *
+ * 2002-05-27:	Nicolas Pitre	Revisited, more cleanup and simplification.
+ *				Storage is on the stack now.
  */
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 #include <asm/hardware.h>
-#include "sleep.h"
+
+
+		.text
 
 /*
  * sa1100_cpu_suspend()
@@ -25,35 +30,25 @@
  *
  */
 
-	.text
-
-ENTRY(sleep_save)	.word	0		@ virtual address of parameter array
-ENTRY(sleep_save_p)	.word	0		@ physical address of parameter array
-
 ENTRY(sa1100_cpu_suspend)
 
-	@ save registers on stack
-	stmfd	sp!, {r4 - r12, lr}
-
-	@ load virtual address for sleep_save array
-	ldr	r4, sleep_save
+	stmfd	sp!, {r4 - r12, lr}		@ save registers on stack
 
-	@ save stack pointer
-	str	sp, [r4, #(SLEEP_SAVE_SP*4)]
-
-	@ save coprocessor registers
-	mrc 	p15, 0, r1, c1, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R1*4)]
-	mrc 	p15, 0, r1, c2, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R2*4)]
-	mrc 	p15, 0, r1, c3, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R3*4)]
-	mrc 	p15, 0, r1, c5, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R5*4)]
-	mrc 	p15, 0, r1, c6, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R6*4)]
-	mrc 	p15, 0, r1, c13, c0, 0
-	str	r1, [r4, #(SLEEP_SAVE_CP15_R13*4)]
+	@ get coprocessor registers
+	mrc 	p15, 0, r4, c3, c0, 0		@ domain ID
+	mrc 	p15, 0, r5, c2, c0, 0		@ translation table base addr
+	mrc	p15, 0, r6, c13, c0, 0		@ PID
+	mrc 	p15, 0, r7, c1, c0, 0		@ control reg
+
+	@ store them plus current virtual stack ptr on stack
+	mov	r8, sp
+	stmfd	sp!, {r4 - r8}
+
+	@ preserve phys address of stack
+	mov	r0, sp
+	bl	sleep_phys_sp
+	ldr	r1, =sleep_save_sp
+	str	r0, [r1]
 
 	@ clean data cache and invalidate WB
 	bl	cpu_sa1100_cache_clean_invalidate_all
@@ -72,32 +67,31 @@
 	@ delay 90us and set CPU PLL to lowest speed
 	@ fixes resume problem on high speed SA1110
 	mov	r0, #90
-	bl	SYMBOL_NAME(udelay)
+	bl	SYMBOL_NAME(__udelay)
 	ldr	r0, =PPCR
 	mov	r1, #0
 	str	r1, [r0]
 	mov	r0, #90
-	bl	SYMBOL_NAME(udelay)
+	bl	SYMBOL_NAME(__udelay)
 
-
-/* setup up register contents for jump to page containing SA1110 SDRAM controller bug fix suspend code
- *
- * r0 points to MSC0 register
- * r1 points to MSC1 register
- * r2 points to MSC2 register
- * r3 is MSC0 value
- * r4 is MSC1 value
- * r5 is MSC2 value
- * r6 points to MDREFR register
- * r7 is first MDREFR value
- * r8 is second MDREFR value
- * r9 is pointer to MDCNFG register
- * r10 is MDCNFG value
- * r11 is third MDREFR value
- * r12 is pointer to PMCR register
- * r13 is PMCR value (1)
- *
- */
+	/*
+	 * SA1110 SDRAM controller workaround.  register values:
+	 *
+	 * r0  = &MSC0
+	 * r1  = &MSC1
+	 * r2  = &MSC2
+	 * r3  = MSC0 value
+	 * r4  = MSC1 value
+	 * r5  = MSC2 value
+	 * r6  = &MDREFR
+	 * r7  = first MDREFR value
+	 * r8  = second MDREFR value
+	 * r9  = &MDCNFG
+	 * r10 = MDCNFG value
+	 * r11 = third MDREFR value
+	 * r12 = &PMCR
+	 * r13 = PMCR value (1)
+	 */
 
 	ldr	r0, =MSC0
 	ldr	r1, =MSC1
@@ -170,69 +164,49 @@
  *
  * entry point from bootloader into kernel during resume
  *
+ * Note: Yes, part of the following code is located into the .data section.
+ *       This is to allow sleep_save_sp to be accessed with a relative load
+ *       while we can't rely on any MMU translation.  We could have put
+ *       sleep_save_sp in the .text section as well, but some setups might
+ *       insist on .text to be truely read-only.
  */
 
+	.data
 	.align 5
 ENTRY(sa1100_cpu_resume)
-
-	@ set SVC, irqs off
-	mov	r0, #I_BIT | MODE_SVC
+	mov	r0, #I_BIT | F_BIT | MODE_SVC	@ set SVC, irqs off
 	msr	cpsr_c, r0
 
-	@ load physical address of sleep_save
-	ldr	r4, sleep_save_p
-
-	@ restore cp15_r3, domain id
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R3*4)]
-	mcr 	p15, 0, r1, c3, c0 ,0
-
-	@ restore cp15_r2, translation table base address
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R2*4)]
-	mcr 	p15, 0, r1, c2, c0 ,0
+	ldr	r0, sleep_save_sp		@ stack phys addr
+	ldr	r2, =resume_after_mmu		@ its absolute virtual address
+	ldmfd	r0, {r4 - r7, sp}		@ CP regs + virt stack ptr
 
 	mov	r1, #0
 	mcr	p15, 0, r1, c8, c7, 0   	@ flush I+D TLBs
 	mcr	p15, 0, r1, c7, c7, 0		@ flush I&D cache
+	mcr	p15, 0, r1, c9, c0, 0		@ invalidate RB
+	mcr     p15, 0, r1, c9, c0, 5		@ allow user space to use RB
 
-	@ get saved cp15 r1 (control register)
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R1*4)]
-
-	@ get address to jump to after turning on MMU
-	ldr	r2, =resume_after_mmu
-
-	cmp	r2, #0
-
-	b	resume_turn_on_mmu
+	mcr 	p15, 0, r4, c3, c0, 0		@ domain ID
+	mcr 	p15, 0, r5, c2, c0, 0		@ translation table base addr
+	mcr	p15, 0, r6, c13, c0, 0		@ PID
+	b	resume_turn_on_mmu		@ cache align execution
 
 	.align 5
 resume_turn_on_mmu:
-
-	@ turn on mmu
-	mcr 	p15, 0, r1, c1, c0 ,0
-
-	@ jump to resume_after_mmu
-	mov	pc, r2
+	mcr 	p15, 0, r7, c1, c0, 0		@ turn on MMU, caches, etc.
+	nop
+	mov	pc, r2				@ jump to virtual addr
+	nop
 	nop
 	nop
 
-	.align 5
-resume_after_mmu:
-
-	@ load virtual address for sleep_save array
-	ldr	r4, sleep_save
-
-	@ restore the rest of CPU state
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R13*4)]
-	mcr	p15, 0, r1, c13, c0, 0
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R5*4)]
-	mcr 	p15, 0, r1, c5, c0 ,0
-	ldr	r1, [r4, #(SLEEP_SAVE_CP15_R6*4)]
-	mcr 	p15, 0, r1, c6, c0 ,0
-
-	@ restore stack pointer
-	ldr	sp, [r4, #(SLEEP_SAVE_SP*4)]
+sleep_save_sp:
+	.word	0				@ preserve stack phys ptr here
 
-	@ return to caller
-	ldmfd	sp!, {r4 - r12, pc}
+	.text
+resume_after_mmu:
+	mcr     p15, 0, r1, c15, c1, 2		@ enable clock switching
+	ldmfd	sp!, {r4 - r12, pc}		@ return to caller
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/sleep.h linux-2.4.22-pre10/arch/arm/mach-sa1100/sleep.h
--- linux-2.4.21/arch/arm/mach-sa1100/sleep.h	2001-10-25 20:53:46.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/sleep.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,30 +0,0 @@
-/*
- * Offsets for register values preserved in RAM while in sleep mode
- */
-
-#define SLEEP_SAVE_OSCR		0
-#define SLEEP_SAVE_OSMR0	1
-#define SLEEP_SAVE_OSMR1	2
-#define SLEEP_SAVE_OSMR2	3
-#define SLEEP_SAVE_OSMR3	4
-#define SLEEP_SAVE_OIER		5
-#define SLEEP_SAVE_GPDR		6
-#define SLEEP_SAVE_GRER		7
-#define SLEEP_SAVE_GFER		8
-#define SLEEP_SAVE_GAFR		9
-#define SLEEP_SAVE_PPDR		10
-#define SLEEP_SAVE_PPSR		11
-#define SLEEP_SAVE_PPAR		12
-#define SLEEP_SAVE_PSDR		13
-#define SLEEP_SAVE_Ser1SDCR0	14
-#define SLEEP_SAVE_ICMR		15
-#define SLEEP_SAVE_SP		16
-#define SLEEP_SAVE_CP15_R1	17
-#define SLEEP_SAVE_CP15_R2	18
-#define SLEEP_SAVE_CP15_R3	19
-#define SLEEP_SAVE_CP15_R5	20
-#define SLEEP_SAVE_CP15_R6	21
-#define SLEEP_SAVE_CP15_R13	22
-
-#define SLEEP_SAVE_SIZE		23
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/ssp.c linux-2.4.22-pre10/arch/arm/mach-sa1100/ssp.c
--- linux-2.4.21/arch/arm/mach-sa1100/ssp.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/ssp.c	2003-08-01 13:31:48.000000000 +0000
@@ -0,0 +1,208 @@
+/*
+ *  linux/arch/arm/mach-sa1100/ssp.c
+ *
+ *  Copyright (C) 2003 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Generic SSP driver.  This provides the generic core for simple
+ *  IO-based SSP applications.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/hardware/ssp.h>
+
+static void ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int status = Ser4SSSR;
+
+	if (status & SSSR_ROR) {
+		printk(KERN_WARNING "SSP: receiver overrun\n");
+	}
+
+	Ser4SSSR = SSSR_ROR;
+}
+
+/**
+ * ssp_write_word - write a word to the SSP port
+ * @data: 16-bit, MSB justified data to write.
+ *
+ * Wait for a free entry in the SSP transmit FIFO, and write a data
+ * word to the SSP port.
+ *
+ * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ *   %-ETIMEDOUT	timeout occurred (for future)
+ *   0			success
+ */
+int ssp_write_word(u16 data)
+{
+	while (!(Ser4SSSR & SSSR_TNF))
+		cpu_relax();
+
+	Ser4SSDR = data;
+
+	return 0;
+}
+
+/**
+ * ssp_read_word - read a word from the SSP port
+ *
+ * Wait for a data word in the SSP receive FIFO, and return the
+ * received data.  Data is LSB justified.
+ *
+ * Note: Currently, if data is not expected to be received, this
+ * function will wait for ever.
+ *
+ * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ *   %-ETIMEDOUT	timeout occurred (for future)
+ *   16-bit data	success
+ */
+int ssp_read_word(void)
+{
+	while (!(Ser4SSSR & SSSR_RNE))
+		cpu_relax();
+
+	return Ser4SSDR;
+}
+
+/**
+ * ssp_flush - flush the transmit and receive FIFOs
+ *
+ * Wait for the SSP to idle, and ensure that the receive FIFO
+ * is empty.
+ *
+ * The caller is expected to perform the necessary locking.
+ */
+void ssp_flush(void)
+{
+	do {
+		while (Ser4SSSR & SSSR_RNE) {
+			(void) Ser4SSDR;
+		}
+	} while (Ser4SSSR & SSSR_BSY);
+}
+
+/**
+ * ssp_enable - enable the SSP port
+ *
+ * Turn on the SSP port.
+ */
+void ssp_enable(void)
+{
+	Ser4SSCR0 |= SSCR0_SSE;
+}
+
+/**
+ * ssp_disable - shut down the SSP port
+ *
+ * Turn off the SSP port, optionally powering it down.
+ */
+void ssp_disable(void)
+{
+	Ser4SSCR0 &= ~SSCR0_SSE;
+}
+
+/**
+ * ssp_save_state - save the SSP configuration
+ * @ssp: pointer to structure to save SSP configuration
+ *
+ * Save the configured SSP state for suspend.
+ */
+void ssp_save_state(struct ssp_state *ssp)
+{
+	ssp->cr0 = Ser4SSCR0;
+	ssp->cr1 = Ser4SSCR1;
+
+	Ser4SSCR0 &= ~SSCR0_SSE;
+}
+
+/**
+ * ssp_restore_state - restore a previously saved SSP configuration
+ * @ssp: pointer to configuration saved by ssp_save_state
+ *
+ * Restore the SSP configuration saved previously by ssp_save_state.
+ */
+void ssp_restore_state(struct ssp_state *ssp)
+{
+	Ser4SSSR = SSSR_ROR;
+
+	Ser4SSCR0 = ssp->cr0 & ~SSCR0_SSE;
+	Ser4SSCR1 = ssp->cr1;
+	Ser4SSCR0 = ssp->cr0;
+}
+
+/**
+ * ssp_init - setup the SSP port
+ *
+ * initialise and claim resources for the SSP port.
+ *
+ * Returns:
+ *   %-ENODEV	if the SSP port is unavailable
+ *   %-EBUSY	if the resources are already in use
+ *   %0		on success
+ */
+int ssp_init(void)
+{
+	int ret;
+
+	if (!(PPAR & PPAR_SPR) && (Ser4MCCR0 & MCCR0_MCE))
+		return -ENODEV;
+
+	if (!request_mem_region(__PREG(Ser4SSCR0), 0x18, "SSP")) {
+		return -EBUSY;
+	}
+
+	Ser4SSSR = SSSR_ROR;
+
+	ret = request_irq(IRQ_Ser4SSP, ssp_interrupt, 0, "SSP", NULL);
+	if (ret)
+		goto out_region;
+
+	return 0;
+
+ out_region:
+	release_mem_region(__PREG(Ser4SSCR0), 0x18);
+	return ret;
+}
+
+/**
+ * ssp_exit - undo the effects of ssp_init
+ *
+ * release and free resources for the SSP port.
+ */
+void ssp_exit(void)
+{
+	Ser4SSCR0 &= ~SSCR0_SSE;
+
+	free_irq(IRQ_Ser4SSP, NULL);
+	release_mem_region(__PREG(Ser4SSCR0), 0x18);
+}
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SA11x0 SSP PIO driver");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(ssp_write_word);
+EXPORT_SYMBOL(ssp_read_word);
+EXPORT_SYMBOL(ssp_flush);
+EXPORT_SYMBOL(ssp_enable);
+EXPORT_SYMBOL(ssp_disable);
+EXPORT_SYMBOL(ssp_save_state);
+EXPORT_SYMBOL(ssp_restore_state);
+EXPORT_SYMBOL(ssp_init);
+EXPORT_SYMBOL(ssp_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mach-sa1100/system3.c linux-2.4.22-pre10/arch/arm/mach-sa1100/system3.c
--- linux-2.4.21/arch/arm/mach-sa1100/system3.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mach-sa1100/system3.c	2003-08-01 13:30:32.000000000 +0000
@@ -42,6 +42,8 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/cpufreq.h>
+#include <linux/list.h>
+#include <linux/timer.h>
 
 #include <asm/hardware.h>
 #include <asm/setup.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/Makefile linux-2.4.22-pre10/arch/arm/mm/Makefile
--- linux-2.4.21/arch/arm/mm/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/Makefile	2003-08-01 13:35:08.000000000 +0000
@@ -36,8 +36,10 @@
 p-$(CONFIG_CPU_ARM720T)	+= proc-arm720.o
 p-$(CONFIG_CPU_ARM920T)	+= proc-arm920.o
 p-$(CONFIG_CPU_ARM922T)	+= proc-arm922.o
+p-$(CONFIG_CPU_ARM925T)	+= proc-arm925.o
 p-$(CONFIG_CPU_ARM926T)	+= proc-arm926.o
 p-$(CONFIG_CPU_ARM1020)	+= proc-arm1020.o
+p-$(CONFIG_CPU_ARM1026)	+= proc-arm1026.o
 p-$(CONFIG_CPU_SA110)	+= proc-sa110.o
 p-$(CONFIG_CPU_SA1100)	+= proc-sa110.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/alignment.c linux-2.4.22-pre10/arch/arm/mm/alignment.c
--- linux-2.4.21/arch/arm/mm/alignment.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/alignment.c	2003-08-01 13:33:12.000000000 +0000
@@ -426,13 +426,13 @@
 		eaddr += 4;
 
 	/* 
-	 * For alignment faults on the ARM922T the MMU  makes 
+	 * For alignment faults on the ARM922T/ARM920T the MMU  makes
 	 * the FSR (and hence addr) equal to the updated base address
 	 * of the multiple access rather than the restored value.
-	 * Switch this messsage off if we've got a ARM922, otherwise
+	 * Switch this messsage off if we've got a ARM92[02], otherwise
 	 * [ls]dm alignment faults are noisy!
 	 */
-#if !(defined CONFIG_CPU_ARM922T)  
+#if !(defined CONFIG_CPU_ARM922T)  && !(defined CONFIG_CPU_ARM920T)
 	/*
 	 * This is a "hint" - we already have eaddr worked out by the
 	 * processor for us.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/consistent.c linux-2.4.22-pre10/arch/arm/mm/consistent.c
--- linux-2.4.21/arch/arm/mm/consistent.c	2001-06-27 21:12:04.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/consistent.c	2003-08-01 13:31:57.000000000 +0000
@@ -30,14 +30,20 @@
  * now, we expressly forbid it, especially as some of the stuff we do
  * here is not interrupt context safe.
  *
+ * We should allow this function to be called from interrupt context.
+ * However, we call ioremap, which needs to fiddle around with various
+ * things (like the vmlist_lock, and allocating page tables).  These
+ * things aren't interrupt safe (yet).
+ *
  * Note that this does *not* zero the allocated area!
  */
 void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
 {
 	struct page *page, *end, *free;
 	unsigned long order;
-	void *ret, *virt;
+	void *ret;
 
+	/* FIXME */
 	if (in_interrupt())
 		BUG();
 
@@ -48,22 +54,22 @@
 	if (!page)
 		goto no_page;
 
-	/*
-	 * We could do with a page_to_phys and page_to_bus here.
-	 */
-	virt = page_address(page);
-	*dma_handle = virt_to_bus(virt);
-	ret = __ioremap(virt_to_phys(virt), size, 0);
+	*dma_handle = page_to_bus(page);
+	ret = __ioremap(page_to_pfn(page) << PAGE_SHIFT, size, 0);
 	if (!ret)
 		goto no_remap;
 
 #if 0 /* ioremap_does_flush_cache_all */
-	/*
-	 * we need to ensure that there are no cachelines in use, or
-	 * worse dirty in this area.  Really, we don't need to do
-	 * this since __ioremap does a flush_cache_all() anyway. --rmk
-	 */
-	invalidate_dcache_range(virt, virt + size);
+	{
+		void *virt = page_address(page);
+
+		/*
+		 * we need to ensure that there are no cachelines in use, or
+		 * worse dirty in this area.  Really, we don't need to do
+		 * this since __ioremap does a flush_cache_all() anyway. --rmk
+		 */
+		invalidate_dcache_range(virt, virt + size);
+	}
 #endif
 
 	/*
@@ -72,7 +78,6 @@
 	 * We also mark the pages in use as reserved so that
 	 * remap_page_range works.
 	 */
-	page = virt_to_page(virt);
 	free = page + (size >> PAGE_SHIFT);
 	end  = page + (1 << order);
 
@@ -93,18 +98,15 @@
 
 void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handle)
 {
-	void *__ret;
-	int __gfp = GFP_KERNEL;
+	int gfp = GFP_KERNEL;
 
-#ifdef CONFIG_PCI
-	if ((hwdev) == NULL ||
+#if defined(CONFIG_PCI) || defined(CONFIG_SA1111)
+	if ((hwdev) == NULL || dev_is_sa1111(hwdev) ||
 	    (hwdev)->dma_mask != 0xffffffff)
 #endif
-		__gfp |= GFP_DMA;
+		gfp |= GFP_DMA;
 
-	__ret = consistent_alloc(__gfp, (size),
-				 (handle));
-	return __ret;
+	return consistent_alloc(gfp, size, handle);
 }
 
 /*
@@ -114,19 +116,16 @@
 void consistent_free(void *vaddr, size_t size, dma_addr_t handle)
 {
 	struct page *page, *end;
-	void *virt;
 
 	if (in_interrupt())
 		BUG();
 
-	virt = bus_to_virt(handle);
-
 	/*
 	 * More messing around with the MM internals.  This is
 	 * sick, but then so is remap_page_range().
 	 */
 	size = PAGE_ALIGN(size);
-	page = virt_to_page(virt);
+	page = virt_to_page(bus_to_virt(handle));
 	end = page + (size >> PAGE_SHIFT);
 
 	for (; page < end; page++)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/fault-armv.c linux-2.4.22-pre10/arch/arm/mm/fault-armv.c
--- linux-2.4.21/arch/arm/mm/fault-armv.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/fault-armv.c	2003-08-01 13:31:52.000000000 +0000
@@ -28,7 +28,6 @@
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 
-extern void die_if_kernel(const char *str, struct pt_regs *regs, int err);
 extern void show_pte(struct mm_struct *mm, unsigned long addr);
 extern int do_page_fault(unsigned long addr, int error_code,
 			 struct pt_regs *regs);
@@ -236,9 +235,13 @@
  */
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
 {
-	struct page *page = pte_page(pte);
+	unsigned long pfn = pte_pfn(pte);
+	struct page *page;
 
-	if (VALID_PAGE(page) && page->mapping) {
+	if (!pfn_valid(pfn))
+		return;
+	page = pfn_to_page(pfn);
+	if (page->mapping) {
 		if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) {
 			unsigned long kvirt = (unsigned long)page_address(page);
 			cpu_cache_clean_invalidate_range(kvirt, kvirt + PAGE_SIZE, 0);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/fault-common.c linux-2.4.22-pre10/arch/arm/mm/fault-common.c
--- linux-2.4.21/arch/arm/mm/fault-common.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/fault-common.c	2003-08-01 13:30:44.000000000 +0000
@@ -43,52 +43,77 @@
 #define READ_FAULT(m)		(!(m))
 #endif
 
-NORET_TYPE void die(const char *msg, struct pt_regs *regs, int err) ATTRIB_NORET;
-
 /*
  * This is useful to dump out the page tables associated with
  * 'addr' in mm 'mm'.
  */
 void show_pte(struct mm_struct *mm, unsigned long addr)
 {
-	pgd_t *pgd;
+	mm_segment_t fs;
 
 	if (!mm)
 		mm = &init_mm;
 
-	printk(KERN_ALERT "pgd = %p\n", mm->pgd);
-	pgd = pgd_offset(mm, addr);
-	printk(KERN_ALERT "*pgd = %08lx", pgd_val(*pgd));
+	printk(KERN_ALERT "mm = %p pgd = %p\n", mm, mm->pgd);
 
+	fs = get_fs();
+	set_fs(get_ds());
 	do {
-		pmd_t *pmd;
-		pte_t *pte;
+		pgd_t pg, *pgd = pgd_offset(mm, addr);
+		pmd_t pm, *pmd;
+		pte_t pt, *pte;
+
+		printk(KERN_ALERT "*pgd = ");
 
-		if (pgd_none(*pgd))
+		if (__get_user(pgd_val(pg), (unsigned long *)pgd)) {
+			printk("(faulted)");
 			break;
+		}
 
-		if (pgd_bad(*pgd)) {
+		printk("%08lx", pgd_val(pg));
+
+		if (pgd_none(pg))
+			break;
+
+		if (pgd_bad(pg)) {
 			printk("(bad)");
 			break;
 		}
 
 		pmd = pmd_offset(pgd, addr);
-		printk(", *pmd = %08lx", pmd_val(*pmd));
 
-		if (pmd_none(*pmd))
+		printk(", *pmd = ");
+
+		if (__get_user(pmd_val(pm), (unsigned long *)pmd)) {
+			printk("(faulted)");
+			break;
+		}
+
+		printk("%08lx", pmd_val(pm));
+
+		if (pmd_none(pm))
 			break;
 
-		if (pmd_bad(*pmd)) {
+		if (pmd_bad(pm)) {
 			printk("(bad)");
 			break;
 		}
 
 		pte = pte_offset(pmd, addr);
-		printk(", *pte = %08lx", pte_val(*pte));
+
+		printk(", *pte = ");
+
+		if (__get_user(pte_val(pt), (unsigned long *)pte)) {
+			printk("(faulted)");
+			break;
+		}
+
+		printk("%08lx", pte_val(pt));
 #ifdef CONFIG_CPU_32
 		printk(", *ppte = %08lx", pte_val(pte[-PTRS_PER_PTE]));
 #endif
 	} while(0);
+	set_fs(fs);
 
 	printk("\n");
 }
@@ -345,6 +370,9 @@
 
 	offset = __pgd_offset(addr);
 
+	/*
+	 * FIXME: CP15 C1 is write only on ARMv3 architectures.
+	 */
 	pgd = cpu_get_pgd() + offset;
 	pgd_k = init_mm.pgd + offset;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/init.c linux-2.4.22-pre10/arch/arm/mm/init.c
--- linux-2.4.21/arch/arm/mm/init.c	2001-10-11 16:04:57.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/init.c	2003-08-01 13:31:01.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/mm/init.c
  *
- *  Copyright (C) 1995-2000 Russell King
+ *  Copyright (C) 1995-2002 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -46,11 +46,13 @@
 #define TABLE_OFFSET	0
 #endif
 
-#define TABLE_SIZE	((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *))
+#define TABLE_SIZE	((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(pte_t))
 
 static unsigned long totalram_pages;
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 extern char _stext, _text, _etext, _end, __init_begin, __init_end;
+extern unsigned long phys_initrd_start;
+extern unsigned long phys_initrd_size;
 
 /*
  * The sole use of this is to pass memory configuration
@@ -292,6 +294,7 @@
 	 * also get rid of some of the stuff above as well.
 	 */
 	max_low_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
+//	max_pfn = memend_pfn - O_PFN_DOWN(PHYS_OFFSET);
 	mi->end = memend_pfn << PAGE_SHIFT;
 
 	return bootmem_pages;
@@ -302,16 +305,16 @@
 	int initrd_node = -2;
 
 #ifdef CONFIG_BLK_DEV_INITRD
+	unsigned long end = phys_initrd_start + phys_initrd_size;
+
 	/*
 	 * Make sure that the initrd is within a valid area of
 	 * memory.
 	 */
-	if (initrd_start) {
-		unsigned long phys_initrd_start, phys_initrd_end;
+	if (phys_initrd_size) {
 		unsigned int i;
 
-		phys_initrd_start = __pa(initrd_start);
-		phys_initrd_end   = __pa(initrd_end);
+		initrd_node = -1;
 
 		for (i = 0; i < mi->nr_banks; i++) {
 			unsigned long bank_end;
@@ -319,7 +322,7 @@
 			bank_end = mi->bank[i].start + mi->bank[i].size;
 
 			if (mi->bank[i].start <= phys_initrd_start &&
-			    phys_initrd_end <= bank_end)
+			    end <= bank_end)
 				initrd_node = mi->bank[i].node;
 		}
 	}
@@ -327,8 +330,8 @@
 	if (initrd_node == -1) {
 		printk(KERN_ERR "initrd (0x%08lx - 0x%08lx) extends beyond "
 		       "physical memory - disabling initrd\n",
-		       initrd_start, initrd_end);
-		initrd_start = initrd_end = 0;
+		       phys_initrd_start, end);
+		phys_initrd_start = phys_initrd_size = 0;
 	}
 #endif
 
@@ -354,7 +357,7 @@
 	 * and can only be in node 0.
 	 */
 	reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
-			     PTRS_PER_PGD * sizeof(void *));
+			     PTRS_PER_PGD * sizeof(pgd_t));
 #endif
 	/*
 	 * And don't forget to reserve the allocator bitmap,
@@ -378,7 +381,7 @@
 	 */
 	if (machine_is_archimedes() || machine_is_a5k())
 		reserve_bootmem_node(pgdat, 0x02000000, 0x00080000);
-	if (machine_is_edb7211())
+	if (machine_is_edb7211() || machine_is_fortunet())
 		reserve_bootmem_node(pgdat, 0xc0000000, 0x00020000);
 	if (machine_is_p720t())
 		reserve_bootmem_node(pgdat, PHYS_OFFSET, 0x00014000);
@@ -469,9 +472,12 @@
 
 
 #ifdef CONFIG_BLK_DEV_INITRD
-	if (initrd_node >= 0)
-		reserve_bootmem_node(NODE_DATA(initrd_node), __pa(initrd_start),
-				     initrd_end - initrd_start);
+	if (phys_initrd_size && initrd_node >= 0) {
+		reserve_bootmem_node(NODE_DATA(initrd_node), phys_initrd_start,
+				     phys_initrd_size);
+		initrd_start = __phys_to_virt(phys_initrd_start);
+		initrd_end = initrd_start + phys_initrd_size;
+	}
 #endif
 
 	if (map_pg != bootmap_pfn + bootmap_pages)
@@ -501,6 +507,7 @@
 	memtable_init(mi);
 	if (mdesc->map_io)
 		mdesc->map_io();
+	flush_cache_all();
 	flush_tlb_all();
 
 	/*
@@ -583,7 +590,7 @@
 	}
 
 	if (size && s)
-		printk("Freeing %s memory: %dK\n", s, size);
+		printk(KERN_INFO "Freeing %s memory: %dK\n", s, size);
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/ioremap.c linux-2.4.22-pre10/arch/arm/mm/ioremap.c
--- linux-2.4.21/arch/arm/mm/ioremap.c	2001-04-12 19:20:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/ioremap.c	2003-08-01 13:33:51.000000000 +0000
@@ -8,24 +8,19 @@
  * Hacked for ARM by Phil Blundell <philb@gnu.org>
  * Hacked to allow all architectures to build, and various cleanups
  * by Russell King
- */
-
-/*
+ *
  * This allows a driver to remap an arbitrary region of bus memory into
  * virtual space.  One should *only* use readl, writel, memcpy_toio and
  * so on with such remapped areas.
  *
- * Because the ARM only has a 32-bit address space we can't address the
- * whole of the (physical) PCI space at once.  PCI huge-mode addressing
- * allows us to circumvent this restriction by splitting PCI space into
- * two 2GB chunks and mapping only one at a time into processor memory.
- * We use MMU protection domains to trap any attempt to access the bank
- * that is not currently mapped.  (This isn't fully implemented yet.)
- *
- * DC21285 currently has a bug in that the PCI address extension
- * register affects the address of any writes waiting in the outbound
- * FIFO.  Unfortunately, it is not possible to tell the DC21285 to
- * flush this - flushing the area causes the bus to lock.
+ * ioremap support tweaked to allow support for large page mappings.  We
+ * have several issues that needs to be resolved first however:
+ *
+ *  1. We need set_pte, or something like set_pte to understand large
+ *     page mappings.
+ *
+ *  2. we need the unmap_* functions to likewise understand large page
+ *     mappings.
  */
 #include <linux/errno.h>
 #include <linux/mm.h>
@@ -35,8 +30,9 @@
 #include <asm/pgalloc.h>
 #include <asm/io.h>
 
-static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
-	unsigned long phys_addr, pgprot_t pgprot)
+static inline void
+remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
+	       unsigned long pfn, pgprot_t pgprot)
 {
 	unsigned long end;
 
@@ -44,22 +40,26 @@
 	end = address + size;
 	if (end > PMD_SIZE)
 		end = PMD_SIZE;
-	if (address >= end)
-		BUG();
+	BUG_ON(address >= end);
 	do {
-		if (!pte_none(*pte)) {
-			printk("remap_area_pte: page already exists\n");
-			BUG();
-		}
-		set_pte(pte, mk_pte_phys(phys_addr, pgprot));
+		if (!pte_none(*pte))
+			goto bad;
+
+		set_pte(pte, pfn_pte(pfn, pgprot));
 		address += PAGE_SIZE;
-		phys_addr += PAGE_SIZE;
+		pfn++;
 		pte++;
 	} while (address && (address < end));
+	return;
+
+ bad:
+	printk("remap_area_pte: page already exists\n");
+	BUG();
 }
 
-static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
-	unsigned long phys_addr, unsigned long flags)
+static inline int
+remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
+	       unsigned long pfn, unsigned long flags)
 {
 	unsigned long end;
 	pgprot_t pgprot;
@@ -70,34 +70,33 @@
 	if (end > PGDIR_SIZE)
 		end = PGDIR_SIZE;
 
-	phys_addr -= address;
-	if (address >= end)
-		BUG();
+	pfn -= address >> PAGE_SHIFT;
+	BUG_ON(address >= end);
 
 	pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
 	do {
 		pte_t * pte = pte_alloc(&init_mm, pmd, address);
 		if (!pte)
 			return -ENOMEM;
-		remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
+		remap_area_pte(pte, address, end - address, pfn + (address >> PAGE_SHIFT), pgprot);
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
 	} while (address && (address < end));
 	return 0;
 }
 
-static int remap_area_pages(unsigned long address, unsigned long phys_addr,
-				 unsigned long size, unsigned long flags)
+static int
+remap_area_pages(unsigned long address, unsigned long pfn,
+		 unsigned long size, unsigned long flags)
 {
 	int error;
 	pgd_t * dir;
 	unsigned long end = address + size;
 
-	phys_addr -= address;
+	pfn -= address >> PAGE_SHIFT;
 	dir = pgd_offset(&init_mm, address);
 	flush_cache_all();
-	if (address >= end)
-		BUG();
+	BUG_ON(address >= end);
 	spin_lock(&init_mm.page_table_lock);
 	do {
 		pmd_t *pmd;
@@ -106,7 +105,7 @@
 		if (!pmd)
 			break;
 		if (remap_area_pmd(pmd, address, end - address,
-					 phys_addr + address, flags))
+					 pfn + (address >> PAGE_SHIFT), flags))
 			break;
 		error = 0;
 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
@@ -154,7 +153,7 @@
 	if (!area)
 		return NULL;
 	addr = area->addr;
-	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
+	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr >> PAGE_SHIFT, size, flags)) {
 		vfree(addr);
 		return NULL;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/mm-armv.c linux-2.4.22-pre10/arch/arm/mm/mm-armv.c
--- linux-2.4.21/arch/arm/mm/mm-armv.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/mm-armv.c	2003-08-01 13:33:52.000000000 +0000
@@ -200,7 +200,7 @@
 	}
 	ptep = pte_offset(pmdp, virt);
 
-	set_pte(ptep, mk_pte_phys(phys, __pgprot(prot)));
+	set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, __pgprot(prot)));
 }
 
 /*
@@ -388,8 +388,6 @@
 	init_maps->bufferable = 0;
 
 	create_mapping(init_maps);
-
-	flush_cache_all();
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/mm-riscstation.c linux-2.4.22-pre10/arch/arm/mm/mm-riscstation.c
--- linux-2.4.21/arch/arm/mm/mm-riscstation.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/mm-riscstation.c	2003-08-01 13:33:51.000000000 +0000
@@ -0,0 +1,35 @@
+/*
+ *  linux/arch/arm/mm/mm-rpc.c
+ *  linux/arch/arm/mm/mm-riscstation.c
+ *
+ *  Copyright (C) 1998-1999 Russell King
+ *  Copyright (C) 2002 Simtec Electronics / Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Extra MM routines for RiscStation
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/page.h>
+#include <asm/proc/domain.h>
+#include <asm/setup.h>
+
+#include <asm/mach/map.h>
+
+/* map the EASI space to use for the ISA slot */
+
+static struct map_desc riscstation_io_desc[] __initdata = {
+ { IO_BASE,	IO_START,	IO_SIZE	 , DOMAIN_IO, 0, 1, 0, 0 }, /* IO space		*/
+ { EASI_BASE,	EASI_START,	EASI_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, /* EASI space	*/
+ LAST_DESC
+};
+
+void __init riscstation_map_io(void)
+{
+	iotable_init(riscstation_io_desc);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/proc-arm1020.S linux-2.4.22-pre10/arch/arm/mm/proc-arm1020.S
--- linux-2.4.21/arch/arm/mm/proc-arm1020.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/proc-arm1020.S	2003-08-01 13:30:55.000000000 +0000
@@ -135,7 +135,7 @@
 	.align	5
 ENTRY(cpu_arm1020_do_idle)
 	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -156,7 +156,7 @@
 ENTRY(cpu_arm1020_cache_clean_invalidate_all)
 	mov	r2, #1
 cpu_arm1020_cache_clean_invalidate_all_r2:
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, ip, c7, c10, 4
 
 	mov	r1, #0xf			@ 16 segments
@@ -165,7 +165,7 @@
 	orr	ip, ip, r1, LSL #5		@ shift in/up index
 	mcr	p15, 0, ip, c7, c14, 2		@ Clean & Inval DCache entry
 	mcr	p15, 0, ip, c7, c10, 4		@ drain WB 
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	ip, ip
 #endif
 	subs	r3, r3, #1
@@ -176,12 +176,12 @@
 	bge	1b				@ segments 7 to 0
 #endif
         
-#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	teq	r2, #0
 	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
 #endif
 	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	ip, ip
 	mov	ip, ip
 #endif
@@ -203,13 +203,13 @@
 	cmp	r3, #MAX_AREA_SIZE
 	bgt	cpu_arm1020_cache_clean_invalidate_all_r2
 	mcr	p15, 0, r3, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	add	r0, r0, #DCACHELINESIZE
@@ -217,11 +217,11 @@
 	blt	1b
 #endif
 
-#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	teq	r2, #0
 	movne	r0, #0
 	mcrne	p15, 0, r0, c7, c5, 0		@ invalidate I cache
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -238,14 +238,14 @@
 	.align	5
 ENTRY(cpu_arm1020_flush_ram_page)
 	mcr	p15, 0, r1, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mov	r1, #PAGESIZE
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -254,7 +254,7 @@
 	mov	r0, #0
 
 #endif
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -275,14 +275,14 @@
  */
 	.align	5
 ENTRY(cpu_arm1020_dcache_invalidate_range)
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	/* D cache are on */
 	tst	r0, #DCACHELINESIZE - 1
 	bic	r0, r0, #DCACHELINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 4
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry at start
 	mcrne	p15, 0, r0, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -290,14 +290,14 @@
 	mcrne	p15, 0, r1, c7, c10, 4
 	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry at end
 	mcrne	p15, 0, r1, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r1, r1
 	mov	r1, r1
 	mov	r1, r1
 #endif
         
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	add	r0, r0, #DCACHELINESIZE
@@ -306,7 +306,7 @@
 #else
 	/* D cache off, but still drain the write buffer */
 	mcr	p15, 0, r0, c7, c10, 4		@ Drain write buffer
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -330,13 +330,13 @@
 	cmp	r3, #MAX_AREA_SIZE
 	bgt	cpu_arm1020_cache_clean_invalidate_all_r2
 	mcr	p15, 0, r3, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	add	r0, r0, #DCACHELINESIZE
@@ -344,7 +344,7 @@
 	blt	1b
 #endif
 
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -367,23 +367,23 @@
 ENTRY(cpu_arm1020_dcache_clean_page)
 	mov	r1, #PAGESIZE
 	mcr	p15, 0, r0, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry  (drain is done by TLB fns)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	add	r0, r0, #DCACHELINESIZE
 	subs	r1, r1, #2 * DCACHELINESIZE
 	bhi	1b
 #endif
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -401,14 +401,14 @@
 ENTRY(cpu_arm1020_dcache_clean_entry)
 	mov	r1, #0
 	mcr	p15, 0, r1, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r0, c7, c10, 1		@ clean single D entry
 	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
 #endif
-#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	mcr	p15, 0, r1, c7, c5, 1		@ invalidate I entry
 #endif
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r1, r1
 	mov	r1, r1
 #endif
@@ -427,14 +427,14 @@
 	.align	5
 ENTRY(cpu_arm1020_icache_invalidate_range)
 1:	mcr	p15, 0, r0, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r0, c7, c10, 1		@ Clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c10, 1		@ Clean D entry
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 #endif
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	add	r0, r0, #DCACHELINESIZE
@@ -442,7 +442,7 @@
 	blo	1b
 ENTRY(cpu_arm1020_icache_invalidate_page)
 	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -460,7 +460,7 @@
 	mov	r0, #0
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I & D tlbs
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -476,12 +476,15 @@
  */
 	.align	5
 ENTRY(cpu_arm1020_tlb_invalidate_range)
+	sub	r3, r1, r0
+	cmp	r3, #256 * PAGESIZE
+	bhi	cpu_arm1020_tlb_invalidate_all
 	mov	r3, #0
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 1:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
 	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
 	add	r0, r0, #PAGESIZE
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 #endif
 	cmp	r0, r1
@@ -500,14 +503,14 @@
 ENTRY(cpu_arm1020_tlb_invalidate_page)
 	mov	r3, #0
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
 	teq	r1, #0
 	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
 	mcrne	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -524,7 +527,7 @@
  */
 	.align	5
 ENTRY(cpu_arm1020_set_pgd)
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r3, c7, c10, 4
 	mov	r1, #0xF			@ 16 segments
 1:	mov	r3, #0x3F			@ 64 entries
@@ -533,7 +536,7 @@
 	mcr	p15, 0, ip, c7, c14, 2		@ Clean & Inval DCache entry
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c10, 4
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	ip, ip
 #endif
 	subs	r3, r3, #1
@@ -545,13 +548,13 @@
 
 #endif
 	mov	r1, #0
-#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	mcr	p15, 0, r1, c7, c5, 0		@ invalidate I cache
 #endif
 	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
 	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
 	mcr	p15, 0, r1, c8, c7, 0		@ invalidate I & D TLBs
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	ip, ip
 	mov	ip, ip
 #endif
@@ -568,18 +571,18 @@
  */
 	.align	5
 ENTRY(cpu_arm1020_set_pmd)
-#ifdef CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r2, r1, #0x0a			@ C & Section
 	tst	r2, #0x0b
 	biceq	r1, r1, #4			@ clear bufferable bit
 #endif
 	str	r1, [r0]
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r0, c7, c10, 4
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry  (drain is done by TLB fns)
 #endif
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
@@ -609,47 +612,42 @@
 	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
 	movne	r2, #0
 
-#ifdef CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r3, r1, #0x0a			@ C & small page?
 	tst	r3, #0x0b
 	biceq	r2, r2, #4
 #endif
 	str	r2, [r0]			@ hardware version
 	mov	r0, r0
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	mcr	p15, 0, r0, c7, c10, 4
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 #endif
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	mov	r0, r0
 	mov	r0, r0
 #endif
 	mov	pc, lr
 
 
-cpu_manu_name:
-	.asciz	"ARM/VLSI"
 ENTRY(cpu_arm1020_name)
 	.ascii	"Arm1020"
-#if defined(CONFIG_CPU_ARM1020_CPU_IDLE)
-	.ascii	"s"
-#endif
-#if defined(CONFIG_CPU_ARM1020_I_CACHE_ON)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	.ascii	"i"
 #endif
-#if defined(CONFIG_CPU_ARM1020_D_CACHE_ON)
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	.ascii	"d"
-#if defined(CONFIG_CPU_ARM1020_FORCE_WRITE_THROUGH)
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	.ascii	"(wt)"
 #else
 	.ascii	"(wb)"
 #endif
 #endif
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	.ascii	"B"
 #endif
-#ifdef CONFIG_CPU_ARM1020_ROUND_ROBIN
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	.ascii	"RR"
 #endif
 	.ascii	"\0"
@@ -679,16 +677,16 @@
 	orr	r0, r0, #0x0031 		@ ..........DP...M
 	orr	r0, r0, #0x0100 		@ .......S........
 
-#ifdef CONFIG_CPU_ARM1020_ROUND_ROBIN
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	orr	r0, r0, #0x4000 		@ .R..............
 #endif
-#ifdef CONFIG_CPU_ARM1020_BRANCH_PREDICTION
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
 	orr	r0, r0, #0x0800 		@ ....Z...........
 #endif
-#ifdef CONFIG_CPU_ARM1020_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	orr	r0, r0, #0x0004 		@ Enable D cache
 #endif
-#ifdef CONFIG_CPU_ARM1020_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	orr	r0, r0, #0x1000 		@ I Cache on
 #endif
 	mov	pc, lr
@@ -736,7 +734,7 @@
 
 	.type	cpu_arm1020_info, #object
 cpu_arm1020_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_arm1020_name
 	.size	cpu_arm1020_info, . - cpu_arm1020_info
 
@@ -761,7 +759,7 @@
 	b	__arm1020_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
-	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
 	.long	cpu_arm1020_info
 	.long	arm1020_processor_functions
 	.size	__arm1020_proc_info, . - __arm1020_proc_info
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/proc-arm1026.S linux-2.4.22-pre10/arch/arm/mm/proc-arm1026.S
--- linux-2.4.21/arch/arm/mm/proc-arm1026.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/proc-arm1026.S	2003-08-01 13:33:53.000000000 +0000
@@ -0,0 +1,660 @@
+/*
+ *  linux/arch/arm/mm/arm1026.S: MMU functions for ARM1026EJ-S
+ *
+ *  Copyright (C) 2002 ARM Limited
+ *  Copyright (C) 2002 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the arm1026.
+ */
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions.  Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define MAX_AREA_SIZE	16384
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define DCACHELINESIZE	32
+#define ICACHELINESIZE	32
+
+/*
+ * and the page size
+ */
+#define PAGESIZE	4096
+
+	.text
+
+/*
+ * cpu_arm1026_data_abort()
+ *
+ * obtain information about current aborted instruction
+ * Note: we read user space.  This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture.  Unfortunately, this does happen.  We live with it.
+ *
+ * Inputs:
+ *  r2 = address of abort 
+ *  r3 = cpsr of abort
+ *
+ * Returns:
+ *  r0 = address of abort
+ *  r1 != 0 if writing
+ *  r3 = FSR
+ *  r4 = corrupted
+ */
+	.align	5
+ENTRY(cpu_arm1026_data_abort)
+	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
+	and	r2, r3, #0b1101			@ Check for translation error
+	sub	r1, r2, #0b0101
+
+	and	r3, r3, #255
+	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_check_bugs()
+ */
+ENTRY(cpu_arm1026_check_bugs)
+	mrs	ip, cpsr
+	bic	ip, ip, #F_BIT
+	msr	cpsr, ip
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_proc_init()
+ */
+ENTRY(cpu_arm1026_proc_init)
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_proc_fin()
+ */
+ENTRY(cpu_arm1026_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #F_BIT | I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	cpu_arm1026_cache_clean_invalidate_all
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1000 		@ ...i............
+	bic	r0, r0, #0x000e 		@ ............wca.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldmfd	sp!, {pc}
+
+/*
+ * cpu_arm1026_reset(loc)
+ *
+ * Perform a soft reset of the system.	Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_arm1026_reset)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
+	bic	ip, ip, #0x000f 		@ ............wcam
+	bic	ip, ip, #0x1100 		@ ...i...s........
+	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+	mov	pc, r0
+
+/*
+ * cpu_arm1026_do_idle()
+ */
+	.align	5
+ENTRY(cpu_arm1026_do_idle)
+	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
+	mov	pc, lr
+
+/* ================================= CACHE ================================ */
+
+
+/*
+ * cpu_arm1026_cache_clean_invalidate_all()
+ *
+ * clean and invalidate all cache lines
+ *
+ * Note:
+ *  1. we should preserve r0 at all times
+ */
+	.align	5
+ENTRY(cpu_arm1026_cache_clean_invalidate_all)
+	mov	r2, #1
+cpu_arm1026_cache_clean_invalidate_all_r2:
+	mov	ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+1:	mrc	p15, 0, r15, c7, c14, 3 	@ test,clean,invalidate
+	bne	1b
+#endif
+	teq	r2, #0
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_cache_clean_invalidate_range(start, end, flags)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * This is a little misleading, it is not intended to clean out
+ * the i-cache but to make sure that any data written to the
+ * range is made consistant.  This means that when we execute code
+ * in that region, everything works as we expect.
+ *
+ * This generally means writing back data in the Dcache and
+ * write buffer and flushing the Icache over that region
+ * start: Area start address
+ * end:   Area end address
+ * flags: nonzero for I cache as well
+ */
+	.align	5
+ENTRY(cpu_arm1026_cache_clean_invalidate_range)
+	bic	r0, r0, #DCACHELINESIZE - 1	@ && added by PGM
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	bhi	cpu_arm1026_cache_clean_invalidate_all_r2
+
+1:	teq	r2, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+#else
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+#endif
+        
+	cmp	r0, r1
+	blo	1b
+
+	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
+
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_flush_ram_page(page)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * page: page to clean and invalidate
+ */
+	.align	5
+ENTRY(cpu_arm1026_flush_ram_page)
+	mov	r1, #PAGESIZE
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+#else
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+#endif
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ D-CACHE =============================== */
+
+/*
+ * cpu_arm1026_dcache_invalidate_range(start, end)
+ *
+ * throw away all D-cached data in specified region without an obligation
+ * to write them back.	Note however that we must clean the D-cached entries
+ * around the boundaries if the start and/or end address are not cache
+ * aligned.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm1026_dcache_invalidate_range)
+#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
+	tst	r0, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
+	tst	r1, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
+#endif
+	bic	r0, r0, #DCACHELINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_dcache_clean_range(start, end)
+ *
+ * For the specified virtual address range, ensure that all caches contain
+ * clean data, such that peripheral accesses to the physical RAM fetch
+ * correct data.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm1026_dcache_clean_range)
+#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
+	bic	r0, r0, #DCACHELINESIZE - 1
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	mov	r2, #0
+	bhi	cpu_arm1026_cache_clean_invalidate_all_r2
+
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+#endif
+	mcr	p15, 0, r2, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_dcache_clean_page(page)
+ *
+ * Cleans a single page of dcache so that if we have any future aliased
+ * mappings, they will be consistent at the time that they are created.
+ *
+ * page: virtual address of page to clean from dcache
+ *
+ * Note:
+ *  1. we don't need to flush the write buffer in this case.
+ *  2. we don't invalidate the entries since when we write the page
+ *     out to disk, the entries may get reloaded into the cache.
+ */
+	.align	5
+ENTRY(cpu_arm1026_dcache_clean_page)
+#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
+	mov	r1, #PAGESIZE
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+#endif
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_dcache_clean_entry(addr)
+ *
+ * Clean the specified entry of any caches such that the MMU
+ * translation fetches will obtain correct data.
+ *
+ * addr: cache-unaligned virtual address
+ */
+	.align	5
+ENTRY(cpu_arm1026_dcache_clean_entry)
+#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ I-CACHE =============================== */
+
+/*
+ * cpu_arm1026_icache_invalidate_range(start, end)
+ *
+ * This *is not* just icache.  It is to make data written to memory
+ * consistent such that instructions fetched from the region are what
+ * we expect.
+ *
+ * This is typically used after we have copied a module into kernel space,
+ * and we're about to start executing code from that module.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm1026_icache_invalidate_range)
+	bic	r0, r0, #DCACHELINESIZE - 1	@ Safety check
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	bhi	cpu_arm1026_cache_clean_invalidate_all_r2
+
+1:	mcr	p15, 0, r0, c7, c5, 1		@ clean I entries
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blo	1b
+
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+ENTRY(cpu_arm1026_icache_invalidate_page)
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mov	pc, lr
+
+
+/* ================================== TLB ================================= */
+
+/*
+ * cpu_arm1026_tlb_invalidate_all()
+ *
+ * Invalidate all TLB entries
+ */
+	.align	5
+ENTRY(cpu_arm1026_tlb_invalidate_all)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_tlb_invalidate_range(start, end)
+ *
+ * invalidate TLB entries covering the specified range
+ *
+ * start: range start address
+ * end:   range end address
+ */
+	.align	5
+ENTRY(cpu_arm1026_tlb_invalidate_range)
+	sub	r3, r1, r0
+	cmp	r3, #256 * PAGESIZE		@ arbitary, should be tuned
+	bhi	cpu_arm1026_tlb_invalidate_all
+
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+
+	bic	r0, r0, #(PAGESIZE - 1) & 0x00ff
+	bic	r0, r0, #(PAGESIZE - 1) & 0xff00
+
+1:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
+	add	r0, r0, #PAGESIZE
+	cmp	r0, r1
+	blo	1b
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_tlb_invalidate_page(page, flags)
+ *
+ * invalidate the TLB entries for the specified page.
+ *
+ * page:  page to invalidate
+ * flags: non-zero if we include the I TLB
+ */
+	.align	5
+ENTRY(cpu_arm1026_tlb_invalidate_page)
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+	teq	r1, #0
+	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcrne	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
+	mov	pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm1026_set_pgd(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_arm1026_set_pgd)
+	mov	ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	/* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+@ && 'Clean & Invalidate whole DCache'
+1:	mrc	p15, 0, r15, c7, c14, 3 	@ test,clean,invalidate
+	bne	1b
+#endif
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_set_pmd(pmdp, pmd)
+ *
+ * Set a level 1 translation table entry, and clean it out of
+ * any caches such that the MMUs can load it correctly.
+ *
+ * pmdp: pointer to PMD entry
+ * pmd:  PMD value to store
+ */
+	.align	5
+ENTRY(cpu_arm1026_set_pmd)
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	eor	r2, r1, #0x0a			@ C & Section
+	tst	r2, #0x0b
+	biceq	r1, r1, #4			@ clear bufferable bit
+#endif
+	str	r1, [r0]
+#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm1026_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ */
+	.align	5
+ENTRY(cpu_arm1026_set_pte)
+	str	r1, [r0], #-1024		@ linux version
+
+	eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+	bic	r2, r1, #0xff0
+	bic	r2, r2, #3
+	orr	r2, r2, #HPTE_TYPE_SMALL
+
+	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	orrne	r2, r2, #HPTE_AP_READ
+
+	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
+	orreq	r2, r2, #HPTE_AP_WRITE
+
+	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
+	movne	r2, #0
+
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	eor	r3, r2, #0x0a			@ C & small page?
+	tst	r3, #0x0b
+	biceq	r2, r2, #4
+#endif
+	str	r2, [r0]			@ hardware version
+	mov	r0, r0
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+
+ENTRY(cpu_arm1026_name)
+	.ascii	"ARM1026EJ-S"
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+	.ascii	"i"
+#endif
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+	.ascii	"d"
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	.ascii	"(wt)"
+#else
+	.ascii	"(wb)"
+#endif
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
+	.ascii	"B"
+#endif
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+	.ascii	"RR"
+#endif
+#endif
+	.ascii	"\0"
+	.align
+
+	.section ".text.init", #alloc, #execinstr
+
+__arm1026_setup:
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
+	mcr	p15, 0, r4, c2, c0		@ load page table pointer
+
+
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+	mov	r0, #4				@ disable write-back on caches explicitly
+	mcr	p15, 7, r0, c15, c0, 0
+#endif 
+
+	mov	r0, #0x1f			@ Domains 0, 1 = client
+	mcr	p15, 0, r0, c3, c0		@ load domain access register
+	mrc	p15, 0, r0, c1, c0		@ get control register v4
+/*
+ * Clear out 'unwanted' bits (then put them in if we need them)
+ */
+						@   VI ZFRS BLDP WCAM
+	bic	r0, r0, #0x0e00
+	bic	r0, r0, #0x0002
+	bic	r0, r0, #0x000c
+	bic	r0, r0, #0x1000 		@ ...0 000. .... 000.
+/*
+ * Turn on what we want
+ */
+	orr	r0, r0, #0x0031
+	orr	r0, r0, #0x2100 		@ ..1. ...1 ..11 ...1
+
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+	orr	r0, r0, #0x4000 		@ .1.. .... .... ....
+#endif
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
+	orr	r0, r0, #0x0800 		@ ....Z...........
+#endif
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+	orr	r0, r0, #0x0004 		@ .... .... .... .1..
+#endif
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+	orr	r0, r0, #0x1000 		@ ...1 .... .... ....
+#endif
+	mov	pc, lr
+
+	.text
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+	.type	arm1026_processor_functions, #object
+arm1026_processor_functions:
+	.word	cpu_arm1026_data_abort
+	.word	cpu_arm1026_check_bugs
+	.word	cpu_arm1026_proc_init
+	.word	cpu_arm1026_proc_fin
+	.word	cpu_arm1026_reset
+	.word	cpu_arm1026_do_idle
+
+	/* cache */
+	.word	cpu_arm1026_cache_clean_invalidate_all
+	.word	cpu_arm1026_cache_clean_invalidate_range
+	.word	cpu_arm1026_flush_ram_page
+
+	/* dcache */
+	.word	cpu_arm1026_dcache_invalidate_range
+	.word	cpu_arm1026_dcache_clean_range
+	.word	cpu_arm1026_dcache_clean_page
+	.word	cpu_arm1026_dcache_clean_entry
+
+	/* icache */
+	.word	cpu_arm1026_icache_invalidate_range
+	.word	cpu_arm1026_icache_invalidate_page
+
+	/* tlb */
+	.word	cpu_arm1026_tlb_invalidate_all
+	.word	cpu_arm1026_tlb_invalidate_range
+	.word	cpu_arm1026_tlb_invalidate_page
+
+	/* pgtable */
+	.word	cpu_arm1026_set_pgd
+	.word	cpu_arm1026_set_pmd
+	.word	cpu_arm1026_set_pte
+	.size	arm1026_processor_functions, . - arm1026_processor_functions
+
+	.type	cpu_arm1026_info, #object
+cpu_arm1026_info:
+	.long	0
+	.long	cpu_arm1026_name
+	.size	cpu_arm1026_info, . - cpu_arm1026_info
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv5EJ"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v5EJ"
+	.size	cpu_elf_name, . - cpu_elf_name
+	.align
+
+	.section ".proc.info", #alloc, #execinstr
+
+	.type	__arm1026_proc_info,#object
+__arm1026_proc_info:
+	.long	0x4100a260
+	.long	0xff00fff0
+	.long	0x00000c1e			@ mmuflags
+	b	__arm1026_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | \
+		HWCAP_FAST_MULT
+	.long	cpu_arm1026_info
+	.long	arm1026_processor_functions
+	.size	__arm1026_proc_info, . - __arm1026_proc_info
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/proc-arm2,3.S linux-2.4.22-pre10/arch/arm/mm/proc-arm2,3.S
--- linux-2.4.21/arch/arm/mm/proc-arm2,3.S	2001-03-07 03:44:35.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/proc-arm2,3.S	2003-08-01 13:33:29.000000000 +0000
@@ -275,7 +275,6 @@
 _arm2_3_check_bugs:
 		bics	pc, lr, #0x04000000		@ Clear FIQ disable bit
 
-armvlsi_name:	.asciz	"ARM/VLSI"
 _arm2_name:	.asciz	"ARM 2"
 _arm250_name:	.asciz	"ARM 250"
 _arm3_name:	.asciz	"ARM 3"
@@ -295,7 +294,7 @@
 		.word	_arm2_xchg_4
 
 cpu_arm2_info:
-		.long	armvlsi_name
+		.long	0
 		.long	_arm2_name
 
 		.globl	SYMBOL_NAME(arm250_processor_functions)
@@ -308,7 +307,7 @@
 		.word	_arm3_xchg_4
 
 cpu_arm250_info:
-		.long	armvlsi_name
+		.long	0
 		.long	_arm250_name
 
 		.globl	SYMBOL_NAME(arm3_processor_functions)
@@ -321,7 +320,7 @@
 		.word	_arm3_xchg_4
 
 cpu_arm3_info:
-		.long	armvlsi_name
+		.long	0
 		.long	_arm3_name
 
 arm2_arch_name:	.asciz	"armv1"
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/proc-arm6,7.S linux-2.4.22-pre10/arch/arm/mm/proc-arm6,7.S
--- linux-2.4.21/arch/arm/mm/proc-arm6,7.S	2001-08-12 18:13:59.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/proc-arm6,7.S	2003-08-01 13:34:10.000000000 +0000
@@ -68,13 +68,27 @@
  * Purpose : flush a TLB entry
  */
 ENTRY(cpu_arm6_tlb_invalidate_range)
-ENTRY(cpu_arm7_tlb_invalidate_range)
-1:		mcr	p15, 0, r0, c6, c0, 0		@ flush TLB
+                @ arm 6 tbl purge reg is bits 12 - 31
+1:		mcr	p15, 0, r0, c6, c0, 0		@ purge TLB
 		add	r0, r0, #4096
 		cmp	r0, r1
 		blt	1b
 		mov	pc, lr
 
+ENTRY(cpu_arm7_tlb_invalidate_range)
+#if defined(CONFIG_ARCH_RISCSTATION)
+		mov	r0, #0
+		mcr	p15, 0, r0, c5, c0, 0		@ flush TLB
+		mov	pc, lr
+#else
+                @ arm 7 tbl purge reg is bits 14 - 31
+1:		mcr	p15, 0, r0, c6, c0, 0		@ purge TLB
+		add	r0, r0, #0x4000
+		cmp	r0, r1
+		blt	1b
+		mov	pc, lr
+#endif
+
 /*
  * Function: arm6_7_tlb_invalidate_page (unsigned long address, int flags)
  *
@@ -143,7 +157,7 @@
 		movs	pc, lr
 
 		b	Ldata_unknown
-		b	Ldata_unknown
+		b	Ldata_simple			@ swp
 		b	Ldata_unknown
 		b	Ldata_unknown
 		b	Ldata_lateldrpostconst		@ ldr	rd, [rn], #m
@@ -160,7 +174,7 @@
 Ldata_unknown:	@ Part of jumptable
 		mov	r0, r2
 		mov	r1, r4
-		mov	r2, r3
+		mov	r2, r5
 		bl	baddataabort
 		b	ret_from_exception
 
@@ -258,7 +272,6 @@
 
 ENTRY(cpu_arm6_do_idle)
 ENTRY(cpu_arm7_do_idle)
-		mov	r0, #-EINVAL
 		mov	pc, lr
 
 /*
@@ -349,8 +362,6 @@
 		mcr	p15, 0, r1, c1, c0, 0		@ turn off MMU etc
 		mov	pc, r0
 
-cpu_armvlsi_name:
-		.asciz	"ARM/VLSI"
 cpu_arm6_name:	.asciz	"ARM 6"
 cpu_arm610_name:
 		.asciz	"ARM 610"
@@ -461,25 +472,25 @@
 
 		.type	cpu_arm6_info, #object
 cpu_arm6_info:
-		.long	cpu_armvlsi_name
+		.long	0
 		.long	cpu_arm6_name
 		.size	cpu_arm6_info, . - cpu_arm6_info
 
 		.type	cpu_arm610_info, #object
 cpu_arm610_info:
-		.long	cpu_armvlsi_name
+		.long	0
 		.long	cpu_arm610_name
 		.size	cpu_arm610_info, . - cpu_Arm610_info
 
 		.type	cpu_arm7_info, #object
 cpu_arm7_info:
-		.long	cpu_armvlsi_name
+		.long	0
 		.long	cpu_arm7_name
 		.size	cpu_arm7_info, . - cpu_arm7_info
 
 		.type	cpu_arm710_info, #object
 cpu_arm710_info:
-		.long	cpu_armvlsi_name
+		.long	0
 		.long	cpu_arm710_name
 		.size	cpu_arm710_info, . - cpu_arm710_info
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/proc-arm720.S linux-2.4.22-pre10/arch/arm/mm/proc-arm720.S
--- linux-2.4.21/arch/arm/mm/proc-arm720.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/proc-arm720.S	2003-08-01 13:33:52.000000000 +0000
@@ -37,6 +37,11 @@
 #include <asm/hardware.h>
 
 /*
+ * and the page size
+ */
+#define PAGESIZE	4096
+
+/*
  * Function: arm720_cache_clean_invalidate_all (void)
  *	   : arm720_cache_clean_invalidate_page (unsigned long address, int size,
  *                                    int flags)
@@ -86,8 +91,11 @@
  * Purpose : flush a TLB entry
  */
 ENTRY(cpu_arm720_tlb_invalidate_range)
+		sub	r3, r1, r0
+		cmp	r3, #256 * PAGESIZE		@ arbitary, should be tuned
+		bhi	cpu_arm720_tlb_invalidate_all
 1:		mcr	p15, 0, r0, c8, c7, 1		@ flush TLB (v4)
-		add	r0, r0, #4096
+		add	r0, r0, #PAGESIZE
 		cmp	r0, r1
 		blt	1b
 		mov	pc, lr
@@ -438,8 +446,6 @@
 		mov	pc, r0
 
 	
-cpu_armvlsi_name:
-		.asciz	"ARM"
 cpu_arm720_name:
 		.asciz	"ARM720T"
 		.align
@@ -500,7 +506,7 @@
 
 		.type	cpu_arm720_info, #object
 cpu_arm720_info:
-		.long	cpu_armvlsi_name
+		.long	0
 		.long	cpu_arm720_name
 		.size	cpu_arm720_info, . - cpu_arm720_info
 	
@@ -527,7 +533,7 @@
 		b	__arm720_setup				@ cpu_flush
 		.long	cpu_arch_name				@ arch_name
 		.long	cpu_elf_name				@ elf_name
-		.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_26BIT	@ elf_hwcap
+		.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB	@ elf_hwcap
 		.long	cpu_arm720_info				@ info
 		.long	arm720_processor_functions
 		.size	__arm720_proc_info, . - __arm720_proc_info
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/proc-arm920.S linux-2.4.22-pre10/arch/arm/mm/proc-arm920.S
--- linux-2.4.21/arch/arm/mm/proc-arm920.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/proc-arm920.S	2003-08-01 13:30:41.000000000 +0000
@@ -134,9 +134,7 @@
  */
 	.align	5
 ENTRY(cpu_arm920_do_idle)
-#if defined(CONFIG_CPU_ARM920_CPU_IDLE)
 	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
-#endif
 	mov	pc, lr
 
 /* ================================= CACHE ================================ */
@@ -155,7 +153,7 @@
 	mov	r2, #1
 cpu_arm920_cache_clean_invalidate_all_r2:
 	mov	ip, #0
-#ifdef CONFIG_CPU_ARM920_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
 #else
 /*
@@ -193,7 +191,7 @@
 	cmp	r3, #MAX_AREA_SIZE
 	bgt	cpu_arm920_cache_clean_invalidate_all_r2
 1:	teq	r2, #0
-#ifdef CONFIG_CPU_ARM920_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
 	add	r0, r0, #DCACHELINESIZE
@@ -224,7 +222,7 @@
 	.align	5
 ENTRY(cpu_arm920_flush_ram_page)
 	mov	r1, #PAGESIZE
-#ifdef CONFIG_CPU_ARM920_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
@@ -410,6 +408,10 @@
  */
 	.align	5
 ENTRY(cpu_arm920_tlb_invalidate_range)
+	sub	r3, r1, r0
+	cmp	r3, #256 * PAGESIZE		@ arbitary, should be tuned
+	bhi	cpu_arm920_tlb_invalidate_all
+
 	mov	r3, #0
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 
@@ -454,7 +456,7 @@
 	.align	5
 ENTRY(cpu_arm920_set_pgd)
 	mov	ip, #0
-#ifdef CONFIG_CPU_ARM920_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	/* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */
 	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
 #else
@@ -487,7 +489,7 @@
  */
 	.align	5
 ENTRY(cpu_arm920_set_pmd)
-#ifdef CONFIG_CPU_ARM920_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r2, r1, #0x0a			@ C & Section
 	tst	r2, #0x0b
 	biceq	r1, r1, #4			@ clear bufferable bit
@@ -521,7 +523,7 @@
 	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
 	movne	r2, #0
 
-#ifdef CONFIG_CPU_ARM920_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r3, r2, #0x0a			@ C & small page?
 	tst	r3, #0x0b
 	biceq	r2, r2, #4
@@ -533,19 +535,14 @@
 	mov	pc, lr
 
 
-cpu_manu_name:
-	.asciz	"ARM/CIRRUS"
 ENTRY(cpu_arm920_name)
 	.ascii	"Arm920T"
-#if defined(CONFIG_CPU_ARM920_CPU_IDLE)
-	.ascii	"s"
-#endif
-#if defined(CONFIG_CPU_ARM920_I_CACHE_ON)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	.ascii	"i"
 #endif
-#if defined(CONFIG_CPU_ARM920_D_CACHE_ON)
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	.ascii	"d"
-#if defined(CONFIG_CPU_ARM920_WRITETHROUGH)
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	.ascii	"(wt)"
 #else
 	.ascii	"(wb)"
@@ -579,10 +576,10 @@
 	orr	r0, r0, #0x0031
 	orr	r0, r0, #0x2100			@ ..1. ...1 ..11 ...1
 
-#ifdef CONFIG_CPU_ARM920_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	orr	r0, r0, #0x0004			@ .... .... .... .1..
 #endif
-#ifdef CONFIG_CPU_ARM920_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	orr	r0, r0, #0x1000			@ ...1 .... .... ....
 #endif
 	mov	pc, lr
@@ -630,7 +627,7 @@
 
 	.type	cpu_arm920_info, #object
 cpu_arm920_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_arm920_name
 	.size	cpu_arm920_info, . - cpu_arm920_info
 
@@ -655,7 +652,7 @@
 	b	__arm920_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
-	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
 	.long	cpu_arm920_info
 	.long	arm920_processor_functions
 	.size	__arm920_proc_info, . - __arm920_proc_info
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/proc-arm922.S linux-2.4.22-pre10/arch/arm/mm/proc-arm922.S
--- linux-2.4.21/arch/arm/mm/proc-arm922.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/proc-arm922.S	2003-08-01 13:33:11.000000000 +0000
@@ -130,9 +130,7 @@
  */
 	.align	5
 ENTRY(cpu_arm922_do_idle)
-#if defined(CONFIG_CPU_ARM922_CPU_IDLE)
 	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
-#endif
 	mov	pc, lr
 
 /* ================================= CACHE ================================ */
@@ -151,7 +149,7 @@
 	mov	r2, #1
 cpu_arm922_cache_clean_invalidate_all_r2:
 	mov	ip, #0
-#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
 #else
 /*
@@ -189,7 +187,7 @@
 	cmp	r3, #MAX_AREA_SIZE
 	bgt	cpu_arm922_cache_clean_invalidate_all_r2
 1:	teq	r2, #0
-#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
 	add	r0, r0, #DCACHELINESIZE
@@ -220,7 +218,7 @@
 	.align	5
 ENTRY(cpu_arm922_flush_ram_page)
 	mov	r1, #PAGESIZE
-#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
@@ -406,6 +404,10 @@
  */
 	.align	5
 ENTRY(cpu_arm922_tlb_invalidate_range)
+	sub	r3, r1, r0
+	cmp	r3, #256 * PAGESIZE		@ arbitary, should be tuned
+	bhi	cpu_arm922_tlb_invalidate_all
+
 	mov	r3, #0
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 
@@ -450,7 +452,7 @@
 	.align	5
 ENTRY(cpu_arm922_set_pgd)
 	mov	ip, #0
-#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	/* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */
 	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
 #else
@@ -483,7 +485,7 @@
  */
 	.align	5
 ENTRY(cpu_arm922_set_pmd)
-#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r2, r1, #0x0a			@ C & Section
 	tst	r2, #0x0b
 	biceq	r1, r1, #4			@ clear bufferable bit
@@ -517,7 +519,7 @@
 	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
 	movne	r2, #0
 
-#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r3, r2, #0x0a			@ C & small page?
 	tst	r3, #0x0b
 	biceq	r2, r2, #4
@@ -529,19 +531,14 @@
 	mov	pc, lr
 
 
-cpu_manu_name:
-	.asciz	"ARM/ALTERA"
 ENTRY(cpu_arm922_name)
 	.ascii	"Arm922T"
-#if defined(CONFIG_CPU_ARM922_CPU_IDLE)
-	.ascii	"s"
-#endif
-#if defined(CONFIG_CPU_ARM922_I_CACHE_ON)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	.ascii	"i"
 #endif
-#if defined(CONFIG_CPU_ARM922_D_CACHE_ON)
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	.ascii	"d"
-#if defined(CONFIG_CPU_ARM922_WRITETHROUGH)
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	.ascii	"(wt)"
 #else
 	.ascii	"(wb)"
@@ -575,10 +572,10 @@
 	orr	r0, r0, #0x0031
 	orr	r0, r0, #0x2100			@ ..1. ...1 ..11 ...1
 
-#ifdef CONFIG_CPU_ARM922_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	orr	r0, r0, #0x0004			@ .... .... .... .1..
 #endif
-#ifdef CONFIG_CPU_ARM922_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	orr	r0, r0, #0x1000			@ ...1 .... .... ....
 #endif
 	mov	pc, lr
@@ -626,7 +623,7 @@
 
 	.type	cpu_arm922_info, #object
 cpu_arm922_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_arm922_name
 	.size	cpu_arm922_info, . - cpu_arm922_info
 
@@ -651,7 +648,7 @@
 	b	__arm922_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
-	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
 	.long	cpu_arm922_info
 	.long	arm922_processor_functions
 	.size	__arm922_proc_info, . - __arm922_proc_info
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/proc-arm925.S linux-2.4.22-pre10/arch/arm/mm/proc-arm925.S
--- linux-2.4.21/arch/arm/mm/proc-arm925.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/proc-arm925.S	2003-08-01 13:32:07.000000000 +0000
@@ -0,0 +1,732 @@
+/*
+ *  linux/arch/arm/mm/arm925.S: MMU functions for ARM925
+ *
+ *  Copyright (C) 1999-2001 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *  Copyright (C) 2002 RidgeRun, Inc.
+ *  Copyright (C) 2002 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the arm925.
+ */
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions.  Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define MAX_AREA_SIZE	(2 * 1024)
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define DCACHELINESIZE	16
+#define ICACHELINESIZE	16
+
+/*
+ * and the page size
+ */
+#define PAGESIZE	4096
+
+	.text
+
+/*
+ * cpu_arm925_data_abort()
+ *
+ * obtain information about current aborted instruction
+ * Note: we read user space.  This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture.  Unfortunately, this does happen.  We live with it.
+ *
+ * Inputs:
+ *  r2 = address of abort
+ *  r3 = cpsr of abort
+ *
+ * Returns:
+ *  r0 = address of abort
+ *  r1 != 0 if writing
+ *  r3 = FSR
+ *  r4 = corrupted
+ */
+	.align	5
+ENTRY(cpu_arm925_data_abort)
+	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+	mrc	p15, 0, r4, c5, c0, 0		@ get FSR
+
+	tst	r3, #1<<5			@ Check for Thumb-bit (NE -> found)
+	ldrneh	r1, [r2]			@ Read aborted Thumb instruction
+	tstne	r1, r1, lsr #12 		@ C = bit 11
+
+	ldreq	r1, [r2]			@ Read aborted ARM instruction
+	tsteq	r1, r1, lsr #21 		@ C = bit 20
+
+	sbc	r1, r1, r1			@ r1 = C - 1
+	and	r3, r4, #255
+	mov	pc, lr
+
+/*
+ * cpu_arm925_check_bugs()
+ */
+ENTRY(cpu_arm925_check_bugs)
+	mrs	ip, cpsr
+	bic	ip, ip, #F_BIT
+	msr	cpsr, ip
+	mov	pc, lr
+
+/*
+ * cpu_arm925_proc_init()
+ */
+ENTRY(cpu_arm925_proc_init)
+	mov	pc, lr
+
+/*
+ * cpu_arm925_proc_fin()
+ */
+ENTRY(cpu_arm925_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #F_BIT | I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	cpu_arm925_cache_clean_invalidate_all
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1000			@ ...i............
+	bic	r0, r0, #0x000e			@ ............wca.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldmfd	sp!, {pc}
+
+/*
+ * cpu_arm925_reset(loc)
+ *
+ * Perform a soft reset of the system.  Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_arm925_reset)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
+	bic	ip, ip, #0x000f			@ ............wcam
+	bic	ip, ip, #0x1100			@ ...i...s........
+	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+	mov	pc, r0
+
+/*
+ * cpu_arm925_do_idle()
+ */
+	.align	5
+ENTRY(cpu_arm925_do_idle)
+#if defined(CONFIG_CPU_ARM925_CPU_IDLE)
+	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
+#endif
+	mov	pc, lr
+
+/* ================================= CACHE ================================ */
+
+
+/*
+ * cpu_arm925_cache_clean_invalidate_all()
+ *
+ * clean and invalidate all cache lines
+ *
+ * Note:
+ *  1. we should preserve r0 at all times
+ */
+	.align	5
+ENTRY(cpu_arm925_cache_clean_invalidate_all)
+	mov	r2, #1
+cpu_arm925_cache_clean_invalidate_all_r2:
+	mov	ip, #0
+#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+/*
+ * 'Clean & Invalidate whole DCache'
+ * Re-written to use Index Ops.
+ * NOTE: Requires TI925T Configuration Register C bit <- 0
+ *       for clean and invalidate of both D-Cache sets.
+ */
+	mov	r3, #255 << 4		@ 256 entries/set
+					@ ((NSETS - 1) << (CIR[13-12] + 3))
+2:	mcr	p15, 0, r3, c7, c14, 2	@ clean & invalidate D index
+	subs	r3, r3, #1 << 4
+	bcs	2b			@ entries 255 to 0
+#endif
+	teq	r2, #0
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm925_cache_clean_invalidate_range(start, end, flags)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * This is a little misleading, it is not intended to clean out
+ * the i-cache but to make sure that any data written to the
+ * range is made consistant.  This means that when we execute code
+ * in that region, everything works as we expect.
+ *
+ * This generally means writing back data in the Dcache and
+ * write buffer and flushing the Icache over that region
+ * start: Area start address
+ * end:   Area end address
+ * flags: nonzero for I cache as well
+ */
+		.align	5
+ENTRY(cpu_arm925_cache_clean_invalidate_range)
+	bic	r0, r0, #DCACHELINESIZE - 1	@ && added by PGM
+	bic	r1, r1, #DCACHELINESIZE - 1     @ && added by DHM
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	bgt	cpu_arm925_cache_clean_invalidate_all_r2
+1:	teq	r2, #0
+#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+#else
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+#endif
+	cmp	r0, r1
+	blt	1b
+
+	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm925_flush_ram_page(page)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * page: page to clean and invalidate
+ */
+	.align	5
+ENTRY(cpu_arm925_flush_ram_page)
+	mov	r1, #PAGESIZE
+#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+#else
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+#endif
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ D-CACHE =============================== */
+
+/*
+ * cpu_arm925_dcache_invalidate_range(start, end)
+ *
+ * throw away all D-cached data in specified region without an obligation
+ * to write them back.  Note however that we must clean the D-cached entries
+ * around the boundaries if the start and/or end address are not cache
+ * aligned.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm925_dcache_invalidate_range)
+#ifndef CONFIG_CPU_ARM925_WRITETHROUGH
+	tst	r0, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
+	tst	r1, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
+#endif
+	bic	r0, r0, #DCACHELINESIZE - 1
+	bic	r1, r1, #DCACHELINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blt	1b
+	mov	pc, lr
+
+/*
+ * cpu_arm925_dcache_clean_range(start, end)
+ *
+ * For the specified virtual address range, ensure that all caches contain
+ * clean data, such that peripheral accesses to the physical RAM fetch
+ * correct data.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm925_dcache_clean_range)
+#ifndef CONFIG_CPU_ARM925_WRITETHROUGH
+	bic	r0, r0, #DCACHELINESIZE - 1
+	sub	r1, r1, r0
+	cmp	r1, #MAX_AREA_SIZE
+	mov	r2, #0
+	bgt	cpu_arm925_cache_clean_invalidate_all_r2
+
+	bic	r1, r1, #DCACHELINESIZE -1
+	add	r1, r1, #DCACHELINESIZE
+
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #DCACHELINESIZE
+	bpl	1b
+#endif
+	mcr	p15, 0, r2, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm925_dcache_clean_page(page)
+ *
+ * Cleans a single page of dcache so that if we have any future aliased
+ * mappings, they will be consistent at the time that they are created.
+ *
+ * page: virtual address of page to clean from dcache
+ *
+ * Note:
+ *  1. we don't need to flush the write buffer in this case.
+ *  2. we don't invalidate the entries since when we write the page
+ *     out to disk, the entries may get reloaded into the cache.
+ */
+	.align	5
+ENTRY(cpu_arm925_dcache_clean_page)
+#ifndef CONFIG_CPU_ARM925_WRITETHROUGH
+	mov	r1, #PAGESIZE
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+#endif
+	mov	pc, lr
+
+/*
+ * cpu_arm925_dcache_clean_entry(addr)
+ *
+ * Clean the specified entry of any caches such that the MMU
+ * translation fetches will obtain correct data.
+ *
+ * addr: cache-unaligned virtual address
+ */
+	.align	5
+ENTRY(cpu_arm925_dcache_clean_entry)
+#ifndef CONFIG_CPU_ARM925_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ I-CACHE =============================== */
+
+/*
+ * cpu_arm925_icache_invalidate_range(start, end)
+ *
+ * invalidate a range of virtual addresses from the Icache
+ *
+ * This is a little misleading, it is not intended to clean out
+ * the i-cache but to make sure that any data written to the
+ * range is made consistant.  This means that when we execute code
+ * in that region, everything works as we expect.
+ *
+ * This generally means writing back data in the Dcache and
+ * write buffer and flushing the Icache over that region
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ *
+ * NOTE: ICACHELINESIZE == DCACHELINESIZE (so we don't need to
+ * loop twice, once for i-cache, once for d-cache)
+ */
+	.align	5
+ENTRY(cpu_arm925_icache_invalidate_range)
+	bic	r0, r0, #ICACHELINESIZE - 1	@ Safety check
+	sub	r1, r1, r0
+	cmp	r1, #MAX_AREA_SIZE
+	bgt	cpu_arm925_cache_clean_invalidate_all_r2
+
+	bic	r1, r1, #ICACHELINESIZE - 1
+	add	r1, r1, #ICACHELINESIZE
+
+1:	mcr	p15, 0, r0, c7, c5, 1		@ Clean I entry
+	mcr	p15, 0, r0, c7, c10, 1		@ Clean D entry
+	add	r0, r0, #ICACHELINESIZE
+	subs	r1, r1, #ICACHELINESIZE
+	bne	1b
+
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+
+ENTRY(cpu_arm925_icache_invalidate_page)
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+        nop
+        nop
+        nop
+        nop
+	mov	pc, lr
+
+/* ================================== TLB ================================= */
+
+/*
+ * cpu_arm925_tlb_invalidate_all()
+ *
+ * Invalidate all TLB entries
+ */
+	.align	5
+ENTRY(cpu_arm925_tlb_invalidate_all)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_arm925_tlb_invalidate_range(start, end)
+ *
+ * invalidate TLB entries covering the specified range
+ *
+ * start: range start address
+ * end:   range end address
+ */
+	.align	5
+ENTRY(cpu_arm925_tlb_invalidate_range)
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+
+	mov	r3, #PAGESIZE
+	sub	r3, r3, #1
+	bic 	r0, r0, r3
+	bic	r1, r1, r3
+
+1:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
+	add	r0, r0, #PAGESIZE
+	cmp	r0, r1
+	blt	1b
+	mov	pc, lr
+
+/*
+ * cpu_arm925_tlb_invalidate_page(page, flags)
+ *
+ * invalidate the TLB entries for the specified page.
+ *
+ * page:  page to invalidate
+ * flags: non-zero if we include the I TLB
+ */
+	.align	5
+ENTRY(cpu_arm925_tlb_invalidate_page)
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+	teq	r1, #0
+	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcrne	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
+	mov	pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm925_set_pgd(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_arm925_set_pgd)
+	mov	ip, #0
+#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I & D cache
+#else
+/*
+ * 'Clean & Invalidate whole DCache'
+ * Re-written to use Index Ops.
+ * NOTE: Requires TI925T Configuration Register C bit <- 0
+ *       for clean and invalidate of both D-Cache sets.
+ */
+	mov	r3, #255 << 4		@ 256 entries/set
+					@ ((NSETS - 1) << (CIR[13-12] + 3))
+2:	mcr	p15, 0, r3, c7, c14, 2	@ clean & invalidate D index
+	subs	r3, r3, #1 << 4
+	bcs	2b			@ entries 255 to 0
+#endif
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_arm925_set_pmd(pmdp, pmd)
+ *
+ * Set a level 1 translation table entry, and clean it out of
+ * any caches such that the MMUs can load it correctly.
+ *
+ * pmdp: pointer to PMD entry
+ * pmd:  PMD value to store
+ */
+	.align	5
+ENTRY(cpu_arm925_set_pmd)
+#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
+	eor	r2, r1, #0x0a			@ C & Section
+	tst	r2, #0x0b
+	biceq	r1, r1, #4			@ clear bufferable bit
+#endif
+	str	r1, [r0]
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm925_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ */
+	.align	5
+ENTRY(cpu_arm925_set_pte)
+	str	r1, [r0], #-1024		@ linux version
+
+	eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+	bic	r2, r1, #0xff0
+	bic	r2, r2, #3
+	orr	r2, r2, #HPTE_TYPE_SMALL
+
+	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	orrne	r2, r2, #HPTE_AP_READ
+
+	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
+	orreq	r2, r2, #HPTE_AP_WRITE
+
+	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
+	movne	r2, #0
+
+#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
+	eor	r3, r2, #0x0a			@ C & small page?
+	tst	r3, #0x0b
+	biceq	r2, r2, #4
+#endif
+	str	r2, [r0]			@ hardware version
+	mov	r0, r0
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+
+ENTRY(cpu_arm925_name)
+	.ascii	"Arm925T"
+#if defined(CONFIG_CPU_ARM925_CPU_IDLE)
+	.ascii	"s"
+#endif
+#if defined(CONFIG_CPU_ARM925_I_CACHE_ON)
+	.ascii	"i"
+#endif
+#if defined(CONFIG_CPU_ARM925_D_CACHE_ON)
+	.ascii	"d"
+#if defined(CONFIG_CPU_ARM925_WRITETHROUGH)
+	.ascii	"(wt)"
+#else
+	.ascii	"(wb)"
+#endif
+#endif
+	.ascii	"\0"
+
+ENTRY(cpu_arm915_name)
+	.ascii	"Arm915T"
+#if defined(CONFIG_CPU_ARM925_CPU_IDLE)
+	.ascii	"s"
+#endif
+#if defined(CONFIG_CPU_ARM925_I_CACHE_ON)
+	.ascii	"i"
+#endif
+#if defined(CONFIG_CPU_ARM925_D_CACHE_ON)
+	.ascii	"d"
+#if defined(CONFIG_CPU_ARM925_WRITETHROUGH)
+	.ascii	"(wt)"
+#else
+	.ascii	"(wb)"
+#endif
+#endif
+	.ascii	"\0"
+	.align
+
+	.section ".text.init", #alloc, #execinstr
+
+__arm925_setup:
+	mov	r0, #0
+#if defined(CONFIG_CPU_ARM925_NON_STREAMING_ON)
+        orr     r0,r0,#0x80
+#endif
+#if defined(CONFIG_CPU_ARM925_TRANSPARENT_ON)
+        orr     r0,r0,#0x2
+#endif
+	mcr	p15, 0, r0, c15, c1, 0		@ write TI config register
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
+	mcr	p15, 0, r4, c2, c0		@ load page table pointer
+	mov	r0, #0x1f			@ Domains 0, 1 = client
+	mcr	p15, 0, r0, c3, c0		@ load domain access register
+	mrc	p15, 0, r0, c1, c0		@ get control register v4
+/*
+ * Clear out 'unwanted' bits (then put them in if we need them)
+ */
+						@   VI ZFRS BLDP WCAM
+	bic	r0, r0, #0x0e00
+	bic	r0, r0, #0x0002
+	bic	r0, r0, #0x000c
+	bic	r0, r0, #0x1000			@ ...0 000. .... 000.
+/*
+ * Turn on what we want
+ */
+	orr	r0, r0, #0x0031
+	orr	r0, r0, #0x2100			@ ..1. ...1 ..11 ...1
+
+#ifdef CONFIG_CPU_ARM925_WRITEBUFFER_ON
+	orr	r0, r0, #0x0008			@ .... .... .... 1...
+#endif
+#ifdef CONFIG_CPU_ARM925_D_CACHE_ON
+	orr	r0, r0, #0x0004			@ .... .... .... .1..
+#endif
+#ifdef CONFIG_CPU_ARM925_I_CACHE_ON
+	orr	r0, r0, #0x1000			@ ...1 .... .... ....
+#endif
+	mov	pc, lr
+
+	.text
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+	.type	arm925_processor_functions, #object
+arm925_processor_functions:
+	.word	cpu_arm925_data_abort
+	.word	cpu_arm925_check_bugs
+	.word	cpu_arm925_proc_init
+	.word	cpu_arm925_proc_fin
+	.word	cpu_arm925_reset
+	.word   cpu_arm925_do_idle
+
+	/* cache */
+	.word	cpu_arm925_cache_clean_invalidate_all
+	.word	cpu_arm925_cache_clean_invalidate_range
+	.word	cpu_arm925_flush_ram_page
+
+	/* dcache */
+	.word	cpu_arm925_dcache_invalidate_range
+	.word	cpu_arm925_dcache_clean_range
+	.word	cpu_arm925_dcache_clean_page
+	.word	cpu_arm925_dcache_clean_entry
+
+	/* icache */
+	.word	cpu_arm925_icache_invalidate_range
+	.word	cpu_arm925_icache_invalidate_page
+
+	/* tlb */
+	.word	cpu_arm925_tlb_invalidate_all
+	.word	cpu_arm925_tlb_invalidate_range
+	.word	cpu_arm925_tlb_invalidate_page
+
+	/* pgtable */
+	.word	cpu_arm925_set_pgd
+	.word	cpu_arm925_set_pmd
+	.word	cpu_arm925_set_pte
+	.size	arm925_processor_functions, . - arm925_processor_functions
+
+	.type	cpu_arm925_info, #object
+cpu_arm925_info:
+	.long	0
+	.long	cpu_arm925_name
+	.size	cpu_arm925_info, . - cpu_arm925_info
+
+	.type	cpu_arm915_info, #object
+cpu_arm915_info:
+	.long	cpu_manu_name
+	.long	cpu_arm915_name
+	.size	cpu_arm915_info, . - cpu_arm915_info
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv4"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v4"
+	.size	cpu_elf_name, . - cpu_elf_name
+	.align
+
+#if	defined(CONFIG_CPU_ARM925_WRITETHROUGH)
+#  define	MMU_FLAGS	0x00000c1a
+#else
+#  define	MMU_FLAGS	0x00000c1e
+#endif
+	.section ".proc.info", #alloc, #execinstr
+
+	.type	__arm925_proc_info,#object
+__arm925_proc_info:
+	.long	0x54029252
+	.long	0xffffffff
+	.long	MMU_FLAGS
+	b	__arm925_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
+	.long	cpu_arm925_info
+	.long	arm925_processor_functions
+	.size	__arm925_proc_info, . - __arm925_proc_info
+
+	.type	__arm915_proc_info,#object
+__arm915_proc_info:
+	.long	0x54029152
+	.long	0xffffffff
+	.long	MMU_FLAGS
+	b	__arm925_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
+	.long	cpu_arm915_info
+	.long	arm925_processor_functions
+	.size	__arm925_proc_info, . - __arm925_proc_info
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/proc-arm926.S linux-2.4.22-pre10/arch/arm/mm/proc-arm926.S
--- linux-2.4.21/arch/arm/mm/proc-arm926.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/proc-arm926.S	2003-08-01 13:33:32.000000000 +0000
@@ -81,9 +81,8 @@
 
 	tst	r3, #1<<5			@ Check for Thumb-bit (NE -> found)
 	ldrneh	r1, [r2]			@ Read aborted Thumb instruction        
-	tstne	r1, r1, lsr #12 		@ C = bit 11
-
 	ldreq	r1, [r2]			@ Read aborted ARM instruction
+	movne	r1, r1, lsl #(20-12)		@ shift thumb bit 10 to ARM bit 20
 	tsteq	r1, r1, lsr #21 		@ C = bit 20
 
 	sbc	r1, r1, r1			@ r1 = C - 1
@@ -146,9 +145,7 @@
  */
 	.align	5
 ENTRY(cpu_arm926_do_idle)
-#if defined(CONFIG_CPU_ARM926_CPU_IDLE)
 	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
-#endif
 	mov	pc, lr
 
 /* ================================= CACHE ================================ */
@@ -167,7 +164,7 @@
 	mov	r2, #1
 cpu_arm926_cache_clean_invalidate_all_r2:
 	mov	ip, #0
-#ifdef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
 #else
 1:	mrc	p15, 0, r15, c7, c14, 3 	@ test,clean,invalidate
@@ -202,7 +199,7 @@
 	bhi	cpu_arm926_cache_clean_invalidate_all_r2
 
 1:	teq	r2, #0
-#ifdef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
 	add	r0, r0, #DCACHELINESIZE
@@ -235,7 +232,7 @@
 	.align	5
 ENTRY(cpu_arm926_flush_ram_page)
 	mov	r1, #PAGESIZE
-#ifdef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	add	r0, r0, #DCACHELINESIZE
 	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
@@ -408,6 +405,10 @@
  */
 	.align	5
 ENTRY(cpu_arm926_tlb_invalidate_range)
+	sub	r3, r1, r0
+	cmp	r3, #256 * PAGESIZE		@ arbitary, should be tuned
+	bhi	cpu_arm926_tlb_invalidate_all
+
 	mov	r3, #0
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 
@@ -450,7 +451,7 @@
 	.align	5
 ENTRY(cpu_arm926_set_pgd)
 	mov	ip, #0
-#ifdef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	/* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */
 	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
 #else
@@ -475,7 +476,7 @@
  */
 	.align	5
 ENTRY(cpu_arm926_set_pmd)
-#ifdef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r2, r1, #0x0a			@ C & Section
 	tst	r2, #0x0b
 	biceq	r1, r1, #4			@ clear bufferable bit
@@ -511,38 +512,33 @@
 	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
 	movne	r2, #0
 
-#ifdef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	eor	r3, r2, #0x0a			@ C & small page?
 	tst	r3, #0x0b
 	biceq	r2, r2, #4
 #endif
 	str	r2, [r0]			@ hardware version
 	mov	r0, r0
-#ifndef CONFIG_CPU_ARM926_WRITETHROUGH
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 #endif
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 
 
-cpu_manu_name:
-	.asciz	"ARM"
 ENTRY(cpu_arm926_name)
 	.ascii	"ARM926EJ-S"
-#if defined(CONFIG_CPU_ARM926_CPU_IDLE)
-	.ascii	"s"
-#endif
-#if defined(CONFIG_CPU_ARM926_I_CACHE_ON)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	.ascii	"i"
 #endif
-#if defined(CONFIG_CPU_ARM926_D_CACHE_ON)
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	.ascii	"d"
-#if defined(CONFIG_CPU_ARM926_WRITETHROUGH)
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	.ascii	"(wt)"
 #else
 	.ascii	"(wb)"
 #endif
-#ifdef CONFIG_CPU_ARM926_ROUND_ROBIN
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	.ascii	"RR"
 #endif
 #endif
@@ -559,7 +555,7 @@
 	mcr	p15, 0, r4, c2, c0		@ load page table pointer
 
 
-#if defined(CONFIG_CPU_ARM926_WRITETHROUGH) 
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
 	mov	r0, #4				@ disable write-back on caches explicitly
 	mcr	p15, 7, r0, c15, c0, 0
 #endif 
@@ -581,13 +577,13 @@
 	orr	r0, r0, #0x0031
 	orr	r0, r0, #0x2100 		@ ..1. ...1 ..11 ...1
 
-#ifdef CONFIG_CPU_ARM926_ROUND_ROBIN
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	orr	r0, r0, #0x4000 		@ .1.. .... .... ....
 #endif
-#ifdef CONFIG_CPU_ARM926_D_CACHE_ON
+#ifndef CONFIG_CPU_DCACHE_DISABLE
 	orr	r0, r0, #0x0004 		@ .... .... .... .1..
 #endif
-#ifdef CONFIG_CPU_ARM926_I_CACHE_ON
+#ifndef CONFIG_CPU_ICACHE_DISABLE
 	orr	r0, r0, #0x1000 		@ ...1 .... .... ....
 #endif
 	mov	pc, lr
@@ -635,7 +631,7 @@
 
 	.type	cpu_arm926_info, #object
 cpu_arm926_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_arm926_name
 	.size	cpu_arm926_info, . - cpu_arm926_info
 
@@ -660,7 +656,8 @@
 	b	__arm926_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
-	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | \
+		HWCAP_FAST_MULT
 	.long	cpu_arm926_info
 	.long	arm926_processor_functions
 	.size	__arm926_proc_info, . - __arm926_proc_info
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/proc-sa110.S linux-2.4.22-pre10/arch/arm/mm/proc-sa110.S
--- linux-2.4.21/arch/arm/mm/proc-sa110.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/proc-sa110.S	2003-08-01 13:33:12.000000000 +0000
@@ -159,43 +159,12 @@
 	mov	pc, r0
 
 /*
- * cpu_sa110_do_idle(type)
+ * cpu_sa110_do_idle()
  *
  * Cause the processor to idle
- *
- * type: call type:
- *   0 = slow idle
- *   1 = fast idle
- *   2 = switch to slow processor clock
- *   3 = switch to fast processor clock
  */
 	.align	5
-idle:	mcr	p15, 0, r0, c15, c8, 2		@ Wait for interrupt, cache aligned
-	mov	r0, r0				@ safety
-	mov	pc, lr
-
 ENTRY(cpu_sa110_do_idle)
-	mov	ip, #0
-	cmp	r0, #4
-	addcc	pc, pc, r0, lsl #2
-	mov	pc, lr
-
-	b	idle
-	b	idle
-	b	slow_clock
-	b	fast_clock
-
-fast_clock:
-	mcr	p15, 0, ip, c15, c1, 2		@ enable clock switching
-	mov	pc, lr
-
-slow_clock:
-	mcr	p15, 0, ip, c15, c2, 2		@ disable clock switching
-	ldr	r1, =UNCACHEABLE_ADDR		@ load from uncacheable loc
-	ldr	r1, [r1, #0]			@ force switch to MCLK
-	mov	pc, lr
-
-	.align	5
 ENTRY(cpu_sa1100_do_idle)
 	mov	r0, r0				@ 4 nop padding
 	mov	r0, r0
@@ -468,6 +437,9 @@
 ENTRY(cpu_sa1100_tlb_invalidate_range)
 	bic	r0, r0, #0x0ff
 	bic	r0, r0, #0xf00
+	sub	r3, r1, r0
+	cmp	r3, #256 * PAGESIZE		@ arbitary, should be tuned
+	bhi	cpu_sa110_tlb_invalidate_all
 	mov	r3, #0
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 1:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
@@ -595,8 +567,6 @@
 	mov	pc, lr
 
 
-cpu_manu_name:
-	.asciz	"Intel"
 cpu_sa110_name:
 	.asciz	"StrongARM-110"
 cpu_sa1100_name:
@@ -676,7 +646,7 @@
 
 	.type	cpu_sa110_info, #object
 cpu_sa110_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_sa110_name
 	.size	cpu_sa110_info, . - cpu_sa110_info
 
@@ -720,12 +690,12 @@
 	.size	sa1100_processor_functions, . - sa1100_processor_functions
 
 cpu_sa1100_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_sa1100_name
 	.size	cpu_sa1100_info, . - cpu_sa1100_info
 
 cpu_sa1110_info:
-	.long	cpu_manu_name
+	.long	0
 	.long	cpu_sa1110_name
 	.size	cpu_sa1110_info, . - cpu_sa1110_info
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/mm/small_page.c linux-2.4.22-pre10/arch/arm/mm/small_page.c
--- linux-2.4.21/arch/arm/mm/small_page.c	2001-04-12 19:20:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/mm/small_page.c	2003-08-01 13:30:37.000000000 +0000
@@ -150,8 +150,8 @@
 	unsigned long flags;
 	struct page *page;
 
-	page = virt_to_page(spage);
-	if (VALID_PAGE(page)) {
+	if (virt_addr_valid(spage)) {
+		page = virt_to_page(spage);
 
 		/*
 		 * The container-page must be marked Reserved
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/ChangeLog linux-2.4.22-pre10/arch/arm/nwfpe/ChangeLog
--- linux-2.4.21/arch/arm/nwfpe/ChangeLog	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/ChangeLog	2003-08-01 13:33:29.000000000 +0000
@@ -1,3 +1,11 @@
+2003-03-22  Ralph Siemsen <ralphs@netwinder.org>
+	* Reformat all but softfloat files to get a consistent coding style.
+	  Used "indent -kr -i8 -ts8 -sob -l132 -ss" and a few manual fixups.
+	* Removed dead code and fixed function protypes to match definitions.
+	* Consolidated use of (opcode && MASK_ARITHMETIC_OPCODE) >> 20.
+	* Make 80-bit precision a compile-time option. (1%)
+	* Only initialize FPE state once in repeat-FP situations. (6%)
+
 2002-01-19  Russell King <rmk@arm.linux.org.uk>
 
 	* fpa11.h - Add documentation
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/Makefile linux-2.4.22-pre10/arch/arm/nwfpe/Makefile
--- linux-2.4.21/arch/arm/nwfpe/Makefile	2001-04-12 02:02:27.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/Makefile	2003-08-01 13:30:43.000000000 +0000
@@ -18,7 +18,11 @@
 
 nwfpe-objs		:= fpa11.o fpa11_cpdo.o fpa11_cpdt.o fpa11_cprt.o \
 			   fpmodule.o fpopcode.o softfloat.o \
-			   single_cpdo.o double_cpdo.o extended_cpdo.o
+			   single_cpdo.o double_cpdo.o
+
+ifeq ($(CONFIG_FPE_NWFPE_XP),y)
+nwfpe-objs		+= extended_cpdo.o
+endif
 
 ifeq ($(CONFIG_CPU_26),y)
 nwfpe-objs		+= entry26.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/double_cpdo.c linux-2.4.22-pre10/arch/arm/nwfpe/double_cpdo.c
--- linux-2.4.21/arch/arm/nwfpe/double_cpdo.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/double_cpdo.c	2003-08-01 13:30:35.000000000 +0000
@@ -23,6 +23,11 @@
 #include "softfloat.h"
 #include "fpopcode.h"
 
+union float64_components {
+	float64 f64;
+	unsigned int i[2];
+};
+
 float64 float64_exp(float64 Fm);
 float64 float64_ln(float64 Fm);
 float64 float64_sin(float64 rFm);
@@ -32,257 +37,123 @@
 float64 float64_log(float64 rFm);
 float64 float64_tan(float64 rFm);
 float64 float64_arccos(float64 rFm);
-float64 float64_pow(float64 rFn,float64 rFm);
-float64 float64_pol(float64 rFn,float64 rFm);
+float64 float64_pow(float64 rFn, float64 rFm);
+float64 float64_pol(float64 rFn, float64 rFm);
 
-unsigned int DoubleCPDO(const unsigned int opcode)
+static float64 float64_rsf(float64 rFn, float64 rFm)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   float64 rFm, rFn;
-   unsigned int Fd, Fm, Fn, nRc = 1;
-
-   //printk("DoubleCPDO(0x%08x)\n",opcode);
-   
-   Fm = getFm(opcode);
-   if (CONSTANT_FM(opcode))
-   {
-     rFm = getDoubleConstant(Fm);
-   }
-   else
-   {  
-     switch (fpa11->fType[Fm])
-     {
-        case typeSingle:
-          rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle);
-        break;
-
-        case typeDouble:
-          rFm = fpa11->fpreg[Fm].fDouble;
-          break;
-
-        case typeExtended:
-            // !! patb
-	    //printk("not implemented! why not?\n");
-            //!! ScottB
-            // should never get here, if extended involved
-            // then other operand should be promoted then
-            // ExtendedCPDO called.
-            break;
-
-        default: return 0;
-     }
-   }
-
-   if (!MONADIC_INSTRUCTION(opcode))
-   {
-      Fn = getFn(opcode);
-      switch (fpa11->fType[Fn])
-      {
-        case typeSingle:
-          rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle);
-        break;
-
-        case typeDouble:
-          rFn = fpa11->fpreg[Fn].fDouble;
-        break;
-        
-        default: return 0;
-      }
-   }
-
-   Fd = getFd(opcode);
-   /* !! this switch isn't optimized; better (opcode & MASK_ARITHMETIC_OPCODE)>>24, sort of */
-   switch (opcode & MASK_ARITHMETIC_OPCODE)
-   {
-      /* dyadic opcodes */
-      case ADF_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_add(rFn,rFm);
-      break;
-
-      case MUF_CODE:
-      case FML_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_mul(rFn,rFm);
-      break;
-
-      case SUF_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_sub(rFn,rFm);
-      break;
-
-      case RSF_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_sub(rFm,rFn);
-      break;
-
-      case DVF_CODE:
-      case FDV_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_div(rFn,rFm);
-      break;
-
-      case RDF_CODE:
-      case FRD_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_div(rFm,rFn);
-      break;
-
-#if 0
-      case POW_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_pow(rFn,rFm);
-      break;
-
-      case RPW_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_pow(rFm,rFn);
-      break;
-#endif
-
-      case RMF_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_rem(rFn,rFm);
-      break;
-
-#if 0
-      case POL_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_pol(rFn,rFm);
-      break;
-#endif
-
-      /* monadic opcodes */
-      case MVF_CODE:
-         fpa11->fpreg[Fd].fDouble = rFm;
-      break;
-
-      case MNF_CODE:
-      {
-         unsigned int *p = (unsigned int*)&rFm;
-         p[1] ^= 0x80000000;
-         fpa11->fpreg[Fd].fDouble = rFm;
-      }
-      break;
-
-      case ABS_CODE:
-      {
-         unsigned int *p = (unsigned int*)&rFm;
-         p[1] &= 0x7fffffff;
-         fpa11->fpreg[Fd].fDouble = rFm;
-      }
-      break;
-
-      case RND_CODE:
-      case URD_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm);
-      break;
-
-      case SQT_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_sqrt(rFm);
-      break;
-
-#if 0
-      case LOG_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_log(rFm);
-      break;
-
-      case LGN_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_ln(rFm);
-      break;
-
-      case EXP_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_exp(rFm);
-      break;
-
-      case SIN_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_sin(rFm);
-      break;
-
-      case COS_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_cos(rFm);
-      break;
-
-      case TAN_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_tan(rFm);
-      break;
-
-      case ASN_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_arcsin(rFm);
-      break;
-
-      case ACS_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_arccos(rFm);
-      break;
-
-      case ATN_CODE:
-         fpa11->fpreg[Fd].fDouble = float64_arctan(rFm);
-      break;
-#endif
-
-      case NRM_CODE:
-      break;
-      
-      default:
-      {
-        nRc = 0;
-      }
-   }
-
-   if (0 != nRc) fpa11->fType[Fd] = typeDouble;
-   return nRc;
+	return float64_sub(rFm, rFn);
 }
 
-#if 0
-float64 float64_exp(float64 rFm)
+static float64 float64_rdv(float64 rFn, float64 rFm)
 {
-  return rFm;
-//series
+	return float64_div(rFm, rFn);
 }
 
-float64 float64_ln(float64 rFm)
-{
-  return rFm;
-//series
-}
+static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = {
+	[ADF_CODE >> 20] = float64_add,
+	[MUF_CODE >> 20] = float64_mul,
+	[SUF_CODE >> 20] = float64_sub,
+	[RSF_CODE >> 20] = float64_rsf,
+	[DVF_CODE >> 20] = float64_div,
+	[RDF_CODE >> 20] = float64_rdv,
+	[RMF_CODE >> 20] = float64_rem,
 
-float64 float64_sin(float64 rFm)
-{
-  return rFm;
-//series
-}
+	/* strictly, these opcodes should not be implemented */
+	[FML_CODE >> 20] = float64_mul,
+	[FDV_CODE >> 20] = float64_div,
+	[FRD_CODE >> 20] = float64_rdv,
+};
 
-float64 float64_cos(float64 rFm)
+static float64 float64_mvf(float64 rFm)
 {
-   return rFm;
-   //series
+	return rFm;
 }
 
-#if 0
-float64 float64_arcsin(float64 rFm)
+static float64 float64_mnf(float64 rFm)
 {
-//series
-}
+	union float64_components u;
 
-float64 float64_arctan(float64 rFm)
-{
-  //series
-}
-#endif
+	u.f64 = rFm;
+	u.i[1] ^= 0x80000000;
 
-float64 float64_log(float64 rFm)
-{
-  return float64_div(float64_ln(rFm),getDoubleConstant(7));
+	return u.f64;
 }
 
-float64 float64_tan(float64 rFm)
+static float64 float64_abs(float64 rFm)
 {
-  return float64_div(float64_sin(rFm),float64_cos(rFm));
-}
+	union float64_components u;
 
-float64 float64_arccos(float64 rFm)
-{
-return rFm;
-   //return float64_sub(halfPi,float64_arcsin(rFm));
-}
+	u.f64 = rFm;
+	u.i[1] &= 0x7fffffff;
 
-float64 float64_pow(float64 rFn,float64 rFm)
-{
-  return float64_exp(float64_mul(rFm,float64_ln(rFn))); 
+	return u.f64;
 }
 
-float64 float64_pol(float64 rFn,float64 rFm)
+static float64 (*const monadic_double[16])(float64 rFm) = {
+	[MVF_CODE >> 20] = float64_mvf,
+	[MNF_CODE >> 20] = float64_mnf,
+	[ABS_CODE >> 20] = float64_abs,
+	[RND_CODE >> 20] = float64_round_to_int,
+	[URD_CODE >> 20] = float64_round_to_int,
+	[SQT_CODE >> 20] = float64_sqrt,
+	[NRM_CODE >> 20] = float64_mvf,
+};
+
+unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd)
 {
-  return float64_arctan(float64_div(rFn,rFm)); 
+	FPA11 *fpa11 = GET_FPA11();
+	float64 rFm;
+	unsigned int Fm, opc_mask_shift;
+
+	Fm = getFm(opcode);
+	if (CONSTANT_FM(opcode)) {
+		rFm = getDoubleConstant(Fm);
+	} else {
+		switch (fpa11->fType[Fm]) {
+		case typeSingle:
+			rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle);
+			break;
+
+		case typeDouble:
+			rFm = fpa11->fpreg[Fm].fDouble;
+			break;
+
+		default:
+			return 0;
+		}
+	}
+
+	opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
+	if (!MONADIC_INSTRUCTION(opcode)) {
+		unsigned int Fn = getFn(opcode);
+		float64 rFn;
+
+		switch (fpa11->fType[Fn]) {
+		case typeSingle:
+			rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle);
+			break;
+
+		case typeDouble:
+			rFn = fpa11->fpreg[Fn].fDouble;
+			break;
+
+		default:
+			return 0;
+		}
+
+		if (dyadic_double[opc_mask_shift]) {
+			rFd->fDouble = dyadic_double[opc_mask_shift](rFn, rFm);
+		} else {
+			return 0;
+		}
+	} else {
+		if (monadic_double[opc_mask_shift]) {
+			rFd->fDouble = monadic_double[opc_mask_shift](rFm);
+		} else {
+			return 0;
+		}
+	}
+
+	return 1;
 }
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/entry.S linux-2.4.22-pre10/arch/arm/nwfpe/entry.S
--- linux-2.4.21/arch/arm/nwfpe/entry.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/entry.S	2003-08-01 13:30:41.000000000 +0000
@@ -70,39 +70,42 @@
 
 	.globl	nwfpe_enter
 nwfpe_enter:
-        mov r4, lr			@ save the failure-return addresses
-	mov sl, sp			@ we access the registers via 'sl'
-
-        ldr r5, [sp, #60]	 	@ get contents of PC;
-	sub r8, r5, #4
-.Lx2:	ldrt r0, [r8]			@ get actual instruction into r0
+	mov	r4, lr			@ save the failure-return addresses
+	ldr	ip, [r10, #112]		@ get init_flag
+	mov	sl, sp			@ we access the registers via 'sl'
+
+	ldr	r5, [sp, #60]		@ get contents of PC;
+	cmp	ip, #0
+	bleq	nwfpe_init_fpa
+	sub	r8, r5, #4
+.Lx1:	ldrt	r0, [r8]		@ get actual instruction into r0
 emulate:
-	bl EmulateAll			@ emulate the instruction
-   	cmp r0, #0			@ was emulation successful
-        moveq pc, r4			@ no, return failure
+	bl	EmulateAll		@ emulate the instruction
+	cmp	r0, #0			@ was emulation successful
+	moveq	pc, r4			@ no, return failure
 
 next:
-.Lx1:	ldrt r6, [r5], #4		@ get the next instruction and
+.Lx2:	ldrt	r6, [r5], #4		@ get the next instruction and
 					@ increment PC
 
-	and   r2, r6, #0x0F000000	@ test for FP insns
-        teq   r2, #0x0C000000
-        teqne r2, #0x0D000000
-        teqne r2, #0x0E000000
-        movne pc, r9			@ return ok if not a fp insn
-
-        str r5, [sp, #60]		@ update PC copy in regs
-
-        mov r0, r6			@ save a copy
-        ldr r1, [sp, #64]		@ fetch the condition codes
-   	bl  checkCondition		@ check the condition
-   	cmp r0, #0			@ r0 = 0 ==> condition failed
-
-        @ if condition code failed to match, next insn
-   	beq next			@ get the next instruction;
-   	    
-        mov r0, r6			@ prepare for EmulateAll()
-   	b emulate			@ if r0 != 0, goto EmulateAll
+	and	r2, r6, #0x0F000000	@ test for FP insns
+	teq	r2, #0x0C000000
+	teqne	r2, #0x0D000000
+	teqne	r2, #0x0E000000
+	movne	pc, r9			@ return ok if not a fp insn
+
+	str	r5, [sp, #60]		@ update PC copy in regs
+
+	mov	r0, r6			@ save a copy
+	ldr	r1, [sp, #64]		@ fetch the condition codes
+	bl	checkCondition		@ check the condition
+	cmp	r0, #0			@ r0 = 0 ==> condition failed
+
+	@ if condition code failed to match, next insn
+	beq	next			@ get the next instruction;
+
+	mov	r0, r6			@ prepare for EmulateAll()
+	b	emulate			@ if r0 != 0, goto EmulateAll
 
 	@ We need to be prepared for the instructions at .Lx1 and .Lx2 
 	@ to fault.  Emit the appropriate exception gunk to fix things up.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/entry26.S linux-2.4.22-pre10/arch/arm/nwfpe/entry26.S
--- linux-2.4.21/arch/arm/nwfpe/entry26.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/entry26.S	2003-08-01 13:32:15.000000000 +0000
@@ -95,7 +95,7 @@
 
 	@ if condition code failed to match, next insn
 	beq	next			@ get the next instruction;
-	    
+
 	mov	r0, r6			@ prepare for EmulateAll()
 	adr	lr, 1b
 	orr	lr, lr, #3
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/extended_cpdo.c linux-2.4.22-pre10/arch/arm/nwfpe/extended_cpdo.c
--- linux-2.4.21/arch/arm/nwfpe/extended_cpdo.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/extended_cpdo.c	2003-08-01 13:33:36.000000000 +0000
@@ -32,242 +32,123 @@
 floatx80 floatx80_log(floatx80 rFm);
 floatx80 floatx80_tan(floatx80 rFm);
 floatx80 floatx80_arccos(floatx80 rFm);
-floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm);
-floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm);
+floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm);
+floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm);
 
-unsigned int ExtendedCPDO(const unsigned int opcode)
+static floatx80 floatx80_rsf(floatx80 rFn, floatx80 rFm)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   floatx80 rFm, rFn;
-   unsigned int Fd, Fm, Fn, nRc = 1;
-
-   //printk("ExtendedCPDO(0x%08x)\n",opcode);
-   
-   Fm = getFm(opcode);
-   if (CONSTANT_FM(opcode))
-   {
-     rFm = getExtendedConstant(Fm);
-   }
-   else
-   {  
-     switch (fpa11->fType[Fm])
-     {
-        case typeSingle:
-          rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
-        break;
-
-        case typeDouble:
-          rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
-        break;
-        
-        case typeExtended:
-          rFm = fpa11->fpreg[Fm].fExtended;
-        break;
-        
-        default: return 0;
-     }
-   }
-   
-   if (!MONADIC_INSTRUCTION(opcode))
-   {
-      Fn = getFn(opcode);
-      switch (fpa11->fType[Fn])
-      {
-        case typeSingle:
-          rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
-        break;
-
-        case typeDouble:
-          rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
-        break;
-        
-        case typeExtended:
-          rFn = fpa11->fpreg[Fn].fExtended;
-        break;
-        
-        default: return 0;
-      }
-   }
-
-   Fd = getFd(opcode);
-   switch (opcode & MASK_ARITHMETIC_OPCODE)
-   {
-      /* dyadic opcodes */
-      case ADF_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_add(rFn,rFm);
-      break;
-
-      case MUF_CODE:
-      case FML_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_mul(rFn,rFm);
-      break;
-
-      case SUF_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_sub(rFn,rFm);
-      break;
-
-      case RSF_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_sub(rFm,rFn);
-      break;
-
-      case DVF_CODE:
-      case FDV_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_div(rFn,rFm);
-      break;
-
-      case RDF_CODE:
-      case FRD_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_div(rFm,rFn);
-      break;
-
-#if 0
-      case POW_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_pow(rFn,rFm);
-      break;
-
-      case RPW_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_pow(rFm,rFn);
-      break;
-#endif
-
-      case RMF_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_rem(rFn,rFm);
-      break;
-
-#if 0
-      case POL_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_pol(rFn,rFm);
-      break;
-#endif
-
-      /* monadic opcodes */
-      case MVF_CODE:
-         fpa11->fpreg[Fd].fExtended = rFm;
-      break;
-
-      case MNF_CODE:
-         rFm.high ^= 0x8000;
-         fpa11->fpreg[Fd].fExtended = rFm;
-      break;
-
-      case ABS_CODE:
-         rFm.high &= 0x7fff;
-         fpa11->fpreg[Fd].fExtended = rFm;
-      break;
-
-      case RND_CODE:
-      case URD_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_round_to_int(rFm);
-      break;
-
-      case SQT_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_sqrt(rFm);
-      break;
-
-#if 0
-      case LOG_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_log(rFm);
-      break;
-
-      case LGN_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_ln(rFm);
-      break;
-
-      case EXP_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_exp(rFm);
-      break;
-
-      case SIN_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_sin(rFm);
-      break;
-
-      case COS_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_cos(rFm);
-      break;
-
-      case TAN_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_tan(rFm);
-      break;
-
-      case ASN_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_arcsin(rFm);
-      break;
-
-      case ACS_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_arccos(rFm);
-      break;
-
-      case ATN_CODE:
-         fpa11->fpreg[Fd].fExtended = floatx80_arctan(rFm);
-      break;
-#endif
-
-      case NRM_CODE:
-      break;
-      
-      default:
-      {
-        nRc = 0;
-      }
-   }
-   
-   if (0 != nRc) fpa11->fType[Fd] = typeExtended;
-   return nRc;
+	return floatx80_sub(rFm, rFn);
 }
 
-#if 0
-floatx80 floatx80_exp(floatx80 Fm)
+static floatx80 floatx80_rdv(floatx80 rFn, floatx80 rFm)
 {
-//series
+	return floatx80_div(rFm, rFn);
 }
 
-floatx80 floatx80_ln(floatx80 Fm)
-{
-//series
-}
+static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = {
+	[ADF_CODE >> 20] = floatx80_add,
+	[MUF_CODE >> 20] = floatx80_mul,
+	[SUF_CODE >> 20] = floatx80_sub,
+	[RSF_CODE >> 20] = floatx80_rsf,
+	[DVF_CODE >> 20] = floatx80_div,
+	[RDF_CODE >> 20] = floatx80_rdv,
+	[RMF_CODE >> 20] = floatx80_rem,
 
-floatx80 floatx80_sin(floatx80 rFm)
-{
-//series
-}
+	/* strictly, these opcodes should not be implemented */
+	[FML_CODE >> 20] = floatx80_mul,
+	[FDV_CODE >> 20] = floatx80_div,
+	[FRD_CODE >> 20] = floatx80_rdv,
+};
 
-floatx80 floatx80_cos(floatx80 rFm)
+static floatx80 floatx80_mvf(floatx80 rFm)
 {
-//series
+	return rFm;
 }
 
-floatx80 floatx80_arcsin(floatx80 rFm)
+static floatx80 floatx80_mnf(floatx80 rFm)
 {
-//series
+	rFm.high ^= 0x8000;
+	return rFm;
 }
 
-floatx80 floatx80_arctan(floatx80 rFm)
+static floatx80 floatx80_abs(floatx80 rFm)
 {
-  //series
+	rFm.high &= 0x7fff;
+	return rFm;
 }
 
-floatx80 floatx80_log(floatx80 rFm)
-{
-  return floatx80_div(floatx80_ln(rFm),getExtendedConstant(7));
-}
+static floatx80 (*const monadic_extended[16])(floatx80 rFm) = {
+	[MVF_CODE >> 20] = floatx80_mvf,
+	[MNF_CODE >> 20] = floatx80_mnf,
+	[ABS_CODE >> 20] = floatx80_abs,
+	[RND_CODE >> 20] = floatx80_round_to_int,
+	[URD_CODE >> 20] = floatx80_round_to_int,
+	[SQT_CODE >> 20] = floatx80_sqrt,
+	[NRM_CODE >> 20] = floatx80_mvf,
+};
 
-floatx80 floatx80_tan(floatx80 rFm)
+unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd)
 {
-  return floatx80_div(floatx80_sin(rFm),floatx80_cos(rFm));
-}
+	FPA11 *fpa11 = GET_FPA11();
+	floatx80 rFm;
+	unsigned int Fm, opc_mask_shift;
 
-floatx80 floatx80_arccos(floatx80 rFm)
-{
-   //return floatx80_sub(halfPi,floatx80_arcsin(rFm));
-}
+	Fm = getFm(opcode);
+	if (CONSTANT_FM(opcode)) {
+		rFm = getExtendedConstant(Fm);
+	} else {
+		switch (fpa11->fType[Fm]) {
+		case typeSingle:
+			rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
+			break;
 
-floatx80 floatx80_pow(floatx80 rFn,floatx80 rFm)
-{
-  return floatx80_exp(floatx80_mul(rFm,floatx80_ln(rFn))); 
-}
+		case typeDouble:
+			rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
+			break;
 
-floatx80 floatx80_pol(floatx80 rFn,floatx80 rFm)
-{
-  return floatx80_arctan(floatx80_div(rFn,rFm)); 
+		case typeExtended:
+			rFm = fpa11->fpreg[Fm].fExtended;
+			break;
+
+		default:
+			return 0;
+		}
+	}
+
+	opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
+	if (!MONADIC_INSTRUCTION(opcode)) {
+		unsigned int Fn = getFn(opcode);
+		floatx80 rFn;
+
+		switch (fpa11->fType[Fn]) {
+		case typeSingle:
+			rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
+			break;
+
+		case typeDouble:
+			rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
+			break;
+
+		case typeExtended:
+			rFn = fpa11->fpreg[Fn].fExtended;
+			break;
+
+		default:
+			return 0;
+		}
+
+		if (dyadic_extended[opc_mask_shift]) {
+			rFd->fExtended = dyadic_extended[opc_mask_shift](rFn, rFm);
+		} else {
+			return 0;
+		}
+	} else {
+		if (monadic_extended[opc_mask_shift]) {
+			rFd->fExtended = monadic_extended[opc_mask_shift](rFm);
+		} else {
+			return 0;
+		}
+	}
+
+	return 1;
 }
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/fpa11.c linux-2.4.22-pre10/arch/arm/nwfpe/fpa11.c
--- linux-2.4.21/arch/arm/nwfpe/fpa11.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/fpa11.c	2003-08-01 13:32:41.000000000 +0000
@@ -1,6 +1,7 @@
 /*
     NetWinder Floating Point Emulator
     (c) Rebel.COM, 1998,1999
+    (c) Philip Blundell, 2001
 
     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
 
@@ -20,7 +21,6 @@
 */
 
 #include "fpa11.h"
-
 #include "fpopcode.h"
 
 #include "fpmodule.h"
@@ -36,180 +36,96 @@
 /* Reset the FPA11 chip.  Called to initialize and reset the emulator. */
 void resetFPA11(void)
 {
-  int i;
-  FPA11 *fpa11 = GET_FPA11();
-  
-  /* initialize the register type array */
-  for (i=0;i<=7;i++)
-  {
-    fpa11->fType[i] = typeNone;
-  }
-  
-  /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
-  fpa11->fpsr = FP_EMULATOR | BIT_AC;
-  
-  /* FPCR: set SB, AB and DA bits, clear all others */
-#if MAINTAIN_FPCR
-  fpa11->fpcr = MASK_RESET;
-#endif
+	int i;
+	FPA11 *fpa11 = GET_FPA11();
+
+	/* initialize the register type array */
+	for (i = 0; i <= 7; i++) {
+		fpa11->fType[i] = typeNone;
+	}
+
+	/* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
+	fpa11->fpsr = FP_EMULATOR | BIT_AC;
 }
 
 void SetRoundingMode(const unsigned int opcode)
 {
-#if MAINTAIN_FPCR
-   FPA11 *fpa11 = GET_FPA11();
-   fpa11->fpcr &= ~MASK_ROUNDING_MODE;
-#endif   
-   switch (opcode & MASK_ROUNDING_MODE)
-   {
-      default:
-      case ROUND_TO_NEAREST:
-         float_rounding_mode = float_round_nearest_even;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_TO_NEAREST;
-#endif         
-      break;
-      
-      case ROUND_TO_PLUS_INFINITY:
-         float_rounding_mode = float_round_up;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_TO_PLUS_INFINITY;
-#endif         
-      break;
-      
-      case ROUND_TO_MINUS_INFINITY:
-         float_rounding_mode = float_round_down;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_TO_MINUS_INFINITY;
-#endif         
-      break;
-      
-      case ROUND_TO_ZERO:
-         float_rounding_mode = float_round_to_zero;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_TO_ZERO;
-#endif         
-      break;
-  }
+	switch (opcode & MASK_ROUNDING_MODE) {
+	default:
+	case ROUND_TO_NEAREST:
+		float_rounding_mode = float_round_nearest_even;
+		break;
+
+	case ROUND_TO_PLUS_INFINITY:
+		float_rounding_mode = float_round_up;
+		break;
+
+	case ROUND_TO_MINUS_INFINITY:
+		float_rounding_mode = float_round_down;
+		break;
+
+	case ROUND_TO_ZERO:
+		float_rounding_mode = float_round_to_zero;
+		break;
+	}
 }
 
 void SetRoundingPrecision(const unsigned int opcode)
 {
-#if MAINTAIN_FPCR
-   FPA11 *fpa11 = GET_FPA11();
-   fpa11->fpcr &= ~MASK_ROUNDING_PRECISION;
-#endif   
-   switch (opcode & MASK_ROUNDING_PRECISION)
-   {
-      case ROUND_SINGLE:
-         floatx80_rounding_precision = 32;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_SINGLE;
-#endif         
-      break;
-      
-      case ROUND_DOUBLE:
-         floatx80_rounding_precision = 64;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_DOUBLE;
-#endif         
-      break;
-      
-      case ROUND_EXTENDED:
-         floatx80_rounding_precision = 80;
-#if MAINTAIN_FPCR         
-         fpa11->fpcr |= ROUND_EXTENDED;
-#endif         
-      break;
-      
-      default: floatx80_rounding_precision = 80;
-  }
+#ifdef CONFIG_FPE_NWFPE_XP
+	switch (opcode & MASK_ROUNDING_PRECISION) {
+	case ROUND_SINGLE:
+		floatx80_rounding_precision = 32;
+		break;
+
+	case ROUND_DOUBLE:
+		floatx80_rounding_precision = 64;
+		break;
+
+	case ROUND_EXTENDED:
+		floatx80_rounding_precision = 80;
+		break;
+
+	default:
+		floatx80_rounding_precision = 80;
+	}
+#endif
 }
 
-/* Emulate the instruction in the opcode. */
-unsigned int EmulateAll(unsigned int opcode)
+void nwfpe_init_fpa(void)
 {
-  unsigned int nRc = 0;
-  unsigned long flags;
-  FPA11 *fpa11; 
-  save_flags(flags); sti();
-
-  fpa11 = GET_FPA11();
-
-  if (fpa11->initflag == 0)		/* good place for __builtin_expect */
-  {
-    resetFPA11();
-    SetRoundingMode(ROUND_TO_NEAREST);
-    SetRoundingPrecision(ROUND_EXTENDED);
-    fpa11->initflag = 1;
-  }
-
-  if (TEST_OPCODE(opcode,MASK_CPRT))
-  {
-    /* Emulate conversion opcodes. */
-    /* Emulate register transfer opcodes. */
-    /* Emulate comparison opcodes. */
-    nRc = EmulateCPRT(opcode);
-  }
-  else if (TEST_OPCODE(opcode,MASK_CPDO))
-  {
-    /* Emulate monadic arithmetic opcodes. */
-    /* Emulate dyadic arithmetic opcodes. */
-    nRc = EmulateCPDO(opcode);
-  }
-  else if (TEST_OPCODE(opcode,MASK_CPDT))
-  {
-    /* Emulate load/store opcodes. */
-    /* Emulate load/store multiple opcodes. */
-    nRc = EmulateCPDT(opcode);
-  }
-  else
-  {
-    /* Invalid instruction detected.  Return FALSE. */
-    nRc = 0;
-  }
-
-  restore_flags(flags);
-
-  return(nRc);
+	FPA11 *fpa11 = GET_FPA11();
+#ifdef NWFPE_DEBUG
+	printk("NWFPE: setting up state.\n");
+#endif
+	resetFPA11();
+	SetRoundingMode(ROUND_TO_NEAREST);
+	SetRoundingPrecision(ROUND_EXTENDED);
+	fpa11->initflag = 1;
 }
 
-#if 0
-unsigned int EmulateAll1(unsigned int opcode)
+/* Emulate the instruction in the opcode. */
+unsigned int EmulateAll(const unsigned int opcode)
 {
-  switch ((opcode >> 24) & 0xf)
-  {
-     case 0xc:
-     case 0xd:
-       if ((opcode >> 20) & 0x1)
-       {
-          switch ((opcode >> 8) & 0xf)
-          {
-             case 0x1: return PerformLDF(opcode); break;
-             case 0x2: return PerformLFM(opcode); break;
-             default: return 0;
-          }
-       }
-       else
-       {
-          switch ((opcode >> 8) & 0xf)
-          {
-             case 0x1: return PerformSTF(opcode); break;
-             case 0x2: return PerformSFM(opcode); break;
-             default: return 0;
-          }
-      }
-     break;
-     
-     case 0xe: 
-       if (opcode & 0x10)
-         return EmulateCPDO(opcode);
-       else
-         return EmulateCPRT(opcode);
-     break;
-  
-     default: return 0;
-  }
-}
+#ifdef NWFPE_DEBUG
+	printk("NWFPE: emulating opcode %08x\n", opcode);
 #endif
 
+	if (TEST_OPCODE(opcode, MASK_CPRT)) {
+		/* Emulate conversion opcodes. */
+		/* Emulate register transfer opcodes. */
+		/* Emulate comparison opcodes. */
+		return EmulateCPRT(opcode);
+	} else if (TEST_OPCODE(opcode, MASK_CPDO)) {
+		/* Emulate monadic arithmetic opcodes. */
+		/* Emulate dyadic arithmetic opcodes. */
+		return EmulateCPDO(opcode);
+	} else if (TEST_OPCODE(opcode, MASK_CPDT)) {
+		/* Emulate load/store opcodes. */
+		/* Emulate load/store multiple opcodes. */
+		return EmulateCPDT(opcode);
+	}
+
+	/* Invalid instruction detected.  Return FALSE. */
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/fpa11.h linux-2.4.22-pre10/arch/arm/nwfpe/fpa11.h
--- linux-2.4.21/arch/arm/nwfpe/fpa11.h	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/fpa11.h	2003-08-01 13:33:02.000000000 +0000
@@ -38,6 +38,7 @@
 
 /* includes */
 #include "fpsr.h"		/* FP control and status register definitions */
+#include "milieu.h"
 #include "softfloat.h"
 
 #define		typeNone		0x00
@@ -49,9 +50,13 @@
  * This must be no more and no less than 12 bytes.
  */
 typedef union tagFPREG {
-   floatx80 fExtended;
-   float64  fDouble;
-   float32  fSingle;
+	float32 fSingle;
+	float64 fDouble;
+#ifdef CONFIG_FPE_NWFPE_XP
+	floatx80 fExtended;
+#else
+	int padding[3];
+#endif
 } FPREG;
 
 /*
@@ -68,17 +73,17 @@
  * not initialise.
  */
 typedef struct tagFPA11 {
-/*   0 */  FPREG fpreg[8];		/* 8 floating point registers */
-/*  96 */  FPSR fpsr;			/* floating point status register */
-/* 100 */  FPCR fpcr;			/* floating point control register */
-/* 104 */  unsigned char fType[8];	/* type of floating point value held in
-					   floating point registers.  One of none
-					   single, double or extended. */
-/* 112 */  int initflag;		/* this is special.  The kernel guarantees
-					   to set it to 0 when a thread is launched,
-					   so we can use it to detect whether this
-					   instance of the emulator needs to be
-					   initialised. */
+/*   0 */ FPREG fpreg[8];	/* 8 floating point registers */
+/*  96 */ FPSR fpsr;		/* floating point status register */
+/* 100 */ FPCR fpcr;		/* floating point control register */
+/* 104 */ unsigned char fType[8];	/* type of floating point value held in
+					   floating point registers.  One of
+					   none, single, double or extended. */
+/* 112 */ int initflag;		/* this is special.  The kernel guarantees
+				   to set it to 0 when a thread is launched,
+				   so we can use it to detect whether this
+				   instance of the emulator needs to be
+				   initialised. */
 } FPA11;
 
 extern void resetFPA11(void);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/fpa11.inl linux-2.4.22-pre10/arch/arm/nwfpe/fpa11.inl
--- linux-2.4.21/arch/arm/nwfpe/fpa11.inl	2001-08-12 18:13:59.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/fpa11.inl	2003-08-01 13:33:18.000000000 +0000
@@ -24,28 +24,28 @@
 /* Read and write floating point status register */
 extern __inline__ unsigned int readFPSR(void)
 {
-  FPA11 *fpa11 = GET_FPA11();
-  return(fpa11->fpsr);
+	FPA11 *fpa11 = GET_FPA11();
+	return (fpa11->fpsr);
 }
 
 extern __inline__ void writeFPSR(FPSR reg)
 {
-  FPA11 *fpa11 = GET_FPA11();
-  /* the sysid byte in the status register is readonly */
-  fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID);
+	FPA11 *fpa11 = GET_FPA11();
+	/* the sysid byte in the status register is readonly */
+	fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID);
 }
 
 /* Read and write floating point control register */
 extern __inline__ FPCR readFPCR(void)
 {
-  FPA11 *fpa11 = GET_FPA11();
-  /* clear SB, AB and DA bits before returning FPCR */
-  return(fpa11->fpcr & ~MASK_RFC);
+	FPA11 *fpa11 = GET_FPA11();
+	/* clear SB, AB and DA bits before returning FPCR */
+	return (fpa11->fpcr & ~MASK_RFC);
 }
 
 extern __inline__ void writeFPCR(FPCR reg)
 {
-  FPA11 *fpa11 = GET_FPA11();
-  fpa11->fpcr &= ~MASK_WFC;		/* clear SB, AB and DA bits */
-  fpa11->fpcr |= (reg & MASK_WFC);	/* write SB, AB and DA bits */
+	FPA11 *fpa11 = GET_FPA11();
+	fpa11->fpcr &= ~MASK_WFC;		/* clear SB, AB and DA bits */
+	fpa11->fpcr |= (reg & MASK_WFC);	/* write SB, AB and DA bits */
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/fpa11_cpdo.c linux-2.4.22-pre10/arch/arm/nwfpe/fpa11_cpdo.c
--- linux-2.4.21/arch/arm/nwfpe/fpa11_cpdo.c	2001-08-12 18:13:59.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/fpa11_cpdo.c	2003-08-01 13:34:04.000000000 +0000
@@ -1,6 +1,7 @@
 /*
     NetWinder Floating Point Emulator
     (c) Rebel.COM, 1998,1999
+    (c) Philip Blundell, 2001
 
     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
 
@@ -22,96 +23,109 @@
 #include "fpa11.h"
 #include "fpopcode.h"
 
-unsigned int SingleCPDO(const unsigned int opcode);
-unsigned int DoubleCPDO(const unsigned int opcode);
-unsigned int ExtendedCPDO(const unsigned int opcode);
+unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd);
+unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd);
+unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd);
 
 unsigned int EmulateCPDO(const unsigned int opcode)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   unsigned int Fd, nType, nDest, nRc = 1;
-   
-   //printk("EmulateCPDO(0x%08x)\n",opcode);
-
-   /* Get the destination size.  If not valid let Linux perform
-      an invalid instruction trap. */
-   nDest = getDestinationSize(opcode);
-   if (typeNone == nDest) return 0;
-   
-   SetRoundingMode(opcode);
-     
-   /* Compare the size of the operands in Fn and Fm.
-      Choose the largest size and perform operations in that size,
-      in order to make use of all the precision of the operands. 
-      If Fm is a constant, we just grab a constant of a size 
-      matching the size of the operand in Fn. */
-   if (MONADIC_INSTRUCTION(opcode))
-     nType = nDest;
-   else
-     nType = fpa11->fType[getFn(opcode)];
-   
-   if (!CONSTANT_FM(opcode))
-   {
-     register unsigned int Fm = getFm(opcode);
-     if (nType < fpa11->fType[Fm])
-     {
-        nType = fpa11->fType[Fm];
-     }
-   }
-
-   switch (nType)
-   {
-      case typeSingle   : nRc = SingleCPDO(opcode);   break;
-      case typeDouble   : nRc = DoubleCPDO(opcode);   break;
-      case typeExtended : nRc = ExtendedCPDO(opcode); break;
-      default           : nRc = 0;
-   }
-
-   /* If the operation succeeded, check to see if the result in the
-      destination register is the correct size.  If not force it
-      to be. */
-   Fd = getFd(opcode);
-   nType = fpa11->fType[Fd];
-   if ((0 != nRc) && (nDest != nType))
-   {
-     switch (nDest)
-     {
-       case typeSingle:
-       {
-         if (typeDouble == nType)
-           fpa11->fpreg[Fd].fSingle = 
-              float64_to_float32(fpa11->fpreg[Fd].fDouble);
-         else
-           fpa11->fpreg[Fd].fSingle = 
-              floatx80_to_float32(fpa11->fpreg[Fd].fExtended);
-       }
-       break;
-          
-       case typeDouble:
-       {
-         if (typeSingle == nType)
-           fpa11->fpreg[Fd].fDouble = 
-              float32_to_float64(fpa11->fpreg[Fd].fSingle);
-         else
-           fpa11->fpreg[Fd].fDouble = 
-              floatx80_to_float64(fpa11->fpreg[Fd].fExtended);
-       }
-       break;
-          
-       case typeExtended:
-       {
-         if (typeSingle == nType)
-           fpa11->fpreg[Fd].fExtended = 
-              float32_to_floatx80(fpa11->fpreg[Fd].fSingle);
-         else
-           fpa11->fpreg[Fd].fExtended = 
-              float64_to_floatx80(fpa11->fpreg[Fd].fDouble);
-       }
-       break;
-     }
-     
-     fpa11->fType[Fd] = nDest;
-   }
-   
-   return nRc;
+	FPA11 *fpa11 = GET_FPA11();
+	FPREG *rFd;
+	unsigned int nType, nDest, nRc;
+
+	/* Get the destination size.  If not valid let Linux perform
+	   an invalid instruction trap. */
+	nDest = getDestinationSize(opcode);
+	if (typeNone == nDest)
+		return 0;
+
+	SetRoundingMode(opcode);
+
+	/* Compare the size of the operands in Fn and Fm.
+	   Choose the largest size and perform operations in that size,
+	   in order to make use of all the precision of the operands.
+	   If Fm is a constant, we just grab a constant of a size
+	   matching the size of the operand in Fn. */
+	if (MONADIC_INSTRUCTION(opcode))
+		nType = nDest;
+	else
+		nType = fpa11->fType[getFn(opcode)];
+
+	if (!CONSTANT_FM(opcode)) {
+		register unsigned int Fm = getFm(opcode);
+		if (nType < fpa11->fType[Fm]) {
+			nType = fpa11->fType[Fm];
+		}
+	}
+
+	rFd = &fpa11->fpreg[getFd(opcode)];
+
+	switch (nType) {
+	case typeSingle:
+		nRc = SingleCPDO(opcode, rFd);
+		break;
+	case typeDouble:
+		nRc = DoubleCPDO(opcode, rFd);
+		break;
+#ifdef CONFIG_FPE_NWFPE_XP
+	case typeExtended:
+		nRc = ExtendedCPDO(opcode, rFd);
+		break;
+#endif
+	default:
+		nRc = 0;
+	}
+
+	/* The CPDO functions used to always set the destination type
+	   to be the same as their working size. */
+
+	if (nRc != 0) {
+		/* If the operation succeeded, check to see if the result in the
+		   destination register is the correct size.  If not force it
+		   to be. */
+
+		fpa11->fType[getFd(opcode)] = nDest;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+		if (nDest != nType) {
+			switch (nDest) {
+			case typeSingle:
+				{
+					if (typeDouble == nType)
+						rFd->fSingle = float64_to_float32(rFd->fDouble);
+					else
+						rFd->fSingle = floatx80_to_float32(rFd->fExtended);
+				}
+				break;
+
+			case typeDouble:
+				{
+					if (typeSingle == nType)
+						rFd->fDouble = float32_to_float64(rFd->fSingle);
+					else
+						rFd->fDouble = floatx80_to_float64(rFd->fExtended);
+				}
+				break;
+
+			case typeExtended:
+				{
+					if (typeSingle == nType)
+						rFd->fExtended = float32_to_floatx80(rFd->fSingle);
+					else
+						rFd->fExtended = float64_to_floatx80(rFd->fDouble);
+				}
+				break;
+			}
+		}
+#else
+		if (nDest != nType) {
+			if (nDest == typeSingle)
+				rFd->fSingle = float64_to_float32(rFd->fDouble);
+			else
+				rFd->fDouble = float32_to_float64(rFd->fSingle);
+		}
+#endif
+	}
+
+	return nRc;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/fpa11_cpdt.c linux-2.4.22-pre10/arch/arm/nwfpe/fpa11_cpdt.c
--- linux-2.4.21/arch/arm/nwfpe/fpa11_cpdt.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/fpa11_cpdt.c	2003-08-01 13:34:43.000000000 +0000
@@ -1,7 +1,7 @@
 /*
     NetWinder Floating Point Emulator
     (c) Rebel.com, 1998-1999
-    (c) Philip Blundell, 1998
+    (c) Philip Blundell, 1998, 2001
 
     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
 
@@ -28,331 +28,347 @@
 
 #include <asm/uaccess.h>
 
-static inline
-void loadSingle(const unsigned int Fn,const unsigned int *pMem)
+static inline void loadSingle(const unsigned int Fn, const unsigned int *pMem)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   fpa11->fType[Fn] = typeSingle;
-   get_user(fpa11->fpreg[Fn].fSingle, pMem);
-}
-
-static inline
-void loadDouble(const unsigned int Fn,const unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   unsigned int *p;
-   p = (unsigned int*)&fpa11->fpreg[Fn].fDouble;
-   fpa11->fType[Fn] = typeDouble;
-   get_user(p[0], &pMem[1]);
-   get_user(p[1], &pMem[0]); /* sign & exponent */
-}   
-
-static inline
-void loadExtended(const unsigned int Fn,const unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   unsigned int *p;
-   p = (unsigned int*)&fpa11->fpreg[Fn].fExtended;
-   fpa11->fType[Fn] = typeExtended;
-   get_user(p[0], &pMem[0]);  /* sign & exponent */
-   get_user(p[1], &pMem[2]);  /* ls bits */
-   get_user(p[2], &pMem[1]);  /* ms bits */
-}   
-
-static inline
-void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   register unsigned int *p;
-   unsigned long x;
-
-   p = (unsigned int*)&(fpa11->fpreg[Fn]);
-   get_user(x, &pMem[0]);
-   fpa11->fType[Fn] = (x >> 14) & 0x00000003;
-   
-   switch (fpa11->fType[Fn])
-   {
-      case typeSingle:
-      case typeDouble:
-      {
-         get_user(p[0], &pMem[2]);  /* Single */
-         get_user(p[1], &pMem[1]);  /* double msw */
-         p[2] = 0;        /* empty */
-      }
-      break; 
-   
-      case typeExtended:
-      {
-         get_user(p[1], &pMem[2]);
-         get_user(p[2], &pMem[1]);  /* msw */
-         p[0] = (x & 0x80003fff);      
-      }
-      break;
-   }
-}
-
-static inline
-void storeSingle(const unsigned int Fn,unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   float32 val;
-   register unsigned int *p = (unsigned int*)&val;
-   
-   switch (fpa11->fType[Fn])
-   {
-      case typeDouble: 
-         val = float64_to_float32(fpa11->fpreg[Fn].fDouble);
-      break;
-
-      case typeExtended: 
-         val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended);
-      break;
-
-      default: val = fpa11->fpreg[Fn].fSingle;
-   }
-  
-   put_user(p[0], pMem);
-}   
-
-static inline
-void storeDouble(const unsigned int Fn,unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   float64 val;
-   register unsigned int *p = (unsigned int*)&val;
-
-   switch (fpa11->fType[Fn])
-   {
-      case typeSingle: 
-         val = float32_to_float64(fpa11->fpreg[Fn].fSingle);
-      break;
-
-      case typeExtended:
-         val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended);
-      break;
-
-      default: val = fpa11->fpreg[Fn].fDouble;
-   }
-   put_user(p[1], &pMem[0]);	/* msw */
-   put_user(p[0], &pMem[1]);	/* lsw */
-}   
-
-static inline
-void storeExtended(const unsigned int Fn,unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   floatx80 val;
-   register unsigned int *p = (unsigned int*)&val;
-   
-   switch (fpa11->fType[Fn])
-   {
-      case typeSingle: 
-         val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
-      break;
-
-      case typeDouble: 
-         val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
-      break;
-
-      default: val = fpa11->fpreg[Fn].fExtended;
-   }
-   
-   put_user(p[0], &pMem[0]); /* sign & exp */
-   put_user(p[1], &pMem[2]);
-   put_user(p[2], &pMem[1]); /* msw */
-}   
-
-static inline
-void storeMultiple(const unsigned int Fn,unsigned int *pMem)
-{
-   FPA11 *fpa11 = GET_FPA11();
-   register unsigned int nType, *p;
-   
-   p = (unsigned int*)&(fpa11->fpreg[Fn]);
-   nType = fpa11->fType[Fn];
-   
-   switch (nType)
-   {
-      case typeSingle:
-      case typeDouble:
-      {
-	 put_user(p[0], &pMem[2]); /* single */
-	 put_user(p[1], &pMem[1]); /* double msw */
-	 put_user(nType << 14, &pMem[0]);
-      }
-      break; 
-   
-      case typeExtended:
-      {
-	 put_user(p[2], &pMem[1]); /* msw */
-	 put_user(p[1], &pMem[2]);
-	 put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]);
-      }
-      break;
-   }
+	FPA11 *fpa11 = GET_FPA11();
+	fpa11->fType[Fn] = typeSingle;
+	get_user(fpa11->fpreg[Fn].fSingle, pMem);
 }
 
-unsigned int PerformLDF(const unsigned int opcode)
+static inline void loadDouble(const unsigned int Fn, const unsigned int *pMem)
+{
+	FPA11 *fpa11 = GET_FPA11();
+	unsigned int *p;
+	p = (unsigned int *) &fpa11->fpreg[Fn].fDouble;
+	fpa11->fType[Fn] = typeDouble;
+	get_user(p[0], &pMem[1]);
+	get_user(p[1], &pMem[0]);	/* sign & exponent */
+}
+
+#ifdef CONFIG_FPE_NWFPE_XP
+static inline void loadExtended(const unsigned int Fn, const unsigned int *pMem)
+{
+	FPA11 *fpa11 = GET_FPA11();
+	unsigned int *p;
+	p = (unsigned int *) &fpa11->fpreg[Fn].fExtended;
+	fpa11->fType[Fn] = typeExtended;
+	get_user(p[0], &pMem[0]);	/* sign & exponent */
+	get_user(p[1], &pMem[2]);	/* ls bits */
+	get_user(p[2], &pMem[1]);	/* ms bits */
+}
+#endif
+
+static inline void loadMultiple(const unsigned int Fn, const unsigned int *pMem)
+{
+	FPA11 *fpa11 = GET_FPA11();
+	register unsigned int *p;
+	unsigned long x;
+
+	p = (unsigned int *) &(fpa11->fpreg[Fn]);
+	get_user(x, &pMem[0]);
+	fpa11->fType[Fn] = (x >> 14) & 0x00000003;
+
+	switch (fpa11->fType[Fn]) {
+	case typeSingle:
+	case typeDouble:
+		{
+			get_user(p[0], &pMem[2]);	/* Single */
+			get_user(p[1], &pMem[1]);	/* double msw */
+			p[2] = 0;			/* empty */
+		}
+		break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	case typeExtended:
+		{
+			get_user(p[1], &pMem[2]);
+			get_user(p[2], &pMem[1]);	/* msw */
+			p[0] = (x & 0x80003fff);
+		}
+		break;
+#endif
+	}
+}
+
+static inline void storeSingle(const unsigned int Fn, unsigned int *pMem)
+{
+	FPA11 *fpa11 = GET_FPA11();
+	float32 val;
+	register unsigned int *p = (unsigned int *) &val;
+
+	switch (fpa11->fType[Fn]) {
+	case typeDouble:
+		val = float64_to_float32(fpa11->fpreg[Fn].fDouble);
+		break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	case typeExtended:
+		val = floatx80_to_float32(fpa11->fpreg[Fn].fExtended);
+		break;
+#endif
+
+	default:
+		val = fpa11->fpreg[Fn].fSingle;
+	}
+
+	put_user(p[0], pMem);
+}
+
+static inline void storeDouble(const unsigned int Fn, unsigned int *pMem)
+{
+	FPA11 *fpa11 = GET_FPA11();
+	float64 val;
+	register unsigned int *p = (unsigned int *) &val;
+
+	switch (fpa11->fType[Fn]) {
+	case typeSingle:
+		val = float32_to_float64(fpa11->fpreg[Fn].fSingle);
+		break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	case typeExtended:
+		val = floatx80_to_float64(fpa11->fpreg[Fn].fExtended);
+		break;
+#endif
+
+	default:
+		val = fpa11->fpreg[Fn].fDouble;
+	}
+	put_user(p[1], &pMem[0]);	/* msw */
+	put_user(p[0], &pMem[1]);	/* lsw */
+}
+
+#ifdef CONFIG_FPE_NWFPE_XP
+static inline void storeExtended(const unsigned int Fn, unsigned int *pMem)
+{
+	FPA11 *fpa11 = GET_FPA11();
+	floatx80 val;
+	register unsigned int *p = (unsigned int *) &val;
+
+	switch (fpa11->fType[Fn]) {
+	case typeSingle:
+		val = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
+		break;
+
+	case typeDouble:
+		val = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
+		break;
+
+	default:
+		val = fpa11->fpreg[Fn].fExtended;
+	}
+
+	put_user(p[0], &pMem[0]);	/* sign & exp */
+	put_user(p[1], &pMem[2]);
+	put_user(p[2], &pMem[1]);	/* msw */
+}
+#endif
+
+static inline void storeMultiple(const unsigned int Fn, unsigned int *pMem)
 {
-   unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
-     write_back = WRITE_BACK(opcode);
+	FPA11 *fpa11 = GET_FPA11();
+	register unsigned int nType, *p;
+
+	p = (unsigned int *) &(fpa11->fpreg[Fn]);
+	nType = fpa11->fType[Fn];
+
+	switch (nType) {
+	case typeSingle:
+	case typeDouble:
+		{
+			put_user(p[0], &pMem[2]);	/* single */
+			put_user(p[1], &pMem[1]);	/* double msw */
+			put_user(nType << 14, &pMem[0]);
+		}
+		break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	case typeExtended:
+		{
+			put_user(p[2], &pMem[1]);	/* msw */
+			put_user(p[1], &pMem[2]);
+			put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]);
+		}
+		break;
+#endif
+	}
+}
 
-   //printk("PerformLDF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
+unsigned int PerformLDF(const unsigned int opcode)
+{
+	unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
+	    write_back = WRITE_BACK(opcode);
 
-   pBase = (unsigned int*)readRegister(getRn(opcode));
-   if (REG_PC == getRn(opcode))
-   {
-     pBase += 2;
-     write_back = 0;
-   }
-
-   pFinal = pBase;
-   if (BIT_UP_SET(opcode))
-     pFinal += getOffset(opcode);
-   else
-     pFinal -= getOffset(opcode);
-
-   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
-
-   switch (opcode & MASK_TRANSFER_LENGTH)
-   {
-      case TRANSFER_SINGLE  : loadSingle(getFd(opcode),pAddress);   break;
-      case TRANSFER_DOUBLE  : loadDouble(getFd(opcode),pAddress);   break;
-      case TRANSFER_EXTENDED: loadExtended(getFd(opcode),pAddress); break;
-      default: nRc = 0;
-   }
-   
-   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
-   return nRc;
+	pBase = (unsigned int *) readRegister(getRn(opcode));
+	if (REG_PC == getRn(opcode)) {
+		pBase += 2;
+		write_back = 0;
+	}
+
+	pFinal = pBase;
+	if (BIT_UP_SET(opcode))
+		pFinal += getOffset(opcode);
+	else
+		pFinal -= getOffset(opcode);
+
+	if (PREINDEXED(opcode))
+		pAddress = pFinal;
+	else
+		pAddress = pBase;
+
+	switch (opcode & MASK_TRANSFER_LENGTH) {
+	case TRANSFER_SINGLE:
+		loadSingle(getFd(opcode), pAddress);
+		break;
+	case TRANSFER_DOUBLE:
+		loadDouble(getFd(opcode), pAddress);
+		break;
+#ifdef CONFIG_FPE_NWFPE_XP
+	case TRANSFER_EXTENDED:
+		loadExtended(getFd(opcode), pAddress);
+		break;
+#endif
+	default:
+		nRc = 0;
+	}
+
+	if (write_back)
+		writeRegister(getRn(opcode), (unsigned int) pFinal);
+	return nRc;
 }
 
 unsigned int PerformSTF(const unsigned int opcode)
 {
-   unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
-     write_back = WRITE_BACK(opcode);
-   
-   //printk("PerformSTF(0x%08x), Fd = 0x%08x\n",opcode,getFd(opcode));
-   SetRoundingMode(ROUND_TO_NEAREST);
-   
-   pBase = (unsigned int*)readRegister(getRn(opcode));
-   if (REG_PC == getRn(opcode))
-   {
-     pBase += 2;
-     write_back = 0;
-   }
-
-   pFinal = pBase;
-   if (BIT_UP_SET(opcode))
-     pFinal += getOffset(opcode);
-   else
-     pFinal -= getOffset(opcode);
-
-   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
-
-   switch (opcode & MASK_TRANSFER_LENGTH)
-   {
-      case TRANSFER_SINGLE  : storeSingle(getFd(opcode),pAddress);   break;
-      case TRANSFER_DOUBLE  : storeDouble(getFd(opcode),pAddress);   break;
-      case TRANSFER_EXTENDED: storeExtended(getFd(opcode),pAddress); break;
-      default: nRc = 0;
-   }
-   
-   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
-   return nRc;
+	unsigned int *pBase, *pAddress, *pFinal, nRc = 1,
+	    write_back = WRITE_BACK(opcode);
+
+	SetRoundingMode(ROUND_TO_NEAREST);
+
+	pBase = (unsigned int *) readRegister(getRn(opcode));
+	if (REG_PC == getRn(opcode)) {
+		pBase += 2;
+		write_back = 0;
+	}
+
+	pFinal = pBase;
+	if (BIT_UP_SET(opcode))
+		pFinal += getOffset(opcode);
+	else
+		pFinal -= getOffset(opcode);
+
+	if (PREINDEXED(opcode))
+		pAddress = pFinal;
+	else
+		pAddress = pBase;
+
+	switch (opcode & MASK_TRANSFER_LENGTH) {
+	case TRANSFER_SINGLE:
+		storeSingle(getFd(opcode), pAddress);
+		break;
+	case TRANSFER_DOUBLE:
+		storeDouble(getFd(opcode), pAddress);
+		break;
+#ifdef CONFIG_FPE_NWFPE_XP
+	case TRANSFER_EXTENDED:
+		storeExtended(getFd(opcode), pAddress);
+		break;
+#endif
+	default:
+		nRc = 0;
+	}
+
+	if (write_back)
+		writeRegister(getRn(opcode), (unsigned int) pFinal);
+	return nRc;
 }
 
 unsigned int PerformLFM(const unsigned int opcode)
 {
-   unsigned int i, Fd, *pBase, *pAddress, *pFinal,
-     write_back = WRITE_BACK(opcode);
-
-   pBase = (unsigned int*)readRegister(getRn(opcode));
-   if (REG_PC == getRn(opcode))
-   {
-     pBase += 2;
-     write_back = 0;
-   }
-
-   pFinal = pBase;
-   if (BIT_UP_SET(opcode))
-     pFinal += getOffset(opcode);
-   else
-     pFinal -= getOffset(opcode);
-
-   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
-
-   Fd = getFd(opcode);
-   for (i=getRegisterCount(opcode);i>0;i--)
-   {
-     loadMultiple(Fd,pAddress);
-     pAddress += 3; Fd++;
-     if (Fd == 8) Fd = 0;
-   }
+	unsigned int i, Fd, *pBase, *pAddress, *pFinal,
+	    write_back = WRITE_BACK(opcode);
 
-   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
-   return 1;
+	pBase = (unsigned int *) readRegister(getRn(opcode));
+	if (REG_PC == getRn(opcode)) {
+		pBase += 2;
+		write_back = 0;
+	}
+
+	pFinal = pBase;
+	if (BIT_UP_SET(opcode))
+		pFinal += getOffset(opcode);
+	else
+		pFinal -= getOffset(opcode);
+
+	if (PREINDEXED(opcode))
+		pAddress = pFinal;
+	else
+		pAddress = pBase;
+
+	Fd = getFd(opcode);
+	for (i = getRegisterCount(opcode); i > 0; i--) {
+		loadMultiple(Fd, pAddress);
+		pAddress += 3;
+		Fd++;
+		if (Fd == 8)
+			Fd = 0;
+	}
+
+	if (write_back)
+		writeRegister(getRn(opcode), (unsigned int) pFinal);
+	return 1;
 }
 
 unsigned int PerformSFM(const unsigned int opcode)
 {
-   unsigned int i, Fd, *pBase, *pAddress, *pFinal,
-     write_back = WRITE_BACK(opcode);
-   
-   pBase = (unsigned int*)readRegister(getRn(opcode));
-   if (REG_PC == getRn(opcode))
-   {
-     pBase += 2;
-     write_back = 0;
-   }
-   
-   pFinal = pBase;
-   if (BIT_UP_SET(opcode))
-     pFinal += getOffset(opcode);
-   else
-     pFinal -= getOffset(opcode);
-
-   if (PREINDEXED(opcode)) pAddress = pFinal; else pAddress = pBase;
-
-   Fd = getFd(opcode);
-   for (i=getRegisterCount(opcode);i>0;i--)
-   {
-     storeMultiple(Fd,pAddress);
-     pAddress += 3; Fd++;
-     if (Fd == 8) Fd = 0;
-   }
+	unsigned int i, Fd, *pBase, *pAddress, *pFinal,
+	    write_back = WRITE_BACK(opcode);
 
-   if (write_back) writeRegister(getRn(opcode),(unsigned int)pFinal);
-   return 1;
+	pBase = (unsigned int *) readRegister(getRn(opcode));
+	if (REG_PC == getRn(opcode)) {
+		pBase += 2;
+		write_back = 0;
+	}
+
+	pFinal = pBase;
+	if (BIT_UP_SET(opcode))
+		pFinal += getOffset(opcode);
+	else
+		pFinal -= getOffset(opcode);
+
+	if (PREINDEXED(opcode))
+		pAddress = pFinal;
+	else
+		pAddress = pBase;
+
+	Fd = getFd(opcode);
+	for (i = getRegisterCount(opcode); i > 0; i--) {
+		storeMultiple(Fd, pAddress);
+		pAddress += 3;
+		Fd++;
+		if (Fd == 8)
+			Fd = 0;
+	}
+
+	if (write_back)
+		writeRegister(getRn(opcode), (unsigned int) pFinal);
+	return 1;
 }
 
-#if 1
 unsigned int EmulateCPDT(const unsigned int opcode)
 {
-  unsigned int nRc = 0;
+	unsigned int nRc = 0;
 
-  //printk("EmulateCPDT(0x%08x)\n",opcode);
-  
-  if (LDF_OP(opcode))
-  {
-    nRc = PerformLDF(opcode);
-  }
-  else if (LFM_OP(opcode))
-  {
-    nRc = PerformLFM(opcode);
-  }
-  else if (STF_OP(opcode))
-  {
-    nRc = PerformSTF(opcode);
-  } 
-  else if (SFM_OP(opcode))
-  {
-    nRc = PerformSFM(opcode);
-  }
-  else
-  {
-    nRc = 0;
-  }
-  
-  return nRc;
+	if (LDF_OP(opcode)) {
+		nRc = PerformLDF(opcode);
+	} else if (LFM_OP(opcode)) {
+		nRc = PerformLFM(opcode);
+	} else if (STF_OP(opcode)) {
+		nRc = PerformSTF(opcode);
+	} else if (SFM_OP(opcode)) {
+		nRc = PerformSFM(opcode);
+	} else {
+		nRc = 0;
+	}
+
+	return nRc;
 }
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/fpa11_cprt.c linux-2.4.22-pre10/arch/arm/nwfpe/fpa11_cprt.c
--- linux-2.4.21/arch/arm/nwfpe/fpa11_cprt.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/fpa11_cprt.c	2003-08-01 13:33:58.000000000 +0000
@@ -1,7 +1,7 @@
 /*
     NetWinder Floating Point Emulator
     (c) Rebel.COM, 1998,1999
-    (c) Philip Blundell, 1999
+    (c) Philip Blundell, 1999, 2001
 
     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
 
@@ -21,269 +21,348 @@
 */
 
 #include "fpa11.h"
-#include "milieu.h"
-#include "softfloat.h"
 #include "fpopcode.h"
 #include "fpa11.inl"
 #include "fpmodule.h"
 #include "fpmodule.inl"
 
+#ifdef CONFIG_FPE_NWFPE_XP
 extern flag floatx80_is_nan(floatx80);
-extern flag float64_is_nan( float64);
-extern flag float32_is_nan( float32);
+#endif
+extern flag float64_is_nan(float64);
+extern flag float32_is_nan(float32);
 
 void SetRoundingMode(const unsigned int opcode);
 
 unsigned int PerformFLT(const unsigned int opcode);
 unsigned int PerformFIX(const unsigned int opcode);
 
-static unsigned int
-PerformComparison(const unsigned int opcode);
+static unsigned int PerformComparison(const unsigned int opcode);
 
 unsigned int EmulateCPRT(const unsigned int opcode)
 {
-  unsigned int nRc = 1;
-
-  //printk("EmulateCPRT(0x%08x)\n",opcode);
 
-  if (opcode & 0x800000)
-  {
-     /* This is some variant of a comparison (PerformComparison will
-	sort out which one).  Since most of the other CPRT
-	instructions are oddball cases of some sort or other it makes
-	sense to pull this out into a fast path.  */
-     return PerformComparison(opcode);
-  }
-
-  /* Hint to GCC that we'd like a jump table rather than a load of CMPs */
-  switch ((opcode & 0x700000) >> 20)
-  {
-    case  FLT_CODE >> 20: nRc = PerformFLT(opcode); break;
-    case  FIX_CODE >> 20: nRc = PerformFIX(opcode); break;
-    
-    case  WFS_CODE >> 20: writeFPSR(readRegister(getRd(opcode))); break;
-    case  RFS_CODE >> 20: writeRegister(getRd(opcode),readFPSR()); break;
-
-#if 0    /* We currently have no use for the FPCR, so there's no point
-	    in emulating it. */
-    case  WFC_CODE >> 20: writeFPCR(readRegister(getRd(opcode)));
-    case  RFC_CODE >> 20: writeRegister(getRd(opcode),readFPCR()); break;
-#endif
+	if (opcode & 0x800000) {
+		/* This is some variant of a comparison (PerformComparison
+		   will sort out which one).  Since most of the other CPRT
+		   instructions are oddball cases of some sort or other it
+		   makes sense to pull this out into a fast path.  */
+		return PerformComparison(opcode);
+	}
+
+	/* Hint to GCC that we'd like a jump table rather than a load of CMPs */
+	switch ((opcode & 0x700000) >> 20) {
+	case FLT_CODE >> 20:
+		return PerformFLT(opcode);
+		break;
+	case FIX_CODE >> 20:
+		return PerformFIX(opcode);
+		break;
+
+	case WFS_CODE >> 20:
+		writeFPSR(readRegister(getRd(opcode)));
+		break;
+	case RFS_CODE >> 20:
+		writeRegister(getRd(opcode), readFPSR());
+		break;
+
+	default:
+		return 0;
+	}
 
-    default: nRc = 0;
-  }
-  
-  return nRc;
+	return 1;
 }
 
 unsigned int PerformFLT(const unsigned int opcode)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   
-   unsigned int nRc = 1;
-   SetRoundingMode(opcode);
-
-   switch (opcode & MASK_ROUNDING_PRECISION)
-   {
-      case ROUND_SINGLE:
-      {
-        fpa11->fType[getFn(opcode)] = typeSingle;
-        fpa11->fpreg[getFn(opcode)].fSingle =
-	   int32_to_float32(readRegister(getRd(opcode)));
-      }
-      break;
-
-      case ROUND_DOUBLE:
-      {
-        fpa11->fType[getFn(opcode)] = typeDouble;
-        fpa11->fpreg[getFn(opcode)].fDouble =
-            int32_to_float64(readRegister(getRd(opcode)));
-      }
-      break;
-        
-      case ROUND_EXTENDED:
-      {
-        fpa11->fType[getFn(opcode)] = typeExtended;
-        fpa11->fpreg[getFn(opcode)].fExtended =
-	   int32_to_floatx80(readRegister(getRd(opcode)));
-      }
-      break;
-      
-      default: nRc = 0;
-  }
-  
-  return nRc;
+	FPA11 *fpa11 = GET_FPA11();
+	SetRoundingMode(opcode);
+	SetRoundingPrecision(opcode);
+
+	switch (opcode & MASK_ROUNDING_PRECISION) {
+	case ROUND_SINGLE:
+		{
+			fpa11->fType[getFn(opcode)] = typeSingle;
+			fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(readRegister(getRd(opcode)));
+		}
+		break;
+
+	case ROUND_DOUBLE:
+		{
+			fpa11->fType[getFn(opcode)] = typeDouble;
+			fpa11->fpreg[getFn(opcode)].fDouble = int32_to_float64(readRegister(getRd(opcode)));
+		}
+		break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	case ROUND_EXTENDED:
+		{
+			fpa11->fType[getFn(opcode)] = typeExtended;
+			fpa11->fpreg[getFn(opcode)].fExtended = int32_to_floatx80(readRegister(getRd(opcode)));
+		}
+		break;
+#endif
+
+	default:
+		return 0;
+	}
+
+	return 1;
 }
 
 unsigned int PerformFIX(const unsigned int opcode)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   unsigned int nRc = 1;
-   unsigned int Fn = getFm(opcode);
-   
-   SetRoundingMode(opcode);
-
-   switch (fpa11->fType[Fn])
-   {
-      case typeSingle:
-      {
-         writeRegister(getRd(opcode),
-	               float32_to_int32(fpa11->fpreg[Fn].fSingle));
-      }
-      break;
-
-      case typeDouble:
-      {
-         writeRegister(getRd(opcode),
-	               float64_to_int32(fpa11->fpreg[Fn].fDouble));
-      }
-      break;
-      	               
-      case typeExtended:
-      {
-         writeRegister(getRd(opcode),
-	               floatx80_to_int32(fpa11->fpreg[Fn].fExtended));
-      }
-      break;
-      
-      default: nRc = 0;
-  }
-  
-  return nRc;
-}
+	FPA11 *fpa11 = GET_FPA11();
+	unsigned int Fn = getFm(opcode);
 
-   
-static unsigned int __inline__
-PerformComparisonOperation(floatx80 Fn, floatx80 Fm)
-{
-   unsigned int flags = 0;
+	SetRoundingMode(opcode);
 
-   /* test for less than condition */
-   if (floatx80_lt(Fn,Fm))
-   {
-      flags |= CC_NEGATIVE;
-   }
-  
-   /* test for equal condition */
-   if (floatx80_eq(Fn,Fm))
-   {
-      flags |= CC_ZERO;
-   }
-
-   /* test for greater than or equal condition */
-   if (floatx80_lt(Fm,Fn))
-   {
-      flags |= CC_CARRY;
-   }
-   
-   writeConditionCodes(flags);
-   return 1;
+	switch (fpa11->fType[Fn]) {
+	case typeSingle:
+		{
+			writeRegister(getRd(opcode), float32_to_int32(fpa11->fpreg[Fn].fSingle));
+		}
+		break;
+
+	case typeDouble:
+		{
+			writeRegister(getRd(opcode), float64_to_int32(fpa11->fpreg[Fn].fDouble));
+		}
+		break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	case typeExtended:
+		{
+			writeRegister(getRd(opcode), floatx80_to_int32(fpa11->fpreg[Fn].fExtended));
+		}
+		break;
+#endif
+
+	default:
+		return 0;
+	}
+
+	return 1;
 }
 
 /* This instruction sets the flags N, Z, C, V in the FPSR. */
-   
 static unsigned int PerformComparison(const unsigned int opcode)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   unsigned int Fn, Fm;
-   floatx80 rFn, rFm;
-   int e_flag = opcode & 0x400000;	/* 1 if CxFE */
-   int n_flag = opcode & 0x200000;	/* 1 if CNxx */
-   unsigned int flags = 0;
-
-   //printk("PerformComparison(0x%08x)\n",opcode);
-
-   Fn = getFn(opcode);
-   Fm = getFm(opcode);
-
-   /* Check for unordered condition and convert all operands to 80-bit
-      format.
-      ?? Might be some mileage in avoiding this conversion if possible.
-      Eg, if both operands are 32-bit, detect this and do a 32-bit
-      comparison (cheaper than an 80-bit one).  */
-   switch (fpa11->fType[Fn])
-   {
-      case typeSingle: 
-        //printk("single.\n");
-	if (float32_is_nan(fpa11->fpreg[Fn].fSingle))
-	   goto unordered;
-        rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
-      break;
-
-      case typeDouble: 
-        //printk("double.\n");
-	if (float64_is_nan(fpa11->fpreg[Fn].fDouble))
-	   goto unordered;
-        rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
-      break;
-      
-      case typeExtended: 
-        //printk("extended.\n");
-	if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended))
-	   goto unordered;
-        rFn = fpa11->fpreg[Fn].fExtended;
-      break;
-      
-      default: return 0;
-   }
-
-   if (CONSTANT_FM(opcode))
-   {
-     //printk("Fm is a constant: #%d.\n",Fm);
-     rFm = getExtendedConstant(Fm);
-     if (floatx80_is_nan(rFm))
-        goto unordered;
-   }
-   else
-   {
-     //printk("Fm = r%d which contains a ",Fm);
-      switch (fpa11->fType[Fm])
-      {
-         case typeSingle: 
-           //printk("single.\n");
-	   if (float32_is_nan(fpa11->fpreg[Fm].fSingle))
-	      goto unordered;
-           rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
-         break;
-
-         case typeDouble: 
-           //printk("double.\n");
-	   if (float64_is_nan(fpa11->fpreg[Fm].fDouble))
-	      goto unordered;
-           rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
-         break;
-      
-         case typeExtended: 
-           //printk("extended.\n");
-	   if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended))
-	      goto unordered;
-           rFm = fpa11->fpreg[Fm].fExtended;
-         break;
-      
-         default: return 0;
-      }
-   }
-
-   if (n_flag)
-   {
-      rFm.high ^= 0x8000;
-   }
-
-   return PerformComparisonOperation(rFn,rFm);
-
- unordered:
-   /* ?? The FPA data sheet is pretty vague about this, in particular
-      about whether the non-E comparisons can ever raise exceptions.
-      This implementation is based on a combination of what it says in
-      the data sheet, observation of how the Acorn emulator actually
-      behaves (and how programs expect it to) and guesswork.  */
-   flags |= CC_OVERFLOW;
-   flags &= ~(CC_ZERO | CC_NEGATIVE);
+	FPA11 *fpa11 = GET_FPA11();
+	unsigned int Fn = getFn(opcode), Fm = getFm(opcode);
+	int e_flag = opcode & 0x400000;	/* 1 if CxFE */
+	int n_flag = opcode & 0x200000;	/* 1 if CNxx */
+	unsigned int flags = 0;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+	floatx80 rFn, rFm;
+
+	/* Check for unordered condition and convert all operands to 80-bit
+	   format.
+	   ?? Might be some mileage in avoiding this conversion if possible.
+	   Eg, if both operands are 32-bit, detect this and do a 32-bit
+	   comparison (cheaper than an 80-bit one).  */
+	switch (fpa11->fType[Fn]) {
+	case typeSingle:
+		//printk("single.\n");
+		if (float32_is_nan(fpa11->fpreg[Fn].fSingle))
+			goto unordered;
+		rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
+		break;
+
+	case typeDouble:
+		//printk("double.\n");
+		if (float64_is_nan(fpa11->fpreg[Fn].fDouble))
+			goto unordered;
+		rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
+		break;
+
+	case typeExtended:
+		//printk("extended.\n");
+		if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended))
+			goto unordered;
+		rFn = fpa11->fpreg[Fn].fExtended;
+		break;
+
+	default:
+		return 0;
+	}
+
+	if (CONSTANT_FM(opcode)) {
+		//printk("Fm is a constant: #%d.\n",Fm);
+		rFm = getExtendedConstant(Fm);
+		if (floatx80_is_nan(rFm))
+			goto unordered;
+	} else {
+		//printk("Fm = r%d which contains a ",Fm);
+		switch (fpa11->fType[Fm]) {
+		case typeSingle:
+			//printk("single.\n");
+			if (float32_is_nan(fpa11->fpreg[Fm].fSingle))
+				goto unordered;
+			rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
+			break;
+
+		case typeDouble:
+			//printk("double.\n");
+			if (float64_is_nan(fpa11->fpreg[Fm].fDouble))
+				goto unordered;
+			rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
+			break;
+
+		case typeExtended:
+			//printk("extended.\n");
+			if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended))
+				goto unordered;
+			rFm = fpa11->fpreg[Fm].fExtended;
+			break;
+
+		default:
+			return 0;
+		}
+	}
+
+	if (n_flag)
+		rFm.high ^= 0x8000;
+
+	/* test for less than condition */
+	if (floatx80_lt(rFn, rFm))
+		flags |= CC_NEGATIVE;
+
+	/* test for equal condition */
+	if (floatx80_eq(rFn, rFm))
+		flags |= CC_ZERO;
+
+	/* test for greater than or equal condition */
+	if (floatx80_lt(rFm, rFn))
+		flags |= CC_CARRY;
+
+#else
+	if (CONSTANT_FM(opcode)) {
+		/* Fm is a constant.  Do the comparison in whatever precision
+		   Fn happens to be stored in.  */
+		if (fpa11->fType[Fn] == typeSingle) {
+			float32 rFm = getSingleConstant(Fm);
+			float32 rFn = fpa11->fpreg[Fn].fSingle;
+
+			if (float32_is_nan(rFn))
+				goto unordered;
+
+			if (n_flag)
+				rFm ^= 0x80000000;
+
+			/* test for less than condition */
+			if (float32_lt_nocheck(rFn, rFm))
+				flags |= CC_NEGATIVE;
+
+			/* test for equal condition */
+			if (float32_eq_nocheck(rFn, rFm))
+				flags |= CC_ZERO;
+
+			/* test for greater than or equal condition */
+			if (float32_lt_nocheck(rFm, rFn))
+				flags |= CC_CARRY;
+		} else {
+			float64 rFm = getDoubleConstant(Fm);
+			float64 rFn = fpa11->fpreg[Fn].fDouble;
+
+			if (float64_is_nan(rFn))
+				goto unordered;
+
+			if (n_flag)
+				rFm ^= 0x8000000000000000ULL;
+
+			/* test for less than condition */
+			if (float64_lt_nocheck(rFn, rFm))
+				flags |= CC_NEGATIVE;
+
+			/* test for equal condition */
+			if (float64_eq_nocheck(rFn, rFm))
+				flags |= CC_ZERO;
+
+			/* test for greater than or equal condition */
+			if (float64_lt_nocheck(rFm, rFn))
+				flags |= CC_CARRY;
+		}
+	} else {
+		/* Both operands are in registers.  */
+		if (fpa11->fType[Fn] == typeSingle
+		    && fpa11->fType[Fm] == typeSingle) {
+			float32 rFm = fpa11->fpreg[Fm].fSingle;
+			float32 rFn = fpa11->fpreg[Fn].fSingle;
+
+			if (float32_is_nan(rFn)
+			    || float32_is_nan(rFm))
+				goto unordered;
+
+			if (n_flag)
+				rFm ^= 0x80000000;
+
+			/* test for less than condition */
+			if (float32_lt_nocheck(rFn, rFm))
+				flags |= CC_NEGATIVE;
+
+			/* test for equal condition */
+			if (float32_eq_nocheck(rFn, rFm))
+				flags |= CC_ZERO;
+
+			/* test for greater than or equal condition */
+			if (float32_lt_nocheck(rFm, rFn))
+				flags |= CC_CARRY;
+		} else {
+			/* Promote 32-bit operand to 64 bits.  */
+			float64 rFm, rFn;
+
+			rFm = (fpa11->fType[Fm] == typeSingle) ?
+			    float32_to_float64(fpa11->fpreg[Fm].fSingle)
+			    : fpa11->fpreg[Fm].fDouble;
+
+			rFn = (fpa11->fType[Fn] == typeSingle) ?
+			    float32_to_float64(fpa11->fpreg[Fn].fSingle)
+			    : fpa11->fpreg[Fn].fDouble;
+
+			if (float64_is_nan(rFn)
+			    || float64_is_nan(rFm))
+				goto unordered;
+
+			if (n_flag)
+				rFm ^= 0x8000000000000000ULL;
+
+			/* test for less than condition */
+			if (float64_lt_nocheck(rFn, rFm))
+				flags |= CC_NEGATIVE;
+
+			/* test for equal condition */
+			if (float64_eq_nocheck(rFn, rFm))
+				flags |= CC_ZERO;
+
+			/* test for greater than or equal condition */
+			if (float64_lt_nocheck(rFm, rFn))
+				flags |= CC_CARRY;
+		}
+	}
+
+#endif
+
+	writeConditionCodes(flags);
+
+	return 1;
+
+      unordered:
+	/* ?? The FPA data sheet is pretty vague about this, in particular
+	   about whether the non-E comparisons can ever raise exceptions.
+	   This implementation is based on a combination of what it says in
+	   the data sheet, observation of how the Acorn emulator actually
+	   behaves (and how programs expect it to) and guesswork.  */
+	flags |= CC_OVERFLOW;
+	flags &= ~(CC_ZERO | CC_NEGATIVE);
 
-   if (BIT_AC & readFPSR()) flags |= CC_CARRY;
+	if (BIT_AC & readFPSR())
+		flags |= CC_CARRY;
 
-   if (e_flag) float_raise(float_flag_invalid);
+	if (e_flag)
+		float_raise(float_flag_invalid);
 
-   writeConditionCodes(flags);
-   return 1;
+	writeConditionCodes(flags);
+	return 1;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/fpmodule.c linux-2.4.22-pre10/arch/arm/nwfpe/fpmodule.c
--- linux-2.4.21/arch/arm/nwfpe/fpmodule.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/fpmodule.c	2003-08-01 13:33:03.000000000 +0000
@@ -41,13 +41,19 @@
 #include "fpa11.inl"
 
 /* kernel symbols required for signal handling */
-typedef struct task_struct*	PTASK;
+typedef struct task_struct *PTASK;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+#define NWFPE_BITS "extended"
+#else
+#define NWFPE_BITS "double"
+#endif
 
 #ifdef MODULE
 void fp_send_sig(unsigned long sig, PTASK p, int priv);
 #if LINUX_VERSION_CODE > 0x20115
 MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
-MODULE_DESCRIPTION("NWFPE floating point emulator");
+MODULE_DESCRIPTION("NWFPE floating point emulator (" NWFPE_BITS " precision)");
 #endif
 
 #else
@@ -63,7 +69,7 @@
 /* external declarations for saved kernel symbols */
 extern void (*kern_fp_enter)(void);
 
-/* Original value of fp_enter from kernel before patched by fpe_init. */ 
+/* Original value of fp_enter from kernel before patched by fpe_init. */
 static void (*orig_fp_enter)(void);
 
 /* forward declarations */
@@ -76,46 +82,45 @@
  */
 static int fpe_unload(void)
 {
-  return (kern_fp_enter == nwfpe_enter) ? 0 : 1;
+	return (kern_fp_enter == nwfpe_enter) ? 0 : 1;
 }
 #endif
 
 static int __init fpe_init(void)
 {
-  if (sizeof(FPA11) > sizeof(union fp_state)) {
-    printk(KERN_ERR "nwfpe: bad structure size\n");
-    return -EINVAL;
-  }
-
-  if (sizeof(FPREG) != 12) {
-    printk(KERN_ERR "nwfpe: bad register size\n");
-    return -EINVAL;
-  }
-
+	if (sizeof(FPA11) > sizeof(union fp_state)) {
+		printk(KERN_ERR "nwfpe: bad structure size\n");
+		return -EINVAL;
+	}
+
+	if (sizeof(FPREG) != 12) {
+		printk(KERN_ERR "nwfpe: bad register size\n");
+		return -EINVAL;
+	}
 #ifdef MODULE
-  if (!mod_member_present(&__this_module, can_unload))
-    return -EINVAL;
-  __this_module.can_unload = fpe_unload;
+	if (!mod_member_present(&__this_module, can_unload))
+		return -EINVAL;
+	__this_module.can_unload = fpe_unload;
 #else
-  if (fpe_type[0] && strcmp(fpe_type, "nwfpe"))
-    return 0;
+	if (fpe_type[0] && strcmp(fpe_type, "nwfpe"))
+		return 0;
 #endif
 
-  /* Display title, version and copyright information. */
-  printk(KERN_WARNING "NetWinder Floating Point Emulator V0.95 "
-	 "(c) 1998-1999 Rebel.com\n");
-
-  /* Save pointer to the old FP handler and then patch ourselves in */
-  orig_fp_enter = kern_fp_enter;
-  kern_fp_enter = nwfpe_enter;
+	/* Display title, version and copyright information. */
+	printk(KERN_WARNING "NetWinder Floating Point Emulator V0.97 ("
+	       NWFPE_BITS " precision)\n");
+
+	/* Save pointer to the old FP handler and then patch ourselves in */
+	orig_fp_enter = kern_fp_enter;
+	kern_fp_enter = nwfpe_enter;
 
-  return 0;
+	return 0;
 }
 
 static void __exit fpe_exit(void)
 {
-  /* Restore the values we saved earlier. */
-  kern_fp_enter = orig_fp_enter;
+	/* Restore the values we saved earlier. */
+	kern_fp_enter = orig_fp_enter;
 }
 
 /*
@@ -140,41 +145,42 @@
 
 void float_raise(signed char flags)
 {
-  register unsigned int fpsr, cumulativeTraps;
-  
+	register unsigned int fpsr, cumulativeTraps;
+
 #ifdef CONFIG_DEBUG_USER
-  printk(KERN_DEBUG "NWFPE: %s[%d] takes exception %08x at %p from %08x\n",
-	 current->comm, current->pid, flags,
-	 __builtin_return_address(0), GET_USERREG()[15]);
-#endif
-
-  /* Keep SoftFloat exception flags up to date.  */
-  float_exception_flags |= flags;
-
-  /* Read fpsr and initialize the cumulativeTraps.  */
-  fpsr = readFPSR();
-  cumulativeTraps = 0;
-  
-  /* For each type of exception, the cumulative trap exception bit is only
-     set if the corresponding trap enable bit is not set.  */
-  if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC))
-     cumulativeTraps |= BIT_IXC;  
-  if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC))
-     cumulativeTraps |= BIT_UFC;  
-  if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC))
-     cumulativeTraps |= BIT_OFC;  
-  if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC))
-     cumulativeTraps |= BIT_DZC;  
-  if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC))
-     cumulativeTraps |= BIT_IOC;  
-
-  /* Set the cumulative exceptions flags.  */
-  if (cumulativeTraps)
-    writeFPSR(fpsr | cumulativeTraps);
-
-  /* Raise an exception if necessary.  */
-  if (fpsr & (flags << 16))
-    fp_send_sig(SIGFPE, current, 1);
+	printk(KERN_DEBUG
+	       "NWFPE: %s[%d] takes exception %08x at %p from %08x\n",
+	       current->comm, current->pid, flags,
+	       __builtin_return_address(0), GET_USERREG()[15]);
+#endif
+
+	/* Keep SoftFloat exception flags up to date.  */
+	float_exception_flags |= flags;
+
+	/* Read fpsr and initialize the cumulativeTraps.  */
+	fpsr = readFPSR();
+	cumulativeTraps = 0;
+
+	/* For each type of exception, the cumulative trap exception bit is only
+	   set if the corresponding trap enable bit is not set.  */
+	if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC))
+		cumulativeTraps |= BIT_IXC;
+	if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC))
+		cumulativeTraps |= BIT_UFC;
+	if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC))
+		cumulativeTraps |= BIT_OFC;
+	if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC))
+		cumulativeTraps |= BIT_DZC;
+	if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC))
+		cumulativeTraps |= BIT_IOC;
+
+	/* Set the cumulative exceptions flags.  */
+	if (cumulativeTraps)
+		writeFPSR(fpsr | cumulativeTraps);
+
+	/* Raise an exception if necessary.  */
+	if (fpsr & (flags << 16))
+		fp_send_sig(SIGFPE, current, 1);
 }
 
 module_init(fpe_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/fpmodule.inl linux-2.4.22-pre10/arch/arm/nwfpe/fpmodule.inl
--- linux-2.4.21/arch/arm/nwfpe/fpmodule.inl	2001-08-12 18:13:59.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/fpmodule.inl	2003-08-01 13:34:38.000000000 +0000
@@ -22,63 +22,64 @@
 extern __inline__
 unsigned int readRegister(const unsigned int nReg)
 {
-  /* Note: The CPU thinks it has dealt with the current instruction.  As
-           a result the program counter has been advanced to the next
-           instruction, and points 4 bytes beyond the actual instruction
-           that caused the invalid instruction trap to occur.  We adjust
-           for this in this routine.  LDF/STF instructions with Rn = PC
-           depend on the PC being correct, as they use PC+8 in their 
-           address calculations. */
-  unsigned int *userRegisters = GET_USERREG();
-  unsigned int val = userRegisters[nReg];
-  if (REG_PC == nReg) val -= 4;
-  return val;
+	/* Note: The CPU thinks it has dealt with the current instruction.
+	   As a result the program counter has been advanced to the next
+	   instruction, and points 4 bytes beyond the actual instruction
+	   that caused the invalid instruction trap to occur.  We adjust
+	   for this in this routine.  LDF/STF instructions with Rn = PC
+	   depend on the PC being correct, as they use PC+8 in their
+	   address calculations. */
+	unsigned int *userRegisters = GET_USERREG();
+	unsigned int val = userRegisters[nReg];
+	if (REG_PC == nReg)
+		val -= 4;
+	return val;
 }
 
 extern __inline__
 void writeRegister(const unsigned int nReg, const unsigned int val)
 {
-  unsigned int *userRegisters = GET_USERREG();
-  userRegisters[nReg] = val;
+	unsigned int *userRegisters = GET_USERREG();
+	userRegisters[nReg] = val;
 }
 
 extern __inline__
 unsigned int readCPSR(void)
 {
-  return(readRegister(REG_CPSR));
+	return (readRegister(REG_CPSR));
 }
 
 extern __inline__
 void writeCPSR(const unsigned int val)
 {
-  writeRegister(REG_CPSR,val);
+	writeRegister(REG_CPSR, val);
 }
 
 extern __inline__
 unsigned int readConditionCodes(void)
 {
 #ifdef __FPEM_TEST__
-   return(0);
+	return (0);
 #else
-   return(readCPSR() & CC_MASK);
+	return (readCPSR() & CC_MASK);
 #endif
 }
 
 extern __inline__
 void writeConditionCodes(const unsigned int val)
 {
-  unsigned int *userRegisters = GET_USERREG();
-  unsigned int rval;
-  /*
-   * Operate directly on userRegisters since
-   * the CPSR may be the PC register itself.
-   */
-  rval = userRegisters[REG_CPSR] & ~CC_MASK;
-  userRegisters[REG_CPSR] = rval | (val & CC_MASK);
+	unsigned int *userRegisters = GET_USERREG();
+	unsigned int rval;
+	/*
+	 * Operate directly on userRegisters since
+	 * the CPSR may be the PC register itself.
+	 */
+	rval = userRegisters[REG_CPSR] & ~CC_MASK;
+	userRegisters[REG_CPSR] = rval | (val & CC_MASK);
 }
 
 extern __inline__
 unsigned int readMemoryInt(unsigned int *pMem)
 {
-  return *pMem;
+	return *pMem;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/fpopcode.c linux-2.4.22-pre10/arch/arm/nwfpe/fpopcode.c
--- linux-2.4.21/arch/arm/nwfpe/fpopcode.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/fpopcode.c	2003-08-01 13:32:59.000000000 +0000
@@ -26,123 +26,64 @@
 #include "fpmodule.h"
 #include "fpmodule.inl"
 
+#ifdef CONFIG_FPE_NWFPE_XP
 const floatx80 floatx80Constant[] = {
-  { 0x0000, 0x0000000000000000ULL},	/* extended 0.0 */
-  { 0x3fff, 0x8000000000000000ULL},	/* extended 1.0 */
-  { 0x4000, 0x8000000000000000ULL},	/* extended 2.0 */
-  { 0x4000, 0xc000000000000000ULL},	/* extended 3.0 */
-  { 0x4001, 0x8000000000000000ULL},	/* extended 4.0 */
-  { 0x4001, 0xa000000000000000ULL},	/* extended 5.0 */
-  { 0x3ffe, 0x8000000000000000ULL},	/* extended 0.5 */
-  { 0x4002, 0xa000000000000000ULL}	/* extended 10.0 */
-};  
+	{0x0000, 0x0000000000000000ULL},	/* extended 0.0 */
+	{0x3fff, 0x8000000000000000ULL},	/* extended 1.0 */
+	{0x4000, 0x8000000000000000ULL},	/* extended 2.0 */
+	{0x4000, 0xc000000000000000ULL},	/* extended 3.0 */
+	{0x4001, 0x8000000000000000ULL},	/* extended 4.0 */
+	{0x4001, 0xa000000000000000ULL},	/* extended 5.0 */
+	{0x3ffe, 0x8000000000000000ULL},	/* extended 0.5 */
+	{0x4002, 0xa000000000000000ULL}		/* extended 10.0 */
+};
+#endif
 
 const float64 float64Constant[] = {
-  0x0000000000000000ULL,		/* double 0.0 */
-  0x3ff0000000000000ULL,		/* double 1.0 */
-  0x4000000000000000ULL,		/* double 2.0 */
-  0x4008000000000000ULL,		/* double 3.0 */
-  0x4010000000000000ULL,		/* double 4.0 */
-  0x4014000000000000ULL,		/* double 5.0 */
-  0x3fe0000000000000ULL,		/* double 0.5 */
-  0x4024000000000000ULL			/* double 10.0 */
-};  
+	0x0000000000000000ULL,	/* double 0.0 */
+	0x3ff0000000000000ULL,	/* double 1.0 */
+	0x4000000000000000ULL,	/* double 2.0 */
+	0x4008000000000000ULL,	/* double 3.0 */
+	0x4010000000000000ULL,	/* double 4.0 */
+	0x4014000000000000ULL,	/* double 5.0 */
+	0x3fe0000000000000ULL,	/* double 0.5 */
+	0x4024000000000000ULL	/* double 10.0 */
+};
 
 const float32 float32Constant[] = {
-  0x00000000,				/* single 0.0 */
-  0x3f800000,				/* single 1.0 */
-  0x40000000,				/* single 2.0 */
-  0x40400000,				/* single 3.0 */
-  0x40800000,				/* single 4.0 */
-  0x40a00000,				/* single 5.0 */
-  0x3f000000,				/* single 0.5 */
-  0x41200000				/* single 10.0 */
-};  
-
-unsigned int getTransferLength(const unsigned int opcode)
-{
-  unsigned int nRc;
-  
-  switch (opcode & MASK_TRANSFER_LENGTH)
-  {
-    case 0x00000000: nRc = 1; break; /* single precision */
-    case 0x00008000: nRc = 2; break; /* double precision */
-    case 0x00400000: nRc = 3; break; /* extended precision */
-    default: nRc = 0;
-  }
-  
-  return(nRc);
-}
-
-unsigned int getRegisterCount(const unsigned int opcode)
-{
-  unsigned int nRc;
-  
-  switch (opcode & MASK_REGISTER_COUNT)
-  {
-    case 0x00000000: nRc = 4; break;
-    case 0x00008000: nRc = 1; break;
-    case 0x00400000: nRc = 2; break;
-    case 0x00408000: nRc = 3; break;
-    default: nRc = 0;
-  }
-  
-  return(nRc);
-}
-
-unsigned int getRoundingPrecision(const unsigned int opcode)
-{
-  unsigned int nRc;
-  
-  switch (opcode & MASK_ROUNDING_PRECISION)
-  {
-    case 0x00000000: nRc = 1; break;
-    case 0x00000080: nRc = 2; break;
-    case 0x00080000: nRc = 3; break;
-    default: nRc = 0;
-  }
-  
-  return(nRc);
-}
-
-unsigned int getDestinationSize(const unsigned int opcode)
-{
-  unsigned int nRc;
-  
-  switch (opcode & MASK_DESTINATION_SIZE)
-  {
-    case 0x00000000: nRc = typeSingle; break;
-    case 0x00000080: nRc = typeDouble; break;
-    case 0x00080000: nRc = typeExtended; break;
-    default: nRc = typeNone;
-  }
-  
-  return(nRc);
-}
+	0x00000000,		/* single 0.0 */
+	0x3f800000,		/* single 1.0 */
+	0x40000000,		/* single 2.0 */
+	0x40400000,		/* single 3.0 */
+	0x40800000,		/* single 4.0 */
+	0x40a00000,		/* single 5.0 */
+	0x3f000000,		/* single 0.5 */
+	0x41200000		/* single 10.0 */
+};
 
 /* condition code lookup table
  index into the table is test code: EQ, NE, ... LT, GT, AL, NV
  bit position in short is condition code: NZCV */
 static const unsigned short aCC[16] = {
-    0xF0F0, // EQ == Z set
-    0x0F0F, // NE
-    0xCCCC, // CS == C set
-    0x3333, // CC
-    0xFF00, // MI == N set
-    0x00FF, // PL
-    0xAAAA, // VS == V set
-    0x5555, // VC
-    0x0C0C, // HI == C set && Z clear
-    0xF3F3, // LS == C clear || Z set
-    0xAA55, // GE == (N==V)
-    0x55AA, // LT == (N!=V)
-    0x0A05, // GT == (!Z && (N==V))
-    0xF5FA, // LE == (Z || (N!=V))
-    0xFFFF, // AL always
-    0 // NV
+	0xF0F0,			// EQ == Z set
+	0x0F0F,			// NE
+	0xCCCC,			// CS == C set
+	0x3333,			// CC
+	0xFF00,			// MI == N set
+	0x00FF,			// PL
+	0xAAAA,			// VS == V set
+	0x5555,			// VC
+	0x0C0C,			// HI == C set && Z clear
+	0xF3F3,			// LS == C clear || Z set
+	0xAA55,			// GE == (N==V)
+	0x55AA,			// LT == (N!=V)
+	0x0A05,			// GT == (!Z && (N==V))
+	0xF5FA,			// LE == (Z || (N!=V))
+	0xFFFF,			// AL always
+	0			// NV
 };
 
 unsigned int checkCondition(const unsigned int opcode, const unsigned int ccodes)
 {
-  return (aCC[opcode>>28] >> (ccodes>>28)) & 1;
+	return (aCC[opcode >> 28] >> (ccodes >> 28)) & 1;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/fpopcode.h linux-2.4.22-pre10/arch/arm/nwfpe/fpopcode.h
--- linux-2.4.21/arch/arm/nwfpe/fpopcode.h	2001-04-12 02:02:27.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/fpopcode.h	2003-08-01 13:32:24.000000000 +0000
@@ -1,6 +1,7 @@
 /*
     NetWinder Floating Point Emulator
     (c) Rebel.COM, 1998,1999
+    (c) Philip Blundell, 2001
 
     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
 
@@ -26,7 +27,7 @@
 ARM Floating Point Instruction Classes
 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
 |c o n d|1 1 0 P|U|u|W|L|   Rn  |v|  Fd |0|0|0|1|  o f f s e t  | CPDT
-|c o n d|1 1 0 P|U|w|W|L|   Rn  |x|  Fd |0|0|0|1|  o f f s e t  | CPDT
+|c o n d|1 1 0 P|U|w|W|L|   Rn  |x|  Fd |0|0|1|0|  o f f s e t  | CPDT (copro 2)
 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
 |c o n d|1 1 1 0|a|b|c|d|e|  Fn |j|  Fd |0|0|0|1|f|g|h|0|i|  Fm | CPDO
 |c o n d|1 1 1 0|a|b|c|L|e|  Fn |   Rd  |0|0|0|1|f|g|h|1|i|  Fm | CPRT
@@ -34,7 +35,7 @@
 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
 
 CPDT		data transfer instructions
-		LDF, STF, LFM, SFM
+		LDF, STF, LFM (copro 2), SFM (copro 2)
 		
 CPDO		dyadic arithmetic instructions
 		ADF, MUF, SUF, RSF, DVF, RDF,
@@ -186,7 +187,7 @@
 #define BIT_LOAD	0x00100000
 
 /* masks for load/store */
-#define MASK_CPDT		0x0c000000  /* data processing opcode */
+#define MASK_CPDT		0x0c000000	/* data processing opcode */
 #define MASK_OFFSET		0x000000ff
 #define MASK_TRANSFER_LENGTH	0x00408000
 #define MASK_REGISTER_COUNT	MASK_TRANSFER_LENGTH
@@ -236,7 +237,7 @@
 #define MONADIC_INSTRUCTION(opcode)	((opcode & BIT_MONADIC) != 0)
 
 /* instruction identification masks */
-#define MASK_CPDO		0x0e000000  /* arithmetic opcode */
+#define MASK_CPDO		0x0e000000	/* arithmetic opcode */
 #define MASK_ARITHMETIC_OPCODE	0x00f08000
 #define MASK_DESTINATION_SIZE	0x00080080
 
@@ -282,7 +283,7 @@
 ===
 */
 
-#define MASK_CPRT		0x0e000010  /* register transfer opcode */
+#define MASK_CPRT		0x0e000010	/* register transfer opcode */
 #define MASK_CPRT_CODE		0x00f00000
 #define FLT_CODE		0x00000000
 #define FIX_CODE		0x00100000
@@ -366,25 +367,111 @@
 /* Get the rounding mode from the opcode. */
 #define getRoundingMode(opcode)		((opcode & MASK_ROUNDING_MODE) >> 5)
 
+#ifdef CONFIG_FPE_NWFPE_XP
 static inline const floatx80 getExtendedConstant(const unsigned int nIndex)
 {
-   extern const floatx80 floatx80Constant[];
-   return floatx80Constant[nIndex];
-} 
+	extern const floatx80 floatx80Constant[];
+	return floatx80Constant[nIndex];
+}
+#endif
 
 static inline const float64 getDoubleConstant(const unsigned int nIndex)
 {
-   extern const float64 float64Constant[];
-   return float64Constant[nIndex];
-} 
+	extern const float64 float64Constant[];
+	return float64Constant[nIndex];
+}
 
 static inline const float32 getSingleConstant(const unsigned int nIndex)
 {
-   extern const float32 float32Constant[];
-   return float32Constant[nIndex];
-} 
+	extern const float32 float32Constant[];
+	return float32Constant[nIndex];
+}
+
+static inline unsigned int getTransferLength(const unsigned int opcode)
+{
+	unsigned int nRc;
+
+	switch (opcode & MASK_TRANSFER_LENGTH) {
+	case 0x00000000:
+		nRc = 1;
+		break;		/* single precision */
+	case 0x00008000:
+		nRc = 2;
+		break;		/* double precision */
+	case 0x00400000:
+		nRc = 3;
+		break;		/* extended precision */
+	default:
+		nRc = 0;
+	}
+
+	return (nRc);
+}
+
+static inline unsigned int getRegisterCount(const unsigned int opcode)
+{
+	unsigned int nRc;
+
+	switch (opcode & MASK_REGISTER_COUNT) {
+	case 0x00000000:
+		nRc = 4;
+		break;
+	case 0x00008000:
+		nRc = 1;
+		break;
+	case 0x00400000:
+		nRc = 2;
+		break;
+	case 0x00408000:
+		nRc = 3;
+		break;
+	default:
+		nRc = 0;
+	}
+
+	return (nRc);
+}
+
+static inline unsigned int getRoundingPrecision(const unsigned int opcode)
+{
+	unsigned int nRc;
+
+	switch (opcode & MASK_ROUNDING_PRECISION) {
+	case 0x00000000:
+		nRc = 1;
+		break;
+	case 0x00000080:
+		nRc = 2;
+		break;
+	case 0x00080000:
+		nRc = 3;
+		break;
+	default:
+		nRc = 0;
+	}
+
+	return (nRc);
+}
+
+static inline unsigned int getDestinationSize(const unsigned int opcode)
+{
+	unsigned int nRc;
+
+	switch (opcode & MASK_DESTINATION_SIZE) {
+	case 0x00000000:
+		nRc = typeSingle;
+		break;
+	case 0x00000080:
+		nRc = typeDouble;
+		break;
+	case 0x00080000:
+		nRc = typeExtended;
+		break;
+	default:
+		nRc = typeNone;
+	}
 
-extern unsigned int getRegisterCount(const unsigned int opcode);
-extern unsigned int getDestinationSize(const unsigned int opcode);
+	return (nRc);
+}
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/fpsr.h linux-2.4.22-pre10/arch/arm/nwfpe/fpsr.h
--- linux-2.4.21/arch/arm/nwfpe/fpsr.h	2000-02-13 18:47:01.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/fpsr.h	2003-08-01 13:31:28.000000000 +0000
@@ -38,12 +38,12 @@
 ------------
 Note: the system id byte is read only  */
 
-typedef unsigned int FPSR;  /* type for floating point status register */
-typedef unsigned int FPCR;  /* type for floating point control register */
+typedef unsigned int FPSR;	/* type for floating point status register */
+typedef unsigned int FPCR;	/* type for floating point control register */
 
 #define MASK_SYSID		0xff000000
 #define BIT_HARDWARE		0x80000000
-#define FP_EMULATOR		0x01000000	/* System ID for emulator */ 
+#define FP_EMULATOR		0x01000000	/* System ID for emulator */
 #define FP_ACCELERATOR		0x81000000	/* System ID for FPA11 */
 
 /* EXCEPTION TRAP ENABLE BYTE
@@ -51,11 +51,11 @@
 
 #define MASK_TRAP_ENABLE	0x00ff0000
 #define MASK_TRAP_ENABLE_STRICT	0x001f0000
-#define BIT_IXE		0x00100000   /* inexact exception enable */
-#define BIT_UFE		0x00080000   /* underflow exception enable */
-#define BIT_OFE		0x00040000   /* overflow exception enable */
-#define BIT_DZE		0x00020000   /* divide by zero exception enable */
-#define BIT_IOE		0x00010000   /* invalid operation exception enable */
+#define BIT_IXE		0x00100000	/* inexact exception enable */
+#define BIT_UFE		0x00080000	/* underflow exception enable */
+#define BIT_OFE		0x00040000	/* overflow exception enable */
+#define BIT_DZE		0x00020000	/* divide by zero exception enable */
+#define BIT_IOE		0x00010000	/* invalid operation exception enable */
 
 /* SYSTEM CONTROL BYTE
 ---------------------- */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/single_cpdo.c linux-2.4.22-pre10/arch/arm/nwfpe/single_cpdo.c
--- linux-2.4.21/arch/arm/nwfpe/single_cpdo.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/single_cpdo.c	2003-08-01 13:34:43.000000000 +0000
@@ -1,6 +1,7 @@
 /*
     NetWinder Floating Point Emulator
     (c) Rebel.COM, 1998,1999
+    (c) Philip Blundell, 2001
 
     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
 
@@ -32,224 +33,92 @@
 float32 float32_log(float32 rFm);
 float32 float32_tan(float32 rFm);
 float32 float32_arccos(float32 rFm);
-float32 float32_pow(float32 rFn,float32 rFm);
-float32 float32_pol(float32 rFn,float32 rFm);
+float32 float32_pow(float32 rFn, float32 rFm);
+float32 float32_pol(float32 rFn, float32 rFm);
 
-unsigned int SingleCPDO(const unsigned int opcode)
+static float32 float32_rsf(float32 rFn, float32 rFm)
 {
-   FPA11 *fpa11 = GET_FPA11();
-   float32 rFm, rFn;
-   unsigned int Fd, Fm, Fn, nRc = 1;
-
-   Fm = getFm(opcode);
-   if (CONSTANT_FM(opcode))
-   {
-     rFm = getSingleConstant(Fm);
-   }
-   else
-   {  
-     switch (fpa11->fType[Fm])
-     {
-        case typeSingle:
-          rFm = fpa11->fpreg[Fm].fSingle;
-        break;
-        
-        default: return 0;
-     }
-   }
-
-   if (!MONADIC_INSTRUCTION(opcode))
-   {
-      Fn = getFn(opcode);
-      switch (fpa11->fType[Fn])
-      {
-        case typeSingle:
-          rFn = fpa11->fpreg[Fn].fSingle;
-        break;
-
-        default: return 0;
-      }
-   }
-
-   Fd = getFd(opcode);
-   switch (opcode & MASK_ARITHMETIC_OPCODE)
-   {
-      /* dyadic opcodes */
-      case ADF_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_add(rFn,rFm);
-      break;
-
-      case MUF_CODE:
-      case FML_CODE:
-        fpa11->fpreg[Fd].fSingle = float32_mul(rFn,rFm);
-      break;
-
-      case SUF_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_sub(rFn,rFm);
-      break;
-
-      case RSF_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_sub(rFm,rFn);
-      break;
-
-      case DVF_CODE:
-      case FDV_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_div(rFn,rFm);
-      break;
-
-      case RDF_CODE:
-      case FRD_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_div(rFm,rFn);
-      break;
-
-#if 0
-      case POW_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_pow(rFn,rFm);
-      break;
-
-      case RPW_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_pow(rFm,rFn);
-      break;
-#endif
-
-      case RMF_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_rem(rFn,rFm);
-      break;
-
-#if 0
-      case POL_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_pol(rFn,rFm);
-      break;
-#endif
-
-      /* monadic opcodes */
-      case MVF_CODE:
-         fpa11->fpreg[Fd].fSingle = rFm;
-      break;
-
-      case MNF_CODE:
-         rFm ^= 0x80000000;
-         fpa11->fpreg[Fd].fSingle = rFm;
-      break;
-
-      case ABS_CODE:
-         rFm &= 0x7fffffff;
-         fpa11->fpreg[Fd].fSingle = rFm;
-      break;
-
-      case RND_CODE:
-      case URD_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_round_to_int(rFm);
-      break;
-
-      case SQT_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_sqrt(rFm);
-      break;
-
-#if 0
-      case LOG_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_log(rFm);
-      break;
-
-      case LGN_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_ln(rFm);
-      break;
-
-      case EXP_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_exp(rFm);
-      break;
-
-      case SIN_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_sin(rFm);
-      break;
-
-      case COS_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_cos(rFm);
-      break;
-
-      case TAN_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_tan(rFm);
-      break;
-
-      case ASN_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_arcsin(rFm);
-      break;
-
-      case ACS_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_arccos(rFm);
-      break;
-
-      case ATN_CODE:
-         fpa11->fpreg[Fd].fSingle = float32_arctan(rFm);
-      break;
-#endif
-
-      case NRM_CODE:
-      break;
-      
-      default:
-      {
-        nRc = 0;
-      }
-   }
-
-   if (0 != nRc) fpa11->fType[Fd] = typeSingle;
-   return nRc;
+	return float32_sub(rFm, rFn);
 }
 
-#if 0
-float32 float32_exp(float32 Fm)
+static float32 float32_rdv(float32 rFn, float32 rFm)
 {
-//series
+	return float32_div(rFm, rFn);
 }
 
-float32 float32_ln(float32 Fm)
-{
-//series
-}
+static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = {
+	[ADF_CODE >> 20] = float32_add,
+	[MUF_CODE >> 20] = float32_mul,
+	[SUF_CODE >> 20] = float32_sub,
+	[RSF_CODE >> 20] = float32_rsf,
+	[DVF_CODE >> 20] = float32_div,
+	[RDF_CODE >> 20] = float32_rdv,
+	[RMF_CODE >> 20] = float32_rem,
 
-float32 float32_sin(float32 rFm)
-{
-//series
-}
+	[FML_CODE >> 20] = float32_mul,
+	[FDV_CODE >> 20] = float32_div,
+	[FRD_CODE >> 20] = float32_rdv,
+};
 
-float32 float32_cos(float32 rFm)
+static float32 float32_mvf(float32 rFm)
 {
-//series
+	return rFm;
 }
 
-float32 float32_arcsin(float32 rFm)
+static float32 float32_mnf(float32 rFm)
 {
-//series
+	return rFm ^ 0x80000000;
 }
 
-float32 float32_arctan(float32 rFm)
+static float32 float32_abs(float32 rFm)
 {
-  //series
+	return rFm & 0x7fffffff;
 }
 
-float32 float32_arccos(float32 rFm)
-{
-   //return float32_sub(halfPi,float32_arcsin(rFm));
-}
+static float32 (*const monadic_single[16])(float32 rFm) = {
+	[MVF_CODE >> 20] = float32_mvf,
+	[MNF_CODE >> 20] = float32_mnf,
+	[ABS_CODE >> 20] = float32_abs,
+	[RND_CODE >> 20] = float32_round_to_int,
+	[URD_CODE >> 20] = float32_round_to_int,
+	[SQT_CODE >> 20] = float32_sqrt,
+	[NRM_CODE >> 20] = float32_mvf,
+};
 
-float32 float32_log(float32 rFm)
+unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd)
 {
-  return float32_div(float32_ln(rFm),getSingleConstant(7));
-}
+	FPA11 *fpa11 = GET_FPA11();
+	float32 rFm;
+	unsigned int Fm, opc_mask_shift;
 
-float32 float32_tan(float32 rFm)
-{
-  return float32_div(float32_sin(rFm),float32_cos(rFm));
-}
+	Fm = getFm(opcode);
+	if (CONSTANT_FM(opcode)) {
+		rFm = getSingleConstant(Fm);
+	} else if (fpa11->fType[Fm] == typeSingle) {
+		rFm = fpa11->fpreg[Fm].fSingle;
+	} else {
+		return 0;
+	}
 
-float32 float32_pow(float32 rFn,float32 rFm)
-{
-  return float32_exp(float32_mul(rFm,float32_ln(rFn))); 
-}
+	opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
+	if (!MONADIC_INSTRUCTION(opcode)) {
+		unsigned int Fn = getFn(opcode);
+		float32 rFn;
 
-float32 float32_pol(float32 rFn,float32 rFm)
-{
-  return float32_arctan(float32_div(rFn,rFm)); 
+		if (fpa11->fType[Fn] == typeSingle &&
+		    dyadic_single[opc_mask_shift]) {
+			rFn = fpa11->fpreg[Fn].fSingle;
+			rFd->fSingle = dyadic_single[opc_mask_shift](rFn, rFm);
+		} else {
+			return 0;
+		}
+	} else {
+		if (monadic_single[opc_mask_shift]) {
+			rFd->fSingle = monadic_single[opc_mask_shift](rFm);
+		} else {
+			return 0;
+		}
+	}
+
+	return 1;
 }
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/softfloat.c linux-2.4.22-pre10/arch/arm/nwfpe/softfloat.c
--- linux-2.4.21/arch/arm/nwfpe/softfloat.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/softfloat.c	2003-08-01 13:35:07.000000000 +0000
@@ -29,8 +29,8 @@
 */
 
 #include "fpa11.h"
-#include "milieu.h"
-#include "softfloat.h"
+//#include "milieu.h"
+//#include "softfloat.h"
 
 /*
 -------------------------------------------------------------------------------
@@ -142,12 +142,14 @@
 Returns the sign bit of the single-precision floating-point value `a'.
 -------------------------------------------------------------------------------
 */
+#if 0	/* in softfloat.h */
 INLINE flag extractFloat32Sign( float32 a )
 {
 
     return a>>31;
 
 }
+#endif
 
 /*
 -------------------------------------------------------------------------------
@@ -184,9 +186,9 @@
 {
 #if 0
    float32 f;
-   __asm__("@ packFloat32;
-   	    mov %0, %1, asl #31;
-   	    orr %0, %2, asl #23;
+   __asm__("@ packFloat32				\n\
+   	    mov %0, %1, asl #31				\n\
+   	    orr %0, %2, asl #23				\n\
    	    orr %0, %3"
    	    : /* no outputs */
    	    : "g" (f), "g" (zSign), "g" (zExp), "g" (zSig)
@@ -321,12 +323,14 @@
 Returns the sign bit of the double-precision floating-point value `a'.
 -------------------------------------------------------------------------------
 */
+#if 0	/* in softfloat.h */
 INLINE flag extractFloat64Sign( float64 a )
 {
 
     return a>>63;
 
 }
+#endif
 
 /*
 -------------------------------------------------------------------------------
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/nwfpe/softfloat.h linux-2.4.22-pre10/arch/arm/nwfpe/softfloat.h
--- linux-2.4.21/arch/arm/nwfpe/softfloat.h	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/nwfpe/softfloat.h	2003-08-01 13:31:02.000000000 +0000
@@ -40,7 +40,9 @@
 input or output the `floatx80' type will be defined.
 -------------------------------------------------------------------------------
 */
+#ifdef CONFIG_FPE_NWFPE_XP
 #define FLOATX80
+#endif
 
 /*
 -------------------------------------------------------------------------------
@@ -229,4 +231,46 @@
 
 #endif
 
+static inline flag extractFloat32Sign(float32 a)
+{
+	return a >> 31;
+}
+
+static inline flag float32_eq_nocheck(float32 a, float32 b)
+{
+	return (a == b) || ((bits32) ((a | b) << 1) == 0);
+}
+
+static inline flag float32_lt_nocheck(float32 a, float32 b)
+{
+	flag aSign, bSign;
+
+	aSign = extractFloat32Sign(a);
+	bSign = extractFloat32Sign(b);
+	if (aSign != bSign)
+		return aSign && ((bits32) ((a | b) << 1) != 0);
+	return (a != b) && (aSign ^ (a < b));
+}
+
+static inline flag extractFloat64Sign(float64 a)
+{
+	return a >> 63;
+}
+
+static inline flag float64_eq_nocheck(float64 a, float64 b)
+{
+	return (a == b) || ((bits64) ((a | b) << 1) == 0);
+}
+
+static inline flag float64_lt_nocheck(float64 a, float64 b)
+{
+	flag aSign, bSign;
+
+	aSign = extractFloat64Sign(a);
+	bSign = extractFloat64Sign(b);
+	if (aSign != bSign)
+		return aSign && ((bits64) ((a | b) << 1) != 0);
+	return (a != b) && (aSign ^ (a < b));
+}
+
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/arm/tools/mach-types linux-2.4.22-pre10/arch/arm/tools/mach-types
--- linux-2.4.21/arch/arm/tools/mach-types	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/arm/tools/mach-types	2003-08-01 13:33:14.000000000 +0000
@@ -6,7 +6,7 @@
 # To add an entry into this database, please see Documentation/arm/README,
 # or contact rmk@arm.linux.org.uk
 #
-# Last update: Sat Mar 16 15:56:27 2002
+# Last update: Sat Jun 28 12:10:54 2003
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -71,7 +71,7 @@
 jupiter			SA1100_JUPITER		JUPITER			59
 psionw			ARCH_PSIONW		PSIONW			60
 aln			SA1100_ALN		ALN			61
-epxa10db		ARCH_CAMELOT		CAMELOT			62
+epxa			ARCH_CAMELOT		CAMELOT			62
 gds2200			SA1100_GDS2200		GDS2200			63
 psion_series7		SA1100_PSION_SERIES7	PSION_SERIES7		64
 xfile			SA1100_XFILE		XFILE			65
@@ -149,12 +149,12 @@
 blue_v1			ARCH_BLUE_V1		BLUE_V1			138
 pxa_cerf		ARCH_PXA_CERF		PXA_CERF		139
 arm7tevb		ARCH_ARM7TEVB		ARM7TEVB		140
-d7400			ARCH_D7400		D7400			141
+d7400			SA1100_D7400		D7400			141
 piranha			ARCH_PIRANHA		PIRANHA			142
 sbcamelot		SA1100_SBCAMELOT	SBCAMELOT		143
 kings			SA1100_KINGS		KINGS			144
 smdk2400		ARCH_SMDK2400		SMDK2400		145
-collie			ARCH_COLLIE		COLLIE			146
+collie			SA1100_COLLIE		COLLIE			146
 idr			ARCH_IDR		IDR			147
 badge4			SA1100_BADGE4		BADGE4			148
 webnet			ARCH_WEBNET		WEBNET			149
@@ -175,6 +175,184 @@
 iam			SA1100_IAM		IAM			164
 tt530			SA1100_TT530		TT530			165
 sam2400			ARCH_SAM2400		SAM2400			166
-jornada56x		ARCH_JORNADA56X		JORNADA56X		167
+jornada56x		SA1100_JORNADA56X	JORNADA56X		167
 active			SA1100_ACTIVE		ACTIVE			168
 iq80321			ARCH_IQ80321		IQ80321			169
+wid			SA1100_WID		WID			170
+sabinal			ARCH_SABINAL		SABINAL			171
+ixp425_matacumbe	ARCH_IXP425_MATACUMBE	IXP425_MATACUMBE	172
+miniprint		SA1100_MINIPRINT	MINIPRINT		173
+adm510x			ARCH_ADM510X		ADM510X			174
+svs200			SA1100_SVS200		SVS200			175
+atg_tcu			ARCH_ATG_TCU		ATG_TCU			176
+jornada820		SA1100_JORNADA820	JORNADA820		177
+s3c44b0			ARCH_S3C44B0		S3C44B0			178
+margis2			ARCH_MARGIS2		MARGIS2			179
+ks8695			ARCH_KS8695		KS8695			180
+brh			ARCH_BRH		BRH			181
+s3c2410			ARCH_S3C2410		S3C2410			182
+possio_px30		ARCH_POSSIO_PX30	POSSIO_PX30		183
+s3c2800			ARCH_S3C2800		S3C2800			184
+fleetwood		SA1100_FLEETWOOD	FLEETWOOD		185
+omaha			ARCH_OMAHA		OMAHA			186
+ta7			ARCH_TA7		TA7			187
+nova			SA1100_NOVA		NOVA			188
+hmk			ARCH_HMK		HMK			189
+karo			ARCH_KARO		KARO			190
+fester			SA1100_FESTER		FESTER			191
+gpi			ARCH_GPI		GPI			192
+smdk2410		ARCH_SMDK2410		SMDK2410		193
+premium			ARCH_PREMIUM		PREMIUM			194
+nexio			SA1100_NEXIO		NEXIO			195
+bitbox			SA1100_BITBOX		BITBOX			196
+g200			SA1100_G200		G200			197
+gill			SA1100_GILL		GILL			198
+pxa_mercury		ARCH_PXA_MERCURY	PXA_MERCURY		199
+ceiva			ARCH_CEIVA		CEIVA			200
+fret			SA1100_FRET		FRET			201
+emailphone		SA1100_EMAILPHONE	EMAILPHONE		202
+h3900			ARCH_H3900		H3900			203
+pxa1			ARCH_PXA1		PXA1			204
+koan369			SA1100_KOAN369		KOAN369			205
+cogent			ARCH_COGENT		COGENT			206
+esl_simputer		ARCH_ESL_SIMPUTER	ESL_SIMPUTER		207
+esl_simputer_clr	ARCH_ESL_SIMPUTER_CLR	ESL_SIMPUTER_CLR	208
+esl_simputer_bw		ARCH_ESL_SIMPUTER_BW	ESL_SIMPUTER_BW		209
+hhp_cradle		ARCH_HHP_CRADLE		HHP_CRADLE		210
+he500			ARCH_HE500		HE500			211
+inhandelf2		SA1100_INHANDELF2	INHANDELF2		212
+inhandftip		SA1100_INHANDFTIP	INHANDFTIP		213
+dnp1110			SA1100_DNP1110		DNP1110			214
+pnp1110			SA1100_PNP1110		PNP1110			215
+csb226			ARCH_CSB226		CSB226			216
+arnold			SA1100_ARNOLD		ARNOLD			217
+psiboard		SA1100_PSIBOARD		PSIBOARD		218
+jz8028			ARCH_JZ8028		JZ8028			219
+h5400			ARCH_IPAQ3		IPAQ3			220
+forte			SA1100_FORTE		FORTE			221
+acam			SA1100_ACAM		ACAM			222
+abox			SA1100_ABOX		ABOX			223
+atmel			ARCH_ATMEL		ATMEL			224
+sitsang			ARCH_SITSANG		SITSANG			225
+cpu1110lcdnet		SA1100_CPU1110LCDNET	CPU1110LCDNET		226
+mpl_vcma9		ARCH_MPL_VCMA9		MPL_VCMA9		227
+opus_a1			ARCH_OPUS_A1		OPUS_A1			228
+daytona			ARCH_DAYTONA		DAYTONA			229
+killbear		SA1100_KILLBEAR		KILLBEAR		230
+yoho			ARCH_YOHO		YOHO			231
+jasper			ARCH_JASPER		JASPER			232
+dsc25			ARCH_DSC25		DSC25			233
+innovator		ARCH_INNOVATOR		INNOVATOR		234
+ramses			ARCH_RAMSES		RAMSES			235
+s28x			ARCH_S28X		S28X			236
+mport3			ARCH_MPORT3		MPORT3			237
+pxa_eagle250		ARCH_PXA_EAGLE250	PXA_EAGLE250		238
+pdb			ARCH_PDB		PDB			239
+blue_2g			SA1100_BLUE_2G		BLUE_2G			240
+bluearch		SA1100_BLUEARCH		BLUEARCH		241
+ixdp2400		ARCH_IXMB2400		IXMB2400		242
+ixdp2800		ARCH_IXMB2800		IXMB2800		243
+explorer		SA1100_EXPLORER		EXPLORER		244
+ixdp425			ARCH_IXDP425		IXDP425			245
+chimp			ARCH_CHIMP		CHIMP			246
+stork_nest		ARCH_STORK_NEST		STORK_NEST		247
+stork_egg		ARCH_STORK_EGG		STORK_EGG		248
+wismo			SA1100_WISMO		WISMO			249
+ezlinx			ARCH_EZLINX		EZLINX			250
+at91rm9200		ARCH_AT91		AT91			251
+orion			ARCH_ORION		ORION			252
+neptune			ARCH_NEPTUNE		NEPTUNE			253
+hackkit			SA1100_HACKKIT		HACKKIT			254
+pxa_wins30		ARCH_PXA_WINS30		PXA_WINS30		255
+lavinna			SA1100_LAVINNA		LAVINNA			256
+pxa_uengine		ARCH_PXA_UENGINE	PXA_UENGINE		257
+innokom			ARCH_INNOKOM		INNOKOM			258
+bms			ARCH_BMS		BMS			259
+ixcdp1100		ARCH_IXCDP1100		IXCDP1100		260
+prpmc1100		ARCH_PRPMC1100		PRPMC1100		261
+at91rm9200dk		ARCH_AT91RM9200DK	AT91RM9200DK		262
+armstick		ARCH_ARMSTICK		ARMSTICK		263
+armonie			ARCH_ARMONIE		ARMONIE			264
+mport1			ARCH_MPORT1		MPORT1			265
+s3c5410			ARCH_S3C5410		S3C5410			266
+zcp320a			ARCH_ZCP320A		ZCP320A			267
+i_box			ARCH_I_BOX		I_BOX			268
+stlc1502		ARCH_STLC1502		STLC1502		269
+siren			ARCH_SIREN		SIREN			270
+greenlake		ARCH_GREENLAKE		GREENLAKE		271
+argus			ARCH_ARGUS		ARGUS			272
+combadge		SA1100_COMBADGE		COMBADGE		273
+rokepxa			ARCH_ROKEPXA		ROKEPXA			274
+cintegrator		ARCH_CINTEGRATOR	CINTEGRATOR		275
+guidea07		ARCH_GUIDEA07		GUIDEA07		276
+tat257			ARCH_TAT257		TAT257			277
+igp2425			ARCH_IGP2425		IGP2425			278
+bluegrama		ARCH_BLUEGRAMMA		BLUEGRAMMA		279
+ipod			ARCH_IPOD		IPOD			280
+adsbitsyx		ARCH_ADSBITSYX		ADSBITSYX		281
+trizeps2		ARCH_TRIZEPS2		TRIZEPS2		282
+viper			ARCH_VIPER		VIPER			283
+adsbitsyplus		SA1100_ADSBITSYPLUS	ADSBITSYPLUS		284
+adsagc			SA1100_ADSAGC		ADSAGC			285
+stp7312			ARCH_STP7312		STP7312			286
+nx_phnx			ARCH_PXA255		PXA255			287
+wep_ep250		ARCH_WEP_EP250		WEP_EP250		288
+inhandelf3		ARCH_INHANDELF3		INHANDELF3		289
+adi_coyote		ARCH_ADI_COYOTE		ADI_COYOTE		290
+iyonix			ARCH_IYONIX		IYONIX			291
+damicam_sa1110		ARCH_DAMICAM_SA1110	DAMICAM_SA1110		292
+meg03			ARCH_MEG03		MEG03			293
+pxa_whitechapel		ARCH_PXA_WHITECHAPEL	PXA_WHITECHAPEL		294
+nwsc			ARCH_NWSC		NWSC			295
+nwlarm			ARCH_NWLARM		NWLARM			296
+ixp425_mguard		ARCH_IXP425_MGUARD	IXP425_MGUARD		297
+pxa_netdcu4		ARCH_PXA_NETDCU4	PXA_NETDCU4		298
+ixdp2401		ARCH_IXDP2401		IXDP2401		299
+ixdp2801		ARCH_IXDP2801		IXDP2801		300
+zodiac			ARCH_ZODIAC		ZODIAC			301
+armmodul		ARCH_ARMMODUL		ARMMODUL		302
+ketop			SA1100_KETOP		KETOP			303
+av7200			ARCH_AV7200		AV7200			304
+arch_ti925		ARCH_ARCH_TI925		ARCH_TI925		305
+acq200			ARCH_ACQ200		ACQ200			306
+pt_dafit		SA1100_PT_DAFIT		PT_DAFIT		307
+ihba			ARCH_IHBA		IHBA			308
+quinque			ARCH_QUINQUE		QUINQUE			309
+nimbraone		ARCH_NIMBRAONE		NIMBRAONE		310
+nimbra29x		ARCH_NIMBRA29X		NIMBRA29X		311
+nimbra210		ARCH_NIMBRA210		NIMBRA210		312
+hhp_d95xx		ARCH_HHP_D95XX		HHP_D95XX		313
+labarm			ARCH_LABARM		LABARM			314
+m825xx			ARCH_M825XX		M825XX			315
+m7100			SA1100_M7100		M7100			316
+nipc2			ARCH_NIPC2		NIPC2			317
+fu7202			ARCH_FU7202		FU7202			318
+adsagx			ARCH_ADSAGX		ADSAGX			319
+pxa_pooh		ARCH_PXA_POOH		PXA_POOH		320
+bandon			ARCH_BANDON		BANDON			321
+pcm7210			ARCH_PCM7210		PCM7210			322
+nms9200			ARCH_NMS9200		NMS9200			323
+logodl			ARCH_LOGODL		LOGODL			324
+m7140			SA1100_M7140		M7140			325
+korebot			ARCH_KOREBOT		KOREBOT			326
+iq31244			ARCH_IQ31244		IQ31244			327
+koan393			SA1100_KOAN393		KOAN393			328
+inhandftip3		ARCH_INHANDFTIP3	INHANDFTIP3		329
+gonzo			ARCH_GONZO		GONZO			330
+bast			ARCH_BAST		BAST			331
+scanpass		ARCH_SCANPASS		SCANPASS		332
+ep7312_pooh		ARCH_EP7312_POOH	EP7312_POOH		333
+ta7s			ARCH_TA7S		TA7S			334
+ta7v			ARCH_TA7V		TA7V			335
+icarus			SA1100_ICARUS		ICARUS			336
+h1900			ARCH_H1900		H1900			337
+gemini			SA1100_GEMINI		GEMINI			338
+axim			ARCH_AXIM		AXIM			339
+audiotron		ARCH_AUDIOTRON		AUDIOTRON		340
+h2200			ARCH_H2200		H2200			341
+loox600			ARCH_LOOX600		LOOX600			342
+niop			ARCH_NIOP		NIOP			343
+dm310			ARCH_DM310		DM310			344
+seedpxa_c2		ARCH_SEEDPXA_C2		SEEDPXA_C2		345
+ixp4xx_mguardpci	ARCH_IXP4XX_MGUARD_PCI	IXP4XX_MGUARD_PCI	346
+h1940			ARCH_H1940		H1940			347
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/Makefile linux-2.4.22-pre10/arch/cris/Makefile
--- linux-2.4.21/arch/cris/Makefile	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/Makefile	2003-08-01 13:33:11.000000000 +0000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.27 2002/03/08 13:08:50 bjornw Exp $
+#
 # cris/Makefile
 #
 # This file is included by the global makefile so that you can add your own
@@ -56,6 +56,10 @@
 # each others config options
 SUBDIRS += arch/cris/boot/rescue
 endif
+
+# Note that the order of .o files below is important is some cases
+# (because initcalls are executed in the order they are linked)
+# Never add any driver before mm.o!
 CORE_FILES += arch/cris/kernel/kernel.o arch/cris/mm/mm.o
 DRIVERS += arch/cris/drivers/drivers.o
 LIBGCC = $(shell $(CC) $(CFLAGS) -print-file-name=libgcc.a)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/boot/compressed/README linux-2.4.22-pre10/arch/cris/boot/compressed/README
--- linux-2.4.21/arch/cris/boot/compressed/README	2001-02-09 00:32:44.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/boot/compressed/README	2003-08-01 13:34:08.000000000 +0000
@@ -1,6 +1,5 @@
 Creation of the self-extracting compressed kernel image (vmlinuz)
 -----------------------------------------------------------------
-$Id: README,v 1.1 2000/11/22 17:20:46 bjornw Exp $
 
 This can be slightly confusing because it's a process with many steps.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/boot/compressed/misc.c linux-2.4.22-pre10/arch/cris/boot/compressed/misc.c
--- linux-2.4.21/arch/cris/boot/compressed/misc.c	2001-05-01 23:04:56.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/boot/compressed/misc.c	2003-08-01 13:34:27.000000000 +0000
@@ -1,19 +1,17 @@
 /*
  * misc.c
  *
- * $Id: misc.c,v 1.6 2001/04/09 10:00:21 starvik Exp $
- * 
- * This is a collection of several routines from gzip-1.0.3 
+ * This is a collection of several routines from gzip-1.0.3
  * adapted for Linux.
  *
  * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
  * puts by Nick Holloway 1993, better puts by Martin Mares 1995
  * adoptation for Linux/CRIS Axis Communications AB, 1999
- * 
+ *
  */
 
 /* where the piggybacked kernel image expects itself to live.
- * it is the same adress we use when we network load an uncompressed
+ * it is the same address we use when we network load an uncompressed
  * image into DRAM, and it is the address the kernel is linked to live
  * at by etrax100.ld.
  */
@@ -65,8 +63,8 @@
 #define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
 #define RESERVED     0xC0 /* bit 6,7:   reserved */
 
-#define get_byte() inbuf[inptr++]	
-	
+#define get_byte() inbuf[inptr++]
+
 /* Diagnostic functions */
 #ifdef DEBUG
 #  define Assert(cond,msg) {if(!(cond)) error(msg);}
@@ -95,20 +93,20 @@
 static long bytes_out = 0;
 static uch *output_data;
 static unsigned long output_ptr = 0;
- 
+
 static void *malloc(int size);
 static void free(void *where);
 static void error(char *m);
 static void gzip_mark(void **);
 static void gzip_release(void **);
- 
+
 static void puts(const char *);
 
 /* the "heap" is put directly after the BSS ends, at end */
-  
+
 extern int end;
 static long free_mem_ptr = (long)&end;
- 
+
 #include "../../../../lib/inflate.c"
 
 static void *malloc(int size)
@@ -196,9 +194,9 @@
     ulg c = crc;         /* temporary variable */
     unsigned n;
     uch *in, *out, ch;
-    
+
     in = window;
-    out = &output_data[output_ptr]; 
+    out = &output_data[output_ptr];
     for (n = 0; n < outcnt; n++) {
 	    ch = *out++ = *in++;
 	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
@@ -229,7 +227,7 @@
 decompress_kernel()
 {
 	char revision;
-	
+
 	/* input_data is set in head.S */
 	inbuf = input_data;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/boot/rescue/head.S linux-2.4.22-pre10/arch/cris/boot/rescue/head.S
--- linux-2.4.21/arch/cris/boot/rescue/head.S	2002-02-25 19:37:52.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/boot/rescue/head.S	2003-08-01 13:34:12.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: head.S,v 1.10 2001/11/08 15:10:16 starvik Exp $
- * 
+/*
  * Rescue code, made to reside at the beginning of the
  * flash-memory. when it starts, it checks a partition
  * table at the first sector after the rescue sector.
@@ -52,7 +51,7 @@
  * 
  * Bit 0 in flags signifies RW or RO. The rescue code only bothers
  * to check the checksum for RO partitions, since the others will
- * change its data without updating the checksums. A 1 in bit 0
+ * change their data without updating the checksums. A 1 in bit 0
  * means RO, 0 means RW. That way, it is possible to set a partition
  * in RO mode initially, and later mark it as RW, since you can always
  * write 0's to the flash.
@@ -60,7 +59,7 @@
  * During the wait for serial input, the status LED will flash so the
  * user knows something went wrong.
  * 
- * Copyright (C) 1999,2001 Axis Communications AB
+ * Copyright (C) 1999, 2000, 2001, 2002, 2003 Axis Communications AB
  */
 
 #include <linux/config.h>
@@ -130,7 +129,7 @@
 
 	;; first put a jump test to give a possibility of upgrading the rescue code
 	;; without erasing/reflashing the sector. we put a longword of -1 here and if
-	;; its not -1, we jump using the value as jump target. since we can always
+	;; it is not -1, we jump using the value as jump target. since we can always
 	;; change 1's to 0's without erasing the sector, it is possible to add new
 	;; code after this and altering the jumptarget in an upgrade.
 
@@ -150,7 +149,20 @@
 	move.d 0x3, $r0    ; enable = on, phy = mii_clk
 	move.d $r0, [R_NETWORK_GEN_CONFIG]
 #endif
+
+	;; Setup port PA and PB default initial directions and data
+	;; (so we can flash LEDs, and so that DTR and others are set)
+	
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
+	move.b	$r0, [R_PORT_PA_DIR]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
+	move.b	$r0, [R_PORT_PA_DATA]
 	
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
+	move.b	$r0, [R_PORT_PB_DIR]
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
+	move.b	$r0, [R_PORT_PB_DATA]
+
 	;; We need to setup the bus registers before we start using the DRAM
 #include "../../lib/dram_init.S"
 
@@ -192,7 +204,7 @@
 	moveq	-1, $r7
 	
 ploop:	move.d	[$r3+], $r1	; partition offset (from ptable start)
-	bne	notfirst	; check if its the partition containing ptable
+	bne	notfirst	; check if it is the partition containing ptable
 	nop			; yes..
 	move.d	$r8, $r1	; for its checksum check, skip the ptable
 	move.d	[$r3+], $r2	; partition length
@@ -226,18 +238,6 @@
 	;; otherwise fall through to the rescue code.
 	
 do_rescue:
-	;; setup port PA and PB default initial directions and data
-	;; (so we can flash LEDs, and so that DTR and others are set)
-	
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
-	move.b	$r0, [R_PORT_PA_DIR]
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
-	move.b	$r0, [R_PORT_PA_DATA]
-	
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
-	move.b	$r0, [R_PORT_PB_DIR]
-	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
-	move.b	$r0, [R_PORT_PB_DATA]
 
 	;; setup the serial port at 115200 baud
 	
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/boot/rescue/kimagerescue.S linux-2.4.22-pre10/arch/cris/boot/rescue/kimagerescue.S
--- linux-2.4.21/arch/cris/boot/rescue/kimagerescue.S	2001-10-08 18:43:54.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/boot/rescue/kimagerescue.S	2003-08-01 13:34:31.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: kimagerescue.S,v 1.5 2001/10/03 17:15:15 bjornw Exp $
- * 
+/*
  * Rescue code to be prepended on a kimage and copied to the
  * rescue serial port.
  * This is called from the rescue code, it will copy received data to
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/boot/rescue/testrescue.S linux-2.4.22-pre10/arch/cris/boot/rescue/testrescue.S
--- linux-2.4.21/arch/cris/boot/rescue/testrescue.S	2001-10-08 18:43:54.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/boot/rescue/testrescue.S	2003-08-01 13:33:10.000000000 +0000
@@ -1,9 +1,8 @@
-/* $Id: testrescue.S,v 1.3 2001/10/03 17:15:15 bjornw Exp $
- *
+/*
  * Simple testcode to download by the rescue block.
  * Just lits some LEDs to show it was downloaded correctly.
- * 
- * Copyright (C) 1999 Axis Communications AB
+ *
+ * Copyright (C) 1999-2003 Axis Communications AB
  */
 
 #define ASSEMBLER_MACROS_ONLY
@@ -16,11 +15,9 @@
 	moveq	-1, $r2
 	move.b	$r2, [R_PORT_PA_DIR]
 	moveq	0, $r2
-	move.b	$r2, [R_PORT_PA_DATA]	
+	move.b	$r2, [R_PORT_PA_DATA]
 
 endless:
 	nop
 	ba	endless
 	nop
-
-	
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/config.in linux-2.4.22-pre10/arch/cris/config.in
--- linux-2.4.21/arch/cris/config.in	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/config.in	2003-08-01 13:33:36.000000000 +0000
@@ -32,14 +32,27 @@
 
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 
+string 'Kernel command line' CONFIG_ETRAX_CMDLINE "root=/dev/mtdblock3"
+
 bool 'Use kernel gdb debugger' CONFIG_ETRAX_KGDB
 
-bool 'Enable Etrax100 watchdog' CONFIG_ETRAX_WATCHDOG
+bool 'Use Artpec gdb debugger' CONFIG_ETRAX_AGDB
+
+bool 'Enable ETRAX watchdog' CONFIG_ETRAX_WATCHDOG
 if [ "$CONFIG_ETRAX_WATCHDOG" = "y" ]; then
-	bool 'Disable watchdog during Oops printouts' CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
+	bool '  Disable watchdog during Oops printouts' CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
 fi
 
+bool 'Enable ETRAX interrupt debugging' CONFIG_ETRAX_DEBUG_INTERRUPT
+
 bool 'Enable ETRAX fast timer API' CONFIG_ETRAX_FAST_TIMER
+if [ "$CONFIG_ETRAX_FAST_TIMER" = "y" ]; then
+	bool '  Enable fast timer logging' CONFIG_ETRAX_FAST_TIMER_LOGGING
+	bool '  Enable fast timer debug' CONFIG_ETRAX_FAST_TIMER_DEBUG
+	bool '  Enable fast timer sanity checks' CONFIG_ETRAX_FAST_TIMER_SANITY_CHECKS
+fi
+
+bool 'Enable reboot at out of memory' CONFIG_OOM_REBOOT
 
 endmenu
 
@@ -51,7 +64,7 @@
 	 Etrax-100-LX-v2	CONFIG_ETRAX100LX_V2	\
 	 Etrax-100-LX-for-xsim-simulator   CONFIG_SVINTO_SIM" Etrax-100-LX-v1
 
-# Etrax100 LX v1 has a MMU "feature" requiring a low mapping
+# ETRAX 100LX v1 has a MMU "feature" requiring a low mapping
 
 if [ "$CONFIG_ETRAX100LX" = "y" ]; then
 	define_bool CONFIG_CRIS_LOW_MAP y
@@ -64,8 +77,6 @@
 
 int 'Buswidth of flash in bytes' CONFIG_ETRAX_FLASH_BUSWIDTH 2
 
-string 'Root device name' CONFIG_ETRAX_ROOT_DEVICE "/dev/mtdblock3"
-
 choice 'Product LED port' \
 	"Port-PA-LEDs	CONFIG_ETRAX_PA_LEDS	\
 	 Port-PB-LEDs	CONFIG_ETRAX_PB_LEDS	\
@@ -73,36 +84,36 @@
 	 None	CONFIG_ETRAX_NO_LEDS" Port-PA-LEDs
 
 if [ "$CONFIG_ETRAX_NO_LEDS" != "y" ]; then
-  int '  First green LED bit' CONFIG_ETRAX_LED1G 2
-  int '  First red LED bit' CONFIG_ETRAX_LED1R 3
-  int '  Second green LED bit' CONFIG_ETRAX_LED2G 4
-  int '  Second red LED bit' CONFIG_ETRAX_LED2R 5
-  int '  Third green LED bit' CONFIG_ETRAX_LED3G 2
-  int '  Third red LED bit' CONFIG_ETRAX_LED3R 2
+	int '  First green LED bit' CONFIG_ETRAX_LED1G 2
+	int '  First red LED bit' CONFIG_ETRAX_LED1R 3
+	int '  Second green LED bit' CONFIG_ETRAX_LED2G 4
+	int '  Second red LED bit' CONFIG_ETRAX_LED2R 5
+	int '  Third green LED bit' CONFIG_ETRAX_LED3G 2
+	int '  Third red LED bit' CONFIG_ETRAX_LED3R 2
 fi
 
 if [ "$CONFIG_ETRAX_CSP0_LEDS" = "y" ]; then
-  int '  Fourth red LED bit' CONFIG_ETRAX_LED4R 2
-  int '  Fourth green LED bit' CONFIG_ETRAX_LED4G 2
-  int '  Fifth red LED bit' CONFIG_ETRAX_LED5R 2
-  int '  Fifth green LED bit' CONFIG_ETRAX_LED5G 2
-  int '  Sixth red LED bit' CONFIG_ETRAX_LED6R 2
-  int '  Sixth green LED bit' CONFIG_ETRAX_LED6G 2
-  int '  Seventh red LED bit' CONFIG_ETRAX_LED7R 2
-  int '  Seventh green LED bit' CONFIG_ETRAX_LED7G 2
-  int '  Eigth yellow LED bit' CONFIG_ETRAX_LED8Y 2
-  int '  Ninth yellow LED bit' CONFIG_ETRAX_LED9Y 2
-  int '  Tenth yellow LED bit' CONFIG_ETRAX_LED10Y 2
-  int '  Eleventh yellow LED bit' CONFIG_ETRAX_LED11Y 2
-  int '  Twelfth red LED bit' CONFIG_ETRAX_LED12R 2
-fi  
+	int '  Fourth red LED bit' CONFIG_ETRAX_LED4R 2
+	int '  Fourth green LED bit' CONFIG_ETRAX_LED4G 2
+	int '  Fifth red LED bit' CONFIG_ETRAX_LED5R 2
+	int '  Fifth green LED bit' CONFIG_ETRAX_LED5G 2
+	int '  Sixth red LED bit' CONFIG_ETRAX_LED6R 2
+	int '  Sixth green LED bit' CONFIG_ETRAX_LED6G 2
+	int '  Seventh red LED bit' CONFIG_ETRAX_LED7R 2
+	int '  Seventh green LED bit' CONFIG_ETRAX_LED7G 2
+	int '  Eigth yellow LED bit' CONFIG_ETRAX_LED8Y 2
+	int '  Ninth yellow LED bit' CONFIG_ETRAX_LED9Y 2
+	int '  Tenth yellow LED bit' CONFIG_ETRAX_LED10Y 2
+	int '  Eleventh yellow LED bit' CONFIG_ETRAX_LED11Y 2
+	int '  Twelfth red LED bit' CONFIG_ETRAX_LED12R 2
+fi
 
 choice 'Product debug-port' \
 	"Serial-0	CONFIG_ETRAX_DEBUG_PORT0	\
 	 Serial-1	CONFIG_ETRAX_DEBUG_PORT1	\
 	 Serial-2	CONFIG_ETRAX_DEBUG_PORT2	\
 	 Serial-3	CONFIG_ETRAX_DEBUG_PORT3	\
-	 disabled	CONFIG_ETRAX_DEBUG_PORT_NULL" Serial-0 
+	 disabled	CONFIG_ETRAX_DEBUG_PORT_NULL" Serial-0
 
 choice 'Product rescue-port' \
 	"Serial-0	CONFIG_ETRAX_RESCUE_SER0	\
@@ -115,13 +126,13 @@
 
 bool 'SDRAM support' CONFIG_ETRAX_SDRAM
 if [ "$CONFIG_ETRAX_SDRAM" = "n" ]; then
-	hex 'R_DRAM_CONFIG' CONFIG_ETRAX_DEF_R_DRAM_CONFIG 1a200040
-	hex 'R_DRAM_TIMING' CONFIG_ETRAX_DEF_R_DRAM_TIMING 5611
+	hex '  R_DRAM_CONFIG' CONFIG_ETRAX_DEF_R_DRAM_CONFIG 1a200040
+	hex '  R_DRAM_TIMING' CONFIG_ETRAX_DEF_R_DRAM_TIMING 5611
 fi
 
 if [ "$CONFIG_ETRAX_SDRAM" = "y" ]; then
-	hex 'R_SDRAM_CONFIG' CONFIG_ETRAX_DEF_R_SDRAM_CONFIG d2fa7878
-	hex 'R_SDRAM_TIMING' CONFIG_ETRAX_DEF_R_SDRAM_TIMING 80004801
+	hex '  R_SDRAM_CONFIG' CONFIG_ETRAX_DEF_R_SDRAM_CONFIG d2fa7878
+	hex '  R_SDRAM_TIMING' CONFIG_ETRAX_DEF_R_SDRAM_TIMING 80004801
 fi
 
 hex 'R_PORT_PA_DIR' CONFIG_ETRAX_DEF_R_PORT_PA_DIR 1c
@@ -132,13 +143,13 @@
 
 bool 'Software Shutdown Support' CONFIG_ETRAX_SOFT_SHUTDOWN
 if [ "$CONFIG_ETRAX_SOFT_SHUTDOWN" = "y" ]; then
-   int 'Shutdown bit on port CSP0' CONFIG_ETRAX_SHUTDOWN_BIT 12
-   int 'Power button bit on port G' CONFIG_ETRAX_POWERBUTTON_BIT 25
+   int '  Shutdown bit on port CSP0' CONFIG_ETRAX_SHUTDOWN_BIT 12
+   int '  Power button bit on port G' CONFIG_ETRAX_POWERBUTTON_BIT 25
 fi
 
 endmenu
 
-# bring in Etrax built-in drivers
+# bring in ETRAX built-in drivers
 
 source arch/cris/drivers/Config.in
 
@@ -199,7 +210,7 @@
   bool 'Network device support' CONFIG_NETDEVICES
   if [ "$CONFIG_NETDEVICES" = "y" ]; then
     source drivers/net/Config.in
-      if [ "$CONFIG_ATM" = "y" ]; then
+      if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
          source drivers/atm/Config.in
       fi
   fi
@@ -258,8 +269,9 @@
 #bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
 bool 'Kernel profiling support' CONFIG_PROFILE
 if [ "$CONFIG_PROFILE" = "y" ]; then
-  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+  int '  Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
 
+source crypto/Config.in
 source lib/Config.in
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/defconfig linux-2.4.22-pre10/arch/cris/defconfig
--- linux-2.4.21/arch/cris/defconfig	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/defconfig	2003-08-01 13:32:07.000000000 +0000
@@ -85,8 +85,12 @@
 # CONFIG_ETRAX_ETHERNET_LPSLAVE is not set
 CONFIG_ETRAX_SERIAL=y
 CONFIG_ETRAX_SERIAL_PORT0=y
+CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT=y
+CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN=y
 # CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB is not set
 CONFIG_ETRAX_SERIAL_PORT1=y
+CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT=y
+CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN=y
 # CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PB is not set
 # CONFIG_ETRAX_SERIAL_PORT2 is not set
 # CONFIG_ETRAX_SERIAL_PORT3 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/Config.in linux-2.4.22-pre10/arch/cris/drivers/Config.in
--- linux-2.4.21/arch/cris/drivers/Config.in	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/Config.in	2003-08-01 13:34:08.000000000 +0000
@@ -23,15 +23,21 @@
 
 bool 'Serial-port support' CONFIG_ETRAX_SERIAL
 if [ "$CONFIG_ETRAX_SERIAL" = "y" ]; then
-  bool '  Use fast timers for serial DMA flush (experimental)' CONFIG_ETRAX_SERIAL_FAST_TIMER
+  bool '  Use fast timers for serial DMA flush' CONFIG_ETRAX_SERIAL_FAST_TIMER
   if [ "$CONFIG_ETRAX_SERIAL_FAST_TIMER" = "n" ]; then
     bool '  Fast serial port DMA flush' CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
     if [ "$CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST" = "n" ]; then
       int '  Receive flush timeout (ticks) ' CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS 5
     fi
   fi
+  bool '  Enable external clock on PB6' CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED
+  if [ "$CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED" = "y" ]; then
+    int '  Extern clock frequency (baudrate=clk/8) (Hz)' CONFIG_ETRAX_EXTERN_PB6CLK_FREQ
+  fi
   bool '  Serial port 0 enabled' CONFIG_ETRAX_SERIAL_PORT0
   if [ "$CONFIG_ETRAX_SERIAL_PORT0" = "y" ]; then
+  bool '  Serial port 0 uses DMA6 out' CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT
+  bool '  Serial port 0 uses DMA7 in' CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN
   choice 'Ser0 DTR, RI, DSR and CD assignment' \
   "No_DTR_RI_DSR_CD      CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE \
    DTR_RI_DSR_CD_on_PA   CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PA \
@@ -67,6 +73,8 @@
 
   bool '  Serial port 1 enabled' CONFIG_ETRAX_SERIAL_PORT1
   if [ "$CONFIG_ETRAX_SERIAL_PORT1" = "y" ]; then
+  bool '  Serial port 1 uses DMA8 out' CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT
+  bool '  Serial port 1 uses DMA9 in' CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN
   choice 'Ser1 DTR, RI, DSR and CD assignment' \
   "No_DTR_RI_DSR_CD      CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_NONE \
    DTR_RI_DSR_CD_on_PA   CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PA \
@@ -106,6 +114,8 @@
   fi
   bool '  Serial port 2 enabled' CONFIG_ETRAX_SERIAL_PORT2
   if [ "$CONFIG_ETRAX_SERIAL_PORT2" = "y" ]; then
+  bool '  Serial port 2 uses DMA2 out' CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT
+  bool '  Serial port 2 uses DMA3 in' CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN
   choice 'Ser2 DTR, RI, DSR and CD assignment' \
   "No_DTR_RI_DSR_CD      CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE \
    DTR_RI_DSR_CD_on_PA   CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PA \
@@ -139,6 +149,8 @@
   fi
   bool '  Serial port 3 enabled' CONFIG_ETRAX_SERIAL_PORT3
   if [ "$CONFIG_ETRAX_SERIAL_PORT3" = "y" ]; then
+  bool '  Serial port 3 uses DMA4 out' CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT
+  bool '  Serial port 3 uses DMA5 in' CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN
   choice 'Ser3 DTR, RI, DSR and CD assignment' \
   "No_DTR_RI_DSR_CD      CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_NONE \
    DTR_RI_DSR_CD_on_PA   CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_ON_PA \
@@ -303,6 +315,7 @@
 
 bool 'Real Time Clock support' CONFIG_ETRAX_RTC
 if [ "$CONFIG_ETRAX_RTC" = "y" ]; then
+  bool '  Enable RTC read only mode' CONFIG_ETRAX_RTC_READONLY	 
   choice '  RTC chip' \
     "DS1302 CONFIG_ETRAX_DS1302 \
      PCF8563  CONFIG_ETRAX_PCF8563" DS1302
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/axisflashmap.c linux-2.4.22-pre10/arch/cris/drivers/axisflashmap.c
--- linux-2.4.21/arch/cris/drivers/axisflashmap.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/axisflashmap.c	2003-08-01 13:34:10.000000000 +0000
@@ -11,6 +11,9 @@
  * partition split defined below.
  *
  * $Log: axisflashmap.c,v $
+ * Revision 1.29  2003/04/01 14:12:06  starvik
+ * Added loglevel for lots of printks
+ *
  * Revision 1.28  2002/10/01 08:08:43  jonashg
  * The first partition ends at the start of the partition table.
  *
@@ -300,7 +303,8 @@
 {
 	struct mtd_info *mtd_cs = NULL;
 
-	printk("%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n",
+	printk(KERN_INFO 
+	       "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n",
 	       map_cs->name, map_cs->size, map_cs->map_priv_1);
 
 #ifdef CONFIG_MTD_AMDSTD
@@ -387,7 +391,7 @@
 	struct partitiontable_head *ptable_head;
 	struct partitiontable_entry *ptable;
 	int use_default_ptable = 1; /* Until proven otherwise. */
-	const char *pmsg = "  /dev/flash%d at 0x%08x, size 0x%08x\n";
+	const char *pmsg = KERN_INFO "  /dev/flash%d at 0x%08x, size 0x%08x\n";
 
 	if (!(mymtd = flash_probe())) {
 		/* There's no reason to use this module if no flash chip can
@@ -396,7 +400,7 @@
 		panic("axisflashmap found no flash chip!\n");
 	}
 
-	printk("%s: 0x%08x bytes of flash memory.\n",
+	printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n",
 	       mymtd->name, mymtd->size);
 
 	mymtd->module = THIS_MODULE;
@@ -440,7 +444,7 @@
 		ptable_ok = (csum == ptable_head->checksum);
 
 		/* Read the entries and use/show the info.  */
-		printk(" Found a%s partition table at 0x%p-0x%p.\n",
+		printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n",
 		       (ptable_ok ? " valid" : "n invalid"), ptable_head,
 		       max_addr);
 
@@ -472,14 +476,14 @@
 		axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR;
 		axis_partitions[pidx].mask_flags |= MTD_WRITEABLE;
 
-		printk(" Adding readonly flash partition for romfs image:\n");
+		printk(KERN_INFO " Adding readonly flash partition for romfs image:\n");
 		printk(pmsg, pidx, axis_partitions[pidx].offset,
 		       axis_partitions[pidx].size);
 		pidx++;
 	}
 
 	if (use_default_ptable) {
-		printk(" Using default partition table.\n");
+		printk(KERN_INFO " Using default partition table.\n");
 		err = add_mtd_partitions(mymtd, axis_default_partitions,
 		                         NUM_DEFAULT_PARTITIONS);
 	} else {
@@ -508,7 +512,7 @@
 			      "mtd_info!\n");
 		}
 
-		printk(" Adding RAM partition for romfs image:\n");
+		printk(KERN_INFO " Adding RAM partition for romfs image:\n");
 		printk(pmsg, pidx, romfs_start, romfs_length);
 
 		err = mtdram_init_device(mtd_ram, (void*)romfs_start, 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/ds1302.c linux-2.4.22-pre10/arch/cris/drivers/ds1302.c
--- linux-2.4.21/arch/cris/drivers/ds1302.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/ds1302.c	2003-08-01 13:34:30.000000000 +0000
@@ -4,9 +4,22 @@
 *!
 *! DESCRIPTION: Implements an interface for the DS1302 RTC through Etrax I/O
 *!
-*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status
+*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init
 *!
 *! $Log: ds1302.c,v $
+*! Revision 1.19  2003/06/12 08:02:05  johana
+*! Removed faulty comma from printk.
+*! Fixed warning () -> (void)
+*!
+*! Revision 1.18  2003/04/16 09:02:28  oskarp
+*! * Merged change_branch--rtc_readonly to main.
+*!
+*! Revision 1.17  2003/04/01 14:12:06  starvik
+*! Added loglevel for lots of printks
+*!
+*! Revision 1.16  2003/02/19 15:51:16  cedric
+*! Start the clock from ds1302_init()
+*!
 *! Revision 1.15  2002/10/11 16:14:33  johana
 *! Added CONFIG_ETRAX_DS1302_TRICKLE_CHARGE and initial setting of the
 *! trcklecharge register.
@@ -95,7 +108,7 @@
 *!
 *! (C) Copyright 1999, 2000, 2001  Axis Communications AB, LUND, SWEDEN
 *!
-*! $Id: ds1302.c,v 1.15 2002/10/11 16:14:33 johana Exp $
+*! $Id: ds1302.c,v 1.19 2003/06/12 08:02:05 johana Exp $
 *!
 *!***************************************************************************/
 
@@ -263,12 +276,23 @@
 void
 ds1302_writereg(int reg, unsigned char val) 
 {
-	ds1302_wenable();
-	start();
-	out_byte(0x80 | (reg << 1)); /* write register */
-	out_byte(val);
-	stop();
-	ds1302_wdisable();
+#ifndef CONFIG_ETRAX_RTC_READONLY
+	int do_writereg = 1;
+#else
+	int do_writereg = 0;
+	
+	if (reg == RTC_TRICKLECHARGER)
+		do_writereg = 1;
+#endif
+	
+	if (do_writereg) {
+		ds1302_wenable();
+		start();
+		out_byte(0x80 | (reg << 1)); /* write register */
+		out_byte(val);
+		stop();
+		ds1302_wdisable();
+	}
 }
 
 void
@@ -405,20 +429,33 @@
 			tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F);
 			ds1302_writereg(RTC_TRICKLECHARGER, tcs_val);
 			return 0;
-		}                
+		}
+		case RTC_VLOW_RD:
+		{
+			/* TODO: 
+			 * Implement voltage low detection support 
+			 */
+			printk(KERN_WARNING "DS1302: RTC Voltage Low detection"
+			       " is not supported\n");
+			return 0;
+		}
+		case RTC_VLOW_SET:
+		{
+			/* TODO:
+			 * Nothing to do since Voltage Low detection is not supported
+			 */
+			return 0;
+		}
 		default:
 			return -ENOIOCTLCMD;
 	}
 }
 
-int
-get_rtc_status(char *buf) 
+static void
+print_rtc_status(void) 
 {
-	char *p;
 	struct rtc_time tm;
 
-	p = buf;
-
 	get_rtc_time(&tm);
 
 	/*
@@ -426,13 +463,10 @@
 	 * time or for Universal Standard Time (GMT). Probably local though.
 	 */
 
-	p += sprintf(p,
-		"rtc_time\t: %02d:%02d:%02d\n"
-		"rtc_date\t: %04d-%02d-%02d\n",
-		tm.tm_hour, tm.tm_min, tm.tm_sec,
-		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
-
-	return  p - buf;
+	printk(KERN_INFO "rtc_time\t: %02d:%02d:%02d\n",
+	       tm.tm_hour, tm.tm_min, tm.tm_sec);
+	printk(KERN_INFO "rtc_date\t: %04d-%02d-%02d\n",
+	       tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
 }
 
 
@@ -466,11 +500,10 @@
 	out_byte(0xc1); /* read RAM byte 0 */
 
 	if((res = in_byte()) == MAGIC_PATTERN) {
-		char buf[100];
 		stop();
 		ds1302_wdisable();
-		printk("%s: RTC found.\n", ds1302_name);
-		printk("%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n",
+		printk(KERN_INFO "%s: RTC found.\n", ds1302_name);
+		printk(KERN_INFO "%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n",
 		       ds1302_name,
 		       CONFIG_ETRAX_DS1302_SDABIT,
 		       CONFIG_ETRAX_DS1302_SCLBIT,
@@ -480,12 +513,10 @@
 		       "PB",
 #endif
 		       CONFIG_ETRAX_DS1302_RSTBIT);
-                get_rtc_status(buf);
-                printk(buf);
+                print_rtc_status();
 		retval = 1;
 	} else {
 		stop();
-		printk("%s: RTC not found.\n", ds1302_name);
 		retval = 0;
 	}
 
@@ -518,9 +549,12 @@
 				   (IO_STATE(R_GEN_CONFIG, g0dir, out)));    
     		*R_GEN_CONFIG = genconfig_shadow;
 #endif
-		if (!ds1302_probe())
+		if (!ds1302_probe()) {
+			printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
       			return -1;
+		}
 #else
+		printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
     		return -1;
 #endif
   	}
@@ -533,5 +567,7 @@
 	/* Initialise trickle charger */
 	ds1302_writereg(RTC_TRICKLECHARGER,
 			RTC_TCR_PATTERN |(CONFIG_ETRAX_DS1302_TRICKLE_CHARGE & 0x0F));
+	// Start clock by resetting CLOCK_HALT
+	ds1302_writereg(RTC_SECONDS, (ds1302_readreg(RTC_SECONDS) & 0x7F));
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/eeprom.c linux-2.4.22-pre10/arch/cris/drivers/eeprom.c
--- linux-2.4.21/arch/cris/drivers/eeprom.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/eeprom.c	2003-08-01 13:32:41.000000000 +0000
@@ -1,4 +1,4 @@
-/*!*****************************************************************************
+/******************************************************************************
 *!
 *!  Implements an interface for i2c compatible eeproms to run under linux.
 *!  Supports 2k, 8k(?) and 16k. Uses adaptive timing adjustents by
@@ -20,6 +20,18 @@
 *!                                  in the spin-lock.
 *!
 *!  $Log: eeprom.c,v $
+*!  Revision 1.12  2003/04/09 08:31:14  pkj
+*!  Typo correction (taken from Linux 2.5).
+*!
+*!  Revision 1.11  2003/02/12 20:43:46  johana
+*!  Previous checkin removed beginning of comment.
+*!
+*!  Revision 1.10  2003/02/10 07:18:20  starvik
+*!  Removed misplaced ;
+*!
+*!  Revision 1.9  2003/01/22 06:54:46  starvik
+*!  Fixed warnings issued by GCC 3.2.1
+*!
 *!  Revision 1.8  2001/06/15 13:24:29  jonashg
 *!  * Added verification of pointers from userspace in read and write.
 *!  * Made busy counter volatile.
@@ -203,7 +215,7 @@
      * it will mirror the address space:
      * 1. We read two locations (that are mirrored), 
      *    if the content differs * it's a 16kB EEPROM.
-     * 2. if it doesn't differ - write diferent value to one of the locations,
+     * 2. if it doesn't differ - write different value to one of the locations,
      *    check the other - if content still is the same it's a 2k EEPROM,
      *    restore original data.
      */
@@ -493,7 +505,7 @@
 
 static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off)
 {
-  int i, read=0;
+  int read=0;
   unsigned long p = file->f_pos;
 
   unsigned char page;
@@ -519,7 +531,7 @@
   if(!eeprom_address(p))
   {
     printk(KERN_INFO "%s: Read failed to address the eeprom: "
-           "0x%08X (%i) page: %i\n", eeprom_name, p, p, page);
+           "0x%08lX (%li) page: %i\n", eeprom_name, p, p, page);
     i2c_stop();
     
     /* don't forget to wake them up */
@@ -602,7 +614,7 @@
       if(!eeprom_address(p))
       {
         printk(KERN_INFO "%s: Write failed to address the eeprom: "
-               "0x%08X (%i) \n", eeprom_name, p, p);
+               "0x%08lX (%li) \n", eeprom_name, p, p);
         i2c_stop();
         
         /* don't forget to wake them up */
@@ -740,7 +752,7 @@
 
 static int eeprom_address(unsigned long addr)
 {
-  int i, j;
+  int i;
   unsigned char page, offset;
 
   page   = (unsigned char) (addr >> 8);
@@ -795,7 +807,7 @@
   return 1;
 }
 
-/* Reads from current adress. */
+/* Reads from current address. */
 
 static int read_from_eeprom(char * buf, int count)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/ethernet.c linux-2.4.22-pre10/arch/cris/drivers/ethernet.c
--- linux-2.4.21/arch/cris/drivers/ethernet.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/ethernet.c	2003-08-01 13:33:06.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: ethernet.c,v 1.34 2002/12/13 07:17:44 starvik Exp $
+/* $Id: ethernet.c,v 1.44 2003/07/01 10:55:07 starvik Exp $
  *
  * e100net.c: A network driver for the ETRAX 100LX network controller.
  *
@@ -7,9 +7,52 @@
  * The outline of this driver comes from skeleton.c.
  *
  * $Log: ethernet.c,v $
- * Revision 1.34  2002/12/13 07:17:44  starvik
- * Basic ethtool and MII ioctls
- * Handle out of memory when allocating new buffers
+ * Revision 1.44  2003/07/01 10:55:07  starvik
+ * Never bring down link to make stupid POE equipment happy
+ *
+ * Revision 1.43  2003/04/24 08:26:50  starvik
+ * New LED behaviour: LED off when no link
+ *
+ * Revision 1.42  2003/04/10 07:14:58  starvik
+ * Merge of changes from todo list
+ *
+ * Revision 1.41  2003/04/09 08:31:14  pkj
+ * Typo correction (taken from Linux 2.5).
+ *
+ * Revision 1.40  2003/04/01 14:12:06  starvik
+ * Added loglevel for lots of printks
+ *
+ * Revision 1.39.2.3  2003/04/01 07:51:14  starvik
+ * Default Ethernet Stations Address can be specified with command line option.
+ *
+ * Revision 1.39.2.2  2003/03/31 15:41:07  starvik
+ * Only communicate with transciever when ETRAX is properly configured.
+ *
+ * Revision 1.39.2.1  2003/03/31 14:12:46  starvik
+ * Transmit interrupt always enabled. This has two side effects:
+ *   1. UDP (and possibly other protocols) works on quiet networks
+ *   2. Slightly lower transmit performance
+ *
+ * Revision 1.39  2003/03/06 15:45:39  henriken
+ * Off by one error in group address register setting.
+ *
+ * Revision 1.38  2003/02/27 17:23:07  starvik
+ * Corrected Rev to Revision
+ *
+ * Revision 1.37  2003/02/27 10:52:59  magnusmn
+ * More generic transceiver support.
+ *
+ * Revision 1.33.2.4  2003/02/24 16:51:26  magnusmn
+ * TDK specific registers to check speed/duplex
+ *
+ * Revision 1.33.2.3  2003/02/24 09:16:31  magnusmn
+ * ethernet.c
+ *
+ * Revision 1.33.2.2  2003/02/21 11:57:27  magnusmn
+ * Merging differences between 1.36 and 1.33 into ethernet.c (needed ethtool ioctl)
+ *
+ * Revision 1.33.2.1  2002/12/04 07:54:49  starvik
+ * First attempt to get more generic transceiver support
  *
  * Revision 1.33  2002/10/02 20:16:17  hp
  * SETF, SETS: Use underscored IO_x_ macros rather than incorrect token concatenation
@@ -220,6 +263,16 @@
 	struct sk_buff* skb;
 } etrax_eth_descr;
 
+/* Some transceivers requires special handling */
+struct transceiver_ops
+{
+	unsigned int oui;
+	void (*check_speed)(void);
+	void (*check_duplex)(void);
+};
+
+struct transceiver_ops* transceiver;
+
 /* Duplex settings */
 enum duplex
 {
@@ -240,10 +293,17 @@
 */
 #define MDIO_BASE_STATUS_REG                0x1
 #define MDIO_BASE_CONTROL_REG               0x0
+#define MDIO_PHY_ID_HIGH_REG                0x2
+#define MDIO_PHY_ID_LOW_REG                 0x3
 #define MDIO_BC_NEGOTIATE                0x0200
 #define MDIO_BC_FULL_DUPLEX_MASK         0x0100
 #define MDIO_BC_AUTO_NEG_MASK            0x1000
 #define MDIO_BC_SPEED_SELECT_MASK        0x2000
+#define MDIO_STATUS_100_FD               0x4000
+#define MDIO_STATUS_100_HD               0x2000
+#define MDIO_STATUS_10_FD                0x1000
+#define MDIO_STATUS_10_HD                0x0800
+#define MDIO_STATUS_SPEED_DUPLEX_MASK	 0x7800
 #define MDIO_ADVERTISMENT_REG               0x4
 #define MDIO_ADVERT_100_FD                0x100
 #define MDIO_ADVERT_100_HD                0x080
@@ -257,9 +317,13 @@
 
 /* Broadcom specific */
 #define MDIO_AUX_CTRL_STATUS_REG           0x18
-#define MDIO_FULL_DUPLEX_IND                0x1
-#define MDIO_SPEED                          0x2
-#define MDIO_PHYS_ADDR                      0x0
+#define MDIO_BC_FULL_DUPLEX_IND             0x1
+#define MDIO_BC_SPEED                       0x2
+
+/* TDK specific */
+#define MDIO_TDK_DIAGNOSTIC_REG              18
+#define MDIO_TDK_DIAGNOSTIC_RATE          0x400
+#define MDIO_TDK_DIAGNOSTIC_DPLX          0x800
 
 /* Network flash constants */
 #define NET_FLASH_TIME                  (HZ/50) /* 20 ms */
@@ -303,11 +367,12 @@
 static etrax_eth_descr TxDescList[NBR_OF_TX_DESC] __attribute__ ((aligned(32)));
 
 static unsigned int network_rec_config_shadow = 0;
+static unsigned int mdio_phy_addr; /* Transciever address */
 
 /* Network speed indication. */
 static struct timer_list speed_timer;
 static struct timer_list clear_led_timer;
-static int current_speed; /* Speed read from tranceiver */
+static int current_speed; /* Speed read from transceiver */
 static int current_speed_selection; /* Speed selected by user */
 static int led_next_time;
 static int led_active;
@@ -337,6 +402,7 @@
 static void e100_hardware_send_packet(char *buf, int length);
 static void update_rx_stats(struct net_device_stats *);
 static void update_tx_stats(struct net_device_stats *);
+static int e100_probe_transceiver(void);
 
 static void e100_check_speed(unsigned long dummy);
 static void e100_set_speed(unsigned long speed);
@@ -349,11 +415,25 @@
 static void e100_send_mdio_cmd(unsigned short cmd, int write_cmd);
 static void e100_send_mdio_bit(unsigned char bit);
 static unsigned char e100_receive_mdio_bit(void);
-static void e100_reset_tranceiver(void);
+static void e100_reset_transceiver(void);
 
 static void e100_clear_network_leds(unsigned long dummy);
 static void e100_set_network_leds(int active);
 
+static void broadcom_check_speed(void);
+static void broadcom_check_duplex(void);
+static void tdk_check_speed(void);
+static void tdk_check_duplex(void);
+static void generic_check_speed(void);
+static void generic_check_duplex(void);
+
+struct transceiver_ops transceivers[] = 
+{
+	{0x1018, broadcom_check_speed, broadcom_check_duplex},  /* Broadcom */
+	{0xC039, tdk_check_speed, tdk_check_duplex},            /* TDK */
+	{0x0000, generic_check_speed, generic_check_duplex}     /* Generic, must be last */
+};
+
 #define tx_done(dev) (*R_DMA_CH0_CMD == 0)
 
 /*
@@ -369,11 +449,12 @@
 {
 	int i;
 
-	printk("ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000-2001 Axis Communications AB\n");
+	printk(KERN_INFO
+	       "ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000-2001 Axis Communications AB\n");
 
 	dev->base_addr = (unsigned int)R_NETWORK_SA_0; /* just to have something to show */
 
-	printk("%s initialized\n", dev->name);
+	printk(KERN_INFO "%s initialized\n", dev->name);
 
 	/* make Linux aware of the new hardware  */
 
@@ -468,7 +549,6 @@
 	current_speed_selection = 0; /* Auto */
 	speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL;
 	speed_timer.function = e100_check_speed;
-	add_timer(&speed_timer);
         
 	clear_led_timer.function = e100_clear_network_leds;
         
@@ -476,8 +556,11 @@
 	current_duplex = autoneg;
 	duplex_timer.expires = jiffies + NET_DUPLEX_CHECK_INTERVAL;		
 	duplex_timer.function = e100_check_duplex;
-	add_timer(&duplex_timer);
 
+        /* Initialize group address registers to make sure that no */
+        /* unwanted addresses are matched */
+	*R_NETWORK_GA_0 = 0x00000000;
+	*R_NETWORK_GA_1 = 0x00000000;
 	return 0;
 }
 
@@ -508,8 +591,7 @@
 
 	/* show it in the log as well */
 
-	printk("%s: changed MAC to ", dev->name);
-
+	printk(KERN_INFO "%s: changed MAC to ", dev->name);
 	for (i = 0; i < 5; i++)
 		printk("%02X:", dev->dev_addr[i]);
 
@@ -532,12 +614,6 @@
 {
 	unsigned long flags;
 
-	/* disable the ethernet interface while we configure it */
-
-	*R_NETWORK_GEN_CONFIG =
-		IO_STATE(R_NETWORK_GEN_CONFIG, phy,    mii_clk) |
-		IO_STATE(R_NETWORK_GEN_CONFIG, enable, off);
-
 	/* enable the MDIO output pin */
 
 	*R_NETWORK_MGM_CTRL = IO_STATE(R_NETWORK_MGM_CTRL, mdoe, enable);
@@ -636,7 +712,8 @@
 	/* enable the irq's for ethernet DMA */
 
 	*R_IRQ_MASK2_SET =
-		IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set); 
+		IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set) |
+		IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set);
 
 	*R_IRQ_MASK0_SET =
 		IO_STATE(R_IRQ_MASK0_SET, overrun,       set) |
@@ -665,6 +742,14 @@
 
 	restore_flags(flags);
 	
+	/* Probe for transceiver */
+	if (e100_probe_transceiver())
+		goto grace_exit4;
+
+	/* Start duplex/speed timers */
+	add_timer(&speed_timer);
+	add_timer(&duplex_timer);
+
 	/* We are now ready to accept transmit requeusts from
 	 * the queueing layer of the networking.
 	 */
@@ -684,6 +769,33 @@
 	return -EAGAIN;
 }
 
+static void
+generic_check_speed(void)
+{
+	unsigned long data;
+	data = e100_get_mdio_reg(MDIO_ADVERTISMENT_REG);
+	if ((data & MDIO_ADVERT_100_FD) ||
+	    (data & MDIO_ADVERT_100_HD))
+		current_speed = 100;
+	else
+		current_speed = 10;
+}
+
+static void
+tdk_check_speed(void)
+{
+	unsigned long data;
+	data = e100_get_mdio_reg(MDIO_TDK_DIAGNOSTIC_REG);
+	current_speed = (data & MDIO_TDK_DIAGNOSTIC_RATE ? 100 : 10);
+}
+
+static void
+broadcom_check_speed(void)
+{
+	unsigned long data;
+	data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG);
+	current_speed = (data & MDIO_BC_SPEED ? 100 : 10);
+}
 
 static void
 e100_check_speed(unsigned long dummy)
@@ -695,8 +807,7 @@
 	if (!(data & MDIO_LINK_UP_MASK)) {
 		current_speed = 0;
 	} else {
-		data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG);
-		current_speed = (data & MDIO_SPEED ? 100 : 10);
+		transceiver->check_speed();
 	}
 	
 	if (old_speed != current_speed)
@@ -761,29 +872,21 @@
 static void
 e100_set_speed(unsigned long speed)
 {
-	current_speed_selection = speed;
-	e100_negotiate();
+	if (speed != current_speed_selection) {
+		current_speed_selection = speed;
+		e100_negotiate();
+	}
 }
 
 static void
 e100_check_duplex(unsigned long dummy)
 {
-	unsigned long data;
-
-	data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG);
-        
-	if (data & MDIO_FULL_DUPLEX_IND) {
-		if (!full_duplex) { /* Duplex changed to full? */
-			full_duplex = 1;
-			SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex);
-			*R_NETWORK_REC_CONFIG = network_rec_config_shadow;
-		}
-	} else { /* half */
-		if (full_duplex) { /* Duplex changed to half? */
-			full_duplex = 0;
-			SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex);
-			*R_NETWORK_REC_CONFIG = network_rec_config_shadow;
-		}
+	int old_duplex = full_duplex;
+	transceiver->check_duplex();
+	if (old_duplex != full_duplex) { 
+		/* Duplex changed */
+		SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex);
+		*R_NETWORK_REC_CONFIG = network_rec_config_shadow;
 	}
 
 	/* Reinitialize the timer. */
@@ -791,13 +894,71 @@
 	add_timer(&duplex_timer);
 }
 
+static void
+generic_check_duplex(void)
+{
+	unsigned long data;
+	data = e100_get_mdio_reg(MDIO_ADVERTISMENT_REG);
+	if ((data & MDIO_ADVERT_100_FD) ||
+	    (data & MDIO_ADVERT_10_FD))
+		full_duplex = 1;
+	else
+		full_duplex = 0;
+}
+
+static void
+tdk_check_duplex(void)
+{
+	unsigned long data;
+	data = e100_get_mdio_reg(MDIO_TDK_DIAGNOSTIC_REG);
+	full_duplex = (data & MDIO_TDK_DIAGNOSTIC_DPLX) ? 1 : 0;
+}
+
+static void
+broadcom_check_duplex(void)
+{
+	unsigned long data;
+	data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG);        
+	full_duplex = (data & MDIO_BC_FULL_DUPLEX_IND) ? 1 : 0;
+}
+
 static void 
 e100_set_duplex(enum duplex new_duplex)
 {
-	current_duplex = new_duplex;
-	e100_negotiate();
+	if (new_duplex != current_duplex) {
+		current_duplex = new_duplex;
+		e100_negotiate();
+	}
 }
 
+static int 
+e100_probe_transceiver(void)
+{
+	unsigned int phyid_high;
+	unsigned int phyid_low;
+	unsigned int oui;
+	struct transceiver_ops* ops = NULL;
+
+	/* Probe MDIO physical address */
+	for (mdio_phy_addr = 0; mdio_phy_addr <= 31; mdio_phy_addr++) {
+		if (e100_get_mdio_reg(MDIO_BASE_STATUS_REG) != 0xffff)
+			break;
+	}
+	if (mdio_phy_addr == 32)
+		 return -ENODEV;
+
+	/* Get manufacturer */
+	phyid_high = e100_get_mdio_reg(MDIO_PHY_ID_HIGH_REG);
+	phyid_low = e100_get_mdio_reg(MDIO_PHY_ID_LOW_REG);
+	oui = (phyid_high << 6) | (phyid_low >> 10);
+	
+	for (ops = &transceivers[0]; ops->oui; ops++) {
+		if (ops->oui == oui)
+			break;
+	}
+	transceiver = ops;
+	return 0;
+}
 
 static unsigned short
 e100_get_mdio_reg(unsigned char reg_num)
@@ -807,7 +968,7 @@
 	int bitCounter;
 	
 	/* Start of frame, OP Code, Physical Address, Register Address */
-	cmd = (MDIO_START << 14) | (MDIO_READ << 12) | (MDIO_PHYS_ADDR << 7) |
+	cmd = (MDIO_START << 14) | (MDIO_READ << 12) | (mdio_phy_addr << 7) |
 		(reg_num << 2);
 	
 	e100_send_mdio_cmd(cmd, 0);
@@ -828,7 +989,7 @@
 	int bitCounter;
 	unsigned short cmd;
 
-	cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (MDIO_PHYS_ADDR << 7) |
+	cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (mdio_phy_addr << 7) |
 	      (reg << 2);
 
 	e100_send_mdio_cmd(cmd, 1);
@@ -888,7 +1049,7 @@
 }
 
 static void 
-e100_reset_tranceiver(void)
+e100_reset_transceiver(void)
 {
 	unsigned short cmd;
 	unsigned short data;
@@ -896,7 +1057,7 @@
 
 	data = e100_get_mdio_reg(MDIO_BASE_CONTROL_REG);
 
-	cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (MDIO_PHYS_ADDR << 7) | (MDIO_BASE_CONTROL_REG << 2);
+	cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (mdio_phy_addr << 7) | (MDIO_BASE_CONTROL_REG << 2);
 
 	e100_send_mdio_cmd(cmd, 1);
 	
@@ -928,9 +1089,9 @@
 	RESET_DMA(NETWORK_TX_DMA_NBR);
 	WAIT_DMA(NETWORK_TX_DMA_NBR);
 	
-	/* Reset the tranceiver. */
+	/* Reset the transceiver. */
 	
-	e100_reset_tranceiver();
+	e100_reset_transceiver();
 	
 	/* and get rid of the packets that never got an interrupt */
 	while (myFirstTxDesc != myNextTxDesc)
@@ -978,9 +1139,6 @@
 
 	/* Stop queue if full */
 	if (myNextTxDesc == myFirstTxDesc) {
-		/* Enable transmit interrupt to wake up queue */
-		*R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do);		
-		*R_IRQ_MASK2_SET = IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set);
 		netif_stop_queue(dev);
 	}
 
@@ -1001,6 +1159,11 @@
 	struct net_local *np = (struct net_local *)dev->priv;
 	unsigned long irqbits = *R_IRQ_MASK2_RD;
  
+	/* Disable RX/TX IRQs to avoid reentrancy */
+	*R_IRQ_MASK2_CLR = 
+	  IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr) |
+	  IO_STATE(R_IRQ_MASK2_CLR, dma1_eop, clr);
+        
 	/* Handle received packets */
 	if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma1_eop, active)) {
 		/* acknowledge the eop interrupt */
@@ -1044,9 +1207,13 @@
 	if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma0_eop, active)) {
 		/* acknowledge the eop interrupt and wake up queue */
 		*R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do);
-		*R_IRQ_MASK2_CLR = IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr);		
 		netif_wake_queue(dev);
 	}
+
+	/* Enable RX/TX IRQs again */
+	*R_IRQ_MASK2_SET = 
+	  IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set) |
+	  IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set);
 }
 
 static void
@@ -1183,14 +1350,10 @@
 {
 	struct net_local *np = (struct net_local *)dev->priv;
 
-	printk("Closing %s.\n", dev->name);
+	printk(KERN_INFO "Closing %s.\n", dev->name);
 
 	netif_stop_queue(dev);
 
-	*R_NETWORK_GEN_CONFIG =
-		IO_STATE(R_NETWORK_GEN_CONFIG, phy,    mii_clk) |
-		IO_STATE(R_NETWORK_GEN_CONFIG, enable, off);
-	
 	*R_IRQ_MASK0_CLR =
 		IO_STATE(R_IRQ_MASK0_CLR, overrun, clr) |
 		IO_STATE(R_IRQ_MASK0_CLR, underrun, clr) |
@@ -1221,6 +1384,9 @@
 	update_rx_stats(&np->stats);
 	update_tx_stats(&np->stats);
 
+	/* Stop speed/duplex timers */
+	del_timer(&speed_timer);
+	del_timer(&duplex_timer);
 	return 0;
 }
 
@@ -1233,7 +1399,7 @@
 		case SIOCETHTOOL:
 			return e100_ethtool_ioctl(dev,ifr);
 		case SIOCGMIIPHY: /* Get PHY address */
-			data->phy_id = MDIO_PHYS_ADDR;
+			data->phy_id = mdio_phy_addr;
 			break;
 		case SIOCGMIIREG: /* Read MII register */
 			data->val_out = e100_get_mdio_reg(data->reg_num);
@@ -1252,7 +1418,7 @@
 		case SET_ETH_SPEED_AUTO:              /* Auto negotiate speed */
 			e100_set_speed(0);
 			break;
-		case SET_ETH_DUPLEX_HALF:              /* Hhalf duplex. */
+		case SET_ETH_DUPLEX_HALF:              /* Half duplex. */
 			e100_set_duplex(half);
 			break;
 		case SET_ETH_DUPLEX_FULL:              /* Full duplex. */
@@ -1285,7 +1451,7 @@
 			  SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
 			ecmd.port = PORT_TP;
 			ecmd.transceiver = XCVR_EXTERNAL;
-			ecmd.phy_address = MDIO_PHYS_ADDR;
+			ecmd.phy_address = mdio_phy_addr;
 			ecmd.speed = current_speed;
 			ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
 			ecmd.advertising = ADVERTISED_TP;
@@ -1328,7 +1494,7 @@
 			struct ethtool_drvinfo info;
 			memset((void *) &info, 0, sizeof (info));
 			strncpy(info.driver, "ETRAX 100LX", sizeof(info.driver) - 1);
-			strncpy(info.version, "$Rev$", sizeof(info.version) - 1);
+			strncpy(info.version, "$Revision: 1.44 $", sizeof(info.version) - 1);
 			strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1);
 			strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1);
 			info.regdump_len = 0;
@@ -1457,7 +1623,7 @@
 			
 			hash_ix &= 0x3f;
 			
-			if (hash_ix > 32) {
+			if (hash_ix >= 32) {
 				hi_bits |= (1 << (hash_ix-32));
 			}
 			else {
@@ -1526,7 +1692,7 @@
 
 	if (!current_speed) {
 		/* Make LED red, link is down */
-		LED_NETWORK_SET(LED_RED);
+		LED_NETWORK_SET(LED_OFF);
 	}
 	else if (light_leds) {
 		if (current_speed == 10) {
@@ -1555,4 +1721,26 @@
 		return -ENODEV;
 }
 
+static int __init
+e100_boot_setup(char* str)
+{
+	struct sockaddr sa = {0};
+	int i;
+
+	/* Parse the colon separated Ethernet station address */
+	for (i = 0; i <  ETH_ALEN; i++) {
+		unsigned int tmp;
+		if (sscanf(str + 3*i, "%2x", &tmp) != 1) {
+			printk(KERN_WARNING "Malformed station address");
+			return 0;
+		}
+		sa.sa_data[i] = (char)tmp;
+	}	
+
+	default_mac = sa;
+	return 1;
+}
+
+__setup("etrax100_eth=", e100_boot_setup);
+
 module_init(etrax_init_module);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/examples/kiobuftest.c linux-2.4.22-pre10/arch/cris/drivers/examples/kiobuftest.c
--- linux-2.4.21/arch/cris/drivers/examples/kiobuftest.c	2001-04-06 17:42:55.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/examples/kiobuftest.c	2003-08-01 13:34:45.000000000 +0000
@@ -4,18 +4,12 @@
  *
  * It is necessary because the pages the virtual pointers reference, might
  * not exist in memory (could be mapped to the zero-page, filemapped etc)
- * and DMA cannot trigger the MMU to force them in (and would have time 
+ * and DMA cannot trigger the MMU to force them in (and would have time
  * contraints making it impossible to wait for it anyway).
  *
- * Author:  Bjorn Wesen
- *
- * $Log: kiobuftest.c,v $
- * Revision 1.2  2001/02/27 13:52:50  bjornw
- * malloc.h -> slab.h
- *
- * Revision 1.1  2001/01/19 15:57:49  bjornw
- * Example of how to do direct HW -> user-mode DMA
+ * Copyright (c) 2001, 2002, 2003  Axis Communications AB
  *
+ * Author:  Bjorn Wesen
  *
  */
 
@@ -32,55 +26,55 @@
 
 #define KIOBUFTEST_MAJOR 124  /* in the local range, experimental */
 
-
 static ssize_t
 kiobuf_read(struct file *filp, char *buf, size_t len, loff_t *ppos)
 {
+	struct kiobuf *iobuf;
+	int res, i;
 
-     struct kiobuf *iobuf;
-     int res, i;
- 
-     /* Make a kiobuf that maps the entire length the reader has given
-      * us
-      */
-
-     res = alloc_kiovec(1, &iobuf);
-     if (res)
-	     return res;
-     
-     if((res = map_user_kiobuf(READ, iobuf, (unsigned long)buf, len))) {
-	     printk("map_user_kiobuf failed, return %d\n", res);
-	     return res;
-     }
-
-     /* At this point, the virtual area buf[0] -> buf[len-1] will
-      * have corresponding pages mapped in physical memory and locked
-      * until we unmap the kiobuf. They cannot be swapped out or moved
-      * around.
-      */
-
-     printk("nr_pages == %d\noffset == %d\nlength == %d\n",
-	    iobuf->nr_pages, iobuf->offset, iobuf->length);
-
-     for(i = 0; i < iobuf->nr_pages; i++) {
-	     printk("page_add(maplist[%d]) == 0x%x\n", i,
-		    page_address(iobuf->maplist[i]));
-     }
-
-     /* This is the place to create the necessary scatter-gather vector
-      * for the DMA using the iobuf->maplist array and page_address
-      * (don't forget __pa if the DMA needs the actual physical DRAM address)
-      * and run it.
-      */
+	/*
+	 * Make a kiobuf that maps the entire length the reader has given us.
+	 */
 
+	res = alloc_kiovec(1, &iobuf);
+	if (res)
+		return res;
+
+	if ((res = map_user_kiobuf(READ, iobuf, (unsigned long)buf, len))) {
+		printk("map_user_kiobuf failed, return %d\n", res);
+		free_kiovec(1, &iobuf);
+		return res;
+	}
+
+	/*
+	 * At this point, the virtual area buf[0] -> buf[len-1] will have
+	 * corresponding pages mapped in physical memory and locked until
+	 * we unmap the kiobuf. They cannot be swapped out or moved around.
+	 */
+
+	printk("nr_pages == %d\noffset == %d\nlength == %d\n",
+	       iobuf->nr_pages, iobuf->offset, iobuf->length);
+
+	for (i = 0; i < iobuf->nr_pages; i++) {
+		printk("page_add(maplist[%d]) == 0x%x\n", i,
+		       page_address(iobuf->maplist[i]));
+	}
+
+	/*
+	 * This is the place to create the necessary scatter-gather vector
+	 * for the DMA using the iobuf->maplist array and page_address (don't
+	 * forget __pa if the DMA needs the actual physical DRAM address)
+	 * and run it.
+	 */
 
 
 
-     /* Release the mapping and exit */
+	/* Release the mapping and exit */
 
-     unmap_kiobuf(iobuf); /* The unlock_kiobuf is implicit here */
+	unmap_kiobuf(iobuf); /* The unlock_kiobuf is implicit here */
+	free_kiovec(1, &iobuf);
 
-     return len;
+	return len;
 }
 
 
@@ -97,7 +91,7 @@
 	/* register char device */
 
 	res = register_chrdev(KIOBUFTEST_MAJOR, "kiobuftest", &kiobuf_fops);
-	if(res < 0) {
+	if (res < 0) {
 		printk(KERN_ERR "kiobuftest: couldn't get a major number.\n");
 		return res;
 	}
@@ -105,4 +99,11 @@
 	printk("Initializing kiobuf-test device\n");
 }
 
+static void __exit
+kiobuftest_exit(void)
+{
+	unregister_chrdev(KIOBUFTEST_MAJOR, "kiobuftest");
+}
+
 module_init(kiobuftest_init);
+module_exit(kiobuftest_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/gpio.c linux-2.4.22-pre10/arch/cris/drivers/gpio.c
--- linux-2.4.21/arch/cris/drivers/gpio.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/gpio.c	2003-08-01 13:30:31.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: gpio.c,v 1.21 2002/12/02 08:11:41 starvik Exp $
+/* $Id: gpio.c,v 1.25 2003/06/24 07:24:31 johana Exp $
  *
  * Etrax general port I/O device
  *
@@ -9,6 +9,22 @@
  *             Johan Adolfsson  (read/set directions, write, port G)
  *
  * $Log: gpio.c,v $
+ * Revision 1.25  2003/06/24 07:24:31  johana
+ * Added gpio_pa_irq_enabled_mask to keep track of what interrupts we have
+ * enabled so we anly clear those that we have enabled and let bits/pins
+ * used by other drivers alone.
+ * Update gpio_some_alarms in IO_CLRALARM ioctl().
+ *
+ * Revision 1.24  2003/06/19 08:58:25  johana
+ * Turn off interrupts while fiddling with genconfig_shadow.
+ * Put some printk within D() macro.
+ *
+ * Revision 1.23  2003/04/01 14:12:06  starvik
+ * Added loglevel for lots of printks
+ *
+ * Revision 1.22  2003/01/09 18:03:47  starvik
+ * init_ioremap is now called by kernel before device drivers are initialized
+ *
  * Revision 1.21  2002/12/02 08:11:41  starvik
  * Merge of Linux 2.4.20
  *
@@ -169,6 +185,7 @@
 static struct gpio_private *alarmlist = 0;
 
 static int gpio_some_alarms = 0; /* Set if someone uses alarm */
+static unsigned long gpio_pa_irq_enabled_mask = 0;
 
 /* Port A and B use 8 bit access, but Port G is 32 bit */
 #define NUM_PORTS (GPIO_MINOR_B+1)
@@ -238,13 +255,19 @@
 	unsigned long data;
 	poll_wait(file, &priv->alarm_wq, wait);
 	if (priv->minor == GPIO_MINOR_A) {
+		unsigned long flags;
 		unsigned long tmp;
 		data = *R_PORT_PA_DATA;
 		/* PA has support for high level interrupt -
 		 * lets activate for those low and with highalarm set
 		 */
 		tmp = ~data & priv->highalarm & 0xFF;
-		*R_IRQ_MASK1_SET = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
+		tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
+		save_flags(flags); cli();
+		gpio_pa_irq_enabled_mask |= tmp;
+		*R_IRQ_MASK1_SET = tmp;
+		restore_flags(flags);
+		
 	} else if (priv->minor == GPIO_MINOR_B)
 		data = *R_PORT_PB_DATA;
 	else if (priv->minor == GPIO_MINOR_G)
@@ -293,12 +316,15 @@
 {
 	unsigned long tmp;
 	/* Find what PA interrupts are active */
-	tmp = (*R_IRQ_READ1 >> R_IRQ_READ1__pa0__BITNR) & 0xFF;
+	tmp = (*R_IRQ_READ1);
+
+	/* Find those that we have enabled */
+	tmp &= gpio_pa_irq_enabled_mask;
+
 	/* Clear them.. */
-	/* NOTE: Maybe we need to be more careful here if some other
-	 * driver uses PA interrupt as well?
-	 */
-	*R_IRQ_MASK1_CLR = (tmp << R_IRQ_MASK1_CLR__pa0__BITNR);
+	*R_IRQ_MASK1_CLR = tmp;
+	gpio_pa_irq_enabled_mask &= ~tmp;
+	
 	if (gpio_some_alarms) {
 		etrax_gpio_wake_up_check();
 	}
@@ -437,7 +463,7 @@
 		p = p->next;
 	}
 	gpio_some_alarms = 0;
-		
+	
 	return 0;
 }
 
@@ -459,6 +485,7 @@
 		return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
 	} else if (priv->minor == GPIO_MINOR_G) {
 		/* We must fiddle with R_GEN_CONFIG to change dir */
+		save_flags(flags); cli();
 		if (((arg & dir_g_in_bits) != arg) && 
 		    (arg & changeable_dir_g)) {
 			arg &= changeable_dir_g;
@@ -483,16 +510,17 @@
 				dir_g_in_bits |= (1<<24);
 				dir_g_out_bits &= ~(1<<24);
 			}
-			printk("gpio: SETINPUT on port G set "
-				"genconfig to 0x%08lX "
-				"in_bits: 0x%08lX "
-				"out_bits: 0x%08lX\n", 
-			       (unsigned long)genconfig_shadow, 
-			       dir_g_in_bits, dir_g_out_bits);
+			D(printk(KERN_INFO "gpio: SETINPUT on port G set "
+				 "genconfig to 0x%08lX "
+				 "in_bits: 0x%08lX "
+				 "out_bits: 0x%08lX\n", 
+				 (unsigned long)genconfig_shadow, 
+				 dir_g_in_bits, dir_g_out_bits));
 			*R_GEN_CONFIG = genconfig_shadow;
 			/* Must be a >120 ns delay before writing this again */
 				
 		}
+		restore_flags(flags);
 		return dir_g_in_bits;
 	}
 	return 0;
@@ -508,7 +536,8 @@
 		restore_flags(flags);
 		return *priv->dir_shadow;
 	} else if (priv->minor == GPIO_MINOR_G) {
-		/* We must fiddle with R_GEN_CONFIG to change dir */			
+		/* We must fiddle with R_GEN_CONFIG to change dir */
+		save_flags(flags); cli();
 		if (((arg & dir_g_out_bits) != arg) &&
 		    (arg & changeable_dir_g)) {
 			/* Set bits in genconfig to set to output */
@@ -532,15 +561,16 @@
 				dir_g_out_bits |= (1<<24);
 				dir_g_in_bits &= ~(1<<24);
 			}
-			printk("gpio: SETOUTPUT on port G set "
-				"genconfig to 0x%08lX "
-				"in_bits: 0x%08lX "
-				"out_bits: 0x%08lX\n", 
-			       (unsigned long)genconfig_shadow, 
-			       dir_g_in_bits, dir_g_out_bits);
+			D(printk(KERN_INFO "gpio: SETOUTPUT on port G set "
+				 "genconfig to 0x%08lX "
+				 "in_bits: 0x%08lX "
+				 "out_bits: 0x%08lX\n", 
+				 (unsigned long)genconfig_shadow, 
+				 dir_g_in_bits, dir_g_out_bits));
 			*R_GEN_CONFIG = genconfig_shadow;
 			/* Must be a >120 ns delay before writing this again */
 		}
+		restore_flags(flags);
 		return dir_g_out_bits & 0x7FFFFFFF;
 	}
 	return 0;
@@ -605,6 +635,20 @@
 		// clear alarm for bits with 1 in arg
 		priv->highalarm &= ~arg;
 		priv->lowalarm  &= ~arg;
+		{
+			/* Must update gpio_some_alarms */
+			struct gpio_private *p = alarmlist;
+			int some_alarms;
+			some_alarms = 0;
+			while (p) {
+				if (p->highalarm | p->lowalarm) {
+					some_alarms = 1;
+					break;
+				}
+				p = p->next;
+			}
+			gpio_some_alarms = some_alarms;
+		}		
 		break;
 	case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
 		/* Read direction 0=input 1=output */
@@ -824,9 +868,11 @@
 	dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
 
 
-	printk("GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n",
+	printk(KERN_INFO
+	       "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n",
 	       dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
-	printk("GPIO port G: dir: %08lX changeable: %08lX\n", 
+	printk(KERN_INFO
+	       "GPIO port G: dir: %08lX changeable: %08lX\n", 
 	       dir_g_shadow, changeable_dir_g);
 }
 
@@ -835,7 +881,6 @@
 static __init int
 gpio_init(void)
 {
-	extern void init_ioremap(void);
 	int res;
 #if defined (CONFIG_ETRAX_CSP0_LEDS)
 	int i;
@@ -850,8 +895,7 @@
 	}
 
 	/* Clear all leds */
-#if defined (CONFIG_ETRAX_CSP0_LEDS) ||  defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS) 
-	init_ioremap();
+#if defined (CONFIG_ETRAX_CSP0_LEDS) ||  defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS)
 	LED_NETWORK_SET(0);
 	LED_ACTIVE_SET(0);
 	LED_DISK_READ(0);
@@ -865,7 +909,8 @@
 
 #endif
 	gpio_init_port_g();
-	printk("ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n");
+	printk(KERN_INFO
+	       "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n");
 	/* We call etrax_gpio_wake_up_check() from timer interrupt and
 	 * from cpu_idle() in kernel/process.c
 	 * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
@@ -873,11 +918,11 @@
 	 */  
 	if (request_irq(TIMER0_IRQ_NBR, gpio_poll_timer_interrupt,
 			SA_SHIRQ | SA_INTERRUPT,"gpio poll", NULL)) {
-		printk("err: timer0 irq for gpio\n");
+		printk(KERN_CRIT "err: timer0 irq for gpio\n");
 	}
 	if (request_irq(PA_IRQ_NBR, gpio_pa_interrupt,
 			SA_SHIRQ | SA_INTERRUPT,"gpio PA", NULL)) {
-		printk("err: PA irq for gpio\n");
+		printk(KERN_CRIT "err: PA irq for gpio\n");
 	}
 	
 	return res;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/i2c.c linux-2.4.22-pre10/arch/cris/drivers/i2c.c
--- linux-2.4.21/arch/cris/drivers/i2c.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/i2c.c	2003-08-01 13:30:57.000000000 +0000
@@ -11,7 +11,26 @@
 *! Jan 14 2000  Johan Adolfsson    Fixed PB shadow register stuff - 
 *!                                 don't use PB_I2C if DS1302 uses same bits,
 *!                                 use PB.
+*| June 23 2003 Pieter Grimmerink  Added 'i2c_sendnack'. i2c_readreg now
+*|                                 generates nack on last received byte, 
+*|                                 instead of ack.
+*|                                 i2c_getack changed data level while clock
+*|                                 was high, causing DS75 to see  a stop condition
+*|
 *! $Log: i2c.c,v $
+*! Revision 1.12  2003/06/23 14:43:47  oskarp
+*! * i2c_sendnack is added.
+*!   - i2c_readreg now generates nack on last received byte, instead of ack.
+*!     i2c_getack changed data level while clock was high, causing DS75 to
+*!     see a stop condition.
+*!
+*! Revision 1.11  2003/05/23 09:37:23  oskarp
+*! * Made i2c_init() visible.
+*!   - e.g. pcf856.c uses i2c_init().
+*!
+*! Revision 1.10  2003/04/01 14:12:06  starvik
+*! Added loglevel for lots of printks
+*!
 *! Revision 1.9  2002/10/31 15:32:26  starvik
 *! Update Port B register and shadow even when running with hardware support
 *!   to avoid glitches when reading bits
@@ -53,7 +72,7 @@
 *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
 *!
 *!***************************************************************************/
-/* $Id: i2c.c,v 1.9 2002/10/31 15:32:26 starvik Exp $ */
+/* $Id: i2c.c,v 1.12 2003/06/23 14:43:47 oskarp Exp $ */
 /****************** INCLUDE FILES SECTION ***********************************/
 
 #include <linux/module.h>
@@ -133,7 +152,7 @@
 
 #define i2c_getbit() (((*R_PORT_PB_READ & (1 << SDABIT))) >> SDABIT)
 
-#else
+#else /* !CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C */
 /* enable or disable the i2c interface */
 
 #define i2c_enable() *R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_en))
@@ -163,7 +182,8 @@
 /* read a bit from the i2c interface */
 
 #define i2c_getbit() (*R_PORT_PB_READ & 0x1)
-#endif
+
+#endif /* CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C */
 
 /* use the kernels delay routine */
 
@@ -299,6 +319,12 @@
 	}
 	i2c_clk(I2C_CLOCK_HIGH);
 	i2c_delay(CLOCK_HIGH_TIME);
+	
+	/*
+	 * we leave the clock low, getbyte is usually followed
+	 * by sendack/nack, they assume the clock to be low
+	 */
+	i2c_clk(I2C_CLOCK_LOW);
 	return aBitByte;
 }
 
@@ -360,6 +386,13 @@
 		i2c_delay(CLOCK_HIGH_TIME/2);
 	}
 
+   /*
+    * our clock is high now, make sure data is low
+    * before we enable our output. If we keep data high
+    * and enable output, we would generate a stop condition.
+    */
+   i2c_data(I2C_DATA_LOW);
+   
 	/*
 	 * end clock pulse
 	 */
@@ -417,6 +450,37 @@
 
 /*#---------------------------------------------------------------------------
 *#
+*# FUNCTION NAME: i2c_sendnack
+*#
+*# DESCRIPTION  : Sends NACK on received data
+*#
+*#--------------------------------------------------------------------------*/
+void
+i2c_sendnack(void)
+{
+	/*
+	 * enable output
+	 */
+	i2c_delay(CLOCK_LOW_TIME);
+	i2c_dir_out();
+	/*
+	 * set data high
+	 */
+	i2c_data(I2C_DATA_HIGH);
+	/*
+	 * generate clock pulse
+	 */
+	i2c_delay(CLOCK_HIGH_TIME/6);
+	i2c_clk(I2C_CLOCK_HIGH);
+	i2c_delay(CLOCK_HIGH_TIME);
+	i2c_clk(I2C_CLOCK_LOW);
+	i2c_delay(CLOCK_LOW_TIME);
+	
+	i2c_dir_in();
+}
+
+/*#---------------------------------------------------------------------------
+*#
 *# FUNCTION NAME: i2c_writereg
 *#
 *# DESCRIPTION  : Writes a value to an I2C device
@@ -546,9 +610,10 @@
 		 */
 		b = i2c_inbyte();
 		/*
-		 * send Ack
+		 * last received byte needs to be nacked
+		 * instead of acked
 		 */
-		i2c_sendack();
+		i2c_sendnack();
 		/*
 		 * end sequence
 		 */
@@ -623,7 +688,7 @@
 	release:  i2c_release,
 };
 
-static int __init
+int __init
 i2c_init(void)
 {
 	int res;
@@ -653,7 +718,7 @@
 		return res;
 	}
 
-	printk("I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n");
+	printk(KERN_INFO "I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n");
 	
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/i2c.h linux-2.4.22-pre10/arch/cris/drivers/i2c.h
--- linux-2.4.21/arch/cris/drivers/i2c.h	2001-05-20 00:43:05.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/i2c.h	2003-08-01 13:34:27.000000000 +0000
@@ -1,6 +1,8 @@
-/* $Id: i2c.h,v 1.3 2001/03/19 12:43:01 markusl Exp $ */
+
+#include <linux/init.h>
 
 /* High level I2C actions */
+int __init i2c_init(void);
 int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue);
 unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg);
 
@@ -11,6 +13,3 @@
 unsigned char i2c_inbyte(void);
 int i2c_getack(void);
 void i2c_sendack(void);
-
-
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/ide.c linux-2.4.22-pre10/arch/cris/drivers/ide.c
--- linux-2.4.21/arch/cris/drivers/ide.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/ide.c	2003-08-01 13:31:53.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: ide.c,v 1.26 2002/09/17 12:16:59 bjornw Exp $
+/* $Id: ide.c,v 1.30 2003/07/08 07:24:47 pkj Exp $
  *
  * Etrax specific IDE functions, like init and PIO-mode setting etc.
  * Almost the entire ide.c is used for the rest of the Etrax ATA driver.
@@ -8,6 +8,19 @@
  *             Mikael Starvik     (pio setup stuff)
  *
  * $Log: ide.c,v $
+ * Revision 1.30  2003/07/08 07:24:47  pkj
+ * Corrected spelling mistakes originally found in 2.5.x
+ *
+ * Revision 1.29  2003/06/17 13:57:49  starvik
+ * Merge of Linux 2.4.21
+ *
+ * Revision 1.28  2003/01/22 12:41:12  starvik
+ * Added LBA48 support
+ * Fixed typo in e100_ideproc
+ *
+ * Revision 1.27  2003/01/09 18:03:47  starvik
+ * init_ioremap is now called by kernel before device drivers are initialized
+ *
  * Revision 1.26  2002/09/17 12:16:59  bjornw
  * Removed unnecessary cli/sti pair
  *
@@ -151,6 +164,8 @@
 static volatile unsigned long *reset_addr;
 #endif
 
+static int e100_read_command = 0;
+
 #define LOWDB(x)
 #define D(x) 
 
@@ -186,14 +201,9 @@
 			    IO_MASK(R_ATA_STATUS_DATA, tr_rdy)))
 		timeleft--;
 }
-unsigned char 
-IN_BYTE(ide_ioreg_t reg) {
-        /* data was in the lower 16 bits in the status reg */
-        return (unsigned char)(IN_WORD(reg));
-}
 
 unsigned short 
-IN_WORD(ide_ioreg_t reg) {
+IN_BYTE(ide_ioreg_t reg) {
 	int status;
 	int timeleft;
 
@@ -237,7 +247,7 @@
 
 	LOWDB(printk("inb: 0x%x from reg 0x%x\n", status & 0xff, reg));
 
-        return (unsigned short)status;
+        return (unsigned char)status;
 }
 
 /* PIO timing (in R_ATA_CONFIG)
@@ -292,9 +302,15 @@
 #define ATA_PIO0_STROBE 19
 #define ATA_PIO0_HOLD    4
 
-static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive);
-static void e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
-			  void *buffer, unsigned int length);
+static int e100_dma_check (ide_drive_t *drive);
+static int e100_dma_begin (ide_drive_t *drive);
+static int e100_dma_end (ide_drive_t *drive);
+static int e100_dma_read (ide_drive_t *drive);
+static int e100_dma_write (ide_drive_t *drive);
+static void e100_ide_input_data (ide_drive_t *drive, void *, unsigned int);
+static void e100_ide_output_data (ide_drive_t *drive, void *, unsigned int);
+static void e100_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
+static void e100_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
 
 /*
  * good_dma_drives() lists the model names (from "hdparm -i")
@@ -309,8 +325,6 @@
 
 static void tune_e100_ide(ide_drive_t *drive, byte pio)
 {
-	unsigned long flags;
-	
 	pio = 4;
 	/* pio = ide_get_best_pio_mode(drive, pio, 4, NULL); */
 	
@@ -374,8 +388,15 @@
 		ide_hwif_t *hwif = &ide_hwifs[h];
 		hwif->chipset = ide_etrax100;
 		hwif->tuneproc = &tune_e100_ide;
-		hwif->dmaproc = &e100_dmaproc;
-		hwif->ideproc = &e100_ideproc;
+                hwif->ata_input_data = &e100_ide_input_data;
+                hwif->ata_output_data = &e100_ide_output_data;
+                hwif->atapi_input_bytes = &e100_atapi_input_bytes;
+                hwif->atapi_output_bytes = &e100_atapi_output_bytes;
+                hwif->ide_dma_check = &e100_dma_check;
+                hwif->ide_dma_end = &e100_dma_end;
+		hwif->ide_dma_write = &e100_dma_write;
+		hwif->ide_dma_read = &e100_dma_read;
+		hwif->ide_dma_begin = &e100_dma_begin;
 	}
 
 	/* actually reset and configure the etrax100 ide/ata interface */
@@ -400,11 +421,9 @@
         REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 27, 0);
 #endif 
 #ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
-        init_ioremap();
         REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, 0);
 #endif
 #ifdef CONFIG_ETRAX_IDE_CSP0_8_RESET
-        init_ioremap();
         REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, 0);
 #endif
 #ifdef CONFIG_ETRAX_IDE_PB7_RESET  
@@ -618,7 +637,7 @@
         LED_DISK_WRITE(1);
         
         /* Etrax will set busy = 1 until the multi pio transfer has finished
-         * and tr_rdy = 1 after each succesful word transfer. 
+         * and tr_rdy = 1 after each successful word transfer.
          * When the last byte has been transferred Etrax will first set tr_tdy = 1 
          * and then busy = 0 (not in the same cycle). If we read busy before it
          * has been set to 0 we will think that we should transfer more bytes 
@@ -655,32 +674,6 @@
 	e100_atapi_output_bytes(drive, buffer, wcount << 2);
 }
 
-/*
- * The multiplexor for ide_xxxput_data and atapi calls
- */
-static void 
-e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
-	      void *buffer, unsigned int length)
-{
-	switch (func) {
-		case ideproc_ide_input_data:
-			e100_ide_input_data(drive, buffer, length);
-			break;
-		case ideproc_ide_output_data:
-			e100_ide_input_data(drive, buffer, length);
-			break;
-		case ideproc_atapi_input_bytes:
-			e100_atapi_input_bytes(drive, buffer, length);
-			break;
-		case ideproc_atapi_output_bytes:
-			e100_atapi_output_bytes(drive, buffer, length);
-			break;
-		default:
-			printk("e100_ideproc: unsupported func %d!\n", func);
-			break;
-	}
-}
-
 /* we only have one DMA channel on the chip for ATA, so we can keep these statically */
 static etrax_dma_descr ata_descrs[MAX_DMA_DESCRS];
 static unsigned int ata_tot_size;
@@ -815,8 +808,8 @@
 	LED_DISK_READ(0);
 	LED_DISK_WRITE(0);
 
-	dma_stat = HWIF(drive)->dmaproc(ide_dma_end, drive);
-	stat = GET_STAT();			/* get drive status */
+	dma_stat = HWIF(drive)->ide_dma_end(drive);
+	stat = HWIF(drive)->INB(IDE_STATUS_REG);		/* get drive status */
 	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
 		if (!dma_stat) {
 			struct request *rq;
@@ -833,7 +826,7 @@
 }
 
 /*
- * e100_dmaproc() initiates/aborts DMA read/write operations on a drive.
+ * Functions below initiates/aborts DMA read/write operations on a drive.
  *
  * The caller is assumed to have selected the drive and programmed the drive's
  * sector address using CHS or LBA.  All that remains is to prepare for DMA
@@ -848,59 +841,19 @@
  * the caller should revert to PIO for the current request.
  */
 
-static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+static int e100_dma_check(ide_drive_t *drive)
 {
-        static unsigned int reading; /* static to support ide_dma_begin semantics */
-	int atapi = 0;
-
-	D(printk("e100_dmaproc func %d\n", func));
-
-        switch (func) {
-		case ide_dma_verbose:
-			return 0;
-                case ide_dma_check:
-                        return config_drive_for_dma (drive);
-		case ide_dma_off:
-		case ide_dma_off_quietly:
-			/* ok.. we don't really need to do anything I think. */
-			return 0;
-                case ide_dma_write:
-                        reading = 0;
-			break;
-                case ide_dma_read:
-			reading = 1;
-                        break;
-                case ide_dma_begin:
-			/* begin DMA, used by ATAPI devices which want to issue the 
-			 * appropriate IDE command themselves.
-			 *
-			 * they have already called ide_dma_read/write to set the
-			 * static reading flag, now they call ide_dma_begin to do
-			 * the real stuff. we tell our code below not to issue
-			 * any IDE commands itself and jump into it. 
-			 */
-			atapi++;
-			goto dma_begin;
-		case ide_dma_end: /* returns 1 on error, 0 otherwise */
-			/* TODO: check if something went wrong with the DMA */
-			return 0;
-
-                default:
-                        printk("e100_dmaproc: unsupported func %d\n", func);
-                        return 1;
-        }
-
-	/* ATAPI-devices (not disks) first call ide_dma_read/write to set the direction
-	 * then they call ide_dma_begin after they have issued the appropriate drive command
-	 * themselves to actually start the chipset DMA. so we just return here if we're
-	 * not a diskdrive.
-	 */
-
-        if (drive->media != ide_disk)
-                return 0;
+	return config_drive_for_dma (drive);
+}
 
- dma_begin:
+static int e100_dma_end(ide_drive_t *drive)
+{
+	/* TODO: check if something went wrong with the DMA */
+	return 0;
+}
 
+static int e100_start_dma(ide_drive_t *drive, int atapi, int reading)
+{
 	if(reading) {
 
 		RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
@@ -917,8 +870,15 @@
 			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
 			
 			/* issue cmd to drive */
-			
-			OUT_BYTE(WIN_READDMA, IDE_COMMAND_REG);
+                        if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) &&
+			    (drive->addressing == 1)) {
+				ide_task_t *args = HWGROUP(drive)->rq->special;
+				OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+			} else if (drive->addressing) {
+				OUT_BYTE(WIN_READDMA_EXT, IDE_COMMAND_REG);
+			} else {
+				OUT_BYTE(WIN_READDMA, IDE_COMMAND_REG);
+			}
 		}
 
 		/* begin DMA */
@@ -968,8 +928,15 @@
 			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
 			
 			/* issue cmd to drive */
-			
-			OUT_BYTE(WIN_WRITEDMA, IDE_COMMAND_REG);
+			if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) &&
+			    (drive->addressing == 1)) {
+				ide_task_t *args = HWGROUP(drive)->rq->special;
+				OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+			} else if (drive->addressing) {
+				OUT_BYTE(WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
+			} else {
+				OUT_BYTE(WIN_WRITEDMA, IDE_COMMAND_REG);
+			}
 		}
 
 		/* begin DMA */
@@ -994,14 +961,44 @@
 
 		D(printk("dma write of %d bytes.\n", ata_tot_size));
 	}
-
-	/* DMA started successfully */
 	return 0;
 }
 
-/* ide.c calls this, but we don't need to do anything particular */
+static int e100_dma_write(ide_drive_t *drive)
+{
+	e100_read_command = 0;
+	/* ATAPI-devices (not disks) first call ide_dma_read/write to set the direction
+	 * then they call ide_dma_begin after they have issued the appropriate drive command
+	 * themselves to actually start the chipset DMA. so we just return here if we're
+	 * not a diskdrive.
+	 */
+	if (drive->media != ide_disk)
+                return 0;
+	return e100_start_dma(drive, 0, 0);
+}
+
+static int e100_dma_read(ide_drive_t *drive)
+{
+	e100_read_command = 1;
+	/* ATAPI-devices (not disks) first call ide_dma_read/write to set the direction
+	 * then they call ide_dma_begin after they have issued the appropriate drive command
+	 * themselves to actually start the chipset DMA. so we just return here if we're
+	 * not a diskdrive.
+	 */
+	if (drive->media != ide_disk)
+                return 0;
+	return e100_start_dma(drive, 0, 1);
+}
 
-int ide_release_dma (ide_hwif_t *hwif)
+static int e100_dma_begin(ide_drive_t *drive)
 {
-	return 1;
+	/* begin DMA, used by ATAPI devices which want to issue the 
+	 * appropriate IDE command themselves.
+	 *
+	 * they have already called ide_dma_read/write to set the
+	 * static reading flag, now they call ide_dma_begin to do
+	 * the real stuff. we tell our code below not to issue
+	 * any IDE commands itself and jump into it. 
+	 */
+	 return e100_start_dma(drive, 1, e100_read_command);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/lpslave/bintocarr.pl linux-2.4.22-pre10/arch/cris/drivers/lpslave/bintocarr.pl
--- linux-2.4.21/arch/cris/drivers/lpslave/bintocarr.pl	2001-10-08 18:43:54.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/lpslave/bintocarr.pl	2003-08-01 13:32:06.000000000 +0000
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
-# $Id: bintocarr.pl,v 1.4 2001/08/08 08:18:13 bjarne Exp $
+
 # Copy of mkjulbin.pl made by Olof
 # convert a binary stdin to a C-file containing a char array of the input
 # first argument is the symbol name
@@ -27,4 +27,3 @@
 $lensymb = ("_" . ($symbol . "_length"));
 
 print "__asm__(\"\\t.globl $lensymb\\n$lensymb = $bcount\\n\");\n";
-  
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/lpslave/e100lpslave.S linux-2.4.22-pre10/arch/cris/drivers/lpslave/e100lpslave.S
--- linux-2.4.21/arch/cris/drivers/lpslave/e100lpslave.S	2001-07-26 22:10:06.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/lpslave/e100lpslave.S	2003-08-01 13:32:18.000000000 +0000
@@ -1,12 +1,11 @@
-	;; $Id: e100lpslave.S,v 1.3 2001/06/21 16:55:26 olof Exp $
-	;;
-	;; Etrax100 slave network<->parport forwarder
-	;;
-	;; Copyright (c) 1999 Bjorn Wesen, Axis Communications AB
-	;;
-	;; We got 784 bytes (par loader size) to do DMA forwarding
-	;; between DMA0/1 (ethernet) and DMA3/4 (par port 0 RX/1 TX)
-	;;
+;;
+;; Etrax100 slave network<->parport forwarder
+;;
+;; Copyright (c) 1999, 2000, 2001, 2002, 2003 Axis Communications AB
+;;
+;; We got 784 bytes (par loader size) to do DMA forwarding
+;; between DMA0/1 (ethernet) and DMA3/4 (par port 0 RX/1 TX)
+;;
 
 #include <linux/config.h>
 #if 0
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/parport.c linux-2.4.22-pre10/arch/cris/drivers/parport.c
--- linux-2.4.21/arch/cris/drivers/parport.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/parport.c	2003-08-01 13:30:54.000000000 +0000
@@ -1,13 +1,13 @@
-/* $Id: parport.c,v 1.10 2002/10/03 05:54:24 starvik Exp $
- * 
- * Elinux parallel port driver
+/*
+ * Parallel port driver for ETRAX.
+ *
  * NOTE!
  *   Since par0 shares DMA with ser2 and par 1 shares DMA with ser3
  *   this should be handled if both are enabled at the same time.
  *   THIS IS NOT HANDLED YET!
  *
- * Copyright (c) 2001 Axis Communications AB
- * 
+ * Copyright (c) 2001, 2002, 2003 Axis Communications AB
+ *
  * Author: Fredrik Hugosson
  *
  */
@@ -406,7 +406,7 @@
 static void __init
 parport_etrax_show_parallel_version(void)
 {
-	printk("ETRAX 100LX parallel port driver v1.0, (c) 2001 Axis Communications AB\n");
+	printk("ETRAX 100LX parallel port driver v1.0, (c) 2001-2003 Axis Communications AB\n");
 }
 
 #ifdef CONFIG_ETRAX_PAR0_DMA
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/pcf8563.c linux-2.4.22-pre10/arch/cris/drivers/pcf8563.c
--- linux-2.4.21/arch/cris/drivers/pcf8563.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/pcf8563.c	2003-08-01 13:33:20.000000000 +0000
@@ -8,14 +8,13 @@
  * low detector are also provided. All address and data are transferred
  * serially via two-line bidirectional I2C-bus. Maximum bus speed is
  * 400 kbits/s. The built-in word address register is incremented
- * automatically after each written or read bute.
+ * automatically after each written or read byte.
  *
- * Copyright (c) 2002, Axis Communications AB
+ * Copyright (c) 2002-2003, Axis Communications AB
  * All rights reserved.
  *
  * Author: Tobias Anderberg <tobiasa@axis.com>.
  *
- * $Id: pcf8563.c,v 1.4 2002/10/15 09:22:42 tobiasa Exp $
  */
 
 #include <linux/config.h>
@@ -36,19 +35,15 @@
 #include <asm/rtc.h>
 #include "i2c.h"
 
-#define PCF8563_MAJOR 121		/* Local major number. */
-#define DEVICE_NAME "rtc"		/* Name which is registered in /proc/devices. */
-#define PCF8563_NAME "PCF8563"
-#define DRIVER_VERSION "$Revision: 1.4 $"
-
-/* I2C bus slave registers. */
-#define RTC_I2C_READ		0xa3
-#define RTC_I2C_WRITE		0xa2
+#define PCF8563_MAJOR	121	/* Local major number. */
+#define DEVICE_NAME	"rtc"	/* Name which is registered in /proc/devices. */
+#define PCF8563_NAME	"PCF8563"
+#define DRIVER_VERSION	"$Revision: 1.15 $"
 
 /* Two simple wrapper macros, saves a few keystrokes. */
 #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
 #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
-	
+
 static const unsigned char days_in_month[] =
 	{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
 
@@ -64,53 +59,73 @@
 };
 
 unsigned char
-pcf8563_readreg(int reg) 
+pcf8563_readreg(int reg)
 {
-	unsigned char res = i2c_readreg(RTC_I2C_READ, reg);
+	unsigned char res = rtc_read(reg);
 
 	/* The PCF8563 does not return 0 for unimplemented bits */
-	switch(reg)
-	{
+	switch (reg) {
 		case RTC_SECONDS:
 		case RTC_MINUTES:
-		     res &= 0x7f;
-		     break;
+			res &= 0x7F;
+			break;
 		case RTC_HOURS:
 		case RTC_DAY_OF_MONTH:
-		     res &= 0x3f;
-		     break;
+			res &= 0x3F;
+			break;
+		case RTC_WEEKDAY:
+			res &= 0x07;
+			break;
 		case RTC_MONTH:
-		     res = (res & 0x1f) - 1;  /* PCF8563 returns month in range 1-12 */
-		     break;
+			res &= 0x1F;
+			break;
+		case RTC_CONTROL1:
+			res &= 0xA8;
+			break;
+		case RTC_CONTROL2:
+			res &= 0x1F;
+			break;
+		case RTC_CLOCKOUT_FREQ:
+		case RTC_TIMER_CONTROL:
+			res &= 0x83;
+			break;
 	}
 	return res;
 }
 
 void
-pcf8563_writereg(int reg, unsigned char val) 
+pcf8563_writereg(int reg, unsigned char val)
 {
-	i2c_writereg(RTC_I2C_WRITE,reg,val);
+#ifdef CONFIG_ETRAX_RTC_READONLY
+	if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR))
+		return;
+#endif
+
+	rtc_write(reg, val);
 }
 
 void
 get_rtc_time(struct rtc_time *tm)
 {
-	tm->tm_sec = rtc_read(RTC_SECONDS);
-	tm->tm_min = rtc_read(RTC_MINUTES);
+	tm->tm_sec  = rtc_read(RTC_SECONDS);
+	tm->tm_min  = rtc_read(RTC_MINUTES);
 	tm->tm_hour = rtc_read(RTC_HOURS);
 	tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH);
-	tm->tm_mon = rtc_read(RTC_MONTH);
+	tm->tm_wday = rtc_read(RTC_WEEKDAY);
+	tm->tm_mon  = rtc_read(RTC_MONTH);
 	tm->tm_year = rtc_read(RTC_YEAR);
 
 	if (tm->tm_sec & 0x80)
-		printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
+		printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
+		       "information is no longer guaranteed!\n", PCF8563_NAME);
 
-	tm->tm_year = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0);
-	tm->tm_sec &= 0x7f;
-	tm->tm_min &= 0x7f;
-	tm->tm_hour &= 0x3f;
-	tm->tm_mday &= 0x3f;
-	tm->tm_mon &= 0x1f;
+	tm->tm_year  = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0);
+	tm->tm_sec  &= 0x7F;
+	tm->tm_min  &= 0x7F;
+	tm->tm_hour &= 0x3F;
+	tm->tm_mday &= 0x3F;
+	tm->tm_wday &= 0x07; /* Not coded in BCD. */
+	tm->tm_mon  &= 0x1F;
 
 	BCD_TO_BIN(tm->tm_sec);
 	BCD_TO_BIN(tm->tm_min);
@@ -124,10 +139,14 @@
 pcf8563_init(void)
 {
 	unsigned char ret;
+
+	/* Initiate the i2c protocol. */
+	i2c_init();
+
 	/*
 	 * First of all we need to reset the chip. This is done by
-	 * clearing control1, control2 and clk freq, clear the 
-	 * Voltage Low bit, and resetting all alarms.
+	 * clearing control1, control2 and clk freq and resetting
+	 * all alarms.
 	 */
 	if (rtc_write(RTC_CONTROL1, 0x00) < 0)
 		goto err;
@@ -138,37 +157,35 @@
 	if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
 		goto err;
 
-	/* Clear the VL bit in the seconds register. */
-	ret = rtc_read(RTC_SECONDS);
-	
-	if (rtc_write(RTC_SECONDS, (ret & 0x7f)) < 0)
+	if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0)
 		goto err;
-		
+
 	/* Reset the alarms. */
-	if (rtc_write(RTC_MINUTE_ALARM, 0x00) < 0)
+	if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0)
 		goto err;
-	
-	if (rtc_write(RTC_HOUR_ALARM, 0x00) < 0)
+
+	if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0)
 		goto err;
-	
-	if (rtc_write(RTC_DAY_ALARM, 0x00) < 0)
+
+	if (rtc_write(RTC_DAY_ALARM, 0x80) < 0)
 		goto err;
-	
-	if (rtc_write(RTC_WEEKDAY_ALARM, 0x00) < 0)
+
+	if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0)
 		goto err;
 
 	if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
-		printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n", 
+		printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n",
 		       PCF8563_NAME, PCF8563_MAJOR);
 		return -1;
 	}
 
 	printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
-        
+
 	/* Check for low voltage, and warn about it.. */
 	if (rtc_read(RTC_SECONDS) & 0x80)
-		printk(KERN_WARNING "%s: RTC Low Voltage - date/time is not reliable!\n", PCF8563_NAME);
-	
+		printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
+		       "information is no longer guaranteed!\n", PCF8563_NAME);
+
 	return 0;
 
 err:
@@ -200,75 +217,113 @@
 
 	switch (cmd) {
 		case RTC_RD_TIME:
-			{
-				struct rtc_time tm;
+		{
+			struct rtc_time tm;
 
-				get_rtc_time(&tm);
+			get_rtc_time(&tm);
 
-				if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) {
-					return -EFAULT;
-				}
-
-				return 0;
+			if (copy_to_user((struct rtc_time *) arg, &tm, sizeof tm)) {
+				return -EFAULT;
 			}
-			break;
-		case RTC_SET_TIME:
-			{
-				int leap;
-				int century;
-				unsigned long flags;
-				struct rtc_time tm;
-
-				if (!capable(CAP_SYS_TIME))
-					return -EPERM;
-
-				if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time)))
-					return -EFAULT;
-
-				/* Convert from struct tm to struct rtc_time. */
-				tm.tm_year += 1900;
-				tm.tm_mon += 1;
-				
-				leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0;
-
-				/* Perform some sanity checks. */
-				if ((tm.tm_year < 1970) ||
-				    (tm.tm_mon > 12) ||
-				    (tm.tm_mday == 0) ||
-				    (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
-				    (tm.tm_hour >= 24) ||
-				    (tm.tm_min >= 60) ||
-				    (tm.tm_sec >= 60))
-					return -EINVAL;
-
-				century = (tm.tm_year >= 2000) ? 0x80 : 0;
-				tm.tm_year = tm.tm_year % 100;
-
-				BIN_TO_BCD(tm.tm_year);
-				BIN_TO_BCD(tm.tm_mday);
-				BIN_TO_BCD(tm.tm_hour);
-				BIN_TO_BCD(tm.tm_min);
-				BIN_TO_BCD(tm.tm_sec);
-				tm.tm_mon |= century;
-				
-				rtc_write(RTC_YEAR, tm.tm_year);
-				rtc_write(RTC_MONTH, tm.tm_mon);
-				rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
-				rtc_write(RTC_HOURS, tm.tm_hour);
-				rtc_write(RTC_MINUTES, tm.tm_min);
-				rtc_write(RTC_SECONDS, tm.tm_sec);
 
-				return 0;
+			return 0;
+		}
+
+		case RTC_SET_TIME:
+		{
+#ifdef CONFIG_ETRAX_RTC_READONLY
+			return -EPERM;
+#else
+			int leap;
+			int year;
+			int century;
+			struct rtc_time tm;
+
+			if (!capable(CAP_SYS_TIME))
+				return -EPERM;
+
+			if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm))
+				return -EFAULT;
+
+			/* Convert from struct tm to struct rtc_time. */
+			tm.tm_year += 1900;
+			tm.tm_mon += 1;
+
+			/*
+			 * Check if tm.tm_year is a leap year. A year is a leap
+			 * year if it is divisible by 4 but not 100, except
+			 * that years divisible by 400 _are_ leap years.
+			 */
+			year = tm.tm_year;
+			leap = (tm.tm_mon == 2) && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
+
+			/* Perform some sanity checks. */
+			if ((tm.tm_year < 1970) ||
+			    (tm.tm_mon > 12) ||
+			    (tm.tm_mday == 0) ||
+			    (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
+			    (tm.tm_wday >= 7) ||
+			    (tm.tm_hour >= 24) ||
+			    (tm.tm_min >= 60) ||
+			    (tm.tm_sec >= 60))
+				return -EINVAL;
+
+			century = (tm.tm_year >= 2000) ? 0x80 : 0;
+			tm.tm_year = tm.tm_year % 100;
+
+			BIN_TO_BCD(tm.tm_year);
+			BIN_TO_BCD(tm.tm_mday);
+			BIN_TO_BCD(tm.tm_hour);
+			BIN_TO_BCD(tm.tm_min);
+			BIN_TO_BCD(tm.tm_sec);
+			tm.tm_mon |= century;
+
+			rtc_write(RTC_YEAR, tm.tm_year);
+			rtc_write(RTC_MONTH, tm.tm_mon);
+			rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
+			rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
+			rtc_write(RTC_HOURS, tm.tm_hour);
+			rtc_write(RTC_MINUTES, tm.tm_min);
+			rtc_write(RTC_SECONDS, tm.tm_sec);
+
+			return 0;
+#endif /* !CONFIG_ETRAX_RTC_READONLY */
+		}
+
+		case RTC_VLOW_RD:
+		{
+			int vl_bit = 0;
+
+			if (rtc_read(RTC_SECONDS) & 0x80) {
+				vl_bit = 1;
+				printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
+				       "date/time information is no longer guaranteed!\n",
+				       PCF8563_NAME);
 			}
-			break;
+			if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
+				return -EFAULT;
+
+			return 0;
+		}
+
+		case RTC_VLOW_SET:
+		{
+			/* Clear the VL bit in the seconds register */
+			int ret = rtc_read(RTC_SECONDS);
+
+			rtc_write(RTC_SECONDS, (ret & 0x7F));
+
+			return 0;
+		}
+
 		default:
-				return -ENOTTY;
+			return -ENOTTY;
 	}
 
 	return 0;
 }
 
-int 
+int
 pcf8563_open(struct inode *inode, struct file *filp)
 {
 	MOD_INC_USE_COUNT;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/serial.c linux-2.4.22-pre10/arch/cris/drivers/serial.c
--- linux-2.4.21/arch/cris/drivers/serial.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/serial.c	2003-08-01 13:31:14.000000000 +0000
@@ -1,12 +1,92 @@
-/* $Id: serial.c,v 1.44 2002/11/21 04:28:06 hp Exp $
+/* $Id: serial.c,v 1.54 2003/07/08 12:42:19 johana Exp $
  *
  * Serial port driver for the ETRAX 100LX chip
  *
- *      Copyright (C) 1998, 1999, 2000, 2001, 2002  Axis Communications AB
+ *    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003  Axis Communications AB
  *
- *      Many, many authors. Based once upon a time on serial.c for 16x50.
+ *    Many, many authors. Based once upon a time on serial.c for 16x50.
  *
  * $Log: serial.c,v $
+ * Revision 1.54  2003/07/08 12:42:19  johana
+ * Removed some test defines within #if 0.
+ * Moved a comment to correct place.
+ *
+ * Revision 1.53  2003/07/08 09:48:28  starvik
+ * Removed test code
+ *
+ * Revision 1.52  2003/07/08 07:24:47  pkj
+ * Corrected spelling mistakes originally found in 2.5.x
+ *
+ * Revision 1.51  2003/07/07 09:17:12  johana
+ * Config.in:
+ * Don't consider ETRAX_FAST_TIMER experimental.
+ * Add CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED
+ * Add CONFIG_ETRAX_EXTERN_PB6CLK_FREQ
+ * Add CONFIG_ETRAX_SERIAL_PORTx_DMAy_OUT/IN
+ *
+ * serial.h:
+ * Support for with and without DMA.
+ * Added baud_base and custom_divisor for flexible baudrate.
+ * Added flush_time_usec.
+ * Removed unused DMA register pointers.
+ *
+ * serial.c:
+ * Use C99 style initialisation of rs_table, some fields added, some removed.
+ * Always disable interrupts when fiddling with shadow variables.
+ * Support for flexible baudrate using prescaler or external clock.
+ * Only disable the DMA channel if we own it.
+ * Support for either using DMA or char-by-char interrupt.
+ *
+ * DMA changes:
+ * o When transmitting with DMA, don't put all in one descriptor, split
+ *   it so that we can wake up the application before everything is sent.
+ * o When starting a fast timer to flip later, use a longer, fixed time.
+ * o Use flush_time_usec and have a minimum value to prevent excessive load
+ *   on high baudrates.
+ * o Do force_eop_if_needed() after processing to reduce load.
+ * o All DMA interrupts uses SA_SHIRQ | SA_INTERRUPT
+ *
+ * Only have interrupts disabled while processing rx interrupts,
+ * unmask just tx interrupts and unblock serial interrupt and keep
+ * global interrupts enabled while processing tx interrupts to make
+ * char-by-char interrupts usable.
+ *
+ * Flow control:
+ * o Use normal tx interrupt when sending x_char.
+ * o Use throttling within the driver when using DMA.
+ *
+ * Improved debugging with DEBUG_LOG macro.
+ *
+ * Revision 1.50  2003/06/13 10:04:12  johana
+ * Help the user to avoid trouble by:
+ * Preventing FAST_TIMER and FAST_DMA_FLUSH at the same time.
+ * Forcing mixed mode for status/control lines if not all pins are used.
+ *
+ * Som minor changes to reduce diff to os/lx25 version.
+ *
+ * Revision 1.49  2003/05/30 11:31:54  johana
+ * Merged in change-branch--serial9bit that adds CMSPAR support for sticky
+ * parity (mark/space)
+ *
+ * Revision 1.48  2003/05/30 11:03:57  johana
+ * Implemented rs_send_xchar() by disabling the DMA and writing manually.
+ * Added e100_disable_txdma_channel() and e100_enable_txdma_channel().
+ * Fixed rs_throttle() and rs_unthrottle() to properly call rs_send_xchar
+ * instead of setting info->x_char and check the CRTSCTS flag before
+ * controlling the rts pin.
+ *
+ * Revision 1.47  2003/04/09 08:31:14  pkj
+ * Typo correction (taken from Linux 2.5).
+ *
+ * Revision 1.46  2003/04/01 14:12:06  starvik
+ * Added loglevel for lots of printks
+ *
+ * Revision 1.45  2003/01/22 06:54:46  starvik
+ * Fixed warnings issued by GCC 3.2.1
+ *
+ * Revision 1.44.4.1  2003/01/08 06:47:12  starvik
+ * Added mark/space parity (for 9-bit serial)
+ *
  * Revision 1.44  2002/11/21 04:28:06  hp
  * Change static inline to extern inline where otherwise outlined with gcc-3.2
  *
@@ -206,7 +286,7 @@
  *   Items worth noticing:
  *
  *      No Etrax100 port 1 workarounds (does only compile on 2.4 anyway now)
- *      RS485 is not ported (why cant it be done in userspace as on x86 ?)
+ *      RS485 is not ported (why can't it be done in userspace as on x86 ?)
  *      Statistics done through async_icount - if any more stats are needed,
  *      that's the place to put them or in an arch-dep version of it.
  *      timeout_interrupt and the other fast timeout stuff not ported yet
@@ -357,7 +437,7 @@
  *
  */
 
-static char *serial_version = "$Revision: 1.44 $";
+static char *serial_version = "$Revision: 1.54 $";
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -392,7 +472,7 @@
 
 #include <asm/svinto.h>
 
-/* non-arch dependant serial structures are in linux/serial.h */
+/* non-arch dependent serial structures are in linux/serial.h */
 #include <linux/serial.h>
 /* while we keep our own stuff (struct e100_serial) in a local .h file */
 #include "serial.h"
@@ -406,6 +486,11 @@
 #error "Enable FAST_TIMER to use SERIAL_FAST_TIMER"
 #endif
 #endif
+
+#if defined(CONFIG_ETRAX_FAST_TIMER) && defined(CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST)
+#error "Disable either ETRAX_SERIAL_FLUSH_DMA_FAST or ETRAX_FAST_TIMER"
+#endif
+
 /*
  * All of the compatibilty code so we can compile serial.c against
  * older kernels is hidden in serial_compat.h
@@ -414,8 +499,11 @@
 #include "serial_compat.h"
 #endif
 
+#if 1 /* Set to 0 to avoid inlining - easier to see how size of parts */
 #define _INLINE_ inline
-
+#else
+#define _INLINE_
+#endif
 static DECLARE_TASK_QUEUE(tq_serial);
 
 struct tty_driver serial_driver, callout_driver;
@@ -436,7 +524,7 @@
 //#define SERIAL_DEBUG_DATA
 //#define SERIAL_DEBUG_THROTTLE
 //#define SERIAL_DEBUG_IO  /* Debug for Extra control and status pins */
-#define SERIAL_DEBUG_LINE 0 /* What serport we want to debug */
+#define SERIAL_DEBUG_LINE 3 /* What serport we want to debug */
 
 /* Enable this to use serial interrupts to handle when you
    expect the first received event on the serial port to
@@ -444,14 +532,78 @@
    from eLinux */
 #define SERIAL_HANDLE_EARLY_ERRORS
 
-#define TTY_THROTTLE_LIMIT (TTY_FLIPBUF_SIZE/10)
+/* Defined and used in n_tty.c, but we need it here as well */
+#define TTY_THRESHOLD_THROTTLE 128
 
+/* Due to buffersizes and threshold values, our SERIAL_DESCR_BUF_SIZE
+ * must not be to high or flow control won't work if we leave it to the tty
+ * layer so we have our own throttling in flush_to_flip
+ * TTY_FLIPBUF_SIZE=512,
+ * TTY_THRESHOLD_THROTTLE/UNTHROTTLE=128
+ * BUF_SIZE can't be > 128
+ */
+/* Currently 16 descriptors x 128 bytes = 2048 bytes */
 #define SERIAL_DESCR_BUF_SIZE 256
 
+#define SERIAL_PRESCALE_BASE 3125000 /* 3.125MHz */
+#define DEF_BAUD_BASE SERIAL_PRESCALE_BASE
+
+/* We don't want to load the system with massive fast timer interrupt
+ * on high baudrates so limit it to 250 us (4kHz) */
+#define MIN_FLUSH_TIME_USEC 250
+
 /* Add an x here to log a lot of timer stuff */
 #define TIMERD(x)
+/* Debug details of interrupt handling */
+#define DINTR1(x)  /* irq on/off, errors */
+#define DINTR2(x)    /* tx and rx */
+/* Debug flip buffer stuff */
+#define DFLIP(x)
+/* Debug flow control and overview of data flow */
+#define DFLOW(x)
+#define DBAUD(x)
+#ifdef CONFIG_ETRAX_DEBUG_INTERRUPT
+#define DLOG_INT_TRIG(x) 
+#else
+#define DLOG_INT_TRIG(x)
+#endif
 
+//#define DEBUG_LOG_INCLUDED
+#ifndef DEBUG_LOG_INCLUDED
 #define DEBUG_LOG(line, string, value)
+#else
+struct debug_log_info 
+{
+	unsigned long time;
+	unsigned long timer_data;
+//  int line;
+	const char *string;
+	int value;
+};
+#define DEBUG_LOG_SIZE 4096
+
+struct debug_log_info debug_log[DEBUG_LOG_SIZE];
+int debug_log_pos = 0;
+  
+#define DEBUG_LOG(_line, _string, _value) do { \
+  if ((_line) == SERIAL_DEBUG_LINE) {\
+    debug_log_func(_line, _string, _value); \
+  }\
+}while(0)
+
+void debug_log_func(int line, const char *string, int value)
+{
+	if (debug_log_pos < DEBUG_LOG_SIZE) { 
+		debug_log[debug_log_pos].time = jiffies;
+		debug_log[debug_log_pos].timer_data = *R_TIMER_DATA;
+//    debug_log[debug_log_pos].line = line;
+		debug_log[debug_log_pos].string = string;
+		debug_log[debug_log_pos].value = value;
+		debug_log_pos++; 
+	}
+	/*printk(string, value);*/
+} 
+#endif
 
 #ifndef CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS
 /* Default number of timer ticks before flushing rx fifo 
@@ -461,21 +613,23 @@
 #define CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS 5 
 #endif
 
+unsigned long timer_data_to_ns(unsigned long timer_data);
+
 static void change_speed(struct e100_serial *info);
+static void rs_throttle(struct tty_struct * tty);
 static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
 static int rs_write(struct tty_struct * tty, int from_user,
                     const unsigned char *buf, int count);
-extern inline int raw_write(struct tty_struct * tty, int from_user,
+extern _INLINE_ int rs_raw_write(struct tty_struct * tty, int from_user,
                             const unsigned char *buf, int count);
 #ifdef CONFIG_ETRAX_RS485
 static int e100_write_rs485(struct tty_struct * tty, int from_user,
                             const unsigned char *buf, int count);
 #endif
-static int 
-get_lsr_info(struct e100_serial * info, unsigned int *value);
+static int get_lsr_info(struct e100_serial * info, unsigned int *value);
 
 
-#define DEF_BAUD 0x99   /* 115.2 kbit/s */
+#define DEF_BAUD 115200   /* 115.2 kbit/s */
 #define STD_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
 #define DEF_RX 0x20  /* or SERIAL_CTRL_W >> 8 */
 /* Default value of tx_ctrl register: has txd(bit 7)=1 (idle) as default */
@@ -484,6 +638,7 @@
 /* offsets from R_SERIALx_CTRL */
 
 #define REG_DATA 0
+#define REG_DATA_STATUS32 0 /* this is the 32 bit register R_SERIALx_READ */
 #define REG_TR_DATA 0
 #define REG_STATUS 1
 #define REG_TR_CTRL 1
@@ -519,60 +674,162 @@
  */
 
 
+/* Mask for the irqs possibly enabled in R_IRQ_MASK1_RD etc. */
+static const unsigned long e100_ser_int_mask = 0
+#ifdef CONFIG_ETRAX_SERIAL_PORT0
+| IO_MASK(R_IRQ_MASK1_RD, ser0_data) | IO_MASK(R_IRQ_MASK1_RD, ser0_ready)
+#endif
+#ifdef CONFIG_ETRAX_SERIAL_PORT1
+| IO_MASK(R_IRQ_MASK1_RD, ser1_data) | IO_MASK(R_IRQ_MASK1_RD, ser1_ready)
+#endif
+#ifdef CONFIG_ETRAX_SERIAL_PORT2
+| IO_MASK(R_IRQ_MASK1_RD, ser2_data) | IO_MASK(R_IRQ_MASK1_RD, ser2_ready)
+#endif
+#ifdef CONFIG_ETRAX_SERIAL_PORT3
+| IO_MASK(R_IRQ_MASK1_RD, ser3_data) | IO_MASK(R_IRQ_MASK1_RD, ser3_ready)
+#endif	
+; 
+unsigned long r_alt_ser_baudrate_shadow = 0;
+
 /* this is the data for the four serial ports in the etrax100 */
 /*  DMA2(ser2), DMA4(ser3), DMA6(ser0) or DMA8(ser1) */
 /* R_DMA_CHx_CLR_INTR, R_DMA_CHx_FIRST, R_DMA_CHx_CMD */
 
 static struct e100_serial rs_table[] = {
-	{ DEF_BAUD, (unsigned char *)R_SERIAL0_CTRL, 1U << 12, /* uses DMA 6 and 7 */
-	  R_DMA_CH6_CLR_INTR, R_DMA_CH6_FIRST, R_DMA_CH6_CMD,
-	  R_DMA_CH6_STATUS, R_DMA_CH6_HWSW, R_DMA_CH6_DESCR,
-	  R_DMA_CH7_CLR_INTR, R_DMA_CH7_FIRST, R_DMA_CH7_CMD,
-	  R_DMA_CH7_STATUS, R_DMA_CH7_HWSW, R_DMA_CH7_DESCR,
-	  STD_FLAGS, DEF_RX, DEF_TX, 2,
+	{ .baud        = DEF_BAUD,
+	  .port        = (unsigned char *)R_SERIAL0_CTRL,
+	  .irq         = 1U << 12, /* uses DMA 6 and 7 */
+	  .oclrintradr = R_DMA_CH6_CLR_INTR,
+	  .ofirstadr   = R_DMA_CH6_FIRST,
+	  .ocmdadr     = R_DMA_CH6_CMD,
+	  .ostatusadr  = R_DMA_CH6_STATUS,
+	  .iclrintradr = R_DMA_CH7_CLR_INTR,
+	  .ifirstadr   = R_DMA_CH7_FIRST,
+	  .icmdadr     = R_DMA_CH7_CMD,
+	  .idescradr   = R_DMA_CH7_DESCR,
+	  .flags       = STD_FLAGS,
+	  .rx_ctrl     = DEF_RX,
+	  .tx_ctrl     = DEF_TX,
+	  .iseteop     = 2,
 #ifdef CONFIG_ETRAX_SERIAL_PORT0
-          1
+          .enabled  = 1,
+#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT
+	  .dma_out_enabled = 1,
+#else
+	  .dma_out_enabled = 0,
+#endif
+#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN
+	  .dma_in_enabled = 1,
+#else
+	  .dma_in_enabled = 0
+#endif
 #else
-          0
+          .enabled  = 0,
+	  .dma_out_enabled = 0,
+	  .dma_in_enabled = 0	  
 #endif
+
 },  /* ttyS0 */
 #ifndef CONFIG_SVINTO_SIM
-	{ DEF_BAUD, (unsigned char *)R_SERIAL1_CTRL, 1U << 16, /* uses DMA 8 and 9 */
-	  R_DMA_CH8_CLR_INTR, R_DMA_CH8_FIRST, R_DMA_CH8_CMD,
-	  R_DMA_CH8_STATUS, R_DMA_CH8_HWSW, R_DMA_CH8_DESCR,
-	  R_DMA_CH9_CLR_INTR, R_DMA_CH9_FIRST, R_DMA_CH9_CMD,
-	  R_DMA_CH9_STATUS, R_DMA_CH9_HWSW, R_DMA_CH9_DESCR,
-	  STD_FLAGS, DEF_RX, DEF_TX, 3 ,
+	{ .baud        = DEF_BAUD,
+	  .port        = (unsigned char *)R_SERIAL1_CTRL,
+	  .irq         = 1U << 16, /* uses DMA 8 and 9 */
+	  .oclrintradr = R_DMA_CH8_CLR_INTR,
+	  .ofirstadr   = R_DMA_CH8_FIRST,
+	  .ocmdadr     = R_DMA_CH8_CMD,
+	  .ostatusadr  = R_DMA_CH8_STATUS,
+	  .iclrintradr = R_DMA_CH9_CLR_INTR,
+	  .ifirstadr   = R_DMA_CH9_FIRST,
+	  .icmdadr     = R_DMA_CH9_CMD,
+	  .idescradr   = R_DMA_CH9_DESCR,
+	  .flags       = STD_FLAGS,
+	  .rx_ctrl     = DEF_RX,
+	  .tx_ctrl     = DEF_TX,
+	  .iseteop     = 3,
 #ifdef CONFIG_ETRAX_SERIAL_PORT1
-          1
+          .enabled  = 1,
+#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT
+	  .dma_out_enabled = 1,
+#else
+	  .dma_out_enabled = 0,
+#endif
+#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN
+	  .dma_in_enabled = 1,
 #else
-          0
+	  .dma_in_enabled = 0
+#endif
+#else
+          .enabled  = 0,
+	  .dma_out_enabled = 0,
+	  .dma_in_enabled = 0
 #endif
 },  /* ttyS1 */
 
-	{ DEF_BAUD, (unsigned char *)R_SERIAL2_CTRL, 1U << 4,  /* uses DMA 2 and 3 */
-	  R_DMA_CH2_CLR_INTR, R_DMA_CH2_FIRST, R_DMA_CH2_CMD,
-	  R_DMA_CH2_STATUS, R_DMA_CH2_HWSW, R_DMA_CH2_DESCR,
-	  R_DMA_CH3_CLR_INTR, R_DMA_CH3_FIRST, R_DMA_CH3_CMD,
-	  R_DMA_CH3_STATUS, R_DMA_CH3_HWSW, R_DMA_CH3_DESCR,
-	  STD_FLAGS, DEF_RX, DEF_TX, 0,
+	{ .baud        = DEF_BAUD,
+	  .port        = (unsigned char *)R_SERIAL2_CTRL,
+	  .irq         = 1U << 4,  /* uses DMA 2 and 3 */
+	  .oclrintradr = R_DMA_CH2_CLR_INTR,
+	  .ofirstadr   = R_DMA_CH2_FIRST,
+	  .ocmdadr     = R_DMA_CH2_CMD,
+	  .ostatusadr  = R_DMA_CH2_STATUS,
+	  .iclrintradr = R_DMA_CH3_CLR_INTR,
+	  .ifirstadr   = R_DMA_CH3_FIRST,
+	  .icmdadr     = R_DMA_CH3_CMD,
+	  .idescradr   = R_DMA_CH3_DESCR,
+	  .flags       = STD_FLAGS,
+	  .rx_ctrl     = DEF_RX,
+	  .tx_ctrl     = DEF_TX,
+	  .iseteop     = 0,
 #ifdef CONFIG_ETRAX_SERIAL_PORT2
-          1
+          .enabled  = 1,
+#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT
+	  .dma_out_enabled = 1,
+#else
+	  .dma_out_enabled = 0,
+#endif
+#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN
+	  .dma_in_enabled = 1,
 #else
-          0
+	  .dma_in_enabled = 0
+#endif
+#else
+          .enabled  = 0,
+	  .dma_out_enabled = 0,
+	  .dma_in_enabled = 0
 #endif
  },  /* ttyS2 */
 
-	{ DEF_BAUD, (unsigned char *)R_SERIAL3_CTRL, 1U << 8,  /* uses DMA 4 and 5 */
-	  R_DMA_CH4_CLR_INTR, R_DMA_CH4_FIRST, R_DMA_CH4_CMD,
-	  R_DMA_CH4_STATUS, R_DMA_CH4_HWSW, R_DMA_CH4_DESCR,
-	  R_DMA_CH5_CLR_INTR, R_DMA_CH5_FIRST, R_DMA_CH5_CMD,
-	  R_DMA_CH5_STATUS, R_DMA_CH5_HWSW, R_DMA_CH5_DESCR,
-	  STD_FLAGS, DEF_RX, DEF_TX, 1,
+	{ .baud        = DEF_BAUD,
+	  .port        = (unsigned char *)R_SERIAL3_CTRL,
+	  .irq         = 1U << 8,  /* uses DMA 4 and 5 */
+	  .oclrintradr = R_DMA_CH4_CLR_INTR,
+	  .ofirstadr   = R_DMA_CH4_FIRST,
+	  .ocmdadr     = R_DMA_CH4_CMD,
+	  .ostatusadr  = R_DMA_CH4_STATUS,
+	  .iclrintradr = R_DMA_CH5_CLR_INTR,
+	  .ifirstadr   = R_DMA_CH5_FIRST,
+	  .icmdadr     = R_DMA_CH5_CMD,
+	  .idescradr   = R_DMA_CH5_DESCR,
+	  .flags       = STD_FLAGS,
+	  .rx_ctrl     = DEF_RX,
+	  .tx_ctrl     = DEF_TX,
+	  .iseteop     = 1,
 #ifdef CONFIG_ETRAX_SERIAL_PORT3
-          1
+          .enabled  = 1,
+#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT
+	  .dma_out_enabled = 1,
+#else
+	  .dma_out_enabled = 0,
+#endif
+#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN
+	  .dma_in_enabled = 1,
 #else
-          0
+	  .dma_in_enabled = 0
+#endif
+#else
+          .enabled  = 0,
+	  .dma_out_enabled = 0,
+	  .dma_in_enabled = 0  
 #endif
  }   /* ttyS3 */
 #endif
@@ -627,7 +884,7 @@
  ((CONFIG_ETRAX_SER##line##_##pinname##_ON_PA_BIT >= 0)? \
 		(R_PORT_PA_DATA): ( \
  (CONFIG_ETRAX_SER##line##_##pinname##_ON_PB_BIT >= 0)? \
-		(R_PORT_PB_DATA):&dummy_ser[##line##]))
+		(R_PORT_PB_DATA):&dummy_ser[line]))
 
 #define E100_STRUCT_SHADOW(line, pinname) \
  ((CONFIG_ETRAX_SER##line##_##pinname##_ON_PA_BIT >= 0)? \
@@ -646,6 +903,225 @@
 #define DUMMY_CD_MASK  8
 static unsigned char dummy_ser[NR_PORTS] = {0xFF, 0xFF, 0xFF,0xFF};
 
+/* If not all status pins are used or disabled, use mixed mode */
+#ifdef CONFIG_ETRAX_SERIAL_PORT0
+
+#define SER0_PA_BITSUM (CONFIG_ETRAX_SER0_DTR_ON_PA_BIT+CONFIG_ETRAX_SER0_RI_ON_PA_BIT+CONFIG_ETRAX_SER0_DSR_ON_PA_BIT+CONFIG_ETRAX_SER0_CD_ON_PA_BIT)
+
+#if SER0_PA_BITSUM != -4
+#  if CONFIG_ETRAX_SER0_DTR_ON_PA_BIT == -1
+#    ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#   endif
+# if CONFIG_ETRAX_SER0_RI_ON_PA_BIT == -1
+#   ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
+#     define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
+#   endif
+#  endif
+#  if CONFIG_ETRAX_SER0_DSR_ON_PA_BIT == -1
+#    ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#  if CONFIG_ETRAX_SER0_CD_ON_PA_BIT == -1
+#    ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#endif
+
+#define SER0_PB_BITSUM (CONFIG_ETRAX_SER0_DTR_ON_PB_BIT+CONFIG_ETRAX_SER0_RI_ON_PB_BIT+CONFIG_ETRAX_SER0_DSR_ON_PB_BIT+CONFIG_ETRAX_SER0_CD_ON_PB_BIT)
+
+#if SER0_PB_BITSUM != -4
+#  if CONFIG_ETRAX_SER0_DTR_ON_PB_BIT == -1
+#    ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#   endif
+# if CONFIG_ETRAX_SER0_RI_ON_PB_BIT == -1
+#   ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
+#     define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
+#   endif
+#  endif
+#  if CONFIG_ETRAX_SER0_DSR_ON_PB_BIT == -1
+#    ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#  if CONFIG_ETRAX_SER0_CD_ON_PB_BIT == -1
+#    ifndef CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#endif
+
+#endif /* PORT0 */
+
+
+#ifdef CONFIG_ETRAX_SERIAL_PORT1
+
+#define SER1_PA_BITSUM (CONFIG_ETRAX_SER1_DTR_ON_PA_BIT+CONFIG_ETRAX_SER1_RI_ON_PA_BIT+CONFIG_ETRAX_SER1_DSR_ON_PA_BIT+CONFIG_ETRAX_SER1_CD_ON_PA_BIT)
+
+#if SER1_PA_BITSUM != -4
+#  if CONFIG_ETRAX_SER1_DTR_ON_PA_BIT == -1
+#    ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#   endif
+# if CONFIG_ETRAX_SER1_RI_ON_PA_BIT == -1
+#   ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
+#     define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
+#   endif
+#  endif
+#  if CONFIG_ETRAX_SER1_DSR_ON_PA_BIT == -1
+#    ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#  if CONFIG_ETRAX_SER1_CD_ON_PA_BIT == -1
+#    ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#endif
+
+#define SER1_PB_BITSUM (CONFIG_ETRAX_SER1_DTR_ON_PB_BIT+CONFIG_ETRAX_SER1_RI_ON_PB_BIT+CONFIG_ETRAX_SER1_DSR_ON_PB_BIT+CONFIG_ETRAX_SER1_CD_ON_PB_BIT)
+
+#if SER1_PB_BITSUM != -4
+#  if CONFIG_ETRAX_SER1_DTR_ON_PB_BIT == -1
+#    ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#   endif
+# if CONFIG_ETRAX_SER1_RI_ON_PB_BIT == -1
+#   ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
+#     define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
+#   endif
+#  endif
+#  if CONFIG_ETRAX_SER1_DSR_ON_PB_BIT == -1
+#    ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#  if CONFIG_ETRAX_SER1_CD_ON_PB_BIT == -1
+#    ifndef CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#endif
+
+#endif /* PORT1 */
+
+#ifdef CONFIG_ETRAX_SERIAL_PORT2
+
+#define SER2_PA_BITSUM (CONFIG_ETRAX_SER2_DTR_ON_PA_BIT+CONFIG_ETRAX_SER2_RI_ON_PA_BIT+CONFIG_ETRAX_SER2_DSR_ON_PA_BIT+CONFIG_ETRAX_SER2_CD_ON_PA_BIT)
+
+#if SER2_PA_BITSUM != -4
+#  if CONFIG_ETRAX_SER2_DTR_ON_PA_BIT == -1
+#    ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#   endif
+# if CONFIG_ETRAX_SER2_RI_ON_PA_BIT == -1
+#   ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
+#     define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
+#   endif
+#  endif
+#  if CONFIG_ETRAX_SER2_DSR_ON_PA_BIT == -1
+#    ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#  if CONFIG_ETRAX_SER2_CD_ON_PA_BIT == -1
+#    ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#endif
+
+#define SER2_PB_BITSUM (CONFIG_ETRAX_SER2_DTR_ON_PB_BIT+CONFIG_ETRAX_SER2_RI_ON_PB_BIT+CONFIG_ETRAX_SER2_DSR_ON_PB_BIT+CONFIG_ETRAX_SER2_CD_ON_PB_BIT)
+
+#if SER2_PB_BITSUM != -4
+#  if CONFIG_ETRAX_SER2_DTR_ON_PB_BIT == -1
+#    ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#   endif
+# if CONFIG_ETRAX_SER2_RI_ON_PB_BIT == -1
+#   ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
+#     define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
+#   endif
+#  endif
+#  if CONFIG_ETRAX_SER2_DSR_ON_PB_BIT == -1
+#    ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#  if CONFIG_ETRAX_SER2_CD_ON_PB_BIT == -1
+#    ifndef CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#endif
+
+#endif /* PORT2 */
+
+#ifdef CONFIG_ETRAX_SERIAL_PORT3
+
+#define SER3_PA_BITSUM (CONFIG_ETRAX_SER3_DTR_ON_PA_BIT+CONFIG_ETRAX_SER3_RI_ON_PA_BIT+CONFIG_ETRAX_SER3_DSR_ON_PA_BIT+CONFIG_ETRAX_SER3_CD_ON_PA_BIT)
+
+#if SER3_PA_BITSUM != -4
+#  if CONFIG_ETRAX_SER3_DTR_ON_PA_BIT == -1
+#    ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#   endif
+# if CONFIG_ETRAX_SER3_RI_ON_PA_BIT == -1
+#   ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
+#     define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
+#   endif
+#  endif
+#  if CONFIG_ETRAX_SER3_DSR_ON_PA_BIT == -1
+#    ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#  if CONFIG_ETRAX_SER3_CD_ON_PA_BIT == -1
+#    ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#endif
+
+#define SER3_PB_BITSUM (CONFIG_ETRAX_SER3_DTR_ON_PB_BIT+CONFIG_ETRAX_SER3_RI_ON_PB_BIT+CONFIG_ETRAX_SER3_DSR_ON_PB_BIT+CONFIG_ETRAX_SER3_CD_ON_PB_BIT)
+
+#if SER3_PB_BITSUM != -4
+#  if CONFIG_ETRAX_SER3_DTR_ON_PB_BIT == -1
+#    ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#   endif
+# if CONFIG_ETRAX_SER3_RI_ON_PB_BIT == -1
+#   ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
+#     define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
+#   endif
+#  endif
+#  if CONFIG_ETRAX_SER3_DSR_ON_PB_BIT == -1
+#    ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#  if CONFIG_ETRAX_SER3_CD_ON_PB_BIT == -1
+#    ifndef CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED
+#      define CONFIG_ETRAX_SER3_DTR_RI_DSR_CD_MIXED 1
+#    endif
+#  endif
+#endif
+
+#endif /* PORT3 */
+
+
 #if defined(CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_MIXED) || \
     defined(CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_MIXED) || \
     defined(CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_MIXED) || \
@@ -653,6 +1129,7 @@
 #define CONFIG_ETRAX_SERX_DTR_RI_DSR_CD_MIXED
 #endif
 
+
 #ifdef CONFIG_ETRAX_SERX_DTR_RI_DSR_CD_MIXED
 /* The pins can be mixed on PA and PB */
 #define CONTROL_PINS_PORT_NOT_USED(line) \
@@ -838,7 +1315,6 @@
 #define E100_RTS_MASK 0x20
 #define E100_CTS_MASK 0x40
 
-
 /* All serial port signals are active low:
  * active   = 0 -> 3.3V to RS-232 driver -> -12V on RS-232 level
  * inactive = 1 -> 0V   to RS-232 driver -> +12V on RS-232 level
@@ -937,6 +1413,9 @@
 
 	/* calc timeout */
 	info->char_time_usec = ((bits * 1000000) / info->baud) + 1;
+	info->flush_time_usec = 4*info->char_time_usec;
+	if (info->flush_time_usec < MIN_FLUSH_TIME_USEC)
+		info->flush_time_usec = MIN_FLUSH_TIME_USEC;
 }
 
 /*
@@ -980,7 +1459,7 @@
 		retval = baud_table[cflag & CBAUD];
 
 	if (retval < 0) {
-		printk("serdriver tried setting invalid baud rate, flags %x.\n", cflag);
+		printk(KERN_WARNING "serdriver tried setting invalid baud rate, flags %x.\n", cflag);
 		retval = 5; /* choose default 9600 instead */
 	}
 
@@ -1036,9 +1515,13 @@
 e100_rts(struct e100_serial *info, int set)
 {
 #ifndef CONFIG_SVINTO_SIM
+	unsigned long flags;
+	save_flags(flags);
+	cli();
 	info->rx_ctrl &= ~E100_RTS_MASK;
 	info->rx_ctrl |= (set ? 0 : E100_RTS_MASK);  /* RTS is active low */
 	info->port[REG_REC_CTRL] = info->rx_ctrl;
+	restore_flags(flags);
 #ifdef SERIAL_DEBUG_IO  
 	printk("ser%i rts %i\n", info->line, set);
 #endif
@@ -1112,6 +1595,7 @@
 #ifdef SERIAL_DEBUG_INTR
 	printk("rxdma_irq(%d): 0\n",info->line);
 #endif
+	DINTR1(DEBUG_LOG(info->line,"IRQ disable_rxdma_irq %i\n", info->line));
 	*R_IRQ_MASK2_CLR = (info->irq << 2) | (info->irq << 3);
 }
 
@@ -1121,6 +1605,7 @@
 #ifdef SERIAL_DEBUG_INTR
 	printk("rxdma_irq(%d): 1\n",info->line);
 #endif
+	DINTR1(DEBUG_LOG(info->line,"IRQ enable_rxdma_irq %i\n", info->line));
 	*R_IRQ_MASK2_SET = (info->irq << 2) | (info->irq << 3);
 }
 
@@ -1132,6 +1617,7 @@
 #ifdef SERIAL_DEBUG_INTR
 	printk("txdma_irq(%d): 0\n",info->line);
 #endif
+	DINTR1(DEBUG_LOG(info->line,"IRQ disable_txdma_irq %i\n", info->line));
 	*R_IRQ_MASK2_CLR = info->irq;
 }
 
@@ -1141,9 +1627,143 @@
 #ifdef SERIAL_DEBUG_INTR
 	printk("txdma_irq(%d): 1\n",info->line);
 #endif
+	DINTR1(DEBUG_LOG(info->line,"IRQ enable_txdma_irq %i\n", info->line));
 	*R_IRQ_MASK2_SET = info->irq;
 }
 
+static _INLINE_ void
+e100_disable_txdma_channel(struct e100_serial *info)
+{
+	unsigned long flags;
+  
+	/* Disable output DMA channel for the serial port in question
+	 * ( set to something other then serialX)
+	 */
+	save_flags(flags);
+	cli();
+	DFLOW(DEBUG_LOG(info->line, "disable_txdma_channel %i\n", info->line));
+	if (info->line == 0) {
+		if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma6)) ==
+		    IO_STATE(R_GEN_CONFIG, dma6, serial0)) {
+			genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma6);
+			genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused);
+		}
+	} else if (info->line == 1) {
+		if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma8)) ==
+		    IO_STATE(R_GEN_CONFIG, dma8, serial1)) {
+			genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma8);
+			genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb);
+		}
+	} else if (info->line == 2) {
+		if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma2)) ==
+		    IO_STATE(R_GEN_CONFIG, dma2, serial2)) {
+			genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma2);
+			genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0);
+		}
+	} else if (info->line == 3) {
+		if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma4)) ==
+		    IO_STATE(R_GEN_CONFIG, dma4, serial3)) {
+			genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma4);
+			genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, par1);
+		}
+	}
+	*R_GEN_CONFIG = genconfig_shadow;
+	restore_flags(flags);
+}
+
+
+static _INLINE_ void
+e100_enable_txdma_channel(struct e100_serial *info)
+{
+	unsigned long flags;
+  
+	save_flags(flags);
+	cli();
+	DFLOW(DEBUG_LOG(info->line, "enable_txdma_channel %i\n", info->line));
+	/* Enable output DMA channel for the serial port in question */
+	if (info->line == 0) {
+		genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma6);
+		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, serial0);
+	} else if (info->line == 1) {
+		genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma8);
+		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, serial1);
+	} else if (info->line == 2) {
+		genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma2);
+		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, serial2);
+	} else if (info->line == 3) {
+		genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma4);
+		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, serial3);
+	}
+	*R_GEN_CONFIG = genconfig_shadow;
+	restore_flags(flags);
+}
+
+static _INLINE_ void
+e100_disable_rxdma_channel(struct e100_serial *info)
+{
+	unsigned long flags;
+  
+	/* Disable input DMA channel for the serial port in question
+	 * ( set to something other then serialX)
+	 */
+	save_flags(flags);
+	cli();  
+	if (info->line == 0) {
+		if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma7)) ==
+		    IO_STATE(R_GEN_CONFIG, dma7, serial0)) {
+			genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma7);
+			genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma7, unused);
+		}
+	} else if (info->line == 1) {
+		if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma9)) ==
+		    IO_STATE(R_GEN_CONFIG, dma9, serial1)) {
+			genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma9);
+			genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma9, usb);
+		}
+	} else if (info->line == 2) {
+		if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma3)) ==
+		    IO_STATE(R_GEN_CONFIG, dma3, serial2)) {
+			genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma3);
+			genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, par0);
+		}
+	} else if (info->line == 3) {
+		if ((genconfig_shadow & IO_MASK(R_GEN_CONFIG, dma5)) ==
+		    IO_STATE(R_GEN_CONFIG, dma5, serial3)) {
+			genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma5);
+			genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, par1);
+		}
+	}
+	*R_GEN_CONFIG = genconfig_shadow;
+	restore_flags(flags);
+}
+
+
+static _INLINE_ void
+e100_enable_rxdma_channel(struct e100_serial *info)
+{
+	unsigned long flags;
+  
+	save_flags(flags);
+	cli();  
+	/* Enable input DMA channel for the serial port in question */
+	if (info->line == 0) {
+		genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma7);
+		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma7, serial0);
+	} else if (info->line == 1) {
+		genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma9);
+		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma9, serial1);
+	} else if (info->line == 2) {
+		genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma3);
+		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, serial2);
+	} else if (info->line == 3) {
+		genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma5);
+		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, serial3);
+	}
+	*R_GEN_CONFIG = genconfig_shadow;
+	restore_flags(flags);
+}
+
+
 #ifdef SERIAL_HANDLE_EARLY_ERRORS
 /* in order to detect and fix errors on the first byte
    we have to use the serial interrupts as well. */
@@ -1154,6 +1774,7 @@
 #ifdef SERIAL_DEBUG_INTR
 	printk("ser_irq(%d): 0\n",info->line);
 #endif
+	DINTR1(DEBUG_LOG(info->line,"IRQ disable data_irq %i\n", info->line));
 	*R_IRQ_MASK1_CLR = (1U << (8+2*info->line));
 }
 
@@ -1166,10 +1787,50 @@
 	       (8+2*info->line),
 	       (1U << (8+2*info->line)));
 #endif
+	DINTR1(DEBUG_LOG(info->line,"IRQ enable data_irq %i\n", info->line));
 	*R_IRQ_MASK1_SET = (1U << (8+2*info->line));
 }
 #endif
 
+static inline void
+e100_disable_serial_tx_ready_irq(struct e100_serial *info) 
+{
+#ifdef SERIAL_DEBUG_INTR
+	printk("ser_tx_irq(%d): 0\n",info->line);
+#endif
+	DINTR1(DEBUG_LOG(info->line,"IRQ disable ready_irq %i\n", info->line));
+	*R_IRQ_MASK1_CLR = (1U << (8+1+2*info->line));
+}
+
+static inline void
+e100_enable_serial_tx_ready_irq(struct e100_serial *info) 
+{
+#ifdef SERIAL_DEBUG_INTR
+	printk("ser_tx_irq(%d): 1\n",info->line);
+	printk("**** %d = %d\n",
+	       (8+1+2*info->line),
+	       (1U << (8+1+2*info->line)));
+#endif
+	DINTR2(DEBUG_LOG(info->line,"IRQ enable ready_irq %i\n", info->line));
+	*R_IRQ_MASK1_SET = (1U << (8+1+2*info->line));
+}
+
+static inline void e100_enable_rx_irq(struct e100_serial *info)
+{
+	if (info->uses_dma_in)
+		e100_enable_rxdma_irq(info);
+	else
+		e100_enable_serial_data_irq(info);
+}
+static inline void e100_disable_rx_irq(struct e100_serial *info)
+{
+	if (info->uses_dma_in)
+		e100_disable_rxdma_irq(info);
+	else
+		e100_disable_serial_data_irq(info);
+}
+
+
 #if defined(CONFIG_ETRAX_RS485)
 /* Enable RS-485 mode on selected port. This is UGLY. */
 static int
@@ -1183,7 +1844,10 @@
 
 	info->rs485.rts_on_send = 0x01 & r->rts_on_send;
 	info->rs485.rts_after_sent = 0x01 & r->rts_after_sent;
-	info->rs485.delay_rts_before_send = r->delay_rts_before_send;
+	if (r->delay_rts_before_send >= 1000)
+		info->rs485.delay_rts_before_send = 1000;
+	else
+		info->rs485.delay_rts_before_send = r->delay_rts_before_send;
 	info->rs485.enabled = r->enabled;
 /*	printk("rts: on send = %i, after = %i, enabled = %i",
 		    info->rs485.rts_on_send,
@@ -1223,7 +1887,7 @@
 	e100_rts(info, info->rs485.rts_after_sent);
 #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
 	e100_enable_rx(info);
-	e100_enable_rxdma_irq(info);
+	e100_enable_rx_irq(info);	
 #endif
 }
 #endif
@@ -1245,8 +1909,12 @@
 	if (info) {
 		unsigned long flags;
 		unsigned long xoff;
-		
+
 		save_flags(flags); cli();
+		DFLOW(DEBUG_LOG(info->line, "XOFF rs_stop xmit %i\n",
+				CIRC_CNT(info->xmit.head,
+					 info->xmit.tail,SERIAL_XMIT_SIZE)));
+		
 		xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->tty));
 		xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop);
 		if (tty->termios->c_iflag & IXON ) {
@@ -1267,6 +1935,9 @@
 		unsigned long xoff;
 
 		save_flags(flags); cli();
+		DFLOW(DEBUG_LOG(info->line, "XOFF rs_start xmit %i\n",
+				CIRC_CNT(info->xmit.head,
+					 info->xmit.tail,SERIAL_XMIT_SIZE)));
 		xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(tty));
 		xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable);
 		if (tty->termios->c_iflag & IXON ) {
@@ -1274,6 +1945,9 @@
 		}
 	
 		*((unsigned long *)&info->port[REG_XOFF]) = xoff;
+		if (!info->uses_dma_out &&
+		    info->xmit.head != info->xmit.tail && info->xmit.buf)
+			e100_enable_serial_tx_ready_irq(info);
 		
 		restore_flags(flags);
 	}
@@ -1308,6 +1982,8 @@
 rs_sched_event(struct e100_serial *info,
 				    int event)
 {
+	if (info->event & (1 << event))
+		return;
 	info->event |= 1 << event;
 	queue_task(&info->tqueue, &tq_serial);
 	mark_bh(SERIAL_BH);
@@ -1325,7 +2001,7 @@
  */
 
 static void 
-transmit_chars(struct e100_serial *info)
+transmit_chars_dma(struct e100_serial *info)
 {
 	unsigned int c, sentl;
 	struct etrax_dma_descr *descr;
@@ -1333,11 +2009,11 @@
 #ifdef CONFIG_SVINTO_SIM
 	/* This will output too little if tail is not 0 always since
 	 * we don't reloop to send the other part. Anyway this SHOULD be a
-	 * no-op - transmit_chars would never really be called during sim
+	 * no-op - transmit_chars_dma would never really be called during sim
 	 * since rs_write does not write into the xmit buffer then.
 	 */
 	if (info->xmit.tail)
-		printk("Error in serial.c:transmit_chars(), tail!=0\n");
+		printk("Error in serial.c:transmit_chars_dma(), tail!=0\n");
 	if (info->xmit.head != info->xmit.tail) {
 		SIMCOUT(info->xmit.buf + info->xmit.tail,
 			CIRC_CNT(info->xmit.head,
@@ -1359,7 +2035,7 @@
 #endif
 	if (!info->tr_running) {
 		/* weirdo... we shouldn't get here! */
-		printk("Achtung: transmit_chars with !tr_running\n");
+		printk(KERN_WARNING "Achtung: transmit_chars_dma with !tr_running\n");
 		return;
 	}
 
@@ -1375,6 +2051,8 @@
 		/* otherwise we find the amount of data sent here */
 		sentl = descr->hw_len;
 
+	DFLOW(DEBUG_LOG(info->line, "TX %i done\n", sentl));
+		
 	/* update stats */
 	info->icount.tx += sentl;
 
@@ -1392,6 +2070,13 @@
 
 	c = CIRC_CNT_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
 
+	/* Don't send all in one DMA transfer - divide it so we wake up
+	 * application before all is sent
+	 */
+
+	if (c >= 4*WAKEUP_CHARS)
+		c = c/2;
+
 	if (c <= 0) {
 		/* our job here is done, don't schedule any new DMA transfer */
 		info->tr_running = 0;
@@ -1411,17 +2096,17 @@
 
 	/* ok we can schedule a dma send of c chars starting at info->xmit.tail */
 	/* set up the descriptor correctly for output */
-
+	DFLOW(DEBUG_LOG(info->line, "TX %i\n", c));
 	descr->ctrl = d_int | d_eol | d_wait; /* Wait needed for tty_wait_until_sent() */
 	descr->sw_len = c;
 	descr->buf = virt_to_phys(info->xmit.buf + info->xmit.tail);
 	descr->status = 0;
 
 	*info->ofirstadr = virt_to_phys(descr); /* write to R_DMAx_FIRST */
-	*info->ocmdadr = 1;       /* dma command start -> R_DMAx_CMD */
+	*info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, start);       /* dma command start -> R_DMAx_CMD */
 	
 	/* DMA is now running (hopefully) */
-} /* transmit_chars */
+} /* transmit_chars_dma */
 
 static void 
 start_transmit(struct e100_serial *info)
@@ -1435,15 +2120,17 @@
 	info->tr_descr.hw_len = 0;
 	info->tr_descr.status = 0;
 	info->tr_running = 1;
-
-	transmit_chars(info);
+	if (info->uses_dma_out)
+		transmit_chars_dma(info);
+	else
+		e100_enable_serial_tx_ready_irq(info);
 } /* start_transmit */
 
 #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
 static int serial_fast_timer_started = 0;
 static int serial_fast_timer_expired = 0;
 static void flush_timeout_function(unsigned long data);
-#define START_FLUSH_FAST_TIMER(info, string) {\
+#define START_FLUSH_FAST_TIMER_TIME(info, string, usec) {\
   unsigned long timer_flags; \
   save_flags(timer_flags); \
   cli(); \
@@ -1454,7 +2141,7 @@
     start_one_shot_timer(&fast_timers[info->line], \
                          flush_timeout_function, \
                          (unsigned long)info, \
-                         info->char_time_usec*4, \
+                         (usec), \
                          string); \
   } \
   else { \
@@ -1462,8 +2149,10 @@
   } \
   restore_flags(timer_flags); \
 }
+#define START_FLUSH_FAST_TIMER(info, string) START_FLUSH_FAST_TIMER_TIME(info, string, info->flush_time_usec)
 
 #else
+#define START_FLUSH_FAST_TIMER_TIME(info, string, usec)
 #define START_FLUSH_FAST_TIMER(info, string)
 #endif
 
@@ -1508,18 +2197,27 @@
 add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char flag)
 {
 	struct etrax_recv_buffer *buffer;
+	if (info->uses_dma_in) {
+		if (!(buffer = alloc_recv_buffer(4)))
+			return 0;
 
-	if (!(buffer = alloc_recv_buffer(4)))
-		return 0;
-
-	buffer->length = 1;
-	buffer->error = flag;
-	buffer->buffer[0] = data;
+		buffer->length = 1;
+		buffer->error = flag;
+		buffer->buffer[0] = data;
 	
-	append_recv_buffer(info, buffer);
-
-	info->icount.rx++;
+		append_recv_buffer(info, buffer);
 
+		info->icount.rx++;
+	} else {
+		struct tty_struct *tty = info->tty;		
+		*tty->flip.char_buf_ptr = data;
+		*tty->flip.flag_buf_ptr = flag;
+		tty->flip.flag_buf_ptr++;
+		tty->flip.char_buf_ptr++;
+		tty->flip.count++;
+		info->icount.rx++;
+	}
+	
 	return 1;
 }
 
@@ -1529,7 +2227,8 @@
 	struct etrax_recv_buffer *buffer = phys_to_virt(descr->buf) - sizeof *buffer;
 
 	if (info->recv_cnt + recvl > 65536) {
-		printk(__FUNCTION__ ": Too much pending incoming serial data! Dropping %u bytes.\n", recvl);
+		printk(KERN_CRIT
+		       "%s: Too much pending incoming serial data! Dropping %u bytes.\n", __FUNCTION__, recvl);
 		return 0;
 	}
 
@@ -1542,7 +2241,7 @@
 	append_recv_buffer(info, buffer);
 
 	if (!(buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE)))
-		panic(__FUNCTION__ ": Failed to allocate memory for receive buffer!\n");
+		panic("%s: Failed to allocate memory for receive buffer!\n", __FUNCTION__);
 
 	descr->buf = virt_to_phys(buffer->buffer);
 	
@@ -1579,8 +2278,16 @@
 		/* Reset the status information */
 		descr->status = 0;
 
-		DEBUG_LOG(info->line, "recvl %lu\n", recvl);
-
+		DFLOW(  DEBUG_LOG(info->line, "RX %lu\n", recvl);
+			if (info->tty->stopped) {
+				unsigned char *buf = phys_to_virt(descr->buf);
+				DEBUG_LOG(info->line, "rx 0x%02X\n", buf[0]);
+				DEBUG_LOG(info->line, "rx 0x%02X\n", buf[1]);
+				DEBUG_LOG(info->line, "rx 0x%02X\n", buf[2]);
+			}
+			);
+		
+		
 		/* update stats */
 		info->icount.rx += recvl;
 
@@ -1591,7 +2298,7 @@
 }
 
 static _INLINE_ void 
-receive_chars(struct e100_serial *info)
+receive_chars_dma(struct e100_serial *info)
 {
 	struct tty_struct *tty;
 	unsigned char rstat;
@@ -1623,7 +2330,10 @@
 
 	/* Read the status register to detect errors */
 	rstat = info->port[REG_STATUS];
-
+	if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) {
+		DFLOW(DEBUG_LOG(info->line, "XOFF detect stat %x\n", rstat));
+	}
+		
 	if (rstat & SER_ERROR_MASK) {
 		/* If we got an error, we must reset it by reading the
 		 * data_in field
@@ -1658,7 +2368,7 @@
 	/* Set up the receiving descriptors */
 	for (i = 0; i < SERIAL_RECV_DESCRIPTORS; i++) {
 		if (!(buffer = alloc_recv_buffer(SERIAL_DESCR_BUF_SIZE)))
-			panic(__FUNCTION__ ": Failed to allocate memory for receive buffer!\n");
+			panic("%s: Failed to allocate memory for receive buffer!\n", __FUNCTION__);
 
 		descr[i].ctrl = d_int;
 		descr[i].buf = virt_to_phys(buffer->buffer);
@@ -1691,20 +2401,20 @@
 	 */
 	return;
 #endif
+	info->tty->flip.count = 0;	
+	if (info->uses_dma_in) {
+		/* reset the input dma channel to be sure it works */
+
+		*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
+		while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) ==
+		       IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
 
-	/* reset the input dma channel to be sure it works */
-
-	*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
-	while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) ==
-	       IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
-
-	info->tty->flip.count = 0;
-
-	start_recv_dma(info);
+		start_recv_dma(info);
 	
 #ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
-	start_flush_timer();
+		start_flush_timer();
 #endif
+	}
 }
 
 
@@ -1749,25 +2459,25 @@
 	
 	for (i = 0; i < NR_PORTS; i++) {
 		info = rs_table + i;
-		if (!info->enabled || !info->uses_dma) 
+		if (!info->enabled || !info->uses_dma_out) 
 			continue; 
 		/* check for dma_descr (don't need to check for dma_eop in output dma for serial */
 		if (ireg & info->irq) {  
 			/* we can send a new dma bunch. make it so. */
-			DEBUG_LOG(info->line, "tr_interrupt %i\n", i);
+			DINTR2(DEBUG_LOG(info->line, "tr_interrupt %i\n", i));
 			/* Read jiffies_usec first, 
 			 * we want this time to be as late as possible
 			 */
  			PROCSTAT(ser_stat[info->line].tx_dma_ints++);
 			info->last_tx_active_usec = GET_JIFFIES_USEC();
 			info->last_tx_active = jiffies;
-			transmit_chars(info);
+			transmit_chars_dma(info);
 		}
 		
 		/* FIXME: here we should really check for a change in the
 		   status lines and if so call status_handle(info) */
 	}
-}
+} /* tr_interrupt */
 
 /* dma input channel interrupt handler */
 
@@ -1795,18 +2505,18 @@
 	
 	for (i = 0; i < NR_PORTS; i++) {
 		info = rs_table + i;
-		if (!info->enabled || !info->uses_dma) 
+		if (!info->enabled || !info->uses_dma_in) 
 			continue; 
 		/* check for both dma_eop and dma_descr for the input dma channel */
 		if (ireg & ((info->irq << 2) | (info->irq << 3))) {
 			/* we have received something */
-			receive_chars(info);
+			receive_chars_dma(info);
 		}
 		
 		/* FIXME: here we should really check for a change in the
 		   status lines and if so call status_handle(info) */
 	}
-}
+} /* rec_interrupt */
 
 static _INLINE_ int
 force_eop_if_needed(struct e100_serial *info)
@@ -1846,7 +2556,7 @@
 	if (!info->forced_eop) {
 		info->forced_eop = 1;
 		PROCSTAT(ser_stat[info->line].timeout_flush_cnt++);
-		DEBUG_LOG(info->line, "timeout EOP %i\n", info->line);
+		TIMERD(DEBUG_LOG(info->line, "timeout EOP %i\n", info->line));
 		FORCE_EOP(info);
 	}
 
@@ -1860,7 +2570,8 @@
 	struct etrax_recv_buffer *buffer;
 	unsigned int length;
 	unsigned long flags;
-
+	int max_flip_size;
+	
 	if (!info->first_recv_buffer)
 		return;
 
@@ -1873,12 +2584,46 @@
 	}
 
 	length = tty->flip.count;
+	/* Don't flip more than the ldisc has room for.
+	 * The return value from ldisc.receive_room(tty) - might not be up to
+	 * date, the previous flip of up to TTY_FLIPBUF_SIZE might be on the
+	 * processed and not accounted for yet.
+	 * Since we use DMA, 1 SERIAL_DESCR_BUF_SIZE could be on the way.
+	 * Lets buffer data here and let flow control take care of it.
+	 * Since we normally flip large chunks, the ldisc don't react
+	 * with throttle until too late if we flip to much.
+	 */
+	max_flip_size = tty->ldisc.receive_room(tty); 
+	if (max_flip_size < 0)
+		max_flip_size = 0;
+	if (max_flip_size <= (TTY_FLIPBUF_SIZE +         /* Maybe not accounted for */
+			      length + info->recv_cnt +  /* We have this queued */
+			      2*SERIAL_DESCR_BUF_SIZE +    /* This could be on the way */
+			      TTY_THRESHOLD_THROTTLE)) { /* Some slack */
+		/* check TTY_THROTTLED first so it indicates our state */
+		if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) {
+			DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles room %lu\n", max_flip_size));
+			rs_throttle(tty);
+		}
+#if 0		
+		else if (max_flip_size <= (TTY_FLIPBUF_SIZE +         /* Maybe not accounted for */
+					   length + info->recv_cnt +  /* We have this queued */
+					   SERIAL_DESCR_BUF_SIZE +    /* This could be on the way */
+					   TTY_THRESHOLD_THROTTLE)) { /* Some slack */
+			DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles again! %lu\n", max_flip_size));
+			rs_throttle(tty);
+		}
+#endif		
+	}
 
-	while ((buffer = info->first_recv_buffer) && length < TTY_FLIPBUF_SIZE) {
+	if (max_flip_size > TTY_FLIPBUF_SIZE)
+		max_flip_size = TTY_FLIPBUF_SIZE;
+
+	while ((buffer = info->first_recv_buffer) && length < max_flip_size) {
 		unsigned int count = buffer->length;
 
-		if (length + count > TTY_FLIPBUF_SIZE)
-			count = TTY_FLIPBUF_SIZE - length;
+		if (length + count > max_flip_size)
+			count = max_flip_size - length;
 
 		memcpy(tty->flip.char_buf_ptr + length, buffer->buffer, count);
 		memset(tty->flip.flag_buf_ptr + length, TTY_NORMAL, count);
@@ -1886,7 +2631,8 @@
 
 		length += count;
 		info->recv_cnt -= count;
-
+		DFLIP(DEBUG_LOG(info->line,"flip: %i\n", length));
+		
 		if (count == buffer->length) {
 			info->first_recv_buffer = buffer->next;
 			kfree(buffer);
@@ -1901,10 +2647,31 @@
 		info->last_recv_buffer = NULL;
 
 	tty->flip.count = length;
-
+	DFLIP(if (tty->ldisc.chars_in_buffer(tty) > 3500) {
+		DEBUG_LOG(info->line, "ldisc %lu\n",
+			  tty->ldisc.chars_in_buffer(tty));
+		DEBUG_LOG(info->line, "flip.count %lu\n",
+			  tty->flip.count);
+	      }
+	      );
 	restore_flags(flags);
 
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,66)
+	DFLIP(
+	  if (1) {
+	  
+		  if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
+			  DEBUG_LOG(info->line, "*** TTY_DONT_FLIP set flip.count %i ***\n", tty->flip.count);
+			  DEBUG_LOG(info->line, "*** recv_cnt %i\n", info->recv_cnt);
+		  } else {
+		  }
+		  DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx);
+		  DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty));
+		  DEBUG_LOG(info->line, "room  %lu\n", tty->ldisc.receive_room(tty));
+	  }
+	  
+	);
+	  
 	/* this includes a check for low-latency */
 	tty_flip_buffer_push(tty);
 #else
@@ -1915,12 +2682,19 @@
 static _INLINE_ void
 check_flush_timeout(struct e100_serial *info)
 {
-	force_eop_if_needed(info);
-
+	/* Flip what we've got (if we can) */
 	flush_to_flip_buffer(info);
 
-	if (info->first_recv_buffer)
-		START_FLUSH_FAST_TIMER(info, "flip");
+	/* We might need to flip later, but not to fast
+	 * since the system is busy processing input... */
+	if (info->first_recv_buffer) 
+		START_FLUSH_FAST_TIMER_TIME(info, "flip", 2000);
+
+	/* Force eop last, since data might have come while we're processing
+	 * and if we started the slow timer above, we won't start a fast
+	 * below.
+	 */
+	force_eop_if_needed(info);	
 }
 
 #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
@@ -1960,7 +2734,7 @@
 	
 	for (i = 0; i < NR_PORTS; i++) {
 		info = rs_table + i;
-		if (info->enabled && info->uses_dma) 
+		if (info->enabled && info->uses_dma_in) 
 			check_flush_timeout(info);
 	}
 } /* timeout_interrupt */
@@ -1988,7 +2762,7 @@
 	
 	for (i = 0; i < NR_PORTS; i++) {
 		info = rs_table + i;
-		if (info->uses_dma) 
+		if (info->uses_dma_in) 
 			check_flush_timeout(info);
 	}
 
@@ -2017,7 +2791,7 @@
 
 B= Break character (0x00) with framing error.
 E= Error byte with parity error received after B characters.
-F= "Faked" valid byte received immediatly after B characters.
+F= "Faked" valid byte received immediately after B characters.
 V= Valid byte
 
 1.
@@ -2054,7 +2828,7 @@
 
 To distinguish a V byte in 1. from an F byte in 2. we keep a timestamp
 of the last faulty char (B) and compares it with the current time:
-If the time elapsed time is less then 2*char_time_usec we will assume
+If the time elapsed time is less than 2*char_time_usec we will assume
 it's a faked F char and not a Valid char and set 
 info->errorcode = ERRCODE_SET_BREAK. 
 
@@ -2066,15 +2840,159 @@
 TODO: The break will be delayed until an F or V character is received.
 
 */
+	
+extern _INLINE_
+struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info)
+{
+	unsigned long data_read;
+	struct tty_struct *tty = info->tty;	  
+
+	if (!tty) {
+		printk("!NO TTY!\n");
+		return info;
+	}
+	if (tty->flip.count >= TTY_FLIPBUF_SIZE - TTY_THRESHOLD_THROTTLE) {
+		/* check TTY_THROTTLED first so it indicates our state */
+		if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) {
+			DFLOW(DEBUG_LOG(info->line, "rs_throttle flip.count: %i\n", tty->flip.count));
+			rs_throttle(tty);
+		}
+	}
+	if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+		DEBUG_LOG(info->line, "force FLIP! %i\n", tty->flip.count);
+		tty->flip.tqueue.routine((void *) tty);
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			DEBUG_LOG(info->line, "FLIP FULL! %i\n", tty->flip.count);
+			return info;		/* if TTY_DONT_FLIP is set */
+		}
+	}
+	/* Read data and status at the same time */
+	data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]);
+more_data:
+	if (data_read & IO_MASK(R_SERIAL0_READ, xoff_detect) ) {
+		DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0));
+	}
+	DINTR2(DEBUG_LOG(info->line, "ser_rx   %c\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read)));
+
+	if (data_read & ( IO_MASK(R_SERIAL0_READ, framing_err) |
+			  IO_MASK(R_SERIAL0_READ, par_err) |
+			  IO_MASK(R_SERIAL0_READ, overrun) )) {
+		/* An error */
+		info->last_rx_active_usec = GET_JIFFIES_USEC();
+		info->last_rx_active = jiffies;
+		DINTR1(DEBUG_LOG(info->line, "ser_rx err stat_data %04X\n", data_read));
+		DLOG_INT_TRIG(
+		if (!log_int_trig1_pos) {
+			log_int_trig1_pos = log_int_pos;
+			log_int(rdpc(), 0, 0);
+		}
+		);
+		
+		
+		if ( ((data_read & IO_MASK(R_SERIAL0_READ, data_in)) == 0) &&
+		     (data_read & IO_MASK(R_SERIAL0_READ, framing_err)) ) {
+			/* Most likely a break, but we get interrupts over and
+			 * over again.
+			 */
 
-extern void _INLINE_ handle_ser_interrupt(struct e100_serial *info)
+			if (!info->break_detected_cnt) {
+				DEBUG_LOG(info->line, "#BRK start\n", 0);
+			}
+			if (data_read & IO_MASK(R_SERIAL0_READ, rxd)) {
+				/* The RX pin is high now, so the break
+				 * must be over, but....
+				 * we can't really know if we will get another
+				 * last byte ending the break or not. 
+				 * And we don't know if the byte (if any) will 
+				 * have an error or look valid.
+				 */
+				DEBUG_LOG(info->line, "# BL BRK\n", 0);
+				info->errorcode = ERRCODE_INSERT_BREAK;
+			}
+			info->break_detected_cnt++;
+		} else {
+			/* The error does not look like a break, but could be
+			 * the end of one
+			 */
+			if (info->break_detected_cnt) {
+				DEBUG_LOG(info->line, "EBRK %i\n", info->break_detected_cnt);
+				info->errorcode = ERRCODE_INSERT_BREAK;
+			} else {
+				if (info->errorcode == ERRCODE_INSERT_BREAK) {
+					info->icount.brk++;
+					*tty->flip.char_buf_ptr = 0;
+					*tty->flip.flag_buf_ptr = TTY_BREAK;
+					tty->flip.flag_buf_ptr++;
+					tty->flip.char_buf_ptr++;
+					tty->flip.count++;
+					info->icount.rx++;
+				}
+				*tty->flip.char_buf_ptr = IO_EXTRACT(R_SERIAL0_READ, data_in, data_read);
+
+				if (data_read & IO_MASK(R_SERIAL0_READ, par_err)) {
+					info->icount.parity++;
+					*tty->flip.flag_buf_ptr = TTY_PARITY;
+				} else if (data_read & IO_MASK(R_SERIAL0_READ, overrun)) {
+					info->icount.overrun++;
+					*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+				} else if (data_read & IO_MASK(R_SERIAL0_READ, framing_err)) {
+					info->icount.frame++;
+					*tty->flip.flag_buf_ptr = TTY_FRAME;
+				}
+				info->errorcode = 0;
+			}
+			info->break_detected_cnt = 0;
+		}
+	} else if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) {
+		/* No error */
+		DLOG_INT_TRIG(
+		if (!log_int_trig1_pos) {
+			if (log_int_pos >= log_int_size) {
+				log_int_pos = 0;
+			}
+			log_int_trig0_pos = log_int_pos;
+			log_int(rdpc(), 0, 0);
+		}
+		);
+		*tty->flip.char_buf_ptr = IO_EXTRACT(R_SERIAL0_READ, data_in, data_read);
+		*tty->flip.flag_buf_ptr = 0;
+	} else {
+		DEBUG_LOG(info->line, "ser_rx int but no data_avail  %08lX\n", data_read);
+	}
+	
+	
+	tty->flip.flag_buf_ptr++;
+	tty->flip.char_buf_ptr++;
+	tty->flip.count++;
+	info->icount.rx++;
+	data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]);
+	if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) {
+		DEBUG_LOG(info->line, "ser_rx   %c in loop\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read));
+		goto more_data;
+	}
+	
+	tty_flip_buffer_push(info->tty);
+	return info;
+}
+
+extern _INLINE_ 
+struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info)
 {
-	unsigned char rstat = info->port[REG_STATUS];
+	unsigned char rstat;
 
 #ifdef SERIAL_DEBUG_INTR
 	printk("Interrupt from serport %d\n", i);
 #endif
 /*	DEBUG_LOG(info->line, "ser_interrupt stat %03X\n", rstat | (i << 8)); */
+	if (!info->uses_dma_in) {
+		return handle_ser_rx_interrupt_no_dma(info);
+	}
+	/* DMA is used */
+	rstat = info->port[REG_STATUS];
+	if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) {
+		DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0));
+	}
+
 	if (rstat & SER_ERROR_MASK) {
 		unsigned char data;
 
@@ -2084,7 +3002,8 @@
 		 * data_in field
 		 */
 		data = info->port[REG_DATA];
-
+		DINTR1(DEBUG_LOG(info->line, "ser_rx!  %c\n", data));
+		DINTR1(DEBUG_LOG(info->line, "ser_rx err stat %02X\n", rstat));
 		if (!data && (rstat & SER_FRAMING_ERR_MASK)) {
 			/* Most likely a break, but we get interrupts over and
 			 * over again.
@@ -2113,15 +3032,22 @@
 				DEBUG_LOG(info->line, "EBRK %i\n", info->break_detected_cnt);
 				info->errorcode = ERRCODE_INSERT_BREAK;
 			} else {
-				if (info->errorcode == ERRCODE_INSERT_BREAK)
+				if (info->errorcode == ERRCODE_INSERT_BREAK) {
+					info->icount.brk++;
 					add_char_and_flag(info, '\0', TTY_BREAK);
+				}
 
-				if (rstat & SER_PAR_ERR_MASK)
+				if (rstat & SER_PAR_ERR_MASK) {
+					info->icount.parity++;
 					add_char_and_flag(info, data, TTY_PARITY);
-				else if (rstat & SER_OVERRUN_MASK)
+				} else if (rstat & SER_OVERRUN_MASK) {
+					info->icount.overrun++;
 					add_char_and_flag(info, data, TTY_OVERRUN);
-				else if (rstat & SER_FRAMING_ERR_MASK)
+				} else if (rstat & SER_FRAMING_ERR_MASK) {
+					info->icount.frame++;
 					add_char_and_flag(info, data, TTY_FRAME);
+				}
+				
 				info->errorcode = 0;
 			}
 			info->break_detected_cnt = 0;
@@ -2145,7 +3071,7 @@
 			if (elapsed_usec < 2*info->char_time_usec) {
 				DEBUG_LOG(info->line, "FBRK %i\n", info->line);
 				/* Report as BREAK (error) and let
-				 * receive_chars() handle it
+				 * receive_chars_dma() handle it
 				 */
 				info->errorcode = ERRCODE_SET_BREAK;
 			} else {
@@ -2155,38 +3081,195 @@
 		}
 
 #ifdef SERIAL_DEBUG_INTR
-		printk("** OK, disabling ser_interupts\n");
+		printk("** OK, disabling ser_interrupts\n");
 #endif
 		e100_disable_serial_data_irq(info);
-
+		DINTR2(DEBUG_LOG(info->line, "ser_rx OK %d\n", info->line));			
 		info->break_detected_cnt = 0;
 
 		PROCSTAT(ser_stat[info->line].ser_ints_ok_cnt++);
-		DEBUG_LOG(info->line, "ser_int OK %d\n", info->line);
 	}
-
 	/* Restarting the DMA never hurts */
 	*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart);
 	START_FLUSH_FAST_TIMER(info, "ser_int");
-} /* handle_ser_interrupt */
+	return info;
+} /* handle_ser_rx_interrupt */
+
+extern _INLINE_ void handle_ser_tx_interrupt(struct e100_serial *info)
+{
+	unsigned long flags;
+	
+	if (info->x_char) {
+		unsigned char rstat;
+		DFLOW(DEBUG_LOG(info->line, "tx_int: xchar 0x%02X\n", info->x_char));
+		save_flags(flags); cli();
+		rstat = info->port[REG_STATUS];
+		DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat));
+				
+		info->port[REG_TR_DATA] = info->x_char;
+		info->icount.tx++;
+		info->x_char = 0;
+		/* We must enable since it is disabled in ser_interrupt */
+		e100_enable_serial_tx_ready_irq(info);
+		restore_flags(flags);
+		return;
+	} 
+	if (info->uses_dma_out) {
+		unsigned char rstat;
+		int i;
+		/* We only use normal tx interrupt when sending x_char */
+		DFLOW(DEBUG_LOG(info->line, "tx_int: xchar sent\n", 0));
+		save_flags(flags); cli();
+		rstat = info->port[REG_STATUS];
+		DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat));
+		e100_disable_serial_tx_ready_irq(info);
+		if (info->tty->stopped)
+			rs_stop(info->tty);
+		/* Enable the DMA channel and tell it to continue */
+		e100_enable_txdma_channel(info);
+		/* Wait 12 cycles before doing the DMA command */
+		for(i = 6;  i > 0; i--)
+			nop();
+		
+		*info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, continue); 
+		restore_flags(flags);
+		return;
+	}
+	/* Normal char-by-char interrupt */
+	if (info->xmit.head == info->xmit.tail
+	    || info->tty->stopped
+	    || info->tty->hw_stopped) {
+		DFLOW(DEBUG_LOG(info->line, "tx_int: stopped %i\n", info->tty->stopped));
+		e100_disable_serial_tx_ready_irq(info);
+		info->tr_running = 0;
+		return;
+	}
+	DINTR2(DEBUG_LOG(info->line, "tx_int %c\n", info->xmit.buf[info->xmit.tail]));
+	/* Send a byte, rs485 timing is critical so turn of ints */
+	save_flags(flags); cli();
+	info->port[REG_TR_DATA] = info->xmit.buf[info->xmit.tail];
+	info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
+	info->icount.tx++;
+	if (info->xmit.head == info->xmit.tail) {
+#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_FAST_TIMER)
+		if (info->rs485.enabled) {
+			/* Set a short timer to toggle RTS */
+			start_one_shot_timer(&fast_timers_rs485[info->line],
+			                     rs485_toggle_rts_timer_function,
+			                     (unsigned long)info,
+			                     info->char_time_usec*2,
+			                     "RS-485");
+		}
+#endif /* RS485 */
+		info->last_tx_active_usec = GET_JIFFIES_USEC();
+		info->last_tx_active = jiffies;
+		e100_disable_serial_tx_ready_irq(info);
+		DFLOW(DEBUG_LOG(info->line, "tx_int: stop2\n", 0));
+	} else {
+		/* We must enable since it is disabled in ser_interrupt */
+		e100_enable_serial_tx_ready_irq(info);
+	}
+	restore_flags(flags);
+	
+	if (CIRC_CNT(info->xmit.head,
+		     info->xmit.tail,
+		     SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
+		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
 
+} /* handle_ser_tx_interrupt */
+
+/* result of time measurements:
+ * RX duration 54-60 us when doing something, otherwise 6-9 us
+ * ser_int duration: just sending: 8-15 us normally, up to 73 us
+ */
 static void 
 ser_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
+	static volatile int tx_started = 0;
 	struct e100_serial *info;
 	int i;
-
+	unsigned long flags;
+	unsigned long irq_mask1_rd;
+	unsigned long data_mask = (1 << (8+2*0)); /* ser0 data_avail */
+	static volatile unsigned long reentered_ready_mask = 0;
+	
+	save_flags(flags); cli();
+	irq_mask1_rd = *R_IRQ_MASK1_RD;
+	/* First handle all rx interrupts with ints disabled */
+	info = rs_table;
+	irq_mask1_rd &= e100_ser_int_mask;
 	for (i = 0; i < NR_PORTS; i++) {
-		info = rs_table + i;
-
-		if (!info->enabled || !info->uses_dma) 
-			continue; 
-
-		/* Which line caused the irq? */
-		if (*R_IRQ_MASK1_RD & (1U << (8+2*info->line))) { 
-			handle_ser_interrupt(info);
+		/* Which line caused the data irq? */
+		if (irq_mask1_rd & data_mask) { 
+			handle_ser_rx_interrupt(info);
 		}
+		info += 1;
+		data_mask <<= 2;
 	}
+	/* Handle tx interrupts with interrupts enabled so we
+	 * can take care of new data interrupts while transmitting
+	 * We protect the tx part with the tx_started flag.
+	 * We disable the tr_ready interrupts we are about to handle and
+	 * unblock the serial interrupt so new serial interrupts may come.
+	 *
+	 * If we get a new interrupt:
+	 *  - it migth be due to synchronous serial ports.
+	 *  - serial irq will be blocked by general irq handler.
+	 *  - async data will be handled above (sync will be ignored).
+	 *  - tx_started flag will prevent us from trying to send again and
+	 *    we will exit fast - no need to unblock serial irq.
+	 *  - Next (sync) serial interrupt handler will be runned with
+	 *    disabled interrupt due to restore_flags() at end of function,
+	 *    so sync handler will not be preempted or reentered.
+	 */
+	if (!tx_started) {
+		unsigned long ready_mask;
+		unsigned long 
+		tx_started = 1;
+		/* Only the tr_ready interrupts left */
+		irq_mask1_rd &= (IO_MASK(R_IRQ_MASK1_RD, ser0_ready) |
+				 IO_MASK(R_IRQ_MASK1_RD, ser1_ready) |
+				 IO_MASK(R_IRQ_MASK1_RD, ser2_ready) |
+				 IO_MASK(R_IRQ_MASK1_RD, ser3_ready));
+		while (irq_mask1_rd) {
+			/* Disable those we are about to handle */
+			*R_IRQ_MASK1_CLR = irq_mask1_rd;
+			/* Unblock the serial interrupt */
+			*R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set);
+			
+			sti();
+			ready_mask = (1 << (8+1+2*0)); /* ser0 tr_ready */
+			info = rs_table;
+			for (i = 0; i < NR_PORTS; i++) {
+				/* Which line caused the ready irq? */
+				if (irq_mask1_rd & ready_mask) { 
+					handle_ser_tx_interrupt(info);
+				}
+				info += 1;
+				ready_mask <<= 2;
+			}
+			/* handle_ser_tx_interrupt enables tr_ready interrupts */
+			cli();
+			/* Handle reentered TX interrupt */
+			irq_mask1_rd = reentered_ready_mask;
+		}
+		cli();	
+		tx_started = 0;
+	} else {
+		unsigned long ready_mask;
+		ready_mask = irq_mask1_rd & (IO_MASK(R_IRQ_MASK1_RD, ser0_ready) |
+					     IO_MASK(R_IRQ_MASK1_RD, ser1_ready) |
+					     IO_MASK(R_IRQ_MASK1_RD, ser2_ready) |
+					     IO_MASK(R_IRQ_MASK1_RD, ser3_ready));
+		if (ready_mask) {
+			reentered_ready_mask |= ready_mask;
+			/* Disable those we are about to handle */
+			*R_IRQ_MASK1_CLR = ready_mask;
+			DFLOW(DEBUG_LOG(SERIAL_DEBUG_LINE, "ser_int reentered with TX %X\n", ready_mask));
+		}
+	}
+	
+	restore_flags(flags);
 } /* ser_interrupt */
 #endif
 
@@ -2288,25 +3371,40 @@
 	 * Reset the DMA channels and make sure their interrupts are cleared
 	 */
 
-	info->uses_dma = 1;
-	*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
-	*info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
-
-	/* Wait until reset cycle is complete */
-	while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) ==
-	       IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
-
-	while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) ==
-	       IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
+	if (info->dma_in_enabled) {
+		info->uses_dma_in = 1;
+		e100_enable_rxdma_channel(info);
+		
+		*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
 
-	/* Make sure the irqs are cleared */
-	*info->iclrintradr =
-		IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
-		IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
-	*info->oclrintradr =
-		IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
-		IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
+		/* Wait until reset cycle is complete */
+		while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) ==
+		       IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
+
+		/* Make sure the irqs are cleared */
+		*info->iclrintradr =
+			IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
+			IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
+	} else {
+		e100_disable_rxdma_channel(info);
+	}
+	
+	if (info->dma_out_enabled) {
+		info->uses_dma_out = 1;
+		e100_enable_txdma_channel(info);
+		*info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
+		
+		while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) ==
+		       IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
 
+		/* Make sure the irqs are cleared */
+		*info->oclrintradr =
+			IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
+			IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
+	} else {
+		e100_disable_txdma_channel(info);
+	}
+	
 	if (info->tty)
 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
 
@@ -2321,8 +3419,10 @@
 	 * and set the speed and other flags of the serial port
 	 * this will start the rx/tx as well
 	 */
+	
 #ifdef SERIAL_HANDLE_EARLY_ERRORS
-	e100_enable_serial_data_irq(info);
+	if (info->uses_dma_in)
+		e100_enable_serial_data_irq(info);
 #endif	
 	change_speed(info);
 
@@ -2331,9 +3431,10 @@
 	(void)info->port[REG_DATA];
 
 	/* enable the interrupts */
+	if (info->uses_dma_out)
+		e100_enable_txdma_irq(info);
 
-	e100_enable_txdma_irq(info);
-	e100_enable_rxdma_irq(info);
+	e100_enable_rx_irq(info);
 
 	info->tr_running = 0; /* to be sure we don't lock up the transmitter */
 
@@ -2342,10 +3443,10 @@
 	start_receive(info);
 	
 	/* for safety, make sure the descriptors last result is 0 bytes written */
-	
 	info->tr_descr.sw_len = 0;
 	info->tr_descr.hw_len = 0;
 	info->tr_descr.status = 0;
+	
 
 	/* enable RTS/DTR last */
 
@@ -2374,20 +3475,28 @@
 
 #ifndef CONFIG_SVINTO_SIM	
 	/* shut down the transmitter and receiver */
-
+	DFLOW(DEBUG_LOG(info->line, "shutdown %i\n", info->line));
 	e100_disable_rx(info);
 	info->port[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40);
 
-	e100_disable_rxdma_irq(info);
-	e100_disable_txdma_irq(info);
-
-	info->tr_running = 0;
-
-	/* reset both dma channels */
-
-	*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
-	*info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
-	info->uses_dma = 0;
+	/* disable interrupts, reset dma channels */
+	if (info->uses_dma_in) {
+		e100_disable_rxdma_irq(info);
+		*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
+		info->uses_dma_in = 0;
+	} else {
+		e100_disable_serial_data_irq(info);
+	}
+	
+	if (info->uses_dma_out) {
+		e100_disable_txdma_irq(info);
+		info->tr_running = 0;
+		*info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
+		info->uses_dma_out = 0;
+	} else {
+		e100_disable_serial_tx_ready_irq(info);
+		info->tr_running = 0;		
+	}
 
 #endif /* CONFIG_SVINTO_SIM */
 
@@ -2435,7 +3544,7 @@
 {
 	unsigned int cflag;
 	unsigned long xoff;
-
+	unsigned long flags;
 	/* first some safety checks */
 	
 	if (!info->tty || !info->tty->termios)
@@ -2444,17 +3553,80 @@
 		return;
 	
 	cflag = info->tty->termios->c_cflag;
-	
+
 	/* possibly, the tx/rx should be disabled first to do this safely */
 	
 	/* change baud-rate and write it to the hardware */
-	
-	info->baud = cflag_to_baud(cflag);
+	if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) {
+		/* Special baudrate */
+		u32 mask = 0xFF << (info->line*8); /* Each port has 8 bits */
+		unsigned long alt_source = 
+				IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, normal) |
+				IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, normal);
+		/* R_ALT_SER_BAUDRATE selects the source */
+		DBAUD(printk("Custom baudrate: baud_base/divisor %lu/%i\n",
+		       (unsigned long)info->baud_base, info->custom_divisor));
+		if (info->baud_base == SERIAL_PRESCALE_BASE) {
+			/* 0, 2-65535 (0=65536) */
+			u16 divisor = info->custom_divisor;
+			/* R_SERIAL_PRESCALE (upper 16 bits of R_CLOCK_PRESCALE) */
+			/* baudrate is 3.125MHz/custom_divisor */
+			alt_source = 
+				IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, prescale) |
+				IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, prescale);
+			alt_source = 0x11;
+			DBAUD(printk("Writing SERIAL_PRESCALE: divisor %i\n", divisor));
+			*R_SERIAL_PRESCALE = divisor;
+			info->baud = SERIAL_PRESCALE_BASE/divisor;
+		}
+#ifdef CONFIG_ETRAX_EXTERN_PB6CLK_ENABLED
+		else if ((info->baud_base==CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8 &&
+			  info->custom_divisor == 1) ||
+			 (info->baud_base==CONFIG_ETRAX_EXTERN_PB6CLK_FREQ &&
+			  info->custom_divisor == 8)) {
+				/* ext_clk selected */
+				alt_source = 
+					IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, extern) |
+					IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, extern);
+				DBAUD(printk("using external baudrate: %lu\n", CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8));
+				info->baud = CONFIG_ETRAX_EXTERN_PB6CLK_FREQ/8;
+			}
+		}
+#endif
+		else
+		{
+			/* Bad baudbase, we don't support using timer0
+			 * for baudrate.
+			 */
+			printk(KERN_WARNING "Bad baud_base/custom_divisor: %lu/%i\n",
+			       (unsigned long)info->baud_base, info->custom_divisor);
+		}
+		r_alt_ser_baudrate_shadow &= ~mask;
+		r_alt_ser_baudrate_shadow |= (alt_source << (info->line*8));
+		*R_ALT_SER_BAUDRATE = r_alt_ser_baudrate_shadow;
+	} else {
+		/* Normal baudrate */
+		/* Make sure we use normal baudrate */
+		u32 mask = 0xFF << (info->line*8); /* Each port has 8 bits */
+		unsigned long alt_source = 
+			IO_STATE(R_ALT_SER_BAUDRATE, ser0_rec, normal) |
+			IO_STATE(R_ALT_SER_BAUDRATE, ser0_tr, normal);
+		r_alt_ser_baudrate_shadow &= ~mask;
+		r_alt_ser_baudrate_shadow |= (alt_source << (info->line*8));
+#ifndef CONFIG_SVINTO_SIM
+		*R_ALT_SER_BAUDRATE = r_alt_ser_baudrate_shadow;
+#endif /* CONFIG_SVINTO_SIM */ 
+
+		info->baud = cflag_to_baud(cflag);
+#ifndef CONFIG_SVINTO_SIM
+		info->port[REG_BAUD] = cflag_to_etrax_baud(cflag);
+#endif /* CONFIG_SVINTO_SIM */
+	}
 	
 #ifndef CONFIG_SVINTO_SIM
-	info->port[REG_BAUD] = cflag_to_etrax_baud(cflag);
 	/* start with default settings and then fill in changes */
-
+	save_flags(flags);
+	cli();
 	/* 8 bit, no/even parity */
 	info->rx_ctrl &= ~(IO_MASK(R_SERIAL0_REC_CTRL, rec_bitnr) |
 			   IO_MASK(R_SERIAL0_REC_CTRL, rec_par_en) |
@@ -2484,14 +3656,26 @@
 		info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable);
 	}
 	
-	if (cflag & PARODD) {
-		/* set odd parity */
-		info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd);
-		info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd);
+	if (cflag & CMSPAR) {
+		/* enable stick parity */
+		info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_stick_par, stick);
+		info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, stick);
+		if (!(cflag & PARODD)) {
+			/* set mark parity */
+			info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd);
+			info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd);
+		}
+	} else {
+		if (cflag & PARODD) {
+			/* set odd parity */
+			info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd);
+			info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd);
+		}
 	}
 	
 	if (cflag & CRTSCTS) {
 		/* enable automatic CTS handling */
+		DFLOW(DEBUG_LOG(info->line, "FLOW auto_cts enabled\n", 0));
 		info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, active);
 	}
 	
@@ -2507,10 +3691,12 @@
 	xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->tty));
 	xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable);
 	if (info->tty->termios->c_iflag & IXON ) {
+		DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n", STOP_CHAR(info->tty)));
 		xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
 	}
 	
 	*((unsigned long *)&info->port[REG_XOFF]) = xoff;
+	restore_flags(flags);
 #endif /* !CONFIG_SVINTO_SIM */
 
 	update_char_time(info);
@@ -2543,8 +3729,8 @@
 	restore_flags(flags);
 }
 
-extern inline int 
-raw_write(struct tty_struct * tty, int from_user,
+extern _INLINE_ int 
+rs_raw_write(struct tty_struct * tty, int from_user,
 	  const unsigned char *buf, int count)
 {
 	int	c, ret = 0;
@@ -2558,7 +3744,7 @@
 	
 #ifdef SERIAL_DEBUG_DATA
 	if (info->line == SERIAL_DEBUG_LINE)
-		printk("raw_write (%d), status %d\n", 
+		printk("rs_raw_write (%d), status %d\n", 
 		       count, info->port[REG_STATUS]);
 #endif
 
@@ -2568,6 +3754,9 @@
 	return count;
 #endif
 	save_flags(flags);
+
+	DFLOW(DEBUG_LOG(info->line, "write count %i ", count));
+	DFLOW(DEBUG_LOG(info->line, "ldisc %i\n", tty->ldisc.chars_in_buffer(tty)));
 	
 	/* the cli/restore_flags pairs below are needed because the
 	 * DMA interrupt handler moves the info->xmit values. the memcpy
@@ -2635,6 +3824,7 @@
 	 * this does not need IRQ protection since if tr_running == 0
 	 * the IRQ's are not running anyway for this port.
 	 */
+	DFLOW(DEBUG_LOG(info->line, "write ret %i\n", ret));
 	
 	if (info->xmit.head != info->xmit.tail &&
 	    !tty->stopped &&
@@ -2644,7 +3834,7 @@
 	}
  	
 	return ret;
-} /* raw_write() */
+} /* rs_raw_write() */
 
 static int 
 rs_write(struct tty_struct * tty, int from_user,
@@ -2666,7 +3856,7 @@
 		e100_rts(info, info->rs485.rts_on_send);
 #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
 		e100_disable_rx(info);
-		e100_disable_rxdma_irq(info);
+		e100_disable_rx_irq(info);
 #endif
 
 		if (info->rs485.delay_rts_before_send > 0) {
@@ -2676,7 +3866,7 @@
 	}
 #endif /* CONFIG_ETRAX_RS485 */
 
-	count = raw_write(tty, from_user, buf, count);
+	count = rs_raw_write(tty, from_user, buf, count);
 
 #if defined(CONFIG_ETRAX_RS485)
 	if (info->rs485.enabled)
@@ -2704,7 +3894,7 @@
 	
 #if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
 		e100_enable_rx(info);
-		e100_enable_rxdma_irq(info);
+		e100_enable_rx_irq(info);
 #endif
 	}
 #endif /* CONFIG_ETRAX_RS485 */
@@ -2760,20 +3950,33 @@
  * This function is used to send a high-priority XON/XOFF character to
  * the device
  *
- * Since we don't bother to check for info->x_char in transmit_chars yet,
- * we don't really implement this function yet.
+ * Since we use DMA we don't check for info->x_char in transmit_chars_dma(),
+ * but we do it in handle_ser_tx_interrupt().
+ * We disable DMA channel and enable tx ready interrupt and write the
+ * character when possible.
  */
 static void rs_send_xchar(struct tty_struct *tty, char ch)
 {
 	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+	unsigned long flags;
+	save_flags(flags); cli();
+	if (info->uses_dma_out) {
+		/* Put the DMA on hold and disable the channel */
+		*info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, hold); 
+		while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) !=
+		       IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, hold));
+		e100_disable_txdma_channel(info);
+	}
+	
+	/* Must make sure transmitter is not stopped before we can transmit */
+	if (tty->stopped)
+		rs_start(tty);
 
-	printk("serial.c:rs_send_xchar not implemented!\n");
-
+	/* Enable manual transmit interrupt and send from there */
+	DFLOW(DEBUG_LOG(info->line, "rs_send_xchar 0x%02X\n", ch));
 	info->x_char = ch;
-	if (ch) {
-		/* Make sure transmit interrupts are on */
-		/* TODO. */
-	}
+	e100_enable_serial_tx_ready_irq(info);
+	restore_flags(flags);
 }
 
 /*
@@ -2788,50 +3991,49 @@
 rs_throttle(struct tty_struct * tty)
 {
 	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
-	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
 
-	printk("throttle %s: %d....\n", _tty_name(tty, buf),
-	       tty->ldisc.chars_in_buffer(tty));
+	printk("throttle %s: %lu....\n", tty_name(tty, buf),
+	       (unsigned long)tty->ldisc.chars_in_buffer(tty));
 #endif
-
+	DFLOW(DEBUG_LOG(info->line,"rs_throttle %lu\n", tty->ldisc.chars_in_buffer(tty)));
+	
+	/* Do RTS before XOFF since XOFF might take some time */
+	if (tty->termios->c_cflag & CRTSCTS) {
+		/* Turn off RTS line */
+		e100_rts(info, 0);
+	}
 	if (I_IXOFF(tty))
-		info->x_char = STOP_CHAR(tty);
+		rs_send_xchar(tty, STOP_CHAR(tty));
 
-	/* Turn off RTS line (do this atomic) should here be an else ?? */
-
-	save_flags(flags); 
-	cli();
-	e100_rts(info, 0);
-	restore_flags(flags);
 }
 
 static void 
 rs_unthrottle(struct tty_struct * tty)
 {
 	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
-	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
 
-	printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
-	       tty->ldisc.chars_in_buffer(tty));
+	printk("unthrottle %s: %lu....\n", tty_name(tty, buf),
+	       (unsigned long)tty->ldisc.chars_in_buffer(tty));
 #endif
+	DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc %d\n", tty->ldisc.chars_in_buffer(tty)));
+	DFLOW(DEBUG_LOG(info->line,"rs_unthrottle flip.count: %i\n", tty->flip.count));	
+	/* Do RTS before XOFF since XOFF might take some time */
+	if (tty->termios->c_cflag & CRTSCTS) {
+		/* Assert RTS line  */
+		e100_rts(info, 1);
+	}
 
 	if (I_IXOFF(tty)) {
 		if (info->x_char)
 			info->x_char = 0;
 		else
-			info->x_char = START_CHAR(tty);
+			rs_send_xchar(tty, START_CHAR(tty));
 	}
 
-	/* Assert RTS line (do this atomic) */
-
-	save_flags(flags); 
-	cli();
-	e100_rts(info, 1);
-	restore_flags(flags);
 }
 
 /*
@@ -2859,8 +4061,10 @@
 	tmp.port = (int)info->port;
 	tmp.irq = info->irq;
 	tmp.flags = info->flags;
+	tmp.baud_base = info->baud_base;
 	tmp.close_delay = info->close_delay;
 	tmp.closing_wait = info->closing_wait;
+	tmp.custom_divisor = info->custom_divisor;
 	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
 		return -EFAULT;
 	return 0;
@@ -2897,9 +4101,11 @@
 	 * OK, past this point, all the error checking has been done.
 	 * At this point, we start making changes.....
 	 */
-	
+
+	info->baud_base = new_serial.baud_base;	
 	info->flags = ((info->flags & ~ASYNC_FLAGS) |
 		       (new_serial.flags & ASYNC_FLAGS));
+	info->custom_divisor = new_serial.custom_divisor;
 	info->type = new_serial.type;
 	info->close_delay = new_serial.close_delay;
 	info->closing_wait = new_serial.closing_wait;
@@ -3098,18 +4304,20 @@
 
 	info->tx_ctrl &= 0x3F; /* Clear bit 7 (txd) and 6 (tr_enable) */
 	info->port[REG_TR_CTRL] = info->tx_ctrl;
-
+	restore_flags(flags);
 	/* wait for "duration" jiffies */
 
 	schedule();
 
+	cli();
 	info->tx_ctrl |= (0x80 | 0x40); /* Set bit 7 (txd) and 6 (tr_enable) */
 	info->port[REG_TR_CTRL] = info->tx_ctrl;
 
 	/* the DMA gets awfully confused if we toggle the tranceiver like this 
 	 * so we need to reset it 
 	 */
-	*info->ocmdadr = 4;
+	if (info->uses_dma_out)
+		*info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
 
 	restore_flags(flags);
 }
@@ -3252,6 +4460,7 @@
 
 	change_speed(info);
 
+	/* Handle turning off CRTSCTS */
 	if ((old_termios->c_cflag & CRTSCTS) &&
 	    !(tty->termios->c_cflag & CRTSCTS)) {
 		tty->hw_stopped = 0;
@@ -3301,12 +4510,13 @@
 		 * one, we've got real problems, since it means the
 		 * serial port won't be shutdown.
 		 */
-		printk("rs_close: bad serial port count; tty->count is 1, "
+		printk(KERN_CRIT
+		       "rs_close: bad serial port count; tty->count is 1, "
 		       "info->count is %d\n", info->count);
 		info->count = 1;
 	}
 	if (--info->count < 0) {
-		printk("rs_close: bad serial port count for ttyS%d: %d\n",
+		printk(KERN_CRIT "rs_close: bad serial port count for ttyS%d: %d\n",
 		       info->line, info->count);
 		info->count = 0;
 	}
@@ -3340,7 +4550,7 @@
 
 #ifndef CONFIG_SVINTO_SIM
 	e100_disable_rx(info);
-	e100_disable_rxdma_irq(info);
+	e100_disable_rx_irq(info);
 
 	if (info->flags & ASYNC_INITIALIZED) {
 		/*
@@ -3676,6 +4886,12 @@
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_open ttyS%d successful...\n", info->line);
 #endif
+	DLOG_INT_TRIG( log_int_pos = 0);
+
+	DFLIP(	if (info->line == SERIAL_DEBUG_LINE) {
+			info->icount.rx = 0;
+		} );
+	
 	return 0;
 }
 
@@ -3683,11 +4899,12 @@
  * /proc fs routines....
  */
 
-extern inline int line_info(char *buf, struct e100_serial *info)
+extern _INLINE_ int line_info(char *buf, struct e100_serial *info)
 {
 	char	stat_buf[30];
 	int	ret;
-
+	unsigned long tmp;
+	
 	ret = sprintf(buf, "%d: uart:E100 port:%lX irq:%d",
 		      info->line, (unsigned long)info->port, info->irq);
 
@@ -3716,11 +4933,39 @@
 	ret += sprintf(buf+ret, " tx:%lu rx:%lu",
 		       (unsigned long)info->icount.tx,
 		       (unsigned long)info->icount.rx);
-
+	tmp = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+	if (tmp) {
+		ret += sprintf(buf+ret, " tx_pend:%lu/%lu",
+			       (unsigned long)tmp,
+			       (unsigned long)SERIAL_XMIT_SIZE);
+	}
+	
 	ret += sprintf(buf+ret, " rx_pend:%lu/%lu",
 		       (unsigned long)info->recv_cnt,
 		       (unsigned long)info->max_recv_cnt);
 
+#if 1
+	if (info->tty) {
+		
+		if (info->tty->stopped)
+			ret += sprintf(buf+ret, " stopped:%i",
+				       (int)info->tty->stopped);
+		if (info->tty->hw_stopped)
+			ret += sprintf(buf+ret, " hw_stopped:%i",
+				       (int)info->tty->hw_stopped);
+	}
+	
+	{
+		unsigned char rstat = info->port[REG_STATUS];
+		if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) )
+			ret += sprintf(buf+ret, " xoff_detect:1");
+	}
+	
+#endif
+	
+
+
+	
 	if (info->icount.frame)
 		ret += sprintf(buf+ret, " fe:%lu",
 			       (unsigned long)info->icount.frame);
@@ -3744,12 +4989,14 @@
 	return ret;
 }
 
+
+
 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, "serinfo:1.0 driver:%s\n",
 		       serial_version);
 	for (i = 0; i < NR_PORTS && len < 4000; i++) {
@@ -3764,6 +5011,22 @@
 			len = 0;
 		}
 	}
+#ifdef DEBUG_LOG_INCLUDED
+	for (i = 0; i < debug_log_pos; i++) {
+		len += sprintf(page + len, "%-4i %lu.%lu ", i, debug_log[i].time, timer_data_to_ns(debug_log[i].timer_data));
+		len += sprintf(page + len, debug_log[i].string, debug_log[i].value);
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	len += sprintf(page + len, "debug_log %i/%i  %li bytes\n",
+		       i, DEBUG_LOG_SIZE, begin+len);
+	debug_log_pos = 0;
+#endif
+
 	*eof = 1;
 done:
 	if (off >= len+begin)
@@ -3777,7 +5040,8 @@
 static void 
 show_serial_version(void)
 {
-	printk("ETRAX 100LX serial-driver %s, (c) 2000-2002 Axis Communications AB\r\n",
+	printk(KERN_INFO
+	       "ETRAX 100LX serial-driver %s, (c) 2000-2003 Axis Communications AB\r\n",
 	       &serial_version[11]); /* "$Revision: x.yy" */
 }
 
@@ -3794,7 +5058,7 @@
 	init_bh(SERIAL_BH, do_serial_bh);
 
 	/* Setup the timed flush handler system */
-
+	
 #if !defined(CONFIG_ETRAX_SERIAL_FAST_TIMER) && !defined(CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST)
 	init_timer(&flush_timer);
 	flush_timer.function = timed_flush_handler;
@@ -3868,12 +5132,15 @@
 	/* do some initializing for the separate ports */
   
 	for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
-		info->uses_dma = 0;   
+		info->uses_dma_in = 0;
+		info->uses_dma_out = 0;
 		info->line = i;
 		info->tty = 0;
 		info->type = PORT_ETRAX;
 		info->tr_running = 0;
 		info->forced_eop = 0;
+		info->baud_base = DEF_BAUD_BASE;
+		info->custom_divisor = 0;		
 		info->flags = 0;
 		info->close_delay = 5*HZ/10;
 		info->closing_wait = 30*HZ;
@@ -3920,41 +5187,58 @@
 #ifndef CONFIG_SVINTO_SIM
 	/* Not needed in simulator.  May only complicate stuff. */
 	/* hook the irq's for DMA channel 6 and 7, serial output and input, and some more... */
+
+	if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial ", NULL))
+		panic("irq8");
+	
 #ifdef CONFIG_ETRAX_SERIAL_PORT0
+#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT
 	if (request_irq(SER0_DMA_TX_IRQ_NBR, tr_interrupt, SA_INTERRUPT, "serial 0 dma tr", NULL))
 		panic("irq22");
+#endif
+#ifdef CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN
 	if (request_irq(SER0_DMA_RX_IRQ_NBR, rec_interrupt, SA_INTERRUPT, "serial 0 dma rec", NULL))
 		panic("irq23");
 #endif
-#ifdef SERIAL_HANDLE_EARLY_ERRORS
-	if (request_irq(SERIAL_IRQ_NBR, ser_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial ", NULL))
-		panic("irq8");
 #endif
+
 #ifdef CONFIG_ETRAX_SERIAL_PORT1
+#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT
 	if (request_irq(SER1_DMA_TX_IRQ_NBR, tr_interrupt, SA_INTERRUPT, "serial 1 dma tr", NULL))
 		panic("irq24");
+#endif
+#ifdef CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN
 	if (request_irq(SER1_DMA_RX_IRQ_NBR, rec_interrupt, SA_INTERRUPT, "serial 1 dma rec", NULL))
 		panic("irq25");
 #endif
+#endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT2
 	/* DMA Shared with par0 (and SCSI0 and ATA) */
-	if (request_irq(SER2_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ, "serial 2 dma tr", NULL))
+#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT
+	if (request_irq(SER2_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial 2 dma tr", NULL))
 		panic("irq18");
-	if (request_irq(SER2_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ, "serial 2 dma rec", NULL))
+#endif
+#ifdef CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN
+	if (request_irq(SER2_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial 2 dma rec", NULL))
 		panic("irq19");
 #endif
+#endif
 #ifdef CONFIG_ETRAX_SERIAL_PORT3
 	/* DMA Shared with par1 (and SCSI1 and Extern DMA 0) */
-	if (request_irq(SER3_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ, "serial 3 dma tr", NULL))
+#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT
+	if (request_irq(SER3_DMA_TX_IRQ_NBR, tr_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial 3 dma tr", NULL))
 		panic("irq20");
-	if (request_irq(SER3_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ, "serial 3 dma rec", NULL))
+#endif
+#ifdef CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN
+	if (request_irq(SER3_DMA_RX_IRQ_NBR, rec_interrupt, SA_SHIRQ | SA_INTERRUPT, "serial 3 dma rec", NULL))
 		panic("irq21");
 #endif
+#endif
 
 #ifdef CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST
 	if (request_irq(TIMER1_IRQ_NBR, timeout_interrupt, SA_SHIRQ | SA_INTERRUPT,
 		       "fast serial dma timeout", NULL)) {
-		printk("err: timer1 irq\n");
+		printk(KERN_CRIT "err: timer1 irq\n");
 	}
 #endif
 #endif /* CONFIG_SVINTO_SIM */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/serial.h linux-2.4.22-pre10/arch/cris/drivers/serial.h
--- linux-2.4.21/arch/cris/drivers/serial.h	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/serial.h	2003-08-01 13:34:30.000000000 +0000
@@ -23,7 +23,7 @@
  * For definitions of the flags field, see tty.h
  */
 
-#define SERIAL_RECV_DESCRIPTORS 8
+#define SERIAL_RECV_DESCRIPTORS 16
 
 struct etrax_recv_buffer {
 	struct etrax_recv_buffer *next;
@@ -44,30 +44,29 @@
 	volatile u32		*ofirstadr;   /* adr to R_DMA_CHx_FIRST */
 	volatile u8		*ocmdadr;     /* adr to R_DMA_CHx_CMD */
 	const volatile u8	*ostatusadr;  /* adr to R_DMA_CHx_STATUS */
-	volatile u32		*ohwswadr;    /* adr to R_DMA_CHx_HWSW */
-	volatile u32		*odescradr;   /* adr to R_DMA_CHx_DESCR */
 
 	/* Input registers */
 	volatile u8		*iclrintradr; /* adr to R_DMA_CHx_CLR_INTR */
 	volatile u32		*ifirstadr;   /* adr to R_DMA_CHx_FIRST */
 	volatile u8		*icmdadr;     /* adr to R_DMA_CHx_CMD */
-	const volatile u8	*istatusadr;  /* adr to R_DMA_CHx_STATUS */
-	volatile u32		*ihwswadr;    /* adr to R_DMA_CHx_HWSW */
 	volatile u32		*idescradr;   /* adr to R_DMA_CHx_DESCR */
 
 	int			flags;	/* defined in tty.h */
 
-	u8			rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */
-	u8			tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */
-	u8			iseteop; /* bit number for R_SET_EOP for the input dma */
-
-	int			enabled; /* Set to 1 if the port is enabled in HW config */
-  
+	u8		rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */
+	u8		tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */
+	u8		iseteop; /* bit number for R_SET_EOP for the input dma */
+	u8		enabled; /* Set to 1 if the port is enabled in HW config */
+	
+	u8		dma_out_enabled:1; /* Set to 1 if DMA should be used */
+	u8		dma_in_enabled:1;  /* Set to 1 if DMA should be used */
+	
 	/* end of fields defined in rs_table[] in .c-file */
-
-	int			uses_dma; /* Set to 1 if DMA should be used */
-	unsigned char           forced_eop; /* a fifo eop has been forced */
-
+	u8		uses_dma_in;  /* Set to 1 if DMA is used */
+	u8		uses_dma_out; /* Set to 1 if DMA is used */
+	u8		forced_eop;   /* a fifo eop has been forced */
+	int			baud_base;     /* For special baudrates */
+	int			custom_divisor; /* For special baudrates */
 	struct etrax_dma_descr	tr_descr;
 	struct etrax_dma_descr	rec_descr[SERIAL_RECV_DESCRIPTORS];
 	int			cur_rec_descr;
@@ -108,6 +107,7 @@
 #endif  
 
 	unsigned long		char_time_usec;       /* The time for 1 char, in usecs */
+	unsigned long		flush_time_usec;      /* How often we should flush */
 	unsigned long		last_tx_active_usec;  /* Last tx usec in the jiffies */
 	unsigned long		last_tx_active;       /* Last tx time in jiffies */
 	unsigned long		last_rx_active_usec;  /* Last rx usec in the jiffies */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/sync_serial.c linux-2.4.22-pre10/arch/cris/drivers/sync_serial.c
--- linux-2.4.21/arch/cris/drivers/sync_serial.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/sync_serial.c	2003-08-01 13:31:06.000000000 +0000
@@ -1,7 +1,7 @@
 /*  
  * Simple synchronous serial port driver for ETRAX 100LX.
  *
- * Synchronous serial ports are used for continous streamed data like audio.
+ * Synchronous serial ports are used for continuous streamed data like audio.
  * The default setting for this driver is compatible with the STA 013 MP3
  * decoder. The driver can easily be tuned to fit other audio encoder/decoders
  * and SPI
@@ -29,7 +29,7 @@
 #include <asm/system.h>
 #include <asm/sync_serial.h>
 
-/* The receiver is a bit tricky beacuse of the continous stream of data. */
+/* The receiver is a bit tricky beacuse of the continuous stream of data.*/
 /*                                                                       */
 /* Two DMA descriptors are linked together. Each DMA descriptor is       */
 /* responsible for one half of a common buffer.                          */
@@ -256,7 +256,7 @@
 	initialize_port(1);
 	if (ports[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */
 	{
-		if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[1]))
+		if (request_irq(8, manual_interrupt, SA_SHIRQ | SA_INTERRUPT, "synchronous serial manual irq", &ports[1]))
 			panic("Can't allocate sync serial manual irq");
 	}
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/usb-host.c linux-2.4.22-pre10/arch/cris/drivers/usb-host.c
--- linux-2.4.21/arch/cris/drivers/usb-host.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/usb-host.c	2003-08-01 13:32:18.000000000 +0000
@@ -1,10 +1,7 @@
 /*
  * usb-host.c: ETRAX 100LX USB Host Controller Driver (HCD)
  *
- * Copyright (c) 2001 Axis Communications AB.
- *
- * $Id: usb-host.c,v 1.13 2001/11/13 12:06:17 pkj Exp $
- *
+ * Copyright (c) 2002, 2003 Axis Communications AB.
  */
 
 #include <linux/config.h>
@@ -19,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/version.h>
 #include <linux/list.h>
+#include <linux/spinlock.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -28,24 +26,37 @@
 #include <asm/svinto.h>
 
 #include <linux/usb.h>
+/* Ugly include because we don't live with the other host drivers. */
+#include <../drivers/usb/hcd.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION (2, 4, 20)
+typedef struct urb urb_t, *purb_t;
+typedef struct iso_packet_descriptor iso_packet_descriptor_t;
+typedef struct usb_ctrlrequest devrequest;
+#endif
+
 #include "usb-host.h"
 
 #define ETRAX_USB_HC_IRQ USB_HC_IRQ_NBR
 #define ETRAX_USB_RX_IRQ USB_DMA_RX_IRQ_NBR
 #define ETRAX_USB_TX_IRQ USB_DMA_TX_IRQ_NBR
 
-static const char *usb_hcd_version = "$Revision: 1.13 $";
+static const char *usb_hcd_version = "$Revision: 1.18 $";
 
 #undef KERN_DEBUG
 #define KERN_DEBUG ""
 
+
 #undef USB_DEBUG_RH
-#undef USB_DEBUG_EP
+#undef USB_DEBUG_EPID
+#undef USB_DEBUG_SB
 #undef USB_DEBUG_DESC
+#undef USB_DEBUG_URB
 #undef USB_DEBUG_TRACE
-#undef USB_DEBUG_CTRL
 #undef USB_DEBUG_BULK
+#undef USB_DEBUG_CTRL
 #undef USB_DEBUG_INTR
+#undef USB_DEBUG_ISOC
 
 #ifdef USB_DEBUG_RH
 #define dbg_rh(format, arg...) printk(KERN_DEBUG __FILE__ ": (RH) " format "\n" , ## arg)
@@ -53,10 +64,16 @@
 #define dbg_rh(format, arg...) do {} while (0)
 #endif
 
-#ifdef USB_DEBUG_EP
-#define dbg_ep(format, arg...) printk(KERN_DEBUG __FILE__ ": (EP) " format "\n" , ## arg)
+#ifdef USB_DEBUG_EPID
+#define dbg_epid(format, arg...) printk(KERN_DEBUG __FILE__ ": (EPID) " format "\n" , ## arg)
 #else
-#define dbg_ep(format, arg...) do {} while (0)
+#define dbg_epid(format, arg...) do {} while (0)
+#endif
+
+#ifdef USB_DEBUG_SB
+#define dbg_sb(format, arg...) printk(KERN_DEBUG __FILE__ ": (SB) " format "\n" , ## arg)
+#else
+#define dbg_sb(format, arg...) do {} while (0)
 #endif
 
 #ifdef USB_DEBUG_CTRL
@@ -77,6 +94,12 @@
 #define dbg_intr(format, arg...) do {} while (0)
 #endif
 
+#ifdef USB_DEBUG_ISOC
+#define dbg_isoc(format, arg...) printk(KERN_DEBUG __FILE__ ": (ISOC) " format "\n" , ## arg)
+#else
+#define dbg_isoc(format, arg...) do {} while (0)
+#endif
+
 #ifdef USB_DEBUG_TRACE
 #define DBFENTER (printk(KERN_DEBUG __FILE__ ": Entering: " __FUNCTION__ "\n"))
 #define DBFEXIT  (printk(KERN_DEBUG __FILE__ ": Exiting:  " __FUNCTION__ "\n"))
@@ -85,6 +108,7 @@
 #define DBFEXIT  do {} while (0)
 #endif
 
+
 /*-------------------------------------------------------------------
  Virtual Root Hub
  -------------------------------------------------------------------*/
@@ -158,78 +182,262 @@
 	0xff   /*  __u8  PortPwrCtrlMask; *** 7 ports max *** */
 };
 
+static struct timer_list bulk_start_timer;
+static struct timer_list bulk_eot_timer;
+/* We want the start timer to expire before the eot timer, because the former might start
+   traffic, thus making it unnecessary for the latter to time out. */
+#define BULK_START_TIMER_INTERVAL (HZ/10) /* 100 ms */
+#define BULK_EOT_TIMER_INTERVAL (HZ/10+2) /* 120 ms */
 
 #define OK(x) len = (x); dbg_rh("OK(%d): line: %d", x, __LINE__); break
 #define CHECK_ALIGN(x) if (((__u32)(x)) & 0x00000003) \
 {panic("Alignment check (DWORD) failed at %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);}
 
-static unsigned long submit_urb_count = 0;
+#define SLAB_FLAG     (in_interrupt() ? SLAB_ATOMIC : SLAB_KERNEL)
+#define KMALLOC_FLAG  (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL)
+
+/* Most helpful debugging aid */
+#define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__))))
 
-//#define ETRAX_USB_INTR_IRQ
-//#define ETRAX_USB_INTR_ERROR_FATAL
+/* Alternative assert define which stops after a failed assert. */
+/*
+#define assert(expr)                                      \
+{                                                         \
+        if (!(expr)) {                                    \
+                err("assert failed at line %d",__LINE__); \
+                while (1);                                \
+        }                                                 \
+}
+*/
 
-#define RX_BUF_SIZE        32768
-#define RX_DESC_BUF_SIZE   64
-#define NBR_OF_RX_DESC     (RX_BUF_SIZE / RX_DESC_BUF_SIZE)
 
-#define NBR_OF_EP_DESC     32
+/* FIXME: Should RX_BUF_SIZE be a config option, or maybe we should adjust it dynamically?
+   To adjust it dynamically we would have to get an interrupt when we reach the end
+   of the rx descriptor list, or when we get close to the end, and then allocate more
+   descriptors. */
+
+#define NBR_OF_RX_DESC     512
+#define RX_DESC_BUF_SIZE   1024
+#define RX_BUF_SIZE        (NBR_OF_RX_DESC * RX_DESC_BUF_SIZE)
+
+/* The number of epids is, among other things, used for pre-allocating
+   ctrl, bulk and isoc EP descriptors (one for each epid).
+   Assumed to be > 1 when initiating the DMA lists. */
+#define NBR_OF_EPIDS       32
 
+/* Support interrupt traffic intervals up to 128 ms. */
 #define MAX_INTR_INTERVAL 128
 
-static __u32 ep_usage_bitmask;
-static __u32 ep_really_active;
-static __u32 ep_out_traffic;
-
-static unsigned char RxBuf[RX_BUF_SIZE];
-static USB_IN_Desc_t RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned (4)));
+/* If periodic traffic (intr or isoc) is to be used, then one entry in the EP table
+   must be "invalid". By this we mean that we shouldn't care about epid attentions
+   for this epid, or at least handle them differently from epid attentions for "valid"
+   epids. This define determines which one to use (don't change it). */   
+#define INVALID_EPID     31
+/* A special epid for the bulk dummys. */
+#define DUMMY_EPID       30
+
+/* This is just a software cache for the valid entries in R_USB_EPT_DATA. */
+static __u32 epid_usage_bitmask;
+
+/* A bitfield to keep information on in/out traffic is needed to uniquely identify
+   an endpoint on a device, since the most significant bit which indicates traffic
+   direction is lacking in the ep_id field (ETRAX epids can handle both in and
+   out traffic on endpoints that are otherwise identical). The USB framework, however,
+   relies on them to be handled separately.  For example, bulk IN and OUT urbs cannot
+   be queued in the same list, since they would block each other. */
+static __u32 epid_out_traffic;
+
+/* DMA IN cache bug. Align the DMA IN buffers to 32 bytes, i.e. a cache line.
+   Since RX_DESC_BUF_SIZE is 1024 is a multiple of 32, all rx buffers will be cache aligned. */
+static volatile unsigned char RxBuf[RX_BUF_SIZE] __attribute__ ((aligned (32)));
+static volatile USB_IN_Desc_t RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned (4)));
 
+/* Pointers into RxDescList. */
 static volatile USB_IN_Desc_t *myNextRxDesc;
 static volatile USB_IN_Desc_t *myLastRxDesc;
 static volatile USB_IN_Desc_t *myPrevRxDesc;
 
-static USB_EP_Desc_t TxCtrlEPList[NBR_OF_EP_DESC] __attribute__ ((aligned (4)));
-static USB_EP_Desc_t TxBulkEPList[NBR_OF_EP_DESC] __attribute__ ((aligned (4)));
+/* EP descriptors must be 32-bit aligned. */
+static volatile USB_EP_Desc_t TxCtrlEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4)));
+static volatile USB_EP_Desc_t TxBulkEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4)));
+/* After each enabled bulk EP (IN or OUT) we put two disabled EP descriptors with the eol flag set,
+   causing the DMA to stop the DMA channel. The first of these two has the intr flag set, which
+   gives us a dma8_sub0_descr interrupt. When we receive this, we advance the DMA one step in the
+   EP list and then restart the bulk channel, thus forcing a switch between bulk EP descriptors
+   in each frame. */
+static volatile USB_EP_Desc_t TxBulkDummyEPList[NBR_OF_EPIDS][2] __attribute__ ((aligned (4)));
+
+static volatile USB_EP_Desc_t TxIsocEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4)));
+static volatile USB_SB_Desc_t TxIsocSB_zout __attribute__ ((aligned (4)));
+
+static volatile USB_EP_Desc_t TxIntrEPList[MAX_INTR_INTERVAL] __attribute__ ((aligned (4)));
+static volatile USB_SB_Desc_t TxIntrSB_zout __attribute__ ((aligned (4)));
+
+/* A zout transfer makes a memory access at the address of its buf pointer, which means that setting
+   this buf pointer to 0 will cause an access to the flash. In addition to this, setting sw_len to 0
+   results in a 16/32 bytes (depending on DMA burst size) transfer. Instead, we set it to 1, and point
+   it to this buffer. */
+static int zout_buffer[4] __attribute__ ((aligned (4)));
 
-static USB_EP_Desc_t TxIntrEPList[MAX_INTR_INTERVAL] __attribute__ ((aligned (4)));
-static USB_SB_Desc_t TxIntrSB_zout __attribute__ ((aligned (4)));
-
-static struct urb *URB_List[NBR_OF_EP_DESC];
+/* Cache for allocating new EP and SB descriptors. */
 static kmem_cache_t *usb_desc_cache;
+
+/* Cache for the registers allocated in the top half. */
+static kmem_cache_t *top_half_reg_cache;
+
 static struct usb_bus *etrax_usb_bus;
 
-#ifdef USB_DEBUG_DESC
-static void dump_urb (struct urb *urb);
-#endif
+/* This is a circular (double-linked) list of the active urbs for each epid.
+   The head is never removed, and new urbs are linked onto the list as 
+   urb_entry_t elements. Don't reference urb_list directly; use the wrapper
+   functions instead. Note that working with these lists might require spinlock
+   protection. */
+static struct list_head urb_list[NBR_OF_EPIDS];
+
+/* Read about the need and usage of this lock in submit_ctrl_urb. */
+static spinlock_t urb_list_lock;
+
+/* Used when unlinking asynchronously. */
+static struct list_head urb_unlink_list;
+
+/* Wrappers around the list functions (include/linux/list.h). */
+
+static inline int urb_list_empty(int epid)
+{
+        return list_empty(&urb_list[epid]);
+}
+
+/* Returns first urb for this epid, or NULL if list is empty. */
+static inline urb_t *urb_list_first(int epid)
+{
+        urb_t *first_urb = 0;
+
+        if (!urb_list_empty(epid)) {
+                /* Get the first urb (i.e. head->next). */
+                urb_entry_t *urb_entry = list_entry((&urb_list[epid])->next, urb_entry_t, list);
+                first_urb = urb_entry->urb;
+        }
+        return first_urb;
+}
+
+/* Adds an urb_entry last in the list for this epid. */
+static inline void urb_list_add(urb_t *urb, int epid)
+{
+        urb_entry_t *urb_entry = (urb_entry_t *)kmalloc(sizeof(urb_entry_t), KMALLOC_FLAG);
+        assert(urb_entry);
+
+        urb_entry->urb = urb;
+        list_add_tail(&urb_entry->list, &urb_list[epid]);
+}
+
+/* Search through the list for an element that contains this urb. (The list
+   is expected to be short and the one we are about to delete will often be
+   the first in the list.) */
+static inline urb_entry_t *__urb_list_entry(urb_t *urb, int epid)
+{
+        struct list_head *entry;
+        struct list_head *tmp;
+        urb_entry_t *urb_entry;
+
+        list_for_each_safe(entry, tmp, &urb_list[epid]) {
+                urb_entry = list_entry(entry, urb_entry_t, list);
+                assert(urb_entry);
+                assert(urb_entry->urb);
+                
+                if (urb_entry->urb == urb) {
+                        return urb_entry;
+                }
+        }
+        return 0;
+}
+
+/* Delete an urb from the list. */
+static inline void urb_list_del(urb_t *urb, int epid)
+{
+        urb_entry_t *urb_entry = __urb_list_entry(urb, epid);
+        assert(urb_entry);
+        
+        /* Delete entry and free. */
+        list_del(&urb_entry->list);
+        kfree(urb_entry);
+}
+
+/* Move an urb to the end of the list. */
+static inline void urb_list_move_last(urb_t *urb, int epid)
+{
+        urb_entry_t *urb_entry = __urb_list_entry(urb, epid);
+        assert(urb_entry);
+
+        list_del(&urb_entry->list);
+        list_add_tail(&urb_entry->list, &urb_list[epid]);
+}
+
+/* For debug purposes only. */
+static inline void urb_list_dump(int epid)
+{
+        struct list_head *entry;
+        struct list_head *tmp;
+        urb_entry_t *urb_entry;
+        int i = 0;
+
+        info("Dumping urb list for epid %d", epid);
+        
+        list_for_each_safe(entry, tmp, &urb_list[epid]) {
+                urb_entry = list_entry(entry, urb_entry_t, list);
+                info("   entry %d, urb = 0x%lx", i, (unsigned long)urb_entry->urb);
+        }
+}
+
 static void init_rx_buffers(void);
-static int etrax_rh_unlink_urb (struct urb *urb);
-static void etrax_rh_send_irq(struct urb *urb);
-static void etrax_rh_init_int_timer(struct urb *urb);
+static int etrax_rh_unlink_urb(urb_t *urb);
+static void etrax_rh_send_irq(urb_t *urb);
+static void etrax_rh_init_int_timer(urb_t *urb);
 static void etrax_rh_int_timer_do(unsigned long ptr);
 
-static void etrax_usb_setup_epid(int epid, char devnum, char endpoint,
-				 char packsize, char slow, char out_traffic);
-static int etrax_usb_lookup_epid(unsigned char devnum, char endpoint,
-				 char slow, int maxp, char out_traffic);
+static int etrax_usb_setup_epid(urb_t *urb);
+static int etrax_usb_lookup_epid(urb_t *urb);
 static int etrax_usb_allocate_epid(void);
 static void etrax_usb_free_epid(int epid);
-static void cleanup_sb(USB_SB_Desc_t *sb);
 
-static void etrax_usb_do_ctrl_hw_add(struct urb *urb, int epid, char maxlen);
-static void etrax_usb_do_bulk_hw_add(struct urb *urb, int epid, char maxlen);
+static int etrax_remove_from_sb_list(urb_t *urb);
 
-static int etrax_usb_submit_ctrl_urb(struct urb *urb);
+static void etrax_usb_add_to_bulk_sb_list(urb_t *urb, int epid);
+static void etrax_usb_add_to_ctrl_sb_list(urb_t *urb, int epid);
+static void etrax_usb_add_to_intr_sb_list(urb_t *urb, int epid);
+static void etrax_usb_add_to_isoc_sb_list(urb_t *urb, int epid); 
+
+static int etrax_usb_submit_bulk_urb(urb_t *urb);
+static int etrax_usb_submit_ctrl_urb(urb_t *urb);
+static int etrax_usb_submit_intr_urb(urb_t *urb);
+static int etrax_usb_submit_isoc_urb(urb_t *urb);
 
-static int etrax_usb_submit_urb(struct urb *urb);
-static int etrax_usb_unlink_urb(struct urb *urb);
+static int etrax_usb_submit_urb(urb_t *urb);
+static int etrax_usb_unlink_urb(urb_t *urb);
 static int etrax_usb_get_frame_number(struct usb_device *usb_dev);
 static int etrax_usb_allocate_dev(struct usb_device *usb_dev);
 static int etrax_usb_deallocate_dev(struct usb_device *usb_dev);
 
 static void etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs);
 static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs);
-static void etrax_usb_hc_intr_top_half(int irq, void *vhc, struct pt_regs *regs);
+static void etrax_usb_hc_interrupt_top_half(int irq, void *vhc, struct pt_regs *regs);
+static void etrax_usb_hc_interrupt_bottom_half(void *data);
 
-static int etrax_rh_submit_urb (struct urb *urb);
+/* The following is a list of interrupt handlers for the host controller interrupts we use.
+   They are called from etrax_usb_hc_interrupt_bottom_half. */
+static void etrax_usb_hc_isoc_eof_interrupt(void);
+static void etrax_usb_hc_bulk_eot_interrupt(int timer_induced);
+static void etrax_usb_hc_epid_attn_interrupt(usb_interrupt_registers_t *reg);
+static void etrax_usb_hc_port_status_interrupt(usb_interrupt_registers_t *reg);
+static void etrax_usb_hc_ctl_status_interrupt(usb_interrupt_registers_t *reg);
+
+static int etrax_rh_submit_urb (urb_t *urb);
+
+/* Forward declaration needed because they are used in the rx interrupt routine. */
+static void etrax_usb_complete_urb(urb_t *urb, int status);
+static void etrax_usb_complete_bulk_urb(urb_t *urb, int status);
+static void etrax_usb_complete_ctrl_urb(urb_t *urb, int status);
+static void etrax_usb_complete_intr_urb(urb_t *urb, int status);
+static void etrax_usb_complete_isoc_urb(urb_t *urb, int status);
 
 static int etrax_usb_hc_init(void);
 static void etrax_usb_hc_cleanup(void);
@@ -243,65 +451,193 @@
 	etrax_usb_unlink_urb
 };
 
-#ifdef USB_DEBUG_DESC
-static void dump_urb(struct urb *urb)
-{
-	printk("\nurb                   :0x%08X\n", urb);
-	printk("next                  :0x%08X\n", urb->next);
-	printk("dev                   :0x%08X\n", urb->dev);
-	printk("pipe                  :0x%08X\n", urb->pipe);
-	printk("status                :%d\n", urb->status);
-	printk("transfer_flags        :0x%08X\n", urb->transfer_flags);
-	printk("transfer_buffer       :0x%08X\n", urb->transfer_buffer);
-	printk("transfer_buffer_length:%d\n", urb->transfer_buffer_length);
-	printk("actual_length         :%d\n", urb->actual_length);
-	printk("setup_packet          :0x%08X\n", urb->setup_packet);
-	printk("start_frame           :%d\n", urb->start_frame);
-	printk("number_of_packets     :%d\n", urb->number_of_packets);
-	printk("interval              :%d\n", urb->interval);
-	printk("error_count           :%d\n", urb->error_count);
-	printk("context               :0x%08X\n", urb->context);
-	printk("complete              :0x%08X\n\n", urb->complete);
-}
-
-static void dump_in_desc(USB_IN_Desc_t *in)
-{
-	printk("\nUSB_IN_Desc at 0x%08X\n", in);
-	printk("  sw_len  : 0x%04X (%d)\n", in->sw_len, in->sw_len);
-	printk("  command : 0x%04X\n", in->command);
-	printk("  next    : 0x%08X\n", in->next);
-	printk("  buf     : 0x%08X\n", in->buf);
-	printk("  hw_len  : 0x%04X (%d)\n", in->hw_len, in->hw_len);
-	printk("  status  : 0x%04X\n\n", in->status);
-}
-
-static void dump_sb_desc(USB_SB_Desc_t *sb)
-{
-	printk("\nUSB_SB_Desc at 0x%08X\n", sb);
-	printk("  sw_len  : 0x%04X (%d)\n", sb->sw_len, sb->sw_len);
-	printk("  command : 0x%04X\n", sb->command);
-	printk("  next    : 0x%08X\n", sb->next);
-	printk("  buf     : 0x%08X\n\n", sb->buf);
+/* Note that these functions are always available in their "__" variants, for use in
+   error situations. The "__" missing variants are controlled by the USB_DEBUG_DESC/
+   USB_DEBUG_URB macros. */
+static void __dump_urb(purb_t purb)
+{
+	printk("\nurb                  :0x%08lx\n", (unsigned long)purb);
+	printk("next                  :0x%08lx\n", (unsigned long)purb->next);
+	printk("dev                   :0x%08lx\n", (unsigned long)purb->dev);
+	printk("pipe                  :0x%08x\n", purb->pipe);
+	printk("status                :%d\n", purb->status);
+	printk("transfer_flags        :0x%08x\n", purb->transfer_flags);
+	printk("transfer_buffer       :0x%08lx\n", (unsigned long)purb->transfer_buffer);
+	printk("transfer_buffer_length:%d\n", purb->transfer_buffer_length);
+	printk("actual_length         :%d\n", purb->actual_length);
+	printk("setup_packet          :0x%08lx\n", (unsigned long)purb->setup_packet);
+	printk("start_frame           :%d\n", purb->start_frame);
+	printk("number_of_packets     :%d\n", purb->number_of_packets);
+	printk("interval              :%d\n", purb->interval);
+	printk("error_count           :%d\n", purb->error_count);
+	printk("context               :0x%08lx\n", (unsigned long)purb->context);
+        printk("complete              :0x%08lx\n\n", (unsigned long)purb->complete);
+}
+
+static void __dump_in_desc(volatile USB_IN_Desc_t *in)
+{
+	printk("\nUSB_IN_Desc at 0x%08lx\n", (unsigned long)in);
+	printk("  sw_len  : 0x%04x (%d)\n", in->sw_len, in->sw_len);
+	printk("  command : 0x%04x\n", in->command);
+	printk("  next    : 0x%08lx\n", in->next);
+	printk("  buf     : 0x%08lx\n", in->buf);
+	printk("  hw_len  : 0x%04x (%d)\n", in->hw_len, in->hw_len);
+        printk("  status  : 0x%04x\n\n", in->status);
+}
+
+static void __dump_sb_desc(volatile USB_SB_Desc_t *sb)
+{
+	char tt = (sb->command & 0x30) >> 4;
+	char *tt_string;
+
+	switch (tt) {
+	case 0:
+		tt_string = "zout";
+		break;
+	case 1:
+		tt_string = "in";
+		break;
+	case 2:
+		tt_string = "out";
+		break;
+	case 3:
+		tt_string = "setup";
+		break;
+	default:
+		tt_string = "unknown (weird)";
+	}
+		
+	printk("\n   USB_SB_Desc at 0x%08lx\n", (unsigned long)sb); 
+        printk("     command : 0x%04x\n", sb->command);
+	printk("        rem     : %d\n", (sb->command & 0x3f00) >> 8);
+	printk("        full    : %d\n", (sb->command & 0x40) >> 6);
+	printk("        tt      : %d (%s)\n", tt, tt_string);
+	printk("        intr    : %d\n", (sb->command & 0x8) >> 3);
+	printk("        eot     : %d\n", (sb->command & 0x2) >> 1);
+	printk("        eol     : %d\n", sb->command & 0x1);
+        printk("     sw_len  : 0x%04x (%d)\n", sb->sw_len, sb->sw_len);
+	printk("     next    : 0x%08lx\n", sb->next);
+        printk("     buf     : 0x%08lx\n\n", sb->buf);
 }
 
 
-static void dump_ep_desc(USB_EP_Desc_t *ep)
-{
-	printk("\nUSB_EP_Desc at 0x%08X\n", ep);
-	printk("  hw_len  : 0x%04X (%d)\n", ep->hw_len, ep->hw_len);
-	printk("  command : 0x%08X\n", ep->command);
-	printk("  sub     : 0x%08X\n", ep->sub);
-	printk("  nep     : 0x%08X\n\n", ep->nep);
+static void __dump_ep_desc(volatile USB_EP_Desc_t *ep)
+{
+	printk("\nUSB_EP_Desc at 0x%08lx\n", (unsigned long)ep);
+        printk("  command : 0x%04x\n", ep->command);
+	printk("     ep_id   : %d\n", (ep->command & 0x1f00) >> 8);
+	printk("     enable  : %d\n", (ep->command & 0x10) >> 4);
+	printk("     intr    : %d\n", (ep->command & 0x8) >> 3);
+	printk("     eof     : %d\n", (ep->command & 0x2) >> 1);
+	printk("     eol     : %d\n", ep->command & 0x1);
+	printk("  hw_len  : 0x%04x (%d)\n", ep->hw_len, ep->hw_len);
+        printk("  next    : 0x%08lx\n", ep->next);
+	printk("  sub     : 0x%08lx\n\n", ep->sub);
+}
+
+static inline void __dump_ep_list(int pipe_type)
+{
+        volatile USB_EP_Desc_t *ep;
+        volatile USB_EP_Desc_t *first_ep;
+        volatile USB_SB_Desc_t *sb;
+
+        switch (pipe_type)
+        {
+        case PIPE_BULK:
+                first_ep = &TxBulkEPList[0];
+                break;
+        case PIPE_CONTROL:
+                first_ep = &TxCtrlEPList[0];
+                break;
+        case PIPE_INTERRUPT:
+                first_ep = &TxIntrEPList[0];
+                break;
+        case PIPE_ISOCHRONOUS:
+                first_ep = &TxIsocEPList[0];
+                break;
+        default:
+		warn("Cannot dump unknown traffic type");
+		return;
+        }
+        ep = first_ep;
+
+        printk("\n\nDumping EP list...\n\n");
+
+        do {
+		__dump_ep_desc(ep);
+		/* Cannot phys_to_virt on 0 as it turns into 80000000, which is != 0. */
+		sb = ep->sub ? phys_to_virt(ep->sub) : 0;                
+		while (sb) {
+			__dump_sb_desc(sb);
+			sb = sb->next ? phys_to_virt(sb->next) : 0;
+		}
+                ep = (volatile USB_EP_Desc_t *)(phys_to_virt(ep->next));
+                
+        } while (ep != first_ep);
+}
+
+static inline void __dump_ept_data(int epid)
+{
+	unsigned long flags;
+	__u32 r_usb_ept_data;
+
+	if (epid < 0 || epid > 31) {
+		printk("Cannot dump ept data for invalid epid %d\n", epid);
+		return;
+	}
+
+	save_flags(flags);
+	cli();
+	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); 
+	nop();
+	r_usb_ept_data = *R_USB_EPT_DATA;
+	restore_flags(flags);
+	
+	printk("\nR_USB_EPT_DATA = 0x%x for epid %d :\n", r_usb_ept_data, epid);
+	if (r_usb_ept_data == 0) {
+		/* No need for more detailed printing. */
+		return;
+	}
+	printk("  valid           : %d\n", (r_usb_ept_data & 0x80000000) >> 31);
+	printk("  hold            : %d\n", (r_usb_ept_data & 0x40000000) >> 30);
+	printk("  error_count_in  : %d\n", (r_usb_ept_data & 0x30000000) >> 28);
+	printk("  t_in            : %d\n", (r_usb_ept_data & 0x08000000) >> 27);
+	printk("  low_speed       : %d\n", (r_usb_ept_data & 0x04000000) >> 26);
+	printk("  port            : %d\n", (r_usb_ept_data & 0x03000000) >> 24);
+	printk("  error_code      : %d\n", (r_usb_ept_data & 0x00c00000) >> 22);
+	printk("  t_out           : %d\n", (r_usb_ept_data & 0x00200000) >> 21);
+	printk("  error_count_out : %d\n", (r_usb_ept_data & 0x00180000) >> 19);
+	printk("  max_len         : %d\n", (r_usb_ept_data & 0x0003f800) >> 11);
+	printk("  ep              : %d\n", (r_usb_ept_data & 0x00000780) >> 7);
+	printk("  dev             : %d\n", (r_usb_ept_data & 0x0000003f)); 
 }
 
+static inline void __dump_ept_data_list(void)
+{
+	int i;
 
+	printk("Dumping the whole R_USB_EPT_DATA list\n");
+
+	for (i = 0; i < 32; i++) {
+		__dump_ept_data(i);
+	}
+}
+#ifdef USB_DEBUG_DESC
+#define dump_in_desc(...) __dump_in_desc(...)
+#define dump_sb_desc(...) __dump_sb_desc(...)
+#define dump_ep_desc(...) __dump_ep_desc(...)
 #else
-#define dump_urb(...)     do {} while (0)
 #define dump_in_desc(...) do {} while (0)
 #define dump_sb_desc(...) do {} while (0)
 #define dump_ep_desc(...) do {} while (0)
 #endif
 
+#ifdef USB_DEBUG_URB
+#define dump_urb(x)     __dump_urb(x)
+#else
+#define dump_urb(x)     do {} while (0)
+#endif
+
 static void init_rx_buffers(void)
 {
 	int i;
@@ -315,6 +651,11 @@
 		RxDescList[i].buf = virt_to_phys(RxBuf + (i * RX_DESC_BUF_SIZE));
 		RxDescList[i].hw_len = 0;
 		RxDescList[i].status = 0;
+
+                /* DMA IN cache bug. (struct etrax_dma_descr has the same layout as USB_IN_Desc
+		   for the relevant fields.) */
+                prepare_rx_descriptor((struct etrax_dma_descr*)&RxDescList[i]);
+
 	}
 	
 	RxDescList[i].sw_len = RX_DESC_BUF_SIZE;
@@ -334,367 +675,254 @@
 	DBFEXIT;
 }
 
-static void init_tx_ctrl_ep(void)
+static void init_tx_bulk_ep(void)
 {
 	int i;
 	
 	DBFENTER;
 	
-	for (i = 0; i < (NBR_OF_EP_DESC - 1); i++) {
-		TxCtrlEPList[i].hw_len = 0;
-		TxCtrlEPList[i].command = IO_FIELD(USB_EP_command, epid, i);
-		TxCtrlEPList[i].sub = 0;
-		TxCtrlEPList[i].nep = virt_to_phys(&TxCtrlEPList[i + 1]);
+	for (i = 0; i < (NBR_OF_EPIDS - 1); i++) {
+                CHECK_ALIGN(&TxBulkEPList[i]);
+		TxBulkEPList[i].hw_len = 0;
+		TxBulkEPList[i].command = IO_FIELD(USB_EP_command, epid, i);
+		TxBulkEPList[i].sub = 0;
+		TxBulkEPList[i].next = virt_to_phys(&TxBulkEPList[i + 1]);
+
+		/* Initiate two EPs, disabled and with the eol flag set. No need for any
+		   preserved epid. */
+
+		/* The first one has the intr flag set so we get an interrupt when the DMA
+		   channel is about to become disabled. */
+		CHECK_ALIGN(&TxBulkDummyEPList[i][0]);
+		TxBulkDummyEPList[i][0].hw_len = 0;
+		TxBulkDummyEPList[i][0].command = (IO_FIELD(USB_EP_command, epid, DUMMY_EPID) |
+						   IO_STATE(USB_EP_command, eol, yes) |
+						   IO_STATE(USB_EP_command, intr, yes));
+		TxBulkDummyEPList[i][0].sub = 0;
+		TxBulkDummyEPList[i][0].next = virt_to_phys(&TxBulkDummyEPList[i][1]);
+
+		/* The second one. */
+		CHECK_ALIGN(&TxBulkDummyEPList[i][1]);
+		TxBulkDummyEPList[i][1].hw_len = 0;
+		TxBulkDummyEPList[i][1].command = (IO_FIELD(USB_EP_command, epid, DUMMY_EPID) |
+						   IO_STATE(USB_EP_command, eol, yes));
+		TxBulkDummyEPList[i][1].sub = 0;
+		/* The last dummy's next pointer is the same as the current EP's next pointer. */
+		TxBulkDummyEPList[i][1].next = virt_to_phys(&TxBulkEPList[i + 1]);
 	}
-	
-	TxCtrlEPList[i].hw_len = 0;
-	TxCtrlEPList[i].command = IO_STATE(USB_EP_command, eol, yes) |
-		IO_FIELD(USB_EP_command, epid, i);
 
-	TxCtrlEPList[i].sub = 0;
-	TxCtrlEPList[i].nep = virt_to_phys(&TxCtrlEPList[0]);
-	
-	*R_DMA_CH8_SUB1_EP = virt_to_phys(&TxCtrlEPList[0]);
-	*R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start);
-	
+	/* Configure the last one. */
+        CHECK_ALIGN(&TxBulkEPList[i]);
+	TxBulkEPList[i].hw_len = 0;
+	TxBulkEPList[i].command = (IO_STATE(USB_EP_command, eol, yes) |
+                                   IO_FIELD(USB_EP_command, epid, i));
+	TxBulkEPList[i].sub = 0;
+	TxBulkEPList[i].next = virt_to_phys(&TxBulkEPList[0]);
+
+	/* No need configuring dummy EPs for the last one as it will never be used for
+	   bulk traffic (i == INVALD_EPID at this point). */
+
+	/* Set up to start on the last EP so we will enable it when inserting traffic
+	   for the first time (imitating the situation where the DMA has stopped
+	   because there was no more traffic). */
+	*R_DMA_CH8_SUB0_EP = virt_to_phys(&TxBulkEPList[i]);
+	/* No point in starting the bulk channel yet.
+	 *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); */
 	DBFEXIT;
 }
 
-static void init_tx_bulk_ep(void)
+static void init_tx_ctrl_ep(void)
 {
 	int i;
 	
 	DBFENTER;
 	
-	for (i = 0; i < (NBR_OF_EP_DESC - 1); i++) {
-		TxBulkEPList[i].hw_len = 0;
-		TxBulkEPList[i].command = IO_FIELD(USB_EP_command, epid, i);
-		TxBulkEPList[i].sub = 0;
-		TxBulkEPList[i].nep = virt_to_phys(&TxBulkEPList[i + 1]);
+	for (i = 0; i < (NBR_OF_EPIDS - 1); i++) {
+                CHECK_ALIGN(&TxCtrlEPList[i]);
+		TxCtrlEPList[i].hw_len = 0;
+		TxCtrlEPList[i].command = IO_FIELD(USB_EP_command, epid, i);
+		TxCtrlEPList[i].sub = 0;
+		TxCtrlEPList[i].next = virt_to_phys(&TxCtrlEPList[i + 1]);
 	}
 	
-	TxBulkEPList[i].hw_len = 0;
-	TxBulkEPList[i].command = IO_STATE(USB_EP_command, eol, yes) |
-		IO_FIELD(USB_EP_command, epid, i);
+        CHECK_ALIGN(&TxCtrlEPList[i]);
+	TxCtrlEPList[i].hw_len = 0;
+	TxCtrlEPList[i].command = (IO_STATE(USB_EP_command, eol, yes) |
+                                   IO_FIELD(USB_EP_command, epid, i));
 
-	TxBulkEPList[i].sub = 0;
-	TxBulkEPList[i].nep = virt_to_phys(&TxBulkEPList[0]);
+	TxCtrlEPList[i].sub = 0;
+	TxCtrlEPList[i].next = virt_to_phys(&TxCtrlEPList[0]);
 	
-	*R_DMA_CH8_SUB0_EP = virt_to_phys(&TxBulkEPList[0]);
-	*R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start);
+	*R_DMA_CH8_SUB1_EP = virt_to_phys(&TxCtrlEPList[0]);
+	*R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start);
 	
 	DBFEXIT;
 }
 
+
 static void init_tx_intr_ep(void)
 {
 	int i;
 
 	DBFENTER;
 
-	TxIntrSB_zout.sw_len = 0;
+        /* Read comment at zout_buffer declaration for an explanation to this. */
+	TxIntrSB_zout.sw_len = 1;
 	TxIntrSB_zout.next = 0;
-	TxIntrSB_zout.buf = 0;
-	TxIntrSB_zout.command = IO_FIELD(USB_SB_command, rem, 0) |
-		IO_STATE(USB_SB_command, tt, zout) |
-		IO_STATE(USB_SB_command, full, yes) |
-		IO_STATE(USB_SB_command, eot, yes) |
-		IO_STATE(USB_SB_command, eol, yes);
+	TxIntrSB_zout.buf = virt_to_phys(&zout_buffer[0]);
+	TxIntrSB_zout.command = (IO_FIELD(USB_SB_command, rem, 0) |
+                                 IO_STATE(USB_SB_command, tt, zout) |
+                                 IO_STATE(USB_SB_command, full, yes) |
+                                 IO_STATE(USB_SB_command, eot, yes) |
+                                 IO_STATE(USB_SB_command, eol, yes));
 
 	for (i = 0; i < (MAX_INTR_INTERVAL - 1); i++) {
+                CHECK_ALIGN(&TxIntrEPList[i]);
 		TxIntrEPList[i].hw_len = 0;
-		TxIntrEPList[i].command = IO_STATE(USB_EP_command, eof, yes) |
-			IO_STATE(USB_EP_command, enable, yes) |
-			IO_FIELD(USB_EP_command, epid, 0);
+		TxIntrEPList[i].command =
+			(IO_STATE(USB_EP_command, eof, yes) |
+                         IO_STATE(USB_EP_command, enable, yes) |
+                         IO_FIELD(USB_EP_command, epid, INVALID_EPID));
 		TxIntrEPList[i].sub = virt_to_phys(&TxIntrSB_zout);
-		TxIntrEPList[i].nep = virt_to_phys(&TxIntrEPList[i + 1]);
+		TxIntrEPList[i].next = virt_to_phys(&TxIntrEPList[i + 1]);
 	}
 	
+	CHECK_ALIGN(&TxIntrEPList[i]);
 	TxIntrEPList[i].hw_len = 0;
 	TxIntrEPList[i].command =
-		IO_STATE(USB_EP_command, eof, yes) |
-		IO_STATE(USB_EP_command, enable, yes) |
-		IO_FIELD(USB_EP_command, epid, 0);
+		(IO_STATE(USB_EP_command, eof, yes) |
+		 IO_STATE(USB_EP_command, eol, yes) |
+		 IO_STATE(USB_EP_command, enable, yes) |
+		 IO_FIELD(USB_EP_command, epid, INVALID_EPID));
 	TxIntrEPList[i].sub = virt_to_phys(&TxIntrSB_zout);
-	TxIntrEPList[i].nep = virt_to_phys(&TxIntrEPList[0]);
+	TxIntrEPList[i].next = virt_to_phys(&TxIntrEPList[0]);
 
 	*R_DMA_CH8_SUB2_EP = virt_to_phys(&TxIntrEPList[0]);
 	*R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start);
-	
 	DBFEXIT;
 }
 
-
-static int etrax_usb_unlink_intr_urb(struct urb *urb)
+static void init_tx_isoc_ep(void)
 {
-	USB_EP_Desc_t *tmp_ep;
-	USB_EP_Desc_t *first_ep;
-	
-	USB_EP_Desc_t *ep_desc;
-	
-	int epid;
-	char devnum;
-	char endpoint;
-	char slow;
-	int maxlen;
-	char out_traffic;
 	int i;
 	
 	DBFENTER;
-
-	devnum = usb_pipedevice(urb->pipe);
-	endpoint = usb_pipeendpoint(urb->pipe);
-	slow = usb_pipeslow(urb->pipe);
-	maxlen = usb_maxpacket(urb->dev, urb->pipe,
-			       usb_pipeout(urb->pipe));
-	out_traffic = usb_pipeout(urb->pipe);
-
-	epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen, out_traffic);
-	if (epid == -1) {
-		err("Trying to unlink urb that is not in traffic queue!!");
-		return -1;  /* fix this */
-	}
-
-	*R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, stop);
-	/* Somehow wait for the DMA to finish current activities */
-	i = jiffies + 100;
-	while (jiffies < i);	
 	
-	first_ep = &TxIntrEPList[0];
-	tmp_ep = first_ep;
+        /* Read comment at zout_buffer declaration for an explanation to this. */
+	TxIsocSB_zout.sw_len = 1;
+	TxIsocSB_zout.next = 0;
+	TxIsocSB_zout.buf = virt_to_phys(&zout_buffer[0]);
+	TxIsocSB_zout.command = (IO_FIELD(USB_SB_command, rem, 0) |
+                                 IO_STATE(USB_SB_command, tt, zout) |
+                                 IO_STATE(USB_SB_command, full, yes) |
+                                 IO_STATE(USB_SB_command, eot, yes) |
+                                 IO_STATE(USB_SB_command, eol, yes));
 	
-	do {
-		if (IO_EXTRACT(USB_EP_command, epid, ((USB_EP_Desc_t *)phys_to_virt(tmp_ep->nep))->command)
-		    == epid) {
-			/* Unlink it !!! */
-			dbg_intr("Found urb to unlink for epid %d", epid);
-			
-			ep_desc = phys_to_virt(tmp_ep->nep);
-			tmp_ep->nep = ep_desc->nep;
-			kmem_cache_free(usb_desc_cache, phys_to_virt(ep_desc->sub));
-			kmem_cache_free(usb_desc_cache, ep_desc);
-		}
+	/* The last isochronous EP descriptor is a dummy. */
+	
+	for (i = 0; i < (NBR_OF_EPIDS - 1); i++) {
+                CHECK_ALIGN(&TxIsocEPList[i]);
+		TxIsocEPList[i].hw_len = 0;
+		TxIsocEPList[i].command = IO_FIELD(USB_EP_command, epid, i);
+		TxIsocEPList[i].sub = 0;
+		TxIsocEPList[i].next = virt_to_phys(&TxIsocEPList[i + 1]);
+	}
 
-		tmp_ep = phys_to_virt(tmp_ep->nep);
-		
-	} while (tmp_ep != first_ep);
+        CHECK_ALIGN(&TxIsocEPList[i]);
+	TxIsocEPList[i].hw_len = 0;
 
-	/* We should really try to move the EP register to an EP that is not removed
-	   instead of restarting, but this will work too */
-	*R_DMA_CH8_SUB2_EP = virt_to_phys(&TxIntrEPList[0]);
-	*R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start);
+	/* Must enable the last EP descr to get eof interrupt. */
+	TxIsocEPList[i].command = (IO_STATE(USB_EP_command, enable, yes) |
+                                   IO_STATE(USB_EP_command, eof, yes) |
+                                   IO_STATE(USB_EP_command, eol, yes) |
+                                   IO_FIELD(USB_EP_command, epid, INVALID_EPID));
+	TxIsocEPList[i].sub = virt_to_phys(&TxIsocSB_zout);
+	TxIsocEPList[i].next = virt_to_phys(&TxIsocEPList[0]);
 
-	clear_bit(epid, (void *)&ep_really_active);
-	URB_List[epid] = NULL;
-	etrax_usb_free_epid(epid);
+	*R_DMA_CH8_SUB3_EP = virt_to_phys(&TxIsocEPList[0]);
+	*R_DMA_CH8_SUB3_CMD = IO_STATE(R_DMA_CH8_SUB3_CMD, cmd, start);
 	
 	DBFEXIT;
-
-	return 0;
 }
 
-void etrax_usb_do_intr_recover(int epid)
+static void etrax_usb_unlink_intr_urb(urb_t *urb)
 {
-	USB_EP_Desc_t *first_ep, *tmp_ep;
-	
-	first_ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB2_EP);
-	tmp_ep = first_ep;
-
-	do {
-		if (IO_EXTRACT(USB_EP_command, epid, tmp_ep->command) == epid &&
-		    !(tmp_ep->command & IO_MASK(USB_EP_command, enable))) {
-			tmp_ep->command |= IO_STATE(USB_EP_command, enable, yes);
-		}
-		
-		tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->nep);
-		
-	} while (tmp_ep != first_ep);
-}
+	volatile USB_EP_Desc_t *first_ep;  /* First EP in the list. */
+	volatile USB_EP_Desc_t *curr_ep;   /* Current EP, the iterator. */
+	volatile USB_EP_Desc_t *next_ep;   /* The EP after current. */
+	volatile USB_EP_Desc_t *unlink_ep; /* The one we should remove from the list. */
 
-static int etrax_usb_submit_intr_urb(struct urb *urb)
-{
-	USB_EP_Desc_t *tmp_ep;
-	USB_EP_Desc_t *first_ep;
-	
 	int epid;
-	char devnum;
-	char endpoint;
-	char maxlen;
-	char out_traffic;
-	char slow;
-	int interval;
-	int i;
-	
-	etrax_urb_priv_t *urb_priv;
-	
-	DBFENTER;
-
-	devnum = usb_pipedevice(urb->pipe);
-	endpoint = usb_pipeendpoint(urb->pipe);
-	maxlen = usb_maxpacket(urb->dev, urb->pipe,
-			       usb_pipeout(urb->pipe));
-	out_traffic = usb_pipeout(urb->pipe);
 
-	slow = usb_pipeslow(urb->pipe);
-	interval = urb->interval;
+        /* Read 8.8.4 in Designer's Reference, "Removing an EP Descriptor from the List". */
 
-	dbg_intr("Intr traffic for dev %d, endpoint %d, maxlen %d, slow %d",
-		 devnum, endpoint, maxlen, slow);
-	
-	epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen, out_traffic);
-	if (epid == -1) {
-		epid = etrax_usb_allocate_epid();
-		if (epid == -1) {
-			/* We're out of endpoints, return some error */
-			err("We're out of endpoints");
-			return -ENOMEM;
-		}
-		/* Now we have to fill in this ep */
-		etrax_usb_setup_epid(epid, devnum, endpoint, maxlen, slow, out_traffic);
-	}
-	/* Ok, now we got valid endpoint, lets insert some traffic */
+	DBFENTER;
 
-	urb_priv = (etrax_urb_priv_t *)kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL);
-	urb_priv->first_sb = 0;
-	urb_priv->rx_offset = 0;
-	urb_priv->eot = 0;
-	INIT_LIST_HEAD(&urb_priv->ep_in_list);
-	urb->hcpriv = urb_priv;
+	epid = ((etrax_urb_priv_t *)urb->hcpriv)->epid;
 
-	/* This is safe since there cannot be any other URB's for this epid */
-	URB_List[epid] = urb;
-#if 0
-	first_ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB2_EP);
-#else
 	first_ep = &TxIntrEPList[0];
-#endif
+	curr_ep = first_ep;
+	
 
-	/* Round of the interval to 2^n, it is obvious that this code favours
-	   smaller numbers, but that is actually a good thing */
-	for (i = 0; interval; i++) {
-		interval = interval >> 1;
-	}
+        /* Note that this loop removes all EP descriptors with this epid. This assumes
+           that all EP descriptors belong to the one and only urb for this epid. */
 
-	urb->interval = interval = 1 << (i - 1);
+	do {
+                next_ep = (USB_EP_Desc_t *)phys_to_virt(curr_ep->next);
 
-	dbg_intr("Interval rounded to %d", interval);
+		if (IO_EXTRACT(USB_EP_command, epid, next_ep->command) == epid) {
 
-	tmp_ep = first_ep;
-	i = 0;
-	do {
-		if (tmp_ep->command & IO_MASK(USB_EP_command, eof)) {
-			if ((i % interval) == 0) {
-				/* Insert the traffic ep after tmp_ep */
-				USB_EP_Desc_t *traffic_ep;
-				USB_SB_Desc_t *traffic_sb;
+			dbg_intr("Found EP to unlink for epid %d", epid);
+                        
+                        /* This is the one we should unlink. */
+			unlink_ep = next_ep;
 
-				traffic_ep = (USB_EP_Desc_t *)
-					kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
-				traffic_sb = (USB_SB_Desc_t *)
-					kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
-
-				traffic_ep->hw_len = 0;
-				traffic_ep->command = IO_FIELD(USB_EP_command, epid, epid) |
-					IO_STATE(USB_EP_command, enable, yes);
-				traffic_ep->sub = virt_to_phys(traffic_sb);
-
-				if (usb_pipein(urb->pipe)) {
-					traffic_sb->sw_len = urb->transfer_buffer_length ?
-						(urb->transfer_buffer_length - 1) / maxlen + 1 : 0;
-					traffic_sb->next = 0;
-					traffic_sb->buf = 0;
-					traffic_sb->command = IO_FIELD(USB_SB_command, rem,
-								       urb->transfer_buffer_length % maxlen) |
-						IO_STATE(USB_SB_command, tt, in) |
-						IO_STATE(USB_SB_command, eot, yes) |
-						IO_STATE(USB_SB_command, eol, yes);
-					
-				} else if (usb_pipeout(urb->pipe)) {
-					traffic_sb->sw_len = urb->transfer_buffer_length;
-					traffic_sb->next = 0;
-					traffic_sb->buf = virt_to_phys(urb->transfer_buffer);
-					traffic_sb->command = IO_FIELD(USB_SB_command, rem, 0) |
-						IO_STATE(USB_SB_command, tt, out) |
-						IO_STATE(USB_SB_command, eot, yes) |
-						IO_STATE(USB_SB_command, eol, yes) |
-						IO_STATE(USB_SB_command, full, yes);
-				}
+                        /* Actually unlink the EP from the DMA list. */
+			curr_ep->next = unlink_ep->next;
 
-				traffic_ep->nep = tmp_ep->nep;
-				tmp_ep->nep = virt_to_phys(traffic_ep);
-				dbg_intr("One ep sucessfully inserted");
-			}
-			i++;
+                        /* Wait until the DMA is no longer at this descriptor. */
+                        while (*R_DMA_CH8_SUB2_EP == virt_to_phys(unlink_ep));
+
+                        /* Now we are free to remove it and its SB descriptor.
+                           Note that it is assumed here that there is only one sb in the
+                           sb list for this ep. */
+			kmem_cache_free(usb_desc_cache, phys_to_virt(unlink_ep->sub));
+			kmem_cache_free(usb_desc_cache, (USB_EP_Desc_t *)unlink_ep);
 		}
-		tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->nep);
-	} while (tmp_ep != first_ep);
 
-	set_bit(epid, (void *)&ep_really_active);
-	
-	*R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start);
+		curr_ep = phys_to_virt(curr_ep->next);
+		
+	} while (curr_ep != first_ep);
 
-	DBFEXIT;
-	
-	return 0;
 }
 
-
-static void handle_intr_transfer_attn(int epid, int status)
+void etrax_usb_do_intr_recover(int epid)
 {
-	struct urb *old_urb;
+	USB_EP_Desc_t *first_ep, *tmp_ep;
 
 	DBFENTER;
+        
+	first_ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB2_EP);
+	tmp_ep = first_ep;
 
-	old_urb = URB_List[epid];
-	
-	/* if (status == 0 && IN) find data and copy to urb */
-	if (status == 0 && usb_pipein(old_urb->pipe)) {
-		unsigned long flags;
-		etrax_urb_priv_t *urb_priv;
-		struct list_head *entry;
-		struct in_chunk *in;
-
-		urb_priv = (etrax_urb_priv_t *)old_urb->hcpriv;
+        /* What this does is simply to walk the list of interrupt
+           ep descriptors and enable those that are disabled. */
+ 
+	do {
+		if (IO_EXTRACT(USB_EP_command, epid, tmp_ep->command) == epid &&
+		    !(tmp_ep->command & IO_MASK(USB_EP_command, enable))) {
+			tmp_ep->command |= IO_STATE(USB_EP_command, enable, yes);
+		}
 		
-		save_flags(flags);
-		cli();
+		tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->next);
+		
+	} while (tmp_ep != first_ep);
 
-		list_for_each(entry, &urb_priv->ep_in_list) {
-			in = list_entry(entry, struct in_chunk, list);
-			memcpy(old_urb->transfer_buffer, in->data, in->length);
-			old_urb->actual_length = in->length;
-			old_urb->status = status;
-			
-			if (old_urb->complete) {
-				old_urb->complete(old_urb);
-			}
-			
-			list_del(entry);
-			kfree(in->data);
-			kfree(in);
-		}		
-		
-		restore_flags(flags);
-
-	} else if (status != 0) {
-		warn("Some sort of error for INTR EP !!!!");
-#ifdef ETRAX_USB_INTR_ERROR_FATAL
-		/* This means that an INTR error is fatal for that endpoint */
-		etrax_usb_unlink_intr_urb(old_urb);
-		old_urb->status = status;
-		if (old_urb->complete) {
-			old_urb->complete(old_urb);
-		}
-#else
-		/* In this case we reenable the disabled endpoint(s) */
-		etrax_usb_do_intr_recover(epid);
-#endif	
-	}
-	
-	DBFEXIT;
+
+        DBFEXIT;
 }
 
-static int etrax_rh_unlink_urb (struct urb *urb)
+static int etrax_rh_unlink_urb (urb_t *urb)
 {
 	etrax_hc_t *hc;
 	
@@ -711,16 +939,12 @@
 	return 0;
 }
 
-static void etrax_rh_send_irq(struct urb *urb)
+static void etrax_rh_send_irq(urb_t *urb)
 {
 	__u16 data = 0;
 	etrax_hc_t *hc = urb->dev->bus->hcpriv;
-//	static prev_wPortStatus_1 = 0;
-//	static prev_wPortStatus_2 = 0;
-	
 /*	DBFENTER; */
-	
-	
+
 /*
   dbg_rh("R_USB_FM_NUMBER   : 0x%08X", *R_USB_FM_NUMBER);
   dbg_rh("R_USB_FM_REMAINING: 0x%08X", *R_USB_FM_REMAINING);
@@ -730,6 +954,8 @@
 	data |= (hc->rh.wPortChange_2) ? (1 << 2) : 0;
 
 	*((__u16 *)urb->transfer_buffer) = cpu_to_le16(data);
+        /* FIXME: Why is actual_length set to 1 when data is 2 bytes?
+           Since only 1 byte is used, why not declare data as __u8? */
 	urb->actual_length = 1;
 	urb->status = 0;
 
@@ -744,7 +970,7 @@
 /*	DBFEXIT; */
 }
 
-static void etrax_rh_init_int_timer(struct urb *urb)
+static void etrax_rh_init_int_timer(urb_t *urb)
 {
 	etrax_hc_t *hc;
 	
@@ -755,6 +981,8 @@
 	init_timer(&hc->rh.rh_int_timer);
 	hc->rh.rh_int_timer.function = etrax_rh_int_timer_do;
 	hc->rh.rh_int_timer.data = (unsigned long)urb;
+        /* FIXME: Is the jiffies resolution enough? All intervals < 10 ms will be mapped
+           to 0, and the rest to the nearest lower 10 ms. */
 	hc->rh.rh_int_timer.expires = jiffies + ((HZ * hc->rh.interval) / 1000);
 	add_timer(&hc->rh.rh_int_timer);
 	
@@ -763,12 +991,12 @@
 
 static void etrax_rh_int_timer_do(unsigned long ptr)
 {
-	struct urb *urb;
+	urb_t *urb;
 	etrax_hc_t *hc;
 	
 /*	DBFENTER; */
 	
-	urb = (struct urb*)ptr;
+	urb = (urb_t*)ptr;
 	hc = urb->dev->bus->hcpriv;
 	
 	if (hc->rh.send) {
@@ -780,44 +1008,81 @@
 /*	DBFEXIT; */
 }
 
-static void etrax_usb_setup_epid(int epid, char devnum, char endpoint, char packsize, char slow, char out_traffic)
+static int etrax_usb_setup_epid(urb_t *urb)
 {
+	int epid;
+	char devnum, endpoint, out_traffic, slow;
+	int maxlen;
 	unsigned long flags;
-	
-	DBFENTER;
 
-	save_flags(flags);
-	cli();
+	DBFENTER;
 	
-	if (test_bit(epid, (void *)&ep_usage_bitmask)) {
-		restore_flags(flags);
-
-		warn("Trying to setup used epid %d", epid);
+	epid = etrax_usb_lookup_epid(urb);
+	if ((epid != -1)){
+		/* An epid that fits this urb has been found. */
 		DBFEXIT;
-		return;
+		return epid;
 	}
 	
-	set_bit(epid, (void *)&ep_usage_bitmask);
+	/* We must find and initiate a new epid for this urb. */
+	epid = etrax_usb_allocate_epid();
+
+	if (epid == -1) {
+		/* Failed to allocate a new epid. */
+		DBFEXIT;
+		return epid;
+	}
+
+	/* We now have a new epid to use. Initiate it. */
+	set_bit(epid, (void *)&epid_usage_bitmask);
 	
+	devnum = usb_pipedevice(urb->pipe);
+	endpoint = usb_pipeendpoint(urb->pipe);
+	slow = usb_pipeslow(urb->pipe);
+	maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
+        if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
+                /* We want both IN and OUT control traffic to be put on the same EP/SB list. */
+                out_traffic = 1;
+        } else {
+                out_traffic = usb_pipeout(urb->pipe);
+        }
+
+	save_flags(flags);
+	cli();
+
 	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
 	nop();
-	*R_USB_EPT_DATA = IO_STATE(R_USB_EPT_DATA, valid, yes) |
-		IO_FIELD(R_USB_EPT_DATA, ep, endpoint) |
-		IO_FIELD(R_USB_EPT_DATA, dev, devnum) |
-		IO_FIELD(R_USB_EPT_DATA, max_len, packsize) |
-		IO_FIELD(R_USB_EPT_DATA, low_speed, slow);
-
-	if (out_traffic)
-		set_bit(epid, (void *)&ep_out_traffic);
-	else
-		clear_bit(epid, (void *)&ep_out_traffic);
 
+	if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+		*R_USB_EPT_DATA_ISO = IO_STATE(R_USB_EPT_DATA_ISO, valid, yes) |
+			/* FIXME: Change any to the actual port? */
+			IO_STATE(R_USB_EPT_DATA_ISO, port, any) |
+			IO_FIELD(R_USB_EPT_DATA_ISO, max_len, maxlen) |
+			IO_FIELD(R_USB_EPT_DATA_ISO, ep, endpoint) |
+			IO_FIELD(R_USB_EPT_DATA_ISO, dev, devnum);
+	} else {
+		*R_USB_EPT_DATA = IO_STATE(R_USB_EPT_DATA, valid, yes) |
+			IO_FIELD(R_USB_EPT_DATA, low_speed, slow) |
+			/* FIXME: Change any to the actual port? */
+			IO_STATE(R_USB_EPT_DATA, port, any) |
+			IO_FIELD(R_USB_EPT_DATA, max_len, maxlen) |
+			IO_FIELD(R_USB_EPT_DATA, ep, endpoint) |
+			IO_FIELD(R_USB_EPT_DATA, dev, devnum);
+	}	
+	
 	restore_flags(flags);
 
-	dbg_ep("Setting up ep_id %d with devnum %d, endpoint %d and max_len %d (%s)",
-	       epid, devnum, endpoint, packsize, out_traffic ? "OUT" : "IN");
+        if (out_traffic) {
+                set_bit(epid, (void *)&epid_out_traffic);
+        } else {
+                clear_bit(epid, (void *)&epid_out_traffic);
+	}
+
+	dbg_epid("Setting up epid %d with devnum %d, endpoint %d and max_len %d (%s)",
+                 epid, devnum, endpoint, maxlen, out_traffic ? "OUT" : "IN");
 
 	DBFEXIT;
+	return epid;
 }
 
 static void etrax_usb_free_epid(int epid)
@@ -826,7 +1091,7 @@
 	
 	DBFENTER;
 
-	if (!test_bit(epid, (void *)&ep_usage_bitmask)) {
+	if (!test_bit(epid, (void *)&epid_usage_bitmask)) {
 		warn("Trying to free unused epid %d", epid);
 		DBFEXIT;
 		return;
@@ -837,56 +1102,81 @@
 
 	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid);
 	nop();
-	while (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold))
-		printk("+");
+	while (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold));
+        /* This will, among other things, set the valid field to 0. */
 	*R_USB_EPT_DATA = 0;
-	clear_bit(epid, (void *)&ep_usage_bitmask);
-
 	restore_flags(flags);
 
-	dbg_ep("epid: %d freed", epid);
+	clear_bit(epid, (void *)&epid_usage_bitmask);
+
+
+	dbg_epid("Freed epid %d", epid);
 	
 	DBFEXIT;
 }
 
-
-static int etrax_usb_lookup_epid(unsigned char devnum, char endpoint, char slow, int maxp, char out_traffic)
+static int etrax_usb_lookup_epid(urb_t *urb)
 {
 	int i;
-	unsigned long flags;
 	__u32 data;
-	
+	char devnum, endpoint, slow, out_traffic;
+	int maxlen;
+	unsigned long flags;
+
 	DBFENTER;
 
-	save_flags(flags);
-	cli();
+	devnum = usb_pipedevice(urb->pipe);
+	endpoint = usb_pipeendpoint(urb->pipe);
+	slow = usb_pipeslow(urb->pipe);
+	maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
+        if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
+                /* We want both IN and OUT control traffic to be put on the same EP/SB list. */
+                out_traffic = 1;
+        } else {
+                out_traffic = usb_pipeout(urb->pipe);
+        }
+        
+	/* Step through att epids. */
+	for (i = 0; i < NBR_OF_EPIDS; i++) {
+		if (test_bit(i, (void *)&epid_usage_bitmask) &&
+                    test_bit(i, (void *)&epid_out_traffic) == out_traffic) {
 
-	/* Skip first ep_id since it is reserved when intr. or iso traffic is used */
-	for (i = 0; i < NBR_OF_EP_DESC; i++) {
-		if (test_bit(i, (void *)&ep_usage_bitmask) &&
-		    test_bit(i, (void *)&ep_out_traffic) == out_traffic) {
+			save_flags(flags);
+			cli();
 			*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, i);
 			nop();
-			data = *R_USB_EPT_DATA;
-			if ((IO_MASK(R_USB_EPT_DATA, valid) & data) &&
-			    (IO_EXTRACT(R_USB_EPT_DATA, dev, data) == devnum) &&
-			    (IO_EXTRACT(R_USB_EPT_DATA, ep, data) == endpoint) &&
-			    (IO_EXTRACT(R_USB_EPT_DATA, low_speed, data) == slow) &&
-			    (IO_EXTRACT(R_USB_EPT_DATA, max_len, data) == maxp)) {
+
+			if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+				data = *R_USB_EPT_DATA_ISO;
 				restore_flags(flags);
-	
-				dbg_ep("Found ep_id %d for devnum %d, endpoint %d (%s)",
-				       i, devnum, endpoint, out_traffic ? "OUT" : "IN");
-				DBFEXIT;
-				return i;
+
+				if ((IO_MASK(R_USB_EPT_DATA_ISO, valid) & data) &&
+                                    (IO_EXTRACT(R_USB_EPT_DATA_ISO, dev, data) == devnum) &&
+                                    (IO_EXTRACT(R_USB_EPT_DATA_ISO, ep, data) == endpoint) &&
+                                    (IO_EXTRACT(R_USB_EPT_DATA_ISO, max_len, data) == maxlen)) {
+                                        dbg_epid("Found epid %d for devnum %d, endpoint %d (%s)",
+                                                 i, devnum, endpoint, out_traffic ? "OUT" : "IN");
+                                        DBFEXIT;
+                                        return i;
+				}
+			} else {
+				data = *R_USB_EPT_DATA;
+				restore_flags(flags);
+
+				if ((IO_MASK(R_USB_EPT_DATA, valid) & data) &&
+				    (IO_EXTRACT(R_USB_EPT_DATA, dev, data) == devnum) &&
+				    (IO_EXTRACT(R_USB_EPT_DATA, ep, data) == endpoint) &&
+				    (IO_EXTRACT(R_USB_EPT_DATA, low_speed, data) == slow) &&
+				    (IO_EXTRACT(R_USB_EPT_DATA, max_len, data) == maxlen)) {	
+					dbg_epid("Found epid %d for devnum %d, endpoint %d (%s)",
+                                                 i, devnum, endpoint, out_traffic ? "OUT" : "IN");
+					DBFEXIT;
+					return i;
+				}
 			}
 		}
 	}
 
-	restore_flags(flags);
-	
-	dbg_ep("Found no ep_id for devnum %d, endpoint %d (%s)",
-	       devnum, endpoint, out_traffic ? "OUT" : "IN");
 	DBFEXIT;
 	return -1;
 }
@@ -897,434 +1187,993 @@
 	
 	DBFENTER;
 
-	for (i = 0; i < NBR_OF_EP_DESC; i++) {
-		if (!test_bit(i, (void *)&ep_usage_bitmask)) {
-			dbg_ep("Found free ep_id at %d", i);
+	for (i = 0; i < NBR_OF_EPIDS; i++) {
+		if (!test_bit(i, (void *)&epid_usage_bitmask)) {
+			dbg_epid("Found free epid %d", i);
 			DBFEXIT;
 			return i;
 		}
 	}
 
-	dbg_ep("Found no free ep_id's");
+	dbg_epid("Found no free epids");
 	DBFEXIT;
 	return -1;
 }
 
-static int etrax_usb_submit_bulk_urb(struct urb *urb)
+static int etrax_usb_submit_urb(urb_t *urb)
 {
-	int epid;
-	char devnum;
-	char endpoint;
-	char maxlen;
-	char out_traffic;
-	char slow;
-
-	struct urb *tmp_urb;
-	
-	unsigned long flags;
+	etrax_hc_t *hc;
+	int ret = -EINVAL;
 	
 	DBFENTER;
 
-	devnum = usb_pipedevice(urb->pipe);
-	endpoint = usb_pipeendpoint(urb->pipe);
-	maxlen = usb_maxpacket(urb->dev, urb->pipe,
-			       usb_pipeout(urb->pipe));
-	out_traffic = usb_pipeout(urb->pipe);
-	slow = usb_pipeslow(urb->pipe);
+        if (!urb->dev || !urb->dev->bus) {
+                return -ENODEV;
+        }
+	if (urb->next != NULL) {
+                /* Is it possible for urb to be the head of a list of urbs (via the urb's
+                   next pointer), used for example in drivers for isochronous traffic.
+                   I haven't seen a device driver that relies on it being used for submit
+                   or unlink, so we warn about it and ignore it. */
+		warn("Urbs are linked, ignoring.");
+	}
+        if (urb->timeout) {
+                /* FIXME. */
+                warn("urb->timeout specified, ignoring.");
+        }
+        
+	hc = (etrax_hc_t*)urb->dev->bus->hcpriv;
 	
-	epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen, out_traffic);
-	if (epid == -1) {
-		epid = etrax_usb_allocate_epid();
-		if (epid == -1) {
-			/* We're out of endpoints, return some error */
-			err("We're out of endpoints");
-			return -ENOMEM;
+	if (usb_pipedevice(urb->pipe) == hc->rh.devnum) {
+		/* This request is for the Virtual Root Hub. */
+		ret = etrax_rh_submit_urb(urb);
+
+	} else if (usb_pipetype(urb->pipe) == PIPE_BULK) {
+
+		ret = etrax_usb_submit_bulk_urb(urb);
+
+	} else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
+
+		ret = etrax_usb_submit_ctrl_urb(urb);
+
+	} else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
+		int bustime;
+                
+		if (urb->bandwidth == 0) {
+			bustime = usb_check_bandwidth(urb->dev, urb);
+			if (bustime < 0) {
+				ret = bustime;
+			} else {
+				ret = etrax_usb_submit_intr_urb(urb);
+				if (ret == 0)
+                                        usb_claim_bandwidth(urb->dev, urb, bustime, 0);
+			}
+                } else {
+                        /* Bandwidth already set. */
+                        ret = etrax_usb_submit_intr_urb(urb);
+		}
+
+	} else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+                int bustime;
+        
+		if (urb->bandwidth == 0) {
+			bustime = usb_check_bandwidth(urb->dev, urb);
+			if (bustime < 0) {
+				ret = bustime;
+			} else {
+				ret = etrax_usb_submit_isoc_urb(urb);
+				if (ret == 0)
+                                        usb_claim_bandwidth(urb->dev, urb, bustime, 0);
+			}
+                } else {
+                        /* Bandwidth already set. */
+                        ret = etrax_usb_submit_isoc_urb(urb);
 		}
-		/* Now we have to fill in this ep */
-		etrax_usb_setup_epid(epid, devnum, endpoint, maxlen, slow, out_traffic);
 	}
-	/* Ok, now we got valid endpoint, lets insert some traffic */
 
-	urb->status = -EINPROGRESS;
+	DBFEXIT;
 
-	save_flags(flags);
-	cli();
-	
-	if (URB_List[epid]) {
-		/* Find end of list and add */
-		for (tmp_urb = URB_List[epid]; tmp_urb->next; tmp_urb = tmp_urb->next)
-			dump_urb(tmp_urb);
+	return ret;
+}
+
+static int etrax_usb_unlink_urb(urb_t *urb)
+{
+        etrax_hc_t *hc;
+        etrax_urb_priv_t *urb_priv;
+        int epid;
+
+	DBFENTER;
+        
+        if (!urb) {
+                return -EINVAL;
+        }        
+        if (!urb->dev || !urb->dev->bus) {
+                return -ENODEV;
+        }
+        if (!urb->hcpriv) {
+                /* This happens if a device driver calls unlink on an urb that
+                   was never submitted (lazy driver). */
+                return 0;
+        }
+        if (urb->transfer_flags & USB_ASYNC_UNLINK) {
+                /* FIXME. */
+                /* If USB_ASYNC_UNLINK is set:
+                   unlink
+                   move to a separate urb list
+                   call complete at next sof with ECONNRESET
+                   
+                   If not:
+                   wait 1 ms
+                   unlink
+                   call complete with ENOENT
+                */
+                warn("USB_ASYNC_UNLINK set, ignoring.");
+        }
+        
+        /* One might think that urb->status = -EINPROGRESS would be a requirement for unlinking,
+           but that doesn't work for interrupt and isochronous traffic since they are completed
+           repeatedly, and urb->status is set then. That may in itself be a bug though. */
+
+        hc = urb->dev->bus->hcpriv;
+        urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
+        epid = urb_priv->epid;
+
+        /* Set the urb status (synchronous unlink). */
+        urb->status = -ENOENT;
+        urb_priv->urb_state = UNLINK;
+        
+	if (usb_pipedevice(urb->pipe) == hc->rh.devnum) {
+		int ret;
+		ret = etrax_rh_unlink_urb(urb);
+		DBFEXIT;
+		return ret;
 
-		tmp_urb->next = urb;
-		restore_flags(flags);
-	} else {
-		/* If this is the first URB, add the URB and do HW add */
-		URB_List[epid] = urb;
-		restore_flags(flags);
-		etrax_usb_do_bulk_hw_add(urb, epid, maxlen);
-	}
+	} else if (usb_pipetype(urb->pipe) == PIPE_BULK) {
+
+                dbg_bulk("Unlink of bulk urb (0x%lx)", (unsigned long)urb);
+
+                if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
+                        /* The EP was enabled, disable it and wait. */
+                        TxBulkEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
+                        
+                        /* Ah, the luxury of busy-wait. */
+                        while (*R_DMA_CH8_SUB0_EP == virt_to_phys(&TxBulkEPList[epid]));
+                }
+		/* Kicking dummy list out of the party. */
+		TxBulkEPList[epid].next = virt_to_phys(&TxBulkEPList[(epid + 1) % NBR_OF_EPIDS]);
+
+        } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
+
+                dbg_ctrl("Unlink of ctrl urb (0x%lx)", (unsigned long)urb);
+
+                if (TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
+                        /* The EP was enabled, disable it and wait. */
+                        TxCtrlEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
+                        
+                        /* Ah, the luxury of busy-wait. */
+                        while (*R_DMA_CH8_SUB1_EP == virt_to_phys(&TxCtrlEPList[epid]));
+                }
+
+	} else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
+
+                dbg_intr("Unlink of intr urb (0x%lx)", (unsigned long)urb);
+
+                /* Separate function because it's a tad more complicated. */
+		etrax_usb_unlink_intr_urb(urb);
+
+        } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
 
+                dbg_isoc("Unlink of isoc urb (0x%lx)", (unsigned long)urb);
+
+                if (TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
+                        /* The EP was enabled, disable it and wait. */
+                        TxIsocEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
+                        
+                        /* Ah, the luxury of busy-wait. */
+                        while (*R_DMA_CH8_SUB3_EP == virt_to_phys(&TxIsocEPList[epid]));
+                }
+        }
+
+        /* Note that we need to remove the urb from the urb list *before* removing its SB
+           descriptors. (This means that the isoc eof handler might get a null urb when we
+           are unlinking the last urb.) */
+
+        urb_list_del(urb, epid);
+
+        if (usb_pipetype(urb->pipe) == PIPE_BULK) {
+
+                TxBulkEPList[epid].sub = 0;
+                etrax_remove_from_sb_list(urb);
+
+        } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
+
+                TxCtrlEPList[epid].sub = 0;
+                etrax_remove_from_sb_list(urb);
+
+        } else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
+
+                /* Sanity check (should never happen). */
+                assert(urb_list_empty(epid));
+
+                /* Release allocated bandwidth. */
+                usb_release_bandwidth(urb->dev, urb, 0);
+
+        } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+
+                if (usb_pipeout(urb->pipe)) {
+                        /* FIXME: If the SB list isn't empty at this point, we need to set up 
+                           the EP descriptor again. */
+                } else {
+                        /* For in traffic there is only one SB descriptor for each EP even
+                           though there may be several urbs (all urbs point at the same SB). */
+                        if (urb_list_empty(epid)) {
+                                /* No more urbs, remove the SB. */
+                                TxIsocEPList[epid].sub = 0;
+                                etrax_remove_from_sb_list(urb);
+                        }
+                }
+                /* Release allocated bandwidth. */
+                usb_release_bandwidth(urb->dev, urb, 1);
+        } 
+        
+        /* Must be done before calling completion handler. */
+        kfree(urb_priv);
+        urb->hcpriv = 0;
+
+        if (urb->complete) {
+                urb->complete(urb);
+        }
+
+        /* Free the epid if urb list is empty. */
+        if (urb_list_empty(epid)) {
+                etrax_usb_free_epid(epid);
+        }
+
+        DBFEXIT;
+        return 0;
+}
+
+static int etrax_usb_get_frame_number(struct usb_device *usb_dev)
+{
+	DBFENTER;
 	DBFEXIT;
+	return (*R_USB_FM_NUMBER & 0x7ff);
+}
 
+static int etrax_usb_allocate_dev(struct usb_device *usb_dev)
+{  
+	DBFENTER;
+	DBFEXIT;
 	return 0;
 }
 
-static void etrax_usb_do_bulk_hw_add(struct urb *urb, int epid, char maxlen)
+static int etrax_usb_deallocate_dev(struct usb_device *usb_dev)
 {
-	USB_SB_Desc_t *sb_desc_1;
+	DBFENTER;
+	DBFEXIT;
+	return 0;
+}
+
+static void etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs)
+{
+	DBFENTER;
+
+        /* This interrupt handler could be used when unlinking EP descriptors. */
+
+	if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub0_descr)) {
+		USB_EP_Desc_t *ep;
+
+		//dbg_bulk("dma8_sub0_descr (BULK) intr.");
+
+		/* It should be safe clearing the interrupt here, since we don't expect to get a new
+		   one until we restart the bulk channel. */
+		*R_DMA_CH8_SUB0_CLR_INTR = IO_STATE(R_DMA_CH8_SUB0_CLR_INTR, clr_descr, do);
 
+		/* Wait while the DMA is running (though we don't expect it to be). */
+		while (*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd));
+
+		/* Advance the DMA to the next EP descriptor. */
+		ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB0_EP);
+
+		//dbg_bulk("descr intr: DMA is at 0x%lx", (unsigned long)ep);
+
+		/* ep->next is already a physical address; no need for a virt_to_phys. */
+		*R_DMA_CH8_SUB0_EP = ep->next;
+
+		/* Start the DMA bulk channel again. */
+		*R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start);
+	}
+	if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub1_descr)) {
+		dbg_ctrl("dma8_sub1_descr (CTRL) intr.");
+		*R_DMA_CH8_SUB1_CLR_INTR = IO_STATE(R_DMA_CH8_SUB1_CLR_INTR, clr_descr, do);
+	}
+	if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub2_descr)) {
+		dbg_intr("dma8_sub2_descr (INTR) intr.");
+		*R_DMA_CH8_SUB2_CLR_INTR = IO_STATE(R_DMA_CH8_SUB2_CLR_INTR, clr_descr, do);
+	}
+	if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub3_descr)) {
+		dbg_isoc("dma8_sub3_descr (ISOC) intr.");
+		*R_DMA_CH8_SUB3_CLR_INTR = IO_STATE(R_DMA_CH8_SUB3_CLR_INTR, clr_descr, do);
+	}
+        
+	DBFEXIT;
+}
+
+static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs)
+{
+	urb_t *urb;
 	etrax_urb_priv_t *urb_priv;
+	int epid = 0;
+        unsigned long flags;
 
-	unsigned long flags;
+        /* Isoc diagnostics. */
+        static int curr_fm = 0;
+        static int prev_fm = 0;
+
+        DBFENTER;
+
+        /* Clear this interrupt. */
+	*R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do);
+
+        /* Note that this while loop assumes that all packets span only
+           one rx descriptor. */
+
+        /* The reason we cli here is that we call the driver's callback functions. */
+        save_flags(flags);
+        cli();
+
+
+ 	while (myNextRxDesc->status & IO_MASK(USB_IN_status, eop)) {
+
+                epid = IO_EXTRACT(USB_IN_status, epid, myNextRxDesc->status);
+                urb = urb_list_first(epid);
+
+                //printk("eop for epid %d, first urb 0x%lx\n", epid, (unsigned long)urb);
+                
+                if (!urb) {
+                        err("No urb for epid %d in rx interrupt", epid);
+			__dump_ept_data(epid);
+                        goto skip_out;
+                }
+
+                /* Note that we cannot indescriminately assert(usb_pipein(urb->pipe)) since
+                   ctrl pipes are not. */
+                
+		if (myNextRxDesc->status & IO_MASK(USB_IN_status, error)) {
+			warn("error in rx desc->status, epid %d, first urb = 0x%lx", 
+                             epid, (unsigned long)urb);
+			__dump_in_desc(myNextRxDesc);
+                        etrax_usb_complete_urb(urb, -EPROTO);
+			goto skip_out;
+		}
+
+                urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
+                assert(urb_priv);
+                
+                if ((usb_pipetype(urb->pipe) == PIPE_BULK) || 
+                    (usb_pipetype(urb->pipe) == PIPE_CONTROL) ||
+                    (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) {
+
+                        if (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata)) {
+                                /* We get nodata for empty data transactions, and the rx descriptor's
+                                   hw_len field is not valid in that case. No data to copy in other 
+                                   words. */
+                        } else {
+                                /* Make sure the data fits in the buffer. */
+                                assert(urb_priv->rx_offset + myNextRxDesc->hw_len 
+                                       <= urb->transfer_buffer_length);
+
+                                memcpy(urb->transfer_buffer + urb_priv->rx_offset,
+                                       phys_to_virt(myNextRxDesc->buf), myNextRxDesc->hw_len);	
+                                urb_priv->rx_offset += myNextRxDesc->hw_len;
+                        }
+
+                        if (myNextRxDesc->status & IO_MASK(USB_IN_status, eot)) {
+                                etrax_usb_complete_urb(urb, 0);
+                        }
+
+                } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+                        
+                        iso_packet_descriptor_t *packet;
+
+                        if (urb_priv->urb_state == UNLINK) {
+                                info("Ignoring rx data for urb being unlinked.");
+                                goto skip_out;
+                        } else if (urb_priv->urb_state == NOT_STARTED) {
+                                info("What? Got rx data for urb that isn't started?");
+                                goto skip_out;
+                        }
+                                
+                        packet = &urb->iso_frame_desc[urb_priv->isoc_packet_counter];
+                        packet->status = 0;
+
+                         if (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata)) {
+                                /* We get nodata for empty data transactions, and the rx descriptor's
+                                   hw_len field is not valid in that case. We copy 0 bytes however to
+                                   stay in synch. */
+                                packet->actual_length = 0;                                
+                        } else {
+                                packet->actual_length = myNextRxDesc->hw_len;
+                                /* Make sure the data fits in the buffer. */
+                                assert(packet->actual_length <= packet->length);
+                                
+                                memcpy(urb->transfer_buffer + packet->offset,
+                                       phys_to_virt(myNextRxDesc->buf), packet->actual_length);
+                        }
+
+                        /* Increment the packet counter. */
+                        urb_priv->isoc_packet_counter++;	
+                        
+                        /* Note that we don't care about the eot field in the rx descriptor's status.
+                           It will always be set for isoc traffic. */
+			if (urb->number_of_packets == urb_priv->isoc_packet_counter) {
+
+                                /* Out-of-synch diagnostics. */
+                                curr_fm = (*R_USB_FM_NUMBER & 0x7ff);
+                                if (((prev_fm + urb_priv->isoc_packet_counter) % (0x7ff + 1)) != curr_fm) {
+                                        warn("Out of synch? Previous frame = %d, current frame = %d",
+                                             prev_fm, curr_fm);
+                                }
+                                prev_fm = curr_fm;
+
+				/* Complete the urb with status OK. */
+				etrax_usb_complete_isoc_urb(urb, 0);
+
+				/* Must set this to 0 since this urb is still active after
+				   completion. */
+				urb_priv->isoc_packet_counter = 0;
+			}
+                }
+                
+	skip_out:
+
+                /* DMA IN cache bug. Flush the DMA IN buffer from the cache. (struct etrax_dma_descr
+		   has the same layout as USB_IN_Desc for the relevant fields.) */
+                prepare_rx_descriptor((struct etrax_dma_descr*)myNextRxDesc);
+
+		myPrevRxDesc = myNextRxDesc;
+		myPrevRxDesc->command |= IO_MASK(USB_IN_command, eol);
+		myLastRxDesc->command &= ~IO_MASK(USB_IN_command, eol);
+		myLastRxDesc = myPrevRxDesc;
+
+		myNextRxDesc->status = 0;
+		myNextRxDesc = phys_to_virt(myNextRxDesc->next);
+	}
+
+        restore_flags(flags);
+        
+        DBFEXIT;
+        
+}
+
+
+/* This function will unlink the SB descriptors associated with this urb. */
+static int etrax_remove_from_sb_list(urb_t *urb)
+{
+	USB_SB_Desc_t *next_sb, *first_sb, *last_sb;
+	etrax_urb_priv_t *urb_priv;
+	int i = 0;
 
 	DBFENTER;
 
-	urb_priv = kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL);
-	sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+	urb_priv = (etrax_urb_priv_t *)urb->hcpriv; 
+	assert(urb_priv);
 
-	if (usb_pipeout(urb->pipe)) {
+        /* Just a sanity check. Since we don't fiddle with the DMA list the EP descriptor
+	   doesn't really need to be disabled, it's just that we expect it to be. */
+        if (usb_pipetype(urb->pipe) == PIPE_BULK) {
+                assert(!(TxBulkEPList[urb_priv->epid].command & IO_MASK(USB_EP_command, enable)));
+        } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
+                assert(!(TxCtrlEPList[urb_priv->epid].command & IO_MASK(USB_EP_command, enable)));
+        } 
 
-		dbg_bulk("Bulk transfer for epid %d is OUT", epid);
-		dbg_bulk("transfer_buffer_length == %d", urb->transfer_buffer_length);
-		dbg_bulk("actual_length == %d", urb->actual_length);
+	first_sb = urb_priv->first_sb;
+	last_sb = urb_priv->last_sb;
 	
+        assert(first_sb);
+        assert(last_sb);
+        
+	while (first_sb != last_sb) {
+		next_sb = (USB_SB_Desc_t *)phys_to_virt(first_sb->next);
+		kmem_cache_free(usb_desc_cache, first_sb);
+		first_sb = next_sb;
+		i++;
+	}
+	kmem_cache_free(usb_desc_cache, last_sb);
+	i++;
+	dbg_sb("%d SB descriptors freed", i);
+	/* Compare i with urb->number_of_packets for Isoc traffic. 
+	   Should be same when calling unlink_urb */
+	
+	DBFEXIT;
+	
+	return i;
+}
+
+static int etrax_usb_submit_bulk_urb(urb_t *urb)
+{
+	int epid;
+        int empty;
+        unsigned long flags;
+        
+	DBFENTER;
+
+        /* Epid allocation, empty check and list add must be protected. 
+           Read about this in etrax_usb_submit_ctrl_urb. */
+
+        spin_lock_irqsave(&urb_list_lock, flags);
+	epid = etrax_usb_setup_epid(urb);
+	if (epid == -1) {
+		DBFEXIT;
+                spin_unlock_irqrestore(&urb_list_lock, flags);
+		return -ENOMEM;
+	}
+        empty = urb_list_empty(epid);
+        urb_list_add(urb, epid);
+        spin_unlock_irqrestore(&urb_list_lock, flags);
+
+        /* USB_QUEUE_BULK is UHCI-specific, but we warn anyway. */
+        if (!(urb->transfer_flags & USB_QUEUE_BULK) && !empty) {
+                warn("USB_QUEUE_BULK is not set and urb queue is not empty, ignoring.");
+        }
+
+        dbg_bulk("Adding bulk %s urb 0x%lx to %s list, epid %d", 
+                 usb_pipein(urb->pipe) ? "IN" : "OUT", (unsigned long)urb, empty ? "empty" : "", epid);
+
+        /* Mark the urb as being in progress. */
+	urb->status = -EINPROGRESS;
+
+        if (empty) {
+                etrax_usb_add_to_bulk_sb_list(urb, epid);
+        }
+	        
+	DBFEXIT;
+
+	return 0;
+}
+
+static void etrax_usb_add_to_bulk_sb_list(urb_t *urb, int epid)
+{
+	USB_SB_Desc_t *sb_desc;
+	etrax_urb_priv_t *urb_priv;
+	unsigned long flags;
+	char maxlen;
+
+	DBFENTER;
+
+	dbg_bulk("etrax_usb_add_to_bulk_sb_list, urb 0x%lx", (unsigned long)urb);
+
+	maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
+	
+	urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG);
+	assert(urb_priv != NULL);
+        /* This sets rx_offset to 0. */
+        memset(urb_priv, 0, sizeof(etrax_urb_priv_t));
+        
+	sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
+	assert(sb_desc != NULL);
+	memset(sb_desc, 0, sizeof(USB_SB_Desc_t));
+
+
+	if (usb_pipeout(urb->pipe)) {
+                
+		dbg_bulk("Grabbing bulk OUT, urb 0x%lx, epid %d", (unsigned long)urb, epid);
+                
+                /* This is probably a sanity check of the bulk transaction length
+                   not being larger than 64 kB. */
 		if (urb->transfer_buffer_length > 0xffff) {
-			panic(__FILE__ __FUNCTION__ ":urb->transfer_buffer_length > 0xffff\n");
+			panic("urb->transfer_buffer_length > 0xffff");
 		}
 
-		sb_desc_1->sw_len = urb->transfer_buffer_length;  /* was actual_length */
-		sb_desc_1->command = IO_FIELD(USB_SB_command, rem, 0) |
-			IO_STATE(USB_SB_command, tt, out) |
+		sb_desc->sw_len = urb->transfer_buffer_length;
 
-#if 0
-			IO_STATE(USB_SB_command, full, no) |
-#else
-			IO_STATE(USB_SB_command, full, yes) |
-#endif
+                /* The rem field is don't care if it's not a full-length transfer, so setting
+                   it shouldn't hurt. Also, rem isn't used for OUT traffic. */
+		sb_desc->command = (IO_FIELD(USB_SB_command, rem, 0) |
+                                    IO_STATE(USB_SB_command, tt, out) |
+                                    IO_STATE(USB_SB_command, eot, yes) |
+                                    IO_STATE(USB_SB_command, eol, yes));
+
+                /* The full field is set to yes, even if we don't actually check that this is
+                   a full-length transfer (i.e., that transfer_buffer_length % maxlen = 0).
+                   Setting full prevents the USB controller from sending an empty packet in
+                   that case.  However, if USB_ZERO_PACKET was set we want that. */
+                if (!(urb->transfer_flags & USB_ZERO_PACKET)) {
+                        sb_desc->command |= IO_STATE(USB_SB_command, full, yes);
+                }
 
-			IO_STATE(USB_SB_command, eot, yes) |
-			IO_STATE(USB_SB_command, eol, yes);
-		
-		dbg_bulk("transfer_buffer is at 0x%08X", urb->transfer_buffer);
-		
-		sb_desc_1->buf = virt_to_phys(urb->transfer_buffer);
-		sb_desc_1->next = 0;
+		sb_desc->buf = virt_to_phys(urb->transfer_buffer);
+		sb_desc->next = 0;
 		
 	} else if (usb_pipein(urb->pipe)) {
 
-		dbg_bulk("Transfer for epid %d is IN", epid);
-		dbg_bulk("transfer_buffer_length = %d", urb->transfer_buffer_length);
-		dbg_bulk("rem is calculated to %d", urb->transfer_buffer_length % maxlen);
-		
-		sb_desc_1->sw_len = urb->transfer_buffer_length ?
+                dbg_bulk("Grabbing bulk IN, urb 0x%lx, epid %d", (unsigned long)urb, epid);
+
+		sb_desc->sw_len = urb->transfer_buffer_length ?
 			(urb->transfer_buffer_length - 1) / maxlen + 1 : 0;
-		dbg_bulk("sw_len got %d", sb_desc_1->sw_len);
-		dbg_bulk("transfer_buffer is at 0x%08X", urb->transfer_buffer);
-		
-		sb_desc_1->command =
-			IO_FIELD(USB_SB_command, rem,
-				 urb->transfer_buffer_length % maxlen) |
-			IO_STATE(USB_SB_command, tt, in) |
-			IO_STATE(USB_SB_command, eot, yes) |
-			IO_STATE(USB_SB_command, eol, yes);
 		
-		sb_desc_1->buf = 0;
-		sb_desc_1->next = 0;
+                /* The rem field is don't care if it's not a full-length transfer, so setting
+                   it shouldn't hurt. */
+		sb_desc->command =
+			(IO_FIELD(USB_SB_command, rem,
+                                  urb->transfer_buffer_length % maxlen) |
+                         IO_STATE(USB_SB_command, tt, in) |
+                         IO_STATE(USB_SB_command, eot, yes) |
+                         IO_STATE(USB_SB_command, eol, yes));
+		
+		sb_desc->buf = 0;
+		sb_desc->next = 0;
+	}
+	
+	urb_priv->first_sb = sb_desc;
+	urb_priv->last_sb = sb_desc;
+	urb_priv->epid = epid;
 
-		urb_priv->rx_offset = 0;
-		urb_priv->eot = 0;
-	}
-	
-	urb_priv->first_sb = sb_desc_1;
-	
-	urb->hcpriv = (void *)urb_priv;
+	urb->hcpriv = urb_priv;
 	
-	/* Reset toggle bits and reset error count, remeber to di and ei */
-	/* Warning: it is possible that this locking doesn't work with bottom-halves */
-
+	/* Reset toggle bits and reset error count. */
 	save_flags(flags);
 	cli();
 
-	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop();
+	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); 
+        nop();
+
+        /* FIXME: Is this a special case since the hold field is checked,
+           or should we check hold in a lot of other cases as well? */
 	if (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)) {
-		panic("Hold was set in %s\n", __FUNCTION__);
+		panic("Hold was set in %s", __FUNCTION__);
 	}
 
+        /* Reset error counters (regardless of which direction this traffic is). */
 	*R_USB_EPT_DATA &=
 		~(IO_MASK(R_USB_EPT_DATA, error_count_in) |
 		  IO_MASK(R_USB_EPT_DATA, error_count_out));
 	
+        /* Software must preset the toggle bits. */
 	if (usb_pipeout(urb->pipe)) {
 		char toggle =
-		usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
+                        usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
 		*R_USB_EPT_DATA &= ~IO_MASK(R_USB_EPT_DATA, t_out);
 		*R_USB_EPT_DATA |= IO_FIELD(R_USB_EPT_DATA, t_out, toggle);
 	} else {
 		char toggle =
-		usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
+                        usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
 		*R_USB_EPT_DATA &= ~IO_MASK(R_USB_EPT_DATA, t_in);
 		*R_USB_EPT_DATA |= IO_FIELD(R_USB_EPT_DATA, t_in, toggle);
 	}
-		
-	/* Enable the EP descr. */
-
-	set_bit(epid, (void *)&ep_really_active);
-	
-	TxBulkEPList[epid].sub = virt_to_phys(sb_desc_1);
+                
+        /* Assert that the EP descriptor is disabled. */
+        assert(!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)));
+
+        /* The reason we set the EP's sub pointer directly instead of
+           walking the SB list and linking it last in the list is that we only
+           have one active urb at a time (the rest are queued). */
+
+	/* Note that we cannot have interrupts running when we have set the SB descriptor
+	   but the EP is not yet enabled.  If a bulk eot happens for another EP, we will
+	   find this EP disabled and with a SB != 0, which will make us think that it's done. */
+	TxBulkEPList[epid].sub = virt_to_phys(sb_desc);
 	TxBulkEPList[epid].hw_len = 0;
-	TxBulkEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
+        /* Note that we don't have to fill in the ep_id field since this
+           was done when we allocated the EP descriptors in init_tx_bulk_ep. */
+
+	/* Check if the dummy list is already with us (if several urbs were queued). */
+	if (TxBulkEPList[epid].next != virt_to_phys(&TxBulkDummyEPList[epid][0])) {
+
+		dbg_bulk("Inviting dummy list to the party for urb 0x%lx, epid %d", 
+			 (unsigned long)urb, epid);
+
+		/* The last EP in the dummy list already has its next pointer set to 
+		   TxBulkEPList[epid].next. */
 
+		/* We don't need to check if the DMA is at this EP or not before changing the
+		   next pointer, since we will do it in one 32-bit write (EP descriptors are
+		   32-bit aligned). */
+		TxBulkEPList[epid].next = virt_to_phys(&TxBulkDummyEPList[epid][0]);
+	}
+        /* Enable the EP descr. */
+	dbg_bulk("Enabling bulk EP for urb 0x%lx, epid %d", (unsigned long)urb, epid);
+        TxBulkEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
+
+	/* Everything is set up, safe to enable interrupts again. */
 	restore_flags(flags);
 
+        /* If the DMA bulk channel isn't running, we need to restart it if it
+	   has stopped at the last EP descriptor (DMA stopped because there was
+	   no more traffic) or if it has stopped at a dummy EP with the intr flag
+	   set (DMA stopped because we were too slow in inserting new traffic). */
 	if (!(*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd))) {
-		*R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start);
-		
-	}
 
+		USB_EP_Desc_t *ep;
+		ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB0_EP);
+		dbg_bulk("DMA channel not running in add");
+		dbg_bulk("DMA is at 0x%lx", (unsigned long)ep);
+
+		if (*R_DMA_CH8_SUB0_EP == virt_to_phys(&TxBulkEPList[NBR_OF_EPIDS - 1]) ||
+		    (ep->command & 0x8) >> 3) {
+			*R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start);
+			/* Update/restart the bulk start timer since we just started the channel. */
+			mod_timer(&bulk_start_timer, jiffies + BULK_START_TIMER_INTERVAL);
+			/* Update/restart the bulk eot timer since we just inserted traffic. */
+			mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL);
+		}
+	}
+        
 	DBFEXIT;
 }
 
-static void handle_bulk_transfer_attn(int epid, int status)
+static void etrax_usb_complete_bulk_urb(urb_t *urb, int status)
 {
-	struct urb *old_urb;
-	etrax_urb_priv_t *hc_priv;
-	unsigned long flags;
-
+	etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
+	int epid = urb_priv->epid;
+        unsigned long flags;
+        
 	DBFENTER;
 
-	clear_bit(epid, (void *)&ep_really_active);
-	
-	old_urb = URB_List[epid];
-	URB_List[epid] = old_urb->next;
+        if (status)
+                warn("Completing bulk urb with status %d.", status);
+
+	dbg_bulk("Completing bulk urb 0x%lx for epid %d", (unsigned long)urb, epid);
+
+	/* Update the urb list. */	
+        urb_list_del(urb, epid);
 
-	/* if (status == 0 && IN) find data and copy to urb */
-	if (status == 0 && usb_pipein(old_urb->pipe)) {
-		etrax_urb_priv_t *urb_priv;
-		
-		urb_priv = (etrax_urb_priv_t *)old_urb->hcpriv;
-		save_flags(flags);
-		cli();
-		if (urb_priv->eot == 1) {
-			old_urb->actual_length = urb_priv->rx_offset;
+        /* For an IN pipe, we always set the actual length, regardless of whether there was
+           an error or not (which means the device driver can use the data if it wants to). */
+	if (usb_pipein(urb->pipe)) {
+                urb->actual_length = urb_priv->rx_offset;
+	} else {
+		/* Set actual_length for OUT urbs also; the USB mass storage driver seems
+		   to want that. We wouldn't know of any partial writes if there was an error. */
+		if (status == 0) {
+			urb->actual_length = urb->transfer_buffer_length;
 		} else {
-			if (urb_priv->rx_offset == 0) {
-				status = 0;
-			} else {
-				status = -EPROTO;
-			}
-			
-			old_urb->actual_length = 0;
-			err("(BULK) No eot set in IN data!!! rx_offset is: %d", urb_priv->rx_offset);
+			urb->actual_length = 0;
 		}
-		
-		restore_flags(flags);
 	}
 
+        /* FIXME: Is there something of the things below we shouldn't do if there was an error?
+           Like, maybe we shouldn't toggle the toggle bits, or maybe we shouldn't insert more traffic. */
+
 	save_flags(flags);
 	cli();
 		
-	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop();
-	if (usb_pipeout(old_urb->pipe)) {
+	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); 
+        nop();
+
+        /* We need to fiddle with the toggle bits because the hardware doesn't do it for us. */
+	if (usb_pipeout(urb->pipe)) {
 		char toggle =
-		IO_EXTRACT(R_USB_EPT_DATA, t_out, *R_USB_EPT_DATA);
-		usb_settoggle(old_urb->dev, usb_pipeendpoint(old_urb->pipe),
-			      usb_pipeout(old_urb->pipe), toggle);
+                        IO_EXTRACT(R_USB_EPT_DATA, t_out, *R_USB_EPT_DATA);
+		usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+			      usb_pipeout(urb->pipe), toggle);
 	} else {
 		char toggle =
-		IO_EXTRACT(R_USB_EPT_DATA, t_in, *R_USB_EPT_DATA);
-		usb_settoggle(old_urb->dev, usb_pipeendpoint(old_urb->pipe),
-			      usb_pipeout(old_urb->pipe), toggle);
+                        IO_EXTRACT(R_USB_EPT_DATA, t_in, *R_USB_EPT_DATA);
+		usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
+			      usb_pipeout(urb->pipe), toggle);
+	}
+        restore_flags(flags);
+
+        /* Remember to free the SBs. */
+	etrax_remove_from_sb_list(urb);
+	kfree(urb_priv);
+        urb->hcpriv = 0;
+        
+	/* If there are any more urb's in the list we'd better start sending */
+	if (!urb_list_empty(epid)) {
+
+                urb_t *new_urb;
+
+                /* Get the first urb. */
+                new_urb = urb_list_first(epid);
+		assert(new_urb);
+
+                dbg_bulk("More bulk for epid %d", epid);
+
+		etrax_usb_add_to_bulk_sb_list(new_urb, epid);
+	}
+
+        urb->status = status;
+
+        /* We let any non-zero status from the layer above have precedence. */
+        if (status == 0) {
+                /* USB_DISABLE_SPD means that short reads (shorter than the endpoint's max length)
+                   is to be treated as an error. */
+                if (urb->transfer_flags & USB_DISABLE_SPD) {
+                        if (usb_pipein(urb->pipe) && 
+                            (urb->actual_length != 
+                             usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)))) {
+                                urb->status = -EREMOTEIO;
+                        } 
+                }
+        }
+        
+	if (urb->complete) {
+		urb->complete(urb);
 	}
 
-	restore_flags(flags);
-
-	/* If there are any more URB's in the list we'd better start sending */
-	if (URB_List[epid]) {
-		etrax_usb_do_bulk_hw_add(URB_List[epid], epid,
-					 usb_maxpacket(URB_List[epid]->dev, URB_List[epid]->pipe,
-						       usb_pipeout(URB_List[epid]->pipe)));
-	}
-#if 1
-	else {
-		/* This means that this EP is now free, deconfigure it */
+	if (urb_list_empty(epid)) {
+		/* This means that this EP is now free, deconfigure it. */
 		etrax_usb_free_epid(epid);
-	}
-#endif
-	
-	/* Remember to free the SB's */
-	hc_priv = (etrax_urb_priv_t *)old_urb->hcpriv;
-	cleanup_sb(hc_priv->first_sb);
-	kfree(hc_priv);
+		
+		/* No more traffic; time to clean up.
+		   Must set sub pointer to 0, since we look at the sub pointer when handling
+		   the bulk eot interrupt. */
+
+                dbg_bulk("No bulk for epid %d", epid);
+                
+		TxBulkEPList[epid].sub = 0;
+
+		/* Unlink the dummy list. */
 
-	old_urb->status = status;
-	if (old_urb->complete) {
-		old_urb->complete(old_urb);
+		dbg_bulk("Kicking dummy list out of party for urb 0x%lx, epid %d", 
+			 (unsigned long)urb, epid);
+
+		/* No need to wait for the DMA before changing the next pointer.
+		   The modulo NBR_OF_EPIDS isn't actually necessary, since we will never use
+		   the last one (INVALID_EPID) for actual traffic. */
+		TxBulkEPList[epid].next = 
+			virt_to_phys(&TxBulkEPList[(epid + 1) % NBR_OF_EPIDS]);
 	}
 
 	DBFEXIT;
 }
 
-/* ---------------------------------------------------------------------------- */
-
-static int etrax_usb_submit_ctrl_urb(struct urb *urb)
+static int etrax_usb_submit_ctrl_urb(urb_t *urb)
 {
 	int epid;
-	char devnum;
-	char endpoint;
-	char maxlen;
-	char out_traffic;
-	char slow;
-
-	struct urb *tmp_urb;
-	
-	unsigned long flags;
-	
+        int empty;
+        unsigned long flags;
+        
 	DBFENTER;
 
-	devnum = usb_pipedevice(urb->pipe);
-	endpoint = usb_pipeendpoint(urb->pipe);
-	maxlen = usb_maxpacket(urb->dev, urb->pipe,
-			       usb_pipeout(urb->pipe));
-	out_traffic = usb_pipeout(urb->pipe);
-	slow = usb_pipeslow(urb->pipe);
-	
-	epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen, out_traffic);
+        /* FIXME: Return -ENXIO if there is already a queued urb for this endpoint? */
+
+        /* Epid allocation, empty check and list add must be protected.
+
+           Epid allocation because if we find an existing epid for this endpoint an urb might be
+           completed (emptying the list) before we add the new urb to the list, causing the epid
+           to be de-allocated. We would then start the transfer with an invalid epid -> epid attn.
+
+           Empty check and add because otherwise we might conclude that the list is not empty,
+           after which it becomes empty before we add the new urb to the list, causing us not to 
+           insert the new traffic into the SB list. */
+
+        spin_lock_irqsave(&urb_list_lock, flags);
+	epid = etrax_usb_setup_epid(urb);
 	if (epid == -1) {
-		epid = etrax_usb_allocate_epid();
-		if (epid == -1) {
-			/* We're out of endpoints, return some error */
-			err("We're out of endpoints");
-			return -ENOMEM;
-		}
-		/* Now we have to fill in this ep */
-		etrax_usb_setup_epid(epid, devnum, endpoint, maxlen, slow, out_traffic);
+                spin_unlock_irqrestore(&urb_list_lock, flags);
+		DBFEXIT;
+		return -ENOMEM;
 	}
-	/* Ok, now we got valid endpoint, lets insert some traffic */
+        empty = urb_list_empty(epid);
+        urb_list_add(urb, epid);
+        spin_unlock_irqrestore(&urb_list_lock, flags);
 
+        dbg_ctrl("Adding ctrl urb 0x%lx to %s list, epid %d", 
+                 (unsigned long)urb, empty ? "empty" : "", epid);
+
+        /* Mark the urb as being in progress. */
 	urb->status = -EINPROGRESS;
 
-	save_flags(flags);
-	cli();
-	
-	if (URB_List[epid]) {
-		/* Find end of list and add */
-		for (tmp_urb = URB_List[epid]; tmp_urb->next; tmp_urb = tmp_urb->next)
-			dump_urb(tmp_urb);
-
-		tmp_urb->next = urb;
-		restore_flags(flags);
-	} else {
-		/* If this is the first URB, add the URB and do HW add */
-		URB_List[epid] = urb;
-		restore_flags(flags);
-		etrax_usb_do_ctrl_hw_add(urb, epid, maxlen);
-	}
+        if (empty) {
+                etrax_usb_add_to_ctrl_sb_list(urb, epid);
+        }
 
 	DBFEXIT;
 
 	return 0;
 }
 
-static void etrax_usb_do_ctrl_hw_add(struct urb *urb, int epid, char maxlen)
+static void etrax_usb_add_to_ctrl_sb_list(urb_t *urb, int epid)
 {
-	USB_SB_Desc_t *sb_desc_1;
-	USB_SB_Desc_t *sb_desc_2;
-	USB_SB_Desc_t *sb_desc_3;
+	USB_SB_Desc_t *sb_desc_setup;
+	USB_SB_Desc_t *sb_desc_data;
+	USB_SB_Desc_t *sb_desc_status;
 
 	etrax_urb_priv_t *urb_priv;
 
 	unsigned long flags;
-
+	char maxlen;
+	
 	DBFENTER;
 
-	urb_priv = kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL);
-	sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
-	sb_desc_2 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
-
-	if (!(sb_desc_1 && sb_desc_2)) {
-		panic("kmem_cache_alloc in ctrl_hw_add gave NULL pointers !!!\n");
-	}
-	
-	sb_desc_1->sw_len = 8;
-	sb_desc_1->command = IO_FIELD(USB_SB_command, rem, 0) |
-		IO_STATE(USB_SB_command, tt, setup) |
-		IO_STATE(USB_SB_command, full, yes) |
-		IO_STATE(USB_SB_command, eot, yes);
-	
-	sb_desc_1->buf = virt_to_phys(urb->setup_packet);
-	sb_desc_1->next = virt_to_phys(sb_desc_2);
-	dump_sb_desc(sb_desc_1);
+	maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
+	
+	urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG);
+	assert(urb_priv != NULL);
+        /* This sets rx_offset to 0. */
+        memset(urb_priv, 0, sizeof(etrax_urb_priv_t));
+        
+	sb_desc_setup = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
+	assert(sb_desc_setup != NULL);
+	sb_desc_status = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
+	assert(sb_desc_status != NULL);
+
+	/* Initialize the mandatory setup SB descriptor (used only in control transfers) */	
+	sb_desc_setup->sw_len = 8;
+	sb_desc_setup->command = (IO_FIELD(USB_SB_command, rem, 0) |
+                                  IO_STATE(USB_SB_command, tt, setup) |
+                                  IO_STATE(USB_SB_command, full, yes) |
+                                  IO_STATE(USB_SB_command, eot, yes));
+	
+	sb_desc_setup->buf = virt_to_phys(urb->setup_packet);
 
 	if (usb_pipeout(urb->pipe)) {
-		dbg_ctrl("Transfer for epid %d is OUT", epid);
+                dbg_ctrl("Transfer for epid %d is OUT", epid);
 
 		/* If this Control OUT transfer has an optional data stage we add an OUT token
 		   before the mandatory IN (status) token, hence the reordered SB list */
 		
+		sb_desc_setup->next = virt_to_phys(sb_desc_status);
 		if (urb->transfer_buffer) {
-			dbg_ctrl("This OUT transfer has an extra data stage");
-			sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
 
-			sb_desc_1->next = virt_to_phys(sb_desc_3);
+			dbg_ctrl("This OUT transfer has an extra data stage");
 			
-			sb_desc_3->sw_len = urb->transfer_buffer_length;
-			sb_desc_3->command = IO_STATE(USB_SB_command, tt, out) |
-				IO_STATE(USB_SB_command, full, yes) |
-				IO_STATE(USB_SB_command, eot, yes);
-			sb_desc_3->buf = virt_to_phys(urb->transfer_buffer);
-			sb_desc_3->next = virt_to_phys(sb_desc_2);
-		}
-		
-		sb_desc_2->sw_len = 1;
-		sb_desc_2->command = IO_FIELD(USB_SB_command, rem, 0) |
-			IO_STATE(USB_SB_command, tt, in) |
-			IO_STATE(USB_SB_command, eot, yes) |
-			IO_STATE(USB_SB_command, eol, yes);
-
-		sb_desc_2->buf = 0;
-		sb_desc_2->next = 0;
-		dump_sb_desc(sb_desc_2);
-		
+                        sb_desc_data = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
+                        assert(sb_desc_data != NULL);
+                        
+                        sb_desc_setup->next = virt_to_phys(sb_desc_data);
+                        
+                        sb_desc_data->sw_len = urb->transfer_buffer_length;
+                        sb_desc_data->command = (IO_STATE(USB_SB_command, tt, out) |
+                                                 IO_STATE(USB_SB_command, full, yes) |
+                                                 IO_STATE(USB_SB_command, eot, yes));
+                        sb_desc_data->buf = virt_to_phys(urb->transfer_buffer);
+                        sb_desc_data->next = virt_to_phys(sb_desc_status);
+		}
+		
+		sb_desc_status->sw_len = 1;
+		sb_desc_status->command = (IO_FIELD(USB_SB_command, rem, 0) |
+                                           IO_STATE(USB_SB_command, tt, in) |
+                                           IO_STATE(USB_SB_command, eot, yes) |
+                                           IO_STATE(USB_SB_command, eol, yes));
+
+		sb_desc_status->buf = 0;
+		sb_desc_status->next = 0;
+                
 	} else if (usb_pipein(urb->pipe)) {
 
 		dbg_ctrl("Transfer for epid %d is IN", epid);
 		dbg_ctrl("transfer_buffer_length = %d", urb->transfer_buffer_length);
 		dbg_ctrl("rem is calculated to %d", urb->transfer_buffer_length % maxlen);
 
-		sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+		sb_desc_data = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
+		assert(sb_desc_data != NULL);
 		
-		sb_desc_2->sw_len = urb->transfer_buffer_length ?
+		sb_desc_setup->next = virt_to_phys(sb_desc_data);
+
+		sb_desc_data->sw_len = urb->transfer_buffer_length ?
 			(urb->transfer_buffer_length - 1) / maxlen + 1 : 0;
-		dbg_ctrl("sw_len got %d", sb_desc_2->sw_len);
+		dbg_ctrl("sw_len got %d", sb_desc_data->sw_len);
 		
-		sb_desc_2->command =
-			IO_FIELD(USB_SB_command, rem,
-				 urb->transfer_buffer_length % maxlen) |
-			IO_STATE(USB_SB_command, tt, in) |
-			IO_STATE(USB_SB_command, eot, yes);
-		
-		sb_desc_2->buf = 0;
-		sb_desc_2->next = virt_to_phys(sb_desc_3);
-		dump_sb_desc(sb_desc_2);
-
-		sb_desc_3->sw_len = 1;
-		sb_desc_3->command = IO_FIELD(USB_SB_command, rem, 0) |
-			IO_STATE(USB_SB_command, tt, zout) |
-			IO_STATE(USB_SB_command, full, yes) |
-			IO_STATE(USB_SB_command, eot, yes) |
-			IO_STATE(USB_SB_command, eol, yes);
+		sb_desc_data->command =
+			(IO_FIELD(USB_SB_command, rem,
+                                  urb->transfer_buffer_length % maxlen) |
+                         IO_STATE(USB_SB_command, tt, in) |
+                         IO_STATE(USB_SB_command, eot, yes));
+		
+		sb_desc_data->buf = 0;
+		sb_desc_data->next = virt_to_phys(sb_desc_status);
+
+                /* Read comment at zout_buffer declaration for an explanation to this. */
+		sb_desc_status->sw_len = 1;
+		sb_desc_status->command = (IO_FIELD(USB_SB_command, rem, 0) |
+                                           IO_STATE(USB_SB_command, tt, zout) |
+                                           IO_STATE(USB_SB_command, full, yes) |
+                                           IO_STATE(USB_SB_command, eot, yes) |
+                                           IO_STATE(USB_SB_command, eol, yes));
 				
-		sb_desc_3->buf = 0;
-		sb_desc_3->next = 0;
-		dump_sb_desc(sb_desc_3);
-
-		urb_priv->rx_offset = 0;
-		urb_priv->eot = 0;
+		sb_desc_status->buf = virt_to_phys(&zout_buffer[0]);
+		sb_desc_status->next = 0;
 	}
 	
-	urb_priv->first_sb = sb_desc_1;
-	
-	urb->hcpriv = (void *)urb_priv;
+	urb_priv->first_sb = sb_desc_setup;
+	urb_priv->last_sb = sb_desc_status;
+	urb_priv->epid = epid;
+
+	urb->hcpriv = urb_priv;
 	
 	/* Reset toggle bits and reset error count, remeber to di and ei */
 	/* Warning: it is possible that this locking doesn't work with bottom-halves */
@@ -1332,661 +2181,1059 @@
 	save_flags(flags);
 	cli();
 
-	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop();
+	*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); 
+        nop();
 	if (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)) {
-		panic("Hold was set in %s\n", __FUNCTION__);
+		panic("Hold was set in %s", __FUNCTION__);
 	}
 	
 
+        /* FIXME: Compare with etrax_usb_add_to_bulk_sb_list where the toggle bits
+           are set to a specific value. Why the difference? Read "Transfer and Toggle Bits
+           in Designer's Reference, p. 8 - 11. */
 	*R_USB_EPT_DATA &=
 		~(IO_MASK(R_USB_EPT_DATA, error_count_in) |
 		  IO_MASK(R_USB_EPT_DATA, error_count_out) |
 		  IO_MASK(R_USB_EPT_DATA, t_in) |
 		  IO_MASK(R_USB_EPT_DATA, t_out));
 
-	/* Enable the EP descr. */
+	/* Since we use the rx interrupt to complete ctrl urbs, we can enable interrupts now
+	   (i.e. we don't check the sub pointer on an eot interrupt like we do for bulk traffic). */
+	restore_flags(flags);
 
-	set_bit(epid, (void *)&ep_really_active);
-	
-	TxCtrlEPList[epid].sub = virt_to_phys(sb_desc_1);
+        /* Assert that the EP descriptor is disabled. */
+        assert(!(TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)));
+
+	/* Set up and enable the EP descriptor. */
+	TxCtrlEPList[epid].sub = virt_to_phys(sb_desc_setup);
 	TxCtrlEPList[epid].hw_len = 0;
 	TxCtrlEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
 
-	restore_flags(flags);
-
-	dump_ep_desc(&TxCtrlEPList[epid]);
-
-	if (!(*R_DMA_CH8_SUB1_CMD & IO_MASK(R_DMA_CH8_SUB1_CMD, cmd))) {
-		*R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start);
-		
-	}
+        /* We start the DMA sub channel without checking if it's running or not, because:
+           1) If it's already running, issuing the start command is a nop.
+           2) We avoid a test-and-set race condition. */
+        *R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start);
 	
 	DBFEXIT;
 }
 
-static int etrax_usb_submit_urb(struct urb *urb)
+static void etrax_usb_complete_ctrl_urb(urb_t *urb, int status)
 {
-	etrax_hc_t *hc;
-	int rval = -EINVAL;
-	
-	DBFENTER;
+        etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
+        int epid = urb_priv->epid;
 
-	urb->next = NULL;
+	DBFENTER;
 
-	dump_urb(urb);
-	submit_urb_count++;
-	
-	hc = (etrax_hc_t*) urb->dev->bus->hcpriv;
-	
-	if (usb_pipedevice(urb->pipe) == hc->rh.devnum) {
-		/* This request if for the Virtual Root Hub */
-		rval = etrax_rh_submit_urb(urb);
-		
-	} else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
-		rval = etrax_usb_submit_ctrl_urb(urb);
+        if (status)
+                warn("Completing ctrl urb with status %d.", status);
 
-	} else if (usb_pipetype(urb->pipe) == PIPE_BULK) {
-		rval = etrax_usb_submit_bulk_urb(urb);
+        dbg_ctrl("Completing ctrl epid %d, urb 0x%lx", epid, (unsigned long)urb);
 
-	} else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
-		int bustime;
+	/* Remove this urb from the list. */
+        urb_list_del(urb, epid);
 
-		if (urb->bandwidth == 0) {
-			bustime = usb_check_bandwidth(urb->dev, urb);
-			if (bustime < 0) {
-				rval = bustime;
-			} else {
-				usb_claim_bandwidth(urb->dev, urb, bustime, 0);
-				rval = etrax_usb_submit_intr_urb(urb);
-			}
-			
-		}
-	} else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
-		warn("Isochronous traffic is not supported !!!");
-		rval = -EINVAL;
+        /* For an IN pipe, we always set the actual length, regardless of whether there was
+           an error or not (which means the device driver can use the data if it wants to). */
+	if (usb_pipein(urb->pipe)) {
+                urb->actual_length = urb_priv->rx_offset;
 	}
 
-	DBFEXIT;
+        /* FIXME: Is there something of the things below we shouldn't do if there was an error?
+           Like, maybe we shouldn't insert more traffic. */
 
-	return rval;
-}
+	/* Remember to free the SBs. */
+	etrax_remove_from_sb_list(urb);
+	kfree(urb_priv);
+        urb->hcpriv = 0;
+        
+	/* If there are any more urbs in the list we'd better start sending. */
+	if (!urb_list_empty(epid)) {
+                urb_t *new_urb;
+                
+                /* Get the first urb. */
+                new_urb = urb_list_first(epid);
+		assert(new_urb);
 
-static int etrax_usb_unlink_urb(struct urb *urb)
-{
-	etrax_hc_t *hc = urb->dev->bus->hcpriv;
-	int epid;
-	int devnum, endpoint, slow, maxlen, out_traffic;
-	etrax_urb_priv_t *hc_priv;
-	unsigned long flags;
-	
-	DBFENTER;
-	dump_urb(urb);
-	devnum = usb_pipedevice(urb->pipe);
-	endpoint = usb_pipeendpoint(urb->pipe);
-	slow = usb_pipeslow(urb->pipe);
-	maxlen = usb_maxpacket(urb->dev, urb->pipe,
-			       usb_pipeout(urb->pipe));
-	out_traffic = usb_pipeout(urb->pipe);
-
-	epid = etrax_usb_lookup_epid(devnum, endpoint, slow, maxlen, out_traffic);
+                dbg_ctrl("More ctrl for epid %d, first urb = 0x%lx", epid, (unsigned long)new_urb);
 
-	if (epid == -1)
-		return 0;
-	
-	if (usb_pipedevice(urb->pipe) == hc->rh.devnum) {
-		int ret;
-		ret =  etrax_rh_unlink_urb(urb);
-		DBFEXIT;
-		return ret;
-	} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) {
-		int ret;
-		ret = etrax_usb_unlink_intr_urb(urb);
-		urb->status = -ENOENT;
-		if (urb->complete) {
-			urb->complete(urb);
-		}
-		DBFEXIT;
-		return ret;
+		etrax_usb_add_to_ctrl_sb_list(new_urb, epid);
 	}
-
-	info("Unlink of BULK or CTRL");
-
-	save_flags(flags);
-	cli();
 	
-	for (epid = 0; epid < 32; epid++) {
-		struct urb *u = URB_List[epid];
-		struct urb *prev = NULL;
-		int pos = 0;
-
-		for (; u; u = u->next) {
-			pos++;
-			if (u == urb) {
-				if (!prev) {
-					URB_List[epid] = u->next;
-				} else {
-					prev->next = u->next;
-				}
+	urb->status = status;
 
-				restore_flags(flags);
-
-				if (!prev) {
-					if (usb_pipetype(u->pipe) == PIPE_CONTROL) {
-						if (TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-							/* The EP was enabled, disable it and wait */
-							TxCtrlEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
-							while (*R_DMA_CH8_SUB1_EP == virt_to_phys(&TxCtrlEPList[epid]));
-						}
-					} else if (usb_pipetype(u->pipe) == PIPE_BULK) {
-						if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
-							TxBulkEPList[epid].command &= ~IO_MASK(USB_EP_command, enable);
-							while (*R_DMA_CH8_SUB0_EP == virt_to_phys(&TxBulkEPList[epid]));
-						}
-					}
-				}
-
-				info("Found urb at epid %d, pos %d", epid, pos);
-
-				u->status = -ENOENT;
-				if (u->complete) {
-					u->complete(u);
-				}
-				
-				hc_priv = (etrax_urb_priv_t *)u->hcpriv;
-				cleanup_sb(hc_priv->first_sb);
-				kfree(hc_priv);
+        /* We let any non-zero status from the layer above have precedence. */
+        if (status == 0) {
+                /* USB_DISABLE_SPD means that short reads (shorter than the endpoint's max length)
+                   is to be treated as an error. */
+                if (urb->transfer_flags & USB_DISABLE_SPD) {
+                        if (usb_pipein(urb->pipe) && 
+                            (urb->actual_length != 
+                             usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)))) {
+                                urb->status = -EREMOTEIO;
+                        } 
+                }
+        }
+        
+	if (urb->complete) {
+		urb->complete(urb);
+	}
 
-				DBFEXIT;
-				return 0;
-			}
-			prev = u;
-		}
+	if (urb_list_empty(epid)) {
+		/* No more traffic. Time to clean up. */
+		etrax_usb_free_epid(epid);
+		/* Must set sub pointer to 0. */
+                dbg_ctrl("No ctrl for epid %d", epid);
+		TxCtrlEPList[epid].sub = 0;
 	}
 
-	restore_flags(flags);
-		
 	DBFEXIT;
-	return 0;
 }
 
-static int etrax_usb_get_frame_number(struct usb_device *usb_dev)
+static int etrax_usb_submit_intr_urb(urb_t *urb)
 {
+	
+	int epid;
+	
 	DBFENTER;
-	DBFEXIT;
-	return (*R_USB_FM_NUMBER);
-}
+        
+        if (usb_pipeout(urb->pipe)) {
+                /* Unsupported transfer type.
+                   We don't support interrupt out traffic. (If we do, we can't support
+                   intervals for neither in or out traffic, but are forced to schedule all
+                   interrupt traffic in one frame.) */
+                return -EINVAL;
+        }
 
-static int etrax_usb_allocate_dev(struct usb_device *usb_dev)
-{  
-	DBFENTER;
-	DBFEXIT;
-	return 0;
-}
+	epid = etrax_usb_setup_epid(urb);
+	if (epid == -1) {
+		DBFEXIT;
+		return -ENOMEM;
+	}
 
-static int etrax_usb_deallocate_dev(struct usb_device *usb_dev)
-{
-	DBFENTER;
-	DBFEXIT;
-	return 0;
-}
+	if (!urb_list_empty(epid)) {
+                /* There is already a queued urb for this endpoint. */
+                etrax_usb_free_epid(epid);
+                return -ENXIO;
+        }
+        
+        urb->status = -EINPROGRESS;
 
-static void etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs)
-{
-	DBFENTER;
+        dbg_intr("Add intr urb 0x%lx, to list, epid %d", (unsigned long)urb, epid);
 
-	if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub0_descr)) {
-		info("dma8_sub0_descr (BULK) intr.");
-		*R_DMA_CH8_SUB0_CLR_INTR = IO_STATE(R_DMA_CH8_SUB0_CLR_INTR, clr_descr, do);
-	}
-	if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub1_descr)) {
-		info("dma8_sub1_descr (CTRL) intr.");
-		*R_DMA_CH8_SUB1_CLR_INTR = IO_STATE(R_DMA_CH8_SUB1_CLR_INTR, clr_descr, do);
-	}
-	if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub2_descr)) {
-		info("dma8_sub2_descr (INT) intr.");
-		*R_DMA_CH8_SUB2_CLR_INTR = IO_STATE(R_DMA_CH8_SUB2_CLR_INTR, clr_descr, do);
-	}
-	if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub3_descr)) {
-		info("dma8_sub3_descr (ISO) intr.");
-		*R_DMA_CH8_SUB3_CLR_INTR = IO_STATE(R_DMA_CH8_SUB3_CLR_INTR, clr_descr, do);
-	}
+        urb_list_add(urb, epid);
+	etrax_usb_add_to_intr_sb_list(urb, epid);
+
+	return 0;
 	
 	DBFEXIT;
 }
 
-static void etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs)
+static void etrax_usb_add_to_intr_sb_list(urb_t *urb, int epid)
 {
-	int epid = 0;
-	struct urb *urb;
+
+	volatile USB_EP_Desc_t *tmp_ep;
+	volatile USB_EP_Desc_t *first_ep;
+	
+	char maxlen;
+	int interval;
+	int i;
+        
 	etrax_urb_priv_t *urb_priv;
-		
-	*R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do);
+	
+	DBFENTER;
 
-	while (myNextRxDesc->status & IO_MASK(USB_IN_status, eop)) {
-		if (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata)) {
+	maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
+	interval = urb->interval;
 
-			goto skip_out;
-		}
+	urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG);
+	assert(urb_priv != NULL);
+        memset(urb_priv, 0, sizeof(etrax_urb_priv_t));
+	urb->hcpriv = urb_priv;
 
-		if (myNextRxDesc->status & IO_MASK(USB_IN_status, error)) {
-			
-			goto skip_out;
-		}
-		
-		epid = IO_EXTRACT(USB_IN_status, epid, myNextRxDesc->status);
+	first_ep = &TxIntrEPList[0];
 
-		urb = URB_List[epid];
+	/* Round of the interval to 2^n, it is obvious that this code favours
+	   smaller numbers, but that is actually a good thing */
+        /* FIXME: The "rounding error" for larger intervals will be quite
+           large. For in traffic this shouldn't be a problem since it will only
+           mean that we "poll" more often. */
+	for (i = 0; interval; i++) {
+		interval = interval >> 1;
+	}
+	interval = 1 << (i - 1);
 
-		if (urb && usb_pipein(urb->pipe)) {
-			urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
+	dbg_intr("Interval rounded to %d", interval);
 
-			if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
-				struct in_chunk *in;
-				dbg_intr("Packet for epid %d in rx buffers", epid);
-				in = kmalloc(sizeof(struct in_chunk), GFP_ATOMIC);
-				in->length = myNextRxDesc->hw_len;
-				in->data = kmalloc(in->length, GFP_ATOMIC);
-				memcpy(in->data, phys_to_virt(myNextRxDesc->buf), in->length);
-				list_add_tail(&in->list, &urb_priv->ep_in_list);
-#ifndef ETRAX_USB_INTR_IRQ
-				etrax_usb_hc_intr_top_half(irq, vhc, regs);
-#endif
-				
-			} else {
-				if ((urb_priv->rx_offset + myNextRxDesc->hw_len) >
-				    urb->transfer_buffer_length) {
-					err("Packet (epid: %d) in RX buffer (%d) was bigger "
-					    "than the URB has room for (%d)!!!", epid, urb_priv->rx_offset + myNextRxDesc->hw_len, urb->transfer_buffer_length);
-					goto skip_out;
-				}
+	tmp_ep = first_ep;
+	i = 0;
+	do {
+		if (tmp_ep->command & IO_MASK(USB_EP_command, eof)) {
+			if ((i % interval) == 0) {
+				/* Insert the traffic ep after tmp_ep */
+				USB_EP_Desc_t *ep_desc;
+				USB_SB_Desc_t *sb_desc;
+
+				dbg_intr("Inserting EP for epid %d", epid);
+                                
+				ep_desc = (USB_EP_Desc_t *)
+					kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
+				sb_desc = (USB_SB_Desc_t *)
+					kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
+				assert(ep_desc != NULL);
+                                CHECK_ALIGN(ep_desc);
+				assert(sb_desc != NULL);
 				
-				memcpy(urb->transfer_buffer + urb_priv->rx_offset,
-				       phys_to_virt(myNextRxDesc->buf), myNextRxDesc->hw_len);
+				ep_desc->sub = virt_to_phys(sb_desc);
+				ep_desc->hw_len = 0;
+				ep_desc->command = (IO_FIELD(USB_EP_command, epid, epid) |
+                                                    IO_STATE(USB_EP_command, enable, yes));
+
+
+                                /* Round upwards the number of packets of size maxlen
+                                   that this SB descriptor should receive. */
+                                sb_desc->sw_len = urb->transfer_buffer_length ?
+                                        (urb->transfer_buffer_length - 1) / maxlen + 1 : 0;
+                                sb_desc->next = 0;
+                                sb_desc->buf = 0;
+                                sb_desc->command = 
+                                        (IO_FIELD(USB_SB_command, rem, urb->transfer_buffer_length % maxlen) |
+                                         IO_STATE(USB_SB_command, tt, in) |
+                                         IO_STATE(USB_SB_command, eot, yes) |
+                                         IO_STATE(USB_SB_command, eol, yes));
 				
-				urb_priv->rx_offset += myNextRxDesc->hw_len;
-			}
-			
-			if (myNextRxDesc->status & IO_MASK(USB_IN_status, eot)) {
-				urb_priv->eot = 1;
+				ep_desc->next = tmp_ep->next;
+				tmp_ep->next = virt_to_phys(ep_desc);
 			}
-			
-		} else {
-			err("This is almost fatal, inpacket for epid %d which does not exist "
-			    " or is out!!!\nURB was at 0x%08lX", epid, (unsigned long)urb);
-			
-			goto skip_out;
+			i++;
 		}
+		tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->next);
+	} while (tmp_ep != first_ep);
 
-	skip_out:
-		myPrevRxDesc = myNextRxDesc;
-		myPrevRxDesc->command |= IO_MASK(USB_IN_command, eol);
-		myLastRxDesc->command &= ~IO_MASK(USB_IN_command, eol);
-		myLastRxDesc = myPrevRxDesc;
 
-		myNextRxDesc->status = 0;
-		myNextRxDesc = phys_to_virt(myNextRxDesc->next);
-	}
+        /* Note that first_sb/last_sb doesn't apply to interrupt traffic. */
+        urb_priv->epid = epid;
+
+        /* We start the DMA sub channel without checking if it's running or not, because:
+           1) If it's already running, issuing the start command is a nop.
+           2) We avoid a test-and-set race condition. */
+        *R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start);
+        
+	DBFEXIT;
 }
 
 
 
-static void cleanup_sb(USB_SB_Desc_t *sb)
+static void etrax_usb_complete_intr_urb(urb_t *urb, int status)
 {
-	USB_SB_Desc_t *next_sb;
-	
+        etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
+        int epid = urb_priv->epid;
+        
 	DBFENTER;
 
-	if (sb == NULL) {
-		err("cleanup_sb was given a NULL pointer");
-		return;
-	}
+        if (status)
+                warn("Completing intr urb with status %d.", status);
 
-	while (!(sb->command & IO_MASK(USB_SB_command, eol))) {
-		next_sb = (USB_SB_Desc_t *)phys_to_virt(sb->next);
-		kmem_cache_free(usb_desc_cache, sb);
-		sb = next_sb;
-	}
+        dbg_intr("Completing intr epid %d, urb 0x%lx", epid, (unsigned long)urb);
 
-	kmem_cache_free(usb_desc_cache, sb);
+        urb->status = status;
+        urb->actual_length = urb_priv->rx_offset;
 
-	DBFEXIT;
+        dbg_intr("interrupt urb->actual_length = %d", urb->actual_length);
 
+        /* We let any non-zero status from the layer above have precedence. */
+        if (status == 0) {
+                /* USB_DISABLE_SPD means that short reads (shorter than the endpoint's max length)
+                   is to be treated as an error. */
+                if (urb->transfer_flags & USB_DISABLE_SPD) {
+                        if (urb->actual_length != 
+                            usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))) {
+                                urb->status = -EREMOTEIO;
+                        }
+                }
+        }
+        
+        if (urb->complete) {
+                urb->complete(urb);
+        }
+			
+        /* Device driver has taken care of the data now. */
+        urb_priv->rx_offset = 0;
+        
+	DBFEXIT;
 }
 
-static void handle_control_transfer_attn(int epid, int status)
+
+static int etrax_usb_submit_isoc_urb(urb_t *urb) 
 {
-	struct urb *old_urb;
-	etrax_urb_priv_t *hc_priv;	
+	int epid;
 
 	DBFENTER;
 
-	clear_bit(epid, (void *)&ep_really_active);
-	
-	old_urb = URB_List[epid];
-	URB_List[epid] = old_urb->next;
-	
-	/* if (status == 0 && IN) find data and copy to urb */
-	if (status == 0 && usb_pipein(old_urb->pipe)) {
-		unsigned long flags;
-		etrax_urb_priv_t *urb_priv;
-
-		urb_priv = (etrax_urb_priv_t *)old_urb->hcpriv;
-		save_flags(flags);
-		cli();
-		if (urb_priv->eot == 1) {
-			old_urb->actual_length = urb_priv->rx_offset;
-			dbg_ctrl("urb_priv->rx_offset: %d in handle_control_attn", urb_priv->rx_offset);
-		} else {
-			status = -EPROTO;
-			old_urb->actual_length = 0;
-			err("(CTRL) No eot set in IN data!!! rx_offset: %d", urb_priv->rx_offset);
-		}
-
-		restore_flags(flags);
-	}
-	
-	/* If there are any more URB's in the list we'd better start sending */
-	if (URB_List[epid]) {
-		etrax_usb_do_ctrl_hw_add(URB_List[epid], epid,
-					 usb_maxpacket(URB_List[epid]->dev, URB_List[epid]->pipe,
-						       usb_pipeout(URB_List[epid]->pipe)));
-	}
-#if 1
-	else {
-		/* This means that this EP is now free, deconfigure it */
-		etrax_usb_free_epid(epid);
+	/* Is there an active epid for this urb ? */	
+	epid = etrax_usb_setup_epid(urb);
+	if (epid == -1) {
+		DBFEXIT;
+		return -ENOMEM;
 	}
-#endif
 	
-	/* Remember to free the SB's */
-	hc_priv = (etrax_urb_priv_t *)old_urb->hcpriv;
-	cleanup_sb(hc_priv->first_sb);
-	kfree(hc_priv);
+        dbg_isoc("Submitting isoc urb = 0x%lx", (unsigned long)urb);
 
-	old_urb->status = status;
-	if (old_urb->complete) {
-		old_urb->complete(old_urb);
-	}
+	/* Ok, now we got valid endpoint, lets insert some traffic */
 
-	DBFEXIT;
-}
+	urb->status = -EINPROGRESS;
 
+	/* Find the last urb in the URB_List and add this urb after that one. 
+	   Also add the traffic, that is do an isoc_hw_add. This is important
+	   to make this in "real time" since isochronous traffic is time sensitive. */
+
+        dbg_isoc("Adding isoc urb to (possibly empty) list");	
+	urb_list_add(urb, epid);
+	etrax_usb_add_to_isoc_sb_list(urb, epid);
+		
+	DBFEXIT;
 
+	return 0;
+}
 
-static void etrax_usb_hc_intr_bottom_half(void *data)
+static void etrax_usb_add_to_isoc_sb_list(urb_t *urb, int epid) 
 {
-	struct usb_reg_context *reg = (struct usb_reg_context *)data;
+
+	int i = 0;	
 	
-	int error_code;
-	int epid;
+	etrax_urb_priv_t *urb_priv; 
+	USB_SB_Desc_t *prev_sb_desc,  *next_sb_desc, *temp_sb_desc; 
 
-	__u32 r_usb_ept_data;
+	DBFENTER;
 
-	etrax_hc_t *hc = reg->hc; 
-	__u16 r_usb_rh_port_status_1;
-	__u16 r_usb_rh_port_status_2;
+	prev_sb_desc = next_sb_desc = temp_sb_desc = NULL; 
 	
-	DBFENTER;
+	urb_priv = kmalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG);
+	assert(urb_priv != NULL);
+        memset(urb_priv, 0, sizeof(etrax_urb_priv_t));
 
-	if (reg->r_usb_irq_mask_read & IO_MASK(R_USB_IRQ_MASK_READ, port_status)) {
+	urb->hcpriv = urb_priv;
+	urb_priv->epid = epid;
+	
+	if (usb_pipeout(urb->pipe)) {
 
-		/*
-		  The Etrax RH does not include a wPortChange register, so this has
-		  to be handled in software. See section 11.16.2.6.2 in USB 1.1 spec
-		  for details.
-		*/
+                /* Not implemented yet! */
+		dbg_isoc("Transfer for epid %d is OUT", epid);
 		
-		r_usb_rh_port_status_1 = reg->r_usb_rh_port_status_1;
-		r_usb_rh_port_status_2 = reg->r_usb_rh_port_status_2;
+		/* Create one SB descriptor for each packet and link them together. */
+		for (i = 0; i < urb->number_of_packets; i++) {	
 		
-		dbg_rh("port_status pending");
-		dbg_rh("r_usb_rh_port_status_1: 0x%04X", r_usb_rh_port_status_1);
-		dbg_rh("r_usb_rh_port_status_2: 0x%04X", r_usb_rh_port_status_2);
+			next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
+			assert(next_sb_desc != NULL);
+			
+			next_sb_desc->command = (IO_STATE(USB_SB_command, tt, out) |
+                                                 IO_STATE(USB_SB_command, eot, yes));
+			
+			next_sb_desc->sw_len = urb->iso_frame_desc[i].length;
+			next_sb_desc->buf = virt_to_phys(urb->transfer_buffer + urb->iso_frame_desc[i].offset);
+			
+			/* First SB descriptor that belongs to this urb */	
+			if (i == 0) 
+				urb_priv->first_sb = next_sb_desc;
+			else
+				prev_sb_desc->next = virt_to_phys(next_sb_desc);			
+						
+			prev_sb_desc = next_sb_desc;	
+		}
+		/* Check if full length transfer. */
+		if (urb->iso_frame_desc[urb->number_of_packets - 1].length ==
+		    usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))) {
+			next_sb_desc->command |= IO_STATE(USB_SB_command, full, yes);
+		}
 
-		/* C_PORT_CONNECTION is set on any transition */
-		hc->rh.wPortChange_1 |=
-			((r_usb_rh_port_status_1 & (1 << RH_PORT_CONNECTION)) !=
-			 (hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_CONNECTION))) ?
-			(1 << RH_PORT_CONNECTION) : 0;
-		
-		hc->rh.wPortChange_2 |=
-			((r_usb_rh_port_status_2 & (1 << RH_PORT_CONNECTION)) !=
-			 (hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_CONNECTION))) ?
-			(1 << RH_PORT_CONNECTION) : 0;
+		next_sb_desc->command |= IO_STATE(USB_SB_command, eol, yes);
+		next_sb_desc->next = 0;
+		urb_priv->last_sb = next_sb_desc;
+	
+	} else if (usb_pipein(urb->pipe)) {
 
-		/* C_PORT_ENABLE is _only_ set on a one to zero transition */
-		hc->rh.wPortChange_1 |=
-			((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_ENABLE))
-			 && !(r_usb_rh_port_status_1 & (1 << RH_PORT_ENABLE))) ?
-			(1 << RH_PORT_ENABLE) : 0;
-		
-		hc->rh.wPortChange_2 |=
-			((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_ENABLE))
-			 && !(r_usb_rh_port_status_2 & (1 << RH_PORT_ENABLE))) ?
-			(1 << RH_PORT_ENABLE) : 0;
-		
-		/* C_PORT_SUSPEND seems difficult, lets ignore it.. (for now) */
-		
-		/* C_PORT_RESET is _only_ set on a transition from the resetting state
-		   to the enabled state */
-		hc->rh.wPortChange_1 |=
-			((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_RESET))
-			 && (r_usb_rh_port_status_1 & (1 << RH_PORT_ENABLE))) ?
-			(1 << RH_PORT_RESET) : 0;
-		
-		hc->rh.wPortChange_2 |=
-			((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_RESET))
-			 && (r_usb_rh_port_status_2 & (1 << RH_PORT_ENABLE))) ?
-			(1 << RH_PORT_RESET) : 0;
-		
-		hc->rh.prev_wPortStatus_1 = r_usb_rh_port_status_1;
-		hc->rh.prev_wPortStatus_2 = r_usb_rh_port_status_2;	
+		dbg_isoc("Transfer for epid %d is IN", epid);
+		dbg_isoc("transfer_buffer_length = %d", urb->transfer_buffer_length);
+		dbg_isoc("rem is calculated to %d", urb->iso_frame_desc[urb->number_of_packets - 1].length);
+		
+                /* Note that in descriptors for periodic traffic are not consumed. This means that
+                   the USB controller never propagates in the SB list. In other words, if there already
+                   is an SB descriptor in the list for this EP we don't have to do anything. */
+                if (TxIsocEPList[epid].sub == 0) {
+                        dbg_isoc("Isoc traffic not already running, allocating SB");
+                        
+                        next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
+                        assert(next_sb_desc != NULL);
+			
+                        next_sb_desc->command = (IO_STATE(USB_SB_command, tt, in) |
+                                                 IO_STATE(USB_SB_command, eot, yes) | 
+                                                 IO_STATE(USB_SB_command, eol, yes));
+			
+                        next_sb_desc->sw_len = urb->number_of_packets;
+                        next_sb_desc->buf = 0;
+
+                        /* The rem field is don't care for isoc traffic, so we don't set it. */
+
+                        /* Only one SB descriptor that belongs to this urb. */
+                        urb_priv->first_sb = next_sb_desc; 	
+                        urb_priv->last_sb = next_sb_desc; 	
+                
+                } else {
+                
+                        dbg_isoc("Isoc traffic already running, just setting first/last_sb");
+                        
+                        /* Each EP for isoc in will have only one SB descriptor, setup when submitting the
+                           already active urb. Note that even though we may have several first_sb/last_sb
+                           pointing at the same SB descriptor, they are freed only once (when the list has
+                           become empty). */
+                        urb_priv->first_sb = phys_to_virt(TxIsocEPList[epid].sub);
+                        urb_priv->last_sb = phys_to_virt(TxIsocEPList[epid].sub);
+                        return;
+                }
+                
+	}
+	
+	/* Find the spot to insert this urb and add it. */
+	if (TxIsocEPList[epid].sub == 0) {
+		/* First SB descriptor inserted in this list (in or out). */
+		dbg_isoc("Inserting SB desc first in list");
+		TxIsocEPList[epid].sub = virt_to_phys(urb_priv->first_sb);
+	} else {	
+		/* Isochronous traffic is already running, insert new traffic last (only out). */
+		dbg_isoc("Inserting SB desc last in list");
+		temp_sb_desc = phys_to_virt(TxIsocEPList[epid].sub);
+		while (!(temp_sb_desc->command & IO_MASK(USB_SB_command, eol))) {
+			temp_sb_desc = phys_to_virt(temp_sb_desc->next);
+		}
+		/* Next pointer must be set before eol is removed. */
+		temp_sb_desc->next = virt_to_phys(urb_priv->first_sb);	
+		/* Clear the previous end of list flag since there is a new in the
+		   added SB descriptor list. */
+		temp_sb_desc->command &= ~IO_MASK(USB_SB_command, eol);
+	}
+	
+        if (urb->transfer_flags & USB_ISO_ASAP) {
+                /* The isoc transfer should be started as soon as possible. The start_frame
+                   field is a return value if URB_ISO_ASAP was set. Comparing R_USB_FM_NUMBER
+                   with a USB Chief trace shows that the first isoc IN token is sent 2 frames
+                   later. I'm not sure how this affects usage of the start_frame field by the
+                   device driver, or how it affects things when USB_ISO_ASAP is not set, so
+                   therefore there's no compensation for the 2 frame "lag" here. */
+                urb->start_frame = (*R_USB_FM_NUMBER & 0x7ff);
+                TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
+                urb_priv->urb_state = STARTED;
+                dbg_isoc("URB_ISO_ASAP set, urb->start_frame set to %d", urb->start_frame);
+        } else {
+                /* Not started yet. */
+                urb_priv->urb_state = NOT_STARTED;
+        }
+        
+       /* We start the DMA sub channel without checking if it's running or not, because:
+          1) If it's already running, issuing the start command is a nop.
+          2) We avoid a test-and-set race condition. */
+        *R_DMA_CH8_SUB3_CMD = IO_STATE(R_DMA_CH8_SUB3_CMD, cmd, start);
+        
+	DBFEXIT;
+}
+
+static void etrax_usb_complete_isoc_urb(urb_t *urb, int status)
+{
+	etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv; 
+        int epid = urb_priv->epid;
+	
+	DBFENTER;
+
+        if (status)
+                warn("Completing isoc urb with status %d.", status);
+        
+        if (usb_pipein(urb->pipe)) {
+		
+                /* Move this one down the list. */
+                urb_list_move_last(urb, epid);
+                
+                /* Mark the now first urb as started (may already be). */
+                ((etrax_urb_priv_t *)(urb_list_first(epid)->hcpriv))->urb_state = STARTED;
 	}
 
-	for (epid = 0; epid < 32; epid++) {
+	urb->status = status;
+	if (urb->complete) {
+		urb->complete(urb);
+	}
 
-		unsigned long flags;
+	DBFEXIT;
+}
 
-		save_flags(flags);
-		cli();
+static void etrax_usb_complete_urb(urb_t *urb, int status)
+{
+        switch (usb_pipetype(urb->pipe)) {
+        case PIPE_BULK:
+                etrax_usb_complete_bulk_urb(urb, status);
+                break;                
+        case PIPE_CONTROL:
+                etrax_usb_complete_ctrl_urb(urb, status);
+                break;
+        case PIPE_INTERRUPT:
+                etrax_usb_complete_intr_urb(urb, status);
+                break;
+        case PIPE_ISOCHRONOUS:
+                etrax_usb_complete_isoc_urb(urb, status);
+                break;
+        default:
+                err("Unknown pipetype");
+        }
+}
 
-		*R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); nop();
-		r_usb_ept_data = *R_USB_EPT_DATA;
 
-		restore_flags(flags);
 
-		if (r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, hold)) {
-			warn("Was hold for epid %d", epid);
-			continue;
-		}
+static void etrax_usb_hc_interrupt_top_half(int irq, void *vhc, struct pt_regs *regs)
+{
+	usb_interrupt_registers_t *reg;
+        unsigned long flags;
+	__u32 irq_mask;
+	__u8 status;
+        __u32 epid_attn;
+        __u16 port_status_1;
+	__u16 port_status_2;
+        __u32 fm_number;
 
-		if (!(r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, valid))) {
-			continue;
-		}
-		
-		
-		if (test_bit(epid, (void *)&reg->r_usb_epid_attn)) {
+	DBFENTER;
 
-			if (URB_List[epid] == NULL) {
-				err("R_USB_EPT_DATA is 0x%08X", r_usb_ept_data);
-				err("submit urb has been called %lu times..", submit_urb_count);
-				err("EPID_ATTN for epid %d, with NULL entry in list", epid);
-				return;
-			}
-			
-			dbg_ep("r_usb_ept_data [%d] == 0x%08X", epid,
-			       r_usb_ept_data);
-			
-			error_code = IO_EXTRACT(R_USB_EPT_DATA, error_code,
-						r_usb_ept_data);
-			
-			if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
-				/* no_error means that this urb was sucessfully sent or that we have
-				   some undefinde error*/
-				
-				if (IO_EXTRACT(R_USB_EPT_DATA, error_count_out, r_usb_ept_data) == 3 ||
-				    IO_EXTRACT(R_USB_EPT_DATA, error_count_in, r_usb_ept_data) == 3) {
-				/* Actually there were transmission errors */
-					warn("Undefined error for epid %d", epid);
-					if (usb_pipetype(URB_List[epid]->pipe) == PIPE_CONTROL) {
-						handle_control_transfer_attn(epid, -EPROTO);
-					} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_BULK) {
-						handle_bulk_transfer_attn(epid, -EPROTO);
-					} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) {
-						handle_intr_transfer_attn(epid, -EPROTO);
-					}
-							   
-				} else {
-
-					if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) {
-						if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) {
-							etrax_usb_do_intr_recover(epid);
-						} else {
-							panic("Epid attention for epid %d (none INTR), with no errors and no "
-							      "exessive retry r_usb_status is 0x%02X\n",
-							      epid, reg->r_usb_status);
-						}
-						
-					} else if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) {
-						panic("Epid attention for epid %d, with no errors and no "
-						      "exessive retry r_usb_status is 0x%02X\n",
-						      epid, reg->r_usb_status);
-						
-					}
-					
-					warn("Epid attention for epid %d, with no errors and no "
-					     "exessive retry r_usb_status is 0x%02X",
-					     epid, reg->r_usb_status);
-					warn("OUT error count: %d", IO_EXTRACT(R_USB_EPT_DATA, error_count_out,
-									       r_usb_ept_data));
-					warn("IN  error count: %d", IO_EXTRACT(R_USB_EPT_DATA, error_count_in,
-									       r_usb_ept_data));
-					
+        /* Read critical registers into local variables, do kmalloc afterwards. */
+        save_flags(flags);
+        cli();
+        
+	irq_mask = *R_USB_IRQ_MASK_READ;
+        /* Reading R_USB_STATUS clears the ctl_status interrupt. Note that R_USB_STATUS
+           must be read before R_USB_EPID_ATTN since reading the latter clears the 
+           ourun and perror fields of R_USB_STATUS. */
+	status = *R_USB_STATUS;
+
+        /* Reading R_USB_EPID_ATTN clears the iso_eof, bulk_eot and epid_attn interrupts. */
+	epid_attn = *R_USB_EPID_ATTN;
+
+        /* Reading R_USB_RH_PORT_STATUS_1 and R_USB_RH_PORT_STATUS_2 clears the
+           port_status interrupt. */
+	port_status_1 = *R_USB_RH_PORT_STATUS_1;
+	port_status_2 = *R_USB_RH_PORT_STATUS_2;
+
+        /* Reading R_USB_FM_NUMBER clears the sof interrupt. */
+        /* Note: the lower 11 bits contain the actual frame number, sent with each sof. */
+        fm_number = *R_USB_FM_NUMBER;
 
-				}
-				
-			} else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, stall)) {
-				warn("Stall for epid %d", epid);
-				if (usb_pipetype(URB_List[epid]->pipe) == PIPE_CONTROL) {
-					handle_control_transfer_attn(epid, -EPIPE);
-				} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_BULK) {
-					handle_bulk_transfer_attn(epid, -EPIPE);
-				} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) {
-					handle_intr_transfer_attn(epid, -EPIPE);
-				}
-				
-				
-			} else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, bus_error)) {
-				panic("USB bus error for epid %d\n", epid);
-				
-			} else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, buffer_error)) {
-				warn("Buffer error for epid %d", epid);
+        restore_flags(flags);
 
-				if (usb_pipetype(URB_List[epid]->pipe) == PIPE_CONTROL) {
-					handle_control_transfer_attn(epid, -EPROTO);
-				} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_BULK) {
-					handle_bulk_transfer_attn(epid, -EPROTO);
-				} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) {
-					handle_intr_transfer_attn(epid, -EPROTO);
-				}
+	reg = (usb_interrupt_registers_t *)kmem_cache_alloc(top_half_reg_cache, SLAB_ATOMIC);
 
-			}
-		} else if (test_bit(epid, (void *)&ep_really_active)) {
-			/* Should really be else if (testbit(really active)) */
+	assert(reg != NULL);
 
-			if (usb_pipetype(URB_List[epid]->pipe) == PIPE_CONTROL) {
+	reg->hc = (etrax_hc_t *)vhc;
 
-				if (!(TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable))) {
-					/* Now we have to verify that this CTRL endpoint got disabled
-					   cause it reached end of list with no error */
-					
-					if (IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data) ==
-					    IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
-						/*
-						  This means that the endpoint has no error, is disabled
-						  and had inserted traffic,
-						  i.e. transfer sucessfully completed
-						*/
-						dbg_ctrl("Last SB for CTRL %d sent sucessfully", epid);
-						handle_control_transfer_attn(epid, 0);
-					}
-				}
-				
-			} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_BULK) {
-				if (!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable))) {
-					/* Now we have to verify that this BULK endpoint go disabled
-					   cause it reached end of list with no error */
-
-					if (IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data) ==
-					    IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
-						/*
-						  This means that the endpoint has no error, is disabled
-						  and had inserted traffic,
-						  i.e. transfer sucessfully completed
-						*/
-						dbg_bulk("Last SB for BULK %d sent sucessfully", epid);
-						handle_bulk_transfer_attn(epid, 0);
-					}
-				}
-			} else if (usb_pipetype(URB_List[epid]->pipe) == PIPE_INTERRUPT) {
-				handle_intr_transfer_attn(epid, 0);
-			}
-		}
-		
-	}	
+        /* Now put register values into kmalloc'd area. */
+        reg->r_usb_irq_mask_read = irq_mask;
+        reg->r_usb_status = status;
+        reg->r_usb_epid_attn = epid_attn;
+	reg->r_usb_rh_port_status_1 = port_status_1;
+	reg->r_usb_rh_port_status_2 = port_status_2;
+        reg->r_usb_fm_number = fm_number;
+        
+	reg->usb_bh.sync = 0;
+	reg->usb_bh.routine = etrax_usb_hc_interrupt_bottom_half;
+	reg->usb_bh.data = reg;
+
+	queue_task(&reg->usb_bh, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+
+	DBFEXIT;
+}
+
+static void etrax_usb_hc_interrupt_bottom_half(void *data)
+{
+	usb_interrupt_registers_t *reg = (usb_interrupt_registers_t *)data;
+        __u32 irq_mask = reg->r_usb_irq_mask_read;
+	
+	DBFENTER;
 
-	kfree(reg);
+        /* Interrupts are handled in order of priority. */
+        if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, epid_attn)) {
+                etrax_usb_hc_epid_attn_interrupt(reg);
+        }
+	if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, port_status)) {
+                etrax_usb_hc_port_status_interrupt(reg);
+        }
+        if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, ctl_status)) {
+                etrax_usb_hc_ctl_status_interrupt(reg);
+        }
+	if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, iso_eof)) {
+                etrax_usb_hc_isoc_eof_interrupt();
+        } 
+	if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, bulk_eot)) {
+                /* Update/restart the bulk start timer since obviously the channel is running. */
+                mod_timer(&bulk_start_timer, jiffies + BULK_START_TIMER_INTERVAL);
+                /* Update/restart the bulk eot timer since we just received an bulk eot interrupt. */
+                mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL);
+                
+                etrax_usb_hc_bulk_eot_interrupt(0);
+        }
+        
+	kmem_cache_free(top_half_reg_cache, reg);
 
 	DBFEXIT;
 }
 
 
-static void etrax_usb_hc_intr_top_half(int irq, void *vhc, struct pt_regs *regs)
+void etrax_usb_hc_isoc_eof_interrupt(void)
 {
-	struct usb_reg_context *reg;
+	urb_t *urb;
+	etrax_urb_priv_t *urb_priv;
+	int epid;
 
 	DBFENTER;
 
-	reg = (struct usb_reg_context *)kmalloc(sizeof(struct usb_reg_context), GFP_ATOMIC);
+	/* Do not check the invalid epid (it has a valid sub pointer). */
+	for (epid = 0; epid < NBR_OF_EPIDS - 1; epid++) {
+	
+		if (TxIsocEPList[epid].sub == 0) {
+			/* Nothing here to see. */
+			continue;
+		}
 
-	if (!(reg)) {
-		panic("kmalloc failed in top_half\n");
-	}
+                /* Get the first urb (if any). */
+		urb = urb_list_first(epid);
+                if (urb == 0) {
+                        warn("Ignoring NULL urb");
+                        continue;
+                }
+
+                /* Sanity check. */
+                assert(usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS);
+
+                urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
+		assert(urb_priv);
+
+                if (urb_priv->urb_state == NOT_STARTED) {
+                        
+                        /* If ASAP is not set and urb->start_frame is the current frame,
+                           start the transfer. */
+                        if (!(urb->transfer_flags & USB_ISO_ASAP) && 
+                            (urb->start_frame == (*R_USB_FM_NUMBER & 0x7ff))) {
+
+                                dbg_isoc("Enabling isoc IN EP descr for epid %d", epid);
+                                TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes);
+
+                                /* This urb is now active. */
+                                urb_priv->urb_state = STARTED;
+                                continue;
+                        }
+                }
+        }
+	
+	DBFEXIT;
 
-	reg->hc = (etrax_hc_t *)vhc;
-	reg->r_usb_irq_mask_read    = *R_USB_IRQ_MASK_READ;
-	reg->r_usb_status           = *R_USB_STATUS;
+}
 
-#if 0
-	if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) {
-		panic("r_usb_status said perror\n");
-	}
-	if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) {
-		panic("r_usb_status said ourun !!!\n");
-	}
-#endif
-	
-	reg->r_usb_epid_attn        = *R_USB_EPID_ATTN;
+void etrax_usb_hc_bulk_eot_interrupt(int timer_induced)
+{
+ 	int epid;
+ 
+        /* The technique is to run one urb at a time, wait for the eot interrupt at which
+           point the EP descriptor has been disabled. */
+        
+        DBFENTER;
+        dbg_bulk("bulk eot%s", timer_induced ? ", called by timer" : "");
+
+        for (epid = 0; epid < NBR_OF_EPIDS; epid++) {
+
+                if (!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) &&
+                    (TxBulkEPList[epid].sub != 0)) {
+
+                        urb_t *urb;
+                        etrax_urb_priv_t *urb_priv;
+                        unsigned long flags;
+                        __u32 r_usb_ept_data;
+
+                        /* Found a disabled EP descriptor which has a non-null sub pointer.
+                           Verify that this ctrl EP descriptor got disabled no errors.
+                           FIXME: Necessary to check error_code? */
+                        dbg_bulk("for epid %d?", epid);
+
+                        /* Get the first urb. */
+                        urb = urb_list_first(epid);
+
+                        /* FIXME: Could this happen for valid reasons? Why did it disappear? Because of
+                           wrong unlinking? */
+                        if (!urb) {
+                                warn("NULL urb for epid %d", epid);
+                                continue;
+                        }
+                        
+                        assert(urb);
+                        urb_priv = (etrax_urb_priv_t *)urb->hcpriv;
+                        assert(urb_priv);
+
+                        /* Sanity checks. */
+                        assert(usb_pipetype(urb->pipe) == PIPE_BULK);
+                        if (phys_to_virt(TxBulkEPList[epid].sub) != urb_priv->last_sb) {
+                                err("bulk endpoint got disabled before reaching last sb");
+                        }
+
+                        /* For bulk IN traffic, there seems to be a race condition between
+                           between the bulk eot and eop interrupts, or rather an uncertainty regarding
+                           the order in which they happen. Normally we expect the eop interrupt from
+                           DMA channel 9 to happen before the eot interrupt.
+
+                           Therefore, we complete the bulk IN urb in the rx interrupt handler instead. */
+                        
+                        if (usb_pipein(urb->pipe)) {
+                                dbg_bulk("in urb, continuing");
+                                continue;
+                        }
+                        
+                        save_flags(flags);
+                        cli();
+                        *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); 
+                        nop();
+                        r_usb_ept_data = *R_USB_EPT_DATA;
+                        restore_flags(flags);
+                        
+                        if (IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data) ==
+                            IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
+                                /* This means that the endpoint has no error, is disabled
+                                   and had inserted traffic, i.e. transfer successfully completed. */
+                                etrax_usb_complete_bulk_urb(urb, 0);
+                        } else {
+                                /* Shouldn't happen. We expect errors to be caught by epid attention. */
+                                err("Found disabled bulk EP desc, error_code != no_error");
+                        }
+                }
+        }
+        
+        /* Normally, we should find (at least) one disabled EP descriptor with a valid sub pointer.
+           However, because of the uncertainty in the deliverance of the eop/eot interrupts, we may
+           not.  Also, we might find two disabled EPs when handling an eot interrupt, and then find
+           none the next time. */
+
+        DBFEXIT;
+
+}
+
+void etrax_usb_hc_epid_attn_interrupt(usb_interrupt_registers_t *reg)
+{
+        /* This function handles the epid attention interrupt.  There are a variety of reasons
+           for this interrupt to happen (Designer's Reference, p. 8 - 22 for the details):
+
+           invalid ep_id  - Invalid epid in an EP (EP disabled).
+           stall          - Not strictly an error condition (EP disabled).
+           3rd error      - Three successive transaction errors  (EP disabled).
+           buffer ourun   - Buffer overrun or underrun (EP disabled).
+           past eof1      - Intr or isoc transaction proceeds past EOF1.
+           near eof       - Intr or isoc transaction would not fit inside the frame.
+           zout transfer  - If zout transfer for a bulk endpoint (EP disabled).
+           setup transfer - If setup transfer for a non-ctrl endpoint (EP disabled). */
+
+        int epid;
+
+
+        DBFENTER;
+        
+        /* Note that we loop through all epids. We still want to catch errors for 
+           the invalid one, even though we might handle them differently. */
+        for (epid = 0; epid < NBR_OF_EPIDS; epid++) {
 
-	reg->r_usb_rh_port_status_1 = *R_USB_RH_PORT_STATUS_1;
-	reg->r_usb_rh_port_status_2 = *R_USB_RH_PORT_STATUS_2;
+		if (test_bit(epid, (void *)&reg->r_usb_epid_attn)) {
+                        
+                        urb_t *urb;
+                        __u32 r_usb_ept_data;
+                        unsigned long flags;
+                        int error_code;
+
+                        save_flags(flags);
+                        cli();                
+                        *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); 
+                        nop();
+                        /* Note that although there are separate R_USB_EPT_DATA and R_USB_EPT_DATA_ISO
+                           registers, they are located at the same address and are of the same size.
+                           In other words, this read should be ok for isoc also. */
+                        r_usb_ept_data = *R_USB_EPT_DATA;
+                        restore_flags(flags);
+
+                        /* First some sanity checks. */
+                        if (epid == INVALID_EPID) {
+                                /* FIXME: What if it became disabled? Could seriously hurt interrupt
+				   traffic. (Use do_intr_recover.) */
+                                warn("Got epid_attn for INVALID_EPID (%d).", epid);
+				err("R_USB_EPT_DATA = 0x%x", r_usb_ept_data);
+				err("R_USB_STATUS = 0x%x", reg->r_usb_status);
+				continue;
+                        } else 	if (epid == DUMMY_EPID) {
+                                /* We definitely don't care about these ones. Besides, they are
+				   always disabled, so any possible disabling caused by the
+				   epid attention interrupt is irrelevant. */
+                                warn("Got epid_attn for DUMMY_EPID (%d).", epid);
+				continue;
+                        }
+
+                        /* Get the first urb in the urb list for this epid. We blatantly assume
+                           that only the first urb could have caused the epid attention.
+                           (For bulk and ctrl, only one urb is active at any one time. For intr
+                           and isoc we remove them once they are completed.) */
+                        urb = urb_list_first(epid);
+
+			if (urb == NULL) {
+                                err("Got epid_attn for epid %i with no urb.", epid);
+                                err("R_USB_EPT_DATA = 0x%x", r_usb_ept_data);
+                                err("R_USB_STATUS = 0x%x", reg->r_usb_status);
+				continue;
+			}
+
+                        switch (usb_pipetype(urb->pipe)) {
+                        case PIPE_BULK:
+                                warn("Got epid attn for bulk endpoint, epid %d", epid);
+                                break;                
+                        case PIPE_CONTROL:
+                                warn("Got epid attn for control endpoint, epid %d", epid);
+                                break;
+                        case PIPE_INTERRUPT:
+                                warn("Got epid attn for interrupt endpoint, epid %d", epid);
+                                break;
+                        case PIPE_ISOCHRONOUS:
+                                warn("Got epid attn for isochronous endpoint, epid %d", epid);
+                                break;
+                        }
+                        
+                        if (usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS) {        
+                                if (r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, hold)) {
+                                        warn("Hold was set for epid %d.", epid);
+                                        continue;
+                                }
+                        }
+                        
+                        /* Even though error_code occupies bits 22 - 23 in both R_USB_EPT_DATA and 
+                           R_USB_EPT_DATA_ISOC, we separate them here so we don't forget in other places. */
+                        if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+                                error_code = IO_EXTRACT(R_USB_EPT_DATA_ISO, error_code, r_usb_ept_data);
+                        } else {
+                                error_code = IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data);
+                        }
+                        
+			/* Using IO_STATE_VALUE on R_USB_EPT_DATA should be ok for isoc also. */
+			if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
 
-	reg->usb_bh.sync = 0;
-	reg->usb_bh.routine = etrax_usb_hc_intr_bottom_half;
-	reg->usb_bh.data = reg;
+                                /* Isoc traffic doesn't have error_count_in/error_count_out. */
+				if ((usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS) &&
+                                    (IO_EXTRACT(R_USB_EPT_DATA, error_count_in, r_usb_ept_data) == 3 ||
+                                     IO_EXTRACT(R_USB_EPT_DATA, error_count_out, r_usb_ept_data) == 3)) {
+				        /* 3rd error. */
+					warn("3rd error for epid %i", epid);
+                                        etrax_usb_complete_urb(urb, -EPROTO);
+
+                                } else if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) {
+                                        
+                                        warn("Perror for epid %d", epid);
+                                        
+                                        if (!(r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, valid))) {
+                                                /* invalid ep_id */
+                                                panic("Perror because of invalid epid."
+                                                      " Deconfigured too early?");
+                                        } else {
+                                                /* past eof1, near eof, zout transfer, setup transfer */
+                                                
+                                                /* Dump the urb and the relevant EP descriptor list. */
+
+                                                __dump_urb(urb);
+						__dump_ept_data(epid);
+                                                __dump_ep_list(usb_pipetype(urb->pipe));
+                                                
+                                                panic("Something wrong with DMA descriptor contents."
+                                                      " Too much traffic inserted?");
+                                        }
+                                } else if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) {
+                                        /* buffer ourun */
+                                        panic("Buffer overrun/underrun for epid %d. DMA too busy?", epid);
+                                }
 
-	queue_task(&reg->usb_bh, &tq_immediate);
-	mark_bh(IMMEDIATE_BH);
+			} else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, stall)) {
+                                /* Not really a protocol error, just says that the endpoint gave
+                                   a stall response. Note that error_code cannot be stall for isoc. */
+                                if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+                                        panic("Isoc traffic cannot stall");
+                                }
+                                
+                                warn("Stall for epid %d", epid);
+                                etrax_usb_complete_urb(urb, -EPIPE);
+				
+			} else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, bus_error)) {
+                                /* Two devices responded to a transaction request. Must be resolved
+                                   by software. FIXME: Reset ports? */
+				panic("Bus error for epid %d."
+                                      " Two devices responded to transaction request",
+                                      epid);
+				
+			} else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, buffer_error)) {
+                                /* DMA overrun or underrun. */
+				warn("Buffer overrun/underrun for epid %d. DMA too busy?", epid);
 
-	DBFEXIT;
+                                /* It seems that error_code = buffer_error in 
+                                   R_USB_EPT_DATA/R_USB_EPT_DATA_ISO and ourun = yes in R_USB_STATUS
+                                   are the same error. */
+                                etrax_usb_complete_urb(urb, -EPROTO);
+                        }               
+                }
+        }
+
+        DBFEXIT;
+        
+}
+
+void etrax_usb_bulk_start_timer_func(unsigned long dummy)
+{
+       
+        /* We might enable an EP descriptor behind the current DMA position when it's about
+           to decide that there are no more bulk traffic and it should stop the bulk channel.
+           Therefore we periodically check if the bulk channel is stopped and there is an
+           enabled bulk EP descriptor, in which case we start the bulk channel. */
+        dbg_bulk("bulk_start_timer timed out.");        
+
+        if (!(*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd))) {
+                int epid;
+                
+		dbg_bulk("Bulk DMA channel not running.");
+
+                for (epid = 0; epid < NBR_OF_EPIDS; epid++) {
+                        if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) {
+                                printk("Found enabled EP for epid %d, starting bulk channel.\n",
+				       epid);
+                                *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start);
+                                
+                                /* Restart the bulk eot timer since we just started the bulk channel. */
+                                mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL);
+
+                                /* No need to search any further. */
+                                break;
+                        }
+                }
+        } else {
+		dbg_bulk("Bulk DMA channel running.");
+	}
+}
+
+void etrax_usb_hc_port_status_interrupt(usb_interrupt_registers_t *reg)
+{
+        etrax_hc_t *hc = reg->hc;
+        __u16 r_usb_rh_port_status_1 = reg->r_usb_rh_port_status_1;
+	__u16 r_usb_rh_port_status_2 = reg->r_usb_rh_port_status_2;
+
+        DBFENTER;
+        
+        /* The Etrax RH does not include a wPortChange register, so this has to be handled in software
+           (by saving the old port status value for comparison when the port status interrupt happens).
+           See section 11.16.2.6.2 in the USB 1.1 spec for details. */
+        
+        dbg_rh("hc->rh.prev_wPortStatus_1 = 0x%x", hc->rh.prev_wPortStatus_1);
+        dbg_rh("hc->rh.prev_wPortStatus_2 = 0x%x", hc->rh.prev_wPortStatus_2);
+        dbg_rh("r_usb_rh_port_status_1 = 0x%x", r_usb_rh_port_status_1);
+        dbg_rh("r_usb_rh_port_status_2 = 0x%x", r_usb_rh_port_status_2);
+        
+        /* C_PORT_CONNECTION is set on any transition. */
+        hc->rh.wPortChange_1 |=
+                ((r_usb_rh_port_status_1 & (1 << RH_PORT_CONNECTION)) !=
+                 (hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_CONNECTION))) ?
+                (1 << RH_PORT_CONNECTION) : 0;
+        
+        hc->rh.wPortChange_2 |=
+                ((r_usb_rh_port_status_2 & (1 << RH_PORT_CONNECTION)) !=
+                 (hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_CONNECTION))) ?
+                (1 << RH_PORT_CONNECTION) : 0;
+        
+        /* C_PORT_ENABLE is _only_ set on a one to zero transition, i.e. when
+           the port is disabled, not when it's enabled. */
+        hc->rh.wPortChange_1 |=
+                ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_ENABLE))
+                 && !(r_usb_rh_port_status_1 & (1 << RH_PORT_ENABLE))) ?
+                (1 << RH_PORT_ENABLE) : 0;
+	
+        hc->rh.wPortChange_2 |=
+                ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_ENABLE))
+                 && !(r_usb_rh_port_status_2 & (1 << RH_PORT_ENABLE))) ?
+                (1 << RH_PORT_ENABLE) : 0;
+
+        /* C_PORT_SUSPEND is set to one when the device has transitioned out
+           of the suspended state, i.e. when suspend goes from one to zero. */
+        hc->rh.wPortChange_1 |=
+                ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_SUSPEND))
+                 && !(r_usb_rh_port_status_1 & (1 << RH_PORT_SUSPEND))) ?
+                (1 << RH_PORT_SUSPEND) : 0;
+        
+        hc->rh.wPortChange_2 |=
+                ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_SUSPEND))
+                 && !(r_usb_rh_port_status_2 & (1 << RH_PORT_SUSPEND))) ?
+                (1 << RH_PORT_SUSPEND) : 0;
+
+        
+        /* C_PORT_RESET is set when reset processing on this port is complete. */
+        hc->rh.wPortChange_1 |=
+                ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_RESET))
+                 && !(r_usb_rh_port_status_1 & (1 << RH_PORT_RESET))) ?
+                (1 << RH_PORT_RESET) : 0;
+        
+        hc->rh.wPortChange_2 |=
+                ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_RESET))
+                 && !(r_usb_rh_port_status_2 & (1 << RH_PORT_RESET))) ?
+                (1 << RH_PORT_RESET) : 0;
+
+        /* Save the new values for next port status change. */
+        hc->rh.prev_wPortStatus_1 = r_usb_rh_port_status_1;
+        hc->rh.prev_wPortStatus_2 = r_usb_rh_port_status_2;	
+
+        dbg_rh("hc->rh.wPortChange_1 set to 0x%x", hc->rh.wPortChange_1);
+        dbg_rh("hc->rh.wPortChange_2 set to 0x%x", hc->rh.wPortChange_2);
+        
+        DBFEXIT;
+
+}
+
+void etrax_usb_hc_ctl_status_interrupt(usb_interrupt_registers_t *reg)
+{
+        DBFENTER;
+
+        /* FIXME: What should we do if we get ourun or perror? Dump the EP and SB
+           list for the corresponding epid? */
+        if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) {
+                panic("USB controller got ourun.");
+        } 
+        if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) {
+
+                /* Before, etrax_usb_do_intr_recover was called on this epid if it was
+                   an interrupt pipe. I don't see how re-enabling all EP descriptors
+                   will help if there was a programming error. */
+                panic("USB controller got perror.");
+        } 
+
+        if (reg->r_usb_status & IO_MASK(R_USB_STATUS, device_mode)) {
+                /* We should never operate in device mode. */
+                panic("USB controller in device mode.");
+        }
+
+        /* These if-statements could probably be nested. */
+        if (reg->r_usb_status & IO_MASK(R_USB_STATUS, host_mode)) {
+                //info("USB controller in host mode.");
+        }
+        if (reg->r_usb_status & IO_MASK(R_USB_STATUS, started)) {
+                //info("USB controller started.");
+        }
+        if (reg->r_usb_status & IO_MASK(R_USB_STATUS, running)) {
+                info("USB controller running.");
+        }
+
+        DBFEXIT;
+        
 }
 
-static int etrax_rh_submit_urb(struct urb *urb)
+
+static int etrax_rh_submit_urb(urb_t *urb)
 {
 	struct usb_device *usb_dev = urb->dev;
 	etrax_hc_t *hc = usb_dev->bus->hcpriv;
 	unsigned int pipe = urb->pipe;
-	struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *) urb->setup_packet;
+	devrequest *cmd = (devrequest *) urb->setup_packet;
 	void *data = urb->transfer_buffer;
 	int leni = urb->transfer_buffer_length;
 	int len = 0;
@@ -1999,10 +3246,14 @@
 
 	DBFENTER;
 
+        /* FIXME: What is this interrupt urb that is sent to the root hub? */
 	if (usb_pipetype (pipe) == PIPE_INTERRUPT) {
 		dbg_rh("Root-Hub submit IRQ: every %d ms", urb->interval);
 		hc->rh.urb = urb;
 		hc->rh.send = 1;
+                /* FIXME: We could probably remove this line since it's done
+                   in etrax_rh_init_int_timer. (Don't remove it from
+                   etrax_rh_init_int_timer though.) */
 		hc->rh.interval = urb->interval;
 		etrax_rh_init_int_timer(urb);
 		DBFEXIT;
@@ -2010,15 +3261,22 @@
 		return 0;
 	}
 
-	bmRType_bReq = cmd->bRequestType | cmd->bRequest << 8;
-	wValue = le16_to_cpu(cmd->wValue);
-	wIndex = le16_to_cpu(cmd->wIndex);
-	wLength = le16_to_cpu(cmd->wLength);
-
-	dbg_rh("bmRType_bReq : 0x%04X (%d)", bmRType_bReq, bmRType_bReq);
-	dbg_rh("wValue       : 0x%04X (%d)", wValue, wValue);
-	dbg_rh("wIndex       : 0x%04X (%d)", wIndex, wIndex);
-	dbg_rh("wLength      : 0x%04X (%d)", wLength, wLength);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION (2, 4, 20)
+	bmRType_bReq = cmd->bRequestType | (cmd->bRequest << 8);
+        wValue = le16_to_cpu(cmd->wValue);
+        wIndex = le16_to_cpu(cmd->wIndex);
+        wLength = le16_to_cpu(cmd->wLength);
+#else
+        bmRType_bReq = cmd->requesttype | (cmd->request << 8);
+        wValue = le16_to_cpu(cmd->value);
+        wIndex = le16_to_cpu(cmd->index);
+        wLength = le16_to_cpu(cmd->length);
+#endif
+									
+	dbg_rh("bmRType_bReq : 0x%04x (%d)", bmRType_bReq, bmRType_bReq);
+	dbg_rh("wValue       : 0x%04x (%d)", wValue, wValue);
+	dbg_rh("wIndex       : 0x%04x (%d)", wIndex, wIndex);
+	dbg_rh("wLength      : 0x%04x (%d)", wLength, wLength);
 	
 	switch (bmRType_bReq) {
 		
@@ -2050,13 +3308,11 @@
 		if (wIndex == 1) {
 			*((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_1);
 			*((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_1);
-		}
-		else if (wIndex == 2) {
+		} else if (wIndex == 2) {
 			*((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_2);
 			*((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_2);
-		}
-		else {
-			dbg_rh("RH_GET_STATUS whith invalid wIndex !!");
+		} else {
+			dbg_rh("RH_GET_STATUS whith invalid wIndex!");
 			OK(0);
 		}
 		
@@ -2081,9 +3337,10 @@
 		case (RH_PORT_ENABLE):
 			if (wIndex == 1) {
 
-				dbg_rh("trying to do disable of port 1");
+				dbg_rh("trying to do disable port 1");
 
 				*R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, yes);
+
 				while (hc->rh.prev_wPortStatus_1 &
 				       IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, yes));
 				*R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, no);
@@ -2091,9 +3348,10 @@
 
 			} else if (wIndex == 2) {
 
-				dbg_rh("trying to do disable of port 2");
+				dbg_rh("trying to do disable port 2");
 				
 				*R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, yes);
+
 				while (hc->rh.prev_wPortStatus_2 &
 				       IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, yes));
 				*R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, no);
@@ -2101,25 +3359,35 @@
 
 			} else {
 				dbg_rh("RH_CLEAR_FEATURE->RH_PORT_ENABLE "
-				       "with invalid wIndex == %d!!", wIndex);
+				       "with invalid wIndex == %d!", wIndex);
 			}			
 				
 			OK (0);
 		case (RH_PORT_SUSPEND):
-			/* Opposite to suspend should be resume, so well do a resume */
+			/* Opposite to suspend should be resume, so we'll do a resume. */
+                        /* FIXME: USB 1.1, 11.16.2.2 says:
+                           "Clearing the PORT_SUSPEND feature causes a host-initiated resume
+                           on the specified port. If the port is not in the Suspended state,
+                           the hub should treat this request as a functional no-operation."
+                           Shouldn't we check if the port is in a suspended state before
+                           resuming? */
+                        
+                        /* Make sure the controller isn't busy. */
+                        while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
+
 			if (wIndex == 1) {
 				*R_USB_COMMAND =
 					IO_STATE(R_USB_COMMAND, port_sel, port1) |
-					IO_STATE(R_USB_COMMAND, port_cmd, resume)|
+					IO_STATE(R_USB_COMMAND, port_cmd, resume) |
 					IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
 			} else if (wIndex == 2) {
 				*R_USB_COMMAND =
 					IO_STATE(R_USB_COMMAND, port_sel, port2) |
-					IO_STATE(R_USB_COMMAND, port_cmd, resume)|
+					IO_STATE(R_USB_COMMAND, port_cmd, resume) |
 					IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
 			} else {
 				dbg_rh("RH_CLEAR_FEATURE->RH_PORT_SUSPEND "
-				       "with invalid wIndex == %d!!", wIndex);
+				       "with invalid wIndex == %d!", wIndex);
 			}
 			
 			OK (0);
@@ -2129,26 +3397,22 @@
 			
 			if (wIndex == 1) {
 				hc->rh.wPortChange_1 &= ~(1 << RH_PORT_CONNECTION);
-			}
-			else if (wIndex == 2) {
+			} else if (wIndex == 2) {
 				hc->rh.wPortChange_2 &= ~(1 << RH_PORT_CONNECTION);
-			}
-			else {
+			} else {
 				dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_CONNECTION "
-				       "with invalid wIndex == %d!!", wIndex);
+				       "with invalid wIndex == %d!", wIndex);
 			}
 
 			OK (0);
 		case (RH_C_PORT_ENABLE):
 			if (wIndex == 1) {
 				hc->rh.wPortChange_1 &= ~(1 << RH_PORT_ENABLE);
-			}
-			else if (wIndex == 2) {
+			} else if (wIndex == 2) {
 				hc->rh.wPortChange_2 &= ~(1 << RH_PORT_ENABLE);
-			}
-			else {
+			} else {
 				dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_ENABLE "
-				       "with invalid wIndex == %d!!", wIndex);
+				       "with invalid wIndex == %d!", wIndex);
 			}
 			OK (0);
 		case (RH_C_PORT_SUSPEND):
@@ -2159,15 +3423,11 @@
 		case (RH_C_PORT_RESET):
 			if (wIndex == 1) {
 				hc->rh.wPortChange_1 &= ~(1 << RH_PORT_RESET);
-			}
-			else if (wIndex == 2) {
-				dbg_rh("This is wPortChange before clear: 0x%04X", hc->rh.wPortChange_2);
-				
+			} else if (wIndex == 2) {
 				hc->rh.wPortChange_2 &= ~(1 << RH_PORT_RESET);
-				dbg_rh("This is wPortChange after clear: 0x%04X", hc->rh.wPortChange_2);
 			} else {
 				dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_RESET "
-				       "with invalid index == %d!!", wIndex);
+				       "with invalid index == %d!", wIndex);
 			}
 
 			OK (0);
@@ -2178,6 +3438,10 @@
 	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
 		switch (wValue) {
 		case (RH_PORT_SUSPEND):
+
+                        /* Make sure the controller isn't busy. */
+                        while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
+
 			if (wIndex == 1) {
 				*R_USB_COMMAND =
 					IO_STATE(R_USB_COMMAND, port_sel, port1) |
@@ -2189,76 +3453,150 @@
 					IO_STATE(R_USB_COMMAND, port_cmd, suspend) |
 					IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
 			} else {
-				dbg_rh("RH_SET_FEATURE->RH_C_PORT_SUSPEND "
-				       "with invalid wIndex == %d!!", wIndex);
+				dbg_rh("RH_SET_FEATURE->RH_PORT_SUSPEND "
+				       "with invalid wIndex == %d!", wIndex);
 			}			
 
 			OK (0);
 		case (RH_PORT_RESET):
 			if (wIndex == 1) {
-				int port1_retry;
 				
-			port1_redo:
+			port_1_reset:
 				dbg_rh("Doing reset of port 1");
+                                
+                                /* Make sure the controller isn't busy. */
+                                while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
 
 				*R_USB_COMMAND =
+					IO_STATE(R_USB_COMMAND, port_sel, port1) | 
 					IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-					IO_STATE(R_USB_COMMAND, port_sel, port1);
-
-				/* We must once again wait at least 10ms for the device to recover */
+					IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
 
-				port1_retry = 0;
-				while (!((*((volatile __u16 *)&hc->rh.prev_wPortStatus_1)) &
-					 IO_STATE(R_USB_RH_PORT_STATUS_1,
-						  enabled, yes))) {
-					printk(""); if (port1_retry++ >= 10000) {goto port1_redo;}
-				}
-				
-				/* This only seems to work if we use printk,
-				   not even schedule() works !!! WHY ?? */
+                                /* We must wait at least 10 ms for the device to recover.
+                                   15 ms should be enough. */
+                                udelay(15000);
+                                
+                                /* Wait for reset bit to go low (should be done by now). */
+                                while (hc->rh.prev_wPortStatus_1 &
+                                       IO_STATE(R_USB_RH_PORT_STATUS_1, reset, yes));
+                                
+                                /* If the port status is
+                                   1) connected and enabled then there is a device and everything is fine
+                                   2) neither connected nor enabled then there is no device, also fine
+                                   3) connected and not enabled then we try again
+                                   (Yes, there are other port status combinations besides these.) */
+
+                                if ((hc->rh.prev_wPortStatus_1 & 
+                                     IO_STATE(R_USB_RH_PORT_STATUS_1, connected, yes)) &&
+                                    (hc->rh.prev_wPortStatus_1 & 
+                                     IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, no))) {
+                                        dbg_rh("Connected device on port 1, but port not enabled?"
+                                               " Trying reset again.");
+                                        goto port_2_reset;
+                                }
+
+                                /* Diagnostic printouts. */
+                                if ((hc->rh.prev_wPortStatus_1 & 
+                                     IO_STATE(R_USB_RH_PORT_STATUS_1, connected, no)) &&
+                                    (hc->rh.prev_wPortStatus_1 & 
+                                     IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, no))) {
+                                        dbg_rh("No connected device on port 1");
+                                } else if ((hc->rh.prev_wPortStatus_1 & 
+                                            IO_STATE(R_USB_RH_PORT_STATUS_1, connected, yes)) &&
+                                           (hc->rh.prev_wPortStatus_1 & 
+                                            IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, yes))) {
+                                        dbg_rh("Connected device on port 1, port 1 enabled");
+                                }
 
-				udelay(15000);
-			}
-			else if (wIndex == 2) {
-				int port2_retry;
-				
-			port2_redo:
+			} else if (wIndex == 2) {
+                                
+			port_2_reset:
 				dbg_rh("Doing reset of port 2");
 				
+                                /* Make sure the controller isn't busy. */
+                                while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
+
+                                /* Issue the reset command. */
 				*R_USB_COMMAND =
+					IO_STATE(R_USB_COMMAND, port_sel, port2) |
 					IO_STATE(R_USB_COMMAND, port_cmd, reset) |
-					IO_STATE(R_USB_COMMAND, port_sel, port2);
-
-				/* We must once again wait at least 10ms for the device to recover */
+					IO_STATE(R_USB_COMMAND, ctrl_cmd, nop);
 
-				port2_retry = 0;
-				while (!((*((volatile __u16 *)&hc->rh.prev_wPortStatus_2)) &
-					 IO_STATE(R_USB_RH_PORT_STATUS_2,
-						  enabled, yes))) {
-					printk(""); if (port2_retry++ >= 10000) {goto port2_redo;}
-				}
-				
-				/* This only seems to work if we use printk,
-				   not even schedule() works !!! WHY ?? */
+				/* We must wait at least 10 ms for the device to recover.
+                                   15 ms should be enough. */
+                                udelay(15000);
+                                
+                                /* Wait for reset bit to go low (should be done by now). */
+                                while (hc->rh.prev_wPortStatus_2 &
+                                       IO_STATE(R_USB_RH_PORT_STATUS_2, reset, yes));
+                                
+                                /* If the port status is
+                                   1) connected and enabled then there is a device and everything is fine
+                                   2) neither connected nor enabled then there is no device, also fine
+                                   3) connected and not enabled then we try again
+                                   (Yes, there are other port status combinations besides these.) */
+
+                                if ((hc->rh.prev_wPortStatus_2 & 
+                                     IO_STATE(R_USB_RH_PORT_STATUS_2, connected, yes)) &&
+                                    (hc->rh.prev_wPortStatus_2 & 
+                                     IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, no))) {
+                                        dbg_rh("Connected device on port 2, but port not enabled?"
+                                               " Trying reset again.");
+                                        goto port_2_reset;
+                                }
+
+                                /* Diagnostic printouts. */
+                                if ((hc->rh.prev_wPortStatus_2 & 
+                                     IO_STATE(R_USB_RH_PORT_STATUS_2, connected, no)) &&
+                                    (hc->rh.prev_wPortStatus_2 & 
+                                     IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, no))) {
+                                        dbg_rh("No connected device on port 2");
+                                } else if ((hc->rh.prev_wPortStatus_2 & 
+                                            IO_STATE(R_USB_RH_PORT_STATUS_2, connected, yes)) &&
+                                           (hc->rh.prev_wPortStatus_2 & 
+                                            IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, yes))) {
+                                        dbg_rh("Connected device on port 2, port 2 enabled");
+                                }
 
-				udelay(15000);
-			}
+			} else {
+				dbg_rh("RH_SET_FEATURE->RH_PORT_RESET with invalid wIndex = %d", wIndex);
+                        }
+                        
+                        /* Make sure the controller isn't busy. */
+                        while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
+
+			/* If all enabled ports were disabled the host controller goes down into
+                           started mode, so we need to bring it back into the running state.
+                           (This is safe even if it's already in the running state.) */
+                        *R_USB_COMMAND =
+                                IO_STATE(R_USB_COMMAND, port_sel, nop) |
+                                IO_STATE(R_USB_COMMAND, port_cmd, reset) |
+                                IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run);
 
-			/* Try to bring the HC into running state */
-			*R_USB_COMMAND =
-				IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run);
-			
-			nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
-			
 			dbg_rh("...Done");
 			OK(0);
 
 		case (RH_PORT_POWER):
 			OK (0);	/* port power ** */
 		case (RH_PORT_ENABLE):
-			/* There is no rh port enable command in the Etrax USB interface!!!! */
+			/* There is no port enable command in the host controller, so if the
+                           port is already enabled, we do nothing. If not, we reset the port
+                           (with an ugly goto). */
+
+                        if (wIndex == 1) {
+                                if (hc->rh.prev_wPortStatus_1 & 
+                                    IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, no)) {
+                                        goto port_1_reset;
+                                }
+                        } else if (wIndex == 2) {
+                                if (hc->rh.prev_wPortStatus_2 & 
+                                    IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, no)) {
+                                        goto port_2_reset;
+                                }
+                        } else {
+                                dbg_rh("RH_SET_FEATURE->RH_GET_STATUS with invalid wIndex = %d", wIndex);
+                        }
 			OK (0);
-
 		}
 		break;
 		
@@ -2283,8 +3621,10 @@
 						   data, wLength);
 			if (len > 0) {
 				OK(min(leni, len));
-			} else 
+			} else {
 				stat = -EPIPE;
+                        }
+                        
 		}
 		break;
 		
@@ -2309,33 +3649,56 @@
 	urb->status = stat;
 	urb->dev = NULL;
 	if (urb->complete) {
-		urb->complete (urb);
+		urb->complete(urb);
 	}
 	DBFEXIT;
 	
 	return 0;
 }
 
+static void
+etrax_usb_bulk_eot_timer_func(unsigned long dummy)
+{
+        /* Because of a race condition in the top half, we might miss a bulk eot.
+           This timer "simulates" a bulk eot if we don't get one for a while, hopefully
+           correcting the situation. */
+        dbg_bulk("bulk_eot_timer timed out.");
+        etrax_usb_hc_bulk_eot_interrupt(1);
+}
+
 static int __init etrax_usb_hc_init(void)
 {
 	static etrax_hc_t *hc;
 	struct usb_bus *bus;
 	struct usb_device *usb_rh;
-	
+	int i;
+        
 	DBFENTER;
 
-	info("ETRAX 100LX USB-HCD %s (c) 2001 Axis Communications AB\n", usb_hcd_version);
-	
-	hc = kmalloc(sizeof(etrax_hc_t), GFP_KERNEL);
+	info("ETRAX 100LX USB-HCD %s (c) 2001-2003 Axis Communications AB\n", usb_hcd_version);
+
+ 	hc = kmalloc(sizeof(etrax_hc_t), GFP_KERNEL);
+	assert(hc != NULL);
 
 	/* We use kmem_cache_* to make sure that all DMA desc. are dword aligned */
-	usb_desc_cache = kmem_cache_create("usb_desc_cache", sizeof(USB_EP_Desc_t), 0, 0, 0, 0);
-	if (!usb_desc_cache) {
-		panic("USB Desc Cache allocation failed !!!\n");
-	}
-	
+        /* Note that we specify sizeof(USB_EP_Desc_t) as the size, but also allocate
+           SB descriptors from this cache. This is ok since sizeof(USB_EP_Desc_t) ==
+           sizeof(USB_SB_Desc_t). */
+
+	usb_desc_cache = kmem_cache_create("usb_desc_cache", sizeof(USB_EP_Desc_t), 0, 
+                                           SLAB_HWCACHE_ALIGN, 0, 0);
+	assert(usb_desc_cache != NULL);
+	
+	top_half_reg_cache = kmem_cache_create("top_half_reg_cache", 
+					       sizeof(usb_interrupt_registers_t), 
+					       0, SLAB_HWCACHE_ALIGN, 0, 0);
+	assert(top_half_reg_cache != NULL);
+
 	etrax_usb_bus = bus = usb_alloc_bus(&etrax_usb_device_operations);
 	hc->bus = bus;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION (2, 4, 20)
+	bus->bus_name="ETRAX 100LX";
+#endif
 	bus->hcpriv = hc;
 
 	/* Initalize RH to the default address.
@@ -2350,17 +3713,50 @@
 	hc->rh.prev_wPortStatus_2 = 0;
 
 	/* Initialize the intr-traffic flags */
+        /* FIXME: This isn't used. (Besides, the error field isn't initialized.) */
 	hc->intr.sleeping = 0;
 	hc->intr.wq = NULL;
 
-	/* Initially all ep's are free except ep 0 */
-	ep_usage_bitmask = 0;
-	set_bit(0, (void *)&ep_usage_bitmask);
-	ep_really_active = 0;
-	ep_out_traffic = 0;
-
-	memset(URB_List, 0, sizeof(URB_List));
+	epid_usage_bitmask = 0;
+	epid_out_traffic = 0;
 
+        /* Mark the invalid epid as being used. */
+	set_bit(INVALID_EPID, (void *)&epid_usage_bitmask);
+        *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, INVALID_EPID);
+        nop();
+        /* The valid bit should still be set ('invalid' is in our world; not the hardware's). */
+        *R_USB_EPT_DATA = (IO_STATE(R_USB_EPT_DATA, valid, yes) |
+			   IO_FIELD(R_USB_EPT_DATA, max_len, 1));
+
+	/* Mark the dummy epid as being used. */
+	set_bit(DUMMY_EPID, (void *)&epid_usage_bitmask);
+        *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, DUMMY_EPID);
+        nop();
+        *R_USB_EPT_DATA = (IO_STATE(R_USB_EPT_DATA, valid, no) |
+			   IO_FIELD(R_USB_EPT_DATA, max_len, 1));
+
+        /* Initialize the urb list by initiating a head for each list. */
+        for (i = 0; i < NBR_OF_EPIDS; i++) {
+                INIT_LIST_HEAD(&urb_list[i]);
+        }
+	spin_lock_init(&urb_list_lock);
+
+        INIT_LIST_HEAD(&urb_unlink_list);
+                        
+
+        /* Initiate the bulk start timer. */
+        init_timer(&bulk_start_timer);
+        bulk_start_timer.expires = jiffies + BULK_START_TIMER_INTERVAL;
+        bulk_start_timer.function = etrax_usb_bulk_start_timer_func;
+        add_timer(&bulk_start_timer);
+
+
+        /* Initiate the bulk eot timer. */
+        init_timer(&bulk_eot_timer);
+        bulk_eot_timer.expires = jiffies + BULK_EOT_TIMER_INTERVAL;
+        bulk_eot_timer.function = etrax_usb_bulk_eot_timer_func;
+        add_timer(&bulk_eot_timer);
+        
 	/* This code should really be moved */
 
 	if (request_dma(USB_TX_DMA_NBR, "ETRAX 100LX built-in USB (Tx)")) {
@@ -2375,48 +3771,41 @@
 		etrax_usb_hc_cleanup();
 		DBFEXIT;
 		return -1;
-	}	
-#if 0  /* Moved to head.S */
-	*R_GEN_CONFIG = genconfig_shadow =
-		(genconfig_shadow & ~(IO_MASK(R_GEN_CONFIG, usb1) |
-				      IO_MASK(R_GEN_CONFIG, usb2) |
-				      IO_MASK(R_GEN_CONFIG, dma8) |
-				      IO_MASK(R_GEN_CONFIG, dma9))) |
-		IO_STATE(R_GEN_CONFIG, dma8, usb) |
-		IO_STATE(R_GEN_CONFIG, dma9, usb)
-#ifdef CONFIG_ETRAX_USB_HOST_PORT1
-		| IO_STATE(R_GEN_CONFIG, usb1, select)
-#endif
-#ifdef CONFIG_ETRAX_USB_HOST_PORT2
-		| IO_STATE(R_GEN_CONFIG, usb2, select)
-#endif
-	;
-#endif
+	}
+
+        /* Set up the data structures for USB traffic. Note that this must be done before
+           any interrupt that relies on sane DMA list occurrs. */
+	init_rx_buffers();
+	init_tx_bulk_ep();
+	init_tx_ctrl_ep();
+	init_tx_intr_ep();
+	init_tx_isoc_ep();
+
 	
 	usb_register_bus(hc->bus);
 
-	/* We may have to set more bits, but these are the obvious ones */
+        /* Note that these interrupts are not used. */
 	*R_IRQ_MASK2_SET =
 		IO_STATE(R_IRQ_MASK2_SET, dma8_sub0_descr, set) |
 		IO_STATE(R_IRQ_MASK2_SET, dma8_sub1_descr, set) |
 		IO_STATE(R_IRQ_MASK2_SET, dma8_sub2_descr, set) |
 		IO_STATE(R_IRQ_MASK2_SET, dma8_sub3_descr, set);
 
+        /* Note that the dma9_descr interrupt is not used. */
 	*R_IRQ_MASK2_SET =
 		IO_STATE(R_IRQ_MASK2_SET, dma9_eop, set) |
 		IO_STATE(R_IRQ_MASK2_SET, dma9_descr, set);
 
+	/* FIXME: Enable iso_eof only when isoc traffic is running. */
 	*R_USB_IRQ_MASK_SET = 
-		IO_STATE(R_USB_IRQ_MASK_SET, ctl_status, set) |
-		IO_STATE(R_USB_IRQ_MASK_SET, ctl_eot, set) |
+                IO_STATE(R_USB_IRQ_MASK_SET, iso_eof, set) |
 		IO_STATE(R_USB_IRQ_MASK_SET, bulk_eot, set) |
-#ifdef ETRAX_USB_INTR_IRQ
-		IO_STATE(R_USB_IRQ_MASK_SET, intr_eot, set) |
-#endif
 		IO_STATE(R_USB_IRQ_MASK_SET, epid_attn, set) |
-		IO_STATE(R_USB_IRQ_MASK_SET, port_status, set);
+		IO_STATE(R_USB_IRQ_MASK_SET, port_status, set) |
+                IO_STATE(R_USB_IRQ_MASK_SET, ctl_status, set);
+
 	
-	if (request_irq(ETRAX_USB_HC_IRQ, etrax_usb_hc_intr_top_half, 0,
+	if (request_irq(ETRAX_USB_HC_IRQ, etrax_usb_hc_interrupt_top_half, 0,
 			"ETRAX 100LX built-in USB (HC)", hc)) {
 		err("Could not allocate IRQ %d for USB", ETRAX_USB_HC_IRQ);
 		etrax_usb_hc_cleanup();
@@ -2440,16 +3829,50 @@
 		return -1;
 	}
 
-	/* Reset the USB interface (configures as HC) */
+        /* R_USB_COMMAND:
+           USB commands in host mode. The fields in this register should all be
+           written to in one write. Do not read-modify-write one field at a time. A
+           write to this register will trigger events in the USB controller and an
+           incomplete command may lead to unpredictable results, and in worst case
+           even to a deadlock in the controller.
+           (Note however that the busy field is read-only, so no need to write to it.) */
+
+        /* Check the busy bit before writing to R_USB_COMMAND. */
+
+        while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
+ 
+	/* Reset the USB interface. */
 	*R_USB_COMMAND =
-		IO_STATE(R_USB_COMMAND, ctrl_cmd, reset) |
-		IO_STATE(R_USB_COMMAND, port_cmd, reset);
-	
-	nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
-#if 1
-	/* Initate PSTART to all unallocatable bit times */
-	*R_USB_FM_PSTART = IO_FIELD(R_USB_FM_PSTART, value, 10000);
-#endif
+                IO_STATE(R_USB_COMMAND, port_sel, nop) |
+		IO_STATE(R_USB_COMMAND, port_cmd, reset) |
+		IO_STATE(R_USB_COMMAND, ctrl_cmd, reset);
+	
+	/* Designer's Reference, p. 8 - 10 says we should Initate R_USB_FM_PSTART to 0x2A30 (10800),
+           to guarantee that control traffic gets 10% of the bandwidth, and periodic transfer may
+           allocate the rest (90%). This doesn't work though. Read on for a lenghty explanation.
+
+           While there is a difference between rev. 2 and rev. 3 of the ETRAX 100LX regarding the NAK
+           behaviour, it doesn't solve this problem. What happens is that a control transfer will not
+           be interrupted in its data stage when PSTART happens (the point at which periodic traffic
+           is started). Thus, if PSTART is set to 10800 and its IN or OUT token is NAKed until just before
+           PSTART happens, it will continue the IN/OUT transfer as long as it's ACKed. After it's done,
+           there may be too little time left for an isochronous transfer, causing an epid attention 
+           interrupt due to perror. The work-around for this is to let the control transfers run at the
+           end of the frame instead of at the beginning, and will be interrupted just fine if it doesn't
+           fit into the frame. However, since there will *always* be a control transfer at the beginning
+           of the frame, regardless of what we set PSTART to, that transfer might be a 64-byte transfer
+           which consumes up to 15% of the frame, leaving only 85% for periodic traffic. The solution to
+           this would be to 'dummy allocate' 5% of the frame with the usb_claim_bandwidth function to make
+           sure that the periodic transfers that are inserted will always fit in the frame.
+
+           The idea was suggested that a control transfer could be split up into several 8 byte transfers,
+           so that it would be interrupted by PSTART, but since this can't be done for an IN transfer this
+           hasn't been implemented.
+
+           The value 11960 is chosen to be just after the SOF token, with a couple of bit times extra
+           for possible bit stuffing. */
+
+        *R_USB_FM_PSTART = IO_FIELD(R_USB_FM_PSTART, value, 11960);
 
 #ifdef CONFIG_ETRAX_USB_HOST_PORT1
 	*R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, no);
@@ -2459,32 +3882,28 @@
 	*R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, no);
 #endif
 	
-	*R_USB_COMMAND =
-		IO_STATE(R_USB_COMMAND, ctrl_cmd, host_config) |
-		IO_STATE(R_USB_COMMAND, port_cmd, reset);
-	
-	nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
+        while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
 
+        /* Configure the USB interface as a host controller. */
 	*R_USB_COMMAND =
-		IO_STATE(R_USB_COMMAND, port_sel, port1) |
-		IO_STATE(R_USB_COMMAND, port_cmd, reset);
-
-	nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
+                IO_STATE(R_USB_COMMAND, port_sel, nop) |
+                IO_STATE(R_USB_COMMAND, port_cmd, reset) |
+		IO_STATE(R_USB_COMMAND, ctrl_cmd, host_config);
+
+        /* Note: Do not reset any ports here. Await the port status interrupts, to have a controlled
+           sequence of resetting the ports. If we reset both ports now, and there are devices
+           on both ports, we will get a bus error because both devices will answer the set address
+           request. */
 
-	/* Here we must wait at least 10ms so the device has time to recover */
-	udelay(15000);
+        while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
 
-	init_rx_buffers();
-	init_tx_bulk_ep();
-	init_tx_ctrl_ep();
-	init_tx_intr_ep();
-
-	/* This works. It seems like the host_run command only has effect when a device is connected,
-	 i.e. it has to be done when a interrup */
+        /* Start processing of USB traffic. */
 	*R_USB_COMMAND =
+		IO_STATE(R_USB_COMMAND, port_sel, nop) |
+		IO_STATE(R_USB_COMMAND, port_cmd, reset) |
 		IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run);
-	
-	nop(); while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
+
+        while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy));
 
 	usb_rh = usb_alloc_dev(NULL, hc->bus);
 	hc->bus->root_hub = usb_rh;
@@ -2508,6 +3927,8 @@
 	free_dma(USB_RX_DMA_NBR);
 	usb_deregister_bus(etrax_usb_bus);
 
+        /* FIXME: call kmem_cache_destroy here? */
+
 	DBFEXIT;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/usb-host.h linux-2.4.22-pre10/arch/cris/drivers/usb-host.h
--- linux-2.4.21/arch/cris/drivers/usb-host.h	2001-08-15 08:22:15.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/usb-host.h	2003-08-01 13:33:03.000000000 +0000
@@ -5,27 +5,27 @@
 #include <linux/list.h>
 
 typedef struct USB_IN_Desc {
-	__u16 sw_len;
-	__u16 command;
-	unsigned long next;
-	unsigned long buf;
-	__u16 hw_len;
-	__u16 status;
+	volatile __u16 sw_len;
+	volatile __u16 command;
+	volatile unsigned long next;
+	volatile unsigned long buf;
+        volatile __u16 hw_len;
+	volatile __u16 status;
 } USB_IN_Desc_t;
 
 typedef struct USB_SB_Desc {
-	__u16 sw_len;
-	__u16 command;
-	unsigned long next;
-	unsigned long buf;
+	volatile __u16 sw_len;
+	volatile __u16 command;
+	volatile unsigned long next;
+	volatile unsigned long buf;
 	__u32 dummy;
 } USB_SB_Desc_t;
 
 typedef struct USB_EP_Desc {
-	__u16 hw_len;
-	__u16 command;
-	unsigned long sub;
-	unsigned long nep;
+	volatile __u16 hw_len;
+	volatile __u16 command;
+	volatile unsigned long sub;
+	volatile unsigned long next;
 	__u32 dummy;
 } USB_EP_Desc_t;
 
@@ -37,10 +37,10 @@
 	int interval;
 	int numports;
 	struct timer_list rh_int_timer;
-	__u16 wPortChange_1;
-	__u16 wPortChange_2;
-	__u16 prev_wPortStatus_1;
-	__u16 prev_wPortStatus_2;
+	volatile __u16 wPortChange_1;
+	volatile __u16 wPortChange_2;
+	volatile __u16 prev_wPortStatus_1;
+	volatile __u16 prev_wPortStatus_2;
 };
 
 struct etrax_usb_intr_traffic {
@@ -55,40 +55,77 @@
 	struct etrax_usb_intr_traffic intr;
 } etrax_hc_t;
 
-typedef enum {idle, eot, nodata}  etrax_usb_rx_state_t;
+typedef enum {
+        STARTED,
+        NOT_STARTED,
+        UNLINK
+} etrax_usb_urb_state_t;
+
+
 
 typedef struct etrax_usb_urb_priv {
+        /* The first_sb field is used for freeing all SB descriptors belonging
+           to an urb. The corresponding ep descriptor's sub pointer cannot be
+           used for this since the DMA advances the sub pointer as it processes
+           the sb list. */
 	USB_SB_Desc_t *first_sb;
+	/* The last_sb field referes to the last SB descriptor that belongs to
+           this urb. This is important to know so we can free the SB descriptors
+	   that ranges between first_sb and last_sb. */	
+	USB_SB_Desc_t *last_sb;
+
+        /* The rx_offset field is used in ctrl and bulk traffic to keep track
+           of the offset in the urb's transfer_buffer where incoming data should be
+           copied to. */
 	__u32 rx_offset;
-	etrax_usb_rx_state_t rx_state;
-	__u8 eot;
-	struct list_head ep_in_list;
-} etrax_urb_priv_t;
 
+	/* Counter used in isochronous transfers to keep track of the
+	   number of packets received/transmitted.  */
+        __u32 isoc_packet_counter;	
+        
+        /* This field is used to pass information about the urb's current state between
+           the various interrupt handlers (thus marked volatile). */
+	volatile etrax_usb_urb_state_t urb_state;
+
+	/* Connection between the submitted urb and ETRAX epid number */
+	__u8 epid;
+
+        /* The rx_data_list field is used for periodic traffic, to hold 
+           received data for later processing in the the complete_urb functions,
+           where the data us copied to the urb's transfer_buffer. Basically, we
+           use this intermediate storage because we don't know when it's safe to
+           reuse the transfer_buffer (FIXME?). */
+	struct list_head rx_data_list;
+} etrax_urb_priv_t;
 
-struct usb_reg_context
+/* This struct is for passing data from the top half to the bottom half. */
+typedef struct usb_interrupt_registers
 {
 	etrax_hc_t *hc;
 	__u32 r_usb_epid_attn;
 	__u8 r_usb_status;
-	__u32 r_usb_rh_port_status_1;
-	__u32 r_usb_rh_port_status_2;
+	__u16 r_usb_rh_port_status_1;
+	__u16 r_usb_rh_port_status_2;
 	__u32 r_usb_irq_mask_read;
+        __u32 r_usb_fm_number;
 	struct tq_struct usb_bh;
-#if 0
-	__u32 r_usb_ept_data[32];
-#endif
-};
+} usb_interrupt_registers_t;
 
-struct in_chunk
+/* This struct holds data we get from the rx descriptors for DMA channel 9
+   for periodic traffic (intr and isoc). */
+typedef struct rx_data
 {
 	void *data;
 	int length;
-	char epid;
 	struct list_head list;
-};
+} rx_data_t;
+
+typedef struct urb_entry
+{
+        urb_t *urb;
+	struct list_head list;
+} urb_entry_t;
 
-  
 /* --------------------------------------------------------------------------- 
    Virtual Root HUB 
    ------------------------------------------------------------------------- */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/virtex.c linux-2.4.22-pre10/arch/cris/drivers/virtex.c
--- linux-2.4.21/arch/cris/drivers/virtex.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/virtex.c	2003-08-01 13:30:28.000000000 +0000
@@ -7,7 +7,7 @@
 *!
 *!              The FPGA can be programmed by copying the bit-file to /dev/fpga.
 *!
-*!                cp fpga.bit > /dev/fpga
+*!                cat fpga.bit > /dev/fpga
 *!
 *!                Kernel log should look like:
 *!                  69900 bytes written
@@ -31,6 +31,9 @@
 *!  
 *! Jul 19 2002  Stefan Lundberg    Initial version.
 *! $Log: virtex.c,v $
+*! Revision 1.2  2003/02/24 07:50:30  fredriko
+*! Bugfixes and cleanups.
+*!
 *! Revision 1.1  2002/06/25 09:58:58  stefanl
 *! New FPGA driver for Platoon
 *!
@@ -40,7 +43,7 @@
 *! (C) Copyright 2002 Axis Communications AB, LUND, SWEDEN
 *!
 *!***************************************************************************/
-/* $Id: virtex.c,v 1.1 2002/06/25 09:58:58 stefanl Exp $ */
+/* $Id: virtex.c,v 1.2 2003/02/24 07:50:30 fredriko Exp $ */
 /****************** INCLUDE FILES SECTION ***********************************/
 
 #include <linux/module.h>
@@ -127,14 +130,20 @@
 
 void start_virtex_program(void)
 {
+  volatile unsigned int i=0;
   unsigned short reg_data=0;
 
   printk("Start writing to FPGA\n");
-  reg_data = SET_CS_BIT(reg_data); // FPGA unselected
+  reg_data = SET_CS_BIT(reg_data); // FPGA unselected, PROGRAM bit not set
+  WRITE_FPGA_PROG_REG(reg_data);
 
+  for(i=0;i<10;i++) { } // at least 300 ns loop
+  
   reg_data = SET_PROGRAM_BIT(reg_data);
   WRITE_FPGA_PROG_REG(reg_data);
 
+  for(i=0;i<10;i++) { } // at least 300 ns loop
+
   while(!READ_INIT); // Wait for init
   
   reg_data = SET_WRITE_BIT(reg_data);
@@ -304,6 +313,7 @@
   }
   if(copy_from_user(ptr, buf, count)) {
     printk("copy_from_user failed\n");
+    kfree(ptr);
     return -EFAULT;
   }
   
@@ -339,7 +349,7 @@
   switch (_IOC_NR(cmd)) {
     case VIRTEX_FPGA_WRITEREG:
       /* write to an FPGA register */
-      VIRTEX_DEBUG(printk("virtex wr %d %d\n", 
+      VIRTEX_DEBUG(printk("virtex wr 0x%x = 0x%x\n", 
                VIRTEX_FPGA_ARGREG(arg),
                VIRTEX_FPGA_ARGVALUE(arg)));
       
@@ -347,12 +357,12 @@
                              VIRTEX_FPGA_ARGVALUE(arg));
     case VIRTEX_FPGA_READREG:
     {
-      unsigned char val;
+      unsigned short val;
       /* read from an FPGA register */
-      VIRTEX_DEBUG(printk("virtex rd %d ", 
+      VIRTEX_DEBUG(printk("virtex rd 0x%x ", 
               VIRTEX_FPGA_ARGREG(arg)));
       val = virtex_readreg(VIRTEX_FPGA_ARGREG(arg));
-      VIRTEX_DEBUG(printk("= %d\n", val));
+      VIRTEX_DEBUG(printk("= 0x%x\n", val));
       return val;
     }					    
     default:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/drivers/virtex.h linux-2.4.22-pre10/arch/cris/drivers/virtex.h
--- linux-2.4.21/arch/cris/drivers/virtex.h	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/drivers/virtex.h	2003-08-01 13:35:10.000000000 +0000
@@ -1,7 +1,2 @@
-/* $Id: virtex.h,v 1.1 2002/06/25 09:58:58 stefanl Exp $ */
-
 int virtex_writereg(unsigned short theReg, unsigned short theValue);
 unsigned short virtex_readreg(unsigned short theReg);
-
-
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/Makefile linux-2.4.22-pre10/arch/cris/kernel/Makefile
--- linux-2.4.21/arch/cris/kernel/Makefile	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/Makefile	2003-08-01 13:30:44.000000000 +0000
@@ -1,4 +1,3 @@
-# $Id: Makefile,v 1.10 2002/05/27 15:41:40 johana Exp $
 #
 # Makefile for the linux kernel.
 #
@@ -17,21 +16,24 @@
 
 O_TARGET := kernel.o
 
-export-objs := ksyms.o
+export-objs := crisksyms.o
 
 obj-y   := process.o signal.o entry.o traps.o irq.o \
            ptrace.o setup.o time.o sys_cris.o shadows.o \
 	   debugport.o semaphore.o
 
-obj-$(CONFIG_MODULES)    += ksyms.o
+obj-$(CONFIG_MODULES)    += crisksyms.o
 obj-$(CONFIG_ETRAX_KGDB) += kgdb.o
 obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o
+obj-$(CONFIG_ETRAX_DEBUG_INTERRUPT) += debug.o
 
 # This dependency isn't caught by mkdep.  See entry.S.
 entry.o: entryoffsets.s
 
+# We don't want debug info for the dummy entryoffsets functions, and the
+# assembler gets confused when file directives are .if 0:d out.
 entryoffsets.s: entryoffsets.c
-	$(CC) $(CFLAGS) -S -c $<
+	$(CC) $(subst -g,,$(CFLAGS)) -S -c $<
 
 clean:
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/crisksyms.c linux-2.4.22-pre10/arch/cris/kernel/crisksyms.c
--- linux-2.4.21/arch/cris/kernel/crisksyms.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/crisksyms.c	2003-08-01 13:32:23.000000000 +0000
@@ -0,0 +1,104 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/sched.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/smp_lock.h>
+#include <linux/pm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+
+#include <asm/semaphore.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/checksum.h>
+#include <asm/io.h>
+#include <asm/hardirq.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/fasttimer.h>
+
+extern void dump_thread(struct pt_regs *, struct user *);
+extern unsigned long get_cmos_time(void);
+extern void __Div(void);
+extern void __Mod(void);
+extern void __Udiv(void);
+extern void __Umod(void);
+extern void __ashrdi3(void);
+extern void iounmap(void *addr);
+
+/* Platform dependent support */
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(kernel_thread);
+EXPORT_SYMBOL(get_cmos_time);
+EXPORT_SYMBOL(loops_per_usec);
+
+/* String functions */
+EXPORT_SYMBOL(memcmp);
+EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(strtok);
+EXPORT_SYMBOL(strpbrk);
+EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strcpy);
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strncat);
+EXPORT_SYMBOL(strncmp);
+EXPORT_SYMBOL(strncpy);
+
+/* Math functions */
+EXPORT_SYMBOL_NOVERS(__Div);
+EXPORT_SYMBOL_NOVERS(__Mod);
+EXPORT_SYMBOL_NOVERS(__Udiv);
+EXPORT_SYMBOL_NOVERS(__Umod);
+EXPORT_SYMBOL_NOVERS(__ashrdi3);
+
+/* Memory functions */
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+
+/* Semaphore functions */
+EXPORT_SYMBOL(__up);
+EXPORT_SYMBOL(__down);
+EXPORT_SYMBOL(__down_interruptible);
+EXPORT_SYMBOL(__down_trylock);
+
+/* Export shadow registers for the CPU I/O pins */
+EXPORT_SYMBOL(genconfig_shadow);
+EXPORT_SYMBOL(port_pa_data_shadow);
+EXPORT_SYMBOL(port_pa_dir_shadow);
+EXPORT_SYMBOL(port_pb_data_shadow);
+EXPORT_SYMBOL(port_pb_dir_shadow);
+EXPORT_SYMBOL(port_pb_config_shadow);
+EXPORT_SYMBOL(port_g_data_shadow);
+
+/* Userspace access functions */
+EXPORT_SYMBOL(__copy_user_zeroing);
+EXPORT_SYMBOL(__copy_user);
+
+/* Cache flush functions */
+EXPORT_SYMBOL(flush_etrax_cache);
+EXPORT_SYMBOL(prepare_rx_descriptor);
+
+#undef memcpy
+#undef memset
+extern void * memset(void *, int, __kernel_size_t);
+extern void * memcpy(void *, const void *, __kernel_size_t);
+EXPORT_SYMBOL_NOVERS(memcpy);
+EXPORT_SYMBOL_NOVERS(memset);
+
+#ifdef CONFIG_ETRAX_FAST_TIMER
+/* Fast timer functions */
+EXPORT_SYMBOL(fast_timer_list);
+EXPORT_SYMBOL(start_one_shot_timer);
+EXPORT_SYMBOL(del_fast_timer);
+EXPORT_SYMBOL(schedule_usleep);
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/debug.c linux-2.4.22-pre10/arch/cris/kernel/debug.c
--- linux-2.4.21/arch/cris/kernel/debug.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/debug.c	2003-08-01 13:33:22.000000000 +0000
@@ -0,0 +1,213 @@
+/*
+ * arch/cris/kernel/debug.c
+ * Various debug routines:
+ * o Logging of interrupt enabling/disabling. /proc/debug_interrupt
+ *   gives result and toggles if it is enabled or not.
+ *
+ * Copyright (C) 2003 Axis Communications AB
+ */
+
+#include <linux/config.h>
+#include <asm/system.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <asm/svinto.h>
+
+#ifdef CONFIG_ETRAX_DEBUG_INTERRUPT
+#define LOG_INT_SIZE 8192
+#define DEBUG_INT_PROC_FILE "debug_interrupt"
+#define LOG_INT_SHOW_MIN_USEC 45000
+
+/* These are global and can be used to trig certain events. */
+int log_int_pos = 0;
+int log_int_size = LOG_INT_SIZE;
+int log_int_trig0_pos = 0;
+int log_int_trig1_pos = 0;
+
+int log_int_enable = 0; /* toggled every read of /proc/debug_interrupt */
+
+struct log_int_struct 
+{
+  unsigned long pc;
+  unsigned long ev_timer_data;
+};
+
+static struct log_int_struct log_ints[LOG_INT_SIZE];
+
+//static unsigned long prev_log_int_t = 0;
+static unsigned long prev_logged_ccr = 0;
+static unsigned long prev_ei_timer_data = 0;
+static unsigned long prev_di_timer_data = 0;
+
+#define CCR_EI_BIT 5
+enum {
+	INT_OLD_MASK = 0x01, INT_OLD_BIT = 0,
+	INT_NEW_MASK = 0x02, INT_NEW_BIT = 1,
+	INT_EI_CHANGE_MASK = 0x04, INT_EI_CHANGE_BIT = 2,
+	INT_ACTION_RESTORE = 0x08, INT_ACTION_RESTORE_BIT = 3,
+	INT_ACTION_MISSED = 0x10, INT_ACTION_MISSED_BIT = 4,
+	INT_ACTION_LONG = 0x20,  INT_ACTION_LONG_BIT = 5,
+
+	INT_OLD_EI = INT_OLD_MASK, INT_OLD_EI_BIT = INT_OLD_BIT,
+	INT_NEW_EI = INT_NEW_MASK, INT_NEW_EI_BIT = INT_NEW_BIT,
+	INT_EV_DI = INT_OLD_EI | INT_EI_CHANGE_MASK,
+	INT_EV_NOP_DI = 0,
+	INT_EV_EI = INT_NEW_EI | INT_EI_CHANGE_MASK,
+	INT_EV_NOP_EI = INT_OLD_EI | INT_NEW_EI, 
+	INT_EV_RESTORE_DI= INT_EV_DI | INT_EI_CHANGE_MASK | INT_ACTION_RESTORE,
+	INT_EV_RESTORE_EI= INT_EV_EI | INT_EI_CHANGE_MASK | INT_ACTION_RESTORE,
+	INT_EV_RESTORE_NOP_DI = INT_EV_NOP_DI | INT_ACTION_RESTORE,
+	INT_EV_RESTORE_NOP_EI = INT_EV_NOP_EI | INT_ACTION_RESTORE,
+};
+
+void log_int(unsigned long pc, unsigned long curr_ccr, unsigned long next_ccr)
+{
+	unsigned long t;
+	int ev;
+	static int no_change_cnt = 0;
+	
+	/* Just disable interrupts without logging here,
+	 * the caller will either do ei, di or restore
+	 */
+	__asm__ __volatile__ ("di" : : :"memory");
+	t = *R_TIMER_DATA;
+
+	if (curr_ccr & CCR_EI_MASK) {
+		prev_ei_timer_data = t;		
+		ev = INT_OLD_EI;
+	} else {
+		prev_di_timer_data = t;
+		if ( (((prev_ei_timer_data >> 8) & 0x000000FF) -
+		      ((prev_di_timer_data >> 8) & 0x000000FF)) & ~0x03)
+					    ev = INT_ACTION_LONG;
+		else
+			ev = 0;
+	}
+	if ((curr_ccr ^ prev_logged_ccr) & CCR_EI_MASK)
+		ev |= INT_ACTION_MISSED;
+	if (next_ccr & CCR_EI_MASK)
+		ev |= INT_NEW_EI;
+	if ((curr_ccr ^ next_ccr) & CCR_EI_MASK) {
+		ev |= INT_EI_CHANGE_MASK;
+		no_change_cnt = 0;
+	} else
+		no_change_cnt++;
+
+	prev_logged_ccr = next_ccr;
+	
+	if (log_int_enable &&
+	    ((ev & (INT_EI_CHANGE_MASK | INT_ACTION_MISSED | INT_ACTION_LONG))
+	     ||	(no_change_cnt < 40)) &&
+	    log_int_pos < LOG_INT_SIZE) {
+		int i;
+		i = log_int_pos;
+		log_int_pos++;
+		log_ints[i].pc = pc;
+		log_ints[i].ev_timer_data = (t & 0x00FFFFFF) |
+			((ev & 0xFF) << 24);
+
+	}
+//	__asm__ __volatile__ ("move %0,$ccr" : : "rm" (curr_ccr) : "memory");
+}
+void log_int_di(void)
+{
+  unsigned long pc;
+  unsigned long flags;
+  __asm__ __volatile__ ("move $srp,%0" : "=rm" (pc) : : "memory");
+  __asm__ __volatile__ ("move $ccr,%0" : "=rm" (flags) : : "memory");
+  log_int(pc, flags, 0);
+}
+
+void log_int_ei(void)
+{
+  unsigned long pc;
+  unsigned long flags;
+  __asm__ __volatile__ ("move $srp,%0" : "=rm" (pc) : : "memory");
+  __asm__ __volatile__ ("move $ccr,%0" : "=rm" (flags) : : "memory");
+  log_int(pc, flags, CCR_EI_MASK);
+}
+
+
+static int log_int_read_proc(char *page, char **start, off_t off, int count,
+			     int *eof, void *data)
+{
+	int i, len = 0;
+	off_t	begin = 0;	
+	int j, t0, t1, t, thigh, tlow, tdi0;
+	int di0, ei1;
+	len += sprintf(page + len, "trig0: %i trig1: %i\n", log_int_trig0_pos, log_int_trig1_pos);
+	for (i = 0; i < log_int_pos-1; i++) {
+
+		if (((log_ints[i].ev_timer_data >> 24) & INT_NEW_EI)) {
+			di0 = i;
+			while (di0 < log_int_pos-1 && (((log_ints[di0].ev_timer_data >> 24) & INT_NEW_EI)))
+				di0++;
+			ei1 = di0+1;
+			while (ei1 < log_int_pos-1 && (((log_ints[ei1].ev_timer_data >> 24) & INT_NEW_EI) == 0))
+				ei1++;
+			thigh = timer_data_to_ns(log_ints[ei1].ev_timer_data);
+			tlow = timer_data_to_ns(log_ints[di0].ev_timer_data);
+			tdi0 = timer_data_to_ns(log_ints[di0].ev_timer_data);
+			
+			t = thigh-tlow;
+			j = di0-1;		
+			if ((t > LOG_INT_SHOW_MIN_USEC) || (log_int_trig0_pos-30 < j && j < log_int_trig1_pos+30)) {
+
+			for (; j <= ei1; j++) {
+				t0 = ((log_ints[j+1].ev_timer_data & 0xFF) -
+				      (log_ints[j].ev_timer_data & 0xFF));
+				t1 = (((log_ints[j+1].ev_timer_data >> 8) & 0xFF) -
+				      ((log_ints[j].ev_timer_data >> 8) & 0xFF));
+				if (t1 == 0 || t1 == 1) {
+					if (t0 < 0)
+						t0 += 256;
+				} else {
+					if (t1 < 0)
+						t1 += 256;
+				}
+				thigh = timer_data_to_ns(log_ints[j+1].ev_timer_data);
+				tlow = timer_data_to_ns(log_ints[j].ev_timer_data);
+				t = thigh-tlow;
+				len += sprintf(page + len, "%4i PC %08lX-%08lX %08lX-%08lX %s high %i in %-6i ns %-7i to %-7i = %-5i ns, from first di %i ns %s\n",
+					       j, log_ints[j].pc, log_ints[j+1].pc,
+					       log_ints[j].ev_timer_data, log_ints[j+1].ev_timer_data,
+					       ((log_ints[j].ev_timer_data >> 24) & INT_NEW_EI)!= 0?"ei":"di", t1, t,
+					       tlow, thigh, thigh-tlow, thigh-tdi0,
+					       j==log_int_trig0_pos?"TRIG0":(j==log_int_trig1_pos?"TRIG1":""));
+				if (len+begin > off+count)
+					goto done;
+				if (len+begin < off) {
+					begin += len;
+					len = 0;
+				}
+			}
+			
+			len += sprintf(page + len,"\n");
+			i = ei1-2;
+			}
+			
+		}
+	
+	}
+	log_int_enable = 1;
+	log_int_pos = 0;
+	log_int_trig0_pos = 0;
+	log_int_trig1_pos = 0;
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (off-begin);
+	return ((count < begin+len-off) ? count : begin+len-off);	
+}
+
+static int __init
+log_int_init(void)
+{
+	create_proc_read_entry (DEBUG_INT_PROC_FILE, 0, 0, log_int_read_proc, NULL);
+	printk(KERN_INFO "/proc/" DEBUG_INT_PROC_FILE " size %i.\r\n",
+	       LOG_INT_SIZE);
+	return 0;
+}
+module_init(log_int_init);
+#endif /* CONFIG_ETRAX_DEBUG_INTERRUPT */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/debugport.c linux-2.4.22-pre10/arch/cris/kernel/debugport.c
--- linux-2.4.21/arch/cris/kernel/debugport.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/debugport.c	2003-08-01 13:30:43.000000000 +0000
@@ -12,6 +12,17 @@
  *    init_etrax_debug()
  *
  * $Log: debugport.c,v $
+ * Revision 1.9  2003/02/17 07:10:34  starvik
+ * Last merge was incomplete
+ *
+ * Revision 1.8  2003/02/17 06:59:00  starvik
+ * Merged printk corruption fix
+ *
+ * Revision 1.7.4.1  2003/01/27 10:21:57  starvik
+ * Solved the problem with corrupted debug output
+ *  * Wait until DMA, FIFO and pipe is empty before and after transmissions
+ *  * Buffer data until a FIFO flush can be triggered.
+ *
  * Revision 1.7  2002/04/23 15:35:50  bjornw
  * Cleaned up sercons struct and removed the waitkey ptr (2.4.19-pre)
  *
@@ -31,6 +42,7 @@
 #include <linux/console.h>
 #include <linux/init.h>
 #include <linux/major.h>
+#include <linux/delay.h>
 
 #include <asm/system.h>
 #include <asm/svinto.h>
@@ -94,6 +106,8 @@
 #define DEBUG_DMA_IRQ_CLR IO_STATE(R_IRQ_MASK2_CLR, dma4_descr, clr)
 #endif
 
+#define MIN_SIZE 32 /* Size that triggers the FIFO to flush characters to interface */
+
 /* Write a string of count length to the console (debug port) using DMA, polled
  * for completion. Interrupts are disabled during the whole process. Some
  * caution needs to be taken to not interfere with ttyS business on this port.
@@ -103,8 +117,11 @@
 console_write(struct console *co, const char *buf, unsigned int len)
 {
 	static struct etrax_dma_descr descr;
+	static struct etrax_dma_descr descr2;
+	static char tmp_buf[MIN_SIZE];
+	static int tmp_size = 0;
+
 	unsigned long flags; 
-	int in_progress;
 	
 #ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
         /* no debug printout at all */
@@ -126,6 +143,37 @@
 	restore_flags(flags);
 	return;
 #endif
+	/* To make this work together with the real serial port driver
+	 * we have to make sure that everything is flushed when we leave
+	 * here. The following steps are made to assure this:
+	 * 1. Wait until DMA stops, FIFO is empty and serial port pipeline empty.
+	 * 2. Write at least half the FIFO to trigger flush to serial port.
+	 * 3. Wait until DMA stops, FIFO is empty and serial port pipeline empty.
+         */
+
+	/* Do we have enough characters to make the DMA/FIFO happy? */
+	if (tmp_size + len < MIN_SIZE)
+	{
+		int size = min((int)(MIN_SIZE - tmp_size),(int)len);
+		memcpy(&tmp_buf[tmp_size], buf, size);
+		tmp_size += size;
+		len -= size;
+        
+		/* Pad with space if complete line */
+		if (tmp_buf[tmp_size-1] == '\n')
+		{
+			memset(&tmp_buf[tmp_size-1], ' ', MIN_SIZE - tmp_size);
+			tmp_buf[MIN_SIZE - 1] = '\n';
+			tmp_size = MIN_SIZE;
+			len = 0;
+		}
+		else
+		{
+                  /* Wait for more characters */
+			restore_flags(flags);
+			return;
+		}
+	}
 
 	/* make sure the transmitter is enabled. 
 	 * NOTE: this overrides any setting done in ttySx, to 8N1, no auto-CTS.
@@ -134,37 +182,36 @@
 	 */
 
 	*DEBUG_TR_CTRL = 0x40;
+	while(*DEBUG_OCMD & 7); /* Until DMA is not running */
+	while(*DEBUG_STATUS & 0x7f); /* wait until output FIFO is empty as well */
+	udelay(200); /* Wait for last two characters to leave the serial transmitter */
 
-	/* if the tty has some ongoing business, remember it */
-
-	in_progress = *DEBUG_OCMD & 7;
-
-	if(in_progress) {
-		/* wait until the output dma channel is ready */
-		
-		while(*DEBUG_OCMD & 7) /* nothing */ ;
+	if (tmp_size)
+	{
+		descr.ctrl = len ?  0 : d_eop | d_wait | d_eol;
+		descr.sw_len = tmp_size;
+		descr.buf = virt_to_phys(tmp_buf);
+		descr.next = virt_to_phys(&descr2);
+		descr2.ctrl = d_eop | d_wait | d_eol;
+		descr2.sw_len = len;
+		descr2.buf = virt_to_phys((char*)buf);
+	}
+	else
+	{
+		descr.ctrl = d_eop | d_wait | d_eol;
+		descr.sw_len = len;
+		descr.buf = virt_to_phys((char*)buf);
 	}
 
-	descr.ctrl = d_eol;
-	descr.sw_len = len;
-	descr.buf = __pa(buf);
-
-	*DEBUG_FIRST = __pa(&descr); /* write to R_DMAx_FIRST */
+	*DEBUG_FIRST = virt_to_phys(&descr); /* write to R_DMAx_FIRST */
 	*DEBUG_OCMD = 1;       /* dma command start -> R_DMAx_CMD */
 
 	/* wait until the output dma channel is ready again */
+	while(*DEBUG_OCMD & 7);
+	while(*DEBUG_STATUS & 0x7f);
+	udelay(200);
 
-	while(*DEBUG_OCMD & 7) /* nothing */;
-
-	/* clear pending interrupts so we don't get a surprise below */
-
-	if(in_progress)
-		*DEBUG_OCLRINT = 2;  /* only clear EOP, leave DESCR for the tty */
-	else
-		*DEBUG_OCLRINT = 3;  /* clear both EOP and DESCR */
-
-	while(*DEBUG_STATUS & 0x7f); /* wait until output FIFO is empty as well */
-
+	tmp_size = 0;
 	restore_flags(flags);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/entry.S linux-2.4.22-pre10/arch/cris/kernel/entry.S
--- linux-2.4.21/arch/cris/kernel/entry.S	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/entry.S	2003-08-01 13:32:57.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.40 2002/12/02 08:11:41 starvik Exp $
+/* $Id: entry.S,v 1.42 2003/07/07 09:00:50 johana Exp $
  *
  *  linux/arch/cris/entry.S
  *
@@ -7,6 +7,12 @@
  *  Authors:	Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: entry.S,v $
+ *  Revision 1.42  2003/07/07 09:00:50  johana
+ *  Added CONFIG_ETRAX_DEBUG_INTERRUPT support.
+ *
+ *  Revision 1.41  2003/06/17 13:57:50  starvik
+ *  Merge of Linux 2.4.21
+ *
  *  Revision 1.40  2002/12/02 08:11:41  starvik
  *  Merge of Linux 2.4.20
  *
@@ -358,6 +364,12 @@
 	
 _Rexit:
 	;; this epilogue MUST match the prologues in multiple_interrupt, irq.h and ptregs.h
+#ifdef CONFIG_ETRAX_DEBUG_INTERRUPT
+	move.d $pc,$r10
+	move $ccr,$r11
+	move.d	[$sp + LDCCR], $r12; regs->dccr	
+	jsr log_int
+#endif
 	pop	$r10		; frametype
 	bne	_RBFexit	; was not CRIS_FRAME_NORMAL, handle otherwise
 	addq	4, $sp		; skip orig_r10, in delayslot
@@ -449,6 +461,22 @@
 	push	$srp		         ; we keep the old/new PC on the stack 
 	add.d	$r12, $r10		 ; r10 = current tasks tss
 	move	$dccr, [$r10+LTHREAD_DCCR] ; save irq enable state
+#ifdef CONFIG_ETRAX_DEBUG_INTERRUPT
+	push $r9
+	push $r10
+	push $r11
+	push $r12
+	push $r13
+	move.d $pc,$r10
+	move $ccr,$r11
+	clear.d $r12
+	jsr log_int
+	pop $r13
+	pop $r12
+	pop $r11
+	pop $r10
+	pop $r9
+#endif
 	di
 
 	move	$usp, [$r10+LTHREAD_USP] ; save user-mode stackpointer
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/fasttimer.c linux-2.4.22-pre10/arch/cris/kernel/fasttimer.c
--- linux-2.4.21/arch/cris/kernel/fasttimer.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/fasttimer.c	2003-08-01 13:32:22.000000000 +0000
@@ -1,10 +1,16 @@
-/* $Id: fasttimer.c,v 1.5 2002/10/15 06:21:39 starvik Exp $
+/* $Id: fasttimer.c,v 1.7 2003/04/01 14:12:07 starvik Exp $
  * linux/arch/cris/kernel/fasttimer.c
  *
  * Fast timers for ETRAX100/ETRAX100LX
  * This may be useful in other OS than Linux so use 2 space indentation...
  *
  * $Log: fasttimer.c,v $
+ * Revision 1.7  2003/04/01 14:12:07  starvik
+ * Added loglevel for lots of printks
+ *
+ * Revision 1.6  2003/02/10 17:05:44  pkj
+ * Made fast_timer_pending() public.
+ *
  * Revision 1.5  2002/10/15 06:21:39  starvik
  * Added call to init_waitqueue_head
  *
@@ -63,7 +69,7 @@
  * Revision 1.1  2000/10/26 15:49:16  johana
  * Added fasttimer, highresolution timers.
  *
- * Copyright (C) 2000,2001 2002 Axis Communications AB, Lund, Sweden
+ * Copyright (C) 2000,2001,2002,2003 Axis Communications AB, Lund, Sweden
  */
 
 #include <linux/errno.h>
@@ -118,7 +124,7 @@
 static int fast_timer_is_init = 0;
 static int fast_timer_ints = 0;
 
-static struct fast_timer *fast_timer_list = NULL;
+struct fast_timer *fast_timer_list = NULL;
 
 #ifdef DEBUG_LOG_INCLUDED
 #define DEBUG_LOG_MAX 128
@@ -313,7 +319,8 @@
     {
       if (tmp == t)
       {
-        printk("timer name: %s data: 0x%08lX already in list!\n", name, data);
+        printk(KERN_WARNING
+	       "timer name: %s data: 0x%08lX already in list!\n", name, data);
         sanity_failed++;
         return;
       }
@@ -379,11 +386,6 @@
   restore_flags(flags);
 } /* start_one_shot_timer */
 
-static inline int fast_timer_pending (const struct fast_timer * t)
-{
-  return (t->next != NULL) || (t->prev != NULL) || (t == fast_timer_list);
-}
-
 static inline int detach_fast_timer (struct fast_timer *t)
 {
   struct fast_timer *next, *prev;
@@ -770,7 +772,7 @@
       cli();
       if (t->next != nextt)
       {
-        printk("timer removed!\n");
+        printk(KERN_WARNING "timer removed!\n");
       }
       t = nextt;
     }
@@ -951,7 +953,7 @@
     int i;
 #endif
 
-    printk("fast_timer_init()\n");
+    printk(KERN_INFO "fast_timer_init()\n");
 
 #if 0 && defined(FAST_TIMER_TEST)
     for (i = 0; i <= TIMER0_DIV; i++)
@@ -971,7 +973,7 @@
     if(request_irq(TIMER1_IRQ_NBR, timer1_handler, SA_SHIRQ,
                    "fast timer int", NULL))
     {
-      printk("err: timer1 irq\n");
+      printk(KERN_CRIT "err: timer1 irq\n");
     }
     fast_timer_is_init = 1;
 #ifdef FAST_TIMER_TEST
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/head.S linux-2.4.22-pre10/arch/cris/kernel/head.S
--- linux-2.4.21/arch/cris/kernel/head.S	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/head.S	2003-08-01 13:32:45.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.44 2002/02/05 15:39:57 bjornw Exp $
+/* $Id: head.S,v 1.47 2003/07/08 09:53:35 starvik Exp $
  * 
  * Head of the kernel - alter with care
  *
@@ -7,6 +7,15 @@
  * Authors:	Bjorn Wesen (bjornw@axis.com)
  * 
  * $Log: head.S,v $
+ * Revision 1.47  2003/07/08 09:53:35  starvik
+ * Corrected last CVS log entry
+ *
+ * Revision 1.46  2003/05/15 08:07:51  gunnard
+ * Removed serial port DMA when using AGDB.
+ *
+ * Revision 1.45  2003/04/28 05:31:05  starvik
+ * Added section attributes
+ *
  * Revision 1.44  2002/02/05 15:39:57  bjornw
  * Oops.. non-CRAMFS_MAGIC should jump over the copying, not into it...
  *
@@ -311,7 +320,7 @@
 
 	;; Put this in a suitable section where we can reclaim storage
 	;; after init.
-	.section ".text.init"
+	.section ".text.init", "ax"
 _inflash:
 #ifdef CONFIG_ETRAX_ETHERNET	
 	;; Start MII clock to make sure it is running when tranceiver is reset
@@ -543,14 +552,24 @@
 #if (!defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT0)) \
 	&& !defined(CONFIG_DMA_MEMCPY)
 	; DMA channels 6 and 7 to ser0, kgdb doesnt want DMA
+#if (defined(CONFIG_ETRAX_AGDB))
+	; agdb only wants DMA out, no dma in
+	or.d	  IO_STATE (R_GEN_CONFIG, dma6, serial0),$r0
+#else
 	or.d	  IO_STATE (R_GEN_CONFIG, dma7, serial0)	\
 		| IO_STATE (R_GEN_CONFIG, dma6, serial0),$r0
 #endif
+#endif
 #if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT1)
 	; DMA channels 8 and 9 to ser1, kgdb doesnt want DMA
+#if (defined(CONFIG_ETRAX_AGDB))
+	  ; agdb only wants DMA out, no dma in
+	or.d	  IO_STATE (R_GEN_CONFIG, dma8, serial1),$r0
+#else
 	or.d	  IO_STATE (R_GEN_CONFIG, dma9, serial1)	\
 		| IO_STATE (R_GEN_CONFIG, dma8, serial1),$r0
 #endif	
+#endif	
 #ifdef CONFIG_DMA_MEMCPY
 	; 6/7 memory-memory DMA
 	or.d	  IO_STATE (R_GEN_CONFIG, dma7, intdma6)	\
@@ -561,19 +580,29 @@
 	or.w	IO_STATE (R_GEN_CONFIG, ser2, select),$r0
 #if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT2)
 	; DMA channels 2 and 3 to ser2, kgdb doesnt want DMA
+#if (defined(CONFIG_ETRAX_AGDB))
+	; agdb only wants DMA out, no dma in
+	or.d	  IO_STATE (R_GEN_CONFIG, dma2, serial2),$r0
+#else
 	or.d	  IO_STATE (R_GEN_CONFIG, dma3, serial2)	\
 		| IO_STATE (R_GEN_CONFIG, dma2, serial2),$r0
 #endif
 #endif
+#endif
 #if defined(CONFIG_ETRAX_SERIAL_PORT3) || defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
 	; Enable serial port 3
 	or.w	IO_STATE (R_GEN_CONFIG, ser3, select),$r0
 #if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT3)
 	; DMA channels 4 and 5 to ser3, kgdb doesnt want DMA
+#if (defined(CONFIG_ETRAX_AGDB))
+	; agdb only wants DMA out, no dma in
+	or.d	  IO_STATE (R_GEN_CONFIG, dma4, serial3),$r0
+#else
 	or.d	  IO_STATE (R_GEN_CONFIG, dma5, serial3)	\
 		| IO_STATE (R_GEN_CONFIG, dma4, serial3),$r0
 #endif
 #endif
+#endif
 #if defined(CONFIG_ETRAX_PARALLEL_PORT0) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE)
 	; parport 0 enabled using DMA 2/3
 	or.w	IO_STATE (R_GEN_CONFIG, par0, select),$r0
@@ -840,5 +869,5 @@
 swapper_pg_dir = 0xc0002000
 #endif
 
-	.section ".data.init"
+	.section ".data.init", "aw"
 #include "../lib/hw_settings.S"
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/irq.c linux-2.4.22-pre10/arch/cris/kernel/irq.c
--- linux-2.4.21/arch/cris/kernel/irq.c	2002-02-25 19:37:52.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/irq.c	2003-08-01 13:34:49.000000000 +0000
@@ -1,8 +1,7 @@
-/* $Id: irq.c,v 1.18 2001/11/21 13:40:18 bjornw Exp $
- *
+/*
  *	linux/arch/cris/kernel/irq.c
  *
- *      Copyright (c) 2000,2001 Axis Communications AB
+ *      Copyright (c) 2000, 2001, 2002, 2003 Axis Communications AB
  *
  *      Authors: Bjorn Wesen (bjornw@axis.com)
  *
@@ -59,7 +58,7 @@
 disable_irq(unsigned int irq_nr)
 {
 	unsigned long flags;
-	
+
 	save_flags(flags);
 	cli();
 	mask_irq(irq_nr);
@@ -70,6 +69,7 @@
 enable_irq(unsigned int irq_nr)
 {
 	unsigned long flags;
+
 	save_flags(flags);
 	cli();
 	unmask_irq(irq_nr);
@@ -88,7 +88,8 @@
 	return 0;
 }
 
-irqvectptr irq_shortcuts[NR_IRQS]; /* vector of shortcut jumps after the irq prologue */
+/* vector of shortcut jumps after the irq prologue */
+irqvectptr irq_shortcuts[NR_IRQS];
 
 /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is
  * global just so that the kernel gdb can use it.
@@ -104,8 +105,8 @@
 	etrax_irv->v[n + 0x20] = (irqvectptr)addr;
 }
 
-/* the breakpoint vector is obviously not made just like the normal irq handlers
- * but needs to contain _code_ to jump to addr.
+/* the breakpoint vector is obviously not made just like the normal irq
+ * handlers but needs to contain _code_ to jump to addr.
  *
  * the BREAK n instruction jumps to IBR + n * 8
  */
@@ -117,7 +118,7 @@
 	unsigned long *jaddr = (unsigned long *)(jinstr + 1);
 
 	/* if you don't know what this does, do not touch it! */
-	
+
 	*jinstr = 0x0d3f;
 	*jaddr = (unsigned long)addr;
 
@@ -163,18 +164,18 @@
 BUILD_IRQ(25, 0x2000000)
 /* IRQ 26-30 are reserved */
 BUILD_IRQ(31, 0x80000000)
- 
+
 /*
- * Pointers to the low-level handlers 
+ * Pointers to the low-level handlers
  */
 
 static void (*interrupt[NR_IRQS])(void) = {
 	NULL, NULL, IRQ2_interrupt, IRQ3_interrupt,
 	IRQ4_interrupt, IRQ5_interrupt, IRQ6_interrupt, IRQ7_interrupt,
 	IRQ8_interrupt, IRQ9_interrupt, IRQ10_interrupt, IRQ11_interrupt,
-	IRQ12_interrupt, IRQ13_interrupt, NULL, NULL,	
-	IRQ16_interrupt, IRQ17_interrupt, IRQ18_interrupt, IRQ19_interrupt,	
-	IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt,	
+	IRQ12_interrupt, IRQ13_interrupt, NULL, NULL,
+	IRQ16_interrupt, IRQ17_interrupt, IRQ18_interrupt, IRQ19_interrupt,
+	IRQ20_interrupt, IRQ21_interrupt, IRQ22_interrupt, IRQ23_interrupt,
 	IRQ24_interrupt, IRQ25_interrupt, NULL, NULL, NULL, NULL, NULL,
 	IRQ31_interrupt
 };
@@ -183,9 +184,9 @@
 	NULL, NULL, sIRQ2_interrupt, sIRQ3_interrupt,
 	sIRQ4_interrupt, sIRQ5_interrupt, sIRQ6_interrupt, sIRQ7_interrupt,
 	sIRQ8_interrupt, sIRQ9_interrupt, sIRQ10_interrupt, sIRQ11_interrupt,
-	sIRQ12_interrupt, sIRQ13_interrupt, NULL, NULL,	
-	sIRQ16_interrupt, sIRQ17_interrupt, sIRQ18_interrupt, sIRQ19_interrupt,	
-	sIRQ20_interrupt, sIRQ21_interrupt, sIRQ22_interrupt, sIRQ23_interrupt,	
+	sIRQ12_interrupt, sIRQ13_interrupt, NULL, NULL,
+	sIRQ16_interrupt, sIRQ17_interrupt, sIRQ18_interrupt, sIRQ19_interrupt,
+	sIRQ20_interrupt, sIRQ21_interrupt, sIRQ22_interrupt, sIRQ23_interrupt,
 	sIRQ24_interrupt, sIRQ25_interrupt, NULL, NULL, NULL, NULL, NULL,
 	sIRQ31_interrupt
 };
@@ -230,7 +231,7 @@
 
 	for (i = 0; i < NR_IRQS; i++) {
 		action = irq_action[i];
-		if (!action) 
+		if (!action)
 			continue;
 		len += sprintf(buf+len, "%2d: %10u %c %s",
 			i, kstat.irqs[0][i],
@@ -286,9 +287,9 @@
 }
 
 /* this function links in a handler into the chain of handlers for the
-   given irq, and if the irq has never been registred, the appropriate
-   handler is entered into the interrupt vector
-*/
+ * given irq, and if the irq has never been registred, the appropriate
+ * handler is entered into the interrupt vector
+ */
 
 int setup_etrax_irq(int irq, struct irqaction * new)
 {
@@ -322,37 +323,39 @@
 	*p = new;
 
 	if (!shared) {
-		/* if the irq wasn't registred before, enter it into the vector table
-		   and unmask it physically 
-		*/
+		/* if the irq wasn't registred before, enter it into the vector
+		 * table and unmask it physically
+		 */
 		set_int_vector(irq, interrupt[irq], sinterrupt[irq]);
 		unmask_irq(irq);
 	}
-	
+
 	restore_flags(flags);
 	return 0;
 }
 
 /* this function is called by a driver to register an irq handler
-   Valid flags:
-   SA_INTERRUPT -> it's a fast interrupt, handler called with irq disabled and
-                   no signal checking etc is performed upon exit
-   SA_SHIRQ -> the interrupt can be shared between different handlers, the handler
-                is required to check if the irq was "aimed" at it explicitely
-   SA_RANDOM -> the interrupt will add to the random generators entropy
-*/
+ * Valid flags:
+ *   SA_INTERRUPT: it's a fast interrupt, handler called with irq disabled and
+ *                 no signal checking etc is performed upon exit
+ *   SA_SHIRQ:     the interrupt can be shared between different handlers, the
+ *                 handler is required to check if the irq was "aimed" at it
+ *                 explicitely
+ *   SA_RANDOM:    the interrupt will add to the random generators entropy
+ */
 
-int request_irq(unsigned int irq, 
+int request_irq(unsigned int irq,
 		void (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
+		unsigned long irqflags,
 		const char * devname,
 		void *dev_id)
 {
 	int retval;
 	struct irqaction * action;
 
-	/* interrupts 0 and 1 are hardware breakpoint and NMI and we can't support
-	   these yet. interrupt 15 is the multiple irq, it's special. */
+	/* interrupts 0 and 1 are hardware breakpoint and NMI and we can't
+	 * support these yet. interrupt 15 is the multiple irq, it's special.
+	 */
 
 	if(irq < 2 || irq == 15 || irq >= NR_IRQS)
 		return -EINVAL;
@@ -362,7 +365,7 @@
 
 	/* allocate and fill in a handler structure and setup the irq */
 
-	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	action = kmalloc(sizeof *action, GFP_KERNEL);
 	if (!action)
 		return -ENOMEM;
 
@@ -379,7 +382,7 @@
 		kfree(action);
 	return retval;
 }
-		
+
 void free_irq(unsigned int irq, void *dev_id)
 {
 	struct irqaction * action, **p;
@@ -415,9 +418,9 @@
 	while(1);
 }
 
-/* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and
-   setting the irq vector table to point to bad_interrupt ptrs.
-*/
+/* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks
+ * and setting the irq vector table to point to bad_interrupt ptrs.
+ */
 
 void system_call(void);  /* from entry.S */
 void do_sigtrap(void); /* from entry.S */
@@ -442,26 +445,27 @@
 
 	for(i = 0; i < NR_IRQS; i++)
 		irq_shortcuts[i] = NULL;
-        
-        for (i = 0; i < 256; i++)
-               etrax_irv->v[i] = weird_irq;
-
-        /* the entries in the break vector contain actual code to be
-           executed by the associated break handler, rather than just a jump
-           address. therefore we need to setup a default breakpoint handler
-           for all breakpoints */
+
+	for (i = 0; i < 256; i++)
+		etrax_irv->v[i] = weird_irq;
+
+	/* the entries in the break vector contain actual code to be
+	 * executed by the associated break handler, rather than just a jump
+	 * address. therefore we need to setup a default breakpoint handler
+	 * for all breakpoints
+	 */
 
 	for (i = 0; i < 16; i++)
-                set_break_vector(i, do_sigtrap);
-        
+		set_break_vector(i, do_sigtrap);
+
 	/* set all etrax irq's to the bad handlers */
 	for (i = 2; i < NR_IRQS; i++)
 		set_int_vector(i, bad_interrupt[i], 0);
-        
+
 	/* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */
 
 	set_int_vector(15, multiple_interrupt, 0);
-	
+
 	/* 0 and 1 which are special breakpoint/NMI traps */
 
 	set_int_vector(0, hwbreakpoint, 0);
@@ -475,17 +479,17 @@
 
 	set_break_vector(13, system_call);
 
-        /* setup a breakpoint handler for debugging used for both user and
-           kernel mode debugging  (which is why it is not inside an ifdef
-           CONFIG_ETRAX_KGDB) */
-        set_break_vector(8, gdb_handle_breakpoint);
+	/* setup a breakpoint handler for debugging used for both user and
+	 * kernel mode debugging  (which is why it is not inside an ifdef
+	 * CONFIG_ETRAX_KGDB)
+	 */
+	set_break_vector(8, gdb_handle_breakpoint);
 
 #ifdef CONFIG_ETRAX_KGDB
 	/* setup kgdb if its enabled, and break into the debugger */
 	kgdb_init();
 	breakpoint();
 #endif
-
 }
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/kgdb.c linux-2.4.22-pre10/arch/cris/kernel/kgdb.c
--- linux-2.4.21/arch/cris/kernel/kgdb.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/kgdb.c	2003-08-01 13:34:33.000000000 +0000
@@ -18,6 +18,9 @@
 *! Jul 21 1999  Bjorn Wesen     eLinux port
 *!
 *! $Log: kgdb.c,v $
+*! Revision 1.8  2003/04/09 08:31:15  pkj
+*! Typo correction (taken from Linux 2.5).
+*!
 *! Revision 1.7  2002/07/12 09:14:56  bjornw
 *! Corrected typo
 *!
@@ -58,7 +61,7 @@
 *!
 *!---------------------------------------------------------------------------
 *!
-*! $Id: kgdb.c,v 1.7 2002/07/12 09:14:56 bjornw Exp $
+*! $Id: kgdb.c,v 1.8 2003/04/09 08:31:15 pkj Exp $
 *!
 *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN
 *!
@@ -152,7 +155,7 @@
  *    (IPL too high, disabled, ...)
  *
  *  - The gdb stub is currently not reentrant, i.e. errors that happen therein
- *    (e.g. accesing invalid memory) may not be caught correctly. This could
+ *    (e.g. accessing invalid memory) may not be caught correctly. This could
  *    be removed in future by introducing a stack of struct registers.
  *
  */
@@ -1486,7 +1489,7 @@
   move.d   $r0,[reg+0x62]   ; Save the return address in BRP
   move     $usp,[reg+0x66]  ; USP
 
-;; get the serial character (from debugport.c) and check if its a ctrl-c
+;; get the serial character (from debugport.c) and check if it is a ctrl-c
 
   jsr getDebugChar
   cmp.b 3, $r10
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/process.c linux-2.4.22-pre10/arch/cris/kernel/process.c
--- linux-2.4.21/arch/cris/kernel/process.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/process.c	2003-08-01 13:33:49.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.23 2002/10/14 18:29:27 johana Exp $
+/* $Id: process.c,v 1.24 2003/03/06 14:19:32 pkj Exp $
  * 
  *  linux/arch/cris/kernel/process.c
  *
@@ -8,6 +8,9 @@
  *  Authors:   Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: process.c,v $
+ *  Revision 1.24  2003/03/06 14:19:32  pkj
+ *  Use a cpu_idle() function identical to the one used by i386.
+ *
  *  Revision 1.23  2002/10/14 18:29:27  johana
  *  Call etrax_gpio_wake_up_check() from cpu_idle() to reduce gpio latency
  *  from ~15 ms to ~6 ms.
@@ -114,7 +117,17 @@
  * region by enable_hlt/disable_hlt.
  */
 
-static int hlt_counter=0;
+static int hlt_counter;
+
+/*
+ * Powermanagement idle function, if any..
+ */
+void (*pm_idle)(void);
+
+/*
+ * Power off function, if any
+ */
+void (*pm_power_off)(void);
 
 void disable_hlt(void)
 {
@@ -125,19 +138,42 @@
 {
 	hlt_counter--;
 }
-#ifdef CONFIG_ETRAX_GPIO
-void etrax_gpio_wake_up_check(void); /* drivers/gpio.c */
-#endif
 
-int cpu_idle(void *unused)
+/*
+ * We use this if we don't have any better
+ * idle routine..
+ */
+static void default_idle(void)
 {
-	while(1) {
-		current->counter = -100;
 #ifdef CONFIG_ETRAX_GPIO
-		/* This can reduce latency from 15 ms to 6 ms */
-		etrax_gpio_wake_up_check(); /* drivers/gpio.c */
+	extern void etrax_gpio_wake_up_check(void); /* drivers/gpio.c */
+
+	/* This can reduce latency from 15 ms to 6 ms */
+	etrax_gpio_wake_up_check(); /* drivers/gpio.c */
 #endif
+}
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle(void)
+{
+	/* endless idle loop with no priority at all */
+	init_idle();
+	current->nice = 20;
+	current->counter = -100;
+
+	while(1) {
+		void (*idle)(void) = pm_idle;
+		if (!idle)
+			idle = default_idle;
+		while (!current->need_resched)
+			idle();
 		schedule();
+		check_pgt_cache();
 	}
 }
 
@@ -191,6 +227,8 @@
 
 void machine_power_off(void)
 {
+	if (pm_power_off)
+		pm_power_off();
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/setup.c linux-2.4.22-pre10/arch/cris/kernel/setup.c
--- linux-2.4.21/arch/cris/kernel/setup.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/setup.c	2003-08-01 13:34:30.000000000 +0000
@@ -1,9 +1,8 @@
-/* $Id: setup.c,v 1.27 2002/10/11 12:57:15 pkj Exp $
- *
+/*
  *  linux/arch/cris/kernel/setup.c
  *
  *  Copyright (C) 1995  Linus Torvalds
- *  Copyright (c) 2001  Axis Communications AB
+ *  Copyright (c) 2001, 2002, 2003  Axis Communications AB
  */
 
 /*
@@ -94,7 +93,8 @@
 		memory_start = (unsigned long) &_end;
 	} else {
 		/* otherwise the free area starts after the ROM filesystem */
-		printk("ROM fs in RAM, size %lu bytes\n", romfs_length);
+		printk(KERN_INFO "ROM fs in RAM, size %lu bytes\n",
+		       romfs_length);
 		memory_start = romfs_start + romfs_length;
 	}
 
@@ -169,9 +169,14 @@
 
 	*cmdline_p = command_line;
 
+#ifdef CONFIG_ETRAX_CMDLINE
+	strncpy(command_line, CONFIG_ETRAX_CMDLINE, COMMAND_LINE_SIZE);
+#elif defined(CONFIG_ETRAX_ROOT_DEVICE)
 	strncpy(command_line, "root=", COMMAND_LINE_SIZE);
 	strncpy(command_line+5, CONFIG_ETRAX_ROOT_DEVICE,
 			COMMAND_LINE_SIZE-5);
+#endif
+	command_line[COMMAND_LINE_SIZE - 1] = '\0';
 
 	/* Save command line copy for /proc/cmdline */
 	
@@ -180,7 +185,7 @@
 
 	/* give credit for the CRIS port */
 
-	printk("Linux/CRIS port on ETRAX 100LX (c) 2001, 2002 Axis Communications AB\n");
+	printk(KERN_INFO "Linux/CRIS port on ETRAX 100LX (c) 2001, 2002 Axis Communications AB\n");
 
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/shadows.c linux-2.4.22-pre10/arch/cris/kernel/shadows.c
--- linux-2.4.21/arch/cris/kernel/shadows.c	2001-05-01 23:04:56.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/shadows.c	2003-08-01 13:34:43.000000000 +0000
@@ -1,6 +1,5 @@
-/* $Id: shadows.c,v 1.2 2001/03/15 14:25:16 bjornw Exp $
- * 
- * Various shadow registers. Defines for these are in include/asm-etrax100/io.h
+/*
+ * Various shadow registers. Defines for these are in include/asm-cris/io.h
  */
 
 /* Shadows for internal Etrax-registers */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/signal.c linux-2.4.22-pre10/arch/cris/kernel/signal.c
--- linux-2.4.21/arch/cris/kernel/signal.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/signal.c	2003-08-01 13:30:53.000000000 +0000
@@ -528,7 +528,7 @@
 			case -ERESTARTNOHAND:
 				/* ERESTARTNOHAND means that the syscall should only be
 				   restarted if there was no handler for the signal, and since
-				   we only get here if there is a handler, we dont restart */
+				   we only get here if there is a handler, we don't restart */
 				regs->r10 = -EINTR;
 				break;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/sys_cris.c linux-2.4.22-pre10/arch/cris/kernel/sys_cris.c
--- linux-2.4.21/arch/cris/kernel/sys_cris.c	2001-07-26 22:10:06.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/sys_cris.c	2003-08-01 13:30:40.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: sys_cris.c,v 1.10 2001/06/27 21:16:15 hp Exp $
- *
+/*
  * linux/arch/cris/kernel/sys_cris.c
  *
  * This file contains various random system calls that
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/time.c linux-2.4.22-pre10/arch/cris/kernel/time.c
--- linux-2.4.21/arch/cris/kernel/time.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/time.c	2003-08-01 13:33:35.000000000 +0000
@@ -1,9 +1,8 @@
-/* $Id: time.c,v 1.17 2002/11/15 14:49:24 oskarp Exp $
- *
+/*
  *  linux/arch/cris/kernel/time.c
  *
  *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
- *  Copyright (C) 1999, 2000, 2001, 2002 Axis Communications AB
+ *  Copyright (C) 1999, 2000, 2001, 2002, 2003 Axis Communications AB
  *
  * 1994-07-02    Alan Modra
  *	fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
@@ -18,15 +17,16 @@
  * Linux/CRIS specific code:
  *
  * Authors:    Bjorn Wesen
- *             Johan Adolfsson  
+ *             Johan Adolfsson
+ *
  * 2002-03-04    Johan Adolfsson
- *      Use prescale timer at 25000 Hz instead of the baudrate timer at 
- *      19200 to get rid of the 64ppm to fast timer (and we get better 
+ *      Use prescale timer at 25000 Hz instead of the baudrate timer at
+ *      19200 to get rid of the 64ppm to fast timer (and we get better
  *      resolution within a jiffie as well.
  * 2002-03-05    Johan Adolfsson
  *      Use prescaler in do_slow_gettimeoffset() to get 1 us resolution (40ns)
  * 2002-09-06    Johan Adolfsson
- *      Handle lost ticks by checking wall_jiffies, more efficient code 
+ *      Handle lost ticks by checking wall_jiffies, more efficient code
  *      by using local vars and not the pointer argument.
  *
  */
@@ -103,6 +103,60 @@
 }
 
 
+/* Convert the clkdiv_low and clkdivb_high fiels in timer_data
+ * (from *R_TIMER_DATA) to nanoseconds (67 ns resolution)
+ */
+unsigned long timer_data_to_ns(unsigned long timer_data) 
+{
+/* low (clkdiv_low lsb toggles with 7.3728MHz so it counts
+ * with 14.7456 MHz = 67.816 ns (0-17361ns)
+ * high (clkdiv_high lsb toggles with 38.4kHz so it counts
+ * with 76.8kHz = 13020.833 ns (0-3333333 ns)
+ * By checking bit 9,8,7 we can now how to compensate the low value
+ * to get a 67 ns resolution all the way.
+Example of R_TIMER_DATA values:
+     bit 98 7   low      9 87     offset
+0289DC00 00 000 0        0 00       0
+0289DC41 00 010 64       0 01       0
+0289DC81 00 100 128      0 10       0
+0289DDC0 01 110 192      1 11       0        13020 = 192        
+0289DD01 01 000 0    256 1 00     +256    
+0289DD41 01 010 64   320 1 01     +256        
+
+0288DE80 10 100 128  384 0 10  0: -128             26040= 384  
+0288DEC1 10 110 192  448 0 11  64 -128            
+0288DE01 10 000 0    512      128 +128    
+0288DF40 11 010 64   576      192 +128             39060 
+0288DF81 11 100 128  640      256 +128   
+0288DFC1 11 110 192  704      320 +128
+                              ..393		 
+*/
+	
+	static const short timer_data_add[8] = {
+		0,   /* 00 0 */
+		0,   /* 00 1 */
+		256, /* 01 0 */
+		0,   /* 01 1 */
+		128, /* 10 0 */
+		-128,/* 10 1 */
+		128, /* 11 0 */
+		128  /* 11 1 */
+	};  
+	unsigned long ns;
+	unsigned long low;
+	unsigned long high;
+  
+	high = (((timer_data & 0x0000FE00)>>8) * 13020833)/1000;
+	ns = high;
+  
+	low = timer_data & 0xFF;
+	low += timer_data_add[(timer_data >>7) & 0x7];
+	ns += (low * 67816)/1000;
+	return ns;
+} /* timer_data_to_ns */
+
+
+
 
 #if CRIS_TEST_TIMERS 
 #define NS_TEST_SIZE 4000
@@ -274,7 +328,7 @@
 	int retval = 0;
 	int real_seconds, real_minutes, cmos_minutes;
 
-	printk("set_rtc_mmss(%lu)\n", nowtime);
+	printk(KERN_INFO "set_rtc_mmss(%lu)\n", nowtime);
 
 	if(!have_rtc)
 		return 0;
@@ -460,7 +514,8 @@
 	mon = CMOS_READ(RTC_MONTH);
 	year = CMOS_READ(RTC_YEAR);
 
-	printk("rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n", 
+	printk(KERN_INFO
+	       "rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n", 
 	       sec, min, hour, day, mon, year);
 
 	BCD_TO_BIN(sec);
@@ -585,7 +640,7 @@
 	/* enable watchdog if we should use one */
 
 #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
-	printk("Enabling watchdog...\n");
+	printk(KERN_INFO "Enabling watchdog...\n");
 	start_watchdog();
 
 	/* If we use the hardware watchdog, we want to trap it as an NMI
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/kernel/traps.c linux-2.4.22-pre10/arch/cris/kernel/traps.c
--- linux-2.4.21/arch/cris/kernel/traps.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/kernel/traps.c	2003-08-01 13:34:27.000000000 +0000
@@ -1,12 +1,11 @@
-/* $Id: traps.c,v 1.18 2002/12/02 08:11:41 starvik Exp $
- *
+/*
  *  linux/arch/cris/traps.c
  *
- *  Here we handle the break vectors not used by the system call 
- *  mechanism, as well as some general stack/register dumping 
+ *  Here we handle the break vectors not used by the system call
+ *  mechanism, as well as some general stack/register dumping
  *  things.
- * 
- *  Copyright (C) 2000,2001 Axis Communications AB
+ *
+ *  Copyright (C) 2000, 2001, 2002, 2003 Axis Communications AB
  *
  *  Authors:   Bjorn Wesen
  *  	       Hans-Peter Nilsson
@@ -216,6 +215,8 @@
  * we have the nice doggy development flag set, we halt here
  * instead of rebooting.
  */
+extern void reset_watchdog(void);
+extern void stop_watchdog(void);
 
 void
 watchdog_bite_hook(struct pt_regs *regs)
@@ -239,9 +240,6 @@
 void 
 die_if_kernel(const char * str, struct pt_regs * regs, long err)
 {
-	extern void reset_watchdog(void);
-	extern void stop_watchdog(void);
-
 	if(user_mode(regs))
 		return;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/lib/checksum.S linux-2.4.22-pre10/arch/cris/lib/checksum.S
--- linux-2.4.21/arch/cris/lib/checksum.S	2001-10-08 18:43:54.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/lib/checksum.S	2003-08-01 13:34:42.000000000 +0000
@@ -1,6 +1,6 @@
-/* $Id: checksum.S,v 1.6 2001/10/01 14:47:35 bjornw Exp $
+/*
  * A fast checksum routine using movem
- * Copyright (c) 1998-2001 Axis Communications AB
+ * Copyright (c) 1998-2003 Axis Communications AB
  *
  * csum_partial(const unsigned char * buff, int len, unsigned int sum)
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/lib/checksumcopy.S linux-2.4.22-pre10/arch/cris/lib/checksumcopy.S
--- linux-2.4.21/arch/cris/lib/checksumcopy.S	2001-10-08 18:43:54.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/lib/checksumcopy.S	2003-08-01 13:32:51.000000000 +0000
@@ -1,9 +1,9 @@
-/* $Id: checksumcopy.S,v 1.7 2001/10/01 14:47:35 bjornw Exp $
+/*
  * A fast checksum+copy routine using movem
- * Copyright (c) 1998, 2001 Axis Communications AB
+ * Copyright (c) 1998-2003 Axis Communications AB
  *
  * Authors:	Bjorn Wesen
- * 
+ *
  * csum_partial_copy_nocheck(const char *src, char *dst,
  *		             int len, unsigned int sum)
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/lib/dmacopy.c linux-2.4.22-pre10/arch/cris/lib/dmacopy.c
--- linux-2.4.21/arch/cris/lib/dmacopy.c	2001-02-09 00:32:44.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/lib/dmacopy.c	2003-08-01 13:32:01.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: dmacopy.c,v 1.1 2000/07/10 16:25:21 bjornw Exp $ 
- *
+/*
  * memcpy for large blocks, using memory-memory DMA channels 6 and 7 in Etrax
  */
 
@@ -13,11 +12,11 @@
 		 unsigned int pn)
 {
 	static etrax_dma_descr indma, outdma;
-	
+
 	D(printk("dma_memcpy %d bytes... ", pn));
 
 #if 0
-	*R_GEN_CONFIG = genconfig_shadow = 
+	*R_GEN_CONFIG = genconfig_shadow =
 		(genconfig_shadow & ~0x3c0000) |
 		IO_STATE(R_GEN_CONFIG, dma6, intdma7) |
 		IO_STATE(R_GEN_CONFIG, dma7, intdma6);
@@ -32,12 +31,9 @@
 	*R_DMA_CH7_FIRST = &outdma;
 	*R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, start);
 	*R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, start);
-	
+
 	while(*R_DMA_CH7_CMD == 1) /* wait for completion */ ;
 
 	D(printk("done\n"));
 
 }
-
-
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/lib/dram_init.S linux-2.4.22-pre10/arch/cris/lib/dram_init.S
--- linux-2.4.21/arch/cris/lib/dram_init.S	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/lib/dram_init.S	2003-08-01 13:34:26.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: dram_init.S,v 1.13 2002/10/30 07:42:28 starvik Exp $
+/* $Id: dram_init.S,v 1.14 2003/03/31 07:07:08 starvik Exp $
  * 
  * DRAM/SDRAM initialization - alter with care
  * This file is intended to be included from other assembler files
@@ -11,6 +11,9 @@
  * Authors:  Mikael Starvik (starvik@axis.com)	
  * 
  * $Log: dram_init.S,v $
+ * Revision 1.14  2003/03/31 07:07:08  starvik
+ * Corrected calculation of end of sdram init commands
+ *
  * Revision 1.13  2002/10/30 07:42:28  starvik
  * Always read SDRAM command sequence from flash
  *
@@ -148,7 +151,7 @@
 	move.d   _sdram_commands_start, $r2
 	and.d    0x00ffffff, $r2 ; Make sure commands are read from flash
 	move.d   _sdram_commands_end,  $r3
-	and.d    0x00ffffff, $r2
+	and.d    0x00ffffff, $r3
 1:	clear.d  $r4
 	move.b   [$r2+], $r4
 	lslq     9, $r4	; Command starts at bit 9
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/lib/hw_settings.S linux-2.4.22-pre10/arch/cris/lib/hw_settings.S
--- linux-2.4.21/arch/cris/lib/hw_settings.S	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/lib/hw_settings.S	2003-08-01 13:33:08.000000000 +0000
@@ -1,13 +1,11 @@
 /*
- * $Id: hw_settings.S,v 1.5 2002/08/15 09:16:06 bjornw Exp $
- * 
  * This table is used by some tools to extract hardware parameters.
  * The table should be included in the kernel and the decompressor.
  * Don't forget to update the tools if you change this table.
  *
- * Copyright (C) 2001, 2002 Axis Communications AB
+ * Copyright (C) 2001, 2002, 2003 Axis Communications AB
  *
- * Authors:  Mikael Starvik (starvik@axis.com)	
+ * Authors:  Mikael Starvik (starvik@axis.com)
  */
 
 #define PA_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PA_DIR << 8) | \
@@ -15,13 +13,13 @@
 #define PB_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG << 16) | \
 		(CONFIG_ETRAX_DEF_R_PORT_PB_DIR << 8) | \
 		(CONFIG_ETRAX_DEF_R_PORT_PB_DATA))
-	
+
 	.ascii "HW_PARAM_MAGIC"	; Magic number
 	.dword 0xc0004000	; Where to load the kernel image (physical!)
 
 	; Debug port
 #ifdef CONFIG_ETRAX_DEBUG_PORT0
-	.dword 0		
+	.dword 0
 #elif defined(CONFIG_ETRAX_DEBUG_PORT1)
 	.dword 1
 #elif defined(CONFIG_ETRAX_DEBUG_PORT2)
@@ -30,7 +28,7 @@
 	.dword 3
 #else
 	.dword 4 ; No debug
-#endif			
+#endif
 
 	; SDRAM or EDO DRAM?
 #ifdef CONFIG_ETRAX_SDRAM
@@ -39,7 +37,7 @@
 	.dword 0
 #endif
 
-	; Register values 
+	; Register values
 	.dword R_WAITSTATES
 	.dword CONFIG_ETRAX_DEF_R_WAITSTATES
 	.dword R_BUS_CONFIG
@@ -56,7 +54,7 @@
 	.dword CONFIG_ETRAX_DEF_R_DRAM_TIMING
 #endif
 	.dword R_PORT_PA_SET
-	.dword PA_SET_VALUE 
+	.dword PA_SET_VALUE
 	.dword R_PORT_PB_SET
 	.dword PB_SET_VALUE
 	.dword 0 ; No more register values
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/lib/old_checksum.c linux-2.4.22-pre10/arch/cris/lib/old_checksum.c
--- linux-2.4.21/arch/cris/lib/old_checksum.c	2001-02-09 00:32:44.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/lib/old_checksum.c	2003-08-01 13:32:01.000000000 +0000
@@ -1,5 +1,4 @@
-/* $Id: old_checksum.c,v 1.1 2000/07/10 16:25:21 bjornw Exp $
- *
+/*
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
  *		interface as the means of communication with the user level.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/mm/fault.c linux-2.4.22-pre10/arch/cris/mm/fault.c
--- linux-2.4.21/arch/cris/mm/fault.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/mm/fault.c	2003-08-01 13:32:23.000000000 +0000
@@ -6,6 +6,10 @@
  *  Authors:  Bjorn Wesen 
  * 
  *  $Log: fault.c,v $
+ *  Revision 1.22  2003/07/07 09:07:04  johana
+ *  Added special CONFIG_ETRAX_DEBUG_INTERRUPT handling here
+ *  to deal with a di in entry.S
+ *
  *  Revision 1.21  2002/05/28 14:24:56  bjornw
  *  Corrected typo
  *
@@ -68,6 +72,7 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -126,6 +131,9 @@
 	int errcode;
 	unsigned long address;
 
+#ifdef CONFIG_ETRAX_DEBUG_INTERRUPT /* The di is actually in entry.S */
+	log_int(rdpc(), regs->dccr, 0);
+#endif
 	cause = *R_MMU_CAUSE;
 	select = *R_TLB_SELECT;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/mm/init.c linux-2.4.22-pre10/arch/cris/mm/init.c
--- linux-2.4.21/arch/cris/mm/init.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/mm/init.c	2003-08-01 13:33:10.000000000 +0000
@@ -7,6 +7,15 @@
  *  Authors:  Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: init.c,v $
+ *  Revision 1.38  2003/04/01 14:12:08  starvik
+ *  Added loglevel for lots of printks
+ *
+ *  Revision 1.37  2003/01/22 06:54:47  starvik
+ *  Fixed warnings issued by GCC 3.2.1
+ *
+ *  Revision 1.36  2003/01/09 17:59:55  starvik
+ *  Added init_ioremap to initcalls
+ *
  *  Revision 1.35  2002/05/17 05:33:59  starvik
  *  Limit cache flush range to the size of the cache
  *
@@ -113,6 +122,7 @@
 #include <linux/swap.h>
 #include <linux/smp.h>
 #include <linux/bootmem.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/segment.h>
@@ -208,7 +218,7 @@
 	int i;
 	unsigned long zones_size[MAX_NR_ZONES];
 
-	printk("Setting up paging and the MMU.\n");
+	printk(KERN_INFO "Setting up paging and the MMU.\n");
 	
 	/* clear out the init_mm.pgd that will contain the kernel's mappings */
 
@@ -404,7 +414,8 @@
         datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 	
-        printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, "
+        printk(KERN_INFO
+	       "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, "
 	       "%dk init)\n" ,
 	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
 	       max_mapnr << (PAGE_SHIFT-10),
@@ -425,47 +436,40 @@
 	return;
 }
 
-/* Initialize remaps of some I/O-ports. This is designed to be callable
- * multiple times from the drivers init-sections, because we don't know
- * beforehand which driver will get initialized first.
+/* Initialize remaps of some I/O-ports. It is important that this
+ * is called before any driver is initialized.
  */
 
-void 
-init_ioremap(void)
+static int 
+__init init_ioremap(void)
 {
   
 	/* Give the external I/O-port addresses their values */
 
-        static int initialized = 0;
-  
-        if( !initialized ) {
-                initialized++;
-            
 #ifdef CONFIG_CRIS_LOW_MAP
-               /* Simply a linear map (see the KSEG map above in paging_init) */
-               port_cse1_addr = (volatile unsigned long *)(MEM_CSE1_START | 
-                                                           MEM_NON_CACHEABLE);
-               port_csp0_addr = (volatile unsigned long *)(MEM_CSP0_START |
-                                                           MEM_NON_CACHEABLE);
-               port_csp4_addr = (volatile unsigned long *)(MEM_CSP4_START |
-                                                           MEM_NON_CACHEABLE);
-#else
-               /* Note that nothing blows up just because we do this remapping 
-                * it's ok even if the ports are not used or connected 
-                * to anything (or connected to a non-I/O thing) */        
-               port_cse1_addr = (volatile unsigned long *)
-                 ioremap((unsigned long)(MEM_CSE1_START | 
-                                         MEM_NON_CACHEABLE), 16);
-               port_csp0_addr = (volatile unsigned long *)
-                 ioremap((unsigned long)(MEM_CSP0_START |
-                                         MEM_NON_CACHEABLE), 16);
-               port_csp4_addr = (volatile unsigned long *)
-                 ioremap((unsigned long)(MEM_CSP4_START |
-                                         MEM_NON_CACHEABLE), 16);
-#endif	
-        }
+	/* Simply a linear map (see the KSEG map above in paging_init) */
+	port_cse1_addr = (volatile unsigned long *)(MEM_CSE1_START |
+	                                            MEM_NON_CACHEABLE);
+	port_csp0_addr = (volatile unsigned long *)(MEM_CSP0_START |
+	                                            MEM_NON_CACHEABLE);
+	port_csp4_addr = (volatile unsigned long *)(MEM_CSP4_START |
+	                                            MEM_NON_CACHEABLE);
+#else						    
+	/* Note that nothing blows up just because we do this remapping 
+	 * it's ok even if the ports are not used or connected 
+	 * to anything (or connected to a non-I/O thing) */        
+	port_cse1_addr = (volatile unsigned long *)
+	ioremap((unsigned long)(MEM_CSE1_START | MEM_NON_CACHEABLE), 16);
+	port_csp0_addr = (volatile unsigned long *)
+	ioremap((unsigned long)(MEM_CSP0_START | MEM_NON_CACHEABLE), 16);
+	port_csp4_addr = (volatile unsigned long *)
+	ioremap((unsigned long)(MEM_CSP4_START | MEM_NON_CACHEABLE), 16);
+#endif
+	return 0;
 }
 
+__initcall(init_ioremap);
+
 /* Helper function for the two below */
 
 static inline void
@@ -481,7 +485,7 @@
 	length = length > 8192 ? 8192 : length;  /* No need to flush more than cache size */
 
 	while(length > 0) {
-		short tmp = *flushadr;           /* dummy read to flush */
+		*flushadr; /* dummy read to flush */
 		flushadr += (32/sizeof(short));  /* a cacheline is 32 bytes */
 		length -= 32;
 	}
@@ -524,7 +528,7 @@
                 totalram_pages++;
         }
         printk (KERN_INFO "Freeing unused kernel memory: %luk freed\n", 
-		(&__init_end - &__init_begin) >> 10);
+		(unsigned long)((&__init_end - &__init_begin) >> 10));
 }
 
 void 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/cris/mm/ioremap.c linux-2.4.22-pre10/arch/cris/mm/ioremap.c
--- linux-2.4.21/arch/cris/mm/ioremap.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/cris/mm/ioremap.c	2003-08-01 13:31:08.000000000 +0000
@@ -146,7 +146,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.21/arch/i386/boot/bootsect.S linux-2.4.22-pre10/arch/i386/boot/bootsect.S
--- linux-2.4.21/arch/i386/boot/bootsect.S	2001-11-09 21:58:02.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/boot/bootsect.S	2003-08-01 13:33:22.000000000 +0000
@@ -234,7 +234,8 @@
 die:	jne	die			# %es must be at 64kB boundary
 	xorw	%bx, %bx		# %bx is starting address within segment
 rp_read:
-#ifdef __BIG_KERNEL__			# look in setup.S for bootsect_kludge
+#ifdef __BIG_KERNEL__
+					# look in setup.S for bootsect_kludge
 	bootsect_kludge = 0x220		# 0x200 + 0x20 which is the size of the
 	lcall	bootsect_kludge		# bootsector + bootsect_kludge offset
 #else
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/boot/compressed/misc.c linux-2.4.22-pre10/arch/i386/boot/compressed/misc.c
--- linux-2.4.21/arch/i386/boot/compressed/misc.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/boot/compressed/misc.c	2003-08-01 13:33:41.000000000 +0000
@@ -101,15 +101,11 @@
 static uch *output_data;
 static unsigned long output_ptr = 0;
 
- 
 static void *malloc(int size);
 static void free(void *where);
-static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
- 
+
 static void puts(const char *);
-  
+
 extern int end;
 static long free_mem_ptr = (long)&end;
 static long free_mem_end_ptr;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/config.in linux-2.4.22-pre10/arch/i386/config.in
--- linux-2.4.21/arch/i386/config.in	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/config.in	2003-08-01 13:32:22.000000000 +0000
@@ -326,14 +326,6 @@
 
 bool 'Power Management support' CONFIG_PM
 
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   dep_bool '  ACPI support' CONFIG_ACPI $CONFIG_PM
-   
-   if [ "$CONFIG_ACPI" != "n" ]; then
-      source drivers/acpi/Config.in
-   fi
-fi
-
 dep_tristate '  Advanced Power Management BIOS support' CONFIG_APM $CONFIG_PM
 if [ "$CONFIG_APM" != "n" ]; then
    bool '    Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND
@@ -345,6 +337,8 @@
    bool '    Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF
 fi
 
+source drivers/acpi/Config.in
+
 endmenu
 
 source drivers/mtd/Config.in
@@ -399,7 +393,7 @@
    bool 'Network device support' CONFIG_NETDEVICES
    if [ "$CONFIG_NETDEVICES" = "y" ]; then
       source drivers/net/Config.in
-      if [ "$CONFIG_ATM" = "y" ]; then
+      if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
          source drivers/atm/Config.in
       fi
    fi
@@ -484,4 +478,5 @@
 
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/Makefile linux-2.4.22-pre10/arch/i386/kernel/Makefile
--- linux-2.4.21/arch/i386/kernel/Makefile	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/Makefile	2003-08-01 13:31:33.000000000 +0000
@@ -14,7 +14,7 @@
 
 O_TARGET := kernel.o
 
-export-objs     := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o
+export-objs     := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o setup.o
 
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
@@ -36,9 +36,12 @@
 obj-$(CONFIG_X86_CPUID)		+= cpuid.o
 obj-$(CONFIG_MICROCODE)		+= microcode.o
 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 acpitable.o
+obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
 obj-$(CONFIG_X86_VISWS_APIC)	+= visws_apic.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/acpi.c linux-2.4.22-pre10/arch/i386/kernel/acpi.c
--- linux-2.4.21/arch/i386/kernel/acpi.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/acpi.c	2003-08-01 13:34:21.000000000 +0000
@@ -0,0 +1,570 @@
+/*
+ *  acpi.c - Architecture-Specific Low-Level ACPI Support
+ *
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
+ *  Copyright (C) 2001 Patrick Mochel <mochel@osdl.org>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+#include <linux/acpi.h>
+#include <asm/mpspec.h>
+#include <asm/io.h>
+#include <asm/apic.h>
+#include <asm/apicdef.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/io_apic.h>
+#include <asm/acpi.h>
+#include <asm/save_state.h>
+#include <asm/smpboot.h>
+
+
+#define PREFIX			"ACPI: "
+
+extern int acpi_disabled;
+
+/* --------------------------------------------------------------------------
+                              Boot-time Configuration
+   -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI_BOOT
+
+enum acpi_irq_model_id		acpi_irq_model;
+
+
+/*
+ * 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.
+ */
+char *__acpi_map_table(unsigned long phys, unsigned long size)
+{
+	unsigned long base, offset, mapped_size;
+	int idx;
+
+	if (phys + size < 8*1024*1024) 
+		return __va(phys); 
+
+	offset = phys & (PAGE_SIZE - 1);
+	mapped_size = PAGE_SIZE - offset;
+	set_fixmap(FIX_ACPI_END, phys);
+	base = fix_to_virt(FIX_ACPI_END);
+
+	/*
+	 * Most cases can be covered by the below.
+	 */
+	idx = FIX_ACPI_END;
+	while (mapped_size < size) {
+		if (--idx < FIX_ACPI_BEGIN)
+			return 0;	/* cannot handle this */
+		phys += PAGE_SIZE;
+		set_fixmap(idx, phys);
+		mapped_size += PAGE_SIZE;
+	}
+
+	return ((unsigned char *) base + offset);
+}
+
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+int acpi_lapic;
+
+static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
+
+
+static int __init
+acpi_parse_madt (
+	unsigned long		phys_addr,
+	unsigned long		size)
+{
+	struct acpi_table_madt	*madt = NULL;
+
+	if (!phys_addr || !size)
+		return -EINVAL;
+
+	madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size);
+	if (!madt) {
+		printk(KERN_WARNING PREFIX "Unable to map MADT\n");
+		return -ENODEV;
+	}
+
+	if (madt->lapic_address)
+		acpi_lapic_addr = (u64) madt->lapic_address;
+
+	printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n",
+		madt->lapic_address);
+
+	detect_clustered_apic(madt->header.oem_id, madt->header.oem_table_id);
+
+	return 0;
+}
+
+
+static int __init
+acpi_parse_lapic (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_lapic	*processor = NULL;
+
+	processor = (struct acpi_table_lapic*) header;
+	if (!processor)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	mp_register_lapic (
+		processor->id,					   /* APIC ID */
+		processor->flags.enabled);			  /* Enabled? */
+
+	return 0;
+}
+
+
+static int __init
+acpi_parse_lapic_addr_ovr (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL;
+
+	lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header;
+	if (!lapic_addr_ovr)
+		return -EINVAL;
+
+	acpi_lapic_addr = lapic_addr_ovr->address;
+
+	return 0;
+}
+
+static int __init
+acpi_parse_lapic_nmi (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_lapic_nmi *lapic_nmi = NULL;
+
+	lapic_nmi = (struct acpi_table_lapic_nmi*) header;
+	if (!lapic_nmi)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	if (lapic_nmi->lint != 1)
+		printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n");
+
+	return 0;
+}
+
+#endif /*CONFIG_X86_LOCAL_APIC*/
+
+#ifdef CONFIG_X86_IO_APIC
+
+int acpi_ioapic;
+
+static int __init
+acpi_parse_ioapic (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_ioapic *ioapic = NULL;
+
+	ioapic = (struct acpi_table_ioapic*) header;
+	if (!ioapic)
+		return -EINVAL;
+ 
+	acpi_table_print_madt_entry(header);
+
+	mp_register_ioapic (
+		ioapic->id,
+		ioapic->address,
+		ioapic->global_irq_base);
+ 
+	return 0;
+}
+
+
+static int __init
+acpi_parse_int_src_ovr (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_int_src_ovr *intsrc = NULL;
+
+	intsrc = (struct acpi_table_int_src_ovr*) header;
+	if (!intsrc)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	mp_override_legacy_irq (
+		intsrc->bus_irq,
+		intsrc->flags.polarity,
+		intsrc->flags.trigger,
+		intsrc->global_irq);
+
+	return 0;
+}
+
+
+static int __init
+acpi_parse_nmi_src (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_nmi_src *nmi_src = NULL;
+
+	nmi_src = (struct acpi_table_nmi_src*) header;
+	if (!nmi_src)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	/* TBD: Support nimsrc entries? */
+
+	return 0;
+}
+
+#endif /*CONFIG_X86_IO_APIC*/
+
+
+static unsigned long __init
+acpi_scan_rsdp (
+	unsigned long		start,
+	unsigned long		length)
+{
+	unsigned long		offset = 0;
+	unsigned long		sig_len = sizeof("RSD PTR ") - 1;
+
+	/*
+	 * Scan all 16-byte boundaries of the physical memory region for the
+	 * RSDP signature.
+	 */
+	for (offset = 0; offset < length; offset += 16) {
+		if (strncmp((char *) (start + offset), "RSD PTR ", sig_len))
+			continue;
+		return (start + offset);
+	}
+
+	return 0;
+}
+
+
+unsigned long __init
+acpi_find_rsdp (void)
+{
+	unsigned long		rsdp_phys = 0;
+
+	/*
+	 * Scan memory looking for the RSDP signature. First search EBDA (low
+	 * memory) paragraphs and then search upper memory (E0000-FFFFF).
+	 */
+	rsdp_phys = acpi_scan_rsdp (0, 0x400);
+	if (!rsdp_phys)
+		rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF);
+
+	return rsdp_phys;
+}
+
+
+int __init
+acpi_boot_init (void)
+{
+	int			result = 0;
+
+	/*
+	 * The default interrupt routing model is PIC (8259).  This gets
+	 * overriden if IOAPICs are enumerated (below).
+	 */
+	acpi_irq_model = ACPI_IRQ_MODEL_PIC;
+
+	/* 
+	 * Initialize the ACPI boot-time table parser.
+	 */
+	result = acpi_table_init();
+	if (result)
+		return result;
+
+	result = acpi_blacklisted();
+	if (result) {
+		acpi_disabled = 1;
+		return result;
+	}
+	else
+		printk(KERN_NOTICE PREFIX "BIOS passes blacklist\n");
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+	/* 
+	 * MADT
+	 * ----
+	 * Parse the Multiple APIC Description Table (MADT), if exists.
+	 * Note that this table provides platform SMP configuration 
+	 * information -- the successor to MPS tables.
+	 */
+
+	result = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
+	if (!result) {
+		printk(KERN_WARNING PREFIX "MADT not present\n");
+		return 0;
+	}
+	else if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing MADT\n");
+		return result;
+	}
+	else if (result > 1) 
+		printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n");
+
+	/* 
+	 * Local APIC
+	 * ----------
+	 * Note that the LAPIC address is obtained from the MADT (32-bit value)
+	 * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
+	 */
+
+	result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr);
+	if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
+		return result;
+	}
+
+	mp_register_lapic_address(acpi_lapic_addr);
+
+	result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic);
+	if (!result) { 
+		printk(KERN_ERR PREFIX "No LAPIC entries present\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return -ENODEV;
+	}
+	else if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return result;
+	}
+
+	result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi);
+	if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return result;
+	}
+
+	acpi_lapic = 1;
+
+#endif /*CONFIG_X86_LOCAL_APIC*/
+
+#ifdef CONFIG_X86_IO_APIC
+
+	/* 
+	 * I/O APIC 
+	 * --------
+	 */
+
+	result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic);
+	if (!result) { 
+		printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
+		return -ENODEV;
+	}
+	else if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n");
+		return result;
+	}
+
+	/* Build a default routing table for legacy (ISA) interrupts. */
+	mp_config_acpi_legacy_irqs();
+
+	result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr);
+	if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return result;
+	}
+
+	result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src);
+	if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return result;
+	}
+
+	acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
+
+	acpi_ioapic = 1;
+
+#endif /*CONFIG_X86_IO_APIC*/
+
+#ifdef CONFIG_X86_LOCAL_APIC
+	if (acpi_lapic && acpi_ioapic)
+		smp_found_config = 1;
+#endif
+
+	return 0;
+}
+
+#endif /*CONFIG_ACPI_BOOT*/
+
+
+/* --------------------------------------------------------------------------
+                              Low-Level Sleep Support
+   -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI_SLEEP
+
+#define DEBUG
+
+#ifdef DEBUG
+#include <linux/serial.h>
+#endif
+
+/* address in low memory of the wakeup routine. */
+unsigned long acpi_wakeup_address = 0;
+
+/* new page directory that we will be using */
+static pmd_t *pmd;
+
+/* saved page directory */
+static pmd_t saved_pmd;
+
+/* page which we'll use for the new page directory */
+static pte_t *ptep;
+
+extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
+
+/*
+ * acpi_create_identity_pmd
+ *
+ * Create a new, identity mapped pmd.
+ *
+ * Do this by creating new page directory, and marking all the pages as R/W
+ * Then set it as the new Page Middle Directory.
+ * And, of course, flush the TLB so it takes effect.
+ *
+ * We save the address of the old one, for later restoration.
+ */
+static void acpi_create_identity_pmd (void)
+{
+	pgd_t *pgd;
+	int i;
+
+	ptep = (pte_t*)__get_free_page(GFP_KERNEL);
+
+	/* fill page with low mapping */
+	for (i = 0; i < PTRS_PER_PTE; i++)
+		set_pte(ptep + i, mk_pte_phys(i << PAGE_SHIFT, PAGE_SHARED));
+
+	pgd = pgd_offset(current->active_mm, 0);
+	pmd = pmd_alloc(current->mm,pgd, 0);
+
+	/* save the old pmd */
+	saved_pmd = *pmd;
+
+	/* set the new one */
+	set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(ptep)));
+
+	/* flush the TLB */
+	local_flush_tlb();
+}
+
+/*
+ * acpi_restore_pmd
+ *
+ * Restore the old pmd saved by acpi_create_identity_pmd and
+ * free the page that said function alloc'd
+ */
+static void acpi_restore_pmd (void)
+{
+	set_pmd(pmd, saved_pmd);
+	local_flush_tlb();
+	free_page((unsigned long)ptep);
+}
+
+/**
+ * acpi_save_state_mem - save kernel state
+ *
+ * Create an identity mapped page table and copy the wakeup routine to
+ * low memory.
+ */
+int acpi_save_state_mem (void)
+{
+	acpi_create_identity_pmd();
+	acpi_copy_wakeup_routine(acpi_wakeup_address);
+
+	return 0;
+}
+
+/**
+ * acpi_save_state_disk - save kernel state to disk
+ *
+ */
+int acpi_save_state_disk (void)
+{
+	return 1;
+}
+
+/*
+ * acpi_restore_state
+ */
+void acpi_restore_state_mem (void)
+{
+	acpi_restore_pmd();
+}
+
+/**
+ * acpi_reserve_bootmem - do _very_ early ACPI initialisation
+ *
+ * We allocate a page in low memory for the wakeup
+ * routine for when we come back from a sleep state. The
+ * runtime allocator allows specification of <16M pages, but not
+ * <1M pages.
+ */
+void __init acpi_reserve_bootmem(void)
+{
+	acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
+	printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
+}
+
+void do_suspend_lowlevel_s4bios(int resume)
+{
+	if (!resume) {
+		save_processor_context();
+		acpi_save_register_state((unsigned long)&&acpi_sleep_done);
+		acpi_enter_sleep_state_s4bios();
+		return;
+	}
+acpi_sleep_done:
+	restore_processor_context();
+}
+
+
+#endif /*CONFIG_ACPI_SLEEP*/
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/acpi_wakeup.S linux-2.4.22-pre10/arch/i386/kernel/acpi_wakeup.S
--- linux-2.4.21/arch/i386/kernel/acpi_wakeup.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/acpi_wakeup.S	2003-08-01 13:33:52.000000000 +0000
@@ -0,0 +1,145 @@
+
+.text
+#include <linux/linkage.h>
+#include <asm/segment.h>
+
+
+ALIGN
+wakeup_start:
+wakeup_code:
+	wakeup_code_start = .
+	.code16
+
+	cli
+	cld
+
+	# setup data segment
+	movw	%cs, %ax
+
+	addw	$(wakeup_data - wakeup_code) >> 4, %ax
+	movw	%ax, %ds
+	movw	%ax, %ss
+
+	# Private stack is needed for ASUS board
+	mov	$(wakeup_stack - wakeup_data), %sp
+
+	# set up page table
+	movl	(real_save_cr3 - wakeup_data), %eax
+	movl	%eax, %cr3
+
+	# make sure %cr4 is set correctly (features, etc)
+	movl	(real_save_cr4 - wakeup_data), %eax
+	movl	%eax, %cr4
+
+	# need a gdt
+	lgdt	real_save_gdt - wakeup_data
+
+	# Flush the prefetch queue
+	jmp 1f
+1:
+
+	movl	%cr0, %eax
+	orl     $0x80000001, %eax
+	movl	%eax, %cr0
+
+	ljmpl	$__KERNEL_CS,$SYMBOL_NAME(wakeup_pmode_return)
+
+	.code32
+	ALIGN
+
+.org	0x100
+wakeup_data:
+		.word 0
+real_save_gdt:	.word 0
+		.long 0
+real_save_cr3:	.long 0
+real_save_cr4:	.long 0
+
+.org	0x300
+wakeup_stack:
+wakeup_end:
+
+wakeup_pmode_return:
+	# restore data segment
+	movl	$__KERNEL_DS, %eax
+	movw	%ax, %ds
+	movw	%ax, %es
+
+	# and restore the stack
+	movw	%ax, %ss
+	movl	saved_esp, %esp
+
+	# restore other segment registers
+	xorl	%eax, %eax
+	movw	%ax, %fs
+	movw	%ax, %gs
+
+	# reload the gdt, as we need the full 32 bit address
+	lgdt	saved_gdt
+	lidt	saved_idt
+	lldt	saved_ldt
+
+	# restore the other general registers
+	movl	saved_ebx, %ebx
+	movl	saved_edi, %edi
+	movl	saved_esi, %esi
+	movl	saved_ebp, %ebp
+
+	# jump to place where we left off
+	movl	saved_eip,%eax
+	jmp	*%eax
+
+##
+# acpi_copy_wakeup_routine
+#
+# Copy the above routine to low memory.
+#
+# Parameters:
+# %eax:	place to copy wakeup routine to
+#
+# Returned address is location of code in low memory (past data and stack)
+#
+ENTRY(acpi_copy_wakeup_routine)
+
+	pushl	%esi
+	pushl	%edi
+
+	sgdt	saved_gdt
+	sidt	saved_idt
+	sldt	saved_ldt
+	str	saved_tss
+
+	movl	%eax, %edi
+	leal	wakeup_start, %esi
+	movl	$(wakeup_end - wakeup_start) >> 2, %ecx
+
+	rep ;  movsl
+
+	movl    %cr3, %edx
+	movl    %edx, real_save_cr3 - wakeup_start (%eax)
+	movl    %cr4, %edx
+	movl    %edx, real_save_cr4 - wakeup_start (%eax)
+	sgdt    real_save_gdt - wakeup_start (%eax)
+
+	# restore the regs we used
+	popl	%edi
+	popl	%esi
+	ret
+
+
+.data
+ALIGN
+# saved registers
+saved_gdt:	.long	0,0
+saved_idt:	.long	0,0
+saved_ldt:	.long	0
+saved_tss:	.long	0
+saved_cr0:	.long	0
+
+ENTRY(saved_ebp)	.long	0
+ENTRY(saved_esi)	.long	0
+ENTRY(saved_edi)	.long	0
+ENTRY(saved_ebx)	.long	0
+
+ENTRY(saved_eip)	.long	0
+ENTRY(saved_esp)	.long	0
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/acpitable.c linux-2.4.22-pre10/arch/i386/kernel/acpitable.c
--- linux-2.4.21/arch/i386/kernel/acpitable.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/acpitable.c	2003-08-01 13:34:18.000000000 +0000
@@ -45,6 +45,7 @@
 
 static acpi_table_handler acpi_boot_ops[ACPI_TABLE_COUNT];
 
+int acpi_lapic;
 
 static unsigned char __init
 acpi_checksum(void *buffer, int length)
@@ -530,14 +531,13 @@
 	return 0;
 }
 
-extern int enable_acpi_smp_table;
 
 /*
  * Configure the processor info using MADT in the ACPI tables. If we fail to
  * configure that, then we use the MPS tables.
  */
 void __init
-config_acpi_tables(void)
+acpi_boot_init(void)
 {
 
 	memset(&acpi_boot_ops, 0, sizeof(acpi_boot_ops));
@@ -547,8 +547,7 @@
 	 * Only do this when requested, either because of CPU/Bios type or from the command line
 	 */
 
-	if (enable_acpi_smp_table && !acpi_tables_init()) {
-		have_acpi_tables = 1;
-		printk("Enabling the CPU's according to the ACPI table\n");
-	}
+	if (!acpi_tables_init())
+		acpi_lapic = 1;
 }
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/apm.c linux-2.4.22-pre10/arch/i386/kernel/apm.c
--- linux-2.4.21/arch/i386/kernel/apm.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/apm.c	2003-08-01 13:30:54.000000000 +0000
@@ -868,6 +868,8 @@
 		idle_percentage *= 100;
 		idle_percentage /= jiffies_since_last_check;
 		use_apm_idle = (idle_percentage > idle_threshold);
+		if (apm_info.forbid_idle)
+			use_apm_idle = 0;
 		last_jiffies = jiffies;
 		last_stime = current->times.tms_stime;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/dmi_scan.c linux-2.4.22-pre10/arch/i386/kernel/dmi_scan.c
--- linux-2.4.21/arch/i386/kernel/dmi_scan.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/dmi_scan.c	2003-08-01 13:32:43.000000000 +0000
@@ -297,6 +297,32 @@
 	return 0;
 }
 
+static __init int apm_is_horked_d850md(struct dmi_blacklist *d)
+{
+	if (apm_info.disabled == 0)
+	{
+		apm_info.disabled = 1;
+		printk(KERN_ERR "%s machine detected. Disabling APM.\n", d->ident);
+		printk(KERN_ERR "This bug is fixed in bios P15 which is available for \n");
+		printk(KERN_ERR "download from support.intel.com \n");
+	}
+	return 0;
+}
+
+/* 
+ * Some APM bioses hang on APM idle calls
+ */
+
+static __init int apm_likes_to_melt(struct dmi_blacklist *d)
+{
+	if (apm_info.forbid_idle == 0)
+	{
+		apm_info.forbid_idle = 1;
+		printk(KERN_INFO "%s machine detected. Disabling APM idle calls.\n", d->ident);
+	}
+	return 0;
+}
+
 /*
  * Some machines, usually laptops, can't handle an enabled local APIC.
  * The symptoms include hangs or reboots when suspending or resuming,
@@ -415,8 +441,10 @@
  */
  
 extern int skip_ioapic_setup;
+#ifdef CONFIG_PCI
 extern int broken_440gx_bios;
 extern unsigned int pci_probe;
+#endif
 static __init int broken_pirq(struct dmi_blacklist *d)
 {
 	printk(KERN_INFO " *** Possibly defective BIOS detected (irqtable)\n");
@@ -483,6 +511,18 @@
 }
 
 /*
+ *	Exploding PnPBIOS. Don't yet know if its the BIOS or us for
+ *	some entries
+ */
+
+static __init int exploding_pnp_bios(struct dmi_blacklist *d)
+{
+	printk(KERN_WARNING "%s detected. Disabling PnPBIOS\n", d->ident);
+	dmi_broken |= BROKEN_PNP_BIOS;
+	return 0;
+}
+
+/*
  *	Simple "print if true" callback
  */
  
@@ -508,17 +548,47 @@
 			MATCH(DMI_PRODUCT_NAME, "KT7-RAID"),
 			NO_MATCH, NO_MATCH, NO_MATCH
 			} },
+	{ disable_ide_dma, "Dell Inspiron 8100", {	/* Kill DMA on Dell Inspiron 8100 laptops */
+			MATCH(DMI_PRODUCT_NAME, "Inspiron 8100"),
+			MATCH(DMI_SYS_VENDOR,"Dell Computer Corporation"), NO_MATCH, NO_MATCH
+			} },
+
 #endif			
+	/* Dell Laptop hall of shame */
 	{ broken_ps2_resume, "Dell Latitude C600", {	/* Handle problems with APM on the C600 */
 		        MATCH(DMI_SYS_VENDOR, "Dell"),
 			MATCH(DMI_PRODUCT_NAME, "Latitude C600"),
 			NO_MATCH, NO_MATCH
 	                } },
+	{ apm_is_horked, "Dell Inspiron 2500", { /* APM crashes */
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
+			MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
+			MATCH(DMI_BIOS_VERSION,"A11")
+			} },
+	{ apm_is_horked, "Dell Dimension 4100", { /* APM crashes */
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
+			MATCH(DMI_BIOS_VENDOR,"Intel Corp."),
+			MATCH(DMI_BIOS_VERSION,"A11")
+			} },
+	{ set_apm_ints, "Dell Inspiron", {	/* Allow interrupts during suspend on Dell Inspiron laptops*/
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"),
+			NO_MATCH, NO_MATCH
+			} },
+	{ set_apm_ints, "Dell Latitude", {	/* Allow interrupts during suspend on Dell Latitude laptops*/
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "Latitude C510"),
+			NO_MATCH, NO_MATCH
+			} },
 	{ broken_apm_power, "Dell Inspiron 5000e", {	/* Handle problems with APM on Inspiron 5000e */
 			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
 			MATCH(DMI_BIOS_VERSION, "A04"),
 			MATCH(DMI_BIOS_DATE, "08/24/2000"), NO_MATCH
 			} },
+
+	/* other items */	
 	{ broken_apm_power, "Dell Inspiron 2500", {	/* Handle problems with APM on Inspiron 2500 */
 			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
 			MATCH(DMI_BIOS_VERSION, "A12"),
@@ -539,16 +609,11 @@
 			MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"),
 			NO_MATCH, NO_MATCH
 			} },
-	{ set_bios_reboot, "Dell PowerEdge 2400", {  /* Handle problems with rebooting on Dell 300/800's */
+	{ set_bios_reboot, "Dell PowerEdge 2400", {  /* Handle problems with rebooting on Dell 2400's */
 			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
 			MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"),
 			NO_MATCH, NO_MATCH
 			} },
-	{ set_apm_ints, "Dell Inspiron", {	/* Allow interrupts during suspend on Dell Inspiron laptops*/
-			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
-			MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"),
-			NO_MATCH, NO_MATCH
-			} },
 	{ set_apm_ints, "Compaq 12XL125", {	/* Allow interrupts during suspend on Compaq Laptops*/
 			MATCH(DMI_SYS_VENDOR, "Compaq"),
 			MATCH(DMI_PRODUCT_NAME, "Compaq PC"),
@@ -570,7 +635,7 @@
 			MATCH(DMI_BIOS_VERSION, "Version1.01"),
 			NO_MATCH, NO_MATCH,
 			} },
-	{ apm_is_horked, "Intel D850MD", { /* APM crashes */
+	{ apm_is_horked_d850md, "Intel D850MD", { /* APM crashes */
 			MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
 			MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"),
 			NO_MATCH, NO_MATCH,
@@ -598,6 +663,22 @@
 			MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
 			MATCH(DMI_BIOS_VERSION,"A11")
 			} },
+	{ apm_likes_to_melt, "Jabil AMD", { /* APM idle hangs */
+			MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
+			MATCH(DMI_BIOS_VERSION, "0AASNP06"),
+			NO_MATCH, NO_MATCH,
+			} },
+	{ apm_likes_to_melt, "AMI Bios", { /* APM idle hangs */
+			MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
+			MATCH(DMI_BIOS_VERSION, "0AASNP05"), 
+			NO_MATCH, NO_MATCH,
+			} },
+	{ apm_likes_to_melt, "Dell Inspiron 7500", { /* APM idle hangs */
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME,  "Inspiron 7500"), 
+			NO_MATCH, NO_MATCH,
+			} },
+
 	{ sony_vaio_laptop, "Sony Vaio", { /* This is a Sony Vaio laptop */
 			MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 			MATCH(DMI_PRODUCT_NAME, "PCG-"),
@@ -692,6 +773,13 @@
 			NO_MATCH, NO_MATCH
 			} },
 
+	{ exploding_pnp_bios, "Higraded P14H", {	/* BIOSPnP problem */
+			MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
+			MATCH(DMI_BIOS_VERSION, "07.00T"),
+			MATCH(DMI_SYS_VENDOR, "Higraded"),
+			MATCH(DMI_PRODUCT_NAME, "P14H")
+			} },
+
 	/* Machines which have problems handling enabled local APICs */
 
 	{ local_apic_kills_bios, "Dell Inspiron", {
@@ -731,11 +819,26 @@
 			} },
 	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
 			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
+			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0066.P07"),
+			NO_MATCH, NO_MATCH
+                        } },
+	{ broken_pirq, "IBM xseries 370", {        		/* Bad $PIR */
+			MATCH(DMI_BIOS_VENDOR, "IBM"),
+			MATCH(DMI_BIOS_VERSION,"MMKT33AUS"),
+			NO_MATCH, NO_MATCH
+                        } },
+	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
+			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
 			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0094.P10"),
 			NO_MATCH, NO_MATCH
                         } },
 	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
 			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
+			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0115.P12"),
+			NO_MATCH, NO_MATCH
+                        } },
+	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
+			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
 			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0120.P12"),
 			NO_MATCH, NO_MATCH
                         } },
@@ -746,7 +849,17 @@
 			} },
 	{ broken_pirq, "l44GX Bios", {		/* Bad $PIR */
 			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0066.P07.9906041405"),
+			MATCH(DMI_BIOS_VERSION,"C440GX0.86B"),
+			NO_MATCH, NO_MATCH
+			} },
+	{ broken_pirq, "l44GX Bios", {		/* Bad $PIR */
+			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
+			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0133.P14"),
+			NO_MATCH, NO_MATCH
+			} },
+	{ broken_pirq, "l44GX Bios", {		/* Bad $PIR */
+			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
+			MATCH(DMI_BIOS_VERSION,"L440GX0"),
 			NO_MATCH, NO_MATCH
 			} },
                         
@@ -774,7 +887,6 @@
 			MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"),
 			MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736")
 			} },
- 
 
 	/*
 	 *	Generic per vendor APM settings
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/i387.c linux-2.4.22-pre10/arch/i386/kernel/i387.c
--- linux-2.4.21/arch/i386/kernel/i387.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/i387.c	2003-08-01 13:35:06.000000000 +0000
@@ -373,14 +373,14 @@
 
 static inline int restore_i387_fxsave( struct _fpstate *buf )
 {
+	int err;
 	struct task_struct *tsk = current;
 	clear_fpu( tsk );
-	if ( __copy_from_user( &tsk->thread.i387.fxsave, &buf->_fxsr_env[0],
-			       sizeof(struct i387_fxsave_struct) ) )
-		return 1;
+	err = __copy_from_user( &tsk->thread.i387.fxsave, &buf->_fxsr_env[0],
+				sizeof(struct i387_fxsave_struct) );
 	/* mxcsr bit 6 and 31-16 must be zero for security reasons */
 	tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
-	return convert_fxsr_from_user( &tsk->thread.i387.fxsave, buf );
+	return err ? 1 : convert_fxsr_from_user( &tsk->thread.i387.fxsave, buf );
 }
 
 int restore_i387( struct _fpstate *buf )
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/io_apic.c linux-2.4.22-pre10/arch/i386/kernel/io_apic.c
--- linux-2.4.21/arch/i386/kernel/io_apic.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/io_apic.c	2003-08-01 13:32:25.000000000 +0000
@@ -17,6 +17,7 @@
  *					thanks to Eric Gilmore
  *					and Rolf G. Tews
  *					for testing these extensively
+ *	Paul Diefenbaugh	:	Added full ACPI support
  */
 
 #include <linux/mm.h>
@@ -28,6 +29,7 @@
 #include <linux/config.h>
 #include <linux/smp_lock.h>
 #include <linux/mc146818rtc.h>
+#include <linux/acpi.h>
 
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -123,7 +125,7 @@
 			break;						\
 		reg = io_apic_read(entry->apic, 0x10 + R + pin*2);	\
 		reg ACTION;						\
-		io_apic_modify(entry->apic, reg);			\
+		io_apic_write(entry->apic, 0x10 + R + pin*2, reg);	\
 		if (!entry->next)					\
 			break;						\
 		entry = irq_2_pin + entry->next;			\
@@ -750,6 +752,7 @@
 	struct IO_APIC_reg_00 reg_00;
 	struct IO_APIC_reg_01 reg_01;
 	struct IO_APIC_reg_02 reg_02;
+	struct IO_APIC_reg_03 reg_03;
 	unsigned long flags;
 
  	printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
@@ -770,6 +773,8 @@
 	*(int *)&reg_01 = io_apic_read(apic, 1);
 	if (reg_01.version >= 0x10)
 		*(int *)&reg_02 = io_apic_read(apic, 2);
+	if (reg_01.version >= 0x20)
+		*(int *)&reg_03 = io_apic_read(apic, 3);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	printk("\n");
@@ -807,13 +812,31 @@
 	if (reg_01.__reserved_1 || reg_01.__reserved_2)
 		UNEXPECTED_IO_APIC();
 
-	if (reg_01.version >= 0x10) {
+	/*
+	 * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02,
+	 * but the value of reg_02 is read as the previous read register
+	 * value, so ignore it if reg_02 == reg_01.
+	 */
+	if (reg_01.version >= 0x10 && *(int *)&reg_02 != *(int *)&reg_01) {
 		printk(KERN_DEBUG ".... register #02: %08X\n", *(int *)&reg_02);
 		printk(KERN_DEBUG ".......     : arbitration: %02X\n", reg_02.arbitration);
 		if (reg_02.__reserved_1 || reg_02.__reserved_2)
 			UNEXPECTED_IO_APIC();
 	}
 
+	/*
+	 * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02
+	 * or reg_03, but the value of reg_0[23] is read as the previous read
+	 * register value, so ignore it if reg_03 == reg_0[12].
+	 */
+	if (reg_01.version >= 0x20 && *(int *)&reg_03 != *(int *)&reg_02 &&
+	    *(int *)&reg_03 != *(int *)&reg_01) {
+		printk(KERN_DEBUG ".... register #03: %08X\n", *(int *)&reg_03);
+		printk(KERN_DEBUG ".......     : Boot DT    : %X\n", reg_03.boot_DT);
+		if (reg_03.__reserved_1)
+			UNEXPECTED_IO_APIC();
+	}
+
 	printk(KERN_DEBUG ".... IRQ redirection table:\n");
 
 	printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol"
@@ -1057,6 +1080,10 @@
 	unsigned char old_id;
 	unsigned long flags;
 
+	if (acpi_ioapic)
+		/* This gets done during IOAPIC enumeration for ACPI. */
+		return;
+
 	if (clustered_apic_mode)
 		/* We don't have a good way to do this yet - hack */
 		phys_id_present_map = (u_long) 0xf;
@@ -1316,6 +1343,25 @@
 
 static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ }
 
+#ifndef CONFIG_SMP
+
+void send_IPI_self(int vector)
+{
+	unsigned int cfg;
+
+	/*
+	 * Wait for idle.
+	 */
+	apic_wait_icr_idle();
+	cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL;
+	/*
+	 * Send the IPI. The write to APIC_ICR fires this off.
+	 */
+	apic_write_around(APIC_ICR, cfg);
+}
+
+#endif /* CONFIG_SMP */
+
 static void set_ioapic_affinity (unsigned int irq, unsigned long mask)
 {
 	unsigned long flags;
@@ -1657,8 +1703,7 @@
 	printk("ENABLING IO-APIC IRQs\n");
 
 	/*
-	 * Set up the IO-APIC IRQ routing table by parsing the MP-BIOS
-	 * mptable:
+	 * Set up IO-APIC IRQ routing.
 	 */
 	setup_ioapic_ids_from_mpc();
 	sync_Arb_IDs();
@@ -1667,3 +1712,166 @@
 	check_timer();
 	print_IO_APIC();
 }
+
+
+/* --------------------------------------------------------------------------
+                          ACPI-based IOAPIC Configuration
+   -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI_BOOT
+
+#define IO_APIC_MAX_ID		15
+
+int __init io_apic_get_unique_id (int ioapic, int apic_id)
+{
+	struct IO_APIC_reg_00 reg_00;
+	static unsigned long apic_id_map = 0;
+	unsigned long flags;
+	int i = 0;
+
+	/*
+	 * The P4 platform supports up to 256 APIC IDs on two separate APIC 
+	 * buses (one for LAPICs, one for IOAPICs), where predecessors only 
+	 * supports up to 16 on one shared APIC bus.
+	 * 
+	 * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full
+	 *      advantage of new APIC bus architecture.
+	 */
+
+	if (!apic_id_map)
+		apic_id_map = phys_cpu_present_map;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	*(int *)&reg_00 = io_apic_read(ioapic, 0);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	if (apic_id >= IO_APIC_MAX_ID) {
+		printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
+			"%d\n", ioapic, apic_id, reg_00.ID);
+		apic_id = reg_00.ID;
+	}
+
+	/* XAPICs do not need unique IDs */
+	if (clustered_apic_mode == CLUSTERED_APIC_XAPIC){
+		printk(KERN_INFO "IOAPIC[%d]: Assigned apic_id %d\n", 
+			ioapic, apic_id);
+		return apic_id;
+	}
+
+	/*
+	 * Every APIC in a system must have a unique ID or we get lots of nice 
+	 * 'stuck on smp_invalidate_needed IPI wait' messages.
+	 */
+	if (apic_id_map & (1 << apic_id)) {
+
+		for (i = 0; i < IO_APIC_MAX_ID; i++) {
+			if (!(apic_id_map & (1 << i)))
+				break;
+		}
+
+		if (i == IO_APIC_MAX_ID)
+			panic("Max apic_id exceeded!\n");
+
+		printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
+			"trying %d\n", ioapic, apic_id, i);
+
+		apic_id = i;
+	} 
+
+	apic_id_map |= (1 << apic_id);
+
+	if (reg_00.ID != apic_id) {
+		reg_00.ID = apic_id;
+
+		spin_lock_irqsave(&ioapic_lock, flags);
+		io_apic_write(ioapic, 0, *(int *)&reg_00);
+		*(int *)&reg_00 = io_apic_read(ioapic, 0);
+		spin_unlock_irqrestore(&ioapic_lock, flags);
+
+		/* Sanity check */
+		if (reg_00.ID != apic_id)
+			panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic);
+	}
+
+	printk(KERN_INFO "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
+
+	return apic_id;
+}
+
+
+int __init io_apic_get_version (int ioapic)
+{
+	struct IO_APIC_reg_01	reg_01;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	*(int *)&reg_01 = io_apic_read(ioapic, 1);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	return reg_01.version;
+}
+
+
+int __init io_apic_get_redir_entries (int ioapic)
+{
+	struct IO_APIC_reg_01	reg_01;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	*(int *)&reg_01 = io_apic_read(ioapic, 1);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	return reg_01.entries;
+}
+
+
+int io_apic_set_pci_routing (int ioapic, int pin, int irq)
+{
+	struct IO_APIC_route_entry entry;
+	unsigned long flags;
+
+	if (!IO_APIC_IRQ(irq)) {
+		printk(KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0/n", 
+			ioapic);
+		return -EINVAL;
+	}
+
+	/*
+	 * Generate a PCI IRQ routing entry and program the IOAPIC accordingly.
+	 * Note that we mask (disable) IRQs now -- these get enabled when the
+	 * corresponding device driver registers for this IRQ.
+	 */
+
+	memset(&entry,0,sizeof(entry));
+
+	entry.delivery_mode = dest_LowestPrio;
+	entry.dest_mode = INT_DELIVERY_MODE;
+	entry.dest.logical.logical_dest = target_cpus();
+	entry.mask = 1;					 /* Disabled (masked) */
+	entry.trigger = 1;				   /* Level sensitive */
+	entry.polarity = 1;					/* Low active */
+
+	add_pin_to_irq(irq, ioapic, pin);
+
+	entry.vector = assign_irq_vector(irq);
+
+	printk(KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> "
+		"IRQ %d)\n", ioapic, 
+		mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq);
+
+	irq_desc[irq].handler = &ioapic_level_irq_type;
+
+	set_intr_gate(entry.vector, interrupt[irq]);
+
+	if (!ioapic && (irq < 16))
+		disable_8259A_irq(irq);
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1));
+	io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0));
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	return 0;
+}
+
+#endif /*CONFIG_ACPI_BOOT*/
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/mpparse.c linux-2.4.22-pre10/arch/i386/kernel/mpparse.c
--- linux-2.4.21/arch/i386/kernel/mpparse.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/mpparse.c	2003-08-01 13:32:17.000000000 +0000
@@ -9,12 +9,14 @@
  *		Erich Boleyn	:	MP v1.4 and additional changes.
  *		Alan Cox	:	Added EBDA scanning
  *		Ingo Molnar	:	various cleanups and rewrites
- *	Maciej W. Rozycki	:	Bits for default MP configurations
+ *		Maciej W. Rozycki:	Bits for default MP configurations
+ *		Paul Diefenbaugh:	Added full ACPI support
  */
 
 #include <linux/mm.h>
 #include <linux/irq.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
 #include <linux/delay.h>
 #include <linux/config.h>
 #include <linux/bootmem.h>
@@ -23,10 +25,12 @@
 #include <linux/mc146818rtc.h>
 
 #include <asm/smp.h>
+#include <asm/acpi.h>
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
 #include <asm/pgalloc.h>
 #include <asm/smpboot.h>
+#include <asm/io_apic.h>
 
 /* Have we found an MP table */
 int smp_found_config;
@@ -137,12 +141,6 @@
 	return n;
 }
 
-#ifdef CONFIG_X86_IO_APIC
-extern int have_acpi_tables;	/* set by acpitable.c */
-#else
-#define have_acpi_tables (0)
-#endif
-
 /* 
  * Have to match translation table entries to main table entries by counter
  * hence the mpc_record variable .... can't see a less disgusting way of
@@ -447,10 +445,11 @@
 	
 	printk("APIC at: 0x%lX\n",mpc->mpc_lapic);
 
-	/* save the local APIC address, it might be non-default,
-	 * but only if we're not using the ACPI tables
+	/* 
+	 * Save the local APIC address (it might be non-default) -- but only
+	 * if we're not using ACPI.
 	 */
-	if (!have_acpi_tables)
+	if (!acpi_lapic)
 		mp_lapic_addr = mpc->mpc_lapic;
 
 	if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ) && mpc->mpc_oemptr) {
@@ -517,7 +516,7 @@
 	mp_bus_id_to_local = (int *)&bus_data[(max_mp_busses * sizeof(int)) * 2];
 	mp_bus_id_to_pci_bus = (int *)&bus_data[(max_mp_busses * sizeof(int)) * 3];
 	mp_irqs = (struct mpc_config_intsrc *)&bus_data[(max_mp_busses * sizeof(int)) * 4];
-	memset(mp_bus_id_to_pci_bus, -1, max_mp_busses);
+	memset(mp_bus_id_to_pci_bus, -1, max_mp_busses * sizeof(int));
 
 	/*
 	 *	Now process the configuration blocks.
@@ -530,9 +529,8 @@
 			{
 				struct mpc_config_processor *m=
 					(struct mpc_config_processor *)mpt;
-
-				/* ACPI may already have provided this one for us */
-				if (!have_acpi_tables)
+				/* ACPI may have already provided this data */
+				if (!acpi_lapic)
 					MP_processor_info(m);
 				mpt += sizeof(*m);
 				count += sizeof(*m);
@@ -761,7 +759,6 @@
 }
 
 static struct intel_mp_floating *mpf_found;
-extern void 	config_acpi_tables(void);
 
 /*
  * Scan the memory blocks for an SMP configuration block.
@@ -770,17 +767,19 @@
 {
 	struct intel_mp_floating *mpf = mpf_found;
 
-#ifdef CONFIG_X86_IO_APIC
 	/*
-	 * Check if the ACPI tables are provided. Use them only to get
-	 * the processor information, mainly because it provides
-	 * the info on the logical processor(s), rather than the physical
-	 * processor(s) that are provided by the MPS. We attempt to 
-	 * check only if the user provided a commandline override
+	 * ACPI may be used to obtain the entire SMP configuration or just to 
+	 * enumerate/configure processors (CONFIG_ACPI_HT_ONLY).  Note that 
+	 * ACPI supports both logical (e.g. Hyper-Threading) and physical 
+	 * processors, where MPS only supports physical.
 	 */
-	config_acpi_tables();
-#endif
-	
+	if (acpi_lapic && acpi_ioapic) {
+		printk(KERN_INFO "Using ACPI (MADT) for SMP configuration information\n");
+		return;
+	}
+	else if (acpi_lapic)
+		printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n");
+
 	printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
 	if (mpf->mpf_feature2 & (1<<7)) {
 		printk("    IMCR and PIC compatibility mode.\n");
@@ -939,3 +938,394 @@
 #endif
 }
 
+
+/* --------------------------------------------------------------------------
+                            ACPI-based MP Configuration
+   -------------------------------------------------------------------------- */
+
+#ifdef CONFIG_ACPI_BOOT
+
+void __init mp_register_lapic_address (
+	u64			address)
+{
+	mp_lapic_addr = (unsigned long) address;
+
+	set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
+
+	if (boot_cpu_physical_apicid == -1U)
+		boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
+
+	Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid);
+}
+
+
+void __init mp_register_lapic (
+	u8			id, 
+	u8			enabled)
+{
+	struct mpc_config_processor processor;
+	int			boot_cpu = 0;
+	
+	if (id >= MAX_APICS) {
+		printk(KERN_WARNING "Processor #%d invalid (max %d)\n",
+			id, MAX_APICS);
+		return;
+	}
+
+	if (id == boot_cpu_physical_apicid)
+		boot_cpu = 1;
+
+	processor.mpc_type = MP_PROCESSOR;
+	processor.mpc_apicid = id;
+	processor.mpc_apicver = 0x10; /* TBD: lapic version */
+	processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0);
+	processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0);
+	processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | 
+		(boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask;
+	processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
+	processor.mpc_reserved[0] = 0;
+	processor.mpc_reserved[1] = 0;
+
+	MP_processor_info(&processor);
+}
+
+#ifdef CONFIG_X86_IO_APIC
+
+#define MP_ISA_BUS		0
+#define MP_MAX_IOAPIC_PIN	127
+
+struct mp_ioapic_routing {
+	int			apic_id;
+	int			irq_start;
+	int			irq_end;
+	u32			pin_programmed[4];
+} mp_ioapic_routing[MAX_IO_APICS];
+
+
+static int __init mp_find_ioapic (
+	int			irq)
+{
+	int			i = 0;
+
+	/* Find the IOAPIC that manages this IRQ. */
+	for (i = 0; i < nr_ioapics; i++) {
+		if ((irq >= mp_ioapic_routing[i].irq_start)
+			&& (irq <= mp_ioapic_routing[i].irq_end))
+			return i;
+	}
+
+	printk(KERN_ERR "ERROR: Unable to locate IOAPIC for IRQ %d/n", irq);
+
+	return -1;
+}
+	
+
+void __init mp_register_ioapic (
+	u8			id, 
+	u32			address,
+	u32			irq_base)
+{
+	int			idx = 0;
+
+	if (nr_ioapics >= MAX_IO_APICS) {
+		printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
+			"(found %d)\n", MAX_IO_APICS, nr_ioapics);
+		panic("Recompile kernel with bigger MAX_IO_APICS!\n");
+	}
+	if (!address) {
+		printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
+			" found in MADT table, skipping!\n");
+		return;
+	}
+
+	idx = nr_ioapics++;
+
+	mp_ioapics[idx].mpc_type = MP_IOAPIC;
+	mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE;
+	mp_ioapics[idx].mpc_apicaddr = address;
+
+	set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
+	mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
+	mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
+	
+	/* 
+	 * Build basic IRQ lookup table to facilitate irq->io_apic lookups
+	 * and to prevent reprogramming of IOAPIC pins (PCI IRQs).
+	 */
+	mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mpc_apicid;
+	mp_ioapic_routing[idx].irq_start = irq_base;
+	mp_ioapic_routing[idx].irq_end = irq_base + 
+		io_apic_get_redir_entries(idx);
+
+	printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
+		"IRQ %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, 
+		mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
+		mp_ioapic_routing[idx].irq_start,
+		mp_ioapic_routing[idx].irq_end);
+
+	return;
+}
+
+
+void __init mp_override_legacy_irq (
+	u8			bus_irq,
+	u8			polarity, 
+	u8			trigger, 
+	u32			global_irq)
+{
+	struct mpc_config_intsrc intsrc;
+	int			i = 0;
+	int			found = 0;
+	int			ioapic = -1;
+	int			pin = -1;
+
+	/* 
+	 * Convert 'global_irq' to 'ioapic.pin'.
+	 */
+	ioapic = mp_find_ioapic(global_irq);
+	if (ioapic < 0)
+		return;
+	pin = global_irq - mp_ioapic_routing[ioapic].irq_start;
+
+	/*
+	 * TBD: This check is for faulty timer entries, where the override
+	 *      erroneously sets the trigger to level, resulting in a HUGE 
+	 *      increase of timer interrupts!
+	 */
+	if ((bus_irq == 0) && (global_irq == 2) && (trigger == 3))
+		trigger = 1;
+
+	intsrc.mpc_type = MP_INTSRC;
+	intsrc.mpc_irqtype = mp_INT;
+	intsrc.mpc_irqflag = (trigger << 2) | polarity;
+	intsrc.mpc_srcbus = MP_ISA_BUS;
+	intsrc.mpc_srcbusirq = bus_irq;				       /* IRQ */
+	intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid;	   /* APIC ID */
+	intsrc.mpc_dstirq = pin;				    /* INTIN# */
+
+	Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, %d-%d\n",
+		intsrc.mpc_irqtype, intsrc.mpc_irqflag & 3, 
+		(intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, 
+		intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq);
+
+	/* 
+	 * If an existing [IOAPIC.PIN -> IRQ] routing entry exists we override it.
+	 * Otherwise create a new entry (e.g. global_irq == 2).
+	 */
+	for (i = 0; i < mp_irq_entries; i++) {
+		if ((mp_irqs[i].mpc_dstapic == intsrc.mpc_dstapic) 
+			&& (mp_irqs[i].mpc_dstirq == intsrc.mpc_dstirq)) {
+			mp_irqs[i] = intsrc;
+			found = 1;
+			break;
+		}
+	}
+	if (!found) {
+		mp_irqs[mp_irq_entries] = intsrc;
+		if (++mp_irq_entries == MAX_IRQ_SOURCES)
+			panic("Max # of irq sources exceeded!\n");
+	}
+
+	return;
+}
+
+
+void __init mp_config_acpi_legacy_irqs (void)
+{
+	int			i = 0;
+	int			ioapic = -1;
+
+	/*
+	 * Initialize mp_irqs for IRQ configuration.
+	 */
+	unsigned char *bus_data;
+	int count;
+
+	count = (MAX_MP_BUSSES * sizeof(int)) * 4;
+	count += (MAX_IRQ_SOURCES * sizeof(int)) * 4;
+	bus_data = alloc_bootmem(count);
+	if (!bus_data) {
+		panic("Fatal: can't allocate bus memory for ACPI legacy IRQ!");
+	}
+	mp_bus_id_to_type = (int *)&bus_data[0];
+	mp_bus_id_to_node = (int *)&bus_data[(MAX_MP_BUSSES * sizeof(int))];
+	mp_bus_id_to_local = (int *)&bus_data[(MAX_MP_BUSSES * sizeof(int)) * 2];
+	mp_bus_id_to_pci_bus = (int *)&bus_data[(MAX_MP_BUSSES * sizeof(int)) * 3];
+	mp_irqs = (struct mpc_config_intsrc *)&bus_data[(MAX_MP_BUSSES * sizeof(int)) * 4];
+	memset(mp_bus_id_to_pci_bus, -1, MAX_MP_BUSSES);
+
+	/* 
+	 * Fabricate the legacy ISA bus (bus #31).
+	 */
+	mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA;
+	Dprintk("Bus #%d is ISA\n", MP_ISA_BUS);
+
+	/* 
+	 * Locate the IOAPIC that manages the ISA IRQs (0-15). 
+	 */
+	ioapic = mp_find_ioapic(0);
+	if (ioapic < 0)
+		return;
+
+	/* 
+	 * Use the default configuration for the IRQs 0-15.  These may be
+	 * overriden by (MADT) interrupt source override entries.
+	 */
+	for (i = 0; i < 16; i++) {
+
+		if (i == 2) continue;			/* Don't connect IRQ2 */
+
+		mp_irqs[mp_irq_entries].mpc_type = MP_INTSRC;
+		mp_irqs[mp_irq_entries].mpc_irqflag = 0;	/* Conforming */
+		mp_irqs[mp_irq_entries].mpc_srcbus = MP_ISA_BUS;
+		mp_irqs[mp_irq_entries].mpc_dstapic = mp_ioapics[ioapic].mpc_apicid;
+		mp_irqs[mp_irq_entries].mpc_irqtype = i ? mp_INT : mp_ExtINT;   /* 8259A to #0 */
+		mp_irqs[mp_irq_entries].mpc_srcbusirq = i;	   /* Identity mapped */
+		mp_irqs[mp_irq_entries].mpc_dstirq = i;
+
+		Dprintk("Int: type %d, pol %d, trig %d, bus %d, irq %d, "
+			"%d-%d\n", 
+			mp_irqs[mp_irq_entries].mpc_irqtype, 
+			mp_irqs[mp_irq_entries].mpc_irqflag & 3, 
+			(mp_irqs[mp_irq_entries].mpc_irqflag >> 2) & 3, 
+			mp_irqs[mp_irq_entries].mpc_srcbus, 
+			mp_irqs[mp_irq_entries].mpc_srcbusirq, 
+			mp_irqs[mp_irq_entries].mpc_dstapic, 
+			mp_irqs[mp_irq_entries].mpc_dstirq);
+
+		if (++mp_irq_entries == MAX_IRQ_SOURCES)
+			panic("Max # of irq sources exceeded!\n");
+	}
+}
+
+/* Ensure the ACPI SCI interrupt level is active low, edge-triggered */
+
+extern FADT_DESCRIPTOR acpi_fadt;
+
+void __init mp_config_ioapic_for_sci(int irq)
+{
+	int ioapic;
+	int ioapic_pin;
+	struct acpi_table_madt* madt;
+	struct acpi_table_int_src_ovr *entry = NULL;
+	void *madt_end;
+	acpi_status status;
+
+	/*
+	 * Ensure that if there is an interrupt source override entry
+	 * for the ACPI SCI, we leave it as is. Unfortunately this involves
+	 * walking the MADT again.
+	 */
+	status = acpi_get_firmware_table("APIC", 1, ACPI_LOGICAL_ADDRESSING,
+		(struct acpi_table_header **) &madt);
+	if (ACPI_SUCCESS(status)) {
+		madt_end = (void *) (unsigned long)madt + madt->header.length;
+
+		entry = (struct acpi_table_int_src_ovr *)
+                ((unsigned long) madt + sizeof(struct acpi_table_madt));
+
+		while ((void *) entry < madt_end) {
+                	if (entry->header.type == ACPI_MADT_INT_SRC_OVR &&
+			    acpi_fadt.sci_int == entry->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;
+			}
+
+                	entry = (struct acpi_table_int_src_ovr *)
+                	        ((unsigned long) entry + entry->header.length);
+        	}
+	}
+
+	ioapic = mp_find_ioapic(irq);
+
+	ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
+
+	io_apic_set_pci_routing(ioapic, ioapic_pin, irq);
+}
+
+
+#ifdef CONFIG_ACPI_PCI
+
+void __init mp_parse_prt (void)
+{
+	struct list_head	*node = NULL;
+	struct acpi_prt_entry	*entry = NULL;
+	int			ioapic = -1;
+	int			ioapic_pin = 0;
+	int			irq = 0;
+	int			idx, bit = 0;
+
+	/*
+	 * Parsing through the PCI Interrupt Routing Table (PRT) and program
+	 * routing for all entries.
+	 */
+	list_for_each(node, &acpi_prt.entries) {
+		entry = list_entry(node, struct acpi_prt_entry, node);
+
+		/* Need to get irq for dynamic entry */
+		if (entry->link.handle) {
+			irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index);
+			if (!irq)
+				continue;
+		}
+		else
+			irq = entry->link.index;
+
+		/* Don't set up the ACPI SCI because it's already set up */
+		if (acpi_fadt.sci_int == irq)
+			continue;
+	
+		ioapic = mp_find_ioapic(irq);
+		if (ioapic < 0)
+			continue;
+		ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
+
+		/* 
+		 * Avoid pin reprogramming.  PRTs typically include entries  
+		 * with redundant pin->irq mappings (but unique PCI devices);
+		 * we only only program the IOAPIC on the first.
+		 */
+		bit = ioapic_pin % 32;
+		idx = (ioapic_pin < 32) ? 0 : (ioapic_pin / 32);
+		if (idx > 3) {
+			printk(KERN_ERR "Invalid reference to IOAPIC pin "
+				"%d-%d\n", mp_ioapic_routing[ioapic].apic_id, 
+				ioapic_pin);
+			continue;
+		}
+		if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
+			printk(KERN_DEBUG "Pin %d-%d already programmed\n",
+				mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
+			entry->irq = irq;
+			continue;
+		}
+
+		mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
+
+		if (!io_apic_set_pci_routing(ioapic, ioapic_pin, irq))
+			entry->irq = irq;
+
+		printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n",
+			entry->id.segment, entry->id.bus, 
+			entry->id.device, ('A' + entry->pin), 
+			mp_ioapic_routing[ioapic].apic_id, ioapic_pin, 
+			entry->irq);
+	}
+	
+	return;
+}
+
+#endif /*CONFIG_ACPI_PCI*/
+
+#endif /*CONFIG_X86_IO_APIC*/
+
+#endif /*CONFIG_ACPI_BOOT*/
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/pci-irq.c linux-2.4.22-pre10/arch/i386/kernel/pci-irq.c
--- linux-2.4.21/arch/i386/kernel/pci-irq.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/pci-irq.c	2003-08-01 13:34:53.000000000 +0000
@@ -116,7 +116,7 @@
  *  Code for querying and setting of IRQ routes on various interrupt routers.
  */
 
-static void eisa_set_level_irq(unsigned int irq)
+void eisa_set_level_irq(unsigned int irq)
 {
 	unsigned char mask = 1 << (irq & 7);
 	unsigned int port = 0x4d0 + (irq >> 3);
@@ -196,15 +196,16 @@
 /*
  * The VIA pirq rules are nibble-based, like ALI,
  * but without the ugly irq number munging.
+ * However, PIRQD is in the upper instead of lower nibble.
  */
 static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
 {
-	return read_config_nybble(router, 0x55, pirq);
+	return read_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq);
 }
 
 static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
 {
-	write_config_nybble(router, 0x55, pirq, irq);
+	write_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq, irq);
 	return 1;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/pci-pc.c linux-2.4.22-pre10/arch/i386/kernel/pci-pc.c
--- linux-2.4.21/arch/i386/kernel/pci-pc.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/pci-pc.c	2003-08-01 13:32:52.000000000 +0000
@@ -11,6 +11,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/acpi.h>
 
 #include <asm/segment.h>
 #include <asm/io.h>
@@ -28,6 +29,8 @@
 int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL;
 int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL;
 
+static int pci_using_acpi_prt = 0;
+
 #ifdef CONFIG_MULTIQUAD
 #define BUS2QUAD(global) (mp_bus_id_to_node[global])
 #define BUS2LOCAL(global) (mp_bus_id_to_local[global])
@@ -1353,6 +1356,23 @@
 	pci_read_bridge_bases(b);
 }
 
+struct pci_bus * __devinit pcibios_scan_root(int busnum)
+{
+	struct list_head *list;
+	struct pci_bus *bus;
+
+	list_for_each(list, &pci_root_buses) {
+		bus = pci_bus_b(list);
+		if (bus->number == busnum) {
+			/* Already scanned */
+			return bus;
+		}
+	}
+
+	printk("PCI: Probing PCI hardware (bus %02x)\n", busnum);
+
+	return pci_scan_bus(busnum, pci_root_ops, NULL);
+}
 
 void __devinit pcibios_config_init(void)
 {
@@ -1394,6 +1414,8 @@
 	return;
 }
 
+int use_acpi_pci __initdata = 1;
+
 void __init pcibios_init(void)
 {
 	int quad;
@@ -1406,7 +1428,19 @@
 	}
 
 	printk(KERN_INFO "PCI: Probing PCI hardware\n");
-	pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
+#ifdef CONFIG_ACPI_PCI
+	if (use_acpi_pci && !acpi_pci_irq_init()) {
+		pci_using_acpi_prt = 1;
+		printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
+		printk(KERN_INFO "PCI: if you experience problems, try using option 'pci=noacpi' or even 'acpi=off'\n");
+	}
+#endif
+	if (!pci_using_acpi_prt) {
+		pci_root_bus = pcibios_scan_root(0);
+		pcibios_irq_init();
+		pcibios_fixup_peer_bridges();
+		pcibios_fixup_irqs();
+	}
 	if (clustered_apic_mode && (numnodes > 1)) {
 		for (quad = 1; quad < numnodes; ++quad) {
 			printk("Scanning PCI bus %d for quad %d\n", 
@@ -1416,9 +1450,6 @@
 		}
 	}
 
-	pcibios_irq_init();
-	pcibios_fixup_peer_bridges();
-	pcibios_fixup_irqs();
 	pcibios_resource_survey();
 
 #ifdef CONFIG_PCI_BIOS
@@ -1470,6 +1501,9 @@
 	} else if (!strncmp(str, "lastbus=", 8)) {
 		pcibios_last_bus = simple_strtol(str+8, NULL, 0);
 		return NULL;
+	} else if (!strncmp(str, "noacpi", 6)) {
+		use_acpi_pci = 0;
+		return NULL;
 	}
 	return str;
 }
@@ -1485,6 +1519,15 @@
 
 	if ((err = pcibios_enable_resources(dev, mask)) < 0)
 		return err;
+
+#ifdef CONFIG_ACPI_PCI
+	if (pci_using_acpi_prt) {
+		acpi_pci_irq_enable(dev);
+		return 0;
+	}
+#endif
+
 	pcibios_enable_irq(dev);
+
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/process.c linux-2.4.22-pre10/arch/i386/kernel/process.c
--- linux-2.4.21/arch/i386/kernel/process.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/process.c	2003-08-01 13:30:27.000000000 +0000
@@ -253,7 +253,7 @@
 	0x66, 0x0f, 0x20, 0xc3,			/*    movl  %cr0,%ebx        */
 	0x66, 0x81, 0xe3, 0x00, 0x00, 0x00, 0x60,	/*    andl  $0x60000000,%ebx */
 	0x74, 0x02,				/*    jz    f                */
-	0x0f, 0x08,				/*    invd                   */
+	0x0f, 0x09,				/*    wbinvd                 */
 	0x24, 0x10,				/* f: andb  $0x10,al         */
 	0x66, 0x0f, 0x22, 0xc0			/*    movl  %eax,%cr0        */
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/setup.c linux-2.4.22-pre10/arch/i386/kernel/setup.c
--- linux-2.4.21/arch/i386/kernel/setup.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/setup.c	2003-08-01 13:33:14.000000000 +0000
@@ -95,6 +95,7 @@
 #include <linux/delay.h>
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
 #include <linux/apm_bios.h>
 #ifdef CONFIG_BLK_DEV_RAM
 #include <linux/blk.h>
@@ -106,6 +107,7 @@
 #include <linux/seq_file.h>
 #include <asm/processor.h>
 #include <linux/console.h>
+#include <linux/module.h>
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -172,9 +174,15 @@
 static int disable_x86_serial_nr __initdata = 1;
 static int disable_x86_ht __initdata = 0;
 static u32 disabled_x86_caps[NCAPINTS] __initdata = { 0 };
-extern int blk_nohighio;
 
-int enable_acpi_smp_table;
+#ifdef CONFIG_ACPI_HT_ONLY
+int acpi_disabled = 1;
+#else
+int acpi_disabled = 0;
+#endif
+EXPORT_SYMBOL(acpi_disabled);
+
+extern int blk_nohighio;
 
 /*
  * This is set up by the setup-routine at boot-time
@@ -782,6 +790,12 @@
 				if (*from == '@') {
 					start_at = memparse(from+1, &from);
 					add_memory_region(start_at, mem_size, E820_RAM);
+				} else if (*from == '#') {
+					start_at = memparse(from+1, &from);
+					add_memory_region(start_at, mem_size, E820_ACPI);
+				} else if (*from == '$') {
+					start_at = memparse(from+1, &from);
+					add_memory_region(start_at, mem_size, E820_RESERVED);
 				} else {
 					limit_regions(mem_size);
 					userdef=1;
@@ -795,9 +809,13 @@
 			set_bit(X86_FEATURE_HT, disabled_x86_caps);
 		}
 
-		/* "acpismp=force" forces parsing and use of the ACPI SMP table */
+		/* "acpi=off" disables both ACPI table parsing and interpreter init */
+		else if (!memcmp(from, "acpi=off", 8))
+			acpi_disabled = 1;
+
+		/* "acpismp=force" turns on ACPI again */
 		else if (!memcmp(from, "acpismp=force", 13))
-			enable_acpi_smp_table = 1;
+			acpi_disabled = 0;
 
 		/*
 		 * highmem=size forces highmem to be exactly 'size' bytes.
@@ -1007,10 +1025,15 @@
 	 */
 	reserve_bootmem(PAGE_SIZE, PAGE_SIZE);
 #endif
-
+#ifdef CONFIG_ACPI_SLEEP
+	/*
+	 * Reserve low memory region for sleep support.
+	 */
+	acpi_reserve_bootmem();
+#endif
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
-	 * Find and reserve possible boot-time SMP configuration:
+	 * Find and reserve possible boot-time SMP configuration.
 	 */
 	find_smp_config();
 #endif
@@ -1043,7 +1066,6 @@
 {
 	unsigned long low_mem_size;
 	int i;
-
 	probe_roms();
 	for (i = 0; i < e820.nr_map; i++) {
 		struct resource *res;
@@ -1129,21 +1151,10 @@
 
 	max_low_pfn = setup_memory();
 
-	/*
-	 * If enable_acpi_smp_table and HT feature present, acpitable.c
-	 * will find all logical cpus despite disable_x86_ht: so if both
-	 * "noht" and "acpismp=force" are specified, let "noht" override
-	 * "acpismp=force" cleanly.  Why retain "acpismp=force"? because
-	 * parsing ACPI SMP table might prove useful on some non-HT cpu.
-	 */
 	if (disable_x86_ht) {
 		clear_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]);
 		set_bit(X86_FEATURE_HT, disabled_x86_caps);
-		enable_acpi_smp_table = 0;
 	}
-	if (test_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]))
-		enable_acpi_smp_table = 1;
-	
 
 	/*
 	 * NOTE: before this point _nobody_ is allowed to allocate
@@ -1154,6 +1165,13 @@
 	smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
 #endif
 	paging_init();
+#ifdef CONFIG_ACPI
+	/*
+	 * Parse the ACPI tables for possible boot-time SMP configuration.
+	 */
+	if (!acpi_disabled)
+		acpi_boot_init();
+#endif
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
 	 * get boot-time SMP configuration:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/sys_i386.c linux-2.4.22-pre10/arch/i386/kernel/sys_i386.c
--- linux-2.4.21/arch/i386/kernel/sys_i386.c	2001-03-19 20:35:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/sys_i386.c	2003-08-01 13:33:03.000000000 +0000
@@ -139,7 +139,10 @@
 
 	switch (call) {
 	case SEMOP:
-		return sys_semop (first, (struct sembuf *)ptr, second);
+		return sys_semtimedop (first, (struct sembuf *)ptr, second, NULL);
+	case SEMTIMEDOP:
+		return sys_semtimedop (first, (struct sembuf *)ptr, second, 
+				       (const struct timespec *)fifth);
 	case SEMGET:
 		return sys_semget (first, second, third);
 	case SEMCTL: {
@@ -200,7 +203,7 @@
 		return sys_shmctl (first, second,
 				   (struct shmid_ds *) ptr);
 	default:
-		return -EINVAL;
+		return -ENOSYS;
 	}
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/kernel/vm86.c linux-2.4.22-pre10/arch/i386/kernel/vm86.c
--- linux-2.4.21/arch/i386/kernel/vm86.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/kernel/vm86.c	2003-08-01 13:31:08.000000000 +0000
@@ -362,6 +362,9 @@
 
 	if (VEFLAGS & VIF_MASK)
 		flags |= IF_MASK;
+	else
+		flags &= ~IF_MASK;
+	flags |= IOPL_MASK;
 	return flags | (VEFLAGS & current->thread.v86mask);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/math-emu/fpu_trig.c linux-2.4.22-pre10/arch/i386/math-emu/fpu_trig.c
--- linux-2.4.21/arch/i386/math-emu/fpu_trig.c	2001-06-12 18:06:54.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/math-emu/fpu_trig.c	2003-08-01 13:30:43.000000000 +0000
@@ -1058,7 +1058,7 @@
 	return;
       goto fprem_valid;
     }
-  else if ( (st0_tag == TAG_Empty) | (st1_tag == TAG_Empty) )
+  else if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
     {
       FPU_stack_underflow();
       return;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/i386/math-emu/poly.h linux-2.4.22-pre10/arch/i386/math-emu/poly.h
--- linux-2.4.21/arch/i386/math-emu/poly.h	2001-07-26 20:37:38.000000000 +0000
+++ linux-2.4.22-pre10/arch/i386/math-emu/poly.h	2003-08-01 13:30:38.000000000 +0000
@@ -64,7 +64,7 @@
 				      const unsigned long arg2)
 {
   int retval;
-  asm volatile ("mull %2; movl %%edx,%%eax" \
+  asm volatile ("mull %2; movl %%edx,%%eax; " \
 		:"=a" (retval) \
 		:"0" (arg1), "g" (arg2) \
 		:"dx");
@@ -75,11 +75,11 @@
 /* Add the 12 byte Xsig x2 to Xsig dest, with no checks for overflow. */
 static inline void add_Xsig_Xsig(Xsig *dest, const Xsig *x2)
 {
-  asm volatile ("movl %1,%%edi; movl %2,%%esi;
-                 movl (%%esi),%%eax; addl %%eax,(%%edi);
-                 movl 4(%%esi),%%eax; adcl %%eax,4(%%edi);
-                 movl 8(%%esi),%%eax; adcl %%eax,8(%%edi);"
-                 :"=g" (*dest):"g" (dest), "g" (x2)
+  asm volatile ("movl %1,%%edi; movl %2,%%esi; " \
+                 "movl (%%esi),%%eax; addl %%eax,(%%edi); " \
+                 "movl 4(%%esi),%%eax; adcl %%eax,4(%%edi); " \
+                 "movl 8(%%esi),%%eax; adcl %%eax,8(%%edi); " \
+                 :"=g" (*dest):"g" (dest), "g" (x2) \
                  :"ax","si","di");
 }
 
@@ -90,19 +90,19 @@
    problem, but keep fingers crossed! */
 static inline void add_two_Xsig(Xsig *dest, const Xsig *x2, long int *exp)
 {
-  asm volatile ("movl %2,%%ecx; movl %3,%%esi;
-                 movl (%%esi),%%eax; addl %%eax,(%%ecx);
-                 movl 4(%%esi),%%eax; adcl %%eax,4(%%ecx);
-                 movl 8(%%esi),%%eax; adcl %%eax,8(%%ecx);
-                 jnc 0f;
-		 rcrl 8(%%ecx); rcrl 4(%%ecx); rcrl (%%ecx)
-                 movl %4,%%ecx; incl (%%ecx)
-                 movl $1,%%eax; jmp 1f;
-                 0: xorl %%eax,%%eax;
-                 1:"
-		:"=g" (*exp), "=g" (*dest)
-		:"g" (dest), "g" (x2), "g" (exp)
-		:"cx","si","ax");
+  asm volatile ("movl %2,%%ecx; movl %3,%%esi; " \
+                 "movl (%%esi),%%eax; addl %%eax,(%%ecx); " \
+                 "movl 4(%%esi),%%eax; adcl %%eax,4(%%ecx); " \
+                 "movl 8(%%esi),%%eax; adcl %%eax,8(%%ecx); " \
+                 "jnc 0f; " \
+		 "rcrl 8(%%ecx); rcrl 4(%%ecx); rcrl (%%ecx); " \
+                 "movl %4,%%ecx; incl (%%ecx); " \
+                 "movl $1,%%eax; jmp 1f; " \
+                 "0: xorl %%eax,%%eax; " \
+                 "1: " \
+		:"=g" (*exp), "=g" (*dest) \
+		:"g" (dest), "g" (x2), "g" (exp) \
+		:"cx","si","ax"); 
 }
 
 
@@ -110,11 +110,11 @@
 /* This is faster in a loop on my 386 than using the "neg" instruction. */
 static inline void negate_Xsig(Xsig *x)
 {
-  asm volatile("movl %1,%%esi; "
-               "xorl %%ecx,%%ecx; "
-               "movl %%ecx,%%eax; subl (%%esi),%%eax; movl %%eax,(%%esi); "
-               "movl %%ecx,%%eax; sbbl 4(%%esi),%%eax; movl %%eax,4(%%esi); "
-               "movl %%ecx,%%eax; sbbl 8(%%esi),%%eax; movl %%eax,8(%%esi); "
+  asm volatile("movl %1,%%esi; " \
+               "xorl %%ecx,%%ecx; " \
+               "movl %%ecx,%%eax; subl (%%esi),%%eax; movl %%eax,(%%esi); " \
+               "movl %%ecx,%%eax; sbbl 4(%%esi),%%eax; movl %%eax,4(%%esi); " \
+               "movl %%ecx,%%eax; sbbl 8(%%esi),%%eax; movl %%eax,8(%%esi); " \
                :"=g" (*x):"g" (x):"si","ax","cx");
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/Makefile linux-2.4.22-pre10/arch/ia64/Makefile
--- linux-2.4.21/arch/ia64/Makefile	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/Makefile	2003-08-01 13:30:45.000000000 +0000
@@ -132,6 +132,9 @@
 archclean:
 	@$(MAKEBOOT) clean
 
+check: vmlinux
+	arch/ia64/scripts/unwcheck.sh vmlinux
+
 archmrproper:
 	rm -f arch/$(ARCH)/vmlinux.lds
 	@$(MAKE) -C arch/$(ARCH)/tools mrproper
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/config.in linux-2.4.22-pre10/arch/ia64/config.in
--- linux-2.4.21/arch/ia64/config.in	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/config.in	2003-08-01 13:33:23.000000000 +0000
@@ -23,8 +23,8 @@
 define_bool CONFIG_EISA n
 define_bool CONFIG_MCA n
 define_bool CONFIG_SBUS n
-define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
-define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
 
 choice 'IA-64 processor type' \
 	"Itanium		CONFIG_ITANIUM \
@@ -179,7 +179,7 @@
     bool 'Network device support' CONFIG_NETDEVICES
     if [ "$CONFIG_NETDEVICES" = "y" ]; then
       source drivers/net/Config.in
-      if [ "$CONFIG_ATM" = "y" ]; then
+      if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
          source drivers/atm/Config.in
       fi
     fi
@@ -242,6 +242,7 @@
 
   source drivers/usb/Config.in
 
+  source crypto/Config.in
   source lib/Config.in
 
   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/configs/dig linux-2.4.22-pre10/arch/ia64/configs/dig
--- linux-2.4.21/arch/ia64/configs/dig	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/configs/dig	2003-08-01 13:33:49.000000000 +0000
@@ -22,8 +22,8 @@
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ITANIUM=y
 # CONFIG_MCKINLEY is not set
 # CONFIG_IA64_GENERIC is not set
@@ -41,6 +41,14 @@
 CONFIG_IA64_MCA=y
 CONFIG_PM=y
 CONFIG_KCORE_ELF=y
+CONFIG_FORCE_MAX_ZONEORDER=19
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_16MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -243,7 +251,7 @@
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_ADMA100 is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
@@ -257,7 +265,6 @@
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -322,6 +329,7 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -623,6 +631,7 @@
 #
 # Video Adapters
 #
+# CONFIG_VIDEO_BT848 is not set
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_SAA5249 is not set
@@ -672,6 +681,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
+CONFIG_HUGETLBFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
@@ -874,6 +884,7 @@
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 
 #
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/configs/generic linux-2.4.22-pre10/arch/ia64/configs/generic
--- linux-2.4.21/arch/ia64/configs/generic	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/configs/generic	2003-08-01 13:30:57.000000000 +0000
@@ -22,8 +22,8 @@
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ITANIUM=y
 # CONFIG_MCKINLEY is not set
 CONFIG_IA64_GENERIC=y
@@ -41,6 +41,14 @@
 CONFIG_IA64_MCA=y
 CONFIG_PM=y
 CONFIG_KCORE_ELF=y
+CONFIG_FORCE_MAX_ZONEORDER=19
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_16MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -243,13 +251,13 @@
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_ADMA100 is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
-# CONFIG_BLK_DEV_CMD64X is not set
+CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
@@ -257,7 +265,6 @@
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -322,6 +329,7 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -628,6 +636,7 @@
 #
 # Video Adapters
 #
+# CONFIG_VIDEO_BT848 is not set
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_SAA5249 is not set
@@ -677,6 +686,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
+CONFIG_HUGETLBFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
@@ -879,6 +889,7 @@
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 
 #
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/configs/ski linux-2.4.22-pre10/arch/ia64/configs/ski
--- linux-2.4.21/arch/ia64/configs/ski	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/configs/ski	2003-08-01 13:31:56.000000000 +0000
@@ -22,8 +22,8 @@
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ITANIUM=y
 # CONFIG_MCKINLEY is not set
 # CONFIG_IA64_GENERIC is not set
@@ -39,6 +39,14 @@
 # CONFIG_ITANIUM_BSTEP_SPECIFIC is not set
 CONFIG_IA64_L1_CACHE_SHIFT=6
 CONFIG_KCORE_ELF=y
+CONFIG_FORCE_MAX_ZONEORDER=19
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_16MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -149,6 +157,7 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -274,6 +283,7 @@
 #
 # Video Adapters
 #
+# CONFIG_VIDEO_BT848 is not set
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_BWQCAM is not set
 # CONFIG_VIDEO_CQCAM is not set
@@ -326,6 +336,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
+CONFIG_HUGETLBFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/configs/zx1 linux-2.4.22-pre10/arch/ia64/configs/zx1
--- linux-2.4.21/arch/ia64/configs/zx1	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/configs/zx1	2003-08-01 13:34:27.000000000 +0000
@@ -22,8 +22,8 @@
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 # CONFIG_ITANIUM is not set
 CONFIG_MCKINLEY=y
 # CONFIG_IA64_GENERIC is not set
@@ -40,6 +40,16 @@
 CONFIG_IA64_MCA=y
 CONFIG_PM=y
 CONFIG_KCORE_ELF=y
+CONFIG_FORCE_MAX_ZONEORDER=19
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_HUGETLB_PAGE_SIZE_4GB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1GB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_16MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -242,7 +252,7 @@
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_ADMA100 is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
@@ -256,7 +266,6 @@
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -321,6 +330,7 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -622,6 +632,7 @@
 #
 # Video Adapters
 #
+# CONFIG_VIDEO_BT848 is not set
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_SAA5249 is not set
@@ -671,6 +682,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
+CONFIG_HUGETLBFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
@@ -873,6 +885,7 @@
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 
 #
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/defconfig linux-2.4.22-pre10/arch/ia64/defconfig
--- linux-2.4.21/arch/ia64/defconfig	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/defconfig	2003-08-01 13:31:05.000000000 +0000
@@ -22,8 +22,8 @@
 # CONFIG_EISA is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ITANIUM=y
 # CONFIG_MCKINLEY is not set
 CONFIG_IA64_GENERIC=y
@@ -41,6 +41,14 @@
 CONFIG_IA64_MCA=y
 CONFIG_PM=y
 CONFIG_KCORE_ELF=y
+CONFIG_FORCE_MAX_ZONEORDER=19
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_16MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
 CONFIG_SMP=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_PERFMON=y
@@ -243,13 +251,13 @@
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_ADMA100 is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
-# CONFIG_BLK_DEV_CMD64X is not set
+CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
@@ -257,7 +265,6 @@
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -322,6 +329,7 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -628,6 +636,7 @@
 #
 # Video Adapters
 #
+# CONFIG_VIDEO_BT848 is not set
 # CONFIG_VIDEO_PMS is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_SAA5249 is not set
@@ -677,6 +686,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
+CONFIG_HUGETLBFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
@@ -879,6 +889,7 @@
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 
 #
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/dig/machvec.c linux-2.4.22-pre10/arch/ia64/dig/machvec.c
--- linux-2.4.21/arch/ia64/dig/machvec.c	2000-08-12 02:09:06.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/dig/machvec.c	2003-08-01 13:30:28.000000000 +0000
@@ -1,2 +1,3 @@
-#define MACHVEC_PLATFORM_NAME	dig
+#define MACHVEC_PLATFORM_NAME		dig
+#define MACHVEC_PLATFORM_HEADER		<asm/machvec_dig.h>
 #include <asm/machvec_init.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/dig/setup.c linux-2.4.22-pre10/arch/ia64/dig/setup.c
--- linux-2.4.21/arch/ia64/dig/setup.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/dig/setup.c	2003-08-01 13:32:00.000000000 +0000
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1999 Intel Corp.
  * Copyright (C) 1999, 2001 Hewlett-Packard Co
- * Copyright (C) 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999, 2001, 2003 David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
@@ -56,7 +56,7 @@
 	if (!ia64_boot_param->console_info.num_rows
 	    || !ia64_boot_param->console_info.num_cols)
 	{
-		printk("dig_setup: warning: invalid screen-info, guessing 80x25\n");
+		printk(KERN_WARNING "dig_setup: warning: invalid screen-info, guessing 80x25\n");
 		orig_x = 0;
 		orig_y = 0;
 		num_cols = 80;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/hp/common/sba_iommu.c linux-2.4.22-pre10/arch/ia64/hp/common/sba_iommu.c
--- linux-2.4.21/arch/ia64/hp/common/sba_iommu.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/hp/common/sba_iommu.c	2003-08-01 13:33:48.000000000 +0000
@@ -1,8 +1,9 @@
 /*
 **  IA64 System Bus Adapter (SBA) I/O MMU manager
 **
-**	(c) Copyright 2002 Alex Williamson
-**	(c) Copyright 2002 Hewlett-Packard Company
+**	(c) Copyright 2002-2003 Alex Williamson
+**	(c) Copyright 2002-2003 Grant Grundler
+**	(c) Copyright 2002-2003 Hewlett-Packard Company
 **
 **	Portions (c) 2000 Grant Grundler (from parisc I/O MMU code)
 **	Portions (c) 1999 Dave S. Miller (from sparc64 I/O MMU code)
@@ -29,12 +30,14 @@
 #include <linux/string.h>
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/acpi.h>
 #include <linux/efi.h>
 
 #include <asm/delay.h>		/* ia64_get_itc() */
 #include <asm/io.h>
 #include <asm/page.h>		/* PAGE_OFFSET */
+#include <asm/system.h>		/* wmb() */
 
 
 #define PFX "IOC: "
@@ -206,7 +209,7 @@
 	/* Stuff we don't need in performance path */
 	struct ioc	*next;		/* list of IOC's in system */
 	acpi_handle	handle;		/* for multiple IOC's */
-	const char 	*name;
+	char		*name;
 	unsigned int	func_id;
 	unsigned int	rev;		/* HW revision of chip */
 	u32		iov_size;
@@ -217,11 +220,15 @@
 static struct ioc *ioc_list;
 static int reserve_sba_gart = 1;
 
-#define sba_sg_address(sg)	(sg->address ? sg->address : \
-				       page_address((sg)->page) + (sg)->offset)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define sba_sg_address(sg)	(page_address((sg)->page) + (sg)->offset)
+#else
+#define sba_sg_address(sg)	((sg)->address ? (sg)->address : \
+                                  page_address((sg)->page) + (sg)->offset)
+#endif
 
 #ifdef FULL_VALID_PDIR
-static void* prefetch_spill_page;
+static u64 prefetch_spill_page;
 #endif
 
 #define GET_IOC(dev)	((struct ioc *) PCI_CONTROLLER(dev)->iommu)
@@ -282,24 +289,23 @@
 sba_dump_pdir_entry(struct ioc *ioc, char *msg, uint pide)
 {
 	/* start printing from lowest pde in rval */
-	u64 *ptr = &(ioc->pdir_base[pide  & ~(BITS_PER_LONG - 1)]);
-	unsigned long *rptr = (unsigned long *) &(ioc->res_map[(pide >>3) & ~(sizeof(unsigned long) - 1)]);
+	u64 *ptr = &ioc->pdir_base[pide  & ~(BITS_PER_LONG - 1)];
+	unsigned long *rptr = (unsigned long *) &ioc->res_map[(pide >>3) & -sizeof(unsigned long)];
 	uint rcnt;
 
-	/* printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n", */
-	printk("SBA: %s rp %p bit %d rval 0x%lx\n",
+	printk(KERN_DEBUG "SBA: %s rp %p bit %d rval 0x%lx\n",
 		 msg, rptr, pide & (BITS_PER_LONG - 1), *rptr);
 
 	rcnt = 0;
 	while (rcnt < BITS_PER_LONG) {
-		printk("%s %2d %p %016Lx\n",
-			(rcnt == (pide & (BITS_PER_LONG - 1)))
-				? "    -->" : "       ",
-			rcnt, ptr, *ptr );
+		printk(KERN_DEBUG "%s %2d %p %016Lx\n",
+		       (rcnt == (pide & (BITS_PER_LONG - 1)))
+		       ? "    -->" : "       ",
+		       rcnt, ptr, (unsigned long long) *ptr );
 		rcnt++;
 		ptr++;
 	}
-	printk("%s", msg);
+	printk(KERN_DEBUG "%s", msg);
 }
 
 
@@ -361,12 +367,13 @@
 sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
 {
 	while (nents-- > 0) {
-		printk(" %d : %08lx/%05x %p\n",
-				nents, startsg->dma_address,
-				startsg->dma_length, sba_sg_address(startsg));
+		printk(KERN_DEBUG " %d : DMA %08lx/%05x CPU %p\n", nents,
+		       startsg->dma_address, startsg->dma_length,
+		       sba_sg_address(startsg));
 		startsg++;
 	}
 }
+
 static void
 sba_check_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
 {
@@ -397,7 +404,8 @@
 #define PAGES_PER_RANGE 1	/* could increase this to 4 or 8 if needed */
 
 /* Convert from IOVP to IOVA and vice versa. */
-#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((ioc->ibase) | (iovp) | (offset) | ((hint_reg)<<(ioc->hint_shift_pdir)))
+#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((ioc->ibase) | (iovp) | (offset) |		\
+					    ((hint_reg)<<(ioc->hint_shift_pdir)))
 #define SBA_IOVP(ioc,iova) (((iova) & ioc->hint_mask_pdir) & ~(ioc->ibase))
 
 /* FIXME : review these macros to verify correctness and usage */
@@ -520,7 +528,8 @@
 	if (pide >= (ioc->res_size << 3)) {
 		pide = sba_search_bitmap(ioc, pages_needed);
 		if (pide >= (ioc->res_size << 3))
-			panic(__FILE__ ": I/O MMU @ %lx is out of mapping resources\n", ioc->ioc_hpa);
+			panic(__FILE__ ": I/O MMU @ %p is out of mapping resources\n",
+			      ioc->ioc_hpa);
 	}
 
 #ifdef ASSERT_PDIR_SANITY
@@ -625,7 +634,8 @@
  */
 
 #if 1
-#define sba_io_pdir_entry(pdir_ptr, vba) *pdir_ptr = ((vba & ~0xE000000000000FFFULL) | 0x8000000000000000ULL)
+#define sba_io_pdir_entry(pdir_ptr, vba) *pdir_ptr = ((vba & ~0xE000000000000FFFULL)	\
+						      | 0x8000000000000000ULL)
 #else
 void SBA_INLINE
 sba_io_pdir_entry(u64 *pdir_ptr, unsigned long vba)
@@ -709,7 +719,7 @@
 		** the spill page so devices prefetching won't
 		** cause a hard fail.
 		*/
-		ioc->pdir_base[off] = (0x80000000000000FFULL | (u64)prefetch_spill_page);
+		ioc->pdir_base[off] = (0x80000000000000FFULL | prefetch_spill_page);
 #endif
 	} else {
 		u32 t = get_order(byte_cnt) + PAGE_SHIFT;
@@ -724,7 +734,7 @@
 			/* clear I/O Pdir entry "valid" bit first */
 			ioc->pdir_base[off] &= ~(0x80000000000000FFULL);
 #else
-			ioc->pdir_base[off] = (0x80000000000000FFULL | (u64)prefetch_spill_page);
+			ioc->pdir_base[off] = (0x80000000000000FFULL | prefetch_spill_page);
 #endif
 			off++;
 			byte_cnt -= IOVP_SIZE;
@@ -747,7 +757,7 @@
 sba_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
 {
 	struct ioc *ioc;
-	unsigned long flags; 
+	unsigned long flags;
 	dma_addr_t iovp;
 	dma_addr_t offset;
 	u64 *pdir_start;
@@ -816,6 +826,9 @@
 		size -= IOVP_SIZE;
 		pdir_start++;
 	}
+	/* force pdir update */
+	wmb();
+
 	/* form complete address */
 #ifdef ASSERT_PDIR_SANITY
 	sba_check_pdir(ioc,"Check after sba_map_single()");
@@ -840,7 +853,7 @@
 #if DELAYED_RESOURCE_CNT > 0
 	struct sba_dma_pair *d;
 #endif
-	unsigned long flags; 
+	unsigned long flags;
 	dma_addr_t offset;
 
 	ioc = GET_IOC(dev);
@@ -932,7 +945,7 @@
 	** we don't need the syncdma. The issue here is I/O MMU cachelines
 	** are *not* coherent in all cases.  May be hwrev dependent.
 	** Need to investigate more.
-	asm volatile("syncdma");	
+	asm volatile("syncdma");
 	*/
 }
 
@@ -1078,6 +1091,9 @@
 		}
 		startsg++;
 	}
+	/* force pdir update */
+	wmb();
+
 #ifdef DEBUG_LARGE_SG_ENTRIES
 	dump_run_sg = 0;
 #endif
@@ -1122,7 +1138,7 @@
 	int n_mappings = 0;
 
 	while (nents > 0) {
-		unsigned long vaddr = (unsigned long) sba_sg_address(startsg); 
+		unsigned long vaddr = (unsigned long) sba_sg_address(startsg);
 
 		/*
 		** Prepare for first/next DMA stream
@@ -1155,7 +1171,8 @@
 			** exceed DMA_CHUNK_SIZE if we coalesce the
 			** next entry.
 			*/
-			if (((dma_len + dma_offset + startsg->length + ~IOVP_MASK) & IOVP_MASK) > DMA_CHUNK_SIZE)
+			if (((dma_len + dma_offset + startsg->length + ~IOVP_MASK) & IOVP_MASK)
+			    > DMA_CHUNK_SIZE)
 				break;
 
 			/*
@@ -1214,7 +1231,7 @@
 		vcontig_sg->dma_length = vcontig_len;
 		dma_len = (dma_len + dma_offset + ~IOVP_MASK) & IOVP_MASK;
 		ASSERT(dma_len <= DMA_CHUNK_SIZE);
-		dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG 
+		dma_sg->dma_address = (dma_addr_t) (PIDE_FLAG
 			| (sba_alloc_range(ioc, dma_len) << IOVP_SHIFT)
 			| dma_offset);
 		n_mappings++;
@@ -1233,8 +1250,7 @@
  *
  * See Documentation/DMA-mapping.txt
  */
-int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents,
-		int direction)
+int sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
 {
 	struct ioc *ioc;
 	int coalesced, filled = 0;
@@ -1299,13 +1315,13 @@
 	** Access to the virtual address is what forces a two pass algorithm.
 	*/
 	coalesced = sba_coalesce_chunks(ioc, sglist, nents);
- 
+
 	/*
 	** Program the I/O Pdir
 	**
 	** map the virtual addresses to the I/O Pdir
 	** o dma_address will contain the pdir index
-	** o dma_len will contain the number of bytes to map 
+	** o dma_len will contain the number of bytes to map
 	** o address contains the virtual address.
 	*/
 	filled = sba_fill_pdir(ioc, sglist, nents);
@@ -1371,7 +1387,8 @@
 		** were coalesced to a single entry.  The stats are fun,
 		** but speed is more important.
 		*/
-		ioc->usg_pages += ((sglist->dma_address & ~IOVP_MASK) + sglist->dma_length + IOVP_SIZE - 1) >> PAGE_SHIFT;
+		ioc->usg_pages += ((sglist->dma_address & ~IOVP_MASK) + sglist->dma_length
+				   + IOVP_SIZE - 1) >> PAGE_SHIFT;
 #endif
 		sglist++;
 		nents--;
@@ -1387,12 +1404,6 @@
 
 }
 
-int
-sba_dma_supported (struct pci_dev *dev, u64 mask)
-{
-	return 1;
-}
-
 /**************************************************************
 *
 *   Initialization and claim
@@ -1418,19 +1429,6 @@
 	ioc->ibase = READ_REG(ioc->ioc_hpa + IOC_IBASE) & ~0x1UL;
 	ioc->iov_size = ~(READ_REG(ioc->ioc_hpa + IOC_IMASK) & 0xFFFFFFFFUL) + 1;
 
-	if (ioc->ibase == 0) {
-		if (((unsigned long) ioc->ioc_hpa & 0x3000UL) == 0x2000)
-			ioc->ibase = 0xc0000000;
-		else
-			ioc->ibase = 0x80000000;
-		printk("WARNING: IBASE is zero; setting to 0x%lx\n", ioc->ibase);
-	}
-
-	if (ioc->ibase < 0xfed00000UL && ioc->ibase + ioc->iov_size >= 0xfee00000UL) {
-		printk("WARNING: IOV space overlaps local config and interrupt message, truncating\n");
-		ioc->iov_size /= 2;
-	}
-
 	/*
 	** iov_order is always based on a 1GB IOVA space since we want to
 	** turn on the other half for AGP GART.
@@ -1438,9 +1436,9 @@
 	iov_order = get_order(ioc->iov_size >> (IOVP_SHIFT - PAGE_SHIFT));
 	ioc->pdir_size = (ioc->iov_size / IOVP_SIZE) * sizeof(u64);
 
-	DBG_INIT("%s() hpa 0x%lx IOV %dMB (%d bits) PDIR size 0x%0x\n",
-		__FUNCTION__, ioc->ioc_hpa, ioc->iov_size >> 20,
-		iov_order + PAGE_SHIFT, ioc->pdir_size);
+	DBG_INIT("%s() hpa %p IOV %dMB (%d bits) PDIR size 0x%x\n",
+		 __FUNCTION__, ioc->ioc_hpa, ioc->iov_size >> 20,
+		 iov_order + PAGE_SHIFT, ioc->pdir_size);
 
 	/* FIXME : DMA HINTs not used */
 	ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;
@@ -1520,7 +1518,8 @@
 		agp_found |= pci_find_capability(device, PCI_CAP_ID_AGP);
 
 	if (agp_found && reserve_sba_gart) {
-		DBG_INIT("%s: AGP device found, reserving half of IOVA for GART support\n", __FUNCTION__);
+		DBG_INIT("%s: AGP device found, reserving half of IOVA for GART support\n",
+			 __FUNCTION__);
 		ioc->pdir_size /= 2;
 		((u64 *)ioc->pdir_base)[PDIR_INDEX(ioc->iov_size/2)] = ZX1_SBA_IOMMU_COOKIE;
 	}
@@ -1532,26 +1531,27 @@
 	if (!prefetch_spill_page) {
 		char *spill_poison = "SBAIOMMU POISON";
 		int poison_size = 16;
-		void *poison_addr;
-									
-		prefetch_spill_page = (void *)__get_free_pages(GFP_KERNEL, get_order(IOVP_SIZE));
-		if (!prefetch_spill_page)
+		void *poison_addr, *addr;
+
+		addr = (void *)__get_free_pages(GFP_KERNEL, get_order(IOVP_SIZE));
+		if (!addr)
 			panic(PFX "Couldn't allocate PDIR spill page\n");
 
-		poison_addr = prefetch_spill_page;
-		for (; (u64)poison_addr < (u64)prefetch_spill_page + IOVP_SIZE ; poison_addr += poison_size)
-			(void)memcpy(poison_addr,spill_poison,poison_size);
+		poison_addr = addr;
+		for ( ; (u64) poison_addr < addr + IOVP_SIZE; poison_addr += poison_size)
+			memcpy(poison_addr, spill_poison, poison_size);
 
-		prefetch_spill_page = (void *)virt_to_phys(prefetch_spill_page);
+		prefetch_spill_page = virt_to_phys(addr);
 
-		DBG_INIT("%s() prefetch spill addr: %p\n", __FUNCTION__, prefetch_spill_page);
+		DBG_INIT("%s() prefetch spill addr: 0x%lx\n", __FUNCTION__, prefetch_spill_page);
 	}
 	/*
   	** Set all the PDIR entries valid w/ the spill page as the target
 	*/
 	for (index = 0 ; index < (ioc->pdir_size / sizeof(u64)) ; index++)
-		((u64 *)ioc->pdir_base)[index] = (0x80000000000000FFULL | (u64)prefetch_spill_page);
+		((u64 *)ioc->pdir_base)[index] = (0x80000000000000FF | prefetch_spill_page);
 #endif
+
 }
 
 static void __init
@@ -1581,7 +1581,8 @@
 #ifdef FULL_VALID_PDIR
 	/* Mark the last resource used so we don't prefetch beyond IOVA space */
 	ioc->res_map[ioc->res_size - 1] |= 0x80UL; /* res_map is chars */
-	ioc->pdir_base[(ioc->pdir_size / sizeof(u64)) - 1] = (0x80000000000000FFULL | (u64)prefetch_spill_page);
+	ioc->pdir_base[(ioc->pdir_size / sizeof(u64)) - 1] = (0x80000000000000FF
+							      | prefetch_spill_page);
 #endif
 
 	DBG_INIT("%s() res_map %x %p\n", __FUNCTION__,
@@ -1701,25 +1702,52 @@
 **************************************************************************/
 
 #ifdef CONFIG_PROC_FS
+static void *
+ioc_start(struct seq_file *s, loff_t *pos)
+{
+	struct ioc *ioc;
+	loff_t n = *pos;
+
+	for (ioc = ioc_list; ioc; ioc = ioc->next)
+		if (!n--)
+			return ioc;
+
+	return NULL;
+}
+
+static void *
+ioc_next(struct seq_file *s, void *v, loff_t *pos)
+{
+	struct ioc *ioc = v;
+
+	++*pos;
+	return ioc->next;
+}
+
+static void
+ioc_stop(struct seq_file *s, void *v)
+{
+}
+
 static int
-sba_proc_info_one(char *buf, struct ioc *ioc)
+ioc_show(struct seq_file *s, void *v)
 {
+	struct ioc *ioc = v;
 	int total_pages = (int) (ioc->res_size << 3); /* 8 bits per byte */
 	unsigned long i = 0, avg = 0, min, max;
 
-	sprintf(buf, "Hewlett Packard %s IOC rev %d.%d\n",
+	seq_printf(s, "Hewlett Packard %s IOC rev %d.%d\n",
 		ioc->name, ((ioc->rev >> 4) & 0xF), (ioc->rev & 0xF));
-	sprintf(buf, "%sIO PDIR size    : %d bytes (%d entries)\n",
-		buf,
+	seq_printf(s, "IO PDIR size    : %d bytes (%d entries)\n",
 		(int) ((ioc->res_size << 3) * sizeof(u64)), /* 8 bits/byte */
 		total_pages);
 
-	sprintf(buf, "%sIO PDIR entries : %ld free  %ld used (%d%%)\n", buf,
+	seq_printf(s, "IO PDIR entries : %ld free  %ld used (%d%%)\n",
 		total_pages - ioc->used_pages, ioc->used_pages,
 		(int) (ioc->used_pages * 100 / total_pages));
-	
-	sprintf(buf, "%sResource bitmap : %d bytes (%d pages)\n", 
-		buf, ioc->res_size, ioc->res_size << 3);   /* 8 bits per byte */
+
+	seq_printf(s, "Resource bitmap : %d bytes (%d pages)\n",
+		ioc->res_size, ioc->res_size << 3);   /* 8 bits per byte */
 
 	min = max = ioc->avg_search[0];
 	for (i = 0; i < SBA_SEARCH_SAMPLE; i++) {
@@ -1728,81 +1756,106 @@
 		if (ioc->avg_search[i] < min) min = ioc->avg_search[i];
 	}
 	avg /= SBA_SEARCH_SAMPLE;
-	sprintf(buf, "%s  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
-		buf, min, avg, max);
+	seq_printf(s, "  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
+		min, avg, max);
 
-	sprintf(buf, "%spci_map_single(): %12ld calls  %12ld pages (avg %d/1000)\n",
-		buf, ioc->msingle_calls, ioc->msingle_pages,
+	seq_printf(s, "pci_map_single(): %12ld calls  %12ld pages (avg %d/1000)\n",
+		ioc->msingle_calls, ioc->msingle_pages,
 		(int) ((ioc->msingle_pages * 1000)/ioc->msingle_calls));
 #ifdef ALLOW_IOV_BYPASS
-	sprintf(buf, "%spci_map_single(): %12ld bypasses\n",
-	        buf, ioc->msingle_bypass);
+	seq_printf(s, "pci_map_single(): %12ld bypasses\n", ioc->msingle_bypass);
 #endif
 
-	sprintf(buf, "%spci_unmap_single: %12ld calls  %12ld pages (avg %d/1000)\n",
-		buf, ioc->usingle_calls, ioc->usingle_pages,
+	seq_printf(s, "pci_unmap_single: %12ld calls  %12ld pages (avg %d/1000)\n",
+		ioc->usingle_calls, ioc->usingle_pages,
 		(int) ((ioc->usingle_pages * 1000)/ioc->usingle_calls));
 #ifdef ALLOW_IOV_BYPASS
-	sprintf(buf, "%spci_unmap_single: %12ld bypasses\n",
-	        buf, ioc->usingle_bypass);
+	seq_printf(s, "pci_unmap_single: %12ld bypasses\n", ioc->usingle_bypass);
 #endif
 
-	sprintf(buf, "%spci_map_sg()    : %12ld calls  %12ld pages (avg %d/1000)\n",
-		buf, ioc->msg_calls, ioc->msg_pages,
+	seq_printf(s, "pci_map_sg()    : %12ld calls  %12ld pages (avg %d/1000)\n",
+		ioc->msg_calls, ioc->msg_pages,
 		(int) ((ioc->msg_pages * 1000)/ioc->msg_calls));
 #ifdef ALLOW_IOV_BYPASS
-	sprintf(buf, "%spci_map_sg()    : %12ld bypasses\n",
-	        buf, ioc->msg_bypass);
+	seq_printf(s, "pci_map_sg()    : %12ld bypasses\n", ioc->msg_bypass);
 #endif
 
-	sprintf(buf, "%spci_unmap_sg()  : %12ld calls  %12ld pages (avg %d/1000)\n",
-		buf, ioc->usg_calls, ioc->usg_pages,
+	seq_printf(s, "pci_unmap_sg()  : %12ld calls  %12ld pages (avg %d/1000)\n",
+		ioc->usg_calls, ioc->usg_pages,
 		(int) ((ioc->usg_pages * 1000)/ioc->usg_calls));
 
-	return strlen(buf);
+	return 0;
 }
 
+static struct seq_operations ioc_seq_ops = {
+	.start = ioc_start,
+	.next  = ioc_next,
+	.stop  = ioc_stop,
+	.show  = ioc_show
+};
+
 static int
-sba_proc_info(char *buf, char **start, off_t offset, int len)
+ioc_open(struct inode *inode, struct file *file)
 {
-	struct ioc *ioc;
-	char *base = buf;
-
-	for (ioc = ioc_list; ioc; ioc = ioc->next) {
-		buf += sba_proc_info_one(buf, ioc);
-	}
-
-	return strlen(base);
+	return seq_open(file, &ioc_seq_ops);
 }
 
+static struct file_operations ioc_fops = {
+	.open    = ioc_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release
+};
+
 static int
-sba_resource_map_one(char *buf, struct ioc *ioc)
+ioc_map_show(struct seq_file *s, void *v)
 {
+	struct ioc *ioc = v;
 	unsigned int *res_ptr = (unsigned int *)ioc->res_map;
 	int i;
 
-	buf[0] = '\0';
-	for(i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr) {
-		if ((i & 7) == 0)
-		    strcat(buf,"\n   ");
-		sprintf(buf, "%s %08x", buf, *res_ptr);
-	}
-	strcat(buf, "\n");
+	for (i = 0; i < (ioc->res_size / sizeof(unsigned int)); ++i, ++res_ptr)
+		seq_printf(s, "%s%08x", (i & 7) ? " " : "\n    ", *res_ptr);
+	seq_printf(s, "\n");
 
-	return strlen(buf);
+	return 0;
 }
 
+static struct seq_operations ioc_map_ops = {
+	.start = ioc_start,
+	.next  = ioc_next,
+	.stop  = ioc_stop,
+	.show  = ioc_map_show
+};
+
 static int
-sba_resource_map(char *buf, char **start, off_t offset, int len)
+ioc_map_open(struct inode *inode, struct file *file)
 {
-	struct ioc *ioc;
-	char *base = buf;
+	return seq_open(file, &ioc_map_ops);
+}
 
-	for (ioc = ioc_list; ioc; ioc = ioc->next) {
-		buf += sba_resource_map_one(buf, ioc);
-	}
+static struct file_operations ioc_map_fops = {
+	.open    = ioc_map_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release
+};
 
-	return strlen(base);
+static void __init
+ioc_proc_init(void)
+{
+	if (ioc_list) {
+		struct proc_dir_entry *dir, *entry;
+
+		dir = proc_mkdir("bus/mckinley", 0);
+		entry = create_proc_entry(ioc_list->name, 0, dir);
+		if (entry)
+			entry->proc_fops = &ioc_fops;
+
+		entry = create_proc_entry("bitmap", 0, dir);
+		if (entry)
+			entry->proc_fops = &ioc_map_fops;
+	}
 }
 #endif
 
@@ -1833,7 +1886,7 @@
 		handle = parent;
 	} while (ACPI_SUCCESS(status));
 
-	printk("No IOC for %s in ACPI\n", dev->slot_name);
+	printk(KERN_WARNING "No IOC for %s in ACPI\n", dev->slot_name);
 }
 
 static int __init
@@ -1842,31 +1895,23 @@
 	struct ioc *ioc;
 	acpi_status status;
 	u64 hpa, length;
+	acpi_device_info dev_info;
 
-	/*
-	 * Only SBA appears in ACPI namespace.  It encloses the PCI
-	 * root bridges, and its CSR space includes the IOC function.
-	 */
 	status = acpi_hp_csr_space(device->handle, &hpa, &length);
 	if (ACPI_FAILURE(status))
 		return 1;
-	ioc = ioc_init(hpa + ZX1_IOC_OFFSET, device->handle);
-	if (!ioc)
-		return 1;
-
-	return 0;
-}
-
-static int __init
-acpi_ioc_add(struct acpi_device *device)
-{
-	struct ioc *ioc;
-	acpi_status status;
-	u64 hpa, length;
 
-	status = acpi_hp_csr_space(device->handle, &hpa, &length);
+	status = acpi_get_object_info(device->handle, &dev_info);
 	if (ACPI_FAILURE(status))
 		return 1;
+
+	/*
+	 * For HWP0001, only SBA appears in ACPI namespace.  It encloses the PCI
+	 * root bridges, and its CSR space includes the IOC function.
+	 */
+	if (strncmp("HWP0001", dev_info.hardware_id, 7) == 0)
+		hpa += ZX1_IOC_OFFSET;
+
 	ioc = ioc_init(hpa, device->handle);
 	if (!ioc)
 		return 1;
@@ -1876,40 +1921,19 @@
 
 static struct acpi_driver acpi_sba_ioc_driver = {
 	name:		"IOC IOMMU Driver",
-	ids:		"HWP0001",
+	ids:		"HWP0001,HWP0004",
 	ops: {
 		add:	acpi_sba_ioc_add,
      },
 };
 
-static struct acpi_driver acpi_ioc_driver = {
-	name:		"IOC IOMMU Driver",
-	ids:		"HWP0004",
-	ops: {
-		add:	acpi_ioc_add,
-     },
-};
-
-void __init
-ioc_acpi_init(void)
-{
-	acpi_bus_register_driver(&acpi_sba_ioc_driver);
-	acpi_bus_register_driver(&acpi_ioc_driver);
-}
-
 void __init
 sba_init(void)
 {
-	ioc_acpi_init();
+	acpi_bus_register_driver(&acpi_sba_ioc_driver);
 
 #ifdef CONFIG_PROC_FS
-	if (ioc_list) {
-		struct proc_dir_entry * proc_mckinley_root;
-
-		proc_mckinley_root = proc_mkdir("bus/mckinley",0);
-		create_proc_info_entry(ioc_list->name, 0, proc_mckinley_root, sba_proc_info);
-		create_proc_info_entry("bitmap", 0, proc_mckinley_root, sba_resource_map);
-	}
+	ioc_proc_init();
 #endif
 }
 
@@ -1920,6 +1944,13 @@
 	return 1;
 }
 
+int
+sba_dma_supported (struct pci_dev *dev, u64 mask)
+{
+	/* make sure it's at least 32bit capable */
+	return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL);
+}
+
 __setup("nosbagart", nosbagart);
 
 EXPORT_SYMBOL(sba_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/hp/sim/hpsim_console.c linux-2.4.22-pre10/arch/ia64/hp/sim/hpsim_console.c
--- linux-2.4.21/arch/ia64/hp/sim/hpsim_console.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/hp/sim/hpsim_console.c	2003-08-01 13:32:07.000000000 +0000
@@ -28,12 +28,12 @@
 static kdev_t simcons_console_device (struct console *);
 
 struct console hpsim_cons = {
-	name:		"simcons",
-	write:		simcons_write,
-	device:		simcons_console_device,
-	setup:		simcons_init,
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
+	.name =		"simcons",
+	.write =	simcons_write,
+	.device =	simcons_console_device,
+	.setup =	simcons_init,
+	.flags =	CON_PRINTBUFFER,
+	.index =	-1,
 };
 
 static int
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/hp/sim/hpsim_irq.c linux-2.4.22-pre10/arch/ia64/hp/sim/hpsim_irq.c
--- linux-2.4.21/arch/ia64/hp/sim/hpsim_irq.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/hp/sim/hpsim_irq.c	2003-08-01 13:33:21.000000000 +0000
@@ -22,14 +22,14 @@
 }
 
 static struct hw_interrupt_type irq_type_hp_sim = {
-	typename:	"hpsim",
-	startup:	hpsim_irq_startup,
-	shutdown:	hpsim_irq_noop,
-	enable:		hpsim_irq_noop,
-	disable:	hpsim_irq_noop,
-	ack:		hpsim_irq_noop,
-	end:		hpsim_irq_noop,
-	set_affinity:	(void (*)(unsigned int, unsigned long)) hpsim_irq_noop,
+	.typename =	"hpsim",
+	.startup =	hpsim_irq_startup,
+	.shutdown =	hpsim_irq_noop,
+	.enable =	hpsim_irq_noop,
+	.disable =	hpsim_irq_noop,
+	.ack =		hpsim_irq_noop,
+	.end =		hpsim_irq_noop,
+	.set_affinity =	(void (*)(unsigned int, unsigned long)) hpsim_irq_noop,
 };
 
 void __init
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/hp/sim/hpsim_machvec.c linux-2.4.22-pre10/arch/ia64/hp/sim/hpsim_machvec.c
--- linux-2.4.21/arch/ia64/hp/sim/hpsim_machvec.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/hp/sim/hpsim_machvec.c	2003-08-01 13:33:34.000000000 +0000
@@ -1,2 +1,3 @@
-#define MACHVEC_PLATFORM_NAME	hpsim
+#define MACHVEC_PLATFORM_NAME		hpsim
+#define MACHVEC_PLATFORM_HEADER		<asm/machvec_hpsim.h>
 #include <asm/machvec_init.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/hp/zx1/hpzx1_machvec.c linux-2.4.22-pre10/arch/ia64/hp/zx1/hpzx1_machvec.c
--- linux-2.4.21/arch/ia64/hp/zx1/hpzx1_machvec.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/hp/zx1/hpzx1_machvec.c	2003-08-01 13:34:42.000000000 +0000
@@ -1,2 +1,3 @@
-#define MACHVEC_PLATFORM_NAME	hpzx1
+#define MACHVEC_PLATFORM_NAME		hpzx1
+#define MACHVEC_PLATFORM_HEADER		<asm/machvec_hpzx1.h>
 #include <asm/machvec_init.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/ia32/binfmt_elf32.c linux-2.4.22-pre10/arch/ia64/ia32/binfmt_elf32.c
--- linux-2.4.21/arch/ia64/ia32/binfmt_elf32.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/ia32/binfmt_elf32.c	2003-08-01 13:34:38.000000000 +0000
@@ -67,7 +67,7 @@
 }
 
 static struct vm_operations_struct ia32_shared_page_vm_ops = {
-	nopage:	ia32_install_shared_page
+	.nopage =ia32_install_shared_page
 };
 
 void
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/ia32/ia32_entry.S linux-2.4.22-pre10/arch/ia64/ia32/ia32_entry.S
--- linux-2.4.21/arch/ia64/ia32/ia32_entry.S	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/ia32/ia32_entry.S	2003-08-01 13:33:35.000000000 +0000
@@ -87,12 +87,19 @@
 
 GLOBAL_ENTRY(ia32_ret_from_clone)
 	PT_REGS_UNWIND_INFO(0)
+{	/*
+	 * Some versions of gas generate bad unwind info if the first instruction of a
+	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
+	 */
+	nop.m 0
+	nop.i 0
 	/*
 	 * We need to call schedule_tail() to complete the scheduling process.
 	 * Called by ia64_switch_to after do_fork()->copy_thread().  r8 contains the
 	 * address of the previously executing task.
 	 */
 	br.call.sptk.many rp=ia64_invoke_schedule_tail
+}
 .ret1:	adds r2=IA64_TASK_PTRACE_OFFSET,r13
 	;;
 	ld8 r2=[r2]
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/ia32/ia32_ioctl.c linux-2.4.22-pre10/arch/ia64/ia32/ia32_ioctl.c
--- linux-2.4.21/arch/ia64/ia32/ia32_ioctl.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/ia32/ia32_ioctl.c	2003-08-01 13:34:07.000000000 +0000
@@ -268,6 +268,6 @@
 		return sys_ioctl(fd, cmd, (unsigned long)arg);
 
 	}
-	printk("%x:unimplemented IA32 ioctl system call\n", cmd);
+	printk(KERN_ERR "%x:unimplemented IA32 ioctl system call\n", cmd);
 	return -EINVAL;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/ia32/sys_ia32.c linux-2.4.22-pre10/arch/ia64/ia32/sys_ia32.c
--- linux-2.4.21/arch/ia64/ia32/sys_ia32.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/ia32/sys_ia32.c	2003-08-01 13:33:43.000000000 +0000
@@ -250,9 +250,8 @@
 
 
 static int
-get_page_prot (unsigned long addr)
+get_page_prot (struct vm_area_struct *vma, unsigned long addr)
 {
-	struct vm_area_struct *vma = find_vma(current->mm, addr);
 	int prot = 0;
 
 	if (!vma || vma->vm_start > addr)
@@ -275,14 +274,26 @@
 mmap_subpage (struct file *file, unsigned long start, unsigned long end, int prot, int flags,
 	      loff_t off)
 {
-	void *page = (void *) get_zeroed_page(GFP_KERNEL);
+	void *page = NULL;
 	struct inode *inode;
-	unsigned long ret;
-	int old_prot = get_page_prot(start);
+	unsigned long ret = 0;
+	struct vm_area_struct *vma = find_vma(current->mm, start);
+	int old_prot = get_page_prot(vma, start);
 
 	DBG("mmap_subpage(file=%p,start=0x%lx,end=0x%lx,prot=%x,flags=%x,off=0x%llx)\n",
 	    file, start, end, prot, flags, off);
 
+
+	/* Optimize the case where the old mmap and the new mmap are both anonymous */
+	if ((old_prot & PROT_WRITE) && (flags & MAP_ANONYMOUS) && !vma->vm_file) {
+		if (clear_user((void *) start, end - start)) {
+			ret = -EFAULT;
+			goto out;
+		}
+		goto skip_mmap;
+	}
+
+	page = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!page)
 		return -ENOMEM;
 
@@ -307,6 +318,7 @@
 			copy_to_user((void *) end, page + PAGE_OFF(end),
 				     PAGE_SIZE - PAGE_OFF(end));
 	}
+
 	if (!(flags & MAP_ANONYMOUS)) {
 		/* read the file contents */
 		inode = file->f_dentry->d_inode;
@@ -317,10 +329,13 @@
 			goto out;
 		}
 	}
+
+ skip_mmap:
 	if (!(prot & PROT_WRITE))
 		ret = sys_mprotect(PAGE_START(start), PAGE_SIZE, prot | old_prot);
   out:
-	free_page((unsigned long) page);
+	if (page)
+		free_page((unsigned long) page);
 	return ret;
 }
 
@@ -448,7 +463,12 @@
 		return addr;
 
 	if (len > IA32_PAGE_OFFSET || addr > IA32_PAGE_OFFSET - len)
+	{
+		if (flags & MAP_FIXED)
+			return -ENOMEM;
+		else
 		return -EINVAL;
+	}
 
 	if (OFFSET4K(offset))
 		return -EINVAL;
@@ -547,7 +567,7 @@
 #if PAGE_SHIFT <= IA32_PAGE_SHIFT
 	ret = sys_munmap(start, end - start);
 #else
-	if (start > end)
+	if (start >= end)
 		return -EINVAL;
 
 	start = PAGE_ALIGN(start);
@@ -576,11 +596,12 @@
 mprotect_subpage (unsigned long address, int new_prot)
 {
 	int old_prot;
+	struct vm_area_struct *vma;
 
 	if (new_prot == PROT_NONE)
 		return 0;		/* optimize case where nothing changes... */
-
-	old_prot = get_page_prot(address);
+	vma = find_vma(current->mm, address);
+	old_prot = get_page_prot(vma, address);
 	return sys_mprotect(address, PAGE_SIZE, new_prot | old_prot);
 }
 
@@ -1230,8 +1251,8 @@
 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
 
 struct rlimit32 {
-	int	rlim_cur;
-	int	rlim_max;
+	unsigned int	rlim_cur;
+	unsigned int	rlim_max;
 };
 
 extern asmlinkage long sys_getrlimit (unsigned int resource, struct rlimit *rlim);
@@ -2085,7 +2106,7 @@
 };
 
 struct shmid64_ds32 {
-	struct ipc64_perm shm_perm;
+	struct ipc64_perm32 shm_perm;
 	__kernel_size_t32 shm_segsz;
 	__kernel_time_t32 shm_atime;
 	unsigned int __unused1;
@@ -2126,6 +2147,7 @@
 #define SEMOP		 1
 #define SEMGET		 2
 #define SEMCTL		 3
+#define SEMTIMEDOP	 4
 #define MSGSND		11
 #define MSGRCV		12
 #define MSGGET		13
@@ -2167,6 +2189,10 @@
 	else
 		fourth.__pad = (void *)A(pad);
 	switch (third) {
+	      default:
+		err = -EINVAL;
+		break;
+
 	      case IPC_INFO:
 	      case IPC_RMID:
 	      case IPC_SET:
@@ -2234,7 +2260,7 @@
 static int
 do_sys32_msgsnd (int first, int second, int third, void *uptr)
 {
-	struct msgbuf *p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
+	struct msgbuf *p = kmalloc(second + sizeof(struct msgbuf), GFP_USER);
 	struct msgbuf32 *up = (struct msgbuf32 *)uptr;
 	mm_segment_t old_fs;
 	int err;
@@ -2276,12 +2302,12 @@
 		msgtyp = ipck.msgtyp;
 	}
 	err = -ENOMEM;
-	p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
+	p = kmalloc(second + sizeof(struct msgbuf), GFP_USER);
 	if (!p)
 		goto out;
 	old_fs = get_fs();
 	set_fs(KERNEL_DS);
-	err = sys_msgrcv(first, p, second + 4, msgtyp, third);
+	err = sys_msgrcv(first, p, second, msgtyp, third);
 	set_fs(old_fs);
 	if (err < 0)
 		goto free_then_out;
@@ -2314,21 +2340,21 @@
 
 	      case IPC_SET:
 		if (version == IPC_64) {
-			err = get_user(m.msg_perm.uid, &up64->msg_perm.uid);
-			err |= get_user(m.msg_perm.gid, &up64->msg_perm.gid);
-			err |= get_user(m.msg_perm.mode, &up64->msg_perm.mode);
-			err |= get_user(m.msg_qbytes, &up64->msg_qbytes);
+			err = get_user(m64.msg_perm.uid, &up64->msg_perm.uid);
+			err |= get_user(m64.msg_perm.gid, &up64->msg_perm.gid);
+			err |= get_user(m64.msg_perm.mode, &up64->msg_perm.mode);
+			err |= get_user(m64.msg_qbytes, &up64->msg_qbytes);
 		} else {
-			err = get_user(m.msg_perm.uid, &up32->msg_perm.uid);
-			err |= get_user(m.msg_perm.gid, &up32->msg_perm.gid);
-			err |= get_user(m.msg_perm.mode, &up32->msg_perm.mode);
-			err |= get_user(m.msg_qbytes, &up32->msg_qbytes);
+			err = get_user(m64.msg_perm.uid, &up32->msg_perm.uid);
+			err |= get_user(m64.msg_perm.gid, &up32->msg_perm.gid);
+			err |= get_user(m64.msg_perm.mode, &up32->msg_perm.mode);
+			err |= get_user(m64.msg_qbytes, &up32->msg_qbytes);
 		}
 		if (err)
 			break;
 		old_fs = get_fs();
 		set_fs(KERNEL_DS);
-		err = sys_msgctl(first, second, &m);
+		err = sys_msgctl(first, second, &m64);
 		set_fs(old_fs);
 		break;
 
@@ -2408,7 +2434,7 @@
 shmctl32 (int first, int second, void *uptr)
 {
 	int err = -EFAULT, err2;
-	struct shmid_ds s;
+
 	struct shmid64_ds s64;
 	struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
 	struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
@@ -2460,19 +2486,19 @@
 
 	      case IPC_SET:
 		if (version == IPC_64) {
-			err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
-			err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
-			err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
+			err = get_user(s64.shm_perm.uid, &up64->shm_perm.uid);
+			err |= get_user(s64.shm_perm.gid, &up64->shm_perm.gid);
+			err |= get_user(s64.shm_perm.mode, &up64->shm_perm.mode);
 		} else {
-			err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
-			err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
-			err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
+			err = get_user(s64.shm_perm.uid, &up32->shm_perm.uid);
+			err |= get_user(s64.shm_perm.gid, &up32->shm_perm.gid);
+			err |= get_user(s64.shm_perm.mode, &up32->shm_perm.mode);
 		}
 		if (err)
 			break;
 		old_fs = get_fs();
 		set_fs(KERNEL_DS);
-		err = sys_shmctl(first, second, &s);
+		err = sys_shmctl(first, second, &s64);
 		set_fs(old_fs);
 		break;
 
@@ -2553,6 +2579,17 @@
 	return err;
 }
 
+static long
+semtimedop32(int semid, struct sembuf *tsems, int nsems,
+	     const struct timespec32 *timeout32)
+{
+	struct timespec t;
+	if (get_user (t.tv_sec, &timeout32->tv_sec) ||
+	    get_user (t.tv_nsec, &timeout32->tv_nsec))
+		return -EFAULT;
+	return sys_semtimedop(semid, tsems, nsems, &t);
+}
+
 asmlinkage long
 sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
 {
@@ -2564,7 +2601,11 @@
 	switch (call) {
 	      case SEMOP:
 		/* struct sembuf is the same on 32 and 64bit :)) */
-		return sys_semop(first, (struct sembuf *)AA(ptr), second);
+		return sys_semtimedop(first, (struct sembuf *)AA(ptr), second,
+				      NULL);
+	      case SEMTIMEDOP:
+		return semtimedop32(first, (struct sembuf *)AA(ptr), second, 
+				    (const struct timespec32 *)AA(fifth));
 	      case SEMGET:
 		return sys_semget(first, second, third);
 	      case SEMCTL:
@@ -2590,7 +2631,7 @@
 		return shmctl32(first, second, (void *)AA(ptr));
 
 	      default:
-		return -EINVAL;
+		return -ENOSYS;
 	}
 	return -EINVAL;
 }
@@ -2924,7 +2965,7 @@
 	ptp = ia64_task_regs(tsk);
 	tos = (tsk->thread.fsr >> 11) & 7;
 	for (i = 0; i < 8; i++)
-		put_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos);
+		put_fpreg(i, &save->st_space[i], ptp, swp, tos);
 	return 0;
 }
 
@@ -2957,7 +2998,7 @@
 	ptp = ia64_task_regs(tsk);
 	tos = (tsk->thread.fsr >> 11) & 7;
 	for (i = 0; i < 8; i++)
-		get_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos);
+		get_fpreg(i, &save->st_space[i], ptp, swp, tos);
 	return 0;
 }
 
@@ -3076,26 +3117,23 @@
 	ret = -ESRCH;
 	read_lock(&tasklist_lock);
 	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
 	read_unlock(&tasklist_lock);
 	if (!child)
 		goto out;
 	ret = -EPERM;
 	if (pid == 1)		/* no messing around with init! */
-		goto out;
+		goto out_tsk;
 
 	if (request == PTRACE_ATTACH) {
 		ret = sys_ptrace(request, pid, addr, data, arg4, arg5, arg6, arg7, stack);
-		goto out;
-	}
-	ret = -ESRCH;
-	if (!(child->ptrace & PT_PTRACED))
-		goto out;
-	if (child->state != TASK_STOPPED) {
-		if (request != PTRACE_KILL)
-			goto out;
+		goto out_tsk;
 	}
-	if (child->p_pptr != current)
-		goto out;
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
+		goto out_tsk;
 
 	switch (request) {
 	      case PTRACE_PEEKTEXT:
@@ -3105,12 +3143,12 @@
 			ret = put_user(value, (unsigned int *) A(data));
 		else
 			ret = -EIO;
-		goto out;
+		goto out_tsk;
 
 	      case PTRACE_POKETEXT:
 	      case PTRACE_POKEDATA:	/* write the word at location addr */
 		ret = ia32_poke(regs, child, addr, data);
-		goto out;
+		goto out_tsk;
 
 	      case PTRACE_PEEKUSR:	/* read word at addr in USER area */
 		ret = -EIO;
@@ -3185,6 +3223,8 @@
 		break;
 
 	}
+  out_tsk:
+	free_task_struct(child);
   out:
 	unlock_kernel();
 	return ret;
@@ -3407,6 +3447,7 @@
 asmlinkage long
 sys32_sysctl (struct sysctl32 *args)
 {
+#ifdef CONFIG_SYSCTL
 	struct sysctl32 a32;
 	mm_segment_t old_fs = get_fs ();
 	void *oldvalp, *newvalp;
@@ -3444,6 +3485,9 @@
 		return -EFAULT;
 
 	return ret;
+#else
+	return -ENOSYS;
+#endif
 }
 
 asmlinkage long
@@ -3707,21 +3751,43 @@
 	u32 bufferram;
 	u32 totalswap;
 	u32 freeswap;
-	unsigned short procs;
-	char _f[22];
+	u16 procs;
+	u16 pad;
+	u32 totalhigh;
+	u32 freehigh;
+	u32 mem_unit;
+	char _f[8];
 };
 
 asmlinkage long
 sys32_sysinfo (struct sysinfo32 *info)
 {
 	extern asmlinkage long sys_sysinfo (struct sysinfo *);
-	mm_segment_t old_fs = get_fs();
 	struct sysinfo s;
 	long ret, err;
+	int bitcount = 0;
+	mm_segment_t old_fs = get_fs();
 
 	set_fs(KERNEL_DS);
 	ret = sys_sysinfo(&s);
 	set_fs(old_fs);
+	/* Check to see if any memory value is too large for 32-bit and
+	 * scale down if needed.
+	 */
+	if ((s.totalram >> 32) || (s.totalswap >> 32)) {
+		while (s.mem_unit < PAGE_SIZE) {
+			s.mem_unit <<= 1;
+			bitcount++;
+		}
+		s.totalram >>= bitcount;
+		s.freeram >>= bitcount;
+		s.sharedram >>= bitcount;
+		s.bufferram >>= bitcount;
+		s.totalswap >>= bitcount;
+		s.freeswap >>= bitcount;
+		s.totalhigh >>= bitcount;
+		s.freehigh >>= bitcount;
+	}
 
 	if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
 		return -EFAULT;
@@ -3737,6 +3803,9 @@
 	err |= __put_user(s.totalswap, &info->totalswap);
 	err |= __put_user(s.freeswap, &info->freeswap);
 	err |= __put_user(s.procs, &info->procs);
+	err |= __put_user(s.totalhigh, &info->totalhigh);
+	err |= __put_user(s.freehigh, &info->freehigh);
+	err |= __put_user(s.mem_unit, &info->mem_unit);
 	if (err)
 		return -EFAULT;
 	return ret;
@@ -3783,7 +3852,7 @@
 	return result;
 }
 
-struct dqblk32 {
+struct user_dqblk32 {
 	__u32 dqb_bhardlimit;
 	__u32 dqb_bsoftlimit;
 	__u32 dqb_curblocks;
@@ -3795,43 +3864,43 @@
 };
 
 asmlinkage long
-sys32_quotactl (int cmd, unsigned int special, int id, struct dqblk32 *addr)
+sys32_quotactl(int cmd, unsigned int special, int id, caddr_t addr)
 {
 	extern asmlinkage long sys_quotactl (int, const char *, int, caddr_t);
 	int cmds = cmd >> SUBCMDSHIFT;
 	mm_segment_t old_fs;
-	struct dqblk d;
+	struct v1c_mem_dqblk d;
 	char *spec;
 	long err;
 
 	switch (cmds) {
-	      case Q_GETQUOTA:
+	case Q_V1_GETQUOTA:
 		break;
-	      case Q_SETQUOTA:
-	      case Q_SETUSE:
-	      case Q_SETQLIM:
-		if (copy_from_user (&d, addr, sizeof(struct dqblk32)))
+	case Q_V1_SETQUOTA:
+	case Q_V1_SETUSE:
+	case Q_V1_SETQLIM:
+		if (copy_from_user(&d, addr, sizeof(struct user_dqblk32)))
 			return -EFAULT;
-		d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
-		d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
+		d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime;
+		d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime;
 		break;
-	      default:
-		return sys_quotactl(cmd, (void *) A(special), id, (caddr_t) addr);
+	default:
+		return sys_quotactl(cmd, (void *)A(special), id, addr);
 	}
 	spec = getname32((void *) A(special));
 	err = PTR_ERR(spec);
 	if (IS_ERR(spec))
 		return err;
-	old_fs = get_fs ();
+	old_fs = get_fs();
 	set_fs(KERNEL_DS);
 	err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
 	set_fs(old_fs);
 	putname(spec);
-	if (cmds == Q_GETQUOTA) {
+	if (cmds == Q_V1_GETQUOTA) {
 		__kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
-		((struct dqblk32 *)&d)->dqb_itime = i;
-		((struct dqblk32 *)&d)->dqb_btime = b;
-		if (copy_to_user(addr, &d, sizeof(struct dqblk32)))
+		((struct user_dqblk32 *)&d)->dqb_itime = i;
+		((struct user_dqblk32 *)&d)->dqb_btime = b;
+		if (copy_to_user(addr, &d, sizeof(struct user_dqblk32)))
 			return -EFAULT;
 	}
 	return err;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/acpi.c linux-2.4.22-pre10/arch/ia64/kernel/acpi.c
--- linux-2.4.21/arch/ia64/kernel/acpi.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/acpi.c	2003-08-01 13:33:18.000000000 +0000
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 1999 VA Linux Systems
  *  Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
- *  Copyright (C) 2000, 2002 Hewlett-Packard Co.
+ *  Copyright (C) 2000, 2002-2003 Hewlett-Packard Co.
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *  Copyright (C) 2000 Intel Corp.
  *  Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
@@ -51,6 +51,7 @@
 asm (".weak iosapic_override_isa_irq");
 asm (".weak iosapic_register_platform_intr");
 asm (".weak iosapic_init");
+asm (".weak iosapic_system_init");
 asm (".weak iosapic_version");
 
 void (*pm_idle) (void);
@@ -69,20 +70,20 @@
 
 	rsdp_phys = acpi_find_rsdp();
 	if (!rsdp_phys) {
-		printk("ACPI 2.0 RSDP not found, default to \"dig\"\n");
+		printk(KERN_ERR "ACPI 2.0 RSDP not found, default to \"dig\"\n");
 		return "dig";
 	}
 
 	rsdp = (struct acpi20_table_rsdp *) __va(rsdp_phys);
 	if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) {
-		printk("ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");
+		printk(KERN_ERR "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");
 		return "dig";
 	}
 
 	xsdt = (struct acpi_table_xsdt *) __va(rsdp->xsdt_address);
 	hdr = &xsdt->header;
 	if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) {
-		printk("ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");
+		printk(KERN_ERR "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");
 		return "dig";
 	}
 
@@ -110,165 +111,88 @@
 
 #ifdef CONFIG_ACPI
 
-static acpi_resource *
-acpi_get_crs_next (acpi_buffer *buf, int *offset)
-{
-	acpi_resource *res;
-
-	if (*offset >= buf->length)
-		return NULL;
+struct acpi_vendor_descriptor {
+	u8				guid_id;
+	efi_guid_t			guid;
+};
+
+struct acpi_vendor_info {
+	struct acpi_vendor_descriptor	*descriptor;
+	u8				*data;
+	u32				length;
+};
 
-	res = (acpi_resource *)((char *) buf->pointer + *offset);
-	*offset += res->length;
-	return res;
-}
-
-static acpi_resource_data *
-acpi_get_crs_type (acpi_buffer *buf, int *offset, int type)
-{
-	for (;;) {
-		acpi_resource *res = acpi_get_crs_next(buf, offset);
-		if (!res)
-			return NULL;
-		if (res->id == type)
-			return &res->data;
-	}
-}
-
-static void
-acpi_get_crs_addr (acpi_buffer *buf, int type, u64 *base, u64 *length, u64 *tra)
-{
-	int offset = 0;
-	acpi_resource_address16 *addr16;
-	acpi_resource_address32 *addr32;
-	acpi_resource_address64 *addr64;
-
-	for (;;) {
-		acpi_resource *res = acpi_get_crs_next(buf, &offset);
-		if (!res)
-			return;
-		switch (res->id) {
-			case ACPI_RSTYPE_ADDRESS16:
-				addr16 = (acpi_resource_address16 *) &res->data;
-
-				if (type == addr16->resource_type) {
-					*base = addr16->min_address_range;
-					*length = addr16->address_length;
-					*tra = addr16->address_translation_offset;
-					return;
-				}
-				break;
-			case ACPI_RSTYPE_ADDRESS32:
-				addr32 = (acpi_resource_address32 *) &res->data;
-				if (type == addr32->resource_type) {
-					*base = addr32->min_address_range;
-					*length = addr32->address_length;
-					*tra = addr32->address_translation_offset;
-					return;
-				}
-				break;
-			case ACPI_RSTYPE_ADDRESS64:
-				addr64 = (acpi_resource_address64 *) &res->data;
-				if (type == addr64->resource_type) {
-					*base = addr64->min_address_range;
-					*length = addr64->address_length;
-					*tra = addr64->address_translation_offset;
-					return;
-				}
-				break;
-			case ACPI_RSTYPE_END_TAG:
-				return;
-				break;
-		}
-	}
+acpi_status
+acpi_vendor_resource_match(acpi_resource *resource, void *context)
+{
+	struct acpi_vendor_info *info = (struct acpi_vendor_info *) context;
+	acpi_resource_vendor *vendor;
+	struct acpi_vendor_descriptor *descriptor;
+	u32 length;
+
+	if (resource->id != ACPI_RSTYPE_VENDOR)
+		return AE_OK;
+
+	vendor = (acpi_resource_vendor *) &resource->data;
+	descriptor = (struct acpi_vendor_descriptor *) vendor->reserved;
+	if (vendor->length <= sizeof(*info->descriptor) ||
+	    descriptor->guid_id != info->descriptor->guid_id ||
+	    efi_guidcmp(descriptor->guid, info->descriptor->guid))
+		return AE_OK;
+
+	length = vendor->length - sizeof(struct acpi_vendor_descriptor);
+	info->data = acpi_os_allocate(length);
+	if (!info->data)
+		return AE_NO_MEMORY;
+
+	memcpy(info->data, vendor->reserved + sizeof(struct acpi_vendor_descriptor), length);
+	info->length = length;
+	return AE_CTRL_TERMINATE;
 }
 
 acpi_status
-acpi_get_addr_space(acpi_handle obj, u8 type, u64 *base, u64 *length, u64 *tra)
+acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor *id,
+		u8 **data, u32 *length)
 {
-	acpi_status status;
-	acpi_buffer buf = { .length  = ACPI_ALLOCATE_BUFFER,
-			    .pointer = NULL };
+	struct acpi_vendor_info info;
 
-	*base = 0;
-	*length = 0;
-	*tra = 0;
+	info.descriptor = id;
+	info.data = 0;
 
-	status = acpi_get_current_resources(obj, &buf);
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n");
-		return status;
-	}
-
-	acpi_get_crs_addr(&buf, type, base, length, tra);
-
-	acpi_os_free(buf.pointer);
+	acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match, &info);
+	if (!info.data)
+		return AE_NOT_FOUND;
 
+	*data = info.data;
+	*length = info.length;
 	return AE_OK;
 }
 
-typedef struct {
-	u8	guid_id;
-	u8	guid[16];
-	u8	csr_base[8];
-	u8	csr_length[8];
-} acpi_hp_vendor_long;
-
-#define HP_CCSR_LENGTH 0x21
-#define HP_CCSR_TYPE 0x2
-#define HP_CCSR_GUID EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, \
-			      0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad)
+struct acpi_vendor_descriptor hp_ccsr_descriptor = {
+	.guid_id = 2,
+	.guid    = EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad)
+};
 
 acpi_status
 acpi_hp_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length)
 {
-	int i, offset = 0;
 	acpi_status status;
-	acpi_buffer buf = { .length  = ACPI_ALLOCATE_BUFFER,
-			    .pointer = NULL };
-	acpi_resource_vendor *res;
-	acpi_hp_vendor_long *hp_res;
-	efi_guid_t vendor_guid;
-
-	*csr_base = 0;
-	*csr_length = 0;
+	u8 *data;
+	u32 length;
+	int i;
+
+	status = acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length);
+
+	if (ACPI_FAILURE(status) || length != 16)
+		return AE_NOT_FOUND;
+
+	memcpy(csr_base, data, sizeof(*csr_base));
+	memcpy(csr_length, data + 8, sizeof(*csr_length));
+	acpi_os_free(data);
 
-	status = acpi_get_current_resources(obj, &buf);
-	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n");
-		return status;
-	}
-
-	status = AE_NOT_FOUND;
-	res = (acpi_resource_vendor *)acpi_get_crs_type(&buf, &offset, ACPI_RSTYPE_VENDOR);
-	if (!res) {
-		printk(KERN_ERR PREFIX "Failed to find config space for device\n");
-		goto out;
-	}
-
-	status = AE_TYPE; /* Revisit error? */
-	hp_res = (acpi_hp_vendor_long *)(res->reserved);
-
-	if (res->length != HP_CCSR_LENGTH || hp_res->guid_id != HP_CCSR_TYPE) {
-		printk(KERN_ERR PREFIX "Unknown Vendor data\n");
-		goto out;
-	}
-
-	memcpy(&vendor_guid, hp_res->guid, sizeof(efi_guid_t));
-	if (efi_guidcmp(vendor_guid, HP_CCSR_GUID) != 0) {
-		printk(KERN_ERR PREFIX "Vendor GUID does not match\n");
-		goto out;
-	}
-
-	/* It's probably unaligned, so use memcpy */
-	memcpy(csr_base, hp_res->csr_base, 8);
-	memcpy(csr_length, hp_res->csr_length, 8);
-	status = AE_OK;
-
- out:
-	acpi_os_free(buf.pointer);
-	return status;
+	return AE_OK;
 }
+
 #endif /* CONFIG_ACPI */
 
 #ifdef CONFIG_ACPI_BOOT
@@ -293,8 +217,7 @@
 		/* correctable platform error interrupt */
 		vector = platform_intr_list[int_type];
 	} else
-		printk("acpi_request_vector(): invalid interrupt type\n");
-
+		printk(KERN_ERR "acpi_request_vector(): invalid interrupt type\n");
 	return vector;
 }
 
@@ -354,7 +277,7 @@
 		return 0;
 	}
 
-	printk("CPU %d (0x%04x)", total_cpus, phys_id);
+	printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, phys_id);
 
 	if (lsapic->flags.enabled) {
 		available_cpus++;
@@ -397,40 +320,6 @@
 
 
 static int __init
-acpi_find_iosapic (unsigned int gsi, u32 *gsi_base, char **iosapic_address)
-{
-	struct acpi_table_iosapic *iosapic;
-	int ver;
-	int max_pin;
-	char *p;
-	char *end;
-
-	if (!gsi_base || !iosapic_address)
-		return -ENODEV;
-
-	p = (char *) (acpi_madt + 1);
-	end = p + (acpi_madt->header.length - sizeof(struct acpi_table_madt));
-
-	while (p < end) {
-		if (*p == ACPI_MADT_IOSAPIC) {
-			iosapic = (struct acpi_table_iosapic *) p;
-
-			*gsi_base = iosapic->global_irq_base;
-			*iosapic_address = ioremap(iosapic->address, 0);
-
-			ver = iosapic_version(*iosapic_address);
-			max_pin = (ver >> 16) & 0xff;
-
-			if ((gsi - *gsi_base) <= max_pin)
-				return 0;	/* Found it! */
-		}
-		p += p[1];
-	}
-	return -ENODEV;
-}
-
-
-static int __init
 acpi_parse_iosapic (acpi_table_entry_header *header)
 {
 	struct acpi_table_iosapic *iosapic;
@@ -441,15 +330,9 @@
 
 	acpi_table_print_madt_entry(header);
 
-	if (iosapic_init) {
-#ifndef CONFIG_ITANIUM
-		iosapic_init(iosapic->address, iosapic->global_irq_base,
-			     has_8259);
-#else
-		/* Firmware on old Itanium systems is broken */
-		iosapic_init(iosapic->address, iosapic->global_irq_base, 1);
-#endif
-	}
+	if (iosapic_init)
+		iosapic_init(iosapic->address, iosapic->global_irq_base);
+
 	return 0;
 }
 
@@ -459,8 +342,6 @@
 {
 	struct acpi_table_plat_int_src *plintsrc;
 	int vector;
-	u32 gsi_base;
-	char *iosapic_address;
 
 	plintsrc = (struct acpi_table_plat_int_src *) header;
 	if (!plintsrc)
@@ -473,11 +354,6 @@
 		return -ENODEV;
 	}
 
-	if (acpi_find_iosapic(plintsrc->global_irq, &gsi_base, &iosapic_address)) {
-		printk(KERN_WARNING PREFIX "IOSAPIC not found\n");
-		return -ENODEV;
-	}
-
 	/*
 	 * Get vector assignment for this interrupt, set attributes,
 	 * and program the IOSAPIC routing table.
@@ -487,10 +363,8 @@
 						plintsrc->iosapic_vector,
 						plintsrc->eid,
 						plintsrc->id,
-						(plintsrc->flags.polarity == 1) ? 1 : 0,
-						(plintsrc->flags.trigger == 1) ? 1 : 0,
-						gsi_base,
-						iosapic_address);
+						(plintsrc->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
+						(plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
 
 	platform_intr_list[plintsrc->type] = vector;
 	return 0;
@@ -513,9 +387,8 @@
 		return 0;
 
 	iosapic_override_isa_irq(p->bus_irq, p->global_irq,
-				 (p->flags.polarity == 1) ? 1 : 0,
-				 (p->flags.trigger == 1) ? 1 : 0);
-
+				 (p->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
+				 (p->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
 	return 0;
 }
 
@@ -546,7 +419,13 @@
 	acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
 
 	/* remember the value for reference after free_initmem() */
+#ifdef CONFIG_ITANIUM
+	has_8259 = 1; /* Firmware on old Itanium systems is broken */
+#else
 	has_8259 = acpi_madt->flags.pcat_compat;
+#endif
+	if (iosapic_system_init)
+		iosapic_system_init(has_8259);
 
 	/* Get base address of IPI Message Block */
 
@@ -563,8 +442,7 @@
 {
 	struct acpi_table_header *fadt_header;
 	fadt_descriptor_rev2 *fadt;
-	u32 sci_irq, gsi_base;
-	char *iosapic_address;
+	u32 sci_irq;
 
 	if (!phys_addr || !size)
 		return -EINVAL;
@@ -587,9 +465,7 @@
 	if (!iosapic_register_intr)
 		return -ENODEV;
 
-	if (!acpi_find_iosapic(sci_irq, &gsi_base, &iosapic_address))
-		iosapic_register_intr(sci_irq, 0, 0, gsi_base, iosapic_address);
-
+	iosapic_register_intr(sci_irq, IOSAPIC_POL_LOW, IOSAPIC_LEVEL);
 	return 0;
 }
 
@@ -676,13 +552,13 @@
 
 #ifdef CONFIG_SMP
 	if (available_cpus == 0) {
-		printk("ACPI: Found 0 CPUS; assuming 1\n");
+		printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
 		available_cpus = 1; /* We've got at least one of these, no? */
 	}
 	smp_boot_data.cpu_count = total_cpus;
 #endif
 	/* Make boot-up look pretty */
-	printk("%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
+	printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
 	return 0;
 }
 
@@ -690,6 +566,7 @@
 /* --------------------------------------------------------------------------
                              PCI Interrupt Routing
    -------------------------------------------------------------------------- */
+#ifdef CONFIG_PCI
 
 int __init
 acpi_get_prt (struct pci_vector_struct **vectors, int *count)
@@ -732,7 +609,7 @@
 	*count = acpi_prt.count;
 	return 0;
 }
-
+#endif
 /* Assume IA64 always use I/O SAPIC */
 
 int __init
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/brl_emu.c linux-2.4.22-pre10/arch/ia64/kernel/brl_emu.c
--- linux-2.4.21/arch/ia64/kernel/brl_emu.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/brl_emu.c	2003-08-01 13:34:11.000000000 +0000
@@ -55,11 +55,11 @@
 ia64_emulate_brl (struct pt_regs *regs, unsigned long ar_ec)
 {
 	unsigned long bundle[2];
-	unsigned long opcode, btype, qp, offset;
+	unsigned long opcode, btype, qp, offset, cpl;
 	unsigned long next_ip;
 	struct siginfo siginfo;
 	struct illegal_op_return rv;
-	int tmp_taken, unimplemented_address;
+	long tmp_taken, unimplemented_address;
 
 	rv.fkt = (unsigned long) -1;
 
@@ -158,9 +158,9 @@
 			 *  AR[PFS].pec = AR[EC]
 			 *  AR[PFS].ppl = PSR.cpl
 			 */
+			cpl = ia64_psr(regs)->cpl;
 			regs->ar_pfs = ((regs->cr_ifs & 0x3fffffffff)
-					| (ar_ec << 52)
-					| ((unsigned long) ia64_psr(regs)->cpl << 62));
+					| (ar_ec << 52) | (cpl << 62));
 
 			/*
 			 *  CFM.sof -= CFM.sol
@@ -195,7 +195,7 @@
 		/*
 		 *  The target address contains unimplemented bits.
 		 */
-		printk("Woah! Unimplemented Instruction Address Trap!\n");
+		printk(KERN_DEBUG "Woah! Unimplemented Instruction Address Trap!\n");
 		siginfo.si_signo = SIGILL;
 		siginfo.si_errno = 0;
 		siginfo.si_flags = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/efi.c linux-2.4.22-pre10/arch/ia64/kernel/efi.c
--- linux-2.4.21/arch/ia64/kernel/efi.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/efi.c	2003-08-01 13:30:45.000000000 +0000
@@ -5,7 +5,7 @@
  *
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999-2002 Hewlett-Packard Co.
+ * Copyright (C) 1999-2003 Hewlett-Packard Co.
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  *
@@ -365,7 +365,7 @@
 				prev_valid = 1;
 			} else {
 				if (curr.start < prev.start)
-					printk("Oops: EFI memory table not ordered!\n");
+					printk(KERN_ERR "Oops: EFI memory table not ordered!\n");
 
 				if (prev.end == curr.start) {
 					/* merge two consecutive memory ranges */
@@ -437,7 +437,8 @@
 		 * dedicated ITR for the PAL code.
 		 */
 		if ((vaddr & mask) == (KERNEL_START & mask)) {
-			printk("%s: no need to install ITR for PAL code\n", __FUNCTION__);
+			printk(KERN_INFO "%s: no need to install ITR for PAL code\n",
+			       __FUNCTION__);
 			continue;
 		}
 
@@ -445,7 +446,7 @@
 			panic("Woah!  PAL code size bigger than a granule!");
 
 		mask  = ~((1 << IA64_GRANULE_SHIFT) - 1);
-		printk("CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
+		printk(KERN_INFO "CPU %d: mapping PAL code [0x%lx-0x%lx) into [0x%lx-0x%lx)\n",
 		       smp_processor_id(), md->phys_addr,
 		       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
 		       vaddr & mask, (vaddr & mask) + IA64_GRANULE_SIZE);
@@ -488,7 +489,7 @@
 		}
 	}
 	if (mem_limit != ~0UL)
-		printk("Ignoring memory above %luMB\n", mem_limit >> 20);
+		printk(KERN_INFO "Ignoring memory above %luMB\n", mem_limit >> 20);
 
 	efi.systab = __va(ia64_boot_param->efi_systab);
 
@@ -500,7 +501,7 @@
 	if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
 		panic("Woah! EFI system table signature incorrect\n");
 	if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0)
-		printk("Warning: EFI system table major version mismatch: "
+		printk(KERN_WARNING "Warning: EFI system table major version mismatch: "
 		       "got %d.%02d, expected %d.%02d\n",
 		       efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff,
 		       EFI_SYSTEM_TABLE_REVISION >> 16, EFI_SYSTEM_TABLE_REVISION & 0xffff);
@@ -515,7 +516,7 @@
 		vendor[i] = '\0';
 	}
 
-	printk("EFI v%u.%.02u by %s:",
+	printk(KERN_INFO "EFI v%u.%.02u by %s:",
 	       efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, vendor);
 
 	for (i = 0; i < efi.systab->nr_tables; i++) {
@@ -607,7 +608,7 @@
 									   | _PAGE_PL_0
 									   | _PAGE_AR_RW));
 #else
-				printk("EFI_MEMORY_WC mapping\n");
+				printk(KERN_INFO "EFI_MEMORY_WC mapping\n");
 				md->virt_addr = (u64) ioremap(md->phys_addr, 0);
 #endif
 			} else if (md->attribute & EFI_MEMORY_WT) {
@@ -617,7 +618,7 @@
 									   | _PAGE_PL_0
 									   | _PAGE_AR_RW));
 #else
-				printk("EFI_MEMORY_WT mapping\n");
+				printk(KERN_INFO "EFI_MEMORY_WT mapping\n");
 				md->virt_addr = (u64) ioremap(md->phys_addr, 0);
 #endif
 			}
@@ -629,7 +630,7 @@
 			       efi_desc_size, ia64_boot_param->efi_memdesc_version,
 			       ia64_boot_param->efi_memmap);
 	if (status != EFI_SUCCESS) {
-		printk("Warning: unable to switch EFI into virtual mode (status=0x%lx)\n", status);
+		printk(KERN_WARNING "warning: unable to switch EFI into virtual mode (status=0x%lx)\n", status);
 		return;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/efivars.c linux-2.4.22-pre10/arch/ia64/kernel/efivars.c
--- linux-2.4.21/arch/ia64/kernel/efivars.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/efivars.c	2003-08-01 13:33:11.000000000 +0000
@@ -29,6 +29,9 @@
  *
  * Changelog:
  *
+ *  10 Dec 2002 - Matt Domsch <Matt_Domsch@dell.com>
+ *   fix locking per Peter Chubb's findings
+ * 
  *  25 Mar 2002 - Matt Domsch <Matt_Domsch@dell.com>
  *   move uuid_unparse() to include/asm-ia64/efi.h:efi_guid_unparse()
  *
@@ -73,7 +76,7 @@
 MODULE_DESCRIPTION("/proc interface to EFI Variables");
 MODULE_LICENSE("GPL");
 
-#define EFIVARS_VERSION "0.05 2002-Mar-26"
+#define EFIVARS_VERSION "0.06 2002-Dec-10"
 
 static int
 efivar_read(char *page, char **start, off_t off,
@@ -106,6 +109,14 @@
 	struct list_head        list;
 } efivar_entry_t;
 
+/*
+  efivars_lock protects two things:
+  1) efivar_list - adds, removals, reads, writes
+  2) efi.[gs]et_variable() calls.
+  It must not be held when creating proc entries or calling kmalloc.
+  efi.get_next_variable() is only called from efivars_init(),
+  which is protected by the BKL, so that path is safe.
+*/
 static spinlock_t efivars_lock = SPIN_LOCK_UNLOCKED;
 static LIST_HEAD(efivar_list);
 static struct proc_dir_entry *efi_vars_dir = NULL;
@@ -150,6 +161,7 @@
  *    variable_name_size = number of bytes required to hold
  *                         variable_name (not counting the NULL
  *                         character at the end.
+ *    efivars_lock is not held on entry or exit.
  * Returns 1 on failure, 0 on success
  */
 static int
@@ -157,13 +169,14 @@
 			 efi_char16_t *variable_name,
 			 efi_guid_t *vendor_guid)
 {
-
 	int i, short_name_size = variable_name_size /
 		sizeof(efi_char16_t) + 38;
-	char *short_name = kmalloc(short_name_size+1,
-				   GFP_KERNEL);
-	efivar_entry_t *new_efivar = kmalloc(sizeof(efivar_entry_t),
-					     GFP_KERNEL);
+	char *short_name;
+	efivar_entry_t *new_efivar;
+
+	short_name = kmalloc(short_name_size+1, GFP_KERNEL);
+	new_efivar = kmalloc(sizeof(efivar_entry_t), GFP_KERNEL);
+
 	if (!short_name || !new_efivar)  {
 		if (short_name)        kfree(short_name);
 		if (new_efivar)        kfree(new_efivar);
@@ -188,19 +201,18 @@
 	*(short_name + strlen(short_name)) = '-';
 	efi_guid_unparse(vendor_guid, short_name + strlen(short_name));
 
-
 	/* Create the entry in proc */
 	new_efivar->entry = create_proc_entry(short_name, 0600, efi_vars_dir);
 	kfree(short_name); short_name = NULL;
 	if (!new_efivar->entry) return 1;
 
-
 	new_efivar->entry->data = new_efivar;
 	new_efivar->entry->read_proc = efivar_read;
 	new_efivar->entry->write_proc = efivar_write;
 
+	spin_lock(&efivars_lock);
 	list_add(&new_efivar->list, &efivar_list);
-
+	spin_unlock(&efivars_lock);
 
 	return 0;
 }
@@ -326,6 +338,8 @@
 		kfree(efivar);
 	}
 
+	spin_unlock(&efivars_lock);
+
 	/* If this is a new variable, set up the proc entry for it. */
 	if (!found) {
 		efivar_create_proc_entry(utf8_strsize(var_data->VariableName,
@@ -336,36 +350,96 @@
 
 	kfree(var_data);
 	MOD_DEC_USE_COUNT;
-	spin_unlock(&efivars_lock);
 	return size;
 }
 
+/*
+ * The EFI system table contains pointers to the SAL system table,
+ * HCDP, ACPI, SMBIOS, etc, that may be useful to applications.
+ */
+static ssize_t
+efi_systab_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	void *data;
+	u8 *proc_buffer;
+	ssize_t size, length;
+	int ret;
+	const int max_nr_entries = 7; 	/* num ptrs to tables we could expose */
+	const int max_line_len = 80;
+
+	if (!efi.systab)
+		return 0;
+
+	proc_buffer = kmalloc(max_nr_entries * max_line_len, GFP_KERNEL);
+	if (!proc_buffer)
+		return -ENOMEM;
+
+	length = 0;
+	if (efi.mps)
+		length += sprintf(proc_buffer + length, "MPS=0x%lx\n", __pa(efi.mps));
+	if (efi.acpi20)
+		length += sprintf(proc_buffer + length, "ACPI20=0x%lx\n", __pa(efi.acpi20));
+	if (efi.acpi)
+		length += sprintf(proc_buffer + length, "ACPI=0x%lx\n", __pa(efi.acpi));
+	if (efi.smbios)
+		length += sprintf(proc_buffer + length, "SMBIOS=0x%lx\n", __pa(efi.smbios));
+	if (efi.sal_systab)
+		length += sprintf(proc_buffer + length, "SAL=0x%lx\n", __pa(efi.sal_systab));
+	if (efi.hcdp)
+		length += sprintf(proc_buffer + length, "HCDP=0x%lx\n", __pa(efi.hcdp));
+	if (efi.boot_info)
+		length += sprintf(proc_buffer + length, "BOOTINFO=0x%lx\n", __pa(efi.boot_info));
+
+	if (*ppos >= length) {
+		ret = 0;
+		goto out;
+	}
 
+	data = proc_buffer + file->f_pos;
+	size = length - file->f_pos;
+	if (size > count)
+		size = count;
+	if (copy_to_user(buffer, data, size)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	*ppos += size;
+	ret = size;
+
+out:
+	kfree(proc_buffer);
+	return ret;
+}
+
+static struct proc_dir_entry *efi_systab_entry;
+static struct file_operations efi_systab_fops = {
+	.read = efi_systab_read,
+};
 
 static int __init
 efivars_init(void)
 {
-
 	efi_status_t status;
 	efi_guid_t vendor_guid;
 	efi_char16_t *variable_name = kmalloc(1024, GFP_KERNEL);
 	unsigned long variable_name_size = 1024;
 
-	spin_lock(&efivars_lock);
-
 	printk(KERN_INFO "EFI Variables Facility v%s\n", EFIVARS_VERSION);
 
-        /* Since efi.c happens before procfs is available,
-           we create the directory here if it doesn't
-           already exist.  There's probably a better way
-           to do this.
-        */
-        if (!efi_dir)
+	/* Since efi.c happens before procfs is available,
+	   we create the directory here if it doesn't
+	   already exist.  There's probably a better way
+	   to do this.
+	*/
+	if (!efi_dir)
                 efi_dir = proc_mkdir("efi", NULL);
 
-	efi_vars_dir = proc_mkdir("vars", efi_dir);
-
+	efi_systab_entry = create_proc_entry("systab", S_IRUSR | S_IRGRP, efi_dir);
+	if (efi_systab_entry)
+		efi_systab_entry->proc_fops = &efi_systab_fops;
 
+	efi_vars_dir = proc_mkdir("vars", efi_dir);
 
 	/* Per EFI spec, the maximum storage allocated for both
 	   the variable name and variable data is 1024 bytes.
@@ -398,7 +472,6 @@
 	} while (status != EFI_NOT_FOUND);
 
 	kfree(variable_name);
-	spin_unlock(&efivars_lock);
 	return 0;
 }
 
@@ -409,16 +482,17 @@
 	efivar_entry_t *efivar;
 
 	spin_lock(&efivars_lock);
-
+	if (efi_systab_entry)
+		remove_proc_entry(efi_systab_entry->name, efi_dir);
 	list_for_each_safe(pos, n, &efivar_list) {
 		efivar = efivar_entry(pos);
 		remove_proc_entry(efivar->entry->name, efi_vars_dir);
 		list_del(&efivar->list);
 		kfree(efivar);
 	}
-	remove_proc_entry(efi_vars_dir->name, efi_dir);
 	spin_unlock(&efivars_lock);
 
+	remove_proc_entry(efi_vars_dir->name, efi_dir);
 }
 
 module_init(efivars_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/entry.S linux-2.4.22-pre10/arch/ia64/kernel/entry.S
--- linux-2.4.21/arch/ia64/kernel/entry.S	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/entry.S	2003-08-01 13:32:00.000000000 +0000
@@ -161,7 +161,7 @@
 	mov r8=r13			// return pointer to previously running task
 	mov r13=in0			// set "current" pointer
 	;;
-(p6)	ssm psr.i			// renable psr.i AFTER the ic bit is serialized
+	ssm psr.i			// renable psr.i AFTER the ic bit is serialized
 	DO_LOAD_SWITCH_STACK
 
 #ifdef CONFIG_SMP
@@ -454,7 +454,14 @@
 
 GLOBAL_ENTRY(ia64_trace_syscall)
 	PT_REGS_UNWIND_INFO(0)
+{	/*
+	 * Some versions of gas generate bad unwind info if the first instruction of a
+	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
+	 */
+	nop.m 0
+	nop.i 0
 	br.call.sptk.many rp=invoke_syscall_trace // give parent a chance to catch syscall args
+}
 .ret6:	br.call.sptk.many rp=b6			// do the syscall
 strace_check_retval:
 	cmp.lt p6,p0=r8,r0			// syscall failed?
@@ -484,12 +491,19 @@
 
 GLOBAL_ENTRY(ia64_ret_from_clone)
 	PT_REGS_UNWIND_INFO(0)
+{	/*
+	 * Some versions of gas generate bad unwind info if the first instruction of a
+	 * procedure doesn't go into the first slot of a bundle.  This is a workaround.
+	 */
+	nop.m 0
+	nop.i 0
 	/*
 	 * We need to call schedule_tail() to complete the scheduling process.
 	 * Called by ia64_switch_to after do_fork()->copy_thread().  r8 contains the
 	 * address of the previously executing task.
 	 */
 	br.call.sptk.many rp=ia64_invoke_schedule_tail
+}
 .ret8:
 	adds r2=IA64_TASK_PTRACE_OFFSET,r13
 	;;
@@ -652,7 +666,7 @@
 	 * NOTE: alloc, loadrs, and cover can't be predicated.
 	 */
 (pNonSys) br.cond.dpnt dont_preserve_current_frame
-	cover				// add current frame into dirty partition
+	cover				// add current frame into dirty partition and set cr.ifs
 	;;
 	mov r19=ar.bsp			// get new backing store pointer
 	sub r16=r16,r18			// krbs = old bsp - size of dirty partition
@@ -678,24 +692,12 @@
 #	define Nregs	14
 #endif
 	alloc loc0=ar.pfs,2,Nregs-2,2,0
-	shr.u loc1=r18,9		// RNaTslots <= dirtySize / (64*8) + 1
+	shr.u loc1=r18,9		// RNaTslots <= floor(dirtySize / (64*8))
 	sub r17=r17,r18			// r17 = (physStackedSize + 8) - dirtySize
 	;;
-#if 1
-	.align 32		// see comment below about gas bug...
-#endif
 	mov ar.rsc=r19			// load ar.rsc to be used for "loadrs"
 	shladd in0=loc1,3,r17
 	mov in1=0
-#if 0
-	// gas-2.11.90 is unable to generate a stop bit after .align, which is bad,
-	// because alloc must be at the beginning of an insn-group.
-	.align 32
-#else
-	nop 0
-	nop 0
-	nop 0
-#endif
 	;;
 rse_clear_invalid:
 #ifdef CONFIG_ITANIUM
@@ -737,13 +739,13 @@
 	;;
 	mov loc3=0
 	mov loc4=0
-	mov loc9=0
 	mov loc5=0
 	mov loc6=0
+	mov loc7=0
 (pRecurse) br.call.sptk.many b6=rse_clear_invalid
 	;;
-	mov loc7=0
 	mov loc8=0
+	mov loc9=0
 	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
 	mov loc10=0
 	mov loc11=0
@@ -848,13 +850,14 @@
 	mov r9=ar.unat
 	mov loc0=rp				// save return address
 	mov out0=0				// there is no "oldset"
-	adds out1=0,sp				// out1=&sigscratch
+	adds out1=8,sp				// out1=&sigscratch->ar_pfs
 (pSys)	mov out2=1				// out2==1 => we're in a syscall
 	;;
 (pNonSys) mov out2=0				// out2==0 => not a syscall
 	.fframe 16
 	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)
 	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
+	st8 [out1]=loc1,-8			// save ar.pfs, out1=&sigscratch
 	.body
 	br.call.sptk.many rp=ia64_do_signal
 .ret15:	.restore sp
@@ -875,11 +878,12 @@
 	mov loc0=rp				// save return address
 	mov out0=in0				// mask
 	mov out1=in1				// sigsetsize
-	adds out2=0,sp				// out2=&sigscratch
+	adds out2=8,sp				// out2=&sigscratch->ar_pfs
 	;;
 	.fframe 16
 	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)
 	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
+	st8 [out2]=loc1,-8			// save ar.pfs, out2=&sigscratch
 	.body
 	br.call.sptk.many rp=ia64_rt_sigsuspend
 .ret17:	.restore sp
@@ -915,17 +919,16 @@
 END(sys_rt_sigreturn)
 
 GLOBAL_ENTRY(ia64_prepare_handle_unaligned)
-	//
-	// r16 = fake ar.pfs, we simply need to make sure
-	// privilege is still 0
-	//
-	mov r16=r0
 	.prologue
+	/*
+	 * r16 = fake ar.pfs, we simply need to make sure privilege is still 0
+	 */
+	mov r16=r0
 	DO_SAVE_SWITCH_STACK
-	br.call.sptk.many rp=ia64_handle_unaligned // stack frame setup in ivt
+	br.call.sptk.many rp=ia64_handle_unaligned	// stack frame setup in ivt
 .ret21:	.body
 	DO_LOAD_SWITCH_STACK
-	br.cond.sptk.many rp			  // goes to ia64_leave_kernel
+	br.cond.sptk.many rp				// goes to ia64_leave_kernel
 END(ia64_prepare_handle_unaligned)
 
 	//
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/gate.S linux-2.4.22-pre10/arch/ia64/kernel/gate.S
--- linux-2.4.21/arch/ia64/kernel/gate.S	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/gate.S	2003-08-01 13:34:20.000000000 +0000
@@ -63,15 +63,19 @@
 	 * call stack.
 	 */
 
+#define SIGTRAMP_SAVES										\
+	.unwabi @svr4, 's';	/* mark this as a sigtramp handler (saves scratch regs) */	\
+	.savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF;						\
+	.savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF;						\
+	.savesp pr, PR_OFF+SIGCONTEXT_OFF;     							\
+	.savesp rp, RP_OFF+SIGCONTEXT_OFF;							\
+	.savesp ar.pfs, CFM_OFF+SIGCONTEXT_OFF;							\
+	.vframesp SP_OFF+SIGCONTEXT_OFF
+
 GLOBAL_ENTRY(ia64_sigtramp)
 	// describe the state that is active when we get here:
 	.prologue
-	.unwabi @svr4, 's'		// mark this as a sigtramp handler (saves scratch regs)
-	.savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF
-	.savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF
-	.savesp pr, PR_OFF+SIGCONTEXT_OFF
-	.savesp rp, RP_OFF+SIGCONTEXT_OFF
-	.vframesp SP_OFF+SIGCONTEXT_OFF
+	SIGTRAMP_SAVES
 	.body
 
 	.label_state 1
@@ -89,9 +93,7 @@
 	.spillsp.p p8, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
 (p8)	br.cond.spnt setup_rbs		// yup -> (clobbers r14, r15, and r16)
 back_from_setup_rbs:
-
-	.spillreg ar.pfs, r8
-	alloc r8=ar.pfs,0,0,3,0		// get CFM0, EC0, and CPL0 into r8
+	alloc r8=ar.pfs,0,0,3,0
 	ld8 out0=[base0],16		// load arg0 (signum)
 	adds base1=(ARG1_OFF-(RBS_BASE_OFF+SIGCONTEXT_OFF)),base1
 	;;
@@ -100,17 +102,12 @@
 	;;
 	ld8 out2=[base0]		// load arg2 (sigcontextp)
 	ld8 gp=[r17]			// get signal handler's global pointer
-
 	adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
 	;;
 	.spillsp ar.bsp, BSP_OFF+SIGCONTEXT_OFF
-	st8 [base0]=r9,(CFM_OFF-BSP_OFF)	// save sc_ar_bsp
-	dep r8=0,r8,38,26			// clear EC0, CPL0 and reserved bits
-	adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
-	;;
-	.spillsp ar.pfs, CFM_OFF+SIGCONTEXT_OFF
-	st8 [base0]=r8				// save CFM0
+	st8 [base0]=r9			// save sc_ar_bsp
 	adds base0=(FR6_OFF+SIGCONTEXT_OFF),sp
+	adds base1=(FR6_OFF+16+SIGCONTEXT_OFF),sp
 	;;
 	stf.spill [base0]=f6,32
 	stf.spill [base1]=f7,32
@@ -133,7 +130,6 @@
 	ld8 r15=[base0],(CFM_OFF-BSP_OFF)	// fetch sc_ar_bsp and advance to CFM_OFF
 	mov r14=ar.bsp
 	;;
-	ld8 r8=[base0]				// restore (perhaps modified) CFM0, EC0, and CPL0
 	cmp.ne p8,p0=r14,r15			// do we need to restore the rbs?
 (p8)	br.cond.spnt restore_rbs		// yup -> (clobbers r14-r18, f6 & f7)
 	;;
@@ -156,10 +152,11 @@
 	ldf.fill f14=[base0],32
 	ldf.fill f15=[base1],32
 	mov r15=__NR_rt_sigreturn
+	.restore sp				// pop .prologue
 	break __BREAK_SYSCALL
 
-	.body
-	.copy_state 1
+	.prologue
+	SIGTRAMP_SAVES
 setup_rbs:
 	mov ar.rsc=0				// put RSE into enforced lazy mode
 	;;
@@ -171,6 +168,7 @@
 	;;
 	.spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
 	st8 [r14]=r16				// save sc_ar_rnat
+	.body
 	adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp
 
 	mov.m r16=ar.bsp			// sc_loadrs <- (new bsp - new bspstore) << 16
@@ -182,10 +180,11 @@
 	;;
 	st8 [r14]=r15				// save sc_loadrs
 	mov ar.rsc=0xf				// set RSE into eager mode, pl 3
+	.restore sp				// pop .prologue
 	br.cond.sptk back_from_setup_rbs
 
 	.prologue
-	.copy_state 1
+	SIGTRAMP_SAVES
 	.spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
 	.body
 restore_rbs:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/ia64_ksyms.c linux-2.4.22-pre10/arch/ia64/kernel/ia64_ksyms.c
--- linux-2.4.21/arch/ia64/kernel/ia64_ksyms.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/ia64_ksyms.c	2003-08-01 13:33:10.000000000 +0000
@@ -4,6 +4,9 @@
 #include <linux/config.h>
 #include <linux/module.h>
 
+#include <linux/pm.h>
+EXPORT_SYMBOL(pm_idle);
+
 #include <linux/string.h>
 
 EXPORT_SYMBOL_NOVERS(memset);
@@ -47,6 +50,7 @@
 EXPORT_SYMBOL(__ia64_memcpy_fromio);
 EXPORT_SYMBOL(__ia64_memcpy_toio);
 EXPORT_SYMBOL(__ia64_memset_c_io);
+EXPORT_SYMBOL(io_space);
 
 #include <asm/semaphore.h>
 EXPORT_SYMBOL_NOVERS(__down);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/iosapic.c linux-2.4.22-pre10/arch/ia64/kernel/iosapic.c
--- linux-2.4.21/arch/ia64/kernel/iosapic.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/iosapic.c	2003-08-01 13:33:13.000000000 +0000
@@ -4,7 +4,7 @@
  * Copyright (C) 1999 Intel Corp.
  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
  * Copyright (C) 2000-2002 J.I. Lee <jung-ik.lee@intel.com>
- * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co.
+ * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co.
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
@@ -28,6 +28,9 @@
  * 02/07/29	T. Kochi	Allocate interrupt vectors dynamically
  * 02/08/04	T. Kochi	Cleaned up terminology (irq, global system interrupt, vector, etc.)
  * 02/08/13	B. Helgaas	Support PCI segments
+ * 03/02/19	B. Helgaas	Make pcat_compat system-wide, not per-IOSAPIC.
+ *				Remove iosapic_address & gsi_base from external interfaces.
+ *				Rationalize __init/__devinit attributes.
  */
 /*
  * Here is what the interrupt logic between a PCI device and the CPU looks like:
@@ -63,14 +66,14 @@
  */
 #include <linux/config.h>
 
-#include <linux/kernel.h>
+#include <linux/acpi.h>
 #include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/string.h>
-#include <linux/irq.h>
-#include <linux/acpi.h>
 
 #include <asm/delay.h>
 #include <asm/hw_irq.h>
@@ -83,7 +86,6 @@
 
 
 #undef DEBUG_INTERRUPT_ROUTING
-#undef OVERRIDE_DEBUG
 
 #ifdef DEBUG_INTERRUPT_ROUTING
 #define DBG(fmt...)	printk(fmt)
@@ -115,23 +117,26 @@
 	char		*addr;		/* base address of IOSAPIC */
 	unsigned int 	gsi_base;	/* first GSI assigned to this IOSAPIC */
 	unsigned short 	num_rte;	/* number of RTE in this IOSAPIC */
-	unsigned char	pcat_compat;	/* 8259 compatibility flag */
-} iosapic_lists[256] __devinitdata;
+} iosapic_lists[256];
 
-static int __devinitdata num_iosapic = 0;
+static int num_iosapic;
+
+static unsigned char pcat_compat __initdata;	/* 8259 compatibility flag */
 
 
 /*
  * Find an IOSAPIC associated with a GSI
  */
-static inline int __devinit
+static inline int
 find_iosapic (unsigned int gsi)
 {
 	int i;
 
-	for (i = 0; i < num_iosapic; i++)
+	for (i = 0; i < num_iosapic; i++) {
 		if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)
 			return i;
+	}
+
 	return -1;
 }
 
@@ -159,6 +164,8 @@
 	int rte_index;
 	char redir;
 
+	DBG(KERN_DEBUG "IOSAPIC: routing vector %d to 0x%x\n", vector, dest);
+
 	rte_index = iosapic_intr_info[vector].rte_index;
 	if (rte_index < 0)
 		return;		/* not an IOSAPIC interrupt */
@@ -171,7 +178,7 @@
 	redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0;
 #ifdef CONFIG_SMP
 	{
-		int irq;
+		unsigned int irq;
 
 		for (irq = 0; irq < NR_IRQS; ++irq)
 			if (irq_to_vector(irq) == vector) {
@@ -333,14 +340,14 @@
 #define iosapic_ack_level_irq		nop
 
 struct hw_interrupt_type irq_type_iosapic_level = {
-	typename:	"IO-SAPIC-level",
-	startup:	iosapic_startup_level_irq,
-	shutdown:	iosapic_shutdown_level_irq,
-	enable:		iosapic_enable_level_irq,
-	disable:	iosapic_disable_level_irq,
-	ack:		iosapic_ack_level_irq,
-	end:		iosapic_end_level_irq,
-	set_affinity:	iosapic_set_affinity
+	.typename =	"IO-SAPIC-level",
+	.startup =	iosapic_startup_level_irq,
+	.shutdown =	iosapic_shutdown_level_irq,
+	.enable =	iosapic_enable_level_irq,
+	.disable =	iosapic_disable_level_irq,
+	.ack =		iosapic_ack_level_irq,
+	.end =		iosapic_end_level_irq,
+	.set_affinity =	iosapic_set_affinity
 };
 
 /*
@@ -377,14 +384,14 @@
 #define iosapic_end_edge_irq		nop
 
 struct hw_interrupt_type irq_type_iosapic_edge = {
-	typename:	"IO-SAPIC-edge",
-	startup:	iosapic_startup_edge_irq,
-	shutdown:	iosapic_disable_edge_irq,
-	enable:		iosapic_enable_edge_irq,
-	disable:	iosapic_disable_edge_irq,
-	ack:		iosapic_ack_edge_irq,
-	end:		iosapic_end_edge_irq,
-	set_affinity:	iosapic_set_affinity
+	.typename =	"IO-SAPIC-edge",
+	.startup =	iosapic_startup_edge_irq,
+	.shutdown =	iosapic_disable_edge_irq,
+	.enable =	iosapic_enable_edge_irq,
+	.disable =	iosapic_disable_edge_irq,
+	.ack =		iosapic_ack_edge_irq,
+	.end =		iosapic_end_edge_irq,
+	.set_affinity =	iosapic_set_affinity
 };
 
 unsigned int
@@ -407,7 +414,7 @@
  * if the given vector is already owned by other,
  *  assign a new vector for the other and make the vector available
  */
-static void
+static void __init
 iosapic_reassign_vector (int vector)
 {
 	int new_vector;
@@ -417,67 +424,52 @@
 	    || iosapic_intr_info[vector].polarity || iosapic_intr_info[vector].trigger)
 	{
 		new_vector = ia64_alloc_vector();
-		printk("Reassigning Vector %d to %d\n", vector, new_vector);
-		memcpy (&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
-			sizeof(struct iosapic_intr_info));
-		memset (&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info));
+		printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector);
+		memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
+		       sizeof(struct iosapic_intr_info));
+		memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info));
 		iosapic_intr_info[vector].rte_index = -1;
 	}
 }
 
 static void
 register_intr (unsigned int gsi, int vector, unsigned char delivery,
-	       unsigned long polarity, unsigned long edge_triggered,
-	       unsigned int gsi_base, char *iosapic_address)
+	       unsigned long polarity, unsigned long trigger)
 {
 	irq_desc_t *idesc;
 	struct hw_interrupt_type *irq_type;
 	int rte_index;
+	int index;
+	unsigned long gsi_base;
+	char *iosapic_address;
+
+	index = find_iosapic(gsi);
+	if (index < 0) {
+		printk(KERN_WARNING "%s: No IOSAPIC for GSI 0x%x\n", __FUNCTION__, gsi);
+		return;
+	}
+
+	iosapic_address = iosapic_lists[index].addr;
+	gsi_base = iosapic_lists[index].gsi_base;
 
 	rte_index = gsi - gsi_base;
 	iosapic_intr_info[vector].rte_index = rte_index;
-	iosapic_intr_info[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW;
+	iosapic_intr_info[vector].polarity = polarity;
 	iosapic_intr_info[vector].dmode    = delivery;
+	iosapic_intr_info[vector].addr     = iosapic_address;
+	iosapic_intr_info[vector].gsi_base = gsi_base;
+	iosapic_intr_info[vector].trigger  = trigger;
 
-	/*
-	 * In override, it may not provide addr/gsi_base.  GSI is enough to
-	 * locate iosapic addr, gsi_base and rte_index by examining
-	 * gsi_base and num_rte of registered iosapics (tbd)
-	 */
-#ifndef	OVERRIDE_DEBUG
-	if (iosapic_address) {
-		iosapic_intr_info[vector].addr = iosapic_address;
-		iosapic_intr_info[vector].gsi_base = gsi_base;
-	}
-#else
-	if (iosapic_address) {
-		if (iosapic_intr_info[vector].addr && (iosapic_intr_info[vector].addr != iosapic_address))
-			printk("WARN: %s: diff IOSAPIC ADDRESS for GSI 0x%x, vector %d\n",
-			       __FUNCTION__, gsi, vector);
-		iosapic_intr_info[vector].addr = iosapic_address;
-		if (iosapic_intr_info[vector].gsi_base && (iosapic_intr_info[vector].gsi_base != gsi_base)) {
-			printk("WARN: %s: diff GSI base 0x%x for GSI 0x%x, vector %d\n",
-			       __FUNCTION__, gsi_base, gsi, vector);
-		}
-		iosapic_intr_info[vector].gsi_base = gsi_base;
-	} else if (!iosapic_intr_info[vector].addr)
-		printk("WARN: %s: invalid override for GSI 0x%x, vector %d\n",
-		       __FUNCTION__, gsi, vector);
-#endif
-	if (edge_triggered) {
-		iosapic_intr_info[vector].trigger = IOSAPIC_EDGE;
+	if (trigger == IOSAPIC_EDGE)
 		irq_type = &irq_type_iosapic_edge;
-	} else {
-		iosapic_intr_info[vector].trigger = IOSAPIC_LEVEL;
+	else
 		irq_type = &irq_type_iosapic_level;
-	}
 
 	idesc = irq_desc(vector);
 	if (idesc->handler != irq_type) {
 		if (idesc->handler != &no_irq_type)
-			printk("%s: changing vector %d from %s to %s\n",
-			       __FUNCTION__, vector, idesc->handler->typename,
-			       irq_type->typename);
+			printk(KERN_WARNING "%s: changing vector %d from %s to %s\n",
+			       __FUNCTION__, vector, idesc->handler->typename, irq_type->typename);
 		idesc->handler = irq_type;
 	}
 }
@@ -489,8 +481,7 @@
  */
 int
 iosapic_register_intr (unsigned int gsi,
-		       unsigned long polarity, unsigned long edge_triggered,
-		       unsigned int gsi_base, char *iosapic_address)
+		       unsigned long polarity, unsigned long trigger)
 {
 	int vector;
 	unsigned int dest = (ia64_get_lid() >> 16) & 0xffff;
@@ -500,11 +491,11 @@
 		vector = ia64_alloc_vector();
 
 	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
-		      polarity, edge_triggered, gsi_base, iosapic_address);
+		      polarity, trigger);
 
-	printk("GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
-	       gsi, (polarity ? "high" : "low"),
-	       (edge_triggered ? "edge" : "level"), dest, vector);
+	printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	       gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
+	       (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
 
 	/* program the IOSAPIC routing table */
 	set_rte(vector, dest);
@@ -515,11 +506,10 @@
  * ACPI calls this when it finds an entry for a platform interrupt.
  * Note that the irq_base and IOSAPIC address must be set in iosapic_init().
  */
-int
+int __init
 iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
 				int iosapic_vector, u16 eid, u16 id,
-				unsigned long polarity, unsigned long edge_triggered,
-				unsigned int gsi_base, char *iosapic_address)
+				unsigned long polarity, unsigned long trigger)
 {
 	unsigned char delivery;
 	int vector;
@@ -544,17 +534,16 @@
 		delivery = IOSAPIC_LOWEST_PRIORITY;
 		break;
 	      default:
-		printk("%s: invalid interrupt type (%d)\n", __FUNCTION__,
+		printk(KERN_ERR "%s: invalid interrupt type (%d)\n", __FUNCTION__,
 			int_type);
 		return -1;
 	}
 
-	register_intr(gsi, vector, delivery, polarity,
-		      edge_triggered, gsi_base, iosapic_address);
+	register_intr(gsi, vector, delivery, polarity, trigger);
 
-	printk("PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
-	       int_type, gsi, (polarity ? "high" : "low"),
-	       (edge_triggered ? "edge" : "level"), dest, vector);
+	printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	       int_type, gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
+	       (trigger == IOSAPIC_EDGE ? "edge" : "level"), dest, vector);
 
 	/* program the IOSAPIC routing table */
 	set_rte(vector, dest);
@@ -566,32 +555,20 @@
  * ACPI calls this when it finds an entry for a legacy ISA IRQ override.
  * Note that the gsi_base and IOSAPIC address must be set in iosapic_init().
  */
-void
+void __init
 iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
-			  unsigned long polarity, unsigned long edge_triggered)
+			  unsigned long polarity, unsigned long trigger)
 {
-	int index, vector;
-	unsigned int gsi_base;
-	char *addr;
+	int vector;
 	unsigned int dest = (ia64_get_lid() >> 16) & 0xffff;
 
-	index = find_iosapic(gsi);
-
-	if (index < 0) {
-		printk("ISA: No corresponding IOSAPIC found : ISA IRQ %u -> GSI 0x%x\n", isa_irq, gsi);
-		return;
-	}
-
 	vector = isa_irq_to_vector(isa_irq);
-	addr = iosapic_lists[index].addr;
-	gsi_base = iosapic_lists[index].gsi_base;
 
-	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, edge_triggered,
-		      gsi_base, addr);
+	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
 
-	DBG("ISA: IRQ %u -> GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
+	DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n",
 	    isa_irq, gsi,
-	    polarity ? "high" : "low", edge_triggered ? "edge" : "level",
+	    polarity == IOSAPIC_POL_HIGH ? "high" : "low", trigger == IOSAPIC_EDGE ? "edge" : "level",
 	    dest, vector);
 
 	/* program the IOSAPIC routing table */
@@ -624,13 +601,11 @@
 static int
 pci_pin_to_vector (int segment, int bus, int slot, int pci_pin)
 {
-	int index, vector;
-	int gsi_base, pcat_compat;
-	char *addr;
+	int vector;
 	unsigned int gsi;
 
 	if (pci_pin_to_gsi(segment, bus, slot, pci_pin, &gsi) < 0) {
-		printk("PCI: no interrupt route for %02x:%02x:%02x pin %c\n",
+		printk(KERN_ERR "PCI: no interrupt route for %02x:%02x:%02x pin %c\n",
 			segment, bus, slot, 'A' + pci_pin);
 		return -1;
 	}
@@ -638,19 +613,7 @@
 	vector = gsi_to_vector(gsi);
 
 	if (vector < 0) {
-		/* we should allocate a vector for this interrupt line */
-
-		index = find_iosapic(gsi);
-
-		if (index < 0) {
-			printk("PCI: GSI 0x%x has no IOSAPIC mapping\n", gsi);
-			return -1;
-		}
-
-		addr = iosapic_lists[index].addr;
-		gsi_base = iosapic_lists[index].gsi_base;
-		pcat_compat = iosapic_lists[index].pcat_compat;
-
+		/* allocate a vector for this interrupt line */
 		if (pcat_compat && (gsi < 16))
 			vector = isa_irq_to_vector(gsi);
 		else {
@@ -658,8 +621,7 @@
 			vector = ia64_alloc_vector();
 		}
 
-		register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
-			      0, 0, gsi_base, addr);
+		register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW, IOSAPIC_LEVEL);
 
 		DBG("PCI: (%02x:%02x:%02x INT%c) -> GSI 0x%x -> vector %d\n",
 		    segment, bus, slot, 'A' + pci_pin, gsi, vector);
@@ -668,29 +630,32 @@
 	return vector;
 }
 
-void __devinit
-iosapic_init (unsigned long phys_addr, unsigned int gsi_base, int pcat_compat)
+void __init
+iosapic_system_init (int system_pcat_compat)
 {
-	int num_rte, vector;
-	unsigned int isa_irq, ver;
-	char *addr;
-	static int first_time = 1;
+	int vector;
 
-	if (first_time) {
-		first_time = 0;
-		for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
-			iosapic_intr_info[vector].rte_index = -1;	/* mark as unused */
-	}
+	for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
+		iosapic_intr_info[vector].rte_index = -1;	/* mark as unused */
 
+	pcat_compat = system_pcat_compat;
 	if (pcat_compat) {
 		/*
 		 * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support
 		 * enabled.
 		 */
-		printk("%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__);
+		printk(KERN_INFO "%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__);
 		outb(0xff, 0xA1);
 		outb(0xff, 0x21);
 	}
+}
+
+void __init
+iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
+{
+	int num_rte;
+	unsigned int isa_irq, ver;
+	char *addr;
 
 	addr = ioremap(phys_addr, 0);
 	ver = iosapic_version(addr);
@@ -703,35 +668,22 @@
 	num_rte = ((ver >> 16) & 0xff) + 1;
 
 	iosapic_lists[num_iosapic].addr = addr;
-	iosapic_lists[num_iosapic].pcat_compat = pcat_compat;
 	iosapic_lists[num_iosapic].gsi_base = gsi_base;
 	iosapic_lists[num_iosapic].num_rte = num_rte;
 	num_iosapic++;
 
-	printk("IOSAPIC: version %x.%x, address 0x%lx, GSIs 0x%x-0x%x\n",
+	printk(KERN_INFO "  IOSAPIC v%x.%x, address 0x%lx, GSIs 0x%x-0x%x\n",
 	       (ver & 0xf0) >> 4, (ver & 0x0f), phys_addr, gsi_base, gsi_base + num_rte - 1);
 
 	if ((gsi_base == 0) && pcat_compat) {
-		unsigned int dest = (ia64_get_lid() >> 16) & 0xffff;
 
 		/*
 		 * Map the legacy ISA devices into the IOSAPIC data.  Some of these may
 		 * get reprogrammed later on with data from the ACPI Interrupt Source
 		 * Override table.
 		 */
-		for (isa_irq = 0; isa_irq < 16; ++isa_irq) {
-			vector = isa_irq_to_vector(isa_irq);
-
-			register_intr(isa_irq, vector, IOSAPIC_LOWEST_PRIORITY,
-				     /* IOSAPIC_POL_HIGH, IOSAPIC_EDGE */
-				     1, 1, gsi_base, addr);
-
-			DBG("ISA: IRQ %u -> GSI 0x%x (high,edge) -> CPU 0x%04x vector %d\n",
-			    isa_irq, isa_irq, dest, vector);
-
-			/* program the IOSAPIC routing table: */
-			set_rte(vector, dest);
-		}
+		for (isa_irq = 0; isa_irq < 16; ++isa_irq)
+			iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
 	}
 }
 
@@ -790,7 +742,7 @@
 			idesc = irq_desc(vector);
 			if (idesc->handler != irq_type) {
 				if (idesc->handler != &no_irq_type)
-					printk("%s: changing vector %d from %s to %s\n",
+					printk(KERN_INFO "%s: changing vector %d from %s to %s\n",
 					       __FUNCTION__, vector,
 					       idesc->handler->typename,
 					       irq_type->typename);
@@ -822,7 +774,7 @@
 			dest = (ia64_get_lid() >> 16) & 0xffff;
 #endif
 
-			printk("PCI->APIC IRQ transform: (%s INT%c) -> CPU 0x%04x vector %d\n",
+			printk(KERN_INFO "PCI->APIC IRQ transform: (%s INT%c) -> CPU 0x%04x vector %d\n",
 			       dev->slot_name, 'A' + pci_pin, dest, vector);
 			set_rte(vector, dest);
 		}
@@ -837,7 +789,7 @@
 
 	if (phase == 0) {
 		if (0 != acpi_get_prt(&pci_irq.route, &pci_irq.num_routes)) {
-			printk("%s: acpi_get_prt failed\n", __FUNCTION__);
+			printk(KERN_ERR "%s: acpi_get_prt failed\n", __FUNCTION__);
 		}
 		return;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/irq.c linux-2.4.22-pre10/arch/ia64/kernel/irq.c
--- linux-2.4.21/arch/ia64/kernel/irq.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/irq.c	2003-08-01 13:32:24.000000000 +0000
@@ -111,7 +111,7 @@
  * a generic callback i think.
  */
 #if CONFIG_X86
-	printk("unexpected IRQ trap at vector %02x\n", irq);
+	printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
 	 * Currently unexpected vectors happen only on SMP and APIC.
@@ -125,7 +125,7 @@
 #endif
 #endif
 #if CONFIG_IA64
-	printk("Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id());
+	printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id());
 #endif
 }
 
@@ -591,7 +591,7 @@
 		desc->depth--;
 		break;
 	case 0:
-		printk("enable_irq(%u) unbalanced from %p\n",
+		printk(KERN_ERR "enable_irq(%u) unbalanced from %p\n",
 		       irq, (void *) __builtin_return_address(0));
 	}
 	spin_unlock_irqrestore(&desc->lock, flags);
@@ -738,7 +738,7 @@
 	 */
 	if (irqflags & SA_SHIRQ) {
 		if (!dev_id)
-			printk("Bad boy: %s called us without a dev_id!\n", devname);
+			printk(KERN_ERR "Bad boy: %s called us without a dev_id!\n", devname);
 	}
 #endif
 
@@ -819,7 +819,7 @@
 			kfree(action);
 			return;
 		}
-		printk("Trying to free free IRQ%d\n",irq);
+		printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
 		spin_unlock_irqrestore(&desc->lock,flags);
 		return;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/irq_ia64.c linux-2.4.22-pre10/arch/ia64/kernel/irq_ia64.c
--- linux-2.4.21/arch/ia64/kernel/irq_ia64.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/irq_ia64.c	2003-08-01 13:32:48.000000000 +0000
@@ -148,9 +148,9 @@
 extern void handle_IPI (int irq, void *dev_id, struct pt_regs *regs);
 
 static struct irqaction ipi_irqaction = {
-	handler:	handle_IPI,
-	flags:		SA_INTERRUPT,
-	name:		"IPI"
+	.handler =	handle_IPI,
+	.flags =	SA_INTERRUPT,
+	.name =		"IPI"
 };
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/irq_lsapic.c linux-2.4.22-pre10/arch/ia64/kernel/irq_lsapic.c
--- linux-2.4.21/arch/ia64/kernel/irq_lsapic.c	2001-07-31 17:30:08.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/irq_lsapic.c	2003-08-01 13:32:15.000000000 +0000
@@ -27,12 +27,12 @@
 }
 
 struct hw_interrupt_type irq_type_ia64_lsapic = {
-	typename:	"LSAPIC",
-	startup:	lsapic_noop_startup,
-	shutdown:	lsapic_noop,
-	enable:		lsapic_noop,
-	disable:	lsapic_noop,
-	ack:		lsapic_noop,
-	end:		lsapic_noop,
-	set_affinity:	(void (*)(unsigned int, unsigned long)) lsapic_noop
+	.typename =	"LSAPIC",
+	.startup =	lsapic_noop_startup,
+	.shutdown =	lsapic_noop,
+	.enable =	lsapic_noop,
+	.disable =	lsapic_noop,
+	.ack =		lsapic_noop,
+	.end =		lsapic_noop,
+	.set_affinity =	(void (*)(unsigned int, unsigned long)) lsapic_noop
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/machvec.c linux-2.4.22-pre10/arch/ia64/kernel/machvec.c
--- linux-2.4.21/arch/ia64/kernel/machvec.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/machvec.c	2003-08-01 13:33:18.000000000 +0000
@@ -44,7 +44,7 @@
 		panic("generic kernel failed to find machine vector for platform %s!", name);
 	}
 	ia64_mv = *mv;
-	printk("booting generic kernel on platform %s\n", name);
+	printk(KERN_INFO "booting generic kernel on platform %s\n", name);
 }
 
 #endif /* CONFIG_IA64_GENERIC */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/mca.c linux-2.4.22-pre10/arch/ia64/kernel/mca.c
--- linux-2.4.21/arch/ia64/kernel/mca.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/mca.c	2003-08-01 13:33:13.000000000 +0000
@@ -3,6 +3,9 @@
  * Purpose:	Generic MCA handling layer
  *
  * Updated for latest kernel
+ * Copyright (C) 2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *
  * Copyright (C) 2002 Dell Computer Corporation
  * Copyright (C) Matt Domsch (Matt_Domsch@dell.com)
  *
@@ -18,6 +21,7 @@
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) Vijay Chander(vijay@engr.sgi.com)
  *
+ * 03/04/15 D. Mosberger Added INIT backtrace support.
  * 02/03/25 M. Domsch	GUID cleanups
  *
  * 02/01/04 J. Hall	Aligned MCA stack to 16 bytes, added platform vs. CPU
@@ -45,7 +49,9 @@
 #include <linux/timer.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/smp.h>
 
+#include <asm/delay.h>
 #include <asm/machvec.h>
 #include <asm/page.h>
 #include <asm/ptrace.h>
@@ -53,11 +59,14 @@
 #include <asm/sal.h>
 #include <asm/mca.h>
 
+#include <asm/processor.h>
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
 
 #undef MCA_PRT_XTRA_DATA
 
+#define print_symbol(fmt, addr)	printk(fmt, "");
+
 typedef struct ia64_fptr {
 	unsigned long fp;
 	unsigned long gp;
@@ -70,7 +79,7 @@
 u64				ia64_mca_stack[1024] __attribute__((aligned(16)));
 u64				ia64_mca_stackframe[32];
 u64				ia64_mca_bspstore[1024];
-u64				ia64_init_stack[INIT_TASK_SIZE] __attribute__((aligned(16)));
+u64				ia64_init_stack[INIT_TASK_SIZE/8] __attribute__((aligned(16)));
 u64				ia64_mca_sal_data_area[1356];
 u64				ia64_tlb_functional;
 u64				ia64_os_mca_recovery_successful;
@@ -85,40 +94,50 @@
 extern struct hw_interrupt_type	irq_type_iosapic_level;
 
 static struct irqaction cmci_irqaction = {
-	handler:    ia64_mca_cmc_int_handler,
-	flags:      SA_INTERRUPT,
-	name:       "cmc_hndlr"
+	.handler =	ia64_mca_cmc_int_handler,
+	.flags =	SA_INTERRUPT,
+	.name =		"cmc_hndlr"
 };
 
 static struct irqaction mca_rdzv_irqaction = {
-	handler:    ia64_mca_rendez_int_handler,
-	flags:      SA_INTERRUPT,
-	name:       "mca_rdzv"
+	.handler =	ia64_mca_rendez_int_handler,
+	.flags =	SA_INTERRUPT,
+	.name =		"mca_rdzv"
 };
 
 static struct irqaction mca_wkup_irqaction = {
-	handler:    ia64_mca_wakeup_int_handler,
-	flags:      SA_INTERRUPT,
-	name:       "mca_wkup"
+	.handler =	ia64_mca_wakeup_int_handler,
+	.flags =	SA_INTERRUPT,
+	.name =		"mca_wkup"
 };
 
 static struct irqaction mca_cpe_irqaction = {
-	handler:    ia64_mca_cpe_int_handler,
-	flags:      SA_INTERRUPT,
-	name:       "cpe_hndlr"
+	.handler =	ia64_mca_cpe_int_handler,
+	.flags =	SA_INTERRUPT,
+	.name =		"cpe_hndlr"
 };
 
 #define MAX_CPE_POLL_INTERVAL (15*60*HZ) /* 15 minutes */
 #define MIN_CPE_POLL_INTERVAL (2*60*HZ)  /* 2 minutes */
+#define CMC_POLL_INTERVAL     (1*60*HZ)  /* 1 minute */
+#define CMC_HISTORY_LENGTH    5
 
 static struct timer_list cpe_poll_timer;
+static struct timer_list cmc_poll_timer;
+/*
+ * Start with this in the wrong state so we won't play w/ timers
+ * before the system is ready.
+ */
+static int cmc_polling_enabled = 1;
+
+extern void salinfo_log_wakeup(int);
 
 /*
  *  ia64_mca_log_sal_error_record
  *
- *  This function retrieves a specified error record type from SAL, sends it to
- *  the system log, and notifies SALs to clear the record from its non-volatile
- *  memory.
+ *  This function retrieves a specified error record type from SAL,
+ *  wakes up any processes waiting for error records, and sends it to
+ *  the system log.
  *
  *  Inputs  :   sal_info_type   (Type of error record MCA/CMC/CPE/INIT)
  *  Outputs :   platform error status
@@ -130,7 +149,7 @@
 
 	/* Get the MCA error record */
 	if (!ia64_log_get(sal_info_type, (prfunc_t)printk))
-		return platform_err;                 // no record retrieved
+		return platform_err;		/* no record retrieved */
 
 	/* TODO:
 	 * 1. analyze error logs to determine recoverability
@@ -138,11 +157,8 @@
 	 * 3. set ia64_os_mca_recovery_successful flag, if applicable
 	 */
 
+	salinfo_log_wakeup(sal_info_type);
 	platform_err = ia64_log_print(sal_info_type, (prfunc_t)printk);
-	/* temporary: only clear SAL logs on hardware-corrected errors
-		or if we're logging an error after an MCA-initiated reboot */
-	if ((sal_info_type > 1) || (called_from_init))
-		ia64_sal_clear_state_info(sal_info_type);
 
 	return platform_err;
 }
@@ -160,24 +176,174 @@
 void
 ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
 {
-	IA64_MCA_DEBUG("ia64_mca_cpe_int_handler: received interrupt. vector = %#x\n", cpe_irq);
+	IA64_MCA_DEBUG("ia64_mca_cpe_int_handler: received interrupt. CPU:%d vector = %#x\n",
+		       smp_processor_id(), cpe_irq);
 
 	/* Get the CMC error record and log it */
 	ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE, 0);
 }
 
-/*
- * This routine will be used to deal with platform specific handling
- * of the init, i.e. drop into the kernel debugger on server machine,
- * or if the processor is part of some parallel machine without a
- * console, then we would call the appropriate debug hooks here.
- */
+static void
+show_min_state (pal_min_state_area_t *minstate)
+{
+	u64 iip = minstate->pmsa_iip + ((struct ia64_psr *)(&minstate->pmsa_ipsr))->ri;
+	u64 xip = minstate->pmsa_xip + ((struct ia64_psr *)(&minstate->pmsa_xpsr))->ri;
+
+	printk("NaT bits\t%016lx\n", minstate->pmsa_nat_bits);
+	printk("pr\t\t%016lx\n", minstate->pmsa_pr);
+	printk("b0\t\t%016lx ", minstate->pmsa_br0); print_symbol("%s\n", minstate->pmsa_br0);
+	printk("ar.rsc\t\t%016lx\n", minstate->pmsa_rsc);
+	printk("cr.iip\t\t%016lx ", iip); print_symbol("%s\n", iip);
+	printk("cr.ipsr\t\t%016lx\n", minstate->pmsa_ipsr);
+	printk("cr.ifs\t\t%016lx\n", minstate->pmsa_ifs);
+	printk("xip\t\t%016lx ", xip); print_symbol("%s\n", xip);
+	printk("xpsr\t\t%016lx\n", minstate->pmsa_xpsr);
+	printk("xfs\t\t%016lx\n", minstate->pmsa_xfs);
+	printk("b1\t\t%016lx ", minstate->pmsa_br1);
+	print_symbol("%s\n", minstate->pmsa_br1);
+
+	printk("\nstatic registers r0-r15:\n");
+	printk(" r0- 3 %016lx %016lx %016lx %016lx\n",
+	       0UL, minstate->pmsa_gr[0], minstate->pmsa_gr[1], minstate->pmsa_gr[2]);
+	printk(" r4- 7 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_gr[3], minstate->pmsa_gr[4],
+	       minstate->pmsa_gr[5], minstate->pmsa_gr[6]);
+	printk(" r8-11 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_gr[7], minstate->pmsa_gr[8],
+	       minstate->pmsa_gr[9], minstate->pmsa_gr[10]);
+	printk("r12-15 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_gr[11], minstate->pmsa_gr[12],
+	       minstate->pmsa_gr[13], minstate->pmsa_gr[14]);
+
+	printk("\nbank 0:\n");
+	printk("r16-19 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank0_gr[0], minstate->pmsa_bank0_gr[1],
+	       minstate->pmsa_bank0_gr[2], minstate->pmsa_bank0_gr[3]);
+	printk("r20-23 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank0_gr[4], minstate->pmsa_bank0_gr[5],
+	       minstate->pmsa_bank0_gr[6], minstate->pmsa_bank0_gr[7]);
+	printk("r24-27 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank0_gr[8], minstate->pmsa_bank0_gr[9],
+	       minstate->pmsa_bank0_gr[10], minstate->pmsa_bank0_gr[11]);
+	printk("r28-31 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank0_gr[12], minstate->pmsa_bank0_gr[13],
+	       minstate->pmsa_bank0_gr[14], minstate->pmsa_bank0_gr[15]);
+
+	printk("\nbank 1:\n");
+	printk("r16-19 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank1_gr[0], minstate->pmsa_bank1_gr[1],
+	       minstate->pmsa_bank1_gr[2], minstate->pmsa_bank1_gr[3]);
+	printk("r20-23 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank1_gr[4], minstate->pmsa_bank1_gr[5],
+	       minstate->pmsa_bank1_gr[6], minstate->pmsa_bank1_gr[7]);
+	printk("r24-27 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank1_gr[8], minstate->pmsa_bank1_gr[9],
+	       minstate->pmsa_bank1_gr[10], minstate->pmsa_bank1_gr[11]);
+	printk("r28-31 %016lx %016lx %016lx %016lx\n",
+	       minstate->pmsa_bank1_gr[12], minstate->pmsa_bank1_gr[13],
+	       minstate->pmsa_bank1_gr[14], minstate->pmsa_bank1_gr[15]);
+}
+
+static void
+fetch_min_state (pal_min_state_area_t *ms, struct pt_regs *pt, struct switch_stack *sw)
+{
+	u64 *dst_banked, *src_banked, bit, shift, nat_bits;
+	int i;
+
+	/*
+	 * First, update the pt-regs and switch-stack structures with the contents stored
+	 * in the min-state area:
+	 */
+	if (((struct ia64_psr *) &ms->pmsa_ipsr)->ic == 0) {
+		pt->cr_ipsr = ms->pmsa_xpsr;
+		pt->cr_iip = ms->pmsa_xip;
+		pt->cr_ifs = ms->pmsa_xfs;
+	} else {
+		pt->cr_ipsr = ms->pmsa_ipsr;
+		pt->cr_iip = ms->pmsa_iip;
+		pt->cr_ifs = ms->pmsa_ifs;
+	}
+	pt->ar_rsc = ms->pmsa_rsc;
+	pt->pr = ms->pmsa_pr;
+	pt->r1 = ms->pmsa_gr[0];
+	pt->r2 = ms->pmsa_gr[1];
+	pt->r3 = ms->pmsa_gr[2];
+	sw->r4 = ms->pmsa_gr[3];
+	sw->r5 = ms->pmsa_gr[4];
+	sw->r6 = ms->pmsa_gr[5];
+	sw->r7 = ms->pmsa_gr[6];
+	pt->r8 = ms->pmsa_gr[7];
+	pt->r9 = ms->pmsa_gr[8];
+	pt->r10 = ms->pmsa_gr[9];
+	pt->r11 = ms->pmsa_gr[10];
+	pt->r12 = ms->pmsa_gr[11];
+	pt->r13 = ms->pmsa_gr[12];
+	pt->r14 = ms->pmsa_gr[13];
+	pt->r15 = ms->pmsa_gr[14];
+	dst_banked = &pt->r16;		/* r16-r31 are contiguous in struct pt_regs */
+	src_banked = ms->pmsa_bank1_gr;
+	for (i = 0; i < 16; ++i)
+		dst_banked[i] = src_banked[i];
+	pt->b0 = ms->pmsa_br0;
+	sw->b1 = ms->pmsa_br1;
+
+	/* construct the NaT bits for the pt-regs structure: */
+#	define PUT_NAT_BIT(dst, addr)					\
+	do {								\
+		bit = nat_bits & 1; nat_bits >>= 1;			\
+		shift = ((unsigned long) addr >> 3) & 0x3f;		\
+		dst = ((dst) & ~(1UL << shift)) | (bit << shift);	\
+	} while (0)
+
+	/* Rotate the saved NaT bits such that bit 0 corresponds to pmsa_gr[0]: */
+	shift = ((unsigned long) &ms->pmsa_gr[0] >> 3) & 0x3f;
+	nat_bits = (ms->pmsa_nat_bits >> shift) | (ms->pmsa_nat_bits << (64 - shift));
+
+	PUT_NAT_BIT(sw->caller_unat, &pt->r1);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r2);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r3);
+	PUT_NAT_BIT(sw->ar_unat, &sw->r4);
+	PUT_NAT_BIT(sw->ar_unat, &sw->r5);
+	PUT_NAT_BIT(sw->ar_unat, &sw->r6);
+	PUT_NAT_BIT(sw->ar_unat, &sw->r7);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r8);	PUT_NAT_BIT(sw->caller_unat, &pt->r9);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r10);	PUT_NAT_BIT(sw->caller_unat, &pt->r11);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r12);	PUT_NAT_BIT(sw->caller_unat, &pt->r13);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r14);	PUT_NAT_BIT(sw->caller_unat, &pt->r15);
+	nat_bits >>= 16;	/* skip over bank0 NaT bits */
+	PUT_NAT_BIT(sw->caller_unat, &pt->r16);	PUT_NAT_BIT(sw->caller_unat, &pt->r17);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r18);	PUT_NAT_BIT(sw->caller_unat, &pt->r19);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r20);	PUT_NAT_BIT(sw->caller_unat, &pt->r21);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r22);	PUT_NAT_BIT(sw->caller_unat, &pt->r23);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r24);	PUT_NAT_BIT(sw->caller_unat, &pt->r25);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r26);	PUT_NAT_BIT(sw->caller_unat, &pt->r27);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r28);	PUT_NAT_BIT(sw->caller_unat, &pt->r29);
+	PUT_NAT_BIT(sw->caller_unat, &pt->r30);	PUT_NAT_BIT(sw->caller_unat, &pt->r31);
+}
+
 void
-init_handler_platform (struct pt_regs *regs)
+init_handler_platform (sal_log_processor_info_t *proc_ptr,
+		       struct pt_regs *pt, struct switch_stack *sw)
 {
+	struct unw_frame_info info;
+
 	/* if a kernel debugger is available call it here else just dump the registers */
 
-	show_regs(regs);		/* dump the state info */
+	/*
+	 * Wait for a bit.  On some machines (e.g., HP's zx2000 and zx6000, INIT can be
+	 * generated via the BMC's command-line interface, but since the console is on the
+	 * same serial line, the user will need some time to switch out of the BMC before
+	 * the dump begins.
+	 */
+	printk("Delaying for 5 seconds...\n");
+	udelay(5*1000000);
+	show_min_state(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area);
+
+	fetch_min_state(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area, pt, sw);
+	unw_init_from_interruption(&info, current, pt, sw);
+	ia64_do_show_stack(&info, NULL);
+
+	printk("\nINIT dump complete.  Please reboot now.\n");
 	while (1);			/* hang city if no debugger */
 }
 
@@ -202,21 +368,22 @@
  *  ia64_mca_check_errors
  *
  *  External entry to check for error records which may have been posted by SAL
- *  for a prior failure which resulted in a machine shutdown before an the
- *  error could be logged.  This function must be called after the filesystem
- *  is initialized.
+ *  for a prior failure.
  *
  *  Inputs  :   None
  *
  *  Outputs :   None
  */
-void
+int
 ia64_mca_check_errors (void)
 {
 	/*
 	 *  If there is an MCA error record pending, get it and log it.
 	 */
+	printk("CPU %d: checking for saved MCA error records\n", smp_processor_id());
 	ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA, 1);
+
+	return 0;
 }
 
 /*
@@ -234,8 +401,11 @@
 ia64_mca_register_cpev (int cpev)
 {
 	/* Register the CPE interrupt vector with SAL */
-	if (ia64_sal_mc_set_params(SAL_MC_PARAM_CPE_INT, SAL_MC_PARAM_MECHANISM_INT, cpev, 0, 0)) {
-		printk("ia64_mca_platform_init: failed to register Corrected "
+	struct ia64_sal_retval isrv;
+
+	isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_CPE_INT, SAL_MC_PARAM_MECHANISM_INT, cpev, 0, 0);
+	if (isrv.status) {
+		printk(KERN_ERR "ia64_mca_platform_init: failed to register Corrected "
 		       "Platform Error interrupt vector with SAL.\n");
 		return;
 	}
@@ -246,26 +416,9 @@
 
 #endif /* PLATFORM_MCA_HANDLERS */
 
-static char *min_state_labels[] = {
-	"nat",
-	"r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
-	"r9", "r10","r11", "r12","r13","r14", "r15",
-	"b0r16","b0r17", "b0r18", "b0r19", "b0r20",
-	"b0r21", "b0r22","b0r23", "b0r24", "b0r25",
-	"b0r26", "b0r27", "b0r28","b0r29", "b0r30", "b0r31",
-	"r16", "r17", "r18","r19", "r20", "r21","r22",
-	"r23", "r24","r25", "r26", "r27","r28", "r29", "r30","r31",
-	"preds", "br0", "rsc",
-	"iip", "ipsr", "ifs",
-	"xip", "xpsr", "xfs"
-};
-
-int ia64_pmss_dump_bank0=0;  /* dump bank 0 ? */
-
 /*
  * routine to process and prepare to dump min_state_save
  * information for debugging purposes.
- *
  */
 void
 ia64_process_min_state_save (pal_min_state_area_t *pmss)
@@ -274,30 +427,12 @@
 	u64 *tpmss_ptr = (u64 *)pmss;
 	u64 *return_min_state_ptr = ia64_mca_min_state_save_info;
 
-	/* dump out the min_state_area information */
-
 	for (i=0;i<max;i++) {
 
 		/* copy min-state register info for eventual return to PAL */
 		*return_min_state_ptr++ = *tpmss_ptr;
 
-#if 1
 		tpmss_ptr++;  /* skip to next entry */
-#else
-		/* the printing part */
-		if(!ia64_pmss_dump_bank0) {
-			if(strncmp("B0",min_state_labels[i],2)==0) {
-				tpmss_ptr++;  /* skip to next entry */
-				continue;
-			}
-		}
-
-		printk("%5s=0x%16.16lx ",min_state_labels[i],*tpmss_ptr++);
-
-		if (((i+1)%3)==0 || ((!strcmp("GR16",min_state_labels[i]))
-				     && !ia64_pmss_dump_bank0))
-			printk("\n");
-#endif
 	}
 }
 
@@ -331,6 +466,60 @@
 		       smp_processor_id(), ia64_get_cmcv());
 }
 
+/*
+ * ia64_mca_cmc_vector_disable
+ *
+ *  Mask the corrected machine check vector register in the processor.
+ *  This function is invoked on a per-processor basis.
+ *
+ * Inputs
+ *      dummy(unused)
+ *
+ * Outputs
+ *	None
+ */
+void
+ia64_mca_cmc_vector_disable (void *dummy)
+{
+	cmcv_reg_t	cmcv;
+	
+	cmcv = (cmcv_reg_t)ia64_get_cmcv();
+
+	cmcv.cmcv_mask = 1; /* Mask/disable interrupt */
+	ia64_set_cmcv(cmcv.cmcv_regval);
+
+	IA64_MCA_DEBUG("ia64_mca_cmc_vector_disable: CPU %d corrected "
+		       "machine check vector %#x disabled.\n",
+		       smp_processor_id(), cmcv.cmcv_vector);
+}
+
+/*
+ * ia64_mca_cmc_vector_enable
+ *
+ *  Unmask the corrected machine check vector register in the processor.
+ *  This function is invoked on a per-processor basis.
+ *
+ * Inputs
+ *      dummy(unused)
+ *
+ * Outputs
+ *	None
+ */
+void
+ia64_mca_cmc_vector_enable (void *dummy)
+{
+	cmcv_reg_t	cmcv;
+	
+	cmcv = (cmcv_reg_t)ia64_get_cmcv();
+
+	cmcv.cmcv_mask = 0; /* Unmask/enable interrupt */
+	ia64_set_cmcv(cmcv.cmcv_regval);
+
+	IA64_MCA_DEBUG("ia64_mca_cmc_vector_enable: CPU %d corrected "
+		       "machine check vector %#x enabled.\n",
+		       smp_processor_id(), cmcv.cmcv_vector);
+}
+
 
 #if defined(MCA_TEST)
 
@@ -413,6 +602,8 @@
 	ia64_fptr_t *mca_hldlr_ptr = (ia64_fptr_t *)ia64_os_mca_dispatch;
 	int i;
 	s64 rc;
+	struct ia64_sal_retval isrv;
+	u64 timeout = IA64_MCA_RENDEZ_TIMEOUT;	/* platform specific */
 
 	IA64_MCA_DEBUG("ia64_mca_init: begin\n");
 
@@ -428,25 +619,35 @@
 	 */
 
 	/* Register the rendezvous interrupt vector with SAL */
-	if ((rc = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_INT,
-					 SAL_MC_PARAM_MECHANISM_INT,
-					 IA64_MCA_RENDEZ_VECTOR,
-					 IA64_MCA_RENDEZ_TIMEOUT,
-					 0)))
-	{
-		printk("ia64_mca_init: Failed to register rendezvous interrupt "
+	while (1) {
+		isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_INT,
+					      SAL_MC_PARAM_MECHANISM_INT,
+					      IA64_MCA_RENDEZ_VECTOR,
+					      timeout,
+					      SAL_MC_PARAM_RZ_ALWAYS);
+		rc = isrv.status;
+		if (rc == 0)
+			break;
+		if (rc == -2) {
+			printk(KERN_INFO "ia64_mca_init: increasing MCA rendezvous timeout from "
+				"%ld to %ld\n", timeout, isrv.v0);
+			timeout = isrv.v0;
+			continue;
+		}
+		printk(KERN_ERR "ia64_mca_init: Failed to register rendezvous interrupt "
 		       "with SAL.  rc = %ld\n", rc);
 		return;
 	}
 
 	/* Register the wakeup interrupt vector with SAL */
-	if ((rc = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_WAKEUP,
-					 SAL_MC_PARAM_MECHANISM_INT,
-					 IA64_MCA_WAKEUP_VECTOR,
-					 0, 0)))
-	{
-		printk("ia64_mca_init: Failed to register wakeup interrupt with SAL.  rc = %ld\n",
-		       rc);
+	isrv = ia64_sal_mc_set_params(SAL_MC_PARAM_RENDEZ_WAKEUP,
+				      SAL_MC_PARAM_MECHANISM_INT,
+				      IA64_MCA_WAKEUP_VECTOR,
+				      0, 0);
+	rc = isrv.status;
+	if (rc) {
+		printk(KERN_ERR "ia64_mca_init: Failed to register wakeup interrupt with SAL.  "
+		       "rc = %ld\n", rc);
 		return;
 	}
 
@@ -466,8 +667,8 @@
 				       ia64_mc_info.imi_mca_handler_size,
 				       0, 0, 0)))
 	{
-		printk("ia64_mca_init: Failed to register os mca handler with SAL.  rc = %ld\n",
-		       rc);
+		printk(KERN_ERR "ia64_mca_init: Failed to register os mca handler with SAL.  "
+		       "rc = %ld\n", rc);
 		return;
 	}
 
@@ -495,8 +696,8 @@
 				       __pa(ia64_get_gp()),
 				       ia64_mc_info.imi_slave_init_handler_size)))
 	{
-		printk("ia64_mca_init: Failed to register m/s init handlers with SAL. rc = %ld\n",
-		       rc);
+		printk(KERN_ERR "ia64_mca_init: Failed to register m/s init handlers with SAL. "
+		       "rc = %ld\n", rc);
 		return;
 	}
 
@@ -546,7 +747,7 @@
 	mca_test();
 #endif /* #if defined(MCA_TEST) */
 
-	printk("Mca related initialization done\n");
+	printk(KERN_INFO "Mca related initialization done\n");
 
 	/* commented out because this is done elsewhere */
 #if 0
@@ -640,13 +841,12 @@
 void
 ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
 {
-	int flags, cpu = 0;
+	int flags;
+	int cpu = smp_processor_id();
+
 	/* Mask all interrupts */
 	save_and_cli(flags);
 
-#ifdef CONFIG_SMP
-	cpu = cpu_logical_id(hard_smp_processor_id());
-#endif
 	ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
 	/* Register with the SAL monarch that the slave has
 	 * reached SAL
@@ -719,7 +919,7 @@
 
 	/* Register pointer to new min state values */
 	ia64_os_to_sal_handoff_state.imots_new_min_state =
-		(pal_min_state_area_t *)ia64_mca_min_state_save_info;
+		ia64_mca_min_state_save_info;
 }
 
 /*
@@ -780,11 +980,68 @@
 void
 ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
 {
+	static unsigned long	cmc_history[CMC_HISTORY_LENGTH];
+	static int		index;
+	static spinlock_t	cmc_history_lock = SPIN_LOCK_UNLOCKED;
+
 	IA64_MCA_DEBUG("ia64_mca_cmc_int_handler: received interrupt vector = %#x on CPU %d\n",
 		       cmc_irq, smp_processor_id());
 
 	/* Get the CMC error record and log it */
 	ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC, 0);
+
+	spin_lock(&cmc_history_lock);
+	if (!cmc_polling_enabled) {
+		int i, count = 1; /* we know 1 happened now */
+		unsigned long now = jiffies;
+		
+		for (i = 0; i < CMC_HISTORY_LENGTH; i++) {
+			if (now - cmc_history[i] <= HZ)
+				count++;
+		}
+
+		IA64_MCA_DEBUG(KERN_INFO "CMC threshold %d/%d\n", count, CMC_HISTORY_LENGTH);
+		if (count >= CMC_HISTORY_LENGTH) {
+			/*
+			 * CMC threshold exceeded, clear the history
+			 * so we have a fresh start when we return
+			 */
+			for (index = 0 ; index < CMC_HISTORY_LENGTH; index++)
+				cmc_history[index] = 0;
+			index = 0;
+
+			/* Switch to polling mode */
+			cmc_polling_enabled = 1;
+
+			/*
+			 * Unlock & enable interrupts  before
+			 * smp_call_function or risk deadlock
+			 */
+			spin_unlock(&cmc_history_lock);
+			ia64_mca_cmc_vector_disable(NULL);
+
+			local_irq_enable();
+			smp_call_function(ia64_mca_cmc_vector_disable, NULL, 1, 1);
+
+			/*
+			 * Corrected errors will still be corrected, but
+			 * make sure there's a log somewhere that indicates
+			 * something is generating more than we can handle.
+			 */
+			printk(KERN_WARNING "ia64_mca_cmc_int_handler: WARNING: Switching to polling CMC handler, error records may be lost\n");
+			
+
+			mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
+
+			/* lock already released, get out now */
+			return;
+		} else {
+			cmc_history[index++] = now;
+			if (index == CMC_HISTORY_LENGTH)
+				index = 0;
+		}
+	}
+	spin_unlock(&cmc_history_lock);
 }
 
 /*
@@ -797,6 +1054,7 @@
 {
 	spinlock_t	isl_lock;
 	int		isl_index;
+	unsigned long	isl_count;
 	ia64_err_rec_t  *isl_log[IA64_MAX_LOGS]; /* need space to store header + error log */
 } ia64_state_log_t;
 
@@ -813,11 +1071,78 @@
 #define IA64_LOG_NEXT_INDEX(it)    ia64_state_log[it].isl_index
 #define IA64_LOG_CURR_INDEX(it)    1 - ia64_state_log[it].isl_index
 #define IA64_LOG_INDEX_INC(it) \
-    ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index
+    {ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index; \
+    ia64_state_log[it].isl_count++;}
 #define IA64_LOG_INDEX_DEC(it) \
     ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index
 #define IA64_LOG_NEXT_BUFFER(it)   (void *)((ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)]))
 #define IA64_LOG_CURR_BUFFER(it)   (void *)((ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)]))
+#define IA64_LOG_COUNT(it)         ia64_state_log[it].isl_count
+
+/*
+ *  ia64_mca_cmc_int_caller
+ *
+ * 	Call CMC interrupt handler, only purpose is to have a
+ * 	smp_call_function callable entry.
+ *
+ * Inputs   :	dummy(unused)
+ * Outputs  :	None
+ * */
+static void
+ia64_mca_cmc_int_caller(void *dummy)
+{
+	ia64_mca_cmc_int_handler(0, NULL, NULL);
+}
+
+/*
+ *  ia64_mca_cmc_poll
+ *
+ *	Poll for Corrected Machine Checks (CMCs)
+ *
+ * Inputs   :   dummy(unused)
+ * Outputs  :   None
+ *
+ */
+static void
+ia64_mca_cmc_poll (unsigned long dummy)
+{
+	int start_count;
+
+	start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CMC);
+
+	/* Call the interrupt handler */
+	smp_call_function(ia64_mca_cmc_int_caller, NULL, 1, 1);
+	local_irq_disable();
+	ia64_mca_cmc_int_caller(NULL);
+	local_irq_enable();
+
+	/*
+	 * If no log recored, switch out of polling mode.
+	 */
+	if (start_count == IA64_LOG_COUNT(SAL_INFO_TYPE_CMC)) {
+		printk(KERN_WARNING "ia64_mca_cmc_poll: Returning to interrupt driven CMC handler\n");
+		cmc_polling_enabled = 0;
+		smp_call_function(ia64_mca_cmc_vector_enable, NULL, 1, 1);
+		ia64_mca_cmc_vector_enable(NULL);
+	} else {
+		mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
+	}
+}
+
+/*
+ *  ia64_mca_cpe_int_caller
+ *
+ * 	Call CPE interrupt handler, only purpose is to have a
+ * 	smp_call_function callable entry.
+ *
+ * Inputs   :	dummy(unused)
+ * Outputs  :	None
+ * */
+static void
+ia64_mca_cpe_int_caller(void *dummy)
+{
+	ia64_mca_cpe_int_handler(0, NULL, NULL);
+}
 
 /*
  *  ia64_mca_cpe_poll
@@ -832,19 +1157,22 @@
 static void
 ia64_mca_cpe_poll (unsigned long dummy)
 {
-	int start_index;
+	int start_count;
 	static int poll_time = MAX_CPE_POLL_INTERVAL;
 
-	start_index = IA64_LOG_CURR_INDEX(SAL_INFO_TYPE_CPE);
+	start_count = IA64_LOG_COUNT(SAL_INFO_TYPE_CPE);
 
 	/* Call the interrupt handler */
-	ia64_mca_cpe_int_handler(0, NULL, NULL);
+	smp_call_function(ia64_mca_cpe_int_caller, NULL, 1, 1);
+	local_irq_disable();
+	ia64_mca_cpe_int_caller(NULL);
+	local_irq_enable();
 
 	/*
 	 * If a log was recorded, increase our polling frequency,
 	 * otherwise, backoff.
 	 */
-	if (start_index != IA64_LOG_CURR_INDEX(SAL_INFO_TYPE_CPE)) {
+	if (start_count != IA64_LOG_COUNT(SAL_INFO_TYPE_CPE)) {
 		poll_time = max(MIN_CPE_POLL_INTERVAL, poll_time/2);
 	} else {
 		poll_time = min(MAX_CPE_POLL_INTERVAL, poll_time * 2);
@@ -865,11 +1193,19 @@
 static int __init
 ia64_mca_late_init(void)
 {
-	if (acpi_request_vector(ACPI_INTERRUPT_CPEI) < 0) {
-		init_timer(&cpe_poll_timer);
-		cpe_poll_timer.function = ia64_mca_cpe_poll;
-		ia64_mca_cpe_poll(0);
-	}
+	init_timer(&cmc_poll_timer);
+	cmc_poll_timer.function = ia64_mca_cmc_poll;
+
+	/* Reset to the correct state */
+	cmc_polling_enabled = 0;
+
+	init_timer(&cpe_poll_timer);
+	cpe_poll_timer.function = ia64_mca_cpe_poll;
+
+	/* If platform doesn't support CPEI, get the timer going. */
+	if (acpi_request_vector(ACPI_INTERRUPT_CPEI) < 0)
+		ia64_mca_cpe_poll(0UL);
+
 	return 0;
 }
 
@@ -888,12 +1224,12 @@
  *
  */
 void
-ia64_init_handler (struct pt_regs *regs)
+ia64_init_handler (struct pt_regs *pt, struct switch_stack *sw)
 {
 	sal_log_processor_info_t *proc_ptr;
 	ia64_err_rec_t *plog_ptr;
 
-	printk("Entered OS INIT handler\n");
+	printk(KERN_INFO "Entered OS INIT handler\n");
 
 	/* Get the INIT processor log */
 	if (!ia64_log_get(SAL_INFO_TYPE_INIT, (prfunc_t)printk))
@@ -910,12 +1246,9 @@
 	plog_ptr=(ia64_err_rec_t *)IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_INIT);
 	proc_ptr = &plog_ptr->proc_err;
 
-	ia64_process_min_state_save(&proc_ptr->processor_static_info.min_state_area);
-
-	/* Clear the INIT SAL logs now that they have been saved in the OS buffer */
-	ia64_sal_clear_state_info(SAL_INFO_TYPE_INIT);
+	ia64_process_min_state_save(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area);
 
-	init_handler_platform(regs);              /* call platform specific routines */
+	init_handler_platform(proc_ptr, pt, sw);	/* call platform specific routines */
 }
 
 /*
@@ -1076,12 +1409,12 @@
 ia64_log_rec_header_print (sal_log_record_header_t *lh, prfunc_t prfunc)
 {
 	prfunc("+Err Record ID: %d    SAL Rev: %2x.%02x\n", lh->id,
-		lh->revision.major, lh->revision.minor);
-	prfunc("+Time: %02x/%02x/%02x%02x %02d:%02d:%02d    Severity %d\n",
-		lh->timestamp.slh_month, lh->timestamp.slh_day,
-		lh->timestamp.slh_century, lh->timestamp.slh_year,
-		lh->timestamp.slh_hour, lh->timestamp.slh_minute,
-		lh->timestamp.slh_second, lh->severity);
+			lh->revision.major, lh->revision.minor);
+	prfunc("+Time: %02x/%02x/%02x%02x %02x:%02x:%02x    Severity %d\n",
+			lh->timestamp.slh_month, lh->timestamp.slh_day,
+			lh->timestamp.slh_century, lh->timestamp.slh_year,
+			lh->timestamp.slh_hour, lh->timestamp.slh_minute,
+			lh->timestamp.slh_second, lh->severity);
 }
 
 /*
@@ -1704,7 +2037,7 @@
 	 *  absent. Also, current implementations only allocate space for number of
 	 *  elements used.  So we walk the data pointer from here on.
 	 */
-	p_data = &slpi->cache_check_info[0];
+	p_data = &slpi->info[0];
 
 	/* Print the cache check information if any*/
 	for (i = 0 ; i < slpi->valid.num_cache_check; i++, p_data++)
@@ -1821,8 +2154,7 @@
 		/*
 		 *  Now process processor device error record section
 		 */
-		ia64_log_proc_dev_err_info_print((sal_log_processor_info_t *)slsh,
-						 printk);
+		ia64_log_proc_dev_err_info_print((sal_log_processor_info_t *)slsh, printk);
 	}
 
 	IA64_MCA_DEBUG("ia64_mca_log_print: "
@@ -1965,9 +2297,8 @@
 
 	switch(sal_info_type) {
 	      case SAL_INFO_TYPE_MCA:
-		prfunc("+BEGIN HARDWARE ERROR STATE AT MCA\n");
-		platform_err = ia64_log_platform_info_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc);
-		prfunc("+END HARDWARE ERROR STATE AT MCA\n");
+		prfunc("+CPU %d: SAL log contains MCA error record\n", smp_processor_id());
+		ia64_log_rec_header_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc);
 		break;
 	      case SAL_INFO_TYPE_INIT:
 		prfunc("+MCA INIT ERROR LOG (UNIMPLEMENTED)\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/mca_asm.S linux-2.4.22-pre10/arch/ia64/kernel/mca_asm.S
--- linux-2.4.21/arch/ia64/kernel/mca_asm.S	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/mca_asm.S	2003-08-01 13:32:22.000000000 +0000
@@ -766,8 +766,6 @@
 	// stash the information the SAL passed to os
 	SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2)
 	;;
-
-// now we want to save information so we can dump registers
 	SAVE_MIN_WITH_COVER
 	;;
 	mov r8=cr.ifa
@@ -798,10 +796,12 @@
 	//
 	// Let's call the C handler to get the rest of the state info
 	//
-	alloc r14=ar.pfs,0,0,1,0		// now it's safe (must be first in insn group!)
-	;;					//
+	alloc r14=ar.pfs,0,0,2,0		// now it's safe (must be first in insn group!)
+	;;
 	adds out0=16,sp				// out0 = pointer to pt_regs
 	;;
+	DO_SAVE_SWITCH_STACK
+	adds out1=16,sp				// out0 = pointer to switch_stack
 
 	br.call.sptk.many rp=ia64_init_handler
 .ret1:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/palinfo.c linux-2.4.22-pre10/arch/ia64/kernel/palinfo.c
--- linux-2.4.21/arch/ia64/kernel/palinfo.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/palinfo.c	2003-08-01 13:30:37.000000000 +0000
@@ -6,7 +6,7 @@
  * Intel IA-64 Architecture Software Developer's Manual v1.0.
  *
  *
- * Copyright (C) 2000-2001 Hewlett-Packard Co
+ * Copyright (C) 2000-2001, 2003 Hewlett-Packard Co
  *	Stephane Eranian <eranian@hpl.hp.com>
  *
  * 05/26/2000	S.Eranian	initial release
@@ -27,9 +27,7 @@
 #include <asm/sal.h>
 #include <asm/page.h>
 #include <asm/processor.h>
-#ifdef CONFIG_SMP
 #include <linux/smp.h>
-#endif
 
 MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>");
 MODULE_DESCRIPTION("/proc interface to IA-64 PAL");
@@ -37,12 +35,6 @@
 
 #define PALINFO_VERSION "0.5"
 
-#ifdef CONFIG_SMP
-#define cpu_is_online(i) (cpu_online_map & (1UL << i))
-#else
-#define cpu_is_online(i)	1
-#endif
-
 typedef int (*palinfo_func_t)(char*);
 
 typedef struct {
@@ -101,26 +93,15 @@
 
 #define RSE_HINTS_COUNT (sizeof(rse_hints)/sizeof(const char *))
 
-/*
- * The current revision of the Volume 2 (July 2000) of
- * IA-64 Architecture Software Developer's Manual is wrong.
- * Table 4-10 has invalid information concerning the ma field:
- * Correct table is:
- *      bit 0 - 001 - UC
- *      bit 4 - 100 - UC
- *      bit 5 - 101 - UCE
- *      bit 6 - 110 - WC
- *      bit 7 - 111 - NatPage
- */
 static const char *mem_attrib[]={
-	"Write Back (WB)",		/* 000 */
-	"Uncacheable (UC)",		/* 001 */
-	"Reserved",			/* 010 */
-	"Reserved",			/* 011 */
-	"Uncacheable (UC)",		/* 100 */
-	"Uncacheable Exported (UCE)",	/* 101 */
-	"Write Coalescing (WC)",	/* 110 */
-	"NaTPage"			/* 111 */
+	"WB",		/* 000 */
+	"SW",		/* 001 */
+	"010",		/* 010 */
+	"011",		/* 011 */
+	"UC",		/* 100 */
+	"UCE",		/* 101 */
+	"WC",		/* 110 */
+	"NaTPage"	/* 111 */
 };
 
 /*
@@ -236,15 +217,12 @@
 	int i,j, k;
 	s64 status;
 
-	if ((status=ia64_pal_cache_summary(&levels, &unique_caches)) != 0) {
-			printk("ia64_pal_cache_summary=%ld\n", status);
-			return 0;
+	if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) {
+		printk(KERN_ERR "ia64_pal_cache_summary=%ld\n", status);
+		return 0;
 	}
 
-	p += sprintf(p, "Cache levels  : %ld\n" \
-			"Unique caches : %ld\n\n",
-			levels,
-			unique_caches);
+	p += sprintf(p, "Cache levels  : %ld\nUnique caches : %ld\n\n", levels, unique_caches);
 
 	for (i=0; i < levels; i++) {
 
@@ -315,11 +293,12 @@
 	pal_vm_info_2_u_t vm_info_2;
 	pal_tc_info_u_t	tc_info;
 	ia64_ptce_info_t ptce;
+	const char *sep;
 	int i, j;
 	s64 status;
 
-	if ((status=ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
-		printk("ia64_pal_vm_summary=%ld\n", status);
+	if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
+		printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status);
 		return 0;
 	}
 
@@ -339,18 +318,26 @@
 
 	if (ia64_pal_mem_attrib(&attrib) != 0) return 0;
 
-	p += sprintf(p, "Supported memory attributes    : %s\n", mem_attrib[attrib&0x7]);
+	p += sprintf(p, "Supported memory attributes    : ");
+	sep = "";
+	for (i = 0; i < 8; i++) {
+		if (attrib & (1 << i)) {
+			p += sprintf(p, "%s%s", sep, mem_attrib[i]);
+			sep = ", ";
+		}
+	}
+	p += sprintf(p, "\n");
 
-	if ((status=ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) {
-		printk("ia64_pal_vm_page_size=%ld\n", status);
+	if ((status = ia64_pal_vm_page_size(&tr_pages, &vw_pages)) !=0) {
+		printk(KERN_ERR "ia64_pal_vm_page_size=%ld\n", status);
 		return 0;
 	}
 
-	p += sprintf(p, "\nTLB walker                     : %s implemented\n" \
+	p += sprintf(p, "\nTLB walker                     : %simplemented\n" \
 			"Number of DTR                  : %d\n" \
 			"Number of ITR                  : %d\n" \
 			"TLB insertable page sizes      : ",
-			vm_info_1.pal_vm_info_1_s.vw ? "\b":"not",
+			vm_info_1.pal_vm_info_1_s.vw ? "" : "not ",
 			vm_info_1.pal_vm_info_1_s.max_dtr_entry+1,
 			vm_info_1.pal_vm_info_1_s.max_itr_entry+1);
 
@@ -362,7 +349,7 @@
 	p = bitvector_process(p, vw_pages);
 
 	if ((status=ia64_get_ptce(&ptce)) != 0) {
-		printk("ia64_get_ptce=%ld\n",status);
+		printk(KERN_ERR "ia64_get_ptce=%ld\n", status);
 		return 0;
 	}
 
@@ -712,8 +699,8 @@
 		u64 rv2:32;
 	} *rid_reg;
 
-	if ((status=ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
-		printk("ia64_pal_vm_summary=%ld\n", status);
+	if ((status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2)) !=0) {
+		printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status);
 		return 0;
 	}
 	max[0] = vm_info_1.pal_vm_info_1_s.max_itr_entry+1;
@@ -724,7 +711,8 @@
 
 		status = ia64_pal_tr_read(j, i, tr_buffer, &tr_valid);
 		if (status != 0) {
-			printk("palinfo: pal call failed on tr[%d:%d]=%ld\n", i, j, status);
+			printk(KERN_ERR "palinfo: pal call failed on tr[%d:%d]=%ld\n",
+			       i, j, status);
 			continue;
 		}
 
@@ -843,7 +831,7 @@
 {
 	palinfo_smp_data_t *data = (palinfo_smp_data_t *)info;
 	if (data == NULL) {
-		printk("%s palinfo: data pointer is NULL\n", KERN_ERR);
+		printk(KERN_ERR "palinfo: data pointer is NULL\n");
 		data->ret = 0; /* no output */
 		return;
 	}
@@ -870,7 +858,8 @@
 
 	/* will send IPI to other CPU and wait for completion of remote call */
 	if ((ret=smp_call_function_single(f->req_cpu, palinfo_smp_call, &ptr, 0, 1))) {
-		printk("palinfo: remote CPU call from %d to %d on function %d: error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret);
+		printk(KERN_ERR "palinfo: remote CPU call from %d to %d on function %d: "
+		       "error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret);
 		return 0;
 	}
 	return ptr.ret;
@@ -879,7 +868,7 @@
 static
 int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page)
 {
-	printk("palinfo: should not be called with non SMP kernel\n");
+	printk(KERN_ERR "palinfo: should not be called with non SMP kernel\n");
 	return 0;
 }
 #endif /* CONFIG_SMP */
@@ -937,7 +926,7 @@
 	 */
 	for (i=0; i < NR_CPUS; i++) {
 
-		if (!cpu_is_online(i)) continue;
+		if (!cpu_online(i)) continue;
 
 		sprintf(cpustr,CPUSTR, i);
 
@@ -947,8 +936,10 @@
 
 		for (j=0; j < NR_PALINFO_ENTRIES; j++) {
 			f.func_id = j;
-			*pdir++ = create_proc_read_entry (palinfo_entries[j].name, 0, cpu_dir,
-						palinfo_read_entry, (void *)f.value);
+			*pdir = create_proc_read_entry(
+					palinfo_entries[j].name, 0, cpu_dir,
+					palinfo_read_entry, (void *)f.value);
+			pdir++;
 		}
 		*pdir++ = cpu_dir;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/pci.c linux-2.4.22-pre10/arch/ia64/kernel/pci.c
--- linux-2.4.21/arch/ia64/kernel/pci.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/pci.c	2003-08-01 13:33:06.000000000 +0000
@@ -2,9 +2,15 @@
  * pci.c - Low-Level PCI Access in IA-64
  *
  * Derived from bios32.c of i386 tree.
+ * Copyright (C) 2002, 2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *	Bjorn Helgaas <bjorn_helgaas@hp.com>
+ *
+ * Note: Above list of copyright holders is incomplete...
  */
 #include <linux/config.h>
 
+#include <linux/acpi.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -13,9 +19,9 @@
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
-#include <linux/acpi.h>
 
 #include <asm/machvec.h>
+#include <asm/mca.h>
 #include <asm/page.h>
 #include <asm/segment.h>
 #include <asm/system.h>
@@ -39,12 +45,6 @@
 #define DBG(x...)
 #endif
 
-#ifdef CONFIG_IA64_MCA
-extern void ia64_mca_check_errors( void );
-#endif
-
-static unsigned int acpi_root_bridges;
-
 struct pci_fixup pcibios_fixups[1];
 
 struct pci_ops *pci_root_ops;
@@ -213,14 +213,14 @@
 	return b;
 }
 
-static void
+static int
 alloc_resource (char *name, struct resource *root, unsigned long start, unsigned long end, unsigned long flags)
 {
 	struct resource *res;
 
 	res = kmalloc(sizeof(*res), GFP_KERNEL);
 	if (!res)
-		return;
+		return -ENOMEM;
 
 	memset(res, 0, sizeof(*res));
 	res->name = name;
@@ -228,7 +228,10 @@
 	res->end = end;
 	res->flags = flags;
 
-	request_resource(root, res);
+	if (request_resource(root, res))
+		return -EBUSY;
+
+	return 0;
 }
 
 static u64
@@ -308,14 +311,24 @@
 		} else
 			return AE_OK;
 
+		if (addr.min_address_range == addr.max_address_range) {
+			printk(KERN_INFO "ACPI reports bogus %s %s range 0x%lx-0x%lx; ignoring it\n",
+					info->name, root->name, addr.min_address_range + offset,
+					addr.max_address_range + offset);
+			return AE_OK;
+		}
+
 		window = &info->controller->window[info->controller->windows++];
 		window->resource.flags |= flags;
 		window->resource.start  = addr.min_address_range;
 		window->resource.end    = addr.max_address_range;
 		window->offset		= offset;
 
-		alloc_resource(info->name, root, addr.min_address_range + offset,
-			addr.max_address_range + offset, flags);
+		if (alloc_resource(info->name, root, addr.min_address_range + offset,
+			addr.max_address_range + offset, flags))
+			printk(KERN_ERR "alloc 0x%lx-0x%lx from %s for %s failed\n",
+				addr.min_address_range + offset, addr.max_address_range + offset,
+				root->name, info->name);
 	}
 
 	return AE_OK;
@@ -329,8 +342,6 @@
 	unsigned int windows = 0;
 	char *name;
 
-	acpi_root_bridges++;
-
 	controller = alloc_pci_controller(seg);
 	if (!controller)
 		goto out1;
@@ -379,7 +390,6 @@
 void __init
 pcibios_init (void)
 {
-#	define PCI_BUSES_TO_SCAN 256
 	int i = 0;
 	struct pci_controller *controller;
 
@@ -391,15 +401,6 @@
 
 	platform_pci_fixup(0);	/* phase 0 fixups (before buses scanned) */
 
-	/* Only probe blindly if ACPI didn't tell us about root bridges */
-	if (!acpi_root_bridges) {
-		printk("PCI: Probing PCI hardware\n");
-		controller = alloc_pci_controller(0);
-		if (controller)
-			for (i = 0; i < PCI_BUSES_TO_SCAN; i++)
-				pci_scan_bus(i, pci_root_ops, controller);
-	}
-
 	platform_pci_fixup(1);	/* phase 1 fixups (after buses scanned) */
 
 	return;
@@ -576,9 +577,81 @@
 		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
 	if (remap_page_range(vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
-			     vma->vm_end - vma->vm_start,
-			     vma->vm_page_prot))
+			     vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;
 
 	return 0;
 }
+
+/**
+ * pci_cacheline_size - determine cacheline size for PCI devices
+ * @dev: void
+ *
+ * We want to use the line-size of the outer-most cache.  We assume
+ * that this line-size is the same for all CPUs.
+ *
+ * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info().
+ *
+ * RETURNS: An appropriate -ERRNO error value on eror, or zero for success.
+ */
+static unsigned long
+pci_cacheline_size (void)
+{
+	u64 levels, unique_caches;
+	s64 status;
+	pal_cache_config_info_t cci;
+	static u8 cacheline_size;
+
+	if (cacheline_size)
+		return cacheline_size;
+
+	status = ia64_pal_cache_summary(&levels, &unique_caches);
+	if (status != 0) {
+		printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n",
+		       __FUNCTION__, status);
+		return SMP_CACHE_BYTES;
+	}
+
+	status = ia64_pal_cache_config_info(levels - 1, /* cache_type (data_or_unified)= */ 2,
+					    &cci);
+	if (status != 0) {
+		printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed (status=%ld)\n",
+		       __FUNCTION__, status);
+		return SMP_CACHE_BYTES;
+	}
+	cacheline_size = 1 << cci.pcci_line_size;
+	return cacheline_size;
+}
+
+/**
+ * pcibios_prep_mwi - helper function for drivers/pci/pci.c:pci_set_mwi()
+ * @dev: the PCI device for which MWI is enabled
+ *
+ * For ia64, we can get the cacheline sizes from PAL.
+ *
+ * RETURNS: An appropriate -ERRNO error value on eror, or zero for success.
+ */
+int
+pcibios_set_mwi (struct pci_dev *dev)
+{
+	unsigned long desired_linesize, current_linesize;
+	int rc = 0;
+	u8 pci_linesize;
+
+	desired_linesize = pci_cacheline_size();
+
+	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &pci_linesize);
+	current_linesize = 4 * pci_linesize;
+	if (desired_linesize != current_linesize) {
+		printk(KERN_WARNING "PCI: slot %s has incorrect PCI cache line size of %lu bytes,",
+		       dev->slot_name, current_linesize);
+		if (current_linesize > desired_linesize) {
+			printk(" expected %lu bytes instead\n", desired_linesize);
+			rc = -EINVAL;
+		} else {
+			printk(" correcting to %lu\n", desired_linesize);
+			pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, desired_linesize / 4);
+		}
+	}
+	return rc;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/perfmon.c linux-2.4.22-pre10/arch/ia64/kernel/perfmon.c
--- linux-2.4.21/arch/ia64/kernel/perfmon.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/perfmon.c	2003-08-01 13:34:39.000000000 +0000
@@ -24,6 +24,7 @@
 #include <linux/wrapper.h>
 #include <linux/mm.h>
 #include <linux/sysctl.h>
+#include <linux/smp.h>
 
 #include <asm/bitops.h>
 #include <asm/errno.h>
@@ -120,8 +121,22 @@
 #define CTX_USED_DBR(ctx,n) 	(ctx)->ctx_used_dbrs[(n)>>6] |= 1UL<< ((n) % 64)
 #define CTX_USES_DBREGS(ctx)	(((pfm_context_t *)(ctx))->ctx_fl_using_dbreg==1)
 
-#define LOCK_CTX(ctx)	spin_lock(&(ctx)->ctx_lock)
-#define UNLOCK_CTX(ctx)	spin_unlock(&(ctx)->ctx_lock)
+#ifdef CONFIG_SMP
+#define GET_ACTIVATION()	pmu_owners[smp_processor_id()].activation_number
+#define INC_ACTIVATION()	pmu_owners[smp_processor_id()].activation_number++
+#define SET_ACTIVATION(c)	(c)->ctx_last_activation = GET_ACTIVATION()
+#define SET_LAST_CPU(ctx, v)	(ctx)->ctx_last_cpu = (v)
+#define GET_LAST_CPU(ctx)	(ctx)->ctx_last_cpu
+#else /* !CONFIG_SMP */
+#define SET_ACTIVATION(t)	do {} while(0)
+#define GET_ACTIVATION(t)	do {} while(0)
+#define INC_ACTIVATION(t)	do {} while(0)
+#define SET_LAST_CPU(ctx, v)	do {} while(0)
+#define GET_LAST_CPU(ctx)	do {} while(0)
+#endif /* CONFIG_SMP */
+
+
+#define PFM_INVALID_ACTIVATION	(~0UL)
 
 #define SET_PMU_OWNER(t)    do { pmu_owners[smp_processor_id()].owner = (t); } while(0)
 #define PMU_OWNER()	    pmu_owners[smp_processor_id()].owner
@@ -131,14 +146,13 @@
 
 #define PFM_REG_RETFLAG_SET(flags, val)	do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0)
 
-#define PFM_CPUINFO_CLEAR(v)	local_cpu_data->pfm_syst_info &= ~(v)
-#define PFM_CPUINFO_SET(v)	local_cpu_data->pfm_syst_info |= (v)
+#define TASK_PTREGS(t) (((struct pt_regs *)((unsigned long) (t) + IA64_STK_OFFSET))-1)
+
+/*
+ * cmp0 must be the value of pmc0
+ */
+#define PMC0_HAS_OVFL(cmp0)  (cmp0 & ~0x1UL)
 
-#ifdef CONFIG_SMP
-#define cpu_is_online(i) (cpu_online_map & (1UL << i))
-#else
-#define cpu_is_online(i)        (i==0)
-#endif
 
 /*
  * debugging
@@ -230,7 +244,8 @@
 	unsigned int protected:1;	/* allow access to creator of context only */
 	unsigned int using_dbreg:1;	/* using range restrictions (debug registers) */
 	unsigned int excl_idle:1;	/* exclude idle task in system wide session */
-	unsigned int reserved:23;
+	unsigned int unsecure:1;	/* sp = 0 for non self-monitored task */
+	unsigned int reserved:22;
 } pfm_context_flags_t;
 
 /*
@@ -265,13 +280,17 @@
 
 	u64			ctx_saved_psr;		/* copy of psr used for lazy ctxsw */
 	unsigned long		ctx_saved_cpus_allowed;	/* copy of the task cpus_allowed (system wide) */
+	unsigned long		ctx_last_activation;	/* context last activation number for last_cpu */
+	unsigned int		ctx_last_cpu;		/* CPU id of current or last CPU used (SMP only) */
 	unsigned int		ctx_cpu;		/* cpu to which perfmon is applied (system wide) */
 
-	atomic_t		ctx_saving_in_progress;	/* flag indicating actual save in progress */
-	atomic_t		ctx_is_busy;		/* context accessed by overflow handler */
-	atomic_t		ctx_last_cpu;		/* CPU id of current or last CPU used */
+	struct tasklet_struct   ctx_tasklet;		/* used for sending signal-based notifications */
 } pfm_context_t;
 
+#define PFM_GET_CTX(t)	((pfm_context_t *)(t)->thread.pfm_context)
+#define LOCK_CTX(ctx)	spin_lock(&(ctx)->ctx_lock)
+#define UNLOCK_CTX(ctx)	spin_unlock(&(ctx)->ctx_lock)
+
 #define ctx_fl_inherit		ctx_flags.inherit
 #define ctx_fl_block		ctx_flags.block
 #define ctx_fl_system		ctx_flags.system
@@ -279,6 +298,7 @@
 #define ctx_fl_protected	ctx_flags.protected
 #define ctx_fl_using_dbreg	ctx_flags.using_dbreg
 #define ctx_fl_excl_idle	ctx_flags.excl_idle
+#define ctx_fl_unsecure		ctx_flags.unsecure
 
 /*
  * global information about all sessions
@@ -335,17 +355,6 @@
 } pmu_config_t;
 
 /*
- * structure used to pass argument to/from remote CPU 
- * using IPI to check and possibly save the PMU context on SMP systems.
- *
- * not used in UP kernels
- */
-typedef struct {
-	struct task_struct *task;	/* which task we are interested in */
-	int retval;			/* return value of the call: 0=you can proceed, 1=need to wait for completion */
-} pfm_smp_ipi_arg_t;
-
-/*
  * perfmon command descriptions
  */
 typedef struct {
@@ -428,7 +437,8 @@
  */
 static struct {
 	struct task_struct *owner;
-	char pad[SMP_CACHE_BYTES] ____cacheline_aligned;
+	unsigned long	   activation_number;
+	char 		   pad[SMP_CACHE_BYTES] ____cacheline_aligned;
 } pmu_owners[NR_CPUS];
 
 
@@ -437,10 +447,7 @@
  * forward declarations
  */
 static void pfm_reset_pmu(struct task_struct *);
-#ifdef CONFIG_SMP
-static void pfm_fetch_regs(int cpu, struct task_struct *task, pfm_context_t *ctx);
-#endif
-static void pfm_lazy_save_regs (struct task_struct *ta);
+static unsigned long pfm_lazy_save_regs (struct task_struct *ta);
 
 #if   defined(CONFIG_ITANIUM)
 #include "perfmon_itanium.h"
@@ -504,6 +511,69 @@
 	ia64_srlz_d();
 }
 
+static inline void
+pfm_restore_ibrs(unsigned long *ibrs, unsigned int nibrs)
+{
+	int i;
+
+	for (i=0; i < nibrs; i++) {
+		ia64_set_ibr(i, ibrs[i]);
+	}
+	ia64_srlz_i();
+}
+
+static inline void
+pfm_restore_dbrs(unsigned long *dbrs, unsigned int ndbrs)
+{
+	int i;
+
+	for (i=0; i < ndbrs; i++) {
+		ia64_set_dbr(i, dbrs[i]);
+	}
+	ia64_srlz_d();
+}
+
+static inline void
+pfm_restore_pmcs(unsigned long *pmcs, unsigned long mask)
+{
+	int i;
+
+	DBprintk(("mask=0x%lx\n", mask));
+	for (i=0; mask; i++, mask>>=1) {
+		if ((mask & 0x1) == 0) continue;
+		ia64_set_pmc(i, pmcs[i]);
+		DBprintk(("pmc[%d]=0x%lx\n", i, pmcs[i]));
+	}
+	ia64_srlz_d();
+}
+
+static inline void
+pfm_restore_pmds(unsigned long *pmds, unsigned long mask)
+{
+	int i;
+	unsigned long val, ovfl_val = pmu_conf.ovfl_val;
+
+	DBprintk(("mask=0x%lx\n", mask));
+	for (i=0; mask; i++, mask>>=1) {
+		if ((mask & 0x1) == 0) continue;
+		val = PMD_IS_COUNTING(i) ? pmds[i] & ovfl_val : pmds[i];
+		ia64_set_pmd(i, val);
+		DBprintk(("pmd[%d]=0x%lx\n", i, val));
+	}
+	ia64_srlz_d();
+}
+
+static inline void
+pfm_save_pmds(unsigned long *pmds, unsigned long mask)
+{
+	int i;
+
+	ia64_srlz_d();
+
+	for (i=0; mask; i++, mask>>=1) {
+		if (mask & 0x1) pmds[i] = ia64_get_pmd(i);
+	}
+}
 
 static inline unsigned long
 pfm_read_soft_counter(pfm_context_t *ctx, int i)
@@ -600,7 +670,7 @@
 	pfm_smpl_buffer_desc_t *psb = (pfm_smpl_buffer_desc_t *)vma->vm_private_data;
 
 	if (psb == NULL) {
-		printk("perfmon: psb is null in [%d]\n", current->pid);
+		printk(KERN_DEBUG "perfmon: psb is null in [%d]\n", current->pid);
 		return;
 	}
 	/*
@@ -665,7 +735,7 @@
 	 * some sanity checks first
 	 */
 	if (ctx == NULL || task->mm == NULL || ctx->ctx_smpl_vaddr == 0 || ctx->ctx_psb == NULL) {
-		printk("perfmon: invalid context mm=%p\n", task->mm);
+		printk(KERN_DEBUG "perfmon: invalid context mm=%p\n", task->mm);
 		return -1;
 	}
 	psb = ctx->ctx_psb;
@@ -676,11 +746,11 @@
 
 	up_write(&task->mm->mmap_sem);
 	if (r !=0) {
-		printk("perfmon: pid %d unable to unmap sampling buffer @0x%lx size=%ld\n", 
-				task->pid, ctx->ctx_smpl_vaddr, psb->psb_size);
+		printk(KERN_DEBUG "perfmon: pid %d unable to unmap sampling buffer "
+		       "@0x%lx size=%ld\n", task->pid, ctx->ctx_smpl_vaddr, psb->psb_size);
 	}
 
-	DBprintk(("[%d] do_unmap(0x%lx, %ld)=%d refcnt=%lu psb_flags=0x%x\n", 
+	DBprintk(("[%d] do_unmap(0x%lx, %ld)=%d refcnt=%lu psb_flags=0x%x\n",
 		task->pid, ctx->ctx_smpl_vaddr, psb->psb_size, r, psb->psb_refcnt, psb->psb_flags));
 
 	return 0;
@@ -701,7 +771,14 @@
 static void
 pfm_context_free(pfm_context_t *ctx)
 {
-	if (ctx) kfree(ctx);
+	if (ctx) {
+		DBprintk(("kill tasklet for ctx %p\n", ctx));
+
+		tasklet_kill(&ctx->ctx_tasklet);
+
+		DBprintk(("free ctx @%p\n", ctx));
+		kfree(ctx);
+	}
 }
 
 static int
@@ -715,7 +792,7 @@
 		page = pfm_kvirt_to_pa(buf);
 
 		if (remap_page_range(addr, page, PAGE_SIZE, PAGE_READONLY)) return -ENOMEM;
-		
+
 		addr  += PAGE_SIZE;
 		buf   += PAGE_SIZE;
 		size  -= PAGE_SIZE;
@@ -873,7 +950,7 @@
 	vma->vm_end = vma->vm_start + size;
 
 	DBprintk(("entries=%ld aligned size=%ld, unmapped @0x%lx\n", entries, size, vma->vm_start));
-		
+
 	/* can only be applied to current, need to have the mm semaphore held when called */
 	if (pfm_remap_buffer((unsigned long)smpl_buf, vma->vm_start, size)) {
 		DBprintk(("Can't remap buffer\n"));
@@ -991,7 +1068,7 @@
 		pfm_sessions.pfs_sys_use_dbregs,
 		is_syswide,
 		cpu_mask));
-		
+
 
 	if (is_syswide) {
 		m = cpu_mask; n = 0;
@@ -1005,7 +1082,8 @@
 		 */
 		if (ctx && ctx->ctx_fl_using_dbreg) {
 			if (pfm_sessions.pfs_sys_use_dbregs == 0) {
-				printk("perfmon: invalid release for [%d] sys_use_dbregs=0\n", task->pid);
+				printk(KERN_DEBUG "perfmon: invalid release for [%d] "
+				       "sys_use_dbregs=0\n", task->pid);
 			} else {
 				pfm_sessions.pfs_sys_use_dbregs--;
 			}
@@ -1025,7 +1103,44 @@
 	return 0;
 }
 
+static void
+pfm_send_notification_signal(unsigned long data)
+{
+	pfm_context_t *ctx = (pfm_context_t *)data;
+	struct siginfo si;
+	int ret;
+
+	DBprintk(("[%d] tasklet called\n", current->pid));
+
+	LOCK_CTX(ctx);
+
+	if (ctx->ctx_notify_task == NULL) {
+		printk(KERN_INFO "perfmon: tasklet lost notify_task\n");
+		goto nothing_to_do;
+	}
+	/* no leak */
+	memset(&si,0, sizeof(si));
 
+	si.si_addr        = NULL;
+	si.si_pid         = current->pid; /* irrelevant */
+	si.si_signo       = SIGPROF;
+	si.si_code        = PROF_OVFL; /* indicates a perfmon SIGPROF signal */
+	si.si_pfm_ovfl[0] = ctx->ctx_ovfl_regs[0];
+
+	if (ctx->ctx_notify_task != current) read_lock(&tasklist_lock);
+
+	DBprintk_ovfl(("[%d] tasklet sending notification to [%d]\n", current->pid, ctx->ctx_notify_task->pid));
+
+	ret = send_sig_info(SIGPROF, &si, ctx->ctx_notify_task);
+	if (ret != 0) printk(KERN_ERR "send_sig_info(process %d, SIGPROF)=%d\n", ctx->ctx_notify_task->pid, ret);
+
+	/*
+	 * now undo the protections in order
+	 */
+	if (ctx->ctx_notify_task != current) read_unlock(&tasklist_lock);
+nothing_to_do:
+	UNLOCK_CTX(ctx);
+}
 
 /*
  * XXX: do something better here
@@ -1080,7 +1195,7 @@
 		 * and it must be a valid CPU
 		 */
 		cpu = ffz(~pfx->ctx_cpu_mask);
-		if (cpu_is_online(cpu) == 0) {
+		if (cpu_online(cpu) == 0) {
 			DBprintk(("CPU%d is not online\n", cpu));
 			return -EINVAL;
 		}
@@ -1229,6 +1344,7 @@
 	ctx->ctx_fl_block     = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0;
 	ctx->ctx_fl_system    = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0;
 	ctx->ctx_fl_excl_idle = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0;
+	ctx->ctx_fl_unsecure  = (ctx_flags & PFM_FL_UNSECURE) ? 1: 0;
 	ctx->ctx_fl_frozen    = 0;
 	/*
 	 * setting this flag to 0 here means, that the creator or the task that the
@@ -1242,14 +1358,20 @@
 	ctx->ctx_cpu = ffz(~tmp.ctx_cpu_mask);
 
 	/* SMP only, means no CPU */
-	atomic_set(&ctx->ctx_last_cpu,-1); 
-
-	/* may be redudant with memset() but at least it's easier to remember */
-	atomic_set(&ctx->ctx_saving_in_progress, 0); 
-	atomic_set(&ctx->ctx_is_busy, 0); 
+	ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
+	SET_LAST_CPU(ctx, -1);
 
 	sema_init(&ctx->ctx_restart_sem, 0); /* init this semaphore to locked */
 
+	/*
+	 * initialize tasklet for signal notifications
+	 *
+	 * ALL signal-based (or any notification using data structures
+	 * external to perfmon) MUST use tasklets to avoid lock contentions
+	 * when a signal has to be sent for overflow interrupt handler.
+	 */
+	tasklet_init(&ctx->ctx_tasklet, pfm_send_notification_signal, (unsigned long)ctx);
+
 	if (__copy_to_user(req, &tmp, sizeof(tmp))) {
 		ret = -EFAULT;
 		goto buffer_error;
@@ -1258,9 +1380,11 @@
 	DBprintk(("context=%p, pid=%d notify_task=%p\n",
 			(void *)ctx, task->pid, ctx->ctx_notify_task));
 
-	DBprintk(("context=%p, pid=%d flags=0x%x inherit=%d block=%d system=%d excl_idle=%d\n", 
+	DBprintk(("context=%p, pid=%d flags=0x%x inherit=%d block=%d system=%d excl_idle=%d unsecure=%d\n", 
 			(void *)ctx, task->pid, ctx_flags, ctx->ctx_fl_inherit, 
-			ctx->ctx_fl_block, ctx->ctx_fl_system, ctx->ctx_fl_excl_idle));
+			ctx->ctx_fl_block, ctx->ctx_fl_system, 
+			ctx->ctx_fl_excl_idle,
+			ctx->ctx_fl_unsecure));
 
 	/*
 	 * when no notification is required, we can make this visible at the last moment
@@ -1362,8 +1486,9 @@
 	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
 	unsigned long value, reset_pmds;
 	unsigned int cnum, reg_flags, flags;
-	int i;
-	int ret = -EINVAL;
+	int is_monitor, is_counting;
+	int i, ret = -EINVAL;
+#define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z))
 
 	/* we don't quite support this right now */
 	if (task != current) return -EINVAL;
@@ -1383,6 +1508,9 @@
 		reset_pmds = tmp.reg_reset_pmds[0];
 		flags      = 0;
 
+		is_counting = PMC_IS_COUNTING(cnum);
+		is_monitor  = PMC_IS_MONITOR(cnum);
+
 		/* 
 		 * we reject all non implemented PMC as well
 		 * as attempts to modify PMC[0-3] which are used
@@ -1393,21 +1521,19 @@
 			goto error;
 		}
 		/*
-		 * A PMC used to configure monitors must be:
-		 * 	- system-wide session: privileged monitor
-		 * 	- per-task : user monitor
-		 * any other configuration is rejected.
-		 */
-		if (PMC_IS_MONITOR(cnum) || PMC_IS_COUNTING(cnum)) {
-			DBprintk(("pmc[%u].pm=%ld\n", cnum, PMC_PM(cnum, value))); 
-
-			if (ctx->ctx_fl_system ^ PMC_PM(cnum, value)) {
-				DBprintk(("pmc_pm=%ld fl_system=%d\n", PMC_PM(cnum, value), ctx->ctx_fl_system));
-				goto error;
-			}
+		 * If the PMC is a monitor, then if the value is not the default:
+		 * 	- system-wide session: PMCx.pm=1 (privileged monitor)
+		 * 	- per-task           : PMCx.pm=0 (user monitor)
+		 */
+		if ((is_monitor || is_counting) && value != PMC_DFL_VAL(i) && PFM_CHECK_PMC_PM(ctx, cnum, value)) {
+			DBprintk(("pmc%u pmc_pm=%ld fl_system=%d\n", 
+				cnum, 
+				PMC_PM(cnum, value), 
+				ctx->ctx_fl_system));
+			goto error;
 		}
 
-		if (PMC_IS_COUNTING(cnum)) {
+		if (is_counting) {
 			pfm_monitor_t *p = (pfm_monitor_t *)&value;
 			/*
 		 	 * enforce generation of overflow interrupt. Necessary on all
@@ -1470,7 +1596,7 @@
 		 */
 		ctx->ctx_soft_pmds[cnum].flags = flags;
 
-		if (PMC_IS_COUNTING(cnum)) {
+		if (is_counting) {
 			ctx->ctx_soft_pmds[cnum].reset_pmds[0] = reset_pmds;
 
 			/* mark all PMDS to be accessed as used */
@@ -1591,7 +1717,7 @@
 		ia64_srlz_d();
 
 		DBprintk(("[%d] pmd[%u]: value=0x%lx hw_value=0x%lx soft_pmd=0x%lx  short_reset=0x%lx "
-			  "long_reset=0x%lx hw_pmd=%lx notify=%c used_pmds=0x%lx reset_pmds=0x%lx\n",
+			  "long_reset=0x%lx hw_pmd=%lx notify=%c used_pmds=0x%lx reset_pmds=0x%lx psr=%d\n",
 				task->pid, cnum,
 				value, hw_value,
 				ctx->ctx_soft_pmds[cnum].val,
@@ -1600,7 +1726,7 @@
 				ia64_get_pmd(cnum) & pmu_conf.ovfl_val,
 				PMC_OVFL_NOTIFY(ctx, cnum) ? 'Y':'N',
 				ctx->ctx_used_pmds[0],
-				ctx->ctx_soft_pmds[cnum].reset_pmds[0]));
+				ctx->ctx_soft_pmds[cnum].reset_pmds[0], ia64_psr(regs)->sp));
 	}
 
 	return 0;
@@ -1635,7 +1761,10 @@
 	int foo;
 #endif
 
-	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
+	if (!CTX_IS_ENABLED(ctx)) {
+		DBprintk(("context for [%d] is disabled\n", task->pid));
+		return -EINVAL;
+	}
 
 	/*
 	 * XXX: MUST MAKE SURE WE DON"T HAVE ANY PENDING OVERFLOW BEFORE READING
@@ -1646,7 +1775,10 @@
 
 	/* XXX: ctx locking may be required here */
 
-	DBprintk(("ctx_last_cpu=%d for [%d]\n", atomic_read(&ctx->ctx_last_cpu), task->pid));
+	/*
+	 * should we need to access the PMU, serialization is needed
+	 */
+	ia64_srlz_d();
 
 	for (i = 0; i < count; i++, req++) {
 
@@ -1673,36 +1805,20 @@
 		if (!CTX_IS_USED_PMD(ctx, cnum)) goto abort_mission;
 
 		/*
-		 * If the task is not the current one, then we check if the
-		 * PMU state is still in the local live register due to lazy ctxsw.
-		 * If true, then we read directly from the registers.
+		 * we can access the registers directly only when task
+		 * is the OWNER of the local PMU. In SMP, this can
+		 * happen only when task == current. In addition
+		 * this can happen when task != currrent but
+		 * only in UP mode.
 		 */
-		if (atomic_read(&ctx->ctx_last_cpu) == smp_processor_id()){
-			ia64_srlz_d();
+		if (task == PMU_OWNER()) {
 			val = ia64_get_pmd(cnum);
 			DBprintk(("reading pmd[%u]=0x%lx from hw\n", cnum, val));
 		} else {
-#ifdef CONFIG_SMP
-			int cpu;
-			/*
-			 * for SMP system, the context may still be live on another
-			 * CPU so we need to fetch it before proceeding with the read
-			 * This call we only be made once for the whole loop because
-			 * of ctx_last_cpu becoming == -1.
-			 *
-			 * We cannot reuse ctx_last_cpu as it may change before we get to the
-			 * actual IPI call. In this case, we will do the call for nothing but
-			 * there is no way around it. The receiving side will simply do nothing.
-			 */
-			cpu = atomic_read(&ctx->ctx_last_cpu);
-			if (cpu != -1) {
-				DBprintk(("must fetch on CPU%d for [%d]\n", cpu, task->pid));
-				pfm_fetch_regs(cpu, task, ctx);
-			}
-#endif
 			/* context has been saved */
 			val = th->pmd[cnum];
 		}
+
 		if (PMD_IS_COUNTING(cnum)) {
 			/*
 			 * XXX: need to check for overflow
@@ -1814,7 +1930,8 @@
 
 	LOCK_PFS();
 	if (pfm_sessions.pfs_ptrace_use_dbregs == 0) {
-		printk("perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task->pid);
+		printk(KERN_DEBUG "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n",
+		       task->pid);
 		ret = -1;
 	}  else {
 		pfm_sessions.pfs_ptrace_use_dbregs--;
@@ -2051,7 +2168,6 @@
 pfm_protect_context(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
 	 struct pt_regs *regs)
 {
-	DBprintk(("context from [%d] is protected\n", task->pid));
 	/*
 	 * from now on, only the creator of the context has access to it
 	 */
@@ -2060,7 +2176,9 @@
 	/*
 	 * reinforce secure monitoring: cannot toggle psr.up
 	 */
-	ia64_psr(regs)->sp = 1;
+	if (ctx->ctx_fl_unsecure == 0) ia64_psr(regs)->sp = 1;
+
+	DBprintk(("[%d] protected psr.sp=%d\n", task->pid, ia64_psr(regs)->sp));
 
 	return 0;
 }
@@ -2073,7 +2191,7 @@
 
 	pfm_sysctl.debug = mode == 0 ? 0 : 1;
 
-	printk("perfmon debugging %s\n", pfm_sysctl.debug ? "on" : "off");
+	printk(KERN_INFO "perfmon debugging %s\n", pfm_sysctl.debug ? "on" : "off");
 
 	return 0;
 }
@@ -2338,7 +2456,7 @@
 				current));
 
 	if (PMU_OWNER() != task) {
-		printk("perfmon: pfm_start task [%d] not pmu owner\n", task->pid);
+		printk(KERN_DEBUG "perfmon: pfm_start task [%d] not pmu owner\n", task->pid);
 		return -EINVAL;
 	}
 
@@ -2359,7 +2477,8 @@
 
 	} else {
 		if ((task->thread.flags & IA64_THREAD_PM_VALID) == 0) {
-			printk("perfmon: pfm_start task flag not set for [%d]\n", task->pid);
+			printk(KERN_DEBUG "perfmon: pfm_start task flag not set for [%d]\n",
+			       task->pid);
 			return -EINVAL;
 		}
 		/* set user level psr.up */
@@ -2384,8 +2503,10 @@
 		return -EINVAL;
 	}
 
+#ifndef CONFIG_SMP
 	if (ctx->ctx_fl_system == 0 && PMU_OWNER()  && PMU_OWNER() != current) 
 		pfm_lazy_save_regs(PMU_OWNER());
+#endif
 
 	/* reset all registers to stable quiet state */
 	pfm_reset_pmu(task);
@@ -2427,7 +2548,9 @@
 	SET_PMU_OWNER(task);
 
 	ctx->ctx_flags.state = PFM_CTX_ENABLED;
-	atomic_set(&ctx->ctx_last_cpu, smp_processor_id());
+	SET_LAST_CPU(ctx, smp_processor_id());
+	INC_ACTIVATION();
+	SET_ACTIVATION(ctx);
 
 	/* simply unfreeze */
 	pfm_unfreeze_pmu();
@@ -2599,12 +2722,15 @@
 
 			if (PFM_CMD_CHK(cmd)) {
 				ret = check_task_state(task);
-				if (ret != 0) goto abort_call;
+				if (ret != 0) {
+					DBprintk(("check_task_state=%ld for [%d]\n", ret, task->pid));
+					goto abort_call;
+				}
 			}
 		} 
 	} 
 
-	ctx = task->thread.pfm_context;
+	ctx = PFM_GET_CTX(task);
 
 	if (PFM_CMD_USE_CTX(cmd)) {
 		ret = -EINVAL;
@@ -2612,6 +2738,8 @@
 			DBprintk(("no context for task %d\n", task->pid));
 			goto abort_call;
 	       }
+
+
 	       ret = -EPERM;
 	       /*
 		* we only grant access to the context if:
@@ -2651,7 +2779,7 @@
 	 * do some sanity checks first
 	 */
 	if (!ctx) {
-		printk("perfmon: [%d] has no PFM context\n", current->pid);
+		printk(KERN_DEBUG "perfmon: [%d] has no PFM context\n", current->pid);
 		return;
 	}
 
@@ -2701,6 +2829,8 @@
 
 /*
  * This function will record an entry in the sampling if it is not full already.
+ * Input:
+ * 	ovfl_mask: mask of overflowed PMD. MUST NEVER be 0.
  * Return:
  * 	0 : buffer is not full (did not BECOME full: still space or was already full)
  * 	1 : buffer is full (recorded the last entry)
@@ -2713,8 +2843,6 @@
 	perfmon_smpl_entry_t *h;
 	int j;
 
-
-
 	idx = ia64_fetch_and_add(1, &psb->psb_index);
 	DBprintk_ovfl(("recording index=%ld entries=%ld\n", idx-1, psb->psb_entries));
 
@@ -2736,7 +2864,7 @@
 	/*
 	 * initialize entry header
 	 */
-	h->pid  = current->pid;
+	h->pid  = ctx->ctx_fl_system ? current->pid : task->pid;
 	h->cpu  = smp_processor_id();
 	h->last_reset_value = ovfl_mask ? ctx->ctx_soft_pmds[ffz(~ovfl_mask)].lval : 0UL;
 	h->ip   = regs ? regs->cr_iip | ((regs->cr_ipsr >> 41) & 0x3): 0x0UL;
@@ -2802,7 +2930,6 @@
 	unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL;
 	int i;
 	int ret = 1;
-	struct siginfo si;
 	/*
 	 * It is never safe to access the task for which the overflow interrupt is destinated
 	 * using the current variable as the interrupt may occur in the middle of a context switch
@@ -2823,16 +2950,16 @@
 	 * Don't think this could happen given upfront tests
 	 */
 	if ((t->flags & IA64_THREAD_PM_VALID) == 0 && ctx->ctx_fl_system == 0) {
-		printk("perfmon: Spurious overflow interrupt: process %d not using perfmon\n", 
-			task->pid);
+		printk(KERN_DEBUG "perfmon: Spurious overflow interrupt: process %d not "
+		       "using perfmon\n", task->pid);
 		return 0x1;
 	}
 	/*
 	 * sanity test. Should never happen
 	 */
 	if ((pmc0 & 0x1) == 0) {
-		printk("perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n", 
-			task->pid, pmc0);
+		printk(KERN_DEBUG "perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n",
+		       task->pid, pmc0);
 		return 0x0;
 	}
 
@@ -2863,7 +2990,7 @@
 		 * taken into consideration here but will be with any read of the pmd via
 		 * pfm_read_pmds().
 		 */
-		old_val = ctx->ctx_soft_pmds[i].val;
+		old_val                    = ctx->ctx_soft_pmds[i].val;
 		ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.ovfl_val;
 
 		/*
@@ -2876,6 +3003,11 @@
 			if (PMC_OVFL_NOTIFY(ctx, i)) {
 				ovfl_notify |= 1UL << i;
 			}
+		} else {
+			/*
+			 * clear top bits (maintain counts in lower part, may not always be zero)
+			 */
+			ia64_set_pmd(i, ia64_get_pmd(i) & pmu_conf.ovfl_val);
 		}
 		DBprintk_ovfl(("soft_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx\n", 
 			  i, ctx->ctx_soft_pmds[i].val, old_val, 
@@ -2885,10 +3017,10 @@
 	/*
 	 * check for sampling buffer
 	 *
-	 * if present, record sample. We propagate notification ONLY when buffer
-	 * becomes full.
+	 * if present, record sample only when a 64-bit counter has overflowed.
+	 * We propagate notification ONLY when buffer becomes full.
 	 */
-	if(CTX_HAS_SMPL(ctx)) {
+	if(CTX_HAS_SMPL(ctx) && ovfl_pmds) {
 		ret = pfm_record_sample(task, ctx, ovfl_pmds, regs);
 		if (ret == 1) {
 			/*
@@ -2924,136 +3056,40 @@
 	ctx->ctx_ovfl_regs[0]  = ovfl_pmds; 
 
 	/*
+	 * As a consequence of the overflow, we always resume
+	 * with monitoring turned off. pfm_restart() will
+	 * reactivate.
+	 */
+	ctx->ctx_fl_frozen = 1;
+
+	/*
 	 * we have come to this point because there was an overflow and that notification
 	 * was requested. The notify_task may have disappeared, in which case notify_task
 	 * is NULL.
 	 */
-	if (ctx->ctx_notify_task) {
-
-		si.si_errno    = 0;
-		si.si_addr     = NULL;
-		si.si_pid      = task->pid; /* who is sending */
-
-		si.si_signo    = SIGPROF;
-		si.si_code     = PROF_OVFL; /* indicates a perfmon SIGPROF signal */
-		/*
-		 * Shift the bitvector such that the user sees bit 4 for PMD4 and so on.
-		 * We only use smpl_ovfl[0] for now. It should be fine for quite a while
-		 * until we have more than 61 PMD available.
-		 */
-		si.si_pfm_ovfl[0] = ovfl_notify;
-	
-		/*
-		 * when the target of the signal is not ourself, we have to be more
-		 * careful. The notify_task may being cleared by the target task itself
-		 * in release_thread(). We must ensure mutual exclusion here such that
-		 * the signal is delivered (even to a dying task) safely.
-		 */
-
-		if (ctx->ctx_notify_task != current) {
-			/*
-			 * grab the notification lock for this task
-			 * This guarantees that the sequence: test + send_signal
-			 * is atomic with regards to the ctx_notify_task field.
-			 *
-			 * We need a spinlock and not just an atomic variable for this.
-			 *
-			 */
-			spin_lock(&ctx->ctx_lock);
-
-			/*
-			 * now notify_task cannot be modified until we're done
-			 * if NULL, they it got modified while we were in the handler
-			 */
-			if (ctx->ctx_notify_task == NULL) {
-
-				spin_unlock(&ctx->ctx_lock);
+	LOCK_CTX(ctx);
 
-				/*
-				 * If we've lost the notified task, then we will run
-				 * to completion wbut keep the PMU frozen. Results
-				 * will be incorrect anyway. We do not kill task
-				 * to leave it possible to attach perfmon context
-				 * to already running task.
-				 */
-				goto lost_notify;
-			}
-			/*
-			 * required by send_sig_info() to make sure the target
-			 * task does not disappear on us.
-			 */
-			read_lock(&tasklist_lock);
+	if (ctx->ctx_notify_task) {
+		if (CTX_OVFL_NOBLOCK(ctx) == 0 && ctx->ctx_notify_task != task) {
+			t->pfm_ovfl_block_reset = 1; /* will cause blocking */
+		} else {
+			t->pfm_ovfl_block_reset = 0;
 		}
-		/*
-	 	 * in this case, we don't stop the task, we let it go on. It will
-	 	 * necessarily go to the signal handler (if any) when it goes back to
-	 	 * user mode.
-	 	 */
-		DBprintk_ovfl(("[%d] sending notification to [%d]\n", 
-			  task->pid, ctx->ctx_notify_task->pid));
-
 
-		/* 
-		 * this call is safe in an interrupt handler, so does read_lock() on tasklist_lock
-		 */
-		ret = send_sig_info(SIGPROF, &si, ctx->ctx_notify_task);
-		if (ret != 0) 
-			printk("send_sig_info(process %d, SIGPROF)=%d\n",  
-			       ctx->ctx_notify_task->pid, ret);
-		/*
-		 * now undo the protections in order
-		 */
-		if (ctx->ctx_notify_task != current) {
-			read_unlock(&tasklist_lock);
-			spin_unlock(&ctx->ctx_lock);
-		}
+		DBprintk_ovfl(("[%d] scheduling tasklet\n", current->pid));
 
 		/*
-		 * if we block set the pfm_must_block bit
-		 * when in block mode, we can effectively block only when the notified
-		 * task is not self, otherwise we would deadlock. 
-		 * in this configuration, the notification is sent, the task will not 
-		 * block on the way back to user mode, but the PMU will be kept frozen
-		 * until PFM_RESTART.
-		 * Note that here there is still a race condition with notify_task
-		 * possibly being nullified behind our back, but this is fine because
-		 * it can only be changed to NULL which by construction, can only be
-		 * done when notify_task != current. So if it was already different
-		 * before, changing it to NULL will still maintain this invariant.
-		 * Of course, when it is equal to current it cannot change at this point.
-		 */
-		DBprintk_ovfl(("block=%d notify [%d] current [%d]\n", 
-			ctx->ctx_fl_block,
-			ctx->ctx_notify_task ? ctx->ctx_notify_task->pid: -1, 
-			current->pid ));
+		 * the tasklet is responsible for sending the notification
+		 * not the PMU owner nor the current task.
+		 */
+		tasklet_schedule(&ctx->ctx_tasklet);
 
-		if (!CTX_OVFL_NOBLOCK(ctx) && ctx->ctx_notify_task != task) {
-			t->pfm_ovfl_block_reset = 1; /* will cause blocking */
-		}
 	} else {
-lost_notify: /* XXX: more to do here, to convert to non-blocking (reset values) */
-
 		DBprintk_ovfl(("notification task has disappeared !\n"));
-		/*
-		 * for a non-blocking context, we make sure we do not fall into the 
-		 * pfm_overflow_notify() trap. Also in the case of a blocking context with lost 
-		 * notify process, then we do not want to block either (even though it is 
-		 * interruptible). In this case, the PMU will be kept frozen and the process will 
-		 * run to completion without monitoring enabled.
-		 *
-		 * Of course, we cannot loose notify process when self-monitoring.
-		 */
-		t->pfm_ovfl_block_reset = 0; 
-
+		t->pfm_ovfl_block_reset = 0;
 	}
-	/*
-	 * If notification was successful, then we rely on the pfm_restart()
-	 * call to unfreeze and reset (in both blocking or non-blocking mode).
-	 *
-	 * If notification failed, then we will keep the PMU frozen and run
-	 * the task to completion
-	 */
-	ctx->ctx_fl_frozen = 1;
+
+	UNLOCK_CTX(ctx);
 
 	DBprintk_ovfl(("return pmc0=0x%x must_block=%ld\n",
 				ctx->ctx_fl_frozen ? 0x1 : 0x0, t->pfm_ovfl_block_reset));
@@ -3084,37 +3120,23 @@
 	 * This is slow
 	 */
 	pmc0 = ia64_get_pmc(0); 
-
+	task = PMU_OWNER();
 	/*
 	 * if we have some pending bits set
 	 * assumes : if any PM[0].bit[63-1] is set, then PMC[0].fr = 1
 	 */
-	if ((pmc0 & ~0x1UL)!=0UL && (task=PMU_OWNER())!= NULL) {
+	if (PMC0_HAS_OVFL(pmc0) && task) {
 		/* 
 		 * we assume that pmc0.fr is always set here
 		 */
-		ctx = task->thread.pfm_context;
+		ctx = PFM_GET_CTX(task);
 
 		/* sanity check */
 		if (!ctx) {
-			printk("perfmon: Spurious overflow interrupt: process %d has no PFM context\n", 
-				task->pid);
+			printk(KERN_DEBUG "perfmon: Spurious overflow interrupt: process %d has "
+			       "no PFM context\n", task->pid);
 			return;
 		}
-#ifdef CONFIG_SMP
-		/*
-		 * Because an IPI has higher priority than the PMU overflow interrupt, it is 
-		 * possible that the handler be interrupted by a request from another CPU to fetch 
-		 * the PMU state of the currently active context. The task may have just been 
-		 * migrated to another CPU which is trying to restore the context. If there was
-		 * a pending overflow interrupt when the task left this CPU, it is possible for
-		 * the handler to get interrupt by the IPI. In which case, we fetch request
-		 * MUST be postponed until the interrupt handler is done. The ctx_is_busy
-		 * flag indicates such a condition. The other CPU must busy wait until it's cleared.
-		 */
-		atomic_set(&ctx->ctx_is_busy, 1);
-#endif
-
 		/* 
 		 * assume PMC[0].fr = 1 at this point 
 		 */
@@ -3122,26 +3144,21 @@
 
 		/*
 		 * we can only update pmc0 when the overflow
-		 * is for the current context. In UP the current
-		 * task may not be the one owning the PMU
+		 * is for the current context or we are in system
+		 * wide mode. In UP (per-task) the current
+		 * task may not be the one owning the PMU,
+		 * same thing for system-wide.
 		 */
-		if (task == current) {
+		if (task == current || ctx->ctx_fl_system) {
 			/*
-		 	* We always clear the overflow status bits and either unfreeze
-		 	* or keep the PMU frozen.
-		 	*/
+		 	 * We always clear the overflow status bits and either unfreeze
+		 	 * or keep the PMU frozen.
+		 	 */
 			ia64_set_pmc(0, pmc0);
 			ia64_srlz_d();
 		} else {
 			task->thread.pmc[0] = pmc0;
 		}
-
-#ifdef CONFIG_SMP
-		/*
-		 * announce that we are doing with the context
-		 */
-		atomic_set(&ctx->ctx_is_busy, 0);
-#endif
 	} else {
 		pfm_stats[smp_processor_id()].pfm_spurious_ovfl_intr_count++;
 	}
@@ -3158,7 +3175,7 @@
 	p += sprintf(p, "ovfl_mask              : 0x%lx\n", pmu_conf.ovfl_val);
 
 	for(i=0; i < NR_CPUS; i++) {
-		if (cpu_is_online(i) == 0) continue;
+		if (cpu_online(i) == 0) continue;
 		p += sprintf(p, "CPU%-2d overflow intrs   : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_count);
 		p += sprintf(p, "CPU%-2d spurious intrs   : %lu\n", i, pfm_stats[i].pfm_spurious_ovfl_intr_count);
 		p += sprintf(p, "CPU%-2d recorded samples : %lu\n", i, pfm_stats[i].pfm_recorded_samples_count);
@@ -3167,6 +3184,7 @@
 		p += sprintf(p, "CPU%-2d dcr_pp           : %d\n", i, cpu_data(i)->pfm_syst_info & PFM_CPUINFO_DCR_PP ? 1 : 0);
 		p += sprintf(p, "CPU%-2d exclude idle     : %d\n", i, cpu_data(i)->pfm_syst_info & PFM_CPUINFO_EXCL_IDLE ? 1 : 0);
 		p += sprintf(p, "CPU%-2d owner            : %d\n", i, pmu_owners[i].owner ? pmu_owners[i].owner->pid: -1);
+		p += sprintf(p, "CPU%-2d activations      : %lu\n", i, pmu_owners[i].activation_number);
 	}
 
 	LOCK_PFS();
@@ -3257,13 +3275,26 @@
 	}
 }
 
+#ifdef CONFIG_SMP
 void
-pfm_save_regs (struct task_struct *task)
+pfm_save_regs(struct task_struct *task)
 {
 	pfm_context_t *ctx;
+	struct thread_struct *t;
 	u64 psr;
 
-	ctx = task->thread.pfm_context;
+	ctx = PFM_GET_CTX(task);
+	if (ctx == NULL) goto save_error;
+	t = &task->thread;
+
+	/* 
+	 * sanity check 
+	 */
+	if (ctx->ctx_last_activation != GET_ACTIVATION()) {
+		DBprintk(("ctx_activation=%lu activation=%lu: no save\n", 
+			ctx->ctx_last_activation, GET_ACTIVATION()));
+		return;
+	}
 
 	/*
 	 * save current PSR: needed because we modify it
@@ -3272,229 +3303,258 @@
 
 	/*
 	 * stop monitoring:
-	 * This is the last instruction which can generate an overflow
+	 * This is the last instruction which may generate an overflow
 	 *
 	 * We do not need to set psr.sp because, it is irrelevant in kernel.
 	 * It will be restored from ipsr when going back to user level
 	 */
 	pfm_clear_psr_up();
-	ia64_srlz_i();
 
+	/*
+	 * keep a copy of the saved psr (for reload)
+	 */
 	ctx->ctx_saved_psr = psr;
 
-	//ctx->ctx_last_cpu  = smp_processor_id();
+	/*
+	 * release ownership of this PMU.
+	 */
+	SET_PMU_OWNER(NULL);
+
+	/*
+	 * we systematically save the PMD as we have no
+	 * guarantee we will be schedule at that same 
+	 * CPU again.
+	 */
+	pfm_save_pmds(t->pmd, ctx->ctx_used_pmds[0]);
+
+	/* 
+	 * save pmc0 ia64_srlz_d() done in pfm_save_pmds() 
+	 * we will need it on the restore path to check
+	 * for pending overflow.
+	 */
+	t->pmc[0] = ia64_get_pmc(0);
+
+	return;
 
+save_error:
+	printk(KERN_ERR "perfmon: pfm_save_regs CPU%d [%d] NULL context PM_VALID=%ld\n", 
+		smp_processor_id(), task->pid,
+		task->thread.flags & IA64_THREAD_PM_VALID);
 }
 
-static void
-pfm_lazy_save_regs (struct task_struct *task)
+#else /* !CONFIG_SMP */
+
+void
+pfm_save_regs(struct task_struct *task)
 {
 	pfm_context_t *ctx;
-	struct thread_struct *t;
-	unsigned long mask;
-	int i;
-
-	DBprintk(("on [%d] by [%d]\n", task->pid, current->pid));
+	u64 psr;
 
-	t   = &task->thread;
-	ctx = task->thread.pfm_context;
+	ctx = PFM_GET_CTX(task);
+	if (ctx == NULL) goto save_error;
+	/*
+	 * save current PSR: needed because we modify it
+	 */
+	psr = pfm_get_psr();
 
-#ifdef CONFIG_SMP
-	/* 
-	 * announce we are saving this PMU state
-	 * This will cause other CPU, to wait until we're done
-	 * before using the context.h
+	/*
+	 * stop monitoring:
+	 * This is the last instruction which may generate an overflow
 	 *
-	 * must be an atomic operation
+	 * We do not need to set psr.sp because, it is irrelevant in kernel.
+	 * It will be restored from ipsr when going back to user level
 	 */
-	atomic_set(&ctx->ctx_saving_in_progress, 1);
-
-	 /*
-	  * if owner is NULL, it means that the other CPU won the race
-	  * and the IPI has caused the context to be saved in pfm_handle_fectch_regs()
-	  * instead of here. We have nothing to do
-	  *
-	  * note that this is safe, because the other CPU NEVER modifies saving_in_progress.
-	  */
-	if (PMU_OWNER() == NULL) goto do_nothing;
-#endif
+	pfm_clear_psr_up();
 
 	/*
-	 * do not own the PMU
+	 * keep a copy of the saved psr (for reload)
 	 */
-	SET_PMU_OWNER(NULL);
+	ctx->ctx_saved_psr = psr;
 
-	ia64_srlz_d();
+	return;
+save_error:
+	printk(KERN_ERR "perfmon: pfm_save_regs CPU%d [%d] NULL context PM_VALID=%ld\n", 
+		smp_processor_id(), task->pid,
+		task->thread.flags & IA64_THREAD_PM_VALID);
+}
 
-	/*
-	 * XXX needs further optimization.
-	 * Also must take holes into account
-	 */
-	mask = ctx->ctx_used_pmds[0];
-	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) t->pmd[i] =ia64_get_pmd(i);
-	}
+static unsigned long
+pfm_lazy_save_regs (struct task_struct *task)
+{
+	pfm_context_t *ctx;
+	struct thread_struct *t;
 
-	/* save pmc0 */
-	t->pmc[0] = ia64_get_pmc(0);
+	ctx = PFM_GET_CTX(task);
+	t   = &task->thread;
 
-	/* not owned by this CPU */
-	atomic_set(&ctx->ctx_last_cpu, -1);
+	DBprintk(("on [%d] used_pmds=0x%lx\n", task->pid, ctx->ctx_used_pmds[0]));
 
-#ifdef CONFIG_SMP
-do_nothing:
-#endif
 	/*
-	 * declare we are done saving this context
+	 * release ownership of this PMU.
+	 * must be done before we save the registers.
 	 *
-	 * must be an atomic operation
+	 * after this call any PMU interrupt is treated
+	 * as spurious.
 	 */
-	atomic_set(&ctx->ctx_saving_in_progress,0);
+	SET_PMU_OWNER(NULL);
 
+	/*
+	 * save all the pmds we use
+	 */
+	pfm_save_pmds(t->pmd, ctx->ctx_used_pmds[0]);
+
+	/* 
+	 * save pmc0 ia64_srlz_d() done in pfm_save_pmds() 
+	 * it is needed to check for pended overflow
+	 * on the restore path
+	 */
+	t->pmc[0] = ia64_get_pmc(0);
+
+	return t->pmc[0];
 }
+#endif /* CONFIG_SMP */
 
 #ifdef CONFIG_SMP
-/*
- * Handles request coming from other CPUs
- */
-static void 
-pfm_handle_fetch_regs(void *info)
+void
+pfm_load_regs (struct task_struct *task)
 {
-	pfm_smp_ipi_arg_t *arg = info;
-	struct thread_struct *t;
 	pfm_context_t *ctx;
-	unsigned long mask;
-	int i;
-
-	ctx = arg->task->thread.pfm_context;
-	t   = &arg->task->thread;
+	struct thread_struct *t;
+	struct task_struct *owner;
+	unsigned long pmc_mask = 0UL, pmd_mask = 0UL;
+	u64 psr;
 
-	DBprintk(("task=%d owner=%d saving=%d\n", 
-		  arg->task->pid,
-		  PMU_OWNER() ? PMU_OWNER()->pid: -1,
-		  atomic_read(&ctx->ctx_saving_in_progress)));
-
-	/* must wait until not busy before retrying whole request */
-	if (atomic_read(&ctx->ctx_is_busy)) {
-		arg->retval = 2;
+	ctx = PFM_GET_CTX(task);
+	if (unlikely(ctx == NULL)) {
+		printk(KERN_ERR "perfmon: pfm_load_regs() null context\n");
 		return;
 	}
 
-	/* must wait if saving was interrupted */
-	if (atomic_read(&ctx->ctx_saving_in_progress)) {
-		arg->retval = 1;
-		return;
-	}
+	owner = PMU_OWNER();
+	t     = &task->thread;
 
-	/* can proceed, done with context */
-	if (PMU_OWNER() != arg->task) {
-		arg->retval = 0;
+	/*
+	 * possible on unload
+	 */
+	if ((t->flags & IA64_THREAD_PM_VALID) == 0) {
+		DBprintk(("[%d] PM_VALID=0, nothing to do\n", task->pid));
 		return;
 	}
 
-	DBprintk(("saving state for [%d] used_pmcs=0x%lx reload_pmcs=0x%lx used_pmds=0x%lx\n", 
-		arg->task->pid,
-		ctx->ctx_used_pmcs[0],
-		ctx->ctx_reload_pmcs[0],
-		ctx->ctx_used_pmds[0]));
-
 	/*
-	 * XXX: will be replaced with pure assembly call
+	 * we restore ALL the debug registers to avoid picking up 
+	 * stale state.
+	 *
+	 * This must be done even when the task is still the owner
+	 * as the registers may have been modified via ptrace()
+	 * (not perfmon) by the previous task. 
 	 */
-	SET_PMU_OWNER(NULL);
-
-	ia64_srlz_d();
+	if (ctx->ctx_fl_using_dbreg) {
+		pfm_restore_ibrs(t->ibr, pmu_conf.num_ibrs);
+		pfm_restore_dbrs(t->dbr, pmu_conf.num_dbrs);
+	}
 
 	/*
-	 * XXX needs further optimization.
+	 * retrieve saved psr
 	 */
-	mask = ctx->ctx_used_pmds[0];
-	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) t->pmd[i] = ia64_get_pmd(i);
-	}
-
-	/* save pmc0 */
-	t->pmc[0] = ia64_get_pmc(0);
-
-	/* not owned by this CPU */
-	atomic_set(&ctx->ctx_last_cpu, -1);
+	psr = ctx->ctx_saved_psr;
 
-	/* can proceed */
-	arg->retval = 0;
-}
+	/*
+	 * if we were the last user of the PMU on that CPU, 
+	 * then nothing to do except restore psr
+	 */
+	if (GET_LAST_CPU(ctx) == smp_processor_id() && ctx->ctx_last_activation == GET_ACTIVATION()) {
+		/*
+		 * retrieve partial reload masks (due to user modifications)
+		 */
+		pmc_mask = 0UL;
+		pmd_mask = 0UL;
 
-/*
- * Function call to fetch PMU state from another CPU identified by 'cpu'.
- * If the context is being saved on the remote CPU, then we busy wait until
- * the saving is done and then we return. In this case, non IPI is sent.
- * Otherwise, we send an IPI to the remote CPU, potentially interrupting 
- * pfm_lazy_save_regs() over there.
- *
- * If the retval==1, then it means that we interrupted remote save and that we must
- * wait until the saving is over before proceeding.
- * Otherwise, we did the saving on the remote CPU, and it was done by the time we got there.
- * in either case, we can proceed.
- */
-static void
-pfm_fetch_regs(int cpu, struct task_struct *task, pfm_context_t *ctx)
-{
-	pfm_smp_ipi_arg_t  arg;
-	int ret;
+		if (pmc_mask || pmd_mask) DBprintk(("partial reload [%d] pmd_mask=0x%lx pmc_mask=0x%lx\n", task->pid, pmd_mask, pmc_mask));
+	} else {
+		/*
+	 	 * To avoid leaking information to the user level when psr.sp=0,
+	 	 * we must reload ALL implemented pmds (even the ones we don't use).
+	 	 * In the kernel we only allow PFM_READ_PMDS on registers which
+	 	 * we initialized or requested (sampling) so there is no risk there.
+	 	 */
+		pmd_mask = pfm_sysctl.fastctxsw ?  ctx->ctx_used_pmds[0] : ctx->ctx_reload_pmds[0];
 
-	arg.task   = task;
-	arg.retval = -1;
+		/* 
+	 	 * ALL accessible PMCs are systematically reloaded, unused registers
+	 	 * get their default (from pfm_reset_pmu_state()) values to avoid picking 
+	 	 * up stale configuration.
+	 	 *
+	 	 * PMC0 is never in the mask. It is always restored separately.  
+	 	 */	
+		pmc_mask = ctx->ctx_reload_pmcs[0];
+
+		DBprintk(("full reload for [%d] owner=%d activation=%lu last_activation=%lu last_cpu=%d pmd_mask=0x%lx pmc_mask=0x%lx\n", 
+			task->pid, owner ? owner->pid : -1, 
+			GET_ACTIVATION(), ctx->ctx_last_activation,
+			GET_LAST_CPU(ctx), pmd_mask, pmc_mask));
 
-	if (atomic_read(&ctx->ctx_is_busy)) {
-must_wait_busy:
-		while (atomic_read(&ctx->ctx_is_busy));
 	}
+	
+	if (pmd_mask) pfm_restore_pmds(t->pmd, pmd_mask);
+	if (pmc_mask) pfm_restore_pmcs(t->pmc, pmc_mask);
 
-	if (atomic_read(&ctx->ctx_saving_in_progress)) {
-		DBprintk(("no IPI, must wait for [%d] to be saved on [%d]\n", task->pid, cpu));
-must_wait_saving:
-		/* busy wait */
-		while (atomic_read(&ctx->ctx_saving_in_progress));
-		DBprintk(("done saving for [%d] on [%d]\n", task->pid, cpu));
-		return;
+	/*
+	 * check for pending overflow at the time the state
+	 * was saved.
+	 */
+	if (PMC0_HAS_OVFL(t->pmc[0])) {
+		struct pt_regs *regs = TASK_PTREGS(task);
+		pfm_overflow_handler(task, ctx, t->pmc[0], regs);
 	}
-	DBprintk(("calling CPU %d from CPU %d\n", cpu, smp_processor_id()));
 
-	if (cpu == -1) {
-		printk("refusing to use -1 for [%d]\n", task->pid);
-		return;
+	/*
+	 * fl_frozen==1 when we are in blocking mode waiting for restart
+	 */
+	if (ctx->ctx_fl_frozen == 0) {
+		pfm_unfreeze_pmu();
 	}
 
-	/* will send IPI to other CPU and wait for completion of remote call */
-	if ((ret=smp_call_function_single(cpu, pfm_handle_fetch_regs, &arg, 0, 1))) {
-		printk("perfmon: remote CPU call from %d to %d error %d\n", smp_processor_id(), cpu, ret);
-		return;
-	}
+	SET_LAST_CPU(ctx, smp_processor_id());
+	
 	/*
-	 * we must wait until saving is over on the other CPU
-	 * This is the case, where we interrupted the saving which started just at the time we sent the
-	 * IPI.
+	 * dump activation value for this PMU
 	 */
-	if (arg.retval == 1) goto must_wait_saving;
-	if (arg.retval == 2) goto must_wait_busy;
-}
-#endif /* CONFIG_SMP */
+	INC_ACTIVATION();
+	/*
+	 * record current activation for this context
+	 */
+	SET_ACTIVATION(ctx);
 
+	/*
+	 * establish new ownership. Interrupts
+	 * are still masked at this point.
+	 */
+	SET_PMU_OWNER(task);
+
+	/*
+	 * restore the psr we changed
+	 */
+	pfm_set_psr_l(psr);
+
+}
+#else /*  !CONFIG_SMP */
+/*
+ * reload PMU state for UP kernels
+ */
 void
 pfm_load_regs (struct task_struct *task)
 {
 	struct thread_struct *t;
 	pfm_context_t *ctx;
 	struct task_struct *owner;
-	unsigned long mask;
+	unsigned long pmd_mask, pmc_mask;
+	unsigned long prev_pmc0 = ~0UL;
 	u64 psr;
-	int i;
-#ifdef CONFIG_SMP
-	int cpu;
-#endif
 
-	owner = PMU_OWNER();
-	ctx   = task->thread.pfm_context;
-	t     = &task->thread;
+	owner      = PMU_OWNER();
+	ctx        = PFM_GET_CTX(task);
+	t          = &task->thread;
 
 	/*
 	 * we restore ALL the debug registers to avoid picking up 
@@ -3503,105 +3563,112 @@
 	 * This must be done even when the task is still the owner
 	 * as the registers may have been modified via ptrace()
 	 * (not perfmon) by the previous task. 
-	 *
-	 * XXX: dealing with this in a lazy fashion requires modifications
-	 * to the way the the debug registers are managed. This is will done
-	 * in the next version of perfmon.
 	 */
 	if (ctx->ctx_fl_using_dbreg) {
-		for (i=0; i < pmu_conf.num_ibrs; i++) {
-			ia64_set_ibr(i, t->ibr[i]);
-		}
-		ia64_srlz_i();
-		for (i=0; i < pmu_conf.num_dbrs; i++) {
-			ia64_set_dbr(i, t->dbr[i]);
-		}
-		ia64_srlz_d();
+		pfm_restore_ibrs(t->ibr, pmu_conf.num_ibrs);
+		pfm_restore_dbrs(t->dbr, pmu_conf.num_dbrs);
 	}
 
 	/*
-	 * if we were the last user, then nothing to do except restore psr
+	 * retrieved save psr
 	 */
-	if (owner == task) {
-		if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id())
-			DBprintk(("invalid last_cpu=%d for [%d]\n", 
-				atomic_read(&ctx->ctx_last_cpu), task->pid));
+	psr = ctx->ctx_saved_psr;
 
-		psr = ctx->ctx_saved_psr;
+	/*
+	 * short path, our state is still there, just
+	 * need to restore psr and we go
+	 *
+	 * we do not touch either PMC nor PMD. the psr is not touched
+	 * by the overflow_handler. So we are safe w.r.t. to interrupt
+	 * concurrency even without interrupt masking.
+	 */
+	if (owner == task) {
 		pfm_set_psr_l(psr);
-
 		return;
 	}
-	DBprintk(("load_regs: must reload for [%d] owner=%d\n", 
-		task->pid, owner ? owner->pid : -1 ));
+
+	DBprintk(("reload for [%d] owner=%d\n", task->pid, owner ? owner->pid : -1));
+
 	/*
 	 * someone else is still using the PMU, first push it out and
 	 * then we'll be able to install our stuff !
+	 *
+	 * Upon return, there will be no owner for the current PMU
 	 */
-	if (owner) pfm_lazy_save_regs(owner);
-
-#ifdef CONFIG_SMP
-	/* 
-	 * check if context on another CPU (-1 means saved)
-	 * We MUST use the variable, as last_cpu may change behind our 
-	 * back. If it changes to -1 (not on a CPU anymore), then in cpu
-	 * we have the last CPU the context was on. We may be sending the 
-	 * IPI for nothing, but we have no way of verifying this. 
-	 */
-	cpu = atomic_read(&ctx->ctx_last_cpu);
-	if (cpu != -1) {
-		pfm_fetch_regs(cpu, task, ctx);
-	}
-#endif
-
+	if (owner) prev_pmc0 = pfm_lazy_save_regs(owner);
 	/*
 	 * To avoid leaking information to the user level when psr.sp=0,
 	 * we must reload ALL implemented pmds (even the ones we don't use).
 	 * In the kernel we only allow PFM_READ_PMDS on registers which
 	 * we initialized or requested (sampling) so there is no risk there.
-	 *
-	 * As an optimization, we will only reload the PMD that we use when 
-	 * the context is in protected mode, i.e. psr.sp=1 because then there
-	 * is no leak possible.
 	 */
-	mask = pfm_sysctl.fastctxsw || ctx->ctx_fl_protected ?  ctx->ctx_used_pmds[0] : ctx->ctx_reload_pmds[0];
-	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) ia64_set_pmd(i, t->pmd[i] & pmu_conf.ovfl_val);
-	}
-
+	pmd_mask = pfm_sysctl.fastctxsw ?  ctx->ctx_used_pmds[0] : ctx->ctx_reload_pmds[0];
+	
 	/* 
-	 * PMC0 is never set in the mask because it is always restored
-	 * separately.  
+	 * ALL accessible PMCs are systematically reloaded, unused registers
+	 * get their default (from pfm_reset_pmu_state()) values to avoid picking 
+	 * up stale configuration.
 	 *
-	 * ALL PMCs are systematically reloaded, unused registers
-	 * get their default (PAL reset) values to avoid picking up 
-	 * stale configuration.
+	 * PMC0 is never in the mask. It is always restored separately.  
 	 */	
-	mask = ctx->ctx_reload_pmcs[0];
-	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) ia64_set_pmc(i, t->pmc[i]);
-	}
+	pmc_mask = ctx->ctx_reload_pmcs[0];
+
+	pfm_restore_pmds(t->pmd, pmd_mask);
+	pfm_restore_pmcs(t->pmc, pmc_mask);
 
-	if (t->pmc[0] & ~0x1) {
-		pfm_overflow_handler(task, ctx, t->pmc[0], NULL);
+	/*
+	 * Check for pending overflow when state was last saved.
+	 * invoked handler is overflow status bits set.
+	 *
+	 * Any PMU overflow in flight at this point, will still
+	 * be treated as spurious because we have no declared
+	 * owner. Note that the first level interrupt handler 
+	 * DOES NOT TOUCH any PMC except PMC0 for which we have 
+	 * a copy already.
+	 */
+	if (PMC0_HAS_OVFL(t->pmc[0])) {
+		struct pt_regs *regs = TASK_PTREGS(task);
+		pfm_overflow_handler(task, ctx, t->pmc[0], regs);
 	}
 
+
+
 	/*
 	 * fl_frozen==1 when we are in blocking mode waiting for restart
 	 */
 	if (ctx->ctx_fl_frozen == 0) {
 		pfm_unfreeze_pmu();
+	} else if (prev_pmc0 == 0UL && ctx->ctx_fl_frozen) {
+		/*
+		 * owner is still NULL at this point.
+		 *
+		 * if the previous owner (from lazy_save_regs())
+		 * was not in frozen state, then we need to freeze
+		 * the PMU if the new context is frozen.
+		 *
+		 * on McKinley this will generate a spurious interrupt
+		 * but we have no other way.
+		 */
+		pfm_freeze_pmu();
 	}
-	atomic_set(&ctx->ctx_last_cpu, smp_processor_id());
 
+	/*
+	 * establish new ownership. If there was an in-flight
+	 * overflow interrupt, it will be treated as spurious 
+	 * before and after the call, because no overflow
+	 * status bit can possibly be set. No new overflow
+	 * can be generated because, at this point, psr.up
+	 * is still cleared.
+	 */
 	SET_PMU_OWNER(task);
 
 	/*
-	 * restore the psr we changed in pfm_save_regs()
+	 * restore the psr. This is the point at which 
+	 * new overflow interrupts can be generated again.
 	 */
-	psr = ctx->ctx_saved_psr;
 	pfm_set_psr_l(psr);
 }
+#endif /* CONFIG_SMP */
 
 /*
  * XXX: make this routine able to work with non current context
@@ -3798,9 +3865,11 @@
 	 * waitpid().
 	 *
 	 */
-
-	if (atomic_read(&ctx->ctx_last_cpu) != smp_processor_id()) 
-		printk("perfmon: [%d] last_cpu=%d\n", task->pid, atomic_read(&ctx->ctx_last_cpu));
+#ifdef CONFIG_SMP
+	if (GET_LAST_CPU(ctx) != smp_processor_id())
+		printk(KERN_DEBUG "perfmon: [%d] last_cpu=%d\n",
+		       task->pid, GET_LAST_CPU(ctx));
+#endif
 
 	/*
 	 * we save all the used pmds
@@ -3847,11 +3916,7 @@
 			task->thread.pmd[i] = val;
 		}
 	}
-	/* 
-	 * indicates that context has been saved
-	 */
-	atomic_set(&ctx->ctx_last_cpu, -1);
-
+	SET_LAST_CPU(ctx, -1);
 }
 
 
@@ -3875,10 +3940,15 @@
 	thread = &task->thread;
 
 	/*
-	 * make sure child cannot mess up the monitoring session
+	 * for secure sessions, make sure child cannot mess up 
+	 * the monitoring session.
 	 */
-	 ia64_psr(regs)->sp = 1;
-	 DBprintk(("enabling psr.sp for [%d]\n", task->pid));
+	if (ctx->ctx_fl_unsecure == 0) {
+		ia64_psr(regs)->sp = 1;
+	 	DBprintk(("enabling psr.sp for [%d]\n", task->pid));
+	} else {
+	 	DBprintk(("psr.sp=%d [%d]\n", ia64_psr(regs)->sp, task->pid));
+	}
 
 
 	/*
@@ -3938,7 +4008,6 @@
 	/* copy content */
 	*nctx = *ctx;
 
-
 	if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_ONCE) {
 		nctx->ctx_fl_inherit = PFM_FL_INHERIT_NONE;
 		DBprintk(("downgrading to INHERIT_NONE for [%d]\n", task->pid));
@@ -3978,7 +4047,7 @@
 
 	nctx->ctx_fl_frozen    = 0;
 	nctx->ctx_ovfl_regs[0] = 0UL;
-	atomic_set(&nctx->ctx_last_cpu, -1);
+	SET_LAST_CPU(nctx, -1);
 
 	/*
 	 * here nctx->ctx_psb == ctx->ctx_psb
@@ -4014,6 +4083,21 @@
 	 */
 	nctx->ctx_saved_psr = pfm_get_psr();
 
+	/*
+	 * force a full reload on ctxsw in
+	 */
+	nctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
+	SET_LAST_CPU(nctx, -1);
+
+	/*
+	 * initialize tasklet for signal notifications
+	 *
+	 * ALL signal-based (or any notification using data structures
+	 * external to perfmon) MUST use tasklets to avoid lock contentions
+	 * when a signal has to be sent for overflow interrupt handler.
+	 */
+	tasklet_init(&nctx->ctx_tasklet, pfm_send_notification_signal, (unsigned long)nctx);
+
 	/* link with new task */
 	thread->pfm_context = nctx;
 
@@ -4027,7 +4111,6 @@
 		DBprintk(("setting PM_VALID for [%d]\n", task->pid));
 		thread->flags |= IA64_THREAD_PM_VALID;
 	}
-
 	return 0;
 }
 
@@ -4171,7 +4254,7 @@
 	pfm_smpl_buffer_desc_t *tmp, *psb = task->thread.pfm_smpl_buf_list;
 
 	if (psb == NULL) {
-		printk("perfmon: psb is null in [%d]\n", current->pid);
+		printk(KERN_DEBUG "perfmon: psb is null in [%d]\n", current->pid);
 		return -1;
 	}
 	/*
@@ -4331,7 +4414,8 @@
 	if (ret) return ret;
 
 	if (pfm_alternate_intr_handler) {
-		printk("perfmon: install_alternate, intr_handler not NULL after reserve\n");
+		printk(KERN_DEBUG "perfmon: install_alternate, intr_handler not NULL "
+		       "after reserve\n");
 		return -EINVAL;
 	}
 
@@ -4368,10 +4452,8 @@
 
 	pmu_conf.disabled = 1;
 
-	printk("perfmon: version %u.%u IRQ %u\n", 
-		PFM_VERSION_MAJ, 
-		PFM_VERSION_MIN, 
-		IA64_PERFMON_VECTOR);
+	printk(KERN_INFO "perfmon: version %u.%u IRQ %u\n", PFM_VERSION_MAJ, PFM_VERSION_MIN,
+	       IA64_PERFMON_VECTOR);
 
 	/*
 	 * compute the number of implemented PMD/PMC from the
@@ -4395,8 +4477,8 @@
 	pmu_conf.num_pmds      = n;
 	pmu_conf.num_counters  = n_counters;
 
-	printk("perfmon: %u PMCs, %u PMDs, %u counters (%lu bits)\n", 
-	       pmu_conf.num_pmcs, 
+	printk(KERN_INFO "perfmon: %u PMCs, %u PMDs, %u counters (%lu bits)\n",
+	       pmu_conf.num_pmcs,
 	       pmu_conf.num_pmds,
 	       pmu_conf.num_counters,
 	       ffz(pmu_conf.ovfl_val));
@@ -4413,7 +4495,7 @@
 	perfmon_dir = create_proc_read_entry ("perfmon", 0, 0, perfmon_read_entry, NULL);
 	if (perfmon_dir == NULL) {
 		printk(KERN_ERR "perfmon: cannot create /proc entry, perfmon disabled\n");
-		return -1; 
+		return -1;
 	}
 
 	/*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/perfmon_mckinley.h linux-2.4.22-pre10/arch/ia64/kernel/perfmon_mckinley.h
--- linux-2.4.21/arch/ia64/kernel/perfmon_mckinley.h	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/perfmon_mckinley.h	2003-08-01 13:34:21.000000000 +0000
@@ -25,8 +25,8 @@
 /* pmc5  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_reserved, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc6  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_reserved, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc7  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_reserved, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc8  */ { PFM_REG_CONFIG  , 0, 0xffffffff3fffffffUL, 0xffffffff9fffffffUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc9  */ { PFM_REG_CONFIG  , 0, 0xffffffff3ffffffcUL, 0xffffffff9fffffffUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc8  */ { PFM_REG_CONFIG  , 0, 0xffffffff3fffffffUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc9  */ { PFM_REG_CONFIG  , 0, 0xffffffff3ffffffcUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc10 */ { PFM_REG_MONITOR , 4, 0x0UL, 0xffffUL, NULL, pfm_mck_reserved, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc11 */ { PFM_REG_MONITOR , 6, 0x0UL, 0x30f01cf, NULL,  pfm_mck_reserved, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc12 */ { PFM_REG_MONITOR , 6, 0x0UL, 0xffffUL, NULL,  pfm_mck_reserved, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
@@ -143,11 +143,8 @@
 		case  8: val8 = *val;
 			 val13 = th->pmc[13];
 			 val14 = th->pmc[14];
-			 *val |= 1UL << 2; /* bit 2 must always be 1 */
 			 check_case1 = 1;
 			 break;
-		case  9: *val |= 1UL << 2; /* bit 2 must always be 1 */
-			 break;
 		case 13: val8  = th->pmc[8];
 			 val13 = *val;
 			 val14 = th->pmc[14];
@@ -163,12 +160,12 @@
 	 * i-side events in L1D and L2 caches
 	 */
 	if (check_case1) {
-		ret =   ((val13 >> 45) & 0xf) == 0 
+		ret =   ((val13 >> 45) & 0xf) == 0
 		   && ((val8 & 0x1) == 0)
 		   && ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0)
 		       ||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0));
 
-		if (ret) printk("perfmon: failure check_case1\n");
+		if (ret) printk(KERN_DEBUG "perfmon: failure check_case1\n");
 	}
 
 	return ret ? -EINVAL : 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/process.c linux-2.4.22-pre10/arch/ia64/kernel/process.c
--- linux-2.4.21/arch/ia64/kernel/process.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/process.c	2003-08-01 13:33:14.000000000 +0000
@@ -33,10 +33,13 @@
 #include <asm/sn/idle.h>
 #endif
 
-static void
-do_show_stack (struct unw_frame_info *info, void *arg)
+#define print_symbol(fmt, addr)	printk(fmt, "");
+
+void
+ia64_do_show_stack (struct unw_frame_info *info, void *arg)
 {
 	unsigned long ip, sp, bsp;
+	char buf[80];			/* don't make it so big that it overflows the stack! */
 
 	printk("\nCall Trace: ");
 	do {
@@ -46,29 +49,28 @@
 
 		unw_get_sp(info, &sp);
 		unw_get_bsp(info, &bsp);
-		printk("[<%016lx>] sp=0x%016lx bsp=0x%016lx\n", ip, sp, bsp);
+		snprintf(buf, sizeof(buf), " [<%016lx>] %%s\n\t\t\t\tsp=%016lx bsp=%016lx\n",
+			 ip, sp, bsp);
+		print_symbol(buf, ip);
 	} while (unw_unwind(info) >= 0);
 }
 
 void
 show_trace_task (struct task_struct *task)
 {
-	struct unw_frame_info info;
-
-	unw_init_from_blocked_task(&info, task);
-	do_show_stack(&info, 0);
+	show_stack(task);
 }
 
 void
 show_stack (struct task_struct *task)
 {
 	if (!task)
-		unw_init_running(do_show_stack, 0);
+		unw_init_running(ia64_do_show_stack, 0);
 	else {
 		struct unw_frame_info info;
 
 		unw_init_from_blocked_task(&info, task);
-		do_show_stack(&info, 0);
+		ia64_do_show_stack(&info, 0);
 	}
 }
 
@@ -119,7 +121,7 @@
 		}
 	}
 	if (!user_mode(regs))
-		show_stack(0);
+		show_stack(NULL);
 }
 
 void __attribute__((noreturn))
@@ -331,6 +333,7 @@
 #	define THREAD_FLAGS_TO_SET	0
 	p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR)
 			   | THREAD_FLAGS_TO_SET);
+	ia64_drop_fpu(p);	/* don't pick up stale state from a CPU's fph */
 #ifdef CONFIG_IA32_SUPPORT
 	/*
 	 * If we're cloning an IA32 task then save the IA32 extra
@@ -492,6 +495,15 @@
 
 	tid = clone(flags | CLONE_VM, 0);
 	if (parent != current) {
+#ifdef CONFIG_IA32_SUPPORT
+		if (IS_IA32_PROCESS(ia64_task_regs(current))) {
+			/* A kernel thread is always a 64-bit process. */
+			current->thread.map_base  = DEFAULT_MAP_BASE;
+			current->thread.task_size = DEFAULT_TASK_SIZE;
+			ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob);
+			ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1);
+		}
+#endif
 		result = (*fn)(arg);
 		_exit(result);
 	}
@@ -506,11 +518,7 @@
 {
 	/* drop floating-point and debug-register state if it exists: */
 	current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID);
-
-#ifndef CONFIG_SMP
-	if (ia64_get_fpu_owner() == current)
-		ia64_set_fpu_owner(0);
-#endif
+	ia64_drop_fpu(current);
 }
 
 #ifdef CONFIG_PERFMON
@@ -548,10 +556,7 @@
 void
 exit_thread (void)
 {
-#ifndef CONFIG_SMP
-	if (ia64_get_fpu_owner() == current)
-		ia64_set_fpu_owner(0);
-#endif
+	ia64_drop_fpu(current);
 #ifdef CONFIG_PERFMON
        /* stop monitoring */
 	if (current->thread.pfm_context)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/ptrace.c linux-2.4.22-pre10/arch/ia64/kernel/ptrace.c
--- linux-2.4.21/arch/ia64/kernel/ptrace.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/ptrace.c	2003-08-01 13:34:48.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Kernel support for the ptrace() and syscall tracing interfaces.
  *
- * Copyright (C) 1999-2002 Hewlett-Packard Co
+ * Copyright (C) 1999-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * Derived from the x86 and Alpha versions.  Most of the code in here
@@ -25,7 +25,7 @@
 #include <asm/uaccess.h>
 #include <asm/unwind.h>
 #ifdef CONFIG_PERFMON
-# include <asm/perfmon.h>
+#include <asm/perfmon.h>
 #endif
 
 /*
@@ -198,20 +198,27 @@
  *   rnat0/rnat1 gets its value from sw->ar_rnat.
  */
 static unsigned long
-get_rnat (struct pt_regs *pt, struct switch_stack *sw,
-	  unsigned long *krbs, unsigned long *urnat_addr)
+get_rnat (struct task_struct *task, struct switch_stack *sw,
+	  unsigned long *krbs, unsigned long *urnat_addr, unsigned long *urbs_end)
 {
-	unsigned long rnat0 = 0, rnat1 = 0, urnat = 0, *slot0_kaddr, kmask = ~0UL;
+	unsigned long rnat0 = 0, rnat1 = 0, urnat = 0, *slot0_kaddr, umask = 0, mask, m;
 	unsigned long *kbsp, *ubspstore, *rnat0_kaddr, *rnat1_kaddr, shift;
-	long num_regs;
+	long num_regs, nbits;
+	struct pt_regs *pt;
 
+	pt = ia64_task_regs(task);
 	kbsp = (unsigned long *) sw->ar_bspstore;
 	ubspstore = (unsigned long *) pt->ar_bspstore;
+
+	if (urbs_end < urnat_addr)
+		nbits = ia64_rse_num_regs(urnat_addr - 63, urbs_end);
+	else
+		nbits = 63;
+	mask = (1UL << nbits) - 1;
 	/*
-	 * First, figure out which bit number slot 0 in user-land maps
-	 * to in the kernel rnat.  Do this by figuring out how many
-	 * register slots we're beyond the user's backingstore and
-	 * then computing the equivalent address in kernel space.
+	 * First, figure out which bit number slot 0 in user-land maps to in the kernel
+	 * rnat.  Do this by figuring out how many register slots we're beyond the user's
+	 * backingstore and then computing the equivalent address in kernel space.
 	 */
 	num_regs = ia64_rse_num_regs(ubspstore, urnat_addr + 1);
 	slot0_kaddr = ia64_rse_skip_regs(krbs, num_regs);
@@ -221,20 +228,26 @@
 
 	if (ubspstore + 63 > urnat_addr) {
 		/* some bits need to be merged in from pt->ar_rnat */
-		kmask = ~((1UL << ia64_rse_slot_num(ubspstore)) - 1);
-		urnat = (pt->ar_rnat & ~kmask);
+		umask = ((1UL << ia64_rse_slot_num(ubspstore)) - 1) & mask;
+		urnat = (pt->ar_rnat & umask);
+		mask &= ~umask;
+		if (!mask)
+			return urnat;
 	}
-	if (rnat0_kaddr >= kbsp) {
+
+	m = mask << shift;
+	if (rnat0_kaddr >= kbsp)
 		rnat0 = sw->ar_rnat;
-	} else if (rnat0_kaddr > krbs) {
+	else if (rnat0_kaddr > krbs)
 		rnat0 = *rnat0_kaddr;
-	}
-	if (rnat1_kaddr >= kbsp) {
+	urnat |= (rnat0 & m) >> shift;
+
+	m = mask >> (63 - shift);
+	if (rnat1_kaddr >= kbsp)
 		rnat1 = sw->ar_rnat;
-	} else if (rnat1_kaddr > krbs) {
+	else if (rnat1_kaddr > krbs)
 		rnat1 = *rnat1_kaddr;
-	}
-	urnat |= ((rnat1 << (63 - shift)) | (rnat0 >> shift)) & kmask;
+	urnat |= (rnat1 & m) << (63 - shift);
 	return urnat;
 }
 
@@ -242,22 +255,49 @@
  * The reverse of get_rnat.
  */
 static void
-put_rnat (struct pt_regs *pt, struct switch_stack *sw,
-	  unsigned long *krbs, unsigned long *urnat_addr, unsigned long urnat)
+put_rnat (struct task_struct *task, struct switch_stack *sw,
+	  unsigned long *krbs, unsigned long *urnat_addr, unsigned long urnat,
+	  unsigned long *urbs_end)
 {
-	unsigned long rnat0 = 0, rnat1 = 0, rnat = 0, *slot0_kaddr, kmask = ~0UL, mask;
+	unsigned long rnat0 = 0, rnat1 = 0, *slot0_kaddr, umask = 0, mask, m;
 	unsigned long *kbsp, *ubspstore, *rnat0_kaddr, *rnat1_kaddr, shift;
-	long num_regs;
+	long num_regs, nbits;
+	struct pt_regs *pt;
+	unsigned long cfm, *urbs_kargs;
+	struct unw_frame_info info;
 
+	pt = ia64_task_regs(task);
 	kbsp = (unsigned long *) sw->ar_bspstore;
 	ubspstore = (unsigned long *) pt->ar_bspstore;
+
+	urbs_kargs = urbs_end;
+	if ((long)pt->cr_ifs >= 0) {
+		/*
+		 * If entered via syscall, don't allow user to set rnat bits
+		 * for syscall args.
+		 */
+		unw_init_from_blocked_task(&info,task);
+		if (unw_unwind_to_user(&info) == 0) {
+			unw_get_cfm(&info,&cfm);
+			urbs_kargs = ia64_rse_skip_regs(urbs_end,-(cfm & 0x7f));
+		}
+	}
+
+	if (urbs_kargs >= urnat_addr)
+		nbits = 63;
+	else {
+		if ((urnat_addr - 63) >= urbs_kargs)
+			return;
+		nbits = ia64_rse_num_regs(urnat_addr - 63, urbs_kargs);
+	}
+	mask = (1UL << nbits) - 1;
+
 	/*
-	 * First, figure out which bit number slot 0 in user-land maps
-	 * to in the kernel rnat.  Do this by figuring out how many
-	 * register slots we're beyond the user's backingstore and
-	 * then computing the equivalent address in kernel space.
+	 * First, figure out which bit number slot 0 in user-land maps to in the kernel
+	 * rnat.  Do this by figuring out how many register slots we're beyond the user's
+	 * backingstore and then computing the equivalent address in kernel space.
 	 */
-	num_regs = (long) ia64_rse_num_regs(ubspstore, urnat_addr + 1);
+	num_regs = ia64_rse_num_regs(ubspstore, urnat_addr + 1);
 	slot0_kaddr = ia64_rse_skip_regs(krbs, num_regs);
 	shift = ia64_rse_slot_num(slot0_kaddr);
 	rnat1_kaddr = ia64_rse_rnat_addr(slot0_kaddr);
@@ -265,28 +305,29 @@
 
 	if (ubspstore + 63 > urnat_addr) {
 		/* some bits need to be place in pt->ar_rnat: */
-		kmask = ~((1UL << ia64_rse_slot_num(ubspstore)) - 1);
-		pt->ar_rnat = (pt->ar_rnat & kmask) | (rnat & ~kmask);
+		umask = ((1UL << ia64_rse_slot_num(ubspstore)) - 1) & mask;
+		pt->ar_rnat = (pt->ar_rnat & ~umask) | (urnat & umask);
+		mask &= ~umask;
+		if (!mask)
+			return;
 	}
 	/*
 	 * Note: Section 11.1 of the EAS guarantees that bit 63 of an
 	 * rnat slot is ignored. so we don't have to clear it here.
 	 */
 	rnat0 = (urnat << shift);
-	mask = ~0UL << shift;
-	if (rnat0_kaddr >= kbsp) {
-		sw->ar_rnat = (sw->ar_rnat & ~mask) | (rnat0 & mask);
-	} else if (rnat0_kaddr > krbs) {
-		*rnat0_kaddr = ((*rnat0_kaddr & ~mask) | (rnat0 & mask));
-	}
+	m = mask << shift;
+	if (rnat0_kaddr >= kbsp)
+		sw->ar_rnat = (sw->ar_rnat & ~m) | (rnat0 & m);
+	else if (rnat0_kaddr > krbs)
+		*rnat0_kaddr = ((*rnat0_kaddr & ~m) | (rnat0 & m));
 
 	rnat1 = (urnat >> (63 - shift));
-	mask = ~0UL >> (63 - shift);
-	if (rnat1_kaddr >= kbsp) {
-		sw->ar_rnat = (sw->ar_rnat & ~mask) | (rnat1 & mask);
-	} else if (rnat1_kaddr > krbs) {
-		*rnat1_kaddr = ((*rnat1_kaddr & ~mask) | (rnat1 & mask));
-	}
+	m = mask >> (63 - shift);
+	if (rnat1_kaddr >= kbsp)
+		sw->ar_rnat = (sw->ar_rnat & ~m) | (rnat1 & m);
+	else if (rnat1_kaddr > krbs)
+		*rnat1_kaddr = ((*rnat1_kaddr & ~m) | (rnat1 & m));
 }
 
 /*
@@ -319,7 +360,7 @@
 		 * read the corresponding bits in the kernel RBS.
 		 */
 		rnat_addr = ia64_rse_rnat_addr(laddr);
-		ret = get_rnat(child_regs, child_stack, krbs, rnat_addr);
+		ret = get_rnat(child, child_stack, krbs, rnat_addr, urbs_end);
 
 		if (laddr == rnat_addr) {
 			/* return NaT collection word itself */
@@ -370,7 +411,7 @@
 		 * => write the corresponding bits in the kernel RBS.
 		 */
 		if (ia64_rse_is_rnat_slot(laddr))
-			put_rnat(child_regs, child_stack, krbs, laddr, val);
+			put_rnat(child, child_stack, krbs, laddr, val, urbs_end);
 		else {
 			if (laddr < urbs_end) {
 				regnum = ia64_rse_num_regs(bspstore, laddr);
@@ -578,16 +619,11 @@
 ia64_flush_fph (struct task_struct *task)
 {
 	struct ia64_psr *psr = ia64_psr(ia64_task_regs(task));
-#ifdef CONFIG_SMP
-	struct task_struct *fpu_owner = current;
-#else
-	struct task_struct *fpu_owner = ia64_get_fpu_owner();
-#endif
 
-	if (task == fpu_owner && psr->mfh) {
+	if (ia64_is_local_fpu_owner(task) && psr->mfh) {
 		psr->mfh = 0;
-		ia64_save_fpu(&task->thread.fph[0]);
 		task->thread.flags |= IA64_THREAD_FPH_VALID;
+		ia64_save_fpu(&task->thread.fph[0]);
 	}
 }
 
@@ -609,10 +645,7 @@
 		task->thread.flags |= IA64_THREAD_FPH_VALID;
 		memset(&task->thread.fph, 0, sizeof(task->thread.fph));
 	}
-#ifndef CONFIG_SMP
-	if (ia64_get_fpu_owner() == task)
-		ia64_set_fpu_owner(0);
-#endif
+	ia64_drop_fpu(task);
 	psr->dfh = 1;
 }
 
@@ -701,7 +734,9 @@
 		      case PT_R4: case PT_R5: case PT_R6: case PT_R7:
 			if (write_access) {
 				/* read NaT bit first: */
-				ret = unw_get_gr(&info, (addr - PT_R4)/8 + 4, data, &nat);
+				unsigned long dummy;
+
+				ret = unw_get_gr(&info, (addr - PT_R4)/8 + 4, &dummy, &nat);
 				if (ret < 0)
 					return ret;
 			}
@@ -846,8 +881,7 @@
 		 * IA64_THREAD_DBG_VALID. The registers are restored by the PMU context
 		 * switch code.
 		 */
-		if (pfm_use_debug_registers(child))
-			return -1;
+		if (pfm_use_debug_registers(child)) return -1;
 #endif
 
 		if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
@@ -1344,10 +1378,11 @@
 	set_current_state(TASK_STOPPED);
 	notify_parent(current, SIGCHLD);
 	schedule();
+
 	/*
-	 * This isn't the same as continuing with a signal, but it
-	 * will do for normal use.  strace only continues with a
-	 * signal if the stopping signal is not SIGTRAP.  -brl
+	 * This isn't the same as continuing with a signal, but it will do for normal use.
+	 * strace only continues with a signal if the stopping signal is not SIGTRAP.
+	 * -brl
 	 */
 	if (current->exit_code) {
 		send_sig(current->exit_code, current, 1);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/sal.c linux-2.4.22-pre10/arch/ia64/kernel/sal.c
--- linux-2.4.21/arch/ia64/kernel/sal.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/sal.c	2003-08-01 13:34:43.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * System Abstraction Layer (SAL) interface routines.
  *
- * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
+ * Copyright (C) 1998, 1999, 2001, 2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
@@ -77,7 +77,7 @@
 	return str;
 }
 
-static void __init
+void __init
 ia64_sal_handler_init (void *entry_point, void *gpval)
 {
 	/* fill in the SAL procedure descriptor and point ia64_sal to it: */
@@ -96,17 +96,17 @@
 	int i;
 
 	if (!systab) {
-		printk("Hmm, no SAL System Table.\n");
+		printk(KERN_WARNING "Hmm, no SAL System Table.\n");
 		return;
 	}
 
 	if (strncmp(systab->signature, "SST_", 4) != 0)
-		printk("bad signature in system table!");
+		printk(KERN_ERR "bad signature in system table!");
 
 	/*
 	 * revisions are coded in BCD, so %x does the job for us
 	 */
-	printk("SAL v%x.%02x: oem=%.32s, product=%.32s\n",
+	printk(KERN_INFO "SAL v%x.%02x: oem=%.32s, product=%.32s\n",
 	       systab->sal_rev_major, systab->sal_rev_minor,
 	       systab->oem_id, systab->product_id);
 
@@ -121,7 +121,7 @@
 		switch (*p) {
 		      case SAL_DESC_ENTRY_POINT:
 			ep = (struct ia64_sal_desc_entry_point *) p;
-			printk("SAL: entry: pal_proc=0x%lx, sal_proc=0x%lx\n",
+			printk(KERN_INFO "SAL: entry: pal_proc=0x%lx, sal_proc=0x%lx\n",
 			       ep->pal_proc, ep->sal_proc);
 			ia64_pal_handler_init(__va(ep->pal_proc));
 			ia64_sal_handler_init(__va(ep->sal_proc), __va(ep->gp));
@@ -139,12 +139,12 @@
 			      switch (ap->mechanism) {
 				    case IA64_SAL_AP_EXTERNAL_INT:
 				      ap_wakeup_vector = ap->vector;
-				      printk("SAL: AP wakeup using external interrupt "
+				      printk(KERN_INFO "SAL: AP wakeup using external interrupt "
 					     "vector 0x%lx\n", ap_wakeup_vector);
 				      break;
 
 				    default:
-				      printk("SAL: AP wakeup mechanism unsupported!\n");
+				      printk(KERN_ERR "SAL: AP wakeup mechanism unsupported!\n");
 				      break;
 			      }
 			      break;
@@ -154,7 +154,7 @@
 		      {
 			      struct ia64_sal_desc_platform_feature *pf = (void *) p;
 			      sal_platform_features = pf->feature_mask;
-			      printk("SAL: Platform features ");
+			      printk(KERN_INFO "SAL: Platform features ");
 
 			      if (pf->feature_mask & IA64_SAL_PLATFORM_FEATURE_BUS_LOCK)
 				      printk("BusLock ");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/salinfo.c linux-2.4.22-pre10/arch/ia64/kernel/salinfo.c
--- linux-2.4.21/arch/ia64/kernel/salinfo.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/salinfo.c	2003-08-01 13:33:06.000000000 +0000
@@ -4,6 +4,8 @@
  * Creates entries in /proc/sal for various system features.
  *
  * Copyright (c) 2001 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2003 Hewlett-Packard Co
+ *	Bjorn Helgaas <bjorn.helgaas@hp.com>
  *
  * 10/30/2001	jbarnes@sgi.com		copied much of Stephane's palinfo
  *					code to create this file
@@ -12,8 +14,10 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/module.h>
+#include <linux/smp.h>
 
 #include <asm/sal.h>
+#include <asm/uaccess.h>
 
 MODULE_AUTHOR("Jesse Barnes <jbarnes@sgi.com>");
 MODULE_DESCRIPTION("/proc interface to IA-64 SAL features");
@@ -40,25 +44,325 @@
 
 #define NR_SALINFO_ENTRIES (sizeof(salinfo_entries)/sizeof(salinfo_entry_t))
 
-/*
- * One for each feature and one more for the directory entry...
- */
-static struct proc_dir_entry *salinfo_proc_entries[NR_SALINFO_ENTRIES + 1];
+static char *salinfo_log_name[] = {
+	"mca",
+	"init",
+	"cmc",
+	"cpe",
+};
+
+static struct proc_dir_entry *salinfo_proc_entries[
+	ARRAY_SIZE(salinfo_entries) +			/* /proc/sal/bus_lock */
+	ARRAY_SIZE(salinfo_log_name) +			/* /proc/sal/{mca,...} */
+	(2 * ARRAY_SIZE(salinfo_log_name)) +		/* /proc/sal/mca/{event,data} */
+	1];						/* /proc/sal */
+
+struct salinfo_log_data {
+	int	type;
+	u8	*log_buffer;
+	u64	log_size;
+};
+
+struct salinfo_event {
+	int			type;
+	int			cpu;		/* next CPU to check */
+	volatile unsigned long	cpu_mask;
+	wait_queue_head_t	queue;
+};
+
+static struct salinfo_event *salinfo_event[ARRAY_SIZE(salinfo_log_name)];
+
+struct salinfo_data {
+	int	open;		/* single-open to prevent races */
+	int	type;
+	int	cpu;		/* "current" cpu for reads */
+};
+
+static struct salinfo_data salinfo_data[ARRAY_SIZE(salinfo_log_name)];
+
+static spinlock_t data_lock;
+
+void
+salinfo_log_wakeup(int type)
+{
+	if (type < ARRAY_SIZE(salinfo_log_name)) {
+		struct salinfo_event *event = salinfo_event[type];
+
+		if (event) {
+			set_bit(smp_processor_id(), &event->cpu_mask);
+			wake_up_interruptible(&event->queue);
+		}
+	}
+}
+
+static int
+salinfo_event_open(struct inode *inode, struct file *file)
+{
+	struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
+	struct salinfo_event *event = entry->data;
+
+	if (!suser())
+		return -EPERM;
+	return 0;
+}
+
+static ssize_t
+salinfo_event_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
+	struct salinfo_event *event = entry->data;
+	char cmd[32];
+	size_t size;
+	int i, n, cpu = -1;
+
+retry:
+	if (!event->cpu_mask) {
+		if (file->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		interruptible_sleep_on(&event->queue);
+		if (signal_pending(current))
+			return -EINTR;
+	}
+
+	n = event->cpu;
+	for (i = 0; i < NR_CPUS; i++) {
+		if (event->cpu_mask & 1UL << n) {
+			cpu = n;
+			break;
+		}
+		if (++n == NR_CPUS)
+			n = 0;
+	}
+
+	if (cpu == -1)
+		goto retry;
+
+	/* for next read, start checking at next CPU */
+	event->cpu = cpu;
+	if (++event->cpu == NR_CPUS)
+		event->cpu = 0;
+
+	snprintf(cmd, sizeof(cmd), "read %d\n", cpu);
+
+	size = strlen(cmd);
+	if (size > count)
+		size = count;
+	if (copy_to_user(buffer, cmd, size))
+		return -EFAULT;
+
+	return size;
+}
+
+static struct file_operations salinfo_event_fops = {
+	.open  = salinfo_event_open,
+	.read  = salinfo_event_read,
+};
+
+static int
+salinfo_log_open(struct inode *inode, struct file *file)
+{
+	struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
+	struct salinfo_data *data = entry->data;
+
+	if (!suser())
+		return -EPERM;
+
+	spin_lock(&data_lock);
+	if (data->open) {
+		spin_unlock(&data_lock);
+		return -EBUSY;
+	}
+	data->open = 1;
+	spin_unlock(&data_lock);
+
+	return 0;
+}
+
+static int
+salinfo_log_release(struct inode *inode, struct file *file)
+{
+	struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
+	struct salinfo_data *data = entry->data;
+
+	spin_lock(&data_lock);
+	data->open = 0;
+	spin_unlock(&data_lock);
+	return 0;
+}
+
+static void
+call_on_cpu(int cpu, void (*fn)(void *), void *arg)
+{
+	if (cpu == smp_processor_id())
+		(*fn)(arg);
+#ifdef CONFIG_SMP
+	else if (cpu_online(cpu))	/* cpu may not have been validated */
+		smp_call_function_single(cpu, fn, arg, 0, 1);
+#endif
+}
+
+static void
+salinfo_log_read_cpu(void *context)
+{
+	struct salinfo_log_data *info = context;
+	struct salinfo_event *event = salinfo_event[info->type];
+	u64 size;
+
+	size = ia64_sal_get_state_info_size(info->type);
+	info->log_buffer = kmalloc(size, GFP_ATOMIC);
+	if (!info->log_buffer)
+		return;
+
+	clear_bit(smp_processor_id(), &event->cpu_mask);
+	info->log_size = ia64_sal_get_state_info(info->type, (u64 *) info->log_buffer);
+	if (info->log_size)
+		salinfo_log_wakeup(info->type);
+}
+
+static ssize_t
+salinfo_log_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
+	struct salinfo_data *data = entry->data;
+	struct salinfo_log_data info;
+	int ret;
+	void *saldata;
+	size_t size;
+
+	info.type = data->type;
+	info.log_buffer = 0;
+	call_on_cpu(data->cpu, salinfo_log_read_cpu, &info);
+	if (!info.log_buffer || *ppos >= info.log_size) {
+		ret = 0;
+		goto out;
+	}
+
+	saldata = info.log_buffer + file->f_pos;
+	size = info.log_size - file->f_pos;
+	if (size > count)
+		size = count;
+	if (copy_to_user(buffer, saldata, size)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	*ppos += size;
+	ret = size;
+
+out:
+	kfree(info.log_buffer);
+	return ret;
+}
+
+static void
+salinfo_log_clear_cpu(void *context)
+{
+	struct salinfo_data *data = context;
+	struct salinfo_event *event = salinfo_event[data->type];
+	struct salinfo_log_data info;
+
+	clear_bit(smp_processor_id(), &event->cpu_mask);
+	ia64_sal_clear_state_info(data->type);
+
+	/* clearing one record may make another visible */
+	info.type = data->type;
+	salinfo_log_read_cpu(&info);
+	if (info.log_buffer && info.log_size)
+		salinfo_log_wakeup(data->type);
+
+	kfree(info.log_buffer);
+}
+
+static ssize_t
+salinfo_log_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct proc_dir_entry *entry = (struct proc_dir_entry *) inode->u.generic_ip;
+	struct salinfo_data *data = entry->data;
+	char cmd[32];
+	size_t size;
+	int cpu;
+
+	size = sizeof(cmd);
+	if (count < size)
+		size = count;
+	if (copy_from_user(cmd, buffer, size))
+		return -EFAULT;
+
+	if (sscanf(cmd, "read %d", &cpu) == 1)
+		data->cpu = cpu;
+	else if (sscanf(cmd, "clear %d", &cpu) == 1)
+		call_on_cpu(cpu, salinfo_log_clear_cpu, data);
+
+	return count;
+}
+
+static struct file_operations salinfo_data_fops = {
+	.open    = salinfo_log_open,
+	.release = salinfo_log_release,
+	.read    = salinfo_log_read,
+	.write   = salinfo_log_write,
+};
 
 static int __init
 salinfo_init(void)
 {
 	struct proc_dir_entry *salinfo_dir; /* /proc/sal dir entry */
 	struct proc_dir_entry **sdir = salinfo_proc_entries; /* keeps track of every entry */
-	int i;
+	struct proc_dir_entry *dir, *entry;
+	struct salinfo_event *event;
+	struct salinfo_data *data;
+	int i, j;
 
 	salinfo_dir = proc_mkdir("sal", NULL);
+	if (!salinfo_dir)
+		return 0;
 
 	for (i=0; i < NR_SALINFO_ENTRIES; i++) {
 		/* pass the feature bit in question as misc data */
 		*sdir++ = create_proc_read_entry (salinfo_entries[i].name, 0, salinfo_dir,
 						  salinfo_read, (void *)salinfo_entries[i].feature);
 	}
+
+	for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) {
+		dir = proc_mkdir(salinfo_log_name[i], salinfo_dir);
+		if (!dir)
+			continue;
+
+		entry = create_proc_entry("event", S_IRUSR, dir);
+		if (!entry)
+			continue;
+
+		event = kmalloc(sizeof(*event), GFP_KERNEL);
+		if (!event)
+			continue;
+		memset(event, 0, sizeof(*event));
+		event->type = i;
+		init_waitqueue_head(&event->queue);
+		salinfo_event[i] = event;
+		/* we missed any events before now */
+		for (j = 0; j < NR_CPUS; j++)
+			if (cpu_online(j))
+				set_bit(j, &event->cpu_mask);
+		entry->data = event;
+		entry->proc_fops = &salinfo_event_fops;
+		*sdir++ = entry;
+
+		entry = create_proc_entry("data", S_IRUSR | S_IWUSR, dir);
+		if (!entry)
+			continue;
+
+		data = &salinfo_data[i];
+		data->type = i;
+		entry->data = data;
+		entry->proc_fops = &salinfo_data_fops;
+		*sdir++ = entry;
+
+		*sdir++ = dir;
+	}
+
 	*sdir++ = salinfo_dir;
 
 	return 0;
@@ -69,7 +373,7 @@
 {
 	int i = 0;
 
-	for (i = 0; i < NR_SALINFO_ENTRIES ; i++) {
+	for (i = 0; i < ARRAY_SIZE(salinfo_proc_entries); i++) {
 		if (salinfo_proc_entries[i])
 			remove_proc_entry (salinfo_proc_entries[i]->name, NULL);
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/setup.c linux-2.4.22-pre10/arch/ia64/kernel/setup.c
--- linux-2.4.21/arch/ia64/kernel/setup.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/setup.c	2003-08-01 13:31:21.000000000 +0000
@@ -125,7 +125,7 @@
 
 #if IGNORE_PFN0
 	if (start == PAGE_OFFSET) {
-		printk("warning: skipping physical page 0\n");
+		printk(KERN_WARNING "warning: skipping physical page 0\n");
 		start += PAGE_SIZE;
 		if (start >= end) return 0;
 	}
@@ -278,7 +278,7 @@
 		initrd_start = (unsigned long)__va(ia64_boot_param->initrd_start);
 		initrd_end   = initrd_start+ia64_boot_param->initrd_size;
 
-		printk("Initial ramdisk at: 0x%lx (%lu bytes)\n",
+		printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n",
 		       initrd_start, ia64_boot_param->initrd_size);
 	}
 #endif
@@ -335,8 +335,9 @@
 		ia64_set_kr(IA64_KR_IO_BASE, phys_iobase);
 	else {
 		phys_iobase = ia64_get_kr(IA64_KR_IO_BASE);
-		printk("No I/O port range found in EFI memory map, falling back to AR.KR0\n");
-		printk("I/O port base = 0x%lx\n", phys_iobase);
+		printk(KERN_INFO "No I/O port range found in EFI memory map, falling back "
+		       "to AR.KR0\n");
+		printk(KERN_INFO "I/O port base = 0x%lx\n", phys_iobase);
 	}
 	ia64_iobase = (unsigned long) ioremap(phys_iobase, 0);
 
@@ -470,10 +471,10 @@
 }
 
 struct seq_operations cpuinfo_op = {
-	start:	c_start,
-	next:	c_next,
-	stop:	c_stop,
-	show:	show_cpuinfo
+	.start =c_start,
+	.next =	c_next,
+	.stop =	c_stop,
+	.show =	show_cpuinfo
 };
 
 void
@@ -526,7 +527,7 @@
 		impl_va_msb = vm2.pal_vm_info_2_s.impl_va_msb;
 		phys_addr_size = vm1.pal_vm_info_1_s.phys_add_size;
 	}
-	printk("CPU %d: %lu virtual and %lu physical address bits\n",
+	printk(KERN_INFO "CPU %d: %lu virtual and %lu physical address bits\n",
 	       smp_processor_id(), impl_va_msb + 1, phys_addr_size);
 	c->unimpl_va_mask = ~((7L<<61) | ((1L << (impl_va_msb + 1)) - 1));
 	c->unimpl_pa_mask = ~((1L<<63) | ((1L << phys_addr_size) - 1));
@@ -609,6 +610,8 @@
 	/* Clear the stack memory reserved for pt_regs: */
 	memset(ia64_task_regs(current), 0, sizeof(struct pt_regs));
 
+	ia64_set_kr(IA64_KR_FPU_OWNER, 0);
+
 	/*
 	 * Initialize default control register to defer all speculative faults.  The
 	 * kernel MUST NOT depend on a particular setting of these bits (in other words,
@@ -619,10 +622,6 @@
 	 */
 	ia64_set_dcr(  IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR
 		     | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC);
-#ifndef CONFIG_SMP
-	ia64_set_fpu_owner(0);
-#endif
-
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
 
@@ -650,7 +649,7 @@
 	if (ia64_pal_vm_summary(NULL, &vmi) == 0)
 		max_ctx = (1U << (vmi.pal_vm_info_2_s.rid_size - 3)) - 1;
 	else {
-		printk("cpu_init: PAL VM summary failed, assuming 18 RID bits\n");
+		printk(KERN_WARNING "cpu_init: PAL VM summary failed, assuming 18 RID bits\n");
 		max_ctx = (1U << 15) - 1;	/* use architected minimum */
 	}
 	while (max_ctx < ia64_ctx.max_ctx) {
@@ -660,7 +659,7 @@
 	}
 
 	if (ia64_pal_rse_info(&num_phys_stacked, 0) != 0) {
-		printk ("cpu_init: PAL RSE info failed, assuming 96 physical stacked regs\n");
+		printk(KERN_WARNING "cpu_init: PAL RSE info failed, assuming 96 physical stacked regs\n");
 		num_phys_stacked = 96;
 	}
 	local_cpu_data->phys_stacked_size_p8 = num_phys_stacked*8 + 8;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/sigframe.h linux-2.4.22-pre10/arch/ia64/kernel/sigframe.h
--- linux-2.4.21/arch/ia64/kernel/sigframe.h	2001-11-09 22:26:17.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/sigframe.h	2003-08-01 13:32:01.000000000 +0000
@@ -1,6 +1,6 @@
 struct sigscratch {
 	unsigned long scratch_unat;	/* ar.unat for the general registers saved in pt */
-	unsigned long pad;
+	unsigned long ar_pfs;		/* for syscalls, the user-level function-state  */
 	struct pt_regs pt;
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/signal.c linux-2.4.22-pre10/arch/ia64/kernel/signal.c
--- linux-2.4.21/arch/ia64/kernel/signal.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/signal.c	2003-08-01 13:33:39.000000000 +0000
@@ -142,8 +142,13 @@
 
 		__copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16);
 		psr->mfh = 0;	/* drop signal handler's fph contents... */
-		if (!psr->dfh)
+		if (psr->dfh)
+			ia64_drop_fpu(current);
+		else {
+			/* We already own the local fph, otherwise psr->dfh wouldn't be 0.  */
 			__ia64_load_fpu(current->thread.fph);
+			ia64_set_local_fpu_owner(current);
+		}
 	}
 	return err;
 }
@@ -315,7 +320,7 @@
 static long
 setup_sigcontext (struct sigcontext *sc, sigset_t *mask, struct sigscratch *scr)
 {
-	unsigned long flags = 0, ifs, nat;
+	unsigned long flags = 0, ifs, cfm, nat;
 	long err;
 
 	ifs = scr->pt.cr_ifs;
@@ -325,7 +330,9 @@
 	if ((ifs & (1UL << 63)) == 0) {
 		/* if cr_ifs isn't valid, we got here through a syscall */
 		flags |= IA64_SC_FLAG_IN_SYSCALL;
-	}
+		cfm = scr->ar_pfs & ((1UL << 38) - 1);
+	} else
+		cfm = ifs & ((1UL << 38) - 1);
 	ia64_flush_fph(current);
 	if ((current->thread.flags & IA64_THREAD_FPH_VALID)) {
 		flags |= IA64_SC_FLAG_FPH_VALID;
@@ -344,6 +351,7 @@
 
 	err |= __put_user(nat, &sc->sc_nat);
 	err |= PUT_SIGSET(mask, &sc->sc_mask);
+	err |= __put_user(cfm, &sc->sc_cfm);
 	err |= __put_user(scr->pt.cr_ipsr & IA64_PSR_UM, &sc->sc_um);
 	err |= __put_user(scr->pt.ar_rsc, &sc->sc_ar_rsc);
 	err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv);
@@ -422,6 +430,15 @@
 	scr->pt.ar_fpsr = FPSR_DEFAULT;			/* reset fpsr for signal handler */
 	scr->pt.cr_iip = tramp_addr;
 	ia64_psr(&scr->pt)->ri = 0;			/* start executing in first slot */
+	/*
+	 * Force the interruption function mask to zero.  This has no effect when a
+	 * system-call got interrupted by a signal (since, in that case, scr->pt_cr_ifs is
+	 * ignored), but it has the desirable effect of making it possible to deliver a
+	 * signal with an incomplete register frame (which happens when a mandatory RSE
+	 * load faults).  Furthermore, it has no negative effect on the getting the user's
+	 * dirty partition preserved, because that's governed by scr->pt.loadrs.
+	 */
+	scr->pt.cr_ifs = (1UL << 63);
 
 	/*
 	 * Note: this affects only the NaT bits of the scratch regs (the ones saved in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/smpboot.c linux-2.4.22-pre10/arch/ia64/kernel/smpboot.c
--- linux-2.4.21/arch/ia64/kernel/smpboot.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/smpboot.c	2003-08-01 13:31:57.000000000 +0000
@@ -1,7 +1,8 @@
 /*
  * SMP boot-related support
  *
- * Copyright (C) 2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * 01/05/16 Rohit Seth <rohit.seth@intel.com>	Moved SMP booting functions from smp.c to here.
  * 01/04/27 David Mosberger <davidm@hpl.hp.com>	Added ITC synching code.
@@ -66,8 +67,8 @@
 
 #define DEBUG_ITC_SYNC	0
 
-extern void __init calibrate_delay(void);
-extern void start_ap(void);
+extern void __init calibrate_delay (void);
+extern void start_ap (void);
 extern unsigned long ia64_iobase;
 
 int cpucount;
@@ -235,7 +236,7 @@
 	go[MASTER] = 1;
 
 	if (smp_call_function_single(master, sync_master, NULL, 1, 0) < 0) {
-		printk("sync_itc: failed to get attention of CPU %u!\n", master);
+		printk(KERN_ERR "sync_itc: failed to get attention of CPU %u!\n", master);
 		return;
 	}
 
@@ -275,8 +276,8 @@
 		       t[i].rt, t[i].master, t[i].diff, t[i].lat);
 #endif
 
-	printk("CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, maxerr %lu cycles)\n",
-	       smp_processor_id(), master, delta, rt);
+	printk(KERN_INFO "CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, "
+	       "maxerr %lu cycles)\n", smp_processor_id(), master, delta, rt);
 }
 
 /*
@@ -328,19 +329,14 @@
 	phys_id = hard_smp_processor_id();
 
 	if (test_and_set_bit(cpuid, &cpu_online_map)) {
-		printk("huh, phys CPU#0x%x, CPU#0x%x already present??\n", phys_id, cpuid);
+		printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
+		       phys_id, cpuid);
 		BUG();
 	}
 
 	smp_setup_percpu_timer();
 
 	/*
-	 * Synchronize the ITC with the BP
-	 */
-	Dprintk("Going to syncup ITC with BP.\n");
-
-	ia64_sync_itc(0);
-	/*
 	 * Get our bogomips.
 	 */
 	ia64_init_itm();
@@ -362,6 +358,27 @@
 	local_irq_enable();
 	calibrate_delay();
 	local_cpu_data->loops_per_jiffy = loops_per_jiffy;
+
+	if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) {
+		/*
+		 * Synchronize the ITC with the BP.  Need to do this after irqs are
+		 * enabled because ia64_sync_itc() calls smp_call_function_single(), which
+		 * calls spin_unlock_bh(), which calls spin_unlock_bh(), which calls
+		 * local_bh_enable(), which bugs out if irqs are not enabled...
+		 */
+		Dprintk("Going to syncup ITC with BP.\n");
+		ia64_sync_itc(0);
+
+		/*
+		 * Make sure we didn't sync the itc ahead of the next
+		 * timer interrupt, if so, just reset it.
+		 */
+		if (time_after(ia64_get_itc(),local_cpu_data->itm_next)) {
+			Dprintk("oops, jumped a timer.\n");
+			ia64_cpu_local_tick();
+		}
+	}
+
 	/*
 	 * Allow the master to continue.
 	 */
@@ -394,8 +411,8 @@
 fork_by_hand (void)
 {
 	/*
-	 * don't care about the eip and regs settings since
-	 * we'll never reschedule the forked task.
+	 * don't care about the eip and regs settings since we'll never reschedule the
+	 * forked task.
 	 */
 	return do_fork(CLONE_VM|CLONE_PID, 0, 0, 0);
 }
@@ -430,7 +447,7 @@
 	unhash_process(idle);
 	init_tasks[cpu] = idle;
 
-	Dprintk("Sending wakeup vector %u to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid);
+	Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid);
 
 	platform_send_ipi(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0);
 
@@ -447,9 +464,7 @@
 
 	if (test_bit(cpu, &cpu_callin_map)) {
 		/* number CPUs logically, starting from 1 (BSP is 0) */
-		printk("CPU%d: ", cpu);
-		/*print_cpu_info(&cpu_data[cpu]); */
-		printk("CPU has booted.\n");
+		printk(KERN_INFO "CPU%d: CPU has booted.\n", cpu);
 	} else {
 		printk(KERN_ERR "Processor 0x%x/0x%x is stuck.\n", cpu, sapicid);
 		ia64_cpu_to_sapicid[cpu] = -1;
@@ -476,15 +491,15 @@
 	smp_setup_percpu_timer();
 
 	/*
-	* We have the boot CPU online for sure.
-	*/
+	 * We have the boot CPU online for sure.
+	 */
 	set_bit(0, &cpu_online_map);
 	set_bit(0, &cpu_callin_map);
 
 	local_cpu_data->loops_per_jiffy = loops_per_jiffy;
 	ia64_cpu_to_sapicid[0] = boot_cpu_id;
 
-	printk("Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id);
+	printk(KERN_INFO "Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id);
 
 	global_irq_holder = 0;
 	current->processor = 0;
@@ -500,7 +515,7 @@
 		goto smp_done;
 	}
 	if  (max_cpus != -1)
-		printk (KERN_INFO "Limiting CPUs to %d\n", max_cpus);
+		printk(KERN_INFO "Limiting CPUs to %d\n", max_cpus);
 
 	if (smp_boot_data.cpu_count > 1) {
 
@@ -518,12 +533,6 @@
 				break;
 
 			do_boot_cpu(sapicid);
-
-			/*
-			 * Make sure we unmap all failed CPUs
-			 */
-			if (ia64_cpu_to_sapicid[cpu] == -1)
-				printk("phys CPU#%d not responding - cannot use it.\n", cpu);
 		}
 
 		smp_num_cpus = cpucount + 1;
@@ -541,7 +550,7 @@
 				if (cpu_online_map & (1UL << cpu))
 					bogosum += cpu_data(cpu)->loops_per_jiffy;
 
-			printk(KERN_INFO"Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
+			printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
 			       cpucount + 1, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100);
 		}
 	}
@@ -550,7 +559,7 @@
 }
 
 /*
- * Assume that CPU's have been discovered by some platform-dependant interface.  For
+ * Assume that CPU's have been discovered by some platform-dependent interface.  For
  * SoftSDV/Lion, that would be ACPI.
  *
  * Setup of the IPI irq handler is done in irq.c:init_IRQ_SMP().
@@ -569,7 +578,7 @@
 	sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ,
 				       __pa(ap_startup->fp), __pa(ap_startup->gp), 0, 0, 0, 0);
 	if (sal_ret < 0) {
-		printk("SMP: Can't set SAL AP Boot Rendezvous: %s\n     Forcing UP mode\n",
+		printk(KERN_ERR "SMP: Can't set SAL AP Boot Rendezvous: %s\n     Forcing UP mode\n",
 		       ia64_sal_strerror(sal_ret));
 		max_cpus = 0;
 		smp_num_cpus = 1;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/sys_ia64.c linux-2.4.22-pre10/arch/ia64/kernel/sys_ia64.c
--- linux-2.4.21/arch/ia64/kernel/sys_ia64.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/sys_ia64.c	2003-08-01 13:33:38.000000000 +0000
@@ -56,16 +56,14 @@
 }
 
 asmlinkage long
-ia64_getpriority (int which, int who, long arg2, long arg3, long arg4, long arg5, long arg6,
-		  long arg7, long stack)
+ia64_getpriority (int which, int who)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
 	extern long sys_getpriority (int, int);
 	long prio;
 
 	prio = sys_getpriority(which, who);
 	if (prio >= 0) {
-		regs->r8 = 0;	/* ensure negative priority is not mistaken as error code */
+		force_successful_syscall_return();
 		prio = 20 - prio;
 	}
 	return prio;
@@ -79,11 +77,9 @@
 }
 
 asmlinkage unsigned long
-ia64_shmat (int shmid, void *shmaddr, int shmflg, long arg3, long arg4, long arg5, long arg6,
-	    long arg7, long stack)
+ia64_shmat (int shmid, void *shmaddr, int shmflg)
 {
 	extern int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr);
-	struct pt_regs *regs = (struct pt_regs *) &stack;
 	unsigned long raddr;
 	int retval;
 
@@ -91,16 +87,14 @@
 	if (retval < 0)
 		return retval;
 
-	regs->r8 = 0;	/* ensure negative addresses are not mistaken as an error code */
+	force_successful_syscall_return();
 	return raddr;
 }
 
 asmlinkage unsigned long
-ia64_brk (unsigned long brk, long arg1, long arg2, long arg3,
-	  long arg4, long arg5, long arg6, long arg7, long stack)
+ia64_brk (unsigned long brk)
 {
 	extern int vm_enough_memory (long pages);
-	struct pt_regs *regs = (struct pt_regs *) &stack;
 	unsigned long rlim, retval, newbrk, oldbrk;
 	struct mm_struct *mm = current->mm;
 
@@ -150,7 +144,7 @@
 out:
 	retval = mm->brk;
 	up_write(&mm->mmap_sem);
-	regs->r8 = 0;		/* ensure large retval isn't mistaken as error code */
+	force_successful_syscall_return();
 	return retval;
 }
 
@@ -227,29 +221,23 @@
  * of) files that are larger than the address space of the CPU.
  */
 asmlinkage unsigned long
-sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff,
-	   long arg6, long arg7, long stack)
+sys_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, long pgoff)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
-
 	addr = do_mmap2(addr, len, prot, flags, fd, pgoff);
 	if (!IS_ERR((void *) addr))
-		regs->r8 = 0;	/* ensure large addresses are not mistaken as failures... */
+		force_successful_syscall_return();
 	return addr;
 }
 
 asmlinkage unsigned long
-sys_mmap (unsigned long addr, unsigned long len, int prot, int flags,
-	  int fd, long off, long arg6, long arg7, long stack)
+sys_mmap (unsigned long addr, unsigned long len, int prot, int flags, int fd, long off)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
-
 	if ((off & ~PAGE_MASK) != 0)
 		return -EINVAL;
 
 	addr = do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
 	if (!IS_ERR((void *) addr))
-		regs->r8 = 0;	/* ensure large addresses are not mistaken as failures... */
+		force_successful_syscall_return();
 	return addr;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/time.c linux-2.4.22-pre10/arch/ia64/kernel/time.c
--- linux-2.4.21/arch/ia64/kernel/time.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/time.c	2003-08-01 13:31:51.000000000 +0000
@@ -73,10 +73,8 @@
 
 	now = ia64_get_itc();
 	if ((long) (now - last_tick) < 0) {
-# if 1
-		printk("CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n",
+		printk(KERN_ERR "CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n",
 		       smp_processor_id(), now, last_tick);
-# endif
 		return last_time_offset;
 	}
 	elapsed_cycles = now - last_tick;
@@ -154,7 +152,7 @@
 	new_itm = local_cpu_data->itm_next;
 
 	if (!time_after(ia64_get_itc(), new_itm))
-		printk("Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
+		printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
 		       ia64_get_itc(), new_itm);
 
 	while (1) {
@@ -243,21 +241,22 @@
 	 */
 	status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM, &platform_base_freq, &drift);
 	if (status != 0) {
-		printk("SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status));
+		printk(KERN_ERR "SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status));
 	} else {
 		status = ia64_pal_freq_ratios(&proc_ratio, 0, &itc_ratio);
 		if (status != 0)
-			printk("PAL_FREQ_RATIOS failed with status=%ld\n", status);
+			printk(KERN_ERR "PAL_FREQ_RATIOS failed with status=%ld\n", status);
 	}
 	if (status != 0) {
 		/* invent "random" values */
-		printk("SAL/PAL failed to obtain frequency info---inventing reasonably values\n");
+		printk(KERN_ERR
+		       "SAL/PAL failed to obtain frequency info---inventing reasonably values\n");
 		platform_base_freq = 100000000;
 		itc_ratio.num = 3;
 		itc_ratio.den = 1;
 	}
 	if (platform_base_freq < 40000000) {
-		printk("Platform base frequency %lu bogus---resetting to 75MHz!\n",
+		printk(KERN_ERR "Platform base frequency %lu bogus---resetting to 75MHz!\n",
 		       platform_base_freq);
 		platform_base_freq = 75000000;
 	}
@@ -268,8 +267,8 @@
 
 	itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den;
 	local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ;
-	printk("CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, ITC freq=%lu.%03luMHz\n",
-	       smp_processor_id(),
+	printk(KERN_INFO "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, "
+	       "ITC freq=%lu.%03luMHz\n", smp_processor_id(),
 	       platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000,
 	       itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000);
 
@@ -284,9 +283,9 @@
 }
 
 static struct irqaction timer_irqaction = {
-	handler:	timer_interrupt,
-	flags:		SA_INTERRUPT,
-	name:		"timer"
+	.handler =	timer_interrupt,
+	.flags =	SA_INTERRUPT,
+	.name =		"timer"
 };
 
 void __init
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/traps.c linux-2.4.22-pre10/arch/ia64/kernel/traps.c
--- linux-2.4.21/arch/ia64/kernel/traps.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/traps.c	2003-08-01 13:34:43.000000000 +0000
@@ -51,12 +51,12 @@
 	if (ia64_boot_param->fpswa) {
 		/* FPSWA fixup: make the interface pointer a kernel virtual address: */
 		fpswa_interface = __va(ia64_boot_param->fpswa);
-		printk("FPSWA interface at 0x%lx, revision %d.%d\n",
+		printk(KERN_INFO "FPSWA interface at 0x%lx, revision %d.%d\n",
 			ia64_boot_param->fpswa,
 			fpswa_interface->revision >> 16,
 			fpswa_interface->revision & 0xffff);
 	} else
-		printk("No FPSWA interface\n");
+		printk(KERN_INFO "No FPSWA interface\n");
 }
 
 /*
@@ -97,9 +97,9 @@
 		int lock_owner;
 		int lock_owner_depth;
 	} die = {
-		lock:			SPIN_LOCK_UNLOCKED,
-		lock_owner:		-1,
-		lock_owner_depth:	0
+		.lock =		SPIN_LOCK_UNLOCKED,
+		.lock_owner =		-1,
+		.lock_owner_depth =	0
 	};
 
 	if (die.lock_owner != smp_processor_id()) {
@@ -223,7 +223,7 @@
 {
 	struct pt_regs *regs = (struct pt_regs *) &stack;
 
-	printk("%s(%d): <sc%ld(%lx,%lx,%lx,%lx)>\n", current->comm, current->pid,
+	printk(KERN_DEBUG "%s(%d): <sc%ld(%lx,%lx,%lx,%lx)>\n", current->comm, current->pid,
 	       regs->r15, arg0, arg1, arg2, arg3);
 	return -ENOSYS;
 }
@@ -245,17 +245,17 @@
 	psr->dfh = 0;
 #ifndef CONFIG_SMP
 	{
-		struct task_struct *fpu_owner = ia64_get_fpu_owner();
+		struct task_struct *fpu_owner
+			= (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER);
 
-		if (fpu_owner == current)
+		if (ia64_is_local_fpu_owner(current))
 			return;
 
 		if (fpu_owner)
 			ia64_flush_fph(fpu_owner);
-
 	}
 #endif /* !CONFIG_SMP */
-	ia64_set_fpu_owner(current);
+	ia64_set_local_fpu_owner(current);
 	if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) {
 		__ia64_load_fpu(current->thread.fph);
 		psr->mfh = 0;
@@ -337,8 +337,8 @@
 		fpu_swa_count = 0;
 	if ((++fpu_swa_count < 5) && !(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) {
 		last_time = jiffies;
-		printk(KERN_WARNING "%s(%d): floating-point assist fault at ip %016lx\n",
-		       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri);
+		printk(KERN_WARNING "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
+		       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
 	}
 
 	exception = fp_emulate(fp_fault, bundle, &regs->cr_ipsr, &regs->ar_fpsr, &isr, &regs->pr,
@@ -348,7 +348,7 @@
 			/* emulation was successful */
 			ia64_increment_ip(regs);
 		} else if (exception == -1) {
-			printk("handle_fpu_swa: fp_emulate() returned -1\n");
+			printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
 			return -1;
 		} else {
 			/* is next instruction a trap? */
@@ -371,7 +371,7 @@
 		}
 	} else {
 		if (exception == -1) {
-			printk("handle_fpu_swa: fp_emulate() returned -1\n");
+			printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
 			return -1;
 		} else if (exception != 0) {
 			/* raise exception */
@@ -469,7 +469,9 @@
 				       ? " (RSE access)" : " (data access)") : "");
 		if (code == 8) {
 # ifdef CONFIG_IA64_PRINT_HAZARDS
-			printk("%016lx:possible hazard, pr = %016lx\n", regs->cr_iip, regs->pr);
+			printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
+			       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri,
+			       regs->pr);
 # endif
 			return;
 		}
@@ -485,19 +487,23 @@
 
 	      case 26: /* NaT Consumption */
 		if (user_mode(regs)) {
+			void *addr;
+
 			if (((isr >> 4) & 0xf) == 2) {
 				/* NaT page consumption */
 				sig = SIGSEGV;
 				code = SEGV_ACCERR;
+				addr = (void *) ifa;
 			} else {
 				/* register NaT consumption */
 				sig = SIGILL;
 				code = ILL_ILLOPN;
+				addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
 			}
 			siginfo.si_signo = sig;
 			siginfo.si_code = code;
 			siginfo.si_errno = 0;
-			siginfo.si_addr = (void *) (regs->cr_iip + ia64_psr(regs)->ri);
+			siginfo.si_addr = addr;
 			siginfo.si_imm = vector;
 			siginfo.si_flags = __ISR_VALID;
 			siginfo.si_isr = isr;
@@ -585,8 +591,9 @@
 		if (ia32_exception(regs, isr) == 0)
 			return;
 #endif
-		printk("Unexpected IA-32 exception (Trap 45)\n");
-		printk("  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n", regs->cr_iip, ifa, isr);
+		printk(KERN_ERR "Unexpected IA-32 exception (Trap 45)\n");
+		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx\n",
+		       regs->cr_iip, ifa, isr);
 		force_sig(SIGSEGV, current);
 		break;
 
@@ -595,8 +602,8 @@
 		if (ia32_intercept(regs, isr) == 0)
 			return;
 #endif
-		printk("Unexpected IA-32 intercept trap (Trap 46)\n");
-		printk("  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
+		printk(KERN_ERR "Unexpected IA-32 intercept trap (Trap 46)\n");
+		printk(KERN_ERR "  iip - 0x%lx, ifa - 0x%lx, isr - 0x%lx, iim - 0x%lx\n",
 		       regs->cr_iip, ifa, isr, iim);
 		force_sig(SIGSEGV, current);
 		return;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/unwind.c linux-2.4.22-pre10/arch/ia64/kernel/unwind.c
--- linux-2.4.21/arch/ia64/kernel/unwind.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/unwind.c	2003-08-01 13:33:23.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999-2002 Hewlett-Packard Co
+ * Copyright (C) 1999-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 /*
@@ -51,18 +51,24 @@
 #define UNW_LOG_HASH_SIZE	(UNW_LOG_CACHE_SIZE + 1)
 #define UNW_HASH_SIZE		(1 << UNW_LOG_HASH_SIZE)
 
-#define UNW_DEBUG	0
 #define UNW_STATS	0	/* WARNING: this disabled interrupts for long time-spans!! */
 
-#if UNW_DEBUG
-  static long unw_debug_level = 255;
-# define debug(level,format...)	if (unw_debug_level > level) printk(format)
-# define dprintk(format...)	printk(format)
-# define inline
-#else
-# define debug(level,format...)
-# define dprintk(format...)
-#endif
+#ifdef UNW_DEBUG
+  static unsigned int unw_debug_level = UNW_DEBUG;
+#  ifdef CONFIG_KDB
+#    include <linux/kdb.h>
+#    define UNW_DEBUG_ON(n)	(unw_debug_level >= n && !KDB_IS_RUNNING())
+#    define UNW_DPRINT(n, ...)	if (UNW_DEBUG_ON(n)) kdb_printf(__VA_ARGS__)
+#  else	/* !CONFIG_KDB */
+#    define UNW_DEBUG_ON(n)	unw_debug_level >= n
+     /* Do not code a printk level, not all debug lines end in newline */
+#    define UNW_DPRINT(n, ...)  if (UNW_DEBUG_ON(n)) printk(__VA_ARGS__)
+#  endif /* CONFIG_KDB */
+#  define inline
+#else /* !UNW_DEBUG */
+#  define UNW_DEBUG_ON(n)  0
+#  define UNW_DPRINT(n, ...)
+#endif /* UNW_DEBUG */
 
 #if UNW_STATS
 # define STAT(x...)	x
@@ -111,7 +117,7 @@
 	/* script cache: */
 	struct unw_script cache[UNW_CACHE_SIZE];
 
-# if UNW_DEBUG
+# ifdef UNW_DEBUG
 	const char *preg_name[UNW_NUM_REGS];
 # endif
 # if UNW_STATS
@@ -140,13 +146,13 @@
 	} stat;
 # endif
 } unw = {
-	tables: &unw.kernel_table,
-	lock: SPIN_LOCK_UNLOCKED,
-	save_order: {
+	.tables = &unw.kernel_table,
+	.lock = SPIN_LOCK_UNLOCKED,
+	.save_order = {
 		UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR,
 		UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR
 	},
-	preg_index: {
+	.preg_index = {
 		struct_offset(struct unw_frame_info, pri_unat_loc)/8,	/* PRI_UNAT_GR */
 		struct_offset(struct unw_frame_info, pri_unat_loc)/8,	/* PRI_UNAT_MEM */
 		struct_offset(struct unw_frame_info, bsp_loc)/8,
@@ -189,9 +195,9 @@
 		struct_offset(struct unw_frame_info, fr_loc[30 - 16])/8,
 		struct_offset(struct unw_frame_info, fr_loc[31 - 16])/8,
 	},
-	hash : { [0 ... UNW_HASH_SIZE - 1] = -1 },
-#if UNW_DEBUG
-	preg_name: {
+	.hash = { [0 ... UNW_HASH_SIZE - 1] = -1 },
+#ifdef UNW_DEBUG
+	.preg_name = {
 		"pri_unat_gr", "pri_unat_mem", "bsp", "bspstore", "ar.pfs", "ar.rnat", "psp", "rp",
 		"r4", "r5", "r6", "r7",
 		"ar.unat", "pr", "ar.lc", "ar.fpsr",
@@ -223,10 +229,25 @@
 	else if (reg <= 31)
 		off = struct_offset(struct pt_regs, r16) + 8*(reg - 16);
 	else
-		dprintk("unwind: bad scratch reg r%lu\n", reg);
+		UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __FUNCTION__, reg);
 	return off;
 }
 
+static inline struct pt_regs *
+get_scratch_regs (struct unw_frame_info *info)
+{
+	if (!info->pt) {
+		/* This should not happen with valid unwind info.  */
+		UNW_DPRINT(0, "unwind.%s: bad unwind info: resetting info->pt\n", __FUNCTION__);
+		if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
+			info->pt = (unsigned long) ((struct pt_regs *) info->psp - 1);
+		else
+			info->pt = info->sp - 16;
+	}
+	UNW_DPRINT(3, "unwind.%s: sp 0x%lx pt 0x%lx\n", __FUNCTION__, info->sp, info->pt);
+	return (struct pt_regs *) info->pt;
+}
+
 int
 unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char *nat, int write)
 {
@@ -235,7 +256,13 @@
 	struct pt_regs *pt;
 
 	if ((unsigned) regnum - 1 >= 127) {
-		dprintk("unwind: trying to access non-existent r%u\n", regnum);
+		if (regnum == 0 && !write) {
+			*val = 0;	/* read r0 always returns 0 */
+			*nat = 0;
+			return 0;
+		}
+		UNW_DPRINT(0, "unwind.%s: trying to access non-existent r%u\n",
+			   __FUNCTION__, regnum);
 		return -1;
 	}
 
@@ -280,8 +307,9 @@
 					if ((unsigned long) addr < info->regstk.limit
 					    || (unsigned long) addr >= info->regstk.top)
 					{
-						dprintk("unwind: %p outside of regstk "
-							"[0x%lx-0x%lx)\n", (void *) addr,
+						UNW_DPRINT(0, "unwind.%s: %p outside of regstk "
+							"[0x%lx-0x%lx)\n",
+							__FUNCTION__, (void *) addr,
 							info->regstk.limit,
 							info->regstk.top);
 						return -1;
@@ -298,11 +326,8 @@
 			}
 		} else {
 			/* access a scratch register */
-			if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
-				pt = (struct pt_regs *) info->psp - 1;
-			else
-				pt = (struct pt_regs *) info->sp - 1;
-			addr = (unsigned long *) ((long) pt + pt_regs_off(regnum));
+			pt = get_scratch_regs(info);
+			addr = (unsigned long *) ((unsigned long)pt + pt_regs_off(regnum));
 			if (info->pri_unat_loc)
 				nat_addr = info->pri_unat_loc;
 			else
@@ -316,7 +341,8 @@
 		if ((unsigned long) addr < info->regstk.limit
 		    || (unsigned long) addr >= info->regstk.top)
 		{
-			dprintk("unwind: ignoring attempt to access register outside of rbs\n");
+			UNW_DPRINT(0, "unwind.%s: ignoring attempt to access register outside "
+				   "of rbs\n",  __FUNCTION__);
 			return -1;
 		}
 		if ((unsigned long) nat_addr >= info->regstk.top)
@@ -348,15 +374,11 @@
 	unsigned long *addr;
 	struct pt_regs *pt;
 
-	if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
-		pt = (struct pt_regs *) info->psp - 1;
-	else
-		pt = (struct pt_regs *) info->sp - 1;
 	switch (regnum) {
 		/* scratch: */
-	      case 0: addr = &pt->b0; break;
-	      case 6: addr = &pt->b6; break;
-	      case 7: addr = &pt->b7; break;
+	      case 0: pt = get_scratch_regs(info); addr = &pt->b0; break;
+	      case 6: pt = get_scratch_regs(info); addr = &pt->b6; break;
+	      case 7: pt = get_scratch_regs(info); addr = &pt->b7; break;
 
 		/* preserved: */
 	      case 1: case 2: case 3: case 4: case 5:
@@ -366,7 +388,8 @@
 		break;
 
 	      default:
-		dprintk("unwind: trying to access non-existent b%u\n", regnum);
+		UNW_DPRINT(0, "unwind.%s: trying to access non-existent b%u\n",
+			   __FUNCTION__, regnum);
 		return -1;
 	}
 	if (write)
@@ -383,22 +406,20 @@
 	struct pt_regs *pt;
 
 	if ((unsigned) (regnum - 2) >= 126) {
-		dprintk("unwind: trying to access non-existent f%u\n", regnum);
+		UNW_DPRINT(0, "unwind.%s: trying to access non-existent f%u\n",
+			   __FUNCTION__, regnum);
 		return -1;
 	}
 
-	if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
-		pt = (struct pt_regs *) info->psp - 1;
-	else
-		pt = (struct pt_regs *) info->sp - 1;
-
 	if (regnum <= 5) {
 		addr = *(&info->f2_loc + (regnum - 2));
 		if (!addr)
 			addr = &info->sw->f2 + (regnum - 2);
 	} else if (regnum <= 15) {
-		if (regnum <= 9)
+		if (regnum <= 9) {
+			pt = get_scratch_regs(info);
 			addr = &pt->f6  + (regnum - 6);
+		}
 		else
 			addr = &info->sw->f10 + (regnum - 10);
 	} else if (regnum <= 31) {
@@ -428,11 +449,6 @@
 	unsigned long *addr;
 	struct pt_regs *pt;
 
-	if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
-		pt = (struct pt_regs *) info->psp - 1;
-	else
-		pt = (struct pt_regs *) info->sp - 1;
-
 	switch (regnum) {
 	      case UNW_AR_BSP:
 		addr = info->bsp_loc;
@@ -487,15 +503,18 @@
 		break;
 
 	      case UNW_AR_RSC:
+		pt = get_scratch_regs(info);
 		addr = &pt->ar_rsc;
 		break;
 
 	      case UNW_AR_CCV:
+		pt = get_scratch_regs(info);
 		addr = &pt->ar_ccv;
 		break;
 
 	      default:
-		dprintk("unwind: trying to access non-existent ar%u\n", regnum);
+		UNW_DPRINT(0, "unwind.%s: trying to access non-existent ar%u\n",
+			   __FUNCTION__, regnum);
 		return -1;
 	}
 
@@ -532,7 +551,7 @@
 
 	rs = alloc_reg_state();
 	if (!rs) {
-		printk("unwind: cannot stack reg state!\n");
+		printk(KERN_ERR "unwind: cannot stack reg state!\n");
 		return;
 	}
 	memcpy(rs, &sr->curr, sizeof(*rs));
@@ -545,7 +564,7 @@
 	struct unw_reg_state *rs = sr->curr.next;
 
 	if (!rs) {
-		printk("unwind: stack underflow!\n");
+		printk(KERN_ERR "unwind: stack underflow!\n");
 		return;
 	}
 	memcpy(&sr->curr, rs, sizeof(*rs));
@@ -561,7 +580,7 @@
 	while (rs) {
 		copy = alloc_reg_state();
 		if (!copy) {
-			printk ("unwind.dup_state_stack: out of memory\n");
+			printk(KERN_ERR "unwind.dup_state_stack: out of memory\n");
 			return NULL;
 		}
 		memcpy(copy, rs, sizeof(*copy));
@@ -612,7 +631,7 @@
 	      default:
 		break;
 	}
-	dprintk("unwind: bad abreg=0x%x\n", abreg);
+	UNW_DPRINT(0, "unwind.%s: bad abreg=0x%x\n", __FUNCTION__, abreg);
 	return UNW_REG_LC;
 }
 
@@ -652,7 +671,7 @@
 			return;
 		}
 	}
-	dprintk("unwind: excess spill!\n");
+	UNW_DPRINT(0, "unwind.%s: excess spill!\n",  __FUNCTION__);
 }
 
 static inline void
@@ -720,7 +739,7 @@
 desc_prologue (int body, unw_word rlen, unsigned char mask, unsigned char grsave,
 	       struct unw_state_record *sr)
 {
-	int i;
+	int i, region_start;
 
 	if (!(sr->in_body || sr->first_region))
 		finish_prologue(sr);
@@ -732,19 +751,20 @@
 		return;
 	}
 
+	region_start = sr->region_start + sr->region_len;
+
 	for (i = 0; i < sr->epilogue_count; ++i)
 		pop(sr);
 	sr->epilogue_count = 0;
 	sr->epilogue_start = UNW_WHEN_NEVER;
 
-	if (!body)
-		push(sr);
-
-	sr->region_start += sr->region_len;
+	sr->region_start = region_start;
 	sr->region_len = rlen;
 	sr->in_body = body;
 
 	if (!body) {
+		push(sr);
+
 		for (i = 0; i < 4; ++i) {
 			if (mask & 0x8)
 				set_reg(sr->curr.reg + unw.save_order[i], UNW_WHERE_GR,
@@ -765,10 +785,13 @@
 static inline void
 desc_abi (unsigned char abi, unsigned char context, struct unw_state_record *sr)
 {
-	if (abi == 0 && context == 'i')
+	if (abi == 0 && context == 'i') {
 		sr->flags |= UNW_FLAG_INTERRUPT_FRAME;
+		UNW_DPRINT(3, "unwind.%s: interrupt frame\n",  __FUNCTION__);
+	}
 	else
-		dprintk("unwind: ignoring unwabi(abi=0x%x,context=0x%x)\n", abi, context);
+		UNW_DPRINT(0, "unwind%s: ignoring unwabi(abi=0x%x,context=0x%x)\n",
+				__FUNCTION__, abi, context);
 }
 
 static inline void
@@ -951,7 +974,7 @@
 			return;
 		}
 	}
-	printk("unwind: failed to find state labeled 0x%lx\n", label);
+	printk(KERN_ERR "unwind: failed to find state labeled 0x%lx\n", label);
 }
 
 static inline void
@@ -961,7 +984,7 @@
 
 	ls = alloc_labeled_state();
 	if (!ls) {
-		printk("unwind.desc_label_state(): out of memory\n");
+		printk(KERN_ERR "unwind.desc_label_state(): out of memory\n");
 		return;
 	}
 	ls->label = label;
@@ -1055,7 +1078,8 @@
 	r->val = 4*spoff;
 }
 
-#define UNW_DEC_BAD_CODE(code)			printk("unwind: unknown code 0x%02x\n", code);
+#define UNW_DEC_BAD_CODE(code)			printk(KERN_ERR "unwind: unknown code 0x%02x\n", \
+						       code);
 
 /*
  * region headers:
@@ -1135,6 +1159,9 @@
 	unsigned short index;
 	unsigned long ip, pr;
 
+	if (UNW_DEBUG_ON(0))
+		return 0;	/* Always regenerate scripts in debug mode */
+
 	STAT(++unw.stat.cache.lookups);
 
 	ip = info->ip;
@@ -1259,8 +1286,8 @@
 script_emit (struct unw_script *script, struct unw_insn insn)
 {
 	if (script->count >= UNW_MAX_SCRIPT_LEN) {
-		dprintk("unwind: script exceeds maximum size of %u instructions!\n",
-			UNW_MAX_SCRIPT_LEN);
+		UNW_DPRINT(0, "unwind.%s: script exceeds maximum size of %u instructions!\n",
+			__FUNCTION__, UNW_MAX_SCRIPT_LEN);
 		return;
 	}
 	script->insn[script->count++] = insn;
@@ -1301,7 +1328,8 @@
 		break;
 
 	      default:
-		dprintk("unwind: don't know how to emit nat info for where = %u\n", r->where);
+		UNW_DPRINT(0, "unwind.%s: don't know how to emit nat info for where = %u\n",
+			   __FUNCTION__, r->where);
 		return;
 	}
 	insn.opc = opc;
@@ -1338,8 +1366,9 @@
 			}
 			val = unw.preg_index[UNW_REG_R4 + (rval - 4)];
 		} else {
-			opc = UNW_INSN_ADD_SP;
-			val = -sizeof(struct pt_regs) + pt_regs_off(rval);
+			/* register got spilled to a scratch register */
+			opc = UNW_INSN_MOVE_SCRATCH;
+			val = pt_regs_off(rval);
 		}
 		break;
 
@@ -1349,12 +1378,12 @@
 		else if (rval >= 16 && rval <= 31)
 			val = unw.preg_index[UNW_REG_F16 + (rval - 16)];
 		else {
-			opc = UNW_INSN_ADD_SP;
-			val = -sizeof(struct pt_regs);
+			opc = UNW_INSN_MOVE_SCRATCH;
 			if (rval <= 9)
-				val += struct_offset(struct pt_regs, f6) + 16*(rval - 6);
+				val = struct_offset(struct pt_regs, f6) + 16*(rval - 6);
 			else
-				dprintk("unwind: kernel may not touch f%lu\n", rval);
+				UNW_DPRINT(0, "unwind.%s: kernel may not touch f%lu\n",
+					   __FUNCTION__, rval);
 		}
 		break;
 
@@ -1362,14 +1391,13 @@
 		if (rval >= 1 && rval <= 5)
 			val = unw.preg_index[UNW_REG_B1 + (rval - 1)];
 		else {
-			opc = UNW_INSN_ADD_SP;
-			val = -sizeof(struct pt_regs);
+			opc = UNW_INSN_MOVE_SCRATCH;
 			if (rval == 0)
-				val += struct_offset(struct pt_regs, b0);
+				val = struct_offset(struct pt_regs, b0);
 			else if (rval == 6)
-				val += struct_offset(struct pt_regs, b6);
+				val = struct_offset(struct pt_regs, b6);
 			else
-				val += struct_offset(struct pt_regs, b7);
+				val = struct_offset(struct pt_regs, b7);
 		}
 		break;
 
@@ -1382,7 +1410,8 @@
 		break;
 
 	      default:
-		dprintk("unwind: register %u has unexpected `where' value of %u\n", i, r->where);
+		UNW_DPRINT(0, "unwind%s: register %u has unexpected `where' value of %u\n",
+			   __FUNCTION__, i, r->where);
 		break;
 	}
 	insn.opc = opc;
@@ -1455,9 +1484,10 @@
 		r->when = UNW_WHEN_NEVER;
 	sr.pr_val = info->pr;
 
+	UNW_DPRINT(3, "unwind.%s: ip 0x%lx\n", __FUNCTION__, ip);
 	script = script_new(ip);
 	if (!script) {
-		dprintk("unwind: failed to create unwind script\n");
+		UNW_DPRINT(0, "unwind.%s: failed to create unwind script\n",  __FUNCTION__);
 		STAT(unw.stat.script.build_time += ia64_get_itc() - start);
 		return 0;
 	}
@@ -1475,8 +1505,8 @@
 	}
 	if (!e) {
 		/* no info, return default unwinder (leaf proc, no mem stack, no saved regs)  */
-		dprintk("unwind: no unwind info for ip=0x%lx (prev ip=0x%lx)\n", ip,
-			unw.cache[info->prev_script].ip);
+		UNW_DPRINT(1, "unwind.%s: no unwind info for ip=0x%lx (prev ip=0x%lx)\n",
+			__FUNCTION__, ip, unw.cache[info->prev_script].ip);
 		sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
 		sr.curr.reg[UNW_REG_RP].when = -1;
 		sr.curr.reg[UNW_REG_RP].val = 0;
@@ -1524,26 +1554,32 @@
 		sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
 		sr.curr.reg[UNW_REG_RP].when = -1;
 		sr.curr.reg[UNW_REG_RP].val = sr.return_link_reg;
+		UNW_DPRINT(1, "unwind.%s: using default for rp at ip=0x%lx where=%d val=0x%lx\n",
+			   __FUNCTION__, ip, sr.curr.reg[UNW_REG_RP].where,
+			   sr.curr.reg[UNW_REG_RP].val);
 	}
 
-#if UNW_DEBUG
-	printk("unwind: state record for func 0x%lx, t=%u:\n",
-	       table->segment_base + e->start_offset, sr.when_target);
+#ifdef UNW_DEBUG
+	UNW_DPRINT(1, "unwind.%s: state record for func 0x%lx, t=%u:\n",
+		__FUNCTION__, table->segment_base + e->start_offset, sr.when_target);
 	for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r) {
 		if (r->where != UNW_WHERE_NONE || r->when != UNW_WHEN_NEVER) {
-			printk("  %s <- ", unw.preg_name[r - sr.curr.reg]);
+			UNW_DPRINT(1, "  %s <- ", unw.preg_name[r - sr.curr.reg]);
 			switch (r->where) {
-			      case UNW_WHERE_GR:     printk("r%lu", r->val); break;
-			      case UNW_WHERE_FR:     printk("f%lu", r->val); break;
-			      case UNW_WHERE_BR:     printk("b%lu", r->val); break;
-			      case UNW_WHERE_SPREL:  printk("[sp+0x%lx]", r->val); break;
-			      case UNW_WHERE_PSPREL: printk("[psp+0x%lx]", r->val); break;
+			      case UNW_WHERE_GR:     UNW_DPRINT(1, "r%lu", r->val); break;
+			      case UNW_WHERE_FR:     UNW_DPRINT(1, "f%lu", r->val); break;
+			      case UNW_WHERE_BR:     UNW_DPRINT(1, "b%lu", r->val); break;
+			      case UNW_WHERE_SPREL:  UNW_DPRINT(1, "[sp+0x%lx]", r->val); break;
+			      case UNW_WHERE_PSPREL: UNW_DPRINT(1, "[psp+0x%lx]", r->val); break;
 			      case UNW_WHERE_NONE:
-				printk("%s+0x%lx", unw.preg_name[r - sr.curr.reg], r->val);
+				UNW_DPRINT(1, "%s+0x%lx", unw.preg_name[r - sr.curr.reg], r->val);
+				break;
+
+			      default:
+				UNW_DPRINT(1, "BADWHERE(%d)", r->where);
 				break;
-			      default:		     printk("BADWHERE(%d)", r->where); break;
 			}
-			printk("\t\t%d\n", r->when);
+			UNW_DPRINT(1, "\t\t%d\n", r->when);
 		}
 	}
 #endif
@@ -1641,6 +1677,16 @@
 			s[dst] = s[val];
 			break;
 
+		      case UNW_INSN_MOVE_SCRATCH:
+			if (state->pt) {
+				s[dst] = (unsigned long) get_scratch_regs(state) + val;
+			} else {
+				s[dst] = 0;
+				UNW_DPRINT(0, "unwind.%s: no state->pt, dst=%ld, val=%ld\n",
+					   __FUNCTION__, dst, val);
+			}
+			break;
+
 		      case UNW_INSN_MOVE_STACKED:
 			s[dst] = (unsigned long) ia64_rse_skip_regs((unsigned long *)state->bsp,
 								    val);
@@ -1666,11 +1712,12 @@
 			break;
 
 		      case UNW_INSN_LOAD:
-#if UNW_DEBUG
+#ifdef UNW_DEBUG
 			if ((s[val] & (local_cpu_data->unimpl_va_mask | 0x7)) != 0
 			    || s[val] < TASK_SIZE)
 			{
-				debug(1, "unwind: rejecting bad psp=0x%lx\n", s[val]);
+				UNW_DPRINT(0, "unwind.%s: rejecting bad psp=0x%lx\n",
+					   __FUNCTION__, s[val]);
 				break;
 			}
 #endif
@@ -1703,7 +1750,8 @@
 
 	if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf)) || info->ip < TASK_SIZE) {
 		/* don't let obviously bad addresses pollute the cache */
-		debug(1, "unwind: rejecting bad ip=0x%lx\n", info->ip);
+		/* FIXME: should really be level 0 but it occurs too often. KAO */
+		UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n", __FUNCTION__, info->ip);
 		info->rp_loc = 0;
 		return -1;
 	}
@@ -1712,8 +1760,9 @@
 	if (!scr) {
 		scr = build_script(info);
 		if (!scr) {
-			dprintk("unwind: failed to locate/build unwind script for ip %lx\n",
-				info->ip);
+			UNW_DPRINT(0,
+				   "unwind.%s: failed to locate/build unwind script for ip %lx\n",
+				   __FUNCTION__, info->ip);
 			return -1;
 		}
 		have_write_lock = 1;
@@ -1746,7 +1795,9 @@
 
 	/* restore the ip */
 	if (!info->rp_loc) {
-		debug(1, "unwind: failed to locate return link (ip=0x%lx)!\n", info->ip);
+		/* FIXME: should really be level 0 but it occurs too often. KAO */
+		UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n",
+			   __FUNCTION__, info->ip);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
 	}
@@ -1756,14 +1807,14 @@
 		 * We don't have unwind info for the gate page, so we consider that part
 		 * of user-space for the purpose of unwinding.
 		 */
-		debug(1, "unwind: reached user-space (ip=0x%lx)\n", ip);
+		UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __FUNCTION__, ip);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
 	}
 
 	/* restore the cfm: */
 	if (!info->pfs_loc) {
-		dprintk("unwind: failed to locate ar.pfs!\n");
+		UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
 	}
@@ -1773,16 +1824,18 @@
 	pr = info->pr;
 	num_regs = 0;
 	if ((info->flags & UNW_FLAG_INTERRUPT_FRAME)) {
+		info->pt = info->sp + 16;
 		if ((pr & (1UL << pNonSys)) != 0)
 			num_regs = *info->cfm_loc & 0x7f;		/* size of frame */
 		info->pfs_loc =
-			(unsigned long *) (info->sp + 16 + struct_offset(struct pt_regs, ar_pfs));
+			(unsigned long *) (info->pt + struct_offset(struct pt_regs, ar_pfs));
+		UNW_DPRINT(3, "unwind.%s: interrupt_frame pt 0x%lx\n", __FUNCTION__, info->pt);
 	} else
 		num_regs = (*info->cfm_loc >> 7) & 0x7f;	/* size of locals */
 	info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->bsp, -num_regs);
 	if (info->bsp < info->regstk.limit || info->bsp > info->regstk.top) {
-		dprintk("unwind: bsp (0x%lx) out of range [0x%lx-0x%lx]\n",
-			info->bsp, info->regstk.limit, info->regstk.top);
+		UNW_DPRINT(0, "unwind.%s: bsp (0x%lx) out of range [0x%lx-0x%lx]\n",
+			__FUNCTION__, info->bsp, info->regstk.limit, info->regstk.top);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
 	}
@@ -1790,14 +1843,15 @@
 	/* restore the sp: */
 	info->sp = info->psp;
 	if (info->sp < info->memstk.top || info->sp > info->memstk.limit) {
-		dprintk("unwind: sp (0x%lx) out of range [0x%lx-0x%lx]\n",
-			info->sp, info->memstk.top, info->memstk.limit);
+		UNW_DPRINT(0, "unwind.%s: sp (0x%lx) out of range [0x%lx-0x%lx]\n",
+			__FUNCTION__, info->sp, info->memstk.top, info->memstk.limit);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
 	}
 
 	if (info->ip == prev_ip && info->sp == prev_sp && info->bsp == prev_bsp) {
-		dprintk("unwind: ip, sp, bsp remain unchanged; stopping here (ip=0x%lx)\n", ip);
+		UNW_DPRINT(0, "unwind.%s: ip, sp, bsp unchanged; stopping here (ip=0x%lx)\n",
+			   __FUNCTION__, ip);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
 	}
@@ -1821,7 +1875,8 @@
 	while (unw_unwind(info) >= 0) {
 		if (unw_get_rp(info, &ip) < 0) {
 			unw_get_ip(info, &ip);
-			dprintk("unwind: failed to read return pointer (ip=0x%lx)\n", ip);
+			UNW_DPRINT(0, "unwind.%s: failed to read return pointer (ip=0x%lx)\n",
+				   __FUNCTION__, ip);
 			return -1;
 		}
 		/*
@@ -1832,26 +1887,25 @@
 			return 0;
 	}
 	unw_get_ip(info, &ip);
-	dprintk("unwind: failed to unwind to user-level (ip=0x%lx)\n", ip);
+	UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n", __FUNCTION__, ip);
 	return -1;
 }
 
-void
-unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct switch_stack *sw)
+static void
+init_frame_info (struct unw_frame_info *info, struct task_struct *t,
+		 struct switch_stack *sw, unsigned long stktop)
 {
-	unsigned long rbslimit, rbstop, stklimit, stktop, sol;
+	unsigned long rbslimit, rbstop, stklimit;
 	STAT(unsigned long start, flags;)
 
 	STAT(local_irq_save(flags); ++unw.stat.api.inits; start = ia64_get_itc());
 
 	/*
-	 * Subtle stuff here: we _could_ unwind through the
-	 * switch_stack frame but we don't want to do that because it
-	 * would be slow as each preserved register would have to be
-	 * processed.  Instead, what we do here is zero out the frame
-	 * info and start the unwind process at the function that
-	 * created the switch_stack frame.  When a preserved value in
-	 * switch_stack needs to be accessed, run_script() will
+	 * Subtle stuff here: we _could_ unwind through the switch_stack frame but we
+	 * don't want to do that because it would be slow as each preserved register would
+	 * have to be processed.  Instead, what we do here is zero out the frame info and
+	 * start the unwind process at the function that created the switch_stack frame.
+	 * When a preserved value in switch_stack needs to be accessed, run_script() will
 	 * initialize the appropriate pointer on demand.
 	 */
 	memset(info, 0, sizeof(*info));
@@ -1862,7 +1916,6 @@
 		rbstop = rbslimit;
 
 	stklimit = (unsigned long) t + IA64_STK_OFFSET;
-	stktop   = (unsigned long) sw - 16;
 	if (stktop <= rbstop)
 		stktop = rbstop;
 
@@ -1872,15 +1925,56 @@
 	info->memstk.top   = stktop;
 	info->task = t;
 	info->sw  = sw;
-	info->sp = info->psp = (unsigned long) (sw + 1) - 16;
+	info->sp = info->psp = stktop;
+	info->pr = sw->pr;
+	UNW_DPRINT(3, "unwind.%s:\n"
+		   "  task   0x%lx\n"
+		   "  rbs = [0x%lx-0x%lx)\n"
+		   "  stk = [0x%lx-0x%lx)\n"
+		   "  pr     0x%lx\n"
+		   "  sw     0x%lx\n"
+		   "  sp     0x%lx\n",
+		   __FUNCTION__, (unsigned long) task, rbslimit, rbstop, stktop, stklimit,
+		   info->pr, (unsigned long) info->sw, info->sp);
+	STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags));
+}
+
+void
+unw_init_from_interruption (struct unw_frame_info *info, struct task_struct *t,
+			    struct pt_regs *pt, struct switch_stack *sw)
+{
+	unsigned long sof;
+
+	init_frame_info(info, t, sw, pt->r12);
+	info->cfm_loc = &pt->cr_ifs;
+	sof = *info->cfm_loc & 0x7f;
+	info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->regstk.top, -sof);
+	info->ip = pt->cr_iip + ia64_psr(pt)->ri;
+	info->pt = (unsigned long) pt;
+	UNW_DPRINT(3, "unwind.%s:\n"
+		   "  bsp    0x%lx\n"
+		   "  sof    0x%lx\n"
+		   "  ip     0x%lx\n",
+		   info->bsp, sof, info->ip);
+	find_save_locs(info);
+}
+
+void
+unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct switch_stack *sw)
+{
+	unsigned long sol;
+
+	init_frame_info(info, t, sw, (unsigned long) (sw + 1) - 16);
 	info->cfm_loc = &sw->ar_pfs;
 	sol = (*info->cfm_loc >> 7) & 0x7f;
 	info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->regstk.top, -sol);
 	info->ip = sw->b0;
-	info->pr = sw->pr;
-
+	UNW_DPRINT(3, "unwind.%s:\n"
+		   "  bsp    0x%lx\n"
+		   "  sol    0x%lx\n"
+		   "  ip     0x%lx\n",
+		   info->bsp, sol, info->ip);
 	find_save_locs(info);
-	STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags));
 }
 
 void
@@ -1888,6 +1982,7 @@
 {
 	struct switch_stack *sw = (struct switch_stack *) (t->thread.ksp + 16);
 
+	UNW_DPRINT(1, "unwind.%s\n", __FUNCTION__);
 	unw_init_frame_info(info, t, sw);
 }
 
@@ -1915,7 +2010,8 @@
 	unsigned long flags;
 
 	if (end - start <= 0) {
-		dprintk("unwind: ignoring attempt to insert empty unwind table\n");
+		UNW_DPRINT(0, "unwind.%s: ignoring attempt to insert empty unwind table\n",
+			   __FUNCTION__);
 		return 0;
 	}
 
@@ -1945,13 +2041,15 @@
 	long index;
 
 	if (!handle) {
-		dprintk("unwind: ignoring attempt to remove non-existent unwind table\n");
+		UNW_DPRINT(0, "unwind.%s: ignoring attempt to remove non-existent unwind table\n",
+			   __FUNCTION__);
 		return;
 	}
 
 	table = handle;
 	if (table == &unw.kernel_table) {
-		dprintk("unwind: sorry, freeing the kernel's unwind table is a no-can-do!\n");
+		UNW_DPRINT(0, "unwind.%s: sorry, freeing the kernel's unwind table is a "
+			   "no-can-do!\n", __FUNCTION__);
 		return;
 	}
 
@@ -1963,7 +2061,8 @@
 			if (prev->next == table)
 				break;
 		if (!prev) {
-			dprintk("unwind: failed to find unwind table %p\n", (void *) table);
+			UNW_DPRINT(0, "unwind.%s: failed to find unwind table %p\n",
+				   __FUNCTION__, (void *) table);
 			spin_unlock_irqrestore(&unw.lock, flags);
 			return;
 		}
@@ -2015,7 +2114,7 @@
 	unw.gate_table = alloc_bootmem(size);
 	if (!unw.gate_table) {
 		unw.gate_table_size = 0;
-		printk("unwind: unable to create unwind data for gate page!\n");
+		printk(KERN_ERR "unwind: unable to create unwind data for gate page!\n");
 		return;
 	}
 	unw.gate_table_size = size;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/kernel/unwind_i.h linux-2.4.22-pre10/arch/ia64/kernel/unwind_i.h
--- linux-2.4.21/arch/ia64/kernel/unwind_i.h	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/kernel/unwind_i.h	2003-08-01 13:33:01.000000000 +0000
@@ -137,7 +137,8 @@
 	UNW_INSN_SETNAT_MEMSTK,		/* s[dst+1].nat.type = MEMSTK;
 					   s[dst+1].nat.off = *s.pri_unat - s[dst] */
 	UNW_INSN_SETNAT_TYPE,		/* s[dst+1].nat.type = val */
-	UNW_INSN_LOAD			/* s[dst] = *s[val] */
+	UNW_INSN_LOAD,			/* s[dst] = *s[val] */
+	UNW_INSN_MOVE_SCRATCH,		/* s[dst] = scratch reg "val" */
 };
 
 struct unw_insn {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/lib/memcpy_mck.S linux-2.4.22-pre10/arch/ia64/lib/memcpy_mck.S
--- linux-2.4.21/arch/ia64/lib/memcpy_mck.S	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/lib/memcpy_mck.S	2003-08-01 13:32:06.000000000 +0000
@@ -163,7 +163,7 @@
 	mov	ar.ec=2
 (p10)	br.dpnt.few .aligned_src_tail
 	;;
-	.align 32
+//	.align 32
 1:
 EX(.ex_handler, (p16)	ld8	r34=[src0],16)
 EK(.ex_handler, (p16)	ld8	r38=[src1],16)
@@ -320,7 +320,7 @@
 (p7)	mov	ar.lc = r21
 (p8)	mov	ar.lc = r0
 	;;
-	.align 32
+//	.align 32
 1:	lfetch	  [src_pre_mem], 128
 	lfetch.excl [dst_pre_mem], 128
 	br.cloop.dptk.few 1b
@@ -526,7 +526,7 @@
 		 shrp	r21=r22,r38,shift;	/* speculative work */			\
 		 br.sptk.few .unaligned_src_tail /* branch out of jump table */		\
 		 ;;
-	.align 32
+//	.align 32
 .jump_table:
 	COPYU(8)	// unaligned cases
 .jmp1:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/lib/memset.S linux-2.4.22-pre10/arch/ia64/lib/memset.S
--- linux-2.4.21/arch/ia64/lib/memset.S	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/lib/memset.S	2003-08-01 13:33:16.000000000 +0000
@@ -125,7 +125,7 @@
 (p_zr)	br.cond.dptk.many .l1b			// Jump to use stf.spill
 ;; }
 
-	.align 32 // -------------------------- //  L1A: store ahead into cache lines; fill later
+//	.align 32 // -------------------------- //  L1A: store ahead into cache lines; fill later
 { .mmi
 	and	tmp = -(LINE_SIZE), cnt		// compute end of range
 	mov	ptr9 = ptr1			// used for prefetching
@@ -194,7 +194,7 @@
 	br.cond.dpnt.many  .move_bytes_from_alignment	// Branch no. 3
 ;; }
 
-	.align 32
+//	.align 32
 .l1b:	// ------------------------------------ //  L1B: store ahead into cache lines; fill later
 { .mmi
 	and	tmp = -(LINE_SIZE), cnt		// compute end of range
@@ -261,7 +261,7 @@
 	and	cnt = 0x1f, cnt			// compute the remaining cnt
 	mov.i   ar.lc = loopcnt
 ;; }
-	.align 32
+//	.align 32
 .l2:	// ------------------------------------ //  L2A:  store 32B in 2 cycles
 { .mmb
 	stf8	[ptr1] = fvalue, 8
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/lib/swiotlb.c linux-2.4.22-pre10/arch/ia64/lib/swiotlb.c
--- linux-2.4.21/arch/ia64/lib/swiotlb.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/lib/swiotlb.c	2003-08-01 13:34:05.000000000 +0000
@@ -116,7 +116,7 @@
 	io_tlb_index = 0;
 	io_tlb_orig_addr = alloc_bootmem(io_tlb_nslabs * sizeof(char *));
 
-	printk("Placing software IO TLB between 0x%p - 0x%p\n",
+	printk(KERN_INFO "Placing software IO TLB between 0x%p - 0x%p\n",
 	       (void *) io_tlb_start, (void *) io_tlb_end);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/mm/extable.c linux-2.4.22-pre10/arch/ia64/mm/extable.c
--- linux-2.4.21/arch/ia64/mm/extable.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/mm/extable.c	2003-08-01 13:32:04.000000000 +0000
@@ -38,6 +38,8 @@
 register unsigned long main_gp __asm__("gp");
 #endif
 
+extern spinlock_t modlist_lock;
+
 struct exception_fixup
 search_exception_table (unsigned long addr)
 {
@@ -52,9 +54,11 @@
 	return fix;
 #else
 	struct archdata *archdata;
+	unsigned long flags;
 	struct module *mp;
 
 	/* The kernel is the last "module" -- no need to treat it special. */
+	spin_lock_irqsave(&modlist_lock, flags);
 	for (mp = module_list; mp; mp = mp->next) {
 		if (!mp->ex_table_start)
 			continue;
@@ -65,9 +69,10 @@
 					 addr, (unsigned long) archdata->gp);
 		if (entry) {
 			fix.cont = entry->cont + (unsigned long) archdata->gp;
-			return fix;
+			break;
 		}
 	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
 #endif
 	return fix;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/mm/fault.c linux-2.4.22-pre10/arch/ia64/mm/fault.c
--- linux-2.4.21/arch/ia64/mm/fault.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/mm/fault.c	2003-08-01 13:34:45.000000000 +0000
@@ -43,6 +43,33 @@
 	return 0;
 }
 
+/*
+ * Return TRUE if ADDRESS points at a page in the kernel's mapped segment
+ * (inside region 5, on ia64) and that page is present.
+ */
+static int
+mapped_kernel_page_is_present (unsigned long address)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *ptep, pte;
+
+	pgd = pgd_offset_k(address);
+	if (pgd_none(*pgd) || pgd_bad(*pgd))
+		return 0;
+
+	pmd = pmd_offset(pgd,address);
+	if (pmd_none(*pmd) || pmd_bad(*pmd))
+		return 0;
+
+	ptep = pte_offset(pmd, address);
+	if (!ptep)
+		return 0;
+
+	pte = *ptep;
+	return pte_present(pte);
+}
+
 void
 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
 {
@@ -183,6 +210,16 @@
 		return;
 
 	/*
+	 * Since we have no vma's for region 5, we might get here even if the address is
+	 * valid, due to the VHPT walker inserting a non present translation that becomes
+	 * stale. If that happens, the non present fault handler already purged the stale
+	 * translation, which fixed the problem. So, we check to see if the translation is
+	 * valid, and return if it is.
+	 */
+	if (REGION_NUMBER(address) == 5 && mapped_kernel_page_is_present(address))
+		return;
+
+	/*
 	 * Oops. The kernel tried to access some bad page. We'll have to terminate things
 	 * with extreme prejudice.
 	 */
@@ -204,7 +241,7 @@
 		goto survive;
 	}
 	up_read(&mm->mmap_sem);
-	printk("VM: killing process %s\n", current->comm);
+	printk(KERN_CRIT "VM: killing process %s\n", current->comm);
 	if (user_mode(regs))
 		do_exit(SIGKILL);
 	goto no_context;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/mm/init.c linux-2.4.22-pre10/arch/ia64/mm/init.c
--- linux-2.4.21/arch/ia64/mm/init.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/mm/init.c	2003-08-01 13:33:00.000000000 +0000
@@ -255,7 +255,7 @@
 	pte_t *pte;
 
 	if (!PageReserved(page))
-		printk("put_gate_page: gate page at 0x%p not in reserved memory\n",
+		printk(KERN_ERR "put_gate_page: gate page at 0x%p not in reserved memory\n",
 		       page_address(page));
 
 	pgd = pgd_offset_k(address);		/* note: this is NOT pgd_offset()! */
@@ -560,7 +560,7 @@
 		efi_memmap_walk(create_mem_map_page_table, 0);
 
 		free_area_init_node(0, NULL, vmem_map, zones_size, 0, zholes_size);
-		printk("Virtual mem_map starts at 0x%p\n", mem_map);
+		printk(KERN_INFO "Virtual mem_map starts at 0x%p\n", mem_map);
 	}
 #endif
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/mm/tlb.c linux-2.4.22-pre10/arch/ia64/mm/tlb.c
--- linux-2.4.21/arch/ia64/mm/tlb.c	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/mm/tlb.c	2003-08-01 13:34:02.000000000 +0000
@@ -34,10 +34,10 @@
 		1 << _PAGE_SIZE_4K )
 
 struct ia64_ctx ia64_ctx = {
-	lock:	SPIN_LOCK_UNLOCKED,
-	next:	1,
-	limit:	(1 << 15) - 1,		/* start out with the safe (architected) limit */
-	max_ctx: ~0U
+	.lock =	SPIN_LOCK_UNLOCKED,
+	.next =	1,
+	.limit =(1 << 15) - 1,		/* start out with the safe (architected) limit */
+	.max_ctx = ~0U
 };
 
 /*
@@ -48,6 +48,7 @@
 {
 	unsigned long tsk_context, max_ctx = ia64_ctx.max_ctx;
 	struct task_struct *tsk;
+	int i;
 
 	if (ia64_ctx.next > max_ctx)
 		ia64_ctx.next = 300;	/* skip daemons */
@@ -76,7 +77,14 @@
 			ia64_ctx.limit = tsk_context;
 	}
 	read_unlock(&tasklist_lock);
-	flush_tlb_all();
+	/*
+	 * Can't call flush_tlb_all() here because of race condition with scheduler [EF]
+	 * and because interrupts are disabled during context switch.
+	 */
+	for (i = 0; i < NR_CPUS; ++i)
+		if (i != smp_processor_id())
+			cpu_data(i)->need_tlb_flush = 1;
+	local_flush_tlb_all();
 }
 
 void
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/scripts/unwcheck.sh linux-2.4.22-pre10/arch/ia64/scripts/unwcheck.sh
--- linux-2.4.21/arch/ia64/scripts/unwcheck.sh	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/scripts/unwcheck.sh	2003-08-01 13:30:46.000000000 +0000
@@ -0,0 +1,109 @@
+#!/bin/sh
+#   Usage: unwcheck.sh <executable_file_name>
+#   Pre-requisite: readelf [from Gnu binutils package]
+#   Purpose: Check the following invariant
+#       For each code range in the input binary:
+#          Sum[ lengths of unwind regions] = Number of slots in code range.
+#   Author : Harish Patil
+#   First version: January 2002
+#   Modified : 2/13/2002
+#   Modified : 3/15/2002: duplicate detection
+readelf -u $1 | gawk '\
+ function todec(hexstr){
+    dec = 0;
+    l = length(hexstr);
+    for (i = 1; i <= l; i++)
+    {
+        c = substr(hexstr, i, 1);
+        if (c == "A")
+            dec = dec*16 + 10;
+        else if (c == "B")
+            dec = dec*16 + 11;
+        else if (c == "C")
+            dec = dec*16 + 12;
+        else if (c == "D")
+            dec = dec*16 + 13;
+        else if (c == "E")
+            dec = dec*16 + 14;
+        else if (c == "F")
+            dec = dec*16 + 15;
+        else
+            dec = dec*16 + c;
+    }
+    return dec;
+ }
+ BEGIN { first = 1; sum_rlen = 0; no_slots = 0; errors=0; no_code_ranges=0; }
+ {
+   if (NF==5 && $3=="info")
+   {
+      no_code_ranges += 1;
+      if (first == 0)
+      {
+         if (sum_rlen != no_slots)
+         {
+            print full_code_range;
+            print "       ", "lo = ", lo, " hi =", hi;
+            print "       ", "sum_rlen = ", sum_rlen, "no_slots = " no_slots;
+            print "       ","   ", "*******ERROR ***********";
+            print "       ","   ", "sum_rlen:", sum_rlen, " != no_slots:" no_slots;
+            errors += 1;
+         }
+         sum_rlen = 0;
+      }
+      full_code_range =  $0;
+      code_range =  $2;
+      gsub("..$", "", code_range);
+      gsub("^.", "", code_range);
+      split(code_range, addr, "-");
+      lo = toupper(addr[1]);
+
+      code_range_lo[no_code_ranges] = addr[1];
+      occurs[addr[1]] += 1;
+      full_range[addr[1]] = $0;
+
+      gsub("0X.[0]*", "", lo);
+      hi = toupper(addr[2]);
+      gsub("0X.[0]*", "", hi);
+      no_slots = (todec(hi) - todec(lo))/ 16*3
+      first = 0;
+   }
+   if (index($0,"rlen") > 0 )
+   {
+    rlen_str =  substr($0, index($0,"rlen"));
+    rlen = rlen_str;
+    gsub("rlen=", "", rlen);
+    gsub(")", "", rlen);
+    sum_rlen = sum_rlen +  rlen;
+   }
+  }
+  END {
+      if (first == 0)
+      {
+         if (sum_rlen != no_slots)
+         {
+            print "code_range=", code_range;
+            print "       ", "lo = ", lo, " hi =", hi;
+            print "       ", "sum_rlen = ", sum_rlen, "no_slots = " no_slots;
+            print "       ","   ", "*******ERROR ***********";
+            print "       ","   ", "sum_rlen:", sum_rlen, " != no_slots:" no_slots;
+            errors += 1;
+         }
+      }
+    no_duplicates = 0;
+    for (i=1; i<=no_code_ranges; i++)
+    {
+        cr = code_range_lo[i];
+        if (reported_cr[cr]==1) continue;
+        if ( occurs[cr] > 1)
+        {
+            reported_cr[cr] = 1;
+            print "Code range low ", code_range_lo[i], ":", full_range[cr], " occurs: ", occurs[cr], " times.";
+            print " ";
+            no_duplicates++;
+        }
+    }
+    print "======================================"
+    print "Total errors:", errors, "/", no_code_ranges, " duplicates:", no_duplicates;
+    print "======================================"
+  }
+  '
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/fakeprom/Makefile linux-2.4.22-pre10/arch/ia64/sn/fakeprom/Makefile
--- linux-2.4.21/arch/ia64/sn/fakeprom/Makefile	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/fakeprom/Makefile	2003-08-01 13:34:28.000000000 +0000
@@ -3,7 +3,7 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-#  Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+#  Copyright (c) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
 #
 
 TOPDIR=../../../..
@@ -13,14 +13,15 @@
 
 OBJ=fpromasm.o main.o  fw-emu.o fpmem.o klgraph_init.o
 obj-y=fprom
+EXTRA_CFLAGS += -DSGI_SN2
+EXTRA_AFLAGS += -DSGI_SN2
+AFLAGS += -DSGI_SN2
 
 fprom: $(OBJ)
 	$(LD) -static -Tfprom.lds -o fprom $(OBJ) $(LIB)
 
 .S.o:
-	$(CC)  -D__ASSEMBLY__ $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
-.c.o:
-	$(CC)  $(CFLAGS) $(CFLAGS_KERNEL) -c -o $*.o $<
+	$(CC)  -D__ASSEMBLY__ $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
 
 clean:
 	rm -f *.o fprom
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/fakeprom/README linux-2.4.22-pre10/arch/ia64/sn/fakeprom/README
--- linux-2.4.21/arch/ia64/sn/fakeprom/README	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/fakeprom/README	2003-08-01 13:35:01.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/fakeprom/fpmem.c linux-2.4.22-pre10/arch/ia64/sn/fakeprom/fpmem.c
--- linux-2.4.21/arch/ia64/sn/fakeprom/fpmem.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/fakeprom/fpmem.c	2003-08-01 13:32:46.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
@@ -13,7 +13,7 @@
  * FPROM EFI memory descriptor build routines
  *
  * 	- Routines to build the EFI memory descriptor map
- * 	- Should also be usable by the SGI SN1 prom to convert
+ * 	- Should also be usable by the SGI prom to convert
  * 	  klconfig to efi_memmap
  */
 
@@ -53,10 +53,7 @@
 #define KERNEL_SIZE		(4*MB)
 #define PROMRESERVED_SIZE	(1*MB)
 
-#ifdef CONFIG_IA64_SGI_SN1
-#define PHYS_ADDRESS(_n, _x)		(((long)_n<<33) | (long)_x)
-#define MD_BANK_SHFT 30
-#else
+#ifdef SGI_SN2
 #define PHYS_ADDRESS(_n, _x)		(((long)_n<<38) | (long)_x | 0x3000000000UL)
 #define MD_BANK_SHFT 34
 #endif
@@ -77,7 +74,7 @@
 	return sn_config->cpus;
 }
 
-/* For SN1, get the index th nasid */
+/* For SN, get the index th nasid */
 
 int
 GetNasid(int index)
@@ -104,40 +101,7 @@
  * actually disabled etc.
  */
 
-#ifdef CONFIG_IA64_SGI_SN1
-int
-IsBankPresent(int index, node_memmap_t nmemmap)
-{
-	switch (index) {
-		case 0:return nmemmap.b0;
-		case 1:return nmemmap.b1;
-		case 2:return nmemmap.b2;
-		case 3:return nmemmap.b3;
-		case 4:return nmemmap.b4;
-		case 5:return nmemmap.b5;
-		case 6:return nmemmap.b6;
-		case 7:return nmemmap.b7;
-		default:return -1 ;
-	}
-}
-
-int
-GetBankSize(int index, node_memmap_t nmemmap)
-{
-        switch (index) {
-                case 0:
-                case 1:return nmemmap.b01size;
-                case 2:
-                case 3:return nmemmap.b23size;
-                case 4:
-                case 5:return nmemmap.b45size;
-                case 6:
-                case 7:return nmemmap.b67size;
-                default:return -1 ;
-        }
-}
-
-#else
+#ifdef SGI_SN2
 int
 IsBankPresent(int index, node_memmap_t nmemmap)
 {
@@ -168,13 +132,13 @@
 #endif
 
 void
-build_mem_desc(efi_memory_desc_t *md, int type, long paddr, long numbytes)
+build_mem_desc(efi_memory_desc_t *md, int type, long paddr, long numbytes, long attr)
 {
         md->type = type;
         md->phys_addr = paddr;
         md->virt_addr = 0;
         md->num_pages = numbytes >> 12;
-        md->attribute = EFI_MEMORY_WB;
+        md->attribute = attr;
 }
 
 int
@@ -192,12 +156,12 @@
 	for (cnode=0;cnode<numnodes;cnode++) {
 		nasid = GetNasid(cnode) ;
 		membank_info = GetMemBankInfo(cnode) ;
-		for (bank=0;bank<PLAT_CLUMPS_PER_NODE;bank++) {
+		for (bank=0;bank<MD_BANKS_PER_NODE;bank++) {
 			if (IsBankPresent(bank, membank_info)) {
 				bsize = GetBankSize(bank, membank_info) ;
                                 paddr = PHYS_ADDRESS(nasid, (long)bank<<MD_BANK_SHFT);
                                 numbytes = BankSizeBytes(bsize);
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 				/* 
 				 * Ignore directory.
 				 * Shorten memory chunk by 1 page - makes a better
@@ -236,28 +200,40 @@
                                  */
                                 if (bank == 0) {
 					if (cnode == 0) {
+						hole = 2*1024*1024;
+						build_mem_desc(md, EFI_PAL_CODE, paddr, hole, EFI_MEMORY_WB|EFI_MEMORY_WB);
+						numbytes -= hole;
+                                        	paddr += hole;
+			        		count++ ;
+                                        	md += mdsize;
 						hole = 1*1024*1024;
-						build_mem_desc(md, EFI_PAL_CODE, paddr, hole);
+						build_mem_desc(md, EFI_CONVENTIONAL_MEMORY, paddr, hole, EFI_MEMORY_UC);
 						numbytes -= hole;
                                         	paddr += hole;
 			        		count++ ;
                                         	md += mdsize;
-						hole = 3*1024*1024;
-						build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole);
+						hole = 1*1024*1024;
+						build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole, EFI_MEMORY_WB|EFI_MEMORY_WB);
 						numbytes -= hole;
                                         	paddr += hole;
 			        		count++ ;
                                         	md += mdsize;
 					} else {
-						hole = PROMRESERVED_SIZE;
-                                        	build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole);
+						hole = 2*1024*1024;
+                                        	build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole, EFI_MEMORY_WB|EFI_MEMORY_WB);
+						numbytes -= hole;
+                                        	paddr += hole;
+			        		count++ ;
+                                        	md += mdsize;
+						hole = 2*1024*1024;
+                                        	build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole, EFI_MEMORY_UC);
 						numbytes -= hole;
                                         	paddr += hole;
 			        		count++ ;
                                         	md += mdsize;
 					}
                                 }
-                                build_mem_desc(md, EFI_CONVENTIONAL_MEMORY, paddr, numbytes);
+                                build_mem_desc(md, EFI_CONVENTIONAL_MEMORY, paddr, numbytes, EFI_MEMORY_WB|EFI_MEMORY_WB);
 
 			        md += mdsize ;
 			        count++ ;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/fakeprom/fpmem.h linux-2.4.22-pre10/arch/ia64/sn/fakeprom/fpmem.h
--- linux-2.4.21/arch/ia64/sn/fakeprom/fpmem.h	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/fakeprom/fpmem.h	2003-08-01 13:33:36.000000000 +0000
@@ -4,13 +4,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 #include <linux/config.h>
 
 /*
- * Structure of the mem config of the node as a SN1 MI reg
+ * Structure of the mem config of the node as a SN MI reg
  * Medusa supports this reg config.
  *
  * BankSize nibble to bank size mapping
@@ -24,32 +24,7 @@
 
 #define MBSHIFT				20
 
-#ifdef CONFIG_IA64_SGI_SN1
-typedef struct node_memmap_s
-{
-        unsigned int    b0      :1,     /* 0 bank 0 present */
-                        b1      :1,     /* 1 bank 1 present */
-                        r01     :2,     /* 2-3 reserved */
-                        b01size :4,     /* 4-7 Size of bank 0 and 1 */
-                        b2      :1,     /* 8 bank 2 present */
-                        b3      :1,     /* 9 bank 3 present */
-                        r23     :2,     /* 10-11 reserved */
-                        b23size :4,     /* 12-15 Size of bank 2 and 3 */
-                        b4      :1,     /* 16 bank 4 present */
-                        b5      :1,     /* 17 bank 5 present */
-                        r45     :2,     /* 18-19 reserved */
-                        b45size :4,     /* 20-23 Size of bank 4 and 5 */
-                        b6      :1,     /* 24 bank 6 present */
-                        b7      :1,     /* 25 bank 7 present */
-                        r67     :2,     /* 26-27 reserved */
-                        b67size :4;     /* 28-31 Size of bank 6 and 7 */
-} node_memmap_t ;
-
-/* Support the medusa hack for 8M/16M/32M nodes */
-#define SN1_BANK_SIZE_SHIFT		(MBSHIFT+6)     /* 64 MB */
-#define BankSizeBytes(bsize)            ((bsize<6) ? (1<<((bsize-1)+SN1_BANK_SIZE_SHIFT)) :\
-                                         (1<<((bsize-9)+MBSHIFT)))
-#else
+#ifdef SGI_SN2
 typedef struct node_memmap_s
 {
         unsigned int    b0size  :3,     /* 0-2   bank 0 size */
@@ -73,6 +48,8 @@
 #define SN2_BANK_SIZE_SHIFT		(MBSHIFT+6)     /* 64 MB */
 #define BankPresent(bsize)		(bsize<6)
 #define BankSizeBytes(bsize)            (BankPresent(bsize) ? 1UL<<((bsize)+SN2_BANK_SIZE_SHIFT) : 0)
+#define MD_BANKS_PER_NODE 4
+#define MD_BANKSIZE			(1UL << 34)
 #endif
 
 typedef struct sn_memmap_s
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/fakeprom/fprom.lds linux-2.4.22-pre10/arch/ia64/sn/fakeprom/fprom.lds
--- linux-2.4.21/arch/ia64/sn/fakeprom/fprom.lds	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/fakeprom/fprom.lds	2003-08-01 13:34:10.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/fakeprom/fpromasm.S linux-2.4.22-pre10/arch/ia64/sn/fakeprom/fpromasm.S
--- linux-2.4.21/arch/ia64/sn/fakeprom/fpromasm.S	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/fakeprom/fpromasm.S	2003-08-01 13:32:01.000000000 +0000
@@ -8,7 +8,7 @@
  * Copyright (C) 1998-2000 Hewlett-Packard Co
  * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -57,9 +57,7 @@
  * be 0x00000ffffc000000, but on snia we use the (inverse swizzled)
  * IOSPEC_BASE value
  */
-#ifdef CONFIG_IA64_SGI_SN1
-#define IOPB_PA		0xc0000FFFFC000000
-#else
+#ifdef SGI_SN2
 #define IOPB_PA		0xc000000fcc000000
 #endif
 
@@ -84,10 +82,7 @@
 
 // Isolate node number we are running on.
 	mov		r6 = ip;;
-#ifdef CONFIG_IA64_SGI_SN1
-	shr		r5 = r6,33;;			// r5 = node number
-	shl		r6 = r5,33			// r6 = base memory address of node
-#else
+#ifdef SGI_SN2
 	shr		r5 = r6,38			// r5 = node number
 	dep		r6 = 0,r6,0,36			// r6 = base memory address of node
 
@@ -99,7 +94,7 @@
 	or 		r1 = r1,r6			// Relocate to boot node
 
 // Lets figure out who we are & put it in the LID register.
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 // On SN2, we (currently) pass the cpu number in r10 at boot
 	and		r25=3,r10;;
 	movl		r16=0x8000008110000400		// Allow IPIs
@@ -324,10 +319,7 @@
 1:	cmp.eq	p6,p7=8,r28		/* PAL_VM_SUMMARY */
 (p7)	br.cond.sptk.few 1f
 	movl	r8=0
-#ifdef CONFIG_IA64_SGI_SN1
-	movl	r9=0x0203083001151059
-	movl	r10=0x1232
-#else
+#ifdef SGI_SN2
 	movl	r9=0x0203083001151065
 	movl	r10=0x183f
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/fakeprom/fw-emu.c linux-2.4.22-pre10/arch/ia64/sn/fakeprom/fw-emu.c
--- linux-2.4.21/arch/ia64/sn/fakeprom/fw-emu.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/fakeprom/fw-emu.c	2003-08-01 13:34:08.000000000 +0000
@@ -5,7 +5,7 @@
  * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
  *
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -42,7 +42,7 @@
 #include <asm/sn/sn_sal.h>
 #include <asm/processor.h>
 #include <asm/sn/sn_cpuid.h>
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 #include <asm/sn/sn2/addrs.h>
 #include <asm/sn/sn2/shub_mmr.h>
 #endif
@@ -68,10 +68,7 @@
 #define ACPI_SLIT_REVISION 1
 
 #define OEMID			"SGI"
-#ifdef CONFIG_IA64_SGI_SN1
-#define PRODUCT			"SN1"
-#define PROXIMITY_DOMAIN(nasid)	(nasid)
-#else
+#ifdef SGI_SN2
 #define PRODUCT			"SN2"
 #define PROXIMITY_DOMAIN(nasid)	(((nasid)>>1) & 255)
 #endif
@@ -99,12 +96,7 @@
 
 typedef union ia64_nasid_va {
         struct {
-#if defined(CONFIG_IA64_SGI_SN1)
-                unsigned long off   : 33;       /* intra-region offset */
-		unsigned long nasid :  7;	/* NASID */
-		unsigned long off2  : 21;	/* fill */
-                unsigned long reg   :  3;       /* region number */
-#elif defined(CONFIG_IA64_SGI_SN2)
+#if defined(SGI_SN2)
                 unsigned long off   : 36;       /* intra-region offset */
 		unsigned long attr  :  2;
 		unsigned long nasid : 11;	/* NASID */
@@ -124,9 +116,7 @@
 #define IS_VIRTUAL_MODE() 	 ({struct ia64_psr psr; asm("mov %0=psr" : "=r"(psr)); psr.dt;})
 #define ADDR_OF(p)		(IS_VIRTUAL_MODE() ? ((void*)((long)(p)+PAGE_OFFSET)) : ((void*) (p)))
 
-#if defined(CONFIG_IA64_SGI_SN1)
-#define __fwtab_pa(n,x)		({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.l;})
-#elif defined(CONFIG_IA64_SGI_SN2)
+#if defined(SGI_SN2)
 #define __fwtab_pa(n,x)		({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.f.attr = 3; _v.l;})
 #endif
 
@@ -207,7 +197,7 @@
 	return EFI_UNSUPPORTED;
 }
 
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 
 #undef cpu_physical_id
 #define cpu_physical_id(cpuid)                  ((ia64_get_lid() >> 16) & 0xffff)
@@ -300,7 +290,7 @@
 		;
 	} else if (index == SAL_UPDATE_PAL) {
 		;
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 	} else if (index == SN_SAL_LOG_CE) {
 #ifdef ajmtestcpei
 		fprom_send_cpei();
@@ -500,9 +490,7 @@
 	/*
 	 * Pass the parameter base address to the build_efi_xxx routines.
 	 */
-#if defined(CONFIG_IA64_SGI_SN1)
-	build_init(8LL*GB*base_nasid);
-#else
+#if defined(SGI_SN2)
 	build_init(0x3000000000UL | ((long)base_nasid<<38));
 #endif
 
@@ -624,10 +612,7 @@
 			lsapic20->header.length = sizeof(struct acpi_table_lsapic);
 			lsapic20->acpi_id = cnode*4+cpu;
 			lsapic20->flags.enabled = 1;
-#if defined(CONFIG_IA64_SGI_SN1)
-			lsapic20->eid = cpu;
-			lsapic20->id = nasid;
-#else
+#if defined(SGI_SN2)
 			lsapic20->eid = nasid&0xffff;
 			lsapic20->id = (cpu<<4) | (nasid>>16);
 #endif
@@ -648,12 +633,9 @@
 		srat_memory_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
 		srat_memory_affinity->base_addr_lo = 0;
 		srat_memory_affinity->length_lo = 0;
-#if defined(CONFIG_IA64_SGI_SN1)
-		srat_memory_affinity->base_addr_hi = nasid<<1;
-		srat_memory_affinity->length_hi = SN1_NODE_SIZE>>32;
-#else
+#if defined(SGI_SN2)
 		srat_memory_affinity->base_addr_hi = (nasid<<6) | (3<<4);
-		srat_memory_affinity->length_hi = SN2_NODE_SIZE>>32;
+		srat_memory_affinity->length_hi = (MD_BANKSIZE*MD_BANKS_PER_NODE)>>32;
 #endif
 		srat_memory_affinity->memory_type = ACPI_ADDRESS_RANGE_MEMORY;
 		srat_memory_affinity->flags.enabled = 1;
@@ -670,10 +652,7 @@
 			srat_cpu_affinity->header.length = sizeof(struct acpi_table_processor_affinity);
 			srat_cpu_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
 			srat_cpu_affinity->flags.enabled = 1;
-#if defined(CONFIG_IA64_SGI_SN1)
-			srat_cpu_affinity->apic_id = nasid;
-			srat_cpu_affinity->lsapic_eid = cpu;
-#else
+#if defined(SGI_SN2)
 			srat_cpu_affinity->lsapic_eid = nasid&0xffff;
 			srat_cpu_affinity->apic_id = (cpu<<4) | (nasid>>16);
 #endif
@@ -707,7 +686,7 @@
 	sal_systab->sal_b_rev_minor = 0x0; /* 1.00 */
 
 	strcpy(sal_systab->oem_id, "SGI");
-	strcpy(sal_systab->product_id, "SN1");
+	strcpy(sal_systab->product_id, "SN2");
 
 	/* fill in an entry point: */	
 	sal_ed->type = SAL_DESC_ENTRY_POINT;
@@ -785,9 +764,7 @@
 		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
 			if (!IsCpuPresent(cnode, cpu))
 				continue;
-#ifdef CONFIG_IA64_SGI_SN1
-			bsp_lid = (GetNasid(cnode)<<24) | (cpu<<16);
-#else
+#ifdef SGI_SN2
 			bsp_lid = (GetNasid(cnode)<<16) | (cpu<<28);
 #endif
 			if (bsp-- > 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/fakeprom/klgraph_init.c linux-2.4.22-pre10/arch/ia64/sn/fakeprom/klgraph_init.c
--- linux-2.4.21/arch/ia64/sn/fakeprom/klgraph_init.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/fakeprom/klgraph_init.c	2003-08-01 13:31:01.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 
@@ -49,41 +49,13 @@
 klgraph_init(void)
 {
 
-#ifdef CONFIG_IA64_SGI_SN1
 	u64 *temp;
-#endif
 	/*
 	 * Initialize some hub/xbow registers that allows access to 
 	 * Xbridge etc.  These are normally done in PROM.
 	 */
 
         /* Write IOERR clear to clear the CRAZY bit in the status */
-#ifdef CONFIG_IA64_SGI_SN1
-        *(volatile uint64_t *)0xc0000a0001c001f8 = (uint64_t)0xffffffff;
-
-        /* set widget control register...setting bedrock widget id to b */
-        *(volatile uint64_t *)0xc0000a0001c00020 = (uint64_t)0x801b;
-
-        /* set io outbound widget access...allow all */
-        *(volatile uint64_t *)0xc0000a0001c00110 = (uint64_t)0xff01;
-
-        /* set io inbound widget access...allow all */
-        *(volatile uint64_t *)0xc0000a0001c00118 = (uint64_t)0xff01;
-
-        /* set io crb timeout to max */
-        *(volatile uint64_t *)0xc0000a0001c003c0 = (uint64_t)0xffffff;
-        *(volatile uint64_t *)0xc0000a0001c003c0 = (uint64_t)0xffffff;
-
-        /* set local block io permission...allow all */
-        *(volatile uint64_t *)0xc0000a0001e04010 = (uint64_t)0xfffffffffffffff;
-
-        /* clear any errors */
-        /* clear_ii_error(); medusa should have cleared these */
-
-        /* set default read response buffers in bridge */
-        *(volatile u32 *)0xc0000a000f000280L = 0xba98;
-        *(volatile u32 *)0xc0000a000f000288L = 0xba98;
-#elif CONFIG_IA64_SGI_SN2
         *(volatile uint64_t *)0xc000000801c001f8 = (uint64_t)0xffffffff;
 
         /* set widget control register...setting bedrock widget id to a */
@@ -108,184 +80,126 @@
         /* set default read response buffers in bridge */
 // [PI]       *(volatile u32 *)0xc00000080f000280L = 0xba98;
 // [PI]       *(volatile u32 *)0xc00000080f000288L = 0xba98;
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-#ifdef CONFIG_IA64_SGI_SN1
-
-	/*
-	 * kldir entries initialization - mankato
-	 */
-	convert(0x8000000000002000, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002010, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002020, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002030, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002040, 0x434d5f53505f5357, 0x0000000000030000);
-	convert(0x8000000000002050, 0x0000000000000000, 0x0000000000010000);
-	convert(0x8000000000002060, 0x0000000000000001, 0x0000000000000000);
-	convert(0x8000000000002070, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002080, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002090, 0x0000000000000000, 0x0000000000000000);
-	convert(0x80000000000020a0, 0x0000000000000000, 0x0000000000000000);
-	convert(0x80000000000020b0, 0x0000000000000000, 0x0000000000000000);
-	convert(0x80000000000020c0, 0x434d5f53505f5357, 0x0000000000000000);
-	convert(0x80000000000020d0, 0x0000000000002400, 0x0000000000000400);
-	convert(0x80000000000020e0, 0x0000000000000001, 0x0000000000000000);
-	convert(0x80000000000020f0, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002100, 0x434d5f53505f5357, 0x0000000000040000);
-	convert(0x8000000000002110, 0x0000000000000000, 0xffffffffffffffff);
-	convert(0x8000000000002120, 0x0000000000000001, 0x0000000000000000);
-	convert(0x8000000000002130, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002140, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002150, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002160, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002170, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002180, 0x434d5f53505f5357, 0x0000000000020000);
-	convert(0x8000000000002190, 0x0000000000000000, 0x0000000000010000);
-	convert(0x80000000000021a0, 0x0000000000000001, 0x0000000000000000); 
 
-	/*
-	 * klconfig entries initialization - mankato
-	 */
-	convert(0x0000000000030000, 0x00000000beedbabe, 0x0000004800000000);
-	convert(0x0000000000030010, 0x0003007000000018, 0x800002000f820178);
-	convert(0x0000000000030020, 0x80000a000f024000, 0x800002000f800000);
-	convert(0x0000000000030030, 0x0300fafa00012580, 0x00000000040f0000);
-	convert(0x0000000000030040, 0x0000000000000000, 0x0003097000030070);
-	convert(0x0000000000030050, 0x00030970000303b0, 0x0003181000033f70);
-	convert(0x0000000000030060, 0x0003d51000037570, 0x0000000000038330);
-	convert(0x0000000000030070, 0x0203110100030140, 0x0001000000000101);
-	convert(0x0000000000030080, 0x0900000000000000, 0x000000004e465e67);
-	convert(0x0000000000030090, 0x0003097000000000, 0x00030b1000030a40);
-	convert(0x00000000000300a0, 0x00030cb000030be0, 0x000315a0000314d0);
-	convert(0x00000000000300b0, 0x0003174000031670, 0x0000000000000000);
-	convert(0x0000000000030100, 0x000000000000001a, 0x3350490000000000);
-	convert(0x0000000000030110, 0x0000000000000037, 0x0000000000000000);
-	convert(0x0000000000030140, 0x0002420100030210, 0x0001000000000101);
-	convert(0x0000000000030150, 0x0100000000000000, 0xffffffffffffffff);
-	convert(0x0000000000030160, 0x00030d8000000000, 0x0000000000030e50);
-	convert(0x00000000000301c0, 0x0000000000000000, 0x0000000000030070);
-	convert(0x00000000000301d0, 0x0000000000000025, 0x424f490000000000);
-	convert(0x00000000000301e0, 0x000000004b434952, 0x0000000000000000);
-	convert(0x0000000000030210, 0x00027101000302e0, 0x00010000000e4101);
-	convert(0x0000000000030220, 0x0200000000000000, 0xffffffffffffffff);
-	convert(0x0000000000030230, 0x00030f2000000000, 0x0000000000030ff0);
-	convert(0x0000000000030290, 0x0000000000000000, 0x0000000000030140);
-	convert(0x00000000000302a0, 0x0000000000000026, 0x7262490000000000);
-	convert(0x00000000000302b0, 0x00000000006b6369, 0x0000000000000000);
-	convert(0x00000000000302e0, 0x0002710100000000, 0x00010000000f3101);
-	convert(0x00000000000302f0, 0x0500000000000000, 0xffffffffffffffff);
-	convert(0x0000000000030300, 0x000310c000000000, 0x0003126000031190);
-	convert(0x0000000000030310, 0x0003140000031330, 0x0000000000000000);
-	convert(0x0000000000030360, 0x0000000000000000, 0x0000000000030140);
-	convert(0x0000000000030370, 0x0000000000000029, 0x7262490000000000);
-	convert(0x0000000000030380, 0x00000000006b6369, 0x0000000000000000);
-	convert(0x0000000000030970, 0x0000000002010102, 0x0000000000000000);
-	convert(0x0000000000030980, 0x000000004e465e67, 0xffffffff00000000);
-	/* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */
-	convert(0x00000000000309a0, 0x0000000000037570, 0xffffffff00000000);
-	convert(0x00000000000309b0, 0x0000000000030070, 0x0000000000000000);
-	convert(0x00000000000309c0, 0x000000000003f420, 0x0000000000000000);
-	convert(0x0000000000030a40, 0x0000000002010125, 0x0000000000000000);
-	convert(0x0000000000030a50, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x0000000000030a70, 0x0000000000037b78, 0x0000000000000000);
-	convert(0x0000000000030b10, 0x0000000002010125, 0x0000000000000000);
-	convert(0x0000000000030b20, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x0000000000030b40, 0x0000000000037d30, 0x0000000000000001);
-	convert(0x0000000000030be0, 0x00000000ff010203, 0x0000000000000000);
-	convert(0x0000000000030bf0, 0xffffffffffffffff, 0xffffffff000000ff);
-	convert(0x0000000000030c10, 0x0000000000037ee8, 0x0100010000000200);
-	convert(0x0000000000030cb0, 0x00000000ff310111, 0x0000000000000000);
-	convert(0x0000000000030cc0, 0xffffffffffffffff, 0x0000000000000000);
-	convert(0x0000000000030d80, 0x0000000002010104, 0x0000000000000000);
-	convert(0x0000000000030d90, 0xffffffffffffffff, 0x00000000000000ff);
-	convert(0x0000000000030db0, 0x0000000000037f18, 0x0000000000000000);
-	convert(0x0000000000030dc0, 0x0000000000000000, 0x0003007000060000);
-	convert(0x0000000000030de0, 0x0000000000000000, 0x0003021000050000);
-	convert(0x0000000000030df0, 0x000302e000050000, 0x0000000000000000);
-	convert(0x0000000000030e30, 0x0000000000000000, 0x000000000000000a);
-	convert(0x0000000000030e50, 0x00000000ff00011a, 0x0000000000000000);
-	convert(0x0000000000030e60, 0xffffffffffffffff, 0x0000000000000000);
-	convert(0x0000000000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e);
-	convert(0x0000000000030e90, 0x000000000000bc6e, 0x0000000000000000);
-	convert(0x0000000000030f20, 0x0000000002010205, 0x00000000d0020000);
-	convert(0x0000000000030f30, 0xffffffffffffffff, 0x0000000e0000000e);
-	convert(0x0000000000030f40, 0x000000000000000e, 0x0000000000000000);
-	convert(0x0000000000030f50, 0x0000000000038010, 0x00000000000007ff);
-	convert(0x0000000000030f70, 0x0000000000000000, 0x0000000022001077);
-	convert(0x0000000000030fa0, 0x0000000000000000, 0x000000000003f4a8);
-	convert(0x0000000000030ff0, 0x0000000000310120, 0x0000000000000000);
-	convert(0x0000000000031000, 0xffffffffffffffff, 0xffffffff00000002);
-	convert(0x0000000000031010, 0x000000000000000e, 0x0000000000000000);
-	convert(0x0000000000031020, 0x0000000000038088, 0x0000000000000000);
-	convert(0x00000000000310c0, 0x0000000002010205, 0x00000000d0020000);
-	convert(0x00000000000310d0, 0xffffffffffffffff, 0x0000000f0000000f);
-	convert(0x00000000000310e0, 0x000000000000000f, 0x0000000000000000);
-	convert(0x00000000000310f0, 0x00000000000380b8, 0x00000000000007ff);
-	convert(0x0000000000031120, 0x0000000022001077, 0x00000000000310a9);
-	convert(0x0000000000031130, 0x00000000580211c1, 0x000000008009104c);
-	convert(0x0000000000031140, 0x0000000000000000, 0x000000000003f4c0);
-	convert(0x0000000000031190, 0x0000000000310120, 0x0000000000000000);
-	convert(0x00000000000311a0, 0xffffffffffffffff, 0xffffffff00000003);
-	convert(0x00000000000311b0, 0x000000000000000f, 0x0000000000000000);
-	convert(0x00000000000311c0, 0x0000000000038130, 0x0000000000000000);
-	convert(0x0000000000031260, 0x0000000000110106, 0x0000000000000000);
-	convert(0x0000000000031270, 0xffffffffffffffff, 0xffffffff00000004);
-	convert(0x0000000000031280, 0x000000000000000f, 0x0000000000000000);
-	convert(0x00000000000312a0, 0x00000000ff110013, 0x0000000000000000);
-	convert(0x00000000000312b0, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x00000000000312c0, 0x000000000000000f, 0x0000000000000000);
-	convert(0x00000000000312e0, 0x0000000000110012, 0x0000000000000000);
-	convert(0x00000000000312f0, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x0000000000031300, 0x000000000000000f, 0x0000000000000000);
-	convert(0x0000000000031310, 0x0000000000038160, 0x0000000000000000);
-	convert(0x0000000000031330, 0x00000000ff310122, 0x0000000000000000);
-	convert(0x0000000000031340, 0xffffffffffffffff, 0xffffffff00000005);
-	convert(0x0000000000031350, 0x000000000000000f, 0x0000000000000000);
-	convert(0x0000000000031360, 0x0000000000038190, 0x0000000000000000);
-	convert(0x0000000000031400, 0x0000000000310121, 0x0000000000000000);
-	convert(0x0000000000031400, 0x0000000000310121, 0x0000000000000000);
-	convert(0x0000000000031410, 0xffffffffffffffff, 0xffffffff00000006);
-	convert(0x0000000000031420, 0x000000000000000f, 0x0000000000000000);
-	convert(0x0000000000031430, 0x00000000000381c0, 0x0000000000000000);
-	convert(0x00000000000314d0, 0x00000000ff010201, 0x0000000000000000);
-	convert(0x00000000000314e0, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x0000000000031500, 0x00000000000381f0, 0x000030430000ffff);
-	convert(0x0000000000031510, 0x000000000000ffff, 0x0000000000000000);
-	convert(0x00000000000315a0, 0x00000020ff000201, 0x0000000000000000);
-	convert(0x00000000000315b0, 0xffffffffffffffff, 0xffffffff00000001);
-	convert(0x00000000000315d0, 0x0000000000038240, 0x00003f3f0000ffff);
-	convert(0x00000000000315e0, 0x000000000000ffff, 0x0000000000000000);
-	convert(0x0000000000031670, 0x00000000ff010201, 0x0000000000000000);
-	convert(0x0000000000031680, 0xffffffffffffffff, 0x0000000100000002);
-	convert(0x00000000000316a0, 0x0000000000038290, 0x000030430000ffff);
-	convert(0x00000000000316b0, 0x000000000000ffff, 0x0000000000000000);
-	convert(0x0000000000031740, 0x00000020ff000201, 0x0000000000000000);
-	convert(0x0000000000031750, 0xffffffffffffffff, 0x0000000500000003);
-	convert(0x0000000000031770, 0x00000000000382e0, 0x00003f3f0000ffff);
-	convert(0x0000000000031780, 0x000000000000ffff, 0x0000000000000000);
-
-	/*
-	 * GDA initialization - mankato
-	 */
-	convert(0x8000000000002400, 0x0000000258464552, 0x000000000ead0000);
-	convert(0x8000000000002480, 0xffffffff00010000, 0xffffffffffffffff);
-	convert(0x8000000000002490, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024a0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024b0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024c0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024d0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024e0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024f0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002500, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002510, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002520, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002530, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002540, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002550, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002560, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002570, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002580, 0x000000000000ffff, 0x0000000000000000);
-#endif
-	
+        /*
+         * klconfig entries initialization - mankato
+         */
+        convert(0xe000003000030000, 0x00000000beedbabe, 0x0000004800000000);
+        convert(0xe000003000030010, 0x0003007000000018, 0x800002000f820178);
+        convert(0xe000003000030020, 0x80000a000f024000, 0x800002000f800000);
+        convert(0xe000003000030030, 0x0300fafa00012580, 0x00000000040f0000);
+        convert(0xe000003000030040, 0x0000000000000000, 0x0003097000030070);
+        convert(0xe000003000030050, 0x00030970000303b0, 0x0003181000033f70);
+        convert(0xe000003000030060, 0x0003d51000037570, 0x0000000000038330);
+        convert(0xe000003000030070, 0x0203110100030140, 0x0001000000000101);
+        convert(0xe000003000030080, 0x0900000000000000, 0x000000004e465e67);
+        convert(0xe000003000030090, 0x0003097000000000, 0x00030b1000030a40);
+        convert(0xe0000030000300a0, 0x00030cb000030be0, 0x000315a0000314d0);
+        convert(0xe0000030000300b0, 0x0003174000031670, 0x0000000000000000);
+        convert(0xe000003000030100, 0x000000000000001a, 0x3350490000000000);
+        convert(0xe000003000030110, 0x0000000000000037, 0x0000000000000000);
+        convert(0xe000003000030140, 0x0002420100030210, 0x0001000000000101);
+        convert(0xe000003000030150, 0x0100000000000000, 0xffffffffffffffff);
+        convert(0xe000003000030160, 0x00030d8000000000, 0x0000000000030e50);
+        convert(0xe0000030000301c0, 0x0000000000000000, 0x0000000000030070);
+        convert(0xe0000030000301d0, 0x0000000000000025, 0x424f490000000000);
+        convert(0xe0000030000301e0, 0x000000004b434952, 0x0000000000000000);
+        convert(0xe000003000030210, 0x00027101000302e0, 0x00010000000e4101);
+        convert(0xe000003000030220, 0x0200000000000000, 0xffffffffffffffff);
+        convert(0xe000003000030230, 0x00030f2000000000, 0x0000000000030ff0);
+        convert(0xe000003000030290, 0x0000000000000000, 0x0000000000030140);
+        convert(0xe0000030000302a0, 0x0000000000000026, 0x7262490000000000);
+        convert(0xe0000030000302b0, 0x00000000006b6369, 0x0000000000000000);
+        convert(0xe0000030000302e0, 0x0002710100000000, 0x00010000000f3101);
+        convert(0xe0000030000302f0, 0x0500000000000000, 0xffffffffffffffff);
+        convert(0xe000003000030300, 0x000310c000000000, 0x0003126000031190);
+        convert(0xe000003000030310, 0x0003140000031330, 0x0000000000000000);
+        convert(0xe000003000030360, 0x0000000000000000, 0x0000000000030140);
+        convert(0xe000003000030370, 0x0000000000000029, 0x7262490000000000);
+        convert(0xe000003000030380, 0x00000000006b6369, 0x0000000000000000);
+        convert(0xe000003000030970, 0x0000000002010102, 0x0000000000000000);
+        convert(0xe000003000030980, 0x000000004e465e67, 0xffffffff00000000);
+        /* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */
+        convert(0xe0000030000309a0, 0x0000000000037570, 0xffffffff00000000);
+        convert(0xe0000030000309b0, 0x0000000000030070, 0x0000000000000000);
+        convert(0xe0000030000309c0, 0x000000000003f420, 0x0000000000000000);
+        convert(0xe000003000030a40, 0x0000000002010125, 0x0000000000000000);
+        convert(0xe000003000030a50, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe000003000030a70, 0x0000000000037b78, 0x0000000000000000);
+        convert(0xe000003000030b10, 0x0000000002010125, 0x0000000000000000);
+        convert(0xe000003000030b20, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe000003000030b40, 0x0000000000037d30, 0x0000000000000001);
+        convert(0xe000003000030be0, 0x00000000ff010203, 0x0000000000000000);
+        convert(0xe000003000030bf0, 0xffffffffffffffff, 0xffffffff000000ff);
+        convert(0xe000003000030c10, 0x0000000000037ee8, 0x0100010000000200);
+        convert(0xe000003000030cb0, 0x00000000ff310111, 0x0000000000000000);
+        convert(0xe000003000030cc0, 0xffffffffffffffff, 0x0000000000000000);
+        convert(0xe000003000030d80, 0x0000000002010104, 0x0000000000000000);
+        convert(0xe000003000030d90, 0xffffffffffffffff, 0x00000000000000ff);
+        convert(0xe000003000030db0, 0x0000000000037f18, 0x0000000000000000);
+        convert(0xe000003000030dc0, 0x0000000000000000, 0x0003007000060000);
+        convert(0xe000003000030de0, 0x0000000000000000, 0x0003021000050000);
+        convert(0xe000003000030df0, 0x000302e000050000, 0x0000000000000000);
+        convert(0xe000003000030e30, 0x0000000000000000, 0x000000000000000a);
+        convert(0xe000003000030e50, 0x00000000ff00011a, 0x0000000000000000);
+        convert(0xe000003000030e60, 0xffffffffffffffff, 0x0000000000000000);
+        convert(0xe000003000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e);
+        convert(0xe000003000030e90, 0x000000000000bc6e, 0x0000000000000000);
+        convert(0xe000003000030f20, 0x0000000002010205, 0x00000000d0020000);
+        convert(0xe000003000030f30, 0xffffffffffffffff, 0x0000000e0000000e);
+        convert(0xe000003000030f40, 0x000000000000000e, 0x0000000000000000);
+        convert(0xe000003000030f50, 0x0000000000038010, 0x00000000000007ff);
+        convert(0xe000003000030f70, 0x0000000000000000, 0x0000000022001077);
+        convert(0xe000003000030fa0, 0x0000000000000000, 0x000000000003f4a8);
+        convert(0xe000003000030ff0, 0x0000000000310120, 0x0000000000000000);
+        convert(0xe000003000031000, 0xffffffffffffffff, 0xffffffff00000002);
+        convert(0xe000003000031010, 0x000000000000000e, 0x0000000000000000);
+        convert(0xe000003000031020, 0x0000000000038088, 0x0000000000000000);
+        convert(0xe0000030000310c0, 0x0000000002010205, 0x00000000d0020000);
+        convert(0xe0000030000310d0, 0xffffffffffffffff, 0x0000000f0000000f);
+        convert(0xe0000030000310e0, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe0000030000310f0, 0x00000000000380b8, 0x00000000000007ff);
+        convert(0xe000003000031120, 0x0000000022001077, 0x00000000000310a9);
+        convert(0xe000003000031130, 0x00000000580211c1, 0x000000008009104c);
+        convert(0xe000003000031140, 0x0000000000000000, 0x000000000003f4c0);
+        convert(0xe000003000031190, 0x0000000000310120, 0x0000000000000000);
+        convert(0xe0000030000311a0, 0xffffffffffffffff, 0xffffffff00000003);
+        convert(0xe0000030000311b0, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe0000030000311c0, 0x0000000000038130, 0x0000000000000000);
+        convert(0xe000003000031260, 0x0000000000110106, 0x0000000000000000);
+        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
+        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
+        convert(0xe000003000031280, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe0000030000312a0, 0x00000000ff110013, 0x0000000000000000);
+        convert(0xe0000030000312b0, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe0000030000312c0, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe0000030000312e0, 0x0000000000110012, 0x0000000000000000);
+        convert(0xe0000030000312f0, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe000003000031300, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe000003000031310, 0x0000000000038160, 0x0000000000000000);
+        convert(0xe000003000031330, 0x00000000ff310122, 0x0000000000000000);
+        convert(0xe000003000031340, 0xffffffffffffffff, 0xffffffff00000005);
+        convert(0xe000003000031350, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe000003000031360, 0x0000000000038190, 0x0000000000000000);
+        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
+        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
+        convert(0xe000003000031410, 0xffffffffffffffff, 0xffffffff00000006);
+        convert(0xe000003000031420, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe000003000031430, 0x00000000000381c0, 0x0000000000000000);
+        convert(0xe0000030000314d0, 0x00000000ff010201, 0x0000000000000000);
+        convert(0xe0000030000314e0, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe000003000031500, 0x00000000000381f0, 0x000030430000ffff);
+        convert(0xe000003000031510, 0x000000000000ffff, 0x0000000000000000);
+        convert(0xe0000030000315a0, 0x00000020ff000201, 0x0000000000000000);
+        convert(0xe0000030000315b0, 0xffffffffffffffff, 0xffffffff00000001);
+        convert(0xe0000030000315d0, 0x0000000000038240, 0x00003f3f0000ffff);
+        convert(0xe0000030000315e0, 0x000000000000ffff, 0x0000000000000000);
+        convert(0xe000003000031670, 0x00000000ff010201, 0x0000000000000000);
+        convert(0xe000003000031680, 0xffffffffffffffff, 0x0000000100000002);
+        convert(0xe0000030000316a0, 0x0000000000038290, 0x000030430000ffff);
+        convert(0xe0000030000316b0, 0x000000000000ffff, 0x0000000000000000);
+        convert(0xe000003000031740, 0x00000020ff000201, 0x0000000000000000);
+        convert(0xe000003000031750, 0xffffffffffffffff, 0x0000000500000003);
+        convert(0xe000003000031770, 0x00000000000382e0, 0x00003f3f0000ffff);
+        convert(0xe000003000031780, 0x000000000000ffff, 0x0000000000000000);
 }
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/fakeprom/main.c linux-2.4.22-pre10/arch/ia64/sn/fakeprom/main.c
--- linux-2.4.21/arch/ia64/sn/fakeprom/main.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/fakeprom/main.c	2003-08-01 13:33:30.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
@@ -33,25 +33,9 @@
 	 * First lets figure out who we are. This is done from the
 	 * LID passed to us.
 	 */
-
-#ifdef CONFIG_IA64_SGI_SN1
-	nasid = (lid>>24);
-	syn = (lid>>17)&1;
-	cpu = (lid>>16)&1;
-
-	/*
-	 * Now pick a synergy master to initialize synergy registers.
-	 */
-	if (test_and_set_bit(syn, &nasidmaster[nasid]) == 0) {
-		synergy_init(nasid, syn);
-		test_and_set_bit(syn+2, &nasidmaster[nasid]);
-	} else
-		while (get_bit(syn+2, &nasidmaster[nasid]) == 0);
-#else
 	nasid = (lid>>16)&0xfff;
 	cpu = (lid>>28)&3;
 	syn = 0;
-#endif
 	
 	/*
 	 * Now pick a nasid master to initialize Bedrock registers.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/fakeprom/runsim linux-2.4.22-pre10/arch/ia64/sn/fakeprom/runsim
--- linux-2.4.21/arch/ia64/sn/fakeprom/runsim	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/fakeprom/runsim	1970-01-01 00:00:00.000000000 +0000
@@ -1,387 +0,0 @@
-#!/bin/sh
-
-# Script for running PROMs and LINUX kernwls on medusa. 
-# Type "sim -H" for instructions.
-
-MEDUSA=${MEDUSA:-/home/rickc/official_medusa/medusa}
-
-# ------------------ err -----------------------
-err() {
-	echo "ERROR - $1"
-	exit 1
-}
-
-# ----------------  help ----------------------
-help() {
-cat <<END
-Script for running a PROM or LINUX kernel under medusa.
-This script creates a control file, creates links to the appropriate
-linux/prom files, and/or calls medusa to make simulation runs.
-
-Usage:  
-   Initial setup:
-   	sim [-c <config_file>] <-p> | <-k>  [<work_dir>]
-		-p	Create PROM control file & links
-		-k	Create LINUX control file & links
-		-c<cf>	Control file name				[Default: cf]
-		<work_dir> Path to directory that contains the linux or PROM files.
-		    The directory can be any of the following:
-		       (linux simulations)
-		       		worktree
-				worktree/linux
-				any directory with vmlinux, vmlinux.sym & fprom files
-			(prom simulations)
-				worktree
-				worktree/stand/arcs/IP37prom/dev
-				any directory with fw.bin & fw.sim files
-
-    Simulations:
-	sim  [-X <n>] [-o <output>] [-M] [<config_file>]
-		-c<cf>	Control file name				[Default: cf]
-		-M	Pipe output thru fmtmedusa
-		-o	Output filename (copy of all commands/output)	[Default: simout]
-		-X	Specifies number of instructions to execute	[Default: 0]
-			(Used only in auto test mode - not described here)
-
-Examples:
-	sim -p <promtree>	# create control file (cf) & links for prom simulations
-	sim -k <linuxtree>	# create control file (cf) & links for linux simulations
-	sim -p -c cfprom	# create a prom control file (cfprom) only. No links are made.
-
-	sim			# run medusa using previously created links &
-				#   control file (cf).
-END
-exit 1
-}
-
-# ----------------------- create control file header --------------------
-create_cf_header() {
-cat <<END >>$CF
-#
-# Template for a control file for running linux kernels under medusa. 
-# You probably want to make mods here but this is a good starting point.
-#
-
-# Preferences
-setenv cpu_stepping A
-setenv exceptionPrint off
-setenv interrupt_messages off
-setenv lastPCsize 100000
-setenv low_power_mode on
-setenv partialIntelChipSet on
-setenv printIntelMessages off
-setenv prom_write_action halt
-setenv prom_write_messages on
-setenv step_quantum 100
-setenv swizzling on
-setenv tsconsole on
-setenv uart_echo on
-symbols on
-
-# IDE disk params
-setenv diskCylinders 611
-setenv bootDrive C
-setenv diskHeads 16
-setenv diskPath idedisk
-setenv diskPresent 1
-setenv diskSpt 63
-
-# Hardware config
-setenv coherency_type nasid
-setenv cpu_cache_type default
-setenv synergy_cache_type syn_cac_64m_8w
-setenv l4_uc_snoop off
-
-# Numalink config
-setenv route_enable on
-setenv network_type router		# Select [xbar|router]
-setenv network_warning 0xff
-
-END
-}
-
-
-# ------------------ create control file entries for linux simulations -------------
-create_cf_linux() {
-cat <<END >>$CF
-# Kernel specific options
-setenv calias_size 0
-setenv mca_on_memory_failure off
-setenv LOADPC 0x00100000		# FPROM load address/entry point (8 digits!)
-setenv symbol_table vmlinux.sym
-load fprom
-load vmlinux
-
-# Useful breakpoints to always have set. Add more if desired.
-break 0xe000000000505e00	all	# dispatch_to_fault_handler
-break panic			all	# stop on panic
-break die_if_kernel		all	# may as well stop
-
-END
-}
-
-# ------------------ create control file entries for prom simulations ---------------
-create_cf_prom() {
-	SYM2=""
-	ADDR="0x80000000ff800000"
-	[ "$EMBEDDED_LINUX" != "0" ] || SYM2="setenv symbol_table2 vmlinux.sym"
-	[ "$SIZE" = "8MB" ] || ADDR="0x80000000ffc00000"
-	cat <<END >>$CF
-# PROM specific options
-setenv mca_on_memory_failure on
-setenv LOADPC 0x80000000ffffffb0
-setenv promFile fw.bin
-setenv promAddr $ADDR
-setenv symbol_table fw.sym
-$SYM2
-
-# Useful breakpoints to always have set. Add more if desired.
-break ivt_gexx 		all
-break ivt_brk		all
-break PROM_Panic_Spin	all
-break PROM_Panic	all
-break PROM_C_Panic	all
-break fled_die		all
-break ResetNow		all
-break zzzbkpt		all
-
-END
-}
-
-
-# ------------------ create control file entries for memory configuration -------------
-create_cf_memory() {
-cat <<END >>$CF
-# CPU/Memory map format:
-#	setenv nodeN_memory_config 0xBSBSBSBS
-#		B=banksize (0=unused, 1=64M, 2=128M, .., 5-1G, c=8M, d=16M, e=32M)
-#		S=bank enable (0=both disable, 3=both enable, 2=bank1 enable, 1=bank0 enable)
-#		  rightmost digits are for bank 0, the lowest address.
-#	setenv nodeN_nasid <nasid>
-#		specifies the NASID for the node. This is used ONLY if booting the kernel.
-#		On PROM configurations, set to 0 - PROM will change it later.
-#	setenv nodeN_cpu_config <cpu_mask>
-#		Set bit number N to 1 to enable cpu N. Ex., a value of 5 enables cpu 0 & 2.
-#
-# Repeat the above 3 commands for each node.
-#
-# For kernel, default to 32MB. Although this is not a valid hardware configuration,
-# it runs faster on medusa. For PROM, 64MB is smallest allowed value.
-
-setenv node0_cpu_config		0x1	# Enable only cpu 0 on the node
-END
-
-if [ $LINUX -eq 1 ] ; then
-cat <<END >>$CF
-setenv node0_nasid		0	# cnode 0 has NASID 0
-setenv node0_memory_config 	0xe1	# 32MB
-END
-else
-cat <<END >>$CF
-setenv node0_memory_config 	0x31	# 256MB
-END
-fi
-}
-
-# -------------------- set links to linux files -------------------------
-set_linux_links() {
-	if [ -d $D/linux/arch ] ; then
-		D=$D/linux
-	elif [ -d $D/arch -o -e vmlinux.sym -o -e $D/vmlinux ] ; then
-		D=$D
-	else
-		err "cant determine directory for linux binaries"
-	fi
-	rm -rf vmlinux vmlinux.sym fprom
-	ln -s $D/vmlinux vmlinux
-	if [ -f $D/vmlinux.sym ] ; then
-		ln -s $D/vmlinux.sym vmlinux.sym
-	elif  [ -f $D/System.map ] ; then
-		ln -s $D/System.map vmlinux.sym
-	fi
-	if [ -d $D/arch ] ; then
-		ln -s $D/arch/ia64/sn/fprom/fprom fprom
-	else
-		ln -s $D/fprom fprom
-	fi
-	echo "  .. Created links to linux files"	
-}
-
-# -------------------- set links to prom files -------------------------
-set_prom_links() {
-	if [ -d $D/stand ] ; then
-		D=$D/stand/arcs/IP37prom/dev
-	elif [ -d $D/sal ] ; then
-		D=$D
-	else
-		err "cant determine directory for PROM binaries"
-	fi
-	SETUP="/tmp/tmp.$$"
-	rm -r -f $SETUP
-	sed 's/export/setenv/' < $D/../../../../.setup | sed 's/=/ /' >$SETUP
-	egrep -q '^ *setenv *PROMSIZE *8MB|^ *export' $SETUP
-	if [ $? -eq 0 ] ; then
-		SIZE="8MB"
-	else
-		SIZE="4MB"
-	fi
-	grep -q '^ *setenv *LAUNCH_VMLINUX' $SETUP
-	EMBEDDED_LINUX=$?
-	PRODUCT=`grep '^ *setenv *PRODUCT' $SETUP | cut -d" " -f3`
-	rm -f fw.bin fw.map fw.sym vmlinux vmlinux.sym fprom $SETUP
-	SDIR="${PRODUCT}${SIZE}.O"
-	BIN="${PRODUCT}ip37prom${SIZE}"
-	ln -s $D/$SDIR/$BIN.bin fw.bin
-	ln -s $D/$SDIR/$BIN.map fw.map
-	ln -s $D/$SDIR/$BIN.sym fw.sym
-	echo "  .. Created links to $SIZE prom files"
-	if [ $EMBEDDED_LINUX -eq 0 ] ; then
-		ln -s $D/linux/vmlinux vmlinux
-		ln -s $D/linux/vmlinux.sym vmlinux.sym
-		if [ -d linux/arch ] ; then
-			ln -s $D/linux/arch/ia64/sn/fprom/fprom fprom
-		else
-			ln -s $D/linux/fprom fprom
-		fi
-		echo "  .. Created links to embedded linux files in prom tree"
-	fi
-}
-
-# --------------- start of shell script --------------------------------
-OUT="simout"
-FMTMED=0
-STEPCNT=0
-PROM=0
-LINUX=0
-NCF="cf"
-while getopts "HMX:c:o:pk" c ; do
-        case ${c} in
-                H) help;;
-		M) FMTMED=1;;
-		X) STEPCNT=${OPTARG};;
-		c) NCF=${OPTARG};;
-		k) PROM=0;LINUX=1;;
-		p) PROM=1;LINUX=0;;
-		o) OUT=${OPTARG};;
-                \?) exit 1;;
-        esac
-done
-shift `expr ${OPTIND} - 1`
-
-# Check if command is for creating control file and/or links to images.
-if [ $PROM -eq 1 -o $LINUX -eq 1 ] ; then
-	CF=$NCF
-	[ ! -f $CF ] || err "wont overwrite an existing control file ($CF)"
-	if [ $# -gt 0 ] ; then
-		D=$1
-		[ -d $D ] || err "cannot find directory $D"
-		[ $PROM -eq 0 ]  || set_prom_links
-		[ $LINUX -eq 0 ] || set_linux_links
-	fi
-	create_cf_header
-	[ $PROM -eq 0 ]  || create_cf_prom
-	[ $LINUX -eq 0 ] || create_cf_linux
-	[ ! -f ../idedisk ] || ln -s ../idedisk .
-	create_cf_memory
-	echo "  .. Basic control file created (in $CF). You might want to edit"
-	echo "     this file (at least, look at it)."
-	exit 0
-fi
-
-# Verify that the control file exists
-CF=${1:-$NCF}
-[ -f $CF ] || err "No control file exists. For help, type: $0 -H"
-
-# Build the .cf files from the user control file. The .cf file is
-# identical except that the actual start & load addresses are inserted
-# into the file. In addition, the FPROM commands for configuring memory
-# and LIDs are generated. 
-
-rm -f .cf .cf1 .cf2
-awk '
-function strtonum(n) {
-	 if (substr(n,1,2) != "0x")
-	 	return int(n)
-	 n = substr(n,3)
-	 r=0
-	 while (length(n) > 0) {
-	 	r = r*16+(index("0123456789abcdef", substr(n,1,1))-1)
-		n = substr(n,2)
-	 }
-	 return r
-	}
-/^#/   	{next}
-/^$/	{next}
-/^setenv *LOADPC/               {loadpc = $3; next}
-/^setenv *node.._cpu_config/	{n=int(substr($2,5,2)); cpuconf[n] = strtonum($3); print; next}
-/^setenv *node.._memory_config/	{n=int(substr($2,5,2)); memconf[n] = strtonum($3); print; next}
-/^setenv *node.._nasid/		{n=int(substr($2,5,2)); nasid[n] = strtonum($3); print; next}
-/^setenv *node._cpu_config/	{n=int(substr($2,5,1)); cpuconf[n] = strtonum($3); print; next}
-/^setenv *node._memory_config/	{n=int(substr($2,5,1)); memconf[n] = strtonum($3); print; next}
-/^setenv *node._nasid/		{n=int(substr($2,5,1)); nasid[n] = strtonum($3); print; next}
-		{print}
-END	{
-	 # Generate the memmap info that starts at the beginning of
-	 # the node the kernel was loaded on.
-	 loadnasid = nasid[0]
-	 cnode = 0
-	 for (i=0; i<128; i++) {
-		if (memconf[i] != "") {
-			printf "sm 0x%x%08x 0x%x%04x%04x\n", 
-				2*loadnasid, 8*cnodes+8, memconf[i], cpuconf[i], nasid[i]
-			cnodes++
-			cpus += substr("0112122312232334", cpuconf[i]+1,1)
-		}
-	 }
-	 printf "sm 0x%x00000000 0x%x%08x\n", 2*loadnasid, cnodes, cpus
-	 printf "setenv number_of_nodes %d\n", cnodes
-
-	 # Now set the starting PC for each cpu.
-	 cnode = 0
-	 lowcpu=-1
-	 for (i=0; i<128; i++) {
-		if (memconf[i] != "") {
-			printf "setnode %d\n", cnode
-			conf = cpuconf[i]
-			for (j=0; j<4; j++) {
-				if (conf != int(conf/2)*2) {
-	 				printf "setcpu %d\n", j
-					if (length(loadpc) == 18)
-						printf "sr pc %s\n", loadpc
-					else
-						printf "sr pc 0x%x%s\n", 2*loadnasid, substr(loadpc,3)
-					if (lowcpu == -1)
-						lowcpu = j
-				}
-				conf = int(conf/2)
-			}
-			cnode++
-		}
-	 }
-	 printf "setnode 0\n"
-	 printf "setcpu %d\n", lowcpu
-	}
-' <$CF >.cf
-
-# Now build the .cf1 & .cf2 control files.
-CF2_LINES="^sm |^break |^run |^si |^quit |^symbols "
-egrep  "$CF2_LINES" .cf >.cf2
-egrep -v "$CF2_LINES" .cf >.cf1
-if [ $STEPCNT -ne 0 ] ; then
-	echo "s $STEPCNT" >>.cf2
-	echo "lastpc 1000" >>.cf2
-	echo "q" >>.cf2
-fi
-if [ -f vmlinux.sym ] ; then
-	awk '/ _start$/ {print "sr g 9 0x" $3}' < vmlinux.sym >> .cf2
-fi
-echo "script-on $OUT" >>.cf2
-
-# Now start medusa....
-if [ $FMTMED -ne 0 ] ; then
-	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 |  fmtmedusa
-elif [ $STEPCNT -eq 0 ] ; then
-	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 
-else
-	$MEDUSA -system mpsn1 -c .cf1 -i .cf2 2>&1 
-fi
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/Makefile linux-2.4.22-pre10/arch/ia64/sn/io/Makefile
--- linux-2.4.21/arch/ia64/sn/io/Makefile	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/Makefile	2003-08-01 13:31:58.000000000 +0000
@@ -3,31 +3,34 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+# Copyright (C) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
 #
 # Makefile for the sn kernel routines.
 
 EXTRA_CFLAGS    := -DLITTLE_ENDIAN
 
-ifdef CONFIG_IA64_SGI_SN2
 EXTRA_CFLAGS    += -DSHUB_SWAP_WAR
-endif
 
 O_TARGET := sgiio.o
  
-export-objs := hcl.o pci_dma.o
+obj-y :=	sgi_if.o xswitch.o sgi_io_sim.o \
+		cdl.o io.o
+
+obj-y		+= sn2/snio.o machvec/snio.o \
+	           drivers/snio.o platform_init/snio.o
 
-obj-y :=	stubs.o sgi_if.o xswitch.o klgraph_hack.o \
-		hcl.o labelcl.o invent.o sgi_io_sim.o \
-		klgraph_hack.o hcl_util.o cdl.o hubdev.o hubspc.o \
-		alenlist.o pci.o pci_dma.o ate_utils.o \
-		ifconfig_net.o io.o ifconfig_bus.o
-
-obj-$(CONFIG_IA64_SGI_SN1)	+= sn1/snio.o
-obj-$(CONFIG_IA64_SGI_SN2)	+= sn2/snio.o
-obj-$(CONFIG_PCIBA)		+= pciba.o
+ifdef CONFIG_HWGFS_FS
+obj-$(CONFIG_HWGFS_FS)		+= hwgfs/snio.o
+else
+obj-$(CONFIG_DEVFS_FS)		+= hwgdfs/snio.o
+endif
 
-subdir-$(CONFIG_IA64_SGI_SN1)	+= sn1
-subdir-$(CONFIG_IA64_SGI_SN2)	+= sn2
+subdir-y			+= sn2 machvec drivers platform_init
+
+ifdef CONFIG_HWGFS_FS
+subdir-$(CONFIG_HWGFS_FS)	+= hwgfs
+else
+subdir-$(CONFIG_DEVFS_FS)	+= hwgdfs
+endif
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/alenlist.c linux-2.4.22-pre10/arch/ia64/sn/io/alenlist.c
--- linux-2.4.21/arch/ia64/sn/io/alenlist.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/alenlist.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,899 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/* Implementation of Address/Length Lists. */
-
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/mmzone.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/alenlist.h>
-
-/*
- * Logically, an Address/Length List is a list of Pairs, where each pair
- * holds an Address and a Length, all in some Address Space.  In this
- * context, "Address Space" is a particular Crosstalk Widget address
- * space, a PCI device address space, a VME bus address space, a
- * physical memory address space, etc.
- *
- * The main use for these Lists is to provide a single mechanism that
- * describes where in an address space a DMA occurs.  This allows the
- * various I/O Bus support layers to provide a single interface for
- * DMA mapping and DMA translation without regard to how the DMA target
- * was specified by upper layers.  The upper layers commonly specify a 
- * DMA target via a buf structure page list, a kernel virtual address,
- * a user virtual address, a vector of addresses (a la uio and iov), 
- * or possibly a pfn list.
- *
- * Address/Length Lists also enable drivers to take advantage of their
- * inate scatter/gather capabilities in systems where some address
- * translation may be required between bus adapters.  The driver forms
- * a List that represents physical memory targets.  This list is passed
- * to the various adapters, which apply various translations.  The final
- * list that's returned to the driver is in terms of its local address
- * address space -- addresses which can be passed off to a scatter/gather
- * capable DMA controller.
- *
- * The current implementation is intended to be useful both in kernels
- * that support interrupt threads (INTR_KTHREAD) and in systems that do
- * not support interrupt threads.  Of course, in the latter case, some
- * interfaces can be called only within a suspendable context.
- *
- * Basic operations on Address/Length Lists include:
- *	alenlist_create		Create a list
- *	alenlist_clear		Clear a list
- *	alenlist_destroy	Destroy a list
- *	alenlist_append		Append a Pair to the end of a list
- *	alenlist_replace	Replace a Pair in the middle of a list
- *	alenlist_get		Get an Address/Length Pair from a list
- *	alenlist_size		Return the number of Pairs in a list
- *	alenlist_concat		Append one list to the end of another
- *	alenlist_clone		Create a new copy of a list
- *
- * Operations that convert from upper-level specifications to Address/
- * Length Lists currently include:
- *	kvaddr_to_alenlist	Convert from a kernel virtual address
- *	uvaddr_to_alenlist	Convert from a user virtual address
- *	buf_to_alenlist		Convert from a buf structure
- *	alenlist_done		Tell system that we're done with an alenlist
- *				obtained from a conversion.
- * Additional convenience operations:
- *	alenpair_init		Create a list and initialize it with a Pair
- *	alenpair_get		Peek at the first pair on a List
- *
- * A supporting type for Address/Length Lists is an alenlist_cursor_t.  A
- * cursor marks a position in a List, and determines which Pair is fetched
- * by alenlist_get.
- *	alenlist_cursor_create	Allocate and initialize a cursor
- *	alenlist_cursor_destroy	Free space consumed by a cursor
- *	alenlist_cursor_init	(Re-)Initialize a cursor to point 
- *				to the start of a list
- *	alenlist_cursor_clone	Clone a cursor (at the current offset)
- *	alenlist_cursor_offset	Return the number of bytes into
- *				a list that this cursor marks
- * Multiple cursors can point at various points into a List.  Also, each
- * list maintains one "internal cursor" which may be updated by alenlist_clear
- * and alenlist_get.  If calling code simply wishes to scan sequentially
- * through a list starting at the beginning, and if it is the only user of
- * a list, it can rely on this internal cursor rather than managing a 
- * separate explicit cursor.
- *
- * The current implementation allows callers to allocate both cursors and
- * the lists as local stack (structure) variables.  This allows for some
- * extra efficiency at the expense of forward binary compatibility.  It 
- * is recommended that customer drivers refrain from local allocation.
- * In fact, we likely will choose to move the structures out of the public 
- * header file into a private place in order to discourage this usage.
- *
- * Currently, no locking is provided by the alenlist implementation.
- *
- * Implementation notes:
- * For efficiency, Pairs are grouped into "chunks" of, say, 32 Pairs
- * and a List consists of some number of these chunks.  Chunks are completely
- * invisible to calling code.  Chunks should be large enough to hold most
- * standard-sized DMA's, but not so large that they consume excessive space.
- *
- * It is generally expected that Lists will be constructed at one time and
- * scanned at a later time.  It is NOT expected that drivers will scan
- * a List while the List is simultaneously extended, although this is
- * theoretically possible with sufficient upper-level locking.
- *
- * In order to support demands of Real-Time drivers and in order to support
- * swapping under low-memory conditions, we support the concept of a
- * "pre-allocated fixed-sized List".  After creating a List with 
- * alenlist_create, a driver may explicitly grow the list (via "alenlist_grow")
- * to a specific number of Address/Length pairs.  It is guaranteed that future 
- * operations involving this list will never automatically grow the list 
- * (i.e. if growth is ever required, the operation will fail).  Additionally, 
- * operations that use alenlist's (e.g. DMA operations) accept a flag which 
- * causes processing to take place "in-situ"; that is, the input alenlist 
- * entries are replaced with output alenlist entries.  The combination of 
- * pre-allocated Lists and in-situ processing allows us to avoid the 
- * potential deadlock scenario where we sleep (waiting for memory) in the 
- * swap out path.
- *
- * For debugging, we track the number of allocated Lists in alenlist_count
- * the number of allocated chunks in alenlist_chunk_count, and the number
- * of allocate cursors in alenlist_cursor_count.  We also provide a debug 
- * routine, alenlist_show, which dumps the contents of an Address/Length List.
- *
- * Currently, Lists are formed by drivers on-demand.  Eventually, we may
- * associate an alenlist with a buf structure and keep it up to date as
- * we go along.  In that case, buf_to_alenlist simply returns a pointer
- * to the existing List, and increments the Lists's reference count.
- * alenlist_done would decrement the reference count and destroys the List
- * if it was the last reference.
- *
- * Eventually alenlist's may allow better support for user-level scatter/
- * gather operations (e.g. via readv/writev):  With proper support, we
- * could potentially handle a vector of reads with a single scatter/gather
- * DMA operation.  This could be especially useful on NUMA systems where
- * there's more of a reason for users to use vector I/O operations.
- *
- * Eventually, alenlist's may replace kaio lists, vhand page lists,
- * buffer cache pfdat lists, DMA page lists, etc.
- */
-
-/* Opaque data types */
-
-/* An Address/Length pair.  */
-typedef struct alen_s {
-	alenaddr_t	al_addr;
-	size_t		al_length;
-} alen_t;
-
-/* 
- * Number of elements in one chunk of an Address/Length List.
- *
- * This size should be sufficient to hold at least an "average" size
- * DMA request.  Must be at least 1, and should be a power of 2,
- * for efficiency.
- */
-#define ALEN_CHUNK_SZ ((512*1024)/NBPP)
-
-/*
- * A fixed-size set of Address/Length Pairs.  Chunks of Pairs are strung together 
- * to form a complete Address/Length List.  Chunking is entirely hidden within the 
- * alenlist implementation, and it simply makes allocation and growth of lists more 
- * efficient.
- */
-typedef struct alenlist_chunk_s {
-	alen_t			alc_pair[ALEN_CHUNK_SZ];/* list of addr/len pairs */
-	struct alenlist_chunk_s *alc_next;		/* point to next chunk of pairs */
-} *alenlist_chunk_t;
-
-/* 
- * An Address/Length List.  An Address/Length List is allocated with alenlist_create.  
- * Alternatively, a list can be allocated on the stack (local variable of type 
- * alenlist_t) and initialized with alenpair_init or with a combination of 
- * alenlist_clear and alenlist_append, etc.  Code which statically allocates these
- * structures loses forward binary compatibility!
- *
- * A statically allocated List is sufficiently large to hold ALEN_CHUNK_SZ pairs.
- */
-struct alenlist_s {
-	unsigned short		al_flags;
-	unsigned short		al_logical_size;	/* logical size of list, in pairs */
-	unsigned short		al_actual_size;		/* actual size of list, in pairs */
-	struct alenlist_chunk_s	*al_last_chunk;		/* pointer to last logical chunk */
-	struct alenlist_cursor_s al_cursor;		/* internal cursor */
-	struct alenlist_chunk_s	al_chunk;		/* initial set of pairs */
-	alenaddr_t		al_compaction_address;	/* used to compact pairs */
-};
-
-/* al_flags field */
-#define AL_FIXED_SIZE	0x1	/* List is pre-allocated, and of fixed size */
-
-
-zone_t *alenlist_zone = NULL;
-zone_t *alenlist_chunk_zone = NULL;
-zone_t *alenlist_cursor_zone = NULL;
-
-#if DEBUG
-int alenlist_count=0;		/* Currently allocated Lists */
-int alenlist_chunk_count = 0;	/* Currently allocated chunks */
-int alenlist_cursor_count = 0;	/* Currently allocate cursors */
-#define INCR_COUNT(ptr) atomic_inc((ptr));
-#define DECR_COUNT(ptr) atomic_dec((ptr));
-#else
-#define INCR_COUNT(ptr)
-#define DECR_COUNT(ptr)
-#endif /* DEBUG */
-
-#if DEBUG
-static void alenlist_show(alenlist_t);
-#endif /* DEBUG */
-
-/*
- * Initialize Address/Length List management.  One time initialization.
- */
-void
-alenlist_init(void)
-{
-	alenlist_zone = snia_kmem_zone_init(sizeof(struct alenlist_s), "alenlist");
-	alenlist_chunk_zone = snia_kmem_zone_init(sizeof(struct alenlist_chunk_s), "alchunk");
-	alenlist_cursor_zone = snia_kmem_zone_init(sizeof(struct alenlist_cursor_s), "alcursor");
-#if DEBUG
-	idbg_addfunc("alenshow", alenlist_show);
-#endif /* DEBUG */
-}
-
-
-/*
- * Initialize an Address/Length List cursor.
- */
-static void
-do_cursor_init(alenlist_t alenlist, alenlist_cursor_t cursorp)
-{
-	cursorp->al_alenlist = alenlist;
-	cursorp->al_offset = 0;
-	cursorp->al_chunk = &alenlist->al_chunk;
-	cursorp->al_index = 0;
-	cursorp->al_bcount = 0;
-}
-
-
-/*
- * Create an Address/Length List, and clear it.
- * Set the cursor to the beginning.
- */
-alenlist_t 
-alenlist_create(unsigned flags)
-{
-	alenlist_t alenlist;
-
-	alenlist = snia_kmem_zone_alloc(alenlist_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
-	if (alenlist) {
-		INCR_COUNT(&alenlist_count);
-
-		alenlist->al_flags = 0;
-		alenlist->al_logical_size = 0;
-		alenlist->al_actual_size = ALEN_CHUNK_SZ;
-		alenlist->al_last_chunk = &alenlist->al_chunk;
-		alenlist->al_chunk.alc_next = NULL;
-		do_cursor_init(alenlist, &alenlist->al_cursor);
-	}
-
-	return(alenlist);
-}
-
-
-/*
- * Grow an Address/Length List so that all resources needed to contain
- * the specified number of Pairs are pre-allocated.  An Address/Length
- * List that has been explicitly "grown" will never *automatically*
- * grow, shrink, or be destroyed.
- *
- * Pre-allocation is useful for Real-Time drivers and for drivers that
- * may be used along the swap-out path and therefore cannot afford to 
- * sleep until memory is freed.
- * 
- * The cursor is set to the beginning of the list.
- */
-int
-alenlist_grow(alenlist_t alenlist, size_t npairs)
-{
-	/* 
-	 * This interface should be used relatively rarely, so
-	 * the implementation is kept simple: We clear the List,
-	 * then append npairs bogus entries.  Finally, we mark
-	 * the list as FIXED_SIZE and re-initialize the internal
-	 * cursor.
-	 */
-
-	/* 
-	 * Temporarily mark as non-fixed size, since we're about
-	 * to shrink and expand it.
-	 */
-	alenlist->al_flags &= ~AL_FIXED_SIZE;
-
-	/* Free whatever was in the alenlist. */
-	alenlist_clear(alenlist);
-
-	/* Allocate everything that we need via automatic expansion. */
-	while (npairs--)
-		if (alenlist_append(alenlist, 0, 0, AL_NOCOMPACT) == ALENLIST_FAILURE)
-			return(ALENLIST_FAILURE);
-
-	/* Now, mark as FIXED_SIZE */
-	alenlist->al_flags |= AL_FIXED_SIZE;
-
-	/* Clear out bogus entries */
-	alenlist_clear(alenlist);
-
-	/* Initialize internal cursor to the beginning */
-	do_cursor_init(alenlist, &alenlist->al_cursor);
-
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Clear an Address/Length List so that it holds no pairs.
- */
-void
-alenlist_clear(alenlist_t alenlist)
-{
-	alenlist_chunk_t chunk, freechunk;
-
-	/*
-	 * If this List is not FIXED_SIZE, free all the
-	 * extra chunks.
-	 */
-	if (!(alenlist->al_flags & AL_FIXED_SIZE)) {
-		/* First, free any extension alenlist chunks */
-		chunk = alenlist->al_chunk.alc_next;
-		while (chunk) {
-			freechunk = chunk;
-			chunk = chunk->alc_next;
-			snia_kmem_zone_free(alenlist_chunk_zone, freechunk);
-			DECR_COUNT(&alenlist_chunk_count);
-		}
-		alenlist->al_actual_size = ALEN_CHUNK_SZ;
-		alenlist->al_chunk.alc_next = NULL;
-	}
-
-	alenlist->al_logical_size = 0;
-	alenlist->al_last_chunk = &alenlist->al_chunk;
-	do_cursor_init(alenlist, &alenlist->al_cursor);
-}
-
-
-/*
- * Create and initialize an Address/Length Pair.
- * This is intended for degenerate lists, consisting of a single 
- * address/length pair.
- */
-alenlist_t
-alenpair_init(	alenaddr_t address, 
-		size_t length)
-{
-	alenlist_t alenlist;
-
-	alenlist = alenlist_create(0);
-
-	alenlist->al_logical_size = 1;
-	ASSERT(alenlist->al_last_chunk == &alenlist->al_chunk);
-	alenlist->al_chunk.alc_pair[0].al_length = length;
-	alenlist->al_chunk.alc_pair[0].al_addr = address;
-
-	return(alenlist);
-}
-
-/*
- * Return address/length from a degenerate (1-pair) List, or
- * first pair from a larger list.  Does NOT update the internal cursor,
- * so this is an easy way to peek at a start address.
- */
-int
-alenpair_get(	alenlist_t alenlist,
-		alenaddr_t *address,
-		size_t *length)
-{
-	if (alenlist->al_logical_size == 0)
-		return(ALENLIST_FAILURE);
-
-	*length = alenlist->al_chunk.alc_pair[0].al_length;
-	*address = alenlist->al_chunk.alc_pair[0].al_addr;
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Destroy an Address/Length List.
- */
-void 
-alenlist_destroy(alenlist_t alenlist)
-{
-	if (alenlist == NULL)
-		return;
-
-	/* 
-	 * Turn off FIXED_SIZE so this List can be 
-	 * automatically shrunk.
-	 */
-	alenlist->al_flags &= ~AL_FIXED_SIZE;
-
-	/* Free extension chunks first */
-	if (alenlist->al_chunk.alc_next)
-		alenlist_clear(alenlist);
-
-	/* Now, free the alenlist itself */
-	snia_kmem_zone_free(alenlist_zone, alenlist);
-	DECR_COUNT(&alenlist_count);
-}
-
-/*
- * Release an Address/Length List.
- * This is in preparation for a day when alenlist's may be longer-lived, and
- * perhaps associated with a buf structure.  We'd add a reference count, and
- * this routine would decrement the count.  For now, we create alenlist's on
- * on demand and free them when done.  If the driver is not explicitly managing
- * a List for its own use, it should call alenlist_done rather than alenlist_destroy.
- */
-void
-alenlist_done(alenlist_t alenlist)
-{
-	alenlist_destroy(alenlist);
-}
-
-
-/*
- * Append another address/length to the end of an Address/Length List,
- * growing the list if permitted and necessary.
- *
- * Returns: SUCCESS/FAILURE
- */
-int 
-alenlist_append(	alenlist_t alenlist, 		/* append to this list */
-			alenaddr_t address, 		/* address to append */
-			size_t length,			/* length to append */
-			unsigned flags)
-{
-	alen_t *alenp;
-	int index, last_index;
-
-	index = alenlist->al_logical_size % ALEN_CHUNK_SZ;
-
-	if ((alenlist->al_logical_size > 0)) {
-		/*
-		 * See if we can compact this new pair in with the previous entry.
-		 * al_compaction_address holds that value that we'd need to see
-		 * in order to compact.
-		 */
-		if (!(flags & AL_NOCOMPACT) &&
-		    (alenlist->al_compaction_address == address)) {
-			last_index = (alenlist->al_logical_size-1) % ALEN_CHUNK_SZ;
-			alenp = &(alenlist->al_last_chunk->alc_pair[last_index]);
-			alenp->al_length += length;
-			alenlist->al_compaction_address += length;
-			return(ALENLIST_SUCCESS);
-		}
-
-		/*
-		 * If we're out of room in this chunk, move to a new chunk.
-	 	 */
-		if (index == 0) {
-			if (alenlist->al_flags & AL_FIXED_SIZE) {
-				alenlist->al_last_chunk = alenlist->al_last_chunk->alc_next;
-
-				/* If we're out of space in a FIXED_SIZE List, quit. */
-				if (alenlist->al_last_chunk == NULL) {
-					ASSERT(alenlist->al_logical_size == alenlist->al_actual_size);
-					return(ALENLIST_FAILURE);
-				}
-			} else {
-				alenlist_chunk_t new_chunk;
-
-				new_chunk = snia_kmem_zone_alloc(alenlist_chunk_zone, 
-							flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
-
-				if (new_chunk == NULL)
-					return(ALENLIST_FAILURE);
-
-				alenlist->al_last_chunk->alc_next = new_chunk;
-				new_chunk->alc_next = NULL;
-				alenlist->al_last_chunk = new_chunk;
-				alenlist->al_actual_size += ALEN_CHUNK_SZ;
-				INCR_COUNT(&alenlist_chunk_count);
-			}
-		}
-	}
-
-	alenp = &(alenlist->al_last_chunk->alc_pair[index]);
-	alenp->al_addr = address;
-	alenp->al_length = length;
-	
-	alenlist->al_logical_size++;
-	alenlist->al_compaction_address = address + length;
-
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Replace an item in an Address/Length List.  Cursor is updated so
- * that alenlist_get will get the next item in the list.  This interface 
- * is not very useful for drivers; but it is useful to bus providers 
- * that need to translate between address spaced in situ.  The old Address
- * and Length are returned.
- */
-/* ARGSUSED */
-int
-alenlist_replace(	alenlist_t alenlist, 		/* in: replace in this list */
-			alenlist_cursor_t cursorp, 	/* inout: which item to replace */
-			alenaddr_t *addrp, 		/* inout: address */
-			size_t *lengthp,		/* inout: length */
-			unsigned flags)
-{
-	alen_t *alenp;
-	alenlist_chunk_t chunk;
-	unsigned int index;
-	size_t length;
-	alenaddr_t addr;
-
-	if ((addrp == NULL) || (lengthp == NULL))
-		return(ALENLIST_FAILURE);
-
-	if (alenlist->al_logical_size == 0)
-		return(ALENLIST_FAILURE);
-
-	addr = *addrp;
-	length = *lengthp;
-
-	/* 
-	 * If no cursor explicitly specified, use the Address/Length List's 
-	 * internal cursor.
-	 */
-	if (cursorp == NULL)
-		cursorp = &alenlist->al_cursor;
-
-	chunk = cursorp->al_chunk;
-	index = cursorp->al_index;
-
-	ASSERT(cursorp->al_alenlist == alenlist);
-	if (cursorp->al_alenlist != alenlist)
-		return(ALENLIST_FAILURE);
-
-	alenp = &chunk->alc_pair[index];
-
-	/* Return old values */
-	*addrp = alenp->al_length;
-	*lengthp = alenp->al_addr;
-
-	/* Set up new values */
-	alenp->al_length = length;
-	alenp->al_addr = addr;
-
-	/* Update cursor to point to next item */
-	cursorp->al_bcount = length;
-
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Initialize a cursor in order to walk an alenlist.
- * An alenlist_cursor always points to the last thing that was obtained
- * from the list.  If al_chunk is NULL, then nothing has yet been obtained.
- *
- * Note: There is an "internal cursor" associated with every Address/Length List.
- * For users that scan sequentially through a List, it is more efficient to
- * simply use the internal cursor.  The caller must insure that no other users
- * will simultaneously scan the List.  The caller can reposition the internal
- * cursor by calling alenlist_cursor_init with a NULL cursorp.
- */
-int
-alenlist_cursor_init(alenlist_t alenlist, size_t offset, alenlist_cursor_t cursorp)
-{
-	size_t byte_count;
-
-	if (cursorp == NULL)
-		cursorp = &alenlist->al_cursor;
-
-	/* Get internal cursor's byte count for use as a hint.
-	 *
-	 * If the internal cursor points passed the point that we're interested in,
-	 * we need to seek forward from the beginning.  Otherwise, we can seek forward
-	 * from the internal cursor.
-	 */
-	if ((offset > 0) &&
-	   ((byte_count = alenlist_cursor_offset(alenlist, (alenlist_cursor_t)NULL)) <= offset)) {
-		offset -= byte_count;
-		alenlist_cursor_clone(alenlist, NULL, cursorp);
-	} else
-		do_cursor_init(alenlist, cursorp);
-
-	/* We could easily speed this up, but it shouldn't be used very often. */
-	while (offset != 0) {
-		alenaddr_t addr;
-		size_t length;
-
-		if (alenlist_get(alenlist, cursorp, offset, &addr, &length, 0) != ALENLIST_SUCCESS)
-			return(ALENLIST_FAILURE);
-		offset -= length;
-	}
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Copy a cursor.  The source cursor is either an internal alenlist cursor
- * or an explicit cursor.
- */
-int
-alenlist_cursor_clone(	alenlist_t alenlist, 
-			alenlist_cursor_t cursorp_in, 
-			alenlist_cursor_t cursorp_out)
-{
-	ASSERT(cursorp_out);
-
-	if (alenlist && cursorp_in)
-		if (alenlist != cursorp_in->al_alenlist)
-			return(ALENLIST_FAILURE);
-
-	if (alenlist)
-		*cursorp_out = alenlist->al_cursor; /* small structure copy */
-	else if (cursorp_in)
-		*cursorp_out = *cursorp_in; /* small structure copy */
-	else
-		return(ALENLIST_FAILURE); /* no source */
-
-	return(ALENLIST_SUCCESS);
-}
-
-/*
- * Return the number of bytes passed so far according to the specified cursor.
- * If cursorp is NULL, use the alenlist's internal cursor.
- */
-size_t
-alenlist_cursor_offset(alenlist_t alenlist, alenlist_cursor_t cursorp)
-{
-	ASSERT(!alenlist || !cursorp || (alenlist == cursorp->al_alenlist));
-
-	if (cursorp == NULL) {
-		ASSERT(alenlist);
-		cursorp = &alenlist->al_cursor;
-	}
-
-	return(cursorp->al_offset);
-}
-
-/*
- * Allocate and initialize an Address/Length List cursor.
- */
-alenlist_cursor_t
-alenlist_cursor_create(alenlist_t alenlist, unsigned flags)
-{
-	alenlist_cursor_t cursorp;
-
-	ASSERT(alenlist != NULL);
-	cursorp = snia_kmem_zone_alloc(alenlist_cursor_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
-	if (cursorp) {
-		INCR_COUNT(&alenlist_cursor_count);
-		alenlist_cursor_init(alenlist, 0, cursorp);
-	}
-	return(cursorp);
-}
-
-/*
- * Free an Address/Length List cursor.
- */
-void
-alenlist_cursor_destroy(alenlist_cursor_t cursorp)
-{
-	DECR_COUNT(&alenlist_cursor_count);
-	snia_kmem_zone_free(alenlist_cursor_zone, cursorp);
-}
-
-
-/*
- * Fetch an address/length pair from an Address/Length List.  Update
- * the "cursor" so that next time this routine is called, we'll get
- * the next address range.  Never return a length that exceeds maxlength
- * (if non-zero).  If maxlength is a power of 2, never return a length 
- * that crosses a maxlength boundary.  [This may seem strange at first,
- * but it's what many drivers want.]
- *
- * Returns: SUCCESS/FAILURE
- */
-int
-alenlist_get(	alenlist_t alenlist, 		/* in: get from this list */
-		alenlist_cursor_t cursorp, 	/* inout: which item to get */
-		size_t	maxlength,		/* in: at most this length */
-		alenaddr_t *addrp, 		/* out: address */
-		size_t *lengthp,		/* out: length */
-		unsigned flags)
-{
-	alen_t *alenp;
-	alenlist_chunk_t chunk;
-	unsigned int index;
-	size_t bcount;
-	size_t length;
-
-	/* 
-	 * If no cursor explicitly specified, use the Address/Length List's 
-	 * internal cursor.
-	 */
-	if (cursorp == NULL) {
-		if (alenlist->al_logical_size == 0)
-			return(ALENLIST_FAILURE);
-		cursorp = &alenlist->al_cursor;
-	}
-
-	chunk = cursorp->al_chunk;
-	index = cursorp->al_index;
-	bcount = cursorp->al_bcount;
-
-	ASSERT(cursorp->al_alenlist == alenlist);
-	if (cursorp->al_alenlist != alenlist)
-		return(ALENLIST_FAILURE);
-
-	alenp = &chunk->alc_pair[index];
-	length = alenp->al_length - bcount;
-
-	/* Bump up to next pair, if we're done with this pair. */
-	if (length == 0) {
-		cursorp->al_bcount = bcount = 0;
-		cursorp->al_index = index = (index + 1) % ALEN_CHUNK_SZ;
-
-		/* Bump up to next chunk, if we're done with this chunk. */
-		if (index == 0) {
-			if (cursorp->al_chunk == alenlist->al_last_chunk)
-				return(ALENLIST_FAILURE);
-			chunk = chunk->alc_next;
-			ASSERT(chunk != NULL);
-		} else {
-			/* If in last chunk, don't go beyond end. */
-			if (cursorp->al_chunk == alenlist->al_last_chunk) {
-				int last_size = alenlist->al_logical_size % ALEN_CHUNK_SZ;
-				if (last_size && (index >= last_size))
-					return(ALENLIST_FAILURE);
-			}
-		}
-
-		alenp = &chunk->alc_pair[index];
-		length = alenp->al_length;
-	}
-
-	/* Constrain what we return according to maxlength */
-	if (maxlength) {
-		size_t maxlen1 = maxlength - 1;
-
-		if ((maxlength & maxlen1) == 0) /* power of 2 */
-			maxlength -= 
-			   ((alenp->al_addr + cursorp->al_bcount) & maxlen1);
-
-		length = min(maxlength, length);
-	}
-
-	/* Update the cursor, if desired. */
-	if (!(flags & AL_LEAVE_CURSOR)) {
-		cursorp->al_bcount += length;
-		cursorp->al_chunk = chunk;
-	}
-
-	*lengthp = length;
-	*addrp = alenp->al_addr + bcount;
-
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Return the number of pairs in the specified Address/Length List.
- * (For FIXED_SIZE Lists, this returns the logical size of the List, 
- * not the actual capacity of the List.)
- */
-int
-alenlist_size(alenlist_t alenlist)
-{
-	return(alenlist->al_logical_size);
-}
-
-
-/*
- * Concatenate two Address/Length Lists.
- */
-void
-alenlist_concat(alenlist_t from,
-		alenlist_t to)
-{
-	struct alenlist_cursor_s cursor;
-	alenaddr_t addr;
-	size_t length;
-
-	alenlist_cursor_init(from, 0, &cursor);
-
-	while(alenlist_get(from, &cursor, (size_t)0, &addr, &length, 0) == ALENLIST_SUCCESS)
-		alenlist_append(to, addr, length, 0);
-}
-
-/*
- * Create a copy of a list.
- * (Not all attributes of the old list are cloned.  For instance, if
- * a FIXED_SIZE list is cloned, the resulting list is NOT FIXED_SIZE.)
- */
-alenlist_t
-alenlist_clone(alenlist_t old_list, unsigned flags)
-{
-	alenlist_t new_list;
-
-	new_list = alenlist_create(flags);
-	if (new_list != NULL)
-		alenlist_concat(old_list, new_list);
-
-	return(new_list);
-}
-
-
-/* 
- * Convert a kernel virtual address to a Physical Address/Length List.
- */
-alenlist_t
-kvaddr_to_alenlist(alenlist_t alenlist, caddr_t kvaddr, size_t length, unsigned flags)
-{
-	alenaddr_t paddr;
-	long offset;
-	size_t piece_length;
-	int created_alenlist;
-
-	if (length <=0)
-		return(NULL);
-
-	/* If caller supplied a List, use it.  Otherwise, allocate one. */
-	if (alenlist == NULL) {
-		alenlist = alenlist_create(0);
-		created_alenlist = 1;
-	} else {
-		alenlist_clear(alenlist);
-		created_alenlist = 0;
-	}
-
-	paddr = kvtophys(kvaddr);
-	offset = poff(kvaddr);
-
-	/* Handle first page */
-	piece_length = min((size_t)(NBPP - offset), length);
-	if (alenlist_append(alenlist, paddr, piece_length, flags) == ALENLIST_FAILURE)
-		goto failure;
-	length -= piece_length;
-	kvaddr += piece_length;
-
-	/* Handle middle pages */
-	while (length >= NBPP) {
-		paddr = kvtophys(kvaddr);
-		if (alenlist_append(alenlist, paddr, NBPP, flags) == ALENLIST_FAILURE)
-			goto failure;
-		length -= NBPP;
-		kvaddr += NBPP;
-	}
-
-	/* Handle last page */
-	if (length) {
-		ASSERT(length < NBPP);
-		paddr = kvtophys(kvaddr);
-		if (alenlist_append(alenlist, paddr, length, flags) == ALENLIST_FAILURE)
-			goto failure;
-	}
-
-	alenlist_cursor_init(alenlist, 0, NULL);
-	return(alenlist);
-
-failure:
-	if (created_alenlist)
-		alenlist_destroy(alenlist);
-	return(NULL);
-}
-
-
-#if DEBUG
-static void
-alenlist_show(alenlist_t alenlist)
-{
-	struct alenlist_cursor_s cursor;
-	alenaddr_t addr;
-	size_t length;
-	int i = 0;
-
-	alenlist_cursor_init(alenlist, 0, &cursor);
-
-	qprintf("Address/Length List@0x%x:\n", alenlist);
-	qprintf("logical size=0x%x actual size=0x%x last_chunk at 0x%x\n", 
-		alenlist->al_logical_size, alenlist->al_actual_size, 
-		alenlist->al_last_chunk);
-	qprintf("cursor: chunk=0x%x index=%d offset=0x%x\n",
-		alenlist->al_cursor.al_chunk, 
-		alenlist->al_cursor.al_index,
-		alenlist->al_cursor.al_bcount);
-	while(alenlist_get(alenlist, &cursor, (size_t)0, &addr, &length, 0) == ALENLIST_SUCCESS)
-		qprintf("%d:\t0x%lx 0x%lx\n", ++i, addr, length);
-}
-#endif /* DEBUG */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/ate_utils.c linux-2.4.22-pre10/arch/ia64/sn/io/ate_utils.c
--- linux-2.4.21/arch/ia64/sn/io/ate_utils.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/ate_utils.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,205 +0,0 @@
-/* $Id: ate_utils.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/io.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_defs.h>
-#include <asm/sn/prio.h>
-#include <asm/sn/ioerror_handling.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/sn_private.h>
-
-#include <asm/sn/ate_utils.h>
-
-/*
- * Allocate the map needed to allocate the ATE entries.
- */
-struct map *
-atemapalloc(ulong_t mapsiz)
-{
-	struct map *mp;
-	ulong_t size;
-	struct a {
-		spinlock_t lock;
-		sv_t 	sema;
-	} *sync;
-
-	if (mapsiz == 0)
-		return(NULL);
-	size = sizeof(struct map) * (mapsiz + 2);
-	if ((mp = (struct map *) kmalloc(size, GFP_KERNEL)) == NULL)
-		return(NULL);
-	memset(mp, 0x0, size);
-
-	sync = kmalloc(sizeof(struct a), GFP_KERNEL);
-	if (sync == NULL) {
-		kfree(mp);
-		return(NULL);
-	}
-	memset(sync, 0x0, sizeof(struct a));
-
-	mutex_spinlock_init(&sync->lock);
-	sv_init( &(sync->sema), &(sync->lock), SV_MON_SPIN | SV_ORDER_FIFO /*| SV_INTS*/);
-	mp[1].m_size = (unsigned long) &sync->lock;
-	mp[1].m_addr = (unsigned long) &sync->sema;
-	mapsize(mp) = mapsiz - 1;
-	return(mp);
-}
-
-/*
- * free a map structure previously allocated via rmallocmap().
- */
-void
-atemapfree(struct map *mp)
-{
-	struct a {
-		spinlock_t lock;
-		sv_t 	sema;
-	};
-	/* ASSERT(sv_waitq(mapout(mp)) == 0); */
-	/* sv_destroy(mapout(mp)); */
-	spin_lock_destroy(maplock(mp));
-	kfree((void *)mp[1].m_size);
-	kfree(mp);
-}
-
-/*
- * Allocate 'size' units from the given map.
- * Return the base of the allocated space.
- * In a map, the addresses are increasing and the
- * list is terminated by a 0 size.
- * Algorithm is first-fit.
- */
-
-ulong_t
-atealloc(
-	struct map *mp,
-	size_t size)
-{
-	register unsigned int a;
-	register struct map *bp;
-	register unsigned long s;
-
-	ASSERT(size >= 0);
-
-	if (size == 0)
-		return((ulong_t) NULL);
-
-	s = mutex_spinlock(maplock(mp));
-
-	for (bp = mapstart(mp); bp->m_size; bp++) {
-		if (bp->m_size >= size) {
-			a = bp->m_addr;
-			bp->m_addr += size;
-			if ((bp->m_size -= size) == 0) {
-				do {
-					bp++;
-					(bp-1)->m_addr = bp->m_addr;
-				} while ((((bp-1)->m_size) = (bp->m_size)));
-				mapsize(mp)++;
-			}
-
-			ASSERT(bp->m_size < 0x80000000);
-			mutex_spinunlock(maplock(mp), s);
-			return(a);
-		}
-	}
-
-	/*
-	 * We did not get what we need .. we cannot sleep .. 
-	 */
-	mutex_spinunlock(maplock(mp), s);
-	return(0);
-}
-
-/*
- * Free the previously allocated space a of size units into the specified map.
- * Sort ``a'' into map and combine on one or both ends if possible.
- * Returns 0 on success, 1 on failure.
- */
-void
-atefree(struct map *mp, size_t size, ulong_t a)
-{
-	register struct map *bp;
-	register unsigned int t;
-	register unsigned long s;
-
-	ASSERT(size >= 0);
-
-	if (size == 0)
-		return;
-
-	bp = mapstart(mp);
-	s = mutex_spinlock(maplock(mp));
-
-	for ( ; bp->m_addr<=a && bp->m_size!=0; bp++)
-		;
-	if (bp>mapstart(mp) && (bp-1)->m_addr+(bp-1)->m_size == a) {
-		(bp-1)->m_size += size;
-		if (bp->m_addr) {	
-			/* m_addr==0 end of map table */
-			ASSERT(a+size <= bp->m_addr);
-			if (a+size == bp->m_addr) { 
-
-				/* compress adjacent map addr entries */
-				(bp-1)->m_size += bp->m_size;
-				while (bp->m_size) {
-					bp++;
-					(bp-1)->m_addr = bp->m_addr;
-					(bp-1)->m_size = bp->m_size;
-				}
-				mapsize(mp)++;
-			}
-		}
-	} else {
-		if (a+size == bp->m_addr && bp->m_size) {
-			bp->m_addr -= size;
-			bp->m_size += size;
-		} else {
-			ASSERT(size);
-			if (mapsize(mp) == 0) {
-				mutex_spinunlock(maplock(mp), s);
-				printk("atefree : map overflow 0x%p Lost 0x%lx items at 0x%lx",
-						(void *)mp, size, a) ;
-				return ;
-			}
-			do {
-				t = bp->m_addr;
-				bp->m_addr = a;
-				a = t;
-				t = bp->m_size;
-				bp->m_size = size;
-				bp++;
-			} while ((size = t));
-			mapsize(mp)--;
-		}
-	}
-	mutex_spinunlock(maplock(mp), s);
-	/*
-	 * wake up everyone waiting for space
-	 */
-	if (mapout(mp))
-		;
-		/* sv_broadcast(mapout(mp)); */
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/cdl.c linux-2.4.22-pre10/arch/ia64/sn/io/cdl.c
--- linux-2.4.21/arch/ia64/sn/io/cdl.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/cdl.c	2003-08-01 13:32:05.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/config.h>
@@ -18,9 +18,9 @@
 #include <asm/sn/xtalk/xbow.h>
 
 /* these get called directly in cdl_add_connpt in fops bypass hack */
-extern int pcibr_attach(devfs_handle_t);
-extern int xbow_attach(devfs_handle_t);
-extern int pic_attach(devfs_handle_t);
+extern int pcibr_attach(vertex_hdl_t);
+extern int xbow_attach(vertex_hdl_t);
+extern int pic_attach(vertex_hdl_t);
 
 
 /*
@@ -32,75 +32,20 @@
  *	IO Infrastructure Drivers e.g. pcibr.
  */
 
-struct cdl {
-    int		part_num;
-    int		mfg_num;
-    int (*attach) (devfs_handle_t);
-} dummy_reg;
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define MAX_SGI_IO_INFRA_DRVR 4
-#else
 #define MAX_SGI_IO_INFRA_DRVR 7
-#endif
+
 static struct cdl sgi_infrastructure_drivers[MAX_SGI_IO_INFRA_DRVR] =
 {
 	{ XBRIDGE_WIDGET_PART_NUM, XBRIDGE_WIDGET_MFGR_NUM, pcibr_attach /* &pcibr_fops  */},
 	{ BRIDGE_WIDGET_PART_NUM,  BRIDGE_WIDGET_MFGR_NUM,  pcibr_attach /* &pcibr_fops */},
-#ifndef CONFIG_IA64_SGI_SN1
 	{ PIC_WIDGET_PART_NUM_BUS0,  PIC_WIDGET_MFGR_NUM,   pic_attach /* &pic_fops */},
 	{ PIC_WIDGET_PART_NUM_BUS1,  PIC_WIDGET_MFGR_NUM,   pic_attach /* &pic_fops */},
-#endif
 	{ XXBOW_WIDGET_PART_NUM,   XXBOW_WIDGET_MFGR_NUM,   xbow_attach /* &xbow_fops */},
 	{ XBOW_WIDGET_PART_NUM,    XBOW_WIDGET_MFGR_NUM,    xbow_attach /* &xbow_fops */},
-#ifndef CONFIG_IA64_SGI_SN1
 	{ PXBOW_WIDGET_PART_NUM,   XXBOW_WIDGET_MFGR_NUM,   xbow_attach /* &xbow_fops */},
-#endif
 };
 
 /*
- * cdl_new:  Called by pciio and xtalk.
- */
-cdl_p
-cdl_new(char *name, char *k1str, char *k2str)
-{
-    /*
-     * Just return a dummy pointer.
-     */
-    return((cdl_p)&dummy_reg);
-}
-
-/*
- * cdl_del: Do nothing.
- */
-void
-cdl_del(cdl_p reg)
-{
-	return;
-}
-
-/*
- * cdl_add_driver: The driver part number and manufacturers number 
- * are statically initialized above.
- * 
-  Do nothing.
- */
-int
-cdl_add_driver(cdl_p reg, int key1, int key2, char *prefix, int flags, cdl_drv_f *func)
-{
-    return 0;
-}
-
-/*
- * cdl_del_driver: Not supported.
- */
-void
-cdl_del_driver(cdl_p reg, char *prefix, cdl_drv_f *func)
-{
-	return;
-}
-
-/*
  * cdl_add_connpt: We found a device and it's connect point.  Call the 
  * attach routine of that driver.
  *
@@ -112,8 +57,8 @@
  * vertices.
  */
 int
-cdl_add_connpt(cdl_p reg, int part_num, int mfg_num, 
-	       devfs_handle_t connpt, int drv_flags)
+cdl_add_connpt(int part_num, int mfg_num, 
+	       vertex_hdl_t connpt, int drv_flags)
 {
 	int i;
 	
@@ -121,7 +66,6 @@
 	 * Find the driver entry point and call the attach routine.
 	 */
 	for (i = 0; i < MAX_SGI_IO_INFRA_DRVR; i++) {
-
 		if ( (part_num == sgi_infrastructure_drivers[i].part_num) &&
 		   ( mfg_num == sgi_infrastructure_drivers[i].mfg_num) ) {
 			/*
@@ -139,73 +83,3 @@
 
 	return (0);
 }
-
-/*
- * cdl_del_connpt: Not implemented.
- */
-int
-cdl_del_connpt(cdl_p reg, int key1, int key2, devfs_handle_t connpt, int drv_flags)
-{
-
-	return(0);
-}
-
-/*
- *    cdl_iterate: Not Implemented.
- */
-void
-cdl_iterate(cdl_p reg,
-	    char *prefix,
-	    cdl_iter_f * func)
-{
-	return;
-}
-
-async_attach_t 
-async_attach_new(void)
-{
-
-	return(0);
-}
-
-void 
-async_attach_free(async_attach_t aa)
-{
-	return;
-}
-
-async_attach_t 
-async_attach_get_info(devfs_handle_t vhdl)
-{
-
-	return(0);
-}
-
-void            
-async_attach_add_info(devfs_handle_t vhdl, async_attach_t aa)
-{
-	return;
-
-}
-
-void            
-async_attach_del_info(devfs_handle_t vhdl)
-{
-	return;
-}
-
-void async_attach_signal_start(async_attach_t aa)
-{
-	return;
-}
-
-void async_attach_signal_done(async_attach_t aa)
-{
-	return;
-}
-
-void async_attach_waitall(async_attach_t aa)
-{
-	return;
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/drivers/Makefile linux-2.4.22-pre10/arch/ia64/sn/io/drivers/Makefile
--- linux-2.4.21/arch/ia64/sn/io/drivers/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/drivers/Makefile	2003-08-01 13:33:11.000000000 +0000
@@ -0,0 +1,18 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+O_TARGET := snio.o
+
+obj-y				+= hubdev.o ioconfig_bus.o ifconfig_net.o
+
+obj-$(CONFIG_PCIBA)		+= pciba.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/drivers/hubdev.c linux-2.4.22-pre10/arch/ia64/sn/io/drivers/hubdev.c
--- linux-2.4.21/arch/ia64/sn/io/drivers/hubdev.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/drivers/hubdev.c	2003-08-01 13:34:07.000000000 +0000
@@ -0,0 +1,100 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+
+struct hubdev_callout {
+        int (*attach_method)(vertex_hdl_t);
+        struct hubdev_callout *fp;
+};
+
+typedef struct hubdev_callout hubdev_callout_t;
+
+mutex_t hubdev_callout_mutex;
+static hubdev_callout_t *hubdev_callout_list;
+
+void
+hubdev_init(void)
+{
+	mutex_init(&hubdev_callout_mutex);
+        hubdev_callout_list = NULL;
+}
+        
+void
+hubdev_register(int (*attach_method)(vertex_hdl_t))
+{
+        hubdev_callout_t *callout;
+        
+        ASSERT(attach_method);
+
+        callout =  (hubdev_callout_t *)snia_kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP);
+        ASSERT(callout);
+        
+	mutex_lock(&hubdev_callout_mutex);
+        /*
+         * Insert at the end of the list
+         */
+        callout->fp = hubdev_callout_list;
+        hubdev_callout_list = callout;
+        callout->attach_method = attach_method;
+	mutex_unlock(&hubdev_callout_mutex);
+}
+
+int
+hubdev_unregister(int (*attach_method)(vertex_hdl_t))
+{
+        hubdev_callout_t **p;
+        
+        ASSERT(attach_method);
+   
+	mutex_lock(&hubdev_callout_mutex);
+        /*
+         * Remove registry element containing attach_method
+         */
+        for (p = &hubdev_callout_list; *p != NULL; p = &(*p)->fp) {
+                if ((*p)->attach_method == attach_method) {
+                        hubdev_callout_t* victim = *p;
+                        *p = (*p)->fp;
+                        kfree(victim);
+                        mutex_unlock(&hubdev_callout_mutex);
+                        return (0);
+                }
+        }
+        mutex_unlock(&hubdev_callout_mutex);
+        return (ENOENT);
+}
+
+
+int
+hubdev_docallouts(vertex_hdl_t hub)
+{
+        hubdev_callout_t *p;
+        int errcode;
+
+	mutex_lock(&hubdev_callout_mutex);
+        
+        for (p = hubdev_callout_list; p != NULL; p = p->fp) {
+                ASSERT(p->attach_method);
+                errcode = (*p->attach_method)(hub);
+                if (errcode != 0) {
+			mutex_unlock(&hubdev_callout_mutex);
+                        return (errcode);
+                }
+        }
+        mutex_unlock(&hubdev_callout_mutex);
+        return (0);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/drivers/ifconfig_net.c linux-2.4.22-pre10/arch/ia64/sn/io/drivers/ifconfig_net.c
--- linux-2.4.21/arch/ia64/sn/io/drivers/ifconfig_net.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/drivers/ifconfig_net.c	2003-08-01 13:30:35.000000000 +0000
@@ -0,0 +1,298 @@
+/* $Id: ifconfig_net.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ *  ifconfig_net - SGI's Persistent Network Device names.
+ *
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/sn/sgi.h>
+#include <linux/devfs_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/ifconfig_net.h>
+
+#define SGI_IFCONFIG_NET "SGI-PERSISTENT NETWORK DEVICE NAME DRIVER"
+#define SGI_IFCONFIG_NET_VERSION "1.0"
+
+/*
+ * Some Global definitions.
+ */
+static devfs_handle_t ifconfig_net_handle;
+static unsigned long ifconfig_net_debug;
+
+/*
+ * ifconfig_net_open - Opens the special device node "/devhw/.ifconfig_net".
+ */
+static int ifconfig_net_open(struct inode * inode, struct file * filp)
+{
+	if (ifconfig_net_debug) {
+        	printk("ifconfig_net_open called.\n");
+	}
+
+        return(0);
+
+}
+
+/*
+ * ifconfig_net_close - Closes the special device node "/devhw/.ifconfig_net".
+ */
+static int ifconfig_net_close(struct inode * inode, struct file * filp)
+{
+
+	if (ifconfig_net_debug) {
+        	printk("ifconfig_net_close called.\n");
+	}
+
+        return(0);
+}
+
+/*
+ * assign_ifname - Assign the next available interface name from the persistent list.
+ */
+void
+assign_ifname(struct net_device *dev,
+		  struct ifname_num *ifname_num)
+
+{
+
+	/*
+	 * Handle eth devices.
+	 */
+        if ( (memcmp(dev->name, "eth", 3) == 0) ) {
+		if (ifname_num->next_eth != -1) {
+			/*
+			 * Assign it the next available eth interface number. 
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "eth%d", (int)ifname_num->next_eth);
+			ifname_num->next_eth++;
+		} 
+
+                return;
+        }
+
+	/*
+	 * Handle fddi devices.
+	 */
+	if ( (memcmp(dev->name, "fddi", 4) == 0) ) {
+		if (ifname_num->next_fddi != -1) {
+			/*
+			 * Assign it the next available fddi interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "fddi%d", (int)ifname_num->next_fddi);
+			ifname_num->next_fddi++;
+		}
+
+		return;
+	}
+
+	/*
+	 * Handle hip devices.
+	 */
+	if ( (memcmp(dev->name, "hip", 3) == 0) ) {
+		if (ifname_num->next_hip != -1) {
+			/*
+			 * Assign it the next available hip interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "hip%d", (int)ifname_num->next_hip);
+			ifname_num->next_hip++;
+		}
+
+		return;
+	}
+
+	/*
+	 * Handle tr devices.
+	 */
+	if ( (memcmp(dev->name, "tr", 2) == 0) ) {
+		if (ifname_num->next_tr != -1) {
+			/*
+			 * Assign it the next available tr interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "tr%d", (int)ifname_num->next_tr);
+			ifname_num->next_tr++;
+		}
+
+		return;
+	}
+
+	/*
+	 * Handle fc devices.
+	 */
+	if ( (memcmp(dev->name, "fc", 2) == 0) ) {
+		if (ifname_num->next_fc != -1) {
+			/*
+			 * Assign it the next available fc interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "fc%d", (int)ifname_num->next_fc);
+			ifname_num->next_fc++;
+		}
+
+		return;
+	}
+}
+
+/*
+ * find_persistent_ifname: Returns the entry that was seen in previous boot.
+ */
+struct ifname_MAC *
+find_persistent_ifname(struct net_device *dev,
+	struct ifname_MAC *ifname_MAC)
+
+{
+
+	while (ifname_MAC->addr_len) {
+		if (memcmp(dev->dev_addr, ifname_MAC->dev_addr, dev->addr_len) == 0)
+			return(ifname_MAC);
+
+		ifname_MAC++;
+	}
+
+	return(NULL);
+}
+
+/*
+ * ifconfig_net_ioctl: ifconfig_net driver ioctl interface.
+ */
+static int ifconfig_net_ioctl(struct inode * inode, struct file * file,
+        unsigned int cmd, unsigned long arg)
+{
+
+	extern struct net_device *__dev_get_by_name(const char *);
+#ifdef CONFIG_NET
+	struct net_device *dev;
+	struct ifname_MAC *found;
+	char temp[64];
+#endif
+	struct ifname_MAC *ifname_MAC;
+	struct ifname_MAC *new_devices, *temp_new_devices;
+	struct ifname_num *ifname_num;
+	unsigned long size;
+
+
+	if (ifconfig_net_debug) {
+		printk("HCL: hcl_ioctl called.\n");
+	}
+
+	/*
+	 * Read in the header and see how big of a buffer we really need to 
+	 * allocate.
+	 */
+	ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num), 
+			GFP_KERNEL);
+	copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num));
+	size = ifname_num->size;
+	kfree(ifname_num);
+	ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL);
+	ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) );
+
+	copy_from_user( ifname_num, (char *) arg, size);
+	new_devices =  kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL);
+	temp_new_devices = new_devices;
+
+	memset(new_devices, 0, size - sizeof(struct ifname_num));
+
+#ifdef CONFIG_NET
+	/*
+	 * Go through the net device entries and make them persistent!
+	 */
+	for (dev = dev_base; dev != NULL; dev = dev->next) {
+		/*
+		 * Skip NULL entries or "lo"
+		 */
+		if ( (dev->addr_len == 0) || ( !strncmp(dev->name, "lo", strlen(dev->name))) ){
+			continue;
+		}
+
+		/*
+		 * See if we have a persistent interface name for this device.
+		 */
+		found = NULL;
+		found = find_persistent_ifname(dev, ifname_MAC);
+		if (found) {
+			strcpy(dev->name, found->name);
+		} else {
+			/* Never seen this before .. */
+			assign_ifname(dev, ifname_num);
+
+			/* 
+			 * Save the information for the next boot.
+			 */
+ 			sprintf(temp,"%s %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
+				dev->dev_addr[0],  dev->dev_addr[1],  dev->dev_addr[2],
+				dev->dev_addr[3],  dev->dev_addr[4],  dev->dev_addr[5]);
+			strcpy(temp_new_devices->name, dev->name);
+			temp_new_devices->addr_len = dev->addr_len;
+			memcpy(temp_new_devices->dev_addr, dev->dev_addr, dev->addr_len);
+			temp_new_devices++;
+		}
+		
+	}
+#endif
+
+	/*
+	 * Copy back to the User Buffer area any new devices encountered.
+	 */
+	copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, 
+			size - sizeof(struct ifname_num));
+
+	return(0);
+
+}
+
+struct file_operations ifconfig_net_fops = {
+	ioctl:ifconfig_net_ioctl,	/* ioctl */
+	open:ifconfig_net_open,		/* open */
+	release:ifconfig_net_close	/* release */
+};
+
+
+/*
+ * init_ifconfig_net() - Boot time initialization.  Ensure that it is called 
+ *	after devfs has been initialized.
+ *
+ */
+#ifdef MODULE
+int init_module (void)
+#else
+int __init init_ifconfig_net(void)
+#endif
+{
+	ifconfig_net_handle = NULL;
+	ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net",
+			0, DEVFS_FL_AUTO_DEVNUM,
+			0, 0,
+			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+			&ifconfig_net_fops, NULL);
+
+	if (ifconfig_net_handle == NULL) {
+		panic("Unable to create SGI PERSISTENT NETWORK DEVICE Name Driver.\n");
+	}
+
+	return(0);
+
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/drivers/ioconfig_bus.c linux-2.4.22-pre10/arch/ia64/sn/io/drivers/ioconfig_bus.c
--- linux-2.4.21/arch/ia64/sn/io/drivers/ioconfig_bus.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/drivers/ioconfig_bus.c	2003-08-01 13:32:39.000000000 +0000
@@ -0,0 +1,401 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ *  ioconfig_bus - SGI's Persistent PCI Bus Numbering.
+ *
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/pci.h>
+
+#include <asm/sn/sgi.h>
+#include <linux/devfs_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm//sn/sn_sal.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/ioconfig_bus.h>
+
+#define SGI_IOCONFIG_BUS "SGI-PERSISTENT PCI BUS NUMBERING"
+#define SGI_IOCONFIG_BUS_VERSION "1.0"
+
+/*
+ * Some Global definitions.
+ */
+static vertex_hdl_t ioconfig_bus_handle;
+static unsigned long ioconfig_bus_debug;
+
+#ifdef IOCONFIG_BUS_DEBUG
+#define DBG(x...)	printk(x)
+#else
+#define DBG(x...)
+#endif
+
+static u64 ioconfig_file;
+static u64 ioconfig_file_size;
+static u64 ioconfig_activated;
+static char ioconfig_kernopts[128];
+
+/*
+ * For debugging purpose .. hardcode a table ..
+ */
+struct  ascii_moduleid *ioconfig_bus_table;
+u64 ioconfig_bus_table_size;
+
+
+static int free_entry;
+static int new_entry;
+
+int next_basebus_number;
+
+void
+ioconfig_get_busnum(char *io_moduleid, int *bus_num)
+{
+	struct	ascii_moduleid  *temp;
+	int index;
+
+	DBG("ioconfig_get_busnum io_moduleid %s\n", io_moduleid);
+
+	*bus_num = -1;
+	temp = ioconfig_bus_table;
+	for (index = 0; index < free_entry; temp++, index++) {
+		if ( (io_moduleid[0] == temp->io_moduleid[0]) &&
+		     (io_moduleid[1] == temp->io_moduleid[1]) &&
+		     (io_moduleid[2] == temp->io_moduleid[2]) &&
+		     (io_moduleid[4] == temp->io_moduleid[4]) &&
+		     (io_moduleid[5] == temp->io_moduleid[5]) ) {
+			*bus_num = index * 0x10;
+			return;
+		}
+	}
+
+	/*
+	 * New IO Brick encountered.
+	 */
+	if (((int)io_moduleid[0]) == 0) {
+		DBG("ioconfig_get_busnum: Invalid Module Id given %s\n", io_moduleid);
+		return;
+	}
+
+	io_moduleid[3] = '#';
+	strcpy((char *)&(ioconfig_bus_table[free_entry].io_moduleid), io_moduleid);
+	*bus_num = free_entry * 0x10;
+	free_entry++;
+}
+
+static void
+dump_ioconfig_table(void)
+{
+
+	int index = 0;
+	struct ascii_moduleid *temp;
+
+	temp = ioconfig_bus_table;
+	while (index < free_entry) {
+		DBG("ASSCI Module ID %s\n", temp->io_moduleid);
+		temp++;
+		index++;
+	}
+}
+
+/*
+ * nextline
+ *	This routine returns the nextline in the buffer.
+ */
+int nextline(char *buffer, char **next, char *line)
+{
+
+	char *temp;
+
+	if (buffer[0] == 0x0) {
+		return(0);
+	}
+
+	temp = buffer;
+	while (*temp != 0) {
+		*line = *temp;
+		if (*temp != '\n'){
+			*line = *temp;
+			temp++; line++;
+		} else
+			break;
+	}
+
+	if (*temp == 0)
+		*next = temp;
+	else
+		*next = ++temp;
+
+	return(1);
+}
+
+/*
+ * build_pcibus_name
+ *	This routine parses the ioconfig contents read into
+ *	memory by ioconfig command in EFI and builds the
+ *	persistent pci bus naming table.
+ */
+void
+build_moduleid_table(char *file_contents, struct ascii_moduleid *table)
+{
+	/*
+	 * Read the whole file into memory.
+	 */
+	int rc;
+	char *name;
+	char *temp;
+	char *next;
+	char *current;
+	char *line;
+	struct ascii_moduleid *moduleid;
+
+	line = kmalloc(256, GFP_KERNEL);
+	memset(line, 0,256);
+	name = kmalloc(125, GFP_KERNEL);
+	memset(name, 0, 125);
+	moduleid = table;
+	current = file_contents;
+	while (nextline(current, &next, line)){
+
+		DBG("current 0x%lx next 0x%lx\n", current, next);
+
+		temp = line;
+		/*
+		 * Skip all leading Blank lines ..
+		 */
+		while (isspace(*temp))
+			if (*temp != '\n')
+				temp++;
+			else
+				break;
+
+		if (*temp == '\n') {
+			current = next;
+			memset(line, 0, 256);
+			continue;
+		}
+ 
+		/*
+		 * Skip comment lines
+		 */
+		if (*temp == '#') {
+			current = next;
+			memset(line, 0, 256);
+			continue;
+		}
+
+		/*
+		 * Get the next free entry in the table.
+		 */
+		rc = sscanf(temp, "%s", name);
+		strcpy(&moduleid->io_moduleid[0], name);
+		DBG("Found %s\n", name);
+		moduleid++;
+		free_entry++;
+		current = next;
+		memset(line, 0, 256);
+	}
+
+	new_entry = free_entry;
+	kfree(line);
+	kfree(name);
+
+	return;
+}
+
+void
+ioconfig_bus_init(void)
+{
+
+	struct ia64_sal_retval ret_stuff;
+	u64	*temp;
+	int	cnode;
+
+	DBG("ioconfig_bus_init called.\n");
+
+        for (cnode = 0; cnode < numnodes; cnode++) {
+		nasid_t nasid;
+		/*
+	 	 * Make SAL call to get the address of the bus configuration table.
+	 	 */
+		ret_stuff.status = (uint64_t)0;
+		ret_stuff.v0 = (uint64_t)0;
+		ret_stuff.v1 = (uint64_t)0;
+		ret_stuff.v2 = (uint64_t)0;
+		nasid = COMPACT_TO_NASID_NODEID(cnode);
+		SAL_CALL(ret_stuff, SN_SAL_BUS_CONFIG, 0, nasid, 0, 0, 0, 0, 0);
+		temp = (u64 *)TO_NODE_CAC(nasid, ret_stuff.v0);
+		ioconfig_file = *temp;
+		DBG("ioconfig_bus_init: Nasid %d ret_stuff.v0 0x%lx\n", nasid,
+			ret_stuff.v0);
+		if (ioconfig_file) {
+			ioconfig_file_size = ret_stuff.v1;
+			ioconfig_file = (ioconfig_file | CACHEABLE_MEM_SPACE);
+			ioconfig_activated = 1;
+			break;
+		}
+	}
+
+	DBG("ioconfig_bus_init: ret_stuff.v0 %p ioconfig_file %p %d\n",
+		ret_stuff.v0, (void *)ioconfig_file, (int)ioconfig_file_size);
+
+	ioconfig_bus_table = kmalloc( 512, GFP_KERNEL );
+	memset(ioconfig_bus_table, 0, 512);
+
+	/*
+	 * If ioconfig options are given on the bootline .. take it.
+	 */
+	if (*ioconfig_kernopts != '\0') {
+		/*
+		 * ioconfig="..." kernel options given.
+		 */
+		DBG("ioconfig_bus_init: Kernel Options given.\n");
+		(void) build_moduleid_table((char *)ioconfig_kernopts, ioconfig_bus_table);
+		(void) dump_ioconfig_table();
+		return;
+	}
+
+	if (ioconfig_activated) {
+		DBG("ioconfig_bus_init: ioconfig file given.\n");
+		(void) build_moduleid_table((char *)ioconfig_file, ioconfig_bus_table);
+		(void) dump_ioconfig_table();
+	} else {
+		DBG("ioconfig_bus_init: ioconfig command not executed in prom\n");
+	}
+
+}
+
+void
+ioconfig_bus_new_entries(void)
+{
+
+	
+	int index = 0;
+	struct ascii_moduleid *temp;
+
+	if ((ioconfig_activated) && (free_entry > new_entry)) {
+		printk("### Please add the following new IO Bricks Module ID \n");
+		printk("### to your Persistent Bus Numbering Config File\n");
+	} else
+		return;
+
+	index = new_entry;
+	temp = &ioconfig_bus_table[index];
+        while (index < free_entry) {
+                printk("%s\n", (char *)temp);
+		temp++;
+                index++;
+        }
+	printk("### End\n");
+
+}
+static int ioconfig_bus_ioctl(struct inode * inode, struct file * file,
+        unsigned int cmd, unsigned long arg)
+{
+
+	struct ioconfig_parm parm;
+
+	/*
+	 * Copy in the parameters.
+	 */
+	copy_from_user(&parm, (char *)arg, sizeof(struct ioconfig_parm));
+	parm.number = free_entry - new_entry;
+	parm.ioconfig_activated = ioconfig_activated;
+	copy_to_user((char *)arg, &parm, sizeof(struct ioconfig_parm));
+	copy_to_user((char *)parm.buffer, &ioconfig_bus_table[new_entry], sizeof(struct  ascii_moduleid) * (free_entry - new_entry));
+
+	return 0;
+}
+
+/*
+ * ioconfig_bus_open - Opens the special device node "/dev/hw/.ioconfig_bus".
+ */
+static int ioconfig_bus_open(struct inode * inode, struct file * filp)
+{
+	if (ioconfig_bus_debug) {
+        	DBG("ioconfig_bus_open called.\n");
+	}
+
+        return(0);
+
+}
+
+/*
+ * ioconfig_bus_close - Closes the special device node "/dev/hw/.ioconfig_bus".
+ */
+static int ioconfig_bus_close(struct inode * inode, struct file * filp)
+{
+
+	if (ioconfig_bus_debug) {
+        	DBG("ioconfig_bus_close called.\n");
+	}
+
+        return(0);
+}
+
+struct file_operations ioconfig_bus_fops = {
+	ioctl:ioconfig_bus_ioctl,
+	open:ioconfig_bus_open,		/* open */
+	release:ioconfig_bus_close	/* release */
+};
+
+
+/*
+ * init_ifconfig_bus() - Boot time initialization.  Ensure that it is called 
+ *	after devfs has been initialized.
+ *
+ */
+int init_ioconfig_bus(void)
+{
+	ioconfig_bus_handle = NULL;
+	ioconfig_bus_handle = hwgraph_register(hwgraph_root, ".ioconfig_bus",
+			0, DEVFS_FL_AUTO_DEVNUM,
+			0, 0,
+			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+			&ioconfig_bus_fops, NULL);
+
+	if (ioconfig_bus_handle == NULL) {
+		panic("Unable to create SGI PERSISTENT BUS NUMBERING Driver.\n");
+	}
+
+	return(0);
+
+}
+
+static int __init ioconfig_bus_setup (char *str)
+{
+
+	char *temp;
+
+	DBG("ioconfig_bus_setup: Kernel Options %s\n", str);
+
+	temp = (char *)ioconfig_kernopts;
+	memset(temp, 0, 128);
+	while ( (*str != '\0') && !isspace (*str) ) {
+		if (*str == ',') {
+			*temp = '\n';
+			temp++;
+			str++;
+			continue;
+		}
+		*temp = *str;
+		temp++;
+		str++;
+	}
+
+	return(0);
+		
+}
+__setup("ioconfig=", ioconfig_bus_setup);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/drivers/pciba.c linux-2.4.22-pre10/arch/ia64/sn/io/drivers/pciba.c
--- linux-2.4.21/arch/ia64/sn/io/drivers/pciba.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/drivers/pciba.c	2003-08-01 13:30:46.000000000 +0000
@@ -0,0 +1,945 @@
+/*
+ * arch/ia64/sn/io/pciba.c
+ *
+ * IRIX PCIBA-inspired user mode PCI interface
+ *
+ * requires: devfs
+ *
+ * device nodes show up in /dev/pci/BB/SS.F (where BB is the bus the
+ * device is on, SS is the slot the device is in, and F is the
+ * device's function on a multi-function card).
+ *
+ * when compiled into the kernel, it will only be initialized by the
+ * sgi sn1 specific initialization code.  in this case, device nodes
+ * are under /dev/hw/..../
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
+ *
+ * 03262001 - Initial version by Chad Talbott
+ */
+
+
+/* jesse's beefs:
+
+   register_pci_device should be documented
+   
+   grossness with do_swap should be documented
+   
+   big, gross union'ized node_data should be replaced with independent
+   structures
+
+   replace global list of nodes with global lists of resources.  could
+   use object oriented approach of allocating and cleaning up
+   resources.
+   
+*/
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <linux/pci.h>
+#include <linux/list.h>
+
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+#include <linux/raw.h>
+#include <linux/capability.h>
+
+#include <asm/uaccess.h>
+#include <asm/sn/sgi.h>
+#include <asm/io.h>
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+#include <asm/system.h>
+
+#include <asm/sn/pci/pciba.h>
+
+
+MODULE_DESCRIPTION("User mode PCI interface");
+MODULE_AUTHOR("Chad Talbott");
+
+
+#undef DEBUG_PCIBA
+/* #define DEBUG_PCIBA */
+
+#undef TRACE_PCIBA
+/* #define TRACE_PCIBA */
+
+#if defined(DEBUG_PCIBA)
+#  define DPRINTF(x...) printk(KERN_DEBUG x)
+#else
+#  define DPRINTF(x...)
+#endif
+
+#if defined(TRACE_PCIBA)
+#  if defined(__GNUC__)
+#    define TRACE()	printk(KERN_DEBUG "%s:%d:%s\n", \
+			       __FILE__, __LINE__, __FUNCTION__)
+#  else
+#    define TRACE()	printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__)
+#  endif
+#else
+#  define TRACE()
+#endif
+
+
+typedef enum { failure, success } status;
+typedef enum { false, true } boolean;
+
+
+/* major data structures:
+
+   struct node_data -
+   
+   	one for each file registered with devfs.  contains everything
+   	that any file's fops would need to know about.
+
+   struct dma_allocation -
+
+   	a single DMA allocation.  only the 'dma' nodes care about
+   	these.  they are there primarily to allow the driver to look
+   	up the kernel virtual address of dma buffers allocated by
+   	pci_alloc_consistent, as the application is only given the
+   	physical address (to program the device's dma, presumably) and
+   	cannot supply the kernel virtual address when freeing the
+   	buffer.
+
+	it's also useful to maintain a list of buffers allocated
+	through a specific node to allow some sanity checking by this
+	driver.  this prevents (for example) a broken application from
+	freeing buffers that it didn't allocate, or buffers allocated
+	on another node.
+   
+   global_node_list -
+
+   	a list of all nodes allocated.  this allows the driver to free
+   	all the memory it has 'kmalloc'd in case of an error, or on
+   	module removal.
+
+   global_dma_list -
+
+        a list of all dma buffers allocated by this driver.  this
+	allows the driver to 'pci_free_consistent' all buffers on
+	module removal or error.
+
+*/
+
+
+struct node_data {
+	/* flat list of all the device nodes.  makes it easy to free
+	   them all when we're unregistered */
+	struct list_head global_node_list;
+	vertex_hdl_t devfs_handle;
+
+	void (* cleanup)(struct node_data *);
+
+	union {
+		struct {
+			struct pci_dev * dev;
+			struct list_head dma_allocs;
+			boolean mmapped;
+		} dma;
+		struct {
+			struct pci_dev * dev;
+			u32 saved_rom_base_reg;
+			boolean mmapped;
+		} rom;
+		struct {
+			struct resource * res;
+		} base;
+		struct {
+			struct pci_dev * dev;
+		} config;
+	} u;
+};
+
+struct dma_allocation {
+	struct list_head list;
+
+	dma_addr_t handle;
+	void * va;
+	size_t size;
+};
+
+
+static LIST_HEAD(global_node_list);
+static LIST_HEAD(global_dma_list);
+
+
+/* module entry points */
+int __init pciba_init(void);
+void __exit pciba_exit(void);
+
+static status __init register_with_devfs(void);
+static void __exit unregister_with_devfs(void);
+
+static status __init register_pci_device(vertex_hdl_t device_dir_handle,
+					 struct pci_dev * dev);
+
+/* file operations */
+static int generic_open(struct inode * inode, struct file * file);
+static int rom_mmap(struct file * file, struct vm_area_struct * vma);
+static int rom_release(struct inode * inode, struct file * file);
+static int base_mmap(struct file * file, struct vm_area_struct * vma);
+static int config_ioctl(struct inode * inode, struct file * file, 
+			unsigned int cmd, 
+			unsigned long arg);
+static int dma_ioctl(struct inode * inode, struct file * file, 
+		     unsigned int cmd, 
+		     unsigned long arg);
+static int dma_mmap(struct file * file, struct vm_area_struct * vma);
+
+/* support routines */
+static int mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va);
+static int mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va);
+
+#ifdef DEBUG_PCIBA
+static void dump_nodes(struct list_head * nodes);
+static void dump_allocations(struct list_head * dalp);
+#endif
+
+/* file operations for each type of node */
+static struct file_operations rom_fops = {
+	owner:		THIS_MODULE,
+	mmap:		rom_mmap,
+	open:		generic_open,
+	release:	rom_release
+};
+ 
+
+static struct file_operations base_fops = {
+	owner:		THIS_MODULE,
+	mmap:		base_mmap,
+	open:		generic_open
+};
+
+
+static struct file_operations config_fops = {
+	owner:		THIS_MODULE,
+	ioctl:		config_ioctl,
+	open:		generic_open
+};	
+
+static struct file_operations dma_fops = {
+	owner:		THIS_MODULE,
+	ioctl:		dma_ioctl,
+	mmap:		dma_mmap,
+	open:		generic_open
+};	
+
+
+module_init(pciba_init);
+module_exit(pciba_exit);
+
+
+int __init
+pciba_init(void)
+{
+	if (!ia64_platform_is("sn2"))
+		return -ENODEV;
+
+	TRACE();
+
+	if (register_with_devfs() == failure)
+		return 1; /* failure */
+
+	printk("PCIBA (a user mode PCI interface) initialized.\n");
+
+	return 0; /* success */
+}
+
+
+void __exit
+pciba_exit(void)
+{
+	TRACE();
+
+	/* FIXME: should also free all that memory that we allocated
+           ;) */
+	unregister_with_devfs();
+}
+
+
+# if 0
+static void __exit
+free_nodes(void)
+{
+	struct node_data * nd;
+	
+	TRACE();
+
+	list_for_each(nd, &node_list) {
+		kfree(list_entry(nd, struct nd, node_list));
+	}
+}
+#endif
+
+
+static vertex_hdl_t pciba_devfs_handle;
+
+
+extern vertex_hdl_t
+devfn_to_vertex(unsigned char busnum, unsigned int devfn);
+
+static status __init
+register_with_devfs(void)
+{
+	struct pci_dev * dev;
+	vertex_hdl_t device_dir_handle;
+
+	TRACE();
+
+	/* FIXME: don't forget /dev/.../pci/mem & /dev/.../pci/io */
+
+	pci_for_each_dev(dev) {
+		device_dir_handle = devfn_to_vertex(dev->bus->number,
+						    dev->devfn);
+		if (device_dir_handle == NULL)
+			return failure;
+	
+		if (register_pci_device(device_dir_handle, dev) == failure) {
+			hwgraph_vertex_destroy(pciba_devfs_handle);
+			return failure;
+		}
+	}
+
+	return success;
+}
+
+static void __exit
+unregister_with_devfs(void)
+{
+	struct list_head * lhp;
+	struct node_data * nd;
+	
+	TRACE();
+
+	list_for_each(lhp, &global_node_list) {
+		nd = list_entry(lhp, struct node_data, global_node_list);
+		hwgraph_vertex_destroy(nd->devfs_handle);
+	}
+
+}
+
+
+struct node_data * new_node(void)
+{
+	struct node_data * node;
+	
+	TRACE();
+	
+	node = kmalloc(sizeof(struct node_data), GFP_KERNEL);
+	if (node == NULL)
+		return NULL;
+	list_add(&node->global_node_list, &global_node_list);
+	return node;
+}
+
+
+void dma_cleanup(struct node_data * dma_node)
+{
+	TRACE();
+
+	/* FIXME: should free these allocations */
+#ifdef DEBUG_PCIBA
+	dump_allocations(&dma_node->u.dma.dma_allocs);
+#endif
+	hwgraph_vertex_destroy(dma_node->devfs_handle);
+}
+
+
+void init_dma_node(struct node_data * node,
+		   struct pci_dev * dev, vertex_hdl_t dh)
+{
+	TRACE();
+
+	node->devfs_handle = dh;
+	node->u.dma.dev = dev;
+	node->cleanup = dma_cleanup;
+	INIT_LIST_HEAD(&node->u.dma.dma_allocs);
+}
+
+
+void rom_cleanup(struct node_data * rom_node)
+{
+	TRACE();
+
+	if (rom_node->u.rom.mmapped)
+		pci_write_config_dword(rom_node->u.rom.dev,
+				       PCI_ROM_ADDRESS,
+				       rom_node->u.rom.saved_rom_base_reg);
+	hwgraph_vertex_destroy(rom_node->devfs_handle);
+}
+
+
+void init_rom_node(struct node_data * node,
+		   struct pci_dev * dev, vertex_hdl_t dh)
+{
+	TRACE();
+
+	node->devfs_handle = dh;
+	node->u.rom.dev = dev;
+	node->cleanup = rom_cleanup;
+	node->u.rom.mmapped = false;
+}
+
+
+static status __init
+register_pci_device(vertex_hdl_t device_dir_handle, struct pci_dev * dev)
+{
+	struct node_data * nd;
+	char devfs_path[20];
+	vertex_hdl_t node_devfs_handle;
+	int ri;
+
+	TRACE();
+
+
+	/* register nodes for all the device's base address registers */
+	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
+		if (pci_resource_len(dev, ri) != 0) {
+			sprintf(devfs_path, "base/%d", ri);
+			if (hwgraph_register(device_dir_handle, devfs_path,
+					   0, DEVFS_FL_NONE,
+					   0, 0,
+					   S_IFCHR | S_IRUSR | S_IWUSR, 0, 0,
+					   &base_fops, 
+					   &dev->resource[ri]) == NULL)
+				return failure;
+		}
+	}
+	
+	/* register a node corresponding to the first MEM resource on
+           the device */
+	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
+		if (dev->resource[ri].flags & IORESOURCE_MEM &&
+		    pci_resource_len(dev, ri) != 0) {
+			if (hwgraph_register(device_dir_handle, "mem",
+					   0, DEVFS_FL_NONE, 0, 0,
+					   S_IFCHR | S_IRUSR | S_IWUSR, 0, 0,
+					   &base_fops, 
+					   &dev->resource[ri]) == NULL)
+				return failure;
+			break;
+		}
+	}
+
+	/* also register a node corresponding to the first IO resource
+           on the device */
+	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
+		if (dev->resource[ri].flags & IORESOURCE_IO &&
+		    pci_resource_len(dev, ri) != 0) {
+			if (hwgraph_register(device_dir_handle, "io",
+					   0, DEVFS_FL_NONE, 0, 0,
+					   S_IFCHR | S_IRUSR | S_IWUSR, 0, 0,
+					   &base_fops, 
+					   &dev->resource[ri]) == NULL)
+				return failure;
+			break;
+		}
+	}
+
+	/* register a node corresponding to the device's ROM resource,
+           if present */
+	if (pci_resource_len(dev, PCI_ROM_RESOURCE) != 0) {
+		nd = new_node();
+		if (nd == NULL)
+			return failure;
+		node_devfs_handle = hwgraph_register(device_dir_handle, "rom",
+						   0, DEVFS_FL_NONE, 0, 0,
+						   S_IFCHR | S_IRUSR, 0, 0,
+						   &rom_fops, nd);
+		if (node_devfs_handle == NULL)
+			return failure;
+		init_rom_node(nd, dev, node_devfs_handle);
+	}
+
+	/* register a node that allows ioctl's to read and write to
+           the device's config space */
+	if (hwgraph_register(device_dir_handle, "config", 0, DEVFS_FL_NONE,
+			   0, 0, S_IFCHR | S_IRUSR | S_IWUSR, 0, 0,
+			   &config_fops, dev) == NULL)
+		return failure;
+
+
+	/* finally, register a node that allows ioctl's to allocate
+           and free DMA buffers, as well as memory map those
+           buffers. */
+	nd = new_node();
+	if (nd == NULL)
+		return failure;
+	node_devfs_handle =
+		hwgraph_register(device_dir_handle, "dma", 0, DEVFS_FL_NONE,
+			       0, 0, S_IFCHR | S_IRUSR | S_IWUSR, 0, 0,
+			       &dma_fops, nd);
+	if (node_devfs_handle == NULL)
+		return failure;
+	init_dma_node(nd, dev, node_devfs_handle);
+
+#ifdef DEBUG_PCIBA
+	dump_nodes(&global_node_list);
+#endif
+	
+	return success;
+}
+
+
+static int
+generic_open(struct inode * inode, struct file * file)
+{
+	TRACE();
+
+	/* FIXME: should check that they're not trying to open the ROM
+           writable */
+
+	return 0; /* success */
+}
+
+
+static int
+rom_mmap(struct file * file, struct vm_area_struct * vma)
+{
+	unsigned long pci_pa;
+	struct node_data * nd;
+
+	TRACE();
+
+#ifdef CONFIG_HWGFS_FS
+	nd = (struct node_data * )file->f_dentry->d_fsdata;
+#else
+	nd = (struct node_data * )file->private_data;
+#endif
+
+	pci_pa = pci_resource_start(nd->u.rom.dev, PCI_ROM_RESOURCE);
+
+	if (!nd->u.rom.mmapped) {
+		nd->u.rom.mmapped = true;
+		DPRINTF("Enabling ROM address decoder.\n");
+		DPRINTF(
+"rom_mmap: FIXME: some cards do not allow both ROM and memory addresses to\n"
+"rom_mmap: FIXME: be enabled simultaneously, as they share a decoder.\n");
+		pci_read_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
+				      &nd->u.rom.saved_rom_base_reg);
+		DPRINTF("ROM base address contains %x\n",
+			nd->u.rom.saved_rom_base_reg);
+		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
+				       nd->u.rom.saved_rom_base_reg |
+				       PCI_ROM_ADDRESS_ENABLE);
+	}
+	
+	return mmap_pci_address(vma, pci_pa);
+}
+
+
+static int
+rom_release(struct inode * inode, struct file * file)
+{
+	struct node_data * nd;
+
+	TRACE();
+
+#ifdef CONFIG_HWGFS_FS
+	nd = (struct node_data * )file->f_dentry->d_fsdata;
+#else
+	nd = (struct node_data * )file->private_data;
+#endif
+
+	if (nd->u.rom.mmapped) {
+		nd->u.rom.mmapped = false;
+		DPRINTF("Disabling ROM address decoder.\n");
+		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
+				       nd->u.rom.saved_rom_base_reg);
+	}
+	return 0; /* indicate success */
+}
+
+
+static int
+base_mmap(struct file * file, struct vm_area_struct * vma)
+{
+	struct resource * resource;
+
+	TRACE();
+
+#ifdef CONFIG_HWGFS_FS
+	resource = (struct resource *)file->f_dentry->d_fsdata;
+#else
+	resource = (struct resource *)file->private_data;
+#endif
+
+	return mmap_pci_address(vma, resource->start);
+}
+
+
+static int
+config_ioctl(struct inode * inode, struct file * file, 
+	     unsigned int cmd, 
+	     unsigned long arg)
+{
+	struct pci_dev * dev;
+
+	union cfg_data {
+		uint8_t byte;
+		uint16_t word;
+		uint32_t dword;
+	} read_data, write_data;
+
+	int dir, size, offset;
+
+	TRACE();
+
+	DPRINTF("cmd = %x (DIR = %x, TYPE = %x, NR = %x, SIZE = %x)\n", 
+		cmd, 
+		_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
+	DPRINTF("arg = %lx\n", arg);
+
+#ifdef CONFIG_HWGFS_FS
+	dev = (struct pci_dev *)file->f_dentry->d_fsdata;
+#else
+	dev = (struct pci_dev *)file->private_data;
+#endif
+
+	/* PCIIOCCFG{RD,WR}: read and/or write PCI configuration
+	   space. If both, the read happens first (this becomes a swap
+	   operation, atomic with respect to other updates through
+	   this path).  */
+
+	dir = _IOC_DIR(cmd);
+
+#define do_swap(suffix, type)	 					\
+	do {								\
+		if (dir & _IOC_READ) {					\
+			pci_read_config_##suffix(dev, _IOC_NR(cmd), 	\
+						 &read_data.suffix);	\
+		}							\
+		if (dir & _IOC_WRITE) {					\
+			get_user(write_data.suffix, (type)arg);		\
+			pci_write_config_##suffix(dev, _IOC_NR(cmd), 	\
+						  write_data.suffix);	\
+		}							\
+		if (dir & _IOC_READ) {					\
+			put_user(read_data.suffix, (type)arg);		\
+		}							\
+	} while (0)
+
+	size = _IOC_SIZE(cmd);
+	offset = _IOC_NR(cmd);
+
+	DPRINTF("sanity check\n");
+	if (((size > 0) || (size <= 4)) &&
+	    ((offset + size) <= 256) &&
+	    (dir & (_IOC_READ | _IOC_WRITE))) {
+
+		switch (size)
+		{
+		case 1:
+			do_swap(byte, uint8_t *);
+			break;
+		case 2:
+			do_swap(word, uint16_t *);
+			break;
+		case 4:
+			do_swap(dword, uint32_t *);
+			break;
+		default:
+			DPRINTF("invalid ioctl\n");
+			return -EINVAL;
+		}
+	} else
+		return -EINVAL;
+		
+	return 0;
+}
+
+
+#ifdef DEBUG_PCIBA
+static void
+dump_allocations(struct list_head * dalp)
+{
+	struct dma_allocation * dap;
+	struct list_head * p;
+	
+	printk("{\n");
+	list_for_each(p, dalp) {
+		dap = list_entry(p, struct dma_allocation, 
+				 list);
+		printk("  handle = %lx, va = %p\n",
+		       dap->handle, dap->va);
+	}
+	printk("}\n");
+}
+
+static void
+dump_nodes(struct list_head * nodes)
+{
+	struct node_data * ndp;
+	struct list_head * p;
+	
+	printk("{\n");
+	list_for_each(p, nodes) {
+		ndp = list_entry(p, struct node_data, 
+				 global_node_list);
+		printk("  %p\n", (void *)ndp);
+	}
+	printk("}\n");
+}
+
+
+#if 0
+#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
+
+static void
+test_list(void)
+{
+	u64 i;
+	LIST_HEAD(the_list);
+
+	for (i = 0; i < 5; i++) {
+		struct dma_allocation * new_alloc;
+		NEW(new_alloc);
+		new_alloc->va = (void *)i;
+		new_alloc->handle = 5*i;
+		printk("%d - the_list->next = %lx\n", i, the_list.next);
+		list_add(&new_alloc->list, &the_list);
+	}
+	dump_allocations(&the_list);
+}
+#endif
+#endif
+
+
+static LIST_HEAD(dma_buffer_list);
+
+
+static int
+dma_ioctl(struct inode * inode, struct file * file, 
+	  unsigned int cmd, 
+	  unsigned long arg)
+{
+	struct node_data * nd;
+	uint64_t argv;
+	int result;
+	struct dma_allocation * dma_alloc;
+	struct list_head * iterp;
+
+	TRACE();
+
+	DPRINTF("cmd = %x\n", cmd);
+	DPRINTF("arg = %lx\n", arg);
+
+#ifdef CONFIG_HWGFS_FS
+	nd = (struct node_data *)file->f_dentry->d_fsdata;
+#else
+	nd = (struct node_data *)file->private_data;
+#endif
+
+#ifdef DEBUG_PCIBA
+	DPRINTF("at dma_ioctl entry\n");
+	dump_allocations(&nd->u.dma.dma_allocs);
+#endif
+
+	switch (cmd) {
+	case PCIIOCDMAALLOC:
+		/* PCIIOCDMAALLOC: allocate a chunk of physical memory
+		   and set it up for DMA. Return the PCI address that
+		   gets to it.  */
+		DPRINTF("case PCIIOCDMAALLOC (%lx)\n", PCIIOCDMAALLOC);
+		
+		if ( (result = get_user(argv, (uint64_t *)arg)) )
+			return result;
+		DPRINTF("argv (size of buffer) = %lx\n", argv);
+
+		dma_alloc = (struct dma_allocation *)
+			kmalloc(sizeof(struct dma_allocation), GFP_KERNEL);
+		if (dma_alloc == NULL)
+			return -ENOMEM;
+
+		dma_alloc->size = (size_t)argv;
+		dma_alloc->va = pci_alloc_consistent(nd->u.dma.dev,
+						     dma_alloc->size,
+						     &dma_alloc->handle);
+		DPRINTF("dma_alloc->va = %p, dma_alloc->handle = %lx\n",
+			dma_alloc->va, dma_alloc->handle);
+		if (dma_alloc->va == NULL) {
+			kfree(dma_alloc);
+			return -ENOMEM;
+		}
+
+		list_add(&dma_alloc->list, &nd->u.dma.dma_allocs);
+		if ( (result = put_user((uint64_t)dma_alloc->handle, 
+				      (uint64_t *)arg)) ) {
+			DPRINTF("put_user failed\n");
+			pci_free_consistent(nd->u.dma.dev, (size_t)argv,
+					    dma_alloc->va, dma_alloc->handle);
+			kfree(dma_alloc);
+			return result;
+		}
+
+#ifdef DEBUG_PCIBA
+		DPRINTF("after insertion\n");
+		dump_allocations(&nd->u.dma.dma_allocs);
+#endif
+		break;
+
+	case PCIIOCDMAFREE:
+		DPRINTF("case PCIIOCDMAFREE (%lx)\n", PCIIOCDMAFREE);
+
+		if ( (result = get_user(argv, (uint64_t *)arg)) ) {
+			DPRINTF("get_user failed\n");
+			return result;
+		}
+
+		DPRINTF("argv (physical address of DMA buffer) = %lx\n", argv);
+		list_for_each(iterp, &nd->u.dma.dma_allocs) {
+			struct dma_allocation * da =
+				list_entry(iterp, struct dma_allocation, list);
+			if (da->handle == argv) {
+				pci_free_consistent(nd->u.dma.dev, da->size,
+						    da->va, da->handle);
+				list_del(&da->list);
+				kfree(da);
+#ifdef DEBUG_PCIBA
+				DPRINTF("after deletion\n");
+				dump_allocations(&nd->u.dma.dma_allocs);
+#endif
+				return 0; /* success */
+			}
+		}
+		/* previously allocated dma buffer wasn't found */
+		DPRINTF("attempt to free invalid dma handle\n");
+		return -EINVAL;
+
+	default:
+		DPRINTF("undefined ioctl\n");
+		return -EINVAL;
+	}
+
+	DPRINTF("success\n");
+	return 0;
+}
+		
+
+static int
+dma_mmap(struct file * file, struct vm_area_struct * vma)
+{
+	struct node_data * nd;
+	struct list_head * iterp;
+	int result;
+	
+	TRACE();
+
+#ifdef CONFIG_HWGFS_FS
+	nd = (struct node_data *)file->f_dentry->d_fsdata;
+#else
+	nd = (struct node_data *)file->private_data;
+#endif
+	
+	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
+	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
+	DPRINTF("offset = %lx\n", vma->vm_pgoff);
+
+	/* get kernel virtual address for the dma buffer (necessary
+	 * for the mmap). */
+	list_for_each(iterp, &nd->u.dma.dma_allocs) {
+		struct dma_allocation * da =
+			list_entry(iterp, struct dma_allocation, list);
+		/* why does mmap shift its offset argument? */
+		if (da->handle == vma->vm_pgoff << PAGE_SHIFT) {
+			DPRINTF("found dma handle\n");
+			if ( (result = mmap_kernel_address(vma,
+							   da->va)) ) {
+				return result; /* failure */
+			} else {
+				/* it seems like at least one of these
+				   should show up in user land....
+				   I'm missing something */
+				*(char *)da->va = 0xaa;
+				strncpy(da->va, "        Toastie!", da->size);
+				if (put_user(0x18badbeeful,
+					     (u64 *)vma->vm_start))
+					DPRINTF("put_user failed?!\n");
+				return 0; /* success */
+			}
+
+		}
+	}
+	DPRINTF("attempt to mmap an invalid dma handle\n");
+	return -EINVAL;
+}
+
+
+static int
+mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va)
+{
+	unsigned long pci_pa;
+
+	TRACE();
+
+	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
+	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
+
+	/* the size of the vma doesn't necessarily correspond to the
+           size specified in the mmap call.  So we can't really do any
+           kind of sanity check here.  This is a dangerous driver, and
+           it's very easy for a user process to kill the machine.  */
+
+	DPRINTF("PCI base at virtual address %lx\n", pci_va);
+	/* the __pa macro is intended for region 7 on IA64, so it
+	   doesn't work for region 6 */
+  	/* pci_pa = __pa(pci_va); */
+	/* should be replaced by __tpa or equivalent (preferably a
+	   generic equivalent) */
+	pci_pa = pci_va & ~0xe000000000000000ul;
+	DPRINTF("PCI base at physical address %lx\n", pci_pa);
+
+	/* there are various arch-specific versions of this function
+           defined in linux/drivers/char/mem.c, but it would be nice
+           if all architectures put it in pgtable.h.  it's defined
+           there for ia64.... */
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
+
+	return io_remap_page_range(vma->vm_start, pci_pa, 
+				   vma->vm_end-vma->vm_start,
+				   vma->vm_page_prot);
+}
+
+
+static int
+mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va)
+{
+	unsigned long kernel_pa;
+
+	TRACE();
+
+	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
+	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
+
+	/* the size of the vma doesn't necessarily correspond to the
+           size specified in the mmap call.  So we can't really do any
+           kind of sanity check here.  This is a dangerous driver, and
+           it's very easy for a user process to kill the machine.  */
+
+	DPRINTF("mapping virtual address %p\n", kernel_va);
+	kernel_pa = __pa(kernel_va);
+	DPRINTF("mapping physical address %lx\n", kernel_pa);
+
+	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
+
+	return remap_page_range(vma->vm_start, kernel_pa, 
+				vma->vm_end-vma->vm_start,
+				vma->vm_page_prot);
+}	
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/eeprom.c linux-2.4.22-pre10/arch/ia64/sn/io/eeprom.c
--- linux-2.4.21/arch/ia64/sn/io/eeprom.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/eeprom.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1422 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1999-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * WARNING:     There is more than one copy of this file in different isms.
- *              All copies must be kept exactly in sync.
- *              Do not modify this file without also updating the following:
- *
- *              irix/kern/io/eeprom.c
- *              stand/arcs/lib/libsk/ml/eeprom.c
- *		stand/arcs/lib/libkl/io/eeprom.c
- *
- *      (from time to time they might not be in sync but that's due to bringup
- *       activity - this comment is to remind us that they eventually have to
- *       get back together)
- *
- * eeprom.c
- *
- * access to board-mounted EEPROMs via the L1 system controllers
- *
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/simulator.h>
-
-#if defined(EEPROM_DEBUG)
-#define db_printf(x) printk x
-#else
-#define db_printf(x) printk x
-#endif
-
-#define BCOPY(x,y,z)	memcpy(y,x,z)
-
-#define UNDERSCORE	0	/* don't convert underscores to hyphens */
-#define HYPHEN		1	/* convert underscores to hyphens */
-
-void		copy_ascii_field( char *to, char *from, int length,
-			          int change_underscore );
-uint64_t	generate_unique_id( char *sn, int sn_len );
-uchar_t		char_to_base36( char c );
-int		nicify( char *dst, eeprom_brd_record_t *src );
-static void	int64_to_hex_string( char *out, uint64_t val );
-
-// extern int router_lock( net_vec_t, int, int );
-// extern int router_unlock( net_vec_t );
-#define ROUTER_LOCK(p) 	// router_lock(p, 10000, 3000000)
-#define ROUTER_UNLOCK(p) 	// router_unlock(p)
-
-#define IP27LOG_OVNIC           "OverrideNIC"
-
-
-/* the following function converts an EEPROM record to a close facsimile
- * of the string returned by reading a Dallas Semiconductor NIC (see
- * one of the many incarnations of nic.c for details on that driver)
- */
-int nicify( char *dst, eeprom_brd_record_t *src )
-{
-    int field_len;
-    uint64_t unique_id;
-    char *cur_dst = dst;
-    eeprom_board_ia_t   *board;
-
-    board   = src->board_ia;
-    ASSERT( board );  /* there should always be a board info area */
-
-    /* copy part number */
-    strcpy( cur_dst, "Part:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->part_num_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->part_num_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->part_num, field_len, HYPHEN );
-    cur_dst += field_len;
-
-    /* copy product name */
-    strcpy( cur_dst, ";Name:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->product_tl & FIELD_FORMAT_MASK) == FIELD_FORMAT_ASCII );
-    field_len = board->product_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->product, field_len, UNDERSCORE );
-    cur_dst += field_len;
-
-    /* copy serial number */
-    strcpy( cur_dst, ";Serial:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->serial_num_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->serial_num_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->serial_num, field_len,
-		      HYPHEN);
-
-    cur_dst += field_len;
-
-    /* copy revision */
-    strcpy( cur_dst, ";Revision:");
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->board_rev_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->board_rev_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->board_rev, field_len, HYPHEN );
-    cur_dst += field_len;
-
-    /* EEPROMs don't have equivalents for the Group, Capability and
-     * Variety fields, so we pad these with 0's
-     */
-    strcpy( cur_dst, ";Group:ff;Capability:ffffffff;Variety:ff" );
-    cur_dst += strlen( cur_dst );
-
-    /* use the board serial number to "fake" a laser id */
-    strcpy( cur_dst, ";Laser:" );
-    cur_dst += strlen( cur_dst );
-    unique_id = generate_unique_id( board->serial_num,
-				    board->serial_num_tl & FIELD_LENGTH_MASK );
-    int64_to_hex_string( cur_dst, unique_id );
-    strcat( dst, ";" );
-
-    return 1;
-}
-
-
-/* These functions borrow heavily from chars2* in nic.c
- */
-void copy_ascii_field( char *to, char *from, int length,
-		       int change_underscore )
-{
-    int i;
-    for( i = 0; i < length; i++ ) {
-
-	/* change underscores to hyphens if requested */
-	if( from[i] == '_' && change_underscore == HYPHEN )
-	    to[i] = '-';
-
-	/* ; and ; are separators, so mustn't appear within
-	 * a field */
-	else if( from[i] == ':' || from[i] == ';' )
-	    to[i] = '?';
-
-	/* I'm not sure why or if ASCII character 0xff would
-	 * show up in an EEPROM field, but the NIC parsing
-	 * routines wouldn't like it if it did... so we
-	 * get rid of it, just in case. */
-	else if( (unsigned char)from[i] == (unsigned char)0xff )
-	    to[i] = ' ';
-	
-	/* unprintable characters are replaced with . */
-	else if( from[i] < ' ' || from[i] >= 0x7f )
-	    to[i] = '.';
-
-	/* otherwise, just copy the character */
-	else
-	    to[i] = from[i];
-    }
-
-    if( i == 0 ) {
-	to[i] = ' '; /* return at least a space... */
-	i++;
-    }
-    to[i] = 0;	     /* terminating null */
-}
-
-/* Note that int64_to_hex_string currently only has a big-endian
- * implementation.
- */
-#ifdef _MIPSEB
-static void int64_to_hex_string( char *out, uint64_t val )
-{
-    int i;
-    uchar_t table[] = "0123456789abcdef";
-    uchar_t *byte_ptr = (uchar_t *)&val;
-    for( i = 0; i < sizeof(uint64_t); i++ ) {
-	out[i*2] = table[ ((*byte_ptr) >> 4) & 0x0f ];
-	out[i*2+1] = table[ (*byte_ptr) & 0x0f ];
-	byte_ptr++;
-    }
-    out[i*2] = '\0';
-}
-
-#else /* little endian */
-
-static void int64_to_hex_string( char *out, uint64_t val )
-{
-
-
-	printk("int64_to_hex_string needs a little-endian implementation.\n");
-}
-#endif /* _MIPSEB */
-
-/* Convert a standard ASCII serial number to a unique integer
- * id number by treating the serial number string as though
- * it were a base 36 number
- */
-uint64_t generate_unique_id( char *sn, int sn_len )
-{
-    int uid = 0;
-    int i;
-
-    #define VALID_BASE36(c)	((c >= '0' && c <='9') \
-			    ||   (c >= 'A' && c <='Z') \
-			    ||   (c >= 'a' && c <='z'))
-
-    for( i = 0; i < sn_len; i++ ) {
-	if( !VALID_BASE36(sn[i]) )
-	    continue;
-	uid *= 36;
-	uid += char_to_base36( sn[i] );
-    }
-
-    if( uid == 0 )
-	return rtc_time();
-
-    return uid;
-}
-
-uchar_t char_to_base36( char c )
-{
-    uchar_t val;
-
-    if( c >= '0' && c <= '9' )
-	val = (c - '0');
-
-    else if( c >= 'A' && c <= 'Z' )
-	val = (c - 'A' + 10);
-
-    else if( c >= 'a' && c <= 'z' )
-	val = (c - 'a' + 10);
-
-    else val = 0;
-
-    return val;
-}
-
-
-/* given a pointer to the three-byte little-endian EEPROM representation
- * of date-of-manufacture, this function translates to a big-endian
- * integer format
- */
-int eeprom_xlate_board_mfr_date( uchar_t *src )
-{
-    int rval = 0;
-    rval += *src; src++;
-    rval += ((int)(*src) << 8); src ++;
-    rval += ((int)(*src) << 16);
-    return rval;
-}
-
-
-int eeprom_str( char *nic_str, nasid_t nasid, int component )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    if( (component & C_DIMM) == C_DIMM ) {
-	/* this function isn't applicable to DIMMs */
-	return EEP_PARAM;
-    }
-    else {
-	eep.board_ia = &board;
-	eep.spd = NULL;
-	if( !(component & SUBORD_MASK) )
-	    eep.chassis_ia = &chassis;  /* only main boards have a chassis
-					 * info area */
-	else
-	    eep.chassis_ia = NULL;
-    }
-    
-    switch( component & BRICK_MASK ) {
-      case C_BRICK:
-	r = cbrick_eeprom_read( &eep, nasid, component );
-	break;
-      case IO_BRICK:
-	r = iobrick_eeprom_read( &eep, nasid, component );
-	break;
-      default:
-	return EEP_PARAM;  /* must be an invalid component */
-    }
-    if( r )
-	return r;
-    if( !nicify( nic_str, &eep ) )
-	return EEP_NICIFY;
-
-    return EEP_OK;
-}
-
-int vector_eeprom_str( char *nic_str, nasid_t nasid,
-		       int component, net_vec_t path )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    eep.board_ia = &board;
-    if( !(component & SUBORD_MASK) )
-        eep.chassis_ia = &chassis;  /* only main boards have a chassis
-                                     * info area */
-    else
-        eep.chassis_ia = NULL;
-
-    if( !(component & VECTOR) )
-	return EEP_PARAM;
-
-    if( (r = vector_eeprom_read( &eep, nasid, path, component )) )
-	return r;
-
-    if( !nicify( nic_str, &eep ) )
-        return EEP_NICIFY;
-
-    return EEP_OK;
-}
-
-
-int is_iobrick( int nasid, int widget_num )
-{
-    uint32_t wid_reg;
-    int part_num, mfg_num;
-
-    /* Read the widget's WIDGET_ID register to get
-     * its part number and mfg number
-     */
-    wid_reg = *(volatile int32_t *)
-        (NODE_SWIN_BASE( nasid, widget_num ) + WIDGET_ID);
-
-    part_num = (wid_reg & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT;
-    mfg_num = (wid_reg & WIDGET_MFG_NUM) >> WIDGET_MFG_NUM_SHFT;
-
-    /* Is this the "xbow part" of an XBridge?  If so, this
-     * widget is definitely part of an I/O brick.
-     */
-    if( part_num == XXBOW_WIDGET_PART_NUM &&
-	mfg_num == XXBOW_WIDGET_MFGR_NUM )
-
-	return 1;
-
-    /* Is this a "bridge part" of an XBridge?  If so, once
-     * again, we know this widget is part of an I/O brick.
-     */
-    if( part_num == XBRIDGE_WIDGET_PART_NUM &&
-	mfg_num == XBRIDGE_WIDGET_MFGR_NUM )
-
-	return 1;
-
-    return 0;
-}
-
-
-int cbrick_uid_get( nasid_t nasid, uint64_t *uid )
-{
-    char uid_str[32];
-    char msg[BRL1_QSIZE];
-    int subch, len;
-    l1sc_t sc;
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* If the promlog variable pointed to by IP27LOG_OVNIC is set,
-     * use that value for the cbrick UID rather than the EEPROM
-     * serial number.
-     */
-#ifdef LOG_GETENV
-    if( ip27log_getenv( nasid, IP27LOG_OVNIC, uid_str, NULL, 0 ) >= 0 )
-    {
-	/* We successfully read IP27LOG_OVNIC, so return it as the UID. */
-	db_printf(( "cbrick_uid_get:"
-		    "Overriding UID with environment variable %s\n", 
-		    IP27LOG_OVNIC ));
-	*uid = strtoull( uid_str, NULL, 0 );
-	return EEP_OK;
-    }
-#endif
-
-    /* If this brick is retrieving its own uid, use the local l1sc_t to
-     * arbitrate access to the l1; otherwise, set up a new one.
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &sc;
-	sc_init( &sc, nasid, BRL1_LOCALHUB_UART );
-    }
-
-    /* fill in msg with the opcode & params */
-    BZERO( msg, BRL1_QSIZE );
-    if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 )
-	return EEP_L1;
-
-    if( (len = sc_construct_msg( scp, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SER_NUM, 0 )) < 0 )
-    {
-	sc_close( scp, subch );
-	return( EEP_L1 );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( scp, subch, msg, msg, &len ) ) {
-	sc_close( scp, subch );
-	return( EEP_L1 );
-    }
-
-    /* free up subchannel */
-    sc_close(scp, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 )
-    {
-	return( EEP_L1 );
-    }
-
-    *uid = generate_unique_id( uid_str, strlen( uid_str ) );
-
-    return EEP_OK;
-}
-
-
-int rbrick_uid_get( nasid_t nasid, net_vec_t path, uint64_t *uid )
-{
-    char uid_str[32];
-    char msg[BRL1_QSIZE];
-    int subch, len;
-    l1sc_t sc;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-#define FAIL								\
-    {									\
-	*uid = rtc_time();						\
-	printk( "rbrick_uid_get failed; using current time as uid\n" );	\
-	return EEP_OK;							\
-    }
-
-    ROUTER_LOCK(path);
-    sc_init( &sc, nasid, path );
-
-    /* fill in msg with the opcode & params */
-    BZERO( msg, BRL1_QSIZE );
-    if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 ) {
-	ROUTER_UNLOCK(path);
-	FAIL;
-    }
-
-    if( (len = sc_construct_msg( &sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SER_NUM, 0 )) < 0 )
-    {
-	ROUTER_UNLOCK(path);
-	sc_close( &sc, subch );
-	FAIL;
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( &sc, subch, msg, msg, &len ) ) {
-	ROUTER_UNLOCK(path);
-	sc_close( &sc, subch );
-	FAIL;
-    }
-
-    /* free up subchannel */
-    ROUTER_UNLOCK(path);
-    sc_close(&sc, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 )
-    {
-	FAIL;
-    }
-
-    *uid = generate_unique_id( uid_str, strlen( uid_str ) );
-
-    return EEP_OK;
-}
-
-int iobrick_uid_get( nasid_t nasid, uint64_t *uid )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    eep.board_ia = &board;
-    eep.chassis_ia = &chassis;
-    eep.spd = NULL;
-
-    r = iobrick_eeprom_read( &eep, nasid, IO_BRICK );
-    if( r != EEP_OK ) {
-        *uid = rtc_time();
-        return r;
-    }
-
-    *uid = generate_unique_id( board.serial_num,
-                               board.serial_num_tl & FIELD_LENGTH_MASK );
-
-    return EEP_OK;
-}
-
-
-int ibrick_mac_addr_get( nasid_t nasid, char *eaddr )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-    char *tmp;
-
-    eep.board_ia = &board;
-    eep.chassis_ia = &chassis;
-    eep.spd = NULL;
-
-    r = iobrick_eeprom_read( &eep, nasid, IO_BRICK );
-    if( (r != EEP_OK) || (board.mac_addr[0] == '\0') ) {
-	db_printf(( "ibrick_mac_addr_get: "
-		    "Couldn't read MAC address from EEPROM\n" ));
-	return EEP_L1;
-    }
-    else {
-	/* successfully read info area */
-	int ix;
-	tmp = board.mac_addr;
-	for( ix = 0; ix < (board.mac_addr_tl & FIELD_LENGTH_MASK); ix++ )
-	{
-	    *eaddr++ = *tmp++;
-	}
-	*eaddr = '\0';
-    }
-
-    return EEP_OK;
-}
-
-
-/* 
- * eeprom_vertex_info_set
- *
- * Given a vertex handle, a component designation, a starting nasid
- * and (in the case of a router) a vector path to the component, this
- * function will read the EEPROM and attach the resulting information
- * to the vertex in the same string format as that provided by the
- * Dallas Semiconductor NIC drivers.  If the vertex already has the
- * string, this function just returns the string.
- */
-
-extern char *nic_vertex_info_get( devfs_handle_t );
-extern void nic_vmc_check( devfs_handle_t, char * );
-/* the following were lifted from nic.c - change later? */
-#define MAX_INFO 2048
-#define NEWSZ(ptr,sz)   ((ptr) = kern_malloc((sz)))
-#define DEL(ptr) (kern_free((ptr)))
-
-char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v,
-                              net_vec_t path )
-{
-        char *info_tmp;
-        int info_len;
-        char *info;
-
-        /* see if this vertex is already marked */
-        info_tmp = nic_vertex_info_get(v);
-        if (info_tmp) return info_tmp;
-
-        /* get a temporary place for the data */
-        NEWSZ(info_tmp, MAX_INFO);
-        if (!info_tmp) return NULL;
-
-        /* read the EEPROM */
-	if( component & R_BRICK ) {
-	    if( RBRICK_EEPROM_STR( info_tmp, nasid, path ) != EEP_OK )
-		return NULL;
-	}
-	else {
-            if( eeprom_str( info_tmp, nasid, component ) != EEP_OK )
-	        return NULL;
-	}
-
-        /* allocate a smaller final place */
-        info_len = strlen(info_tmp)+1;
-        NEWSZ(info, info_len);
-        if (info) {
-                strcpy(info, info_tmp);
-                DEL(info_tmp);
-        } else {
-                info = info_tmp;
-        }
-
-        /* add info to the vertex */
-        hwgraph_info_add_LBL(v, INFO_LBL_NIC,
-                             (arbitrary_info_t) info);
-
-        /* see if someone else got there first */
-        info_tmp = nic_vertex_info_get(v);
-        if (info != info_tmp) {
-            DEL(info);
-            return info_tmp;
-        }
-
-        /* export the data */
-        hwgraph_info_export_LBL(v, INFO_LBL_NIC, info_len);
-
-        /* trigger all matching callbacks */
-        nic_vmc_check(v, info);
-
-        return info;
-}
-
-
-/*********************************************************************
- *
- * stubs for use until the Bedrock/L1 link is available
- *
- */
-
-#include <asm/sn/nic.h>
-
-/* #define EEPROM_TEST */
-
-/* fake eeprom reading functions (replace when the BR/L1 communication
- * channel is in working order)
- */
-
-
-/* generate a charater in [0-9A-Z]; if an "extra" character is
- * specified (such as '_'), include it as one of the possibilities.
- */
-char random_eeprom_ch( char extra ) 
-{
-    char ch;
-    int modval = 36;
-    if( extra )
-	modval++;
-    
-    ch = rtc_time() % modval;
-
-    if( ch < 10 )
-        ch += '0';
-    else if( ch >= 10 && ch < 36 )
-	ch += ('A' - 10);
-    else
-	ch = extra;
-
-    return ch;
-}
-
-/* create a part number of the form xxx-xxxx-xxx.
- * It may be important later to generate different
- * part numbers depending on the component we're
- * supposed to be "reading" from, so the component
- * paramter is provided.
- */
-void fake_a_part_number( char *buf, int component )
-{
-    int i;
-    switch( component ) {
-
-    /* insert component-specific routines here */
-
-    case C_BRICK:
-	strcpy( buf, "030-1266-001" );
-	break;
-    default:
-        for( i = 0; i < 12; i++ ) {
-	    if( i == 3 || i == 8 )
-	        buf[i] = '-';
-	    else
-	        buf[i] = random_eeprom_ch(0);
-        }
-    }
-}
-
-
-/* create a six-character serial number */
-void fake_a_serial_number( char *buf, uint64_t ser )
-{
-    int i;
-    static const char hexchars[] = "0123456789ABCDEF";
-
-    if (ser) {
-	for( i = 5; i >=0; i-- ) {
-	    buf[i] = hexchars[ser & 0xf];
-	    ser >>= 4;
-	}
-    }
-    else {
-	for( i = 0; i < 6; i++ )
-	    buf[i] = random_eeprom_ch(0);
-    }
-}
-
-
-void fake_a_product_name( uchar_t *format, char* buf, int component )
-{
-    switch( component & BRICK_MASK ) {
-
-    case C_BRICK:
-	if( component & SUBORD_MASK ) {
-	    strcpy( buf, "C_BRICK_SUB" );
-	    *format = 0xCB;
-	}
-	else {
-	    strcpy( buf, "IP35" );
-	    *format = 0xC4;
-	}
-	break;
-
-    case R_BRICK:
-        if( component & SUBORD_MASK ) {
-            strcpy( buf, "R_BRICK_SUB" );
-            *format = 0xCB;
-        }
-        else {
-            strcpy( buf, "R_BRICK" );
-            *format = 0xC7;
-        }
-        break;
-
-    case IO_BRICK:
-        if( component & SUBORD_MASK ) {
-            strcpy( buf, "IO_BRICK_SUB" );
-            *format = 0xCC;
-        }
-        else {
-            strcpy( buf, "IO_BRICK" );
-            *format = 0xC8;
-        }
-        break;
-
-    default:
-	strcpy( buf, "UNK_DEVICE" );
-	*format = 0xCA;
-    }
-}
-
-
-
-int fake_an_eeprom_record( eeprom_brd_record_t *buf, int component, 
-			   uint64_t ser )
-{
-    eeprom_board_ia_t *board;
-    eeprom_chassis_ia_t *chassis;
-    int i, cs;
-
-    board = buf->board_ia;
-    chassis = buf->chassis_ia;
-
-    if( !(component & SUBORD_MASK) ) {
-	if( !chassis )
-	    return EEP_PARAM;
-	chassis->format = 0;
-	chassis->length = 5;
-	chassis->type = 0x17;
-
-	chassis->part_num_tl = 0xCC;
-	fake_a_part_number( chassis->part_num, component );
-	chassis->serial_num_tl = 0xC6;
-	fake_a_serial_number( chassis->serial_num, ser );
-
-	cs = chassis->format + chassis->length + chassis->type
-	    + chassis->part_num_tl + chassis->serial_num_tl;
-	for( i = 0; i < (chassis->part_num_tl & FIELD_LENGTH_MASK); i++ )
-	    cs += chassis->part_num[i];
-	for( i = 0; i < (chassis->serial_num_tl & FIELD_LENGTH_MASK); i++ )
-	    cs += chassis->serial_num[i];
-	chassis->checksum = 256 - (cs % 256);
-    }
-
-    if( !board )
-	return EEP_PARAM;
-    board->format = 0;
-    board->length = 10;
-    board->language = 0;
-    board->mfg_date = 1789200; /* noon, 5/26/99 */
-    board->manuf_tl = 0xC3;
-    strcpy( board->manuf, "SGI" );
-
-    fake_a_product_name( &(board->product_tl), board->product, component );
-
-    board->serial_num_tl = 0xC6;
-    fake_a_serial_number( board->serial_num, ser );
-
-    board->part_num_tl = 0xCC;
-    fake_a_part_number( board->part_num, component );
-
-    board->board_rev_tl = 0xC2;
-    board->board_rev[0] = '0';
-    board->board_rev[1] = '1';
-
-    board->eeprom_size_tl = 0x01;
-    board->eeprom_size = 1;
-
-    board->temp_waiver_tl = 0xC2;
-    board->temp_waiver[0] = '0';
-    board->temp_waiver[1] = '1';
-
-    cs = board->format + board->length + board->language
-	+ (board->mfg_date & 0xFF)
-	+ (board->mfg_date & 0xFF00)
-	+ (board->mfg_date & 0xFF0000)
-	+ board->manuf_tl + board->product_tl + board->serial_num_tl
-	+ board->part_num_tl + board->board_rev_tl
-	+ board->board_rev[0] + board->board_rev[1]
-	+ board->eeprom_size_tl + board->eeprom_size + board->temp_waiver_tl
-	+ board->temp_waiver[0] + board->temp_waiver[1];
-    for( i = 0; i < (board->manuf_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->manuf[i];
-    for( i = 0; i < (board->product_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->product[i];
-    for( i = 0; i < (board->serial_num_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->serial_num[i];
-    for( i = 0; i < (board->part_num_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->part_num[i];
-    
-    board->checksum = 256 - (cs % 256);
-
-    return EEP_OK;
-}
-
-#define EEPROM_CHUNKSIZE	64
-
-#if defined(EEPROM_DEBUG)
-#define RETURN_ERROR							\
-{									\
-    printk( "read_ia error return, component 0x%x, line %d"		\
-	    ", address 0x%x, ia code 0x%x\n",				\
-	    l1_compt, __LINE__, sc->subch[subch].target, ia_code );	\
-    return EEP_L1;							\
-}
-
-#else
-#define RETURN_ERROR	return(EEP_L1)
-#endif
-
-int read_ia( l1sc_t *sc, int subch, int l1_compt, 
-	     int ia_code, char *eep_record )
-{
-    char msg[BRL1_QSIZE]; 	   /* message buffer */
-    int len;              	   /* number of bytes used in message buffer */
-    int ia_len = EEPROM_CHUNKSIZE; /* remaining bytes in info area */
-    int offset = 0;                /* current offset into info area */
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    BZERO( msg, BRL1_QSIZE );
-
-    /* retrieve EEPROM data in 64-byte chunks
-     */
-
-    while( ia_len )
-    {
-	/* fill in msg with opcode & params */
-	if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				     L1_ADDR_TASK_GENERAL,
-				     L1_REQ_EEPROM, 8,
-				     L1_ARG_INT, l1_compt,
-				     L1_ARG_INT, ia_code,
-				     L1_ARG_INT, offset,
-				     L1_ARG_INT, ia_len )) < 0 )
-	{
-	    RETURN_ERROR;
-	}
-
-	/* send the request to the L1 */
-
-	if( sc_command( sc, subch, msg, msg, &len ) ) {
-	    RETURN_ERROR;
-	}
-
-	/* check response */
-	if( sc_interpret_resp( msg, 5, 
-			       L1_ARG_INT, &ia_len,
-			       L1_ARG_UNKNOWN, &len, eep_record ) < 0 )
-	{
-	    RETURN_ERROR;
-	}
-
-	if( ia_len > EEPROM_CHUNKSIZE )
-	    ia_len = EEPROM_CHUNKSIZE;
-
-	eep_record += EEPROM_CHUNKSIZE;
-	offset += EEPROM_CHUNKSIZE;
-    }
-
-    return EEP_OK;
-}
-
-
-int read_spd( l1sc_t *sc, int subch, int l1_compt,
-	      eeprom_spd_u *spd )
-{
-    char msg[BRL1_QSIZE]; 	    /* message buffer */
-    int len;              	    /* number of bytes used in message buffer */
-    int resp;                       /* l1 response code */
-    int spd_len = EEPROM_CHUNKSIZE; /* remaining bytes in spd record */
-    int offset = 0;		    /* current offset into spd record */
-    char *spd_p = spd->bytes;	    /* "thumb" for writing to spd */
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    BZERO( msg, BRL1_QSIZE );
-
-    /* retrieve EEPROM data in 64-byte chunks
-     */
-
-    while( spd_len )
-    {
-	/* fill in msg with opcode & params */
-	if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				     L1_ADDR_TASK_GENERAL,
-				     L1_REQ_EEPROM, 8,
-				     L1_ARG_INT, l1_compt,
-				     L1_ARG_INT, L1_EEP_SPD,
-				     L1_ARG_INT, offset,
-				     L1_ARG_INT, spd_len )) < 0 )
-	{
-	    return( EEP_L1 );
-	}
-
-	/* send the request to the L1 */
-	if( sc_command( sc, subch, msg, msg, &len ) ) {
-	    return( EEP_L1 );
-	}
-
-	/* check response */
-	if( (resp = sc_interpret_resp( msg, 5, 
-			       L1_ARG_INT, &spd_len,
-			       L1_ARG_UNKNOWN, &len, spd_p )) < 0 )
-	{
-            /*
-             * translate l1 response code to eeprom.c error codes:
-             * The L1 response will be L1_RESP_NAVAIL if the spd
-             * can't be read (i.e. the spd isn't physically there). It will
-             * return L1_RESP_INVAL if the spd exists, but fails the checksum
-             * test because the eeprom wasn't programmed, programmed incorrectly,
-             * or corrupted. L1_RESP_NAVAIL indicates the eeprom is likely not present,
-             * whereas L1_RESP_INVAL indicates the eeprom is present, but the data is
-             * invalid.
-             */
-            if(resp == L1_RESP_INVAL) {
-                resp = EEP_BAD_CHECKSUM;
-            } else {
-                resp = EEP_L1;
-            }
-            return( resp );
-	}
-
-	if( spd_len > EEPROM_CHUNKSIZE )
-	    spd_len = EEPROM_CHUNKSIZE;
-
-	spd_p += EEPROM_CHUNKSIZE;
-	offset += EEPROM_CHUNKSIZE;
-    }
-    return EEP_OK;
-}
-
-
-int read_chassis_ia( l1sc_t *sc, int subch, int l1_compt,
-		     eeprom_chassis_ia_t *ia )
-{
-    char eep_record[512];          /* scratch area for building up info area */
-    char *eep_rec_p = eep_record;  /* thumb for moving through eep_record */
-    int checksum = 0;              /* use to verify eeprom record checksum */
-    int i;
-
-    /* Read in info area record from the L1.
-     */
-    if( read_ia( sc, subch, l1_compt, L1_EEP_CHASSIS, eep_record )
-	!= EEP_OK )
-    {
-	return EEP_L1;
-    }
-
-    /* Now we've got the whole info area.  Transfer it to the data structure.
-     */
-
-    eep_rec_p = eep_record;
-    ia->format = *eep_rec_p++;
-    ia->length = *eep_rec_p++;
-    if( ia->length == 0 ) {
-	/* since we're using 8*ia->length-1 as an array index later, make
-	 * sure it's sane.
-	 */
-	db_printf(( "read_chassis_ia: eeprom length byte of ZERO\n" ));
-	return EEP_L1;
-    }
-    ia->type = *eep_rec_p++;
-   
-    ia->part_num_tl = *eep_rec_p++;
-
-    (void)BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK);
-
-    ia->serial_num_tl = *eep_rec_p++;
-
-    BCOPY( eep_rec_p, ia->serial_num, 
-	   (ia->serial_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK);
-
-    ia->checksum = eep_record[(8 * ia->length) - 1];
-
-    /* verify checksum */
-    eep_rec_p = eep_record;
-    checksum = 0;
-    for( i = 0; i < (8 * ia->length); i++ ) {
-	checksum += *eep_rec_p++;
-    }
-
-    if( (checksum & 0xff) != 0 )
-    {
-	db_printf(( "read_chassis_ia: bad checksum\n" ));
-	db_printf(( "read_chassis_ia: target 0x%x  uart 0x%lx\n",
-			   sc->subch[subch].target, sc->uart ));
-	return EEP_BAD_CHECKSUM;
-    }
-
-    return EEP_OK;
-}
-
-
-int read_board_ia( l1sc_t *sc, int subch, int l1_compt,
-		   eeprom_board_ia_t *ia )
-{
-    char eep_record[512];          /* scratch area for building up info area */
-    char *eep_rec_p = eep_record;  /* thumb for moving through eep_record */
-    int checksum = 0;              /* running checksum total */
-    int i;
-
-    BZERO( ia, sizeof( eeprom_board_ia_t ) );
-
-    /* Read in info area record from the L1.
-     */
-    if( read_ia( sc, subch, l1_compt, L1_EEP_BOARD, eep_record )
-	!= EEP_OK )
-    {
-	db_printf(( "read_board_ia: error reading info area from L1\n" ));
-	return EEP_L1;
-    }
-
-     /* Now we've got the whole info area.  Transfer it to the data structure.
-      */
-
-    eep_rec_p = eep_record;
-    ia->format = *eep_rec_p++;
-    ia->length = *eep_rec_p++;
-    if( ia->length == 0 ) {
-	/* since we're using 8*ia->length-1 as an array index later, make
-	 * sure it's sane.
-	 */
-	db_printf(( "read_board_ia: eeprom length byte of ZERO\n" ));
-	return EEP_L1;
-    }
-    ia->language = *eep_rec_p++;
-    
-    ia->mfg_date = eeprom_xlate_board_mfr_date( (uchar_t *)eep_rec_p );
-    eep_rec_p += 3;
-
-    ia->manuf_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->manuf, (ia->manuf_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->manuf_tl & FIELD_LENGTH_MASK);
-
-    ia->product_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->product, (ia->product_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->product_tl & FIELD_LENGTH_MASK);
-
-    ia->serial_num_tl = *eep_rec_p++;
-    
-    BCOPY(eep_rec_p, ia->serial_num, (ia->serial_num_tl & FIELD_LENGTH_MASK));
-    eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK);
-
-    ia->part_num_tl = *eep_rec_p++;
-
-    BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK);
-
-    eep_rec_p++; /* we do not use the FRU file id */
-    
-    ia->board_rev_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->board_rev, (ia->board_rev_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->board_rev_tl & FIELD_LENGTH_MASK);
-
-    ia->eeprom_size_tl = *eep_rec_p++;
-    ia->eeprom_size = *eep_rec_p++;
-
-    ia->temp_waiver_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->temp_waiver, 
-	   (ia->temp_waiver_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->temp_waiver_tl & FIELD_LENGTH_MASK);
-
-    /* if there's more, we must be reading a main board; get
-     * additional fields
-     */
-    if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) {
-
-	ia->ekey_G_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_G, 
-	       ia->ekey_G_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_G_tl & FIELD_LENGTH_MASK);
-	
-	ia->ekey_P_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_P, 
-	       ia->ekey_P_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_P_tl & FIELD_LENGTH_MASK);
-	
-	ia->ekey_Y_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_Y, 
-	       ia->ekey_Y_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_Y_tl & FIELD_LENGTH_MASK);
-	
-	/* 
-	 * need to get a couple more fields if this is an I brick 
-	 */
-	if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) {
-
-	    ia->mac_addr_tl = *eep_rec_p++;
-	    BCOPY( eep_rec_p, ia->mac_addr, 
-		   ia->mac_addr_tl & FIELD_LENGTH_MASK );
-	    eep_rec_p += (ia->mac_addr_tl & FIELD_LENGTH_MASK);
-	    
-	    ia->ieee1394_cfg_tl = *eep_rec_p++;
-	    BCOPY( eep_rec_p, ia->ieee1394_cfg,
-		   ia->ieee1394_cfg_tl & FIELD_LENGTH_MASK );
-	    
-	}
-    }
-
-    ia->checksum = eep_record[(ia->length * 8) - 1];
-
-    /* verify checksum */
-    eep_rec_p = eep_record;
-    checksum = 0;
-    for( i = 0; i < (8 * ia->length); i++ ) {
-	checksum += *eep_rec_p++;
-    }
-
-    if( (checksum & 0xff) != 0 )
-    {
-	db_printf(( "read_board_ia: bad checksum\n" ));
-	db_printf(( "read_board_ia: target 0x%x  uart 0x%lx\n",
-		    sc->subch[subch].target, sc->uart ));
-	return EEP_BAD_CHECKSUM;
-    }
-
-    return EEP_OK;
-}
-
-
-int _cbrick_eeprom_read( eeprom_brd_record_t *buf, l1sc_t *scp,
-			 int component )
-{
-    int r;
-    uint64_t uid = 0;
-#ifdef LOG_GETENV
-    char uid_str[32];
-#endif
-    int l1_compt, subch;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're targeting a cbrick */
-    if( !(component & C_BRICK) )
-	return EEP_PARAM;
-
-    /* If the promlog variable pointed to by IP27LOG_OVNIC is set,
-     * use that value for the cbrick UID rather than the EEPROM
-     * serial number.
-     */
-#ifdef LOG_GETENV
-    if( ip27log_getenv( scp->nasid, IP27LOG_OVNIC, uid_str, "0", 0 ) >= 0 )
-    {
-	db_printf(( "_cbrick_eeprom_read: "
-		    "Overriding UID with environment variable %s\n", 
-		    IP27LOG_OVNIC ));
-	uid = strtoull( uid_str, NULL, 0 );
-    }
-#endif
-
-    if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 )
-	return EEP_L1;
-
-    if((component & C_DIMM) == C_DIMM) {
-        l1_compt = L1_EEP_DIMM(component & COMPT_MASK);
-        r = read_spd(scp,subch,l1_compt, buf->spd);
-        sc_close(scp,subch);
-        return(r);
-    }
-
-    switch( component )
-    {
-      case C_BRICK:
-	/* c-brick motherboard */
-	l1_compt = L1_EEP_NODE;
-	r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia );
-	if( r != EEP_OK ) {
-	    sc_close( scp, subch );
-	    db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" ));
-	    return fake_an_eeprom_record( buf, component, uid );
-	}
-	if( uid ) {
-	    /* If IP27LOG_OVNIC is set, we want to put that value
-	     * in as our UID. */
-	    fake_a_serial_number( buf->chassis_ia->serial_num, uid );
-	    buf->chassis_ia->serial_num_tl = 6;
-	}
-	break;
-
-      case C_PIMM:
-	/* one of the PIMM boards */
-	l1_compt = L1_EEP_PIMM( component & COMPT_MASK );
-	break;
-
-      default:
-	/* unsupported board type */
-	sc_close( scp, subch );
-	return EEP_PARAM;
-    }
-	      
-    r = read_board_ia( scp, subch, l1_compt, buf->board_ia );
-    sc_close( scp, subch );
-    if( r != EEP_OK ) 
-    {
-	db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" ));
-	return fake_an_eeprom_record( buf, component, uid );
-    }
-    return EEP_OK;
-}
-
-
-int cbrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-    		        int component )
-{
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* If this brick is retrieving its own uid, use the local l1sc_t to
-     * arbitrate access to the l1; otherwise, set up a new one (prom) or
-     * use an existing remote l1sc_t (kernel)
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    }
-
-    return _cbrick_eeprom_read( buf, scp, component );
-}
-
-
-int iobrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			 int component )
-{
-    int r;
-    int l1_compt, subch;
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're talking to an applicable brick */
-    if( !(component & IO_BRICK) ) {
-	return EEP_PARAM;
-    }
-
-    /* If we're talking to this c-brick's attached io brick, use
-     * the local l1sc_t; otherwise, set up a new one (prom) or
-     * use an existing remote l1sc_t (kernel)
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    }
-
-    if( (subch = sc_open( scp, L1_ADDR_LOCALIO )) < 0 )
-	return EEP_L1;
-
-
-    switch( component )
-    {
-      case IO_BRICK:
-	/* IO brick motherboard */
-	l1_compt = L1_EEP_LOGIC;
-	r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia );
-
-	if( r != EEP_OK ) {
-	    sc_close( scp, subch );
-	/*
-	 * Whenever we no longer need to test on hardware
-	 * that does not have EEPROMS, then this can be removed.
-	 */
-	    r = fake_an_eeprom_record( buf, component, rtc_time() );
-	    return r;
-	}
-	break;
-
-      case IO_POWER:
-	/* IO brick power board */
-	l1_compt = L1_EEP_POWER;
-	break;
-
-      default:
-	/* unsupported board type */
-	sc_close( scp, subch );
-	return EEP_PARAM;
-    }
-
-    r = read_board_ia( scp, subch, l1_compt, buf->board_ia );
-    sc_close( scp, subch );
-    if( r != EEP_OK ) {
-	return r;
-    }
-    return EEP_OK;
-}
-
-
-int vector_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			net_vec_t path, int component )
-{
-    int r;
-    uint64_t uid = 0;
-    int l1_compt, subch;
-    l1sc_t sc;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're targeting an applicable brick */
-    if( !(component & VECTOR) )
-	return EEP_PARAM;
-
-    switch( component & BRICK_MASK )
-    {
-      case R_BRICK:
-	ROUTER_LOCK( path );
-	sc_init( &sc, nasid, path );
-
-	if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 )
-	{
-	    db_printf(( "vector_eeprom_read: couldn't open subch\n" ));
-	    ROUTER_UNLOCK(path);
-	    return EEP_L1;
-	}
-	switch( component )
-	{
-	  case R_BRICK:
-	    /* r-brick motherboard */
-	    l1_compt = L1_EEP_LOGIC;
-    	    r = read_chassis_ia( &sc, subch, l1_compt, buf->chassis_ia );
-	    if( r != EEP_OK ) {
-		sc_close( &sc, subch );
-		ROUTER_UNLOCK( path );
-		printk( "vector_eeprom_read: couldn't get rbrick eeprom info;"
-			" using current time as uid\n" );
-		uid = rtc_time();
-		db_printf(("vector_eeprom_read: using a fake eeprom record\n"));
-		return fake_an_eeprom_record( buf, component, uid );
-	    }
-	    break;
-
-	  case R_POWER:
-	    /* r-brick power board */
-	    l1_compt = L1_EEP_POWER;
-	    break;
-
-	  default:
-	    /* unsupported board type */
-	    sc_close( &sc, subch );
-	    ROUTER_UNLOCK( path );
-	    return EEP_PARAM;
-	}
-	r = read_board_ia( &sc, subch, l1_compt, buf->board_ia );
-	sc_close( &sc, subch );
-	ROUTER_UNLOCK( path );
-	if( r != EEP_OK ) {
-	    db_printf(( "vector_eeprom_read: using a fake eeprom record\n" ));
-	    return fake_an_eeprom_record( buf, component, uid );
-	}
-	return EEP_OK;
-
-      case C_BRICK:
-	sc_init( &sc, nasid, path );
-	return _cbrick_eeprom_read( buf, &sc, component );
-
-      default:
-	/* unsupported brick type */
-	return EEP_PARAM;
-    }
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/efi-rtc.c linux-2.4.22-pre10/arch/ia64/sn/io/efi-rtc.c
--- linux-2.4.21/arch/ia64/sn/io/efi-rtc.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/efi-rtc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,185 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001 Silicon Graphics, Inc.
- * Copyright (C) 2001 by Ralf Baechle
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/efi.h>
-#include <asm/sn/klclock.h>
-
-/*
- * No locking necessary when this is called from efirtc which protects us
- * from racing by efi_rtc_lock.
- */
-#define __swizzle(addr) ((u8 *)((unsigned long)(addr) ^ 3))
-#define read_io_port(addr) (*(volatile u8 *) __swizzle(addr))
-#define write_io_port(addr, data) (*(volatile u8 *) __swizzle(addr) = (data))
-
-#define TOD_SGS_M48T35		1
-#define TOD_DALLAS_DS1386	2
-
-static unsigned long nvram_base = 0;
-static int tod_chip_type;
-
-static int
-get_tod_chip_type(void)
-{
-	unsigned char testval;
-
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-	write_io_port(RTC_DAL_DAY_ADDR, 0xff);
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-
-	testval = read_io_port(RTC_DAL_DAY_ADDR);
-	if (testval == 0xff)
-		return TOD_SGS_M48T35;
-
-	return TOD_DALLAS_DS1386;
-}
-
-efi_status_t
-ioc3_get_time(efi_time_t *time, efi_time_cap_t *caps)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	memset(time, 0, sizeof(*time));
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_READ_PROTECT);
-
-		time->year = BCD_TO_INT(read_io_port(RTC_SGS_YEAR_ADDR)) + YRREF;
-		time->month = BCD_TO_INT(read_io_port(RTC_SGS_MONTH_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_SGS_DATE_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_SGS_HOUR_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_SGS_MIN_ADDR));
-		time->second = BCD_TO_INT(read_io_port(RTC_SGS_SEC_ADDR));
-		time->nanosecond = 0;
-
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-
-		time->nanosecond = 0;
-		time->second = BCD_TO_INT(read_io_port(RTC_DAL_SEC_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_DAL_MIN_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_DAL_HOUR_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_DAL_DATE_ADDR));
-		time->month = BCD_TO_INT(read_io_port(RTC_DAL_MONTH_ADDR));
-		time->year = BCD_TO_INT(read_io_port(RTC_DAL_YEAR_ADDR)) + YRREF;
-
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	if (caps) {
-		caps->resolution = 50000000;	/*  50PPM */
-		caps->accuracy = 1000;		/*  1ms */
-		caps->sets_to_zero = 0;
-	}
-
-	return EFI_SUCCESS;
-}
-
-static efi_status_t ioc3_set_time (efi_time_t *t)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_WRITE_ENABLE);
-        	write_io_port(RTC_SGS_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_SGS_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_SGS_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_SGS_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_SGS_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_SGS_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-		write_io_port(RTC_DAL_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_DAL_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_DAL_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_DAL_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_DAL_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_DAL_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	return EFI_SUCCESS;
-}
-
-/* The following two are not supported atm.  */
-static efi_status_t
-ioc3_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-static efi_status_t
-ioc3_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-/*
- * It looks like the master IOC3 is usually on bus 0, device 4.  Hope
- * that's right
- */
-static __init int efi_ioc3_time_init(void)
-{
-	struct pci_dev *dev;
-	static struct ioc3 *ioc3;
-
-	dev = pci_find_slot(0, PCI_DEVFN(4, 0));
-	if (!dev) {
-		printk(KERN_CRIT "Couldn't find master IOC3\n");
-
-		return -ENODEV;
-	}
-
-	ioc3 = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0));
-	nvram_base = (unsigned long) ioc3 + IOC3_BYTEBUS_DEV0;
-
-	tod_chip_type = get_tod_chip_type();
-	if (tod_chip_type == 1)
-		printk(KERN_NOTICE "TOD type is SGS M48T35\n");
-	else if (tod_chip_type == 2)
-		printk(KERN_NOTICE "TOD type is Dallas DS1386\n");
-	else
-		printk(KERN_CRIT "No or unknown TOD\n");
-
-	efi.get_time = ioc3_get_time;
-	efi.set_time = ioc3_set_time;
-	efi.get_wakeup_time = ioc3_get_wakeup_time;
-	efi.set_wakeup_time = ioc3_set_wakeup_time;
-
-	return 0;
-}
-
-module_init(efi_ioc3_time_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hcl.c linux-2.4.22-pre10/arch/ia64/sn/io/hcl.c
--- linux-2.4.21/arch/ia64/sn/io/hcl.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hcl.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1531 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- *  hcl - SGI's Hardware Graph compatibility layer.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <asm/sn/sgi.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-
-#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER"
-#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE"
-#define HCL_TEMP_NAME_LEN 44 
-#define HCL_VERSION "1.0"
-devfs_handle_t hwgraph_root = NULL;
-devfs_handle_t linux_busnum = NULL;
-
-/*
- * Debug flag definition.
- */
-#define OPTION_NONE             0x00
-#define HCL_DEBUG_NONE 0x00000
-#define HCL_DEBUG_ALL  0x0ffff
-#if defined(CONFIG_HCL_DEBUG)
-static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE;
-#endif
-static unsigned int hcl_debug = HCL_DEBUG_NONE;
-#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
-static unsigned int boot_options = OPTION_NONE;
-#endif
-
-/*
- * Some Global definitions.
- */
-devfs_handle_t hcl_handle = NULL;
-
-invplace_t invplace_none = {
-	GRAPH_VERTEX_NONE,
-	GRAPH_VERTEX_PLACE_NONE,
-	NULL
-};
-
-/*
- * HCL device driver.
- * The purpose of this device driver is to provide a facility 
- * for User Level Apps e.g. hinv, ioconfig etc. an ioctl path 
- * to manipulate label entries without having to implement
- * system call interfaces.  This methodology will enable us to 
- * make this feature module loadable.
- */
-static int hcl_open(struct inode * inode, struct file * filp)
-{
-	if (hcl_debug) {
-        	printk("HCL: hcl_open called.\n");
-	}
-
-        return(0);
-
-}
-
-static int hcl_close(struct inode * inode, struct file * filp)
-{
-
-	if (hcl_debug) {
-        	printk("HCL: hcl_close called.\n");
-	}
-
-        return(0);
-
-}
-
-static int hcl_ioctl(struct inode * inode, struct file * file,
-        unsigned int cmd, unsigned long arg)
-{
-
-	if (hcl_debug) {
-		printk("HCL: hcl_ioctl called.\n");
-	}
-
-	switch (cmd) {
-		default:
-			if (hcl_debug) {
-				printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd);
-			}
-	}
-
-	return(0);
-
-}
-
-struct file_operations hcl_fops = {
-	(struct module *)0,
-	NULL,		/* lseek - default */
-	NULL,		/* read - general block-dev read */
-	NULL,		/* write - general block-dev write */
-	NULL,		/* readdir - bad */
-	NULL,		/* poll */
-	hcl_ioctl,      /* ioctl */
-	NULL,		/* mmap */
-	hcl_open,	/* open */
-	NULL,		/* flush */
-	hcl_close,	/* release */
-	NULL,		/* fsync */
-	NULL,		/* fasync */
-	NULL,		/* lock */
-	NULL,		/* readv */
-	NULL,		/* writev */
-};
-
-
-/*
- * init_hcl() - Boot time initialization.  Ensure that it is called 
- *	after devfs has been initialized.
- *
- * For now this routine is being called out of devfs/base.c.  Actually 
- * Not a bad place to be ..
- *
- */
-#ifdef MODULE
-int init_module (void)
-#else
-int __init init_hcl(void)
-#endif
-{
-	extern void string_table_init(struct string_table *);
-	extern struct string_table label_string_table;
-	extern int init_ifconfig_net(void);
-	int rv = 0;
-
-#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
-	printk ("\n%s: v%s Colin Ngam (cngam@sgi.com)\n",
-		HCL_NAME, HCL_VERSION);
-
-	hcl_debug = hcl_debug_init;
-	printk ("%s: hcl_debug: 0x%0x\n", HCL_NAME, hcl_debug);
-	printk ("\n%s: boot_options: 0x%0x\n", HCL_NAME, boot_options);
-#endif
-
-	/*
-	 * Create the hwgraph_root on devfs.
-	 */
-	rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
-	if (rv)
-		printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
-
-	/*
-	 * Create the hcl driver to support inventory entry manipulations.
-	 * By default, it is expected that devfs is mounted on /dev.
-	 *
-	 */
-	hcl_handle = hwgraph_register(hwgraph_root, ".hcl",
-			0, DEVFS_FL_AUTO_DEVNUM,
-			0, 0,
-			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-			&hcl_fops, NULL);
-
-	if (hcl_handle == NULL) {
-		panic("HCL: Unable to create HCL Driver in init_hcl().\n");
-		return(0);
-	}
-
-	/*
-	 * Initialize the HCL string table.
-	 */
-	string_table_init(&label_string_table);
-
-	/*
-	 * Create the directory that links Linux bus numbers to our Xwidget.
-	 */
-	rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum);
-	if (linux_busnum == NULL) {
-		panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS);
-		return(0);
-	}
-
-	/*
-	 * Initialize the ifconfgi_net driver that does network devices 
-	 * Persistent Naming.
-	 */
-	init_ifconfig_net();
-
-	return(0);
-
-}
-
-
-/*
- * hcl_setup() - Process boot time parameters if given.
- *	"hcl="
- *	This routine gets called only if "hcl=" is given in the 
- *	boot line and before init_hcl().
- *
- *	We currently do not have any boot options .. when we do, 
- *	functionalities can be added here.
- *
- */
-static int __init hcl_setup(char *str)
-{
-    while ( (*str != '\0') && !isspace (*str) )
-    {
-#ifdef CONFIG_HCL_DEBUG
-        if (strncmp (str, "all", 3) == 0) {
-            hcl_debug_init |= HCL_DEBUG_ALL;
-            str += 3;
-        } else 
-        	return 0;
-#endif
-        if (*str != ',') return 0;
-        ++str;
-    }
-
-    return 1;
-
-}
-
-__setup("hcl=", hcl_setup);
-
-
-/*
- * Set device specific "fast information".
- *
- */
-void
-hwgraph_fastinfo_set(devfs_handle_t de, arbitrary_info_t fastinfo)
-{
-
-	if (hcl_debug) {
-		printk("HCL: hwgraph_fastinfo_set handle 0x%p fastinfo %ld\n", (void *)de, fastinfo);
-	}
-		
-	labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL);
-
-}
-
-
-/*
- * Get device specific "fast information".
- *
- */
-arbitrary_info_t
-hwgraph_fastinfo_get(devfs_handle_t de)
-{
-	arbitrary_info_t fastinfo;
-	int rv;
-
-	if (!de) {
-		printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n");
-		return(-1);
-	}
-
-	rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo);
-	if (rv == 0)
-		return(fastinfo);
-
-	return(0);
-}
-
-
-/*
- * hwgraph_connectpt_set - Sets the connect point handle in de to the 
- *	given connect_de handle.  By default, the connect point of the 
- *	devfs node is the parent.  This effectively changes this assumption.
- */
-int
-hwgraph_connectpt_set(devfs_handle_t de, devfs_handle_t connect_de)
-{
-	int rv;
-
-	if (!de)
-		return(-1);
-
-	rv = labelcl_info_connectpt_set(de, connect_de);
-
-	return(rv);
-}
-
-
-/*
- * hwgraph_connectpt_get: Returns the entry's connect point  in the devfs 
- *	tree.
- */
-devfs_handle_t
-hwgraph_connectpt_get(devfs_handle_t de)
-{
-	int rv;
-	arbitrary_info_t info;
-	devfs_handle_t connect;
-
-	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
-	if (rv != 0) {
-		return(NULL);
-	}
-
-	connect = (devfs_handle_t)info;
-	return(connect);
-
-}
-
-
-/*
- * hwgraph_mk_dir - Creates a directory entry with devfs.
- *	Note that a directory entry in devfs can have children 
- *	but it cannot be a char|block special file.
- */
-devfs_handle_t
-hwgraph_mk_dir(devfs_handle_t de, const char *name,
-                unsigned int namelen, void *info)
-{
-
-	int rv;
-	labelcl_info_t *labelcl_info = NULL;
-	devfs_handle_t new_devfs_handle = NULL;
-	devfs_handle_t parent = NULL;
-
-	/*
-	 * Create the device info structure for hwgraph compatiblity support.
-	 */
-	labelcl_info = labelcl_info_create();
-	if (!labelcl_info)
-		return(NULL);
-
-	/*
-	 * Create a devfs entry.
-	 */
-	new_devfs_handle = devfs_mk_dir(de, name, (void *)labelcl_info);
-	if (!new_devfs_handle) {
-		labelcl_info_destroy(labelcl_info);
-		return(NULL);
-	}
-
-	/*
-	 * Get the parent handle.
-	 */
-	parent = devfs_get_parent (new_devfs_handle);
-
-	/*
-	 * To provide the same semantics as the hwgraph, set the connect point.
-	 */
-	rv = hwgraph_connectpt_set(new_devfs_handle, parent);
-	if (!rv) {
-		/*
-		 * We need to clean up!
-		 */
-	}
-
-	/*
-	 * If the caller provides a private data pointer, save it in the 
-	 * labelcl info structure(fastinfo).  This can be retrieved via
-	 * hwgraph_fastinfo_get()
-	 */
-	if (info)
-		hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
-		
-	return(new_devfs_handle);
-
-}
-
-/*
- * hwgraph_vertex_create - Create a vertex by giving it a temp name.
- */
-
-/*
- * hwgraph_path_add - Create a directory node with the given path starting 
- * from the given devfs_handle_t.
- */
-extern char * dev_to_name(devfs_handle_t, char *, uint);
-int
-hwgraph_path_add(devfs_handle_t  fromv,
-		 char *path,
-		 devfs_handle_t *new_de)
-{
-
-	unsigned int	namelen = strlen(path);
-	int		rv;
-
-	/*
-	 * We need to handle the case when fromv is NULL ..
-	 * in this case we need to create the path from the 
-	 * hwgraph root!
-	 */
-	if (fromv == NULL)
-		fromv = hwgraph_root;
-
-	/*
-	 * check the entry doesn't already exist, if it does
-	 * then we simply want new_de to point to it (otherwise
-	 * we'll overwrite the existing labelcl_info struct)
-	 */
-	rv = hwgraph_edge_get(fromv, path, new_de);
-	if (rv)	{	/* couldn't find entry so we create it */
-		*new_de = hwgraph_mk_dir(fromv, path, namelen, NULL);
-		if (new_de == NULL)
-			return(-1);
-		else
-			return(0);
-	}
-	else 
- 		return(0);
-
-}
-
-/*
- * hwgraph_register  - Creates a file entry with devfs.
- *	Note that a file entry cannot have children .. it is like a 
- *	char|block special vertex in hwgraph.
- */
-devfs_handle_t
-hwgraph_register(devfs_handle_t de, const char *name,
-                unsigned int namelen, unsigned int flags, 
-		unsigned int major, unsigned int minor,
-                umode_t mode, uid_t uid, gid_t gid, 
-		struct file_operations *fops,
-                void *info)
-{
-
-	int rv;
-        void *labelcl_info = NULL;
-        devfs_handle_t new_devfs_handle = NULL;
-	devfs_handle_t parent = NULL;
-
-        /*
-         * Create the labelcl info structure for hwgraph compatiblity support.
-         */
-        labelcl_info = labelcl_info_create();
-        if (!labelcl_info)
-                return(NULL);
-
-        /*
-         * Create a devfs entry.
-         */
-        new_devfs_handle = devfs_register(de, name, flags, major,
-				minor, mode, fops, labelcl_info);
-        if (!new_devfs_handle) {
-                labelcl_info_destroy((labelcl_info_t *)labelcl_info);
-                return(NULL);
-        }
-
-	/*
-	 * Get the parent handle.
-	 */
-	if (de == NULL)
-		parent = devfs_get_parent (new_devfs_handle);
-	else
-		parent = de;
-		
-	/*
-	 * To provide the same semantics as the hwgraph, set the connect point.
-	 */
-	rv = hwgraph_connectpt_set(new_devfs_handle, parent);
-	if (rv) {
-		/*
-		 * We need to clean up!
-		 */
-		printk(KERN_WARNING "HCL: Unable to set the connect point to it's parent 0x%p\n",
-			(void *)new_devfs_handle);
-	}
-
-        /*
-         * If the caller provides a private data pointer, save it in the 
-         * labelcl info structure(fastinfo).  This can be retrieved via
-         * hwgraph_fastinfo_get()
-         */
-        if (info)
-                hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
-
-        return(new_devfs_handle);
-
-}
-
-
-/*
- * hwgraph_mk_symlink - Create a symbolic link.
- */
-int
-hwgraph_mk_symlink(devfs_handle_t de, const char *name, unsigned int namelen,
-                unsigned int flags, const char *link, unsigned int linklen, 
-		devfs_handle_t *handle, void *info)
-{
-
-	void *labelcl_info = NULL;
-	int status = 0;
-	devfs_handle_t new_devfs_handle = NULL;
-
-	/*
-	 * Create the labelcl info structure for hwgraph compatiblity support.
-	 */
-	labelcl_info = labelcl_info_create();
-	if (!labelcl_info)
-		return(-1);
-
-	/*
-	 * Create a symbolic link devfs entry.
-	 */
-	status = devfs_mk_symlink(de, name, flags, link,
-				&new_devfs_handle, labelcl_info);
-	if ( (!new_devfs_handle) || (!status) ){
-		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
-		return(-1);
-	}
-
-	/*
-	 * If the caller provides a private data pointer, save it in the 
-	 * labelcl info structure(fastinfo).  This can be retrieved via
-	 * hwgraph_fastinfo_get()
-	 */
-	if (info)
-		hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
-
-	*handle = new_devfs_handle;
-	return(0);
-
-}
-
-/*
- * hwgraph_vertex_get_next - this routine returns the next sibbling for the 
- *	device entry given in de.  If there are no more sibbling, NULL 
- * 	is returned in next_sibbling.
- *
- *	Currently we do not have any protection against de being deleted 
- *	while it's handle is being held.
- */
-int
-hwgraph_vertex_get_next(devfs_handle_t *next_sibbling, devfs_handle_t *de)
-{
-	*next_sibbling = devfs_get_next_sibling (*de);
-
-	if (*next_sibbling != NULL)
-		*de = *next_sibbling;
-	return (0);
-}
-
-
-/*
- * hwgraph_vertex_destroy - Destroy the devfs entry
- */
-int
-hwgraph_vertex_destroy(devfs_handle_t de)
-{
-
-	void *labelcl_info = NULL;
-
-	labelcl_info = devfs_get_info(de);
-	devfs_unregister(de);
-
-	if (labelcl_info)
-		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
-
-	return(0);
-}
-
-/*
-** See if a vertex has an outgoing edge with a specified name.
-** Vertices in the hwgraph *implicitly* contain these edges:
-**	"." 	refers to "current vertex"
-**	".." 	refers to "connect point vertex"
-**	"char"	refers to current vertex (character device access)
-**	"block"	refers to current vertex (block device access)
-*/
-
-/*
- * hwgraph_edge_add - This routines has changed from the original conext.
- * All it does now is to create a symbolic link from "from" to "to".
- */
-/* ARGSUSED */
-int
-hwgraph_edge_add(devfs_handle_t from, devfs_handle_t to, char *name)
-{
-
-	char *path;
-	char *s1;
-	char *index;
-	int name_start;
-	devfs_handle_t handle = NULL;
-	int rv;
-	int i, count;
-
-	path = kmalloc(1024, GFP_KERNEL);
-	memset(path, 0x0, 1024);
-	name_start = devfs_generate_path (from, path, 1024);
-	s1 = &path[name_start];
-	count = 0;
-	while (1) {
-		index = strstr (s1, "/");
-		if (index) {
-			count++;
-			s1 = ++index;
-		} else {
-			count++;
-			break;
-		}
-	}
-
-	memset(path, 0x0, 1024);
-	name_start = devfs_generate_path (to, path, 1024);
-
-	for (i = 0; i < count; i++) {
-		strcat(path,"../");
-	}
-
-	strcat(path, &path[name_start]);
-
-	/*
-	 * Otherwise, just create a symlink to the vertex.
-	 * In this case the vertex was previous created with a REAL pathname.
-	 */
-	rv = devfs_mk_symlink (from, (const char *)name, 
-			       DEVFS_FL_DEFAULT, path,
-			       &handle, NULL);
-
-	name_start = devfs_generate_path (handle, path, 1024);
-	return(rv);
-
-	
-}
-/* ARGSUSED */
-int
-hwgraph_edge_get(devfs_handle_t from, char *name, devfs_handle_t *toptr)
-{
-
-	int namelen = 0;
-	devfs_handle_t target_handle = NULL;
-
-	if (name == NULL)
-		return(-1);
-
-	if (toptr == NULL)
-		return(-1);
-
-	/*
-	 * If the name is "." just return the current devfs entry handle.
-	 */
-	if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) {
-		if (toptr) {
-			*toptr = from;
-		}
-	} else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) {
-		/*
-		 * Hmmm .. should we return the connect point or parent ..
-		 * see in hwgraph, the concept of parent is the connectpt!
-		 *
-		 * Maybe we should see whether the connectpt is set .. if 
-		 * not just return the parent!
-		 */
-		target_handle = hwgraph_connectpt_get(from);
-		if (target_handle) {
-			/*
-			 * Just return the connect point.
-			 */
-			*toptr = target_handle;
-			return(0);
-		}
-		target_handle = devfs_get_parent(from);
-		*toptr = target_handle;
-
-	} else {
-		/*
-		 * Call devfs to get the devfs entry.
-		 */
-		namelen = (int) strlen(name);
-		target_handle = devfs_find_handle (from, name, 0, 0,
-					0, 1); /* Yes traverse symbolic links */
-		if (target_handle == NULL)
-			return(-1);
-		else
-		*toptr = target_handle;
-	}
-
-	return(0);
-}
-
-
-/*
- * hwgraph_edge_get_next - Retrieves the next sibbling given the current
- *	entry number "placeptr".
- *
- * 	Allow the caller to retrieve walk through the sibblings of "source" 
- * 	devfs_handle_t.  The implicit edges "." and ".." is returned first 
- * 	followed by each of the real children.
- *
- *	We may end up returning garbage if another thread perform any deletion 
- *	in this directory before "placeptr".
- *
- */
-/* ARGSUSED */
-int
-hwgraph_edge_get_next(devfs_handle_t source, char *name, devfs_handle_t *target,
-                              uint *placeptr)
-
-{
-
-        uint which_place;
-	unsigned int namelen = 0;
-	const char *tempname = NULL;
-
-        if (placeptr == NULL)
-                return(-1);
-
-        which_place = *placeptr;
-
-again:
-        if (which_place <= HWGRAPH_RESERVED_PLACES) {
-                if (which_place == EDGE_PLACE_WANT_CURRENT) {
-			/*
-			 * Looking for "."
-			 * Return the current devfs handle.
-			 */
-                        if (name != NULL)
-                                strcpy(name, HWGRAPH_EDGELBL_DOT);
-
-                        if (target != NULL) {
-                                *target = source; 
-				/* XXX should incr "source" ref count here if we
-				 * ever implement ref counts */
-                        }
-
-                } else if (which_place == EDGE_PLACE_WANT_CONNECTPT) {
-			/*
-			 * Looking for the connect point or parent.
-			 * If the connect point is set .. it returns the connect point.
-			 * Otherwise, it returns the parent .. will we support 
-			 * connect point?
-			 */
-                        devfs_handle_t connect_point = hwgraph_connectpt_get(source);
-
-                        if (connect_point == NULL) {
-				/*
-				 * No connectpoint set .. either the User
-				 * explicitly NULL it or this node was not 
-				 * created via hcl.
-				 */
-                                which_place++;
-                                goto again;
-                        }
-
-                        if (name != NULL)
-                                strcpy(name, HWGRAPH_EDGELBL_DOTDOT);
-
-                        if (target != NULL)
-                                *target = connect_point;
-
-                } else if (which_place == EDGE_PLACE_WANT_REAL_EDGES) {
-			/* 
-			 * return first "real" entry in directory, and increment
-			 * placeptr.  Next time around we should have 
-			 * which_place > HWGRAPH_RESERVED_EDGES so we'll fall through
-			 * this nested if block.
-			 */
-			*target = devfs_get_first_child(source);
-			if (*target && name) {
-				tempname = devfs_get_name(*target, &namelen);
-				if (tempname && namelen)
-					strcpy(name, tempname);
-			}
-					
-			*placeptr = which_place + 1;
-			return (0);
-                }
-
-                *placeptr = which_place+1;
-                return(0);
-        }
-
-	/*
-	 * walk linked list, (which_place - HWGRAPH_RESERVED_PLACES) times
-	 */
-	{
-		devfs_handle_t	curr;
-		int		i = 0;
-
-		for (curr=devfs_get_first_child(source), i= i+HWGRAPH_RESERVED_PLACES; 
-			curr!=NULL && i<which_place; 
-			curr=devfs_get_next_sibling(curr), i++)
-			;
-		*target = curr;
-		*placeptr = which_place + 1;
-		if (curr && name) {
-			tempname = devfs_get_name(*target, &namelen);
-			if (tempname && namelen)
-				strcpy(name, tempname);
-		}
-	}
-	if (target == NULL)
-		return(-1);
-	else
-        	return(0);
-}
-
-/*
- * hwgraph_info_add_LBL - Adds a new label for the device.  Mark the info_desc
- *	of the label as INFO_DESC_PRIVATE and store the info in the label.
- */
-/* ARGSUSED */
-int
-hwgraph_info_add_LBL(	devfs_handle_t de,
-			char *name,
-			arbitrary_info_t info)
-{
-	return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info));
-}
-
-/*
- * hwgraph_info_remove_LBL - Remove the label entry for the device.
- */
-/* ARGSUSED */
-int
-hwgraph_info_remove_LBL(	devfs_handle_t de,
-				char *name,
-				arbitrary_info_t *old_info)
-{
-	return(labelcl_info_remove_LBL(de, name, NULL, old_info));
-}
-
-/*
- * hwgraph_info_replace_LBL - replaces an existing label with 
- *	a new label info value.
- */
-/* ARGSUSED */
-int
-hwgraph_info_replace_LBL(	devfs_handle_t de,
-				char *name,
-				arbitrary_info_t info,
-				arbitrary_info_t *old_info)
-{
-	return(labelcl_info_replace_LBL(de, name,
-			INFO_DESC_PRIVATE, info,
-			NULL, old_info));
-}
-/*
- * hwgraph_info_get_LBL - Get and return the info value in the label of the 
- * 	device.
- */
-/* ARGSUSED */
-int
-hwgraph_info_get_LBL(	devfs_handle_t de,
-			char *name,
-			arbitrary_info_t *infop)
-{
-	return(labelcl_info_get_LBL(de, name, NULL, infop));
-}
-
-/*
- * hwgraph_info_get_exported_LBL - Retrieve the info_desc and info pointer 
- *	of the given label for the device.  The weird thing is that the label 
- *	that matches the name is return irrespective of the info_desc value!
- *	Do not understand why the word "exported" is used!
- */
-/* ARGSUSED */
-int
-hwgraph_info_get_exported_LBL(	devfs_handle_t de,
-				char *name,
-				int *export_info,
-				arbitrary_info_t *infop)
-{
-	int rc;
-	arb_info_desc_t info_desc;
-
-	rc = labelcl_info_get_LBL(de, name, &info_desc, infop);
-	if (rc == 0)
-		*export_info = (int)info_desc;
-
-	return(rc);
-}
-
-/*
- * hwgraph_info_get_next_LBL - Returns the next label info given the 
- *	current label entry in place.
- *
- *	Once again this has no locking or reference count for protection.
- *
- */
-/* ARGSUSED */
-int
-hwgraph_info_get_next_LBL(	devfs_handle_t de,
-				char *buf,
-				arbitrary_info_t *infop,
-				labelcl_info_place_t *place)
-{
-	return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place));
-}
-
-/*
- * hwgraph_info_export_LBL - Retrieve the specified label entry and modify 
- *	the info_desc field with the given value in nbytes.
- */
-/* ARGSUSED */
-int
-hwgraph_info_export_LBL(devfs_handle_t de, char *name, int nbytes)
-{
-	arbitrary_info_t info;
-	int rc;
-
-	if (nbytes == 0)
-		nbytes = INFO_DESC_EXPORT;
-
-	if (nbytes < 0)
-		return(-1);
-
-	rc = labelcl_info_get_LBL(de, name, NULL, &info);
-	if (rc != 0)
-		return(rc);
-
-	rc = labelcl_info_replace_LBL(de, name,
-				nbytes, info, NULL, NULL);
-
-	return(rc);
-}
-
-/*
- * hwgraph_info_unexport_LBL - Retrieve the given label entry and change the 
- * label info_descr filed to INFO_DESC_PRIVATE.
- */
-/* ARGSUSED */
-int
-hwgraph_info_unexport_LBL(devfs_handle_t de, char *name)
-{
-	arbitrary_info_t info;
-	int rc;
-
-	rc = labelcl_info_get_LBL(de, name, NULL, &info);
-	if (rc != 0)
-		return(rc);
-
-	rc = labelcl_info_replace_LBL(de, name,
-				INFO_DESC_PRIVATE, info, NULL, NULL);
-
-	return(rc);
-}
-
-/*
- * hwgraph_path_lookup - return the handle for the given path.
- *
- */
-int
-hwgraph_path_lookup(	devfs_handle_t start_vertex_handle,
-			char *lookup_path,
-			devfs_handle_t *vertex_handle_ptr,
-			char **remainder)
-{
-	*vertex_handle_ptr = devfs_find_handle(start_vertex_handle,	/* start dir */
-					lookup_path,		/* path */
-					0,			/* major */
-					0,			/* minor */
-					0,			/* char | block */
-					1);			/* traverse symlinks */
-	if (*vertex_handle_ptr == NULL)
-		return(-1);
-	else
-		return(0);
-}
-
-/*
- * hwgraph_traverse - Find and return the devfs handle starting from de.
- *
- */
-graph_error_t
-hwgraph_traverse(devfs_handle_t de, char *path, devfs_handle_t *found)
-{
-	/* 
-	 * get the directory entry (path should end in a directory)
-	 */
-
-	*found = devfs_find_handle(de,	/* start dir */
-			    path,	/* path */
-			    0,		/* major */
-			    0,		/* minor */
-			    0,		/* char | block */
-			    1);		/* traverse symlinks */
-	if (*found == NULL)
-		return(GRAPH_NOT_FOUND);
-	else
-		return(GRAPH_SUCCESS);
-}
-
-/*
- * hwgraph_path_to_vertex - Return the devfs entry handle for the given 
- *	pathname .. assume traverse symlinks too!.
- */
-devfs_handle_t
-hwgraph_path_to_vertex(char *path)
-{
-	return(devfs_find_handle(NULL,	/* start dir */
-			path,		/* path */
-		    	0,		/* major */
-		    	0,		/* minor */
-		    	0,		/* char | block */
-		    	1));		/* traverse symlinks */
-}
-
-/*
- * hwgraph_path_to_dev - Returns the devfs_handle_t of the given path ..
- *	We only deal with devfs handle and not devfs_handle_t.
-*/
-devfs_handle_t
-hwgraph_path_to_dev(char *path)
-{
-	devfs_handle_t  de;
-
-	de = hwgraph_path_to_vertex(path);
-	return(de);
-}
-
-/*
- * hwgraph_block_device_get - return the handle of the block device file.
- *	The assumption here is that de is a directory.
-*/
-devfs_handle_t
-hwgraph_block_device_get(devfs_handle_t de)
-{
-	return(devfs_find_handle(de,		/* start dir */
-			"block",		/* path */
-		    	0,			/* major */
-		    	0,			/* minor */
-		    	DEVFS_SPECIAL_BLK,	/* char | block */
-		    	1));			/* traverse symlinks */
-}
-
-/*
- * hwgraph_char_device_get - return the handle of the char device file.
- *      The assumption here is that de is a directory.
-*/
-devfs_handle_t
-hwgraph_char_device_get(devfs_handle_t de)
-{
-	return(devfs_find_handle(de,		/* start dir */
-			"char",			/* path */
-		    	0,			/* major */
-		    	0,			/* minor */
-		    	DEVFS_SPECIAL_CHR,	/* char | block */
-		    	1));			/* traverse symlinks */
-}
-
-/*
-** Inventory is now associated with a vertex in the graph.  For items that
-** belong in the inventory but have no vertex 
-** (e.g. old non-graph-aware drivers), we create a bogus vertex under the 
-** INFO_LBL_INVENT name.
-**
-** For historical reasons, we prevent exact duplicate entries from being added
-** to a single vertex.
-*/
-
-/*
- * hwgraph_inventory_add - Adds an inventory entry into de.
- */
-int
-hwgraph_inventory_add(	devfs_handle_t de,
-			int class,
-			int type,
-			major_t controller,
-			minor_t unit,
-			int state)
-{
-	inventory_t *pinv = NULL, *old_pinv = NULL, *last_pinv = NULL;
-	int rv;
-
-	/*
-	 * Add our inventory data to the list of inventory data
-	 * associated with this vertex.
-	 */
-again:
-	/* GRAPH_LOCK_UPDATE(&invent_lock); */
-	rv = labelcl_info_get_LBL(de,
-			INFO_LBL_INVENT,
-			NULL, (arbitrary_info_t *)&old_pinv);
-	if ((rv != LABELCL_SUCCESS) && (rv != LABELCL_NOT_FOUND))
-		goto failure;
-
-	/*
-	 * Seek to end of inventory items associated with this
-	 * vertex.  Along the way, make sure we're not duplicating
-	 * an inventory item (for compatibility with old add_to_inventory)
-	 */
-	for (;old_pinv; last_pinv = old_pinv, old_pinv = old_pinv->inv_next) {
-		if ((int)class != -1 && old_pinv->inv_class != class)
-			continue;
-		if ((int)type != -1 && old_pinv->inv_type != type)
-			continue;
-		if ((int)state != -1 && old_pinv->inv_state != state)
-			continue;
-		if ((int)controller != -1
-		    && old_pinv->inv_controller != controller)
-			continue;
-		if ((int)unit != -1 && old_pinv->inv_unit != unit)
-			continue;
-
-		/* exact duplicate of previously-added inventory item */
-		rv = LABELCL_DUP;
-		goto failure;
-	}
-
-	/* Not a duplicate, so we know that we need to add something. */
-	if (pinv == NULL) {
-		/* Release lock while we wait for memory. */
-		/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */
-		pinv = (inventory_t *)kmalloc(sizeof(inventory_t), GFP_KERNEL);
-		replace_in_inventory(pinv, class, type, controller, unit, state);
-		goto again;
-	}
-
-	pinv->inv_next = NULL;
-	if (last_pinv) {
-		last_pinv->inv_next = pinv;
-	} else {
-		rv = labelcl_info_add_LBL(de, INFO_LBL_INVENT, 
-			sizeof(inventory_t), (arbitrary_info_t)pinv);
-
-		if (!rv)
-			goto failure;
-	}
-
-	/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */
-	return(0);
-
-failure:
-	/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */
-	if (pinv)
-		kfree(pinv);
-	return(rv);
-}
-
-
-/*
- * hwgraph_inventory_remove - Removes an inventory entry.
- *
- *	Remove an inventory item associated with a vertex.   It is the caller's
- *	responsibility to make sure that there are no races between removing
- *	inventory from a vertex and simultaneously removing that vertex.
-*/
-int
-hwgraph_inventory_remove(	devfs_handle_t de,
-				int class,
-				int type,
-				major_t controller,
-				minor_t unit,
-				int state)
-{
-	inventory_t *pinv = NULL, *last_pinv = NULL, *next_pinv = NULL;
-	labelcl_error_t rv;
-
-	/*
-	 * We never remove stuff from ".invent" ..
-	 */
-	if (!de)
-		return (-1);
-
-	/*
-	 * Remove our inventory data to the list of inventory data
-	 * associated with this vertex.
-	 */
-	/* GRAPH_LOCK_UPDATE(&invent_lock); */
-	rv = labelcl_info_get_LBL(de,
-			INFO_LBL_INVENT,
-			NULL, (arbitrary_info_t *)&pinv);
-	if (rv != LABELCL_SUCCESS)
-		goto failure;
-
-	/*
-	 * Search through inventory items associated with this
-	 * vertex, looking for a match.
-	 */
-	for (;pinv; pinv = next_pinv) {
-		next_pinv = pinv->inv_next;
-
-		if(((int)class == -1 || pinv->inv_class == class) &&
-		   ((int)type == -1 || pinv->inv_type == type) &&
-		   ((int)state == -1 || pinv->inv_state == state) &&
-		   ((int)controller == -1 || pinv->inv_controller == controller) &&
-		   ((int)unit == -1 || pinv->inv_unit == unit)) {
-
-			/* Found a matching inventory item. Remove it. */
-			if (last_pinv) {
-				last_pinv->inv_next = pinv->inv_next;
-			} else {
-				rv = hwgraph_info_replace_LBL(de, INFO_LBL_INVENT, (arbitrary_info_t)pinv->inv_next, NULL);
-				if (rv != LABELCL_SUCCESS)
-					goto failure;
-			}
-
-			pinv->inv_next = NULL; /* sanity */
-			kfree(pinv);
-		} else
-			last_pinv = pinv;
-	}
-
-	if (last_pinv == NULL) {
-		rv = hwgraph_info_remove_LBL(de, INFO_LBL_INVENT, NULL);
-		if (rv != LABELCL_SUCCESS)
-			goto failure;
-	}
-
-	rv = LABELCL_SUCCESS;
-
-failure:
-	/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */
-	return(rv);
-}
-
-/*
- * hwgraph_inventory_get_next - Get next inventory item associated with the 
- *	specified vertex.
- *
- *	No locking is really needed.  We don't yet have the ability
- *	to remove inventory items, and new items are always added to
- *	the end of a vertex' inventory list.
- *
- * 	However, a devfs entry can be removed!
-*/
-int
-hwgraph_inventory_get_next(devfs_handle_t de, invplace_t *place, inventory_t **ppinv)
-{
-	inventory_t *pinv;
-	labelcl_error_t rv;
-
-	if (de == NULL)
-		return(LABELCL_BAD_PARAM);
-
-	if (place->invplace_vhdl == NULL) {
-		place->invplace_vhdl = de;
-		place->invplace_inv = NULL;
-	}
-
-	if (de != place->invplace_vhdl)
-		return(LABELCL_BAD_PARAM);
-
-	if (place->invplace_inv == NULL) {
-		/* Just starting on this vertex */
-		rv = labelcl_info_get_LBL(de, INFO_LBL_INVENT,
-						NULL, (arbitrary_info_t *)&pinv);
-		if (rv != LABELCL_SUCCESS)
-			return(LABELCL_NOT_FOUND);
-
-	} else {
-		/* Advance to next item on this vertex */
-		pinv = place->invplace_inv->inv_next;
-	}
-	place->invplace_inv = pinv;
-	*ppinv = pinv;
-
-	return(LABELCL_SUCCESS);
-}
-
-/*
- * hwgraph_controller_num_get - Returns the controller number in the inventory 
- *	entry.
- */
-int
-hwgraph_controller_num_get(devfs_handle_t device)
-{
-	inventory_t *pinv;
-	invplace_t invplace = { NULL, NULL, NULL };
-	int val = -1;
-	if ((pinv = device_inventory_get_next(device, &invplace)) != NULL) {
-		val = (pinv->inv_class == INV_NETWORK)? pinv->inv_unit: pinv->inv_controller;
-	}
-#ifdef DEBUG
-	/*
-	 * It does not make any sense to call this on vertexes with multiple
-	 * inventory structs chained together
-	 */
-	if ( device_inventory_get_next(device, &invplace) != NULL ) {
-		printk("Should panic here ... !\n");
-#endif
-	return (val);	
-}
-
-/*
- * hwgraph_controller_num_set - Sets the controller number in the inventory 
- *	entry.
- */
-void
-hwgraph_controller_num_set(devfs_handle_t device, int contr_num)
-{
-	inventory_t *pinv;
-	invplace_t invplace = { NULL, NULL, NULL };
-	if ((pinv = device_inventory_get_next(device, &invplace)) != NULL) {
-		if (pinv->inv_class == INV_NETWORK)
-			pinv->inv_unit = contr_num;
-		else {
-			if (pinv->inv_class == INV_FCNODE)
-				pinv = device_inventory_get_next(device, &invplace);
-			if (pinv != NULL)
-				pinv->inv_controller = contr_num;
-		}
-	}
-#ifdef DEBUG
-	/*
-	 * It does not make any sense to call this on vertexes with multiple
-	 * inventory structs chained together
-	 */
-	if(pinv != NULL)
-		ASSERT(device_inventory_get_next(device, &invplace) == NULL);
-#endif
-}
-
-/*
- * Find the canonical name for a given vertex by walking back through
- * connectpt's until we hit the hwgraph root vertex (or until we run
- * out of buffer space or until something goes wrong).
- *
- *	COMPATIBILITY FUNCTIONALITY
- * Walks back through 'parents', not necessarily the same as connectpts.
- *
- * Need to resolve the fact that devfs does not return the path from 
- * "/" but rather it just stops right before /dev ..
- */
-int
-hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen)
-{
-	char *locbuf;
-	int   pos;
-
-	if (buflen < 1)
-		return(-1);	/* XXX should be GRAPH_BAD_PARAM ? */
-
-	locbuf = kmalloc(buflen, GFP_KERNEL);
-
-	pos = devfs_generate_path(vhdl, locbuf, buflen);
-	if (pos < 0) {
-		kfree(locbuf);
-		return pos;
-	}
-
-	strcpy(buf, &locbuf[pos]);
-	kfree(locbuf);
-	return 0;
-}
-
-/*
-** vertex_to_name converts a vertex into a canonical name by walking
-** back through connect points until we hit the hwgraph root (or until
-** we run out of buffer space).
-**
-** Usually returns a pointer to the original buffer, filled in as
-** appropriate.  If the buffer is too small to hold the entire name,
-** or if anything goes wrong while determining the name, vertex_to_name
-** returns "UnknownDevice".
-*/
-
-#define DEVNAME_UNKNOWN "UnknownDevice"
-
-char *
-vertex_to_name(devfs_handle_t vhdl, char *buf, uint buflen)
-{
-	if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS)
-		return(buf);
-	else
-		return(DEVNAME_UNKNOWN);
-}
-
-#ifdef LATER
-/*
-** Return the compact node id of the node that ultimately "owns" the specified
-** vertex.  In order to do this, we walk back through masters and connect points
-** until we reach a vertex that represents a node.
-*/
-cnodeid_t
-master_node_get(devfs_handle_t vhdl)
-{
-	cnodeid_t cnodeid;
-	devfs_handle_t master;
-
-	for (;;) {
-		cnodeid = nodevertex_to_cnodeid(vhdl);
-		if (cnodeid != CNODEID_NONE)
-			return(cnodeid);
-
-		master = device_master_get(vhdl);
-
-		/* Check for exceptional cases */
-		if (master == vhdl) {
-			/* Since we got a reference to the "master" thru
-			 * device_master_get() we should decrement
-			 * its reference count by 1
-			 */
-			hwgraph_vertex_unref(master);
-			return(CNODEID_NONE);
-		}
-
-		if (master == GRAPH_VERTEX_NONE) {
-			master = hwgraph_connectpt_get(vhdl);
-			if ((master == GRAPH_VERTEX_NONE) ||
-			    (master == vhdl)) {
-				if (master == vhdl)
-					/* Since we got a reference to the
-					 * "master" thru
-					 * hwgraph_connectpt_get() we should
-					 * decrement its reference count by 1
-					 */
-					hwgraph_vertex_unref(master);
-				return(CNODEID_NONE);
-			}
-		}
-		
-		vhdl = master;
-		/* Decrement the reference to "master" which was got
-		 * either thru device_master_get() or hwgraph_connectpt_get()
-		 * above.
-		 */
-		hwgraph_vertex_unref(master);
-	}
-}
-
-/*
- * Using the canonical path name to get hold of the desired vertex handle will
- * not work on multi-hub sn0 nodes. Hence, we use the following (slightly
- * convoluted) algorithm.
- *
- * - Start at the vertex corresponding to the driver (provided as input parameter)
- * - Loop till you reach a vertex which has EDGE_LBL_MEMORY
- *    - If EDGE_LBL_CONN exists, follow that up.
- *      else if EDGE_LBL_MASTER exists, follow that up.
- *      else follow EDGE_LBL_DOTDOT up.
- *
- * * We should be at desired hub/heart vertex now *
- * - Follow EDGE_LBL_CONN to the widget vertex.
- *
- * - return vertex handle of this widget.
- */
-devfs_handle_t
-mem_vhdl_get(devfs_handle_t drv_vhdl)
-{
-devfs_handle_t cur_vhdl, cur_upper_vhdl;
-devfs_handle_t tmp_mem_vhdl, mem_vhdl;
-graph_error_t loop_rv;
-
-  /* Initializations */
-  cur_vhdl = drv_vhdl;
-  loop_rv = ~GRAPH_SUCCESS;
-
-  /* Loop till current vertex has EDGE_LBL_MEMORY */
-  while (loop_rv != GRAPH_SUCCESS) {
-
-    if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_CONN, &cur_upper_vhdl)) == GRAPH_SUCCESS) {
-
-    } else if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_MASTER, &cur_upper_vhdl)) == GRAPH_SUCCESS) {
-      } else { /* Follow HWGRAPH_EDGELBL_DOTDOT up */
-           (void) hwgraph_edge_get(cur_vhdl, HWGRAPH_EDGELBL_DOTDOT, &cur_upper_vhdl);
-        }
-
-    cur_vhdl = cur_upper_vhdl;
-
-#if DEBUG && HWG_DEBUG
-    printf("Current vhdl %d \n", cur_vhdl);
-#endif /* DEBUG */
-
-    loop_rv = hwgraph_edge_get(cur_vhdl, EDGE_LBL_MEMORY, &tmp_mem_vhdl);
-  }
-
-  /* We should be at desired hub/heart vertex now */
-  if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_CONN, &mem_vhdl)) != GRAPH_SUCCESS)
-    return (GRAPH_VERTEX_NONE);
-
-  return (mem_vhdl);
-}
-#endif /* LATER */
-
-
-/*
-** Add a char device -- if the driver supports it -- at a specified vertex.
-*/
-graph_error_t
-hwgraph_char_device_add(        devfs_handle_t from,
-                                char *path,
-                                char *prefix,
-                                devfs_handle_t *devhdl)
-{
-	devfs_handle_t xx = NULL;
-
-	printk("WARNING: hwgraph_char_device_add() not supported .. use hwgraph_register.\n");
-	*devhdl = xx;	// Must set devhdl
-	return(GRAPH_SUCCESS);
-}
-
-graph_error_t
-hwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr)
-{
-	printk("WARNING: hwgraph_edge_remove NOT supported.\n");
-	return(GRAPH_ILLEGAL_REQUEST);
-}
-
-graph_error_t
-hwgraph_vertex_unref(devfs_handle_t vhdl)
-{
-	return(GRAPH_ILLEGAL_REQUEST);
-}
-
-
-EXPORT_SYMBOL(hwgraph_mk_dir);
-EXPORT_SYMBOL(hwgraph_path_add);
-EXPORT_SYMBOL(hwgraph_char_device_add);
-EXPORT_SYMBOL(hwgraph_register);
-EXPORT_SYMBOL(hwgraph_vertex_destroy);
-
-EXPORT_SYMBOL(hwgraph_fastinfo_get);
-EXPORT_SYMBOL(hwgraph_edge_get);
-
-EXPORT_SYMBOL(hwgraph_fastinfo_set);
-EXPORT_SYMBOL(hwgraph_connectpt_set);
-EXPORT_SYMBOL(hwgraph_connectpt_get);
-EXPORT_SYMBOL(hwgraph_edge_get_next);
-EXPORT_SYMBOL(hwgraph_info_add_LBL);
-EXPORT_SYMBOL(hwgraph_info_remove_LBL);
-EXPORT_SYMBOL(hwgraph_info_replace_LBL);
-EXPORT_SYMBOL(hwgraph_info_get_LBL);
-EXPORT_SYMBOL(hwgraph_info_get_exported_LBL);
-EXPORT_SYMBOL(hwgraph_info_get_next_LBL);
-EXPORT_SYMBOL(hwgraph_info_export_LBL);
-EXPORT_SYMBOL(hwgraph_info_unexport_LBL);
-EXPORT_SYMBOL(hwgraph_path_lookup);
-EXPORT_SYMBOL(hwgraph_traverse);
-EXPORT_SYMBOL(hwgraph_path_to_vertex);
-EXPORT_SYMBOL(hwgraph_path_to_dev);
-EXPORT_SYMBOL(hwgraph_block_device_get);
-EXPORT_SYMBOL(hwgraph_char_device_get);
-EXPORT_SYMBOL(hwgraph_vertex_name_get);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hcl_util.c linux-2.4.22-pre10/arch/ia64/sn/io/hcl_util.c
--- linux-2.4.21/arch/ia64/sn/io/hcl_util.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hcl_util.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,200 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/sn/sgi.h>
-#include <asm/io.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/nodepda.h>
-
-static devfs_handle_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE;
-extern devfs_handle_t hwgraph_root;
-
-
-/*
-** Return the "master" for a given vertex.  A master vertex is a
-** controller or adapter or other piece of hardware that the given
-** vertex passes through on the way to the rest of the system.
-*/
-devfs_handle_t
-device_master_get(devfs_handle_t vhdl)
-{
-	graph_error_t rc;
-	devfs_handle_t master;
-
-	rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master);
-	if (rc == GRAPH_SUCCESS)
-		return(master);
-	else
-		return(GRAPH_VERTEX_NONE);
-}
-
-/*
-** Set the master for a given vertex.
-** Returns 0 on success, non-0 indicates failure
-*/
-int
-device_master_set(devfs_handle_t vhdl, devfs_handle_t master)
-{
-	graph_error_t rc;
-
-	rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER);
-	return(rc != GRAPH_SUCCESS);
-}
-
-
-/*
-** Return the compact node id of the node that ultimately "owns" the specified
-** vertex.  In order to do this, we walk back through masters and connect points
-** until we reach a vertex that represents a node.
-*/
-cnodeid_t
-master_node_get(devfs_handle_t vhdl)
-{
-	cnodeid_t cnodeid;
-	devfs_handle_t master;
-
-	for (;;) {
-		cnodeid = nodevertex_to_cnodeid(vhdl);
-		if (cnodeid != CNODEID_NONE)
-			return(cnodeid);
-
-		master = device_master_get(vhdl);
-
-		/* Check for exceptional cases */
-		if (master == vhdl) {
-			/* Since we got a reference to the "master" thru
-			 * device_master_get() we should decrement
-			 * its reference count by 1
-			 */
-			return(CNODEID_NONE);
-		}
-
-		if (master == GRAPH_VERTEX_NONE) {
-			master = hwgraph_connectpt_get(vhdl);
-			if ((master == GRAPH_VERTEX_NONE) ||
-			    (master == vhdl)) {
-				return(CNODEID_NONE);
-			}
-		}
-
-		vhdl = master;
-	}
-}
-
-static devfs_handle_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE;
-extern int maxcpus;
-
-void
-mark_cpuvertex_as_cpu(devfs_handle_t vhdl, cpuid_t cpuid)
-{
-	if (cpuid == CPU_NONE)
-		return;
-
-	(void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT,
-			(arbitrary_info_t)cpuid);
-	{
-		char cpuid_buffer[10];
-
-		if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) {
-			(void)hwgraph_path_add( hwgraph_root,
-						EDGE_LBL_CPUNUM,
-						&hwgraph_all_cpuids);
-		}
-
-		sprintf(cpuid_buffer, "%ld", cpuid);
-		(void)hwgraph_edge_add( hwgraph_all_cpuids,
-							vhdl,
-							cpuid_buffer);
-	}
-}
-
-/*
-** If the specified device represents a node, return its
-** compact node ID; otherwise, return CNODEID_NONE.
-*/
-cnodeid_t
-nodevertex_to_cnodeid(devfs_handle_t vhdl)
-{
-	int rv = 0;
-	arbitrary_info_t cnodeid = CNODEID_NONE;
-
-	rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid);
-
-	return((cnodeid_t)cnodeid);
-}
-
-void
-mark_nodevertex_as_node(devfs_handle_t vhdl, cnodeid_t cnodeid)
-{
-	if (cnodeid == CNODEID_NONE)
-		return;
-
-	cnodeid_to_vertex(cnodeid) = vhdl;
-	labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, 
-		(arbitrary_info_t)cnodeid);
-
-	{
-		char cnodeid_buffer[10];
-
-		if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) {
-			(void)hwgraph_path_add( hwgraph_root,
-						EDGE_LBL_NODENUM,
-						&hwgraph_all_cnodes);
-		}
-
-		sprintf(cnodeid_buffer, "%d", cnodeid);
-		(void)hwgraph_edge_add( hwgraph_all_cnodes,
-					vhdl,
-					cnodeid_buffer);
-	}
-}
-
-/*
-** If the specified device represents a CPU, return its cpuid;
-** otherwise, return CPU_NONE.
-*/
-cpuid_t
-cpuvertex_to_cpuid(devfs_handle_t vhdl)
-{
-	arbitrary_info_t cpuid = CPU_NONE;
-
-	(void)labelcl_info_get_LBL(vhdl, INFO_LBL_CPUID, NULL, &cpuid);
-
-	return((cpuid_t)cpuid);
-}
-
-
-/*
-** dev_to_name converts a devfs_handle_t into a canonical name.  If the devfs_handle_t
-** represents a vertex in the hardware graph, it is converted in the
-** normal way for vertices.  If the devfs_handle_t is an old devfs_handle_t (one which
-** does not represent a hwgraph vertex), we synthesize a name based
-** on major/minor number.
-**
-** Usually returns a pointer to the original buffer, filled in as
-** appropriate.  If the buffer is too small to hold the entire name,
-** or if anything goes wrong while determining the name, dev_to_name
-** returns "UnknownDevice".
-*/
-char *
-dev_to_name(devfs_handle_t dev, char *buf, uint buflen)
-{
-        return(vertex_to_name(dev, buf, buflen));
-}
-
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hubdev.c linux-2.4.22-pre10/arch/ia64/sn/io/hubdev.c
--- linux-2.4.21/arch/ia64/sn/io/hubdev.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hubdev.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,132 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/sn1/hubdev.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-
-struct hubdev_callout {
-        int (*attach_method)(devfs_handle_t);
-        struct hubdev_callout *fp;
-};
-
-typedef struct hubdev_callout hubdev_callout_t;
-
-mutex_t hubdev_callout_mutex;
-hubdev_callout_t *hubdev_callout_list = NULL;
-
-void
-hubdev_init(void)
-{
-	mutex_init(&hubdev_callout_mutex);
-        hubdev_callout_list = NULL;
-}
-        
-void
-hubdev_register(int (*attach_method)(devfs_handle_t))
-{
-        hubdev_callout_t *callout;
-        
-        ASSERT(attach_method);
-
-        callout =  (hubdev_callout_t *)snia_kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP);
-        ASSERT(callout);
-        
-	mutex_lock(&hubdev_callout_mutex);
-        /*
-         * Insert at the end of the list
-         */
-        callout->fp = hubdev_callout_list;
-        hubdev_callout_list = callout;
-        callout->attach_method = attach_method;
-	mutex_unlock(&hubdev_callout_mutex);
-}
-
-int
-hubdev_unregister(int (*attach_method)(devfs_handle_t))
-{
-        hubdev_callout_t **p;
-        
-        ASSERT(attach_method);
-   
-	mutex_lock(&hubdev_callout_mutex);
-        /*
-         * Remove registry element containing attach_method
-         */
-        for (p = &hubdev_callout_list; *p != NULL; p = &(*p)->fp) {
-                if ((*p)->attach_method == attach_method) {
-                        hubdev_callout_t* victim = *p;
-                        *p = (*p)->fp;
-                        kfree(victim);
-                        mutex_unlock(&hubdev_callout_mutex);
-                        return (0);
-                }
-        }
-        mutex_unlock(&hubdev_callout_mutex);
-        return (ENOENT);
-}
-
-
-int
-hubdev_docallouts(devfs_handle_t hub)
-{
-        hubdev_callout_t *p;
-        int errcode;
-
-	mutex_lock(&hubdev_callout_mutex);
-        
-        for (p = hubdev_callout_list; p != NULL; p = p->fp) {
-                ASSERT(p->attach_method);
-                errcode = (*p->attach_method)(hub);
-                if (errcode != 0) {
-			mutex_unlock(&hubdev_callout_mutex);
-                        return (errcode);
-                }
-        }
-        mutex_unlock(&hubdev_callout_mutex);
-        return (0);
-}
-
-/*
- * Given a hub vertex, return the base address of the Hspec space
- * for that hub.
- */
-
-#if defined(CONFIG_IA64_SGI_SN1)
-
-caddr_t
-hubdev_prombase_get(devfs_handle_t hub)
-{
-	hubinfo_t	hinfo = NULL;
-
-	hubinfo_get(hub, &hinfo);
-	ASSERT(hinfo);
-
-	return ((caddr_t)NODE_RBOOT_BASE(hinfo->h_nasid));
-}
-
-cnodeid_t
-hubdev_cnodeid_get(devfs_handle_t hub)
-{
-	hubinfo_t	hinfo = NULL;
-	hubinfo_get(hub, &hinfo);
-	ASSERT(hinfo);
-
-	return hinfo->h_cnodeid;
-}
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hubspc.c linux-2.4.22-pre10/arch/ia64/sn/io/hubspc.c
--- linux-2.4.21/arch/ia64/sn/io/hubspc.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hubspc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,251 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/*
- * hubspc.c - Hub Memory Space Management Driver
- * This driver implements the managers for the following
- * memory resources:
- * 1) reference counters
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn1/mem_refcnt.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/snconfig.h>
-#include <asm/sn/sn1/hubspc.h>
-#include <asm/sn/ksys/elsc.h>
-#include <asm/sn/simulator.h>
-
-
-/* Uncomment the following line for tracing */
-/* #define HUBSPC_DEBUG 1 */
-
-int hubspc_devflag = D_MP;
-
-
-/***********************************************************************/
-/* CPU Prom Space 						       */
-/***********************************************************************/
-
-typedef struct cpuprom_info {
-	devfs_handle_t	prom_dev;
-	devfs_handle_t	nodevrtx;
-	struct	cpuprom_info *next;
-}cpuprom_info_t;
-
-static cpuprom_info_t	*cpuprom_head;
-static spinlock_t	cpuprom_spinlock;
-#define	PROM_LOCK()	mutex_spinlock(&cpuprom_spinlock)
-#define	PROM_UNLOCK(s)	mutex_spinunlock(&cpuprom_spinlock, (s))
-
-/*
- * Add prominfo to the linked list maintained.
- */
-void
-prominfo_add(devfs_handle_t hub, devfs_handle_t prom)
-{
-	cpuprom_info_t	*info;
-	unsigned long	s;
-
-	info = kmalloc(sizeof(cpuprom_info_t), GFP_KERNEL);
-	ASSERT(info);
-	info->prom_dev = prom;
-	info->nodevrtx = hub;
-
-
-	s = PROM_LOCK();
-	info->next = cpuprom_head;
-	cpuprom_head = info;
-	PROM_UNLOCK(s);
-}
-
-void
-prominfo_del(devfs_handle_t prom)
-{
-	unsigned long	s;
-	cpuprom_info_t	*info;
-	cpuprom_info_t	**prev;
-
-	s = PROM_LOCK();
-	prev = &cpuprom_head;
-	while ( (info = *prev) ) {
-		if (info->prom_dev == prom) {
-			*prev = info->next;
-			PROM_UNLOCK(s);
-			return;
-		}
-		
-		prev = &info->next;
-	}
-	PROM_UNLOCK(s);
-	ASSERT(0);
-}
-
-devfs_handle_t
-prominfo_nodeget(devfs_handle_t prom)
-{
-	unsigned long	s;
-	cpuprom_info_t	*info;
-
-	s = PROM_LOCK();
-	info = cpuprom_head;
-	while (info) {
-		if(info->prom_dev == prom) {
-			PROM_UNLOCK(s);
-			return info->nodevrtx;
-		}
-		info = info->next;
-	}
-	PROM_UNLOCK(s);
-	return 0;
-}
-
-#if defined(CONFIG_IA64_SGI_SN1)
-#define	SN_PROMVERSION		INV_IP35PROM
-
-/* Add "detailed" labelled inventory information to the
- * prom vertex 
- */
-void
-cpuprom_detailed_inventory_info_add(devfs_handle_t prom_dev,devfs_handle_t node)
-{
-	invent_miscinfo_t 	*cpuprom_inventory_info;
-	extern invent_generic_t *klhwg_invent_alloc(cnodeid_t cnode, 
-						     int class, int size);
-	cnodeid_t		cnode = hubdev_cnodeid_get(node);
-
-	/* Allocate memory for the extra inventory information
-	 * for the  prom
-	 */
-	cpuprom_inventory_info = (invent_miscinfo_t *) 
-		klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t));
-
-	ASSERT(cpuprom_inventory_info);
-
-	/* Set the enabled flag so that the hinv interprets this
-	 * information
-	 */
-	cpuprom_inventory_info->im_gen.ig_flag = INVENT_ENABLED;
-	cpuprom_inventory_info->im_type = SN_PROMVERSION;
-	/* Store prom revision into inventory information */
-	cpuprom_inventory_info->im_rev = IP27CONFIG.pvers_rev;
-	cpuprom_inventory_info->im_version = IP27CONFIG.pvers_vers;
-
-	/* Store this info as labelled information hanging off the
-	 * prom device vertex
-	 */
-	hwgraph_info_add_LBL(prom_dev, INFO_LBL_DETAIL_INVENT, 
-			     (arbitrary_info_t) cpuprom_inventory_info);
-	/* Export this information so that user programs can get to
-	 * this by using attr_get()
-	 */
-        hwgraph_info_export_LBL(prom_dev, INFO_LBL_DETAIL_INVENT,
-				sizeof(invent_miscinfo_t));
-}
-
-#endif  /* CONFIG_IA64_SGI_SN1 */
-
-
-/***********************************************************************/
-/* Base Hub Space Driver                                               */
-/***********************************************************************/
-
-/*
- * hubspc_init
- * Registration of the hubspc devices with the hub manager
- */
-void
-hubspc_init(void)
-{
-        /*
-         * Register with the hub manager
-         */
-
-        /* The reference counters */
-#if defined(CONFIG_IA64_SGI_SN1)
-        hubdev_register(mem_refcnt_attach);
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN1
-	/* L1 system controller link */
-	if ( !IS_RUNNING_ON_SIMULATOR() ) {
-		/* initialize the L1 link */
-		extern void l1_init(void);
-		l1_init();
-	}
-#endif	/* CONFIG_IA64_SGI_SN1 */
-#ifdef	HUBSPC_DEBUG
-	printk("hubspc_init: Completed\n");
-#endif	/* HUBSPC_DEBUG */
-	/* Initialize spinlocks */
-	mutex_spinlock_init(&cpuprom_spinlock);
-}
-
-/* ARGSUSED */
-int
-hubspc_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp)
-{
-        return (0);
-}
-
-
-/* ARGSUSED */
-int
-hubspc_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-        return (0);
-}
-
-/* ARGSUSED */
-int
-hubspc_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-	/*REFERENCED*/
-        int errcode = 0;
-
-	/* check validity of request */
-	if( len == 0 ) {
-		return -ENXIO;
-        }
-
-	return errcode;
-}
-
-/* ARGSUSED */
-int
-hubspc_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-	return (0);
-
-}
-
-/* ARGSUSED */
-int
-hubspc_ioctl(devfs_handle_t dev,
-             int cmd,
-             void *arg,
-             int mode,
-             cred_t *cred_p,
-             int *rvalp)
-{
-	return (0);
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hwgdfs/Makefile linux-2.4.22-pre10/arch/ia64/sn/io/hwgdfs/Makefile
--- linux-2.4.21/arch/ia64/sn/io/hwgdfs/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hwgdfs/Makefile	2003-08-01 13:34:08.000000000 +0000
@@ -0,0 +1,18 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+O_TARGET := snio.o
+
+export-objs := hcl.o
+
+obj-y				+= hcl.o labelcl.o hcl_util.o invent_stub.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hwgdfs/hcl.c linux-2.4.22-pre10/arch/ia64/sn/io/hwgdfs/hcl.c
--- linux-2.4.21/arch/ia64/sn/io/hwgdfs/hcl.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hwgdfs/hcl.c	2003-08-01 13:32:01.000000000 +0000
@@ -0,0 +1,916 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ *  hcl - SGI's Hardware Graph compatibility layer.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <asm/sn/sgi.h>
+#include <linux/devfs_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/simulator.h>
+
+#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER"
+#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE"
+#define HCL_TEMP_NAME_LEN 44 
+#define HCL_VERSION "1.0"
+vertex_hdl_t hwgraph_root;
+vertex_hdl_t linux_busnum;
+
+extern void pci_bus_cvlink_init(void);
+
+/*
+ * Debug flag definition.
+ */
+#define OPTION_NONE             0x00
+#define HCL_DEBUG_NONE 0x00000
+#define HCL_DEBUG_ALL  0x0ffff
+#if defined(CONFIG_HCL_DEBUG)
+static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE;
+#endif
+static unsigned int hcl_debug = HCL_DEBUG_NONE;
+#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
+static unsigned int boot_options = OPTION_NONE;
+#endif
+
+/*
+ * Some Global definitions.
+ */
+static vertex_hdl_t hcl_handle;
+
+invplace_t invplace_none = {
+	GRAPH_VERTEX_NONE,
+	GRAPH_VERTEX_PLACE_NONE,
+	NULL
+};
+
+/*
+ * HCL device driver.
+ * The purpose of this device driver is to provide a facility 
+ * for User Level Apps e.g. hinv, ioconfig etc. an ioctl path 
+ * to manipulate label entries without having to implement
+ * system call interfaces.  This methodology will enable us to 
+ * make this feature module loadable.
+ */
+static int hcl_open(struct inode * inode, struct file * filp)
+{
+	if (hcl_debug) {
+        	printk("HCL: hcl_open called.\n");
+	}
+
+        return(0);
+
+}
+
+static int hcl_close(struct inode * inode, struct file * filp)
+{
+
+	if (hcl_debug) {
+        	printk("HCL: hcl_close called.\n");
+	}
+
+        return(0);
+
+}
+
+static int hcl_ioctl(struct inode * inode, struct file * file,
+        unsigned int cmd, unsigned long arg)
+{
+
+	if (hcl_debug) {
+		printk("HCL: hcl_ioctl called.\n");
+	}
+
+	switch (cmd) {
+		default:
+			if (hcl_debug) {
+				printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd);
+			}
+	}
+
+	return(0);
+
+}
+
+struct file_operations hcl_fops = {
+	(struct module *)0,
+	NULL,		/* lseek - default */
+	NULL,		/* read - general block-dev read */
+	NULL,		/* write - general block-dev write */
+	NULL,		/* readdir - bad */
+	NULL,		/* poll */
+	hcl_ioctl,      /* ioctl */
+	NULL,		/* mmap */
+	hcl_open,	/* open */
+	NULL,		/* flush */
+	hcl_close,	/* release */
+	NULL,		/* fsync */
+	NULL,		/* fasync */
+	NULL,		/* lock */
+	NULL,		/* readv */
+	NULL,		/* writev */
+};
+
+
+/*
+ * init_hcl() - Boot time initialization.  Ensure that it is called 
+ *	after devfs has been initialized.
+ *
+ * For now this routine is being called out of devfs/base.c.  Actually 
+ * Not a bad place to be ..
+ *
+ */
+int __init init_hcl(void)
+{
+	extern void string_table_init(struct string_table *);
+	extern struct string_table label_string_table;
+	extern int init_ifconfig_net(void);
+	extern int init_ioconfig_bus(void);
+	int status = 0;
+	int rv = 0;
+
+	if (IS_RUNNING_ON_SIMULATOR()) {
+		extern u64 klgraph_addr[];
+		klgraph_addr[0] = 0xe000003000030000;
+	}
+
+	/*
+	 * Create the hwgraph_root on devfs.
+	 */
+	rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
+	if (rv)
+		printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
+
+	status = devfs_set_flags (hwgraph_root, DEVFS_FL_HIDE);
+
+	/*
+	 * Create the hcl driver to support inventory entry manipulations.
+	 * By default, it is expected that devfs is mounted on /dev.
+	 *
+	 */
+	hcl_handle = hwgraph_register(hwgraph_root, ".hcl",
+			0, DEVFS_FL_AUTO_DEVNUM,
+			0, 0,
+			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+			&hcl_fops, NULL);
+
+	if (hcl_handle == NULL) {
+		panic("HCL: Unable to create HCL Driver in init_hcl().\n");
+		return(0);
+	}
+
+	/*
+	 * Initialize the HCL string table.
+	 */
+	string_table_init(&label_string_table);
+
+	/*
+	 * Create the directory that links Linux bus numbers to our Xwidget.
+	 */
+	rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum);
+	if (linux_busnum == NULL) {
+		panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS);
+		return(0);
+	}
+
+	pci_bus_cvlink_init();
+
+	/*
+	 * Initialize the ifconfgi_net driver that does network devices 
+	 * Persistent Naming.
+	 */
+	init_ifconfig_net();
+	init_ioconfig_bus();
+
+	return(0);
+
+}
+
+
+/*
+ * hcl_setup() - Process boot time parameters if given.
+ *	"hcl="
+ *	This routine gets called only if "hcl=" is given in the 
+ *	boot line and before init_hcl().
+ *
+ *	We currently do not have any boot options .. when we do, 
+ *	functionalities can be added here.
+ *
+ */
+static int __init hcl_setup(char *str)
+{
+    while ( (*str != '\0') && !isspace (*str) )
+    {
+#ifdef CONFIG_HCL_DEBUG
+        if (strncmp (str, "all", 3) == 0) {
+            hcl_debug_init |= HCL_DEBUG_ALL;
+            str += 3;
+        } else 
+        	return 0;
+#endif
+        if (*str != ',') return 0;
+        ++str;
+    }
+
+    return 1;
+
+}
+
+__setup("hcl=", hcl_setup);
+
+
+/*
+ * Set device specific "fast information".
+ *
+ */
+void
+hwgraph_fastinfo_set(vertex_hdl_t de, arbitrary_info_t fastinfo)
+{
+	labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL);
+}
+
+
+/*
+ * Get device specific "fast information".
+ *
+ */
+arbitrary_info_t
+hwgraph_fastinfo_get(vertex_hdl_t de)
+{
+	arbitrary_info_t fastinfo;
+	int rv;
+
+	if (!de) {
+		printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n");
+		return(-1);
+	}
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo);
+	if (rv == 0)
+		return(fastinfo);
+
+	return(0);
+}
+
+
+/*
+ * hwgraph_connectpt_set - Sets the connect point handle in de to the 
+ *	given connect_de handle.  By default, the connect point of the 
+ *	devfs node is the parent.  This effectively changes this assumption.
+ */
+int
+hwgraph_connectpt_set(vertex_hdl_t de, vertex_hdl_t connect_de)
+{
+	int rv;
+
+	if (!de)
+		return(-1);
+
+	rv = labelcl_info_connectpt_set(de, connect_de);
+
+	return(rv);
+}
+
+
+/*
+ * hwgraph_connectpt_get: Returns the entry's connect point  in the devfs 
+ *	tree.
+ */
+vertex_hdl_t
+hwgraph_connectpt_get(vertex_hdl_t de)
+{
+	int rv;
+	arbitrary_info_t info;
+	vertex_hdl_t connect;
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
+	if (rv != 0) {
+		return(NULL);
+	}
+
+	connect = (vertex_hdl_t)info;
+	return(connect);
+
+}
+
+
+/*
+ * hwgraph_mk_dir - Creates a directory entry with devfs.
+ *	Note that a directory entry in devfs can have children 
+ *	but it cannot be a char|block special file.
+ */
+vertex_hdl_t
+hwgraph_mk_dir(vertex_hdl_t de, const char *name,
+                unsigned int namelen, void *info)
+{
+
+	int rv;
+	labelcl_info_t *labelcl_info = NULL;
+	vertex_hdl_t new_devfs_handle = NULL;
+	vertex_hdl_t parent = NULL;
+
+	/*
+	 * Create the device info structure for hwgraph compatiblity support.
+	 */
+	labelcl_info = labelcl_info_create();
+	if (!labelcl_info)
+		return(NULL);
+
+	/*
+	 * Create a devfs entry.
+	 */
+	new_devfs_handle = devfs_mk_dir(de, name, (void *)labelcl_info);
+	if (!new_devfs_handle) {
+		labelcl_info_destroy(labelcl_info);
+		return(NULL);
+	}
+
+	/*
+	 * Get the parent handle.
+	 */
+	parent = devfs_get_parent (new_devfs_handle);
+
+	/*
+	 * To provide the same semantics as the hwgraph, set the connect point.
+	 */
+	rv = hwgraph_connectpt_set(new_devfs_handle, parent);
+	if (!rv) {
+		/*
+		 * We need to clean up!
+		 */
+	}
+
+	/*
+	 * If the caller provides a private data pointer, save it in the 
+	 * labelcl info structure(fastinfo).  This can be retrieved via
+	 * hwgraph_fastinfo_get()
+	 */
+	if (info)
+		hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
+		
+	return(new_devfs_handle);
+
+}
+
+/*
+ * hwgraph_path_add - Create a directory node with the given path starting 
+ * from the given vertex_hdl_t.
+ */
+int
+hwgraph_path_add(vertex_hdl_t  fromv,
+		 char *path,
+		 vertex_hdl_t *new_de)
+{
+
+	unsigned int	namelen = strlen(path);
+	int		rv;
+
+	/*
+	 * We need to handle the case when fromv is NULL ..
+	 * in this case we need to create the path from the 
+	 * hwgraph root!
+	 */
+	if (fromv == NULL)
+		fromv = hwgraph_root;
+
+	/*
+	 * check the entry doesn't already exist, if it does
+	 * then we simply want new_de to point to it (otherwise
+	 * we'll overwrite the existing labelcl_info struct)
+	 */
+	rv = hwgraph_edge_get(fromv, path, new_de);
+	if (rv)	{	/* couldn't find entry so we create it */
+		*new_de = hwgraph_mk_dir(fromv, path, namelen, NULL);
+		if (new_de == NULL)
+			return(-1);
+		else
+			return(0);
+	}
+	else 
+ 		return(0);
+
+}
+
+/*
+ * hwgraph_register  - Creates a file entry with devfs.
+ *	Note that a file entry cannot have children .. it is like a 
+ *	char|block special vertex in hwgraph.
+ */
+vertex_hdl_t
+hwgraph_register(vertex_hdl_t de, const char *name,
+                unsigned int namelen, unsigned int flags, 
+		unsigned int major, unsigned int minor,
+                umode_t mode, uid_t uid, gid_t gid, 
+		struct file_operations *fops,
+                void *info)
+{
+
+        vertex_hdl_t new_devfs_handle = NULL;
+
+        /*
+         * Create a devfs entry.
+         */
+        new_devfs_handle = devfs_register(de, name, flags, major,
+				minor, mode, fops, info);
+        if (!new_devfs_handle) {
+                return(NULL);
+        }
+
+        return(new_devfs_handle);
+
+}
+
+
+/*
+ * hwgraph_mk_symlink - Create a symbolic link.
+ */
+int
+hwgraph_mk_symlink(vertex_hdl_t de, const char *name, unsigned int namelen,
+                unsigned int flags, const char *link, unsigned int linklen, 
+		vertex_hdl_t *handle, void *info)
+{
+
+	void *labelcl_info = NULL;
+	int status = 0;
+	vertex_hdl_t new_devfs_handle = NULL;
+
+	/*
+	 * Create the labelcl info structure for hwgraph compatiblity support.
+	 */
+	labelcl_info = labelcl_info_create();
+	if (!labelcl_info)
+		return(-1);
+
+	/*
+	 * Create a symbolic link devfs entry.
+	 */
+	status = devfs_mk_symlink(de, name, flags, link,
+				&new_devfs_handle, labelcl_info);
+	if ( (!new_devfs_handle) || (!status) ){
+		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
+		return(-1);
+	}
+
+	/*
+	 * If the caller provides a private data pointer, save it in the 
+	 * labelcl info structure(fastinfo).  This can be retrieved via
+	 * hwgraph_fastinfo_get()
+	 */
+	if (info)
+		hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
+
+	*handle = new_devfs_handle;
+	return(0);
+
+}
+
+/*
+ * hwgraph_vertex_destroy - Destroy the devfs entry
+ */
+int
+hwgraph_vertex_destroy(vertex_hdl_t de)
+{
+
+	void *labelcl_info = NULL;
+
+	labelcl_info = devfs_get_info(de);
+	devfs_unregister(de);
+
+	if (labelcl_info)
+		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
+
+	return(0);
+}
+
+/*
+ * hwgraph_edge_add - This routines has changed from the original conext.
+ * All it does now is to create a symbolic link from "from" to "to".
+ */
+/* ARGSUSED */
+int
+hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
+{
+
+	char *path;
+	char *s1;
+	char *index;
+	int name_start;
+	vertex_hdl_t handle = NULL;
+	int rv;
+	int i, count;
+
+	path = kmalloc(1024, GFP_KERNEL);
+	memset(path, 0x0, 1024);
+	name_start = devfs_generate_path (from, path, 1024);
+	s1 = &path[name_start];
+	count = 0;
+	while (1) {
+		index = strstr (s1, "/");
+		if (index) {
+			count++;
+			s1 = ++index;
+		} else {
+			count++;
+			break;
+		}
+	}
+
+	memset(path, 0x0, 1024);
+	name_start = devfs_generate_path (to, path, 1024);
+
+	for (i = 0; i < count; i++) {
+		strcat(path,"../");
+	}
+
+	strcat(path, &path[name_start]);
+
+	/*
+	 * Otherwise, just create a symlink to the vertex.
+	 * In this case the vertex was previous created with a REAL pathname.
+	 */
+	rv = devfs_mk_symlink (from, (const char *)name, 
+			       DEVFS_FL_DEFAULT, path,
+			       &handle, NULL);
+
+	name_start = devfs_generate_path (handle, path, 1024);
+	return(rv);
+
+	
+}
+/* ARGSUSED */
+int
+hwgraph_edge_get(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
+{
+
+	int namelen = 0;
+	vertex_hdl_t target_handle = NULL;
+
+	if (name == NULL)
+		return(-1);
+
+	if (toptr == NULL)
+		return(-1);
+
+	/*
+	 * If the name is "." just return the current devfs entry handle.
+	 */
+	if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) {
+		if (toptr) {
+			*toptr = from;
+		}
+	} else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) {
+		/*
+		 * Hmmm .. should we return the connect point or parent ..
+		 * see in hwgraph, the concept of parent is the connectpt!
+		 *
+		 * Maybe we should see whether the connectpt is set .. if 
+		 * not just return the parent!
+		 */
+		target_handle = hwgraph_connectpt_get(from);
+		if (target_handle) {
+			/*
+			 * Just return the connect point.
+			 */
+			*toptr = target_handle;
+			return(0);
+		}
+		target_handle = devfs_get_parent(from);
+		*toptr = target_handle;
+
+	} else {
+		/*
+		 * Call devfs to get the devfs entry.
+		 */
+		namelen = (int) strlen(name);
+		target_handle = devfs_find_handle (from, name, 0, 0,
+					0, 1); /* Yes traverse symbolic links */
+		if (target_handle == NULL)
+			return(-1);
+		else
+		*toptr = target_handle;
+	}
+
+	return(0);
+}
+
+/*
+ * hwgraph_info_add_LBL - Adds a new label for the device.  Mark the info_desc
+ *	of the label as INFO_DESC_PRIVATE and store the info in the label.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_add_LBL(	vertex_hdl_t de,
+			char *name,
+			arbitrary_info_t info)
+{
+	return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info));
+}
+
+/*
+ * hwgraph_info_remove_LBL - Remove the label entry for the device.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_remove_LBL(	vertex_hdl_t de,
+				char *name,
+				arbitrary_info_t *old_info)
+{
+	return(labelcl_info_remove_LBL(de, name, NULL, old_info));
+}
+
+/*
+ * hwgraph_info_replace_LBL - replaces an existing label with 
+ *	a new label info value.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_replace_LBL(	vertex_hdl_t de,
+				char *name,
+				arbitrary_info_t info,
+				arbitrary_info_t *old_info)
+{
+	return(labelcl_info_replace_LBL(de, name,
+			INFO_DESC_PRIVATE, info,
+			NULL, old_info));
+}
+/*
+ * hwgraph_info_get_LBL - Get and return the info value in the label of the 
+ * 	device.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_LBL(	vertex_hdl_t de,
+			char *name,
+			arbitrary_info_t *infop)
+{
+	return(labelcl_info_get_LBL(de, name, NULL, infop));
+}
+
+/*
+ * hwgraph_info_get_exported_LBL - Retrieve the info_desc and info pointer 
+ *	of the given label for the device.  The weird thing is that the label 
+ *	that matches the name is return irrespective of the info_desc value!
+ *	Do not understand why the word "exported" is used!
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_exported_LBL(	vertex_hdl_t de,
+				char *name,
+				int *export_info,
+				arbitrary_info_t *infop)
+{
+	int rc;
+	arb_info_desc_t info_desc;
+
+	rc = labelcl_info_get_LBL(de, name, &info_desc, infop);
+	if (rc == 0)
+		*export_info = (int)info_desc;
+
+	return(rc);
+}
+
+/*
+ * hwgraph_info_get_next_LBL - Returns the next label info given the 
+ *	current label entry in place.
+ *
+ *	Once again this has no locking or reference count for protection.
+ *
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_next_LBL(	vertex_hdl_t de,
+				char *buf,
+				arbitrary_info_t *infop,
+				labelcl_info_place_t *place)
+{
+	return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place));
+}
+
+/*
+ * hwgraph_info_export_LBL - Retrieve the specified label entry and modify 
+ *	the info_desc field with the given value in nbytes.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_export_LBL(vertex_hdl_t de, char *name, int nbytes)
+{
+	arbitrary_info_t info;
+	int rc;
+
+	if (nbytes == 0)
+		nbytes = INFO_DESC_EXPORT;
+
+	if (nbytes < 0)
+		return(-1);
+
+	rc = labelcl_info_get_LBL(de, name, NULL, &info);
+	if (rc != 0)
+		return(rc);
+
+	rc = labelcl_info_replace_LBL(de, name,
+				nbytes, info, NULL, NULL);
+
+	return(rc);
+}
+
+/*
+ * hwgraph_info_unexport_LBL - Retrieve the given label entry and change the 
+ * label info_descr filed to INFO_DESC_PRIVATE.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_unexport_LBL(vertex_hdl_t de, char *name)
+{
+	arbitrary_info_t info;
+	int rc;
+
+	rc = labelcl_info_get_LBL(de, name, NULL, &info);
+	if (rc != 0)
+		return(rc);
+
+	rc = labelcl_info_replace_LBL(de, name,
+				INFO_DESC_PRIVATE, info, NULL, NULL);
+
+	return(rc);
+}
+
+/*
+ * hwgraph_path_lookup - return the handle for the given path.
+ *
+ */
+int
+hwgraph_path_lookup(	vertex_hdl_t start_vertex_handle,
+			char *lookup_path,
+			vertex_hdl_t *vertex_handle_ptr,
+			char **remainder)
+{
+	*vertex_handle_ptr = devfs_find_handle(start_vertex_handle,	/* start dir */
+					lookup_path,		/* path */
+					0,			/* major */
+					0,			/* minor */
+					0,			/* char | block */
+					1);			/* traverse symlinks */
+	if (*vertex_handle_ptr == NULL)
+		return(-1);
+	else
+		return(0);
+}
+
+/*
+ * hwgraph_traverse - Find and return the devfs handle starting from de.
+ *
+ */
+graph_error_t
+hwgraph_traverse(vertex_hdl_t de, char *path, vertex_hdl_t *found)
+{
+	/* 
+	 * get the directory entry (path should end in a directory)
+	 */
+
+	*found = devfs_find_handle(de,	/* start dir */
+			    path,	/* path */
+			    0,		/* major */
+			    0,		/* minor */
+			    0,		/* char | block */
+			    1);		/* traverse symlinks */
+	if (*found == NULL)
+		return(GRAPH_NOT_FOUND);
+	else
+		return(GRAPH_SUCCESS);
+}
+
+/*
+ * hwgraph_path_to_vertex - Return the devfs entry handle for the given 
+ *	pathname .. assume traverse symlinks too!.
+ */
+vertex_hdl_t
+hwgraph_path_to_vertex(char *path)
+{
+	return(devfs_find_handle(NULL,	/* start dir */
+			path,		/* path */
+		    	0,		/* major */
+		    	0,		/* minor */
+		    	0,		/* char | block */
+		    	1));		/* traverse symlinks */
+}
+
+/*
+ * hwgraph_inventory_remove - Removes an inventory entry.
+ *
+ *	Remove an inventory item associated with a vertex.   It is the caller's
+ *	responsibility to make sure that there are no races between removing
+ *	inventory from a vertex and simultaneously removing that vertex.
+*/
+int
+hwgraph_inventory_remove(	vertex_hdl_t de,
+				int class,
+				int type,
+				major_t controller,
+				minor_t unit,
+				int state)
+{
+	return(0); /* Just a Stub for IRIX code. */
+}
+
+/*
+ * Find the canonical name for a given vertex by walking back through
+ * connectpt's until we hit the hwgraph root vertex (or until we run
+ * out of buffer space or until something goes wrong).
+ *
+ *	COMPATIBILITY FUNCTIONALITY
+ * Walks back through 'parents', not necessarily the same as connectpts.
+ *
+ * Need to resolve the fact that devfs does not return the path from 
+ * "/" but rather it just stops right before /dev ..
+ */
+int
+hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen)
+{
+	char *locbuf;
+	int   pos;
+
+	if (buflen < 1)
+		return(-1);	/* XXX should be GRAPH_BAD_PARAM ? */
+
+	locbuf = kmalloc(buflen, GFP_KERNEL);
+
+	pos = devfs_generate_path(vhdl, locbuf, buflen);
+	if (pos < 0) {
+		kfree(locbuf);
+		return pos;
+	}
+
+	strcpy(buf, &locbuf[pos]);
+	kfree(locbuf);
+	return 0;
+}
+
+/*
+** vertex_to_name converts a vertex into a canonical name by walking
+** back through connect points until we hit the hwgraph root (or until
+** we run out of buffer space).
+**
+** Usually returns a pointer to the original buffer, filled in as
+** appropriate.  If the buffer is too small to hold the entire name,
+** or if anything goes wrong while determining the name, vertex_to_name
+** returns "UnknownDevice".
+*/
+
+#define DEVNAME_UNKNOWN "UnknownDevice"
+
+char *
+vertex_to_name(vertex_hdl_t vhdl, char *buf, uint buflen)
+{
+	if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS)
+		return(buf);
+	else
+		return(DEVNAME_UNKNOWN);
+}
+
+graph_error_t
+hwgraph_edge_remove(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
+{
+	printk("WARNING: hwgraph_edge_remove NOT supported.\n");
+	return(GRAPH_ILLEGAL_REQUEST);
+}
+
+graph_error_t
+hwgraph_vertex_unref(vertex_hdl_t vhdl)
+{
+	return(GRAPH_ILLEGAL_REQUEST);
+}
+
+
+EXPORT_SYMBOL(hwgraph_mk_dir);
+EXPORT_SYMBOL(hwgraph_path_add);
+EXPORT_SYMBOL(hwgraph_register);
+EXPORT_SYMBOL(hwgraph_vertex_destroy);
+EXPORT_SYMBOL(hwgraph_fastinfo_get);
+EXPORT_SYMBOL(hwgraph_fastinfo_set);
+EXPORT_SYMBOL(hwgraph_connectpt_set);
+EXPORT_SYMBOL(hwgraph_connectpt_get);
+EXPORT_SYMBOL(hwgraph_info_add_LBL);
+EXPORT_SYMBOL(hwgraph_info_remove_LBL);
+EXPORT_SYMBOL(hwgraph_info_replace_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_exported_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_next_LBL);
+EXPORT_SYMBOL(hwgraph_info_export_LBL);
+EXPORT_SYMBOL(hwgraph_info_unexport_LBL);
+EXPORT_SYMBOL(hwgraph_path_lookup);
+EXPORT_SYMBOL(hwgraph_traverse);
+EXPORT_SYMBOL(hwgraph_vertex_name_get);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hwgdfs/hcl_util.c linux-2.4.22-pre10/arch/ia64/sn/io/hwgdfs/hcl_util.c
--- linux-2.4.21/arch/ia64/sn/io/hwgdfs/hcl_util.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hwgdfs/hcl_util.c	2003-08-01 13:33:41.000000000 +0000
@@ -0,0 +1,200 @@
+/* $Id: hcl_util.c,v 1.3 2003/04/24 13:59:39 pfg Exp $
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/devfs_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/sn/sgi.h>
+#include <asm/io.h>
+#include <asm/sn/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/nodepda.h>
+
+static vertex_hdl_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE;
+extern vertex_hdl_t hwgraph_root;
+
+
+/*
+** Return the "master" for a given vertex.  A master vertex is a
+** controller or adapter or other piece of hardware that the given
+** vertex passes through on the way to the rest of the system.
+*/
+vertex_hdl_t
+device_master_get(vertex_hdl_t vhdl)
+{
+	graph_error_t rc;
+	vertex_hdl_t master;
+
+	rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master);
+	if (rc == GRAPH_SUCCESS)
+		return(master);
+	else
+		return(GRAPH_VERTEX_NONE);
+}
+
+/*
+** Set the master for a given vertex.
+** Returns 0 on success, non-0 indicates failure
+*/
+int
+device_master_set(vertex_hdl_t vhdl, vertex_hdl_t master)
+{
+	graph_error_t rc;
+
+	rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER);
+	return(rc != GRAPH_SUCCESS);
+}
+
+
+/*
+** Return the compact node id of the node that ultimately "owns" the specified
+** vertex.  In order to do this, we walk back through masters and connect points
+** until we reach a vertex that represents a node.
+*/
+cnodeid_t
+master_node_get(vertex_hdl_t vhdl)
+{
+	cnodeid_t cnodeid;
+	vertex_hdl_t master;
+
+	for (;;) {
+		cnodeid = nodevertex_to_cnodeid(vhdl);
+		if (cnodeid != CNODEID_NONE)
+			return(cnodeid);
+
+		master = device_master_get(vhdl);
+
+		/* Check for exceptional cases */
+		if (master == vhdl) {
+			/* Since we got a reference to the "master" thru
+			 * device_master_get() we should decrement
+			 * its reference count by 1
+			 */
+			return(CNODEID_NONE);
+		}
+
+		if (master == GRAPH_VERTEX_NONE) {
+			master = hwgraph_connectpt_get(vhdl);
+			if ((master == GRAPH_VERTEX_NONE) ||
+			    (master == vhdl)) {
+				return(CNODEID_NONE);
+			}
+		}
+
+		vhdl = master;
+	}
+}
+
+static vertex_hdl_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE;
+extern int maxcpus;
+
+void
+mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid)
+{
+	if (cpuid == CPU_NONE)
+		return;
+
+	(void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT,
+			(arbitrary_info_t)cpuid);
+	{
+		char cpuid_buffer[10];
+
+		if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) {
+			(void)hwgraph_path_add( hwgraph_root,
+						EDGE_LBL_CPUNUM,
+						&hwgraph_all_cpuids);
+		}
+
+		sprintf(cpuid_buffer, "%ld", cpuid);
+		(void)hwgraph_edge_add( hwgraph_all_cpuids,
+							vhdl,
+							cpuid_buffer);
+	}
+}
+
+/*
+** If the specified device represents a node, return its
+** compact node ID; otherwise, return CNODEID_NONE.
+*/
+cnodeid_t
+nodevertex_to_cnodeid(vertex_hdl_t vhdl)
+{
+	int rv = 0;
+	arbitrary_info_t cnodeid = CNODEID_NONE;
+
+	rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid);
+
+	return((cnodeid_t)cnodeid);
+}
+
+void
+mark_nodevertex_as_node(vertex_hdl_t vhdl, cnodeid_t cnodeid)
+{
+	if (cnodeid == CNODEID_NONE)
+		return;
+
+	cnodeid_to_vertex(cnodeid) = vhdl;
+	labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, 
+		(arbitrary_info_t)cnodeid);
+
+	{
+		char cnodeid_buffer[10];
+
+		if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) {
+			(void)hwgraph_path_add( hwgraph_root,
+						EDGE_LBL_NODENUM,
+						&hwgraph_all_cnodes);
+		}
+
+		sprintf(cnodeid_buffer, "%d", cnodeid);
+		(void)hwgraph_edge_add( hwgraph_all_cnodes,
+					vhdl,
+					cnodeid_buffer);
+	}
+}
+
+/*
+** If the specified device represents a CPU, return its cpuid;
+** otherwise, return CPU_NONE.
+*/
+cpuid_t
+cpuvertex_to_cpuid(vertex_hdl_t vhdl)
+{
+	arbitrary_info_t cpuid = CPU_NONE;
+
+	(void)labelcl_info_get_LBL(vhdl, INFO_LBL_CPUID, NULL, &cpuid);
+
+	return((cpuid_t)cpuid);
+}
+
+
+/*
+** dev_to_name converts a vertex_hdl_t into a canonical name.  If the vertex_hdl_t
+** represents a vertex in the hardware graph, it is converted in the
+** normal way for vertices.  If the vertex_hdl_t is an old vertex_hdl_t (one which
+** does not represent a hwgraph vertex), we synthesize a name based
+** on major/minor number.
+**
+** Usually returns a pointer to the original buffer, filled in as
+** appropriate.  If the buffer is too small to hold the entire name,
+** or if anything goes wrong while determining the name, dev_to_name
+** returns "UnknownDevice".
+*/
+char *
+dev_to_name(vertex_hdl_t dev, char *buf, uint buflen)
+{
+        return(vertex_to_name(dev, buf, buflen));
+}
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hwgdfs/invent_stub.c linux-2.4.22-pre10/arch/ia64/sn/io/hwgdfs/invent_stub.c
--- linux-2.4.21/arch/ia64/sn/io/hwgdfs/invent_stub.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hwgdfs/invent_stub.c	2003-08-01 13:30:44.000000000 +0000
@@ -0,0 +1,146 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+/*
+ * Hardware Inventory
+ *
+ * See sys/sn/invent.h for an explanation of the hardware inventory contents.
+ *
+ */
+#include <linux/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+
+void
+inventinit(void)
+{
+}
+
+/*
+ * For initializing/updating an inventory entry.
+ */
+void
+replace_in_inventory(
+	inventory_t *pinv, int class, int type,
+	int controller, int unit, int state)
+{
+}
+
+/*
+ * Inventory addition 
+ *
+ * XXX NOTE: Currently must be called after dynamic memory allocator is
+ * initialized.
+ *
+ */
+void
+add_to_inventory(int class, int type, int controller, int unit, int state)
+{
+}
+
+
+/*
+ * Inventory retrieval 
+ *
+ * These two routines are intended to prevent the caller from having to know
+ * the internal structure of the inventory table.
+ *
+ * The caller of get_next_inventory is supposed to call start_scan_invent
+ * before the irst call to get_next_inventory, and the caller is required
+ * to call end_scan_invent after the last call to get_next_inventory.
+ */
+inventory_t *
+get_next_inventory(invplace_t *place)
+{
+	return((inventory_t *) NULL);
+}
+
+/* ARGSUSED */
+int
+get_sizeof_inventory(int abi)
+{
+	return sizeof(inventory_t);
+}
+
+/* Must be called prior to first call to get_next_inventory */
+void
+start_scan_inventory(invplace_t *iplace)
+{
+}
+
+/* Must be called after last call to get_next_inventory */
+void
+end_scan_inventory(invplace_t *iplace)
+{
+}
+
+/*
+ * Hardware inventory scanner.
+ *
+ * Calls fun() for every entry in inventory list unless fun() returns something
+ * other than 0.
+ */
+int
+scaninvent(int (*fun)(inventory_t *, void *), void *arg)
+{
+	return 0;
+}
+
+/*
+ * Find a particular inventory object
+ *
+ * pinv can be a pointer to an inventory entry and the search will begin from
+ * there, or it can be 0 in which case the search starts at the beginning.
+ * A -1 for any of the other arguments is a wildcard (i.e. it always matches).
+ */
+inventory_t *
+find_inventory(inventory_t *pinv, int class, int type, int controller,
+	       int unit, int state)
+{
+	return((inventory_t *) NULL);
+}
+
+
+/*
+** Retrieve inventory data associated with a device.
+*/
+inventory_t *
+device_inventory_get_next(	vertex_hdl_t device,
+				invplace_t *invplace)
+{
+		return((inventory_t *) NULL);
+}
+
+
+/*
+** Associate canonical inventory information with a device (and
+** add it to the general inventory).
+*/
+void
+device_inventory_add(	vertex_hdl_t device,
+			int class, 
+			int type, 
+			major_t controller, 
+			minor_t unit, 
+			int state)
+{
+}
+
+int
+device_controller_num_get(vertex_hdl_t device)
+{
+	return (0);
+}
+
+void
+device_controller_num_set(vertex_hdl_t device, int contr_num)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hwgdfs/labelcl.c linux-2.4.22-pre10/arch/ia64/sn/io/hwgdfs/labelcl.c
--- linux-2.4.21/arch/ia64/sn/io/hwgdfs/labelcl.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hwgdfs/labelcl.c	2003-08-01 13:32:47.000000000 +0000
@@ -0,0 +1,653 @@
+/*  labelcl - SGI's Hwgraph Compatibility Layer.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
+*/
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/sn/sgi.h>
+#include <linux/devfs_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+
+/*
+** Very simple and dumb string table that supports only find/insert.
+** In practice, if this table gets too large, we may need a more
+** efficient data structure.   Also note that currently there is no 
+** way to delete an item once it's added.  Therefore, name collision 
+** will return an error.
+*/
+
+struct string_table label_string_table;
+
+
+
+/*
+ * string_table_init - Initialize the given string table.
+ */
+void
+string_table_init(struct string_table *string_table)
+{
+	string_table->string_table_head = NULL;
+	string_table->string_table_generation = 0;
+
+	/*
+	 * We nedd to initialize locks here!
+	 */
+
+	return;
+}
+
+
+/*
+ * string_table_destroy - Destroy the given string table.
+ */
+void
+string_table_destroy(struct string_table *string_table)
+{
+	struct string_table_item *item, *next_item;
+
+	item = string_table->string_table_head;
+	while (item) {
+		next_item = item->next;
+
+		STRTBL_FREE(item);
+		item = next_item;
+	}
+
+	/*
+	 * We need to destroy whatever lock we have here
+	 */
+
+	return;
+}
+
+
+
+/*
+ * string_table_insert - Insert an entry in the string table .. duplicate 
+ *	names are not allowed.
+ */
+char *
+string_table_insert(struct string_table *string_table, char *name)
+{
+	struct string_table_item *item, *new_item = NULL, *last_item = NULL;
+
+again:
+	/*
+	 * Need to lock the table ..
+	 */
+	item = string_table->string_table_head;
+	last_item = NULL;
+
+	while (item) {
+		if (!strcmp(item->string, name)) {
+			/*
+			 * If we allocated space for the string and the found that
+			 * someone else already entered it into the string table,
+			 * free the space we just allocated.
+			 */
+			if (new_item)
+				STRTBL_FREE(new_item);
+
+
+			/*
+			 * Search optimization: move the found item to the head
+			 * of the list.
+			 */
+			if (last_item != NULL) {
+				last_item->next = item->next;
+				item->next = string_table->string_table_head;
+				string_table->string_table_head = item;
+			}
+			goto out;
+		}
+		last_item = item;
+		item=item->next;
+	}
+
+	/*
+	 * name was not found, so add it to the string table.
+	 */
+	if (new_item == NULL) {
+		long old_generation = string_table->string_table_generation;
+
+		new_item = STRTBL_ALLOC(strlen(name));
+
+		strcpy(new_item->string, name);
+
+		/*
+		 * While we allocated memory for the new string, someone else 
+		 * changed the string table.
+		 */
+		if (old_generation != string_table->string_table_generation) {
+			goto again;
+		}
+	} else {
+		/* At this we only have the string table lock in access mode.
+		 * Promote the access lock to an update lock for the string
+		 * table insertion below.
+		 */
+			long old_generation = 
+				string_table->string_table_generation;
+
+			/*
+			 * After we did the unlock and wer waiting for update
+			 * lock someone could have potentially updated
+			 * the string table. Check the generation number
+			 * for this case. If it is the case we have to
+			 * try all over again.
+			 */
+			if (old_generation != 
+			    string_table->string_table_generation) {
+				goto again;
+			}
+		}
+
+	/*
+	 * At this point, we're committed to adding new_item to the string table.
+	 */
+	new_item->next = string_table->string_table_head;
+	item = string_table->string_table_head = new_item;
+	string_table->string_table_generation++;
+
+out:
+	/*
+	 * Need to unlock here.
+	 */
+	return(item->string);
+}
+
+/*
+ * labelcl_info_create - Creates the data structure that will hold the
+ *	device private information asscoiated with a devfs entry.
+ *	The pointer to this structure is what gets stored in the devfs 
+ *	(void * info).
+ */
+labelcl_info_t *
+labelcl_info_create()
+{
+
+	labelcl_info_t *new = NULL;
+
+	/* Initial allocation does not include any area for labels */
+	if ( ( new = (labelcl_info_t *)kmalloc (sizeof(labelcl_info_t), GFP_KERNEL) ) == NULL )
+		return NULL;
+
+	memset (new, 0, sizeof(labelcl_info_t));
+	new->hwcl_magic = LABELCL_MAGIC;
+	return( new);
+
+}
+
+/*
+ * labelcl_info_destroy - Frees the data structure that holds the
+ *      device private information asscoiated with a devfs entry.  This 
+ *	data structure was created by device_info_create().
+ *
+ *	The caller is responsible for nulling the (void *info) in the 
+ *	corresponding devfs entry.
+ */
+int
+labelcl_info_destroy(labelcl_info_t *labelcl_info)
+{
+
+	if (labelcl_info == NULL)
+		return(0);
+
+	/* Free the label list */
+	if (labelcl_info->label_list)
+		kfree(labelcl_info->label_list);
+
+	/* Now free the label info area */
+	labelcl_info->hwcl_magic = 0;
+	kfree(labelcl_info);
+
+	return(0);
+}
+
+/*
+ * labelcl_info_add_LBL - Adds a new label entry in the labelcl info 
+ *	structure.
+ *
+ *	Error is returned if we find another label with the same name.
+ */
+int
+labelcl_info_add_LBL(vertex_hdl_t de,
+			char *info_name,
+			arb_info_desc_t info_desc,
+			arbitrary_info_t info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	int new_label_list_size;
+	label_info_t *old_label_list, *new_label_list = NULL;
+	char *name;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+        labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if (info_name == NULL)
+		return(-1);
+
+	if (strlen(info_name) >= LABEL_LENGTH_MAX)
+		return(-1);
+
+	name = string_table_insert(&label_string_table, info_name);
+
+	num_labels = labelcl_info->num_labels;
+	new_label_list_size = sizeof(label_info_t) * (num_labels+1);
+
+	/*
+	 * Create a new label info area.
+	 */
+	if (new_label_list_size != 0) {
+		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
+
+		if (new_label_list == NULL)
+			return(-1);
+	}
+
+	/*
+	 * At this point, we are committed to adding the labelled info, 
+	 * if there isn't already information there with the same name.
+	 */
+	old_label_list = labelcl_info->label_list;
+
+	/* 
+	 * Look for matching info name.
+	 */
+	for (i=0; i<num_labels; i++) {
+		if (!strcmp(info_name, old_label_list[i].name)) {
+			/* Not allowed to add duplicate labelled info names. */
+			kfree(new_label_list);
+			return(-1);
+		}
+		new_label_list[i] = old_label_list[i]; /* structure copy */
+	}
+
+	new_label_list[num_labels].name = name;
+	new_label_list[num_labels].desc = info_desc;
+	new_label_list[num_labels].info = info;
+
+	labelcl_info->num_labels = num_labels+1;
+	labelcl_info->label_list = new_label_list;
+
+	if (old_label_list != NULL)
+		kfree(old_label_list);
+
+	return(0);
+}
+
+/*
+ * labelcl_info_remove_LBL - Remove a label entry.
+ */
+int
+labelcl_info_remove_LBL(vertex_hdl_t de,
+			 char *info_name,
+			 arb_info_desc_t *info_desc,
+			 arbitrary_info_t *info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	int new_label_list_size;
+	label_info_t *old_label_list, *new_label_list = NULL;
+	arb_info_desc_t label_desc_found;
+	arbitrary_info_t label_info_found;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	/*
+	 * Create a new info area.
+	 */
+	new_label_list_size = sizeof(label_info_t) * (num_labels-1);
+	if (new_label_list_size) {
+		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
+		if (new_label_list == NULL)
+			return(-1);
+	}
+
+	/*
+	 * At this point, we are committed to removing the labelled info, 
+	 * if it still exists.
+	 */
+	old_label_list = labelcl_info->label_list;
+
+	/* 
+	 * Find matching info name.
+	 */
+	for (i=0; i<num_labels; i++) {
+		if (!strcmp(info_name, old_label_list[i].name)) {
+			label_desc_found = old_label_list[i].desc;
+			label_info_found = old_label_list[i].info;
+			goto found;
+		}
+		if (i < num_labels-1) /* avoid walking off the end of the new vertex */
+			new_label_list[i] = old_label_list[i]; /* structure copy */
+	}
+
+	/* The named info doesn't exist. */
+	if (new_label_list)
+		kfree(new_label_list);
+
+	return(-1);
+
+found:
+	/* Finish up rest of labelled info */
+	for (i=i+1; i<num_labels; i++)
+		new_label_list[i-1] = old_label_list[i]; /* structure copy */
+
+	labelcl_info->num_labels = num_labels+1;
+	labelcl_info->label_list = new_label_list;
+
+	kfree(old_label_list);
+
+	if (info != NULL)
+		*info = label_info_found;
+
+	if (info_desc != NULL)
+		*info_desc = label_desc_found;
+
+	return(0);
+}
+
+
+/*
+ * labelcl_info_replace_LBL - Replace an existing label entry with the 
+ *	given new information.
+ *
+ *	Label entry must exist.
+ */
+int
+labelcl_info_replace_LBL(vertex_hdl_t de,
+			char *info_name,
+			arb_info_desc_t info_desc,
+			arbitrary_info_t info,
+			arb_info_desc_t *old_info_desc,
+			arbitrary_info_t *old_info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	label_info_t *label_list;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	if (info_name == NULL)
+		return(-1);
+
+	label_list = labelcl_info->label_list;
+
+	/* 
+	 * Verify that information under info_name already exists.
+	 */
+	for (i=0; i<num_labels; i++)
+		if (!strcmp(info_name, label_list[i].name)) {
+			if (old_info != NULL)
+				*old_info = label_list[i].info;
+
+			if (old_info_desc != NULL)
+				*old_info_desc = label_list[i].desc;
+
+			label_list[i].info = info;
+			label_list[i].desc = info_desc;
+
+			return(0);
+		}
+
+
+	return(-1);
+}
+
+/*
+ * labelcl_info_get_LBL - Retrieve and return the information for the 
+ *	given label entry.
+ */
+int
+labelcl_info_get_LBL(vertex_hdl_t de,
+		      char *info_name,
+		      arb_info_desc_t *info_desc,
+		      arbitrary_info_t *info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	label_info_t *label_list;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	label_list = labelcl_info->label_list;
+
+	/* 
+	 * Find information under info_name.
+	 */
+	for (i=0; i<num_labels; i++)
+		if (!strcmp(info_name, label_list[i].name)) {
+			if (info != NULL)
+				*info = label_list[i].info;
+			if (info_desc != NULL)
+				*info_desc = label_list[i].desc;
+
+			return(0);
+		}
+
+	return(-1);
+}
+
+/*
+ * labelcl_info_get_next_LBL - returns the next label entry on the list.
+ */
+int
+labelcl_info_get_next_LBL(vertex_hdl_t de,
+			   char *buffer,
+			   arb_info_desc_t *info_descp,
+			   arbitrary_info_t *infop,
+			   labelcl_info_place_t *placeptr)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	uint which_info;
+	label_info_t *label_list;
+
+	if ((buffer == NULL) && (infop == NULL))
+		return(-1);
+
+	if (placeptr == NULL)
+		return(-1);
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	which_info = *placeptr;
+
+	if (which_info >= labelcl_info->num_labels) {
+		return(-1);
+	}
+
+	label_list = (label_info_t *) labelcl_info->label_list;
+
+	if (buffer != NULL)
+		strcpy(buffer, label_list[which_info].name);
+
+	if (infop)
+		*infop = label_list[which_info].info;
+
+	if (info_descp)
+		*info_descp = label_list[which_info].desc;
+
+	*placeptr = which_info + 1;
+
+	return(0);
+}
+
+
+int
+labelcl_info_replace_IDX(vertex_hdl_t de,
+			int index,
+			arbitrary_info_t info,
+			arbitrary_info_t *old_info)
+{
+	arbitrary_info_t *info_list_IDX;
+	labelcl_info_t	*labelcl_info = NULL;
+
+	if (de == NULL) {
+		printk(KERN_ALERT "labelcl: NULL devfs handle given.\n");
+		return(-1);
+	}
+
+	labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL) {
+		printk(KERN_ALERT "labelcl: Entry does not have info pointer.\n");
+		return(-1);
+	}
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
+		return(-1);
+
+	/*
+	 * Replace information at the appropriate index in this vertex with 
+	 * the new info.
+	 */
+	info_list_IDX = labelcl_info->IDX_list;
+	if (old_info != NULL)
+		*old_info = info_list_IDX[index];
+	info_list_IDX[index] = info;
+
+	return(0);
+
+}
+
+/*
+ * labelcl_info_connectpt_set - Sets the connectpt.
+ */
+int
+labelcl_info_connectpt_set(struct devfs_entry *de,
+			  struct devfs_entry *connect_de)
+{
+	arbitrary_info_t old_info;
+	int	rv;
+
+	rv = labelcl_info_replace_IDX(de, HWGRAPH_CONNECTPT, 
+		(arbitrary_info_t) connect_de, &old_info);
+
+	if (rv) {
+		return(rv);
+	}
+
+	return(0);
+}
+
+
+/*
+ * labelcl_info_get_IDX - Returns the information pointed at by index.
+ *
+ */
+int
+labelcl_info_get_IDX(vertex_hdl_t de,
+			int index,
+			arbitrary_info_t *info)
+{
+	arbitrary_info_t *info_list_IDX;
+	labelcl_info_t	*labelcl_info = NULL;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = devfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
+		return(-1);
+
+	/*
+	 * Return information at the appropriate index in this vertex.
+	 */
+	info_list_IDX = labelcl_info->IDX_list;
+	if (info != NULL)
+		*info = info_list_IDX[index];
+
+	return(0);
+}
+
+/*
+ * labelcl_info_connectpt_get - Retrieve the connect point for a device entry.
+ */
+struct devfs_entry *
+labelcl_info_connectpt_get(struct devfs_entry *de)
+{
+	int rv;
+	arbitrary_info_t info;
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
+	if (rv)
+		return(NULL);
+
+	return((struct devfs_entry *)info);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hwgfs/Makefile linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/Makefile
--- linux-2.4.21/arch/ia64/sn/io/hwgfs/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/Makefile	2003-08-01 13:32:39.000000000 +0000
@@ -0,0 +1,19 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+O_TARGET := snio.o
+
+export-objs := hcl.o ramfs.o interface.o
+
+obj-y				+= hcl.o labelcl.o hcl_util.o invent_stub.o \
+				   ramfs.o interface.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hwgfs/hcl.c linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/hcl.c
--- linux-2.4.21/arch/ia64/sn/io/hwgfs/hcl.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/hcl.c	2003-08-01 13:34:25.000000000 +0000
@@ -0,0 +1,938 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ *  hcl - SGI's Hardware Graph compatibility layer.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/sched.h>                /* needed for smp_lock.h :( */
+#include <linux/smp_lock.h>
+#include <asm/sn/sgi.h>
+#include <asm/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/hwgfs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/simulator.h>
+
+#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER"
+#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE"
+#define HCL_TEMP_NAME_LEN 44 
+#define HCL_VERSION "1.0"
+
+#define vertex_hdl_t hwgfs_handle_t
+vertex_hdl_t hwgraph_root;
+vertex_hdl_t linux_busnum;
+
+extern void pci_bus_cvlink_init(void);
+
+/*
+ * Debug flag definition.
+ */
+#define OPTION_NONE             0x00
+#define HCL_DEBUG_NONE 0x00000
+#define HCL_DEBUG_ALL  0x0ffff
+#if defined(CONFIG_HCL_DEBUG)
+static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE;
+#endif
+static unsigned int hcl_debug = HCL_DEBUG_NONE;
+#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
+static unsigned int boot_options = OPTION_NONE;
+#endif
+
+/*
+ * Some Global definitions.
+ */
+vertex_hdl_t hcl_handle;
+
+invplace_t invplace_none = {
+	GRAPH_VERTEX_NONE,
+	GRAPH_VERTEX_PLACE_NONE,
+	NULL
+};
+
+/*
+ * HCL device driver.
+ * The purpose of this device driver is to provide a facility 
+ * for User Level Apps e.g. hinv, ioconfig etc. an ioctl path 
+ * to manipulate label entries without having to implement
+ * system call interfaces.  This methodology will enable us to 
+ * make this feature module loadable.
+ */
+static int hcl_open(struct inode * inode, struct file * filp)
+{
+	if (hcl_debug) {
+        	printk("HCL: hcl_open called.\n");
+	}
+
+        return(0);
+
+}
+
+static int hcl_close(struct inode * inode, struct file * filp)
+{
+
+	if (hcl_debug) {
+        	printk("HCL: hcl_close called.\n");
+	}
+
+        return(0);
+
+}
+
+static int hcl_ioctl(struct inode * inode, struct file * file,
+        unsigned int cmd, unsigned long arg)
+{
+
+	if (hcl_debug) {
+		printk("HCL: hcl_ioctl called.\n");
+	}
+
+	switch (cmd) {
+		default:
+			if (hcl_debug) {
+				printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd);
+			}
+	}
+
+	return(0);
+
+}
+
+struct file_operations hcl_fops = {
+	(struct module *)0,
+	NULL,		/* lseek - default */
+	NULL,		/* read - general block-dev read */
+	NULL,		/* write - general block-dev write */
+	NULL,		/* readdir - bad */
+	NULL,		/* poll */
+	hcl_ioctl,      /* ioctl */
+	NULL,		/* mmap */
+	hcl_open,	/* open */
+	NULL,		/* flush */
+	hcl_close,	/* release */
+	NULL,		/* fsync */
+	NULL,		/* fasync */
+	NULL,		/* lock */
+	NULL,		/* readv */
+	NULL,		/* writev */
+};
+
+
+/*
+ * init_hcl() - Boot time initialization.
+ *
+ */
+int __init init_hcl(void)
+{
+	extern void string_table_init(struct string_table *);
+	extern struct string_table label_string_table;
+	extern int init_ifconfig_net(void);
+	extern int init_ioconfig_bus(void);
+	extern int init_hwgfs_fs(void);
+	int rv = 0;
+
+	if (IS_RUNNING_ON_SIMULATOR()) {
+		extern u64 klgraph_addr[];
+		klgraph_addr[0] = 0xe000003000030000;
+	}
+
+	init_hwgfs_fs();
+
+	/*
+	 * Create the hwgraph_root.
+	 */
+	rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
+	if (rv)
+		printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
+
+	/*
+	 * Create the hcl driver to support inventory entry manipulations.
+	 *
+	 */
+	hcl_handle = hwgraph_register(hwgraph_root, ".hcl",
+			0, DEVFS_FL_AUTO_DEVNUM,
+			0, 0,
+			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+			&hcl_fops, NULL);
+
+	if (hcl_handle == NULL) {
+		panic("HCL: Unable to create HCL Driver in init_hcl().\n");
+		return(0);
+	}
+
+	/*
+	 * Initialize the HCL string table.
+	 */
+
+	string_table_init(&label_string_table);
+
+	/*
+	 * Create the directory that links Linux bus numbers to our Xwidget.
+	 */
+	rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum);
+	if (linux_busnum == NULL) {
+		panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS);
+		return(0);
+	}
+
+	pci_bus_cvlink_init();
+
+	/*
+	 * Initialize the ifconfgi_net driver that does network devices 
+	 * Persistent Naming.
+	 */
+	init_ifconfig_net();
+	init_ioconfig_bus();
+
+	return(0);
+
+}
+
+
+/*
+ * hcl_setup() - Process boot time parameters if given.
+ *	"hcl="
+ *	This routine gets called only if "hcl=" is given in the 
+ *	boot line and before init_hcl().
+ *
+ *	We currently do not have any boot options .. when we do, 
+ *	functionalities can be added here.
+ *
+ */
+static int __init hcl_setup(char *str)
+{
+    while ( (*str != '\0') && !isspace (*str) )
+    {
+#ifdef CONFIG_HCL_DEBUG
+        if (strncmp (str, "all", 3) == 0) {
+            hcl_debug_init |= HCL_DEBUG_ALL;
+            str += 3;
+        } else 
+        	return 0;
+#endif
+        if (*str != ',') return 0;
+        ++str;
+    }
+
+    return 1;
+
+}
+
+__setup("hcl=", hcl_setup);
+
+
+/*
+ * Set device specific "fast information".
+ *
+ */
+void
+hwgraph_fastinfo_set(vertex_hdl_t de, arbitrary_info_t fastinfo)
+{
+	labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL);
+}
+
+
+/*
+ * Get device specific "fast information".
+ *
+ */
+arbitrary_info_t
+hwgraph_fastinfo_get(vertex_hdl_t de)
+{
+	arbitrary_info_t fastinfo;
+	int rv;
+
+	if (!de) {
+		printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n");
+		return(-1);
+	}
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo);
+	if (rv == 0)
+		return(fastinfo);
+
+	return(0);
+}
+
+
+/*
+ * hwgraph_connectpt_set - Sets the connect point handle in de to the 
+ *	given connect_de handle.  By default, the connect point of the 
+ *	node is the parent.  This effectively changes this assumption.
+ */
+int
+hwgraph_connectpt_set(vertex_hdl_t de, vertex_hdl_t connect_de)
+{
+	int rv;
+
+	if (!de)
+		return(-1);
+
+	rv = labelcl_info_connectpt_set(de, connect_de);
+
+	return(rv);
+}
+
+
+/*
+ * hwgraph_connectpt_get: Returns the entry's connect point.
+ *
+ */
+vertex_hdl_t
+hwgraph_connectpt_get(vertex_hdl_t de)
+{
+	int rv;
+	arbitrary_info_t info;
+	vertex_hdl_t connect;
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
+	if (rv != 0) {
+		return(NULL);
+	}
+
+	connect = (vertex_hdl_t)info;
+	return(connect);
+
+}
+
+
+/*
+ * hwgraph_mk_dir - Creates a directory entry.
+ */
+vertex_hdl_t
+hwgraph_mk_dir(vertex_hdl_t de, const char *name,
+                unsigned int namelen, void *info)
+{
+
+	int rv;
+	labelcl_info_t *labelcl_info = NULL;
+	vertex_hdl_t new_handle = NULL;
+	vertex_hdl_t parent = NULL;
+
+	/*
+	 * Create the device info structure for hwgraph compatiblity support.
+	 */
+	labelcl_info = labelcl_info_create();
+	if (!labelcl_info)
+		return(NULL);
+
+	/*
+	 * Create an entry.
+	 */
+	new_handle = hwgfs_mk_dir(de, name, (void *)labelcl_info);
+	if (!new_handle) {
+		labelcl_info_destroy(labelcl_info);
+		return(NULL);
+	}
+
+	/*
+	 * Get the parent handle.
+	 */
+	parent = hwgfs_get_parent (new_handle);
+
+	/*
+	 * To provide the same semantics as the hwgraph, set the connect point.
+	 */
+	rv = hwgraph_connectpt_set(new_handle, parent);
+	if (!rv) {
+		/*
+		 * We need to clean up!
+		 */
+	}
+
+	/*
+	 * If the caller provides a private data pointer, save it in the 
+	 * labelcl info structure(fastinfo).  This can be retrieved via
+	 * hwgraph_fastinfo_get()
+	 */
+	if (info)
+		hwgraph_fastinfo_set(new_handle, (arbitrary_info_t)info);
+		
+	return(new_handle);
+
+}
+
+/*
+ * hwgraph_path_add - Create a directory node with the given path starting 
+ * from the given fromv.
+ */
+int
+hwgraph_path_add(vertex_hdl_t  fromv,
+		 char *path,
+		 vertex_hdl_t *new_de)
+{
+
+	unsigned int	namelen = strlen(path);
+	int		rv;
+
+	/*
+	 * We need to handle the case when fromv is NULL ..
+	 * in this case we need to create the path from the 
+	 * hwgraph root!
+	 */
+	if (fromv == NULL)
+		fromv = hwgraph_root;
+
+	/*
+	 * check the entry doesn't already exist, if it does
+	 * then we simply want new_de to point to it (otherwise
+	 * we'll overwrite the existing labelcl_info struct)
+	 */
+	rv = hwgraph_edge_get(fromv, path, new_de);
+	if (rv)	{	/* couldn't find entry so we create it */
+		*new_de = hwgraph_mk_dir(fromv, path, namelen, NULL);
+		if (new_de == NULL)
+			return(-1);
+		else
+			return(0);
+	}
+	else 
+ 		return(0);
+
+}
+
+/*
+ * hwgraph_register  - Creates a special device file.
+ *
+ */
+vertex_hdl_t
+hwgraph_register(vertex_hdl_t de, const char *name,
+                unsigned int namelen, unsigned int flags, 
+		unsigned int major, unsigned int minor,
+                umode_t mode, uid_t uid, gid_t gid, 
+		struct file_operations *fops,
+                void *info)
+{
+
+        vertex_hdl_t new_handle = NULL;
+
+        /*
+         * Create an entry.
+         */
+        new_handle = hwgfs_register(de, name, flags, major,
+				minor, mode, fops, info);
+
+        return(new_handle);
+
+}
+
+
+/*
+ * hwgraph_mk_symlink - Create a symbolic link.
+ */
+int
+hwgraph_mk_symlink(vertex_hdl_t de, const char *name, unsigned int namelen,
+                unsigned int flags, const char *link, unsigned int linklen, 
+		vertex_hdl_t *handle, void *info)
+{
+
+	void *labelcl_info = NULL;
+	int status = 0;
+	vertex_hdl_t new_handle = NULL;
+
+	/*
+	 * Create the labelcl info structure for hwgraph compatiblity support.
+	 */
+	labelcl_info = labelcl_info_create();
+	if (!labelcl_info)
+		return(-1);
+
+	/*
+	 * Create a symbolic link.
+	 */
+	status = hwgfs_mk_symlink(de, name, flags, link,
+				&new_handle, labelcl_info);
+	if ( (!new_handle) || (!status) ){
+		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
+		return(-1);
+	}
+
+	/*
+	 * If the caller provides a private data pointer, save it in the 
+	 * labelcl info structure(fastinfo).  This can be retrieved via
+	 * hwgraph_fastinfo_get()
+	 */
+	if (info)
+		hwgraph_fastinfo_set(new_handle, (arbitrary_info_t)info);
+
+	*handle = new_handle;
+	return(0);
+
+}
+
+/*
+ * hwgraph_vertex_destroy - Destroy the entry
+ */
+int
+hwgraph_vertex_destroy(vertex_hdl_t de)
+{
+
+	void *labelcl_info = NULL;
+
+	labelcl_info = hwgfs_get_info(de);
+	hwgfs_unregister(de);
+
+	if (labelcl_info)
+		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
+
+	return(0);
+}
+
+#if 0
+/*
+ * hwgraph_edge_add - This routines has changed from the original conext.
+ * All it does now is to create a symbolic link from "from" to "to".
+ */
+/* ARGSUSED */
+int
+hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
+{
+
+	char *path, *link;
+	vertex_hdl_t handle = NULL;
+	int rv, i;
+
+	handle = hwgfs_find_handle(from, name, 0, 0, 0, 1);
+	if (handle) {
+		return(0);
+	}
+
+	path = kmalloc(1024, GFP_KERNEL);
+	memset(path, 0x0, 1024);
+	link = kmalloc(1024, GFP_KERNEL);
+	memset(path, 0x0, 1024);
+	i = hwgfs_generate_path (to, link, 1024);
+	rv = hwgfs_mk_symlink (from, (const char *)name, 
+			       DEVFS_FL_DEFAULT, link,
+			       &handle, NULL);
+	return(0);
+
+
+}
+#endif
+
+int
+hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
+{
+
+	char *path, *link;
+	char *s1;
+	char *index;
+	vertex_hdl_t handle = NULL;
+	int rv;
+	int i, count;
+
+	path = kmalloc(1024, GFP_KERNEL);
+	memset((char *)path, 0x0, 1024);
+	link = kmalloc(1024, GFP_KERNEL);
+	memset((char *)link, 0x0, 1024);
+
+	i = hwgfs_generate_path (from, path, 1024);
+	s1 = (char *)path;
+	count = 0;
+	while (1) {
+		index = strstr (s1, "/");
+		if (index) {
+			count++;
+			s1 = ++index;
+		} else {
+			count++;
+			break;
+		}
+	}
+
+	for (i = 0; i < count; i++) {
+		strcat((char *)link,"../");
+	}
+
+	memset(path, 0x0, 1024);
+	i = hwgfs_generate_path (to, path, 1024);
+	strcat((char *)link, (char *)path);
+
+	/*
+	 * Otherwise, just create a symlink to the vertex.
+	 * In this case the vertex was previous created with a REAL pathname.
+	 */
+	rv = hwgfs_mk_symlink (from, (const char *)name,
+			       DEVFS_FL_DEFAULT, link,
+			       &handle, NULL);
+	kfree(path);
+	kfree(link);
+
+	return(rv);
+
+
+}
+
+/* ARGSUSED */
+int
+hwgraph_edge_get(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
+{
+
+	vertex_hdl_t target_handle = NULL;
+
+	if (name == NULL)
+		return(-1);
+
+	if (toptr == NULL)
+		return(-1);
+
+	/*
+	 * If the name is "." just return the current entry handle.
+	 */
+	if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) {
+		if (toptr) {
+			*toptr = from;
+		}
+	} else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) {
+		/*
+		 * Hmmm .. should we return the connect point or parent ..
+		 * see in hwgraph, the concept of parent is the connectpt!
+		 *
+		 * Maybe we should see whether the connectpt is set .. if 
+		 * not just return the parent!
+		 */
+		target_handle = hwgraph_connectpt_get(from);
+		if (target_handle) {
+			/*
+			 * Just return the connect point.
+			 */
+			*toptr = target_handle;
+			return(0);
+		}
+		target_handle = hwgfs_get_parent(from);
+		*toptr = target_handle;
+
+	} else {
+		target_handle = hwgfs_find_handle (from, name, 0, 0,
+					0, 1); /* Yes traverse symbolic links */
+	}
+
+	if (target_handle == NULL)
+		return(-1);
+	else
+	 *toptr = target_handle;
+
+	return(0);
+}
+
+/*
+ * hwgraph_info_add_LBL - Adds a new label for the device.  Mark the info_desc
+ *	of the label as INFO_DESC_PRIVATE and store the info in the label.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_add_LBL( vertex_hdl_t de,
+			char *name,
+			arbitrary_info_t info)
+{
+	return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info));
+}
+
+/*
+ * hwgraph_info_remove_LBL - Remove the label entry for the device.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_remove_LBL( vertex_hdl_t de,
+				char *name,
+				arbitrary_info_t *old_info)
+{
+	return(labelcl_info_remove_LBL(de, name, NULL, old_info));
+}
+
+/*
+ * hwgraph_info_replace_LBL - replaces an existing label with 
+ *	a new label info value.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_replace_LBL( vertex_hdl_t de,
+				char *name,
+				arbitrary_info_t info,
+				arbitrary_info_t *old_info)
+{
+	return(labelcl_info_replace_LBL(de, name,
+			INFO_DESC_PRIVATE, info,
+			NULL, old_info));
+}
+/*
+ * hwgraph_info_get_LBL - Get and return the info value in the label of the 
+ * 	device.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_LBL(vertex_hdl_t de,
+			char *name,
+			arbitrary_info_t *infop)
+{
+	return(labelcl_info_get_LBL(de, name, NULL, infop));
+}
+
+/*
+ * hwgraph_info_get_exported_LBL - Retrieve the info_desc and info pointer 
+ *	of the given label for the device.  The weird thing is that the label 
+ *	that matches the name is return irrespective of the info_desc value!
+ *	Do not understand why the word "exported" is used!
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_exported_LBL(vertex_hdl_t de,
+				char *name,
+				int *export_info,
+				arbitrary_info_t *infop)
+{
+	int rc;
+	arb_info_desc_t info_desc;
+
+	rc = labelcl_info_get_LBL(de, name, &info_desc, infop);
+	if (rc == 0)
+		*export_info = (int)info_desc;
+
+	return(rc);
+}
+
+/*
+ * hwgraph_info_get_next_LBL - Returns the next label info given the 
+ *	current label entry in place.
+ *
+ *	Once again this has no locking or reference count for protection.
+ *
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_next_LBL(vertex_hdl_t de,
+				char *buf,
+				arbitrary_info_t *infop,
+				labelcl_info_place_t *place)
+{
+	return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place));
+}
+
+/*
+ * hwgraph_info_export_LBL - Retrieve the specified label entry and modify 
+ *	the info_desc field with the given value in nbytes.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_export_LBL(vertex_hdl_t de, char *name, int nbytes)
+{
+	arbitrary_info_t info;
+	int rc;
+
+	if (nbytes == 0)
+		nbytes = INFO_DESC_EXPORT;
+
+	if (nbytes < 0)
+		return(-1);
+
+	rc = labelcl_info_get_LBL(de, name, NULL, &info);
+	if (rc != 0)
+		return(rc);
+
+	rc = labelcl_info_replace_LBL(de, name,
+				nbytes, info, NULL, NULL);
+
+	return(rc);
+}
+
+/*
+ * hwgraph_info_unexport_LBL - Retrieve the given label entry and change the 
+ * label info_descr filed to INFO_DESC_PRIVATE.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_unexport_LBL(vertex_hdl_t de, char *name)
+{
+	arbitrary_info_t info;
+	int rc;
+
+	rc = labelcl_info_get_LBL(de, name, NULL, &info);
+	if (rc != 0)
+		return(rc);
+
+	rc = labelcl_info_replace_LBL(de, name,
+				INFO_DESC_PRIVATE, info, NULL, NULL);
+
+	return(rc);
+}
+
+/*
+ * hwgraph_path_lookup - return the handle for the given path.
+ *
+ */
+int
+hwgraph_path_lookup(vertex_hdl_t start_vertex_handle,
+			char *lookup_path,
+			vertex_hdl_t *vertex_handle_ptr,
+			char **remainder)
+{
+	*vertex_handle_ptr = hwgfs_find_handle(start_vertex_handle,	/* start dir */
+					lookup_path,		/* path */
+					0,			/* major */
+					0,			/* minor */
+					0,			/* char | block */
+					1);			/* traverse symlinks */
+	if (*vertex_handle_ptr == NULL)
+		return(-1);
+	else
+		return(0);
+}
+
+/*
+ * hwgraph_traverse - Find and return the handle starting from de.
+ *
+ */
+graph_error_t
+hwgraph_traverse(vertex_hdl_t de, char *path, vertex_hdl_t *found)
+{
+	/* 
+	 * get the directory entry (path should end in a directory)
+	 */
+
+	*found = hwgfs_find_handle(de,	/* start dir */
+			    path,	/* path */
+			    0,		/* major */
+			    0,		/* minor */
+			    0,		/* char | block */
+			    1);		/* traverse symlinks */
+	if (*found == NULL)
+		return(GRAPH_NOT_FOUND);
+	else
+		return(GRAPH_SUCCESS);
+}
+
+/*
+ * hwgraph_path_to_vertex - Return the entry handle for the given 
+ *	pathname .. assume traverse symlinks too!.
+ */
+vertex_hdl_t
+hwgraph_path_to_vertex(char *path)
+{
+	return(hwgfs_find_handle(NULL,	/* start dir */
+			path,		/* path */
+		    	0,		/* major */
+		    	0,		/* minor */
+		    	0,		/* char | block */
+		    	1));		/* traverse symlinks */
+}
+
+/*
+ * hwgraph_inventory_remove - Removes an inventory entry.
+ *
+ *	Remove an inventory item associated with a vertex.   It is the caller's
+ *	responsibility to make sure that there are no races between removing
+ *	inventory from a vertex and simultaneously removing that vertex.
+*/
+int
+hwgraph_inventory_remove(	vertex_hdl_t de,
+				int class,
+				int type,
+				major_t controller,
+				minor_t unit,
+				int state)
+{
+	return(0); /* Just a Stub for IRIX code. */
+}
+
+/*
+ * Find the canonical name for a given vertex by walking back through
+ * connectpt's until we hit the hwgraph root vertex (or until we run
+ * out of buffer space or until something goes wrong).
+ *
+ *	COMPATIBILITY FUNCTIONALITY
+ * Walks back through 'parents', not necessarily the same as connectpts.
+ *
+ * Need to resolve the fact that does not return the path from 
+ * "/" but rather it just stops right before /dev ..
+ */
+int
+hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen)
+{
+	char *locbuf;
+	int   pos;
+
+	if (buflen < 1)
+		return(-1);	/* XXX should be GRAPH_BAD_PARAM ? */
+
+	locbuf = kmalloc(buflen, GFP_KERNEL);
+
+	pos = hwgfs_generate_path(vhdl, locbuf, buflen);
+	if (pos < 0) {
+		kfree(locbuf);
+		return pos;
+	}
+
+	strcpy(buf, &locbuf[pos]);
+	kfree(locbuf);
+	return 0;
+}
+
+/*
+** vertex_to_name converts a vertex into a canonical name by walking
+** back through connect points until we hit the hwgraph root (or until
+** we run out of buffer space).
+**
+** Usually returns a pointer to the original buffer, filled in as
+** appropriate.  If the buffer is too small to hold the entire name,
+** or if anything goes wrong while determining the name, vertex_to_name
+** returns "UnknownDevice".
+*/
+
+#define DEVNAME_UNKNOWN "UnknownDevice"
+
+char *
+vertex_to_name(vertex_hdl_t vhdl, char *buf, uint buflen)
+{
+	if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS)
+		return(buf);
+	else
+		return(DEVNAME_UNKNOWN);
+}
+
+graph_error_t
+hwgraph_edge_remove(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
+{
+	return(GRAPH_ILLEGAL_REQUEST);
+}
+
+graph_error_t
+hwgraph_vertex_unref(vertex_hdl_t vhdl)
+{
+	return(GRAPH_ILLEGAL_REQUEST);
+}
+
+
+EXPORT_SYMBOL(hwgraph_mk_dir);
+EXPORT_SYMBOL(hwgraph_path_add);
+EXPORT_SYMBOL(hwgraph_register);
+EXPORT_SYMBOL(hwgraph_vertex_destroy);
+EXPORT_SYMBOL(hwgraph_fastinfo_get);
+EXPORT_SYMBOL(hwgraph_fastinfo_set);
+EXPORT_SYMBOL(hwgraph_connectpt_set);
+EXPORT_SYMBOL(hwgraph_connectpt_get);
+EXPORT_SYMBOL(hwgraph_info_add_LBL);
+EXPORT_SYMBOL(hwgraph_info_remove_LBL);
+EXPORT_SYMBOL(hwgraph_info_replace_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_exported_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_next_LBL);
+EXPORT_SYMBOL(hwgraph_info_export_LBL);
+EXPORT_SYMBOL(hwgraph_info_unexport_LBL);
+EXPORT_SYMBOL(hwgraph_path_lookup);
+EXPORT_SYMBOL(hwgraph_traverse);
+EXPORT_SYMBOL(hwgraph_vertex_name_get);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hwgfs/hcl_util.c linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/hcl_util.c
--- linux-2.4.21/arch/ia64/sn/io/hwgfs/hcl_util.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/hcl_util.c	2003-08-01 13:34:43.000000000 +0000
@@ -0,0 +1,200 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/sn/sgi.h>
+#include <asm/io.h>
+#include <asm/sn/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/hwgfs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/nodepda.h>
+
+static vertex_hdl_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE;
+extern vertex_hdl_t hwgraph_root;
+
+
+/*
+** Return the "master" for a given vertex.  A master vertex is a
+** controller or adapter or other piece of hardware that the given
+** vertex passes through on the way to the rest of the system.
+*/
+vertex_hdl_t
+device_master_get(vertex_hdl_t vhdl)
+{
+	graph_error_t rc;
+	vertex_hdl_t master;
+
+	rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master);
+	if (rc == GRAPH_SUCCESS)
+		return(master);
+	else
+		return(GRAPH_VERTEX_NONE);
+}
+
+/*
+** Set the master for a given vertex.
+** Returns 0 on success, non-0 indicates failure
+*/
+int
+device_master_set(vertex_hdl_t vhdl, vertex_hdl_t master)
+{
+	graph_error_t rc;
+
+	rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER);
+	return(rc != GRAPH_SUCCESS);
+}
+
+
+/*
+** Return the compact node id of the node that ultimately "owns" the specified
+** vertex.  In order to do this, we walk back through masters and connect points
+** until we reach a vertex that represents a node.
+*/
+cnodeid_t
+master_node_get(vertex_hdl_t vhdl)
+{
+	cnodeid_t cnodeid;
+	vertex_hdl_t master;
+
+	for (;;) {
+		cnodeid = nodevertex_to_cnodeid(vhdl);
+		if (cnodeid != CNODEID_NONE)
+			return(cnodeid);
+
+		master = device_master_get(vhdl);
+
+		/* Check for exceptional cases */
+		if (master == vhdl) {
+			/* Since we got a reference to the "master" thru
+			 * device_master_get() we should decrement
+			 * its reference count by 1
+			 */
+			return(CNODEID_NONE);
+		}
+
+		if (master == GRAPH_VERTEX_NONE) {
+			master = hwgraph_connectpt_get(vhdl);
+			if ((master == GRAPH_VERTEX_NONE) ||
+			    (master == vhdl)) {
+				return(CNODEID_NONE);
+			}
+		}
+
+		vhdl = master;
+	}
+}
+
+static vertex_hdl_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE;
+extern int maxcpus;
+
+void
+mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid)
+{
+	if (cpuid == CPU_NONE)
+		return;
+
+	(void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT,
+			(arbitrary_info_t)cpuid);
+	{
+		char cpuid_buffer[10];
+
+		if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) {
+			(void)hwgraph_path_add( hwgraph_root,
+						EDGE_LBL_CPUNUM,
+						&hwgraph_all_cpuids);
+		}
+
+		sprintf(cpuid_buffer, "%ld", cpuid);
+		(void)hwgraph_edge_add( hwgraph_all_cpuids,
+							vhdl,
+							cpuid_buffer);
+	}
+}
+
+/*
+** If the specified device represents a node, return its
+** compact node ID; otherwise, return CNODEID_NONE.
+*/
+cnodeid_t
+nodevertex_to_cnodeid(vertex_hdl_t vhdl)
+{
+	int rv = 0;
+	arbitrary_info_t cnodeid = CNODEID_NONE;
+
+	rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid);
+
+	return((cnodeid_t)cnodeid);
+}
+
+void
+mark_nodevertex_as_node(vertex_hdl_t vhdl, cnodeid_t cnodeid)
+{
+	if (cnodeid == CNODEID_NONE)
+		return;
+
+	cnodeid_to_vertex(cnodeid) = vhdl;
+	labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, 
+		(arbitrary_info_t)cnodeid);
+
+	{
+		char cnodeid_buffer[10];
+
+		if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) {
+			(void)hwgraph_path_add( hwgraph_root,
+						EDGE_LBL_NODENUM,
+						&hwgraph_all_cnodes);
+		}
+
+		sprintf(cnodeid_buffer, "%d", cnodeid);
+		(void)hwgraph_edge_add( hwgraph_all_cnodes,
+					vhdl,
+					cnodeid_buffer);
+	}
+}
+
+/*
+** If the specified device represents a CPU, return its cpuid;
+** otherwise, return CPU_NONE.
+*/
+cpuid_t
+cpuvertex_to_cpuid(vertex_hdl_t vhdl)
+{
+	arbitrary_info_t cpuid = CPU_NONE;
+
+	(void)labelcl_info_get_LBL(vhdl, INFO_LBL_CPUID, NULL, &cpuid);
+
+	return((cpuid_t)cpuid);
+}
+
+
+/*
+** dev_to_name converts a vertex_hdl_t into a canonical name.  If the vertex_hdl_t
+** represents a vertex in the hardware graph, it is converted in the
+** normal way for vertices.  If the vertex_hdl_t is an old vertex_hdl_t (one which
+** does not represent a hwgraph vertex), we synthesize a name based
+** on major/minor number.
+**
+** Usually returns a pointer to the original buffer, filled in as
+** appropriate.  If the buffer is too small to hold the entire name,
+** or if anything goes wrong while determining the name, dev_to_name
+** returns "UnknownDevice".
+*/
+char *
+dev_to_name(vertex_hdl_t dev, char *buf, uint buflen)
+{
+        return(vertex_to_name(dev, buf, buflen));
+}
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hwgfs/hwgfs.h linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/hwgfs.h
--- linux-2.4.21/arch/ia64/sn/io/hwgfs/hwgfs.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/hwgfs.h	2003-08-01 13:30:44.000000000 +0000
@@ -0,0 +1,23 @@
+
+typedef struct dentry *hwgfs_handle_t;
+
+extern hwgfs_handle_t hwgfs_register(hwgfs_handle_t dir, const char *name,
+				     unsigned int flags,
+				     unsigned int major, unsigned int minor,
+				     umode_t mode, void *ops, void *info);
+extern int hwgfs_mk_symlink(hwgfs_handle_t dir, const char *name,
+			     unsigned int flags, const char *link,
+			     hwgfs_handle_t *handle, void *info);
+extern hwgfs_handle_t hwgfs_mk_dir(hwgfs_handle_t dir, const char *name,
+				    void *info);
+extern void hwgfs_unregister(hwgfs_handle_t de);
+
+extern hwgfs_handle_t hwgfs_find_handle(hwgfs_handle_t dir, const char *name,
+					unsigned int major,unsigned int minor,
+					char type, int traverse_symlinks);
+extern hwgfs_handle_t hwgfs_get_parent(hwgfs_handle_t de);
+extern int hwgfs_generate_path(hwgfs_handle_t de, char *path, int buflen);
+
+extern void *hwgfs_get_info(hwgfs_handle_t de);
+extern int hwgfs_set_info(hwgfs_handle_t de, void *info);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hwgfs/interface.c linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/interface.c
--- linux-2.4.21/arch/ia64/sn/io/hwgfs/interface.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/interface.c	2003-08-01 13:34:04.000000000 +0000
@@ -0,0 +1,326 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/sched.h>		/* needed for smp_lock.h :( */
+#include <linux/smp_lock.h>
+
+#include <linux/slab.h>
+
+#include <asm/sn/hwgfs.h>
+
+extern struct vfsmount *hwgfs_vfsmount;
+
+/* TODO: Move this to some .h file or, more likely, use a slightly
+   different interface from lookup_create. */
+extern struct dentry *lookup_create(struct nameidata *nd, int is_dir);
+
+static int
+walk_parents_mkdir(
+	const char		**path,
+	struct nameidata	*nd,
+	int			is_dir)
+{
+	char			*slash;
+	char			buf[strlen(*path)+1];
+	int			error;
+
+	while ((slash = strchr(*path, '/')) != NULL) {
+		int len = slash - *path;
+		memcpy(buf, *path, len);
+		buf[len] = '\0';
+
+		error = link_path_walk(buf, nd); 
+		if (unlikely(error))
+			return error;
+
+		nd->dentry = lookup_create(nd, is_dir);
+		if (unlikely(IS_ERR(nd->dentry)))
+			return PTR_ERR(nd->dentry);
+
+		if (!nd->dentry->d_inode)
+			error = vfs_mkdir(nd->dentry->d_parent->d_inode,
+					nd->dentry, 0755);
+		
+		up(&nd->dentry->d_parent->d_inode->i_sem);
+		if (unlikely(error))
+			return error;
+
+		*path += len + 1;
+	}
+
+	return 0;
+}
+
+/* On success, returns with parent_inode->i_sem taken. */
+static int
+hwgfs_decode(
+	hwgfs_handle_t		dir,
+	const char		*name,
+	int			is_dir,
+	struct inode		**parent_inode,
+	struct dentry		**dentry)
+{
+	struct nameidata	nd;
+	int			error;
+
+	if (!dir)
+		dir = hwgfs_vfsmount->mnt_sb->s_root;
+
+	memset(&nd, 0, sizeof(nd));
+	nd.flags = LOOKUP_PARENT;
+	nd.mnt = mntget(hwgfs_vfsmount);
+	nd.dentry = dget(dir);
+
+	error = walk_parents_mkdir(&name, &nd, is_dir);
+	if (unlikely(error))
+		return error;
+
+	error = link_path_walk(name, &nd);
+	if (unlikely(error))
+		return error;
+
+	*dentry = lookup_create(&nd, is_dir);
+
+	if (unlikely(IS_ERR(*dentry)))
+		return PTR_ERR(*dentry);
+	*parent_inode = (*dentry)->d_parent->d_inode;
+	return 0;
+}
+
+static int
+path_len(
+	struct dentry		*de,
+	struct dentry		*root)
+{
+	int			len = 0;
+
+	while (de != root) {
+		len += de->d_name.len + 1;	/* count the '/' */
+		de = de->d_parent;
+	}
+	return len;		/* -1 because we omit the leading '/',
+				   +1 because we include trailing '\0' */
+}
+
+int
+hwgfs_generate_path(
+	hwgfs_handle_t		de,
+	char			*path,
+	int			buflen)
+{
+	struct dentry		*hwgfs_root;
+	int			len;
+	char			*path_orig = path;
+
+	if (unlikely(de == NULL))
+		return -EINVAL;
+
+	hwgfs_root = hwgfs_vfsmount->mnt_sb->s_root;
+	if (unlikely(de == hwgfs_root))
+		return -EINVAL;
+
+	spin_lock(&dcache_lock);
+	len = path_len(de, hwgfs_root);
+	if (len > buflen) {
+		spin_unlock(&dcache_lock);
+		return -ENAMETOOLONG;
+	}
+
+	path += len - 1;
+	*path = '\0';
+
+	for (;;) {
+		path -= de->d_name.len;
+		memcpy(path, de->d_name.name, de->d_name.len);
+		de = de->d_parent;
+		if (de == hwgfs_root)
+			break;
+		*(--path) = '/';
+	}
+		
+	spin_unlock(&dcache_lock);
+	BUG_ON(path != path_orig);
+	return 0;
+}
+
+hwgfs_handle_t
+hwgfs_register(
+	hwgfs_handle_t		dir,
+	const char		*name,
+	unsigned int		flags,
+	unsigned int		major,
+	unsigned int		minor,
+	umode_t			mode,
+	void			*ops,
+	void			*info)
+{
+	dev_t			devnum = MKDEV(major, minor);
+	struct inode		*parent_inode;
+	struct dentry		*dentry;
+	int			error;
+
+	error = hwgfs_decode(dir, name, 0, &parent_inode, &dentry);
+	if (likely(!error)) {
+		error = vfs_mknod(parent_inode, dentry, mode, devnum);
+		if (likely(!error)) {
+			/*
+			 * Do this inside parents i_sem to avoid racing
+			 * with lookups.
+			 */
+			if (S_ISCHR(mode))
+				dentry->d_inode->i_fop = ops;
+			dentry->d_fsdata = info;
+			up(&parent_inode->i_sem);
+		} else {
+			up(&parent_inode->i_sem);
+			dput(dentry);
+			dentry = NULL;
+                }
+	}
+
+	return dentry;
+}
+
+int
+hwgfs_mk_symlink(
+	hwgfs_handle_t		dir,
+	const char		*name,
+	unsigned int		flags,
+	const char		*link,
+	hwgfs_handle_t		*handle,
+	void			*info)
+{
+	struct inode		*parent_inode;
+	struct dentry		*dentry;
+	int			error;
+
+	error = hwgfs_decode(dir, name, 0, &parent_inode, &dentry);
+	if (likely(!error)) {
+		error = vfs_symlink(parent_inode, dentry, link);
+		dentry->d_fsdata = info;
+		if (handle)
+			*handle = dentry;
+		up(&parent_inode->i_sem);
+		/* dput(dentry); */
+	}
+	return error;
+}
+
+hwgfs_handle_t
+hwgfs_mk_dir(
+	hwgfs_handle_t		dir,
+	const char		*name,
+	void			*info)
+{
+	struct inode		*parent_inode;
+	struct dentry		*dentry;
+	int			error;
+
+	error = hwgfs_decode(dir, name, 1, &parent_inode, &dentry);
+	if (likely(!error)) {
+		error = vfs_mkdir(parent_inode, dentry, 0755);
+		up(&parent_inode->i_sem);
+
+		if (unlikely(error)) {
+			dput(dentry);
+			dentry = NULL;
+		} else {
+			dentry->d_fsdata = info;
+		}
+	}
+	return dentry;
+}
+
+void
+hwgfs_unregister(
+	hwgfs_handle_t		de)
+{
+	struct inode		*parent_inode = de->d_parent->d_inode;
+
+	if (S_ISDIR(de->d_inode->i_mode))
+		vfs_rmdir(parent_inode, de);
+	else
+		vfs_unlink(parent_inode, de);
+}
+
+/* XXX: this function is utterly bogus.  Every use of it is racy and the
+        prototype is stupid.  You have been warned.  --hch.  */
+hwgfs_handle_t
+hwgfs_find_handle(
+	hwgfs_handle_t		base,
+	const char		*name,
+	unsigned int		major,		/* IGNORED */
+	unsigned int		minor,		/* IGNORED */
+	char			type,		/* IGNORED */
+	int			traverse_symlinks)
+{
+	struct dentry		*dentry = NULL;
+	struct nameidata	nd;
+	int			error;
+
+	BUG_ON(*name=='/');
+
+	memset(&nd, 0, sizeof(nd));
+
+	nd.mnt = mntget(hwgfs_vfsmount);
+	nd.dentry = dget(base ? base : hwgfs_vfsmount->mnt_sb->s_root);
+	nd.flags = LOOKUP_POSITIVE | (traverse_symlinks ? LOOKUP_FOLLOW : 0);
+
+	error = link_path_walk(name, &nd);
+	if (likely(!error)) {
+		dentry = nd.dentry;
+		path_release(&nd);		/* stale data from here! */
+	}
+
+	return dentry;
+}
+
+hwgfs_handle_t
+hwgfs_get_parent(
+	hwgfs_handle_t		de)
+{
+	struct dentry		*parent;
+
+	lock_kernel();		/* XXX: for LBS this must be dparent_lock */
+	parent = de->d_parent;
+	unlock_kernel();
+
+	return parent;
+}
+
+int
+hwgfs_set_info(
+	hwgfs_handle_t		de,
+	void			*info)
+{
+	if (unlikely(de == NULL))
+		return -EINVAL;
+	de->d_fsdata = info;
+	return 0;
+}
+
+void *
+hwgfs_get_info(
+	hwgfs_handle_t		de)
+{
+	return de->d_fsdata;
+}
+
+EXPORT_SYMBOL(hwgfs_generate_path);
+EXPORT_SYMBOL(hwgfs_register);
+EXPORT_SYMBOL(hwgfs_unregister);
+EXPORT_SYMBOL(hwgfs_mk_symlink);
+EXPORT_SYMBOL(hwgfs_mk_dir);
+EXPORT_SYMBOL(hwgfs_find_handle);
+EXPORT_SYMBOL(hwgfs_get_parent);
+EXPORT_SYMBOL(hwgfs_set_info);
+EXPORT_SYMBOL(hwgfs_get_info);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hwgfs/invent_stub.c linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/invent_stub.c
--- linux-2.4.21/arch/ia64/sn/io/hwgfs/invent_stub.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/invent_stub.c	2003-08-01 13:34:42.000000000 +0000
@@ -0,0 +1,148 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+/*
+ * Hardware Inventory
+ *
+ * See sys/sn/invent.h for an explanation of the hardware inventory contents.
+ *
+ */
+#include <linux/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/hwgfs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/invent.h>
+
+void
+inventinit(void)
+{
+}
+
+/*
+ * For initializing/updating an inventory entry.
+ */
+void
+replace_in_inventory(
+	inventory_t *pinv, int class, int type,
+	int controller, int unit, int state)
+{
+}
+
+/*
+ * Inventory addition 
+ *
+ * XXX NOTE: Currently must be called after dynamic memory allocator is
+ * initialized.
+ *
+ */
+void
+add_to_inventory(int class, int type, int controller, int unit, int state)
+{
+}
+
+
+/*
+ * Inventory retrieval 
+ *
+ * These two routines are intended to prevent the caller from having to know
+ * the internal structure of the inventory table.
+ *
+ * The caller of get_next_inventory is supposed to call start_scan_invent
+ * before the irst call to get_next_inventory, and the caller is required
+ * to call end_scan_invent after the last call to get_next_inventory.
+ */
+inventory_t *
+get_next_inventory(invplace_t *place)
+{
+	return((inventory_t *) NULL);
+}
+
+/* ARGSUSED */
+int
+get_sizeof_inventory(int abi)
+{
+	return sizeof(inventory_t);
+}
+
+/* Must be called prior to first call to get_next_inventory */
+void
+start_scan_inventory(invplace_t *iplace)
+{
+}
+
+/* Must be called after last call to get_next_inventory */
+void
+end_scan_inventory(invplace_t *iplace)
+{
+}
+
+/*
+ * Hardware inventory scanner.
+ *
+ * Calls fun() for every entry in inventory list unless fun() returns something
+ * other than 0.
+ */
+int
+scaninvent(int (*fun)(inventory_t *, void *), void *arg)
+{
+	return 0;
+}
+
+/*
+ * Find a particular inventory object
+ *
+ * pinv can be a pointer to an inventory entry and the search will begin from
+ * there, or it can be 0 in which case the search starts at the beginning.
+ * A -1 for any of the other arguments is a wildcard (i.e. it always matches).
+ */
+inventory_t *
+find_inventory(inventory_t *pinv, int class, int type, int controller,
+	       int unit, int state)
+{
+	return((inventory_t *) NULL);
+}
+
+
+/*
+** Retrieve inventory data associated with a device.
+*/
+inventory_t *
+device_inventory_get_next(	vertex_hdl_t device,
+				invplace_t *invplace)
+{
+		return((inventory_t *) NULL);
+}
+
+
+/*
+** Associate canonical inventory information with a device (and
+** add it to the general inventory).
+*/
+void
+device_inventory_add(	vertex_hdl_t device,
+			int class, 
+			int type, 
+			major_t controller, 
+			minor_t unit, 
+			int state)
+{
+}
+
+int
+device_controller_num_get(vertex_hdl_t device)
+{
+	return (0);
+}
+
+void
+device_controller_num_set(vertex_hdl_t device, int contr_num)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hwgfs/labelcl.c linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/labelcl.c
--- linux-2.4.21/arch/ia64/sn/io/hwgfs/labelcl.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/labelcl.c	2003-08-01 13:32:00.000000000 +0000
@@ -0,0 +1,657 @@
+/*  labelcl - SGI's Hwgraph Compatibility Layer.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
+*/
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/sched.h>                /* needed for smp_lock.h :( */
+#include <linux/smp_lock.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/hwgfs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+
+/*
+** Very simple and dumb string table that supports only find/insert.
+** In practice, if this table gets too large, we may need a more
+** efficient data structure.   Also note that currently there is no 
+** way to delete an item once it's added.  Therefore, name collision 
+** will return an error.
+*/
+
+struct string_table label_string_table;
+
+
+
+/*
+ * string_table_init - Initialize the given string table.
+ */
+void
+string_table_init(struct string_table *string_table)
+{
+	string_table->string_table_head = NULL;
+	string_table->string_table_generation = 0;
+
+	/*
+	 * We nedd to initialize locks here!
+	 */
+
+	return;
+}
+
+
+/*
+ * string_table_destroy - Destroy the given string table.
+ */
+void
+string_table_destroy(struct string_table *string_table)
+{
+	struct string_table_item *item, *next_item;
+
+	item = string_table->string_table_head;
+	while (item) {
+		next_item = item->next;
+
+		STRTBL_FREE(item);
+		item = next_item;
+	}
+
+	/*
+	 * We need to destroy whatever lock we have here
+	 */
+
+	return;
+}
+
+
+
+/*
+ * string_table_insert - Insert an entry in the string table .. duplicate 
+ *	names are not allowed.
+ */
+char *
+string_table_insert(struct string_table *string_table, char *name)
+{
+	struct string_table_item *item, *new_item = NULL, *last_item = NULL;
+
+again:
+	/*
+	 * Need to lock the table ..
+	 */
+	item = string_table->string_table_head;
+	last_item = NULL;
+
+	while (item) {
+		if (!strcmp(item->string, name)) {
+			/*
+			 * If we allocated space for the string and the found that
+			 * someone else already entered it into the string table,
+			 * free the space we just allocated.
+			 */
+			if (new_item)
+				STRTBL_FREE(new_item);
+
+
+			/*
+			 * Search optimization: move the found item to the head
+			 * of the list.
+			 */
+			if (last_item != NULL) {
+				last_item->next = item->next;
+				item->next = string_table->string_table_head;
+				string_table->string_table_head = item;
+			}
+			goto out;
+		}
+		last_item = item;
+		item=item->next;
+	}
+
+	/*
+	 * name was not found, so add it to the string table.
+	 */
+	if (new_item == NULL) {
+		long old_generation = string_table->string_table_generation;
+
+		new_item = STRTBL_ALLOC(strlen(name));
+
+		strcpy(new_item->string, name);
+
+		/*
+		 * While we allocated memory for the new string, someone else 
+		 * changed the string table.
+		 */
+		if (old_generation != string_table->string_table_generation) {
+			goto again;
+		}
+	} else {
+		/* At this we only have the string table lock in access mode.
+		 * Promote the access lock to an update lock for the string
+		 * table insertion below.
+		 */
+			long old_generation = 
+				string_table->string_table_generation;
+
+			/*
+			 * After we did the unlock and wer waiting for update
+			 * lock someone could have potentially updated
+			 * the string table. Check the generation number
+			 * for this case. If it is the case we have to
+			 * try all over again.
+			 */
+			if (old_generation != 
+			    string_table->string_table_generation) {
+				goto again;
+			}
+		}
+
+	/*
+	 * At this point, we're committed to adding new_item to the string table.
+	 */
+	new_item->next = string_table->string_table_head;
+	item = string_table->string_table_head = new_item;
+	string_table->string_table_generation++;
+
+out:
+	/*
+	 * Need to unlock here.
+	 */
+	return(item->string);
+}
+
+/*
+ * labelcl_info_create - Creates the data structure that will hold the
+ *	device private information asscoiated with a entry.
+ *	The pointer to this structure is what gets stored in the 
+ *	(void * info).
+ */
+labelcl_info_t *
+labelcl_info_create()
+{
+
+	labelcl_info_t *new = NULL;
+
+	/* Initial allocation does not include any area for labels */
+	if ( ( new = (labelcl_info_t *)kmalloc (sizeof(labelcl_info_t), GFP_KERNEL) ) == NULL )
+		return NULL;
+
+	memset (new, 0, sizeof(labelcl_info_t));
+	new->hwcl_magic = LABELCL_MAGIC;
+	return( new);
+
+}
+
+/*
+ * labelcl_info_destroy - Frees the data structure that holds the
+ *      device private information asscoiated with a entry.  This 
+ *	data structure was created by device_info_create().
+ *
+ *	The caller is responsible for nulling the (void *info) in the 
+ *	corresponding entry.
+ */
+int
+labelcl_info_destroy(labelcl_info_t *labelcl_info)
+{
+
+	if (labelcl_info == NULL)
+		return(0);
+
+	/* Free the label list */
+	if (labelcl_info->label_list)
+		kfree(labelcl_info->label_list);
+
+	/* Now free the label info area */
+	labelcl_info->hwcl_magic = 0;
+	kfree(labelcl_info);
+
+	return(0);
+}
+
+/*
+ * labelcl_info_add_LBL - Adds a new label entry in the labelcl info 
+ *	structure.
+ *
+ *	Error is returned if we find another label with the same name.
+ */
+int
+labelcl_info_add_LBL(vertex_hdl_t de,
+			char *info_name,
+			arb_info_desc_t info_desc,
+			arbitrary_info_t info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	int new_label_list_size;
+	label_info_t *old_label_list, *new_label_list = NULL;
+	char *name;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+        labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if (info_name == NULL)
+		return(-1);
+
+	if (strlen(info_name) >= LABEL_LENGTH_MAX)
+		return(-1);
+
+	name = string_table_insert(&label_string_table, info_name);
+
+	num_labels = labelcl_info->num_labels;
+	new_label_list_size = sizeof(label_info_t) * (num_labels+1);
+
+	/*
+	 * Create a new label info area.
+	 */
+	if (new_label_list_size != 0) {
+		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
+
+		if (new_label_list == NULL)
+			return(-1);
+	}
+
+	/*
+	 * At this point, we are committed to adding the labelled info, 
+	 * if there isn't already information there with the same name.
+	 */
+	old_label_list = labelcl_info->label_list;
+
+	/* 
+	 * Look for matching info name.
+	 */
+	for (i=0; i<num_labels; i++) {
+		if (!strcmp(info_name, old_label_list[i].name)) {
+			/* Not allowed to add duplicate labelled info names. */
+			kfree(new_label_list);
+			return(-1);
+		}
+		new_label_list[i] = old_label_list[i]; /* structure copy */
+	}
+
+	new_label_list[num_labels].name = name;
+	new_label_list[num_labels].desc = info_desc;
+	new_label_list[num_labels].info = info;
+
+	labelcl_info->num_labels = num_labels+1;
+	labelcl_info->label_list = new_label_list;
+
+	if (old_label_list != NULL)
+		kfree(old_label_list);
+
+	return(0);
+}
+
+/*
+ * labelcl_info_remove_LBL - Remove a label entry.
+ */
+int
+labelcl_info_remove_LBL(vertex_hdl_t de,
+			 char *info_name,
+			 arb_info_desc_t *info_desc,
+			 arbitrary_info_t *info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	int new_label_list_size;
+	label_info_t *old_label_list, *new_label_list = NULL;
+	arb_info_desc_t label_desc_found;
+	arbitrary_info_t label_info_found;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	/*
+	 * Create a new info area.
+	 */
+	new_label_list_size = sizeof(label_info_t) * (num_labels-1);
+	if (new_label_list_size) {
+		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
+		if (new_label_list == NULL)
+			return(-1);
+	}
+
+	/*
+	 * At this point, we are committed to removing the labelled info, 
+	 * if it still exists.
+	 */
+	old_label_list = labelcl_info->label_list;
+
+	/* 
+	 * Find matching info name.
+	 */
+	for (i=0; i<num_labels; i++) {
+		if (!strcmp(info_name, old_label_list[i].name)) {
+			label_desc_found = old_label_list[i].desc;
+			label_info_found = old_label_list[i].info;
+			goto found;
+		}
+		if (i < num_labels-1) /* avoid walking off the end of the new vertex */
+			new_label_list[i] = old_label_list[i]; /* structure copy */
+	}
+
+	/* The named info doesn't exist. */
+	if (new_label_list)
+		kfree(new_label_list);
+
+	return(-1);
+
+found:
+	/* Finish up rest of labelled info */
+	for (i=i+1; i<num_labels; i++)
+		new_label_list[i-1] = old_label_list[i]; /* structure copy */
+
+	labelcl_info->num_labels = num_labels+1;
+	labelcl_info->label_list = new_label_list;
+
+	kfree(old_label_list);
+
+	if (info != NULL)
+		*info = label_info_found;
+
+	if (info_desc != NULL)
+		*info_desc = label_desc_found;
+
+	return(0);
+}
+
+
+/*
+ * labelcl_info_replace_LBL - Replace an existing label entry with the 
+ *	given new information.
+ *
+ *	Label entry must exist.
+ */
+int
+labelcl_info_replace_LBL(vertex_hdl_t de,
+			char *info_name,
+			arb_info_desc_t info_desc,
+			arbitrary_info_t info,
+			arb_info_desc_t *old_info_desc,
+			arbitrary_info_t *old_info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	label_info_t *label_list;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	if (info_name == NULL)
+		return(-1);
+
+	label_list = labelcl_info->label_list;
+
+	/* 
+	 * Verify that information under info_name already exists.
+	 */
+	for (i=0; i<num_labels; i++)
+		if (!strcmp(info_name, label_list[i].name)) {
+			if (old_info != NULL)
+				*old_info = label_list[i].info;
+
+			if (old_info_desc != NULL)
+				*old_info_desc = label_list[i].desc;
+
+			label_list[i].info = info;
+			label_list[i].desc = info_desc;
+
+			return(0);
+		}
+
+
+	return(-1);
+}
+
+/*
+ * labelcl_info_get_LBL - Retrieve and return the information for the 
+ *	given label entry.
+ */
+int
+labelcl_info_get_LBL(vertex_hdl_t de,
+		      char *info_name,
+		      arb_info_desc_t *info_desc,
+		      arbitrary_info_t *info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	label_info_t *label_list;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	label_list = labelcl_info->label_list;
+
+	/* 
+	 * Find information under info_name.
+	 */
+	for (i=0; i<num_labels; i++)
+		if (!strcmp(info_name, label_list[i].name)) {
+			if (info != NULL)
+				*info = label_list[i].info;
+			if (info_desc != NULL)
+				*info_desc = label_list[i].desc;
+
+			return(0);
+		}
+
+	return(-1);
+}
+
+/*
+ * labelcl_info_get_next_LBL - returns the next label entry on the list.
+ */
+int
+labelcl_info_get_next_LBL(vertex_hdl_t de,
+			   char *buffer,
+			   arb_info_desc_t *info_descp,
+			   arbitrary_info_t *infop,
+			   labelcl_info_place_t *placeptr)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	uint which_info;
+	label_info_t *label_list;
+
+	if ((buffer == NULL) && (infop == NULL))
+		return(-1);
+
+	if (placeptr == NULL)
+		return(-1);
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	which_info = *placeptr;
+
+	if (which_info >= labelcl_info->num_labels) {
+		return(-1);
+	}
+
+	label_list = (label_info_t *) labelcl_info->label_list;
+
+	if (buffer != NULL)
+		strcpy(buffer, label_list[which_info].name);
+
+	if (infop)
+		*infop = label_list[which_info].info;
+
+	if (info_descp)
+		*info_descp = label_list[which_info].desc;
+
+	*placeptr = which_info + 1;
+
+	return(0);
+}
+
+
+int
+labelcl_info_replace_IDX(vertex_hdl_t de,
+			int index,
+			arbitrary_info_t info,
+			arbitrary_info_t *old_info)
+{
+	arbitrary_info_t *info_list_IDX;
+	labelcl_info_t	*labelcl_info = NULL;
+
+	if (de == NULL) {
+		printk(KERN_ALERT "labelcl: NULL handle given.\n");
+		return(-1);
+	}
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL) {
+		printk(KERN_ALERT "labelcl: Entry %p does not have info pointer.\n", (void *)de);
+		return(-1);
+	}
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
+		return(-1);
+
+	/*
+	 * Replace information at the appropriate index in this vertex with 
+	 * the new info.
+	 */
+	info_list_IDX = labelcl_info->IDX_list;
+	if (old_info != NULL)
+		*old_info = info_list_IDX[index];
+	info_list_IDX[index] = info;
+
+	return(0);
+
+}
+
+/*
+ * labelcl_info_connectpt_set - Sets the connectpt.
+ */
+int
+labelcl_info_connectpt_set(hwgfs_handle_t de,
+			  hwgfs_handle_t connect_de)
+{
+	arbitrary_info_t old_info;
+	int	rv;
+
+	rv = labelcl_info_replace_IDX(de, HWGRAPH_CONNECTPT, 
+		(arbitrary_info_t) connect_de, &old_info);
+
+	if (rv) {
+		return(rv);
+	}
+
+	return(0);
+}
+
+
+/*
+ * labelcl_info_get_IDX - Returns the information pointed at by index.
+ *
+ */
+int
+labelcl_info_get_IDX(vertex_hdl_t de,
+			int index,
+			arbitrary_info_t *info)
+{
+	arbitrary_info_t *info_list_IDX;
+	labelcl_info_t	*labelcl_info = NULL;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
+		return(-1);
+
+	/*
+	 * Return information at the appropriate index in this vertex.
+	 */
+	info_list_IDX = labelcl_info->IDX_list;
+	if (info != NULL)
+		*info = info_list_IDX[index];
+
+	return(0);
+}
+
+/*
+ * labelcl_info_connectpt_get - Retrieve the connect point for a device entry.
+ */
+hwgfs_handle_t
+labelcl_info_connectpt_get(hwgfs_handle_t de)
+{
+	int rv;
+	arbitrary_info_t info;
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
+	if (rv)
+		return(NULL);
+
+	return((hwgfs_handle_t) info);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/hwgfs/ramfs.c linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/ramfs.c
--- linux-2.4.21/arch/ia64/sn/io/hwgfs/ramfs.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/hwgfs/ramfs.c	2003-08-01 13:31:13.000000000 +0000
@@ -0,0 +1,341 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/machvec.h>
+
+/* some random number */
+#define HWGFS_MAGIC	0x12061983
+
+static struct super_operations hwgfs_ops;
+static struct address_space_operations hwgfs_aops;
+static struct file_operations hwgfs_file_operations;
+static struct inode_operations hwgfs_dir_inode_operations;
+
+static int hwgfs_statfs(struct super_block *sb, struct statfs *buf)
+{
+	buf->f_type = HWGFS_MAGIC;
+	buf->f_bsize = PAGE_CACHE_SIZE;
+	buf->f_namelen = 255;
+	return 0;
+}
+
+/*
+ * Lookup the data. This is trivial - if the dentry didn't already
+ * exist, we know it is negative.
+ */
+static struct dentry * hwgfs_lookup(struct inode *dir, struct dentry *dentry)
+{
+	d_add(dentry, NULL);
+	return NULL;
+}
+
+/*
+ * Read a page. Again trivial. If it didn't already exist
+ * in the page cache, it is zero-filled.
+ */
+static int hwgfs_readpage(struct file *file, struct page * page)
+{
+	if (!Page_Uptodate(page)) {
+		memset(kmap(page), 0, PAGE_CACHE_SIZE);
+		kunmap(page);
+		flush_dcache_page(page);
+		SetPageUptodate(page);
+	}
+	UnlockPage(page);
+	return 0;
+}
+
+static int hwgfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+{
+	void *addr = kmap(page);
+	if (!Page_Uptodate(page)) {
+		memset(addr, 0, PAGE_CACHE_SIZE);
+		flush_dcache_page(page);
+		SetPageUptodate(page);
+	}
+	SetPageDirty(page);
+	return 0;
+}
+
+static int hwgfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+{
+	struct inode *inode = page->mapping->host;
+	loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+
+	kunmap(page);
+	if (pos > inode->i_size)
+		inode->i_size = pos;
+	return 0;
+}
+
+struct inode *hwgfs_get_inode(struct super_block *sb, int mode, int dev)
+{
+	struct inode * inode = new_inode(sb);
+
+	if (inode) {
+		inode->i_mode = mode;
+		inode->i_uid = current->fsuid;
+		inode->i_gid = current->fsgid;
+		inode->i_blksize = PAGE_CACHE_SIZE;
+		inode->i_blocks = 0;
+		inode->i_rdev = NODEV;
+		inode->i_mapping->a_ops = &hwgfs_aops;
+		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		switch (mode & S_IFMT) {
+		default:
+			init_special_inode(inode, mode, dev);
+			break;
+		case S_IFREG:
+			inode->i_fop = &hwgfs_file_operations;
+			break;
+		case S_IFDIR:
+			inode->i_op = &hwgfs_dir_inode_operations;
+			inode->i_fop = &dcache_dir_ops;
+			break;
+		case S_IFLNK:
+			inode->i_op = &page_symlink_inode_operations;
+			break;
+		}
+	}
+	return inode;
+}
+
+/*
+ * File creation. Allocate an inode, and we're done..
+ */
+static int hwgfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
+{
+	struct inode * inode = hwgfs_get_inode(dir->i_sb, mode, dev);
+	int error = -ENOSPC;
+
+	if (inode) {
+		d_instantiate(dentry, inode);
+		dget(dentry);		/* Extra count - pin the dentry in core */
+		error = 0;
+	}
+	return error;
+}
+
+static int hwgfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+{
+	return hwgfs_mknod(dir, dentry, mode | S_IFDIR, 0);
+}
+
+static int hwgfs_create(struct inode *dir, struct dentry *dentry, int mode)
+{
+	return hwgfs_mknod(dir, dentry, mode | S_IFREG, 0);
+}
+
+/*
+ * Link a file..
+ */
+static int hwgfs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry)
+{
+	struct inode *inode = old_dentry->d_inode;
+
+	if (S_ISDIR(inode->i_mode))
+		return -EPERM;
+
+	inode->i_nlink++;
+	atomic_inc(&inode->i_count);	/* New dentry reference */
+	dget(dentry);		/* Extra pinning count for the created dentry */
+	d_instantiate(dentry, inode);
+	return 0;
+}
+
+static inline int hwgfs_positive(struct dentry *dentry)
+{
+	return dentry->d_inode && !d_unhashed(dentry);
+}
+
+/*
+ * Check that a directory is empty (this works
+ * for regular files too, they'll just always be
+ * considered empty..).
+ *
+ * Note that an empty directory can still have
+ * children, they just all have to be negative..
+ */
+static int hwgfs_empty(struct dentry *dentry)
+{
+	struct list_head *list;
+
+	spin_lock(&dcache_lock);
+	list = dentry->d_subdirs.next;
+
+	while (list != &dentry->d_subdirs) {
+		struct dentry *de = list_entry(list, struct dentry, d_child);
+
+		if (hwgfs_positive(de)) {
+			spin_unlock(&dcache_lock);
+			return 0;
+		}
+		list = list->next;
+	}
+	spin_unlock(&dcache_lock);
+	return 1;
+}
+
+/*
+ * This works for both directories and regular files.
+ * (non-directories will always have empty subdirs)
+ */
+static int hwgfs_unlink(struct inode * dir, struct dentry *dentry)
+{
+	int retval = -ENOTEMPTY;
+
+	if (hwgfs_empty(dentry)) {
+		struct inode *inode = dentry->d_inode;
+
+		inode->i_nlink--;
+		dput(dentry);			/* Undo the count from "create" - this does all the work */
+		retval = 0;
+	}
+	return retval;
+}
+
+#define hwgfs_rmdir hwgfs_unlink
+
+/*
+ * The VFS layer already does all the dentry stuff for rename,
+ * we just have to decrement the usage count for the target if
+ * it exists so that the VFS layer correctly free's it when it
+ * gets overwritten.
+ */
+static int hwgfs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
+{
+	int error = -ENOTEMPTY;
+
+	if (hwgfs_empty(new_dentry)) {
+		struct inode *inode = new_dentry->d_inode;
+		if (inode) {
+			inode->i_nlink--;
+			dput(new_dentry);
+		}
+		error = 0;
+	}
+	return error;
+}
+
+static int hwgfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
+{
+	int error;
+
+	error = hwgfs_mknod(dir, dentry, S_IFLNK | S_IRWXUGO, 0);
+	if (!error) {
+		int l = strlen(symname)+1;
+		struct inode *inode = dentry->d_inode;
+		error = block_symlink(inode, symname, l);
+	}
+	return error;
+}
+
+static int hwgfs_sync_file(struct file * file, struct dentry *dentry, int datasync)
+{
+	return 0;
+}
+
+static struct address_space_operations hwgfs_aops = {
+	.readpage	= hwgfs_readpage,
+	.writepage	= fail_writepage,
+	.prepare_write	= hwgfs_prepare_write,
+	.commit_write	= hwgfs_commit_write
+};
+
+static struct file_operations hwgfs_file_operations = {
+	.read		= generic_file_read,
+	.write		= generic_file_write,
+	.mmap		= generic_file_mmap,
+	.fsync		= hwgfs_sync_file,
+};
+
+static struct inode_operations hwgfs_dir_inode_operations = {
+	.create		= hwgfs_create,
+	.lookup		= hwgfs_lookup,
+	.link		= hwgfs_link,
+	.unlink		= hwgfs_unlink,
+	.symlink	= hwgfs_symlink,
+	.mkdir		= hwgfs_mkdir,
+	.rmdir		= hwgfs_rmdir,
+	.mknod		= hwgfs_mknod,
+	.rename		= hwgfs_rename,
+};
+
+static struct super_operations hwgfs_ops = {
+	.statfs		= hwgfs_statfs,
+	.put_inode	= force_delete,
+};
+
+static struct super_block *hwgfs_read_super(struct super_block * sb, void * data, int silent)
+{
+	struct inode * inode;
+	struct dentry * root;
+
+	sb->s_blocksize = PAGE_CACHE_SIZE;
+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+	sb->s_magic = HWGFS_MAGIC;
+	sb->s_op = &hwgfs_ops;
+	inode = hwgfs_get_inode(sb, S_IFDIR | 0755, 0);
+	if (!inode)
+		return NULL;
+
+	root = d_alloc_root(inode);
+	if (!root) {
+		iput(inode);
+		return NULL;
+	}
+	sb->s_root = root;
+	return sb;
+}
+
+static struct file_system_type hwgfs_fs_type = {
+	.owner			= THIS_MODULE,
+	.name			= "hwgfs",
+	.read_super		= hwgfs_read_super,
+	.fs_flags		= FS_SINGLE|FS_LITTER,
+};
+
+struct vfsmount *hwgfs_vfsmount;
+
+int __init init_hwgfs_fs(void)
+{
+	int error;
+
+	if (!ia64_platform_is("sn2"))
+		return -ENODEV;
+
+	error = register_filesystem(&hwgfs_fs_type);
+	if (error)
+		return error;
+
+	hwgfs_vfsmount = kern_mount(&hwgfs_fs_type);
+	if (IS_ERR(hwgfs_vfsmount))
+		goto fail;
+	return 0;
+
+fail:
+	unregister_filesystem(&hwgfs_fs_type);
+	return PTR_ERR(hwgfs_vfsmount);
+}
+
+static void __exit exit_hwgfs_fs(void)
+{
+	unregister_filesystem(&hwgfs_fs_type);
+}
+
+MODULE_LICENSE("GPL");
+
+module_init(init_hwgfs_fs)
+module_exit(exit_hwgfs_fs)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/ifconfig_bus.c linux-2.4.22-pre10/arch/ia64/sn/io/ifconfig_bus.c
--- linux-2.4.21/arch/ia64/sn/io/ifconfig_bus.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/ifconfig_bus.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,345 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- *  ifconfig_bus - SGI's Persistent PCI Bus Numbering.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/pci.h>
-
-#include <asm/sn/sgi.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm//sn/sn_sal.h>
-#include <asm/sn/addrs.h>
-
-#define SGI_IFCONFIG_BUS "SGI-PERSISTENT PCI BUS NUMBERING"
-#define SGI_IFCONFIG_BUS_VERSION "1.0"
-
-/*
- * Some Global definitions.
- */
-devfs_handle_t ioconfig_bus_handle = NULL;
-unsigned long ioconfig_bus_debug = 0;
-
-#define IFCONFIG_BUS_DEBUG 1
-#ifdef IFCONFIG_BUS_DEBUG
-#define DBG(x...)	printk(x)
-#else
-#define DBG(x...)
-#endif
-
-u64 ioconfig_file = 0;
-u64 ioconfig_file_size = 0;
-
-
-/*
- * PCI Bus Name for PCI
- * 		 module/001c02/Ibrick/xtalk/14/pci - only 1 bus per widget
- *
- * PCI Bus Name for PCI-X
- *		 module/001c02/Ibrick/xtalk/14/pci-x/0 - PCI bus 0 on Widget 14
- *		 module/001c02/Ibrick/xtalk/14/pci-x/1 - PCI bus 1 on Widget 14
- */
-
-struct	pcipath_to_busnum{
-	unsigned int  num;			/* persistent bus number */
-	unsigned int  len;			/* pci path length */
-	unsigned char	path[120];		/* pci path name */
-};
-
-struct  pcipath_to_busnum *ioconfig_bus_table;
-u64 ioconfig_bus_table_size = 0;
-
-
-struct pcipath_to_busnum pcibus_names[256];
-
-/*
- * highest_pcibus_num : The highest PCI bus number allocated.  Use for next 
- *			PCI Bus Number to be assigned.
- * pcibus_names_index : The starting entry of any new configuration.  It also 
- *			tracks the number of old config in the table.
- * current_index : Next free index in the table for new config.
- *		   current_index - pcibus_names_index = number new config.
- */
-
-int	highest_pcibus_num = 0;
-int	pcibus_names_index = 0; /* Start of new config */
-int	current_index = 0; /* Next entry for new config */
-
-/*
- * ioconfig_get_busnum():
- *	ioconfig_get_busnum() returns the bus number given a pci path name.
- *	If the pci path name exist in the persistent naming table, the
- *	corresponding bun number is returned.  If the pci path name does not
- *	exist, the next bus number is assigned to that path, added to the
- *	persistent naming table and the new bus num returned.
- */
-void
-ioconfig_get_busnum(char *pci_path, int *bus_num)
-{
-	struct	pcipath_to_busnum *temp;
-	int index;
-
-	*bus_num = -1;
-	temp = ioconfig_bus_table;
-	for (index = 0; index < current_index; ioconfig_bus_table++, index++) {
-		if ( (strncmp(pci_path, ioconfig_bus_table->path, strlen(pci_path) == 0)) ){
-			*bus_num = ioconfig_bus_table->num;
-			return;
-		}
-	}
-
-	/*
-	 * This is a new path and it is not in the config table.
-	 * Add it to the end.
-	 */
-	*bus_num = highest_pcibus_num;
-	highest_pcibus_num++;
-	ioconfig_bus_table->num = *bus_num;
-	strcpy((char *)&(ioconfig_bus_table->path), pci_path);
-	ioconfig_bus_table->len = strlen(pci_path);
-	current_index++;
-
-}
-
-void
-dump_ioconfig_table(struct pcipath_to_busnum *ioconfig_bus_table)
-{
-
-	int index = 0;
-	struct pcipath_to_busnum *temp;
-
-	temp = ioconfig_bus_table;
-	while (index < pcibus_names_index) {
-		printk("Bus Number %d PCI path %s\n", temp->num, temp->path);
-		temp++;
-		index++;
-	}
-		
-}
-/*
- * nextline
- *	This routine returns the nextline in the buffer.
- */
-int nextline(char *buffer, char **next, char *line)
-{
-
-	char *temp;
-
-	if (buffer[0] == 0x0) {
-		return(0);
-	}
-
-	temp = buffer;
-	while (*temp != 0) {
-		*line = *temp;
-		if (*temp != '\n'){
-			*line = *temp;
-			temp++; line++;
-		} else
-			break;
-	}
-
-	if (*temp == 0)
-		*next = temp;
-	else
-		*next = ++temp;
-
-	return(1);
-}
-
-/*
- * build_pcibus_name
- *	This routine parses the ioconfig contents read into
- *	memory by ioconfig command in EFI and builds the
- *	persistent pci bus naming table.
- */
-void
-build_pcibus_name(char *file_contents, struct pcipath_to_busnum *table)
-{
-	/*
-	 * Read the whole file into memory.
-	 */
-	int busnum;
-	int rc;
-	char *name;
-	char *temp;
-	char *next;
-	char *current;
-	char *line;
-	struct pcipath_to_busnum *pcibus;
-
-	line = kmalloc(256, GFP_KERNEL);
-	memset(line, 0,256);
-	name = kmalloc(125, GFP_KERNEL);
-	memset(name, 0, 125);
-	pcibus = table;
-	current = file_contents;
-	while (nextline(current, &next, line)){
-printk("current 0x%lx next 0x%lx\n", current, next);
-		temp = line;
-		/*
-		 * Skip all leading Blank lines ..
-		 */
-		while (isspace(*temp))
-			if (*temp != '\n')
-				temp++;
-			else
-				break;
-
-		if (*temp == '\n') {
-			current = next;
-			memset(line, 0, 256);
-			continue;
-		}
- 
-		/*
-		 * Skip comment lines
-		 */
-		if (*temp == '#') {
-			current = next;
-			memset(line, 0, 256);
-			continue;
-		}
-
-		/*
-		 * Get the next free entry in the table.
-		 */
-		rc = sscanf(temp, "%d %s", &busnum, name);
-		pcibus->num = busnum;
-		pcibus->len = strlen(name);
-		strcpy(&pcibus->path[0], name);
-		DBG("pci number = %d pci path = %s\n", pcibus->num, pcibus->path);
-		if (busnum > highest_pcibus_num)
-			highest_pcibus_num = busnum;
-		else 
-			highest_pcibus_num = busnum; 
- 
-		pcibus_names_index++;
-		pcibus++;
-		current = next;
-		memset(line, 0, 256);
-	}
-
-	DBG("highest_pcibus_num %d pcibus_names_index %d\n", highest_pcibus_num, pcibus_names_index);
-
-	current_index = pcibus_names_index;
-	kfree(line);
-	kfree(name);
-
-	return;
-}
-
-void
-ioconfig_bus_init(void)
-{
-
-	struct ia64_sal_retval ret_stuff;
-
-	DBG("ioconfig_bus_init called.\n");
-
-	/*
-	 * Make SAL call to get the address of the bus configuration table.
-	 */
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
-	SAL_CALL(ret_stuff, SN_SAL_BUS_CONFIG, 0, get_nasid(), 0, 0, 0, 0, 0);
-	if (ret_stuff.status != 0) {
-		DBG("ifconfig_bus_init: No Address given\n");
-	}
-
-	ioconfig_file = ret_stuff.v0;
-	ioconfig_file_size = ret_stuff.v1;
-	DBG("ioconfig_bus_init: ioconfig_file %p %d\n", 
-		(void *)ioconfig_file, (int)ioconfig_file_size);
-
-	/*
-	 * Convert the address to a Cache Address.
-	 */
-	ioconfig_file = (CACHEABLE_MEM_SPACE | 
-		(ioconfig_file & TO_PHYS_MASK));
-
-	ioconfig_bus_table = kmalloc( 512*sizeof(struct pcipath_to_busnum), 
-				GFP_KERNEL );
-
-	DBG("ioconfig_bus_init: Kernel virtual ioconfig_file %p ioconfig_bus_table %p\n", 
-		(void *)ioconfig_file, (void *)ioconfig_bus_table);
-
-	(void) build_pcibus_name((char *)ioconfig_file, ioconfig_bus_table);
-
-	(void) dump_ioconfig_table(ioconfig_bus_table);
-
-}
-
-/*
- * ioconfig_bus_open - Opens the special device node "/dev/hw/.ioconfig_bus".
- */
-static int ioconfig_bus_open(struct inode * inode, struct file * filp)
-{
-	if (ioconfig_bus_debug) {
-        	printk("ioconfig_bus_open called.\n");
-	}
-
-        return(0);
-
-}
-
-/*
- * ioconfig_bus_close - Closes the special device node "/dev/hw/.ioconfig_bus".
- */
-static int ioconfig_bus_close(struct inode * inode, struct file * filp)
-{
-
-	if (ioconfig_bus_debug) {
-        	printk("ioconfig_bus_close called.\n");
-	}
-
-        return(0);
-}
-
-struct file_operations ioconfig_bus_fops = {
-	/* ioctl:ioconfig_bus_ioctl, ioctl */
-	open:ioconfig_bus_open,		/* open */
-	release:ioconfig_bus_close	/* release */
-};
-
-
-/*
- * init_ifconfig_net() - Boot time initialization.  Ensure that it is called 
- *	after devfs has been initialized.
- *
- */
-int init_ioconfig_bus(void)
-{
-	ioconfig_bus_handle = NULL;
-	ioconfig_bus_handle = hwgraph_register(hwgraph_root, ".ioconfig_bus",
-			0, DEVFS_FL_AUTO_DEVNUM,
-			0, 0,
-			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-			&ioconfig_bus_fops, NULL);
-
-	if (ioconfig_bus_handle == NULL) {
-		panic("Unable to create SGI PERSISTENT BUS NUMBERING Driver.\n");
-	}
-
-	return(0);
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/ifconfig_net.c linux-2.4.22-pre10/arch/ia64/sn/io/ifconfig_net.c
--- linux-2.4.21/arch/ia64/sn/io/ifconfig_net.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/ifconfig_net.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,298 +0,0 @@
-/* $Id: ifconfig_net.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- *  ifconfig_net - SGI's Persistent Network Device names.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <asm/sn/sgi.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/ifconfig_net.h>
-
-#define SGI_IFCONFIG_NET "SGI-PERSISTENT NETWORK DEVICE NAME DRIVER"
-#define SGI_IFCONFIG_NET_VERSION "1.0"
-
-/*
- * Some Global definitions.
- */
-devfs_handle_t ifconfig_net_handle = NULL;
-unsigned long ifconfig_net_debug = 0;
-
-/*
- * ifconfig_net_open - Opens the special device node "/devhw/.ifconfig_net".
- */
-static int ifconfig_net_open(struct inode * inode, struct file * filp)
-{
-	if (ifconfig_net_debug) {
-        	printk("ifconfig_net_open called.\n");
-	}
-
-        return(0);
-
-}
-
-/*
- * ifconfig_net_close - Closes the special device node "/devhw/.ifconfig_net".
- */
-static int ifconfig_net_close(struct inode * inode, struct file * filp)
-{
-
-	if (ifconfig_net_debug) {
-        	printk("ifconfig_net_close called.\n");
-	}
-
-        return(0);
-}
-
-/*
- * assign_ifname - Assign the next available interface name from the persistent list.
- */
-void
-assign_ifname(struct net_device *dev,
-		  struct ifname_num *ifname_num)
-
-{
-
-	/*
-	 * Handle eth devices.
-	 */
-        if ( (memcmp(dev->name, "eth", 3) == 0) ) {
-		if (ifname_num->next_eth != -1) {
-			/*
-			 * Assign it the next available eth interface number. 
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "eth%d", (int)ifname_num->next_eth);
-			ifname_num->next_eth++;
-		} 
-
-                return;
-        }
-
-	/*
-	 * Handle fddi devices.
-	 */
-	if ( (memcmp(dev->name, "fddi", 4) == 0) ) {
-		if (ifname_num->next_fddi != -1) {
-			/*
-			 * Assign it the next available fddi interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "fddi%d", (int)ifname_num->next_fddi);
-			ifname_num->next_fddi++;
-		}
-
-		return;
-	}
-
-	/*
-	 * Handle hip devices.
-	 */
-	if ( (memcmp(dev->name, "hip", 3) == 0) ) {
-		if (ifname_num->next_hip != -1) {
-			/*
-			 * Assign it the next available hip interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "hip%d", (int)ifname_num->next_hip);
-			ifname_num->next_hip++;
-		}
-
-		return;
-	}
-
-	/*
-	 * Handle tr devices.
-	 */
-	if ( (memcmp(dev->name, "tr", 2) == 0) ) {
-		if (ifname_num->next_tr != -1) {
-			/*
-			 * Assign it the next available tr interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "tr%d", (int)ifname_num->next_tr);
-			ifname_num->next_tr++;
-		}
-
-		return;
-	}
-
-	/*
-	 * Handle fc devices.
-	 */
-	if ( (memcmp(dev->name, "fc", 2) == 0) ) {
-		if (ifname_num->next_fc != -1) {
-			/*
-			 * Assign it the next available fc interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "fc%d", (int)ifname_num->next_fc);
-			ifname_num->next_fc++;
-		}
-
-		return;
-	}
-}
-
-/*
- * find_persistent_ifname: Returns the entry that was seen in previous boot.
- */
-struct ifname_MAC *
-find_persistent_ifname(struct net_device *dev,
-	struct ifname_MAC *ifname_MAC)
-
-{
-
-	while (ifname_MAC->addr_len) {
-		if (memcmp(dev->dev_addr, ifname_MAC->dev_addr, dev->addr_len) == 0)
-			return(ifname_MAC);
-
-		ifname_MAC++;
-	}
-
-	return(NULL);
-}
-
-/*
- * ifconfig_net_ioctl: ifconfig_net driver ioctl interface.
- */
-static int ifconfig_net_ioctl(struct inode * inode, struct file * file,
-        unsigned int cmd, unsigned long arg)
-{
-
-	extern struct net_device *__dev_get_by_name(const char *);
-#ifdef CONFIG_NET
-	struct net_device *dev;
-	struct ifname_MAC *found;
-	char temp[64];
-#endif
-	struct ifname_MAC *ifname_MAC;
-	struct ifname_MAC *new_devices, *temp_new_devices;
-	struct ifname_num *ifname_num;
-	unsigned long size;
-
-
-	if (ifconfig_net_debug) {
-		printk("HCL: hcl_ioctl called.\n");
-	}
-
-	/*
-	 * Read in the header and see how big of a buffer we really need to 
-	 * allocate.
-	 */
-	ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num), 
-			GFP_KERNEL);
-	copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num));
-	size = ifname_num->size;
-	kfree(ifname_num);
-	ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL);
-	ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) );
-
-	copy_from_user( ifname_num, (char *) arg, size);
-	new_devices =  kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL);
-	temp_new_devices = new_devices;
-
-	memset(new_devices, 0, size - sizeof(struct ifname_num));
-
-#ifdef CONFIG_NET
-	/*
-	 * Go through the net device entries and make them persistent!
-	 */
-	for (dev = dev_base; dev != NULL; dev = dev->next) {
-		/*
-		 * Skip NULL entries or "lo"
-		 */
-		if ( (dev->addr_len == 0) || ( !strncmp(dev->name, "lo", strlen(dev->name))) ){
-			continue;
-		}
-
-		/*
-		 * See if we have a persistent interface name for this device.
-		 */
-		found = NULL;
-		found = find_persistent_ifname(dev, ifname_MAC);
-		if (found) {
-			strcpy(dev->name, found->name);
-		} else {
-			/* Never seen this before .. */
-			assign_ifname(dev, ifname_num);
-
-			/* 
-			 * Save the information for the next boot.
-			 */
- 			sprintf(temp,"%s %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
-				dev->dev_addr[0],  dev->dev_addr[1],  dev->dev_addr[2],
-				dev->dev_addr[3],  dev->dev_addr[4],  dev->dev_addr[5]);
-			strcpy(temp_new_devices->name, dev->name);
-			temp_new_devices->addr_len = dev->addr_len;
-			memcpy(temp_new_devices->dev_addr, dev->dev_addr, dev->addr_len);
-			temp_new_devices++;
-		}
-		
-	}
-#endif
-
-	/*
-	 * Copy back to the User Buffer area any new devices encountered.
-	 */
-	copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, 
-			size - sizeof(struct ifname_num));
-
-	return(0);
-
-}
-
-struct file_operations ifconfig_net_fops = {
-	ioctl:ifconfig_net_ioctl,	/* ioctl */
-	open:ifconfig_net_open,		/* open */
-	release:ifconfig_net_close	/* release */
-};
-
-
-/*
- * init_ifconfig_net() - Boot time initialization.  Ensure that it is called 
- *	after devfs has been initialized.
- *
- */
-#ifdef MODULE
-int init_module (void)
-#else
-int __init init_ifconfig_net(void)
-#endif
-{
-	ifconfig_net_handle = NULL;
-	ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net",
-			0, DEVFS_FL_AUTO_DEVNUM,
-			0, 0,
-			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-			&ifconfig_net_fops, NULL);
-
-	if (ifconfig_net_handle == NULL) {
-		panic("Unable to create SGI PERSISTENT NETWORK DEVICE Name Driver.\n");
-	}
-
-	return(0);
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/invent.c linux-2.4.22-pre10/arch/ia64/sn/io/invent.c
--- linux-2.4.21/arch/ia64/sn/io/invent.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/invent.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,224 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * Hardware Inventory
- *
- * See sys/sn/invent.h for an explanation of the hardware inventory contents.
- *
- */
-#include <linux/types.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-
-void
-inventinit(void)
-{
-}
-
-/*
- * For initializing/updating an inventory entry.
- */
-void
-replace_in_inventory(
-	inventory_t *pinv, int class, int type,
-	int controller, int unit, int state)
-{
-	pinv->inv_class = class;
-	pinv->inv_type = type;
-	pinv->inv_controller = controller;
-	pinv->inv_unit = unit;
-	pinv->inv_state = state;
-}
-
-/*
- * Inventory addition 
- *
- * XXX NOTE: Currently must be called after dynamic memory allocator is
- * initialized.
- *
- */
-void
-add_to_inventory(int class, int type, int controller, int unit, int state)
-{
-	(void)device_inventory_add((devfs_handle_t)GRAPH_VERTEX_NONE, class, type, 
-					controller, unit, state);
-}
-
-
-/*
- * Inventory retrieval 
- *
- * These two routines are intended to prevent the caller from having to know
- * the internal structure of the inventory table.
- *
- * The caller of get_next_inventory is supposed to call start_scan_invent
- * before the irst call to get_next_inventory, and the caller is required
- * to call end_scan_invent after the last call to get_next_inventory.
- */
-inventory_t *
-get_next_inventory(invplace_t *place)
-{
-	inventory_t *pinv;
-	devfs_handle_t device = place->invplace_vhdl;
-	int rv;
-
-	while ((pinv = device_inventory_get_next(device, place)) == NULL) {
-		/*
-		 * We've exhausted inventory items on the last device.
-		 * Advance to next device.
-		 */
-		place->invplace_inv = NULL; /* Start from beginning invent on this device */
-		rv = hwgraph_vertex_get_next(&device, &place->invplace_vplace);
-		if (rv == LABELCL_SUCCESS) {
-			place->invplace_vhdl = device;
-		}
-		else {
-			place->invplace_vhdl = GRAPH_VERTEX_NONE;
-			return(NULL);
-		}
-	}
-
-	return(pinv);
-}
-
-/* ARGSUSED */
-int
-get_sizeof_inventory(int abi)
-{
-	return sizeof(inventory_t);
-}
-
-/* Must be called prior to first call to get_next_inventory */
-void
-start_scan_inventory(invplace_t *iplace)
-{
-	*iplace = INVPLACE_NONE;
-}
-
-/* Must be called after last call to get_next_inventory */
-void
-end_scan_inventory(invplace_t *iplace)
-{
-	devfs_handle_t vhdl = iplace->invplace_vhdl;
-	if (vhdl != GRAPH_VERTEX_NONE)
-		hwgraph_vertex_unref(vhdl);
-	*iplace = INVPLACE_NONE; /* paranoia */
-}
-
-/*
- * Hardware inventory scanner.
- *
- * Calls fun() for every entry in inventory list unless fun() returns something
- * other than 0.
- */
-int
-scaninvent(int (*fun)(inventory_t *, void *), void *arg)
-{
-	inventory_t *ie;
-	invplace_t iplace = { NULL,NULL, NULL };
-	int rc;
-
-	ie = 0;
-	rc = 0;
-	start_scan_inventory(&iplace);
-	while ((ie = (inventory_t *)get_next_inventory(&iplace))) {
-		rc = (*fun)(ie, arg);
-		if (rc)
-			break;
-	}
-	end_scan_inventory(&iplace);
-	return rc;
-}
-
-/*
- * Find a particular inventory object
- *
- * pinv can be a pointer to an inventory entry and the search will begin from
- * there, or it can be 0 in which case the search starts at the beginning.
- * A -1 for any of the other arguments is a wildcard (i.e. it always matches).
- */
-inventory_t *
-find_inventory(inventory_t *pinv, int class, int type, int controller,
-	       int unit, int state)
-{
-	invplace_t iplace =  { NULL,NULL, NULL };
-
-	start_scan_inventory(&iplace);
-	while ((pinv = (inventory_t *)get_next_inventory(&iplace)) != NULL) {
-		if (class != -1 && pinv->inv_class != class)
-			continue;
-		if (type != -1 && pinv->inv_type != type)
-			continue;
-
-		/* XXXX - perhaps the "state" entry should be ignored so an
-		 * an existing entry can be updated.  See vino_init() and
-		 * ml/IP22.c:add_ioboard() for an example.
-		 */
-		if (state != -1 && pinv->inv_state != state)
-			continue;
-		if (controller != -1
-		    && pinv->inv_controller != controller)
-			continue;
-		if (unit != -1 && pinv->inv_unit != unit)
-			continue;
-		break;
-	}
-	end_scan_inventory(&iplace);
-
-	return(pinv);
-}
-
-
-/*
-** Retrieve inventory data associated with a device.
-*/
-inventory_t *
-device_inventory_get_next(	devfs_handle_t device,
-				invplace_t *invplace)
-{
-	inventory_t *pinv;
-	int rv;
-
-	rv = hwgraph_inventory_get_next(device, invplace, &pinv);
-	if (rv == LABELCL_SUCCESS)
-		return(pinv);
-	else
-		return(NULL);
-}
-
-
-/*
-** Associate canonical inventory information with a device (and
-** add it to the general inventory).
-*/
-void
-device_inventory_add(	devfs_handle_t device,
-			int class, 
-			int type, 
-			major_t controller, 
-			minor_t unit, 
-			int state)
-{
-	hwgraph_inventory_add(device, class, type, controller, unit, state);
-}
-
-int
-device_controller_num_get(devfs_handle_t device)
-{
-	return (hwgraph_controller_num_get(device));
-}
-
-void
-device_controller_num_set(devfs_handle_t device, int contr_num)
-{
-	hwgraph_controller_num_set(device, contr_num);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/io.c linux-2.4.22-pre10/arch/ia64/sn/io/io.c
--- linux-2.4.21/arch/ia64/sn/io/io.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/io.c	2003-08-01 13:33:05.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/config.h>
@@ -29,17 +29,11 @@
 #include <asm/sn/sn_cpuid.h>
 
 extern xtalk_provider_t hub_provider;
-extern void hub_intr_init(devfs_handle_t hubv);
+extern void hub_intr_init(vertex_hdl_t hubv);
 
+static int force_fire_and_forget = 1;
+static int ignore_conveyor_override;
 
-/*
- * Perform any initializations needed to support hub-based I/O.
- * Called once during startup.
- */
-void
-hubio_init(void)
-{
-}
 
 /* 
  * Implementation of hub iobus operations.
@@ -58,8 +52,8 @@
 /*
  * Setup pio structures needed for a particular hub.
  */
-void
-hub_pio_init(devfs_handle_t hubv)
+static void
+hub_pio_init(vertex_hdl_t hubv)
 {
 	xwidgetnum_t widget;
 	hubinfo_t hubinfo;
@@ -114,7 +108,7 @@
  */
 /* ARGSUSED */
 hub_piomap_t
-hub_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
+hub_piomap_alloc(vertex_hdl_t dev,	/* set up mapping for this device */
 		device_desc_t dev_desc,	/* device descriptor */
 		iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
 		size_t byte_count,
@@ -123,7 +117,7 @@
 {
 	xwidget_info_t widget_info = xwidget_info_get(dev);
 	xwidgetnum_t widget = xwidget_info_id_get(widget_info);
-	devfs_handle_t hubv = xwidget_info_master_get(widget_info);
+	vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
 	hubinfo_t hubinfo;
 	hub_piomap_t bw_piomap;
 	int bigwin, free_bw_index;
@@ -288,7 +282,7 @@
 void
 hub_piomap_free(hub_piomap_t hub_piomap)
 {
-	devfs_handle_t hubv;
+	vertex_hdl_t hubv;
 	hubinfo_t hubinfo;
 	nasid_t nasid;
 	unsigned long s;
@@ -371,7 +365,7 @@
  */
 /* ARGSUSED */
 caddr_t
-hub_piotrans_addr(	devfs_handle_t dev,	/* translate to this device */
+hub_piotrans_addr(	vertex_hdl_t dev,	/* translate to this device */
 			device_desc_t dev_desc,	/* device descriptor */
 			iopaddr_t xtalk_addr,	/* Crosstalk address */
 			size_t byte_count,	/* map this many bytes */
@@ -379,7 +373,7 @@
 {
 	xwidget_info_t widget_info = xwidget_info_get(dev);
 	xwidgetnum_t widget = xwidget_info_id_get(widget_info);
-	devfs_handle_t hubv = xwidget_info_master_get(widget_info);
+	vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
 	hub_piomap_t hub_piomap;
 	hubinfo_t hubinfo;
 	caddr_t addr;
@@ -416,7 +410,7 @@
  */
 /* ARGSUSED */
 hub_dmamap_t
-hub_dmamap_alloc(	devfs_handle_t dev,	/* set up mappings for this device */
+hub_dmamap_alloc(	vertex_hdl_t dev,	/* set up mappings for this device */
 			device_desc_t dev_desc,	/* device descriptor */
 			size_t byte_count_max, 	/* max size of a mapping */
 			unsigned flags)		/* defined in dma.h */
@@ -424,7 +418,7 @@
 	hub_dmamap_t dmamap;
 	xwidget_info_t widget_info = xwidget_info_get(dev);
 	xwidgetnum_t widget = xwidget_info_id_get(widget_info);
-	devfs_handle_t hubv = xwidget_info_master_get(widget_info);
+	vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
 
 	dmamap = kmalloc(sizeof(struct hub_dmamap_s), GFP_ATOMIC);
 	dmamap->hdma_xtalk_info.xd_dev = dev;
@@ -460,7 +454,7 @@
 			paddr_t paddr,		/* map for this address */
 			size_t byte_count)	/* map this many bytes */
 {
-	devfs_handle_t vhdl;
+	vertex_hdl_t vhdl;
 
 	ASSERT(dmamap->hdma_flags & HUB_DMAMAP_IS_VALID);
 
@@ -479,12 +473,7 @@
 	}
 
 	/* There isn't actually any DMA mapping hardware on the hub. */
-#ifdef CONFIG_IA64_SGI_SN2
         return( (PHYS_TO_DMA(paddr)) );
-#else
-        /* no translation needed */
-        return(paddr);
-#endif
 }
 
 /*
@@ -498,7 +487,7 @@
 		alenlist_t palenlist,		/* map this area of memory */
 		unsigned flags)
 {
-	devfs_handle_t vhdl;
+	vertex_hdl_t vhdl;
 
 	ASSERT(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_VALID);
 
@@ -527,7 +516,7 @@
 void
 hub_dmamap_done(hub_dmamap_t hub_dmamap)	/* done with these mapping resources */
 {
-	devfs_handle_t vhdl;
+	vertex_hdl_t vhdl;
 
 	if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) {
 		hub_dmamap->hdma_flags &= ~HUB_DMAMAP_USED;
@@ -549,18 +538,13 @@
  */
 /* ARGSUSED */
 iopaddr_t
-hub_dmatrans_addr(	devfs_handle_t dev,	/* translate for this device */
+hub_dmatrans_addr(	vertex_hdl_t dev,	/* translate for this device */
 			device_desc_t dev_desc,	/* device descriptor */
 			paddr_t paddr,		/* system physical address */
 			size_t byte_count,	/* length */
 			unsigned flags)		/* defined in dma.h */
 {
-#ifdef CONFIG_IA64_SGI_SN2
 	return( (PHYS_TO_DMA(paddr)) );
-#else
-	/* no translation needed */
-	return(paddr);
-#endif
 }
 
 /*
@@ -570,7 +554,7 @@
  */
 /* ARGSUSED */
 alenlist_t
-hub_dmatrans_list(	devfs_handle_t dev,	/* translate for this device */
+hub_dmatrans_list(	vertex_hdl_t dev,	/* translate for this device */
 			device_desc_t dev_desc,	/* device descriptor */
 			alenlist_t palenlist,	/* system address/length list */
 			unsigned flags)		/* defined in dma.h */
@@ -589,7 +573,7 @@
 
 /*ARGSUSED*/
 void
-hub_dmaaddr_drain(	devfs_handle_t vhdl,
+hub_dmaaddr_drain(	vertex_hdl_t vhdl,
 			paddr_t addr,
 			size_t bytes)
 {
@@ -598,7 +582,7 @@
 
 /*ARGSUSED*/
 void
-hub_dmalist_drain(	devfs_handle_t vhdl,
+hub_dmalist_drain(	vertex_hdl_t vhdl,
 			alenlist_t list)
 {
     /* XXX- flush caches, if cache coherency WAR is needed */
@@ -612,10 +596,8 @@
  * Perform initializations that allow this hub to start crosstalk support.
  */
 void
-hub_provider_startup(devfs_handle_t hubv)
+hub_provider_startup(vertex_hdl_t hubv)
 {
-	extern void hub_pio_init(devfs_handle_t hubv);
-
 	hub_pio_init(hubv);
 	hub_intr_init(hubv);
 }
@@ -624,14 +606,14 @@
  * Shutdown crosstalk support from a hub.
  */
 void
-hub_provider_shutdown(devfs_handle_t hub)
+hub_provider_shutdown(vertex_hdl_t hub)
 {
 	/* TBD */
 	xtalk_provider_unregister(hub);
 }
 
 /*
- * Check that an address is in teh real small window widget 0 space
+ * Check that an address is in the real small window widget 0 space
  * or else in the big window we're using to emulate small window 0
  * in the kernel.
  */
@@ -666,49 +648,9 @@
 
 
 /*
- * Determine whether two PCI addresses actually refer to the same device.
- * This only works if both addresses are in small windows.  It's used to
- * determine whether prom addresses refer to particular PCI devices.
- */
-/*	
- * XXX - This won't work as written if we ever have more than two nodes
- * on a crossbow.  In that case, we'll need an array or partners.
- */
-int
-hub_check_pci_equiv(void *addra, void *addrb)
-{
-	nasid_t nasida, nasidb;
-
-	/*
-	 * This is for a permanent workaround that causes us to use a
-	 * big window in place of small window 0.
-	 */
-	if (!hub_check_window_equiv(addra, addrb))
-		return 0;
-
-	/* If the offsets aren't the same, forget it. */
-	if (SWIN_WIDGETADDR((__psunsigned_t)addra) !=
-	    (SWIN_WIDGETADDR((__psunsigned_t)addrb)))
-		return 0;
-
-	/* Now, check the nasids */
-	nasida = NASID_GET(addra);
-	nasidb = NASID_GET(addrb);
-
-	ASSERT(NASID_TO_COMPACT_NODEID(nasida) != INVALID_NASID);
-	ASSERT(NASID_TO_COMPACT_NODEID(nasidb) != INVALID_NASID);
-
-	/*
-	 * Either the NASIDs must be the same or they must be crossbow
-	 * partners (on the same crossbow).
-	 */
-	return (check_nasid_equiv(nasida, nasidb));
-}
-
-/*
  * hub_setup_prb(nasid, prbnum, credits, conveyor)
  *
- * 	Put a PRB into fire-and-forget mode if conveyor isn't set.  Otehrwise,
+ * 	Put a PRB into fire-and-forget mode if conveyor isn't set.  Otherwise,
  * 	put it into conveyor belt mode with the specified number of credits.
  */
 void
@@ -716,8 +658,6 @@
 {
 	iprb_t prb;
 	int prb_offset;
-	extern int force_fire_and_forget;
-	extern volatile int ignore_conveyor_override;
 
 	if (force_fire_and_forget && !ignore_conveyor_override)
 	    if (conveyor == HUB_PIO_CONVEYOR)
@@ -776,13 +716,8 @@
 	int direct_connect;
 	hubii_wcr_t ii_wcr;
 	int prbnum;
-	int cons_lock = 0;
 
 	ASSERT(NASID_TO_COMPACT_NODEID(nasid) != INVALID_CNODEID);
-	if (nasid == get_console_nasid()) {
-		PUTBUF_LOCK(s);	
-		cons_lock = 1;
-	}
 
 	ii_iowa = REMOTE_HUB_L(nasid, IIO_OUTWIDGET_ACCESS);
 	REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, 0);
@@ -812,9 +747,6 @@
 	}
 
 	REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, ii_iowa);
-
-	if (cons_lock)
-	    PUTBUF_UNLOCK(s);
 }
 /* Interface to allow special drivers to set hub specific
  * device flags.
@@ -842,90 +774,6 @@
 
 	return 1;
 }
-/* Interface to allow special drivers to set hub specific
- * device flags.
- * Return 0 on failure , 1 on success
- */
-int
-hub_device_flags_set(devfs_handle_t	widget_vhdl,
-		     hub_widget_flags_t	flags)
-{
-	xwidget_info_t		widget_info = xwidget_info_get(widget_vhdl);
-	xwidgetnum_t		widget_num  = xwidget_info_id_get(widget_info);
-	devfs_handle_t		hub_vhdl    = xwidget_info_master_get(widget_info);
-	hubinfo_t		hub_info = 0;
-	nasid_t			nasid;
-	unsigned long		s;
-	int			rv;
-
-	/* Use the nasid from the hub info hanging off the hub vertex
-	 * and widget number from the widget vertex
-	 */
-	hubinfo_get(hub_vhdl, &hub_info);
-	/* Being over cautious by grabbing a lock */
-	s 	= mutex_spinlock(&hub_info->h_bwlock);
-	nasid 	= hub_info->h_nasid;
-	rv 	= hub_widget_flags_set(nasid,widget_num,flags);
-	mutex_spinunlock(&hub_info->h_bwlock, s);
-
-	return rv;
-}
-
-/*
- * hub_device_inquiry
- *	Find out the xtalk widget related information stored in this 
- *	hub's II.
- */
-void
-hub_device_inquiry(devfs_handle_t	xbus_vhdl, xwidgetnum_t widget)
-{
-	devfs_handle_t	xconn, hub_vhdl;
-	char		widget_name[8];
-	hubreg_t	ii_iidem,ii_iiwa, ii_iowa;
-	hubinfo_t	hubinfo;
-	nasid_t		nasid;
-	int		d;
-
-	sprintf(widget_name, "%d", widget);
-	if (hwgraph_traverse(xbus_vhdl, widget_name, &xconn)
-	    != GRAPH_SUCCESS)
-		return;
-
-	hub_vhdl = device_master_get(xconn);
-	if (hub_vhdl == GRAPH_VERTEX_NONE)
-		return;
-
-	hubinfo_get(hub_vhdl, &hubinfo);
-	if (!hubinfo)
-		return;
-	
-	nasid = hubinfo->h_nasid;
-
-	ii_iidem	= REMOTE_HUB_L(nasid, IIO_IIDEM);
-	ii_iiwa 	= REMOTE_HUB_L(nasid, IIO_IIWA);
-	ii_iowa 	= REMOTE_HUB_L(nasid, IIO_IOWA);
-
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	printk("Inquiry Info for %v\n", xconn);
-#else
-	printk("Inquiry Info for %p\n", (void *)xconn);
-#endif
-
-	printk("\tDevices shutdown [ ");
-
-	for (d = 0 ; d <= 7 ; d++)
-		if (!(ii_iidem & (IIO_IIDEM_WIDGETDEV_MASK(widget,d))))
-			printk(" %d", d);
-
-	printk("]\n");
-
-	printk("\tInbound access ? %s\n",
-		ii_iiwa & IIO_IIWA_WIDGET(widget) ? "yes" : "no");
-
-	printk("\tOutbound access ? %s\n",
-		ii_iowa & IIO_IOWA_WIDGET(widget) ? "yes" : "no");
-
-}
 
 /*
  * A pointer to this structure hangs off of every hub hwgraph vertex.
@@ -955,8 +803,6 @@
 	(xtalk_intr_free_f *)		hub_intr_free,
 	(xtalk_intr_connect_f *)	hub_intr_connect,
 	(xtalk_intr_disconnect_f *)	hub_intr_disconnect,
-	(xtalk_intr_cpu_get_f *)	hub_intr_cpu_get,
-
 	(xtalk_provider_startup_f *)	hub_provider_startup,
 	(xtalk_provider_shutdown_f *)	hub_provider_shutdown,
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/klconflib.c linux-2.4.22-pre10/arch/ia64/sn/io/klconflib.c
--- linux-2.4.21/arch/ia64/sn/io/klconflib.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/klconflib.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1046 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/ctype.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/module.h>
-#include <asm/sn/router.h>
-#include <asm/sn/xtalk/xbow.h>
-
-#define printf printk
-int hasmetarouter;
-
-#define LDEBUG 0
-#define NIC_UNKNOWN ((nic_t) -1)
-
-#undef DEBUG_KLGRAPH
-#ifdef DEBUG_KLGRAPH
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_KLGRAPH */
-
-static void sort_nic_names(lboard_t *) ;
-
-u64 klgraph_addr[MAX_COMPACT_NODES];
-int module_number = 0;
-
-lboard_t *
-find_lboard(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (start->brd_type == brd_type)
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_class(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-klinfo_t *
-find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
-{
-	int index, j;
-
-	if (kli == (klinfo_t *)NULL) {
-		index = 0;
-	} else {
-		for (j = 0; j < KLCF_NUM_COMPS(brd); j++) {
-			if (kli == KLCF_COMP(brd, j))
-				break;
-		}
-		index = j;
-		if (index == KLCF_NUM_COMPS(brd)) {
-			DBG("find_component: Bad pointer: 0x%p\n", kli);
-			return (klinfo_t *)NULL;
-		}
-		index++;	/* next component */
-	}
-	
-	for (; index < KLCF_NUM_COMPS(brd); index++) {		
-		kli = KLCF_COMP(brd, index);
-		DBG("find_component: brd %p kli %p  request type = 0x%x kli type 0x%x\n", brd, kli, kli->struct_type, KLCF_COMP_TYPE(kli));
-		if (KLCF_COMP_TYPE(kli) == struct_type)
-			return kli;
-	}
-
-	/* Didn't find it. */
-	return (klinfo_t *)NULL;
-}
-
-klinfo_t *
-find_first_component(lboard_t *brd, unsigned char struct_type)
-{
-	return find_component(brd, (klinfo_t *)NULL, struct_type);
-}
-
-lboard_t *
-find_lboard_modslot(lboard_t *start, moduleid_t mod, slotid_t slot)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (MODULE_MATCH(start->brd_module, mod) &&
-		    (start->brd_slot == slot))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_module(lboard_t *start, moduleid_t mod)
-{
-        /* Search all boards stored on this node. */
-        while (start) {
-                if (MODULE_MATCH(start->brd_module, mod))
-                        return start;
-                start = KLCF_NEXT(start);
-        }
-
-        /* Didn't find it. */
-        return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_module_class(lboard_t *start, moduleid_t mod,
-                                                unsigned char brd_type)
-{
-	while (start) {
-
-		DBG("find_lboard_module_class: lboard 0x%p, start->brd_module 0x%x, mod 0x%x, start->brd_type 0x%x, brd_type 0x%x\n", start, start->brd_module, mod, start->brd_type, brd_type);
-
-		if (MODULE_MATCH(start->brd_module, mod) &&
-			(KLCLASS(start->brd_type) == KLCLASS(brd_type)))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-
-/*
- * Convert a NIC name to a name for use in the hardware graph.
- */
-void
-nic_name_convert(char *old_name, char *new_name)
-{
-        int i;
-        char c;
-        char *compare_ptr;
-
-	if ((old_name[0] == '\0') || (old_name[1] == '\0')) {
-                strcpy(new_name, EDGE_LBL_XWIDGET);
-        } else {
-                for (i = 0; i < strlen(old_name); i++) {
-                        c = old_name[i];
-
-                        if (isalpha(c))
-                                new_name[i] = tolower(c);
-                        else if (isdigit(c))
-                                new_name[i] = c;
-                        else
-                                new_name[i] = '_';
-                }
-                new_name[i] = '\0';
-        }
-
-        /* XXX -
-         * Since a bunch of boards made it out with weird names like
-         * IO6-fibbbed and IO6P2, we need to look for IO6 in a name and
-         * replace it with "baseio" to avoid confusion in the field.
-	 * We also have to make sure we don't report media_io instead of
-	 * baseio.
-         */
-
-        /* Skip underscores at the beginning of the name */
-        for (compare_ptr = new_name; (*compare_ptr) == '_'; compare_ptr++)
-                ;
-
-	/*
-	 * Check for some names we need to replace.  Early boards
-	 * had junk following the name so check only the first
-	 * characters.
-	 */
-        if (!strncmp(new_name, "io6", 3) || 
-            !strncmp(new_name, "mio", 3) || 
-	    !strncmp(new_name, "media_io", 8))
-		strcpy(new_name, "baseio");
-	else if (!strncmp(new_name, "divo", 4))
-		strcpy(new_name, "divo") ;
-
-}
-
-/* Check if the given board corresponds to the global 
- * master io6
- */
-int
-is_master_baseio(nasid_t nasid,moduleid_t module,slotid_t slot)
-{
-	lboard_t	*board;
-
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-/* If this works then look for callers of is_master_baseio()
- * (e.g. iograph.c) and let them pass in a slot if they want
- */
-	board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), module);
-#else
-	board = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid), module, slot);
-#endif
-
-#ifndef _STANDALONE
-	{
-		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
-
-		if (!board && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-			board = find_lboard_module((lboard_t *)
-				    KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				    module);
-#else
-			board = find_lboard_modslot((lboard_t *)
-				    KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				    module, slot);
-#endif
-	}
-#endif
-	if (!board)
-		return(0);
-	return(board->brd_flags & GLOBAL_MASTER_IO6);
-}
-/*
- * Find the lboard structure and get the board name.
- * If we can't find the structure or it's too low a revision,
- * use default name.
- */
-lboard_t *
-get_board_name(nasid_t nasid, moduleid_t mod, slotid_t slot, char *name)
-{
-	lboard_t *brd;
-
-	brd = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid),
-				  mod, slot);
-
-#ifndef _STANDALONE
-	{
-		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
-
-		if (!brd && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-			brd = find_lboard_modslot((lboard_t *)
-				KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				mod, slot);
-	}
-#endif
-
-	if (!brd || (brd->brd_sversion < 2)) {
-		strcpy(name, EDGE_LBL_XWIDGET);
-	} else {
-		nic_name_convert(brd->brd_name, name);
-	}
-
-	/*
- 	 * PV # 540860
-	 * If the name is not 'baseio' 
-	 * get the lowest of all the names in the nic string.
-	 * This is needed for boards like divo, which can have
-	 * a bunch of daughter cards, but would like to be called
-	 * divo. We could do this for baseio 
- 	 * but it has some special case names that we would not
- 	 * like to disturb at this point.
-	 */
-
-	/* gfx boards don't need any of this name scrambling */
-	if (brd && (KLCLASS(brd->brd_type) == KLCLASS_GFX)) {
-		return(brd);
-	}
-
-	if (!(!strcmp(name, "baseio") )) {
-		if (brd) {
-			sort_nic_names(brd) ;
-			/* Convert to small case, '-' to '_' etc */
-			nic_name_convert(brd->brd_name, name) ;
-		}
-	}
-
-	return(brd);
-}
-
-/*
- * get_actual_nasid
- *
- *	Completely disabled brds have their klconfig on 
- *	some other nasid as they have no memory. But their
- *	actual nasid is hidden in the klconfig. Use this
- *	routine to get it. Works for normal boards too.
- */
-nasid_t
-get_actual_nasid(lboard_t *brd)
-{
-	klhub_t	*hub ;
-
-	if (!brd)
-		return INVALID_NASID ;
-
-	/* find out if we are a completely disabled brd. */
-
-        hub  = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-	if (!hub)
-                return INVALID_NASID ;
-	if (!(hub->hub_info.flags & KLINFO_ENABLE))	/* disabled node brd */
-		return hub->hub_info.physid ;
-	else
-		return brd->brd_nasid ;
-}
-
-int
-xbow_port_io_enabled(nasid_t nasid, int link)
-{
-	lboard_t *brd;
-	klxbow_t *xbow_p;
-
-	/*
-	 * look for boards that might contain an xbow or xbridge
-	 */
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW);
-	if (brd == NULL) return 0;
-		
-	if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW))
-	    == NULL)
-	    return 0;
-
-	if (!XBOW_PORT_TYPE_IO(xbow_p, link) || !XBOW_PORT_IS_ENABLED(xbow_p, link))
-	    return 0;
-
-	DBG("xbow_port_io_enabled:  brd 0x%p xbow_p 0x%p \n", brd, xbow_p);
-
-	return 1;
-}
-
-void
-board_to_path(lboard_t *brd, char *path)
-{
-	moduleid_t modnum;
-	char *board_name;
-
-	ASSERT(brd);
-
-	switch (KLCLASS(brd->brd_type)) {
-
-		case KLCLASS_NODE:
-			board_name = EDGE_LBL_NODE;
-			break;
-		case KLCLASS_ROUTER:
-			if (brd->brd_type == KLTYPE_META_ROUTER) {
-				board_name = EDGE_LBL_META_ROUTER;
-				hasmetarouter++;
-			} else if (brd->brd_type == KLTYPE_REPEATER_ROUTER) {
-				board_name = EDGE_LBL_REPEATER_ROUTER;
-				hasmetarouter++;
-			} else
-				board_name = EDGE_LBL_ROUTER;
-			break;
-		case KLCLASS_MIDPLANE:
-			board_name = EDGE_LBL_MIDPLANE;
-			break;
-		case KLCLASS_IO:
-			board_name = EDGE_LBL_IO;
-			break;
-		case KLCLASS_IOBRICK:
-			if (brd->brd_type == KLTYPE_PBRICK)
-				board_name = EDGE_LBL_PBRICK;
-			else if (brd->brd_type == KLTYPE_IBRICK)
-				board_name = EDGE_LBL_IBRICK;
-			else if (brd->brd_type == KLTYPE_XBRICK)
-				board_name = EDGE_LBL_XBRICK;
-			else
-				board_name = EDGE_LBL_IOBRICK;
-			break;
-		default:
-			board_name = EDGE_LBL_UNKNOWN;
-	}
-			
-	modnum = brd->brd_module;
-
-	/* ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE); */
-if ((modnum == MODULE_UNKNOWN) || (modnum == INVALID_MODULE)) {
-	modnum = ++module_number;
-}
-#ifdef __ia64
-	{
-		char	buffer[16];
-		memset(buffer, 0, 16);
-		format_module_id(buffer, modnum, MODULE_FORMAT_BRIEF);
-		sprintf(path, EDGE_LBL_MODULE "/%s/%s", buffer, board_name);
-	}
-#else
-	sprintf(path, "%H/%s", modnum, board_name);
-#endif
-}
-
-/*
- * Get the module number for a NASID.
- */
-moduleid_t
-get_module_id(nasid_t nasid)
-{
-	lboard_t *brd;
-
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-
-	if (!brd)
-		return INVALID_MODULE;
-	else
-		return brd->brd_module;
-}
-
-
-#define MHZ	1000000
-
-
-/* Get the canonical hardware graph name for the given pci component
- * on the given io board.
- */
-void
-device_component_canonical_name_get(lboard_t 	*brd,
-				    klinfo_t 	*component,
-				    char 	*name)
-{
-	moduleid_t 	modnum;
-	slotid_t 	slot;
-	char 		board_name[20];
-
-	ASSERT(brd);
-
-	/* Get the module number of this board */
-	modnum = brd->brd_module;
-
-	/* Convert the [ CLASS | TYPE ] kind of slotid
-	 * into a string 
-	 */
-	slot = brd->brd_slot;
-	ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE);
-
-	/* Get the io board name  */
-	if (!brd || (brd->brd_sversion < 2)) {
-		strcpy(name, EDGE_LBL_XWIDGET);
-	} else {
-		nic_name_convert(brd->brd_name, board_name);
-	}
-
-	/* Give out the canonical  name of the pci device*/
-	sprintf(name, 
-		"/dev/hw/"EDGE_LBL_MODULE "/%x/"EDGE_LBL_SLOT"/%s/"
-		EDGE_LBL_PCI"/%d", 
-		modnum, board_name,KLCF_BRIDGE_W_ID(component));
-}
-
-/*
- * Get the serial number of the main  component of a board
- * Returns 0 if a valid serial number is found
- * 1 otherwise.
- * Assumptions: Nic manufacturing string  has the following format
- *			*Serial:<serial_number>;*
- */
-static int
-component_serial_number_get(lboard_t 		*board,
-			    klconf_off_t 	mfg_nic_offset,
-			    char		*serial_number,
-			    char		*key_pattern)
-{
-
-	char	*mfg_nic_string;
-	char	*serial_string,*str;
-	int	i;
-	char	*serial_pattern = "Serial:";
-
-	/* We have an error on a null mfg nic offset */
-	if (!mfg_nic_offset)
-		return(1);
-	/* Get the hub's manufacturing nic information
-	 * which is in the form of a pre-formatted string
-	 */
-	mfg_nic_string = 
-		(char *)NODE_OFFSET_TO_K0(NASID_GET(board),
-					  mfg_nic_offset);
-	/* There is no manufacturing nic info */
-	if (!mfg_nic_string)
-		return(1);
-
-	str = mfg_nic_string;
-	/* Look for the key pattern first (if it is  specified)
-	 * and then print the serial number corresponding to that.
-	 */
-	if (strcmp(key_pattern,"") && 
-	    !(str = strstr(mfg_nic_string,key_pattern)))
-		return(1);
-
-	/* There is no serial number info in the manufacturing
-	 * nic info
-	 */
-	if (!(serial_string = strstr(str,serial_pattern)))
-		return(1);
-
-	serial_string = serial_string + strlen(serial_pattern);
-	/*  Copy the serial number information from the klconfig */
-	i = 0;
-	while (serial_string[i] != ';') {
-		serial_number[i] = serial_string[i];
-		i++;
-	}
-	serial_number[i] = 0;
-	
-	return(0);
-}
-/*
- * Get the serial number of a board
- * Returns 0 if a valid serial number is found
- * 1 otherwise.
- */
-
-int
-board_serial_number_get(lboard_t *board,char *serial_number)
-{
-	ASSERT(board && serial_number);
-	if (!board || !serial_number)
-		return(1);
-
-	strcpy(serial_number,"");
-	switch(KLCLASS(board->brd_type)) {
-	case KLCLASS_CPU: {	/* Node board */
-		klhub_t	*hub;
-		
-		/* Get the hub component information */
-		hub = (klhub_t *)find_first_component(board,
-						      KLSTRUCT_HUB);
-		/* If we don't have a hub component on an IP27
-		 * then we have a weird klconfig.
-		 */
-		if (!hub)
-			return(1);
-		/* Get the serial number information from
-		 * the hub's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						hub->hub_mfg_nic,
-						serial_number,
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-						"IP37"))
-#else
-						"IP27"))
-			/* Try with IP31 key if IP27 key fails */
-			if (component_serial_number_get(board,
-							hub->hub_mfg_nic,
-							serial_number,
-							"IP31"))
-#endif /* CONFIG_IA64_SGI_SN1 */
-				return(1);
-		break;
-	}
-	case KLCLASS_IO: {	/* IO board */
-		if (KLTYPE(board->brd_type) == KLTYPE_TPU) {
-		/* Special case for TPU boards */
-			kltpu_t *tpu;	
-		
-			/* Get the tpu component information */
-			tpu = (kltpu_t *)find_first_component(board,
-						      KLSTRUCT_TPU);
-			/* If we don't have a tpu component on a tpu board
-			 * then we have a weird klconfig.
-			 */
-			if (!tpu)
-				return(1);
-			/* Get the serial number information from
-			 * the tpu's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						tpu->tpu_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		} else  if ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) ||
-		            (KLTYPE(board->brd_type) == KLTYPE_GSN_B)) {
-		/* Special case for GSN boards */
-			klgsn_t *gsn;	
-		
-			/* Get the gsn component information */
-			gsn = (klgsn_t *)find_first_component(board,
-			      ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) ?
-					KLSTRUCT_GSN_A : KLSTRUCT_GSN_B));
-			/* If we don't have a gsn component on a gsn board
-			 * then we have a weird klconfig.
-			 */
-			if (!gsn)
-				return(1);
-			/* Get the serial number information from
-			 * the gsn's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						gsn->gsn_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		} else {
-		     	klbri_t	*bridge;
-		
-			/* Get the bridge component information */
-			bridge = (klbri_t *)find_first_component(board,
-							 KLSTRUCT_BRI);
-			/* If we don't have a bridge component on an IO board
-			 * then we have a weird klconfig.
-			 */
-			if (!bridge)
-				return(1);
-			/* Get the serial number information from
-		 	 * the bridge's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						bridge->bri_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		}
-	}
-	case KLCLASS_ROUTER: {	/* Router board */
-		klrou_t *router;	
-		
-		/* Get the router component information */
-		router = (klrou_t *)find_first_component(board,
-							 KLSTRUCT_ROU);
-		/* If we don't have a router component on a router board
-		 * then we have a weird klconfig.
-		 */
-		if (!router)
-			return(1);
-		/* Get the serial number information from
-		 * the router's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						router->rou_mfg_nic,
-						serial_number,
-						""))
-			return(1);
-		break;
-	}
-	case KLCLASS_GFX: {	/* Gfx board */
-		klgfx_t *graphics;
-		
-		/* Get the graphics component information */
-		graphics = (klgfx_t *)find_first_component(board, KLSTRUCT_GFX);
-		/* If we don't have a gfx component on a gfx board
-		 * then we have a weird klconfig.
-		 */
-		if (!graphics)
-			return(1);
-		/* Get the serial number information from
-		 * the graphics's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						graphics->gfx_mfg_nic,
-						serial_number,
-						""))
-			return(1);
-		break;
-	}
-	default:
-		strcpy(serial_number,"");
-		break;
-	}
-	return(0);
-}
-
-#include "asm/sn/sn_private.h"
-
-xwidgetnum_t
-nodevertex_widgetnum_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, 
-			     (arbitrary_info_t *) &hubinfo_p);
-	return(hubinfo_p->h_widgetid);
-}
-
-devfs_handle_t
-nodevertex_xbow_peer_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-	nasid_t xbow_peer_nasid;
-	cnodeid_t xbow_peer;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO,
-				     (arbitrary_info_t *) &hubinfo_p);
-	xbow_peer_nasid = hubinfo_p->h_nodepda->xbow_peer;
-	if(xbow_peer_nasid == INVALID_NASID) 
-			return ( (devfs_handle_t)-1);
-	xbow_peer = NASID_TO_COMPACT_NODEID(xbow_peer_nasid);
-	return(NODEPDA(xbow_peer)->node_vertex);
-}
-
-/* NIC Sorting Support */
-
-#define MAX_NICS_PER_STRING 	32
-#define MAX_NIC_NAME_LEN	32
-
-static char *
-get_nic_string(lboard_t *lb)
-{
-        int         	i;
-        klinfo_t    	*k = NULL ;
-    	klconf_off_t    mfg_off = 0 ;
-    	char            *mfg_nic = NULL ;
-
-        for (i = 0; i < KLCF_NUM_COMPS(lb); i++) {
-                k = KLCF_COMP(lb, i) ;
-                switch(k->struct_type) {
-                        case KLSTRUCT_BRI:
-            			mfg_off = ((klbri_t *)k)->bri_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_HUB:
-            			mfg_off = ((klhub_t *)k)->hub_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_ROU:
-            			mfg_off = ((klrou_t *)k)->rou_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GFX:
-            			mfg_off = ((klgfx_t *)k)->gfx_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_TPU:
-            			mfg_off = ((kltpu_t *)k)->tpu_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GSN_A:
-                        case KLSTRUCT_GSN_B:
-            			mfg_off = ((klgsn_t *)k)->gsn_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_XTHD:
-                                mfg_off = ((klxthd_t *)k)->xthd_mfg_nic ;
-                                break;
-
-			default:
-				mfg_off = 0 ;
-                                break ;
-                }
-		if (mfg_off)
-			break ;
-        }
-
-	if ((mfg_off) && (k))
-		mfg_nic = (char *)NODE_OFFSET_TO_K0(k->nasid, mfg_off) ;
-
-        return mfg_nic ;
-}
-
-char *
-get_first_string(char **ptrs, int n)
-{
-        int     i ;
-        char    *tmpptr ;
-
-        if ((ptrs == NULL) || (n == 0))
-                return NULL ;
-
-        tmpptr = ptrs[0] ;
-
-        if (n == 1)
-                return tmpptr ;
-
-        for (i = 0 ; i < n ; i++) {
-                if (strcmp(tmpptr, ptrs[i]) > 0)
-                        tmpptr = ptrs[i] ;
-        }
-
-        return tmpptr ;
-}
-
-int
-get_ptrs(char *idata, char **ptrs, int n, char *label)
-{
-        int     i = 0 ;
-        char    *tmp = idata ;
-
-        if ((ptrs == NULL) || (idata == NULL) || (label == NULL) || (n == 0))
-                return 0 ;
-
-        while  ( (tmp = strstr(tmp, label)) ){
-                tmp += strlen(label) ;
-                /* check for empty name field, and last NULL ptr */
-                if ((i < (n-1)) && (*tmp != ';')) {
-                        ptrs[i++] = tmp ;
-                }
-        }
-
-        ptrs[i] = NULL ;
-
-        return i ;
-}
-
-/*
- * sort_nic_names
- *
- * 	Does not really do sorting. Find the alphabetically lowest
- *	name among all the nic names found in a nic string.
- *
- * Return:
- *	Nothing
- *
- * Side Effects:
- *
- *	lb->brd_name gets the new name found
- */
-
-static void
-sort_nic_names(lboard_t *lb)
-{
-	char 	*nic_str ;
-        char    *ptrs[MAX_NICS_PER_STRING] ;
-        char    name[MAX_NIC_NAME_LEN] ;
-        char    *tmp, *tmp1 ;
-
-	*name = 0 ;
-
-	/* Get the nic pointer from the lb */
-
-	if ((nic_str = get_nic_string(lb)) == NULL)
-		return ;
-
-        tmp = get_first_string(ptrs,
-                        get_ptrs(nic_str, ptrs, MAX_NICS_PER_STRING, "Name:")) ;
-
-        if (tmp == NULL)
-		return ;
-
-        if  ( (tmp1 = strchr(tmp, ';')) ){
-                strncpy(name, tmp, tmp1-tmp) ;
-                name[tmp1-tmp] = 0 ;
-        } else {
-                strncpy(name, tmp, (sizeof(name) -1)) ;
-                name[sizeof(name)-1] = 0 ;
-        }
-
-	strcpy(lb->brd_name, name) ;
-}
-
-
-
-char brick_types[MAX_BRICK_TYPES + 1] = "crikxdp789012345";
-
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-
-/*
- * Format a module id for printing.
- */
-void
-format_module_id(char *buffer, moduleid_t m, int fmt)
-{
-	int rack, position;
-	char brickchar;
-
-	rack = MODULE_GET_RACK(m);
-	ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES);
-	brickchar = MODULE_GET_BTCHAR(m);
-	position = MODULE_GET_BPOS(m);
-
-	if (fmt == MODULE_FORMAT_BRIEF) {
-	    /* Brief module number format, eg. 002c15 */
-
-	    /* Decompress the rack number */
-	    *buffer++ = '0' + RACK_GET_CLASS(rack);
-	    *buffer++ = '0' + RACK_GET_GROUP(rack);
-	    *buffer++ = '0' + RACK_GET_NUM(rack);
-
-	    /* Add the brick type */
-	    *buffer++ = brickchar;
-	}
-	else if (fmt == MODULE_FORMAT_LONG) {
-	    /* Fuller hwgraph format, eg. rack/002/bay/15 */
-
-	    strcpy(buffer, EDGE_LBL_RACK "/");  buffer += strlen(buffer);
-
-	    *buffer++ = '0' + RACK_GET_CLASS(rack);
-	    *buffer++ = '0' + RACK_GET_GROUP(rack);
-	    *buffer++ = '0' + RACK_GET_NUM(rack);
-
-	    strcpy(buffer, "/" EDGE_LBL_RPOS "/");  buffer += strlen(buffer);
-	}
-
-	/* Add the bay position, using at least two digits */
-	if (position < 10)
-	    *buffer++ = '0';
-	sprintf(buffer, "%d", position);
-
-}
-
-/*
- * Parse a module id, in either brief or long form.
- * Returns < 0 on error.
- * The long form does not include a brick type, so it defaults to 0 (CBrick)
- */
-int
-parse_module_id(char *buffer)
-{
-	unsigned int	v, rack, bay, type, form;
-	moduleid_t	m;
-	char 		c;
-
-	if (strstr(buffer, EDGE_LBL_RACK "/") == buffer) {
-		form = MODULE_FORMAT_LONG;
-		buffer += strlen(EDGE_LBL_RACK "/");
-
-		/* A long module ID must be exactly 5 non-template chars. */
-		if (strlen(buffer) != strlen("/" EDGE_LBL_RPOS "/") + 5)
-			return -1;
-	}
-	else {
-		form = MODULE_FORMAT_BRIEF;
-
-		/* A brief module id must be exactly 6 characters */
-		if (strlen(buffer) != 6)
-			return -2;
-	}
-
-	/* The rack number must be exactly 3 digits */
-	if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && isdigit(buffer[2])))
-		return -3;
-
-	rack = 0;
-	v = *buffer++ - '0';
-	if (v > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-		return -4;
-	RACK_ADD_CLASS(rack, v);
-
-	v = *buffer++ - '0';
-	if (v > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-		return -5;
-	RACK_ADD_GROUP(rack, v);
-
-	v = *buffer++ - '0';
-	/* rack numbers are 1-based */
-	if (v-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-		return -6;
-	RACK_ADD_NUM(rack, v);
-
-	if (form == MODULE_FORMAT_BRIEF) {
-		/* Next should be a module type character.  Accept ucase or lcase. */
-		c = *buffer++;
-		if (!isalpha(c))
-			return -7;
-
-		/* strchr() returns a pointer into brick_types[], or NULL */
-		type = (unsigned int)(strchr(brick_types, tolower(c)) - brick_types);
-		if (type > MODULE_BTYPE_MASK >> MODULE_BTYPE_SHFT)
-			return -8;
-	}
-	else {
-		/* Hardcode the module type, and skip over the boilerplate */
-		type = MODULE_CBRICK;
-
-		if (strstr(buffer, "/" EDGE_LBL_RPOS "/") != buffer)
-			return -9;
-
-		buffer += strlen("/" EDGE_LBL_RPOS "/");
-	}
-		
-	/* The bay number is last.  Make sure it's exactly two digits */
-
-	if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && !buffer[2]))
-		return -10;
-
-	bay = 10 * (buffer[0] - '0') + (buffer[1] - '0');
-
-	if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-		return -11;
-
-	m = RBT_TO_MODULE(rack, bay, type);
-
-	/* avoid sign extending the moduleid_t */
-	return (int)(unsigned short)m;
-}
-
-#else /* CONFIG_IA64_SGI_SN1 */
-
-/*
- * Format a module id for printing.
- */
-void
-format_module_id(char *buffer, moduleid_t m, int fmt)
-{
-    if (fmt == MODULE_FORMAT_BRIEF) {
-		sprintf(buffer, "%d", m);
-    }
-    else if (fmt == MODULE_FORMAT_LONG) {
-		sprintf(buffer, EDGE_LBL_MODULE "/%d", m);
-    }
-}
-
-/*
- * Parse a module id, in either brief or long form.
- * Returns < 0 on error.
- */
-int
-parse_module_id(char *buffer)
-{
-    moduleid_t m;
-    char c;
-
-    if (strstr(buffer, EDGE_LBL_MODULE "/") == buffer)
-	buffer += strlen(EDGE_LBL_MODULE "/");
-
-    for (m = 0; *buffer; buffer++) {
-	c = *buffer;
-	if (!isdigit(c))
-	    return -1;
-	m = 10 * m + (c - '0');
-    }
-
-    /* avoid sign extending the moduleid_t */
-    return (int)(unsigned short)m;
-}
-
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/klgraph.c linux-2.4.22-pre10/arch/ia64/sn/io/klgraph.c
--- linux-2.4.21/arch/ia64/sn/io/klgraph.c	2002-08-03 00:39:42.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/klgraph.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,795 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * klgraph.c-
- *      This file specifies the interface between the kernel and the PROM's
- *      configuration data structures.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/kldir.h>
-#include <asm/sn/gda.h> 
-#include <asm/sn/klconfig.h>
-#include <asm/sn/router.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/hcl_util.h>
-
-/* #define KLGRAPH_DEBUG 1 */
-#ifdef KLGRAPH_DEBUG
-#define GRPRINTF(x)	printk x
-#define CE_GRPANIC	CE_PANIC
-#else
-#define GRPRINTF(x)
-#define CE_GRPANIC	CE_PANIC
-#endif
-
-#include <asm/sn/sn_private.h>
-
-extern char arg_maxnodes[];
-extern u64 klgraph_addr[];
-
-/*
- * Support for verbose inventory via hardware graph. 
- * klhwg_invent_alloc allocates the necessary size of inventory information
- * and fills in the generic information.
- */
-invent_generic_t *
-klhwg_invent_alloc(cnodeid_t cnode, int class, int size)
-{
-	invent_generic_t *invent;
-
-	invent = kern_malloc(size);
-	if (!invent) return NULL;
-	
-	invent->ig_module = NODE_MODULEID(cnode);
-	invent->ig_slot = SLOTNUM_GETSLOT(NODE_SLOTID(cnode));
-	invent->ig_invclass = class;
-
-	return invent;
-}
-
-/* 
- * Add information about the baseio prom version number
- * as a part of detailed inventory info in the hwgraph.
- */
-void
-klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode)
-{
-	invent_miscinfo_t	*baseio_inventory;
-	unsigned char		version = 0,revision = 0;
-
-	/* Allocate memory for the "detailed inventory" info
-	 * for the baseio
-	 */
-	baseio_inventory = (invent_miscinfo_t *) 
-		klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t));
-	baseio_inventory->im_type = INV_IO6PROM;
-	/* Read the io6prom revision from the nvram */
-#ifdef LATER
-	nvram_prom_version_get(&version,&revision);
-#endif
-	/* Store the revision info  in the inventory */
-	baseio_inventory->im_version = version;
-	baseio_inventory->im_rev = revision;
-	/* Put the inventory info in the hardware graph */
-	hwgraph_info_add_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, 
-			     (arbitrary_info_t) baseio_inventory);
-	/* Make the information available to the user programs
-	 * thru hwgfs.
-	 */
-        hwgraph_info_export_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT,
-				sizeof(invent_miscinfo_t));
-}
-
-char	*hub_rev[] = {
-	"0.0",
-	"1.0",
-	"2.0",
-	"2.1",
-	"2.2",
-	"2.3"
-};
-
-/*
- * Add detailed cpu inventory info to the hardware graph.
- */
-void
-klhwg_hub_invent_info(devfs_handle_t hubv,
-		      cnodeid_t cnode, 
-		      klhub_t *hub)
-{
-	invent_miscinfo_t *hub_invent;
-
-	hub_invent = (invent_miscinfo_t *) 
-	    klhwg_invent_alloc(cnode, INV_MISC, sizeof(invent_miscinfo_t));
-	if (!hub_invent)
-	    return;
-
-	if (KLCONFIG_INFO_ENABLED((klinfo_t *)hub))
-	    hub_invent->im_gen.ig_flag = INVENT_ENABLED;
-
-	hub_invent->im_type = INV_HUB;
-	hub_invent->im_rev = hub->hub_info.revision;
-	hub_invent->im_speed = hub->hub_speed;
-	hwgraph_info_add_LBL(hubv, INFO_LBL_DETAIL_INVENT, 
-			     (arbitrary_info_t) hub_invent);
-        hwgraph_info_export_LBL(hubv, INFO_LBL_DETAIL_INVENT,
-				sizeof(invent_miscinfo_t));
-}
-
-/* ARGSUSED */
-void
-klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode)
-{
-#if defined(CONFIG_IA64_SGI_SN1)
-	devfs_handle_t myhubv;
-	devfs_handle_t hub_mon;
-	devfs_handle_t synergy;
-	devfs_handle_t fsb0;
-	devfs_handle_t fsb1;
-	int rc;
-	extern struct file_operations hub_mon_fops;
-
-	GRPRINTF(("klhwg_add_hub: adding %s\n", EDGE_LBL_HUB));
-
-	(void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv);
-	rc = device_master_set(myhubv, node_vertex);
-
-	/*
-	 * hub perf stats.
-	 */
-	rc = hwgraph_info_add_LBL(myhubv, INFO_LBL_HUB_INFO,
-                        (arbitrary_info_t)(&NODEPDA(cnode)->hubstats));
-
-	if (rc != GRAPH_SUCCESS) {
-		printk(KERN_WARNING  "klhwg_add_hub: Can't add hub info label 0x%p, code %d",
-			(void *)myhubv, rc);
-	}
-
-	klhwg_hub_invent_info(myhubv, cnode, hub);
-
-	hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &hub_mon_fops,
-	    (void *)(long)cnode);
-
-	init_hub_stats(cnode, NODEPDA(cnode));
-
-	/*
-	 * synergy perf
-	 */
-	(void) hwgraph_path_add(myhubv, EDGE_LBL_SYNERGY, &synergy);
-	(void) hwgraph_path_add(synergy, "0", &fsb0);
-	(void) hwgraph_path_add(synergy, "1", &fsb1);
-
-	fsb0 = hwgraph_register(fsb0, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 0));
-
-	fsb1 = hwgraph_register(fsb1, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 1));
-#endif /* CONFIG_IA64_SGI_SN1 */
-}
-
-void
-klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid)
-{
-	lboard_t *brd;
-	klxbow_t *xbow_p;
-	nasid_t hub_nasid;
-	cnodeid_t hub_cnode;
-	int widgetnum;
-	devfs_handle_t xbow_v, hubv;
-	/*REFERENCED*/
-	graph_error_t err;
-
-	if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW)) == NULL)
-			return;
-
-	if (KL_CONFIG_DUPLICATE_BOARD(brd))
-	    return;
-
-	GRPRINTF(("klhwg_add_xbow: adding cnode %d nasid %d xbow edges\n",
-			cnode, nasid));
-
-	if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW))
-	    == NULL)
-	    return;
-
-#ifdef	LATER
-	/*
-	 * We cannot support this function in devfs .. see below where 
-	 * we use hwgraph_path_add() to create this vertex with a known 
-	 * name.
-	 */
-	err = hwgraph_vertex_create(&xbow_v);
-	ASSERT(err == GRAPH_SUCCESS);
-
-	xswitch_vertex_init(xbow_v);
-#endif /* LATER */
-
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
-		if (!XBOW_PORT_TYPE_HUB(xbow_p, widgetnum)) 
-		    continue;
-
-		hub_nasid = XBOW_PORT_NASID(xbow_p, widgetnum);
-		if (hub_nasid == INVALID_NASID) {
-			printk(KERN_WARNING  "hub widget %d, skipping xbow graph\n", widgetnum);
-			continue;
-		}
-
-		hub_cnode = NASID_TO_COMPACT_NODEID(hub_nasid);
-
-		if (is_specified(arg_maxnodes) && hub_cnode == INVALID_CNODEID) {
-			continue;
-		}
-			
-		hubv = cnodeid_to_vertex(hub_cnode);
-
-		err = hwgraph_path_add(hubv, EDGE_LBL_XTALK, &xbow_v);
-                if (err != GRAPH_SUCCESS) {
-                        if (err == GRAPH_DUP)
-                                printk(KERN_WARNING  "klhwg_add_xbow: Check for "
-                                        "working routers and router links!");
-
-                        PRINT_PANIC("klhwg_add_xbow: Failed to add "
-                                "edge: vertex 0x%p to vertex 0x%p,"
-                                "error %d\n",
-                                (void *)hubv, (void *)xbow_v, err);
-                }
-		xswitch_vertex_init(xbow_v); 
-
-		NODEPDA(hub_cnode)->xbow_vhdl = xbow_v;
-
-		/*
-		 * XXX - This won't work is we ever hook up two hubs
-		 * by crosstown through a crossbow.
-		 */
-		if (hub_nasid != nasid) {
-			NODEPDA(hub_cnode)->xbow_peer = nasid;
-			NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer =
-				hub_nasid;
-		}
-
-		GRPRINTF(("klhwg_add_xbow: adding port nasid %d %s to vertex 0x%p\n",
-			hub_nasid, EDGE_LBL_XTALK, hubv));
-
-#ifdef	LATER
-		err = hwgraph_edge_add(hubv, xbow_v, EDGE_LBL_XTALK);
-		if (err != GRAPH_SUCCESS) {
-			if (err == GRAPH_DUP)
-				printk(KERN_WARNING  "klhwg_add_xbow: Check for "
-					"working routers and router links!");
-
-			PRINT_PANIC("klhwg_add_xbow: Failed to add "
-				"edge: vertex 0x%p (0x%p) to vertex 0x%p (0x%p), "
-				"error %d\n",
-				hubv, hubv, xbow_v, xbow_v, err);
-		}
-#endif
-	}
-}
-
-
-/* ARGSUSED */
-void
-klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap)
-{
-	nasid_t nasid;
-	lboard_t *brd;
-	klhub_t *hub;
-	devfs_handle_t node_vertex = NULL;
-	char path_buffer[100];
-	int rv;
-	char *s;
-	int board_disabled = 0;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-	GRPRINTF(("klhwg_add_node: Adding cnode %d, nasid %d, brd 0x%p\n",
-                cnode, nasid, brd));
-	ASSERT(brd);
-
-	do {
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(brd, path_buffer);
-
-		GRPRINTF(("klhwg_add_node: adding %s to vertex 0x%p\n",
-			path_buffer, hwgraph_root));
-		rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
-
-		if (rv != GRAPH_SUCCESS)
-			PRINT_PANIC("Node vertex creation failed.  "
-					  "Path == %s",
-				path_buffer);
-
-		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-		ASSERT(hub);
-		if(hub->hub_info.flags & KLINFO_ENABLE)
-			board_disabled = 0;
-		else
-			board_disabled = 1;
-		
-		if(!board_disabled) {
-			mark_nodevertex_as_node(node_vertex,
-					    cnode + board_disabled * numnodes);
-
-			s = dev_to_name(node_vertex, path_buffer, sizeof(path_buffer));
-			NODEPDA(cnode)->hwg_node_name =
-						kmalloc(strlen(s) + 1,
-						GFP_KERNEL);
-			ASSERT_ALWAYS(NODEPDA(cnode)->hwg_node_name != NULL);
-			strcpy(NODEPDA(cnode)->hwg_node_name, s);
-
-			hubinfo_set(node_vertex, NODEPDA(cnode)->pdinfo);
-
-			/* Set up node board's slot */
-			NODEPDA(cnode)->slotdesc = brd->brd_slot;
-
-			/* Set up the module we're in */
-			NODEPDA(cnode)->module_id = brd->brd_module;
-			NODEPDA(cnode)->module = module_lookup(brd->brd_module);
-		}
-
-		if(!board_disabled)
-		klhwg_add_hub(node_vertex, hub, cnode);
-		
-		brd = KLCF_NEXT(brd);
-		if (brd)
-			brd = find_lboard(brd, KLTYPE_SNIA);
-		else
-			break;
-	} while(brd);
-}
-
-
-/* ARGSUSED */
-void
-klhwg_add_all_routers(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-	devfs_handle_t node_vertex;
-	char path_buffer[100];
-	int rv;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_add_all_routers: adding router on cnode %d\n",
-			cnode));
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-				KLTYPE_ROUTER);
-
-		if (!brd)
-			/* No routers stored in this node's memory */
-			continue;
-
-		do {
-			ASSERT(brd);
-			GRPRINTF(("Router board struct is %p\n", brd));
-
-			/* Don't add duplicate boards. */
-			if (brd->brd_flags & DUPLICATE_BOARD)
-				continue;
-
-			GRPRINTF(("Router 0x%p module number is %d\n", brd, brd->brd_module));
-			/* Generate a hardware graph path for this board. */
-			board_to_path(brd, path_buffer);
-
-			GRPRINTF(("Router path is %s\n", path_buffer));
-
-			/* Add the router */
-			GRPRINTF(("klhwg_add_all_routers: adding %s to vertex 0x%p\n",
-				path_buffer, hwgraph_root));
-			rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
-
-			if (rv != GRAPH_SUCCESS)
-				PRINT_PANIC("Router vertex creation "
-						  "failed.  Path == %s",
-					path_buffer);
-
-			GRPRINTF(("klhwg_add_all_routers: get next board from 0x%p\n",
-					brd));
-		/* Find the rest of the routers stored on this node. */
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd),
-			 KLTYPE_ROUTER)) );
-
-		GRPRINTF(("klhwg_add_all_routers: Done.\n"));
-	}
-
-}
-
-/* ARGSUSED */
-void
-klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd,
-			 cnodeid_t cnode, nasid_t nasid)
-{
-	klrou_t *router;
-	char path_buffer[50];
-	char dest_path[50];
-	devfs_handle_t router_hndl;
-	devfs_handle_t dest_hndl;
-	int rc;
-	int port;
-	lboard_t *dest_brd;
-
-	GRPRINTF(("klhwg_connect_one_router: Connecting router on cnode %d\n",
-			cnode));
-
-	/* Don't add duplicate boards. */
-	if (brd->brd_flags & DUPLICATE_BOARD) {
-		GRPRINTF(("klhwg_connect_one_router: Duplicate router 0x%p on cnode %d\n",
-			brd, cnode));
-		return;
-	}
-
-	/* Generate a hardware graph path for this board. */
-	board_to_path(brd, path_buffer);
-
-	rc = hwgraph_traverse(hwgraph_root, path_buffer, &router_hndl);
-
-	if (rc != GRAPH_SUCCESS && is_specified(arg_maxnodes))
-			return;
-
-	if (rc != GRAPH_SUCCESS)
-		printk(KERN_WARNING  "Can't find router: %s", path_buffer);
-
-	/* We don't know what to do with multiple router components */
-	if (brd->brd_numcompts != 1) {
-		PRINT_PANIC("klhwg_connect_one_router: %d cmpts on router\n",
-			brd->brd_numcompts);
-		return;
-	}
-
-
-	/* Convert component 0 to klrou_t ptr */
-	router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd),
-					      brd->brd_compts[0]);
-
-	for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
-		/* See if the port's active */
-		if (router->rou_port[port].port_nasid == INVALID_NASID) {
-			GRPRINTF(("klhwg_connect_one_router: port %d inactive.\n",
-				 port));
-			continue;
-		}
-		if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(router->rou_port[port].port_nasid) 
-		    == INVALID_CNODEID) {
-			continue;
-		}
-
-		dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-				router->rou_port[port].port_nasid,
-				router->rou_port[port].port_offset);
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(dest_brd, dest_path);
-
-		rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);
-
-		if (rc != GRAPH_SUCCESS) {
-			if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
-				continue;
-			PRINT_PANIC("Can't find router: %s", dest_path);
-		}
-		GRPRINTF(("klhwg_connect_one_router: Link from %s/%d to %s\n",
-			  path_buffer, port, dest_path));
-
-		sprintf(dest_path, "%d", port);
-
-		rc = hwgraph_edge_add(router_hndl, dest_hndl, dest_path);
-
-		if (rc == GRAPH_DUP) {
-			GRPRINTF(("Skipping port %d. nasid %d %s/%s\n",
-				  port, router->rou_port[port].port_nasid,
-				  path_buffer, dest_path));
-			continue;
-		}
-
-		if (rc != GRAPH_SUCCESS && !is_specified(arg_maxnodes))
-			PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n",
-				path_buffer, dest_path, (void *)dest_hndl, rc);
-		
-	}
-}
-
-
-void
-klhwg_connect_routers(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_connect_routers: Connecting routers on cnode %d\n",
-			cnode));
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-				KLTYPE_ROUTER);
-
-		if (!brd)
-			continue;
-
-		do {
-
-			nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-			klhwg_connect_one_router(hwgraph_root, brd,
-						 cnode, nasid);
-
-		/* Find the rest of the routers stored on this node. */
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
-	}
-}
-
-
-
-void
-klhwg_connect_hubs(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-	klhub_t *hub;
-	lboard_t *dest_brd;
-	devfs_handle_t hub_hndl;
-	devfs_handle_t dest_hndl;
-	char path_buffer[50];
-	char dest_path[50];
-	graph_error_t rc;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_connect_hubs: Connecting hubs on cnode %d\n",
-			cnode));
-
-		brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-		ASSERT(brd);
-
-		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-		ASSERT(hub);
-
-		/* See if the port's active */
-		if (hub->hub_port.port_nasid == INVALID_NASID) {
-			GRPRINTF(("klhwg_connect_hubs: port inactive.\n"));
-			continue;
-		}
-
-		if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(hub->hub_port.port_nasid) == INVALID_CNODEID)
-			continue;
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(brd, path_buffer);
-
-		GRPRINTF(("klhwg_connect_hubs: Hub path is %s.\n", path_buffer));
-		rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl);
-
-		if (rc != GRAPH_SUCCESS)
-			printk(KERN_WARNING  "Can't find hub: %s", path_buffer);
-
-		dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-				hub->hub_port.port_nasid,
-				hub->hub_port.port_offset);
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(dest_brd, dest_path);
-
-		rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);
-
-		if (rc != GRAPH_SUCCESS) {
-			if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
-				continue;
-			PRINT_PANIC("Can't find board: %s", dest_path);
-		} else {
-		
-
-			GRPRINTF(("klhwg_connect_hubs: Link from %s to %s.\n",
-			  path_buffer, dest_path));
-
-			rc = hwgraph_edge_add(hub_hndl, dest_hndl, EDGE_LBL_INTERCONNECT);
-
-			if (rc != GRAPH_SUCCESS)
-				PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n",
-				path_buffer, dest_path, (void *)dest_hndl, rc);
-
-		}
-	}
-}
-
-/* Store the pci/vme disabled board information as extended administrative
- * hints which can later be used by the drivers using the device/driver
- * admin interface. 
- */
-void
-klhwg_device_disable_hints_add(void)
-{
-	cnodeid_t	cnode; 		/* node we are looking at */
-	nasid_t		nasid;		/* nasid of the node */
-	lboard_t	*board;		/* board we are looking at */
-	int		comp_index;	/* component index */
-	klinfo_t	*component;	/* component in the board we are
-					 * looking at 
-					 */
-	char		device_name[MAXDEVNAME];
-	
-#ifdef	LATER
-	device_admin_table_init();
-#endif
-	for(cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-		board = (lboard_t *)KL_CONFIG_INFO(nasid);
-		/* Check out all the board info stored  on a node */
-		while(board) {
-			/* No need to look at duplicate boards or non-io 
-			 * boards
-			 */
-			if (KL_CONFIG_DUPLICATE_BOARD(board) ||
-			    KLCLASS(board->brd_type) != KLCLASS_IO) {
-				board = KLCF_NEXT(board);
-				continue;
-			}
-			/* Check out all the components of a board */
-			for (comp_index = 0; 
-			     comp_index < KLCF_NUM_COMPS(board);
-			     comp_index++) {
-				component = KLCF_COMP(board,comp_index);
-				/* If the component is enabled move on to
-				 * the next component
-				 */
-				if (KLCONFIG_INFO_ENABLED(component))
-					continue;
-				/* NOTE : Since the prom only supports
-				 * the disabling of pci devices the following
-				 * piece of code makes sense. 
-				 * Make sure that this assumption is valid
-				 */
-				/* This component is disabled. Store this
-				 * hint in the extended device admin table
-				 */
-				/* Get the canonical name of the pci device */
-				device_component_canonical_name_get(board,
-							    component,
-							    device_name);
-#ifdef	LATER
-				device_admin_table_update(device_name,
-							  ADMIN_LBL_DISABLED,
-							  "yes");
-#endif
-#ifdef DEBUG
-				printf("%s DISABLED\n",device_name);
-#endif				
-			}
-			/* go to the next board info stored on this 
-			 * node 
-			 */
-			board = KLCF_NEXT(board);
-		}
-	}
-}
-
-void
-klhwg_add_all_modules(devfs_handle_t hwgraph_root)
-{
-	cmoduleid_t	cm;
-	char		name[128];
-	devfs_handle_t	vhdl;
-	int		rc;
-	char		buffer[16];
-
-	/* Add devices under each module */
-
-	for (cm = 0; cm < nummodules; cm++) {
-		/* Use module as module vertex fastinfo */
-
-#ifdef __ia64
-		memset(buffer, 0, 16);
-		format_module_id(buffer, modules[cm]->id, MODULE_FORMAT_BRIEF);
-		sprintf(name, EDGE_LBL_MODULE "/%s", buffer);
-#else
-		sprintf(name, EDGE_LBL_MODULE "/%x", modules[cm]->id);
-#endif
-
-		rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
-		ASSERT(rc == GRAPH_SUCCESS);
-		rc = rc;
-
-		hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) modules[cm]);
-
-		/* Add system controller */
-
-#ifdef __ia64
-		sprintf(name,
-			EDGE_LBL_MODULE "/%s/" EDGE_LBL_L1,
-			buffer);
-#else
-		sprintf(name,
-			EDGE_LBL_MODULE "/%x/" EDGE_LBL_L1,
-			modules[cm]->id);
-#endif
-
-		rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
-		ASSERT_ALWAYS(rc == GRAPH_SUCCESS); 
-		rc = rc;
-
-		hwgraph_info_add_LBL(vhdl,
-				     INFO_LBL_ELSC,
-				     (arbitrary_info_t) (__psint_t) 1);
-
-#ifdef	LATER
-		sndrv_attach(vhdl);
-#else
-		/*
-		 * We need to call the drivers attach routine ..
-		 */
-		FIXME("klhwg_add_all_modules: Need code to call driver attach.\n");
-#endif
-	}
-}
-
-void
-klhwg_add_all_nodes(devfs_handle_t hwgraph_root)
-{
-	cnodeid_t	cnode;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		klhwg_add_node(hwgraph_root, cnode, NULL);
-	}
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		klhwg_add_xbow(cnode, cnodeid_to_nasid(cnode));
-	}
-
-	/*
-	 * As for router hardware inventory information, we set this
-	 * up in router.c. 
-	 */
-	
-	klhwg_add_all_routers(hwgraph_root);
-	klhwg_connect_routers(hwgraph_root);
-	klhwg_connect_hubs(hwgraph_root);
-
-	/* Assign guardian nodes to each of the
-	 * routers in the system.
-	 */
-
-#ifdef	LATER
-	router_guardians_set(hwgraph_root);
-#endif
-
-	/* Go through the entire system's klconfig
-	 * to figure out which pci components have been disabled
-	 */
-	klhwg_device_disable_hints_add();
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/klgraph_hack.c linux-2.4.22-pre10/arch/ia64/sn/io/klgraph_hack.c
--- linux-2.4.21/arch/ia64/sn/io/klgraph_hack.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/klgraph_hack.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,341 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-/*
- * This is a temporary file that statically initializes the expected 
- * initial klgraph information that is normally provided by prom.
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/simulator.h>
-
-extern u64 klgraph_addr[];
-void * real_port;
-void * real_io_base;
-void * real_addr;
-
-char *BW0 = NULL;
-
-kl_config_hdr_t *linux_klcfg;
-
-#ifdef DEFINE_DUMP_RTNS
-/* forward declarations */
-static void dump_ii(void), dump_crossbow(void);
-static void clear_ii_error(void);
-#endif /* DEFINE_DUMP_RTNS */
-
-#define SYNERGY_WIDGET          ((char *)0xc0000e0000000000)
-#define SYNERGY_SWIZZLE         ((char *)0xc0000e0000000400)
-#define HUBREG                  ((char *)0xc0000a0001e00000)
-#define WIDGET0                 ((char *)0xc0000a0000000000)
-#define WIDGET4                 ((char *)0xc0000a0000000004)
-
-#define SYNERGY_WIDGET          ((char *)0xc0000e0000000000)
-#define SYNERGY_SWIZZLE         ((char *)0xc0000e0000000400)
-#define HUBREG                  ((char *)0xc0000a0001e00000)
-#define WIDGET0                 ((char *)0xc0000a0000000000)
-
-#define convert(a,b,c) temp = (u64 *)a; *temp = b; temp++; *temp = c
-
-void
-klgraph_hack_init(void)
-{
-
-	u64     *temp;
-
-#ifdef CONFIG_IA64_SGI_SN1
-	/*
-	 * We need to know whether we are booting from PROM or 
-	 * boot from disk.
-	 */
-	linux_klcfg = (kl_config_hdr_t *)0xe000000000030000;
-	if (linux_klcfg->ch_magic == 0xbeedbabe) {
-		return;
-	} else {
-		panic("klgraph_hack_init: Unable to locate KLCONFIG TABLE\n");
-	}
-
-	convert(0x0000000000030000, 0x00000000beedbabe, 0x0000004800000000);
-
-#else
-
-	if (IS_RUNNING_ON_SIMULATOR()) {
-		printk("Creating FAKE Klconfig Structure for Embeded Kernel\n");
-		klgraph_addr[0] = 0xe000003000030000;
-
-        /*
-         * klconfig entries initialization - mankato
-         */
-        convert(0xe000003000030000, 0x00000000beedbabe, 0x0000004800000000);
-        convert(0xe000003000030010, 0x0003007000000018, 0x800002000f820178);
-        convert(0xe000003000030020, 0x80000a000f024000, 0x800002000f800000);
-        convert(0xe000003000030030, 0x0300fafa00012580, 0x00000000040f0000);
-        convert(0xe000003000030040, 0x0000000000000000, 0x0003097000030070);
-        convert(0xe000003000030050, 0x00030970000303b0, 0x0003181000033f70);
-        convert(0xe000003000030060, 0x0003d51000037570, 0x0000000000038330);
-        convert(0xe000003000030070, 0x0203110100030140, 0x0001000000000101);
-        convert(0xe000003000030080, 0x0900000000000000, 0x000000004e465e67);
-        convert(0xe000003000030090, 0x0003097000000000, 0x00030b1000030a40);
-        convert(0xe0000030000300a0, 0x00030cb000030be0, 0x000315a0000314d0);
-        convert(0xe0000030000300b0, 0x0003174000031670, 0x0000000000000000);
-        convert(0xe000003000030100, 0x000000000000001a, 0x3350490000000000);
-        convert(0xe000003000030110, 0x0000000000000037, 0x0000000000000000);
-        convert(0xe000003000030140, 0x0002420100030210, 0x0001000000000101);
-        convert(0xe000003000030150, 0x0100000000000000, 0xffffffffffffffff);
-        convert(0xe000003000030160, 0x00030d8000000000, 0x0000000000030e50);
-        convert(0xe0000030000301c0, 0x0000000000000000, 0x0000000000030070);
-        convert(0xe0000030000301d0, 0x0000000000000025, 0x424f490000000000);
-        convert(0xe0000030000301e0, 0x000000004b434952, 0x0000000000000000);
-        convert(0xe000003000030210, 0x00027101000302e0, 0x00010000000e4101);
-        convert(0xe000003000030220, 0x0200000000000000, 0xffffffffffffffff);
-        convert(0xe000003000030230, 0x00030f2000000000, 0x0000000000030ff0);
-        convert(0xe000003000030290, 0x0000000000000000, 0x0000000000030140);
-        convert(0xe0000030000302a0, 0x0000000000000026, 0x7262490000000000);
-        convert(0xe0000030000302b0, 0x00000000006b6369, 0x0000000000000000);
-        convert(0xe0000030000302e0, 0x0002710100000000, 0x00010000000f3101);
-        convert(0xe0000030000302f0, 0x0500000000000000, 0xffffffffffffffff);
-        convert(0xe000003000030300, 0x000310c000000000, 0x0003126000031190);
-        convert(0xe000003000030310, 0x0003140000031330, 0x0000000000000000);
-        convert(0xe000003000030360, 0x0000000000000000, 0x0000000000030140);
-        convert(0xe000003000030370, 0x0000000000000029, 0x7262490000000000);
-        convert(0xe000003000030380, 0x00000000006b6369, 0x0000000000000000);
-        convert(0xe000003000030970, 0x0000000002010102, 0x0000000000000000);
-        convert(0xe000003000030980, 0x000000004e465e67, 0xffffffff00000000);
-        /* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */
-        convert(0xe0000030000309a0, 0x0000000000037570, 0xffffffff00000000);
-        convert(0xe0000030000309b0, 0x0000000000030070, 0x0000000000000000);
-        convert(0xe0000030000309c0, 0x000000000003f420, 0x0000000000000000);
-        convert(0xe000003000030a40, 0x0000000002010125, 0x0000000000000000);
-        convert(0xe000003000030a50, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000030a70, 0x0000000000037b78, 0x0000000000000000);
-        convert(0xe000003000030b10, 0x0000000002010125, 0x0000000000000000);
-        convert(0xe000003000030b20, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000030b40, 0x0000000000037d30, 0x0000000000000001);
-        convert(0xe000003000030be0, 0x00000000ff010203, 0x0000000000000000);
-        convert(0xe000003000030bf0, 0xffffffffffffffff, 0xffffffff000000ff);
-        convert(0xe000003000030c10, 0x0000000000037ee8, 0x0100010000000200);
-        convert(0xe000003000030cb0, 0x00000000ff310111, 0x0000000000000000);
-        convert(0xe000003000030cc0, 0xffffffffffffffff, 0x0000000000000000);
-        convert(0xe000003000030d80, 0x0000000002010104, 0x0000000000000000);
-        convert(0xe000003000030d90, 0xffffffffffffffff, 0x00000000000000ff);
-        convert(0xe000003000030db0, 0x0000000000037f18, 0x0000000000000000);
-        convert(0xe000003000030dc0, 0x0000000000000000, 0x0003007000060000);
-        convert(0xe000003000030de0, 0x0000000000000000, 0x0003021000050000);
-        convert(0xe000003000030df0, 0x000302e000050000, 0x0000000000000000);
-        convert(0xe000003000030e30, 0x0000000000000000, 0x000000000000000a);
-        convert(0xe000003000030e50, 0x00000000ff00011a, 0x0000000000000000);
-        convert(0xe000003000030e60, 0xffffffffffffffff, 0x0000000000000000);
-        convert(0xe000003000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e);
-        convert(0xe000003000030e90, 0x000000000000bc6e, 0x0000000000000000);
-        convert(0xe000003000030f20, 0x0000000002010205, 0x00000000d0020000);
-        convert(0xe000003000030f30, 0xffffffffffffffff, 0x0000000e0000000e);
-        convert(0xe000003000030f40, 0x000000000000000e, 0x0000000000000000);
-        convert(0xe000003000030f50, 0x0000000000038010, 0x00000000000007ff);
-        convert(0xe000003000030f70, 0x0000000000000000, 0x0000000022001077);
-        convert(0xe000003000030fa0, 0x0000000000000000, 0x000000000003f4a8);
-        convert(0xe000003000030ff0, 0x0000000000310120, 0x0000000000000000);
-        convert(0xe000003000031000, 0xffffffffffffffff, 0xffffffff00000002);
-        convert(0xe000003000031010, 0x000000000000000e, 0x0000000000000000);
-        convert(0xe000003000031020, 0x0000000000038088, 0x0000000000000000);
-        convert(0xe0000030000310c0, 0x0000000002010205, 0x00000000d0020000);
-        convert(0xe0000030000310d0, 0xffffffffffffffff, 0x0000000f0000000f);
-        convert(0xe0000030000310e0, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000310f0, 0x00000000000380b8, 0x00000000000007ff);
-        convert(0xe000003000031120, 0x0000000022001077, 0x00000000000310a9);
-        convert(0xe000003000031130, 0x00000000580211c1, 0x000000008009104c);
-        convert(0xe000003000031140, 0x0000000000000000, 0x000000000003f4c0);
-        convert(0xe000003000031190, 0x0000000000310120, 0x0000000000000000);
-        convert(0xe0000030000311a0, 0xffffffffffffffff, 0xffffffff00000003);
-        convert(0xe0000030000311b0, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000311c0, 0x0000000000038130, 0x0000000000000000);
-        convert(0xe000003000031260, 0x0000000000110106, 0x0000000000000000);
-        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
-        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
-        convert(0xe000003000031280, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000312a0, 0x00000000ff110013, 0x0000000000000000);
-        convert(0xe0000030000312b0, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe0000030000312c0, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000312e0, 0x0000000000110012, 0x0000000000000000);
-        convert(0xe0000030000312f0, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000031300, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe000003000031310, 0x0000000000038160, 0x0000000000000000);
-        convert(0xe000003000031330, 0x00000000ff310122, 0x0000000000000000);
-        convert(0xe000003000031340, 0xffffffffffffffff, 0xffffffff00000005);
-        convert(0xe000003000031350, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe000003000031360, 0x0000000000038190, 0x0000000000000000);
-        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
-        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
-        convert(0xe000003000031410, 0xffffffffffffffff, 0xffffffff00000006);
-        convert(0xe000003000031420, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe000003000031430, 0x00000000000381c0, 0x0000000000000000);
-        convert(0xe0000030000314d0, 0x00000000ff010201, 0x0000000000000000);
-        convert(0xe0000030000314e0, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000031500, 0x00000000000381f0, 0x000030430000ffff);
-        convert(0xe000003000031510, 0x000000000000ffff, 0x0000000000000000);
-        convert(0xe0000030000315a0, 0x00000020ff000201, 0x0000000000000000);
-        convert(0xe0000030000315b0, 0xffffffffffffffff, 0xffffffff00000001);
-        convert(0xe0000030000315d0, 0x0000000000038240, 0x00003f3f0000ffff);
-        convert(0xe0000030000315e0, 0x000000000000ffff, 0x0000000000000000);
-        convert(0xe000003000031670, 0x00000000ff010201, 0x0000000000000000);
-        convert(0xe000003000031680, 0xffffffffffffffff, 0x0000000100000002);
-        convert(0xe0000030000316a0, 0x0000000000038290, 0x000030430000ffff);
-        convert(0xe0000030000316b0, 0x000000000000ffff, 0x0000000000000000);
-        convert(0xe000003000031740, 0x00000020ff000201, 0x0000000000000000);
-        convert(0xe000003000031750, 0xffffffffffffffff, 0x0000000500000003);
-        convert(0xe000003000031770, 0x00000000000382e0, 0x00003f3f0000ffff);
-        convert(0xe000003000031780, 0x000000000000ffff, 0x0000000000000000);
-}
-
-#endif
-
-}
-
-
-
-
-	
-#ifdef DEFINE_DUMP_RTNS
-/* 
- * these were useful for printing out registers etc
- * during bringup  
- */
-
-static void
-xdump(long long *addr, int count)
-{
-	int ii;
-	volatile long long *xx = addr;
-
-	for ( ii = 0; ii < count; ii++, xx++ ) {
-		printk("0x%p : 0x%p\n", (void *)xx, (void *)*xx);
-	}
-}
-
-static void
-xdump32(unsigned int *addr, int count)
-{
-	int ii;
-	volatile unsigned int *xx = addr;
-
-	for ( ii = 0; ii < count; ii++, xx++ ) {
-		printk("0x%p : 0x%0x\n", (void *)xx, (int)*xx);
-	}
-}
-
-static void
-clear_ii_error(void)
-{
-	volatile long long *tmp;
-
-	printk("... WSTAT ");
-	xdump((long long *)0xc0000a0001c00008, 1);
-	printk("... WCTRL ");
-	xdump((long long *)0xc0000a0001c00020, 1);
-	printk("... WLCSR ");
-	xdump((long long *)0xc0000a0001c00128, 1);
-	printk("... IIDSR ");
-	xdump((long long *)0xc0000a0001c00138, 1);
-        printk("... IOPRBs ");
-	xdump((long long *)0xc0000a0001c00198, 9);
-	printk("... IXSS ");
-	xdump((long long *)0xc0000a0001c00210, 1);
-	printk("... IBLS0 ");
-	xdump((long long *)0xc0000a0001c10000, 1);
-	printk("... IBLS1 ");
-	xdump((long long *)0xc0000a0001c20000, 1);
-
-        /* Write IOERR clear to clear the CRAZY bit in the status */
-        tmp = (long long *)0xc0000a0001c001f8; *tmp = (long long)0xffffffff;
-
-	/* dump out local block error registers */
-	printk("... ");
-	xdump((long long *)0xc0000a0001e04040, 1);	/* LB_ERROR_BITS */
-	printk("... ");
-	xdump((long long *)0xc0000a0001e04050, 1);	/* LB_ERROR_HDR1 */
-	printk("... ");
-	xdump((long long *)0xc0000a0001e04058, 1);	/* LB_ERROR_HDR2 */
-	/* and clear the LB_ERROR_BITS */
-	tmp = (long long *)0xc0000a0001e04040; *tmp = 0x0;
-	printk("clr: ");
-	xdump((long long *)0xc0000a0001e04040, 1);	/* LB_ERROR_BITS */
-	tmp = (long long *)0xc0000a0001e04050; *tmp = 0x0;
-	tmp = (long long *)0xc0000a0001e04058; *tmp = 0x0;
-}
-
-
-static void
-dump_ii(void)
-{
-	printk("===== Dump the II regs =====\n");
-	xdump((long long *)0xc0000a0001c00000, 2);
-	xdump((long long *)0xc0000a0001c00020, 1);
-	xdump((long long *)0xc0000a0001c00100, 37);
-	xdump((long long *)0xc0000a0001c00300, 98);
-	xdump((long long *)0xc0000a0001c10000, 6);
-	xdump((long long *)0xc0000a0001c20000, 6);
-	xdump((long long *)0xc0000a0001c30000, 2);
-
-	xdump((long long *)0xc0000a0000000000, 1);
-	xdump((long long *)0xc0000a0001000000, 1);
-	xdump((long long *)0xc0000a0002000000, 1);
-	xdump((long long *)0xc0000a0003000000, 1);
-	xdump((long long *)0xc0000a0004000000, 1);
-	xdump((long long *)0xc0000a0005000000, 1);
-	xdump((long long *)0xc0000a0006000000, 1);
-	xdump((long long *)0xc0000a0007000000, 1);
-	xdump((long long *)0xc0000a0008000000, 1);
-	xdump((long long *)0xc0000a0009000000, 1);
-	xdump((long long *)0xc0000a000a000000, 1);
-	xdump((long long *)0xc0000a000b000000, 1);
-	xdump((long long *)0xc0000a000c000000, 1);
-	xdump((long long *)0xc0000a000d000000, 1);
-	xdump((long long *)0xc0000a000e000000, 1);
-	xdump((long long *)0xc0000a000f000000, 1);
-}
-
-static void
-dump_crossbow(void)
-{
-	printk("===== Dump the Crossbow regs =====\n");
-	clear_ii_error();
-	xdump32((unsigned int *)0xc0000a0000000004, 1);
-	clear_ii_error();
-	xdump32((unsigned int *)0xc0000a0000000000, 1);
-	printk("and again..\n");
-	xdump32((unsigned int *)0xc0000a0000000000, 1);
-	xdump32((unsigned int *)0xc0000a0000000000, 1);
-
-
-	clear_ii_error();
-
-	xdump32((unsigned int *)0xc000020000000004, 1);
-	clear_ii_error();
-	xdump32((unsigned int *)0xc000020000000000, 1);
-	clear_ii_error();
-
-	xdump32((unsigned int *)0xc0000a0000800004, 1);
-	clear_ii_error();
-	xdump32((unsigned int *)0xc0000a0000800000, 1);
-	clear_ii_error();
-
-	xdump32((unsigned int *)0xc000020000800004, 1);
-	clear_ii_error();
-	xdump32((unsigned int *)0xc000020000800000, 1);
-	clear_ii_error();
-
-
-}
-#endif /* DEFINE_DUMP_RTNS */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/l1.c linux-2.4.22-pre10/arch/ia64/sn/io/l1.c
--- linux-2.4.21/arch/ia64/sn/io/l1.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/l1.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,3143 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/* In general, this file is organized in a hierarchy from lower-level
- * to higher-level layers, as follows:
- *
- *	UART routines
- *	Bedrock/L1 "PPP-like" protocol implementation
- *	System controller "message" interface (allows multiplexing
- *		of various kinds of requests and responses with
- *		console I/O)
- *	Console interface:
- *	  "l1_cons", the glue that allows the L1 to act
- *		as the system console for the stdio libraries
- *
- * Routines making use of the system controller "message"-style interface
- * can be found in l1_command.c.
- */
-
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/uart16550.h>
-#include <asm/sn/simulator.h>
-
-#if defined(CONFIG_IA64_SGI_SN2)
-#define USE_SAL_CONSOLE_IO	1	/* DON'T un-def this for the simulator... */
-#endif
-
-/* Make all console writes atomic */
-#define SYNC_CONSOLE_WRITE	1
-
-
-/*********************************************************************
- * Hardware-level (UART) driver routines.
- */
-
-/* macros for reading/writing registers */
-
-#define LD(x)			(*(volatile uint64_t *)(x))
-#define SD(x, v)        	(LD(x) = (uint64_t) (v))
-
-/* location of uart receive/xmit data register */
-#if defined(CONFIG_IA64_SGI_SN1)
-#define L1_UART_BASE(n)		((ulong)REMOTE_HSPEC_ADDR((n), 0x00000080))
-#define LOCK_HUB		REMOTE_HUB_ADDR
-#elif defined(CONFIG_IA64_SGI_SN2)
-#define L1_UART_BASE(n)		((ulong)REMOTE_HUB((n), SH_JUNK_BUS_UART0))
-#define LOCK_HUB		REMOTE_HUB
-typedef u64 rtc_time_t;
-#endif
-
-
-#define ADDR_L1_REG(n, r)	( L1_UART_BASE(n) | ( (r) << 3 ) )
-#define READ_L1_UART_REG(n, r)	( LD(ADDR_L1_REG((n), (r))) )
-#define WRITE_L1_UART_REG(n, r, v) ( SD(ADDR_L1_REG((n), (r)), (v)) )
-
-/* upper layer interface calling methods */
-#define SERIAL_INTERRUPT_MODE	0
-#define SERIAL_POLLED_MODE	1
-
-
-/* UART-related #defines */
-
-#define UART_BAUD_RATE		57600
-#define UART_FIFO_DEPTH		16
-#define UART_DELAY_SPAN		10
-#define UART_PUTC_TIMEOUT	50000
-#define UART_INIT_TIMEOUT	100000
-
-/* error codes */
-#define UART_SUCCESS		  0
-#define UART_TIMEOUT		(-1)
-#define UART_LINK		(-2)
-#define UART_NO_CHAR		(-3)
-#define UART_VECTOR		(-4)
-
-#define UART_DELAY(x)		udelay(x)
-
-/* Some debug counters */
-#define L1C_INTERRUPTS		0
-#define L1C_OUR_R_INTERRUPTS	1
-#define L1C_OUR_X_INTERRUPTS	2
-#define L1C_SEND_CALLUPS	3
-#define L1C_RECEIVE_CALLUPS	4
-#define L1C_SET_BAUD		5
-#define L1C_ALREADY_LOCKED	L1C_SET_BAUD
-#define L1C_R_IRQ		6
-#define L1C_R_IRQ_RET		7
-#define L1C_LOCK_TIMEOUTS	8
-#define L1C_LOCK_COUNTER	9
-#define L1C_UNLOCK_COUNTER	10
-#define L1C_REC_STALLS		11
-#define L1C_CONNECT_CALLS	12
-#define L1C_SIZE		L1C_CONNECT_CALLS	/* Set to the last one */
-
-uint64_t L1_collectibles[L1C_SIZE + 1];
-
-
-/*
- *	Some macros for handling Endian-ness
- */
-
-#define COPY_INT_TO_BUFFER(_b, _i, _n)		\
-	{					\
-		_b[_i++] = (_n >> 24) & 0xff;	\
-		_b[_i++] = (_n >> 16) & 0xff;	\
-		_b[_i++] = (_n >>  8) & 0xff;	\
-		_b[_i++] =  _n        & 0xff;	\
-	}
-
-#define COPY_BUFFER_TO_INT(_b, _i, _n)		\
-	{					\
-		_n  = (_b[_i++] << 24) & 0xff;	\
-		_n |= (_b[_i++] << 16) & 0xff;	\
-		_n |= (_b[_i++] <<  8) & 0xff;	\
-		_n |=  _b[_i++]        & 0xff;	\
-	}
-
-#define COPY_BUFFER_TO_BUFFER(_b, _i, _bn)	\
-	{					\
-	    char *_xyz = (char *)_bn;		\
-	    _xyz[3] = _b[_i++];			\
-	    _xyz[2] = _b[_i++];			\
-	    _xyz[1] = _b[_i++];			\
-	    _xyz[0] = _b[_i++];			\
-	}
-
-void snia_kmem_free(void *where, int size);
-
-#define ALREADY_LOCKED		1
-#define NOT_LOCKED		0
-static int early_l1_serial_out(nasid_t, char *, int, int /* defines above*/ );
-
-#define BCOPY(x,y,z)	memcpy(y,x,z)
-
-uint8_t L1_interrupts_connected;		/* Non-zero when we are in interrupt mode */
-
-
-/*
- * Console locking defines and functions.
- *
- */
-
-uint8_t L1_cons_is_inited = 0;			/* non-zero when console is init'd */
-nasid_t Master_console_nasid = (nasid_t)-1;
-extern nasid_t console_nasid;
-
-#if defined(CONFIG_IA64_SGI_SN1)
-u64 ia64_sn_get_console_nasid(void);
-#endif
-
-inline nasid_t
-get_master_nasid(void)
-{
-#if defined(CONFIG_IA64_SGI_SN1)
-	nasid_t nasid = Master_console_nasid;
-
-	if ( nasid == (nasid_t)-1 ) {
-		nasid = (nasid_t)ia64_sn_get_console_nasid();
-		if ( (nasid < 0) || (nasid >= MAX_NASIDS) ) {
-			/* Out of bounds, use local */
-			console_nasid = nasid = get_nasid();
-		}
-		else {
-			/* Got a valid nasid, set the console_nasid */
-			char xx[100];
-/* zzzzzz - force nasid to 0 for now */
-			sprintf(xx, "Master console is set to nasid %d (%d)\n", 0, (int)nasid);
-nasid = 0;
-/* end zzzzzz */
-			xx[99] = (char)0;
-			early_l1_serial_out(nasid, xx, strlen(xx), NOT_LOCKED);
-			Master_console_nasid = console_nasid = nasid;
-		}
-	}
-	return(nasid);
-#else
-	return((nasid_t)0);
-#endif	/* CONFIG_IA64_SGI_SN1 */
-}
-
-
-#if defined(CONFIG_IA64_SGI_SN1)
-
-#define HUB_LOCK		16
-
-#define PRIMARY_LOCK_TIMEOUT    10000000
-#define HUB_LOCK_REG(n)         LOCK_HUB(n, MD_PERF_CNT0)
-
-#define SET_BITS(reg, bits)     SD(reg, LD(reg) |  (bits))
-#define CLR_BITS(reg, bits)     SD(reg, LD(reg) & ~(bits))
-#define TST_BITS(reg, bits)     ((LD(reg) & (bits)) != 0)
-
-#define HUB_TEST_AND_SET(n)	LD(LOCK_HUB(n,LB_SCRATCH_REG3_RZ))
-#define HUB_CLEAR(n)		SD(LOCK_HUB(n,LB_SCRATCH_REG3),0)
-
-#define RTC_TIME_MAX		((rtc_time_t) ~0ULL)
-
-/*
- * primary_lock
- *
- *   Allows CPU's 0-3  to mutually exclude the hub from one another by
- *   obtaining a blocking lock.  Does nothing if only one CPU is active.
- *
- *   This lock should be held just long enough to set or clear a global
- *   lock bit.  After a relatively short timeout period, this routine
- *   figures something is wrong, and steals the lock. It does not set
- *   any other CPU to "dead".
- */
-inline void
-primary_lock(nasid_t nasid)
-{
-	rtc_time_t          expire;
-
-	expire = rtc_time() + PRIMARY_LOCK_TIMEOUT;
-
-	while (HUB_TEST_AND_SET(nasid)) {
-		if (rtc_time() > expire) {
-			HUB_CLEAR(nasid);
-		}
-	}
-}
-
-/*
- * primary_unlock (internal)
- *
- *   Counterpart to primary_lock
- */
-
-inline void
-primary_unlock(nasid_t nasid)
-{
-	HUB_CLEAR(nasid);
-}
-
-/*
- * hub_unlock
- *
- *   Counterpart to hub_lock_timeout and hub_lock
- */
-
-inline void
-hub_unlock(nasid_t nasid, int level)
-{
-	uint64_t mask = 1ULL << level;
-
-	primary_lock(nasid);
-	CLR_BITS(HUB_LOCK_REG(nasid), mask);
-	primary_unlock(nasid);
-}
-
-/*
- * hub_lock_timeout
- *
- *   Uses primary_lock to implement multiple lock levels.
- *
- *   There are 20 lock levels from 0 to 19 (limited by the number of bits
- *   in HUB_LOCK_REG).  To prevent deadlock, multiple locks should be
- *   obtained in order of increasingly higher level, and released in the
- *   reverse order.
- *
- *   A timeout value of 0 may be used for no timeout.
- *
- *   Returns 0 if successful, -1 if lock times out.
- */
-
-inline int
-hub_lock_timeout(nasid_t nasid, int level, rtc_time_t timeout)
-{
-	uint64_t mask = 1ULL << level;
-	rtc_time_t expire = (timeout ?  rtc_time() + timeout : RTC_TIME_MAX);
-	int done    = 0;
-
-	while (! done) {
-		while (TST_BITS(HUB_LOCK_REG(nasid), mask)) {
-			if (rtc_time() > expire)
-				return -1;
-		}
-
-		primary_lock(nasid);
-
-		if (! TST_BITS(HUB_LOCK_REG(nasid), mask)) {
-			SET_BITS(HUB_LOCK_REG(nasid), mask);
-			done = 1;
-		}
-		primary_unlock(nasid);
-	}
-	return 0;
-}
-
-
-#define LOCK_TIMEOUT	(0x1500000 * 1) /* 0x1500000 is ~30 sec */
-
-void
-lock_console(nasid_t nasid)
-{
-	int ret;
-
-	/* If we already have it locked, just return */
-	L1_collectibles[L1C_LOCK_COUNTER]++;
-
-	ret = hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
-	if ( ret != 0 ) {
-		L1_collectibles[L1C_LOCK_TIMEOUTS]++;
-		/* timeout */
-		hub_unlock(nasid, HUB_LOCK);
-		/* If the 2nd lock fails, just pile ahead.... */
-		hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
-		L1_collectibles[L1C_LOCK_TIMEOUTS]++;
-	}
-}
-
-inline void
-unlock_console(nasid_t nasid)
-{
-	L1_collectibles[L1C_UNLOCK_COUNTER]++;
-	hub_unlock(nasid, HUB_LOCK);
-}
-
-#else /* SN2 */
-inline void lock_console(nasid_t n)	{}
-inline void unlock_console(nasid_t n)	{}
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-int 
-get_L1_baud(void)
-{
-    return UART_BAUD_RATE;
-}
-
-
-/* uart driver functions */
-
-static inline void
-uart_delay( rtc_time_t delay_span )
-{
-    UART_DELAY( delay_span );
-}
-
-#define UART_PUTC_READY(n)      (READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE)
-
-static int
-uart_putc( l1sc_t *sc ) 
-{
-    WRITE_L1_UART_REG( sc->nasid, REG_DAT, sc->send[sc->sent] );
-    return UART_SUCCESS;
-}
-
-
-static int
-uart_getc( l1sc_t *sc )
-{
-    u_char lsr_reg = 0;
-    nasid_t nasid = sc->nasid;
-
-    if( (lsr_reg = READ_L1_UART_REG( nasid, REG_LSR )) & 
-	(LSR_RCA | LSR_PARERR | LSR_FRMERR) ) 
-    {
-	if( lsr_reg & LSR_RCA ) 
-	    return( (u_char)READ_L1_UART_REG( nasid, REG_DAT ) );
-	else if( lsr_reg & (LSR_PARERR | LSR_FRMERR) ) {
-	    return UART_LINK;
-	}
-    }
-
-    return UART_NO_CHAR;
-}
-
-
-#define PROM_SER_CLK_SPEED	12000000
-#define PROM_SER_DIVISOR(x)	(PROM_SER_CLK_SPEED / ((x) * 16))
-
-static void
-uart_init( l1sc_t *sc, int baud )
-{
-    rtc_time_t expire;
-    int clkdiv;
-    nasid_t nasid;
-
-    clkdiv = PROM_SER_DIVISOR(baud);
-    expire = rtc_time() + UART_INIT_TIMEOUT;
-    nasid = sc->nasid;
-    
-    /* make sure the transmit FIFO is empty */
-    while( !(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XSRE) ) {
-	uart_delay( UART_DELAY_SPAN );
-	if( rtc_time() > expire ) {
-	    break;
-	}
-    }
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* Setup for the proper baud rate */
-    WRITE_L1_UART_REG( nasid, REG_LCR, LCR_DLAB );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_DLH, (clkdiv >> 8) & 0xff );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_DLL, clkdiv & 0xff );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* set operating parameters and set DLAB to 0 */
-
-    /* 8bit, one stop, clear request to send, auto flow control */
-    WRITE_L1_UART_REG( nasid, REG_LCR, LCR_BITS8 | LCR_STOP1 );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_MCR, MCR_RTS | MCR_AFE );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* disable interrupts */
-    WRITE_L1_UART_REG( nasid, REG_ICR, 0x0 );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* enable FIFO mode and reset both FIFOs, trigger on 1 */
-    WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO | RxLVL0);
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-}
-
-/* This requires the console lock */
-
-#if	defined(CONFIG_IA64_SGI_SN1)
-
-static void
-uart_intr_enable( l1sc_t *sc, u_char mask )
-{
-    u_char lcr_reg, icr_reg;
-    nasid_t nasid = sc->nasid;
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* make sure that the DLAB bit in the LCR register is 0
-     */
-    lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
-    lcr_reg &= ~(LCR_DLAB);
-    WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg );
-
-    /* enable indicated interrupts
-     */
-    icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
-    icr_reg |= mask;
-    WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-}
-
-/* This requires the console lock */
-static void
-uart_intr_disable( l1sc_t *sc, u_char mask )
-{
-    u_char lcr_reg, icr_reg;
-    nasid_t nasid = sc->nasid;
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* make sure that the DLAB bit in the LCR register is 0
-     */
-    lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
-    lcr_reg &= ~(LCR_DLAB);
-    WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg );
-
-    /* enable indicated interrupts
-     */
-    icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
-    icr_reg &= mask;
-    WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-}
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-#define uart_enable_xmit_intr(sc) \
-	uart_intr_enable((sc), ICR_TIEN)
-
-#define uart_disable_xmit_intr(sc) \
-        uart_intr_disable((sc), ~(ICR_TIEN))
-
-#define uart_enable_recv_intr(sc) \
-        uart_intr_enable((sc), ICR_RIEN)
-
-#define uart_disable_recv_intr(sc) \
-        uart_intr_disable((sc), ~(ICR_RIEN))
-
-
-/*********************************************************************
- * Routines for accessing a remote (router) UART
- */
-
-#define READ_RTR_L1_UART_REG(p, n, r, v)		\
-    {							\
-	if( vector_read_node( (p), (n), 0,		\
-			      RR_JBUS1(r), (v) ) ) {	\
-	    return UART_VECTOR;				\
-	}						\
-    }
-
-#define WRITE_RTR_L1_UART_REG(p, n, r, v)		\
-    {							\
-	if( vector_write_node( (p), (n), 0,		\
-			       RR_JBUS1(r), (v) ) ) {	\
-	    return UART_VECTOR;				\
-	}						\
-    }
-
-#define RTR_UART_PUTC_TIMEOUT	UART_PUTC_TIMEOUT*10
-#define RTR_UART_DELAY_SPAN	UART_DELAY_SPAN
-#define RTR_UART_INIT_TIMEOUT	UART_INIT_TIMEOUT*10
-
-static int
-rtr_uart_putc( l1sc_t *sc )
-{
-    uint64_t regval, c;
-    nasid_t nasid = sc->nasid;
-    net_vec_t path = sc->uart;
-    rtc_time_t expire = rtc_time() + RTR_UART_PUTC_TIMEOUT;
-
-    c = (sc->send[sc->sent] & 0xffULL);
-    
-    while( 1 ) 
-    {
-        /* Check for "tx hold reg empty" bit. */
-	READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-	if( regval & LSR_XHRE )
-	{
-	    WRITE_RTR_L1_UART_REG( path, nasid, REG_DAT, c );
-	    return UART_SUCCESS;
-	}
-
-	if( rtc_time() >= expire ) 
-	{
-	    return UART_TIMEOUT;
-	}
-	uart_delay( RTR_UART_DELAY_SPAN );
-    }
-}
-
-
-static int
-rtr_uart_getc( l1sc_t *sc )
-{
-    uint64_t regval;
-    nasid_t nasid = sc->nasid;
-    net_vec_t path = sc->uart;
-
-    READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-    if( regval & (LSR_RCA | LSR_PARERR | LSR_FRMERR) )
-    {
-	if( regval & LSR_RCA )
-	{
-	    READ_RTR_L1_UART_REG( path, nasid, REG_DAT, &regval );
-	    return( (int)regval );
-	}
-	else
-	{
-	    return UART_LINK;
-	}
-    }
-
-    return UART_NO_CHAR;
-}
-
-
-static int
-rtr_uart_init( l1sc_t *sc, int baud )
-{
-    rtc_time_t expire;
-    int clkdiv;
-    nasid_t nasid;
-    net_vec_t path;
-    uint64_t regval;
-
-    clkdiv = PROM_SER_DIVISOR(baud);
-    expire = rtc_time() + RTR_UART_INIT_TIMEOUT;
-    nasid = sc->nasid;
-    path = sc->uart;
-
-    /* make sure the transmit FIFO is empty */
-    while(1) {
-	READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-	if( regval & LSR_XSRE ) {
-	    break;
-	}
-	if( rtc_time() > expire ) {
-	    break;
-	}
-	uart_delay( RTR_UART_DELAY_SPAN );
-    }
-
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_DLAB  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_DLH, (clkdiv >> 8) & 0xff  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_DLL, clkdiv & 0xff  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* set operating parameters and set DLAB to 0 */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_BITS8 | LCR_STOP1  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_MCR, MCR_RTS | MCR_AFE  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* disable interrupts */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_ICR, 0x0  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* enable FIFO mode and reset both FIFOs */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR, FCR_FIFOEN  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR,
-	FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO );
-
-    return 0;
-}
-
-/*********************************************************************
- * locking macros 
- */
-
-#define L1SC_SEND_LOCK(l,p)   { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->send_lock),p); }
-#define L1SC_SEND_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->send_lock), p); }
-#define L1SC_RECV_LOCK(l,p)   { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->recv_lock), p); } 
-#define L1SC_RECV_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->recv_lock), p); }
-
-
-/*********************************************************************
- * subchannel manipulation 
- *
- * The SUBCH_[UN]LOCK macros are used to arbitrate subchannel
- * allocation.  SUBCH_DATA_[UN]LOCK control access to data structures
- * associated with particular subchannels (e.g., receive queues).
- *
- */
-#define SUBCH_LOCK(sc, p)		spin_lock_irqsave( &((sc)->subch_lock), p )
-#define SUBCH_UNLOCK(sc, p)		spin_unlock_irqrestore( &((sc)->subch_lock), p )
-#define SUBCH_DATA_LOCK(sbch, p) 	spin_lock_irqsave( &((sbch)->data_lock), p )
-#define SUBCH_DATA_UNLOCK(sbch, p)	spin_unlock_irqrestore( &((sbch)->data_lock), p )
-
-
-/*
- * set a function to be called for subchannel ch in the event of
- * a transmission low-water interrupt from the uart
- */
-void
-subch_set_tx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
-{
-    unsigned long pl = 0;
-
-    L1SC_SEND_LOCK( sc, pl );
-#if	!defined(SYNC_CONSOLE_WRITE)
-    if ( func && !sc->send_in_use )
-	uart_enable_xmit_intr( sc );
-#endif
-    sc->subch[ch].tx_notify = func;
-    L1SC_SEND_UNLOCK(sc, pl );
-}
-
-/*
- * set a function to be called for subchannel ch when data is received
- */
-void
-subch_set_rx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    SUBCH_DATA_LOCK( subch, pl );
-    sc->subch[ch].rx_notify = func;
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-/*********************************************************************
- * Queue manipulation macros
- *
- *
- */
-#define NEXT(p)         (((p) + 1) & (BRL1_QSIZE-1)) /* assume power of 2 */
-
-#define cq_init(q)      bzero((q), sizeof (*(q)))
-#define cq_empty(q)     ((q)->ipos == (q)->opos)
-#define cq_full(q)      (NEXT((q)->ipos) == (q)->opos)
-#define cq_used(q)      ((q)->opos <= (q)->ipos ?                       \
-                         (q)->ipos - (q)->opos :                        \
-                         BRL1_QSIZE + (q)->ipos - (q)->opos)
-#define cq_room(q)      ((q)->opos <= (q)->ipos ?                       \
-                         BRL1_QSIZE - 1 + (q)->opos - (q)->ipos :       \
-                         (q)->opos - (q)->ipos - 1)
-#define cq_add(q, c)    ((q)->buf[(q)->ipos] = (u_char) (c),            \
-                         (q)->ipos = NEXT((q)->ipos))
-#define cq_rem(q, c)    ((c) = (q)->buf[(q)->opos],                     \
-                         (q)->opos = NEXT((q)->opos))
-#define cq_discard(q)	((q)->opos = NEXT((q)->opos))
-
-#define cq_tent_full(q)	(NEXT((q)->tent_next) == (q)->opos)
-#define cq_tent_len(q)	((q)->ipos <= (q)->tent_next ?			\
-			 (q)->tent_next - (q)->ipos :			\
-			 BRL1_QSIZE + (q)->tent_next - (q)->ipos)
-#define cq_tent_add(q, c)						\
-			((q)->buf[(q)->tent_next] = (u_char) (c),	\
-			 (q)->tent_next = NEXT((q)->tent_next))
-#define cq_commit_tent(q)						\
-			((q)->ipos = (q)->tent_next)
-#define cq_discard_tent(q)						\
-			((q)->tent_next = (q)->ipos)
-
-
-
-
-/*********************************************************************
- * CRC-16 (for checking bedrock/L1 packets).
- *
- * These are based on RFC 1662 ("PPP in HDLC-like framing").
- */
-
-static unsigned short fcstab[256] = {
-      0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
-      0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
-      0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
-      0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
-      0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
-      0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
-      0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
-      0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
-      0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
-      0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
-      0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
-      0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
-      0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
-      0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
-      0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
-      0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
-      0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
-      0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
-      0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
-      0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
-      0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
-      0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
-      0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
-      0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
-      0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
-      0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
-      0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
-      0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
-      0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
-      0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
-      0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
-      0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
-};
-
-#define INIT_CRC	0xFFFF	/* initial CRC value	  */
-#define	GOOD_CRC	0xF0B8	/* "good" final CRC value */
-
-static unsigned short crc16_calc( unsigned short crc, u_char c )
-{
-    return( (crc >> 8) ^ fcstab[(crc ^ c) & 0xff] );
-}
-
-
-/***********************************************************************
- * The following functions implement the PPP-like bedrock/L1 protocol
- * layer.
- *
- */
-
-#define BRL1_FLAG_CH	0x7e
-#define BRL1_ESC_CH	0x7d
-#define BRL1_XOR_CH	0x20
-
-/* L1<->Bedrock packet types */
-#define BRL1_REQUEST    0x00
-#define BRL1_RESPONSE   0x20
-#define BRL1_EVENT      0x40
-
-#define BRL1_PKT_TYPE_MASK      0xE0
-#define BRL1_SUBCH_MASK         0x1F
-
-#define PKT_TYPE(tsb)   ((tsb) & BRL1_PKT_TYPE_MASK)
-#define SUBCH(tsb)	((tsb) & BRL1_SUBCH_MASK)
-
-/* timeouts */
-#define BRL1_INIT_TIMEOUT	500000
-
-/*
- * brl1_discard_packet is a dummy "receive callback" used to get rid
- * of packets we don't want
- */
-void brl1_discard_packet( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &sc->subch[ch];
-
-    sc_cq_t *q = subch->iqp;
-    SUBCH_DATA_LOCK( subch, pl );
-    q->opos = q->ipos;
-    atomic_set(&(subch->packet_arrived), 0);
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-
-/*
- * brl1_send_chars sends the send buffer in the l1sc_t structure
- * out through the uart.  Assumes that the caller has locked the
- * UART (or send buffer in the kernel).
- *
- * This routine doesn't block-- if you want it to, call it in
- * a loop.
- */
-static int
-brl1_send_chars( l1sc_t *sc )
-{
-    /* We track the depth of the C brick's UART's
-     * fifo in software, and only check if the UART is accepting
-     * characters when our count indicates that the fifo should
-     * be full.
-     *
-     * For remote (router) UARTs, we check with the UART before sending every
-     * character.
-     */
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	if( !(sc->fifo_space) && UART_PUTC_READY( sc->nasid ) )
-	    sc->fifo_space = UART_FIFO_DEPTH;
-	
-	while( (sc->sent < sc->send_len) && (sc->fifo_space) ) {
-	    uart_putc( sc );
-	    sc->fifo_space--;
-	    sc->sent++;
-	}
-    }
-    else {
-
-	/* remote (router) UARTs */
-
-	int result;
-	int tries = 0;
-
-	while( sc->sent < sc->send_len ) {
-	    result = sc->putc_f( sc );
-	    if( result >= 0 ) {
-		(sc->sent)++;
-		continue;
-	    }
-	    if( result == UART_TIMEOUT ) {
-		tries++;
-		/* send this character in TIMEOUT_RETRIES... */
-		if( tries < 30 /* TIMEOUT_RETRIES */ ) {
-		    continue;
-		}
-		/* ...or else... */
-		else {
-		    /* ...drop the packet. */
-		    sc->sent = sc->send_len;
-		    return sc->send_len;
-		}
-	    }
-	    if( result < 0 ) {
-		return result;
-	    }
-	}
-    }
-    return sc->sent;
-}
-
-
-/* brl1_send formats up a packet and (at least begins to) send it
- * to the uart.  If the send buffer is in use when this routine obtains
- * the lock, it will behave differently depending on the "wait" parameter.
- * For wait == 0 (most I/O), it will return 0 (as in "zero bytes sent"),
- * hopefully encouraging the caller to back off (unlock any high-level 
- * spinlocks) and allow the buffer some time to drain.  For wait==1 (high-
- * priority I/O along the lines of kernel error messages), we will flush
- * the current contents of the send buffer and beat on the uart
- * until our message has been completely transmitted.
- */
-
-static int
-brl1_send( l1sc_t *sc, char *msg, int len, u_char type_and_subch, int wait )
-{
-    unsigned long pl = 0;
-    int index;
-    int pkt_len = 0;
-    unsigned short crc = INIT_CRC;
-    char *send_ptr = sc->send;
-
-
-    if( sc->send_in_use && !(wait) ) {
-	/* We are in the middle of sending, but can wait until done */
-	return 0;
-    }
-    else if( sc->send_in_use ) {
-	/* buffer's in use, but we're synchronous I/O, so we're going
-	 * to send whatever's in there right now and take the buffer
-	 */
-	int counter = 0;
-
-	if ( sc->uart == BRL1_LOCALHUB_UART )
-		lock_console(sc->nasid);
-	L1SC_SEND_LOCK(sc, pl);
-	while( sc->sent < sc->send_len ) {
-		brl1_send_chars( sc );
-		if ( counter++ > 0xfffff ) {
-			char *str = "Looping waiting for uart to clear (1)\n";
-			early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED);
-			break;
-		}
-	}
-    }
-    else {
-	if ( sc->uart == BRL1_LOCALHUB_UART )
-		lock_console(sc->nasid);
-	L1SC_SEND_LOCK(sc, pl);
-	sc->send_in_use = 1;
-    }
-    *send_ptr++ = BRL1_FLAG_CH;
-    *send_ptr++ = type_and_subch;
-    pkt_len += 2;
-    crc = crc16_calc( crc, type_and_subch );
-
-    /* limit number of characters accepted to max payload size */
-    if( len > (BRL1_QSIZE - 1) )
-	len = (BRL1_QSIZE - 1);
-
-    /* copy in the message buffer (inserting PPP 
-     * framing info where necessary)
-     */
-    for( index = 0; index < len; index++ ) {
-
-	switch( *msg ) {
-	    
-	  case BRL1_FLAG_CH:
-	    *send_ptr++ = BRL1_ESC_CH;
-	    *send_ptr++ = (*msg) ^ BRL1_XOR_CH;
-	    pkt_len += 2;
-	    break;
-	    
-	  case BRL1_ESC_CH:
-	    *send_ptr++ = BRL1_ESC_CH;
-	    *send_ptr++ = (*msg) ^ BRL1_XOR_CH;
-	    pkt_len += 2;
-	    break;
-	    
-	  default:
-	    *send_ptr++ = *msg;
-	    pkt_len++;
-	}
-	crc = crc16_calc( crc, *msg );
-	msg++;
-    }
-    crc ^= 0xffff;
-
-    for( index = 0; index < sizeof(crc); index++ ) {
-	char crc_char = (char)(crc & 0x00FF);
-	if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	    *send_ptr++ = BRL1_ESC_CH;
-	    pkt_len++;
-	    crc_char ^= BRL1_XOR_CH;
-	}
-	*send_ptr++ = crc_char;
-	pkt_len++;
-	crc >>= 8;
-    }
-    
-    *send_ptr++ = BRL1_FLAG_CH;
-    pkt_len++;
-
-    sc->send_len = pkt_len;
-    sc->sent = 0;
-
-    {
-	int counter = 0;
-	do {
-		brl1_send_chars( sc );
-		if ( counter++ > 0xfffff ) {
-			char *str = "Looping waiting for uart to clear (2)\n";
-			early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED);
-			break;
-		}
-	} while( (sc->sent < sc->send_len) && wait );
-    }
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(sc->nasid);
-
-    if( sc->sent == sc->send_len ) {
-	/* success! release the send buffer and call the callup */
-#if	!defined(SYNC_CONSOLE_WRITE)
-	brl1_notif_t callup;
-#endif
-
-	sc->send_in_use = 0;
-	/* call any upper layer that's asked for notification */
-#if	defined(XX_SYNC_CONSOLE_WRITE)
-	/*
-	 * This is probably not a good idea - since the l1_ write func can be called multiple
-	 * time within the callup function.
-	 */
-	callup = subch->tx_notify;
-	if( callup && (SUBCH(type_and_subch) == SC_CONS_SYSTEM) ) {
-		L1_collectibles[L1C_SEND_CALLUPS]++;
-		(*callup)(sc->subch[SUBCH(type_and_subch)].irq_frame.bf_irq,
-				sc->subch[SUBCH(type_and_subch)].irq_frame.bf_dev_id,
-				sc->subch[SUBCH(type_and_subch)].irq_frame.bf_regs, sc, SUBCH(type_and_subch));
-	}
-#endif	/* SYNC_CONSOLE_WRITE */
-    }
-#if	!defined(SYNC_CONSOLE_WRITE)
-    else if ( !wait ) {
-	/* enable low-water interrupts so buffer will be drained */
-	uart_enable_xmit_intr(sc);
-    }
-#endif
-
-    L1SC_SEND_UNLOCK(sc, pl);
-
-    return len;
-}
-
-/* brl1_send_cont is intended to be called as an interrupt service
- * routine.  It sends until the UART won't accept any more characters,
- * or until an error is encountered (in which case we surrender the
- * send buffer and give up trying to send the packet).  Once the
- * last character in the packet has been sent, this routine releases
- * the send buffer and calls any previously-registered "low-water"
- * output routines.
- */
-
-#if	!defined(SYNC_CONSOLE_WRITE)
-
-int
-brl1_send_cont( l1sc_t *sc )
-{
-    unsigned long pl = 0;
-    int done = 0;
-    brl1_notif_t callups[BRL1_NUM_SUBCHANS];
-    brl1_notif_t *callup;
-    brl1_sch_t *subch;
-    int index;
-
-    /*
-     * I'm not sure how I think this is to be handled - whether the lock is held
-     * over the interrupt - but it seems like it is a bad idea....
-     */
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(sc->nasid);
-    L1SC_SEND_LOCK(sc, pl);
-    brl1_send_chars( sc );
-    done = (sc->sent == sc->send_len);
-    if( done ) {
-	sc->send_in_use = 0;
-#if	!defined(SYNC_CONSOLE_WRITE)
-	uart_disable_xmit_intr(sc);
-#endif
-    }
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(sc->nasid);
-    /* Release the lock */
-    L1SC_SEND_UNLOCK(sc, pl);
-
-    return 0;
-}
-#endif	/* SYNC_CONSOLE_WRITE */
-
-/* internal function -- used by brl1_receive to read a character 
- * from the uart and check whether errors occurred in the process.
- */
-static int
-read_uart( l1sc_t *sc, int *c, int *result )
-{
-    *c = sc->getc_f( sc );
-
-    /* no character is available */
-    if( *c == UART_NO_CHAR ) {
-	*result = BRL1_NO_MESSAGE;
-	return 0;
-    }
-
-    /* some error in UART */
-    if( *c < 0 ) {
-	*result = BRL1_LINK;
-	return 0;
-    }
-
-    /* everything's fine */
-    *result = BRL1_VALID;
-    return 1;
-}
-
-
-/*
- * brl1_receive
- *
- * This function reads a Bedrock-L1 protocol packet into the l1sc_t
- * response buffer.
- *
- * The operation of this function can be expressed as a finite state
- * machine:
- *
-
-START STATE			INPUT		TRANSITION
-==========================================================
-BRL1_IDLE (reset or error)	flag		BRL1_FLAG
-				other		BRL1_IDLE@
-
-BRL1_FLAG (saw a flag (0x7e))	flag		BRL1_FLAG
-				escape		BRL1_IDLE@
-				header byte	BRL1_HDR
-				other		BRL1_IDLE@
-
-BRL1_HDR (saw a type/subch byte)(see below)	BRL1_BODY
-						BRL1_HDR
-
-BRL1_BODY (reading packet body)	flag		BRL1_FLAG
-				escape		BRL1_ESC
-				other		BRL1_BODY
-
-BRL1_ESC (saw an escape (0x7d))	flag		BRL1_FLAG@
-				escape		BRL1_IDLE@
-				other		BRL1_BODY
-==========================================================
-
-"@" denotes an error transition.
-
- * The BRL1_HDR state is a transient state which doesn't read input,
- * but just provides a way in to code which decides to whom an
- * incoming packet should be directed.
- *
- * brl1_receive can be used to poll for input from the L1, or as 
- * an interrupt service routine.  It reads as much data as is
- * ready from the junk bus UART and places into the appropriate
- * input queues according to subchannel.  The header byte is
- * stripped from console-type data, but is retained for message-
- * type data (L1 responses).  A length byte will also be
- * prepended to message-type packets.
- *
- * This routine is non-blocking; if the caller needs to block
- * for input, it must call brl1_receive in a loop.
- *
- * brl1_receive returns when there is no more input, the queue
- * for the current incoming message is full, or there is an
- * error (parity error, bad header, bad CRC, etc.).
- */
-
-#define STATE_SET(l,s)		((l)->brl1_state = (s))
-#define STATE_GET(l)		((l)->brl1_state)
-
-#define LAST_HDR_SET(l,h)	((l)->brl1_last_hdr = (h))
-#define LAST_HDR_GET(l)		((l)->brl1_last_hdr)
-
-#define VALID_HDR(c)				\
-    ( SUBCH((c)) <= SC_CONS_SYSTEM		\
-	? PKT_TYPE((c)) == BRL1_REQUEST		\
-	: ( PKT_TYPE((c)) == BRL1_RESPONSE ||	\
-	    PKT_TYPE((c)) == BRL1_EVENT ) )
-
-#define IS_TTY_PKT(l)		( SUBCH(LAST_HDR_GET(l)) <= SC_CONS_SYSTEM ? 1 : 0 )
-
-
-int
-brl1_receive( l1sc_t *sc, int mode )
-{
-    int result;		/* value to be returned by brl1_receive */
-    int c;		/* most-recently-read character	     	*/
-    int done;		/* set done to break out of recv loop	*/
-    unsigned long pl = 0, cpl = 0;
-    sc_cq_t *q;		/* pointer to queue we're working with	*/
-
-    result = BRL1_NO_MESSAGE;
-
-    L1SC_RECV_LOCK(sc, cpl);
-
-    done = 0;
-    while( !done )
-    {
-	switch( STATE_GET(sc) )
-	{
-
-	  case BRL1_IDLE:
-	    /* Initial or error state.  Waiting for a flag character
-             * to resynchronize with the L1.
-             */
-
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* saw a flag character */
-		STATE_SET( sc, BRL1_FLAG );
-		continue;
-	    }
-	    break;
-	    
-	  case BRL1_FLAG:
-	    /* One or more flag characters have been read; look for
-	     * the beginning of a packet (header byte).
-	     */
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR )
-		    STATE_SET( sc, BRL1_IDLE );
-
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* multiple flags are OK */
-		continue;
-	    }
-
-	    if( !VALID_HDR( c ) ) {
-		/* if c isn't a flag it should have been
-		 * a valid header, so we have an error
-		 */
-		result = BRL1_PROTOCOL;
-		STATE_SET( sc, BRL1_IDLE );
-		done = 1;
-		continue;
-	    }
-
-	    /* we have a valid header byte */
-	    LAST_HDR_SET( sc, c );
-	    STATE_SET( sc, BRL1_HDR );
-
-	    break; 
-
-	  case BRL1_HDR:
-	    /* A header byte has been read. Do some bookkeeping. */
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-	    
-	    if( !IS_TTY_PKT(sc) ) {
-		/* if this is an event or command response rather
-		 * than console I/O, we need to reserve a couple
-		 * of extra spaces in the queue for the header
-		 * byte and a length byte; if we can't, stay in
-		 * the BRL1_HDR state.
-		 */
-		if( cq_room( q ) < 2 ) {
-		    result = BRL1_FULL_Q;
-		    done = 1;
-		    continue;
-		}
-		cq_tent_add( q, 0 );			/* reserve length byte */
-		cq_tent_add( q, LAST_HDR_GET( sc ) );	/* record header byte  */
-	    }
-	    STATE_SET( sc, BRL1_BODY );
-
-	    break;
-
-	  case BRL1_BODY:
-	    /* A header byte has been read.  We are now attempting
-	     * to receive the packet body.
-	     */
-
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-
-	    /* if the queue we want to write into is full, don't read from
-	     * the uart (this provides backpressure to the L1 side)
-	     */
-	    if( cq_tent_full( q ) ) {
-		result = BRL1_FULL_Q;
-		done = 1;
-		continue;
-	    }
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR )
-		    STATE_SET( sc, BRL1_IDLE );
-		done = 1;
-		continue;
-	    }
-
-	    if( c == BRL1_ESC_CH ) {
-		/* prepare to unescape the next character */
-		STATE_SET( sc, BRL1_ESC );
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* flag signifies the end of a packet */
-
-		unsigned short crc;	/* holds the crc as we calculate it */
-		int i;			/* index variable */
-		brl1_sch_t *subch;      /* subchannel for received packet */
-		brl1_notif_t callup;	/* "data ready" callup */
-
-		/* whatever else may happen, we've seen a flag and we're
-		 * starting a new packet
-		 */
-		STATE_SET( sc, BRL1_FLAG );
-
-		/* if the packet body has less than 2 characters,
-		 * it can't be a well-formed packet.  Discard it.
-		 */
-		if( cq_tent_len( q ) < /* 2 + possible length byte */
-		    (2 + (IS_TTY_PKT(sc) ? 0 : 1)) )
-		{
-		    result = BRL1_PROTOCOL;
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_FLAG );
-		    done = 1;
-		    continue;
-		}
-		
-		/* check CRC */
-
-		/* accumulate CRC, starting with the header byte and
-		 * ending with the transmitted CRC.  This should
-		 * result in a known good value.
-		 */
-		crc = crc16_calc( INIT_CRC, LAST_HDR_GET(sc) );
-		for( i = (q->ipos + (IS_TTY_PKT(sc) ? 0 : 2)) % BRL1_QSIZE;
-		     i != q->tent_next;
-		     i = (i + 1) % BRL1_QSIZE )
-		{
-		    crc = crc16_calc( crc, q->buf[i] );
-		}
-
-		/* verify the caclulated crc against the "good" crc value;
-		 * if we fail, discard the bad packet and return an error.
-		 */
-		if( crc != (unsigned short)GOOD_CRC ) {
-		    result = BRL1_CRC;
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_FLAG );
-		    done = 1;
-		    continue;
-		}
-		
-		/* so the crc check was ok.  Now we discard the CRC
-		 * from the end of the received bytes.
-		 */
-		q->tent_next += (BRL1_QSIZE - 2);
-		q->tent_next %= BRL1_QSIZE;
-
-		/* get the subchannel and lock it */
-		subch = &(sc->subch[SUBCH( LAST_HDR_GET(sc) )]);
-		SUBCH_DATA_LOCK( subch, pl );
-		
-		/* if this isn't a console packet, we need to record
-		 * a length byte
-		 */
-		if( !IS_TTY_PKT(sc) ) {
-		    q->buf[q->ipos] = cq_tent_len( q ) - 1;
-		}
-		
-		/* record packet for posterity */
-		cq_commit_tent( q );
-		result = BRL1_VALID;
-
-		/* notify subchannel owner that there's something
-		 * on the queue for them
-		 */
-		atomic_inc(&(subch->packet_arrived));
-		callup = subch->rx_notify;
-		SUBCH_DATA_UNLOCK( subch, pl );
-
-		if( callup && (mode == SERIAL_INTERRUPT_MODE) ) {
-		    L1SC_RECV_UNLOCK( sc, cpl );
-		    L1_collectibles[L1C_RECEIVE_CALLUPS]++;
-		    (*callup)( sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_irq,
-				sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_dev_id,
-				sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_regs,
-				sc, SUBCH(LAST_HDR_GET(sc)) );
-		    L1SC_RECV_LOCK( sc, cpl );
-		}
-		continue;	/* go back for more! */
-	    }
-	    
-	    /* none of the special cases applied; we've got a normal
-	     * body character
-	     */
-	    cq_tent_add( q, c );
-
-	    break;
-
-	  case BRL1_ESC:
-	    /* saw an escape character.  The next character will need
-	     * to be unescaped.
-	     */
-
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-
-	    /* if the queue we want to write into is full, don't read from
-	     * the uart (this provides backpressure to the L1 side)
-	     */
-	    if( cq_tent_full( q ) ) {
-		result = BRL1_FULL_Q;
-		done = 1;
-		continue;
-	    }
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR ) {
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_IDLE );
-		}
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* flag after escape is an error */
-		STATE_SET( sc, BRL1_FLAG );
-		cq_discard_tent( q );
-		result = BRL1_PROTOCOL;
-		done = 1;
-		continue;
-	    }
-
-	    if( c == BRL1_ESC_CH ) {
-		/* two consecutive escapes is an error */
-		STATE_SET( sc, BRL1_IDLE );
-		cq_discard_tent( q );
-		result = BRL1_PROTOCOL;
-		done = 1;
-		continue;
-	    }
-	    
-	    /* otherwise, we've got a character that needs
-	     * to be unescaped
-	     */
-	    cq_tent_add( q, (c ^ BRL1_XOR_CH) );
-	    STATE_SET( sc, BRL1_BODY );
-
-	    break;
-
-	} /* end of switch( STATE_GET(sc) ) */
-    } /* end of while(!done) */
-
-    L1SC_RECV_UNLOCK( sc, cpl );
-
-    return result;
-}	    
-
-
-/* brl1_init initializes the Bedrock/L1 protocol layer.  This includes
- * zeroing out the send and receive state information.
- */
-
-void
-brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    int i;
-    brl1_sch_t *subch;
-
-    bzero( sc, sizeof( *sc ) );
-    sc->nasid = nasid;
-    sc->uart = uart;
-    sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc);
-    sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc);
-    sc->sol = 1;
-    subch = sc->subch;
-
-    /* initialize L1 subchannels
-     */
-
-    /* assign processor TTY channels */
-    for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_RSVD;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	spin_lock_init( &(subch->data_lock) );
-	sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );
-	subch->tx_notify = NULL;
-	/* (for now, drop elscuart packets in the kernel) */
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* assign system TTY channel (first free subchannel after each
-     * processor's individual TTY channel has been assigned)
-     */
-    subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = ATOMIC_INIT(0);
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &subch->data_lock, SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );
-    subch->tx_notify = NULL;
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, NASID_TO_COMPACT_NODEID(nasid) );
-	ASSERT( subch->iqp );
-	cq_init( subch->iqp );
-	subch->rx_notify = NULL;
-    }
-    else {
-	/* we shouldn't be getting console input from remote UARTs */
-	subch->iqp = &sc->garbage_q;
-	subch->rx_notify = brl1_discard_packet;
-    }
-    subch++; i++;
-
-    /* "reserved" subchannels (0x05-0x0F); for now, throw away
-     * incoming packets
-     */
-    for( ; i < 0x10; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* remaining subchannels are free */
-    for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* initialize synchronization structures
-     */
-    spin_lock_init( &(sc->subch_lock) );
-    spin_lock_init( &(sc->send_lock) );
-    spin_lock_init( &(sc->recv_lock) );
-
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	uart_init( sc, UART_BAUD_RATE );
-    }
-    else {
-	rtr_uart_init( sc, UART_BAUD_RATE );
-    }
-
-    /* Set up remaining fields using L1 command functions-- elsc_module_get
-     * to read the module id, elsc_debug_get to see whether or not we're
-     * in verbose mode.
-     */
-    {
-	extern int elsc_module_get(l1sc_t *);
-
-	sc->modid = elsc_module_get( sc );
-	sc->modid = (sc->modid < 0 ? INVALID_MODULE : sc->modid);
-	sc->verbose = 1;
-    }
-}
-
-/*********************************************************************
- * These are interrupt-related functions used in the kernel to service
- * the L1.
- */
-
-/*
- * brl1_intrd is the function which is called on a console interrupt.
- */
-
-#if defined(CONFIG_IA64_SGI_SN1)
-
-static void
-brl1_intrd(int irq, void *dev_id, struct pt_regs *stuff)
-{
-    u_char isr_reg;
-    l1sc_t *sc = get_elsc();
-    int ret;
-
-    L1_collectibles[L1C_INTERRUPTS]++;
-    isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-
-    /* Save for callup args in console */
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_irq = irq;
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_dev_id = dev_id;
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_regs = stuff;
-
-#if	defined(SYNC_CONSOLE_WRITE)
-    while( isr_reg & ISR_RxRDY )
-#else
-    while( isr_reg & (ISR_RxRDY | ISR_TxRDY) )
-#endif
-    {
-	if( isr_reg & ISR_RxRDY ) {
-	    L1_collectibles[L1C_OUR_R_INTERRUPTS]++;
-	    ret = brl1_receive(sc, SERIAL_INTERRUPT_MODE);
-	    if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) )
-		L1_collectibles[L1C_REC_STALLS] = ret;
-	}
-#if	!defined(SYNC_CONSOLE_WRITE)
-	if( (isr_reg & ISR_TxRDY) || (sc->send_in_use && UART_PUTC_READY(sc->nasid)) ) {
-	    L1_collectibles[L1C_OUR_X_INTERRUPTS]++;
-	    brl1_send_cont(sc);
-	}
-#endif	/* SYNC_CONSOLE_WRITE */
-	isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-    }
-}
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-
-/*
- * Install a callback function for the system console subchannel 
- * to allow an upper layer to be notified when the send buffer 
- * has been emptied.
- */
-static inline void
-l1_tx_notif( brl1_notif_t func )
-{
-	subch_set_tx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,
-			SC_CONS_SYSTEM, func );
-}
-
-
-/*
- * Install a callback function for the system console subchannel
- * to allow an upper layer to be notified when a packet has been
- * received.
- */
-static inline void
-l1_rx_notif( brl1_notif_t func )
-{
-	subch_set_rx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,
-				SC_CONS_SYSTEM, func );
-}
-
-
-/* brl1_intr is called directly from the uart interrupt; after it runs, the
- * interrupt "daemon" xthread is signalled to continue.
- */
-void
-brl1_intr( void )
-{
-}
-
-#define BRL1_INTERRUPT_LEVEL	65	/* linux request_irq() value */
-
-/* Return the current interrupt level */
-
-//#define CONSOLE_POLLING_ALSO
-
-int
-l1_get_intr_value( void )
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	return(0);
-#else
-#if defined(CONSOLE_POLLING_ALSO)
-	return(0);
-#else
-	return(BRL1_INTERRUPT_LEVEL);
-#endif /* CONSOLE_POLLING_ALSO */
-#endif /* USE_SAL_CONSOLE_IO */
-}
-
-/* Disconnect the callup functions - throw away interrupts */
-
-void
-l1_unconnect_intr(void)
-{
-#if !defined(USE_SAL_CONSOLE_IO)
-	/* UnRegister the upper-level callup functions */
-	l1_rx_notif((brl1_notif_t)NULL);
-	l1_tx_notif((brl1_notif_t)NULL);
-	/* We do NOT unregister the interrupts */
-#endif /* !USE_SAL_CONSOLE_IO */
-}
-
-/* Set up uart interrupt handling for this node's uart */
-
-void
-l1_connect_intr(void *rx_notify, void *tx_notify)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-#if 0
-	// Will need code here for sn2 - something like this
-	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid());
-	intr_connect_level(console_nodepda->node_first_cpu,
-                                SGI_UART_VECTOR, INTPEND0_MAXMASK,
-                                dummy_intr_func);
-	request_irq(SGI_UART_VECTOR | (console_nodepda->node_first_cpu << 8),
-                                intr_func, SA_INTERRUPT | SA_SHIRQ,
-                                "l1_protocol_driver", (void *)sc);
-#endif
-#else
-	l1sc_t *sc;
-	nasid_t nasid;
-#if defined(CONFIG_IA64_SGI_SN1)
-	int tmp;
-#endif
-	nodepda_t *console_nodepda;
-	int intr_connect_level(cpuid_t, int, ilvl_t, intr_func_t);
-
-	if ( L1_interrupts_connected ) {
-		/* Interrupts are connected, so just register the callups */
-		l1_rx_notif((brl1_notif_t)rx_notify);
-		l1_tx_notif((brl1_notif_t)tx_notify);
-
-		L1_collectibles[L1C_CONNECT_CALLS]++;
-		return;
-	}
-	else
-		L1_interrupts_connected = 1;
-
-	nasid = get_master_nasid();
-	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(nasid));
-	sc = &console_nodepda->module->elsc;
-	sc->intr_cpu = console_nodepda->node_first_cpu;
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	if ( intr_connect_level(sc->intr_cpu, UART_INTR, INTPEND0_MAXMASK, (intr_func_t)brl1_intr) ) {
-		L1_interrupts_connected = 0; /* FAILS !! */
-	}
-	else {
-		void synergy_intr_connect(int, int);
-
-		synergy_intr_connect(UART_INTR, sc->intr_cpu);
-		L1_collectibles[L1C_R_IRQ]++;
-		tmp = request_irq(BRL1_INTERRUPT_LEVEL, brl1_intrd, SA_INTERRUPT | SA_SHIRQ, "l1_protocol_driver", (void *)sc);
-		L1_collectibles[L1C_R_IRQ_RET] = (uint64_t)tmp;
-		if ( tmp ) {
-			L1_interrupts_connected = 0; /* FAILS !! */
-		}
-		else {
-			/* Register the upper-level callup functions */
-			l1_rx_notif((brl1_notif_t)rx_notify);
-			l1_tx_notif((brl1_notif_t)tx_notify);
-
-			/* Set the uarts the way we like it */
-			uart_enable_recv_intr( sc );
-			uart_disable_xmit_intr( sc );
-		}
-	}
-#endif	/* CONFIG_IA64_SGI_SN1 */
-#endif	/* USE_SAL_CONSOLE_IO */
-}
-
-
-/* These are functions to use from serial_in/out when in protocol
- * mode to send and receive uart control regs. These are external
- * interfaces into the protocol driver.
- */
-
-void
-l1_control_out(int offset, int value)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	/* quietly ignore unless simulator */
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		if ( master_node_bedrock_address != (u64)0 ) {
-			writeb(value, (unsigned long)master_node_bedrock_address +
-				(offset<< 3));
-		}
-		return;
-	}
-#else
-	nasid_t nasid = get_master_nasid();
-	WRITE_L1_UART_REG(nasid, offset, value); 
-#endif
-}
-
-/* Console input exported interface. Return a register value.  */
-
-int
-l1_control_in_polled(int offset)
-{
-	static int l1_control_in_local(int, int);
-
-	return(l1_control_in_local(offset, SERIAL_POLLED_MODE));
-}
-
-int
-l1_control_in(int offset)
-{
-	static int l1_control_in_local(int, int);
-
-	return(l1_control_in_local(offset, SERIAL_INTERRUPT_MODE));
-}
-
-static int
-l1_control_in_local(int offset, int mode)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	int sal_call_status = 0, input;
-	int ret = 0;
-
-	if ( offset == REG_LSR ) {
-		ret = (LSR_XHRE | LSR_XSRE);	/* can send anytime */
-		sal_call_status = ia64_sn_console_check(&input);
-		if ( !sal_call_status && input ) {
-			/* input pending */
-			ret |= LSR_RCA;
-		}
-	}
-
-	/* If the sal call failed, do it the old-fashioned way */
-	if ( sal_call_status ) {
-		if ( IS_RUNNING_ON_SIMULATOR() ) {
-			extern u64 master_node_bedrock_address;
-			ret = readb((unsigned long)master_node_bedrock_address +
-					(offset<< 3));
-		}		
-		else {
-#endif	/* USE_SAL_CONSOLE_IO */
-			nasid_t nasid;
-			int ret, input;
-			static int l1_poll(l1sc_t *, int);
-
-			nasid = get_master_nasid();
-			ret = READ_L1_UART_REG(nasid, offset); 
-
-			if ( offset == REG_LSR ) {
-				ret |= (LSR_XHRE | LSR_XSRE);	/* can send anytime */
-				if ( L1_cons_is_inited ) {
-					if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {
-						input = l1_poll(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, mode);
-						if ( input ) {
-							ret |= LSR_RCA;
-						}
-					}
-				}
-			}
-#if defined(USE_SAL_CONSOLE_IO)
-		}
-	}
-#endif
-	return(ret);
-}
-
-/*
- * Console input exported interface. Return a character (if one is available)
- */
-
-int
-l1_serial_in_polled(void)
-{
-	static int l1_serial_in_local(int mode);
-
-	return(l1_serial_in_local(SERIAL_POLLED_MODE));
-}
-
-int
-l1_serial_in(void)
-{
-	static int l1_serial_in_local(int mode);
-
-	return(l1_serial_in_local(SERIAL_INTERRUPT_MODE));
-}
-
-static int
-l1_serial_in_local(int mode)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	int sal_call_status;
-	int ch;
-
-	sal_call_status = ia64_sn_console_getc(&ch);
-	if ( !sal_call_status ) {
-		return(ch);
-	}
-	else {
-		/* If the sal called failed - do it the old-fashioned way */
-		if ( IS_RUNNING_ON_SIMULATOR() ) {
-			extern u64 master_node_bedrock_address;
-			return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3)));
-		}		
-		else {
-#endif	/* USE_SAL_CONSOLE_IO */
-			nasid_t nasid;
-			l1sc_t *sc;
-			int value;
-			static int l1_getc( l1sc_t *, int );
-			static inline l1sc_t *early_sc_init(nasid_t);
-
-			nasid = get_master_nasid();
-			sc = early_sc_init(nasid);
-			if ( L1_cons_is_inited ) {
-				if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {
-					sc = &NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc;
-				}
-			}
-			value = l1_getc(sc, mode);
-			return(value);
-#if defined(USE_SAL_CONSOLE_IO)
-		}
-	}
-#endif
-}
-
-/* Console output exported interface. Write message to the console.  */
-
-int
-l1_serial_out( char *str, int len )
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	int sal_call_status = 0;
-	int counter = len;
-
-	/* Attempt to write things out thru the sal */
-	while ( counter > 0 ) {
-		if ( (sal_call_status = ia64_sn_console_putc(*str)) ) {
-			break;
-		}
-		counter--;
-		str++;
-	}
-	if ( sal_call_status ) {
-		/* If the sal called failed - do it the old-fashioned way */
-		if ( IS_RUNNING_ON_SIMULATOR() ) {
-			extern u64 master_node_bedrock_address;
-                        if (!master_node_bedrock_address)
-                                early_sn_setup();
-			if ( master_node_bedrock_address != (u64)0 ) {
-#ifdef FLAG_DIRECT_CONSOLE_WRITES
-				/* This is an easy way to pre-pend the output to know whether the output
-				 * was done via sal or directly */
-				writeb('[', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				writeb('+', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				writeb(']', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				writeb(' ', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-#endif	/* FLAG_DIRECT_CONSOLE_WRITES */
-				while ( counter > 0 ) {
-					writeb(*str, (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-					counter--;
-					str++;
-				}
-			}
-		}
-		else {
-#endif	/* USE_SAL_CONSOLE_IO */
-			nasid_t nasid = get_master_nasid();
-			int l1_write(l1sc_t *, char *, int, int);
-
-			if ( L1_cons_is_inited ) {
-				if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 )
-					return(l1_write(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, str, len,
-#if	defined(SYNC_CONSOLE_WRITE)
-							1
-#else
-							!L1_interrupts_connected
-#endif
-									));
-			}
-			return(early_l1_serial_out(nasid, str, len, NOT_LOCKED));
-#if defined(USE_SAL_CONSOLE_IO)
-		}
-	}
-	return((counter <= 0) ? 0 : (len - counter));
-#endif
-}
-
-
-/*
- * These are the 'early' functions - when we need to do things before we have
- * all the structs setup.
- */
-
-
-static l1sc_t Early_console;		/* fake l1sc_t */
-static int Early_console_inited = 0;
-
-static void
-early_brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    int i;
-    brl1_sch_t *subch;
-
-    bzero( sc, sizeof( *sc ) );
-    sc->nasid = nasid;
-    sc->uart = uart;
-    sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc);
-    sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc);
-    sc->sol = 1;
-    subch = sc->subch;
-
-    /* initialize L1 subchannels
-     */
-
-    /* assign processor TTY channels */
-    for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_RSVD;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* assign system TTY channel (first free subchannel after each
-     * processor's individual TTY channel has been assigned)
-     */
-    subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = ATOMIC_INIT(0);
-    subch->tx_notify = NULL;
-    subch->rx_notify = NULL;
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	static sc_cq_t x_iqp;
-
-	subch->iqp = &x_iqp;
-	ASSERT( subch->iqp );
-	cq_init( subch->iqp );
-    }
-    else {
-	/* we shouldn't be getting console input from remote UARTs */
-	subch->iqp = &sc->garbage_q;
-    }
-    subch++; i++;
-
-    /* "reserved" subchannels (0x05-0x0F); for now, throw away
-     * incoming packets
-     */
-    for( ; i < 0x10; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* remaining subchannels are free */
-    for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-}
-
-static inline l1sc_t *
-early_sc_init(nasid_t nasid)
-{
-	/* This is for early I/O */
-	if ( Early_console_inited == 0 ) {
-    		early_brl1_init(&Early_console, nasid,  BRL1_LOCALHUB_UART);
-		Early_console_inited = 1;
-	}
-	return(&Early_console);
-}
-
-#define PUTCHAR(ch) \
-    { \
-        while( (!(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XHRE)) || \
-                (!(READ_L1_UART_REG( nasid, REG_MSR ) & MSR_CTS)) ); \
-        WRITE_L1_UART_REG( nasid, REG_DAT, (ch) ); \
-    }
-
-static int
-early_l1_serial_out( nasid_t nasid, char *str, int len, int lock_state )
-{
-	int ret, sent = 0;
-	char *msg = str;
-	static int early_l1_send( nasid_t nasid, char *str, int len, int lock_state );
-
-	while ( sent < len ) {
-		ret = early_l1_send(nasid, msg, len - sent, lock_state);
-		sent += ret;
-		msg += ret;
-	}
-	return(len);
-}
-
-static inline int
-early_l1_send( nasid_t nasid, char *str, int len, int lock_state )
-{
-    int sent;
-    char crc_char;
-    unsigned short crc = INIT_CRC;
-
-    if( len > (BRL1_QSIZE - 1) )
-	len = (BRL1_QSIZE - 1);
-
-    sent = len;
-    if ( lock_state == NOT_LOCKED )
-    	lock_console(nasid);
-
-    PUTCHAR( BRL1_FLAG_CH );
-    PUTCHAR( BRL1_EVENT | SC_CONS_SYSTEM );
-    crc = crc16_calc( crc, (BRL1_EVENT | SC_CONS_SYSTEM) );
-
-    while( len ) {
-
-	if( (*str == BRL1_FLAG_CH) || (*str == BRL1_ESC_CH) ) {
-	    PUTCHAR( BRL1_ESC_CH );
-	    PUTCHAR( (*str) ^ BRL1_XOR_CH );
-	}
-	else {
-	    PUTCHAR( *str );
-	}
-	
-	crc = crc16_calc( crc, *str );
-
-	str++; len--;
-    }
-    
-    crc ^= 0xffff;
-    crc_char = crc & 0xff;
-    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	crc_char ^= BRL1_XOR_CH;
-	PUTCHAR( BRL1_ESC_CH );
-    }
-    PUTCHAR( crc_char );
-    crc_char = (crc >> 8) & 0xff;
-    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	crc_char ^= BRL1_XOR_CH;
-	PUTCHAR( BRL1_ESC_CH );
-    }
-    PUTCHAR( crc_char );
-    PUTCHAR( BRL1_FLAG_CH );
-
-    if ( lock_state == NOT_LOCKED )
-    	unlock_console(nasid);
-    return sent;
-}
-
-/*********************************************************************
- * l1_cons functions
- *
- * These allow the L1 to act as the system console.  They're intended
- * to abstract away most of the br/l1 internal details from the
- * _L1_cons_* functions (in the prom-- see "l1_console.c") and
- * l1_* functions (in the kernel-- see "sio_l1.c") that they support.
- *
- */
-
-static int
-l1_poll( l1sc_t *sc, int mode )
-{
-    int ret;
-
-    /* in case this gets called before the l1sc_t structure for the module_t
-     * struct for this node is initialized (i.e., if we're called with a
-     * zero l1sc_t pointer)...
-     */
-
-
-    if( !sc ) {
-	return 0;
-    }
-
-    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
-	return 1;
-    }
-
-    ret = brl1_receive( sc, mode );
-    if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) )
-	L1_collectibles[L1C_REC_STALLS] = ret;
-
-    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
-	return 1;
-    }
-    return 0;
-}
-
-
-/* pull a character off of the system console queue (if one is available)
- */
-static int
-l1_getc( l1sc_t *sc, int mode )
-{
-    unsigned long pl = 0;
-    int c;
-
-    brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
-    sc_cq_t *q = subch->iqp;
-
-    if( !l1_poll( sc, mode ) ) {
-	return 0;
-    }
-
-    SUBCH_DATA_LOCK( subch, pl );
-    if( cq_empty( q ) ) {
-	atomic_set(&subch->packet_arrived, 0);
-	SUBCH_DATA_UNLOCK( subch, pl );
-	return 0;
-    }
-    cq_rem( q, c );
-    if( cq_empty( q ) )
-	atomic_set(&subch->packet_arrived, 0);
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return c;
-}
-
-/*
- * Write a message to the L1 on the system console subchannel.
- *
- * Danger: don't use a non-zero value for the wait parameter unless you're
- * someone important (like a kernel error message).
- */
-
-int
-l1_write( l1sc_t *sc, char *msg, int len, int wait )
-{
-	int sent = 0, ret = 0;
-
-	if ( wait ) {
-		while ( sent < len ) {
-			ret = brl1_send( sc, msg, len - sent, (SC_CONS_SYSTEM | BRL1_EVENT), wait );
-			sent += ret;
-			msg += ret;
-		}
-		ret = len;
-	}
-	else {
-		ret = brl1_send( sc, msg, len, (SC_CONS_SYSTEM | BRL1_EVENT), wait );
-	}
-	return(ret);
-}
-
-/* initialize the system console subchannel
- */
-void
-l1_init(void)
-{
-	/* All we do now is remember that we have been called */
-	L1_cons_is_inited = 1;
-}
-
-
-/*********************************************************************
- * The following functions and definitions implement the "message"-
- * style interface to the L1 system controller.
- *
- * Note that throughout this file, "sc" generally stands for "system
- * controller", while "subchannels" tend to be represented by
- * variables with names like subch or ch.
- *
- */
-
-#ifdef L1_DEBUG
-#define L1_DBG_PRF(x) printf x
-#else
-#define L1_DBG_PRF(x)
-#endif
-
-/*
- * sc_data_ready is called to signal threads that are blocked on l1 input.
- */
-void
-sc_data_ready( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-
-    brl1_sch_t *subch = &(sc->subch[ch]);
-    SUBCH_DATA_LOCK( subch, pl );
-    sv_signal( &(subch->arrive_sv) );
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-/* sc_open reserves a subchannel to send a request to the L1 (the
- * L1's response will arrive on the same channel).  The number
- * returned by sc_open is the system controller subchannel
- * acquired.
- */
-int
-sc_open( l1sc_t *sc, uint target )
-{
-    /* The kernel version implements a locking scheme to arbitrate
-     * subchannel assignment.
-     */
-    int ch;
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    SUBCH_LOCK( sc, pl );
-
-    /* Look for a free subchannel. Subchannels 0-15 are reserved
-     * for other purposes.
-     */
-    for( subch = &(sc->subch[BRL1_CMD_SUBCH]), ch = BRL1_CMD_SUBCH; 
-			ch < BRL1_NUM_SUBCHANS; subch++, ch++ ) {
-        if( subch->use == BRL1_SUBCH_FREE )
-            break;
-    }
-
-    if( ch == BRL1_NUM_SUBCHANS ) {
-        /* there were no subchannels available! */
-        SUBCH_UNLOCK( sc, pl );
-        return SC_NSUBCH;
-    }
-
-    subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->target = target;
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
-    subch->tx_notify = NULL;
-    subch->rx_notify = sc_data_ready;
-    subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
-				   NASID_TO_COMPACT_NODEID(sc->nasid) );
-    ASSERT( subch->iqp );
-    cq_init( subch->iqp );
-
-    return ch;
-}
-
-
-/* sc_close frees a Bedrock<->L1 subchannel.
- */
-int
-sc_close( l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    SUBCH_LOCK( sc, pl );
-    subch = &(sc->subch[ch]);
-    if( subch->use != BRL1_SUBCH_RSVD ) {
-        /* we're trying to close a subchannel that's not open */
-	SUBCH_UNLOCK( sc, pl );
-        return SC_NOPEN;
-    }
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->use = BRL1_SUBCH_FREE;
-
-    sv_broadcast( &(subch->arrive_sv) );
-    sv_destroy( &(subch->arrive_sv) );
-    spin_lock_destroy( &(subch->data_lock) );
-
-    ASSERT( subch->iqp && (subch->iqp != &sc->garbage_q) );
-    snia_kmem_free( subch->iqp, sizeof(sc_cq_t) );
-    subch->iqp = &sc->garbage_q;
-    subch->tx_notify = NULL;
-    subch->rx_notify = brl1_discard_packet;
-
-    SUBCH_UNLOCK( sc, pl );
-
-    return SC_SUCCESS;
-}
-
-
-/* sc_construct_msg builds a bedrock-to-L1 request in the supplied
- * buffer.  Returns the length of the message.  The
- * safest course when passing a buffer to be filled in is to use
- * BRL1_QSIZE as the buffer size.
- *
- * Command arguments are passed as type/argument pairs, i.e., to
- * pass the number 5 as an argument to an L1 command, call
- * sc_construct_msg as follows:
- *
- *    char msg[BRL1_QSIZE];
- *    msg_len = sc_construct_msg( msg,
- *				  BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                2,
- *                                L1_ARG_INT, 5 );
- *
- * To pass an additional ASCII argument, you'd do the following:
- *
- *    char *str;
- *    ... str points to a null-terminated ascii string ...
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                4,
- *                                L1_ARG_INT, 5,
- *                                L1_ARG_ASCII, str );
- *
- * Finally, arbitrary data of unknown type is passed using the argtype
- * code L1_ARG_UNKNOWN, a data length, and a buffer pointer, e.g.
- *
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                3,
- *                                L1_ARG_UNKNOWN, 32, bufptr );
- *
- * ...passes 32 bytes of data starting at bufptr.  Note that no string or
- * "unknown"-type argument should be long enough to overflow the message
- * buffer.
- *
- * To construct a message for an L1 command that requires no arguments,
- * you'd use the following:
- *
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                0 );
- *
- * The final 0 means "no varargs".  Notice that this parameter is used to hold
- * the number of additional arguments to sc_construct_msg, _not_ the actual
- * number of arguments used by the L1 command (so 2 per L1_ARG_[INT,ASCII]
- * type argument, and 3 per L1_ARG_UNKOWN type argument).  A call to construct
- * an L1 command which required three integer arguments and two arguments of
- * some arbitrary (unknown) type would pass 12 as the value for this parameter.
- *
- * ENDIANNESS WARNING: The following code does a lot of copying back-and-forth
- * between byte arrays and four-byte big-endian integers.  Depending on the
- * system controller connection and endianness of future architectures, some
- * rewriting might be necessary.
- */
-int
-sc_construct_msg( l1sc_t  *sc,		/* system controller struct */
-		  int	   ch,           /* subchannel for this message */
-		  char    *msg,          /* message buffer */
-		  int      msg_len,      /* size of message buffer */
-                  l1addr_t addr_task,    /* target system controller task */
-                  short    req_code,     /* 16-bit request code */
-                  int      req_nargs,    /* # of arguments (varargs) passed */
-                  ... )                 /* any additional parameters */
-{
-    uint32_t buf32;   /* 32-bit buffer used to bounce things around */
-    void *bufptr;       /* used to hold command argument addresses */
-    va_list al;         /* variable argument list */
-    int index;          /* current index into msg buffer */
-    int argno;          /* current position in varargs list */
-    int l1_argno;       /* running total of arguments to l1 */
-    int l1_arg_t;       /* argument type/length */
-    int l1_argno_byte;  /* offset of argument count byte */
-
-    index = argno = 0;
-
-    /* set up destination address */
-    if( (msg_len -= sizeof( buf32 )) < 0 )
-	return -1;
-    L1_ADDRESS_TO_TASK( &buf32, sc->subch[ch].target, addr_task );
-    COPY_INT_TO_BUFFER(msg, index, buf32);
-
-    /* copy request code */
-    if( (msg_len -= 2) < 0 )
-	return( -1 );
-    msg[index++] = ((req_code >> 8) & 0xff);
-    msg[index++] = (req_code & 0xff);
-
-    if( !req_nargs ) {
-        return index;
-    }
-
-    /* reserve a byte for the argument count */
-    if( (msg_len -= 1) < 0 )
-	return( -1 );
-    l1_argno_byte = index++;
-    l1_argno = 0;
-
-    /* copy additional arguments */
-    va_start( al, req_nargs );
-    while( argno < req_nargs ) {
-        l1_argno++;
-        l1_arg_t = va_arg( al, int ); argno++;
-        switch( l1_arg_t )
-        {
-          case L1_ARG_INT:
-	    if( (msg_len -= (sizeof( buf32 ) + 1)) < 0 )
-		return( -1 );
-            msg[index++] = L1_ARG_INT;
-            buf32 = (unsigned)va_arg( al, int ); argno++;
-	    COPY_INT_TO_BUFFER(msg, index, buf32);
-            break;
-
-          case L1_ARG_ASCII:
-            bufptr = va_arg( al, char* ); argno++;
-	    if( (msg_len -= (strlen( bufptr ) + 2)) < 0 )
-		return( -1 );
-            msg[index++] = L1_ARG_ASCII;
-            strcpy( (char *)&(msg[index]), (char *)bufptr );
-            index += (strlen( bufptr ) + 1); /* include terminating null */
-            break;
-
-	  case L1_ARG_UNKNOWN:
-              {
-                  int arglen;
-		  
-                  arglen = va_arg( al, int ); argno++;
-                  bufptr = va_arg( al, void* ); argno++;
-		  if( (msg_len -= (arglen + 1)) < 0 )
-		      return( -1 );
-                  msg[index++] = L1_ARG_UNKNOWN | arglen;
-                  BCOPY( bufptr, &(msg[index]), arglen  );
-                  index += arglen;
-		  break;
-              }
-	  
-	  default: /* unhandled argument type */
-	    return -1;
-        }
-    }
-
-    va_end( al );
-    msg[l1_argno_byte] = l1_argno;
-
-    return index;
-}
-
-
-
-/* sc_interpret_resp verifies an L1 response to a bedrock request, and
- * breaks the response data up into the constituent parts.  If the
- * response message indicates error, or if a mismatch is found in the
- * expected number and type of arguments, an error is returned.  The
- * arguments to this function work very much like the arguments to
- * sc_construct_msg, above, except that L1_ARG_INTs must be followed
- * by a _pointer_ to an integer that can be filled in by this function.
- */
-int
-sc_interpret_resp( char *resp,          /* buffer received from L1 */
-                   int   resp_nargs,    /* number of _varargs_ passed in */
-                   ... )
-{
-    uint32_t buf32;   /* 32-bit buffer used to bounce things around */
-    void *bufptr;       /* used to hold response field addresses */
-    va_list al;         /* variable argument list */
-    int index;          /* current index into response buffer */
-    int argno;          /* current position in varargs list */
-    int l1_fldno;       /* number of resp fields received from l1 */
-    int l1_fld_t;       /* field type/length */
-
-    index = argno = 0;
-
-#if defined(L1_DEBUG)
-#define DUMP_RESP							  \
-    {									  \
-	int ix;								  \
-        char outbuf[512];						  \
-        sprintf( outbuf, "sc_interpret_resp error line %d: ", __LINE__ ); \
-	for( ix = 0; ix < 16; ix++ ) {					  \
-	    sprintf( &outbuf[strlen(outbuf)], "%x ", resp[ix] );	  \
-	}								  \
-	printk( "%s\n", outbuf );					  \
-    }
-#else
-#define DUMP_RESP
-#endif /* L1_DEBUG */
-
-    /* check response code */
-    COPY_BUFFER_TO_INT(resp, index, buf32);
-    if( buf32 != L1_RESP_OK ) {
-	DUMP_RESP;
-        return buf32;
-    }
-
-    /* get number of response fields */
-    l1_fldno = resp[index++];
-
-    va_start( al, resp_nargs );
-
-    /* copy out response fields */
-    while( argno < resp_nargs ) {
-        l1_fldno--;
-        l1_fld_t = va_arg( al, int ); argno++;
-        switch( l1_fld_t )
-        {
-          case L1_ARG_INT:
-            if( resp[index++] != L1_ARG_INT ) {
-                /* type mismatch */
-		va_end( al );
-		DUMP_RESP;
-		return -1;
-            }
-            bufptr = va_arg( al, int* ); argno++;
-	    COPY_BUFFER_TO_BUFFER(resp, index, bufptr);
-            break;
-
-          case L1_ARG_ASCII:
-            if( resp[index++] != L1_ARG_ASCII ) {
-                /* type mismatch */
-		va_end( al );
-		DUMP_RESP;
-                return -1;
-            }
-            bufptr = va_arg( al, char* ); argno++;
-            strcpy( (char *)bufptr, (char *)&(resp[index]) );
-            /* include terminating null */
-            index += (strlen( &(resp[index]) ) + 1);
-            break;
-
-          default:
-	    if( (l1_fld_t & L1_ARG_UNKNOWN) == L1_ARG_UNKNOWN )
-	    {
-		int *arglen;
-		
-		arglen = va_arg( al, int* ); argno++;
-		bufptr = va_arg( al, void* ); argno++;
-		*arglen = ((resp[index++] & ~L1_ARG_UNKNOWN) & 0xff);
-		BCOPY( &(resp[index]), bufptr, *arglen  );
-		index += (*arglen);
-	    }
-	    
-	    else {
-		/* unhandled type */
-		va_end( al );
-		DUMP_RESP;
-		return -1;
-	    }
-        }
-    }
-    va_end( al );
-  
-    if( (l1_fldno != 0) || (argno != resp_nargs) ) {
-        /* wrong number of arguments */
-	DUMP_RESP;
-        return -1;
-    }
-    return 0;
-}
-
-/* sc_send takes as arguments a system controller struct, a
- * buffer which contains a Bedrock<->L1 "request" message,
- * the message length, and the subchannel (presumably obtained
- * from an earlier invocation of sc_open) over which the
- * message is to be sent.  The final argument ("wait") indicates
- * whether the send is to be performed synchronously or not.
- *
- * sc_send returns either zero or an error value.  Synchronous sends 
- * (wait != 0) will not return until the data has actually been sent
- * to the UART.  Synchronous sends generally receive privileged
- * treatment.  The intent is that they be used sparingly, for such
- * purposes as kernel printf's (the "ducons" routines).  Run-of-the-mill
- * console output and L1 requests should NOT use a non-zero value
- * for wait.
- */
-int
-sc_send( l1sc_t *sc, int ch, char *msg, int len, int wait )
-{
-    char type_and_subch;
-    int result;
-
-    if( (ch < 0) || ( ch >= BRL1_NUM_SUBCHANS) ) {
-        return SC_BADSUBCH;
-    }
-
-    /* Verify that this is an open subchannel
-     */
-    if( sc->subch[ch].use == BRL1_SUBCH_FREE ) {
-        return SC_NOPEN;
-    }
-
-    type_and_subch = (BRL1_REQUEST | ((u_char)ch));
-    result = brl1_send( sc, msg, len, type_and_subch, wait );
-
-    /* If we sent as much as we asked to, return "ok". */
-    if( result == len )
-	return( SC_SUCCESS );
-
-    /* Or, if we sent less, than either the UART is busy or
-     * we're trying to send too large a packet anyway.
-     */
-    else if( result >= 0 && result < len )
-	return( SC_BUSY );
-
-    /* Or, if something else went wrong (result < 0), then
-     * return that error value.
-     */
-    else
-	return( result );
-}
-
-/* subch_pull_msg pulls a message off the receive queue for subch
- * and places it the buffer pointed to by msg.  This routine should only
- * be called when the caller already knows a message is available on the
- * receive queue (and, in the kernel, only when the subchannel data lock
- * is held by the caller).
- */
-static void
-subch_pull_msg( brl1_sch_t *subch, char *msg, int *len )
-{
-    sc_cq_t *q;         /* receive queue */
-    int before_wrap,    /* packet may be split into two different       */
-        after_wrap;     /*   pieces to acommodate queue wraparound      */
-
-    /* pull message off the receive queue */
-    q = subch->iqp;
-
-    cq_rem( q, *len );   /* remove length byte and store */
-    cq_discard( q );     /* remove type/subch byte and discard */
-
-    if ( *len > 0 )
-	(*len)--;        /* don't count type/subch byte in length returned */
-
-    if( (q->opos + (*len)) > BRL1_QSIZE ) {
-        before_wrap = BRL1_QSIZE - q->opos;
-        after_wrap = (*len) - before_wrap;
-    }
-    else {
-        before_wrap = (*len);
-        after_wrap = 0;
-    }
-
-    BCOPY( q->buf + q->opos, msg, before_wrap  );
-    if( after_wrap ) {
-        BCOPY( q->buf, msg + before_wrap, after_wrap  );
-	q->opos = after_wrap;
-    }
-    else {
-	q->opos = ((q->opos + before_wrap) & (BRL1_QSIZE - 1));
-    }
-    atomic_dec(&(subch->packet_arrived));
-}
-
-
-/* sc_recv_poll can be called as a blocking or non-blocking function;
- * it attempts to pull a message off of the subchannel specified
- * in the argument list (ch).
- *
- * The "block" argument, if non-zero, is interpreted as a timeout
- * delay (to avoid permanent waiting).
- */
-
-int
-sc_recv_poll( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
-{
-    int is_msg = 0;
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    rtc_time_t exp_time = rtc_time() + block;
-
-    /* sanity check-- make sure this is an open subchannel */
-    if( subch->use == BRL1_SUBCH_FREE )
-	return( SC_NOPEN );
-
-    do {
-
-        /* kick the next lower layer and see if it pulls anything in
-         */
-	brl1_receive( sc, SERIAL_POLLED_MODE );
-	is_msg = atomic_read(&subch->packet_arrived);
-
-    } while( block && !is_msg && (rtc_time() < exp_time) );
-
-    if( !is_msg ) {
-	/* no message and we didn't care to wait for one */
-	return( SC_NMSG );
-    }
-
-    SUBCH_DATA_LOCK( subch, pl );
-    subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return( SC_SUCCESS );
-}
-    
-
-/* Like sc_recv_poll, sc_recv_intr can be called in either a blocking
- * or non-blocking mode.  Rather than polling until an appointed timeout,
- * however, sc_recv_intr sleeps on a syncrhonization variable until a
- * signal from the lower layer tells us that a packet has arrived.
- *
- * sc_recv_intr can't be used with remote (router) L1s.
- */
-int
-sc_recv_intr( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
-{
-    int is_msg = 0;
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    do {
-	SUBCH_DATA_LOCK(subch, pl);
-	is_msg = atomic_read(&subch->packet_arrived);
-	if( !is_msg && block ) {
-	    /* wake me when you've got something */
-	    subch->rx_notify = sc_data_ready;
-	    sv_wait( &(subch->arrive_sv), 0, 0);
-	    if( subch->use == BRL1_SUBCH_FREE ) {
-		/* oops-- somebody closed our subchannel while we were
-		 * sleeping!
-		 */
-
-		/* no need to unlock since the channel's closed anyhow */
-		return( SC_NOPEN );
-	    }
-	}
-    } while( !is_msg && block );
-
-    if( !is_msg ) {
-	/* no message and we didn't care to wait for one */
-	SUBCH_DATA_UNLOCK( subch, pl );
-	return( SC_NMSG );
-    }
-
-    subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return( SC_SUCCESS );
-}
-
-/* sc_command implements a (blocking) combination of sc_send and sc_recv.
- * It is intended to be the SN1 equivalent of SN0's "elsc_command", which
- * issued a system controller command and then waited for a response from
- * the system controller before returning.
- *
- * cmd points to the outgoing command; resp points to the buffer in
- * which the response is to be stored.  Both buffers are assumed to
- * be the same length; if there is any doubt as to whether the
- * response buffer is long enough to hold the L1's response, then
- * make it BRL1_QSIZE bytes-- no Bedrock<->L1 message can be any
- * bigger.
- *
- * Be careful using the same buffer for both cmd and resp; it could get
- * hairy if there were ever an L1 command reqeuest that spanned multiple
- * packets.  (On the other hand, that would require some additional
- * rewriting of the L1 command interface anyway.)
- */
-#define __RETRIES	50
-#define __WAIT_SEND	1	// ( sc->uart != BRL1_LOCALHUB_UART )
-#define __WAIT_RECV	10000000
-
-
-int
-sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len )
-{
-    int result;
-    int retries;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-    	return SC_NMSG;
-
-    retries = __RETRIES;
-
-    while( (result = sc_send( sc, ch, cmd, *len, __WAIT_SEND )) < 0 ) {
-	if( result == SC_BUSY ) {
-	    retries--;
-	    if( retries <= 0 )
-		return result;
-	    uart_delay(500);
-	}
-	else {
-	    return result;
-	}
-    }
-    
-    /* block on sc_recv_* */
-    if( (sc->uart == BRL1_LOCALHUB_UART) && L1_interrupts_connected ) {
-	return( sc_recv_intr( sc, ch, resp, len, __WAIT_RECV ) );
-    }
-    else {
-	return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
-    }
-}
-
-/* sc_command_kern is a knuckle-dragging, no-patience version of sc_command
- * used in situations where the kernel has a command that shouldn't be
- * delayed until the send buffer clears.  sc_command should be used instead
- * under most circumstances.
- */
-
-int
-sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len )
-{
-    int result;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-    	return SC_NMSG;
-
-    if( (result = sc_send( sc, ch, cmd, *len, 1 )) < 0 ) {
-	return result;
-    }
-
-    return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
-}
-
-
-
-/* sc_poll checks the queue corresponding to the given
- * subchannel to see if there's anything available.  If
- * not, it kicks the brl1 layer and then checks again.
- *
- * Returns 1 if input is available on the given queue,
- * 0 otherwise.
- */
-
-int
-sc_poll( l1sc_t *sc, int ch )
-{
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    if( atomic_read(&subch->packet_arrived) )
-	return 1;
-
-    brl1_receive( sc, SERIAL_POLLED_MODE );
-
-    if( atomic_read(&subch->packet_arrived) )
-	return 1;
-
-    return 0;
-}
-
-/* for now, sc_init just calls brl1_init */
-
-void
-sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    if ( !IS_RUNNING_ON_SIMULATOR() )
-    	brl1_init( sc, nasid, uart );
-}
-
-/* sc_dispatch_env_event handles events sent from the system control
- * network's environmental monitor tasks.
- */
-
-#if	defined(LINUX_KERNEL_THREADS)
-
-static void
-sc_dispatch_env_event( uint code, int argc, char *args, int maxlen )
-{
-    int j, i = 0;
-    uint32_t ESPcode;
-
-    switch( code ) {
-	/* for now, all codes do the same thing: grab two arguments
-	 * and print a cmn_err_tag message */
-      default:
-	/* check number of arguments */
-	if( argc != 2 ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected 2 arguments, got %d\n", argc ));
-	    return;
-	}
-	
-	/* get ESP code (integer argument) */
-	if( args[i++] != L1_ARG_INT ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected integer argument\n" ));
-	    return;
-	}
-	/* WARNING: highly endian */
-	COPY_BUFFER_TO_INT(args, i, ESPcode);
-
-	/* verify string argument */
-	if( args[i++] != L1_ARG_ASCII ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected an ASCII string\n" ));
-	    return;
-	}
-	for( j = i; j < maxlen; j++ ) {
-	    if( args[j] == '\0' ) break; /* found string termination */
-	}
-	if( j == maxlen ) {
-	    j--;
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "message too long-- truncating\n" ));
-	}
-
-	/* strip out trailing cr/lf */
-	for( ; 
-	     j > 1 && ((args[j-1] == 0xd) || (args[j-1] == 0xa)); 
-	     j-- );
-	args[j] = '\0';
-	
-	/* strip out leading cr/lf */
-	for( ;
-	     i < j && ((args[i] == 0xd) || (args[i] == 0xa));
-	     i++ );
-    }
-}
-
-
-/* sc_event waits for events to arrive from the system controller, and
- * prints appropriate messages to the syslog.
- */
-
-static void
-sc_event( l1sc_t *sc, int ch )
-{
-    char event[BRL1_QSIZE];
-    int i;
-    int result;
-    int event_len;
-    uint32_t ev_src;
-    uint32_t ev_code;
-    int ev_argc;
-
-    while(1) {
-	
-	bzero( event, BRL1_QSIZE );
-
-	/*
-	 * wait for an event 
-	 */
-	result = sc_recv_intr( sc, ch, event, &event_len, 1 );
-	if( result != SC_SUCCESS ) {
-	    printk(KERN_WARNING  "Error receiving sysctl event on nasid %d\n",
-		     sc->nasid );
-	}
-	else {
-	    /*
-	     * an event arrived; break it down into useful pieces
-	     */
-#if defined(L1_DEBUG) && 0
-	    int ix;
-	    printf( "Event packet received:\n" );
-	    for (ix = 0; ix < 64; ix++) {
-		printf( "%x%x ", ((event[ix] >> 4) & ((uint64_t)0xf)),
-			(event[ix] & ((uint64_t)0xf)) );
-		if( (ix % 16) == 0xf ) printf( "\n" );
-	    }
-#endif /* L1_DEBUG */
-
-	    i = 0;
-
-	    /* get event source */
-	    COPY_BUFFER_TO_INT(event, i, ev_src);
-	    COPY_BUFFER_TO_INT(event, i, ev_code);
-
-	    /* get arg count */
-	    ev_argc = (event[i++] & 0xffUL);
-	    
-	    /* dispatch events by task */
-	    switch( (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT )
-	    {
-	      case L1_ADDR_TASK_ENV: /* environmental monitor event */
-		sc_dispatch_env_event( ev_code, ev_argc, &(event[i]), 
-				       BRL1_QSIZE - i );
-		break;
-
-	      default: /* unhandled task type */
-		L1_DBG_PRF(( "Unhandled event type received from system "
-			     "controllers: source task %x\n",
-			     (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT
-			   ));
-	    }
-	}
-	
-    }			
-}
-
-/* sc_listen sets up a service thread to listen for incoming events.
- */
-
-void
-sc_listen( l1sc_t *sc )
-{
-    int result;
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    char        msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         ch;     /* system controller subchannel used */
-
-    extern int msc_shutdown_pri;
-
-    /* grab the designated "event subchannel" */
-    SUBCH_LOCK( sc, pl );
-    subch = &(sc->subch[BRL1_EVENT_SUBCH]);
-    if( subch->use != BRL1_SUBCH_FREE ) {
-	SUBCH_UNLOCK( sc, pl );
-	printk(KERN_WARNING  "sysctl event subchannel in use! "
-		 "Not monitoring sysctl events.\n" );
-	return;
-    }
-    subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->target = BRL1_LOCALHUB_UART;
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
-    subch->tx_notify = NULL;
-    subch->rx_notify = sc_data_ready;
-    subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
-				   NASID_TO_COMPACT_NODEID(sc->nasid) );
-    ASSERT( subch->iqp );
-    cq_init( subch->iqp );
-
-    /* set up a thread to listen for events */
-    sthread_create( "sysctl event handler", 0, 0, 0, msc_shutdown_pri,
-		    KT_PS, (st_func_t *) sc_event,
-		    (void *)sc, (void *)(uint64_t)BRL1_EVENT_SUBCH, 0, 0 );
-
-    /* signal the L1 to begin sending events */
-    bzero( msg, BRL1_QSIZE );
-    ch = sc_open( sc, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( sc, ch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_EVENT_SUBCH, 2,
-				 L1_ARG_INT, BRL1_EVENT_SUBCH )) < 0 )
-    {
-	sc_close( sc, ch );
-	L1_DBG_PRF(( "Failure in sc_construct_msg (%d)\n", len ));
-	goto err_return;
-    }
-
-    result = sc_command_kern( sc, ch, msg, msg, &len );
-    if( result < 0 )
-    {
-	sc_close( sc, ch );
-	L1_DBG_PRF(( "Failure in sc_command_kern (%d)\n", result ));
-	goto err_return;
-    }
-
-    sc_close( sc, ch );
-
-    result = sc_interpret_resp( msg, 0 );
-    if( result < 0 )
-    {
-	L1_DBG_PRF(( "Failure in sc_interpret_resp (%d)\n", result ));
-	goto err_return;
-    }
-
-    /* everything went fine; just return */
-    return;
-	
-err_return:
-    /* there was a problem; complain */
-    printk(KERN_WARNING  "failed to set sysctl event-monitoring subchannel.  "
-	     "Sysctl events will not be monitored.\n" );
-}
-
-#endif	/* LINUX_KERNEL_THREADS */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/l1_command.c linux-2.4.22-pre10/arch/ia64/sn/io/l1_command.c
--- linux-2.4.21/arch/ia64/sn/io/l1_command.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/l1_command.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1378 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000 - 2001 Silicon Graphics, Inc.
- * All rights reserved.
- */ 
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-
-#define ELSC_TIMEOUT	1000000		/* ELSC response timeout (usec) */
-#define LOCK_TIMEOUT	5000000		/* Hub lock timeout (usec) */
-
-#define LD(x)		(*(volatile uint64_t *)(x))
-#define SD(x, v)	(LD(x) = (uint64_t) (v))
-
-#define hub_cpu_get()	0
-
-#define LBYTE(caddr)	(*(char *) caddr)
-
-extern char *bcopy(const char * src, char * dest, int count);
-
-#define LDEBUG		0
-
-/*
- * ELSC data is in NVRAM page 7 at the following offsets.
- */
-
-#define NVRAM_MAGIC_AD	0x700		/* magic number used for init */
-#define NVRAM_PASS_WD	0x701		/* password (4 bytes in length) */
-#define NVRAM_DBG1	0x705		/* virtual XOR debug switches */
-#define NVRAM_DBG2	0x706		/* physical XOR debug switches */
-#define NVRAM_CFG	0x707		/* ELSC Configuration info */
-#define NVRAM_MODULE	0x708		/* system module number */
-#define NVRAM_BIST_FLG	0x709		/* BIST flags (2 bits per nodeboard) */
-#define NVRAM_PARTITION 0x70a		/* module's partition id */
-#define	NVRAM_DOMAIN	0x70b		/* module's domain id */
-#define	NVRAM_CLUSTER	0x70c		/* module's cluster id */
-#define	NVRAM_CELL	0x70d		/* module's cellid */
-
-#define NVRAM_MAGIC_NO	0x37		/* value of magic number */
-#define NVRAM_SIZE	16		/* 16 bytes in nvram */
-
-/*
- * Declare a static ELSC NVRAM buffer to hold all data read from
- * and written to NVRAM.  This nvram "cache" will be used only during the
- * IP27prom execution.
- */
-static char elsc_nvram_buffer[NVRAM_SIZE];
-
-#define SC_COMMAND sc_command
-
-/*
- * elsc_init
- *
- *   Initialize ELSC structure
- */
-
-void elsc_init(elsc_t *e, nasid_t nasid)
-{
-    sc_init((l1sc_t *)e, nasid, BRL1_LOCALHUB_UART);
-}
-
-
-/*
- * elsc_errmsg
- *
- *   Given a negative error code,
- *   returns a corresponding static error string.
- */
-
-char *elsc_errmsg(int code)
-{
-    switch (code) {
-    case ELSC_ERROR_CMD_SEND:
-	return "Command send error";
-    case ELSC_ERROR_CMD_CHECKSUM:
-	return "Command packet checksum error";
-    case ELSC_ERROR_CMD_UNKNOWN:
-	return "Unknown command";
-    case ELSC_ERROR_CMD_ARGS:
-	return "Invalid command argument(s)";
-    case ELSC_ERROR_CMD_PERM:
-	return "Permission denied";
-    case ELSC_ERROR_RESP_TIMEOUT:
-	return "System controller response timeout";
-    case ELSC_ERROR_RESP_CHECKSUM:
-	return "Response packet checksum error";
-    case ELSC_ERROR_RESP_FORMAT:
-	return "Response format error";
-    case ELSC_ERROR_RESP_DIR:
-	return "Response direction error";
-    case ELSC_ERROR_MSG_LOST:
-	return "Message lost because queue is full";
-    case ELSC_ERROR_LOCK_TIMEOUT:
-	return "Timed out getting ELSC lock";
-    case ELSC_ERROR_DATA_SEND:
-	return "Error sending data";
-    case ELSC_ERROR_NIC:
-	return "NIC protocol error";
-    case ELSC_ERROR_NVMAGIC:
-	return "Bad magic number in NVRAM";
-    case ELSC_ERROR_MODULE:
-	return "Module location protocol error";
-    default:
-	return "Unknown error";
-    }
-}
-
-/*
- * elsc_nvram_init
- *
- *   Initializes reads and writes to NVRAM.  This will perform a single
- *   read to NVRAM, getting all data at once.  When the PROM tries to
- *   read NVRAM, it returns the data from the buffer being read.  If the
- *   PROM tries to write out to NVRAM, the write is done, and the internal
- *   buffer is updated.
- */
-
-void elsc_nvram_init(nasid_t nasid, uchar_t *elsc_nvram_data)
-{
-    /* This might require implementation of multiple-packet request/responses
-     * if it's to provide the same behavior that was available in SN0.
-     */
-    nasid = nasid;
-    elsc_nvram_data = elsc_nvram_data;
-}
-
-/*
- * elsc_nvram_copy
- *
- *   Copies the content of a buffer into the static buffer in this library.
- */
-
-void elsc_nvram_copy(uchar_t *elsc_nvram_data)
-{
-    memcpy(elsc_nvram_buffer, elsc_nvram_data, NVRAM_SIZE);
-}
-
-/*
- * elsc_nvram_write
- *
- *   Copies bytes from 'buf' into NVRAM, starting at NVRAM address
- *   'addr' which must be between 0 and 2047.
- *
- *   If 'len' is non-negative, the routine copies 'len' bytes.
- *
- *   If 'len' is negative, the routine treats the data as a string and
- *   copies bytes up to and including a NUL-terminating zero, but not
- *   to exceed '-len' bytes.
- */
-
-int elsc_nvram_write(elsc_t *e, int addr, char *buf, int len)
-{
-    /* Here again, we might need to work out the details of a
-     * multiple-packet protocol.
-     */
-
-    /* For now, pretend it worked. */
-    e = e;
-    addr = addr;
-    buf = buf;
-    return (len < 0 ? -len : len);
-}
-
-/*
- * elsc_nvram_read
- *
- *   Copies bytes from NVRAM into 'buf', starting at NVRAM address
- *   'addr' which must be between 0 and 2047.
- *
- *   If 'len' is non-negative, the routine copies 'len' bytes.
- *
- *   If 'len' is negative, the routine treats the data as a string and
- *   copies bytes up to and including a NUL-terminating zero, but not
- *   to exceed '-len' bytes.  NOTE:  This method is no longer supported.
- *   It was never used in the first place.
- */
-
-int elsc_nvram_read(elsc_t *e, int addr, char *buf, int len)
-{
-    /* multiple packets? */
-    e = e;
-    addr = addr;
-    buf = buf;
-    len = len;
-    return -1;
-}
-
-
-/*
- * Command Set
- */
-
-int elsc_version(elsc_t *e, char *result)
-{
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-    int		major,  /* major rev number */
-	        minor,  /* minor rev number */
-                bugfix; /* bugfix rev number */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_FW_REV, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major,
-			   L1_ARG_INT, &minor, L1_ARG_INT, &bugfix )
-	< 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    sprintf( result, "%d.%d.%d", major, minor, bugfix );
-
-    return 0;
-}
-
-int elsc_debug_set(elsc_t *e, u_char byte1, u_char byte2)
-{
-    /* shush compiler */
-    e = e;
-    byte1 = byte1;
-    byte2 = byte2;
-
-    /* fill in a buffer with the opcode & params; call sc_command */
-
-    return 0;
-}
-
-int elsc_debug_get(elsc_t *e, u_char *byte1, u_char *byte2)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		dbg_sw; /* holds debug switch settings */
-    int		len;	/* number of msg buffer bytes used */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RDBG, 0 ) ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &dbg_sw ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* copy out debug switch settings (last two bytes of the
-     * integer response)
-     */
-    *byte1 = ((dbg_sw >> 8) & 0xFF);
-    *byte2 = (dbg_sw & 0xFF);
-
-    return 0;
-}
-
-
-/*
- * elsc_rack_bay_get fills in the two int * arguments with the
- * rack number and bay number of the L1 being addressed
- */
-int elsc_rack_bay_get(elsc_t *e, uint *rack, uint *bay)
-{
-    char msg[BRL1_QSIZE];	/* L1 request/response info */
-    int subch;			/* system controller subchannel used */
-    int len;			/* length of message */
-    uint32_t	buf32;		/* used to copy 32-bit rack/bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRACK, 0 )) < 0 ) 
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-
-    /* send the request to the L1 */
-    if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close(e, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &buf32 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    return 0;
-}
-
-
-/* elsc_rack_bay_type_get fills in the three int * arguments with the
- * rack number, bay number and brick type of the L1 being addressed.  Note
- * that if the L1 operation fails and this function returns an error value, 
- * garbage may be written to brick_type.
- */
-int elsc_rack_bay_type_get( l1sc_t *sc, uint *rack, 
-			       uint *bay, uint *brick_type )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t buf32;	        /* used to copy 32-bit rack & bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRBT, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, 
-			           L1_ARG_INT, brick_type ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    /* convert brick_type to lower case */
-    *brick_type = *brick_type - 'A' + 'a';
-
-    return 0;
-}
-
-
-int elsc_module_get(elsc_t *e)
-{
-    extern char brick_types[];
-    uint rnum, rack, bay, bricktype, t;
-    int ret;
-
-    /* construct module ID from rack and slot info */
-
-    if ((ret = elsc_rack_bay_type_get(e, &rnum, &bay, &bricktype)) < 0) {
-	return ret;
-    }
-
-    /* report unset location info. with a special, otherwise invalid modid */
-    if (rnum == 0 && bay == 0)
-	return MODULE_NOT_SET;
-
-    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-	return ELSC_ERROR_MODULE;
-
-    /* Build a moduleid_t-compatible rack number */
-
-    rack = 0;		
-    t = rnum / 100;		/* rack class (CPU/IO) */
-    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_CLASS(rack, t);
-    rnum %= 100;
-
-    t = rnum / 10;		/* rack group */
-    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_GROUP(rack, t);
-
-    t = rnum % 10;		/* rack number (one-based) */
-    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_NUM(rack, t);
-
-    for( t = 0; t < MAX_BRICK_TYPES; t++ ) {
-	if( brick_types[t] == bricktype )
-	    return RBT_TO_MODULE(rack, bay, t);
-    }
-    
-    return ELSC_ERROR_MODULE;
-}
-
-int elsc_partition_set(elsc_t *e, int partition)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PARTITION_SET, 2,
-				 L1_ARG_INT, partition )) < 0 )
-    {
-	
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-    
-    return( 0 );
-}
-
-int elsc_partition_get(elsc_t *e)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t partition_id;    /* used to copy partition id out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PARTITION_GET, 0 )) < 0 )
-
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &partition_id ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-    
-    return( partition_id );
-}
-
-
-/*
- * elsc_cons_subch selects the "active" console subchannel for this node
- * (i.e., the one that will currently receive input)
- */
-int elsc_cons_subch(elsc_t *e, uint ch)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( e, L1_ADDR_LOCAL );
-    
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_CONS_SUBCH, 2,
-				 L1_ARG_INT, ch)) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-/*
- * elsc_cons_node should only be executed by one node.  It declares to
- * the system controller that the node from which it is called will be
- * the owner of the system console.
- */
-int elsc_cons_node(elsc_t *e)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( e, L1_ADDR_LOCAL );
-    
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_CONS_NODE, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-    
-
-/* elsc_display_line writes up to 12 characters to either the top or bottom
- * line of the L1 display.  line points to a buffer containing the message
- * to be displayed.  The zero-based line number is specified by lnum (so
- * lnum == 0 specifies the top line and lnum == 1 specifies the bottom).
- * Lines longer than 12 characters, or line numbers not less than
- * L1_DISPLAY_LINES, cause elsc_display_line to return an error.
- */
-int elsc_display_line(elsc_t *e, char *line, int lnum)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		len;	/* number of msg buffer bytes used */
-
-    /* argument sanity checking */
-    if( !(lnum < L1_DISPLAY_LINES) )
-	return( ELSC_ERROR_CMD_ARGS );
-    if( !(strlen( line ) <= L1_DISPLAY_LINE_LENGTH) )
-	return( ELSC_ERROR_CMD_ARGS );
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 (L1_REQ_DISP1+lnum), 2,
-				 L1_ARG_ASCII, line )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-/* elsc_display_mesg silently drops message characters beyond the 12th.
- */
-int elsc_display_mesg(elsc_t *e, char *chr)
-{
-
-    char line[L1_DISPLAY_LINE_LENGTH+1];
-    int numlines, i;
-    int result;
-
-    numlines = (strlen( chr ) + L1_DISPLAY_LINE_LENGTH - 1) /
-	L1_DISPLAY_LINE_LENGTH;
-
-    if( numlines > L1_DISPLAY_LINES )
-	numlines = L1_DISPLAY_LINES;
-
-    for( i = 0; i < numlines; i++ )
-    {
-	strncpy( line, chr, L1_DISPLAY_LINE_LENGTH );
-	line[L1_DISPLAY_LINE_LENGTH] = '\0';
-
-	/* generally we want to leave the first line of the L1 display
-	 * alone (so the L1 can manipulate it).  If you need to be able
-	 * to display to both lines (for debugging purposes), define
-	 * L1_DISP_2LINES in irix/kern/ksys/l1.h, or add -DL1_DISP_2LINES
-	 * to your 'defs file.
-	 */
-#if defined(L1_DISP_2LINES)
-	if( (result = elsc_display_line( e, line, i )) < 0 )
-#else
-	if( (result = elsc_display_line( e, line, i+1 )) < 0 )
-#endif
-
-	    return result;
-
-	chr += L1_DISPLAY_LINE_LENGTH;
-    }
-    
-    return 0;
-}
-
-
-int elsc_password_set(elsc_t *e, char *password)
-{
-    /* shush compiler */
-    e = e;
-    password = password;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-int elsc_password_get(elsc_t *e, char *password)
-{
-    /* shush compiler */
-    e = e;
-    password = password;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-/*
- * sc_portspeed_get
- *
- * retrieve the current portspeed setting for the bedrock II
- */
-int sc_portspeed_get(l1sc_t *sc)
-{
-    char	msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         subch;  /* system controller subchannel used */
-    int		portspeed_a, portspeed_b;
-			/* ioport clock rates */
-
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-                                 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PORTSPEED,
-				 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-    
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) < 0 )
-    {
-        sc_close( sc, subch );
-        return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, 
-			   L1_ARG_INT, &portspeed_a,
-			   L1_ARG_INT, &portspeed_b ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* for the c-brick, we ignore the portspeed_b value */
-    return (portspeed_a ? 600 : 400);
-}
-
-/*
- * elsc_power_query
- *
- *   To be used after system reset, this command returns 1 if the reset
- *   was the result of a power-on, 0 otherwise.
- *
- *   The power query status is cleared to 0 after it is read.
- */
-
-int elsc_power_query(elsc_t *e)
-{
-    e = e; /* shush the compiler */
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 1;
-}
-
-int elsc_rpwr_query(elsc_t *e, int is_master)
-{
-    /* shush the compiler */
-    e = e;
-    is_master = is_master;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-} 
-
-/*
- * elsc_power_down
- *
- *   Sets up system to shut down in "sec" seconds (or modifies the
- *   shutdown time if one is already in effect).  Use 0 to power
- *   down immediately.
- */
-
-int elsc_power_down(elsc_t *e, int sec)
-{
-    /* shush compiler */
-    e = e;
-    sec = sec;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-int elsc_system_reset(elsc_t *e)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		len;	/* number of msg buffer bytes used */
-    int		result;
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RESET, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( (result = sc_command( e, subch, msg, msg, &len )) ) {
-	sc_close( e, subch );
-	if( result == SC_NMSG ) {
-	    /* timeout is OK.  We've sent the reset.  Now it's just
-	     * a matter of time...
-	     */
-	    return( 0 );
-	}
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-int elsc_power_cycle(elsc_t *e)
-{
-    /* shush compiler */
-    e = e;
-
-    /* fill in buffer with the opcode & params; call sc_command */
-
-    return 0;
-}
-
-
-/*
- * L1 Support for reading 
- * cbrick uid.
- */
-
-int elsc_nic_get(elsc_t *e, uint64_t *nic, int verbose)
-{
-    /* this parameter included only for SN0 compatibility */
-    verbose = verbose;
-
-    /* We don't go straight to the bedrock/L1 protocol on this one, but let
-     * the eeprom layer prepare the eeprom data as we would like it to
-     * appear to the caller
-     */
-    return cbrick_uid_get( e->nasid, nic );
-}
-
-
-int _elsc_hbt(elsc_t *e, int ival, int rdly)
-{
-    e = e;
-    ival = ival;
-    rdly = rdly;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-/* send a command string to an L1 */
-int sc_command_interp( l1sc_t *sc, l1addr_t compt, l1addr_t rack, l1addr_t bay,
-		       char *cmd )
-{
-    char        msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         subch;  /* system controller subchannel used */
-    l1addr_t	target; /* target system controller for command */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-
-    L1_BUILD_ADDR( &target, compt, rack, bay, 0 );
-    subch = sc_open( sc, target );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_CMD, L1_REQ_EXEC_CMD, 2,
-				 L1_ARG_ASCII, cmd )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-		   
-    /* send the request to the L1 */
-    if( SC_COMMAND( sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-    
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-/*
- * sc_power_down
- *
- * Shuts down the c-brick associated with sc, and any attached I/O bricks
- * or other c-bricks (won't go through r-bricks).
- */
-
-int sc_power_down(l1sc_t *sc)
-{
-    return sc_command_interp( sc, L1_ADDR_TYPE_L1, L1_ADDR_RACK_LOCAL, 
-			      L1_ADDR_BAY_LOCAL, "* pwr d" );
-}
-
-
-/*
- * sc_power_down_all
- *
- * Works similarly to sc_power_down, except that the request is sent to the
- * closest L2 and EVERYBODY gets turned off.
- */
-
-int sc_power_down_all(l1sc_t *sc)
-{
-    if( nodepda->num_routers > 0 ) {
-	return sc_command_interp( sc, L1_ADDR_TYPE_L2, L1_ADDR_RACK_LOCAL, 
-				  L1_ADDR_BAY_LOCAL, "* pwr d" );
-    }
-    else {
-	return sc_power_down( sc );
-    }
-}
-
-
-/*
- * Routines for reading the R-brick's L1
- */
-
-int router_module_get( nasid_t nasid, net_vec_t path )
-{
-    uint rnum, rack, bay, t;
-    int ret;
-    l1sc_t sc;
-
-    /* prepare l1sc_t struct */
-    sc_init( &sc, nasid, path );
-
-    /* construct module ID from rack and slot info */
-
-    if ((ret = elsc_rack_bay_get(&sc, &rnum, &bay)) < 0)
-	return ret;
-
-    /* report unset location info. with a special, otherwise invalid modid */
-    if (rnum == 0 && bay == 0)
-	return MODULE_NOT_SET;
-
-    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-	return ELSC_ERROR_MODULE;
-
-    /* Build a moduleid_t-compatible rack number */
-
-    rack = 0;		
-    t = rnum / 100;		/* rack class (CPU/IO) */
-    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_CLASS(rack, t);
-    rnum %= 100;
-
-    t = rnum / 10;		/* rack group */
-    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_GROUP(rack, t);
-
-    t = rnum % 10;		/* rack number (one-based) */
-    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_NUM(rack, t);
-
-    ret = RBT_TO_MODULE(rack, bay, MODULE_RBRICK);
-    return ret;
-}
-    
-
-/*
- * iobrick routines
- */
-
-/* iobrick_rack_bay_type_get fills in the three int * arguments with the
- * rack number, bay number and brick type of the L1 being addressed.  Note
- * that if the L1 operation fails and this function returns an error value, 
- * garbage may be written to brick_type.
- */
-int iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack, 
-			       uint *bay, uint *brick_type )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t buf32;	        /* used to copy 32-bit rack & bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRBT, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, 
-			           L1_ARG_INT, brick_type ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    return 0;
-}
-
-
-int iobrick_module_get(l1sc_t *sc)
-{
-    uint rnum, rack, bay, brick_type, t;
-    int ret;
-
-    /* construct module ID from rack and slot info */
-
-    if ((ret = iobrick_rack_bay_type_get(sc, &rnum, &bay, &brick_type)) < 0)
-        return ret;
-
-    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-        return ELSC_ERROR_MODULE;
-
-    /* Build a moduleid_t-compatible rack number */
-
-    rack = 0;           
-    t = rnum / 100;             /* rack class (CPU/IO) */
-    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_CLASS(rack, t);
-    rnum %= 100;
-
-    t = rnum / 10;              /* rack group */
-    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_GROUP(rack, t);
-
-    t = rnum % 10;              /* rack number (one-based) */
-    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_NUM(rack, t);
-
-    switch( brick_type ) {
-      case 'I': 
-	brick_type = MODULE_IBRICK; break;
-      case 'P':
-	brick_type = MODULE_PBRICK; break;
-      case 'X':
-	brick_type = MODULE_XBRICK; break;
-    }
-
-    ret = RBT_TO_MODULE(rack, bay, brick_type);
-
-    return ret;
-}
-
-/* iobrick_get_sys_snum asks the attached iobrick for the system
- * serial number.  This function will only be relevant to the master
- * cbrick (the one attached to the bootmaster ibrick); other nodes
- * may call the function, but the value returned to the master node
- * will be the one used as the system serial number by the kernel.
- */
-
-int
-iobrick_get_sys_snum( l1sc_t *sc, char *snum_str )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SYS_SERIAL, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    return( sc_interpret_resp( msg, 2, L1_ARG_ASCII, snum_str ) );
-}
-
-
-/*
- * The following functions apply (or cut off) power to the specified
- * pci bus or slot.
- */
-
-int
-iobrick_pci_pwr( l1sc_t *sc, int bus, int slot, int req_code )
-{
-#if 0 /* The "bedrock request" method of performing this function
-       * seems to be broken in the L1, so for now use the command-
-       * interpreter method
-       */
-
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCALIO );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 req_code, 4,
-				 L1_ARG_INT, bus,
-				 L1_ARG_INT, slot )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-
-#else
-    char cmd[64];
-    char *fxn;
-
-    switch( req_code )
-    {
-    case L1_REQ_PCI_UP:
-	fxn = "u";
-	break;
-    case L1_REQ_PCI_DOWN:
-	fxn = "d";
-	break;
-    case L1_REQ_PCI_RESET:
-	fxn = "rst";
-	break;
-    default:
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    if( slot == -1 ) 
-	sprintf( cmd, "pci %d %s", bus, fxn );
-    else
-        sprintf( cmd, "pci %d %d %s", bus, slot, fxn );
-	
-    return sc_command_interp( sc, L1_ADDR_TYPE_IOBRICK,
-	L1_ADDR_RACK_LOCAL, L1_ADDR_BAY_LOCAL, cmd );
-#endif
-}
-				 
-int
-iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up )
-{
-    return iobrick_pci_pwr( sc, bus, slot, up );
-}
-
-int
-iobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up )
-{
-    return iobrick_pci_pwr( sc, bus, -1, up );
-}
-
-
-int
-iobrick_pci_slot_rst( l1sc_t *sc, int bus, int slot )
-{
-    return iobrick_pci_pwr( sc, bus, slot, L1_REQ_PCI_RESET );
-}
-
-int
-iobrick_pci_bus_rst( l1sc_t *sc, int bus )
-{
-    return iobrick_pci_pwr( sc, bus, -1, L1_REQ_PCI_RESET );
-}
-
-
-/* get the L1 firmware version for an iobrick */
-int
-iobrick_sc_version( l1sc_t *sc, char *result )
-{
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-    int		major,  /* major rev number */
-	        minor,  /* minor rev number */
-                bugfix; /* bugfix rev number */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCALIO );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_FW_REV, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major,
-			   L1_ARG_INT, &minor, L1_ARG_INT, &bugfix )
-	< 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    sprintf( result, "%d.%d.%d", major, minor, bugfix );
-
-    return 0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/labelcl.c linux-2.4.22-pre10/arch/ia64/sn/io/labelcl.c
--- linux-2.4.21/arch/ia64/sn/io/labelcl.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/labelcl.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,654 +0,0 @@
-/*  labelcl - SGI's Hwgraph Compatibility Layer.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
-*/
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-
-/*
-** Very simple and dumb string table that supports only find/insert.
-** In practice, if this table gets too large, we may need a more
-** efficient data structure.   Also note that currently there is no 
-** way to delete an item once it's added.  Therefore, name collision 
-** will return an error.
-*/
-
-struct string_table label_string_table;
-
-
-
-/*
- * string_table_init - Initialize the given string table.
- */
-void
-string_table_init(struct string_table *string_table)
-{
-	string_table->string_table_head = NULL;
-	string_table->string_table_generation = 0;
-
-	/*
-	 * We nedd to initialize locks here!
-	 */
-
-	return;
-}
-
-
-/*
- * string_table_destroy - Destroy the given string table.
- */
-void
-string_table_destroy(struct string_table *string_table)
-{
-	struct string_table_item *item, *next_item;
-
-	item = string_table->string_table_head;
-	while (item) {
-		next_item = item->next;
-
-		STRTBL_FREE(item);
-		item = next_item;
-	}
-
-	/*
-	 * We need to destroy whatever lock we have here
-	 */
-
-	return;
-}
-
-
-
-/*
- * string_table_insert - Insert an entry in the string table .. duplicate 
- *	names are not allowed.
- */
-char *
-string_table_insert(struct string_table *string_table, char *name)
-{
-	struct string_table_item *item, *new_item = NULL, *last_item = NULL;
-
-again:
-	/*
-	 * Need to lock the table ..
-	 */
-	item = string_table->string_table_head;
-	last_item = NULL;
-
-	while (item) {
-		if (!strcmp(item->string, name)) {
-			/*
-			 * If we allocated space for the string and the found that
-			 * someone else already entered it into the string table,
-			 * free the space we just allocated.
-			 */
-			if (new_item)
-				STRTBL_FREE(new_item);
-
-
-			/*
-			 * Search optimization: move the found item to the head
-			 * of the list.
-			 */
-			if (last_item != NULL) {
-				last_item->next = item->next;
-				item->next = string_table->string_table_head;
-				string_table->string_table_head = item;
-			}
-			goto out;
-		}
-		last_item = item;
-		item=item->next;
-	}
-
-	/*
-	 * name was not found, so add it to the string table.
-	 */
-	if (new_item == NULL) {
-		long old_generation = string_table->string_table_generation;
-
-		new_item = STRTBL_ALLOC(strlen(name));
-
-		strcpy(new_item->string, name);
-
-		/*
-		 * While we allocated memory for the new string, someone else 
-		 * changed the string table.
-		 */
-		if (old_generation != string_table->string_table_generation) {
-			goto again;
-		}
-	} else {
-		/* At this we only have the string table lock in access mode.
-		 * Promote the access lock to an update lock for the string
-		 * table insertion below.
-		 */
-			long old_generation = 
-				string_table->string_table_generation;
-
-			/*
-			 * After we did the unlock and wer waiting for update
-			 * lock someone could have potentially updated
-			 * the string table. Check the generation number
-			 * for this case. If it is the case we have to
-			 * try all over again.
-			 */
-			if (old_generation != 
-			    string_table->string_table_generation) {
-				goto again;
-			}
-		}
-
-	/*
-	 * At this point, we're committed to adding new_item to the string table.
-	 */
-	new_item->next = string_table->string_table_head;
-	item = string_table->string_table_head = new_item;
-	string_table->string_table_generation++;
-
-out:
-	/*
-	 * Need to unlock here.
-	 */
-	return(item->string);
-}
-
-/*
- * labelcl_info_create - Creates the data structure that will hold the
- *	device private information asscoiated with a devfs entry.
- *	The pointer to this structure is what gets stored in the devfs 
- *	(void * info).
- */
-labelcl_info_t *
-labelcl_info_create()
-{
-
-	labelcl_info_t *new = NULL;
-
-	/* Initial allocation does not include any area for labels */
-	if ( ( new = (labelcl_info_t *)kmalloc (sizeof(labelcl_info_t), GFP_KERNEL) ) == NULL )
-		return NULL;
-
-	memset (new, 0, sizeof(labelcl_info_t));
-	new->hwcl_magic = LABELCL_MAGIC;
-	return( new);
-
-}
-
-/*
- * labelcl_info_destroy - Frees the data structure that holds the
- *      device private information asscoiated with a devfs entry.  This 
- *	data structure was created by device_info_create().
- *
- *	The caller is responsible for nulling the (void *info) in the 
- *	corresponding devfs entry.
- */
-int
-labelcl_info_destroy(labelcl_info_t *labelcl_info)
-{
-
-	if (labelcl_info == NULL)
-		return(0);
-
-	/* Free the label list */
-	if (labelcl_info->label_list)
-		kfree(labelcl_info->label_list);
-
-	/* Now free the label info area */
-	labelcl_info->hwcl_magic = 0;
-	kfree(labelcl_info);
-
-	return(0);
-}
-
-/*
- * labelcl_info_add_LBL - Adds a new label entry in the labelcl info 
- *	structure.
- *
- *	Error is returned if we find another label with the same name.
- */
-int
-labelcl_info_add_LBL(devfs_handle_t de,
-			char *info_name,
-			arb_info_desc_t info_desc,
-			arbitrary_info_t info)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	int num_labels;
-	int new_label_list_size;
-	label_info_t *old_label_list, *new_label_list = NULL;
-	char *name;
-	int i;
-
-	if (de == NULL)
-		return(-1);
-
-        labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	if (info_name == NULL)
-		return(-1);
-
-	if (strlen(info_name) >= LABEL_LENGTH_MAX)
-		return(-1);
-
-	name = string_table_insert(&label_string_table, info_name);
-
-	num_labels = labelcl_info->num_labels;
-	new_label_list_size = sizeof(label_info_t) * (num_labels+1);
-
-	/*
-	 * Create a new label info area.
-	 */
-	if (new_label_list_size != 0) {
-		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
-
-		if (new_label_list == NULL)
-			return(-1);
-	}
-
-	/*
-	 * At this point, we are committed to adding the labelled info, 
-	 * if there isn't already information there with the same name.
-	 */
-	old_label_list = labelcl_info->label_list;
-
-	/* 
-	 * Look for matching info name.
-	 */
-	for (i=0; i<num_labels; i++) {
-		if (!strcmp(info_name, old_label_list[i].name)) {
-			/* Not allowed to add duplicate labelled info names. */
-			kfree(new_label_list);
-			printk(KERN_WARNING "labelcl_info_add_LBL: Duplicate label name %s for vertex 0x%p\n", info_name, (void *)de);
-			return(-1);
-		}
-		new_label_list[i] = old_label_list[i]; /* structure copy */
-	}
-
-	new_label_list[num_labels].name = name;
-	new_label_list[num_labels].desc = info_desc;
-	new_label_list[num_labels].info = info;
-
-	labelcl_info->num_labels = num_labels+1;
-	labelcl_info->label_list = new_label_list;
-
-	if (old_label_list != NULL)
-		kfree(old_label_list);
-
-	return(0);
-}
-
-/*
- * labelcl_info_remove_LBL - Remove a label entry.
- */
-int
-labelcl_info_remove_LBL(devfs_handle_t de,
-			 char *info_name,
-			 arb_info_desc_t *info_desc,
-			 arbitrary_info_t *info)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	int num_labels;
-	int new_label_list_size;
-	label_info_t *old_label_list, *new_label_list = NULL;
-	arb_info_desc_t label_desc_found;
-	arbitrary_info_t label_info_found;
-	int i;
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	num_labels = labelcl_info->num_labels;
-	if (num_labels == 0) {
-		return(-1);
-	}
-
-	/*
-	 * Create a new info area.
-	 */
-	new_label_list_size = sizeof(label_info_t) * (num_labels-1);
-	if (new_label_list_size) {
-		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
-		if (new_label_list == NULL)
-			return(-1);
-	}
-
-	/*
-	 * At this point, we are committed to removing the labelled info, 
-	 * if it still exists.
-	 */
-	old_label_list = labelcl_info->label_list;
-
-	/* 
-	 * Find matching info name.
-	 */
-	for (i=0; i<num_labels; i++) {
-		if (!strcmp(info_name, old_label_list[i].name)) {
-			label_desc_found = old_label_list[i].desc;
-			label_info_found = old_label_list[i].info;
-			goto found;
-		}
-		if (i < num_labels-1) /* avoid walking off the end of the new vertex */
-			new_label_list[i] = old_label_list[i]; /* structure copy */
-	}
-
-	/* The named info doesn't exist. */
-	if (new_label_list)
-		kfree(new_label_list);
-
-	return(-1);
-
-found:
-	/* Finish up rest of labelled info */
-	for (i=i+1; i<num_labels; i++)
-		new_label_list[i-1] = old_label_list[i]; /* structure copy */
-
-	labelcl_info->num_labels = num_labels+1;
-	labelcl_info->label_list = new_label_list;
-
-	kfree(old_label_list);
-
-	if (info != NULL)
-		*info = label_info_found;
-
-	if (info_desc != NULL)
-		*info_desc = label_desc_found;
-
-	return(0);
-}
-
-
-/*
- * labelcl_info_replace_LBL - Replace an existing label entry with the 
- *	given new information.
- *
- *	Label entry must exist.
- */
-int
-labelcl_info_replace_LBL(devfs_handle_t de,
-			char *info_name,
-			arb_info_desc_t info_desc,
-			arbitrary_info_t info,
-			arb_info_desc_t *old_info_desc,
-			arbitrary_info_t *old_info)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	int num_labels;
-	label_info_t *label_list;
-	int i;
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	num_labels = labelcl_info->num_labels;
-	if (num_labels == 0) {
-		return(-1);
-	}
-
-	if (info_name == NULL)
-		return(-1);
-
-	label_list = labelcl_info->label_list;
-
-	/* 
-	 * Verify that information under info_name already exists.
-	 */
-	for (i=0; i<num_labels; i++)
-		if (!strcmp(info_name, label_list[i].name)) {
-			if (old_info != NULL)
-				*old_info = label_list[i].info;
-
-			if (old_info_desc != NULL)
-				*old_info_desc = label_list[i].desc;
-
-			label_list[i].info = info;
-			label_list[i].desc = info_desc;
-
-			return(0);
-		}
-
-
-	return(-1);
-}
-
-/*
- * labelcl_info_get_LBL - Retrieve and return the information for the 
- *	given label entry.
- */
-int
-labelcl_info_get_LBL(devfs_handle_t de,
-		      char *info_name,
-		      arb_info_desc_t *info_desc,
-		      arbitrary_info_t *info)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	int num_labels;
-	label_info_t *label_list;
-	int i;
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	num_labels = labelcl_info->num_labels;
-	if (num_labels == 0) {
-		return(-1);
-	}
-
-	label_list = labelcl_info->label_list;
-
-	/* 
-	 * Find information under info_name.
-	 */
-	for (i=0; i<num_labels; i++)
-		if (!strcmp(info_name, label_list[i].name)) {
-			if (info != NULL)
-				*info = label_list[i].info;
-			if (info_desc != NULL)
-				*info_desc = label_list[i].desc;
-
-			return(0);
-		}
-
-	return(-1);
-}
-
-/*
- * labelcl_info_get_next_LBL - returns the next label entry on the list.
- */
-int
-labelcl_info_get_next_LBL(devfs_handle_t de,
-			   char *buffer,
-			   arb_info_desc_t *info_descp,
-			   arbitrary_info_t *infop,
-			   labelcl_info_place_t *placeptr)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	uint which_info;
-	label_info_t *label_list;
-
-	if ((buffer == NULL) && (infop == NULL))
-		return(-1);
-
-	if (placeptr == NULL)
-		return(-1);
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	which_info = *placeptr;
-
-	if (which_info >= labelcl_info->num_labels) {
-		return(-1);
-	}
-
-	label_list = (label_info_t *) labelcl_info->label_list;
-
-	if (buffer != NULL)
-		strcpy(buffer, label_list[which_info].name);
-
-	if (infop)
-		*infop = label_list[which_info].info;
-
-	if (info_descp)
-		*info_descp = label_list[which_info].desc;
-
-	*placeptr = which_info + 1;
-
-	return(0);
-}
-
-
-int
-labelcl_info_replace_IDX(devfs_handle_t de,
-			int index,
-			arbitrary_info_t info,
-			arbitrary_info_t *old_info)
-{
-	arbitrary_info_t *info_list_IDX;
-	labelcl_info_t	*labelcl_info = NULL;
-
-	if (de == NULL) {
-		printk(KERN_ALERT "labelcl: NULL devfs handle given.\n");
-		return(-1);
-	}
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL) {
-		printk(KERN_ALERT "labelcl: Entry does not have info pointer.\n");
-		return(-1);
-	}
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
-		return(-1);
-
-	/*
-	 * Replace information at the appropriate index in this vertex with 
-	 * the new info.
-	 */
-	info_list_IDX = labelcl_info->IDX_list;
-	if (old_info != NULL)
-		*old_info = info_list_IDX[index];
-	info_list_IDX[index] = info;
-
-	return(0);
-
-}
-
-/*
- * labelcl_info_connectpt_set - Sets the connectpt.
- */
-int
-labelcl_info_connectpt_set(struct devfs_entry *de,
-			  struct devfs_entry *connect_de)
-{
-	arbitrary_info_t old_info;
-	int	rv;
-
-	rv = labelcl_info_replace_IDX(de, HWGRAPH_CONNECTPT, 
-		(arbitrary_info_t) connect_de, &old_info);
-
-	if (rv) {
-		return(rv);
-	}
-
-	return(0);
-}
-
-
-/*
- * labelcl_info_get_IDX - Returns the information pointed at by index.
- *
- */
-int
-labelcl_info_get_IDX(devfs_handle_t de,
-			int index,
-			arbitrary_info_t *info)
-{
-	arbitrary_info_t *info_list_IDX;
-	labelcl_info_t	*labelcl_info = NULL;
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
-		return(-1);
-
-	/*
-	 * Return information at the appropriate index in this vertex.
-	 */
-	info_list_IDX = labelcl_info->IDX_list;
-	if (info != NULL)
-		*info = info_list_IDX[index];
-
-	return(0);
-}
-
-/*
- * labelcl_info_connectpt_get - Retrieve the connect point for a device entry.
- */
-struct devfs_entry *
-labelcl_info_connectpt_get(struct devfs_entry *de)
-{
-	int rv;
-	arbitrary_info_t info;
-
-	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
-	if (rv)
-		return(NULL);
-
-	return((struct devfs_entry *)info);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/machvec/Makefile linux-2.4.22-pre10/arch/ia64/sn/io/machvec/Makefile
--- linux-2.4.21/arch/ia64/sn/io/machvec/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/machvec/Makefile	2003-08-01 13:34:48.000000000 +0000
@@ -0,0 +1,18 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+O_TARGET := snio.o
+
+export-objs := pci_dma.o iomv.o
+
+obj-y				+= pci.o pci_dma.o pci_bus_cvlink.o iomv.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/machvec/iomv.c linux-2.4.22-pre10/arch/ia64/sn/io/machvec/iomv.c
--- linux-2.4.21/arch/ia64/sn/io/machvec/iomv.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/machvec/iomv.c	2003-08-01 13:33:13.000000000 +0000
@@ -0,0 +1,75 @@
+/* 
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <asm/sn/simulator.h>
+#include <asm/sn/pda.h>
+#include <asm/sn/sn_cpuid.h>
+
+/**
+ * sn_io_addr - convert an in/out port to an i/o address
+ * @port: port to convert
+ *
+ * Legacy in/out instructions are converted to ld/st instructions
+ * on IA64.  This routine will convert a port number into a valid 
+ * SN i/o address.  Used by sn_in*() and sn_out*().
+ */
+void *
+sn_io_addr(unsigned long port)
+{
+	if (!IS_RUNNING_ON_SIMULATOR()) {
+		/* On sn2, legacy I/O ports don't point at anything */
+		if (port < 64*1024)
+			return 0;
+		return( (void *)  (port | __IA64_UNCACHED_OFFSET));
+	} else {
+		/* but the simulator uses them... */
+		unsigned long io_base;
+		unsigned long addr;
+ 
+		/*
+ 		 * word align port, but need more than 10 bits
+ 		 * for accessing registers in bedrock local block
+ 		 * (so we don't do port&0xfff)
+ 		 */
+		if ((port >= 0x1f0 && port <= 0x1f7) ||
+			port == 0x3f6 || port == 0x3f7) {
+			io_base = (0xc000000fcc000000 | ((unsigned long)get_nasid() << 38));
+			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
+		} else {
+			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
+		}
+		return(void *) addr;
+	}
+}
+
+EXPORT_SYMBOL(sn_io_addr);
+
+/**
+ * sn_mmiob - I/O space memory barrier
+ *
+ * Acts as a memory mapped I/O barrier for platforms that queue writes to 
+ * I/O space.  This ensures that subsequent writes to I/O space arrive after
+ * all previous writes.  For most ia64 platforms, this is a simple
+ * 'mf.a' instruction.  For other platforms, mmiob() may have to read
+ * a chipset register to ensure ordering.
+ *
+ * On SN2, we wait for the PIO_WRITE_STATUS SHub register to clear.
+ * See PV 871084 for details about the WAR about zero value.
+ *
+ */
+void
+sn_mmiob (void)
+{
+	while ((((volatile unsigned long) (*pda.pio_write_status_addr)) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) != 
+				SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK)
+		udelay(1);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/machvec/pci.c linux-2.4.22-pre10/arch/ia64/sn/io/machvec/pci.c
--- linux-2.4.21/arch/ia64/sn/io/machvec/pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/machvec/pci.c	2003-08-01 13:32:05.000000000 +0000
@@ -0,0 +1,291 @@
+/* 
+ *
+ * SNI64 specific PCI support for SNI IO.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1997, 1998, 2000-2003 Silicon Graphics, Inc.  All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/iograph.h>
+#include <asm/param.h>
+#include <asm/sn/pio.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/bridge.h>
+
+#ifdef DEBUG_CONFIG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+
+
+#ifdef CONFIG_PCI
+
+extern vertex_hdl_t pci_bus_to_vertex(unsigned char);
+extern vertex_hdl_t devfn_to_vertex(unsigned char bus, unsigned char devfn);
+
+/*
+ * snia64_read_config_byte - Read a byte from the config area of the device.
+ */
+static int snia64_read_config_byte (struct pci_dev *dev,
+                                   int where, unsigned char *val)
+{
+	unsigned long res = 0;
+	unsigned size = 1;
+	vertex_hdl_t device_vertex;
+
+	if ( (dev == (struct pci_dev *)0) || (val == (unsigned char *)0) ) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
+	if (!device_vertex) {
+		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
+		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		return(-1);
+	}
+	res = pciio_config_get(device_vertex, (unsigned) where, size);
+	*val = (unsigned char) res;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * snia64_read_config_word - Read 2 bytes from the config area of the device.
+ */
+static int snia64_read_config_word (struct pci_dev *dev,
+                                   int where, unsigned short *val)
+{
+	unsigned long res = 0;
+	unsigned size = 2; /* 2 bytes */
+	vertex_hdl_t device_vertex;
+
+	if ( (dev == (struct pci_dev *)0) || (val == (unsigned short *)0) ) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
+	if (!device_vertex) {
+		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
+		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		return(-1);
+	}
+	res = pciio_config_get(device_vertex, (unsigned) where, size);
+	*val = (unsigned short) res;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * snia64_read_config_dword - Read 4 bytes from the config area of the device.
+ */
+static int snia64_read_config_dword (struct pci_dev *dev,
+                                    int where, unsigned int *val)
+{
+	unsigned long res = 0;
+	unsigned size = 4; /* 4 bytes */
+	vertex_hdl_t device_vertex;
+
+	if (where & 3) {
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+	if ( (dev == (struct pci_dev *)0) || (val == (unsigned int *)0) ) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
+	if (!device_vertex) {
+		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
+		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		return(-1);
+	}
+	res = pciio_config_get(device_vertex, (unsigned) where, size);
+	*val = (unsigned int) res;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * snia64_write_config_byte - Writes 1 byte to the config area of the device.
+ */
+static int snia64_write_config_byte (struct pci_dev *dev,
+                                    int where, unsigned char val)
+{
+	vertex_hdl_t device_vertex;
+
+	if ( dev == (struct pci_dev *)0 ) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	/* 
+	 * if it's an IOC3 then we bail out, we special
+	 * case them with pci_fixup_ioc3
+	 */
+	if (dev->vendor == PCI_VENDOR_ID_SGI && 
+	    dev->device == PCI_DEVICE_ID_SGI_IOC3 )
+		return PCIBIOS_SUCCESSFUL;
+
+	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
+	if (!device_vertex) {
+		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
+		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		return(-1);
+	}
+	pciio_config_set( device_vertex, (unsigned)where, 1, (uint64_t) val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * snia64_write_config_word - Writes 2 bytes to the config area of the device.
+ */
+static int snia64_write_config_word (struct pci_dev *dev,
+                                    int where, unsigned short val)
+{
+	vertex_hdl_t device_vertex = NULL;
+
+	if (where & 1) {
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+	if ( dev == (struct pci_dev *)0 ) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	/* 
+	 * if it's an IOC3 then we bail out, we special
+	 * case them with pci_fixup_ioc3
+	 */
+	if (dev->vendor == PCI_VENDOR_ID_SGI && 
+	    dev->device == PCI_DEVICE_ID_SGI_IOC3)
+		return PCIBIOS_SUCCESSFUL;
+
+	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
+	if (!device_vertex) {
+		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
+		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		return(-1);
+	}
+	pciio_config_set( device_vertex, (unsigned)where, 2, (uint64_t) val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * snia64_write_config_dword - Writes 4 bytes to the config area of the device.
+ */
+static int snia64_write_config_dword (struct pci_dev *dev,
+                                     int where, unsigned int val)
+{
+	vertex_hdl_t device_vertex;
+
+	if (where & 3) {
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+	if ( dev == (struct pci_dev *)0 ) {
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+	/* 
+	 * if it's an IOC3 then we bail out, we special
+	 * case them with pci_fixup_ioc3
+	 */
+	if (dev->vendor == PCI_VENDOR_ID_SGI && 
+	    dev->device == PCI_DEVICE_ID_SGI_IOC3)
+		return PCIBIOS_SUCCESSFUL;
+
+	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
+	if (!device_vertex) {
+		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
+		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		return(-1);
+	}
+	pciio_config_set( device_vertex, (unsigned)where, 4, (uint64_t) val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops snia64_pci_ops = {
+	snia64_read_config_byte,
+	snia64_read_config_word,
+	snia64_read_config_dword,
+	snia64_write_config_byte,
+	snia64_write_config_word,
+	snia64_write_config_dword
+};
+
+/*
+ * snia64_pci_find_bios - SNIA64 pci_find_bios() platform specific code.
+ */
+void __init
+sn_pci_find_bios(void)
+{
+	extern struct pci_ops *pci_root_ops;
+	/*
+	 * Go initialize our IO Infrastructure ..
+	 */
+	extern void sgi_master_io_infr_init(void);
+
+	sgi_master_io_infr_init();
+
+	/* sn_io_infrastructure_init(); */
+	pci_root_ops = &snia64_pci_ops;
+}
+
+void
+pci_fixup_ioc3(struct pci_dev *d)
+{
+        int 		i;
+	unsigned int 	size;
+
+        /* IOC3 only decodes 0x20 bytes of the config space, reading
+	 * beyond that is relatively benign but writing beyond that
+	 * (especially the base address registers) will shut down the
+	 * pci bus...so avoid doing so.
+	 * NOTE: this means we can't program the intr_pin into the device,
+	 *       currently we hack this with special code in 
+	 *	 sgi_pci_intr_support()
+	 */
+        DBG("pci_fixup_ioc3: Fixing base addresses for ioc3 device %s\n", d->slot_name);
+
+	/* I happen to know from the spec that the ioc3 needs only 0xfffff 
+	 * The standard pci trick of writing ~0 to the baddr and seeing
+	 * what comes back doesn't work with the ioc3
+	 */
+	size = 0xfffff;
+	d->resource[0].end = (unsigned long) d->resource[0].start + (unsigned long) size;
+
+	/*
+	 * Zero out the resource structure .. because we did not go through 
+	 * the normal PCI Infrastructure Init, garbbage are left in these 
+	 * fileds.
+	 */
+        for (i = 1; i <= PCI_ROM_RESOURCE; i++) {
+                d->resource[i].start = 0UL;
+                d->resource[i].end = 0UL;
+                d->resource[i].flags = 0UL;
+        }
+
+        d->subsystem_vendor = 0;
+        d->subsystem_device = 0;
+
+}
+
+#else
+void sn_pci_find_bios(void) {}
+void pci_fixup_ioc3(struct pci_dev *d) {}
+struct list_head pci_root_buses;
+struct list_head pci_root_buses;
+struct list_head pci_devices;
+
+#endif /* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/machvec/pci_bus_cvlink.c linux-2.4.22-pre10/arch/ia64/sn/io/machvec/pci_bus_cvlink.c
--- linux-2.4.21/arch/ia64/sn/io/machvec/pci_bus_cvlink.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/machvec/pci_bus_cvlink.c	2003-08-01 13:34:12.000000000 +0000
@@ -0,0 +1,930 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/iograph.h>
+#include <asm/param.h>
+#include <asm/sn/pio.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/xtalk/xtalkaddrs.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/nodepda.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_bus_cvlink.h>
+#include <asm/sn/simulator.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/arch.h>
+
+extern int bridge_rev_b_data_check_disable;
+
+vertex_hdl_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
+nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
+void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
+unsigned char num_bridges;
+static int done_probing;
+extern irqpda_t *irqpdaindr;
+
+static int pci_bus_map_create(vertex_hdl_t xtalk, char * io_moduleid);
+vertex_hdl_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
+
+extern void register_pcibr_intr(int irq, pcibr_intr_t intr);
+
+void sn_dma_flush_init(unsigned long start, unsigned long end, int idx, int pin, int slot);
+
+
+/*
+ * For the given device, initialize whether it is a PIC device.
+ */
+static void
+set_isPIC(struct sn_device_sysdata *device_sysdata)
+{
+	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
+	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+
+	device_sysdata->isPIC = IS_PIC_SOFT(pcibr_soft);;
+}
+
+/*
+ * pci_bus_cvlink_init() - To be called once during initialization before 
+ *	SGI IO Infrastructure init is called.
+ */
+void
+pci_bus_cvlink_init(void)
+{
+
+	extern void ioconfig_bus_init(void);
+
+	memset(busnum_to_pcibr_vhdl, 0x0, sizeof(vertex_hdl_t) * MAX_PCI_XWIDGET);
+	memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET);
+
+	memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET);
+
+	num_bridges = 0;
+
+	ioconfig_bus_init();
+}
+
+/*
+ * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated 
+ *	pci bus vertex from the SGI IO Infrastructure.
+ */
+vertex_hdl_t
+pci_bus_to_vertex(unsigned char busnum)
+{
+
+	vertex_hdl_t	pci_bus = NULL;
+
+
+	/*
+	 * First get the xwidget vertex.
+	 */
+	pci_bus = busnum_to_pcibr_vhdl[busnum];
+	return(pci_bus);
+}
+
+/*
+ * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
+ *	and function numbers.
+ */
+vertex_hdl_t
+devfn_to_vertex(unsigned char busnum, unsigned int devfn)
+{
+
+	int slot = 0;
+	int func = 0;
+	char	name[16];
+	vertex_hdl_t  pci_bus = NULL;
+	vertex_hdl_t	device_vertex = (vertex_hdl_t)NULL;
+
+	/*
+	 * Go get the pci bus vertex.
+	 */
+	pci_bus = pci_bus_to_vertex(busnum);
+	if (!pci_bus) {
+		/*
+		 * During probing, the Linux pci code invents non-existent
+		 * bus numbers and pci_dev structures and tries to access
+		 * them to determine existence. Don't crib during probing.
+		 */
+		if (done_probing)
+			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
+		return(NULL);
+	}
+
+
+	/*
+	 * Go get the slot&function vertex.
+	 * Should call pciio_slot_func_to_name() when ready.
+	 */
+	slot = PCI_SLOT(devfn);
+	func = PCI_FUNC(devfn);
+
+	/*
+	 * For a NON Multi-function card the name of the device looks like:
+	 * ../pci/1, ../pci/2 ..
+	 */
+	if (func == 0) {
+        	sprintf(name, "%d", slot);
+		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
+			GRAPH_SUCCESS) {
+			if (device_vertex) {
+				return(device_vertex);
+			}
+		}
+	}
+			
+	/*
+	 * This maybe a multifunction card.  It's names look like:
+	 * ../pci/1a, ../pci/1b, etc.
+	 */
+	sprintf(name, "%d%c", slot, 'a'+func);
+	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
+		if (!device_vertex) {
+			return(NULL);
+		}
+	}
+
+	return(device_vertex);
+}
+
+/*
+ * For the given device, initialize the addresses for both the Device(x) Flush 
+ * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
+ * is connected.
+ */
+static void
+set_flush_addresses(struct pci_dev *device_dev, 
+	struct sn_device_sysdata *device_sysdata)
+{
+	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
+	pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
+	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    	bridge_t               *bridge = pcibr_soft->bs_base;
+	nasid_t			nasid;
+
+	/*
+	 * Get the nasid from the bridge.
+	 */
+	nasid = NASID_GET(device_sysdata->dma_buf_sync);
+	if (IS_PIC_DEVICE(device_dev)) {
+		device_sysdata->dma_buf_sync = (volatile unsigned int *)
+			&bridge->b_wr_req_buf[pciio_slot].reg;
+		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
+			XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(nasid, 0),
+			pcibr_soft->bs_xid);
+	} else {
+		/*
+		 * Accessing Xbridge and Xbow register when SHUB swapoper is on!.
+		 */
+		device_sysdata->dma_buf_sync = (volatile unsigned int *)
+			((uint64_t)&(bridge->b_wr_req_buf[pciio_slot].reg)^4);
+		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
+			((uint64_t)(XBOW_PRIO_LINKREGS_PTR(
+			NODE_SWIN_BASE(nasid, 0), pcibr_soft->bs_xid)) ^ 4);
+	}
+
+#ifdef DEBUG
+	printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
+		device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
+
+printk("set_flush_addresses: dma_buf_sync\n");
+	while((volatile unsigned int )*device_sysdata->dma_buf_sync);
+printk("set_flush_addresses: xbow_buf_sync\n");
+	while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
+#endif
+
+}
+
+struct sn_flush_nasid_entry flush_nasid_list[MAX_NASIDS];
+
+// Initialize the data structures for flushing write buffers after a PIO read.
+// The theory is: 
+// Take an unused int. pin and associate it with a pin that is in use.
+// After a PIO read, force an interrupt on the unused pin, forcing a write buffer flush
+// on the in use pin.  This will prevent the race condition between PIO read responses and 
+// DMA writes.
+void
+sn_dma_flush_init(unsigned long start, unsigned long end, int idx, int pin, int slot) {
+	nasid_t nasid; 
+	unsigned long dnasid;
+	int wid_num;
+	int bus;
+	struct sn_flush_device_list *p;
+	bridge_t *b;
+	bridgereg_t dev_sel;
+	extern int isIO9(int);
+	int bwin;
+	int i;
+
+	nasid = NASID_GET(start);
+	wid_num = SWIN_WIDGETNUM(start);
+	bus = (start >> 23) & 0x1;
+	bwin = BWIN_WINDOWNUM(start);
+
+	if (flush_nasid_list[nasid].widget_p == NULL) {
+		flush_nasid_list[nasid].widget_p = (struct sn_flush_device_list **)kmalloc((HUB_WIDGET_ID_MAX+1) *
+			sizeof(struct sn_flush_device_list *), GFP_KERNEL);
+		memset(flush_nasid_list[nasid].widget_p, 0, (HUB_WIDGET_ID_MAX+1) * sizeof(struct sn_flush_device_list *));
+	}
+	if (bwin > 0) {
+		bwin--;
+		switch (bwin) {
+			case 0:
+				flush_nasid_list[nasid].iio_itte1 = HUB_L(IIO_ITTE_GET(nasid, 0));
+				wid_num = ((flush_nasid_list[nasid].iio_itte1) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte1 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 1:
+				flush_nasid_list[nasid].iio_itte2 = HUB_L(IIO_ITTE_GET(nasid, 1));
+				wid_num = ((flush_nasid_list[nasid].iio_itte2) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte2 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 2:
+				flush_nasid_list[nasid].iio_itte3 = HUB_L(IIO_ITTE_GET(nasid, 2));
+				wid_num = ((flush_nasid_list[nasid].iio_itte3) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte3 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 3:
+				flush_nasid_list[nasid].iio_itte4 = HUB_L(IIO_ITTE_GET(nasid, 3));
+				wid_num = ((flush_nasid_list[nasid].iio_itte4) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte4 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 4:
+				flush_nasid_list[nasid].iio_itte5 = HUB_L(IIO_ITTE_GET(nasid, 4));
+				wid_num = ((flush_nasid_list[nasid].iio_itte5) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte5 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 5:
+				flush_nasid_list[nasid].iio_itte6 = HUB_L(IIO_ITTE_GET(nasid, 5));
+				wid_num = ((flush_nasid_list[nasid].iio_itte6) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte6 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 6:
+				flush_nasid_list[nasid].iio_itte7 = HUB_L(IIO_ITTE_GET(nasid, 6));
+				wid_num = ((flush_nasid_list[nasid].iio_itte7) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte7 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+		}
+	}
+
+	// if it's IO9, bus 1, we don't care about slots 1, 3, and 4.  This is
+	// because these are the IOC4 slots and we don't flush them.
+	if (isIO9(nasid) && bus == 0 && (slot == 1 || slot == 4)) {
+		return;
+	}
+	if (flush_nasid_list[nasid].widget_p[wid_num] == NULL) {
+		flush_nasid_list[nasid].widget_p[wid_num] = (struct sn_flush_device_list *)kmalloc(
+			DEV_PER_WIDGET * sizeof (struct sn_flush_device_list), GFP_KERNEL);
+		memset(flush_nasid_list[nasid].widget_p[wid_num], 0, 
+			DEV_PER_WIDGET * sizeof (struct sn_flush_device_list));
+		p = &flush_nasid_list[nasid].widget_p[wid_num][0];
+		for (i=0; i<DEV_PER_WIDGET;i++) {
+			p->bus = -1;
+			p->pin = -1;
+			p++;
+		}
+	}
+
+	p = &flush_nasid_list[nasid].widget_p[wid_num][0];
+	for (i=0;i<DEV_PER_WIDGET; i++) {
+		if (p->pin == pin && p->bus == bus) break;
+		if (p->pin < 0) {
+			p->pin = pin;
+			p->bus = bus;
+			break;
+		}
+		p++;
+	}
+
+	for (i=0; i<PCI_ROM_RESOURCE; i++) {
+		if (p->bar_list[i].start == 0) {
+			p->bar_list[i].start = start;
+			p->bar_list[i].end = end;
+			break;
+		}
+	}
+	b = (bridge_t *)(NODE_SWIN_BASE(nasid, wid_num) | (bus << 23) );
+
+	// If it's IO9, then slot 2 maps to slot 7 and slot 6 maps to slot 8.
+	// To see this is non-trivial.  By drawing pictures and reading manuals and talking
+	// to HW guys, we can see that on IO9 bus 1, slots 7 and 8 are always unused.
+	// Further, since we short-circuit slots  1, 3, and 4 above, we only have to worry
+	// about the case when there is a card in slot 2.  A multifunction card will appear
+	// to be in slot 6 (from an interrupt point of view) also.  That's the  most we'll
+	// have to worry about.  A four function card will overload the interrupt lines in
+	// slot 2 and 6.  
+	// We also need to special case the 12160 device in slot 3.  Fortunately, we have
+	// a spare intr. line for pin 4, so we'll use that for the 12160.
+	// All other buses have slot 3 and 4 and slots 7 and 8 unused.  Since we can only
+	// see slots 1 and 2 and slots 5 and 6 coming through here for those buses (this
+	// is true only on Pxbricks with 2 physical slots per bus), we just need to add
+	// 2 to the slot number to find an unused slot.
+	// We have convinced ourselves that we will never see a case where two different cards
+	// in two different slots will ever share an interrupt line, so there is no need to
+	// special case this.
+
+	if (isIO9(nasid) && wid_num == 0xc && bus == 0) {
+		if (slot == 2) {
+			p->force_int_addr = (unsigned long)&b->b_force_always[6].intr;
+			dev_sel = b->b_int_device;
+			dev_sel |= (1<<18);
+			b->b_int_device = dev_sel;
+			dnasid = NASID_GET(virt_to_phys(&p->flush_addr));
+			b->p_int_addr_64[6] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | 
+				(dnasid << 36) | (0xfUL << 48);
+		} else  if (slot == 3) { /* 12160 SCSI device in IO9 */
+			p->force_int_addr = (unsigned long)&b->b_force_always[4].intr;
+			dev_sel = b->b_int_device;
+			dev_sel |= (2<<12);
+			b->b_int_device = dev_sel;
+			dnasid = NASID_GET(virt_to_phys(&p->flush_addr));
+			b->p_int_addr_64[4] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | 
+				(dnasid << 36) | (0xfUL << 48);
+		} else { /* slot == 6 */
+			p->force_int_addr = (unsigned long)&b->b_force_always[7].intr;
+			dev_sel = b->b_int_device;
+			dev_sel |= (5<<21);
+			b->b_int_device = dev_sel;
+			dnasid = NASID_GET(virt_to_phys(&p->flush_addr));
+			b->p_int_addr_64[7] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | 
+				(dnasid << 36) | (0xfUL << 48);
+		}
+	} else {
+		p->force_int_addr = (unsigned long)&b->b_force_always[pin + 2].intr;
+		dev_sel = b->b_int_device;
+		dev_sel |= ((slot - 1) << ( pin * 3) );
+		b->b_int_device = dev_sel;
+		dnasid = NASID_GET(virt_to_phys(&p->flush_addr));
+		b->p_int_addr_64[pin + 2] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | 
+			(dnasid << 36) | (0xfUL << 48);
+	}
+}
+
+/*
+ * Most drivers currently do not properly tell the arch specific pci dma
+ * interfaces whether they can handle A64. Here is where we privately
+ * keep track of this.
+ */
+static void __init
+set_sn_pci64(struct pci_dev *dev)
+{
+	unsigned short vendor = dev->vendor;
+	unsigned short device = dev->device;
+
+	if (vendor == PCI_VENDOR_ID_QLOGIC) {
+		if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) ||
+				(device == PCI_DEVICE_ID_QLOGIC_ISP2200)) {
+			SET_PCIA64(dev);
+			return;
+		}
+	}
+
+	if (vendor == PCI_VENDOR_ID_SGI) {
+		if (device == PCI_DEVICE_ID_SGI_IOC3) {
+			SET_PCIA64(dev);
+			return;
+		}
+	}
+
+}
+
+/*
+ * sn_pci_fixup() - This routine is called when platform_pci_fixup() is 
+ *	invoked at the end of pcibios_init() to link the Linux pci 
+ *	infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
+ *
+ *	Other platform specific fixup can also be done here.
+ */
+void
+sn_pci_fixup(int arg)
+{
+	struct list_head *ln;
+	struct pci_bus *pci_bus = NULL;
+	struct pci_dev *device_dev = NULL;
+	struct sn_widget_sysdata *widget_sysdata;
+	struct sn_device_sysdata *device_sysdata;
+	pciio_intr_t intr_handle;
+	int cpuid, bit;
+	vertex_hdl_t device_vertex;
+	pciio_intr_line_t lines;
+	extern void sn_pci_find_bios(void);
+	extern int numnodes;
+	int cnode;
+
+	if (arg == 0) {
+#ifdef CONFIG_PROC_FS
+		extern void register_sn_procfs(void);
+#endif
+
+		sn_pci_find_bios();
+		for (cnode = 0; cnode < numnodes; cnode++) {
+			extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
+			intr_init_vecblk(NODEPDA(cnode), cnode, 0);
+		} 
+#ifdef CONFIG_PROC_FS
+		register_sn_procfs();
+#endif
+		return;
+	}
+
+
+	done_probing = 1;
+
+	/*
+	 * Initialize the pci bus vertex in the pci_bus struct.
+	 */
+	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
+		pci_bus = pci_bus_b(ln);
+		widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), 
+					GFP_KERNEL);
+		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
+		pci_bus->sysdata = (void *)widget_sysdata;
+	}
+
+	/*
+ 	 * set the root start and end so that drivers calling check_region()
+	 * won't see a conflict
+	 */
+	ioport_resource.start  = 0xc000000000000000;
+	ioport_resource.end =    0xcfffffffffffffff;
+
+	/*
+	 * Set the root start and end for Mem Resource.
+	 */
+	iomem_resource.start = 0;
+	iomem_resource.end = 0xffffffffffffffff;
+
+	/*
+	 * Initialize the device vertex in the pci_dev struct.
+	 */
+	pci_for_each_dev(device_dev) {
+		unsigned int irq;
+		int idx;
+		u16 cmd;
+		vertex_hdl_t vhdl;
+		unsigned long size;
+		extern int bit_pos_to_irq(int);
+
+		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
+				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
+			extern void pci_fixup_ioc3(struct pci_dev *d);
+			pci_fixup_ioc3(device_dev);
+		}
+
+		/* Set the device vertex */
+
+		device_sysdata = kmalloc(sizeof(struct sn_device_sysdata),
+					GFP_KERNEL);
+		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
+		device_sysdata->isa64 = 0;
+		/*
+		 * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
+		 * register addresses.
+		 */
+		(void) set_flush_addresses(device_dev, device_sysdata);
+
+		device_dev->sysdata = (void *) device_sysdata;
+		set_sn_pci64(device_dev);
+		set_isPIC(device_sysdata);
+
+		pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
+
+		/*
+		 * Set the resources address correctly.  The assumption here 
+		 * is that the addresses in the resource structure has been
+		 * read from the card and it was set in the card by our
+		 * Infrastructure ..
+		 */
+		vhdl = device_sysdata->vhdl;
+		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
+			size = 0;
+			size = device_dev->resource[idx].end -
+				device_dev->resource[idx].start;
+			if (size) {
+				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
+				device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
+			}
+			else
+				continue;
+
+			device_dev->resource[idx].end = 
+				device_dev->resource[idx].start + size;
+
+			if (device_dev->resource[idx].flags & IORESOURCE_IO)
+				cmd |= PCI_COMMAND_IO;
+
+			if (device_dev->resource[idx].flags & IORESOURCE_MEM)
+				cmd |= PCI_COMMAND_MEMORY;
+		}
+#if 0
+	/*
+	 * Software WAR for a Software BUG.
+	 * This is only temporary.
+	 * See PV 872791
+	 */
+
+		/*
+		 * Now handle the ROM resource ..
+		 */
+		size = device_dev->resource[PCI_ROM_RESOURCE].end -
+			device_dev->resource[PCI_ROM_RESOURCE].start;
+
+		if (size) {
+			device_dev->resource[PCI_ROM_RESOURCE].start =
+			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
+				size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
+			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
+			device_dev->resource[PCI_ROM_RESOURCE].end =
+			device_dev->resource[PCI_ROM_RESOURCE].start + size;
+		}
+#endif
+
+		/*
+		 * Update the Command Word on the Card.
+		 */
+		cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */
+					   /* bit gets dropped .. no harm */
+		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
+
+		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
+		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
+			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
+				lines = 1;
+		}
+ 
+		device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;
+		device_vertex = device_sysdata->vhdl;
+ 
+		irqpdaindr->current = device_dev;
+		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
+
+		irq = intr_handle->pi_irq;
+		irqpdaindr->device_dev[irq] = device_dev;
+		cpuid = intr_handle->pi_cpu;
+		pciio_intr_connect(intr_handle, (intr_func_t)0, (intr_arg_t)0);
+		device_dev->irq = irq;
+		register_pcibr_intr(irq, (pcibr_intr_t)intr_handle);
+
+		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
+			int ibits = ((pcibr_intr_t)intr_handle)->bi_ibits;
+			int i;
+
+			size = device_dev->resource[idx].end -
+				device_dev->resource[idx].start;
+			if (size == 0) continue;
+
+			for (i=0; i<8; i++) {
+				if (ibits & (1 << i) ) {
+					sn_dma_flush_init(device_dev->resource[idx].start, 
+							device_dev->resource[idx].end,
+							idx,
+							i,
+							PCI_SLOT(device_dev->devfn));
+				}
+			}
+		}
+
+	}
+#ifdef ajmtestintr
+		{
+			int slot = PCI_SLOT(device_dev->devfn);
+			static int timer_set = 0;
+			pcibr_intr_t	pcibr_intr = (pcibr_intr_t)intr_handle;
+			pcibr_soft_t	pcibr_soft = pcibr_intr->bi_soft;
+			extern void intr_test_handle_intr(int, void*, struct pt_regs *);
+
+			if (!timer_set) {
+				intr_test_set_timer();
+				timer_set = 1;
+			}
+			intr_test_register_irq(irq, pcibr_soft, slot);
+			request_irq(irq, intr_test_handle_intr,0,NULL, NULL);
+		}
+#endif
+}
+
+/*
+ * linux_bus_cvlink() Creates a link between the Linux PCI Bus number 
+ *	to the actual hardware component that it represents:
+ *	/dev/hw/linux/busnum/0 -> ../../../hw/module/001c01/slab/0/Ibrick/xtalk/15/pci
+ *
+ *	The bus vertex, when called to devfs_generate_path() returns:
+ *		hw/module/001c01/slab/0/Ibrick/xtalk/15/pci
+ *		hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/0
+ *		hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/1
+ */
+void
+linux_bus_cvlink(void)
+{
+	char name[8];
+	int index;
+	
+	for (index=0; index < MAX_PCI_XWIDGET; index++) {
+		if (!busnum_to_pcibr_vhdl[index])
+			continue;
+
+		sprintf(name, "%x", index);
+		(void) hwgraph_edge_add(linux_busnum, busnum_to_pcibr_vhdl[index], 
+				name);
+	}
+}
+
+/*
+ * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
+ *
+ *	Linux PCI Bus numbers are assigned from lowest module_id numbers
+ *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
+ *	HUB_WIDGET_ID_MIN:
+ *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
+ *
+ *	Given 2 modules 001c01 and 001c02 we get the following mappings:
+ *		001c01, widgetnum 15 = Bus number 0
+ *		001c01, widgetnum 14 = Bus number 1
+ *		001c02, widgetnum 15 = Bus number 3
+ *		001c02, widgetnum 14 = Bus number 4
+ *		etc.
+ *
+ * The rational for starting Bus Number 0 with Widget number 15 is because 
+ * the system boot disks are always connected via Widget 15 Slot 0 of the 
+ * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
+ * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
+ * module id(Master Cnode) of the system.
+ *	
+ */
+static int 
+pci_bus_map_create(vertex_hdl_t xtalk, char * io_moduleid)
+{
+
+	vertex_hdl_t master_node_vertex = NULL;
+	vertex_hdl_t xwidget = NULL;
+	vertex_hdl_t pci_bus = NULL;
+	hubinfo_t hubinfo = NULL;
+	xwidgetnum_t widgetnum;
+	char pathname[128];
+	graph_error_t rv;
+	int bus;
+	int basebus_num;
+	extern void ioconfig_get_busnum(char *, int *);
+
+	int bus_number;
+
+	/*
+	 * Loop throught this vertex and get the Xwidgets ..
+	 */
+
+
+	/* PCI devices */
+
+	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
+		sprintf(pathname, "%d", widgetnum);
+		xwidget = NULL;
+		
+		/*
+		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
+		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
+		 */
+		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
+		if ( (rv != GRAPH_SUCCESS) ) {
+			if (!xwidget) {
+				continue;
+			}
+		}
+
+		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
+		pci_bus = NULL;
+		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
+			if (!pci_bus) {
+				continue;
+}
+
+		/*
+		 * Assign the correct bus number and also the nasid of this 
+		 * pci Xwidget.
+		 * 
+		 * Should not be any race here ...
+		 */
+		num_bridges++;
+		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
+
+		/*
+		 * Get the master node and from there get the NASID.
+		 */
+		master_node_vertex = device_master_get(xwidget);
+		if (!master_node_vertex) {
+			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
+		}
+	
+		hubinfo_get(master_node_vertex, &hubinfo);
+		if (!hubinfo) {
+			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
+			return(1);
+		} else {
+			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
+		}
+
+		/*
+		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
+		 */
+		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
+			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
+		if (!busnum_to_atedmamaps[num_bridges - 1])
+			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
+
+		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
+			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
+
+	}
+
+	/*
+	 * PCIX devices
+	 * We number busses differently for PCI-X devices.
+	 * We start from Lowest Widget on up ..
+	 */
+
+        (void) ioconfig_get_busnum((char *)io_moduleid, &basebus_num);
+
+	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
+
+		/* Do both buses */
+		for ( bus = 0; bus < 2; bus++ ) {
+			sprintf(pathname, "%d", widgetnum);
+			xwidget = NULL;
+			
+			/*
+			 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
+			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0 is the bus
+			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0/1 is device
+			 */
+			rv = hwgraph_traverse(xtalk, pathname, &xwidget);
+			if ( (rv != GRAPH_SUCCESS) ) {
+				if (!xwidget) {
+					continue;
+				}
+			}
+	
+			if ( bus == 0 )
+				sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);
+			else
+				sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);
+			pci_bus = NULL;
+			if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
+				if (!pci_bus) {
+					continue;
+				}
+	
+			/*
+			 * Assign the correct bus number and also the nasid of this 
+			 * pci Xwidget.
+			 * 
+			 * Should not be any race here ...
+			 */
+			bus_number = basebus_num + bus + io_brick_map_widget(MODULE_PXBRICK, widgetnum);
+#ifdef DEBUG
+			printk("bus_number %d basebus_num %d bus %d io %d\n", 
+				bus_number, basebus_num, bus, 
+				io_brick_map_widget(MODULE_PXBRICK, widgetnum));
+#endif
+			busnum_to_pcibr_vhdl[bus_number] = pci_bus;
+	
+			/*
+			 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
+			 */
+			busnum_to_atedmamaps[bus_number] = (void *) kmalloc(
+				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
+			if (!busnum_to_atedmamaps[bus_number])
+				printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
+	
+			memset(busnum_to_atedmamaps[bus_number], 0x0, 
+				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
+		}
+	}
+
+        return(0);
+}
+
+/*
+ * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure   
+ *      initialization has completed to set up the mappings between Xbridge
+ *      and logical pci bus numbers.  We also set up the NASID for each of these
+ *      xbridges.
+ *
+ *      Must be called before pci_init() is invoked.
+ */
+int
+pci_bus_to_hcl_cvlink(void) 
+{
+
+	vertex_hdl_t devfs_hdl = NULL;
+	vertex_hdl_t xtalk = NULL;
+	int rv = 0;
+	char name[256];
+	char tmp_name[256];
+	int i, ii, j;
+	char *brick_name;
+	extern void ioconfig_bus_new_entries(void);
+
+	/*
+	 * Figure out which IO Brick is connected to the Compute Bricks.
+	 */
+	for (i = 0; i < nummodules; i++) {
+		extern int iomoduleid_get(nasid_t);
+		moduleid_t iobrick_id;
+		nasid_t nasid = -1;
+		int nodecnt;
+		int n = 0;
+
+		nodecnt = modules[i]->nodecnt;
+		for ( n = 0; n < nodecnt; n++ ) {
+			nasid = cnodeid_to_nasid(modules[i]->nodes[n]);
+			iobrick_id = iomoduleid_get(nasid);
+			if ((int)iobrick_id > 0) { /* Valid module id */
+				char name[12];
+				memset(name, 0, 12);
+				format_module_id((char *)&(modules[i]->io[n].moduleid), iobrick_id, MODULE_FORMAT_BRIEF);
+			}
+		}
+	}
+				
+	devfs_hdl = hwgraph_path_to_vertex("hw/module");
+	for (i = 0; i < nummodules ; i++) {
+	    for ( j = 0; j < 3; j++ ) {
+		if ( j == 0 )
+			brick_name = EDGE_LBL_PBRICK;
+		else if ( j == 1 )
+			brick_name = EDGE_LBL_PXBRICK;
+		else
+			brick_name = EDGE_LBL_IXBRICK;
+
+		for ( ii = 0; ii < 2 ; ii++ ) {
+			memset(name, 0, 256);
+			memset(tmp_name, 0, 256);
+			format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
+			sprintf(tmp_name, "/slab/%d/%s/xtalk", geo_slab(modules[i]->geoid[ii]), brick_name);
+			strcat(name, tmp_name);
+			xtalk = NULL;
+			rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
+			if ( rv == 0 ) 
+				pci_bus_map_create(xtalk, (char *)&(modules[i]->io[ii].moduleid));
+		}
+	    }
+	}
+
+	/*
+	 * Create the Linux PCI bus number vertex link.
+	 */
+	(void)linux_bus_cvlink();
+	(void)ioconfig_bus_new_entries();
+
+	return(0);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/machvec/pci_dma.c linux-2.4.22-pre10/arch/ia64/sn/io/machvec/pci_dma.c
--- linux-2.4.21/arch/ia64/sn/io/machvec/pci_dma.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/machvec/pci_dma.c	2003-08-01 13:32:13.000000000 +0000
@@ -0,0 +1,584 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000,2002-2003 Silicon Graphics, Inc. All rights reserved.
+ *
+ * Routines for PCI DMA mapping.  See Documentation/DMA-mapping.txt for
+ * a description of how these routines should be used.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/module.h>
+
+#include <asm/delay.h>
+#include <asm/io.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/types.h>
+#include <asm/sn/alenlist.h>
+#include <asm/sn/pci/pci_bus_cvlink.h>
+#include <asm/sn/nag.h>
+
+/*
+ * For ATE allocations
+ */
+pciio_dmamap_t get_free_pciio_dmamap(vertex_hdl_t);
+void free_pciio_dmamap(pcibr_dmamap_t);
+static struct sn_dma_maps_s *find_sn_dma_map(dma_addr_t, unsigned char);
+void sn_pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction);
+
+/*
+ * Toplogy stuff
+ */
+extern vertex_hdl_t busnum_to_pcibr_vhdl[];
+extern nasid_t busnum_to_nid[];
+extern void * busnum_to_atedmamaps[];
+
+/**
+ * get_free_pciio_dmamap - find and allocate an ATE
+ * @pci_bus: PCI bus to get an entry for
+ *
+ * Finds and allocates an ATE on the PCI bus specified
+ * by @pci_bus.
+ */
+pciio_dmamap_t
+get_free_pciio_dmamap(vertex_hdl_t pci_bus)
+{
+	int i;
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+
+	/*
+	 * Darn, we need to get the maps allocated for this bus.
+	 */
+	for (i = 0; i < MAX_PCI_XWIDGET; i++) {
+		if (busnum_to_pcibr_vhdl[i] == pci_bus) {
+			sn_dma_map = busnum_to_atedmamaps[i];
+		}
+	}
+
+	/*
+	 * Now get a free dmamap entry from this list.
+	 */
+	for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) {
+		if (!sn_dma_map->dma_addr) {
+			sn_dma_map->dma_addr = -1;
+			return( (pciio_dmamap_t) sn_dma_map );
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * free_pciio_dmamap - free an ATE
+ * @dma_map: ATE to free
+ *
+ * Frees the ATE specified by @dma_map.
+ */
+void
+free_pciio_dmamap(pcibr_dmamap_t dma_map)
+{
+	struct sn_dma_maps_s *sn_dma_map;
+
+	sn_dma_map = (struct sn_dma_maps_s *) dma_map;
+	sn_dma_map->dma_addr = 0;
+}
+
+/**
+ * find_sn_dma_map - find an ATE associated with @dma_addr and @busnum
+ * @dma_addr: DMA address to look for
+ * @busnum: PCI bus to look on
+ *
+ * Finds the ATE associated with @dma_addr and @busnum.
+ */
+static struct sn_dma_maps_s *
+find_sn_dma_map(dma_addr_t dma_addr, unsigned char busnum)
+{
+
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+	int i;
+
+	sn_dma_map = busnum_to_atedmamaps[busnum];
+
+	for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) {
+		if (sn_dma_map->dma_addr == dma_addr) {
+			return sn_dma_map;
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * sn_pci_alloc_consistent - allocate memory for coherent DMA
+ * @hwdev: device to allocate for
+ * @size: size of the region
+ * @dma_handle: DMA (bus) address
+ *
+ * pci_alloc_consistent() returns a pointer to a memory region suitable for
+ * coherent DMA traffic to/from a PCI device.  On SN platforms, this means
+ * that @dma_handle will have the %PCIIO_DMA_CMD flag set.
+ *
+ * This interface is usually used for "command" streams (e.g. the command
+ * queue for a SCSI controller).  See Documentation/DMA-mapping.txt for
+ * more information.  Note that this routine will always put a 32 bit
+ * DMA address into @dma_handle.  This is because most devices
+ * that are capable of 64 bit PCI DMA transactions can't do 64 bit _coherent_
+ * DMAs, and unfortunately this interface has to cater to the LCD.  Oh well.
+ *
+ * Also known as platform_pci_alloc_consistent() by the IA64 machvec code.
+ */
+void *
+sn_pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+{
+        void *cpuaddr;
+	vertex_hdl_t vhdl;
+	struct sn_device_sysdata *device_sysdata;
+	unsigned long phys_addr;
+	pciio_dmamap_t dma_map = 0;
+	struct sn_dma_maps_s *sn_dma_map;
+
+	*dma_handle = 0;
+
+	if (hwdev->dma_mask < 0xffffffffUL)
+		return NULL;
+
+	/*
+	 * Get hwgraph vertex for the device
+	 */
+	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
+	vhdl = device_sysdata->vhdl;
+
+	/*
+	 * Allocate the memory.  FIXME: if we're allocating for
+	 * two devices on the same bus, we should at least try to
+	 * allocate memory in the same 2 GB window to avoid using
+	 * ATEs for the translation.  See the comment above about the
+	 * 32 bit requirement for this function.
+	 */
+	if(!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size))))
+		return NULL;
+
+	/* physical addr. of the memory we just got */
+	phys_addr = __pa(cpuaddr);
+
+	/*
+	 * This will try to use a Direct Map register to do the
+	 * 32 bit DMA mapping, but it may not succeed if another
+	 * device on the same bus is already mapped with different
+	 * attributes or to a different memory region.
+	 */
+	*dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					  PCIIO_DMA_CMD);
+
+        /*
+	 * If this device is in PCI-X mode, the system would have
+	 * automatically allocated a 64Bits DMA Address.  Error out if the 
+	 * device cannot support DAC.
+	 */
+	if (*dma_handle > hwdev->consistent_dma_mask) {
+		free_pages((unsigned long) cpuaddr, get_order(size));
+		return NULL;
+	}
+
+	/*
+	 * It is a 32 bit card and we cannot do direct mapping,
+	 * so we try to use an ATE.
+	 */
+	if (!(*dma_handle)) {
+		dma_map = pciio_dmamap_alloc(vhdl, NULL, size,
+				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					     PCIIO_DMA_CMD);
+		if (!dma_map) {
+			printk(KERN_ERR "sn_pci_alloc_consistent: Unable to "
+			       "allocate anymore 32 bit page map entries.\n");
+			return 0;
+		}
+		*dma_handle = (dma_addr_t) pciio_dmamap_addr(dma_map,phys_addr,
+							     size);
+		sn_dma_map = (struct sn_dma_maps_s *)dma_map;
+		sn_dma_map->dma_addr = *dma_handle;
+	}
+
+        return cpuaddr;
+}
+
+/**
+ * sn_pci_free_consistent - free memory associated with coherent DMAable region
+ * @hwdev: device to free for
+ * @size: size to free
+ * @vaddr: kernel virtual address to free
+ * @dma_handle: DMA address associated with this region
+ *
+ * Frees the memory allocated by pci_alloc_consistent().  Also known
+ * as platform_pci_free_consistent() by the IA64 machvec code.
+ */
+void
+sn_pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+{
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+
+	/*
+	 * Get the sn_dma_map entry.
+	 */
+	if (IS_PCI32_MAPPED(dma_handle))
+		sn_dma_map = find_sn_dma_map(dma_handle, hwdev->bus->number);
+
+	/*
+	 * and free it if necessary...
+	 */
+	if (sn_dma_map) {
+		pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
+		pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
+		sn_dma_map->dma_addr = (dma_addr_t)NULL;
+	}
+	free_pages((unsigned long) vaddr, get_order(size));
+}
+
+/**
+ * sn_pci_map_sg - map a scatter-gather list for DMA
+ * @hwdev: device to map for
+ * @sg: scatterlist to map
+ * @nents: number of entries
+ * @direction: direction of the DMA transaction
+ *
+ * Maps each entry of @sg for DMA.  Also known as platform_pci_map_sg by the
+ * IA64 machvec code.
+ */
+int
+sn_pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+{
+
+	int i;
+	vertex_hdl_t vhdl;
+	unsigned long phys_addr;
+	struct sn_device_sysdata *device_sysdata;
+	pciio_dmamap_t dma_map;
+	struct sn_dma_maps_s *sn_dma_map;
+	struct scatterlist *saved_sg = sg;
+
+	/* can't go anywhere w/o a direction in life */
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/*
+	 * Get the hwgraph vertex for the device
+	 */
+	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
+	vhdl = device_sysdata->vhdl;
+
+	/*
+	 * Setup a DMA address for each entry in the
+	 * scatterlist.
+	 */
+	for (i = 0; i < nents; i++, sg++) {
+		phys_addr = __pa(sg->address ? sg->address :
+			page_address(sg->page) + sg->offset);
+
+		/*
+		 * Handle the most common case: 64 bit cards.  This
+		 * call should always succeed.
+		 */
+		if (IS_PCIA64(hwdev)) {
+			sg->dma_address = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
+						       sg->length,
+			       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+						       PCIIO_DMA_DATA |
+						       PCIIO_DMA_A64);
+			sg->dma_length = sg->length;
+			continue;
+		}
+
+		/*
+		 * Handle 32-63 bit cards via direct mapping
+		 */
+		if (IS_PCI32G(hwdev)) {
+			sg->dma_address = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
+						       sg->length,
+					((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+						       PCIIO_DMA_DATA);
+			sg->dma_length = sg->length;
+			/*
+			 * See if we got a direct map entry
+			 */
+			if (sg->dma_address) {
+				continue;
+			}
+
+		}
+
+		/*
+		 * It is a 32 bit card and we cannot do direct mapping,
+		 * so we use an ATE.
+		 */
+		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length,
+				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					     PCIIO_DMA_DATA);
+		if (!dma_map) {
+			printk(KERN_ERR "sn_pci_map_sg: Unable to allocate "
+			       "anymore 32 bit page map entries.\n");
+			/*
+			 * We will need to free all previously allocated entries.
+			 */
+			if (i > 0) {
+				sn_pci_unmap_sg(hwdev, saved_sg, i, direction);
+			}
+			return (0);
+		}
+
+		sg->dma_address = pciio_dmamap_addr(dma_map, phys_addr, sg->length);
+		sg->dma_length = sg->length;
+		sn_dma_map = (struct sn_dma_maps_s *)dma_map;
+		sn_dma_map->dma_addr = sg->dma_address;
+	}
+
+	return nents;
+
+}
+
+/**
+ * sn_pci_unmap_sg - unmap a scatter-gather list
+ * @hwdev: device to unmap
+ * @sg: scatterlist to unmap
+ * @nents: number of scatterlist entries
+ * @direction: DMA direction
+ *
+ * Unmap a set of streaming mode DMA translations.  Again, cpu read rules
+ * concerning calls here are the same as for pci_unmap_single() below.  Also
+ * known as sn_pci_unmap_sg() by the IA64 machvec code.
+ */
+void
+sn_pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+{
+	int i;
+	struct sn_dma_maps_s *sn_dma_map;
+
+	/* can't go anywhere w/o a direction in life */
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	for (i = 0; i < nents; i++, sg++){
+
+		if (IS_PCI32_MAPPED(sg->dma_address)) {
+			sn_dma_map = NULL;
+                	sn_dma_map = find_sn_dma_map(sg->dma_address, hwdev->bus->number);
+        		if (sn_dma_map) {
+                		pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
+                		pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
+                		sn_dma_map->dma_addr = (dma_addr_t)NULL;
+			}
+        	}
+
+		sg->dma_address = (dma_addr_t)NULL;
+		sg->dma_length = 0;
+	}
+}
+
+/**
+ * sn_pci_map_single - map a single region for DMA
+ * @hwdev: device to map for
+ * @ptr: kernel virtual address of the region to map
+ * @size: size of the region
+ * @direction: DMA direction
+ *
+ * Map the region pointed to by @ptr for DMA and return the
+ * DMA address.   Also known as platform_pci_map_single() by
+ * the IA64 machvec code.
+ *
+ * We map this to the one step pciio_dmamap_trans interface rather than
+ * the two step pciio_dmamap_alloc/pciio_dmamap_addr because we have
+ * no way of saving the dmamap handle from the alloc to later free
+ * (which is pretty much unacceptable).
+ *
+ * TODO: simplify our interface;
+ *       get rid of dev_desc and vhdl (seems redundant given a pci_dev);
+ *       figure out how to save dmamap handle so can use two step.
+ */
+dma_addr_t
+sn_pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
+{
+	vertex_hdl_t vhdl;
+	dma_addr_t dma_addr;
+	unsigned long phys_addr;
+	struct sn_device_sysdata *device_sysdata;
+	pciio_dmamap_t dma_map = NULL;
+	struct sn_dma_maps_s *sn_dma_map;
+
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/* SN cannot support DMA addresses smaller than 32 bits. */
+	if (IS_PCI32L(hwdev))
+		return 0;
+
+	/*
+	 * find vertex for the device
+	 */
+	device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata;
+	vhdl = device_sysdata->vhdl;
+
+	/*
+	 * Call our dmamap interface
+	 */
+	dma_addr = 0;
+	phys_addr = __pa(ptr);
+
+	if (IS_PCIA64(hwdev)) {
+		/* This device supports 64 bit DMA addresses. */
+		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+		       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					       PCIIO_DMA_DATA |
+					       PCIIO_DMA_A64);
+		return dma_addr;
+	}
+
+	/*
+	 * Devices that support 32 bit to 63 bit DMA addresses get
+	 * 32 bit DMA addresses.
+	 *
+	 * First try to get a 32 bit direct map register.
+	 */
+	if (IS_PCI32G(hwdev)) {
+		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					       PCIIO_DMA_DATA);
+		if (dma_addr)
+			return dma_addr;
+	}
+
+	/*
+	 * It's a 32 bit card and we cannot do direct mapping so
+	 * let's use the PMU instead.
+	 */
+	dma_map = NULL;
+	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, 
+			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+			PCIIO_DMA_DATA);
+
+	if (!dma_map) {
+		printk(KERN_ERR "pci_map_single: Unable to allocate anymore "
+		       "32 bit page map entries.\n");
+		return 0;
+	}
+
+	dma_addr = (dma_addr_t) pciio_dmamap_addr(dma_map, phys_addr, size);
+	sn_dma_map = (struct sn_dma_maps_s *)dma_map;
+	sn_dma_map->dma_addr = dma_addr;
+
+	return ((dma_addr_t)dma_addr);
+}
+
+/**
+ * sn_pci_unmap_single - unmap a region used for DMA
+ * @hwdev: device to unmap
+ * @dma_addr: DMA address to unmap
+ * @size: size of region
+ * @direction: DMA direction
+ *
+ * Unmaps the region pointed to by @dma_addr.  Also known as
+ * platform_pci_unmap_single() by the IA64 machvec code.
+ */
+void
+sn_pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
+{
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+
+        if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/*
+	 * Get the sn_dma_map entry.
+	 */
+	if (IS_PCI32_MAPPED(dma_addr))
+		sn_dma_map = find_sn_dma_map(dma_addr, hwdev->bus->number);
+
+	/*
+	 * and free it if necessary...
+	 */
+	if (sn_dma_map) {
+		pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
+		pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
+		sn_dma_map->dma_addr = (dma_addr_t)NULL;
+	}
+}
+
+/**
+ * sn_pci_dma_sync_single - make sure all DMAs have completed
+ * @hwdev: device to sync
+ * @dma_handle: DMA address to sync
+ * @size: size of region
+ * @direction: DMA direction
+ *
+ * This routine is supposed to sync the DMA region specified
+ * by @dma_handle into the 'coherence domain'.  We do not need to do 
+ * anything on our platform.
+ */
+void
+sn_pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
+{
+	return;
+
+}
+
+/**
+ * sn_pci_dma_sync_sg - make sure all DMAs have completed
+ * @hwdev: device to sync
+ * @sg: scatterlist to sync
+ * @nents: number of entries in the scatterlist
+ * @direction: DMA direction
+ *
+ * This routine is supposed to sync the DMA regions specified
+ * by @sg into the 'coherence domain'.  We do not need to do anything 
+ * on our platform.
+ */
+void
+sn_pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+{
+	return;
+
+}
+
+/**
+ * sn_dma_supported - test a DMA mask
+ * @hwdev: device to test
+ * @mask: DMA mask to test
+ *
+ * Return whether the given PCI device DMA address mask can be supported
+ * properly.  For example, if your device can only drive the low 24-bits
+ * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
+ * this function.  Of course, SN only supports devices that have 32 or more
+ * address bits when using the PMU.  We could theoretically support <32 bit
+ * cards using direct mapping, but we'll worry about that later--on the off
+ * chance that someone actually wants to use such a card.
+ */
+int
+sn_pci_dma_supported(struct pci_dev *hwdev, u64 mask)
+{
+	if (mask < 0xffffffff)
+		return 0;
+	return 1;
+}
+
+EXPORT_SYMBOL(sn_pci_unmap_single);
+EXPORT_SYMBOL(sn_pci_map_single);
+EXPORT_SYMBOL(sn_pci_dma_sync_single);
+EXPORT_SYMBOL(sn_pci_map_sg);
+EXPORT_SYMBOL(sn_pci_unmap_sg);
+EXPORT_SYMBOL(sn_pci_alloc_consistent);
+EXPORT_SYMBOL(sn_pci_free_consistent);
+EXPORT_SYMBOL(sn_pci_dma_supported);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/ml_SN_init.c linux-2.4.22-pre10/arch/ia64/sn/io/ml_SN_init.c
--- linux-2.4.21/arch/ia64/sn/io/ml_SN_init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/ml_SN_init.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,235 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/bootmem.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/snconfig.h>
-
-extern int numcpus;
-extern char arg_maxnodes[];
-extern cpuid_t master_procid;
-#if defined(CONFIG_IA64_SGI_SN1)
-extern synergy_da_t    *Synergy_da_indr[];
-#endif
-
-extern int hasmetarouter;
-
-int		maxcpus;
-cpumask_t	boot_cpumask;
-hubreg_t	region_mask = 0;
-
-
-extern xwidgetnum_t hub_widget_id(nasid_t);
-
-extern int valid_icache_reasons;	/* Reasons to flush the icache */
-extern int valid_dcache_reasons;	/* Reasons to flush the dcache */
-extern u_char miniroot;
-extern volatile int	need_utlbmiss_patch;
-extern void iograph_early_init(void);
-
-nasid_t master_nasid = INVALID_NASID;
-
-
-/*
- * mlreset(int slave)
- * 	very early machine reset - at this point NO interrupts have been
- * 	enabled; nor is memory, tlb, p0, etc setup.
- *
- * 	slave is zero when mlreset is called for the master processor and
- *	is nonzero thereafter.
- */
-
-
-void
-mlreset(int slave)
-{
-	if (!slave) {
-		/*
-		 * We are the master cpu and node.
-		 */ 
-		master_nasid = get_nasid();
-		set_master_bridge_base();
-
-		/* We're the master processor */
-		master_procid = smp_processor_id();
-		master_nasid = cpuid_to_nasid(master_procid);
-
-		/*
-		 * master_nasid we get back better be same as one from
-		 * get_nasid()
-		 */
-		ASSERT_ALWAYS(master_nasid == get_nasid());
-
-		/* early initialization of iograph */
-		iograph_early_init();
-
-		/* Initialize Hub Pseudodriver Management */
-		hubdev_init();
-
-	} else { /* slave != 0 */
-		/*
-		 * This code is performed ONLY by slave processors.
-		 */
-
-	}
-}
-
-
-/* XXX - Move the meat of this to intr.c ? */
-/*
- * Set up the platform-dependent fields in the nodepda.
- */
-void init_platform_nodepda(nodepda_t *npda, cnodeid_t node)
-{
-	hubinfo_t hubinfo;
-#ifdef CONFIG_IA64_SGI_SN1
-	int	  sn;
-#endif
-
-	extern void router_map_init(nodepda_t *);
-	extern void router_queue_init(nodepda_t *,cnodeid_t);
-	extern void intr_init_vecblk(nodepda_t *, cnodeid_t, int);
-
-	/* Allocate per-node platform-dependent data */
-	hubinfo = (hubinfo_t)alloc_bootmem_node(NODE_DATA(node), sizeof(struct hubinfo_s));
-
-	npda->pdinfo = (void *)hubinfo;
-	hubinfo->h_nodepda = npda;
-	hubinfo->h_cnodeid = node;
-	hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(node);
-
-	spin_lock_init(&hubinfo->h_crblock);
-
-	hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid);
-	npda->xbow_peer = INVALID_NASID;
-
-	/* 
-	 * Initialize the linked list of
-	 * router info pointers to the dependent routers
-	 */
-	npda->npda_rip_first = NULL;
-
-	/*
-	 * npda_rip_last always points to the place
-	 * where the next element is to be inserted
-	 * into the list 
-	 */
-	npda->npda_rip_last = &npda->npda_rip_first;
-	npda->module_id = INVALID_MODULE;
-
-#ifdef CONFIG_IA64_SGI_SN1
-	/*
-	* Initialize the interrupts.
-	* On sn2, this is done at pci init time,
-	* because sn2 needs the cpus checked in
-	* when it initializes interrupts.  This is
-	* so we don't see all the nodes as headless.
-	*/
-	for (sn=0; sn<NUM_SUBNODES; sn++) {
-		intr_init_vecblk(npda, node, sn);
-	}
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-	mutex_init_locked(&npda->xbow_sema); /* init it locked? */
-
-#ifdef	LATER
-
-	/* Setup the (module,slot) --> nic mapping for all the routers
-	 * in the system. This is useful during error handling when
-	 * there is no shared memory.
-	 */
-	router_map_init(npda);
-
-	/* Allocate memory for the per-node router traversal queue */
-	router_queue_init(npda,node);
-	npda->sbe_info = alloc_bootmem_node(NODE_DATA(node), sizeof (sbe_info_t));
-	ASSERT(npda->sbe_info);
-
-#endif /* LATER */
-}
-
-/* XXX - Move the interrupt stuff to intr.c ? */
-/*
- * Set up the platform-dependent fields in the processor pda.
- * Must be done _after_ init_platform_nodepda().
- * If we need a lock here, something else is wrong!
- */
-void init_platform_pda(cpuid_t cpu)
-{
-#if defined(CONFIG_IA64_SGI_SN1)
-	hub_intmasks_t *intmasks;
-	int i, subnode;
-	cnodeid_t	cnode;
-	synergy_da_t	*sda;
-	int	which_synergy;
-
-
-	cnode = cpuid_to_cnodeid(cpu);
-	which_synergy = cpuid_to_synergy(cpu);
-
-	sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-	intmasks = &sda->s_intmasks;
-
-	/* Clear INT_PEND0 masks. */
-	for (i = 0; i < N_INTPEND0_MASKS; i++)
-		intmasks->intpend0_masks[i] = 0;
-
-	/* Set up pointer to the vector block in the nodepda. */
-	/* (Cant use SUBNODEPDA - not working yet) */
-	subnode = cpuid_to_subnode(cpu);
-	intmasks->dispatch0 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch0;
-	intmasks->dispatch1 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch1;
-	if (intmasks->dispatch0 !=  &SUBNODEPDA(cnode, subnode)->intr_dispatch0 ||
-	   intmasks->dispatch1 !=  &SUBNODEPDA(cnode, subnode)->intr_dispatch1)
-	   	panic("xxx");
-	intmasks->dispatch0 = &SUBNODEPDA(cnode, subnode)->intr_dispatch0;
-	intmasks->dispatch1 = &SUBNODEPDA(cnode, subnode)->intr_dispatch1;
-
-	/* Clear INT_PEND1 masks. */
-	for (i = 0; i < N_INTPEND1_MASKS; i++)
-		intmasks->intpend1_masks[i] = 0;
-#endif	/* CONFIG_IA64_SGI_SN1 */
-}
-
-void
-update_node_information(cnodeid_t cnodeid)
-{
-	nodepda_t *npda = NODEPDA(cnodeid);
-	nodepda_router_info_t *npda_rip;
-	
-	/* Go through the list of router info 
-	 * structures and copy some frequently
-	 * accessed info from the info hanging
-	 * off the corresponding router vertices
-	 */
-	npda_rip = npda->npda_rip_first;
-	while(npda_rip) {
-		if (npda_rip->router_infop) {
-			npda_rip->router_portmask = 
-				npda_rip->router_infop->ri_portmask;
-			npda_rip->router_slot = 
-				npda_rip->router_infop->ri_slotnum;
-		} else {
-			/* No router, no ports. */
-			npda_rip->router_portmask = 0;
-		}
-		npda_rip = npda_rip->router_next;
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/ml_iograph.c linux-2.4.22-pre10/arch/ia64/sn/io/ml_iograph.c
--- linux-2.4.21/arch/ia64/sn/io/ml_iograph.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/ml_iograph.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1570 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-
-/* #define IOGRAPH_DEBUG */
-#ifdef IOGRAPH_DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* IOGRAPH_DEBUG */
-
-/* #define PROBE_TEST */
-
-/* At most 2 hubs can be connected to an xswitch */
-#define NUM_XSWITCH_VOLUNTEER 2
-
-/*
- * Track which hubs have volunteered to manage devices hanging off of
- * a Crosstalk Switch (e.g. xbow).  This structure is allocated,
- * initialized, and hung off the xswitch vertex early on when the
- * xswitch vertex is created.
- */
-typedef struct xswitch_vol_s {
-	mutex_t xswitch_volunteer_mutex;
-	int		xswitch_volunteer_count;
-	devfs_handle_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];
-} *xswitch_vol_t;
-
-void
-xswitch_vertex_init(devfs_handle_t xswitch)
-{
-	xswitch_vol_t xvolinfo;
-	int rc;
-
-	xvolinfo = kmalloc(sizeof(struct xswitch_vol_s), GFP_KERNEL);
-	mutex_init(&xvolinfo->xswitch_volunteer_mutex);
-	xvolinfo->xswitch_volunteer_count = 0;
-	rc = hwgraph_info_add_LBL(xswitch, 
-			INFO_LBL_XSWITCH_VOL,
-			(arbitrary_info_t)xvolinfo);
-	ASSERT(rc == GRAPH_SUCCESS); rc = rc;
-}
-
-
-/*
- * When assignment of hubs to widgets is complete, we no longer need the
- * xswitch volunteer structure hanging around.  Destroy it.
- */
-static void
-xswitch_volunteer_delete(devfs_handle_t xswitch)
-{
-	xswitch_vol_t xvolinfo;
-	int rc;
-
-	rc = hwgraph_info_remove_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL,
-				(arbitrary_info_t *)&xvolinfo);
-#ifdef LATER
-	ASSERT(rc == GRAPH_SUCCESS); rc = rc;
-#endif
-
-	kfree(xvolinfo);
-}
-/*
- * A Crosstalk master volunteers to manage xwidgets on the specified xswitch.
- */
-/* ARGSUSED */
-static void
-volunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master)
-{
-	xswitch_vol_t xvolinfo = NULL;
-
-	(void)hwgraph_info_get_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL, 
-				(arbitrary_info_t *)&xvolinfo);
-	if (xvolinfo == NULL) {
-#ifdef LATER
-	    if (!is_headless_node_vertex(master)) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		printk(KERN_WARNING  "volunteer for widgets: vertex %v has no info label",
-			xswitch);
-#else
-		printk(KERN_WARNING  "volunteer for widgets: vertex 0x%x has no info label",
-			xswitch);
-#endif
-	    }
-#endif	/* LATER */
-	    return;
-	}
-
-	mutex_lock(&xvolinfo->xswitch_volunteer_mutex);
-	ASSERT(xvolinfo->xswitch_volunteer_count < NUM_XSWITCH_VOLUNTEER);
-	xvolinfo->xswitch_volunteer[xvolinfo->xswitch_volunteer_count] = master;
-	xvolinfo->xswitch_volunteer_count++;
-	mutex_unlock(&xvolinfo->xswitch_volunteer_mutex);
-}
-
-extern int xbow_port_io_enabled(nasid_t nasid, int widgetnum);
-
-/*
- * Assign all the xwidgets hanging off the specified xswitch to the
- * Crosstalk masters that have volunteered for xswitch duty.
- */
-/* ARGSUSED */
-static void
-assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv)
-{
-	int curr_volunteer, num_volunteer;
-	xwidgetnum_t widgetnum;
-	xswitch_info_t xswitch_info;
-	xswitch_vol_t xvolinfo = NULL;
-	nasid_t nasid;
-	hubinfo_t hubinfo;
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-	
-	xswitch_info = xswitch_info_get(xswitch);
-	ASSERT(xswitch_info != NULL);
-
-	(void)hwgraph_info_get_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL, 
-				(arbitrary_info_t *)&xvolinfo);
-	if (xvolinfo == NULL) {
-#ifdef LATER
-	    if (!is_headless_node_vertex(hubv)) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		printk(KERN_WARNING  "assign_widgets_to_volunteers:vertex %v has "
-			" no info label",
-			xswitch);
-#else
-		printk(KERN_WARNING  "assign_widgets_to_volunteers:vertex 0x%x has "
-			" no info label",
-			xswitch);
-#endif
-	    }
-#endif	/* LATER */
-	    return;
-	}
-
-	num_volunteer = xvolinfo->xswitch_volunteer_count;
-	ASSERT(num_volunteer > 0);
-	curr_volunteer = 0;
-
-	/* Assign master hub for xswitch itself.  */
-	if (HUB_WIDGET_ID_MIN > 0) {
-		hubv = xvolinfo->xswitch_volunteer[0];
-		xswitch_info_master_assignment_set(xswitch_info, (xwidgetnum_t)0, hubv);
-	}
-
-	/*
-	 * TBD: Use administrative information to alter assignment of
-	 * widgets to hubs.
-	 */
-	for (widgetnum=HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
-
-		/*
-		 * Ignore disabled/empty ports.
-		 */
-		if (!xbow_port_io_enabled(nasid, widgetnum)) 
-		    continue;
-
-		/*
-		 * If this is the master IO board, assign it to the same 
-		 * hub that owned it in the prom.
-		 */
-		if (is_master_nasid_widget(nasid, widgetnum)) {
-			int i;
-
-			for (i=0; i<num_volunteer; i++) {
-				hubv = xvolinfo->xswitch_volunteer[i];
-				hubinfo_get(hubv, &hubinfo);
-				nasid = hubinfo->h_nasid;
-				if (nasid == get_console_nasid())
-					goto do_assignment;
-			}
-#ifdef LATER
-			PRINT_PANIC("Nasid == %d, console nasid == %d",
-				nasid, get_console_nasid());
-#endif
-		}
-
-
-		/*
-		 * Do a round-robin assignment among the volunteer nodes.
-		 */
-		hubv = xvolinfo->xswitch_volunteer[curr_volunteer];
-		curr_volunteer = (curr_volunteer + 1) % num_volunteer;
-		/* fall through */
-
-do_assignment:
-		/*
-		 * At this point, we want to make hubv the master of widgetnum.
-		 */
-		xswitch_info_master_assignment_set(xswitch_info, widgetnum, hubv);
-	}
-
-	xswitch_volunteer_delete(xswitch);
-}
-
-/*
- * Early iograph initialization.  Called by master CPU in mlreset().
- * Useful for including iograph.o in kernel.o.
- */
-void
-iograph_early_init(void)
-{
-/*
- * Need new way to get this information ..
- */
-	cnodeid_t cnode;
-	nasid_t nasid;
-	lboard_t *board;
-	
-	/*
-	 * Init. the board-to-hwgraph link early, so FRU analyzer
-	 * doesn't trip on leftover values if we panic early on.
-	 */
-	for(cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-		board = (lboard_t *)KL_CONFIG_INFO(nasid);
-		DBG("iograph_early_init: Found board 0x%p\n", board);
-
-		/* Check out all the board info stored on a node */
-		while(board) {
-			board->brd_graph_link = GRAPH_VERTEX_NONE;
-			board = KLCF_NEXT(board);
-			DBG("iograph_early_init: Found board 0x%p\n", board);
-
-
-		}
-	}
-
-	hubio_init();
-}
-
-#ifdef LINUX_KERNEL_THREADS
-static struct semaphore io_init_sema;
-#endif
-
-/*
- * Let boot processor know that we're done initializing our node's IO
- * and then exit.
- */
-/* ARGSUSED */
-static void
-io_init_done(cnodeid_t cnodeid,cpu_cookie_t c)
-{
-	/* Let boot processor know that we're done. */
-#ifdef LINUX_KERNEL_THREADS
-	up(&io_init_sema);
-#endif
-#ifdef LATER
-	/* This is for the setnoderun done when the io_init thread
-	 * started 
-	 */
-	restorenoderun(c);
-	sthread_exit();
-#endif
-}
-
-/* 
- * Probe to see if this hub's xtalk link is active.  If so,
- * return the Crosstalk Identification of the widget that we talk to.  
- * This is called before any of the Crosstalk infrastructure for 
- * this hub is set up.  It's usually called on the node that we're
- * probing, but not always.
- *
- * TBD: Prom code should actually do this work, and pass through 
- * hwid for our use.
- */
-static void
-early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid)
-{
-	hubreg_t llp_csr_reg;
-	nasid_t nasid;
-	hubinfo_t hubinfo;
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-
-	llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
-	/* 
-	 * If link is up, read the widget's part number.
-	 * A direct connect widget must respond to widgetnum=0.
-	 */
-	if (llp_csr_reg & IIO_LLP_CSR_IS_UP) {
-		/* TBD: Put hub into "indirect" mode */
-		/*
-		 * We're able to read from a widget because our hub's 
-		 * WIDGET_ID was set up earlier.
-		 */
-		widgetreg_t widget_id = *(volatile widgetreg_t *)
-			(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
-
-		DBG("early_probe_for_widget: Hub Vertex 0x%p is UP widget_id = 0x%x Register 0x%p\n", hubv, widget_id,
-		(volatile widgetreg_t *)(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID) );
-
-		hwid->part_num = XWIDGET_PART_NUM(widget_id);
-		hwid->rev_num = XWIDGET_REV_NUM(widget_id);
-		hwid->mfg_num = XWIDGET_MFG_NUM(widget_id);
-
-		/* TBD: link reset */
-	} else {
-
-		hwid->part_num = XWIDGET_PART_NUM_NONE;
-		hwid->rev_num = XWIDGET_REV_NUM_NONE;
-		hwid->mfg_num = XWIDGET_MFG_NUM_NONE;
-	}
-
-}
-
-/* Add inventory information to the widget vertex 
- * Right now (module,slot,revision) is being
- * added as inventory information.
- */
-static void
-xwidget_inventory_add(devfs_handle_t 		widgetv,
-		      lboard_t 			*board,
-		      struct xwidget_hwid_s 	hwid)
-{
-	if (!board)
-		return;
-	/* Donot add inventory information for the baseio
-	 * on a speedo with an xbox. It has already been
-	 * taken care of in SN00_vmc.
-	 * Speedo with xbox's baseio comes in at slot io1 (widget 9)
-	 */
-	device_inventory_add(widgetv,INV_IOBD,board->brd_type,
-			     board->brd_module,
-			     SLOTNUM_GETSLOT(board->brd_slot),
-			     hwid.rev_num);
-}
-
-/*
- * io_xswitch_widget_init
- *	
- */
-
-/* defined in include/linux/ctype.h  */
-/* #define toupper(c)	(islower(c) ? (c) - 'a' + 'A' : (c)) */
-
-void
-io_xswitch_widget_init(devfs_handle_t  	xswitchv,
-		       devfs_handle_t	hubv,
-		       xwidgetnum_t	widgetnum,
-		       async_attach_t	aa)
-{
-	xswitch_info_t		xswitch_info;
-	xwidgetnum_t		hub_widgetid;
-	devfs_handle_t		widgetv;
-	cnodeid_t		cnode;
-	widgetreg_t		widget_id;
-	nasid_t			nasid, peer_nasid;
-	struct xwidget_hwid_s 	hwid;
-	hubinfo_t		hubinfo;
-	/*REFERENCED*/
-	int			rc;
-	char			slotname[SLOTNUM_MAXLENGTH];
-	char 			pathname[128];
-	char			new_name[64];
-	moduleid_t		module;
-	slotid_t		slot;
-	lboard_t		*board = NULL;
-	char			buffer[16];
-	slotid_t get_widget_slotnum(int xbow, int widget);
-	
-	DBG("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum);
-	/*
-	 * Verify that xswitchv is indeed an attached xswitch.
-	 */
-	xswitch_info = xswitch_info_get(xswitchv);
-	ASSERT(xswitch_info != NULL);
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-	cnode = NASID_TO_COMPACT_NODEID(nasid);
-	hub_widgetid = hubinfo->h_widgetid;
-
-
-	/* Who's the other guy on out crossbow (if anyone) */
-	peer_nasid = NODEPDA(cnode)->xbow_peer;
-	if (peer_nasid == INVALID_NASID)
-		/* If I don't have a peer, use myself. */
-		peer_nasid = nasid;
-
-
-	/* Check my xbow structure and my peer's */
-	if (!xbow_port_io_enabled(nasid, widgetnum) &&
-	    !xbow_port_io_enabled(peer_nasid, widgetnum)) {
-		return;
-	}
-
-	if (xswitch_info_link_ok(xswitch_info, widgetnum)) {
-		char			name[4];
-		/*
-		 * If the current hub is not supposed to be the master 
-		 * for this widgetnum, then skip this widget.
-		 */
-		if (xswitch_info_master_assignment_get(xswitch_info,
-						       widgetnum) != hubv) {
-			return;
-		}
-
-		module  = NODEPDA(cnode)->module_id;
-#ifdef XBRIDGE_REGS_SIM
-		/* hardwire for now...could do this with something like:
-		 * xbow_soft_t soft = hwgraph_fastinfo_get(vhdl);
-		 * xbow_t xbow = soft->base;
-		 * xbowreg_t xwidget_id = xbow->xb_wid_id;
-		 * but I don't feel like figuring out vhdl right now..
-		 * and I know for a fact the answer is 0x2d000049 
-		 */
-		DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n");
-		DBG("XWIDGET_PART_NUM(0x2d000049)= 0x%x\n", XWIDGET_PART_NUM(0x2d000049));
-		if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) {
-#else
-		if (nasid_has_xbridge(nasid)) {
-#endif /* XBRIDGE_REGS_SIM */
-			board = find_lboard_module_class(
-				(lboard_t *)KL_CONFIG_INFO(nasid),
-				module,
-				KLTYPE_IOBRICK);
-
-DBG("io_xswitch_widget_init: Board 0x%p\n", board);
-{
-		lboard_t dummy;
-
-
-			if (board) {
-				DBG("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type);
-			} else {
-				DBG("io_xswitch_widget_init: FIXME did not find IOBOARD\n");
-				board = &dummy;
-			}
-				
-}
-
-			/*
-	 		 * Make sure we really want to say xbrick, pbrick,
-			 * etc. rather than XIO, graphics, etc.
-	 		 */
-
-#ifdef SUPPORT_PRINTING_M_FORMAT
-			sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-				"%cbrick" "/%s/%d",
-				NODEPDA(cnode)->module_id,
-				
-#else
-			memset(buffer, 0, 16);
-			format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF);
-			sprintf(pathname, EDGE_LBL_MODULE "/%s/"
-				"%cbrick" "/%s/%d",
-				buffer,
-#endif
-
-				(board->brd_type == KLTYPE_IBRICK) ? 'I' :
-				(board->brd_type == KLTYPE_PBRICK) ? 'P' :
-				(board->brd_type == KLTYPE_XBRICK) ? 'X' : '?',
-				EDGE_LBL_XTALK, widgetnum);
-		} 
-		
-		DBG("io_xswitch_widget_init: path= %s\n", pathname);
-		rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv);
-		
-		ASSERT(rc == GRAPH_SUCCESS);
-
-		/* This is needed to let the user programs to map the
-		 * module,slot numbers to the corresponding widget numbers
-		 * on the crossbow.
-		 */
-		rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv);
-
-		/* If we are looking at the global master io6
-		 * then add information about the version of
-		 * the io6prom as a part of "detailed inventory"
-		 * information.
-		 */
-		if (is_master_baseio(nasid,
-				     NODEPDA(cnode)->module_id,
- 				     get_widget_slotnum(0,widgetnum))) {
-			extern void klhwg_baseio_inventory_add(devfs_handle_t,
-							       cnodeid_t);
-			module 	= NODEPDA(cnode)->module_id;
-
-#ifdef XBRIDGE_REGS_SIM
-			DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n");
-			if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) {
-#else
-			if (nasid_has_xbridge(nasid)) {
-#endif /* XBRIDGE_REGS_SIM */
-				board = find_lboard_module(
-					(lboard_t *)KL_CONFIG_INFO(nasid),
-					module);
-				/*
-				 * Change iobrick to correct i/o brick
-				 */
-#ifdef SUPPORT_PRINTING_M_FORMAT
-				sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-#else
-				sprintf(pathname, EDGE_LBL_MODULE "/%x/"
-#endif
-					"iobrick" "/%s/%d",
-					NODEPDA(cnode)->module_id,
-					EDGE_LBL_XTALK, widgetnum);
-			} else {
-				slot = get_widget_slotnum(0, widgetnum);
-				board = get_board_name(nasid, module, slot,
-								new_name);
-				/*
-			 	 * Create the vertex for the widget, 
-				 * using the decimal 
-			 	 * widgetnum as the name of the primary edge.
-			 	 */
-#ifdef SUPPORT_PRINTING_M_FORMAT
-				sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-                                                EDGE_LBL_SLOT "/%s/%s",
-                                        NODEPDA(cnode)->module_id,
-                                        slotname, new_name);
-#else
-				memset(buffer, 0, 16);
-				format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF);
-				sprintf(pathname, EDGE_LBL_MODULE "/%s/"
-					  	EDGE_LBL_SLOT "/%s/%s",
-					buffer,
-					slotname, new_name);
-#endif
-			}
-
-			rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv);
-			DBG("io_xswitch_widget_init: (2) path= %s\n", pathname);
-		        /*
-		         * This is a weird ass code needed for error injection
-		         * purposes.
-		         */
-		        rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv);
-			
-			klhwg_baseio_inventory_add(widgetv,cnode);
-		}
-		sprintf(name, "%d", widgetnum);
-		DBG("io_xswitch_widget_init: FIXME hwgraph_edge_add %s xswitchv 0x%p, widgetv 0x%p\n", name, xswitchv, widgetv);
-		rc = hwgraph_edge_add(xswitchv, widgetv, name);
-		
-		/*
-		 * crosstalk switch code tracks which
-		 * widget is attached to each link.
-		 */
-		xswitch_info_vhdl_set(xswitch_info, widgetnum, widgetv);
-		
-		/*
-		 * Peek at the widget to get its crosstalk part and
-		 * mfgr numbers, then present it to the generic xtalk
-		 * bus provider to have its driver attach routine
-		 * called (or not).
-		 */
-#ifdef XBRIDGE_REGS_SIM
-		widget_id = 0x2d000049;
-		DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: id hardwired to widget_id\n");
-#else
-		widget_id = XWIDGET_ID_READ(nasid, widgetnum);
-#endif /* XBRIDGE_REGS_SIM */
-		hwid.part_num = XWIDGET_PART_NUM(widget_id);
-		hwid.rev_num = XWIDGET_REV_NUM(widget_id);
-		hwid.mfg_num = XWIDGET_MFG_NUM(widget_id);
-		/* Store some inventory information about
-		 * the xwidget in the hardware graph.
-		 */
-		xwidget_inventory_add(widgetv,board,hwid);
-		
-		(void)xwidget_register(&hwid, widgetv, widgetnum,
-				       hubv, hub_widgetid,
-				       aa);
-
-#ifdef	SN0_USE_BTE
-		bte_bpush_war(cnode, (void *)board);
-#endif
-	}
-
-}
-
-
-static void
-io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode)
-{
-	xwidgetnum_t		widgetnum;
-	async_attach_t          aa;
-
-	aa = async_attach_new();
-	
-	DBG("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode);
-
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; 
-	     widgetnum++) {
-		io_xswitch_widget_init(xswitchv,
-				       cnodeid_to_vertex(cnode),
-				       widgetnum, aa);
-	}
-	/* 
-	 * Wait for parallel attach threads, if any, to complete.
-	 */
-	async_attach_waitall(aa);
-	async_attach_free(aa);
-}
-
-/*
- * For each PCI bridge connected to the xswitch, add a link from the
- * board's klconfig info to the bridge's hwgraph vertex.  This lets
- * the FRU analyzer find the bridge without traversing the hardware
- * graph and risking hangs.
- */
-static void
-io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid)
-{
-	xwidgetnum_t		widgetnum;
-	char 			pathname[128];
-	devfs_handle_t		vhdl;
-	nasid_t			nasid, peer_nasid;
-	lboard_t		*board;
-
-
-
-	/* And its connected hub's nasids */
-	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
-	peer_nasid = NODEPDA(cnodeid)->xbow_peer;
-
-	/* 
-	 * Look for paths matching "<widgetnum>/pci" under xswitchv.
-	 * For every widget, init. its lboard's hwgraph link.  If the
-	 * board has a PCI bridge, point the link to it.
-	 */
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX;
-		 widgetnum++) {
-		sprintf(pathname, "%d", widgetnum);
-		if (hwgraph_traverse(xswitchv, pathname, &vhdl) !=
-		    GRAPH_SUCCESS)
-			continue;
-
-		board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid),
-				NODEPDA(cnodeid)->module_id);
-		if (board == NULL && peer_nasid != INVALID_NASID) {
-			/*
-			 * Try to find the board on our peer
-			 */
-			board = find_lboard_module(
-				(lboard_t *)KL_CONFIG_INFO(peer_nasid),
-				NODEPDA(cnodeid)->module_id);
-		}
-		if (board == NULL) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-			printk(KERN_WARNING  "Could not find PROM info for vertex %v, "
-				"FRU analyzer may fail",
-				vhdl);
-#else
-			printk(KERN_WARNING  "Could not find PROM info for vertex 0x%p, "
-				"FRU analyzer may fail",
-				(void *)vhdl);
-#endif
-			return;
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		if (hwgraph_traverse(xswitchv, pathname, &vhdl) == 
-		    GRAPH_SUCCESS)
-			board->brd_graph_link = vhdl;
-		else
-			board->brd_graph_link = GRAPH_VERTEX_NONE;
-	}
-}
-
-/*
- * Initialize all I/O on the specified node.
- */
-static void
-io_init_node(cnodeid_t cnodeid)
-{
-	/*REFERENCED*/
-	devfs_handle_t hubv, switchv, widgetv;
-	struct xwidget_hwid_s hwid;
-	hubinfo_t hubinfo;
-	int is_xswitch;
-	nodepda_t	*npdap;
-	struct semaphore *peer_sema = 0;
-	uint32_t	widget_partnum;
-	nodepda_router_info_t *npda_rip;
-	cpu_cookie_t	c = 0;
-	extern int hubdev_docallouts(devfs_handle_t);
-
-#ifdef LATER
-	/* Try to execute on the node that we're initializing. */
-	c = setnoderun(cnodeid);
-#endif
-	npdap = NODEPDA(cnodeid);
-
-	/*
-	 * Get the "top" vertex for this node's hardware
-	 * graph; it will carry the per-hub hub-specific
-	 * data, and act as the crosstalk provider master.
-	 * It's canonical path is probably something of the
-	 * form /hw/module/%M/slot/%d/node
-	 */
-	hubv = cnodeid_to_vertex(cnodeid);
-	DBG("io_init_node: Initialize IO for cnode %d hubv(node) 0x%p npdap 0x%p\n", cnodeid, hubv, npdap);
-
-	ASSERT(hubv != GRAPH_VERTEX_NONE);
-
-	hubdev_docallouts(hubv);
-
-	/*
-	 * Set up the dependent routers if we have any.
-	 */
-	npda_rip = npdap->npda_rip_first;
-
-	while(npda_rip) {
-		/* If the router info has not been initialized
-		 * then we need to do the router initialization
-		 */
-		if (!npda_rip->router_infop) {
-			router_init(cnodeid,0,npda_rip);
-		}
-		npda_rip = npda_rip->router_next;
-	}
-
-	/*
-	 * Read mfg info on this hub
-	 */
-#ifdef LATER
-	printk("io_init_node: FIXME need to implement HUB_VERTEX_MFG_INFO\n");
-	HUB_VERTEX_MFG_INFO(hubv);
-#endif /* LATER */
-
-	/* 
-	 * If nothing connected to this hub's xtalk port, we're done.
-	 */
-	early_probe_for_widget(hubv, &hwid);
-	if (hwid.part_num == XWIDGET_PART_NUM_NONE) {
-#ifdef PROBE_TEST
-		if ((cnodeid == 1) || (cnodeid == 2)) {
-			int index;
-
-			for (index = 0; index < 600; index++)
-				DBG("Interfering with device probing!!!\n");
-		}
-#endif
-		/* io_init_done takes cpu cookie as 2nd argument 
-		 * to do a restorenoderun for the setnoderun done 
-		 * at the start of this thread 
-		 */
-		
-		DBG("**** io_init_node: Node's 0x%p hub widget has XWIDGET_PART_NUM_NONE ****\n", hubv);
-		return;
-		/* NOTREACHED */
-	}
-
-	/* 
-	 * attach our hub_provider information to hubv,
-	 * so we can use it as a crosstalk provider "master"
-	 * vertex.
-	 */
-	xtalk_provider_register(hubv, &hub_provider);
-	xtalk_provider_startup(hubv);
-
-	/*
-	 * Create a vertex to represent the crosstalk bus
-	 * attached to this hub, and a vertex to be used
-	 * as the connect point for whatever is out there
-	 * on the other side of our crosstalk connection.
-	 *
-	 * Crosstalk Switch drivers "climb up" from their
-	 * connection point to try and take over the switch
-	 * point.
-	 *
-	 * Of course, the edges and verticies may already
-	 * exist, in which case our net effect is just to
-	 * associate the "xtalk_" driver with the connection
-	 * point for the device.
-	 */
-
-	(void)hwgraph_path_add(hubv, EDGE_LBL_XTALK, &switchv);
-
-	DBG("io_init_node: Created 'xtalk' entry to '../node/' xtalk vertex 0x%p\n", switchv);
-
-	ASSERT(switchv != GRAPH_VERTEX_NONE);
-
-	(void)hwgraph_edge_add(hubv, switchv, EDGE_LBL_IO);
-
-	DBG("io_init_node: Created symlink 'io' from ../node/io to ../node/xtalk \n");
-
-	/*
-	 * We need to find the widget id and update the basew_id field
-	 * accordingly. In particular, SN00 has direct connected bridge,
-	 * and hence widget id is Not 0.
-	 */
-
-	widget_partnum = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + WIDGET_ID))) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT;
-
-	if (widget_partnum == BRIDGE_WIDGET_PART_NUM ||
-				widget_partnum == XBRIDGE_WIDGET_PART_NUM){
-		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-
-		DBG("io_init_node: Found XBRIDGE widget_partnum= 0x%x\n", widget_partnum);
-
-	} else if (widget_partnum == XBOW_WIDGET_PART_NUM ||
-				widget_partnum == XXBOW_WIDGET_PART_NUM) {
-		/* 
-		 * Xbow control register does not have the widget ID field.
-		 * So, hard code the widget ID to be zero.
-		 */
-		DBG("io_init_node: Found XBOW widget_partnum= 0x%x\n", widget_partnum);
-		npdap->basew_id = 0;
-
-	} else if (widget_partnum == XG_WIDGET_PART_NUM) {
-		/* 
-		 * OK, WTF do we do here if we have an XG direct connected to a HUB/Bedrock???
-		 * So, hard code the widget ID to be zero?
-		 */
-		npdap->basew_id = 0;
-		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-	} else { 
-		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-
-		panic(" ****io_init_node: Unknown Widget Part Number 0x%x Widgt ID 0x%x attached to Hubv 0x%p ****\n", widget_partnum, npdap->basew_id, (void *)hubv);
-
-		/*NOTREACHED*/
-	}
-	{
-		char widname[10];
-		sprintf(widname, "%x", npdap->basew_id);
-		(void)hwgraph_path_add(switchv, widname, &widgetv);
-		DBG("io_init_node: Created '%s' to '..node/xtalk/' vertex 0x%p\n", widname, widgetv);
-		ASSERT(widgetv != GRAPH_VERTEX_NONE);
-	}
-	
-	nodepda->basew_xc = widgetv;
-
-	is_xswitch = xwidget_hwid_is_xswitch(&hwid);
-
-	/* 
-	 * Try to become the master of the widget.  If this is an xswitch
-	 * with multiple hubs connected, only one will succeed.  Mastership
-	 * of an xswitch is used only when touching registers on that xswitch.
-	 * The slave xwidgets connected to the xswitch can be owned by various
-	 * masters.
-	 */
-	if (device_master_set(widgetv, hubv) == 0) {
-
-		/* Only one hub (thread) per Crosstalk device or switch makes
-		 * it to here.
-		 */
-
-		/* 
-		 * Initialize whatever xwidget is hanging off our hub.
-		 * Whatever it is, it's accessible through widgetnum 0.
-		 */
-		hubinfo_get(hubv, &hubinfo);
-
-		(void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL);
-
-		if (!is_xswitch) {
-			/* io_init_done takes cpu cookie as 2nd argument 
-			 * to do a restorenoderun for the setnoderun done 
-			 * at the start of this thread 
-			 */
-			io_init_done(cnodeid,c);
-			/* NOTREACHED */
-		}
-
-		/* 
-		 * Special handling for Crosstalk Switches (e.g. xbow).
-		 * We need to do things in roughly the following order:
-		 *	1) Initialize xswitch hardware (done above)
-		 *	2) Determine which hubs are available to be widget masters
-		 *	3) Discover which links are active from the xswitch
-		 *	4) Assign xwidgets hanging off the xswitch to hubs
-		 *	5) Initialize all xwidgets on the xswitch
-		 */
-
-		volunteer_for_widgets(switchv, hubv);
-
-		/* If there's someone else on this crossbow, recognize him */
-		if (npdap->xbow_peer != INVALID_NASID) {
-			nodepda_t *peer_npdap = NODEPDA(NASID_TO_COMPACT_NODEID(npdap->xbow_peer));
-			peer_sema = &peer_npdap->xbow_sema;
-			volunteer_for_widgets(switchv, peer_npdap->node_vertex);
-		}
-
-		assign_widgets_to_volunteers(switchv, hubv);
-
-		/* Signal that we're done */
-		if (peer_sema) {
-			mutex_unlock(peer_sema);
-		}
-		
-	}
-	else {
-	    /* Wait 'til master is done assigning widgets. */
-	    mutex_lock(&npdap->xbow_sema);
-	}
-
-#ifdef PROBE_TEST
-	if ((cnodeid == 1) || (cnodeid == 2)) {
-		int index;
-
-		for (index = 0; index < 500; index++)
-			DBG("Interfering with device probing!!!\n");
-	}
-#endif
-	/* Now both nodes can safely inititialize widgets */
-	io_init_xswitch_widgets(switchv, cnodeid);
-	io_link_xswitch_widgets(switchv, cnodeid);
-
-	/* io_init_done takes cpu cookie as 2nd argument 
-	 * to do a restorenoderun for the setnoderun done 
-	 * at the start of this thread 
-	 */
-	io_init_done(cnodeid,c);
-
-	DBG("\nio_init_node: DONE INITIALIZED ALL I/O FOR CNODEID %d\n\n", cnodeid);
-}
-
-
-#define IOINIT_STKSZ	(16 * 1024)
-
-#define __DEVSTR1 	"/../.master/"
-#define __DEVSTR2 	"/target/"
-#define __DEVSTR3 	"/lun/0/disk/partition/"
-#define	__DEVSTR4	"/../ef"
-
-#if defined(CONFIG_IA64_SGI_SN1)
-/*
- * Currently, we need to allow for 5 IBrick slots with 1 FC each
- * plus an internal 1394.
- *
- * ioconfig starts numbering SCSI's at NUM_BASE_IO_SCSI_CTLR.
- */
-#define NUM_BASE_IO_SCSI_CTLR 6
-#else
-#define NUM_BASE_IO_SCSI_CTLR 6
-#endif
-/*
- * This tells ioconfig where it can start numbering scsi controllers.
- * Below this base number, platform-specific handles the numbering.
- * XXX Irix legacy..controller numbering should be part of devfsd's job
- */
-int num_base_io_scsi_ctlr = 2; /* used by syssgi */
-devfs_handle_t		base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR];
-static devfs_handle_t	baseio_enet_vhdl,baseio_console_vhdl;
-
-/*
- * Put the logical controller number information in the 
- * scsi controller vertices for each scsi controller that
- * is in a "fixed position".
- */
-static void
-scsi_ctlr_nums_add(devfs_handle_t pci_vhdl)
-{
-	{
-		int i;
-
-		num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR;
-
-		/* Initialize base_io_scsi_ctlr_vhdl array */
-		for (i=0; i<NUM_BASE_IO_SCSI_CTLR; i++)
-			base_io_scsi_ctlr_vhdl[i] = GRAPH_VERTEX_NONE;
-	}
-	{
-	/*
-	 * May want to consider changing the SN0 code, above, to work more like
-	 * the way this works.
-	 */
-	devfs_handle_t base_ibrick_xbridge_vhdl;
-	devfs_handle_t base_ibrick_xtalk_widget_vhdl;
-	devfs_handle_t scsi_ctlr_vhdl;
-	int i;
-	graph_error_t rv;
-
-	/*
-	 * This is a table of "well-known" SCSI controllers and their well-known
-	 * controller numbers.  The names in the table start from the base IBrick's
-	 * Xbridge vertex, so the first component is the xtalk widget number.
-	 */
-	static struct {
-		char	*base_ibrick_scsi_path;
-		int	controller_number;
-	} hardwired_scsi_controllers[] = {
-		{"15/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 0},
-		{"15/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 1},
-		{"15/" EDGE_LBL_PCI "/3/" EDGE_LBL_SCSI_CTLR "/0", 2},
-		{"14/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 3},
-		{"14/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 4},
-		{"15/" EDGE_LBL_PCI "/6/ohci/0/" EDGE_LBL_SCSI_CTLR "/0", 5},
-		{NULL, -1} /* must be last */
-	};
-
-	base_ibrick_xtalk_widget_vhdl = hwgraph_connectpt_get(pci_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xtalk_widget_vhdl != GRAPH_VERTEX_NONE);
-
-	base_ibrick_xbridge_vhdl = hwgraph_connectpt_get(base_ibrick_xtalk_widget_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xbridge_vhdl != GRAPH_VERTEX_NONE);
-	hwgraph_vertex_unref(base_ibrick_xtalk_widget_vhdl);
-
-	/*
-	 * Iterate through the list of well-known SCSI controllers.
-	 * For each controller found, set it's controller number according
-	 * to the table.
-	 */
-	for (i=0; hardwired_scsi_controllers[i].base_ibrick_scsi_path != NULL; i++) {
-		rv = hwgraph_path_lookup(base_ibrick_xbridge_vhdl,
-			hardwired_scsi_controllers[i].base_ibrick_scsi_path, &scsi_ctlr_vhdl, NULL);
-
-		if (rv != GRAPH_SUCCESS) /* No SCSI at this path */
-			continue;
-
-		ASSERT(hardwired_scsi_controllers[i].controller_number < NUM_BASE_IO_SCSI_CTLR);
-		base_io_scsi_ctlr_vhdl[hardwired_scsi_controllers[i].controller_number] = scsi_ctlr_vhdl;
-		device_controller_num_set(scsi_ctlr_vhdl, hardwired_scsi_controllers[i].controller_number);
-		hwgraph_vertex_unref(scsi_ctlr_vhdl); /* (even though we're actually keeping a reference) */
-	}
-
-	hwgraph_vertex_unref(base_ibrick_xbridge_vhdl);
-	}
-}
-
-
-#include <asm/sn/ioerror_handling.h>
-devfs_handle_t		sys_critical_graph_root = GRAPH_VERTEX_NONE;
-
-/* Define the system critical vertices and connect them through
- * a canonical parent-child relationships for easy traversal
- * during io error handling.
- */
-static void
-sys_critical_graph_init(void)
-{
-	devfs_handle_t		bridge_vhdl,master_node_vhdl;
-	devfs_handle_t  		xbow_vhdl = GRAPH_VERTEX_NONE;
-	extern devfs_handle_t	hwgraph_root;
-	devfs_handle_t		pci_slot_conn;
-	int			slot;
-	devfs_handle_t		baseio_console_conn;
-
-	DBG("sys_critical_graph_init: FIXME.\n");
-	baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl);
-
-	if (baseio_console_conn == NULL) {
-		return;
-	}
-
-	/* Get the vertex handle for the baseio bridge */
-	bridge_vhdl = device_master_get(baseio_console_conn);
-
-	/* Get the master node of the baseio card */
-	master_node_vhdl = cnodeid_to_vertex(
-				master_node_get(baseio_console_vhdl));
-	
-	/* Add the "root->node" part of the system critical graph */
-
-	sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl);
-
-	/* Check if we have a crossbow */
-	if (hwgraph_traverse(master_node_vhdl,
-			     EDGE_LBL_XTALK"/0",
-			     &xbow_vhdl) == GRAPH_SUCCESS) {
-		/* We have a crossbow.Add "node->xbow" part of the system 
-		 * critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl);
-		
-		/* Add "xbow->baseio bridge" of the system critical graph */
-		sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl);
-
-		hwgraph_vertex_unref(xbow_vhdl);
-	} else 
-		/* We donot have a crossbow. Add "node->baseio_bridge"
-		 * part of the system critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl);
-
-	/* Add all the populated PCI slot vertices to the system critical
-	 * graph with the bridge vertex as the parent.
-	 */
-	for (slot = 0 ; slot < 8; slot++) {
-		char	slot_edge[10];
-
-		sprintf(slot_edge,"%d",slot);
-		if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn)
-		    != GRAPH_SUCCESS)
-			continue;
-		sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	hwgraph_vertex_unref(bridge_vhdl);
-
-	/* Add the "ioc3 pci connection point  -> console ioc3" part 
-	 * of the system critical graph
-	 */
-
-	if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_console_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "ethernet pci connection point  -> base ethernet" part of 
-	 * the system  critical graph
-	 */
-	if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_enet_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "scsi controller pci connection point  -> base scsi 
-	 * controller" part of the system critical graph
-	 */
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[0]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[1]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	hwgraph_vertex_unref(baseio_console_conn);
-
-}
-
-static void
-baseio_ctlr_num_set(void)
-{
-	char 			name[MAXDEVNAME];
-	devfs_handle_t		console_vhdl, pci_vhdl, enet_vhdl;
-	devfs_handle_t		ioc3_console_vhdl_get(void);
-
-
-	DBG("baseio_ctlr_num_set; FIXME\n");
-	console_vhdl = ioc3_console_vhdl_get();
-	if (console_vhdl == GRAPH_VERTEX_NONE)
-		return;
-	/* Useful for setting up the system critical graph */
-	baseio_console_vhdl = console_vhdl;
-
-	vertex_to_name(console_vhdl,name,MAXDEVNAME);
-
-	strcat(name,__DEVSTR1);
-	pci_vhdl =  hwgraph_path_to_vertex(name);
-	scsi_ctlr_nums_add(pci_vhdl);
-	/* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(pci_vhdl);
-
-	vertex_to_name(console_vhdl, name, MAXDEVNAME);
-	strcat(name, __DEVSTR4);
-	enet_vhdl = hwgraph_path_to_vertex(name);
-
-	/* Useful for setting up the system critical graph */
-	baseio_enet_vhdl = enet_vhdl;
-
-	device_controller_num_set(enet_vhdl, 0);
-	/* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(enet_vhdl);
-}
-/* #endif */
-
-void
-sn00_rrb_alloc(devfs_handle_t vhdl, int *vendor_list)
-{
-	/* REFERENCED */
-	int rtn_val;
-
-	/* 
-	** sn00 population:		errb	orrb
-	**	0- ql			3+?
-	**	1- ql			        2
-	**	2- ioc3 ethernet	2+?
-	**	3- ioc3 secondary	        1
-	**	4-                      0
-	** 	5- PCI slot
-	** 	6- PCI slot
-	** 	7- PCI slot
-	*/	
-	
-	/* The following code implements this heuristic for getting 
-	 * maximum usage out of the rrbs
-	 *
-	 * constraints:
-	 *  8 bit ql1 needs 1+1
-	 *  ql0 or ql5,6,7 wants 1+2
-	 *  ethernet wants 2 or more
-	 *
-	 * rules for even rrbs:
-	 *  if nothing in slot 6 
-	 *   4 rrbs to 0 and 2  (0xc8889999)
-	 *  else 
-         *   3 2 3 to slots 0 2 6  (0xc8899bbb)
-	 *
-         * rules for odd rrbs
-	 *  if nothing in slot 5 or 7  (0xc8889999)
-	 *   4 rrbs to 1 and 3
-	 *  else if 1 thing in 5 or 7  (0xc8899aaa) or (0xc8899bbb)
-         *   3 2 3 to slots 1 3 5|7
-         *  else
-         *   2 1 3 2 to slots 1 3 5 7 (note: if there's a ql card in 7 this
-	 *           (0xc89aaabb)      may short what it wants therefore the
-	 *			       rule should be to plug pci slots in order)
-	 */
-
-
-	if (vendor_list[6] != PCIIO_VENDOR_ID_NONE) {
-		/* something in slot 6 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 3,1, 2,0, 0,0, 3,0);
-	}
-	else {
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 4,1, 4,0, 0,0, 0,0);
-	}
-	if (rtn_val)
-		printk(KERN_WARNING  "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
-
-	if ((vendor_list[5] != PCIIO_VENDOR_ID_NONE) && 
-	    (vendor_list[7] != PCIIO_VENDOR_ID_NONE)) {
-		/* soemthing in slot 5 and 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 2,1, 1,0, 3,0, 2,0);
-	}
-	else if (vendor_list[5] != PCIIO_VENDOR_ID_NONE) {
-		/* soemthing in slot 5 but not 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 3,0, 0,0);
-	}
-	else if (vendor_list[7] != PCIIO_VENDOR_ID_NONE) {
-		/* soemthing in slot 7 but not 5 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 0,0, 3,0);
-	}
-	else {
-		/* nothing in slot 5 or 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 4,1, 4,0, 0,0, 0,0);
-	}
-	if (rtn_val)
-		printk(KERN_WARNING  "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
-}
-
-
-/*
- * Initialize all I/O devices.  Starting closest to nodes, probe and
- * initialize outward.
- */
-void
-init_all_devices(void)
-{
-	/* Governor on init threads..bump up when safe 
-	 * (beware many devfs races) 
-	 */
-#ifdef LATER
-	int io_init_node_threads = 2;	
-#endif
-	cnodeid_t cnodeid, active;
-
-#ifdef LINUX_KERNEL_THREADS
-	sema_init(&io_init_sema, 0);
-#endif
-
-	active = 0;
-	for (cnodeid = 0; cnodeid < numnodes; cnodeid++) {
-#ifdef LINUX_KERNEL_THREADS
-		char thread_name[16];
-		extern int io_init_pri;
-
-		/*
-		 * Spawn a service thread for each node to initialize all
-		 * I/O on that node.  Each thread attempts to bind itself 
-		 * to the node whose I/O it's initializing.
-		 */
-		sprintf(thread_name, "IO_init[%d]", cnodeid);
-
-		(void)sthread_create(thread_name, 0, IOINIT_STKSZ, 0,
-			io_init_pri, KT_PS, (st_func_t *)io_init_node,
-			(void *)(long)cnodeid, 0, 0, 0);
-#else
-                DBG("init_all_devices: Calling io_init_node() for cnode %d\n", cnodeid);
-                io_init_node(cnodeid);
-
-		DBG("init_all_devices: Done io_init_node() for cnode %d\n", cnodeid);
-
-#endif /* LINUX_KERNEL_THREADS */
-
-#ifdef LINUX_KERNEL_THREADS
-		/* Limit how many nodes go at once, to not overload hwgraph */
-		/* TBD: Should timeout */
-		DBG("started thread for cnode %d\n", cnodeid);
-		active++;
-		if (io_init_node_threads && 
-			active >= io_init_node_threads) {
-			down(&io_init_sema);
-			active--;
-		}
-#endif /* LINUX_KERNEL_THREADS */
-	}
-
-#ifdef LINUX_KERNEL_THREADS
-	/* Wait until all IO_init threads are done */
-
-	while (active > 0) {
-#ifdef AA_DEBUG
-	    DBG("waiting, %d still active\n", active);
-#endif
-	    down(&io_init_sema);
-	    active--;
-	}
-
-#endif /* LINUX_KERNEL_THREADS */
-
-	for (cnodeid = 0; cnodeid < numnodes; cnodeid++)
-		/*
-	 	 * Update information generated by IO init.
-		 */
-		update_node_information(cnodeid);
-
-	baseio_ctlr_num_set();
-	/* Setup the system critical graph (which is a subgraph of the
-	 * main hwgraph). This information is useful during io error
-	 * handling.
-	 */
-	sys_critical_graph_init();
-
-#if HWG_PRINT
-	hwgraph_print();
-#endif
-
-}
-
-#define toint(x) ((int)(x) - (int)('0'))
-
-void
-devnamefromarcs(char *devnm)
-{
-	int 			val;
-	char 			tmpnm[MAXDEVNAME];
-	char 			*tmp1, *tmp2;
-	
-	val = strncmp(devnm, "dks", 3);
-	if (val != 0) 
-		return;
-	tmp1 = devnm + 3;
-	if (!isdigit(*tmp1))
-		return;
-
-	val = 0;
-	while (isdigit(*tmp1)) {
-		val = 10*val+toint(*tmp1);
-		tmp1++;
-	}
-
-	if(*tmp1 != 'd')
-		return;
-	else
-		tmp1++;
-
-	if ((val < 0) || (val >= NUM_BASE_IO_SCSI_CTLR)) {
-		int i;
-		int viable_found = 0;
-
-		DBG("Only controller numbers 0..%d  are supported for\n", NUM_BASE_IO_SCSI_CTLR-1);
-		DBG("prom \"root\" variables of the form dksXdXsX.\n");
-		DBG("To use another disk you must use the full hardware graph path\n\n");
-		DBG("Possible controller numbers for use in 'dksXdXsX' on this system: ");
-		for (i=0; i<NUM_BASE_IO_SCSI_CTLR; i++) {
-			if (base_io_scsi_ctlr_vhdl[i] != GRAPH_VERTEX_NONE) {
-				DBG("%d ", i);
-				viable_found=1;
-			}
-		}
-		if (viable_found)
-			DBG("\n");
-		else
-			DBG("none found!\n");
-
-#ifdef LATER
-		if (kdebug)
-			debug("ring");
-#endif
-		DELAY(15000000);
-		//prom_reboot();
-		panic("FIXME: devnamefromarcs: should call prom_reboot here.\n");
-		/* NOTREACHED */
-	}
-		
-	ASSERT(base_io_scsi_ctlr_vhdl[val] != GRAPH_VERTEX_NONE);
-	vertex_to_name(base_io_scsi_ctlr_vhdl[val],
-		       tmpnm,
-		       MAXDEVNAME);
-	tmp2 = 	tmpnm + strlen(tmpnm);
-	strcpy(tmp2, __DEVSTR2);
-	tmp2 += strlen(__DEVSTR2);
-	while (*tmp1 != 's') {
-		if((*tmp2++ = *tmp1++) == '\0')
-			return;
-	}	
-	tmp1++;
-	strcpy(tmp2, __DEVSTR3);
-	tmp2 += strlen(__DEVSTR3);
-	while ( (*tmp2++ = *tmp1++) )
-		;
-	tmp2--;
-	*tmp2++ = '/';
-	strcpy(tmp2, EDGE_LBL_BLOCK);
-	strcpy(devnm,tmpnm);
-}
-
-static
-struct io_brick_map_s io_brick_tab[] = {
-
-/* Ibrick widget number to PCI bus number map */
-  {
-        'I',                                    /* Ibrick type    */ 
-    /*  PCI Bus #                                  Widget #       */
-     {  0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        0,                                      /* 0x8            */
-        0,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        0,                                      /* 0xc            */
-        0,                                      /* 0xd            */
-        2,                                      /* 0xe            */
-        1                                       /* 0xf            */
-     }
-  },
-
-/* Pbrick widget number to PCI bus number map */
-  {
-        'P',                                    /* Pbrick type    */ 
-    /*  PCI Bus #                                  Widget #       */
-     {  0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        2,                                      /* 0x8            */
-        1,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        5,                                      /* 0xc            */
-        6,                                      /* 0xd            */
-        4,                                      /* 0xe            */
-        3                                       /* 0xf            */
-     }
-  },
-
-/* Xbrick widget to XIO slot map */
-  {
-        'X',                                    /* Xbrick type    */ 
-    /*  XIO Slot #                                 Widget #       */
-     {  0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        1,                                      /* 0x8            */
-        2,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        3,                                      /* 0xc            */
-        4,                                      /* 0xd            */
-        0,                                      /* 0xe            */
-        0                                       /* 0xf            */
-     }
-  }
-};
-
-/*
- * Use the brick's type to map a widget number to a meaningful int
- */
-int
-io_brick_map_widget(char brick_type, int widget_num)
-{
-        int num_bricks, i;
-
-        /* Calculate number of bricks in table */
-        num_bricks = sizeof(io_brick_tab)/sizeof(io_brick_tab[0]);
-
-        /* Look for brick prefix in table */
-        for (i = 0; i < num_bricks; i++) {
-               if (brick_type == io_brick_tab[i].ibm_type)
-                       return(io_brick_tab[i].ibm_map_wid[widget_num]);
-        }
-
-        return 0;
-
-}
-
-/*
- * Use the device's vertex to map the device's widget to a meaningful int
- */
-int
-io_path_map_widget(devfs_handle_t vertex)
-{
-        char hw_path_name[MAXDEVNAME];
-        char *wp, *bp, *sp = NULL;
-        int  widget_num;
-	long atoi(char *);
-	int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-
-
-        /* Get the full path name of the vertex */
-        if (GRAPH_SUCCESS != hwgraph_vertex_name_get(vertex, hw_path_name,
-                                                     MAXDEVNAME))
-                return 0;
-
-        /* Find the widget number in the path name */
-        wp = strstr(hw_path_name, "/"EDGE_LBL_XTALK"/");
-        if (wp == NULL)
-                return 0;
-        widget_num = atoi(wp+7);
-        if (widget_num < XBOW_PORT_8 || widget_num > XBOW_PORT_F)
-                return 0;
-
-        /* Find "brick" in the path name */
-        bp = strstr(hw_path_name, "brick");
-        if (bp == NULL)
-                return 0;
-
-        /* Find preceding slash */
-        sp = bp;
-        while (sp > hw_path_name) {
-                sp--;
-                if (*sp == '/')
-                        break;
-        }
-
-        /* Invalid if no preceding slash */
-        if (!sp)
-                return 0;
-
-        /* Bump slash pointer to "brick" prefix */
-        sp++;
-        /*
-         * Verify "brick" prefix length;  valid exaples:
-         * 'I' from "/Ibrick"
-         * 'P' from "/Pbrick"
-         * 'X' from "/Xbrick"
-         */
-         if ((bp - sp) != 1)
-                return 0;
-
-        return (io_brick_map_widget(*sp, widget_num));
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/module.c linux-2.4.22-pre10/arch/ia64/sn/io/module.c
--- linux-2.4.21/arch/ia64/sn/io/module.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/module.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,312 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn1/hubdev.h>
-#include <asm/sn/module.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/sn_cpuid.h>
-
-
-/* #define LDEBUG	1 */
-
-#ifdef LDEBUG
-#define DPRINTF		printk
-#define printf		printk
-#else
-#define DPRINTF(x...)
-#endif
-
-module_t	       *modules[MODULE_MAX];
-int			nummodules;
-
-#define SN00_SERIAL_FUDGE	0x3b1af409d513c2
-#define SN0_SERIAL_FUDGE	0x6e
-
-void
-encode_int_serial(uint64_t src,uint64_t *dest)
-{
-    uint64_t val;
-    int i;
-
-    val = src + SN00_SERIAL_FUDGE;
-
-
-    for (i = 0; i < sizeof(long long); i++) {
-	((char*)dest)[i] =
-	    ((char*)&val)[sizeof(long long)/2 +
-			 ((i%2) ? ((i/2 * -1) - 1) : (i/2))];
-    }
-}
-
-
-void
-decode_int_serial(uint64_t src, uint64_t *dest)
-{
-    uint64_t val;
-    int i;
-
-    for (i = 0; i < sizeof(long long); i++) {
-	((char*)&val)[sizeof(long long)/2 +
-		     ((i%2) ? ((i/2 * -1) - 1) : (i/2))] =
-	    ((char*)&src)[i];
-    }
-
-    *dest = val - SN00_SERIAL_FUDGE;
-}
-
-
-void
-encode_str_serial(const char *src, char *dest)
-{
-    int i;
-
-    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) {
-
-	dest[i] = src[MAX_SERIAL_NUM_SIZE/2 +
-		     ((i%2) ? ((i/2 * -1) - 1) : (i/2))] +
-	    SN0_SERIAL_FUDGE;
-    }
-}
-
-void
-decode_str_serial(const char *src, char *dest)
-{
-    int i;
-
-    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) {
-	dest[MAX_SERIAL_NUM_SIZE/2 +
-	    ((i%2) ? ((i/2 * -1) - 1) : (i/2))] = src[i] -
-	    SN0_SERIAL_FUDGE;
-    }
-}
-
-
-module_t *module_lookup(moduleid_t id)
-{
-    int			i;
-
-    for (i = 0; i < nummodules; i++)
-	if (modules[i]->id == id) {
-	    DPRINTF("module_lookup: found m=0x%p\n", modules[i]);
-	    return modules[i];
-	}
-
-    return NULL;
-}
-
-/*
- * module_add_node
- *
- *   The first time a new module number is seen, a module structure is
- *   inserted into the module list in order sorted by module number
- *   and the structure is initialized.
- *
- *   The node number is added to the list of nodes in the module.
- */
-
-module_t *module_add_node(moduleid_t id, cnodeid_t n)
-{
-    module_t	       *m;
-    int			i;
-    char		buffer[16];
-
-#ifdef __ia64
-    memset(buffer, 0, 16);
-    format_module_id(buffer, id, MODULE_FORMAT_BRIEF);
-    DPRINTF("module_add_node: id=%s node=%d\n", buffer, n);
-#endif
-
-    if ((m = module_lookup(id)) == 0) {
-#ifdef LATER
-	m = kmem_zalloc_node(sizeof (module_t), KM_NOSLEEP, n);
-#else
-	m = kmalloc(sizeof (module_t), GFP_KERNEL);
-	memset(m, 0 , sizeof(module_t));
-#endif
-	ASSERT_ALWAYS(m);
-
-	m->id = id;
-	spin_lock_init(&m->lock);
-
-	mutex_init_locked(&m->thdcnt);
-
-// set_elsc(&m->elsc);
-	elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n));
-	spin_lock_init(&m->elsclock);
-
-	/* Insert in sorted order by module number */
-
-	for (i = nummodules; i > 0 && modules[i - 1]->id > id; i--)
-	    modules[i] = modules[i - 1];
-
-	modules[i] = m;
-	nummodules++;
-    }
-
-    m->nodes[m->nodecnt++] = n;
-
-    DPRINTF("module_add_node: module %s now has %d nodes\n", buffer, m->nodecnt);
-
-    return m;
-}
-
-int module_probe_snum(module_t *m, nasid_t nasid)
-{
-    lboard_t	       *board;
-    klmod_serial_num_t *comp;
-    char * bcopy(const char * src, char * dest, int count);
-    char serial_number[16];
-
-    /*
-     * record brick serial number
-     */
-    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-
-    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
-    {
-#if	LDEBUG
-	printf ("module_probe_snum: no IP35 board found!\n");
-#endif
-	return 0;
-    }
-
-    board_serial_number_get( board, serial_number );
-    if( serial_number[0] != '\0' ) {
-	encode_str_serial( serial_number, m->snum.snum_str );
-	m->snum_valid = 1;
-    }
-#if	LDEBUG
-    else {
-	printf("module_probe_snum: brick serial number is null!\n");
-    }
-    printf("module_probe_snum: brick serial number == %s\n", serial_number);
-#endif /* DEBUG */
-
-    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid),
-			KLTYPE_IOBRICK_XBOW);
-
-    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
-	return 0;
-
-    comp = GET_SNUM_COMP(board);
-
-    if (comp) {
-#if LDEBUG
-	    int i;
-
-	    printf("********found module with id %x and string", m->id);
-
-	    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++)
-		printf(" %x ", comp->snum.snum_str[i]);
-
-	    printf("\n");	/* Fudged string is not ASCII */
-#endif
-
-	    if (comp->snum.snum_str[0] != '\0') {
-		bcopy(comp->snum.snum_str,
-		      m->sys_snum,
-		      MAX_SERIAL_NUM_SIZE);
-		m->sys_snum_valid = 1;
-	    }
-    }
-
-    if (m->sys_snum_valid)
-	return 1;
-    else {
-	DPRINTF("Invalid serial number for module %d, "
-		"possible missing or invalid NIC.", m->id);
-	return 0;
-    }
-}
-
-void
-io_module_init(void)
-{
-    cnodeid_t		node;
-    lboard_t	       *board;
-    nasid_t		nasid;
-    int			nserial;
-    module_t	       *m;
-
-    DPRINTF("*******module_init\n");
-
-    nserial = 0;
-
-    for (node = 0; node < numnodes; node++) {
-	nasid = COMPACT_TO_NASID_NODEID(node);
-
-	board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-	ASSERT(board);
-
-	m = module_add_node(board->brd_module, node);
-
-	if (! m->snum_valid && module_probe_snum(m, nasid))
-	    nserial++;
-    }
-
-    DPRINTF("********found total of %d serial numbers in the system\n",
-	    nserial);
-
-    if (nserial == 0)
-	printk(KERN_WARNING  "io_module_init: No serial number found.\n");
-}
-
-elsc_t *get_elsc(void)
-{
-	return &NODEPDA(cpuid_to_cnodeid(smp_processor_id()))->module->elsc;
-}
-
-int
-get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info)
-{
-    int i;
-
-    if (cmod < 0 || cmod >= nummodules)
-	return EINVAL;
-
-    if (! modules[cmod]->snum_valid)
-	return ENXIO;
-
-    mod_info->mod_num = modules[cmod]->id;
-    {
-	char temp[MAX_SERIAL_NUM_SIZE];
-
-	decode_str_serial(modules[cmod]->snum.snum_str, temp);
-
-	/* if this is an invalid serial number return an error */
-	if (temp[0] != 'K')
-	    return ENXIO;
-
-	mod_info->serial_num = 0;
-
-	for (i = 0; i < MAX_SERIAL_NUM_SIZE && temp[i] != '\0'; i++) {
-	    mod_info->serial_num <<= 4;
-	    mod_info->serial_num |= (temp[i] & 0xf);
-
-	    mod_info->serial_str[i] = temp[i];
-	}
-
-	mod_info->serial_str[i] = '\0';
-    }
-
-    return 0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/pci.c linux-2.4.22-pre10/arch/ia64/sn/io/pci.c
--- linux-2.4.21/arch/ia64/sn/io/pci.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/pci.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,294 +0,0 @@
-/* 
- *
- * SNI64 specific PCI support for SNI IO.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 1997, 1998, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <asm/sn/types.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/bridge.h>
-
-#ifdef DEBUG_CONFIG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-
-
-#ifdef CONFIG_PCI
-
-extern devfs_handle_t pci_bus_to_vertex(unsigned char);
-extern devfs_handle_t devfn_to_vertex(unsigned char bus, unsigned char devfn);
-
-/*
- * snia64_read_config_byte - Read a byte from the config area of the device.
- */
-static int snia64_read_config_byte (struct pci_dev *dev,
-                                   int where, unsigned char *val)
-{
-	unsigned long res = 0;
-	unsigned size = 1;
-	devfs_handle_t device_vertex;
-
-	if ( (dev == (struct pci_dev *)0) || (val == (unsigned char *)0) ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	res = pciio_config_get(device_vertex, (unsigned) where, size);
-	*val = (unsigned char) res;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_read_config_word - Read 2 bytes from the config area of the device.
- */
-static int snia64_read_config_word (struct pci_dev *dev,
-                                   int where, unsigned short *val)
-{
-	unsigned long res = 0;
-	unsigned size = 2; /* 2 bytes */
-	devfs_handle_t device_vertex;
-
-	if ( (dev == (struct pci_dev *)0) || (val == (unsigned short *)0) ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	res = pciio_config_get(device_vertex, (unsigned) where, size);
-	*val = (unsigned short) res;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_read_config_dword - Read 4 bytes from the config area of the device.
- */
-static int snia64_read_config_dword (struct pci_dev *dev,
-                                    int where, unsigned int *val)
-{
-	unsigned long res = 0;
-	unsigned size = 4; /* 4 bytes */
-	devfs_handle_t device_vertex;
-
-	if (where & 3) {
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-	if ( (dev == (struct pci_dev *)0) || (val == (unsigned int *)0) ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	res = pciio_config_get(device_vertex, (unsigned) where, size);
-	*val = (unsigned int) res;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_write_config_byte - Writes 1 byte to the config area of the device.
- */
-static int snia64_write_config_byte (struct pci_dev *dev,
-                                    int where, unsigned char val)
-{
-	devfs_handle_t device_vertex;
-
-	if ( dev == (struct pci_dev *)0 ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	/* 
-	 * if it's an IOC3 then we bail out, we special
-	 * case them with pci_fixup_ioc3
-	 */
-	if (dev->vendor == PCI_VENDOR_ID_SGI && 
-	    dev->device == PCI_DEVICE_ID_SGI_IOC3 )
-		return PCIBIOS_SUCCESSFUL;
-
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	pciio_config_set( device_vertex, (unsigned)where, 1, (uint64_t) val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_write_config_word - Writes 2 bytes to the config area of the device.
- */
-static int snia64_write_config_word (struct pci_dev *dev,
-                                    int where, unsigned short val)
-{
-	devfs_handle_t device_vertex = NULL;
-
-	if (where & 1) {
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-	if ( dev == (struct pci_dev *)0 ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	/* 
-	 * if it's an IOC3 then we bail out, we special
-	 * case them with pci_fixup_ioc3
-	 */
-	if (dev->vendor == PCI_VENDOR_ID_SGI && 
-	    dev->device == PCI_DEVICE_ID_SGI_IOC3)
-		return PCIBIOS_SUCCESSFUL;
-
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	pciio_config_set( device_vertex, (unsigned)where, 2, (uint64_t) val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_write_config_dword - Writes 4 bytes to the config area of the device.
- */
-static int snia64_write_config_dword (struct pci_dev *dev,
-                                     int where, unsigned int val)
-{
-	devfs_handle_t device_vertex;
-
-	if (where & 3) {
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-	if ( dev == (struct pci_dev *)0 ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	/* 
-	 * if it's an IOC3 then we bail out, we special
-	 * case them with pci_fixup_ioc3
-	 */
-	if (dev->vendor == PCI_VENDOR_ID_SGI && 
-	    dev->device == PCI_DEVICE_ID_SGI_IOC3)
-		return PCIBIOS_SUCCESSFUL;
-
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	pciio_config_set( device_vertex, (unsigned)where, 4, (uint64_t) val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops snia64_pci_ops = {
-	snia64_read_config_byte,
-	snia64_read_config_word,
-	snia64_read_config_dword,
-	snia64_write_config_byte,
-	snia64_write_config_word,
-	snia64_write_config_dword
-};
-
-/*
- * snia64_pci_find_bios - SNIA64 pci_find_bios() platform specific code.
- */
-void __init
-sn_pci_find_bios(void)
-{
-	extern struct pci_ops *pci_root_ops;
-	/*
-	 * Go initialize our IO Infrastructure ..
-	 */
-	extern void sgi_master_io_infr_init(void);
-
-	sgi_master_io_infr_init();
-
-	/* sn_io_infrastructure_init(); */
-	pci_root_ops = &snia64_pci_ops;
-}
-
-void
-pci_fixup_ioc3(struct pci_dev *d)
-{
-        int 		i;
-	unsigned int 	size;
-
-        /* IOC3 only decodes 0x20 bytes of the config space, reading
-	 * beyond that is relatively benign but writing beyond that
-	 * (especially the base address registers) will shut down the
-	 * pci bus...so avoid doing so.
-	 * NOTE: this means we can't program the intr_pin into the device,
-	 *       currently we hack this with special code in 
-	 *	 sgi_pci_intr_support()
-	 */
-        DBG("pci_fixup_ioc3: Fixing base addresses for ioc3 device %s\n", d->slot_name);
-
-	/* I happen to know from the spec that the ioc3 needs only 0xfffff 
-	 * The standard pci trick of writing ~0 to the baddr and seeing
-	 * what comes back doesn't work with the ioc3
-	 */
-	size = 0xfffff;
-	d->resource[0].end = (unsigned long) d->resource[0].start + (unsigned long) size;
-
-	/*
-	 * Zero out the resource structure .. because we did not go through 
-	 * the normal PCI Infrastructure Init, garbbage are left in these 
-	 * fileds.
-	 */
-        for (i = 1; i <= PCI_ROM_RESOURCE; i++) {
-                d->resource[i].start = 0UL;
-                d->resource[i].end = 0UL;
-                d->resource[i].flags = 0UL;
-        }
-
-#ifdef CONFIG_IA64_SGI_SN1
-	*(volatile u32 *)0xc0000a000f000220 |= 0x90000;
-#endif
-        d->subsystem_vendor = 0;
-        d->subsystem_device = 0;
-
-}
-
-#else
-void sn_pci_find_bios(void) {}
-void pci_fixup_ioc3(struct pci_dev *d) {}
-struct list_head pci_root_buses;
-struct list_head pci_root_buses;
-struct list_head pci_devices;
-
-#endif /* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/pci_bus_cvlink.c linux-2.4.22-pre10/arch/ia64/sn/io/pci_bus_cvlink.c
--- linux-2.4.21/arch/ia64/sn/io/pci_bus_cvlink.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/pci_bus_cvlink.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,743 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <asm/sn/types.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/sn_cpuid.h>
-
-extern int bridge_rev_b_data_check_disable;
-
-devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
-nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
-void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
-unsigned char num_bridges;
-static int done_probing = 0;
-
-static int pci_bus_map_create(devfs_handle_t xtalk);
-devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
-
-#define SN_IOPORTS_UNIT 256
-#define MAX_IOPORTS 0xffff
-#define MAX_IOPORTS_CHUNKS (MAX_IOPORTS / SN_IOPORTS_UNIT)
-struct ioports_to_tlbs_s ioports_to_tlbs[MAX_IOPORTS_CHUNKS];
-unsigned long sn_allocate_ioports(unsigned long pci_address);
-
-extern void sn_init_irq_desc(void);
-
-
-
-/*
- * pci_bus_cvlink_init() - To be called once during initialization before 
- *	SGI IO Infrastructure init is called.
- */
-void
-pci_bus_cvlink_init(void)
-{
-	memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET);
-	memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET);
-
-	memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET);
-
-	memset(ioports_to_tlbs, 0x0, sizeof(ioports_to_tlbs));
-
-	num_bridges = 0;
-}
-
-/*
- * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated 
- *	pci bus vertex from the SGI IO Infrastructure.
- */
-devfs_handle_t
-pci_bus_to_vertex(unsigned char busnum)
-{
-
-	devfs_handle_t	pci_bus = NULL;
-
-
-	/*
-	 * First get the xwidget vertex.
-	 */
-	pci_bus = busnum_to_pcibr_vhdl[busnum];
-	return(pci_bus);
-}
-
-/*
- * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
- *	and function numbers.
- */
-devfs_handle_t
-devfn_to_vertex(unsigned char busnum, unsigned int devfn)
-{
-
-	int slot = 0;
-	int func = 0;
-	char	name[16];
-	devfs_handle_t  pci_bus = NULL;
-	devfs_handle_t	device_vertex = (devfs_handle_t)NULL;
-
-	/*
-	 * Go get the pci bus vertex.
-	 */
-	pci_bus = pci_bus_to_vertex(busnum);
-	if (!pci_bus) {
-		/*
-		 * During probing, the Linux pci code invents non-existent
-		 * bus numbers and pci_dev structures and tries to access
-		 * them to determine existence. Don't crib during probing.
-		 */
-		if (done_probing)
-			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
-		return(NULL);
-	}
-
-
-	/*
-	 * Go get the slot&function vertex.
-	 * Should call pciio_slot_func_to_name() when ready.
-	 */
-	slot = PCI_SLOT(devfn);
-	func = PCI_FUNC(devfn);
-
-	/*
-	 * For a NON Multi-function card the name of the device looks like:
-	 * ../pci/1, ../pci/2 ..
-	 */
-	if (func == 0) {
-        	sprintf(name, "%d", slot);
-		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
-			GRAPH_SUCCESS) {
-			if (device_vertex) {
-				return(device_vertex);
-			}
-		}
-	}
-			
-	/*
-	 * This maybe a multifunction card.  It's names look like:
-	 * ../pci/1a, ../pci/1b, etc.
-	 */
-	sprintf(name, "%d%c", slot, 'a'+func);
-	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
-		if (!device_vertex) {
-			return(NULL);
-		}
-	}
-
-	return(device_vertex);
-}
-
-/*
- * For the given device, initialize the addresses for both the Device(x) Flush 
- * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
- * is connected.
- */
-static void
-set_flush_addresses(struct pci_dev *device_dev, 
-	struct sn_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    	bridge_t               *bridge = pcibr_soft->bs_base;
-
-	device_sysdata->dma_buf_sync = (volatile unsigned int *) 
-		&(bridge->b_wr_req_buf[pciio_slot].reg);
-	device_sysdata->xbow_buf_sync = (volatile unsigned int *)
-		XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(get_nasid(), 0), 
-		pcibr_soft->bs_xid);
-#ifdef DEBUG
-
-	printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
-		device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
-
-	while((volatile unsigned int )*device_sysdata->dma_buf_sync);
-	while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
-#endif
-
-}
-
-/*
- * Most drivers currently do not properly tell the arch specific pci dma
- * interfaces whether they can handle A64. Here is where we privately
- * keep track of this.
- */
-static void __init
-set_sn_pci64(struct pci_dev *dev)
-{
-	unsigned short vendor = dev->vendor;
-	unsigned short device = dev->device;
-
-	if (vendor == PCI_VENDOR_ID_QLOGIC) {
-		if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) ||
-				(device == PCI_DEVICE_ID_QLOGIC_ISP2200)) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-	if (vendor == PCI_VENDOR_ID_SGI) {
-		if (device == PCI_DEVICE_ID_SGI_IOC3) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-}
-
-/*
- * sn_allocate_ioports() - This routine provides the allocation and 
- *	mappings between Linux style IOPORTs management.
- *
- *	For simplicity sake, SN1 will allocate IOPORTs in chunks of 
- *	256bytes .. irrespective of what the card desires.  This may 
- *	have to change when we understand how to deal with legacy ioports 
- *	which are hardcoded in some drivers e.g. SVGA.
- *
- *	Ofcourse, the SN1 IO Infrastructure has no concept of IOPORT numbers.
- *	It will remain so.  The IO Infrastructure will continue to map 
- *	IO Resource just like IRIX.  When this is done, we map IOPORT 
- *	chunks to these resources.  The Linux drivers will see and use real 
- *	IOPORT numbers.  The various IOPORT access macros e.g. inb/outb etc. 
- *	does the munging of these IOPORT numbers to make a Uncache Virtual 
- *	Address.  This address via the tlb entries generates the PCI Address 
- *	allocated by the SN1 IO Infrastructure Layer.
- */
-static unsigned long sn_ioport_num = 0x1000; /* Reserve room for Legacy stuff */
-unsigned long
-sn_allocate_ioports(unsigned long pci_address)
-{
-	
-	unsigned long ioport_index;
-
-	/*
-	 * Just some idiot checking ..
-	 */
-	if ( sn_ioport_num > 0xffff ) {
-		printk("sn_allocate_ioports: No more IO PORTS available\n");
-		return(-1);
-	}
-
-	/*
-	 * See Section 4.1.1.5 of Intel IA-64 Acrchitecture Software Developer's
-	 * Manual for details.
-	 */
-	ioport_index = sn_ioport_num / SN_IOPORTS_UNIT;
-
-	ioports_to_tlbs[ioport_index].p = 1; /* Present Bit */
-	ioports_to_tlbs[ioport_index].rv_1 = 0; /* 1 Bit */
-	ioports_to_tlbs[ioport_index].ma = 4; /* Memory Attributes 3 bits*/
-	ioports_to_tlbs[ioport_index].a = 1; /* Set Data Access Bit Fault 1 Bit*/
-	ioports_to_tlbs[ioport_index].d = 1; /* Dirty Bit */
-	ioports_to_tlbs[ioport_index].pl = 0;/* Privilege Level - All levels can R/W*/
-	ioports_to_tlbs[ioport_index].ar = 3; /* Access Rights - R/W only*/
-	ioports_to_tlbs[ioport_index].ppn = pci_address >> 12; /* 4K page size */
-	ioports_to_tlbs[ioport_index].ed = 0; /* Exception Deferral Bit */
-	ioports_to_tlbs[ioport_index].ig = 0; /* Ignored */
-
-	/* printk("sn_allocate_ioports: ioport_index 0x%x ioports_to_tlbs 0x%p\n", ioport_index, ioports_to_tlbs[ioport_index]); */
-	
-	sn_ioport_num += SN_IOPORTS_UNIT;
-
-	return(sn_ioport_num - SN_IOPORTS_UNIT);
-}
-
-/*
- * sn_pci_fixup() - This routine is called when platform_pci_fixup() is 
- *	invoked at the end of pcibios_init() to link the Linux pci 
- *	infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
- *
- *	Other platform specific fixup can also be done here.
- */
-void
-sn_pci_fixup(int arg)
-{
-	struct list_head *ln;
-	struct pci_bus *pci_bus = NULL;
-	struct pci_dev *device_dev = NULL;
-	struct sn_widget_sysdata *widget_sysdata;
-	struct sn_device_sysdata *device_sysdata;
-#ifdef SN_IOPORTS
-	unsigned long ioport;
-#endif
-	pciio_intr_t intr_handle;
-	int cpuid, bit;
-	devfs_handle_t device_vertex;
-	pciio_intr_line_t lines;
-	extern void sn_pci_find_bios(void);
-#ifdef CONFIG_IA64_SGI_SN2
-	extern int numnodes;
-	int cnode;
-#endif /* CONFIG_IA64_SGI_SN2 */
-
-
-	if (arg == 0) {
-		sn_init_irq_desc();
-		sn_pci_find_bios();
-#ifdef CONFIG_IA64_SGI_SN2
-		for (cnode = 0; cnode < numnodes; cnode++) {
-				extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
-				intr_init_vecblk(NODEPDA(cnode), cnode, 0);
-		} 
-#endif /* CONFIG_IA64_SGI_SN2 */
-		return;
-	}
-
-#if 0
-{
-        devfs_handle_t  bridge_vhdl = pci_bus_to_vertex(0);
-        pcibr_soft_t    pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl);
-	bridge_t        *bridge = pcibr_soft->bs_base;
-        printk("pci_fixup_ioc3: Before devreg fixup\n");
-        printk("pci_fixup_ioc3: Devreg 0 0x%x\n", bridge->b_device[0].reg);
-        printk("pci_fixup_ioc3: Devreg 1 0x%x\n", bridge->b_device[1].reg);
-        printk("pci_fixup_ioc3: Devreg 2 0x%x\n", bridge->b_device[2].reg);
-        printk("pci_fixup_ioc3: Devreg 3 0x%x\n", bridge->b_device[3].reg);
-        printk("pci_fixup_ioc3: Devreg 4 0x%x\n", bridge->b_device[4].reg);
-        printk("pci_fixup_ioc3: Devreg 5 0x%x\n", bridge->b_device[5].reg);
-        printk("pci_fixup_ioc3: Devreg 6 0x%x\n", bridge->b_device[6].reg);
-        printk("pci_fixup_ioc3: Devreg 7 0x%x\n", bridge->b_device[7].reg);
-}
-#endif
-	done_probing = 1;
-
-	/*
-	 * Initialize the pci bus vertex in the pci_bus struct.
-	 */
-	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
-		pci_bus = pci_bus_b(ln);
-		widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), 
-					GFP_KERNEL);
-		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
-		pci_bus->sysdata = (void *)widget_sysdata;
-	}
-
-	/*
- 	 * set the root start and end so that drivers calling check_region()
-	 * won't see a conflict
-	 */
-#ifdef SN_IOPORTS
-	ioport_resource.start  = sn_ioport_num;
-	ioport_resource.end = 0xffff;
-#else
-#if defined(CONFIG_IA64_SGI_SN1)
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		/*
-		 * IDE legacy IO PORTs are supported in Medusa.
-		 * Just open up IO PORTs from 0 .. ioport_resource.end.
-		 */
-		ioport_resource.start = 0;
-	} else {
-		/*
-		 * We do not support Legacy IO PORT numbers.
-		 */
-		ioport_resource.start |= IO_SWIZ_BASE | __IA64_UNCACHED_OFFSET;
-	}
-	ioport_resource.end |= (HSPEC_SWIZ_BASE-1) | __IA64_UNCACHED_OFFSET;
-#else
-	// Need something here for sn2.... ZXZXZX
-#endif
-#endif
-
-	/*
-	 * Set the root start and end for Mem Resource.
-	 */
-	iomem_resource.start = 0;
-	iomem_resource.end = 0xffffffffffffffff;
-
-	/*
-	 * Initialize the device vertex in the pci_dev struct.
-	 */
-	pci_for_each_dev(device_dev) {
-		unsigned int irq;
-		int idx;
-		u16 cmd;
-		devfs_handle_t vhdl;
-		unsigned long size;
-		extern int bit_pos_to_irq(int);
-
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
-			extern void pci_fixup_ioc3(struct pci_dev *d);
-			pci_fixup_ioc3(device_dev);
-		}
-
-		/* Set the device vertex */
-
-		device_sysdata = kmalloc(sizeof(struct sn_device_sysdata),
-					GFP_KERNEL);
-		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
-		device_sysdata->isa64 = 0;
-		/*
-		 * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
-		 * register addresses.
-		 */
-		(void) set_flush_addresses(device_dev, device_sysdata);
-
-		device_dev->sysdata = (void *) device_sysdata;
-		set_sn_pci64(device_dev);
-		pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
-
-		/*
-		 * Set the resources address correctly.  The assumption here 
-		 * is that the addresses in the resource structure has been
-		 * read from the card and it was set in the card by our
-		 * Infrastructure ..
-		 */
-		vhdl = device_sysdata->vhdl;
-		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
-			size = 0;
-			size = device_dev->resource[idx].end -
-				device_dev->resource[idx].start;
-			if (size) {
-				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, PCIIO_BYTE_STREAM);
-				device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
-			}
-			else
-				continue;
-
-			device_dev->resource[idx].end = 
-				device_dev->resource[idx].start + size;
-
-#ifdef CONFIG_IA64_SGI_SN1
-			/*
-			 * Adjust the addresses to go to the SWIZZLE ..
-			 */
-			device_dev->resource[idx].start = 
-				device_dev->resource[idx].start & 0xfffff7ffffffffff;
-			device_dev->resource[idx].end = 
-				device_dev->resource[idx].end & 0xfffff7ffffffffff;
-#endif
-
-			if (device_dev->resource[idx].flags & IORESOURCE_IO) {
-				cmd |= PCI_COMMAND_IO;
-#ifdef SN_IOPORTS
-				ioport = sn_allocate_ioports(device_dev->resource[idx].start);
-				if (ioport < 0) {
-					printk("sn_pci_fixup: PCI Device 0x%x on PCI Bus %d not mapped to IO PORTs .. IO PORTs exhausted\n", device_dev->devfn, device_dev->bus->number);
-					continue;
-				}
-				pciio_config_set(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + (idx * 4), 4, (res + (ioport & 0xfff)));
-
-printk("sn_pci_fixup: ioport number %d mapped to pci address 0x%lx\n", ioport, (res + (ioport & 0xfff)));
-
-				device_dev->resource[idx].start = ioport;
-				device_dev->resource[idx].end = ioport + SN_IOPORTS_UNIT;
-#endif
-			}
-			if (device_dev->resource[idx].flags & IORESOURCE_MEM)
-				cmd |= PCI_COMMAND_MEMORY;
-		}
-		/*
-		 * Now handle the ROM resource ..
-		 */
-		size = device_dev->resource[PCI_ROM_RESOURCE].end -
-			device_dev->resource[PCI_ROM_RESOURCE].start;
-
-		if (size) {
-			device_dev->resource[PCI_ROM_RESOURCE].start =
-			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
-				size, 0, PCIIO_BYTE_STREAM);
-			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
-			device_dev->resource[PCI_ROM_RESOURCE].end =
-			device_dev->resource[PCI_ROM_RESOURCE].start + size;
-
-#ifdef CONFIG_IA64_SGI_SN1
-                	/*
-                 	 * go through synergy swizzled space
-                 	 */
-			device_dev->resource[PCI_ROM_RESOURCE].start &= 0xfffff7ffffffffffUL;
-			device_dev->resource[PCI_ROM_RESOURCE].end   &= 0xfffff7ffffffffffUL;
-#endif
-
-		}
-
-		/*
-		 * Update the Command Word on the Card.
-		 */
-		cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */
-					   /* bit gets dropped .. no harm */
-		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
-
-		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-				lines = 1;
-		}
- 
-		device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;
-		device_vertex = device_sysdata->vhdl;
- 
-		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
-
-		bit = intr_handle->pi_irq;
-		cpuid = intr_handle->pi_cpu;
-#ifdef CONFIG_IA64_SGI_SN1
-		irq = bit_pos_to_irq(bit);
-#else /* SN2 */
-		irq = bit;
-#endif
-		irq = irq + (cpuid << 8);
-		pciio_intr_connect(intr_handle);
-		device_dev->irq = irq;
-#ifdef ajmtestintr
-		{
-			int slot = PCI_SLOT(device_dev->devfn);
-			static int timer_set = 0;
-			pcibr_intr_t	pcibr_intr = (pcibr_intr_t)intr_handle;
-			pcibr_soft_t	pcibr_soft = pcibr_intr->bi_soft;
-			extern void intr_test_handle_intr(int, void*, struct pt_regs *);
-
-			if (!timer_set) {
-				intr_test_set_timer();
-				timer_set = 1;
-			}
-			intr_test_register_irq(irq, pcibr_soft, slot);
-			request_irq(irq, intr_test_handle_intr,0,NULL, NULL);
-		}
-#endif
-
-	}
-
-#if 0
-
-{
-        devfs_handle_t  bridge_vhdl = pci_bus_to_vertex(0);
-        pcibr_soft_t    pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl);
-        bridge_t        *bridge = pcibr_soft->bs_base;
-
-        printk("pci_fixup_ioc3: Before devreg fixup\n");
-        printk("pci_fixup_ioc3: Devreg 0 0x%x\n", bridge->b_device[0].reg);
-        printk("pci_fixup_ioc3: Devreg 1 0x%x\n", bridge->b_device[1].reg);
-        printk("pci_fixup_ioc3: Devreg 2 0x%x\n", bridge->b_device[2].reg);
-        printk("pci_fixup_ioc3: Devreg 3 0x%x\n", bridge->b_device[3].reg);
-        printk("pci_fixup_ioc3: Devreg 4 0x%x\n", bridge->b_device[4].reg);
-        printk("pci_fixup_ioc3: Devreg 5 0x%x\n", bridge->b_device[5].reg);
-        printk("pci_fixup_ioc3: Devreg 6 0x%x\n", bridge->b_device[6].reg);
-        printk("pci_fixup_ioc3: Devreg 7 0x%x\n", bridge->b_device[7].reg);
-}
-
-printk("testing Big Window: 0xC0000200c0000000 %p\n", *( (volatile uint64_t *)0xc0000200a0000000));
-printk("testing Big Window: 0xC0000200c0000008 %p\n", *( (volatile uint64_t *)0xc0000200a0000008));
-
-#endif
-
-}
-
-/*
- * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
- *
- *	Linux PCI Bus numbers are assigned from lowest module_id numbers
- *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
- *	HUB_WIDGET_ID_MIN:
- *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
- *
- *	Given 2 modules 001c01 and 001c02 we get the following mappings:
- *		001c01, widgetnum 15 = Bus number 0
- *		001c01, widgetnum 14 = Bus number 1
- *		001c02, widgetnum 15 = Bus number 3
- *		001c02, widgetnum 14 = Bus number 4
- *		etc.
- *
- * The rational for starting Bus Number 0 with Widget number 15 is because 
- * the system boot disks are always connected via Widget 15 Slot 0 of the 
- * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
- * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
- * module id(Master Cnode) of the system.
- *	
- */
-static int 
-pci_bus_map_create(devfs_handle_t xtalk)
-{
-
-	devfs_handle_t master_node_vertex = NULL;
-	devfs_handle_t xwidget = NULL;
-	devfs_handle_t pci_bus = NULL;
-	hubinfo_t hubinfo = NULL;
-	xwidgetnum_t widgetnum;
-	char pathname[128];
-	graph_error_t rv;
-
-	/*
-	 * Loop throught this vertex and get the Xwidgets ..
-	 */
-	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
-#if 0
-        {
-                int pos;
-                char dname[256];
-                pos = devfs_generate_path(xtalk, dname, 256);
-                printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-        }
-#endif
-
-		sprintf(pathname, "%d", widgetnum);
-		xwidget = NULL;
-		
-		/*
-		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
-		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
-		 */
-		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
-		if ( (rv != GRAPH_SUCCESS) ) {
-			if (!xwidget)
-				continue;
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		pci_bus = NULL;
-		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
-			if (!pci_bus)
-				continue;
-
-		/*
-		 * Assign the correct bus number and also the nasid of this 
-		 * pci Xwidget.
-		 * 
-		 * Should not be any race here ...
-		 */
-		num_bridges++;
-		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
-
-		/*
-		 * Get the master node and from there get the NASID.
-		 */
-		master_node_vertex = device_master_get(xwidget);
-		if (!master_node_vertex) {
-			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
-		}
-	
-		hubinfo_get(master_node_vertex, &hubinfo);
-		if (!hubinfo) {
-			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
-			return(1);
-		} else {
-			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
-		}
-
-		/*
-		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
-		 */
-		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
-		if (!busnum_to_atedmamaps[num_bridges - 1])
-			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
-
-		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
-
-	}
-
-        return(0);
-}
-
-/*
- * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure   
- *      initialization has completed to set up the mappings between Xbridge
- *      and logical pci bus numbers.  We also set up the NASID for each of these
- *      xbridges.
- *
- *      Must be called before pci_init() is invoked.
- */
-int
-pci_bus_to_hcl_cvlink(void) 
-{
-
-	devfs_handle_t devfs_hdl = NULL;
-	devfs_handle_t xtalk = NULL;
-	int rv = 0;
-	char name[256];
-	int master_iobrick;
-	int i;
-
-	/*
-	 * Iterate throught each xtalk links in the system ..
-	 * /hw/module/001c01/node/xtalk/ 8|9|10|11|12|13|14|15 
-	 *
-	 * /hw/module/001c01/node/xtalk/15 -> /hw/module/001c01/Ibrick/xtalk/15
-	 *
-	 * What if it is not pci?
-	 */
-	devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module");
-
-	/*
-	 * To provide consistent(not persistent) device naming, we need to start 
-	 * bus number allocation from the C-Brick with the lowest module id e.g. 001c01 
-	 * with an attached I-Brick.  Find the master_iobrick.
-	 */
-	master_iobrick = -1;
-	for (i = 0; i < nummodules; i++) {
-		moduleid_t iobrick_id; 
-		iobrick_id = iobrick_module_get(&modules[i]->elsc);
-		if (iobrick_id > 0) { /* Valid module id */
-			if (MODULE_GET_BTYPE(iobrick_id) == MODULE_IBRICK) {
-				master_iobrick = i;
-				break;
-			}
-		}
-	}
-
-	/*
-	 * The master_iobrick gets bus 0 and 1.
-	 */
-	if (master_iobrick >= 0) {
-		memset(name, 0, 256);
-		format_module_id(name, modules[master_iobrick]->id, MODULE_FORMAT_BRIEF);
-		strcat(name, "/node/xtalk");
-		xtalk = NULL;
-		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-		pci_bus_map_create(xtalk);
-	}
-		
-	/*
-	 * Now go do the rest of the modules, starting from the C-Brick with the lowest 
-	 * module id, remembering to skip the master_iobrick, which was done above.
-	 */
-	for (i = 0; i < nummodules; i++) {
-		if (i == master_iobrick) {
-			continue; /* Did the master_iobrick already. */
-		}
-
-		memset(name, 0, 256);
-		format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
-		strcat(name, "/node/xtalk");
-		xtalk = NULL;
-		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-		pci_bus_map_create(xtalk);
-	}
-
-	return(0);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/pci_dma.c linux-2.4.22-pre10/arch/ia64/sn/io/pci_dma.c
--- linux-2.4.21/arch/ia64/sn/io/pci_dma.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/pci_dma.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,700 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000,2002 Silicon Graphics, Inc. All rights reserved.
- *
- * Routines for PCI DMA mapping.  See Documentation/DMA-mapping.txt for
- * a description of how these routines should be used.
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/module.h>
-
-#include <asm/delay.h>
-#include <asm/io.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/types.h>
-#include <asm/sn/alenlist.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/nag.h>
-
-/*
- * For ATE allocations
- */
-pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t);
-void free_pciio_dmamap(pcibr_dmamap_t);
-static struct sn_dma_maps_s *find_sn_dma_map(dma_addr_t, unsigned char);
-
-/*
- * Toplogy stuff
- */
-extern devfs_handle_t busnum_to_pcibr_vhdl[];
-extern nasid_t busnum_to_nid[];
-extern void * busnum_to_atedmamaps[];
-
-/**
- * get_free_pciio_dmamap - find and allocate an ATE
- * @pci_bus: PCI bus to get an entry for
- *
- * Finds and allocates an ATE on the PCI bus specified
- * by @pci_bus.
- */
-pciio_dmamap_t
-get_free_pciio_dmamap(devfs_handle_t pci_bus)
-{
-	int i;
-	struct sn_dma_maps_s *sn_dma_map = NULL;
-
-	/*
-	 * Darn, we need to get the maps allocated for this bus.
-	 */
-	for (i = 0; i < MAX_PCI_XWIDGET; i++) {
-		if (busnum_to_pcibr_vhdl[i] == pci_bus) {
-			sn_dma_map = busnum_to_atedmamaps[i];
-		}
-	}
-
-	/*
-	 * Now get a free dmamap entry from this list.
-	 */
-	for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) {
-		if (!sn_dma_map->dma_addr) {
-			sn_dma_map->dma_addr = -1;
-			return( (pciio_dmamap_t) sn_dma_map );
-		}
-	}
-
-	return NULL;
-}
-
-/**
- * free_pciio_dmamap - free an ATE
- * @dma_map: ATE to free
- *
- * Frees the ATE specified by @dma_map.
- */
-void
-free_pciio_dmamap(pcibr_dmamap_t dma_map)
-{
-	struct sn_dma_maps_s *sn_dma_map;
-
-	sn_dma_map = (struct sn_dma_maps_s *) dma_map;
-	sn_dma_map->dma_addr = 0;
-}
-
-/**
- * find_sn_dma_map - find an ATE associated with @dma_addr and @busnum
- * @dma_addr: DMA address to look for
- * @busnum: PCI bus to look on
- *
- * Finds the ATE associated with @dma_addr and @busnum.
- */
-static struct sn_dma_maps_s *
-find_sn_dma_map(dma_addr_t dma_addr, unsigned char busnum)
-{
-
-	struct sn_dma_maps_s *sn_dma_map = NULL;
-	int i;
-
-	sn_dma_map = busnum_to_atedmamaps[busnum];
-
-	for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) {
-		if (sn_dma_map->dma_addr == dma_addr) {
-			return sn_dma_map;
-		}
-	}
-
-	return NULL;
-}
-
-/**
- * sn_dma_sync - try to flush DMA buffers into the coherence domain
- * @hwdev: device to flush
- *
- * This routine flushes all DMA buffers for the device into the II of
- * the destination hub.
- *
- * NOTE!: this does not mean that the data is in the "coherence domain",
- * but it is very close.  In other words, this routine *does not work*
- * as advertised due to hardware bugs.  That said, it should be good enough for
- * most situations.
- */
-void
-sn_dma_sync(struct pci_dev *hwdev)
-{
-
-#ifdef SN_DMA_SYNC
-
-	struct sn_device_sysdata *device_sysdata;
-	volatile unsigned long dummy;
-
-	/*
-	 * A DMA sync is supposed to ensure that 
-	 * all the DMA from a particular device
-	 * is complete and coherent.  We
-	 * try to do this by
-	 *	1. flushing the write wuffers from Bridge
-	 *	2. flushing the Xbow port.
-	 * Unfortunately, this only gets the DMA transactions 'very close' to
-	 * the coherence domain, but not quite in it.
-	 */
-	device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata;
-	dummy = (volatile unsigned long ) *device_sysdata->dma_buf_sync;
-
-	/*
-	 * For the Xbow port flush, we may be denied the request because 
-	 * someone else may be flushing the port .. try again.
-	 */
-	while((volatile unsigned long ) *device_sysdata->xbow_buf_sync) {
-		udelay(2);
-	}
-#endif
-}
-
-/**
- * sn_pci_alloc_consistent - allocate memory for coherent DMA
- * @hwdev: device to allocate for
- * @size: size of the region
- * @dma_handle: DMA (bus) address
- *
- * pci_alloc_consistent() returns a pointer to a memory region suitable for
- * coherent DMA traffic to/from a PCI device.  On SN platforms, this means
- * that @dma_handle will have the %PCIIO_DMA_CMD flag set.
- *
- * This interface is usually used for "command" streams (e.g. the command
- * queue for a SCSI controller).  See Documentation/DMA-mapping.txt for
- * more information.  Note that this routine will always put a 32 bit
- * DMA address into @dma_handle.  This is because most devices
- * that are capable of 64 bit PCI DMA transactions can't do 64 bit _coherent_
- * DMAs, and unfortunately this interface has to cater to the LCD.  Oh well.
- *
- * Also known as platform_pci_alloc_consistent() by the IA64 machvec code.
- */
-void *
-sn_pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
-{
-        void *cpuaddr;
-	devfs_handle_t vhdl;
-	struct sn_device_sysdata *device_sysdata;
-	unsigned long phys_addr;
-	pciio_dmamap_t dma_map = 0;
-	struct sn_dma_maps_s *sn_dma_map;
-
-	*dma_handle = 0;
-
-	/* We can't easily support < 32 bit devices */
-	if (IS_PCI32L(hwdev))
-		return NULL;
-
-	/*
-	 * Get hwgraph vertex for the device
-	 */
-	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
-	vhdl = device_sysdata->vhdl;
-
-	/*
-	 * Allocate the memory.  FIXME: if we're allocating for
-	 * two devices on the same bus, we should at least try to
-	 * allocate memory in the same 2 GB window to avoid using
-	 * ATEs for the translation.  See the comment above about the
-	 * 32 bit requirement for this function.
-	 */
-	if(!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size))))
-		return NULL;
-
-	memset(cpuaddr, 0, size); /* have to zero it out */
-
-	/* physical addr. of the memory we just got */
-	phys_addr = __pa(cpuaddr);
-
-	/*
-	 * This will try to use a Direct Map register to do the
-	 * 32 bit DMA mapping, but it may not succeed if another
-	 * device on the same bus is already mapped with different
-	 * attributes or to a different memory region.
-	 */
-#ifdef CONFIG_IA64_SGI_SN1
-	*dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-					  PCIIO_BYTE_STREAM |
-					  PCIIO_DMA_CMD);
-#elif defined(CONFIG_IA64_SGI_SN2)
-	*dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					  PCIIO_DMA_CMD);
-#else
-#error unsupported platform
-#endif
-
-	/*
-	 * It is a 32 bit card and we cannot do direct mapping,
-	 * so we try to use an ATE.
-	 */
-	if (!(*dma_handle)) {
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, size,
-					     PCIIO_BYTE_STREAM |
-					     PCIIO_DMA_CMD);
-#elif defined(CONFIG_IA64_SGI_SN2)
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, size,
-				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					     PCIIO_DMA_CMD);
-#else
-#error unsupported platform
-#endif
-		if (!dma_map) {
-			printk(KERN_ERR "sn_pci_alloc_consistent: Unable to "
-			       "allocate anymore 32 bit page map entries.\n");
-			BUG();
-		}
-		*dma_handle = (dma_addr_t) pciio_dmamap_addr(dma_map,phys_addr,
-							     size);
-		sn_dma_map = (struct sn_dma_maps_s *)dma_map;
-		sn_dma_map->dma_addr = *dma_handle;
-	}
-
-        return cpuaddr;
-}
-
-/**
- * sn_pci_free_consistent - free memory associated with coherent DMAable region
- * @hwdev: device to free for
- * @size: size to free
- * @vaddr: kernel virtual address to free
- * @dma_handle: DMA address associated with this region
- *
- * Frees the memory allocated by pci_alloc_consistent().  Also known
- * as platform_pci_free_consistent() by the IA64 machvec code.
- */
-void
-sn_pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
-{
-	struct sn_dma_maps_s *sn_dma_map = NULL;
-
-	/*
-	 * Get the sn_dma_map entry.
-	 */
-	if (IS_PCI32_MAPPED(dma_handle))
-		sn_dma_map = find_sn_dma_map(dma_handle, hwdev->bus->number);
-
-	/*
-	 * and free it if necessary...
-	 */
-	if (sn_dma_map) {
-		pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
-		pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
-		sn_dma_map->dma_addr = (dma_addr_t)NULL;
-	}
-	free_pages((unsigned long) vaddr, get_order(size));
-}
-
-/**
- * sn_pci_map_sg - map a scatter-gather list for DMA
- * @hwdev: device to map for
- * @sg: scatterlist to map
- * @nents: number of entries
- * @direction: direction of the DMA transaction
- *
- * Maps each entry of @sg for DMA.  Also known as platform_pci_map_sg by the
- * IA64 machvec code.
- */
-int
-sn_pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
-{
-
-	int i;
-	devfs_handle_t vhdl;
-	dma_addr_t dma_addr;
-	unsigned long phys_addr;
-	struct sn_device_sysdata *device_sysdata;
-	pciio_dmamap_t dma_map;
-
-	/* can't go anywhere w/o a direction in life */
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/*
-	 * Get the hwgraph vertex for the device
-	 */
-	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
-	vhdl = device_sysdata->vhdl;
-
-	/*
-	 * Setup a DMA address for each entry in the
-	 * scatterlist.
-	 */
-	for (i = 0; i < nents; i++, sg++) {
-		/* this catches incorrectly written drivers that
-                   attempt to map scatterlists that they have
-                   previously mapped.  we print a warning and
-                   continue, but the driver should be fixed */
-		switch (((u64)sg->address) >> 60) {
-		case 0xa:
-		case 0xb:
-#ifdef DEBUG
-/* This needs to be cleaned up at some point. */
-			NAG("A PCI driver (for device at%8s) has attempted to "
-			    "map a scatterlist that was previously mapped at "
-			    "%p - this is currently being worked around.\n",
-			    hwdev->slot_name, (void *)sg->address);
-#endif
-			phys_addr = (u64)sg->address & TO_PHYS_MASK;
-			break;
-		default: /* not previously mapped, get the phys. addr */
-			phys_addr = __pa(sg->address);
-			break;
-		}
-		sg->page = NULL;
-		dma_addr = 0;
-
-		/*
-		 * Handle the most common case: 64 bit cards.  This
-		 * call should always succeed.
-		 */
-		if (IS_PCIA64(hwdev)) {
-			dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
-						       sg->length,
-			       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-						       PCIIO_DMA_DATA |
-						       PCIIO_DMA_A64);
-			sg->address = (char *)dma_addr;
-			continue;
-		}
-
-		/*
-		 * Handle 32-63 bit cards via direct mapping
-		 */
-		if (IS_PCI32G(hwdev)) {
-#ifdef CONFIG_IA64_SGI_SN1
-			dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
-						       sg->length,
-						       PCIIO_BYTE_STREAM |
-						       PCIIO_DMA_DATA);
-#elif defined(CONFIG_IA64_SGI_SN2)
-			dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
-						       sg->length,
-					((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-						       PCIIO_DMA_DATA);
-#else
-#error unsupported platform
-#endif
-			/*
-			 * See if we got a direct map entry
-			 */
-			if (dma_addr) {
-				sg->address = (char *)dma_addr;
-				continue;
-			}
-
-		}
-
-		/*
-		 * It is a 32 bit card and we cannot do direct mapping,
-		 * so we use an ATE.
-		 */
-		dma_map = 0;
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length,
-					     PCIIO_BYTE_STREAM |
-					     PCIIO_DMA_DATA);
-#elif defined(CONFIG_IA64_SGI_SN2)
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length,
-				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					     PCIIO_DMA_DATA);
-#else
-#error unsupported platform
-#endif
-		if (!dma_map) {
-			printk(KERN_ERR "sn_pci_map_sg: Unable to allocate "
-			       "anymore 32 bit page map entries.\n");
-			BUG();
-		}
-		dma_addr = pciio_dmamap_addr(dma_map, phys_addr, sg->length);
-		sg->address = (char *)dma_addr;
-		sg->page = (struct page *)dma_map;
-		
-	}
-
-	return nents;
-
-}
-
-/**
- * sn_pci_unmap_sg - unmap a scatter-gather list
- * @hwdev: device to unmap
- * @sg: scatterlist to unmap
- * @nents: number of scatterlist entries
- * @direction: DMA direction
- *
- * Unmap a set of streaming mode DMA translations.  Again, cpu read rules
- * concerning calls here are the same as for pci_unmap_single() below.  Also
- * known as sn_pci_unmap_sg() by the IA64 machvec code.
- */
-void
-sn_pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
-{
-	int i;
-	struct sn_dma_maps_s *sn_dma_map;
-
-	/* can't go anywhere w/o a direction in life */
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	for (i = 0; i < nents; i++, sg++)
-		if (sg->page) {
-			/*
-			 * We maintain the DMA Map pointer in sg->page if 
-			 * it is ever allocated.
-			 */
-			sg->address = 0;
-			sn_dma_map = (struct sn_dma_maps_s *)sg->page;
-			pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
-			pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
-			sn_dma_map->dma_addr = 0;
-			sg->page = 0;
-		}
-
-}
-
-/**
- * sn_pci_map_single - map a single region for DMA
- * @hwdev: device to map for
- * @ptr: kernel virtual address of the region to map
- * @size: size of the region
- * @direction: DMA direction
- *
- * Map the region pointed to by @ptr for DMA and return the
- * DMA address.   Also known as platform_pci_map_single() by
- * the IA64 machvec code.
- *
- * We map this to the one step pciio_dmamap_trans interface rather than
- * the two step pciio_dmamap_alloc/pciio_dmamap_addr because we have
- * no way of saving the dmamap handle from the alloc to later free
- * (which is pretty much unacceptable).
- *
- * TODO: simplify our interface;
- *       get rid of dev_desc and vhdl (seems redundant given a pci_dev);
- *       figure out how to save dmamap handle so can use two step.
- */
-dma_addr_t
-sn_pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
-{
-	devfs_handle_t vhdl;
-	dma_addr_t dma_addr;
-	unsigned long phys_addr;
-	struct sn_device_sysdata *device_sysdata;
-	pciio_dmamap_t dma_map = NULL;
-	struct sn_dma_maps_s *sn_dma_map;
-
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/* SN cannot support DMA addresses smaller than 32 bits. */
-	if (IS_PCI32L(hwdev))
-		return 0;
-
-	/*
-	 * find vertex for the device
-	 */
-	device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata;
-	vhdl = device_sysdata->vhdl;
-
-	/*
-	 * Call our dmamap interface
-	 */
-	dma_addr = 0;
-	phys_addr = __pa(ptr);
-
-	if (IS_PCIA64(hwdev)) {
-		/* This device supports 64 bit DMA addresses. */
-		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-		       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					       PCIIO_DMA_DATA |
-					       PCIIO_DMA_A64);
-		return dma_addr;
-	}
-
-	/*
-	 * Devices that support 32 bit to 63 bit DMA addresses get
-	 * 32 bit DMA addresses.
-	 *
-	 * First try to get a 32 bit direct map register.
-	 */
-	if (IS_PCI32G(hwdev)) {
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-					       PCIIO_BYTE_STREAM |
-					       PCIIO_DMA_DATA);
-#elif defined(CONFIG_IA64_SGI_SN2)
-		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					       PCIIO_DMA_DATA);
-#else
-#error unsupported platform
-#endif
-		if (dma_addr)
-			return dma_addr;
-	}
-
-	/*
-	 * It's a 32 bit card and we cannot do direct mapping so
-	 * let's use the PMU instead.
-	 */
-	dma_map = NULL;
-#ifdef CONFIG_IA64_SGI_SN1
-	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, PCIIO_BYTE_STREAM |
-				     PCIIO_DMA_DATA);
-#elif defined(CONFIG_IA64_SGI_SN2)
-	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, 
-			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-			PCIIO_DMA_DATA);
-#else
-#error unsupported platform
-#endif
-
-	if (!dma_map) {
-		printk(KERN_ERR "pci_map_single: Unable to allocate anymore "
-		       "32 bit page map entries.\n");
-		BUG();
-	}
-
-	dma_addr = (dma_addr_t) pciio_dmamap_addr(dma_map, phys_addr, size);
-	sn_dma_map = (struct sn_dma_maps_s *)dma_map;
-	sn_dma_map->dma_addr = dma_addr;
-
-	return ((dma_addr_t)dma_addr);
-}
-
-/**
- * sn_pci_unmap_single - unmap a region used for DMA
- * @hwdev: device to unmap
- * @dma_addr: DMA address to unmap
- * @size: size of region
- * @direction: DMA direction
- *
- * Unmaps the region pointed to by @dma_addr.  Also known as
- * platform_pci_unmap_single() by the IA64 machvec code.
- */
-void
-sn_pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
-{
-	struct sn_dma_maps_s *sn_dma_map = NULL;
-
-        if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/*
-	 * Get the sn_dma_map entry.
-	 */
-	if (IS_PCI32_MAPPED(dma_addr))
-		sn_dma_map = find_sn_dma_map(dma_addr, hwdev->bus->number);
-
-	/*
-	 * and free it if necessary...
-	 */
-	if (sn_dma_map) {
-		pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
-		pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
-		sn_dma_map->dma_addr = (dma_addr_t)NULL;
-	}
-}
-
-/**
- * sn_pci_dma_sync_single - make sure all DMAs have completed
- * @hwdev: device to sync
- * @dma_handle: DMA address to sync
- * @size: size of region
- * @direction: DMA direction
- *
- * This routine is supposed to sync the DMA region specified
- * by @dma_handle into the 'coherence domain'.  See sn_dma_sync()
- * above for more information.   Also known as
- * platform_pci_dma_sync_single() by the IA64 machvec code.
- */
-void
-sn_pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
-{
-	if (direction == PCI_DMA_NONE)
-                BUG();
-
-	sn_dma_sync(hwdev);
-}
-
-/**
- * sn_pci_dma_sync_sg - make sure all DMAs have completed
- * @hwdev: device to sync
- * @sg: scatterlist to sync
- * @nents: number of entries in the scatterlist
- * @direction: DMA direction
- *
- * This routine is supposed to sync the DMA regions specified
- * by @sg into the 'coherence domain'.  See sn_dma_sync()
- * above for more information.   Also known as
- * platform_pci_dma_sync_sg() by the IA64 machvec code.
- */
-void
-sn_pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
-{
-        if (direction == PCI_DMA_NONE)
-                BUG();
-
-	sn_dma_sync(hwdev);
-}
-
-/**
- * sn_dma_address - get the DMA address for the first entry of a scatterlist
- * @sg: sg to look at
- *
- * Gets the DMA address for the scatterlist @sg.  Also known as
- * platform_dma_address() by the IA64 machvec code.
- */
-unsigned long
-sn_dma_address(struct scatterlist *sg)
-{
-	return ((unsigned long)sg->address);
-}
-
-/**
- * sn_dma_supported - test a DMA mask
- * @hwdev: device to test
- * @mask: DMA mask to test
- *
- * Return whether the given PCI device DMA address mask can be supported
- * properly.  For example, if your device can only drive the low 24-bits
- * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
- * this function.  Of course, SN only supports devices that have 32 or more
- * address bits when using the PMU.  We could theoretically support <32 bit
- * cards using direct mapping, but we'll worry about that later--on the off
- * chance that someone actually wants to use such a card.
- */
-int
-sn_pci_dma_supported(struct pci_dev *hwdev, u64 mask)
-{
-	if (mask < 0xffffffff)
-		return 0;
-	return 1;
-}
-
-EXPORT_SYMBOL(sn_pci_unmap_single);
-EXPORT_SYMBOL(sn_pci_map_single);
-EXPORT_SYMBOL(sn_pci_dma_sync_single);
-EXPORT_SYMBOL(sn_pci_map_sg);
-EXPORT_SYMBOL(sn_pci_unmap_sg);
-EXPORT_SYMBOL(sn_pci_alloc_consistent);
-EXPORT_SYMBOL(sn_pci_free_consistent);
-EXPORT_SYMBOL(sn_dma_address);
-EXPORT_SYMBOL(sn_pci_dma_supported);
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/pciba.c linux-2.4.22-pre10/arch/ia64/sn/io/pciba.c
--- linux-2.4.21/arch/ia64/sn/io/pciba.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/pciba.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,916 +0,0 @@
-/*
- * arch/ia64/sn/io/pciba.c
- *
- * IRIX PCIBA-inspired user mode PCI interface
- *
- * requires: devfs
- *
- * device nodes show up in /dev/pci/BB/SS.F (where BB is the bus the
- * device is on, SS is the slot the device is in, and F is the
- * device's function on a multi-function card).
- *
- * when compiled into the kernel, it will only be initialized by the
- * sgi sn1 specific initialization code.  in this case, device nodes
- * are under /dev/hw/..../
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License.  See the file "COPYING" in the main directory of
- * this archive for more details.
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
- *
- * 03262001 - Initial version by Chad Talbott
- */
-
-
-/* jesse's beefs:
-
-   register_pci_device should be documented
-   
-   grossness with do_swap should be documented
-   
-   big, gross union'ized node_data should be replaced with independent
-   structures
-
-   replace global list of nodes with global lists of resources.  could
-   use object oriented approach of allocating and cleaning up
-   resources.
-   
-*/
-
-
-#include <linux/config.h>
-#ifndef CONFIG_DEVFS_FS
-#  error PCIBA requires devfs
-#endif
-
-#include <linux/module.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/pci.h>
-#include <linux/list.h>
-
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/mman.h>
-#include <linux/init.h>
-#include <linux/raw.h>
-#include <linux/capability.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/pgalloc.h>
-#include <asm/page.h>
-
-#include <asm/sn/pci/pciba.h>
-
-
-MODULE_DESCRIPTION("User mode PCI interface");
-MODULE_AUTHOR("Chad Talbott");
-
-
-#undef DEBUG_PCIBA
-/* #define DEBUG_PCIBA */
-
-#undef TRACE_PCIBA
-/* #define TRACE_PCIBA */
-
-#if defined(DEBUG_PCIBA)
-#  define DPRINTF(x...) printk(KERN_DEBUG x)
-#else
-#  define DPRINTF(x...)
-#endif
-
-#if defined(TRACE_PCIBA)
-#  if defined(__GNUC__)
-#    define TRACE()	printk(KERN_DEBUG "%s:%d:%s\n", \
-			       __FILE__, __LINE__, __FUNCTION__)
-#  else
-#    define TRACE()	printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__)
-#  endif
-#else
-#  define TRACE()
-#endif
-
-
-typedef enum { failure, success } status;
-typedef enum { false, true } boolean;
-
-
-/* major data structures:
-
-   struct node_data -
-   
-   	one for each file registered with devfs.  contains everything
-   	that any file's fops would need to know about.
-
-   struct dma_allocation -
-
-   	a single DMA allocation.  only the 'dma' nodes care about
-   	these.  they are there primarily to allow the driver to look
-   	up the kernel virtual address of dma buffers allocated by
-   	pci_alloc_consistent, as the application is only given the
-   	physical address (to program the device's dma, presumably) and
-   	cannot supply the kernel virtual address when freeing the
-   	buffer.
-
-	it's also useful to maintain a list of buffers allocated
-	through a specific node to allow some sanity checking by this
-	driver.  this prevents (for example) a broken application from
-	freeing buffers that it didn't allocate, or buffers allocated
-	on another node.
-   
-   global_node_list -
-
-   	a list of all nodes allocated.  this allows the driver to free
-   	all the memory it has 'kmalloc'd in case of an error, or on
-   	module removal.
-
-   global_dma_list -
-
-        a list of all dma buffers allocated by this driver.  this
-	allows the driver to 'pci_free_consistent' all buffers on
-	module removal or error.
-
-*/
-
-
-struct node_data {
-	/* flat list of all the device nodes.  makes it easy to free
-	   them all when we're unregistered */
-	struct list_head global_node_list;
-	devfs_handle_t devfs_handle;
-
-	void (* cleanup)(struct node_data *);
-
-	union {
-		struct {
-			struct pci_dev * dev;
-			struct list_head dma_allocs;
-			boolean mmapped;
-		} dma;
-		struct {
-			struct pci_dev * dev;
-			u32 saved_rom_base_reg;
-			boolean mmapped;
-		} rom;
-		struct {
-			struct resource * res;
-		} base;
-		struct {
-			struct pci_dev * dev;
-		} config;
-	} u;
-};
-
-struct dma_allocation {
-	struct list_head list;
-
-	dma_addr_t handle;
-	void * va;
-	size_t size;
-};
-
-
-static LIST_HEAD(global_node_list);
-static LIST_HEAD(global_dma_list);
-
-
-/* module entry points */
-int __init pciba_init(void);
-void __exit pciba_exit(void);
-
-static status __init register_with_devfs(void);
-static void __exit unregister_with_devfs(void);
-
-static status __init register_pci_device(devfs_handle_t device_dir_handle,
-					 struct pci_dev * dev);
-
-/* file operations */
-static int generic_open(struct inode * inode, struct file * file);
-static int rom_mmap(struct file * file, struct vm_area_struct * vma);
-static int rom_release(struct inode * inode, struct file * file);
-static int base_mmap(struct file * file, struct vm_area_struct * vma);
-static int config_ioctl(struct inode * inode, struct file * file, 
-			unsigned int cmd, 
-			unsigned long arg);
-static int dma_ioctl(struct inode * inode, struct file * file, 
-		     unsigned int cmd, 
-		     unsigned long arg);
-static int dma_mmap(struct file * file, struct vm_area_struct * vma);
-
-/* support routines */
-static int mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va);
-static int mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va);
-
-#ifdef DEBUG_PCIBA
-static void dump_nodes(struct list_head * nodes);
-static void dump_allocations(struct list_head * dalp);
-#endif
-
-/* file operations for each type of node */
-static struct file_operations rom_fops = {
-	owner:		THIS_MODULE,
-	mmap:		rom_mmap,
-	open:		generic_open,
-	release:	rom_release
-};
- 
-
-static struct file_operations base_fops = {
-	owner:		THIS_MODULE,
-	mmap:		base_mmap,
-	open:		generic_open
-};
-
-
-static struct file_operations config_fops = {
-	owner:		THIS_MODULE,
-	ioctl:		config_ioctl,
-	open:		generic_open
-};	
-
-static struct file_operations dma_fops = {
-	owner:		THIS_MODULE,
-	ioctl:		dma_ioctl,
-	mmap:		dma_mmap,
-	open:		generic_open
-};	
-
-
-module_init(pciba_init);
-module_exit(pciba_exit);
-
-
-int __init
-pciba_init(void)
-{
-	TRACE();
-
-	if (register_with_devfs() == failure)
-		return 1; /* failure */
-
-	printk("PCIBA (a user mode PCI interface) initialized.\n");
-
-	return 0; /* success */
-}
-
-
-void __exit
-pciba_exit(void)
-{
-	TRACE();
-
-	/* FIXME: should also free all that memory that we allocated
-           ;) */
-	unregister_with_devfs();
-}
-
-
-# if 0
-static void __exit
-free_nodes(void)
-{
-	struct node_data * nd;
-	
-	TRACE();
-
-	list_for_each(nd, &node_list) {
-		kfree(list_entry(nd, struct nd, node_list));
-	}
-}
-#endif
-
-
-static devfs_handle_t pciba_devfs_handle;
-
-
-extern devfs_handle_t
-devfn_to_vertex(unsigned char busnum, unsigned int devfn);
-
-static status __init
-register_with_devfs(void)
-{
-	struct pci_dev * dev;
-	devfs_handle_t device_dir_handle;
-
-	TRACE();
-
-	/* FIXME: don't forget /dev/.../pci/mem & /dev/.../pci/io */
-
-	pci_for_each_dev(dev) {
-		device_dir_handle = devfn_to_vertex(dev->bus->number,
-						    dev->devfn);
-		if (device_dir_handle == NULL)
-			return failure;
-	
-		if (register_pci_device(device_dir_handle, dev) == failure) {
-			devfs_unregister(pciba_devfs_handle);
-			return failure;
-		}
-	}
-
-	return success;
-}
-
-static void __exit
-unregister_with_devfs(void)
-{
-	struct list_head * lhp;
-	struct node_data * nd;
-	
-	TRACE();
-
-	list_for_each(lhp, &global_node_list) {
-		nd = list_entry(lhp, struct node_data, global_node_list);
-		devfs_unregister(nd->devfs_handle);
-	}
-
-}
-
-
-struct node_data * new_node(void)
-{
-	struct node_data * node;
-	
-	TRACE();
-	
-	node = kmalloc(sizeof(struct node_data), GFP_KERNEL);
-	if (node == NULL)
-		return NULL;
-	list_add(&node->global_node_list, &global_node_list);
-	return node;
-}
-
-
-void dma_cleanup(struct node_data * dma_node)
-{
-	TRACE();
-
-	/* FIXME: should free these allocations */
-#ifdef DEBUG_PCIBA
-	dump_allocations(&dma_node->u.dma.dma_allocs);
-#endif
-	devfs_unregister(dma_node->devfs_handle);
-}
-
-
-void init_dma_node(struct node_data * node,
-		   struct pci_dev * dev, devfs_handle_t dh)
-{
-	TRACE();
-
-	node->devfs_handle = dh;
-	node->u.dma.dev = dev;
-	node->cleanup = dma_cleanup;
-	INIT_LIST_HEAD(&node->u.dma.dma_allocs);
-}
-
-
-void rom_cleanup(struct node_data * rom_node)
-{
-	TRACE();
-
-	if (rom_node->u.rom.mmapped)
-		pci_write_config_dword(rom_node->u.rom.dev,
-				       PCI_ROM_ADDRESS,
-				       rom_node->u.rom.saved_rom_base_reg);
-	devfs_unregister(rom_node->devfs_handle);
-}
-
-
-void init_rom_node(struct node_data * node,
-		   struct pci_dev * dev, devfs_handle_t dh)
-{
-	TRACE();
-
-	node->devfs_handle = dh;
-	node->u.rom.dev = dev;
-	node->cleanup = rom_cleanup;
-	node->u.rom.mmapped = false;
-}
-
-
-static status __init
-register_pci_device(devfs_handle_t device_dir_handle, struct pci_dev * dev)
-{
-	struct node_data * nd;
-	char devfs_path[20];
-	devfs_handle_t node_devfs_handle;
-	int ri;
-
-	TRACE();
-
-
-	/* register nodes for all the device's base address registers */
-	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
-		if (pci_resource_len(dev, ri) != 0) {
-			sprintf(devfs_path, "base/%d", ri);
-			if (devfs_register(device_dir_handle, devfs_path,
-					   DEVFS_FL_NONE,
-					   0, 0,
-					   S_IFREG | S_IRUSR | S_IWUSR,
-					   &base_fops, 
-					   &dev->resource[ri]) == NULL)
-				return failure;
-		}
-	}
-	
-	/* register a node corresponding to the first MEM resource on
-           the device */
-	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
-		if (dev->resource[ri].flags & IORESOURCE_MEM &&
-		    pci_resource_len(dev, ri) != 0) {
-			if (devfs_register(device_dir_handle, "mem",
-					   DEVFS_FL_NONE, 0, 0,
-					   S_IFREG | S_IRUSR | S_IWUSR,
-					   &base_fops, 
-					   &dev->resource[ri]) == NULL)
-				return failure;
-			break;
-		}
-	}
-
-	/* also register a node corresponding to the first IO resource
-           on the device */
-	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
-		if (dev->resource[ri].flags & IORESOURCE_IO &&
-		    pci_resource_len(dev, ri) != 0) {
-			if (devfs_register(device_dir_handle, "io",
-					   DEVFS_FL_NONE, 0, 0,
-					   S_IFREG | S_IRUSR | S_IWUSR,
-					   &base_fops, 
-					   &dev->resource[ri]) == NULL)
-				return failure;
-			break;
-		}
-	}
-
-	/* register a node corresponding to the device's ROM resource,
-           if present */
-	if (pci_resource_len(dev, PCI_ROM_RESOURCE) != 0) {
-		nd = new_node();
-		if (nd == NULL)
-			return failure;
-		node_devfs_handle = devfs_register(device_dir_handle, "rom",
-						   DEVFS_FL_NONE, 0, 0,
-						   S_IFREG | S_IRUSR,
-						   &rom_fops, nd);
-		if (node_devfs_handle == NULL)
-			return failure;
-		init_rom_node(nd, dev, node_devfs_handle);
-	}
-
-	/* register a node that allows ioctl's to read and write to
-           the device's config space */
-	if (devfs_register(device_dir_handle, "config", DEVFS_FL_NONE,
-			   0, 0, S_IFREG | S_IRUSR | S_IWUSR,
-			   &config_fops, dev) == NULL)
-		return failure;
-
-
-	/* finally, register a node that allows ioctl's to allocate
-           and free DMA buffers, as well as memory map those
-           buffers. */
-	nd = new_node();
-	if (nd == NULL)
-		return failure;
-	node_devfs_handle =
-		devfs_register(device_dir_handle, "dma", DEVFS_FL_NONE,
-			       0, 0, S_IFREG | S_IRUSR | S_IWUSR,
-			       &dma_fops, nd);
-	if (node_devfs_handle == NULL)
-		return failure;
-	init_dma_node(nd, dev, node_devfs_handle);
-
-#ifdef DEBUG_PCIBA
-	dump_nodes(&global_node_list);
-#endif
-	
-	return success;
-}
-
-
-static int
-generic_open(struct inode * inode, struct file * file)
-{
-	TRACE();
-
-	/* FIXME: should check that they're not trying to open the ROM
-           writable */
-
-	return 0; /* success */
-}
-
-
-static int
-rom_mmap(struct file * file, struct vm_area_struct * vma)
-{
-	unsigned long pci_pa;
-	struct node_data * nd;
-
-	TRACE();
-
-	nd = (struct node_data * )file->private_data;
-
-	pci_pa = pci_resource_start(nd->u.rom.dev, PCI_ROM_RESOURCE);
-
-	if (!nd->u.rom.mmapped) {
-		nd->u.rom.mmapped = true;
-		DPRINTF("Enabling ROM address decoder.\n");
-		DPRINTF(
-"rom_mmap: FIXME: some cards do not allow both ROM and memory addresses to\n"
-"rom_mmap: FIXME: be enabled simultaneously, as they share a decoder.\n");
-		pci_read_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
-				      &nd->u.rom.saved_rom_base_reg);
-		DPRINTF("ROM base address contains %x\n",
-			nd->u.rom.saved_rom_base_reg);
-		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
-				       nd->u.rom.saved_rom_base_reg |
-				       PCI_ROM_ADDRESS_ENABLE);
-	}
-	
-	return mmap_pci_address(vma, pci_pa);
-}
-
-
-static int
-rom_release(struct inode * inode, struct file * file)
-{
-	struct node_data * nd;
-
-	TRACE();
-
-	nd = (struct node_data * )file->private_data;
-
-	if (nd->u.rom.mmapped) {
-		nd->u.rom.mmapped = false;
-		DPRINTF("Disabling ROM address decoder.\n");
-		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
-				       nd->u.rom.saved_rom_base_reg);
-	}
-	return 0; /* indicate success */
-}
-
-
-static int
-base_mmap(struct file * file, struct vm_area_struct * vma)
-{
-	struct resource * resource;
-
-	TRACE();
-
-	resource = (struct resource *)file->private_data;
-
-	return mmap_pci_address(vma, resource->start);
-}
-
-
-static int
-config_ioctl(struct inode * inode, struct file * file, 
-	     unsigned int cmd, 
-	     unsigned long arg)
-{
-	struct pci_dev * dev;
-
-	union cfg_data {
-		uint8_t byte;
-		uint16_t word;
-		uint32_t dword;
-	} read_data, write_data;
-
-	int dir, size, offset;
-
-	TRACE();
-
-	DPRINTF("cmd = %x (DIR = %x, TYPE = %x, NR = %x, SIZE = %x)\n", 
-		cmd, 
-		_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
-	DPRINTF("arg = %lx\n", arg);
-
-	dev = (struct pci_dev *)file->private_data;
-
-	/* PCIIOCCFG{RD,WR}: read and/or write PCI configuration
-	   space. If both, the read happens first (this becomes a swap
-	   operation, atomic with respect to other updates through
-	   this path).  */
-
-	dir = _IOC_DIR(cmd);
-
-#define do_swap(suffix, type)	 					\
-	do {								\
-		if (dir & _IOC_READ) {					\
-			pci_read_config_##suffix(dev, _IOC_NR(cmd), 	\
-						 &read_data.suffix);	\
-		}							\
-		if (dir & _IOC_WRITE) {					\
-			get_user(write_data.suffix, (type)arg);		\
-			pci_write_config_##suffix(dev, _IOC_NR(cmd), 	\
-						  write_data.suffix);	\
-		}							\
-		if (dir & _IOC_READ) {					\
-			put_user(read_data.suffix, (type)arg);		\
-		}							\
-	} while (0)
-
-	size = _IOC_SIZE(cmd);
-	offset = _IOC_NR(cmd);
-
-	DPRINTF("sanity check\n");
-	if (((size > 0) || (size <= 4)) &&
-	    ((offset + size) <= 256) &&
-	    (dir & (_IOC_READ | _IOC_WRITE))) {
-
-		switch (size)
-		{
-		case 1:
-			do_swap(byte, uint8_t *);
-			break;
-		case 2:
-			do_swap(word, uint16_t *);
-			break;
-		case 4:
-			do_swap(dword, uint32_t *);
-			break;
-		default:
-			DPRINTF("invalid ioctl\n");
-			return -EINVAL;
-		}
-	} else
-		return -EINVAL;
-		
-	return 0;
-}
-
-
-#ifdef DEBUG_PCIBA
-static void
-dump_allocations(struct list_head * dalp)
-{
-	struct dma_allocation * dap;
-	struct list_head * p;
-	
-	printk("{\n");
-	list_for_each(p, dalp) {
-		dap = list_entry(p, struct dma_allocation, 
-				 list);
-		printk("  handle = %lx, va = %p\n",
-		       dap->handle, dap->va);
-	}
-	printk("}\n");
-}
-
-static void
-dump_nodes(struct list_head * nodes)
-{
-	struct node_data * ndp;
-	struct list_head * p;
-	
-	printk("{\n");
-	list_for_each(p, nodes) {
-		ndp = list_entry(p, struct node_data, 
-				 global_node_list);
-		printk("  %p\n", (void *)ndp);
-	}
-	printk("}\n");
-}
-
-
-#if 0
-#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-
-static void
-test_list(void)
-{
-	u64 i;
-	LIST_HEAD(the_list);
-
-	for (i = 0; i < 5; i++) {
-		struct dma_allocation * new_alloc;
-		NEW(new_alloc);
-		new_alloc->va = (void *)i;
-		new_alloc->handle = 5*i;
-		printk("%d - the_list->next = %lx\n", i, the_list.next);
-		list_add(&new_alloc->list, &the_list);
-	}
-	dump_allocations(&the_list);
-}
-#endif
-#endif
-
-
-static LIST_HEAD(dma_buffer_list);
-
-
-static int
-dma_ioctl(struct inode * inode, struct file * file, 
-	  unsigned int cmd, 
-	  unsigned long arg)
-{
-	struct node_data * nd;
-	uint64_t argv;
-	int result;
-	struct dma_allocation * dma_alloc;
-	struct list_head * iterp;
-
-	TRACE();
-
-	DPRINTF("cmd = %x\n", cmd);
-	DPRINTF("arg = %lx\n", arg);
-
-	nd = (struct node_data *)file->private_data;
-
-#ifdef DEBUG_PCIBA
-	DPRINTF("at dma_ioctl entry\n");
-	dump_allocations(&nd->u.dma.dma_allocs);
-#endif
-
-	switch (cmd) {
-	case PCIIOCDMAALLOC:
-		/* PCIIOCDMAALLOC: allocate a chunk of physical memory
-		   and set it up for DMA. Return the PCI address that
-		   gets to it.  */
-		DPRINTF("case PCIIOCDMAALLOC (%lx)\n", PCIIOCDMAALLOC);
-		
-		if ( (result = get_user(argv, (uint64_t *)arg)) )
-			return result;
-		DPRINTF("argv (size of buffer) = %lx\n", argv);
-
-		dma_alloc = (struct dma_allocation *)
-			kmalloc(sizeof(struct dma_allocation), GFP_KERNEL);
-		if (dma_alloc == NULL)
-			return -ENOMEM;
-
-		dma_alloc->size = (size_t)argv;
-		dma_alloc->va = pci_alloc_consistent(nd->u.dma.dev,
-						     dma_alloc->size,
-						     &dma_alloc->handle);
-		DPRINTF("dma_alloc->va = %p, dma_alloc->handle = %lx\n",
-			dma_alloc->va, dma_alloc->handle);
-		if (dma_alloc->va == NULL) {
-			kfree(dma_alloc);
-			return -ENOMEM;
-		}
-
-		list_add(&dma_alloc->list, &nd->u.dma.dma_allocs);
-		if ( (result = put_user((uint64_t)dma_alloc->handle, 
-				      (uint64_t *)arg)) ) {
-			DPRINTF("put_user failed\n");
-			pci_free_consistent(nd->u.dma.dev, (size_t)argv,
-					    dma_alloc->va, dma_alloc->handle);
-			kfree(dma_alloc);
-			return result;
-		}
-
-#ifdef DEBUG_PCIBA
-		DPRINTF("after insertion\n");
-		dump_allocations(&nd->u.dma.dma_allocs);
-#endif
-		break;
-
-	case PCIIOCDMAFREE:
-		DPRINTF("case PCIIOCDMAFREE (%lx)\n", PCIIOCDMAFREE);
-
-		if ( (result = get_user(argv, (uint64_t *)arg)) ) {
-			DPRINTF("get_user failed\n");
-			return result;
-		}
-
-		DPRINTF("argv (physical address of DMA buffer) = %lx\n", argv);
-		list_for_each(iterp, &nd->u.dma.dma_allocs) {
-			struct dma_allocation * da =
-				list_entry(iterp, struct dma_allocation, list);
-			if (da->handle == argv) {
-				pci_free_consistent(nd->u.dma.dev, da->size,
-						    da->va, da->handle);
-				list_del(&da->list);
-				kfree(da);
-#ifdef DEBUG_PCIBA
-				DPRINTF("after deletion\n");
-				dump_allocations(&nd->u.dma.dma_allocs);
-#endif
-				return 0; /* success */
-			}
-		}
-		/* previously allocated dma buffer wasn't found */
-		DPRINTF("attempt to free invalid dma handle\n");
-		return -EINVAL;
-
-	default:
-		DPRINTF("undefined ioctl\n");
-		return -EINVAL;
-	}
-
-	DPRINTF("success\n");
-	return 0;
-}
-		
-
-static int
-dma_mmap(struct file * file, struct vm_area_struct * vma)
-{
-	struct node_data * nd;
-	struct list_head * iterp;
-	int result;
-	
-	TRACE();
-
-	nd = (struct node_data *)file->private_data;
-	
-	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
-	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
-	DPRINTF("offset = %lx\n", vma->vm_pgoff);
-
-	/* get kernel virtual address for the dma buffer (necessary
-	 * for the mmap). */
-	list_for_each(iterp, &nd->u.dma.dma_allocs) {
-		struct dma_allocation * da =
-			list_entry(iterp, struct dma_allocation, list);
-		/* why does mmap shift its offset argument? */
-		if (da->handle == vma->vm_pgoff << PAGE_SHIFT) {
-			DPRINTF("found dma handle\n");
-			if ( (result = mmap_kernel_address(vma,
-							   da->va)) ) {
-				return result; /* failure */
-			} else {
-				/* it seems like at least one of these
-				   should show up in user land....
-				   I'm missing something */
-				*(char *)da->va = 0xaa;
-				strncpy(da->va, "        Toastie!", da->size);
-				if (put_user(0x18badbeeful,
-					     (u64 *)vma->vm_start))
-					DPRINTF("put_user failed?!\n");
-				return 0; /* success */
-			}
-
-		}
-	}
-	DPRINTF("attempt to mmap an invalid dma handle\n");
-	return -EINVAL;
-}
-
-
-static int
-mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va)
-{
-	unsigned long pci_pa;
-
-	TRACE();
-
-	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
-	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
-
-	/* the size of the vma doesn't necessarily correspond to the
-           size specified in the mmap call.  So we can't really do any
-           kind of sanity check here.  This is a dangerous driver, and
-           it's very easy for a user process to kill the machine.  */
-
-	DPRINTF("PCI base at virtual address %lx\n", pci_va);
-	/* the __pa macro is intended for region 7 on IA64, so it
-	   doesn't work for region 6 */
-  	/* pci_pa = __pa(pci_va); */
-	/* should be replaced by __tpa or equivalent (preferably a
-	   generic equivalent) */
-	pci_pa = pci_va & ~0xe000000000000000ul;
-	DPRINTF("PCI base at physical address %lx\n", pci_pa);
-
-	/* there are various arch-specific versions of this function
-           defined in linux/drivers/char/mem.c, but it would be nice
-           if all architectures put it in pgtable.h.  it's defined
-           there for ia64.... */
-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
-
-	return io_remap_page_range(vma->vm_start, pci_pa, 
-				   vma->vm_end-vma->vm_start,
-				   vma->vm_page_prot);
-}
-
-
-static int
-mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va)
-{
-	unsigned long kernel_pa;
-
-	TRACE();
-
-	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
-	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
-
-	/* the size of the vma doesn't necessarily correspond to the
-           size specified in the mmap call.  So we can't really do any
-           kind of sanity check here.  This is a dangerous driver, and
-           it's very easy for a user process to kill the machine.  */
-
-	DPRINTF("mapping virtual address %p\n", kernel_va);
-	kernel_pa = __pa(kernel_va);
-	DPRINTF("mapping physical address %lx\n", kernel_pa);
-
-	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
-
-	return remap_page_range(vma->vm_start, kernel_pa, 
-				vma->vm_end-vma->vm_start,
-				vma->vm_page_prot);
-}	
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/pciio.c linux-2.4.22-pre10/arch/ia64/sn/io/pciio.c
--- linux-2.4.21/arch/ia64/sn/io/pciio.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/pciio.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1511 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#define	USRPCI	0
-
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/xtalk/xbow.h>	/* Must be before iograph.h to get MAX_PORT_NUM */
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/ioerror_handling.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pciio_private.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/simulator.h>
-
-#define DEBUG_PCIIO
-#undef DEBUG_PCIIO	/* turn this on for yet more console output */
-
-
-#define GET_NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DO_DEL(ptr)	(kfree(ptr))
-
-char                    pciio_info_fingerprint[] = "pciio_info";
-
-cdl_p                   pciio_registry = NULL;
-
-int
-badaddr_val(volatile void *addr, int len, volatile void *ptr)
-{
-	int ret = 0;
-	volatile void *new_addr;
-
-	switch (len) {
-		case 4:
-#ifdef CONFIG_IA64_SGI_SN1
-			new_addr = (void *)(((u64) addr)^4);
-#else
-			new_addr = (void *) addr;
-#endif
-			ret = ia64_sn_probe_io_slot((long)new_addr, len, (void *)ptr);
-			break;
-		default:
-			printk(KERN_WARNING "badaddr_val given len %x but supports len of 4 only\n", len);
-	}
-
-	if (ret < 0)
-		panic("badaddr_val: unexpected status (%d) in probing", ret);
-	return(ret);
-
-}
-
-
-nasid_t
-get_console_nasid(void)
-{
-	extern nasid_t console_nasid;
-	if (console_nasid < 0) {
-		console_nasid = ia64_sn_get_console_nasid();
-		if (console_nasid < 0) {
-// ZZZ What do we do if we don't get a console nasid on the hardware????
-			if (IS_RUNNING_ON_SIMULATOR() )
-				console_nasid = master_nasid;
-		}
-	} 
-	return console_nasid;
-}
-
-int
-hub_dma_enabled(devfs_handle_t xconn_vhdl)
-{
-	return(0);
-}
-
-int
-hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
-{
-	return(0);
-}
-
-void
-ioerror_dump(char *name, int error_code, int error_mode, ioerror_t *ioerror)
-{
-}
-
-/******
- ****** end hack defines ......
- ******/
-
-
-
-
-/* =====================================================================
- *    PCI Generic Bus Provider
- * Implement PCI provider operations.  The pciio* layer provides a
- * platform-independent interface for PCI devices.  This layer
- * switches among the possible implementations of a PCI adapter.
- */
-
-/* =====================================================================
- *    Provider Function Location SHORTCUT
- *
- * On platforms with only one possible PCI provider, macros can be
- * set up at the top that cause the table lookups and indirections to
- * completely disappear.
- */
-
-#if defined(CONFIG_IA64_SGI_SN1)
-/*
- *    For the moment, we will assume that IP27
- *      only use Bridge ASICs to provide PCI support.
- */
-#include <asm/sn/pci/pcibr.h>
-#define DEV_FUNC(dev,func)	pcibr_##func
-#define CAST_PIOMAP(x)		((pcibr_piomap_t)(x))
-#define CAST_DMAMAP(x)		((pcibr_dmamap_t)(x))
-#define CAST_INTR(x)		((pcibr_intr_t)(x))
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-/* =====================================================================
- *    Function Table of Contents
- */
-
-#if !defined(DEV_FUNC)
-static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev);
-#endif
-
-pciio_piomap_t          pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
-void                    pciio_piomap_free(pciio_piomap_t);
-caddr_t                 pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t);
-
-void                    pciio_piomap_done(pciio_piomap_t);
-caddr_t                 pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-caddr_t			pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned);
-
-iopaddr_t               pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
-
-pciio_dmamap_t          pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    pciio_dmamap_free(pciio_dmamap_t);
-iopaddr_t               pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
-alenlist_t              pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned);
-void                    pciio_dmamap_done(pciio_dmamap_t);
-iopaddr_t               pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void			pciio_dmamap_drain(pciio_dmamap_t);
-void			pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void			pciio_dmalist_drain(devfs_handle_t, alenlist_t);
-iopaddr_t               pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned);
-
-pciio_intr_t            pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
-void                    pciio_intr_free(pciio_intr_t);
-int                     pciio_intr_connect(pciio_intr_t);
-void                    pciio_intr_disconnect(pciio_intr_t);
-devfs_handle_t            pciio_intr_cpu_get(pciio_intr_t);
-
-void			pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t);
-
-void                    pciio_provider_startup(devfs_handle_t);
-void                    pciio_provider_shutdown(devfs_handle_t);
-
-pciio_endian_t          pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
-pciio_priority_t        pciio_priority_set(devfs_handle_t, pciio_priority_t);
-devfs_handle_t            pciio_intr_dev_get(pciio_intr_t);
-
-devfs_handle_t            pciio_pio_dev_get(pciio_piomap_t);
-pciio_slot_t            pciio_pio_slot_get(pciio_piomap_t);
-pciio_space_t           pciio_pio_space_get(pciio_piomap_t);
-iopaddr_t               pciio_pio_pciaddr_get(pciio_piomap_t);
-ulong                   pciio_pio_mapsz_get(pciio_piomap_t);
-caddr_t                 pciio_pio_kvaddr_get(pciio_piomap_t);
-
-devfs_handle_t            pciio_dma_dev_get(pciio_dmamap_t);
-pciio_slot_t            pciio_dma_slot_get(pciio_dmamap_t);
-
-pciio_info_t            pciio_info_chk(devfs_handle_t);
-pciio_info_t            pciio_info_get(devfs_handle_t);
-void                    pciio_info_set(devfs_handle_t, pciio_info_t);
-devfs_handle_t            pciio_info_dev_get(pciio_info_t);
-pciio_slot_t            pciio_info_slot_get(pciio_info_t);
-pciio_function_t        pciio_info_function_get(pciio_info_t);
-pciio_vendor_id_t       pciio_info_vendor_id_get(pciio_info_t);
-pciio_device_id_t       pciio_info_device_id_get(pciio_info_t);
-devfs_handle_t            pciio_info_master_get(pciio_info_t);
-arbitrary_info_t        pciio_info_mfast_get(pciio_info_t);
-pciio_provider_t       *pciio_info_pops_get(pciio_info_t);
-error_handler_f	       *pciio_info_efunc_get(pciio_info_t);
-error_handler_arg_t    *pciio_info_einfo_get(pciio_info_t);
-pciio_space_t		pciio_info_bar_space_get(pciio_info_t, int);
-iopaddr_t		pciio_info_bar_base_get(pciio_info_t, int);
-size_t			pciio_info_bar_size_get(pciio_info_t, int);
-iopaddr_t		pciio_info_rom_base_get(pciio_info_t);
-size_t			pciio_info_rom_size_get(pciio_info_t);
-
-void                    pciio_init(void);
-int                     pciio_attach(devfs_handle_t);
-
-void                    pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns);
-void                    pciio_provider_unregister(devfs_handle_t);
-pciio_provider_t       *pciio_provider_fns_get(devfs_handle_t);
-
-int                     pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned);
-void                    pciio_driver_unregister(char *driver_prefix);
-
-devfs_handle_t            pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-
-void			pciio_device_unregister(devfs_handle_t);
-pciio_info_t		pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-void			pciio_device_info_free(pciio_info_t);
-devfs_handle_t		pciio_device_info_register(devfs_handle_t, pciio_info_t);
-void			pciio_device_info_unregister(devfs_handle_t, pciio_info_t);
-int                     pciio_device_attach(devfs_handle_t, int);
-int			pciio_device_detach(devfs_handle_t, int);
-void                    pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t);
-
-int                     pciio_reset(devfs_handle_t);
-int                     pciio_write_gather_flush(devfs_handle_t);
-int                     pciio_slot_inuse(devfs_handle_t);
-
-/* =====================================================================
- *    Provider Function Location
- *
- *      If there is more than one possible provider for
- *      this platform, we need to examine the master
- *      vertex of the current vertex for a provider
- *      function structure, and indirect through the
- *      appropriately named member.
- */
-
-#if !defined(DEV_FUNC)
-
-static pciio_provider_t *
-pciio_to_provider_fns(devfs_handle_t dev)
-{
-    pciio_info_t            card_info;
-    pciio_provider_t       *provider_fns;
-
-    /*
-     * We're called with two types of vertices, one is
-     * the bridge vertex (ends with "pci") and the other is the
-     * pci slot vertex (ends with "pci/[0-8]").  For the first type
-     * we need to get the provider from the PFUNCS label.  For
-     * the second we get it from fastinfo/c_pops.
-     */
-    provider_fns = pciio_provider_fns_get(dev);
-    if (provider_fns == NULL) {
-	card_info = pciio_info_get(dev);
-	if (card_info != NULL) {
-		provider_fns = pciio_info_pops_get(card_info);
-	}
-    }
-
-    if (provider_fns == NULL)
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	PRINT_PANIC("%v: provider_fns == NULL", dev);
-#else
-	PRINT_PANIC("0x%p: provider_fns == NULL", (void *)dev);
-#endif
-
-    return provider_fns;
-
-}
-
-#define DEV_FUNC(dev,func)	pciio_to_provider_fns(dev)->func
-#define CAST_PIOMAP(x)		((pciio_piomap_t)(x))
-#define CAST_DMAMAP(x)		((pciio_dmamap_t)(x))
-#define CAST_INTR(x)		((pciio_intr_t)(x))
-#endif
-
-/*
- * Many functions are not passed their vertex
- * information directly; rather, they must
- * dive through a resource map. These macros
- * are available to coordinate this detail.
- */
-#define PIOMAP_FUNC(map,func)		DEV_FUNC((map)->pp_dev,func)
-#define DMAMAP_FUNC(map,func)		DEV_FUNC((map)->pd_dev,func)
-#define INTR_FUNC(intr_hdl,func)	DEV_FUNC((intr_hdl)->pi_dev,func)
-
-/* =====================================================================
- *          PIO MANAGEMENT
- *
- *      For mapping system virtual address space to
- *      pciio space on a specified card
- */
-
-pciio_piomap_t
-pciio_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-		   iopaddr_t addr,	/* lowest address (or offset in window) */
-		   size_t byte_count,	/* size of region containing our mappings */
-		   size_t byte_count_max,	/* maximum size of a mapping */
-		   unsigned flags)
-{					/* defined in sys/pio.h */
-    return (pciio_piomap_t) DEV_FUNC(dev, piomap_alloc)
-	(dev, dev_desc, space, addr, byte_count, byte_count_max, flags);
-}
-
-void
-pciio_piomap_free(pciio_piomap_t pciio_piomap)
-{
-    PIOMAP_FUNC(pciio_piomap, piomap_free)
-	(CAST_PIOMAP(pciio_piomap));
-}
-
-caddr_t
-pciio_piomap_addr(pciio_piomap_t pciio_piomap,	/* mapping resources */
-		  iopaddr_t pciio_addr,	/* map for this pciio address */
-		  size_t byte_count)
-{					/* map this many bytes */
-    pciio_piomap->pp_kvaddr = PIOMAP_FUNC(pciio_piomap, piomap_addr)
-	(CAST_PIOMAP(pciio_piomap), pciio_addr, byte_count);
-
-    return pciio_piomap->pp_kvaddr;
-}
-
-void
-pciio_piomap_done(pciio_piomap_t pciio_piomap)
-{
-    PIOMAP_FUNC(pciio_piomap, piomap_done)
-	(CAST_PIOMAP(pciio_piomap));
-}
-
-caddr_t
-pciio_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-		    iopaddr_t addr,	/* starting address (or offset in window) */
-		    size_t byte_count,	/* map this many bytes */
-		    unsigned flags)
-{					/* (currently unused) */
-    return DEV_FUNC(dev, piotrans_addr)
-	(dev, dev_desc, space, addr, byte_count, flags);
-}
-
-caddr_t
-pciio_pio_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-	       iopaddr_t addr,		/* starting address (or offset in window) */
-	       size_t byte_count,	/* map this many bytes */
-	       pciio_piomap_t *mapp,	/* where to return the map pointer */
-	       unsigned flags)
-{					/* PIO flags */
-    pciio_piomap_t          map = 0;
-    int			    errfree = 0;
-    caddr_t                 res;
-
-    if (mapp) {
-	map = *mapp;			/* possible pre-allocated map */
-	*mapp = 0;			/* record "no map used" */
-    }
-
-    res = pciio_piotrans_addr
-	(dev, dev_desc, space, addr, byte_count, flags);
-    if (res)
-	return res;			/* pciio_piotrans worked */
-
-    if (!map) {
-	map = pciio_piomap_alloc
-	    (dev, dev_desc, space, addr, byte_count, byte_count, flags);
-	if (!map)
-	    return res;			/* pciio_piomap_alloc failed */
-	errfree = 1;
-    }
-
-    res = pciio_piomap_addr
-	(map, addr, byte_count);
-    if (!res) {
-	if (errfree)
-	    pciio_piomap_free(map);
-	return res;			/* pciio_piomap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* pciio_piomap_addr succeeded */
-}
-
-iopaddr_t
-pciio_piospace_alloc(devfs_handle_t dev,	/* Device requiring space */
-		     device_desc_t dev_desc,	/* Device descriptor */
-		     pciio_space_t space,	/* MEM32/MEM64/IO */
-		     size_t byte_count,	/* Size of mapping */
-		     size_t align)
-{					/* Alignment needed */
-    if (align < NBPP)
-	align = NBPP;
-    return DEV_FUNC(dev, piospace_alloc)
-	(dev, dev_desc, space, byte_count, align);
-}
-
-void
-pciio_piospace_free(devfs_handle_t dev,	/* Device freeing space */
-		    pciio_space_t space,	/* Type of space        */
-		    iopaddr_t pciaddr,	/* starting address */
-		    size_t byte_count)
-{					/* Range of address   */
-    DEV_FUNC(dev, piospace_free)
-	(dev, space, pciaddr, byte_count);
-}
-
-/* =====================================================================
- *          DMA MANAGEMENT
- *
- *      For mapping from pci space to system
- *      physical space.
- */
-
-pciio_dmamap_t
-pciio_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   size_t byte_count_max,	/* max size of a mapping */
-		   unsigned flags)
-{					/* defined in dma.h */
-    return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-	(dev, dev_desc, byte_count_max, flags);
-}
-
-void
-pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_free)
-	(CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
-		  paddr_t paddr,	/* map for this address */
-		  size_t byte_count)
-{					/* map this many bytes */
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_addr)
-	(CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
-}
-
-alenlist_t
-pciio_dmamap_list(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
-		  alenlist_t alenlist,	/* map this Address/Length List */
-		  unsigned flags)
-{
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_list)
-	(CAST_DMAMAP(pciio_dmamap), alenlist, flags);
-}
-
-void
-pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_done)
-	(CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-pciio_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    paddr_t paddr,	/* system physical address */
-		    size_t byte_count,	/* length */
-		    unsigned flags)
-{					/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_addr)
-	(dev, dev_desc, paddr, byte_count, flags);
-}
-
-alenlist_t
-pciio_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    alenlist_t palenlist,	/* system address/length list */
-		    unsigned flags)
-{					/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-	(dev, dev_desc, palenlist, flags);
-}
-
-iopaddr_t
-pciio_dma_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       paddr_t paddr,		/* system physical address */
-	       size_t byte_count,	/* length */
-	       pciio_dmamap_t *mapp,	/* map to use, then map we used */
-	       unsigned flags)
-{					/* PIO flags */
-    pciio_dmamap_t          map = 0;
-    int			    errfree = 0;
-    iopaddr_t               res;
-
-    if (mapp) {
-	map = *mapp;			/* possible pre-allocated map */
-	*mapp = 0;			/* record "no map used" */
-    }
-
-    res = pciio_dmatrans_addr
-	(dev, dev_desc, paddr, byte_count, flags);
-    if (res)
-	return res;			/* pciio_dmatrans worked */
-
-    if (!map) {
-	map = pciio_dmamap_alloc
-	    (dev, dev_desc, byte_count, flags);
-	if (!map)
-	    return res;			/* pciio_dmamap_alloc failed */
-	errfree = 1;
-    }
-
-    res = pciio_dmamap_addr
-	(map, paddr, byte_count);
-    if (!res) {
-	if (errfree)
-	    pciio_dmamap_free(map);
-	return res;			/* pciio_dmamap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* pciio_dmamap_addr succeeded */
-}
-
-void
-pciio_dmamap_drain(pciio_dmamap_t map)
-{
-    DMAMAP_FUNC(map, dmamap_drain)
-	(CAST_DMAMAP(map));
-}
-
-void
-pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
-{
-    DEV_FUNC(dev, dmaaddr_drain)
-	(dev, addr, size);
-}
-
-void
-pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list)
-{
-    DEV_FUNC(dev, dmalist_drain)
-	(dev, list);
-}
-
-/* =====================================================================
- *          INTERRUPT MANAGEMENT
- *
- *      Allow crosstalk devices to establish interrupts
- */
-
-/*
- * Allocate resources required for an interrupt as specified in intr_desc.
- * Return resource handle in intr_hdl.
- */
-pciio_intr_t
-pciio_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
-		 device_desc_t dev_desc,	/* device descriptor */
-		 pciio_intr_line_t lines,	/* INTR line(s) to attach */
-		 devfs_handle_t owner_dev)
-{					/* owner of this interrupt */
-    return (pciio_intr_t) DEV_FUNC(dev, intr_alloc)
-	(dev, dev_desc, lines, owner_dev);
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-pciio_intr_free(pciio_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_free)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Associate resources allocated with a previous pciio_intr_alloc call with the
- * described handler, arg, name, etc.
- *
- * Returns 0 on success, returns <0 on failure.
- */
-int
-pciio_intr_connect(pciio_intr_t intr_hdl)	/* pciio intr resource handle */
-{
-    return INTR_FUNC(intr_hdl, intr_connect)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-pciio_intr_disconnect(pciio_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_disconnect)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-pciio_intr_cpu_get(pciio_intr_t intr_hdl)
-{
-    return INTR_FUNC(intr_hdl, intr_cpu_get)
-	(CAST_INTR(intr_hdl));
-}
-
-void
-pciio_slot_func_to_name(char		       *name,
-			pciio_slot_t		slot,
-			pciio_function_t	func)
-{
-    /*
-     * standard connection points:
-     *
-     * PCIIO_SLOT_NONE:	.../pci/direct
-     * PCIIO_FUNC_NONE: .../pci/<SLOT>			ie. .../pci/3
-     * multifunction:   .../pci/<SLOT><FUNC>		ie. .../pci/3c
-     */
-
-    if (slot == PCIIO_SLOT_NONE)
-	sprintf(name, "direct");
-    else if (func == PCIIO_FUNC_NONE)
-	sprintf(name, "%d", slot);
-    else
-	sprintf(name, "%d%c", slot, 'a'+func);
-}
-
-/* =====================================================================
- *          CONFIGURATION MANAGEMENT
- */
-
-/*
- * Startup a crosstalk provider
- */
-void
-pciio_provider_startup(devfs_handle_t pciio_provider)
-{
-    DEV_FUNC(pciio_provider, provider_startup)
-	(pciio_provider);
-}
-
-/*
- * Shutdown a crosstalk provider
- */
-void
-pciio_provider_shutdown(devfs_handle_t pciio_provider)
-{
-    DEV_FUNC(pciio_provider, provider_shutdown)
-	(pciio_provider);
-}
-
-/*
- * Specify endianness constraints.  The driver tells us what the device
- * does and how it would like to see things in memory.  We reply with
- * how things will actually appear in memory.
- */
-pciio_endian_t
-pciio_endian_set(devfs_handle_t dev,
-		 pciio_endian_t device_end,
-		 pciio_endian_t desired_end)
-{
-    ASSERT((device_end == PCIDMA_ENDIAN_BIG) || (device_end == PCIDMA_ENDIAN_LITTLE));
-    ASSERT((desired_end == PCIDMA_ENDIAN_BIG) || (desired_end == PCIDMA_ENDIAN_LITTLE));
-
-#if DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    printk(KERN_ALERT  "%v: pciio_endian_set is going away.\n"
-	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
-	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
-	    dev);
-#else
-    printk(KERN_ALERT  "0x%x: pciio_endian_set is going away.\n"
-	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
-	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
-	    dev);
-#endif
-#endif
-
-    return DEV_FUNC(dev, endian_set)
-	(dev, device_end, desired_end);
-}
-
-/*
- * Specify PCI arbitration priority.
- */
-pciio_priority_t
-pciio_priority_set(devfs_handle_t dev,
-		   pciio_priority_t device_prio)
-{
-    ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW));
-
-    return DEV_FUNC(dev, priority_set)
-	(dev, device_prio);
-}
-
-/*
- * Read value of configuration register
- */
-uint64_t
-pciio_config_get(devfs_handle_t	dev,
-		 unsigned	reg,
-		 unsigned	size)
-{
-    uint64_t	value = 0;
-    unsigned	shift = 0;
-
-    /* handle accesses that cross words here,
-     * since that's common code between all
-     * possible providers.
-     */
-    while (size > 0) {
-	unsigned	biw = 4 - (reg&3);
-	if (biw > size)
-	    biw = size;
-
-	value |= DEV_FUNC(dev, config_get)
-	    (dev, reg, biw) << shift;
-
-	shift += 8*biw;
-	reg += biw;
-	size -= biw;
-    }
-    return value;
-}
-
-/*
- * Change value of configuration register
- */
-void
-pciio_config_set(devfs_handle_t	dev,
-		 unsigned	reg,
-		 unsigned	size,
-		 uint64_t	value)
-{
-    /* handle accesses that cross words here,
-     * since that's common code between all
-     * possible providers.
-     */
-    while (size > 0) {
-	unsigned	biw = 4 - (reg&3);
-	if (biw > size)
-	    biw = size;
-	    
-	DEV_FUNC(dev, config_set)
-	    (dev, reg, biw, value);
-	reg += biw;
-	size -= biw;
-	value >>= biw * 8;
-    }
-}
-
-/* =====================================================================
- *          GENERIC PCI SUPPORT FUNCTIONS
- */
-
-/*
- * Issue a hardware reset to a card.
- */
-int
-pciio_reset(devfs_handle_t dev)
-{
-    return DEV_FUNC(dev, reset) (dev);
-}
-
-/*
- * flush write gather buffers
- */
-int
-pciio_write_gather_flush(devfs_handle_t dev)
-{
-    return DEV_FUNC(dev, write_gather_flush) (dev);
-}
-
-devfs_handle_t
-pciio_intr_dev_get(pciio_intr_t pciio_intr)
-{
-    return (pciio_intr->pi_dev);
-}
-
-/****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
-pciio_pio_dev_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_dev);
-}
-
-pciio_slot_t
-pciio_pio_slot_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_slot);
-}
-
-pciio_space_t
-pciio_pio_space_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_space);
-}
-
-iopaddr_t
-pciio_pio_pciaddr_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_pciaddr);
-}
-
-ulong
-pciio_pio_mapsz_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_mapsz);
-}
-
-caddr_t
-pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_kvaddr);
-}
-
-/****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
-pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap)
-{
-    return (pciio_dmamap->pd_dev);
-}
-
-pciio_slot_t
-pciio_dma_slot_get(pciio_dmamap_t pciio_dmamap)
-{
-    return (pciio_dmamap->pd_slot);
-}
-
-/****** Generic pci slot information interfaces ******/
-
-pciio_info_t
-pciio_info_chk(devfs_handle_t pciio)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    hwgraph_info_get_LBL(pciio, INFO_LBL_PCIIO, &ainfo);
-    return (pciio_info_t) ainfo;
-}
-
-pciio_info_t
-pciio_info_get(devfs_handle_t pciio)
-{
-    pciio_info_t            pciio_info;
-
-    pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio);
-
-#ifdef DEBUG_PCIIO
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(pciio, dname, 256);
-	printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-    }
-#endif /* DEBUG_PCIIO */
-
-    if ((pciio_info != NULL) &&
-	(pciio_info->c_fingerprint != pciio_info_fingerprint)
-	&& (pciio_info->c_fingerprint != NULL)) {
-
-	return((pciio_info_t)-1); /* Should panic .. */
-    }
-	
-
-    return pciio_info;
-}
-
-void
-pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info)
-{
-    if (pciio_info != NULL)
-	pciio_info->c_fingerprint = pciio_info_fingerprint;
-    hwgraph_fastinfo_set(pciio, (arbitrary_info_t) pciio_info);
-
-    /* Also, mark this vertex as a PCI slot
-     * and use the pciio_info, so pciio_info_chk
-     * can work (and be fairly efficient).
-     */
-    hwgraph_info_add_LBL(pciio, INFO_LBL_PCIIO,
-			 (arbitrary_info_t) pciio_info);
-}
-
-devfs_handle_t
-pciio_info_dev_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_vertex);
-}
-
-/*ARGSUSED*/
-pciio_bus_t
-pciio_info_bus_get(pciio_info_t pciio_info)
-{
-    /* XXX for now O2 always gets back bus 0 */
-    return (pciio_bus_t)0;
-}
-
-pciio_slot_t
-pciio_info_slot_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_slot);
-}
-
-pciio_function_t
-pciio_info_function_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_func);
-}
-
-pciio_vendor_id_t
-pciio_info_vendor_id_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_vendor);
-}
-
-pciio_device_id_t
-pciio_info_device_id_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_device);
-}
-
-devfs_handle_t
-pciio_info_master_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_master);
-}
-
-arbitrary_info_t
-pciio_info_mfast_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_mfast);
-}
-
-pciio_provider_t       *
-pciio_info_pops_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_pops);
-}
-
-error_handler_f	       *
-pciio_info_efunc_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_efunc);
-}
-
-error_handler_arg_t    *
-pciio_info_einfo_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_einfo);
-}
-
-pciio_space_t
-pciio_info_bar_space_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_space;
-}
-
-iopaddr_t
-pciio_info_bar_base_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_base;
-}
-
-size_t
-pciio_info_bar_size_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_size;
-}
-
-iopaddr_t
-pciio_info_rom_base_get(pciio_info_t info)
-{
-    return info->c_rbase;
-}
-
-size_t
-pciio_info_rom_size_get(pciio_info_t info)
-{
-    return info->c_rsize;
-}
-
-
-/* =====================================================================
- *          GENERIC PCI INITIALIZATION FUNCTIONS
- */
-
-/*
- *    pciioinit: called once during device driver
- *      initializtion if this driver is configured into
- *      the system.
- */
-void
-pciio_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("pciio_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (pciio_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_PCI, "vendor", "device");
-	if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(pciio_registry != NULL);
-}
-
-/*
- *    pciioattach: called for each vertex in the graph
- *      that is a PCI provider.
- */
-/*ARGSUSED */
-int
-pciio_attach(devfs_handle_t pciio)
-{
-#if DEBUG && ATTACH_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    printk("%v: pciio_attach\n", pciio);
-#else
-    printk("0x%x: pciio_attach\n", pciio);
-#endif
-#endif
-    return 0;
-}
-
-/*
- * Associate a set of pciio_provider functions with a vertex.
- */
-void
-pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns)
-{
-    hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns);
-}
-
-/*
- * Disassociate a set of pciio_provider functions with a vertex.
- */
-void
-pciio_provider_unregister(devfs_handle_t provider)
-{
-    arbitrary_info_t        ainfo;
-
-    hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, (long *) &ainfo);
-}
-
-/*
- * Obtain a pointer to the pciio_provider functions for a specified Crosstalk
- * provider.
- */
-pciio_provider_t       *
-pciio_provider_fns_get(devfs_handle_t provider)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    (void) hwgraph_info_get_LBL(provider, INFO_LBL_PFUNCS, &ainfo);
-    return (pciio_provider_t *) ainfo;
-}
-
-/*ARGSUSED4 */
-int
-pciio_driver_register(
-			 pciio_vendor_id_t vendor_id,
-			 pciio_device_id_t device_id,
-			 char *driver_prefix,
-			 unsigned flags)
-{
-    /* a driver's init routine might call
-     * pciio_driver_register before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    return cdl_add_driver(pciio_registry,
-			  vendor_id, device_id,
-			  driver_prefix, flags, NULL);
-}
-
-/*
- * Remove an initialization function.
- */
-void
-pciio_driver_unregister(
-			   char *driver_prefix)
-{
-    /* before a driver calls unregister,
-     * it must have called register; so
-     * we can assume we have a registry here.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    cdl_del_driver(pciio_registry, driver_prefix, NULL);
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being registered.
- */
-void
-pciio_driver_reg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being unregistered.
- */
-void
-pciio_driver_unreg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/*
- * Call some function with each vertex that
- * might be one of this driver's attach points.
- */
-void
-pciio_iterate(char *driver_prefix,
-	      pciio_iter_f * func)
-{
-    /* a driver's init routine might call
-     * pciio_iterate before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    ASSERT(pciio_registry != NULL);
-
-    cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func);
-}
-
-devfs_handle_t
-pciio_device_register(
-		devfs_handle_t connectpt,	/* vertex for /hw/.../pciio/%d */
-		devfs_handle_t master,	/* card's master ASIC (PCI provider) */
-		pciio_slot_t slot,	/* card's slot */
-		pciio_function_t func,	/* card's func */
-		pciio_vendor_id_t vendor_id,
-		pciio_device_id_t device_id)
-{
-    return pciio_device_info_register
-	(connectpt, pciio_device_info_new (NULL, master, slot, func,
-					   vendor_id, device_id));
-}
-
-void
-pciio_device_unregister(devfs_handle_t pconn)
-{
-    DEV_FUNC(pconn,device_unregister)(pconn);
-}
-
-pciio_info_t
-pciio_device_info_new(
-		pciio_info_t pciio_info,
-		devfs_handle_t master,
-		pciio_slot_t slot,
-		pciio_function_t func,
-		pciio_vendor_id_t vendor_id,
-		pciio_device_id_t device_id)
-{
-    if (!pciio_info)
-	GET_NEW(pciio_info);
-    ASSERT(pciio_info != NULL);
-
-    pciio_info->c_slot = slot;
-    pciio_info->c_func = func;
-    pciio_info->c_vendor = vendor_id;
-    pciio_info->c_device = device_id;
-    pciio_info->c_master = master;
-    pciio_info->c_mfast = hwgraph_fastinfo_get(master);
-    pciio_info->c_pops = pciio_provider_fns_get(master);
-    pciio_info->c_efunc = 0;
-    pciio_info->c_einfo = 0;
-
-    return pciio_info;
-}
-
-void
-pciio_device_info_free(pciio_info_t pciio_info)
-{
-    /* NOTE : pciio_info is a structure within the pcibr_info
-     *	      and not a pointer to memory allocated on the heap !!
-     */
-    BZERO((char *)pciio_info,sizeof(pciio_info));
-}
-
-devfs_handle_t
-pciio_device_info_register(
-		devfs_handle_t connectpt,		/* vertex at center of bus */
-		pciio_info_t pciio_info)	/* details about the connectpt */
-{
-    char		name[32];
-    devfs_handle_t	pconn;
-    int device_master_set(devfs_handle_t, devfs_handle_t);
-
-    pciio_slot_func_to_name(name,
-			    pciio_info->c_slot,
-			    pciio_info->c_func);
-
-    if (GRAPH_SUCCESS !=
-	hwgraph_path_add(connectpt, name, &pconn))
-	return pconn;
-
-    pciio_info->c_vertex = pconn;
-    pciio_info_set(pconn, pciio_info);
-#ifdef DEBUG_PCIIO
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(pconn, dname, 256);
-	printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);
-    }
-#endif /* DEBUG_PCIIO */
-
-    /*
-     * create link to our pci provider
-     */
-
-    device_master_set(pconn, pciio_info->c_master);
-
-#if USRPCI
-    /*
-     * Call into usrpci provider to let it initialize for
-     * the given slot.
-     */
-    if (pciio_info->c_slot != PCIIO_SLOT_NONE)
-	usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot);
-#endif
-
-    return pconn;
-}
-
-void
-pciio_device_info_unregister(devfs_handle_t connectpt,
-			     pciio_info_t pciio_info)
-{
-    char		name[32];
-    devfs_handle_t	pconn;
-
-    if (!pciio_info)
-	return;
-
-    pciio_slot_func_to_name(name,
-			    pciio_info->c_slot,
-			    pciio_info->c_func);
-
-    hwgraph_edge_remove(connectpt,name,&pconn);
-    pciio_info_set(pconn,0);
-
-    /* Remove the link to our pci provider */
-    hwgraph_edge_remove(pconn, EDGE_LBL_MASTER, NULL);
-
-
-    hwgraph_vertex_unref(pconn);
-    hwgraph_vertex_destroy(pconn);
-    
-}
-/* Add the pci card inventory information to the hwgraph
- */
-static void
-pciio_device_inventory_add(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
-
-    ASSERT(pciio_info);
-    ASSERT(pciio_info->c_vertex == pconn_vhdl);
-
-    /* Donot add inventory  for non-existent devices */
-    if ((pciio_info->c_vendor == PCIIO_VENDOR_ID_NONE)	||
-	(pciio_info->c_device == PCIIO_DEVICE_ID_NONE))
-	return;
-    device_inventory_add(pconn_vhdl,INV_IOBD,INV_PCIADAP,
-			 pciio_info->c_vendor,pciio_info->c_device,
-			 pciio_info->c_slot);
-}
-
-static void
-pciio_device_inventory_remove(devfs_handle_t pconn_vhdl)
-{
-#ifdef LATER
-    hwgraph_inventory_remove(pconn_vhdl,-1,-1,-1,-1,-1);
-#endif
-}
-
-/*ARGSUSED */
-int
-pciio_device_attach(devfs_handle_t pconn,
-		    int          drv_flags)
-{
-    pciio_info_t            pciio_info;
-    pciio_vendor_id_t       vendor_id;
-    pciio_device_id_t       device_id;
-
-
-    pciio_device_inventory_add(pconn);
-    pciio_info = pciio_info_get(pconn);
-
-    vendor_id = pciio_info->c_vendor;
-    device_id = pciio_info->c_device;
-
-    /* we don't start attaching things until
-     * all the driver init routines (including
-     * pciio_init) have been called; so we
-     * can assume here that we have a registry.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags));
-}
-
-int
-pciio_device_detach(devfs_handle_t pconn,
-		    int          drv_flags)
-{
-    pciio_info_t            pciio_info;
-    pciio_vendor_id_t       vendor_id;
-    pciio_device_id_t       device_id;
-
-    pciio_device_inventory_remove(pconn);
-    pciio_info = pciio_info_get(pconn);
-
-    vendor_id = pciio_info->c_vendor;
-    device_id = pciio_info->c_device;
-
-    /* we don't start attaching things until
-     * all the driver init routines (including
-     * pciio_init) have been called; so we
-     * can assume here that we have a registry.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    return(cdl_del_connpt(pciio_registry, vendor_id, device_id,
-		          pconn, drv_flags));
-
-}
-
-/*
- * pciio_error_register:
- * arrange for a function to be called with
- * a specified first parameter plus other
- * information when an error is encountered
- * and traced to the pci slot corresponding
- * to the connection point pconn.
- *
- * may also be called with a null function
- * pointer to "unregister" the error handler.
- *
- * NOTE: subsequent calls silently overwrite
- * previous data for this vertex. We assume that
- * cooperating drivers, well, cooperate ...
- */
-void
-pciio_error_register(devfs_handle_t pconn,
-		     error_handler_f *efunc,
-		     error_handler_arg_t einfo)
-{
-    pciio_info_t            pciio_info;
-
-    pciio_info = pciio_info_get(pconn);
-    ASSERT(pciio_info != NULL);
-    pciio_info->c_efunc = efunc;
-    pciio_info->c_einfo = einfo;
-}
-
-/*
- * Check if any device has been found in this slot, and return
- * true or false
- * vhdl is the vertex for the slot
- */
-int
-pciio_slot_inuse(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-
-    ASSERT(pciio_info);
-    ASSERT(pciio_info->c_vertex == pconn_vhdl);
-    if (pciio_info->c_vendor) {
-	/*
-	 * Non-zero value for vendor indicate
-	 * a board being found in this slot.
-	 */
-	return 1;
-    }
-    return 0;
-}
-
-int
-pciio_dma_enabled(devfs_handle_t pconn_vhdl)
-{
-	return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl);
-}
-
-/*
- * These are complementary Linux interfaces that takes in a pci_dev * as the 
- * first arguement instead of devfs_handle_t.
- */
-iopaddr_t               snia_pciio_dmatrans_addr(struct pci_dev *, device_desc_t, paddr_t, size_t, unsigned);
-pciio_dmamap_t          snia_pciio_dmamap_alloc(struct pci_dev *, device_desc_t, size_t, unsigned);
-void                    snia_pciio_dmamap_free(pciio_dmamap_t);
-iopaddr_t               snia_pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
-void                    snia_pciio_dmamap_done(pciio_dmamap_t);
-pciio_endian_t          snia_pciio_endian_set(struct pci_dev *pci_dev, pciio_endian_t device_end,
-					      pciio_endian_t desired_end);
-
-#include <linux/module.h>
-EXPORT_SYMBOL(snia_pciio_dmatrans_addr);
-EXPORT_SYMBOL(snia_pciio_dmamap_alloc);
-EXPORT_SYMBOL(snia_pciio_dmamap_free);
-EXPORT_SYMBOL(snia_pciio_dmamap_addr);
-EXPORT_SYMBOL(snia_pciio_dmamap_done);
-EXPORT_SYMBOL(snia_pciio_endian_set);
-
-pciio_endian_t
-snia_pciio_endian_set(struct pci_dev *pci_dev,
-	pciio_endian_t device_end,
-	pciio_endian_t desired_end)
-{
-	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-	
-	return DEV_FUNC(dev, endian_set)
-		(dev, device_end, desired_end);
-}
-
-iopaddr_t
-snia_pciio_dmatrans_addr(struct pci_dev *pci_dev, /* translate for this device */
-                    device_desc_t dev_desc,     /* device descriptor */
-                    paddr_t paddr,      /* system physical address */
-                    size_t byte_count,  /* length */
-                    unsigned flags)
-{                                       /* defined in dma.h */
-
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-
-    return DEV_FUNC(dev, dmatrans_addr)
-        (dev, dev_desc, paddr, byte_count, flags);
-}
-
-pciio_dmamap_t
-snia_pciio_dmamap_alloc(struct pci_dev *pci_dev,  /* set up mappings for this device */
-                   device_desc_t dev_desc,      /* device descriptor */
-                   size_t byte_count_max,       /* max size of a mapping */
-                   unsigned flags)
-{                                       /* defined in dma.h */
-
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-
-    return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-        (dev, dev_desc, byte_count_max, flags);
-}
-
-void
-snia_pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_free)
-        (CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-snia_pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,  /* use these mapping resources */
-                  paddr_t paddr,        /* map for this address */
-                  size_t byte_count)
-{                                       /* map this many bytes */
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_addr)
-        (CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
-}
-
-void
-snia_pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_done)
-        (CAST_DMAMAP(pciio_dmamap));
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/platform_init/Makefile linux-2.4.22-pre10/arch/ia64/sn/io/platform_init/Makefile
--- linux-2.4.21/arch/ia64/sn/io/platform_init/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/platform_init/Makefile	2003-08-01 13:34:49.000000000 +0000
@@ -0,0 +1,16 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+O_TARGET := snio.o
+
+obj-y				+=  sgi_io_init.o irix_io_init.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/platform_init/irix_io_init.c linux-2.4.22-pre10/arch/ia64/sn/io/platform_init/irix_io_init.c
--- linux-2.4.21/arch/ia64/sn/io/platform_init/irix_io_init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/platform_init/irix_io_init.c	2003-08-01 13:35:06.000000000 +0000
@@ -0,0 +1,89 @@
+/* $Id$
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/pci/pciba.h>
+#include <linux/smp.h>
+#include <asm/sn/simulator.h>
+
+extern void init_all_devices(void);
+extern void klhwg_add_all_modules(vertex_hdl_t);
+extern void klhwg_add_all_nodes(vertex_hdl_t);
+
+extern vertex_hdl_t hwgraph_root;
+extern void io_module_init(void);
+extern int pci_bus_to_hcl_cvlink(void);
+extern void mlreset(void);
+
+/* #define DEBUG_IO_INIT 1 */
+#ifdef DEBUG_IO_INIT
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG_IO_INIT */
+
+/*
+ * This routine is responsible for the setup of all the IRIX hwgraph style
+ * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
+ * is called just before the generic Linux PCI layer does its probing (by 
+ * platform_pci_fixup aka sn_pci_fixup).
+ *
+ * It is very IMPORTANT that this call is only made by the Master CPU!
+ *
+ */
+
+void
+irix_io_init(void)
+{
+	cnodeid_t cnode;
+
+	/*
+	 * This is the Master CPU.  Emulate mlsetup and main.c in Irix.
+	 */
+	mlreset();
+
+        /*
+         * Initialize platform-dependent vertices in the hwgraph:
+         *      module
+         *      node
+         *      cpu
+         *      memory
+         *      slot
+         *      hub
+         *      router
+         *      xbow
+         */
+
+        io_module_init(); /* Use to be called module_init() .. */
+        klhwg_add_all_modules(hwgraph_root);
+        klhwg_add_all_nodes(hwgraph_root);
+
+	for (cnode = 0; cnode < numnodes; cnode++) {
+		extern void per_hub_init(cnodeid_t);
+		per_hub_init(cnode);
+	}
+
+	/* We can do headless hub cnodes here .. */
+
+	/*
+	 *
+	 * Our IO Infrastructure drivers are in place .. 
+	 * Initialize the whole IO Infrastructure .. xwidget/device probes.
+	 *
+	 */
+	init_all_devices();
+	pci_bus_to_hcl_cvlink();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/platform_init/sgi_io_init.c linux-2.4.22-pre10/arch/ia64/sn/io/platform_init/sgi_io_init.c
--- linux-2.4.21/arch/ia64/sn/io/platform_init/sgi_io_init.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/platform_init/sgi_io_init.c	2003-08-01 13:33:22.000000000 +0000
@@ -0,0 +1,109 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/pda.h>
+#include <linux/smp.h>
+
+extern int init_hcl(void);
+
+/*
+ * per_hub_init
+ *
+ * 	This code is executed once for each Hub chip.
+ */
+void
+per_hub_init(cnodeid_t cnode)
+{
+	nasid_t		nasid;
+	nodepda_t	*npdap;
+	ii_icmr_u_t	ii_icmr;
+	ii_ibcr_u_t	ii_ibcr;
+	ii_ilcsr_u_t	ii_ilcsr;
+
+	nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+	ASSERT(nasid != INVALID_NASID);
+	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
+
+	npdap = NODEPDA(cnode);
+
+	/* Disable the request and reply errors. */
+	REMOTE_HUB_S(nasid, IIO_IWEIM, 0xC000);
+
+	/*
+	 * Set the total number of CRBs that can be used.
+	 */
+	ii_icmr.ii_icmr_regval= 0x0;
+	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xf;
+	if (enable_shub_wars_1_1() ) {
+		// Set bit one of ICMR to prevent II from sending interrupt for II bug.
+		ii_icmr.ii_icmr_regval |= 0x1; 
+	}
+	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
+
+	/*
+	 * Set the number of CRBs that both of the BTEs combined
+	 * can use minus 1.
+	 */
+	ii_ibcr.ii_ibcr_regval= 0x0;
+	ii_ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
+	if (ii_ilcsr.ii_ilcsr_fld_s.i_llp_stat & LNK_STAT_WORKING) {
+	    ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
+	} else {
+	    /*
+	     * if the LLP is down, there is no attached I/O, so
+	    * give BTE all the CRBs.
+	    */
+	    ii_ibcr.ii_ibcr_fld_s.i_count = 0x14;
+	}
+	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
+
+	/*
+	 * Set CRB timeout to be 10ms.
+	 */
+	REMOTE_HUB_S(nasid, IIO_ICTP, 0xffffff );
+	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
+
+	/* Initialize error interrupts for this hub. */
+	hub_error_init(cnode);
+}
+
+/*
+ * This routine is responsible for the setup of all the IRIX hwgraph style
+ * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
+ * is called just before the generic Linux PCI layer does its probing (by 
+ * platform_pci_fixup aka sn_pci_fixup).
+ *
+ * It is very IMPORTANT that this call is only made by the Master CPU!
+ *
+ */
+
+void
+sgi_master_io_infr_init(void)
+{
+	extern void irix_io_init(void);
+
+	init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */
+	irix_io_init(); /* Do IRIX Compatibility IO Init */
+
+#ifdef	CONFIG_KDB
+	{
+		extern void kdba_io_init(void);
+		kdba_io_init();
+	}
+#endif
+
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sgi_if.c linux-2.4.22-pre10/arch/ia64/sn/io/sgi_if.c
--- linux-2.4.21/arch/ia64/sn/io/sgi_if.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sgi_if.c	2003-08-01 13:33:18.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -20,8 +20,6 @@
 #include <asm/sn/pci/pciio.h>
 #include <asm/sn/slotnum.h>
 
-unsigned char Is_pic_on_this_nasid[512];	/* non-0 when this is a pic shub */
-
 void *
 snia_kmem_zalloc(size_t size, int flag)
 {
@@ -37,13 +35,6 @@
         kfree(ptr);
 }
 
-int
-nic_vertex_info_match(devfs_handle_t v, char *s)
-{
-	/* we don't support this */
-	return(0);
-}
-
 /*
  * the alloc/free_node routines do a simple kmalloc for now ..
  */
@@ -64,74 +55,6 @@
 }
 
 
-#define xtod(c)         ((c) <= '9' ? '0' - (c) : 'a' - (c) - 10)
-long
-atoi(register char *p)
-{
-        register long n;
-        register int c, neg = 0;
-
-        if (p == NULL)
-                return 0;
-
-        if (!isdigit(c = *p)) {
-                while (isspace(c))
-                        c = *++p;
-                switch (c) {
-                case '-':
-                        neg++;
-                case '+': /* fall-through */
-                        c = *++p;
-                }
-                if (!isdigit(c))
-                        return (0);
-        }
-        if (c == '0' && *(p + 1) == 'x') {
-                p += 2;
-                c = *p;
-                n = xtod(c);
-                while ((c = *++p) && isxdigit(c)) {
-                        n *= 16; /* two steps to avoid unnecessary overflow */
-                        n += xtod(c); /* accum neg to avoid surprises at MAX */
-                }
-        } else {
-                n = '0' - c;
-                while ((c = *++p) && isdigit(c)) {
-                        n *= 10; /* two steps to avoid unnecessary overflow */
-                        n += '0' - c; /* accum neg to avoid surprises at MAX */
-                }
-        }
-        return (neg ? n : -n);
-}
-
-char *
-strtok_r(char *string, const char *sepset, char **lasts)
-{
-        register char   *q, *r;
-
-        /*first or subsequent call*/
-        if (string == NULL)
-                string = *lasts;
-
-        if(string == 0)         /* return if no tokens remaining */
-                return(NULL);
-
-        q = string + strspn(string, sepset);    /* skip leading separators */
-
-        if(*q == '\0') {                /* return if no tokens remaining */
-                *lasts = 0;     /* indicate this is last token */
-                return(NULL);
-        }
-
-        if((r = strpbrk(q, sepset)) == NULL)    /* move past token */
-                *lasts = 0;     /* indicate this is last token */
-        else {
-                *r = '\0';
-                *lasts = r+1;
-        }
-        return(q);
-}
-
 /*
  * print_register() allows formatted printing of bit fields.  individual
  * bit fields are described by a struct reg_desc, multiple bit fields within
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sgi_io_init.c linux-2.4.22-pre10/arch/ia64/sn/io/sgi_io_init.c
--- linux-2.4.21/arch/ia64/sn/io/sgi_io_init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sgi_io_init.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,336 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/pci/pciba.h>
-#include <linux/smp.h>
-
-extern void mlreset(int );
-extern int init_hcl(void);
-extern void klgraph_hack_init(void);
-extern void hubspc_init(void);
-extern void pciio_init(void);
-extern void pcibr_init(void);
-extern void xtalk_init(void);
-extern void xbow_init(void);
-extern void xbmon_init(void);
-extern void pciiox_init(void);
-extern void usrpci_init(void);
-extern void ioc3_init(void);
-extern void initialize_io(void);
-#if defined(CONFIG_IA64_SGI_SN1)
-extern void intr_clear_all(nasid_t);
-#endif
-extern void klhwg_add_all_modules(devfs_handle_t);
-extern void klhwg_add_all_nodes(devfs_handle_t);
-
-void sn_mp_setup(void);
-extern devfs_handle_t hwgraph_root;
-extern void io_module_init(void);
-extern void pci_bus_cvlink_init(void);
-extern void temp_hack(void);
-
-extern int pci_bus_to_hcl_cvlink(void);
-
-/* #define DEBUG_IO_INIT 1 */
-#ifdef DEBUG_IO_INIT
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_IO_INIT */
-
-/*
- * per_hub_init
- *
- * 	This code is executed once for each Hub chip.
- */
-static void
-per_hub_init(cnodeid_t cnode)
-{
-	nasid_t		nasid;
-	nodepda_t	*npdap;
-	ii_icmr_u_t	ii_icmr;
-	ii_ibcr_u_t	ii_ibcr;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	ASSERT(nasid != INVALID_NASID);
-	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
-
-	npdap = NODEPDA(cnode);
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	/* initialize per-node synergy perf instrumentation */
-	npdap->synergy_perf_enabled = 0; /* off by default */
-	npdap->synergy_perf_lock = SPIN_LOCK_UNLOCKED;
-	npdap->synergy_perf_freq = SYNERGY_PERF_FREQ_DEFAULT;
-	npdap->synergy_inactive_intervals = 0;
-	npdap->synergy_active_intervals = 0;
-	npdap->synergy_perf_data = NULL;
-	npdap->synergy_perf_first = NULL;
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-
-	/*
-	 * Set the total number of CRBs that can be used.
-	 */
-	ii_icmr.ii_icmr_regval= 0x0;
-	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xF;
-	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
-
-	/*
-	 * Set the number of CRBs that both of the BTEs combined
-	 * can use minus 1.
-	 */
-	ii_ibcr.ii_ibcr_regval= 0x0;
-	ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
-	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
-
-	/*
-	 * Set CRB timeout to be 10ms.
-	 */
-	REMOTE_HUB_S(nasid, IIO_ICTP, 0x1000 );
-	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
-
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	/* Reserve all of the hardwired interrupt levels. */
-	intr_reserve_hardwired(cnode);
-#endif
-
-	/* Initialize error interrupts for this hub. */
-	hub_error_init(cnode);
-}
-
-/*
- * This routine is responsible for the setup of all the IRIX hwgraph style
- * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
- * is called just before the generic Linux PCI layer does its probing (by 
- * platform_pci_fixup aka sn_pci_fixup).
- *
- * It is very IMPORTANT that this call is only made by the Master CPU!
- *
- */
-
-void
-sgi_master_io_infr_init(void)
-{
-	int cnode;
-
-	/*
-	 * Do any early init stuff .. einit_tbl[] etc.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling init_hcl().\n");
-	init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */
-
-#ifdef Colin
-
-printk("Testing out Xbridge Access .. if it hangs Xbridge is not init yet.\n");
-printk("	Reading Xbridge WID at address 0xc00000080f000000 0x%p\n", (* (volatile uint32_t *)(0xc00000080f000000)));
-
-printk("Testing out PCI Address Space Accesses\n");
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020000 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020000)));
-
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020001 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020001)));
-
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020002 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020002)));
-
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020003 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020003)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020004)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020005 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020005)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020006 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020006)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020007 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020007)));
-
-printk("	Testing PCI Config Word: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020004)));
-
-printk("	Testing PCI Config Word: address 0xc00000080f020008 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020008)));
-
-#endif
-
-	/*
-	 * initialize the Linux PCI to xwidget vertexes ..
-	 */
-	DBG("--> sgi_master_io_infr_init: calling pci_bus_cvlink_init().\n");
-	pci_bus_cvlink_init();
-
-#ifdef BRINGUP
-#ifdef CONFIG_IA64_SGI_SN1
-	/*
-	 * Hack to provide statically initialzed klgraph entries.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n");
-	klgraph_hack_init();
-#endif /* CONFIG_IA64_SGI_SN1 */
-#endif /* BRINGUP */
-
-	/*
-	 * This is the Master CPU.  Emulate mlsetup and main.c in Irix.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling mlreset(0).\n");
-	mlreset(0); /* Master .. */
-
-	/*
-	 * allowboot() is called by kern/os/main.c in main()
-	 * Emulate allowboot() ...
-	 *   per_cpu_init() - only need per_hub_init()
-	 *   cpu_io_setup() - Nothing to do.
-	 * 
-	 */
-	DBG("--> sgi_master_io_infr_init: calling sn_mp_setup().\n");
-	sn_mp_setup();
-
-	DBG("--> sgi_master_io_infr_init: calling per_hub_init(0).\n");
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		per_hub_init(cnode);
-	}
-
-	/* We can do headless hub cnodes here .. */
-
-	/*
-	 * io_init[] stuff.
-	 *
-	 * Get SGI IO Infrastructure drivers to init and register with 
-	 * each other etc.
-	 */
-
-	DBG("--> sgi_master_io_infr_init: calling hubspc_init()\n");
-	hubspc_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pciio_init()\n");
-	pciio_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pcibr_init()\n");
-	pcibr_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xtalk_init()\n");
-	xtalk_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xbow_init()\n");
-	xbow_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xbmon_init()\n");
-	xbmon_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pciiox_init()\n");
-	pciiox_init();
-
-	DBG("--> sgi_master_io_infr_init: calling usrpci_init()\n");
-	usrpci_init();
-
-	DBG("--> sgi_master_io_infr_init: calling ioc3_init()\n");
-	ioc3_init();
-
-	/*
-	 *
-	 * Our IO Infrastructure drivers are in place .. 
-	 * Initialize the whole IO Infrastructure .. xwidget/device probes.
-	 *
-	 */
-	DBG("--> sgi_master_io_infr_init: Start Probe and IO Initialization\n");
-	initialize_io();
-
-	DBG("--> sgi_master_io_infr_init: Setting up SGI IO Links for Linux PCI\n");
-	pci_bus_to_hcl_cvlink();
-
-#ifdef CONFIG_PCIBA
-	DBG("--> sgi_master_io_infr_init: calling pciba_init()\n");
-	pciba_init();
-#endif
-
-	DBG("--> Leave sgi_master_io_infr_init: DONE setting up SGI Links for PCI\n");
-}
-
-/*
- * sgi_slave_io_infr_init - This routine must be called on all cpus except 
- * the Master CPU.
- */
-void
-sgi_slave_io_infr_init(void)
-{
-	/* Emulate cboot() .. */
-	mlreset(1); /* This is a slave cpu */
-
-	// per_hub_init(0); /* Need to get and send in actual cnode number */
-
-	/* Done */
-}
-
-/*
- * One-time setup for MP SN.
- * Allocate per-node data, slurp prom klconfig information and
- * convert it to hwgraph information.
- */
-void
-sn_mp_setup(void)
-{
-	cnodeid_t	cnode;
-	cpuid_t		cpu;
-
-	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-		/* Skip holes in CPU space */
-		if (cpu_enabled(cpu)) {
-			init_platform_pda(cpu);
-		}
-	}
-
-	/*
-	 * Initialize platform-dependent vertices in the hwgraph:
-	 *	module
-	 *	node
-	 *	cpu
-	 *	memory
-	 *	slot
-	 *	hub
-	 *	router
-	 *	xbow
-	 */
-
-	DBG("sn_mp_io_setup: calling io_module_init()\n");
-	io_module_init(); /* Use to be called module_init() .. */
-
-	DBG("sn_mp_setup: calling klhwg_add_all_modules()\n");
-	klhwg_add_all_modules(hwgraph_root);
-	DBG("sn_mp_setup: calling klhwg_add_all_nodes()\n");
-	klhwg_add_all_nodes(hwgraph_root);
-
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-
-		/*
-		 * This routine clears the Hub's Interrupt registers.
-		 */
-		/*
-		 * We need to move this intr_clear_all() routine 
-		 * from SN/intr.c to a more appropriate file.
-		 * Talk to Al Mayer.
-		 */
-#if defined(CONFIG_IA64_SGI_SN1)
-                intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
-#endif
-		/* now init the hub */
-	//	per_hub_init(cnode);
-
-	}
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	synergy_perf_init();
-#endif
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sgi_io_sim.c linux-2.4.22-pre10/arch/ia64/sn/io/sgi_io_sim.c
--- linux-2.4.21/arch/ia64/sn/io/sgi_io_sim.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sgi_io_sim.c	2003-08-01 13:32:24.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/config.h>
@@ -15,18 +15,11 @@
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/module.h>
-#include <asm/sn/nic.h>
 #include <asm/sn/sn_private.h>
 
-cpuid_t         master_procid = 0;
+cpuid_t         master_procid;
 char arg_maxnodes[4];
 
-extern void init_all_devices(void);
-
-#if defined(CONFIG_IA64_SGI_SN1)
-synergy_da_t	*Synergy_da_indr[MAX_COMPACT_NODES * 2];
-#endif
-
 /*
  * Return non-zero if the given variable was specified
  */
@@ -36,44 +29,12 @@
         return (strlen(s) != 0);
 }
 
-void xbmon_init(void)
-{
-	FIXME("xbmon_init : no-op\n");
-
-}
-
-void pciiox_init(void)
-{
-	FIXME("pciiox_init : no-op\n");
-
-}
-
-void usrpci_init(void)
-{
-	FIXME("usrpci_init : no-op\n");
-
-}
-
-void ioc3_init(void)
-{
-	FIXME("ioc3_init : no-op\n");
-
-}
-
-void initialize_io(void)
-{
-
-	init_all_devices();
-}
-
 /*
  * Routines provided by ml/SN/promif.c.
  */
-static __psunsigned_t master_bridge_base = (__psunsigned_t)NULL;
+static __psunsigned_t master_bridge_base;
 nasid_t console_nasid = (nasid_t)-1;
-#if !defined(CONFIG_IA64_SGI_SN1)
 char master_baseio_wid;
-#endif
 static char console_wid;
 static char console_pcislot;
 
@@ -95,27 +56,6 @@
                 return 0;
 }
 
-#if defined(CONFIG_IA64_SGI_SN1)
-int
-is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid)
-{
-
-        /*
-         * If the widget numbers are different, we're not the master.
-         */
-        if (test_wid != (xwidgetnum_t)console_wid)
-                return 0;
-
-        /*
-         * If the NASIDs are the same or equivalent, we're the master.
-         */
-        if (check_nasid_equiv(test_nasid, console_nasid)) {
-                return 1;
-        } else {
-                return 0;
-        }
-}
-#else
 int
 is_master_baseio_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid)
 {
@@ -137,14 +77,3 @@
                 return 0;
         }
 }
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-/*
- * Routines provided by ml/SN/nvram.c
- */
-void
-nvram_baseinit(void)
-{
-	FIXME("nvram_baseinit : no-op\n");
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/Makefile linux-2.4.22-pre10/arch/ia64/sn/io/sn1/Makefile
--- linux-2.4.21/arch/ia64/sn/io/sn1/Makefile	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,25 +0,0 @@
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 2002 Silicon Graphics, Inc.  All Rights Reserved.
-#
-# Makefile for the sn1 io routines.
-
-EXTRA_CFLAGS    := -DLITTLE_ENDIAN
-
-O_TARGET := snio.o
-
-export-objs := pciio.o
-
-obj-$(CONFIG_IA64_SGI_SN1)	+= ml_SN_intr.o mem_refcnt.o hubcounters.o \
-				   ip37.o huberror.o hub_intr.o pcibr.o \
-				   eeprom.o l1.o l1_command.o pciio.o \
-				   klconflib.o klgraph.o \
-				   efi-rtc.o xbow.o xtalk.o \
-				   ml_SN_init.o ml_iograph.o module.o \
-				   pci_bus_cvlink.o sgi_io_init.o
-
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/eeprom.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/eeprom.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/eeprom.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/eeprom.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1421 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1999-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * WARNING:     There is more than one copy of this file in different isms.
- *              All copies must be kept exactly in sync.
- *              Do not modify this file without also updating the following:
- *
- *              irix/kern/io/eeprom.c
- *              stand/arcs/lib/libsk/ml/eeprom.c
- *		stand/arcs/lib/libkl/io/eeprom.c
- *
- *      (from time to time they might not be in sync but that's due to bringup
- *       activity - this comment is to remind us that they eventually have to
- *       get back together)
- *
- * eeprom.c
- *
- * access to board-mounted EEPROMs via the L1 system controllers
- *
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/simulator.h>
-
-#if defined(EEPROM_DEBUG)
-#define db_printf(x) printk x
-#else
-#define db_printf(x) printk x
-#endif
-
-#define BCOPY(x,y,z)	memcpy(y,x,z)
-
-#define UNDERSCORE	0	/* don't convert underscores to hyphens */
-#define HYPHEN		1	/* convert underscores to hyphens */
-
-void		copy_ascii_field( char *to, char *from, int length,
-			          int change_underscore );
-uint64_t	generate_unique_id( char *sn, int sn_len );
-uchar_t		char_to_base36( char c );
-int		nicify( char *dst, eeprom_brd_record_t *src );
-static void	int64_to_hex_string( char *out, uint64_t val );
-
-// extern int router_lock( net_vec_t, int, int );
-// extern int router_unlock( net_vec_t );
-#define ROUTER_LOCK(p) 	// router_lock(p, 10000, 3000000)
-#define ROUTER_UNLOCK(p) 	// router_unlock(p)
-
-#define IP27LOG_OVNIC           "OverrideNIC"
-
-
-/* the following function converts an EEPROM record to a close facsimile
- * of the string returned by reading a Dallas Semiconductor NIC (see
- * one of the many incarnations of nic.c for details on that driver)
- */
-int nicify( char *dst, eeprom_brd_record_t *src )
-{
-    int field_len;
-    uint64_t unique_id;
-    char *cur_dst = dst;
-    eeprom_board_ia_t   *board;
-
-    board   = src->board_ia;
-    ASSERT( board );  /* there should always be a board info area */
-
-    /* copy part number */
-    strcpy( cur_dst, "Part:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->part_num_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->part_num_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->part_num, field_len, HYPHEN );
-    cur_dst += field_len;
-
-    /* copy product name */
-    strcpy( cur_dst, ";Name:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->product_tl & FIELD_FORMAT_MASK) == FIELD_FORMAT_ASCII );
-    field_len = board->product_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->product, field_len, UNDERSCORE );
-    cur_dst += field_len;
-
-    /* copy serial number */
-    strcpy( cur_dst, ";Serial:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->serial_num_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->serial_num_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->serial_num, field_len,
-		      HYPHEN);
-
-    cur_dst += field_len;
-
-    /* copy revision */
-    strcpy( cur_dst, ";Revision:");
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->board_rev_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->board_rev_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->board_rev, field_len, HYPHEN );
-    cur_dst += field_len;
-
-    /* EEPROMs don't have equivalents for the Group, Capability and
-     * Variety fields, so we pad these with 0's
-     */
-    strcpy( cur_dst, ";Group:ff;Capability:ffffffff;Variety:ff" );
-    cur_dst += strlen( cur_dst );
-
-    /* use the board serial number to "fake" a laser id */
-    strcpy( cur_dst, ";Laser:" );
-    cur_dst += strlen( cur_dst );
-    unique_id = generate_unique_id( board->serial_num,
-				    board->serial_num_tl & FIELD_LENGTH_MASK );
-    int64_to_hex_string( cur_dst, unique_id );
-    strcat( dst, ";" );
-
-    return 1;
-}
-
-
-/* These functions borrow heavily from chars2* in nic.c
- */
-void copy_ascii_field( char *to, char *from, int length,
-		       int change_underscore )
-{
-    int i;
-    for( i = 0; i < length; i++ ) {
-
-	/* change underscores to hyphens if requested */
-	if( from[i] == '_' && change_underscore == HYPHEN )
-	    to[i] = '-';
-
-	/* ; and ; are separators, so mustn't appear within
-	 * a field */
-	else if( from[i] == ':' || from[i] == ';' )
-	    to[i] = '?';
-
-	/* I'm not sure why or if ASCII character 0xff would
-	 * show up in an EEPROM field, but the NIC parsing
-	 * routines wouldn't like it if it did... so we
-	 * get rid of it, just in case. */
-	else if( (unsigned char)from[i] == (unsigned char)0xff )
-	    to[i] = ' ';
-	
-	/* unprintable characters are replaced with . */
-	else if( from[i] < ' ' || from[i] >= 0x7f )
-	    to[i] = '.';
-
-	/* otherwise, just copy the character */
-	else
-	    to[i] = from[i];
-    }
-
-    if( i == 0 ) {
-	to[i] = ' '; /* return at least a space... */
-	i++;
-    }
-    to[i] = 0;	     /* terminating null */
-}
-
-/* Note that int64_to_hex_string currently only has a big-endian
- * implementation.
- */
-#ifdef _MIPSEB
-static void int64_to_hex_string( char *out, uint64_t val )
-{
-    int i;
-    uchar_t table[] = "0123456789abcdef";
-    uchar_t *byte_ptr = (uchar_t *)&val;
-    for( i = 0; i < sizeof(uint64_t); i++ ) {
-	out[i*2] = table[ ((*byte_ptr) >> 4) & 0x0f ];
-	out[i*2+1] = table[ (*byte_ptr) & 0x0f ];
-	byte_ptr++;
-    }
-    out[i*2] = '\0';
-}
-
-#else /* little endian */
-
-static void int64_to_hex_string( char *out, uint64_t val )
-{
-
-
-	printk("int64_to_hex_string needs a little-endian implementation.\n");
-}
-#endif /* _MIPSEB */
-
-/* Convert a standard ASCII serial number to a unique integer
- * id number by treating the serial number string as though
- * it were a base 36 number
- */
-uint64_t generate_unique_id( char *sn, int sn_len )
-{
-    int uid = 0;
-    int i;
-
-    #define VALID_BASE36(c)	((c >= '0' && c <='9') \
-			    ||   (c >= 'A' && c <='Z') \
-			    ||   (c >= 'a' && c <='z'))
-
-    for( i = 0; i < sn_len; i++ ) {
-	if( !VALID_BASE36(sn[i]) )
-	    continue;
-	uid *= 36;
-	uid += char_to_base36( sn[i] );
-    }
-
-    if( uid == 0 )
-	return rtc_time();
-
-    return uid;
-}
-
-uchar_t char_to_base36( char c )
-{
-    uchar_t val;
-
-    if( c >= '0' && c <= '9' )
-	val = (c - '0');
-
-    else if( c >= 'A' && c <= 'Z' )
-	val = (c - 'A' + 10);
-
-    else if( c >= 'a' && c <= 'z' )
-	val = (c - 'a' + 10);
-
-    else val = 0;
-
-    return val;
-}
-
-
-/* given a pointer to the three-byte little-endian EEPROM representation
- * of date-of-manufacture, this function translates to a big-endian
- * integer format
- */
-int eeprom_xlate_board_mfr_date( uchar_t *src )
-{
-    int rval = 0;
-    rval += *src; src++;
-    rval += ((int)(*src) << 8); src ++;
-    rval += ((int)(*src) << 16);
-    return rval;
-}
-
-
-int eeprom_str( char *nic_str, nasid_t nasid, int component )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    if( (component & C_DIMM) == C_DIMM ) {
-	/* this function isn't applicable to DIMMs */
-	return EEP_PARAM;
-    }
-    else {
-	eep.board_ia = &board;
-	eep.spd = NULL;
-	if( !(component & SUBORD_MASK) )
-	    eep.chassis_ia = &chassis;  /* only main boards have a chassis
-					 * info area */
-	else
-	    eep.chassis_ia = NULL;
-    }
-    
-    switch( component & BRICK_MASK ) {
-      case C_BRICK:
-	r = cbrick_eeprom_read( &eep, nasid, component );
-	break;
-      case IO_BRICK:
-	r = iobrick_eeprom_read( &eep, nasid, component );
-	break;
-      default:
-	return EEP_PARAM;  /* must be an invalid component */
-    }
-    if( r )
-	return r;
-    if( !nicify( nic_str, &eep ) )
-	return EEP_NICIFY;
-
-    return EEP_OK;
-}
-
-int vector_eeprom_str( char *nic_str, nasid_t nasid,
-		       int component, net_vec_t path )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    eep.board_ia = &board;
-    if( !(component & SUBORD_MASK) )
-        eep.chassis_ia = &chassis;  /* only main boards have a chassis
-                                     * info area */
-    else
-        eep.chassis_ia = NULL;
-
-    if( !(component & VECTOR) )
-	return EEP_PARAM;
-
-    if( (r = vector_eeprom_read( &eep, nasid, path, component )) )
-	return r;
-
-    if( !nicify( nic_str, &eep ) )
-        return EEP_NICIFY;
-
-    return EEP_OK;
-}
-
-
-int is_iobrick( int nasid, int widget_num )
-{
-    uint32_t wid_reg;
-    int part_num, mfg_num;
-
-    /* Read the widget's WIDGET_ID register to get
-     * its part number and mfg number
-     */
-    wid_reg = *(volatile int32_t *)
-        (NODE_SWIN_BASE( nasid, widget_num ) + WIDGET_ID);
-
-    part_num = (wid_reg & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT;
-    mfg_num = (wid_reg & WIDGET_MFG_NUM) >> WIDGET_MFG_NUM_SHFT;
-
-    /* Is this the "xbow part" of an XBridge?  If so, this
-     * widget is definitely part of an I/O brick.
-     */
-    if( part_num == XXBOW_WIDGET_PART_NUM &&
-	mfg_num == XXBOW_WIDGET_MFGR_NUM )
-
-	return 1;
-
-    /* Is this a "bridge part" of an XBridge?  If so, once
-     * again, we know this widget is part of an I/O brick.
-     */
-    if( part_num == XBRIDGE_WIDGET_PART_NUM &&
-	mfg_num == XBRIDGE_WIDGET_MFGR_NUM )
-
-	return 1;
-
-    return 0;
-}
-
-
-int cbrick_uid_get( nasid_t nasid, uint64_t *uid )
-{
-    char uid_str[32];
-    char msg[BRL1_QSIZE];
-    int subch, len;
-    l1sc_t sc;
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* If the promlog variable pointed to by IP27LOG_OVNIC is set,
-     * use that value for the cbrick UID rather than the EEPROM
-     * serial number.
-     */
-#ifdef LOG_GETENV
-    if( ip27log_getenv( nasid, IP27LOG_OVNIC, uid_str, NULL, 0 ) >= 0 )
-    {
-	/* We successfully read IP27LOG_OVNIC, so return it as the UID. */
-	db_printf(( "cbrick_uid_get:"
-		    "Overriding UID with environment variable %s\n", 
-		    IP27LOG_OVNIC ));
-	*uid = strtoull( uid_str, NULL, 0 );
-	return EEP_OK;
-    }
-#endif
-
-    /* If this brick is retrieving its own uid, use the local l1sc_t to
-     * arbitrate access to the l1; otherwise, set up a new one.
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &sc;
-	sc_init( &sc, nasid, BRL1_LOCALHUB_UART );
-    }
-
-    /* fill in msg with the opcode & params */
-    BZERO( msg, BRL1_QSIZE );
-    if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 )
-	return EEP_L1;
-
-    if( (len = sc_construct_msg( scp, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SER_NUM, 0 )) < 0 )
-    {
-	sc_close( scp, subch );
-	return( EEP_L1 );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( scp, subch, msg, msg, &len ) ) {
-	sc_close( scp, subch );
-	return( EEP_L1 );
-    }
-
-    /* free up subchannel */
-    sc_close(scp, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 )
-    {
-	return( EEP_L1 );
-    }
-
-    *uid = generate_unique_id( uid_str, strlen( uid_str ) );
-
-    return EEP_OK;
-}
-
-
-int rbrick_uid_get( nasid_t nasid, net_vec_t path, uint64_t *uid )
-{
-    char uid_str[32];
-    char msg[BRL1_QSIZE];
-    int subch, len;
-    l1sc_t sc;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-#define FAIL								\
-    {									\
-	*uid = rtc_time();						\
-	printk( "rbrick_uid_get failed; using current time as uid\n" );	\
-	return EEP_OK;							\
-    }
-
-    ROUTER_LOCK(path);
-    sc_init( &sc, nasid, path );
-
-    /* fill in msg with the opcode & params */
-    BZERO( msg, BRL1_QSIZE );
-    if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 ) {
-	ROUTER_UNLOCK(path);
-	FAIL;
-    }
-
-    if( (len = sc_construct_msg( &sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SER_NUM, 0 )) < 0 )
-    {
-	ROUTER_UNLOCK(path);
-	sc_close( &sc, subch );
-	FAIL;
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( &sc, subch, msg, msg, &len ) ) {
-	ROUTER_UNLOCK(path);
-	sc_close( &sc, subch );
-	FAIL;
-    }
-
-    /* free up subchannel */
-    ROUTER_UNLOCK(path);
-    sc_close(&sc, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 )
-    {
-	FAIL;
-    }
-
-    *uid = generate_unique_id( uid_str, strlen( uid_str ) );
-
-    return EEP_OK;
-}
-
-int iobrick_uid_get( nasid_t nasid, uint64_t *uid )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    eep.board_ia = &board;
-    eep.chassis_ia = &chassis;
-    eep.spd = NULL;
-
-    r = iobrick_eeprom_read( &eep, nasid, IO_BRICK );
-    if( r != EEP_OK ) {
-        *uid = rtc_time();
-        return r;
-    }
-
-    *uid = generate_unique_id( board.serial_num,
-                               board.serial_num_tl & FIELD_LENGTH_MASK );
-
-    return EEP_OK;
-}
-
-
-int ibrick_mac_addr_get( nasid_t nasid, char *eaddr )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-    char *tmp;
-
-    eep.board_ia = &board;
-    eep.chassis_ia = &chassis;
-    eep.spd = NULL;
-
-    r = iobrick_eeprom_read( &eep, nasid, IO_BRICK );
-    if( (r != EEP_OK) || (board.mac_addr[0] == '\0') ) {
-	db_printf(( "ibrick_mac_addr_get: "
-		    "Couldn't read MAC address from EEPROM\n" ));
-	return EEP_L1;
-    }
-    else {
-	/* successfully read info area */
-	int ix;
-	tmp = board.mac_addr;
-	for( ix = 0; ix < (board.mac_addr_tl & FIELD_LENGTH_MASK); ix++ )
-	{
-	    *eaddr++ = *tmp++;
-	}
-	*eaddr = '\0';
-    }
-
-    return EEP_OK;
-}
-
-
-/* 
- * eeprom_vertex_info_set
- *
- * Given a vertex handle, a component designation, a starting nasid
- * and (in the case of a router) a vector path to the component, this
- * function will read the EEPROM and attach the resulting information
- * to the vertex in the same string format as that provided by the
- * Dallas Semiconductor NIC drivers.  If the vertex already has the
- * string, this function just returns the string.
- */
-
-extern char *nic_vertex_info_get( devfs_handle_t );
-extern void nic_vmc_check( devfs_handle_t, char * );
-/* the following were lifted from nic.c - change later? */
-#define MAX_INFO 2048
-#define NEWSZ(ptr,sz)   ((ptr) = kern_malloc((sz)))
-#define DEL(ptr) (kern_free((ptr)))
-
-char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v,
-                              net_vec_t path )
-{
-        char *info_tmp;
-        int info_len;
-        char *info;
-
-        /* see if this vertex is already marked */
-        info_tmp = nic_vertex_info_get(v);
-        if (info_tmp) return info_tmp;
-
-        /* get a temporary place for the data */
-        NEWSZ(info_tmp, MAX_INFO);
-        if (!info_tmp) return NULL;
-
-        /* read the EEPROM */
-	if( component & R_BRICK ) {
-	    if( RBRICK_EEPROM_STR( info_tmp, nasid, path ) != EEP_OK )
-		return NULL;
-	}
-	else {
-            if( eeprom_str( info_tmp, nasid, component ) != EEP_OK )
-	        return NULL;
-	}
-
-        /* allocate a smaller final place */
-        info_len = strlen(info_tmp)+1;
-        NEWSZ(info, info_len);
-        if (info) {
-                strcpy(info, info_tmp);
-                DEL(info_tmp);
-        } else {
-                info = info_tmp;
-        }
-
-        /* add info to the vertex */
-        hwgraph_info_add_LBL(v, INFO_LBL_NIC,
-                             (arbitrary_info_t) info);
-
-        /* see if someone else got there first */
-        info_tmp = nic_vertex_info_get(v);
-        if (info != info_tmp) {
-            DEL(info);
-            return info_tmp;
-        }
-
-        /* export the data */
-        hwgraph_info_export_LBL(v, INFO_LBL_NIC, info_len);
-
-        /* trigger all matching callbacks */
-        nic_vmc_check(v, info);
-
-        return info;
-}
-
-
-/*********************************************************************
- *
- * stubs for use until the Bedrock/L1 link is available
- *
- */
-
-#include <asm/sn/nic.h>
-
-/* #define EEPROM_TEST */
-
-/* fake eeprom reading functions (replace when the BR/L1 communication
- * channel is in working order)
- */
-
-
-/* generate a charater in [0-9A-Z]; if an "extra" character is
- * specified (such as '_'), include it as one of the possibilities.
- */
-char random_eeprom_ch( char extra ) 
-{
-    char ch;
-    int modval = 36;
-    if( extra )
-	modval++;
-    
-    ch = rtc_time() % modval;
-
-    if( ch < 10 )
-        ch += '0';
-    else if( ch >= 10 && ch < 36 )
-	ch += ('A' - 10);
-    else
-	ch = extra;
-
-    return ch;
-}
-
-/* create a part number of the form xxx-xxxx-xxx.
- * It may be important later to generate different
- * part numbers depending on the component we're
- * supposed to be "reading" from, so the component
- * paramter is provided.
- */
-void fake_a_part_number( char *buf, int component )
-{
-    int i;
-    switch( component ) {
-
-    /* insert component-specific routines here */
-
-    case C_BRICK:
-	strcpy( buf, "030-1266-001" );
-	break;
-    default:
-        for( i = 0; i < 12; i++ ) {
-	    if( i == 3 || i == 8 )
-	        buf[i] = '-';
-	    else
-	        buf[i] = random_eeprom_ch(0);
-        }
-    }
-}
-
-
-/* create a six-character serial number */
-void fake_a_serial_number( char *buf, uint64_t ser )
-{
-    int i;
-    static const char hexchars[] = "0123456789ABCDEF";
-
-    if (ser) {
-	for( i = 5; i >=0; i-- ) {
-	    buf[i] = hexchars[ser & 0xf];
-	    ser >>= 4;
-	}
-    }
-    else {
-	for( i = 0; i < 6; i++ )
-	    buf[i] = random_eeprom_ch(0);
-    }
-}
-
-
-void fake_a_product_name( uchar_t *format, char* buf, int component )
-{
-    switch( component & BRICK_MASK ) {
-
-    case C_BRICK:
-	if( component & SUBORD_MASK ) {
-	    strcpy( buf, "C_BRICK_SUB" );
-	    *format = 0xCB;
-	}
-	else {
-	    strcpy( buf, "IP35" );
-	    *format = 0xC4;
-	}
-	break;
-
-    case R_BRICK:
-        if( component & SUBORD_MASK ) {
-            strcpy( buf, "R_BRICK_SUB" );
-            *format = 0xCB;
-        }
-        else {
-            strcpy( buf, "R_BRICK" );
-            *format = 0xC7;
-        }
-        break;
-
-    case IO_BRICK:
-        if( component & SUBORD_MASK ) {
-            strcpy( buf, "IO_BRICK_SUB" );
-            *format = 0xCC;
-        }
-        else {
-            strcpy( buf, "IO_BRICK" );
-            *format = 0xC8;
-        }
-        break;
-
-    default:
-	strcpy( buf, "UNK_DEVICE" );
-	*format = 0xCA;
-    }
-}
-
-
-
-int fake_an_eeprom_record( eeprom_brd_record_t *buf, int component, 
-			   uint64_t ser )
-{
-    eeprom_board_ia_t *board;
-    eeprom_chassis_ia_t *chassis;
-    int i, cs;
-
-    board = buf->board_ia;
-    chassis = buf->chassis_ia;
-
-    if( !(component & SUBORD_MASK) ) {
-	if( !chassis )
-	    return EEP_PARAM;
-	chassis->format = 0;
-	chassis->length = 5;
-	chassis->type = 0x17;
-
-	chassis->part_num_tl = 0xCC;
-	fake_a_part_number( chassis->part_num, component );
-	chassis->serial_num_tl = 0xC6;
-	fake_a_serial_number( chassis->serial_num, ser );
-
-	cs = chassis->format + chassis->length + chassis->type
-	    + chassis->part_num_tl + chassis->serial_num_tl;
-	for( i = 0; i < (chassis->part_num_tl & FIELD_LENGTH_MASK); i++ )
-	    cs += chassis->part_num[i];
-	for( i = 0; i < (chassis->serial_num_tl & FIELD_LENGTH_MASK); i++ )
-	    cs += chassis->serial_num[i];
-	chassis->checksum = 256 - (cs % 256);
-    }
-
-    if( !board )
-	return EEP_PARAM;
-    board->format = 0;
-    board->length = 10;
-    board->language = 0;
-    board->mfg_date = 1789200; /* noon, 5/26/99 */
-    board->manuf_tl = 0xC3;
-    strcpy( board->manuf, "SGI" );
-
-    fake_a_product_name( &(board->product_tl), board->product, component );
-
-    board->serial_num_tl = 0xC6;
-    fake_a_serial_number( board->serial_num, ser );
-
-    board->part_num_tl = 0xCC;
-    fake_a_part_number( board->part_num, component );
-
-    board->board_rev_tl = 0xC2;
-    board->board_rev[0] = '0';
-    board->board_rev[1] = '1';
-
-    board->eeprom_size_tl = 0x01;
-    board->eeprom_size = 1;
-
-    board->temp_waiver_tl = 0xC2;
-    board->temp_waiver[0] = '0';
-    board->temp_waiver[1] = '1';
-
-    cs = board->format + board->length + board->language
-	+ (board->mfg_date & 0xFF)
-	+ (board->mfg_date & 0xFF00)
-	+ (board->mfg_date & 0xFF0000)
-	+ board->manuf_tl + board->product_tl + board->serial_num_tl
-	+ board->part_num_tl + board->board_rev_tl
-	+ board->board_rev[0] + board->board_rev[1]
-	+ board->eeprom_size_tl + board->eeprom_size + board->temp_waiver_tl
-	+ board->temp_waiver[0] + board->temp_waiver[1];
-    for( i = 0; i < (board->manuf_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->manuf[i];
-    for( i = 0; i < (board->product_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->product[i];
-    for( i = 0; i < (board->serial_num_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->serial_num[i];
-    for( i = 0; i < (board->part_num_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->part_num[i];
-    
-    board->checksum = 256 - (cs % 256);
-
-    return EEP_OK;
-}
-
-#define EEPROM_CHUNKSIZE	64
-
-#if defined(EEPROM_DEBUG)
-#define RETURN_ERROR							\
-{									\
-    printk( "read_ia error return, component 0x%x, line %d"		\
-	    ", address 0x%x, ia code 0x%x\n",				\
-	    l1_compt, __LINE__, sc->subch[subch].target, ia_code );	\
-    return EEP_L1;							\
-}
-
-#else
-#define RETURN_ERROR	return(EEP_L1)
-#endif
-
-int read_ia( l1sc_t *sc, int subch, int l1_compt, 
-	     int ia_code, char *eep_record )
-{
-    char msg[BRL1_QSIZE]; 	   /* message buffer */
-    int len;              	   /* number of bytes used in message buffer */
-    int ia_len = EEPROM_CHUNKSIZE; /* remaining bytes in info area */
-    int offset = 0;                /* current offset into info area */
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    BZERO( msg, BRL1_QSIZE );
-
-    /* retrieve EEPROM data in 64-byte chunks
-     */
-
-    while( ia_len )
-    {
-	/* fill in msg with opcode & params */
-	if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				     L1_ADDR_TASK_GENERAL,
-				     L1_REQ_EEPROM, 8,
-				     L1_ARG_INT, l1_compt,
-				     L1_ARG_INT, ia_code,
-				     L1_ARG_INT, offset,
-				     L1_ARG_INT, ia_len )) < 0 )
-	{
-	    RETURN_ERROR;
-	}
-
-	/* send the request to the L1 */
-
-	if( sc_command( sc, subch, msg, msg, &len ) ) {
-	    RETURN_ERROR;
-	}
-
-	/* check response */
-	if( sc_interpret_resp( msg, 5, 
-			       L1_ARG_INT, &ia_len,
-			       L1_ARG_UNKNOWN, &len, eep_record ) < 0 )
-	{
-	    RETURN_ERROR;
-	}
-
-	if( ia_len > EEPROM_CHUNKSIZE )
-	    ia_len = EEPROM_CHUNKSIZE;
-
-	eep_record += EEPROM_CHUNKSIZE;
-	offset += EEPROM_CHUNKSIZE;
-    }
-
-    return EEP_OK;
-}
-
-
-int read_spd( l1sc_t *sc, int subch, int l1_compt,
-	      eeprom_spd_u *spd )
-{
-    char msg[BRL1_QSIZE]; 	    /* message buffer */
-    int len;              	    /* number of bytes used in message buffer */
-    int resp;                       /* l1 response code */
-    int spd_len = EEPROM_CHUNKSIZE; /* remaining bytes in spd record */
-    int offset = 0;		    /* current offset into spd record */
-    char *spd_p = spd->bytes;	    /* "thumb" for writing to spd */
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    BZERO( msg, BRL1_QSIZE );
-
-    /* retrieve EEPROM data in 64-byte chunks
-     */
-
-    while( spd_len )
-    {
-	/* fill in msg with opcode & params */
-	if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				     L1_ADDR_TASK_GENERAL,
-				     L1_REQ_EEPROM, 8,
-				     L1_ARG_INT, l1_compt,
-				     L1_ARG_INT, L1_EEP_SPD,
-				     L1_ARG_INT, offset,
-				     L1_ARG_INT, spd_len )) < 0 )
-	{
-	    return( EEP_L1 );
-	}
-
-	/* send the request to the L1 */
-	if( sc_command( sc, subch, msg, msg, &len ) ) {
-	    return( EEP_L1 );
-	}
-
-	/* check response */
-	if( (resp = sc_interpret_resp( msg, 5, 
-			       L1_ARG_INT, &spd_len,
-			       L1_ARG_UNKNOWN, &len, spd_p )) < 0 )
-	{
-            /*
-             * translate l1 response code to eeprom.c error codes:
-             * The L1 response will be L1_RESP_NAVAIL if the spd
-             * can't be read (i.e. the spd isn't physically there). It will
-             * return L1_RESP_INVAL if the spd exists, but fails the checksum
-             * test because the eeprom wasn't programmed, programmed incorrectly,
-             * or corrupted. L1_RESP_NAVAIL indicates the eeprom is likely not present,
-             * whereas L1_RESP_INVAL indicates the eeprom is present, but the data is
-             * invalid.
-             */
-            if(resp == L1_RESP_INVAL) {
-                resp = EEP_BAD_CHECKSUM;
-            } else {
-                resp = EEP_L1;
-            }
-            return( resp );
-	}
-
-	if( spd_len > EEPROM_CHUNKSIZE )
-	    spd_len = EEPROM_CHUNKSIZE;
-
-	spd_p += EEPROM_CHUNKSIZE;
-	offset += EEPROM_CHUNKSIZE;
-    }
-    return EEP_OK;
-}
-
-
-int read_chassis_ia( l1sc_t *sc, int subch, int l1_compt,
-		     eeprom_chassis_ia_t *ia )
-{
-    char eep_record[512];          /* scratch area for building up info area */
-    char *eep_rec_p = eep_record;  /* thumb for moving through eep_record */
-    int checksum = 0;              /* use to verify eeprom record checksum */
-    int i;
-
-    /* Read in info area record from the L1.
-     */
-    if( read_ia( sc, subch, l1_compt, L1_EEP_CHASSIS, eep_record )
-	!= EEP_OK )
-    {
-	return EEP_L1;
-    }
-
-    /* Now we've got the whole info area.  Transfer it to the data structure.
-     */
-
-    eep_rec_p = eep_record;
-    ia->format = *eep_rec_p++;
-    ia->length = *eep_rec_p++;
-    if( ia->length == 0 ) {
-	/* since we're using 8*ia->length-1 as an array index later, make
-	 * sure it's sane.
-	 */
-	db_printf(( "read_chassis_ia: eeprom length byte of ZERO\n" ));
-	return EEP_L1;
-    }
-    ia->type = *eep_rec_p++;
-   
-    ia->part_num_tl = *eep_rec_p++;
-
-    (void)BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK);
-
-    ia->serial_num_tl = *eep_rec_p++;
-
-    BCOPY( eep_rec_p, ia->serial_num, 
-	   (ia->serial_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK);
-
-    ia->checksum = eep_record[(8 * ia->length) - 1];
-
-    /* verify checksum */
-    eep_rec_p = eep_record;
-    checksum = 0;
-    for( i = 0; i < (8 * ia->length); i++ ) {
-	checksum += *eep_rec_p++;
-    }
-
-    if( (checksum & 0xff) != 0 )
-    {
-	db_printf(( "read_chassis_ia: bad checksum\n" ));
-	db_printf(( "read_chassis_ia: target 0x%x  uart 0x%lx\n",
-			   sc->subch[subch].target, sc->uart ));
-	return EEP_BAD_CHECKSUM;
-    }
-
-    return EEP_OK;
-}
-
-
-int read_board_ia( l1sc_t *sc, int subch, int l1_compt,
-		   eeprom_board_ia_t *ia )
-{
-    char eep_record[512];          /* scratch area for building up info area */
-    char *eep_rec_p = eep_record;  /* thumb for moving through eep_record */
-    int checksum = 0;              /* running checksum total */
-    int i;
-
-    BZERO( ia, sizeof( eeprom_board_ia_t ) );
-
-    /* Read in info area record from the L1.
-     */
-    if( read_ia( sc, subch, l1_compt, L1_EEP_BOARD, eep_record )
-	!= EEP_OK )
-    {
-	db_printf(( "read_board_ia: error reading info area from L1\n" ));
-	return EEP_L1;
-    }
-
-     /* Now we've got the whole info area.  Transfer it to the data structure.
-      */
-
-    eep_rec_p = eep_record;
-    ia->format = *eep_rec_p++;
-    ia->length = *eep_rec_p++;
-    if( ia->length == 0 ) {
-	/* since we're using 8*ia->length-1 as an array index later, make
-	 * sure it's sane.
-	 */
-	db_printf(( "read_board_ia: eeprom length byte of ZERO\n" ));
-	return EEP_L1;
-    }
-    ia->language = *eep_rec_p++;
-    
-    ia->mfg_date = eeprom_xlate_board_mfr_date( (uchar_t *)eep_rec_p );
-    eep_rec_p += 3;
-
-    ia->manuf_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->manuf, (ia->manuf_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->manuf_tl & FIELD_LENGTH_MASK);
-
-    ia->product_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->product, (ia->product_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->product_tl & FIELD_LENGTH_MASK);
-
-    ia->serial_num_tl = *eep_rec_p++;
-    
-    BCOPY(eep_rec_p, ia->serial_num, (ia->serial_num_tl & FIELD_LENGTH_MASK));
-    eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK);
-
-    ia->part_num_tl = *eep_rec_p++;
-
-    BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK);
-
-    eep_rec_p++; /* we do not use the FRU file id */
-    
-    ia->board_rev_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->board_rev, (ia->board_rev_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->board_rev_tl & FIELD_LENGTH_MASK);
-
-    ia->eeprom_size_tl = *eep_rec_p++;
-    ia->eeprom_size = *eep_rec_p++;
-
-    ia->temp_waiver_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->temp_waiver, 
-	   (ia->temp_waiver_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->temp_waiver_tl & FIELD_LENGTH_MASK);
-
-    /* if there's more, we must be reading a main board; get
-     * additional fields
-     */
-    if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) {
-
-	ia->ekey_G_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_G, 
-	       ia->ekey_G_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_G_tl & FIELD_LENGTH_MASK);
-	
-	ia->ekey_P_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_P, 
-	       ia->ekey_P_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_P_tl & FIELD_LENGTH_MASK);
-	
-	ia->ekey_Y_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_Y, 
-	       ia->ekey_Y_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_Y_tl & FIELD_LENGTH_MASK);
-	
-	/* 
-	 * need to get a couple more fields if this is an I brick 
-	 */
-	if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) {
-
-	    ia->mac_addr_tl = *eep_rec_p++;
-	    BCOPY( eep_rec_p, ia->mac_addr, 
-		   ia->mac_addr_tl & FIELD_LENGTH_MASK );
-	    eep_rec_p += (ia->mac_addr_tl & FIELD_LENGTH_MASK);
-	    
-	    ia->ieee1394_cfg_tl = *eep_rec_p++;
-	    BCOPY( eep_rec_p, ia->ieee1394_cfg,
-		   ia->ieee1394_cfg_tl & FIELD_LENGTH_MASK );
-	    
-	}
-    }
-
-    ia->checksum = eep_record[(ia->length * 8) - 1];
-
-    /* verify checksum */
-    eep_rec_p = eep_record;
-    checksum = 0;
-    for( i = 0; i < (8 * ia->length); i++ ) {
-	checksum += *eep_rec_p++;
-    }
-
-    if( (checksum & 0xff) != 0 )
-    {
-	db_printf(( "read_board_ia: bad checksum\n" ));
-	db_printf(( "read_board_ia: target 0x%x  uart 0x%lx\n",
-		    sc->subch[subch].target, sc->uart ));
-	return EEP_BAD_CHECKSUM;
-    }
-
-    return EEP_OK;
-}
-
-
-int _cbrick_eeprom_read( eeprom_brd_record_t *buf, l1sc_t *scp,
-			 int component )
-{
-    int r;
-    uint64_t uid = 0;
-#ifdef LOG_GETENV
-    char uid_str[32];
-#endif
-    int l1_compt, subch;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're targeting a cbrick */
-    if( !(component & C_BRICK) )
-	return EEP_PARAM;
-
-    /* If the promlog variable pointed to by IP27LOG_OVNIC is set,
-     * use that value for the cbrick UID rather than the EEPROM
-     * serial number.
-     */
-#ifdef LOG_GETENV
-    if( ip27log_getenv( scp->nasid, IP27LOG_OVNIC, uid_str, "0", 0 ) >= 0 )
-    {
-	db_printf(( "_cbrick_eeprom_read: "
-		    "Overriding UID with environment variable %s\n", 
-		    IP27LOG_OVNIC ));
-	uid = strtoull( uid_str, NULL, 0 );
-    }
-#endif
-
-    if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 )
-	return EEP_L1;
-
-    if((component & C_DIMM) == C_DIMM) {
-        l1_compt = L1_EEP_DIMM(component & COMPT_MASK);
-        r = read_spd(scp,subch,l1_compt, buf->spd);
-        sc_close(scp,subch);
-        return(r);
-    }
-
-    switch( component )
-    {
-      case C_BRICK:
-	/* c-brick motherboard */
-	l1_compt = L1_EEP_NODE;
-	r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia );
-	if( r != EEP_OK ) {
-	    sc_close( scp, subch );
-	    db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" ));
-	    return fake_an_eeprom_record( buf, component, uid );
-	}
-	if( uid ) {
-	    /* If IP27LOG_OVNIC is set, we want to put that value
-	     * in as our UID. */
-	    fake_a_serial_number( buf->chassis_ia->serial_num, uid );
-	    buf->chassis_ia->serial_num_tl = 6;
-	}
-	break;
-
-      case C_PIMM:
-	/* one of the PIMM boards */
-	l1_compt = L1_EEP_PIMM( component & COMPT_MASK );
-	break;
-
-      default:
-	/* unsupported board type */
-	sc_close( scp, subch );
-	return EEP_PARAM;
-    }
-	      
-    r = read_board_ia( scp, subch, l1_compt, buf->board_ia );
-    sc_close( scp, subch );
-    if( r != EEP_OK ) 
-    {
-	db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" ));
-	return fake_an_eeprom_record( buf, component, uid );
-    }
-    return EEP_OK;
-}
-
-
-int cbrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-    		        int component )
-{
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* If this brick is retrieving its own uid, use the local l1sc_t to
-     * arbitrate access to the l1; otherwise, set up a new one (prom) or
-     * use an existing remote l1sc_t (kernel)
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    }
-
-    return _cbrick_eeprom_read( buf, scp, component );
-}
-
-
-int iobrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			 int component )
-{
-    int r;
-    int l1_compt, subch;
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're talking to an applicable brick */
-    if( !(component & IO_BRICK) ) {
-	return EEP_PARAM;
-    }
-
-    /* If we're talking to this c-brick's attached io brick, use
-     * the local l1sc_t; otherwise, set up a new one (prom) or
-     * use an existing remote l1sc_t (kernel)
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    }
-
-    if( (subch = sc_open( scp, L1_ADDR_LOCALIO )) < 0 )
-	return EEP_L1;
-
-
-    switch( component )
-    {
-      case IO_BRICK:
-	/* IO brick motherboard */
-	l1_compt = L1_EEP_LOGIC;
-	r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia );
-
-	if( r != EEP_OK ) {
-	    sc_close( scp, subch );
-	/*
-	 * Whenever we no longer need to test on hardware
-	 * that does not have EEPROMS, then this can be removed.
-	 */
-	    r = fake_an_eeprom_record( buf, component, rtc_time() );
-	    return r;
-	}
-	break;
-
-      case IO_POWER:
-	/* IO brick power board */
-	l1_compt = L1_EEP_POWER;
-	break;
-
-      default:
-	/* unsupported board type */
-	sc_close( scp, subch );
-	return EEP_PARAM;
-    }
-
-    r = read_board_ia( scp, subch, l1_compt, buf->board_ia );
-    sc_close( scp, subch );
-    if( r != EEP_OK ) {
-	return r;
-    }
-    return EEP_OK;
-}
-
-
-int vector_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			net_vec_t path, int component )
-{
-    int r;
-    uint64_t uid = 0;
-    int l1_compt, subch;
-    l1sc_t sc;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're targeting an applicable brick */
-    if( !(component & VECTOR) )
-	return EEP_PARAM;
-
-    switch( component & BRICK_MASK )
-    {
-      case R_BRICK:
-	ROUTER_LOCK( path );
-	sc_init( &sc, nasid, path );
-
-	if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 )
-	{
-	    db_printf(( "vector_eeprom_read: couldn't open subch\n" ));
-	    ROUTER_UNLOCK(path);
-	    return EEP_L1;
-	}
-	switch( component )
-	{
-	  case R_BRICK:
-	    /* r-brick motherboard */
-	    l1_compt = L1_EEP_LOGIC;
-    	    r = read_chassis_ia( &sc, subch, l1_compt, buf->chassis_ia );
-	    if( r != EEP_OK ) {
-		sc_close( &sc, subch );
-		ROUTER_UNLOCK( path );
-		printk( "vector_eeprom_read: couldn't get rbrick eeprom info;"
-			" using current time as uid\n" );
-		uid = rtc_time();
-		db_printf(("vector_eeprom_read: using a fake eeprom record\n"));
-		return fake_an_eeprom_record( buf, component, uid );
-	    }
-	    break;
-
-	  case R_POWER:
-	    /* r-brick power board */
-	    l1_compt = L1_EEP_POWER;
-	    break;
-
-	  default:
-	    /* unsupported board type */
-	    sc_close( &sc, subch );
-	    ROUTER_UNLOCK( path );
-	    return EEP_PARAM;
-	}
-	r = read_board_ia( &sc, subch, l1_compt, buf->board_ia );
-	sc_close( &sc, subch );
-	ROUTER_UNLOCK( path );
-	if( r != EEP_OK ) {
-	    db_printf(( "vector_eeprom_read: using a fake eeprom record\n" ));
-	    return fake_an_eeprom_record( buf, component, uid );
-	}
-	return EEP_OK;
-
-      case C_BRICK:
-	sc_init( &sc, nasid, path );
-	return _cbrick_eeprom_read( buf, &sc, component );
-
-      default:
-	/* unsupported brick type */
-	return EEP_PARAM;
-    }
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/efi-rtc.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/efi-rtc.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/efi-rtc.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/efi-rtc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,202 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
- * Copyright (C) 2001 by Ralf Baechle
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/efi.h>
-#include <asm/sn/klclock.h>
-
-/*
- * No locking necessary when this is called from efirtc which protects us
- * from racing by efi_rtc_lock.
- */
-#define __swizzle(addr) ((u8 *)((unsigned long)(addr) ^ 3))
-#define read_io_port(addr) (*(volatile u8 *) __swizzle(addr))
-#define write_io_port(addr, data) (*(volatile u8 *) __swizzle(addr) = (data))
-
-#define TOD_SGS_M48T35		1
-#define TOD_DALLAS_DS1386	2
-
-#define TYPE_IOC3		1
-#define TYPE_IOC4		2
-
-static unsigned long nvram_base = 0;
-static int tod_chip_type;
-static int ioc_type;
-
-static int
-get_tod_chip_type(void)
-{
-	unsigned char testval;
-
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-	write_io_port(RTC_DAL_DAY_ADDR, 0xff);
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-
-	testval = read_io_port(RTC_DAL_DAY_ADDR);
-	if (testval == 0xff)
-		return TOD_SGS_M48T35;
-
-	return TOD_DALLAS_DS1386;
-}
-
-efi_status_t
-ioc3_get_time(efi_time_t *time, efi_time_cap_t *caps)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	memset(time, 0, sizeof(*time));
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_READ_PROTECT);
-
-		time->year = BCD_TO_INT(read_io_port(RTC_SGS_YEAR_ADDR)) + YRREF;
-		time->month = BCD_TO_INT(read_io_port(RTC_SGS_MONTH_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_SGS_DATE_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_SGS_HOUR_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_SGS_MIN_ADDR));
-		time->second = BCD_TO_INT(read_io_port(RTC_SGS_SEC_ADDR));
-		time->nanosecond = 0;
-
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-
-		time->nanosecond = 0;
-		time->second = BCD_TO_INT(read_io_port(RTC_DAL_SEC_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_DAL_MIN_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_DAL_HOUR_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_DAL_DATE_ADDR));
-		time->month = BCD_TO_INT(read_io_port(RTC_DAL_MONTH_ADDR));
-		time->year = BCD_TO_INT(read_io_port(RTC_DAL_YEAR_ADDR)) + YRREF;
-
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	if (caps) {
-		caps->resolution = 50000000;	/*  50PPM */
-		caps->accuracy = 1000;		/*  1ms */
-		caps->sets_to_zero = 0;
-	}
-
-	return EFI_SUCCESS;
-}
-
-static efi_status_t ioc3_set_time (efi_time_t *t)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_WRITE_ENABLE);
-        	write_io_port(RTC_SGS_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_SGS_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_SGS_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_SGS_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_SGS_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_SGS_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-		write_io_port(RTC_DAL_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_DAL_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_DAL_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_DAL_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_DAL_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_DAL_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	return EFI_SUCCESS;
-}
-
-/* The following two are not supported atm.  */
-static efi_status_t
-ioc3_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-static efi_status_t
-ioc3_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-static __init int efi_ioc_time_init(void)
-{
-	struct pci_dev *dev = NULL;
-	static void *ioc_base;
-
-        while ( (dev = pci_find_subsys(PCI_VENDOR_ID_SGI,
-                               PCI_ANY_ID,
-                               PCI_ANY_ID,
-                               PCI_ANY_ID, dev))) {
-		if ( dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-			ioc_type = TYPE_IOC3;
-			break;
-		}
-		else if ( dev->device == PCI_DEVICE_ID_SGI_IOC4 ) {
-			ioc_type = TYPE_IOC4;
-			break;
-		}
-		else
-			;; // keep looking
-	}
-
-	if ( !dev ) {
-		printk(KERN_CRIT "Couldn't find master IOC\n");
-		return -ENODEV;
-	}
-
-	ioc_base = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0));
-	if ( ioc_type == TYPE_IOC3 )
-		nvram_base = (unsigned long) ioc_base + IOC3_BYTEBUS_DEV0;
-	if ( ioc_type == TYPE_IOC4 )
-		nvram_base = (unsigned long) ioc_base + IOC4_BYTEBUS_DEV0;
-
-	tod_chip_type = get_tod_chip_type();
-	if (tod_chip_type == 1)
-		printk(KERN_NOTICE "TOD type is SGS M48T35\n");
-	else if (tod_chip_type == 2)
-		printk(KERN_NOTICE "TOD type is Dallas DS1386\n");
-	else
-		printk(KERN_CRIT "No or unknown TOD\n");
-
-	efi.get_time = ioc3_get_time;
-	efi.set_time = ioc3_set_time;
-	efi.get_wakeup_time = ioc3_get_wakeup_time;
-	efi.set_wakeup_time = ioc3_set_wakeup_time;
-
-	return 0;
-}
-
-module_init(efi_ioc_time_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/hub_intr.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/hub_intr.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/hub_intr.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/hub_intr.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,307 +0,0 @@
-/* $Id: hub_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/types.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-
-extern xtalk_provider_t hub_provider;
-
-/* ARGSUSED */
-void
-hub_intr_init(devfs_handle_t hubv)
-{
-}
-
-/*
- * hub_device_desc_update
- *	Update the passed in device descriptor with the actual the
- * 	target cpu number and interrupt priority level.
- *	NOTE : These might be the same as the ones passed in thru
- *	the descriptor.
- */
-static void
-hub_device_desc_update(device_desc_t 	dev_desc, 
-		       ilvl_t 		intr_swlevel,
-		       cpuid_t		cpu)
-{
-}
-
-int allocate_my_bit = INTRCONNECT_ANYBIT;
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Returns a hub interrupt handle on success, or 0 on failure.
- */
-static hub_intr_t
-do_hub_intr_alloc(devfs_handle_t dev,		/* which crosstalk device */
-		  device_desc_t dev_desc,	/* device descriptor */
-		  devfs_handle_t owner_dev,	/* owner of this interrupt, if known */
-		  int uncond_nothread)		/* unconditionally non-threaded */
-{
-	cpuid_t cpu = (cpuid_t)0;			/* cpu to receive interrupt */
-        int cpupicked = 0;
-	int bit;			/* interrupt vector */
-	/*REFERENCED*/
-	int intr_resflags = 0;
-	hub_intr_t intr_hdl;
-	cnodeid_t nodeid;		/* node to receive interrupt */
-	/*REFERENCED*/
-	nasid_t nasid;			/* nasid to receive interrupt */
-	struct xtalk_intr_s *xtalk_info;
-	iopaddr_t xtalk_addr;		/* xtalk addr on hub to set intr */
-	xwidget_info_t xwidget_info;	/* standard crosstalk widget info handle */
-	char *intr_name = NULL;
-	ilvl_t intr_swlevel = (ilvl_t)0;
-	extern int default_intr_pri;
-	extern void synergy_intr_alloc(int, int);
-
-
-	if (dev_desc) {
-		if (dev_desc->flags & D_INTR_ISERR) {
-			intr_resflags = II_ERRORINT;
-		} else if (!uncond_nothread && !(dev_desc->flags & D_INTR_NOTHREAD)) {
-			intr_resflags = II_THREADED;
-		} else {
-			/* Neither an error nor a thread. */
-			intr_resflags = 0;
-		}
-	} else {
-		intr_swlevel = default_intr_pri;
-		if (!uncond_nothread)
-			intr_resflags = II_THREADED;
-	}
-
-	/* XXX - Need to determine if the interrupt should be threaded. */
-
-	/* If the cpu has not been picked already then choose a candidate 
-	 * interrupt target and reserve the interrupt bit 
-	 */
-	if (!cpupicked) {
-		cpu = intr_heuristic(dev,dev_desc,allocate_my_bit,
-				     intr_resflags,owner_dev,
-				     intr_name,&bit);
-	}
-
-	/* At this point we SHOULD have a valid cpu */
-	if (cpu == CPU_NONE) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		printk(KERN_WARNING  "%v hub_intr_alloc could not allocate interrupt\n",
-			owner_dev);
-#else
-		printk(KERN_WARNING  "%p hub_intr_alloc could not allocate interrupt\n",
-			(void *)owner_dev);
-#endif
-		return(0);
-
-	}
-
-	/* If the cpu has been picked already (due to the bridge data 
-	 * corruption bug) then try to reserve an interrupt bit .
-	 */
-	if (cpupicked) {
-		bit = intr_reserve_level(cpu, allocate_my_bit, 
-					 intr_resflags, 
-					 owner_dev, intr_name);
-		if (bit < 0) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-			printk(KERN_WARNING  "Could not reserve an interrupt bit for cpu "
-				" %d and dev %v\n",
-				cpu,owner_dev);
-#else
-			printk(KERN_WARNING  "Could not reserve an interrupt bit for cpu "
-				" %d and dev %p\n",
-				(int)cpu, (void *)owner_dev);
-#endif
-				
-			return(0);
-		}
-	}
-
-	nodeid = cpuid_to_cnodeid(cpu);
-	nasid = cpuid_to_nasid(cpu);
-	xtalk_addr = HUBREG_AS_XTALKADDR(nasid, PIREG(PI_INT_PEND_MOD, cpuid_to_subnode(cpu)));
-
-	/*
-	 * Allocate an interrupt handle, and fill it in.  There are two
-	 * pieces to an interrupt handle: the piece needed by generic
-	 * xtalk code which is used by crosstalk device drivers, and
-	 * the piece needed by low-level IP27 hardware code.
-	 */
-	intr_hdl = snia_kmem_alloc_node(sizeof(struct hub_intr_s), KM_NOSLEEP, nodeid);
-	ASSERT_ALWAYS(intr_hdl);
-
-	/* 
-	 * Fill in xtalk information for generic xtalk interfaces that
-	 * operate on xtalk_intr_hdl's.
-	 */
-	xtalk_info = &intr_hdl->i_xtalk_info;
-	xtalk_info->xi_dev = dev;
-	xtalk_info->xi_vector = bit;
-	xtalk_info->xi_addr = xtalk_addr;
-
-	/*
-	 * Regardless of which CPU we ultimately interrupt, a given crosstalk
-	 * widget always handles interrupts (and PIO and DMA) through its 
-	 * designated "master" crosstalk provider.
-	 */
-	xwidget_info = xwidget_info_get(dev);
-	if (xwidget_info)
-		xtalk_info->xi_target = xwidget_info_masterid_get(xwidget_info);
-
-	/* Fill in low level hub information for hub_* interrupt interface */
-	intr_hdl->i_swlevel = intr_swlevel;
-	intr_hdl->i_cpuid = cpu;
-	intr_hdl->i_bit = bit;
-	intr_hdl->i_flags = HUB_INTR_IS_ALLOCED;
-
-	/* Store the actual interrupt priority level & interrupt target
-	 * cpu back in the device descriptor.
-	 */
-	hub_device_desc_update(dev_desc, intr_swlevel, cpu);
-	synergy_intr_alloc((int)bit, (int)cpu);
-	return(intr_hdl);
-}
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Returns a hub interrupt handle on success, or 0 on failure.
- */
-hub_intr_t
-hub_intr_alloc(	devfs_handle_t dev,		/* which crosstalk device */
-		device_desc_t dev_desc,		/* device descriptor */
-		devfs_handle_t owner_dev)		/* owner of this interrupt, if known */
-{
-	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 0));
-}
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Uncondtionally request non-threaded, regardless of what the device
- * descriptor might say.
- * Returns a hub interrupt handle on success, or 0 on failure.
- */
-hub_intr_t
-hub_intr_alloc_nothd(devfs_handle_t dev,		/* which crosstalk device */
-		device_desc_t dev_desc,		/* device descriptor */
-		devfs_handle_t owner_dev)		/* owner of this interrupt, if known */
-{
-	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 1));
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-hub_intr_free(hub_intr_t intr_hdl)
-{
-	cpuid_t cpu = intr_hdl->i_cpuid;
-	int bit = intr_hdl->i_bit;
-	xtalk_intr_t xtalk_info;
-
-	if (intr_hdl->i_flags & HUB_INTR_IS_CONNECTED) {
-		/* Setting the following fields in the xtalk interrupt info
-	 	 * clears the interrupt target register in the xtalk user
-	 	 */
-		xtalk_info = &intr_hdl->i_xtalk_info;
-		xtalk_info->xi_dev = NODEV;
-		xtalk_info->xi_vector = 0;
-		xtalk_info->xi_addr = 0;
-		hub_intr_disconnect(intr_hdl);
-	}
-
-	if (intr_hdl->i_flags & HUB_INTR_IS_ALLOCED)
-		kfree(intr_hdl);
-
-	intr_unreserve_level(cpu, bit);
-}
-
-
-/*
- * Associate resources allocated with a previous hub_intr_alloc call with the
- * described handler, arg, name, etc.
- */
-/*ARGSUSED*/
-int
-hub_intr_connect(	hub_intr_t intr_hdl,		/* xtalk intr resource handle */
-			xtalk_intr_setfunc_t setfunc,	/* func to set intr hw */
-			void *setfunc_arg)		/* arg to setfunc */
-{
-	int rv;
-	cpuid_t cpu = intr_hdl->i_cpuid;
-	int bit = intr_hdl->i_bit;
-	extern int synergy_intr_connect(int, int);
-
-	ASSERT(intr_hdl->i_flags & HUB_INTR_IS_ALLOCED);
-
-	rv = intr_connect_level(cpu, bit, intr_hdl->i_swlevel, NULL);
-	if (rv < 0)
-		return(rv);
-
-	intr_hdl->i_xtalk_info.xi_setfunc = setfunc;
-	intr_hdl->i_xtalk_info.xi_sfarg = setfunc_arg;
-
-	if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl);
-
-	intr_hdl->i_flags |= HUB_INTR_IS_CONNECTED;
-	return(synergy_intr_connect((int)bit, (int)cpu));
-}
-
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-hub_intr_disconnect(hub_intr_t intr_hdl)
-{
-	/*REFERENCED*/
-	int rv;
-	cpuid_t cpu = intr_hdl->i_cpuid;
-	int bit = intr_hdl->i_bit;
-	xtalk_intr_setfunc_t setfunc;
-
-	setfunc = intr_hdl->i_xtalk_info.xi_setfunc;
-
-	/* TBD: send disconnected interrupts somewhere harmless */
-	if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl);
-
-	rv = intr_disconnect_level(cpu, bit);
-	ASSERT(rv == 0);
-	intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED;
-}
-
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-hub_intr_cpu_get(hub_intr_t intr_hdl)
-{
-	cpuid_t cpuid = intr_hdl->i_cpuid;
-	ASSERT(cpuid != CPU_NONE);
-
-	return(cpuid_to_vertex(cpuid));
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/hubcounters.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/hubcounters.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/hubcounters.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/hubcounters.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,282 +0,0 @@
-/* $Id: hubcounters.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All Rights Reserved.
- */
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <asm/types.h>
-#include <asm/sn/io.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/router.h>
-#include <asm/sn/snconfig.h>
-#include <asm/sn/slotnum.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sndrv.h>
-
-extern void hubni_error_handler(char *, int); /* huberror.c */
-
-static int hubstats_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-struct file_operations hub_mon_fops = {
-        ioctl:          hubstats_ioctl,
-};
-
-#define HUB_CAPTURE_TICKS	(2 * HZ)
-
-#define HUB_ERR_THRESH		500
-#define USEC_PER_SEC		1000000
-#define NSEC_PER_SEC		USEC_PER_SEC*1000
-
-volatile int hub_print_usecs = 600 * USEC_PER_SEC;
-
-/* Return success if the hub's crosstalk link is working */
-int
-hub_xtalk_link_up(nasid_t nasid)
-{
-	hubreg_t	llp_csr_reg;
-
-	/* Read the IO LLP control status register */
-	llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
-
-	/* Check if the xtalk link is working */
-	if (llp_csr_reg & IIO_LLP_CSR_IS_UP) 
-		return(1);
-
-	return(0);
-
-	
-}
-
-static char *error_flag_to_type(unsigned char error_flag)
-{
-    switch(error_flag) {
-    case 0x1: return ("NI retries");
-    case 0x2: return ("NI SN errors");
-    case 0x4: return ("NI CB errors");
-    case 0x8: return ("II CB errors");
-    case 0x10: return ("II SN errors");
-    default: return ("Errors");
-    }
-}
-
-int
-print_hub_error(hubstat_t *hsp, hubreg_t reg,
-		int64_t delta, unsigned char error_flag)
-{
-	int64_t rate;
-
-	reg *= hsp->hs_per_minute;	/* Convert to minutes */
-	rate = reg / delta;
-
-	if (rate > HUB_ERR_THRESH) {
-		
-		if(hsp->hs_maint & error_flag) 
-		{
-		printk( "Excessive %s (%ld/min) on %s",
-			error_flag_to_type(error_flag), rate, hsp->hs_name); 
-		}
-		else 
-		{
-		   hsp->hs_maint |= error_flag;
-		printk( "Excessive %s (%ld/min) on %s",
-			error_flag_to_type(error_flag), rate, hsp->hs_name); 
-		}
-		return 1;
-	} else {
-		return 0;
-	}
-}
-
-
-int
-check_hub_error_rates(hubstat_t *hsp)
-{
-	int64_t delta = hsp->hs_timestamp - hsp->hs_timebase;
-	int printed = 0;
-
-	printed += print_hub_error(hsp, hsp->hs_ni_retry_errors,
-				   delta, 0x1);
-
-#if 0
-	printed += print_hub_error(hsp, hsp->hs_ni_sn_errors,
-				   delta, 0x2);
-#endif
-
-	printed += print_hub_error(hsp, hsp->hs_ni_cb_errors,
-				   delta, 0x4);
-
-
-	/* If the hub's xtalk link is not working there is 
-	 * no need to print the "Excessive..." warning 
-	 * messages
-	 */
-	if (!hub_xtalk_link_up(hsp->hs_nasid))
-		return(printed);
-
-
-	printed += print_hub_error(hsp, hsp->hs_ii_cb_errors,
-				   delta, 0x8);
-
-	printed += print_hub_error(hsp, hsp->hs_ii_sn_errors,
-				   delta, 0x10);
-
-	return printed;
-}
-
-
-void
-capture_hub_stats(cnodeid_t cnodeid, struct nodepda_s *npda)
-{
-	nasid_t nasid;
-	hubstat_t *hsp = &(npda->hubstats);
-	hubreg_t port_error;
-	ii_illr_u_t illr;
-	int count;
-	int overflow = 0;
-
-	/*
-	 * If our link wasn't up at boot time, don't worry about error rates.
-	 */
-	if (!(hsp->hs_ni_port_status & NPS_LINKUP_MASK)) {
-		printk("capture_hub_stats: cnode=%d hs_ni_port_status=0x%016lx : link is not up\n",
-		cnodeid, hsp->hs_ni_port_status);
-		return;
-	}
-
-	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
-
-	hsp->hs_timestamp = GET_RTC_COUNTER();
-
-	port_error = REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
-	count = ((port_error & NPE_RETRYCOUNT_MASK) >> NPE_RETRYCOUNT_SHFT);
-	hsp->hs_ni_retry_errors += count;
-	if (count == NPE_COUNT_MAX)
-		overflow = 1;
-	count = ((port_error & NPE_SNERRCOUNT_MASK) >> NPE_SNERRCOUNT_SHFT);
-	hsp->hs_ni_sn_errors += count;
-	if (count == NPE_COUNT_MAX)
-		overflow = 1;
-	count = ((port_error & NPE_CBERRCOUNT_MASK) >> NPE_CBERRCOUNT_SHFT);
-	hsp->hs_ni_cb_errors += count;
-	if (overflow || count == NPE_COUNT_MAX)
-		hsp->hs_ni_overflows++;
-
-	if (port_error & NPE_FATAL_ERRORS) {
-#ifdef ajm
-		hubni_error_handler("capture_hub_stats", 1);
-#else
-		printk("Error: hubni_error_handler in capture_hub_stats");
-#endif
-	}
-
-	illr.ii_illr_regval = REMOTE_HUB_L(nasid, IIO_LLP_LOG);
-	REMOTE_HUB_S(nasid, IIO_LLP_LOG, 0);
-
-	hsp->hs_ii_sn_errors += illr.ii_illr_fld_s.i_sn_cnt;
-	hsp->hs_ii_cb_errors += illr.ii_illr_fld_s.i_cb_cnt;
-	if ((illr.ii_illr_fld_s.i_sn_cnt == IIO_LLP_SN_MAX) ||
-	    (illr.ii_illr_fld_s.i_cb_cnt == IIO_LLP_CB_MAX))
-		hsp->hs_ii_overflows++;
-
-	if (hsp->hs_print) {
-		if (check_hub_error_rates(hsp)) {
-			hsp->hs_last_print = GET_RTC_COUNTER();
-			hsp->hs_print = 0;
-		}
-	} else {
-		if ((GET_RTC_COUNTER() -
-		    hsp->hs_last_print) > hub_print_usecs)
-			hsp->hs_print = 1;
-	}
-		
-	npda->hubticks = HUB_CAPTURE_TICKS;
-}
-
-
-void
-init_hub_stats(cnodeid_t cnodeid, struct nodepda_s *npda)
-{
-	hubstat_t *hsp = &(npda->hubstats);
-	nasid_t nasid = cnodeid_to_nasid(cnodeid);
-	bzero(&(npda->hubstats), sizeof(hubstat_t));
-
-	hsp->hs_version = HUBSTAT_VERSION;
-	hsp->hs_cnode = cnodeid;
-	hsp->hs_nasid = nasid;
-	hsp->hs_timebase = GET_RTC_COUNTER();
-	hsp->hs_ni_port_status = REMOTE_HUB_L(nasid, NI_PORT_STATUS);
-
-	/* Clear the II error counts. */
-	REMOTE_HUB_S(nasid, IIO_LLP_LOG, 0);
-
-	/* Clear the NI counts. */
-	REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
-
-	hsp->hs_per_minute = (long long)RTC_CYCLES_PER_SEC * 60LL;
-
-	npda->hubticks = HUB_CAPTURE_TICKS;
-
-	/* XX should use kmem_alloc_node */
-	hsp->hs_name = (char *)kmalloc(MAX_HUB_PATH, GFP_KERNEL);
-	ASSERT_ALWAYS(hsp->hs_name);
-
-	sprintf(hsp->hs_name, "/dev/hw/" EDGE_LBL_MODULE "/%03d/"
-	        EDGE_LBL_NODE "/" EDGE_LBL_HUB,
-		npda->module_id);
-
-	hsp->hs_last_print = 0;
-	hsp->hs_print = 1;
-
-	hub_print_usecs = hub_print_usecs;
-
-#if 0
-	printk("init_hub_stats: cnode=%d nasid=%d hs_version=%d hs_ni_port_status=0x%016lx\n",
-		cnodeid, nasid, hsp->hs_version, hsp->hs_ni_port_status);
-#endif
-}
-
-static int
-hubstats_ioctl(struct inode *inode, struct file *file,
-        unsigned int cmd, unsigned long arg)
-{
-        cnodeid_t       cnode;
-        nodepda_t       *npdap;
-        uint64_t        longarg;
-        devfs_handle_t  d;
-
-        if ((d = devfs_get_handle_from_inode(inode)) == NULL)
-                return -ENODEV;
-        cnode = (cnodeid_t)hwgraph_fastinfo_get(d);
-        npdap = NODEPDA(cnode);
-
-	if (npdap->hubstats.hs_version != HUBSTAT_VERSION) {
-		init_hub_stats(cnode, npdap);
-	}
-
-        switch (cmd) {
-	case SNDRV_GET_INFOSIZE:
-		longarg = sizeof(hubstat_t);
-		if (copy_to_user((void *)arg, &longarg, sizeof(longarg))) {
-		    return -EFAULT;
-		}
-		break;
-
-	case SNDRV_GET_HUBINFO:
-		/* refresh npda->hubstats */
-		capture_hub_stats(cnode, npdap);
-		if (copy_to_user((void *)arg, &npdap->hubstats, sizeof(hubstat_t))) {
-		    return -EFAULT;
-		}
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/huberror.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/huberror.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/huberror.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/huberror.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,228 +0,0 @@
-/* $Id: huberror.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/smp.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/intr.h>
-
-extern void hubni_eint_init(cnodeid_t cnode);
-extern void hubii_eint_init(cnodeid_t cnode);
-extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep);
-extern void snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs);
-
-extern int maxcpus;
-
-#define HUB_ERROR_PERIOD        (120 * HZ)      /* 2 minutes */
-
-
-void
-hub_error_clear(nasid_t nasid)
-{
-	int i;
-	hubreg_t idsr;
-	int sn;
-
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_PEND, -1);
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS0_A_CLR, -1);
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS0_B_CLR, -1);
-		REMOTE_HUB_PI_S(nasid, sn, PI_SPURIOUS_HDR_0, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_SPURIOUS_HDR_1, 0);
-	}
-
-	REMOTE_HUB_L(nasid, MD_DIR_ERROR_CLR);
-	REMOTE_HUB_L(nasid, MD_MEM_ERROR_CLR);
-	REMOTE_HUB_L(nasid, MD_MISC1_ERROR_CLR);
-	REMOTE_HUB_L(nasid, MD_PROTOCOL_ERR_CLR);
-
-    /*
-     * Make sure spurious write response errors are cleared
-     * (values are from hub_set_prb())
-     */
-    for (i = 0; i <= HUB_WIDGET_ID_MAX - HUB_WIDGET_ID_MIN + 1; i++) {
-        iprb_t prb;
-
-	prb.iprb_regval = REMOTE_HUB_L(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)));
-
-        /* Clear out some fields */
-        prb.iprb_ovflow = 1;
-        prb.iprb_bnakctr = 0;
-        prb.iprb_anakctr = 0;
-
-	/*
-	 * PIO reads in fire-and-forget mode on bedrock 1.0 don't
-	 * frob the credit count properly, making the responses appear
-	 * spurious.  So don't use fire-and-forget mode.  Bug 761802.
-	 */
-        prb.iprb_ff = 0;        /* disable fire-and-forget mode by default */
-
-        prb.iprb_xtalkctr = 3;  /* approx. PIO credits for the widget */
-
-        REMOTE_HUB_S(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)), prb.iprb_regval);
-    }
-
-    REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, -1);
-    idsr = REMOTE_HUB_L(nasid, IIO_IIDSR);
-    REMOTE_HUB_S(nasid, IIO_IIDSR, (idsr & ~(IIO_IIDSR_SENT_MASK)));
-
-    REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
-    /* No need to clear NI_PORT_HEADER regs; they are continually overwritten*/
-
-    REMOTE_HUB_S(nasid, LB_ERROR_MASK_CLR, -1);
-    REMOTE_HUB_S(nasid, LB_ERROR_HDR1, 0);
-
-    /* Clear XB error regs, in order */
-    for (i = 0;
-         i <= XB_FIRST_ERROR_CLEAR - XB_POQ0_ERROR_CLEAR;
-         i += sizeof(hubreg_t)) {
-        REMOTE_HUB_S(nasid, XB_POQ0_ERROR_CLEAR + i, 0);
-    }
-}
-
-
-/*
- * Function	: hub_error_init
- * Purpose	: initialize the error handling requirements for a given hub.
- * Parameters	: cnode, the compact nodeid.
- * Assumptions	: Called only once per hub, either by a local cpu. Or by a 
- *			remote cpu, when this hub is headless.(cpuless)
- * Returns	: None
- */
-
-void
-hub_error_init(cnodeid_t cnode)
-{
-	nasid_t nasid;
-
-    nasid = cnodeid_to_nasid(cnode);
-    hub_error_clear(nasid);
-
-    /*
-     * Now setup the hub ii and ni error interrupt handler.
-     */
-
-    hubii_eint_init(cnode);
-    hubni_eint_init(cnode);
-
-    return;
-}
-
-/*
- * Function	: hubii_eint_init
- * Parameters	: cnode
- * Purpose	: to initialize the hub iio error interrupt.
- * Assumptions	: Called once per hub, by the cpu which will ultimately
- *			handle this interrupt.
- * Returns	: None.
- */
-
-
-void
-hubii_eint_init(cnodeid_t cnode)
-{
-    int			bit, rv;
-    ii_iidsr_u_t    	hubio_eint;
-    hubinfo_t		hinfo; 
-    cpuid_t		intr_cpu;
-    devfs_handle_t 	hub_v;
-    ii_ilcsr_u_t	ilcsr;
-    int bit_pos_to_irq(int bit);
-    int synergy_intr_connect(int bit, int cpuid);
-
-
-    hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode);
-    ASSERT_ALWAYS(hub_v);
-    hubinfo_get(hub_v, &hinfo);
-
-    ASSERT(hinfo);
-    ASSERT(hinfo->h_cnodeid == cnode);
-
-    ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
-
-    if ((ilcsr.ii_ilcsr_fld_s.i_llp_stat & 0x2) == 0) {
-	/* 
-	 * HUB II link is not up. 
-	 * Just disable LLP, and don't connect any interrupts.
-	 */
-	ilcsr.ii_ilcsr_fld_s.i_llp_en = 0;
-	REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval);
-	return;
-    }
-    /* Select a possible interrupt target where there is a free interrupt
-     * bit and also reserve the interrupt bit for this IO error interrupt
-     */
-    intr_cpu = intr_heuristic(hub_v,0,INTRCONNECT_ANYBIT,II_ERRORINT,hub_v,
-			      "HUB IO error interrupt",&bit);
-    if (intr_cpu == CPU_NONE) {
-	printk("hubii_eint_init: intr_reserve_level failed, cnode %d", cnode);
-	return;
-    }
-	
-    rv = intr_connect_level(intr_cpu, bit, 0, NULL);
-    synergy_intr_connect(bit, intr_cpu);
-    request_irq(bit_pos_to_irq(bit) + (intr_cpu << 8), hubii_eint_handler, 0, "SN hub error", (void *)hub_v);
-    ASSERT_ALWAYS(rv >= 0);
-    hubio_eint.ii_iidsr_regval = 0;
-    hubio_eint.ii_iidsr_fld_s.i_enable = 1;
-    hubio_eint.ii_iidsr_fld_s.i_level = bit;/* Take the least significant bits*/
-    hubio_eint.ii_iidsr_fld_s.i_node = COMPACT_TO_NASID_NODEID(cnode);
-    hubio_eint.ii_iidsr_fld_s.i_pi_id = cpuid_to_subnode(intr_cpu);
-    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, hubio_eint.ii_iidsr_regval);
-
-}
-
-void
-hubni_eint_init(cnodeid_t cnode)
-{
-    int intr_bit;
-    cpuid_t targ;
-
-
-    if ((targ = cnodeid_to_cpuid(cnode)) == CPU_NONE)
-	return;
-
-	/* The prom chooses which cpu gets these interrupts, but we
-	*  don't know which one it chose.  We will register all of the 
-	*  cpus to be sure.  This only costs us an irqaction per cpu.
-	*/
-    for (; targ < CPUS_PER_NODE; targ++) {
-	if (!cpu_enabled(targ) ) continue;
-	/* connect the INTEND1 bits. */
-	for (intr_bit = XB_ERROR; intr_bit <= MSC_PANIC_INTR; intr_bit++) {
-		intr_connect_level(targ, intr_bit, II_ERRORINT, NULL);
-	}
-	request_irq(SGI_HUB_ERROR_IRQ + (targ << 8), snia_error_intr_handler, 0, "SN hub error", NULL);
-	/* synergy masks are initialized in the prom to enable all interrupts. */
-	/* We'll just leave them that way, here, for these interrupts. */
-    }
-}
-
-
-/*ARGSUSED*/
-void
-hubii_eint_handler (int irq, void *arg, struct pt_regs *ep)
-{
-
-	panic("Hubii interrupt\n");
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/ip37.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/ip37.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/ip37.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/ip37.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,47 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * ip37.c
- *	Support for IP35/IP37 machines
- */
-
-#include <linux/types.h>
-
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/pci/bridge.h>     /* for bridge_t */
-
-
-xwidgetnum_t
-hub_widget_id(nasid_t nasid)
-{
-	hubii_wcr_t	ii_wcr;	/* the control status register */
-		
-	ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid,IIO_WCR);
-
-	return ii_wcr.wcr_fields_s.wcr_widget_id;
-}
-
-int
-is_fine_dirmode(void)
-{
-	return (((LOCAL_HUB_L(LB_REV_ID) & LRI_SYSTEM_SIZE_MASK)
-		>> LRI_SYSTEM_SIZE_SHFT) == SYSTEM_SIZE_SMALL);
-
-}
-
-
-void
-ni_reset_port(void)
-{
-	LOCAL_HUB_S(NI_RESET_ENABLE, NRE_RESETOK);
-	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/klconflib.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/klconflib.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/klconflib.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/klconflib.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,979 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#include <linux/types.h>
-#include <linux/ctype.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/module.h>
-#include <asm/sn/router.h>
-#include <asm/sn/xtalk/xbow.h>
-
-#define printf printk
-int hasmetarouter;
-
-#define LDEBUG 0
-#define NIC_UNKNOWN ((nic_t) -1)
-
-#undef DEBUG_KLGRAPH
-#ifdef DEBUG_KLGRAPH
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_KLGRAPH */
-
-static void sort_nic_names(lboard_t *) ;
-
-u64 klgraph_addr[MAX_COMPACT_NODES];
-int module_number = 0;
-
-lboard_t *
-find_lboard(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (start->brd_type == brd_type)
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_class(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-klinfo_t *
-find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
-{
-	int index, j;
-
-	if (kli == (klinfo_t *)NULL) {
-		index = 0;
-	} else {
-		for (j = 0; j < KLCF_NUM_COMPS(brd); j++) {
-			if (kli == KLCF_COMP(brd, j))
-				break;
-		}
-		index = j;
-		if (index == KLCF_NUM_COMPS(brd)) {
-			DBG("find_component: Bad pointer: 0x%p\n", kli);
-			return (klinfo_t *)NULL;
-		}
-		index++;	/* next component */
-	}
-	
-	for (; index < KLCF_NUM_COMPS(brd); index++) {		
-		kli = KLCF_COMP(brd, index);
-		DBG("find_component: brd %p kli %p  request type = 0x%x kli type 0x%x\n", brd, kli, kli->struct_type, KLCF_COMP_TYPE(kli));
-		if (KLCF_COMP_TYPE(kli) == struct_type)
-			return kli;
-	}
-
-	/* Didn't find it. */
-	return (klinfo_t *)NULL;
-}
-
-klinfo_t *
-find_first_component(lboard_t *brd, unsigned char struct_type)
-{
-	return find_component(brd, (klinfo_t *)NULL, struct_type);
-}
-
-lboard_t *
-find_lboard_modslot(lboard_t *start, moduleid_t mod, slotid_t slot)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (MODULE_MATCH(start->brd_module, mod) &&
-		    (start->brd_slot == slot))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_module(lboard_t *start, moduleid_t mod)
-{
-        /* Search all boards stored on this node. */
-        while (start) {
-                if (MODULE_MATCH(start->brd_module, mod))
-                        return start;
-                start = KLCF_NEXT(start);
-        }
-
-        /* Didn't find it. */
-        return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_module_class(lboard_t *start, moduleid_t mod,
-                                                unsigned char brd_type)
-{
-	while (start) {
-		DBG("find_lboard_module_class: lboard 0x%p, start->brd_module 0x%x, mod 0x%x, start->brd_type 0x%x, brd_type 0x%x\n", start, start->brd_module, mod, start->brd_type, brd_type);
-
-		if (MODULE_MATCH(start->brd_module, mod) &&
-			(KLCLASS(start->brd_type) == KLCLASS(brd_type)))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-
-/*
- * Convert a NIC name to a name for use in the hardware graph.
- */
-void
-nic_name_convert(char *old_name, char *new_name)
-{
-        int i;
-        char c;
-        char *compare_ptr;
-
-	if ((old_name[0] == '\0') || (old_name[1] == '\0')) {
-                strcpy(new_name, EDGE_LBL_XWIDGET);
-        } else {
-                for (i = 0; i < strlen(old_name); i++) {
-                        c = old_name[i];
-
-                        if (isalpha(c))
-                                new_name[i] = tolower(c);
-                        else if (isdigit(c))
-                                new_name[i] = c;
-                        else
-                                new_name[i] = '_';
-                }
-                new_name[i] = '\0';
-        }
-
-        /* XXX -
-         * Since a bunch of boards made it out with weird names like
-         * IO6-fibbbed and IO6P2, we need to look for IO6 in a name and
-         * replace it with "baseio" to avoid confusion in the field.
-	 * We also have to make sure we don't report media_io instead of
-	 * baseio.
-         */
-
-        /* Skip underscores at the beginning of the name */
-        for (compare_ptr = new_name; (*compare_ptr) == '_'; compare_ptr++)
-                ;
-
-	/*
-	 * Check for some names we need to replace.  Early boards
-	 * had junk following the name so check only the first
-	 * characters.
-	 */
-        if (!strncmp(new_name, "io6", 3) || 
-            !strncmp(new_name, "mio", 3) || 
-	    !strncmp(new_name, "media_io", 8))
-		strcpy(new_name, "baseio");
-	else if (!strncmp(new_name, "divo", 4))
-		strcpy(new_name, "divo") ;
-
-}
-
-/* Check if the given board corresponds to the global 
- * master io6
- */
-int
-is_master_baseio(nasid_t nasid,moduleid_t module,slotid_t slot)
-{
-	lboard_t	*board;
-
-/* If this works then look for callers of is_master_baseio()
- * (e.g. iograph.c) and let them pass in a slot if they want
- */
-	board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), module);
-
-#ifndef _STANDALONE
-	{
-		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
-
-		if (!board && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-			board = find_lboard_module((lboard_t *)
-				    KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				    module);
-	}
-#endif
-	if (!board)
-		return(0);
-	return(board->brd_flags & GLOBAL_MASTER_IO6);
-}
-/*
- * Find the lboard structure and get the board name.
- * If we can't find the structure or it's too low a revision,
- * use default name.
- */
-lboard_t *
-get_board_name(nasid_t nasid, moduleid_t mod, slotid_t slot, char *name)
-{
-	lboard_t *brd;
-
-	brd = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid),
-				  mod, slot);
-
-#ifndef _STANDALONE
-	{
-		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
-
-		if (!brd && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-			brd = find_lboard_modslot((lboard_t *)
-				KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				mod, slot);
-	}
-#endif
-
-	if (!brd || (brd->brd_sversion < 2)) {
-		strcpy(name, EDGE_LBL_XWIDGET);
-	} else {
-		nic_name_convert(brd->brd_name, name);
-	}
-
-	/*
- 	 * PV # 540860
-	 * If the name is not 'baseio' 
-	 * get the lowest of all the names in the nic string.
-	 * This is needed for boards like divo, which can have
-	 * a bunch of daughter cards, but would like to be called
-	 * divo. We could do this for baseio 
- 	 * but it has some special case names that we would not
- 	 * like to disturb at this point.
-	 */
-
-	/* gfx boards don't need any of this name scrambling */
-	if (brd && (KLCLASS(brd->brd_type) == KLCLASS_GFX)) {
-		return(brd);
-	}
-
-	if (!(!strcmp(name, "baseio") )) {
-		if (brd) {
-			sort_nic_names(brd) ;
-			/* Convert to small case, '-' to '_' etc */
-			nic_name_convert(brd->brd_name, name) ;
-		}
-	}
-
-	return(brd);
-}
-
-/*
- * get_actual_nasid
- *
- *	Completely disabled brds have their klconfig on 
- *	some other nasid as they have no memory. But their
- *	actual nasid is hidden in the klconfig. Use this
- *	routine to get it. Works for normal boards too.
- */
-nasid_t
-get_actual_nasid(lboard_t *brd)
-{
-	klhub_t	*hub ;
-
-	if (!brd)
-		return INVALID_NASID ;
-
-	/* find out if we are a completely disabled brd. */
-
-        hub  = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-	if (!hub)
-                return INVALID_NASID ;
-	if (!(hub->hub_info.flags & KLINFO_ENABLE))	/* disabled node brd */
-		return hub->hub_info.physid ;
-	else
-		return brd->brd_nasid ;
-}
-
-int
-xbow_port_io_enabled(nasid_t nasid, int link)
-{
-	lboard_t *brd;
-	klxbow_t *xbow_p;
-
-	/*
-	 * look for boards that might contain an xbow or xbridge
-	 */
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW);
-	if (brd == NULL) return 0;
-		
-	if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW))
-	    == NULL)
-	    return 0;
-
-	if (!XBOW_PORT_TYPE_IO(xbow_p, link) || !XBOW_PORT_IS_ENABLED(xbow_p, link))
-	    return 0;
-
-	return 1;
-}
-
-void
-board_to_path(lboard_t *brd, char *path)
-{
-	moduleid_t modnum;
-	char *board_name;
-
-	ASSERT(brd);
-
-	switch (KLCLASS(brd->brd_type)) {
-
-		case KLCLASS_NODE:
-			board_name = EDGE_LBL_NODE;
-			break;
-		case KLCLASS_ROUTER:
-			if (brd->brd_type == KLTYPE_META_ROUTER) {
-				board_name = EDGE_LBL_META_ROUTER;
-				hasmetarouter++;
-			} else if (brd->brd_type == KLTYPE_REPEATER_ROUTER) {
-				board_name = EDGE_LBL_REPEATER_ROUTER;
-				hasmetarouter++;
-			} else
-				board_name = EDGE_LBL_ROUTER;
-			break;
-		case KLCLASS_MIDPLANE:
-			board_name = EDGE_LBL_MIDPLANE;
-			break;
-		case KLCLASS_IO:
-			board_name = EDGE_LBL_IO;
-			break;
-		case KLCLASS_IOBRICK:
-			if (brd->brd_type == KLTYPE_PBRICK)
-				board_name = EDGE_LBL_PBRICK;
-			else if (brd->brd_type == KLTYPE_IBRICK)
-				board_name = EDGE_LBL_IBRICK;
-			else if (brd->brd_type == KLTYPE_XBRICK)
-				board_name = EDGE_LBL_XBRICK;
-			else
-				board_name = EDGE_LBL_IOBRICK;
-			break;
-		default:
-			board_name = EDGE_LBL_UNKNOWN;
-	}
-			
-	modnum = brd->brd_module;
-
-	/* ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE); */
-if ((modnum == MODULE_UNKNOWN) || (modnum == INVALID_MODULE)) {
-	modnum = ++module_number;
-}
-#ifdef __ia64
-	{
-		char	buffer[16];
-		memset(buffer, 0, 16);
-		format_module_id(buffer, modnum, MODULE_FORMAT_BRIEF);
-		sprintf(path, EDGE_LBL_MODULE "/%s/%s", buffer, board_name);
-	}
-#else
-	sprintf(path, "%H/%s", modnum, board_name);
-#endif
-}
-
-/*
- * Get the module number for a NASID.
- */
-moduleid_t
-get_module_id(nasid_t nasid)
-{
-	lboard_t *brd;
-
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-
-	if (!brd)
-		return INVALID_MODULE;
-	else
-		return brd->brd_module;
-}
-
-
-#define MHZ	1000000
-
-
-/* Get the canonical hardware graph name for the given pci component
- * on the given io board.
- */
-void
-device_component_canonical_name_get(lboard_t 	*brd,
-				    klinfo_t 	*component,
-				    char 	*name)
-{
-	moduleid_t 	modnum;
-	slotid_t 	slot;
-	char 		board_name[20];
-
-	ASSERT(brd);
-
-	/* Get the module number of this board */
-	modnum = brd->brd_module;
-
-	/* Convert the [ CLASS | TYPE ] kind of slotid
-	 * into a string 
-	 */
-	slot = brd->brd_slot;
-	ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE);
-
-	/* Get the io board name  */
-	if (!brd || (brd->brd_sversion < 2)) {
-		strcpy(name, EDGE_LBL_XWIDGET);
-	} else {
-		nic_name_convert(brd->brd_name, board_name);
-	}
-
-	/* Give out the canonical  name of the pci device*/
-	sprintf(name, 
-		"/dev/hw/"EDGE_LBL_MODULE "/%x/"EDGE_LBL_SLOT"/%s/"
-		EDGE_LBL_PCI"/%d", 
-		modnum, board_name,KLCF_BRIDGE_W_ID(component));
-}
-
-/*
- * Get the serial number of the main  component of a board
- * Returns 0 if a valid serial number is found
- * 1 otherwise.
- * Assumptions: Nic manufacturing string  has the following format
- *			*Serial:<serial_number>;*
- */
-static int
-component_serial_number_get(lboard_t 		*board,
-			    klconf_off_t 	mfg_nic_offset,
-			    char		*serial_number,
-			    char		*key_pattern)
-{
-
-	char	*mfg_nic_string;
-	char	*serial_string,*str;
-	int	i;
-	char	*serial_pattern = "Serial:";
-
-	/* We have an error on a null mfg nic offset */
-	if (!mfg_nic_offset)
-		return(1);
-	/* Get the hub's manufacturing nic information
-	 * which is in the form of a pre-formatted string
-	 */
-	mfg_nic_string = 
-		(char *)NODE_OFFSET_TO_K0(NASID_GET(board),
-					  mfg_nic_offset);
-	/* There is no manufacturing nic info */
-	if (!mfg_nic_string)
-		return(1);
-
-	str = mfg_nic_string;
-	/* Look for the key pattern first (if it is  specified)
-	 * and then print the serial number corresponding to that.
-	 */
-	if (strcmp(key_pattern,"") && 
-	    !(str = strstr(mfg_nic_string,key_pattern)))
-		return(1);
-
-	/* There is no serial number info in the manufacturing
-	 * nic info
-	 */
-	if (!(serial_string = strstr(str,serial_pattern)))
-		return(1);
-
-	serial_string = serial_string + strlen(serial_pattern);
-	/*  Copy the serial number information from the klconfig */
-	i = 0;
-	while (serial_string[i] != ';') {
-		serial_number[i] = serial_string[i];
-		i++;
-	}
-	serial_number[i] = 0;
-	
-	return(0);
-}
-/*
- * Get the serial number of a board
- * Returns 0 if a valid serial number is found
- * 1 otherwise.
- */
-
-int
-board_serial_number_get(lboard_t *board,char *serial_number)
-{
-	ASSERT(board && serial_number);
-	if (!board || !serial_number)
-		return(1);
-
-	strcpy(serial_number,"");
-	switch(KLCLASS(board->brd_type)) {
-	case KLCLASS_CPU: {	/* Node board */
-		klhub_t	*hub;
-		
-		/* Get the hub component information */
-		hub = (klhub_t *)find_first_component(board,
-						      KLSTRUCT_HUB);
-		/* If we don't have a hub component on an IP27
-		 * then we have a weird klconfig.
-		 */
-		if (!hub)
-			return(1);
-		/* Get the serial number information from
-		 * the hub's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						hub->hub_mfg_nic,
-						serial_number,
-						"IP37"))
-				return(1);
-		break;
-	}
-	case KLCLASS_IO: {	/* IO board */
-		if (KLTYPE(board->brd_type) == KLTYPE_TPU) {
-		/* Special case for TPU boards */
-			kltpu_t *tpu;	
-		
-			/* Get the tpu component information */
-			tpu = (kltpu_t *)find_first_component(board,
-						      KLSTRUCT_TPU);
-			/* If we don't have a tpu component on a tpu board
-			 * then we have a weird klconfig.
-			 */
-			if (!tpu)
-				return(1);
-			/* Get the serial number information from
-			 * the tpu's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						tpu->tpu_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		} else  if ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) ||
-		            (KLTYPE(board->brd_type) == KLTYPE_GSN_B)) {
-		/* Special case for GSN boards */
-			klgsn_t *gsn;	
-		
-			/* Get the gsn component information */
-			gsn = (klgsn_t *)find_first_component(board,
-			      ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) ?
-					KLSTRUCT_GSN_A : KLSTRUCT_GSN_B));
-			/* If we don't have a gsn component on a gsn board
-			 * then we have a weird klconfig.
-			 */
-			if (!gsn)
-				return(1);
-			/* Get the serial number information from
-			 * the gsn's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						gsn->gsn_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		} else {
-		     	klbri_t	*bridge;
-		
-			/* Get the bridge component information */
-			bridge = (klbri_t *)find_first_component(board,
-							 KLSTRUCT_BRI);
-			/* If we don't have a bridge component on an IO board
-			 * then we have a weird klconfig.
-			 */
-			if (!bridge)
-				return(1);
-			/* Get the serial number information from
-		 	 * the bridge's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						bridge->bri_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		}
-	}
-	case KLCLASS_ROUTER: {	/* Router board */
-		klrou_t *router;	
-		
-		/* Get the router component information */
-		router = (klrou_t *)find_first_component(board,
-							 KLSTRUCT_ROU);
-		/* If we don't have a router component on a router board
-		 * then we have a weird klconfig.
-		 */
-		if (!router)
-			return(1);
-		/* Get the serial number information from
-		 * the router's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						router->rou_mfg_nic,
-						serial_number,
-						""))
-			return(1);
-		break;
-	}
-	case KLCLASS_GFX: {	/* Gfx board */
-		klgfx_t *graphics;
-		
-		/* Get the graphics component information */
-		graphics = (klgfx_t *)find_first_component(board, KLSTRUCT_GFX);
-		/* If we don't have a gfx component on a gfx board
-		 * then we have a weird klconfig.
-		 */
-		if (!graphics)
-			return(1);
-		/* Get the serial number information from
-		 * the graphics's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						graphics->gfx_mfg_nic,
-						serial_number,
-						""))
-			return(1);
-		break;
-	}
-	default:
-		strcpy(serial_number,"");
-		break;
-	}
-	return(0);
-}
-
-#include "asm/sn/sn_private.h"
-
-xwidgetnum_t
-nodevertex_widgetnum_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, 
-			     (arbitrary_info_t *) &hubinfo_p);
-	return(hubinfo_p->h_widgetid);
-}
-
-devfs_handle_t
-nodevertex_xbow_peer_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-	nasid_t xbow_peer_nasid;
-	cnodeid_t xbow_peer;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO,
-				     (arbitrary_info_t *) &hubinfo_p);
-	xbow_peer_nasid = hubinfo_p->h_nodepda->xbow_peer;
-	if(xbow_peer_nasid == INVALID_NASID) 
-			return ( (devfs_handle_t)-1);
-	xbow_peer = NASID_TO_COMPACT_NODEID(xbow_peer_nasid);
-	return(NODEPDA(xbow_peer)->node_vertex);
-}
-
-/* NIC Sorting Support */
-
-#define MAX_NICS_PER_STRING 	32
-#define MAX_NIC_NAME_LEN	32
-
-static char *
-get_nic_string(lboard_t *lb)
-{
-        int         	i;
-        klinfo_t    	*k = NULL ;
-    	klconf_off_t    mfg_off = 0 ;
-    	char            *mfg_nic = NULL ;
-
-        for (i = 0; i < KLCF_NUM_COMPS(lb); i++) {
-                k = KLCF_COMP(lb, i) ;
-                switch(k->struct_type) {
-                        case KLSTRUCT_BRI:
-            			mfg_off = ((klbri_t *)k)->bri_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_HUB:
-            			mfg_off = ((klhub_t *)k)->hub_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_ROU:
-            			mfg_off = ((klrou_t *)k)->rou_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GFX:
-            			mfg_off = ((klgfx_t *)k)->gfx_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_TPU:
-            			mfg_off = ((kltpu_t *)k)->tpu_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GSN_A:
-                        case KLSTRUCT_GSN_B:
-            			mfg_off = ((klgsn_t *)k)->gsn_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_XTHD:
-                                mfg_off = ((klxthd_t *)k)->xthd_mfg_nic ;
-                                break;
-
-			default:
-				mfg_off = 0 ;
-                                break ;
-                }
-		if (mfg_off)
-			break ;
-        }
-
-	if ((mfg_off) && (k))
-		mfg_nic = (char *)NODE_OFFSET_TO_K0(k->nasid, mfg_off) ;
-
-        return mfg_nic ;
-}
-
-char *
-get_first_string(char **ptrs, int n)
-{
-        int     i ;
-        char    *tmpptr ;
-
-        if ((ptrs == NULL) || (n == 0))
-                return NULL ;
-
-        tmpptr = ptrs[0] ;
-
-        if (n == 1)
-                return tmpptr ;
-
-        for (i = 0 ; i < n ; i++) {
-                if (strcmp(tmpptr, ptrs[i]) > 0)
-                        tmpptr = ptrs[i] ;
-        }
-
-        return tmpptr ;
-}
-
-int
-get_ptrs(char *idata, char **ptrs, int n, char *label)
-{
-        int     i = 0 ;
-        char    *tmp = idata ;
-
-        if ((ptrs == NULL) || (idata == NULL) || (label == NULL) || (n == 0))
-                return 0 ;
-
-        while  ( (tmp = strstr(tmp, label)) ){
-                tmp += strlen(label) ;
-                /* check for empty name field, and last NULL ptr */
-                if ((i < (n-1)) && (*tmp != ';')) {
-                        ptrs[i++] = tmp ;
-                }
-        }
-
-        ptrs[i] = NULL ;
-
-        return i ;
-}
-
-/*
- * sort_nic_names
- *
- * 	Does not really do sorting. Find the alphabetically lowest
- *	name among all the nic names found in a nic string.
- *
- * Return:
- *	Nothing
- *
- * Side Effects:
- *
- *	lb->brd_name gets the new name found
- */
-
-static void
-sort_nic_names(lboard_t *lb)
-{
-	char 	*nic_str ;
-        char    *ptrs[MAX_NICS_PER_STRING] ;
-        char    name[MAX_NIC_NAME_LEN] ;
-        char    *tmp, *tmp1 ;
-
-	*name = 0 ;
-
-	/* Get the nic pointer from the lb */
-
-	if ((nic_str = get_nic_string(lb)) == NULL)
-		return ;
-
-        tmp = get_first_string(ptrs,
-                        get_ptrs(nic_str, ptrs, MAX_NICS_PER_STRING, "Name:")) ;
-
-        if (tmp == NULL)
-		return ;
-
-        if  ( (tmp1 = strchr(tmp, ';')) ){
-                strncpy(name, tmp, tmp1-tmp) ;
-                name[tmp1-tmp] = 0 ;
-        } else {
-                strncpy(name, tmp, (sizeof(name) -1)) ;
-                name[sizeof(name)-1] = 0 ;
-        }
-
-	strcpy(lb->brd_name, name) ;
-}
-
-
-
-char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#012345";
-
-
-/*
- * Format a module id for printing.
- */
-void
-format_module_id(char *buffer, moduleid_t m, int fmt)
-{
-	int rack, position;
-	char brickchar;
-
-	rack = MODULE_GET_RACK(m);
-	ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES);
-	brickchar = MODULE_GET_BTCHAR(m);
-	position = MODULE_GET_BPOS(m);
-
-	if (fmt == MODULE_FORMAT_BRIEF) {
-	    /* Brief module number format, eg. 002c15 */
-
-	    /* Decompress the rack number */
-	    *buffer++ = '0' + RACK_GET_CLASS(rack);
-	    *buffer++ = '0' + RACK_GET_GROUP(rack);
-	    *buffer++ = '0' + RACK_GET_NUM(rack);
-
-	    /* Add the brick type */
-	    *buffer++ = brickchar;
-	}
-	else if (fmt == MODULE_FORMAT_LONG) {
-	    /* Fuller hwgraph format, eg. rack/002/bay/15 */
-
-	    strcpy(buffer, EDGE_LBL_RACK "/");  buffer += strlen(buffer);
-
-	    *buffer++ = '0' + RACK_GET_CLASS(rack);
-	    *buffer++ = '0' + RACK_GET_GROUP(rack);
-	    *buffer++ = '0' + RACK_GET_NUM(rack);
-
-	    strcpy(buffer, "/" EDGE_LBL_RPOS "/");  buffer += strlen(buffer);
-	}
-
-	/* Add the bay position, using at least two digits */
-	if (position < 10)
-	    *buffer++ = '0';
-	sprintf(buffer, "%d", position);
-
-}
-
-/*
- * Parse a module id, in either brief or long form.
- * Returns < 0 on error.
- * The long form does not include a brick type, so it defaults to 0 (CBrick)
- */
-int
-parse_module_id(char *buffer)
-{
-	unsigned int	v, rack, bay, type, form;
-	moduleid_t	m;
-	char 		c;
-
-	if (strstr(buffer, EDGE_LBL_RACK "/") == buffer) {
-		form = MODULE_FORMAT_LONG;
-		buffer += strlen(EDGE_LBL_RACK "/");
-
-		/* A long module ID must be exactly 5 non-template chars. */
-		if (strlen(buffer) != strlen("/" EDGE_LBL_RPOS "/") + 5)
-			return -1;
-	}
-	else {
-		form = MODULE_FORMAT_BRIEF;
-
-		/* A brief module id must be exactly 6 characters */
-		if (strlen(buffer) != 6)
-			return -2;
-	}
-
-	/* The rack number must be exactly 3 digits */
-	if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && isdigit(buffer[2])))
-		return -3;
-
-	rack = 0;
-	v = *buffer++ - '0';
-	if (v > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-		return -4;
-	RACK_ADD_CLASS(rack, v);
-
-	v = *buffer++ - '0';
-	if (v > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-		return -5;
-	RACK_ADD_GROUP(rack, v);
-
-	v = *buffer++ - '0';
-	/* rack numbers are 1-based */
-	if (v-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-		return -6;
-	RACK_ADD_NUM(rack, v);
-
-	if (form == MODULE_FORMAT_BRIEF) {
-		/* Next should be a module type character.  Accept ucase or lcase. */
-		c = *buffer++;
-		if (!isalpha(c))
-			return -7;
-
-		/* strchr() returns a pointer into brick_types[], or NULL */
-		type = (unsigned int)(strchr(brick_types, tolower(c)) - brick_types);
-		if (type > MODULE_BTYPE_MASK >> MODULE_BTYPE_SHFT)
-			return -8;
-	}
-	else {
-		/* Hardcode the module type, and skip over the boilerplate */
-		type = MODULE_CBRICK;
-
-		if (strstr(buffer, "/" EDGE_LBL_RPOS "/") != buffer)
-			return -9;
-
-		buffer += strlen("/" EDGE_LBL_RPOS "/");
-	}
-		
-	/* The bay number is last.  Make sure it's exactly two digits */
-
-	if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && !buffer[2]))
-		return -10;
-
-	bay = 10 * (buffer[0] - '0') + (buffer[1] - '0');
-
-	if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-		return -11;
-
-	m = RBT_TO_MODULE(rack, bay, type);
-
-	/* avoid sign extending the moduleid_t */
-	return (int)(unsigned short)m;
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/klgraph.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/klgraph.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/klgraph.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/klgraph.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,940 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * klgraph.c-
- *      This file specifies the interface between the kernel and the PROM's
- *      configuration data structures.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/kldir.h>
-#include <asm/sn/gda.h> 
-#include <asm/sn/klconfig.h>
-#include <asm/sn/router.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/hcl_util.h>
-
-/* #define KLGRAPH_DEBUG 1 */
-#ifdef KLGRAPH_DEBUG
-#define GRPRINTF(x)	printk x
-#define CE_GRPANIC	CE_PANIC
-#else
-#define GRPRINTF(x)
-#define CE_GRPANIC	CE_PANIC
-#endif
-
-#include <asm/sn/sn_private.h>
-
-extern char arg_maxnodes[];
-extern u64 klgraph_addr[];
-
-/*
- * Support for verbose inventory via hardware graph. 
- * klhwg_invent_alloc allocates the necessary size of inventory information
- * and fills in the generic information.
- */
-invent_generic_t *
-klhwg_invent_alloc(cnodeid_t cnode, int class, int size)
-{
-	invent_generic_t *invent;
-
-	invent = kern_malloc(size);
-	if (!invent) return NULL;
-	
-	invent->ig_module = NODE_MODULEID(cnode);
-	invent->ig_slot = SLOTNUM_GETSLOT(NODE_SLOTID(cnode));
-	invent->ig_invclass = class;
-
-	return invent;
-}
-
-/*
- * Add detailed disabled cpu inventory info to the hardware graph.
- */
-void
-klhwg_disabled_cpu_invent_info(devfs_handle_t cpuv,
-                               cnodeid_t cnode,
-                               klcpu_t *cpu, slotid_t slot)
-{
-	invent_cpuinfo_t *cpu_invent;
-	diag_inv_t       *diag_invent;
-
-	cpu_invent = (invent_cpuinfo_t *)
-	klhwg_invent_alloc(cnode, INV_PROCESSOR, sizeof(invent_cpuinfo_t));
-	if (!cpu_invent)
-		return;
-
-	/* Diag information on this processor */
-	diag_invent = (diag_inv_t *)
-	klhwg_invent_alloc(cnode, INV_CPUDIAGVAL, sizeof(diag_inv_t));
-
-	if (!diag_invent)
-		return;
-
-
-	/* Disabled CPU */
-	cpu_invent->ic_gen.ig_flag = 0x0;
-	cpu_invent->ic_gen.ig_slot = slot;
-	cpu_invent->ic_cpu_info.cpuflavor = cpu->cpu_prid;
-	cpu_invent->ic_cpu_info.cpufq = cpu->cpu_speed;
-	cpu_invent->ic_cpu_info.sdfreq = cpu->cpu_scachespeed;
-
-	cpu_invent->ic_cpu_info.sdsize = cpu->cpu_scachesz;
-	cpu_invent->ic_cpuid = cpu->cpu_info.virtid;
-	cpu_invent->ic_slice = cpu->cpu_info.physid;
-
-	/* Disabled CPU label */
-	hwgraph_info_add_LBL(cpuv, INFO_LBL_DETAIL_INVENT,
-			(arbitrary_info_t) cpu_invent);
-	hwgraph_info_export_LBL(cpuv, INFO_LBL_DETAIL_INVENT,
-			sizeof(invent_cpuinfo_t));
-
-	/* Diagval label - stores reason for disable +{virt,phys}id +diagval*/
-	hwgraph_info_add_LBL(cpuv, INFO_LBL_DIAGVAL,
-			(arbitrary_info_t) diag_invent);
-
-	hwgraph_info_export_LBL(cpuv, INFO_LBL_DIAGVAL,
-			sizeof(diag_inv_t));
-}
-
-/*
- * Add detailed cpu inventory info to the hardware graph.
- */
-void
-klhwg_cpu_invent_info(devfs_handle_t cpuv,
-			cnodeid_t cnode,
-			klcpu_t *cpu)
-{
-	invent_cpuinfo_t *cpu_invent;
-
-	cpu_invent = (invent_cpuinfo_t *)
-		klhwg_invent_alloc(cnode, INV_PROCESSOR, sizeof(invent_cpuinfo_t));
-	if (!cpu_invent)
-		return;
-
-	if (KLCONFIG_INFO_ENABLED((klinfo_t *)cpu))
-		cpu_invent->ic_gen.ig_flag = INVENT_ENABLED;
-	else
-		cpu_invent->ic_gen.ig_flag = 0x0;
-
-	cpu_invent->ic_cpu_info.cpuflavor = cpu->cpu_prid;
-	cpu_invent->ic_cpu_info.cpufq = cpu->cpu_speed;
-	cpu_invent->ic_cpu_info.sdfreq = cpu->cpu_scachespeed;
-
-	cpu_invent->ic_cpu_info.sdsize = cpu->cpu_scachesz;
-	cpu_invent->ic_cpuid = cpu->cpu_info.virtid;
-	cpu_invent->ic_slice = cpu_physical_id_to_slice(cpu->cpu_info.virtid);
-
-	hwgraph_info_add_LBL(cpuv, INFO_LBL_DETAIL_INVENT,
-			(arbitrary_info_t) cpu_invent);
-	hwgraph_info_export_LBL(cpuv, INFO_LBL_DETAIL_INVENT,
-			sizeof(invent_cpuinfo_t));
-}
-
-/* 
- * Add information about the baseio prom version number
- * as a part of detailed inventory info in the hwgraph.
- */
-void
-klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode)
-{
-	invent_miscinfo_t	*baseio_inventory;
-	unsigned char		version = 0,revision = 0;
-
-	/* Allocate memory for the "detailed inventory" info
-	 * for the baseio
-	 */
-	baseio_inventory = (invent_miscinfo_t *) 
-		klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t));
-	baseio_inventory->im_type = INV_IO6PROM;
-	/* Store the revision info  in the inventory */
-	baseio_inventory->im_version = version;
-	baseio_inventory->im_rev = revision;
-	/* Put the inventory info in the hardware graph */
-	hwgraph_info_add_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, 
-			     (arbitrary_info_t) baseio_inventory);
-	/* Make the information available to the user programs
-	 * thru hwgfs.
-	 */
-        hwgraph_info_export_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT,
-				sizeof(invent_miscinfo_t));
-}
-
-char	*hub_rev[] = {
-	"0.0",
-	"1.0",
-	"2.0",
-	"2.1",
-	"2.2",
-	"2.3"
-};
-
-/*
- * Add detailed cpu inventory info to the hardware graph.
- */
-void
-klhwg_hub_invent_info(devfs_handle_t hubv,
-		      cnodeid_t cnode, 
-		      klhub_t *hub)
-{
-	invent_miscinfo_t *hub_invent;
-
-	hub_invent = (invent_miscinfo_t *) 
-	    klhwg_invent_alloc(cnode, INV_MISC, sizeof(invent_miscinfo_t));
-	if (!hub_invent)
-	    return;
-
-	if (KLCONFIG_INFO_ENABLED((klinfo_t *)hub))
-	    hub_invent->im_gen.ig_flag = INVENT_ENABLED;
-
-	hub_invent->im_type = INV_HUB;
-	hub_invent->im_rev = hub->hub_info.revision;
-	hub_invent->im_speed = hub->hub_speed;
-	hwgraph_info_add_LBL(hubv, INFO_LBL_DETAIL_INVENT, 
-			     (arbitrary_info_t) hub_invent);
-        hwgraph_info_export_LBL(hubv, INFO_LBL_DETAIL_INVENT,
-				sizeof(invent_miscinfo_t));
-}
-
-/* ARGSUSED */
-void
-klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode)
-{
-	devfs_handle_t myhubv;
-	devfs_handle_t hub_mon;
-	devfs_handle_t synergy;
-	devfs_handle_t fsb0;
-	devfs_handle_t fsb1;
-	int rc;
-	extern struct file_operations hub_mon_fops;
-
-	GRPRINTF(("klhwg_add_hub: adding %s\n", EDGE_LBL_HUB));
-
-	(void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv);
-	rc = device_master_set(myhubv, node_vertex);
-
-	/*
-	 * hub perf stats.
-	 */
-	rc = hwgraph_info_add_LBL(myhubv, INFO_LBL_HUB_INFO,
-                        (arbitrary_info_t)(&NODEPDA(cnode)->hubstats));
-
-	if (rc != GRAPH_SUCCESS) {
-		printk(KERN_WARNING  "klhwg_add_hub: Can't add hub info label 0x%p, code %d",
-			(void *)myhubv, rc);
-	}
-
-	klhwg_hub_invent_info(myhubv, cnode, hub);
-
-	hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &hub_mon_fops,
-	    (void *)(long)cnode);
-
-	init_hub_stats(cnode, NODEPDA(cnode));
-
-	/*
-	 * synergy perf
-	 */
-	(void) hwgraph_path_add(myhubv, EDGE_LBL_SYNERGY, &synergy);
-	(void) hwgraph_path_add(synergy, "0", &fsb0);
-	(void) hwgraph_path_add(synergy, "1", &fsb1);
-
-	fsb0 = hwgraph_register(fsb0, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 0));
-
-	fsb1 = hwgraph_register(fsb1, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 1));
-}
-
-/* ARGSUSED */
-void
-klhwg_add_disabled_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot)
-{
-        devfs_handle_t my_cpu;
-        char name[120];
-        cpuid_t cpu_id;
-	nasid_t nasid;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-        cpu_id = nasid_slice_to_cpuid(nasid, cpu->cpu_info.physid);
-        if(cpu_id != -1){
-		sprintf(name, "%s/%s/%c", EDGE_LBL_DISABLED, EDGE_LBL_CPU, 'a' + cpu->cpu_info.physid);
-		(void) hwgraph_path_add(node_vertex, name, &my_cpu);
-
-		mark_cpuvertex_as_cpu(my_cpu, cpu_id);
-		device_master_set(my_cpu, node_vertex);
-
-		klhwg_disabled_cpu_invent_info(my_cpu, cnode, cpu, slot);
-		return;
-        }
-}
-
-/* ARGSUSED */
-void
-klhwg_add_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu)
-{
-        devfs_handle_t my_cpu, cpu_dir;
-        char name[120];
-        cpuid_t cpu_id;
-	nasid_t nasid;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-        cpu_id = nasid_slice_to_cpuid(nasid, cpu->cpu_info.physid);
-
-        sprintf(name, "%s/%d/%c",
-                EDGE_LBL_CPUBUS,
-                0,
-                'a' + cpu->cpu_info.physid);
-
-        GRPRINTF(("klhwg_add_cpu: adding %s to vertex 0x%x\n", name, node_vertex));
-        (void) hwgraph_path_add(node_vertex, name, &my_cpu);
-        mark_cpuvertex_as_cpu(my_cpu, cpu_id);
-        device_master_set(my_cpu, node_vertex);
-
-        /* Add an alias under the node's CPU directory */
-        if (hwgraph_edge_get(node_vertex, EDGE_LBL_CPU, &cpu_dir) == GRAPH_SUCCESS) {
-                sprintf(name, "%c", 'a' + cpu->cpu_info.physid);
-                (void) hwgraph_edge_add(cpu_dir, my_cpu, name);
-        }
-
-        klhwg_cpu_invent_info(my_cpu, cnode, cpu);
-}
-
-
-void
-klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid)
-{
-	lboard_t *brd;
-	klxbow_t *xbow_p;
-	nasid_t hub_nasid;
-	cnodeid_t hub_cnode;
-	int widgetnum;
-	devfs_handle_t xbow_v, hubv;
-	/*REFERENCED*/
-	graph_error_t err;
-
-	if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW)) == NULL)
-			return;
-
-	if (KL_CONFIG_DUPLICATE_BOARD(brd))
-	    return;
-
-	GRPRINTF(("klhwg_add_xbow: adding cnode %d nasid %d xbow edges\n",
-			cnode, nasid));
-
-	if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW))
-	    == NULL)
-	    return;
-
-#ifdef	LATER
-	/*
-	 * We cannot support this function in devfs .. see below where 
-	 * we use hwgraph_path_add() to create this vertex with a known 
-	 * name.
-	 */
-	err = hwgraph_vertex_create(&xbow_v);
-	ASSERT(err == GRAPH_SUCCESS);
-
-	xswitch_vertex_init(xbow_v);
-#endif /* LATER */
-
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
-		if (!XBOW_PORT_TYPE_HUB(xbow_p, widgetnum)) 
-		    continue;
-
-		hub_nasid = XBOW_PORT_NASID(xbow_p, widgetnum);
-		if (hub_nasid == INVALID_NASID) {
-			printk(KERN_WARNING  "hub widget %d, skipping xbow graph\n", widgetnum);
-			continue;
-		}
-
-		hub_cnode = NASID_TO_COMPACT_NODEID(hub_nasid);
-
-		if (is_specified(arg_maxnodes) && hub_cnode == INVALID_CNODEID) {
-			continue;
-		}
-			
-		hubv = cnodeid_to_vertex(hub_cnode);
-
-		err = hwgraph_path_add(hubv, EDGE_LBL_XTALK, &xbow_v);
-                if (err != GRAPH_SUCCESS) {
-                        if (err == GRAPH_DUP)
-                                printk(KERN_WARNING  "klhwg_add_xbow: Check for "
-                                        "working routers and router links!");
-
-                        PRINT_PANIC("klhwg_add_xbow: Failed to add "
-                                "edge: vertex 0x%p to vertex 0x%p,"
-                                "error %d\n",
-                                (void *)hubv, (void *)xbow_v, err);
-                }
-		xswitch_vertex_init(xbow_v); 
-
-		NODEPDA(hub_cnode)->xbow_vhdl = xbow_v;
-
-		/*
-		 * XXX - This won't work is we ever hook up two hubs
-		 * by crosstown through a crossbow.
-		 */
-		if (hub_nasid != nasid) {
-			NODEPDA(hub_cnode)->xbow_peer = nasid;
-			NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer =
-				hub_nasid;
-		}
-
-		GRPRINTF(("klhwg_add_xbow: adding port nasid %d %s to vertex 0x%p\n",
-			hub_nasid, EDGE_LBL_XTALK, hubv));
-
-#ifdef	LATER
-		err = hwgraph_edge_add(hubv, xbow_v, EDGE_LBL_XTALK);
-		if (err != GRAPH_SUCCESS) {
-			if (err == GRAPH_DUP)
-				printk(KERN_WARNING  "klhwg_add_xbow: Check for "
-					"working routers and router links!");
-
-			PRINT_PANIC("klhwg_add_xbow: Failed to add "
-				"edge: vertex 0x%p (0x%p) to vertex 0x%p (0x%p), "
-				"error %d\n",
-				hubv, hubv, xbow_v, xbow_v, err);
-		}
-#endif
-	}
-}
-
-
-/* ARGSUSED */
-void
-klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap)
-{
-	nasid_t nasid;
-	lboard_t *brd;
-	klhub_t *hub;
-	devfs_handle_t node_vertex = NULL;
-	char path_buffer[100];
-	int rv;
-	char *s;
-	int board_disabled = 0;
-	klcpu_t *cpu;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-	GRPRINTF(("klhwg_add_node: Adding cnode %d, nasid %d, brd 0x%p\n",
-                cnode, nasid, brd));
-	ASSERT(brd);
-
-	do {
-		devfs_handle_t cpu_dir;
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(brd, path_buffer);
-
-		GRPRINTF(("klhwg_add_node: adding %s to vertex 0x%p\n",
-			path_buffer, hwgraph_root));
-		rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
-
-		if (rv != GRAPH_SUCCESS)
-			PRINT_PANIC("Node vertex creation failed.  "
-					  "Path == %s",
-				path_buffer);
-
-		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-		ASSERT(hub);
-		if(hub->hub_info.flags & KLINFO_ENABLE)
-			board_disabled = 0;
-		else
-			board_disabled = 1;
-		
-		if(!board_disabled) {
-			mark_nodevertex_as_node(node_vertex,
-					    cnode + board_disabled * numnodes);
-
-			s = dev_to_name(node_vertex, path_buffer, sizeof(path_buffer));
-			NODEPDA(cnode)->hwg_node_name =
-						kmalloc(strlen(s) + 1,
-						GFP_KERNEL);
-			ASSERT_ALWAYS(NODEPDA(cnode)->hwg_node_name != NULL);
-			strcpy(NODEPDA(cnode)->hwg_node_name, s);
-
-			hubinfo_set(node_vertex, NODEPDA(cnode)->pdinfo);
-
-			/* Set up node board's slot */
-			NODEPDA(cnode)->slotdesc = brd->brd_slot;
-
-			/* Set up the module we're in */
-			NODEPDA(cnode)->module_id = brd->brd_module;
-			NODEPDA(cnode)->module = module_lookup(brd->brd_module);
-		}
-
-
-		/* Get the first CPU structure */
-		cpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
-
-		/*
-		* If there's at least 1 CPU, add a "cpu" directory to represent
-		* the collection of all CPUs attached to this node.
-		*/
-		if (cpu) {
-			graph_error_t rv;
-
-			rv = hwgraph_path_add(node_vertex, EDGE_LBL_CPU, &cpu_dir);
-			if (rv != GRAPH_SUCCESS)
-				panic("klhwg_add_node: Cannot create CPU directory\n");
-		}
-
-		/* Add each CPU */
-		while (cpu) {
-			cpuid_t cpu_id;
-			cpu_id = nasid_slice_to_cpuid(nasid,cpu->cpu_info.physid);
-			if (cpu_enabled(cpu_id))
-				klhwg_add_cpu(node_vertex, cnode, cpu);
-			else
-				klhwg_add_disabled_cpu(node_vertex, cnode, cpu, brd->brd_slot);
-
-			cpu = (klcpu_t *)
-				find_component(brd, (klinfo_t *)cpu, KLSTRUCT_CPU);
-		} /* while */
-
-		if(!board_disabled)
-		klhwg_add_hub(node_vertex, hub, cnode);
-		
-		brd = KLCF_NEXT(brd);
-		if (brd)
-			brd = find_lboard(brd, KLTYPE_SNIA);
-		else
-			break;
-	} while(brd);
-}
-
-
-/* ARGSUSED */
-void
-klhwg_add_all_routers(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-	devfs_handle_t node_vertex;
-	char path_buffer[100];
-	int rv;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_add_all_routers: adding router on cnode %d\n",
-			cnode));
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-				KLTYPE_ROUTER);
-
-		if (!brd)
-			/* No routers stored in this node's memory */
-			continue;
-
-		do {
-			ASSERT(brd);
-			GRPRINTF(("Router board struct is %p\n", brd));
-
-			/* Don't add duplicate boards. */
-			if (brd->brd_flags & DUPLICATE_BOARD)
-				continue;
-
-			GRPRINTF(("Router 0x%p module number is %d\n", brd, brd->brd_module));
-			/* Generate a hardware graph path for this board. */
-			board_to_path(brd, path_buffer);
-
-			GRPRINTF(("Router path is %s\n", path_buffer));
-
-			/* Add the router */
-			GRPRINTF(("klhwg_add_all_routers: adding %s to vertex 0x%p\n",
-				path_buffer, hwgraph_root));
-			rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
-
-			if (rv != GRAPH_SUCCESS)
-				PRINT_PANIC("Router vertex creation "
-						  "failed.  Path == %s",
-					path_buffer);
-
-			GRPRINTF(("klhwg_add_all_routers: get next board from 0x%p\n",
-					brd));
-		/* Find the rest of the routers stored on this node. */
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd),
-			 KLTYPE_ROUTER)) );
-
-		GRPRINTF(("klhwg_add_all_routers: Done.\n"));
-	}
-
-}
-
-/* ARGSUSED */
-void
-klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd,
-			 cnodeid_t cnode, nasid_t nasid)
-{
-	klrou_t *router;
-	char path_buffer[50];
-	char dest_path[50];
-	devfs_handle_t router_hndl;
-	devfs_handle_t dest_hndl;
-	int rc;
-	int port;
-	lboard_t *dest_brd;
-
-	GRPRINTF(("klhwg_connect_one_router: Connecting router on cnode %d\n",
-			cnode));
-
-	/* Don't add duplicate boards. */
-	if (brd->brd_flags & DUPLICATE_BOARD) {
-		GRPRINTF(("klhwg_connect_one_router: Duplicate router 0x%p on cnode %d\n",
-			brd, cnode));
-		return;
-	}
-
-	/* Generate a hardware graph path for this board. */
-	board_to_path(brd, path_buffer);
-
-	rc = hwgraph_traverse(hwgraph_root, path_buffer, &router_hndl);
-
-	if (rc != GRAPH_SUCCESS && is_specified(arg_maxnodes))
-			return;
-
-	if (rc != GRAPH_SUCCESS)
-		printk(KERN_WARNING  "Can't find router: %s", path_buffer);
-
-	/* We don't know what to do with multiple router components */
-	if (brd->brd_numcompts != 1) {
-		PRINT_PANIC("klhwg_connect_one_router: %d cmpts on router\n",
-			brd->brd_numcompts);
-		return;
-	}
-
-
-	/* Convert component 0 to klrou_t ptr */
-	router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd),
-					      brd->brd_compts[0]);
-
-	for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
-		/* See if the port's active */
-		if (router->rou_port[port].port_nasid == INVALID_NASID) {
-			GRPRINTF(("klhwg_connect_one_router: port %d inactive.\n",
-				 port));
-			continue;
-		}
-		if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(router->rou_port[port].port_nasid) 
-		    == INVALID_CNODEID) {
-			continue;
-		}
-
-		dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-				router->rou_port[port].port_nasid,
-				router->rou_port[port].port_offset);
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(dest_brd, dest_path);
-
-		rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);
-
-		if (rc != GRAPH_SUCCESS) {
-			if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
-				continue;
-			PRINT_PANIC("Can't find router: %s", dest_path);
-		}
-		GRPRINTF(("klhwg_connect_one_router: Link from %s/%d to %s\n",
-			  path_buffer, port, dest_path));
-
-		sprintf(dest_path, "%d", port);
-
-		rc = hwgraph_edge_add(router_hndl, dest_hndl, dest_path);
-
-		if (rc == GRAPH_DUP) {
-			GRPRINTF(("Skipping port %d. nasid %d %s/%s\n",
-				  port, router->rou_port[port].port_nasid,
-				  path_buffer, dest_path));
-			continue;
-		}
-
-		if (rc != GRAPH_SUCCESS && !is_specified(arg_maxnodes))
-			PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n",
-				path_buffer, dest_path, (void *)dest_hndl, rc);
-		
-	}
-}
-
-
-void
-klhwg_connect_routers(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_connect_routers: Connecting routers on cnode %d\n",
-			cnode));
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-				KLTYPE_ROUTER);
-
-		if (!brd)
-			continue;
-
-		do {
-
-			nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-			klhwg_connect_one_router(hwgraph_root, brd,
-						 cnode, nasid);
-
-		/* Find the rest of the routers stored on this node. */
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
-	}
-}
-
-
-
-void
-klhwg_connect_hubs(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-	klhub_t *hub;
-	lboard_t *dest_brd;
-	devfs_handle_t hub_hndl;
-	devfs_handle_t dest_hndl;
-	char path_buffer[50];
-	char dest_path[50];
-	graph_error_t rc;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_connect_hubs: Connecting hubs on cnode %d\n",
-			cnode));
-
-		brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-		ASSERT(brd);
-
-		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-		ASSERT(hub);
-
-		/* See if the port's active */
-		if (hub->hub_port.port_nasid == INVALID_NASID) {
-			GRPRINTF(("klhwg_connect_hubs: port inactive.\n"));
-			continue;
-		}
-
-		if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(hub->hub_port.port_nasid) == INVALID_CNODEID)
-			continue;
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(brd, path_buffer);
-
-		GRPRINTF(("klhwg_connect_hubs: Hub path is %s.\n", path_buffer));
-		rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl);
-
-		if (rc != GRAPH_SUCCESS)
-			printk(KERN_WARNING  "Can't find hub: %s", path_buffer);
-
-		dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-				hub->hub_port.port_nasid,
-				hub->hub_port.port_offset);
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(dest_brd, dest_path);
-
-		rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);
-
-		if (rc != GRAPH_SUCCESS) {
-			if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
-				continue;
-			PRINT_PANIC("Can't find board: %s", dest_path);
-		} else {
-		
-
-			GRPRINTF(("klhwg_connect_hubs: Link from %s to %s.\n",
-			  path_buffer, dest_path));
-
-			rc = hwgraph_edge_add(hub_hndl, dest_hndl, EDGE_LBL_INTERCONNECT);
-
-			if (rc != GRAPH_SUCCESS)
-				PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n",
-				path_buffer, dest_path, (void *)dest_hndl, rc);
-
-		}
-	}
-}
-
-/* Store the pci/vme disabled board information as extended administrative
- * hints which can later be used by the drivers using the device/driver
- * admin interface. 
- */
-void
-klhwg_device_disable_hints_add(void)
-{
-	cnodeid_t	cnode; 		/* node we are looking at */
-	nasid_t		nasid;		/* nasid of the node */
-	lboard_t	*board;		/* board we are looking at */
-	int		comp_index;	/* component index */
-	klinfo_t	*component;	/* component in the board we are
-					 * looking at 
-					 */
-	char		device_name[MAXDEVNAME];
-	
-	for(cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-		board = (lboard_t *)KL_CONFIG_INFO(nasid);
-		/* Check out all the board info stored  on a node */
-		while(board) {
-			/* No need to look at duplicate boards or non-io 
-			 * boards
-			 */
-			if (KL_CONFIG_DUPLICATE_BOARD(board) ||
-			    KLCLASS(board->brd_type) != KLCLASS_IO) {
-				board = KLCF_NEXT(board);
-				continue;
-			}
-			/* Check out all the components of a board */
-			for (comp_index = 0; 
-			     comp_index < KLCF_NUM_COMPS(board);
-			     comp_index++) {
-				component = KLCF_COMP(board,comp_index);
-				/* If the component is enabled move on to
-				 * the next component
-				 */
-				if (KLCONFIG_INFO_ENABLED(component))
-					continue;
-				/* NOTE : Since the prom only supports
-				 * the disabling of pci devices the following
-				 * piece of code makes sense. 
-				 * Make sure that this assumption is valid
-				 */
-				/* This component is disabled. Store this
-				 * hint in the extended device admin table
-				 */
-				/* Get the canonical name of the pci device */
-				device_component_canonical_name_get(board,
-							    component,
-							    device_name);
-#ifdef DEBUG
-				printf("%s DISABLED\n",device_name);
-#endif				
-			}
-			/* go to the next board info stored on this 
-			 * node 
-			 */
-			board = KLCF_NEXT(board);
-		}
-	}
-}
-
-void
-klhwg_add_all_modules(devfs_handle_t hwgraph_root)
-{
-	cmoduleid_t	cm;
-	char		name[128];
-	devfs_handle_t	vhdl;
-	int		rc;
-	char		buffer[16];
-
-	/* Add devices under each module */
-
-	for (cm = 0; cm < nummodules; cm++) {
-		/* Use module as module vertex fastinfo */
-
-#ifdef __ia64
-		memset(buffer, 0, 16);
-		format_module_id(buffer, modules[cm]->id, MODULE_FORMAT_BRIEF);
-		sprintf(name, EDGE_LBL_MODULE "/%s", buffer);
-#else
-		sprintf(name, EDGE_LBL_MODULE "/%x", modules[cm]->id);
-#endif
-
-		rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
-		ASSERT(rc == GRAPH_SUCCESS);
-		rc = rc;
-
-		hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) modules[cm]);
-
-		/* Add system controller */
-
-#ifdef __ia64
-		sprintf(name,
-			EDGE_LBL_MODULE "/%s/" EDGE_LBL_L1,
-			buffer);
-#else
-		sprintf(name,
-			EDGE_LBL_MODULE "/%x/" EDGE_LBL_L1,
-			modules[cm]->id);
-#endif
-
-		rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
-		ASSERT_ALWAYS(rc == GRAPH_SUCCESS); 
-		rc = rc;
-
-		hwgraph_info_add_LBL(vhdl,
-				     INFO_LBL_ELSC,
-				     (arbitrary_info_t) (__psint_t) 1);
-
-#ifdef	LATER
-		sndrv_attach(vhdl);
-		/*
-		 * We need to call the drivers attach routine ..
-		 */
-		FIXME("klhwg_add_all_modules: Need code to call driver attach.\n");
-#endif
-	}
-}
-
-void
-klhwg_add_all_nodes(devfs_handle_t hwgraph_root)
-{
-	cnodeid_t	cnode;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		klhwg_add_node(hwgraph_root, cnode, NULL);
-	}
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		klhwg_add_xbow(cnode, cnodeid_to_nasid(cnode));
-	}
-
-	/*
-	 * As for router hardware inventory information, we set this
-	 * up in router.c. 
-	 */
-	
-	klhwg_add_all_routers(hwgraph_root);
-	klhwg_connect_routers(hwgraph_root);
-	klhwg_connect_hubs(hwgraph_root);
-
-	/* Go through the entire system's klconfig
-	 * to figure out which pci components have been disabled
-	 */
-	klhwg_device_disable_hints_add();
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/l1.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/l1.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/l1.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/l1.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,3124 +0,0 @@
-/* $Id: l1.c,v 1.2 2002/11/16 02:23:19 steiner Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/* In general, this file is organized in a hierarchy from lower-level
- * to higher-level layers, as follows:
- *
- *	UART routines
- *	Bedrock/L1 "PPP-like" protocol implementation
- *	System controller "message" interface (allows multiplexing
- *		of various kinds of requests and responses with
- *		console I/O)
- *	Console interface:
- *	  "l1_cons", the glue that allows the L1 to act
- *		as the system console for the stdio libraries
- *
- * Routines making use of the system controller "message"-style interface
- * can be found in l1_command.c.
- */
-
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/uart16550.h>
-#include <asm/sn/simulator.h>
-
-
-/* Make all console writes atomic */
-#define SYNC_CONSOLE_WRITE	1
-
-
-/*********************************************************************
- * Hardware-level (UART) driver routines.
- */
-
-/* macros for reading/writing registers */
-
-/* USLD and USSD are needed for SN2 - but since we moving this code out soon ... */
-#define LD(x)			(*(volatile uint64_t *)(x))
-#define USLD(x)			LD(x)			// (*(volatile ushort *)(x))
-#define SD(x, v)        	(LD(x) = (uint64_t) (v))
-#define USSD(x, v)        	SD(x,v)			// (USLD(x) = (ushort) (v))
-
-/* location of uart receive/xmit data register */
-#define L1_UART_BASE(n)		((ulong)REMOTE_HSPEC_ADDR((n), 0x00000080))
-#define LOCK_HUB		REMOTE_HUB_ADDR
-
-#define ADDR_L1_REG(n, r)	( L1_UART_BASE(n) | ( (r) << 3 ) )
-#define READ_L1_UART_REG(n, r)  ( LD(ADDR_L1_REG((n), (r))) )
-
-#define WRITE_L1_UART_REG(n, r, v) ( SD(ADDR_L1_REG((n), (r)), (v)) )
-
-/* upper layer interface calling methods */
-#define SERIAL_INTERRUPT_MODE	0
-#define SERIAL_POLLED_MODE	1
-
-
-/* UART-related #defines */
-
-#define UART_BAUD_RATE		57600
-#define UART_FIFO_DEPTH		16
-#define UART_DELAY_SPAN		10
-#define UART_PUTC_TIMEOUT	50000
-#define UART_INIT_TIMEOUT	100000
-
-/* error codes */
-#define UART_SUCCESS		  0
-#define UART_TIMEOUT		(-1)
-#define UART_LINK		(-2)
-#define UART_NO_CHAR		(-3)
-#define UART_VECTOR		(-4)
-
-#define UART_DELAY(x)		udelay(x)
-
-/* Some debug counters */
-#define L1C_INTERRUPTS		0
-#define L1C_OUR_R_INTERRUPTS	1
-#define L1C_OUR_X_INTERRUPTS	2
-#define L1C_SEND_CALLUPS	3
-#define L1C_RECEIVE_CALLUPS	4
-#define L1C_SET_BAUD		5
-#define L1C_ALREADY_LOCKED	L1C_SET_BAUD
-#define L1C_R_IRQ		6
-#define L1C_R_IRQ_RET		7
-#define L1C_LOCK_TIMEOUTS	8
-#define L1C_LOCK_COUNTER	9
-#define L1C_UNLOCK_COUNTER	10
-#define L1C_REC_STALLS		11
-#define L1C_CONNECT_CALLS	12
-#define L1C_SIZE		L1C_CONNECT_CALLS	/* Set to the last one */
-
-uint64_t L1_collectibles[L1C_SIZE + 1];
-
-
-/*
- *	Some macros for handling Endian-ness
- */
-
-#define COPY_INT_TO_BUFFER(_b, _i, _n)		\
-	{					\
-		_b[_i++] = (_n >> 24) & 0xff;	\
-		_b[_i++] = (_n >> 16) & 0xff;	\
-		_b[_i++] = (_n >>  8) & 0xff;	\
-		_b[_i++] =  _n        & 0xff;	\
-	}
-
-#define COPY_BUFFER_TO_INT(_b, _i, _n)		\
-	{					\
-		_n  = (_b[_i++] << 24) & 0xff;	\
-		_n |= (_b[_i++] << 16) & 0xff;	\
-		_n |= (_b[_i++] <<  8) & 0xff;	\
-		_n |=  _b[_i++]        & 0xff;	\
-	}
-
-#define COPY_BUFFER_TO_BUFFER(_b, _i, _bn)	\
-	{					\
-	    char *_xyz = (char *)_bn;		\
-	    _xyz[3] = _b[_i++];			\
-	    _xyz[2] = _b[_i++];			\
-	    _xyz[1] = _b[_i++];			\
-	    _xyz[0] = _b[_i++];			\
-	}
-
-void snia_kmem_free(void *where, int size);
-
-#define ALREADY_LOCKED		1
-#define NOT_LOCKED		0
-static int early_l1_serial_out(nasid_t, char *, int, int /* defines above*/ );
-
-#define BCOPY(x,y,z)	memcpy(y,x,z)
-
-uint8_t L1_interrupts_connected;		/* Non-zero when we are in interrupt mode */
-
-
-/*
- * Console locking defines and functions.
- *
- */
-
-uint8_t L1_cons_is_inited = 0;			/* non-zero when console is init'd */
-nasid_t Master_console_nasid = (nasid_t)-1;
-extern nasid_t console_nasid;
-
-u64 ia64_sn_get_console_nasid(void);
-
-inline nasid_t
-get_master_nasid(void)
-{
-	nasid_t nasid = Master_console_nasid;
-
-	master_nasid = Master_console_nasid = nasid = 0;
-	if ( nasid == (nasid_t)-1 ) {
-		nasid = (nasid_t)ia64_sn_get_console_nasid();
-		if ( (nasid < 0) || (nasid >= MAX_NASIDS) ) {
-			/* Out of bounds, use local */
-			console_nasid = nasid = get_nasid();
-		}
-		else {
-			/* Got a valid nasid, set the console_nasid */
-			char xx[100];
-/* zzzzzz - force nasid to 0 for now */
-			sprintf(xx, "Master console is set to nasid %d (%d)\n", 0, (int)nasid);
-nasid = 0;
-/* end zzzzzz */
-			xx[99] = (char)0;
-			early_l1_serial_out(nasid, xx, strlen(xx), NOT_LOCKED);
-			Master_console_nasid = console_nasid = nasid;
-		}
-	}
-	return(nasid);
-}
-
-
-
-#define HUB_LOCK		16
-
-#define PRIMARY_LOCK_TIMEOUT    10000000
-#define HUB_LOCK_REG(n)         LOCK_HUB(n, MD_PERF_CNT0)
-
-#define SET_BITS(reg, bits)     SD(reg, LD(reg) |  (bits))
-#define CLR_BITS(reg, bits)     SD(reg, LD(reg) & ~(bits))
-#define TST_BITS(reg, bits)     ((LD(reg) & (bits)) != 0)
-
-#define HUB_TEST_AND_SET(n)	LD(LOCK_HUB(n,LB_SCRATCH_REG3_RZ))
-#define HUB_CLEAR(n)		SD(LOCK_HUB(n,LB_SCRATCH_REG3),0)
-
-#define RTC_TIME_MAX		((rtc_time_t) ~0ULL)
-
-/*
- * primary_lock
- *
- *   Allows CPU's 0-3  to mutually exclude the hub from one another by
- *   obtaining a blocking lock.  Does nothing if only one CPU is active.
- *
- *   This lock should be held just long enough to set or clear a global
- *   lock bit.  After a relatively short timeout period, this routine
- *   figures something is wrong, and steals the lock. It does not set
- *   any other CPU to "dead".
- */
-inline void
-primary_lock(nasid_t nasid)
-{
-	rtc_time_t          expire;
-
-	expire = rtc_time() + PRIMARY_LOCK_TIMEOUT;
-
-	while (HUB_TEST_AND_SET(nasid)) {
-		if (rtc_time() > expire) {
-			HUB_CLEAR(nasid);
-		}
-	}
-}
-
-/*
- * primary_unlock (internal)
- *
- *   Counterpart to primary_lock
- */
-
-inline void
-primary_unlock(nasid_t nasid)
-{
-	HUB_CLEAR(nasid);
-}
-
-/*
- * hub_unlock
- *
- *   Counterpart to hub_lock_timeout and hub_lock
- */
-
-inline void
-hub_unlock(nasid_t nasid, int level)
-{
-	uint64_t mask = 1ULL << level;
-
-	primary_lock(nasid);
-	CLR_BITS(HUB_LOCK_REG(nasid), mask);
-	primary_unlock(nasid);
-}
-
-/*
- * hub_lock_timeout
- *
- *   Uses primary_lock to implement multiple lock levels.
- *
- *   There are 20 lock levels from 0 to 19 (limited by the number of bits
- *   in HUB_LOCK_REG).  To prevent deadlock, multiple locks should be
- *   obtained in order of increasingly higher level, and released in the
- *   reverse order.
- *
- *   A timeout value of 0 may be used for no timeout.
- *
- *   Returns 0 if successful, -1 if lock times out.
- */
-
-inline int
-hub_lock_timeout(nasid_t nasid, int level, rtc_time_t timeout)
-{
-	uint64_t mask = 1ULL << level;
-	rtc_time_t expire = (timeout ?  rtc_time() + timeout : RTC_TIME_MAX);
-	int done    = 0;
-
-	while (! done) {
-		while (TST_BITS(HUB_LOCK_REG(nasid), mask)) {
-			if (rtc_time() > expire)
-				return -1;
-		}
-
-		primary_lock(nasid);
-
-		if (! TST_BITS(HUB_LOCK_REG(nasid), mask)) {
-			SET_BITS(HUB_LOCK_REG(nasid), mask);
-			done = 1;
-		}
-		primary_unlock(nasid);
-	}
-	return 0;
-}
-
-
-#define LOCK_TIMEOUT	(0x1500000 * 1) /* 0x1500000 is ~30 sec */
-
-void
-lock_console(nasid_t nasid)
-{
-	int ret;
-
-	/* If we already have it locked, just return */
-	L1_collectibles[L1C_LOCK_COUNTER]++;
-
-	ret = hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
-	if ( ret != 0 ) {
-		L1_collectibles[L1C_LOCK_TIMEOUTS]++;
-		/* timeout */
-		hub_unlock(nasid, HUB_LOCK);
-		/* If the 2nd lock fails, just pile ahead.... */
-		hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
-		L1_collectibles[L1C_LOCK_TIMEOUTS]++;
-	}
-}
-
-inline void
-unlock_console(nasid_t nasid)
-{
-	L1_collectibles[L1C_UNLOCK_COUNTER]++;
-	hub_unlock(nasid, HUB_LOCK);
-}
-
-
-int 
-get_L1_baud(void)
-{
-    return UART_BAUD_RATE;
-}
-
-
-/* uart driver functions */
-
-static inline void
-uart_delay( rtc_time_t delay_span )
-{
-    UART_DELAY( delay_span );
-}
-
-#define UART_PUTC_READY(n)      (READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE)
-
-static int
-uart_putc( l1sc_t *sc ) 
-{
-    WRITE_L1_UART_REG( sc->nasid, REG_DAT, sc->send[sc->sent] );
-    return UART_SUCCESS;
-}
-
-
-static int
-uart_getc( l1sc_t *sc )
-{
-    u_char lsr_reg = 0;
-    nasid_t nasid = sc->nasid;
-
-    if( (lsr_reg = READ_L1_UART_REG( nasid, REG_LSR )) & 
-	(LSR_RCA | LSR_PARERR | LSR_FRMERR) ) 
-    {
-	if( lsr_reg & LSR_RCA ) 
-	    return( (u_char)READ_L1_UART_REG( nasid, REG_DAT ) );
-	else if( lsr_reg & (LSR_PARERR | LSR_FRMERR) ) {
-	    return UART_LINK;
-	}
-    }
-    return UART_NO_CHAR;
-}
-
-
-#define PROM_SER_CLK_SPEED	12000000
-#define PROM_SER_DIVISOR(x)	(PROM_SER_CLK_SPEED / ((x) * 16))
-
-static void
-uart_init( l1sc_t *sc, int baud )
-{
-#if !defined(USE_SAL_CONSOLE_IO)
-    rtc_time_t expire;
-    int clkdiv;
-    nasid_t nasid;
-
-    clkdiv = PROM_SER_DIVISOR(baud);
-    expire = rtc_time() + UART_INIT_TIMEOUT;
-    nasid = sc->nasid;
-    
-    /* make sure the transmit FIFO is empty */
-    while( !(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XSRE) ) {
-	uart_delay( UART_DELAY_SPAN );
-	if( rtc_time() > expire ) {
-	    break;
-	}
-    }
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* Setup for the proper baud rate */
-    WRITE_L1_UART_REG( nasid, REG_LCR, LCR_DLAB );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_DLH, (clkdiv >> 8) & 0xff );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_DLL, clkdiv & 0xff );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* set operating parameters and set DLAB to 0 */
-
-    /* 8bit, one stop, clear request to send, auto flow control */
-    WRITE_L1_UART_REG( nasid, REG_LCR, LCR_BITS8 | LCR_STOP1 );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_MCR, MCR_RTS | MCR_AFE );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* disable interrupts */
-    WRITE_L1_UART_REG( nasid, REG_ICR, 0x0 );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* enable FIFO mode and reset both FIFOs, trigger on 1 */
-    WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO | RxLVL0);
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-#endif	/* !USE_SAL_CONSOLE_IO */
-}
-
-/* This requires the console lock */
-
-
-static void
-uart_intr_enable( l1sc_t *sc, u_char mask )
-{
-    u_char lcr_reg, icr_reg;
-    nasid_t nasid = sc->nasid;
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* make sure that the DLAB bit in the LCR register is 0
-     */
-    lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
-    lcr_reg &= ~(LCR_DLAB);
-    WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg );
-
-    /* enable indicated interrupts
-     */
-    icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
-    icr_reg |= mask;
-    WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-}
-
-/* This requires the console lock */
-static void
-uart_intr_disable( l1sc_t *sc, u_char mask )
-{
-    u_char lcr_reg, icr_reg;
-    nasid_t nasid = sc->nasid;
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* make sure that the DLAB bit in the LCR register is 0
-     */
-    lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
-    lcr_reg &= ~(LCR_DLAB);
-    WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg );
-
-    /* enable indicated interrupts
-     */
-    icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
-    icr_reg &= mask;
-    WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-}
-
-#define uart_enable_xmit_intr(sc) \
-	uart_intr_enable((sc), ICR_TIEN)
-
-#define uart_disable_xmit_intr(sc) \
-        uart_intr_disable((sc), ~(ICR_TIEN))
-
-#define uart_enable_recv_intr(sc) \
-        uart_intr_enable((sc), ICR_RIEN)
-
-#define uart_disable_recv_intr(sc) \
-        uart_intr_disable((sc), ~(ICR_RIEN))
-
-
-/*********************************************************************
- * Routines for accessing a remote (router) UART
- */
-
-#define READ_RTR_L1_UART_REG(p, n, r, v)		\
-    {							\
-	if( vector_read_node( (p), (n), 0,		\
-			      RR_JBUS1(r), (v) ) ) {	\
-	    return UART_VECTOR;				\
-	}						\
-    }
-
-#define WRITE_RTR_L1_UART_REG(p, n, r, v)		\
-    {							\
-	if( vector_write_node( (p), (n), 0,		\
-			       RR_JBUS1(r), (v) ) ) {	\
-	    return UART_VECTOR;				\
-	}						\
-    }
-
-#define RTR_UART_PUTC_TIMEOUT	UART_PUTC_TIMEOUT*10
-#define RTR_UART_DELAY_SPAN	UART_DELAY_SPAN
-#define RTR_UART_INIT_TIMEOUT	UART_INIT_TIMEOUT*10
-
-static int
-rtr_uart_putc( l1sc_t *sc )
-{
-    uint64_t regval, c;
-    nasid_t nasid = sc->nasid;
-    net_vec_t path = sc->uart;
-    rtc_time_t expire = rtc_time() + RTR_UART_PUTC_TIMEOUT;
-
-    c = (sc->send[sc->sent] & 0xffULL);
-    
-    while( 1 ) 
-    {
-        /* Check for "tx hold reg empty" bit. */
-	READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-	if( regval & LSR_XHRE )
-	{
-	    WRITE_RTR_L1_UART_REG( path, nasid, REG_DAT, c );
-	    return UART_SUCCESS;
-	}
-
-	if( rtc_time() >= expire ) 
-	{
-	    return UART_TIMEOUT;
-	}
-	uart_delay( RTR_UART_DELAY_SPAN );
-    }
-}
-
-
-static int
-rtr_uart_getc( l1sc_t *sc )
-{
-    uint64_t regval;
-    nasid_t nasid = sc->nasid;
-    net_vec_t path = sc->uart;
-
-    READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-    if( regval & (LSR_RCA | LSR_PARERR | LSR_FRMERR) )
-    {
-	if( regval & LSR_RCA )
-	{
-	    READ_RTR_L1_UART_REG( path, nasid, REG_DAT, &regval );
-	    return( (int)regval );
-	}
-	else
-	{
-	    return UART_LINK;
-	}
-    }
-
-    return UART_NO_CHAR;
-}
-
-
-static int
-rtr_uart_init( l1sc_t *sc, int baud )
-{
-    rtc_time_t expire;
-    int clkdiv;
-    nasid_t nasid;
-    net_vec_t path;
-    uint64_t regval;
-
-    clkdiv = PROM_SER_DIVISOR(baud);
-    expire = rtc_time() + RTR_UART_INIT_TIMEOUT;
-    nasid = sc->nasid;
-    path = sc->uart;
-
-    /* make sure the transmit FIFO is empty */
-    while(1) {
-	READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-	if( regval & LSR_XSRE ) {
-	    break;
-	}
-	if( rtc_time() > expire ) {
-	    break;
-	}
-	uart_delay( RTR_UART_DELAY_SPAN );
-    }
-
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_DLAB  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_DLH, (clkdiv >> 8) & 0xff  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_DLL, clkdiv & 0xff  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* set operating parameters and set DLAB to 0 */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_BITS8 | LCR_STOP1  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_MCR, MCR_RTS | MCR_AFE  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* disable interrupts */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_ICR, 0x0  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* enable FIFO mode and reset both FIFOs */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR, FCR_FIFOEN  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR,
-	FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO );
-
-    return 0;
-}
-
-/*********************************************************************
- * locking macros 
- */
-
-#define L1SC_SEND_LOCK(l,p)   { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->send_lock),p); }
-#define L1SC_SEND_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->send_lock), p); }
-#define L1SC_RECV_LOCK(l,p)   { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->recv_lock), p); } 
-#define L1SC_RECV_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->recv_lock), p); }
-
-
-/*********************************************************************
- * subchannel manipulation 
- *
- * The SUBCH_[UN]LOCK macros are used to arbitrate subchannel
- * allocation.  SUBCH_DATA_[UN]LOCK control access to data structures
- * associated with particular subchannels (e.g., receive queues).
- *
- */
-#define SUBCH_LOCK(sc, p)		spin_lock_irqsave( &((sc)->subch_lock), p )
-#define SUBCH_UNLOCK(sc, p)		spin_unlock_irqrestore( &((sc)->subch_lock), p )
-#define SUBCH_DATA_LOCK(sbch, p) 	spin_lock_irqsave( &((sbch)->data_lock), p )
-#define SUBCH_DATA_UNLOCK(sbch, p)	spin_unlock_irqrestore( &((sbch)->data_lock), p )
-
-
-/*
- * set a function to be called for subchannel ch in the event of
- * a transmission low-water interrupt from the uart
- */
-void
-subch_set_tx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
-{
-    unsigned long pl = 0;
-
-    L1SC_SEND_LOCK( sc, pl );
-#if	!defined(SYNC_CONSOLE_WRITE)
-    if ( func && !sc->send_in_use )
-	uart_enable_xmit_intr( sc );
-#endif
-    sc->subch[ch].tx_notify = func;
-    L1SC_SEND_UNLOCK(sc, pl );
-}
-
-/*
- * set a function to be called for subchannel ch when data is received
- */
-void
-subch_set_rx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    SUBCH_DATA_LOCK( subch, pl );
-    sc->subch[ch].rx_notify = func;
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-/*********************************************************************
- * Queue manipulation macros
- *
- *
- */
-#define NEXT(p)         (((p) + 1) & (BRL1_QSIZE-1)) /* assume power of 2 */
-
-#define cq_init(q)      bzero((q), sizeof (*(q)))
-#define cq_empty(q)     ((q)->ipos == (q)->opos)
-#define cq_full(q)      (NEXT((q)->ipos) == (q)->opos)
-#define cq_used(q)      ((q)->opos <= (q)->ipos ?                       \
-                         (q)->ipos - (q)->opos :                        \
-                         BRL1_QSIZE + (q)->ipos - (q)->opos)
-#define cq_room(q)      ((q)->opos <= (q)->ipos ?                       \
-                         BRL1_QSIZE - 1 + (q)->opos - (q)->ipos :       \
-                         (q)->opos - (q)->ipos - 1)
-#define cq_add(q, c)    ((q)->buf[(q)->ipos] = (u_char) (c),            \
-                         (q)->ipos = NEXT((q)->ipos))
-#define cq_rem(q, c)    ((c) = (q)->buf[(q)->opos],                     \
-                         (q)->opos = NEXT((q)->opos))
-#define cq_discard(q)	((q)->opos = NEXT((q)->opos))
-
-#define cq_tent_full(q)	(NEXT((q)->tent_next) == (q)->opos)
-#define cq_tent_len(q)	((q)->ipos <= (q)->tent_next ?			\
-			 (q)->tent_next - (q)->ipos :			\
-			 BRL1_QSIZE + (q)->tent_next - (q)->ipos)
-#define cq_tent_add(q, c)						\
-			((q)->buf[(q)->tent_next] = (u_char) (c),	\
-			 (q)->tent_next = NEXT((q)->tent_next))
-#define cq_commit_tent(q)						\
-			((q)->ipos = (q)->tent_next)
-#define cq_discard_tent(q)						\
-			((q)->tent_next = (q)->ipos)
-
-
-
-
-/*********************************************************************
- * CRC-16 (for checking bedrock/L1 packets).
- *
- * These are based on RFC 1662 ("PPP in HDLC-like framing").
- */
-
-static unsigned short fcstab[256] = {
-      0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
-      0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
-      0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
-      0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
-      0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
-      0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
-      0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
-      0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
-      0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
-      0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
-      0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
-      0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
-      0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
-      0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
-      0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
-      0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
-      0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
-      0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
-      0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
-      0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
-      0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
-      0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
-      0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
-      0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
-      0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
-      0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
-      0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
-      0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
-      0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
-      0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
-      0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
-      0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
-};
-
-#define INIT_CRC	0xFFFF	/* initial CRC value	  */
-#define	GOOD_CRC	0xF0B8	/* "good" final CRC value */
-
-static unsigned short crc16_calc( unsigned short crc, u_char c )
-{
-    return( (crc >> 8) ^ fcstab[(crc ^ c) & 0xff] );
-}
-
-
-/***********************************************************************
- * The following functions implement the PPP-like bedrock/L1 protocol
- * layer.
- *
- */
-
-#define BRL1_FLAG_CH	0x7e
-#define BRL1_ESC_CH	0x7d
-#define BRL1_XOR_CH	0x20
-
-/* L1<->Bedrock packet types */
-#define BRL1_REQUEST    0x00
-#define BRL1_RESPONSE   0x20
-#define BRL1_EVENT      0x40
-
-#define BRL1_PKT_TYPE_MASK      0xE0
-#define BRL1_SUBCH_MASK         0x1F
-
-#define PKT_TYPE(tsb)   ((tsb) & BRL1_PKT_TYPE_MASK)
-#define SUBCH(tsb)	((tsb) & BRL1_SUBCH_MASK)
-
-/* timeouts */
-#define BRL1_INIT_TIMEOUT	500000
-
-/*
- * brl1_discard_packet is a dummy "receive callback" used to get rid
- * of packets we don't want
- */
-void brl1_discard_packet( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &sc->subch[ch];
-
-    sc_cq_t *q = subch->iqp;
-    SUBCH_DATA_LOCK( subch, pl );
-    q->opos = q->ipos;
-    atomic_set(&(subch->packet_arrived), 0);
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-
-/*
- * brl1_send_chars sends the send buffer in the l1sc_t structure
- * out through the uart.  Assumes that the caller has locked the
- * UART (or send buffer in the kernel).
- *
- * This routine doesn't block-- if you want it to, call it in
- * a loop.
- */
-static int
-brl1_send_chars( l1sc_t *sc )
-{
-    /* We track the depth of the C brick's UART's
-     * fifo in software, and only check if the UART is accepting
-     * characters when our count indicates that the fifo should
-     * be full.
-     *
-     * For remote (router) UARTs, we check with the UART before sending every
-     * character.
-     */
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	if( !(sc->fifo_space) && UART_PUTC_READY( sc->nasid ) )
-	    sc->fifo_space = UART_FIFO_DEPTH;
-	
-	while( (sc->sent < sc->send_len) && (sc->fifo_space) ) {
-	    uart_putc( sc );
-	    sc->fifo_space--;
-	    sc->sent++;
-	}
-    }
-    else {
-
-	/* remote (router) UARTs */
-
-	int result;
-	int tries = 0;
-
-	while( sc->sent < sc->send_len ) {
-	    result = sc->putc_f( sc );
-	    if( result >= 0 ) {
-		(sc->sent)++;
-		continue;
-	    }
-	    if( result == UART_TIMEOUT ) {
-		tries++;
-		/* send this character in TIMEOUT_RETRIES... */
-		if( tries < 30 /* TIMEOUT_RETRIES */ ) {
-		    continue;
-		}
-		/* ...or else... */
-		else {
-		    /* ...drop the packet. */
-		    sc->sent = sc->send_len;
-		    return sc->send_len;
-		}
-	    }
-	    if( result < 0 ) {
-		return result;
-	    }
-	}
-    }
-    return sc->sent;
-}
-
-
-/* brl1_send formats up a packet and (at least begins to) send it
- * to the uart.  If the send buffer is in use when this routine obtains
- * the lock, it will behave differently depending on the "wait" parameter.
- * For wait == 0 (most I/O), it will return 0 (as in "zero bytes sent"),
- * hopefully encouraging the caller to back off (unlock any high-level 
- * spinlocks) and allow the buffer some time to drain.  For wait==1 (high-
- * priority I/O along the lines of kernel error messages), we will flush
- * the current contents of the send buffer and beat on the uart
- * until our message has been completely transmitted.
- */
-
-static int
-brl1_send( l1sc_t *sc, char *msg, int len, u_char type_and_subch, int wait )
-{
-    unsigned long pl = 0;
-    int index;
-    int pkt_len = 0;
-    unsigned short crc = INIT_CRC;
-    char *send_ptr = sc->send;
-
-
-    if( sc->send_in_use && !(wait) ) {
-	/* We are in the middle of sending, but can wait until done */
-	return 0;
-    }
-    else if( sc->send_in_use ) {
-	/* buffer's in use, but we're synchronous I/O, so we're going
-	 * to send whatever's in there right now and take the buffer
-	 */
-	int counter = 0;
-
-	if ( sc->uart == BRL1_LOCALHUB_UART )
-		lock_console(sc->nasid);
-	L1SC_SEND_LOCK(sc, pl);
-	while( sc->sent < sc->send_len ) {
-		brl1_send_chars( sc );
-		if ( counter++ > 0xfffff ) {
-			char *str = "Looping waiting for uart to clear (1)\n";
-			early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED);
-			break;
-		}
-	}
-    }
-    else {
-	if ( sc->uart == BRL1_LOCALHUB_UART )
-		lock_console(sc->nasid);
-	L1SC_SEND_LOCK(sc, pl);
-	sc->send_in_use = 1;
-    }
-    *send_ptr++ = BRL1_FLAG_CH;
-    *send_ptr++ = type_and_subch;
-    pkt_len += 2;
-    crc = crc16_calc( crc, type_and_subch );
-
-    /* limit number of characters accepted to max payload size */
-    if( len > (BRL1_QSIZE - 1) )
-	len = (BRL1_QSIZE - 1);
-
-    /* copy in the message buffer (inserting PPP 
-     * framing info where necessary)
-     */
-    for( index = 0; index < len; index++ ) {
-
-	switch( *msg ) {
-	    
-	  case BRL1_FLAG_CH:
-	    *send_ptr++ = BRL1_ESC_CH;
-	    *send_ptr++ = (*msg) ^ BRL1_XOR_CH;
-	    pkt_len += 2;
-	    break;
-	    
-	  case BRL1_ESC_CH:
-	    *send_ptr++ = BRL1_ESC_CH;
-	    *send_ptr++ = (*msg) ^ BRL1_XOR_CH;
-	    pkt_len += 2;
-	    break;
-	    
-	  default:
-	    *send_ptr++ = *msg;
-	    pkt_len++;
-	}
-	crc = crc16_calc( crc, *msg );
-	msg++;
-    }
-    crc ^= 0xffff;
-
-    for( index = 0; index < sizeof(crc); index++ ) {
-	char crc_char = (char)(crc & 0x00FF);
-	if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	    *send_ptr++ = BRL1_ESC_CH;
-	    pkt_len++;
-	    crc_char ^= BRL1_XOR_CH;
-	}
-	*send_ptr++ = crc_char;
-	pkt_len++;
-	crc >>= 8;
-    }
-    
-    *send_ptr++ = BRL1_FLAG_CH;
-    pkt_len++;
-
-    sc->send_len = pkt_len;
-    sc->sent = 0;
-
-    {
-	int counter = 0;
-	do {
-		brl1_send_chars( sc );
-		if ( counter++ > 0xfffff ) {
-			char *str = "Looping waiting for uart to clear (2)\n";
-			early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED);
-			break;
-		}
-	} while( (sc->sent < sc->send_len) && wait );
-    }
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(sc->nasid);
-
-    if( sc->sent == sc->send_len ) {
-	/* success! release the send buffer and call the callup */
-#if	!defined(SYNC_CONSOLE_WRITE)
-	brl1_notif_t callup;
-#endif
-
-	sc->send_in_use = 0;
-	/* call any upper layer that's asked for notification */
-#if	defined(XX_SYNC_CONSOLE_WRITE)
-	/*
-	 * This is probably not a good idea - since the l1_ write func can be called multiple
-	 * time within the callup function.
-	 */
-	callup = subch->tx_notify;
-	if( callup && (SUBCH(type_and_subch) == SC_CONS_SYSTEM) ) {
-		L1_collectibles[L1C_SEND_CALLUPS]++;
-		(*callup)(sc->subch[SUBCH(type_and_subch)].irq_frame.bf_irq,
-				sc->subch[SUBCH(type_and_subch)].irq_frame.bf_dev_id,
-				sc->subch[SUBCH(type_and_subch)].irq_frame.bf_regs, sc, SUBCH(type_and_subch));
-	}
-#endif	/* SYNC_CONSOLE_WRITE */
-    }
-#if	!defined(SYNC_CONSOLE_WRITE)
-    else if ( !wait ) {
-	/* enable low-water interrupts so buffer will be drained */
-	uart_enable_xmit_intr(sc);
-    }
-#endif
-
-    L1SC_SEND_UNLOCK(sc, pl);
-
-    return len;
-}
-
-/* brl1_send_cont is intended to be called as an interrupt service
- * routine.  It sends until the UART won't accept any more characters,
- * or until an error is encountered (in which case we surrender the
- * send buffer and give up trying to send the packet).  Once the
- * last character in the packet has been sent, this routine releases
- * the send buffer and calls any previously-registered "low-water"
- * output routines.
- */
-
-#if	!defined(SYNC_CONSOLE_WRITE)
-
-int
-brl1_send_cont( l1sc_t *sc )
-{
-    unsigned long pl = 0;
-    int done = 0;
-    brl1_notif_t callups[BRL1_NUM_SUBCHANS];
-    brl1_notif_t *callup;
-    brl1_sch_t *subch;
-    int index;
-
-    /*
-     * I'm not sure how I think this is to be handled - whether the lock is held
-     * over the interrupt - but it seems like it is a bad idea....
-     */
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(sc->nasid);
-    L1SC_SEND_LOCK(sc, pl);
-    brl1_send_chars( sc );
-    done = (sc->sent == sc->send_len);
-    if( done ) {
-	sc->send_in_use = 0;
-#if	!defined(SYNC_CONSOLE_WRITE)
-	uart_disable_xmit_intr(sc);
-#endif
-    }
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(sc->nasid);
-    /* Release the lock */
-    L1SC_SEND_UNLOCK(sc, pl);
-
-    return 0;
-}
-#endif	/* SYNC_CONSOLE_WRITE */
-
-/* internal function -- used by brl1_receive to read a character 
- * from the uart and check whether errors occurred in the process.
- */
-static int
-read_uart( l1sc_t *sc, int *c, int *result )
-{
-    *c = sc->getc_f( sc );
-
-    /* no character is available */
-    if( *c == UART_NO_CHAR ) {
-	*result = BRL1_NO_MESSAGE;
-	return 0;
-    }
-
-    /* some error in UART */
-    if( *c < 0 ) {
-	*result = BRL1_LINK;
-	return 0;
-    }
-
-    /* everything's fine */
-    *result = BRL1_VALID;
-    return 1;
-}
-
-
-/*
- * brl1_receive
- *
- * This function reads a Bedrock-L1 protocol packet into the l1sc_t
- * response buffer.
- *
- * The operation of this function can be expressed as a finite state
- * machine:
- *
-
-START STATE			INPUT		TRANSITION
-==========================================================
-BRL1_IDLE (reset or error)	flag		BRL1_FLAG
-				other		BRL1_IDLE@
-
-BRL1_FLAG (saw a flag (0x7e))	flag		BRL1_FLAG
-				escape		BRL1_IDLE@
-				header byte	BRL1_HDR
-				other		BRL1_IDLE@
-
-BRL1_HDR (saw a type/subch byte)(see below)	BRL1_BODY
-						BRL1_HDR
-
-BRL1_BODY (reading packet body)	flag		BRL1_FLAG
-				escape		BRL1_ESC
-				other		BRL1_BODY
-
-BRL1_ESC (saw an escape (0x7d))	flag		BRL1_FLAG@
-				escape		BRL1_IDLE@
-				other		BRL1_BODY
-==========================================================
-
-"@" denotes an error transition.
-
- * The BRL1_HDR state is a transient state which doesn't read input,
- * but just provides a way in to code which decides to whom an
- * incoming packet should be directed.
- *
- * brl1_receive can be used to poll for input from the L1, or as 
- * an interrupt service routine.  It reads as much data as is
- * ready from the junk bus UART and places into the appropriate
- * input queues according to subchannel.  The header byte is
- * stripped from console-type data, but is retained for message-
- * type data (L1 responses).  A length byte will also be
- * prepended to message-type packets.
- *
- * This routine is non-blocking; if the caller needs to block
- * for input, it must call brl1_receive in a loop.
- *
- * brl1_receive returns when there is no more input, the queue
- * for the current incoming message is full, or there is an
- * error (parity error, bad header, bad CRC, etc.).
- */
-
-#define STATE_SET(l,s)		((l)->brl1_state = (s))
-#define STATE_GET(l)		((l)->brl1_state)
-
-#define LAST_HDR_SET(l,h)	((l)->brl1_last_hdr = (h))
-#define LAST_HDR_GET(l)		((l)->brl1_last_hdr)
-
-#define VALID_HDR(c)				\
-    ( SUBCH((c)) <= SC_CONS_SYSTEM		\
-	? PKT_TYPE((c)) == BRL1_REQUEST		\
-	: ( PKT_TYPE((c)) == BRL1_RESPONSE ||	\
-	    PKT_TYPE((c)) == BRL1_EVENT ) )
-
-#define IS_TTY_PKT(l)		( SUBCH(LAST_HDR_GET(l)) <= SC_CONS_SYSTEM ? 1 : 0 )
-
-
-int
-brl1_receive( l1sc_t *sc, int mode )
-{
-    int result;		/* value to be returned by brl1_receive */
-    int c;		/* most-recently-read character	     	*/
-    int done;		/* set done to break out of recv loop	*/
-    unsigned long pl = 0, cpl = 0;
-    sc_cq_t *q;		/* pointer to queue we're working with	*/
-
-    result = BRL1_NO_MESSAGE;
-
-    L1SC_RECV_LOCK(sc, cpl);
-
-    done = 0;
-    while( !done )
-    {
-	switch( STATE_GET(sc) )
-	{
-
-	  case BRL1_IDLE:
-	    /* Initial or error state.  Waiting for a flag character
-             * to resynchronize with the L1.
-             */
-
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* saw a flag character */
-		STATE_SET( sc, BRL1_FLAG );
-		continue;
-	    }
-	    break;
-	    
-	  case BRL1_FLAG:
-	    /* One or more flag characters have been read; look for
-	     * the beginning of a packet (header byte).
-	     */
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR )
-		    STATE_SET( sc, BRL1_IDLE );
-
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* multiple flags are OK */
-		continue;
-	    }
-
-	    if( !VALID_HDR( c ) ) {
-		/* if c isn't a flag it should have been
-		 * a valid header, so we have an error
-		 */
-		result = BRL1_PROTOCOL;
-		STATE_SET( sc, BRL1_IDLE );
-		done = 1;
-		continue;
-	    }
-
-	    /* we have a valid header byte */
-	    LAST_HDR_SET( sc, c );
-	    STATE_SET( sc, BRL1_HDR );
-
-	    break; 
-
-	  case BRL1_HDR:
-	    /* A header byte has been read. Do some bookkeeping. */
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-	    
-	    if( !IS_TTY_PKT(sc) ) {
-		/* if this is an event or command response rather
-		 * than console I/O, we need to reserve a couple
-		 * of extra spaces in the queue for the header
-		 * byte and a length byte; if we can't, stay in
-		 * the BRL1_HDR state.
-		 */
-		if( cq_room( q ) < 2 ) {
-		    result = BRL1_FULL_Q;
-		    done = 1;
-		    continue;
-		}
-		cq_tent_add( q, 0 );			/* reserve length byte */
-		cq_tent_add( q, LAST_HDR_GET( sc ) );	/* record header byte  */
-	    }
-	    STATE_SET( sc, BRL1_BODY );
-
-	    break;
-
-	  case BRL1_BODY:
-	    /* A header byte has been read.  We are now attempting
-	     * to receive the packet body.
-	     */
-
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-
-	    /* if the queue we want to write into is full, don't read from
-	     * the uart (this provides backpressure to the L1 side)
-	     */
-	    if( cq_tent_full( q ) ) {
-		result = BRL1_FULL_Q;
-		done = 1;
-		continue;
-	    }
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR )
-		    STATE_SET( sc, BRL1_IDLE );
-		done = 1;
-		continue;
-	    }
-
-	    if( c == BRL1_ESC_CH ) {
-		/* prepare to unescape the next character */
-		STATE_SET( sc, BRL1_ESC );
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* flag signifies the end of a packet */
-
-		unsigned short crc;	/* holds the crc as we calculate it */
-		int i;			/* index variable */
-		brl1_sch_t *subch;      /* subchannel for received packet */
-		brl1_notif_t callup;	/* "data ready" callup */
-
-		/* whatever else may happen, we've seen a flag and we're
-		 * starting a new packet
-		 */
-		STATE_SET( sc, BRL1_FLAG );
-
-		/* if the packet body has less than 2 characters,
-		 * it can't be a well-formed packet.  Discard it.
-		 */
-		if( cq_tent_len( q ) < /* 2 + possible length byte */
-		    (2 + (IS_TTY_PKT(sc) ? 0 : 1)) )
-		{
-		    result = BRL1_PROTOCOL;
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_FLAG );
-		    done = 1;
-		    continue;
-		}
-		
-		/* check CRC */
-
-		/* accumulate CRC, starting with the header byte and
-		 * ending with the transmitted CRC.  This should
-		 * result in a known good value.
-		 */
-		crc = crc16_calc( INIT_CRC, LAST_HDR_GET(sc) );
-		for( i = (q->ipos + (IS_TTY_PKT(sc) ? 0 : 2)) % BRL1_QSIZE;
-		     i != q->tent_next;
-		     i = (i + 1) % BRL1_QSIZE )
-		{
-		    crc = crc16_calc( crc, q->buf[i] );
-		}
-
-		/* verify the caclulated crc against the "good" crc value;
-		 * if we fail, discard the bad packet and return an error.
-		 */
-		if( crc != (unsigned short)GOOD_CRC ) {
-		    result = BRL1_CRC;
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_FLAG );
-		    done = 1;
-		    continue;
-		}
-		
-		/* so the crc check was ok.  Now we discard the CRC
-		 * from the end of the received bytes.
-		 */
-		q->tent_next += (BRL1_QSIZE - 2);
-		q->tent_next %= BRL1_QSIZE;
-
-		/* get the subchannel and lock it */
-		subch = &(sc->subch[SUBCH( LAST_HDR_GET(sc) )]);
-		SUBCH_DATA_LOCK( subch, pl );
-		
-		/* if this isn't a console packet, we need to record
-		 * a length byte
-		 */
-		if( !IS_TTY_PKT(sc) ) {
-		    q->buf[q->ipos] = cq_tent_len( q ) - 1;
-		}
-		
-		/* record packet for posterity */
-		cq_commit_tent( q );
-		result = BRL1_VALID;
-
-		/* notify subchannel owner that there's something
-		 * on the queue for them
-		 */
-		atomic_inc(&(subch->packet_arrived));
-		callup = subch->rx_notify;
-		SUBCH_DATA_UNLOCK( subch, pl );
-
-		if( callup && (mode == SERIAL_INTERRUPT_MODE) ) {
-		    L1SC_RECV_UNLOCK( sc, cpl );
-		    L1_collectibles[L1C_RECEIVE_CALLUPS]++;
-		    (*callup)( sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_irq,
-				sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_dev_id,
-				sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_regs,
-				sc, SUBCH(LAST_HDR_GET(sc)) );
-		    L1SC_RECV_LOCK( sc, cpl );
-		}
-		continue;	/* go back for more! */
-	    }
-	    
-	    /* none of the special cases applied; we've got a normal
-	     * body character
-	     */
-	    cq_tent_add( q, c );
-
-	    break;
-
-	  case BRL1_ESC:
-	    /* saw an escape character.  The next character will need
-	     * to be unescaped.
-	     */
-
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-
-	    /* if the queue we want to write into is full, don't read from
-	     * the uart (this provides backpressure to the L1 side)
-	     */
-	    if( cq_tent_full( q ) ) {
-		result = BRL1_FULL_Q;
-		done = 1;
-		continue;
-	    }
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR ) {
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_IDLE );
-		}
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* flag after escape is an error */
-		STATE_SET( sc, BRL1_FLAG );
-		cq_discard_tent( q );
-		result = BRL1_PROTOCOL;
-		done = 1;
-		continue;
-	    }
-
-	    if( c == BRL1_ESC_CH ) {
-		/* two consecutive escapes is an error */
-		STATE_SET( sc, BRL1_IDLE );
-		cq_discard_tent( q );
-		result = BRL1_PROTOCOL;
-		done = 1;
-		continue;
-	    }
-	    
-	    /* otherwise, we've got a character that needs
-	     * to be unescaped
-	     */
-	    cq_tent_add( q, (c ^ BRL1_XOR_CH) );
-	    STATE_SET( sc, BRL1_BODY );
-
-	    break;
-
-	} /* end of switch( STATE_GET(sc) ) */
-    } /* end of while(!done) */
-
-    L1SC_RECV_UNLOCK( sc, cpl );
-
-    return result;
-}	    
-
-
-/* brl1_init initializes the Bedrock/L1 protocol layer.  This includes
- * zeroing out the send and receive state information.
- */
-
-void
-brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    int i;
-    brl1_sch_t *subch;
-
-    bzero( sc, sizeof( *sc ) );
-    sc->nasid = nasid;
-    sc->uart = uart;
-    sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc);
-    sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc);
-    sc->sol = 1;
-    subch = sc->subch;
-
-    /* initialize L1 subchannels
-     */
-
-    /* assign processor TTY channels */
-    for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_RSVD;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	spin_lock_init( &(subch->data_lock) );
-	sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );
-	subch->tx_notify = NULL;
-	/* (for now, drop elscuart packets in the kernel) */
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* assign system TTY channel (first free subchannel after each
-     * processor's individual TTY channel has been assigned)
-     */
-    subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = ATOMIC_INIT(0);
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &subch->data_lock, SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );
-    subch->tx_notify = NULL;
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, NASID_TO_COMPACT_NODEID(nasid) );
-	ASSERT( subch->iqp );
-	cq_init( subch->iqp );
-	subch->rx_notify = NULL;
-    }
-    else {
-	/* we shouldn't be getting console input from remote UARTs */
-	subch->iqp = &sc->garbage_q;
-	subch->rx_notify = brl1_discard_packet;
-    }
-    subch++; i++;
-
-    /* "reserved" subchannels (0x05-0x0F); for now, throw away
-     * incoming packets
-     */
-    for( ; i < 0x10; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* remaining subchannels are free */
-    for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* initialize synchronization structures
-     */
-    spin_lock_init( &(sc->subch_lock) );
-    spin_lock_init( &(sc->send_lock) );
-    spin_lock_init( &(sc->recv_lock) );
-
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	uart_init( sc, UART_BAUD_RATE );
-    }
-    else {
-	rtr_uart_init( sc, UART_BAUD_RATE );
-    }
-
-    /* Set up remaining fields using L1 command functions-- elsc_module_get
-     * to read the module id, elsc_debug_get to see whether or not we're
-     * in verbose mode.
-     */
-    {
-	extern int elsc_module_get(l1sc_t *);
-
-	sc->modid = elsc_module_get( sc );
-	sc->modid = (sc->modid < 0 ? INVALID_MODULE : sc->modid);
-	sc->verbose = 1;
-    }
-}
-
-/*********************************************************************
- * These are interrupt-related functions used in the kernel to service
- * the L1.
- */
-
-/*
- * brl1_intrd is the function which is called on a console interrupt.
- */
-
-
-static void
-brl1_intrd(int irq, void *dev_id, struct pt_regs *stuff)
-{
-    u_char isr_reg;
-    l1sc_t *sc = get_elsc();
-    int ret;
-
-    L1_collectibles[L1C_INTERRUPTS]++;
-    isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-
-    /* Save for callup args in console */
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_irq = irq;
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_dev_id = dev_id;
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_regs = stuff;
-
-#if	defined(SYNC_CONSOLE_WRITE)
-    while( isr_reg & ISR_RxRDY )
-#else
-    while( isr_reg & (ISR_RxRDY | ISR_TxRDY) )
-#endif
-    {
-	if( isr_reg & ISR_RxRDY ) {
-	    L1_collectibles[L1C_OUR_R_INTERRUPTS]++;
-	    ret = brl1_receive(sc, SERIAL_INTERRUPT_MODE);
-	    if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) )
-		L1_collectibles[L1C_REC_STALLS] = ret;
-	}
-#if	!defined(SYNC_CONSOLE_WRITE)
-	if( (isr_reg & ISR_TxRDY) || (sc->send_in_use && UART_PUTC_READY(sc->nasid)) ) {
-	    L1_collectibles[L1C_OUR_X_INTERRUPTS]++;
-	    brl1_send_cont(sc);
-	}
-#endif	/* SYNC_CONSOLE_WRITE */
-	isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-    }
-}
-
-
-/*
- * Install a callback function for the system console subchannel 
- * to allow an upper layer to be notified when the send buffer 
- * has been emptied.
- */
-static inline void
-l1_tx_notif( brl1_notif_t func )
-{
-	subch_set_tx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,
-			SC_CONS_SYSTEM, func );
-}
-
-
-/*
- * Install a callback function for the system console subchannel
- * to allow an upper layer to be notified when a packet has been
- * received.
- */
-static inline void
-l1_rx_notif( brl1_notif_t func )
-{
-	subch_set_rx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,
-				SC_CONS_SYSTEM, func );
-}
-
-
-/* brl1_intr is called directly from the uart interrupt; after it runs, the
- * interrupt "daemon" xthread is signalled to continue.
- */
-void
-brl1_intr( void )
-{
-}
-
-#define BRL1_INTERRUPT_LEVEL	65	/* linux request_irq() value */
-
-/* Return the current interrupt level */
-
-//#define CONSOLE_POLLING_ALSO
-
-int
-l1_get_intr_value( void )
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	return(0);
-#else
-#if defined(CONSOLE_POLLING_ALSO)
-	return(0);
-#else
-	return(BRL1_INTERRUPT_LEVEL);
-#endif /* CONSOLE_POLLING_ALSO */
-#endif /* USE_SAL_CONSOLE_IO */
-}
-
-/* Disconnect the callup functions - throw away interrupts */
-
-void
-l1_unconnect_intr(void)
-{
-#if !defined(USE_SAL_CONSOLE_IO)
-	/* UnRegister the upper-level callup functions */
-	l1_rx_notif((brl1_notif_t)NULL);
-	l1_tx_notif((brl1_notif_t)NULL);
-	/* We do NOT unregister the interrupts */
-#endif /* !USE_SAL_CONSOLE_IO */
-}
-
-/* Set up uart interrupt handling for this node's uart */
-
-void
-l1_connect_intr(void *rx_notify, void *tx_notify)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-#if 0
-	// Will need code here for sn2 - something like this
-	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid());
-	intr_connect_level(console_nodepda->node_first_cpu,
-                                SGI_UART_VECTOR, INTPEND0_MAXMASK,
-                                dummy_intr_func);
-	request_irq(SGI_UART_VECTOR | (console_nodepda->node_first_cpu << 8),
-                                intr_func, SA_INTERRUPT | SA_SHIRQ,
-                                "l1_protocol_driver", (void *)sc);
-#endif
-#else
-	l1sc_t *sc;
-	nasid_t nasid;
-	int tmp;
-	nodepda_t *console_nodepda;
-	int intr_connect_level(cpuid_t, int, ilvl_t, intr_func_t);
-
-	if ( L1_interrupts_connected ) {
-		/* Interrupts are connected, so just register the callups */
-		l1_rx_notif((brl1_notif_t)rx_notify);
-		l1_tx_notif((brl1_notif_t)tx_notify);
-
-		L1_collectibles[L1C_CONNECT_CALLS]++;
-		return;
-	}
-	else
-		L1_interrupts_connected = 1;
-
-	nasid = get_master_nasid();
-	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(nasid));
-	sc = &console_nodepda->module->elsc;
-	sc->intr_cpu = console_nodepda->node_first_cpu;
-
-	if ( intr_connect_level(sc->intr_cpu, UART_INTR, INTPEND0_MAXMASK, (intr_func_t)brl1_intr) ) {
-		L1_interrupts_connected = 0; /* FAILS !! */
-	}
-	else {
-		void synergy_intr_connect(int, int);
-
-		synergy_intr_connect(UART_INTR, sc->intr_cpu);
-		L1_collectibles[L1C_R_IRQ]++;
-		tmp = request_irq(BRL1_INTERRUPT_LEVEL, brl1_intrd, SA_INTERRUPT | SA_SHIRQ, "l1_protocol_driver", (void *)sc);
-		L1_collectibles[L1C_R_IRQ_RET] = (uint64_t)tmp;
-		if ( tmp ) {
-			L1_interrupts_connected = 0; /* FAILS !! */
-		}
-		else {
-			/* Register the upper-level callup functions */
-			l1_rx_notif((brl1_notif_t)rx_notify);
-			l1_tx_notif((brl1_notif_t)tx_notify);
-
-			/* Set the uarts the way we like it */
-			uart_enable_recv_intr( sc );
-			uart_disable_xmit_intr( sc );
-		}
-	}
-#endif	/* USE_SAL_CONSOLE_IO */
-}
-
-
-/* These are functions to use from serial_in/out when in protocol
- * mode to send and receive uart control regs. These are external
- * interfaces into the protocol driver.
- */
-
-void
-l1_control_out(int offset, int value)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	/* quietly ignore unless simulator */
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		if ( master_node_bedrock_address != (u64)0 ) {
-			writeb(value, (unsigned long)master_node_bedrock_address +
-				(offset<< 3));
-		}
-		return;
-	}
-#else
-	nasid_t nasid = get_master_nasid();
-	WRITE_L1_UART_REG(nasid, offset, value); 
-#endif
-}
-
-/* Console input exported interface. Return a register value.  */
-
-int
-l1_control_in_polled(int offset)
-{
-	static int l1_control_in_local(int, int);
-
-	return(l1_control_in_local(offset, SERIAL_POLLED_MODE));
-}
-
-int
-l1_control_in(int offset)
-{
-	static int l1_control_in_local(int, int);
-
-	return(l1_control_in_local(offset, SERIAL_INTERRUPT_MODE));
-}
-
-static int
-l1_control_in_local(int offset, int mode)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	int sal_call_status = 0, input;
-	int ret = 0;
-
-	if ( offset == REG_LSR ) {
-		ret = (LSR_XHRE | LSR_XSRE);	/* can send anytime */
-		sal_call_status = ia64_sn_console_check(&input);
-		if ( !sal_call_status && input ) {
-			/* input pending */
-			ret |= LSR_RCA;
-		}
-	}
-
-	/* If the sal call failed, do it the old-fashioned way */
-	if ( sal_call_status ) {
-		if ( IS_RUNNING_ON_SIMULATOR() ) {
-			extern u64 master_node_bedrock_address;
-			ret = readb((unsigned long)master_node_bedrock_address +
-					(offset<< 3));
-		}		
-		else {
-#endif	/* USE_SAL_CONSOLE_IO */
-			nasid_t nasid;
-			int ret, input;
-			static int l1_poll(l1sc_t *, int);
-
-			nasid = get_master_nasid();
-			ret = READ_L1_UART_REG(nasid, offset); 
-
-			if ( offset == REG_LSR ) {
-				ret |= (LSR_XHRE | LSR_XSRE);	/* can send anytime */
-				if ( L1_cons_is_inited ) {
-					if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {
-						input = l1_poll(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, mode);
-						if ( input ) {
-							ret |= LSR_RCA;
-						}
-					}
-				}
-			}
-#if defined(USE_SAL_CONSOLE_IO)
-		}
-	}
-#endif
-	return(ret);
-}
-
-/*
- * Console input exported interface. Return a character (if one is available)
- */
-
-int
-l1_serial_in_polled(void)
-{
-	static int l1_serial_in_local(int mode);
-
-	return(l1_serial_in_local(SERIAL_POLLED_MODE));
-}
-
-int
-l1_serial_in(void)
-{
-	static int l1_serial_in_local(int mode);
-
-	return(l1_serial_in_local(SERIAL_INTERRUPT_MODE));
-}
-
-static int
-l1_serial_in_local(int mode)
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	int sal_call_status;
-	int ch;
-
-	sal_call_status = ia64_sn_console_getc(&ch);
-	if ( !sal_call_status ) {
-		return(ch);
-	}
-	else {
-		/* If the sal called failed - do it the old-fashioned way */
-		if ( IS_RUNNING_ON_SIMULATOR() ) {
-			extern u64 master_node_bedrock_address;
-			return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3)));
-		}		
-		else {
-#endif	/* USE_SAL_CONSOLE_IO */
-			nasid_t nasid;
-			l1sc_t *sc;
-			int value;
-			static int l1_getc( l1sc_t *, int );
-			static inline l1sc_t *early_sc_init(nasid_t);
-
-			nasid = get_master_nasid();
-			sc = early_sc_init(nasid);
-			if ( L1_cons_is_inited ) {
-				if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {
-					sc = &NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc;
-				}
-			}
-			value = l1_getc(sc, mode);
-			return(value);
-#if defined(USE_SAL_CONSOLE_IO)
-		}
-	}
-#endif
-}
-
-/* Console output exported interface. Write message to the console.  */
-
-int
-l1_serial_out( char *str, int len )
-{
-#if defined(USE_SAL_CONSOLE_IO)
-	void early_sn_setup(void);
-	int sal_call_status = 0;
-	int counter = len;
-
-#if defined(CONFIG_IA64_EARLY_PRINTK)
-	{
-		static int inited;
-		if(!inited) {
-			inited=1;
-			early_sn_setup();
-		}
-	}
-#endif
-
-	/* Attempt to write things out thru the sal */
-	sal_call_status = ia64_sn_console_putb(str, len);
-	if ( sal_call_status ) {
-		/* If the sal called failed - do it the old-fashioned way */
-		if ( IS_RUNNING_ON_SIMULATOR() ) {
-			extern u64 master_node_bedrock_address;
-                        if (!master_node_bedrock_address)
-                                early_sn_setup();
-			if ( master_node_bedrock_address != (u64)0 ) {
-#ifdef FLAG_DIRECT_CONSOLE_WRITES
-				/* This is an easy way to pre-pend the output to know whether the output
-				 * was done via sal or directly */
-				writeb('[', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				writeb('+', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				writeb(']', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				writeb(' ', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-#endif	/* FLAG_DIRECT_CONSOLE_WRITES */
-				while ( counter > 0 ) {
-					writeb(*str, (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-					counter--;
-					str++;
-				}
-			}
-		}
-		else {
-#endif	/* USE_SAL_CONSOLE_IO */
-			nasid_t nasid = get_master_nasid();
-			int l1_write(l1sc_t *, char *, int, int);
-
-			if ( L1_cons_is_inited ) {
-				if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 )
-					return(l1_write(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, str, len,
-#if	defined(SYNC_CONSOLE_WRITE)
-							1
-#else
-							!L1_interrupts_connected
-#endif
-									));
-			}
-			return(early_l1_serial_out(nasid, str, len, NOT_LOCKED));
-#if defined(USE_SAL_CONSOLE_IO)
-		}
-	}
-	return((counter <= 0) ? 0 : (len - counter));
-#endif
-}
-
-
-/*
- * These are the 'early' functions - when we need to do things before we have
- * all the structs setup.
- */
-
-
-static l1sc_t Early_console;		/* fake l1sc_t */
-static int Early_console_inited = 0;
-
-static void
-early_brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    int i;
-    brl1_sch_t *subch;
-
-    bzero( sc, sizeof( *sc ) );
-    sc->nasid = nasid;
-    sc->uart = uart;
-    sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc);
-    sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc);
-    sc->sol = 1;
-    subch = sc->subch;
-
-    /* initialize L1 subchannels
-     */
-
-    /* assign processor TTY channels */
-    for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_RSVD;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* assign system TTY channel (first free subchannel after each
-     * processor's individual TTY channel has been assigned)
-     */
-    subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = ATOMIC_INIT(0);
-    subch->tx_notify = NULL;
-    subch->rx_notify = NULL;
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	static sc_cq_t x_iqp;
-
-	subch->iqp = &x_iqp;
-	ASSERT( subch->iqp );
-	cq_init( subch->iqp );
-    }
-    else {
-	/* we shouldn't be getting console input from remote UARTs */
-	subch->iqp = &sc->garbage_q;
-    }
-    subch++; i++;
-
-    /* "reserved" subchannels (0x05-0x0F); for now, throw away
-     * incoming packets
-     */
-    for( ; i < 0x10; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* remaining subchannels are free */
-    for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-}
-
-static inline l1sc_t *
-early_sc_init(nasid_t nasid)
-{
-	/* This is for early I/O */
-	if ( Early_console_inited == 0 ) {
-    		early_brl1_init(&Early_console, nasid,  BRL1_LOCALHUB_UART);
-		Early_console_inited = 1;
-	}
-	return(&Early_console);
-}
-
-#define PUTCHAR(ch) \
-    { \
-        while( (!(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XHRE)) || \
-                (!(READ_L1_UART_REG( nasid, REG_MSR ) & MSR_CTS)) ); \
-        WRITE_L1_UART_REG( nasid, REG_DAT, (ch) ); \
-    }
-
-static int
-early_l1_serial_out( nasid_t nasid, char *str, int len, int lock_state )
-{
-	int ret, sent = 0;
-	char *msg = str;
-	static int early_l1_send( nasid_t nasid, char *str, int len, int lock_state );
-
-	while ( sent < len ) {
-		ret = early_l1_send(nasid, msg, len - sent, lock_state);
-		sent += ret;
-		msg += ret;
-	}
-	return(len);
-}
-
-static inline int
-early_l1_send( nasid_t nasid, char *str, int len, int lock_state )
-{
-    int sent;
-    char crc_char;
-    unsigned short crc = INIT_CRC;
-
-    if( len > (BRL1_QSIZE - 1) )
-	len = (BRL1_QSIZE - 1);
-
-    sent = len;
-    if ( lock_state == NOT_LOCKED )
-    	lock_console(nasid);
-
-    PUTCHAR( BRL1_FLAG_CH );
-    PUTCHAR( BRL1_EVENT | SC_CONS_SYSTEM );
-    crc = crc16_calc( crc, (BRL1_EVENT | SC_CONS_SYSTEM) );
-
-    while( len ) {
-
-	if( (*str == BRL1_FLAG_CH) || (*str == BRL1_ESC_CH) ) {
-	    PUTCHAR( BRL1_ESC_CH );
-	    PUTCHAR( (*str) ^ BRL1_XOR_CH );
-	}
-	else {
-	    PUTCHAR( *str );
-	}
-	
-	crc = crc16_calc( crc, *str );
-
-	str++; len--;
-    }
-    
-    crc ^= 0xffff;
-    crc_char = crc & 0xff;
-    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	crc_char ^= BRL1_XOR_CH;
-	PUTCHAR( BRL1_ESC_CH );
-    }
-    PUTCHAR( crc_char );
-    crc_char = (crc >> 8) & 0xff;
-    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	crc_char ^= BRL1_XOR_CH;
-	PUTCHAR( BRL1_ESC_CH );
-    }
-    PUTCHAR( crc_char );
-    PUTCHAR( BRL1_FLAG_CH );
-
-    if ( lock_state == NOT_LOCKED )
-    	unlock_console(nasid);
-    return sent;
-}
-
-/*********************************************************************
- * l1_cons functions
- *
- * These allow the L1 to act as the system console.  They're intended
- * to abstract away most of the br/l1 internal details from the
- * _L1_cons_* functions (in the prom-- see "l1_console.c") and
- * l1_* functions (in the kernel-- see "sio_l1.c") that they support.
- *
- */
-
-static int
-l1_poll( l1sc_t *sc, int mode )
-{
-    int ret;
-
-    /* in case this gets called before the l1sc_t structure for the module_t
-     * struct for this node is initialized (i.e., if we're called with a
-     * zero l1sc_t pointer)...
-     */
-
-
-    if( !sc ) {
-	return 0;
-    }
-
-    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
-	return 1;
-    }
-
-    ret = brl1_receive( sc, mode );
-    if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) )
-	L1_collectibles[L1C_REC_STALLS] = ret;
-
-    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
-	return 1;
-    }
-    return 0;
-}
-
-
-/* pull a character off of the system console queue (if one is available)
- */
-static int
-l1_getc( l1sc_t *sc, int mode )
-{
-    unsigned long pl = 0;
-    int c;
-
-    brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
-    sc_cq_t *q = subch->iqp;
-
-    if( !l1_poll( sc, mode ) ) {
-	return 0;
-    }
-
-    SUBCH_DATA_LOCK( subch, pl );
-    if( cq_empty( q ) ) {
-	atomic_set(&subch->packet_arrived, 0);
-	SUBCH_DATA_UNLOCK( subch, pl );
-	return 0;
-    }
-    cq_rem( q, c );
-    if( cq_empty( q ) )
-	atomic_set(&subch->packet_arrived, 0);
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return c;
-}
-
-/*
- * Write a message to the L1 on the system console subchannel.
- *
- * Danger: don't use a non-zero value for the wait parameter unless you're
- * someone important (like a kernel error message).
- */
-
-int
-l1_write( l1sc_t *sc, char *msg, int len, int wait )
-{
-	int sent = 0, ret = 0;
-
-	if ( wait ) {
-		while ( sent < len ) {
-			ret = brl1_send( sc, msg, len - sent, (SC_CONS_SYSTEM | BRL1_EVENT), wait );
-			sent += ret;
-			msg += ret;
-		}
-		ret = len;
-	}
-	else {
-		ret = brl1_send( sc, msg, len, (SC_CONS_SYSTEM | BRL1_EVENT), wait );
-	}
-	return(ret);
-}
-
-/* initialize the system console subchannel
- */
-void
-l1_init(void)
-{
-	/* All we do now is remember that we have been called */
-	L1_cons_is_inited = 1;
-}
-
-
-/*********************************************************************
- * The following functions and definitions implement the "message"-
- * style interface to the L1 system controller.
- *
- * Note that throughout this file, "sc" generally stands for "system
- * controller", while "subchannels" tend to be represented by
- * variables with names like subch or ch.
- *
- */
-
-#ifdef L1_DEBUG
-#define L1_DBG_PRF(x) printf x
-#else
-#define L1_DBG_PRF(x)
-#endif
-
-/*
- * sc_data_ready is called to signal threads that are blocked on l1 input.
- */
-void
-sc_data_ready( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-
-    brl1_sch_t *subch = &(sc->subch[ch]);
-    SUBCH_DATA_LOCK( subch, pl );
-    sv_signal( &(subch->arrive_sv) );
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-/* sc_open reserves a subchannel to send a request to the L1 (the
- * L1's response will arrive on the same channel).  The number
- * returned by sc_open is the system controller subchannel
- * acquired.
- */
-int
-sc_open( l1sc_t *sc, uint target )
-{
-    /* The kernel version implements a locking scheme to arbitrate
-     * subchannel assignment.
-     */
-    int ch;
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    SUBCH_LOCK( sc, pl );
-
-    /* Look for a free subchannel. Subchannels 0-15 are reserved
-     * for other purposes.
-     */
-    for( subch = &(sc->subch[BRL1_CMD_SUBCH]), ch = BRL1_CMD_SUBCH; 
-			ch < BRL1_NUM_SUBCHANS; subch++, ch++ ) {
-        if( subch->use == BRL1_SUBCH_FREE )
-            break;
-    }
-
-    if( ch == BRL1_NUM_SUBCHANS ) {
-        /* there were no subchannels available! */
-        SUBCH_UNLOCK( sc, pl );
-        return SC_NSUBCH;
-    }
-
-    subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->target = target;
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
-    subch->tx_notify = NULL;
-    subch->rx_notify = sc_data_ready;
-    subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
-				   NASID_TO_COMPACT_NODEID(sc->nasid) );
-    ASSERT( subch->iqp );
-    cq_init( subch->iqp );
-
-    return ch;
-}
-
-
-/* sc_close frees a Bedrock<->L1 subchannel.
- */
-int
-sc_close( l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    SUBCH_LOCK( sc, pl );
-    subch = &(sc->subch[ch]);
-    if( subch->use != BRL1_SUBCH_RSVD ) {
-        /* we're trying to close a subchannel that's not open */
-	SUBCH_UNLOCK( sc, pl );
-        return SC_NOPEN;
-    }
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->use = BRL1_SUBCH_FREE;
-
-    sv_broadcast( &(subch->arrive_sv) );
-    sv_destroy( &(subch->arrive_sv) );
-    spin_lock_destroy( &(subch->data_lock) );
-
-    ASSERT( subch->iqp && (subch->iqp != &sc->garbage_q) );
-    snia_kmem_free( subch->iqp, sizeof(sc_cq_t) );
-    subch->iqp = &sc->garbage_q;
-    subch->tx_notify = NULL;
-    subch->rx_notify = brl1_discard_packet;
-
-    SUBCH_UNLOCK( sc, pl );
-
-    return SC_SUCCESS;
-}
-
-
-/* sc_construct_msg builds a bedrock-to-L1 request in the supplied
- * buffer.  Returns the length of the message.  The
- * safest course when passing a buffer to be filled in is to use
- * BRL1_QSIZE as the buffer size.
- *
- * Command arguments are passed as type/argument pairs, i.e., to
- * pass the number 5 as an argument to an L1 command, call
- * sc_construct_msg as follows:
- *
- *    char msg[BRL1_QSIZE];
- *    msg_len = sc_construct_msg( msg,
- *				  BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                2,
- *                                L1_ARG_INT, 5 );
- *
- * To pass an additional ASCII argument, you'd do the following:
- *
- *    char *str;
- *    ... str points to a null-terminated ascii string ...
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                4,
- *                                L1_ARG_INT, 5,
- *                                L1_ARG_ASCII, str );
- *
- * Finally, arbitrary data of unknown type is passed using the argtype
- * code L1_ARG_UNKNOWN, a data length, and a buffer pointer, e.g.
- *
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                3,
- *                                L1_ARG_UNKNOWN, 32, bufptr );
- *
- * ...passes 32 bytes of data starting at bufptr.  Note that no string or
- * "unknown"-type argument should be long enough to overflow the message
- * buffer.
- *
- * To construct a message for an L1 command that requires no arguments,
- * you'd use the following:
- *
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                0 );
- *
- * The final 0 means "no varargs".  Notice that this parameter is used to hold
- * the number of additional arguments to sc_construct_msg, _not_ the actual
- * number of arguments used by the L1 command (so 2 per L1_ARG_[INT,ASCII]
- * type argument, and 3 per L1_ARG_UNKOWN type argument).  A call to construct
- * an L1 command which required three integer arguments and two arguments of
- * some arbitrary (unknown) type would pass 12 as the value for this parameter.
- *
- * ENDIANNESS WARNING: The following code does a lot of copying back-and-forth
- * between byte arrays and four-byte big-endian integers.  Depending on the
- * system controller connection and endianness of future architectures, some
- * rewriting might be necessary.
- */
-int
-sc_construct_msg( l1sc_t  *sc,		/* system controller struct */
-		  int	   ch,           /* subchannel for this message */
-		  char    *msg,          /* message buffer */
-		  int      msg_len,      /* size of message buffer */
-                  l1addr_t addr_task,    /* target system controller task */
-                  short    req_code,     /* 16-bit request code */
-                  int      req_nargs,    /* # of arguments (varargs) passed */
-                  ... )                 /* any additional parameters */
-{
-    uint32_t buf32;   /* 32-bit buffer used to bounce things around */
-    void *bufptr;       /* used to hold command argument addresses */
-    va_list al;         /* variable argument list */
-    int index;          /* current index into msg buffer */
-    int argno;          /* current position in varargs list */
-    int l1_argno;       /* running total of arguments to l1 */
-    int l1_arg_t;       /* argument type/length */
-    int l1_argno_byte;  /* offset of argument count byte */
-
-    index = argno = 0;
-
-    /* set up destination address */
-    if( (msg_len -= sizeof( buf32 )) < 0 )
-	return -1;
-    L1_ADDRESS_TO_TASK( &buf32, sc->subch[ch].target, addr_task );
-    COPY_INT_TO_BUFFER(msg, index, buf32);
-
-    /* copy request code */
-    if( (msg_len -= 2) < 0 )
-	return( -1 );
-    msg[index++] = ((req_code >> 8) & 0xff);
-    msg[index++] = (req_code & 0xff);
-
-    if( !req_nargs ) {
-        return index;
-    }
-
-    /* reserve a byte for the argument count */
-    if( (msg_len -= 1) < 0 )
-	return( -1 );
-    l1_argno_byte = index++;
-    l1_argno = 0;
-
-    /* copy additional arguments */
-    va_start( al, req_nargs );
-    while( argno < req_nargs ) {
-        l1_argno++;
-        l1_arg_t = va_arg( al, int ); argno++;
-        switch( l1_arg_t )
-        {
-          case L1_ARG_INT:
-	    if( (msg_len -= (sizeof( buf32 ) + 1)) < 0 )
-		return( -1 );
-            msg[index++] = L1_ARG_INT;
-            buf32 = (unsigned)va_arg( al, int ); argno++;
-	    COPY_INT_TO_BUFFER(msg, index, buf32);
-            break;
-
-          case L1_ARG_ASCII:
-            bufptr = va_arg( al, char* ); argno++;
-	    if( (msg_len -= (strlen( bufptr ) + 2)) < 0 )
-		return( -1 );
-            msg[index++] = L1_ARG_ASCII;
-            strcpy( (char *)&(msg[index]), (char *)bufptr );
-            index += (strlen( bufptr ) + 1); /* include terminating null */
-            break;
-
-	  case L1_ARG_UNKNOWN:
-              {
-                  int arglen;
-		  
-                  arglen = va_arg( al, int ); argno++;
-                  bufptr = va_arg( al, void* ); argno++;
-		  if( (msg_len -= (arglen + 1)) < 0 )
-		      return( -1 );
-                  msg[index++] = L1_ARG_UNKNOWN | arglen;
-                  BCOPY( bufptr, &(msg[index]), arglen  );
-                  index += arglen;
-		  break;
-              }
-	  
-	  default: /* unhandled argument type */
-	    return -1;
-        }
-    }
-
-    va_end( al );
-    msg[l1_argno_byte] = l1_argno;
-
-    return index;
-}
-
-
-
-/* sc_interpret_resp verifies an L1 response to a bedrock request, and
- * breaks the response data up into the constituent parts.  If the
- * response message indicates error, or if a mismatch is found in the
- * expected number and type of arguments, an error is returned.  The
- * arguments to this function work very much like the arguments to
- * sc_construct_msg, above, except that L1_ARG_INTs must be followed
- * by a _pointer_ to an integer that can be filled in by this function.
- */
-int
-sc_interpret_resp( char *resp,          /* buffer received from L1 */
-                   int   resp_nargs,    /* number of _varargs_ passed in */
-                   ... )
-{
-    uint32_t buf32;   /* 32-bit buffer used to bounce things around */
-    void *bufptr;       /* used to hold response field addresses */
-    va_list al;         /* variable argument list */
-    int index;          /* current index into response buffer */
-    int argno;          /* current position in varargs list */
-    int l1_fldno;       /* number of resp fields received from l1 */
-    int l1_fld_t;       /* field type/length */
-
-    index = argno = 0;
-
-#if defined(L1_DEBUG)
-#define DUMP_RESP							  \
-    {									  \
-	int ix;								  \
-        char outbuf[512];						  \
-        sprintf( outbuf, "sc_interpret_resp error line %d: ", __LINE__ ); \
-	for( ix = 0; ix < 16; ix++ ) {					  \
-	    sprintf( &outbuf[strlen(outbuf)], "%x ", resp[ix] );	  \
-	}								  \
-	printk( "%s\n", outbuf );					  \
-    }
-#else
-#define DUMP_RESP
-#endif /* L1_DEBUG */
-
-    /* check response code */
-    COPY_BUFFER_TO_INT(resp, index, buf32);
-    if( buf32 != L1_RESP_OK ) {
-	DUMP_RESP;
-        return buf32;
-    }
-
-    /* get number of response fields */
-    l1_fldno = resp[index++];
-
-    va_start( al, resp_nargs );
-
-    /* copy out response fields */
-    while( argno < resp_nargs ) {
-        l1_fldno--;
-        l1_fld_t = va_arg( al, int ); argno++;
-        switch( l1_fld_t )
-        {
-          case L1_ARG_INT:
-            if( resp[index++] != L1_ARG_INT ) {
-                /* type mismatch */
-		va_end( al );
-		DUMP_RESP;
-		return -1;
-            }
-            bufptr = va_arg( al, int* ); argno++;
-	    COPY_BUFFER_TO_BUFFER(resp, index, bufptr);
-            break;
-
-          case L1_ARG_ASCII:
-            if( resp[index++] != L1_ARG_ASCII ) {
-                /* type mismatch */
-		va_end( al );
-		DUMP_RESP;
-                return -1;
-            }
-            bufptr = va_arg( al, char* ); argno++;
-            strcpy( (char *)bufptr, (char *)&(resp[index]) );
-            /* include terminating null */
-            index += (strlen( &(resp[index]) ) + 1);
-            break;
-
-          default:
-	    if( (l1_fld_t & L1_ARG_UNKNOWN) == L1_ARG_UNKNOWN )
-	    {
-		int *arglen;
-		
-		arglen = va_arg( al, int* ); argno++;
-		bufptr = va_arg( al, void* ); argno++;
-		*arglen = ((resp[index++] & ~L1_ARG_UNKNOWN) & 0xff);
-		BCOPY( &(resp[index]), bufptr, *arglen  );
-		index += (*arglen);
-	    }
-	    
-	    else {
-		/* unhandled type */
-		va_end( al );
-		DUMP_RESP;
-		return -1;
-	    }
-        }
-    }
-    va_end( al );
-  
-    if( (l1_fldno != 0) || (argno != resp_nargs) ) {
-        /* wrong number of arguments */
-	DUMP_RESP;
-        return -1;
-    }
-    return 0;
-}
-
-/* sc_send takes as arguments a system controller struct, a
- * buffer which contains a Bedrock<->L1 "request" message,
- * the message length, and the subchannel (presumably obtained
- * from an earlier invocation of sc_open) over which the
- * message is to be sent.  The final argument ("wait") indicates
- * whether the send is to be performed synchronously or not.
- *
- * sc_send returns either zero or an error value.  Synchronous sends 
- * (wait != 0) will not return until the data has actually been sent
- * to the UART.  Synchronous sends generally receive privileged
- * treatment.  The intent is that they be used sparingly, for such
- * purposes as kernel printf's (the "ducons" routines).  Run-of-the-mill
- * console output and L1 requests should NOT use a non-zero value
- * for wait.
- */
-int
-sc_send( l1sc_t *sc, int ch, char *msg, int len, int wait )
-{
-    char type_and_subch;
-    int result;
-
-    if( (ch < 0) || ( ch >= BRL1_NUM_SUBCHANS) ) {
-        return SC_BADSUBCH;
-    }
-
-    /* Verify that this is an open subchannel
-     */
-    if( sc->subch[ch].use == BRL1_SUBCH_FREE ) {
-        return SC_NOPEN;
-    }
-
-    type_and_subch = (BRL1_REQUEST | ((u_char)ch));
-    result = brl1_send( sc, msg, len, type_and_subch, wait );
-
-    /* If we sent as much as we asked to, return "ok". */
-    if( result == len )
-	return( SC_SUCCESS );
-
-    /* Or, if we sent less, than either the UART is busy or
-     * we're trying to send too large a packet anyway.
-     */
-    else if( result >= 0 && result < len )
-	return( SC_BUSY );
-
-    /* Or, if something else went wrong (result < 0), then
-     * return that error value.
-     */
-    else
-	return( result );
-}
-
-/* subch_pull_msg pulls a message off the receive queue for subch
- * and places it the buffer pointed to by msg.  This routine should only
- * be called when the caller already knows a message is available on the
- * receive queue (and, in the kernel, only when the subchannel data lock
- * is held by the caller).
- */
-static void
-subch_pull_msg( brl1_sch_t *subch, char *msg, int *len )
-{
-    sc_cq_t *q;         /* receive queue */
-    int before_wrap,    /* packet may be split into two different       */
-        after_wrap;     /*   pieces to acommodate queue wraparound      */
-
-    /* pull message off the receive queue */
-    q = subch->iqp;
-
-    cq_rem( q, *len );   /* remove length byte and store */
-    cq_discard( q );     /* remove type/subch byte and discard */
-
-    if ( *len > 0 )
-	(*len)--;        /* don't count type/subch byte in length returned */
-
-    if( (q->opos + (*len)) > BRL1_QSIZE ) {
-        before_wrap = BRL1_QSIZE - q->opos;
-        after_wrap = (*len) - before_wrap;
-    }
-    else {
-        before_wrap = (*len);
-        after_wrap = 0;
-    }
-
-    BCOPY( q->buf + q->opos, msg, before_wrap  );
-    if( after_wrap ) {
-        BCOPY( q->buf, msg + before_wrap, after_wrap  );
-	q->opos = after_wrap;
-    }
-    else {
-	q->opos = ((q->opos + before_wrap) & (BRL1_QSIZE - 1));
-    }
-    atomic_dec(&(subch->packet_arrived));
-}
-
-
-/* sc_recv_poll can be called as a blocking or non-blocking function;
- * it attempts to pull a message off of the subchannel specified
- * in the argument list (ch).
- *
- * The "block" argument, if non-zero, is interpreted as a timeout
- * delay (to avoid permanent waiting).
- */
-
-int
-sc_recv_poll( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
-{
-    int is_msg = 0;
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    rtc_time_t exp_time = rtc_time() + block;
-
-    /* sanity check-- make sure this is an open subchannel */
-    if( subch->use == BRL1_SUBCH_FREE )
-	return( SC_NOPEN );
-
-    do {
-
-        /* kick the next lower layer and see if it pulls anything in
-         */
-	brl1_receive( sc, SERIAL_POLLED_MODE );
-	is_msg = atomic_read(&subch->packet_arrived);
-
-    } while( block && !is_msg && (rtc_time() < exp_time) );
-
-    if( !is_msg ) {
-	/* no message and we didn't care to wait for one */
-	return( SC_NMSG );
-    }
-
-    SUBCH_DATA_LOCK( subch, pl );
-    subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return( SC_SUCCESS );
-}
-    
-
-/* Like sc_recv_poll, sc_recv_intr can be called in either a blocking
- * or non-blocking mode.  Rather than polling until an appointed timeout,
- * however, sc_recv_intr sleeps on a syncrhonization variable until a
- * signal from the lower layer tells us that a packet has arrived.
- *
- * sc_recv_intr can't be used with remote (router) L1s.
- */
-int
-sc_recv_intr( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
-{
-    int is_msg = 0;
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    do {
-	SUBCH_DATA_LOCK(subch, pl);
-	is_msg = atomic_read(&subch->packet_arrived);
-	if( !is_msg && block ) {
-	    /* wake me when you've got something */
-	    subch->rx_notify = sc_data_ready;
-	    sv_wait( &(subch->arrive_sv), 0, 0);
-	    if( subch->use == BRL1_SUBCH_FREE ) {
-		/* oops-- somebody closed our subchannel while we were
-		 * sleeping!
-		 */
-
-		/* no need to unlock since the channel's closed anyhow */
-		return( SC_NOPEN );
-	    }
-	}
-    } while( !is_msg && block );
-
-    if( !is_msg ) {
-	/* no message and we didn't care to wait for one */
-	SUBCH_DATA_UNLOCK( subch, pl );
-	return( SC_NMSG );
-    }
-
-    subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return( SC_SUCCESS );
-}
-
-/* sc_command implements a (blocking) combination of sc_send and sc_recv.
- * It is intended to be the SN1 equivalent of SN0's "elsc_command", which
- * issued a system controller command and then waited for a response from
- * the system controller before returning.
- *
- * cmd points to the outgoing command; resp points to the buffer in
- * which the response is to be stored.  Both buffers are assumed to
- * be the same length; if there is any doubt as to whether the
- * response buffer is long enough to hold the L1's response, then
- * make it BRL1_QSIZE bytes-- no Bedrock<->L1 message can be any
- * bigger.
- *
- * Be careful using the same buffer for both cmd and resp; it could get
- * hairy if there were ever an L1 command reqeuest that spanned multiple
- * packets.  (On the other hand, that would require some additional
- * rewriting of the L1 command interface anyway.)
- */
-#define __RETRIES	50
-#define __WAIT_SEND	1	// ( sc->uart != BRL1_LOCALHUB_UART )
-#define __WAIT_RECV	10000000
-
-
-int
-sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len )
-{
-    int result;
-    int retries;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-    	return SC_NMSG;
-
-    retries = __RETRIES;
-
-    while( (result = sc_send( sc, ch, cmd, *len, __WAIT_SEND )) < 0 ) {
-	if( result == SC_BUSY ) {
-	    retries--;
-	    if( retries <= 0 )
-		return result;
-	    uart_delay(500);
-	}
-	else {
-	    return result;
-	}
-    }
-    
-    /* block on sc_recv_* */
-    if( (sc->uart == BRL1_LOCALHUB_UART) && L1_interrupts_connected ) {
-	return( sc_recv_intr( sc, ch, resp, len, __WAIT_RECV ) );
-    }
-    else {
-	return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
-    }
-}
-
-/* sc_command_kern is a knuckle-dragging, no-patience version of sc_command
- * used in situations where the kernel has a command that shouldn't be
- * delayed until the send buffer clears.  sc_command should be used instead
- * under most circumstances.
- */
-
-int
-sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len )
-{
-    int result;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-    	return SC_NMSG;
-
-    if( (result = sc_send( sc, ch, cmd, *len, 1 )) < 0 ) {
-	return result;
-    }
-
-    return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
-}
-
-
-
-/* sc_poll checks the queue corresponding to the given
- * subchannel to see if there's anything available.  If
- * not, it kicks the brl1 layer and then checks again.
- *
- * Returns 1 if input is available on the given queue,
- * 0 otherwise.
- */
-
-int
-sc_poll( l1sc_t *sc, int ch )
-{
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    if( atomic_read(&subch->packet_arrived) )
-	return 1;
-
-    brl1_receive( sc, SERIAL_POLLED_MODE );
-
-    if( atomic_read(&subch->packet_arrived) )
-	return 1;
-
-    return 0;
-}
-
-/* for now, sc_init just calls brl1_init */
-
-void
-sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    if ( !IS_RUNNING_ON_SIMULATOR() )
-    	brl1_init( sc, nasid, uart );
-}
-
-/* sc_dispatch_env_event handles events sent from the system control
- * network's environmental monitor tasks.
- */
-
-#if	defined(LINUX_KERNEL_THREADS)
-
-static void
-sc_dispatch_env_event( uint code, int argc, char *args, int maxlen )
-{
-    int j, i = 0;
-    uint32_t ESPcode;
-
-    switch( code ) {
-	/* for now, all codes do the same thing: grab two arguments
-	 * and print a cmn_err_tag message */
-      default:
-	/* check number of arguments */
-	if( argc != 2 ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected 2 arguments, got %d\n", argc ));
-	    return;
-	}
-	
-	/* get ESP code (integer argument) */
-	if( args[i++] != L1_ARG_INT ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected integer argument\n" ));
-	    return;
-	}
-	/* WARNING: highly endian */
-	COPY_BUFFER_TO_INT(args, i, ESPcode);
-
-	/* verify string argument */
-	if( args[i++] != L1_ARG_ASCII ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected an ASCII string\n" ));
-	    return;
-	}
-	for( j = i; j < maxlen; j++ ) {
-	    if( args[j] == '\0' ) break; /* found string termination */
-	}
-	if( j == maxlen ) {
-	    j--;
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "message too long-- truncating\n" ));
-	}
-
-	/* strip out trailing cr/lf */
-	for( ; 
-	     j > 1 && ((args[j-1] == 0xd) || (args[j-1] == 0xa)); 
-	     j-- );
-	args[j] = '\0';
-	
-	/* strip out leading cr/lf */
-	for( ;
-	     i < j && ((args[i] == 0xd) || (args[i] == 0xa));
-	     i++ );
-    }
-}
-
-
-/* sc_event waits for events to arrive from the system controller, and
- * prints appropriate messages to the syslog.
- */
-
-static void
-sc_event( l1sc_t *sc, int ch )
-{
-    char event[BRL1_QSIZE];
-    int i;
-    int result;
-    int event_len;
-    uint32_t ev_src;
-    uint32_t ev_code;
-    int ev_argc;
-
-    while(1) {
-	
-	bzero( event, BRL1_QSIZE );
-
-	/*
-	 * wait for an event 
-	 */
-	result = sc_recv_intr( sc, ch, event, &event_len, 1 );
-	if( result != SC_SUCCESS ) {
-	    printk(KERN_WARNING  "Error receiving sysctl event on nasid %d\n",
-		     sc->nasid );
-	}
-	else {
-	    /*
-	     * an event arrived; break it down into useful pieces
-	     */
-#if defined(L1_DEBUG) && 0
-	    int ix;
-	    printf( "Event packet received:\n" );
-	    for (ix = 0; ix < 64; ix++) {
-		printf( "%x%x ", ((event[ix] >> 4) & ((uint64_t)0xf)),
-			(event[ix] & ((uint64_t)0xf)) );
-		if( (ix % 16) == 0xf ) printf( "\n" );
-	    }
-#endif /* L1_DEBUG */
-
-	    i = 0;
-
-	    /* get event source */
-	    COPY_BUFFER_TO_INT(event, i, ev_src);
-	    COPY_BUFFER_TO_INT(event, i, ev_code);
-
-	    /* get arg count */
-	    ev_argc = (event[i++] & 0xffUL);
-	    
-	    /* dispatch events by task */
-	    switch( (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT )
-	    {
-	      case L1_ADDR_TASK_ENV: /* environmental monitor event */
-		sc_dispatch_env_event( ev_code, ev_argc, &(event[i]), 
-				       BRL1_QSIZE - i );
-		break;
-
-	      default: /* unhandled task type */
-		L1_DBG_PRF(( "Unhandled event type received from system "
-			     "controllers: source task %x\n",
-			     (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT
-			   ));
-	    }
-	}
-	
-    }			
-}
-
-/* sc_listen sets up a service thread to listen for incoming events.
- */
-
-void
-sc_listen( l1sc_t *sc )
-{
-    int result;
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    char        msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         ch;     /* system controller subchannel used */
-
-    extern int msc_shutdown_pri;
-
-    /* grab the designated "event subchannel" */
-    SUBCH_LOCK( sc, pl );
-    subch = &(sc->subch[BRL1_EVENT_SUBCH]);
-    if( subch->use != BRL1_SUBCH_FREE ) {
-	SUBCH_UNLOCK( sc, pl );
-	printk(KERN_WARNING  "sysctl event subchannel in use! "
-		 "Not monitoring sysctl events.\n" );
-	return;
-    }
-    subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->target = BRL1_LOCALHUB_UART;
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
-    subch->tx_notify = NULL;
-    subch->rx_notify = sc_data_ready;
-    subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
-				   NASID_TO_COMPACT_NODEID(sc->nasid) );
-    ASSERT( subch->iqp );
-    cq_init( subch->iqp );
-
-    /* set up a thread to listen for events */
-    sthread_create( "sysctl event handler", 0, 0, 0, msc_shutdown_pri,
-		    KT_PS, (st_func_t *) sc_event,
-		    (void *)sc, (void *)(uint64_t)BRL1_EVENT_SUBCH, 0, 0 );
-
-    /* signal the L1 to begin sending events */
-    bzero( msg, BRL1_QSIZE );
-    ch = sc_open( sc, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( sc, ch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_EVENT_SUBCH, 2,
-				 L1_ARG_INT, BRL1_EVENT_SUBCH )) < 0 )
-    {
-	sc_close( sc, ch );
-	L1_DBG_PRF(( "Failure in sc_construct_msg (%d)\n", len ));
-	goto err_return;
-    }
-
-    result = sc_command_kern( sc, ch, msg, msg, &len );
-    if( result < 0 )
-    {
-	sc_close( sc, ch );
-	L1_DBG_PRF(( "Failure in sc_command_kern (%d)\n", result ));
-	goto err_return;
-    }
-
-    sc_close( sc, ch );
-
-    result = sc_interpret_resp( msg, 0 );
-    if( result < 0 )
-    {
-	L1_DBG_PRF(( "Failure in sc_interpret_resp (%d)\n", result ));
-	goto err_return;
-    }
-
-    /* everything went fine; just return */
-    return;
-	
-err_return:
-    /* there was a problem; complain */
-    printk(KERN_WARNING  "failed to set sysctl event-monitoring subchannel.  "
-	     "Sysctl events will not be monitored.\n" );
-}
-
-#endif	/* LINUX_KERNEL_THREADS */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/l1_command.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/l1_command.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/l1_command.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/l1_command.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1409 +0,0 @@
-/* $Id: l1_command.c,v 1.2 2002/11/21 17:51:57 jh Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */ 
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_cpuid.h>
-
-#define ELSC_TIMEOUT	1000000		/* ELSC response timeout (usec) */
-#define LOCK_TIMEOUT	5000000		/* Hub lock timeout (usec) */
-
-#define LD(x)		(*(volatile uint64_t *)(x))
-#define SD(x, v)	(LD(x) = (uint64_t) (v))
-
-#define hub_cpu_get()	0
-
-#define LBYTE(caddr)	(*(char *) caddr)
-
-extern char *bcopy(const char * src, char * dest, int count);
-
-#define LDEBUG		0
-
-/*
- * ELSC data is in NVRAM page 7 at the following offsets.
- */
-
-#define NVRAM_MAGIC_AD	0x700		/* magic number used for init */
-#define NVRAM_PASS_WD	0x701		/* password (4 bytes in length) */
-#define NVRAM_DBG1	0x705		/* virtual XOR debug switches */
-#define NVRAM_DBG2	0x706		/* physical XOR debug switches */
-#define NVRAM_CFG	0x707		/* ELSC Configuration info */
-#define NVRAM_MODULE	0x708		/* system module number */
-#define NVRAM_BIST_FLG	0x709		/* BIST flags (2 bits per nodeboard) */
-#define NVRAM_PARTITION 0x70a		/* module's partition id */
-#define	NVRAM_DOMAIN	0x70b		/* module's domain id */
-#define	NVRAM_CLUSTER	0x70c		/* module's cluster id */
-#define	NVRAM_CELL	0x70d		/* module's cellid */
-
-#define NVRAM_MAGIC_NO	0x37		/* value of magic number */
-#define NVRAM_SIZE	16		/* 16 bytes in nvram */
-
-/*
- * Declare a static ELSC NVRAM buffer to hold all data read from
- * and written to NVRAM.  This nvram "cache" will be used only during the
- * IP27prom execution.
- */
-static char elsc_nvram_buffer[NVRAM_SIZE];
-
-#define SC_COMMAND sc_command
-
-/*
- * elsc_init
- *
- *   Initialize ELSC structure
- */
-
-void elsc_init(elsc_t *e, nasid_t nasid)
-{
-    sc_init((l1sc_t *)e, nasid, BRL1_LOCALHUB_UART);
-}
-
-
-/*
- * elsc_errmsg
- *
- *   Given a negative error code,
- *   returns a corresponding static error string.
- */
-
-char *elsc_errmsg(int code)
-{
-    switch (code) {
-    case ELSC_ERROR_CMD_SEND:
-	return "Command send error";
-    case ELSC_ERROR_CMD_CHECKSUM:
-	return "Command packet checksum error";
-    case ELSC_ERROR_CMD_UNKNOWN:
-	return "Unknown command";
-    case ELSC_ERROR_CMD_ARGS:
-	return "Invalid command argument(s)";
-    case ELSC_ERROR_CMD_PERM:
-	return "Permission denied";
-    case ELSC_ERROR_RESP_TIMEOUT:
-	return "System controller response timeout";
-    case ELSC_ERROR_RESP_CHECKSUM:
-	return "Response packet checksum error";
-    case ELSC_ERROR_RESP_FORMAT:
-	return "Response format error";
-    case ELSC_ERROR_RESP_DIR:
-	return "Response direction error";
-    case ELSC_ERROR_MSG_LOST:
-	return "Message lost because queue is full";
-    case ELSC_ERROR_LOCK_TIMEOUT:
-	return "Timed out getting ELSC lock";
-    case ELSC_ERROR_DATA_SEND:
-	return "Error sending data";
-    case ELSC_ERROR_NIC:
-	return "NIC protocol error";
-    case ELSC_ERROR_NVMAGIC:
-	return "Bad magic number in NVRAM";
-    case ELSC_ERROR_MODULE:
-	return "Module location protocol error";
-    default:
-	return "Unknown error";
-    }
-}
-
-/*
- * elsc_nvram_init
- *
- *   Initializes reads and writes to NVRAM.  This will perform a single
- *   read to NVRAM, getting all data at once.  When the PROM tries to
- *   read NVRAM, it returns the data from the buffer being read.  If the
- *   PROM tries to write out to NVRAM, the write is done, and the internal
- *   buffer is updated.
- */
-
-void elsc_nvram_init(nasid_t nasid, uchar_t *elsc_nvram_data)
-{
-    /* This might require implementation of multiple-packet request/responses
-     * if it's to provide the same behavior that was available in SN0.
-     */
-    nasid = nasid;
-    elsc_nvram_data = elsc_nvram_data;
-}
-
-/*
- * elsc_nvram_copy
- *
- *   Copies the content of a buffer into the static buffer in this library.
- */
-
-void elsc_nvram_copy(uchar_t *elsc_nvram_data)
-{
-    memcpy(elsc_nvram_buffer, elsc_nvram_data, NVRAM_SIZE);
-}
-
-/*
- * elsc_nvram_write
- *
- *   Copies bytes from 'buf' into NVRAM, starting at NVRAM address
- *   'addr' which must be between 0 and 2047.
- *
- *   If 'len' is non-negative, the routine copies 'len' bytes.
- *
- *   If 'len' is negative, the routine treats the data as a string and
- *   copies bytes up to and including a NUL-terminating zero, but not
- *   to exceed '-len' bytes.
- */
-
-int elsc_nvram_write(elsc_t *e, int addr, char *buf, int len)
-{
-    /* Here again, we might need to work out the details of a
-     * multiple-packet protocol.
-     */
-
-    /* For now, pretend it worked. */
-    e = e;
-    addr = addr;
-    buf = buf;
-    return (len < 0 ? -len : len);
-}
-
-/*
- * elsc_nvram_read
- *
- *   Copies bytes from NVRAM into 'buf', starting at NVRAM address
- *   'addr' which must be between 0 and 2047.
- *
- *   If 'len' is non-negative, the routine copies 'len' bytes.
- *
- *   If 'len' is negative, the routine treats the data as a string and
- *   copies bytes up to and including a NUL-terminating zero, but not
- *   to exceed '-len' bytes.  NOTE:  This method is no longer supported.
- *   It was never used in the first place.
- */
-
-int elsc_nvram_read(elsc_t *e, int addr, char *buf, int len)
-{
-    /* multiple packets? */
-    e = e;
-    addr = addr;
-    buf = buf;
-    len = len;
-    return -1;
-}
-
-
-/*
- * Command Set
- */
-
-int elsc_version(elsc_t *e, char *result)
-{
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-    int		major,  /* major rev number */
-	        minor,  /* minor rev number */
-                bugfix; /* bugfix rev number */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_FW_REV, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major,
-			   L1_ARG_INT, &minor, L1_ARG_INT, &bugfix )
-	< 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    sprintf( result, "%d.%d.%d", major, minor, bugfix );
-
-    return 0;
-}
-
-int elsc_debug_set(elsc_t *e, u_char byte1, u_char byte2)
-{
-    /* shush compiler */
-    e = e;
-    byte1 = byte1;
-    byte2 = byte2;
-
-    /* fill in a buffer with the opcode & params; call sc_command */
-
-    return 0;
-}
-
-int elsc_debug_get(elsc_t *e, u_char *byte1, u_char *byte2)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		dbg_sw; /* holds debug switch settings */
-    int		len;	/* number of msg buffer bytes used */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RDBG, 0 ) ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &dbg_sw ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* copy out debug switch settings (last two bytes of the
-     * integer response)
-     */
-    *byte1 = ((dbg_sw >> 8) & 0xFF);
-    *byte2 = (dbg_sw & 0xFF);
-
-    return 0;
-}
-
-
-/*
- * elsc_rack_bay_get fills in the two int * arguments with the
- * rack number and bay number of the L1 being addressed
- */
-int elsc_rack_bay_get(elsc_t *e, uint *rack, uint *bay)
-{
-    char msg[BRL1_QSIZE];	/* L1 request/response info */
-    int subch;			/* system controller subchannel used */
-    int len;			/* length of message */
-    uint32_t	buf32;		/* used to copy 32-bit rack/bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRACK, 0 )) < 0 ) 
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-
-    /* send the request to the L1 */
-    if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close(e, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &buf32 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    return 0;
-}
-
-
-/* elsc_rack_bay_type_get fills in the three int * arguments with the
- * rack number, bay number and brick type of the L1 being addressed.  Note
- * that if the L1 operation fails and this function returns an error value, 
- * garbage may be written to brick_type.
- */
-int elsc_rack_bay_type_get( l1sc_t *sc, uint *rack, 
-			       uint *bay, uint *brick_type )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t buf32;	        /* used to copy 32-bit rack & bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRBT, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, 
-			           L1_ARG_INT, brick_type ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    /* convert brick_type to lower case */
-    *brick_type = *brick_type - 'A' + 'a';
-
-    return 0;
-}
-
-
-int elsc_module_get(elsc_t *e)
-{
-    extern char brick_types[];
-    uint rnum, rack, bay, bricktype, t;
-    int ret;
-
-    /* construct module ID from rack and slot info */
-
-    if ((ret = elsc_rack_bay_type_get(e, &rnum, &bay, &bricktype)) < 0) {
-	return ret;
-    }
-
-    /* report unset location info. with a special, otherwise invalid modid */
-    if (rnum == 0 && bay == 0)
-	return MODULE_NOT_SET;
-
-    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-	return ELSC_ERROR_MODULE;
-
-    /* Build a moduleid_t-compatible rack number */
-
-    rack = 0;		
-    t = rnum / 100;		/* rack class (CPU/IO) */
-    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_CLASS(rack, t);
-    rnum %= 100;
-
-    t = rnum / 10;		/* rack group */
-    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_GROUP(rack, t);
-
-    t = rnum % 10;		/* rack number (one-based) */
-    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_NUM(rack, t);
-
-    for( t = 0; t < MAX_BRICK_TYPES; t++ ) {
-	if( brick_types[t] == bricktype )
-	    return RBT_TO_MODULE(rack, bay, t);
-    }
-    
-    return ELSC_ERROR_MODULE;
-}
-
-int elsc_partition_set(elsc_t *e, int partition)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PARTITION_SET, 2,
-				 L1_ARG_INT, partition )) < 0 )
-    {
-	
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-    
-    return( 0 );
-}
-
-int elsc_partition_get(elsc_t *e)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t partition_id;    /* used to copy partition id out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PARTITION_GET, 0 )) < 0 )
-
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &partition_id ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-    
-    return( partition_id );
-}
-
-
-/*
- * elsc_cons_subch selects the "active" console subchannel for this node
- * (i.e., the one that will currently receive input)
- */
-int elsc_cons_subch(elsc_t *e, uint ch)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( e, L1_ADDR_LOCAL );
-    
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_CONS_SUBCH, 2,
-				 L1_ARG_INT, ch)) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-/*
- * elsc_cons_node should only be executed by one node.  It declares to
- * the system controller that the node from which it is called will be
- * the owner of the system console.
- */
-int elsc_cons_node(elsc_t *e)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( e, L1_ADDR_LOCAL );
-    
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_CONS_NODE, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-    
-
-/* elsc_display_line writes up to 12 characters to either the top or bottom
- * line of the L1 display.  line points to a buffer containing the message
- * to be displayed.  The zero-based line number is specified by lnum (so
- * lnum == 0 specifies the top line and lnum == 1 specifies the bottom).
- * Lines longer than 12 characters, or line numbers not less than
- * L1_DISPLAY_LINES, cause elsc_display_line to return an error.
- */
-int elsc_display_line(elsc_t *e, char *line, int lnum)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		len;	/* number of msg buffer bytes used */
-
-    /* argument sanity checking */
-    if( !(lnum < L1_DISPLAY_LINES) )
-	return( ELSC_ERROR_CMD_ARGS );
-    if( !(strlen( line ) <= L1_DISPLAY_LINE_LENGTH) )
-	return( ELSC_ERROR_CMD_ARGS );
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 (L1_REQ_DISP1+lnum), 2,
-				 L1_ARG_ASCII, line )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-/* elsc_display_mesg silently drops message characters beyond the 12th.
- */
-int elsc_display_mesg(elsc_t *e, char *chr)
-{
-
-    char line[L1_DISPLAY_LINE_LENGTH+1];
-    int numlines, i;
-    int result;
-
-    numlines = (strlen( chr ) + L1_DISPLAY_LINE_LENGTH - 1) /
-	L1_DISPLAY_LINE_LENGTH;
-
-    if( numlines > L1_DISPLAY_LINES )
-	numlines = L1_DISPLAY_LINES;
-
-    for( i = 0; i < numlines; i++ )
-    {
-	strncpy( line, chr, L1_DISPLAY_LINE_LENGTH );
-	line[L1_DISPLAY_LINE_LENGTH] = '\0';
-
-	/* generally we want to leave the first line of the L1 display
-	 * alone (so the L1 can manipulate it).  If you need to be able
-	 * to display to both lines (for debugging purposes), define
-	 * L1_DISP_2LINES in irix/kern/ksys/l1.h, or add -DL1_DISP_2LINES
-	 * to your 'defs file.
-	 */
-#if defined(L1_DISP_2LINES)
-	if( (result = elsc_display_line( e, line, i )) < 0 )
-#else
-	if( (result = elsc_display_line( e, line, i+1 )) < 0 )
-#endif
-
-	    return result;
-
-	chr += L1_DISPLAY_LINE_LENGTH;
-    }
-    
-    return 0;
-}
-
-
-int elsc_password_set(elsc_t *e, char *password)
-{
-    /* shush compiler */
-    e = e;
-    password = password;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-int elsc_password_get(elsc_t *e, char *password)
-{
-    /* shush compiler */
-    e = e;
-    password = password;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-/*
- * sc_portspeed_get
- *
- * retrieve the current portspeed setting for the bedrock II
- */
-int sc_portspeed_get(l1sc_t *sc)
-{
-    char	msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         subch;  /* system controller subchannel used */
-    int		portspeed_a, portspeed_b;
-			/* ioport clock rates */
-
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-                                 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PORTSPEED,
-				 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-    
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) < 0 )
-    {
-        sc_close( sc, subch );
-        return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, 
-			   L1_ARG_INT, &portspeed_a,
-			   L1_ARG_INT, &portspeed_b ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* for the c-brick, we ignore the portspeed_b value */
-    return (portspeed_a ? 600 : 400);
-}
-
-/*
- * elsc_power_query
- *
- *   To be used after system reset, this command returns 1 if the reset
- *   was the result of a power-on, 0 otherwise.
- *
- *   The power query status is cleared to 0 after it is read.
- */
-
-int elsc_power_query(elsc_t *e)
-{
-    e = e; /* shush the compiler */
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 1;
-}
-
-int elsc_rpwr_query(elsc_t *e, int is_master)
-{
-    /* shush the compiler */
-    e = e;
-    is_master = is_master;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-} 
-
-/*
- * elsc_power_down
- *
- *   Sets up system to shut down in "sec" seconds (or modifies the
- *   shutdown time if one is already in effect).  Use 0 to power
- *   down immediately.
- */
-
-int elsc_power_down(elsc_t *e, int sec)
-{
-    /* shush compiler */
-    e = e;
-    sec = sec;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-int elsc_system_reset(elsc_t *e)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		len;	/* number of msg buffer bytes used */
-    int		result;
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RESET, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( (result = sc_command( e, subch, msg, msg, &len )) ) {
-	sc_close( e, subch );
-	if( result == SC_NMSG ) {
-	    /* timeout is OK.  We've sent the reset.  Now it's just
-	     * a matter of time...
-	     */
-	    return( 0 );
-	}
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-int elsc_power_cycle(elsc_t *e)
-{
-    /* shush compiler */
-    e = e;
-
-    /* fill in buffer with the opcode & params; call sc_command */
-
-    return 0;
-}
-
-
-int _elsc_hbt(elsc_t *e, int ival, int rdly)
-{
-    e = e;
-    ival = ival;
-    rdly = rdly;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-/* send a command string to an L1 */
-int sc_command_interp( l1sc_t *sc, l1addr_t compt, l1addr_t rack, l1addr_t bay,
-		       char *cmd )
-{
-    char        msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         subch;  /* system controller subchannel used */
-    l1addr_t	target; /* target system controller for command */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-
-    L1_BUILD_ADDR( &target, compt, rack, bay, 0 );
-    subch = sc_open( sc, target );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_CMD, L1_REQ_EXEC_CMD, 2,
-				 L1_ARG_ASCII, cmd )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-		   
-    /* send the request to the L1 */
-    if( SC_COMMAND( sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-    
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-/*
- * sc_power_down
- *
- * Shuts down the c-brick associated with sc, and any attached I/O bricks
- * or other c-bricks (won't go through r-bricks).
- */
-
-int sc_power_down(l1sc_t *sc)
-{
-    return sc_command_interp( sc, L1_ADDR_TYPE_L1, L1_ADDR_RACK_LOCAL, 
-			      L1_ADDR_BAY_LOCAL, "* pwr d" );
-}
-
-
-/*
- * sc_power_down_all
- *
- * Works similarly to sc_power_down, except that the request is sent to the
- * closest L2 and EVERYBODY gets turned off.
- */
-
-int sc_power_down_all(l1sc_t *sc)
-{
-    if( nodepda->num_routers > 0 ) {
-	return sc_command_interp( sc, L1_ADDR_TYPE_L2, L1_ADDR_RACK_LOCAL, 
-				  L1_ADDR_BAY_LOCAL, "* pwr d" );
-    }
-    else {
-	return sc_power_down( sc );
-    }
-}
-
-
-/*
- * iobrick routines
- */
-
-/* iobrick_rack_bay_type_get fills in the three int * arguments with the
- * rack number, bay number and brick type of the L1 being addressed.  Note
- * that if the L1 operation fails and this function returns an error value, 
- * garbage may be written to brick_type.
- */
-int iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack, 
-			       uint *bay, uint *brick_type )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t buf32;	        /* used to copy 32-bit rack & bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRBT, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, 
-			           L1_ARG_INT, brick_type ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    return 0;
-}
-
-
-int iobrick_module_get(l1sc_t *sc)
-{
-    uint rnum, rack, bay, brick_type, t;
-    int ret;
-
-    /* construct module ID from rack and slot info */
-
-    if ((ret = iobrick_rack_bay_type_get(sc, &rnum, &bay, &brick_type)) < 0)
-        return ret;
-
-    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-        return ELSC_ERROR_MODULE;
-
-    /* Build a moduleid_t-compatible rack number */
-
-    rack = 0;           
-    t = rnum / 100;             /* rack class (CPU/IO) */
-    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_CLASS(rack, t);
-    rnum %= 100;
-
-    t = rnum / 10;              /* rack group */
-    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_GROUP(rack, t);
-
-    t = rnum % 10;              /* rack number (one-based) */
-    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_NUM(rack, t);
-
-    switch( brick_type ) {
-      case 'I': 
-	brick_type = MODULE_IBRICK; break;
-      case 'P':
-	brick_type = MODULE_PBRICK; break;
-      case 'X':
-	brick_type = MODULE_XBRICK; break;
-    }
-
-    ret = RBT_TO_MODULE(rack, bay, brick_type);
-
-    return ret;
-}
-
-/*
- * iobrick_module_get_nasid() returns a module_id which has the brick
- * type encoded in bits 15-12, but this is not the true brick type...
- * The module_id returned by iobrick_module_get_nasid() is modified
- * to make a PEBRICKs & PXBRICKs look like a PBRICK.  So this routine
- * iobrick_type_get_nasid() returns the true unmodified brick type.
- */
-int
-iobrick_type_get_nasid(nasid_t nasid)
-{
-    l1sc_t *sc = get_elsc();
-    elsc_t tmp_sc;
-    uint rack, bay, type;
-    int t, ret;
-
-#ifdef PIC_LATER
-    if (PEBRICK_NODE(nasid)) {
-        if (peer_iobrick_rack_bay_get(nasid, &rack, &bay)) {
-            printf("Could not read rack and bay location "
-                   "of PEBrick at nasid %d\n", nasid);
-        }
-        if ((ret = peer_iobrick_type_get(sc, rack, bay, &type)) < 0)
-            return ret;
-    }
-    else
-#endif	/* PIC_LATER */
-    if (nasid != get_nasid()) { /* get the io_moduleid from remote node */
-        elsc_init(&tmp_sc, nasid);
-        if ((ret = iobrick_rack_bay_type_get(&tmp_sc, &rack, &bay, &type)) < 0)
-            return ret;
-    }
-    else {
-        if ((ret = iobrick_rack_bay_type_get(sc, &rack, &bay, &type)) < 0)
-            return ret;
-    }
-
-    /*
-     * Some brick_types need special treatment.  NOTE: This switch is
-     * duplicated in iobrick_module_get(),  so if you change this switch
-     * you must also change it there.
-     */
-    switch (type)
-    {
-    case L1_BRICKTYPE_IP45:
-        /* treat speedo2 like Ibrick for moduleid purposes */
-        type = L1_BRICKTYPE_I;
-        break;
-    case L1_BRICKTYPE_X2:
-        /* give X2 bricks the same moduleid as earlier models */
-        type = L1_BRICKTYPE_X;
-        break;
-    }
-
-    /* convert brick_type to lower case */
-    if ((type >= 'A') && (type <= 'Z'))
-        type = type - 'A' + 'a';
-
-    /* convert to a module.h brick type */
-    for( t = 0; t < MAX_BRICK_TYPES; t++ ) {
-        if( brick_types[t] == type )
-            return t;
-    }
-
-    return -1;    /* unknown brick */
-}
-
-int iobrick_module_get_nasid(nasid_t nasid)
-{
-    int io_moduleid;
-    l1sc_t *sc = get_elsc();
-    elsc_t tmp_sc;
-
-#ifdef PIC_LATER
-    uint rack, bay;
-
-    if (PEBRICK_NODE(nasid)) {
-        if (peer_iobrick_rack_bay_get(nasid, &rack, &bay)) {
-            printf("Could not read rack and bay location "
-                   "of PEBrick at nasid %d\n", nasid);
-        }
-
-        io_moduleid = peer_iobrick_module_get(sc, rack, bay);
-    }
-    else
-#endif	/* PIC_LATER */
-    if (nasid != get_nasid()) { /* get the io_moduleid from remote node */
-        elsc_init(&tmp_sc, nasid);
-
-        io_moduleid = iobrick_module_get(&tmp_sc);
-    }
-    else {
-        io_moduleid = iobrick_module_get(sc);
-    }
-
-    return io_moduleid;
-}
-
-
-/* iobrick_get_sys_snum asks the attached iobrick for the system
- * serial number.  This function will only be relevant to the master
- * cbrick (the one attached to the bootmaster ibrick); other nodes
- * may call the function, but the value returned to the master node
- * will be the one used as the system serial number by the kernel.
- */
-
-int
-iobrick_get_sys_snum( l1sc_t *sc, char *snum_str )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SYS_SERIAL, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    return( sc_interpret_resp( msg, 2, L1_ARG_ASCII, snum_str ) );
-}
-
-
-/*
- * The following functions apply (or cut off) power to the specified
- * pci bus or slot.
- */
-
-int
-iobrick_pci_pwr( l1sc_t *sc, int bus, int slot, int req_code )
-{
-#if 0 /* The "bedrock request" method of performing this function
-       * seems to be broken in the L1, so for now use the command-
-       * interpreter method
-       */
-
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCALIO );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 req_code, 4,
-				 L1_ARG_INT, bus,
-				 L1_ARG_INT, slot )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-
-#else
-    char cmd[64];
-    char *fxn;
-
-    switch( req_code )
-    {
-    case L1_REQ_PCI_UP:
-	fxn = "u";
-	break;
-    case L1_REQ_PCI_DOWN:
-	fxn = "d";
-	break;
-    case L1_REQ_PCI_RESET:
-	fxn = "rst";
-	break;
-    default:
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    if( slot == -1 ) 
-	sprintf( cmd, "pci %d %s", bus, fxn );
-    else
-        sprintf( cmd, "pci %d %d %s", bus, slot, fxn );
-	
-    return sc_command_interp( sc, L1_ADDR_TYPE_IOBRICK,
-	L1_ADDR_RACK_LOCAL, L1_ADDR_BAY_LOCAL, cmd );
-#endif
-}
-				 
-int
-iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up )
-{
-    return iobrick_pci_pwr( sc, bus, slot, up );
-}
-
-int
-iobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up )
-{
-    return iobrick_pci_pwr( sc, bus, -1, up );
-}
-
-
-int
-iobrick_pci_slot_rst( l1sc_t *sc, int bus, int slot )
-{
-    return iobrick_pci_pwr( sc, bus, slot, L1_REQ_PCI_RESET );
-}
-
-int
-iobrick_pci_bus_rst( l1sc_t *sc, int bus )
-{
-    return iobrick_pci_pwr( sc, bus, -1, L1_REQ_PCI_RESET );
-}
-
-
-/* get the L1 firmware version for an iobrick */
-int
-iobrick_sc_version( l1sc_t *sc, char *result )
-{
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-    int		major,  /* major rev number */
-	        minor,  /* minor rev number */
-                bugfix; /* bugfix rev number */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCALIO );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_FW_REV, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major,
-			   L1_ARG_INT, &minor, L1_ARG_INT, &bugfix )
-	< 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    sprintf( result, "%d.%d.%d", major, minor, bugfix );
-
-    return 0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/mem_refcnt.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/mem_refcnt.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/mem_refcnt.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/mem_refcnt.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,220 +0,0 @@
-/* $Id: mem_refcnt.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/sn1/mem_refcnt.h>
-#include <asm/sn/sn1/hwcntrs.h>
-#include <asm/sn/sn1/hubspc.h>
-// From numa_hw.h
-
-#define MIGR_COUNTER_MAX_GET(nodeid) \
-        (NODEPDA_MCD((nodeid))->migr_system_kparms.migr_threshold_reference)
-/*
- * Get the Absolute Theshold
- */
-#define MIGR_THRESHOLD_ABS_GET(nodeid) ( \
-        MD_MIG_VALUE_THRESH_GET(COMPACT_TO_NASID_NODEID(nodeid)))
-/*
- * Get the current Differential Threshold
- */
-#define MIGR_THRESHOLD_DIFF_GET(nodeid) \
-        (NODEPDA_MCD(nodeid)->migr_as_kparms.migr_base_threshold)
-
-#define NUM_OF_HW_PAGES_PER_SW_PAGE()   (NBPP / MD_PAGE_SIZE)
-
-// #include "migr_control.h"
-
-int
-mem_refcnt_attach(devfs_handle_t hub)
-{
-#if 0
-        devfs_handle_t refcnt_dev;
-        
-        hwgraph_char_device_add(hub,
-                                "refcnt",
-                                "hubspc_", 
-				&refcnt_dev);
-        device_info_set(refcnt_dev, (void*)(ulong)HUBSPC_REFCOUNTERS);
-#endif
-
-        return (0);
-}
-
-
-/*ARGSUSED*/
-int
-mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp)
-{
-        cnodeid_t node;
-
-        node = master_node_get(*devp);
-
-        ASSERT( (node >= 0) && (node < numnodes) );
-
-        if (NODEPDA(node)->migr_refcnt_counterbuffer == NULL) {
-                return (ENODEV);
-        }
-
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
-        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != (size_t)0 );
-
-        return (0);
-}
-
-/*ARGSUSED*/
-int
-mem_refcnt_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-        return 0;
-}
-
-/*ARGSUSED*/
-int
-mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-        cnodeid_t node;
-        int errcode;
-        char* buffer;
-        size_t blen;
-        
-        node = master_node_get(dev);
-
-        ASSERT( (node >= 0) && (node < numnodes) );
-
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL);
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
-        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );
-
-        /*
-         * XXXX deal with prot's somewhere around here....
-         */
-
-        buffer = NODEPDA(node)->migr_refcnt_counterbuffer;
-        blen = NODEPDA(node)->migr_refcnt_cbsize;
-
-        /*
-         * Force offset to be a multiple of sizeof(refcnt_t)
-         * We round up.
-         */
-
-        off = (((off - 1)/sizeof(refcnt_t)) + 1) * sizeof(refcnt_t);
-
-        if ( ((buffer + blen) - (buffer + off + len)) < 0 ) {
-                return (EPERM);
-        }
-
-        errcode = v_mapphys(vt,
-                            buffer + off,
-                            len);
-
-        return errcode;
-}
-
-/*ARGSUSED*/
-int
-mem_refcnt_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-        return 0;
-}
-
-/* ARGSUSED */
-int
-mem_refcnt_ioctl(devfs_handle_t dev,
-                 int cmd,
-                 void *arg,
-                 int mode,
-                 cred_t *cred_p,
-                 int *rvalp)
-{
-        cnodeid_t node;
-        int errcode;
-	extern int numnodes;
-        
-        node = master_node_get(dev);
-
-        ASSERT( (node >= 0) && (node < numnodes) );
-
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL);
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
-        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );
-
-        errcode = 0;
-        
-        switch (cmd) {
-        case RCB_INFO_GET:
-        {
-                rcb_info_t rcb;
-                
-                rcb.rcb_len = NODEPDA(node)->migr_refcnt_cbsize;
-                
-                rcb.rcb_sw_sets = NODEPDA(node)->migr_refcnt_numsets;
-                rcb.rcb_sw_counters_per_set = numnodes;
-                rcb.rcb_sw_counter_size = sizeof(refcnt_t);
-
-                rcb.rcb_base_pages = NODEPDA(node)->migr_refcnt_numsets /
-                                     NUM_OF_HW_PAGES_PER_SW_PAGE();  
-                rcb.rcb_base_page_size = NBPP;
-                rcb.rcb_base_paddr = ctob(slot_getbasepfn(node, 0));
-                
-                rcb.rcb_cnodeid = node;
-                rcb.rcb_granularity = MD_PAGE_SIZE;
-#ifdef LATER
-                rcb.rcb_hw_counter_max = MIGR_COUNTER_MAX_GET(node);
-                rcb.rcb_diff_threshold = MIGR_THRESHOLD_DIFF_GET(node);
-#endif
-                rcb.rcb_abs_threshold = MIGR_THRESHOLD_ABS_GET(node);
-                rcb.rcb_num_slots = MAX_MEM_SLOTS;
-
-                if (COPYOUT(&rcb, arg, sizeof(rcb_info_t))) {
-                        errcode = EFAULT;
-                }
-
-                break;
-        }
-        case RCB_SLOT_GET:
-        {
-                rcb_slot_t slot[MAX_MEM_SLOTS];
-                int s;
-                int nslots;
-
-                nslots = MAX_MEM_SLOTS;
-                ASSERT(nslots <= MAX_MEM_SLOTS);
-                for (s = 0; s < nslots; s++) {
-                        slot[s].base = (uint64_t)ctob(slot_getbasepfn(node, s));
-#ifdef LATER
-                        slot[s].size  = (uint64_t)ctob(slot_getsize(node, s));
-#else
-                        slot[s].size  = (uint64_t)1;
-#endif
-                }
-                if (COPYOUT(&slot[0], arg, nslots * sizeof(rcb_slot_t))) {
-                        errcode = EFAULT;
-                }
-                
-                *rvalp = nslots;
-                break;
-        }
-                
-        default:
-                errcode = EINVAL;
-                break;
-
-        }
-        
-        return errcode;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/ml_SN_init.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/ml_SN_init.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/ml_SN_init.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/ml_SN_init.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,211 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/bootmem.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/snconfig.h>
-
-extern int numcpus;
-extern char arg_maxnodes[];
-extern cpuid_t master_procid;
-extern synergy_da_t    *Synergy_da_indr[];
-
-extern int hasmetarouter;
-
-int		maxcpus;
-cpumask_t	boot_cpumask;
-hubreg_t	region_mask = 0;
-
-
-extern xwidgetnum_t hub_widget_id(nasid_t);
-
-extern int valid_icache_reasons;	/* Reasons to flush the icache */
-extern int valid_dcache_reasons;	/* Reasons to flush the dcache */
-extern u_char miniroot;
-extern volatile int	need_utlbmiss_patch;
-extern void iograph_early_init(void);
-
-nasid_t master_nasid = INVALID_NASID;
-
-
-/*
- * mlreset(int slave)
- * 	very early machine reset - at this point NO interrupts have been
- * 	enabled; nor is memory, tlb, p0, etc setup.
- *
- * 	slave is zero when mlreset is called for the master processor and
- *	is nonzero thereafter.
- */
-
-
-void
-mlreset(int slave)
-{
-	if (!slave) {
-		/*
-		 * We are the master cpu and node.
-		 */ 
-		master_nasid = get_nasid();
-		set_master_bridge_base();
-
-		/* We're the master processor */
-		master_procid = smp_processor_id();
-		master_nasid = cpuid_to_nasid(master_procid);
-
-		/*
-		 * master_nasid we get back better be same as one from
-		 * get_nasid()
-		 */
-		ASSERT_ALWAYS(master_nasid == get_nasid());
-
-		/* early initialization of iograph */
-		iograph_early_init();
-
-		/* Initialize Hub Pseudodriver Management */
-		hubdev_init();
-
-	} else { /* slave != 0 */
-		/*
-		 * This code is performed ONLY by slave processors.
-		 */
-
-	}
-}
-
-
-/* XXX - Move the meat of this to intr.c ? */
-/*
- * Set up the platform-dependent fields in the nodepda.
- */
-void init_platform_nodepda(nodepda_t *npda, cnodeid_t node)
-{
-	hubinfo_t hubinfo;
-	int	  sn;
-
-	extern void router_map_init(nodepda_t *);
-	extern void router_queue_init(nodepda_t *,cnodeid_t);
-	extern void intr_init_vecblk(nodepda_t *, cnodeid_t, int);
-
-	/* Allocate per-node platform-dependent data */
-	hubinfo = (hubinfo_t)alloc_bootmem_node(NODE_DATA(node), sizeof(struct hubinfo_s));
-
-	npda->pdinfo = (void *)hubinfo;
-	hubinfo->h_nodepda = npda;
-	hubinfo->h_cnodeid = node;
-	hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(node);
-
-	spin_lock_init(&hubinfo->h_crblock);
-
-	hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid);
-	npda->xbow_peer = INVALID_NASID;
-
-	/* 
-	 * Initialize the linked list of
-	 * router info pointers to the dependent routers
-	 */
-	npda->npda_rip_first = NULL;
-
-	/*
-	 * npda_rip_last always points to the place
-	 * where the next element is to be inserted
-	 * into the list 
-	 */
-	npda->npda_rip_last = &npda->npda_rip_first;
-	npda->module_id = INVALID_MODULE;
-
-	/*
-	* Initialize the interrupts.
-	* On sn2, this is done at pci init time,
-	* because sn2 needs the cpus checked in
-	* when it initializes interrupts.  This is
-	* so we don't see all the nodes as headless.
-	*/
-	for (sn=0; sn<NUM_SUBNODES; sn++) {
-		intr_init_vecblk(npda, node, sn);
-	}
-
-	mutex_init_locked(&npda->xbow_sema); /* init it locked? */
-}
-
-/* XXX - Move the interrupt stuff to intr.c ? */
-/*
- * Set up the platform-dependent fields in the processor pda.
- * Must be done _after_ init_platform_nodepda().
- * If we need a lock here, something else is wrong!
- */
-void init_platform_pda(cpuid_t cpu)
-{
-	hub_intmasks_t *intmasks;
-	int i, subnode;
-	cnodeid_t	cnode;
-	synergy_da_t	*sda;
-	int	which_synergy;
-
-
-	cnode = cpuid_to_cnodeid(cpu);
-	which_synergy = cpuid_to_synergy(cpu);
-
-	sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-	intmasks = &sda->s_intmasks;
-
-	/* Clear INT_PEND0 masks. */
-	for (i = 0; i < N_INTPEND0_MASKS; i++)
-		intmasks->intpend0_masks[i] = 0;
-
-	/* Set up pointer to the vector block in the nodepda. */
-	/* (Cant use SUBNODEPDA - not working yet) */
-	subnode = cpuid_to_subnode(cpu);
-	intmasks->dispatch0 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch0;
-	intmasks->dispatch1 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch1;
-	if (intmasks->dispatch0 !=  &SUBNODEPDA(cnode, subnode)->intr_dispatch0 ||
-	   intmasks->dispatch1 !=  &SUBNODEPDA(cnode, subnode)->intr_dispatch1)
-	   	panic("xxx");
-	intmasks->dispatch0 = &SUBNODEPDA(cnode, subnode)->intr_dispatch0;
-	intmasks->dispatch1 = &SUBNODEPDA(cnode, subnode)->intr_dispatch1;
-
-	/* Clear INT_PEND1 masks. */
-	for (i = 0; i < N_INTPEND1_MASKS; i++)
-		intmasks->intpend1_masks[i] = 0;
-}
-
-void
-update_node_information(cnodeid_t cnodeid)
-{
-	nodepda_t *npda = NODEPDA(cnodeid);
-	nodepda_router_info_t *npda_rip;
-	
-	/* Go through the list of router info 
-	 * structures and copy some frequently
-	 * accessed info from the info hanging
-	 * off the corresponding router vertices
-	 */
-	npda_rip = npda->npda_rip_first;
-	while(npda_rip) {
-		if (npda_rip->router_infop) {
-			npda_rip->router_portmask = 
-				npda_rip->router_infop->ri_portmask;
-			npda_rip->router_slot = 
-				npda_rip->router_infop->ri_slotnum;
-		} else {
-			/* No router, no ports. */
-			npda_rip->router_portmask = 0;
-		}
-		npda_rip = npda_rip->router_next;
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/ml_SN_intr.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/ml_SN_intr.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/ml_SN_intr.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/ml_SN_intr.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1154 +0,0 @@
-/* $Id: ml_SN_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * intr.c-
- *	This file contains all of the routines necessary to set up and
- *	handle interrupts on an IP27 board.
- */
-
-#ident  "$Revision: 1.1 $"
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/smp.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/intr.h>
-
-
-#if DEBUG_INTR_TSTAMP_DEBUG
-#include <sys/debug.h>
-#include <sys/idbg.h>
-#include <sys/inst.h>
-void do_splx_log(int, int);
-void spldebug_log_event(int);
-#endif
-
-#ifdef CONFIG_SMP
-extern unsigned long cpu_online_map;
-#endif
-#define cpu_allows_intr(cpu)	(1)
-// If I understand what's going on with this, 32 should work.
-// physmem_maxradius seems to be the maximum number of router
-// hops to get from one end of the system to the other.  With
-// a maximally configured machine, with the dumbest possible
-// topology, we would make 32 router hops.  For what we're using
-// it for, the dumbest possible should suffice.
-#define physmem_maxradius()	32
-
-#define SUBNODE_ANY (-1)
-
-extern int	nmied;
-extern int	hub_intr_wakeup_cnt;
-extern synergy_da_t	*Synergy_da_indr[];
-extern cpuid_t         master_procid;
-
-extern cnodeid_t master_node_get(devfs_handle_t vhdl);
-
-extern void snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs);
-
-
-#define INTR_LOCK(vecblk) \
-     (s = mutex_spinlock(&(vecblk)->vector_lock))
-#define INTR_UNLOCK(vecblk) \
-      mutex_spinunlock(&(vecblk)->vector_lock, s)
-
-/*
- * REACT/Pro
- */
-
-
-
-/* 
- * Find first bit set 
- * Used outside this file also 
- */
-int ms1bit(unsigned long x)
-{
-    int			b;
-
-    if (x >> 32)	b  = 32, x >>= 32;
-    else		b  =  0;
-    if (x >> 16)	b += 16, x >>= 16;
-    if (x >>  8)	b +=  8, x >>=  8;
-    if (x >>  4)	b +=  4, x >>=  4;
-    if (x >>  2)	b +=  2, x >>=  2;
-
-    return b + (int) (x >> 1);
-}
-
-/* ARGSUSED */
-void
-intr_stray(void *lvl)
-{
-    printk(KERN_WARNING  "Stray Interrupt - level %ld to cpu %d", (long)lvl, smp_processor_id());
-}
-
-#if defined(DEBUG)
-
-/* Infrastructure  to gather the device - target cpu mapping info */
-#define MAX_DEVICES	1000	/* Reasonable large number . Need not be 
-				 * the exact maximum # devices possible.
-				 */
-#define MAX_NAME	100	
-typedef struct {
-	dev_t		dev;	/* device */
-	cpuid_t		cpuid;	/* target cpu */
-	cnodeid_t	cnodeid;/* node on which the target cpu is present */
-	int		bit;	/* intr bit reserved */
-	char		intr_name[MAX_NAME]; /* name of the interrupt */
-} intr_dev_targ_map_t;
-
-intr_dev_targ_map_t 	intr_dev_targ_map[MAX_DEVICES];
-uint64_t		intr_dev_targ_map_size;
-spinlock_t		intr_dev_targ_map_lock;
-
-/* Print out the device - target cpu mapping.
- * This routine is used only in the idbg command
- * "intrmap" 
- */
-void
-intr_dev_targ_map_print(cnodeid_t cnodeid)
-{
-	int  i,j,size = 0;
-	int  print_flag = 0,verbose = 0;	
-	char node_name[10];
-	
-	if (cnodeid != CNODEID_NONE) {
-		nodepda_t 	*npda;
-
-		npda = NODEPDA(cnodeid);
-		for (j=0; j<NUM_SUBNODES; j++) {
-			qprintf("\n SUBNODE %d\n INT_PEND0: ", j);
-			for(i = 0 ; i < N_INTPEND_BITS ; i++)
-				qprintf("%d",SNPDA(npda,j)->intr_dispatch0.info[i].ii_flags);
-			qprintf("\n INT_PEND1: ");
-			for(i = 0 ; i < N_INTPEND_BITS ; i++)
-				qprintf("%d",SNPDA(npda,j)->intr_dispatch1.info[i].ii_flags);
-		}
-		verbose = 1;
-	}
-	qprintf("\n Device - Target Map [Interrupts: %s Node%s]\n\n",
-		(verbose ? "All" : "Non-hardwired"),
-		(cnodeid == CNODEID_NONE) ? "s: All" : node_name); 
-		
-	qprintf("Device\tCpu\tCnode\tIntr_bit\tIntr_name\n");
-	for (i = 0 ; i < intr_dev_targ_map_size ; i++) {
-
-		print_flag = 0;
-		if (verbose) {
-			if (cnodeid != CNODEID_NONE) {
-				if (cnodeid == intr_dev_targ_map[i].cnodeid)
-					print_flag = 1;
-			} else {
-				print_flag = 1;
-			}
-		} else {
-			if (intr_dev_targ_map[i].dev != 0) {
-				if (cnodeid != CNODEID_NONE) {
-					if (cnodeid == 
-					    intr_dev_targ_map[i].cnodeid)
-						print_flag = 1;
-				} else {
-					print_flag = 1;
-				}
-			}
-		}
-		if (print_flag) {
-			size++;
-			qprintf("%d\t%d\t%d\t%d\t%s\n",
-				intr_dev_targ_map[i].dev,
-				intr_dev_targ_map[i].cpuid,
-				intr_dev_targ_map[i].cnodeid,
-				intr_dev_targ_map[i].bit,
-				intr_dev_targ_map[i].intr_name);
-		}
-
-	}
-	qprintf("\nTotal : %d\n",size);
-}
-#endif /* DEBUG */
-
-/*
- * The spinlocks have already been initialized.  Now initialize the interrupt
- * vectors.  One processor on each hub does the work.
- */
-void
-intr_init_vecblk(nodepda_t *npda, cnodeid_t node, int sn)
-{
-    int			i, ip=0;
-    intr_vecblk_t	*vecblk;
-    subnode_pda_t	*snpda;
-
-
-    snpda = SNPDA(npda,sn);
-    do {
-	if (ip == 0) {
-	    vecblk = &snpda->intr_dispatch0;
-	} else {
-	    vecblk = &snpda->intr_dispatch1;
-	}
-
-	/* Initialize this vector. */
-	for (i = 0; i < N_INTPEND_BITS; i++) {
-		vecblk->vectors[i].iv_func = intr_stray;
-		vecblk->vectors[i].iv_prefunc = NULL;
-		vecblk->vectors[i].iv_arg = (void *)(__psint_t)(ip * N_INTPEND_BITS + i);
-
-		vecblk->info[i].ii_owner_dev = 0;
-		strcpy(vecblk->info[i].ii_name, "Unused");
-		vecblk->info[i].ii_flags = 0;	/* No flags */
-		vecblk->vectors[i].iv_mustruncpu = -1; /* No CPU yet. */
-
-	    }
-
-	mutex_spinlock_init(&vecblk->vector_lock);
-
-	vecblk->vector_count = 0;    
-	for (i = 0; i < CPUS_PER_SUBNODE; i++)
-		vecblk->cpu_count[i] = 0;
-
-	vecblk->vector_state = VECTOR_UNINITED;
-
-    } while (++ip < 2);
-
-}
-
-
-/*
- * do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, 
- *					devfs_handle_t owner_dev, char *name)
- *	Internal work routine to reserve or unreserve an interrupt level.
- *		cpu is the CPU to which the interrupt will be sent.
- *		bit is the level bit to reserve.  -1 means any level
- *		resflags should include II_ERRORINT if this is an
- *			error interrupt, II_THREADED if the interrupt handler
- *			will be threaded, or 0 otherwise.
- *		reserve should be set to II_RESERVE or II_UNRESERVE
- *			to get or clear a reservation.
- *		owner_dev is the device that "owns" this interrupt, if supplied
- *		name is a human-readable name for this interrupt, if supplied
- *	intr_reserve_level returns the bit reserved or -1 to indicate an error
- */
-static int
-do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, 
-					devfs_handle_t owner_dev, char *name)
-{
-    intr_vecblk_t	*vecblk;
-    hub_intmasks_t 	*hub_intmasks;
-    unsigned long s;
-    int rv = 0;
-    int ip;
-    synergy_da_t	*sda;
-    int		which_synergy;
-    cnodeid_t	cnode;
-
-    ASSERT(bit < N_INTPEND_BITS * 2);
-
-    cnode = cpuid_to_cnodeid(cpu);
-    which_synergy = cpuid_to_synergy(cpu);
-    sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-    hub_intmasks = &sda->s_intmasks;
-    // hub_intmasks = &pdaindr[cpu].pda->p_intmasks;
-
-    // if (pdaindr[cpu].pda == NULL) return -1;
-    if ((bit < N_INTPEND_BITS) && !(resflags & II_ERRORINT)) {
-	vecblk = hub_intmasks->dispatch0;
-	ip = 0;
-    } else {
-	ASSERT((bit >= N_INTPEND_BITS) || (bit == -1));
-	bit -= N_INTPEND_BITS;	/* Get position relative to INT_PEND1 reg. */
-	vecblk = hub_intmasks->dispatch1;
-	ip = 1;
-    }
-
-    INTR_LOCK(vecblk);
-
-    if (bit <= -1) {
-	bit = 0;
-	ASSERT(reserve == II_RESERVE);
-	/* Choose any available level */
-	for (; bit < N_INTPEND_BITS; bit++) {
-	    if (!(vecblk->info[bit].ii_flags & II_RESERVE)) {
-		rv = bit;
-		break;
-	    }
-	}
-
-	/* Return -1 if all interrupt levels int this register are taken. */
-	if (bit == N_INTPEND_BITS)
-	    rv = -1;
-
-    } else {
-	/* Reserve a particular level if it's available. */
-	if ((vecblk->info[bit].ii_flags & II_RESERVE) == reserve) {
-	    /* Can't (un)reserve a level that's already (un)reserved. */
-	    rv = -1;
-	} else {
-	    rv = bit;
-	}
-    }
-
-    /* Reserve the level and bump the count. */
-    if (rv != -1) {
-	if (reserve) {
-	    int maxlen = sizeof(vecblk->info[bit].ii_name) - 1;
-	    int namelen;
-	    vecblk->info[bit].ii_flags |= (II_RESERVE | resflags);
-	    vecblk->info[bit].ii_owner_dev = owner_dev;
-	    /* Copy in the name. */
-	    namelen = name ? strlen(name) : 0;
-	    strncpy(vecblk->info[bit].ii_name, name, min(namelen, maxlen)); 
-	    vecblk->info[bit].ii_name[maxlen] = '\0';
-	    vecblk->vector_count++;
-	} else {
-	    vecblk->info[bit].ii_flags = 0;	/* Clear all the flags */
-	    vecblk->info[bit].ii_owner_dev = 0;
-	    /* Clear the name. */
-	    vecblk->info[bit].ii_name[0] = '\0';
-	    vecblk->vector_count--;
-	}
-    }
-
-    INTR_UNLOCK(vecblk);
-
-#if defined(DEBUG)
-    if (rv >= 0) {
-	    int namelen = name ? strlen(name) : 0;
-	    /* Gather this device - target cpu mapping information
-	     * in a table which can be used later by the idbg "intrmap"
-	     * command
-	     */
-	    s = mutex_spinlock(&intr_dev_targ_map_lock);
-	    if (intr_dev_targ_map_size < MAX_DEVICES) {
-		    intr_dev_targ_map_t	*p;
-
-		    p 		= &intr_dev_targ_map[intr_dev_targ_map_size];
-		    p->dev  	= owner_dev;
-		    p->cpuid 	= cpu; 
-		    p->cnodeid 	= cpuid_to_cnodeid(cpu); 
-		    p->bit 	= ip * N_INTPEND_BITS + rv;
-		    strncpy(p->intr_name,
-			    name,
-			    min(MAX_NAME,namelen));
-		    intr_dev_targ_map_size++;
-	    }
-	    mutex_spinunlock(&intr_dev_targ_map_lock,s);
-    }
-#endif /* DEBUG */
-
-    return (((rv == -1) ? rv : (ip * N_INTPEND_BITS) + rv)) ;
-}
-
-
-/*
- * WARNING:  This routine should only be called from within ml/SN.
- *	Reserve an interrupt level.
- */
-int
-intr_reserve_level(cpuid_t cpu, int bit, int resflags, devfs_handle_t owner_dev, char *name)
-{
-	return(do_intr_reserve_level(cpu, bit, resflags, II_RESERVE, owner_dev, name));
-}
-
-
-/*
- * WARNING:  This routine should only be called from within ml/SN.
- *	Unreserve an interrupt level.
- */
-void
-intr_unreserve_level(cpuid_t cpu, int bit)
-{
-	(void)do_intr_reserve_level(cpu, bit, 0, II_UNRESERVE, 0, NULL);
-}
-
-/*
- * Get values that vary depending on which CPU and bit we're operating on
- */
-static hub_intmasks_t *
-intr_get_ptrs(cpuid_t cpu, int bit,
-	      int *new_bit,		/* Bit relative to the register */
-	      hubreg_t **intpend_masks, /* Masks for this register */
-	      intr_vecblk_t **vecblk,	/* Vecblock for this interrupt */
-	      int *ip)			/* Which intpend register */
-{
-	hub_intmasks_t *hub_intmasks;
-	synergy_da_t	*sda;
-	int		which_synergy;
-	cnodeid_t	cnode;
-
-	ASSERT(bit < N_INTPEND_BITS * 2);
-
-	cnode = cpuid_to_cnodeid(cpu);
-	which_synergy = cpuid_to_synergy(cpu);
-	sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-	hub_intmasks = &sda->s_intmasks;
-
-	// hub_intmasks = &pdaindr[cpu].pda->p_intmasks;
-
-	if (bit < N_INTPEND_BITS) {
-		*intpend_masks = hub_intmasks->intpend0_masks;
-		*vecblk = hub_intmasks->dispatch0;
-		*ip = 0;
-		*new_bit = bit;
-	} else {
-		*intpend_masks = hub_intmasks->intpend1_masks;
-		*vecblk = hub_intmasks->dispatch1;
-		*ip = 1;
-		*new_bit = bit - N_INTPEND_BITS;
-	}
-
-	return hub_intmasks;
-}
-
-
-/*
- * intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, 
- *		intr_func_t intr_func, void *intr_arg);
- *	This is the lowest-level interface to the interrupt code.  It shouldn't
- *	be called from outside the ml/SN directory.
- *	intr_connect_level hooks up an interrupt to a particular bit in
- *	the INT_PEND0/1 masks.  Returns 0 on success.
- *		cpu is the CPU to which the interrupt will be sent.
- *		bit is the level bit to connect to
- *		intr_swlevel tells which software level to use
- *		intr_func is the interrupt handler
- *		intr_arg is an arbitrary argument interpreted by the handler
- *		intr_prefunc is a prologue function, to be called
- *			with interrupts disabled, to disable
- *			the interrupt at source.  It is called
- *			with the same argument.  Should be NULL for
- *			typical interrupts, which can be masked
- *			by the infrastructure at the level bit.
- *	intr_connect_level returns 0 on success or nonzero on an error
- */
-/* ARGSUSED */
-int
-intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, intr_func_t intr_prefunc)
-{
-    intr_vecblk_t	*vecblk;
-    hubreg_t		*intpend_masks;
-    int rv = 0;
-    int ip;
-    unsigned long s;
-
-    ASSERT(bit < N_INTPEND_BITS * 2);
-
-    (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks,
-				 &vecblk, &ip);
-
-    INTR_LOCK(vecblk);
-
-    if ((vecblk->info[bit].ii_flags & II_INUSE) ||
-	(!(vecblk->info[bit].ii_flags & II_RESERVE))) {
-	/* Can't assign to a level that's in use or isn't reserved. */
-	rv = -1;
-    } else {
-	/* Stuff parameters into vector and info */
-	vecblk->vectors[bit].iv_prefunc = intr_prefunc;
-	vecblk->info[bit].ii_flags |= II_INUSE;
-    }
-
-    /* Now stuff the masks if everything's okay. */
-    if (!rv) {
-	int lslice;
-	volatile hubreg_t *mask_reg;
-	// nasid_t nasid = COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu));
-	nasid_t nasid = cpuid_to_nasid(cpu);
-	int	subnode = cpuid_to_subnode(cpu);
-
-	/* Make sure it's not already pending when we connect it. */
-	REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit + ip * N_INTPEND_BITS);
-
-	if (bit >= GFX_INTR_A && bit <= CC_PEND_B) {
-		intpend_masks[0] |= (1ULL << (uint64_t)bit);
-	}
-
-	lslice = cpuid_to_localslice(cpu);
-	vecblk->cpu_count[lslice]++;
-#if SN1
-	/*
-	 * On SN1, there are 8 interrupt mask registers per node:
-	 * 	PI_0 MASK_0 A
-	 * 	PI_0 MASK_1 A
-	 * 	PI_0 MASK_0 B
-	 * 	PI_0 MASK_1 B
-	 * 	PI_1 MASK_0 A
-	 * 	PI_1 MASK_1 A
-	 * 	PI_1 MASK_0 B
-	 * 	PI_1 MASK_1 B
-	 */
-#endif
-	if (ip == 0) {
-		mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode, 
-		        PI_INT_MASK0_A + PI_INT_MASK_OFFSET * lslice);
-	} else {
-		mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode,
-			PI_INT_MASK1_A + PI_INT_MASK_OFFSET * lslice);
-	}
-
-	HUB_S(mask_reg, intpend_masks[0]);
-    }
-
-    INTR_UNLOCK(vecblk);
-
-    return rv;
-}
-
-
-/*
- * intr_disconnect_level(cpuid_t cpu, int bit)
- *
- *	This is the lowest-level interface to the interrupt code.  It should
- *	not be called from outside the ml/SN directory.
- *	intr_disconnect_level removes a particular bit from an interrupt in
- * 	the INT_PEND0/1 masks.  Returns 0 on success or nonzero on failure.
- */
-int
-intr_disconnect_level(cpuid_t cpu, int bit)
-{
-    intr_vecblk_t	*vecblk;
-    hubreg_t		*intpend_masks;
-    unsigned long s;
-    int rv = 0;
-    int ip;
-
-    (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks,
-				 &vecblk, &ip);
-
-    INTR_LOCK(vecblk);
-
-    if ((vecblk->info[bit].ii_flags & (II_RESERVE | II_INUSE)) !=
-	((II_RESERVE | II_INUSE))) {
-	/* Can't remove a level that's not in use or isn't reserved. */
-	rv = -1;
-    } else {
-	/* Stuff parameters into vector and info */
-	vecblk->vectors[bit].iv_func = (intr_func_t)NULL;
-	vecblk->vectors[bit].iv_prefunc = (intr_func_t)NULL;
-	vecblk->vectors[bit].iv_arg = 0;
-	vecblk->info[bit].ii_flags &= ~II_INUSE;
-#ifdef BASE_ITHRTEAD
-	vecblk->vectors[bit].iv_mustruncpu = -1; /* No mustrun CPU any more. */
-#endif
-    }
-
-    /* Now clear the masks if everything's okay. */
-    if (!rv) {
-	int lslice;
-	volatile hubreg_t *mask_reg;
-
-	intpend_masks[0] &= ~(1ULL << (uint64_t)bit);
-	lslice = cpuid_to_localslice(cpu);
-	vecblk->cpu_count[lslice]--;
-	mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), 
-				   cpuid_to_subnode(cpu),
-				   ip == 0 ? PI_INT_MASK0_A : PI_INT_MASK1_A);
-	mask_reg = (volatile hubreg_t *)((__psunsigned_t)mask_reg +
-					(PI_INT_MASK_OFFSET * lslice));
-	*mask_reg = intpend_masks[0];
-    }
-
-    INTR_UNLOCK(vecblk);
-
-    return rv;
-}
-
-/*
- * Actually block or unblock an interrupt
- */
-void
-do_intr_block_bit(cpuid_t cpu, int bit, int block)
-{
-	intr_vecblk_t *vecblk;
-	int ip;
-	unsigned long s;
-	hubreg_t *intpend_masks;
-	volatile hubreg_t mask_value;
-	volatile hubreg_t *mask_reg;
-
-	intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &vecblk, &ip);
-
-	INTR_LOCK(vecblk);
-
-	if (block)
-		/* Block */
-		intpend_masks[0] &= ~(1ULL << (uint64_t)bit);
-	else
-		/* Unblock */
-		intpend_masks[0] |= (1ULL << (uint64_t)bit);
-
-	if (ip == 0) {
-		mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), 
-		        cpuid_to_subnode(cpu), PI_INT_MASK0_A);
-	} else {
-		mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), 
-			cpuid_to_subnode(cpu), PI_INT_MASK1_A);
-	}
-
-	HUB_S(mask_reg, intpend_masks[0]);
-
-	/*
-	 * Wait for it to take effect.  (One read should suffice.)
-	 * This is only necessary when blocking an interrupt
-	 */
-	if (block)
-		while ((mask_value = HUB_L(mask_reg)) != intpend_masks[0])
-			;
-
-	INTR_UNLOCK(vecblk);
-}
-
-
-/*
- * Block a particular interrupt (cpu/bit pair).
- */
-/* ARGSUSED */
-void
-intr_block_bit(cpuid_t cpu, int bit)
-{
-	do_intr_block_bit(cpu, bit, 1);
-}
-
-
-/*
- * Unblock a particular interrupt (cpu/bit pair).
- */
-/* ARGSUSED */
-void
-intr_unblock_bit(cpuid_t cpu, int bit)
-{
-	do_intr_block_bit(cpu, bit, 0);
-}
-
-
-/* verifies that the specified CPUID is on the specified SUBNODE (if any) */
-#define cpu_on_subnode(cpuid, which_subnode) \
-	   (((which_subnode) == SUBNODE_ANY) || (cpuid_to_subnode(cpuid) == (which_subnode)))
-
-
-/*
- * Choose one of the CPUs on a specified node or subnode to receive
- * interrupts. Don't pick a cpu which has been specified as a NOINTR cpu.
- *
- * Among all acceptable CPUs, the CPU that has the fewest total number
- * of interrupts targetted towards it is chosen.  Note that we never
- * consider how frequent each of these interrupts might occur, so a rare
- * hardware error interrupt is weighted equally with a disk interrupt.
- */
-static cpuid_t
-do_intr_cpu_choose(cnodeid_t cnode, int which_subnode)
-{
-	cpuid_t 	cpu, best_cpu = CPU_NONE;
-	int		slice, min_count=1000;
-
-	min_count = 1000;
-	for (slice=0; slice < CPUS_PER_NODE; slice++) {
-		intr_vecblk_t 	*vecblk0, *vecblk1;
-		int total_intrs_to_slice;
-		subnode_pda_t *snpda;
-		int local_cpu_num;
-
-		cpu = cnode_slice_to_cpuid(cnode, slice);
-		if (cpu == CPU_NONE)
-			continue;
-
-		/* If this cpu isn't enabled for interrupts, skip it */
-		if (!cpu_enabled(cpu) || !cpu_allows_intr(cpu))
-			continue;
-
-		/* If this isn't the right subnode, skip it */
-		if (!cpu_on_subnode(cpu, which_subnode))
-			continue;
-
-		/* OK, this one's a potential CPU for interrupts */
-		snpda = SUBNODEPDA(cnode,SUBNODE(slice));
-		vecblk0 = &snpda->intr_dispatch0;
-		vecblk1 = &snpda->intr_dispatch1;
-		local_cpu_num = LOCALCPU(slice);
-		total_intrs_to_slice = vecblk0->cpu_count[local_cpu_num] +
-		              vecblk1->cpu_count[local_cpu_num];
-
-		if (min_count > total_intrs_to_slice) {
-			min_count = total_intrs_to_slice;
-			best_cpu = cpu;
-		}
-	}
-	return best_cpu;
-}
-
-/*
- * Choose an appropriate interrupt target CPU on a specified node.
- * If which_subnode is SUBNODE_ANY, then subnode is not considered.
- * Otherwise, the chosen CPU must be on the specified subnode.
- */
-static cpuid_t
-intr_cpu_choose_from_node(cnodeid_t cnode, int which_subnode)
-{
-	return(do_intr_cpu_choose(cnode, which_subnode));
-}
-
-
-/* Make it easy to identify subnode vertices in the hwgraph */
-void
-mark_subnodevertex_as_subnode(devfs_handle_t vhdl, int which_subnode)
-{
-	graph_error_t rv;
-
-	ASSERT(0 <= which_subnode);
-	ASSERT(which_subnode < NUM_SUBNODES);
-
-	rv = hwgraph_info_add_LBL(vhdl, INFO_LBL_CPUBUS, (arbitrary_info_t)which_subnode);
-	ASSERT_ALWAYS(rv == GRAPH_SUCCESS);
-
-	rv = hwgraph_info_export_LBL(vhdl, INFO_LBL_CPUBUS, sizeof(arbitrary_info_t));
-	ASSERT_ALWAYS(rv == GRAPH_SUCCESS);
-}
-
-
-/*
- * Given a device descriptor, extract interrupt target information and
- * choose an appropriate CPU.  Return CPU_NONE if we can't make sense
- * out of the target information.
- * TBD: Should this be considered platform-independent code?
- */
-
-
-/*
- * intr_bit_reserve_test(cpuid,which_subnode,cnode,req_bit,intr_resflags,
- *		owner_dev,intr_name,*resp_bit)
- *	Either cpuid is not CPU_NONE or cnodeid not CNODE_NONE but
- * 	not both.
- * 1. 	If cpuid is specified, this routine tests if this cpu can be a valid
- * 	interrupt target candidate.
- * 2. 	If cnodeid is specified, this routine tests if there is a cpu on 
- *	this node which can be a valid interrupt target candidate.
- * 3.	If a valid interrupt target cpu candidate is found then an attempt at 
- * 	reserving an interrupt bit on the corresponding cnode is made.
- *
- * If steps 1 & 2 both fail or step 3 fails then we are not able to get a valid
- * interrupt target cpu then routine returns CPU_NONE (failure)
- * Otherwise routine returns cpuid of interrupt target (success)
- */
-static cpuid_t
-intr_bit_reserve_test(cpuid_t 		cpuid,
-		      int		favor_subnode,
-		      cnodeid_t 	cnodeid,
-		      int		req_bit,
-		      int 		intr_resflags,
-		      devfs_handle_t 	owner_dev,
-		      char		*intr_name,
-		      int		*resp_bit)
-{
-
-	ASSERT((cpuid==CPU_NONE) || (cnodeid==CNODEID_NONE));
-
-	if (cnodeid != CNODEID_NONE) {
-		/* Try to choose a interrupt cpu candidate */
-		cpuid = intr_cpu_choose_from_node(cnodeid, favor_subnode);
-	}
-
-	if (cpuid != CPU_NONE) {
-		/* Try to reserve an interrupt bit on the hub 
-		 * corresponding to the canidate cnode. If we
-		 * are successful then we got a cpu which can
-		 * act as an interrupt target for the io device.
-		 * Otherwise we need to continue the search
-		 * further.
-		 */
-		*resp_bit = do_intr_reserve_level(cpuid, 
-						  req_bit,
-						  intr_resflags,
-						  II_RESERVE,
-						  owner_dev, 
-						  intr_name);
-
-		if (*resp_bit >= 0)
-			/* The interrupt target  specified was fine */
-			return(cpuid);
-	}
-	return(CPU_NONE);
-}
-/*
- * intr_heuristic(dev_t dev,device_desc_t dev_desc,
- *		  int req_bit,int intr_resflags,dev_t owner_dev,
- *		  char *intr_name,int *resp_bit)
- *
- * Choose an interrupt destination for an interrupt.
- *	dev is the device for which the interrupt is being set up
- *	dev_desc is a description of hardware and policy that could
- *		help determine where this interrupt should go
- *	req_bit is the interrupt bit requested 
- *		(can be INTRCONNECT_ANY_BIT in which the first available
- * 		 interrupt bit is used)
- *	intr_resflags indicates whether we want to (un)reserve bit
- *	owner_dev is the owner device
- *	intr_name is the readable interrupt name	
- * 	resp_bit indicates whether we succeeded in getting the required
- *		 action  { (un)reservation} done	
- *		 negative value indicates failure
- *
- */
-/* ARGSUSED */
-cpuid_t
-intr_heuristic(devfs_handle_t 		dev,
-	       device_desc_t 	dev_desc,
-	       int		req_bit,
-	       int 		intr_resflags,
-	       devfs_handle_t 		owner_dev,
-	       char		*intr_name,
-	       int		*resp_bit)
-{
-	cpuid_t		cpuid;				/* possible intr targ*/
-	cnodeid_t 	candidate;			/* possible canidate */
-	int		which_subnode = SUBNODE_ANY;
-
-/* SN1 + pcibr Addressing Limitation */
-	{
-	devfs_handle_t pconn_vhdl;
-	pcibr_soft_t pcibr_soft;
-
-	/*
-	 * This combination of SN1 and Bridge hardware has an odd "limitation".
-	 * Due to the choice of addresses for PI0 and PI1 registers on SN1
-	 * and historical limitations in Bridge, Bridge is unable to
-	 * send interrupts to both PI0 CPUs and PI1 CPUs -- we have
-	 * to choose one set or the other.  That choice is implicitly
-	 * made when Bridge first attaches its error interrupt.  After
-	 * that point, all subsequent interrupts are restricted to the
-	 * same PI number (though it's possible to send interrupts to
-	 * the same PI number on a different node).
-	 *
-	 * Since neither SN1 nor Bridge designers are willing to admit a
-	 * bug, we can't really call this a "workaround".  It's a permanent
-	 * solution for an SN1-specific and Bridge-specific hardware
-	 * limitation that won't ever be lifted.
-	 */
-        if ((hwgraph_edge_get(dev, EDGE_LBL_PCI, &pconn_vhdl) == GRAPH_SUCCESS) &&
-	   ((pcibr_soft = pcibr_soft_get(pconn_vhdl)) != NULL)) {
-		/*
-		 * We "know" that the error interrupt is the first
-		 * interrupt set up by pcibr_attach.  Send all interrupts
-		 * on this bridge to the same subnode number.
-		 */
-		if (pcibr_soft->bsi_err_intr) {
-			which_subnode = cpuid_to_subnode(((hub_intr_t) pcibr_soft->bsi_err_intr)->i_cpuid);
-		}
-	}
-	}
-
-	/* Check if we can find a valid interrupt target candidate on
-	 * the master node for the device.
-	 */
-	cpuid = intr_bit_reserve_test(CPU_NONE,
-				      which_subnode,	
-				      master_node_get(dev),
-				      req_bit,
-				      intr_resflags,
-				      owner_dev,
-				      intr_name,
-				      resp_bit);
-
-	if (cpuid != CPU_NONE) {
-		if (cpu_on_subnode(cpuid, which_subnode))
-			return(cpuid);	/* got a valid interrupt target */
-		else
-			intr_unreserve_level(cpuid, *resp_bit);
-	}
-
-	printk(KERN_WARNING  "Cannot target interrupts to closest node(%d): (0x%lx)\n",
-		master_node_get(dev),(unsigned long)owner_dev);
-
-	/* Fall through into the default algorithm
-	 * (exhaustive-search-for-the-nearest-possible-interrupt-target)
-	 * for finding the interrupt target
-	 */
-
-	{
-	/*
-	 * Do a stupid round-robin assignment of the node.
-	 *  (Should do a "nearest neighbor" but not for SN1.
-	 */
-		static cnodeid_t last_node = -1;
-
-		if (last_node >= numnodes) last_node = 0;
-		for (candidate = last_node + 1; candidate != last_node; candidate++) {
-			if (candidate == numnodes) candidate = 0;
-			cpuid = intr_bit_reserve_test(CPU_NONE,
-					      which_subnode,
-					      candidate,
-					      req_bit,
-					      intr_resflags,
-					      owner_dev,
-					      intr_name,
-					      resp_bit);
-
-			if (cpuid != CPU_NONE) {
-				if (cpu_on_subnode(cpuid, which_subnode)) {
-					last_node = candidate;
-					return(cpuid);	/* got a valid interrupt target */
-				}
-				else
-					intr_unreserve_level(cpuid, *resp_bit);
-			}
-		}
-		last_node = candidate;
-	}
-
-	printk(KERN_WARNING  "Cannot target interrupts to any close node: %ld (0x%lx)\n",
-		(long)owner_dev, (unsigned long)owner_dev);
-
-	/* In the worst case try to allocate interrupt bits on the
-	 * master processor's node. We may get here during error interrupt
-	 * allocation phase when the topology matrix is not yet setup
-	 * and hence cannot do an exhaustive search.
-	 */
-	ASSERT(cpu_allows_intr(master_procid));
-	cpuid = intr_bit_reserve_test(master_procid,
-				      which_subnode,
-				      CNODEID_NONE,
-				      req_bit,
-				      intr_resflags,
-				      owner_dev,
-				      intr_name,
-				      resp_bit);
-
-	if (cpuid != CPU_NONE) {
-		if (cpu_on_subnode(cpuid, which_subnode))
-			return(cpuid);
-		else
-			intr_unreserve_level(cpuid, *resp_bit);
-	}
-
-	printk(KERN_WARNING  "Cannot target interrupts: (0x%lx)\n",
-		(unsigned long)owner_dev);
-
-	return(CPU_NONE);	/* Should never get here */
-}
-
-struct hardwired_intr_s {
-	signed char level;
-	int flags;
-	char *name;
-} const hardwired_intr[] = {
-	{ INT_PEND0_BASELVL + RESERVED_INTR,	0,	"Reserved" },
-	{ INT_PEND0_BASELVL + GFX_INTR_A,	0, 	"Gfx A" },
-	{ INT_PEND0_BASELVL + GFX_INTR_B,	0, 	"Gfx B" },
-	{ INT_PEND0_BASELVL + PG_MIG_INTR,	II_THREADED, "Migration" },
-	{ INT_PEND0_BASELVL + UART_INTR,	II_THREADED, "Bedrock/L1" },
-	{ INT_PEND0_BASELVL + CC_PEND_A,	0,	"Crosscall A" },
-	{ INT_PEND0_BASELVL + CC_PEND_B,	0,	"Crosscall B" },
-	{ INT_PEND1_BASELVL + CLK_ERR_INTR,	II_ERRORINT, "Clock Error" },
-	{ INT_PEND1_BASELVL + COR_ERR_INTR_A,	II_ERRORINT, "Correctable Error A" },
-	{ INT_PEND1_BASELVL + COR_ERR_INTR_B,	II_ERRORINT, "Correctable Error B" },
-	{ INT_PEND1_BASELVL + MD_COR_ERR_INTR,	II_ERRORINT, "MD Correct. Error" },
-	{ INT_PEND1_BASELVL + NI_ERROR_INTR,	II_ERRORINT, "NI Error" },
-	{ INT_PEND1_BASELVL + NI_BRDCAST_ERR_A,	II_ERRORINT, "Remote NI Error"},
-	{ INT_PEND1_BASELVL + NI_BRDCAST_ERR_B,	II_ERRORINT, "Remote NI Error"},
-	{ INT_PEND1_BASELVL + MSC_PANIC_INTR,	II_ERRORINT, "MSC Panic" },
-	{ INT_PEND1_BASELVL + LLP_PFAIL_INTR_A,	II_ERRORINT, "LLP Pfail WAR" },
-	{ INT_PEND1_BASELVL + LLP_PFAIL_INTR_B,	II_ERRORINT, "LLP Pfail WAR" },
-	{ INT_PEND1_BASELVL + NACK_INT_A,	0, "CPU A Nack count == NACK_CMP" },
-	{ INT_PEND1_BASELVL + NACK_INT_B,	0, "CPU B Nack count == NACK_CMP" },
-	{ INT_PEND1_BASELVL + LB_ERROR,		0, "Local Block Error" },
-	{ INT_PEND1_BASELVL + XB_ERROR,		0, "Local XBar Error" },
-	{ -1, 0, (char *)NULL},
-};
-
-/*
- * Reserve all of the hardwired interrupt levels so they're not used as
- * general purpose bits later.
- */
-void
-intr_reserve_hardwired(cnodeid_t cnode)
-{
-	cpuid_t cpu;
-	int level;
-	int i;
-	char subnode_done[NUM_SUBNODES];
-
-	// cpu = cnodetocpu(cnode);
-	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-		if (cpuid_to_cnodeid(cpu) == cnode) {
-			break;
-		}
-	}
-	if (cpu == smp_num_cpus) cpu = CPU_NONE;
-	if (cpu == CPU_NONE) {
-		printk("Node %d has no CPUs", cnode);
-		return;
-	}
-
-	for (i=0; i<NUM_SUBNODES; i++)
-		subnode_done[i] = 0;
-
-	for (; cpu<smp_num_cpus && cpu_enabled(cpu) && cpuid_to_cnodeid(cpu) == cnode; cpu++) {
-		int which_subnode = cpuid_to_subnode(cpu);
-		if (subnode_done[which_subnode])
-			continue;
-		subnode_done[which_subnode] = 1;
-
-		for (i = 0; hardwired_intr[i].level != -1; i++) {
-			level = hardwired_intr[i].level;
-
-			if (level != intr_reserve_level(cpu, level,
-						hardwired_intr[i].flags,
-						(devfs_handle_t) NULL,
-						hardwired_intr[i].name))
-				panic("intr_reserve_hardwired: Can't reserve level %d, cpu %ld.", level, cpu);
-		}
-	}
-}
-
-
-/*
- * Check and clear interrupts.
- */
-/*ARGSUSED*/
-static void
-intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend, int base_level,
-		char *name)
-{
-	volatile hubreg_t bits;
-	int i;
-
-	/* Check pending interrupts */
-	if ((bits = HUB_L(pend)) != 0) {
-		for (i = 0; i < N_INTPEND_BITS; i++) {
-			if (bits & (1 << i)) {
-#ifdef INTRDEBUG
-				printk(KERN_WARNING  "Nasid %d interrupt bit %d set in %s",
-					nasid, i, name);
-#endif
-				LOCAL_HUB_CLR_INTR(base_level + i);
-			}
-		}
-	}
-}
-
-/*
- * Clear out our interrupt registers.
- */
-void
-intr_clear_all(nasid_t nasid)
-{
-	int	sn;
-
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK0_A, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK0_B, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK1_A, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK1_B, 0);
-	
-		intr_clear_bits(nasid, REMOTE_HUB_PI_ADDR(nasid, sn, PI_INT_PEND0),
-				INT_PEND0_BASELVL, "INT_PEND0");
-		intr_clear_bits(nasid, REMOTE_HUB_PI_ADDR(nasid, sn, PI_INT_PEND1),
-				INT_PEND1_BASELVL, "INT_PEND1");
-	}
-}
-
-/* 
- * Dump information about a particular interrupt vector.
- */
-static void
-dump_vector(intr_info_t *info, intr_vector_t *vector, int bit, hubreg_t ip,
-		hubreg_t ima, hubreg_t imb, void (*pf)(char *, ...))
-{
-	hubreg_t value = 1LL << bit;
-
-	pf("  Bit %02d: %s: func 0x%x arg 0x%x prefunc 0x%x\n",
-		bit, info->ii_name,
-		vector->iv_func, vector->iv_arg, vector->iv_prefunc);
-	pf("   vertex 0x%x %s%s",
-		info->ii_owner_dev,
-		((info->ii_flags) & II_RESERVE) ? "R" : "U",
-		((info->ii_flags) & II_INUSE) ? "C" : "-");
-	pf("%s%s%s%s",
-		ip & value ? "P" : "-",
-		ima & value ? "A" : "-",
-		imb & value ? "B" : "-",
-		((info->ii_flags) & II_ERRORINT) ? "E" : "-");
-	pf("\n");
-}
-
-
-/*
- * Dump information about interrupt vector assignment.
- */
-void
-intr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...))
-{
-	nodepda_t *npda;
-	int ip, sn, bit;
-	intr_vecblk_t *dispatch;
-	hubreg_t ipr, ima, imb;
-	nasid_t nasid;
-
-	if ((cnode < 0) || (cnode >= numnodes)) {
-		pf("intr_dumpvec: cnodeid out of range: %d\n", cnode);
-		return ;
-	}
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	if (nasid == INVALID_NASID) {
-		pf("intr_dumpvec: Bad cnodeid: %d\n", cnode);
-		return ;
-	}
-		
-
-	npda = NODEPDA(cnode);
-
-	for (sn = 0; sn < NUM_SUBNODES; sn++) {
-		for (ip = 0; ip < 2; ip++) {
-			dispatch = ip ? &(SNPDA(npda,sn)->intr_dispatch1) : &(SNPDA(npda,sn)->intr_dispatch0);
-			ipr = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_PEND1 : PI_INT_PEND0);
-			ima = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_A : PI_INT_MASK0_A);
-			imb = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_B : PI_INT_MASK0_B);
-	
-			pf("Node %d INT_PEND%d:\n", cnode, ip);
-	
-			if (dispatch->ithreads_enabled)
-				pf(" Ithreads enabled\n");
-			else
-				pf(" Ithreads disabled\n");
-			pf(" vector_count = %d, vector_state = %d\n",
-				dispatch->vector_count,
-				dispatch->vector_state);
-			pf(" CPU A count %d, CPU B count %d\n",
- 		   	dispatch->cpu_count[0],
- 		   	dispatch->cpu_count[1]);
-			pf(" &vector_lock = 0x%x\n",
-				&(dispatch->vector_lock));
-			for (bit = 0; bit < N_INTPEND_BITS; bit++) {
-				if ((dispatch->info[bit].ii_flags & II_RESERVE) ||
-			    	(ipr & (1L << bit))) {
-					dump_vector(&(dispatch->info[bit]),
-					    	&(dispatch->vectors[bit]),
-					    	bit, ipr, ima, imb, pf);
-				}
-			}
-			pf("\n");
-		}
-	}
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/ml_iograph.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/ml_iograph.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/ml_iograph.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/ml_iograph.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1505 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-
-/* #define IOGRAPH_DEBUG */
-#ifdef IOGRAPH_DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* IOGRAPH_DEBUG */
-
-/* #define PROBE_TEST */
-
-/* At most 2 hubs can be connected to an xswitch */
-#define NUM_XSWITCH_VOLUNTEER 2
-
-/*
- * Track which hubs have volunteered to manage devices hanging off of
- * a Crosstalk Switch (e.g. xbow).  This structure is allocated,
- * initialized, and hung off the xswitch vertex early on when the
- * xswitch vertex is created.
- */
-typedef struct xswitch_vol_s {
-	mutex_t xswitch_volunteer_mutex;
-	int		xswitch_volunteer_count;
-	devfs_handle_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];
-} *xswitch_vol_t;
-
-void
-xswitch_vertex_init(devfs_handle_t xswitch)
-{
-	xswitch_vol_t xvolinfo;
-	int rc;
-
-	xvolinfo = kmalloc(sizeof(struct xswitch_vol_s), GFP_KERNEL);
-	mutex_init(&xvolinfo->xswitch_volunteer_mutex);
-	xvolinfo->xswitch_volunteer_count = 0;
-	rc = hwgraph_info_add_LBL(xswitch, 
-			INFO_LBL_XSWITCH_VOL,
-			(arbitrary_info_t)xvolinfo);
-	ASSERT(rc == GRAPH_SUCCESS); rc = rc;
-}
-
-
-/*
- * When assignment of hubs to widgets is complete, we no longer need the
- * xswitch volunteer structure hanging around.  Destroy it.
- */
-static void
-xswitch_volunteer_delete(devfs_handle_t xswitch)
-{
-	xswitch_vol_t xvolinfo;
-	int rc;
-
-	rc = hwgraph_info_remove_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL,
-				(arbitrary_info_t *)&xvolinfo);
-	kfree(xvolinfo);
-}
-/*
- * A Crosstalk master volunteers to manage xwidgets on the specified xswitch.
- */
-/* ARGSUSED */
-static void
-volunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master)
-{
-	xswitch_vol_t xvolinfo = NULL;
-	devfs_handle_t hubv;
-	hubinfo_t hubinfo;
-
-	(void)hwgraph_info_get_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL, 
-				(arbitrary_info_t *)&xvolinfo);
-	if (xvolinfo == NULL) {
-	    return;
-	}
-
-	mutex_lock(&xvolinfo->xswitch_volunteer_mutex);
-	ASSERT(xvolinfo->xswitch_volunteer_count < NUM_XSWITCH_VOLUNTEER);
-	xvolinfo->xswitch_volunteer[xvolinfo->xswitch_volunteer_count] = master;
-	xvolinfo->xswitch_volunteer_count++;
-
-	/*
-	 * if dual ported, make the lowest widgetid always be 
-	 * xswitch_volunteer[0].
-	 */
-	if (xvolinfo->xswitch_volunteer_count == NUM_XSWITCH_VOLUNTEER) {
-		hubv = xvolinfo->xswitch_volunteer[0];
-		hubinfo_get(hubv, &hubinfo);
-		if (hubinfo->h_widgetid != XBOW_HUBLINK_LOW) {
-			xvolinfo->xswitch_volunteer[0] = 
-						xvolinfo->xswitch_volunteer[1];
-			xvolinfo->xswitch_volunteer[1] = hubv;
-		}
-	}
-	mutex_unlock(&xvolinfo->xswitch_volunteer_mutex);
-}
-
-extern int xbow_port_io_enabled(nasid_t nasid, int widgetnum);
-
-/*
- * Assign all the xwidgets hanging off the specified xswitch to the
- * Crosstalk masters that have volunteered for xswitch duty.
- */
-/* ARGSUSED */
-static void
-assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv)
-{
-	xswitch_info_t xswitch_info;
-	xswitch_vol_t xvolinfo = NULL;
-	xwidgetnum_t widgetnum;
-	int num_volunteer;
-	nasid_t nasid;
-	hubinfo_t hubinfo;
-	extern int iobrick_type_get_nasid(nasid_t);
-
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-	
-	xswitch_info = xswitch_info_get(xswitch);
-	ASSERT(xswitch_info != NULL);
-
-	(void)hwgraph_info_get_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL, 
-				(arbitrary_info_t *)&xvolinfo);
-	if (xvolinfo == NULL) {
-	    return;
-	}
-
-	num_volunteer = xvolinfo->xswitch_volunteer_count;
-	ASSERT(num_volunteer > 0);
-
-	/* Assign master hub for xswitch itself.  */
-	if (HUB_WIDGET_ID_MIN > 0) {
-		hubv = xvolinfo->xswitch_volunteer[0];
-		xswitch_info_master_assignment_set(xswitch_info, (xwidgetnum_t)0, hubv);
-	}
-
-	/*
-	 * TBD: Use administrative information to alter assignment of
-	 * widgets to hubs.
-	 */
-	for (widgetnum=HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
-		int i;
-
-		/*
-		 * Ignore disabled/empty ports.
-		 */
-		if (!xbow_port_io_enabled(nasid, widgetnum)) 
-		    continue;
-
-		/*
-		 * If this is the master IO board, assign it to the same 
-		 * hub that owned it in the prom.
-		 */
-		if (is_master_nasid_widget(nasid, widgetnum)) {
-			for (i=0; i<num_volunteer; i++) {
-				hubv = xvolinfo->xswitch_volunteer[i];
-				hubinfo_get(hubv, &hubinfo);
-				nasid = hubinfo->h_nasid;
-				if (nasid == get_console_nasid())
-					goto do_assignment;
-			}
-		}
-
-		/*
-		 * Assuming that we're dual-hosted and that PCI cards 
-		 * are naturally placed left-to-right, alternate PCI 
-		 * buses across both Cbricks.   For Pbricks, and Ibricks,
-                 * io_brick_map_widget() returns the PCI bus number
-                 * associated with the given brick type and widget number.
-                 * For Xbricks, it returns the XIO slot number.
-		 */
-
-		i = 0;
-		if (num_volunteer > 1) {
-                        int	       bt;
-
-                       	bt = iobrick_type_get_nasid(nasid);
-                        if (bt >= 0) {
-				/*
-				 * PXBRICK has two busses per widget so this
-				 * algorithm wouldn't work (all busses would
-				 * be assigned to one volunteer). Change the
-				 * bricktype to PBRICK whose mapping is setup
-				 * suchthat 2 of the PICs will be assigned to
-				 * one volunteer and the other one will be
-				 * assigned to the other volunteer.
-				 */
-				if (bt == MODULE_PXBRICK) 
-					bt = MODULE_PBRICK;
-
-			        i = io_brick_map_widget(bt, widgetnum) & 1;
-                        }
-                }
-
-		hubv = xvolinfo->xswitch_volunteer[i];
-
-do_assignment:
-		/*
-		 * At this point, we want to make hubv the master of widgetnum.
-		 */
-		xswitch_info_master_assignment_set(xswitch_info, widgetnum, hubv);
-	}
-
-	xswitch_volunteer_delete(xswitch);
-}
-
-/*
- * Early iograph initialization.  Called by master CPU in mlreset().
- * Useful for including iograph.o in kernel.o.
- */
-void
-iograph_early_init(void)
-{
-/*
- * Need new way to get this information ..
- */
-	cnodeid_t cnode;
-	nasid_t nasid;
-	lboard_t *board;
-	
-	/*
-	 * Init. the board-to-hwgraph link early, so FRU analyzer
-	 * doesn't trip on leftover values if we panic early on.
-	 */
-	for(cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-		board = (lboard_t *)KL_CONFIG_INFO(nasid);
-		DBG("iograph_early_init: Found board 0x%p\n", board);
-
-		/* Check out all the board info stored on a node */
-		while(board) {
-			board->brd_graph_link = GRAPH_VERTEX_NONE;
-			board = KLCF_NEXT(board);
-			DBG("iograph_early_init: Found board 0x%p\n", board);
-		}
-	}
-
-	hubio_init();
-}
-
-/*
- * Let boot processor know that we're done initializing our node's IO
- * and then exit.
- */
-/* ARGSUSED */
-static void
-io_init_done(cnodeid_t cnodeid,cpu_cookie_t c)
-{
-	/* Let boot processor know that we're done. */
-}
-
-/* 
- * Probe to see if this hub's xtalk link is active.  If so,
- * return the Crosstalk Identification of the widget that we talk to.  
- * This is called before any of the Crosstalk infrastructure for 
- * this hub is set up.  It's usually called on the node that we're
- * probing, but not always.
- *
- * TBD: Prom code should actually do this work, and pass through 
- * hwid for our use.
- */
-static void
-early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid)
-{
-	hubreg_t llp_csr_reg;
-	nasid_t nasid;
-	hubinfo_t hubinfo;
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-
-	llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
-	/* 
-	 * If link is up, read the widget's part number.
-	 * A direct connect widget must respond to widgetnum=0.
-	 */
-	if (llp_csr_reg & IIO_LLP_CSR_IS_UP) {
-		/* TBD: Put hub into "indirect" mode */
-		/*
-		 * We're able to read from a widget because our hub's 
-		 * WIDGET_ID was set up earlier.
-		 */
-		widgetreg_t widget_id = *(volatile widgetreg_t *)
-			(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
-
-		DBG("early_probe_for_widget: Hub Vertex 0x%p is UP widget_id = 0x%x Register 0x%p\n", hubv, widget_id,
-		(volatile widgetreg_t *)(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID) );
-
-		hwid->part_num = XWIDGET_PART_NUM(widget_id);
-		hwid->rev_num = XWIDGET_REV_NUM(widget_id);
-		hwid->mfg_num = XWIDGET_MFG_NUM(widget_id);
-
-		/* TBD: link reset */
-	} else {
-
-		hwid->part_num = XWIDGET_PART_NUM_NONE;
-		hwid->rev_num = XWIDGET_REV_NUM_NONE;
-		hwid->mfg_num = XWIDGET_MFG_NUM_NONE;
-	}
-}
-
-/* Add inventory information to the widget vertex 
- * Right now (module,slot,revision) is being
- * added as inventory information.
- */
-static void
-xwidget_inventory_add(devfs_handle_t 		widgetv,
-		      lboard_t 			*board,
-		      struct xwidget_hwid_s 	hwid)
-{
-	if (!board)
-		return;
-	/* Donot add inventory information for the baseio
-	 * on a speedo with an xbox. It has already been
-	 * taken care of in SN00_vmc.
-	 * Speedo with xbox's baseio comes in at slot io1 (widget 9)
-	 */
-	device_inventory_add(widgetv,INV_IOBD,board->brd_type,
-			     board->brd_module,
-			     SLOTNUM_GETSLOT(board->brd_slot),
-			     hwid.rev_num);
-}
-
-/*
- * io_xswitch_widget_init
- *	
- */
-
-void
-io_xswitch_widget_init(devfs_handle_t  	xswitchv,
-		       devfs_handle_t	hubv,
-		       xwidgetnum_t	widgetnum,
-		       async_attach_t	aa)
-{
-	xswitch_info_t		xswitch_info;
-	xwidgetnum_t		hub_widgetid;
-	devfs_handle_t		widgetv;
-	cnodeid_t		cnode;
-	widgetreg_t		widget_id;
-	nasid_t			nasid, peer_nasid;
-	struct xwidget_hwid_s 	hwid;
-	hubinfo_t		hubinfo;
-	/*REFERENCED*/
-	int			rc;
-	char 			pathname[128];
-	char			new_name[64];
-	moduleid_t		module;
-	slotid_t		slot;
-	lboard_t		*board = NULL;
-	char			buffer[16];
-	slotid_t get_widget_slotnum(int xbow, int widget);
-	
-	DBG("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum);
-
-	/*
-	 * Verify that xswitchv is indeed an attached xswitch.
-	 */
-	xswitch_info = xswitch_info_get(xswitchv);
-	ASSERT(xswitch_info != NULL);
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-	cnode = NASID_TO_COMPACT_NODEID(nasid);
-	hub_widgetid = hubinfo->h_widgetid;
-
-	/*
-	 * Check that the widget is an io widget and is enabled
-	 * on this nasid or the `peer' nasid.  The peer nasid
-	 * is the other hub/bedrock connected to the xbow.
-	 */
-	peer_nasid = NODEPDA(cnode)->xbow_peer;
-	if (peer_nasid == INVALID_NASID)
-		/* If I don't have a peer, use myself. */
-		peer_nasid = nasid;
-	if (!xbow_port_io_enabled(nasid, widgetnum) &&
-	    !xbow_port_io_enabled(peer_nasid, widgetnum)) {
-		return;
-	}
-
-	if (xswitch_info_link_ok(xswitch_info, widgetnum)) {
-		char			name[4];
-
-		/*
-		 * If the current hub is not supposed to be the master 
-		 * for this widgetnum, then skip this widget.
-		 */
-		if (xswitch_info_master_assignment_get(xswitch_info,
-						       widgetnum) != hubv) {
-			return;
-		}
-
-		module  = NODEPDA(cnode)->module_id;
-#ifdef XBRIDGE_REGS_SIM
-		/* hardwire for now...could do this with something like:
-		 * xbow_soft_t soft = hwgraph_fastinfo_get(vhdl);
-		 * xbow_t xbow = soft->base;
-		 * xbowreg_t xwidget_id = xbow->xb_wid_id;
-		 * but I don't feel like figuring out vhdl right now..
-		 * and I know for a fact the answer is 0x2d000049 
-		 */
-		DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n");
-		DBG("XWIDGET_PART_NUM(0x2d000049)= 0x%x\n", XWIDGET_PART_NUM(0x2d000049));
-		if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM)
-#else
-		if (nasid_has_xbridge(nasid))
-#endif /* XBRIDGE_REGS_SIM */
-		{
-			board = find_lboard_module_class(
-				(lboard_t *)KL_CONFIG_INFO(nasid),
-				module,
-				KLTYPE_IOBRICK);
-
-DBG("io_xswitch_widget_init: Board 0x%p\n", board);
-{
-		lboard_t dummy;
-
-
-			if (board) {
-				DBG("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type);
-			} else {
-				DBG("io_xswitch_widget_init: FIXME did not find IOBOARD\n");
-				board = &dummy;
-			}
-				
-}
-
-			/*
-	 		 * Make sure we really want to say xbrick, pbrick,
-			 * etc. rather than XIO, graphics, etc.
-	 		 */
-
-#ifdef SUPPORT_PRINTING_M_FORMAT
-			sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-				"%cbrick" "/%s/%d",
-				NODEPDA(cnode)->module_id,
-				
-#else
-			memset(buffer, 0, 16);
-			format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF);
-			sprintf(pathname, EDGE_LBL_MODULE "/%s/"
-				"%cbrick" "/%s/%d",
-				buffer,
-#endif
-
-				(board->brd_type == KLTYPE_IBRICK) ? 'I' :
-				(board->brd_type == KLTYPE_PBRICK) ? 'P' :
-				(board->brd_type == KLTYPE_XBRICK) ? 'X' : '?',
-				EDGE_LBL_XTALK, widgetnum);
-		} 
-		
-		DBG("io_xswitch_widget_init: path= %s\n", pathname);
-		rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv);
-		
-		ASSERT(rc == GRAPH_SUCCESS);
-
-		/* This is needed to let the user programs to map the
-		 * module,slot numbers to the corresponding widget numbers
-		 * on the crossbow.
-		 */
-		rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv);
-
-		/* If we are looking at the global master io6
-		 * then add information about the version of
-		 * the io6prom as a part of "detailed inventory"
-		 * information.
-		 */
-		if (is_master_baseio(nasid,
-				     NODEPDA(cnode)->module_id,
- 				     get_widget_slotnum(0,widgetnum))) {
-			extern void klhwg_baseio_inventory_add(devfs_handle_t,
-							       cnodeid_t);
-			module 	= NODEPDA(cnode)->module_id;
-
-#ifdef XBRIDGE_REGS_SIM
-			DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n");
-			if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM)
-#else
-			if (nasid_has_xbridge(nasid))
-#endif /* XBRIDGE_REGS_SIM */
-			{
-				board = find_lboard_module(
-					(lboard_t *)KL_CONFIG_INFO(nasid),
-					module);
-				/*
-				 * Change iobrick to correct i/o brick
-				 */
-#ifdef SUPPORT_PRINTING_M_FORMAT
-				sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-#else
-				sprintf(pathname, EDGE_LBL_MODULE "/%x/"
-#endif
-					"iobrick" "/%s/%d",
-					NODEPDA(cnode)->module_id,
-					EDGE_LBL_XTALK, widgetnum);
-			} else {
-				slot = get_widget_slotnum(0, widgetnum);
-				board = get_board_name(nasid, module, slot,
-								new_name);
-				/*
-			 	 * Create the vertex for the widget, 
-				 * using the decimal 
-			 	 * widgetnum as the name of the primary edge.
-			 	 */
-#ifdef SUPPORT_PRINTING_M_FORMAT
-				sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-                                                EDGE_LBL_SLOT "/%s",
-                                        NODEPDA(cnode)->module_id,
-                                        new_name);
-#else
-				memset(buffer, 0, 16);
-				format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF);
-				sprintf(pathname, EDGE_LBL_MODULE "/%s/"
-					  	EDGE_LBL_SLOT "/%s",
-					buffer,
-					new_name);
-#endif
-			}
-
-			rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv);
-			DBG("io_xswitch_widget_init: (2) path= %s\n", pathname);
-		        /*
-		         * This is a weird ass code needed for error injection
-		         * purposes.
-		         */
-		        rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv);
-			
-			klhwg_baseio_inventory_add(widgetv,cnode);
-		}
-		sprintf(name, "%d", widgetnum);
-		DBG("io_xswitch_widget_init: FIXME hwgraph_edge_add %s xswitchv 0x%p, widgetv 0x%p\n", name, xswitchv, widgetv);
-		rc = hwgraph_edge_add(xswitchv, widgetv, name);
-		
-		/*
-		 * crosstalk switch code tracks which
-		 * widget is attached to each link.
-		 */
-		xswitch_info_vhdl_set(xswitch_info, widgetnum, widgetv);
-		
-		/*
-		 * Peek at the widget to get its crosstalk part and
-		 * mfgr numbers, then present it to the generic xtalk
-		 * bus provider to have its driver attach routine
-		 * called (or not).
-		 */
-#ifdef XBRIDGE_REGS_SIM
-		widget_id = 0x2d000049;
-		DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: id hardwired to widget_id\n");
-#else
-		widget_id = XWIDGET_ID_READ(nasid, widgetnum);
-#endif /* XBRIDGE_REGS_SIM */
-		hwid.part_num = XWIDGET_PART_NUM(widget_id);
-		hwid.rev_num = XWIDGET_REV_NUM(widget_id);
-		hwid.mfg_num = XWIDGET_MFG_NUM(widget_id);
-		/* Store some inventory information about
-		 * the xwidget in the hardware graph.
-		 */
-		xwidget_inventory_add(widgetv,board,hwid);
-		
-		(void)xwidget_register(&hwid, widgetv, widgetnum,
-				       hubv, hub_widgetid,
-				       aa);
-
-#ifdef	SN0_USE_BTE
-		bte_bpush_war(cnode, (void *)board);
-#endif
-	}
-}
-
-
-static void
-io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode)
-{
-	xwidgetnum_t		widgetnum;
-	async_attach_t          aa;
-
-	aa = async_attach_new();
-	
-	DBG("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode);
-
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; 
-	     widgetnum++) {
-		io_xswitch_widget_init(xswitchv,
-				       cnodeid_to_vertex(cnode),
-				       widgetnum, aa);
-	}
-	/* 
-	 * Wait for parallel attach threads, if any, to complete.
-	 */
-	async_attach_waitall(aa);
-	async_attach_free(aa);
-}
-
-/*
- * For each PCI bridge connected to the xswitch, add a link from the
- * board's klconfig info to the bridge's hwgraph vertex.  This lets
- * the FRU analyzer find the bridge without traversing the hardware
- * graph and risking hangs.
- */
-static void
-io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid)
-{
-	xwidgetnum_t		widgetnum;
-	char 			pathname[128];
-	devfs_handle_t		vhdl;
-	nasid_t			nasid, peer_nasid;
-	lboard_t		*board;
-
-
-
-	/* And its connected hub's nasids */
-	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
-	peer_nasid = NODEPDA(cnodeid)->xbow_peer;
-
-	/* 
-	 * Look for paths matching "<widgetnum>/pci" under xswitchv.
-	 * For every widget, init. its lboard's hwgraph link.  If the
-	 * board has a PCI bridge, point the link to it.
-	 */
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX;
-		 widgetnum++) {
-		sprintf(pathname, "%d", widgetnum);
-		if (hwgraph_traverse(xswitchv, pathname, &vhdl) !=
-		    GRAPH_SUCCESS)
-			continue;
-
-		board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid),
-				NODEPDA(cnodeid)->module_id);
-		if (board == NULL && peer_nasid != INVALID_NASID) {
-			/*
-			 * Try to find the board on our peer
-			 */
-			board = find_lboard_module(
-				(lboard_t *)KL_CONFIG_INFO(peer_nasid),
-				NODEPDA(cnodeid)->module_id);
-		}
-		if (board == NULL) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-			printk(KERN_WARNING  "Could not find PROM info for vertex %v, "
-				"FRU analyzer may fail",
-				vhdl);
-#else
-			printk(KERN_WARNING  "Could not find PROM info for vertex 0x%p, "
-				"FRU analyzer may fail",
-				(void *)vhdl);
-#endif
-			return;
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		if (hwgraph_traverse(xswitchv, pathname, &vhdl) == 
-		    GRAPH_SUCCESS)
-			board->brd_graph_link = vhdl;
-		else
-			board->brd_graph_link = GRAPH_VERTEX_NONE;
-	}
-}
-
-/*
- * Initialize all I/O on the specified node.
- */
-static void
-io_init_node(cnodeid_t cnodeid)
-{
-	/*REFERENCED*/
-	devfs_handle_t hubv, switchv, widgetv;
-	struct xwidget_hwid_s hwid;
-	hubinfo_t hubinfo;
-	int is_xswitch;
-	nodepda_t	*npdap;
-	struct semaphore *peer_sema = 0;
-	uint32_t	widget_partnum;
-	nodepda_router_info_t *npda_rip;
-	cpu_cookie_t	c = 0;
-	extern int hubdev_docallouts(devfs_handle_t);
-
-#ifdef LATER
-	/* Try to execute on the node that we're initializing. */
-	c = setnoderun(cnodeid);
-#endif
-	npdap = NODEPDA(cnodeid);
-
-	/*
-	 * Get the "top" vertex for this node's hardware
-	 * graph; it will carry the per-hub hub-specific
-	 * data, and act as the crosstalk provider master.
-	 * It's canonical path is probably something of the
-	 * form /hw/module/%M/slot/%d/node
-	 */
-	hubv = cnodeid_to_vertex(cnodeid);
-	DBG("io_init_node: Initialize IO for cnode %d hubv(node) 0x%p npdap 0x%p\n", cnodeid, hubv, npdap);
-
-	ASSERT(hubv != GRAPH_VERTEX_NONE);
-
-	hubdev_docallouts(hubv);
-
-	/*
-	 * Set up the dependent routers if we have any.
-	 */
-	npda_rip = npdap->npda_rip_first;
-
-	while(npda_rip) {
-		/* If the router info has not been initialized
-		 * then we need to do the router initialization
-		 */
-		if (!npda_rip->router_infop) {
-			router_init(cnodeid,0,npda_rip);
-		}
-		npda_rip = npda_rip->router_next;
-	}
-
-	/*
-	 * Read mfg info on this hub
-	 */
-
-	/* 
-	 * If nothing connected to this hub's xtalk port, we're done.
-	 */
-	early_probe_for_widget(hubv, &hwid);
-	if (hwid.part_num == XWIDGET_PART_NUM_NONE) {
-#ifdef PROBE_TEST
-		if ((cnodeid == 1) || (cnodeid == 2)) {
-			int index;
-
-			for (index = 0; index < 600; index++)
-				DBG("Interfering with device probing!!!\n");
-		}
-#endif
-		/* io_init_done takes cpu cookie as 2nd argument 
-		 * to do a restorenoderun for the setnoderun done 
-		 * at the start of this thread 
-		 */
-		
-		DBG("**** io_init_node: Node's 0x%p hub widget has XWIDGET_PART_NUM_NONE ****\n", hubv);
-		return;
-		/* NOTREACHED */
-	}
-
-	/* 
-	 * attach our hub_provider information to hubv,
-	 * so we can use it as a crosstalk provider "master"
-	 * vertex.
-	 */
-	xtalk_provider_register(hubv, &hub_provider);
-	xtalk_provider_startup(hubv);
-
-	/*
-	 * Create a vertex to represent the crosstalk bus
-	 * attached to this hub, and a vertex to be used
-	 * as the connect point for whatever is out there
-	 * on the other side of our crosstalk connection.
-	 *
-	 * Crosstalk Switch drivers "climb up" from their
-	 * connection point to try and take over the switch
-	 * point.
-	 *
-	 * Of course, the edges and verticies may already
-	 * exist, in which case our net effect is just to
-	 * associate the "xtalk_" driver with the connection
-	 * point for the device.
-	 */
-
-	(void)hwgraph_path_add(hubv, EDGE_LBL_XTALK, &switchv);
-
-	DBG("io_init_node: Created 'xtalk' entry to '../node/' xtalk vertex 0x%p\n", switchv);
-
-	ASSERT(switchv != GRAPH_VERTEX_NONE);
-
-	(void)hwgraph_edge_add(hubv, switchv, EDGE_LBL_IO);
-
-	DBG("io_init_node: Created symlink 'io' from ../node/io to ../node/xtalk \n");
-
-	/*
-	 * We need to find the widget id and update the basew_id field
-	 * accordingly. In particular, SN00 has direct connected bridge,
-	 * and hence widget id is Not 0.
-	 */
-
-	widget_partnum = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + WIDGET_ID))) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT;
-
-	if (widget_partnum == BRIDGE_WIDGET_PART_NUM ||
-				widget_partnum == XBRIDGE_WIDGET_PART_NUM){
-		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-
-		DBG("io_init_node: Found XBRIDGE widget_partnum= 0x%x\n", widget_partnum);
-
-	} else if ((widget_partnum == XBOW_WIDGET_PART_NUM) ||
-			(widget_partnum == XXBOW_WIDGET_PART_NUM) ||
-			(widget_partnum == PXBOW_WIDGET_PART_NUM) ) {
-		/* 
-		 * Xbow control register does not have the widget ID field.
-		 * So, hard code the widget ID to be zero.
-		 */
-		DBG("io_init_node: Found XBOW widget_partnum= 0x%x\n", widget_partnum);
-		npdap->basew_id = 0;
-
-	} else {
-		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-
-		panic(" ****io_init_node: Unknown Widget Part Number 0x%x Widget ID 0x%x attached to Hubv 0x%p ****\n", widget_partnum, npdap->basew_id, (void *)hubv);
-
-		/*NOTREACHED*/
-	}
-	{
-		char widname[10];
-		sprintf(widname, "%x", npdap->basew_id);
-		(void)hwgraph_path_add(switchv, widname, &widgetv);
-		DBG("io_init_node: Created '%s' to '..node/xtalk/' vertex 0x%p\n", widname, widgetv);
-		ASSERT(widgetv != GRAPH_VERTEX_NONE);
-	}
-	
-	nodepda->basew_xc = widgetv;
-
-	is_xswitch = xwidget_hwid_is_xswitch(&hwid);
-
-	/* 
-	 * Try to become the master of the widget.  If this is an xswitch
-	 * with multiple hubs connected, only one will succeed.  Mastership
-	 * of an xswitch is used only when touching registers on that xswitch.
-	 * The slave xwidgets connected to the xswitch can be owned by various
-	 * masters.
-	 */
-	if (device_master_set(widgetv, hubv) == 0) {
-
-		/* Only one hub (thread) per Crosstalk device or switch makes
-		 * it to here.
-		 */
-
-		/* 
-		 * Initialize whatever xwidget is hanging off our hub.
-		 * Whatever it is, it's accessible through widgetnum 0.
-		 */
-		hubinfo_get(hubv, &hubinfo);
-
-		(void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL);
-
-		if (!is_xswitch) {
-			/* io_init_done takes cpu cookie as 2nd argument 
-			 * to do a restorenoderun for the setnoderun done 
-			 * at the start of this thread 
-			 */
-			io_init_done(cnodeid,c);
-			/* NOTREACHED */
-		}
-
-		/* 
-		 * Special handling for Crosstalk Switches (e.g. xbow).
-		 * We need to do things in roughly the following order:
-		 *	1) Initialize xswitch hardware (done above)
-		 *	2) Determine which hubs are available to be widget masters
-		 *	3) Discover which links are active from the xswitch
-		 *	4) Assign xwidgets hanging off the xswitch to hubs
-		 *	5) Initialize all xwidgets on the xswitch
-		 */
-
-		volunteer_for_widgets(switchv, hubv);
-
-		/* If there's someone else on this crossbow, recognize him */
-		if (npdap->xbow_peer != INVALID_NASID) {
-			nodepda_t *peer_npdap = NODEPDA(NASID_TO_COMPACT_NODEID(npdap->xbow_peer));
-			peer_sema = &peer_npdap->xbow_sema;
-			volunteer_for_widgets(switchv, peer_npdap->node_vertex);
-		}
-
-		assign_widgets_to_volunteers(switchv, hubv);
-
-		/* Signal that we're done */
-		if (peer_sema) {
-			mutex_unlock(peer_sema);
-		}
-		
-	}
-	else {
-	    /* Wait 'til master is done assigning widgets. */
-	    mutex_lock(&npdap->xbow_sema);
-	}
-
-#ifdef PROBE_TEST
-	if ((cnodeid == 1) || (cnodeid == 2)) {
-		int index;
-
-		for (index = 0; index < 500; index++)
-			DBG("Interfering with device probing!!!\n");
-	}
-#endif
-	/* Now both nodes can safely inititialize widgets */
-	io_init_xswitch_widgets(switchv, cnodeid);
-	io_link_xswitch_widgets(switchv, cnodeid);
-
-	/* io_init_done takes cpu cookie as 2nd argument 
-	 * to do a restorenoderun for the setnoderun done 
-	 * at the start of this thread 
-	 */
-	io_init_done(cnodeid,c);
-
-	DBG("\nio_init_node: DONE INITIALIZED ALL I/O FOR CNODEID %d\n\n", cnodeid);
-}
-
-
-#define IOINIT_STKSZ	(16 * 1024)
-
-#define __DEVSTR1 	"/../.master/"
-#define __DEVSTR2 	"/target/"
-#define __DEVSTR3 	"/lun/0/disk/partition/"
-#define	__DEVSTR4	"/../ef"
-
-/*
- * Currently, we need to allow for 5 IBrick slots with 1 FC each
- * plus an internal 1394.
- *
- * ioconfig starts numbering SCSI's at NUM_BASE_IO_SCSI_CTLR.
- */
-#define NUM_BASE_IO_SCSI_CTLR 6
-
-/*
- * This tells ioconfig where it can start numbering scsi controllers.
- * Below this base number, platform-specific handles the numbering.
- * XXX Irix legacy..controller numbering should be part of devfsd's job
- */
-int num_base_io_scsi_ctlr = 2; /* used by syssgi */
-devfs_handle_t		base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR];
-static devfs_handle_t	baseio_enet_vhdl,baseio_console_vhdl;
-
-/*
- * Put the logical controller number information in the 
- * scsi controller vertices for each scsi controller that
- * is in a "fixed position".
- */
-static void
-scsi_ctlr_nums_add(devfs_handle_t pci_vhdl)
-{
-	{
-		int i;
-
-		num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR;
-
-		/* Initialize base_io_scsi_ctlr_vhdl array */
-		for (i=0; i<num_base_io_scsi_ctlr; i++)
-			base_io_scsi_ctlr_vhdl[i] = GRAPH_VERTEX_NONE;
-	}
-	{
-	/*
-	 * May want to consider changing the SN0 code, above, to work more like
-	 * the way this works.
-	 */
-	devfs_handle_t base_ibrick_xbridge_vhdl;
-	devfs_handle_t base_ibrick_xtalk_widget_vhdl;
-	devfs_handle_t scsi_ctlr_vhdl;
-	int i;
-	graph_error_t rv;
-
-	/*
-	 * This is a table of "well-known" SCSI controllers and their well-known
-	 * controller numbers.  The names in the table start from the base IBrick's
-	 * Xbridge vertex, so the first component is the xtalk widget number.
-	 */
-	static struct {
-		char	*base_ibrick_scsi_path;
-		int	controller_number;
-	} hardwired_scsi_controllers[] = {
-		{"15/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 0},
-		{"15/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 1},
-		{"15/" EDGE_LBL_PCI "/3/" EDGE_LBL_SCSI_CTLR "/0", 2},
-		{"14/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 3},
-		{"14/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 4},
-		{"15/" EDGE_LBL_PCI "/6/ohci/0/" EDGE_LBL_SCSI_CTLR "/0", 5},
-		{NULL, -1} /* must be last */
-	};
-
-	base_ibrick_xtalk_widget_vhdl = hwgraph_connectpt_get(pci_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xtalk_widget_vhdl != GRAPH_VERTEX_NONE);
-
-	base_ibrick_xbridge_vhdl = hwgraph_connectpt_get(base_ibrick_xtalk_widget_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xbridge_vhdl != GRAPH_VERTEX_NONE);
-	hwgraph_vertex_unref(base_ibrick_xtalk_widget_vhdl);
-
-	/*
-	 * Iterate through the list of well-known SCSI controllers.
-	 * For each controller found, set it's controller number according
-	 * to the table.
-	 */
-	for (i=0; hardwired_scsi_controllers[i].base_ibrick_scsi_path != NULL; i++) {
-		rv = hwgraph_path_lookup(base_ibrick_xbridge_vhdl,
-			hardwired_scsi_controllers[i].base_ibrick_scsi_path, &scsi_ctlr_vhdl, NULL);
-
-		if (rv != GRAPH_SUCCESS) /* No SCSI at this path */
-			continue;
-
-		ASSERT(hardwired_scsi_controllers[i].controller_number < NUM_BASE_IO_SCSI_CTLR);
-		base_io_scsi_ctlr_vhdl[hardwired_scsi_controllers[i].controller_number] = scsi_ctlr_vhdl;
-		device_controller_num_set(scsi_ctlr_vhdl, hardwired_scsi_controllers[i].controller_number);
-		hwgraph_vertex_unref(scsi_ctlr_vhdl); /* (even though we're actually keeping a reference) */
-	}
-
-	hwgraph_vertex_unref(base_ibrick_xbridge_vhdl);
-	}
-}
-
-
-#include <asm/sn/ioerror_handling.h>
-devfs_handle_t		sys_critical_graph_root = GRAPH_VERTEX_NONE;
-
-/* Define the system critical vertices and connect them through
- * a canonical parent-child relationships for easy traversal
- * during io error handling.
- */
-static void
-sys_critical_graph_init(void)
-{
-	devfs_handle_t		bridge_vhdl,master_node_vhdl;
-	devfs_handle_t  		xbow_vhdl = GRAPH_VERTEX_NONE;
-	extern devfs_handle_t	hwgraph_root;
-	devfs_handle_t		pci_slot_conn;
-	int			slot;
-	devfs_handle_t		baseio_console_conn;
-
-	DBG("sys_critical_graph_init: FIXME.\n");
-	baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl);
-
-	if (baseio_console_conn == NULL) {
-		return;
-	}
-
-	/* Get the vertex handle for the baseio bridge */
-	bridge_vhdl = device_master_get(baseio_console_conn);
-
-	/* Get the master node of the baseio card */
-	master_node_vhdl = cnodeid_to_vertex(
-				master_node_get(baseio_console_vhdl));
-	
-	/* Add the "root->node" part of the system critical graph */
-
-	sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl);
-
-	/* Check if we have a crossbow */
-	if (hwgraph_traverse(master_node_vhdl,
-			     EDGE_LBL_XTALK"/0",
-			     &xbow_vhdl) == GRAPH_SUCCESS) {
-		/* We have a crossbow.Add "node->xbow" part of the system 
-		 * critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl);
-		
-		/* Add "xbow->baseio bridge" of the system critical graph */
-		sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl);
-
-		hwgraph_vertex_unref(xbow_vhdl);
-	} else 
-		/* We donot have a crossbow. Add "node->baseio_bridge"
-		 * part of the system critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl);
-
-	/* Add all the populated PCI slot vertices to the system critical
-	 * graph with the bridge vertex as the parent.
-	 */
-	for (slot = 0 ; slot < 8; slot++) {
-		char	slot_edge[10];
-
-		sprintf(slot_edge,"%d",slot);
-		if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn)
-		    != GRAPH_SUCCESS)
-			continue;
-		sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	hwgraph_vertex_unref(bridge_vhdl);
-
-	/* Add the "ioc3 pci connection point  -> console ioc3" part 
-	 * of the system critical graph
-	 */
-
-	if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_console_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "ethernet pci connection point  -> base ethernet" part of 
-	 * the system  critical graph
-	 */
-	if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_enet_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "scsi controller pci connection point  -> base scsi 
-	 * controller" part of the system critical graph
-	 */
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[0]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[1]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	hwgraph_vertex_unref(baseio_console_conn);
-
-}
-
-static void
-baseio_ctlr_num_set(void)
-{
-	char 			name[MAXDEVNAME];
-	devfs_handle_t		console_vhdl, pci_vhdl, enet_vhdl;
-	devfs_handle_t		ioc3_console_vhdl_get(void);
-
-
-	DBG("baseio_ctlr_num_set; FIXME\n");
-	console_vhdl = ioc3_console_vhdl_get();
-	if (console_vhdl == GRAPH_VERTEX_NONE)
-		return;
-	/* Useful for setting up the system critical graph */
-	baseio_console_vhdl = console_vhdl;
-
-	vertex_to_name(console_vhdl,name,MAXDEVNAME);
-
-	strcat(name,__DEVSTR1);
-	pci_vhdl =  hwgraph_path_to_vertex(name);
-	scsi_ctlr_nums_add(pci_vhdl);
-	/* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(pci_vhdl);
-
-	vertex_to_name(console_vhdl, name, MAXDEVNAME);
-	strcat(name, __DEVSTR4);
-	enet_vhdl = hwgraph_path_to_vertex(name);
-
-	/* Useful for setting up the system critical graph */
-	baseio_enet_vhdl = enet_vhdl;
-
-	device_controller_num_set(enet_vhdl, 0);
-	/* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(enet_vhdl);
-}
-/* #endif */
-
-void
-sn00_rrb_alloc(devfs_handle_t vhdl, int *vendor_list)
-{
-	/* REFERENCED */
-	int rtn_val;
-
-	/* 
-	** sn00 population:		errb	orrb
-	**	0- ql			3+?
-	**	1- ql			        2
-	**	2- ioc3 ethernet	2+?
-	**	3- ioc3 secondary	        1
-	**	4-                      0
-	** 	5- PCI slot
-	** 	6- PCI slot
-	** 	7- PCI slot
-	*/	
-	
-	/* The following code implements this heuristic for getting 
-	 * maximum usage out of the rrbs
-	 *
-	 * constraints:
-	 *  8 bit ql1 needs 1+1
-	 *  ql0 or ql5,6,7 wants 1+2
-	 *  ethernet wants 2 or more
-	 *
-	 * rules for even rrbs:
-	 *  if nothing in slot 6 
-	 *   4 rrbs to 0 and 2  (0xc8889999)
-	 *  else 
-         *   3 2 3 to slots 0 2 6  (0xc8899bbb)
-	 *
-         * rules for odd rrbs
-	 *  if nothing in slot 5 or 7  (0xc8889999)
-	 *   4 rrbs to 1 and 3
-	 *  else if 1 thing in 5 or 7  (0xc8899aaa) or (0xc8899bbb)
-         *   3 2 3 to slots 1 3 5|7
-         *  else
-         *   2 1 3 2 to slots 1 3 5 7 (note: if there's a ql card in 7 this
-	 *           (0xc89aaabb)      may short what it wants therefore the
-	 *			       rule should be to plug pci slots in order)
-	 */
-
-
-	if (vendor_list[6] != PCIIO_VENDOR_ID_NONE) {
-		/* something in slot 6 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 3,1, 2,0, 0,0, 3,0);
-	}
-	else {
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 4,1, 4,0, 0,0, 0,0);
-	}
-	if (rtn_val)
-		printk(KERN_WARNING  "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
-
-	if ((vendor_list[5] != PCIIO_VENDOR_ID_NONE) && 
-	    (vendor_list[7] != PCIIO_VENDOR_ID_NONE)) {
-		/* soemthing in slot 5 and 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 2,1, 1,0, 3,0, 2,0);
-	}
-	else if (vendor_list[5] != PCIIO_VENDOR_ID_NONE) {
-		/* soemthing in slot 5 but not 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 3,0, 0,0);
-	}
-	else if (vendor_list[7] != PCIIO_VENDOR_ID_NONE) {
-		/* soemthing in slot 7 but not 5 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 0,0, 3,0);
-	}
-	else {
-		/* nothing in slot 5 or 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 4,1, 4,0, 0,0, 0,0);
-	}
-	if (rtn_val)
-		printk(KERN_WARNING  "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
-}
-
-
-/*
- * Initialize all I/O devices.  Starting closest to nodes, probe and
- * initialize outward.
- */
-void
-init_all_devices(void)
-{
-	/* Governor on init threads..bump up when safe 
-	 * (beware many devfs races) 
-	 */
-	cnodeid_t cnodeid, active;
-
-	active = 0;
-	for (cnodeid = 0; cnodeid < numnodes; cnodeid++) {
-                DBG("init_all_devices: Calling io_init_node() for cnode %d\n", cnodeid);
-                io_init_node(cnodeid);
-
-		DBG("init_all_devices: Done io_init_node() for cnode %d\n", cnodeid);
-	}
-
-	for (cnodeid = 0; cnodeid < numnodes; cnodeid++)
-		/*
-	 	 * Update information generated by IO init.
-		 */
-		update_node_information(cnodeid);
-
-	baseio_ctlr_num_set();
-	/* Setup the system critical graph (which is a subgraph of the
-	 * main hwgraph). This information is useful during io error
-	 * handling.
-	 */
-	sys_critical_graph_init();
-
-#if HWG_PRINT
-	hwgraph_print();
-#endif
-
-}
-
-#define toint(x) ((int)(x) - (int)('0'))
-
-void
-devnamefromarcs(char *devnm)
-{
-	int 			val;
-	char 			tmpnm[MAXDEVNAME];
-	char 			*tmp1, *tmp2;
-	
-	val = strncmp(devnm, "dks", 3);
-	if (val != 0) 
-		return;
-	tmp1 = devnm + 3;
-	if (!isdigit(*tmp1))
-		return;
-
-	val = 0;
-	while (isdigit(*tmp1)) {
-		val = 10*val+toint(*tmp1);
-		tmp1++;
-	}
-
-	if(*tmp1 != 'd')
-		return;
-	else
-		tmp1++;
-
-	if ((val < 0) || (val >= num_base_io_scsi_ctlr)) {
-		int i;
-		int viable_found = 0;
-
-		DBG("Only controller numbers 0..%d  are supported for\n", NUM_BASE_IO_SCSI_CTLR-1);
-		DBG("prom \"root\" variables of the form dksXdXsX.\n");
-		DBG("To use another disk you must use the full hardware graph path\n\n");
-		DBG("Possible controller numbers for use in 'dksXdXsX' on this system: ");
-		for (i=0; i<NUM_BASE_IO_SCSI_CTLR; i++) {
-			if (base_io_scsi_ctlr_vhdl[i] != GRAPH_VERTEX_NONE) {
-				DBG("%d ", i);
-				viable_found=1;
-			}
-		}
-		if (viable_found)
-			DBG("\n");
-		else
-			DBG("none found!\n");
-
-		DELAY(15000000);
-		//prom_reboot();
-		panic("FIXME: devnamefromarcs: should call prom_reboot here.\n");
-		/* NOTREACHED */
-	}
-		
-	ASSERT(base_io_scsi_ctlr_vhdl[val] != GRAPH_VERTEX_NONE);
-	vertex_to_name(base_io_scsi_ctlr_vhdl[val],
-		       tmpnm,
-		       MAXDEVNAME);
-	tmp2 = 	tmpnm + strlen(tmpnm);
-	strcpy(tmp2, __DEVSTR2);
-	tmp2 += strlen(__DEVSTR2);
-	while (*tmp1 != 's') {
-		if((*tmp2++ = *tmp1++) == '\0')
-			return;
-	}	
-	tmp1++;
-	strcpy(tmp2, __DEVSTR3);
-	tmp2 += strlen(__DEVSTR3);
-	while ( (*tmp2++ = *tmp1++) )
-		;
-	tmp2--;
-	*tmp2++ = '/';
-	strcpy(tmp2, EDGE_LBL_BLOCK);
-	strcpy(devnm,tmpnm);
-}
-
-static
-struct io_brick_map_s io_brick_tab[] = {
-
-/* Ibrick widget number to PCI bus number map */
- {      MODULE_IBRICK,                          /* Ibrick type    */ 
-    /*  PCI Bus #                                  Widget #       */
-    {   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        0,                                      /* 0x8            */
-        0,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        0,                                      /* 0xc            */
-        0,                                      /* 0xd            */
-        2,                                      /* 0xe            */
-        1                                       /* 0xf            */
-     }
- },
-
-/* Pbrick widget number to PCI bus number map */
- {      MODULE_PBRICK,                          /* Pbrick type    */ 
-    /*  PCI Bus #                                  Widget #       */
-    {   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        2,                                      /* 0x8            */
-        1,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        5,                                      /* 0xc            */
-        6,                                      /* 0xd            */
-        4,                                      /* 0xe            */
-        3                                       /* 0xf            */
-    }
- },
-
-/* PXbrick widget number to PCI bus number map */
- {      MODULE_PXBRICK,                         /* PXbrick type   */ 
-    /*  PCI Bus #                                  Widget #       */
-    {   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        0,                                      /* 0x8            */
-        0,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        1,                                      /* 0xc            */
-        5,                                      /* 0xd            */
-        0,                                      /* 0xe            */
-        3                                       /* 0xf            */
-    }
- },
-
-/* Xbrick widget to XIO slot map */
- {      MODULE_XBRICK,                          /* Xbrick type    */ 
-    /*  XIO Slot #                                 Widget #       */
-    {   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        1,                                      /* 0x8            */
-        3,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        2,                                      /* 0xc            */
-        4,                                      /* 0xd            */
-        0,                                      /* 0xe            */
-        0                                       /* 0xf            */
-    }
- }
-};
-
-/*
- * Use the brick's type to map a widget number to a meaningful int
- */
-int
-io_brick_map_widget(int brick_type, int widget_num)
-{
-        int num_bricks, i;
-
-        /* Calculate number of bricks in table */
-        num_bricks = sizeof(io_brick_tab)/sizeof(io_brick_tab[0]);
-
-        /* Look for brick prefix in table */
-        for (i = 0; i < num_bricks; i++) {
-               if (brick_type == io_brick_tab[i].ibm_type)
-                       return(io_brick_tab[i].ibm_map_wid[widget_num]);
-        }
-
-        return 0;
-
-}
-
-/*
- * Use the device's vertex to map the device's widget to a meaningful int
- */
-int
-io_path_map_widget(devfs_handle_t vertex)
-{
-        char hw_path_name[MAXDEVNAME];
-        char *wp, *bp, *sp = NULL;
-        int  widget_num;
-	long atoi(char *);
-	int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-
-
-        /* Get the full path name of the vertex */
-        if (GRAPH_SUCCESS != hwgraph_vertex_name_get(vertex, hw_path_name,
-                                                     MAXDEVNAME))
-                return 0;
-
-        /* Find the widget number in the path name */
-        wp = strstr(hw_path_name, "/"EDGE_LBL_XTALK"/");
-        if (wp == NULL)
-                return 0;
-        widget_num = atoi(wp+7);
-        if (widget_num < XBOW_PORT_8 || widget_num > XBOW_PORT_F)
-                return 0;
-
-        /* Find "brick" in the path name */
-        bp = strstr(hw_path_name, "brick");
-        if (bp == NULL)
-                return 0;
-
-        /* Find preceding slash */
-        sp = bp;
-        while (sp > hw_path_name) {
-                sp--;
-                if (*sp == '/')
-                        break;
-        }
-
-        /* Invalid if no preceding slash */
-        if (!sp)
-                return 0;
-
-        /* Bump slash pointer to "brick" prefix */
-        sp++;
-        /*
-         * Verify "brick" prefix length;  valid exaples:
-         * 'I' from "/Ibrick"
-         * 'P' from "/Pbrick"
-         * 'X' from "/Xbrick"
-         */
-         if ((bp - sp) != 1)
-                return 0;
-
-        return (io_brick_map_widget((int)*sp, widget_num));
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/module.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/module.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/module.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/module.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,311 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn1/hubdev.h>
-#include <asm/sn/module.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/sn_cpuid.h>
-
-
-/* #define LDEBUG	1 */
-
-#ifdef LDEBUG
-#define DPRINTF		printk
-#define printf		printk
-#else
-#define DPRINTF(x...)
-#endif
-
-module_t	       *modules[MODULE_MAX];
-int			nummodules;
-
-#define SN00_SERIAL_FUDGE	0x3b1af409d513c2
-#define SN0_SERIAL_FUDGE	0x6e
-
-void
-encode_int_serial(uint64_t src,uint64_t *dest)
-{
-    uint64_t val;
-    int i;
-
-    val = src + SN00_SERIAL_FUDGE;
-
-
-    for (i = 0; i < sizeof(long long); i++) {
-	((char*)dest)[i] =
-	    ((char*)&val)[sizeof(long long)/2 +
-			 ((i%2) ? ((i/2 * -1) - 1) : (i/2))];
-    }
-}
-
-
-void
-decode_int_serial(uint64_t src, uint64_t *dest)
-{
-    uint64_t val;
-    int i;
-
-    for (i = 0; i < sizeof(long long); i++) {
-	((char*)&val)[sizeof(long long)/2 +
-		     ((i%2) ? ((i/2 * -1) - 1) : (i/2))] =
-	    ((char*)&src)[i];
-    }
-
-    *dest = val - SN00_SERIAL_FUDGE;
-}
-
-
-void
-encode_str_serial(const char *src, char *dest)
-{
-    int i;
-
-    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) {
-
-	dest[i] = src[MAX_SERIAL_NUM_SIZE/2 +
-		     ((i%2) ? ((i/2 * -1) - 1) : (i/2))] +
-	    SN0_SERIAL_FUDGE;
-    }
-}
-
-void
-decode_str_serial(const char *src, char *dest)
-{
-    int i;
-
-    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) {
-	dest[MAX_SERIAL_NUM_SIZE/2 +
-	    ((i%2) ? ((i/2 * -1) - 1) : (i/2))] = src[i] -
-	    SN0_SERIAL_FUDGE;
-    }
-}
-
-
-module_t *module_lookup(moduleid_t id)
-{
-    int			i;
-
-    for (i = 0; i < nummodules; i++)
-	if (modules[i]->id == id) {
-	    DPRINTF("module_lookup: found m=0x%p\n", modules[i]);
-	    return modules[i];
-	}
-
-    return NULL;
-}
-
-/*
- * module_add_node
- *
- *   The first time a new module number is seen, a module structure is
- *   inserted into the module list in order sorted by module number
- *   and the structure is initialized.
- *
- *   The node number is added to the list of nodes in the module.
- */
-
-module_t *module_add_node(moduleid_t id, cnodeid_t n)
-{
-    module_t	       *m;
-    int			i;
-    char		buffer[16];
-
-#ifdef __ia64
-    memset(buffer, 0, 16);
-    format_module_id(buffer, id, MODULE_FORMAT_BRIEF);
-    DPRINTF("module_add_node: id=%s node=%d\n", buffer, n);
-#endif
-
-    if ((m = module_lookup(id)) == 0) {
-#ifdef LATER
-	m = kmem_zalloc_node(sizeof (module_t), KM_NOSLEEP, n);
-#else
-	m = kmalloc(sizeof (module_t), GFP_KERNEL);
-	memset(m, 0 , sizeof(module_t));
-#endif
-	ASSERT_ALWAYS(m);
-
-	m->id = id;
-	spin_lock_init(&m->lock);
-
-	mutex_init_locked(&m->thdcnt);
-
-	elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n));
-	spin_lock_init(&m->elsclock);
-
-	/* Insert in sorted order by module number */
-
-	for (i = nummodules; i > 0 && modules[i - 1]->id > id; i--)
-	    modules[i] = modules[i - 1];
-
-	modules[i] = m;
-	nummodules++;
-    }
-
-    m->nodes[m->nodecnt++] = n;
-
-    DPRINTF("module_add_node: module %s now has %d nodes\n", buffer, m->nodecnt);
-
-    return m;
-}
-
-int module_probe_snum(module_t *m, nasid_t nasid)
-{
-    lboard_t	       *board;
-    klmod_serial_num_t *comp;
-    char * bcopy(const char * src, char * dest, int count);
-    char serial_number[16];
-
-    /*
-     * record brick serial number
-     */
-    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-
-    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
-    {
-#if	LDEBUG
-	printf ("module_probe_snum: no IP35 board found!\n");
-#endif
-	return 0;
-    }
-
-    board_serial_number_get( board, serial_number );
-    if( serial_number[0] != '\0' ) {
-	encode_str_serial( serial_number, m->snum.snum_str );
-	m->snum_valid = 1;
-    }
-#if	LDEBUG
-    else {
-	printf("module_probe_snum: brick serial number is null!\n");
-    }
-    printf("module_probe_snum: brick serial number == %s\n", serial_number);
-#endif /* DEBUG */
-
-    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid),
-			KLTYPE_IOBRICK_XBOW);
-
-    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
-	return 0;
-
-    comp = GET_SNUM_COMP(board);
-
-    if (comp) {
-#if LDEBUG
-	    int i;
-
-	    printf("********found module with id %x and string", m->id);
-
-	    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++)
-		printf(" %x ", comp->snum.snum_str[i]);
-
-	    printf("\n");	/* Fudged string is not ASCII */
-#endif
-
-	    if (comp->snum.snum_str[0] != '\0') {
-		bcopy(comp->snum.snum_str,
-		      m->sys_snum,
-		      MAX_SERIAL_NUM_SIZE);
-		m->sys_snum_valid = 1;
-	    }
-    }
-
-    if (m->sys_snum_valid)
-	return 1;
-    else {
-	DPRINTF("Invalid serial number for module %d, "
-		"possible missing or invalid NIC.", m->id);
-	return 0;
-    }
-}
-
-void
-io_module_init(void)
-{
-    cnodeid_t		node;
-    lboard_t	       *board;
-    nasid_t		nasid;
-    int			nserial;
-    module_t	       *m;
-
-    DPRINTF("*******module_init\n");
-
-    nserial = 0;
-
-    for (node = 0; node < numnodes; node++) {
-	nasid = COMPACT_TO_NASID_NODEID(node);
-
-	board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-	ASSERT(board);
-
-	m = module_add_node(board->brd_module, node);
-
-	if (! m->snum_valid && module_probe_snum(m, nasid))
-	    nserial++;
-    }
-
-    DPRINTF("********found total of %d serial numbers in the system\n",
-	    nserial);
-
-    if (nserial == 0)
-	printk(KERN_WARNING  "io_module_init: No serial number found.\n");
-}
-
-elsc_t *get_elsc(void)
-{
-	return &NODEPDA(cpuid_to_cnodeid(smp_processor_id()))->module->elsc;
-}
-
-int
-get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info)
-{
-    int i;
-
-    if (cmod < 0 || cmod >= nummodules)
-	return -EINVAL;
-
-    if (! modules[cmod]->snum_valid)
-	return -ENXIO;
-
-    mod_info->mod_num = modules[cmod]->id;
-    {
-	char temp[MAX_SERIAL_NUM_SIZE];
-
-	decode_str_serial(modules[cmod]->snum.snum_str, temp);
-
-	/* if this is an invalid serial number return an error */
-	if (temp[0] != 'K')
-	    return -ENXIO;
-
-	mod_info->serial_num = 0;
-
-	for (i = 0; i < MAX_SERIAL_NUM_SIZE && temp[i] != '\0'; i++) {
-	    mod_info->serial_num <<= 4;
-	    mod_info->serial_num |= (temp[i] & 0xf);
-
-	    mod_info->serial_str[i] = temp[i];
-	}
-
-	mod_info->serial_str[i] = '\0';
-    }
-
-    return 0;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/pci_bus_cvlink.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/pci_bus_cvlink.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/pci_bus_cvlink.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/pci_bus_cvlink.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,696 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <asm/sn/types.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/sn_cpuid.h>
-
-extern int bridge_rev_b_data_check_disable;
-
-devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
-nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
-void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
-unsigned char num_bridges;
-static int done_probing = 0;
-
-static int pci_bus_map_create(devfs_handle_t xtalk);
-devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
-
-#define SN_IOPORTS_UNIT 256
-#define MAX_IOPORTS 0xffff
-#define MAX_IOPORTS_CHUNKS (MAX_IOPORTS / SN_IOPORTS_UNIT)
-struct ioports_to_tlbs_s ioports_to_tlbs[MAX_IOPORTS_CHUNKS];
-unsigned long sn_allocate_ioports(unsigned long pci_address);
-extern unsigned char Is_pic_on_this_nasid[512];
-
-extern void sn_init_irq_desc(void);
-
-
-/*
- * For the given device, initialize whether it is a PIC device.
- */
-static void
-set_isPIC(struct sn_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-	device_sysdata->isPIC = IS_PIC_SOFT(pcibr_soft);;
-}
-
-/*
- * pci_bus_cvlink_init() - To be called once during initialization before 
- *	SGI IO Infrastructure init is called.
- */
-void
-pci_bus_cvlink_init(void)
-{
-	memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET);
-	memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET);
-
-	memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET);
-
-	memset(ioports_to_tlbs, 0x0, sizeof(ioports_to_tlbs));
-
-	num_bridges = 0;
-}
-
-/*
- * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated 
- *	pci bus vertex from the SGI IO Infrastructure.
- */
-devfs_handle_t
-pci_bus_to_vertex(unsigned char busnum)
-{
-
-	devfs_handle_t	pci_bus = NULL;
-
-
-	/*
-	 * First get the xwidget vertex.
-	 */
-	pci_bus = busnum_to_pcibr_vhdl[busnum];
-	return(pci_bus);
-}
-
-/*
- * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
- *	and function numbers.
- */
-devfs_handle_t
-devfn_to_vertex(unsigned char busnum, unsigned int devfn)
-{
-
-	int slot = 0;
-	int func = 0;
-	char	name[16];
-	devfs_handle_t  pci_bus = NULL;
-	devfs_handle_t	device_vertex = (devfs_handle_t)NULL;
-
-	/*
-	 * Go get the pci bus vertex.
-	 */
-	pci_bus = pci_bus_to_vertex(busnum);
-	if (!pci_bus) {
-		/*
-		 * During probing, the Linux pci code invents non existant
-		 * bus numbers and pci_dev structures and tries to access
-		 * them to determine existance. Don't crib during probing.
-		 */
-		if (done_probing)
-			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
-		return(NULL);
-	}
-
-
-	/*
-	 * Go get the slot&function vertex.
-	 * Should call pciio_slot_func_to_name() when ready.
-	 */
-	slot = PCI_SLOT(devfn);
-	func = PCI_FUNC(devfn);
-
-	/*
-	 * For a NON Multi-function card the name of the device looks like:
-	 * ../pci/1, ../pci/2 ..
-	 */
-	if (func == 0) {
-        	sprintf(name, "%d", slot);
-		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
-			GRAPH_SUCCESS) {
-			if (device_vertex) {
-				return(device_vertex);
-			}
-		}
-	}
-			
-	/*
-	 * This maybe a multifunction card.  It's names look like:
-	 * ../pci/1a, ../pci/1b, etc.
-	 */
-	sprintf(name, "%d%c", slot, 'a'+func);
-	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
-		if (!device_vertex) {
-			return(NULL);
-		}
-	}
-
-	return(device_vertex);
-}
-
-/*
- * For the given device, initialize the addresses for both the Device(x) Flush 
- * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
- * is connected.
- */
-static void
-set_flush_addresses(struct pci_dev *device_dev, 
-	struct sn_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    	bridge_t               *bridge = pcibr_soft->bs_base;
-
-	device_sysdata->dma_buf_sync = (volatile unsigned int *) 
-		&(bridge->b_wr_req_buf[pciio_slot].reg);
-	device_sysdata->xbow_buf_sync = (volatile unsigned int *)
-		XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(get_nasid(), 0), 
-		pcibr_soft->bs_xid);
-#ifdef DEBUG
-
-	printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
-		device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
-
-	while((volatile unsigned int )*device_sysdata->dma_buf_sync);
-	while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
-#endif
-
-}
-
-/*
- * Most drivers currently do not properly tell the arch specific pci dma
- * interfaces whether they can handle A64. Here is where we privately
- * keep track of this.
- */
-static void __init
-set_sn_pci64(struct pci_dev *dev)
-{
-	unsigned short vendor = dev->vendor;
-	unsigned short device = dev->device;
-
-	if (vendor == PCI_VENDOR_ID_QLOGIC) {
-		if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) ||
-				(device == PCI_DEVICE_ID_QLOGIC_ISP2200)) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-	if (vendor == PCI_VENDOR_ID_SGI) {
-		if (device == PCI_DEVICE_ID_SGI_IOC3) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-}
-
-/*
- * sn_allocate_ioports() - This routine provides the allocation and 
- *	mappings between Linux style IOPORTs management.
- *
- *	For simplicity sake, SN1 will allocate IOPORTs in chunks of 
- *	256bytes .. irrespective of what the card desires.  This may 
- *	have to change when we understand how to deal with legacy ioports 
- *	which are hardcoded in some drivers e.g. SVGA.
- *
- *	Ofcourse, the SN1 IO Infrastructure has no concept of IOPORT numbers.
- *	It will remain so.  The IO Infrastructure will continue to map 
- *	IO Resource just like IRIX.  When this is done, we map IOPORT 
- *	chunks to these resources.  The Linux drivers will see and use real 
- *	IOPORT numbers.  The various IOPORT access macros e.g. inb/outb etc. 
- *	does the munging of these IOPORT numbers to make a Uncache Virtual 
- *	Address.  This address via the tlb entries generates the PCI Address 
- *	allocated by the SN1 IO Infrastructure Layer.
- */
-static unsigned long sn_ioport_num = 0x1000; /* Reserve room for Legacy stuff */
-unsigned long
-sn_allocate_ioports(unsigned long pci_address)
-{
-	
-	unsigned long ioport_index;
-
-	/*
-	 * Just some idiot checking ..
-	 */
-	if ( sn_ioport_num > 0xffff ) {
-		printk("sn_allocate_ioports: No more IO PORTS available\n");
-		return(-1);
-	}
-
-	/*
-	 * See Section 4.1.1.5 of Intel IA-64 Acrchitecture Software Developer's
-	 * Manual for details.
-	 */
-	ioport_index = sn_ioport_num / SN_IOPORTS_UNIT;
-
-	ioports_to_tlbs[ioport_index].p = 1; /* Present Bit */
-	ioports_to_tlbs[ioport_index].rv_1 = 0; /* 1 Bit */
-	ioports_to_tlbs[ioport_index].ma = 4; /* Memory Attributes 3 bits*/
-	ioports_to_tlbs[ioport_index].a = 1; /* Set Data Access Bit Fault 1 Bit*/
-	ioports_to_tlbs[ioport_index].d = 1; /* Dirty Bit */
-	ioports_to_tlbs[ioport_index].pl = 0;/* Privilege Level - All levels can R/W*/
-	ioports_to_tlbs[ioport_index].ar = 3; /* Access Rights - R/W only*/
-	ioports_to_tlbs[ioport_index].ppn = pci_address >> 12; /* 4K page size */
-	ioports_to_tlbs[ioport_index].ed = 0; /* Exception Deferral Bit */
-	ioports_to_tlbs[ioport_index].ig = 0; /* Ignored */
-
-	/* printk("sn_allocate_ioports: ioport_index 0x%x ioports_to_tlbs 0x%p\n", ioport_index, ioports_to_tlbs[ioport_index]); */
-	
-	sn_ioport_num += SN_IOPORTS_UNIT;
-
-	return(sn_ioport_num - SN_IOPORTS_UNIT);
-}
-
-/*
- * sn_pci_fixup() - This routine is called when platform_pci_fixup() is 
- *	invoked at the end of pcibios_init() to link the Linux pci 
- *	infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
- *
- *	Other platform specific fixup can also be done here.
- */
-void
-sn_pci_fixup(int arg)
-{
-	struct list_head *ln;
-	struct pci_bus *pci_bus = NULL;
-	struct pci_dev *device_dev = NULL;
-	struct sn_widget_sysdata *widget_sysdata;
-	struct sn_device_sysdata *device_sysdata;
-#ifdef SN_IOPORTS
-	unsigned long ioport;
-#endif
-	pciio_intr_t intr_handle;
-	int cpuid, bit;
-	devfs_handle_t device_vertex;
-	pciio_intr_line_t lines;
-	extern void sn_pci_find_bios(void);
-
-	if (arg == 0) {
-		sn_init_irq_desc();
-		sn_pci_find_bios();
-		return;
-	}
-
-	done_probing = 1;
-
-	/*
-	 * Initialize the pci bus vertex in the pci_bus struct.
-	 */
-	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
-		pci_bus = pci_bus_b(ln);
-		widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), 
-					GFP_KERNEL);
-		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
-		pci_bus->sysdata = (void *)widget_sysdata;
-	}
-
-	/*
- 	 * set the root start and end so that drivers calling check_region()
-	 * won't see a conflict
-	 */
-#ifdef SN_IOPORTS
-	ioport_resource.start  = sn_ioport_num;
-	ioport_resource.end = 0xffff;
-#else
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		/*
-		 * IDE legacy IO PORTs are supported in Medusa.
-		 * Just open up IO PORTs from 0 .. ioport_resource.end.
-		 */
-		ioport_resource.start = 0;
-	} else {
-		/*
-		 * We do not support Legacy IO PORT numbers.
-		 */
-		ioport_resource.start |= IO_SWIZ_BASE | __IA64_UNCACHED_OFFSET;
-	}
-	ioport_resource.end |= (HSPEC_SWIZ_BASE-1) | __IA64_UNCACHED_OFFSET;
-#endif
-
-	/*
-	 * Set the root start and end for Mem Resource.
-	 */
-	iomem_resource.start = 0;
-	iomem_resource.end = 0xffffffffffffffff;
-
-	/*
-	 * Initialize the device vertex in the pci_dev struct.
-	 */
-	pci_for_each_dev(device_dev) {
-		unsigned int irq;
-		int idx;
-		u16 cmd;
-		devfs_handle_t vhdl;
-		unsigned long size;
-		extern int bit_pos_to_irq(int);
-
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
-			extern void pci_fixup_ioc3(struct pci_dev *d);
-			pci_fixup_ioc3(device_dev);
-		}
-
-		/* Set the device vertex */
-
-		device_sysdata = kmalloc(sizeof(struct sn_device_sysdata),
-					GFP_KERNEL);
-		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
-		device_sysdata->isa64 = 0;
-		/*
-		 * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
-		 * register addresses.
-		 */
-		(void) set_flush_addresses(device_dev, device_sysdata);
-
-		device_dev->sysdata = (void *) device_sysdata;
-		set_sn_pci64(device_dev);
-		set_isPIC(device_sysdata);
-
-		pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
-
-		/*
-		 * Set the resources address correctly.  The assumption here 
-		 * is that the addresses in the resource structure has been
-		 * read from the card and it was set in the card by our
-		 * Infrastructure ..
-		 */
-		vhdl = device_sysdata->vhdl;
-		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
-			size = 0;
-			size = device_dev->resource[idx].end -
-				device_dev->resource[idx].start;
-			if (size) {
-				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
-				device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
-			}
-			else
-				continue;
-
-			device_dev->resource[idx].end = 
-				device_dev->resource[idx].start + size;
-
-			/*
-			 * Adjust the addresses to go to the SWIZZLE ..
-			 */
-			device_dev->resource[idx].start = 
-				device_dev->resource[idx].start & 0xfffff7ffffffffff;
-			device_dev->resource[idx].end = 
-				device_dev->resource[idx].end & 0xfffff7ffffffffff;
-
-			if (device_dev->resource[idx].flags & IORESOURCE_IO) {
-				cmd |= PCI_COMMAND_IO;
-#ifdef SN_IOPORTS
-				ioport = sn_allocate_ioports(device_dev->resource[idx].start);
-				if (ioport < 0) {
-					printk("sn_pci_fixup: PCI Device 0x%x on PCI Bus %d not mapped to IO PORTs .. IO PORTs exhausted\n", device_dev->devfn, device_dev->bus->number);
-					continue;
-				}
-				pciio_config_set(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + (idx * 4), 4, (res + (ioport & 0xfff)));
-
-				printk("sn_pci_fixup: ioport number %d mapped to pci address 0x%lx\n", ioport, (res + (ioport & 0xfff)));
-
-				device_dev->resource[idx].start = ioport;
-				device_dev->resource[idx].end = ioport + SN_IOPORTS_UNIT;
-#endif
-			}
-			if (device_dev->resource[idx].flags & IORESOURCE_MEM)
-				cmd |= PCI_COMMAND_MEMORY;
-		}
-		/*
-		 * Now handle the ROM resource ..
-		 */
-		size = device_dev->resource[PCI_ROM_RESOURCE].end -
-			device_dev->resource[PCI_ROM_RESOURCE].start;
-
-		if (size) {
-			device_dev->resource[PCI_ROM_RESOURCE].start =
-			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
-				size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
-			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
-			device_dev->resource[PCI_ROM_RESOURCE].end =
-			device_dev->resource[PCI_ROM_RESOURCE].start + size;
-
-                	/*
-                 	 * go through synergy swizzled space
-                 	 */
-			device_dev->resource[PCI_ROM_RESOURCE].start &= 0xfffff7ffffffffffUL;
-			device_dev->resource[PCI_ROM_RESOURCE].end   &= 0xfffff7ffffffffffUL;
-
-		}
-
-		/*
-		 * Update the Command Word on the Card.
-		 */
-		cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */
-					   /* bit gets dropped .. no harm */
-		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
-
-		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-				lines = 1;
-		}
- 
-		device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;
-		device_vertex = device_sysdata->vhdl;
- 
-		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
-
-		bit = intr_handle->pi_irq;
-		cpuid = intr_handle->pi_cpu;
-		irq = bit_pos_to_irq(bit);
-		irq = irq + (cpuid << 8);
-		pciio_intr_connect(intr_handle);
-		device_dev->irq = irq;
-#ifdef ajmtestintr
-		{
-			int slot = PCI_SLOT(device_dev->devfn);
-			static int timer_set = 0;
-			pcibr_intr_t	pcibr_intr = (pcibr_intr_t)intr_handle;
-			pcibr_soft_t	pcibr_soft = pcibr_intr->bi_soft;
-			extern void intr_test_handle_intr(int, void*, struct pt_regs *);
-
-			if (!timer_set) {
-				intr_test_set_timer();
-				timer_set = 1;
-			}
-			intr_test_register_irq(irq, pcibr_soft, slot);
-			request_irq(irq, intr_test_handle_intr,0,NULL, NULL);
-		}
-#endif
-
-	}
-}
-
-/*
- * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
- *
- *	Linux PCI Bus numbers are assigned from lowest module_id numbers
- *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
- *	HUB_WIDGET_ID_MIN:
- *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
- *
- *	Given 2 modules 001c01 and 001c02 we get the following mappings:
- *		001c01, widgetnum 15 = Bus number 0
- *		001c01, widgetnum 14 = Bus number 1
- *		001c02, widgetnum 15 = Bus number 3
- *		001c02, widgetnum 14 = Bus number 4
- *		etc.
- *
- * The rational for starting Bus Number 0 with Widget number 15 is because 
- * the system boot disks are always connected via Widget 15 Slot 0 of the 
- * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
- * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
- * module id(Master Cnode) of the system.
- *	
- */
-static int 
-pci_bus_map_create(devfs_handle_t xtalk)
-{
-
-	devfs_handle_t master_node_vertex = NULL;
-	devfs_handle_t xwidget = NULL;
-	devfs_handle_t pci_bus = NULL;
-	hubinfo_t hubinfo = NULL;
-	xwidgetnum_t widgetnum;
-	char pathname[128];
-	graph_error_t rv;
-
-	/*
-	 * Loop throught this vertex and get the Xwidgets ..
-	 */
-	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
-
-#if 0
-        {
-                int pos;
-                char dname[256];
-                pos = devfs_generate_path(xtalk, dname, 256);
-                printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-        }
-#endif
-
-		sprintf(pathname, "%d", widgetnum);
-		xwidget = NULL;
-		
-		/*
-		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
-		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
-		 */
-		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
-		if ( (rv != GRAPH_SUCCESS) ) {
-			if (!xwidget) {
-				continue;
-}
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		pci_bus = NULL;
-		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
-			if (!pci_bus) {
-				continue;
-}
-
-		/*
-		 * Assign the correct bus number and also the nasid of this 
-		 * pci Xwidget.
-		 * 
-		 * Should not be any race here ...
-		 */
-		num_bridges++;
-		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
-
-		/*
-		 * Get the master node and from there get the NASID.
-		 */
-		master_node_vertex = device_master_get(xwidget);
-		if (!master_node_vertex) {
-			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
-		}
-	
-		hubinfo_get(master_node_vertex, &hubinfo);
-		if (!hubinfo) {
-			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
-			return(1);
-		} else {
-			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
-		}
-
-		/*
-		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
-		 */
-		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
-		if (!busnum_to_atedmamaps[num_bridges - 1])
-			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
-
-		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
-
-	}
-
-        return(0);
-}
-
-/*
- * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure   
- *      initialization has completed to set up the mappings between Xbridge
- *      and logical pci bus numbers.  We also set up the NASID for each of these
- *      xbridges.
- *
- *      Must be called before pci_init() is invoked.
- */
-int
-pci_bus_to_hcl_cvlink(void) 
-{
-
-	devfs_handle_t devfs_hdl = NULL;
-	devfs_handle_t xtalk = NULL;
-	int rv = 0;
-	char name[256];
-	int master_iobrick;
-	int i;
-
-	/*
-	 * Iterate throught each xtalk links in the system ..
-	 * /hw/module/001c01/node/xtalk/ 8|9|10|11|12|13|14|15 
-	 *
-	 * /hw/module/001c01/node/xtalk/15 -> /hw/module/001c01/Ibrick/xtalk/15
-	 *
-	 * What if it is not pci?
-	 */
-	devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module");
-
-	/*
-	 * To provide consistent(not persistent) device naming, we need to start 
-	 * bus number allocation from the C-Brick with the lowest module id e.g. 001c01 
-	 * with an attached I-Brick.  Find the master_iobrick.
-	 */
-	master_iobrick = -1;
-	for (i = 0; i < nummodules; i++) {
-		moduleid_t iobrick_id; 
-		iobrick_id = iobrick_module_get(&modules[i]->elsc);
-		if (iobrick_id > 0) { /* Valid module id */
-			if (MODULE_GET_BTYPE(iobrick_id) == MODULE_IBRICK) {
-				master_iobrick = i;
-				break;
-			}
-		}
-	}
-
-	/*
-	 * The master_iobrick gets bus 0 and 1.
-	 */
-	if (master_iobrick >= 0) {
-		memset(name, 0, 256);
-		format_module_id(name, modules[master_iobrick]->id, MODULE_FORMAT_BRIEF);
-		strcat(name, "/node/xtalk");
-		xtalk = NULL;
-		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-		pci_bus_map_create(xtalk);
-	}
-		
-	/*
-	 * Now go do the rest of the modules, starting from the C-Brick with the lowest 
-	 * module id, remembering to skip the master_iobrick, which was done above.
-	 */
-	for (i = 0; i < nummodules; i++) {
-		if (i == master_iobrick) {
-			continue; /* Did the master_iobrick already. */
-		}
-
-		memset(name, 0, 256);
-		format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
-		strcat(name, "/node/xtalk");
-		xtalk = NULL;
-		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-		pci_bus_map_create(xtalk);
-	}
-
-	return(0);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/pcibr.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/pcibr.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/pcibr.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/pcibr.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,7704 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-int NeedXbridgeSwap = 0;
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_defs.h>
-#include <asm/sn/prio.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_private.h>
-
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
-extern boolean_t                is_sys_critical_vertex(devfs_handle_t);
-
-#undef PCIBR_ATE_DEBUG
-
-#if 0
-#define DEBUG 1	 /* To avoid lots of bad printk() formats leave off */
-#endif
-#define PCI_DEBUG 1
-#define ATTACH_DEBUG 1
-#define PCIBR_SOFT_LIST 1
-
-#ifndef	LOCAL
-#define	LOCAL		static
-#endif
-
-/*
- * Macros related to the Lucent USS 302/312 usb timeout workaround.  It
- * appears that if the lucent part can get into a retry loop if it sees a
- * DAC on the bus during a pio read retry.  The loop is broken after about
- * 1ms, so we need to set up bridges holding this part to allow at least
- * 1ms for pio.
- */
-
-#define USS302_TIMEOUT_WAR
-
-#ifdef USS302_TIMEOUT_WAR
-#define LUCENT_USBHC_VENDOR_ID_NUM	0x11c1
-#define LUCENT_USBHC302_DEVICE_ID_NUM	0x5801
-#define LUCENT_USBHC312_DEVICE_ID_NUM	0x5802
-#define USS302_BRIDGE_TIMEOUT_HLD	4
-#endif
-
-#define PCIBR_LLP_CONTROL_WAR
-#if defined (PCIBR_LLP_CONTROL_WAR)
-int                     pcibr_llp_control_war_cnt;
-#endif				/* PCIBR_LLP_CONTROL_WAR */
-
-int                     pcibr_devflag = D_MP;
-
-#ifdef LATER
-#define F(s,n)		{ 1l<<(s),-(s), n }
-
-struct reg_desc         bridge_int_status_desc[] =
-{
-    F(31, "MULTI_ERR"),
-    F(30, "PMU_ESIZE_EFAULT"),
-    F(29, "UNEXPECTED_RESP"),
-    F(28, "BAD_XRESP_PACKET"),
-    F(27, "BAD_XREQ_PACKET"),
-    F(26, "RESP_XTALK_ERROR"),
-    F(25, "REQ_XTALK_ERROR"),
-    F(24, "INVALID_ADDRESS"),
-    F(23, "UNSUPPORTED_XOP"),
-    F(22, "XREQ_FIFO_OFLOW"),
-    F(21, "LLP_REC_SNERROR"),
-    F(20, "LLP_REC_CBERROR"),
-    F(19, "LLP_RCTY"),
-    F(18, "LLP_TX_RETRY"),
-    F(17, "LLP_TCTY"),
-    F(16, "SSRAM_PERR"),
-    F(15, "PCI_ABORT"),
-    F(14, "PCI_PARITY"),
-    F(13, "PCI_SERR"),
-    F(12, "PCI_PERR"),
-    F(11, "PCI_MASTER_TOUT"),
-    F(10, "PCI_RETRY_CNT"),
-    F(9, "XREAD_REQ_TOUT"),
-    F(8, "GIO_BENABLE_ERR"),
-    F(7, "INT7"),
-    F(6, "INT6"),
-    F(5, "INT5"),
-    F(4, "INT4"),
-    F(3, "INT3"),
-    F(2, "INT2"),
-    F(1, "INT1"),
-    F(0, "INT0"),
-    {0}
-};
-
-struct reg_values       space_v[] =
-{
-    {PCIIO_SPACE_NONE, "none"},
-    {PCIIO_SPACE_ROM, "ROM"},
-    {PCIIO_SPACE_IO, "I/O"},
-    {PCIIO_SPACE_MEM, "MEM"},
-    {PCIIO_SPACE_MEM32, "MEM(32)"},
-    {PCIIO_SPACE_MEM64, "MEM(64)"},
-    {PCIIO_SPACE_CFG, "CFG"},
-    {PCIIO_SPACE_WIN(0), "WIN(0)"},
-    {PCIIO_SPACE_WIN(1), "WIN(1)"},
-    {PCIIO_SPACE_WIN(2), "WIN(2)"},
-    {PCIIO_SPACE_WIN(3), "WIN(3)"},
-    {PCIIO_SPACE_WIN(4), "WIN(4)"},
-    {PCIIO_SPACE_WIN(5), "WIN(5)"},
-    {PCIIO_SPACE_BAD, "BAD"},
-    {0}
-};
-
-struct reg_desc         space_desc[] =
-{
-    {0xFF, 0, "space", 0, space_v},
-    {0}
-};
-
-#if DEBUG
-#define	device_desc	device_bits
-LOCAL struct reg_desc   device_bits[] =
-{
-    {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"},
-    {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"},
-    {BRIDGE_DEV_FORCE_PCI_PAR, 0, "FORCE_PCI_PAR"},
-    {BRIDGE_DEV_VIRTUAL_EN, 0, "VIRTUAL_EN"},
-    {BRIDGE_DEV_PMU_WRGA_EN, 0, "PMU_WRGA_EN"},
-    {BRIDGE_DEV_DIR_WRGA_EN, 0, "DIR_WRGA_EN"},
-    {BRIDGE_DEV_DEV_SIZE, 0, "DEV_SIZE"},
-    {BRIDGE_DEV_RT, 0, "RT"},
-    {BRIDGE_DEV_SWAP_PMU, 0, "SWAP_PMU"},
-    {BRIDGE_DEV_SWAP_DIR, 0, "SWAP_DIR"},
-    {BRIDGE_DEV_PREF, 0, "PREF"},
-    {BRIDGE_DEV_PRECISE, 0, "PRECISE"},
-    {BRIDGE_DEV_COH, 0, "COH"},
-    {BRIDGE_DEV_BARRIER, 0, "BARRIER"},
-    {BRIDGE_DEV_GBR, 0, "GBR"},
-    {BRIDGE_DEV_DEV_SWAP, 0, "DEV_SWAP"},
-    {BRIDGE_DEV_DEV_IO_MEM, 0, "DEV_IO_MEM"},
-    {BRIDGE_DEV_OFF_MASK, BRIDGE_DEV_OFF_ADDR_SHFT, "DEV_OFF", "%x"},
-    {0}
-};
-#endif	/* DEBUG */
-
-#ifdef SUPPORT_PRINTING_R_FORMAT
-LOCAL struct reg_values xio_cmd_pactyp[] =
-{
-    {0x0, "RdReq"},
-    {0x1, "RdResp"},
-    {0x2, "WrReqWithResp"},
-    {0x3, "WrResp"},
-    {0x4, "WrReqNoResp"},
-    {0x5, "Reserved(5)"},
-    {0x6, "FetchAndOp"},
-    {0x7, "Reserved(7)"},
-    {0x8, "StoreAndOp"},
-    {0x9, "Reserved(9)"},
-    {0xa, "Reserved(a)"},
-    {0xb, "Reserved(b)"},
-    {0xc, "Reserved(c)"},
-    {0xd, "Reserved(d)"},
-    {0xe, "SpecialReq"},
-    {0xf, "SpecialResp"},
-    {0}
-};
-
-LOCAL struct reg_desc   xio_cmd_bits[] =
-{
-    {WIDGET_DIDN, -28, "DIDN", "%x"},
-    {WIDGET_SIDN, -24, "SIDN", "%x"},
-    {WIDGET_PACTYP, -20, "PACTYP", 0, xio_cmd_pactyp},
-    {WIDGET_TNUM, -15, "TNUM", "%x"},
-    {WIDGET_COHERENT, 0, "COHERENT"},
-    {WIDGET_DS, 0, "DS"},
-    {WIDGET_GBR, 0, "GBR"},
-    {WIDGET_VBPM, 0, "VBPM"},
-    {WIDGET_ERROR, 0, "ERROR"},
-    {WIDGET_BARRIER, 0, "BARRIER"},
-    {0}
-};
-#endif	/* SUPPORT_PRINTING_R_FORMAT */
-
-#if PCIBR_FREEZE_TIME || PCIBR_ATE_DEBUG
-LOCAL struct reg_desc   ate_bits[] =
-{
-    {0xFFFF000000000000ull, -48, "RMF", "%x"},
-    {~(IOPGSIZE - 1) &			/* may trim off some low bits */
-     0x0000FFFFFFFFF000ull, 0, "XIO", "%x"},
-    {0x0000000000000F00ull, -8, "port", "%x"},
-    {0x0000000000000010ull, 0, "Barrier"},
-    {0x0000000000000008ull, 0, "Prefetch"},
-    {0x0000000000000004ull, 0, "Precise"},
-    {0x0000000000000002ull, 0, "Coherent"},
-    {0x0000000000000001ull, 0, "Valid"},
-    {0}
-};
-#endif
-
-#if PCIBR_ATE_DEBUG
-LOCAL struct reg_values ssram_sizes[] =
-{
-    {BRIDGE_CTRL_SSRAM_512K, "512k"},
-    {BRIDGE_CTRL_SSRAM_128K, "128k"},
-    {BRIDGE_CTRL_SSRAM_64K, "64k"},
-    {BRIDGE_CTRL_SSRAM_1K, "1k"},
-    {0}
-};
-
-LOCAL struct reg_desc   control_bits[] =
-{
-    {BRIDGE_CTRL_FLASH_WR_EN, 0, "FLASH_WR_EN"},
-    {BRIDGE_CTRL_EN_CLK50, 0, "EN_CLK50"},
-    {BRIDGE_CTRL_EN_CLK40, 0, "EN_CLK40"},
-    {BRIDGE_CTRL_EN_CLK33, 0, "EN_CLK33"},
-    {BRIDGE_CTRL_RST_MASK, -24, "RST", "%x"},
-    {BRIDGE_CTRL_IO_SWAP, 0, "IO_SWAP"},
-    {BRIDGE_CTRL_MEM_SWAP, 0, "MEM_SWAP"},
-    {BRIDGE_CTRL_PAGE_SIZE, 0, "PAGE_SIZE"},
-    {BRIDGE_CTRL_SS_PAR_BAD, 0, "SS_PAR_BAD"},
-    {BRIDGE_CTRL_SS_PAR_EN, 0, "SS_PAR_EN"},
-    {BRIDGE_CTRL_SSRAM_SIZE_MASK, 0, "SSRAM_SIZE", 0, ssram_sizes},
-    {BRIDGE_CTRL_F_BAD_PKT, 0, "F_BAD_PKT"},
-    {BRIDGE_CTRL_LLP_XBAR_CRD_MASK, -12, "LLP_XBAR_CRD", "%d"},
-    {BRIDGE_CTRL_CLR_RLLP_CNT, 0, "CLR_RLLP_CNT"},
-    {BRIDGE_CTRL_CLR_TLLP_CNT, 0, "CLR_TLLP_CNT"},
-    {BRIDGE_CTRL_SYS_END, 0, "SYS_END"},
-    {BRIDGE_CTRL_MAX_TRANS_MASK, -4, "MAX_TRANS", "%d"},
-    {BRIDGE_CTRL_WIDGET_ID_MASK, 0, "WIDGET_ID", "%x"},
-    {0}
-};
-#endif
-#endif	/* LATER */
-
-/* kbrick widgetnum-to-bus layout */
-int p_busnum[MAX_PORT_NUM] = {                  /* widget#      */
-        0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7    */
-        2,                                      /* 0x8          */
-        1,                                      /* 0x9          */
-        0, 0,                                   /* 0xa - 0xb    */
-        5,                                      /* 0xc          */
-        6,                                      /* 0xd          */
-        4,                                      /* 0xe          */
-        3,                                      /* 0xf          */
-};
-
-/*
- * Additional PIO spaces per slot are
- * recorded in this structure.
- */
-struct pciio_piospace_s {
-    pciio_piospace_t        next;	/* another space for this device */
-    char                    free;	/* 1 if free, 0 if in use               */
-    pciio_space_t           space;	/* Which space is in use                */
-    iopaddr_t               start;	/* Starting address of the PIO space    */
-    size_t                  count;	/* size of PIO space                    */
-};
-
-#if PCIBR_SOFT_LIST
-pcibr_list_p            pcibr_list = 0;
-#endif
-
-#define	INFO_LBL_PCIBR_ASIC_REV	"_pcibr_asic_rev"
-
-#define	PCIBR_D64_BASE_UNSET	(0xFFFFFFFFFFFFFFFF)
-#define	PCIBR_D32_BASE_UNSET	(0xFFFFFFFF)
-
-#define PCIBR_VALID_SLOT(s)	(s < 8)
-
-#ifdef SN_XXX
-extern int      hub_device_flags_set(devfs_handle_t       widget_dev,
-                                     hub_widget_flags_t flags);
-#endif
-extern pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t);
-extern void free_pciio_dmamap(pcibr_dmamap_t);
-
-/*
- * This is the file operation table for the pcibr driver.
- * As each of the functions are implemented, put the 
- * appropriate function name below.
- */
-struct file_operations pcibr_fops = {
-        owner:  THIS_MODULE,
-        llseek: NULL,
-        read: NULL,
-        write: NULL,
-        readdir: NULL,
-        poll: NULL,
-        ioctl: NULL,
-        mmap: NULL,
-        open: NULL,
-        flush: NULL,
-        release: NULL,
-        fsync: NULL,
-        fasync: NULL,
-        lock: NULL,
-        readv: NULL,
-        writev: NULL
-};
-
-extern devfs_handle_t hwgraph_root;
-extern graph_error_t hwgraph_vertex_unref(devfs_handle_t vhdl);
-extern int cap_able(uint64_t x);
-extern uint64_t rmalloc(struct map *mp, size_t size);
-extern void rmfree(struct map *mp, size_t size, uint64_t a);
-extern int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-extern long atoi(register char *p);
-extern char *dev_to_name(devfs_handle_t dev, char *buf, uint buflen);
-extern cnodeid_t nodevertex_to_cnodeid(devfs_handle_t vhdl);
-extern graph_error_t hwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr);
-extern struct map *rmallocmap(uint64_t mapsiz);
-extern void rmfreemap(struct map *mp);
-extern int compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr);
-extern int io_path_map_widget(devfs_handle_t vertex);
-
-
-
-/* =====================================================================
- *    Function Table of Contents
- *
- *      The order of functions in this file has stopped
- *      making much sense. We might want to take a look
- *      at it some time and bring back some sanity, or
- *      perhaps bust this file into smaller chunks.
- */
-
-LOCAL void              do_pcibr_rrb_clear(bridge_t *, int);
-LOCAL void              do_pcibr_rrb_flush(bridge_t *, int);
-LOCAL int               do_pcibr_rrb_count_valid(bridge_t *, pciio_slot_t);
-LOCAL int               do_pcibr_rrb_count_avail(bridge_t *, pciio_slot_t);
-LOCAL int               do_pcibr_rrb_alloc(bridge_t *, pciio_slot_t, int);
-LOCAL int               do_pcibr_rrb_free(bridge_t *, pciio_slot_t, int);
-
-LOCAL void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int);
-
-int			pcibr_wrb_flush(devfs_handle_t);
-int                     pcibr_rrb_alloc(devfs_handle_t, int *, int *);
-int                     pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *);
-int                     pcibr_alloc_all_rrbs(devfs_handle_t, int, int, int, int, int, int, int, int, int);
-void                    pcibr_rrb_flush(devfs_handle_t);
-
-LOCAL int               pcibr_try_set_device(pcibr_soft_t, pciio_slot_t, unsigned, bridgereg_t);
-void                    pcibr_release_device(pcibr_soft_t, pciio_slot_t, bridgereg_t);
-
-LOCAL void              pcibr_clearwidint(bridge_t *);
-LOCAL void              pcibr_setwidint(xtalk_intr_t);
-LOCAL int               pcibr_probe_slot(bridge_t *, cfg_p, unsigned *);
-
-void                    pcibr_init(void);
-int                     pcibr_attach(devfs_handle_t);
-int			pcibr_detach(devfs_handle_t);
-int                     pcibr_open(devfs_handle_t *, int, int, cred_t *);
-int                     pcibr_close(devfs_handle_t, int, int, cred_t *);
-int                     pcibr_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                     pcibr_unmap(devfs_handle_t, vhandl_t *);
-int                     pcibr_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
-
-void                    pcibr_freeblock_sub(iopaddr_t *, iopaddr_t *, iopaddr_t, size_t);
-
-LOCAL int               pcibr_init_ext_ate_ram(bridge_t *);
-LOCAL int               pcibr_ate_alloc(pcibr_soft_t, int);
-LOCAL void              pcibr_ate_free(pcibr_soft_t, int, int);
-
-LOCAL pcibr_info_t      pcibr_info_get(devfs_handle_t);
-LOCAL pcibr_info_t      pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-LOCAL void		pcibr_device_info_free(devfs_handle_t, pciio_slot_t);
-LOCAL iopaddr_t         pcibr_addr_pci_to_xio(devfs_handle_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-
-pcibr_piomap_t          pcibr_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
-void                    pcibr_piomap_free(pcibr_piomap_t);
-caddr_t                 pcibr_piomap_addr(pcibr_piomap_t, iopaddr_t, size_t);
-void                    pcibr_piomap_done(pcibr_piomap_t);
-caddr_t                 pcibr_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-iopaddr_t               pcibr_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pcibr_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
-
-LOCAL iopaddr_t         pcibr_flags_to_d64(unsigned, pcibr_soft_t);
-LOCAL bridge_ate_t      pcibr_flags_to_ate(unsigned);
-
-pcibr_dmamap_t          pcibr_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    pcibr_dmamap_free(pcibr_dmamap_t);
-LOCAL bridge_ate_p      pcibr_ate_addr(pcibr_soft_t, int);
-LOCAL iopaddr_t         pcibr_addr_xio_to_pci(pcibr_soft_t, iopaddr_t, size_t);
-iopaddr_t               pcibr_dmamap_addr(pcibr_dmamap_t, paddr_t, size_t);
-alenlist_t              pcibr_dmamap_list(pcibr_dmamap_t, alenlist_t, unsigned);
-void                    pcibr_dmamap_done(pcibr_dmamap_t);
-cnodeid_t		pcibr_get_dmatrans_node(devfs_handle_t);
-iopaddr_t               pcibr_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pcibr_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void                    pcibr_dmamap_drain(pcibr_dmamap_t);
-void                    pcibr_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void                    pcibr_dmalist_drain(devfs_handle_t, alenlist_t);
-iopaddr_t               pcibr_dmamap_pciaddr_get(pcibr_dmamap_t);
-
-static unsigned		pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines);
-pcibr_intr_t            pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
-void                    pcibr_intr_free(pcibr_intr_t);
-LOCAL void              pcibr_setpciint(xtalk_intr_t);
-int                     pcibr_intr_connect(pcibr_intr_t);
-void                    pcibr_intr_disconnect(pcibr_intr_t);
-
-devfs_handle_t            pcibr_intr_cpu_get(pcibr_intr_t);
-void                    pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
-void                    pcibr_intr_func(intr_arg_t);
-
-void                    pcibr_provider_startup(devfs_handle_t);
-void                    pcibr_provider_shutdown(devfs_handle_t);
-
-int                     pcibr_reset(devfs_handle_t);
-pciio_endian_t          pcibr_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
-int                     pcibr_priority_bits_set(pcibr_soft_t, pciio_slot_t, pciio_priority_t);
-pciio_priority_t        pcibr_priority_set(devfs_handle_t, pciio_priority_t);
-int                     pcibr_device_flags_set(devfs_handle_t, pcibr_device_flags_t);
-
-LOCAL cfg_p             pcibr_config_addr(devfs_handle_t, unsigned);
-uint64_t                pcibr_config_get(devfs_handle_t, unsigned, unsigned);
-LOCAL uint64_t          do_pcibr_config_get(cfg_p, unsigned, unsigned);
-void                    pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
-LOCAL void              do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
-
-LOCAL pcibr_hints_t     pcibr_hints_get(devfs_handle_t, int);
-void                    pcibr_hints_fix_rrbs(devfs_handle_t);
-void                    pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
-void			pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
-void                    pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t);
-void                    pcibr_hints_handsoff(devfs_handle_t);
-void                    pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, ulong);
-
-LOCAL int		pcibr_slot_info_init(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_info_free(devfs_handle_t,pciio_slot_t);
-
-#ifdef LATER
-LOCAL int	        pcibr_slot_info_return(pcibr_soft_t, pciio_slot_t,
-                                               pcibr_slot_info_resp_t);
-LOCAL void       	pcibr_slot_func_info_return(pcibr_info_h, int,
-                                                    pcibr_slot_func_info_resp_t);
-#endif	/* LATER */
-
-LOCAL int		pcibr_slot_addr_space_init(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_device_init(devfs_handle_t, pciio_slot_t);
-LOCAL int		pcibr_slot_guest_info_init(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_call_device_attach(devfs_handle_t,
-						      pciio_slot_t, int);
-LOCAL int		pcibr_slot_call_device_detach(devfs_handle_t,
-						      pciio_slot_t, int);
-
-LOCAL int               pcibr_slot_detach(devfs_handle_t, pciio_slot_t, int);
-LOCAL int 		pcibr_is_slot_sys_critical(devfs_handle_t, pciio_slot_t);
-#ifdef LATER
-LOCAL int		pcibr_slot_query(devfs_handle_t, pcibr_slot_info_req_t);
-#endif
-
-/* =====================================================================
- *    RRB management
- */
-
-#define LSBIT(word)		((word) &~ ((word)-1))
-
-#define PCIBR_RRB_SLOT_VIRTUAL	8
-
-LOCAL void
-do_pcibr_rrb_clear(bridge_t *bridge, int rrb)
-{
-    bridgereg_t             status;
-
-    /* bridge_lock must be held;
-     * this RRB must be disabled.
-     */
-
-    /* wait until RRB has no outstanduing XIO packets. */
-    while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
-	;				/* XXX- beats on bridge. bad idea? */
-    }
-
-    /* if the RRB has data, drain it. */
-    if (status & BRIDGE_RRB_VALID(rrb)) {
-	bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
-
-	/* wait until RRB is no longer valid. */
-	while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
-	    ;				/* XXX- beats on bridge. bad idea? */
-	}
-    }
-}
-
-LOCAL void
-do_pcibr_rrb_flush(bridge_t *bridge, int rrbn)
-{
-    reg_p                   rrbp = &bridge->b_rrb_map[rrbn & 1].reg;
-    bridgereg_t             rrbv;
-    int                     shft = 4 * (rrbn >> 1);
-    unsigned                ebit = BRIDGE_RRB_EN << shft;
-
-    rrbv = *rrbp;
-    if (rrbv & ebit)
-	*rrbp = rrbv & ~ebit;
-
-    do_pcibr_rrb_clear(bridge, rrbn);
-
-    if (rrbv & ebit)
-	*rrbp = rrbv;
-}
-
-/*
- *    pcibr_rrb_count_valid: count how many RRBs are
- *      marked valid for the specified PCI slot on this
- *      bridge.
- *
- *      NOTE: The "slot" parameter for all pcibr_rrb
- *      management routines must include the "virtual"
- *      bit; when manageing both the normal and the
- *      virtual channel, separate calls to these
- *      routines must be made. To denote the virtual
- *      channel, add PCIBR_RRB_SLOT_VIRTUAL to the slot
- *      number.
- *
- *      IMPL NOTE: The obvious algorithm is to iterate
- *      through the RRB fields, incrementing a count if
- *      the RRB is valid and matches the slot. However,
- *      it is much simpler to use an algorithm derived
- *      from the "partitioned add" idea. First, XOR in a
- *      pattern such that the fields that match this
- *      slot come up "all ones" and all other fields
- *      have zeros in the mismatching bits. Then AND
- *      together the bits in the field, so we end up
- *      with one bit turned on for each field that
- *      matched. Now we need to count these bits. This
- *      can be done either with a series of shift/add
- *      instructions or by using "tmp % 15"; I expect
- *      that the cascaded shift/add will be faster.
- */
-
-LOCAL int
-do_pcibr_rrb_count_valid(bridge_t *bridge,
-			 pciio_slot_t slot)
-{
-    bridgereg_t             tmp;
-
-    tmp = bridge->b_rrb_map[slot & 1].reg;
-    tmp ^= 0x11111111 * (7 - slot / 2);
-    tmp &= (0xCCCCCCCC & tmp) >> 2;
-    tmp &= (0x22222222 & tmp) >> 1;
-    tmp += tmp >> 4;
-    tmp += tmp >> 8;
-    tmp += tmp >> 16;
-    return tmp & 15;
-}
-
-/*
- *    do_pcibr_rrb_count_avail: count how many RRBs are
- *      available to be allocated for the specified slot.
- *
- *      IMPL NOTE: similar to the above, except we are
- *      just counting how many fields have the valid bit
- *      turned off.
- */
-LOCAL int
-do_pcibr_rrb_count_avail(bridge_t *bridge,
-			 pciio_slot_t slot)
-{
-    bridgereg_t             tmp;
-
-    tmp = bridge->b_rrb_map[slot & 1].reg;
-    tmp = (0x88888888 & ~tmp) >> 3;
-    tmp += tmp >> 4;
-    tmp += tmp >> 8;
-    tmp += tmp >> 16;
-    return tmp & 15;
-}
-
-/*
- *    do_pcibr_rrb_alloc: allocate some additional RRBs
- *      for the specified slot. Returns -1 if there were
- *      insufficient free RRBs to satisfy the request,
- *      or 0 if the request was fulfilled.
- *
- *      Note that if a request can be partially filled,
- *      it will be, even if we return failure.
- *
- *      IMPL NOTE: again we avoid iterating across all
- *      the RRBs; instead, we form up a word containing
- *      one bit for each free RRB, then peel the bits
- *      off from the low end.
- */
-LOCAL int
-do_pcibr_rrb_alloc(bridge_t *bridge,
-		   pciio_slot_t slot,
-		   int more)
-{
-    int                     rv = 0;
-    bridgereg_t             reg, tmp, bit;
-
-    reg = bridge->b_rrb_map[slot & 1].reg;
-    tmp = (0x88888888 & ~reg) >> 3;
-    while (more-- > 0) {
-	bit = LSBIT(tmp);
-	if (!bit) {
-	    rv = -1;
-	    break;
-	}
-	tmp &= ~bit;
-	reg = ((reg & ~(bit * 15)) | (bit * (8 + slot / 2)));
-    }
-    bridge->b_rrb_map[slot & 1].reg = reg;
-    return rv;
-}
-
-/*
- *    do_pcibr_rrb_free: release some of the RRBs that
- *      have been allocated for the specified
- *      slot. Returns zero for success, or negative if
- *      it was unable to free that many RRBs.
- *
- *      IMPL NOTE: We form up a bit for each RRB
- *      allocated to the slot, aligned with the VALID
- *      bitfield this time; then we peel bits off one at
- *      a time, releasing the corresponding RRB.
- */
-LOCAL int
-do_pcibr_rrb_free(bridge_t *bridge,
-		  pciio_slot_t slot,
-		  int less)
-{
-    int                     rv = 0;
-    bridgereg_t             reg, tmp, clr, bit;
-    int                     i;
-
-    clr = 0;
-    reg = bridge->b_rrb_map[slot & 1].reg;
-
-    /* This needs to be done otherwise the rrb's on the virtual channel
-     * for this slot won't be freed !!
-     */
-    tmp = reg & 0xbbbbbbbb;
-
-    tmp ^= (0x11111111 * (7 - slot / 2));
-    tmp &= (0x33333333 & tmp) << 2;
-    tmp &= (0x44444444 & tmp) << 1;
-    while (less-- > 0) {
-	bit = LSBIT(tmp);
-	if (!bit) {
-	    rv = -1;
-	    break;
-	}
-	tmp &= ~bit;
-	reg &= ~bit;
-	clr |= bit;
-    }
-    bridge->b_rrb_map[slot & 1].reg = reg;
-
-    for (i = 0; i < 8; i++)
-	if (clr & (8 << (4 * i)))
-	    do_pcibr_rrb_clear(bridge, (2 * i) + (slot & 1));
-
-    return rv;
-}
-
-LOCAL void
-do_pcibr_rrb_autoalloc(pcibr_soft_t pcibr_soft,
-		       int slot,
-		       int more_rrbs)
-{
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     got;
-
-    for (got = 0; got < more_rrbs; ++got) {
-	if (pcibr_soft->bs_rrb_res[slot & 7] > 0)
-	    pcibr_soft->bs_rrb_res[slot & 7]--;
-	else if (pcibr_soft->bs_rrb_avail[slot & 1] > 0)
-	    pcibr_soft->bs_rrb_avail[slot & 1]--;
-	else
-	    break;
-	if (do_pcibr_rrb_alloc(bridge, slot, 1) < 0)
-	    break;
-#if PCIBR_RRB_DEBUG
-	printk( "do_pcibr_rrb_autoalloc: add one to slot %d%s\n",
-		slot & 7, slot & 8 ? "v" : "");
-#endif
-	pcibr_soft->bs_rrb_valid[slot]++;
-    }
-#if PCIBR_RRB_DEBUG
-    printk("%s: %d+%d free RRBs. Allocation list:\n", pcibr_soft->bs_name,
-	    pcibr_soft->bs_rrb_avail[0],
-	    pcibr_soft->bs_rrb_avail[1]);
-    for (slot = 0; slot < 8; ++slot)
-	printk("\t%d+%d+%d",
-		0xFFF & pcibr_soft->bs_rrb_valid[slot],
-		0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-		pcibr_soft->bs_rrb_res[slot]);
-	printk("\n");
-#endif
-}
-
-/*
- * Device driver interface to flush the write buffers for a specified
- * device hanging off the bridge.
- */
-int
-pcibr_wrb_flush(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    volatile bridgereg_t   *wrb_flush;
-
-    wrb_flush = &(bridge->b_wr_req_buf[pciio_slot].reg);
-    while (*wrb_flush);
-
-    return(0);
-}
-/*
- * Device driver interface to request RRBs for a specified device
- * hanging off a Bridge.  The driver requests the total number of
- * RRBs it would like for the normal channel (vchan0) and for the
- * "virtual channel" (vchan1).  The actual number allocated to each
- * channel is returned.
- *
- * If we cannot allocate at least one RRB to a channel that needs
- * at least one, return -1 (failure).  Otherwise, satisfy the request
- * as best we can and return 0.
- */
-int
-pcibr_rrb_alloc(devfs_handle_t pconn_vhdl,
-		int *count_vchan0,
-		int *count_vchan1)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     desired_vchan0;
-    int                     desired_vchan1;
-    int                     orig_vchan0;
-    int                     orig_vchan1;
-    int                     delta_vchan0;
-    int                     delta_vchan1;
-    int                     final_vchan0;
-    int                     final_vchan1;
-    int                     avail_rrbs;
-    unsigned long           s;
-    int                     error;
-
-    /*
-     * TBD: temper request with admin info about RRB allocation,
-     * and according to demand from other devices on this Bridge.
-     *
-     * One way of doing this would be to allocate two RRBs
-     * for each device on the bus, before any drivers start
-     * asking for extras. This has the weakness that one
-     * driver might not give back an "extra" RRB until after
-     * another driver has already failed to get one that
-     * it wanted.
-     */
-
-    s = pcibr_lock(pcibr_soft);
-
-    /* How many RRBs do we own? */
-    orig_vchan0 = pcibr_soft->bs_rrb_valid[pciio_slot];
-    orig_vchan1 = pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
-
-    /* How many RRBs do we want? */
-    desired_vchan0 = count_vchan0 ? *count_vchan0 : orig_vchan0;
-    desired_vchan1 = count_vchan1 ? *count_vchan1 : orig_vchan1;
-
-    /* How many RRBs are free? */
-    avail_rrbs = pcibr_soft->bs_rrb_avail[pciio_slot & 1]
-	+ pcibr_soft->bs_rrb_res[pciio_slot];
-
-    /* Figure desired deltas */
-    delta_vchan0 = desired_vchan0 - orig_vchan0;
-    delta_vchan1 = desired_vchan1 - orig_vchan1;
-
-    /* Trim back deltas to something
-     * that we can actually meet, by
-     * decreasing the ending allocation
-     * for whichever channel wants
-     * more RRBs. If both want the same
-     * number, cut the second channel.
-     * NOTE: do not change the allocation for
-     * a channel that was passed as NULL.
-     */
-    while ((delta_vchan0 + delta_vchan1) > avail_rrbs) {
-	if (count_vchan0 &&
-	    (!count_vchan1 ||
-	     ((orig_vchan0 + delta_vchan0) >
-	      (orig_vchan1 + delta_vchan1))))
-	    delta_vchan0--;
-	else
-	    delta_vchan1--;
-    }
-
-    /* Figure final RRB allocations
-     */
-    final_vchan0 = orig_vchan0 + delta_vchan0;
-    final_vchan1 = orig_vchan1 + delta_vchan1;
-
-    /* If either channel wants RRBs but our actions
-     * would leave it with none, declare an error,
-     * but DO NOT change any RRB allocations.
-     */
-    if ((desired_vchan0 && !final_vchan0) ||
-	(desired_vchan1 && !final_vchan1)) {
-
-	error = -1;
-
-    } else {
-
-	/* Commit the allocations: free, then alloc.
-	 */
-	if (delta_vchan0 < 0)
-	    (void) do_pcibr_rrb_free(bridge, pciio_slot, -delta_vchan0);
-	if (delta_vchan1 < 0)
-	    (void) do_pcibr_rrb_free(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, -delta_vchan1);
-
-	if (delta_vchan0 > 0)
-	    (void) do_pcibr_rrb_alloc(bridge, pciio_slot, delta_vchan0);
-	if (delta_vchan1 > 0)
-	    (void) do_pcibr_rrb_alloc(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, delta_vchan1);
-
-	/* Return final values to caller.
-	 */
-	if (count_vchan0)
-	    *count_vchan0 = final_vchan0;
-	if (count_vchan1)
-	    *count_vchan1 = final_vchan1;
-
-	/* prevent automatic changes to this slot's RRBs
-	 */
-	pcibr_soft->bs_rrb_fixed |= 1 << pciio_slot;
-
-	/* Track the actual allocations, release
-	 * any further reservations, and update the
-	 * number of available RRBs.
-	 */
-
-	pcibr_soft->bs_rrb_valid[pciio_slot] = final_vchan0;
-	pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL] = final_vchan1;
-	pcibr_soft->bs_rrb_avail[pciio_slot & 1] =
-	    pcibr_soft->bs_rrb_avail[pciio_slot & 1]
-	    + pcibr_soft->bs_rrb_res[pciio_slot]
-	    - delta_vchan0
-	    - delta_vchan1;
-	pcibr_soft->bs_rrb_res[pciio_slot] = 0;
-
-#if PCIBR_RRB_DEBUG
-	printk("pcibr_rrb_alloc: slot %d set to %d+%d; %d+%d free\n",
-		pciio_slot, final_vchan0, final_vchan1,
-		pcibr_soft->bs_rrb_avail[0],
-		pcibr_soft->bs_rrb_avail[1]);
-	for (pciio_slot = 0; pciio_slot < 8; ++pciio_slot)
-	    printk("\t%d+%d+%d",
-		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot],
-		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL],
-		    pcibr_soft->bs_rrb_res[pciio_slot]);
-	printk("\n");
-#endif
-
-	error = 0;
-    }
-
-    pcibr_unlock(pcibr_soft, s);
-    return error;
-}
-
-/*
- * Device driver interface to check the current state
- * of the RRB allocations.
- *
- *   pconn_vhdl is your PCI connection point (specifies which
- *      PCI bus and which slot).
- *
- *   count_vchan0 points to where to return the number of RRBs
- *      assigned to the primary DMA channel, used by all DMA
- *      that does not explicitly ask for the alternate virtual
- *      channel.
- *
- *   count_vchan1 points to where to return the number of RRBs
- *      assigned to the secondary DMA channel, used when
- *      PCIBR_VCHAN1 and PCIIO_DMA_A64 are specified.
- *
- *   count_reserved points to where to return the number of RRBs
- *      that have been automatically reserved for your device at
- *      startup, but which have not been assigned to a
- *      channel. RRBs must be assigned to a channel to be used;
- *      this can be done either with an explicit pcibr_rrb_alloc
- *      call, or automatically by the infrastructure when a DMA
- *      translation is constructed. Any call to pcibr_rrb_alloc
- *      will release any unassigned reserved RRBs back to the
- *      free pool.
- *
- *   count_pool points to where to return the number of RRBs
- *      that are currently unassigned and unreserved. This
- *      number can (and will) change as other drivers make calls
- *      to pcibr_rrb_alloc, or automatically allocate RRBs for
- *      DMA beyond their initial reservation.
- *
- * NULL may be passed for any of the return value pointers
- * the caller is not interested in.
- *
- * The return value is "0" if all went well, or "-1" if
- * there is a problem. Additionally, if the wrong vertex
- * is passed in, one of the subsidiary support functions
- * could panic with a "bad pciio fingerprint."
- */
-
-int
-pcibr_rrb_check(devfs_handle_t pconn_vhdl,
-		int *count_vchan0,
-		int *count_vchan1,
-		int *count_reserved,
-		int *count_pool)
-{
-    pciio_info_t            pciio_info;
-    pciio_slot_t            pciio_slot;
-    pcibr_soft_t            pcibr_soft;
-    unsigned long           s;
-    int                     error = -1;
-
-    if ((pciio_info = pciio_info_get(pconn_vhdl)) &&
-	(pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info)) &&
-	((pciio_slot = pciio_info_slot_get(pciio_info)) < 8)) {
-
-	s = pcibr_lock(pcibr_soft);
-
-	if (count_vchan0)
-	    *count_vchan0 =
-		pcibr_soft->bs_rrb_valid[pciio_slot];
-
-	if (count_vchan1)
-	    *count_vchan1 =
-		pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
-
-	if (count_reserved)
-	    *count_reserved =
-		pcibr_soft->bs_rrb_res[pciio_slot];
-
-	if (count_pool)
-	    *count_pool =
-		pcibr_soft->bs_rrb_avail[pciio_slot & 1];
-
-	error = 0;
-
-	pcibr_unlock(pcibr_soft, s);
-    }
-    return error;
-}
-
-/* pcibr_alloc_all_rrbs allocates all the rrbs available in the quantities
- * requested for each of the devies.  The evn_odd argument indicates whether
- * allcoation for the odd or even rrbs is requested and next group of four pairse
- * are the amount to assign to each device (they should sum to <= 8) and
- * whether to set the viritual bit for that device (1 indictaes yes, 0 indicates no)
- * the devices in order are either 0, 2, 4, 6 or 1, 3, 5, 7
- * if even_odd is even we alloc even rrbs else we allocate odd rrbs
- * returns 0 if no errors else returns -1
- */
-
-int
-pcibr_alloc_all_rrbs(devfs_handle_t vhdl, int even_odd,
-		     int dev_1_rrbs, int virt1, int dev_2_rrbs, int virt2,
-		     int dev_3_rrbs, int virt3, int dev_4_rrbs, int virt4)
-{
-    devfs_handle_t            pcibr_vhdl;
-    pcibr_soft_t            pcibr_soft = NULL;
-    bridge_t               *bridge = NULL;
-
-    uint32_t              rrb_setting = 0;
-    int                     rrb_shift = 7;
-    uint32_t              cur_rrb;
-    int                     dev_rrbs[4];
-    int                     virt[4];
-    int                     i, j;
-    unsigned long           s;
-
-    if (GRAPH_SUCCESS ==
-	hwgraph_traverse(vhdl, EDGE_LBL_PCI, &pcibr_vhdl)) {
-	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-	if (pcibr_soft)
-	    bridge = pcibr_soft->bs_base;
-	hwgraph_vertex_unref(pcibr_vhdl);
-    }
-    if (bridge == NULL)
-	bridge = (bridge_t *) xtalk_piotrans_addr
-	    (vhdl, NULL, 0, sizeof(bridge_t), 0);
-
-    even_odd &= 1;
-
-    dev_rrbs[0] = dev_1_rrbs;
-    dev_rrbs[1] = dev_2_rrbs;
-    dev_rrbs[2] = dev_3_rrbs;
-    dev_rrbs[3] = dev_4_rrbs;
-
-    virt[0] = virt1;
-    virt[1] = virt2;
-    virt[2] = virt3;
-    virt[3] = virt4;
-
-    if ((dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs) > 8) {
-	return -1;
-    }
-    if ((dev_1_rrbs < 0) || (dev_2_rrbs < 0) || (dev_3_rrbs < 0) || (dev_4_rrbs < 0)) {
-	return -1;
-    }
-    /* walk through rrbs */
-    for (i = 0; i < 4; i++) {
-	if (virt[i]) {
-	    cur_rrb = i | 0xc;
-	    cur_rrb = cur_rrb << (rrb_shift * 4);
-	    rrb_shift--;
-	    rrb_setting = rrb_setting | cur_rrb;
-	    dev_rrbs[i] = dev_rrbs[i] - 1;
-	}
-	for (j = 0; j < dev_rrbs[i]; j++) {
-	    cur_rrb = i | 0x8;
-	    cur_rrb = cur_rrb << (rrb_shift * 4);
-	    rrb_shift--;
-	    rrb_setting = rrb_setting | cur_rrb;
-	}
-    }
-
-    if (pcibr_soft)
-	s = pcibr_lock(pcibr_soft);
-
-    bridge->b_rrb_map[even_odd].reg = rrb_setting;
-
-    if (pcibr_soft) {
-
-	pcibr_soft->bs_rrb_fixed |= 0x55 << even_odd;
-
-	/* since we've "FIXED" the allocations
-	 * for these slots, we probably can dispense
-	 * with tracking avail/res/valid data, but
-	 * keeping it up to date helps debugging.
-	 */
-
-	pcibr_soft->bs_rrb_avail[even_odd] =
-	    8 - (dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs);
-
-	pcibr_soft->bs_rrb_res[even_odd + 0] = 0;
-	pcibr_soft->bs_rrb_res[even_odd + 2] = 0;
-	pcibr_soft->bs_rrb_res[even_odd + 4] = 0;
-	pcibr_soft->bs_rrb_res[even_odd + 6] = 0;
-
-	pcibr_soft->bs_rrb_valid[even_odd + 0] = dev_1_rrbs - virt1;
-	pcibr_soft->bs_rrb_valid[even_odd + 2] = dev_2_rrbs - virt2;
-	pcibr_soft->bs_rrb_valid[even_odd + 4] = dev_3_rrbs - virt3;
-	pcibr_soft->bs_rrb_valid[even_odd + 6] = dev_4_rrbs - virt4;
-
-	pcibr_soft->bs_rrb_valid[even_odd + 0 + PCIBR_RRB_SLOT_VIRTUAL] = virt1;
-	pcibr_soft->bs_rrb_valid[even_odd + 2 + PCIBR_RRB_SLOT_VIRTUAL] = virt2;
-	pcibr_soft->bs_rrb_valid[even_odd + 4 + PCIBR_RRB_SLOT_VIRTUAL] = virt3;
-	pcibr_soft->bs_rrb_valid[even_odd + 6 + PCIBR_RRB_SLOT_VIRTUAL] = virt4;
-
-	pcibr_unlock(pcibr_soft, s);
-    }
-    return 0;
-}
-
-/*
- *    pcibr_rrb_flush: chase down all the RRBs assigned
- *      to the specified connection point, and flush
- *      them.
- */
-void
-pcibr_rrb_flush(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    unsigned long           s;
-    reg_p                   rrbp;
-    unsigned                rrbm;
-    int                     i;
-    int                     rrbn;
-    unsigned                sval;
-    unsigned                mask;
-
-    sval = BRIDGE_RRB_EN | (pciio_slot >> 1);
-    mask = BRIDGE_RRB_EN | BRIDGE_RRB_PDEV;
-    rrbn = pciio_slot & 1;
-    rrbp = &bridge->b_rrb_map[rrbn].reg;
-
-    s = pcibr_lock(pcibr_soft);
-    rrbm = *rrbp;
-    for (i = 0; i < 8; ++i) {
-	if ((rrbm & mask) == sval)
-	    do_pcibr_rrb_flush(bridge, rrbn);
-	rrbm >>= 4;
-	rrbn += 2;
-    }
-    pcibr_unlock(pcibr_soft, s);
-}
-
-/* =====================================================================
- *    Device(x) register management
- */
-
-/* pcibr_try_set_device: attempt to modify Device(x)
- * for the specified slot on the specified bridge
- * as requested in flags, limited to the specified
- * bits. Returns which BRIDGE bits were in conflict,
- * or ZERO if everything went OK.
- *
- * Caller MUST hold pcibr_lock when calling this function.
- */
-LOCAL int
-pcibr_try_set_device(pcibr_soft_t pcibr_soft,
-		     pciio_slot_t slot,
-		     unsigned flags,
-		     bridgereg_t mask)
-{
-    bridge_t               *bridge;
-    pcibr_soft_slot_t       slotp;
-    bridgereg_t             old;
-    bridgereg_t             new;
-    bridgereg_t             chg;
-    bridgereg_t             bad;
-    bridgereg_t             badpmu;
-    bridgereg_t             badd32;
-    bridgereg_t             badd64;
-    bridgereg_t             fix;
-    unsigned long           s;
-    bridgereg_t             xmask;
-
-    xmask = mask;
-    if (pcibr_soft->bs_xbridge) {
-    	if (mask == BRIDGE_DEV_PMU_BITS)
-		xmask = XBRIDGE_DEV_PMU_BITS;
-	if (mask == BRIDGE_DEV_D64_BITS)
-		xmask = XBRIDGE_DEV_D64_BITS;
-    }
-
-    slotp = &pcibr_soft->bs_slot[slot];
-
-    s = pcibr_lock(pcibr_soft);
-
-    bridge = pcibr_soft->bs_base;
-
-    old = slotp->bss_device;
-
-    /* figure out what the desired
-     * Device(x) bits are based on
-     * the flags specified.
-     */
-
-    new = old;
-
-    /* Currently, we inherit anything that
-     * the new caller has not specified in
-     * one way or another, unless we take
-     * action here to not inherit.
-     *
-     * This is needed for the "swap" stuff,
-     * since it could have been set via
-     * pcibr_endian_set -- altho note that
-     * any explicit PCIBR_BYTE_STREAM or
-     * PCIBR_WORD_VALUES will freely override
-     * the effect of that call (and vice
-     * versa, no protection either way).
-     *
-     * I want to get rid of pcibr_endian_set
-     * in favor of tracking DMA endianness
-     * using the flags specified when DMA
-     * channels are created.
-     */
-
-#define	BRIDGE_DEV_WRGA_BITS	(BRIDGE_DEV_PMU_WRGA_EN | BRIDGE_DEV_DIR_WRGA_EN)
-#define	BRIDGE_DEV_SWAP_BITS	(BRIDGE_DEV_SWAP_PMU | BRIDGE_DEV_SWAP_DIR)
-
-    /* Do not use Barrier, Write Gather,
-     * or Prefetch unless asked.
-     * Leave everything else as it
-     * was from the last time.
-     */
-    new = new
-	& ~BRIDGE_DEV_BARRIER
-	& ~BRIDGE_DEV_WRGA_BITS
-	& ~BRIDGE_DEV_PREF
-	;
-
-    /* Generic macro flags
-     */
-    if (flags & PCIIO_DMA_DATA) {
-	new = (new
-            & ~BRIDGE_DEV_BARRIER)      /* barrier off */
-            | BRIDGE_DEV_PREF;          /* prefetch on */
-
-    }
-    if (flags & PCIIO_DMA_CMD) {
-        new = ((new
-            & ~BRIDGE_DEV_PREF)         /* prefetch off */
-            & ~BRIDGE_DEV_WRGA_BITS)    /* write gather off */
-            | BRIDGE_DEV_BARRIER;       /* barrier on */
-    }
-    /* Generic detail flags
-     */
-    if (flags & PCIIO_WRITE_GATHER)
-	new |= BRIDGE_DEV_WRGA_BITS;
-    if (flags & PCIIO_NOWRITE_GATHER)
-	new &= ~BRIDGE_DEV_WRGA_BITS;
-
-    if (flags & PCIIO_PREFETCH)
-	new |= BRIDGE_DEV_PREF;
-    if (flags & PCIIO_NOPREFETCH)
-	new &= ~BRIDGE_DEV_PREF;
-
-    if (flags & PCIBR_WRITE_GATHER)
-	new |= BRIDGE_DEV_WRGA_BITS;
-    if (flags & PCIBR_NOWRITE_GATHER)
-	new &= ~BRIDGE_DEV_WRGA_BITS;
-
-    if (flags & PCIIO_BYTE_STREAM)
-	new |= (pcibr_soft->bs_xbridge) ? 
-			BRIDGE_DEV_SWAP_DIR : BRIDGE_DEV_SWAP_BITS;
-    if (flags & PCIIO_WORD_VALUES)
-	new &= (pcibr_soft->bs_xbridge) ? 
-			~BRIDGE_DEV_SWAP_DIR : ~BRIDGE_DEV_SWAP_BITS;
-
-    /* Provider-specific flags
-     */
-    if (flags & PCIBR_PREFETCH)
-	new |= BRIDGE_DEV_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	new &= ~BRIDGE_DEV_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	new |= BRIDGE_DEV_PRECISE;
-    if (flags & PCIBR_NOPRECISE)
-	new &= ~BRIDGE_DEV_PRECISE;
-
-    if (flags & PCIBR_BARRIER)
-	new |= BRIDGE_DEV_BARRIER;
-    if (flags & PCIBR_NOBARRIER)
-	new &= ~BRIDGE_DEV_BARRIER;
-
-    if (flags & PCIBR_64BIT)
-	new |= BRIDGE_DEV_DEV_SIZE;
-    if (flags & PCIBR_NO64BIT)
-	new &= ~BRIDGE_DEV_DEV_SIZE;
-
-    chg = old ^ new;				/* what are we changing, */
-    chg &= xmask;				/* of the interesting bits */
-
-    if (chg) {
-
-	badd32 = slotp->bss_d32_uctr ? (BRIDGE_DEV_D32_BITS & chg) : 0;
-	if (pcibr_soft->bs_xbridge) {
-		badpmu = slotp->bss_pmu_uctr ? (XBRIDGE_DEV_PMU_BITS & chg) : 0;
-		badd64 = slotp->bss_d64_uctr ? (XBRIDGE_DEV_D64_BITS & chg) : 0;
-	} else {
-		badpmu = slotp->bss_pmu_uctr ? (BRIDGE_DEV_PMU_BITS & chg) : 0;
-		badd64 = slotp->bss_d64_uctr ? (BRIDGE_DEV_D64_BITS & chg) : 0;
-	}
-	bad = badpmu | badd32 | badd64;
-
-	if (bad) {
-
-	    /* some conflicts can be resolved by
-	     * forcing the bit on. this may cause
-	     * some performance degredation in
-	     * the stream(s) that want the bit off,
-	     * but the alternative is not allowing
-	     * the new stream at all.
-	     */
-            if ( (fix = bad & (BRIDGE_DEV_PRECISE |
-                             BRIDGE_DEV_BARRIER)) ){
-		bad &= ~fix;
-		/* don't change these bits if
-		 * they are already set in "old"
-		 */
-		chg &= ~(fix & old);
-	    }
-	    /* some conflicts can be resolved by
-	     * forcing the bit off. this may cause
-	     * some performance degredation in
-	     * the stream(s) that want the bit on,
-	     * but the alternative is not allowing
-	     * the new stream at all.
-	     */
-	    if ( (fix = bad & (BRIDGE_DEV_WRGA_BITS |
-			     BRIDGE_DEV_PREF)) ) {
-		bad &= ~fix;
-		/* don't change these bits if
-		 * we wanted to turn them on.
-		 */
-		chg &= ~(fix & new);
-	    }
-	    /* conflicts in other bits mean
-	     * we can not establish this DMA
-	     * channel while the other(s) are
-	     * still present.
-	     */
-	    if (bad) {
-		pcibr_unlock(pcibr_soft, s);
-#if (DEBUG && PCIBR_DEV_DEBUG)
-		printk("pcibr_try_set_device: mod blocked by %R\n", bad, device_bits);
-#endif
-		return bad;
-	    }
-	}
-    }
-    if (mask == BRIDGE_DEV_PMU_BITS)
-	slotp->bss_pmu_uctr++;
-    if (mask == BRIDGE_DEV_D32_BITS)
-	slotp->bss_d32_uctr++;
-    if (mask == BRIDGE_DEV_D64_BITS)
-	slotp->bss_d64_uctr++;
-
-    /* the value we want to write is the
-     * original value, with the bits for
-     * our selected changes flipped, and
-     * with any disabled features turned off.
-     */
-    new = old ^ chg;			/* only change what we want to change */
-
-    if (slotp->bss_device == new) {
-	pcibr_unlock(pcibr_soft, s);
-	return 0;
-    }
-    bridge->b_device[slot].reg = new;
-    slotp->bss_device = new;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    pcibr_unlock(pcibr_soft, s);
-#if DEBUG && PCIBR_DEV_DEBUG
-    printk("pcibr Device(%d): 0x%p\n", slot, bridge->b_device[slot].reg);
-#endif
-
-    return 0;
-}
-
-void
-pcibr_release_device(pcibr_soft_t pcibr_soft,
-		     pciio_slot_t slot,
-		     bridgereg_t mask)
-{
-    pcibr_soft_slot_t       slotp;
-    unsigned long           s;
-
-    slotp = &pcibr_soft->bs_slot[slot];
-
-    s = pcibr_lock(pcibr_soft);
-
-    if (mask == BRIDGE_DEV_PMU_BITS)
-	slotp->bss_pmu_uctr--;
-    if (mask == BRIDGE_DEV_D32_BITS)
-	slotp->bss_d32_uctr--;
-    if (mask == BRIDGE_DEV_D64_BITS)
-	slotp->bss_d64_uctr--;
-
-    pcibr_unlock(pcibr_soft, s);
-}
-
-/*
- * flush write gather buffer for slot
- */
-LOCAL void
-pcibr_device_write_gather_flush(pcibr_soft_t pcibr_soft,
-              pciio_slot_t slot)
-{
-    bridge_t               *bridge;
-    unsigned long          s;
-    volatile uint32_t     wrf;
-    s = pcibr_lock(pcibr_soft);
-    bridge = pcibr_soft->bs_base;
-    wrf = bridge->b_wr_req_buf[slot].reg;
-    pcibr_unlock(pcibr_soft, s);
-}
-
-/* =====================================================================
- *    Bridge (pcibr) "Device Driver" entry points
- */
-
-/*
- * pcibr_probe_slot: read a config space word
- * while trapping any errors; reutrn zero if
- * all went OK, or nonzero if there was an error.
- * The value read, if any, is passed back
- * through the valp parameter.
- */
-LOCAL int
-pcibr_probe_slot(bridge_t *bridge,
-		 cfg_p cfg,
-		 unsigned *valp)
-{
-    int                     rv;
-    bridgereg_t             old_enable, new_enable;
-    int badaddr_val(volatile void *, int, volatile void *);
-
-
-    old_enable = bridge->b_int_enable;
-    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-
-    bridge->b_int_enable = new_enable;
-
-	/*
-	 * The xbridge doesn't clear b_err_int_view unless
-	 * multi-err is cleared...
-	 */
-	if (is_xbridge(bridge))
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-	    }
-
-    if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) {
-	bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR;
-	(void) bridge->b_wid_tflush;	/* flushbus */
-    }
-    rv = badaddr_val((void *) cfg, 4, valp);
-
-	/*
-	 * The xbridge doesn't set master timeout in b_int_status
-	 * here.  Fortunately it's in error_interrupt_view.
-	 */
-	if (is_xbridge(bridge))
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-		rv = 1;		/* unoccupied slot */
-	    }
-
-    bridge->b_int_enable = old_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    return rv;
-}
-
-/*
- *    pcibr_init: called once during system startup or
- *      when a loadable driver is loaded.
- *
- *      The driver_register function should normally
- *      be in _reg, not _init.  But the pcibr driver is
- *      required by devinit before the _reg routines
- *      are called, so this is an exception.
- */
-void
-pcibr_init(void)
-{
-#if DEBUG && ATTACH_DEBUG
-    printk("pcibr_init\n");
-#endif
-
-    xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM,
-			    XBRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
-    xwidget_driver_register(BRIDGE_WIDGET_PART_NUM,
-			    BRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
-}
-
-/*
- * open/close mmap/munmap interface would be used by processes
- * that plan to map the PCI bridge, and muck around with the
- * registers. This is dangerous to do, and will be allowed
- * to a select brand of programs. Typically these are
- * diagnostics programs, or some user level commands we may
- * write to do some weird things.
- * To start with expect them to have root priveleges.
- * We will ask for more later.
- */
-/* ARGSUSED */
-int
-pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    int                     error;
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get(vhdl);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    ASSERT(pcibr_soft);
-    len = ctob(btoc(len));		/* Make len page aligned */
-    error = v_mapphys(vt, (void *) ((__psunsigned_t) bridge + off), len);
-
-    /*
-     * If the offset being mapped corresponds to the flash prom
-     * base, and if the mapping succeeds, and if the user
-     * has requested the protections to be WRITE, enable the
-     * flash prom to be written.
-     *
-     * XXX- deprecate this in favor of using the
-     * real flash driver ...
-     */
-    if (!error &&
-	((off == BRIDGE_EXTERNAL_FLASH) ||
-	 (len > BRIDGE_EXTERNAL_FLASH))) {
-	int                     s;
-
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	s = splhi();
-	bridge->b_wid_control |= BRIDGE_CTRL_FLASH_WR_EN;
-	bridge->b_wid_control;		/* inval addr bug war */
-	splx(s);
-    }
-    return error;
-}
-
-/*ARGSUSED */
-int
-pcibr_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    /*
-     * If flashprom write was enabled, disable it, as
-     * this is the last unmap.
-     */
-    if (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN) {
-	int                     s;
-
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	s = splhi();
-	bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN;
-	bridge->b_wid_control;		/* inval addr bug war */
-	splx(s);
-    }
-    return 0;
-}
-
-/* This is special case code used by grio. There are plans to make
- * this a bit more general in the future, but till then this should
- * be sufficient.
- */
-pciio_slot_t
-pcibr_device_slot_get(devfs_handle_t dev_vhdl)
-{
-    char                    devname[MAXDEVNAME];
-    devfs_handle_t            tdev;
-    pciio_info_t            pciio_info;
-    pciio_slot_t            slot = PCIIO_SLOT_NONE;
-
-    vertex_to_name(dev_vhdl, devname, MAXDEVNAME);
-
-    /* run back along the canonical path
-     * until we find a PCI connection point.
-     */
-    tdev = hwgraph_connectpt_get(dev_vhdl);
-    while (tdev != GRAPH_VERTEX_NONE) {
-	pciio_info = pciio_info_chk(tdev);
-	if (pciio_info) {
-	    slot = pciio_info_slot_get(pciio_info);
-	    break;
-	}
-	hwgraph_vertex_unref(tdev);
-	tdev = hwgraph_connectpt_get(tdev);
-    }
-    hwgraph_vertex_unref(tdev);
-
-    return slot;
-}
-
-/*==========================================================================
- *	BRIDGE PCI SLOT RELATED IOCTLs
- */
-char *pci_space_name[] = {"NONE", 
-			  "ROM",
-			  "IO",
-			  "",
-			  "MEM",
-			  "MEM32",
-			  "MEM64",
-			  "CFG",
-			  "WIN0",
-			  "WIN1",
-			  "WIN2",
-			  "WIN3",
-			  "WIN4",
-			  "WIN5",
-			  "",
-			  "BAD"};
-
-
-/*ARGSUSED */
-int
-pcibr_ioctl(devfs_handle_t dev,
-	    int cmd,
-	    void *arg,
-	    int flag,
-	    struct cred *cr,
-	    int *rvalp)
-{
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t)dev);
-#ifdef LATER
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-#endif
-    int                     error = 0;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    switch (cmd) {
-#ifdef LATER
-    case GIOCSETBW:
-	{
-	    grio_ioctl_info_t       info;
-	    pciio_slot_t            slot = 0;
-
-	    if (!cap_able((uint64_t)CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",
-		    info.prev_vhdl, info.reqbw);
-#endif				/* GRIO_DEBUG */
-
-	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==
-		PCIIO_SLOT_NONE) {
-		error = EIO;
-		break;
-	    }
-	    if (info.reqbw)
-		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_HIGH);
-	    break;
-	}
-
-    case GIOCRELEASEBW:
-	{
-	    grio_ioctl_info_t       info;
-	    pciio_slot_t            slot = 0;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",
-		    info.prev_vhdl, info.reqbw);
-#endif				/* GRIO_DEBUG */
-
-	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==
-		PCIIO_SLOT_NONE) {
-		error = EIO;
-		break;
-	    }
-	    if (info.reqbw)
-		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_LOW);
-	    break;
-	}
-
-    case PCIBR_SLOT_POWERUP:
-	{
-	    pciio_slot_t	slot;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-	    slot = (pciio_slot_t)(uint64_t)arg;
-	    error = pcibr_slot_powerup(pcibr_vhdl,slot);
-	    break;
-	}
-    case PCIBR_SLOT_SHUTDOWN:
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-	    slot = (pciio_slot_t)(uint64_t)arg;
-	    error = pcibr_slot_powerup(pcibr_vhdl,slot);
-	    break;
-	}
-    case PCIBR_SLOT_QUERY:
-	{
-	    struct pcibr_slot_info_req_s        req;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-            if (COPYIN(arg, &req, sizeof(req))) {
-                error = EFAULT;
-                break;
-            }
-
-            error = pcibr_slot_query(pcibr_vhdl, &req);
-	    break;
-	}
-#endif	/* LATER */
-    default:
-	break;
-
-    }
-
-    return error;
-}
-
-void
-pcibr_freeblock_sub(iopaddr_t *free_basep,
-		    iopaddr_t *free_lastp,
-		    iopaddr_t base,
-		    size_t size)
-{
-    iopaddr_t               free_base = *free_basep;
-    iopaddr_t               free_last = *free_lastp;
-    iopaddr_t               last = base + size - 1;
-
-    if ((last < free_base) || (base > free_last));	/* free block outside arena */
-
-    else if ((base <= free_base) && (last >= free_last))
-	/* free block contains entire arena */
-	*free_basep = *free_lastp = 0;
-
-    else if (base <= free_base)
-	/* free block is head of arena */
-	*free_basep = last + 1;
-
-    else if (last >= free_last)
-	/* free block is tail of arena */
-	*free_lastp = base - 1;
-
-    /*
-     * We are left with two regions: the free area
-     * in the arena "below" the block, and the free
-     * area in the arena "above" the block. Keep
-     * the one that is bigger.
-     */
-
-    else if ((base - free_base) > (free_last - last))
-	*free_lastp = base - 1;		/* keep lower chunk */
-    else
-	*free_basep = last + 1;		/* keep upper chunk */
-}
-
-/* Convert from ssram_bits in control register to number of SSRAM entries */
-#define ATE_NUM_ENTRIES(n) _ate_info[n]
-
-/* Possible choices for number of ATE entries in Bridge's SSRAM */
-LOCAL int               _ate_info[] =
-{
-    0,					/* 0 entries */
-    8 * 1024,				/* 8K entries */
-    16 * 1024,				/* 16K entries */
-    64 * 1024				/* 64K entries */
-};
-
-#define ATE_NUM_SIZES (sizeof(_ate_info) / sizeof(int))
-#define ATE_PROBE_VALUE 0x0123456789abcdefULL
-
-/*
- * Determine the size of this bridge's external mapping SSRAM, and set
- * the control register appropriately to reflect this size, and initialize
- * the external SSRAM.
- */
-LOCAL int
-pcibr_init_ext_ate_ram(bridge_t *bridge)
-{
-    int                     largest_working_size = 0;
-    int                     num_entries, entry;
-    int                     i, j;
-    bridgereg_t             old_enable, new_enable;
-    int                     s;
-
-    /* Probe SSRAM to determine its size. */
-    old_enable = bridge->b_int_enable;
-    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-    bridge->b_int_enable = new_enable;
-
-    for (i = 1; i < ATE_NUM_SIZES; i++) {
-	/* Try writing a value */
-	bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
-
-	/* Guard against wrap */
-	for (j = 1; j < i; j++)
-	    bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0;
-
-	/* See if value was written */
-	if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
-	    largest_working_size = i;
-    }
-    bridge->b_int_enable = old_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    /*
-     * ensure that we write and read without any interruption.
-     * The read following the write is required for the Bridge war
-     */
-
-    s = splhi();
-    bridge->b_wid_control = (bridge->b_wid_control
-	& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
-	| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
-    bridge->b_wid_control;		/* inval addr bug war */
-    splx(s);
-
-    num_entries = ATE_NUM_ENTRIES(largest_working_size);
-
-#if PCIBR_ATE_DEBUG
-    if (num_entries)
-	printk("bridge at 0x%x: clearing %d external ATEs\n", bridge, num_entries);
-    else
-	printk("bridge at 0x%x: no externa9422l ATE RAM found\n", bridge);
-#endif
-
-    /* Initialize external mapping entries */
-    for (entry = 0; entry < num_entries; entry++)
-	bridge->b_ext_ate_ram[entry] = 0;
-
-    return (num_entries);
-}
-
-/*
- * Allocate "count" contiguous Bridge Address Translation Entries
- * on the specified bridge to be used for PCI to XTALK mappings.
- * Indices in rm map range from 1..num_entries.  Indicies returned
- * to caller range from 0..num_entries-1.
- *
- * Return the start index on success, -1 on failure.
- */
-LOCAL int
-pcibr_ate_alloc(pcibr_soft_t pcibr_soft, int count)
-{
-    int                     index = 0;
-
-    index = (int) rmalloc(pcibr_soft->bs_int_ate_map, (size_t) count);
-/* printk("Colin: pcibr_ate_alloc - index %d count %d \n", index, count); */
-
-    if (!index && pcibr_soft->bs_ext_ate_map)
-	index = (int) rmalloc(pcibr_soft->bs_ext_ate_map, (size_t) count);
-
-    /* rmalloc manages resources in the 1..n
-     * range, with 0 being failure.
-     * pcibr_ate_alloc manages resources
-     * in the 0..n-1 range, with -1 being failure.
-     */
-    return index - 1;
-}
-
-LOCAL void
-pcibr_ate_free(pcibr_soft_t pcibr_soft, int index, int count)
-/* Who says there's no such thing as a free meal? :-) */
-{
-    /* note the "+1" since rmalloc handles 1..n but
-     * we start counting ATEs at zero.
-     */
-/* printk("Colin: pcibr_ate_free - index %d count %d\n", index, count); */
-
-    rmfree((index < pcibr_soft->bs_int_ate_size)
-	   ? pcibr_soft->bs_int_ate_map
-	   : pcibr_soft->bs_ext_ate_map,
-	   count, index + 1);
-}
-
-LOCAL pcibr_info_t
-pcibr_info_get(devfs_handle_t vhdl)
-{
-    return (pcibr_info_t) pciio_info_get(vhdl);
-}
-
-pcibr_info_t
-pcibr_device_info_new(
-			 pcibr_soft_t pcibr_soft,
-			 pciio_slot_t slot,
-			 pciio_function_t rfunc,
-			 pciio_vendor_id_t vendor,
-			 pciio_device_id_t device)
-{
-    pcibr_info_t            pcibr_info;
-    pciio_function_t        func;
-    int                     ibit;
-
-    func = (rfunc == PCIIO_FUNC_NONE) ? 0 : rfunc;
-
-    NEW(pcibr_info);
-    pciio_device_info_new(&pcibr_info->f_c,
-			  pcibr_soft->bs_vhdl,
-			  slot, rfunc,
-			  vendor, device);
-
-    if (slot != PCIIO_SLOT_NONE) {
-
-	/*
-	 * Currently favored mapping from PCI
-	 * slot number and INTA/B/C/D to Bridge
-	 * PCI Interrupt Bit Number:
-	 *
-	 *     SLOT     A B C D
-	 *      0       0 4 0 4
-	 *      1       1 5 1 5
-	 *      2       2 6 2 6
-	 *      3       3 7 3 7
-	 *      4       4 0 4 0
-	 *      5       5 1 5 1
-	 *      6       6 2 6 2
-	 *      7       7 3 7 3
-	 *
-	 * XXX- allow pcibr_hints to override default
-	 * XXX- allow ADMIN to override pcibr_hints
-	 */
-	for (ibit = 0; ibit < 4; ++ibit)
-	    pcibr_info->f_ibit[ibit] =
-		(slot + 4 * ibit) & 7;
-
-	/*
-	 * Record the info in the sparse func info space.
-	 */
-	if (func < pcibr_soft->bs_slot[slot].bss_ninfo)
-	    pcibr_soft->bs_slot[slot].bss_infos[func] = pcibr_info;
-    }
-    return pcibr_info;
-}
-
-void
-pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
-{
-    pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    pcibr_info_t	pcibr_info;
-    pciio_function_t	func;
-    pcibr_soft_slot_t	slotp = &pcibr_soft->bs_slot[slot];
-    int			nfunc = slotp->bss_ninfo;
-
-
-    for (func = 0; func < nfunc; func++) {
-	pcibr_info = slotp->bss_infos[func];
-
-	if (!pcibr_info) 
-	    continue;
-
-	slotp->bss_infos[func] = 0;
-	pciio_device_info_unregister(pcibr_vhdl, &pcibr_info->f_c);
-	pciio_device_info_free(&pcibr_info->f_c);
-	DEL(pcibr_info);
-    }
-
-    /* Clear the DEVIO(x) for this slot */
-    slotp->bss_devio.bssd_space = PCIIO_SPACE_NONE;
-    slotp->bss_devio.bssd_base = PCIBR_D32_BASE_UNSET;
-    slotp->bss_device  = 0;
-
-    
-    /* Reset the mapping usage counters */
-    slotp->bss_pmu_uctr = 0;
-    slotp->bss_d32_uctr = 0;
-    slotp->bss_d64_uctr = 0;
-
-    /* Clear the Direct translation info */
-    slotp->bss_d64_base = PCIBR_D64_BASE_UNSET;
-    slotp->bss_d64_flags = 0;
-    slotp->bss_d32_base = PCIBR_D32_BASE_UNSET;
-    slotp->bss_d32_flags = 0;
-
-    /* Clear out shadow info necessary for the external SSRAM workaround */
-    slotp->bss_ext_ates_active = ATOMIC_INIT(0);
-    slotp->bss_cmd_pointer = 0;
-    slotp->bss_cmd_shadow = 0;
-
-}
-
-/* 
- * PCI_ADDR_SPACE_LIMITS_LOAD
- *	Gets the current values of 
- *		pci io base, 
- *		pci io last,
- *		pci low memory base,
- *		pci low memory last,
- *		pci high memory base,
- * 		pci high memory last
- */
-#define PCI_ADDR_SPACE_LIMITS_LOAD()			\
-    pci_io_fb = pcibr_soft->bs_spinfo.pci_io_base;	\
-    pci_io_fl = pcibr_soft->bs_spinfo.pci_io_last;	\
-    pci_lo_fb = pcibr_soft->bs_spinfo.pci_swin_base;	\
-    pci_lo_fl = pcibr_soft->bs_spinfo.pci_swin_last;	\
-    pci_hi_fb = pcibr_soft->bs_spinfo.pci_mem_base;	\
-    pci_hi_fl = pcibr_soft->bs_spinfo.pci_mem_last;
-/*
- * PCI_ADDR_SPACE_LIMITS_STORE
- *	Sets the current values of
- *		pci io base, 
- *		pci io last,
- *		pci low memory base,
- *		pci low memory last,
- *		pci high memory base,
- * 		pci high memory last
- */
-#define PCI_ADDR_SPACE_LIMITS_STORE()			\
-    pcibr_soft->bs_spinfo.pci_io_base = pci_io_fb;	\
-    pcibr_soft->bs_spinfo.pci_io_last = pci_io_fl;	\
-    pcibr_soft->bs_spinfo.pci_swin_base = pci_lo_fb;	\
-    pcibr_soft->bs_spinfo.pci_swin_last = pci_lo_fl;	\
-    pcibr_soft->bs_spinfo.pci_mem_base = pci_hi_fb;	\
-    pcibr_soft->bs_spinfo.pci_mem_last = pci_hi_fl;
-
-#define PCI_ADDR_SPACE_LIMITS_PRINT()			\
-    printf("+++++++++++++++++++++++\n"			\
-	   "IO base 0x%x last 0x%x\n"			\
-	   "SWIN base 0x%x last 0x%x\n"			\
-	   "MEM base 0x%x last 0x%x\n"			\
-	   "+++++++++++++++++++++++\n",			\
-	   pcibr_soft->bs_spinfo.pci_io_base,		\
-	   pcibr_soft->bs_spinfo.pci_io_last,		\
-	   pcibr_soft->bs_spinfo.pci_swin_base,		\
-	   pcibr_soft->bs_spinfo.pci_swin_last,		\
-	   pcibr_soft->bs_spinfo.pci_mem_base,		\
-	   pcibr_soft->bs_spinfo.pci_mem_last);
-
-/*
- * pcibr_slot_info_init
- *	Probe for this slot and see if it is populated.
- *	If it is populated initialize the generic PCI infrastructural
- * 	information associated with this particular PCI device.
- */
-int
-pcibr_slot_info_init(devfs_handle_t 	pcibr_vhdl,
-		     pciio_slot_t 	slot)
-{
-    pcibr_soft_t	    pcibr_soft;
-    pcibr_info_h	    pcibr_infoh;
-    pcibr_info_t	    pcibr_info;
-    bridge_t		   *bridge;
-    cfg_p                   cfgw;
-    unsigned                idword;
-    unsigned                pfail;
-    unsigned                idwords[8];
-    pciio_vendor_id_t       vendor;
-    pciio_device_id_t       device;
-    unsigned                htype;
-    cfg_p                   wptr;
-    int                     win;
-    pciio_space_t           space;
-    iopaddr_t		    pci_io_fb,	pci_io_fl;
-    iopaddr_t		    pci_lo_fb,  pci_lo_fl;
-    iopaddr_t		    pci_hi_fb,  pci_hi_fl;
-    int			    nfunc;
-    pciio_function_t	    rfunc;
-    int			    func;
-    devfs_handle_t	    conn_vhdl;
-    pcibr_soft_slot_t	    slotp;
-    
-    /* Get the basic software information required to proceed */
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (!pcibr_soft)
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-    if (!PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    /* If we have a host slot (eg:- IOC3 has 2 PCI slots and the initialization
-     * is done by the host slot then we are done.
-     */
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	return(0);    
-    }
-
-    /* Check for a slot with any system critical functions */
-    if (pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(EPERM);
-
-    /* Load the current values of allocated PCI address spaces */
-    PCI_ADDR_SPACE_LIMITS_LOAD();
-    
-    /* Try to read the device-id/vendor-id from the config space */
-    cfgw = bridge->b_type0_cfg_dev[slot].l;
-
-    if (pcibr_probe_slot(bridge, cfgw, &idword)) 
-	return(ENODEV);
-
-    slotp = &pcibr_soft->bs_slot[slot];
-    slotp->slot_status |= SLOT_POWER_UP;
-
-    vendor = 0xFFFF & idword;
-    /* If the vendor id is not valid then the slot is not populated
-     * and we are done.
-     */
-    if (vendor == 0xFFFF) 
-	return(ENODEV);			
-    
-    device = 0xFFFF & (idword >> 16);
-    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
-
-    nfunc = 1;
-    rfunc = PCIIO_FUNC_NONE;
-    pfail = 0;
-
-    /* NOTE: if a card claims to be multifunction
-     * but only responds to config space 0, treat
-     * it as a unifunction card.
-     */
-
-    if (htype & 0x80) {		/* MULTIFUNCTION */
-	for (func = 1; func < 8; ++func) {
-	    cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
-	    if (pcibr_probe_slot(bridge, cfgw, &idwords[func])) {
-		pfail |= 1 << func;
-		continue;
-	    }
-	    vendor = 0xFFFF & idwords[func];
-	    if (vendor == 0xFFFF) {
-		pfail |= 1 << func;
-		continue;
-	    }
-	    nfunc = func + 1;
-	    rfunc = 0;
-	}
-	cfgw = bridge->b_type0_cfg_dev[slot].l;
-    }
-    NEWA(pcibr_infoh, nfunc);
-    
-    pcibr_soft->bs_slot[slot].bss_ninfo = nfunc;
-    pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
-
-    for (func = 0; func < nfunc; ++func) {
-	unsigned                cmd_reg;
-	
-	if (func) {
-	    if (pfail & (1 << func))
-		continue;
-	    
-	    idword = idwords[func];
-	    cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
-	    
-	    device = 0xFFFF & (idword >> 16);
-	    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
-	    rfunc = func;
-	}
-	htype &= 0x7f;
-	if (htype != 0x00) {
-	    printk(KERN_WARNING  "%s pcibr: pci slot %d func %d has strange header type 0x%x\n",
-		    pcibr_soft->bs_name, slot, func, htype);
-	    continue;
-	}
-#if DEBUG && ATTACH_DEBUG
-	printk(KERN_NOTICE   
-		"%s pcibr: pci slot %d func %d: vendor 0x%x device 0x%x",
-		pcibr_soft->bs_name, slot, func, vendor, device);
-#endif	
-
-	pcibr_info = pcibr_device_info_new
-	    (pcibr_soft, slot, rfunc, vendor, device);
-	conn_vhdl = pciio_device_info_register(pcibr_vhdl, &pcibr_info->f_c);
-	if (func == 0)
-	    slotp->slot_conn = conn_vhdl;
-
-#ifdef LITTLE_ENDIAN
-	cmd_reg = cfgw[(PCI_CFG_COMMAND ^ 4) / 4];
-#else
-	cmd_reg = cfgw[PCI_CFG_COMMAND / 4];
-#endif
-	
-	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
-
-	for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win) {
-	    iopaddr_t               base, mask, code;
-	    size_t                  size;
-
-	    /*
-	     * GET THE BASE & SIZE OF THIS WINDOW:
-	     *
-	     * The low two or four bits of the BASE register
-	     * determines which address space we are in; the
-	     * rest is a base address. BASE registers
-	     * determine windows that are power-of-two sized
-	     * and naturally aligned, so we can get the size
-	     * of a window by writing all-ones to the
-	     * register, reading it back, and seeing which
-	     * bits are used for decode; the least
-	     * significant nonzero bit is also the size of
-	     * the window.
-	     *
-	     * WARNING: someone may already have allocated
-	     * some PCI space to this window, and in fact
-	     * PIO may be in process at this very moment
-	     * from another processor (or even from this
-	     * one, if we get interrupted)! So, if the BASE
-	     * already has a nonzero address, be generous
-	     * and use the LSBit of that address as the
-	     * size; this could overstate the window size.
-	     * Usually, when one card is set up, all are set
-	     * up; so, since we don't bitch about
-	     * overlapping windows, we are ok.
-	     *
-	     * UNFORTUNATELY, some cards do not clear their
-	     * BASE registers on reset. I have two heuristics
-	     * that can detect such cards: first, if the
-	     * decode enable is turned off for the space
-	     * that the window uses, we can disregard the
-	     * initial value. second, if the address is
-	     * outside the range that we use, we can disregard
-	     * it as well.
-	     *
-	     * This is looking very PCI generic. Except for
-	     * knowing how many slots and where their config
-	     * spaces are, this window loop and the next one
-	     * could probably be shared with other PCI host
-	     * adapters. It would be interesting to see if
-	     * this could be pushed up into pciio, when we
-	     * start supporting more PCI providers.
-	     */
-#ifdef LITTLE_ENDIAN
-	    base = wptr[((win*4)^4)/4];
-#else
-	    base = wptr[win];
-#endif
-
-	    if (base & PCI_BA_IO_SPACE) {
-		/* BASE is in I/O space. */
-		space = PCIIO_SPACE_IO;
-		mask = -4;
-		code = base & 3;
-		base = base & mask;
-		if (base == 0) {
-		    ;		/* not assigned */
-		} else if (!(cmd_reg & PCI_CMD_IO_SPACE)) {
-		    base = 0;	/* decode not enabled */
-		}
-	    } else {
-		/* BASE is in MEM space. */
-		space = PCIIO_SPACE_MEM;
-		mask = -16;
-		code = base & PCI_BA_MEM_LOCATION;	/* extract BAR type */
-		base = base & mask;
-		if (base == 0) {
-		    ;		/* not assigned */
-		} else if (!(cmd_reg & PCI_CMD_MEM_SPACE)) {
-		    base = 0;	/* decode not enabled */
-		} else if (base & 0xC0000000) {
-		    base = 0;	/* outside permissable range */
-		} else if ((code == PCI_BA_MEM_64BIT) &&
-#ifdef LITTLE_ENDIAN
-			   (wptr[(((win + 1)*4)^4)/4] != 0)) {
-#else 
-			   (wptr[win + 1] != 0)) {
-#endif /* LITTLE_ENDIAN */
-		    base = 0;	/* outside permissable range */
-		}
-	    }
-
-	    if (base != 0) {	/* estimate size */
-		size = base & -base;
-	    } else {		/* calculate size */
-#ifdef LITTLE_ENDIAN
-		wptr[((win*4)^4)/4] = ~0;	/* turn on all bits */
-		size = wptr[((win*4)^4)/4];	/* get stored bits */
-#else 
-		wptr[win] = ~0;	/* turn on all bits */
-		size = wptr[win];	/* get stored bits */
-#endif /* LITTLE_ENDIAN */
-		size &= mask;	/* keep addr */
-		size &= -size;	/* keep lsbit */
-		if (size == 0)
-		    continue;
-	    }	
-
-	    pcibr_info->f_window[win].w_space = space;
-	    pcibr_info->f_window[win].w_base = base;
-	    pcibr_info->f_window[win].w_size = size;
-
-	    /*
-	     * If this window already has PCI space
-	     * allocated for it, "subtract" that space from
-	     * our running freeblocks. Don't worry about
-	     * overlaps in existing allocated windows; we
-	     * may be overstating their sizes anyway.
-	     */
-
-	    if (base && size) {
-		if (space == PCIIO_SPACE_IO) {
-		    pcibr_freeblock_sub(&pci_io_fb,
-					&pci_io_fl,
-					base, size);
-		} else {
-		    pcibr_freeblock_sub(&pci_lo_fb,
-					&pci_lo_fl,
-					base, size);
-		    pcibr_freeblock_sub(&pci_hi_fb,
-					&pci_hi_fl,
-					base, size);
-		}	
-	    }
-#if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM)
-	    /*
-	     * IOC3 BASE_ADDR* BUG WORKAROUND
-	     *
-	     
-	     * If we write to BASE1 on the IOC3, the
-	     * data in BASE0 is replaced. The
-	     * original workaround was to remember
-	     * the value of BASE0 and restore it
-	     * when we ran off the end of the BASE
-	     * registers; however, a later
-	     * workaround was added (I think it was
-	     * rev 1.44) to avoid setting up
-	     * anything but BASE0, with the comment
-	     * that writing all ones to BASE1 set
-	     * the enable-parity-error test feature
-	     * in IOC3's SCR bit 14.
-	     *
-	     * So, unless we defer doing any PCI
-	     * space allocation until drivers
-	     * attach, and set up a way for drivers
-	     * (the IOC3 in paricular) to tell us
-	     * generically to keep our hands off
-	     * BASE registers, we gotta "know" about
-	     * the IOC3 here.
-	     *
-	     * Too bad the PCI folks didn't reserve the
-	     * all-zero value for 'no BASE here' (it is a
-	     * valid code for an uninitialized BASE in
-	     * 32-bit PCI memory space).
-	     */
-	    
-	    if ((vendor == IOC3_VENDOR_ID_NUM) &&
-		(device == IOC3_DEVICE_ID_NUM))
-		break;
-#endif
-	    if (code == PCI_BA_MEM_64BIT) {
-		win++;		/* skip upper half */
-#ifdef LITTLE_ENDIAN
-		wptr[((win*4)^4)/4] = 0;	/* which must be zero */
-#else 
-		wptr[win] = 0;	/* which must be zero */
-#endif /* LITTLE_ENDIAN */
-	    }
-	}				/* next win */
-    }				/* next func */
-
-    /* Store back the values for allocated PCI address spaces */
-    PCI_ADDR_SPACE_LIMITS_STORE();
-    return(0);
-}					
-
-/*
- * pcibr_slot_info_free
- *	Remove all the PCI infrastructural information associated
- * 	with a particular PCI device.
- */
-int
-pcibr_slot_info_free(devfs_handle_t pcibr_vhdl,
-                     pciio_slot_t slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    int			nfunc;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-
-    pcibr_device_info_free(pcibr_vhdl, slot);
-
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-    DELA(pcibr_infoh,nfunc);
-    pcibr_soft->bs_slot[slot].bss_ninfo = 0;
-
-    return(0);
-}
-
-int as_debug = 0;
-/*
- * pcibr_slot_addr_space_init
- *	Reserve chunks of PCI address space as required by 
- * 	the base registers in the card.
- */
-int
-pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,
-			   pciio_slot_t	slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    bridge_t		*bridge;
-    iopaddr_t		pci_io_fb, pci_io_fl;
-    iopaddr_t		pci_lo_fb, pci_lo_fl;
-    iopaddr_t		pci_hi_fb, pci_hi_fl;
-    size_t              align;
-    iopaddr_t           mask;
-    int		    	nbars;
-    int		       	nfunc;
-    int			func;
-    int			win;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-
-    /* Get the current values for the allocated PCI address spaces */
-    PCI_ADDR_SPACE_LIMITS_LOAD();
-
-    if (as_debug)
-#ifdef LATER
-    PCI_ADDR_SPACE_LIMITS_PRINT();
-#endif
-    /* allocate address space,
-     * for windows that have not been
-     * previously assigned.
-     */
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	return(0);
-    }
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    if (nfunc < 1)
-	return(EINVAL);
-
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-    if (!pcibr_infoh)
-	return(EINVAL);
-
-    /*
-     * Try to make the DevIO windows not
-     * overlap by pushing the "io" and "hi"
-     * allocation areas up to the next one
-     * or two megabyte bound. This also
-     * keeps them from being zero.
-     *
-     * DO NOT do this with "pci_lo" since
-     * the entire "lo" area is only a
-     * megabyte, total ...
-     */
-    align = (slot < 2) ? 0x200000 : 0x100000;
-    mask = -align;
-    pci_io_fb = (pci_io_fb + align - 1) & mask;
-    pci_hi_fb = (pci_hi_fb + align - 1) & mask;
-
-    for (func = 0; func < nfunc; ++func) {
-	cfg_p                   cfgw;
-	cfg_p                   wptr;
-	pciio_space_t           space;
-	iopaddr_t               base;
-	size_t                  size;
-	cfg_p                   pci_cfg_cmd_reg_p;
-	unsigned                pci_cfg_cmd_reg;
-	unsigned                pci_cfg_cmd_reg_add = 0;
-
-	pcibr_info = pcibr_infoh[func];
-
-	if (!pcibr_info)
-	    continue;
-
-	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-	    continue;
-	
-	cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
-	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
-
-	nbars = PCI_CFG_BASE_ADDRS;
-
-	for (win = 0; win < nbars; ++win) {
-
-	    space = pcibr_info->f_window[win].w_space;
-	    base = pcibr_info->f_window[win].w_base;
-	    size = pcibr_info->f_window[win].w_size;
-	    
-	    if (size < 1)
-		continue;
-
-	    if (base >= size) {
-#if DEBUG && PCI_DEBUG
-		printk("pcibr: slot %d func %d window %d is in %d[0x%x..0x%x], alloc by prom\n",
-			slot, func, win, space, base, base + size - 1);
-#endif
-		continue;		/* already allocated */
-	    }
-	    align = size;		/* ie. 0x00001000 */
-	    if (align < _PAGESZ)
-		align = _PAGESZ;	/* ie. 0x00004000 */
-	    mask = -align;		/* ie. 0xFFFFC000 */
-
-	    switch (space) {
-	    case PCIIO_SPACE_IO:
-		base = (pci_io_fb + align - 1) & mask;
-		if ((base + size) > pci_io_fl) {
-		    base = 0;
-		    break;
-		}
-		pci_io_fb = base + size;
-		break;
-		
-	    case PCIIO_SPACE_MEM:
-#ifdef LITTLE_ENDIAN
-		if ((wptr[((win*4)^4)/4] & PCI_BA_MEM_LOCATION) ==
-#else
-		if ((wptr[win] & PCI_BA_MEM_LOCATION) ==
-#endif  /* LITTLE_ENDIAN */
-		    PCI_BA_MEM_1MEG) {
-		    /* allocate from 20-bit PCI space */
-		    base = (pci_lo_fb + align - 1) & mask;
-		    if ((base + size) > pci_lo_fl) {
-			base = 0;
-			break;
-		    }
-		    pci_lo_fb = base + size;
-		} else {
-		    /* allocate from 32-bit or 64-bit PCI space */
-		    base = (pci_hi_fb + align - 1) & mask;
-		    if ((base + size) > pci_hi_fl) {
-			base = 0;
-			break;
-		    }
-		    pci_hi_fb = base + size;
-		}
-		break;
-		
-	    default:
-		base = 0;
-#if DEBUG && PCI_DEBUG
-		printk("pcibr: slot %d window %d had bad space code %d\n",
-			slot, win, space);
-#endif
-	    }
-	    pcibr_info->f_window[win].w_base = base;
-#ifdef LITTLE_ENDIAN
-	    wptr[((win*4)^4)/4] = base;
-#if DEBUG && PCI_DEBUG
-		printk("Setting base address 0x%p base 0x%x\n", &(wptr[((win*4)^4)/4]), base);
-#endif
-#else
-	    wptr[win] = base;
-#endif  /* LITTLE_ENDIAN */
-
-#if DEBUG && PCI_DEBUG
-	    if (base >= size)
-		printk("pcibr: slot %d func %d window %d is in %d [0x%x..0x%x], alloc by pcibr\n",
-			slot, func, win, space, base, base + size - 1);
-	    else
-		printk("pcibr: slot %d func %d window %d, unable to alloc 0x%x in 0x%p\n",
-			slot, func, win, size, space);
-#endif
-	}				/* next base */
-
-	/*
-	 * Allocate space for the EXPANSION ROM
-	 * NOTE: DO NOT DO THIS ON AN IOC3,
-	 * as it blows the system away.
-	 */
-	base = size = 0;
-	if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) ||
-	    (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) {
-
-	    wptr = cfgw + PCI_EXPANSION_ROM / 4;
-#ifdef LITTLE_ENDIAN
-	    wptr[1] = 0xFFFFF000;
-	    mask = wptr[1];
-#else
-	    *wptr = 0xFFFFF000;
-	    mask = *wptr;
-#endif  /* LITTLE_ENDIAN */
-	    if (mask & 0xFFFFF000) {
-		size = mask & -mask;
-		align = size;
-		if (align < _PAGESZ)
-		    align = _PAGESZ;
-		mask = -align;
-		base = (pci_hi_fb + align - 1) & mask;
-		if ((base + size) > pci_hi_fl)
-		    base = size = 0;
-		else {
-		    pci_hi_fb = base + size;
-#ifdef LITTLE_ENDIAN
-		    wptr[1] = base;
-#else
-		    *wptr = base;
-#endif  /* LITTLE_ENDIAN */
-#if DEBUG && PCI_DEBUG
-		    printk("%s/%d ROM in 0x%lx..0x%lx (alloc by pcibr)\n",
-			    pcibr_soft->bs_name, slot,
-			    base, base + size - 1);
-#endif
-		}
-	    }
-	}
-	pcibr_info->f_rbase = base;
-	pcibr_info->f_rsize = size;
-	
-	/*
-	 * if necessary, update the board's
-	 * command register to enable decoding
-	 * in the windows we added.
-	 *
-	 * There are some bits we always want to
-	 * be sure are set.
-	 */
-	pci_cfg_cmd_reg_add |= PCI_CMD_IO_SPACE;
-
-	/*
-	 * The Adaptec 1160 FC Controller WAR #767995:
-	 * The part incorrectly ignores the upper 32 bits of a 64 bit
-	 * address when decoding references to it's registers so to
-	 * keep it from responding to a bus cycle that it shouldn't
-	 * we only use I/O space to get at it's registers.  Don't
-	 * enable memory space accesses on that PCI device.
-	 */
-	#define FCADP_VENDID 0x9004 /* Adaptec Vendor ID from fcadp.h */
-	#define FCADP_DEVID 0x1160  /* Adaptec 1160 Device ID from fcadp.h */
-
-	if ((pcibr_info->f_vendor != FCADP_VENDID) ||
-	    (pcibr_info->f_device != FCADP_DEVID))
-	    pci_cfg_cmd_reg_add |= PCI_CMD_MEM_SPACE;
-
-	pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER;
-
-	pci_cfg_cmd_reg_p = cfgw + PCI_CFG_COMMAND / 4;
-	pci_cfg_cmd_reg = *pci_cfg_cmd_reg_p;
-#if PCI_FBBE	/* XXX- check here to see if dev can do fast-back-to-back */
-	if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP))
-	    fast_back_to_back_enable = 0;
-#endif
-	pci_cfg_cmd_reg &= 0xFFFF;
-	if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg)
-	    *pci_cfg_cmd_reg_p = pci_cfg_cmd_reg | pci_cfg_cmd_reg_add;
-	
-    }				/* next func */
-
-    /* Now that we have allocated new chunks of PCI address spaces to this
-     * card we need to update the bookkeeping values which indicate
-     * the current PCI address space allocations.
-     */
-    PCI_ADDR_SPACE_LIMITS_STORE();
-    return(0);
-}
-
-/*
- * pcibr_slot_device_init
- * 	Setup the device register in the bridge for this PCI slot.
- */
-int
-pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,
-		       pciio_slot_t slot)
-{
-    pcibr_soft_t	 pcibr_soft;
-    bridge_t		*bridge;
-    bridgereg_t		 devreg;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-
-    /*
-     * Adjustments to Device(x)
-     * and init of bss_device shadow
-     */
-    devreg = bridge->b_device[slot].reg;
-    devreg &= ~BRIDGE_DEV_PAGE_CHK_DIS;
-    devreg |= BRIDGE_DEV_COH | BRIDGE_DEV_VIRTUAL_EN;
-#ifdef LITTLE_ENDIAN
-    devreg |= BRIDGE_DEV_DEV_SWAP;
-#endif
-    pcibr_soft->bs_slot[slot].bss_device = devreg;
-    bridge->b_device[slot].reg = devreg;
-
-#if DEBUG && PCI_DEBUG
-	printk("pcibr Device(%d): 0x%lx\n", slot, bridge->b_device[slot].reg);
-#endif
-
-#if DEBUG && PCI_DEBUG
-    printk("pcibr: PCI space allocation done.\n");
-#endif
-
-    return(0);
-}
-
-/*
- * pcibr_slot_guest_info_init
- *	Setup the host/guest relations for a PCI slot.
- */
-int
-pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,
-			   pciio_slot_t	slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    pcibr_soft_slot_t	slotp;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    slotp = &pcibr_soft->bs_slot[slot];
-
-    /* create info and verticies for guest slots;
-     * for compatibilitiy macros, create info
-     * for even unpopulated slots (but do not
-     * build verticies for them).
-     */
-    if (pcibr_soft->bs_slot[slot].bss_ninfo < 1) {
-	NEWA(pcibr_infoh, 1);
-	pcibr_soft->bs_slot[slot].bss_ninfo = 1;
-	pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
-
-	pcibr_info = pcibr_device_info_new
-	    (pcibr_soft, slot, PCIIO_FUNC_NONE,
-	     PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
-
-	if (pcibr_soft->bs_slot[slot].has_host) {
-	    slotp->slot_conn = pciio_device_info_register
-		(pcibr_vhdl, &pcibr_info->f_c);
-	}
-    }
-
-    /* generate host/guest relations
-     */
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	int  host = pcibr_soft->bs_slot[slot].host_slot;
-	pcibr_soft_slot_t host_slotp = &pcibr_soft->bs_slot[host];
-
-	hwgraph_edge_add(slotp->slot_conn,
-			 host_slotp->slot_conn,
-			 EDGE_LBL_HOST);
-
-	/* XXX- only gives us one guest edge per
-	 * host. If/when we have a host with more than
-	 * one guest, we will need to figure out how
-	 * the host finds all its guests, and sorts
-	 * out which one is which.
-	 */
-	hwgraph_edge_add(host_slotp->slot_conn,
-			 slotp->slot_conn,
-			 EDGE_LBL_GUEST);
-    }
-
-    return(0);
-}
-
-/*
- * pcibr_slot_initial_rrb_alloc
- *	Allocate a default number of rrbs for this slot on 
- * 	the two channels.  This is dictated by the rrb allocation
- * 	strategy routine defined per platform.
- */
-
-int
-pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl,
-			     pciio_slot_t slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    bridge_t		*bridge;
-    int                 c0, c1;
-    int			r;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-
-    /* How may RRBs are on this slot?
-     */
-    c0 = do_pcibr_rrb_count_valid(bridge, slot);
-    c1 = do_pcibr_rrb_count_valid(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL);
-
-#if PCIBR_RRB_DEBUG
-    printk("pcibr_attach: slot %d started with %d+%d\n", slot, c0, c1);
-#endif
-
-    /* Do we really need any?
-     */
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-    pcibr_info = pcibr_infoh[0];
-    if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) &&
-	!pcibr_soft->bs_slot[slot].has_host) {
-	if (c0 > 0)
-	    do_pcibr_rrb_free(bridge, slot, c0);
-	if (c1 > 0)
-	    do_pcibr_rrb_free(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL, c1);
-	pcibr_soft->bs_rrb_valid[slot] = 0x1000;
-	pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0x1000;
-	return(ENODEV);
-    }
-
-    pcibr_soft->bs_rrb_avail[slot & 1] -= c0 + c1;
-    pcibr_soft->bs_rrb_valid[slot] = c0;
-    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = c1;
-
-    pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(bridge, 0);
-    pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(bridge, 1);
-
-    r = 3 - (c0 + c1);
-
-    if (r > 0) {
-	pcibr_soft->bs_rrb_res[slot] = r;
-	pcibr_soft->bs_rrb_avail[slot & 1] -= r;
-    }
-
-#if PCIBR_RRB_DEBUG
-    printk("\t%d+%d+%d",
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot],
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-    printk("\n");
-#endif
-
-    return(0);
-}
-
-/*
- * pcibr_slot_call_device_attach
- *	This calls the associated driver attach routine for the PCI
- * 	card in this slot.
- */
-int
-pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
-			      pciio_slot_t slot,
-			      int          drv_flags)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    async_attach_t	aa = NULL;
-    int			func;
-    devfs_handle_t	xconn_vhdl,conn_vhdl;
-    int			nfunc;
-    int                 error_func;
-    int                 error_slot = 0;
-    int                 error = ENODEV;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-
-    if (pcibr_soft->bs_slot[slot].has_host) {
-        return(EPERM);
-    }
-    
-    xconn_vhdl = pcibr_soft->bs_conn;
-    aa = async_attach_get_info(xconn_vhdl);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-	pcibr_info = pcibr_infoh[func];
-	
-	if (!pcibr_info)
-	    continue;
-
-	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-	    continue;
-
-	conn_vhdl = pcibr_info->f_vertex;
-
-#ifdef LATER
-	/*
-	 * Activate if and when we support cdl.
-	 */
-	if (aa)
-	    async_attach_add_info(conn_vhdl, aa);
-#endif	/* LATER */
-
-	error_func = pciio_device_attach(conn_vhdl, drv_flags);
-
-        pcibr_info->f_att_det_error = error_func;
-
-	if (error_func)
-	    error_slot = error_func;
-
-        error = error_slot;
-
-    }				/* next func */
-
-    if (error) {
-	if ((error != ENODEV) && (error != EUNATCH))
-	    pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_INCMPLT;
-    } else {
-        pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_CMPLT;
-    }
-        
-    return(error);
-}
-
-/*
- * pcibr_slot_call_device_detach
- *	This calls the associated driver detach routine for the PCI
- * 	card in this slot.
- */
-int
-pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
-			      pciio_slot_t slot,
-			      int          drv_flags)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    int			func;
-    devfs_handle_t	conn_vhdl = GRAPH_VERTEX_NONE;
-    int			nfunc;
-    int                 error_func;
-    int                 error_slot = 0;
-    int                 error = ENODEV;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    if (pcibr_soft->bs_slot[slot].has_host)
-        return(EPERM);
-
-    /* Make sure that we do not detach a system critical function vertex */
-    if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(EPERM);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-	pcibr_info = pcibr_infoh[func];
-	
-	if (!pcibr_info)
-	    continue;
-
-	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-	    continue;
-
-	conn_vhdl = pcibr_info->f_vertex;
-
-	error_func = pciio_device_detach(conn_vhdl, drv_flags);
-
-        pcibr_info->f_att_det_error = error_func;
-
-	if (error_func)
-	    error_slot = error_func;
-
-	error = error_slot;
-
-    }				/* next func */
-
-    pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;
-
-    if (error) {
-	if ((error != ENODEV) && (error != EUNATCH))
-            pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_INCMPLT;
-    } else {
-        if (conn_vhdl != GRAPH_VERTEX_NONE) 
-            pcibr_device_unregister(conn_vhdl);
-        pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_CMPLT;
-    }
-        
-    return(error);
-}
-
-/*
- * pcibr_slot_detach
- *	This is a place holder routine to keep track of all the
- *	slot-specific freeing that needs to be done.
- */
-int
-pcibr_slot_detach(devfs_handle_t pcibr_vhdl,
-		  pciio_slot_t slot,
-		  int          drv_flags)
-{
-    int		  error;
-    
-    /* Call the device detach function */
-    error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags));
-    return (error);
-
-}
-
-/*
- * pcibr_is_slot_sys_critical
- *      Check slot for any functions that are system critical.
- *      Return 1 if any are system critical or 0 otherwise.
- *
- *      This function will always return 0 when called by 
- *      pcibr_attach() because the system critical vertices 
- *      have not yet been set in the hwgraph.
- */
-int
-pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl,
-                      pciio_slot_t slot)
-{
-    pcibr_soft_t        pcibr_soft;
-    pcibr_info_h        pcibr_infoh;
-    pcibr_info_t        pcibr_info;
-    devfs_handle_t        conn_vhdl = GRAPH_VERTEX_NONE;
-    int                 nfunc;
-    int                 func;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-        return(0);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-        pcibr_info = pcibr_infoh[func];
-        if (!pcibr_info)
-            continue;
-
-        if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-            continue;
-
-        conn_vhdl = pcibr_info->f_vertex;
-        if (is_sys_critical_vertex(conn_vhdl)) { 
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-            printk(KERN_WARNING  "%v is a system critical device vertex\n", conn_vhdl);
-#else
-            printk(KERN_WARNING  "%p is a system critical device vertex\n", (void *)conn_vhdl);
-#endif
-            return(1); 
-        }
-
-    }
-
-    return(0);
-}
-
-/*
- * pcibr_device_unregister
- *	This frees up any hardware resources reserved for this PCI device
- * 	and removes any PCI infrastructural information setup for it.
- *	This is usually used at the time of shutting down of the PCI card.
- */
-int
-pcibr_device_unregister(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t	 pciio_info;
-    devfs_handle_t	 pcibr_vhdl;
-    pciio_slot_t	 slot;
-    pcibr_soft_t	 pcibr_soft;
-    bridge_t		*bridge;
-    int			 error_call;
-    int			 error = 0;
-
-    pciio_info = pciio_info_get(pconn_vhdl);
-
-    pcibr_vhdl = pciio_info_master_get(pciio_info);
-    slot = pciio_info_slot_get(pciio_info);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge = pcibr_soft->bs_base;
-
-    /* Clear all the hardware xtalk resources for this device */
-    xtalk_widgetdev_shutdown(pcibr_soft->bs_conn, slot);
-
-    /* Flush all the rrbs */
-    pcibr_rrb_flush(pconn_vhdl);
-
-    /* Free the rrbs allocated to this slot */
-    error_call = do_pcibr_rrb_free(bridge, slot, 
-		                   pcibr_soft->bs_rrb_valid[slot] +
-		                   pcibr_soft->bs_rrb_valid[slot + 
-                                   PCIBR_RRB_SLOT_VIRTUAL]);
-
-    if (error_call)
-        error = ERANGE;
-
-    pcibr_soft->bs_rrb_valid[slot] = 0;
-    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0;
-    pcibr_soft->bs_rrb_res[slot] = 0;
-
-    /* Flush the write buffers !! */
-    error_call = pcibr_wrb_flush(pconn_vhdl);
-
-    if (error_call)
-        error = error_call;
-
-    /* Clear the information specific to the slot */
-    error_call = pcibr_slot_info_free(pcibr_vhdl, slot);
-
-    if (error_call)
-        error = error_call;
-
-    return(error);
-    
-}
-
-/* 
- * build a convenience link path in the
- * form of ".../<iobrick>/bus/<busnum>"
- * 
- * returns 1 on success, 0 otherwise
- *
- * depends on hwgraph separator == '/'
- */
-int
-pcibr_bus_cnvlink(devfs_handle_t f_c, int slot)
-{
-        char dst[MAXDEVNAME];
-	char *dp = dst;
-        char *cp, *xp;
-        int widgetnum;
-        char pcibus[8];
-	devfs_handle_t nvtx, svtx;
-	int rv;
-
-#if DEBUG
-	printk("pcibr_bus_cnvlink: slot= %d f_c= %p\n", 
-		slot, f_c);
-	{
-		int pos;
-		char dname[256];
-		pos = devfs_generate_path(f_c, dname, 256);
-		printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-	}
-#endif
-
-	if (GRAPH_SUCCESS != hwgraph_vertex_name_get(f_c, dst, MAXDEVNAME))
-		return 0;
-
-	/* dst example == /hw/module/001c02/Pbrick/xtalk/8/pci/direct */
-
-	/* find the widget number */
-	xp = strstr(dst, "/"EDGE_LBL_XTALK"/");
-	if (xp == NULL)
-		return 0;
-	widgetnum = atoi(xp+7);
-	if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F)
-		return 0;
-
-	/* remove "/pci/direct" from path */
-	cp = strstr(dst, "/" EDGE_LBL_PCI "/" "direct");
-	if (cp == NULL)
-		return 0;
-	*cp = (char)NULL;
-
-	/* get the vertex for the widget */
-	if (GRAPH_SUCCESS != hwgraph_traverse(NULL, dp, &svtx))	
-		return 0;
-
-	*xp = (char)NULL;		/* remove "/xtalk/..." from path */
-
-	/* dst example now == /hw/module/001c02/Pbrick */
-
-	/* get the bus number */
-        strcat(dst, "/bus");
-        sprintf(pcibus, "%d", p_busnum[widgetnum]);
-
-	/* link to bus to widget */
-	rv = hwgraph_path_add(NULL, dp, &nvtx);
-	if (GRAPH_SUCCESS == rv)
-		rv = hwgraph_edge_add(nvtx, svtx, pcibus);
-
-	return (rv == GRAPH_SUCCESS);
-}
-
-
-/*
- *    pcibr_attach: called every time the crosstalk
- *      infrastructure is asked to initialize a widget
- *      that matches the part number we handed to the
- *      registration routine above.
- */
-/*ARGSUSED */
-int
-pcibr_attach(devfs_handle_t xconn_vhdl)
-{
-    /* REFERENCED */
-    graph_error_t           rc;
-    devfs_handle_t            pcibr_vhdl;
-    devfs_handle_t            ctlr_vhdl;
-    bridge_t               *bridge = NULL;
-    bridgereg_t             id;
-    int                     rev;
-    pcibr_soft_t            pcibr_soft;
-    pcibr_info_t            pcibr_info;
-    xwidget_info_t          info;
-    xtalk_intr_t            xtalk_intr;
-    device_desc_t           dev_desc = (device_desc_t)0;
-    int                     slot;
-    int                     ibit;
-    devfs_handle_t            noslot_conn;
-    char                    devnm[MAXDEVNAME], *s;
-    pcibr_hints_t           pcibr_hints;
-    bridgereg_t             b_int_enable;
-    unsigned                rrb_fixed = 0;
-
-    iopaddr_t               pci_io_fb, pci_io_fl;
-    iopaddr_t               pci_lo_fb, pci_lo_fl;
-    iopaddr_t               pci_hi_fb, pci_hi_fl;
-
-    int                     spl_level;
-#ifdef LATER
-    char		    *nicinfo = (char *)0;
-#endif
-
-#if PCI_FBBE
-    int                     fast_back_to_back_enable;
-#endif
-    l1sc_t		    *scp;
-    nasid_t		    nasid;
-
-    async_attach_t          aa = NULL;
-
-    aa = async_attach_get_info(xconn_vhdl);
-
-#if DEBUG && ATTACH_DEBUG
-    printk("pcibr_attach: xconn_vhdl=  %p\n", xconn_vhdl);
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(xconn_vhdl, dname, 256);
-	printk("%s : path= %s \n", __FUNCTION__, &dname[pos]);
-    }
-#endif
-
-    /* Setup the PRB for the bridge in CONVEYOR BELT
-     * mode. PRBs are setup in default FIRE-AND-FORGET
-     * mode during the initialization.
-     */
-    hub_device_flags_set(xconn_vhdl, HUB_PIO_CONVEYOR);
-
-    bridge = (bridge_t *)
-	xtalk_piotrans_addr(xconn_vhdl, NULL,
-			    0, sizeof(bridge_t), 0);
-
-#ifndef MEDUSA_HACK
-    if ((bridge->b_wid_stat & BRIDGE_STAT_PCI_GIO_N) == 0)
-	return -1;			/* someone else handles GIO bridges. */
-#endif
-
-    if (XWIDGET_PART_REV_NUM(bridge->b_wid_id) == XBRIDGE_PART_REV_A)
-	NeedXbridgeSwap = 1;
-
-    /*
-     * Create the vertex for the PCI bus, which we
-     * will also use to hold the pcibr_soft and
-     * which will be the "master" vertex for all the
-     * pciio connection points we will hang off it.
-     * This needs to happen before we call nic_bridge_vertex_info
-     * as we are some of the *_vmc functions need access to the edges.
-     *
-     * Opening this vertex will provide access to
-     * the Bridge registers themselves.
-     */
-    rc = hwgraph_path_add(xconn_vhdl, EDGE_LBL_PCI, &pcibr_vhdl);
-    ASSERT(rc == GRAPH_SUCCESS);
-
-    ctlr_vhdl = NULL;
-    ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER,
-                0, DEVFS_FL_AUTO_DEVNUM,
-                0, 0,
-                S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                &pcibr_fops, NULL);
-
-    ASSERT(ctlr_vhdl != NULL);
-
-    /*
-     * decode the nic, and hang its stuff off our
-     * connection point where other drivers can get
-     * at it.
-     */
-#ifdef LATER
-    nicinfo = BRIDGE_VERTEX_MFG_INFO(xconn_vhdl, (nic_data_t) & bridge->b_nic);
-#endif
-
-    /*
-     * Get the hint structure; if some NIC callback
-     * marked this vertex as "hands-off" then we
-     * just return here, before doing anything else.
-     */
-    pcibr_hints = pcibr_hints_get(xconn_vhdl, 0);
-
-    if (pcibr_hints && pcibr_hints->ph_hands_off)
-	return -1;			/* generic operations disabled */
-
-    id = bridge->b_wid_id;
-    rev = XWIDGET_PART_REV_NUM(id);
-
-    hwgraph_info_add_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, (arbitrary_info_t) rev);
-
-    /*
-     * allocate soft state structure, fill in some
-     * fields, and hook it up to our vertex.
-     */
-    NEW(pcibr_soft);
-    BZERO(pcibr_soft, sizeof *pcibr_soft);
-    pcibr_soft_set(pcibr_vhdl, pcibr_soft);
-
-    pcibr_soft->bs_conn = xconn_vhdl;
-    pcibr_soft->bs_vhdl = pcibr_vhdl;
-    pcibr_soft->bs_base = bridge;
-    pcibr_soft->bs_rev_num = rev;
-    pcibr_soft->bs_intr_bits = pcibr_intr_bits;
-    if (is_xbridge(bridge)) {
-	pcibr_soft->bs_int_ate_size = XBRIDGE_INTERNAL_ATES;
-	pcibr_soft->bs_xbridge = 1;
-    } else {
-	pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES;
-	pcibr_soft->bs_xbridge = 0;
-    }
-
-    nasid = NASID_GET(bridge);
-    scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    pcibr_soft->bs_l1sc = scp;
-    pcibr_soft->bs_moduleid = iobrick_module_get(scp);
-    pcibr_soft->bsi_err_intr = 0;
-
-    /* Bridges up through REV C
-     * are unable to set the direct
-     * byteswappers to BYTE_STREAM.
-     */
-    if (pcibr_soft->bs_rev_num <= BRIDGE_PART_REV_C) {
-	pcibr_soft->bs_pio_end_io = PCIIO_WORD_VALUES;
-	pcibr_soft->bs_pio_end_mem = PCIIO_WORD_VALUES;
-    }
-#if PCIBR_SOFT_LIST
-    {
-	pcibr_list_p            self;
-
-	NEW(self);
-	self->bl_soft = pcibr_soft;
-	self->bl_vhdl = pcibr_vhdl;
-	self->bl_next = pcibr_list;
-        pcibr_list = self; 
-    }
-#endif
-
-    /*
-     * get the name of this bridge vertex and keep the info. Use this
-     * only where it is really needed now: like error interrupts.
-     */
-    s = dev_to_name(pcibr_vhdl, devnm, MAXDEVNAME);
-    pcibr_soft->bs_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
-    strcpy(pcibr_soft->bs_name, s);
-
-#if SHOW_REVS || DEBUG
-#if !DEBUG
-    if (kdebug)
-#endif
-	printk("%sBridge ASIC: rev %s (code=0x%x) at %s\n",
-		is_xbridge(bridge) ? "X" : "",
-		(rev == BRIDGE_PART_REV_A) ? "A" :
-		(rev == BRIDGE_PART_REV_B) ? "B" :
-		(rev == BRIDGE_PART_REV_C) ? "C" :
-		(rev == BRIDGE_PART_REV_D) ? "D" :
-		(rev == XBRIDGE_PART_REV_A) ? "A" :
-		(rev == XBRIDGE_PART_REV_B) ? "B" :
-		"unknown",
-		rev, pcibr_soft->bs_name);
-#endif
-
-    info = xwidget_info_get(xconn_vhdl);
-    pcibr_soft->bs_xid = xwidget_info_id_get(info);
-    pcibr_soft->bs_master = xwidget_info_master_get(info);
-    pcibr_soft->bs_mxid = xwidget_info_masterid_get(info);
-
-    /*
-     * Init bridge lock.
-     */
-    spin_lock_init(&pcibr_soft->bs_lock);
-
-    /*
-     * If we have one, process the hints structure.
-     */
-    if (pcibr_hints) {
-	rrb_fixed = pcibr_hints->ph_rrb_fixed;
-
-	pcibr_soft->bs_rrb_fixed = rrb_fixed;
-
-	if (pcibr_hints->ph_intr_bits)
-	    pcibr_soft->bs_intr_bits = pcibr_hints->ph_intr_bits;
-
-	for (slot = 0; slot < 8; ++slot) {
-	    int                     hslot = pcibr_hints->ph_host_slot[slot] - 1;
-
-	    if (hslot < 0) {
-		pcibr_soft->bs_slot[slot].host_slot = slot;
-	    } else {
-		pcibr_soft->bs_slot[slot].has_host = 1;
-		pcibr_soft->bs_slot[slot].host_slot = hslot;
-	    }
-	}
-    }
-    /*
-     * set up initial values for state fields
-     */
-    for (slot = 0; slot < 8; ++slot) {
-	pcibr_soft->bs_slot[slot].bss_devio.bssd_space = PCIIO_SPACE_NONE;
-	pcibr_soft->bs_slot[slot].bss_d64_base = PCIBR_D64_BASE_UNSET;
-	pcibr_soft->bs_slot[slot].bss_d32_base = PCIBR_D32_BASE_UNSET;
-	pcibr_soft->bs_slot[slot].bss_ext_ates_active = ATOMIC_INIT(0);
-    }
-
-    for (ibit = 0; ibit < 8; ++ibit) {
-	pcibr_soft->bs_intr[ibit].bsi_xtalk_intr = 0;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_soft = pcibr_soft;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_list = NULL;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_stat = 
-							&(bridge->b_int_status);
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_hdlrcnt = 0;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_shared = 0;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_connected = 0;
-    }
-
-    /*
-     * Initialize various Bridge registers.
-     */
-
-    /*
-     * On pre-Rev.D bridges, set the PCI_RETRY_CNT
-     * to zero to avoid dropping stores. (#475347)
-     */
-    if (rev < BRIDGE_PART_REV_D)
-	bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_MASK;
-
-    /*
-     * Clear all pending interrupts.
-     */
-    bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);
-
-    /*
-     * Until otherwise set up,
-     * assume all interrupts are
-     * from slot 7.
-     */
-    bridge->b_int_device = (uint32_t) 0xffffffff;
-
-    {
-	bridgereg_t             dirmap;
-	paddr_t                 paddr;
-	iopaddr_t               xbase;
-	xwidgetnum_t            xport;
-	iopaddr_t               offset;
-	int                     num_entries = 0;
-	int                     entry;
-	cnodeid_t		cnodeid;
-	nasid_t			nasid;
-
-	/* Set the Bridge's 32-bit PCI to XTalk
-	 * Direct Map register to the most useful
-	 * value we can determine.  Note that we
-	 * must use a single xid for all of:
-	 *      direct-mapped 32-bit DMA accesses
-	 *      direct-mapped 64-bit DMA accesses
-	 *      DMA accesses through the PMU
-	 *      interrupts
-	 * This is the only way to guarantee that
-	 * completion interrupts will reach a CPU
-	 * after all DMA data has reached memory.
-	 * (Of course, there may be a few special
-	 * drivers/controlers that explicitly manage
-	 * this ordering problem.)
-	 */
-
-	cnodeid = 0;  /* default node id */
-	/*
-	 * Determine the base address node id to be used for all 32-bit
-	 * Direct Mapping I/O. The default is node 0, but this can be changed
-	 * via a DEVICE_ADMIN directive and the PCIBUS_DMATRANS_NODE
-	 * attribute in the irix.sm config file. A device driver can obtain
-	 * this node value via a call to pcibr_get_dmatrans_node().
-	 */
-	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
-	paddr = NODE_OFFSET(nasid) + 0;
-
-	/* currently, we just assume that if we ask
-	 * for a DMA mapping to "zero" the XIO
-	 * host will transmute this into a request
-	 * for the lowest hunk of memory.
-	 */
-	xbase = xtalk_dmatrans_addr(xconn_vhdl, 0,
-				    paddr, _PAGESZ, 0);
-
-	if (xbase != XIO_NOWHERE) {
-	    if (XIO_PACKED(xbase)) {
-		xport = XIO_PORT(xbase);
-		xbase = XIO_ADDR(xbase);
-	    } else
-		xport = pcibr_soft->bs_mxid;
-
-	    offset = xbase & ((1ull << BRIDGE_DIRMAP_OFF_ADDRSHFT) - 1ull);
-	    xbase >>= BRIDGE_DIRMAP_OFF_ADDRSHFT;
-
-	    dirmap = xport << BRIDGE_DIRMAP_W_ID_SHFT;
-
-	    if (xbase)
-		dirmap |= BRIDGE_DIRMAP_OFF & xbase;
-	    else if (offset >= (512 << 20))
-		dirmap |= BRIDGE_DIRMAP_ADD512;
-
-	    bridge->b_dir_map = dirmap;
-	}
-	/*
-	 * Set bridge's idea of page size according to the system's
-	 * idea of "IO page size".  TBD: The idea of IO page size
-	 * should really go away.
-	 */
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	spl_level = splhi();
-#if IOPGSIZE == 4096
-	bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE;
-#elif IOPGSIZE == 16384
-	bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE;
-#else
-	<<<Unable to deal with IOPGSIZE >>>;
-#endif
-	bridge->b_wid_control;		/* inval addr bug war */
-	splx(spl_level);
-
-	/* Initialize internal mapping entries */
-	for (entry = 0; entry < pcibr_soft->bs_int_ate_size; entry++)
-	    bridge->b_int_ate_ram[entry].wr = 0;
-
-	/*
-	 * Determine if there's external mapping SSRAM on this
-	 * bridge.  Set up Bridge control register appropriately,
-	 * inititlize SSRAM, and set software up to manage RAM
-	 * entries as an allocatable resource.
-	 *
-	 * Currently, we just use the rm* routines to manage ATE
-	 * allocation.  We should probably replace this with a
-	 * Best Fit allocator.
-	 *
-	 * For now, if we have external SSRAM, avoid using
-	 * the internal ssram: we can't turn PREFETCH on
-	 * when we use the internal SSRAM; and besides,
-	 * this also guarantees that no allocation will
-	 * straddle the internal/external line, so we
-	 * can increment ATE write addresses rather than
-	 * recomparing against BRIDGE_INTERNAL_ATES every
-	 * time.
-	 */
-	if (is_xbridge(bridge))
-		num_entries = 0;
-	else
-		num_entries = pcibr_init_ext_ate_ram(bridge);
-
-	/* we always have 128 ATEs (512 for Xbridge) inside the chip
-	 * even if disabled for debugging.
-	 */
-	pcibr_soft->bs_int_ate_map = rmallocmap(pcibr_soft->bs_int_ate_size);
-	pcibr_ate_free(pcibr_soft, 0, pcibr_soft->bs_int_ate_size);
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_attach: %d INTERNAL ATEs\n", pcibr_soft->bs_int_ate_size);
-#endif
-
-	if (num_entries > pcibr_soft->bs_int_ate_size) {
-#if PCIBR_ATE_NOTBOTH			/* for debug -- forces us to use external ates */
-	    printk("pcibr_attach: disabling internal ATEs.\n");
-	    pcibr_ate_alloc(pcibr_soft, pcibr_soft->bs_int_ate_size);
-#endif
-	    pcibr_soft->bs_ext_ate_map = rmallocmap(num_entries);
-	    pcibr_ate_free(pcibr_soft, pcibr_soft->bs_int_ate_size,
-			   num_entries - pcibr_soft->bs_int_ate_size);
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_attach: %d EXTERNAL ATEs\n",
-		    num_entries - pcibr_soft->bs_int_ate_size);
-#endif
-	}
-    }
-
-    {
-	bridgereg_t             dirmap;
-	iopaddr_t               xbase;
-
-	/*
-	 * now figure the *real* xtalk base address
-	 * that dirmap sends us to.
-	 */
-	dirmap = bridge->b_dir_map;
-	if (dirmap & BRIDGE_DIRMAP_OFF)
-	    xbase = (iopaddr_t)(dirmap & BRIDGE_DIRMAP_OFF)
-			<< BRIDGE_DIRMAP_OFF_ADDRSHFT;
-	else if (dirmap & BRIDGE_DIRMAP_ADD512)
-	    xbase = 512 << 20;
-	else
-	    xbase = 0;
-
-	pcibr_soft->bs_dir_xbase = xbase;
-
-	/* it is entirely possible that we may, at this
-	 * point, have our dirmap pointing somewhere
-	 * other than our "master" port.
-	 */
-	pcibr_soft->bs_dir_xport =
-	    (dirmap & BRIDGE_DIRMAP_W_ID) >> BRIDGE_DIRMAP_W_ID_SHFT;
-    }
-
-    /* pcibr sources an error interrupt;
-     * figure out where to send it.
-     *
-     * If any interrupts are enabled in bridge,
-     * then the prom set us up and our interrupt
-     * has already been reconnected in mlreset
-     * above.
-     *
-     * Need to set the D_INTR_ISERR flag
-     * in the dev_desc used for allocating the
-     * error interrupt, so our interrupt will
-     * be properly routed and prioritized.
-     *
-     * If our crosstalk provider wants to
-     * fix widget error interrupts to specific
-     * destinations, D_INTR_ISERR is how it
-     * knows to do this.
-     */
-
-    xtalk_intr = xtalk_intr_alloc(xconn_vhdl, dev_desc, pcibr_vhdl);
-    ASSERT(xtalk_intr != NULL);
-
-    pcibr_soft->bsi_err_intr = xtalk_intr;
-
-    /*
-     * On IP35 with XBridge, we do some extra checks in pcibr_setwidint
-     * in order to work around some addressing limitations.  In order
-     * for that fire wall to work properly, we need to make sure we
-     * start from a known clean state.
-     */
-    pcibr_clearwidint(bridge);
-
-    xtalk_intr_connect(xtalk_intr, (xtalk_intr_setfunc_t)pcibr_setwidint, (void *)bridge);
-
-    /*
-     * now we can start handling error interrupts;
-     * enable all of them.
-     * NOTE: some PCI ints may already be enabled.
-     */
-    b_int_enable = bridge->b_int_enable | BRIDGE_ISR_ERRORS;
-
-
-    bridge->b_int_enable = b_int_enable;
-    bridge->b_int_mode = 0;		/* do not send "clear interrupt" packets */
-
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    /*
-     * Depending on the rev of bridge, disable certain features.
-     * Easiest way seems to be to force the PCIBR_NOwhatever
-     * flag to be on for all DMA calls, which overrides any
-     * PCIBR_whatever flag or even the setting of whatever
-     * from the PCIIO_DMA_class flags (or even from the other
-     * PCIBR flags, since NO overrides YES).
-     */
-    pcibr_soft->bs_dma_flags = 0;
-
-    /* PREFETCH:
-     * Always completely disabled for REV.A;
-     * at "pcibr_prefetch_enable_rev", anyone
-     * asking for PCIIO_PREFETCH gets it.
-     * Between these two points, you have to ask
-     * for PCIBR_PREFETCH, which promises that
-     * your driver knows about known Bridge WARs.
-     */
-    if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_B)
-	pcibr_soft->bs_dma_flags |= PCIBR_NOPREFETCH;
-    else if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_prefetch_enable_rev))
-	pcibr_soft->bs_dma_flags |= PCIIO_NOPREFETCH;
-
-    /* WRITE_GATHER:
-     * Disabled up to but not including the
-     * rev number in pcibr_wg_enable_rev. There
-     * is no "WAR range" as with prefetch.
-     */
-    if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_wg_enable_rev))
-	pcibr_soft->bs_dma_flags |= PCIBR_NOWRITE_GATHER;
-
-    pciio_provider_register(pcibr_vhdl, &pcibr_provider);
-    pciio_provider_startup(pcibr_vhdl);
-
-    pci_io_fb = 0x00000004;		/* I/O FreeBlock Base */
-    pci_io_fl = 0xFFFFFFFF;		/* I/O FreeBlock Last */
-
-    pci_lo_fb = 0x00000010;		/* Low Memory FreeBlock Base */
-    pci_lo_fl = 0x001FFFFF;		/* Low Memory FreeBlock Last */
-
-    pci_hi_fb = 0x00200000;		/* High Memory FreeBlock Base */
-    pci_hi_fl = 0x3FFFFFFF;		/* High Memory FreeBlock Last */
-
-
-    PCI_ADDR_SPACE_LIMITS_STORE();
-
-    /* build "no-slot" connection point
-     */
-    pcibr_info = pcibr_device_info_new
-	(pcibr_soft, PCIIO_SLOT_NONE, PCIIO_FUNC_NONE,
-	 PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
-    noslot_conn = pciio_device_info_register
-	(pcibr_vhdl, &pcibr_info->f_c);
-
-    /* Remember the no slot connection point info for tearing it
-     * down during detach.
-     */
-    pcibr_soft->bs_noslot_conn = noslot_conn;
-    pcibr_soft->bs_noslot_info = pcibr_info;
-#if PCI_FBBE
-    fast_back_to_back_enable = 1;
-#endif
-
-#if PCI_FBBE
-    if (fast_back_to_back_enable) {
-	/*
-	 * All devices on the bus are capable of fast back to back, so
-	 * we need to set the fast back to back bit in all devices on
-	 * the bus that are capable of doing such accesses.
-	 */
-    }
-#endif
-
-#ifdef LATER
-    /* If the bridge has been reset then there is no need to reset
-     * the individual PCI slots.
-     */
-    for (slot = 0; slot < 8; ++slot)  
-	/* Reset all the slots */
-	(void)pcibr_slot_reset(pcibr_vhdl, slot);
-#endif
-
-    for (slot = 0; slot < 8; ++slot)
-	/* Find out what is out there */
-	(void)pcibr_slot_info_init(pcibr_vhdl,slot);
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Set up the address space for this slot in the pci land */
-	(void)pcibr_slot_addr_space_init(pcibr_vhdl,slot);
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Setup the device register */
-	(void)pcibr_slot_device_init(pcibr_vhdl, slot);
-
-#ifndef __ia64
-    for (slot = 0; slot < 8; ++slot)  
-	/* Set up convenience links */
-	if (is_xbridge(bridge))
-		if (pcibr_soft->bs_slot[slot].bss_ninfo > 0) /* if occupied */
-			pcibr_bus_cnvlink(pcibr_info->f_vertex, slot);
-#endif
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Setup host/guest relations */
-	(void)pcibr_slot_guest_info_init(pcibr_vhdl,slot);
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Initial RRB management */
-	(void)pcibr_slot_initial_rrb_alloc(pcibr_vhdl,slot);
-
-    /* driver attach routines should be called out from generic linux code */
-    for (slot = 0; slot < 8; ++slot)  
-	/* Call the device attach */
-	(void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0);
-
-    /*
-     * Each Pbrick PCI bus only has slots 1 and 2.   Similarly for
-     * widget 0xe on Ibricks.  Allocate RRB's accordingly.
-     */
-    if (pcibr_soft->bs_moduleid > 0) {
-	switch (MODULE_GET_BTCHAR(pcibr_soft->bs_moduleid)) {
-	case 'p':		/* Pbrick */
-		do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
-		do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8);
-		break;
-	case 'i':		/* Ibrick */
-	  	/* port 0xe on the Ibrick only has slots 1 and 2 */
-		if (pcibr_soft->bs_xid == 0xe) {
-			do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
-			do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8);
-		}
-		else {
-		    	/* allocate one RRB for the serial port */
-			do_pcibr_rrb_autoalloc(pcibr_soft, 0, 1);
-		}
-		break;
-	} /* switch */
-    }
-
-#ifdef LATER
-    if (strstr(nicinfo, XTALK_PCI_PART_NUM)) {
-	do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
-#if PCIBR_RRB_DEBUG
-	printf("\n\nFound XTALK_PCI (030-1275) at %v\n", xconn_vhdl);
-
-	printf("pcibr_attach: %v Shoebox RRB MANAGEMENT: %d+%d free\n",
-		pcibr_vhdl,
-		pcibr_soft->bs_rrb_avail[0],
-		pcibr_soft->bs_rrb_avail[1]);
-
-	for (slot = 0; slot < 8; ++slot)
-	    printf("\t%d+%d+%d",
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot],
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-
-	printf("\n");
-#endif
-    }
-#else
-	FIXME("pcibr_attach: Call do_pcibr_rrb_autoalloc nicinfo\n");
-#endif
-
-    if (aa)
-	    async_attach_add_info(noslot_conn, aa);
-
-    pciio_device_attach(noslot_conn, 0);
-
-
-    /* 
-     * Tear down pointer to async attach info -- async threads for
-     * bridge's descendants may be running but the bridge's work is done.
-     */
-    if (aa)
-	    async_attach_del_info(xconn_vhdl);
-
-    return 0;
-}
-/*
- * pcibr_detach:
- *	Detach the bridge device from the hwgraph after cleaning out all the 
- *	underlying vertices.
- */
-int
-pcibr_detach(devfs_handle_t xconn)
-{
-    pciio_slot_t	slot;
-    devfs_handle_t	pcibr_vhdl;
-    pcibr_soft_t	pcibr_soft;
-    bridge_t		*bridge;
-
-    /* Get the bridge vertex from its xtalk connection point */
-    if (hwgraph_traverse(xconn, EDGE_LBL_PCI, &pcibr_vhdl) != GRAPH_SUCCESS)
-	return(1);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge = pcibr_soft->bs_base;
-
-    /* Disable the interrupts from the bridge */
-    bridge->b_int_enable = 0;
-
-    /* Detach all the PCI devices talking to this bridge */
-    for(slot = 0; slot < 8; slot++) {
-#ifdef DEBUG
-	printk("pcibr_device_detach called for %p/%d\n",
-		pcibr_vhdl,slot);
-#endif
-	pcibr_slot_detach(pcibr_vhdl, slot, 0);
-    }
-
-    /* Unregister the no-slot connection point */
-    pciio_device_info_unregister(pcibr_vhdl,
-				 &(pcibr_soft->bs_noslot_info->f_c));
-
-    spin_lock_destroy(&pcibr_soft->bs_lock);
-    kfree(pcibr_soft->bs_name);
-    
-    /* Error handler gets unregistered when the widget info is 
-     * cleaned 
-     */
-    /* Free the soft ATE maps */
-    if (pcibr_soft->bs_int_ate_map)
-	rmfreemap(pcibr_soft->bs_int_ate_map);
-    if (pcibr_soft->bs_ext_ate_map)
-	rmfreemap(pcibr_soft->bs_ext_ate_map);
-
-    /* Disconnect the error interrupt and free the xtalk resources 
-     * associated with it.
-     */
-    xtalk_intr_disconnect(pcibr_soft->bsi_err_intr);
-    xtalk_intr_free(pcibr_soft->bsi_err_intr);
-
-    /* Clear the software state maintained by the bridge driver for this
-     * bridge.
-     */
-    DEL(pcibr_soft);
-    /* Remove the Bridge revision labelled info */
-    (void)hwgraph_info_remove_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, NULL);
-    /* Remove the character device associated with this bridge */
-    (void)hwgraph_edge_remove(pcibr_vhdl, EDGE_LBL_CONTROLLER, NULL);
-    /* Remove the PCI bridge vertex */
-    (void)hwgraph_edge_remove(xconn, EDGE_LBL_PCI, NULL);
-
-    return(0);
-}
-
-int
-pcibr_asic_rev(devfs_handle_t pconn_vhdl)
-{
-    devfs_handle_t            pcibr_vhdl;
-    arbitrary_info_t        ainfo;
-
-    if (GRAPH_SUCCESS !=
-	hwgraph_traverse(pconn_vhdl, EDGE_LBL_MASTER, &pcibr_vhdl))
-	return -1;
-
-    if (GRAPH_SUCCESS !=
-	hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &ainfo))
-	return -1;
-
-    return (int) ainfo;
-}
-
-int
-pcibr_write_gather_flush(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t  pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t  pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    pciio_slot_t  slot;
-    slot = pciio_info_slot_get(pciio_info);
-    pcibr_device_write_gather_flush(pcibr_soft, slot);
-    return 0;
-}
-
-/* =====================================================================
- *    PIO MANAGEMENT
- */
-
-LOCAL iopaddr_t
-pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl,
-		      pciio_slot_t slot,
-		      pciio_space_t space,
-		      iopaddr_t pci_addr,
-		      size_t req_size,
-		      unsigned flags)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_info_t            pciio_info = &pcibr_info->f_c;
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    unsigned                bar;	/* which BASE reg on device is decoding */
-    iopaddr_t               xio_addr = XIO_NOWHERE;
-
-    pciio_space_t           wspace;	/* which space device is decoding */
-    iopaddr_t               wbase;	/* base of device decode on PCI */
-    size_t                  wsize;	/* size of device decode on PCI */
-
-    int                     try;	/* DevIO(x) window scanning order control */
-    int                     win;	/* which DevIO(x) window is being used */
-    pciio_space_t           mspace;	/* target space for devio(x) register */
-    iopaddr_t               mbase;	/* base of devio(x) mapped area on PCI */
-    size_t                  msize;	/* size of devio(x) mapped area on PCI */
-    size_t                  mmask;	/* addr bits stored in Device(x) */
-
-    unsigned long           s;
-
-    s = pcibr_lock(pcibr_soft);
-
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	slot = pcibr_soft->bs_slot[slot].host_slot;
-	pcibr_info = pcibr_soft->bs_slot[slot].bss_infos[0];
-    }
-    if (space == PCIIO_SPACE_NONE)
-	goto done;
-
-    if (space == PCIIO_SPACE_CFG) {
-	/*
-	 * Usually, the first mapping
-	 * established to a PCI device
-	 * is to its config space.
-	 *
-	 * In any case, we definitely
-	 * do NOT need to worry about
-	 * PCI BASE registers, and
-	 * MUST NOT attempt to point
-	 * the DevIO(x) window at
-	 * this access ...
-	 */
-	if (((flags & PCIIO_BYTE_STREAM) == 0) &&
-	    ((pci_addr + req_size) <= BRIDGE_TYPE0_CFG_FUNC_OFF))
-	    xio_addr = pci_addr + BRIDGE_TYPE0_CFG_DEV(slot);
-
-	goto done;
-    }
-    if (space == PCIIO_SPACE_ROM) {
-	/* PIO to the Expansion Rom.
-	 * Driver is responsible for
-	 * enabling and disabling
-	 * decodes properly.
-	 */
-	wbase = pcibr_info->f_rbase;
-	wsize = pcibr_info->f_rsize;
-
-	/*
-	 * While the driver should know better
-	 * than to attempt to map more space
-	 * than the device is decoding, he might
-	 * do it; better to bail out here.
-	 */
-	if ((pci_addr + req_size) > wsize)
-	    goto done;
-
-	pci_addr += wbase;
-	space = PCIIO_SPACE_MEM;
-    }
-    /*
-     * reduce window mappings to raw
-     * space mappings (maybe allocating
-     * windows), and try for DevIO(x)
-     * usage (setting it if it is available).
-     */
-    bar = space - PCIIO_SPACE_WIN0;
-    if (bar < 6) {
-	wspace = pcibr_info->f_window[bar].w_space;
-	if (wspace == PCIIO_SPACE_NONE)
-	    goto done;
-
-	/* get PCI base and size */
-	wbase = pcibr_info->f_window[bar].w_base;
-	wsize = pcibr_info->f_window[bar].w_size;
-
-	/*
-	 * While the driver should know better
-	 * than to attempt to map more space
-	 * than the device is decoding, he might
-	 * do it; better to bail out here.
-	 */
-	if ((pci_addr + req_size) > wsize)
-	    goto done;
-
-	/* shift from window relative to
-	 * decoded space relative.
-	 */
-	pci_addr += wbase;
-	space = wspace;
-    } else
-	bar = -1;
-
-    /* Scan all the DevIO(x) windows twice looking for one
-     * that can satisfy our request. The first time through,
-     * only look at assigned windows; the second time, also
-     * look at PCIIO_SPACE_NONE windows. Arrange the order
-     * so we always look at our own window first.
-     *
-     * We will not attempt to satisfy a single request
-     * by concatinating multiple windows.
-     */
-    for (try = 0; try < 16; ++try) {
-	bridgereg_t             devreg;
-	unsigned                offset;
-
-	win = (try + slot) % 8;
-
-	/* If this DevIO(x) mapping area can provide
-	 * a mapping to this address, use it.
-	 */
-	msize = (win < 2) ? 0x200000 : 0x100000;
-	mmask = -msize;
-	if (space != PCIIO_SPACE_IO)
-	    mmask &= 0x3FFFFFFF;
-
-	offset = pci_addr & (msize - 1);
-
-	/* If this window can't possibly handle that request,
-	 * go on to the next window.
-	 */
-	if (((pci_addr & (msize - 1)) + req_size) > msize)
-	    continue;
-
-	devreg = pcibr_soft->bs_slot[win].bss_device;
-
-	/* Is this window "nailed down"?
-	 * If not, maybe we can use it.
-	 * (only check this the second time through)
-	 */
-	mspace = pcibr_soft->bs_slot[win].bss_devio.bssd_space;
-	if ((try > 7) && (mspace == PCIIO_SPACE_NONE)) {
-
-	    /* If this is the primary DevIO(x) window
-	     * for some other device, skip it.
-	     */
-	    if ((win != slot) &&
-		(PCIIO_VENDOR_ID_NONE !=
-		 pcibr_soft->bs_slot[win].bss_vendor_id))
-		continue;
-
-	    /* It's a free window, and we fit in it.
-	     * Set up Device(win) to our taste.
-	     */
-	    mbase = pci_addr & mmask;
-
-	    /* check that we would really get from
-	     * here to there.
-	     */
-	    if ((mbase | offset) != pci_addr)
-		continue;
-
-	    devreg &= ~BRIDGE_DEV_OFF_MASK;
-	    if (space != PCIIO_SPACE_IO)
-		devreg |= BRIDGE_DEV_DEV_IO_MEM;
-	    else
-		devreg &= ~BRIDGE_DEV_DEV_IO_MEM;
-	    devreg |= (mbase >> 20) & BRIDGE_DEV_OFF_MASK;
-
-	    /* default is WORD_VALUES.
-	     * if you specify both,
-	     * operation is undefined.
-	     */
-	    if (flags & PCIIO_BYTE_STREAM)
-		devreg |= BRIDGE_DEV_DEV_SWAP;
-	    else
-		devreg &= ~BRIDGE_DEV_DEV_SWAP;
-
-	    if (pcibr_soft->bs_slot[win].bss_device != devreg) {
-		bridge->b_device[win].reg = devreg;
-		pcibr_soft->bs_slot[win].bss_device = devreg;
-		bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-
-#if DEBUG && PCI_DEBUG
-		printk("pcibr Device(%d): 0x%lx\n", win, bridge->b_device[win].reg);
-#endif
-	    }
-	    pcibr_soft->bs_slot[win].bss_devio.bssd_space = space;
-	    pcibr_soft->bs_slot[win].bss_devio.bssd_base = mbase;
-	    xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase);
-
-#if DEBUG && PCI_DEBUG
-	    printk("%s LINE %d map to space %d space desc 0x%x[%lx..%lx] for slot %d allocates DevIO(%d) devreg 0x%x\n", 
-		    __FUNCTION__, __LINE__, space, space_desc,
-		    pci_addr, pci_addr + req_size - 1,
-		    slot, win, devreg);
-#endif
-
-	    goto done;
-	}				/* endif DevIO(x) not pointed */
-	mbase = pcibr_soft->bs_slot[win].bss_devio.bssd_base;
-
-	/* Now check for request incompat with DevIO(x)
-	 */
-	if ((mspace != space) ||
-	    (pci_addr < mbase) ||
-	    ((pci_addr + req_size) > (mbase + msize)) ||
-	    ((flags & PCIIO_BYTE_STREAM) && !(devreg & BRIDGE_DEV_DEV_SWAP)) ||
-	    (!(flags & PCIIO_BYTE_STREAM) && (devreg & BRIDGE_DEV_DEV_SWAP)))
-	    continue;
-
-	/* DevIO(x) window is pointed at PCI space
-	 * that includes our target. Calculate the
-	 * final XIO address, release the lock and
-	 * return.
-	 */
-	xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase);
-
-#if DEBUG && PCI_DEBUG
-	printk("%s LINE %d map to space %d [0x%p..0x%p] for slot %d uses DevIO(%d)\n",
-		__FUNCTION__, __LINE__, space,  pci_addr, pci_addr + req_size - 1, slot, win);
-#endif
-	goto done;
-    }
-
-    switch (space) {
-	/*
-	 * Accesses to device decode
-	 * areas that do a not fit
-	 * within the DevIO(x) space are
-	 * modified to be accesses via
-	 * the direct mapping areas.
-	 *
-	 * If necessary, drivers can
-	 * explicitly ask for mappings
-	 * into these address spaces,
-	 * but this should never be needed.
-	 */
-    case PCIIO_SPACE_MEM:		/* "mem space" */
-    case PCIIO_SPACE_MEM32:		/* "mem, use 32-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM32_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM32_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM32_BASE;
-	break;
-
-    case PCIIO_SPACE_MEM64:		/* "mem, use 64-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM64_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM64_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM64_BASE;
-	break;
-
-    case PCIIO_SPACE_IO:		/* "i/o space" */
-	/* Bridge Hardware Bug WAR #482741:
-	 * The 4G area that maps directly from
-	 * XIO space to PCI I/O space is busted
-	 * until Bridge Rev D.
-	 */
-	if ((pcibr_soft->bs_rev_num > BRIDGE_PART_REV_C) &&
-	    ((pci_addr + BRIDGE_PCI_IO_BASE + req_size - 1) <=
-	     BRIDGE_PCI_IO_LIMIT))
-	    xio_addr = pci_addr + BRIDGE_PCI_IO_BASE;
-	break;
-    }
-
-    /* Check that "Direct PIO" byteswapping matches,
-     * try to change it if it does not.
-     */
-    if (xio_addr != XIO_NOWHERE) {
-	unsigned                bst;	/* nonzero to set bytestream */
-	unsigned               *bfp;	/* addr of record of how swapper is set */
-	unsigned                swb;	/* which control bit to mung */
-	unsigned                bfo;	/* current swapper setting */
-	unsigned                bfn;	/* desired swapper setting */
-
-	bfp = ((space == PCIIO_SPACE_IO)
-	       ? (&pcibr_soft->bs_pio_end_io)
-	       : (&pcibr_soft->bs_pio_end_mem));
-
-	bfo = *bfp;
-
-	bst = flags & PCIIO_BYTE_STREAM;
-
-	bfn = bst ? PCIIO_BYTE_STREAM : PCIIO_WORD_VALUES;
-
-	if (bfn == bfo) {		/* we already match. */
-	    ;
-	} else if (bfo != 0) {		/* we have a conflict. */
-#if DEBUG && PCI_DEBUG
-	    printk("pcibr_addr_pci_to_xio: swap conflict in space %d , was%s%s, want%s%s\n",
-		    space, 
-		    bfo & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
-		    bfo & PCIIO_WORD_VALUES ? " WORD_VALUES" : "",
-		    bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
-		    bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : "");
-#endif
-	    xio_addr = XIO_NOWHERE;
-	} else {			/* OK to make the change. */
-	    bridgereg_t             octl, nctl;
-
-	    swb = (space == PCIIO_SPACE_IO) ? BRIDGE_CTRL_IO_SWAP : BRIDGE_CTRL_MEM_SWAP;
-	    octl = bridge->b_wid_control;
-	    nctl = bst ? octl | swb : octl & ~swb;
-
-	    if (octl != nctl)		/* make the change if any */
-		bridge->b_wid_control = nctl;
-
-	    *bfp = bfn;			/* record the assignment */
-
-#if DEBUG && PCI_DEBUG
-	    printk("pcibr_addr_pci_to_xio: swap for space %d  set to%s%s\n",
-		    space, 
-		    bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
-		    bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : "");
-#endif
-	}
-    }
-  done:
-    pcibr_unlock(pcibr_soft, s);
-    return xio_addr;
-}
-
-/*ARGSUSED6 */
-pcibr_piomap_t
-pcibr_piomap_alloc(devfs_handle_t pconn_vhdl,
-		   device_desc_t dev_desc,
-		   pciio_space_t space,
-		   iopaddr_t pci_addr,
-		   size_t req_size,
-		   size_t req_size_max,
-		   unsigned flags)
-{
-    pcibr_info_t	    pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_info_t            pciio_info = &pcibr_info->f_c;
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    pcibr_piomap_t         *mapptr;
-    pcibr_piomap_t          maplist;
-    pcibr_piomap_t          pcibr_piomap;
-    iopaddr_t               xio_addr;
-    xtalk_piomap_t          xtalk_piomap;
-    unsigned long           s;
-
-    /* Make sure that the req sizes are non-zero */
-    if ((req_size < 1) || (req_size_max < 1))
-	return NULL;
-
-    /*
-     * Code to translate slot/space/addr
-     * into xio_addr is common between
-     * this routine and pcibr_piotrans_addr.
-     */
-    xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags);
-
-    if (xio_addr == XIO_NOWHERE)
-	return NULL;
-
-    /* Check the piomap list to see if there is already an allocated
-     * piomap entry but not in use. If so use that one. Otherwise
-     * allocate a new piomap entry and add it to the piomap list
-     */
-    mapptr = &(pcibr_info->f_piomap);
-
-    s = pcibr_lock(pcibr_soft);
-    for (pcibr_piomap = *mapptr;
-	 pcibr_piomap != NULL;
-	 pcibr_piomap = pcibr_piomap->bp_next) {
-	if (pcibr_piomap->bp_mapsz == 0)
-	    break;
-    }
-
-    if (pcibr_piomap)
-	mapptr = NULL;
-    else {
-	pcibr_unlock(pcibr_soft, s);
-	NEW(pcibr_piomap);
-    }
-
-    pcibr_piomap->bp_dev = pconn_vhdl;
-    pcibr_piomap->bp_slot = pciio_slot;
-    pcibr_piomap->bp_flags = flags;
-    pcibr_piomap->bp_space = space;
-    pcibr_piomap->bp_pciaddr = pci_addr;
-    pcibr_piomap->bp_mapsz = req_size;
-    pcibr_piomap->bp_soft = pcibr_soft;
-    pcibr_piomap->bp_toc[0] = ATOMIC_INIT(0);
-
-    if (mapptr) {
-	s = pcibr_lock(pcibr_soft);
-	maplist = *mapptr;
-	pcibr_piomap->bp_next = maplist;
-	*mapptr = pcibr_piomap;
-    }
-    pcibr_unlock(pcibr_soft, s);
-
-
-    if (pcibr_piomap) {
-	xtalk_piomap =
-	    xtalk_piomap_alloc(xconn_vhdl, 0,
-			       xio_addr,
-			       req_size, req_size_max,
-			       flags & PIOMAP_FLAGS);
-	if (xtalk_piomap) {
-	    pcibr_piomap->bp_xtalk_addr = xio_addr;
-	    pcibr_piomap->bp_xtalk_pio = xtalk_piomap;
-	} else {
-	    pcibr_piomap->bp_mapsz = 0;
-	    pcibr_piomap = 0;
-	}
-    }
-    return pcibr_piomap;
-}
-
-/*ARGSUSED */
-void
-pcibr_piomap_free(pcibr_piomap_t pcibr_piomap)
-{
-    xtalk_piomap_free(pcibr_piomap->bp_xtalk_pio);
-    pcibr_piomap->bp_xtalk_pio = 0;
-    pcibr_piomap->bp_mapsz = 0;
-}
-
-/*ARGSUSED */
-caddr_t
-pcibr_piomap_addr(pcibr_piomap_t pcibr_piomap,
-		  iopaddr_t pci_addr,
-		  size_t req_size)
-{
-    return xtalk_piomap_addr(pcibr_piomap->bp_xtalk_pio,
-			     pcibr_piomap->bp_xtalk_addr +
-			     pci_addr - pcibr_piomap->bp_pciaddr,
-			     req_size);
-}
-
-/*ARGSUSED */
-void
-pcibr_piomap_done(pcibr_piomap_t pcibr_piomap)
-{
-    xtalk_piomap_done(pcibr_piomap->bp_xtalk_pio);
-}
-
-/*ARGSUSED */
-caddr_t
-pcibr_piotrans_addr(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    pciio_space_t space,
-		    iopaddr_t pci_addr,
-		    size_t req_size,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    iopaddr_t               xio_addr;
-
-    xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags);
-
-    if (xio_addr == XIO_NOWHERE)
-	return NULL;
-
-    return xtalk_piotrans_addr(xconn_vhdl, 0, xio_addr, req_size, flags & PIOMAP_FLAGS);
-}
-
-/*
- * PIO Space allocation and management.
- *      Allocate and Manage the PCI PIO space (mem and io space)
- *      This routine is pretty simplistic at this time, and
- *      does pretty trivial management of allocation and freeing..
- *      The current scheme is prone for fragmentation..
- *      Change the scheme to use bitmaps.
- */
-
-/*ARGSUSED */
-iopaddr_t
-pcibr_piospace_alloc(devfs_handle_t pconn_vhdl,
-		     device_desc_t dev_desc,
-		     pciio_space_t space,
-		     size_t req_size,
-		     size_t alignment)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_info_t            pciio_info = &pcibr_info->f_c;
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-    pciio_piospace_t        piosp;
-    unsigned long           s;
-
-    iopaddr_t              *pciaddr, *pcilast;
-    iopaddr_t               start_addr;
-    size_t                  align_mask;
-
-    /*
-     * Check for proper alignment
-     */
-    ASSERT(alignment >= NBPP);
-    ASSERT((alignment & (alignment - 1)) == 0);
-
-    align_mask = alignment - 1;
-    s = pcibr_lock(pcibr_soft);
-
-    /*
-     * First look if a previously allocated chunk exists.
-     */
-    if ((piosp = pcibr_info->f_piospace)) {
-	/*
-	 * Look through the list for a right sized free chunk.
-	 */
-	do {
-	    if (piosp->free &&
-		(piosp->space == space) &&
-		(piosp->count >= req_size) &&
-		!(piosp->start & align_mask)) {
-		piosp->free = 0;
-		pcibr_unlock(pcibr_soft, s);
-		return piosp->start;
-	    }
-	    piosp = piosp->next;
-	} while (piosp);
-    }
-    ASSERT(!piosp);
-
-    switch (space) {
-    case PCIIO_SPACE_IO:
-	pciaddr = &pcibr_soft->bs_spinfo.pci_io_base;
-	pcilast = &pcibr_soft->bs_spinfo.pci_io_last;
-	break;
-    case PCIIO_SPACE_MEM:
-    case PCIIO_SPACE_MEM32:
-	pciaddr = &pcibr_soft->bs_spinfo.pci_mem_base;
-	pcilast = &pcibr_soft->bs_spinfo.pci_mem_last;
-	break;
-    default:
-	ASSERT(0);
-	pcibr_unlock(pcibr_soft, s);
-	return 0;
-    }
-
-    start_addr = *pciaddr;
-
-    /*
-     * Align start_addr.
-     */
-    if (start_addr & align_mask)
-	start_addr = (start_addr + align_mask) & ~align_mask;
-
-    if ((start_addr + req_size) > *pcilast) {
-	/*
-	 * If too big a request, reject it.
-	 */
-	pcibr_unlock(pcibr_soft, s);
-	return 0;
-    }
-    *pciaddr = (start_addr + req_size);
-
-    NEW(piosp);
-    piosp->free = 0;
-    piosp->space = space;
-    piosp->start = start_addr;
-    piosp->count = req_size;
-    piosp->next = pcibr_info->f_piospace;
-    pcibr_info->f_piospace = piosp;
-
-    pcibr_unlock(pcibr_soft, s);
-    return start_addr;
-}
-
-/*ARGSUSED */
-void
-pcibr_piospace_free(devfs_handle_t pconn_vhdl,
-		    pciio_space_t space,
-		    iopaddr_t pciaddr,
-		    size_t req_size)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-
-    pciio_piospace_t        piosp;
-    unsigned long           s;
-    char                    name[1024];
-
-    /*
-     * Look through the bridge data structures for the pciio_piospace_t
-     * structure corresponding to  'pciaddr'
-     */
-    s = pcibr_lock(pcibr_soft);
-    piosp = pcibr_info->f_piospace;
-    while (piosp) {
-	/*
-	 * Piospace free can only be for the complete
-	 * chunk and not parts of it..
-	 */
-	if (piosp->start == pciaddr) {
-	    if (piosp->count == req_size)
-		break;
-	    /*
-	     * Improper size passed for freeing..
-	     * Print a message and break;
-	     */
-	    hwgraph_vertex_name_get(pconn_vhdl, name, 1024);
-	    printk(KERN_WARNING  "pcibr_piospace_free: error");
-	    printk(KERN_WARNING  "Device %s freeing size (0x%lx) different than allocated (0x%lx)",
-					name, req_size, piosp->count);
-	    printk(KERN_WARNING  "Freeing 0x%lx instead", piosp->count);
-	    break;
-	}
-	piosp = piosp->next;
-    }
-
-    if (!piosp) {
-	printk(KERN_WARNING  
-		"pcibr_piospace_free: Address 0x%lx size 0x%lx - No match\n",
-		pciaddr, req_size);
-	pcibr_unlock(pcibr_soft, s);
-	return;
-    }
-    piosp->free = 1;
-    pcibr_unlock(pcibr_soft, s);
-    return;
-}
-
-/* =====================================================================
- *    DMA MANAGEMENT
- *
- *      The Bridge ASIC provides three methods of doing
- *      DMA: via a "direct map" register available in
- *      32-bit PCI space (which selects a contiguous 2G
- *      address space on some other widget), via
- *      "direct" addressing via 64-bit PCI space (all
- *      destination information comes from the PCI
- *      address, including transfer attributes), and via
- *      a "mapped" region that allows a bunch of
- *      different small mappings to be established with
- *      the PMU.
- *
- *      For efficiency, we most prefer to use the 32-bit
- *      direct mapping facility, since it requires no
- *      resource allocations. The advantage of using the
- *      PMU over the 64-bit direct is that single-cycle
- *      PCI addressing can be used; the advantage of
- *      using 64-bit direct over PMU addressing is that
- *      we do not have to allocate entries in the PMU.
- */
-
-/*
- * Convert PCI-generic software flags and Bridge-specific software flags
- * into Bridge-specific Direct Map attribute bits.
- */
-LOCAL iopaddr_t
-pcibr_flags_to_d64(unsigned flags, pcibr_soft_t pcibr_soft)
-{
-    iopaddr_t               attributes = 0;
-
-    /* Sanity check: Bridge only allows use of VCHAN1 via 64-bit addrs */
-#ifdef LATER
-    ASSERT_ALWAYS(!(flags & PCIBR_VCHAN1) || (flags & PCIIO_DMA_A64));
-#endif
-
-    /* Generic macro flags
-     */
-    if (flags & PCIIO_DMA_DATA) {	/* standard data channel */
-	attributes &= ~PCI64_ATTR_BAR;	/* no barrier bit */
-	attributes |= PCI64_ATTR_PREF;	/* prefetch on */
-    }
-    if (flags & PCIIO_DMA_CMD) {	/* standard command channel */
-	attributes |= PCI64_ATTR_BAR;	/* barrier bit on */
-	attributes &= ~PCI64_ATTR_PREF;	/* disable prefetch */
-    }
-    /* Generic detail flags
-     */
-    if (flags & PCIIO_PREFETCH)
-	attributes |= PCI64_ATTR_PREF;
-    if (flags & PCIIO_NOPREFETCH)
-	attributes &= ~PCI64_ATTR_PREF;
-
-    /* the swap bit is in the address attributes for xbridge */
-    if (pcibr_soft->bs_xbridge) {
-    	if (flags & PCIIO_BYTE_STREAM)
-        	attributes |= PCI64_ATTR_SWAP;
-    	if (flags & PCIIO_WORD_VALUES)
-        	attributes &= ~PCI64_ATTR_SWAP;
-    }
-
-    /* Provider-specific flags
-     */
-    if (flags & PCIBR_BARRIER)
-	attributes |= PCI64_ATTR_BAR;
-    if (flags & PCIBR_NOBARRIER)
-	attributes &= ~PCI64_ATTR_BAR;
-
-    if (flags & PCIBR_PREFETCH)
-	attributes |= PCI64_ATTR_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	attributes &= ~PCI64_ATTR_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	attributes |= PCI64_ATTR_PREC;
-    if (flags & PCIBR_NOPRECISE)
-	attributes &= ~PCI64_ATTR_PREC;
-
-    if (flags & PCIBR_VCHAN1)
-	attributes |= PCI64_ATTR_VIRTUAL;
-    if (flags & PCIBR_VCHAN0)
-	attributes &= ~PCI64_ATTR_VIRTUAL;
-
-    return (attributes);
-}
-
-/*
- * Convert PCI-generic software flags and Bridge-specific software flags
- * into Bridge-specific Address Translation Entry attribute bits.
- */
-LOCAL bridge_ate_t
-pcibr_flags_to_ate(unsigned flags)
-{
-    bridge_ate_t            attributes;
-
-    /* default if nothing specified:
-     * NOBARRIER
-     * NOPREFETCH
-     * NOPRECISE
-     * COHERENT
-     * Plus the valid bit
-     */
-    attributes = ATE_CO | ATE_V;
-
-    /* Generic macro flags
-     */
-    if (flags & PCIIO_DMA_DATA) {	/* standard data channel */
-	attributes &= ~ATE_BAR;		/* no barrier */
-	attributes |= ATE_PREF;		/* prefetch on */
-    }
-    if (flags & PCIIO_DMA_CMD) {	/* standard command channel */
-	attributes |= ATE_BAR;		/* barrier bit on */
-	attributes &= ~ATE_PREF;	/* disable prefetch */
-    }
-    /* Generic detail flags
-     */
-    if (flags & PCIIO_PREFETCH)
-	attributes |= ATE_PREF;
-    if (flags & PCIIO_NOPREFETCH)
-	attributes &= ~ATE_PREF;
-
-    /* Provider-specific flags
-     */
-    if (flags & PCIBR_BARRIER)
-	attributes |= ATE_BAR;
-    if (flags & PCIBR_NOBARRIER)
-	attributes &= ~ATE_BAR;
-
-    if (flags & PCIBR_PREFETCH)
-	attributes |= ATE_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	attributes &= ~ATE_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	attributes |= ATE_PREC;
-    if (flags & PCIBR_NOPRECISE)
-	attributes &= ~ATE_PREC;
-
-    return (attributes);
-}
-
-/*ARGSUSED */
-pcibr_dmamap_t
-pcibr_dmamap_alloc(devfs_handle_t pconn_vhdl,
-		   device_desc_t dev_desc,
-		   size_t req_size_max,
-		   unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            slot;
-    xwidgetnum_t            xio_port;
-
-    xtalk_dmamap_t          xtalk_dmamap;
-    pcibr_dmamap_t          pcibr_dmamap;
-    int                     ate_count;
-    int                     ate_index;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-#ifdef IRIX
-    NEWf(pcibr_dmamap, flags);
-#else
-    /*
-     * On SNIA64, these maps are pre-allocated because pcibr_dmamap_alloc()
-     * can be called within an interrupt thread.
-     */
-    pcibr_dmamap = (pcibr_dmamap_t)get_free_pciio_dmamap(pcibr_soft->bs_vhdl);
-#endif
-
-    if (!pcibr_dmamap)
-	return 0;
-
-    xtalk_dmamap = xtalk_dmamap_alloc(xconn_vhdl, dev_desc, req_size_max,
-				      flags & DMAMAP_FLAGS);
-    if (!xtalk_dmamap) {
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_attach: xtalk_dmamap_alloc failed\n");
-#endif
-#ifdef IRIX
-	DEL(pcibr_dmamap);
-#else
-	free_pciio_dmamap(pcibr_dmamap);
-#endif
-	return 0;
-    }
-    xio_port = pcibr_soft->bs_mxid;
-    slot = pciio_info_slot_get(pciio_info);
-
-    pcibr_dmamap->bd_dev = pconn_vhdl;
-    pcibr_dmamap->bd_slot = slot;
-    pcibr_dmamap->bd_soft = pcibr_soft;
-    pcibr_dmamap->bd_xtalk = xtalk_dmamap;
-    pcibr_dmamap->bd_max_size = req_size_max;
-    pcibr_dmamap->bd_xio_port = xio_port;
-
-    if (flags & PCIIO_DMA_A64) {
-	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D64_BITS)) {
-	    iopaddr_t               pci_addr;
-	    int                     have_rrbs;
-	    int                     min_rrbs;
-
-	    /* Device is capable of A64 operations,
-	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
-	     * mappings using shared resources.
-	     */
-
-	    pci_addr = pcibr_flags_to_d64(flags, pcibr_soft);
-
-	    pcibr_dmamap->bd_flags = flags;
-	    pcibr_dmamap->bd_xio_addr = 0;
-	    pcibr_dmamap->bd_pci_addr = pci_addr;
-
-	    /* Make sure we have an RRB (or two).
-	     */
-	    if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) {
-		if (flags & PCIBR_VCHAN1)
-		    slot += PCIBR_RRB_SLOT_VIRTUAL;
-		have_rrbs = pcibr_soft->bs_rrb_valid[slot];
-		if (have_rrbs < 2) {
-		    if (pci_addr & PCI64_ATTR_PREF)
-			min_rrbs = 2;
-		    else
-			min_rrbs = 1;
-		    if (have_rrbs < min_rrbs)
-			do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs);
-		}
-	    }
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_dmamap_alloc: using direct64\n");
-#endif
-	    return pcibr_dmamap;
-	}
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_dmamap_alloc: unable to use direct64\n");
-#endif
-	flags &= ~PCIIO_DMA_A64;
-    }
-    if (flags & PCIIO_FIXED) {
-	/* warning: mappings may fail later,
-	 * if direct32 can't get to the address.
-	 */
-	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) {
-	    /* User desires DIRECT A32 operations,
-	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
-	     * mappings using shared resources.
-	     * Mapping calls may fail if target
-	     * is outside the direct32 range.
-	     */
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_dmamap_alloc: using direct32\n");
-#endif
-	    pcibr_dmamap->bd_flags = flags;
-	    pcibr_dmamap->bd_xio_addr = pcibr_soft->bs_dir_xbase;
-	    pcibr_dmamap->bd_pci_addr = PCI32_DIRECT_BASE;
-	    return pcibr_dmamap;
-	}
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_dmamap_alloc: unable to use direct32\n");
-#endif
-	/* If the user demands FIXED and we can't
-	 * give it to him, fail.
-	 */
-	xtalk_dmamap_free(xtalk_dmamap);
-#ifdef IRIX
-	DEL(pcibr_dmamap);
-#else
-	free_pciio_dmamap(pcibr_dmamap);
-#endif
-	return 0;
-    }
-    /*
-     * Allocate Address Translation Entries from the mapping RAM.
-     * Unless the PCIBR_NO_ATE_ROUNDUP flag is specified,
-     * the maximum number of ATEs is based on the worst-case
-     * scenario, where the requested target is in the
-     * last byte of an ATE; thus, mapping IOPGSIZE+2
-     * does end up requiring three ATEs.
-     */
-    if (!(flags & PCIBR_NO_ATE_ROUNDUP)) {
-	ate_count = IOPG((IOPGSIZE - 1)	/* worst case start offset */
-		     +req_size_max	/* max mapping bytes */
-		     - 1) + 1;		/* round UP */
-    } else {	/* assume requested target is page aligned */
-	ate_count = IOPG(req_size_max   /* max mapping bytes */
-		     - 1) + 1;		/* round UP */
-    }
-
-    ate_index = pcibr_ate_alloc(pcibr_soft, ate_count);
-
-    if (ate_index != -1) {
-	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_PMU_BITS)) {
-	    bridge_ate_t            ate_proto;
-	    int                     have_rrbs;
-	    int                     min_rrbs;
-
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_dmamap_alloc: using PMU\n");
-#endif
-
-	    ate_proto = pcibr_flags_to_ate(flags);
-
-	    pcibr_dmamap->bd_flags = flags;
-	    pcibr_dmamap->bd_pci_addr =
-		PCI32_MAPPED_BASE + IOPGSIZE * ate_index;
-	    /*
-	     * for xbridge the byte-swap bit == bit 29 of PCI address
-	     */
-	    if (pcibr_soft->bs_xbridge) {
-		    if (flags & PCIIO_BYTE_STREAM)
-			    ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr);
-		    /*
-		     * If swap was set in bss_device in pcibr_endian_set()
-		     * we need to change the address bit.
-		     */
-		    if (pcibr_soft->bs_slot[slot].bss_device & 
-							BRIDGE_DEV_SWAP_PMU)
-			    ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr);
-		    if (flags & PCIIO_WORD_VALUES)
-			    ATE_SWAP_OFF(pcibr_dmamap->bd_pci_addr);
-	    }
-	    pcibr_dmamap->bd_xio_addr = 0;
-	    pcibr_dmamap->bd_ate_ptr = pcibr_ate_addr(pcibr_soft, ate_index);
-	    pcibr_dmamap->bd_ate_index = ate_index;
-	    pcibr_dmamap->bd_ate_count = ate_count;
-	    pcibr_dmamap->bd_ate_proto = ate_proto;
-
-	    /* Make sure we have an RRB (or two).
-	     */
-	    if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) {
-		have_rrbs = pcibr_soft->bs_rrb_valid[slot];
-		if (have_rrbs < 2) {
-		    if (ate_proto & ATE_PREF)
-			min_rrbs = 2;
-		    else
-			min_rrbs = 1;
-		    if (have_rrbs < min_rrbs)
-			do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs);
-		}
-	    }
-	    if (ate_index >= pcibr_soft->bs_int_ate_size && 
-				!pcibr_soft->bs_xbridge) {
-		bridge_t               *bridge = pcibr_soft->bs_base;
-		volatile unsigned      *cmd_regp;
-		unsigned                cmd_reg;
-		unsigned long           s;
-
-		pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_SSRAM;
-
-		s = pcibr_lock(pcibr_soft);
-		cmd_regp = &(bridge->
-			     b_type0_cfg_dev[slot].
-			     l[PCI_CFG_COMMAND / 4]);
-		cmd_reg = *cmd_regp;
-		pcibr_soft->bs_slot[slot].bss_cmd_pointer = cmd_regp;
-		pcibr_soft->bs_slot[slot].bss_cmd_shadow = cmd_reg;
-		pcibr_unlock(pcibr_soft, s);
-	    }
-	    return pcibr_dmamap;
-	}
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_dmamap_alloc: unable to use PMU\n");
-#endif
-	pcibr_ate_free(pcibr_soft, ate_index, ate_count);
-    }
-    /* total failure: sorry, you just can't
-     * get from here to there that way.
-     */
-#if PCIBR_ATE_DEBUG
-    printk("pcibr_dmamap_alloc: complete failure.\n");
-#endif
-    xtalk_dmamap_free(xtalk_dmamap);
-#ifdef IRIX
-    DEL(pcibr_dmamap);
-#else
-    free_pciio_dmamap(pcibr_dmamap);
-#endif
-    return 0;
-}
-
-/*ARGSUSED */
-void
-pcibr_dmamap_free(pcibr_dmamap_t pcibr_dmamap)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-    pciio_slot_t            slot = pcibr_dmamap->bd_slot;
-
-    unsigned                flags = pcibr_dmamap->bd_flags;
-
-    /* Make sure that bss_ext_ates_active
-     * is properly kept up to date.
-     */
-
-    if (PCIBR_DMAMAP_BUSY & flags)
-	if (PCIBR_DMAMAP_SSRAM & flags)
-	    atomic_dec(&(pcibr_soft->bs_slot[slot]. bss_ext_ates_active));
-
-    xtalk_dmamap_free(pcibr_dmamap->bd_xtalk);
-
-    if (pcibr_dmamap->bd_flags & PCIIO_DMA_A64) {
-	pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_D64_BITS);
-    }
-    if (pcibr_dmamap->bd_ate_count) {
-	pcibr_ate_free(pcibr_dmamap->bd_soft,
-		       pcibr_dmamap->bd_ate_index,
-		       pcibr_dmamap->bd_ate_count);
-	pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_PMU_BITS);
-    }
-#ifdef IRIX
-    DEL(pcibr_dmamap);
-#else
-    free_pciio_dmamap(pcibr_dmamap);
-#endif
-}
-
-/*
- * Setup an Address Translation Entry as specified.  Use either the Bridge
- * internal maps or the external map RAM, as appropriate.
- */
-LOCAL bridge_ate_p
-pcibr_ate_addr(pcibr_soft_t pcibr_soft,
-	       int ate_index)
-{
-    bridge_t *bridge = pcibr_soft->bs_base;
-
-    return (ate_index < pcibr_soft->bs_int_ate_size)
-	? &(bridge->b_int_ate_ram[ate_index].wr)
-	: &(bridge->b_ext_ate_ram[ate_index]);
-}
-
-/*
- *    pcibr_addr_xio_to_pci: given a PIO range, hand
- *      back the corresponding base PCI MEM address;
- *      this is used to short-circuit DMA requests that
- *      loop back onto this PCI bus.
- */
-LOCAL iopaddr_t
-pcibr_addr_xio_to_pci(pcibr_soft_t soft,
-		      iopaddr_t xio_addr,
-		      size_t req_size)
-{
-    iopaddr_t               xio_lim = xio_addr + req_size - 1;
-    iopaddr_t               pci_addr;
-    pciio_slot_t            slot;
-
-    if ((xio_addr >= BRIDGE_PCI_MEM32_BASE) &&
-	(xio_lim <= BRIDGE_PCI_MEM32_LIMIT)) {
-	pci_addr = xio_addr - BRIDGE_PCI_MEM32_BASE;
-	return pci_addr;
-    }
-    if ((xio_addr >= BRIDGE_PCI_MEM64_BASE) &&
-	(xio_lim <= BRIDGE_PCI_MEM64_LIMIT)) {
-	pci_addr = xio_addr - BRIDGE_PCI_MEM64_BASE;
-	return pci_addr;
-    }
-    for (slot = 0; slot < 8; ++slot)
-	if ((xio_addr >= BRIDGE_DEVIO(slot)) &&
-	    (xio_lim < BRIDGE_DEVIO(slot + 1))) {
-	    bridgereg_t             dev;
-
-	    dev = soft->bs_slot[slot].bss_device;
-	    pci_addr = dev & BRIDGE_DEV_OFF_MASK;
-	    pci_addr <<= BRIDGE_DEV_OFF_ADDR_SHFT;
-	    pci_addr += xio_addr - BRIDGE_DEVIO(slot);
-	    return (dev & BRIDGE_DEV_DEV_IO_MEM) ? pci_addr : PCI_NOWHERE;
-	}
-    return 0;
-}
-
-/* We are starting to get more complexity
- * surrounding writing ATEs, so pull
- * the writing code into this new function.
- */
-
-#if PCIBR_FREEZE_TIME
-#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, &freeze_time, cmd_regs)
-#else
-#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, cmd_regs)
-#endif
-
-LOCAL unsigned
-ate_freeze(pcibr_dmamap_t pcibr_dmamap,
-#if PCIBR_FREEZE_TIME
-	   unsigned *freeze_time_ptr,
-#endif
-	   unsigned *cmd_regs)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-#ifdef LATER
-    int                     dma_slot = pcibr_dmamap->bd_slot;
-#endif
-    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
-    int                     slot;
-
-    unsigned long           s;
-    unsigned                cmd_reg;
-    volatile unsigned      *cmd_lwa;
-    unsigned                cmd_lwd;
-
-    if (!ext_ates)
-	return 0;
-
-    /* Bridge Hardware Bug WAR #484930:
-     * Bridge can't handle updating External ATEs
-     * while DMA is occuring that uses External ATEs,
-     * even if the particular ATEs involved are disjoint.
-     */
-
-    /* need to prevent anyone else from
-     * unfreezing the grant while we
-     * are working; also need to prevent
-     * this thread from being interrupted
-     * to keep PCI grant freeze time
-     * at an absolute minimum.
-     */
-    s = pcibr_lock(pcibr_soft);
-
-#ifdef LATER
-    /* just in case pcibr_dmamap_done was not called */
-    if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) {
-	pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY;
-	if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM)
-	    atomic_dec(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
-	xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
-    }
-#endif	/* LATER */
-#if PCIBR_FREEZE_TIME
-    *freeze_time_ptr = get_timestamp();
-#endif
-
-    cmd_lwa = 0;
-    for (slot = 0; slot < 8; ++slot)
-	if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
-	    cmd_reg = pcibr_soft->
-		bs_slot[slot].
-		bss_cmd_shadow;
-	    if (cmd_reg & PCI_CMD_BUS_MASTER) {
-		cmd_lwa = pcibr_soft->
-		    bs_slot[slot].
-		    bss_cmd_pointer;
-		cmd_lwd = cmd_reg ^ PCI_CMD_BUS_MASTER;
-		cmd_lwa[0] = cmd_lwd;
-	    }
-	    cmd_regs[slot] = cmd_reg;
-	} else
-	    cmd_regs[slot] = 0;
-
-    if (cmd_lwa) {
-	    bridge_t	*bridge = pcibr_soft->bs_base;
-
-	    /* Read the last master bit that has been cleared. This PIO read
-	     * on the PCI bus is to ensure the completion of any DMAs that
-	     * are due to bus requests issued by PCI devices before the
-	     * clearing of master bits.
-	     */
-	    cmd_lwa[0];
-
-	    /* Flush all the write buffers in the bridge */
-	    for (slot = 0; slot < 8; ++slot)
-		    if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
-			    /* Flush the write buffer associated with this
-			     * PCI device which might be using dma map RAM.
-			     */
-			    bridge->b_wr_req_buf[slot].reg;
-		    }
-    }
-    return s;
-}
-
-#define	ATE_WRITE()    ate_write(ate_ptr, ate_count, ate)
-
-LOCAL void
-ate_write(bridge_ate_p ate_ptr,
-	  int ate_count,
-	  bridge_ate_t ate)
-{
-    while (ate_count-- > 0) {
-	*ate_ptr++ = ate;
-	ate += IOPGSIZE;
-    }
-}
-
-
-#if PCIBR_FREEZE_TIME
-#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, ate, ate_total, freeze_time, cmd_regs, s)
-#else
-#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, cmd_regs, s)
-#endif
-
-LOCAL void
-ate_thaw(pcibr_dmamap_t pcibr_dmamap,
-	 int ate_index,
-#if PCIBR_FREEZE_TIME
-	 bridge_ate_t ate,
-	 int ate_total,
-	 unsigned freeze_time_start,
-#endif
-	 unsigned *cmd_regs,
-	 unsigned s)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-    int                     dma_slot = pcibr_dmamap->bd_slot;
-    int                     slot;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
-
-    unsigned                cmd_reg;
-
-#if PCIBR_FREEZE_TIME
-    unsigned                freeze_time;
-    static unsigned         max_freeze_time = 0;
-    static unsigned         max_ate_total;
-#endif
-
-    if (!ext_ates)
-	return;
-
-    /* restore cmd regs */
-    for (slot = 0; slot < 8; ++slot)
-	if ((cmd_reg = cmd_regs[slot]) & PCI_CMD_BUS_MASTER)
-	    bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg;
-
-    pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY;
-    atomic_inc(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
-
-#if PCIBR_FREEZE_TIME
-    freeze_time = get_timestamp() - freeze_time_start;
-
-    if ((max_freeze_time < freeze_time) ||
-	(max_ate_total < ate_total)) {
-	if (max_freeze_time < freeze_time)
-	    max_freeze_time = freeze_time;
-	if (max_ate_total < ate_total)
-	    max_ate_total = ate_total;
-	pcibr_unlock(pcibr_soft, s);
-	printk("%s: pci freeze time %d usec for %d ATEs\n"
-		"\tfirst ate: %R\n",
-		pcibr_soft->bs_name,
-		freeze_time * 1000 / 1250,
-		ate_total,
-		ate, ate_bits);
-    } else
-#endif
-	pcibr_unlock(pcibr_soft, s);
-}
-
-/*ARGSUSED */
-iopaddr_t
-pcibr_dmamap_addr(pcibr_dmamap_t pcibr_dmamap,
-		  paddr_t paddr,
-		  size_t req_size)
-{
-    pcibr_soft_t            pcibr_soft;
-    iopaddr_t               xio_addr;
-    xwidgetnum_t            xio_port;
-    iopaddr_t               pci_addr;
-    unsigned                flags;
-
-    ASSERT(pcibr_dmamap != NULL);
-    ASSERT(req_size > 0);
-    ASSERT(req_size <= pcibr_dmamap->bd_max_size);
-
-    pcibr_soft = pcibr_dmamap->bd_soft;
-
-    flags = pcibr_dmamap->bd_flags;
-
-    xio_addr = xtalk_dmamap_addr(pcibr_dmamap->bd_xtalk, paddr, req_size);
-    if (XIO_PACKED(xio_addr)) {
-	xio_port = XIO_PORT(xio_addr);
-	xio_addr = XIO_ADDR(xio_addr);
-    } else
-	xio_port = pcibr_dmamap->bd_xio_port;
-
-    /* If this DMA is to an address that
-     * refers back to this Bridge chip,
-     * reduce it back to the correct
-     * PCI MEM address.
-     */
-    if (xio_port == pcibr_soft->bs_xid) {
-	pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size);
-    } else if (flags & PCIIO_DMA_A64) {
-	/* A64 DMA:
-	 * always use 64-bit direct mapping,
-	 * which always works.
-	 * Device(x) was set up during
-	 * dmamap allocation.
-	 */
-
-	/* attributes are already bundled up into bd_pci_addr.
-	 */
-	pci_addr = pcibr_dmamap->bd_pci_addr
-	    | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT)
-	    | xio_addr;
-
-	/* Bridge Hardware WAR #482836:
-	 * If the transfer is not cache aligned
-	 * and the Bridge Rev is <= B, force
-	 * prefetch to be off.
-	 */
-	if (flags & PCIBR_NOPREFETCH)
-	    pci_addr &= ~PCI64_ATTR_PREF;
-
-#if DEBUG && PCIBR_DMA_DEBUG
-	printk("pcibr_dmamap_addr (direct64):\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\tXIO port 0x%x offset 0x%x\n"
-		"\treturning PCI 0x%x\n",
-		paddr, paddr + req_size - 1,
-		xio_port, xio_addr, pci_addr);
-#endif
-    } else if (flags & PCIIO_FIXED) {
-	/* A32 direct DMA:
-	 * always use 32-bit direct mapping,
-	 * which may fail.
-	 * Device(x) was set up during
-	 * dmamap allocation.
-	 */
-
-	if (xio_port != pcibr_soft->bs_dir_xport)
-	    pci_addr = 0;		/* wrong DIDN */
-	else if (xio_addr < pcibr_dmamap->bd_xio_addr)
-	    pci_addr = 0;		/* out of range */
-	else if ((xio_addr + req_size) >
-		 (pcibr_dmamap->bd_xio_addr + BRIDGE_DMA_DIRECT_SIZE))
-	    pci_addr = 0;		/* out of range */
-	else
-	    pci_addr = pcibr_dmamap->bd_pci_addr +
-		xio_addr - pcibr_dmamap->bd_xio_addr;
-
-#if DEBUG && PCIBR_DMA_DEBUG
-	printk("pcibr_dmamap_addr (direct32):\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\tXIO port 0x%x offset 0x%x\n"
-		"\treturning PCI 0x%x\n",
-		paddr, paddr + req_size - 1,
-		xio_port, xio_addr, pci_addr);
-#endif
-    } else {
-	bridge_t               *bridge = pcibr_soft->bs_base;
-	iopaddr_t               offset = IOPGOFF(xio_addr);
-	bridge_ate_t            ate_proto = pcibr_dmamap->bd_ate_proto;
-	int                     ate_count = IOPG(offset + req_size - 1) + 1;
-
-	int                     ate_index = pcibr_dmamap->bd_ate_index;
-	unsigned                cmd_regs[8];
-	unsigned                s;
-
-#if PCIBR_FREEZE_TIME
-	int                     ate_total = ate_count;
-	unsigned                freeze_time;
-#endif
-
-#if PCIBR_ATE_DEBUG
-	bridge_ate_t            ate_cmp;
-	bridge_ate_p            ate_cptr;
-	unsigned                ate_lo, ate_hi;
-	int                     ate_bad = 0;
-	int                     ate_rbc = 0;
-#endif
-	bridge_ate_p            ate_ptr = pcibr_dmamap->bd_ate_ptr;
-	bridge_ate_t            ate;
-
-	/* Bridge Hardware WAR #482836:
-	 * If the transfer is not cache aligned
-	 * and the Bridge Rev is <= B, force
-	 * prefetch to be off.
-	 */
-	if (flags & PCIBR_NOPREFETCH)
-	    ate_proto &= ~ATE_PREF;
-
-	ate = ate_proto
-	    | (xio_port << ATE_TIDSHIFT)
-	    | (xio_addr - offset);
-
-	pci_addr = pcibr_dmamap->bd_pci_addr + offset;
-
-	/* Fill in our mapping registers
-	 * with the appropriate xtalk data,
-	 * and hand back the PCI address.
-	 */
-
-	ASSERT(ate_count > 0);
-	if (ate_count <= pcibr_dmamap->bd_ate_count) {
-		ATE_FREEZE();
-		ATE_WRITE();
-		ATE_THAW();
-		bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-	} else {
-		/* The number of ATE's required is greater than the number
-		 * allocated for this map. One way this can happen is if
-		 * pcibr_dmamap_alloc() was called with the PCIBR_NO_ATE_ROUNDUP
-		 * flag, and then when that map is used (right now), the
-		 * target address tells us we really did need to roundup.
-		 * The other possibility is that the map is just plain too
-		 * small to handle the requested target area.
-		 */
-#if PCIBR_ATE_DEBUG
-		printk(KERN_WARNING   "pcibr_dmamap_addr :\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\tate_count 0x%x bd_ate_count 0x%x\n"
-			"\tATE's required > number allocated\n",
-			paddr, paddr + req_size - 1,
-			ate_count, pcibr_dmamap->bd_ate_count);
-#endif
-		pci_addr = 0;
-	}
-
-    }
-    return pci_addr;
-}
-
-/*ARGSUSED */
-alenlist_t
-pcibr_dmamap_list(pcibr_dmamap_t pcibr_dmamap,
-		  alenlist_t palenlist,
-		  unsigned flags)
-{
-    pcibr_soft_t            pcibr_soft;
-    bridge_t               *bridge=NULL;
-
-    unsigned                al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-    int                     inplace = flags & PCIIO_INPLACE;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist;
-    size_t                  length;
-    iopaddr_t               offset;
-    unsigned                direct64;
-    int                     ate_index = 0;
-    int                     ate_count = 0;
-    int                     ate_total = 0;
-    bridge_ate_p            ate_ptr = (bridge_ate_p)0;
-    bridge_ate_t            ate_proto = (bridge_ate_t)0;
-    bridge_ate_t            ate_prev;
-    bridge_ate_t            ate;
-    alenaddr_t              xio_addr;
-    xwidgetnum_t            xio_port;
-    iopaddr_t               pci_addr;
-    alenaddr_t              new_addr;
-
-    unsigned                cmd_regs[8];
-    unsigned                s = 0;
-
-#if PCIBR_FREEZE_TIME
-    unsigned                freeze_time;
-#endif
-    int			    ate_freeze_done = 0;	/* To pair ATE_THAW
-							 * with an ATE_FREEZE
-							 */
-
-    pcibr_soft = pcibr_dmamap->bd_soft;
-
-    xtalk_alenlist = xtalk_dmamap_list(pcibr_dmamap->bd_xtalk, palenlist,
-				       flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist)
-	goto fail;
-
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist)
-	    goto fail;
-    }
-
-    direct64 = pcibr_dmamap->bd_flags & PCIIO_DMA_A64;
-    if (!direct64) {
-	bridge = pcibr_soft->bs_base;
-	ate_ptr = pcibr_dmamap->bd_ate_ptr;
-	ate_index = pcibr_dmamap->bd_ate_index;
-	ate_proto = pcibr_dmamap->bd_ate_proto;
-	ATE_FREEZE();
-	ate_freeze_done = 1;	/* Remember that we need to do an ATE_THAW */
-    }
-    pci_addr = pcibr_dmamap->bd_pci_addr;
-
-    ate_prev = 0;			/* matches no valid ATEs */
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &length, al_flags)) {
-	if (XIO_PACKED(xio_addr)) {
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_dmamap->bd_xio_port;
-
-	if (xio_port == pcibr_soft->bs_xid) {
-	    new_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, length);
-	    if (new_addr == PCI_NOWHERE)
-		goto fail;
-	} else if (direct64) {
-	    new_addr = pci_addr | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-	    /* Bridge Hardware WAR #482836:
-	     * If the transfer is not cache aligned
-	     * and the Bridge Rev is <= B, force
-	     * prefetch to be off.
-	     */
-	    if (flags & PCIBR_NOPREFETCH)
-		new_addr &= ~PCI64_ATTR_PREF;
-
-	} else {
-	    /* calculate the ate value for
-	     * the first address. If it
-	     * matches the previous
-	     * ATE written (ie. we had
-	     * multiple blocks in the
-	     * same IOPG), then back up
-	     * and reuse that ATE.
-	     *
-	     * We are NOT going to
-	     * aggressively try to
-	     * reuse any other ATEs.
-	     */
-	    offset = IOPGOFF(xio_addr);
-	    ate = ate_proto
-		| (xio_port << ATE_TIDSHIFT)
-		| (xio_addr - offset);
-	    if (ate == ate_prev) {
-#if PCIBR_ATE_DEBUG
-		printk("pcibr_dmamap_list: ATE share\n");
-#endif
-		ate_ptr--;
-		ate_index--;
-		pci_addr -= IOPGSIZE;
-	    }
-	    new_addr = pci_addr + offset;
-
-	    /* Fill in the hardware ATEs
-	     * that contain this block.
-	     */
-	    ate_count = IOPG(offset + length - 1) + 1;
-	    ate_total += ate_count;
-
-	    /* Ensure that this map contains enough ATE's */
-	    if (ate_total > pcibr_dmamap->bd_ate_count) {
-#if PCIBR_ATE_DEBUG
-		printk(KERN_WARNING   "pcibr_dmamap_list :\n"
-			"\twanted xio_addr [0x%x..0x%x]\n"
-			"\tate_total 0x%x bd_ate_count 0x%x\n"
-			"\tATE's required > number allocated\n",
-			xio_addr, xio_addr + length - 1,
-			ate_total, pcibr_dmamap->bd_ate_count);
-#endif
-		goto fail;
-	    }
-
-	    ATE_WRITE();
-
-	    ate_index += ate_count;
-	    ate_ptr += ate_count;
-
-	    ate_count <<= IOPFNSHIFT;
-	    ate += ate_count;
-	    pci_addr += ate_count;
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &new_addr, &length, al_flags))
-		goto fail;
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				new_addr, length, al_flags))
-		goto fail;
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-
-
-    /* In case an ATE_FREEZE was done do the ATE_THAW to unroll all the
-     * changes that ATE_FREEZE has done to implement the external SSRAM
-     * bug workaround.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    return pciio_alenlist;
-
-  fail:
-    /* There are various points of failure after doing an ATE_FREEZE
-     * We need to do an ATE_THAW. Otherwise the ATEs are locked forever.
-     * The decision to do an ATE_THAW needs to be based on whether a
-     * an ATE_FREEZE was done before.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	bridge->b_wid_tflush;
-    }
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
-/*ARGSUSED */
-void
-pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap)
-{
-    /*
-     * We could go through and invalidate ATEs here;
-     * for performance reasons, we don't.
-     * We also don't enforce the strict alternation
-     * between _addr/_list and _done, but Hub does.
-     */
-
-    if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) {
-	pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY;
-
-	if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM)
-	    atomic_dec(&(pcibr_dmamap->bd_soft->bs_slot[pcibr_dmamap->bd_slot]. bss_ext_ates_active));
-    }
-
-    xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
-}
-
-
-/*
- * For each bridge, the DIR_OFF value in the Direct Mapping Register
- * determines the PCI to Crosstalk memory mapping to be used for all
- * 32-bit Direct Mapping memory accesses. This mapping can be to any
- * node in the system. This function will return that compact node id.
- */
-
-/*ARGSUSED */
-cnodeid_t
-pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl)
-{
-
-	pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
-	pcibr_soft_t	pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-	return(NASID_TO_COMPACT_NODEID(NASID_GET(pcibr_soft->bs_dir_xbase)));
-}
-
-/*ARGSUSED */
-iopaddr_t
-pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    paddr_t paddr,
-		    size_t req_size,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
-
-    xwidgetnum_t            xio_port;
-    iopaddr_t               xio_addr;
-    iopaddr_t               pci_addr;
-
-    int                     have_rrbs;
-    int                     min_rrbs;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-    xio_addr = xtalk_dmatrans_addr(xconn_vhdl, 0, paddr, req_size,
-				   flags & DMAMAP_FLAGS);
-
-    if (!xio_addr) {
-#if PCIBR_DMA_DEBUG
-	printk("pcibr_dmatrans_addr:\n"
-		"\tpciio connection point %v\n"
-		"\txtalk connection point %v\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\txtalk_dmatrans_addr returned 0x%x\n",
-		pconn_vhdl, xconn_vhdl,
-		paddr, paddr + req_size - 1,
-		xio_addr);
-#endif
-	return 0;
-    }
-    /*
-     * find which XIO port this goes to.
-     */
-    if (XIO_PACKED(xio_addr)) {
-	if (xio_addr == XIO_NOWHERE) {
-#if PCIBR_DMA_DEBUG
-	    printk("pcibr_dmatrans_addr:\n"
-		    "\tpciio connection point %v\n"
-		    "\txtalk connection point %v\n"
-		    "\twanted paddr [0x%x..0x%x]\n"
-		    "\txtalk_dmatrans_addr returned 0x%x\n",
-		    pconn_vhdl, xconn_vhdl,
-		    paddr, paddr + req_size - 1,
-		    xio_addr);
-#endif
-	    return 0;
-	}
-	xio_port = XIO_PORT(xio_addr);
-	xio_addr = XIO_ADDR(xio_addr);
-
-    } else
-	xio_port = pcibr_soft->bs_mxid;
-
-    /*
-     * If this DMA comes back to us,
-     * return the PCI MEM address on
-     * which it would land, or NULL
-     * if the target is something
-     * on bridge other than PCI MEM.
-     */
-    if (xio_port == pcibr_soft->bs_xid) {
-	pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size);
-	return pci_addr;
-    }
-    /* If the caller can use A64, try to
-     * satisfy the request with the 64-bit
-     * direct map. This can fail if the
-     * configuration bits in Device(x)
-     * conflict with our flags.
-     */
-
-    if (flags & PCIIO_DMA_A64) {
-	pci_addr = slotp->bss_d64_base;
-	if (!(flags & PCIBR_VCHAN1))
-	    flags |= PCIBR_VCHAN0;
-	if ((pci_addr != PCIBR_D64_BASE_UNSET) &&
-	    (flags == slotp->bss_d64_flags)) {
-
-	    pci_addr |= xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-#if DEBUG && PCIBR_DMA_DEBUG
-#if HWG_PERF_CHECK
-	    if (xio_addr != 0x20000000)
-#endif
-		printk("pcibr_dmatrans_addr: [reuse]\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n"
-			"\tdirect 64bit address is 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr, pci_addr);
-#endif
-	    return (pci_addr);
-	}
-	if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS)) {
-	    pci_addr = pcibr_flags_to_d64(flags, pcibr_soft);
-	    slotp->bss_d64_flags = flags;
-	    slotp->bss_d64_base = pci_addr;
-	    pci_addr |= xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-	    /* Make sure we have an RRB (or two).
-	     */
-	    if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) {
-		if (flags & PCIBR_VCHAN1)
-		    pciio_slot += PCIBR_RRB_SLOT_VIRTUAL;
-		have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot];
-		if (have_rrbs < 2) {
-		    if (pci_addr & PCI64_ATTR_PREF)
-			min_rrbs = 2;
-		    else
-			min_rrbs = 1;
-		    if (have_rrbs < min_rrbs)
-			do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs);
-		}
-	    }
-#if PCIBR_DMA_DEBUG
-#if HWG_PERF_CHECK
-	    if (xio_addr != 0x20000000)
-#endif
-		printk("pcibr_dmatrans_addr:\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n"
-			"\tdirect 64bit address is 0x%x\n"
-			"\tnew flags: 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr, pci_addr, (uint64_t) flags);
-#endif
-	    return (pci_addr);
-	}
-	/* our flags conflict with Device(x).
-	 */
-	flags = flags
-	    & ~PCIIO_DMA_A64
-	    & ~PCIBR_VCHAN0
-	    ;
-
-#if PCIBR_DMA_DEBUG
-	printk("pcibr_dmatrans_addr:\n"
-		"\tpciio connection point %v\n"
-		"\txtalk connection point %v\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\txtalk_dmatrans_addr returned 0x%x\n"
-		"\tUnable to set Device(x) bits for Direct-64\n",
-		pconn_vhdl, xconn_vhdl,
-		paddr, paddr + req_size - 1,
-		xio_addr);
-#endif
-    }
-    /* Try to satisfy the request with the 32-bit direct
-     * map. This can fail if the configuration bits in
-     * Device(x) conflict with our flags, or if the
-     * target address is outside where DIR_OFF points.
-     */
-    {
-	size_t                  map_size = 1ULL << 31;
-	iopaddr_t               xio_base = pcibr_soft->bs_dir_xbase;
-	iopaddr_t               offset = xio_addr - xio_base;
-	iopaddr_t               endoff = req_size + offset;
-
-	if ((req_size > map_size) ||
-	    (xio_addr < xio_base) ||
-	    (xio_port != pcibr_soft->bs_dir_xport) ||
-	    (endoff > map_size)) {
-#if PCIBR_DMA_DEBUG
-	    printk("pcibr_dmatrans_addr:\n"
-		    "\tpciio connection point %v\n"
-		    "\txtalk connection point %v\n"
-		    "\twanted paddr [0x%x..0x%x]\n"
-		    "\txtalk_dmatrans_addr returned 0x%x\n"
-		    "\txio region outside direct32 target\n",
-		    pconn_vhdl, xconn_vhdl,
-		    paddr, paddr + req_size - 1,
-		    xio_addr);
-#endif
-	} else {
-	    pci_addr = slotp->bss_d32_base;
-	    if ((pci_addr != PCIBR_D32_BASE_UNSET) &&
-		(flags == slotp->bss_d32_flags)) {
-
-		pci_addr |= offset;
-
-#if DEBUG && PCIBR_DMA_DEBUG
-		printk("pcibr_dmatrans_addr: [reuse]\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n"
-			"\tmapped via direct32 offset 0x%x\n"
-			"\twill DMA via pci addr 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr, offset, pci_addr);
-#endif
-		return (pci_addr);
-	    }
-	    if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS)) {
-
-		pci_addr = PCI32_DIRECT_BASE;
-		slotp->bss_d32_flags = flags;
-		slotp->bss_d32_base = pci_addr;
-		pci_addr |= offset;
-
-		/* Make sure we have an RRB (or two).
-		 */
-		if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) {
-		    have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot];
-		    if (have_rrbs < 2) {
-			if (slotp->bss_device & BRIDGE_DEV_PREF)
-			    min_rrbs = 2;
-			else
-			    min_rrbs = 1;
-			if (have_rrbs < min_rrbs)
-			    do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs);
-		    }
-		}
-#if PCIBR_DMA_DEBUG
-#if HWG_PERF_CHECK
-		if (xio_addr != 0x20000000)
-#endif
-		    printk("pcibr_dmatrans_addr:\n"
-			    "\tpciio connection point %v\n"
-			    "\txtalk connection point %v\n"
-			    "\twanted paddr [0x%x..0x%x]\n"
-			    "\txtalk_dmatrans_addr returned 0x%x\n"
-			    "\tmapped via direct32 offset 0x%x\n"
-			    "\twill DMA via pci addr 0x%x\n"
-			    "\tnew flags: 0x%x\n",
-			    pconn_vhdl, xconn_vhdl,
-			    paddr, paddr + req_size - 1,
-			    xio_addr, offset, pci_addr, (uint64_t) flags);
-#endif
-		return (pci_addr);
-	    }
-	    /* our flags conflict with Device(x).
-	     */
-#if PCIBR_DMA_DEBUG
-	    printk("pcibr_dmatrans_addr:\n"
-		    "\tpciio connection point %v\n"
-		    "\txtalk connection point %v\n"
-		    "\twanted paddr [0x%x..0x%x]\n"
-		    "\txtalk_dmatrans_addr returned 0x%x\n"
-		    "\tUnable to set Device(x) bits for Direct-32\n",
-		    pconn_vhdl, xconn_vhdl,
-		    paddr, paddr + req_size - 1,
-		    xio_addr);
-#endif
-	}
-    }
-
-#if PCIBR_DMA_DEBUG
-    printk("pcibr_dmatrans_addr:\n"
-	    "\tpciio connection point %v\n"
-	    "\txtalk connection point %v\n"
-	    "\twanted paddr [0x%x..0x%x]\n"
-	    "\txtalk_dmatrans_addr returned 0x%x\n"
-	    "\tno acceptable PCI address found or constructable\n",
-	    pconn_vhdl, xconn_vhdl,
-	    paddr, paddr + req_size - 1,
-	    xio_addr);
-#endif
-
-    return 0;
-}
-
-/*ARGSUSED */
-alenlist_t
-pcibr_dmatrans_list(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    alenlist_t palenlist,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
-    xwidgetnum_t            xio_port;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist = 0;
-
-    int                     inplace;
-    unsigned                direct64;
-    unsigned                al_flags;
-
-    iopaddr_t               xio_base;
-    alenaddr_t              xio_addr;
-    size_t                  xio_size;
-
-    size_t                  map_size;
-    iopaddr_t               pci_base;
-    alenaddr_t              pci_addr;
-
-    unsigned                relbits = 0;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-    inplace = flags & PCIIO_INPLACE;
-    direct64 = flags & PCIIO_DMA_A64;
-    al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-
-    if (direct64) {
-	map_size = 1ull << 48;
-	xio_base = 0;
-	pci_base = slotp->bss_d64_base;
-	if ((pci_base != PCIBR_D64_BASE_UNSET) &&
-	    (flags == slotp->bss_d64_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D64_BITS;
-	    pci_base =
-		pcibr_flags_to_d64(flags, pcibr_soft);
-	}
-    } else {
-	xio_base = pcibr_soft->bs_dir_xbase;
-	map_size = 1ull << 31;
-	pci_base = slotp->bss_d32_base;
-	if ((pci_base != PCIBR_D32_BASE_UNSET) &&
-	    (flags == slotp->bss_d32_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D32_BITS;
-	    pci_base = PCI32_DIRECT_BASE;
-	}
-    }
-
-    xtalk_alenlist = xtalk_dmatrans_list(xconn_vhdl, 0, palenlist,
-					 flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist)
-	goto fail;
-
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist)
-	    goto fail;
-    }
-
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &xio_size, al_flags)) {
-
-	/*
-	 * find which XIO port this goes to.
-	 */
-	if (XIO_PACKED(xio_addr)) {
-	    if (xio_addr == XIO_NOWHERE) {
-#if PCIBR_DMA_DEBUG
-		printk("pcibr_dmatrans_addr:\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr);
-#endif
-		return 0;
-	    }
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_soft->bs_mxid;
-
-	/*
-	 * If this DMA comes back to us,
-	 * return the PCI MEM address on
-	 * which it would land, or NULL
-	 * if the target is something
-	 * on bridge other than PCI MEM.
-	 */
-	if (xio_port == pcibr_soft->bs_xid) {
-	    pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size);
-	    if ( (pci_addr == (alenaddr_t)NULL) )
-		goto fail;
-	} else if (direct64) {
-	    ASSERT(xio_port != 0);
-	    pci_addr = pci_base | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-	} else {
-	    iopaddr_t               offset = xio_addr - xio_base;
-	    iopaddr_t               endoff = xio_size + offset;
-
-	    if ((xio_size > map_size) ||
-		(xio_addr < xio_base) ||
-		(xio_port != pcibr_soft->bs_dir_xport) ||
-		(endoff > map_size))
-		goto fail;
-
-	    pci_addr = pci_base + (xio_addr - xio_base);
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &pci_addr, &xio_size, al_flags))
-		goto fail;
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				pci_addr, xio_size, al_flags))
-		goto fail;
-	}
-    }
-
-    if (relbits) {
-	if (direct64) {
-	    slotp->bss_d64_flags = flags;
-	    slotp->bss_d64_base = pci_base;
-	} else {
-	    slotp->bss_d32_flags = flags;
-	    slotp->bss_d32_base = pci_base;
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-    return pciio_alenlist;
-
-  fail:
-    if (relbits)
-	pcibr_release_device(pcibr_soft, pciio_slot, relbits);
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
-void
-pcibr_dmamap_drain(pcibr_dmamap_t map)
-{
-    xtalk_dmamap_drain(map->bd_xtalk);
-}
-
-void
-pcibr_dmaaddr_drain(devfs_handle_t pconn_vhdl,
-		    paddr_t paddr,
-		    size_t bytes)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes);
-}
-
-void
-pcibr_dmalist_drain(devfs_handle_t pconn_vhdl,
-		    alenlist_t list)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    xtalk_dmalist_drain(xconn_vhdl, list);
-}
-
-/*
- * Get the starting PCIbus address out of the given DMA map.
- * This function is supposed to be used by a close friend of PCI bridge
- * since it relies on the fact that the starting address of the map is fixed at
- * the allocation time in the current implementation of PCI bridge.
- */
-iopaddr_t
-pcibr_dmamap_pciaddr_get(pcibr_dmamap_t pcibr_dmamap)
-{
-    return (pcibr_dmamap->bd_pci_addr);
-}
-
-/*
- *	There are end cases where a deadlock can occur if interrupt 
- *	processing completes and the Bridge b_int_status bit is still set.
- *
- *	One scenerio is if a second PCI interrupt occurs within 60ns of
- *	the previous interrupt being cleared. In this case the Bridge
- *	does not detect the transition, the Bridge b_int_status bit
- *	remains set, and because no transition was detected no interrupt
- *	packet is sent to the Hub/Heart.
- *
- *	A second scenerio is possible when a b_int_status bit is being
- *	shared by multiple devices:
- *						Device #1 generates interrupt
- *						Bridge b_int_status bit set
- *						Device #2 generates interrupt
- *		interrupt processing begins
- *		  ISR for device #1 runs and
- *			clears interrupt
- *						Device #1 generates interrupt
- *		  ISR for device #2 runs and
- *			clears interrupt
- *						(b_int_status bit still set)
- *		interrupt processing completes
- *		  
- *	Interrupt processing is now complete, but an interrupt is still
- *	outstanding for Device #1. But because there was no transition of
- *	the b_int_status bit, no interrupt packet will be generated and
- *	a deadlock will occur.
- *
- *	To avoid these deadlock situations, this function is used
- *	to check if a specific Bridge b_int_status bit is set, and if so,
- *	cause the setting of the corresponding interrupt bit.
- *
- *	On a XBridge (IP35), we do this by writing the appropriate Bridge Force 
- *	Interrupt register.
- */
-void
-pcibr_force_interrupt(pcibr_intr_wrap_t wrap)
-{
-	unsigned	bit;
-	pcibr_soft_t    pcibr_soft = wrap->iw_soft;
-	bridge_t       *bridge = pcibr_soft->bs_base;
-	cpuid_t cpuvertex_to_cpuid(devfs_handle_t vhdl);
-
-	bit = wrap->iw_intr;
-
-	if (pcibr_soft->bs_xbridge) {
-	    bridge->b_force_pin[bit].intr = 1;
-	} else if ((1 << bit) & *wrap->iw_stat) {
-	    cpuid_t	    cpu;
-	    unsigned        intr_bit;
-	    xtalk_intr_t    xtalk_intr =
-				pcibr_soft->bs_intr[bit].bsi_xtalk_intr;
-
-	    intr_bit = (short) xtalk_intr_vector_get(xtalk_intr);
-	    cpu = cpuvertex_to_cpuid(xtalk_intr_cpu_get(xtalk_intr));
-	    REMOTE_CPU_SEND_INTR(cpu, intr_bit);
-	}
-}
-
-/* =====================================================================
- *    INTERRUPT MANAGEMENT
- */
-
-static unsigned
-pcibr_intr_bits(pciio_info_t info,
-		pciio_intr_line_t lines)
-{
-    pciio_slot_t            slot = pciio_info_slot_get(info);
-    unsigned		    bbits = 0;
-
-    /*
-     * Currently favored mapping from PCI
-     * slot number and INTA/B/C/D to Bridge
-     * PCI Interrupt Bit Number:
-     *
-     *     SLOT     A B C D
-     *      0       0 4 0 4
-     *      1       1 5 1 5
-     *      2       2 6 2 6
-     *      3       3 7 3 7
-     *      4       4 0 4 0
-     *      5       5 1 5 1
-     *      6       6 2 6 2
-     *      7       7 3 7 3
-     */
-
-    if (slot < 8) {
-	if (lines & (PCIIO_INTR_LINE_A| PCIIO_INTR_LINE_C))
-	    bbits |= 1 << slot;
-	if (lines & (PCIIO_INTR_LINE_B| PCIIO_INTR_LINE_D))
-	    bbits |= 1 << (slot ^ 4);
-    }
-    return bbits;
-}
-
-
-/*ARGSUSED */
-pcibr_intr_t
-pcibr_intr_alloc(devfs_handle_t pconn_vhdl,
-		 device_desc_t dev_desc,
-		 pciio_intr_line_t lines,
-		 devfs_handle_t owner_dev)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pcibr_info->f_slot;
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     is_threaded = 0;
-    int                     thread_swlevel;
-
-    xtalk_intr_t           *xtalk_intr_p;
-    pcibr_intr_t           *pcibr_intr_p;
-    pcibr_intr_list_t      *intr_list_p;
-
-    unsigned                pcibr_int_bits;
-    unsigned                pcibr_int_bit;
-    xtalk_intr_t            xtalk_intr = (xtalk_intr_t)0;
-    hub_intr_t		    hub_intr;
-    pcibr_intr_t            pcibr_intr;
-    pcibr_intr_list_t       intr_entry;
-    pcibr_intr_list_t       intr_list;
-    bridgereg_t             int_dev;
-
-#if DEBUG && INTR_DEBUG
-    printk("%v: pcibr_intr_alloc\n"
-	    "%v:%s%s%s%s%s\n",
-	    owner_dev, pconn_vhdl,
-	    !(lines & 15) ? " No INTs?" : "",
-	    lines & 1 ? " INTA" : "",
-	    lines & 2 ? " INTB" : "",
-	    lines & 4 ? " INTC" : "",
-	    lines & 8 ? " INTD" : "");
-#endif
-
-    NEW(pcibr_intr);
-    if (!pcibr_intr)
-	return NULL;
-
-    if (dev_desc) {
-	cpuid_t intr_target_from_desc(device_desc_t, int);
-    } else {
-	extern int default_intr_pri;
-
-	is_threaded = 1; /* PCI interrupts are threaded, by default */
-	thread_swlevel = default_intr_pri;
-    }
-
-    pcibr_intr->bi_dev = pconn_vhdl;
-    pcibr_intr->bi_lines = lines;
-    pcibr_intr->bi_soft = pcibr_soft;
-    pcibr_intr->bi_ibits = 0;		/* bits will be added below */
-    pcibr_intr->bi_flags = is_threaded ? 0 : PCIIO_INTR_NOTHREAD;
-    pcibr_intr->bi_mustruncpu = CPU_NONE;
-    mutex_spinlock_init(&pcibr_intr->bi_ibuf.ib_lock);
-
-    pcibr_int_bits = pcibr_soft->bs_intr_bits((pciio_info_t)pcibr_info, lines);
-
-
-    /*
-     * For each PCI interrupt line requested, figure
-     * out which Bridge PCI Interrupt Line it maps
-     * to, and make sure there are xtalk resources
-     * allocated for it.
-     */
-#if DEBUG && INTR_DEBUG
-    printk("pcibr_int_bits: 0x%X\n", pcibr_int_bits);
-#endif 
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit ++) {
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    xtalk_intr_p = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
-
-	    xtalk_intr = *xtalk_intr_p;
-
-	    if (xtalk_intr == NULL) {
-		/*
-		 * This xtalk_intr_alloc is constrained for two reasons:
-		 * 1) Normal interrupts and error interrupts need to be delivered
-		 *    through a single xtalk target widget so that there aren't any
-		 *    ordering problems with DMA, completion interrupts, and error
-		 *    interrupts. (Use of xconn_vhdl forces this.)
-		 *
-		 * 2) On IP35, addressing constraints on IP35 and Bridge force
-		 *    us to use a single PI number for all interrupts from a
-		 *    single Bridge. (IP35-specific code forces this, and we
-		 *    verify in pcibr_setwidint.)
-		 */
-
-		/*
-		 * All code dealing with threaded PCI interrupt handlers
-		 * is located at the pcibr level. Because of this,
-		 * we always want the lower layers (hub/heart_intr_alloc, 
-		 * intr_level_connect) to treat us as non-threaded so we
-		 * don't set up a duplicate threaded environment. We make
-		 * this happen by calling a special xtalk interface.
-		 */
-		xtalk_intr = xtalk_intr_alloc_nothd(xconn_vhdl, dev_desc, 
-			owner_dev);
-#if DEBUG && INTR_DEBUG
-		printk("%v: xtalk_intr=0x%X\n", xconn_vhdl, xtalk_intr);
-#endif
-
-		/* both an assert and a runtime check on this:
-		 * we need to check in non-DEBUG kernels, and
-		 * the ASSERT gets us more information when
-		 * we use DEBUG kernels.
-		 */
-		ASSERT(xtalk_intr != NULL);
-		if (xtalk_intr == NULL) {
-		    /* it is quite possible that our
-		     * xtalk_intr_alloc failed because
-		     * someone else got there first,
-		     * and we can find their results
-		     * in xtalk_intr_p.
-		     */
-		    if (!*xtalk_intr_p) {
-#ifdef SUPPORT_PRINTING_V_FORMAT
-			printk(KERN_ALERT  
-				"pcibr_intr_alloc %v: unable to get xtalk interrupt resources",
-				xconn_vhdl);
-#else
-			printk(KERN_ALERT  
-				"pcibr_intr_alloc 0x%p: unable to get xtalk interrupt resources",
-				(void *)xconn_vhdl);
-#endif
-			/* yes, we leak resources here. */
-			return 0;
-		    }
-		} else if (compare_and_swap_ptr((void **) xtalk_intr_p, NULL, xtalk_intr)) {
-		    /*
-		     * now tell the bridge which slot is
-		     * using this interrupt line.
-		     */
-		    int_dev = bridge->b_int_device;
-		    int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit);
-		    int_dev |= pciio_slot << BRIDGE_INT_DEV_SHFT(pcibr_int_bit);
-		    bridge->b_int_device = int_dev;	/* XXXMP */
-
-#if DEBUG && INTR_DEBUG
-		    printk("%v: bridge intr bit %d clears my wrb\n",
-			    pconn_vhdl, pcibr_int_bit);
-#endif
-		} else {
-		    /* someone else got one allocated first;
-		     * free the one we just created, and
-		     * retrieve the one they allocated.
-		     */
-		    xtalk_intr_free(xtalk_intr);
-		    xtalk_intr = *xtalk_intr_p;
-#if PARANOID
-		    /* once xtalk_intr is set, we never clear it,
-		     * so if the CAS fails above, this condition
-		     * can "never happen" ...
-		     */
-		    if (!xtalk_intr) {
-			printk(KERN_ALERT  
-				"pcibr_intr_alloc %v: unable to set xtalk interrupt resources",
-				xconn_vhdl);
-			/* yes, we leak resources here. */
-			return 0;
-		    }
-#endif
-		}
-	    }
-
-	    pcibr_intr->bi_ibits |= 1 << pcibr_int_bit;
-
-	    NEW(intr_entry);
-	    intr_entry->il_next = NULL;
-	    intr_entry->il_intr = pcibr_intr;
-	    intr_entry->il_wrbf = &(bridge->b_wr_req_buf[pciio_slot].reg);
-	    intr_list_p = 
-		&pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list;
-#if DEBUG && INTR_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	    printk("0x%x: Bridge bit %d wrap=0x%x\n",
-		pconn_vhdl, pcibr_int_bit,
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap);
-#else
-	    printk("%v: Bridge bit %d wrap=0x%x\n",
-		pconn_vhdl, pcibr_int_bit,
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap);
-#endif
-#endif
-
-	    if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
-		/* we are the first interrupt on this bridge bit.
-		 */
-#if DEBUG && INTR_DEBUG
-		printk("%v INT 0x%x (bridge bit %d) allocated [FIRST]\n",
-			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		continue;
-	    }
-	    intr_list = *intr_list_p;
-	    pcibr_intr_p = &intr_list->il_intr;
-	    if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) {
-		/* first entry on list was erased,
-		 * and we replaced it, so we
-		 * don't need our intr_entry.
-		 */
-		DEL(intr_entry);
-#if DEBUG && INTR_DEBUG
-		printk("%v INT 0x%x (bridge bit %d) replaces erased first\n",
-			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		continue;
-	    }
-	    intr_list_p = &intr_list->il_next;
-	    if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
-		/* we are the new second interrupt on this bit.
-		 */
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared = 1;
-#if DEBUG && INTR_DEBUG
-		printk("%v INT 0x%x (bridge bit %d) is new SECOND\n",
-			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		continue;
-	    }
-	    while (1) {
-		pcibr_intr_p = &intr_list->il_intr;
-		if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) {
-		    /* an entry on list was erased,
-		     * and we replaced it, so we
-		     * don't need our intr_entry.
-		     */
-		    DEL(intr_entry);
-#if DEBUG && INTR_DEBUG
-		    printk("%v INT 0x%x (bridge bit %d) replaces erased Nth\n",
-			    pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		    break;
-		}
-		intr_list_p = &intr_list->il_next;
-		if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
-		    /* entry appended to share list
-		     */
-#if DEBUG && INTR_DEBUG
-		    printk("%v INT 0x%x (bridge bit %d) is new Nth\n",
-			    pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		    break;
-		}
-		/* step to next record in chain
-		 */
-		intr_list = *intr_list_p;
-	    }
-	}
-    }
-
-#if DEBUG && INTR_DEBUG
-    printk("%v pcibr_intr_alloc complete\n", pconn_vhdl);
-#endif
-    hub_intr = (hub_intr_t)xtalk_intr;
-    pcibr_intr->bi_irq = hub_intr->i_bit;
-    pcibr_intr->bi_cpu = hub_intr->i_cpuid;
-    return pcibr_intr;
-}
-
-/*ARGSUSED */
-void
-pcibr_intr_free(pcibr_intr_t pcibr_intr)
-{
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    unsigned                pcibr_int_bit;
-    pcibr_intr_list_t       intr_list;
-    int			    intr_shared;
-    xtalk_intr_t	    *xtalk_intrp;
-
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) {
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    for (intr_list = 
-		     pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list;
-		 intr_list != NULL;
-		 intr_list = intr_list->il_next)
-		if (compare_and_swap_ptr((void **) &intr_list->il_intr, 
-					 pcibr_intr, 
-					 NULL)) {
-#if DEBUG && INTR_DEBUG
-		    printk("%s: cleared a handler from bit %d\n",
-			    pcibr_soft->bs_name, pcibr_int_bit);
-#endif
-		}
-	    /* If this interrupt line is not being shared between multiple
-	     * devices release the xtalk interrupt resources.
-	     */
-	    intr_shared = 
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared;
-	    xtalk_intrp = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
-
-	    if ((!intr_shared) && (*xtalk_intrp)) {
-
-		bridge_t 	*bridge = pcibr_soft->bs_base;
-		bridgereg_t	int_dev;
-
-		xtalk_intr_free(*xtalk_intrp);
-		*xtalk_intrp = 0;
-
-		/* Clear the PCI device interrupt to bridge interrupt pin
-		 * mapping.
-		 */
-		int_dev = bridge->b_int_device;
-		int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit);
-		bridge->b_int_device = int_dev;
-
-	    }
-	}
-    }
-    DEL(pcibr_intr);
-}
-
-LOCAL void
-pcibr_setpciint(xtalk_intr_t xtalk_intr)
-{
-    iopaddr_t               addr = xtalk_intr_addr_get(xtalk_intr);
-    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(xtalk_intr);
-    bridgereg_t            *int_addr = (bridgereg_t *)
-    xtalk_intr_sfarg_get(xtalk_intr);
-
-    *int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
-		 (BRIDGE_INT_ADDR_FLD & vect));
-}
-
-/*ARGSUSED */
-int
-pcibr_intr_connect(pcibr_intr_t pcibr_intr)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    unsigned                pcibr_int_bit;
-    bridgereg_t             b_int_enable;
-    unsigned long           s;
-
-    if (pcibr_intr == NULL)
-	return -1;
-
-#if DEBUG && INTR_DEBUG
-    printk("%v: pcibr_intr_connect\n",
-	    pcibr_intr->bi_dev);
-#endif
-
-    *((volatile unsigned *)&pcibr_intr->bi_flags) |= PCIIO_INTR_CONNECTED;
-
-    /*
-     * For each PCI interrupt line requested, figure
-     * out which Bridge PCI Interrupt Line it maps
-     * to, and make sure there are xtalk resources
-     * allocated for it.
-     */
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    xtalk_intr_t            xtalk_intr;
-
-	    xtalk_intr = pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
-
-	    /*
-	     * If this interrupt line is being shared and the connect has
-	     * already been done, no need to do it again.
-	     */
-	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected)
-		continue;
-
-
-	    /*
-	     * Use the pcibr wrapper function to handle all Bridge interrupts
-	     * regardless of whether the interrupt line is shared or not.
-	     */
-	    xtalk_intr_connect(xtalk_intr, (xtalk_intr_setfunc_t) pcibr_setpciint,
-			       (void *)&(bridge->b_int_addr[pcibr_int_bit].addr));
-	    pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 1;
-
-#if DEBUG && INTR_DEBUG
-	    printk("%v bridge bit %d wrapper connected\n",
-		    pcibr_intr->bi_dev, pcibr_int_bit);
-#endif
-	}
-    s = pcibr_lock(pcibr_soft);
-    b_int_enable = bridge->b_int_enable;
-    b_int_enable |= pcibr_int_bits;
-    bridge->b_int_enable = b_int_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    pcibr_unlock(pcibr_soft, s);
-
-    return 0;
-}
-
-/*ARGSUSED */
-void
-pcibr_intr_disconnect(pcibr_intr_t pcibr_intr)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    unsigned                pcibr_int_bit;
-    bridgereg_t             b_int_enable;
-    unsigned long           s;
-
-    /* Stop calling the function. Now.
-     */
-    *((volatile unsigned *)&pcibr_intr->bi_flags) &= ~PCIIO_INTR_CONNECTED;
-    /*
-     * For each PCI interrupt line requested, figure
-     * out which Bridge PCI Interrupt Line it maps
-     * to, and disconnect the interrupt.
-     */
-
-    /* don't disable interrupts for lines that
-     * are shared between devices.
-     */
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if ((pcibr_int_bits & (1 << pcibr_int_bit)) &&
-	    (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared))
-	    pcibr_int_bits &= ~(1 << pcibr_int_bit);
-    if (!pcibr_int_bits)
-	return;
-
-    s = pcibr_lock(pcibr_soft);
-    b_int_enable = bridge->b_int_enable;
-    b_int_enable &= ~pcibr_int_bits;
-    bridge->b_int_enable = b_int_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    pcibr_unlock(pcibr_soft, s);
-
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    /* if the interrupt line is now shared,
-	     * do not disconnect it.
-	     */
-	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)
-		continue;
-
-	    xtalk_intr_disconnect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr);
-	    pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 0;
-
-#if DEBUG && INTR_DEBUG
-	    printk("%s: xtalk disconnect done for Bridge bit %d\n",
-		pcibr_soft->bs_name, pcibr_int_bit);
-#endif
-
-	    /* if we are sharing the interrupt line,
-	     * connect us up; this closes the hole
-	     * where the another pcibr_intr_alloc()
-	     * was in progress as we disconnected.
-	     */
-	    if (!pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)
-		continue;
-
-	    xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr,
-			       (xtalk_intr_setfunc_t)pcibr_setpciint,
-			       (void *) &(bridge->b_int_addr[pcibr_int_bit].addr));
-	}
-}
-
-/*ARGSUSED */
-devfs_handle_t
-pcibr_intr_cpu_get(pcibr_intr_t pcibr_intr)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    unsigned                pcibr_int_bit;
-
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if (pcibr_int_bits & (1 << pcibr_int_bit))
-	    return xtalk_intr_cpu_get(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr);
-    return 0;
-}
-
-/* =====================================================================
- *    INTERRUPT HANDLING
- */
-LOCAL void
-pcibr_clearwidint(bridge_t *bridge)
-{
-    bridge->b_wid_int_upper = 0;
-    bridge->b_wid_int_lower = 0;
-}
-
-LOCAL void
-pcibr_setwidint(xtalk_intr_t intr)
-{
-    xwidgetnum_t            targ = xtalk_intr_target_get(intr);
-    iopaddr_t               addr = xtalk_intr_addr_get(intr);
-    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(intr);
-    widgetreg_t		    NEW_b_wid_int_upper, NEW_b_wid_int_lower;
-    widgetreg_t		    OLD_b_wid_int_upper, OLD_b_wid_int_lower;
-
-    bridge_t               *bridge = (bridge_t *)xtalk_intr_sfarg_get(intr);
-
-    NEW_b_wid_int_upper = ( (0x000F0000 & (targ << 16)) |
-			       XTALK_ADDR_TO_UPPER(addr));
-    NEW_b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
-
-    OLD_b_wid_int_upper = bridge->b_wid_int_upper;
-    OLD_b_wid_int_lower = bridge->b_wid_int_lower;
-
-    /* Verify that all interrupts from this Bridge are using a single PI */
-    if ((OLD_b_wid_int_upper != 0) && (OLD_b_wid_int_lower != 0)) {
-	/*
-	 * Once set, these registers shouldn't change; they should
-	 * be set multiple times with the same values.
-	 *
-	 * If we're attempting to change these registers, it means
-	 * that our heuristics for allocating interrupts in a way
-	 * appropriate for IP35 have failed, and the admin needs to
-	 * explicitly direct some interrupts (or we need to make the
-	 * heuristics more clever).
-	 *
-	 * In practice, we hope this doesn't happen very often, if
-	 * at all.
-	 */
-	if ((OLD_b_wid_int_upper != NEW_b_wid_int_upper) ||
-	    (OLD_b_wid_int_lower != NEW_b_wid_int_lower)) {
-		printk(KERN_WARNING  "Interrupt allocation is too complex.\n");
-		printk(KERN_WARNING  "Use explicit administrative interrupt targetting.\n");
-		printk(KERN_WARNING  "bridge=0x%lx targ=0x%x\n", (unsigned long)bridge, targ);
-		printk(KERN_WARNING  "NEW=0x%x/0x%x  OLD=0x%x/0x%x\n",
-			NEW_b_wid_int_upper, NEW_b_wid_int_lower,
-			OLD_b_wid_int_upper, OLD_b_wid_int_lower);
-		PRINT_PANIC("PCI Bridge interrupt targetting error\n");
-	}
-    }
-
-    bridge->b_wid_int_upper = NEW_b_wid_int_upper;
-    bridge->b_wid_int_lower = NEW_b_wid_int_lower;
-    bridge->b_int_host_err = vect;
-}
-
-/*
- * pcibr_intr_preset: called during mlreset time
- * if the platform specific code needs to route
- * one of the Bridge's xtalk interrupts before the
- * xtalk infrastructure is available.
- */
-void
-pcibr_xintr_preset(void *which_widget,
-		   int which_widget_intr,
-		   xwidgetnum_t targ,
-		   iopaddr_t addr,
-		   xtalk_intr_vector_t vect)
-{
-    bridge_t               *bridge = (bridge_t *) which_widget;
-
-    if (which_widget_intr == -1) {
-	/* bridge widget error interrupt */
-	bridge->b_wid_int_upper = ( (0x000F0000 & (targ << 16)) |
-				   XTALK_ADDR_TO_UPPER(addr));
-	bridge->b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
-	bridge->b_int_host_err = vect;
-
-	/* turn on all interrupts except
-	 * the PCI interrupt requests,
-	 * at least at heart.
-	 */
-	bridge->b_int_enable |= ~BRIDGE_IMR_INT_MSK;
-
-    } else {
-	/* routing a PCI device interrupt.
-	 * targ and low 38 bits of addr must
-	 * be the same as the already set
-	 * value for the widget error interrupt.
-	 */
-	bridge->b_int_addr[which_widget_intr].addr =
-	    ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
-	     (BRIDGE_INT_ADDR_FLD & vect));
-	/*
-	 * now bridge can let it through;
-	 * NB: still should be blocked at
-	 * xtalk provider end, until the service
-	 * function is set.
-	 */
-	bridge->b_int_enable |= 1 << vect;
-    }
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-}
-
-
-/*
- * pcibr_intr_func()
- *
- * This is the pcibr interrupt "wrapper" function that is called,
- * in interrupt context, to initiate the interrupt handler(s) registered
- * (via pcibr_intr_alloc/connect) for the occuring interrupt. Non-threaded 
- * handlers will be called directly, and threaded handlers will have their 
- * thread woken up.
- */
-void
-pcibr_intr_func(intr_arg_t arg)
-{
-    pcibr_intr_wrap_t       wrap = (pcibr_intr_wrap_t) arg;
-    reg_p                   wrbf;
-    pcibr_intr_t            intr;
-    pcibr_intr_list_t       list;
-    int                     clearit;
-    int			    do_nonthreaded = 1;
-    int			    is_threaded = 0;
-    int			    x = 0;
-
-	/*
-	 * If any handler is still running from a previous interrupt
-	 * just return. If there's a need to call the handler(s) again,
-	 * another interrupt will be generated either by the device or by
-	 * pcibr_force_interrupt().
-	 */
-
-	if (wrap->iw_hdlrcnt) {
-		return;
-	}
-
-    /*
-     * Call all interrupt handlers registered.
-     * First, the pcibr_intrd threads for any threaded handlers will be
-     * awoken, then any non-threaded handlers will be called sequentially.
-     */
-	
-	clearit = 1;
-	while (do_nonthreaded) {
-	    for (list = wrap->iw_list; list != NULL; list = list->il_next) {
-		if ((intr = list->il_intr) &&
-		    (intr->bi_flags & PCIIO_INTR_CONNECTED)) {
-
-		/*
-		 * This device may have initiated write
-		 * requests since the bridge last saw
-		 * an edge on this interrupt input; flushing
-		 * the buffer prior to invoking the handler
-		 * should help but may not be sufficient if we 
-		 * get more requests after the flush, followed
-		 * by the card deciding it wants service, before
-		 * the interrupt handler checks to see if things need
-		 * to be done.
-		 *
-		 * There is a similar race condition if
-		 * an interrupt handler loops around and
-		 * notices further service is required.
-		 * Perhaps we need to have an explicit
-		 * call that interrupt handlers need to
-		 * do between noticing that DMA to memory
-		 * has completed, but before observing the
-		 * contents of memory?
-		 */
-
-			if ((do_nonthreaded) && (!is_threaded)) {
-			/* Non-threaded. 
-			 * Call the interrupt handler at interrupt level
-			 */
-
-			/* Only need to flush write buffers if sharing */
-
-			if ((wrap->iw_shared) && (wrbf = list->il_wrbf)) {
-			    if ((x = *wrbf))	/* write request buffer flush */
-#ifdef SUPPORT_PRINTING_V_FORMAT
-				printk(KERN_ALERT  "pcibr_intr_func %v: \n"
-				    "write buffer flush failed, wrbf=0x%x\n", 
-				    list->il_intr->bi_dev, wrbf);
-#else
-				printk(KERN_ALERT  "pcibr_intr_func %p: \n"
-				    "write buffer flush failed, wrbf=0x%lx\n", 
-				    (void *)list->il_intr->bi_dev, (long) wrbf);
-#endif
-			}
-		    }
-
-		    clearit = 0;
-		}
-	    }
-
-		do_nonthreaded = 0;
-		/*
-		 * If the non-threaded handler was the last to complete,
-		 * (i.e., no threaded handlers still running) force an
-		 * interrupt to avoid a potential deadlock situation.
-		 */
-		if (wrap->iw_hdlrcnt == 0) {
-			pcibr_force_interrupt(wrap);
-		}
-	}
-
-	/* If there were no handlers,
-	 * disable the interrupt and return.
-	 * It will get enabled again after
-	 * a handler is connected.
-	 * If we don't do this, we would
-	 * sit here and spin through the
-	 * list forever.
-	 */
-	if (clearit) {
-	    pcibr_soft_t            pcibr_soft = wrap->iw_soft;
-	    bridge_t               *bridge = pcibr_soft->bs_base;
-	    bridgereg_t             b_int_enable;
-	    bridgereg_t		    mask = 1 << wrap->iw_intr;
-	    unsigned long           s;
-
-	    s = pcibr_lock(pcibr_soft);
-	    b_int_enable = bridge->b_int_enable;
-	    b_int_enable &= ~mask;
-	    bridge->b_int_enable = b_int_enable;
-	    bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-	    pcibr_unlock(pcibr_soft, s);
-	    return;
-	}
-}
-
-/* =====================================================================
- *    CONFIGURATION MANAGEMENT
- */
-/*ARGSUSED */
-void
-pcibr_provider_startup(devfs_handle_t pcibr)
-{
-}
-
-/*ARGSUSED */
-void
-pcibr_provider_shutdown(devfs_handle_t pcibr)
-{
-}
-
-int
-pcibr_reset(devfs_handle_t conn)
-{
-    pciio_info_t            pciio_info = pciio_info_get(conn);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    bridgereg_t             ctlreg;
-    unsigned                cfgctl[8];
-    unsigned long           s;
-    int                     f, nf;
-    pcibr_info_h            pcibr_infoh;
-    pcibr_info_t            pcibr_info;
-    int                     win;
-
-    if (pcibr_soft->bs_slot[pciio_slot].has_host) {
-	pciio_slot = pcibr_soft->bs_slot[pciio_slot].host_slot;
-	pcibr_info = pcibr_soft->bs_slot[pciio_slot].bss_infos[0];
-    }
-    if (pciio_slot < 4) {
-	s = pcibr_lock(pcibr_soft);
-	nf = pcibr_soft->bs_slot[pciio_slot].bss_ninfo;
-	pcibr_infoh = pcibr_soft->bs_slot[pciio_slot].bss_infos;
-	for (f = 0; f < nf; ++f)
-	    if (pcibr_infoh[f])
-		cfgctl[f] = bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4];
-
-	ctlreg = bridge->b_wid_control;
-	bridge->b_wid_control = ctlreg | BRIDGE_CTRL_RST(pciio_slot);
-	/* XXX delay? */
-	bridge->b_wid_control = ctlreg;
-	/* XXX delay? */
-
-	for (f = 0; f < nf; ++f)
-	    if ((pcibr_info = pcibr_infoh[f]))
-		for (win = 0; win < 6; ++win)
-		    if (pcibr_info->f_window[win].w_base != 0)
-			bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_BASE_ADDR(win) / 4] =
-			    pcibr_info->f_window[win].w_base;
-	for (f = 0; f < nf; ++f)
-	    if (pcibr_infoh[f])
-		bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4] = cfgctl[f];
-	pcibr_unlock(pcibr_soft, s);
-
-	return 0;
-    }
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    printk(KERN_WARNING   "%v: pcibr_reset unimplemented for slot %d\n",
-	    conn, pciio_slot);
-#endif
-    return -1;
-}
-
-pciio_endian_t
-pcibr_endian_set(devfs_handle_t pconn_vhdl,
-		 pciio_endian_t device_end,
-		 pciio_endian_t desired_end)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridgereg_t             devreg;
-    unsigned long           s;
-
-    /*
-     * Bridge supports hardware swapping; so we can always
-     * arrange for the caller's desired endianness.
-     */
-
-    s = pcibr_lock(pcibr_soft);
-    devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
-    if (device_end != desired_end)
-	devreg |= BRIDGE_DEV_SWAP_BITS;
-    else
-	devreg &= ~BRIDGE_DEV_SWAP_BITS;
-
-    /* NOTE- if we ever put SWAP bits
-     * onto the disabled list, we will
-     * have to change the logic here.
-     */
-    if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
-	bridge_t               *bridge = pcibr_soft->bs_base;
-
-	bridge->b_device[pciio_slot].reg = devreg;
-	pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    pcibr_unlock(pcibr_soft, s);
-
-#if DEBUG && PCIBR_DEV_DEBUG
-    printk("pcibr Device(%d): 0x%p\n", pciio_slot, bridge->b_device[pciio_slot].reg);
-#endif
-
-    return desired_end;
-}
-
-/* This (re)sets the GBR and REALTIME bits and also keeps track of how
- * many sets are outstanding. Reset succeeds only if the number of outstanding
- * sets == 1.
- */
-int
-pcibr_priority_bits_set(pcibr_soft_t pcibr_soft,
-			pciio_slot_t pciio_slot,
-			pciio_priority_t device_prio)
-{
-    unsigned long           s;
-    int                    *counter;
-    bridgereg_t             rtbits = 0;
-    bridgereg_t             devreg;
-    int                     rc = PRIO_SUCCESS;
-
-    /* in dual-slot configurations, the host and the
-     * guest have separate DMA resources, so they
-     * have separate requirements for priority bits.
-     */
-
-    counter = &(pcibr_soft->bs_slot[pciio_slot].bss_pri_uctr);
-
-    /*
-     * Bridge supports PCI notions of LOW and HIGH priority
-     * arbitration rings via a "REAL_TIME" bit in the per-device
-     * Bridge register. The "GBR" bit controls access to the GBR
-     * ring on the xbow. These two bits are (re)set together.
-     *
-     * XXX- Bug in Rev B Bridge Si:
-     * Symptom: Prefetcher starts operating incorrectly. This happens
-     * due to corruption of the address storage ram in the prefetcher
-     * when a non-real time PCI request is pulled and a real-time one is
-     * put in it's place. Workaround: Use only a single arbitration ring
-     * on PCI bus. GBR and RR can still be uniquely used per
-     * device. NETLIST MERGE DONE, WILL BE FIXED IN REV C.
-     */
-
-    if (pcibr_soft->bs_rev_num != BRIDGE_PART_REV_B)
-	rtbits |= BRIDGE_DEV_RT;
-
-    /* NOTE- if we ever put DEV_RT or DEV_GBR on
-     * the disabled list, we will have to take
-     * it into account here.
-     */
-
-    s = pcibr_lock(pcibr_soft);
-    devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
-    if (device_prio == PCI_PRIO_HIGH) {
-	if ((++*counter == 1)) {
-	    if (rtbits)
-		devreg |= rtbits;
-	    else
-		rc = PRIO_FAIL;
-	}
-    } else if (device_prio == PCI_PRIO_LOW) {
-	if (*counter <= 0)
-	    rc = PRIO_FAIL;
-	else if (--*counter == 0)
-	    if (rtbits)
-		devreg &= ~rtbits;
-    }
-    if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
-	bridge_t               *bridge = pcibr_soft->bs_base;
-
-	bridge->b_device[pciio_slot].reg = devreg;
-	pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    pcibr_unlock(pcibr_soft, s);
-
-    return rc;
-}
-
-pciio_priority_t
-pcibr_priority_set(devfs_handle_t pconn_vhdl,
-		   pciio_priority_t device_prio)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-    (void) pcibr_priority_bits_set(pcibr_soft, pciio_slot, device_prio);
-
-    return device_prio;
-}
-
-/*
- * Interfaces to allow special (e.g. SGI) drivers to set/clear
- * Bridge-specific device flags.  Many flags are modified through
- * PCI-generic interfaces; we don't allow them to be directly
- * manipulated here.  Only flags that at this point seem pretty
- * Bridge-specific can be set through these special interfaces.
- * We may add more flags as the need arises, or remove flags and
- * create PCI-generic interfaces as the need arises.
- *
- * Returns 0 on failure, 1 on success
- */
-int
-pcibr_device_flags_set(devfs_handle_t pconn_vhdl,
-		       pcibr_device_flags_t flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridgereg_t             set = 0;
-    bridgereg_t             clr = 0;
-
-    ASSERT((flags & PCIBR_DEVICE_FLAGS) == flags);
-
-    if (flags & PCIBR_WRITE_GATHER)
-	set |= BRIDGE_DEV_PMU_WRGA_EN;
-    if (flags & PCIBR_NOWRITE_GATHER)
-	clr |= BRIDGE_DEV_PMU_WRGA_EN;
-
-    if (flags & PCIBR_WRITE_GATHER)
-	set |= BRIDGE_DEV_DIR_WRGA_EN;
-    if (flags & PCIBR_NOWRITE_GATHER)
-	clr |= BRIDGE_DEV_DIR_WRGA_EN;
-
-    if (flags & PCIBR_PREFETCH)
-	set |= BRIDGE_DEV_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	clr |= BRIDGE_DEV_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	set |= BRIDGE_DEV_PRECISE;
-    if (flags & PCIBR_NOPRECISE)
-	clr |= BRIDGE_DEV_PRECISE;
-
-    if (flags & PCIBR_BARRIER)
-	set |= BRIDGE_DEV_BARRIER;
-    if (flags & PCIBR_NOBARRIER)
-	clr |= BRIDGE_DEV_BARRIER;
-
-    if (flags & PCIBR_64BIT)
-	set |= BRIDGE_DEV_DEV_SIZE;
-    if (flags & PCIBR_NO64BIT)
-	clr |= BRIDGE_DEV_DEV_SIZE;
-
-    if (set || clr) {
-	bridgereg_t             devreg;
-	unsigned long           s;
-
-	s = pcibr_lock(pcibr_soft);
-	devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
-	devreg = (devreg & ~clr) | set;
-	if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
-	    bridge_t               *bridge = pcibr_soft->bs_base;
-
-	    bridge->b_device[pciio_slot].reg = devreg;
-	    pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
-	    bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-	}
-	pcibr_unlock(pcibr_soft, s);
-#if DEBUG && PCIBR_DEV_DEBUG
-	printk("pcibr Device(%d): %R\n", pciio_slot, bridge->b_device[pciio_slot].regbridge->b_device[pciio_slot].reg, device_bits);
-#endif
-    }
-    return (1);
-}
-
-#ifdef LITTLE_ENDIAN
-/*
- * on sn-ia we need to twiddle the addresses going out
- * the pci bus because we use the unswizzled synergy space
- * (the alternative is to use the swizzled synergy space
- * and byte swap the data)
- */
-#define	CB(b,r)	(((volatile uint8_t *) b)[((r)^4)])
-#define	CS(b,r)	(((volatile uint16_t *) b)[((r^4)/2)])
-#define	CW(b,r)	(((volatile uint32_t *) b)[((r^4)/4)])
-#else
-#define	CB(b,r)	(((volatile uint8_t *) cfgbase)[(r)^3])
-#define	CS(b,r)	(((volatile uint16_t *) cfgbase)[((r)/2)^1])
-#define	CW(b,r)	(((volatile uint32_t *) cfgbase)[(r)/4])
-#endif /* LITTLE_ENDIAN */
-
-
-LOCAL                   cfg_p
-pcibr_config_addr(devfs_handle_t conn,
-		  unsigned reg)
-{
-    pcibr_info_t            pcibr_info;
-    pciio_slot_t            pciio_slot;
-    pciio_function_t        pciio_func;
-    pcibr_soft_t            pcibr_soft;
-    bridge_t               *bridge;
-    cfg_p                   cfgbase = (cfg_p)0;
-
-    pcibr_info = pcibr_info_get(conn);
-
-    pciio_slot = pcibr_info->f_slot;
-    if (pciio_slot == PCIIO_SLOT_NONE)
-	pciio_slot = PCI_TYPE1_SLOT(reg);
-
-    pciio_func = pcibr_info->f_func;
-    if (pciio_func == PCIIO_FUNC_NONE)
-	pciio_func = PCI_TYPE1_FUNC(reg);
-
-    pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-
-    bridge = pcibr_soft->bs_base;
-
-    cfgbase = bridge->b_type0_cfg_dev[pciio_slot].f[pciio_func].l;
-
-    return cfgbase;
-}
-
-uint64_t
-pcibr_config_get(devfs_handle_t conn,
-		 unsigned reg,
-		 unsigned size)
-{
-    return do_pcibr_config_get(pcibr_config_addr(conn, reg),
-			       PCI_TYPE1_REG(reg), size);
-}
-
-LOCAL uint64_t
-do_pcibr_config_get(
-		       cfg_p cfgbase,
-		       unsigned reg,
-		       unsigned size)
-{
-    unsigned                value;
-
-   
-    value = CW(cfgbase, reg);
-
-    if (reg & 3)
-	value >>= 8 * (reg & 3);
-    if (size < 4)
-	value &= (1 << (8 * size)) - 1;
-
-    return value;
-}
-
-void
-pcibr_config_set(devfs_handle_t conn,
-		 unsigned reg,
-		 unsigned size,
-		 uint64_t value)
-{
-    do_pcibr_config_set(pcibr_config_addr(conn, reg),
-			PCI_TYPE1_REG(reg), size, value);
-}
-
-LOCAL void
-do_pcibr_config_set(cfg_p cfgbase,
-		    unsigned reg,
-		    unsigned size,
-		    uint64_t value)
-{
-    switch (size) {
-    case 1:
-	CB(cfgbase, reg) = value;
-	break;
-    case 2:
-	if (reg & 1) {
-	    CB(cfgbase, reg) = value;
-	    CB(cfgbase, reg + 1) = value >> 8;
-	} else
-	    CS(cfgbase, reg) = value;
-	break;
-    case 3:
-	if (reg & 1) {
-	    CB(cfgbase, reg) = value;
-	    CS(cfgbase, (reg + 1)) = value >> 8;
-	} else {
-	    CS(cfgbase, reg) = value;
-	    CB(cfgbase, reg + 2) = value >> 16;
-	}
-	break;
-
-    case 4:
-	CW(cfgbase, reg) = value;
-	break;
-    }
-}
-
-pciio_provider_t        pcibr_provider =
-{
-    (pciio_piomap_alloc_f *) pcibr_piomap_alloc,
-    (pciio_piomap_free_f *) pcibr_piomap_free,
-    (pciio_piomap_addr_f *) pcibr_piomap_addr,
-    (pciio_piomap_done_f *) pcibr_piomap_done,
-    (pciio_piotrans_addr_f *) pcibr_piotrans_addr,
-    (pciio_piospace_alloc_f *) pcibr_piospace_alloc,
-    (pciio_piospace_free_f *) pcibr_piospace_free,
-
-    (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,
-    (pciio_dmamap_free_f *) pcibr_dmamap_free,
-    (pciio_dmamap_addr_f *) pcibr_dmamap_addr,
-    (pciio_dmamap_list_f *) pcibr_dmamap_list,
-    (pciio_dmamap_done_f *) pcibr_dmamap_done,
-    (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
-    (pciio_dmatrans_list_f *) pcibr_dmatrans_list,
-    (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
-    (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
-    (pciio_dmalist_drain_f *) pcibr_dmalist_drain,
-
-    (pciio_intr_alloc_f *) pcibr_intr_alloc,
-    (pciio_intr_free_f *) pcibr_intr_free,
-    (pciio_intr_connect_f *) pcibr_intr_connect,
-    (pciio_intr_disconnect_f *) pcibr_intr_disconnect,
-    (pciio_intr_cpu_get_f *) pcibr_intr_cpu_get,
-
-    (pciio_provider_startup_f *) pcibr_provider_startup,
-    (pciio_provider_shutdown_f *) pcibr_provider_shutdown,
-    (pciio_reset_f *) pcibr_reset,
-    (pciio_write_gather_flush_f *) pcibr_write_gather_flush,
-    (pciio_endian_set_f *) pcibr_endian_set,
-    (pciio_priority_set_f *) pcibr_priority_set,
-    (pciio_config_get_f *) pcibr_config_get,
-    (pciio_config_set_f *) pcibr_config_set,
-
-    (pciio_error_devenable_f *) 0,
-    (pciio_error_extract_f *) 0,
-
-#ifdef LATER
-    (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback,
-    (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback,
-#else
-    (pciio_driver_reg_callback_f *) 0,
-    (pciio_driver_unreg_callback_f *) 0,
-#endif
-    (pciio_device_unregister_f 	*) pcibr_device_unregister,
-    (pciio_dma_enabled_f		*) pcibr_dma_enabled,
-};
-
-LOCAL                   pcibr_hints_t
-pcibr_hints_get(devfs_handle_t xconn_vhdl, int alloc)
-{
-    arbitrary_info_t        ainfo = 0;
-    graph_error_t	    rv;
-    pcibr_hints_t           hint;
-
-    rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
-
-    if (alloc && (rv != GRAPH_SUCCESS)) {
-
-	NEW(hint);
-	hint->rrb_alloc_funct = NULL;
-	hint->ph_intr_bits = NULL;
-	rv = hwgraph_info_add_LBL(xconn_vhdl, 
-				  INFO_LBL_PCIBR_HINTS, 	
-				  (arbitrary_info_t) hint);
-	if (rv != GRAPH_SUCCESS)
-	    goto abnormal_exit;
-
-	rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
-	
-	if (rv != GRAPH_SUCCESS)
-	    goto abnormal_exit;
-
-	if (ainfo != (arbitrary_info_t) hint)
-	    goto abnormal_exit;
-    }
-    return (pcibr_hints_t) ainfo;
-
-abnormal_exit:
-#ifdef LATER
-    printf("SHOULD NOT BE HERE\n");
-#endif
-    DEL(hint);
-    return(NULL);
-
-}
-
-void
-pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_rrb_fixed = mask;
-#if DEBUG
-    else
-	printk("pcibr_hints_fix_rrbs: pcibr_hints_get failed at\n"
-		"\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_hints_fix_rrbs(devfs_handle_t xconn_vhdl)
-{
-    pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF);
-}
-
-void
-pcibr_hints_dualslot(devfs_handle_t xconn_vhdl,
-		     pciio_slot_t host,
-		     pciio_slot_t guest)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_host_slot[guest] = host + 1;
-#if DEBUG
-    else
-	printk("pcibr_hints_dualslot: pcibr_hints_get failed at\n"
-		"\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl,
-		      pcibr_intr_bits_f *xxx_intr_bits)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_intr_bits = xxx_intr_bits;
-#if DEBUG
-    else
-	printk("pcibr_hints_intr_bits: pcibr_hints_get failed at\n"
-	       "\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->rrb_alloc_funct = rrb_alloc_funct;
-}
-
-void
-pcibr_hints_handsoff(devfs_handle_t xconn_vhdl)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_hands_off = 1;
-#if DEBUG
-    else
-	printk("pcibr_hints_handsoff: pcibr_hints_get failed at\n"
-		"\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
-		    pciio_slot_t slot,
-		    uint64_t subdevs)
-{
-    arbitrary_info_t        ainfo = 0;
-    char                    sdname[16];
-    devfs_handle_t            pconn_vhdl = GRAPH_VERTEX_NONE;
-
-    sprintf(sdname, "pci/%d", slot);
-    (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl);
-    if (pconn_vhdl == GRAPH_VERTEX_NONE) {
-#if DEBUG
-	printk("pcibr_hints_subdevs: hwgraph_path_create failed at\n"
-		"\t%p (seeking %s)\n", xconn_vhdl, sdname);
-#endif
-	return;
-    }
-    hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
-    if (ainfo == 0) {
-	uint64_t                *subdevp;
-
-	NEW(subdevp);
-	if (!subdevp) {
-#if DEBUG
-	    printk("pcibr_hints_subdevs: subdev ptr alloc failed at\n"
-		    "\t%p\n", pconn_vhdl);
-#endif
-	    return;
-	}
-	*subdevp = subdevs;
-	hwgraph_info_add_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, (arbitrary_info_t) subdevp);
-	hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
-	if (ainfo == (arbitrary_info_t) subdevp)
-	    return;
-	DEL(subdevp);
-	if (ainfo == (arbitrary_info_t) NULL) {
-#if DEBUG
-	    printk("pcibr_hints_subdevs: null subdevs ptr at\n"
-		    "\t%p\n", pconn_vhdl);
-#endif
-	    return;
-	}
-#if DEBUG
-	printk("pcibr_subdevs_get: dup subdev add_LBL at\n"
-		"\t%p\n", pconn_vhdl);
-#endif
-    }
-    *(uint64_t *) ainfo = subdevs;
-}
-
-
-#ifdef LATER
-
-#include <sys/idbg.h>
-#include <sys/idbgentry.h>
-
-char *pci_space[] = {"NONE", 
-		     "ROM",
-		     "IO",
-		     "",
-		     "MEM",
-		     "MEM32",
-		     "MEM64",
-		     "CFG",
-		     "WIN0",
-		     "WIN1",
-		     "WIN2",
-		     "WIN3",
-		     "WIN4",
-		     "WIN5",
-		     "",
-		     "BAD"};
-
-void
-idbg_pss_func(pcibr_info_h pcibr_infoh, int func)
-{
-    pcibr_info_t	pcibr_info = pcibr_infoh[func];
-    char		name[MAXDEVNAME];
-    int			win;
-    
-    if (!pcibr_info)
-	return;
-    qprintf("Per-slot Function Info\n");
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    sprintf(name, "%v", pcibr_info->f_vertex);
-#endif
-    qprintf("\tSlot Name : %s\n",name);
-    qprintf("\tPCI Bus : %d ",pcibr_info->f_bus);
-    qprintf("Slot : %d ", pcibr_info->f_slot);
-    qprintf("Function : %d ", pcibr_info->f_func);
-    qprintf("VendorId : 0x%x " , pcibr_info->f_vendor);
-    qprintf("DeviceId : 0x%x\n", pcibr_info->f_device);
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    sprintf(name, "%v", pcibr_info->f_master);
-#endif
-    qprintf("\tBus provider : %s\n",name);
-    qprintf("\tProvider Fns : 0x%x ", pcibr_info->f_pops);
-    qprintf("Error Handler : 0x%x Arg 0x%x\n", 
-	    pcibr_info->f_efunc,pcibr_info->f_einfo);
-    for(win = 0 ; win < 6 ; win++) 
-	qprintf("\tBase Reg #%d space %s base 0x%x size 0x%x\n",
-		win,pci_space[pcibr_info->f_window[win].w_space],
-		pcibr_info->f_window[win].w_base,
-		pcibr_info->f_window[win].w_size);
-
-    qprintf("\tRom base 0x%x size 0x%x\n", 
-	    pcibr_info->f_rbase,pcibr_info->f_rsize);
-
-    qprintf("\tInterrupt Bit Map\n");
-    qprintf("\t\tPCI Int#\tBridge Pin#\n");
-    for (win = 0 ; win < 4; win++)
-	qprintf("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]);
-    qprintf("\n");
-}
-
-
-void
-idbg_pss_info(pcibr_soft_t pcibr_soft, pciio_slot_t slot)
-{
-    pcibr_soft_slot_t	pss;
-    char		slot_conn_name[MAXDEVNAME];
-    int			func;
-
-    pss = &pcibr_soft->bs_slot[slot];
-    qprintf("PCI INFRASTRUCTURAL INFO FOR SLOT %d\n", slot);
-    qprintf("\tHost Present ? %s ", pss->has_host ? "yes" : "no");
-    qprintf("\tHost Slot : %d\n",pss->host_slot);
-    sprintf(slot_conn_name, "%v", pss->slot_conn);
-    qprintf("\tSlot Conn : %s\n",slot_conn_name);	
-    qprintf("\t#Functions : %d\n",pss->bss_ninfo);
-    for (func = 0; func < pss->bss_ninfo; func++)
-	idbg_pss_func(pss->bss_infos,func);
-    qprintf("\tSpace : %s ",pci_space[pss->bss_devio.bssd_space]);
-    qprintf("\tBase : 0x%x ", pss->bss_devio.bssd_base);
-    qprintf("\tShadow Devreg : 0x%x\n", pss->bss_device);
-    qprintf("\tUsage counts : pmu %d d32 %d d64 %d\n",
-	    pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr);
-    
-    qprintf("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x"
-	    "d32_base 0x%x d32_flags 0x%x\n",
-	    pss->bss_d64_base, pss->bss_d64_flags,
-	    pss->bss_d32_base, pss->bss_d32_flags);
-    
-    qprintf("\tExt ATEs active ? %s", 
-	    atomic_read(&pss->bss_ext_ates_active) ? "yes" : "no");
-    qprintf(" Command register : 0x%x ", pss->bss_cmd_pointer);
-    qprintf(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow);
-
-    qprintf("\tRRB Info : Valid %d+%d Reserved %d\n",
-	    pcibr_soft->bs_rrb_valid[slot],
-	    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-		
-}
-
-int	ips = 0;
-
-void
-idbg_pss(pcibr_soft_t pcibr_soft)
-{
-    pciio_slot_t	slot;
-
-    
-    if (ips >= 0 && ips < 8)
-	idbg_pss_info(pcibr_soft,ips);
-    else if (ips < 0)
-	for (slot = 0; slot < 8; slot++) 
-	    idbg_pss_info(pcibr_soft,slot);
-    else
-	qprintf("Invalid ips %d\n",ips);
-}
-
-#endif /* LATER */
-
-int
-pcibr_dma_enabled(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-	
-
-    return xtalk_dma_enabled(pcibr_soft->bs_conn);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/pciio.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/pciio.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/pciio.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/pciio.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1681 +0,0 @@
-/* $Id: pciio.c,v 1.2 2002/11/16 02:23:19 steiner Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#define	USRPCI	0
-
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/xtalk/xbow.h>	/* Must be before iograph.h to get MAX_PORT_NUM */
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/ioerror_handling.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pciio_private.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/ate_utils.h>
-#include <asm/sn/simulator.h>
-
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
-#define DEBUG_PCIIO
-#undef DEBUG_PCIIO	/* turn this on for yet more console output */
-
-
-#define GET_NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DO_DEL(ptr)	(kfree(ptr))
-
-char                    pciio_info_fingerprint[] = "pciio_info";
-
-cdl_p                   pciio_registry = NULL;
-
-int
-badaddr_val(volatile void *addr, int len, volatile void *ptr)
-{
-	int ret = 0;
-	volatile void *new_addr;
-
-	switch (len) {
-		case 4:
-			new_addr = (void *)(((u64) addr)^4);
-			ret = ia64_sn_probe_io_slot((long)new_addr, len, (void *)ptr);
-			break;
-		default:
-			printk(KERN_WARNING "badaddr_val given len %x but supports len of 4 only\n", len);
-	}
-
-	if (ret < 0)
-		panic("badaddr_val: unexpected status (%d) in probing", ret);
-	return(ret);
-
-}
-
-
-nasid_t
-get_console_nasid(void)
-{
-	extern nasid_t console_nasid;
-	if (console_nasid < 0) {
-		console_nasid = ia64_sn_get_console_nasid();
-		if (console_nasid < 0) {
-// ZZZ What do we do if we don't get a console nasid on the hardware????
-			if (IS_RUNNING_ON_SIMULATOR() )
-				console_nasid = master_nasid;
-		}
-	} 
-	return console_nasid;
-}
-
-int
-hub_dma_enabled(devfs_handle_t xconn_vhdl)
-{
-	return(0);
-}
-
-int
-hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
-{
-	return(0);
-}
-
-void
-ioerror_dump(char *name, int error_code, int error_mode, ioerror_t *ioerror)
-{
-}
-
-/******
- ****** end hack defines ......
- ******/
-
-
-
-
-/* =====================================================================
- *    PCI Generic Bus Provider
- * Implement PCI provider operations.  The pciio* layer provides a
- * platform-independent interface for PCI devices.  This layer
- * switches among the possible implementations of a PCI adapter.
- */
-
-/* =====================================================================
- *    Provider Function Location SHORTCUT
- *
- * On platforms with only one possible PCI provider, macros can be
- * set up at the top that cause the table lookups and indirections to
- * completely disappear.
- */
-
-/*
- *    For the moment, we will assume that IP27
- *      only use Bridge ASICs to provide PCI support.
- */
-#include <asm/sn/pci/pcibr.h>
-#define DEV_FUNC(dev,func)	pcibr_##func
-#define CAST_PIOMAP(x)		((pcibr_piomap_t)(x))
-#define CAST_DMAMAP(x)		((pcibr_dmamap_t)(x))
-#define CAST_INTR(x)		((pcibr_intr_t)(x))
-
-/* =====================================================================
- *    Function Table of Contents
- */
-
-#if !defined(DEV_FUNC)
-static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev);
-#endif
-
-pciio_piomap_t          pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
-void                    pciio_piomap_free(pciio_piomap_t);
-caddr_t                 pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t);
-
-void                    pciio_piomap_done(pciio_piomap_t);
-caddr_t                 pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-caddr_t			pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned);
-
-iopaddr_t               pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
-
-pciio_dmamap_t          pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    pciio_dmamap_free(pciio_dmamap_t);
-iopaddr_t               pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
-alenlist_t              pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned);
-void                    pciio_dmamap_done(pciio_dmamap_t);
-iopaddr_t               pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void			pciio_dmamap_drain(pciio_dmamap_t);
-void			pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void			pciio_dmalist_drain(devfs_handle_t, alenlist_t);
-iopaddr_t               pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned);
-
-pciio_intr_t            pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
-void                    pciio_intr_free(pciio_intr_t);
-int                     pciio_intr_connect(pciio_intr_t);
-void                    pciio_intr_disconnect(pciio_intr_t);
-devfs_handle_t            pciio_intr_cpu_get(pciio_intr_t);
-
-void			pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t);
-
-void                    pciio_provider_startup(devfs_handle_t);
-void                    pciio_provider_shutdown(devfs_handle_t);
-
-pciio_endian_t          pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
-pciio_priority_t        pciio_priority_set(devfs_handle_t, pciio_priority_t);
-devfs_handle_t            pciio_intr_dev_get(pciio_intr_t);
-
-devfs_handle_t            pciio_pio_dev_get(pciio_piomap_t);
-pciio_slot_t            pciio_pio_slot_get(pciio_piomap_t);
-pciio_space_t           pciio_pio_space_get(pciio_piomap_t);
-iopaddr_t               pciio_pio_pciaddr_get(pciio_piomap_t);
-ulong                   pciio_pio_mapsz_get(pciio_piomap_t);
-caddr_t                 pciio_pio_kvaddr_get(pciio_piomap_t);
-
-devfs_handle_t            pciio_dma_dev_get(pciio_dmamap_t);
-pciio_slot_t            pciio_dma_slot_get(pciio_dmamap_t);
-
-pciio_info_t            pciio_info_chk(devfs_handle_t);
-pciio_info_t            pciio_info_get(devfs_handle_t);
-void                    pciio_info_set(devfs_handle_t, pciio_info_t);
-devfs_handle_t            pciio_info_dev_get(pciio_info_t);
-pciio_slot_t            pciio_info_slot_get(pciio_info_t);
-pciio_function_t        pciio_info_function_get(pciio_info_t);
-pciio_vendor_id_t       pciio_info_vendor_id_get(pciio_info_t);
-pciio_device_id_t       pciio_info_device_id_get(pciio_info_t);
-devfs_handle_t            pciio_info_master_get(pciio_info_t);
-arbitrary_info_t        pciio_info_mfast_get(pciio_info_t);
-pciio_provider_t       *pciio_info_pops_get(pciio_info_t);
-error_handler_f	       *pciio_info_efunc_get(pciio_info_t);
-error_handler_arg_t    *pciio_info_einfo_get(pciio_info_t);
-pciio_space_t		pciio_info_bar_space_get(pciio_info_t, int);
-iopaddr_t		pciio_info_bar_base_get(pciio_info_t, int);
-size_t			pciio_info_bar_size_get(pciio_info_t, int);
-iopaddr_t		pciio_info_rom_base_get(pciio_info_t);
-size_t			pciio_info_rom_size_get(pciio_info_t);
-
-void                    pciio_init(void);
-int                     pciio_attach(devfs_handle_t);
-
-void                    pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns);
-void                    pciio_provider_unregister(devfs_handle_t);
-pciio_provider_t       *pciio_provider_fns_get(devfs_handle_t);
-
-int                     pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned);
-void                    pciio_driver_unregister(char *driver_prefix);
-
-devfs_handle_t            pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-
-void			pciio_device_unregister(devfs_handle_t);
-pciio_info_t		pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-void			pciio_device_info_free(pciio_info_t);
-devfs_handle_t		pciio_device_info_register(devfs_handle_t, pciio_info_t);
-void			pciio_device_info_unregister(devfs_handle_t, pciio_info_t);
-int                     pciio_device_attach(devfs_handle_t, int);
-int			pciio_device_detach(devfs_handle_t, int);
-void                    pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t);
-
-int                     pciio_reset(devfs_handle_t);
-int                     pciio_write_gather_flush(devfs_handle_t);
-int                     pciio_slot_inuse(devfs_handle_t);
-
-/* =====================================================================
- *    Provider Function Location
- *
- *      If there is more than one possible provider for
- *      this platform, we need to examine the master
- *      vertex of the current vertex for a provider
- *      function structure, and indirect through the
- *      appropriately named member.
- */
-
-#if !defined(DEV_FUNC)
-
-static pciio_provider_t *
-pciio_to_provider_fns(devfs_handle_t dev)
-{
-    pciio_info_t            card_info;
-    pciio_provider_t       *provider_fns;
-
-    /*
-     * We're called with two types of vertices, one is
-     * the bridge vertex (ends with "pci") and the other is the
-     * pci slot vertex (ends with "pci/[0-8]").  For the first type
-     * we need to get the provider from the PFUNCS label.  For
-     * the second we get it from fastinfo/c_pops.
-     */
-    provider_fns = pciio_provider_fns_get(dev);
-    if (provider_fns == NULL) {
-	card_info = pciio_info_get(dev);
-	if (card_info != NULL) {
-		provider_fns = pciio_info_pops_get(card_info);
-	}
-    }
-
-    if (provider_fns == NULL)
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	PRINT_PANIC("%v: provider_fns == NULL", dev);
-#else
-	PRINT_PANIC("0x%p: provider_fns == NULL", (void *)dev);
-#endif
-
-    return provider_fns;
-
-}
-
-#define DEV_FUNC(dev,func)	pciio_to_provider_fns(dev)->func
-#define CAST_PIOMAP(x)		((pciio_piomap_t)(x))
-#define CAST_DMAMAP(x)		((pciio_dmamap_t)(x))
-#define CAST_INTR(x)		((pciio_intr_t)(x))
-#endif
-
-/*
- * Many functions are not passed their vertex
- * information directly; rather, they must
- * dive through a resource map. These macros
- * are available to coordinate this detail.
- */
-#define PIOMAP_FUNC(map,func)		DEV_FUNC((map)->pp_dev,func)
-#define DMAMAP_FUNC(map,func)		DEV_FUNC((map)->pd_dev,func)
-#define INTR_FUNC(intr_hdl,func)	DEV_FUNC((intr_hdl)->pi_dev,func)
-
-/* =====================================================================
- *          PIO MANAGEMENT
- *
- *      For mapping system virtual address space to
- *      pciio space on a specified card
- */
-
-pciio_piomap_t
-pciio_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-		   iopaddr_t addr,	/* lowest address (or offset in window) */
-		   size_t byte_count,	/* size of region containing our mappings */
-		   size_t byte_count_max,	/* maximum size of a mapping */
-		   unsigned flags)
-{					/* defined in sys/pio.h */
-    return (pciio_piomap_t) DEV_FUNC(dev, piomap_alloc)
-	(dev, dev_desc, space, addr, byte_count, byte_count_max, flags);
-}
-
-void
-pciio_piomap_free(pciio_piomap_t pciio_piomap)
-{
-    PIOMAP_FUNC(pciio_piomap, piomap_free)
-	(CAST_PIOMAP(pciio_piomap));
-}
-
-caddr_t
-pciio_piomap_addr(pciio_piomap_t pciio_piomap,	/* mapping resources */
-		  iopaddr_t pciio_addr,	/* map for this pciio address */
-		  size_t byte_count)
-{					/* map this many bytes */
-    pciio_piomap->pp_kvaddr = PIOMAP_FUNC(pciio_piomap, piomap_addr)
-	(CAST_PIOMAP(pciio_piomap), pciio_addr, byte_count);
-
-    return pciio_piomap->pp_kvaddr;
-}
-
-void
-pciio_piomap_done(pciio_piomap_t pciio_piomap)
-{
-    PIOMAP_FUNC(pciio_piomap, piomap_done)
-	(CAST_PIOMAP(pciio_piomap));
-}
-
-caddr_t
-pciio_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-		    iopaddr_t addr,	/* starting address (or offset in window) */
-		    size_t byte_count,	/* map this many bytes */
-		    unsigned flags)
-{					/* (currently unused) */
-    return DEV_FUNC(dev, piotrans_addr)
-	(dev, dev_desc, space, addr, byte_count, flags);
-}
-
-caddr_t
-pciio_pio_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-	       iopaddr_t addr,		/* starting address (or offset in window) */
-	       size_t byte_count,	/* map this many bytes */
-	       pciio_piomap_t *mapp,	/* where to return the map pointer */
-	       unsigned flags)
-{					/* PIO flags */
-    pciio_piomap_t          map = 0;
-    int			    errfree = 0;
-    caddr_t                 res;
-
-    if (mapp) {
-	map = *mapp;			/* possible pre-allocated map */
-	*mapp = 0;			/* record "no map used" */
-    }
-
-    res = pciio_piotrans_addr
-	(dev, dev_desc, space, addr, byte_count, flags);
-    if (res)
-	return res;			/* pciio_piotrans worked */
-
-    if (!map) {
-	map = pciio_piomap_alloc
-	    (dev, dev_desc, space, addr, byte_count, byte_count, flags);
-	if (!map)
-	    return res;			/* pciio_piomap_alloc failed */
-	errfree = 1;
-    }
-
-    res = pciio_piomap_addr
-	(map, addr, byte_count);
-    if (!res) {
-	if (errfree)
-	    pciio_piomap_free(map);
-	return res;			/* pciio_piomap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* pciio_piomap_addr succeeded */
-}
-
-iopaddr_t
-pciio_piospace_alloc(devfs_handle_t dev,	/* Device requiring space */
-		     device_desc_t dev_desc,	/* Device descriptor */
-		     pciio_space_t space,	/* MEM32/MEM64/IO */
-		     size_t byte_count,	/* Size of mapping */
-		     size_t align)
-{					/* Alignment needed */
-    if (align < NBPP)
-	align = NBPP;
-    return DEV_FUNC(dev, piospace_alloc)
-	(dev, dev_desc, space, byte_count, align);
-}
-
-void
-pciio_piospace_free(devfs_handle_t dev,	/* Device freeing space */
-		    pciio_space_t space,	/* Type of space        */
-		    iopaddr_t pciaddr,	/* starting address */
-		    size_t byte_count)
-{					/* Range of address   */
-    DEV_FUNC(dev, piospace_free)
-	(dev, space, pciaddr, byte_count);
-}
-
-/* =====================================================================
- *          DMA MANAGEMENT
- *
- *      For mapping from pci space to system
- *      physical space.
- */
-
-pciio_dmamap_t
-pciio_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   size_t byte_count_max,	/* max size of a mapping */
-		   unsigned flags)
-{					/* defined in dma.h */
-    return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-	(dev, dev_desc, byte_count_max, flags);
-}
-
-void
-pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_free)
-	(CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
-		  paddr_t paddr,	/* map for this address */
-		  size_t byte_count)
-{					/* map this many bytes */
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_addr)
-	(CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
-}
-
-alenlist_t
-pciio_dmamap_list(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
-		  alenlist_t alenlist,	/* map this Address/Length List */
-		  unsigned flags)
-{
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_list)
-	(CAST_DMAMAP(pciio_dmamap), alenlist, flags);
-}
-
-void
-pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_done)
-	(CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-pciio_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    paddr_t paddr,	/* system physical address */
-		    size_t byte_count,	/* length */
-		    unsigned flags)
-{					/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_addr)
-	(dev, dev_desc, paddr, byte_count, flags);
-}
-
-alenlist_t
-pciio_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    alenlist_t palenlist,	/* system address/length list */
-		    unsigned flags)
-{					/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-	(dev, dev_desc, palenlist, flags);
-}
-
-iopaddr_t
-pciio_dma_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       paddr_t paddr,		/* system physical address */
-	       size_t byte_count,	/* length */
-	       pciio_dmamap_t *mapp,	/* map to use, then map we used */
-	       unsigned flags)
-{					/* PIO flags */
-    pciio_dmamap_t          map = 0;
-    int			    errfree = 0;
-    iopaddr_t               res;
-
-    if (mapp) {
-	map = *mapp;			/* possible pre-allocated map */
-	*mapp = 0;			/* record "no map used" */
-    }
-
-    res = pciio_dmatrans_addr
-	(dev, dev_desc, paddr, byte_count, flags);
-    if (res)
-	return res;			/* pciio_dmatrans worked */
-
-    if (!map) {
-	map = pciio_dmamap_alloc
-	    (dev, dev_desc, byte_count, flags);
-	if (!map)
-	    return res;			/* pciio_dmamap_alloc failed */
-	errfree = 1;
-    }
-
-    res = pciio_dmamap_addr
-	(map, paddr, byte_count);
-    if (!res) {
-	if (errfree)
-	    pciio_dmamap_free(map);
-	return res;			/* pciio_dmamap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* pciio_dmamap_addr succeeded */
-}
-
-void
-pciio_dmamap_drain(pciio_dmamap_t map)
-{
-    DMAMAP_FUNC(map, dmamap_drain)
-	(CAST_DMAMAP(map));
-}
-
-void
-pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
-{
-    DEV_FUNC(dev, dmaaddr_drain)
-	(dev, addr, size);
-}
-
-void
-pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list)
-{
-    DEV_FUNC(dev, dmalist_drain)
-	(dev, list);
-}
-
-/* =====================================================================
- *          INTERRUPT MANAGEMENT
- *
- *      Allow crosstalk devices to establish interrupts
- */
-
-/*
- * Allocate resources required for an interrupt as specified in intr_desc.
- * Return resource handle in intr_hdl.
- */
-pciio_intr_t
-pciio_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
-		 device_desc_t dev_desc,	/* device descriptor */
-		 pciio_intr_line_t lines,	/* INTR line(s) to attach */
-		 devfs_handle_t owner_dev)
-{					/* owner of this interrupt */
-    return (pciio_intr_t) DEV_FUNC(dev, intr_alloc)
-	(dev, dev_desc, lines, owner_dev);
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-pciio_intr_free(pciio_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_free)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Associate resources allocated with a previous pciio_intr_alloc call with the
- * described handler, arg, name, etc.
- *
- * Returns 0 on success, returns <0 on failure.
- */
-int
-pciio_intr_connect(pciio_intr_t intr_hdl)	/* pciio intr resource handle */
-{
-    return INTR_FUNC(intr_hdl, intr_connect)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-pciio_intr_disconnect(pciio_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_disconnect)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-pciio_intr_cpu_get(pciio_intr_t intr_hdl)
-{
-    return INTR_FUNC(intr_hdl, intr_cpu_get)
-	(CAST_INTR(intr_hdl));
-}
-
-void
-pciio_slot_func_to_name(char		       *name,
-			pciio_slot_t		slot,
-			pciio_function_t	func)
-{
-    /*
-     * standard connection points:
-     *
-     * PCIIO_SLOT_NONE:	.../pci/direct
-     * PCIIO_FUNC_NONE: .../pci/<SLOT>			ie. .../pci/3
-     * multifunction:   .../pci/<SLOT><FUNC>		ie. .../pci/3c
-     */
-
-    if (slot == PCIIO_SLOT_NONE)
-	sprintf(name, EDGE_LBL_DIRECT);
-    else if (func == PCIIO_FUNC_NONE)
-	sprintf(name, "%d", slot);
-    else
-	sprintf(name, "%d%c", slot, 'a'+func);
-}
-
-/* =====================================================================
- *          CONFIGURATION MANAGEMENT
- */
-
-/*
- * Startup a crosstalk provider
- */
-void
-pciio_provider_startup(devfs_handle_t pciio_provider)
-{
-    DEV_FUNC(pciio_provider, provider_startup)
-	(pciio_provider);
-}
-
-/*
- * Shutdown a crosstalk provider
- */
-void
-pciio_provider_shutdown(devfs_handle_t pciio_provider)
-{
-    DEV_FUNC(pciio_provider, provider_shutdown)
-	(pciio_provider);
-}
-
-/*
- * Specify endianness constraints.  The driver tells us what the device
- * does and how it would like to see things in memory.  We reply with
- * how things will actually appear in memory.
- */
-pciio_endian_t
-pciio_endian_set(devfs_handle_t dev,
-		 pciio_endian_t device_end,
-		 pciio_endian_t desired_end)
-{
-    ASSERT((device_end == PCIDMA_ENDIAN_BIG) || (device_end == PCIDMA_ENDIAN_LITTLE));
-    ASSERT((desired_end == PCIDMA_ENDIAN_BIG) || (desired_end == PCIDMA_ENDIAN_LITTLE));
-
-#if DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    printk(KERN_ALERT  "%v: pciio_endian_set is going away.\n"
-	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
-	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
-	    dev);
-#else
-    printk(KERN_ALERT  "0x%x: pciio_endian_set is going away.\n"
-	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
-	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
-	    dev);
-#endif
-#endif
-
-    return DEV_FUNC(dev, endian_set)
-	(dev, device_end, desired_end);
-}
-
-/*
- * Specify PCI arbitration priority.
- */
-pciio_priority_t
-pciio_priority_set(devfs_handle_t dev,
-		   pciio_priority_t device_prio)
-{
-    ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW));
-
-    return DEV_FUNC(dev, priority_set)
-	(dev, device_prio);
-}
-
-/*
- * Read value of configuration register
- */
-uint64_t
-pciio_config_get(devfs_handle_t	dev,
-		 unsigned	reg,
-		 unsigned	size)
-{
-    uint64_t	value = 0;
-    unsigned	shift = 0;
-
-    /* handle accesses that cross words here,
-     * since that's common code between all
-     * possible providers.
-     */
-    while (size > 0) {
-	unsigned	biw = 4 - (reg&3);
-	if (biw > size)
-	    biw = size;
-
-	value |= DEV_FUNC(dev, config_get)
-	    (dev, reg, biw) << shift;
-
-	shift += 8*biw;
-	reg += biw;
-	size -= biw;
-    }
-    return value;
-}
-
-/*
- * Change value of configuration register
- */
-void
-pciio_config_set(devfs_handle_t	dev,
-		 unsigned	reg,
-		 unsigned	size,
-		 uint64_t	value)
-{
-    /* handle accesses that cross words here,
-     * since that's common code between all
-     * possible providers.
-     */
-    while (size > 0) {
-	unsigned	biw = 4 - (reg&3);
-	if (biw > size)
-	    biw = size;
-	    
-	DEV_FUNC(dev, config_set)
-	    (dev, reg, biw, value);
-	reg += biw;
-	size -= biw;
-	value >>= biw * 8;
-    }
-}
-
-/* =====================================================================
- *          GENERIC PCI SUPPORT FUNCTIONS
- */
-
-/*
- * Issue a hardware reset to a card.
- */
-int
-pciio_reset(devfs_handle_t dev)
-{
-    return DEV_FUNC(dev, reset) (dev);
-}
-
-/*
- * flush write gather buffers
- */
-int
-pciio_write_gather_flush(devfs_handle_t dev)
-{
-    return DEV_FUNC(dev, write_gather_flush) (dev);
-}
-
-devfs_handle_t
-pciio_intr_dev_get(pciio_intr_t pciio_intr)
-{
-    return (pciio_intr->pi_dev);
-}
-
-/****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
-pciio_pio_dev_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_dev);
-}
-
-pciio_slot_t
-pciio_pio_slot_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_slot);
-}
-
-pciio_space_t
-pciio_pio_space_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_space);
-}
-
-iopaddr_t
-pciio_pio_pciaddr_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_pciaddr);
-}
-
-ulong
-pciio_pio_mapsz_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_mapsz);
-}
-
-caddr_t
-pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_kvaddr);
-}
-
-/****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
-pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap)
-{
-    return (pciio_dmamap->pd_dev);
-}
-
-pciio_slot_t
-pciio_dma_slot_get(pciio_dmamap_t pciio_dmamap)
-{
-    return (pciio_dmamap->pd_slot);
-}
-
-/****** Generic pci slot information interfaces ******/
-
-pciio_info_t
-pciio_info_chk(devfs_handle_t pciio)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    hwgraph_info_get_LBL(pciio, INFO_LBL_PCIIO, &ainfo);
-    return (pciio_info_t) ainfo;
-}
-
-pciio_info_t
-pciio_info_get(devfs_handle_t pciio)
-{
-    pciio_info_t            pciio_info;
-
-    pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio);
-
-#ifdef DEBUG_PCIIO
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(pciio, dname, 256);
-	printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-    }
-#endif /* DEBUG_PCIIO */
-
-    if ((pciio_info != NULL) &&
-	(pciio_info->c_fingerprint != pciio_info_fingerprint)
-	&& (pciio_info->c_fingerprint != NULL)) {
-
-	return((pciio_info_t)-1); /* Should panic .. */
-    }
-	
-
-    return pciio_info;
-}
-
-void
-pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info)
-{
-    if (pciio_info != NULL)
-	pciio_info->c_fingerprint = pciio_info_fingerprint;
-    hwgraph_fastinfo_set(pciio, (arbitrary_info_t) pciio_info);
-
-    /* Also, mark this vertex as a PCI slot
-     * and use the pciio_info, so pciio_info_chk
-     * can work (and be fairly efficient).
-     */
-    hwgraph_info_add_LBL(pciio, INFO_LBL_PCIIO,
-			 (arbitrary_info_t) pciio_info);
-}
-
-devfs_handle_t
-pciio_info_dev_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_vertex);
-}
-
-pciio_slot_t
-pciio_info_slot_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_slot);
-}
-
-pciio_function_t
-pciio_info_function_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_func);
-}
-
-pciio_vendor_id_t
-pciio_info_vendor_id_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_vendor);
-}
-
-pciio_device_id_t
-pciio_info_device_id_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_device);
-}
-
-devfs_handle_t
-pciio_info_master_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_master);
-}
-
-arbitrary_info_t
-pciio_info_mfast_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_mfast);
-}
-
-pciio_provider_t       *
-pciio_info_pops_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_pops);
-}
-
-error_handler_f	       *
-pciio_info_efunc_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_efunc);
-}
-
-error_handler_arg_t    *
-pciio_info_einfo_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_einfo);
-}
-
-pciio_space_t
-pciio_info_bar_space_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_space;
-}
-
-iopaddr_t
-pciio_info_bar_base_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_base;
-}
-
-size_t
-pciio_info_bar_size_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_size;
-}
-
-iopaddr_t
-pciio_info_rom_base_get(pciio_info_t info)
-{
-    return info->c_rbase;
-}
-
-size_t
-pciio_info_rom_size_get(pciio_info_t info)
-{
-    return info->c_rsize;
-}
-
-
-/* =====================================================================
- *          GENERIC PCI INITIALIZATION FUNCTIONS
- */
-
-/*
- *    pciioinit: called once during device driver
- *      initializtion if this driver is configured into
- *      the system.
- */
-void
-pciio_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("pciio_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (pciio_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_PCI, "vendor", "device");
-	if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(pciio_registry != NULL);
-}
-
-/*
- *    pciioattach: called for each vertex in the graph
- *      that is a PCI provider.
- */
-/*ARGSUSED */
-int
-pciio_attach(devfs_handle_t pciio)
-{
-#if DEBUG && ATTACH_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    printk("%v: pciio_attach\n", pciio);
-#else
-    printk("0x%x: pciio_attach\n", pciio);
-#endif
-#endif
-    return 0;
-}
-
-/*
- * Associate a set of pciio_provider functions with a vertex.
- */
-void
-pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns)
-{
-    hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns);
-}
-
-/*
- * Disassociate a set of pciio_provider functions with a vertex.
- */
-void
-pciio_provider_unregister(devfs_handle_t provider)
-{
-    arbitrary_info_t        ainfo;
-
-    hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, (long *) &ainfo);
-}
-
-/*
- * Obtain a pointer to the pciio_provider functions for a specified Crosstalk
- * provider.
- */
-pciio_provider_t       *
-pciio_provider_fns_get(devfs_handle_t provider)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    (void) hwgraph_info_get_LBL(provider, INFO_LBL_PFUNCS, &ainfo);
-    return (pciio_provider_t *) ainfo;
-}
-
-/*ARGSUSED4 */
-int
-pciio_driver_register(
-			 pciio_vendor_id_t vendor_id,
-			 pciio_device_id_t device_id,
-			 char *driver_prefix,
-			 unsigned flags)
-{
-    /* a driver's init routine might call
-     * pciio_driver_register before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    return cdl_add_driver(pciio_registry,
-			  vendor_id, device_id,
-			  driver_prefix, flags, NULL);
-}
-
-/*
- * Remove an initialization function.
- */
-void
-pciio_driver_unregister(
-			   char *driver_prefix)
-{
-    /* before a driver calls unregister,
-     * it must have called register; so
-     * we can assume we have a registry here.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    cdl_del_driver(pciio_registry, driver_prefix, NULL);
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being registered.
- */
-void
-pciio_driver_reg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being unregistered.
- */
-void
-pciio_driver_unreg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/*
- * Call some function with each vertex that
- * might be one of this driver's attach points.
- */
-void
-pciio_iterate(char *driver_prefix,
-	      pciio_iter_f * func)
-{
-    /* a driver's init routine might call
-     * pciio_iterate before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    ASSERT(pciio_registry != NULL);
-
-    cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func);
-}
-
-devfs_handle_t
-pciio_device_register(
-		devfs_handle_t connectpt,	/* vertex for /hw/.../pciio/%d */
-		devfs_handle_t master,	/* card's master ASIC (PCI provider) */
-		pciio_slot_t slot,	/* card's slot */
-		pciio_function_t func,	/* card's func */
-		pciio_vendor_id_t vendor_id,
-		pciio_device_id_t device_id)
-{
-    return pciio_device_info_register
-	(connectpt, pciio_device_info_new (NULL, master, slot, func,
-					   vendor_id, device_id));
-}
-
-void
-pciio_device_unregister(devfs_handle_t pconn)
-{
-    DEV_FUNC(pconn,device_unregister)(pconn);
-}
-
-pciio_info_t
-pciio_device_info_new(
-		pciio_info_t pciio_info,
-		devfs_handle_t master,
-		pciio_slot_t slot,
-		pciio_function_t func,
-		pciio_vendor_id_t vendor_id,
-		pciio_device_id_t device_id)
-{
-    if (!pciio_info)
-	GET_NEW(pciio_info);
-    ASSERT(pciio_info != NULL);
-
-    pciio_info->c_slot = slot;
-    pciio_info->c_func = func;
-    pciio_info->c_vendor = vendor_id;
-    pciio_info->c_device = device_id;
-    pciio_info->c_master = master;
-    pciio_info->c_mfast = hwgraph_fastinfo_get(master);
-    pciio_info->c_pops = pciio_provider_fns_get(master);
-    pciio_info->c_efunc = 0;
-    pciio_info->c_einfo = 0;
-
-    return pciio_info;
-}
-
-void
-pciio_device_info_free(pciio_info_t pciio_info)
-{
-    /* NOTE : pciio_info is a structure within the pcibr_info
-     *	      and not a pointer to memory allocated on the heap !!
-     */
-    BZERO((char *)pciio_info,sizeof(pciio_info));
-}
-
-devfs_handle_t
-pciio_device_info_register(
-		devfs_handle_t connectpt,		/* vertex at center of bus */
-		pciio_info_t pciio_info)	/* details about the connectpt */
-{
-    char		name[32];
-    devfs_handle_t	pconn;
-    int device_master_set(devfs_handle_t, devfs_handle_t);
-
-    pciio_slot_func_to_name(name,
-			    pciio_info->c_slot,
-			    pciio_info->c_func);
-
-    if (GRAPH_SUCCESS !=
-	hwgraph_path_add(connectpt, name, &pconn))
-	return pconn;
-
-    pciio_info->c_vertex = pconn;
-    pciio_info_set(pconn, pciio_info);
-#ifdef DEBUG_PCIIO
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(pconn, dname, 256);
-	printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);
-    }
-#endif /* DEBUG_PCIIO */
-
-    /*
-     * create link to our pci provider
-     */
-
-    device_master_set(pconn, pciio_info->c_master);
-
-#if USRPCI
-    /*
-     * Call into usrpci provider to let it initialize for
-     * the given slot.
-     */
-    if (pciio_info->c_slot != PCIIO_SLOT_NONE)
-	usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot);
-#endif
-
-    return pconn;
-}
-
-void
-pciio_device_info_unregister(devfs_handle_t connectpt,
-			     pciio_info_t pciio_info)
-{
-    char		name[32];
-    devfs_handle_t	pconn;
-
-    if (!pciio_info)
-	return;
-
-    pciio_slot_func_to_name(name,
-			    pciio_info->c_slot,
-			    pciio_info->c_func);
-
-    hwgraph_edge_remove(connectpt,name,&pconn);
-    pciio_info_set(pconn,0);
-
-    /* Remove the link to our pci provider */
-    hwgraph_edge_remove(pconn, EDGE_LBL_MASTER, NULL);
-
-
-    hwgraph_vertex_unref(pconn);
-    hwgraph_vertex_destroy(pconn);
-    
-}
-/* Add the pci card inventory information to the hwgraph
- */
-static void
-pciio_device_inventory_add(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
-
-    ASSERT(pciio_info);
-    ASSERT(pciio_info->c_vertex == pconn_vhdl);
-
-    /* Donot add inventory  for non-existent devices */
-    if ((pciio_info->c_vendor == PCIIO_VENDOR_ID_NONE)	||
-	(pciio_info->c_device == PCIIO_DEVICE_ID_NONE))
-	return;
-    device_inventory_add(pconn_vhdl,INV_IOBD,INV_PCIADAP,
-			 pciio_info->c_vendor,pciio_info->c_device,
-			 pciio_info->c_slot);
-}
-
-/*ARGSUSED */
-int
-pciio_device_attach(devfs_handle_t pconn,
-		    int          drv_flags)
-{
-    pciio_info_t            pciio_info;
-    pciio_vendor_id_t       vendor_id;
-    pciio_device_id_t       device_id;
-
-
-    pciio_device_inventory_add(pconn);
-    pciio_info = pciio_info_get(pconn);
-
-    vendor_id = pciio_info->c_vendor;
-    device_id = pciio_info->c_device;
-
-    /* we don't start attaching things until
-     * all the driver init routines (including
-     * pciio_init) have been called; so we
-     * can assume here that we have a registry.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags));
-}
-
-int
-pciio_device_detach(devfs_handle_t pconn,
-		    int          drv_flags)
-{
-    pciio_info_t            pciio_info;
-    pciio_vendor_id_t       vendor_id;
-    pciio_device_id_t       device_id;
-
-    pciio_info = pciio_info_get(pconn);
-
-    vendor_id = pciio_info->c_vendor;
-    device_id = pciio_info->c_device;
-
-    /* we don't start attaching things until
-     * all the driver init routines (including
-     * pciio_init) have been called; so we
-     * can assume here that we have a registry.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    return(cdl_del_connpt(pciio_registry, vendor_id, device_id,
-		          pconn, drv_flags));
-
-}
-
-/* SN2 */
-/*
- * Allocate (if necessary) and initialize a PCI window mapping structure.
- */
-pciio_win_map_t
-pciio_device_win_map_new(pciio_win_map_t win_map,
-			 size_t region_size,
-			 size_t page_size)
-{
-	ASSERT((page_size & (page_size - 1)) == 0);
-	ASSERT((region_size & (page_size - 1)) == 0);
-
-	if (win_map == NULL)
-		NEW(win_map);
-
-	/*
-	 * The map array tracks the free ``pages'' in the region.  The worst
-	 * case scenario is when every other page in the region is free --
-	 * e.i. maximum fragmentation.  This leads to (max pages + 1) / 2 + 1
-	 * map entries.  The first "+1" handles the divide by 2 rounding; the
-	 * second handles the need for an end marker sentinel.
-	 */
-	win_map->wm_map = rmallocmap((region_size / page_size + 1) / 2 + 1);
-	win_map->wm_page_size = page_size;
-	ASSERT(win_map->wm_map != NULL);
-
-	return win_map;
-}
-
-/*
- * Free resources associated with a PCI window mapping structure.
- */
-extern void
-pciio_device_win_map_free(pciio_win_map_t win_map)
-{
-	rmfreemap(win_map->wm_map);
-	bzero(win_map, sizeof *win_map);
-}
-
-/*
- * Populate window map with specified free range.
- */
-void
-pciio_device_win_populate(pciio_win_map_t win_map,
-                          iopaddr_t ioaddr,
-                          size_t size)
-{
-	ASSERT((size & (win_map->wm_page_size - 1)) == 0);
-	ASSERT((ioaddr & (win_map->wm_page_size - 1)) == 0);
-
-	rmfree(win_map->wm_map,
-	       size / win_map->wm_page_size,
-	       (unsigned long)ioaddr / win_map->wm_page_size);
-	       
-}
-/*
- * Allocate space from the specified PCI window mapping resource.  On
- * success record information about the allocation in the supplied window
- * allocation cookie (if non-NULL) and return the address of the allocated
- * window.  On failure return NULL.
- *
- * The "size" parameter is usually from a PCI device's Base Address Register
- * (BAR) decoder.  As such, the allocation must be aligned to be a multiple of
- * that.  The "align" parameter acts as a ``minimum alignment'' allocation
- * constraint.  The alignment contraint reflects system or device addressing
- * restrictions such as the inability to share higher level ``windows''
- * between devices, etc.  The returned PCI address allocation will be a
- * multiple of the alignment constraint both in alignment and size.  Thus, the
- * returned PCI address block is aligned to the maximum of the requested size
- * and alignment.
- */
-iopaddr_t
-pciio_device_win_alloc(pciio_win_map_t win_map,
-		       pciio_win_alloc_t win_alloc,
-		       size_t size, size_t align)
-{
-	unsigned long base;
-
-#ifdef PIC_LATER
-	ASSERT((size & (size - 1)) == 0);
-	ASSERT((align & (align - 1)) == 0);
-
-	/*
-	 * Convert size and alignment to pages.  If size is greated than the
-	 * requested alignment, we bump the alignment up to size; otherwise
-	 * convert the size into a multiple of the alignment request.
-	 */
-	size = (size + win_map->wm_page_size - 1) / win_map->wm_page_size;
-	align = align / win_map->wm_page_size;
-	if (size > align)
-		align = size;
-	else
-		size = (size + align - 1) & ~(align - 1);
-
-	/* XXXX */
-	base = rmalloc_align(win_map->wm_map, size, align, VM_NOSLEEP);
-	if (base == RMALLOC_FAIL)
-		return((iopaddr_t)NULL);
-#else
-    int                 index_page, index_page_align;
-    int                 align_pages, size_pages;
-    int                 alloc_pages, free_pages;
-    int                 addr_align;
-
-    /* Convert PCI bus alignment from bytes to pages */
-    align_pages = align / win_map->wm_page_size;
-
-    /* Convert PCI request from bytes to pages */
-    size_pages = (size / win_map->wm_page_size) +
-                  ((size % win_map->wm_page_size) ? 1 : 0);
-
-    /* Align address with the larger of the size or the requested slot align */
-    if (size_pages > align_pages)
-        align_pages = size_pages;
-  
-    /*
-     * Avoid wasting space by aligning - 1; this will prevent crossing
-     * another alignment boundary.
-     */
-    alloc_pages = size_pages + (align_pages - 1);
-
-    /* Allocate PCI bus space in pages */
-    index_page = (int) rmalloc(win_map->wm_map,
-                               (size_t) alloc_pages);
-
-    /* Error if no PCI bus address space available */
-    if (!index_page)
-        return 0;
-
-    /* PCI bus address index starts at 0 */
-    index_page--;
-
-    /* Align the page offset as requested */
-    index_page_align = (index_page + (align_pages - 1)) -
-                       ((index_page + (align_pages - 1)) % align_pages);
-
-    free_pages = (align_pages - 1) - (index_page_align - index_page);
-
-    /* Free unused PCI bus pages adjusting the index to start at 1 */
-    rmfree(win_map->wm_map, 
-           free_pages,
-           (index_page_align + 1) + size_pages);
-
-    /* Return aligned PCI bus space in bytes */ 
-    addr_align = (index_page_align * win_map->wm_page_size); 
-    base = index_page;
-    size = alloc_pages - free_pages;
-#endif	/* PIC_LATER */
-
-	/*
-	 * If a window allocation cookie has been supplied, use it to keep
-	 * track of all the allocated space assigned to this window.
-	 */
-	if (win_alloc) {
-		win_alloc->wa_map = win_map;
-		win_alloc->wa_base = base;
-		win_alloc->wa_pages = size;
-	}
-
-	return base * win_map->wm_page_size;
-}
-
-/*
- * Free the specified window allocation back into the PCI window mapping
- * resource.  As noted above, we keep page addresses offset by 1 ...
- */
-void
-pciio_device_win_free(pciio_win_alloc_t win_alloc)
-{
-	if (win_alloc->wa_pages)
-		rmfree(win_alloc->wa_map->wm_map,
-		       win_alloc->wa_pages,
-		       win_alloc->wa_base);
-}
-
-/*
- * pciio_error_register:
- * arrange for a function to be called with
- * a specified first parameter plus other
- * information when an error is encountered
- * and traced to the pci slot corresponding
- * to the connection point pconn.
- *
- * may also be called with a null function
- * pointer to "unregister" the error handler.
- *
- * NOTE: subsequent calls silently overwrite
- * previous data for this vertex. We assume that
- * cooperating drivers, well, cooperate ...
- */
-void
-pciio_error_register(devfs_handle_t pconn,
-		     error_handler_f *efunc,
-		     error_handler_arg_t einfo)
-{
-    pciio_info_t            pciio_info;
-
-    pciio_info = pciio_info_get(pconn);
-    ASSERT(pciio_info != NULL);
-    pciio_info->c_efunc = efunc;
-    pciio_info->c_einfo = einfo;
-}
-
-/*
- * Check if any device has been found in this slot, and return
- * true or false
- * vhdl is the vertex for the slot
- */
-int
-pciio_slot_inuse(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-
-    ASSERT(pciio_info);
-    ASSERT(pciio_info->c_vertex == pconn_vhdl);
-    if (pciio_info->c_vendor) {
-	/*
-	 * Non-zero value for vendor indicate
-	 * a board being found in this slot.
-	 */
-	return 1;
-    }
-    return 0;
-}
-
-int
-pciio_dma_enabled(devfs_handle_t pconn_vhdl)
-{
-	return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl);
-}
-
-/*
- * These are complementary Linux interfaces that takes in a pci_dev * as the 
- * first arguement instead of devfs_handle_t.
- */
-iopaddr_t               snia_pciio_dmatrans_addr(struct pci_dev *, device_desc_t, paddr_t, size_t, unsigned);
-pciio_dmamap_t          snia_pciio_dmamap_alloc(struct pci_dev *, device_desc_t, size_t, unsigned);
-void                    snia_pciio_dmamap_free(pciio_dmamap_t);
-iopaddr_t               snia_pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
-void                    snia_pciio_dmamap_done(pciio_dmamap_t);
-pciio_endian_t          snia_pciio_endian_set(struct pci_dev *pci_dev, pciio_endian_t device_end,
-					      pciio_endian_t desired_end);
-
-#include <linux/module.h>
-EXPORT_SYMBOL(snia_pciio_dmatrans_addr);
-EXPORT_SYMBOL(snia_pciio_dmamap_alloc);
-EXPORT_SYMBOL(snia_pciio_dmamap_free);
-EXPORT_SYMBOL(snia_pciio_dmamap_addr);
-EXPORT_SYMBOL(snia_pciio_dmamap_done);
-EXPORT_SYMBOL(snia_pciio_endian_set);
-
-int
-snia_pcibr_rrb_alloc(struct pci_dev *pci_dev,
-	int *count_vchan0,
-	int *count_vchan1)
-{
-	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-
-	return pcibr_rrb_alloc(dev, count_vchan0, count_vchan1);
-}
-EXPORT_SYMBOL(snia_pcibr_rrb_alloc);
-
-pciio_endian_t
-snia_pciio_endian_set(struct pci_dev *pci_dev,
-	pciio_endian_t device_end,
-	pciio_endian_t desired_end)
-{
-	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-	
-	return DEV_FUNC(dev, endian_set)
-		(dev, device_end, desired_end);
-}
-
-iopaddr_t
-snia_pciio_dmatrans_addr(struct pci_dev *pci_dev, /* translate for this device */
-                    device_desc_t dev_desc,     /* device descriptor */
-                    paddr_t paddr,      /* system physical address */
-                    size_t byte_count,  /* length */
-                    unsigned flags)
-{                                       /* defined in dma.h */
-
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-
-    return DEV_FUNC(dev, dmatrans_addr)
-        (dev, dev_desc, paddr, byte_count, flags);
-}
-
-pciio_dmamap_t
-snia_pciio_dmamap_alloc(struct pci_dev *pci_dev,  /* set up mappings for this device */
-                   device_desc_t dev_desc,      /* device descriptor */
-                   size_t byte_count_max,       /* max size of a mapping */
-                   unsigned flags)
-{                                       /* defined in dma.h */
-
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-
-    return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-        (dev, dev_desc, byte_count_max, flags);
-}
-
-void
-snia_pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_free)
-        (CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-snia_pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,  /* use these mapping resources */
-                  paddr_t paddr,        /* map for this address */
-                  size_t byte_count)
-{                                       /* map this many bytes */
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_addr)
-        (CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
-}
-
-void
-snia_pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_done)
-        (CAST_DMAMAP(pciio_dmamap));
-}
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/sgi_io_init.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/sgi_io_init.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/sgi_io_init.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/sgi_io_init.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,324 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/pci/pciba.h>
-#include <linux/smp.h>
-
-extern void mlreset(int );
-extern int init_hcl(void);
-extern void klgraph_hack_init(void);
-extern void hubspc_init(void);
-extern void pciio_init(void);
-extern void pcibr_init(void);
-extern void xtalk_init(void);
-extern void xbow_init(void);
-extern void xbmon_init(void);
-extern void pciiox_init(void);
-extern void usrpci_init(void);
-extern void ioc3_init(void);
-extern void initialize_io(void);
-extern void intr_clear_all(nasid_t);
-extern void klhwg_add_all_modules(devfs_handle_t);
-extern void klhwg_add_all_nodes(devfs_handle_t);
-
-void sn_mp_setup(void);
-extern devfs_handle_t hwgraph_root;
-extern void io_module_init(void);
-extern void pci_bus_cvlink_init(void);
-extern void temp_hack(void);
-
-extern int pci_bus_to_hcl_cvlink(void);
-
-/* #define DEBUG_IO_INIT 1 */
-#ifdef DEBUG_IO_INIT
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_IO_INIT */
-
-/*
- * per_hub_init
- *
- * 	This code is executed once for each Hub chip.
- */
-static void
-per_hub_init(cnodeid_t cnode)
-{
-	nasid_t		nasid;
-	nodepda_t	*npdap;
-	ii_icmr_u_t	ii_icmr;
-	ii_ibcr_u_t	ii_ibcr;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	ASSERT(nasid != INVALID_NASID);
-	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
-
-	npdap = NODEPDA(cnode);
-
-	/* initialize per-node synergy perf instrumentation */
-	npdap->synergy_perf_enabled = 0; /* off by default */
-	npdap->synergy_perf_lock = SPIN_LOCK_UNLOCKED;
-	npdap->synergy_perf_freq = SYNERGY_PERF_FREQ_DEFAULT;
-	npdap->synergy_inactive_intervals = 0;
-	npdap->synergy_active_intervals = 0;
-	npdap->synergy_perf_data = NULL;
-	npdap->synergy_perf_first = NULL;
-
-
-	/*
-	 * Set the total number of CRBs that can be used.
-	 */
-	ii_icmr.ii_icmr_regval= 0x0;
-	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xF;
-	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
-
-	/*
-	 * Set the number of CRBs that both of the BTEs combined
-	 * can use minus 1.
-	 */
-	ii_ibcr.ii_ibcr_regval= 0x0;
-	ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
-	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
-
-	/*
-	 * Set CRB timeout to be 10ms.
-	 */
-	REMOTE_HUB_S(nasid, IIO_ICTP, 0x1000 );
-	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
-
-
-	/* Reserve all of the hardwired interrupt levels. */
-	intr_reserve_hardwired(cnode);
-
-	/* Initialize error interrupts for this hub. */
-	hub_error_init(cnode);
-}
-
-/*
- * This routine is responsible for the setup of all the IRIX hwgraph style
- * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
- * is called just before the generic Linux PCI layer does its probing (by 
- * platform_pci_fixup aka sn_pci_fixup).
- *
- * It is very IMPORTANT that this call is only made by the Master CPU!
- *
- */
-
-void
-sgi_master_io_infr_init(void)
-{
-	int cnode;
-
-	/*
-	 * Do any early init stuff .. einit_tbl[] etc.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling init_hcl().\n");
-	init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */
-
-#ifdef Colin
-
-printk("Testing out Xbridge Access .. if it hangs Xbridge is not init yet.\n");
-printk("	Reading Xbridge WID at address 0xc00000080f000000 0x%p\n", (* (volatile uint32_t *)(0xc00000080f000000)));
-
-printk("Testing out PCI Address Space Accesses\n");
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020000 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020000)));
-
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020001 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020001)));
-
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020002 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020002)));
-
-printk("	Testing PCI Config Read Byte: address 0xc00000080f020003 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020003)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020004)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020005 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020005)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020006 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020006)));
-
-printk("        Testing PCI Config Read Byte: address 0xc00000080f020007 value 0x%x\n",(* (volatile uint8_t *)(0xc00000080f020007)));
-
-printk("	Testing PCI Config Word: address 0xc00000080f020004 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020004)));
-
-printk("	Testing PCI Config Word: address 0xc00000080f020008 value 0x%x\n",(* (volatile uint32_t *)(0xc00000080f020008)));
-
-#endif
-
-	/*
-	 * initialize the Linux PCI to xwidget vertexes ..
-	 */
-	DBG("--> sgi_master_io_infr_init: calling pci_bus_cvlink_init().\n");
-	pci_bus_cvlink_init();
-
-#ifdef BRINGUP
-	/*
-	 * Hack to provide statically initialzed klgraph entries.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n");
-	klgraph_hack_init();
-#endif /* BRINGUP */
-
-	/*
-	 * This is the Master CPU.  Emulate mlsetup and main.c in Irix.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling mlreset(0).\n");
-	mlreset(0); /* Master .. */
-
-	/*
-	 * allowboot() is called by kern/os/main.c in main()
-	 * Emulate allowboot() ...
-	 *   per_cpu_init() - only need per_hub_init()
-	 *   cpu_io_setup() - Nothing to do.
-	 * 
-	 */
-	DBG("--> sgi_master_io_infr_init: calling sn_mp_setup().\n");
-	sn_mp_setup();
-
-	DBG("--> sgi_master_io_infr_init: calling per_hub_init(0).\n");
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		per_hub_init(cnode);
-	}
-
-	/* We can do headless hub cnodes here .. */
-
-	/*
-	 * io_init[] stuff.
-	 *
-	 * Get SGI IO Infrastructure drivers to init and register with 
-	 * each other etc.
-	 */
-
-	DBG("--> sgi_master_io_infr_init: calling hubspc_init()\n");
-	hubspc_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pciio_init()\n");
-	pciio_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pcibr_init()\n");
-	pcibr_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xtalk_init()\n");
-	xtalk_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xbow_init()\n");
-	xbow_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xbmon_init()\n");
-	xbmon_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pciiox_init()\n");
-	pciiox_init();
-
-	DBG("--> sgi_master_io_infr_init: calling usrpci_init()\n");
-	usrpci_init();
-
-	DBG("--> sgi_master_io_infr_init: calling ioc3_init()\n");
-	ioc3_init();
-
-	/*
-	 *
-	 * Our IO Infrastructure drivers are in place .. 
-	 * Initialize the whole IO Infrastructure .. xwidget/device probes.
-	 *
-	 */
-	DBG("--> sgi_master_io_infr_init: Start Probe and IO Initialization\n");
-	initialize_io();
-
-	DBG("--> sgi_master_io_infr_init: Setting up SGI IO Links for Linux PCI\n");
-	pci_bus_to_hcl_cvlink();
-
-#ifdef CONFIG_PCIBA
-	DBG("--> sgi_master_io_infr_init: calling pciba_init()\n");
- 	pciba_init();
-#endif
-
-	DBG("--> Leave sgi_master_io_infr_init: DONE setting up SGI Links for PCI\n");
-}
-
-/*
- * sgi_slave_io_infr_init - This routine must be called on all cpus except 
- * the Master CPU.
- */
-void
-sgi_slave_io_infr_init(void)
-{
-	/* Emulate cboot() .. */
-	mlreset(1); /* This is a slave cpu */
-
-	// per_hub_init(0); /* Need to get and send in actual cnode number */
-
-	/* Done */
-}
-
-/*
- * One-time setup for MP SN.
- * Allocate per-node data, slurp prom klconfig information and
- * convert it to hwgraph information.
- */
-void
-sn_mp_setup(void)
-{
-	cnodeid_t	cnode;
-	cpuid_t		cpu;
-
-	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-		/* Skip holes in CPU space */
-		if (cpu_enabled(cpu)) {
-			init_platform_pda(cpu);
-		}
-	}
-
-	/*
-	 * Initialize platform-dependent vertices in the hwgraph:
-	 *	module
-	 *	node
-	 *	cpu
-	 *	memory
-	 *	slot
-	 *	hub
-	 *	router
-	 *	xbow
-	 */
-
-	DBG("sn_mp_io_setup: calling io_module_init()\n");
-	io_module_init(); /* Use to be called module_init() .. */
-
-	DBG("sn_mp_setup: calling klhwg_add_all_modules()\n");
-	klhwg_add_all_modules(hwgraph_root);
-	DBG("sn_mp_setup: calling klhwg_add_all_nodes()\n");
-	klhwg_add_all_nodes(hwgraph_root);
-
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-
-		/*
-		 * This routine clears the Hub's Interrupt registers.
-		 */
-		/*
-		 * We need to move this intr_clear_all() routine 
-		 * from SN/intr.c to a more appropriate file.
-		 * Talk to Al Mayer.
-		 */
-                intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
-		/* now init the hub */
-	//	per_hub_init(cnode);
-
-	}
-
-	synergy_perf_init();
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/xbow.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/xbow.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/xbow.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/xbow.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1086 +0,0 @@
-/* $Id: xbow.c,v 1.3 2002/11/21 17:51:57 jh Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-#include <asm/sn/simulator.h>
-
-/* #define DEBUG		1 */
-/* #define XBOW_DEBUG	1 */
-
-
-/*
- * Files needed to get the device driver entry points
- */
-
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-
-#include <asm/sn/prio.h>
-#include <asm/sn/hcl_util.h>
-
-
-#define NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DEL(ptr)	(kfree(ptr))
-
-int                     xbow_devflag = D_MP;
-
-/*
- * This file supports the Xbow chip.  Main functions: initializtion,
- * error handling, and GBR.
- */
-
-/*
- * each vertex corresponding to an xbow chip
- * has a "fastinfo" pointer pointing at one
- * of these things.
- */
-typedef struct xbow_soft_s *xbow_soft_t;
-
-struct xbow_soft_s {
-    devfs_handle_t            conn;	/* our connection point */
-    devfs_handle_t            vhdl;	/* xbow's private vertex */
-    devfs_handle_t            busv;	/* the xswitch vertex */
-    xbow_t                 *base;	/* PIO pointer to crossbow chip */
-    char                   *name;	/* hwgraph name */
-
-    xbow_perf_t             xbow_perfcnt[XBOW_PERF_COUNTERS];
-    xbow_perf_link_t        xbow_perflink[MAX_XBOW_PORTS];
-    xbow_link_status_t      xbow_link_status[MAX_XBOW_PORTS];
-    spinlock_t              xbow_perf_lock;
-    int                     link_monitor;
-    widget_cfg_t	   *wpio[MAX_XBOW_PORTS];	/* cached PIO pointer */
-
-    /* Bandwidth allocation state. Bandwidth values are for the
-     * destination port since contention happens there.
-     * Implicit mapping from xbow ports (8..f) -> (0..7) array indices.
-     */
-    spinlock_t		    xbow_bw_alloc_lock;		/* bw allocation lock */
-    unsigned long long	    bw_hiwm[MAX_XBOW_PORTS];	/* hiwater mark values */
-    unsigned long long      bw_cur_used[MAX_XBOW_PORTS]; /* bw used currently */
-};
-
-#define xbow_soft_set(v,i)	hwgraph_fastinfo_set((v), (arbitrary_info_t)(i))
-#define xbow_soft_get(v)	((xbow_soft_t)hwgraph_fastinfo_get((v)))
-
-/*
- * Function Table of Contents
- */
-
-void                    xbow_mlreset(xbow_t *);
-void                    xbow_init(void);
-int                     xbow_attach(devfs_handle_t);
-
-int                     xbow_open(devfs_handle_t *, int, int, cred_t *);
-int                     xbow_close(devfs_handle_t, int, int, cred_t *);
-
-int                     xbow_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                     xbow_unmap(devfs_handle_t, vhandl_t *);
-int                     xbow_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
-
-int                     xbow_widget_present(xbow_t *, int);
-static int              xbow_link_alive(xbow_t *, int);
-devfs_handle_t            xbow_widget_lookup(devfs_handle_t, int);
-
-void                    xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
-
-
-
-void                    xbow_update_perf_counters(devfs_handle_t);
-xbow_perf_link_t       *xbow_get_perf_counters(devfs_handle_t);
-int                     xbow_enable_perf_counter(devfs_handle_t, int, int, int);
-xbow_link_status_t     *xbow_get_llp_status(devfs_handle_t);
-void                    xbow_update_llp_status(devfs_handle_t);
-
-int                     xbow_disable_llp_monitor(devfs_handle_t);
-int                     xbow_enable_llp_monitor(devfs_handle_t);
-int                     xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t,
-                                unsigned long long, unsigned long long);
-
-xswitch_reset_link_f    xbow_reset_link;
-
-void                    idbg_xbowregs(int64_t);
-
-xswitch_provider_t      xbow_provider =
-{
-    xbow_reset_link,
-};
-
-/*
- *    xbow_mlreset: called at mlreset time if the
- *      platform specific code determines that there is
- *      a crossbow in a critical path that must be
- *      functional before the driver would normally get
- *      the device properly set up.
- *
- *      what do we need to do, that the boot prom can
- *      not be counted on to have already done, that is
- *      generic across all platforms using crossbows?
- */
-/*ARGSUSED */
-void
-xbow_mlreset(xbow_t * xbow)
-{
-}
-
-/*
- *    xbow_init: called with the rest of the device
- *      driver XXX_init routines. This platform *might*
- *      have a Crossbow chip, or even several, but it
- *      might have none. Register with the crosstalk
- *      generic provider so when we encounter the chip
- *      the right magic happens.
- */
-void
-xbow_init(void)
-{
-
-#if DEBUG && ATTACH_DEBUG
-    printk("xbow_init\n");
-#endif
-
-    xwidget_driver_register(PXBOW_WIDGET_PART_NUM,
-			    0, /* XXBOW_WIDGET_MFGR_NUM, */
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-
-
-    xwidget_driver_register(XXBOW_WIDGET_PART_NUM,
-			    0, /* XXBOW_WIDGET_MFGR_NUM, */
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-
-    xwidget_driver_register(XBOW_WIDGET_PART_NUM,
-			    XBOW_WIDGET_MFGR_NUM,
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-}
-
-#ifdef XBRIDGE_REGS_SIM
-/*    xbow_set_simulated_regs: sets xbow regs as needed
- *	for powering through the boot
- */
-void
-xbow_set_simulated_regs(xbow_t *xbow, int port)
-{
-    /*
-     * turn on link
-     */
-    xbow->xb_link(port).link_status = (1<<31);
-    /*
-     * and give it a live widget too
-     */
-    xbow->xb_link(port).link_aux_status = XB_AUX_STAT_PRESENT;
-    /*
-     * zero the link control reg
-     */
-    xbow->xb_link(port).link_control = 0x0;
-}
-#endif /* XBRIDGE_REGS_SIM */
-
-/*
- *    xbow_attach: the crosstalk provider has
- *      determined that there is a crossbow widget
- *      present, and has handed us the connection
- *      point for that vertex.
- *
- *      We not only add our own vertex, but add
- *      some "xtalk switch" data to the switch
- *      vertex (at the connect point's parent) if
- *      it does not have any.
- */
-
-/*ARGSUSED */
-int
-xbow_attach(devfs_handle_t conn)
-{
-    /*REFERENCED */
-    devfs_handle_t            vhdl;
-    devfs_handle_t            busv;
-    xbow_t                 *xbow;
-    xbow_soft_t             soft;
-    int                     port;
-    xswitch_info_t          info;
-    char                    devnm[MAXDEVNAME], *s;
-    xbowreg_t               id;
-    int                     rev;
-    int			    i;
-    int			    xbow_num;
-	
-#if DEBUG && ATTACH_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    printk("%v: xbow_attach\n", conn);
-#else
-    printk("0x%x: xbow_attach\n", conn);
-#endif
-#endif
-
-    /*
-     * Get a PIO pointer to the base of the crossbow
-     * chip.
-     */
-#ifdef XBRIDGE_REGS_SIM
-    printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: allocating %ld bytes for xbow_s\n", sizeof(xbow_t));
-    xbow = (xbow_t *) kmalloc(sizeof(xbow_t), GFP_KERNEL);
-    /*
-     * turn on ports e and f like in a real live ibrick
-     */
-    xbow_set_simulated_regs(xbow, 0xe);
-    xbow_set_simulated_regs(xbow, 0xf);
-#else
-    xbow = (xbow_t *) xtalk_piotrans_addr(conn, 0, 0, sizeof(xbow_t), 0);
-#endif /* XBRIDGE_REGS_SIM */
-
-    /*
-     * Locate the "switch" vertex: it is the parent
-     * of our connection point.
-     */
-    busv = hwgraph_connectpt_get(conn);
-#if DEBUG && ATTACH_DEBUG
-    printk("xbow_attach: Bus Vertex 0x%p, conn 0x%p, xbow register 0x%p wid= 0x%x\n", busv, conn, xbow, *(volatile u32 *)xbow);
-#endif
-
-    ASSERT(busv != GRAPH_VERTEX_NONE);
-
-    /*
-     * Create our private vertex, and connect our
-     * driver information to it. This makes it possible
-     * for diagnostic drivers to open the crossbow
-     * vertex for access to registers.
-     */
-
-    /*
-     * We need to teach xbow drivers to provide the right set of
-     * file ops.
-     */
-    vhdl = NULL;
-    vhdl = hwgraph_register(conn, EDGE_LBL_XBOW,
-                        0, DEVFS_FL_AUTO_DEVNUM,
-                        0, 0,
-                        S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                        /* &hcl_fops */ (void *)&vhdl, NULL);
-    if (!vhdl) {
-        printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n",
-                (void *)conn);
-    }
-
-    /*
-     * Allocate the soft state structure and attach
-     * it to the xbow's vertex
-     */
-    NEW(soft);
-    soft->conn = conn;
-    soft->vhdl = vhdl;
-    soft->busv = busv;
-    soft->base = xbow;
-    /* does the universe really need another macro?  */
-    /* xbow_soft_set(vhdl, (arbitrary_info_t) soft); */
-    hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft);
-
-#define XBOW_NUM_SUFFIX_FORMAT	"[xbow# %d]"
-
-    /* Add xbow number as a suffix to the hwgraph name of the xbow.
-     * This is helpful while looking at the error/warning messages.
-     */
-    xbow_num = 0;
-
-    /*
-     * get the name of this xbow vertex and keep the info.
-     * This is needed during errors and interupts, but as
-     * long as we have it, we can use it elsewhere.
-     */
-    s = dev_to_name(vhdl, devnm, MAXDEVNAME);
-    soft->name = kmalloc(strlen(s) + strlen(XBOW_NUM_SUFFIX_FORMAT) + 1, 
-			    GFP_KERNEL);
-    sprintf(soft->name,"%s"XBOW_NUM_SUFFIX_FORMAT, s,xbow_num);
-
-#ifdef XBRIDGE_REGS_SIM
-    /* my o200/ibrick has id=0x2d002049, but XXBOW_WIDGET_PART_NUM is defined
-     * as 0xd000, so I'm using that for the partnum bitfield.
-     */
-    printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: need xb_wid_id value!!\n");
-    id = 0x2d000049;
-#else
-    id = xbow->xb_wid_id;
-#endif /* XBRIDGE_REGS_SIM */
-    rev = XWIDGET_PART_REV_NUM(id);
-
-    mutex_spinlock_init(&soft->xbow_perf_lock);
-    soft->xbow_perfcnt[0].xp_perf_reg = &xbow->xb_perf_ctr_a;
-    soft->xbow_perfcnt[1].xp_perf_reg = &xbow->xb_perf_ctr_b;
-
-    /* Initialization for GBR bw allocation */
-    mutex_spinlock_init(&soft->xbow_bw_alloc_lock);
-
-#define	XBOW_8_BIT_PORT_BW_MAX		(400 * 1000 * 1000)	/* 400 MB/s */
-#define XBOW_16_BIT_PORT_BW_MAX		(800 * 1000 * 1000)	/* 800 MB/s */
-
-    /* Set bandwidth hiwatermark and current values */
-    for (i = 0; i < MAX_XBOW_PORTS; i++) {
-	soft->bw_hiwm[i] = XBOW_16_BIT_PORT_BW_MAX;	/* for now */
-	soft->bw_cur_used[i] = 0;
-    }
-
-    /*
-     * Enable xbow error interrupts
-     */
-    xbow->xb_wid_control = (XB_WID_CTRL_REG_ACC_IE | XB_WID_CTRL_XTALK_IE);
-
-    /*
-     * take a census of the widgets present,
-     * leaving notes at the switch vertex.
-     */
-    info = xswitch_info_new(busv);
-
-    for (port = MAX_PORT_NUM - MAX_XBOW_PORTS;
-	 port < MAX_PORT_NUM; ++port) {
-	if (!xbow_link_alive(xbow, port)) {
-#if DEBUG && XBOW_DEBUG
-	    printk(KERN_INFO "0x%p link %d is not alive\n",
-		    busv, port);
-#endif
-	    continue;
-	}
-	if (!xbow_widget_present(xbow, port)) {
-#if DEBUG && XBOW_DEBUG
-	    printk(KERN_INFO "0x%p link %d is alive but no widget is present\n", busv, port);
-#endif
-	    continue;
-	}
-#if DEBUG && XBOW_DEBUG
-	printk(KERN_INFO "0x%p link %d has a widget\n",
-		busv, port);
-#endif
-
-	xswitch_info_link_is_ok(info, port);
-	/*
-	 * Turn some error interrupts on
-	 * and turn others off. The PROM has
-	 * some things turned on we don't
-	 * want to see (bandwidth allocation
-	 * errors for instance); so if it
-	 * is not listed here, it is not on.
-	 */
-	xbow->xb_link(port).link_control =
-	    ( (xbow->xb_link(port).link_control
-	/*
-	 * Turn off these bits; they are non-fatal,
-	 * but we might want to save some statistics
-	 * on the frequency of these errors.
-	 * XXX FIXME XXX
-	 */
-	    & ~XB_CTRL_RCV_CNT_OFLOW_IE
-	    & ~XB_CTRL_XMT_CNT_OFLOW_IE
-	    & ~XB_CTRL_BNDWDTH_ALLOC_IE
-	    & ~XB_CTRL_RCV_IE)
-	/*
-	 * These are the ones we want to turn on.
-	 */
-	    | (XB_CTRL_ILLEGAL_DST_IE
-	    | XB_CTRL_OALLOC_IBUF_IE
-	    | XB_CTRL_XMT_MAX_RTRY_IE
-	    | XB_CTRL_MAXREQ_TOUT_IE
-	    | XB_CTRL_XMT_RTRY_IE
-	    | XB_CTRL_SRC_TOUT_IE) );
-    }
-
-    xswitch_provider_register(busv, &xbow_provider);
-
-    return 0;				/* attach successful */
-}
-
-/*ARGSUSED */
-int
-xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-
-}
-
-/*ARGSUSED */
-int
-xbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    xbow_soft_t             soft = xbow_soft_get(vhdl);
-    int                     error;
-
-    ASSERT(soft);
-    len = ctob(btoc(len));
-    /* XXX- this ignores the offset!!! */
-    error = v_mapphys(vt, (void *) soft->base, len);
-    return error;
-}
-
-/*ARGSUSED */
-int
-xbow_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    return 0;
-}
-
-/* This contains special-case code for grio. There are plans to make
- * this general sometime in the future, but till then this should
- * be good enough.
- */
-xwidgetnum_t
-xbow_widget_num_get(devfs_handle_t dev)
-{
-	devfs_handle_t	tdev;
-	char		devname[MAXDEVNAME];
-	xwidget_info_t	xwidget_info;
-	int		i;
-
-	vertex_to_name(dev, devname, MAXDEVNAME);
-
-	/* If this is a pci controller vertex, traverse up using
-	 * the ".." links to get to the widget.
-	 */
-	if (strstr(devname, EDGE_LBL_PCI) &&
-			strstr(devname, EDGE_LBL_CONTROLLER)) {
-		tdev = dev;
-		for (i=0; i< 2; i++) {
-			if (hwgraph_edge_get(tdev,
-				HWGRAPH_EDGELBL_DOTDOT, &tdev) !=
-					GRAPH_SUCCESS)
-				return XWIDGET_NONE;
-		}
-
-		if ((xwidget_info = xwidget_info_chk(tdev)) != NULL) {
-			return (xwidget_info_id_get(xwidget_info));
-		} else {
-			return XWIDGET_NONE;
-		}
-	}
-
-	return XWIDGET_NONE;
-}
-
-int
-xbow_ioctl(devfs_handle_t dev,
-	   int cmd,
-	   void *arg,
-	   int flag,
-	   struct cred *cr,
-	   int *rvalp)
-{
-    devfs_handle_t            vhdl;
-    int                     error = 0;
-
-#if defined (DEBUG)
-    int                     rc;
-    devfs_handle_t            conn;
-    struct xwidget_info_s  *xwidget_info;
-    xbow_soft_t             xbow_soft;
-#endif
-    *rvalp = 0;
-
-    vhdl = dev_to_vhdl(dev);
-#if defined (DEBUG)
-    xbow_soft = xbow_soft_get(vhdl);
-    conn = xbow_soft->conn;
-
-    xwidget_info = xwidget_info_get(conn);
-    ASSERT_ALWAYS(xwidget_info != NULL);
-
-    rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid);
-    ASSERT_ALWAYS(rc != 0);
-#endif
-    switch (cmd) {
-
-    case XBOWIOC_LLP_ERROR_ENABLE:
-	if ((error = xbow_enable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-    case XBOWIOC_LLP_ERROR_DISABLE:
-
-	if ((error = xbow_disable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-    default:
-	break;
-
-    }
-    return error;
-}
-
-/*
- * xbow_widget_present: See if a device is present
- * on the specified port of this crossbow.
- */
-int
-xbow_widget_present(xbow_t *xbow, int port)
-{
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		if ( (port == 14) || (port == 15) ) {
-			return 1;
-		}
-		else {
-			return 0;
-		}
-	}
-	else {
-		/* WAR: port 0xf on PIC is missing present bit */
-		/* Need this for PIC */
-		if (IS_PIC_XBOW(xbow->xb_wid_id) && port == 0xf) {
-			return 1;
-		}
-		return xbow->xb_link(port).link_aux_status & XB_AUX_STAT_PRESENT;
-	}
-}
-
-static int
-xbow_link_alive(xbow_t * xbow, int port)
-{
-    xbwX_stat_t             xbow_linkstat;
-
-    xbow_linkstat.linkstatus = xbow->xb_link(port).link_status;
-    return (xbow_linkstat.link_alive);
-}
-
-/*
- * xbow_widget_lookup
- *      Lookup the edges connected to the xbow specified, and
- *      retrieve the handle corresponding to the widgetnum
- *      specified.
- *      If not found, return 0.
- */
-devfs_handle_t
-xbow_widget_lookup(devfs_handle_t vhdl,
-		   int widgetnum)
-{
-    xswitch_info_t          xswitch_info;
-    devfs_handle_t            conn;
-
-    xswitch_info = xswitch_info_get(vhdl);
-    conn = xswitch_info_vhdl_get(xswitch_info, widgetnum);
-    return conn;
-}
-
-/*
- * xbow_intr_preset: called during mlreset time
- * if the platform specific code needs to route
- * an xbow interrupt before the xtalk infrastructure
- * is available for use.
- *
- * Also called from xbow_setwidint, so we don't
- * replicate the guts of the routine.
- *
- * XXX- probably should be renamed xbow_wid_intr_set or
- * something to reduce confusion.
- */
-/*ARGSUSED3 */
-void
-xbow_intr_preset(void *which_widget,
-		 int which_widget_intr,
-		 xwidgetnum_t targ,
-		 iopaddr_t addr,
-		 xtalk_intr_vector_t vect)
-{
-    xbow_t                 *xbow = (xbow_t *) which_widget;
-
-    xbow->xb_wid_int_upper = ((0xFF000000 & (vect << 24)) |
-			      (0x000F0000 & (targ << 16)) |
-			      XTALK_ADDR_TO_UPPER(addr));
-    xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
-
-}
-
-int                     xbow_xmit_retry_errors = 0;
-
-int
-xbow_xmit_retry_error(xbow_soft_t soft,
-		      int port)
-{
-    xswitch_info_t          info;
-    devfs_handle_t            vhdl;
-    widget_cfg_t           *wid;
-    widgetreg_t             id;
-    int                     part;
-    int                     mfgr;
-
-    wid = soft->wpio[port - BASE_XBOW_PORT];
-    if (wid == NULL) {
-	/* If we can't track down a PIO
-	 * pointer to our widget yet,
-	 * leave our caller knowing that
-	 * we are interested in this
-	 * interrupt if it occurs in
-	 * the future.
-	 */
-	info = xswitch_info_get(soft->busv);
-	if (!info)
-	    return 1;
-	vhdl = xswitch_info_vhdl_get(info, port);
-	if (vhdl == GRAPH_VERTEX_NONE)
-	    return 1;
-	wid = (widget_cfg_t *) xtalk_piotrans_addr
-	    (vhdl, 0, 0, sizeof *wid, 0);
-	if (!wid)
-	    return 1;
-	soft->wpio[port - BASE_XBOW_PORT] = wid;
-    }
-    id = wid->w_id;
-    part = XWIDGET_PART_NUM(id);
-    mfgr = XWIDGET_MFG_NUM(id);
-
-    /* If this thing is not a Bridge,
-     * do not activate the WAR, and
-     * tell our caller we do not need
-     * to be called again.
-     */
-    if ((part != BRIDGE_WIDGET_PART_NUM) ||
-	(mfgr != BRIDGE_WIDGET_MFGR_NUM)) {
-		/* FIXME: add Xbridge to the WAR.
-		 * Shouldn't hurt anything.  Later need to
-		 * check if we can remove this.
-                 */
-    		if ((part != XBRIDGE_WIDGET_PART_NUM) ||
-		    (mfgr != XBRIDGE_WIDGET_MFGR_NUM))
-			return 0;
-    }
-
-    /* count how many times we
-     * have picked up after
-     * LLP Transmit problems.
-     */
-    xbow_xmit_retry_errors++;
-
-    /* rewrite the control register
-     * to fix things up.
-     */
-    wid->w_control = wid->w_control;
-    wid->w_control;
-
-    return 1;
-}
-
-void
-xbow_update_perf_counters(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
-    xbow_perf_link_t       *xbow_plink = xbow_soft->xbow_perflink;
-    xbow_perfcount_t        perf_reg;
-    unsigned long           s;
-    int                     link, i;
-
-    for (i = 0; i < XBOW_PERF_COUNTERS; i++, xbow_perf++) {
-	if (xbow_perf->xp_mode == XBOW_MONITOR_NONE)
-	    continue;
-
-	s = mutex_spinlock(&xbow_soft->xbow_perf_lock);
-
-	perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg;
-
-	link = perf_reg.xb_perf.link_select;
-
-	(xbow_plink + link)->xlp_cumulative[xbow_perf->xp_curmode] +=
-	    ((perf_reg.xb_perf.count - xbow_perf->xp_current) & XBOW_COUNTER_MASK);
-	xbow_perf->xp_current = perf_reg.xb_perf.count;
-
-	mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-    }
-}
-
-xbow_perf_link_t       *
-xbow_get_perf_counters(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_link_t       *xbow_perf_link = xbow_soft->xbow_perflink;
-
-    return xbow_perf_link;
-}
-
-int
-xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
-    xbow_linkctrl_t         xbow_link_ctrl;
-    xbow_t                 *xbow = xbow_soft->base;
-    xbow_perfcount_t        perf_reg;
-    unsigned long           s;
-    int                     i;
-
-    link -= BASE_XBOW_PORT;
-    if ((link < 0) || (link >= MAX_XBOW_PORTS))
-	return -1;
-
-    if ((mode < XBOW_MONITOR_NONE) || (mode > XBOW_MONITOR_DEST_LINK))
-	return -1;
-
-    if ((counter < 0) || (counter >= XBOW_PERF_COUNTERS))
-	return -1;
-
-    s = mutex_spinlock(&xbow_soft->xbow_perf_lock);
-
-    if ((xbow_perf + counter)->xp_mode && mode) {
-	mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-	return -1;
-    }
-    for (i = 0; i < XBOW_PERF_COUNTERS; i++) {
-	if (i == counter)
-	    continue;
-	if (((xbow_perf + i)->xp_link == link) &&
-	    ((xbow_perf + i)->xp_mode)) {
-	    mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-	    return -1;
-	}
-    }
-    xbow_perf += counter;
-
-    xbow_perf->xp_curlink = xbow_perf->xp_link = link;
-    xbow_perf->xp_curmode = xbow_perf->xp_mode = mode;
-
-    xbow_link_ctrl.xbl_ctrlword = xbow->xb_link_raw[link].link_control;
-    xbow_link_ctrl.xb_linkcontrol.perf_mode = mode;
-    xbow->xb_link_raw[link].link_control = xbow_link_ctrl.xbl_ctrlword;
-
-    perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg;
-    perf_reg.xb_perf.link_select = link;
-    *(xbowreg_t *) xbow_perf->xp_perf_reg = perf_reg.xb_counter_val;
-    xbow_perf->xp_current = perf_reg.xb_perf.count;
-
-    mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-    return 0;
-}
-
-xbow_link_status_t     *
-xbow_get_llp_status(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
-
-    return xbow_llp_status;
-}
-
-void
-xbow_update_llp_status(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
-    xbow_t                 *xbow;
-    xbwX_stat_t             lnk_sts;
-    xbow_aux_link_status_t  aux_sts;
-    int                     link;
-    devfs_handle_t	    xwidget_vhdl;
-    char		   *xwidget_name;	
-
-    xbow = (xbow_t *) xbow_soft->base;
-    for (link = 0; link < MAX_XBOW_PORTS; link++, xbow_llp_status++) {
-	/* Get the widget name corresponding the current link.
-	 * Note : 0 <= link < MAX_XBOW_PORTS(8).
-	 * 	  BASE_XBOW_PORT(0x8) <= xwidget number < MAX_PORT_NUM (0x10)
-	 */
-	xwidget_vhdl = xbow_widget_lookup(xbow_soft->busv,link+BASE_XBOW_PORT);
-	xwidget_name = xwidget_name_get(xwidget_vhdl);
-	aux_sts.aux_linkstatus
-	    = xbow->xb_link_raw[link].link_aux_status;
-	lnk_sts.linkstatus = xbow->xb_link_raw[link].link_status_clr;
-
-	if (lnk_sts.link_alive == 0)
-	    continue;
-
-	xbow_llp_status->rx_err_count +=
-	    aux_sts.xb_aux_linkstatus.rx_err_cnt;
-
-	xbow_llp_status->tx_retry_count +=
-	    aux_sts.xb_aux_linkstatus.tx_retry_cnt;
-
-	if (lnk_sts.linkstatus & ~(XB_STAT_RCV_ERR | XB_STAT_XMT_RTRY_ERR | XB_STAT_LINKALIVE)) {
-#ifdef	LATER
-	    printk(KERN_WARNING  "link %d[%s]: bad status 0x%x\n",
-		    link, xwidget_name, lnk_sts.linkstatus);
-#endif
-	}
-    }
-}
-
-int
-xbow_disable_llp_monitor(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    int                     port;
-
-    for (port = 0; port < MAX_XBOW_PORTS; port++) {
-	xbow_soft->xbow_link_status[port].rx_err_count = 0;
-	xbow_soft->xbow_link_status[port].tx_retry_count = 0;
-    }
-
-    xbow_soft->link_monitor = 0;
-    return 0;
-}
-
-int
-xbow_enable_llp_monitor(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-
-    xbow_soft->link_monitor = 1;
-    return 0;
-}
-
-
-int
-xbow_reset_link(devfs_handle_t xconn_vhdl)
-{
-    xwidget_info_t          widget_info;
-    xwidgetnum_t            port;
-    xbow_t                 *xbow;
-    xbowreg_t               ctrl;
-    xbwX_stat_t             stat;
-    unsigned                itick;
-    unsigned                dtick;
-    static int              ticks_per_ms = 0;
-
-    if (!ticks_per_ms) {
-	itick = get_timestamp();
-	us_delay(1000);
-	ticks_per_ms = get_timestamp() - itick;
-    }
-    widget_info = xwidget_info_get(xconn_vhdl);
-    port = xwidget_info_id_get(widget_info);
-
-#ifdef XBOW_K1PTR			/* defined if we only have one xbow ... */
-    xbow = XBOW_K1PTR;
-#else
-    {
-	devfs_handle_t            xbow_vhdl;
-	xbow_soft_t             xbow_soft;
-
-	hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl);
-	xbow_soft = xbow_soft_get(xbow_vhdl);
-	xbow = xbow_soft->base;
-    }
-#endif
-
-    /*
-     * This requires three PIOs (reset the link, check for the
-     * reset, restore the control register for the link) plus
-     * 10us to wait for the reset. We allow up to 1ms for the
-     * widget to come out of reset before giving up and
-     * returning a failure.
-     */
-    ctrl = xbow->xb_link(port).link_control;
-    xbow->xb_link(port).link_reset = 0;
-    itick = get_timestamp();
-    while (1) {
-	stat.linkstatus = xbow->xb_link(port).link_status;
-	if (stat.link_alive)
-	    break;
-	dtick = get_timestamp() - itick;
-	if (dtick > ticks_per_ms) {
-	    return -1;			/* never came out of reset */
-	}
-	DELAY(2);			/* don't beat on link_status */
-    }
-    xbow->xb_link(port).link_control = ctrl;
-    return 0;
-}
-
-/*
- * Dump xbow registers.
- * input parameter is either a pointer to
- * the xbow chip or the vertex handle for
- * an xbow vertex.
- */
-void
-idbg_xbowregs(int64_t regs)
-{
-    xbow_t                 *xbow;
-    int                     i;
-    xb_linkregs_t          *link;
-
-    xbow = (xbow_t *) regs;
-
-#ifdef LATER
-    qprintf("Printing xbow registers starting at 0x%x\n", xbow);
-    qprintf("wid %x status %x erruppr %x errlower %x control %x timeout %x\n",
-	    xbow->xb_wid_id, xbow->xb_wid_stat, xbow->xb_wid_err_upper,
-	    xbow->xb_wid_err_lower, xbow->xb_wid_control,
-	    xbow->xb_wid_req_timeout);
-    qprintf("intr uppr %x lower %x errcmd %x llp ctrl %x arb_reload %x\n",
-	    xbow->xb_wid_int_upper, xbow->xb_wid_int_lower,
-	    xbow->xb_wid_err_cmdword, xbow->xb_wid_llp,
-	    xbow->xb_wid_arb_reload);
-#endif
-
-    for (i = 8; i <= 0xf; i++) {
-	link = &xbow->xb_link(i);
-#ifdef LATER
-	qprintf("Link %d registers\n", i);
-	qprintf("\tctrl %x stat %x arbuppr %x arblowr %x auxstat %x\n",
-		link->link_control, link->link_status,
-		link->link_arb_upper, link->link_arb_lower,
-		link->link_aux_status);
-#endif
-    }
-}
-
-
-#define XBOW_ARB_RELOAD_TICKS		25
-					/* granularity: 4 MB/s, max: 124 MB/s */
-#define GRANULARITY			((100 * 1000000) / XBOW_ARB_RELOAD_TICKS)
-
-#define XBOW_BYTES_TO_GBR(BYTES_per_s)	(int) (BYTES_per_s / GRANULARITY)
-
-#define XBOW_GBR_TO_BYTES(cnt)		(bandwidth_t) ((cnt) * GRANULARITY)
-
-#define CEILING_BYTES_TO_GBR(gbr, bytes_per_sec)	\
-			((XBOW_GBR_TO_BYTES(gbr) < bytes_per_sec) ? gbr+1 : gbr)
-
-#define XBOW_ARB_GBR_MAX		31
-
-#define ABS(x)				((x > 0) ? (x) : (-1 * x))
-					/* absolute value */
-
-int
-xbow_bytes_to_gbr(bandwidth_t old_bytes_per_sec, bandwidth_t bytes_per_sec)
-{
-    int                     gbr_granted;
-    int                     new_total_gbr;
-    int                     change_gbr;
-    bandwidth_t             new_total_bw;
-
-#ifdef GRIO_DEBUG
-    printk("xbow_bytes_to_gbr: old_bytes_per_sec %lld bytes_per_sec %lld\n",
-		old_bytes_per_sec, bytes_per_sec);
-#endif	/* GRIO_DEBUG */
-
-    gbr_granted = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(old_bytes_per_sec)),
-			old_bytes_per_sec);
-    new_total_bw = old_bytes_per_sec + bytes_per_sec;
-    new_total_gbr = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(new_total_bw)),
-			new_total_bw);
-
-    change_gbr = new_total_gbr - gbr_granted;
-
-#ifdef GRIO_DEBUG
-    printk("xbow_bytes_to_gbr: gbr_granted %d new_total_gbr %d change_gbr %d\n",
-		gbr_granted, new_total_gbr, change_gbr);
-#endif	/* GRIO_DEBUG */
-
-    return (change_gbr);
-}
-
-/* Conversion from GBR to bytes */
-bandwidth_t
-xbow_gbr_to_bytes(int gbr)
-{
-    return (XBOW_GBR_TO_BYTES(gbr));
-}
-
-/* Given the vhdl for the desired xbow, the src and dest. widget ids
- * and the req_bw value, this xbow driver entry point accesses the
- * xbow registers and allocates the desired bandwidth if available.
- *
- * If bandwidth allocation is successful, return success else return failure.
- */
-int
-xbow_prio_bw_alloc(devfs_handle_t vhdl,
-		xwidgetnum_t src_wid,
-		xwidgetnum_t dest_wid,
-		unsigned long long old_alloc_bw,
-		unsigned long long req_bw)
-{
-    xbow_soft_t             soft = xbow_soft_get(vhdl);
-    volatile xbowreg_t     *xreg;
-    xbowreg_t               mask;
-    unsigned long           s;
-    int                     error = 0;
-    bandwidth_t             old_bw_BYTES, req_bw_BYTES;
-    xbowreg_t               old_xreg;
-    int                     old_bw_GBR, req_bw_GBR, new_bw_GBR;
-
-#ifdef GRIO_DEBUG
-    printk("xbow_prio_bw_alloc: vhdl %d src_wid %d dest_wid %d req_bw %lld\n",
-		(int) vhdl, (int) src_wid, (int) dest_wid, req_bw);
-#endif
-
-    ASSERT(XBOW_WIDGET_IS_VALID(src_wid));
-    ASSERT(XBOW_WIDGET_IS_VALID(dest_wid));
-
-    s = mutex_spinlock(&soft->xbow_bw_alloc_lock);
-
-    /* Get pointer to the correct register */
-    xreg = XBOW_PRIO_ARBREG_PTR(soft->base, dest_wid, src_wid);
-
-    /* Get mask for GBR count value */
-    mask = XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(src_wid);
-
-    req_bw_GBR = xbow_bytes_to_gbr(old_alloc_bw, req_bw);
-    req_bw_BYTES = (req_bw_GBR < 0) ? (-1 * xbow_gbr_to_bytes(ABS(req_bw_GBR)))
-		: xbow_gbr_to_bytes(req_bw_GBR);
-
-#ifdef GRIO_DEBUG
-    printk("req_bw %lld req_bw_BYTES %lld req_bw_GBR %d\n",
-		req_bw, req_bw_BYTES, req_bw_GBR);
-#endif	/* GRIO_DEBUG */
-
-    old_bw_BYTES = soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS];
-    old_xreg = *xreg;
-    old_bw_GBR = (((*xreg) & mask) >> XB_ARB_GBR_SHFT(src_wid));
-
-#ifdef GRIO_DEBUG
-    ASSERT(XBOW_BYTES_TO_GBR(old_bw_BYTES) == old_bw_GBR);
-
-    printk("old_bw_BYTES %lld old_bw_GBR %d\n", old_bw_BYTES, old_bw_GBR);
-
-    printk("req_bw_BYTES %lld old_bw_BYTES %lld soft->bw_hiwm %lld\n",
-		req_bw_BYTES, old_bw_BYTES,
-		soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]);
-	   
-#endif				/* GRIO_DEBUG */
-
-    /* Accept the request only if we don't exceed the destination
-     * port HIWATER_MARK *AND* the max. link GBR arbitration count
-     */
-    if (((old_bw_BYTES + req_bw_BYTES) <=
-		soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]) &&
-		(req_bw_GBR + old_bw_GBR <= XBOW_ARB_GBR_MAX)) {
-
-	new_bw_GBR = (old_bw_GBR + req_bw_GBR);
-
-	/* Set this in the xbow link register */
-	*xreg = (old_xreg & ~mask) | \
-	    (new_bw_GBR << XB_ARB_GBR_SHFT(src_wid) & mask);
-
-	soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS] =
-			xbow_gbr_to_bytes(new_bw_GBR);
-    } else {
-	error = 1;
-    }
-
-    mutex_spinunlock(&soft->xbow_bw_alloc_lock, s);
-
-    return (error);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn1/xtalk.c linux-2.4.22-pre10/arch/ia64/sn/io/sn1/xtalk.c
--- linux-2.4.21/arch/ia64/sn/io/sn1/xtalk.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn1/xtalk.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1003 +0,0 @@
-/* $Id: xtalk.c,v 1.2 2002/11/21 17:51:57 jh Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-
-/*
- * Implement crosstalk provider operations.  The xtalk* layer provides a
- * platform-independent interface for crosstalk devices.  This layer
- * switches among the possible implementations of a crosstalk adapter.
- *
- * On platforms with only one possible xtalk provider, macros can be
- * set up at the top that cause the table lookups and indirections to
- * completely disappear.
- */
-
-#define	NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define	DEL(ptr)	(kfree(ptr))
-
-char                    widget_info_fingerprint[] = "widget_info";
-
-cdl_p                   xtalk_registry = NULL;
-
-#define	DEV_FUNC(dev,func)	hub_##func
-#define	CAST_PIOMAP(x)		((hub_piomap_t)(x))
-#define	CAST_DMAMAP(x)		((hub_dmamap_t)(x))
-#define	CAST_INTR(x)		((hub_intr_t)(x))
-
-/* =====================================================================
- *            Function Table of Contents
- */
-xtalk_piomap_t          xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);
-void                    xtalk_piomap_free(xtalk_piomap_t);
-caddr_t                 xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t);
-void                    xtalk_piomap_done(xtalk_piomap_t);
-caddr_t                 xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned);
-caddr_t                 xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);
-void                    xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *);
-caddr_t                 xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
-static caddr_t          null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
-xtalk_dmamap_t          xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    xtalk_dmamap_free(xtalk_dmamap_t);
-iopaddr_t               xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t);
-alenlist_t              xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned);
-void                    xtalk_dmamap_done(xtalk_dmamap_t);
-iopaddr_t               xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void			xtalk_dmamap_drain(xtalk_dmamap_t);
-void			xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t);
-void			xtalk_dmalist_drain(devfs_handle_t, alenlist_t);
-xtalk_intr_t            xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t);
-xtalk_intr_t            xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t);
-void                    xtalk_intr_free(xtalk_intr_t);
-int                     xtalk_intr_connect(xtalk_intr_t, xtalk_intr_setfunc_t, void *);
-void                    xtalk_intr_disconnect(xtalk_intr_t);
-devfs_handle_t            xtalk_intr_cpu_get(xtalk_intr_t);
-int                     xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
-int                     xtalk_error_devenable(devfs_handle_t, int, int);
-void                    xtalk_provider_startup(devfs_handle_t);
-void                    xtalk_provider_shutdown(devfs_handle_t);
-devfs_handle_t            xtalk_intr_dev_get(xtalk_intr_t);
-xwidgetnum_t            xtalk_intr_target_get(xtalk_intr_t);
-xtalk_intr_vector_t     xtalk_intr_vector_get(xtalk_intr_t);
-iopaddr_t               xtalk_intr_addr_get(struct xtalk_intr_s *);
-void                   *xtalk_intr_sfarg_get(xtalk_intr_t);
-devfs_handle_t            xtalk_pio_dev_get(xtalk_piomap_t);
-xwidgetnum_t            xtalk_pio_target_get(xtalk_piomap_t);
-iopaddr_t               xtalk_pio_xtalk_addr_get(xtalk_piomap_t);
-ulong                   xtalk_pio_mapsz_get(xtalk_piomap_t);
-caddr_t                 xtalk_pio_kvaddr_get(xtalk_piomap_t);
-devfs_handle_t            xtalk_dma_dev_get(xtalk_dmamap_t);
-xwidgetnum_t            xtalk_dma_target_get(xtalk_dmamap_t);
-xwidget_info_t          xwidget_info_chk(devfs_handle_t);
-xwidget_info_t          xwidget_info_get(devfs_handle_t);
-void                    xwidget_info_set(devfs_handle_t, xwidget_info_t);
-devfs_handle_t            xwidget_info_dev_get(xwidget_info_t);
-xwidgetnum_t            xwidget_info_id_get(xwidget_info_t);
-devfs_handle_t            xwidget_info_master_get(xwidget_info_t);
-xwidgetnum_t            xwidget_info_masterid_get(xwidget_info_t);
-xwidget_part_num_t      xwidget_info_part_num_get(xwidget_info_t);
-xwidget_mfg_num_t       xwidget_info_mfg_num_get(xwidget_info_t);
-char 			*xwidget_info_name_get(xwidget_info_t);
-void                    xtalk_init(void);
-void                    xtalk_provider_register(devfs_handle_t, xtalk_provider_t *);
-void                    xtalk_provider_unregister(devfs_handle_t);
-xtalk_provider_t       *xtalk_provider_fns_get(devfs_handle_t);
-int                     xwidget_driver_register(xwidget_part_num_t, 
-						xwidget_mfg_num_t, 
-						char *, unsigned);
-void                    xwidget_driver_unregister(char *);
-int                     xwidget_register(xwidget_hwid_t, devfs_handle_t, 
-					 xwidgetnum_t, devfs_handle_t, 
-					 xwidgetnum_t, async_attach_t);
-int			xwidget_unregister(devfs_handle_t);
-void                    xwidget_reset(devfs_handle_t);
-char			*xwidget_name_get(devfs_handle_t);
-#if !defined(DEV_FUNC)
-/*
- * There is more than one possible provider
- * for this platform. We need to examine the
- * master vertex of the current vertex for
- * a provider function structure, and indirect
- * through the appropriately named member.
- */
-#define	DEV_FUNC(dev,func)	xwidget_to_provider_fns(dev)->func
-#define	CAST_PIOMAP(x)		((xtalk_piomap_t)(x))
-#define	CAST_DMAMAP(x)		((xtalk_dmamap_t)(x))
-#define	CAST_INTR(x)		((xtalk_intr_t)(x))
-
-static xtalk_provider_t *
-xwidget_to_provider_fns(devfs_handle_t xconn)
-{
-    xwidget_info_t          widget_info;
-    xtalk_provider_t       *provider_fns;
-
-    widget_info = xwidget_info_get(xconn);
-    ASSERT(widget_info != NULL);
-
-    provider_fns = xwidget_info_pops_get(widget_info);
-    ASSERT(provider_fns != NULL);
-
-    return (provider_fns);
-}
-#endif
-
-/*
- * Many functions are not passed their vertex
- * information directly; rather, they must
- * dive through a resource map. These macros
- * are available to coordinate this detail.
- */
-#define	PIOMAP_FUNC(map,func)	DEV_FUNC(map->xp_dev,func)
-#define	DMAMAP_FUNC(map,func)	DEV_FUNC(map->xd_dev,func)
-#define	INTR_FUNC(intr,func)	DEV_FUNC(intr_hdl->xi_dev,func)
-
-/* =====================================================================
- *                    PIO MANAGEMENT
- *
- *      For mapping system virtual address space to
- *      xtalk space on a specified widget
- */
-
-xtalk_piomap_t
-xtalk_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
-		   size_t byte_count,
-		   size_t byte_count_max,	/* maximum size of a mapping */
-		   unsigned flags)
-{				/* defined in sys/pio.h */
-    return (xtalk_piomap_t) DEV_FUNC(dev, piomap_alloc)
-	(dev, dev_desc, xtalk_addr, byte_count, byte_count_max, flags);
-}
-
-
-void
-xtalk_piomap_free(xtalk_piomap_t xtalk_piomap)
-{
-    PIOMAP_FUNC(xtalk_piomap, piomap_free)
-	(CAST_PIOMAP(xtalk_piomap));
-}
-
-
-caddr_t
-xtalk_piomap_addr(xtalk_piomap_t xtalk_piomap,	/* mapping resources */
-		  iopaddr_t xtalk_addr,		/* map for this xtalk address */
-		  size_t byte_count)
-{				/* map this many bytes */
-    return PIOMAP_FUNC(xtalk_piomap, piomap_addr)
-	(CAST_PIOMAP(xtalk_piomap), xtalk_addr, byte_count);
-}
-
-
-void
-xtalk_piomap_done(xtalk_piomap_t xtalk_piomap)
-{
-    PIOMAP_FUNC(xtalk_piomap, piomap_done)
-	(CAST_PIOMAP(xtalk_piomap));
-}
-
-
-caddr_t
-xtalk_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    iopaddr_t xtalk_addr,	/* Crosstalk address */
-		    size_t byte_count,	/* map this many bytes */
-		    unsigned flags)
-{				/* (currently unused) */
-    return DEV_FUNC(dev, piotrans_addr)
-	(dev, dev_desc, xtalk_addr, byte_count, flags);
-}
-
-caddr_t
-xtalk_pio_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       iopaddr_t addr,		/* starting address (or offset in window) */
-	       size_t byte_count,	/* map this many bytes */
-	       xtalk_piomap_t *mapp,	/* where to return the map pointer */
-	       unsigned flags)
-{					/* PIO flags */
-    xtalk_piomap_t          map = 0;
-    caddr_t                 res;
-
-    if (mapp)
-	*mapp = 0;			/* record "no map used" */
-
-    res = xtalk_piotrans_addr
-	(dev, dev_desc, addr, byte_count, flags);
-    if (res)
-	return res;			/* xtalk_piotrans worked */
-
-    map = xtalk_piomap_alloc
-	(dev, dev_desc, addr, byte_count, byte_count, flags);
-    if (!map)
-	return res;			/* xtalk_piomap_alloc failed */
-
-    res = xtalk_piomap_addr
-	(map, addr, byte_count);
-    if (!res) {
-	xtalk_piomap_free(map);
-	return res;			/* xtalk_piomap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* xtalk_piomap_addr succeeded */
-}
-
-/* =====================================================================
- *            EARLY PIOTRANS SUPPORT
- *
- *      There are places where drivers (mgras, for instance)
- *      need to get PIO translations before the infrastructure
- *      is extended to them (setting up textports, for
- *      instance). These drivers should call
- *      xtalk_early_piotrans_addr with their xtalk ID
- *      information, a sequence number (so we can use the second
- *      mgras for instance), and the usual piotrans parameters.
- *
- *      Machine specific code should provide an implementation
- *      of early_piotrans_addr, and present a pointer to this
- *      function to xtalk_set_early_piotrans_addr so it can be
- *      used by clients without the clients having to know what
- *      platform or what xtalk provider is in use.
- */
-
-static xtalk_early_piotrans_addr_f null_xtalk_early_piotrans_addr;
-
-xtalk_early_piotrans_addr_f *impl_early_piotrans_addr = null_xtalk_early_piotrans_addr;
-
-/* xtalk_set_early_piotrans_addr:
- * specify the early_piotrans_addr implementation function.
- */
-void
-xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *impl)
-{
-    impl_early_piotrans_addr = impl;
-}
-
-/* xtalk_early_piotrans_addr:
- * figure out a PIO address for the "nth" crosstalk widget that
- * matches the specified part and mfgr number. Returns NULL if
- * there is no such widget, or if the requested mapping can not
- * be constructed.
- * Limitations on which crosstalk slots (and busses) are
- * checked, and definitions of the ordering of the search across
- * the crosstalk slots, are defined by the platform.
- */
-caddr_t
-xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
-			  xwidget_mfg_num_t mfg_num,
-			  int which,
-			  iopaddr_t xtalk_addr,
-			  size_t byte_count,
-			  unsigned flags)
-{
-    return impl_early_piotrans_addr
-	(part_num, mfg_num, which, xtalk_addr, byte_count, flags);
-}
-
-/* null_xtalk_early_piotrans_addr:
- * used as the early_piotrans_addr implementation until and
- * unless a real implementation is provided. In DEBUG kernels,
- * we want to know who is calling before the implementation is
- * registered; in non-DEBUG kernels, return NULL representing
- * lack of mapping support.
- */
-/*ARGSUSED */
-static caddr_t
-null_xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
-			       xwidget_mfg_num_t mfg_num,
-			       int which,
-			       iopaddr_t xtalk_addr,
-			       size_t byte_count,
-			       unsigned flags)
-{
-#if DEBUG
-    PRINT_PANIC("null_xtalk_early_piotrans_addr");
-#endif
-    return NULL;
-}
-
-/* =====================================================================
- *                    DMA MANAGEMENT
- *
- *      For mapping from crosstalk space to system
- *      physical space.
- */
-
-xtalk_dmamap_t
-xtalk_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   size_t byte_count_max,	/* max size of a mapping */
-		   unsigned flags)
-{				/* defined in dma.h */
-    return (xtalk_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-	(dev, dev_desc, byte_count_max, flags);
-}
-
-
-void
-xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap)
-{
-    DMAMAP_FUNC(xtalk_dmamap, dmamap_free)
-	(CAST_DMAMAP(xtalk_dmamap));
-}
-
-
-iopaddr_t
-xtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap,	/* use these mapping resources */
-		  paddr_t paddr,	/* map for this address */
-		  size_t byte_count)
-{				/* map this many bytes */
-    return DMAMAP_FUNC(xtalk_dmamap, dmamap_addr)
-	(CAST_DMAMAP(xtalk_dmamap), paddr, byte_count);
-}
-
-
-alenlist_t
-xtalk_dmamap_list(xtalk_dmamap_t xtalk_dmamap,	/* use these mapping resources */
-		  alenlist_t alenlist,	/* map this Address/Length List */
-		  unsigned flags)
-{
-    return DMAMAP_FUNC(xtalk_dmamap, dmamap_list)
-	(CAST_DMAMAP(xtalk_dmamap), alenlist, flags);
-}
-
-
-void
-xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap)
-{
-    DMAMAP_FUNC(xtalk_dmamap, dmamap_done)
-	(CAST_DMAMAP(xtalk_dmamap));
-}
-
-
-iopaddr_t
-xtalk_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    paddr_t paddr,	/* system physical address */
-		    size_t byte_count,	/* length */
-		    unsigned flags)
-{				/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_addr)
-	(dev, dev_desc, paddr, byte_count, flags);
-}
-
-
-alenlist_t
-xtalk_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    alenlist_t palenlist,	/* system address/length list */
-		    unsigned flags)
-{				/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-	(dev, dev_desc, palenlist, flags);
-}
-
-void
-xtalk_dmamap_drain(xtalk_dmamap_t map)
-{
-    DMAMAP_FUNC(map, dmamap_drain)
-	(CAST_DMAMAP(map));
-}
-
-void
-xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
-{
-    DEV_FUNC(dev, dmaaddr_drain)
-	(dev, addr, size);
-}
-
-void
-xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list)
-{
-    DEV_FUNC(dev, dmalist_drain)
-	(dev, list);
-}
-
-/* =====================================================================
- *                    INTERRUPT MANAGEMENT
- *
- *      Allow crosstalk devices to establish interrupts
- */
-
-/*
- * Allocate resources required for an interrupt as specified in intr_desc.
- * Return resource handle in intr_hdl.
- */
-xtalk_intr_t
-xtalk_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
-		 device_desc_t dev_desc,	/* device descriptor */
-		 devfs_handle_t owner_dev)
-{				/* owner of this interrupt */
-    return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc)
-	(dev, dev_desc, owner_dev);
-}
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Unconditionally setup resources to be non-threaded.
- * Return resource handle in intr_hdl.
- */
-xtalk_intr_t
-xtalk_intr_alloc_nothd(devfs_handle_t dev,	/* which Crosstalk device */
-		 	device_desc_t dev_desc,	/* device descriptor */
-		 	devfs_handle_t owner_dev)	/* owner of this interrupt */
-{
-    return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd)
-	(dev, dev_desc, owner_dev);
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-xtalk_intr_free(xtalk_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_free)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/*
- * Associate resources allocated with a previous xtalk_intr_alloc call with the
- * described handler, arg, name, etc.
- *
- * Returns 0 on success, returns <0 on failure.
- */
-int
-xtalk_intr_connect(xtalk_intr_t intr_hdl,	/* xtalk intr resource handle */
-		   xtalk_intr_setfunc_t setfunc,	/* func to set intr hw */
-		   void *setfunc_arg)	/* arg to setfunc */
-{
-    return INTR_FUNC(intr_hdl, intr_connect)
-	(CAST_INTR(intr_hdl), setfunc, setfunc_arg);
-}
-
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-xtalk_intr_disconnect(xtalk_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_disconnect)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-xtalk_intr_cpu_get(xtalk_intr_t intr_hdl)
-{
-    return INTR_FUNC(intr_hdl, intr_cpu_get)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/* =====================================================================
- *                    CONFIGURATION MANAGEMENT
- */
-
-/*
- * Startup a crosstalk provider
- */
-void
-xtalk_provider_startup(devfs_handle_t xtalk_provider)
-{
-    DEV_FUNC(xtalk_provider, provider_startup)
-	(xtalk_provider);
-}
-
-
-/*
- * Shutdown a crosstalk provider
- */
-void
-xtalk_provider_shutdown(devfs_handle_t xtalk_provider)
-{
-    DEV_FUNC(xtalk_provider, provider_shutdown)
-	(xtalk_provider);
-}
-
-/* 
- * Enable a device on a xtalk widget 
- */
-void
-xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum)
-{
-    DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum);
-}
-
-/* 
- * Shutdown a device on a xtalk widget 
- */
-void
-xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum)
-{
-    DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum);
-}
-
-int
-xtalk_dma_enabled(devfs_handle_t xconn_vhdl)
-{
-    return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl);
-}
-/*
- * Generic crosstalk functions, for use with all crosstalk providers
- * and all crosstalk devices.
- */
-
-/****** Generic crosstalk interrupt interfaces ******/
-devfs_handle_t
-xtalk_intr_dev_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_dev);
-}
-
-xwidgetnum_t
-xtalk_intr_target_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_target);
-}
-
-xtalk_intr_vector_t
-xtalk_intr_vector_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_vector);
-}
-
-iopaddr_t
-xtalk_intr_addr_get(struct xtalk_intr_s *xtalk_intr)
-{
-    return (xtalk_intr->xi_addr);
-}
-
-void                   *
-xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_sfarg);
-}
-
-/****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
-xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_dev);
-}
-
-xwidgetnum_t
-xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_target);
-}
-
-iopaddr_t
-xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_xtalk_addr);
-}
-
-ulong
-xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_mapsz);
-}
-
-caddr_t
-xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_kvaddr);
-}
-
-
-/****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
-xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap)
-{
-    return (xtalk_dmamap->xd_dev);
-}
-
-xwidgetnum_t
-xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap)
-{
-    return (xtalk_dmamap->xd_target);
-}
-
-
-/****** Generic crosstalk widget information interfaces ******/
-
-/* xwidget_info_chk:
- * check to see if this vertex is a widget;
- * if so, return its widget_info (if any).
- * if not, return NULL.
- */
-xwidget_info_t
-xwidget_info_chk(devfs_handle_t xwidget)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    hwgraph_info_get_LBL(xwidget, INFO_LBL_XWIDGET, &ainfo);
-    return (xwidget_info_t) ainfo;
-}
-
-
-xwidget_info_t
-xwidget_info_get(devfs_handle_t xwidget)
-{
-    xwidget_info_t          widget_info;
-
-    widget_info = (xwidget_info_t)
-	hwgraph_fastinfo_get(xwidget);
-
-#ifdef	LATER
-    if ((widget_info != NULL) &&
-	(widget_info->w_fingerprint != widget_info_fingerprint))
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	PRINT_PANIC("%v bad xwidget_info", xwidget);
-#else
-	PRINT_PANIC("%x bad xwidget_info", xwidget);
-#endif
-#endif	/* LATER */
-
-    return (widget_info);
-}
-
-void
-xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info)
-{
-    if (widget_info != NULL)
-	widget_info->w_fingerprint = widget_info_fingerprint;
-
-    hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) widget_info);
-
-    /* Also, mark this vertex as an xwidget,
-     * and use the widget_info, so xwidget_info_chk
-     * can work (and be fairly efficient).
-     */
-    hwgraph_info_add_LBL(xwidget, INFO_LBL_XWIDGET,
-			 (arbitrary_info_t) widget_info);
-}
-
-devfs_handle_t
-xwidget_info_dev_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_vertex);
-}
-
-xwidgetnum_t
-xwidget_info_id_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_id);
-}
-
-
-devfs_handle_t
-xwidget_info_master_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_master);
-}
-
-xwidgetnum_t
-xwidget_info_masterid_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_masterid);
-}
-
-xwidget_part_num_t
-xwidget_info_part_num_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_hwid.part_num);
-}
-
-xwidget_mfg_num_t
-xwidget_info_mfg_num_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_hwid.mfg_num);
-}
-/* Extract the widget name from the widget information
- * for the xtalk widget.
- */
-char *
-xwidget_info_name_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget info");
-    return(xwidget_info->w_name);
-}
-/****** Generic crosstalk initialization interfaces ******/
-
-/*
- * One-time initialization needed for systems that support crosstalk.
- */
-void
-xtalk_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("xtalk_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (xtalk_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr");
-	if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(xtalk_registry != NULL);
-}
-
-/*
- * Associate a set of xtalk_provider functions with a vertex.
- */
-void
-xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns)
-{
-    hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns);
-}
-
-/*
- * Disassociate a set of xtalk_provider functions with a vertex.
- */
-void
-xtalk_provider_unregister(devfs_handle_t provider)
-{
-    hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL);
-}
-
-/*
- * Obtain a pointer to the xtalk_provider functions for a specified Crosstalk
- * provider.
- */
-xtalk_provider_t       *
-xtalk_provider_fns_get(devfs_handle_t provider)
-{
-    return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider));
-}
-
-/*
- * Announce a driver for a particular crosstalk part.
- * Returns 0 on success or -1 on failure.  Failure occurs if the
- * specified hardware already has a driver.
- */
-/*ARGSUSED4 */
-int
-xwidget_driver_register(xwidget_part_num_t part_num,
-			xwidget_mfg_num_t mfg_num,
-			char *driver_prefix,
-			unsigned flags)
-{
-    /* a driver's init routine could call
-     * xwidget_driver_register before the
-     * system calls xtalk_init; so, we
-     * make the call here.
-     */
-    if (xtalk_registry == NULL)
-	xtalk_init();
-
-    return cdl_add_driver(xtalk_registry,
-			  part_num, mfg_num,
-			  driver_prefix, flags, NULL);
-}
-
-/*
- * Inform xtalk infrastructure that a driver is no longer available for
- * handling any widgets.
- */
-void
-xwidget_driver_unregister(char *driver_prefix)
-{
-    /* before a driver calls unregister,
-     * it must have called registger; so we
-     * can assume we have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_del_driver(xtalk_registry, driver_prefix, NULL);
-}
-
-/*
- * Call some function with each vertex that
- * might be one of this driver's attach points.
- */
-void
-xtalk_iterate(char *driver_prefix,
-	      xtalk_iter_f *func)
-{
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func);
-}
-
-/*
- * xwidget_register:
- *	Register a xtalk device (xwidget) by doing the following.
- *      -allocate and initialize xwidget_info data
- *      -allocate a hwgraph vertex with name based on widget number (id)
- *      -look up the widget's initialization function and call it,
- *      or remember the vertex for later initialization.
- *
- */
-int
-xwidget_register(xwidget_hwid_t hwid,		/* widget's hardware ID */
-		 devfs_handle_t 	widget,		/* widget to initialize */
-		 xwidgetnum_t 	id,		/* widget's target id (0..f) */
-		 devfs_handle_t 	master,		/* widget's master vertex */
-		 xwidgetnum_t 	targetid,	/* master's target id (9/a) */
-		 async_attach_t aa)
-{			
-    xwidget_info_t          widget_info;
-    char		    *s,devnm[MAXDEVNAME];
-
-    /* Allocate widget_info and associate it with widget vertex */
-    NEW(widget_info);
-
-    /* Initialize widget_info */
-    widget_info->w_vertex = widget;
-    widget_info->w_id = id;
-    widget_info->w_master = master;
-    widget_info->w_masterid = targetid;
-    widget_info->w_hwid = *hwid;	/* structure copy */
-    widget_info->w_efunc = 0;
-    widget_info->w_einfo = 0;
-    /*
-     * get the name of this xwidget vertex and keep the info.
-     * This is needed during errors and interupts, but as
-     * long as we have it, we can use it elsewhere.
-     */
-    s = dev_to_name(widget,devnm,MAXDEVNAME);
-    widget_info->w_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
-    strcpy(widget_info->w_name,s);
-    
-    xwidget_info_set(widget, widget_info);
-
-    device_master_set(widget, master);
-
-    /* All the driver init routines (including
-     * xtalk_init) are called before we get into
-     * attaching devices, so we can assume we
-     * have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
-    /* 
-     * Add pointer to async attach info -- tear down will be done when
-     * the particular descendant is done with the info.
-     */
-    if (aa)
-	    async_attach_add_info(widget, aa);
-
-    return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
-                          widget, 0);
-}
-
-/*
- * xwidget_unregister :
- *	Unregister the xtalk device and detach all its hwgraph namespace.
- */
-int
-xwidget_unregister(devfs_handle_t widget)
-{
-    xwidget_info_t	widget_info;
-    xwidget_hwid_t	hwid;
-
-    /* Make sure that we have valid widget information initialized */
-    if (!(widget_info = xwidget_info_get(widget)))
-	return(1);
-
-    /* Remove the inventory information associated
-     * with the widget.
-     */
-    hwgraph_inventory_remove(widget, -1, -1, -1, -1, -1);
-    
-    hwid = &(widget_info->w_hwid);
-
-    cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
-                   widget, 0);
-
-    /* Clean out the xwidget information */
-    (void)kfree(widget_info->w_name);
-    BZERO((void *)widget_info, sizeof(widget_info));
-    DEL(widget_info);
-    
-    return(0);
-}
-
-/*
- * Issue a link reset to a widget.
- */
-void
-xwidget_reset(devfs_handle_t xwidget)
-{
-    xswitch_reset_link(xwidget);
-
-}
-
-
-void
-xwidget_gfx_reset(devfs_handle_t xwidget)
-{
-    xwidget_info_t info;
-
-    xswitch_reset_link(xwidget);
-    info = xwidget_info_get(xwidget);
-#ifdef LATER
-    ASSERT_ALWAYS(info != NULL);
-#endif
-
-    /*
-     * Enable this for other architectures once we add widget_reset to the
-     * xtalk provider interface.
-     */
-    DEV_FUNC(xtalk_provider, widget_reset)
-	(xwidget_info_master_get(info), xwidget_info_id_get(info));
-}
-
-#define ANON_XWIDGET_NAME	"No Name"	/* Default Widget Name */
-
-/* Get the canonical hwgraph  name of xtalk widget */
-char *
-xwidget_name_get(devfs_handle_t xwidget_vhdl)
-{
-	xwidget_info_t  info;
-
-	/* If we have a bogus widget handle then return
-	 * a default anonymous widget name.
-	 */
-	if (xwidget_vhdl == GRAPH_VERTEX_NONE)
-	    return(ANON_XWIDGET_NAME);
-	/* Read the widget name stored in the widget info
-	 * for the widget setup during widget initialization.
-	 */
-	info = xwidget_info_get(xwidget_vhdl);
-	ASSERT(info != NULL);
-	return(xwidget_info_name_get(info));
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/Makefile linux-2.4.22-pre10/arch/ia64/sn/io/sn2/Makefile
--- linux-2.4.21/arch/ia64/sn/io/sn2/Makefile	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/Makefile	2003-08-01 13:34:18.000000000 +0000
@@ -3,7 +3,7 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
 #
 # Makefile for the sn2 io routines.
 
@@ -15,13 +15,11 @@
 
 obj-y				+= ml_SN_intr.o shub_intr.o shuberror.o shub.o \
 				   bte_error.o pcibr/pcibr.o pic.o geo_op.o \
-				   l1.o l1_command.o klconflib.o klgraph.o \
+				   l1_command.o klconflib.o klgraph.o \
 				   ml_SN_init.o ml_iograph.o module.o pciio.o \
-				   xbow.o xtalk.o \
-				   pci_bus_cvlink.o sgi_io_init.o shubio.o
+				   xbow.o xtalk.o shubio.o
+obj-$(CONFIG_KDB)		+= kdba_io.o
 
 subdir-y			+= pcibr
 
-obj-$(CONFIG_SHUB_1_0_SPECIFIC) += efi-rtc.o
-
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/bte_error.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/bte_error.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/bte_error.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/bte_error.c	2003-08-01 13:33:20.000000000 +0000
@@ -1,10 +1,35 @@
-/* $Id: bte_error.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+/*
  *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 
 
@@ -29,121 +54,208 @@
 #include <asm/sn/sn2/shubio.h>
 #include <asm/sn/bte.h>
 
-/************************************************************************
- *									*
- * 			 BTE ERROR RECOVERY				*
- *									*
- * Given a BTE error, the node causing the error must do the following: *
- *    a) Clear all crbs relating to that BTE				*
- *		1) Read CRBA value for crb in question			*
- *		2) Mark CRB as VALID, store local physical 		*
- *		   address known to be good in the address field	*
- *		   (bte_notification_targ is a known good local		*
- *		    address).						*
- *		3) Write CRBA						*
- *		4) Using ICCR, FLUSH the CRB, and wait for it to 	*
- *		   complete.						*
- *		... BTE BUSY bit should now be clear (or at least 	*
- *		    should be after ALL CRBs associated with the 	*
- *		    transfer are complete.				*
- *									*
- *    b) Re-enable BTE							*
- *		1) Write IMEM with BTE Enable + XXX bits
- *		2) Write IECLR with BTE clear bits
- *		3) Clear IIDSR INT_SENT bits.
- *									*
- ************************************************************************/
-
-/* 
- * >>> bte_crb_error_handler needs to be broken into two parts.  The
- * first should cleanup the CRB.  The second should wait until all bte
- * related CRB's are complete and then do the error reset.
+
+/*
+ * Bte error handling is done in two parts.  The first captures
+ * any crb related errors.  Since there can be multiple crbs per
+ * interface and multiple interfaces active, we need to wait until
+ * all active crbs are completed.  This is the first job of the
+ * second part error handler.  When all bte related CRBs are cleanly
+ * completed, it resets the interfaces and gets them ready for new
+ * transfers to be queued.
  */
-void
-bte_crb_error_handler(devfs_handle_t hub_v, int btenum, 
-		      int crbnum, ioerror_t *ioe, int bteop)
+
+
+void bte_error_handler(unsigned long);
+
+
 /*
- * Function: 	bte_crb_error_handler
- * Purpose:	Process a CRB for a specific HUB/BTE
- * Parameters:	hub_v	- vertex of hub in HW graph
- *		btenum	- bte number on hub (0 == a, 1 == b)
- *		crbnum	- crb number being processed
- * Notes: 
- *	This routine assumes serialization at a higher level. A CRB 
- *	should not be processed more than once. The error recovery 
- *	follows the following sequence - if you change this, be real
- *	sure about what you are doing. 
- *
+ * First part error handler.  This is called whenever any error CRB interrupt
+ * is generated by the II.
  */
+void
+bte_crb_error_handler(vertex_hdl_t hub_v, int btenum,
+		      int crbnum, ioerror_t * ioe, int bteop)
 {
-        hubinfo_t	hinfo;
-	icrba_t		crba; 
-	icrbb_t		crbb; 
-	nasid_t		n;
-	hubreg_t	iidsr, imem, ieclr;
+	hubinfo_t hinfo;
+	struct bteinfo_s *bte;
+
 
 	hubinfo_get(hub_v, &hinfo);
+	bte = &hinfo->h_nodepda->bte_if[btenum];
+
+	/*
+	 * The caller has already figured out the error type, we save that
+	 * in the bte handle structure for the thread excercising the
+	 * interface to consume.
+	 */
+	switch (ioe->ie_errortype) {
+	case IIO_ICRB_ECODE_PERR:
+		bte->bh_error = BTEFAIL_POISON;
+		break;
+	case IIO_ICRB_ECODE_WERR:
+		bte->bh_error = BTEFAIL_PROT;
+		break;
+	case IIO_ICRB_ECODE_AERR:
+		bte->bh_error = BTEFAIL_ACCESS;
+		break;
+	case IIO_ICRB_ECODE_TOUT:
+		bte->bh_error = BTEFAIL_TOUT;
+		break;
+	case IIO_ICRB_ECODE_XTERR:
+		bte->bh_error = BTEFAIL_XTERR;
+		break;
+	case IIO_ICRB_ECODE_DERR:
+		bte->bh_error = BTEFAIL_DIR;
+		break;
+	case IIO_ICRB_ECODE_PWERR:
+	case IIO_ICRB_ECODE_PRERR:
+		/* NO BREAK */
+	default:
+		bte->bh_error = BTEFAIL_ERROR;
+	}
+
+	bte->bte_error_count++;
 
+	BTE_PRINTK(("Got an error on cnode %d bte %d\n",
+		    bte->bte_cnode, bte->bte_num));
+	bte_error_handler((unsigned long) hinfo->h_nodepda);
+}
 
-	n = hinfo->h_nasid;
-	
 
+/*
+ * Second part error handler.  Wait until all BTE related CRBs are completed
+ * and then reset the interfaces.
+ */
+void
+bte_error_handler(unsigned long _nodepda)
+{
+	struct nodepda_s *err_nodepda = (struct nodepda_s *) _nodepda;
+	spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock;
+	struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer;
+	nasid_t nasid;
+	int i;
+	int valid_crbs;
+	unsigned long irq_flags;
+	volatile u64 *notify;
+	bte_result_t bh_error;
+	ii_imem_u_t imem;	/* II IMEM Register */
+	ii_icrb0_d_u_t icrbd;	/* II CRB Register D */
+	ii_ibcr_u_t ibcr;
+	ii_icmr_u_t icmr;
+
+
+	BTE_PRINTK(("bte_error_handler(%p) - %d\n", err_nodepda,
+		    smp_processor_id()));
+
+	spin_lock_irqsave(recovery_lock, irq_flags);
+
+	if ((err_nodepda->bte_if[0].bh_error == BTE_SUCCESS) &&
+	    (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) {
+		BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda,
+			    smp_processor_id()));
+		spin_unlock_irqrestore(recovery_lock, irq_flags);
+		return;
+	}
 	/*
-	 * The following 10 lines (or so) are adapted from IRIXs
-	 * bte_crb_error function.  No clear documentation tells
-	 * why the crb needs to complete normally in order for
-	 * the BTE to resume normal operations.  This first step
-	 * appears vital!
+	 * Lock all interfaces on this node to prevent new transfers
+	 * from being queued.
 	 */
+	for (i = 0; i < BTES_PER_NODE; i++) {
+		if (err_nodepda->bte_if[i].cleanup_active) {
+			continue;
+		}
+		spin_lock(&err_nodepda->bte_if[i].spinlock);
+		BTE_PRINTK(("eh:%p:%d locked %d\n", err_nodepda,
+			    smp_processor_id(), i));
+		err_nodepda->bte_if[i].cleanup_active = 1;
+	}
+
+	/* Determine information about our hub */
+	nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode);
+
 
 	/*
-	 * Zero error and error code to prevent error_dump complaining
-	 * about these CRBs. Copy the CRB to the notification line.
-	 * The crb address is in shub format (physical address shifted
-	 * right by cacheline size).
+	 * A BTE transfer can use multiple CRBs.  We need to make sure
+	 * that all the BTE CRBs are complete (or timed out) before
+	 * attempting to clean up the error.  Resetting the BTE while
+	 * there are still BTE CRBs active will hang the BTE.
+	 * We should look at all the CRBs to see if they are allocated
+	 * to the BTE and see if they are still active.  When none
+	 * are active, we can continue with the cleanup.
+	 *
+	 * We also want to make sure that the local NI port is up.
+	 * When a router resets the NI port can go down, while it
+	 * goes through the LLP handshake, but then comes back up.
 	 */
-	crbb.ii_icrb0_b_regval = REMOTE_HUB_L(n, IIO_ICRB_B(crbnum));
-	crbb.b_error=0;
-	crbb.b_ecode=0;
-	REMOTE_HUB_S(n, IIO_ICRB_B(crbnum), crbb.ii_icrb0_b_regval);
-
-	crba.ii_icrb0_a_regval = REMOTE_HUB_L(n, IIO_ICRB_A(crbnum));
-	crba.a_addr = TO_PHYS((u64)&nodepda->bte_if[btenum].notify) >> 3;
-	crba.a_valid = 1;
-	REMOTE_HUB_S(n, IIO_ICRB_A(crbnum), crba.ii_icrb0_a_regval);
-
-	REMOTE_HUB_S(n, IIO_ICCR, 
-		     IIO_ICCR_PENDING | IIO_ICCR_CMD_FLUSH | crbnum);
-
-	while (REMOTE_HUB_L(n, IIO_ICCR) & IIO_ICCR_PENDING)
-	    ;
-
-
-	/* Terminate the BTE. */
-	/* >>> The other bte transfer will need to be restarted. */
-	HUB_L((shubreg_t *)((nodepda->bte_if[btenum].bte_base_addr +
-		       IIO_IBCT0 - IIO_IBLS0)));
-
-	imem = REMOTE_HUB_L(n, IIO_IMEM);
-	ieclr = REMOTE_HUB_L(n, IIO_IECLR);
-	if (btenum == 0) {
-		imem |= IIO_IMEM_W0ESD | IIO_IMEM_B0ESD;
-		ieclr|= IECLR_BTE0;
-	} else {
-		imem |= IIO_IMEM_W0ESD | IIO_IMEM_B1ESD;
-		ieclr|= IECLR_BTE1;
-	}
-	REMOTE_HUB_S(n, IIO_IMEM, imem);
-	REMOTE_HUB_S(n, IIO_IECLR, ieclr);
-		
-	iidsr  = REMOTE_HUB_L(n, IIO_IIDSR);
-	iidsr &= ~IIO_IIDSR_SENT_MASK;
-	iidsr |= IIO_IIDSR_ENB_MASK;
-	REMOTE_HUB_S(n, IIO_IIDSR, iidsr);
+	icmr.ii_icmr_regval = REMOTE_HUB_L(nasid, IIO_ICMR);
+	if (icmr.ii_icmr_fld_s.i_crb_mark != 0) {
+		/*
+		 * There are errors which still need to be cleaned up by
+		 * hubiio_crb_error_handler
+		 */
+		mod_timer(recovery_timer, HZ * 5);
+		BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
+			    smp_processor_id()));
+		spin_unlock_irqrestore(recovery_lock, irq_flags);
+		return;
+	}
+	if (icmr.ii_icmr_fld_s.i_crb_vld != 0) {
 
+		valid_crbs = icmr.ii_icmr_fld_s.i_crb_vld;
 
- 	bte_reset_nasid(n);
+		for (i = 0; i < IIO_NUM_CRBS; i++) {
+			if (!((1 << i) & valid_crbs)) {
+				/* This crb was not marked as valid, ignore */
+				continue;
+			}
+			icrbd.ii_icrb0_d_regval =
+			    REMOTE_HUB_L(nasid, IIO_ICRB_D(i));
+			if (icrbd.d_bteop) {
+				mod_timer(recovery_timer, HZ * 5);
+				BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n",
+					 err_nodepda, smp_processor_id(), i));
+				spin_unlock_irqrestore(recovery_lock,
+						       irq_flags);
+				return;
+			}
+		}
+	}
 
-	*nodepda->bte_if[btenum].most_rcnt_na = IBLS_ERROR;
-}
 
+	BTE_PRINTK(("eh:%p:%d Cleaning up\n", err_nodepda,
+		    smp_processor_id()));
+	/* Reenable both bte interfaces */
+	imem.ii_imem_regval = REMOTE_HUB_L(nasid, IIO_IMEM);
+	imem.ii_imem_fld_s.i_b0_esd = imem.ii_imem_fld_s.i_b1_esd = 1;
+	REMOTE_HUB_S(nasid, IIO_IMEM, imem.ii_imem_regval);
+
+	/* Reinitialize both BTE state machines. */
+	ibcr.ii_ibcr_regval = REMOTE_HUB_L(nasid, IIO_IBCR);
+	ibcr.ii_ibcr_fld_s.i_soft_reset = 1;
+	REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval);
+
+
+	for (i = 0; i < BTES_PER_NODE; i++) {
+		bh_error = err_nodepda->bte_if[i].bh_error;
+		if (bh_error != BTE_SUCCESS) {
+			/* There is an error which needs to be notified */
+			notify = err_nodepda->bte_if[i].most_rcnt_na;
+			BTE_PRINTK(("cnode %d bte %d error=0x%lx\n",
+				    err_nodepda->bte_if[i].bte_cnode,
+				    err_nodepda->bte_if[i].bte_num,
+				    IBLS_ERROR | (u64) bh_error));
+			*notify = IBLS_ERROR | bh_error;
+			err_nodepda->bte_if[i].bh_error = BTE_SUCCESS;
+		}
+
+		err_nodepda->bte_if[i].cleanup_active = 0;
+		BTE_PRINTK(("eh:%p:%d Unlocked %d\n", err_nodepda,
+			    smp_processor_id(), i));
+		spin_unlock(&pda.cpu_bte_if[i]->spinlock);
+	}
+
+	del_timer(recovery_timer);
+
+	spin_unlock_irqrestore(recovery_lock, irq_flags);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/efi-rtc.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/efi-rtc.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/efi-rtc.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/efi-rtc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,202 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
- * Copyright (C) 2001 by Ralf Baechle
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/efi.h>
-#include <asm/sn/klclock.h>
-
-/*
- * No locking necessary when this is called from efirtc which protects us
- * from racing by efi_rtc_lock.
- */
-#define __swizzle(addr) ((u8 *)((unsigned long)(addr) ^ 3))
-#define read_io_port(addr) (*(volatile u8 *) __swizzle(addr))
-#define write_io_port(addr, data) (*(volatile u8 *) __swizzle(addr) = (data))
-
-#define TOD_SGS_M48T35		1
-#define TOD_DALLAS_DS1386	2
-
-#define TYPE_IOC3		1
-#define TYPE_IOC4		2
-
-static unsigned long nvram_base = 0;
-static int tod_chip_type;
-static int ioc_type;
-
-static int
-get_tod_chip_type(void)
-{
-	unsigned char testval;
-
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-	write_io_port(RTC_DAL_DAY_ADDR, 0xff);
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-
-	testval = read_io_port(RTC_DAL_DAY_ADDR);
-	if (testval == 0xff)
-		return TOD_SGS_M48T35;
-
-	return TOD_DALLAS_DS1386;
-}
-
-efi_status_t
-ioc3_get_time(efi_time_t *time, efi_time_cap_t *caps)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	memset(time, 0, sizeof(*time));
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_READ_PROTECT);
-
-		time->year = BCD_TO_INT(read_io_port(RTC_SGS_YEAR_ADDR)) + YRREF;
-		time->month = BCD_TO_INT(read_io_port(RTC_SGS_MONTH_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_SGS_DATE_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_SGS_HOUR_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_SGS_MIN_ADDR));
-		time->second = BCD_TO_INT(read_io_port(RTC_SGS_SEC_ADDR));
-		time->nanosecond = 0;
-
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-
-		time->nanosecond = 0;
-		time->second = BCD_TO_INT(read_io_port(RTC_DAL_SEC_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_DAL_MIN_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_DAL_HOUR_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_DAL_DATE_ADDR));
-		time->month = BCD_TO_INT(read_io_port(RTC_DAL_MONTH_ADDR));
-		time->year = BCD_TO_INT(read_io_port(RTC_DAL_YEAR_ADDR)) + YRREF;
-
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	if (caps) {
-		caps->resolution = 50000000;	/*  50PPM */
-		caps->accuracy = 1000;		/*  1ms */
-		caps->sets_to_zero = 0;
-	}
-
-	return EFI_SUCCESS;
-}
-
-static efi_status_t ioc3_set_time (efi_time_t *t)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_WRITE_ENABLE);
-        	write_io_port(RTC_SGS_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_SGS_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_SGS_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_SGS_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_SGS_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_SGS_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-		write_io_port(RTC_DAL_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_DAL_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_DAL_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_DAL_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_DAL_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_DAL_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	return EFI_SUCCESS;
-}
-
-/* The following two are not supported atm.  */
-static efi_status_t
-ioc3_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-static efi_status_t
-ioc3_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-static __init int efi_ioc_time_init(void)
-{
-	struct pci_dev *dev = NULL;
-	static void *ioc_base;
-
-        while ( (dev = pci_find_subsys(PCI_VENDOR_ID_SGI,
-                               PCI_ANY_ID,
-                               PCI_ANY_ID,
-                               PCI_ANY_ID, dev))) {
-		if ( dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-			ioc_type = TYPE_IOC3;
-			break;
-		}
-		else if ( dev->device == PCI_DEVICE_ID_SGI_IOC4 ) {
-			ioc_type = TYPE_IOC4;
-			break;
-		}
-		else
-			;; // keep looking
-	}
-
-	if ( !dev ) {
-		printk(KERN_CRIT "Couldn't find master IOC\n");
-		return -ENODEV;
-	}
-
-	ioc_base = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0));
-	if ( ioc_type == TYPE_IOC3 )
-		nvram_base = (unsigned long) ioc_base + IOC3_BYTEBUS_DEV0;
-	if ( ioc_type == TYPE_IOC4 )
-		nvram_base = (unsigned long) ioc_base + IOC4_BYTEBUS_DEV0;
-
-	tod_chip_type = get_tod_chip_type();
-	if (tod_chip_type == 1)
-		printk(KERN_NOTICE "TOD type is SGS M48T35\n");
-	else if (tod_chip_type == 2)
-		printk(KERN_NOTICE "TOD type is Dallas DS1386\n");
-	else
-		printk(KERN_CRIT "No or unknown TOD\n");
-
-	efi.get_time = ioc3_get_time;
-	efi.set_time = ioc3_set_time;
-	efi.get_wakeup_time = ioc3_get_wakeup_time;
-	efi.set_wakeup_time = ioc3_set_wakeup_time;
-
-	return 0;
-}
-
-module_init(efi_ioc_time_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/geo_op.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/geo_op.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/geo_op.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/geo_op.c	2003-08-01 13:31:21.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/kdba_io.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/kdba_io.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/kdba_io.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/kdba_io.c	2003-08-01 13:35:08.000000000 +0000
@@ -0,0 +1,76 @@
+/*
+ * Kernel Debugger Architecture Dependent POD functions.
+ *
+ * Copyright (C) 1999-2003 Silicon Graphics, Inc.  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA  94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#include <linux/types.h>
+#include <linux/kdb.h>
+//#include <linux/kdbprivate.h>
+
+/**
+ * kdba_io - enter POD mode from kdb
+ * @argc: arg count
+ * @argv: arg values
+ * @envp: kdb env. vars
+ * @regs: current register state
+ *
+ * Enter POD mode from kdb using SGI SN specific SAL function call.
+ */
+static int
+kdba_io(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+	kdb_printf("kdba_io entered with addr 0x%p\n", (void *) regs);
+
+        return(0);
+}
+
+/**
+ * kdba_io_init - register 'io' command with kdb
+ *
+ * Register the 'io' command with kdb at load time.
+ */
+void
+kdba_io_init(void)
+{
+        kdb_register("io", kdba_io, "<vaddr>", "Display IO Contents", 0);
+}
+
+/**
+ * kdba_io_exit - unregister the 'io' command
+ *
+ * Tell kdb that the 'io' command is no longer available.
+ */
+static void __exit
+kdba_exit(void)
+{
+        kdb_unregister("io");
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/klconflib.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/klconflib.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/klconflib.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/klconflib.c	2003-08-01 13:34:26.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -24,8 +24,6 @@
 #include <asm/sn/router.h>
 #include <asm/sn/xtalk/xbow.h>
 
-#define printf printk
-int hasmetarouter;
 
 #define LDEBUG 0
 #define NIC_UNKNOWN ((nic_t) -1)
@@ -37,10 +35,11 @@
 #define DBG(x...)
 #endif /* DEBUG_KLGRAPH */
 
-static void sort_nic_names(lboard_t *) ;
-
 u64 klgraph_addr[MAX_COMPACT_NODES];
-int module_number = 0;
+static int hasmetarouter;
+
+
+char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#=012345";
 
 lboard_t *
 find_lboard(lboard_t *start, unsigned char brd_type)
@@ -135,23 +134,6 @@
         return (lboard_t *)NULL;
 }
 
-lboard_t *
-find_lboard_module_class(lboard_t *start, geoid_t geoid,
-                                                unsigned char brd_type)
-{
-	while (start) {
-		DBG("find_lboard_module_class: lboard 0x%p, start->brd_geoid 0x%x, mod 0x%x, start->brd_type 0x%x, brd_type 0x%x\n", start, start->brd_geoid, geoid, start->brd_type, brd_type);
-
-		if (geo_cmp(start->brd_geoid, geoid) &&
-			(KLCLASS(start->brd_type) == KLCLASS(brd_type)))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
 /*
  * Convert a NIC name to a name for use in the hardware graph.
  */
@@ -205,63 +187,6 @@
 }
 
 /*
- * Find the lboard structure and get the board name.
- * If we can't find the structure or it's too low a revision,
- * use default name.
- */
-lboard_t *
-get_board_name(nasid_t nasid, geoid_t geoid, slotid_t slot, char *name)
-{
-	lboard_t *brd;
-
-	brd = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid),
-				  geoid);
-
-#ifndef _STANDALONE
-	{
-		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
-
-		if (!brd && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-			brd = find_lboard_modslot((lboard_t *)
-				KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				geoid);
-	}
-#endif
-
-	if (!brd || (brd->brd_sversion < 2)) {
-		strcpy(name, EDGE_LBL_XWIDGET);
-	} else {
-		nic_name_convert(brd->brd_name, name);
-	}
-
-	/*
-	 * PV # 540860
-	 * If the name is not 'baseio'
-	 * get the lowest of all the names in the nic string.
-	 * This is needed for boards like divo, which can have
-	 * a bunch of daughter cards, but would like to be called
-	 * divo. We could do this for baseio
-	 * but it has some special case names that we would not
-	 * like to disturb at this point.
-	 */
-
-	/* gfx boards don't need any of this name scrambling */
-	if (brd && (KLCLASS(brd->brd_type) == KLCLASS_GFX)) {
-		return(brd);
-	}
-
-	if (!(!strcmp(name, "baseio") )) {
-		if (brd) {
-			sort_nic_names(brd) ;
-			/* Convert to small case, '-' to '_' etc */
-			nic_name_convert(brd->brd_name, name) ;
-		}
-	}
-
-	return(brd);
-}
-
-/*
  * get_actual_nasid
  *
  *	Completely disabled brds have their klconfig on 
@@ -341,12 +266,20 @@
 			board_name = EDGE_LBL_IO;
 			break;
 		case KLCLASS_IOBRICK:
-			if (brd->brd_type == KLTYPE_PBRICK)
+			if (brd->brd_type == KLTYPE_PXBRICK)
+				board_name = EDGE_LBL_PXBRICK;
+			else if (brd->brd_type == KLTYPE_IXBRICK)
+				board_name = EDGE_LBL_IXBRICK;
+			else if (brd->brd_type == KLTYPE_PBRICK)
 				board_name = EDGE_LBL_PBRICK;
 			else if (brd->brd_type == KLTYPE_IBRICK)
 				board_name = EDGE_LBL_IBRICK;
 			else if (brd->brd_type == KLTYPE_XBRICK)
 				board_name = EDGE_LBL_XBRICK;
+			else if (brd->brd_type == KLTYPE_PEBRICK)
+				board_name = EDGE_LBL_PEBRICK;
+			else if (brd->brd_type == KLTYPE_CGBRICK)
+				board_name = EDGE_LBL_CGBRICK;
 			else
 				board_name = EDGE_LBL_IOBRICK;
 			break;
@@ -623,185 +556,6 @@
 
 #include "asm/sn/sn_private.h"
 
-xwidgetnum_t
-nodevertex_widgetnum_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, 
-			     (arbitrary_info_t *) &hubinfo_p);
-	return(hubinfo_p->h_widgetid);
-}
-
-devfs_handle_t
-nodevertex_xbow_peer_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-	nasid_t xbow_peer_nasid;
-	cnodeid_t xbow_peer;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO,
-				     (arbitrary_info_t *) &hubinfo_p);
-	xbow_peer_nasid = hubinfo_p->h_nodepda->xbow_peer;
-	if(xbow_peer_nasid == INVALID_NASID) 
-			return ( (devfs_handle_t)-1);
-	xbow_peer = NASID_TO_COMPACT_NODEID(xbow_peer_nasid);
-	return(NODEPDA(xbow_peer)->node_vertex);
-}
-
-/* NIC Sorting Support */
-
-#define MAX_NICS_PER_STRING 	32
-#define MAX_NIC_NAME_LEN	32
-
-static char *
-get_nic_string(lboard_t *lb)
-{
-        int         	i;
-        klinfo_t    	*k = NULL ;
-    	klconf_off_t    mfg_off = 0 ;
-    	char            *mfg_nic = NULL ;
-
-        for (i = 0; i < KLCF_NUM_COMPS(lb); i++) {
-                k = KLCF_COMP(lb, i) ;
-                switch(k->struct_type) {
-                        case KLSTRUCT_BRI:
-            			mfg_off = ((klbri_t *)k)->bri_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_HUB:
-            			mfg_off = ((klhub_t *)k)->hub_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_ROU:
-            			mfg_off = ((klrou_t *)k)->rou_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GFX:
-            			mfg_off = ((klgfx_t *)k)->gfx_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_TPU:
-            			mfg_off = ((kltpu_t *)k)->tpu_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GSN_A:
-                        case KLSTRUCT_GSN_B:
-            			mfg_off = ((klgsn_t *)k)->gsn_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_XTHD:
-                                mfg_off = ((klxthd_t *)k)->xthd_mfg_nic ;
-                                break;
-
-			default:
-				mfg_off = 0 ;
-                                break ;
-                }
-		if (mfg_off)
-			break ;
-        }
-
-	if ((mfg_off) && (k))
-		mfg_nic = (char *)NODE_OFFSET_TO_K0(k->nasid, mfg_off) ;
-
-        return mfg_nic ;
-}
-
-char *
-get_first_string(char **ptrs, int n)
-{
-        int     i ;
-        char    *tmpptr ;
-
-        if ((ptrs == NULL) || (n == 0))
-                return NULL ;
-
-        tmpptr = ptrs[0] ;
-
-        if (n == 1)
-                return tmpptr ;
-
-        for (i = 0 ; i < n ; i++) {
-                if (strcmp(tmpptr, ptrs[i]) > 0)
-                        tmpptr = ptrs[i] ;
-        }
-
-        return tmpptr ;
-}
-
-int
-get_ptrs(char *idata, char **ptrs, int n, char *label)
-{
-        int     i = 0 ;
-        char    *tmp = idata ;
-
-        if ((ptrs == NULL) || (idata == NULL) || (label == NULL) || (n == 0))
-                return 0 ;
-
-        while  ( (tmp = strstr(tmp, label)) ){
-                tmp += strlen(label) ;
-                /* check for empty name field, and last NULL ptr */
-                if ((i < (n-1)) && (*tmp != ';')) {
-                        ptrs[i++] = tmp ;
-                }
-        }
-
-        ptrs[i] = NULL ;
-
-        return i ;
-}
-
-/*
- * sort_nic_names
- *
- * 	Does not really do sorting. Find the alphabetically lowest
- *	name among all the nic names found in a nic string.
- *
- * Return:
- *	Nothing
- *
- * Side Effects:
- *
- *	lb->brd_name gets the new name found
- */
-
-static void
-sort_nic_names(lboard_t *lb)
-{
-	char 	*nic_str ;
-        char    *ptrs[MAX_NICS_PER_STRING] ;
-        char    name[MAX_NIC_NAME_LEN] ;
-        char    *tmp, *tmp1 ;
-
-	*name = 0 ;
-
-	/* Get the nic pointer from the lb */
-
-	if ((nic_str = get_nic_string(lb)) == NULL)
-		return ;
-
-        tmp = get_first_string(ptrs,
-                        get_ptrs(nic_str, ptrs, MAX_NICS_PER_STRING, "Name:")) ;
-
-        if (tmp == NULL)
-		return ;
-
-        if  ( (tmp1 = strchr(tmp, ';')) ){
-                strncpy(name, tmp, tmp1-tmp) ;
-                name[tmp1-tmp] = 0 ;
-        } else {
-                strncpy(name, tmp, (sizeof(name) -1)) ;
-                name[sizeof(name)-1] = 0 ;
-        }
-
-	strcpy(lb->brd_name, name) ;
-}
-
-
-
-char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#012345";
-
 /*
  * Format a module id for printing.
  */
@@ -814,6 +568,7 @@
 	rack = MODULE_GET_RACK(m);
 	ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES);
 	brickchar = MODULE_GET_BTCHAR(m);
+
 	position = MODULE_GET_BPOS(m);
 
 	if (fmt == MODULE_FORMAT_BRIEF) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/klgraph.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/klgraph.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/klgraph.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/klgraph.c	2003-08-01 13:30:44.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 /*
@@ -23,7 +23,6 @@
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
 #include <asm/sn/kldir.h>
-#include <asm/sn/gda.h> 
 #include <asm/sn/klconfig.h>
 #include <asm/sn/router.h>
 #include <asm/sn/xtalk/xbow.h>
@@ -42,7 +41,7 @@
 
 extern char arg_maxnodes[];
 extern u64 klgraph_addr[];
-void mark_cpuvertex_as_cpu(devfs_handle_t vhdl, cpuid_t cpuid);
+void mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid);
 
 
 /*
@@ -69,7 +68,7 @@
  * Add detailed disabled cpu inventory info to the hardware graph.
  */
 void
-klhwg_disabled_cpu_invent_info(devfs_handle_t cpuv,
+klhwg_disabled_cpu_invent_info(vertex_hdl_t cpuv,
                                cnodeid_t cnode,
                                klcpu_t *cpu, slotid_t slot)
 {
@@ -118,7 +117,7 @@
  * Add detailed cpu inventory info to the hardware graph.
  */
 void
-klhwg_cpu_invent_info(devfs_handle_t cpuv,
+klhwg_cpu_invent_info(vertex_hdl_t cpuv,
 			cnodeid_t cnode,
 			klcpu_t *cpu)
 {
@@ -153,7 +152,7 @@
  * as a part of detailed inventory info in the hwgraph.
  */
 void
-klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode)
+klhwg_baseio_inventory_add(vertex_hdl_t baseio_vhdl,cnodeid_t cnode)
 {
 	invent_miscinfo_t	*baseio_inventory;
 	unsigned char		version = 0,revision = 0;
@@ -177,20 +176,11 @@
 				sizeof(invent_miscinfo_t));
 }
 
-char	*hub_rev[] = {
-	"0.0",
-	"1.0",
-	"2.0",
-	"2.1",
-	"2.2",
-	"2.3"
-};
-
 /*
  * Add detailed cpu inventory info to the hardware graph.
  */
 void
-klhwg_hub_invent_info(devfs_handle_t hubv,
+klhwg_hub_invent_info(vertex_hdl_t hubv,
 		      cnodeid_t cnode, 
 		      klhub_t *hub)
 {
@@ -215,10 +205,10 @@
 
 /* ARGSUSED */
 void
-klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode)
+klhwg_add_hub(vertex_hdl_t node_vertex, klhub_t *hub, cnodeid_t cnode)
 {
-	devfs_handle_t myhubv;
-	devfs_handle_t hub_mon;
+	vertex_hdl_t myhubv;
+	vertex_hdl_t hub_mon;
 	int rc;
 	extern struct file_operations shub_mon_fops;
 
@@ -234,9 +224,9 @@
 
 /* ARGSUSED */
 void
-klhwg_add_disabled_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot)
+klhwg_add_disabled_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot)
 {
-        devfs_handle_t my_cpu;
+        vertex_hdl_t my_cpu;
         char name[120];
         cpuid_t cpu_id;
 	nasid_t nasid;
@@ -257,9 +247,9 @@
 
 /* ARGSUSED */
 void
-klhwg_add_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu)
+klhwg_add_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu)
 {
-        devfs_handle_t my_cpu, cpu_dir;
+        vertex_hdl_t my_cpu, cpu_dir;
         char name[120];
         cpuid_t cpu_id;
 	nasid_t nasid;
@@ -295,7 +285,7 @@
 	nasid_t hub_nasid;
 	cnodeid_t hub_cnode;
 	int widgetnum;
-	devfs_handle_t xbow_v, hubv;
+	vertex_hdl_t xbow_v, hubv;
 	/*REFERENCED*/
 	graph_error_t err;
 
@@ -363,12 +353,12 @@
 
 /* ARGSUSED */
 void
-klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap)
+klhwg_add_node(vertex_hdl_t hwgraph_root, cnodeid_t cnode)
 {
 	nasid_t nasid;
 	lboard_t *brd;
 	klhub_t *hub;
-	devfs_handle_t node_vertex = NULL;
+	vertex_hdl_t node_vertex = NULL;
 	char path_buffer[100];
 	int rv;
 	char *s;
@@ -382,7 +372,7 @@
 	ASSERT(brd);
 
 	do {
-		devfs_handle_t cpu_dir;
+		vertex_hdl_t cpu_dir;
 
 		/* Generate a hardware graph path for this board. */
 		board_to_path(brd, path_buffer);
@@ -443,7 +433,7 @@
 		while (cpu) {
 			cpuid_t cpu_id;
 			cpu_id = nasid_slice_to_cpuid(nasid,cpu->cpu_info.physid);
-			if (cpu_enabled(cpu_id))
+			if (cpu_online(cpu_id))
 				klhwg_add_cpu(node_vertex, cnode, cpu);
 			else
 				klhwg_add_disabled_cpu(node_vertex, cnode, cpu, brd->brd_slot);
@@ -466,12 +456,12 @@
 
 /* ARGSUSED */
 void
-klhwg_add_all_routers(devfs_handle_t hwgraph_root)
+klhwg_add_all_routers(vertex_hdl_t hwgraph_root)
 {
 	nasid_t nasid;
 	cnodeid_t cnode;
 	lboard_t *brd;
-	devfs_handle_t node_vertex;
+	vertex_hdl_t node_vertex;
 	char path_buffer[100];
 	int rv;
 
@@ -525,14 +515,14 @@
 
 /* ARGSUSED */
 void
-klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd,
+klhwg_connect_one_router(vertex_hdl_t hwgraph_root, lboard_t *brd,
 			 cnodeid_t cnode, nasid_t nasid)
 {
 	klrou_t *router;
 	char path_buffer[50];
 	char dest_path[50];
-	devfs_handle_t router_hndl;
-	devfs_handle_t dest_hndl;
+	vertex_hdl_t router_hndl;
+	vertex_hdl_t dest_hndl;
 	int rc;
 	int port;
 	lboard_t *dest_brd;
@@ -619,7 +609,7 @@
 
 
 void
-klhwg_connect_routers(devfs_handle_t hwgraph_root)
+klhwg_connect_routers(vertex_hdl_t hwgraph_root)
 {
 	nasid_t nasid;
 	cnodeid_t cnode;
@@ -652,15 +642,15 @@
 
 
 void
-klhwg_connect_hubs(devfs_handle_t hwgraph_root)
+klhwg_connect_hubs(vertex_hdl_t hwgraph_root)
 {
 	nasid_t nasid;
 	cnodeid_t cnode;
 	lboard_t *brd;
 	klhub_t *hub;
 	lboard_t *dest_brd;
-	devfs_handle_t hub_hndl;
-	devfs_handle_t dest_hndl;
+	vertex_hdl_t hub_hndl;
+	vertex_hdl_t dest_hndl;
 	char path_buffer[50];
 	char dest_path[50];
 	graph_error_t rc;
@@ -796,12 +786,12 @@
 }
 
 void
-klhwg_add_all_modules(devfs_handle_t hwgraph_root)
+klhwg_add_all_modules(vertex_hdl_t hwgraph_root)
 {
 	cmoduleid_t	cm;
 	char		name[128];
-	devfs_handle_t	vhdl;
-	devfs_handle_t  module_vhdl;
+	vertex_hdl_t	vhdl;
+	vertex_hdl_t  module_vhdl;
 	int		rc;
 	char		buffer[16];
 
@@ -837,12 +827,12 @@
 }
 
 void
-klhwg_add_all_nodes(devfs_handle_t hwgraph_root)
+klhwg_add_all_nodes(vertex_hdl_t hwgraph_root)
 {
 	cnodeid_t	cnode;
 
 	for (cnode = 0; cnode < numnodes; cnode++) {
-		klhwg_add_node(hwgraph_root, cnode, NULL);
+		klhwg_add_node(hwgraph_root, cnode);
 	}
 
 	for (cnode = 0; cnode < numnodes; cnode++) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/l1.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/l1.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/l1.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/l1.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,239 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/* In general, this file is organized in a hierarchy from lower-level
- * to higher-level layers, as follows:
- *
- *	UART routines
- *	Bedrock/L1 "PPP-like" protocol implementation
- *	System controller "message" interface (allows multiplexing
- *		of various kinds of requests and responses with
- *		console I/O)
- *	Console interface:
- *	  "l1_cons", the glue that allows the L1 to act
- *		as the system console for the stdio libraries
- *
- * Routines making use of the system controller "message"-style interface
- * can be found in l1_command.c.
- */
-
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/uart16550.h>
-#include <asm/sn/simulator.h>
-
-
-#define UART_BAUD_RATE          57600
-
-int 
-get_L1_baud(void)
-{
-    return UART_BAUD_RATE;
-}
-
-
-
-/* Return the current interrupt level */
-int
-l1_get_intr_value( void )
-{
-	return(0);
-}
-
-/* Disconnect the callup functions - throw away interrupts */
-
-void
-l1_unconnect_intr(void)
-{
-}
-
-/* Set up uart interrupt handling for this node's uart */
-
-void
-l1_connect_intr(void *rx_notify, void *tx_notify)
-{
-#if 0
-	// Will need code here for sn2 - something like this
-	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid());
-	intr_connect_level(console_nodepda->node_first_cpu,
-                                SGI_UART_VECTOR, INTPEND0_MAXMASK,
-                                dummy_intr_func);
-	request_irq(SGI_UART_VECTOR | (console_nodepda->node_first_cpu << 8),
-                                intr_func, SA_INTERRUPT | SA_SHIRQ,
-                                "l1_protocol_driver", (void *)sc);
-#endif
-}
-
-
-/* These are functions to use from serial_in/out when in protocol
- * mode to send and receive uart control regs. These are external
- * interfaces into the protocol driver.
- */
-
-void
-l1_control_out(int offset, int value)
-{
-	/* quietly ignore unless simulator */
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		if ( master_node_bedrock_address != (u64)0 ) {
-			writeb(value, (unsigned long)master_node_bedrock_address +
-				(offset<< 3));
-		}
-		return;
-	}
-}
-
-/* Console input exported interface. Return a register value.  */
-
-int
-l1_control_in_polled(int offset)
-{
-	static int l1_control_in_local(int);
-
-	return(l1_control_in_local(offset));
-}
-
-int
-l1_control_in(int offset)
-{
-	static int l1_control_in_local(int);
-
-	return(l1_control_in_local(offset));
-}
-
-static int
-l1_control_in_local(int offset)
-{
-	int sal_call_status = 0, input;
-	int ret = 0;
-
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		ret = readb((unsigned long)master_node_bedrock_address +
-				(offset<< 3));
-		return(ret);
-	}		
-	if ( offset == REG_LSR ) {
-		ret = (LSR_XHRE | LSR_XSRE);	/* can send anytime */
-		sal_call_status = ia64_sn_console_check(&input);
-		if ( !sal_call_status && input ) {
-			/* input pending */
-			ret |= LSR_RCA;
-		}
-	}
-	return(ret);
-}
-
-/*
- * Console input exported interface. Return a character (if one is available)
- */
-
-int
-l1_serial_in_polled(void)
-{
-	static int l1_serial_in_local(void);
-
-	return(l1_serial_in_local());
-}
-
-int
-l1_serial_in(void)
-{
-	static int l1_serial_in_local(void);
-
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3)));
-	}	
-	return(l1_serial_in_local());
-}
-
-static int
-l1_serial_in_local(void)
-{
-	int ch;
-
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		return(readb((unsigned long)master_node_bedrock_address + (REG_DAT<< 3)));
-	}		
-
-	if ( !(ia64_sn_console_getc(&ch)) )
-		return(ch);
-	else
-		return(0);
-}
-
-/* Console output exported interface. Write message to the console.  */
-
-int
-l1_serial_out( char *str, int len )
-{
-	int counter = len;
-
-#if defined(CONFIG_IA64_EARLY_PRINTK)
-	/* Need to setup SAL calls so the PROM calls will work */
-	{
-		static int inited;
-		void early_sn_setup(void);
-		if(!inited) {
-			inited=1;
-			early_sn_setup();
-		}
-	}
-#endif
-
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		extern u64 master_node_bedrock_address;
-		void early_sn_setup(void);
-		if (!master_node_bedrock_address)
-			early_sn_setup();
-		if ( master_node_bedrock_address != (u64)0 ) {
-#ifdef FLAG_DIRECT_CONSOLE_WRITES
-			/* This is an easy way to pre-pend the output to know whether the output
-			 * was done via sal or directly */
-			writeb('[', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-			writeb('+', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-			writeb(']', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-			writeb(' ', (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-#endif	/* FLAG_DIRECT_CONSOLE_WRITES */
-			while ( counter > 0 ) {
-				writeb(*str, (unsigned long)master_node_bedrock_address + (REG_DAT<< 3));
-				counter--;
-				str++;
-			}
-		}
-		return(len);
-	}
-
-	/* Attempt to write things out thru the sal */
-	if ( ia64_sn_console_putb(str, len) )
-		return(0);
-	return((counter <= 0) ? 0 : (len - counter));
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/l1_command.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/l1_command.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/l1_command.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/l1_command.c	2003-08-01 13:31:48.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */ 
 
 #include <linux/types.h>
@@ -16,7 +16,6 @@
 #include <asm/sn/hcl.h>
 #include <asm/sn/hcl_util.h>
 #include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/router.h>
 #include <asm/sn/module.h>
 #include <asm/sn/ksys/l1.h>
@@ -26,37 +25,6 @@
 #include <asm/sn/sn_sal.h>
 #include <linux/ctype.h>
 
-#define ELSC_TIMEOUT	1000000		/* ELSC response timeout (usec) */
-#define LOCK_TIMEOUT	5000000		/* Hub lock timeout (usec) */
-
-#define hub_cpu_get()	0
-
-#define LBYTE(caddr)	(*(char *) caddr)
-
-extern char *bcopy(const char * src, char * dest, int count);
-
-#define LDEBUG		0
-
-/*
- * ELSC data is in NVRAM page 7 at the following offsets.
- */
-
-#define NVRAM_MAGIC_AD	0x700		/* magic number used for init */
-#define NVRAM_PASS_WD	0x701		/* password (4 bytes in length) */
-#define NVRAM_DBG1	0x705		/* virtual XOR debug switches */
-#define NVRAM_DBG2	0x706		/* physical XOR debug switches */
-#define NVRAM_CFG	0x707		/* ELSC Configuration info */
-#define NVRAM_MODULE	0x708		/* system module number */
-#define NVRAM_BIST_FLG	0x709		/* BIST flags (2 bits per nodeboard) */
-#define NVRAM_PARTITION 0x70a		/* module's partition id */
-#define	NVRAM_DOMAIN	0x70b		/* module's domain id */
-#define	NVRAM_CLUSTER	0x70c		/* module's cluster id */
-#define	NVRAM_CELL	0x70d		/* module's cellid */
-
-#define NVRAM_MAGIC_NO	0x37		/* value of magic number */
-#define NVRAM_SIZE	16		/* 16 bytes in nvram */
-
-
 /* elsc_display_line writes up to 12 characters to either the top or bottom
  * line of the L1 display.  line points to a buffer containing the message
  * to be displayed.  The zero-based line number is specified by lnum (so
@@ -69,6 +37,7 @@
     return 0;
 }
 
+
 /*
  * iobrick routines
  */
@@ -88,15 +57,25 @@
 	if ( ia64_sn_sysctl_iobrick_module_get(nasid, &result) )
 		return( ELSC_ERROR_CMD_SEND );
 
-	*rack = (result & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-	*bay = (result & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-	*brick_type = (result & L1_ADDR_TYPE_MASK) >> L1_ADDR_TYPE_SHFT;
+	*rack = (result & MODULE_RACK_MASK) >> MODULE_RACK_SHFT;
+	*bay = (result & MODULE_BPOS_MASK) >> MODULE_BPOS_SHFT;
+	*brick_type = (result & MODULE_BTYPE_MASK) >> MODULE_BTYPE_SHFT;
 	*brick_type = toupper(*brick_type);
 
 	return 0;
 }
 
 
+int iomoduleid_get(nasid_t nasid)
+{
+	int result = 0;
+
+	if ( ia64_sn_sysctl_iobrick_module_get(nasid, &result) )
+		return( ELSC_ERROR_CMD_SEND );
+
+	return result;
+}
+
 int iobrick_module_get(nasid_t nasid)
 {
     uint rnum, rack, bay, brick_type, t;
@@ -130,11 +109,15 @@
     RACK_ADD_NUM(rack, t);
 
     switch( brick_type ) {
-      case 'I': 
+      case L1_BRICKTYPE_IX: 
+	brick_type = MODULE_IXBRICK; break;
+      case L1_BRICKTYPE_PX: 
+	brick_type = MODULE_PXBRICK; break;
+      case L1_BRICKTYPE_I: 
 	brick_type = MODULE_IBRICK; break;
-      case 'P':
+      case L1_BRICKTYPE_P:
 	brick_type = MODULE_PBRICK; break;
-      case 'X':
+      case L1_BRICKTYPE_X:
 	brick_type = MODULE_XBRICK; break;
     }
 
@@ -167,8 +150,9 @@
 
     /* convert to a module.h brick type */
     for( t = 0; t < MAX_BRICK_TYPES; t++ ) {
-        if( brick_types[t] == type )
+        if( brick_types[t] == type ) {
             return t;
+	}
     }
 
     return -1;    /* unknown brick */
@@ -178,18 +162,42 @@
 {
     int io_moduleid;
 
-#ifdef PIC_LATER
-    uint rack, bay;
+    io_moduleid = iobrick_module_get(nasid);
+    return io_moduleid;
+}
+
+/*
+ * given a L1 bricktype, return a bricktype string.  This string is the
+ * string that will be used in the hwpath for I/O bricks
+ */
+char *
+iobrick_L1bricktype_to_name(int type)
+{
+    switch (type)
+    {
+    default:
+        return("Unknown");
 
-    if (PEBRICK_NODE(nasid)) {
-        if (peer_iobrick_rack_bay_get(nasid, &rack, &bay)) {
-            printf("Could not read rack and bay location "
-                   "of PEBrick at nasid %d\n", nasid);
-        }
+    case L1_BRICKTYPE_X:
+        return("Xbrick");
 
-        io_moduleid = peer_iobrick_module_get(sc, rack, bay);
+    case L1_BRICKTYPE_I:
+        return("Ibrick");
+
+    case L1_BRICKTYPE_P:
+        return("Pbrick");
+
+    case L1_BRICKTYPE_PX:
+        return("PXbrick");
+
+    case L1_BRICKTYPE_IX:
+        return("IXbrick");
+
+    case L1_BRICKTYPE_C:
+        return("Cbrick");
+
+    case L1_BRICKTYPE_R:
+        return("Rbrick");
     }
-#endif	/* PIC_LATER */
-    io_moduleid = iobrick_module_get(nasid);
-    return io_moduleid;
 }
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/ml_SN_init.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/ml_SN_init.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/ml_SN_init.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/ml_SN_init.c	2003-08-01 13:34:20.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -19,25 +19,12 @@
 #include <asm/sn/sn_private.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/sn_cpuid.h>
-#include <asm/sn/snconfig.h>
 
-extern int numcpus;
-extern char arg_maxnodes[];
 extern cpuid_t master_procid;
-
-extern int hasmetarouter;
-
 int		maxcpus;
-cpumask_t	boot_cpumask;
-hubreg_t	region_mask = 0;
-
 
 extern xwidgetnum_t hub_widget_id(nasid_t);
 
-extern int valid_icache_reasons;	/* Reasons to flush the icache */
-extern int valid_dcache_reasons;	/* Reasons to flush the dcache */
-extern u_char miniroot;
-extern volatile int	need_utlbmiss_patch;
 extern void iograph_early_init(void);
 
 nasid_t master_nasid = INVALID_NASID;		/* This is the partition master nasid */
@@ -123,16 +110,6 @@
 	mutex_init_locked(&npda->xbow_sema); /* init it locked? */
 }
 
-/* XXX - Move the interrupt stuff to intr.c ? */
-/*
- * Set up the platform-dependent fields in the processor pda.
- * Must be done _after_ init_platform_nodepda().
- * If we need a lock here, something else is wrong!
- */
-void init_platform_pda(cpuid_t cpu)
-{
-}
-
 void
 update_node_information(cnodeid_t cnodeid)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/ml_SN_intr.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/ml_SN_intr.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/ml_SN_intr.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/ml_SN_intr.c	2003-08-01 13:31:27.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 /*
@@ -40,30 +40,13 @@
 #include <asm/sal.h>
 #include <asm/sn/sn_sal.h>
 
-extern irqpda_t	*irqpdaindr[];
-extern cnodeid_t master_node_get(devfs_handle_t vhdl);
+extern irqpda_t	*irqpdaindr;
+extern cnodeid_t master_node_get(vertex_hdl_t vhdl);
 extern nasid_t master_nasid;
 
 //  Initialize some shub registers for interrupts, both IO and error.
 //  
 
-#ifdef BRINGUP2
-static long vec1_opt, ii0_opt;
-static int __init set_vec1_opt(char *str)
-{
-        vec1_opt = 1;
-        return 1;
-}
-
-static int __init set_ii0_opt(char *str)
-{
-        ii0_opt = 1;
-        return 1;
-}
-
-__setup("vec1", set_vec1_opt);
-__setup("ii0", set_ii0_opt);
-#endif
 
 
 void
@@ -78,6 +61,8 @@
 	nodepda_t		*lnodepda;
 	sh_ii_int0_enable_u_t	ii_int_enable;
 	sh_int_node_id_config_u_t	node_id_config;
+	sh_local_int5_config_u_t	local5_config;
+	sh_local_int5_enable_u_t	local5_enable;
 	extern void sn_init_cpei_timer(void);
 	static int timer_added = 0;
 
@@ -113,6 +98,19 @@
 	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_ERROR_MASK), 0);
 	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_CRBP_ERROR_MASK), 0);
 
+	// Config and enable UART interrupt, all nodes.
+
+	local5_config.sh_local_int5_config_regval = 0;
+	local5_config.sh_local_int5_config_s.idx = SGI_UART_VECTOR;
+	local5_config.sh_local_int5_config_s.pid = cpu0;
+	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_CONFIG),
+		local5_config.sh_local_int5_config_regval);
+
+	local5_enable.sh_local_int5_enable_regval = 0;
+	local5_enable.sh_local_int5_enable_s.uart_int = 1;
+	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_ENABLE),
+		local5_enable.sh_local_int5_enable_regval);
+
 
 	// The II_INT_CONFIG register for cpu 0.
 	ii_int_config.sh_ii_int0_config_regval = 0;
@@ -139,13 +137,6 @@
 	// Enable interrupts for II_INT0 and 1.
 	ii_int_enable.sh_ii_int0_enable_regval = 0;
 	ii_int_enable.sh_ii_int0_enable_s.ii_enable = 1;
-#if defined(BUS_INT_WAR) && defined(CONFIG_SHUB_1_0_SPECIFIC)
-	/* Dont enable any ints from II. We will poll for interrupts. */
-	ii_int_enable.sh_ii_int0_enable_s.ii_enable = 0;
-
-	/* Enable IPIs. We use them ONLY for send INITs to hung cpus */
-	*(volatile long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT_ENABLE) = 1;
-#endif
 
 	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_ENABLE),
 		ii_int_enable.sh_ii_int0_enable_regval);
@@ -167,24 +158,44 @@
 			int reserve)
 {
 	int i;
-	irqpda_t	*irqs = irqpdaindr[cpu];
-	static int	nextvec=IA64_SN2_FIRST_DEVICE_VECTOR;
+	irqpda_t	*irqs = irqpdaindr;
+	int		min_shared;
 
 	if (reserve) {
 		if (bit < 0) {
-			for (i = nextvec; i <= IA64_SN2_LAST_DEVICE_VECTOR; i++) {
+			for (i = IA64_SN2_FIRST_DEVICE_VECTOR; i <= IA64_SN2_LAST_DEVICE_VECTOR; i++) {
 				if (irqs->irq_flags[i] == 0) {
 					bit = i;
-#ifdef BRINGUP2
-					if (vec1_opt)
-						nextvec = i+1;
-#endif
 					break;
 				}
 			}
 		}
-		if (bit < 0) {
-			return -1;
+		if (bit < 0) {  /* ran out of irqs.  Have to share.  This will be rare. */
+			min_shared = 256;
+			for (i=IA64_SN2_FIRST_DEVICE_VECTOR; i < IA64_SN2_LAST_DEVICE_VECTOR; i++) {
+				/* Share with the same device class */
+				if (irqpdaindr->current->vendor == irqpdaindr->device_dev[i]->vendor &&
+					irqpdaindr->current->device == irqpdaindr->device_dev[i]->device &&
+					irqpdaindr->share_count[i] < min_shared) {
+						min_shared = irqpdaindr->share_count[i];
+						bit = i;
+				}
+			}
+			min_shared = 256;
+			if (bit < 0) {  /* didn't find a matching device, just pick one. This will be */
+					/* exceptionally rare. */
+				for (i=IA64_SN2_FIRST_DEVICE_VECTOR; i < IA64_SN2_LAST_DEVICE_VECTOR; i++) {
+					if (irqpdaindr->share_count[i] < min_shared) {
+						min_shared = irqpdaindr->share_count[i];
+						bit = i;
+					}
+				}
+			}
+			irqpdaindr->share_count[bit]++;
+		}
+		if (irqs->irq_flags[bit] & SN2_IRQ_SHARED) {
+			irqs->irq_flags[bit] |= SN2_IRQ_RESERVED;
+			return bit;
 		}
 		if (irqs->irq_flags[bit] & SN2_IRQ_RESERVED) {
 			return -1;
@@ -208,7 +219,7 @@
 intr_reserve_level(cpuid_t cpu,
 		int bit,
 		int resflags,
-		devfs_handle_t owner_dev,
+		vertex_hdl_t owner_dev,
 		char *name)
 {
 	return(do_intr_reserve_level(cpu, bit, 1));
@@ -228,9 +239,13 @@
 			int bit,
 			int connect)
 {
-	irqpda_t	*irqs = irqpdaindr[cpu];
+	irqpda_t	*irqs = irqpdaindr;
 
 	if (connect) {
+		if (irqs->irq_flags[bit] & SN2_IRQ_SHARED) {
+			irqs->irq_flags[bit] |= SN2_IRQ_CONNECTED;
+			return bit;
+		}
 		if (irqs->irq_flags[bit] & SN2_IRQ_CONNECTED) {
 			return -1;
 		} else {
@@ -273,28 +288,29 @@
 	int		slice, min_count = 1000;
 	irqpda_t	*irqs;
 
-	for (slice = 0; slice < CPUS_PER_NODE; slice++) {
+	for (slice = CPUS_PER_NODE - 1; slice >= 0; slice--) {
 		int intrs;
 
 		cpu = cnode_slice_to_cpuid(cnode, slice);
-		if (cpu == CPU_NONE) {
+		if (cpu == smp_num_cpus) {
 			continue;
 		}
 
-		if (!cpu_enabled(cpu)) {
+		if (!cpu_online(cpu)) {
 			continue;
 		}
 
-		irqs = irqpdaindr[cpu];
+		irqs = irqpdaindr;
 		intrs = irqs->num_irq_used;
 
 		if (min_count > intrs) {
 			min_count = intrs;
 			best_cpu = cpu;
-#ifdef BRINGUP2
-			if (ii0_opt)
+			if ( enable_shub_wars_1_1() ) {
+				/* Rather than finding the best cpu, always return the first cpu*/
+				/* This forces all interrupts to the same cpu */
 				break;
-#endif
+			}
 		}
 	}
 	return best_cpu;
@@ -314,7 +330,7 @@
 			cnodeid_t cnode,
 			int req_bit,
 			int resflags,
-			devfs_handle_t owner_dev,
+			vertex_hdl_t owner_dev,
 			char *name,
 			int *resp_bit)
 {
@@ -336,18 +352,18 @@
 // Find the node to assign for this interrupt.
 
 cpuid_t
-intr_heuristic(devfs_handle_t dev,
+intr_heuristic(vertex_hdl_t dev,
 		device_desc_t dev_desc,
 		int	req_bit,
 		int resflags,
-		devfs_handle_t owner_dev,
+		vertex_hdl_t owner_dev,
 		char *name,
 		int *resp_bit)
 {
 	cpuid_t		cpuid;
 	cpuid_t		candidate = CPU_NONE;
 	cnodeid_t	candidate_node;
-	devfs_handle_t	pconn_vhdl;
+	vertex_hdl_t	pconn_vhdl;
 	pcibr_soft_t	pcibr_soft;
 	int 		bit;
 
@@ -398,8 +414,8 @@
 	if (candidate  != CPU_NONE) {
 		printk("Cannot target interrupt to target node (%ld).\n",candidate);
 		return CPU_NONE; } else {
-		printk("Cannot target interrupt to closest node (%d) 0x%p\n",
-			master_node_get(dev), (void *)owner_dev);
+		/* printk("Cannot target interrupt to closest node (%d) 0x%p\n",
+			master_node_get(dev), (void *)owner_dev); */
 	}
 
 	// We couldn't put it on the closest node.  Try to find another one.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/ml_iograph.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/ml_iograph.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/ml_iograph.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/ml_iograph.c	2003-08-01 13:34:05.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -22,7 +22,6 @@
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/klconfig.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/sn_private.h>
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/xtalk/xtalk.h>
@@ -43,8 +42,6 @@
 /* At most 2 hubs can be connected to an xswitch */
 #define NUM_XSWITCH_VOLUNTEER 2
 
-extern unsigned char Is_pic_on_this_nasid[512];
-
 /*
  * Track which hubs have volunteered to manage devices hanging off of
  * a Crosstalk Switch (e.g. xbow).  This structure is allocated,
@@ -54,11 +51,11 @@
 typedef struct xswitch_vol_s {
 	mutex_t xswitch_volunteer_mutex;
 	int		xswitch_volunteer_count;
-	devfs_handle_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];
+	vertex_hdl_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];
 } *xswitch_vol_t;
 
 void
-xswitch_vertex_init(devfs_handle_t xswitch)
+xswitch_vertex_init(vertex_hdl_t xswitch)
 {
 	xswitch_vol_t xvolinfo;
 	int rc;
@@ -78,7 +75,7 @@
  * xswitch volunteer structure hanging around.  Destroy it.
  */
 static void
-xswitch_volunteer_delete(devfs_handle_t xswitch)
+xswitch_volunteer_delete(vertex_hdl_t xswitch)
 {
 	xswitch_vol_t xvolinfo;
 	int rc;
@@ -94,10 +91,10 @@
  */
 /* ARGSUSED */
 static void
-volunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master)
+volunteer_for_widgets(vertex_hdl_t xswitch, vertex_hdl_t master)
 {
 	xswitch_vol_t xvolinfo = NULL;
-	devfs_handle_t hubv;
+	vertex_hdl_t hubv;
 	hubinfo_t hubinfo;
 
 	(void)hwgraph_info_get_LBL(xswitch, 
@@ -140,7 +137,7 @@
  */
 /* ARGSUSED */
 static void
-assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv)
+assign_widgets_to_volunteers(vertex_hdl_t xswitch, vertex_hdl_t hubv)
 {
 	xswitch_info_t xswitch_info;
 	xswitch_vol_t xvolinfo = NULL;
@@ -223,18 +220,6 @@
 
                        	bt = iobrick_type_get_nasid(nasid);
                         if (bt >= 0) {
-				/*
-				 * PXBRICK has two busses per widget so this
-				 * algorithm wouldn't work (all busses would
-				 * be assigned to one volunteer). Change the
-				 * bricktype to PBRICK whose mapping is setup
-				 * suchthat 2 of the PICs will be assigned to
-				 * one volunteer and the other one will be
-				 * assigned to the other volunteer.
-				 */
-				if (bt == MODULE_PXBRICK) 
-					bt = MODULE_PBRICK;
-
 			        i = io_brick_map_widget(bt, widgetnum) & 1;
                         }
                 }
@@ -281,8 +266,6 @@
 			DBG("iograph_early_init: Found board 0x%p\n", board);
 		}
 	}
-
-	hubio_init();
 }
 
 /*
@@ -307,7 +290,7 @@
  * hwid for our use.
  */
 static void
-early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid)
+early_probe_for_widget(vertex_hdl_t hubv, xwidget_hwid_t hwid)
 {
 	hubreg_t llp_csr_reg;
 	nasid_t nasid;
@@ -351,7 +334,7 @@
  * added as inventory information.
  */
 static void
-xwidget_inventory_add(devfs_handle_t 		widgetv,
+xwidget_inventory_add(vertex_hdl_t 		widgetv,
 		      lboard_t 			*board,
 		      struct xwidget_hwid_s 	hwid)
 {
@@ -374,14 +357,13 @@
  */
 
 void
-io_xswitch_widget_init(devfs_handle_t  	xswitchv,
-		       devfs_handle_t	hubv,
-		       xwidgetnum_t	widgetnum,
-		       async_attach_t	aa)
+io_xswitch_widget_init(vertex_hdl_t  	xswitchv,
+		       vertex_hdl_t	hubv,
+		       xwidgetnum_t	widgetnum)
 {
 	xswitch_info_t		xswitch_info;
 	xwidgetnum_t		hub_widgetid;
-	devfs_handle_t		widgetv;
+	vertex_hdl_t		widgetv;
 	cnodeid_t		cnode;
 	widgetreg_t		widget_id;
 	nasid_t			nasid, peer_nasid;
@@ -427,6 +409,7 @@
 		char			name[4];
 		lboard_t dummy;
 
+
 		/*
 		 * If the current hub is not supposed to be the master 
 		 * for this widgetnum, then skip this widget.
@@ -470,12 +453,15 @@
 
 		memset(buffer, 0, 16);
 		format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF);
-		sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d" "/%cbrick" "/%s/%d",
+
+		sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d" "/%s" "/%s/%d",
 			buffer,
 			geo_slab(board->brd_geoid),
-			(board->brd_type == KLTYPE_IBRICK) ? 'I' :
-			(board->brd_type == KLTYPE_PBRICK) ? 'P' :
-			(board->brd_type == KLTYPE_XBRICK) ? 'X' : '?',
+			(board->brd_type == KLTYPE_IBRICK) ? EDGE_LBL_IBRICK :
+			(board->brd_type == KLTYPE_PBRICK) ? EDGE_LBL_PBRICK :
+			(board->brd_type == KLTYPE_PXBRICK) ? EDGE_LBL_PXBRICK :
+			(board->brd_type == KLTYPE_IXBRICK) ? EDGE_LBL_IXBRICK :
+			(board->brd_type == KLTYPE_XBRICK) ? EDGE_LBL_XBRICK : "?brick",
 			EDGE_LBL_XTALK, widgetnum);
 		
 		DBG("io_xswitch_widget_init: path= %s\n", pathname);
@@ -514,36 +500,46 @@
 		xwidget_inventory_add(widgetv,board,hwid);
 
 		(void)xwidget_register(&hwid, widgetv, widgetnum,
-				       hubv, hub_widgetid,
-				       aa);
+				       hubv, hub_widgetid);
 
 		ia64_sn_sysctl_iobrick_module_get(nasid, &io_module);
 
 		if (io_module >= 0) {
 			char			buffer[16];
-			devfs_handle_t		to, from;
+			vertex_hdl_t		to, from;
+			char           		*brick_name;
+			extern char *iobrick_L1bricktype_to_name(int type);
+
 
 			memset(buffer, 0, 16);
 			format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF);
 
-			bt = toupper(MODULE_GET_BTCHAR(io_module));
+			if ( islower(MODULE_GET_BTCHAR(io_module)) ) {
+				bt = toupper(MODULE_GET_BTCHAR(io_module));
+			}
+			else {
+				bt = MODULE_GET_BTCHAR(io_module);
+			}
+
+			brick_name = iobrick_L1bricktype_to_name(bt);
+
 			/* Add a helper vertex so xbow monitoring
 			* can identify the brick type. It's simply
 			* an edge from the widget 0 vertex to the
 			*  brick vertex.
 			*/
 
-			sprintf(pathname, "/dev/hw/" EDGE_LBL_MODULE "/%s/"
+			sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/"
 				EDGE_LBL_SLAB "/%d/"
 				EDGE_LBL_NODE "/" EDGE_LBL_XTALK "/"
 				"0",
 				buffer, geo_slab(board->brd_geoid));
 			from = hwgraph_path_to_vertex(pathname);
 			ASSERT_ALWAYS(from);
-			sprintf(pathname, "/dev/hw/" EDGE_LBL_MODULE "/%s/"
+			sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/"
 				EDGE_LBL_SLAB "/%d/"
-				"%cbrick",
-				buffer, geo_slab(board->brd_geoid), bt);
+				"%s",
+				buffer, geo_slab(board->brd_geoid), brick_name);
 
 			to = hwgraph_path_to_vertex(pathname);
 			ASSERT_ALWAYS(to);
@@ -566,12 +562,9 @@
 
 
 static void
-io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode)
+io_init_xswitch_widgets(vertex_hdl_t xswitchv, cnodeid_t cnode)
 {
 	xwidgetnum_t		widgetnum;
-	async_attach_t          aa;
-
-	aa = async_attach_new();
 	
 	DBG("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode);
 
@@ -579,13 +572,8 @@
 	     widgetnum++) {
 		io_xswitch_widget_init(xswitchv,
 				       cnodeid_to_vertex(cnode),
-				       widgetnum, aa);
+				       widgetnum);
 	}
-	/* 
-	 * Wait for parallel attach threads, if any, to complete.
-	 */
-	async_attach_waitall(aa);
-	async_attach_free(aa);
 }
 
 /*
@@ -595,11 +583,11 @@
  * graph and risking hangs.
  */
 static void
-io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid)
+io_link_xswitch_widgets(vertex_hdl_t xswitchv, cnodeid_t cnodeid)
 {
 	xwidgetnum_t		widgetnum;
 	char 			pathname[128];
-	devfs_handle_t		vhdl;
+	vertex_hdl_t		vhdl;
 	nasid_t			nasid, peer_nasid;
 	lboard_t		*board;
 
@@ -638,21 +626,12 @@
 			return;
 		}
 
-		if ( Is_pic_on_this_nasid[nasid] ) {
-			/* Check both buses */
-			sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);
-			if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS)
-				board->brd_graph_link = vhdl;
-			else {
-				sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);
-				if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS)
-					board->brd_graph_link = vhdl;
-				else
-					board->brd_graph_link = GRAPH_VERTEX_NONE;
-			}
-		}
+		/* Check both buses */
+		sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);
+		if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS)
+			board->brd_graph_link = vhdl;
 		else {
-			sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
+			sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);
 			if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS)
 				board->brd_graph_link = vhdl;
 			else
@@ -668,16 +647,15 @@
 io_init_node(cnodeid_t cnodeid)
 {
 	/*REFERENCED*/
-	devfs_handle_t hubv, switchv, widgetv;
+	vertex_hdl_t hubv, switchv, widgetv;
 	struct xwidget_hwid_s hwid;
 	hubinfo_t hubinfo;
 	int is_xswitch;
 	nodepda_t	*npdap;
 	struct semaphore *peer_sema = 0;
 	uint32_t	widget_partnum;
-	nodepda_router_info_t *npda_rip;
 	cpu_cookie_t	c = 0;
-	extern int hubdev_docallouts(devfs_handle_t);
+	extern int hubdev_docallouts(vertex_hdl_t);
 
 	npdap = NODEPDA(cnodeid);
 
@@ -696,21 +674,6 @@
 	hubdev_docallouts(hubv);
 
 	/*
-	 * Set up the dependent routers if we have any.
-	 */
-	npda_rip = npdap->npda_rip_first;
-
-	while(npda_rip) {
-		/* If the router info has not been initialized
-		 * then we need to do the router initialization
-		 */
-		if (!npda_rip->router_infop) {
-			router_init(cnodeid,0,npda_rip);
-		}
-		npda_rip = npda_rip->router_next;
-	}
-
-	/*
 	 * Read mfg info on this hub
 	 */
 
@@ -833,7 +796,7 @@
 		 */
 		hubinfo_get(hubv, &hubinfo);
 
-		(void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL);
+		(void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid);
 
 		if (!is_xswitch) {
 			/* io_init_done takes cpu cookie as 2nd argument 
@@ -915,231 +878,9 @@
  * XXX Irix legacy..controller numbering should be part of devfsd's job
  */
 int num_base_io_scsi_ctlr = 2; /* used by syssgi */
-devfs_handle_t		base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR];
-static devfs_handle_t	baseio_enet_vhdl,baseio_console_vhdl;
-
-/*
- * Put the logical controller number information in the 
- * scsi controller vertices for each scsi controller that
- * is in a "fixed position".
- */
-static void
-scsi_ctlr_nums_add(devfs_handle_t pci_vhdl)
-{
-	{
-		int i;
-
-		num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR;
-
-		/* Initialize base_io_scsi_ctlr_vhdl array */
-		for (i=0; i<num_base_io_scsi_ctlr; i++)
-			base_io_scsi_ctlr_vhdl[i] = GRAPH_VERTEX_NONE;
-	}
-	{
-	/*
-	 * May want to consider changing the SN0 code, above, to work more like
-	 * the way this works.
-	 */
-	devfs_handle_t base_ibrick_xbridge_vhdl;
-	devfs_handle_t base_ibrick_xtalk_widget_vhdl;
-	devfs_handle_t scsi_ctlr_vhdl;
-	int i;
-	graph_error_t rv;
-
-	/*
-	 * This is a table of "well-known" SCSI controllers and their well-known
-	 * controller numbers.  The names in the table start from the base IBrick's
-	 * Xbridge vertex, so the first component is the xtalk widget number.
-	 */
-	static struct {
-		char	*base_ibrick_scsi_path;
-		int	controller_number;
-	} hardwired_scsi_controllers[] = {
-		{"15/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 0},
-		{"15/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 1},
-		{"15/" EDGE_LBL_PCI "/3/" EDGE_LBL_SCSI_CTLR "/0", 2},
-		{"14/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 3},
-		{"14/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 4},
-		{"15/" EDGE_LBL_PCI "/6/ohci/0/" EDGE_LBL_SCSI_CTLR "/0", 5},
-		{NULL, -1} /* must be last */
-	};
-
-	base_ibrick_xtalk_widget_vhdl = hwgraph_connectpt_get(pci_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xtalk_widget_vhdl != GRAPH_VERTEX_NONE);
-
-	base_ibrick_xbridge_vhdl = hwgraph_connectpt_get(base_ibrick_xtalk_widget_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xbridge_vhdl != GRAPH_VERTEX_NONE);
-	hwgraph_vertex_unref(base_ibrick_xtalk_widget_vhdl);
-
-	/*
-	 * Iterate through the list of well-known SCSI controllers.
-	 * For each controller found, set it's controller number according
-	 * to the table.
-	 */
-	for (i=0; hardwired_scsi_controllers[i].base_ibrick_scsi_path != NULL; i++) {
-		rv = hwgraph_path_lookup(base_ibrick_xbridge_vhdl,
-			hardwired_scsi_controllers[i].base_ibrick_scsi_path, &scsi_ctlr_vhdl, NULL);
-
-		if (rv != GRAPH_SUCCESS) /* No SCSI at this path */
-			continue;
-
-		ASSERT(hardwired_scsi_controllers[i].controller_number < NUM_BASE_IO_SCSI_CTLR);
-		base_io_scsi_ctlr_vhdl[hardwired_scsi_controllers[i].controller_number] = scsi_ctlr_vhdl;
-		device_controller_num_set(scsi_ctlr_vhdl, hardwired_scsi_controllers[i].controller_number);
-		hwgraph_vertex_unref(scsi_ctlr_vhdl); /* (even though we're actually keeping a reference) */
-	}
-
-	hwgraph_vertex_unref(base_ibrick_xbridge_vhdl);
-	}
-}
-
+vertex_hdl_t		base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR];
 
 #include <asm/sn/ioerror_handling.h>
-devfs_handle_t		sys_critical_graph_root = GRAPH_VERTEX_NONE;
-
-/* Define the system critical vertices and connect them through
- * a canonical parent-child relationships for easy traversal
- * during io error handling.
- */
-static void
-sys_critical_graph_init(void)
-{
-	devfs_handle_t		bridge_vhdl,master_node_vhdl;
-	devfs_handle_t  		xbow_vhdl = GRAPH_VERTEX_NONE;
-	extern devfs_handle_t	hwgraph_root;
-	devfs_handle_t		pci_slot_conn;
-	int			slot;
-	devfs_handle_t		baseio_console_conn;
-
-	DBG("sys_critical_graph_init: FIXME.\n");
-	baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl);
-
-	if (baseio_console_conn == NULL) {
-		return;
-	}
-
-	/* Get the vertex handle for the baseio bridge */
-	bridge_vhdl = device_master_get(baseio_console_conn);
-
-	/* Get the master node of the baseio card */
-	master_node_vhdl = cnodeid_to_vertex(
-				master_node_get(baseio_console_vhdl));
-	
-	/* Add the "root->node" part of the system critical graph */
-
-	sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl);
-
-	/* Check if we have a crossbow */
-	if (hwgraph_traverse(master_node_vhdl,
-			     EDGE_LBL_XTALK"/0",
-			     &xbow_vhdl) == GRAPH_SUCCESS) {
-		/* We have a crossbow.Add "node->xbow" part of the system 
-		 * critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl);
-		
-		/* Add "xbow->baseio bridge" of the system critical graph */
-		sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl);
-
-		hwgraph_vertex_unref(xbow_vhdl);
-	} else 
-		/* We donot have a crossbow. Add "node->baseio_bridge"
-		 * part of the system critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl);
-
-	/* Add all the populated PCI slot vertices to the system critical
-	 * graph with the bridge vertex as the parent.
-	 */
-	for (slot = 0 ; slot < 8; slot++) {
-		char	slot_edge[10];
-
-		sprintf(slot_edge,"%d",slot);
-		if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn)
-		    != GRAPH_SUCCESS)
-			continue;
-		sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	hwgraph_vertex_unref(bridge_vhdl);
-
-	/* Add the "ioc3 pci connection point  -> console ioc3" part 
-	 * of the system critical graph
-	 */
-
-	if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_console_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "ethernet pci connection point  -> base ethernet" part of 
-	 * the system  critical graph
-	 */
-	if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_enet_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "scsi controller pci connection point  -> base scsi 
-	 * controller" part of the system critical graph
-	 */
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[0]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[1]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	hwgraph_vertex_unref(baseio_console_conn);
-
-}
-
-static void
-baseio_ctlr_num_set(void)
-{
-	char 			name[MAXDEVNAME];
-	devfs_handle_t		console_vhdl, pci_vhdl, enet_vhdl;
-	devfs_handle_t		ioc3_console_vhdl_get(void);
-
-
-	DBG("baseio_ctlr_num_set; FIXME\n");
-	console_vhdl = ioc3_console_vhdl_get();
-	if (console_vhdl == GRAPH_VERTEX_NONE)
-		return;
-	/* Useful for setting up the system critical graph */
-	baseio_console_vhdl = console_vhdl;
-
-	vertex_to_name(console_vhdl,name,MAXDEVNAME);
-
-	strcat(name,__DEVSTR1);
-	pci_vhdl =  hwgraph_path_to_vertex(name);
-	scsi_ctlr_nums_add(pci_vhdl);
-	/* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(pci_vhdl);
-
-	vertex_to_name(console_vhdl, name, MAXDEVNAME);
-	strcat(name, __DEVSTR4);
-	enet_vhdl = hwgraph_path_to_vertex(name);
-
-	/* Useful for setting up the system critical graph */
-	baseio_enet_vhdl = enet_vhdl;
-
-	device_controller_num_set(enet_vhdl, 0);
-	/* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(enet_vhdl);
-}
 /* #endif */
 
 /*
@@ -1168,13 +909,6 @@
 		 */
 		update_node_information(cnodeid);
 
-	baseio_ctlr_num_set();
-	/* Setup the system critical graph (which is a subgraph of the
-	 * main hwgraph). This information is useful during io error
-	 * handling.
-	 */
-	sys_critical_graph_init();
-
 #if HWG_PRINT
 	hwgraph_print();
 #endif
@@ -1279,10 +1013,10 @@
         2,                                      /* 0x8            */
         1,                                      /* 0x9            */
         0, 0,                                   /* 0xa - 0xb      */
-        5,                                      /* 0xc            */
+        4,                                      /* 0xc            */
         6,                                      /* 0xd            */
-        4,                                      /* 0xe            */
-        3                                       /* 0xf            */
+        3,                                      /* 0xe            */
+        5                                       /* 0xf            */
     }
  },
 
@@ -1300,6 +1034,20 @@
     }
  },
 
+/* IXbrick widget number to PCI bus number map */
+ {      MODULE_IXBRICK,                         /* IXbrick type   */ 
+    /*  PCI Bus #                                  Widget #       */
+    {   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
+        0,                                      /* 0x8            */
+        0,                                      /* 0x9            */
+        0, 0,                                   /* 0xa - 0xb      */
+        1,                                      /* 0xc            */
+        5,                                      /* 0xd            */
+        0,                                      /* 0xe            */
+        3                                       /* 0xf            */
+    }
+ },
+
 /* Xbrick widget to XIO slot map */
  {      MODULE_XBRICK,                          /* Xbrick type    */ 
     /*  XIO Slot #                                 Widget #       */
@@ -1335,61 +1083,3 @@
         return 0;
 
 }
-
-/*
- * Use the device's vertex to map the device's widget to a meaningful int
- */
-int
-io_path_map_widget(devfs_handle_t vertex)
-{
-        char hw_path_name[MAXDEVNAME];
-        char *wp, *bp, *sp = NULL;
-        int  widget_num;
-	long atoi(char *);
-	int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-
-
-        /* Get the full path name of the vertex */
-        if (GRAPH_SUCCESS != hwgraph_vertex_name_get(vertex, hw_path_name,
-                                                     MAXDEVNAME))
-                return 0;
-
-        /* Find the widget number in the path name */
-        wp = strstr(hw_path_name, "/"EDGE_LBL_XTALK"/");
-        if (wp == NULL)
-                return 0;
-        widget_num = atoi(wp+7);
-        if (widget_num < XBOW_PORT_8 || widget_num > XBOW_PORT_F)
-                return 0;
-
-        /* Find "brick" in the path name */
-        bp = strstr(hw_path_name, "brick");
-        if (bp == NULL)
-                return 0;
-
-        /* Find preceding slash */
-        sp = bp;
-        while (sp > hw_path_name) {
-                sp--;
-                if (*sp == '/')
-                        break;
-        }
-
-        /* Invalid if no preceding slash */
-        if (!sp)
-                return 0;
-
-        /* Bump slash pointer to "brick" prefix */
-        sp++;
-        /*
-         * Verify "brick" prefix length;  valid exaples:
-         * 'I' from "/Ibrick"
-         * 'P' from "/Pbrick"
-         * 'X' from "/Xbrick"
-         */
-         if ((bp - sp) != 1)
-                return 0;
-
-        return (io_brick_map_widget((int)*sp, widget_num));
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/module.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/module.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/module.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/module.c	2003-08-01 13:30:33.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -18,7 +18,6 @@
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/klconfig.h>
-#include <asm/sn/sn1/hubdev.h>
 #include <asm/sn/module.h>
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/xtalk/xswitch.h>
@@ -261,20 +260,5 @@
 	    nserial);
 
     if (nserial == 0)
-	printk(KERN_WARNING  "io_module_init: No serial number found.\n");
-}
-
-int
-get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info)
-{
-    if (cmod < 0 || cmod >= nummodules)
-	return -EINVAL;
-
-    mod_info->mod_num = modules[cmod]->id;
-
-    ia64_sn_sys_serial_get(mod_info->serial_str);
-    
-    mod_info->serial_num = ia64_sn_partition_serial_get();
-
-    return 0;
+	DPRINTF(KERN_WARNING  "io_module_init: No serial number found.\n");
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/pci_bus_cvlink.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pci_bus_cvlink.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/pci_bus_cvlink.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pci_bus_cvlink.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,811 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <asm/sn/types.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/sn_cpuid.h>
-
-extern int bridge_rev_b_data_check_disable;
-
-devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
-nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
-void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
-unsigned char num_bridges;
-static int done_probing = 0;
-
-static int pci_bus_map_create(devfs_handle_t xtalk);
-devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
-
-extern unsigned char Is_pic_on_this_nasid[512];
-
-extern void sn_init_irq_desc(void);
-
-
-/*
- * For the given device, initialize whether it is a PIC device.
- */
-static void
-set_isPIC(struct sn_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-	device_sysdata->isPIC = IS_PIC_SOFT(pcibr_soft);;
-}
-
-/*
- * pci_bus_cvlink_init() - To be called once during initialization before 
- *	SGI IO Infrastructure init is called.
- */
-void
-pci_bus_cvlink_init(void)
-{
-
-	extern void ioconfig_bus_init(void);
-
-	memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET);
-	memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET);
-
-	memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET);
-
-	num_bridges = 0;
-
-	// ioconfig_bus_init();
-}
-
-/*
- * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated 
- *	pci bus vertex from the SGI IO Infrastructure.
- */
-devfs_handle_t
-pci_bus_to_vertex(unsigned char busnum)
-{
-
-	devfs_handle_t	pci_bus = NULL;
-
-
-	/*
-	 * First get the xwidget vertex.
-	 */
-	pci_bus = busnum_to_pcibr_vhdl[busnum];
-	return(pci_bus);
-}
-
-/*
- * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
- *	and function numbers.
- */
-devfs_handle_t
-devfn_to_vertex(unsigned char busnum, unsigned int devfn)
-{
-
-	int slot = 0;
-	int func = 0;
-	char	name[16];
-	devfs_handle_t  pci_bus = NULL;
-	devfs_handle_t	device_vertex = (devfs_handle_t)NULL;
-
-	/*
-	 * Go get the pci bus vertex.
-	 */
-	pci_bus = pci_bus_to_vertex(busnum);
-	if (!pci_bus) {
-		/*
-		 * During probing, the Linux pci code invents non existant
-		 * bus numbers and pci_dev structures and tries to access
-		 * them to determine existance. Don't crib during probing.
-		 */
-		if (done_probing)
-			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
-		return(NULL);
-	}
-
-
-	/*
-	 * Go get the slot&function vertex.
-	 * Should call pciio_slot_func_to_name() when ready.
-	 */
-	slot = PCI_SLOT(devfn);
-	func = PCI_FUNC(devfn);
-
-	/*
-	 * For a NON Multi-function card the name of the device looks like:
-	 * ../pci/1, ../pci/2 ..
-	 */
-	if (func == 0) {
-        	sprintf(name, "%d", slot);
-		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
-			GRAPH_SUCCESS) {
-			if (device_vertex) {
-				return(device_vertex);
-			}
-		}
-	}
-			
-	/*
-	 * This maybe a multifunction card.  It's names look like:
-	 * ../pci/1a, ../pci/1b, etc.
-	 */
-	sprintf(name, "%d%c", slot, 'a'+func);
-	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
-		if (!device_vertex) {
-			return(NULL);
-		}
-	}
-
-	return(device_vertex);
-}
-
-/*
- * For the given device, initialize the addresses for both the Device(x) Flush 
- * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
- * is connected.
- */
-static void
-set_flush_addresses(struct pci_dev *device_dev, 
-	struct sn_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    	bridge_t               *bridge = pcibr_soft->bs_base;
-	nasid_t			nasid;
-
-	/*
-	 * Get the nasid from the bridge.
-	 */
-	nasid = NASID_GET(device_sysdata->dma_buf_sync);
-	if (IS_PIC_DEVICE(device_dev)) {
-		device_sysdata->dma_buf_sync = (volatile unsigned int *)
-			&bridge->b_wr_req_buf[pciio_slot].reg;
-		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
-			XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(nasid, 0),
-			pcibr_soft->bs_xid);
-	} else {
-		/*
-		 * Accessing Xbridge and Xbow register when SHUB swapoper is on!.
-		 */
-		device_sysdata->dma_buf_sync = (volatile unsigned int *)
-			((uint64_t)&(bridge->b_wr_req_buf[pciio_slot].reg)^4);
-		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
-			((uint64_t)(XBOW_PRIO_LINKREGS_PTR(
-			NODE_SWIN_BASE(nasid, 0), pcibr_soft->bs_xid)) ^ 4);
-	}
-
-#ifdef DEBUG
-	printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
-		device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
-
-printk("set_flush_addresses: dma_buf_sync\n");
-	while((volatile unsigned int )*device_sysdata->dma_buf_sync);
-printk("set_flush_addresses: xbow_buf_sync\n");
-	while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
-#endif
-
-}
-
-/*
- * Most drivers currently do not properly tell the arch specific pci dma
- * interfaces whether they can handle A64. Here is where we privately
- * keep track of this.
- */
-static void __init
-set_sn_pci64(struct pci_dev *dev)
-{
-	unsigned short vendor = dev->vendor;
-	unsigned short device = dev->device;
-
-	if (vendor == PCI_VENDOR_ID_QLOGIC) {
-		if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) ||
-				(device == PCI_DEVICE_ID_QLOGIC_ISP2200)) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-	if (vendor == PCI_VENDOR_ID_SGI) {
-		if (device == PCI_DEVICE_ID_SGI_IOC3) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-}
-
-/*
- * sn_pci_fixup() - This routine is called when platform_pci_fixup() is 
- *	invoked at the end of pcibios_init() to link the Linux pci 
- *	infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
- *
- *	Other platform specific fixup can also be done here.
- */
-void
-sn_pci_fixup(int arg)
-{
-	struct list_head *ln;
-	struct pci_bus *pci_bus = NULL;
-	struct pci_dev *device_dev = NULL;
-	struct sn_widget_sysdata *widget_sysdata;
-	struct sn_device_sysdata *device_sysdata;
-	pciio_intr_t intr_handle;
-	int cpuid, bit;
-	devfs_handle_t device_vertex;
-	pciio_intr_line_t lines;
-	extern void sn_pci_find_bios(void);
-	extern int numnodes;
-	int cnode;
-	extern void io_sh_swapper(int, int);
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] )
-			io_sh_swapper((cnodeid_to_nasid(cnode)), 0);
-	}
-
-	if (arg == 0) {
-#ifdef CONFIG_PROC_FS
-		extern void register_sn_partition_id(void);
-		extern void register_sn_serial_numbers(void);
-#endif
-
-		sn_init_irq_desc();
-		sn_pci_find_bios();
-		for (cnode = 0; cnode < numnodes; cnode++) {
-			extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
-			intr_init_vecblk(NODEPDA(cnode), cnode, 0);
-		} 
-
-		/*
-		 * When we return to generic Linux, Swapper is always on ..
-		 */
-		for (cnode = 0; cnode < numnodes; cnode++) {
-			if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] )
-				io_sh_swapper((cnodeid_to_nasid(cnode)), 1);
-		}
-#ifdef CONFIG_PROC_FS
-		register_sn_partition_id();
-		register_sn_serial_numbers();
-#endif
-		return;
-	}
-
-
-	done_probing = 1;
-
-	/*
-	 * Initialize the pci bus vertex in the pci_bus struct.
-	 */
-	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
-		pci_bus = pci_bus_b(ln);
-		widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), 
-					GFP_KERNEL);
-		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
-		pci_bus->sysdata = (void *)widget_sysdata;
-	}
-
-	/*
- 	 * set the root start and end so that drivers calling check_region()
-	 * won't see a conflict
-	 */
-	ioport_resource.start  = 0xc000000000000000;
-	ioport_resource.end =    0xcfffffffffffffff;
-
-	/*
-	 * Set the root start and end for Mem Resource.
-	 */
-	iomem_resource.start = 0;
-	iomem_resource.end = 0xffffffffffffffff;
-
-	/*
-	 * Initialize the device vertex in the pci_dev struct.
-	 */
-	pci_for_each_dev(device_dev) {
-		unsigned int irq;
-		int idx;
-		u16 cmd;
-		devfs_handle_t vhdl;
-		unsigned long size;
-		extern int bit_pos_to_irq(int);
-
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
-			extern void pci_fixup_ioc3(struct pci_dev *d);
-			pci_fixup_ioc3(device_dev);
-		}
-
-		/* Set the device vertex */
-
-		device_sysdata = kmalloc(sizeof(struct sn_device_sysdata),
-					GFP_KERNEL);
-		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
-		device_sysdata->isa64 = 0;
-		/*
-		 * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
-		 * register addresses.
-		 */
-		(void) set_flush_addresses(device_dev, device_sysdata);
-
-		device_dev->sysdata = (void *) device_sysdata;
-		set_sn_pci64(device_dev);
-		set_isPIC(device_sysdata);
-
-		pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
-
-		/*
-		 * Set the resources address correctly.  The assumption here 
-		 * is that the addresses in the resource structure has been
-		 * read from the card and it was set in the card by our
-		 * Infrastructure ..
-		 */
-		vhdl = device_sysdata->vhdl;
-		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
-			size = 0;
-			size = device_dev->resource[idx].end -
-				device_dev->resource[idx].start;
-			if (size) {
-				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
-				device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
-			}
-			else
-				continue;
-
-			device_dev->resource[idx].end = 
-				device_dev->resource[idx].start + size;
-#ifdef BRINGUP2
-			printk("Device Vendor 0x%x, resource[%d] PIO Address = 0x%lx\n", device_dev->vendor, idx, (long)device_dev->resource[idx].start);
-#endif
-
-			if (device_dev->resource[idx].flags & IORESOURCE_IO)
-				cmd |= PCI_COMMAND_IO;
-
-			if (device_dev->resource[idx].flags & IORESOURCE_MEM)
-				cmd |= PCI_COMMAND_MEMORY;
-		}
-		/*
-		 * Now handle the ROM resource ..
-		 */
-#if 0
-	/*
-	 * Software WAR for a Software BUG.
-	 * This is only temporary.
-	 * See PV 872791
-	 */
-		size = device_dev->resource[PCI_ROM_RESOURCE].end -
-			device_dev->resource[PCI_ROM_RESOURCE].start;
-
-		if (size) {
-			device_dev->resource[PCI_ROM_RESOURCE].start =
-			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
-				size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
-			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
-			device_dev->resource[PCI_ROM_RESOURCE].end =
-			device_dev->resource[PCI_ROM_RESOURCE].start + size;
-		}
-#endif
-
-		/*
-		 * Update the Command Word on the Card.
-		 */
-		cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */
-					   /* bit gets dropped .. no harm */
-		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
-
-		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-				lines = 1;
-		}
- 
-		device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;
-		device_vertex = device_sysdata->vhdl;
- 
-		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
-
-		bit = intr_handle->pi_irq;
-		cpuid = intr_handle->pi_cpu;
-		irq = bit;
-		irq = irq + (cpuid << 8);
-		pciio_intr_connect(intr_handle, (intr_func_t)0, (intr_arg_t)0);
-		device_dev->irq = irq;
-#ifdef ajmtestintr
-		{
-			int slot = PCI_SLOT(device_dev->devfn);
-			static int timer_set = 0;
-			pcibr_intr_t	pcibr_intr = (pcibr_intr_t)intr_handle;
-			pcibr_soft_t	pcibr_soft = pcibr_intr->bi_soft;
-			extern void intr_test_handle_intr(int, void*, struct pt_regs *);
-
-			if (!timer_set) {
-				intr_test_set_timer();
-				timer_set = 1;
-			}
-			intr_test_register_irq(irq, pcibr_soft, slot);
-			request_irq(irq, intr_test_handle_intr,0,NULL, NULL);
-		}
-#endif
-
-	}
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] )
-			io_sh_swapper((cnodeid_to_nasid(cnode)), 1);
-	}
-}
-
-/*
- * linux_bus_cvlink() Creates a link between the Linux PCI Bus number 
- *	to the actual hardware component that it represents:
- *	/dev/hw/linux/busnum/0 -> ../../../hw/module/001c01/slab/0/Ibrick/xtalk/15/pci
- */
-void
-linux_bus_cvlink(void)
-{
-	char name[8];
-	int index;
-	
-	for (index=0; index < MAX_PCI_XWIDGET; index++) {
-		if (!busnum_to_pcibr_vhdl[index])
-			continue;
-
-		sprintf(name, "%d", index);
-		(void) hwgraph_edge_add(linux_busnum, busnum_to_pcibr_vhdl[index], 
-				name);
-	}
-}
-
-/*
- * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
- *
- *	Linux PCI Bus numbers are assigned from lowest module_id numbers
- *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
- *	HUB_WIDGET_ID_MIN:
- *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
- *
- *	Given 2 modules 001c01 and 001c02 we get the following mappings:
- *		001c01, widgetnum 15 = Bus number 0
- *		001c01, widgetnum 14 = Bus number 1
- *		001c02, widgetnum 15 = Bus number 3
- *		001c02, widgetnum 14 = Bus number 4
- *		etc.
- *
- * The rational for starting Bus Number 0 with Widget number 15 is because 
- * the system boot disks are always connected via Widget 15 Slot 0 of the 
- * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
- * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
- * module id(Master Cnode) of the system.
- *	
- */
-static int 
-pci_bus_map_create(devfs_handle_t xtalk)
-{
-
-	devfs_handle_t master_node_vertex = NULL;
-	devfs_handle_t xwidget = NULL;
-	devfs_handle_t pci_bus = NULL;
-	hubinfo_t hubinfo = NULL;
-	xwidgetnum_t widgetnum;
-	char pathname[128];
-	graph_error_t rv;
-	int bus;
-
-	/*
-	 * Loop throught this vertex and get the Xwidgets ..
-	 */
-
-
-	/* PCI devices */
-
-	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
-
-#if  0
-        {
-                int pos;
-                char dname[256];
-                pos = devfs_generate_path(xtalk, dname, 256);
-                printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-        }
-#endif
-
-		sprintf(pathname, "%d", widgetnum);
-		xwidget = NULL;
-		
-		/*
-		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
-		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
-		 */
-		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
-		if ( (rv != GRAPH_SUCCESS) ) {
-			if (!xwidget) {
-				continue;
-}
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		pci_bus = NULL;
-		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
-			if (!pci_bus) {
-				continue;
-}
-
-		/*
-		 * Assign the correct bus number and also the nasid of this 
-		 * pci Xwidget.
-		 * 
-		 * Should not be any race here ...
-		 */
-		num_bridges++;
-		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
-
-		/*
-		 * Get the master node and from there get the NASID.
-		 */
-		master_node_vertex = device_master_get(xwidget);
-		if (!master_node_vertex) {
-			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
-		}
-	
-		hubinfo_get(master_node_vertex, &hubinfo);
-		if (!hubinfo) {
-			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
-			return(1);
-		} else {
-			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
-		}
-
-		/*
-		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
-		 */
-		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
-		if (!busnum_to_atedmamaps[num_bridges - 1])
-			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
-
-		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
-
-	}
-
-	/*
-	 * PCIX devices
-	 * We number busses differently for PCI-X devices.
-	 * We start from Lowest Widget on up ..
-	 */
-
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
-
-		/* Do both buses */
-		for ( bus = 0; bus < 2; bus++ ) {
-			sprintf(pathname, "%d", widgetnum);
-			xwidget = NULL;
-			
-			/*
-			 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
-			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0 is the bus
-			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0/1 is device
-			 */
-			rv = hwgraph_traverse(xtalk, pathname, &xwidget);
-			if ( (rv != GRAPH_SUCCESS) ) {
-				if (!xwidget) {
-					continue;
-				}
-			}
-	
-			if ( bus == 0 )
-				sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);
-			else
-				sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);
-			pci_bus = NULL;
-			if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
-				if (!pci_bus) {
-					continue;
-				}
-	
-			/*
-			 * Assign the correct bus number and also the nasid of this 
-			 * pci Xwidget.
-			 * 
-			 * Should not be any race here ...
-			 */
-			num_bridges++;
-			busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
-	
-			/*
-			 * Get the master node and from there get the NASID.
-			 */
-			master_node_vertex = device_master_get(xwidget);
-			if (!master_node_vertex) {
-				printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
-			}
-		
-			hubinfo_get(master_node_vertex, &hubinfo);
-			if (!hubinfo) {
-				printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
-				return(1);
-			} else {
-				busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
-			}
-	
-			/*
-			 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
-			 */
-			busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
-				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
-			if (!busnum_to_atedmamaps[num_bridges - 1])
-				printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
-	
-			memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
-				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
-		}
-	}
-
-        return(0);
-}
-
-/*
- * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure   
- *      initialization has completed to set up the mappings between Xbridge
- *      and logical pci bus numbers.  We also set up the NASID for each of these
- *      xbridges.
- *
- *      Must be called before pci_init() is invoked.
- */
-int
-pci_bus_to_hcl_cvlink(void) 
-{
-
-	devfs_handle_t devfs_hdl = NULL;
-	devfs_handle_t xtalk = NULL;
-	int rv = 0;
-	char name[256];
-	char tmp_name[256];
-	int master_iobrick;
-	slabid_t master_slab;
-	int i, ii;
-	extern nasid_t master_baseio_nasid;
-	extern nasid_t get_master_baseio_nasid(void);
-
-	/*
-	 * Iterate throught each xtalk links in the system ..
-	 * /hw/module/001c01/slab/0/node/xtalk/ 8|9|10|11|12|13|14|15 
-	 *
-	 * /hw/module/001c01/slab/0/node/xtalk/15 -> /hw/module/001c01/slab/0/Ibrick/xtalk/15
-	 *
-	 * What if it is not pci?
-	 */
-	devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module");
-
-	/*
-	 * To provide consistent(not persistent) device naming, we need to start 
-	 * bus number allocation from the C-Brick with the lowest module id e.g. 001c01 
-	 * with an attached I-Brick.  Find the master_iobrick.
-	 */
-	master_baseio_nasid = get_master_baseio_nasid();
-	master_iobrick = -1;
-	master_slab = -1;
-	if ( master_baseio_nasid >= 0 ) {
-		/* Valid nasid, need the slab ID */
-		for (i = 0; i < nummodules; i++) {
-			extern int iobrick_module_get_nasid(nasid_t);
-			moduleid_t iobrick_id; 
-			nasid_t nasid = -1;
-			int n = 0;
-			for ( n = 0; n < modules[i]->nodecnt; n++ ) {
-				nasid = cnodeid_to_nasid(modules[i]->nodes[n]);
-				iobrick_id = iobrick_module_get_nasid(nasid);
-				if (iobrick_id > 0) { /* Valid module id */
-					if ( master_baseio_nasid == nasid ) {
-						master_iobrick = i;
-						master_slab = geo_slab(modules[i]->geoid[n]);
-						printk("pci_bus_to_hcl_cvlink: Found Master Base IO Brick type %d Master Base I/O nasid %d Master Cbrick Index %d Slab %d\n", MODULE_GET_BTYPE(iobrick_id), master_baseio_nasid, master_iobrick, master_slab);
-						break;
-					}
-				}
-			}
-			if (master_slab >= 0)
-				break;
-		}
-	}
-	else {
-		/* Not sure which nasid it is - call failed, so make a guess */
-		for (i = 0; i < nummodules; i++) {
-			extern int iobrick_module_get_nasid(nasid_t);
-			moduleid_t iobrick_id; 
-			nasid_t nasid = -1;
-			int n = 0;
-			for ( n = 0; n < modules[i]->nodecnt; n++ ) {
-				nasid = cnodeid_to_nasid(modules[i]->nodes[n]);
-				iobrick_id = iobrick_module_get_nasid(nasid);
-				if (iobrick_id > 0) { /* Valid module id */
-					if ( (MODULE_GET_BTYPE(iobrick_id) == MODULE_IBRICK) || 
-					   		(MODULE_GET_BTYPE(iobrick_id) == MODULE_PXBRICK) ||
-				   			(MODULE_GET_BTYPE(iobrick_id) == MODULE_PBRICK) ) {
-						master_iobrick = i;
-						master_baseio_nasid = nasid;
-						master_slab = geo_slab(modules[i]->geoid[n]);
-						printk("pci_bus_to_hcl_cvlink: Found Master Base IO Brick type %d Master Cbrick Index %d Slab %d\n", MODULE_GET_BTYPE(iobrick_id), master_iobrick, master_slab);
-						break;
-					}
-				}
-			}
-			if (master_iobrick >= 0)
-				break;
-		}
-	}
-
-	if (master_iobrick == -1) {
-		panic("Unable to find the Master BaseIO PCI/PCIX Bus\n");
-	}
-
-	/*
-	 * The master_iobrick gets bus 0 and 1.
-	 */
-	if (master_iobrick >= 0) {
-		memset(name, 0, 256);
-		memset(tmp_name, 0, 256);
-		format_module_id(name, modules[master_iobrick]->id, MODULE_FORMAT_BRIEF);
-		sprintf(tmp_name, "/slab/%d/node/xtalk", master_slab);
-		strcat(name, tmp_name);
-		xtalk = NULL;
-		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-		pci_bus_map_create(xtalk);
-	}
-		
-	/*
-	 * Now go do the rest of the modules, starting from the C-Brick with the lowest 
-	 * module id, remembering to skip the master_iobrick, which was done above.
-	 */
-	for (i = 0; i < nummodules ; i++) {
-		for ( ii = 0; ii < MAX_SLABS; ii++ ) {
-			if ((i == master_iobrick) && (master_slab == ii))
-				continue; /* Did the master_iobrick/slab already. */
-			memset(name, 0, 256);
-			memset(tmp_name, 0, 256);
-			format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
-			sprintf(tmp_name, "/slab/%d/node/xtalk", ii);
-			strcat(name, tmp_name);
-			xtalk = NULL;
-			rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-			pci_bus_map_create(xtalk);
-		}
-	}
-
-	/*
-	 * Create the Linux PCI bus number vertex link.
-	 */
-	(void)linux_bus_cvlink();
-
-	return(0);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/Makefile linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/Makefile
--- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/Makefile	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/Makefile	2003-08-01 13:34:26.000000000 +0000
@@ -3,21 +3,20 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+# Copyright (C) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
 #
 # Makefile for the sn2 io pcibr routines.
 
 EXTRA_CFLAGS    := -DLITTLE_ENDIAN
 
-ifdef CONFIG_IA64_SGI_SN2
 EXTRA_CFLAGS    += -DSHUB_SWAP_WAR
-endif
 
 O_TARGET := pcibr.o
+export-objs := pcibr_intr.o
 
-obj-$(CONFIG_IA64_SGI_SN2)	+= pcibr_dvr.o pcibr_ate.o pcibr_config.o \
-                                   pcibr_dvr.o pcibr_hints.o \
-				   pcibr_intr.o pcibr_rrb.o pcibr_slot.o \
-				   pcibr_error.o
+obj-y	+= pcibr_ate.o pcibr_config.o \
+           pcibr_dvr.o pcibr_hints.o \
+	   pcibr_intr.o pcibr_rrb.o pcibr_slot.o \
+	   pcibr_error.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c	2003-06-13 14:51:30.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c	2003-08-01 13:34:21.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,23 +27,9 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
-#ifdef __ia64
-uint64_t atealloc(struct map *mp, size_t size);
-void atefree(struct map *mp, size_t size, uint64_t a);
-void atemapfree(struct map *mp);
-struct map *atemapalloc(uint64_t mapsiz);
-
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
-
 #ifndef LOCAL
 #define LOCAL           static
 #endif
@@ -101,73 +87,26 @@
     int                     i, j;
     bridgereg_t             old_enable, new_enable;
     int                     s;
-    int			    this_is_pic = is_pic(bridge);
 
     /* Probe SSRAM to determine its size. */
-    if ( this_is_pic ) {
-	old_enable = bridge->b_int_enable;
-	new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-	bridge->b_int_enable = new_enable;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		old_enable = BRIDGE_REG_GET32((&bridge->b_int_enable));
-		new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-		BRIDGE_REG_SET32((&bridge->b_int_enable)) = new_enable;
-	}
-	else {
-		old_enable = bridge->b_int_enable;
-		new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-		bridge->b_int_enable = new_enable;
-	}
-    }
+    old_enable = bridge->b_int_enable;
+    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
+    bridge->b_int_enable = new_enable;
 
     for (i = 1; i < ATE_NUM_SIZES; i++) {
 	/* Try writing a value */
-	if ( this_is_pic ) {
-		bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge)))
-			bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = __swab64(ATE_PROBE_VALUE);
-		else
-			bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
-	}
+	bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
 
 	/* Guard against wrap */
 	for (j = 1; j < i; j++)
 	    bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0;
 
 	/* See if value was written */
-	if ( this_is_pic ) {
-		if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
+	if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
 				largest_working_size = i;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == __swab64(ATE_PROBE_VALUE))
-					largest_working_size = i;
-			else {
-				if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
-					largest_working_size = i;
-			}
-		}
-	}
-    }
-    if ( this_is_pic ) {
-	bridge->b_int_enable = old_enable;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&bridge->b_int_enable)) = old_enable;
-		BRIDGE_REG_GET32((&bridge->b_wid_tflush));   /* wait until Bridge PIO complete */
-	}
-	else {
-		bridge->b_int_enable = old_enable;
-		bridge->b_wid_tflush;               /* wait until Bridge PIO complete */
-	}
     }
+    bridge->b_int_enable = old_enable;
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
 
     /*
      * ensure that we write and read without any interruption.
@@ -175,26 +114,10 @@
      */
 
     s = splhi();
-    if ( this_is_pic ) {
-	bridge->b_wid_control = (bridge->b_wid_control
+    bridge->b_wid_control = (bridge->b_wid_control
 			& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
 			| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
-	bridge->b_wid_control;		/* inval addr bug war */
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&(bridge->b_wid_control))) = 
-				__swab32((BRIDGE_REG_GET32((&bridge->b_wid_control))
-					& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
-					| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size));
-		BRIDGE_REG_GET32((&bridge->b_wid_control));/* inval addr bug war */
-	}
-	else {
-		bridge->b_wid_control = (bridge->b_wid_control & ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
-				| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
-		bridge->b_wid_control;              /* inval addr bug war */
-	}
-    }
+    bridge->b_wid_control;		/* inval addr bug war */
     splx(s);
 
     num_entries = ATE_NUM_ENTRIES(largest_working_size);
@@ -229,32 +152,55 @@
 int
 pcibr_ate_alloc(pcibr_soft_t pcibr_soft, int count)
 {
-    int                     index = 0;
-
-    index = (int) rmalloc(pcibr_soft->bs_int_ate_map, (size_t) count);
+    int			    status = 0;
+    struct resource	    *new_res;
+    struct resource         **allocated_res;
+
+    new_res = (struct resource *) kmalloc( sizeof(struct resource), GFP_ATOMIC);
+    memset(new_res, 0, sizeof(*new_res));
+    status = allocate_resource( &pcibr_soft->bs_int_ate_resource, new_res,
+				count, pcibr_soft->bs_int_ate_resource.start, 
+				pcibr_soft->bs_int_ate_resource.end, 1,
+				NULL, NULL);
+
+    if ( status && (pcibr_soft->bs_ext_ate_resource.end != 0) ) {
+	status = allocate_resource( &pcibr_soft->bs_ext_ate_resource, new_res,
+				count, pcibr_soft->bs_ext_ate_resource.start,
+				pcibr_soft->bs_ext_ate_resource.end, 1,
+				NULL, NULL);
+	if (status) {
+		new_res->start = -1;
+	}
+    }
 
-    if (!index && pcibr_soft->bs_ext_ate_map)
-	index = (int) rmalloc(pcibr_soft->bs_ext_ate_map, (size_t) count);
+    if (status) {
+	/* Failed to allocate */
+	kfree(new_res);
+	return -1;
+    }
+
+    /* Save the resource for freeing */
+    allocated_res = (struct resource **)(((unsigned long)pcibr_soft->bs_allocated_ate_res) + new_res->start * sizeof( unsigned long));
+    *allocated_res = new_res;
 
-    /* rmalloc manages resources in the 1..n
-     * range, with 0 being failure.
-     * pcibr_ate_alloc manages resources
-     * in the 0..n-1 range, with -1 being failure.
-     */
-    return index - 1;
+    return new_res->start;
 }
 
 void
 pcibr_ate_free(pcibr_soft_t pcibr_soft, int index, int count)
 /* Who says there's no such thing as a free meal? :-) */
 {
-    /* note the "+1" since rmalloc handles 1..n but
-     * we start counting ATEs at zero.
-     */
-    rmfree((index < pcibr_soft->bs_int_ate_size)
-	   ? pcibr_soft->bs_int_ate_map
-	   : pcibr_soft->bs_ext_ate_map,
-	   count, index + 1);
+
+    struct resource **allocated_res;
+    int status = 0;
+
+    allocated_res = (struct resource **)(((unsigned long)pcibr_soft->bs_allocated_ate_res) + index * sizeof(unsigned long));
+
+    status = release_resource(*allocated_res);
+    if (status)
+	BUG(); /* Ouch .. */
+    kfree(*allocated_res);
+
 }
 
 /*
@@ -362,7 +308,7 @@
 
     /* Bridge Hardware Bug WAR #484930:
      * Bridge can't handle updating External ATEs
-     * while DMA is occuring that uses External ATEs,
+     * while DMA is occurring that uses External ATEs,
      * even if the particular ATEs involved are disjoint.
      */
 
@@ -423,16 +369,7 @@
 			    /* Flush the write buffer associated with this
 			     * PCI device which might be using dma map RAM.
 			     */
-			if ( is_pic(bridge) ) {
-				bridge->b_wr_req_buf[slot].reg;
-			}
-			else {
-				if (io_get_sh_swapper(NASID_GET(bridge)) ) {
-					BRIDGE_REG_GET32((&bridge->b_wr_req_buf[slot].reg));
-				}
-				else
-					bridge->b_wr_req_buf[slot].reg;
-			}
+			bridge->b_wr_req_buf[slot].reg;
 		    }
 	    }
     }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c	2003-08-01 13:30:33.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -28,21 +28,18 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
-extern pcibr_info_t      pcibr_info_get(devfs_handle_t);
+extern pcibr_info_t      pcibr_info_get(vertex_hdl_t);
 
-uint64_t          pcibr_config_get(devfs_handle_t, unsigned, unsigned);
-uint64_t          do_pcibr_config_get(int, cfg_p, unsigned, unsigned);
-void              pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
-void       	  do_pcibr_config_set(int, cfg_p, unsigned, unsigned, uint64_t);
-static void	  swap_do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
+uint64_t          pcibr_config_get(vertex_hdl_t, unsigned, unsigned);
+uint64_t          do_pcibr_config_get(cfg_p, unsigned, unsigned);
+void              pcibr_config_set(vertex_hdl_t, unsigned, unsigned, uint64_t);
+void       	  do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
 
-#ifdef LITTLE_ENDIAN
 /*
- * on sn-ia we need to twiddle the addresses going out
+ * on sn-ia we need to twiddle the the addresses going out
  * the pci bus because we use the unswizzled synergy space
  * (the alternative is to use the swizzled synergy space
  * and byte swap the data)
@@ -51,18 +48,13 @@
 #define CS(b,r) (((volatile uint16_t *) b)[((r^4)/2)])
 #define CW(b,r) (((volatile uint32_t *) b)[((r^4)/4)])
 
-#define	CBP(b,r) (((volatile uint8_t *) b)[(r)^3])
-#define	CSP(b,r) (((volatile uint16_t *) b)[((r)/2)^1])
+#define	CBP(b,r) (((volatile uint8_t *) b)[(r)])
+#define	CSP(b,r) (((volatile uint16_t *) b)[((r)/2)])
 #define	CWP(b,r) (((volatile uint32_t *) b)[(r)/4])
 
 #define SCB(b,r) (((volatile uint8_t *) b)[((r)^3)])
 #define SCS(b,r) (((volatile uint16_t *) b)[((r^2)/2)])
 #define SCW(b,r) (((volatile uint32_t *) b)[((r)/4)])
-#else
-#define	CB(b,r)	(((volatile uint8_t *) cfgbase)[(r)^3])
-#define	CS(b,r)	(((volatile uint16_t *) cfgbase)[((r)/2)^1])
-#define	CW(b,r)	(((volatile uint32_t *) cfgbase)[(r)/4])
-#endif
 
 /*
  * Return a config space address for given slot / func / offset.  Note the
@@ -84,8 +76,7 @@
 	/*
 	 * Type 0 config space
 	 */
-	if (is_pic(bridge))
-		slot++;
+	slot++;
 	return &bridge->b_type0_cfg_dev[slot].f[func].l[offset];
 }
 
@@ -109,7 +100,7 @@
 	cfg_p  cfg_base;
 	
 	cfg_base = pcibr_slot_config_addr(bridge, slot, 0);
-	return (do_pcibr_config_get(is_pic(bridge), cfg_base, offset, sizeof(unsigned)));
+	return (do_pcibr_config_get(cfg_base, offset, sizeof(unsigned)));
 }
 
 /*
@@ -122,7 +113,7 @@
 	cfg_p  cfg_base;
 
 	cfg_base = pcibr_func_config_addr(bridge, 0, slot, func, 0);
-	return (do_pcibr_config_get(is_pic(bridge), cfg_base, offset, sizeof(unsigned)));
+	return (do_pcibr_config_get(cfg_base, offset, sizeof(unsigned)));
 }
 
 /*
@@ -135,7 +126,7 @@
 	cfg_p  cfg_base;
 
 	cfg_base = pcibr_slot_config_addr(bridge, slot, 0);
-	do_pcibr_config_set(is_pic(bridge), cfg_base, offset, sizeof(unsigned), val);
+	do_pcibr_config_set(cfg_base, offset, sizeof(unsigned), val);
 }
 
 /*
@@ -148,13 +139,13 @@
 	cfg_p  cfg_base;
 
 	cfg_base = pcibr_func_config_addr(bridge, 0, slot, func, 0);
-	do_pcibr_config_set(is_pic(bridge), cfg_base, offset, sizeof(unsigned), val);
+	do_pcibr_config_set(cfg_base, offset, sizeof(unsigned), val);
 }
 
 int pcibr_config_debug = 0;
 
 cfg_p
-pcibr_config_addr(devfs_handle_t conn,
+pcibr_config_addr(vertex_hdl_t conn,
 		  unsigned reg)
 {
     pcibr_info_t            pcibr_info;
@@ -183,19 +174,6 @@
 	pciio_func = PCI_TYPE1_FUNC(reg);
 
 	ASSERT(pciio_bus != 0);
-#if 0
-    } else if (conn != pciio_info_hostdev_get(pciio_info)) {
-	/*
-	 * Conn is on a subordinate bus, so get bus/slot/func directly from
-	 * its pciio_info_t structure.
-	 */
-	pciio_bus = pciio_info->c_bus;
-	pciio_slot = pciio_info->c_slot;
-	pciio_func = pciio_info->c_func;
-	if (pciio_func == PCIIO_FUNC_NONE) {
-		pciio_func = 0;
-	}
-#endif
     } else {
 	/*
 	 * Conn is directly connected to the host bus.  PCI bus number is
@@ -224,44 +202,23 @@
     return cfgbase;
 }
 
-extern unsigned char Is_pic_on_this_nasid[];
 uint64_t
-pcibr_config_get(devfs_handle_t conn,
+pcibr_config_get(vertex_hdl_t conn,
 		 unsigned reg,
 		 unsigned size)
 {
-    if ( !Is_pic_on_this_nasid[ NASID_GET((pcibr_config_addr(conn, reg)))] )
-    	return do_pcibr_config_get(0, pcibr_config_addr(conn, reg),
-				PCI_TYPE1_REG(reg), size);
-    else
-    	return do_pcibr_config_get(1, pcibr_config_addr(conn, reg),
+	return do_pcibr_config_get(pcibr_config_addr(conn, reg),
 				PCI_TYPE1_REG(reg), size);
 }
 
 uint64_t
-do_pcibr_config_get(
-		       int pic,
-		       cfg_p cfgbase,
+do_pcibr_config_get(cfg_p cfgbase,
 		       unsigned reg,
 		       unsigned size)
 {
     unsigned                value;
 
-    if ( pic ) {
-	value = CWP(cfgbase, reg);
-    }
-    else {
-	if ( io_get_sh_swapper(NASID_GET(cfgbase)) ) {
-	    /*
-	     * Shub Swapper on - 0 returns PCI Offset 0 but byte swapped!
-	     * Do not swizzle address and byte swap the result.
-	     */
-	    value = SCW(cfgbase, reg);
-	    value = __swab32(value);
-	} else {
-    	    value = CW(cfgbase, reg);
-	}
-    }
+    value = CWP(cfgbase, reg);
     if (reg & 3)
 	value >>= 8 * (reg & 3);
     if (size < 4)
@@ -270,108 +227,43 @@
 }
 
 void
-pcibr_config_set(devfs_handle_t conn,
+pcibr_config_set(vertex_hdl_t conn,
 		 unsigned reg,
 		 unsigned size,
 		 uint64_t value)
 {
-    if ( Is_pic_on_this_nasid[ NASID_GET((pcibr_config_addr(conn, reg)))] )
-    	do_pcibr_config_set(1, pcibr_config_addr(conn, reg),
-			PCI_TYPE1_REG(reg), size, value);
-    else
-	swap_do_pcibr_config_set(pcibr_config_addr(conn, reg),
+	do_pcibr_config_set(pcibr_config_addr(conn, reg),
 			PCI_TYPE1_REG(reg), size, value);
 }
 
 void
-do_pcibr_config_set(int pic,
-		    cfg_p cfgbase,
+do_pcibr_config_set(cfg_p cfgbase,
 		    unsigned reg,
 		    unsigned size,
 		    uint64_t value)
 {
-	if ( pic ) {
-		switch (size) {
-		case 1:
+	switch (size) {
+	case 1:
+		CBP(cfgbase, reg) = value;
+		break;
+	case 2:
+		if (reg & 1) {
 			CBP(cfgbase, reg) = value;
-			break;
-		case 2:
-			if (reg & 1) {
-				CBP(cfgbase, reg) = value;
-				CBP(cfgbase, reg + 1) = value >> 8;
-			} else
-				CSP(cfgbase, reg) = value;
-			break;
-		case 3:
-			if (reg & 1) {
-				CBP(cfgbase, reg) = value;
-				CSP(cfgbase, (reg + 1)) = value >> 8;
-			} else {
-				CSP(cfgbase, reg) = value;
-				CBP(cfgbase, reg + 2) = value >> 16;
-			}
-			break;
-		case 4:
-			CWP(cfgbase, reg) = value;
-			break;
-   		}
-	}
-	else {
-		switch (size) {
-		case 1:
-			CB(cfgbase, reg) = value;
-			break;
-		case 2:
-			if (reg & 1) {
-				CB(cfgbase, reg) = value;
-				CB(cfgbase, reg + 1) = value >> 8;
-			} else
-				CS(cfgbase, reg) = value;
-			break;
-		case 3:
-			if (reg & 1) {
-				CB(cfgbase, reg) = value;
-				CS(cfgbase, (reg + 1)) = value >> 8;
-			} else {
-				CS(cfgbase, reg) = value;
-				CB(cfgbase, reg + 2) = value >> 16;
-			}
-			break;
-		case 4:
-			CW(cfgbase, reg) = value;
-			break;
-   		}
-	}
-}
-
-void
-swap_do_pcibr_config_set(cfg_p cfgbase,
-                    unsigned reg,
-                    unsigned size,
-                    uint64_t value)
-{
-
-    uint64_t temp_value = 0;
-
-    switch (size) {
-    case 1:
-        SCB(cfgbase, reg) = value;
-        break;
-    case 2:
-	temp_value = __swab16(value);
-        if (reg & 1) {
-            SCB(cfgbase, reg) = temp_value;
-            SCB(cfgbase, reg + 1) = temp_value >> 8;
-        } else
-            SCS(cfgbase, reg) = temp_value;
-        break;
-    case 3:
-	BUG();
-        break;
-
-    case 4:
-	temp_value = __swab32(value);
-        SCW(cfgbase, reg) = temp_value;
-        break;
-    }
+			CBP(cfgbase, reg + 1) = value >> 8;
+		} else
+			CSP(cfgbase, reg) = value;
+		break;
+	case 3:
+		if (reg & 1) {
+			CBP(cfgbase, reg) = value;
+			CSP(cfgbase, (reg + 1)) = value >> 8;
+		} else {
+			CSP(cfgbase, reg) = value;
+			CBP(cfgbase, reg + 2) = value >> 16;
+		}
+		break;
+	case 4:
+		CWP(cfgbase, reg) = value;
+		break;
+ 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c	2003-08-01 13:32:51.000000000 +0000
@@ -4,13 +4,17 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/sn_sal.h>
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
@@ -18,6 +22,7 @@
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
+#include <asm/sn/klconfig.h>
 #include <asm/sn/xtalk/xwidget.h>
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/pci/pciio.h>
@@ -27,17 +32,9 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
 /*
  * global variables to toggle the different levels of pcibr debugging.  
  *   -pcibr_debug_mask is the mask of the different types of debugging
@@ -74,32 +71,6 @@
 #define USS302_BRIDGE_TIMEOUT_HLD	4
 #endif
 
-int                     pcibr_devflag = D_MP;
-
-/*
- * This is the file operation table for the pcibr driver.
- * As each of the functions are implemented, put the
- * appropriate function name below.
- */
-struct file_operations pcibr_fops = {
-	owner:  THIS_MODULE,
-	llseek: NULL,
-	read: NULL,
-	write: NULL,
-	readdir: NULL,
-	poll: NULL,
-	ioctl: NULL,
-	mmap: NULL,
-	open: NULL,
-	flush: NULL,
-	release: NULL,
-	fsync: NULL,
-	fasync: NULL,
-	lock: NULL,
-	readv: NULL,
-	writev: NULL
-};
-
 /* kbrick widgetnum-to-bus layout */
 int p_busnum[MAX_PORT_NUM] = {                  /* widget#      */
         0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7    */
@@ -116,17 +87,16 @@
 pcibr_list_p            pcibr_list = 0;
 #endif
 
-extern int              hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-extern int              hub_device_flags_set(devfs_handle_t widget_dev, hub_widget_flags_t flags);
+extern int              hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen);
 extern long             atoi(register char *p);
-extern cnodeid_t        nodevertex_to_cnodeid(devfs_handle_t vhdl);
-extern char             *dev_to_name(devfs_handle_t dev, char *buf, uint buflen);
+extern cnodeid_t        nodevertex_to_cnodeid(vertex_hdl_t vhdl);
+extern char             *dev_to_name(vertex_hdl_t dev, char *buf, uint buflen);
 extern struct map       *atemapalloc(uint64_t);
 extern void             atefree(struct map *, size_t, uint64_t);
 extern void             atemapfree(struct map *);
-extern pciio_dmamap_t   get_free_pciio_dmamap(devfs_handle_t);
+extern pciio_dmamap_t   get_free_pciio_dmamap(vertex_hdl_t);
 extern void		free_pciio_dmamap(pcibr_dmamap_t);
-extern void		xwidget_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t);
+extern void		xwidget_error_register(vertex_hdl_t, error_handler_f *, error_handler_arg_t);
 
 #define	ATE_WRITE()    ate_write(pcibr_soft, ate_ptr, ate_count, ate)
 #if PCIBR_FREEZE_TIME
@@ -153,9 +123,9 @@
 extern int		 do_pcibr_rrb_free_all(pcibr_soft_t, bridge_t *, pciio_slot_t);
 extern void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int, int);
 
-extern int  		 pcibr_wrb_flush(devfs_handle_t);
-extern int               pcibr_rrb_alloc(devfs_handle_t, int *, int *);
-extern void              pcibr_rrb_flush(devfs_handle_t);
+extern int  		 pcibr_wrb_flush(vertex_hdl_t);
+extern int               pcibr_rrb_alloc(vertex_hdl_t, int *, int *);
+extern void              pcibr_rrb_flush(vertex_hdl_t);
 
 static int                pcibr_try_set_device(pcibr_soft_t, pciio_slot_t, unsigned, bridgereg_t);
 void                     pcibr_release_device(pcibr_soft_t, pciio_slot_t, bridgereg_t);
@@ -166,21 +136,15 @@
 extern iopaddr_t         pcibr_bus_addr_alloc(pcibr_soft_t, pciio_win_info_t,
                                               pciio_space_t, int, int, int);
 
-void                     pcibr_init(void);
-int                      pcibr_attach(devfs_handle_t);
-int			 pcibr_attach2(devfs_handle_t, bridge_t *, devfs_handle_t,
+int                      pcibr_attach(vertex_hdl_t);
+int			 pcibr_attach2(vertex_hdl_t, bridge_t *, vertex_hdl_t,
 				       int, pcibr_soft_t *);
-int			 pcibr_detach(devfs_handle_t);
-int                      pcibr_open(devfs_handle_t *, int, int, cred_t *);
-int                      pcibr_close(devfs_handle_t, int, int, cred_t *);
-int                      pcibr_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                      pcibr_unmap(devfs_handle_t, vhandl_t *);
-int                      pcibr_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
+int			 pcibr_detach(vertex_hdl_t);
 int			 pcibr_pcix_rbars_calc(pcibr_soft_t);
 extern int               pcibr_init_ext_ate_ram(bridge_t *);
 extern int               pcibr_ate_alloc(pcibr_soft_t, int);
 extern void              pcibr_ate_free(pcibr_soft_t, int, int);
-extern int 		 pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl);
+extern int 		 pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl);
 
 extern unsigned ate_freeze(pcibr_dmamap_t pcibr_dmamap,
 #if PCIBR_FREEZE_TIME
@@ -197,45 +161,43 @@
 	 		unsigned *cmd_regs,
 	 		unsigned s);
 
-pcibr_info_t      pcibr_info_get(devfs_handle_t);
+pcibr_info_t      pcibr_info_get(vertex_hdl_t);
 
-static iopaddr_t         pcibr_addr_pci_to_xio(devfs_handle_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned);
+static iopaddr_t         pcibr_addr_pci_to_xio(vertex_hdl_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned);
 
-pcibr_piomap_t          pcibr_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
+pcibr_piomap_t          pcibr_piomap_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
 void                    pcibr_piomap_free(pcibr_piomap_t);
 caddr_t                 pcibr_piomap_addr(pcibr_piomap_t, iopaddr_t, size_t);
 void                    pcibr_piomap_done(pcibr_piomap_t);
-caddr_t                 pcibr_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-iopaddr_t               pcibr_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pcibr_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
+caddr_t                 pcibr_piotrans_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
+iopaddr_t               pcibr_piospace_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, size_t, size_t);
+void                    pcibr_piospace_free(vertex_hdl_t, pciio_space_t, iopaddr_t, size_t);
 
 static iopaddr_t         pcibr_flags_to_d64(unsigned, pcibr_soft_t);
 extern bridge_ate_t     pcibr_flags_to_ate(unsigned);
 
-pcibr_dmamap_t          pcibr_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
+pcibr_dmamap_t          pcibr_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned);
 void                    pcibr_dmamap_free(pcibr_dmamap_t);
 extern bridge_ate_p     pcibr_ate_addr(pcibr_soft_t, int);
 static iopaddr_t         pcibr_addr_xio_to_pci(pcibr_soft_t, iopaddr_t, size_t);
 iopaddr_t               pcibr_dmamap_addr(pcibr_dmamap_t, paddr_t, size_t);
-alenlist_t              pcibr_dmamap_list(pcibr_dmamap_t, alenlist_t, unsigned);
 void                    pcibr_dmamap_done(pcibr_dmamap_t);
-cnodeid_t		pcibr_get_dmatrans_node(devfs_handle_t);
-iopaddr_t               pcibr_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pcibr_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
+cnodeid_t		pcibr_get_dmatrans_node(vertex_hdl_t);
+iopaddr_t               pcibr_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned);
 void                    pcibr_dmamap_drain(pcibr_dmamap_t);
-void                    pcibr_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void                    pcibr_dmalist_drain(devfs_handle_t, alenlist_t);
+void                    pcibr_dmaaddr_drain(vertex_hdl_t, paddr_t, size_t);
+void                    pcibr_dmalist_drain(vertex_hdl_t, alenlist_t);
 iopaddr_t               pcibr_dmamap_pciaddr_get(pcibr_dmamap_t);
 
 extern unsigned		pcibr_intr_bits(pciio_info_t info, 
 					pciio_intr_line_t lines, int nslots);
-extern pcibr_intr_t     pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
+extern pcibr_intr_t     pcibr_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t);
 extern void             pcibr_intr_free(pcibr_intr_t);
 extern void             pcibr_setpciint(xtalk_intr_t);
 extern int              pcibr_intr_connect(pcibr_intr_t, intr_func_t, intr_arg_t);
 extern void             pcibr_intr_disconnect(pcibr_intr_t);
 
-extern devfs_handle_t     pcibr_intr_cpu_get(pcibr_intr_t);
+extern vertex_hdl_t     pcibr_intr_cpu_get(pcibr_intr_t);
 extern void             pcibr_intr_func(intr_arg_t);
 
 extern void             print_bridge_errcmd(uint32_t, char *);
@@ -253,51 +215,48 @@
 extern int              pcibr_dmawr_error(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *);
 extern int              pcibr_error_handler(error_handler_arg_t, int, ioerror_mode_t, ioerror_t *);
 extern int              pcibr_error_handler_wrapper(error_handler_arg_t, int, ioerror_mode_t, ioerror_t *);
-void                    pcibr_provider_startup(devfs_handle_t);
-void                    pcibr_provider_shutdown(devfs_handle_t);
+void                    pcibr_provider_startup(vertex_hdl_t);
+void                    pcibr_provider_shutdown(vertex_hdl_t);
 
-int                     pcibr_reset(devfs_handle_t);
-pciio_endian_t          pcibr_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
+int                     pcibr_reset(vertex_hdl_t);
+pciio_endian_t          pcibr_endian_set(vertex_hdl_t, pciio_endian_t, pciio_endian_t);
 int                     pcibr_priority_bits_set(pcibr_soft_t, pciio_slot_t, pciio_priority_t);
-pciio_priority_t        pcibr_priority_set(devfs_handle_t, pciio_priority_t);
-int                     pcibr_device_flags_set(devfs_handle_t, pcibr_device_flags_t);
+pciio_priority_t        pcibr_priority_set(vertex_hdl_t, pciio_priority_t);
+int                     pcibr_device_flags_set(vertex_hdl_t, pcibr_device_flags_t);
+
+extern cfg_p            pcibr_config_addr(vertex_hdl_t, unsigned);
+extern uint64_t         pcibr_config_get(vertex_hdl_t, unsigned, unsigned);
+extern void             pcibr_config_set(vertex_hdl_t, unsigned, unsigned, uint64_t);
+
+extern pcibr_hints_t    pcibr_hints_get(vertex_hdl_t, int);
+extern void             pcibr_hints_fix_rrbs(vertex_hdl_t);
+extern void             pcibr_hints_dualslot(vertex_hdl_t, pciio_slot_t, pciio_slot_t);
+extern void	 	pcibr_hints_intr_bits(vertex_hdl_t, pcibr_intr_bits_f *);
+extern void             pcibr_set_rrb_callback(vertex_hdl_t, rrb_alloc_funct_t);
+extern void             pcibr_hints_handsoff(vertex_hdl_t);
+extern void             pcibr_hints_subdevs(vertex_hdl_t, pciio_slot_t, uint64_t);
 
-extern cfg_p            pcibr_config_addr(devfs_handle_t, unsigned);
-extern uint64_t         pcibr_config_get(devfs_handle_t, unsigned, unsigned);
-extern void             pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
-
-extern pcibr_hints_t    pcibr_hints_get(devfs_handle_t, int);
-extern void             pcibr_hints_fix_rrbs(devfs_handle_t);
-extern void             pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
-extern void	 	pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
-extern void             pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t);
-extern void             pcibr_hints_handsoff(devfs_handle_t);
-extern void             pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t);
-
-extern int		pcibr_slot_reset(devfs_handle_t,pciio_slot_t);
-extern int		pcibr_slot_info_init(devfs_handle_t,pciio_slot_t);
-extern int		pcibr_slot_info_free(devfs_handle_t,pciio_slot_t);
+extern int		pcibr_slot_info_init(vertex_hdl_t,pciio_slot_t);
+extern int		pcibr_slot_info_free(vertex_hdl_t,pciio_slot_t);
 extern int	        pcibr_slot_info_return(pcibr_soft_t, pciio_slot_t,
                                                pcibr_slot_info_resp_t);
 extern void       	pcibr_slot_func_info_return(pcibr_info_h, int,
                                                     pcibr_slot_func_info_resp_t);
-extern int		pcibr_slot_addr_space_init(devfs_handle_t,pciio_slot_t);
+extern int		pcibr_slot_addr_space_init(vertex_hdl_t,pciio_slot_t);
 extern int		pcibr_slot_pcix_rbar_init(pcibr_soft_t, pciio_slot_t);
-extern int		pcibr_slot_device_init(devfs_handle_t, pciio_slot_t);
-extern int		pcibr_slot_guest_info_init(devfs_handle_t,pciio_slot_t);
-extern int		pcibr_slot_call_device_attach(devfs_handle_t,
+extern int		pcibr_slot_device_init(vertex_hdl_t, pciio_slot_t);
+extern int		pcibr_slot_guest_info_init(vertex_hdl_t,pciio_slot_t);
+extern int		pcibr_slot_call_device_attach(vertex_hdl_t,
 						      pciio_slot_t, int);
-extern int		pcibr_slot_call_device_detach(devfs_handle_t,
+extern int		pcibr_slot_call_device_detach(vertex_hdl_t,
 						      pciio_slot_t, int);
-extern int              pcibr_slot_attach(devfs_handle_t, pciio_slot_t, int, 
+extern int              pcibr_slot_attach(vertex_hdl_t, pciio_slot_t, int, 
                                                       char *, int *);
-extern int              pcibr_slot_detach(devfs_handle_t, pciio_slot_t, int,
+extern int              pcibr_slot_detach(vertex_hdl_t, pciio_slot_t, int,
                                                       char *, int *);
-extern int 		pcibr_is_slot_sys_critical(devfs_handle_t, pciio_slot_t);
-
-extern int		pcibr_slot_initial_rrb_alloc(devfs_handle_t, pciio_slot_t);
-extern int		pcibr_initial_rrb(devfs_handle_t, pciio_slot_t, pciio_slot_t);
 
+extern int		pcibr_slot_initial_rrb_alloc(vertex_hdl_t, pciio_slot_t);
+extern int		pcibr_initial_rrb(vertex_hdl_t, pciio_slot_t, pciio_slot_t);
 
 /* =====================================================================
  *    Device(x) register management
@@ -623,172 +582,52 @@
  */
 
 
-/*
- *    pcibr_init: called once during system startup or
- *      when a loadable driver is loaded.
- *
- *      The driver_register function should normally
- *      be in _reg, not _init.  But the pcibr driver is
- *      required by devinit before the _reg routines
- *      are called, so this is an exception.
- */
-void
-pcibr_init(void)
+static int
+pcibr_mmap(struct file * file, struct vm_area_struct * vma)
 {
-    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INIT, NULL, "pcibr_init()\n"));
+	vertex_hdl_t		pcibr_vhdl;
+	pcibr_soft_t            pcibr_soft;
+	bridge_t               *bridge;
+	unsigned long		phys_addr;
+	int			error = 0;
 
-    xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM,
-			    XBRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
-    xwidget_driver_register(BRIDGE_WIDGET_PART_NUM,
-			    BRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
+#ifdef CONFIG_HWGFS_FS
+	pcibr_vhdl = (vertex_hdl_t) file->f_dentry->d_fsdata;
+#else
+	pcibr_vhdl = (vertex_hdl_t) file->private_data;
+#endif
+	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+	bridge = pcibr_soft->bs_base;
+	phys_addr = (unsigned long)bridge & ~0xc000000000000000; /* Mask out the Uncache bits */
+        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+        vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
+        error = io_remap_page_range(vma->vm_start, phys_addr,
+                                   vma->vm_end-vma->vm_start,
+                                   vma->vm_page_prot);
+	return(error);
 }
 
 /*
- * open/close mmap/munmap interface would be used by processes
- * that plan to map the PCI bridge, and muck around with the
- * registers. This is dangerous to do, and will be allowed
- * to a select brand of programs. Typically these are
- * diagnostics programs, or some user level commands we may
- * write to do some weird things.
- * To start with expect them to have root priveleges.
- * We will ask for more later.
+ * This is the file operation table for the pcibr driver.
+ * As each of the functions are implemented, put the
+ * appropriate function name below.
  */
-/* ARGSUSED */
-int
-pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    int                     error;
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get(vhdl);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    ASSERT(pcibr_soft);
-    len = ctob(btoc(len));		/* Make len page aligned */
-    error = v_mapphys(vt, (void *) ((__psunsigned_t) bridge + off), len);
-
-    /*
-     * If the offset being mapped corresponds to the flash prom
-     * base, and if the mapping succeeds, and if the user
-     * has requested the protections to be WRITE, enable the
-     * flash prom to be written.
-     *
-     * XXX- deprecate this in favor of using the
-     * real flash driver ...
-     */
-    if (IS_BRIDGE_SOFT(pcibr_soft) && !error &&
-	((off == BRIDGE_EXTERNAL_FLASH) ||
-	 (len > BRIDGE_EXTERNAL_FLASH))) {
-	int                     s;
-
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	s = splhi();
-
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&bridge->b_wid_control)) |= __swab32(BRIDGE_CTRL_FLASH_WR_EN);
-		BRIDGE_REG_GET32((&bridge->b_wid_control));          /* inval addr bug war */
-	} else {
-		bridge->b_wid_control |= BRIDGE_CTRL_FLASH_WR_EN;
-		bridge->b_wid_control;          /* inval addr bug war */
-	}
-	splx(s);
-    }
-    return error;
-}
-
-/*ARGSUSED */
-int
-pcibr_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    if ( IS_PIC_SOFT(pcibr_soft) ) {
-	/*
-	 * If flashprom write was enabled, disable it, as
-	 * this is the last unmap.
-	 */
-	if (IS_BRIDGE_SOFT(pcibr_soft) && 
-			(bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN)) {
-		int                     s;
-
-		/*
-		 * ensure that we write and read without any interruption.
-		 * The read following the write is required for the Bridge war
-		 */
-		s = splhi();
-		bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN;
-		bridge->b_wid_control;		/* inval addr bug war */
-		splx(s);
-	}
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		if (BRIDGE_REG_GET32((&bridge->b_wid_control)) & BRIDGE_CTRL_FLASH_WR_EN) {
-			int                     s;
-
-			/*
-			 * ensure that we write and read without any interruption.
-			 * The read following the write is required for the Bridge war
-			 */
-			s = splhi();
-			BRIDGE_REG_SET32((&bridge->b_wid_control)) &= __swab32((unsigned int)~BRIDGE_CTRL_FLASH_WR_EN);
-			BRIDGE_REG_GET32((&bridge->b_wid_control));          /* inval addr bug war */
-			splx(s);
-		} else {
-			if (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN) {
-				int                     s;
+static int pcibr_mmap(struct file * file, struct vm_area_struct * vma);
+struct file_operations pcibr_fops = {
+	.owner		= THIS_MODULE,
+	.mmap		= pcibr_mmap,
+};
 
-				/*
-				 * ensure that we write and read without any interruption.
-				 * The read following the write is required for the Bridge war
-				 */
-				s = splhi();
-				bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN;
-				bridge->b_wid_control;          /* inval addr bug war */
-				splx(s);
-    			}
-		}
-	}
-    }
-    return 0;
-}
 
 /* This is special case code used by grio. There are plans to make
  * this a bit more general in the future, but till then this should
  * be sufficient.
  */
 pciio_slot_t
-pcibr_device_slot_get(devfs_handle_t dev_vhdl)
+pcibr_device_slot_get(vertex_hdl_t dev_vhdl)
 {
     char                    devname[MAXDEVNAME];
-    devfs_handle_t            tdev;
+    vertex_hdl_t            tdev;
     pciio_info_t            pciio_info;
     pciio_slot_t            slot = PCIIO_SLOT_NONE;
 
@@ -812,20 +651,8 @@
     return slot;
 }
 
-/*ARGSUSED */
-int
-pcibr_ioctl(devfs_handle_t dev,
-	    int cmd,
-	    void *arg,
-	    int flag,
-	    struct cred *cr,
-	    int *rvalp)
-{
-    return 0;
-}
-
 pcibr_info_t
-pcibr_info_get(devfs_handle_t vhdl)
+pcibr_info_get(vertex_hdl_t vhdl)
 {
     return (pcibr_info_t) pciio_info_get(vhdl);
 }
@@ -849,7 +676,7 @@
      * will set the c_slot (which is suppose to represent the external
      * slot (i.e the slot number silk screened on the back of the I/O
      * brick)).  So for PIC we need to adjust this "internal slot" num
-     * passed into us, into it's external representation.  See comment
+     * passed into us, into its external representation.  See comment
      * for the PCIBR_DEVICE_TO_SLOT macro for more information.
      */
     NEW(pcibr_info);
@@ -902,10 +729,10 @@
  *	This is usually used at the time of shutting down of the PCI card.
  */
 int
-pcibr_device_unregister(devfs_handle_t pconn_vhdl)
+pcibr_device_unregister(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t	 pciio_info;
-    devfs_handle_t	 pcibr_vhdl;
+    vertex_hdl_t	 pcibr_vhdl;
     pciio_slot_t	 slot;
     pcibr_soft_t	 pcibr_soft;
     bridge_t		*bridge;
@@ -982,12 +809,12 @@
  *      slot's device status to be set.
  */
 void
-pcibr_driver_reg_callback(devfs_handle_t pconn_vhdl,
+pcibr_driver_reg_callback(vertex_hdl_t pconn_vhdl,
 			  int key1, int key2, int error)
 {
     pciio_info_t	 pciio_info;
     pcibr_info_t         pcibr_info;
-    devfs_handle_t	 pcibr_vhdl;
+    vertex_hdl_t	 pcibr_vhdl;
     pciio_slot_t	 slot;
     pcibr_soft_t	 pcibr_soft;
 
@@ -1033,12 +860,12 @@
  *      slot's device status to be set.
  */
 void
-pcibr_driver_unreg_callback(devfs_handle_t pconn_vhdl, 
+pcibr_driver_unreg_callback(vertex_hdl_t pconn_vhdl, 
                             int key1, int key2, int error)
 {
     pciio_info_t	 pciio_info;
     pcibr_info_t         pcibr_info;
-    devfs_handle_t	 pcibr_vhdl;
+    vertex_hdl_t	 pcibr_vhdl;
     pciio_slot_t	 slot;
     pcibr_soft_t	 pcibr_soft;
 
@@ -1084,14 +911,14 @@
  * depends on hwgraph separator == '/'
  */
 int
-pcibr_bus_cnvlink(devfs_handle_t f_c)
+pcibr_bus_cnvlink(vertex_hdl_t f_c)
 {
         char dst[MAXDEVNAME];
 	char *dp = dst;
         char *cp, *xp;
         int widgetnum;
         char pcibus[8];
-	devfs_handle_t nvtx, svtx;
+	vertex_hdl_t nvtx, svtx;
 	int rv;
 
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, f_c, "pcibr_bus_cnvlink\n"));
@@ -1105,7 +932,7 @@
 	xp = strstr(dst, "/"EDGE_LBL_XTALK"/");
 	if (xp == NULL)
 		return 0;
-	widgetnum = atoi(xp+7);
+	widgetnum = simple_strtoul(xp+7, NULL, 0);
 	if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F)
 		return 0;
 
@@ -1145,11 +972,11 @@
  */
 /*ARGSUSED */
 int
-pcibr_attach(devfs_handle_t xconn_vhdl)
+pcibr_attach(vertex_hdl_t xconn_vhdl)
 {
     /* REFERENCED */
     graph_error_t           rc;
-    devfs_handle_t            pcibr_vhdl;
+    vertex_hdl_t            pcibr_vhdl;
     bridge_t               *bridge;
 
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, xconn_vhdl, "pcibr_attach\n"));
@@ -1180,11 +1007,11 @@
 
 /*ARGSUSED */
 int
-pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, 
-	      devfs_handle_t pcibr_vhdl, int busnum, pcibr_soft_t *ret_softp)
+pcibr_attach2(vertex_hdl_t xconn_vhdl, bridge_t *bridge, 
+	      vertex_hdl_t pcibr_vhdl, int busnum, pcibr_soft_t *ret_softp)
 {
     /* REFERENCED */
-    devfs_handle_t            ctlr_vhdl;
+    vertex_hdl_t            ctlr_vhdl;
     bridgereg_t             id;
     int                     rev;
     pcibr_soft_t            pcibr_soft;
@@ -1193,7 +1020,7 @@
     xtalk_intr_t            xtalk_intr;
     int                     slot;
     int                     ibit;
-    devfs_handle_t            noslot_conn;
+    vertex_hdl_t            noslot_conn;
     char                    devnm[MAXDEVNAME], *s;
     pcibr_hints_t           pcibr_hints;
     uint64_t              int_enable;
@@ -1209,23 +1036,15 @@
     nasid_t		    nasid;
     int	                    iobrick_type_get_nasid(nasid_t nasid);
     int                     iobrick_module_get_nasid(nasid_t nasid);
-    extern unsigned char    Is_pic_on_this_nasid[512];
-
-
-    async_attach_t          aa = NULL;
 
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,
 	        "pcibr_attach2: bridge=0x%p, busnum=%d\n", bridge, busnum));
 
-    aa = async_attach_get_info(xconn_vhdl);
-
     ctlr_vhdl = NULL;
-    ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER,
-                0, DEVFS_FL_AUTO_DEVNUM,
-                0, 0,
-                S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                &pcibr_fops, NULL);
-
+    ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER, 0, 
+                DEVFS_FL_AUTO_DEVNUM, 0, 0,
+		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, 
+		(struct file_operations *)&pcibr_fops, (void *)pcibr_vhdl);
     ASSERT(ctlr_vhdl != NULL);
 
     /*
@@ -1261,13 +1080,7 @@
     pcibr_soft->bs_min_slot = 0;		/* lowest possible slot# */
     pcibr_soft->bs_max_slot = 7;		/* highest possible slot# */
     pcibr_soft->bs_busnum = busnum;
-    if (is_xbridge(bridge)) {
-	pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_XBRIDGE;
-    } else if (is_pic(bridge)) {
-	pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_PIC;
-    } else {
-	pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_BRIDGE;
-    }
+    pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_PIC;
     switch(pcibr_soft->bs_bridge_type) {
     case PCIBR_BRIDGETYPE_BRIDGE:
 	pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES;
@@ -1367,10 +1180,6 @@
 
     nasid = NASID_GET(bridge);
 
-    /* set whether it is a PIC or not */
-    Is_pic_on_this_nasid[nasid] = (IS_PIC_SOFT(pcibr_soft)) ? 1 : 0;
-
-
     if ((pcibr_soft->bs_bricktype = iobrick_type_get_nasid(nasid)) < 0)
 	printk(KERN_WARNING "0x%p: Unknown bricktype : 0x%x\n", (void *)xconn_vhdl,
 				(unsigned int)pcibr_soft->bs_bricktype);
@@ -1380,11 +1189,27 @@
     if (pcibr_soft->bs_bricktype > 0) {
 	switch (pcibr_soft->bs_bricktype) {
 	case MODULE_PXBRICK:
+	case MODULE_IXBRICK:
 	    pcibr_soft->bs_first_slot = 0;
 	    pcibr_soft->bs_last_slot = 1;
 	    pcibr_soft->bs_last_reset = 1;
+
+	    /* If Bus 1 has IO9 then there are 4 devices in that bus.  Note
+	     * we figure this out from klconfig since the kernel has yet to 
+	     * probe
+	     */
+	    if (pcibr_widget_to_bus(pcibr_vhdl) == 1) {
+		lboard_t *brd = (lboard_t *)KL_CONFIG_INFO(nasid);
+
+		while (brd) {
+		    if (brd->brd_flags & LOCAL_MASTER_IO6) {
+			pcibr_soft->bs_last_slot = 3;
+			pcibr_soft->bs_last_reset = 3;
+		    }
+		    brd = KLCF_NEXT(brd);
+		}
+	    }
 	    break;
-	case MODULE_PEBRICK:
 	case MODULE_PBRICK:
             pcibr_soft->bs_first_slot = 1;
             pcibr_soft->bs_last_slot = 2;
@@ -1559,11 +1384,6 @@
 	int                     entry;
 	cnodeid_t		cnodeid;
 	nasid_t			nasid;
-#ifdef PIC_LATER
-	char		       *node_val;
-	devfs_handle_t		node_vhdl;
-	char			vname[MAXDEVNAME];
-#endif
 
 	/* Set the Bridge's 32-bit PCI to XTalk
 	 * Direct Map register to the most useful
@@ -1582,30 +1402,6 @@
 	 */
 
 	cnodeid = 0;  /* default node id */
-	/*
-	 * Determine the base address node id to be used for all 32-bit
-	 * Direct Mapping I/O. The default is node 0, but this can be changed
-	 * via a DEVICE_ADMIN directive and the PCIBUS_DMATRANS_NODE
-	 * attribute in the irix.sm config file. A device driver can obtain
-	 * this node value via a call to pcibr_get_dmatrans_node().
-	 */
-#ifdef PIC_LATER
-// This probably needs to be addressed - pfg
-	node_val = device_admin_info_get(pcibr_vhdl, ADMIN_LBL_DMATRANS_NODE);
-	if (node_val != NULL) {
-	    node_vhdl = hwgraph_path_to_vertex(node_val);
-	    if (node_vhdl != GRAPH_VERTEX_NONE) {
-		cnodeid = nodevertex_to_cnodeid(node_vhdl);
-	    }
-	    if ((node_vhdl == GRAPH_VERTEX_NONE) || (cnodeid == CNODEID_NONE)) {
-		cnodeid = 0;
-		vertex_to_name(pcibr_vhdl, vname, sizeof(vname));
-		printk(KERN_WARNING "Invalid hwgraph node path specified:\n"
-			"    DEVICE_ADMIN: %s %s=%s\n",
-			vname, ADMIN_LBL_DMATRANS_NODE, node_val);
-	    }
-	}
-#endif	/* PIC_LATER */
 	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
 	paddr = NODE_OFFSET(nasid) + 0;
 
@@ -1697,18 +1493,21 @@
 	/* we always have 128 ATEs (512 for Xbridge) inside the chip
 	 * even if disabled for debugging.
 	 */
-	pcibr_soft->bs_int_ate_map = rmallocmap(pcibr_soft->bs_int_ate_size);
-	pcibr_ate_free(pcibr_soft, 0, pcibr_soft->bs_int_ate_size);
+	pcibr_soft->bs_int_ate_resource.start = 0;
+	pcibr_soft->bs_int_ate_resource.end = pcibr_soft->bs_int_ate_size - 1;
 
 	if (num_entries > pcibr_soft->bs_int_ate_size) {
 #if PCIBR_ATE_NOTBOTH			/* for debug -- forces us to use external ates */
 	    printk("pcibr_attach: disabling internal ATEs.\n");
 	    pcibr_ate_alloc(pcibr_soft, pcibr_soft->bs_int_ate_size);
 #endif
-	    pcibr_soft->bs_ext_ate_map = rmallocmap(num_entries);
-	    pcibr_ate_free(pcibr_soft, pcibr_soft->bs_int_ate_size,
-			   num_entries - pcibr_soft->bs_int_ate_size);
+	   pcibr_soft->bs_ext_ate_resource.start = pcibr_soft->bs_int_ate_size;
+	   pcibr_soft->bs_ext_ate_resource.end = num_entries;
 	}
+
+        pcibr_soft->bs_allocated_ate_res = (void *) kmalloc(pcibr_soft->bs_int_ate_size * sizeof(unsigned long), GFP_KERNEL);
+	memset(pcibr_soft->bs_allocated_ate_res, 0x0, pcibr_soft->bs_int_ate_size * sizeof(unsigned long));
+
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATE, pcibr_vhdl,
 		    "pcibr_attach2: %d ATEs, %d internal & %d external\n",
 		    num_entries ? num_entries : pcibr_soft->bs_int_ate_size,
@@ -1763,6 +1562,13 @@
      */
 
     xtalk_intr = xtalk_intr_alloc(xconn_vhdl, (device_desc_t)0, pcibr_vhdl);
+	{
+		int irq = ((hub_intr_t)xtalk_intr)->i_bit;
+		int cpu = ((hub_intr_t)xtalk_intr)->i_cpuid;
+
+		intr_unreserve_level(cpu, irq);
+		((hub_intr_t)xtalk_intr)->i_bit = SGI_PCIBR_ERROR;
+	}
     ASSERT(xtalk_intr != NULL);
 
     pcibr_soft->bsi_err_intr = xtalk_intr;
@@ -1778,12 +1584,8 @@
     xtalk_intr_connect(xtalk_intr, (intr_func_t) pcibr_error_intr_handler,
 		(intr_arg_t) pcibr_soft, (xtalk_intr_setfunc_t)pcibr_setwidint, (void *)bridge);
 
-#ifdef BUS_INT_WAR_NOT_YET
-    request_irq(CPU_VECTOR_TO_IRQ(((hub_intr_t)xtalk_intr)->i_cpuid,
-			((hub_intr_t)xtalk_intr)->i_bit),
-				(intr_func_t)pcibr_error_intr_handler, 0, "PCIBR error",
+    request_irq(SGI_PCIBR_ERROR, (void *)pcibr_error_intr_handler, SA_SHIRQ, "PCIBR error",
 					(intr_arg_t) pcibr_soft);
-#endif
 
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_vhdl,
 		"pcibr_setwidint: b_wid_int_upper=0x%x, b_wid_int_lower=0x%x\n",
@@ -1801,18 +1603,16 @@
     if (IS_PIC_SOFT(pcibr_soft)) {
 	int_enable_64 = bridge->p_int_enable_64 | BRIDGE_ISR_ERRORS;
         int_enable = (uint64_t)int_enable_64;
+#ifdef PFG_TEST
+	int_enable = (uint64_t)0x7ffffeff7ffffeff;
+#endif
     } else {
 	int_enable_32 = bridge->b_int_enable | (BRIDGE_ISR_ERRORS & 0xffffffff);
 	int_enable = ((uint64_t)int_enable_32 & 0xffffffff);
-    }
-#ifdef BUS_INT_WAR_NOT_YET
-    {
-	extern void sn_add_polled_interrupt(int irq, int interval);
-
-        sn_add_polled_interrupt(CPU_VECTOR_TO_IRQ(((hub_intr_t)xtalk_intr)->i_cpuid,
-				((hub_intr_t)xtalk_intr)->i_bit), 20000);
-    }
+#ifdef PFG_TEST
+	int_enable = (uint64_t)0x7ffffeff;
 #endif
+    }
 
 
 #if BRIDGE_ERROR_INTR_WAR
@@ -1849,24 +1649,6 @@
     }
 #endif
 
-#ifdef BRIDGE_B_DATACORR_WAR
-
-    /* WAR panic for Rev B silent data corruption.
-     * PIOERR turned off here because there is a problem
-     * with not re-arming it in pcibr_error_intr_handler.
-     * We don't get LLP error interrupts if we don't
-     * re-arm PIOERR interrupts! Just disable them here
-     */
-
-    if (pcibr_soft->bs_rev_num == BRIDGE_PART_REV_B) {
-	int_enable |= BRIDGE_IMR_LLP_REC_CBERR;
-	int_enable &= ~BRIDGE_ISR_PCIBUS_PIOERR;
-
-	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,
-		    "Turning on LLP_REC_CBERR for Rev B Bridge.\n"));
-    }
-#endif
-
     /* PIC BRINGUP WAR (PV# 856864 & 856865): allow the tnums that are
      * locked out to be freed up sooner (by timing out) so that the
      * read tnums are never completely used up.
@@ -1918,16 +1700,12 @@
     if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_B)
 	pcibr_soft->bs_dma_flags |= PCIBR_NOPREFETCH;
     else if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_prefetch_enable_rev))
+		(BRIDGE_WIDGET_PART_NUM << 4))
 	pcibr_soft->bs_dma_flags |= PCIIO_NOPREFETCH;
 
-    /* WRITE_GATHER:
-     * Disabled up to but not including the
-     * rev number in pcibr_wg_enable_rev. There
-     * is no "WAR range" as with prefetch.
-     */
+    /* WRITE_GATHER: Disabled */
     if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_wg_enable_rev))
+		(BRIDGE_WIDGET_PART_NUM << 4))
 	pcibr_soft->bs_dma_flags |= PCIBR_NOWRITE_GATHER;
 
     /* PIC only supports 64-bit direct mapping in PCI-X mode.  Since
@@ -1940,10 +1718,10 @@
 
     {
 
-    pciio_win_map_t         win_map_p;
     iopaddr_t               prom_base_addr = pcibr_soft->bs_xid << 24;
     int                     prom_base_size = 0x1000000;
-    iopaddr_t               prom_base_limit = prom_base_addr + prom_base_size; 
+    int			    status;
+    struct resource	    *res;
 
     /* Allocate resource maps based on bus page size; for I/O and memory
      * space, free all pages except those in the base area and in the
@@ -1953,35 +1731,38 @@
      * the widget number and s is the device register offset for the slot.
      */
 
-    win_map_p = &pcibr_soft->bs_io_win_map;
-    pciio_device_win_map_new(win_map_p,
-			     PCIBR_BUS_IO_MAX + 1,
-			     PCIBR_BUS_IO_PAGE);
-    pciio_device_win_populate(win_map_p,
-			      PCIBR_BUS_IO_BASE,
-			      prom_base_addr - PCIBR_BUS_IO_BASE);
-    pciio_device_win_populate(win_map_p,
-			      prom_base_limit,
-			      (PCIBR_BUS_IO_MAX + 1) - prom_base_limit);
-
-    win_map_p = &pcibr_soft->bs_swin_map;
-    pciio_device_win_map_new(win_map_p,
-			     PCIBR_BUS_SWIN_MAX + 1,
-			     PCIBR_BUS_SWIN_PAGE);
-    pciio_device_win_populate(win_map_p,
-			      PCIBR_BUS_SWIN_BASE,
-			      (PCIBR_BUS_SWIN_MAX + 1) - PCIBR_BUS_SWIN_PAGE);
-
-    win_map_p = &pcibr_soft->bs_mem_win_map;
-    pciio_device_win_map_new(win_map_p,
-			     PCIBR_BUS_MEM_MAX + 1,
-			     PCIBR_BUS_MEM_PAGE);
-    pciio_device_win_populate(win_map_p,
-			      PCIBR_BUS_MEM_BASE,
-			      prom_base_addr - PCIBR_BUS_MEM_BASE);
-    pciio_device_win_populate(win_map_p,
-			      prom_base_limit,
-			      (PCIBR_BUS_MEM_MAX + 1) - prom_base_limit);
+    /* Setup the Bus's PCI IO Root Resource. */
+    pcibr_soft->bs_io_win_root_resource.start = PCIBR_BUS_IO_BASE;
+    pcibr_soft->bs_io_win_root_resource.end = 0xffffffff;
+    res = (struct resource *) kmalloc( sizeof(struct resource), KM_NOSLEEP);
+    if (!res)
+	panic("PCIBR:Unable to allocate resource structure\n");
+
+    /* Block off the range used by PROM. */
+    res->start = prom_base_addr;
+    res->end = prom_base_addr + (prom_base_size - 1);
+    status = request_resource(&pcibr_soft->bs_io_win_root_resource, res);
+    if (status)
+	panic("PCIBR:Unable to request_resource()\n");
+
+    /* Setup the Small Window Root Resource */
+    pcibr_soft->bs_swin_root_resource.start = _PAGESZ;
+    pcibr_soft->bs_swin_root_resource.end = 0x000FFFFF;
+
+    /* Setup the Bus's PCI Memory Root Resource */
+    pcibr_soft->bs_mem_win_root_resource.start = 0x200000;
+    pcibr_soft->bs_mem_win_root_resource.end = 0xffffffff;
+    res = (struct resource *) kmalloc( sizeof(struct resource), KM_NOSLEEP);
+    if (!res)
+        panic("PCIBR:Unable to allocate resource structure\n");
+
+    /* Block off the range used by PROM. */
+    res->start = prom_base_addr;
+    res->end = prom_base_addr + (prom_base_size - 1);;
+    status = request_resource(&pcibr_soft->bs_mem_win_root_resource, res);
+    if (status)
+        panic("PCIBR:Unable to request_resource()\n");
+
     }
 
     /* build "no-slot" connection point
@@ -2064,7 +1845,23 @@
      */
     if (pcibr_soft->bs_bricktype > 0) {
 	switch (pcibr_soft->bs_bricktype) {
+	case MODULE_PBRICK:
+		do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
+		do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8);
+		break;
+	case MODULE_IBRICK:
+	  	/* port 0xe on the Ibrick only has slots 1 and 2 */
+		if (pcibr_soft->bs_xid == 0xe) {
+			do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
+			do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8);
+		}
+		else {
+		    	/* allocate one RRB for the serial port */
+			do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 1);
+		}
+		break;
 	case MODULE_PXBRICK:
+	case MODULE_IXBRICK:
 		/* 
 		 * If the IO9 is in the PXBrick (bus1, slot1) allocate
                  * RRBs to all the devices
@@ -2080,23 +1877,6 @@
 			do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 8);
 			do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
 		}
-
-		break;
-	case MODULE_PEBRICK:
-	case MODULE_PBRICK:
-		do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
-		do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8);
-		break;
-	case MODULE_IBRICK:
-	  	/* port 0xe on the Ibrick only has slots 1 and 2 */
-		if (pcibr_soft->bs_xid == 0xe) {
-			do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
-			do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8);
-		}
-		else {
-		    	/* allocate one RRB for the serial port */
-			do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 1);
-		}
 		break;
 	} /* switch */
     }
@@ -2113,78 +1893,8 @@
 	/* Call the device attach */
 	(void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0);
 
-#ifdef PIC_LATER
-#if (defined(USS302_TIMEOUT_WAR))
-    /*
-     * If this bridge holds a Lucent USS-302 or USS-312 pci/usb controller,
-     * increase the Bridge PCI retry backoff interval.  This part seems
-     * to go away for long periods of time if a DAC appears on the bus during
-     * a read command that is being retried.
-     */
-
-{
-    ii_ixtt_u_t ixtt;
-
-    for (slot = pcibr_soft->bs_min_slot; 
-				slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
-	if (pcibr_soft->bs_slot[slot].bss_vendor_id ==
-					LUCENT_USBHC_VENDOR_ID_NUM &&
-	    (pcibr_soft->bs_slot[slot].bss_device_id ==
-					LUCENT_USBHC302_DEVICE_ID_NUM ||
-	     pcibr_soft->bs_slot[slot].bss_device_id ==
-					LUCENT_USBHC312_DEVICE_ID_NUM)) {
-	    printk(KERN_NOTICE
-		    "pcibr_attach: %x Bus holds a usb part - setting"
-		    "bridge PCI_RETRY_HLD to %d\n",
-		    pcibr_vhdl, USS302_BRIDGE_TIMEOUT_HLD);
-
-	    bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_HLD_MASK;
-	    bridge->b_bus_timeout |=
-			BRIDGE_BUS_PCI_RETRY_HLD(USS302_BRIDGE_TIMEOUT_HLD);
-
-	    /*
-	     * Have to consider the read response timer in the hub II as well
-	     */
-
-	    hubii_ixtt_get(xconn_vhdl, &ixtt);
-
-	    /*
-	     * bump rrsp_ps to allow at least 1ms for read
- 	     * responses from this widget
-	     */
-
-	    ixtt.ii_ixtt_fld_s.i_rrsp_ps = 20000;
-	    hubii_ixtt_set(xconn_vhdl, &ixtt);
-
-	    /*
-	     * print the current setting
-	     */
-
-	    hubii_ixtt_get(xconn_vhdl, &ixtt);
-	    printk( "Setting hub ixtt.rrsp_ps field to 0x%x\n",
-		    ixtt.ii_ixtt_fld_s.i_rrsp_ps);
-
-	    break;	/* only need to do it once */
-	}
-    }
-}
-#endif	/* (defined(USS302_TIMEOUT_WAR)) */
-#else
-	FIXME("pcibr_attach: Call do_pcibr_rrb_autoalloc nicinfo\n");
-#endif	/* PIC_LATER */
-
-    if (aa)
-	    async_attach_add_info(noslot_conn, aa);
-
     pciio_device_attach(noslot_conn, (int)0);
 
-    /* 
-     * Tear down pointer to async attach info -- async threads for
-     * bridge's descendants may be running but the bridge's work is done.
-     */
-    if (aa)
-	    async_attach_del_info(xconn_vhdl);
-
     return 0;
 }
 
@@ -2195,10 +1905,10 @@
  */
 
 int
-pcibr_detach(devfs_handle_t xconn)
+pcibr_detach(vertex_hdl_t xconn)
 {
     pciio_slot_t	slot;
-    devfs_handle_t	pcibr_vhdl;
+    vertex_hdl_t	pcibr_vhdl;
     pcibr_soft_t	pcibr_soft;
     bridge_t		*bridge;
     unsigned             s;
@@ -2235,15 +1945,6 @@
     spin_lock_destroy(&pcibr_soft->bs_lock);
     kfree(pcibr_soft->bs_name);
     
-    /* Error handler gets unregistered when the widget info is 
-     * cleaned 
-     */
-    /* Free the soft ATE maps */
-    if (pcibr_soft->bs_int_ate_map)
-	rmfreemap(pcibr_soft->bs_int_ate_map);
-    if (pcibr_soft->bs_ext_ate_map)
-	rmfreemap(pcibr_soft->bs_ext_ate_map);
-
     /* Disconnect the error interrupt and free the xtalk resources 
      * associated with it.
      */
@@ -2265,9 +1966,9 @@
 }
 
 int
-pcibr_asic_rev(devfs_handle_t pconn_vhdl)
+pcibr_asic_rev(vertex_hdl_t pconn_vhdl)
 {
-    devfs_handle_t          pcibr_vhdl;
+    vertex_hdl_t          pcibr_vhdl;
     int                     tmp_vhdl;
     arbitrary_info_t        ainfo;
 
@@ -2294,7 +1995,7 @@
 }
 
 int
-pcibr_write_gather_flush(devfs_handle_t pconn_vhdl)
+pcibr_write_gather_flush(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t  pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t  pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
@@ -2309,7 +2010,7 @@
  */
 
 static iopaddr_t
-pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl,
+pcibr_addr_pci_to_xio(vertex_hdl_t pconn_vhdl,
 		      pciio_slot_t slot,
 		      pciio_space_t space,
 		      iopaddr_t pci_addr,
@@ -2323,6 +2024,8 @@
 
     unsigned                bar;	/* which BASE reg on device is decoding */
     iopaddr_t               xio_addr = XIO_NOWHERE;
+    iopaddr_t               base;	/* base of devio(x) mapped area on PCI */
+    iopaddr_t               limit;	/* base of devio(x) mapped area on PCI */
 
     pciio_space_t           wspace;	/* which space device is decoding */
     iopaddr_t               wbase;	/* base of device decode on PCI */
@@ -2533,8 +2236,6 @@
 		PCIBR_DEBUG((PCIBR_DEBUG_DEVREG, pconn_vhdl, 
 			    "pcibr_addr_pci_to_xio: Device(%d): %x\n",
 			    win, devreg, device_bits));
-#else
-	        printk("pcibr_addr_pci_to_xio: Device(%d): %x\n", win, devreg);
 #endif
 	    }
 	    pcibr_soft->bs_slot[win].bss_devio.bssd_space = space;
@@ -2620,18 +2321,46 @@
 	 */
     case PCIIO_SPACE_MEM:		/* "mem space" */
     case PCIIO_SPACE_MEM32:		/* "mem, use 32-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM32_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM32_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM32_BASE;
+	if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 0)) {	/* PIC bus 0 */
+		base = PICBRIDGE0_PCI_MEM32_BASE;
+		limit = PICBRIDGE0_PCI_MEM32_LIMIT;
+	} else if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 1)) {	/* PIC bus 1 */
+		base = PICBRIDGE1_PCI_MEM32_BASE;
+		limit = PICBRIDGE1_PCI_MEM32_LIMIT;
+	} else {					/* Bridge/Xbridge */
+		base = BRIDGE_PCI_MEM32_BASE;
+		limit = BRIDGE_PCI_MEM32_LIMIT;
+	}
+
+	if ((pci_addr + base + req_size - 1) <= limit)
+	    xio_addr = pci_addr + base;
 	break;
 
     case PCIIO_SPACE_MEM64:		/* "mem, use 64-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM64_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM64_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM64_BASE;
+	if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 0)) {	/* PIC bus 0 */
+		base = PICBRIDGE0_PCI_MEM64_BASE;
+		limit = PICBRIDGE0_PCI_MEM64_LIMIT;
+	} else if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 1)) {	/* PIC bus 1 */
+		base = PICBRIDGE1_PCI_MEM64_BASE;
+		limit = PICBRIDGE1_PCI_MEM64_LIMIT;
+	} else {					/* Bridge/Xbridge */
+		base = BRIDGE_PCI_MEM64_BASE;
+		limit = BRIDGE_PCI_MEM64_LIMIT;
+	}
+
+	if ((pci_addr + base + req_size - 1) <= limit)
+	    xio_addr = pci_addr + base;
 	break;
 
     case PCIIO_SPACE_IO:		/* "i/o space" */
+	/*
+	 * PIC bridges do not support big-window aliases into PCI I/O space
+	 */
+	if (IS_PIC_SOFT(pcibr_soft)) {
+		xio_addr = XIO_NOWHERE;
+		break;
+	}
+
 	/* Bridge Hardware Bug WAR #482741:
 	 * The 4G area that maps directly from
 	 * XIO space to PCI I/O space is busted
@@ -2725,7 +2454,7 @@
 
 /*ARGSUSED6 */
 pcibr_piomap_t
-pcibr_piomap_alloc(devfs_handle_t pconn_vhdl,
+pcibr_piomap_alloc(vertex_hdl_t pconn_vhdl,
 		   device_desc_t dev_desc,
 		   pciio_space_t space,
 		   iopaddr_t pci_addr,
@@ -2737,7 +2466,7 @@
     pciio_info_t            pciio_info = &pcibr_info->f_c;
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
 
     pcibr_piomap_t         *mapptr;
     pcibr_piomap_t          maplist;
@@ -2867,7 +2596,7 @@
 
 /*ARGSUSED */
 caddr_t
-pcibr_piotrans_addr(devfs_handle_t pconn_vhdl,
+pcibr_piotrans_addr(vertex_hdl_t pconn_vhdl,
 		    device_desc_t dev_desc,
 		    pciio_space_t space,
 		    iopaddr_t pci_addr,
@@ -2877,7 +2606,7 @@
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
 
     iopaddr_t               xio_addr;
     caddr_t		    addr;
@@ -2908,7 +2637,7 @@
 
 /*ARGSUSED */
 iopaddr_t
-pcibr_piospace_alloc(devfs_handle_t pconn_vhdl,
+pcibr_piospace_alloc(vertex_hdl_t pconn_vhdl,
 		     device_desc_t dev_desc,
 		     pciio_space_t space,
 		     size_t req_size,
@@ -3010,7 +2739,7 @@
 
 /*ARGSUSED */
 void
-pcibr_piospace_free(devfs_handle_t pconn_vhdl,
+pcibr_piospace_free(vertex_hdl_t pconn_vhdl,
 		    pciio_space_t space,
 		    iopaddr_t pciaddr,
 		    size_t req_size)
@@ -3161,14 +2890,14 @@
 
 /*ARGSUSED */
 pcibr_dmamap_t
-pcibr_dmamap_alloc(devfs_handle_t pconn_vhdl,
+pcibr_dmamap_alloc(vertex_hdl_t pconn_vhdl,
 		   device_desc_t dev_desc,
 		   size_t req_size_max,
 		   unsigned flags)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
     pciio_slot_t            slot;
     xwidgetnum_t            xio_port;
 
@@ -3216,7 +2945,7 @@
 
 	    /* Device is capable of A64 operations,
 	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
+	     * consistent with any previous DMA
 	     * mappings using shared resources.
 	     */
 
@@ -3266,7 +2995,7 @@
 	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) {
 	    /* User desires DIRECT A32 operations,
 	     * and the attributes of the DMA are
-	     * consistant with any previous DMA
+	     * consistent with any previous DMA
 	     * mappings using shared resources.
 	     * Mapping calls may fail if target
 	     * is outside the direct32 range.
@@ -3454,6 +3183,29 @@
     iopaddr_t               pci_addr;
     pciio_slot_t            slot;
 
+    if (IS_PIC_BUSNUM_SOFT(soft, 0)) {
+    	if ((xio_addr >= PICBRIDGE0_PCI_MEM32_BASE) &&
+	    (xio_lim <= PICBRIDGE0_PCI_MEM32_LIMIT)) {
+	    pci_addr = xio_addr - PICBRIDGE0_PCI_MEM32_BASE;
+	    return pci_addr;
+    	}
+    	if ((xio_addr >= PICBRIDGE0_PCI_MEM64_BASE) &&
+	    (xio_lim <= PICBRIDGE0_PCI_MEM64_LIMIT)) {
+	    pci_addr = xio_addr - PICBRIDGE0_PCI_MEM64_BASE;
+	    return pci_addr;
+    	}
+    } else if (IS_PIC_BUSNUM_SOFT(soft, 1)) {
+    	if ((xio_addr >= PICBRIDGE1_PCI_MEM32_BASE) &&
+	    (xio_lim <= PICBRIDGE1_PCI_MEM32_LIMIT)) {
+	    pci_addr = xio_addr - PICBRIDGE1_PCI_MEM32_BASE;
+	    return pci_addr;
+    	}
+    	if ((xio_addr >= PICBRIDGE1_PCI_MEM64_BASE) &&
+	    (xio_lim <= PICBRIDGE1_PCI_MEM64_LIMIT)) {
+	    pci_addr = xio_addr - PICBRIDGE1_PCI_MEM64_BASE;
+	    return pci_addr;
+    	}
+    } else {
     if ((xio_addr >= BRIDGE_PCI_MEM32_BASE) &&
 	(xio_lim <= BRIDGE_PCI_MEM32_LIMIT)) {
 	pci_addr = xio_addr - BRIDGE_PCI_MEM32_BASE;
@@ -3464,6 +3216,7 @@
 	pci_addr = xio_addr - BRIDGE_PCI_MEM64_BASE;
 	return pci_addr;
     }
+    }
     for (slot = soft->bs_min_slot; slot < PCIBR_NUM_SLOTS(soft); ++slot)
 	if ((xio_addr >= PCIBR_BRIDGE_DEVIO(soft, slot)) &&
 	    (xio_lim < PCIBR_BRIDGE_DEVIO(soft, slot + 1))) {
@@ -3505,7 +3258,7 @@
     } else
 	xio_port = pcibr_dmamap->bd_xio_port;
 
-    /* If this DMA is to an addres that
+    /* If this DMA is to an address that
      * refers back to this Bridge chip,
      * reduce it back to the correct
      * PCI MEM address.
@@ -3644,243 +3397,6 @@
 }
 
 /*ARGSUSED */
-alenlist_t
-pcibr_dmamap_list(pcibr_dmamap_t pcibr_dmamap,
-		  alenlist_t palenlist,
-		  unsigned flags)
-{
-    pcibr_soft_t            pcibr_soft;
-    bridge_t               *bridge=NULL;
-
-    unsigned                al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-    int                     inplace = flags & PCIIO_INPLACE;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist;
-    size_t                  length;
-    iopaddr_t               offset;
-    unsigned                direct64;
-    int                     ate_index = 0;
-    int                     ate_count = 0;
-    int                     ate_total = 0;
-    bridge_ate_p            ate_ptr = (bridge_ate_p)0;
-    bridge_ate_t            ate_proto = (bridge_ate_t)0;
-    bridge_ate_t            ate_prev;
-    bridge_ate_t            ate;
-    alenaddr_t              xio_addr;
-    xwidgetnum_t            xio_port;
-    iopaddr_t               pci_addr;
-    alenaddr_t              new_addr;
-    unsigned                cmd_regs[8];
-    unsigned                s = 0;
-
-#if PCIBR_FREEZE_TIME
-    unsigned                freeze_time;
-#endif
-    int			    ate_freeze_done = 0;	/* To pair ATE_THAW
-							 * with an ATE_FREEZE
-							 */
-
-    pcibr_soft = pcibr_dmamap->bd_soft;
-
-    xtalk_alenlist = xtalk_dmamap_list(pcibr_dmamap->bd_xtalk, palenlist,
-				       flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist) {
-        PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-                    "pcibr_dmamap_list: xtalk_dmamap_list() failed, "
-		    "pcibr_dmamap=0x%x\n", pcibr_dmamap));
-	goto fail;
-    }
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist) {
-	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-			"pcibr_dmamap_list: alenlist_create() failed, "
-			"pcibr_dmamap=0x%lx\n", (unsigned long)pcibr_dmamap));
-	    goto fail;
-	}
-    }
-
-    direct64 = pcibr_dmamap->bd_flags & PCIIO_DMA_A64;
-    if (!direct64) {
-	bridge = pcibr_soft->bs_base;
-	ate_ptr = pcibr_dmamap->bd_ate_ptr;
-	ate_index = pcibr_dmamap->bd_ate_index;
-	ate_proto = pcibr_dmamap->bd_ate_proto;
-	ATE_FREEZE();
-	ate_freeze_done = 1;	/* Remember that we need to do an ATE_THAW */
-    }
-    pci_addr = pcibr_dmamap->bd_pci_addr;
-
-    ate_prev = 0;			/* matches no valid ATEs */
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &length, al_flags)) {
-	if (XIO_PACKED(xio_addr)) {
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_dmamap->bd_xio_port;
-
-	if (xio_port == pcibr_soft->bs_xid) {
-	    new_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, length);
-	    if (new_addr == PCI_NOWHERE) {
-                PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-                            "pcibr_dmamap_list: pcibr_addr_xio_to_pci failed, "
-                            "pcibr_dmamap=0x%x\n", pcibr_dmamap));
-		goto fail;
-	    }
-	} else if (direct64) {
-	    new_addr = pci_addr | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-	    /* Bridge Hardware WAR #482836:
-	     * If the transfer is not cache aligned
-	     * and the Bridge Rev is <= B, force
-	     * prefetch to be off.
-	     */
-	    if (flags & PCIBR_NOPREFETCH)
-		new_addr &= ~PCI64_ATTR_PREF;
-
-	} else {
-	    /* calculate the ate value for
-	     * the first address. If it
-	     * matches the previous
-	     * ATE written (ie. we had
-	     * multiple blocks in the
-	     * same IOPG), then back up
-	     * and reuse that ATE.
-	     *
-	     * We are NOT going to
-	     * aggressively try to
-	     * reuse any other ATEs.
-	     */
-	    offset = IOPGOFF(xio_addr);
-	    ate = ate_proto
-		| (xio_port << ATE_TIDSHIFT)
-		| (xio_addr - offset);
-	    if (ate == ate_prev) {
-		PCIBR_DEBUG((PCIBR_DEBUG_ATE, pcibr_dmamap->bd_dev,
-			    "pcibr_dmamap_list: ATE share\n"));
-		ate_ptr--;
-		ate_index--;
-		pci_addr -= IOPGSIZE;
-	    }
-	    new_addr = pci_addr + offset;
-
-	    /* Fill in the hardware ATEs
-	     * that contain this block.
-	     */
-	    ate_count = IOPG(offset + length - 1) + 1;
-	    ate_total += ate_count;
-
-	    /* Ensure that this map contains enough ATE's */
-	    if (ate_total > pcibr_dmamap->bd_ate_count) {
-		PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATE, pcibr_dmamap->bd_dev,
-			     "pcibr_dmamap_list :\n"
-			     "\twanted xio_addr [0x%x..0x%x]\n"
-			     "\tate_total 0x%x bd_ate_count 0x%x\n"
-			     "\tATE's required > number allocated\n",
-			     xio_addr, xio_addr + length - 1,
-			     ate_total, pcibr_dmamap->bd_ate_count));
-		goto fail;
-	    }
-
-	    ATE_WRITE();
-
-	    ate_index += ate_count;
-	    ate_ptr += ate_count;
-
-	    ate_count <<= IOPFNSHIFT;
-	    ate += ate_count;
-	    pci_addr += ate_count;
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &new_addr, &length, al_flags)) {
-                PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-                            "pcibr_dmamap_list: alenlist_replace() failed, "
-                            "pcibr_dmamap=0x%x\n", pcibr_dmamap));
-
-		goto fail;
-	    }
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				new_addr, length, al_flags)) {
-                PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-                            "pcibr_dmamap_list: alenlist_append() failed, "
-                            "pcibr_dmamap=0x%x\n", pcibr_dmamap));
-		goto fail;
-	    }
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-
-
-    /* In case an ATE_FREEZE was done do the ATE_THAW to unroll all the
-     * changes that ATE_FREEZE has done to implement the external SSRAM
-     * bug workaround.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	if ( IS_PIC_SOFT(pcibr_soft) ) {
-		bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			BRIDGE_REG_GET32((&bridge->b_wid_tflush));
-		} else {
-			bridge->b_wid_tflush;
-		}
-	}
-    }
-    PCIBR_DEBUG((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-		"pcibr_dmamap_list: pcibr_dmamap=0x%x, pciio_alenlist=0x%x\n",
-		pcibr_dmamap, pciio_alenlist));
-
-    return pciio_alenlist;
-
-  fail:
-    /* There are various points of failure after doing an ATE_FREEZE
-     * We need to do an ATE_THAW. Otherwise the ATEs are locked forever.
-     * The decision to do an ATE_THAW needs to be based on whether a
-     * an ATE_FREEZE was done before.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	if ( IS_PIC_SOFT(pcibr_soft) ) {
-		bridge->b_wid_tflush;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			BRIDGE_REG_GET32((&bridge->b_wid_tflush));
-		} else {
-			bridge->b_wid_tflush;
-		}
-	}
-    }
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
-/*ARGSUSED */
 void
 pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap)
 {
@@ -3917,7 +3433,7 @@
 
 /*ARGSUSED */
 cnodeid_t
-pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl)
+pcibr_get_dmatrans_node(vertex_hdl_t pconn_vhdl)
 {
 
 	pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
@@ -3928,7 +3444,7 @@
 
 /*ARGSUSED */
 iopaddr_t
-pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl,
+pcibr_dmatrans_addr(vertex_hdl_t pconn_vhdl,
 		    device_desc_t dev_desc,
 		    paddr_t paddr,
 		    size_t req_size,
@@ -3936,7 +3452,7 @@
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
     pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
 
@@ -4149,213 +3665,6 @@
     return 0;
 }
 
-/*ARGSUSED */
-alenlist_t
-pcibr_dmatrans_list(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    alenlist_t palenlist,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
-    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
-    xwidgetnum_t            xio_port;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist = 0;
-
-    int                     inplace;
-    unsigned                direct64;
-    unsigned                al_flags;
-
-    iopaddr_t               xio_base;
-    alenaddr_t              xio_addr;
-    size_t                  xio_size;
-
-    size_t                  map_size;
-    iopaddr_t               pci_base;
-    alenaddr_t              pci_addr;
-
-    unsigned                relbits = 0;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-    inplace = flags & PCIIO_INPLACE;
-    direct64 = flags & PCIIO_DMA_A64;
-    al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-
-    if (direct64) {
-	map_size = 1ull << 48;
-	xio_base = 0;
-	pci_base = slotp->bss_d64_base;
-	if ((pci_base != PCIBR_D64_BASE_UNSET) &&
-	    (flags == slotp->bss_d64_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: DMA configuration conflict "
-			"for direct64, flags=0x%x\n", flags));
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D64_BITS;
-	    pci_base =
-		pcibr_flags_to_d64(flags, pcibr_soft);
-	}
-    } else {
-	xio_base = pcibr_soft->bs_dir_xbase;
-	map_size = 1ull << 31;
-	pci_base = slotp->bss_d32_base;
-	if ((pci_base != PCIBR_D32_BASE_UNSET) &&
-	    (flags == slotp->bss_d32_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: DMA configuration conflict "
-			"for direct32, flags=0x%x\n", flags));
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D32_BITS;
-	    pci_base = PCI32_DIRECT_BASE;
-	}
-    }
-
-    xtalk_alenlist = xtalk_dmatrans_list(xconn_vhdl, 0, palenlist,
-					 flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist) {
-	    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: xtalk_dmatrans_list failed "
-			"xtalk_alenlist=0x%x\n", xtalk_alenlist));
-	goto fail;
-    }
-
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist) {
-	    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: alenlist_create failed with "
-			" 0x%x\n", pciio_alenlist));
-	    goto fail;
-	}
-    }
-
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &xio_size, al_flags)) {
-
-	/*
-	 * find which XIO port this goes to.
-	 */
-	if (XIO_PACKED(xio_addr)) {
-	    if (xio_addr == XIO_NOWHERE) {
-	        PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: xio_addr == XIO_NOWHERE\n"));
-		return 0;
-	    }
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_soft->bs_mxid;
-
-	/*
-	 * If this DMA comes back to us,
-	 * return the PCI MEM address on
-	 * which it would land, or NULL
-	 * if the target is something
-	 * on bridge other than PCI MEM.
-	 */
-	if (xio_port == pcibr_soft->bs_xid) {
-	    pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size);
-	    if (pci_addr == (alenaddr_t)NULL) {
-	        PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: pcibr_addr_xio_to_pci failed "
-			"xio_addr=0x%x, xio_size=0x%x\n", xio_addr, xio_size));
-		goto fail;
-	    }
-	} else if (direct64) {
-	    ASSERT(xio_port != 0);
-	    pci_addr = pci_base | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-	} else {
-	    iopaddr_t               offset = xio_addr - xio_base;
-	    iopaddr_t               endoff = xio_size + offset;
-
-	    if ((xio_size > map_size) ||
-		(xio_addr < xio_base) ||
-		(xio_port != pcibr_soft->bs_dir_xport) ||
-		(endoff > map_size)) {
-		PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			    "pcibr_dmatrans_list: xio_size > map_size fail\n"
-			    "xio_addr=0x%x, xio_size=0x%x. map_size=0x%x, "
-			    "xio_port=0x%x, endoff=0x%x\n", 
-			    xio_addr, xio_size, map_size, xio_port, endoff));
-		goto fail;
-	    }
-
-	    pci_addr = pci_base + (xio_addr - xio_base);
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &pci_addr, &xio_size, al_flags)) {
-		PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			    "pcibr_dmatrans_list: alenlist_replace failed\n"));
-		goto fail;
-	    }
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				pci_addr, xio_size, al_flags)) {
-		PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			    "pcibr_dmatrans_list: alenlist_append failed\n"));
-		goto fail;
-	    }
-	}
-    }
-
-    if (relbits) {
-	if (direct64) {
-	    slotp->bss_d64_flags = flags;
-	    slotp->bss_d64_base = pci_base;
-	} else {
-	    slotp->bss_d32_flags = flags;
-	    slotp->bss_d32_base = pci_base;
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-
-    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-		"pcibr_dmatrans_list: pciio_alenlist=0x%x\n",
-		 pciio_alenlist));
-
-    return pciio_alenlist;
-
-  fail:
-    if (relbits)
-	pcibr_release_device(pcibr_soft, pciio_slot, relbits);
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
 void
 pcibr_dmamap_drain(pcibr_dmamap_t map)
 {
@@ -4363,24 +3672,24 @@
 }
 
 void
-pcibr_dmaaddr_drain(devfs_handle_t pconn_vhdl,
+pcibr_dmaaddr_drain(vertex_hdl_t pconn_vhdl,
 		    paddr_t paddr,
 		    size_t bytes)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
 
     xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes);
 }
 
 void
-pcibr_dmalist_drain(devfs_handle_t pconn_vhdl,
+pcibr_dmalist_drain(vertex_hdl_t pconn_vhdl,
 		    alenlist_t list)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
 
     xtalk_dmalist_drain(xconn_vhdl, list);
 }
@@ -4402,18 +3711,18 @@
  */
 /*ARGSUSED */
 void
-pcibr_provider_startup(devfs_handle_t pcibr)
+pcibr_provider_startup(vertex_hdl_t pcibr)
 {
 }
 
 /*ARGSUSED */
 void
-pcibr_provider_shutdown(devfs_handle_t pcibr)
+pcibr_provider_shutdown(vertex_hdl_t pcibr)
 {
 }
 
 int
-pcibr_reset(devfs_handle_t conn)
+pcibr_reset(vertex_hdl_t conn)
 {
 #ifdef PIC_LATER
     pciio_info_t            pciio_info = pciio_info_get(conn);
@@ -4484,7 +3793,7 @@
 }
 
 pciio_endian_t
-pcibr_endian_set(devfs_handle_t pconn_vhdl,
+pcibr_endian_set(vertex_hdl_t pconn_vhdl,
 		 pciio_endian_t device_end,
 		 pciio_endian_t desired_end)
 {
@@ -4629,7 +3938,7 @@
 }
 
 pciio_priority_t
-pcibr_priority_set(devfs_handle_t pconn_vhdl,
+pcibr_priority_set(vertex_hdl_t pconn_vhdl,
 		   pciio_priority_t device_prio)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
@@ -4653,7 +3962,7 @@
  * Returns 0 on failure, 1 on success
  */
 int
-pcibr_device_flags_set(devfs_handle_t pconn_vhdl,
+pcibr_device_flags_set(vertex_hdl_t pconn_vhdl,
 		       pcibr_device_flags_t flags)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
@@ -4792,10 +4101,8 @@
     (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,
     (pciio_dmamap_free_f *) pcibr_dmamap_free,
     (pciio_dmamap_addr_f *) pcibr_dmamap_addr,
-    (pciio_dmamap_list_f *) pcibr_dmamap_list,
     (pciio_dmamap_done_f *) pcibr_dmamap_done,
     (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
-    (pciio_dmatrans_list_f *) pcibr_dmatrans_list,
     (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
     (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
     (pciio_dmalist_drain_f *) pcibr_dmalist_drain,
@@ -4814,23 +4121,16 @@
     (pciio_priority_set_f *) pcibr_priority_set,
     (pciio_config_get_f *) pcibr_config_get,
     (pciio_config_set_f *) pcibr_config_set,
-#ifdef PIC_LATER
-    (pciio_error_devenable_f *) pcibr_error_devenable,
-    (pciio_error_extract_f *) pcibr_error_extract,
-    (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback,
-    (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback,
-#else
     (pciio_error_devenable_f *) 0,
     (pciio_error_extract_f *) 0,
     (pciio_driver_reg_callback_f *) 0,
     (pciio_driver_unreg_callback_f *) 0,
-#endif	/* PIC_LATER */
     (pciio_device_unregister_f 	*) pcibr_device_unregister,
     (pciio_dma_enabled_f		*) pcibr_dma_enabled,
 };
 
 int
-pcibr_dma_enabled(devfs_handle_t pconn_vhdl)
+pcibr_dma_enabled(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
@@ -4857,7 +4157,7 @@
  * parameter 'format' is sent to the console.
  */
 void
-pcibr_debug(uint32_t type, devfs_handle_t vhdl, char *format, ...)
+pcibr_debug(uint32_t type, vertex_hdl_t vhdl, char *format, ...)
 {
     char hwpath[MAXDEVNAME] = "\0";
     char copy_of_hwpath[MAXDEVNAME];
@@ -4865,7 +4165,6 @@
     short widget = -1;
     short slot = -1;
     va_list ap;
-    char *strtok_r(char *string, const char *sepset, char **lasts);
 
     if (pcibr_debug_mask & type) {
         if (vhdl) {
@@ -4873,27 +4172,26 @@
                 char *cp;
 
                 if (strcmp(module, pcibr_debug_module)) {
-		    /* strtok_r() wipes out string, use a copy */
+		    /* use a copy */
                     (void)strcpy(copy_of_hwpath, hwpath);
                     cp = strstr(copy_of_hwpath, "/module/");
                     if (cp) {
-                        char *last = NULL;
                         cp += strlen("/module");
-                        module = strtok_r(cp, "/", &last);
+                        module = strsep(&cp, "/");
                     }
                 }
                 if (pcibr_debug_widget != -1) {
                     cp = strstr(hwpath, "/xtalk/");
                     if (cp) {
                         cp += strlen("/xtalk/");
-                        widget = atoi(cp);
+                        widget = simple_strtoul(cp, NULL, 0);
                     }
                 }
                 if (pcibr_debug_slot != -1) {
                     cp = strstr(hwpath, "/pci/");
                     if (cp) {
                         cp += strlen("/pci/");
-                        slot = atoi(cp);
+                        slot = simple_strtoul(cp, NULL, 0);
                     }
                 }
             }
@@ -4912,9 +4210,38 @@
 	     * Since we have a variable length argument list, we
 	     * need to call printk this way rather than directly
 	     */
-	    va_start(ap, format);
-	    printk(format, ap);
-	    va_end(ap);
+	    {
+		char buffer[500];
+
+		va_start(ap, format);
+		vsnprintf(buffer, 500, format, ap);
+		va_end(ap);
+		buffer[499] = (char)0;	/* just to be safe */
+		printk("%s", buffer);
+	    }
         }
     }
 }
+
+int
+isIO9(nasid_t nasid) {
+	lboard_t *brd = (lboard_t *)KL_CONFIG_INFO(nasid);
+
+	while (brd) {
+		if (brd->brd_flags & LOCAL_MASTER_IO6) {
+			return 1;
+		}
+		brd = KLCF_NEXT(brd);
+	}
+	/* if it's dual ported, check the peer also */
+	nasid = NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer;
+	if (nasid < 0) return 0;
+	brd = (lboard_t *)KL_CONFIG_INFO(nasid);
+	while (brd) {
+		if (brd->brd_flags & LOCAL_MASTER_IO6) {
+			return 1;
+		}
+		brd = KLCF_NEXT(brd);
+	}
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c	2003-08-01 13:32:28.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,26 +27,11 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
 extern int	hubii_check_widget_disabled(nasid_t, int);
-#ifdef BRIDGE_B_DATACORR_WAR
-extern int              ql_bridge_rev_b_war(devfs_handle_t);
-extern int              bridge_rev_b_data_check_disable;
-char                   *rev_b_datacorr_warning =
-"***************************** WARNING! ******************************\n";
-char                   *rev_b_datacorr_mesg =
-"UNRECOVERABLE IO LINK ERROR. CONTACT SERVICE PROVIDER\n";
-#endif
+
 
 /* =====================================================================
  *    ERROR HANDLING
@@ -76,13 +61,9 @@
                                    BRIDGE_ISR_PCIBUS_PIOERR;
 #endif
 
-#if defined (PCIBR_LLP_CONTROL_WAR)
-int                     pcibr_llp_control_war_cnt;
-#endif				/* PCIBR_LLP_CONTROL_WAR */
+int                     pcibr_llp_control_war_cnt; /* PCIBR_LLP_CONTROL_WAR */
 
-/* FIXME: can these arrays be local ? */
-
-struct reg_values xio_cmd_pactyp[] =
+static struct reg_values xio_cmd_pactyp[] =
 {
     {0x0, "RdReq"},
     {0x1, "RdResp"},
@@ -103,7 +84,7 @@
     {0}
 };
 
-struct reg_desc   xio_cmd_bits[] =
+static struct reg_desc   xio_cmd_bits[] =
 {
     {WIDGET_DIDN, -28, "DIDN", "%x"},
     {WIDGET_SIDN, -24, "SIDN", "%x"},
@@ -120,58 +101,7 @@
 
 #define F(s,n)          { 1l<<(s),-(s), n }
 
-struct reg_desc         bridge_int_status_desc[] =
-{
-    F(45, "PCI_X_SPLIT_MES_PE"),/* PIC ONLY */
-    F(44, "PCI_X_SPLIT_EMES"),	/* PIC ONLY */
-    F(43, "PCI_X_SPLIT_TO"),	/* PIC ONLY */
-    F(42, "PCI_X_UNEX_COMP"),	/* PIC ONLY */
-    F(41, "INT_RAM_PERR"),	/* PIC ONLY */
-    F(40, "PCI_X_ARB_ERR"),	/* PIC ONLY */
-    F(39, "PCI_X_REQ_TOUT"),	/* PIC ONLY */
-    F(38, "PCI_X_TABORT"),	/* PIC ONLY */
-    F(37, "PCI_X_PERR"),	/* PIC ONLY */
-    F(36, "PCI_X_SERR"),	/* PIC ONLY */
-    F(35, "PCI_X_MRETRY"),	/* PIC ONLY */
-    F(34, "PCI_X_MTOUT"),	/* PIC ONLY */
-    F(33, "PCI_X_DA_PARITY"),	/* PIC ONLY */
-    F(32, "PCI_X_AD_PARITY"),	/* PIC ONLY */
-    F(31, "MULTI_ERR"),		/* BRIDGE ONLY */
-    F(30, "PMU_ESIZE_EFAULT"),
-    F(29, "UNEXPECTED_RESP"),
-    F(28, "BAD_XRESP_PACKET"),
-    F(27, "BAD_XREQ_PACKET"),
-    F(26, "RESP_XTALK_ERROR"),
-    F(25, "REQ_XTALK_ERROR"),
-    F(24, "INVALID_ADDRESS"),
-    F(23, "UNSUPPORTED_XOP"),
-    F(22, "XREQ_FIFO_OFLOW"),
-    F(21, "LLP_REC_SNERROR"),
-    F(20, "LLP_REC_CBERROR"),
-    F(19, "LLP_RCTY"),
-    F(18, "LLP_TX_RETRY"),
-    F(17, "LLP_TCTY"),
-    F(16, "SSRAM_PERR"),	/* BRIDGE ONLY */
-    F(15, "PCI_ABORT"),
-    F(14, "PCI_PARITY"),
-    F(13, "PCI_SERR"),
-    F(12, "PCI_PERR"),
-    F(11, "PCI_MASTER_TOUT"),
-    F(10, "PCI_RETRY_CNT"),
-    F(9, "XREAD_REQ_TOUT"),
-    F(8, "GIO_BENABLE_ERR"),	/* BRIDGE ONLY */
-    F(7, "INT7"),
-    F(6, "INT6"),
-    F(5, "INT5"),
-    F(4, "INT4"),
-    F(3, "INT3"),
-    F(2, "INT2"),
-    F(1, "INT1"),
-    F(0, "INT0"),
-    {0}
-};
-
-struct reg_values       space_v[] =
+static struct reg_values       space_v[] =
 {
     {PCIIO_SPACE_NONE, "none"},
     {PCIIO_SPACE_ROM, "ROM"},
@@ -189,13 +119,13 @@
     {PCIIO_SPACE_BAD, "BAD"},
     {0}
 };
-struct reg_desc         space_desc[] =
+static struct reg_desc         space_desc[] =
 {
     {0xFF, 0, "space", 0, space_v},
     {0}
 };
 #define	device_desc	device_bits
-struct reg_desc   device_bits[] =
+static struct reg_desc   device_bits[] =
 {
     {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"},
     {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"},
@@ -218,14 +148,14 @@
     {0}
 };
 
-void
+static void
 print_bridge_errcmd(uint32_t cmdword, char *errtype)
 {
     printk("\t    Bridge %s Error Command Word Register ", errtype);
     print_register(cmdword, xio_cmd_bits);
 }
 
-char             *pcibr_isr_errs[] =
+static char             *pcibr_isr_errs[] =
 {
     "", "", "", "", "", "", "", "",
     "08: GIO non-contiguous byte enable in crosstalk packet", /* BRIDGE ONLY */
@@ -279,7 +209,7 @@
 /*
  * display memory directory state
  */
-void
+static void
 pcibr_show_dir_state(paddr_t paddr, char *prefix)
 {
 #ifdef LATER
@@ -428,7 +358,6 @@
 		break;
 
 	    case BRIDGE_ISR_PAGE_FAULT:	    /* bit30	PMU_PAGE_FAULT */
-/*	    case BRIDGE_ISR_PMU_ESIZE_FAULT:   bit30	PMU_ESIZE_FAULT */
 		if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft))
 		    reg_desc = "Map Fault Address";
 		else
@@ -592,31 +521,9 @@
 		printk( "\t%s\n", pcibr_isr_errs[i]);
 	}
     }
-
-#if BRIDGE_ERROR_INTR_WAR
-    if (pcibr_soft->bs_rev_num == BRIDGE_PART_REV_A) {	/* known bridge bug */
-	/*
-	 * Should never receive interrupts for these reasons on Rev 1 bridge
-	 * as they are not enabled. Assert for it.
-	 */
-	ASSERT((int_status & (BRIDGE_IMR_PCI_MST_TIMEOUT |
-			      BRIDGE_ISR_RESP_XTLK_ERR |
-			      BRIDGE_ISR_LLP_TX_RETRY)) == 0);
-    }
-    if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_C) {	/* known bridge bug */
-	/*
-	 * This interrupt is turned off at init time. So, should never
-	 * see this interrupt.
-	 */
-	ASSERT((int_status & BRIDGE_ISR_BAD_XRESP_PKT) == 0);
-    }
-#endif
 }
 
-#define PCIBR_ERRINTR_GROUP(error)	\
-		(( error & (BRIDGE_IRR_PCI_GRP|BRIDGE_IRR_GIO_GRP)
-
-uint32_t
+static uint32_t
 pcibr_errintr_group(uint32_t error)
 {
     uint32_t              group = BRIDGE_IRR_MULTI_CLR;
@@ -741,15 +648,7 @@
     picreg_t                int_status_64;
     int			    number_bits;
     int                     i;
-
-    /* REFERENCED */
     uint64_t		    disable_errintr_mask = 0;
-#ifdef EHE_ENABLE
-    int 		    rv;
-    int 		    error_code = IOECODE_DMA | IOECODE_READ;
-    ioerror_mode_t 	    mode = MODE_DEVERROR;
-    ioerror_t 	            ioe;
-#endif /* EHE_ENABLE */
     nasid_t		    nasid;
 
 
@@ -806,10 +705,6 @@
 	pcibr_soft->bs_errinfo.bserr_toutcnt++;
 	/* Let's go recursive */
 	return(pcibr_error_intr_handler(irq, arg, ep));
-#ifdef LATER
-	timeout(pcibr_error_intr_handler, pcibr_soft, BRIDGE_PIOERR_TIMEOUT);
-#endif
-	return;
     }
 
     /* We read the INT_STATUS register as a 64bit picreg_t for PIC and a
@@ -847,24 +742,6 @@
 	pcibr_pioerr_check(pcibr_soft);
     }
 
-#ifdef BRIDGE_B_DATACORR_WAR
-    if ((pcibr_soft->bs_rev_num == BRIDGE_PART_REV_B) &&
-	(err_status & BRIDGE_IMR_LLP_REC_CBERR)) {
-	if (bridge_rev_b_data_check_disable)
-	    printk(KERN_WARNING "\n%s%s: %s%s\n", rev_b_datacorr_warning,
-		    pcibr_soft->bs_name, rev_b_datacorr_mesg,
-		    rev_b_datacorr_warning);
-	else {
-	    ql_bridge_rev_b_war(pcibr_soft->bs_vhdl);
-	    PRINT_PANIC( "\n%s%s: %s%s\n", rev_b_datacorr_warning,
-		    pcibr_soft->bs_name, rev_b_datacorr_mesg,
-		    rev_b_datacorr_warning);
-	}
-
-	err_status &= ~BRIDGE_IMR_LLP_REC_CBERR;
-    }
-#endif				/* BRIDGE_B_DATACORR_WAR */
-
     if (err_status) {
 	struct bs_errintr_stat_s *bs_estat = pcibr_soft->bs_errintr_stat;
 
@@ -1024,9 +901,8 @@
 	(0x00402000 == (0x00F07F00 & bridge->b_wid_err_cmdword))) {
 	err_status &= ~BRIDGE_ISR_INVLD_ADDR;
     }
-#if defined (PCIBR_LLP_CONTROL_WAR)
     /*
-     * The bridge bug, where the llp_config or control registers
+     * The bridge bug (PCIBR_LLP_CONTROL_WAR), where the llp_config or control registers
      * need to be read back after being written, affects an MP
      * system since there could be small windows between writing
      * the register and reading it back on one cpu while another
@@ -1039,40 +915,9 @@
     if ((err_status & BRIDGE_ISR_INVLD_ADDR) &&
 	((((uint64_t) bridge->b_wid_err_upper << 32) | (bridge->b_wid_err_lower))
 	 == (BRIDGE_INT_RST_STAT & 0xff0))) {
-#if 0
-	if (kdebug)
-	    printk(KERN_NOTICE "%s bridge: ignoring llp/control address interrupt",
-		    pcibr_soft->bs_name);
-#endif
 	pcibr_llp_control_war_cnt++;
 	err_status &= ~BRIDGE_ISR_INVLD_ADDR;
     }
-#endif				/* PCIBR_LLP_CONTROL_WAR */
-
-#ifdef EHE_ENABLE
-    /* Check if this is the RESP_XTALK_ERROR interrupt. 
-     * This can happen due to a failed DMA READ operation.
-     */
-    if (err_status & BRIDGE_ISR_RESP_XTLK_ERR) {
-	/* Phase 1 : Look at the error state in the bridge and further
-	 * down in the device layers.
-	 */
-	(void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_LOOKUP);
-	IOERROR_SETVALUE(&ioe, widgetnum, pcibr_soft->bs_xid);
-	(void)pcibr_error_handler((error_handler_arg_t)pcibr_soft,
-				  error_code,
-				  mode,
-				  &ioe);
-	/* Phase 2 : Perform the action agreed upon in phase 1.
-	 */
-	(void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_ACTION);
-	rv = pcibr_error_handler((error_handler_arg_t)pcibr_soft,
-				 error_code,
-				 mode,
-				 &ioe);
-    }
-    if (rv != IOERROR_HANDLED) {
-#endif /* EHE_ENABLE */
 
     bridge_errors_to_dump |= BRIDGE_ISR_PCIBUS_PIOERR;
 
@@ -1089,25 +934,16 @@
      */
     if (IS_PIC_SOFT(pcibr_soft) && PCIBR_WAR_ENABLED(PV867308, pcibr_soft) &&
         (err_status & (BRIDGE_ISR_LLP_REC_SNERR | BRIDGE_ISR_LLP_REC_CBERR))) {
-        printk("BRIDGE ERR_STATUS 0x%x\n", err_status);
+        printk("BRIDGE ERR_STATUS 0x%lx\n", err_status);
         pcibr_error_dump(pcibr_soft);
-#ifdef LATER
-        machine_error_dump("");
-#endif
         PRINT_PANIC("PCI Bridge Error interrupt killed the system");
     }
 
     if (err_status & BRIDGE_ISR_ERROR_FATAL) {
-#ifdef LATER
-	machine_error_dump("");
-#endif
 	PRINT_PANIC("PCI Bridge Error interrupt killed the system");
 	    /*NOTREACHED */
     }
 
-#ifdef EHE_ENABLE
-    }
-#endif
 
     /*
      * We can't return without re-enabling the interrupt, since
@@ -1137,136 +973,6 @@
     pcibr_soft->bs_errinfo.bserr_intstat = 0;
 }
 
-/*
- * pcibr_addr_toslot
- *      Given the 'pciaddr' find out which slot this address is
- *      allocated to, and return the slot number.
- *      While we have the info handy, construct the
- *      function number, space code and offset as well.
- *
- * NOTE: if this routine is called, we don't know whether
- * the address is in CFG, MEM, or I/O space. We have to guess.
- * This will be the case on PIO stores, where the only way
- * we have of getting the address is to check the Bridge, which
- * stores the PCI address but not the space and not the xtalk
- * address (from which we could get it).
- */
-int
-pcibr_addr_toslot(pcibr_soft_t pcibr_soft,
-		  iopaddr_t pciaddr,
-		  pciio_space_t *spacep,
-		  iopaddr_t *offsetp,
-		  pciio_function_t *funcp)
-{
-    int                     s, f = 0, w;
-    iopaddr_t               base;
-    size_t                  size;
-    pciio_piospace_t        piosp;
-
-    /*
-     * Check if the address is in config space
-     */
-
-    if ((pciaddr >= BRIDGE_CONFIG_BASE) && (pciaddr < BRIDGE_CONFIG_END)) {
-
-	if (pciaddr >= BRIDGE_CONFIG1_BASE)
-	    pciaddr -= BRIDGE_CONFIG1_BASE;
-	else
-	    pciaddr -= BRIDGE_CONFIG_BASE;
-
-	s = pciaddr / BRIDGE_CONFIG_SLOT_SIZE;
-	pciaddr %= BRIDGE_CONFIG_SLOT_SIZE;
-
-	if (funcp) {
-	    f = pciaddr / 0x100;
-	    pciaddr %= 0x100;
-	}
-	if (spacep)
-	    *spacep = PCIIO_SPACE_CFG;
-	if (offsetp)
-	    *offsetp = pciaddr;
-	if (funcp)
-	    *funcp = f;
-
-	return s;
-    }
-    for (s = pcibr_soft->bs_min_slot; s < PCIBR_NUM_SLOTS(pcibr_soft); ++s) {
-	int                     nf = pcibr_soft->bs_slot[s].bss_ninfo;
-	pcibr_info_h            pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos;
-
-	for (f = 0; f < nf; f++) {
-	    pcibr_info_t            pcibr_info = pcibr_infoh[f];
-
-	    if (!pcibr_info)
-		continue;
-	    for (w = 0; w < 6; w++) {
-		if (pcibr_info->f_window[w].w_space == PCIIO_SPACE_NONE) {
-		    continue;
-		}
-		base = pcibr_info->f_window[w].w_base;
-		size = pcibr_info->f_window[w].w_size;
-
-		if ((pciaddr >= base) && (pciaddr < (base + size))) {
-		    if (spacep)
-			*spacep = PCIIO_SPACE_WIN(w);
-		    if (offsetp)
-			*offsetp = pciaddr - base;
-		    if (funcp)
-			*funcp = f;
-		    return s;
-		}			/* endif match */
-	    }				/* next window */
-	}				/* next func */
-    }					/* next slot */
-
-    /*
-     * Check if the address was allocated as part of the
-     * pcibr_piospace_alloc calls.
-     */
-    for (s = pcibr_soft->bs_min_slot; s < PCIBR_NUM_SLOTS(pcibr_soft); ++s) {
-	int                     nf = pcibr_soft->bs_slot[s].bss_ninfo;
-	pcibr_info_h            pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos;
-
-	for (f = 0; f < nf; f++) {
-	    pcibr_info_t            pcibr_info = pcibr_infoh[f];
-
-	    if (!pcibr_info)
-		continue;
-	    piosp = pcibr_info->f_piospace;
-	    while (piosp) {
-		if ((piosp->start <= pciaddr) &&
-		    ((piosp->count + piosp->start) > pciaddr)) {
-		    if (spacep)
-			*spacep = piosp->space;
-		    if (offsetp)
-			*offsetp = pciaddr - piosp->start;
-		    return s;
-		}			/* endif match */
-		piosp = piosp->next;
-	    }				/* next piosp */
-	}				/* next func */
-    }					/* next slot */
-
-    /*
-     * Some other random address on the PCI bus ...
-     * we have no way of knowing whether this was
-     * a MEM or I/O access; so, for now, we just
-     * assume that the low 1G is MEM, the next
-     * 3G is I/O, and anything above the 4G limit
-     * is obviously MEM.
-     */
-
-    if (spacep)
-	*spacep = ((pciaddr < (1ul << 30)) ? PCIIO_SPACE_MEM :
-		   (pciaddr < (4ul << 30)) ? PCIIO_SPACE_IO :
-		   PCIIO_SPACE_MEM);
-    if (offsetp)
-	*offsetp = pciaddr;
-
-    return PCIIO_SLOT_NONE;
-
-}
-
 void
 pcibr_error_cleanup(pcibr_soft_t pcibr_soft, int error_code)
 {
@@ -1286,59 +992,6 @@
     (void) bridge->b_wid_tflush;	/* flushbus */
 }
 
-/*
- * pcibr_error_extract
- *      Given the 'pcibr vertex handle' find out which slot
- *      the bridge status error address (from pcibr_soft info
- *      hanging off the vertex)
- *      allocated to, and return the slot number.
- *      While we have the info handy, construct the
- *      space code and offset as well.
- *
- * NOTE: if this routine is called, we don't know whether
- * the address is in CFG, MEM, or I/O space. We have to guess.
- * This will be the case on PIO stores, where the only way
- * we have of getting the address is to check the Bridge, which
- * stores the PCI address but not the space and not the xtalk
- * address (from which we could get it).
- *
- * XXX- this interface has no way to return the function
- * number on a multifunction card, even though that data
- * is available.
- */
-
-pciio_slot_t
-pcibr_error_extract(devfs_handle_t pcibr_vhdl,
-		    pciio_space_t *spacep,
-		    iopaddr_t *offsetp)
-{
-    pcibr_soft_t            pcibr_soft = 0;
-    iopaddr_t               bserr_addr;
-    bridge_t               *bridge;
-    pciio_slot_t            slot = PCIIO_SLOT_NONE;
-    arbitrary_info_t	    rev;
-
-    /* Do a sanity check as to whether we really got a 
-     * bridge vertex handle.
-     */
-    if (hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &rev) !=
-	GRAPH_SUCCESS) 
-	return(slot);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (pcibr_soft) {
-	bridge = pcibr_soft->bs_base;
-	bserr_addr =
-	    bridge->b_pci_err_lower |
-	    ((uint64_t) (bridge->b_pci_err_upper &
-			   BRIDGE_ERRUPPR_ADDRMASK) << 32);
-
-	slot = pcibr_addr_toslot(pcibr_soft, bserr_addr,
-				 spacep, offsetp, NULL);
-    }
-    return slot;
-}
-
 /*ARGSUSED */
 void
 pcibr_device_disable(pcibr_soft_t pcibr_soft, int devnum)
@@ -1426,7 +1079,7 @@
 {
     int                     retval = IOERROR_HANDLED;
 
-    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
+    vertex_hdl_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
     bridge_t               *bridge = pcibr_soft->bs_base;
 
     iopaddr_t               bad_xaddr;
@@ -1806,7 +1459,7 @@
 	 *
 	 * CAUTION: Resetting bit BRIDGE_IRR_PCI_GRP_CLR, acknowledges
 	 *      a group of interrupts. If while handling this error,
-	 *      some other error has occured, that would be
+	 *      some other error has occurred, that would be
 	 *      implicitly cleared by this write.
 	 *      Need a way to ensure we don't inadvertently clear some
 	 *      other errors.
@@ -1837,7 +1490,7 @@
 		     ioerror_mode_t mode,
 		     ioerror_t *ioe)
 {
-    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
+    vertex_hdl_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
     bridge_t               *bridge = pcibr_soft->bs_base;
     bridgereg_t             bus_lowaddr, bus_uppraddr;
     int                     retval = 0;
@@ -1874,7 +1527,7 @@
 			BRIDGE_ERRUPPR_ADDRMASK) << 32)));
 
     /*
-     * need to ensure that the xtalk adress in ioe
+     * need to ensure that the xtalk address in ioe
      * maps to PCI error address read from bridge.
      * How to convert PCI address back to Xtalk address ?
      * (better idea: convert XTalk address to PCI address
@@ -1946,7 +1599,7 @@
 		     ioerror_mode_t mode,
 		     ioerror_t *ioe)
 {
-    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
+    vertex_hdl_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
     int                     retval;
 
     retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe);
@@ -1982,34 +1635,12 @@
     pcibr_soft_t            pcibr_soft;
     int                     retval = IOERROR_BADERRORCODE;
 
-#ifdef EHE_ENABLE
-    devfs_handle_t	    xconn_vhdl,pcibr_vhdl;
-    error_state_t	    e_state;
-#endif /* EHE_ENABLE */
-
     pcibr_soft = (pcibr_soft_t) einfo;
 
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ERROR_HDLR, pcibr_soft->bs_conn,
 		"pcibr_error_handler: pcibr_soft=0x%x, error_code=0x%x\n",
 		pcibr_soft, error_code));
 
-#ifdef EHE_ENABLE
-    xconn_vhdl = pcibr_soft->bs_conn;
-    pcibr_vhdl = pcibr_soft->bs_vhdl;
-
-    e_state = error_state_get(xconn_vhdl);
-    
-    if (error_state_set(pcibr_vhdl, e_state) == 
-	ERROR_RETURN_CODE_CANNOT_SET_STATE)
-	return(IOERROR_UNHANDLED);
-
-    /* If we are in the action handling phase clean out the error state
-     * on the xswitch.
-     */
-    if (e_state == ERROR_STATE_ACTION)
-	(void)error_state_set(xconn_vhdl, ERROR_STATE_NONE);
-#endif /* EHE_ENABLE */
-
 #if DEBUG && ERROR_DEBUG
     printk( "%s: pcibr_error_handler\n", pcibr_soft->bs_name);
 #endif
@@ -2086,11 +1717,6 @@
      * the error from the PIO address.
      */
 
-#if 0
-    if (mode == MODE_DEVPROBE)
-	pio_retval = IOERROR_HANDLED;
-    else {
-#endif
     if (error_code & IOECODE_PIO) {
 	iopaddr_t               bad_xaddr;
 	/*
@@ -2123,9 +1749,6 @@
 	    pio_retval = IOERROR_UNHANDLED;
 	}
     } 
-#if 0
-    } /* MODE_DEVPROBE */
-#endif
 
     /* 
      * If the error was a result of a DMA Write, we tell what bus on the PIC
@@ -2201,37 +1824,3 @@
 	return IOERROR_HANDLED;
     }
 }
-
-
-/*
- * Reenable a device after handling the error.
- * This is called by the lower layers when they wish to be reenabled
- * after an error.
- * Note that each layer would be calling the previous layer to reenable
- * first, before going ahead with their own re-enabling.
- */
-
-int
-pcibr_error_devenable(devfs_handle_t pconn_vhdl, int error_code)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-    ASSERT(error_code & IOECODE_PIO);
-
-    /* If the error is not known to be a write,
-     * we have to call devenable.
-     * write errors are isolated to the bridge.
-     */
-    if (!(error_code & IOECODE_WRITE)) {
-	devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-	int                     rc;
-
-	rc = xtalk_error_devenable(xconn_vhdl, pciio_slot, error_code);
-	if (rc != IOERROR_HANDLED)
-	    return rc;
-    }
-    pcibr_error_cleanup(pcibr_soft, error_code);
-    return IOERROR_HANDLED;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c	2003-08-01 13:32:16.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,20 +27,19 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
-pcibr_hints_t           pcibr_hints_get(devfs_handle_t, int);
-void                    pcibr_hints_fix_rrbs(devfs_handle_t);
-void                    pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
-void			pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
-void                    pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t);
-void                    pcibr_hints_handsoff(devfs_handle_t);
-void                    pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t);
+pcibr_hints_t           pcibr_hints_get(vertex_hdl_t, int);
+void                    pcibr_hints_fix_rrbs(vertex_hdl_t);
+void                    pcibr_hints_dualslot(vertex_hdl_t, pciio_slot_t, pciio_slot_t);
+void			pcibr_hints_intr_bits(vertex_hdl_t, pcibr_intr_bits_f *);
+void                    pcibr_set_rrb_callback(vertex_hdl_t, rrb_alloc_funct_t);
+void                    pcibr_hints_handsoff(vertex_hdl_t);
+void                    pcibr_hints_subdevs(vertex_hdl_t, pciio_slot_t, uint64_t);
 
 pcibr_hints_t
-pcibr_hints_get(devfs_handle_t xconn_vhdl, int alloc)
+pcibr_hints_get(vertex_hdl_t xconn_vhdl, int alloc)
 {
     arbitrary_info_t        ainfo = 0;
     graph_error_t	    rv;
@@ -79,7 +78,7 @@
 }
 
 void
-pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask)
+pcibr_hints_fix_some_rrbs(vertex_hdl_t xconn_vhdl, unsigned mask)
 {
     pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
 
@@ -91,13 +90,13 @@
 }
 
 void
-pcibr_hints_fix_rrbs(devfs_handle_t xconn_vhdl)
+pcibr_hints_fix_rrbs(vertex_hdl_t xconn_vhdl)
 {
     pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF);
 }
 
 void
-pcibr_hints_dualslot(devfs_handle_t xconn_vhdl,
+pcibr_hints_dualslot(vertex_hdl_t xconn_vhdl,
 		     pciio_slot_t host,
 		     pciio_slot_t guest)
 {
@@ -111,7 +110,7 @@
 }
 
 void
-pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl,
+pcibr_hints_intr_bits(vertex_hdl_t xconn_vhdl,
 		      pcibr_intr_bits_f *xxx_intr_bits)
 {
     pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
@@ -124,7 +123,7 @@
 }
 
 void
-pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct)
+pcibr_set_rrb_callback(vertex_hdl_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct)
 {
     pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
 
@@ -133,7 +132,7 @@
 }
 
 void
-pcibr_hints_handsoff(devfs_handle_t xconn_vhdl)
+pcibr_hints_handsoff(vertex_hdl_t xconn_vhdl)
 {
     pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
 
@@ -145,13 +144,13 @@
 }
 
 void
-pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
+pcibr_hints_subdevs(vertex_hdl_t xconn_vhdl,
 		    pciio_slot_t slot,
 		    uint64_t subdevs)
 {
     arbitrary_info_t        ainfo = 0;
     char                    sdname[16];
-    devfs_handle_t            pconn_vhdl = GRAPH_VERTEX_NONE;
+    vertex_hdl_t            pconn_vhdl = GRAPH_VERTEX_NONE;
 
     sprintf(sdname, "%s/%d", EDGE_LBL_PCI, slot);
     (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,147 +0,0 @@
-/*
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_defs.h>
-#include <asm/sn/prio.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_private.h>
-
-#ifdef LATER
-
-char *pci_space[] = {"NONE", 
-		     "ROM",
-		     "IO",
-		     "",
-		     "MEM",
-		     "MEM32",
-		     "MEM64",
-		     "CFG",
-		     "WIN0",
-		     "WIN1",
-		     "WIN2",
-		     "WIN3",
-		     "WIN4",
-		     "WIN5",
-		     "",
-		     "BAD"};
-
-void
-idbg_pss_func(pcibr_info_h pcibr_infoh, int func)
-{
-    pcibr_info_t	pcibr_info = pcibr_infoh[func];
-    char		name[MAXDEVNAME];
-    int			win;
-    
-    if (!pcibr_info)
-	return;
-    qprintf("Per-slot Function Info\n");
-    sprintf(name, "%v", pcibr_info->f_vertex);
-    qprintf("\tSlot Name : %s\n",name);
-    qprintf("\tPCI Bus : %d ",pcibr_info->f_bus);
-    qprintf("Slot : %d ", pcibr_info->f_slot);
-    qprintf("Function : %d ", pcibr_info->f_func);
-    qprintf("VendorId : 0x%x " , pcibr_info->f_vendor);
-    qprintf("DeviceId : 0x%x\n", pcibr_info->f_device);
-    sprintf(name, "%v", pcibr_info->f_master);
-    qprintf("\tBus provider : %s\n",name);
-    qprintf("\tProvider Fns : 0x%x ", pcibr_info->f_pops);
-    qprintf("Error Handler : 0x%x Arg 0x%x\n", 
-	    pcibr_info->f_efunc,pcibr_info->f_einfo);
-    for(win = 0 ; win < 6 ; win++) 
-	qprintf("\tBase Reg #%d space %s base 0x%x size 0x%x\n",
-		win,pci_space[pcibr_info->f_window[win].w_space],
-		pcibr_info->f_window[win].w_base,
-		pcibr_info->f_window[win].w_size);
-
-    qprintf("\tRom base 0x%x size 0x%x\n", 
-	    pcibr_info->f_rbase,pcibr_info->f_rsize);
-
-    qprintf("\tInterrupt Bit Map\n");
-    qprintf("\t\tPCI Int#\tBridge Pin#\n");
-    for (win = 0 ; win < 4; win++)
-	qprintf("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]);
-    qprintf("\n");
-}
-
-
-void
-idbg_pss_info(pcibr_soft_t pcibr_soft, pciio_slot_t slot)
-{
-    pcibr_soft_slot_t	pss;
-    char		slot_conn_name[MAXDEVNAME];
-    int			func;
-
-    pss = &pcibr_soft->bs_slot[slot];
-    qprintf("PCI INFRASTRUCTURAL INFO FOR SLOT %d\n", slot);
-    qprintf("\tHost Present ? %s ", pss->has_host ? "yes" : "no");
-    qprintf("\tHost Slot : %d\n",pss->host_slot);
-    sprintf(slot_conn_name, "%v", pss->slot_conn);
-    qprintf("\tSlot Conn : %s\n",slot_conn_name);	
-    qprintf("\t#Functions : %d\n",pss->bss_ninfo);
-    for (func = 0; func < pss->bss_ninfo; func++)
-	idbg_pss_func(pss->bss_infos,func);
-    qprintf("\tSpace : %s ",pci_space[pss->bss_devio.bssd_space]);
-    qprintf("\tBase : 0x%x ", pss->bss_devio.bssd_base);
-    qprintf("\tShadow Devreg : 0x%x\n", pss->bss_device);
-    qprintf("\tUsage counts : pmu %d d32 %d d64 %d\n",
-	    pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr);
-    
-    qprintf("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x"
-	    "d32_base 0x%x d32_flags 0x%x\n",
-	    pss->bss_d64_base, pss->bss_d64_flags,
-	    pss->bss_d32_base, pss->bss_d32_flags);
-    
-    qprintf("\tExt ATEs active ? %s", 
-	    pss->bss_ext_ates_active ? "yes" : "no");
-    qprintf(" Command register : 0x%x ", pss->bss_cmd_pointer);
-    qprintf(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow);
-
-    qprintf("\tRRB Info : Valid %d+%d Reserved %d\n",
-	    pcibr_soft->bs_rrb_valid[slot],
-	    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-		
-}
-
-int	ips = 0;
-
-void
-idbg_pss(pcibr_soft_t pcibr_soft)
-{
-    pciio_slot_t	slot;
-
-    
-    if (ips >= 0 && ips < 8)
-	idbg_pss_info(pcibr_soft,ips);
-    else if (ips < 0)
-	for (slot = 0; slot < 8; slot++) 
-	    idbg_pss_info(pcibr_soft,slot);
-    else
-	qprintf("Invalid ips %d\n",ips);
-}
-#endif	/* LATER */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c	2003-08-01 13:30:31.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,29 +27,35 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
 #ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
+inline int
+compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr)
+{
+	FIXME("compare_and_swap_ptr : NOT ATOMIC");
+	if (*location == old_ptr) {
+		*location = new_ptr;
+		return(1);
+	}
+	else
+		return(0);
+}
 #endif
 
 unsigned		pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines, int nslots);
-pcibr_intr_t            pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
+pcibr_intr_t            pcibr_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t);
 void                    pcibr_intr_free(pcibr_intr_t);
 void              pcibr_setpciint(xtalk_intr_t);
 int                     pcibr_intr_connect(pcibr_intr_t, intr_func_t, intr_arg_t);
 void                    pcibr_intr_disconnect(pcibr_intr_t);
 
-devfs_handle_t            pcibr_intr_cpu_get(pcibr_intr_t);
+vertex_hdl_t            pcibr_intr_cpu_get(pcibr_intr_t);
 void                    pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
 void                    pcibr_intr_func(intr_arg_t);
 
-extern pcibr_info_t      pcibr_info_get(devfs_handle_t);
+extern pcibr_info_t      pcibr_info_get(vertex_hdl_t);
 
 /* =====================================================================
  *    INTERRUPT MANAGEMENT
@@ -132,6 +138,102 @@
 }
 
 /*
+ *	On SN systems there is a race condition between a PIO read response
+ *	and DMA's.  In rare cases, the read response may beat the DMA, causing
+ *	the driver to think that data in memory is complete and meaningful.
+ *	This code eliminates that race.
+ *	This routine is called by the PIO read routines after doing the read.
+ *	This routine then forces a fake interrupt on another line, which
+ *	is logically associated with the slot that the PIO is addressed to.
+ *	(see sn_dma_flush_init() )
+ *	It then spins while watching the memory location that the interrupt
+ *	is targetted to.  When the interrupt response arrives, we are sure
+ *	that the DMA has landed in memory and it is safe for the driver
+ *	to proceed.
+ */
+
+extern struct sn_flush_nasid_entry flush_nasid_list[MAX_NASIDS];
+
+void
+sn_dma_flush(unsigned long addr) {
+	nasid_t nasid;
+	int wid_num;
+	volatile struct sn_flush_device_list *p;
+	int i,j;
+	int bwin;
+	unsigned long flags;
+
+	nasid = NASID_GET(addr);
+	wid_num = SWIN_WIDGETNUM(addr);
+	bwin = BWIN_WINDOWNUM(addr);
+
+	if (flush_nasid_list[nasid].widget_p == NULL) return;
+	if (bwin > 0) {
+		bwin--;
+		switch (bwin) {
+			case 0:
+				wid_num = ((flush_nasid_list[nasid].iio_itte1) >> 8) & 0xf;
+				break;
+			case 1:
+				wid_num = ((flush_nasid_list[nasid].iio_itte2) >> 8) & 0xf;
+				break;
+			case 2: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte3) >> 8) & 0xf;
+				break;
+			case 3: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte4) >> 8) & 0xf;
+				break;
+			case 4: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte5) >> 8) & 0xf;
+				break;
+			case 5: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte6) >> 8) & 0xf;
+				break;
+			case 6: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte7) >> 8) & 0xf;
+				break;
+		}
+	}
+	if (flush_nasid_list[nasid].widget_p == NULL) return;
+	if (flush_nasid_list[nasid].widget_p[wid_num] == NULL) return;
+	p = &flush_nasid_list[nasid].widget_p[wid_num][0];
+
+	// find a matching BAR
+
+	for (i=0; i<DEV_PER_WIDGET;i++) {
+		for (j=0; j<PCI_ROM_RESOURCE;j++) {
+			if (p->bar_list[j].start == 0) break;
+			if (addr >= p->bar_list[j].start && addr <= p->bar_list[j].end) break;
+		}
+		if (j < PCI_ROM_RESOURCE && p->bar_list[j].start != 0) break;
+		p++;
+	}
+
+	// if no matching BAR, return without doing anything.
+
+	if (i == DEV_PER_WIDGET) return;
+
+	spin_lock_irqsave(&p->flush_lock, flags);
+
+	p->flush_addr = 0;
+
+	// force an interrupt.
+
+	*(bridgereg_t *)(p->force_int_addr) = 1;
+
+	// wait for the interrupt to come back.
+
+	while (p->flush_addr != 0x10f);
+
+	// okay, everything is synched up.
+	spin_unlock_irqrestore(&p->flush_lock, flags);
+
+	return;
+}
+
+EXPORT_SYMBOL(sn_dma_flush);
+
+/*
  *	There are end cases where a deadlock can occur if interrupt 
  *	processing completes and the Bridge b_int_status bit is still set.
  *
@@ -164,51 +266,42 @@
  *	to check if a specific Bridge b_int_status bit is set, and if so,
  *	cause the setting of the corresponding interrupt bit.
  *
- *	On a XBridge (SN1), we do this by writing the appropriate Bridge Force 
- *	Interrupt register. On SN0, or SN1 with an older Bridge, the Bridge 
- *	Force Interrupt register does not exist, so we write the Hub 
- *	INT_PEND_MOD register directly. Likewise for Octane, where we write the 
- *	Heart Set Interrupt Status register directly.
+ *	On a XBridge (SN1) and PIC (SN2), we do this by writing the appropriate Bridge Force 
+ *	Interrupt register.
  */
 void
-pcibr_force_interrupt(pcibr_intr_wrap_t wrap)
+pcibr_force_interrupt(pcibr_intr_t intr)
 {
-#ifdef PIC_LATER
 	unsigned	bit;
-	pcibr_soft_t    pcibr_soft = wrap->iw_soft;
+	unsigned	bits;
+	pcibr_soft_t    pcibr_soft = intr->bi_soft;
 	bridge_t       *bridge = pcibr_soft->bs_base;
 
-	bit = wrap->iw_ibit;
+	bits = intr->bi_ibits;
+	for (bit = 0; bit < 8; bit++) {
+		if (bits & (1 << bit)) {
 
-	PCIBR_DEBUG((PCIBR_DEBUG_INTR, pcibr_soft->bs_vhdl,
-		    "pcibr_force_interrupt: bit=0x%x\n", bit));
+			PCIBR_DEBUG((PCIBR_DEBUG_INTR, pcibr_soft->bs_vhdl,
+		    		"pcibr_force_interrupt: bit=0x%x\n", bit));
 
-	if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft)) {
-	    bridge->b_force_pin[bit].intr = 1;
-	} else if ((1 << bit) & *wrap->iw_stat) {
-	    cpuid_t	    cpu;
-	    unsigned        intr_bit;
-	    xtalk_intr_t    xtalk_intr =
-				pcibr_soft->bs_intr[bit].bsi_xtalk_intr;
-
-	    intr_bit = (short) xtalk_intr_vector_get(xtalk_intr);
-	    cpu = xtalk_intr_cpuid_get(xtalk_intr);
-	    REMOTE_CPU_SEND_INTR(cpu, intr_bit);
+			if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft)) {
+	    			bridge->b_force_pin[bit].intr = 1;
+			}
+		}
 	}
-#endif	/* PIC_LATER */
 }
 
 /*ARGSUSED */
 pcibr_intr_t
-pcibr_intr_alloc(devfs_handle_t pconn_vhdl,
+pcibr_intr_alloc(vertex_hdl_t pconn_vhdl,
 		 device_desc_t dev_desc,
 		 pciio_intr_line_t lines,
-		 devfs_handle_t owner_dev)
+		 vertex_hdl_t owner_dev)
 {
     pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pcibr_info);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
     bridge_t               *bridge = pcibr_soft->bs_base;
     int                     is_threaded = 0;
 
@@ -498,25 +591,18 @@
 {
     iopaddr_t		 addr;
     xtalk_intr_vector_t	 vect;
-    devfs_handle_t	 vhdl;
+    vertex_hdl_t	 vhdl;
     bridge_t		*bridge;
+    picreg_t	*int_addr;
 
     addr = xtalk_intr_addr_get(xtalk_intr);
     vect = xtalk_intr_vector_get(xtalk_intr);
     vhdl = xtalk_intr_dev_get(xtalk_intr);
     bridge = (bridge_t *)xtalk_piotrans_addr(vhdl, 0, 0, sizeof(bridge_t), 0);
 
-    if (is_pic(bridge)) {
-	picreg_t	*int_addr;
-	int_addr = (picreg_t *)xtalk_intr_sfarg_get(xtalk_intr);
-	*int_addr = ((PIC_INT_ADDR_FLD & ((uint64_t)vect << 48)) |
+    int_addr = (picreg_t *)xtalk_intr_sfarg_get(xtalk_intr);
+    *int_addr = ((PIC_INT_ADDR_FLD & ((uint64_t)vect << 48)) |
 		     (PIC_INT_ADDR_HOST & addr));
-    } else {
-	bridgereg_t	*int_addr;
-	int_addr = (bridgereg_t *)xtalk_intr_sfarg_get(xtalk_intr);
-	*int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
-		     (BRIDGE_INT_ADDR_FLD & vect));
-    }
 }
 
 /*ARGSUSED */
@@ -582,8 +668,7 @@
 	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_intr->bi_dev,
 			"pcibr_setpciint: int_addr=0x%x, *int_addr=0x%x, "
 			"pcibr_int_bit=0x%x\n", int_addr,
-			(is_pic(bridge) ? 
-			 *(picreg_t *)int_addr : *(bridgereg_t *)int_addr),
+			 *(picreg_t *)int_addr,
 			pcibr_int_bit));
 	}
 
@@ -699,7 +784,7 @@
 	    xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr,
 				pcibr_intr_func, (intr_arg_t) intr_wrap,
 			       (xtalk_intr_setfunc_t)pcibr_setpciint,
-			       (void *)pcibr_int_bit);
+			       (void *)(long)pcibr_int_bit);
 	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_intr->bi_dev,
 			"pcibr_intr_disconnect: now-sharing int_bits=0x%x\n",
 			pcibr_int_bit));
@@ -707,7 +792,7 @@
 }
 
 /*ARGSUSED */
-devfs_handle_t
+vertex_hdl_t
 pcibr_intr_cpu_get(pcibr_intr_t pcibr_intr)
 {
     pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
@@ -780,9 +865,6 @@
     bridge->b_wid_int_lower = NEW_b_wid_int_lower;
     bridge->b_int_host_err = vect;
 
-printk("pcibr_setwidint: b_wid_int_upper 0x%x b_wid_int_lower 0x%x b_int_host_err 0x%x\n",
-	NEW_b_wid_int_upper, NEW_b_wid_int_lower, vect);
-
 }
 
 /*
@@ -842,7 +924,7 @@
  *
  * This is the pcibr interrupt "wrapper" function that is called,
  * in interrupt context, to initiate the interrupt handler(s) registered
- * (via pcibr_intr_alloc/connect) for the occuring interrupt. Non-threaded 
+ * (via pcibr_intr_alloc/connect) for the occurring interrupt. Non-threaded 
  * handlers will be called directly, and threaded handlers will have their 
  * thread woken up.
  */
@@ -957,7 +1039,7 @@
 	     * interrupt to avoid a potential deadlock situation.
 	     */
 	    if (wrap->iw_hdlrcnt == 0) {
-		pcibr_force_interrupt(wrap);
+		pcibr_force_interrupt((pcibr_intr_t) wrap);
 	    }
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c	2003-08-01 13:31:14.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,7 +27,6 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
@@ -41,11 +40,11 @@
 
 void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int, int);
 
-int		  pcibr_wrb_flush(devfs_handle_t);
-int               pcibr_rrb_alloc(devfs_handle_t, int *, int *);
-int               pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *);
-void              pcibr_rrb_flush(devfs_handle_t);
-int		  pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
+int		  pcibr_wrb_flush(vertex_hdl_t);
+int               pcibr_rrb_alloc(vertex_hdl_t, int *, int *);
+int               pcibr_rrb_check(vertex_hdl_t, int *, int *, int *, int *);
+void              pcibr_rrb_flush(vertex_hdl_t);
+int		  pcibr_slot_initial_rrb_alloc(vertex_hdl_t,pciio_slot_t);
 
 void		  pcibr_rrb_debug(char *, pcibr_soft_t);
 
@@ -70,17 +69,15 @@
 #define RRB_SIZE (4)			/* sizeof rrb within reg (bits) */
  
 #define RRB_ENABLE_BIT(bridge)		(0x8)  /* [BRIDGE | PIC]_RRB_EN */
-#define NUM_PDEV_BITS(bridge)		(is_pic((bridge)) ? 1 : 2)
-#define NUM_VDEV_BITS(bridge)		(is_pic((bridge)) ? 2 : 1)
-#define NUMBER_VCHANNELS(bridge)	(is_pic((bridge)) ? 4 : 2)
+#define NUM_PDEV_BITS(bridge)		(1)
+#define NUM_VDEV_BITS(bridge)		(2)
+#define NUMBER_VCHANNELS(bridge)	(4)
 #define SLOT_2_PDEV(bridge, slot)	((slot) >> 1)
 #define SLOT_2_RRB_REG(bridge, slot)	((slot) & 0x1)
  
 /* validate that the slot and virtual channel are valid for a given bridge */
 #define VALIDATE_SLOT_n_VCHAN(bridge, s, v) \
-  (is_pic((bridge)) ? \
-    (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)3)) && (((v) >= 0) && ((v) <= 3))) ? 1 : 0) : \
-    (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)7)) && (((v) >= 0) && ((v) <= 1))) ? 1 : 0))
+    (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)3)) && (((v) >= 0) && ((v) <= 3))) ? 1 : 0)
  
 /*  
  * Count how many RRBs are marked valid for the specified PCI slot
@@ -105,16 +102,7 @@
     pdev_bits = SLOT_2_PDEV(bridge, slot);
     rrb_bits = enable_bit | vchan_bits | pdev_bits;
     
-    if ( is_pic(bridge) ) {
-	tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg));
-	} else {
-		tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-	}
-    }
+    tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
 
     for (rrb_index = 0; rrb_index < 8; rrb_index++) {
 	if ((tmp & RRB_MASK) == rrb_bits)
@@ -144,16 +132,7 @@
     
     enable_bit = RRB_ENABLE_BIT(bridge);
 
-    if ( is_pic(bridge) ) {
-	tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg));
-	} else {
-		tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-	}
-    }
+    tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
 
     for (rrb_index = 0; rrb_index < 8; rrb_index++) {
 	if ((tmp & enable_bit) != enable_bit)
@@ -192,17 +171,8 @@
     pdev_bits = SLOT_2_PDEV(bridge, slot);
     rrb_bits = enable_bit | vchan_bits | pdev_bits;
 
-    if ( is_pic(bridge) ) {
-	reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		reg = tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg));
-	} else {
-		reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-	}
-    }
-    
+    reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
+
     for (rrb_index = 0; ((rrb_index < 8) && (more > 0)); rrb_index++) {
 	if ((tmp & enable_bit) != enable_bit) {
 	    /* clear the rrb and OR in the new rrb into 'reg' */
@@ -213,16 +183,7 @@
 	tmp = (tmp >> RRB_SIZE);
     }
 
-    if ( is_pic(bridge) ) {
-	bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)) = reg;
-	} else {
-		bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
-	}
-    }
+    bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
     return (more ? -1 : 0);
 }
  
@@ -255,24 +216,15 @@
     pdev_bits = SLOT_2_PDEV(bridge, slot);
     rrb_bits = enable_bit | vchan_bits | pdev_bits;
 
-    if ( is_pic(bridge) ) {
-	reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		reg = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg));
-	} else {
-		reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-	}
-    }
-    
+    reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
+
     for (rrb_index = 0; ((rrb_index < 8) && (less > 0)); rrb_index++) {
 	if ((tmp & RRB_MASK) == rrb_bits) {
 	   /*
 	    * the old do_pcibr_rrb_free() code only clears the enable bit
 	    * but I say we should clear the whole rrb (ie):
 	    *	  reg = reg & ~(RRB_MASK << (RRB_SIZE * rrb_index));
-	    * But to be compatable with old code we'll only clear enable.
+	    * But to be compatible with old code we'll only clear enable.
 	    */
 	    reg = reg & ~(RRB_ENABLE_BIT(bridge) << (RRB_SIZE * rrb_index));
 	    clr = clr | (enable_bit << (RRB_SIZE * rrb_index));
@@ -281,16 +233,7 @@
 	tmp = (tmp >> RRB_SIZE);
     }
 
-    if ( is_pic(bridge) ) {
-	bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)) = reg;
-	} else {
-		bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
-	}
-    }
+    bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
 
     /* call do_pcibr_rrb_clear() for all the rrbs we've freed */
     for (rrb_index = 0; rrb_index < 8; rrb_index++) {
@@ -337,50 +280,18 @@
      * this RRB must be disabled.
      */
 
-    if ( is_pic(bridge) ) {
-	/* wait until RRB has no outstanduing XIO packets. */
-	while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
-		;				/* XXX- beats on bridge. bad idea? */
-	}
-
-	/* if the RRB has data, drain it. */
-	if (status & BRIDGE_RRB_VALID(rrb)) {
-		bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
-
-		/* wait until RRB is no longer valid. */
-		while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
-			;				/* XXX- beats on bridge. bad idea? */
-		}
-	}
+    /* wait until RRB has no outstanduing XIO packets. */
+    while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
+	;				/* XXX- beats on bridge. bad idea? */
     }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		while ((status = BRIDGE_REG_GET32((&bridge->b_resp_status))) & BRIDGE_RRB_INUSE(rrb)) {
-			;                               /* XXX- beats on bridge. bad idea? */
-		}
-
-		/* if the RRB has data, drain it. */
-		if (status & BRIDGE_RRB_VALID(rrb)) {
-			BRIDGE_REG_SET32((&bridge->b_resp_clear)) = __swab32(BRIDGE_RRB_CLEAR(rrb));
-
-			/* wait until RRB is no longer valid. */
-			while ((status = BRIDGE_REG_GET32((&bridge->b_resp_status))) & BRIDGE_RRB_VALID(rrb)) {
-				;                           /* XXX- beats on bridge. bad idea? */
-			}
-		}
-	} else { /* io_get_sh_swapper(NASID_GET(bridge)) */
-		while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
-			;                               /* XXX- beats on bridge. bad idea? */
-		}
-
-		/* if the RRB has data, drain it. */
-		if (status & BRIDGE_RRB_VALID(rrb)) {
-			bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
-			/* wait until RRB is no longer valid. */
-			while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
-				;                           /* XXX- beats on bridge. bad idea? */
-			}
-		}
+
+    /* if the RRB has data, drain it. */
+    if (status & BRIDGE_RRB_VALID(rrb)) {
+	bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
+
+	/* wait until RRB is no longer valid. */
+	while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
+		;				/* XXX- beats on bridge. bad idea? */
 	}
     }
 }
@@ -399,43 +310,16 @@
     int		 shft = (RRB_SIZE * (rrbn >> 1));
     unsigned long	 ebit = RRB_ENABLE_BIT(bridge) << shft;
 
-    if ( is_pic(bridge) ) {
-	rrbv = *rrbp;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		rrbv = BRIDGE_REG_GET32((&rrbp));
-	} else {
-		rrbv = *rrbp;
-	}
-    }
+    rrbv = *rrbp;
 
     if (rrbv & ebit) {
-    	if ( is_pic(bridge) ) {
-		*rrbp = rrbv & ~ebit;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			BRIDGE_REG_SET32((&rrbp)) = __swab32((rrbv & ~ebit));
-		} else {
-			*rrbp = rrbv & ~ebit;
-		}
-	}
+	*rrbp = rrbv & ~ebit;
     }
 
     do_pcibr_rrb_clear(bridge, rrbn);
 
     if (rrbv & ebit) {
-	if ( is_pic(bridge) ) {
-		*rrbp = rrbv;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			BRIDGE_REG_SET32((&rrbp)) = __swab32(rrbv);
-		} else {
-			*rrbp = rrbv;
-		}
-	}
+	*rrbp = rrbv;
     }
 }
 
@@ -475,7 +359,7 @@
  * Flush all the rrb's assigned to the specified connection point.
  */
 void
-pcibr_rrb_flush(devfs_handle_t pconn_vhdl)
+pcibr_rrb_flush(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t  pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t  pcibr_soft = (pcibr_soft_t)pciio_info_mfast_get(pciio_info);
@@ -510,7 +394,7 @@
  * device hanging off the bridge.
  */
 int
-pcibr_wrb_flush(devfs_handle_t pconn_vhdl)
+pcibr_wrb_flush(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
@@ -546,7 +430,7 @@
  * as best we can and return 0.
  */
 int
-pcibr_rrb_alloc(devfs_handle_t pconn_vhdl,
+pcibr_rrb_alloc(vertex_hdl_t pconn_vhdl,
 		int *count_vchan0,
 		int *count_vchan1)
 {
@@ -753,7 +637,7 @@
  */
 
 int
-pcibr_rrb_check(devfs_handle_t pconn_vhdl,
+pcibr_rrb_check(vertex_hdl_t pconn_vhdl,
 		int *count_vchan0,
 		int *count_vchan1,
 		int *count_reserved,
@@ -802,7 +686,7 @@
  */
 
 int
-pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl,
+pcibr_slot_initial_rrb_alloc(vertex_hdl_t pcibr_vhdl,
 			     pciio_slot_t slot)
 {
     pcibr_soft_t	 pcibr_soft;
@@ -816,10 +700,10 @@
     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
 
     if (!pcibr_soft)
-	return(EINVAL);
+	return(-EINVAL);
 
     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
-	return(EINVAL);
+	return(-EINVAL);
 
     bridge = pcibr_soft->bs_base;
 
@@ -857,7 +741,13 @@
 
         pcibr_soft->bs_rrb_valid[slot][3] = chan[3];
 
-        return(ENODEV);
+        return(-ENODEV);
+    }
+
+    /* Give back any assigned to empty slots */
+    if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) && !pcibr_soft->bs_slot[slot].has_host) {
+	do_pcibr_rrb_free_all(pcibr_soft, bridge, slot);
+	return(-ENODEV);
     }
 
     for (vchan = 0; vchan < vchan_total; vchan++)
@@ -889,7 +779,7 @@
  */
 
 int
-pcibr_initial_rrb(devfs_handle_t pcibr_vhdl,
+pcibr_initial_rrb(vertex_hdl_t pcibr_vhdl,
 			     pciio_slot_t first, pciio_slot_t last)
 {
     pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c	2003-08-01 13:31:53.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -28,55 +28,44 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
-#include <asm/sn/ate_utils.h>
 
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
-
-extern pcibr_info_t     pcibr_info_get(devfs_handle_t);
-extern int              pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl);
+extern pcibr_info_t     pcibr_info_get(vertex_hdl_t);
+extern int              pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl);
 extern pcibr_info_t     pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-extern int		pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
+extern int		pcibr_slot_initial_rrb_alloc(vertex_hdl_t,pciio_slot_t);
 extern int		pcibr_pcix_rbars_calc(pcibr_soft_t);
 
-int pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
-int pcibr_slot_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
-int pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
+int pcibr_slot_info_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot);
+int pcibr_slot_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot);
+int pcibr_slot_addr_space_init(vertex_hdl_t pcibr_vhdl,  pciio_slot_t slot);
 int pcibr_slot_pcix_rbar_init(pcibr_soft_t pcibr_soft,  pciio_slot_t slot);
-int pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
-int pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
-int pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
+int pcibr_slot_device_init(vertex_hdl_t pcibr_vhdl,  pciio_slot_t slot);
+int pcibr_slot_guest_info_init(vertex_hdl_t pcibr_vhdl,  pciio_slot_t slot);
+int pcibr_slot_call_device_attach(vertex_hdl_t pcibr_vhdl,
 		 pciio_slot_t slot, int drv_flags);
-int pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
+int pcibr_slot_call_device_detach(vertex_hdl_t pcibr_vhdl,
 		 pciio_slot_t slot, int drv_flags);
-int pcibr_slot_detach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot,
+int pcibr_slot_detach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot,
                  int drv_flags, char *l1_msg, int *sub_errorp);
-int pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
 static int pcibr_probe_slot(bridge_t *, cfg_p, unsigned int *);
-void pcibr_device_info_free(devfs_handle_t, pciio_slot_t);
+void pcibr_device_info_free(vertex_hdl_t, pciio_slot_t);
 iopaddr_t pcibr_bus_addr_alloc(pcibr_soft_t, pciio_win_info_t, 
                                pciio_space_t, int, int, int);
 void pciibr_bus_addr_free(pcibr_soft_t, pciio_win_info_t);
 cfg_p pcibr_find_capability(cfg_p, unsigned);
-extern uint64_t  do_pcibr_config_get(int, cfg_p, unsigned, unsigned);
-void do_pcibr_config_set(int, cfg_p, unsigned, unsigned, uint64_t); 
+extern uint64_t  do_pcibr_config_get(cfg_p, unsigned, unsigned);
+void do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t); 
 
-int pcibr_slot_attach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot,
+int pcibr_slot_attach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot,
                 int drv_flags, char *l1_msg, int *sub_errorp);
 
 int pcibr_slot_info_return(pcibr_soft_t pcibr_soft, pciio_slot_t slot,
                  pcibr_slot_info_resp_t respp);
 
-extern devfs_handle_t baseio_pci_vhdl;
-int scsi_ctlr_nums_add(devfs_handle_t, devfs_handle_t);
+extern vertex_hdl_t baseio_pci_vhdl;
+int scsi_ctlr_nums_add(vertex_hdl_t, vertex_hdl_t);
 
 
 /* For now .... */
@@ -111,7 +100,7 @@
 #ifdef PIC_LATER
 
 int
-pcibr_slot_startup(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
+pcibr_slot_startup(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp)
 {
     pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     pciio_slot_t                   slot;
@@ -127,11 +116,6 @@
     /* req_slot is the 'external' slot number, convert for internal use */
     slot = PCIBR_SLOT_TO_DEVICE(pcibr_soft, reqp->req_slot);
 
-    /* Do not allow start-up of a slot in a shoehorn */
-    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
-       return(PCI_SLOT_IN_SHOEHORN);
-    }
- 
     /* Check for the valid slot */
     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
         return(PCI_NOT_A_SLOT);
@@ -170,7 +154,7 @@
  *	Software shut-down the PCI slot
  */
 int
-pcibr_slot_shutdown(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
+pcibr_slot_shutdown(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp)
 {
     pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     bridge_t                      *bridge;
@@ -194,11 +178,6 @@
     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
         return(PCI_NOT_A_SLOT);
 
-    /* Do not allow shut-down of a slot in a shoehorn */
-    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
-       return(PCI_SLOT_IN_SHOEHORN);
-    }
-
 #ifdef PIC_LATER
     /* Acquire update access to the bus */
     mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);
@@ -284,7 +263,6 @@
 {
     pcibr_info_t                 pcibr_info = pcibr_infoh[func];
     int                          win;
-    boolean_t is_sys_critical_vertex(devfs_handle_t);
 
     funcp->resp_f_status = 0;
 
@@ -296,9 +274,6 @@
 #if defined(SUPPORT_PRINTING_V_FORMAT)
     sprintf(funcp->resp_f_slot_name, "%v", pcibr_info->f_vertex);
 #endif
-    if(is_sys_critical_vertex(pcibr_info->f_vertex)) {
-        funcp->resp_f_status |= FUNC_IS_SYS_CRITICAL;
-    }
 
     funcp->resp_f_bus = pcibr_info->f_bus;
     funcp->resp_f_slot = PCIBR_INFO_SLOT_GET_EXT(pcibr_info);
@@ -345,7 +320,6 @@
     reg_p                        b_respp;
     pcibr_slot_info_resp_t       slotp;
     pcibr_slot_func_info_resp_t  funcp;
-    boolean_t is_sys_critical_vertex(devfs_handle_t);
     extern void snia_kmem_free(void *, int);
 
     slotp = snia_kmem_zalloc(sizeof(*slotp), 0);
@@ -368,11 +342,6 @@
     slotp->resp_slot_status = pss->slot_status;
 
     slotp->resp_l1_bus_num = pcibr_widget_to_bus(pcibr_soft->bs_vhdl);
-
-    if (is_sys_critical_vertex(pss->slot_conn)) {
-        slotp->resp_slot_status |= SLOT_IS_SYS_CRITICAL;
-    }
-
     slotp->resp_bss_ninfo = pss->bss_ninfo;
 
     for (func = 0; func < pss->bss_ninfo; func++) {
@@ -455,7 +424,7 @@
  *		External SSRAM workaround info
  */
 int
-pcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
+pcibr_slot_query(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp)
 {
     pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     pciio_slot_t            slot;
@@ -481,11 +450,6 @@
         return(PCI_NOT_A_SLOT);
     }
 
-    /* Do not allow a query of a slot in a shoehorn */
-    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
-       return(PCI_SLOT_IN_SHOEHORN);
-    }
-
     /* Return information for the requested PCI slot */
     if (slot != PCIIO_SLOT_NONE) {
         if (size < sizeof(*respp)) {
@@ -534,88 +498,6 @@
     return(error);
 }
 
-#if 0
-/*
- * pcibr_slot_reset
- *	Reset the PCI device in the particular slot.
- *
- *      The Xbridge does not comply with the PCI Specification
- *      when resetting an indiviaudl slot.  An individual slot is
- *      is reset by toggling the slot's bit in the Xbridge Control
- *      Register.  The Xbridge will assert the target slot's 
- *      (non-bussed) RST signal, but does not assert the (bussed) 
- *      REQ64 signal as required by the specification.   As
- *      designed, the Xbridge cannot assert the REQ64 signal
- *      becuase it may interfere with a bus transaction in progress.
- *      The practical effects of this Xbridge implementation is
- *      device dependent;  it probably will not adversely effect
- *      32-bit cards, but may disable 64-bit data transfers by those
- *      cards that normally support 64-bit data transfers.  
- *
- *      The Xbridge will assert REQ64 when all four slots are reset
- *      by simultaneously toggling all four slot reset bits in the
- *      Xbridge Control Register.  This is basically a PCI bus reset
- *      and asserting the (bussed) REQ64 signal will not interfere
- *      with any bus transactions in progress.
- *
- *      The Xbridge (and the SN0 Bridge) support resetting only
- *      four PCI bus slots via the (X)bridge Control Register.
- *
- *      To reset an individual slot for the PCI Hot-Plug feature
- *      use the L1 console commands to power-down and then 
- *      power-up the slot, or use the kernel infrastructure
- *      functions to power-down/up the slot when they are
- *      implemented for SN1.
- */
-int
-pcibr_slot_reset(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
-{
-	pcibr_soft_t		 pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-	bridge_t		*bridge;
-	bridgereg_t		 ctrlreg,tmp;
-	volatile bridgereg_t	*wrb_flush;
-
-	if (!pcibr_soft)
-		return(EINVAL);
-
-	if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
-		return(EINVAL);
-
-	/* Enable the DMA operations from this device of the xtalk widget
-	 * (PCI host bridge in this case).
-	 */
-	xtalk_widgetdev_enable(pcibr_soft->bs_conn, slot);
-
-	/* Set the reset slot bit in the bridge's wid control register
-	 * to reset the PCI slot 
-	 */
-	bridge = pcibr_soft->bs_base;
-
-	/* Read the bridge widget control and clear out the reset pin
-	 * bit for the corresponding slot. 
-	 */
-	tmp = ctrlreg = bridge->b_wid_control;
-
-	tmp &= ~BRIDGE_CTRL_RST_PIN(slot); 
-
-	bridge->b_wid_control = tmp;
-	tmp = bridge->b_wid_control;
-
-	/* Restore the old control register back.
-	 * NOTE : PCI card gets reset when the reset pin bit
-	 * changes from 0 (set above) to 1 (going to be set now).
-	 */
-
-	bridge->b_wid_control = ctrlreg;
-
-	/* Flush the write buffers if any !! */
-	wrb_flush = &(bridge->b_wr_req_buf[slot].reg);
-	while (*wrb_flush);
-
-	return(0);
-}
-#endif
-
 #define PROBE_LOCK 0	/* FIXME: we're attempting to lock around accesses
 			 * to b_int_enable.   This hangs pcibr_probe_slot()
 			 */
@@ -627,7 +509,7 @@
  * 	information associated with this particular PCI device.
  */
 int
-pcibr_slot_info_init(devfs_handle_t 	pcibr_vhdl,
+pcibr_slot_info_init(vertex_hdl_t 	pcibr_vhdl,
 		     pciio_slot_t 	slot)
 {
     pcibr_soft_t	    pcibr_soft;
@@ -650,7 +532,7 @@
     int			    nfunc;
     pciio_function_t	    rfunc;
     int			    func;
-    devfs_handle_t	    conn_vhdl;
+    vertex_hdl_t	    conn_vhdl;
     pcibr_soft_slot_t	    slotp;
     
     /* Get the basic software information required to proceed */
@@ -669,10 +551,6 @@
 	return(0);    
     }
 
-    /* Check for a slot with any system critical functions */
-    if (pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(EPERM);
-
     /* Try to read the device-id/vendor-id from the config space */
     cfgw = pcibr_slot_config_addr(bridge, slot, 0);
 
@@ -701,7 +579,7 @@
     if (vendor == 0xFFFF) 
 	return(ENODEV);			
     
-    htype = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1);
+    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
     nfunc = 1;
     rfunc = PCIIO_FUNC_NONE;
     pfail = 0;
@@ -750,7 +628,7 @@
 	    cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0);
 	    
 	    device = 0xFFFF & (idword >> 16);
-	    htype = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1);
+	    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
 	    rfunc = func;
 	}
 	htype &= 0x7f;
@@ -803,23 +681,17 @@
 	 * 'min_gnt' and attempt to calculate a latency time. 
 	 *
 	 * NOTE: For now if the device is on the 'real time' arbitration
-	 * ring we dont set the latency timer.  
+	 * ring we don't set the latency timer.  
 	 *
 	 * WAR: SGI's IOC3 and RAD devices target abort if you write a 
 	 * single byte into their config space.  So don't set the Latency
 	 * Timer for these devices
 	 */
 
-	lt_time = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_LATENCY_TIMER, 1);
+	lt_time = do_pcibr_config_get(cfgw, PCI_CFG_LATENCY_TIMER, 1);
 
 	if ((lt_time == 0) && !(bridge->b_device[slot].reg & BRIDGE_DEV_RT) &&
-	    !((vendor == IOC3_VENDOR_ID_NUM) && 
-	      (
-#ifdef PIC_LATER
-	       (device == IOC3_DEVICE_ID_NUM) ||
-	       (device == LINC_DEVICE_ID_NUM) ||
-#endif
-	       (device == 0x5 /* RAD_DEV */)))) {
+				       (device == 0x5 /* RAD_DEV */)) {
 	     unsigned	min_gnt;
 	     unsigned	min_gnt_mult;
 	    
@@ -827,7 +699,7 @@
 	     * needs in increments of 250ns.  But latency timer is in
 	     * PCI clock cycles, so a conversion is needed.
 	     */
-	    min_gnt = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_MIN_GNT, 1);
+	    min_gnt = do_pcibr_config_get(cfgw, PCI_MIN_GNT, 1);
 
 	    if (IS_133MHZ(pcibr_soft))
 		min_gnt_mult = 32;	/* 250ns @ 133MHz in clocks */
@@ -843,7 +715,7 @@
 	    else
 		lt_time = 4 * min_gnt_mult;	  /* 1 micro second */
 
-	    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_LATENCY_TIMER, 1, lt_time);
+	    do_pcibr_config_set(cfgw, PCI_CFG_LATENCY_TIMER, 1, lt_time);
 
 	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl,
                     "pcibr_slot_info_init: set Latency Timer for slot=%d, "
@@ -851,12 +723,27 @@
 		    PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func, lt_time));
 	}
 
-	/* Get the PCI-X capability if running in PCI-X mode.  If the func
-	 * doesnt have a pcix capability, allocate a PCIIO_VENDOR_ID_NONE
-	 * pcibr_info struct so the device driver for that function is not
-	 * called.
+
+	/* In our architecture the setting of the cacheline size isn't 
+	 * beneficial for cards in PCI mode, but in PCI-X mode devices
+	 * can optionally use the cacheline size value for internal 
+	 * device optimizations    (See 7.1.5 of the PCI-X v1.0 spec).
+	 * NOTE: cachline size is in doubleword increments
 	 */
 	if (IS_PCIX(pcibr_soft)) {
+	    if (!do_pcibr_config_get(cfgw, PCI_CFG_CACHE_LINE, 1)) {
+		do_pcibr_config_set(cfgw, PCI_CFG_CACHE_LINE, 1, 0x20);
+		PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl,
+			"pcibr_slot_info_init: set CacheLine for slot=%d, "
+			"func=%d, to 0x20\n",
+			PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func));
+	    }
+
+	    /* Get the PCI-X capability if running in PCI-X mode.  If the func
+	     * doesnt have a pcix capability, allocate a PCIIO_VENDOR_ID_NONE
+	     * pcibr_info struct so the device driver for that function is not
+	     * called.
+	     */
 	    if (!(pcix_cap = pcibr_find_capability(cfgw, PCI_CAP_PCIX))) {
 		printk(KERN_WARNING
 #if defined(SUPPORT_PRINTING_V_FORMAT)
@@ -898,7 +785,7 @@
 	if (func == 0)
 	    slotp->slot_conn = conn_vhdl;
 
-	cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4);
+	cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4);
 	
 	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
 
@@ -949,7 +836,7 @@
 	     * this could be pushed up into pciio, when we
 	     * start supporting more PCI providers.
 	     */
-	    base = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4);
+	    base = do_pcibr_config_get(wptr, (win * 4), 4);
 
 	    if (base & PCI_BA_IO_SPACE) {
 		/* BASE is in I/O space. */
@@ -975,7 +862,7 @@
 		} else if (base & 0xC0000000) {
 		    base = 0;	/* outside permissable range */
 		} else if ((code == PCI_BA_MEM_64BIT) &&
-			   (do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, ((win + 1)*4), 4) != 0)) {
+			   (do_pcibr_config_get(wptr, ((win + 1)*4), 4) != 0)) {
 		    base = 0;	/* outside permissable range */
 		}
 	    }
@@ -983,8 +870,8 @@
 	    if (base != 0) {	/* estimate size */
 		size = base & -base;
 	    } else {		/* calculate size */
-		do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, ~0);    /* write 1's */
-		size = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4); /* read back */
+		do_pcibr_config_set(wptr, (win * 4), 4, ~0);    /* write 1's */
+		size = do_pcibr_config_get(wptr, (win * 4), 4); /* read back */
 		size &= mask;	/* keep addr */
 		size &= -size;	/* keep lsbit */
 		if (size == 0)
@@ -995,45 +882,9 @@
 	    pcibr_info->f_window[win].w_base = base;
 	    pcibr_info->f_window[win].w_size = size;
 
-#if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM)
-	    /*
-	     * IOC3 BASE_ADDR* BUG WORKAROUND
-	     *
-	     
-	     * If we write to BASE1 on the IOC3, the
-	     * data in BASE0 is replaced. The
-	     * original workaround was to remember
-	     * the value of BASE0 and restore it
-	     * when we ran off the end of the BASE
-	     * registers; however, a later
-	     * workaround was added (I think it was
-	     * rev 1.44) to avoid setting up
-	     * anything but BASE0, with the comment
-	     * that writing all ones to BASE1 set
-	     * the enable-parity-error test feature
-	     * in IOC3's SCR bit 14.
-	     *
-	     * So, unless we defer doing any PCI
-	     * space allocation until drivers
-	     * attach, and set up a way for drivers
-	     * (the IOC3 in paricular) to tell us
-	     * generically to keep our hands off
-	     * BASE registers, we gotta "know" about
-	     * the IOC3 here.
-	     *
-	     * Too bad the PCI folks didn't reserve the
-	     * all-zero value for 'no BASE here' (it is a
-	     * valid code for an uninitialized BASE in
-	     * 32-bit PCI memory space).
-	     */
-	    
-	    if ((vendor == IOC3_VENDOR_ID_NUM) &&
-		(device == IOC3_DEVICE_ID_NUM))
-		break;
-#endif
 	    if (code == PCI_BA_MEM_64BIT) {
 		win++;		/* skip upper half */
-		do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, 0);  /* must be zero */
+		do_pcibr_config_set(wptr, (win * 4), 4, 0);  /* must be zero */
 	    }
 	}				/* next win */
     }				/* next func */
@@ -1056,7 +907,7 @@
     int			defend_against_circular_linkedlist = 0;
 
     /* Check to see if there is a capabilities pointer in the cfg header */
-    if (!(do_pcibr_config_get(1, cfgw, PCI_CFG_STATUS, 2) & PCI_STAT_CAP_LIST)) {
+    if (!(do_pcibr_config_get(cfgw, PCI_CFG_STATUS, 2) & PCI_STAT_CAP_LIST)) {
 	return (NULL);
     }
 
@@ -1067,14 +918,14 @@
      * significant bits of the next pointer must be ignored,  so we mask
      * with 0xfc).
      */
-    cap_nxt = (do_pcibr_config_get(1, cfgw, PCI_CAPABILITIES_PTR, 1) & 0xfc);
+    cap_nxt = (do_pcibr_config_get(cfgw, PCI_CAPABILITIES_PTR, 1) & 0xfc);
 
     while (cap_nxt && (defend_against_circular_linkedlist <= 48)) {
-	cap_id = do_pcibr_config_get(1, cfgw, cap_nxt, 1);
+	cap_id = do_pcibr_config_get(cfgw, cap_nxt, 1);
 	if (cap_id == capability) {
 	    return ((cfg_p)((char *)cfgw + cap_nxt));
 	}
-	cap_nxt = (do_pcibr_config_get(1, cfgw, cap_nxt+1, 1) & 0xfc);
+	cap_nxt = (do_pcibr_config_get(cfgw, cap_nxt+1, 1) & 0xfc);
 	defend_against_circular_linkedlist++;
     }
 
@@ -1087,7 +938,7 @@
  * 	with a particular PCI device.
  */
 int
-pcibr_slot_info_free(devfs_handle_t pcibr_vhdl,
+pcibr_slot_info_free(vertex_hdl_t pcibr_vhdl,
                      pciio_slot_t slot)
 {
     pcibr_soft_t	pcibr_soft;
@@ -1223,20 +1074,21 @@
  * 	the base registers in the card.
  */
 int
-pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,
+pcibr_slot_addr_space_init(vertex_hdl_t pcibr_vhdl,
 			   pciio_slot_t	slot)
 {
     pcibr_soft_t	 pcibr_soft;
     pcibr_info_h	 pcibr_infoh;
     pcibr_info_t	 pcibr_info;
     bridge_t		*bridge;
-    size_t               align_slot;
     iopaddr_t            mask;
     int		       	 nbars;
     int		       	 nfunc;
     int			 func;
     int			 win;
     int                  rc = 0;
+    int			 align;
+    int			 align_slot;
 
     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
 
@@ -1275,7 +1127,8 @@
      * the entire "lo" area is only a
      * megabyte, total ...
      */
-    align_slot = (slot < 2) ? 0x200000 : 0x100000;
+    align_slot = 0x100000;
+    align = align_slot;
 
     for (func = 0; func < nfunc; ++func) {
 	cfg_p                   cfgw;
@@ -1300,7 +1153,7 @@
         cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0);
 	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
 
-	if ((do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1) & 0x7f) != 0)
+	if ((do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1) & 0x7f) != 0)
 	    nbars = 2;
 	else
 	    nbars = PCI_CFG_BASE_ADDRS;
@@ -1333,23 +1186,24 @@
 		continue;		/* already allocated */
 	    }
 
+	    align = (win) ? size : align_slot; 
+
+	    if (align < _PAGESZ)
+		align = _PAGESZ;        /* ie. 0x00004000 */
+ 
 	    switch (space) {
 	    case PCIIO_SPACE_IO:
                 base = pcibr_bus_addr_alloc(pcibr_soft,
                                             &pcibr_info->f_window[win],
                                             PCIIO_SPACE_IO,
-                                            0, size, align_slot);
+                                            0, size, align);
                 if (!base)
                     rc = ENOSPC;
 		break;
 		
 	    case PCIIO_SPACE_MEM:
-		if ((do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4) &
+		if ((do_pcibr_config_get(wptr, (win * 4), 4) &
 		     PCI_BA_MEM_LOCATION) == PCI_BA_MEM_1MEG) {
-                    int align = size;           /* ie. 0x00001000 */
-                    
-                    if (align < _PAGESZ)
-                        align = _PAGESZ;        /* ie. 0x00004000 */
  
 		    /* allocate from 20-bit PCI space */
                     base = pcibr_bus_addr_alloc(pcibr_soft,
@@ -1363,7 +1217,7 @@
                     base = pcibr_bus_addr_alloc(pcibr_soft,
                                                 &pcibr_info->f_window[win],
                                                 PCIIO_SPACE_MEM32,
-                                                0, size, align_slot);
+                                                0, size, align);
 		    if (!base) 
 			rc = ENOSPC;
 		}
@@ -1377,7 +1231,7 @@
 			    PCIBR_DEVICE_TO_SLOT(pcibr_soft,slot), win, space));
 	    }
 	    pcibr_info->f_window[win].w_base = base;
-	    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, base);
+	    do_pcibr_config_set(wptr, (win * 4), 4, base);
 
 #if defined(SUPPORT_PRINTING_R_FORMAT)
 	    if (pcibr_debug_mask & PCIBR_DEBUG_BAR) {
@@ -1405,26 +1259,22 @@
 
 	/*
 	 * Allocate space for the EXPANSION ROM
-	 * NOTE: DO NOT DO THIS ON AN IOC3,
-	 * as it blows the system away.
 	 */
 	base = size = 0;
-	if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) ||
-	    (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) {
-
+	{
 	    wptr = cfgw + PCI_EXPANSION_ROM / 4;
-	    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4, 0xFFFFF000);
-	    mask = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4);
+	    do_pcibr_config_set(wptr, 0, 4, 0xFFFFF000);
+	    mask = do_pcibr_config_get(wptr, 0, 4);
 	    if (mask & 0xFFFFF000) {
 		size = mask & -mask;
                 base = pcibr_bus_addr_alloc(pcibr_soft,
                                             &pcibr_info->f_rwindow,
                                             PCIIO_SPACE_MEM32, 
-                                            0, size, align_slot);
+                                            0, size, align);
 		if (!base)
 		    rc = ENOSPC;
 		else {
-		    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4, base);
+		    do_pcibr_config_set(wptr, 0, 4, base);
 		    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_BAR, pcibr_vhdl,
 				"pcibr_slot_addr_space_init: slot=%d, func=%d, "
 				"ROM in [0x%X..0x%X], allocated by pcibr\n",
@@ -1435,7 +1285,7 @@
 	}
 	pcibr_info->f_rbase = base;
 	pcibr_info->f_rsize = size;
-	
+
 	/*
 	 * if necessary, update the board's
 	 * command register to enable decoding
@@ -1449,7 +1299,7 @@
 	/*
 	 * The Adaptec 1160 FC Controller WAR #767995:
 	 * The part incorrectly ignores the upper 32 bits of a 64 bit
-	 * address when decoding references to it's registers so to
+	 * address when decoding references to its registers so to
 	 * keep it from responding to a bus cycle that it shouldn't
 	 * we only use I/O space to get at it's registers.  Don't
 	 * enable memory space accesses on that PCI device.
@@ -1463,7 +1313,7 @@
 
 	pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER;
 
-	pci_cfg_cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4);
+	pci_cfg_cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4);
 
 #if PCI_FBBE	/* XXX- check here to see if dev can do fast-back-to-back */
 	if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP))
@@ -1471,7 +1321,7 @@
 #endif
 	pci_cfg_cmd_reg &= 0xFFFF;
 	if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg)
-	    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4, 
+	    do_pcibr_config_set(cfgw, PCI_CFG_COMMAND, 4, 
 				pci_cfg_cmd_reg | pci_cfg_cmd_reg_add);
     }				/* next func */
     return(rc);
@@ -1483,7 +1333,7 @@
  */
 
 int
-pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,
+pcibr_slot_device_init(vertex_hdl_t pcibr_vhdl,
 		       pciio_slot_t slot)
 {
     pcibr_soft_t	 pcibr_soft;
@@ -1525,8 +1375,6 @@
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DEVREG, pcibr_vhdl,
 		"pcibr_slot_device_init: Device(%d): %R\n",
 		slot, devreg, device_bits));
-#else
-    printk("pcibr_slot_device_init: Device(%d) 0x%x\n", slot, devreg);
 #endif
     return(0);
 }
@@ -1536,7 +1384,7 @@
  *	Setup the host/guest relations for a PCI slot.
  */
 int
-pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,
+pcibr_slot_guest_info_init(vertex_hdl_t pcibr_vhdl,
 			   pciio_slot_t	slot)
 {
     pcibr_soft_t	pcibr_soft;
@@ -1605,18 +1453,17 @@
  * 	card in this slot.
  */
 int
-pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
+pcibr_slot_call_device_attach(vertex_hdl_t pcibr_vhdl,
 			      pciio_slot_t slot,
 			      int          drv_flags)
 {
     pcibr_soft_t	pcibr_soft;
     pcibr_info_h	pcibr_infoh;
     pcibr_info_t	pcibr_info;
-    async_attach_t	aa = NULL;
     int			func;
-    devfs_handle_t	xconn_vhdl, conn_vhdl;
+    vertex_hdl_t	xconn_vhdl, conn_vhdl;
 #ifdef PIC_LATER
-    devfs_handle_t	scsi_vhdl;
+    vertex_hdl_t	scsi_vhdl;
 #endif
     int			nfunc;
     int                 error_func;
@@ -1639,7 +1486,6 @@
     }
     
     xconn_vhdl = pcibr_soft->bs_conn;
-    aa = async_attach_get_info(xconn_vhdl);
 
     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
@@ -1656,13 +1502,6 @@
 
 	conn_vhdl = pcibr_info->f_vertex;
 
-#ifdef LATER
-	/*
-	 * Activate if and when we support cdl.
-	 */
-	if (aa)
-	    async_attach_add_info(conn_vhdl, aa);
-#endif	/* LATER */
 
 	error_func = pciio_device_attach(conn_vhdl, drv_flags);
 
@@ -1728,7 +1567,7 @@
  * 	card in this slot.
  */
 int
-pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
+pcibr_slot_call_device_detach(vertex_hdl_t pcibr_vhdl,
 			      pciio_slot_t slot,
 			      int          drv_flags)
 {
@@ -1736,7 +1575,7 @@
     pcibr_info_h	pcibr_infoh;
     pcibr_info_t	pcibr_info;
     int			func;
-    devfs_handle_t	conn_vhdl = GRAPH_VERTEX_NONE;
+    vertex_hdl_t	conn_vhdl = GRAPH_VERTEX_NONE;
     int			nfunc;
     int                 error_func;
     int                 error_slot = 0;
@@ -1811,7 +1650,7 @@
  * 	PCI card on the bus.
  */
 int
-pcibr_slot_attach(devfs_handle_t pcibr_vhdl,
+pcibr_slot_attach(vertex_hdl_t pcibr_vhdl,
 		  pciio_slot_t slot,
 		  int          drv_flags,
 		  char        *l1_msg,
@@ -1850,7 +1689,7 @@
  *	slot-specific freeing that needs to be done.
  */
 int
-pcibr_slot_detach(devfs_handle_t pcibr_vhdl,
+pcibr_slot_detach(vertex_hdl_t pcibr_vhdl,
 		  pciio_slot_t slot,
 		  int          drv_flags,
 		  char        *l1_msg,
@@ -1859,10 +1698,6 @@
     pcibr_soft_t  pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     int		  error;
     
-    /* Make sure that we do not detach a system critical function vertex */
-    if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(PCI_IS_SYS_CRITICAL);
-
     /* Call the device detach function */
     error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags));
     if (error) {
@@ -1892,61 +1727,6 @@
 }
 
 /*
- * pcibr_is_slot_sys_critical
- *      Check slot for any functions that are system critical.
- *      Return 1 if any are system critical or 0 otherwise.
- *
- *      This function will always return 0 when called by 
- *      pcibr_attach() because the system critical vertices 
- *      have not yet been set in the hwgraph.
- */
-int
-pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl,
-                      pciio_slot_t slot)
-{
-    pcibr_soft_t        pcibr_soft;
-    pcibr_info_h        pcibr_infoh;
-    pcibr_info_t        pcibr_info;
-    devfs_handle_t        conn_vhdl = GRAPH_VERTEX_NONE;
-    int                 nfunc;
-    int                 func;
-    boolean_t is_sys_critical_vertex(devfs_handle_t);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (!pcibr_soft)
-	return(EINVAL);
-
-    if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
-	return(EINVAL);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-        pcibr_info = pcibr_infoh[func];
-        if (!pcibr_info)
-            continue;
-
-        if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-            continue;
-
-        conn_vhdl = pcibr_info->f_vertex;
-        if (is_sys_critical_vertex(conn_vhdl)) { 
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-            printk(KERN_WARNING  "%v is a system critical device vertex\n", conn_vhdl);
-#else
-            printk(KERN_WARNING  "%p is a system critical device vertex\n", (void *)conn_vhdl);
-#endif
-            return(1); 
-        }
-
-    }
-
-    return(0);
-}
-
-/*
  * pcibr_probe_slot_pic: read a config space word
  * while trapping any errors; return zero if
  * all went OK, or nonzero if there was an error.
@@ -1984,57 +1764,6 @@
 }
 
 /*
- * pcibr_probe_slot_non_pic: read a config space word
- * while trapping any errors; return zero if
- * all went OK, or nonzero if there was an error.
- * The value read, if any, is passed back
- * through the valp parameter.
- */
-static int
-pcibr_probe_slot_non_pic(bridge_t *bridge,
-                 cfg_p cfg,
-                 unsigned *valp)
-{
-	int                     rv;
-	bridgereg_t             b_old_enable = (bridgereg_t)0, b_new_enable = (bridgereg_t)0;
-	extern int              badaddr_val(volatile void *, int, volatile void *);
-
-        b_old_enable = bridge->b_int_enable;
-        b_new_enable = b_old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-        bridge->b_int_enable = b_new_enable;
-
-	/*
-	 * The xbridge doesn't clear b_err_int_view unless
-	 * multi-err is cleared...
-	 */
-	if (is_xbridge(bridge)) {
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT)
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-	}
-
-        if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) {
-	    bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR;
-	    (void) bridge->b_wid_tflush;	/* flushbus */
-        }
-	rv = badaddr_val((void *) (((uint64_t)cfg) ^ 4), 4, valp);
-	/*
-	 * The xbridge doesn't set master timeout in b_int_status
-	 * here.  Fortunately it's in error_interrupt_view.
-	 */
-	if (is_xbridge(bridge)) {
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-		rv = 1;		/* unoccupied slot */
-	    }
-	}
-        bridge->b_int_enable = b_old_enable;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    	return(rv);
-}
-
-
-/*
  * pcibr_probe_slot: read a config space word
  * while trapping any errors; return zero if
  * all went OK, or nonzero if there was an error.
@@ -2046,15 +1775,12 @@
 		 cfg_p cfg,
 		 unsigned *valp)
 {
-    if ( is_pic(bridge) )
-	return(pcibr_probe_slot_pic(bridge, cfg, valp));
-    else
-	return(pcibr_probe_slot_non_pic(bridge, cfg, valp));
+    return(pcibr_probe_slot_pic(bridge, cfg, valp));
 }
 
 
 void
-pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
+pcibr_device_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot)
 {
     pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     pcibr_info_t	pcibr_info;
@@ -2079,9 +1805,9 @@
 
         /* Disable memory and I/O BARs */
 	cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0);
-	cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4);
+	cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4);
 	cmd_reg &= (PCI_CMD_MEM_SPACE | PCI_CMD_IO_SPACE);
-	do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4, cmd_reg);
+	do_pcibr_config_set(cfgw, PCI_CFG_COMMAND, 4, cmd_reg);
 
         for (bar = 0; bar < PCI_CFG_BASE_ADDRS; bar++) {
             if (pcibr_info->f_window[bar].w_space == PCIIO_SPACE_NONE)
@@ -2142,30 +1868,36 @@
                      pciio_space_t space, int start, int size, int align)
 {
     pciio_win_map_t win_map_p;
+    struct resource *root_resource = NULL;
+    iopaddr_t iopaddr = 0;
 
     switch (space) {
 
         case PCIIO_SPACE_IO:
             win_map_p = &pcibr_soft->bs_io_win_map;
+	    root_resource = &pcibr_soft->bs_io_win_root_resource;
             break;
 
         case PCIIO_SPACE_MEM:
             win_map_p = &pcibr_soft->bs_swin_map;
+	    root_resource = &pcibr_soft->bs_swin_root_resource;
             break;
 
         case PCIIO_SPACE_MEM32:
             win_map_p = &pcibr_soft->bs_mem_win_map;
+	    root_resource = &pcibr_soft->bs_mem_win_root_resource;
             break;
 
         default:
             return 0;
 
     }
-    return pciio_device_win_alloc(win_map_p,
+    iopaddr = pciio_device_win_alloc(root_resource,
 				  win_info_p
 				  ? &win_info_p->w_win_alloc
 				  : NULL,
 				  start, size, align);
+    return(iopaddr);
 }
 
 
@@ -2181,7 +1913,7 @@
  * io_brick_tab[] array defined in ml/SN/iograph.c
  */
 int
-pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl) 
+pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl) 
 {
     pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     xwidgetnum_t	widget = pcibr_soft->bs_xid;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/pciio.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pciio.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/pciio.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pciio.c	2003-08-01 13:32:45.000000000 +0000
@@ -4,11 +4,9 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
-#define	USRPCI	0
-
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/pci.h>
@@ -30,27 +28,14 @@
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/io.h>
 #include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/ate_utils.h>
 #include <asm/sn/simulator.h>
 
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
 #define DEBUG_PCIIO
 #undef DEBUG_PCIIO	/* turn this on for yet more console output */
 
 
-#define GET_NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DO_DEL(ptr)	(kfree(ptr))
-
 char                    pciio_info_fingerprint[] = "pciio_info";
 
-cdl_p                   pciio_registry = NULL;
-
 int
 badaddr_val(volatile void *addr, int len, volatile void *ptr)
 {
@@ -97,8 +82,6 @@
 	extern char master_baseio_wid;
 
 	if (master_baseio_nasid < 0) {
-		nasid_t tmp;
-
 		master_baseio_nasid = ia64_sn_get_master_baseio_nasid();
 
 		if ( master_baseio_nasid >= 0 ) {
@@ -109,13 +92,13 @@
 }
 
 int
-hub_dma_enabled(devfs_handle_t xconn_vhdl)
+hub_dma_enabled(vertex_hdl_t xconn_vhdl)
 {
 	return(0);
 }
 
 int
-hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
+hub_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code)
 {
 	return(0);
 }
@@ -153,66 +136,64 @@
  */
 
 #if !defined(DEV_FUNC)
-static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev);
+static pciio_provider_t *pciio_to_provider_fns(vertex_hdl_t dev);
 #endif
 
-pciio_piomap_t          pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
+pciio_piomap_t          pciio_piomap_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
 void                    pciio_piomap_free(pciio_piomap_t);
 caddr_t                 pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t);
 
 void                    pciio_piomap_done(pciio_piomap_t);
-caddr_t                 pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-caddr_t			pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned);
+caddr_t                 pciio_piotrans_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
+caddr_t			pciio_pio_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned);
 
-iopaddr_t               pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
+iopaddr_t               pciio_piospace_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, size_t, size_t);
+void                    pciio_piospace_free(vertex_hdl_t, pciio_space_t, iopaddr_t, size_t);
 
-pciio_dmamap_t          pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
+pciio_dmamap_t          pciio_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned);
 void                    pciio_dmamap_free(pciio_dmamap_t);
 iopaddr_t               pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
-alenlist_t              pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned);
 void                    pciio_dmamap_done(pciio_dmamap_t);
-iopaddr_t               pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
+iopaddr_t               pciio_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned);
 void			pciio_dmamap_drain(pciio_dmamap_t);
-void			pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void			pciio_dmalist_drain(devfs_handle_t, alenlist_t);
-iopaddr_t               pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned);
+void			pciio_dmaaddr_drain(vertex_hdl_t, paddr_t, size_t);
+void			pciio_dmalist_drain(vertex_hdl_t, alenlist_t);
+iopaddr_t               pciio_dma_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned);
 
-pciio_intr_t            pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
+pciio_intr_t            pciio_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t);
 void                    pciio_intr_free(pciio_intr_t);
 int                     pciio_intr_connect(pciio_intr_t, intr_func_t, intr_arg_t);
 void                    pciio_intr_disconnect(pciio_intr_t);
-devfs_handle_t            pciio_intr_cpu_get(pciio_intr_t);
+vertex_hdl_t            pciio_intr_cpu_get(pciio_intr_t);
 
 void			pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t);
 
-void                    pciio_provider_startup(devfs_handle_t);
-void                    pciio_provider_shutdown(devfs_handle_t);
+void                    pciio_provider_startup(vertex_hdl_t);
+void                    pciio_provider_shutdown(vertex_hdl_t);
 
-pciio_endian_t          pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
-pciio_priority_t        pciio_priority_set(devfs_handle_t, pciio_priority_t);
-devfs_handle_t            pciio_intr_dev_get(pciio_intr_t);
+pciio_endian_t          pciio_endian_set(vertex_hdl_t, pciio_endian_t, pciio_endian_t);
+pciio_priority_t        pciio_priority_set(vertex_hdl_t, pciio_priority_t);
+vertex_hdl_t            pciio_intr_dev_get(pciio_intr_t);
 
-devfs_handle_t            pciio_pio_dev_get(pciio_piomap_t);
+vertex_hdl_t            pciio_pio_dev_get(pciio_piomap_t);
 pciio_slot_t            pciio_pio_slot_get(pciio_piomap_t);
 pciio_space_t           pciio_pio_space_get(pciio_piomap_t);
 iopaddr_t               pciio_pio_pciaddr_get(pciio_piomap_t);
 ulong                   pciio_pio_mapsz_get(pciio_piomap_t);
 caddr_t                 pciio_pio_kvaddr_get(pciio_piomap_t);
 
-devfs_handle_t            pciio_dma_dev_get(pciio_dmamap_t);
+vertex_hdl_t            pciio_dma_dev_get(pciio_dmamap_t);
 pciio_slot_t            pciio_dma_slot_get(pciio_dmamap_t);
 
-pciio_info_t            pciio_info_chk(devfs_handle_t);
-pciio_info_t            pciio_info_get(devfs_handle_t);
-void                    pciio_info_set(devfs_handle_t, pciio_info_t);
-devfs_handle_t            pciio_info_dev_get(pciio_info_t);
+pciio_info_t            pciio_info_chk(vertex_hdl_t);
+pciio_info_t            pciio_info_get(vertex_hdl_t);
+void                    pciio_info_set(vertex_hdl_t, pciio_info_t);
+vertex_hdl_t            pciio_info_dev_get(pciio_info_t);
 pciio_slot_t            pciio_info_slot_get(pciio_info_t);
 pciio_function_t        pciio_info_function_get(pciio_info_t);
 pciio_vendor_id_t       pciio_info_vendor_id_get(pciio_info_t);
 pciio_device_id_t       pciio_info_device_id_get(pciio_info_t);
-devfs_handle_t            pciio_info_master_get(pciio_info_t);
+vertex_hdl_t            pciio_info_master_get(pciio_info_t);
 arbitrary_info_t        pciio_info_mfast_get(pciio_info_t);
 pciio_provider_t       *pciio_info_pops_get(pciio_info_t);
 error_handler_f	       *pciio_info_efunc_get(pciio_info_t);
@@ -223,30 +204,28 @@
 iopaddr_t		pciio_info_rom_base_get(pciio_info_t);
 size_t			pciio_info_rom_size_get(pciio_info_t);
 
-void                    pciio_init(void);
-int                     pciio_attach(devfs_handle_t);
+int                     pciio_attach(vertex_hdl_t);
 
-void                    pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns);
-void                    pciio_provider_unregister(devfs_handle_t);
-pciio_provider_t       *pciio_provider_fns_get(devfs_handle_t);
+void                    pciio_provider_register(vertex_hdl_t, pciio_provider_t *pciio_fns);
+void                    pciio_provider_unregister(vertex_hdl_t);
+pciio_provider_t       *pciio_provider_fns_get(vertex_hdl_t);
 
 int                     pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned);
-void                    pciio_driver_unregister(char *driver_prefix);
 
-devfs_handle_t            pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
+vertex_hdl_t            pciio_device_register(vertex_hdl_t, vertex_hdl_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
 
-void			pciio_device_unregister(devfs_handle_t);
-pciio_info_t		pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
+void			pciio_device_unregister(vertex_hdl_t);
+pciio_info_t		pciio_device_info_new(pciio_info_t, vertex_hdl_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
 void			pciio_device_info_free(pciio_info_t);
-devfs_handle_t		pciio_device_info_register(devfs_handle_t, pciio_info_t);
-void			pciio_device_info_unregister(devfs_handle_t, pciio_info_t);
-int                     pciio_device_attach(devfs_handle_t, int);
-int			pciio_device_detach(devfs_handle_t, int);
-void                    pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t);
-
-int                     pciio_reset(devfs_handle_t);
-int                     pciio_write_gather_flush(devfs_handle_t);
-int                     pciio_slot_inuse(devfs_handle_t);
+vertex_hdl_t		pciio_device_info_register(vertex_hdl_t, pciio_info_t);
+void			pciio_device_info_unregister(vertex_hdl_t, pciio_info_t);
+int                     pciio_device_attach(vertex_hdl_t, int);
+int			pciio_device_detach(vertex_hdl_t, int);
+void                    pciio_error_register(vertex_hdl_t, error_handler_f *, error_handler_arg_t);
+
+int                     pciio_reset(vertex_hdl_t);
+int                     pciio_write_gather_flush(vertex_hdl_t);
+int                     pciio_slot_inuse(vertex_hdl_t);
 
 /* =====================================================================
  *    Provider Function Location
@@ -261,7 +240,7 @@
 #if !defined(DEV_FUNC)
 
 static pciio_provider_t *
-pciio_to_provider_fns(devfs_handle_t dev)
+pciio_to_provider_fns(vertex_hdl_t dev)
 {
     pciio_info_t            card_info;
     pciio_provider_t       *provider_fns;
@@ -316,7 +295,7 @@
  */
 
 pciio_piomap_t
-pciio_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
+pciio_piomap_alloc(vertex_hdl_t dev,	/* set up mapping for this device */
 		   device_desc_t dev_desc,	/* device descriptor */
 		   pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
 		   iopaddr_t addr,	/* lowest address (or offset in window) */
@@ -354,7 +333,7 @@
 }
 
 caddr_t
-pciio_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
+pciio_piotrans_addr(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
 		    iopaddr_t addr,	/* starting address (or offset in window) */
@@ -366,7 +345,7 @@
 }
 
 caddr_t
-pciio_pio_addr(devfs_handle_t dev,	/* translate for this device */
+pciio_pio_addr(vertex_hdl_t dev,	/* translate for this device */
 	       device_desc_t dev_desc,	/* device descriptor */
 	       pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
 	       iopaddr_t addr,		/* starting address (or offset in window) */
@@ -410,7 +389,7 @@
 }
 
 iopaddr_t
-pciio_piospace_alloc(devfs_handle_t dev,	/* Device requiring space */
+pciio_piospace_alloc(vertex_hdl_t dev,	/* Device requiring space */
 		     device_desc_t dev_desc,	/* Device descriptor */
 		     pciio_space_t space,	/* MEM32/MEM64/IO */
 		     size_t byte_count,	/* Size of mapping */
@@ -423,7 +402,7 @@
 }
 
 void
-pciio_piospace_free(devfs_handle_t dev,	/* Device freeing space */
+pciio_piospace_free(vertex_hdl_t dev,	/* Device freeing space */
 		    pciio_space_t space,	/* Type of space        */
 		    iopaddr_t pciaddr,	/* starting address */
 		    size_t byte_count)
@@ -440,7 +419,7 @@
  */
 
 pciio_dmamap_t
-pciio_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
+pciio_dmamap_alloc(vertex_hdl_t dev,	/* set up mappings for this device */
 		   device_desc_t dev_desc,	/* device descriptor */
 		   size_t byte_count_max,	/* max size of a mapping */
 		   unsigned flags)
@@ -465,15 +444,6 @@
 	(CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
 }
 
-alenlist_t
-pciio_dmamap_list(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
-		  alenlist_t alenlist,	/* map this Address/Length List */
-		  unsigned flags)
-{
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_list)
-	(CAST_DMAMAP(pciio_dmamap), alenlist, flags);
-}
-
 void
 pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
 {
@@ -482,7 +452,7 @@
 }
 
 iopaddr_t
-pciio_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
+pciio_dmatrans_addr(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    paddr_t paddr,	/* system physical address */
 		    size_t byte_count,	/* length */
@@ -492,18 +462,8 @@
 	(dev, dev_desc, paddr, byte_count, flags);
 }
 
-alenlist_t
-pciio_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    alenlist_t palenlist,	/* system address/length list */
-		    unsigned flags)
-{					/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-	(dev, dev_desc, palenlist, flags);
-}
-
 iopaddr_t
-pciio_dma_addr(devfs_handle_t dev,	/* translate for this device */
+pciio_dma_addr(vertex_hdl_t dev,	/* translate for this device */
 	       device_desc_t dev_desc,	/* device descriptor */
 	       paddr_t paddr,		/* system physical address */
 	       size_t byte_count,	/* length */
@@ -553,14 +513,14 @@
 }
 
 void
-pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
+pciio_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size)
 {
     DEV_FUNC(dev, dmaaddr_drain)
 	(dev, addr, size);
 }
 
 void
-pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list)
+pciio_dmalist_drain(vertex_hdl_t dev, alenlist_t list)
 {
     DEV_FUNC(dev, dmalist_drain)
 	(dev, list);
@@ -577,10 +537,10 @@
  * Return resource handle in intr_hdl.
  */
 pciio_intr_t
-pciio_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
+pciio_intr_alloc(vertex_hdl_t dev,	/* which Crosstalk device */
 		 device_desc_t dev_desc,	/* device descriptor */
 		 pciio_intr_line_t lines,	/* INTR line(s) to attach */
-		 devfs_handle_t owner_dev)
+		 vertex_hdl_t owner_dev)
 {					/* owner of this interrupt */
     return (pciio_intr_t) DEV_FUNC(dev, intr_alloc)
 	(dev, dev_desc, lines, owner_dev);
@@ -624,7 +584,7 @@
  * Return a hwgraph vertex that represents the CPU currently
  * targeted by an interrupt.
  */
-devfs_handle_t
+vertex_hdl_t
 pciio_intr_cpu_get(pciio_intr_t intr_hdl)
 {
     return INTR_FUNC(intr_hdl, intr_cpu_get)
@@ -663,12 +623,12 @@
  */
 static pciio_info_t
 pciio_cardinfo_get(
-		      devfs_handle_t pciio_vhdl,
+		      vertex_hdl_t pciio_vhdl,
 		      pciio_slot_t pci_slot)
 {
     char                    namebuf[16];
     pciio_info_t	    info = 0;
-    devfs_handle_t	    conn;
+    vertex_hdl_t	    conn;
 
     pciio_slot_func_to_name(namebuf, pci_slot, PCIIO_FUNC_NONE);
     if (GRAPH_SUCCESS ==
@@ -699,22 +659,16 @@
 /*ARGSUSED */
 int
 pciio_error_handler(
-		       devfs_handle_t pciio_vhdl,
+		       vertex_hdl_t pciio_vhdl,
 		       int error_code,
 		       ioerror_mode_t mode,
 		       ioerror_t *ioerror)
 {
     pciio_info_t            pciio_info;
-    devfs_handle_t            pconn_vhdl;
-#if USRPCI
-    devfs_handle_t            usrpci_v;
-#endif
+    vertex_hdl_t            pconn_vhdl;
     pciio_slot_t            slot;
 
     int                     retval;
-#ifdef EHE_ENABLE
-    error_state_t	    e_state;
-#endif /* EHE_ENABLE */
 
 #if DEBUG && ERROR_DEBUG
     printk("%v: pciio_error_handler\n", pciio_vhdl);
@@ -733,16 +687,6 @@
     if (pciio_info && pciio_info->c_efunc) {
 	pconn_vhdl = pciio_info_dev_get(pciio_info);
 
-#ifdef EHE_ENABLE
-	e_state = error_state_get(pciio_vhdl);
-
-	if (e_state == ERROR_STATE_ACTION)
-	    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);
-
-	if (error_state_set(pconn_vhdl,e_state) == ERROR_RETURN_CODE_CANNOT_SET_STATE)
-	    return(IOERROR_UNHANDLED);
-#endif 
-
 	retval = pciio_info->c_efunc
 	    (pciio_info->c_einfo, error_code, mode, ioerror);
 	if (retval != IOERROR_UNHANDLED)
@@ -770,49 +714,11 @@
 
 		pconn_vhdl = pciio_info_dev_get(pciio_info);
 
-#ifdef EHE_ENABLE
-		e_state = error_state_get(pciio_vhdl);
-
-		if (e_state == ERROR_STATE_ACTION)
-		    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);
-
-		if (error_state_set(pconn_vhdl,e_state) ==
-		    ERROR_RETURN_CODE_CANNOT_SET_STATE)
-		    return(IOERROR_UNHANDLED);
-#endif /* EHE_ENABLE */
-
 		retval = pciio_info->c_efunc
 		    (pciio_info->c_einfo, error_code, mode, ioerror);
 		if (retval != IOERROR_UNHANDLED)
 		    return retval;
 	    }
-
-#if USRPCI
-	    /* If the USRPCI driver is available and
-	     * knows about this connection point,
-	     * deliver the error to it.
-	     *
-	     * OK to use pconn_vhdl here, even though we
-	     * have already UNREF'd it, since we know that
-	     * it is not going away.
-	     */
-	    pconn_vhdl = pciio_info_dev_get(pciio_info);
-	    if (GRAPH_SUCCESS == hwgraph_traverse(pconn_vhdl, EDGE_LBL_USRPCI, &usrpci_v)) {
-		iopaddr_t busaddr;
-		IOERROR_GETVALUE(busaddr, ioerror, busaddr);
-		retval = usrpci_error_handler (usrpci_v, error_code, busaddr);
-		hwgraph_vertex_unref(usrpci_v);
-		if (retval != IOERROR_UNHANDLED) {
-		    /*
-		     * This unref is not needed.  If this code is called often enough,
-		     * the system will crash, due to vertex reference count reaching 0,
-		     * causing vertex to be unallocated.  -jeremy
-		     * hwgraph_vertex_unref(pconn_vhdl);
-		     */
-		    return retval;
-		}
-	    }
-#endif
 	}
     }
 
@@ -829,7 +735,7 @@
  * Startup a crosstalk provider
  */
 void
-pciio_provider_startup(devfs_handle_t pciio_provider)
+pciio_provider_startup(vertex_hdl_t pciio_provider)
 {
     DEV_FUNC(pciio_provider, provider_startup)
 	(pciio_provider);
@@ -839,7 +745,7 @@
  * Shutdown a crosstalk provider
  */
 void
-pciio_provider_shutdown(devfs_handle_t pciio_provider)
+pciio_provider_shutdown(vertex_hdl_t pciio_provider)
 {
     DEV_FUNC(pciio_provider, provider_shutdown)
 	(pciio_provider);
@@ -851,7 +757,7 @@
  * how things will actually appear in memory.
  */
 pciio_endian_t
-pciio_endian_set(devfs_handle_t dev,
+pciio_endian_set(vertex_hdl_t dev,
 		 pciio_endian_t device_end,
 		 pciio_endian_t desired_end)
 {
@@ -880,7 +786,7 @@
  * Specify PCI arbitration priority.
  */
 pciio_priority_t
-pciio_priority_set(devfs_handle_t dev,
+pciio_priority_set(vertex_hdl_t dev,
 		   pciio_priority_t device_prio)
 {
     ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW));
@@ -893,7 +799,7 @@
  * Read value of configuration register
  */
 uint64_t
-pciio_config_get(devfs_handle_t	dev,
+pciio_config_get(vertex_hdl_t	dev,
 		 unsigned	reg,
 		 unsigned	size)
 {
@@ -923,7 +829,7 @@
  * Change value of configuration register
  */
 void
-pciio_config_set(devfs_handle_t	dev,
+pciio_config_set(vertex_hdl_t	dev,
 		 unsigned	reg,
 		 unsigned	size,
 		 uint64_t	value)
@@ -953,7 +859,7 @@
  * Issue a hardware reset to a card.
  */
 int
-pciio_reset(devfs_handle_t dev)
+pciio_reset(vertex_hdl_t dev)
 {
     return DEV_FUNC(dev, reset) (dev);
 }
@@ -962,19 +868,19 @@
  * flush write gather buffers
  */
 int
-pciio_write_gather_flush(devfs_handle_t dev)
+pciio_write_gather_flush(vertex_hdl_t dev)
 {
     return DEV_FUNC(dev, write_gather_flush) (dev);
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_intr_dev_get(pciio_intr_t pciio_intr)
 {
     return (pciio_intr->pi_dev);
 }
 
 /****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 pciio_pio_dev_get(pciio_piomap_t pciio_piomap)
 {
     return (pciio_piomap->pp_dev);
@@ -1011,7 +917,7 @@
 }
 
 /****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap)
 {
     return (pciio_dmamap->pd_dev);
@@ -1026,7 +932,7 @@
 /****** Generic pci slot information interfaces ******/
 
 pciio_info_t
-pciio_info_chk(devfs_handle_t pciio)
+pciio_info_chk(vertex_hdl_t pciio)
 {
     arbitrary_info_t        ainfo = 0;
 
@@ -1035,7 +941,7 @@
 }
 
 pciio_info_t
-pciio_info_get(devfs_handle_t pciio)
+pciio_info_get(vertex_hdl_t pciio)
 {
     pciio_info_t            pciio_info;
 
@@ -1051,18 +957,17 @@
 #endif /* DEBUG_PCIIO */
 
     if ((pciio_info != NULL) &&
-	(pciio_info->c_fingerprint != pciio_info_fingerprint)
-	&& (pciio_info->c_fingerprint != NULL)) {
+        (pciio_info->c_fingerprint != pciio_info_fingerprint)
+        && (pciio_info->c_fingerprint != NULL)) {
 
-	return((pciio_info_t)-1); /* Should panic .. */
+        return((pciio_info_t)-1); /* Should panic .. */
     }
-	
 
     return pciio_info;
 }
 
 void
-pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info)
+pciio_info_set(vertex_hdl_t pciio, pciio_info_t pciio_info)
 {
     if (pciio_info != NULL)
 	pciio_info->c_fingerprint = pciio_info_fingerprint;
@@ -1076,7 +981,7 @@
 			 (arbitrary_info_t) pciio_info);
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_info_dev_get(pciio_info_t pciio_info)
 {
     return (pciio_info->c_vertex);
@@ -1106,7 +1011,7 @@
     return (pciio_info->c_device);
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_info_master_get(pciio_info_t pciio_info)
 {
     return (pciio_info->c_master);
@@ -1172,47 +1077,12 @@
  */
 
 /*
- *    pciioinit: called once during device driver
- *      initializtion if this driver is configured into
- *      the system.
- */
-void
-pciio_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("pciio_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (pciio_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_PCI, "vendor", "device");
-	if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(pciio_registry != NULL);
-}
-
-/*
  *    pciioattach: called for each vertex in the graph
  *      that is a PCI provider.
  */
 /*ARGSUSED */
 int
-pciio_attach(devfs_handle_t pciio)
+pciio_attach(vertex_hdl_t pciio)
 {
 #if DEBUG && ATTACH_DEBUG
 #if defined(SUPPORT_PRINTING_V_FORMAT)
@@ -1228,7 +1098,7 @@
  * Associate a set of pciio_provider functions with a vertex.
  */
 void
-pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns)
+pciio_provider_register(vertex_hdl_t provider, pciio_provider_t *pciio_fns)
 {
     hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns);
 }
@@ -1237,7 +1107,7 @@
  * Disassociate a set of pciio_provider functions with a vertex.
  */
 void
-pciio_provider_unregister(devfs_handle_t provider)
+pciio_provider_unregister(vertex_hdl_t provider)
 {
     arbitrary_info_t        ainfo;
 
@@ -1249,7 +1119,7 @@
  * provider.
  */
 pciio_provider_t       *
-pciio_provider_fns_get(devfs_handle_t provider)
+pciio_provider_fns_get(vertex_hdl_t provider)
 {
     arbitrary_info_t        ainfo = 0;
 
@@ -1265,86 +1135,13 @@
 			 char *driver_prefix,
 			 unsigned flags)
 {
-    /* a driver's init routine might call
-     * pciio_driver_register before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    return cdl_add_driver(pciio_registry,
-			  vendor_id, device_id,
-			  driver_prefix, flags, NULL);
-}
-
-/*
- * Remove an initialization function.
- */
-void
-pciio_driver_unregister(
-			   char *driver_prefix)
-{
-    /* before a driver calls unregister,
-     * it must have called register; so
-     * we can assume we have a registry here.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    cdl_del_driver(pciio_registry, driver_prefix, NULL);
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being registered.
- */
-void
-pciio_driver_reg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being unregistered.
- */
-void
-pciio_driver_unreg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/*
- * Call some function with each vertex that
- * might be one of this driver's attach points.
- */
-void
-pciio_iterate(char *driver_prefix,
-	      pciio_iter_f * func)
-{
-    /* a driver's init routine might call
-     * pciio_iterate before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    ASSERT(pciio_registry != NULL);
-
-    cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func);
+	return(0);
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_device_register(
-		devfs_handle_t connectpt,	/* vertex for /hw/.../pciio/%d */
-		devfs_handle_t master,	/* card's master ASIC (PCI provider) */
+		vertex_hdl_t connectpt,	/* vertex for /hw/.../pciio/%d */
+		vertex_hdl_t master,	/* card's master ASIC (PCI provider) */
 		pciio_slot_t slot,	/* card's slot */
 		pciio_function_t func,	/* card's func */
 		pciio_vendor_id_t vendor_id,
@@ -1356,7 +1153,7 @@
 }
 
 void
-pciio_device_unregister(devfs_handle_t pconn)
+pciio_device_unregister(vertex_hdl_t pconn)
 {
     DEV_FUNC(pconn,device_unregister)(pconn);
 }
@@ -1364,14 +1161,14 @@
 pciio_info_t
 pciio_device_info_new(
 		pciio_info_t pciio_info,
-		devfs_handle_t master,
+		vertex_hdl_t master,
 		pciio_slot_t slot,
 		pciio_function_t func,
 		pciio_vendor_id_t vendor_id,
 		pciio_device_id_t device_id)
 {
     if (!pciio_info)
-	GET_NEW(pciio_info);
+	NEW(pciio_info);
     ASSERT(pciio_info != NULL);
 
     pciio_info->c_slot = slot;
@@ -1396,14 +1193,14 @@
     BZERO((char *)pciio_info,sizeof(pciio_info));
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_device_info_register(
-		devfs_handle_t connectpt,		/* vertex at center of bus */
+		vertex_hdl_t connectpt,		/* vertex at center of bus */
 		pciio_info_t pciio_info)	/* details about the connectpt */
 {
     char		name[32];
-    devfs_handle_t	pconn;
-    int device_master_set(devfs_handle_t, devfs_handle_t);
+    vertex_hdl_t	pconn;
+    int device_master_set(vertex_hdl_t, vertex_hdl_t);
 
     pciio_slot_func_to_name(name,
 			    pciio_info->c_slot,
@@ -1429,25 +1226,15 @@
      */
 
     device_master_set(pconn, pciio_info->c_master);
-
-#if USRPCI
-    /*
-     * Call into usrpci provider to let it initialize for
-     * the given slot.
-     */
-    if (pciio_info->c_slot != PCIIO_SLOT_NONE)
-	usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot);
-#endif
-
     return pconn;
 }
 
 void
-pciio_device_info_unregister(devfs_handle_t connectpt,
+pciio_device_info_unregister(vertex_hdl_t connectpt,
 			     pciio_info_t pciio_info)
 {
     char		name[32];
-    devfs_handle_t	pconn;
+    vertex_hdl_t	pconn;
 
     if (!pciio_info)
 	return;
@@ -1470,7 +1257,7 @@
 /* Add the pci card inventory information to the hwgraph
  */
 static void
-pciio_device_inventory_add(devfs_handle_t pconn_vhdl)
+pciio_device_inventory_add(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
 
@@ -1488,7 +1275,7 @@
 
 /*ARGSUSED */
 int
-pciio_device_attach(devfs_handle_t pconn,
+pciio_device_attach(vertex_hdl_t pconn,
 		    int          drv_flags)
 {
     pciio_info_t            pciio_info;
@@ -1507,92 +1294,18 @@
      * pciio_init) have been called; so we
      * can assume here that we have a registry.
      */
-    ASSERT(pciio_registry != NULL);
 
-    return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags));
+    return(cdl_add_connpt(vendor_id, device_id, pconn, drv_flags));
 }
 
 int
-pciio_device_detach(devfs_handle_t pconn,
+pciio_device_detach(vertex_hdl_t pconn,
 		    int          drv_flags)
 {
-    pciio_info_t            pciio_info;
-    pciio_vendor_id_t       vendor_id;
-    pciio_device_id_t       device_id;
-
-    pciio_info = pciio_info_get(pconn);
-
-    vendor_id = pciio_info->c_vendor;
-    device_id = pciio_info->c_device;
-
-    /* we don't start attaching things until
-     * all the driver init routines (including
-     * pciio_init) have been called; so we
-     * can assume here that we have a registry.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    return(cdl_del_connpt(pciio_registry, vendor_id, device_id,
-		          pconn, drv_flags));
-
-}
-
-/* SN2 */
-/*
- * Allocate (if necessary) and initialize a PCI window mapping structure.
- */
-pciio_win_map_t
-pciio_device_win_map_new(pciio_win_map_t win_map,
-			 size_t region_size,
-			 size_t page_size)
-{
-	ASSERT((page_size & (page_size - 1)) == 0);
-	ASSERT((region_size & (page_size - 1)) == 0);
-
-	if (win_map == NULL)
-		NEW(win_map);
-
-	/*
-	 * The map array tracks the free ``pages'' in the region.  The worst
-	 * case scenario is when every other page in the region is free --
-	 * e.i. maximum fragmentation.  This leads to (max pages + 1) / 2 + 1
-	 * map entries.  The first "+1" handles the divide by 2 rounding; the
-	 * second handles the need for an end marker sentinel.
-	 */
-	win_map->wm_map = rmallocmap((region_size / page_size + 1) / 2 + 1);
-	win_map->wm_page_size = page_size;
-	ASSERT(win_map->wm_map != NULL);
-
-	return win_map;
-}
-
-/*
- * Free resources associated with a PCI window mapping structure.
- */
-extern void
-pciio_device_win_map_free(pciio_win_map_t win_map)
-{
-	rmfreemap(win_map->wm_map);
-	bzero(win_map, sizeof *win_map);
+    return(0);
 }
 
 /*
- * Populate window map with specified free range.
- */
-void
-pciio_device_win_populate(pciio_win_map_t win_map,
-                          iopaddr_t ioaddr,
-                          size_t size)
-{
-	ASSERT((size & (win_map->wm_page_size - 1)) == 0);
-	ASSERT((ioaddr & (win_map->wm_page_size - 1)) == 0);
-
-	rmfree(win_map->wm_map,
-	       size / win_map->wm_page_size,
-	       (unsigned long)ioaddr / win_map->wm_page_size);
-	       
-}
-/*
  * Allocate space from the specified PCI window mapping resource.  On
  * success record information about the allocation in the supplied window
  * allocation cookie (if non-NULL) and return the address of the allocated
@@ -1609,94 +1322,36 @@
  * and alignment.
  */
 iopaddr_t
-pciio_device_win_alloc(pciio_win_map_t win_map,
+pciio_device_win_alloc(struct resource *root_resource,
 		       pciio_win_alloc_t win_alloc,
 		       size_t start, size_t size, size_t align)
 {
-	unsigned long base;
 
-#ifdef PIC_LATER
-	ASSERT((size & (size - 1)) == 0);
-	ASSERT((align & (align - 1)) == 0);
+	struct resource *new_res;
+	int status = 0;
 
-	/*
-	 * Convert size and alignment to pages.  If size is greated than the
-	 * requested alignment, we bump the alignment up to size; otherwise
-	 * convert the size into a multiple of the alignment request.
-	 */
-	size = (size + win_map->wm_page_size - 1) / win_map->wm_page_size;
-	align = align / win_map->wm_page_size;
-	if (size > align)
-		align = size;
-	else
-		size = (size + align - 1) & ~(align - 1);
-
-	/* XXXX */
-	base = rmalloc_align(win_map->wm_map, size, align, VM_NOSLEEP);
-	if (base == RMALLOC_FAIL)
-		return((iopaddr_t)NULL);
-#else
-    int                 index_page, index_page_align;
-    int                 align_pages, size_pages;
-    int                 alloc_pages, free_pages;
-    int                 addr_align;
-
-    /* Convert PCI bus alignment from bytes to pages */
-    align_pages = align / win_map->wm_page_size;
-
-    /* Convert PCI request from bytes to pages */
-    size_pages = (size / win_map->wm_page_size) +
-                  ((size % win_map->wm_page_size) ? 1 : 0);
-
-    /* Align address with the larger of the size or the requested slot align */
-    if (size_pages > align_pages)
-        align_pages = size_pages;
-  
-    /*
-     * Avoid wasting space by aligning - 1; this will prevent crossing
-     * another alignment boundary.
-     */
-    alloc_pages = size_pages + (align_pages - 1);
+	new_res = (struct resource *) kmalloc( sizeof(struct resource), KM_NOSLEEP);
 
-    /* Allocate PCI bus space in pages */
-    index_page = (int) rmalloc(win_map->wm_map,
-                               (size_t) alloc_pages);
-
-    /* Error if no PCI bus address space available */
-    if (!index_page)
-        return 0;
-
-    /* PCI bus address index starts at 0 */
-    index_page--;
-
-    /* Align the page offset as requested */
-    index_page_align = (index_page + (align_pages - 1)) -
-                       ((index_page + (align_pages - 1)) % align_pages);
-
-    free_pages = (align_pages - 1) - (index_page_align - index_page);
-
-    /* Free unused PCI bus pages adjusting the index to start at 1 */
-    rmfree(win_map->wm_map, 
-           free_pages,
-           (index_page_align + 1) + size_pages);
-
-    /* Return aligned PCI bus space in bytes */ 
-    addr_align = (index_page_align * win_map->wm_page_size); 
-    base = index_page;
-    size = alloc_pages - free_pages;
-#endif	/* PIC_LATER */
+	status = allocate_resource( root_resource, new_res,
+				    size, align /* Min start addr. */,
+				    root_resource->end, align,
+				    NULL, NULL);
+	if (status) {
+		kfree(new_res);
+		return((iopaddr_t) NULL);
+	}
 
 	/*
 	 * If a window allocation cookie has been supplied, use it to keep
 	 * track of all the allocated space assigned to this window.
 	 */
 	if (win_alloc) {
-		win_alloc->wa_map = win_map;
-		win_alloc->wa_base = base;
+		win_alloc->wa_resource = new_res;
+		win_alloc->wa_base = new_res->start;
 		win_alloc->wa_pages = size;
 	}
 
-	return base * win_map->wm_page_size;
+	return new_res->start;;
 }
 
 /*
@@ -1706,10 +1361,16 @@
 void
 pciio_device_win_free(pciio_win_alloc_t win_alloc)
 {
-	if (win_alloc->wa_pages)
-		rmfree(win_alloc->wa_map->wm_map,
-		       win_alloc->wa_pages,
-		       win_alloc->wa_base);
+
+	int status = 0;
+
+	if (win_alloc->wa_resource) {
+		status = release_resource(win_alloc->wa_resource);
+		if (!status)
+			kfree(win_alloc->wa_resource);
+		else
+			BUG();
+	}
 }
 
 /*
@@ -1728,7 +1389,7 @@
  * cooperating drivers, well, cooperate ...
  */
 void
-pciio_error_register(devfs_handle_t pconn,
+pciio_error_register(vertex_hdl_t pconn,
 		     error_handler_f *efunc,
 		     error_handler_arg_t einfo)
 {
@@ -1746,7 +1407,7 @@
  * vhdl is the vertex for the slot
  */
 int
-pciio_slot_inuse(devfs_handle_t pconn_vhdl)
+pciio_slot_inuse(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
 
@@ -1763,7 +1424,7 @@
 }
 
 int
-pciio_dma_enabled(devfs_handle_t pconn_vhdl)
+pciio_dma_enabled(vertex_hdl_t pconn_vhdl)
 {
 	return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl);
 }
@@ -1777,7 +1438,7 @@
 
 /*
  * These are complementary Linux interfaces that takes in a pci_dev * as the 
- * first arguement instead of devfs_handle_t.
+ * first arguement instead of vertex_hdl_t.
  */
 iopaddr_t               snia_pciio_dmatrans_addr(struct pci_dev *, device_desc_t, paddr_t, size_t, unsigned);
 pciio_dmamap_t          snia_pciio_dmamap_alloc(struct pci_dev *, device_desc_t, size_t, unsigned);
@@ -1800,7 +1461,7 @@
 	int *count_vchan0,
 	int *count_vchan1)
 {
-	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+	vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev);
 
 	return pcibr_rrb_alloc(dev, count_vchan0, count_vchan1);
 }
@@ -1811,7 +1472,7 @@
 	pciio_endian_t device_end,
 	pciio_endian_t desired_end)
 {
-	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+	vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev);
 	
 	return DEV_FUNC(dev, endian_set)
 		(dev, device_end, desired_end);
@@ -1825,7 +1486,7 @@
                     unsigned flags)
 {                                       /* defined in dma.h */
 
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+    vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev);
 
     /*
      * If the device is not a PIC, we always want the PCIIO_BYTE_STREAM to be 
@@ -1842,7 +1503,7 @@
                    unsigned flags)
 {                                       /* defined in dma.h */
 
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+    vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev);
 
     /*
      * If the device is not a PIC, we always want the PCIIO_BYTE_STREAM to be
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/pic.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pic.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/pic.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/pic.c	2003-08-01 13:33:21.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,51 +27,195 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
+extern char *bcopy(const char * src, char * dest, int count);
+
 
 #define PCI_BUS_NO_1 1
 
-int pic_devflag = D_MP;
+extern int pcibr_attach2(vertex_hdl_t, bridge_t *, vertex_hdl_t, int, pcibr_soft_t *);
+extern void pcibr_driver_reg_callback(vertex_hdl_t, int, int, int);
+extern void pcibr_driver_unreg_callback(vertex_hdl_t, int, int, int);
 
-extern int pcibr_attach2(devfs_handle_t, bridge_t *, devfs_handle_t, int, pcibr_soft_t *);
-extern void pcibr_driver_reg_callback(devfs_handle_t, int, int, int);
-extern void pcibr_driver_unreg_callback(devfs_handle_t, int, int, int);
 
+/*
+ * copy inventory_t from conn_v to peer_conn_v
+ */
+int
+pic_bus1_inventory_dup(vertex_hdl_t conn_v, vertex_hdl_t peer_conn_v)
+{
+	inventory_t *pinv, *peer_pinv;
+
+	if (hwgraph_info_get_LBL(conn_v, INFO_LBL_INVENT,
+				(arbitrary_info_t *)&pinv) == GRAPH_SUCCESS)
+ {
+		NEW(peer_pinv);
+		bcopy((const char *)pinv, (char *)peer_pinv, sizeof(inventory_t));
+		if (hwgraph_info_add_LBL(peer_conn_v, INFO_LBL_INVENT,
+			    (arbitrary_info_t)peer_pinv) != GRAPH_SUCCESS) {
+			DEL(peer_pinv);
+			return 0;
+		}
+		return 1;
+	}
+
+	printk("pic_bus1_inventory_dup: cannot get INFO_LBL_INVENT from 0x%lx\n ", (uint64_t)conn_v);
+	return 0;
+}
 
-void
-pic_init(void)
+/*
+ * copy xwidget_info_t from conn_v to peer_conn_v
+ */
+int
+pic_bus1_widget_info_dup(vertex_hdl_t conn_v, vertex_hdl_t peer_conn_v,
+							cnodeid_t xbow_peer)
 {
-	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INIT, NULL, "pic_init()\n"));	
+	xwidget_info_t widget_info, peer_widget_info;
+	char peer_path[256];
+	vertex_hdl_t peer_hubv;
+	hubinfo_t peer_hub_info;
+
+	/* get the peer hub's widgetid */
+	peer_hubv = NODEPDA(xbow_peer)->node_vertex;
+	peer_hub_info = NULL;
+	hubinfo_get(peer_hubv, &peer_hub_info);
+	if (peer_hub_info == NULL)
+		return 0;
+
+	if (hwgraph_info_get_LBL(conn_v, INFO_LBL_XWIDGET,
+			(arbitrary_info_t *)&widget_info) == GRAPH_SUCCESS) {
+		NEW(peer_widget_info);
+		peer_widget_info->w_vertex = peer_conn_v;
+		peer_widget_info->w_id = widget_info->w_id;
+		peer_widget_info->w_master = peer_hubv;
+		peer_widget_info->w_masterid = peer_hub_info->h_widgetid;
+		/* structure copy */
+		peer_widget_info->w_hwid = widget_info->w_hwid;
+		peer_widget_info->w_efunc = 0;
+		peer_widget_info->w_einfo = 0;
+		peer_widget_info->w_name = kmalloc(strlen(peer_path) + 1, GFP_KERNEL);
+		strcpy(peer_widget_info->w_name, peer_path);
+
+		if (hwgraph_info_add_LBL(peer_conn_v, INFO_LBL_XWIDGET,
+			(arbitrary_info_t)peer_widget_info) != GRAPH_SUCCESS) {
+				DEL(peer_widget_info);
+				return 0;
+		}
+
+		xwidget_info_set(peer_conn_v, peer_widget_info);
 
-	xwidget_driver_register(PIC_WIDGET_PART_NUM_BUS0,
-			    PIC_WIDGET_MFGR_NUM,
-			    "pic_",
-			    0);
+		return 1;
+	}
+
+	printk("pic_bus1_widget_info_dup: "
+			"cannot get INFO_LBL_XWIDGET from 0x%lx\n", (uint64_t)conn_v);
+	return 0;
 }
 
+/*
+ * If this PIC is attached to two Cbricks ("dual-ported") then
+ * attach each bus to opposite Cbricks.
+ *
+ * If successful, return a new vertex suitable for attaching the PIC bus.
+ * If not successful, return zero and both buses will attach to the
+ * vertex passed into pic_attach().
+ */
+vertex_hdl_t
+pic_bus1_redist(nasid_t nasid, vertex_hdl_t conn_v)
+{
+	cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
+	cnodeid_t xbow_peer = -1;
+	char pathname[256], peer_path[256], tmpbuf[256];
+	char *p;
+	int rc;
+	vertex_hdl_t peer_conn_v;
+	int pos;
+	slabid_t slab;
+
+	if (NODEPDA(cnode)->xbow_peer >= 0) {			/* if dual-ported */
+		/* create a path for this widget on the peer Cbrick */
+		/* pcibr widget hw/module/001c11/slab/0/Pbrick/xtalk/12 */
+		/* sprintf(pathname, "%v", conn_v); */
+		xbow_peer = NASID_TO_COMPACT_NODEID(NODEPDA(cnode)->xbow_peer);
+		pos = hwgfs_generate_path(conn_v, tmpbuf, 256);
+		strcpy(pathname, &tmpbuf[pos]);
+		p = pathname + strlen("hw/module/001c01/slab/0/");
+
+		memset(tmpbuf, 0, 16);
+		format_module_id(tmpbuf, geo_module((NODEPDA(xbow_peer))->geoid), MODULE_FORMAT_BRIEF);
+		slab = geo_slab((NODEPDA(xbow_peer))->geoid);
+		sprintf(peer_path, "module/%s/slab/%d/%s", tmpbuf, (int)slab, p); 
+		
+		/* Look for vertex for this widget on the peer Cbrick.
+		 * Expect GRAPH_NOT_FOUND.
+		 */
+		rc = hwgraph_traverse(hwgraph_root, peer_path, &peer_conn_v);
+		if (GRAPH_SUCCESS == rc)
+			printk("pic_attach: found unexpected vertex: 0x%lx\n",
+								(uint64_t)peer_conn_v);
+		else if (GRAPH_NOT_FOUND != rc) {
+			printk("pic_attach: hwgraph_traverse unexpectedly"
+					" returned 0x%x\n", rc);
+		} else {
+			/* try to add the widget vertex to the peer Cbrick */
+			rc = hwgraph_path_add(hwgraph_root, peer_path, &peer_conn_v);
+
+			if (GRAPH_SUCCESS != rc)
+			    printk("pic_attach: hwgraph_path_add"
+						" failed with 0x%x\n", rc);
+			else {
+			    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
+					"pic_bus1_redist: added vertex %v\n", peer_conn_v)); 
+
+			    /* Now hang appropiate stuff off of the new
+			     * vertex.	We bail out if we cannot add something.
+			     * In that case, we don't remove the newly added
+			     * vertex but that should be safe and we don't
+			     * really expect the additions to fail anyway.
+			     */
+#if 0
+			    if (!pic_bus1_inventory_dup(conn_v, peer_conn_v))
+					return 0;
+			    pic_bus1_device_desc_dup(conn_v, peer_conn_v);
+#endif
+			    if (!pic_bus1_widget_info_dup(conn_v, peer_conn_v, xbow_peer))
+					return 0;
+
+			    return peer_conn_v;
+			}
+		}
+	}
+	return 0;
+}
+
+
 int
-pic_attach(devfs_handle_t conn_v)
+pic_attach(vertex_hdl_t conn_v)
 {
 	int		rc;
 	bridge_t	*bridge0, *bridge1 = (bridge_t *)0;
-	devfs_handle_t	pcibr_vhdl0, pcibr_vhdl1 = (devfs_handle_t)0;
+	vertex_hdl_t	pcibr_vhdl0, pcibr_vhdl1 = (vertex_hdl_t)0;
 	pcibr_soft_t	bus0_soft, bus1_soft = (pcibr_soft_t)0;
+	vertex_hdl_t  conn_v0, conn_v1, peer_conn_v;
 
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach()\n"));
 
 	bridge0 = (bridge_t *) xtalk_piotrans_addr(conn_v, NULL,
 	                        0, sizeof(bridge_t), 0);
-#ifdef	PCI_BUS_NO_1
 	bridge1 = (bridge_t *)((char *)bridge0 + PIC_BUS1_OFFSET);
-#endif
 
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
 		    "pic_attach: bridge0=0x%x, bridge1=0x%x\n", 
 		    bridge0, bridge1));
 
+	conn_v0 = conn_v1 = conn_v;
+
+	/* If dual-ported then split the two PIC buses across both Cbricks */
+	if ((peer_conn_v = (pic_bus1_redist(NASID_GET(bridge0), conn_v))))
+		conn_v1 = peer_conn_v;
+
 	/*
 	 * Create the vertex for the PCI buses, which we
 	 * will also use to hold the pcibr_soft and
@@ -84,12 +228,10 @@
 	 * the Bridge registers themselves.
 	 */
 	/* FIXME: what should the hwgraph path look like ? */
-	rc = hwgraph_path_add(conn_v, EDGE_LBL_PCIX_0, &pcibr_vhdl0);
+	rc = hwgraph_path_add(conn_v0, EDGE_LBL_PCIX_0, &pcibr_vhdl0);
 	ASSERT(rc == GRAPH_SUCCESS);
-#ifdef	PCI_BUS_NO_1
-	rc = hwgraph_path_add(conn_v, EDGE_LBL_PCIX_1, &pcibr_vhdl1);
+	rc = hwgraph_path_add(conn_v1, EDGE_LBL_PCIX_1, &pcibr_vhdl1);
 	ASSERT(rc == GRAPH_SUCCESS);
-#endif
 
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
 		    "pic_attach: pcibr_vhdl0=%v, pcibr_vhdl1=%v\n",
@@ -97,27 +239,17 @@
 
 	/* register pci provider array */
 	pciio_provider_register(pcibr_vhdl0, &pci_pic_provider);
-#ifdef	PCI_BUS_NO_1
 	pciio_provider_register(pcibr_vhdl1, &pci_pic_provider);
-#endif
 
 	pciio_provider_startup(pcibr_vhdl0);
-#ifdef	PCI_BUS_NO_1
 	pciio_provider_startup(pcibr_vhdl1);
-#endif
 
-	pcibr_attach2(conn_v, bridge0, pcibr_vhdl0, 0, &bus0_soft);
-#ifdef	PCI_BUS_NO_1
-	pcibr_attach2(conn_v, bridge1, pcibr_vhdl1, 1, &bus1_soft);
-#endif
+	pcibr_attach2(conn_v0, bridge0, pcibr_vhdl0, 0, &bus0_soft);
+	pcibr_attach2(conn_v1, bridge1, pcibr_vhdl1, 1, &bus1_soft);
 
 	/* save a pointer to the PIC's other bus's soft struct */
-#ifdef	PCI_BUS_NO_1
         bus0_soft->bs_peers_soft = bus1_soft;
         bus1_soft->bs_peers_soft = bus0_soft;
-#else
-        bus0_soft->bs_peers_soft = (pcibr_soft_t)0;
-#endif
 
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
 		    "pic_attach: bus0_soft=0x%x, bus1_soft=0x%x\n",
@@ -145,10 +277,8 @@
     (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,
     (pciio_dmamap_free_f *) pcibr_dmamap_free,
     (pciio_dmamap_addr_f *) pcibr_dmamap_addr,
-    (pciio_dmamap_list_f *) pcibr_dmamap_list,
     (pciio_dmamap_done_f *) pcibr_dmamap_done,
     (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
-    (pciio_dmatrans_list_f *) pcibr_dmatrans_list,
     (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
     (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
     (pciio_dmalist_drain_f *) pcibr_dmalist_drain,
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/sgi_io_init.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/sgi_io_init.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/sgi_io_init.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/sgi_io_init.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,230 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/pci/pciba.h>
-#include <linux/smp.h>
-
-extern void mlreset(void);
-extern int init_hcl(void);
-extern void klgraph_hack_init(void);
-extern void hubspc_init(void);
-extern void pciio_init(void);
-extern void pcibr_init(void);
-extern void xtalk_init(void);
-extern void xbow_init(void);
-extern void xbmon_init(void);
-extern void pciiox_init(void);
-extern void pic_init(void);
-extern void usrpci_init(void);
-extern void ioc3_init(void);
-extern void initialize_io(void);
-extern void klhwg_add_all_modules(devfs_handle_t);
-extern void klhwg_add_all_nodes(devfs_handle_t);
-
-void sn_mp_setup(void);
-extern devfs_handle_t hwgraph_root;
-extern void io_module_init(void);
-extern void pci_bus_cvlink_init(void);
-extern void temp_hack(void);
-
-extern int pci_bus_to_hcl_cvlink(void);
-
-/* #define DEBUG_IO_INIT 1 */
-#ifdef DEBUG_IO_INIT
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_IO_INIT */
-
-/*
- * per_hub_init
- *
- * 	This code is executed once for each Hub chip.
- */
-static void
-per_hub_init(cnodeid_t cnode)
-{
-	nasid_t		nasid;
-	nodepda_t	*npdap;
-	ii_icmr_u_t	ii_icmr;
-	ii_ibcr_u_t	ii_ibcr;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	ASSERT(nasid != INVALID_NASID);
-	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
-
-	npdap = NODEPDA(cnode);
-
-#ifdef BRINGUP2
-#if 0
-	while ((REMOTE_HUB_L(nasid, IIO_IFDR)) != 0x2d2d)
-		REMOTE_HUB_S(nasid, IIO_IFDR, 0xadad);
-#endif
-	printk("IIO_IFDR = 0x%x\n", REMOTE_HUB_L(nasid, IIO_IFDR));
-	REMOTE_HUB_S(nasid, IIO_IWEIM, 0x8000);
-#endif
-	/*
-	 * Set the total number of CRBs that can be used.
-	 */
-	ii_icmr.ii_icmr_regval= 0x0;
-	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xF;
-	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
-
-	/*
-	 * Set the number of CRBs that both of the BTEs combined
-	 * can use minus 1.
-	 */
-	ii_ibcr.ii_ibcr_regval= 0x0;
-	ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
-	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
-
-	/*
-	 * Set CRB timeout to be 10ms.
-	 */
-#ifdef BRINGUP2
-	REMOTE_HUB_S(nasid, IIO_ICTP, 0xffffff );
-	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
-	REMOTE_HUB_S(nasid, IIO_IDBSS, 0x504);
-	REMOTE_HUB_S(nasid, SH_DEBUG_SELECT, 0x0002DF6D74CF2C70);
-#endif
-
-	/* Initialize error interrupts for this hub. */
-	hub_error_init(cnode);
-}
-
-/*
- * This routine is responsible for the setup of all the IRIX hwgraph style
- * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
- * is called just before the generic Linux PCI layer does its probing (by 
- * platform_pci_fixup aka sn_pci_fixup).
- *
- * It is very IMPORTANT that this call is only made by the Master CPU!
- *
- */
-
-void
-sgi_master_io_infr_init(void)
-{
-	int cnode;
-
-	/*
-	 * Do any early init stuff .. einit_tbl[] etc.
-	 */
-	init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */
-
-	/*
-	 * initialize the Linux PCI to xwidget vertexes ..
-	 */
-	pci_bus_cvlink_init();
-
-#ifdef BRINGUP
-	/*
-	 * Hack to provide statically initialzed klgraph entries.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n");
-	klgraph_hack_init();
-#endif /* BRINGUP */
-
-	/*
-	 * This is the Master CPU.  Emulate mlsetup and main.c in Irix.
-	 */
-	mlreset();
-
-	/*
-	 * allowboot() is called by kern/os/main.c in main()
-	 * Emulate allowboot() ...
-	 *   per_cpu_init() - only need per_hub_init()
-	 *   cpu_io_setup() - Nothing to do.
-	 * 
-	 */
-	sn_mp_setup();
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		per_hub_init(cnode);
-	}
-
-	/* We can do headless hub cnodes here .. */
-
-	/*
-	 * io_init[] stuff.
-	 *
-	 * Get SGI IO Infrastructure drivers to init and register with 
-	 * each other etc.
-	 */
-
-	hubspc_init();
-	pciio_init();
-	pcibr_init();
-	pic_init();
-	xtalk_init();
-	xbow_init();
-	xbmon_init();
-	pciiox_init();
-	usrpci_init();
-	ioc3_init();
-
-	/*
-	 *
-	 * Our IO Infrastructure drivers are in place .. 
-	 * Initialize the whole IO Infrastructure .. xwidget/device probes.
-	 *
-	 */
-	initialize_io();
-	pci_bus_to_hcl_cvlink();
-
-#ifdef CONFIG_PCIBA
-	DBG("--> sgi_master_io_infr_init: calling pciba_init()\n");
-#ifndef BRINGUP2
- 	pciba_init();
-#endif
-#endif
-}
-
-/*
- * One-time setup for MP SN.
- * Allocate per-node data, slurp prom klconfig information and
- * convert it to hwgraph information.
- */
-void
-sn_mp_setup(void)
-{
-	cpuid_t		cpu;
-
-	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-		/* Skip holes in CPU space */
-		if (cpu_enabled(cpu)) {
-			init_platform_pda(cpu);
-		}
-	}
-
-	/*
-	 * Initialize platform-dependent vertices in the hwgraph:
-	 *	module
-	 *	node
-	 *	cpu
-	 *	memory
-	 *	slot
-	 *	hub
-	 *	router
-	 *	xbow
-	 */
-
-	io_module_init(); /* Use to be called module_init() .. */
-	klhwg_add_all_modules(hwgraph_root);
-	klhwg_add_all_nodes(hwgraph_root);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/shub.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/shub.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/shub.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/shub.c	2003-08-01 13:30:35.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #ident  "$Revision: 1.167 $"
@@ -15,6 +15,7 @@
 #include <asm/smp.h>
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
+#include <asm/system.h>
 #include <asm/sn/sgi.h>
 #include <asm/sn/iograph.h>
 #include <asm/sn/invent.h>
@@ -97,6 +98,14 @@
 }
 
 static inline void
+shub_mmr_write_iospace(cnodeid_t cnode, shubreg_t reg, uint64_t val)
+{
+	int		   nasid = cnodeid_to_nasid(cnode);
+
+	REMOTE_HUB_S(nasid, reg, val);
+}
+
+static inline void
 shub_mmr_write32(cnodeid_t cnode, shubreg_t reg, uint32_t val)
 {
 	int		   nasid = cnodeid_to_nasid(cnode);
@@ -118,6 +127,14 @@
 	return val;
 }
 
+static inline uint64_t
+shub_mmr_read_iospace(cnodeid_t cnode, shubreg_t reg)
+{
+	int		  nasid = cnodeid_to_nasid(cnode);
+
+	return REMOTE_HUB_L(nasid, reg);
+}
+
 static inline uint32_t
 shub_mmr_read32(cnodeid_t cnode, shubreg_t reg)
 {
@@ -182,12 +199,15 @@
 {
         cnodeid_t       cnode;
         uint64_t        longarg;
-        devfs_handle_t  d;
 	int		nasid;
 
-        if ((d = devfs_get_handle_from_inode(inode)) == NULL)
+#ifdef CONFIG_HWGFS_FS
+        cnode = (cnodeid_t)file->f_dentry->d_fsdata;
+#else
+        cnode = (cnodeid_t)file->private_data;
+#endif
+        if (!cnode)
                 return -ENODEV;
-        cnode = (cnodeid_t)hwgraph_fastinfo_get(d);
 
         switch (cmd) {
 	case SNDRV_SHUB_CONFIGURE:
@@ -231,3 +251,255 @@
 struct file_operations shub_mon_fops = {
 	        ioctl:          shubstats_ioctl,
 };
+
+/*
+ * "linkstatd" kernel thread to export SGI Numalink
+ * stats via /proc/sgi_sn/linkstats
+ */
+static struct s_linkstats {
+	uint64_t	hs_ni_sn_errors[2];
+	uint64_t	hs_ni_cb_errors[2];
+	uint64_t	hs_ni_retry_errors[2];
+	int		hs_ii_up;
+	uint64_t	hs_ii_sn_errors;
+	uint64_t	hs_ii_cb_errors;
+	uint64_t	hs_ii_retry_errors;
+} *sn_linkstats;
+
+static spinlock_t    sn_linkstats_lock;
+static unsigned long sn_linkstats_starttime;
+static unsigned long sn_linkstats_samples;
+static unsigned long sn_linkstats_overflows;
+static unsigned long sn_linkstats_update_msecs;
+
+void
+sn_linkstats_reset(unsigned long msecs)
+{
+	int		    cnode;
+	uint64_t	    iio_wstat;
+	uint64_t	    llp_csr_reg;
+
+	spin_lock(&sn_linkstats_lock);
+	memset(sn_linkstats, 0, numnodes * sizeof(struct s_linkstats));
+	for (cnode=0; cnode < numnodes; cnode++) {
+	    shub_mmr_write(cnode, SH_NI0_LLP_ERR, 0L);
+	    shub_mmr_write(cnode, SH_NI1_LLP_ERR, 0L);
+	    shub_mmr_write_iospace(cnode, IIO_LLP_LOG, 0L);
+
+	    /* zero the II retry counter */
+	    iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT);
+	    iio_wstat &= 0xffffffffff00ffff; /* bits 23:16 */
+	    shub_mmr_write_iospace(cnode, IIO_WSTAT, iio_wstat);
+
+	    /* Check if the II xtalk link is working */
+	    llp_csr_reg = shub_mmr_read_iospace(cnode, IIO_LLP_CSR);
+	    if (llp_csr_reg & IIO_LLP_CSR_IS_UP)
+		sn_linkstats[cnode].hs_ii_up = 1;
+	}
+
+    	sn_linkstats_update_msecs = msecs;
+	sn_linkstats_samples = 0;
+	sn_linkstats_overflows = 0;
+	sn_linkstats_starttime = jiffies;
+	spin_unlock(&sn_linkstats_lock);
+}
+
+int
+linkstatd_thread(void *unused)
+{
+	int		    cnode;
+	int		    overflows;
+	uint64_t	    reg[2];
+	uint64_t	    iio_wstat = 0L;
+	ii_illr_u_t	    illr;
+	struct s_linkstats  *lsp;
+	struct task_struct  *tsk = current;
+
+	daemonize();
+	set_user_nice(tsk, 19);
+	sigfillset(&tsk->blocked);
+	strcpy(tsk->comm, "linkstatd");
+
+	while(1) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(sn_linkstats_update_msecs * HZ / 1000);
+
+		spin_lock(&sn_linkstats_lock);
+
+		overflows = 0;
+		for (lsp=sn_linkstats, cnode=0; cnode < numnodes; cnode++, lsp++) {
+			reg[0] = shub_mmr_read(cnode, SH_NI0_LLP_ERR);
+			reg[1] = shub_mmr_read(cnode, SH_NI1_LLP_ERR);
+			if (lsp->hs_ii_up) {
+			    illr = (ii_illr_u_t)shub_mmr_read_iospace(cnode, IIO_LLP_LOG);
+			    iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT);
+			}
+
+			if (!overflows && (
+			    (reg[0] & SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK) == 
+				     SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK ||
+			    (reg[0] & SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK) ==
+			             SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK ||
+			    (reg[1] & SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK) ==
+			             SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK ||
+			    (reg[1] & SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK) ==
+			             SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK ||
+			    (lsp->hs_ii_up && illr.ii_illr_fld_s.i_sn_cnt == IIO_LLP_SN_MAX) ||
+			    (lsp->hs_ii_up && illr.ii_illr_fld_s.i_cb_cnt == IIO_LLP_CB_MAX))) {
+			    overflows = 1;
+			}
+
+#define LINKSTAT_UPDATE(reg, cnt, mask, shift) cnt += (reg & mask) >> shift
+
+			LINKSTAT_UPDATE(reg[0], lsp->hs_ni_sn_errors[0],
+					SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK,
+					SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[1], lsp->hs_ni_sn_errors[1],
+					SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK,
+					SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[0], lsp->hs_ni_cb_errors[0],
+					SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK,
+					SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[1], lsp->hs_ni_cb_errors[1],
+					SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK,
+					SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[0], lsp->hs_ni_retry_errors[0],
+					SH_NI0_LLP_ERR_RETRY_COUNT_MASK,
+					SH_NI0_LLP_ERR_RETRY_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[1], lsp->hs_ni_retry_errors[1],
+					SH_NI1_LLP_ERR_RETRY_COUNT_MASK,
+					SH_NI1_LLP_ERR_RETRY_COUNT_SHFT);
+
+			if (lsp->hs_ii_up) {
+			    /* II sn and cb errors */
+			    lsp->hs_ii_sn_errors += illr.ii_illr_fld_s.i_sn_cnt;
+			    lsp->hs_ii_cb_errors += illr.ii_illr_fld_s.i_cb_cnt;
+			    lsp->hs_ii_retry_errors += (iio_wstat & 0x0000000000ff0000) >> 16;
+
+			    shub_mmr_write(cnode, SH_NI0_LLP_ERR, 0L);
+			    shub_mmr_write(cnode, SH_NI1_LLP_ERR, 0L);
+			    shub_mmr_write_iospace(cnode, IIO_LLP_LOG, 0L);
+
+			    /* zero the II retry counter */
+			    iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT);
+			    iio_wstat &= 0xffffffffff00ffff; /* bits 23:16 */
+			    shub_mmr_write_iospace(cnode, IIO_WSTAT, iio_wstat);
+			}
+		}
+
+		sn_linkstats_samples++;
+		if (overflows)
+		    sn_linkstats_overflows++;
+
+		spin_unlock(&sn_linkstats_lock);
+	}
+}
+
+static char *
+rate_per_minute(uint64_t val, uint64_t secs)
+{
+	static char	buf[16];
+	uint64_t	a=0, b=0, c=0, d=0;
+
+	if (secs) {
+		a = 60 * val / secs;
+		b = 60 * 10 * val / secs - (10 * a);
+		c = 60 * 100 * val / secs - (100 * a) - (10 * b);
+		d = 60 * 1000 * val / secs - (1000 * a) - (100 * b) - (10 * c);
+	}
+	sprintf(buf, "%4lu.%lu%lu%lu", a, b, c, d);
+
+	return buf;
+}
+
+int
+sn_linkstats_get(char *page)
+{
+	int			n = 0;
+	int			cnode;
+	int			nlport;
+	struct s_linkstats	*lsp;
+	nodepda_t		*npda;
+	uint64_t	    	snsum = 0;
+	uint64_t	    	cbsum = 0;
+	uint64_t	    	retrysum = 0;
+	uint64_t	    	snsum_ii = 0;
+	uint64_t	    	cbsum_ii = 0;
+	uint64_t	    	retrysum_ii = 0;
+	uint64_t		secs;
+
+	spin_lock(&sn_linkstats_lock);
+	secs = (jiffies - sn_linkstats_starttime) / HZ;
+
+	n += sprintf(page, "# SGI Numalink stats v1 : %lu samples, %lu o/flows, update %lu msecs\n",
+		sn_linkstats_samples, sn_linkstats_overflows, sn_linkstats_update_msecs);
+
+	n += sprintf(page+n, "%-37s %8s %8s %8s %8s\n",
+		"# Numalink", "sn errs", "cb errs", "cb/min", "retries");
+
+	for (lsp=sn_linkstats, cnode=0; cnode < numnodes; cnode++, lsp++) {
+		npda = NODEPDA(cnode);
+
+		/* two NL links on each SHub */
+		for (nlport=0; nlport < 2; nlport++) {
+			cbsum += lsp->hs_ni_cb_errors[nlport];
+			snsum += lsp->hs_ni_sn_errors[nlport];
+			retrysum += lsp->hs_ni_retry_errors[nlport];
+
+			/* avoid buffer overrun (should be using seq_read API) */
+			if (numnodes > 64)
+				continue;
+
+			n += sprintf(page + n, "/%s/link/%d  %8lu %8lu %8s %8lu\n",
+			    npda->hwg_node_name, nlport+1, lsp->hs_ni_sn_errors[nlport],
+			    lsp->hs_ni_cb_errors[nlport], 
+			    rate_per_minute(lsp->hs_ni_cb_errors[nlport], secs),
+			    lsp->hs_ni_retry_errors[nlport]);
+		}
+
+		/* one II port on each SHub (may not be connected) */
+		if (lsp->hs_ii_up) {
+		    n += sprintf(page + n, "/%s/xtalk   %8lu %8lu %8s %8lu\n",
+			npda->hwg_node_name, lsp->hs_ii_sn_errors,
+			lsp->hs_ii_cb_errors, rate_per_minute(lsp->hs_ii_cb_errors, secs),
+			lsp->hs_ii_retry_errors);
+
+		    snsum_ii += lsp->hs_ii_sn_errors;
+		    cbsum_ii += lsp->hs_ii_cb_errors;
+		    retrysum_ii += lsp->hs_ii_retry_errors;
+		}
+	}
+
+	n += sprintf(page + n, "%-37s %8lu %8lu %8s %8lu\n",
+		"System wide NL totals", snsum, cbsum, 
+		rate_per_minute(cbsum, secs), retrysum);
+
+	n += sprintf(page + n, "%-37s %8lu %8lu %8s %8lu\n",
+		"System wide II totals", snsum_ii, cbsum_ii, 
+		rate_per_minute(cbsum_ii, secs), retrysum_ii);
+
+	spin_unlock(&sn_linkstats_lock);
+
+	return n;
+}
+
+static int __init
+linkstatd_init(void)
+{
+	if (!ia64_platform_is("sn2"))
+		return -ENODEV;
+
+	spin_lock_init(&sn_linkstats_lock);
+	sn_linkstats = kmalloc(numnodes * sizeof(struct s_linkstats), GFP_KERNEL);
+	sn_linkstats_reset(60000UL); /* default 60 second update interval */
+	kernel_thread(linkstatd_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
+
+	return 0;                                                                       
+}
+
+__initcall(linkstatd_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/shub_intr.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/shub_intr.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/shub_intr.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/shub_intr.c	2003-08-01 13:30:36.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/types.h>
@@ -30,7 +30,7 @@
 
 /* ARGSUSED */
 void
-hub_intr_init(devfs_handle_t hubv)
+hub_intr_init(vertex_hdl_t hubv)
 {
 }
 
@@ -45,9 +45,9 @@
 }
 
 static hub_intr_t
-do_hub_intr_alloc(devfs_handle_t dev,
+do_hub_intr_alloc(vertex_hdl_t dev,
 		device_desc_t dev_desc,
-		devfs_handle_t owner_dev,
+		vertex_hdl_t owner_dev,
 		int uncond_nothread)
 {
 	cpuid_t		cpu = 0;
@@ -101,17 +101,17 @@
 }
 
 hub_intr_t
-hub_intr_alloc(devfs_handle_t dev,
+hub_intr_alloc(vertex_hdl_t dev,
 		device_desc_t dev_desc,
-		devfs_handle_t owner_dev)
+		vertex_hdl_t owner_dev)
 {
 	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 0));
 }
 
 hub_intr_t
-hub_intr_alloc_nothd(devfs_handle_t dev,
+hub_intr_alloc_nothd(vertex_hdl_t dev,
 		device_desc_t dev_desc,
-		devfs_handle_t owner_dev)
+		vertex_hdl_t owner_dev)
 {
 	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 1));
 }
@@ -188,18 +188,3 @@
 	ASSERT(rv == 0);
 	intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED;
 }
-
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-hub_intr_cpu_get(hub_intr_t intr_hdl)
-{
-	cpuid_t cpuid = intr_hdl->i_cpuid;
-
-	ASSERT(cpuid != CPU_NONE);
-
-	return(cpuid_to_vertex(cpuid));
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/shuberror.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/shuberror.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/shuberror.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/shuberror.c	2003-08-01 13:33:22.000000000 +0000
@@ -4,13 +4,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000,2002-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/irq.h>
+#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/smp.h>
 #include <asm/sn/sgi.h>
@@ -27,6 +28,7 @@
 #include <asm/sn/xtalk/xtalk.h>
 #include <asm/sn/pci/pcibr_private.h>
 #include <asm/sn/intr.h>
+#include <asm/sn/ioerror_handling.h>
 #include <asm/sn/ioerror.h>
 #include <asm/sn/sn2/shubio.h>
 #include <asm/sn/bte.h>
@@ -34,21 +36,18 @@
 extern void hubni_eint_init(cnodeid_t cnode);
 extern void hubii_eint_init(cnodeid_t cnode);
 extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep);
-int hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo);
-int hubiio_prb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo);
-extern void bte_crb_error_handler(devfs_handle_t hub_v, int btenum, int crbnum, ioerror_t *ioe, int bteop);
+int hubiio_crb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo);
+int hubiio_prb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo);
+extern void bte_crb_error_handler(vertex_hdl_t hub_v, int btenum, int crbnum, ioerror_t *ioe, int bteop);
+void print_crb_fields(int crb_num, ii_icrb0_a_u_t icrba,
+	ii_icrb0_b_u_t icrbb, ii_icrb0_c_u_t icrbc,
+	ii_icrb0_d_u_t icrbd, ii_icrb0_e_u_t icrbe);
 
 extern int maxcpus;
+extern error_return_code_t error_state_set(vertex_hdl_t v,error_state_t new_state);
 
 #define HUB_ERROR_PERIOD        (120 * HZ)      /* 2 minutes */
 
-#ifdef BUS_INT_WAR
-void sn_add_polled_interrupt(int irq, int interval);
-void sn_delete_polled_interrupt(int irq);
-extern int bus_int_war_ide_irq;
-#endif
-
-
 void
 hub_error_clear(nasid_t nasid)
 {
@@ -74,9 +73,7 @@
         REMOTE_HUB_S(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)), prb.iprb_regval);
     }
 
-    REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, -1);
-    idsr = REMOTE_HUB_L(nasid, IIO_IIDSR);
-    REMOTE_HUB_S(nasid, IIO_IIDSR, (idsr & ~(IIO_IIDSR_SENT_MASK)));
+    REMOTE_HUB_S(nasid, IIO_IECLR, -1);
 
 }
 
@@ -117,7 +114,6 @@
  * Returns	: None.
  */
 
-
 void
 hubii_eint_init(cnodeid_t cnode)
 {
@@ -125,33 +121,41 @@
     ii_iidsr_u_t    	hubio_eint;
     hubinfo_t		hinfo; 
     cpuid_t		intr_cpu;
-    devfs_handle_t 	hub_v;
+    vertex_hdl_t 	hub_v;
     int bit_pos_to_irq(int bit);
+    ii_ilcsr_u_t	ilcsr;
 
 
-    hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode);
+    hub_v = (vertex_hdl_t)cnodeid_to_vertex(cnode);
     ASSERT_ALWAYS(hub_v);
     hubinfo_get(hub_v, &hinfo);
 
     ASSERT(hinfo);
     ASSERT(hinfo->h_cnodeid == cnode);
 
+    ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
+    if ((ilcsr.ii_ilcsr_fld_s.i_llp_stat & 0x2) == 0) {
+	/*
+	 * HUB II link is not up.  Disable LLP. Clear old errors.
+	 * Enable interrupts to handle BTE errors.
+	 */
+	ilcsr.ii_ilcsr_fld_s.i_llp_en = 0;
+	REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval);
+    }
+
     /* Select a possible interrupt target where there is a free interrupt
      * bit and also reserve the interrupt bit for this IO error interrupt
      */
-    intr_cpu = intr_heuristic(hub_v,0,-1,0,hub_v,
+    intr_cpu = intr_heuristic(hub_v,0,SGI_II_ERROR,0,hub_v,
 			      "HUB IO error interrupt",&bit);
     if (intr_cpu == CPU_NONE) {
 	printk("hubii_eint_init: intr_reserve_level failed, cnode %d", cnode);
 	return;
     }
 	
-    rv = intr_connect_level(intr_cpu, bit, 0, NULL);
-    request_irq(bit + (intr_cpu << 8), hubii_eint_handler, 0, "SN_hub_error", (void *)hub_v);
-    irq_desc(bit + (intr_cpu << 8))->status |= SN2_IRQ_PER_HUB;
-#ifdef BUS_INT_WAR                                              
-    sn_add_polled_interrupt(bit + (intr_cpu << 8), (0.01 * HZ));
-#endif
+    rv = intr_connect_level(intr_cpu, SGI_II_ERROR, 0, NULL);
+    request_irq(SGI_II_ERROR, hubii_eint_handler, SA_SHIRQ, "SN_hub_error", (void *)hub_v);
+    irq_desc(bit)->status |= SN2_IRQ_PER_HUB;
     ASSERT_ALWAYS(rv >= 0);
     hubio_eint.ii_iidsr_regval = 0;
     hubio_eint.ii_iidsr_fld_s.i_enable = 1;
@@ -167,18 +171,29 @@
 void
 hubii_eint_handler (int irq, void *arg, struct pt_regs *ep)
 {
-    devfs_handle_t	hub_v;
+    vertex_hdl_t	hub_v;
     hubinfo_t		hinfo; 
     ii_wstat_u_t	wstat;
     hubreg_t		idsr;
+    ii_ilcsr_u_t	ilcsr;
 
 
     /* two levels of casting avoids compiler warning.!! */
-    hub_v = (devfs_handle_t)(long)(arg); 
+    hub_v = (vertex_hdl_t)(long)(arg); 
     ASSERT(hub_v);
 
     hubinfo_get(hub_v, &hinfo);
     
+    idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_ICMR);
+#if 0
+    if (idsr & 0x1) {
+	/* ICMR bit is set .. we are getting into "Spurious Interrupts condition. */
+	printk("Cnode %d II has seen the ICMR condition\n", hinfo->h_cnodeid);
+	printk("***** Please file PV with the above messages *****\n");
+	/* panic("We have to panic to prevent further unknown states ..\n"); */
+    }
+#endif
+	
     /* 
      * Identify the reason for error. 
      */
@@ -218,10 +233,26 @@
 	 * Note: we may never be able to print this, if the II talking
 	 * to Xbow which hosts the console is dead. 
 	 */
-	printk("Hub %d to Xtalk Link failed (II_ECRAZY) Reason: %s", 
-		hinfo->h_cnodeid, reason);
+	ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
+	if (ilcsr.ii_ilcsr_fld_s.i_llp_en == 1) {	/* Link is enabled */
+	    printk("Hub %d, cnode %d to Xtalk Link failed (II_ECRAZY) Reason: %s", 
+		hinfo->h_nasid, hinfo->h_cnodeid, reason);
+	}
     }
 
+
+    /*
+     * Before processing any interrupt related information, clear all
+     * error indication and reenable interrupts.  This will prevent
+     * lost interrupts due to the interrupt handler scanning past a PRB/CRB
+     * which has not errorred yet and then the PRB/CRB goes into error.
+     * Note, PRB errors are cleared individually.
+     */
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, 0xff0000);
+    idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR) & ~IIO_IIDSR_SENT_MASK;
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, idsr);
+
+
     /* 
      * It's a toss as to which one among PRB/CRB to check first. 
      * Current decision is based on the severity of the errors. 
@@ -232,14 +263,6 @@
      */
     (void)hubiio_crb_error_handler(hub_v, hinfo);
     (void)hubiio_prb_error_handler(hub_v, hinfo);
-    /*
-     * If we reach here, it indicates crb/prb handlers successfully
-     * handled the error. So, re-enable II to send more interrupt
-     * and return.
-     */
-    REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, 0xffffff);
-    idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR) & ~IIO_IIDSR_SENT_MASK;
-    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, idsr);
 }
 
 /*
@@ -295,6 +318,105 @@
 	"Xtalk Error Packet"
 };
 
+void
+print_crb_fields(int crb_num, ii_icrb0_a_u_t icrba,
+	ii_icrb0_b_u_t icrbb, ii_icrb0_c_u_t icrbc,
+	ii_icrb0_d_u_t icrbd, ii_icrb0_e_u_t icrbe)
+{
+    printk("CRB %d regA\n\t"
+	    "a_iow 0x%x\n\t"
+	    "valid0x%x\n\t"
+	    "Address0x%lx\n\t"
+	    "a_tnum 0x%x\n\t"
+	    "a_sidn 0x%x\n",
+	    crb_num,
+	    icrba.a_iow, 
+	    icrba.a_valid, 
+	    icrba.a_addr, 
+	    icrba.a_tnum, 
+	    icrba.a_sidn);
+    printk("CRB %d regB\n\t"
+	    "b_imsgtype 0x%x\n\t"
+	    "b_imsg 0x%x\n"
+	    "\tb_use_old 0x%x\n\t"
+	    "b_initiator 0x%x\n\t"
+	    "b_exc 0x%x\n"
+	    "\tb_ackcnt 0x%x\n\t"
+	    "b_resp 0x%x\n\t"
+	    "b_ack 0x%x\n"
+	    "\tb_hold 0x%x\n\t"
+	    "b_wb 0x%x\n\t"
+	    "b_intvn 0x%x\n"
+	    "\tb_stall_ib 0x%x\n\t"
+	    "b_stall_int 0x%x\n"
+	    "\tb_stall_bte_0 0x%x\n\t"
+	    "b_stall_bte_1 0x%x\n"
+	    "\tb_error 0x%x\n\t"
+	    "b_lnetuce 0x%x\n\t"
+	    "b_mark 0x%x\n\t"
+	    "b_xerr 0x%x\n",
+	    crb_num,
+	    icrbb.b_imsgtype, 
+	    icrbb.b_imsg, 
+	    icrbb.b_use_old, 
+	    icrbb.b_initiator,
+	    icrbb.b_exc, 
+	    icrbb.b_ackcnt, 
+	    icrbb.b_resp, 
+	    icrbb.b_ack, 
+	    icrbb.b_hold,
+	    icrbb.b_wb, 
+	    icrbb.b_intvn, 
+	    icrbb.b_stall_ib, 
+	    icrbb.b_stall_int,
+	    icrbb.b_stall_bte_0, 
+	    icrbb.b_stall_bte_1, 
+	    icrbb.b_error,
+	    icrbb.b_lnetuce, 
+	    icrbb.b_mark, 
+	    icrbb.b_xerr);
+    printk("CRB %d regC\n\t"
+	    "c_source 0x%x\n\t"
+	    "c_xtsize 0x%x\n\t"
+	    "c_cohtrans 0x%x\n\t"
+	    "c_btenum 0x%x\n\t"
+	    "c_gbr 0x%x\n\t"
+	    "c_doresp 0x%x\n\t"
+	    "c_barrop 0x%x\n\t"
+	    "c_suppl 0x%x\n",
+	    crb_num,
+	    icrbc.c_source,
+	    icrbc.c_xtsize,
+	    icrbc.c_cohtrans,
+	    icrbc.c_btenum,
+	    icrbc.c_gbr,
+	    icrbc.c_doresp,
+	    icrbc.c_barrop,
+	    icrbc.c_suppl);
+    printk("CRB %d regD\n\t"
+	    "d_bteaddr 0x%lx\n\t"
+	    "d_bteop 0x%x\n\t"
+	    "d_pripsc 0x%x\n\t"
+	    "d_pricnt 0x%x\n\t"
+	    "d_sleep 0x%x\n\t",
+	    crb_num,
+	    icrbd.d_bteaddr,
+	    icrbd.d_bteop,
+	    icrbd.d_pripsc,
+	    icrbd.d_pricnt,
+	    icrbd.d_sleep);
+    printk("CRB %d regE\n\t"
+	    "icrbe_timeout 0x%x\n\t"
+	    "icrbe_context 0x%x\n\t"
+	    "icrbe_toutvld 0x%x\n\t"
+	    "icrbe_ctxtvld 0x%x\n\t",
+	    crb_num,
+	    icrbe.icrbe_timeout,
+	    icrbe.icrbe_context,
+	    icrbe.icrbe_toutvld,
+	    icrbe.icrbe_ctxtvld);
+}
+
 /*
  * hubiio_crb_error_handler
  *
@@ -317,7 +439,7 @@
  */
 
 int
-hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo)
+hubiio_crb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo)
 {
 	cnodeid_t	cnode;
 	nasid_t		nasid;
@@ -335,6 +457,9 @@
 	cnode = NASID_TO_COMPACT_NODEID(nasid);
 
 	/*
+	 * XXX - Add locking for any recovery actions
+	 */
+	/*
 	 * Scan through all CRBs in the Hub, and handle the errors
 	 * in any of the CRBs marked.
 	 */
@@ -373,16 +498,11 @@
 			else /* b_initiator bit 2 gives BTE number */
 				bte_num = (icrbb.b_initiator & 0x4) >> 2;
 
-			/* >>> bte_crb_error_handler needs to be 
-			 * broken into two parts.  The first should
-			 * cleanup the CRB.  The second should wait
-			 * until all bte related CRB's are complete
-			 * and then do the error reset.
-			 */
+			hubiio_crb_free(hinfo, i);
+
 			bte_crb_error_handler(hub_v, bte_num,
 					      i, &ioerror,
 					      icrbd.d_bteop);
-			hubiio_crb_free(hinfo, i);
 			num_errors++;
 			continue;
 		}
@@ -430,6 +550,86 @@
 			IOERROR_SETVALUE(&ioerror, tnum, icrba.a_tnum);
 
 		}
+		if (icrbb.b_error) {
+		    /*
+		     * CRB 'i' has some error. Identify the type of error,
+		     * and try to handle it.
+		     *
+		     */
+		    switch(icrbb.b_ecode) {
+			case IIO_ICRB_ECODE_PERR:
+			case IIO_ICRB_ECODE_WERR:
+			case IIO_ICRB_ECODE_AERR:
+			case IIO_ICRB_ECODE_PWERR:
+			case IIO_ICRB_ECODE_TOUT:
+			case IIO_ICRB_ECODE_XTERR:
+			    printk("Shub II CRB %d: error %s on hub cnodeid: %d",
+				    i, hubiio_crb_errors[icrbb.b_ecode], cnode);
+			    /*
+			     * Any sort of write error is mostly due
+			     * bad programming (Note it's not a timeout.)
+			     * So, invoke hub_iio_error_handler with
+			     * appropriate information.
+			     */
+			    IOERROR_SETVALUE(&ioerror,errortype,icrbb.b_ecode);
+
+			    /* Go through the error bit lookup phase */
+			    if (error_state_set(hub_v, ERROR_STATE_LOOKUP) ==
+				    ERROR_RETURN_CODE_CANNOT_SET_STATE)
+				return(IOERROR_UNHANDLED);
+			    rc = hub_ioerror_handler(
+				    hub_v,
+				    DMA_WRITE_ERROR,
+				    MODE_DEVERROR,
+				    &ioerror);
+			    if (rc == IOERROR_HANDLED) {
+				rc = hub_ioerror_handler(
+					hub_v,
+					DMA_WRITE_ERROR,
+					MODE_DEVREENABLE,
+					&ioerror);
+			    }else {
+				printk("Unable to handle %s on hub %d",
+					hubiio_crb_errors[icrbb.b_ecode],
+					cnode);
+				/* panic; */
+			    }
+			    /* Go to Next error */
+			    print_crb_fields(i, icrba, icrbb, icrbc,
+				    icrbd, icrbe);
+			    hubiio_crb_free(hinfo, i);
+			    continue;
+			case IIO_ICRB_ECODE_PRERR:
+			case IIO_ICRB_ECODE_DERR:
+			    printk("Shub II CRB %d: error %s on hub : %d",
+				    i, hubiio_crb_errors[icrbb.b_ecode], cnode);
+			    /* panic */
+			default:
+			    printk("Shub II CRB error (code : %d) on hub : %d",
+				    icrbb.b_ecode, cnode);
+			    /* panic */
+		    }
+		} 
+		/*
+		 * Error is not indicated via the errcode field
+		 * Check other error indications in this register.
+		 */
+		if (icrbb.b_xerr) {
+		    printk("Shub II CRB %d: Xtalk Packet with error bit set to hub %d",
+			    i, cnode);
+		    /* panic */
+		}
+		if (icrbb.b_lnetuce) {
+		    printk("Shub II CRB %d: Uncorrectable data error detected on data "
+			    " from NUMAlink to node %d",
+			    i, cnode);
+		    /* panic */
+		}
+		print_crb_fields(i, icrba, icrbb, icrbc, icrbd, icrbe);
+
+
+
+
 
 		if (icrbb.b_error) {
 		/* 
@@ -488,7 +688,7 @@
 		
 		default:
 			panic("Fatal error (code : %d) on hub : %d",
-				cnode);
+				icrbb.b_ecode, cnode);
 			/*NOTREACHED*/
 
 		}
@@ -568,7 +768,7 @@
  *      Cleanup involes freeing the PRB register
  */
 static void
-hubii_prb_handler(devfs_handle_t hub_v, hubinfo_t hinfo, int wnum)
+hubii_prb_handler(vertex_hdl_t hub_v, hubinfo_t hinfo, int wnum)
 {
         nasid_t         nasid;
 
@@ -576,13 +776,13 @@
         /*
          * Clear error bit by writing to IECLR register.
          */
-        REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, (1 << wnum));
+        REMOTE_HUB_S(nasid, IIO_IECLR, (1 << wnum));
         /*
          * PIO Write to Widget 'i' got into an error.
          * Invoke hubiio_error_handler with this information.
          */
-        printk( "Hub nasid %d got a PIO Write error from widget %d, cleaning up and continuing",
-                        nasid, wnum);
+        printk( "Hub nasid %d got a PIO Write error from widget %d, "
+				"cleaning up and continuing", nasid, wnum);
         /*
          * XXX
          * It may be necessary to adjust IO PRB counter
@@ -591,7 +791,7 @@
 }
 
 int
-hubiio_prb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo)
+hubiio_prb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo)
 {
         int             wnum;
         nasid_t         nasid;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/shubio.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/shubio.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/shubio.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/shubio.c	2003-08-01 13:33:09.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000,2002-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -30,8 +30,8 @@
 #include <asm/sn/sn2/shubio.h>
 
 
-error_state_t error_state_get(devfs_handle_t v);
-error_return_code_t error_state_set(devfs_handle_t v,error_state_t new_state);
+error_state_t error_state_get(vertex_hdl_t v);
+error_return_code_t error_state_set(vertex_hdl_t v,error_state_t new_state);
 
 
 /*
@@ -42,7 +42,7 @@
 /*ARGSUSED*/
 int
 hub_xp_error_handler(
-	devfs_handle_t 	hub_v, 
+	vertex_hdl_t 	hub_v, 
 	nasid_t		nasid, 
 	int		error_code, 
 	ioerror_mode_t	mode, 
@@ -50,7 +50,7 @@
 {
 	/*REFERENCED*/
 	hubreg_t	iio_imem;
-	devfs_handle_t	xswitch;
+	vertex_hdl_t	xswitch;
 	error_state_t	e_state;
 	cnodeid_t	cnode;
 
@@ -148,7 +148,7 @@
  */
 int
 hub_ioerror_handler(
-	devfs_handle_t 	hub_v, 
+	vertex_hdl_t 	hub_v, 
 	int		error_code,
 	int		mode,
 	struct io_error_s	*ioerror)
@@ -158,6 +158,7 @@
 	int		retval = 0;
 	/*REFERENCED*/
 	iopaddr_t 	p;
+	caddr_t 	cp;
 
 	IOERROR_DUMP("hub_ioerror_handler", error_code, mode, ioerror);
 
@@ -193,14 +194,14 @@
 		 * This is typically true for user mode bus errors while
 		 * accessing I/O space.
 		 */
-		 IOERROR_GETVALUE(p,ioerror,vaddr);
-		 if (p){
+		 IOERROR_GETVALUE(cp,ioerror,vaddr);
+		 if (cp){
 		    /* 
 		     * If neither in small window nor in large window range,
 		     * outright reject it.
 		     */
-		    IOERROR_GETVALUE(p,ioerror,vaddr);
-		    if (NODE_SWIN_ADDR(nasid, (paddr_t)p)){
+		    IOERROR_GETVALUE(cp,ioerror,vaddr);
+		    if (NODE_SWIN_ADDR(nasid, (paddr_t)cp)){
 			iopaddr_t	hubaddr;
 			xwidgetnum_t	widgetnum;
 			iopaddr_t	xtalkaddr;
@@ -216,7 +217,7 @@
 			IOERROR_SETVALUE(ioerror,xtalkaddr,xtalkaddr);
 
 
-		    } else if (NODE_BWIN_ADDR(nasid, (paddr_t)p)){
+		    } else if (NODE_BWIN_ADDR(nasid, (paddr_t)cp)){
 			/* 
 			 * Address corresponds to large window space. 
 			 * Convert it to xtalk address.
@@ -428,11 +429,6 @@
 	return retval;
 }
 
-#define L_BITSMINOR 18
-#define L_MAXMAJ 0x1ff
-#define emajor(x) (int )(((unsigned )(x)>>L_BITSMINOR) & L_MAXMAJ)
-#define dev_is_vertex(dev) (emajor((dev_t)(dev)) == 0)
-
 #define INFO_LBL_ERROR_STATE    "error_state"
 
 #define v_error_state_get(v,s)                                          \
@@ -454,12 +450,12 @@
  *                      current state otherwise
  */
 error_state_t
-error_state_get(devfs_handle_t v)
+error_state_get(vertex_hdl_t v)
 {
         error_state_t   s;
 
         /* Check if we have a valid hwgraph vertex */
-        if (!dev_is_vertex(v))
+        if ( v == (vertex_hdl_t)0 )
                 return(ERROR_STATE_NONE);
 
         /* Get the labelled info hanging off the vertex which corresponds
@@ -479,13 +475,13 @@
  *                      ERROR_RETURN_CODE_SUCCESS otherwise
  */
 error_return_code_t
-error_state_set(devfs_handle_t v,error_state_t new_state)
+error_state_set(vertex_hdl_t v,error_state_t new_state)
 {
         error_state_t   old_state;
         boolean_t       replace = B_TRUE;
 
         /* Check if we have a valid hwgraph vertex */
-        if (!dev_is_vertex(v))
+        if ( v == (vertex_hdl_t)0 )
                 return(ERROR_RETURN_CODE_GENERAL_FAILURE);
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/xbow.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/xbow.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/xbow.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/xbow.c	2003-08-01 13:31:44.000000000 +0000
@@ -4,12 +4,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/interrupt.h>
 #include <asm/sn/sgi.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/sn2/sn_private.h>
@@ -18,7 +20,6 @@
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
-#include <asm/sn/hack.h>
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/xtalk/xtalk_private.h>
 #include <asm/sn/simulator.h>
@@ -44,8 +45,6 @@
 #define NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
 #define DEL(ptr)	(kfree(ptr))
 
-int                     xbow_devflag = D_MP;
-
 /*
  * This file supports the Xbow chip.  Main functions: initializtion,
  * error handling, and GBR.
@@ -59,9 +58,9 @@
 typedef struct xbow_soft_s *xbow_soft_t;
 
 struct xbow_soft_s {
-    devfs_handle_t            conn;	/* our connection point */
-    devfs_handle_t            vhdl;	/* xbow's private vertex */
-    devfs_handle_t            busv;	/* the xswitch vertex */
+    vertex_hdl_t            conn;	/* our connection point */
+    vertex_hdl_t            vhdl;	/* xbow's private vertex */
+    vertex_hdl_t            busv;	/* the xswitch vertex */
     xbow_t                 *base;	/* PIO pointer to crossbow chip */
     char                   *name;	/* hwgraph name */
 
@@ -89,36 +88,27 @@
  */
 
 void                    xbow_mlreset(xbow_t *);
-void                    xbow_init(void);
-int                     xbow_attach(devfs_handle_t);
-
-int                     xbow_open(devfs_handle_t *, int, int, cred_t *);
-int                     xbow_close(devfs_handle_t, int, int, cred_t *);
-
-int                     xbow_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                     xbow_unmap(devfs_handle_t, vhandl_t *);
-int                     xbow_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
+int                     xbow_attach(vertex_hdl_t);
 
 int                     xbow_widget_present(xbow_t *, int);
 static int              xbow_link_alive(xbow_t *, int);
-devfs_handle_t            xbow_widget_lookup(devfs_handle_t, int);
+vertex_hdl_t            xbow_widget_lookup(vertex_hdl_t, int);
 
 void                    xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
 
 
 
-void                    xbow_update_perf_counters(devfs_handle_t);
-xbow_perf_link_t       *xbow_get_perf_counters(devfs_handle_t);
-int                     xbow_enable_perf_counter(devfs_handle_t, int, int, int);
-xbow_link_status_t     *xbow_get_llp_status(devfs_handle_t);
-void                    xbow_update_llp_status(devfs_handle_t);
-
-int                     xbow_disable_llp_monitor(devfs_handle_t);
-int                     xbow_enable_llp_monitor(devfs_handle_t);
-int                     xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t,
+void                    xbow_update_perf_counters(vertex_hdl_t);
+xbow_perf_link_t       *xbow_get_perf_counters(vertex_hdl_t);
+int                     xbow_enable_perf_counter(vertex_hdl_t, int, int, int);
+xbow_link_status_t     *xbow_get_llp_status(vertex_hdl_t);
+void                    xbow_update_llp_status(vertex_hdl_t);
+
+int                     xbow_disable_llp_monitor(vertex_hdl_t);
+int                     xbow_enable_llp_monitor(vertex_hdl_t);
+int                     xbow_prio_bw_alloc(vertex_hdl_t, xwidgetnum_t, xwidgetnum_t,
                                 unsigned long long, unsigned long long);
 static void		xbow_setwidint(xtalk_intr_t);
-void                    idbg_xbowregs(int64_t);
 
 xswitch_reset_link_f    xbow_reset_link;
 
@@ -127,6 +117,32 @@
     xbow_reset_link,
 };
 
+
+static int
+xbow_mmap(struct file * file, struct vm_area_struct * vma)
+{
+        unsigned long           phys_addr;
+        int                     error = 0;
+
+        phys_addr = (unsigned long)file->private_data & ~0xc000000000000000; /* Mask out the Uncache bits */
+        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+        vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
+        error = io_remap_page_range(vma->vm_start, phys_addr,
+                                   vma->vm_end-vma->vm_start,
+                                   vma->vm_page_prot);
+        return(error);
+}
+
+/*
+ * This is the file operation table for the pcibr driver.
+ * As each of the functions are implemented, put the
+ * appropriate function name below.
+ */
+struct file_operations xbow_fops = {
+        .owner		= THIS_MODULE,
+        .mmap		= xbow_mmap,
+};
+
 /*
  *    xbow_mlreset: called at mlreset time if the
  *      platform specific code determines that there is
@@ -144,39 +160,6 @@
 {
 }
 
-/*
- *    xbow_init: called with the rest of the device
- *      driver XXX_init routines. This platform *might*
- *      have a Crossbow chip, or even several, but it
- *      might have none. Register with the crosstalk
- *      generic provider so when we encounter the chip
- *      the right magic happens.
- */
-void
-xbow_init(void)
-{
-
-#if DEBUG && ATTACH_DEBUG
-    printk("xbow_init\n");
-#endif
-
-    xwidget_driver_register(PXBOW_WIDGET_PART_NUM,
-			    0, /* XXBOW_WIDGET_MFGR_NUM, */
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-
-
-    xwidget_driver_register(XXBOW_WIDGET_PART_NUM,
-			    0, /* XXBOW_WIDGET_MFGR_NUM, */
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-
-    xwidget_driver_register(XBOW_WIDGET_PART_NUM,
-			    XBOW_WIDGET_MFGR_NUM,
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-}
-
 #ifdef XBRIDGE_REGS_SIM
 /*    xbow_set_simulated_regs: sets xbow regs as needed
  *	for powering through the boot
@@ -213,11 +196,11 @@
 
 /*ARGSUSED */
 int
-xbow_attach(devfs_handle_t conn)
+xbow_attach(vertex_hdl_t conn)
 {
     /*REFERENCED */
-    devfs_handle_t            vhdl;
-    devfs_handle_t            busv;
+    vertex_hdl_t            vhdl;
+    vertex_hdl_t            busv;
     xbow_t                 *xbow;
     xbow_soft_t             soft;
     int                     port;
@@ -274,15 +257,14 @@
      */
 
     /*
-     * We need to teach xbow drivers to provide the right set of
+     * Register a xbow driver with devfs.
      * file ops.
      */
     vhdl = NULL;
-    vhdl = hwgraph_register(conn, EDGE_LBL_XBOW,
-                        0, DEVFS_FL_AUTO_DEVNUM,
-                        0, 0,
-                        S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                        /* &hcl_fops */ (void *)&vhdl, NULL);
+    vhdl = hwgraph_register(conn, EDGE_LBL_XBOW, 0,
+	   DEVFS_FL_AUTO_DEVNUM, 0, 0,
+	   S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+	   (struct file_operations *)&xbow_fops, (void *)xbow);
     if (!vhdl) {
         printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n",
                 (void *)conn);
@@ -299,7 +281,7 @@
     soft->base = xbow;
     /* does the universe really need another macro?  */
     /* xbow_soft_set(vhdl, (arbitrary_info_t) soft); */
-    hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft);
+    /* hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft); */
 
 #define XBOW_NUM_SUFFIX_FORMAT	"[xbow# %d]"
 
@@ -350,6 +332,14 @@
       */
      intr_hdl = xtalk_intr_alloc(conn, (device_desc_t)0, vhdl);
      ASSERT(intr_hdl != NULL);
+
+        {
+                int irq = ((hub_intr_t)intr_hdl)->i_bit;
+                int cpu = ((hub_intr_t)intr_hdl)->i_cpuid;
+
+                intr_unreserve_level(cpu, irq);
+                ((hub_intr_t)intr_hdl)->i_bit = SGI_XBOW_ERROR;
+        }
  
      xtalk_intr_connect(intr_hdl,
                         (intr_func_t) xbow_errintr_handler,
@@ -357,19 +347,9 @@
                         (xtalk_intr_setfunc_t) xbow_setwidint,
                         (void *) xbow);
 
-#ifdef BUS_INT_WAR_NOT_YET
-     request_irq(CPU_VECTOR_TO_IRQ(((hub_intr_t)intr_hdl)->i_cpuid,
-			((hub_intr_t)intr_hdl)->i_bit),
-			(intr_func_t)xbow_errintr_handler, 0, "XBOW error",
+     request_irq(SGI_XBOW_ERROR, (void *)xbow_errintr_handler, SA_SHIRQ, "XBOW error",
 			(intr_arg_t) soft);
 
-    {
-	void sn_add_polled_interrupt(int, int);
-        sn_add_polled_interrupt(CPU_VECTOR_TO_IRQ(((hub_intr_t)intr_hdl)->i_cpuid,
-                                ((hub_intr_t)intr_hdl)->i_bit), 5000);
-    }
-#endif
-
  
     /*
      * Enable xbow error interrupts
@@ -439,50 +419,14 @@
     return 0;				/* attach successful */
 }
 
-/*ARGSUSED */
-int
-xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-xbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    xbow_soft_t             soft = xbow_soft_get(vhdl);
-    int                     error;
-
-    ASSERT(soft);
-    len = ctob(btoc(len));
-    /* XXX- this ignores the offset!!! */
-    error = v_mapphys(vt, (void *) soft->base, len);
-    return error;
-}
-
-/*ARGSUSED */
-int
-xbow_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    return 0;
-}
-
 /* This contains special-case code for grio. There are plans to make
  * this general sometime in the future, but till then this should
  * be good enough.
  */
 xwidgetnum_t
-xbow_widget_num_get(devfs_handle_t dev)
+xbow_widget_num_get(vertex_hdl_t dev)
 {
-	devfs_handle_t	tdev;
+	vertex_hdl_t	tdev;
 	char		devname[MAXDEVNAME];
 	xwidget_info_t	xwidget_info;
 	int		i;
@@ -512,58 +456,6 @@
 	return XWIDGET_NONE;
 }
 
-int
-xbow_ioctl(devfs_handle_t dev,
-	   int cmd,
-	   void *arg,
-	   int flag,
-	   struct cred *cr,
-	   int *rvalp)
-{
-    devfs_handle_t            vhdl;
-    int                     error = 0;
-
-#if defined (DEBUG)
-    int                     rc;
-    devfs_handle_t            conn;
-    struct xwidget_info_s  *xwidget_info;
-    xbow_soft_t             xbow_soft;
-#endif
-    *rvalp = 0;
-
-    vhdl = dev_to_vhdl(dev);
-#if defined (DEBUG)
-    xbow_soft = xbow_soft_get(vhdl);
-    conn = xbow_soft->conn;
-
-    xwidget_info = xwidget_info_get(conn);
-    ASSERT_ALWAYS(xwidget_info != NULL);
-
-    rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid);
-    ASSERT_ALWAYS(rc != 0);
-#endif
-    switch (cmd) {
-
-    case XBOWIOC_LLP_ERROR_ENABLE:
-	if ((error = xbow_enable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-    case XBOWIOC_LLP_ERROR_DISABLE:
-
-	if ((error = xbow_disable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-    default:
-	break;
-
-    }
-    return error;
-}
-
 /*
  * xbow_widget_present: See if a device is present
  * on the specified port of this crossbow.
@@ -605,12 +497,12 @@
  *      specified.
  *      If not found, return 0.
  */
-devfs_handle_t
-xbow_widget_lookup(devfs_handle_t vhdl,
+vertex_hdl_t
+xbow_widget_lookup(vertex_hdl_t vhdl,
 		   int widgetnum)
 {
     xswitch_info_t          xswitch_info;
-    devfs_handle_t            conn;
+    vertex_hdl_t            conn;
 
     xswitch_info = xswitch_info_get(vhdl);
     conn = xswitch_info_vhdl_get(xswitch_info, widgetnum);
@@ -660,10 +552,6 @@
 			      XTALK_ADDR_TO_UPPER(addr));
     xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
 
-#ifdef BRINGUP2
-printk("xbow_intr_preset: xb_wid_int_upper 0x%lx xb_wid_int_lower 0x%lx\n",
-	(long)(((0xFF000000 & (vect << 24)) | (0x000F0000 & (targ << 16)) |XTALK_ADDR_TO_UPPER(addr))), (long)XTALK_ADDR_TO_LOWER(addr));
-#endif
 }
 
 #define	XEM_ADD_STR(s)		printk("%s", (s))
@@ -674,48 +562,14 @@
 				    XEM_ADD_NVAR("ioe." #n, p);		\
 				}
 
-#ifdef LATER
-static void
-xem_add_ioe(ioerror_t *ioe)
-{
-    union tmp {
-	ushort stmp;
-	unsigned long long lltmp;
-	cpuid_t cputmp;
-	cnodeid_t cntmp;
-	iopaddr_t iotmp;
-	caddr_t catmp;
-	paddr_t patmp;
-    } tmp;
-
-    XEM_ADD_IOEF(tmp.stmp, errortype);
-    XEM_ADD_IOEF(tmp.stmp, widgetnum);
-    XEM_ADD_IOEF(tmp.stmp, widgetdev);
-    XEM_ADD_IOEF(tmp.cputmp, srccpu);
-    XEM_ADD_IOEF(tmp.cntmp, srcnode);
-    XEM_ADD_IOEF(tmp.cntmp, errnode);
-    XEM_ADD_IOEF(tmp.iotmp, sysioaddr);
-    XEM_ADD_IOEF(tmp.iotmp, xtalkaddr);
-    XEM_ADD_IOEF(tmp.iotmp, busspace);
-    XEM_ADD_IOEF(tmp.iotmp, busaddr);
-    XEM_ADD_IOEF(tmp.catmp, vaddr);
-    XEM_ADD_IOEF(tmp.patmp, memaddr);
-    XEM_ADD_IOEF(tmp.catmp, epc);
-    XEM_ADD_IOEF(tmp.catmp, ef);
-    XEM_ADD_IOEF(tmp.stmp, tnum);
-}
-
-#define XEM_ADD_IOE()   (xem_add_ioe(ioe))
-#endif	/* LATER */
-
-int                     xbow_xmit_retry_errors = 0;
+int                     xbow_xmit_retry_errors;
 
 int
 xbow_xmit_retry_error(xbow_soft_t soft,
 		      int port)
 {
     xswitch_info_t          info;
-    devfs_handle_t            vhdl;
+    vertex_hdl_t            vhdl;
     widget_cfg_t           *wid;
     widgetreg_t             id;
     int                     part;
@@ -865,7 +719,7 @@
 		    link_pend &= ~XB_STAT_XMT_RTRY_ERR;
 		}
 		if (link_pend) {
-		    devfs_handle_t	xwidget_vhdl;
+		    vertex_hdl_t	xwidget_vhdl;
 		    char		*xwidget_name;
 		    
 		    /* Get the widget name corresponding to the current
@@ -917,12 +771,6 @@
 			XEM_ADD_VAR(link_status);
 			XEM_ADD_VAR(link_aux_status);
 
-#ifdef LATER
-			if (dump_ioe) {
-			    XEM_ADD_IOE();
-			    dump_ioe = 0;
-			}
-#endif
 #if !DEBUG
 		    }
 #endif
@@ -987,8 +835,8 @@
 
     xbow_soft_t             soft = (xbow_soft_t) einfo;
     int                     port;
-    devfs_handle_t          conn;
-    devfs_handle_t          busv;
+    vertex_hdl_t          conn;
+    vertex_hdl_t          busv;
 
     xbow_t                 *xbow = soft->base;
     xbowreg_t               wid_stat;
@@ -1240,7 +1088,7 @@
 }
 
 void
-xbow_update_perf_counters(devfs_handle_t vhdl)
+xbow_update_perf_counters(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
@@ -1268,7 +1116,7 @@
 }
 
 xbow_perf_link_t       *
-xbow_get_perf_counters(devfs_handle_t vhdl)
+xbow_get_perf_counters(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_perf_link_t       *xbow_perf_link = xbow_soft->xbow_perflink;
@@ -1277,7 +1125,7 @@
 }
 
 int
-xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter)
+xbow_enable_perf_counter(vertex_hdl_t vhdl, int link, int mode, int counter)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
@@ -1331,7 +1179,7 @@
 }
 
 xbow_link_status_t     *
-xbow_get_llp_status(devfs_handle_t vhdl)
+xbow_get_llp_status(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
@@ -1340,7 +1188,7 @@
 }
 
 void
-xbow_update_llp_status(devfs_handle_t vhdl)
+xbow_update_llp_status(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
@@ -1348,7 +1196,7 @@
     xbwX_stat_t             lnk_sts;
     xbow_aux_link_status_t  aux_sts;
     int                     link;
-    devfs_handle_t	    xwidget_vhdl;
+    vertex_hdl_t	    xwidget_vhdl;
     char		   *xwidget_name;	
 
     xbow = (xbow_t *) xbow_soft->base;
@@ -1382,7 +1230,7 @@
 }
 
 int
-xbow_disable_llp_monitor(devfs_handle_t vhdl)
+xbow_disable_llp_monitor(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     int                     port;
@@ -1397,7 +1245,7 @@
 }
 
 int
-xbow_enable_llp_monitor(devfs_handle_t vhdl)
+xbow_enable_llp_monitor(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
 
@@ -1407,7 +1255,7 @@
 
 
 int
-xbow_reset_link(devfs_handle_t xconn_vhdl)
+xbow_reset_link(vertex_hdl_t xconn_vhdl)
 {
     xwidget_info_t          widget_info;
     xwidgetnum_t            port;
@@ -1430,7 +1278,7 @@
     xbow = XBOW_K1PTR;
 #else
     {
-	devfs_handle_t            xbow_vhdl;
+	vertex_hdl_t            xbow_vhdl;
 	xbow_soft_t             xbow_soft;
 
 	hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl);
@@ -1463,46 +1311,6 @@
     return 0;
 }
 
-/*
- * Dump xbow registers.
- * input parameter is either a pointer to
- * the xbow chip or the vertex handle for
- * an xbow vertex.
- */
-void
-idbg_xbowregs(int64_t regs)
-{
-    xbow_t                 *xbow;
-    int                     i;
-    xb_linkregs_t          *link;
-
-    xbow = (xbow_t *) regs;
-
-#ifdef LATER
-    qprintf("Printing xbow registers starting at 0x%x\n", xbow);
-    qprintf("wid %x status %x erruppr %x errlower %x control %x timeout %x\n",
-	    xbow->xb_wid_id, xbow->xb_wid_stat, xbow->xb_wid_err_upper,
-	    xbow->xb_wid_err_lower, xbow->xb_wid_control,
-	    xbow->xb_wid_req_timeout);
-    qprintf("intr uppr %x lower %x errcmd %x llp ctrl %x arb_reload %x\n",
-	    xbow->xb_wid_int_upper, xbow->xb_wid_int_lower,
-	    xbow->xb_wid_err_cmdword, xbow->xb_wid_llp,
-	    xbow->xb_wid_arb_reload);
-#endif
-
-    for (i = 8; i <= 0xf; i++) {
-	link = &xbow->xb_link(i);
-#ifdef LATER
-	qprintf("Link %d registers\n", i);
-	qprintf("\tctrl %x stat %x arbuppr %x arblowr %x auxstat %x\n",
-		link->link_control, link->link_status,
-		link->link_arb_upper, link->link_arb_lower,
-		link->link_aux_status);
-#endif
-    }
-}
-
-
 #define XBOW_ARB_RELOAD_TICKS		25
 					/* granularity: 4 MB/s, max: 124 MB/s */
 #define GRANULARITY			((100 * 1000000) / XBOW_ARB_RELOAD_TICKS)
@@ -1562,7 +1370,7 @@
  * If bandwidth allocation is successful, return success else return failure.
  */
 int
-xbow_prio_bw_alloc(devfs_handle_t vhdl,
+xbow_prio_bw_alloc(vertex_hdl_t vhdl,
 		xwidgetnum_t src_wid,
 		xwidgetnum_t dest_wid,
 		unsigned long long old_alloc_bw,
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/sn2/xtalk.c linux-2.4.22-pre10/arch/ia64/sn/io/sn2/xtalk.c
--- linux-2.4.21/arch/ia64/sn/io/sn2/xtalk.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/sn2/xtalk.c	2003-08-01 13:33:21.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -37,8 +37,6 @@
 
 char                    widget_info_fingerprint[] = "widget_info";
 
-cdl_p                   xtalk_registry = NULL;
-
 #define	DEV_FUNC(dev,func)	hub_##func
 #define	CAST_PIOMAP(x)		((hub_piomap_t)(x))
 #define	CAST_DMAMAP(x)		((hub_dmamap_t)(x))
@@ -47,71 +45,70 @@
 /* =====================================================================
  *            Function Table of Contents
  */
-xtalk_piomap_t          xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);
+xtalk_piomap_t          xtalk_piomap_alloc(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);
 void                    xtalk_piomap_free(xtalk_piomap_t);
 caddr_t                 xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t);
 void                    xtalk_piomap_done(xtalk_piomap_t);
-caddr_t                 xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned);
-caddr_t                 xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);
+caddr_t                 xtalk_piotrans_addr(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, unsigned);
+caddr_t                 xtalk_pio_addr(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);
 void                    xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *);
 caddr_t                 xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
 static caddr_t          null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
-xtalk_dmamap_t          xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
+xtalk_dmamap_t          xtalk_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned);
 void                    xtalk_dmamap_free(xtalk_dmamap_t);
 iopaddr_t               xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t);
 alenlist_t              xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned);
 void                    xtalk_dmamap_done(xtalk_dmamap_t);
-iopaddr_t               xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
+iopaddr_t               xtalk_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned);
+alenlist_t              xtalk_dmatrans_list(vertex_hdl_t, device_desc_t, alenlist_t, unsigned);
 void			xtalk_dmamap_drain(xtalk_dmamap_t);
-void			xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t);
-void			xtalk_dmalist_drain(devfs_handle_t, alenlist_t);
-xtalk_intr_t            xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t);
-xtalk_intr_t            xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t);
+void			xtalk_dmaaddr_drain(vertex_hdl_t, iopaddr_t, size_t);
+void			xtalk_dmalist_drain(vertex_hdl_t, alenlist_t);
+xtalk_intr_t            xtalk_intr_alloc(vertex_hdl_t, device_desc_t, vertex_hdl_t);
+xtalk_intr_t            xtalk_intr_alloc_nothd(vertex_hdl_t, device_desc_t, vertex_hdl_t);
 void                    xtalk_intr_free(xtalk_intr_t);
 int                     xtalk_intr_connect(xtalk_intr_t, intr_func_t, intr_arg_t, xtalk_intr_setfunc_t, void *);
 void                    xtalk_intr_disconnect(xtalk_intr_t);
-devfs_handle_t            xtalk_intr_cpu_get(xtalk_intr_t);
-int                     xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
-int                     xtalk_error_devenable(devfs_handle_t, int, int);
-void                    xtalk_provider_startup(devfs_handle_t);
-void                    xtalk_provider_shutdown(devfs_handle_t);
-devfs_handle_t            xtalk_intr_dev_get(xtalk_intr_t);
+vertex_hdl_t            xtalk_intr_cpu_get(xtalk_intr_t);
+int                     xtalk_error_handler(vertex_hdl_t, int, ioerror_mode_t, ioerror_t *);
+int                     xtalk_error_devenable(vertex_hdl_t, int, int);
+void                    xtalk_provider_startup(vertex_hdl_t);
+void                    xtalk_provider_shutdown(vertex_hdl_t);
+vertex_hdl_t            xtalk_intr_dev_get(xtalk_intr_t);
 xwidgetnum_t            xtalk_intr_target_get(xtalk_intr_t);
 xtalk_intr_vector_t     xtalk_intr_vector_get(xtalk_intr_t);
 iopaddr_t               xtalk_intr_addr_get(struct xtalk_intr_s *);
 void                   *xtalk_intr_sfarg_get(xtalk_intr_t);
-devfs_handle_t            xtalk_pio_dev_get(xtalk_piomap_t);
+vertex_hdl_t            xtalk_pio_dev_get(xtalk_piomap_t);
 xwidgetnum_t            xtalk_pio_target_get(xtalk_piomap_t);
 iopaddr_t               xtalk_pio_xtalk_addr_get(xtalk_piomap_t);
 ulong                   xtalk_pio_mapsz_get(xtalk_piomap_t);
 caddr_t                 xtalk_pio_kvaddr_get(xtalk_piomap_t);
-devfs_handle_t            xtalk_dma_dev_get(xtalk_dmamap_t);
+vertex_hdl_t            xtalk_dma_dev_get(xtalk_dmamap_t);
 xwidgetnum_t            xtalk_dma_target_get(xtalk_dmamap_t);
-xwidget_info_t          xwidget_info_chk(devfs_handle_t);
-xwidget_info_t          xwidget_info_get(devfs_handle_t);
-void                    xwidget_info_set(devfs_handle_t, xwidget_info_t);
-devfs_handle_t            xwidget_info_dev_get(xwidget_info_t);
+xwidget_info_t          xwidget_info_chk(vertex_hdl_t);
+xwidget_info_t          xwidget_info_get(vertex_hdl_t);
+void                    xwidget_info_set(vertex_hdl_t, xwidget_info_t);
+vertex_hdl_t            xwidget_info_dev_get(xwidget_info_t);
 xwidgetnum_t            xwidget_info_id_get(xwidget_info_t);
-devfs_handle_t            xwidget_info_master_get(xwidget_info_t);
+vertex_hdl_t            xwidget_info_master_get(xwidget_info_t);
 xwidgetnum_t            xwidget_info_masterid_get(xwidget_info_t);
 xwidget_part_num_t      xwidget_info_part_num_get(xwidget_info_t);
 xwidget_mfg_num_t       xwidget_info_mfg_num_get(xwidget_info_t);
 char 			*xwidget_info_name_get(xwidget_info_t);
-void                    xtalk_init(void);
-void                    xtalk_provider_register(devfs_handle_t, xtalk_provider_t *);
-void                    xtalk_provider_unregister(devfs_handle_t);
-xtalk_provider_t       *xtalk_provider_fns_get(devfs_handle_t);
+void                    xtalk_provider_register(vertex_hdl_t, xtalk_provider_t *);
+void                    xtalk_provider_unregister(vertex_hdl_t);
+xtalk_provider_t       *xtalk_provider_fns_get(vertex_hdl_t);
 int                     xwidget_driver_register(xwidget_part_num_t, 
 						xwidget_mfg_num_t, 
 						char *, unsigned);
 void                    xwidget_driver_unregister(char *);
-int                     xwidget_register(xwidget_hwid_t, devfs_handle_t, 
-					 xwidgetnum_t, devfs_handle_t, 
-					 xwidgetnum_t, async_attach_t);
-int			xwidget_unregister(devfs_handle_t);
-void                    xwidget_reset(devfs_handle_t);
-char			*xwidget_name_get(devfs_handle_t);
+int                     xwidget_register(xwidget_hwid_t, vertex_hdl_t, 
+					 xwidgetnum_t, vertex_hdl_t, 
+					 xwidgetnum_t);
+int			xwidget_unregister(vertex_hdl_t);
+void                    xwidget_reset(vertex_hdl_t);
+char			*xwidget_name_get(vertex_hdl_t);
 #if !defined(DEV_FUNC)
 /*
  * There is more than one possible provider
@@ -126,7 +123,7 @@
 #define	CAST_INTR(x)		((xtalk_intr_t)(x))
 
 static xtalk_provider_t *
-xwidget_to_provider_fns(devfs_handle_t xconn)
+xwidget_to_provider_fns(vertex_hdl_t xconn)
 {
     xwidget_info_t          widget_info;
     xtalk_provider_t       *provider_fns;
@@ -159,7 +156,7 @@
  */
 
 xtalk_piomap_t
-xtalk_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
+xtalk_piomap_alloc(vertex_hdl_t dev,	/* set up mapping for this device */
 		   device_desc_t dev_desc,	/* device descriptor */
 		   iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
 		   size_t byte_count,
@@ -198,7 +195,7 @@
 
 
 caddr_t
-xtalk_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
+xtalk_piotrans_addr(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    iopaddr_t xtalk_addr,	/* Crosstalk address */
 		    size_t byte_count,	/* map this many bytes */
@@ -209,7 +206,7 @@
 }
 
 caddr_t
-xtalk_pio_addr(devfs_handle_t dev,	/* translate for this device */
+xtalk_pio_addr(vertex_hdl_t dev,	/* translate for this device */
 	       device_desc_t dev_desc,	/* device descriptor */
 	       iopaddr_t addr,		/* starting address (or offset in window) */
 	       size_t byte_count,	/* map this many bytes */
@@ -326,7 +323,7 @@
  */
 
 xtalk_dmamap_t
-xtalk_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
+xtalk_dmamap_alloc(vertex_hdl_t dev,	/* set up mappings for this device */
 		   device_desc_t dev_desc,	/* device descriptor */
 		   size_t byte_count_max,	/* max size of a mapping */
 		   unsigned flags)
@@ -373,7 +370,7 @@
 
 
 iopaddr_t
-xtalk_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
+xtalk_dmatrans_addr(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    paddr_t paddr,	/* system physical address */
 		    size_t byte_count,	/* length */
@@ -385,7 +382,7 @@
 
 
 alenlist_t
-xtalk_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
+xtalk_dmatrans_list(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    alenlist_t palenlist,	/* system address/length list */
 		    unsigned flags)
@@ -402,14 +399,14 @@
 }
 
 void
-xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
+xtalk_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size)
 {
     DEV_FUNC(dev, dmaaddr_drain)
 	(dev, addr, size);
 }
 
 void
-xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list)
+xtalk_dmalist_drain(vertex_hdl_t dev, alenlist_t list)
 {
     DEV_FUNC(dev, dmalist_drain)
 	(dev, list);
@@ -426,9 +423,9 @@
  * Return resource handle in intr_hdl.
  */
 xtalk_intr_t
-xtalk_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
+xtalk_intr_alloc(vertex_hdl_t dev,	/* which Crosstalk device */
 		 device_desc_t dev_desc,	/* device descriptor */
-		 devfs_handle_t owner_dev)
+		 vertex_hdl_t owner_dev)
 {				/* owner of this interrupt */
     return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc)
 	(dev, dev_desc, owner_dev);
@@ -440,9 +437,9 @@
  * Return resource handle in intr_hdl.
  */
 xtalk_intr_t
-xtalk_intr_alloc_nothd(devfs_handle_t dev,	/* which Crosstalk device */
+xtalk_intr_alloc_nothd(vertex_hdl_t dev,	/* which Crosstalk device */
 		 	device_desc_t dev_desc,	/* device descriptor */
-		 	devfs_handle_t owner_dev)	/* owner of this interrupt */
+		 	vertex_hdl_t owner_dev)	/* owner of this interrupt */
 {
     return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd)
 	(dev, dev_desc, owner_dev);
@@ -492,11 +489,10 @@
  * Return a hwgraph vertex that represents the CPU currently
  * targeted by an interrupt.
  */
-devfs_handle_t
+vertex_hdl_t
 xtalk_intr_cpu_get(xtalk_intr_t intr_hdl)
 {
-    return INTR_FUNC(intr_hdl, intr_cpu_get)
-	(CAST_INTR(intr_hdl));
+      return (vertex_hdl_t)0;
 }
 
 
@@ -526,7 +522,7 @@
  */
 int
 xtalk_error_handler(
-		       devfs_handle_t xconn,
+		       vertex_hdl_t xconn,
 		       int error_code,
 		       ioerror_mode_t mode,
 		       ioerror_t *ioerror)
@@ -555,7 +551,7 @@
 #if defined(SUPPORT_PRINTING_V_FORMAT)
     printk(KERN_WARNING "Xbow at %v encountered Fatal error", xconn);
 #else
-    printk(KERN_WARNING "Xbow at 0x%p encountered Fatal error", xconn);
+    printk(KERN_WARNING "Xbow at 0x%p encountered Fatal error", (void *)xconn);
 #endif
     ioerror_dump("xtalk", error_code, mode, ioerror);
 
@@ -563,7 +559,7 @@
 }
 
 int
-xtalk_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
+xtalk_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code)
 {
     return DEV_FUNC(xconn_vhdl, error_devenable) (xconn_vhdl, devnum, error_code);
 }
@@ -577,7 +573,7 @@
  * Startup a crosstalk provider
  */
 void
-xtalk_provider_startup(devfs_handle_t xtalk_provider)
+xtalk_provider_startup(vertex_hdl_t xtalk_provider)
 {
     DEV_FUNC(xtalk_provider, provider_startup)
 	(xtalk_provider);
@@ -588,7 +584,7 @@
  * Shutdown a crosstalk provider
  */
 void
-xtalk_provider_shutdown(devfs_handle_t xtalk_provider)
+xtalk_provider_shutdown(vertex_hdl_t xtalk_provider)
 {
     DEV_FUNC(xtalk_provider, provider_shutdown)
 	(xtalk_provider);
@@ -598,22 +594,22 @@
  * Enable a device on a xtalk widget 
  */
 void
-xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum)
+xtalk_widgetdev_enable(vertex_hdl_t xconn_vhdl, int devnum)
 {
-    DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum);
+	return;
 }
 
 /* 
  * Shutdown a device on a xtalk widget 
  */
 void
-xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum)
+xtalk_widgetdev_shutdown(vertex_hdl_t xconn_vhdl, int devnum)
 {
-    DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum);
+	return;
 }
 
 int
-xtalk_dma_enabled(devfs_handle_t xconn_vhdl)
+xtalk_dma_enabled(vertex_hdl_t xconn_vhdl)
 {
     return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl);
 }
@@ -623,7 +619,7 @@
  */
 
 /****** Generic crosstalk interrupt interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 xtalk_intr_dev_get(xtalk_intr_t xtalk_intr)
 {
     return (xtalk_intr->xi_dev);
@@ -654,7 +650,7 @@
 }
 
 /****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap)
 {
     return (xtalk_piomap->xp_dev);
@@ -686,7 +682,7 @@
 
 
 /****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap)
 {
     return (xtalk_dmamap->xd_dev);
@@ -707,7 +703,7 @@
  * if not, return NULL.
  */
 xwidget_info_t
-xwidget_info_chk(devfs_handle_t xwidget)
+xwidget_info_chk(vertex_hdl_t xwidget)
 {
     arbitrary_info_t        ainfo = 0;
 
@@ -717,28 +713,18 @@
 
 
 xwidget_info_t
-xwidget_info_get(devfs_handle_t xwidget)
+xwidget_info_get(vertex_hdl_t xwidget)
 {
     xwidget_info_t          widget_info;
 
     widget_info = (xwidget_info_t)
 	hwgraph_fastinfo_get(xwidget);
 
-#ifdef	LATER
-    if ((widget_info != NULL) &&
-	(widget_info->w_fingerprint != widget_info_fingerprint))
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	PRINT_PANIC("%v bad xwidget_info", xwidget);
-#else
-	PRINT_PANIC("%x bad xwidget_info", xwidget);
-#endif
-#endif	/* LATER */
-
     return (widget_info);
 }
 
 void
-xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info)
+xwidget_info_set(vertex_hdl_t xwidget, xwidget_info_t widget_info)
 {
     if (widget_info != NULL)
 	widget_info->w_fingerprint = widget_info_fingerprint;
@@ -753,11 +739,11 @@
 			 (arbitrary_info_t) widget_info);
 }
 
-devfs_handle_t
+vertex_hdl_t
 xwidget_info_dev_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_dev_get: null xwidget_info");
     return (xwidget_info->w_vertex);
 }
 
@@ -765,16 +751,16 @@
 xwidget_info_id_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_id_get: null xwidget_info");
     return (xwidget_info->w_id);
 }
 
 
-devfs_handle_t
+vertex_hdl_t
 xwidget_info_master_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_master_get: null xwidget_info");
     return (xwidget_info->w_master);
 }
 
@@ -782,7 +768,7 @@
 xwidget_info_masterid_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_masterid_get: null xwidget_info");
     return (xwidget_info->w_masterid);
 }
 
@@ -790,7 +776,7 @@
 xwidget_info_part_num_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_part_num_get: null xwidget_info");
     return (xwidget_info->w_hwid.part_num);
 }
 
@@ -798,7 +784,7 @@
 xwidget_info_mfg_num_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_mfg_num_get: null xwidget_info");
     return (xwidget_info->w_hwid.mfg_num);
 }
 /* Extract the widget name from the widget information
@@ -808,49 +794,16 @@
 xwidget_info_name_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget info");
+	panic("xwidget_info_name_get: null xwidget_info");
     return(xwidget_info->w_name);
 }
 /****** Generic crosstalk initialization interfaces ******/
 
 /*
- * One-time initialization needed for systems that support crosstalk.
- */
-void
-xtalk_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("xtalk_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (xtalk_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr");
-	if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(xtalk_registry != NULL);
-}
-
-/*
  * Associate a set of xtalk_provider functions with a vertex.
  */
 void
-xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns)
+xtalk_provider_register(vertex_hdl_t provider, xtalk_provider_t *xtalk_fns)
 {
     hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns);
 }
@@ -859,7 +812,7 @@
  * Disassociate a set of xtalk_provider functions with a vertex.
  */
 void
-xtalk_provider_unregister(devfs_handle_t provider)
+xtalk_provider_unregister(vertex_hdl_t provider)
 {
     hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL);
 }
@@ -869,50 +822,19 @@
  * provider.
  */
 xtalk_provider_t       *
-xtalk_provider_fns_get(devfs_handle_t provider)
+xtalk_provider_fns_get(vertex_hdl_t provider)
 {
     return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider));
 }
 
 /*
- * Announce a driver for a particular crosstalk part.
- * Returns 0 on success or -1 on failure.  Failure occurs if the
- * specified hardware already has a driver.
- */
-/*ARGSUSED4 */
-int
-xwidget_driver_register(xwidget_part_num_t part_num,
-			xwidget_mfg_num_t mfg_num,
-			char *driver_prefix,
-			unsigned flags)
-{
-    /* a driver's init routine could call
-     * xwidget_driver_register before the
-     * system calls xtalk_init; so, we
-     * make the call here.
-     */
-    if (xtalk_registry == NULL)
-	xtalk_init();
-
-    return cdl_add_driver(xtalk_registry,
-			  part_num, mfg_num,
-			  driver_prefix, flags, NULL);
-}
-
-/*
  * Inform xtalk infrastructure that a driver is no longer available for
  * handling any widgets.
  */
 void
 xwidget_driver_unregister(char *driver_prefix)
 {
-    /* before a driver calls unregister,
-     * it must have called registger; so we
-     * can assume we have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_del_driver(xtalk_registry, driver_prefix, NULL);
+	return;
 }
 
 /*
@@ -923,9 +845,6 @@
 xtalk_iterate(char *driver_prefix,
 	      xtalk_iter_f *func)
 {
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func);
 }
 
 /*
@@ -939,11 +858,10 @@
  */
 int
 xwidget_register(xwidget_hwid_t hwid,		/* widget's hardware ID */
-		 devfs_handle_t 	widget,		/* widget to initialize */
+		 vertex_hdl_t 	widget,		/* widget to initialize */
 		 xwidgetnum_t 	id,		/* widget's target id (0..f) */
-		 devfs_handle_t 	master,		/* widget's master vertex */
-		 xwidgetnum_t 	targetid,	/* master's target id (9/a) */
-		 async_attach_t aa)
+		 vertex_hdl_t 	master,		/* widget's master vertex */
+		 xwidgetnum_t 	targetid)	/* master's target id (9/a) */
 {			
     xwidget_info_t          widget_info;
     char		    *s,devnm[MAXDEVNAME];
@@ -972,21 +890,11 @@
 
     device_master_set(widget, master);
 
-    /* All the driver init routines (including
-     * xtalk_init) are called before we get into
-     * attaching devices, so we can assume we
-     * have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
     /* 
      * Add pointer to async attach info -- tear down will be done when
      * the particular descendant is done with the info.
      */
-    if (aa)
-	    async_attach_add_info(widget, aa);
-
-    return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
+    return cdl_add_connpt(hwid->part_num, hwid->mfg_num,
                           widget, 0);
 }
 
@@ -995,7 +903,7 @@
  *	Unregister the xtalk device and detach all its hwgraph namespace.
  */
 int
-xwidget_unregister(devfs_handle_t widget)
+xwidget_unregister(vertex_hdl_t widget)
 {
     xwidget_info_t	widget_info;
     xwidget_hwid_t	hwid;
@@ -1011,9 +919,6 @@
     
     hwid = &(widget_info->w_hwid);
 
-    cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
-                   widget, 0);
-
     /* Clean out the xwidget information */
     (void)kfree(widget_info->w_name);
     BZERO((void *)widget_info, sizeof(widget_info));
@@ -1023,7 +928,7 @@
 }
 
 void
-xwidget_error_register(devfs_handle_t xwidget,
+xwidget_error_register(vertex_hdl_t xwidget,
 		       error_handler_f *efunc,
 		       error_handler_arg_t einfo)
 {
@@ -1039,37 +944,23 @@
  * Issue a link reset to a widget.
  */
 void
-xwidget_reset(devfs_handle_t xwidget)
+xwidget_reset(vertex_hdl_t xwidget)
 {
     xswitch_reset_link(xwidget);
-
 }
 
 
 void
-xwidget_gfx_reset(devfs_handle_t xwidget)
+xwidget_gfx_reset(vertex_hdl_t xwidget)
 {
-    xwidget_info_t info;
-
-    xswitch_reset_link(xwidget);
-    info = xwidget_info_get(xwidget);
-#ifdef LATER
-    ASSERT_ALWAYS(info != NULL);
-#endif
-
-    /*
-     * Enable this for other architectures once we add widget_reset to the
-     * xtalk provider interface.
-     */
-    DEV_FUNC(xtalk_provider, widget_reset)
-	(xwidget_info_master_get(info), xwidget_info_id_get(info));
+	return;
 }
 
 #define ANON_XWIDGET_NAME	"No Name"	/* Default Widget Name */
 
 /* Get the canonical hwgraph  name of xtalk widget */
 char *
-xwidget_name_get(devfs_handle_t xwidget_vhdl)
+xwidget_name_get(vertex_hdl_t xwidget_vhdl)
 {
 	xwidget_info_t  info;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/stubs.c linux-2.4.22-pre10/arch/ia64/sn/io/stubs.c
--- linux-2.4.21/arch/ia64/sn/io/stubs.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/stubs.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,139 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/ctype.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/ioerror_handling.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/slotnum.h>
-#include <asm/sn/vector.h>
-#include <asm/sn/nic.h>
-
-/******
- ****** hack defines ......
- ******/
-
-int pcibr_prefetch_enable_rev, pcibr_wg_enable_rev;
-int default_intr_pri;
-int force_fire_and_forget = 1;
-int ignore_conveyor_override = 0;
-
-devfs_handle_t dummy_vrtx;	/* Needed for cpuid_to_vertex() in hack.h */
-
-
-/* ARGSUSED */
-void hub_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum)
-        {FIXME("hub_widgetdev_enable");}
-
-/* ARGSUSED */
-void hub_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum)
-        {FIXME("hub_widgetdev_shutdown");}
-
-/* ARGSUSED */
-void hub_widget_reset(devfs_handle_t hubv, xwidgetnum_t widget)
-        {FIXME("hub_widget_reset");}
-
-boolean_t
-is_sys_critical_vertex(devfs_handle_t x)
-{
-	FIXME("is_sys_critical_vertex : returns 0");
-	return(0);
-}
-
-void *
-snia_kmem_zone_alloc(register zone_t *zone, int flags)
-{
-	FIXME("snia_kmem_zone_alloc : return null");
-	return((void *)0);
-}
-
-void
-snia_kmem_zone_free(register zone_t *zone, void *ptr)
-{
-	FIXME("snia_kmem_zone_free : no-op");
-}
-
-zone_t *
-snia_kmem_zone_init(register int size, char *zone_name)
-{
-	FIXME("snia_kmem_zone_free : returns NULL");
-	return((zone_t *)0);
-}
-
-int
-compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr)
-{
-	FIXME("compare_and_swap_ptr : NOT ATOMIC");
-	if (*location == old_ptr) {
-		*location = new_ptr;
-		return(1);
-	}
-	else
-		return(0);
-}
-
-/* For ml/SN/SN1/slots.c */
-/* ARGSUSED */
-slotid_t get_widget_slotnum(int xbow, int widget)
-        {FIXME("get_widget_slotnum"); return (unsigned char)NULL;}
-
-/* For router */
-int
-router_init(cnodeid_t cnode,int writeid, void *npda_rip)
-        {FIXME("router_init"); return(0);}
-
-/* From io/ioerror_handling.c */
-error_return_code_t
-sys_critical_graph_vertex_add(devfs_handle_t parent, devfs_handle_t child)
-	{FIXME("sys_critical_graph_vertex_add"); return(0);}
-
-/* From io/ioc3.c */
-devfs_handle_t
-ioc3_console_vhdl_get(void)
-	{FIXME("ioc3_console_vhdl_get"); return( (devfs_handle_t)-1);}
-
-void
-nic_vmc_check(devfs_handle_t vhdl, char *nicinfo)
-{
-
-	FIXME("nic_vmc_check\n");
-
-}
-
-char *
-nic_vertex_info_get(devfs_handle_t v)
-{
-	FIXME("nic_vertex_info_get\n");
-	return(NULL);
-}
-
-int
-vector_read_node(net_vec_t dest, nasid_t nasid,
-             int write_id, int address,
-             uint64_t *value)
-{
-	FIXME("vector_read_node\n");
-	return(0);
-}
-
-int
-vector_write_node(net_vec_t dest, nasid_t nasid,
-              int write_id, int address,
-              uint64_t value)
-{
-	FIXME("vector_write_node\n");
-	return(0);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/xbow.c linux-2.4.22-pre10/arch/ia64/sn/io/xbow.c
--- linux-2.4.21/arch/ia64/sn/io/xbow.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/xbow.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1325 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-#include <asm/sn/simulator.h>
-
-/* #define DEBUG		1 */
-/* #define XBOW_DEBUG	1 */
-
-
-/*
- * Files needed to get the device driver entry points
- */
-
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-
-#include <asm/sn/prio.h>
-#include <asm/sn/hcl_util.h>
-
-
-#define NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DEL(ptr)	(kfree(ptr))
-
-int                     xbow_devflag = D_MP;
-
-/*
- * This file supports the Xbow chip.  Main functions: initializtion,
- * error handling, and GBR.
- */
-
-/*
- * each vertex corresponding to an xbow chip
- * has a "fastinfo" pointer pointing at one
- * of these things.
- */
-typedef struct xbow_soft_s *xbow_soft_t;
-
-struct xbow_soft_s {
-    devfs_handle_t            conn;	/* our connection point */
-    devfs_handle_t            vhdl;	/* xbow's private vertex */
-    devfs_handle_t            busv;	/* the xswitch vertex */
-    xbow_t                 *base;	/* PIO pointer to crossbow chip */
-    char                   *name;	/* hwgraph name */
-
-    xbow_perf_t             xbow_perfcnt[XBOW_PERF_COUNTERS];
-    xbow_perf_link_t        xbow_perflink[MAX_XBOW_PORTS];
-    xbow_link_status_t      xbow_link_status[MAX_XBOW_PORTS];
-    spinlock_t              xbow_perf_lock;
-    int                     link_monitor;
-    widget_cfg_t	   *wpio[MAX_XBOW_PORTS];	/* cached PIO pointer */
-
-    /* Bandwidth allocation state. Bandwidth values are for the
-     * destination port since contention happens there.
-     * Implicit mapping from xbow ports (8..f) -> (0..7) array indices.
-     */
-    spinlock_t		    xbow_bw_alloc_lock;		/* bw allocation lock */
-    unsigned long long	    bw_hiwm[MAX_XBOW_PORTS];	/* hiwater mark values */
-    unsigned long long      bw_cur_used[MAX_XBOW_PORTS]; /* bw used currently */
-};
-
-#define xbow_soft_set(v,i)	hwgraph_fastinfo_set((v), (arbitrary_info_t)(i))
-#define xbow_soft_get(v)	((xbow_soft_t)hwgraph_fastinfo_get((v)))
-
-/*
- * Function Table of Contents
- */
-
-void                    xbow_mlreset(xbow_t *);
-void                    xbow_init(void);
-int                     xbow_attach(devfs_handle_t);
-
-int                     xbow_open(devfs_handle_t *, int, int, cred_t *);
-int                     xbow_close(devfs_handle_t, int, int, cred_t *);
-
-int                     xbow_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                     xbow_unmap(devfs_handle_t, vhandl_t *);
-int                     xbow_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
-
-int                     xbow_widget_present(xbow_t *, int);
-static int              xbow_link_alive(xbow_t *, int);
-devfs_handle_t            xbow_widget_lookup(devfs_handle_t, int);
-
-#ifdef LATER
-static void             xbow_setwidint(xtalk_intr_t);
-static void             xbow_errintr_handler(intr_arg_t);
-#endif
-void                    xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
-
-
-
-void                    xbow_update_perf_counters(devfs_handle_t);
-xbow_perf_link_t       *xbow_get_perf_counters(devfs_handle_t);
-int                     xbow_enable_perf_counter(devfs_handle_t, int, int, int);
-xbow_link_status_t     *xbow_get_llp_status(devfs_handle_t);
-void                    xbow_update_llp_status(devfs_handle_t);
-
-int                     xbow_disable_llp_monitor(devfs_handle_t);
-int                     xbow_enable_llp_monitor(devfs_handle_t);
-int                     xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t,
-                                unsigned long long, unsigned long long);
-
-xswitch_reset_link_f    xbow_reset_link;
-
-void                    idbg_xbowregs(int64_t);
-
-xswitch_provider_t      xbow_provider =
-{
-    xbow_reset_link,
-};
-
-/*
- *    xbow_mlreset: called at mlreset time if the
- *      platform specific code determines that there is
- *      a crossbow in a critical path that must be
- *      functional before the driver would normally get
- *      the device properly set up.
- *
- *      what do we need to do, that the boot prom can
- *      not be counted on to have already done, that is
- *      generic across all platforms using crossbows?
- */
-/*ARGSUSED */
-void
-xbow_mlreset(xbow_t * xbow)
-{
-}
-
-/*
- *    xbow_init: called with the rest of the device
- *      driver XXX_init routines. This platform *might*
- *      have a Crossbow chip, or even several, but it
- *      might have none. Register with the crosstalk
- *      generic provider so when we encounter the chip
- *      the right magic happens.
- */
-void
-xbow_init(void)
-{
-
-#if DEBUG && ATTACH_DEBUG
-    printf("xbow_init\n");
-#endif
-
-    xwidget_driver_register(XXBOW_WIDGET_PART_NUM,
-			    0, /* XXBOW_WIDGET_MFGR_NUM, */
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-
-    xwidget_driver_register(XBOW_WIDGET_PART_NUM,
-			    XBOW_WIDGET_MFGR_NUM,
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-}
-
-#ifdef XBRIDGE_REGS_SIM
-/*    xbow_set_simulated_regs: sets xbow regs as needed
- *	for powering through the boot
- */
-void
-xbow_set_simulated_regs(xbow_t *xbow, int port)
-{
-    /*
-     * turn on link
-     */
-    xbow->xb_link(port).link_status = (1<<31);
-    /*
-     * and give it a live widget too
-     */
-    xbow->xb_link(port).link_aux_status = XB_AUX_STAT_PRESENT;
-    /*
-     * zero the link control reg
-     */
-    xbow->xb_link(port).link_control = 0x0;
-}
-#endif /* XBRIDGE_REGS_SIM */
-
-/*
- *    xbow_attach: the crosstalk provider has
- *      determined that there is a crossbow widget
- *      present, and has handed us the connection
- *      point for that vertex.
- *
- *      We not only add our own vertex, but add
- *      some "xtalk switch" data to the switch
- *      vertex (at the connect point's parent) if
- *      it does not have any.
- */
-
-/*ARGSUSED */
-int
-xbow_attach(devfs_handle_t conn)
-{
-    /*REFERENCED */
-    devfs_handle_t            vhdl;
-    devfs_handle_t            busv;
-    xbow_t                 *xbow;
-    xbow_soft_t             soft;
-    int                     port;
-    xswitch_info_t          info;
-#ifdef LATER
-    xtalk_intr_t            intr_hdl;
-    device_desc_t           dev_desc;
-#endif
-    char                    devnm[MAXDEVNAME], *s;
-    xbowreg_t               id;
-    int                     rev;
-    int			    i;
-    int			    xbow_num;
-	
-#if DEBUG && ATTACH_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT
-    printk("%v: xbow_attach\n", conn);
-#else
-    printk("0x%x: xbow_attach\n", conn);
-#endif
-#endif
-
-    /*
-     * Get a PIO pointer to the base of the crossbow
-     * chip.
-     */
-#ifdef XBRIDGE_REGS_SIM
-    printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: allocating %ld bytes for xbow_s\n", sizeof(xbow_t));
-    xbow = (xbow_t *) kmalloc(sizeof(xbow_t), GFP_KERNEL);
-    /*
-     * turn on ports e and f like in a real live ibrick
-     */
-    xbow_set_simulated_regs(xbow, 0xe);
-    xbow_set_simulated_regs(xbow, 0xf);
-#else
-    xbow = (xbow_t *) xtalk_piotrans_addr(conn, 0, 0, sizeof(xbow_t), 0);
-#endif /* XBRIDGE_REGS_SIM */
-
-    /*
-     * Locate the "switch" vertex: it is the parent
-     * of our connection point.
-     */
-    busv = hwgraph_connectpt_get(conn);
-#if DEBUG && ATTACH_DEBUG
-    printk("xbow_attach: Bus Vertex 0x%p, conn 0x%p, xbow register 0x%p wid= 0x%x\n", busv, conn, xbow, *(volatile u32 *)xbow);
-#endif
-
-    ASSERT(busv != GRAPH_VERTEX_NONE);
-
-    /*
-     * Create our private vertex, and connect our
-     * driver information to it. This makes it possible
-     * for diagnostic drivers to open the crossbow
-     * vertex for access to registers.
-     */
-
-    /*
-     * We need to teach xbow drivers to provide the right set of
-     * file ops.
-     */
-    vhdl = NULL;
-    vhdl = hwgraph_register(conn, EDGE_LBL_XBOW,
-                        0, DEVFS_FL_AUTO_DEVNUM,
-                        0, 0,
-                        S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                        /* &hcl_fops */ (void *)&vhdl, NULL);
-    if (!vhdl) {
-        printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n",
-                (void *)conn);
-    }
-
-    /*
-     * Allocate the soft state structure and attach
-     * it to the xbow's vertex
-     */
-    NEW(soft);
-    soft->conn = conn;
-    soft->vhdl = vhdl;
-    soft->busv = busv;
-    soft->base = xbow;
-    /* does the universe really need another macro?  */
-    /* xbow_soft_set(vhdl, (arbitrary_info_t) soft); */
-    hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft);
-
-#define XBOW_NUM_SUFFIX_FORMAT	"[xbow# %d]"
-
-    /* Add xbow number as a suffix to the hwgraph name of the xbow.
-     * This is helpful while looking at the error/warning messages.
-     */
-    xbow_num = 0;
-
-    /*
-     * get the name of this xbow vertex and keep the info.
-     * This is needed during errors and interupts, but as
-     * long as we have it, we can use it elsewhere.
-     */
-    s = dev_to_name(vhdl, devnm, MAXDEVNAME);
-    soft->name = kmalloc(strlen(s) + strlen(XBOW_NUM_SUFFIX_FORMAT) + 1, 
-			    GFP_KERNEL);
-    sprintf(soft->name,"%s"XBOW_NUM_SUFFIX_FORMAT, s,xbow_num);
-
-#ifdef XBRIDGE_REGS_SIM
-    /* my o200/ibrick has id=0x2d002049, but XXBOW_WIDGET_PART_NUM is defined
-     * as 0xd000, so I'm using that for the partnum bitfield.
-     */
-    printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: need xb_wid_id value!!\n");
-    id = 0x2d000049;
-#else
-    id = xbow->xb_wid_id;
-#endif /* XBRIDGE_REGS_SIM */
-    rev = XWIDGET_PART_REV_NUM(id);
-
-    /*
-     * Print the revision if DEBUG, or SHOW_REVS and kdebug,
-     * or the xbow is downrev.
-     *
-     * If xbow is downrev, make it a WARNING that the
-     * Crossbow is DOWNREV: these chips are not good
-     * to have around, and the operator should be told.
-     */
-#ifdef	LATER
-#if !DEBUG
-    if (
-#if SHOW_REVS
-	   (kdebug) ||
-#endif	/* SHOW_REVS */
-	   (rev < XBOW_REV_1_1))
-#endif	/* !DEBUG  */
-	printk("%sCrossbow ASIC: rev %s (code=%d) at %s%s",
-		(rev < XBOW_REV_1_1) ? "DOWNREV " : "",
-		(rev == XBOW_REV_1_0) ? "1.0" :
-		(rev == XBOW_REV_1_1) ? "1.1" :
-		(rev == XBOW_REV_1_2) ? "1.2" :
-		(rev == XBOW_REV_1_3) ? "1.3" :
-		(rev == XBOW_REV_2_0) ? "2.0" :
-		(rev == XXBOW_PART_REV_1_0) ? "Xbridge 1.0" :
-		(rev == XXBOW_PART_REV_2_0) ? "Xbridge 2.0" :
-		"unknown",
-		rev, soft->name,
-		(rev < XBOW_REV_1_1) ? "" : "\n");
-#endif	/* LATER */
-    mutex_spinlock_init(&soft->xbow_perf_lock);
-    soft->xbow_perfcnt[0].xp_perf_reg = &xbow->xb_perf_ctr_a;
-    soft->xbow_perfcnt[1].xp_perf_reg = &xbow->xb_perf_ctr_b;
-
-    /* Initialization for GBR bw allocation */
-    mutex_spinlock_init(&soft->xbow_bw_alloc_lock);
-
-#define	XBOW_8_BIT_PORT_BW_MAX		(400 * 1000 * 1000)	/* 400 MB/s */
-#define XBOW_16_BIT_PORT_BW_MAX		(800 * 1000 * 1000)	/* 800 MB/s */
-
-    /* Set bandwidth hiwatermark and current values */
-    for (i = 0; i < MAX_XBOW_PORTS; i++) {
-	soft->bw_hiwm[i] = XBOW_16_BIT_PORT_BW_MAX;	/* for now */
-	soft->bw_cur_used[i] = 0;
-    }
-
-    /*
-     * Enable xbow error interrupts
-     */
-    xbow->xb_wid_control = (XB_WID_CTRL_REG_ACC_IE | XB_WID_CTRL_XTALK_IE);
-
-    /*
-     * take a census of the widgets present,
-     * leaving notes at the switch vertex.
-     */
-    info = xswitch_info_new(busv);
-
-    for (port = MAX_PORT_NUM - MAX_XBOW_PORTS;
-	 port < MAX_PORT_NUM; ++port) {
-	if (!xbow_link_alive(xbow, port)) {
-#if DEBUG && XBOW_DEBUG
-	    printk(KERN_INFO "0x%p link %d is not alive\n",
-		    busv, port);
-#endif
-	    continue;
-	}
-	if (!xbow_widget_present(xbow, port)) {
-#if DEBUG && XBOW_DEBUG
-	    printk(KERN_INFO "0x%p link %d is alive but no widget is present\n", busv, port);
-#endif
-	    continue;
-	}
-#if DEBUG && XBOW_DEBUG
-	printk(KERN_INFO "0x%p link %d has a widget\n",
-		busv, port);
-#endif
-
-	xswitch_info_link_is_ok(info, port);
-	/*
-	 * Turn some error interrupts on
-	 * and turn others off. The PROM has
-	 * some things turned on we don't
-	 * want to see (bandwidth allocation
-	 * errors for instance); so if it
-	 * is not listed here, it is not on.
-	 */
-	xbow->xb_link(port).link_control =
-	    ( (xbow->xb_link(port).link_control
-	/*
-	 * Turn off these bits; they are non-fatal,
-	 * but we might want to save some statistics
-	 * on the frequency of these errors.
-	 * XXX FIXME XXX
-	 */
-	    & ~XB_CTRL_RCV_CNT_OFLOW_IE
-	    & ~XB_CTRL_XMT_CNT_OFLOW_IE
-	    & ~XB_CTRL_BNDWDTH_ALLOC_IE
-	    & ~XB_CTRL_RCV_IE)
-	/*
-	 * These are the ones we want to turn on.
-	 */
-	    | (XB_CTRL_ILLEGAL_DST_IE
-	    | XB_CTRL_OALLOC_IBUF_IE
-	    | XB_CTRL_XMT_MAX_RTRY_IE
-	    | XB_CTRL_MAXREQ_TOUT_IE
-	    | XB_CTRL_XMT_RTRY_IE
-	    | XB_CTRL_SRC_TOUT_IE) );
-    }
-
-    xswitch_provider_register(busv, &xbow_provider);
-
-    return 0;				/* attach successful */
-}
-
-/*ARGSUSED */
-int
-xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-
-}
-
-/*ARGSUSED */
-int
-xbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    xbow_soft_t             soft = xbow_soft_get(vhdl);
-    int                     error;
-
-    ASSERT(soft);
-    len = ctob(btoc(len));
-    /* XXX- this ignores the offset!!! */
-    error = v_mapphys(vt, (void *) soft->base, len);
-    return error;
-}
-
-/*ARGSUSED */
-int
-xbow_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    return 0;
-}
-
-/* This contains special-case code for grio. There are plans to make
- * this general sometime in the future, but till then this should
- * be good enough.
- */
-xwidgetnum_t
-xbow_widget_num_get(devfs_handle_t dev)
-{
-	devfs_handle_t	tdev;
-	char		devname[MAXDEVNAME];
-	xwidget_info_t	xwidget_info;
-	int		i;
-
-	vertex_to_name(dev, devname, MAXDEVNAME);
-
-	/* If this is a pci controller vertex, traverse up using
-	 * the ".." links to get to the widget.
-	 */
-	if (strstr(devname, EDGE_LBL_PCI) &&
-			strstr(devname, EDGE_LBL_CONTROLLER)) {
-		tdev = dev;
-		for (i=0; i< 2; i++) {
-			if (hwgraph_edge_get(tdev,
-				HWGRAPH_EDGELBL_DOTDOT, &tdev) !=
-					GRAPH_SUCCESS)
-				return XWIDGET_NONE;
-		}
-
-		if ((xwidget_info = xwidget_info_chk(tdev)) != NULL) {
-			return (xwidget_info_id_get(xwidget_info));
-		} else {
-			return XWIDGET_NONE;
-		}
-	}
-
-	return XWIDGET_NONE;
-}
-
-int
-xbow_ioctl(devfs_handle_t dev,
-	   int cmd,
-	   void *arg,
-	   int flag,
-	   struct cred *cr,
-	   int *rvalp)
-{
-    devfs_handle_t            vhdl;
-    int                     error = 0;
-
-#if defined (DEBUG)
-    int                     rc;
-    devfs_handle_t            conn;
-    struct xwidget_info_s  *xwidget_info;
-    xbow_soft_t             xbow_soft;
-#endif
-    *rvalp = 0;
-
-    vhdl = dev_to_vhdl(dev);
-#if defined (DEBUG)
-    xbow_soft = xbow_soft_get(vhdl);
-    conn = xbow_soft->conn;
-
-    xwidget_info = xwidget_info_get(conn);
-    ASSERT_ALWAYS(xwidget_info != NULL);
-
-    rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid);
-    ASSERT_ALWAYS(rc != 0);
-#endif
-    switch (cmd) {
-#ifdef LATER
-    case XBOWIOC_PERF_ENABLE:
-    case XBOWIOC_PERF_DISABLE:
-	{
-	    struct xbow_perfarg_t   xbow_perf_en;
-
-	    if (!_CAP_CRABLE(cr, CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-	    if ((flag & FWRITE) == 0) {
-		error = EBADF;
-		break;
-	    }
-	    if (COPYIN(arg, &xbow_perf_en, sizeof(xbow_perf_en))) {
-		error = EFAULT;
-		break;
-	    }
-	    if (error = xbow_enable_perf_counter(vhdl,
-						 xbow_perf_en.link,
-						 (cmd == XBOWIOC_PERF_DISABLE) ? 0 : xbow_perf_en.mode,
-						 xbow_perf_en.counter)) {
-		error = EINVAL;
-		break;
-	    }
-	    break;
-	}
-#endif
-
-#ifdef LATER
-    case XBOWIOC_PERF_GET:
-	{
-	    xbow_perf_link_t       *xbow_perf_cnt;
-
-	    if ((flag & FREAD) == 0) {
-		error = EBADF;
-		break;
-	    }
-	    xbow_perf_cnt = xbow_get_perf_counters(vhdl);
-	    ASSERT_ALWAYS(xbow_perf_cnt != NULL);
-
-	    if (COPYOUT((void *) xbow_perf_cnt, (void *) arg,
-			MAX_XBOW_PORTS * sizeof(xbow_perf_link_t))) {
-		error = EFAULT;
-		break;
-	    }
-	    break;
-	}
-#endif
-
-    case XBOWIOC_LLP_ERROR_ENABLE:
-	if ((error = xbow_enable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-    case XBOWIOC_LLP_ERROR_DISABLE:
-
-	if ((error = xbow_disable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-#ifdef LATER
-    case XBOWIOC_LLP_ERROR_GET:
-	{
-	    xbow_link_status_t     *xbow_llp_status;
-
-	    if ((flag & FREAD) == 0) {
-		error = EBADF;
-		break;
-	    }
-	    xbow_llp_status = xbow_get_llp_status(vhdl);
-	    ASSERT_ALWAYS(xbow_llp_status != NULL);
-
-	    if (COPYOUT((void *) xbow_llp_status, (void *) arg,
-			MAX_XBOW_PORTS * sizeof(xbow_link_status_t))) {
-		error = EFAULT;
-		break;
-	    }
-	    break;
-	}
-#endif
-
-#ifdef LATER
-    case GIOCSETBW:
-	{
-	    grio_ioctl_info_t info;
-	    xwidgetnum_t src_widgetnum, dest_widgetnum;
-
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printf("xbow:: prev_vhdl: %d next_vhdl: %d reqbw: %lld\n",
-			info.prev_vhdl, info.next_vhdl, info.reqbw);
-#endif /* GRIO_DEBUG */
-
-	    src_widgetnum = xbow_widget_num_get(info.prev_vhdl);
-	    dest_widgetnum = xbow_widget_num_get(info.next_vhdl);
-
-	    /* Bandwidth allocation is bi-directional. Since bandwidth
-	     * reservations have already been done at an earlier stage,
-	     * we cannot fail here for lack of bandwidth.
-	     */
-	    xbow_prio_bw_alloc(dev, src_widgetnum, dest_widgetnum,
-			0, info.reqbw);
-	    xbow_prio_bw_alloc(dev, dest_widgetnum, src_widgetnum,
-			0, info.reqbw);
-
-	    break;
-	}
-
-    case GIOCRELEASEBW:
-	{
-	    grio_ioctl_info_t info;
-	    xwidgetnum_t src_widgetnum, dest_widgetnum;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printf("xbow:: prev_vhdl: %d next_vhdl: %d reqbw: %lld\n",
-			info.prev_vhdl, info.next_vhdl, info.reqbw);
-#endif /* GRIO_DEBUG */
-
-	    src_widgetnum = xbow_widget_num_get(info.prev_vhdl);
-	    dest_widgetnum = xbow_widget_num_get(info.next_vhdl);
-
-	    /* Bandwidth reservation is bi-directional. Hence, remove
-	     * bandwidth reservations for both directions.
-	     */
-	    xbow_prio_bw_alloc(dev, src_widgetnum, dest_widgetnum,
-			info.reqbw, (-1 * info.reqbw));
-	    xbow_prio_bw_alloc(dev, dest_widgetnum, src_widgetnum,
-			info.reqbw, (-1 * info.reqbw));
-
-	    break;
-	}
-#endif
-
-    default:
-	break;
-
-    }
-    return error;
-}
-
-/*
- * xbow_widget_present: See if a device is present
- * on the specified port of this crossbow.
- */
-int
-xbow_widget_present(xbow_t * xbow, int port)
-{
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		if ( (port == 14) || (port == 15) ) {
-			return 1;
-		}
-		else {
-			return 0;
-		}
-	}
-	else {
-		return xbow->xb_link(port).link_aux_status & XB_AUX_STAT_PRESENT;
-	}
-}
-
-static int
-xbow_link_alive(xbow_t * xbow, int port)
-{
-    xbwX_stat_t             xbow_linkstat;
-
-    xbow_linkstat.linkstatus = xbow->xb_link(port).link_status;
-    return (xbow_linkstat.link_alive);
-}
-
-/*
- * xbow_widget_lookup
- *      Lookup the edges connected to the xbow specified, and
- *      retrieve the handle corresponding to the widgetnum
- *      specified.
- *      If not found, return 0.
- */
-devfs_handle_t
-xbow_widget_lookup(devfs_handle_t vhdl,
-		   int widgetnum)
-{
-    xswitch_info_t          xswitch_info;
-    devfs_handle_t            conn;
-
-    xswitch_info = xswitch_info_get(vhdl);
-    conn = xswitch_info_vhdl_get(xswitch_info, widgetnum);
-    return conn;
-}
-
-/*
- * xbow_setwidint: called when xtalk
- * is establishing or migrating our
- * interrupt service.
- */
-#ifdef LATER
-static void
-xbow_setwidint(xtalk_intr_t intr)
-{
-    xwidgetnum_t            targ = xtalk_intr_target_get(intr);
-    iopaddr_t               addr = xtalk_intr_addr_get(intr);
-    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(intr);
-    xbow_t                 *xbow = (xbow_t *) xtalk_intr_sfarg_get(intr);
-
-    xbow_intr_preset((void *) xbow, 0, targ, addr, vect);
-}
-#endif	/* LATER */
-
-/*
- * xbow_intr_preset: called during mlreset time
- * if the platform specific code needs to route
- * an xbow interrupt before the xtalk infrastructure
- * is available for use.
- *
- * Also called from xbow_setwidint, so we don't
- * replicate the guts of the routine.
- *
- * XXX- probably should be renamed xbow_wid_intr_set or
- * something to reduce confusion.
- */
-/*ARGSUSED3 */
-void
-xbow_intr_preset(void *which_widget,
-		 int which_widget_intr,
-		 xwidgetnum_t targ,
-		 iopaddr_t addr,
-		 xtalk_intr_vector_t vect)
-{
-    xbow_t                 *xbow = (xbow_t *) which_widget;
-
-    xbow->xb_wid_int_upper = ((0xFF000000 & (vect << 24)) |
-			      (0x000F0000 & (targ << 16)) |
-			      XTALK_ADDR_TO_UPPER(addr));
-    xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
-}
-
-#define	XEM_ADD_STR(s)		printk("%s", (s))
-#define	XEM_ADD_NVAR(n,v)	printk("\t%20s: 0x%x\n", (n), (v))
-#define	XEM_ADD_VAR(v)		XEM_ADD_NVAR(#v,(v))
-#define XEM_ADD_IOEF(n) 	if (IOERROR_FIELDVALID(ioe,n))		    \
-				    XEM_ADD_NVAR("ioe." #n,		    \
-						 IOERROR_GETVALUE(ioe,n))
-
-#ifdef LATER
-static void
-xem_add_ioe(ioerror_t *ioe)
-{
-    XEM_ADD_IOEF(errortype);
-    XEM_ADD_IOEF(widgetnum);
-    XEM_ADD_IOEF(widgetdev);
-    XEM_ADD_IOEF(srccpu);
-    XEM_ADD_IOEF(srcnode);
-    XEM_ADD_IOEF(errnode);
-    XEM_ADD_IOEF(sysioaddr);
-    XEM_ADD_IOEF(xtalkaddr);
-    XEM_ADD_IOEF(busspace);
-    XEM_ADD_IOEF(busaddr);
-    XEM_ADD_IOEF(vaddr);
-    XEM_ADD_IOEF(memaddr);
-    XEM_ADD_IOEF(epc);
-    XEM_ADD_IOEF(ef);
-}
-
-#define XEM_ADD_IOE()	(xem_add_ioe(ioe))
-#endif	/* LATER */
-
-int                     xbow_xmit_retry_errors = 0;
-
-int
-xbow_xmit_retry_error(xbow_soft_t soft,
-		      int port)
-{
-    xswitch_info_t          info;
-    devfs_handle_t            vhdl;
-    widget_cfg_t           *wid;
-    widgetreg_t             id;
-    int                     part;
-    int                     mfgr;
-
-    wid = soft->wpio[port - BASE_XBOW_PORT];
-    if (wid == NULL) {
-	/* If we can't track down a PIO
-	 * pointer to our widget yet,
-	 * leave our caller knowing that
-	 * we are interested in this
-	 * interrupt if it occurs in
-	 * the future.
-	 */
-	info = xswitch_info_get(soft->busv);
-	if (!info)
-	    return 1;
-	vhdl = xswitch_info_vhdl_get(info, port);
-	if (vhdl == GRAPH_VERTEX_NONE)
-	    return 1;
-	wid = (widget_cfg_t *) xtalk_piotrans_addr
-	    (vhdl, 0, 0, sizeof *wid, 0);
-	if (!wid)
-	    return 1;
-	soft->wpio[port - BASE_XBOW_PORT] = wid;
-    }
-    id = wid->w_id;
-    part = XWIDGET_PART_NUM(id);
-    mfgr = XWIDGET_MFG_NUM(id);
-
-    /* If this thing is not a Bridge,
-     * do not activate the WAR, and
-     * tell our caller we do not need
-     * to be called again.
-     */
-    if ((part != BRIDGE_WIDGET_PART_NUM) ||
-	(mfgr != BRIDGE_WIDGET_MFGR_NUM)) {
-		/* FIXME: add Xbridge to the WAR.
-		 * Shouldn't hurt anything.  Later need to
-		 * check if we can remove this.
-                 */
-    		if ((part != XBRIDGE_WIDGET_PART_NUM) ||
-		    (mfgr != XBRIDGE_WIDGET_MFGR_NUM))
-			return 0;
-    }
-
-    /* count how many times we
-     * have picked up after
-     * LLP Transmit problems.
-     */
-    xbow_xmit_retry_errors++;
-
-    /* rewrite the control register
-     * to fix things up.
-     */
-    wid->w_control = wid->w_control;
-    wid->w_control;
-
-    return 1;
-}
-
-void
-xbow_update_perf_counters(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
-    xbow_perf_link_t       *xbow_plink = xbow_soft->xbow_perflink;
-    xbow_perfcount_t        perf_reg;
-    unsigned long           s;
-    int                     link, i;
-
-    for (i = 0; i < XBOW_PERF_COUNTERS; i++, xbow_perf++) {
-	if (xbow_perf->xp_mode == XBOW_MONITOR_NONE)
-	    continue;
-
-	s = mutex_spinlock(&xbow_soft->xbow_perf_lock);
-
-	perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg;
-
-	link = perf_reg.xb_perf.link_select;
-
-	(xbow_plink + link)->xlp_cumulative[xbow_perf->xp_curmode] +=
-	    ((perf_reg.xb_perf.count - xbow_perf->xp_current) & XBOW_COUNTER_MASK);
-	xbow_perf->xp_current = perf_reg.xb_perf.count;
-
-	mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-    }
-    /* Do port /mode multiplexing here */
-
-#ifdef LATER
-    (void) timeout(xbow_update_perf_counters,
-		   (void *) (__psunsigned_t) vhdl, XBOW_PERF_TIMEOUT);
-#endif
-
-}
-
-xbow_perf_link_t       *
-xbow_get_perf_counters(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_link_t       *xbow_perf_link = xbow_soft->xbow_perflink;
-
-    return xbow_perf_link;
-}
-
-int
-xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
-    xbow_linkctrl_t         xbow_link_ctrl;
-    xbow_t                 *xbow = xbow_soft->base;
-    xbow_perfcount_t        perf_reg;
-    unsigned long           s;
-    int                     i;
-
-    link -= BASE_XBOW_PORT;
-    if ((link < 0) || (link >= MAX_XBOW_PORTS))
-	return -1;
-
-    if ((mode < XBOW_MONITOR_NONE) || (mode > XBOW_MONITOR_DEST_LINK))
-	return -1;
-
-    if ((counter < 0) || (counter >= XBOW_PERF_COUNTERS))
-	return -1;
-
-    s = mutex_spinlock(&xbow_soft->xbow_perf_lock);
-
-    if ((xbow_perf + counter)->xp_mode && mode) {
-	mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-	return -1;
-    }
-    for (i = 0; i < XBOW_PERF_COUNTERS; i++) {
-	if (i == counter)
-	    continue;
-	if (((xbow_perf + i)->xp_link == link) &&
-	    ((xbow_perf + i)->xp_mode)) {
-	    mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-	    return -1;
-	}
-    }
-    xbow_perf += counter;
-
-    xbow_perf->xp_curlink = xbow_perf->xp_link = link;
-    xbow_perf->xp_curmode = xbow_perf->xp_mode = mode;
-
-    xbow_link_ctrl.xbl_ctrlword = xbow->xb_link_raw[link].link_control;
-    xbow_link_ctrl.xb_linkcontrol.perf_mode = mode;
-    xbow->xb_link_raw[link].link_control = xbow_link_ctrl.xbl_ctrlword;
-
-    perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg;
-    perf_reg.xb_perf.link_select = link;
-    *(xbowreg_t *) xbow_perf->xp_perf_reg = perf_reg.xb_counter_val;
-    xbow_perf->xp_current = perf_reg.xb_perf.count;
-
-#ifdef LATER
-    (void) timeout(xbow_update_perf_counters,
-		   (void *) (__psunsigned_t) vhdl, XBOW_PERF_TIMEOUT);
-#endif
-
-    mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-
-    return 0;
-}
-
-xbow_link_status_t     *
-xbow_get_llp_status(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
-
-    return xbow_llp_status;
-}
-
-void
-xbow_update_llp_status(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
-    xbow_t                 *xbow;
-    xbwX_stat_t             lnk_sts;
-    xbow_aux_link_status_t  aux_sts;
-    int                     link;
-    devfs_handle_t	    xwidget_vhdl;
-    char		   *xwidget_name;	
-
-    xbow = (xbow_t *) xbow_soft->base;
-    for (link = 0; link < MAX_XBOW_PORTS; link++, xbow_llp_status++) {
-	/* Get the widget name corresponding the current link.
-	 * Note : 0 <= link < MAX_XBOW_PORTS(8).
-	 * 	  BASE_XBOW_PORT(0x8) <= xwidget number < MAX_PORT_NUM (0x10)
-	 */
-	xwidget_vhdl = xbow_widget_lookup(xbow_soft->busv,link+BASE_XBOW_PORT);
-	xwidget_name = xwidget_name_get(xwidget_vhdl);
-	aux_sts.aux_linkstatus
-	    = xbow->xb_link_raw[link].link_aux_status;
-	lnk_sts.linkstatus = xbow->xb_link_raw[link].link_status_clr;
-
-	if (lnk_sts.link_alive == 0)
-	    continue;
-
-	xbow_llp_status->rx_err_count +=
-	    aux_sts.xb_aux_linkstatus.rx_err_cnt;
-
-	xbow_llp_status->tx_retry_count +=
-	    aux_sts.xb_aux_linkstatus.tx_retry_cnt;
-
-	if (lnk_sts.linkstatus & ~(XB_STAT_RCV_ERR | XB_STAT_XMT_RTRY_ERR | XB_STAT_LINKALIVE)) {
-#ifdef	LATER
-	    printk(KERN_WARNING  "link %d[%s]: bad status 0x%x\n",
-		    link, xwidget_name, lnk_sts.linkstatus);
-#endif
-	}
-    }
-#ifdef LATER
-    if (xbow_soft->link_monitor)
-	(void) timeout(xbow_update_llp_status,
-		       (void *) (__psunsigned_t) vhdl, XBOW_STATS_TIMEOUT);
-#endif
-}
-
-int
-xbow_disable_llp_monitor(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    int                     port;
-
-    for (port = 0; port < MAX_XBOW_PORTS; port++) {
-	xbow_soft->xbow_link_status[port].rx_err_count = 0;
-	xbow_soft->xbow_link_status[port].tx_retry_count = 0;
-    }
-
-    xbow_soft->link_monitor = 0;
-    return 0;
-}
-
-int
-xbow_enable_llp_monitor(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-
-#ifdef LATER
-    (void) timeout(xbow_update_llp_status,
-		   (void *) (__psunsigned_t) vhdl, XBOW_STATS_TIMEOUT);
-#endif
-    xbow_soft->link_monitor = 1;
-    return 0;
-}
-
-
-int
-xbow_reset_link(devfs_handle_t xconn_vhdl)
-{
-    xwidget_info_t          widget_info;
-    xwidgetnum_t            port;
-    xbow_t                 *xbow;
-    xbowreg_t               ctrl;
-    xbwX_stat_t             stat;
-    unsigned                itick;
-    unsigned                dtick;
-    static int              ticks_per_ms = 0;
-
-    if (!ticks_per_ms) {
-	itick = get_timestamp();
-	us_delay(1000);
-	ticks_per_ms = get_timestamp() - itick;
-    }
-    widget_info = xwidget_info_get(xconn_vhdl);
-    port = xwidget_info_id_get(widget_info);
-
-#ifdef XBOW_K1PTR			/* defined if we only have one xbow ... */
-    xbow = XBOW_K1PTR;
-#else
-    {
-	devfs_handle_t            xbow_vhdl;
-	xbow_soft_t             xbow_soft;
-
-	hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl);
-	xbow_soft = xbow_soft_get(xbow_vhdl);
-	xbow = xbow_soft->base;
-    }
-#endif
-
-    /*
-     * This requires three PIOs (reset the link, check for the
-     * reset, restore the control register for the link) plus
-     * 10us to wait for the reset. We allow up to 1ms for the
-     * widget to come out of reset before giving up and
-     * returning a failure.
-     */
-    ctrl = xbow->xb_link(port).link_control;
-    xbow->xb_link(port).link_reset = 0;
-    itick = get_timestamp();
-    while (1) {
-	stat.linkstatus = xbow->xb_link(port).link_status;
-	if (stat.link_alive)
-	    break;
-	dtick = get_timestamp() - itick;
-	if (dtick > ticks_per_ms) {
-	    return -1;			/* never came out of reset */
-	}
-	DELAY(2);			/* don't beat on link_status */
-    }
-    xbow->xb_link(port).link_control = ctrl;
-    return 0;
-}
-
-/*
- * Dump xbow registers.
- * input parameter is either a pointer to
- * the xbow chip or the vertex handle for
- * an xbow vertex.
- */
-void
-idbg_xbowregs(int64_t regs)
-{
-    xbow_t                 *xbow;
-    int                     i;
-    xb_linkregs_t          *link;
-
-#ifdef LATER
-    if (dev_is_vertex((devfs_handle_t) regs)) {
-	devfs_handle_t            vhdl = (devfs_handle_t) regs;
-	xbow_soft_t             soft = xbow_soft_get(vhdl);
-
-	xbow = soft->base;
-    } else
-#endif
-    {
-	xbow = (xbow_t *) regs;
-    }
-
-#ifdef LATER
-    qprintf("Printing xbow registers starting at 0x%x\n", xbow);
-    qprintf("wid %x status %x erruppr %x errlower %x control %x timeout %x\n",
-	    xbow->xb_wid_id, xbow->xb_wid_stat, xbow->xb_wid_err_upper,
-	    xbow->xb_wid_err_lower, xbow->xb_wid_control,
-	    xbow->xb_wid_req_timeout);
-    qprintf("intr uppr %x lower %x errcmd %x llp ctrl %x arb_reload %x\n",
-	    xbow->xb_wid_int_upper, xbow->xb_wid_int_lower,
-	    xbow->xb_wid_err_cmdword, xbow->xb_wid_llp,
-	    xbow->xb_wid_arb_reload);
-#endif
-
-    for (i = 8; i <= 0xf; i++) {
-	link = &xbow->xb_link(i);
-#ifdef LATER
-	qprintf("Link %d registers\n", i);
-	qprintf("\tctrl %x stat %x arbuppr %x arblowr %x auxstat %x\n",
-		link->link_control, link->link_status,
-		link->link_arb_upper, link->link_arb_lower,
-		link->link_aux_status);
-#endif
-    }
-}
-
-
-#define XBOW_ARB_RELOAD_TICKS		25
-					/* granularity: 4 MB/s, max: 124 MB/s */
-#define GRANULARITY			((100 * 1000000) / XBOW_ARB_RELOAD_TICKS)
-
-#define XBOW_BYTES_TO_GBR(BYTES_per_s)	(int) (BYTES_per_s / GRANULARITY)
-
-#define XBOW_GBR_TO_BYTES(cnt)		(bandwidth_t) ((cnt) * GRANULARITY)
-
-#define CEILING_BYTES_TO_GBR(gbr, bytes_per_sec)	\
-			((XBOW_GBR_TO_BYTES(gbr) < bytes_per_sec) ? gbr+1 : gbr)
-
-#define XBOW_ARB_GBR_MAX		31
-
-#define ABS(x)				((x > 0) ? (x) : (-1 * x))
-					/* absolute value */
-
-int
-xbow_bytes_to_gbr(bandwidth_t old_bytes_per_sec, bandwidth_t bytes_per_sec)
-{
-    int                     gbr_granted;
-    int                     new_total_gbr;
-    int                     change_gbr;
-    bandwidth_t             new_total_bw;
-
-#ifdef GRIO_DEBUG
-    printf("xbow_bytes_to_gbr: old_bytes_per_sec %lld bytes_per_sec %lld\n",
-		old_bytes_per_sec, bytes_per_sec);
-#endif	/* GRIO_DEBUG */
-
-    gbr_granted = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(old_bytes_per_sec)),
-			old_bytes_per_sec);
-    new_total_bw = old_bytes_per_sec + bytes_per_sec;
-    new_total_gbr = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(new_total_bw)),
-			new_total_bw);
-
-    change_gbr = new_total_gbr - gbr_granted;
-
-#ifdef GRIO_DEBUG
-    printf("xbow_bytes_to_gbr: gbr_granted %d new_total_gbr %d change_gbr %d\n",
-		gbr_granted, new_total_gbr, change_gbr);
-#endif	/* GRIO_DEBUG */
-
-    return (change_gbr);
-}
-
-/* Conversion from GBR to bytes */
-bandwidth_t
-xbow_gbr_to_bytes(int gbr)
-{
-    return (XBOW_GBR_TO_BYTES(gbr));
-}
-
-/* Given the vhdl for the desired xbow, the src and dest. widget ids
- * and the req_bw value, this xbow driver entry point accesses the
- * xbow registers and allocates the desired bandwidth if available.
- *
- * If bandwidth allocation is successful, return success else return failure.
- */
-int
-xbow_prio_bw_alloc(devfs_handle_t vhdl,
-		xwidgetnum_t src_wid,
-		xwidgetnum_t dest_wid,
-		unsigned long long old_alloc_bw,
-		unsigned long long req_bw)
-{
-    xbow_soft_t             soft = xbow_soft_get(vhdl);
-    volatile xbowreg_t     *xreg;
-    xbowreg_t               mask;
-    unsigned long           s;
-    int                     error = 0;
-    bandwidth_t             old_bw_BYTES, req_bw_BYTES;
-    xbowreg_t               old_xreg;
-    int                     old_bw_GBR, req_bw_GBR, new_bw_GBR;
-
-#ifdef GRIO_DEBUG
-    printf("xbow_prio_bw_alloc: vhdl %d src_wid %d dest_wid %d req_bw %lld\n",
-		(int) vhdl, (int) src_wid, (int) dest_wid, req_bw);
-#endif
-
-    ASSERT(XBOW_WIDGET_IS_VALID(src_wid));
-    ASSERT(XBOW_WIDGET_IS_VALID(dest_wid));
-
-    s = mutex_spinlock(&soft->xbow_bw_alloc_lock);
-
-    /* Get pointer to the correct register */
-    xreg = XBOW_PRIO_ARBREG_PTR(soft->base, dest_wid, src_wid);
-
-    /* Get mask for GBR count value */
-    mask = XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(src_wid);
-
-    req_bw_GBR = xbow_bytes_to_gbr(old_alloc_bw, req_bw);
-    req_bw_BYTES = (req_bw_GBR < 0) ? (-1 * xbow_gbr_to_bytes(ABS(req_bw_GBR)))
-		: xbow_gbr_to_bytes(req_bw_GBR);
-
-#ifdef GRIO_DEBUG
-    printf("req_bw %lld req_bw_BYTES %lld req_bw_GBR %d\n",
-		req_bw, req_bw_BYTES, req_bw_GBR);
-#endif	/* GRIO_DEBUG */
-
-    old_bw_BYTES = soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS];
-    old_xreg = *xreg;
-    old_bw_GBR = (((*xreg) & mask) >> XB_ARB_GBR_SHFT(src_wid));
-
-#ifdef GRIO_DEBUG
-    ASSERT(XBOW_BYTES_TO_GBR(old_bw_BYTES) == old_bw_GBR);
-
-    printf("old_bw_BYTES %lld old_bw_GBR %d\n", old_bw_BYTES, old_bw_GBR);
-
-    printf("req_bw_BYTES %lld old_bw_BYTES %lld soft->bw_hiwm %lld\n",
-		req_bw_BYTES, old_bw_BYTES,
-		soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]);
-	   
-#endif				/* GRIO_DEBUG */
-
-    /* Accept the request only if we don't exceed the destination
-     * port HIWATER_MARK *AND* the max. link GBR arbitration count
-     */
-    if (((old_bw_BYTES + req_bw_BYTES) <=
-		soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]) &&
-		(req_bw_GBR + old_bw_GBR <= XBOW_ARB_GBR_MAX)) {
-
-	new_bw_GBR = (old_bw_GBR + req_bw_GBR);
-
-	/* Set this in the xbow link register */
-	*xreg = (old_xreg & ~mask) | \
-	    (new_bw_GBR << XB_ARB_GBR_SHFT(src_wid) & mask);
-
-	soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS] =
-			xbow_gbr_to_bytes(new_bw_GBR);
-    } else {
-	error = 1;
-    }
-
-    mutex_spinunlock(&soft->xbow_bw_alloc_lock, s);
-
-    return (error);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/xswitch.c linux-2.4.22-pre10/arch/ia64/sn/io/xswitch.c
--- linux-2.4.21/arch/ia64/sn/io/xswitch.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/xswitch.c	2003-08-01 13:31:48.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -23,8 +23,6 @@
 #define	NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
 #define	DEL(ptr)	(kfree(ptr))
 
-int                     xswitch_devflag = D_MP;
-
 /*
  * This file provides generic support for Crosstalk
  * Switches, in a way that insulates crosstalk providers
@@ -45,9 +43,9 @@
 #define	DEV_FUNC(dev,func)	xwidget_to_provider_fns(dev)->func
 
 static xswitch_provider_t *
-xwidget_to_provider_fns(devfs_handle_t xconn)
+xwidget_to_provider_fns(vertex_hdl_t xconn)
 {
-    devfs_handle_t            busv;
+    vertex_hdl_t            busv;
     xswitch_info_t          xswitch_info;
     xswitch_provider_t      provider_fns;
 
@@ -75,27 +73,18 @@
 struct xswitch_info_s {
     char                   *fingerprint;
     unsigned                census;
-    devfs_handle_t            vhdl[XSWITCH_CENSUS_PORTS];
-    devfs_handle_t            master_vhdl[XSWITCH_CENSUS_PORTS];
+    vertex_hdl_t            vhdl[XSWITCH_CENSUS_PORTS];
+    vertex_hdl_t            master_vhdl[XSWITCH_CENSUS_PORTS];
     xswitch_provider_t     *xswitch_fns;
 };
 
 xswitch_info_t
-xswitch_info_get(devfs_handle_t xwidget)
+xswitch_info_get(vertex_hdl_t xwidget)
 {
     xswitch_info_t          xswitch_info;
 
     xswitch_info = (xswitch_info_t)
 	hwgraph_fastinfo_get(xwidget);
-#ifdef	LATER
-    if ((xswitch_info != NULL) &&
-	(xswitch_info->fingerprint != xswitch_info_fingerprint))
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	PRINT_PANIC("%v xswitch_info_get bad fingerprint", xwidget);
-#else
-	PRINT_PANIC("%x xswitch_info_get bad fingerprint", xwidget);
-#endif
-#endif	/* LATER */
 
     return (xswitch_info);
 }
@@ -103,7 +92,7 @@
 void
 xswitch_info_vhdl_set(xswitch_info_t xswitch_info,
 		      xwidgetnum_t port,
-		      devfs_handle_t xwidget)
+		      vertex_hdl_t xwidget)
 {
 #if XSWITCH_CENSUS_PORT_MIN
     if (port < XSWITCH_CENSUS_PORT_MIN)
@@ -115,15 +104,10 @@
     xswitch_info->vhdl[port - XSWITCH_CENSUS_PORT_MIN] = xwidget;
 }
 
-devfs_handle_t
+vertex_hdl_t
 xswitch_info_vhdl_get(xswitch_info_t xswitch_info,
 		      xwidgetnum_t port)
 {
-#ifdef	LATER
-    if (xswitch_info == NULL)
-	PRINT_PANIC("xswitch_info_vhdl_get: null xswitch_info");
-#endif
-
 #if XSWITCH_CENSUS_PORT_MIN
     if (port < XSWITCH_CENSUS_PORT_MIN)
 	return GRAPH_VERTEX_NONE;
@@ -142,7 +126,7 @@
 void
 xswitch_info_master_assignment_set(xswitch_info_t xswitch_info,
 				   xwidgetnum_t port,
-				   devfs_handle_t master_vhdl)
+				   vertex_hdl_t master_vhdl)
 {
 #if XSWITCH_CENSUS_PORT_MIN
     if (port < XSWITCH_CENSUS_PORT_MIN)
@@ -154,7 +138,7 @@
     xswitch_info->master_vhdl[port - XSWITCH_CENSUS_PORT_MIN] = master_vhdl;
 }
 
-devfs_handle_t
+vertex_hdl_t
 xswitch_info_master_assignment_get(xswitch_info_t xswitch_info,
 				   xwidgetnum_t port)
 {
@@ -169,14 +153,14 @@
 }
 
 void
-xswitch_info_set(devfs_handle_t xwidget, xswitch_info_t xswitch_info)
+xswitch_info_set(vertex_hdl_t xwidget, xswitch_info_t xswitch_info)
 {
     xswitch_info->fingerprint = xswitch_info_fingerprint;
     hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) xswitch_info);
 }
 
 xswitch_info_t
-xswitch_info_new(devfs_handle_t xwidget)
+xswitch_info_new(vertex_hdl_t xwidget)
 {
     xswitch_info_t          xswitch_info;
 
@@ -202,7 +186,7 @@
 }
 
 void
-xswitch_provider_register(devfs_handle_t busv,
+xswitch_provider_register(vertex_hdl_t busv,
 			  xswitch_provider_t * xswitch_fns)
 {
     xswitch_info_t          xswitch_info = xswitch_info_get(busv);
@@ -232,35 +216,8 @@
 }
 
 int
-xswitch_reset_link(devfs_handle_t xconn_vhdl)
+xswitch_reset_link(vertex_hdl_t xconn_vhdl)
 {
     return DEV_FUNC(xconn_vhdl, reset_link)
 	(xconn_vhdl);
 }
-
-/* Given a vertex handle to the xswitch get its logical
- * id.
- */
-int
-xswitch_id_get(devfs_handle_t	xconn_vhdl)
-{
-    arbitrary_info_t 	xbow_num;
-    graph_error_t	rv;
-
-    rv = hwgraph_info_get_LBL(xconn_vhdl,INFO_LBL_XSWITCH_ID,&xbow_num);
-    ASSERT(rv == GRAPH_SUCCESS);
-    return(xbow_num);
-}
-
-/* Given a vertex handle to the xswitch set its logical
- * id.
- */
-void
-xswitch_id_set(devfs_handle_t	xconn_vhdl,int xbow_num)
-{
-    graph_error_t	rv;
-
-    rv = hwgraph_info_add_LBL(xconn_vhdl,INFO_LBL_XSWITCH_ID,
-			      (arbitrary_info_t)xbow_num);
-    ASSERT(rv == GRAPH_SUCCESS);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/io/xtalk.c linux-2.4.22-pre10/arch/ia64/sn/io/xtalk.c
--- linux-2.4.21/arch/ia64/sn/io/xtalk.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/io/xtalk.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1024 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-
-/*
- * Implement crosstalk provider operations.  The xtalk* layer provides a
- * platform-independent interface for crosstalk devices.  This layer
- * switches among the possible implementations of a crosstalk adapter.
- *
- * On platforms with only one possible xtalk provider, macros can be
- * set up at the top that cause the table lookups and indirections to
- * completely disappear.
- */
-
-#define	NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define	DEL(ptr)	(kfree(ptr))
-
-char                    widget_info_fingerprint[] = "widget_info";
-
-cdl_p                   xtalk_registry = NULL;
-
-#define	DEV_FUNC(dev,func)	hub_##func
-#define	CAST_PIOMAP(x)		((hub_piomap_t)(x))
-#define	CAST_DMAMAP(x)		((hub_dmamap_t)(x))
-#define	CAST_INTR(x)		((hub_intr_t)(x))
-
-/* =====================================================================
- *            Function Table of Contents
- */
-xtalk_piomap_t          xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);
-void                    xtalk_piomap_free(xtalk_piomap_t);
-caddr_t                 xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t);
-void                    xtalk_piomap_done(xtalk_piomap_t);
-caddr_t                 xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned);
-caddr_t                 xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);
-void                    xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *);
-caddr_t                 xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
-static caddr_t          null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
-xtalk_dmamap_t          xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    xtalk_dmamap_free(xtalk_dmamap_t);
-iopaddr_t               xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t);
-alenlist_t              xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned);
-void                    xtalk_dmamap_done(xtalk_dmamap_t);
-iopaddr_t               xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void			xtalk_dmamap_drain(xtalk_dmamap_t);
-void			xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t);
-void			xtalk_dmalist_drain(devfs_handle_t, alenlist_t);
-xtalk_intr_t            xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t);
-xtalk_intr_t            xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t);
-void                    xtalk_intr_free(xtalk_intr_t);
-int                     xtalk_intr_connect(xtalk_intr_t, xtalk_intr_setfunc_t, void *);
-void                    xtalk_intr_disconnect(xtalk_intr_t);
-devfs_handle_t            xtalk_intr_cpu_get(xtalk_intr_t);
-int                     xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
-int                     xtalk_error_devenable(devfs_handle_t, int, int);
-void                    xtalk_provider_startup(devfs_handle_t);
-void                    xtalk_provider_shutdown(devfs_handle_t);
-devfs_handle_t            xtalk_intr_dev_get(xtalk_intr_t);
-xwidgetnum_t            xtalk_intr_target_get(xtalk_intr_t);
-xtalk_intr_vector_t     xtalk_intr_vector_get(xtalk_intr_t);
-iopaddr_t               xtalk_intr_addr_get(struct xtalk_intr_s *);
-void                   *xtalk_intr_sfarg_get(xtalk_intr_t);
-devfs_handle_t            xtalk_pio_dev_get(xtalk_piomap_t);
-xwidgetnum_t            xtalk_pio_target_get(xtalk_piomap_t);
-iopaddr_t               xtalk_pio_xtalk_addr_get(xtalk_piomap_t);
-ulong                   xtalk_pio_mapsz_get(xtalk_piomap_t);
-caddr_t                 xtalk_pio_kvaddr_get(xtalk_piomap_t);
-devfs_handle_t            xtalk_dma_dev_get(xtalk_dmamap_t);
-xwidgetnum_t            xtalk_dma_target_get(xtalk_dmamap_t);
-xwidget_info_t          xwidget_info_chk(devfs_handle_t);
-xwidget_info_t          xwidget_info_get(devfs_handle_t);
-void                    xwidget_info_set(devfs_handle_t, xwidget_info_t);
-devfs_handle_t            xwidget_info_dev_get(xwidget_info_t);
-xwidgetnum_t            xwidget_info_id_get(xwidget_info_t);
-devfs_handle_t            xwidget_info_master_get(xwidget_info_t);
-xwidgetnum_t            xwidget_info_masterid_get(xwidget_info_t);
-xwidget_part_num_t      xwidget_info_part_num_get(xwidget_info_t);
-xwidget_mfg_num_t       xwidget_info_mfg_num_get(xwidget_info_t);
-char 			*xwidget_info_name_get(xwidget_info_t);
-void                    xtalk_init(void);
-void                    xtalk_provider_register(devfs_handle_t, xtalk_provider_t *);
-void                    xtalk_provider_unregister(devfs_handle_t);
-xtalk_provider_t       *xtalk_provider_fns_get(devfs_handle_t);
-int                     xwidget_driver_register(xwidget_part_num_t, 
-						xwidget_mfg_num_t, 
-						char *, unsigned);
-void                    xwidget_driver_unregister(char *);
-int                     xwidget_register(xwidget_hwid_t, devfs_handle_t, 
-					 xwidgetnum_t, devfs_handle_t, 
-					 xwidgetnum_t, async_attach_t);
-int			xwidget_unregister(devfs_handle_t);
-void                    xwidget_reset(devfs_handle_t);
-char			*xwidget_name_get(devfs_handle_t);
-#if !defined(DEV_FUNC)
-/*
- * There is more than one possible provider
- * for this platform. We need to examine the
- * master vertex of the current vertex for
- * a provider function structure, and indirect
- * through the appropriately named member.
- */
-#define	DEV_FUNC(dev,func)	xwidget_to_provider_fns(dev)->func
-#define	CAST_PIOMAP(x)		((xtalk_piomap_t)(x))
-#define	CAST_DMAMAP(x)		((xtalk_dmamap_t)(x))
-#define	CAST_INTR(x)		((xtalk_intr_t)(x))
-
-static xtalk_provider_t *
-xwidget_to_provider_fns(devfs_handle_t xconn)
-{
-    xwidget_info_t          widget_info;
-    xtalk_provider_t       *provider_fns;
-
-    widget_info = xwidget_info_get(xconn);
-    ASSERT(widget_info != NULL);
-
-    provider_fns = xwidget_info_pops_get(widget_info);
-    ASSERT(provider_fns != NULL);
-
-    return (provider_fns);
-}
-#endif
-
-/*
- * Many functions are not passed their vertex
- * information directly; rather, they must
- * dive through a resource map. These macros
- * are available to coordinate this detail.
- */
-#define	PIOMAP_FUNC(map,func)	DEV_FUNC(map->xp_dev,func)
-#define	DMAMAP_FUNC(map,func)	DEV_FUNC(map->xd_dev,func)
-#define	INTR_FUNC(intr,func)	DEV_FUNC(intr_hdl->xi_dev,func)
-
-/* =====================================================================
- *                    PIO MANAGEMENT
- *
- *      For mapping system virtual address space to
- *      xtalk space on a specified widget
- */
-
-xtalk_piomap_t
-xtalk_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
-		   size_t byte_count,
-		   size_t byte_count_max,	/* maximum size of a mapping */
-		   unsigned flags)
-{				/* defined in sys/pio.h */
-    return (xtalk_piomap_t) DEV_FUNC(dev, piomap_alloc)
-	(dev, dev_desc, xtalk_addr, byte_count, byte_count_max, flags);
-}
-
-
-void
-xtalk_piomap_free(xtalk_piomap_t xtalk_piomap)
-{
-    PIOMAP_FUNC(xtalk_piomap, piomap_free)
-	(CAST_PIOMAP(xtalk_piomap));
-}
-
-
-caddr_t
-xtalk_piomap_addr(xtalk_piomap_t xtalk_piomap,	/* mapping resources */
-		  iopaddr_t xtalk_addr,		/* map for this xtalk address */
-		  size_t byte_count)
-{				/* map this many bytes */
-    return PIOMAP_FUNC(xtalk_piomap, piomap_addr)
-	(CAST_PIOMAP(xtalk_piomap), xtalk_addr, byte_count);
-}
-
-
-void
-xtalk_piomap_done(xtalk_piomap_t xtalk_piomap)
-{
-    PIOMAP_FUNC(xtalk_piomap, piomap_done)
-	(CAST_PIOMAP(xtalk_piomap));
-}
-
-
-caddr_t
-xtalk_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    iopaddr_t xtalk_addr,	/* Crosstalk address */
-		    size_t byte_count,	/* map this many bytes */
-		    unsigned flags)
-{				/* (currently unused) */
-    return DEV_FUNC(dev, piotrans_addr)
-	(dev, dev_desc, xtalk_addr, byte_count, flags);
-}
-
-caddr_t
-xtalk_pio_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       iopaddr_t addr,		/* starting address (or offset in window) */
-	       size_t byte_count,	/* map this many bytes */
-	       xtalk_piomap_t *mapp,	/* where to return the map pointer */
-	       unsigned flags)
-{					/* PIO flags */
-    xtalk_piomap_t          map = 0;
-    caddr_t                 res;
-
-    if (mapp)
-	*mapp = 0;			/* record "no map used" */
-
-    res = xtalk_piotrans_addr
-	(dev, dev_desc, addr, byte_count, flags);
-    if (res)
-	return res;			/* xtalk_piotrans worked */
-
-    map = xtalk_piomap_alloc
-	(dev, dev_desc, addr, byte_count, byte_count, flags);
-    if (!map)
-	return res;			/* xtalk_piomap_alloc failed */
-
-    res = xtalk_piomap_addr
-	(map, addr, byte_count);
-    if (!res) {
-	xtalk_piomap_free(map);
-	return res;			/* xtalk_piomap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* xtalk_piomap_addr succeeded */
-}
-
-/* =====================================================================
- *            EARLY PIOTRANS SUPPORT
- *
- *      There are places where drivers (mgras, for instance)
- *      need to get PIO translations before the infrastructure
- *      is extended to them (setting up textports, for
- *      instance). These drivers should call
- *      xtalk_early_piotrans_addr with their xtalk ID
- *      information, a sequence number (so we can use the second
- *      mgras for instance), and the usual piotrans parameters.
- *
- *      Machine specific code should provide an implementation
- *      of early_piotrans_addr, and present a pointer to this
- *      function to xtalk_set_early_piotrans_addr so it can be
- *      used by clients without the clients having to know what
- *      platform or what xtalk provider is in use.
- */
-
-static xtalk_early_piotrans_addr_f null_xtalk_early_piotrans_addr;
-
-xtalk_early_piotrans_addr_f *impl_early_piotrans_addr = null_xtalk_early_piotrans_addr;
-
-/* xtalk_set_early_piotrans_addr:
- * specify the early_piotrans_addr implementation function.
- */
-void
-xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *impl)
-{
-    impl_early_piotrans_addr = impl;
-}
-
-/* xtalk_early_piotrans_addr:
- * figure out a PIO address for the "nth" crosstalk widget that
- * matches the specified part and mfgr number. Returns NULL if
- * there is no such widget, or if the requested mapping can not
- * be constructed.
- * Limitations on which crosstalk slots (and busses) are
- * checked, and definitions of the ordering of the search across
- * the crosstalk slots, are defined by the platform.
- */
-caddr_t
-xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
-			  xwidget_mfg_num_t mfg_num,
-			  int which,
-			  iopaddr_t xtalk_addr,
-			  size_t byte_count,
-			  unsigned flags)
-{
-    return impl_early_piotrans_addr
-	(part_num, mfg_num, which, xtalk_addr, byte_count, flags);
-}
-
-/* null_xtalk_early_piotrans_addr:
- * used as the early_piotrans_addr implementation until and
- * unless a real implementation is provided. In DEBUG kernels,
- * we want to know who is calling before the implementation is
- * registered; in non-DEBUG kernels, return NULL representing
- * lack of mapping support.
- */
-/*ARGSUSED */
-static caddr_t
-null_xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
-			       xwidget_mfg_num_t mfg_num,
-			       int which,
-			       iopaddr_t xtalk_addr,
-			       size_t byte_count,
-			       unsigned flags)
-{
-#if DEBUG
-    PRINT_PANIC("null_xtalk_early_piotrans_addr");
-#endif
-    return NULL;
-}
-
-/* =====================================================================
- *                    DMA MANAGEMENT
- *
- *      For mapping from crosstalk space to system
- *      physical space.
- */
-
-xtalk_dmamap_t
-xtalk_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   size_t byte_count_max,	/* max size of a mapping */
-		   unsigned flags)
-{				/* defined in dma.h */
-    return (xtalk_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-	(dev, dev_desc, byte_count_max, flags);
-}
-
-
-void
-xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap)
-{
-    DMAMAP_FUNC(xtalk_dmamap, dmamap_free)
-	(CAST_DMAMAP(xtalk_dmamap));
-}
-
-
-iopaddr_t
-xtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap,	/* use these mapping resources */
-		  paddr_t paddr,	/* map for this address */
-		  size_t byte_count)
-{				/* map this many bytes */
-    return DMAMAP_FUNC(xtalk_dmamap, dmamap_addr)
-	(CAST_DMAMAP(xtalk_dmamap), paddr, byte_count);
-}
-
-
-alenlist_t
-xtalk_dmamap_list(xtalk_dmamap_t xtalk_dmamap,	/* use these mapping resources */
-		  alenlist_t alenlist,	/* map this Address/Length List */
-		  unsigned flags)
-{
-    return DMAMAP_FUNC(xtalk_dmamap, dmamap_list)
-	(CAST_DMAMAP(xtalk_dmamap), alenlist, flags);
-}
-
-
-void
-xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap)
-{
-    DMAMAP_FUNC(xtalk_dmamap, dmamap_done)
-	(CAST_DMAMAP(xtalk_dmamap));
-}
-
-
-iopaddr_t
-xtalk_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    paddr_t paddr,	/* system physical address */
-		    size_t byte_count,	/* length */
-		    unsigned flags)
-{				/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_addr)
-	(dev, dev_desc, paddr, byte_count, flags);
-}
-
-
-alenlist_t
-xtalk_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    alenlist_t palenlist,	/* system address/length list */
-		    unsigned flags)
-{				/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-	(dev, dev_desc, palenlist, flags);
-}
-
-void
-xtalk_dmamap_drain(xtalk_dmamap_t map)
-{
-    DMAMAP_FUNC(map, dmamap_drain)
-	(CAST_DMAMAP(map));
-}
-
-void
-xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
-{
-    DEV_FUNC(dev, dmaaddr_drain)
-	(dev, addr, size);
-}
-
-void
-xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list)
-{
-    DEV_FUNC(dev, dmalist_drain)
-	(dev, list);
-}
-
-/* =====================================================================
- *                    INTERRUPT MANAGEMENT
- *
- *      Allow crosstalk devices to establish interrupts
- */
-
-/*
- * Allocate resources required for an interrupt as specified in intr_desc.
- * Return resource handle in intr_hdl.
- */
-xtalk_intr_t
-xtalk_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
-		 device_desc_t dev_desc,	/* device descriptor */
-		 devfs_handle_t owner_dev)
-{				/* owner of this interrupt */
-    return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc)
-	(dev, dev_desc, owner_dev);
-}
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Unconditionally setup resources to be non-threaded.
- * Return resource handle in intr_hdl.
- */
-xtalk_intr_t
-xtalk_intr_alloc_nothd(devfs_handle_t dev,	/* which Crosstalk device */
-		 	device_desc_t dev_desc,	/* device descriptor */
-		 	devfs_handle_t owner_dev)	/* owner of this interrupt */
-{
-    return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd)
-	(dev, dev_desc, owner_dev);
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-xtalk_intr_free(xtalk_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_free)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/*
- * Associate resources allocated with a previous xtalk_intr_alloc call with the
- * described handler, arg, name, etc.
- *
- * Returns 0 on success, returns <0 on failure.
- */
-int
-xtalk_intr_connect(xtalk_intr_t intr_hdl,	/* xtalk intr resource handle */
-		   xtalk_intr_setfunc_t setfunc,	/* func to set intr hw */
-		   void *setfunc_arg)	/* arg to setfunc */
-{
-    return INTR_FUNC(intr_hdl, intr_connect)
-	(CAST_INTR(intr_hdl), setfunc, setfunc_arg);
-}
-
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-xtalk_intr_disconnect(xtalk_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_disconnect)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-xtalk_intr_cpu_get(xtalk_intr_t intr_hdl)
-{
-    return INTR_FUNC(intr_hdl, intr_cpu_get)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/* =====================================================================
- *                    CONFIGURATION MANAGEMENT
- */
-
-/*
- * Startup a crosstalk provider
- */
-void
-xtalk_provider_startup(devfs_handle_t xtalk_provider)
-{
-    DEV_FUNC(xtalk_provider, provider_startup)
-	(xtalk_provider);
-}
-
-
-/*
- * Shutdown a crosstalk provider
- */
-void
-xtalk_provider_shutdown(devfs_handle_t xtalk_provider)
-{
-    DEV_FUNC(xtalk_provider, provider_shutdown)
-	(xtalk_provider);
-}
-
-/* 
- * Enable a device on a xtalk widget 
- */
-void
-xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum)
-{
-    DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum);
-}
-
-/* 
- * Shutdown a device on a xtalk widget 
- */
-void
-xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum)
-{
-    DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum);
-}
-
-int
-xtalk_dma_enabled(devfs_handle_t xconn_vhdl)
-{
-    return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl);
-}
-/*
- * Generic crosstalk functions, for use with all crosstalk providers
- * and all crosstalk devices.
- */
-
-/****** Generic crosstalk interrupt interfaces ******/
-devfs_handle_t
-xtalk_intr_dev_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_dev);
-}
-
-xwidgetnum_t
-xtalk_intr_target_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_target);
-}
-
-xtalk_intr_vector_t
-xtalk_intr_vector_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_vector);
-}
-
-iopaddr_t
-xtalk_intr_addr_get(struct xtalk_intr_s *xtalk_intr)
-{
-    return (xtalk_intr->xi_addr);
-}
-
-void                   *
-xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_sfarg);
-}
-
-/****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
-xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_dev);
-}
-
-xwidgetnum_t
-xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_target);
-}
-
-iopaddr_t
-xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_xtalk_addr);
-}
-
-ulong
-xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_mapsz);
-}
-
-caddr_t
-xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_kvaddr);
-}
-
-
-/****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
-xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap)
-{
-    return (xtalk_dmamap->xd_dev);
-}
-
-xwidgetnum_t
-xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap)
-{
-    return (xtalk_dmamap->xd_target);
-}
-
-
-/****** Generic crosstalk widget information interfaces ******/
-
-/* xwidget_info_chk:
- * check to see if this vertex is a widget;
- * if so, return its widget_info (if any).
- * if not, return NULL.
- */
-xwidget_info_t
-xwidget_info_chk(devfs_handle_t xwidget)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    hwgraph_info_get_LBL(xwidget, INFO_LBL_XWIDGET, &ainfo);
-    return (xwidget_info_t) ainfo;
-}
-
-
-xwidget_info_t
-xwidget_info_get(devfs_handle_t xwidget)
-{
-    xwidget_info_t          widget_info;
-
-    widget_info = (xwidget_info_t)
-	hwgraph_fastinfo_get(xwidget);
-
-#ifdef	LATER
-    if ((widget_info != NULL) &&
-	(widget_info->w_fingerprint != widget_info_fingerprint))
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	PRINT_PANIC("%v bad xwidget_info", xwidget);
-#else
-	PRINT_PANIC("%x bad xwidget_info", xwidget);
-#endif
-#endif	/* LATER */
-
-    return (widget_info);
-}
-
-void
-xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info)
-{
-    if (widget_info != NULL)
-	widget_info->w_fingerprint = widget_info_fingerprint;
-
-    hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) widget_info);
-
-    /* Also, mark this vertex as an xwidget,
-     * and use the widget_info, so xwidget_info_chk
-     * can work (and be fairly efficient).
-     */
-    hwgraph_info_add_LBL(xwidget, INFO_LBL_XWIDGET,
-			 (arbitrary_info_t) widget_info);
-}
-
-devfs_handle_t
-xwidget_info_dev_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_vertex);
-}
-
-xwidgetnum_t
-xwidget_info_id_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_id);
-}
-
-
-devfs_handle_t
-xwidget_info_master_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_master);
-}
-
-xwidgetnum_t
-xwidget_info_masterid_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_masterid);
-}
-
-xwidget_part_num_t
-xwidget_info_part_num_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_hwid.part_num);
-}
-
-xwidget_mfg_num_t
-xwidget_info_mfg_num_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_hwid.mfg_num);
-}
-/* Extract the widget name from the widget information
- * for the xtalk widget.
- */
-char *
-xwidget_info_name_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget info");
-    return(xwidget_info->w_name);
-}
-/****** Generic crosstalk initialization interfaces ******/
-
-/*
- * One-time initialization needed for systems that support crosstalk.
- */
-void
-xtalk_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("xtalk_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (xtalk_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr");
-	if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(xtalk_registry != NULL);
-}
-
-/*
- * Associate a set of xtalk_provider functions with a vertex.
- */
-void
-xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns)
-{
-    hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns);
-}
-
-/*
- * Disassociate a set of xtalk_provider functions with a vertex.
- */
-void
-xtalk_provider_unregister(devfs_handle_t provider)
-{
-    hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL);
-}
-
-/*
- * Obtain a pointer to the xtalk_provider functions for a specified Crosstalk
- * provider.
- */
-xtalk_provider_t       *
-xtalk_provider_fns_get(devfs_handle_t provider)
-{
-    return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider));
-}
-
-/*
- * Announce a driver for a particular crosstalk part.
- * Returns 0 on success or -1 on failure.  Failure occurs if the
- * specified hardware already has a driver.
- */
-/*ARGSUSED4 */
-int
-xwidget_driver_register(xwidget_part_num_t part_num,
-			xwidget_mfg_num_t mfg_num,
-			char *driver_prefix,
-			unsigned flags)
-{
-    /* a driver's init routine could call
-     * xwidget_driver_register before the
-     * system calls xtalk_init; so, we
-     * make the call here.
-     */
-    if (xtalk_registry == NULL)
-	xtalk_init();
-
-    return cdl_add_driver(xtalk_registry,
-			  part_num, mfg_num,
-			  driver_prefix, flags, NULL);
-}
-
-/*
- * Inform xtalk infrastructure that a driver is no longer available for
- * handling any widgets.
- */
-void
-xwidget_driver_unregister(char *driver_prefix)
-{
-    /* before a driver calls unregister,
-     * it must have called registger; so we
-     * can assume we have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_del_driver(xtalk_registry, driver_prefix, NULL);
-}
-
-/*
- * Call some function with each vertex that
- * might be one of this driver's attach points.
- */
-void
-xtalk_iterate(char *driver_prefix,
-	      xtalk_iter_f *func)
-{
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func);
-}
-
-/*
- * xwidget_register:
- *	Register a xtalk device (xwidget) by doing the following.
- *      -allocate and initialize xwidget_info data
- *      -allocate a hwgraph vertex with name based on widget number (id)
- *      -look up the widget's initialization function and call it,
- *      or remember the vertex for later initialization.
- *
- */
-int
-xwidget_register(xwidget_hwid_t hwid,		/* widget's hardware ID */
-		 devfs_handle_t 	widget,		/* widget to initialize */
-		 xwidgetnum_t 	id,		/* widget's target id (0..f) */
-		 devfs_handle_t 	master,		/* widget's master vertex */
-		 xwidgetnum_t 	targetid,	/* master's target id (9/a) */
-		 async_attach_t aa)
-{			
-    xwidget_info_t          widget_info;
-    char		    *s,devnm[MAXDEVNAME];
-
-    /* Allocate widget_info and associate it with widget vertex */
-    NEW(widget_info);
-
-    /* Initialize widget_info */
-    widget_info->w_vertex = widget;
-    widget_info->w_id = id;
-    widget_info->w_master = master;
-    widget_info->w_masterid = targetid;
-    widget_info->w_hwid = *hwid;	/* structure copy */
-    widget_info->w_efunc = 0;
-    widget_info->w_einfo = 0;
-    /*
-     * get the name of this xwidget vertex and keep the info.
-     * This is needed during errors and interupts, but as
-     * long as we have it, we can use it elsewhere.
-     */
-    s = dev_to_name(widget,devnm,MAXDEVNAME);
-    widget_info->w_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
-    strcpy(widget_info->w_name,s);
-    
-    xwidget_info_set(widget, widget_info);
-
-    device_master_set(widget, master);
-
-    /* All the driver init routines (including
-     * xtalk_init) are called before we get into
-     * attaching devices, so we can assume we
-     * have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
-    /* 
-     * Add pointer to async attach info -- tear down will be done when
-     * the particular descendant is done with the info.
-     */
-    if (aa)
-	    async_attach_add_info(widget, aa);
-
-    return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
-                          widget, 0);
-}
-
-/*
- * xwidget_unregister :
- *	Unregister the xtalk device and detach all its hwgraph namespace.
- */
-int
-xwidget_unregister(devfs_handle_t widget)
-{
-    xwidget_info_t	widget_info;
-    xwidget_hwid_t	hwid;
-
-    /* Make sure that we have valid widget information initialized */
-    if (!(widget_info = xwidget_info_get(widget)))
-	return(1);
-
-    /* Remove the inventory information associated
-     * with the widget.
-     */
-    hwgraph_inventory_remove(widget, -1, -1, -1, -1, -1);
-    
-    hwid = &(widget_info->w_hwid);
-
-    cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
-                   widget, 0);
-
-    /* Clean out the xwidget information */
-    (void)kfree(widget_info->w_name);
-    BZERO((void *)widget_info, sizeof(widget_info));
-    DEL(widget_info);
-    
-    return(0);
-}
-
-/*
- * Issue a link reset to a widget.
- */
-void
-xwidget_reset(devfs_handle_t xwidget)
-{
-    xswitch_reset_link(xwidget);
-
-}
-
-
-void
-xwidget_gfx_reset(devfs_handle_t xwidget)
-{
-    xwidget_info_t info;
-
-    xswitch_reset_link(xwidget);
-    info = xwidget_info_get(xwidget);
-#ifdef LATER
-    ASSERT_ALWAYS(info != NULL);
-#endif
-
-    /*
-     * Enable this for other architectures once we add widget_reset to the
-     * xtalk provider interface.
-     */
-    DEV_FUNC(xtalk_provider, widget_reset)
-	(xwidget_info_master_get(info), xwidget_info_id_get(info));
-}
-
-#define ANON_XWIDGET_NAME	"No Name"	/* Default Widget Name */
-
-/* Get the canonical hwgraph  name of xtalk widget */
-char *
-xwidget_name_get(devfs_handle_t xwidget_vhdl)
-{
-	xwidget_info_t  info;
-
-	/* If we have a bogus widget handle then return
-	 * a default anonymous widget name.
-	 */
-	if (xwidget_vhdl == GRAPH_VERTEX_NONE)
-	    return(ANON_XWIDGET_NAME);
-	/* Read the widget name stored in the widget info
-	 * for the widget setup during widget initialization.
-	 */
-	info = xwidget_info_get(xwidget_vhdl);
-	ASSERT(info != NULL);
-	return(xwidget_info_name_get(info));
-}
-
-/*
- * xtalk_device_shutdown
- *	Disable  the specified xtalk widget and clean out all the software
- *	state associated with it.
- */
-int
-xtalk_device_shutdown(devfs_handle_t xbus_vhdl, xwidgetnum_t widget)
-{
-	devfs_handle_t	widget_vhdl;
-	char		edge_name[8];
-
-	sprintf(edge_name, "%d", widget);
-	if (hwgraph_traverse(xbus_vhdl, edge_name, &widget_vhdl) 
-	    != GRAPH_SUCCESS)
-		return(1);
-
-	xwidget_unregister(widget_vhdl);
-	
-	return(0);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/Makefile linux-2.4.22-pre10/arch/ia64/sn/kernel/Makefile
--- linux-2.4.21/arch/ia64/sn/kernel/Makefile	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/Makefile	2003-08-01 13:31:53.000000000 +0000
@@ -1,6 +1,6 @@
 # arch/ia64/sn/kernel/Makefile
 #
-# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+# Copyright (C) 1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
 #
 # This program is free software; you can redistribute it and/or modify it 
 # under the terms of version 2 of the GNU General Public License 
@@ -40,21 +40,15 @@
 
 O_TARGET        = sn.o
 
-export-objs = sn_ksyms.o iomv.o
+export-objs = sn_ksyms.o
 
-subdir-$(CONFIG_IA64_SGI_SN1)	= sn1
-subdir-$(CONFIG_IA64_SGI_SN2)	= sn2
+subdir-y			= sn2
 
-obj-y		= probe.o setup.o sn_asm.o sv.o bte.o iomv.o
-obj-$(CONFIG_IA64_SGI_SN1)      += irq.o mca.o
-obj-$(CONFIG_IA64_SGI_SN2)      += irq.o mca.o
+obj-y				= probe.o setup.o sv.o bte.o
+obj-y			        += irq.o mca.o idle.o
+obj-y			        += sn2/sn2.o
 
-obj-$(CONFIG_IA64_SGI_SN1)      += sn1/sn1.o  
-obj-$(CONFIG_IA64_SGI_SN2)      += sn2/sn2.o  
-
-obj-$(CONFIG_IA64_SGI_AUTOTEST) += llsc4.o misctest.o
 obj-$(CONFIG_IA64_GENERIC)      += machvec.o
 obj-$(CONFIG_MODULES)           += sn_ksyms.o
-obj-$(CONFIG_IA64_SGI_SN_BRT)	+= bte_regr_test.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/bte.c linux-2.4.22-pre10/arch/ia64/sn/kernel/bte.c
--- linux-2.4.21/arch/ia64/sn/kernel/bte.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/bte.c	2003-08-01 13:30:35.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *
  *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -38,130 +38,157 @@
 #include <asm/sn/arch.h>
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/pda.h>
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/sn2/shubio.h>
-#endif
 #include <asm/nodedata.h>
 
 #include <linux/bootmem.h>
 #include <linux/string.h>
 #include <linux/sched.h>
 
-#include <asm/sn/bte_copy.h>
+#include <asm/sn/bte.h>
 
-int bte_offsets[] = { IIO_IBLS0, IIO_IBLS1 };
 
 /*
- * bte_init_node(nodepda, cnode)
+ * The base address of for each set of bte registers.
+ */
+static int bte_offsets[] = { IIO_IBLS0, IIO_IBLS1 };
+
+
+/************************************************************************
+ * Block Transfer Engine copy related functions.
  *
- * Initialize the nodepda structure with BTE base addresses and
- * spinlocks.
+ ***********************************************************************/
+
+
+/*
+ * bte_copy(src, dest, len, mode, notification)
  *
- * NOTE: The kernel parameter btetest will cause the initialization
- * code to reserve blocks of physically contiguous memory to be
- * used by the bte test module.
+ * Use the block transfer engine to move kernel memory from src to dest
+ * using the assigned mode.
+ *
+ * Paramaters:
+ *   src - physical address of the transfer source.
+ *   dest - physical address of the transfer destination.
+ *   len - number of bytes to transfer from source to dest.
+ *   mode - hardware defined.  See reference information
+ *          for IBCT0/1 in the SHUB Programmers Reference
+ *   notification - kernel virtual address of the notification cache
+ *                  line.  If NULL, the default is used and
+ *                  the bte_copy is synchronous.
+ *
+ * NOTE:  This function requires src, dest, and len to
+ * be cacheline aligned.
  */
-void
-bte_init_node(nodepda_t * mynodepda, cnodeid_t cnode)
+bte_result_t
+bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
 {
-	int i;
+	int bte_to_use;
+	u64 transfer_size;
+	struct bteinfo_s *bte;
+	bte_result_t bte_status;
+	unsigned long irq_flags;
 
 
-	/*
-	 * Indicate that all the block transfer engines on this node
-	 * are available.
-	 */
-	for (i = 0; i < BTES_PER_NODE; i++) {
-#ifdef CONFIG_IA64_SGI_SN2
-		/* >>> Don't know why the 0x1800000L is here.  Robin */
-		mynodepda->bte_if[i].bte_base_addr =
-		    (char *)LOCAL_MMR_ADDR(bte_offsets[i] | 0x1800000L);
+	BTE_PRINTK(("bte_copy(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%p)\n",
+		    src, dest, len, mode, notification));
 
-#elif CONFIG_IA64_SGI_SN1
-		mynodepda->bte_if[i].bte_base_addr =
-		    (char *)LOCAL_HUB_ADDR(bte_offsets[i]);
-#else
-#error BTE Not defined for this hardware platform.
-#endif
+	if (len == 0) {
+		return BTE_SUCCESS;
+	}
 
-		/*
-		 * Initialize the notification and spinlock
-		 * so the first transfer can occur.
-		 */
-		mynodepda->bte_if[i].most_rcnt_na =
-		    &(mynodepda->bte_if[i].notify);
-		mynodepda->bte_if[i].notify = 0L;
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-		spin_lock_init(&mynodepda->bte_if[i].spinlock);
-#endif				/* CONFIG_IA64_SGI_BTE_LOCKING */
+	ASSERT(!((len & L1_CACHE_MASK) ||
+		 (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK)));
+	ASSERT(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT));
+
+	do {
+		local_irq_save(irq_flags);
+
+		bte_to_use = 0;
+		/* Attempt to lock one of the BTE interfaces. */
+		while ((bte_to_use < BTES_PER_NODE) &&
+		       BTE_LOCK_IF_AVAIL(bte_to_use)) {
+			bte_to_use++;
+		}
+
+		if (bte_to_use < BTES_PER_NODE) {
+			break;
+		}
+
+		local_irq_restore(irq_flags);
+
+		if (!(mode & BTE_WACQUIRE)) {
+			return BTEFAIL_NOTAVAIL;
+		}
 
-		mynodepda->bte_if[i].bte_test_buf =
-			alloc_bootmem_node(NODE_DATA(cnode), BTE_MAX_XFER);
+		/* Wait until a bte is available. */
+		udelay(10);
+	} while (1);
+
+	bte = pda.cpu_bte_if[bte_to_use];
+	BTE_PRINTKV(("Got a lock on bte %d\n", bte_to_use));
+
+
+	if (notification == NULL) {
+		/* User does not want to be notified. */
+		bte->most_rcnt_na = &bte->notify;
+	} else {
+		bte->most_rcnt_na = notification;
 	}
 
-}
+	/* Calculate the number of cache lines to transfer. */
+	transfer_size = ((len >> L1_CACHE_SHIFT) & BTE_LEN_MASK);
 
+	/* Initialize the notification to a known value. */
+	*bte->most_rcnt_na = -1L;
 
-/*
- * bte_reset_nasid(nasid_t)
- *
- * Does a soft reset of the BTEs on the specified nasid.
- * This is followed by a one-line transfer from each of the
- * virtual interfaces.
- */
-void
-bte_reset_nasid(nasid_t n)
-{
-	ii_ibcr_u_t	ibcr;
+	/* Set the status reg busy bit and transfer length */
+	BTE_PRINTKV(("IBLS - HUB_S(0x%p, 0x%lx)\n",
+		     BTEREG_LNSTAT_ADDR, IBLS_BUSY | transfer_size));
+	HUB_S(BTEREG_LNSTAT_ADDR, (IBLS_BUSY | transfer_size));
+
+	/* Set the source and destination registers */
+	BTE_PRINTKV(("IBSA - HUB_S(0x%p, 0x%lx)\n", BTEREG_SRC_ADDR,
+		     (TO_PHYS(src))));
+	HUB_S(BTEREG_SRC_ADDR, (TO_PHYS(src)));
+	BTE_PRINTKV(("IBDA - HUB_S(0x%p, 0x%lx)\n", BTEREG_DEST_ADDR,
+		     (TO_PHYS(dest))));
+	HUB_S(BTEREG_DEST_ADDR, (TO_PHYS(dest)));
+
+	/* Set the notification register */
+	BTE_PRINTKV(("IBNA - HUB_S(0x%p, 0x%lx)\n", BTEREG_NOTIF_ADDR,
+		     (TO_PHYS(__tpa(bte->most_rcnt_na)))));
+	HUB_S(BTEREG_NOTIF_ADDR, (TO_PHYS(__tpa(bte->most_rcnt_na))));
+
+
+	/* Initiate the transfer */
+	BTE_PRINTK(("IBCT - HUB_S(0x%p, 0x%lx)\n", BTEREG_CTRL_ADDR,
+		     BTE_VALID_MODE(mode)));
+	HUB_S(BTEREG_CTRL_ADDR, BTE_VALID_MODE(mode));
 
-	ibcr.ii_ibcr_regval  = REMOTE_HUB_L(n, IIO_IBCR);
-	ibcr.ii_ibcr_fld_s.i_soft_reset = 1;
-	REMOTE_HUB_S(n, IIO_IBCR, ibcr.ii_ibcr_regval);
-
-	/* One line transfer on virtual interface 0 */
-	REMOTE_HUB_S(n, IIO_IBLS_0, IBLS_BUSY | 1);
-	REMOTE_HUB_S(n, IIO_IBSA_0, TO_PHYS(__pa(&nodepda->bte_cleanup)));
-	REMOTE_HUB_S(n, IIO_IBDA_0,
-		     TO_PHYS(__pa(&nodepda->bte_cleanup[4*L1_CACHE_BYTES])));
-	REMOTE_HUB_S(n, IIO_IBNA_0,
-		     TO_PHYS(__pa(&nodepda->bte_cleanup[4*L1_CACHE_BYTES])));
-	REMOTE_HUB_S(n, IIO_IBCT_0, BTE_NOTIFY);
-	while (REMOTE_HUB_L(n, IIO_IBLS0)) {
-		/* >>> Need some way out in case of hang... */
+	spin_unlock_irqrestore(&bte->spinlock, irq_flags);
+
+
+	if (notification != NULL) {
+		return BTE_SUCCESS;
 	}
 
-	/* One line transfer on virtual interface 1 */
-	REMOTE_HUB_S(n, IIO_IBLS_1, IBLS_BUSY | 1);
-	REMOTE_HUB_S(n, IIO_IBSA_1, TO_PHYS(__pa(nodepda->bte_cleanup)));
-	REMOTE_HUB_S(n, IIO_IBDA_1,
-		     TO_PHYS(__pa(nodepda->bte_cleanup[4 * L1_CACHE_BYTES])));
-	REMOTE_HUB_S(n, IIO_IBNA_1,
-		     TO_PHYS(__pa(nodepda->bte_cleanup[5 * L1_CACHE_BYTES])));
-	REMOTE_HUB_S(n, IIO_IBCT_1, BTE_NOTIFY);
-	while (REMOTE_HUB_L(n, IIO_IBLS1)) {
-		/* >>> Need some way out in case of hang... */
+	while (*bte->most_rcnt_na == -1UL) {
 	}
-}
 
 
-/*
- * bte_init_cpu()
- *
- * Initialize the cpupda structure with pointers to the
- * nodepda bte blocks.
- *
- */
-void
-bte_init_cpu(void)
-{
-	/* Called by setup.c as each cpu is being added to the nodepda */
-	if (local_node_data->active_cpu_count & 0x1) {
-		pda.cpu_bte_if[0] = &(nodepda->bte_if[0]);
-		pda.cpu_bte_if[1] = &(nodepda->bte_if[1]);
+	BTE_PRINTKV((" Delay Done.  IBLS = 0x%lx, most_rcnt_na = 0x%lx\n",
+				HUB_L(BTEREG_LNSTAT_ADDR), *bte->most_rcnt_na));
+
+	if (*bte->most_rcnt_na & IBLS_ERROR) {
+		bte_status = *bte->most_rcnt_na & ~IBLS_ERROR;
+		*bte->most_rcnt_na = 0L;
 	} else {
-		pda.cpu_bte_if[0] = &(nodepda->bte_if[1]);
-		pda.cpu_bte_if[1] = &(nodepda->bte_if[0]);
+		bte_status = BTE_SUCCESS;
 	}
+	BTE_PRINTK(("Returning status is 0x%lx and most_rcnt_na is 0x%lx\n",
+				HUB_L(BTEREG_LNSTAT_ADDR), *bte->most_rcnt_na));
+
+	return bte_status;
 }
 
 
@@ -198,15 +225,11 @@
 	char *bteBlock;
 
 	if (len == 0) {
-		return (BTE_SUCCESS);
+		return BTE_SUCCESS;
 	}
 
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-#error bte_unaligned_copy() assumes single BTE selection in bte_copy().
-#else
 	/* temporary buffer used during unaligned transfers */
-	bteBlock = pda.cpu_bte_if[0]->bte_test_buf;
-#endif
+	bteBlock = pda.cpu_bte_if[0]->scratch_buf;
 
 	headBcopySrcOffset = src & L1_CACHE_MASK;
 	destFirstCacheOffset = dest & L1_CACHE_MASK;
@@ -271,15 +294,15 @@
 				headBteLen += footBteLen;
 			} else if (footBcopyLen > 0) {
 				rv = bte_copy(footBteSource,
-					      __pa(bteBlock),
+					      __tpa(bteBlock),
 					      footBteLen, mode, NULL);
 				if (rv != BTE_SUCCESS) {
-					return (rv);
+					return rv;
 				}
 
 
 				memcpy(__va(footBcopyDest),
-				       (char *)bteBlock, footBcopyLen);
+				       (char *) bteBlock, footBcopyLen);
 			}
 		} else {
 			footBcopyLen = 0;
@@ -294,7 +317,7 @@
 				      (len - headBcopyLen -
 				       footBcopyLen), mode, NULL);
 			if (rv != BTE_SUCCESS) {
-				return (rv);
+				return rv;
 			}
 
 		}
@@ -321,14 +344,93 @@
 
 	if (headBcopyLen > 0) {
 		rv = bte_copy(headBteSource,
-			      __pa(bteBlock), headBteLen, mode, NULL);
+			      __tpa(bteBlock), headBteLen, mode, NULL);
 		if (rv != BTE_SUCCESS) {
-			return (rv);
+			return rv;
 		}
 
-		memcpy(__va(headBcopyDest), ((char *)bteBlock +
+		memcpy(__va(headBcopyDest), ((char *) bteBlock +
 					     headBcopySrcOffset),
 		       headBcopyLen);
 	}
-	return (BTE_SUCCESS);
+	return BTE_SUCCESS;
+}
+
+
+/************************************************************************
+ * Block Transfer Engine initialization functions.
+ *
+ ***********************************************************************/
+
+
+/*
+ * bte_init_node(nodepda, cnode)
+ *
+ * Initialize the nodepda structure with BTE base addresses and
+ * spinlocks.
+ */
+void
+bte_init_node(nodepda_t * mynodepda, cnodeid_t cnode)
+{
+	int i;
+
+
+	/*
+	 * Indicate that all the block transfer engines on this node
+	 * are available.
+	 */
+
+	/*
+	 * Allocate one bte_recover_t structure per node.  It holds
+	 * the recovery lock for node.  All the bte interface structures
+	 * will point at this one bte_recover structure to get the lock.
+	 */
+	spin_lock_init(&mynodepda->bte_recovery_lock);
+	init_timer(&mynodepda->bte_recovery_timer);
+	mynodepda->bte_recovery_timer.function = bte_error_handler;
+	mynodepda->bte_recovery_timer.data = (unsigned long) mynodepda;
+
+	for (i = 0; i < BTES_PER_NODE; i++) {
+		/* >>> Don't know why the 0x1800000L is here.  Robin */
+		mynodepda->bte_if[i].bte_base_addr =
+		    (char *) LOCAL_MMR_ADDR(bte_offsets[i] | 0x1800000L);
+
+		/*
+		 * Initialize the notification and spinlock
+		 * so the first transfer can occur.
+		 */
+		mynodepda->bte_if[i].most_rcnt_na =
+		    &(mynodepda->bte_if[i].notify);
+		mynodepda->bte_if[i].notify = 0L;
+		spin_lock_init(&mynodepda->bte_if[i].spinlock);
+
+		mynodepda->bte_if[i].scratch_buf =
+		    alloc_bootmem_node(NODE_DATA(cnode), BTE_MAX_XFER);
+		mynodepda->bte_if[i].bte_cnode = cnode;
+		mynodepda->bte_if[i].bte_error_count = 0;
+		mynodepda->bte_if[i].bte_num = i;
+		mynodepda->bte_if[i].cleanup_active = 0;
+		mynodepda->bte_if[i].bh_error = 0;
+	}
+
+}
+
+/*
+ * bte_init_cpu()
+ *
+ * Initialize the cpupda structure with pointers to the
+ * nodepda bte blocks.
+ *
+ */
+void
+bte_init_cpu(void)
+{
+	/* Called by setup.c as each cpu is being added to the nodepda */
+	if (local_node_data->active_cpu_count & 0x1) {
+		pda.cpu_bte_if[0] = &(nodepda->bte_if[0]);
+		pda.cpu_bte_if[1] = &(nodepda->bte_if[1]);
+	} else {
+		pda.cpu_bte_if[0] = &(nodepda->bte_if[1]);
+		pda.cpu_bte_if[1] = &(nodepda->bte_if[0]);
+	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/bte_regr_test.c linux-2.4.22-pre10/arch/ia64/sn/kernel/bte_regr_test.c
--- linux-2.4.21/arch/ia64/sn/kernel/bte_regr_test.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/bte_regr_test.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1062 +0,0 @@
-/*
- *
- *
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-
-/***********************************************************************
- * Block Transfer Engine regression tests.
- *
- *	The following set of tests can be used to test for regressions.
- *	It is implemented as a loadable module.
- *
- *	To enable the tests, the kernel must be booted with the
- *	"btetest" command line flag.  If the tests are compiled into the
- *	kernel, additional values may be passed with
- *	"bte_test=t,v,ht,tn,tx,ti,ta,tc"
- *	where:
- *	    t = Bitmask of tests to run.
- *	    v = Level of verbosity.
- *	    ht = Number of seconds to try to force a notification hang.
- *          hu = Number of uSecs to wait until warning of hang.
- *	    tn = Min number of lines to rate test with (2 raised to).
- *	    tx = Max number of lines to rate test with (2 raised to).
- *	    ti = Number of iterations per timing.
- *          ta = Aternate through cpus on each pass.
- *	    tc = Use/Don't Use memcopy
- *
- *	When loaded as a module, each of those values has a seperate
- *	parameter.  Just do a modinfo bte_test.o to get those names
- *	and valid ranges.
- *
- *	Tests are performed in the following order.
- *
- *	Standard Transfer Test - Just transfers a block of initialized
- *	data to a cleared block and ensures that memory before and after
- *	is untouched, but that the body has all the correct values.
- *
- *	Transfer Rate Test - Data is transfered from node to node
- *	to ensure every node is able to BTE data.  Timings are created
- *	for each node.
- *
- *	Notification Hang Test - Attempts to force the Notification
- *	hang problem to arise.  A hang occurs when the BTE fails
- *	to invalidate a processors cache line for the notification
- *	word, resulting in the processor not seeing the updated
- *	value.
- *
- *	Invalid Transfer Test - In this test, we attempt to transfer
- *	data from a valid address to a nasid which does not exist.
- *
- **********************************************************************/
-
-
-#define BTE_TIME 1		/* Needed to ensure bte_copy records
-				 * timings */
-// #define BTE_DEBUG
-// #define BTE_DEBUG_VERBOSE
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <asm/sn/nodepda.h>
-#include <asm/processor.h>
-
-#include <asm/sn/bte_copy.h>
-
-
-/***********************************************************************
- * Local defines, structs, and typedefs.
- *
- **********************************************************************/
-
-
-/*
- * The following struct defines standard transfers to use while
- * testing.
- */
-typedef struct brt_xfer_entry_s {
-	int source_offset;
-	int dest_offset;
-	int length;
-} brt_xfer_entry_t;
-
-/*
- * BRT_TEST_BLOCK_SIZE needs to accomodate the largest transfer that
- * is found in brt_xfer_tests.
- */
-#define BRT_TEST_BLOCK_SIZE 1024
-
-/* Flags for selecting tests to run. */
-#define TEST_REGRESSION		0x00000001	/* Standard Transfer */
-#define TEST_TIME		0x00000002	/* Timed Transfer */
-#define TEST_NOTIFY		0x00000004	/* Notification Hang */
-#define TEST_NONODE		0x00000008	/* Invalid Nasid Xfer */
-
-
-/***********************************************************************
- * Global variables.
- * 
- **********************************************************************/
-
-
-/*
- * bte_setup_time - Time it takes for bte_copy to get locks
- * 		    acquired and values into SHUB registers to start the
- * 		    xfer.
- *
- * bte_transfer_time - Time where hardware is doing the xfer.
- *
- * bte_tear_down_time - Time to unlock and return.
- *
- * bte_execute_time - Time from first call until return.
- */
-volatile static u64 bte_setup_time;
-volatile static u64 bte_transfer_time;
-volatile static u64 bte_tear_down_time;
-volatile static u64 bte_execute_time;
-
-/* Tests to run during standard transfer tests. */
-static brt_xfer_entry_t brt_xfer_tests[] = {
-	{0, 0, 2 * L1_CACHE_BYTES},	/* The ideal case. */
-
-	{0, 0, 35},		/* Symetrical aligned test. */
-	{L1_CACHE_BYTES, L1_CACHE_BYTES, 35},
-	{0, 0, L1_CACHE_BYTES + 35},
-	{L1_CACHE_BYTES, L1_CACHE_BYTES, L1_CACHE_BYTES + 35},
-	{0, 0, (2 * L1_CACHE_BYTES) + 35},
-	{L1_CACHE_BYTES, L1_CACHE_BYTES, (2 * L1_CACHE_BYTES) + 35},
-	{0, 0, (4 * L1_CACHE_BYTES) + 35},
-	{L1_CACHE_BYTES, L1_CACHE_BYTES, (4 * L1_CACHE_BYTES) + 35},
-
-	{(0 + 25), (0 + 25), 35},	/* Symetrical unaligned test. */
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25), 35},
-	{(0 + 25), (0 + 25), L1_CACHE_BYTES + 35},
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25),
-	 (L1_CACHE_BYTES + 25) + 35},
-	{(0 + 25), (0 + 25), (2 * L1_CACHE_BYTES) + 35},
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25),
-	 (2 * L1_CACHE_BYTES) + 35},
-	{(0 + 25), (0 + 25), (4 * L1_CACHE_BYTES) + 35},
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 25),
-	 (4 * L1_CACHE_BYTES) + 35},
-
-	{(0 + 25), (0 + 26), 35},	/* Asymetrical unaligned test. */
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26), 35},
-	{(0 + 25), (0 + 26), L1_CACHE_BYTES + 35},
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26),
-	 (L1_CACHE_BYTES + 25) + 35},
-	{(0 + 25), (0 + 26), (2 * L1_CACHE_BYTES) + 35},
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26),
-	 (2 * L1_CACHE_BYTES) + 35},
-	{(0 + 25), (0 + 26), (4 * L1_CACHE_BYTES) + 35},
-	{(L1_CACHE_BYTES + 25), (L1_CACHE_BYTES + 26),
-	 (4 * L1_CACHE_BYTES) + 35},
-
-	{0, 0, 0}		/* Terminator */
-};
-
-static atomic_t brt_thread_cnt;	/* Threads in test. */
-volatile static int brt_exit_flag;	/* Flag termination of hang test */
-
-/* command line/module parameters */
-static int selected_tests = 0;
-static int verbose = 0;
-static int hang_timeout = 10;
-static int hang_usec = 12;
-static int tm_min_lines = 1;
-static int tm_max_lines = 3;
-static int tm_iterations = 1;
-static int tm_alternate = 0;
-static int tm_memcpy = 1;
-static int ix_iterations = 1000;
-static int ix_srcnasid = -1;
-
-
-/***********************************************************************
- * Local Function Prototypes.
- * 
- **********************************************************************/
-
-
-static int __init brt_test_init(void);
-static void __exit brt_test_exit(void);
-
-/* Standard Transfer Test related functions. */
-static int brt_tst_std_xfer(void);
-static int brt_std_xfer(char *, char *, int, int, int, int);
-static void brt_hex_dump(char *, int);
-
-/* Timed Transfer Test related functions. */
-static int brt_tst_time_xfers(void);
-static void brt_time_xfer(int, int, int);
-
-/* Notification Hang Test related functions. */
-static int brt_tst_notify_hang(void);
-static int brt_notify_thrd(void *);
-
-/* Transfers to Invalid Nasid Test related functions. */
-static int brt_tst_invalid_xfers(void);
-
-#if !defined(MODULE)
-/* Kernel command line handler. */
-static int __init brt_setup(char *);
-#endif				/* !defined(MODULE) */
-
-
-/***********************************************************************
- * Module Load/Unload.
- * 
- **********************************************************************/
-
-
-#define brt_marker() \
-	printk("**************************************************" \
-	       "**********************.\n"); \
-	printk("\n"); \
-	printk("**************************************************" \
-	       "**********************.\n"); \
-	printk("\n"); \
-	printk("**************************************************" \
-	       "**********************.\n"); \
-	printk("\n");
-
-
-static int __init
-brt_test_init(void)
-{
-	int some_tests_removed;
-
-	if (numnodes < 2) {
-		printk("These tests are best run on multinode "
-		       "systems.\n");
-	}
-
-	if (!pda.cpu_bte_if[0]->bte_test_buf) {
-		some_tests_removed = 0;
-
-		/* Timed Transfers go node-to-node. */
-		if (selected_tests & TEST_TIME) {
-			some_tests_removed = 1;
-			selected_tests &= ~(TEST_TIME);
-		}
-
-		/* Notification Hang runs on all cpus simultaneously */
-		if (selected_tests & TEST_NOTIFY) {
-			some_tests_removed = 1;
-			selected_tests &= ~(TEST_NOTIFY);
-		}
-
-		/* Invalid Tests */
-		if (selected_tests & TEST_NONODE) {
-			some_tests_removed = 1;
-			selected_tests &= ~(TEST_NONODE);
-		}
-
-		if (some_tests_removed) {
-			printk("Test Buffers were not allocated.\n");
-			printk("Please reboot the system and supply "
-			       "the \"btetest\" kernel flag\n");
-			printk("Some tests were removed.\n");
-		}
-	}
-
-	brt_marker();
-
-	printk("brt_test(): Starting.\n");
-
-	if (selected_tests & TEST_REGRESSION) {
-		if (brt_tst_std_xfer()) {
-			printk("Standard Transfers had errors.\n");
-		}
-
-	}
-
-	if (selected_tests & TEST_TIME) {
-		if (tm_min_lines < 0) {
-			tm_min_lines = 0;
-		}
-		if (tm_max_lines < 0) {
-			tm_max_lines = 0;
-		}
-
-		if (tm_max_lines > BTE_LEN_MASK) {
-			tm_max_lines = BTE_LEN_MASK;
-		}
-		if (tm_min_lines > tm_max_lines) {
-			tm_min_lines = tm_max_lines;
-		}
-
-		if (brt_tst_time_xfers()) {
-			printk("Timed transfers had errors.\n");
-		}
-
-	}
-
-	if (selected_tests & TEST_NOTIFY) {
-		if (hang_usec < 8) {
-			hang_usec = 8;
-		}
-		if (hang_usec > 256) {
-			hang_usec = 256;
-		}
-
-		if (brt_tst_notify_hang()) {
-			printk("Notification Hang test had errors.\n");
-		}
-	}
-
-	if (selected_tests & TEST_NONODE) {
-		if (brt_tst_invalid_xfers()) {
-			printk("Invalid Nasid test had errors.\n");
-		}
-	}
-
-	return (1);		/* Prevent module load. */
-}
-
-
-static void __exit
-brt_test_exit(void)
-{
-}
-
-
-/***********************************************************************
- * Standard Transfer Test.
- *	
- *	This test has a table of transfers defined above.  For each
- *	transfer, it calls bte_unaligned_copy.  It compares the actual
- *	result with the expected result.  If they differ, it prints out
- *	information about the transfer and hex dumps the actual block
- *
- **********************************************************************/
-
-
-/*
- * Allocate the needed buffers and then initiate each xfer specified
- * by brt_xfer_tests.
- */
-static int
-brt_tst_std_xfer(void)
-{
-	char *block_1;
-	char *block_2;
-	int iteration = 0;
-	brt_xfer_entry_t *cur_test;
-	int cpu;
-	int err_cnt;
-
-	block_1 = kmalloc(BRT_TEST_BLOCK_SIZE, GFP_KERNEL);
-	ASSERT(!((u64) block_1 & L1_CACHE_MASK));
-	block_2 = kmalloc(BRT_TEST_BLOCK_SIZE, GFP_KERNEL);
-	ASSERT(!((u64) block_2 & L1_CACHE_MASK));
-
-	cur_test = brt_xfer_tests;
-
-	err_cnt = 0;
-	while (cur_test->length) {
-		for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-			set_cpus_allowed(current, (1UL << cpu));
-
-			if (verbose > 1) {
-				printk("Cpu %d Transfering %d from "
-				       "%d to %d.\n",
-				       smp_processor_id(),
-				       cur_test->length,
-				       cur_test->source_offset,
-				       cur_test->dest_offset);
-			}
-
-			err_cnt += brt_std_xfer(block_1, block_2,
-						cur_test->source_offset,
-						cur_test->dest_offset,
-						cur_test->length,
-						++iteration);
-
-		}
-		cur_test++;
-	}
-
-	kfree(block_2);
-	kfree(block_1);
-
-	return ((err_cnt ? 1 : 0));
-}
-
-
-/*
- * Perform a single transfer and ensure the result matches
- * the expected.  Returns the number of differences found.
- *
- * Testing is performed by setting the source buffer to a
- * known value, and zeroing out the destination.
- *
- * After the copy, if the destination has only the known
- * source values at the correct place, we know we had a
- * good transfer.
- *
- */
-static int
-brt_std_xfer(char *src, char *dst,
-	     int src_offset, int dst_offset, int len,
-	     int magic)
-{
-	int i, ret;
-	int err_cnt = 0;
-
-	if (verbose > 3) {
-		printk("brt_test(src=0x%lx, dst=0x%lx, src_offset=%d, "
-		       "dst_offset=%d, len=%d, magic=%d\n",
-		       (u64) src, (u64) dst, src_offset,
-		       dst_offset, len, magic);
-	}
-
-	memset(src, ((magic + 1) & 0xff), BRT_TEST_BLOCK_SIZE);
-	memset((src + src_offset), magic, len);
-	if (verbose > 8) {
-		printk("Before transfer: Source is\n");
-		brt_hex_dump(src, BRT_TEST_BLOCK_SIZE);
-	}
-	memset(dst, 0, BRT_TEST_BLOCK_SIZE);
-	if (verbose > 8) {
-		printk("Before transfer: dest is\n");
-		brt_hex_dump(dst, BRT_TEST_BLOCK_SIZE);
-	}
-
-	ret = BTE_UNALIGNED_COPY(__pa(src + src_offset),
-				 __pa(dst + dst_offset),
-				 len, BTE_NOTIFY);
-	if (ret != BTE_SUCCESS) {
-		printk("brt_test: BTE_UNALIGNED_COPY() error: %d\n", ret);
-		return (1);
-	}
-
-	/* Check head */
-	for (i = 0; i < dst_offset; i++) {
-		if ((dst[i] & 0xff) != 0) {
-			err_cnt++;
-		}
-	}
-	/* Check body */
-	for (i = 0; i < len; i++) {
-		if ((dst[dst_offset + i] & 0xff) != (magic & 0xff)) {
-			err_cnt++;
-		}
-	}
-	/* Check foot */
-	for (i = (dst_offset + len); i < BRT_TEST_BLOCK_SIZE; i++) {
-		if ((dst[i] & 0xff) != 0) {
-			err_cnt++;
-		}
-	}
-
-	if ((verbose > 3) || err_cnt) {
-		printk("brt_test: %d errors during basic "
-		       "transfer test.\n", err_cnt);
-		brt_hex_dump(dst, BRT_TEST_BLOCK_SIZE);
-	}
-
-	return (err_cnt);
-}
-
-
-/*
- * Dump a block of data to console as hex.
- */
-static void
-brt_hex_dump(char *block_to_dump, int block_len)
-{
-	int i;
-	char fmt_line[128];
-	char *fmt_eol = fmt_line;
-
-	for (i = 0; i < block_len; i++) {
-		if (!(i % 16)) {
-			if (i > 0) {
-				printk("%s\n", fmt_line);
-			}
-			sprintf(fmt_line, "0x%lx %05d ",
-				__pa(&block_to_dump[i]), i);
-			fmt_eol = fmt_line;
-		}
-		while (*fmt_eol++) {	/* empty */
-		};
-		fmt_eol--;
-		sprintf(fmt_eol, "%s%02x",
-			(!(i % 4) ? " " : ""), (block_to_dump[i] & 0xff));
-	}
-	printk("%s\n", fmt_line);
-}
-
-
-/***********************************************************************
- * Transfer Rate Test.
- * 
- *	This test migrates to each cpu one at a time.  This is done to
- *	get a complete view of how each of the bte engines is performing
- *	and help ensure that each virtual interface is being used.
- *	NOTE: All virtual interfaces will not necessarily be used.
- *
- *	Now that we have migrated to the desired cpu, we transfer from
- *	our node to all the other nodes (including ourself).  We
- *	accomplish this with both a memcpy and a bte_copy.  Timings
- *	for both are printed.
- *
- **********************************************************************/
-
-
-#define NSEC(x) ((x) * (1000000000UL / local_cpu_data->itc_freq))
-
-
-/*
- * Migrate to each cpu. When on the desired cpu, time transfers to
- * each node by calling brt_time_xfer.
- */
-static int
-brt_tst_time_xfers(void)
-{
-	int tst_cpu;
-	int dest_node;
-	int xfer_lines;
-	int i;
-
-	if (tm_memcpy) {
-		printk("Cpu,Src,Dst,Lines,Stup,Transfr,Fin,Execute,"
-		       "Overall,Memcpy\n");
-	} else {
-		printk("Cpu,Src,Dst,Lines,Stup,Transfr,Fin,Execute,"
-		       "Overall\n");
-	}
-
-	if (tm_alternate) {
-		/* Now transfer from this node to all the others. */
-		for (dest_node = 0; dest_node < numnodes; dest_node++) {
-			for (xfer_lines = tm_min_lines;
-			     xfer_lines <= tm_max_lines;) {
-
-				for (i = 0; i < tm_iterations; i++) {
-					for (tst_cpu = 0;
-					     tst_cpu < smp_num_cpus;
-					     tst_cpu++) {
-						/* Move to the desired CPU. */
-						set_cpus_allowed(current,
-						    (1UL << tst_cpu));
-
-						brt_time_xfer(dest_node,
-							      1,
-							      xfer_lines);
-
-					}
-				}
-				/* Handle a min of 0 */
-				if (xfer_lines < 1) {
-					xfer_lines = 1;
-				} else {
-					xfer_lines *= 2;
-				}
-			}
-		}
-	} else {
-		for (tst_cpu = 0; tst_cpu < smp_num_cpus; tst_cpu++) {
-			/* Move to the desired CPU. */
-			set_cpus_allowed(current, (1UL << tst_cpu));
-
-			/* Now transfer from this node to all the others. */
-			for (dest_node = 0; dest_node < numnodes;
-			     dest_node++) {
-				for (xfer_lines = tm_min_lines;
-				     xfer_lines <= tm_max_lines;) {
-
-					brt_time_xfer(dest_node,
-						      tm_iterations,
-						      xfer_lines);
-
-					/* Handle a min of 0 */
-					if (xfer_lines < 1) {
-						xfer_lines = 1;
-					} else {
-						xfer_lines *= 2;
-					}
-				}
-			}
-		}
-	}
-	return (0);
-}
-
-
-/*
- * Transfer the bte_test_buffer from our node to the specified
- * destination and print out timing results.
- */
-static void
-brt_time_xfer(int dest_node, int iterations, int xfer_lines)
-{
-	int iteration;
-	char *src, *dst;
-	u64 xfer_len, src_phys, dst_phys;
-	u64 itc_before, itc_after, mem_intvl, bte_intvl;
-
-
-	xfer_len = xfer_lines * L1_CACHE_BYTES;
-
-	src = nodepda->bte_if[0].bte_test_buf;
-	src_phys = __pa(src);
-	dst = NODEPDA(dest_node)->bte_if[1].bte_test_buf;
-	dst_phys = __pa(dst);
-	mem_intvl = 0;
-
-	for (iteration = 0; iteration < iterations; iteration++) {
-		if (tm_memcpy) {
-			itc_before = ia64_get_itc();
-			memcpy(dst, src, xfer_len);
-			itc_after = ia64_get_itc();
-			mem_intvl = itc_after - itc_before;
-		}
-
-		itc_before = ia64_get_itc();
-		bte_copy(src_phys, dst_phys, xfer_len, BTE_NOTIFY, NULL);
-		itc_after = ia64_get_itc();
-		bte_intvl = itc_after - itc_before;
-
-		if (tm_memcpy) {
-			printk("%3d,%3d,%3d,%5d,%4ld,%7ld,%3ld,"
-			       "%7ld,%7ld,%7ld\n",
-			       smp_processor_id(), NASID_GET(src),
-			       NASID_GET(dst), xfer_lines,
-			       NSEC(bte_setup_time),
-			       NSEC(bte_transfer_time),
-			       NSEC(bte_tear_down_time),
-			       NSEC(bte_execute_time), NSEC(bte_intvl),
-			       NSEC(mem_intvl));
-		} else {
-			printk("%3d,%3d,%3d,%5d,%4ld,%7ld,%3ld,"
-			       "%7ld,%7ld\n",
-			       smp_processor_id(), NASID_GET(src),
-			       NASID_GET(dst), xfer_lines,
-			       NSEC(bte_setup_time),
-			       NSEC(bte_transfer_time),
-			       NSEC(bte_tear_down_time),
-			       NSEC(bte_execute_time), NSEC(bte_intvl));
-		}
-	}
-
-}
-
-
-/***********************************************************************
- * Notification Hang Test. -- NOTE: Has never actually caused a hang.
- *
- *	The next set of code checks to see if the Notification Hang
- *	occurs.  It does this by starting one thread per cpu, pinning
- *	the thread to its assigned cpu.  After it is pinned, we lock
- *	the associated bte.  Source, Dest, and Notification are
- *	assigned.
- *
- *	Inside of a loop, we set the length and trigger the
- *	transfer. We use the ITC to determine when the transfer should
- *	complete. Whenever the IBLS_BUSY bit is cleared, the transfer
- *	has completed. We occasionally call schedule (Since all CPUs
- *	have a pinned process The machine will be doing nothing but
- *	out tranfers) and loop.
- *
- *	If twice max normal time has passed without seeing the
- *	notification, we check the Length/Status register to see if
- *	IBLS_BUSY is still asserted and length is zero.  This is an
- *	indication of the hang.
- *
- **********************************************************************/
-
-
-/*
- * Launch one thread per cpu.  When all threads are started, sleep
- * the specified timeout and then notify the other threads that it
- * is time to exit.
- */
-static int
-brt_tst_notify_hang(void)
-{
-	int tst_cpu;
-
-	printk("Waiting %d seconds to complete test.\n", hang_timeout);
-
-	atomic_set(&brt_thread_cnt, 0);
-	brt_exit_flag = 0;
-
-	for (tst_cpu = 0; tst_cpu < smp_num_cpus; tst_cpu++) {
-		if ((kernel_thread(brt_notify_thrd,
-				   (void *)(long)tst_cpu, 0)) < 0) {
-			printk("Failed to start thread.\n");
-		}
-	}
-
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(hang_timeout * HZ);
-	set_current_state(TASK_RUNNING);
-
-	printk("Flagging an exit.\n");
-	brt_exit_flag = 1;
-
-	while (atomic_read(&brt_thread_cnt)) {
-		/* Wait until everyone else is done. */
-		schedule();
-	}
-
-	printk("All threads have exited.\n");
-	return (0);
-}
-
-
-/*
- * One of these threads is started per cpu.  Each thread is responsible
- * for loading that cpu's bte interface and then writing to the
- * test buffer.  The transfers are set in a round-robin fashion.
- * The end result is that each test buffer is being written into
- * by the previous node and both cpu's at the same time as the
- * local bte is transferring it to the next node.
- */
-static int
-brt_notify_thrd(void *__bind_cpu)
-{
-	int bind_cpu = (long int)__bind_cpu;
-	int cpu = cpu_logical_map(bind_cpu);
-	nodepda_t *nxt_node;
-	long tmout_itc_intvls;
-	long tmout;
-	long passes;
-	long good_xfer_cnt;
-	u64 src_phys, dst_phys;
-	int i;
-	volatile char *src_buf;
-	u64 *notify;
-
-	atomic_inc(&brt_thread_cnt);
-	daemonize();
-	set_user_nice(current, 19);
-	sigfillset(&current->blocked);
-
-	/* Migrate to the right CPU */
-	set_cpus_allowed(current, 1UL << cpu);
-
-	/* Calculate the uSec timeout itc offset. */
-	tmout_itc_intvls = local_cpu_data->cyc_per_usec * hang_usec;
-
-	if (local_cnodeid() == (numnodes - 1)) {
-		nxt_node = NODEPDA(0);
-	} else {
-		nxt_node = NODEPDA(local_cnodeid() + 1);
-	}
-
-	src_buf = nodepda->bte_if[0].bte_test_buf;
-	src_phys = __pa(src_buf);
-	dst_phys = __pa(nxt_node->bte_if[0].bte_test_buf);
-
-	notify = kmalloc(L1_CACHE_BYTES, GFP_KERNEL);
-	ASSERT(!((u64) notify & L1_CACHE_MASK));
-
-	printk("BTE Hang %d xfer 0x%lx -> 0x%lx, Notify=0x%lx\n",
-	       smp_processor_id(), src_phys, dst_phys, (u64) notify);
-
-	passes = 0;
-	good_xfer_cnt = 0;
-
-	/* Loop until signalled to exit. */
-	while (!brt_exit_flag) {
-		/*
-		 * A hang will prevent further transfers.
-		 * NOTE: Sometimes, it appears like a hang occurred and
-		 * then transfers begin again.  This just means that
-		 * there is NUMA congestion and the hang_usec param
-		 * should be increased.
-		 */
-		if (!(*notify & IBLS_BUSY)) {
-			if ((bte_copy(src_phys,
-				      dst_phys,
-				      4UL * L1_CACHE_BYTES,
-				      BTE_NOTIFY,
-				      (void *)notify)) != BTE_SUCCESS) {
-				printk("<0>Cpu %d Could not "
-				       "allocate a bte.\n",
-				       smp_processor_id());
-				continue;
-			}
-
-			tmout = ia64_get_itc() + tmout_itc_intvls;
-
-			while ((*notify & IBLS_BUSY) &&
-			       (ia64_get_itc() < tmout)) {
-
-
-				/* Push data out with the processor. */
-				for (i = 0; i < (4 * L1_CACHE_BYTES);
-				     i += L1_CACHE_BYTES) {
-					src_buf[i] = (passes % 128);
-				}
-			};
-
-			if (*notify & IBLS_BUSY) {
-				printk("<0>Cpu %d BTE appears to have "
-				       "hung.\n", smp_processor_id());
-			} else {
-				good_xfer_cnt++;
-			}
-		}
-
-		/* Every x passes, take a little break. */
-		if (!(++passes % 40)) {
-			passes = 0;
-			schedule_timeout(0.01 * HZ);
-		}
-	}
-
-	kfree(notify);
-
-	printk("Cpu %d had %ld good passes\n",
-	       smp_processor_id(), good_xfer_cnt);
-
-	atomic_dec(&brt_thread_cnt);
-	return (0);
-}
-
-
-/***********************************************************************
- * Invalid Transfer Test.
- * 
- *	Just transfer from the local node to a nasid which does not
- *	exist.
- *
- *	>>> Potential Problem: on SN1, HUB interrupt doesn't always
- *	occurr.
- *
- **********************************************************************/
-
-
-/*
- * Locate a nasid which doesn't exist.  Perform a bte_copy from that
- * node to our local node.
- */
-static int
-brt_tst_invalid_xfers(void)
-{
-	int i;
-	int free_nasid = -1;
-	int cpu;
-	int error_cnt;
-
-	u64 ret_code;
-
-	if (ix_srcnasid != -1) {
-		free_nasid = ix_srcnasid;
-	} else {
-		/* Only looking for nasids from C-Nodes. */
-		for (i = 0; i < PLAT_MAX_NODE_NUMBER; i += 2) {
-			if (local_node_data->physical_node_map[i] == -1) {
-				free_nasid = i;
-				break;
-			}
-		}
-	}
-
-	if (free_nasid == -1) {
-		printk("tst_invalid_xfers: No free nodes found. "
-		       "Exiting.\n");
-		return (0);
-	}
-
-	printk("tst_invalid_xfers: Using source nasid of %d\n",
-	       free_nasid);
-
-	error_cnt = 0;
-
-	for (i = 0; i < ix_iterations; i++) {
-		if (verbose >= 1) {
-			printk("-------------------------------"
-			       "-------------------------------"
-			       "--------------\n");
-		}
-		if ((verbose >= 1) || !(i % 10)) {
-			printk("  Loop %d\n", i);
-		}
-
-		for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-			set_cpus_allowed(current, (1UL << cpu));
-
-			if (verbose > 1) {
-				printk("Testing with CPU %d\n",
-				       smp_processor_id());
-			}
-
-			/* >>> Need a better means of calculating a
-			 * remote addr. */
-			ret_code = bte_copy(TO_NODE(free_nasid, 0),
-					    __pa(nodepda->bte_if[0].
-						 bte_test_buf),
-					    4 * L1_CACHE_BYTES,
-					    BTE_NOTIFY,
-					    NULL);
-			error_cnt += (ret_code ? 1 : 0);
-		}
-	}
-
-	ret_code = ((error_cnt != (ix_iterations * smp_num_cpus)) ?
-		    1 : 0);
-	return (ret_code);
-}
-
-
-/***********************************************************************
- * Kernel command line handler.
- * 
- **********************************************************************/
-
-
-#if !defined(MODULE)
-static int __init
-brt_setup(char *str)
-{
-	int cur_val;
-
-	if (get_option(&str, &cur_val)) {
-		selected_tests = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		verbose = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		hang_timeout = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		hang_usec = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		tm_min_lines = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		tm_max_lines = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		tm_iterations = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		tm_alternate = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		tm_memcpy = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		ix_iterations = cur_val;
-	}
-	if (get_option(&str, &cur_val)) {
-		ix_srcnasid = cur_val;
-	}
-
-	return (1);
-}
-#endif				/* !defined(MODULE) */
-
-
-/***********************************************************************
- * Module parameters.
- *	
- *	The two supported cases are loadable module parms and kernel
- *	command line support.
- *	
- *	The loadable module options are specified below in the
- *	MODULE_PARM macros and have associated descriptions.
- *	
- *	The kernel command line option is btetest=x[,y[,z]] etc.  The
- *	individual setting order is constant.  NOTE: The btetest flag
- *	is checked for in the bte_init_node function.
- *	
- **********************************************************************/
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Silicon Graphics, Inc.");
-MODULE_DESCRIPTION("Test the Block Transfer Engine(BTE) "
-		   "present on SGI machines.");
-
-MODULE_PARM(selected_tests, "1i");
-MODULE_PARM_DESC(selected_tests, "Bitmask of tests to run.");
-
-MODULE_PARM(verbose, "1i");
-MODULE_PARM_DESC(verbose,
-		 "How much information should be "
-		 "printed during the tests.");
-
-MODULE_PARM(hang_timeout, "1i");
-MODULE_PARM_DESC(hang_timeout,
-		 "Number of seconds to wait for the Bte "
-		 "Notification Failure.");
-
-MODULE_PARM(hang_usec, "1i");
-MODULE_PARM_DESC(hang_usec,
-		 "Number of micro-seconds to wait for the 4-line Bte "
-		 "transfer to complete.");
-
-MODULE_PARM(tm_min_lines, "1i");
-MODULE_PARM_DESC(tm_min_lines, "Minimum number of cache lines"
-		 " to time with.");
-
-MODULE_PARM(tm_max_lines, "1i");
-MODULE_PARM_DESC(tm_max_lines, "Maximum number of cache lines"
-		 " to time with.");
-
-MODULE_PARM(tm_iterations, "1i");
-MODULE_PARM_DESC(tm_iterations, "Rerun each timed transfer this "
-		 "many times.");
-
-MODULE_PARM(tm_alternate, "1i");
-MODULE_PARM_DESC(tm_alternate, "Cycle across cpus between each "
-		 "iteration");
-
-MODULE_PARM(tm_memcpy, "1i");
-MODULE_PARM_DESC(tm_memcpy, "Use memcpy as a comparison to BTE");
-
-MODULE_PARM(ix_iterations, "1i");
-MODULE_PARM_DESC(ix_iterations, "Rerun each transfer from an "
-		 "invalid nasid this many times.");
-
-MODULE_PARM(ix_srcnasid, "1i");
-MODULE_PARM_DESC(ix_srcnasid, "Nasid to attempt xfer from.");
-
-
-#if !defined(MODULE)
-__setup("btetest=", brt_setup);
-#endif				/* !defined(MODULE) */
-
-
-module_init(brt_test_init);
-module_exit(brt_test_exit);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/idle.c linux-2.4.22-pre10/arch/ia64/sn/kernel/idle.c
--- linux-2.4.21/arch/ia64/sn/kernel/idle.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/idle.c	2003-08-01 13:33:22.000000000 +0000
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/config.h>
+#include <asm/sn/leds.h>
+#include <asm/sn/simulator.h>
+
+void snidle(int state) {
+	if (state) {
+		if (pda.idle_flag == 0) {
+			/* 
+			 * Turn the activity LED off.
+			 */
+			set_led_bits(0, LED_CPU_ACTIVITY);
+		}
+
+#ifdef CONFIG_IA64_SGI_SN_SIM
+		if (IS_RUNNING_ON_SIMULATOR())
+			SIMULATOR_SLEEP();
+#endif
+
+		pda.idle_flag = 1;
+	} else {
+		/* 
+		 * Turn the activity LED on.
+		 */
+		set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY);
+
+		pda.idle_flag = 0;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/iomv.c linux-2.4.22-pre10/arch/ia64/sn/kernel/iomv.c
--- linux-2.4.21/arch/ia64/sn/kernel/iomv.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/iomv.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,115 +0,0 @@
-/* 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <asm/io.h>
-#include <linux/module.h>
-
-extern void * sn_io_addr(unsigned long port); /* defined in sn[12]/iomv.c */
-
-/**
- * sn_inb - read a byte from a port
- * @port: port to read from
- *
- * Reads a byte from @port and returns it to the caller.
- */
-unsigned int
-sn_inb (unsigned long port)
-{
-	volatile unsigned char *addr = sn_io_addr(port);
-	unsigned char ret;
-
-	ret = *addr;
-	__ia64_mf_a();
-	return ret;
-}
-
-/**
- * sn_inw - read a word from a port
- * @port: port to read from
- *
- * Reads a word from @port and returns it to the caller.
- */
-unsigned int
-sn_inw (unsigned long port)
-{
-	volatile unsigned short *addr = sn_io_addr(port);
-	unsigned short ret;
-
-	ret = *addr;
-	__ia64_mf_a();
-	return ret;
-}
-
-/**
- * sn_inl - read a word from a port
- * @port: port to read from
- *
- * Reads a word from @port and returns it to the caller.
- */
-unsigned int
-sn_inl (unsigned long port)
-{
-	volatile unsigned int *addr = sn_io_addr(port);
-	unsigned int ret;
-
-	ret = *addr;
-	__ia64_mf_a();
-	return ret;
-}
-
-/**
- * sn_outb - write a byte to a port
- * @port: port to write to
- * @val: value to write
- *
- * Writes @val to @port.
- */
-void
-sn_outb (unsigned char val, unsigned long port)
-{
-	volatile unsigned char *addr = sn_io_addr(port);
-
-	*addr = val;
-}
-
-/**
- * sn_outw - write a word to a port
- * @port: port to write to
- * @val: value to write
- *
- * Writes @val to @port.
- */
-void
-sn_outw (unsigned short val, unsigned long port)
-{
-	volatile unsigned short *addr = sn_io_addr(port);
-
-	*addr = val;
-}
-
-/**
- * sn_outl - write a word to a port
- * @port: port to write to
- * @val: value to write
- *
- * Writes @val to @port.
- */
-void
-sn_outl (unsigned int val, unsigned long port)
-{
-	volatile unsigned int *addr = sn_io_addr(port);
-
-	*addr = val;
-}
-
-EXPORT_SYMBOL(sn_inb);
-EXPORT_SYMBOL(sn_inw);
-EXPORT_SYMBOL(sn_inl);
-EXPORT_SYMBOL(sn_outb);
-EXPORT_SYMBOL(sn_outw);
-EXPORT_SYMBOL(sn_outl);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/irq.c linux-2.4.22-pre10/arch/ia64/sn/kernel/irq.c
--- linux-2.4.21/arch/ia64/sn/kernel/irq.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/irq.c	2003-08-01 13:30:57.000000000 +0000
@@ -1,7 +1,7 @@
 /*
- * Platform dependent support for SGI SN1
+ * Platform dependent support for SGI SN
  *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -32,12 +32,13 @@
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/vmalloc.h>
 #include <asm/current.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/sn/sgi.h>
@@ -49,18 +50,23 @@
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/pci/pciio.h>
 #include <asm/sn/pci/pciio_private.h>
-#ifdef ajmtestintr
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/pci/pcibr_private.h>
-#endif /* ajmtestintr */
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/io.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/driver.h>
 #include <asm/sn/arch.h>
+#include <asm/sn/pda.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
 
 int irq_to_bit_pos(int irq);
+static void force_interrupt(int irq);
+extern void pcibr_force_interrupt(pcibr_intr_t intr);
+extern int sn_force_interrupt_flag;
 
 
 
@@ -88,49 +94,11 @@
 static void
 sn_ack_irq(unsigned int irq)
 {
-#ifdef CONFIG_IA64_SGI_SN1
-	int bit = -1;
-	unsigned long long intpend_val;
-	int subnode;
-#endif
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long event_occurred, mask = 0;
-#endif
 	int nasid;
 
 	irq = irq & 0xff;
 	nasid = smp_physical_node_id();
-#ifdef CONFIG_IA64_SGI_SN1
-	subnode = cpuid_to_subnode(smp_processor_id());
-	if (irq == SGI_UART_IRQ) {
-		intpend_val = REMOTE_HUB_PI_L(nasid, subnode, PI_INT_PEND0);
-		if (intpend_val & (1L<<GFX_INTR_A) ) {
-			bit = GFX_INTR_A;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		if ( intpend_val & (1L<<GFX_INTR_B) ) {
-			bit = GFX_INTR_B;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		if (intpend_val & (1L<<PG_MIG_INTR) ) {
-			bit = PG_MIG_INTR;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		if (intpend_val & (1L<<CC_PEND_A)) {
-			bit = CC_PEND_A;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		if (intpend_val & (1L<<CC_PEND_B)) {
-			bit = CC_PEND_B;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		return;
-	}
-	bit = irq_to_bit_pos(irq);
-	REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN2
 	event_occurred = HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid,SH_EVENT_OCCURRED) );
 	if (event_occurred & SH_EVENT_OCCURRED_UART_INT_MASK) {
 		mask |= (1 << SH_EVENT_OCCURRED_UART_INT_SHFT);
@@ -145,34 +113,18 @@
 		mask |= (1 << SH_EVENT_OCCURRED_II_INT1_SHFT);
 	}
 	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_EVENT_OCCURRED_ALIAS), mask );
-#endif
+	__set_bit(irq, (volatile void *)pda.sn_in_service_ivecs);
 }
 
 static void
 sn_end_irq(unsigned int irq)
 {
-#ifdef CONFIG_IA64_SGI_SN1
-	unsigned long long intpend_val, mask = 0x70L;
-	int subnode;
-#endif
 	int nasid;
-#ifdef CONFIG_IA64_SGI_SN2
+	int ivec;
 	unsigned long event_occurred;
-#endif
 
-	irq = irq & 0xff;
-#ifdef CONFIG_IA64_SGI_SN1
-	if (irq == SGI_UART_IRQ) {
-		nasid = smp_physical_node_id();
-		subnode = cpuid_to_subnode(smp_processor_id());
-		intpend_val = REMOTE_HUB_PI_L(nasid, subnode, PI_INT_PEND0);
-		if (intpend_val & mask) {
-			platform_send_ipi(smp_processor_id(), SGI_UART_IRQ, IA64_IPI_DM_INT, 0);
-		}
-	}
-#endif
-#ifdef CONFIG_IA64_SGI_SN2
-	if (irq == SGI_UART_VECTOR) {
+	ivec = irq & 0xff;
+	if (ivec == SGI_UART_VECTOR) {
 		nasid = smp_physical_node_id();
 		event_occurred = HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid,SH_EVENT_OCCURRED) );
 		// If the UART bit is set here, we may have received an interrupt from the
@@ -182,8 +134,9 @@
 				platform_send_ipi(smp_processor_id(), SGI_UART_VECTOR, IA64_IPI_DM_INT, 0);
 		}
 	}
-#endif
-
+	__clear_bit(ivec, (volatile void *)pda.sn_in_service_ivecs);
+	if (sn_force_interrupt_flag)
+		force_interrupt(irq);
 }
 
 static void
@@ -192,7 +145,7 @@
 }
 
 
-struct hw_interrupt_type irq_type_iosapic_level = {
+struct hw_interrupt_type irq_type_sn = {
 	"SN hub",
 	sn_startup_irq,
 	sn_shutdown_irq,
@@ -204,21 +157,17 @@
 };
 
 
-#define irq_type_sn irq_type_iosapic_level
-struct irq_desc *_sn_irq_desc[NR_CPUS];
-
 struct irq_desc *
 sn_irq_desc(unsigned int irq) {
-	int cpu = irq >> 8;
 
-	irq = irq & 0xff;
+	irq = SN_IVEC_FROM_IRQ(irq);
 
-	return(_sn_irq_desc[cpu] + irq);
+	return(_irq_desc + irq);
 }
 
 u8
 sn_irq_to_vector(u8 irq) {
-	return(irq & 0xff);
+	return(irq);
 }
 
 unsigned int
@@ -226,47 +175,24 @@
 	return (CPU_VECTOR_TO_IRQ(smp_processor_id(), vector));
 }
 
-void *kmalloc(size_t, int);
-
 void
 sn_irq_init (void)
 {
 	int i;
 	irq_desc_t *base_desc = _irq_desc;
 
-	for (i=IA64_FIRST_DEVICE_VECTOR; i<NR_IVECS; i++) {
+	for (i=IA64_FIRST_DEVICE_VECTOR; i<NR_IRQS; i++) {
 		if (base_desc[i].handler == &no_irq_type) {
 			base_desc[i].handler = &irq_type_sn;
 		}
 	}
 }
 
-void
-sn_init_irq_desc(void) {
-	int i;
-	irq_desc_t *base_desc = _irq_desc, *p;
-
-	for (i=0; i < NR_CPUS; i++) {
-		p =  page_address(alloc_pages_node(local_cnodeid(), GFP_KERNEL,
-			get_order(sizeof(struct irq_desc) * NR_IVECS) ) );
-		ASSERT(p);
-		memcpy(p, base_desc, sizeof(struct irq_desc) * NR_IVECS);
-		_sn_irq_desc[i] = p;
-	}
-}
-
-
 int
 bit_pos_to_irq(int bit) {
 #define BIT_TO_IRQ 64
 	if (bit > 118) bit = 118;
 
-#ifdef CONFIG_IA64_SGI_SN1
-	if (bit >= GFX_INTR_A && bit <= CC_PEND_B) {
-		return SGI_UART_IRQ;
-	}
-#endif
-
         return bit + BIT_TO_IRQ;
 }
 
@@ -278,53 +204,183 @@
         return bit;
 }
 
-#ifdef ajmtestintr
-
-#include <linux/timer.h>
-struct timer_list intr_test_timer;
-int intr_test_icount[NR_IRQS];
-struct intr_test_reg_struct {
-	pcibr_soft_t pcibr_soft;
-	int slot;
+struct pcibr_intr_list_t {
+	struct pcibr_intr_list_t *next;
+	pcibr_intr_t intr;
 };
-struct intr_test_reg_struct intr_test_registered[NR_IRQS];
+
+static struct pcibr_intr_list_t **pcibr_intr_list;
 
 void
-intr_test_handle_timer(unsigned long data) {
+register_pcibr_intr(int irq, pcibr_intr_t intr) {
+	struct pcibr_intr_list_t *p = kmalloc(sizeof(struct pcibr_intr_list_t), GFP_KERNEL);
+	struct pcibr_intr_list_t *list;
+	int cpu = SN_CPU_FROM_IRQ(irq);
+
+	if (pcibr_intr_list == NULL) {
+		pcibr_intr_list = kmalloc(sizeof(struct pcibr_intr_list_t *) * NR_IRQS, GFP_KERNEL);
+		if (pcibr_intr_list == NULL) 
+			pcibr_intr_list = vmalloc(sizeof(struct pcibr_intr_list_t *) * NR_IRQS);
+		if (pcibr_intr_list == NULL) panic("Could not allocate memory for pcibr_intr_list\n");
+		memset( (void *)pcibr_intr_list, 0, sizeof(struct pcibr_intr_list_t *) * NR_IRQS);
+	}
+	if (pdacpu(cpu).sn_last_irq < irq) {
+		pdacpu(cpu).sn_last_irq = irq;
+	}
+	if (pdacpu(cpu).sn_first_irq > irq) pdacpu(cpu).sn_first_irq = irq;
+	if (!p) panic("Could not allocate memory for pcibr_intr_list_t\n");
+	if ((list = pcibr_intr_list[irq])) {
+		while (list->next) list = list->next;
+		list->next = p;
+		p->next = NULL;
+		p->intr = intr;
+	} else {
+		pcibr_intr_list[irq] = p;
+		p->next = NULL;
+		p->intr = intr;
+	}
+}
+
+void
+force_polled_int(void) {
 	int i;
-	bridge_t	*bridge;
+	struct pcibr_intr_list_t *p;
 
-	for (i=0;i<NR_IRQS;i++) {
-		if (intr_test_registered[i].pcibr_soft) {
-			pcibr_soft_t pcibr_soft = intr_test_registered[i].pcibr_soft;
-			xtalk_intr_t intr = pcibr_soft->bs_intr[intr_test_registered[i].slot].bsi_xtalk_intr;
-			/* send interrupt */
-			bridge = pcibr_soft->bs_base;
-			bridge->b_force_always[intr_test_registered[i].slot].intr = 1;
+	for (i=0; i<NR_IRQS;i++) {
+		p = pcibr_intr_list[i];
+		while (p) {
+			if (p->intr){
+				pcibr_force_interrupt(p->intr);
+			}
+			p = p->next;
 		}
 	}
-	del_timer(&intr_test_timer);
-	intr_test_timer.expires = jiffies + HZ/100;
-	add_timer(&intr_test_timer);
 }
 
-void
-intr_test_set_timer(void) {
-	intr_test_timer.expires = jiffies + HZ/100;
-	intr_test_timer.function = intr_test_handle_timer;
-	add_timer(&intr_test_timer);
+static void
+force_interrupt(int irq) {
+	struct pcibr_intr_list_t *p = pcibr_intr_list[irq];
+
+	while (p) {
+		if (p->intr) {
+			pcibr_force_interrupt(p->intr);
+		}
+		p = p->next;
+	}
+}
+
+/*
+Check for lost interrupts.  If the PIC int_status reg. says that
+an interrupt has been sent, but not handled, and the interrupt
+is not pending in either the cpu irr regs or in the soft irr regs,
+and the interrupt is not in service, then the interrupt may have
+been lost.  Force an interrupt on that pin.  It is possible that
+the interrupt is in flight, so we may generate a spurious interrupt,
+but we should never miss a real lost interrupt.
+*/
+
+static void
+sn_check_intr(int irq, pcibr_intr_t intr) {
+	unsigned long regval;
+	int irr_reg_num;
+	int irr_bit;
+	unsigned long irr_reg;
+
+
+	regval = intr->bi_soft->bs_base->p_int_status_64;
+	irr_reg_num = irq_to_vector(irq) / 64;
+	irr_bit = irq_to_vector(irq) % 64;
+	switch (irr_reg_num) {
+		case 0:
+			irr_reg = ia64_get_irr0();
+			break;
+		case 1:
+			irr_reg = ia64_get_irr1();
+			break;
+		case 2:
+			irr_reg = ia64_get_irr2();
+			break;
+		case 3:
+			irr_reg = ia64_get_irr3();
+			break;
+	}
+	if (!test_bit(irr_bit, &irr_reg) ) {
+		if (!test_bit(irq, pda.sn_soft_irr) ) {
+			if (!test_bit(irq, pda.sn_in_service_ivecs) ) {
+				regval &= 0xff;
+				if (intr->bi_ibits & regval & intr->bi_last_intr) {
+					regval &= ~(intr->bi_ibits & regval);
+					pcibr_force_interrupt(intr);
+				}
+			}
+		}
+	}
+	intr->bi_last_intr = regval;
 }
 
 void
-intr_test_register_irq(int irq, pcibr_soft_t pcibr_soft, int slot) {
-	irq = irq & 0xff;
-	intr_test_registered[irq].pcibr_soft = pcibr_soft;
-	intr_test_registered[irq].slot = slot;
+sn_lb_int_war_check(void) {
+	int i;
+
+	if (pda.sn_first_irq == 0) return;
+	for (i=pda.sn_first_irq;
+		i <= pda.sn_last_irq; i++) {
+			struct pcibr_intr_list_t *p = pcibr_intr_list[i];
+			if (p == NULL) {
+				continue;
+			}
+			while (p) {
+				sn_check_intr(i, p->intr);
+				p = p->next;
+			}
+	}
+}
+
+static inline int
+sn_get_next_bit(void) {
+	int i;
+	int bit;
+
+	for (i = 3; i >= 0; i--) {
+		if (pda.sn_soft_irr[i] != 0) {
+			bit = (i * 64) +  __ffs(pda.sn_soft_irr[i]);
+			__change_bit(bit, (volatile void *)pda.sn_soft_irr);
+			return(bit);
+		}
+	}
+	return IA64_SPURIOUS_INT_VECTOR;
 }
 
 void
-intr_test_handle_intr(int irq, void *junk, struct pt_regs *morejunk) {
-	intr_test_icount[irq]++;
-	printk("RECEIVED %d INTERRUPTS ON IRQ %d\n",intr_test_icount[irq], irq);
+sn_set_tpr(int vector) {
+	if (vector > IA64_LAST_DEVICE_VECTOR || vector < IA64_FIRST_DEVICE_VECTOR) {
+		ia64_set_tpr(vector);
+	} else {
+		ia64_set_tpr(IA64_LAST_DEVICE_VECTOR);
+	}
+}
+
+static inline void
+sn_get_all_ivr(void) {
+	int vector;
+
+	vector = ia64_get_ivr();
+	while (vector != IA64_SPURIOUS_INT_VECTOR) {
+		__set_bit(vector, (volatile void *)pda.sn_soft_irr);
+		ia64_eoi();
+		if (vector > IA64_LAST_DEVICE_VECTOR) return;
+		vector = ia64_get_ivr();
+	}
+}
+	
+int
+sn_get_ivr(void) {
+	int vector;
+
+	vector = sn_get_next_bit();
+	if (vector == IA64_SPURIOUS_INT_VECTOR) {
+		sn_get_all_ivr();
+		vector = sn_get_next_bit();
+	}
+	return vector;
 }
-#endif /* ajmtestintr */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/llsc4.c linux-2.4.22-pre10/arch/ia64/sn/kernel/llsc4.c
--- linux-2.4.21/arch/ia64/sn/kernel/llsc4.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/llsc4.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,1044 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-#include <linux/kernel_stat.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/efi.h>
-#include <asm/page.h>
-#include <linux/threads.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/leds.h>
-
-#include "llsc4.h"
-
-
-#ifdef STANDALONE
-#include "lock.h"
-#endif
-
-#ifdef INTTEST
-static int	inttest=0;
-#endif
-
-#ifdef IA64_SEMFIX_INSN
-#undef IA64_SEMFIX_INSN
-#endif
-#ifdef IA64_SEMFIX
-#undef IA64_SEMFIX
-#endif
-# define IA64_SEMFIX_INSN
-# define IA64_SEMFIX    ""
-
-#define NOLOCK		0xdead
-#define BGUARD(linei)	(0xbbbb0000 | (linei));
-#define EGUARD(linei)	(0xeeee0000 | (linei));
-#define GUARDLINE(v)	((v)&0xffff)
-
-/*
- * Test parameter table for AUTOTEST
- */
-typedef struct {
-	int	passes;
-	int	linecount;
-	int	linepad;
-} autotest_table_t;
-
-autotest_table_t autotest_table[] = {
-	{50000000,	2,	0x2b4		},
-	{50000000,	16,	0,		},
-	{50000000,	16,	4,		},
-	{50000000,	128,	0x44		},
-	{50000000,	128,	0x84		},
-	{50000000,	128,	0x200		},
-	{50000000,	128,	0x204		},
-	{50000000,	128,	0x2b4		},
-	{50000000,	2,	8*MB+0x2b4	},
-	{50000000,	16,	8*MB+0		},
-	{50000000,	16,	8*MB+4		},
-	{50000000,	128,	8*MB+0x44	},
-	{50000000,	128,	8*MB+0x84	},
-	{50000000,	128,	8*MB+0x200	},
-	{50000000,	128,	8*MB+0x204	},
-	{50000000,	128,	8*MB+0x2b4	},
-	{0}};
-
-/*
- * Array of virtual addresses available for test purposes.
- */
-
-typedef struct {
-	long	vstart;
-	long	vend;
-	long	nextaddr;
-	long	nextinit;
-	int	wrapcount;
-} memmap_t;
-
-#define MAPCHUNKS		128
-memmap_t 	memmap[MAPCHUNKS];
-int		memmapx=0;
-
-typedef struct {
-	void	*addr;
-	long	data[16];
-	long	data_fc[16];
-} capture_line_t;
-
-typedef struct {
-	int	size;
-	void	*blockaddr;
-	void	*shadaddr;
-	long	blockdata[48];
-	long	shaddata[48];
-	long	blockdata_fc[48];
-	long	shaddata_fc[48];
-	long	synerr;
-} capture_t;
-
-/*
- * PORTING NOTE: revisit this statement. On hardware we put mbase at 0 and
- * the rest of the tables have to start at 1MB to skip PROM tables.
- */
-#define THREADPRIVATESZ()	((sizeof(threadprivate_t)+511)/512*512)
-#define THREADPRIVATE(t)	((threadprivate_t*)(((long)mbase)+4096+t*THREADPRIVATESZ()))
-
-#define k_capture		mbase->sk_capture
-#define k_go			mbase->sk_go
-#define k_linecount		mbase->sk_linecount
-#define k_passes		mbase->sk_passes
-#define k_napticks		mbase->sk_napticks
-#define k_stop_on_error		mbase->sk_stop_on_error
-#define k_verbose		mbase->sk_verbose
-#define k_threadprivate		mbase->sk_threadprivate
-#define k_blocks		mbase->sk_blocks
-#define k_iter_msg		mbase->sk_iter_msg
-#define k_vv			mbase->sk_vv
-#define k_linepad		mbase->sk_linepad
-#define k_options		mbase->sk_options
-#define k_testnumber		mbase->sk_testnumber
-#define k_currentpass		mbase->sk_currentpass
-
-static long		blocks[MAX_LINECOUNT];		/* addresses of data blocks */
-static control_t	*mbase;
-static vint		initialized=0;
-
-static unsigned int ran_conf_llsc(int);
-static int  rerr(capture_t *, char *, void *, void *, int, int, int, int, int, int);
-static void dumpline(void *, char *, char *, void *, void *, int);
-static int  checkstop(int, int, uint);
-static void spin(int);
-static void capturedata(capture_t *, uint, void *, void *, int);
-static int  randn(uint max, uint *seed);
-static uint zrandom (uint *zranseed);
-static int  set_lock(uint *, uint);
-static int  clr_lock(uint *, uint);
-static void Speedo(void);
-
-int autotest_enabled=0;
-static int llsctest_number=-1;
-static int errstop_enabled=0;
-static int fail_enabled=0;
-static int l4_opt=0;
-static int selective_trigger=0;
-static int dump_block_addrs_opt=0;
-static lock_t errlock=NOLOCK;
-static private_t init_private[LLSC_MAXCPUS];
-
-static int __init autotest_enable(char *str)
-{
-        autotest_enabled = 1;
-	return 1;
-}
-static int __init set_llscblkadr(char *str)
-{
-	dump_block_addrs_opt = 1;
-	return 1;
-}
-static int __init set_llscselt(char *str)
-{
-	selective_trigger = 1;
-	return 1;
-}
-static int __init set_llsctest(char *str)
-{
-        llsctest_number = simple_strtol(str, &str, 10);
-	if (llsctest_number < 0 || llsctest_number > 15)
-		llsctest_number = -1;
-	return 1;
-}
-static int __init set_llscerrstop(char *str)
-{
-        errstop_enabled = 1;
-	return 1;
-}
-static int __init set_llscfail(char *str)
-{
-        fail_enabled = 8;
-	return 1;
-}
-static int __init set_llscl4(char *str)
-{
-        l4_opt = 1;
-	return 1;
-}
-
-static void print_params(void)
-{
-	printk ("********* Enter AUTOTEST facility on master cpu *************\n");
-	printk ("  Test options:\n");
-	printk ("     llsctest=<n>\t%d\tTest number to run (all = -1)\n", llsctest_number);
-	printk ("     llscerrstop \t%s\tStop on error\n", errstop_enabled ? "on" : "off");
-	printk ("     llscfail    \t%s\tForce a failure to test the trigger & error messages\n", fail_enabled ? "on" : "off");
-	printk ("     llscselt    \t%s\tSelective triger on failures\n", selective_trigger ? "on" : "off");
-	printk ("     llscblkadr  \t%s\tDump data block addresses\n", dump_block_addrs_opt ? "on" : "off");
-	printk ("     llscl4      \t%s\tRun only tests that evict from L4\n", l4_opt ? "on" : "off");
-	printk ("  SEMFIX: %s\n", IA64_SEMFIX);
-	printk ("\n");
-}
-__setup("autotest", autotest_enable);
-__setup("llsctest=", set_llsctest);
-__setup("llscerrstop", set_llscerrstop);
-__setup("llscfail", set_llscfail);
-__setup("llscselt", set_llscselt);
-__setup("llscblkadr", set_llscblkadr);
-__setup("llscl4", set_llscl4);
-
-
-
-static inline int
-set_lock(uint *lock, uint id)
-{
-	uint	old;
-	old = cmpxchg_acq(lock, NOLOCK, id);
-	return (old == NOLOCK);
-}
-
-static inline int
-clr_lock(uint *lock, uint id)
-{
-	uint	old;
-	old = cmpxchg_rel(lock, id, NOLOCK);
-	return (old == id);
-}
-
-static inline void
-init_lock(uint *lock)
-{
-	*lock = NOLOCK;
-}
-
-/*------------------------------------------------------------------------+
-| Routine  :  ran_conf_llsc - ll/sc shared data test                      |
-| Description: This test checks the coherency of shared data              |
-+------------------------------------------------------------------------*/
-static unsigned int
-ran_conf_llsc(int thread)
-{
-	private_t	pval;
-	share_t		sval, sval2;
-	uint		vv, linei, slinei, sharei, pass;
-	long		t;
-	lock_t		lockpat;
-	share_t		*sharecopy;
-	long		verbose, napticks, passes, linecount, lcount;
-	dataline_t	*linep, *slinep;
-	int		s, seed;
-	threadprivate_t	*tp;
-	uint		iter_msg, iter_msg_i=0;
-	int		vv_mask;
-	int		correct_errors;
-	int		errs=0;
-	int		stillbad;
-	capture_t	capdata;
-	private_t	*privp;
-	share_t		*sharep;
-
-
-	linecount = k_linecount;
-	napticks = k_napticks;
-	verbose = k_verbose;
-	passes = k_passes;
-	iter_msg = k_iter_msg;
-	seed = (thread + 1) * 647;
-	tp = THREADPRIVATE(thread);
-	vv_mask = (k_vv>>((thread%16)*4)) & 0xf;
-	correct_errors = k_options&0xff;
-
-	memset (&capdata, 0, sizeof(capdata));
-	for (linei=0; linei<linecount; linei++)
-		tp->private[linei] = thread;	
-
-	for (pass = 1; passes == 0 || pass < passes; pass++) {
-		lockpat = (pass & 0x0fffffff) + (thread <<28);
-		if (lockpat == NOLOCK)
-			continue;
-		tp->threadpasses = pass;
-		if (checkstop(thread, pass, lockpat))
-			return 0;
-		iter_msg_i++;
-		if (iter_msg && iter_msg_i > iter_msg) {
-			printk("Thread %d, Pass %d\n", thread, pass);
-			iter_msg_i = 0;
-		}
-		lcount = 0;
-
-		/*
-		 * Select line to perform operations on.
-		 */
-		linei = randn(linecount, &seed);
-		sharei = randn(2, &seed);
-		slinei = (linei + (linecount/2))%linecount;		/* I dont like this - fix later */
-
-		linep = (dataline_t *)blocks[linei];
-		slinep = (dataline_t *)blocks[slinei];
-		if (sharei == 0)
-			sharecopy = &slinep->share0;
-		else
-			sharecopy = &slinep->share1;
-
-
-		vv = randn(4, &seed);
-		if ((vv_mask & (1<<vv)) == 0)
-			continue;
-
-		if (napticks) {
-			t = randn(napticks, &seed);
-			udelay(t);
-		}
-		privp = &linep->private[thread];
-		sharep = &linep->share[sharei];
-		
-		switch(vv) {
-		case 0:
-			/* Read and verify private count on line. */
-			pval = *privp;
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]);
-			if (pval != tp->private[linei]) {
-				capturedata(&capdata, pass, privp, NULL, sizeof(*privp));
-				stillbad = (*privp != tp->private[linei]);
-				if (rerr(&capdata, "Private count", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {
-					return 1;
-				}
-				if (correct_errors) {
-					tp->private[linei] = *privp;
-				}
-				errs++;
-			}
-			break;
-
-		case 1:
-			/* Read, verify, and increment private count on line. */
-			pval = *privp;
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]);
-			if (pval != tp->private[linei]) {
-				capturedata(&capdata, pass, privp, NULL, sizeof(*privp));
-				stillbad = (*privp != tp->private[linei]);
-				if (rerr(&capdata, "Private count & inc", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {
-					return 1;
-				}
-				errs++;
-			}
-			pval = (pval==255) ? 0 : pval+1;
-			*privp = pval;
-			tp->private[linei] = pval;
-			break;
-
-		case 2:
-			/* Lock line, read and verify shared data. */
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy);
-			lcount = 0;
-			while (LOCK(sharei) != 1) {
-				if (checkstop(thread, pass, lockpat))
-					return 0;
-				if (lcount++>1000000) {
-					capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));
-					stillbad = (GETLOCK(sharei) != 0);
-					rerr(&capdata, "Shared data lock", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);
-					return 1;
-				}
-				if ((lcount&0x3fff) == 0)
-					udelay(1000);
-			}
-
-			sval = *sharep;
-			sval2 = *sharecopy;
-			if (pass > 12 && thread == 0 && fail_enabled == 1)
-				sval++;
-			if (sval != sval2) {
-				capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));
-				stillbad = (*sharep != *sharecopy);
-				if (!stillbad && *sharep != sval && *sharecopy == sval2)
-					stillbad = 2;
-				if (rerr(&capdata, "Shared data", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {
-					return 1;
-				}
-				if (correct_errors)
-					*sharep = *sharecopy;
-				errs++;
-			}
-
-
-			if ( (s=UNLOCK(sharei)) != 1) {
-				capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);
-				stillbad = (GETLOCK(sharei) != lockpat);
-				if (rerr(&capdata, "Shared data unlock", linep, slinep, thread, pass, linei, lockpat, GETLOCK(sharei), stillbad))
-					return 1;
-				if (correct_errors)
-					ZEROLOCK(sharei);	
-				errs++;
-			}
-			break;
-
-		case 3:
-			/* Lock line, read and verify shared data, modify shared data. */
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy);
-			lcount = 0;
-			while (LOCK(sharei) != 1) {
-				if (checkstop(thread, pass, lockpat))
-					return 0;
-				if (lcount++>1000000) {
-					capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));
-					stillbad = (GETLOCK(sharei) != 0);
-					rerr(&capdata, "Shared data lock & inc", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);
-					return 1;
-				}
-				if ((lcount&0x3fff) == 0)
-					udelay(1000);
-			}
-			sval = *sharep;
-			sval2 = *sharecopy;
-			if (sval != sval2) {
-				capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));
-				stillbad = (*sharep != *sharecopy);
-				if (!stillbad && *sharep != sval && *sharecopy == sval2)
-					stillbad = 2;
-				if (rerr(&capdata, "Shared data & inc", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {
-					return 1;
-				}
-				errs++;
-			}
-
-			*sharep = lockpat;
-			*sharecopy = lockpat;
-
-
-			if ( (s=UNLOCK(sharei)) != 1) {
-				capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);
-				stillbad = (GETLOCK(sharei) != lockpat);
-				if (rerr(&capdata, "Shared data & inc unlock", linep, slinep, thread, pass, linei, thread, GETLOCK(sharei), stillbad))
-					return 1;
-				if (correct_errors)
-					ZEROLOCK(sharei);	
-				errs++;
-			}
-			break;
-		}
-	}
-
-	return (errs > 0);
-}
-
-static void
-trigger_la(long val)
-{
-	long	*p;
-
-	p = (long*)0xc0000a0001000020L; /* PI_CPU_NUM */
-	*p = val;
-}
-
-static long
-getsynerr(void)
-{
-	long	err, *errp;
-
-	errp = (long*)0xc0000e0000000340L;	/* SYN_ERR */
-	err = *errp;
-	if (err)
-		*errp = -1L;
-	return (err & ~0x60);
-}
-
-static int
-rerr(capture_t *cap, char *msg, void *lp, void *slp, int thread, int pass, int badlinei, int exp, int found, int stillbad)
-{
-	int		cpu, i, linei;
-	long 		synerr;
-	int		selt;
-
-
-	selt = selective_trigger && stillbad > 1 && 
-			memcmp(cap->blockdata, cap->blockdata_fc, 128) != 0 &&
-			memcmp(cap->shaddata, cap->shaddata_fc, 128) == 0;
-	if (selt) {
-		trigger_la(pass);
-	} else if (selective_trigger) {
-		k_go = ST_STOP;
-		return k_stop_on_error;;
-	}
-
-	spin(1);
-	i = 100;
-	while (i && set_lock(&errlock, 1) != 1) {
-		spin(1);
-		i--;
-	}
-	printk ("\nDataError!: %-20s, test %ld, thread %d, line:%d, pass %d (0x%x), time %ld expected:%x, found:%x\n",
-	    msg, k_testnumber, thread, badlinei, pass, pass, jiffies, exp, found);
-
-	dumpline (lp, "Corrupted data", "D ", cap->blockaddr, cap->blockdata, cap->size);
-#ifdef ZZZ
-	if (memcmp(cap->blockdata, cap->blockdata_fc, 128))
-		dumpline (lp, "Corrupted data", "DF", cap->blockaddr, cap->blockdata_fc, cap->size);
-#endif
-
-	if (cap->shadaddr) {
-		dumpline (slp, "Shadow    data", "S ", cap->shadaddr, cap->shaddata, cap->size);
-#ifdef ZZZ
-		if (memcmp(cap->shaddata, cap->shaddata_fc, 128))
-			dumpline (slp, "Shadow    data", "SF", cap->shadaddr, cap->shaddata_fc, cap->size);
-#endif
-	}
-	
-	printk("Threadpasses: ");
-	for (cpu=0,i=0; cpu<LLSC_MAXCPUS; cpu++)
-		if (k_threadprivate[cpu]->threadpasses) {
-			if (i && (i%8) == 0)
-				printk("\n            : ");
-			printk("  %d:0x%x", cpu, k_threadprivate[cpu]->threadpasses);
-			i++;
-		}
-	printk("\n");
-	
-	for (linei=0; linei<k_linecount; linei++) {
-		int		slinei, g1linei, g2linei, g1err, g2err, sh0err, sh1err;
-		dataline_t	*linep, *slinep;
-
-		slinei = (linei + (k_linecount/2))%k_linecount;
-		linep = (dataline_t *)blocks[linei];
-		slinep = (dataline_t *)blocks[slinei];
-
-		g1linei = GUARDLINE(linep->guard1);
-		g2linei = GUARDLINE(linep->guard2);
-		g1err = (g1linei != linei);
-		g2err = (g2linei != linei);
-		sh0err = (linep->share[0] != slinep->share0);
-		sh1err = (linep->share[1] != slinep->share1);
-
-		if (g1err || g2err || sh0err || sh1err) {
-			printk("Line 0x%lx (%03d), %sG1 0x%lx (%03d), %sG2 0x%lx (%03d), %sSH0 %08x (%08x), %sSH1 %08x (%08x)\n",
-				blocks[linei], linei, 
-				g1err ? "*" : " ", blocks[g1linei], g1linei,
-				g2err ? "*" : " ", blocks[g2linei], g2linei,
-				sh0err ? "*" : " ", linep->share[0], slinep->share0,
-				sh1err ? "*" : " ", linep->share[1], slinep->share1);
-
-
-		}
-	}
-
-	printk("\nData was %sfixed by flushcache\n", (stillbad == 1 ? "**** NOT **** " : " "));
-	synerr = getsynerr();
-	if (synerr)
-		printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr);
-	spin(2);
-	printk("\n\n");
-	clr_lock(&errlock, 1);
-
-	if (errstop_enabled) {
-		local_irq_disable();
-		while(1);
-	}
-	return k_stop_on_error;
-}
-
-
-static void
-dumpline(void *lp, char *str1, char *str2, void *addr, void *data, int size)
-{
-	long *p;
-	int i, off;
-
-	printk("%s at 0x%lx, size %d, block starts at 0x%lx\n", str1, (long)addr, size, (long)lp);
-	p = (long*) data;
-	for (i=0; i<48; i++, p++) {
-		if (i%8 == 0) printk("%2s", i==16 ? str2 : "  ");
-		printk(" %016lx", *p);
-		if ((i&7)==7) printk("\n");
-	}
-	printk("   ");
-	off = (((long)addr) ^ size) & 63L;
-	for (i=0; i<off+size; i++) {
-		printk("%s", (i>=off) ? "--" : "  ");
-		if ((i%8) == 7)
-			printk(" ");
-	}
-
-	off = ((long)addr) & 127;
-	printk(" (line %d)\n", 2+off/64+1);
-}
-
-
-static int
-randn(uint max, uint *seedp)
-{
-	if (max == 1)
-		return(0);
-	else
-		return((int)(zrandom(seedp)>>10) % max);
-}
-
-
-static int
-checkstop(int thread, int pass, uint lockpat)
-{
-	long	synerr;
-
-	if (k_go == ST_RUN)
-		return 0;
-	if (k_go == ST_STOP)
-		return 1;
-
-	if (errstop_enabled) {
-		local_irq_disable();
-		while(1);
-	}
-	synerr = getsynerr();
-	spin(2);
-	if (k_go == ST_STOP)
-		return 1;
-	if (synerr)
-		printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr);
-	return 1;
-}
-
-
-static void
-spin(int j)
-{
-	udelay(j * 500000);
-}
-
-static void
-capturedata(capture_t *cap, uint pass, void *blockaddr, void *shadaddr, int size)
-{
-
-	if (!selective_trigger)
-		trigger_la (pass);
-
-	memcpy (cap->blockdata, CACHEALIGN(blockaddr)-128, 3*128);
-	if (shadaddr) 
-		memcpy (cap->shaddata, CACHEALIGN(shadaddr)-128, 3*128);
-
-	if (k_stop_on_error) {
-		k_go = ST_ERRSTOP;
-	}
-
- 	cap->size = size;
-	cap->blockaddr = blockaddr;
-	cap->shadaddr = shadaddr;
-
-	asm volatile ("fc %0" :: "r"(blockaddr) : "memory");
-	ia64_sync_i();
-	ia64_srlz_d();
-	memcpy (cap->blockdata_fc, CACHEALIGN(blockaddr)-128, 3*128);
-
-	if (shadaddr) {
-		asm volatile ("fc %0" :: "r"(shadaddr) : "memory");
-		ia64_sync_i();
-		ia64_srlz_d();
-		memcpy (cap->shaddata_fc, CACHEALIGN(shadaddr)-128, 3*128);
-	}
-}
-
-int             zranmult = 0x48c27395;
-
-static uint  
-zrandom (uint *seedp)
-{
-        *seedp = (*seedp * zranmult) & 0x7fffffff;
-        return (*seedp);
-}
-
-
-void
-set_autotest_params(void)
-{
-	static int	testnumber=-1;
-
-	if (llsctest_number >= 0) {
-		testnumber = llsctest_number;
-	} else {
-		testnumber++;
-		if (autotest_table[testnumber].passes == 0) {
-			testnumber = 0;
-			dump_block_addrs_opt = 0;
-		}
-	}
-	if (testnumber == 0 && l4_opt) testnumber = 9;
-
-	k_passes = autotest_table[testnumber].passes;
-	k_linepad = autotest_table[testnumber].linepad;
-	k_linecount = autotest_table[testnumber].linecount;
-	k_testnumber = testnumber;
-
-	if (IS_RUNNING_ON_SIMULATOR()) {
-		printk ("llsc start test %ld\n", k_testnumber);
-		k_passes = 1000;
-	}
-}
-
-
-static void
-set_leds(int errs)
-{
-	unsigned char	leds=0;
-
-	/*
-	 * Leds are:
-	 * 	ppppeee-  
-	 *   where
-	 *      pppp = test number
-	 *       eee = error count but top bit is stick
-	 */
-
-	leds =  ((errs&7)<<1) | ((k_testnumber&15)<<4) | (errs ? 0x08 : 0);
-	set_led_bits(leds, LED_MASK_AUTOTEST);
-}
-
-static void
-setup_block_addresses(void)
-{
-	int			i, stride, memmapi;
-	dataline_t		*dp;
-	long			*ip, *ipe;
-
-
-	stride = k_linepad + sizeof(dataline_t);
-	memmapi = 0;
-	for (i=0; i<memmapx; i++) {
-		memmap[i].nextaddr = memmap[i].vstart;
-		memmap[i].nextinit = memmap[i].vstart;
-		memmap[i].wrapcount = 0;
-	}
-
-	for (i=0; i<k_linecount; i++) {
-		blocks[i] = memmap[memmapi].nextaddr;
-		dp = (dataline_t*)blocks[i];
-		memmap[memmapi].nextaddr += (stride & 0xffff);
-		if (memmap[memmapi].nextaddr + sizeof(dataline_t) >= memmap[memmapi].vend) {
-			memmap[memmapi].wrapcount++;
-			memmap[memmapi].nextaddr = memmap[memmapi].vstart + 
-					memmap[memmapi].wrapcount * sizeof(dataline_t);
-		}
-
-		ip = (long*)((memmap[memmapi].nextinit+7)&~7);
-		ipe = (long*)(memmap[memmapi].nextaddr+2*sizeof(dataline_t)+8);
-		while(ip <= ipe && ip < ((long*)memmap[memmapi].vend-8))
-			*ip++ = (long)ip;
-		memmap[memmapi].nextinit = (long) ipe;
-		dp->guard1 = BGUARD(i);
-		dp->guard2 = EGUARD(i);
-		dp->lock[0] = dp->lock[1] = NOLOCK;
-		dp->share[0] = dp->share0 = 0x1111;
-		dp->share[1] = dp->share1 = 0x2222;
-		memcpy(dp->private, init_private, LLSC_MAXCPUS*sizeof(private_t));
-
-
-		if (stride > 16384) {
-			memmapi++;
-			if (memmapi == memmapx)
-				memmapi = 0;
-		}
-	}
-
-}
-
-static void
-dump_block_addrs(void)
-{
-	int	i;
-
-	printk("LLSC TestNumber %ld\n", k_testnumber);
-
-	for (i=0; i<k_linecount; i++) {
-		printk("  %lx", blocks[i]);
-		if (i%4 == 3)
-			printk("\n");
-	}
-	printk("\n");
-}
-
-
-static void
-set_thread_state(int cpuid, int state)
-{
-	if (k_threadprivate[cpuid]->threadstate == TS_KILLED) {
-		set_led_bits(LED_MASK_AUTOTEST, LED_MASK_AUTOTEST);
-		while(1);
-	}
-	k_threadprivate[cpuid]->threadstate = state;
-}
-
-#define MINBLK	(16*1024*1024)
-static int
-build_mem_map(unsigned long start, unsigned long end, void *arg)
-{
-	long	lstart, lend;
-	long	align = 8*MB;
-
-	printk ("LLSC memmap: start 0x%lx, end 0x%lx, (0x%lx - 0x%lx)\n", 
-		start, end, (long) virt_to_page(start), (long) virt_to_page(end-PAGE_SIZE));
-
-	if (memmapx >= MAPCHUNKS || (end-start) < MINBLK)
-		return 0;
-
-	/*
-	 * Start in the middle of the range & find the first non-free page in both directions
-	 * from the midpoint. This is likely to be the bigest free block.
-	 */
-	lend = lstart = start + (end-start)/2;
-	while (lend < end && !PageReserved(virt_to_page(lend)) && virt_to_page(lend)->count.counter == 0)
-		lend += PAGE_SIZE;
-	lend -= PAGE_SIZE;
-
-	while (lstart >= start && !PageReserved(virt_to_page(lstart)) && virt_to_page(lstart)->count.counter == 0)
-		lstart -= PAGE_SIZE;
-	lstart += PAGE_SIZE;
-
-	lstart = (lstart + align -1) /align * align;
-	end = end / align * align;
-	if (lstart >= end)
-		return 0;
-	printk ("     memmap: start 0x%lx, end 0x%lx\n", lstart, end);
-
-	memmap[memmapx].vstart = lstart;
-	memmap[memmapx].vend = end;
-	memmapx++;
-	return 0;
-}
-
-void int_test(void);
-
-int
-llsc_main (int cpuid)
-{
-	int		i, cpu, is_master, repeatcnt=0;
-	unsigned int	preverr=0, errs=0, pass=0;
-	int		automode=0;
-
-#ifdef INTTEST
-	if (inttest)
-		int_test();
-#endif
-
-	if (!autotest_enabled)
-		return 0;
-
-#ifdef CONFIG_SMP
-	is_master = !smp_processor_id();
-#else
-	is_master = 1;
-#endif
-
-
-	if (is_master) {
-		mbase = (control_t*) __get_free_pages(GFP_KERNEL, get_order(4096+THREADPRIVATESZ()*LLSC_MAXCPUS));
-		printk("LLSC: mbase 0x%lx\n", (long)mbase);
-		print_params();
-		if(!IS_RUNNING_ON_SIMULATOR())
-			spin(10);
-		k_currentpass = 0;
-		k_go = ST_IDLE;
-		k_passes = DEF_PASSES;
-		k_napticks = DEF_NAPTICKS;
-		k_stop_on_error = DEF_STOP_ON_ERROR;
-		k_verbose = DEF_VERBOSE;
-		k_linecount = DEF_LINECOUNT;
-		k_iter_msg = DEF_ITER_MSG;
-		k_vv = DEF_VV;
-		k_linepad = DEF_LINEPAD;
-		k_blocks = (void*)blocks;
-		efi_memmap_walk(build_mem_map, 0);
-	
-#ifdef CONFIG_IA64_SGI_AUTOTEST
-		automode = 1;
-#endif
-
-		for (i=0; i<LLSC_MAXCPUS; i++) {
-			k_threadprivate[i] = THREADPRIVATE(i);
-			memset(k_threadprivate[i], 0, sizeof(*k_threadprivate[i]));
-			init_private[i] = i;
-		}
-		mb();
-		initialized = 1;
-	} else {
-		while (initialized == 0)
-			udelay(100);
-	}
-
-loop:
-	if (is_master) {
-		if (automode) {
-			if (!preverr || repeatcnt++ > 5) {
-				set_autotest_params();
-				repeatcnt = 0;
-			}
-		} else {
-			while (k_go == ST_IDLE);
-		}
-
-		k_go = ST_INIT;
-		if (k_linecount > MAX_LINECOUNT) k_linecount = MAX_LINECOUNT;
-		k_linecount = k_linecount & ~1;
-		setup_block_addresses();
-		if (!preverr && dump_block_addrs_opt)
-			dump_block_addrs();
-
-		k_currentpass = pass++;
-		k_go = ST_RUN;
-		if (fail_enabled)
-			fail_enabled--;
-
-	} else {
-		while (k_go != ST_RUN || k_currentpass != pass);
-		pass++;
-	}
-
-
-	set_leds(errs);
-	set_thread_state(cpuid, TS_RUNNING);
-
-	errs += ran_conf_llsc(cpuid);
-	preverr = (k_go == ST_ERRSTOP);
-
-	set_leds(errs);
-	set_thread_state(cpuid, TS_STOPPED);
-
-	if (is_master) {
-		Speedo();
-		for (i=0, cpu=0; cpu<LLSC_MAXCPUS; cpu++) {
-			while (k_threadprivate[cpu]->threadstate == TS_RUNNING) {
-				i++;
-				if (i == 10000) { 
-					k_go = ST_STOP;
-					printk ("  llsc master stopping test number %ld\n", k_testnumber);
-				}
-				if (i > 100000) {
-					k_threadprivate[cpu]->threadstate = TS_KILLED;
-					printk ("  llsc: master killing cpuid %d, running test number %ld\n", 
-							cpu, k_testnumber);
-				}
-				udelay(1000);
-			}
-		}
-	}
-
-	goto loop;
-}
-
-
-static void
-Speedo(void)
-{
-	static int i = 0;
-
-	switch (++i%4) {
-	case 0:
-		printk("|\b");
-		break;
-	case 1:
-		printk("\\\b");
-		break;
-	case 2:
-		printk("-\b");
-		break;
-	case 3:
-		printk("/\b");
-		break;
-	}
-}
-
-#ifdef INTTEST
-
-/* ======================================================================================================== 
- *
- * Some test code to verify that interrupts work
- *
- * Add the following to the arch/ia64/kernel/smp.c after the comment "Reschedule callback"
- * 		if (zzzprint_resched) printk("  cpu %d got interrupt\n", smp_processor_id());
- *
- * Enable the code in arch/ia64/sn/sn1/smp.c to print sending IPIs.
- *
- */
-
-static int __init set_inttest(char *str)
-{
-        inttest = 1;
-	autotest_enabled = 1;
-
-	return 1;
-}	
-
-__setup("inttest=", set_inttest);
-
-int	zzzprint_resched=0;
-
-void
-int_test() {
-	int			mycpu, cpu;
-	static volatile int	control_cpu=0;
-
-	mycpu = smp_processor_id();
-	zzzprint_resched = 2;
-
-	printk("Testing cross interrupts\n");
-	
-	while (control_cpu != smp_num_cpus) {
-		if (mycpu == cpu_logical_map(control_cpu)) {
-			for (cpu=0; cpu<smp_num_cpus; cpu++) {
-				printk("Sending interrupt from %d to %d\n", mycpu, cpu_logical_map(cpu));
-				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
-				smp_send_reschedule(cpu_logical_map(cpu));
-				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
-				smp_send_reschedule(cpu_logical_map(cpu));
-				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
-			}
-			control_cpu++;
-		}
-	}
-
-	zzzprint_resched = 1;
-
-	if (mycpu == cpu_logical_map(smp_num_cpus-1)) {
-		printk("\nTight loop of cpu %d sending ints to cpu 0 (every 100 us)\n", mycpu);
-		udelay(IS_RUNNING_ON_SIMULATOR ? 1000 : 1000000);
-		__cli();
-		while (1) {
-			smp_send_reschedule(0);
-			udelay(100);
-		}
-
-	}
-
-	while(1);
-}
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/llsc4.h linux-2.4.22-pre10/arch/ia64/sn/kernel/llsc4.h
--- linux-2.4.21/arch/ia64/sn/kernel/llsc4.h	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/llsc4.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,107 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifdef STANDALONE
-#include "lock.h"
-#endif
-
-
-#define DEF_NAPTICKS		0
-#define DEF_PASSES		0
-#define DEF_AUTO_PASSES		1000000
-#define DEF_STOP_ON_ERROR	1
-#define DEF_VERBOSE		0
-#define DEF_LINECOUNT		2
-#define DEF_ITER_MSG		0
-#define DEF_VV			0xffffffff
-#define DEF_LINEPAD		0x234
-
-
-
-#define LLSC_MAXCPUS		64
-#define CACHELINE		64
-#define MAX_LINECOUNT		1024
-#define K			1024
-#define	MB			(K*K)
-
-
-#define	uint 		unsigned int
-#define	ushort		unsigned short
-#define	uchar		unsigned char
-#define vint		volatile int
-#define vlong		volatile long
-
-#define LOCKADDR(i)	&linep->lock[(i)]
-#define LOCK(i)		set_lock(LOCKADDR(i), lockpat)
-#define UNLOCK(i)	clr_lock(LOCKADDR(i), lockpat)
-#define GETLOCK(i)	*LOCKADDR(i)
-#define ZEROLOCK(i)	init_lock(LOCKADDR(i))
-
-#define CACHEALIGN(a)	((char*)((long)(a) & ~127L))
-
-typedef uint		guard_t;
-typedef uint		lock_t;
-typedef uint		share_t;
-typedef uchar		private_t;
-
-typedef struct {
-	guard_t		guard1;
-	lock_t		lock[2];
-	share_t		share[2];
-	private_t	private[LLSC_MAXCPUS];
-	share_t		share0;
-	share_t		share1;
-	guard_t		guard2;
-} dataline_t ;
-
-
-#define LINEPAD			k_linepad
-#define LINESTRIDE		(((sizeof(dataline_t)+CACHELINE-1)/CACHELINE)*CACHELINE + LINEPAD)
-
-
-typedef struct {
-	vint		threadstate;
-	uint		threadpasses;
-	private_t	private[MAX_LINECOUNT];
-} threadprivate_t;
-
-typedef struct {
-	vlong		sk_go;		/* 0=idle, 1=init, 2=run */
-	long		sk_linecount;
-	long		sk_passes;
-	long		sk_napticks;
-	long		sk_stop_on_error;
-	long		sk_verbose;
-	long		sk_iter_msg;
-	long		sk_vv;
-	long		sk_linepad;
-	long		sk_options;
-	long		sk_testnumber;
-	vlong		sk_currentpass;
-	void 		*sk_blocks;
-	threadprivate_t	*sk_threadprivate[LLSC_MAXCPUS];
-} control_t;
-
-/* Run state (k_go) constants */
-#define ST_IDLE		0
-#define ST_INIT		1
-#define ST_RUN		2
-#define ST_STOP		3
-#define ST_ERRSTOP	4
-
-
-/* Threadstate constants */
-#define TS_STOPPED	0
-#define	TS_RUNNING	1
-#define TS_KILLED	2
-
-
-
-int llsc_main (int cpuid);
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/machvec.c linux-2.4.22-pre10/arch/ia64/sn/kernel/machvec.c
--- linux-2.4.21/arch/ia64/sn/kernel/machvec.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/machvec.c	2003-08-01 13:34:07.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -30,30 +30,5 @@
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 
-#include <linux/config.h>
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define MACHVEC_PLATFORM_NAME	sn1
-#else CONFIG_IA64_SGI_SN1
 #define MACHVEC_PLATFORM_NAME	sn2
-#else
-#error "unknown platform"
-#endif
-
 #include <asm/machvec_init.h>
-#include <asm/io.h>
-#include <linux/pci.h>
-void*
-sn_mk_io_addr_MACRO
-
-dma_addr_t
-sn_pci_map_single_MACRO
-
-int
-sn_pci_map_sg_MACRO
-
-unsigned long
-sn_virt_to_phys_MACRO
-
-void *
-sn_phys_to_virt_MACRO
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/mca.c linux-2.4.22-pre10/arch/ia64/sn/kernel/mca.c
--- linux-2.4.21/arch/ia64/sn/kernel/mca.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/mca.c	2003-08-01 13:32:07.000000000 +0000
@@ -2,7 +2,7 @@
  * File:	mca.c
  * Purpose:	SN specific MCA code.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -123,9 +123,7 @@
 static void
 sn_cpei_timer_handler(unsigned long dummy) {
 	sn_cpei_handler(-1, NULL, NULL);
-	del_timer(&sn_cpei_timer);
-	sn_cpei_timer.expires = jiffies + CPEI_INTERVAL;
-        add_timer(&sn_cpei_timer);
+	mod_timer(&sn_cpei_timer, jiffies + CPEI_INTERVAL);
 }
 
 void
@@ -134,27 +132,3 @@
         sn_cpei_timer.function = sn_cpei_timer_handler;
         add_timer(&sn_cpei_timer);
 }
-
-
-
-
-#ifdef ajmtestceintr
-
-struct timer_list sn_ce_timer;
-
-void
-sn_ce_timer_handler(long dummy) {
-	unsigned long *pi_ce_error_inject_reg = 0xc00000092fffff00;
-
-	*pi_ce_error_inject_reg = 0x0000000000000100;
-	del_timer(&sn_ce_timer);
-	sn_ce_timer.expires = jiffies + CPEI_INTERVAL;
-        add_timer(&sn_ce_timer);
-}
-
-sn_init_ce_timer() {
-	sn_ce_timer.expires = jiffies + CPEI_INTERVAL;
-        sn_ce_timer.function = sn_ce_timer_handler;
-        add_timer(&sn_ce_timer);
-}
-#endif /* ajmtestceintr */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/misctest.c linux-2.4.22-pre10/arch/ia64/sn/kernel/misctest.c
--- linux-2.4.21/arch/ia64/sn/kernel/misctest.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/misctest.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,371 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/processor.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/timex.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/sn/intr.h>
-#include <asm/hw_irq.h>
-#include <asm/sn/leds.h>
-
-extern	int autotest_enabled;
-long	mcatest=0, debug0, debug1, debug2, debug3;
-
-#define HDELAY(t)	(IS_RUNNING_ON_SIMULATOR() ? udelay(1) : udelay(t))
-
-/* 
- * mcatest
- *	mactest contains a decimal number (RPTT) where
- *		R - flag, if non zero, run forever
- *
- *		P - identifies when to run the test
- *		    0 execute test at cpu 0 early init
- *		    1 execute test at cpu 0 idle
- *		    2 execute test at last (highest numbered) cpu idle
- *		    3 execute test on all cpus at idle
- *
- *		TT- identifies test to run
- *		    01 = MCA via dup TLB dropin
- *		    02 = MCA via garbage address
- *		    03 = lfetch via garbage address
- *		    05 = INIT self
- *		    06 = INIT other cpu
- *		    07 = INIT non-existent cpu
- *		    10 = IPI stress test. Target cpu 0
- *		    11 = IPI stress test. Target all cpus
- *		    12 = TLB stress test
- *		    13 = Park cpu (spinloop)
- *		    14 = One shot TLB test with tlb spinlock
- *		    15 = One shot TLB test
- *		    16 = One shot TLB test sync'ed with RTC
- *		    20 = set led to the cpuid & spin.
- *		    21 = Try mixed cache/uncached refs & see what happens
- *		    22 = Call SAL reboot
- *		    23 = Call PAL halt
- */
-static int __init set_mcatest(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	mcatest = val;
-	return 1;
-}
-__setup("mcatest=", set_mcatest);
-
-static int __init set_debug0(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	debug0 = val;
-	return 1;
-}
-__setup("debug0=", set_debug0);
-
-static int __init set_debug1(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	debug1 = val;
-	return 1;
-}
-__setup("debug1=", set_debug1);
-
-static int __init set_debug2(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	debug2 = val;
-	return 1;
-}
-__setup("debug2=", set_debug2);
-
-static int __init set_debug3(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	debug3 = val;
-	return 1;
-}
-__setup("debug3=", set_debug3);
-
-static volatile int	go;
-
-static void
-do_sync(int pos) {
-	if (pos != 3)
-		return;
-	else if (smp_processor_id() == 0)
-		go = 1;
-	else
-		while (!go);
-}
-
-static void
-sgi_mcatest_bkpt(void)
-{
-}
-
-
-/*
- * Optional test
- *	pos - 0 called from early init
- *	pos - called when cpu about to go idle (fully initialized
- */
-void
-sgi_mcatest(int pos)
-{
-	long	spos, test, repeat;
-	int	cpu, curcpu, i, n;
-
-	//if (IS_RUNNING_ON_SIMULATOR()) mcatest=1323;
-	repeat = mcatest/1000;
-	spos = (mcatest/100)%10;
-	test = mcatest % 100;
-	curcpu = smp_processor_id();
-
-	if ( mcatest == 0 || !((pos == 0 && spos == 0) ||
-		(pos == 1 && spos == 3) ||
-	        (pos == 1 && spos == 1 && curcpu == 0) ||
-	        (pos == 1 && spos == 2 && curcpu == smp_num_cpus-1)))
-		return;
-	     
-again:
-	if (test == 1 || test == 2 || test == 3) {
-		void zzzmca(int);
-		printk("CPU %d: About to cause unexpected MCA\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		zzzmca(test-1);
-	
-		HDELAY(100000);
-	}
-
-	if (test == 4) {
-		long    result, adrs[] = {0xe0021000009821e0UL, 0xc0003f3000000000UL, 0xc0000081101c0000UL, 0xc00000180e021004UL,  0xc00000180e022004UL, 0xc00000180e023004UL };
-		long    size[] = {1,2,4,8};
-		int     r, i, j, k;
-
-		for (k=0; k<2; k++) {
-			for (i=0; i<6; i++) {
-				for (j=0; j<4; j++) {
-					printk("Probing 0x%lx, size %ld\n", adrs[i], size[j]);
-					result = -1;
-					r = ia64_sn_probe_io_slot (adrs[i], size[j], &result);
-					printk("    status %d, val 0x%lx\n", r, result);
-					udelay(100000);
-				}
-			}
-		}
-
-	}
-
-	if (test == 5) {
-		cpu =  curcpu;
-		printk("CPU %d: About to send INIT to self (cpu %d)\n", curcpu, cpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
-		
-		HDELAY(100000);
-		printk("CPU %d: Returned from INIT\n", curcpu);
-	}
-
-	if (test == 6) {
-		cpu =  curcpu ^ 1;
-		printk("CPU %d: About to send INIT to other cpu (cpu %d)\n", curcpu, cpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-
-	if (test == 7) {
-		printk("CPU %d: About to send INIT to non-existent cpu\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		sn_send_IPI_phys(0xffff, 0, IA64_IPI_DM_INIT);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-
-	if (test == 10) {
-		n = IS_RUNNING_ON_SIMULATOR() ? 10 : 10000000;
-		cpu = 0;
-		printk("CPU %d: IPI stress test. Target cpu 0\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		for (i=0; i<n; i++)
-			platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-
-	if (test == 11) {
-		n = IS_RUNNING_ON_SIMULATOR() ? 100 : 10000000;
-		printk("CPU %d: IPI stress test. Target all cpus\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		for (i=0; i<n; i++)
-			for (cpu=0; cpu<smp_num_cpus; cpu++)
-				if (smp_num_cpus > 2 && cpu != curcpu)
-					platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-
-	if (test == 12) {
-		long adr = 0xe002200000000000UL;
-		n = IS_RUNNING_ON_SIMULATOR() ? 1000 : 100000;
-		printk("CPU %d: TLB flush stress test\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		for (i=0; i<n; i++)
-			platform_global_tlb_purge(adr, adr+25*PAGE_SIZE, 14);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-	
-	if (test == 13) {
-		printk("CPU %d: Park cpu in spinloop\n", curcpu);
-		while(1);
-	}
-	if (test == 14 || test == 15 || test == 16 || test == 17) {
-		long adr = 0xe002200000000000UL;
-		static int inited=0;
-		if (inited == 0) {
-			if (debug0 == 0) debug0 = 1;
-			repeat = 1;
-			do_sync(spos);
-			if (curcpu >= smp_num_cpus-2) {
-				printk("Parking cpu %d\n", curcpu);
-				local_irq_disable();
-				while(1);
-			} else {
-				printk("Waiting cpu %d\n", curcpu);
-				HDELAY(1000000);
-			}
-			HDELAY(1000000);
-			inited = 1;
-		}
-		if (test == 16 || test == 17) {
-			unsigned long t, shift, mask;
-			mask =  (smp_num_cpus > 16) ? 0x1f : 0xf;
-			shift = 25-debug1;
-			do {
-				t = get_cycles();
-				if (IS_RUNNING_ON_SIMULATOR())
-					t = (t>>8);
-				else
-					t = (t>>shift);
-				t = t & mask;
-			} while (t == curcpu);
-			do {
-				t = get_cycles();
-				if (IS_RUNNING_ON_SIMULATOR())
-					t = (t>>8);
-				else
-					t = (t>>shift);
-				t = t & mask;
-			} while (t != curcpu);
-		}
-		if(debug3) printk("CPU %d: One TLB start\n", curcpu);
-		if (test != 17) platform_global_tlb_purge(adr, adr+PAGE_SIZE*debug0, 14);
-		if(debug3) printk("CPU %d: One TLB flush done\n", curcpu);
-	}
-	if (test == 20) {
-		local_irq_disable();
-		set_led_bits(smp_processor_id(), 0xff);
-		while(1);
-	}
-	if (test == 21) {
-		extern long ia64_mca_stack[];
-		int		i, n;
-		volatile long	*p, *up;
-		p = (volatile long*)__imva(ia64_mca_stack);
-		up = (volatile long*)(__pa(p) | __IA64_UNCACHED_OFFSET);
-
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ get data in cache\n");
-		for (n=0, i=0; i<100; i++)
-			n += *(p+i);
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Make uncached refs to same data\n");
-		for (n=0, i=0; i<100; i++)
-			n += *(up+i);
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ dirty the data via cached refs\n");
-		for (n=0, i=0; i<100; i++)
-			*(p+i) = i;
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Make uncached refs to same data\n");
-		for (n=0, i=0; i<100; i++)
-			n += *(up+i);
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Flushing cache\n");
-		for (n=0, i=0; i<100; i++)
-			ia64_fc((void*)(p+i));
-		printk("ZZZ done\n");
-	}
-	if (test == 21) {
-		int i;
-		volatile long tb, t[10];
-		for (i=0; i<10; i++) {
-			tb = debug3+ia64_get_itc();
-			sgi_mcatest_bkpt();
-			t[i] = ia64_get_itc() - tb;
-		}
-		for (i=0; i<10; i++) {
-			printk("ZZZ NULL  0x%lx\n", t[i]);
-		}
-		for (i=0; i<10; i++) {
-			tb = debug3+ia64_get_itc();
-			ia64_pal_call_static(PAL_MC_DRAIN, 0, 0, 0, 0);
-			t[i] = ia64_get_itc() - tb;
-		}
-		for (i=0; i<10; i++) {
-			printk("ZZZ DRAIN 0x%lx\n", t[i]);
-		}
-	}
-	if (test == 22) {
-		extern void machine_restart(char*);
-		printk("ZZZ machine_restart\n");
-		machine_restart(0);
-	}
-	if (test == 23) {
-		printk("ZZZ ia64_pal_halt_light\n");
-		ia64_pal_halt_light();
-	}
-	if (repeat)
-		goto again;
-
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/probe.c linux-2.4.22-pre10/arch/ia64/sn/kernel/probe.c
--- linux-2.4.21/arch/ia64/sn/kernel/probe.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/probe.c	2003-08-01 13:33:34.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Platform dependent support for IO probing.
  *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/setup.c linux-2.4.22-pre10/arch/ia64/sn/kernel/setup.c
--- linux-2.4.21/arch/ia64/sn/kernel/setup.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/setup.c	2003-08-01 13:34:25.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -69,21 +69,27 @@
 #include <asm/sn/bte.h>
 #include <asm/sn/clksupport.h>
 #include <asm/sn/sn_sal.h>
-
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/sn2/shub.h>
-#endif
+
+#define pxm_to_nasid(pxm) ((pxm)<<1)
+
+#define MAX_PHYS_MEMORY		(1UL << 49)	/* 1 TB */
 
 extern void bte_init_node (nodepda_t *, cnodeid_t);
 extern void bte_init_cpu (void);
+extern void sn_timer_init(void);
+extern unsigned long last_time_offset;
+extern void (*ia64_mark_idle)(int);
+extern void snidle(int);
 
 unsigned long sn_rtc_cycles_per_second;   
-unsigned long sn_rtc_usec_per_cyc;
 
 partid_t sn_partid = -1;
 char sn_system_serial_number_string[128];
 u64 sn_partition_serial_number;
 
+short	physical_node_map[MAX_PHYSNODE_ID];
+
 /*
  * This is the address of the RRegs in the HSpace of the global
  * master.  It is used by a hack in serial.c (serial_[in|out],
@@ -92,21 +98,14 @@
  * early_printk won't try to access the UART before
  * master_node_bedrock_address is properly calculated.
  */
-u64 master_node_bedrock_address = 0UL;
+u64 master_node_bedrock_address;
 
 static void sn_init_pdas(char **);
 
-extern struct irq_desc *_sn_irq_desc[];
-
-#if defined(CONFIG_IA64_SGI_SN1)
-extern synergy_da_t	*Synergy_da_indr[];
-#endif
 
 static nodepda_t	*nodepdaindr[MAX_COMPACT_NODES];
 
-#ifdef CONFIG_IA64_SGI_SN2
-irqpda_t		*irqpdaindr[NR_CPUS];
-#endif /* CONFIG_IA64_SGI_SN2 */
+irqpda_t		*irqpdaindr;
 
 
 /*
@@ -133,29 +132,19 @@
  * running in the simulator.  Note that passing zeroes in DRIVE_INFO
  * is sufficient (the IDE driver will autodetect the drive geometry).
  */
+#ifdef CONFIG_IA64_GENERIC
+extern char drive_info[4*16];
+#else
 char drive_info[4*16];
-
-/**
- * sn_map_nr - return the mem_map entry for a given kernel address
- * @addr: kernel address to query
- *
- * Finds the mem_map entry for the kernel address given.  Used by
- * virt_to_page() (asm-ia64/page.h), among other things.
- */
-unsigned long
-sn_map_nr (void *addr)
-{
-	return MAP_NR_DISCONTIG(addr);
-}
+#endif
 
 /**
  * early_sn_setup - early setup routine for SN platforms
  *
- * Sets up an intial console to aid debugging.  Intended primarily
- * for bringup, it's only called if %BRINGUP and %CONFIG_IA64_EARLY_PRINTK
- * are turned on.  See start_kernel() in init/main.c.
+ * Sets up an initial console to aid debugging.  Intended primarily
+ * for bringup.  See start_kernel() in init/main.c.
  */
-#if defined(CONFIG_IA64_EARLY_PRINTK)
+#if defined(CONFIG_IA64_EARLY_PRINTK_SGI_SN) || defined(CONFIG_IA64_SGI_SN_SIM)
 
 void __init
 early_sn_setup(void)
@@ -170,7 +159,7 @@
 
 	/*
 	 * Parse enough of the SAL tables to locate the SAL entry point. Since, console
-	 * IO on SN2 is done via SAL calls, early_printk wont work without this.
+	 * IO on SN2 is done via SAL calls, early_printk won't work without this.
 	 *
 	 * This code duplicates some of the ACPI table parsing that is in efi.c & sal.c.
 	 * Any changes to those file may have to be made hereas well.
@@ -193,21 +182,48 @@
 	}
 
 	if ( IS_RUNNING_ON_SIMULATOR() ) {
-#if defined(CONFIG_IA64_SGI_SN1)
-		master_node_bedrock_address = (u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
-#else
 		master_node_bedrock_address = (u64)REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
-#endif
 		printk(KERN_DEBUG "early_sn_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address);
 	}
 }
-#endif /* CONFIG_IA64_SGI_SN1 */
+#endif /* CONFIG_IA64_EARLY_PRINTK_SGI_SN */
 
 #ifdef CONFIG_IA64_MCA
 extern int platform_intr_list[];
 #endif
 
 extern nasid_t master_nasid;
+static int shub_1_1_found __initdata;
+
+
+/*
+ * sn_check_for_wars
+ *
+ * Set flag for enabling shub specific wars
+ */
+
+static inline int __init
+is_shub_1_1(int nasid)
+{
+	unsigned long id;
+	int	rev;
+
+	id = REMOTE_HUB_L(nasid, SH_SHUB_ID);
+	rev =  (id & SH_SHUB_ID_REVISION_MASK) >> SH_SHUB_ID_REVISION_SHFT;
+	return rev <= 2;
+}
+
+static void __init
+sn_check_for_wars(void)
+{
+	int	cnode;
+
+	for (cnode=0; cnode< numnodes; cnode++)
+		if (is_shub_1_1(cnodeid_to_nasid(cnode)))
+			shub_1_1_found = 1;
+}
+
+
 
 /**
  * sn_setup - SN platform setup routine
@@ -221,8 +237,18 @@
 sn_setup(char **cmdline_p)
 {
 	long status, ticks_per_sec, drift;
-	int i;
+	int i, pxm;
 	int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
+	extern void io_sh_swapper(int, int);
+	extern nasid_t get_master_baseio_nasid(void);
+	extern void sn_cpu_init(void);
+
+	MAX_DMA_ADDRESS = PAGE_OFFSET + MAX_PHYS_MEMORY;
+
+	memset(physical_node_map, -1, sizeof(physical_node_map));
+	for (pxm=0; pxm<MAX_PXM_DOMAINS; pxm++)
+		if (pxm_to_nid_map[pxm] != -1)
+			physical_node_map[pxm_to_nasid(pxm)] = pxm_to_nid_map[pxm];
 
 	printk("SGI SAL version %x.%02x\n", major, minor);
 
@@ -236,21 +262,11 @@
 		panic("PROM version too old\n");
 	}
 
-#ifdef CONFIG_IA64_SGI_SN2
-	{
-		extern void io_sh_swapper(int, int);
-		io_sh_swapper(get_nasid(), 0);
-	}
-#endif
+	io_sh_swapper(get_nasid(), 0);
 
 	master_nasid = get_nasid();
 	(void)get_console_nasid();
-#ifndef CONFIG_IA64_SGI_SN1
-	{
-		extern nasid_t get_master_baseio_nasid(void);
-		(void)get_master_baseio_nasid();
-	}
-#endif
+	(void)get_master_baseio_nasid();
 
 	status = ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, &drift);
 	if (status != 0 || ticks_per_sec < 100000) {
@@ -261,26 +277,12 @@
 	else
 		sn_rtc_cycles_per_second = ticks_per_sec;
 
-#ifdef CONFIG_IA64_SGI_SN1
-	/* PROM has wrong value on SN1 */
-	sn_rtc_cycles_per_second = 990177;
-#endif
-	sn_rtc_usec_per_cyc = ((1000000UL<<IA64_USEC_PER_CYC_SHIFT)
-			       + sn_rtc_cycles_per_second/2) / sn_rtc_cycles_per_second;
-		
-	for (i=0;i<NR_CPUS;i++)
-		_sn_irq_desc[i] = _irq_desc;
-
 	platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_PCE_VECTOR;
 
 
 	if ( IS_RUNNING_ON_SIMULATOR() )
 	{
-#ifdef CONFIG_IA64_SGI_SN2
 		master_node_bedrock_address = (u64)REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
-#else
-		master_node_bedrock_address = (u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
-#endif
 		printk(KERN_DEBUG "sn_setup: setting master_node_bedrock_address to 0x%lx\n",
 		       master_node_bedrock_address);
 	}
@@ -296,6 +298,12 @@
 	 */
 	sn_init_pdas(cmdline_p);
 
+	/*
+	 * Check for WARs.
+	 */
+	sn_check_for_wars();
+
+	ia64_mark_idle = &snidle;
 
 	/* 
 	 * For the bootcpu, we do this here. All other cpus will make the
@@ -303,16 +311,12 @@
 	 */
 	sn_cpu_init();
 
-
 #ifdef CONFIG_SMP
 	init_smp_config();
 #endif
 	screen_info = sn_screen_info;
 
-	/*
-	 * Turn off "floating-point assist fault" warnings by default.
-	 */
-	current->thread.flags |= IA64_THREAD_FPEMU_NOPRINT;
+	sn_timer_init();
 }
 
 /**
@@ -332,19 +336,16 @@
 	if ((PDAADDR&~PAGE_MASK)+sizeof(pda_t) > PAGE_SIZE)
 		panic("overflow of cpu_data page");
 
+	memset(pda.cnodeid_to_nasid_table, -1, sizeof(pda.cnodeid_to_nasid_table));
+	for (cnode=0; cnode<numnodes; cnode++)
+		pda.cnodeid_to_nasid_table[cnode] = pxm_to_nasid(nid_to_pxm_map[cnode]);
+
         /*
          * Allocate & initalize the nodepda for each node.
          */
         for (cnode=0; cnode < numnodes; cnode++) {
 		nodepdaindr[cnode] = alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t));
 		memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
-
-#if defined(CONFIG_IA64_SGI_SN1)
-		Synergy_da_indr[cnode * 2] = (synergy_da_t *) alloc_bootmem_node(NODE_DATA(cnode), sizeof(synergy_da_t));
-		Synergy_da_indr[cnode * 2 + 1] = (synergy_da_t *) alloc_bootmem_node(NODE_DATA(cnode), sizeof(synergy_da_t));
-		memset(Synergy_da_indr[cnode * 2], 0, sizeof(synergy_da_t));
-		memset(Synergy_da_indr[cnode * 2 + 1], 0, sizeof(synergy_da_t));
-#endif
         }
 
 	/*
@@ -381,7 +382,7 @@
 	int	cpuphyid;
 	int	nasid;
 	int	slice;
-	int	cnode;
+	int	cnode, i;
 
 	/*
 	 * The boot cpu makes this call again after platform initialization is
@@ -402,38 +403,33 @@
 	memset(&pda, 0, sizeof(pda));
 	pda.p_nodepda = nodepdaindr[cnode];
 	pda.led_address = (typeof(pda.led_address)) (LED0 + (slice<<LED_CPU_SHIFT));
-#ifdef LED_WAR
-	pda.led_address = (typeof(pda.led_address)) (LED0 + (slice<<(LED_CPU_SHIFT-1))); /* temp til L1 firmware fixed */
-#endif
 	pda.led_state = LED_ALWAYS_SET;
 	pda.hb_count = HZ/2;
 	pda.hb_state = 0;
 	pda.idle_flag = 0;
+	pda.shub_1_1_found = shub_1_1_found;
 	
+	memset(pda.cnodeid_to_nasid_table, -1, sizeof(pda.cnodeid_to_nasid_table));
+	for (i=0; i<numnodes; i++)
+		pda.cnodeid_to_nasid_table[i] = pxm_to_nasid(nid_to_pxm_map[i]);
+
 	if (local_node_data->active_cpu_count == 1)
 		nodepda->node_first_cpu = cpuid;
 
-#ifdef CONFIG_IA64_SGI_SN1
-	{
-		int	synergy;
-		synergy = cpu_physical_id_to_synergy(cpuphyid);
-		pda.p_subnodepda = &nodepdaindr[cnode]->snpda[synergy];
-	}
-#endif
 
-#ifdef CONFIG_IA64_SGI_SN2
 
 	/*
 	 * We must use different memory allocators for first cpu (bootmem 
 	 * allocator) than for the other cpus (regular allocator).
 	 */
 	if (cpuid == 0)
-		irqpdaindr[cpuid] = alloc_bootmem_node(NODE_DATA(cpuid_to_cnodeid(cpuid)),sizeof(irqpda_t));
-	else
-		irqpdaindr[cpuid] = page_address(alloc_pages_node(local_cnodeid(), GFP_KERNEL, get_order(sizeof(irqpda_t))));
+		irqpdaindr = alloc_bootmem_node(NODE_DATA(cpuid_to_cnodeid(cpuid)),sizeof(irqpda_t));
 
-	memset(irqpdaindr[cpuid], 0, sizeof(irqpda_t));
-	pda.p_irqpda = irqpdaindr[cpuid];
+	memset(irqpdaindr, 0, sizeof(irqpda_t));
+	irqpdaindr->irq_flags[SGI_PCIBR_ERROR] = SN2_IRQ_SHARED;
+	irqpdaindr->irq_flags[SGI_PCIBR_ERROR] |= SN2_IRQ_RESERVED;
+	irqpdaindr->irq_flags[SGI_II_ERROR] = SN2_IRQ_SHARED;
+	irqpdaindr->irq_flags[SGI_II_ERROR] |= SN2_IRQ_RESERVED;
 
 	pda.pio_write_status_addr = (volatile unsigned long *)
 			LOCAL_MMR_ADDR((slice < 2 ? SH_PIO_WRITE_STATUS_0 : SH_PIO_WRITE_STATUS_1 ) );
@@ -442,253 +438,9 @@
 
 	if (nodepda->node_first_cpu == cpuid) {
 		int	buddy_nasid;
-		buddy_nasid = cnodeid_to_nasid(local_cnodeid() == numnodes-1 ? 0 : local_cnodeid()+ 1);
+		buddy_nasid = cnodeid_to_nasid(numa_node_id() == numnodes-1 ? 0 : numa_node_id()+ 1);
 		pda.pio_shub_war_cam_addr = (volatile unsigned long*)GLOBAL_MMR_ADDR(nasid, SH_PI_CAM_CONTROL);
 	}
 
-#ifdef BRINGUP2
-	/*
-	 * Zero out the counters used for counting MCAs
-	 *   ZZZZZ temp
-	 */
-	{
-		long	*p;
-		p = (long*)LOCAL_MMR_ADDR(SH_XN_IILB_LB_CMP_ENABLE0);
-		*p = 0;
-		p = (long*)LOCAL_MMR_ADDR(SH_XN_IILB_LB_CMP_ENABLE1);
-		*p = 0;
-	}
-
-#endif
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN1
-	pda.bedrock_rev_id = (volatile unsigned long *) LOCAL_HUB(LB_REV_ID);
-	if (cpuid_to_synergy(cpuid))
-		/* CPU B */
-		pda.pio_write_status_addr = (volatile unsigned long *) GBL_PERF_B_ADDR;
-	else
-		/* CPU A */
-		pda.pio_write_status_addr = (volatile unsigned long *) GBL_PERF_A_ADDR;
-#endif
-
-
 	bte_init_cpu();
 }
-
-
-/**
- * cnodeid_to_cpuid - convert a cnode to a cpuid of a cpu on the node.
- * @cnode: node to get a cpuid from
- *	
- * Returns -1 if no cpus exist on the node.
- * NOTE:BRINGUP ZZZ This is NOT a good way to find cpus on the node.
- * Need a better way!!
- */
-int
-cnodeid_to_cpuid(int cnode) {
-	int cpu;
-
-	for (cpu = 0; cpu < smp_num_cpus; cpu++)
-		if (cpuid_to_cnodeid(cpu) == cnode)
-			break;
-
-	if (cpu == smp_num_cpus) 
-		cpu = -1;
-
-	return cpu;
-}
-
-/**
- * get_cycles - return a non-decreasing timestamp
- *
- * On SN, we use an RTC read for this function
- */
-cycles_t
-get_cycles (void)
-{
-	return GET_RTC_COUNTER();
-}
-
-/**
- * gettimeoffset - number of usecs elapsed since &xtime was last updated
- *
- * This function is used by do_gettimeofday() to determine the number
- * of usecs that have elapsed since the last update to &xtime.  On SN
- * this is accomplished using the RTC built in to each Hub chip; each
- * is guaranteed to be synchronized by the PROM, so a local read will
- * suffice (get_cycles() does this for us).  A snapshot of the RTC value
- * is taken on every timer interrupt and this function more or less
- * subtracts that snapshot value from the current value.
- *
- * Note that if a lot of processing was done during the last timer
- * interrupt then &xtime may be some number of jiffies out of date.
- * This function must account for that.
- */
-unsigned long
-gettimeoffset(void)
-{
-	unsigned long current_rtc_val, local_last_rtc_val;
-	unsigned long usec;
-
-	local_last_rtc_val = last_rtc_val;
-	current_rtc_val = get_cycles();
-	usec = last_itc_lost_usec;
-
-	/* If the RTC has wrapped around, compensate */
-	if (unlikely(current_rtc_val < local_last_rtc_val)) {
-		printk(KERN_NOTICE "RTC wrapped cpu:%d current:0x%lx last:0x%lx\n",
-				smp_processor_id(), current_rtc_val,
-				local_last_rtc_val);
-		current_rtc_val += RTC_MASK;
-	}
-
-	usec += ((current_rtc_val - local_last_rtc_val)*sn_rtc_usec_per_cyc) >> 
-		IA64_USEC_PER_CYC_SHIFT;
-
-	/*
-	 * usec is the number of microseconds into the current clock interval. Every
-	 * clock tick, xtime is advanced by "tick" microseconds. If "usec"
-	 * is allowed to get larger than "tick", the time value returned by gettimeofday
-	 * will go backward.
-	 */
-	if (usec >= tick)
-		usec = tick-1;
-
-	return usec;
-}
-
-#ifdef II_PRTE_TLB_WAR
-long iiprt_lock[16*64] __cacheline_aligned; /* allow for NASIDs up to 64 */
-#endif
-
-#ifdef BUS_INT_WAR
-
-#include <asm/hw_irq.h>
-#include <asm/sn/pda.h>
-
-void ia64_handle_irq (ia64_vector vector, struct pt_regs *regs);
-
-static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;
-
-#define IRQCPU(irq)	((irq)>>8)
-
-void
-sn_add_polled_interrupt(int irq, int interval)
-{
-	unsigned long flags, irq_cnt;
-	sn_poll_entry_t	*irq_list;
-
-	irq_list = pdacpu(IRQCPU(irq)).pda_poll_entries;;
-
-	spin_lock_irqsave(&irq_lock, flags);
-	irq_cnt = pdacpu(IRQCPU(irq)).pda_poll_entry_count;
-	irq_list[irq_cnt].irq = irq;
-	irq_list[irq_cnt].interval = interval;
-	irq_list[irq_cnt].tick = interval;
-	pdacpu(IRQCPU(irq)).pda_poll_entry_count++;
-	spin_unlock_irqrestore(&irq_lock, flags);
-
-
-}
-
-void
-sn_delete_polled_interrupt(int irq)
-{
-	unsigned long flags, i, irq_cnt;
-	sn_poll_entry_t	*irq_list;
-
-	irq_list = pdacpu(IRQCPU(irq)).pda_poll_entries;
-
-	spin_lock_irqsave(&irq_lock, flags);
-	irq_cnt = pdacpu(IRQCPU(irq)).pda_poll_entry_count;
-	for (i=0; i<irq_cnt; i++) {
-		if (irq_list[i].irq == irq) {
-			irq_list[i] = irq_list[irq_cnt-1];
-			pdacpu(IRQCPU(irq)).pda_poll_entry_count--;
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&irq_lock, flags);
-}
-
-long sn_int_poll_ticks=50;
-
-void
-sn_irq_poll(int cpu, int reason) 
-{
-	unsigned long flags, i;
-	sn_poll_entry_t	*irq_list;
-
-
-#ifdef CONFIG_SHUB_1_0_SPECIFIC
-	ia64_handle_irq(IA64_IPI_VECTOR, 0);
-#else
-	if (sn_int_poll_ticks == 0)
-		return;
-#endif
-	irq_list = pda.pda_poll_entries;
-
-	for (i=0; i<pda.pda_poll_entry_count; i++, irq_list++) {
-		if (--irq_list->tick <= 0) {
-#ifdef CONFIG_SHUB_1_0_SPECIFIC
-			irq_list->tick = irq_list->interval;
-#else
-			irq_list->tick = sn_int_poll_ticks;
-#endif
-			local_irq_save(flags);
-			ia64_handle_irq(irq_to_vector(irq_list->irq), 0);
-			local_irq_restore(flags);
-		}
-	}
-}	
-
-#define PROCFILENAME	"sn_int_poll_ticks"
-
-static struct proc_dir_entry *proc_op;
-
-
-static int
-read_proc(char *buffer, char **start, off_t off, int count, int *eof, void *data)
-{
-	int len = 0;
-
-	len += sprintf(buffer + len, "Poll hack: interval %ld ticks\n", sn_int_poll_ticks);
-
-	if (len <= off+count) *eof = 1;
-	*start = buffer + off;
-	len   -= off;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-	return len;
-}
-
-static int
-write_proc (struct file *file, const char *userbuf, unsigned long count, void *data)
-{
-       extern long atoi(char *);
-       char        buf[80];
-
-       if (copy_from_user(buf, userbuf, count < sizeof(buf) ? count : sizeof(buf)))
-           return -EFAULT;
-
-       sn_int_poll_ticks = atoi(buf);
-
-       return count;
-}
-
-
-int __init
-sn_poll_init(void)
-{
-	if ((proc_op = create_proc_entry(PROCFILENAME, 0644, NULL)) == NULL) {
-		printk("%s: unable to create proc entry", PROCFILENAME);
-		return -1;
-	}
-	proc_op->read_proc = read_proc;
-	proc_op->write_proc = write_proc;
-	return 0;
-}
-
-module_init(sn_poll_init);
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn1/Makefile linux-2.4.22-pre10/arch/ia64/sn/kernel/sn1/Makefile
--- linux-2.4.21/arch/ia64/sn/kernel/sn1/Makefile	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn1/Makefile	1970-01-01 00:00:00.000000000 +0000
@@ -1,47 +0,0 @@
-#
-# arch/ia64/sn/kernel/sn1/Makefile
-#
-# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify it 
-# under the terms of version 2 of the GNU General Public License 
-# as published by the Free Software Foundation.
-# 
-# This program is distributed in the hope that it would be useful, but 
-# WITHOUT ANY WARRANTY; without even the implied warranty of 
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
-# 
-# Further, this software is distributed without any warranty that it is 
-# free of the rightful claim of any third person regarding infringement 
-# or the like.  Any license provided herein, whether implied or 
-# otherwise, applies only to this software file.  Patent licenses, if 
-# any, provided herein do not apply to combinations of this program with 
-# other software, or any other product whatsoever.
-# 
-# You should have received a copy of the GNU General Public 
-# License along with this program; if not, write the Free Software 
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
-# 
-# Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
-# Mountain View, CA  94043, or:
-# 
-# http://www.sgi.com 
-# 
-# For further information regarding this notice, see: 
-# 
-# http://oss.sgi.com/projects/GenInfo/NoticeExplan
-#
-
-
-EXTRA_CFLAGS    := -DLITTLE_ENDIAN
-
-.S.s:
-	$(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $<
-.S.o:
-	$(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
-
-O_TARGET        = sn1.o
-
-obj-y          = cache.o error.o iomv.o synergy.o sn1_smp.o
-
-include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn1/cache.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sn1/cache.c
--- linux-2.4.21/arch/ia64/sn/kernel/sn1/cache.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn1/cache.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,81 +0,0 @@
-/*
- * 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- * 
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- *
- */
-
-#include <linux/kernel.h>
-#include <asm/pgalloc.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/synergy.h>
-#include <asm/delay.h>
-
-#ifndef MB
-#define	MB	(1024*1024)
-#endif
-
-/*
- * Lock for protecting SYN_TAG_DISABLE_WAY.
- * Consider making this a per-FSB lock. 
- */
-static spinlock_t flush_lock = SPIN_LOCK_UNLOCKED;
-
-/**
- * sn_flush_all_caches - flush a range of addresses from all caches (incl. L4)
- * @flush_addr: identity mapped region 7 address to start flushing
- * @bytes: number of bytes to flush
- *
- * Flush a range of addresses from all caches including L4.  All addresses 
- * fully or partially contained within @flush_addr to @flush_addr + @bytes 
- * are flushed from the all caches.
- */
-void
-sn_flush_all_caches(long flush_addr, long bytes)
-{
-	ulong 	addr, baddr, eaddr, bitbucket;
-	int	way, alias;
-
-	/*
-	 * Because of the way synergy implements "fc", this flushes the
-	 * data from all caches on all cpus & L4's on OTHER FSBs. It also
-	 * flushes both cpus on the local FSB. It does NOT flush it from 
-	 * the local FSB.
-	 */
-	flush_icache_range(flush_addr, flush_addr+bytes);
-
-	/*
-	 * Memory DIMMs are a minimum of 256MB and start on 256MB
-	 * boundaries. Convert the start address to an address
-	 * that is between +0MB & +128 of the same DIMM. 
-	 * Then add 8MB to skip the uncached MinState areas if the address
-	 * is on the master node.
-	 */
-	if (bytes > SYNERGY_L4_BYTES_PER_WAY)
-		bytes = SYNERGY_L4_BYTES_PER_WAY;
-	baddr = TO_NODE(smp_physical_node_id(), PAGE_OFFSET + (flush_addr & (128*MB-1)) + 8*MB); 
-	eaddr = (baddr+bytes+SYNERGY_BLOCK_SIZE-1) & ~(SYNERGY_BLOCK_SIZE-1);
-	baddr = baddr & ~(SYNERGY_BLOCK_SIZE-1);
-
-	/*
-	 * Now flush the local synergy.
-	 */
-	spin_lock(&flush_lock);
-	for(way=0; way<SYNERGY_L4_WAYS; way++) {
-		WRITE_LOCAL_SYNERGY_REG(SYN_TAG_DISABLE_WAY, 0xffL ^ (1L<<way));
-		mb();
-		for(alias=0; alias < 9; alias++)
-			for(addr=baddr; addr<eaddr; addr+=SYNERGY_BLOCK_SIZE)
-				bitbucket = *(volatile ulong *)(addr+alias*8*MB);
-		mb();
-	}
-	WRITE_LOCAL_SYNERGY_REG(SYN_TAG_DISABLE_WAY, 0);
-	spin_unlock(&flush_lock);
-
-}
-
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn1/error.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sn1/error.c
--- linux-2.4.21/arch/ia64/sn/kernel/sn1/error.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn1/error.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,187 +0,0 @@
-/*
- * SN1 Platform specific error Support
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/ptrace.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/smp.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/addrs.h>
-
-/**
- * snia_error_intr_handler - handle SN specific error interrupts
- * @irq: error interrupt received
- * @devid: device causing the interrupt
- * @pt_regs: saved register state
- *
- * This routine is called when certain interrupts occur on SN systems.
- * It will either recover from the situations that caused the interrupt
- * or panic.
- */
-void
-snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs)
-{
-	unsigned long long intpend_val;
-	unsigned long long bit;
-
-	switch (irq) {
-	case SGI_UART_IRQ:
-		/*
-		 * This isn't really an error interrupt.  We're just
-		 * here because we have to do something with them.
-		 * This is probably wrong, and this code will be
-		 * removed.
-		 */
-		intpend_val = LOCAL_HUB_L(PI_INT_PEND0);
-		if ( (bit = ~(1L<<GFX_INTR_A)) ==
-			(intpend_val & ~(1L<<GFX_INTR_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<GFX_INTR_B)) ==
-			(intpend_val & ~(1L<<GFX_INTR_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<PG_MIG_INTR)) ==
-			(intpend_val & ~(1L<<PG_MIG_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<UART_INTR)) ==
-			(intpend_val & ~(1L<<UART_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<CC_PEND_A)) ==
-			(intpend_val & ~(1L<<CC_PEND_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<CC_PEND_B)) ==
-			(intpend_val & ~(1L<<CC_PEND_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		printk("Received SGI_UART_IRQ (65), but no intpend0 bits were set???\n");
-		return;
-	case SGI_HUB_ERROR_IRQ:
-		/*
-		 * These are mostly error interrupts of various
-		 * sorts.  We need to do more than panic here, but
-		 * what the heck, this is bring up.
-		 */
-		intpend_val = LOCAL_HUB_L(PI_INT_PEND1);
-		
-		if ( (bit = ~(1L<<XB_ERROR)) ==
-			(intpend_val & ~(1L<<XB_ERROR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED XB_ERROR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<LB_ERROR)) ==
-			(intpend_val & ~(1L<<LB_ERROR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED LB_ERROR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<NACK_INT_A)) ==
-			(intpend_val & ~(1L<<NACK_INT_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED NACK_INT_A on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<NACK_INT_B)) ==
-			(intpend_val & ~(1L<<NACK_INT_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED NACK_INT_B on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<CLK_ERR_INTR)) ==
-			(intpend_val & ~(1L<<CLK_ERR_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED CLK_ERR_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<COR_ERR_INTR_A)) ==
-			(intpend_val & ~(1L<<COR_ERR_INTR_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED COR_ERR_INTR_A on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<COR_ERR_INTR_B)) ==
-			(intpend_val & ~(1L<<COR_ERR_INTR_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED COR_ERR_INTR_B on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<MD_COR_ERR_INTR)) ==
-			(intpend_val & ~(1L<<MD_COR_ERR_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED MD_COR_ERR_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<NI_ERROR_INTR)) ==
-			(intpend_val & ~(1L<<NI_ERROR_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED NI_ERROR_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<MSC_PANIC_INTR)) ==
-			(intpend_val & ~(1L<<MSC_PANIC_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED MSC_PANIC_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		printk("Received SGI_XB_ERROR_IRQ (182) but no intpend1 bits are set???\n");
-		return;
-	default:
-		printk("Received invalid irq in snia_error_intr_handler()\n");
-	}
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn1/iomv.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sn1/iomv.c
--- linux-2.4.21/arch/ia64/sn/kernel/sn1/iomv.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn1/iomv.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,65 +0,0 @@
-/* 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <asm/sn/simulator.h>
-#include <asm/delay.h>
-#include <asm/sn/pda.h>
-
-/**
- * sn_io_addr - convert an in/out port to an i/o address
- * @port: port to convert
- *
- * Legacy in/out instructions are converted to ld/st instructions
- * on IA64.  This routine will convert a port number into a valid 
- * SN i/o address.  Used by sn_in*() and sn_out*().
- */
-void *
-sn_io_addr(unsigned long port)
-{
-	if (!IS_RUNNING_ON_SIMULATOR()) {
-		return( (void *)  (port | __IA64_UNCACHED_OFFSET));
-	} else {
-		unsigned long io_base;
-		unsigned long addr;
- 
-		/*
- 		 * word align port, but need more than 10 bits
- 		 * for accessing registers in bedrock local block
- 		 * (so we don't do port&0xfff)
- 		 */
-		if ((port >= 0x1f0 && port <= 0x1f7) ||
-			port == 0x3f6 || port == 0x3f7) {
-			io_base = __IA64_UNCACHED_OFFSET | 0x00000FFFFC000000;
-			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
-		} else {
-			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
-		}
-		return(void *) addr;
-	}
-}
-
-/**
- * sn1_mmiob - I/O space memory barrier
- *
- * Acts as a memory mapped I/O barrier for platforms that queue writes to 
- * I/O space.  This ensures that subsequent writes to I/O space arrive after
- * all previous writes.  For most ia64 platforms, this is a simple
- * 'mf.a' instruction.  For other platforms, mmiob() may have to read
- * a chipset register to ensure ordering.
- *
- * On SN1, we wait for the PIO_WRITE_STATUS Bedrock register to clear.
- */
-void
-sn1_mmiob (void)
-{
-	(volatile unsigned long) (*pda.bedrock_rev_id);
-	while (!(volatile unsigned long) (*pda.pio_write_status_addr))
-		udelay(5);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn1/sn1_smp.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sn1/sn1_smp.c
--- linux-2.4.21/arch/ia64/sn/kernel/sn1/sn1_smp.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn1/sn1_smp.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,476 +0,0 @@
-/*
- * SN1 Platform specific SMP Support
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/threads.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mmzone.h>
-
-#include <asm/processor.h>
-#include <asm/irq.h>
-#include <asm/sal.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/hw_irq.h>
-#include <asm/current.h>
-#include <asm/delay.h>
-#include <asm/sn/sn_cpuid.h>
-
-/*
- * The following structure is used to pass params thru smp_call_function
- * to other cpus for flushing TLB ranges.
- */
-typedef struct {
-	union {
-		struct {
-			unsigned long	start;
-			unsigned long	end;
-			unsigned long	nbits;
-			unsigned int	rid;
-			atomic_t	unfinished_count;
-		} ptc;
-		char pad[SMP_CACHE_BYTES];
-	};
-} ptc_params_t;
-
-#define NUMPTC	512
-
-static ptc_params_t	ptcParamArray[NUMPTC] __attribute__((__aligned__(128)));
-
-/* use separate cache lines on ptcParamsNextByCpu to avoid false sharing */
-static ptc_params_t	*ptcParamsNextByCpu[NR_CPUS*16] __attribute__((__aligned__(128)));
-static volatile ptc_params_t	*ptcParamsEmpty __cacheline_aligned;
-
-/*REFERENCED*/
-static spinlock_t ptcParamsLock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
-
-static int ptcInit = 0;
-#ifdef PTCDEBUG
-static int ptcParamsAllBusy = 0;		/* debugging/statistics */
-static int ptcCountBacklog = 0;
-static int ptcBacklog[NUMPTC+1];
-static char ptcParamsCounts[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-static char ptcParamsResults[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-#endif
-
-/*
- * Make smp_send_flush_tlbsmp_send_flush_tlb() a weak reference,
- * so that we get a clean compile with the ia64 patch without the
- * actual SN1 specific code in arch/ia64/kernel/smp.c.
- */
-extern void smp_send_flush_tlb (void) __attribute((weak));
-
-/*
- * The following table/struct is for remembering PTC coherency domains. It
- * is also used to translate sapicid into cpuids. We dont want to start 
- * cpus unless we know their cache domain.
- */
-#ifdef PTC_NOTYET
-sn_sapicid_info_t	sn_sapicid_info[NR_CPUS];
-#endif
-
-/**
- * sn1_ptc_l_range - purge local translation cache
- * @start: start of virtual address range
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Purges the range specified from the local processor's translation cache
- * (as opposed to the translation registers).  Note that more than the specified
- * range *may* be cleared from the cache by some processors.
- *
- * This is probably not good enough, but I don't want to try to make it better 
- * until I get some statistics on a running system. At a minimum, we should only 
- * send IPIs to 1 processor in each TLB domain & have it issue a ptc.g on it's 
- * own FSB. Also, we only have to serialize per FSB, not globally.
- *
- * More likely, we will have to do some work to reduce the frequency of calls to
- * this routine.
- */
-static inline void
-sn1_ptc_l_range(unsigned long start, unsigned long end, unsigned long nbits)
-{
-	do {
-		__asm__ __volatile__ ("ptc.l %0,%1" :: "r"(start), "r"(nbits<<2) : "memory");
-		start += (1UL << nbits);
-	} while (start < end);
-	ia64_srlz_d();
-}
-
-/**
- * sn1_received_flush_tlb - cpu tlb flush routine
- *
- * Flushes the TLB of a given processor.
- */
-void
-sn1_received_flush_tlb(void)
-{
-	unsigned long	start, end, nbits;
-	unsigned int	rid, saved_rid;
-	int		cpu = smp_processor_id();
-	int		result;
-	ptc_params_t	*ptcParams;
-
-	ptcParams = ptcParamsNextByCpu[cpu*16];
-	if (ptcParams == ptcParamsEmpty)
-		return;
-
-	do {
-		start = ptcParams->ptc.start;
-		saved_rid = (unsigned int) ia64_get_rr(start);
-		end = ptcParams->ptc.end;
-		nbits = ptcParams->ptc.nbits;
-		rid = ptcParams->ptc.rid;
-
-		if (saved_rid != rid) {
-			ia64_set_rr(start, (unsigned long)rid);
-			ia64_srlz_d();
-		}
-
-		sn1_ptc_l_range(start, end, nbits);
-
-		if (saved_rid != rid) 
-			ia64_set_rr(start, (unsigned long)saved_rid);
-
-		ia64_srlz_i();
-
-		result = atomic_dec(&ptcParams->ptc.unfinished_count);
-#ifdef PTCDEBUG
-		{
-		    int i = ptcParams-&ptcParamArray[0];
-		    ptcParamsResults[cpu][i] = (char) result;
-		    ptcParamsCounts[cpu][i]++;
-		}
-#endif /* PTCDEBUG */
-
-		if (++ptcParams == &ptcParamArray[NUMPTC])
-			ptcParams = &ptcParamArray[0];
-
-	} while (ptcParams != ptcParamsEmpty);
-
-	ptcParamsNextByCpu[cpu*16] = ptcParams;
-}
-
-/**
- * sn1_global_tlb_purge - flush a translation cache range on all processors
- * @start: start of virtual address range to flush
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Flushes the translation cache of all processors from @start to @end.
- */
-void
-sn1_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
-{
-	ptc_params_t	*params;
-	ptc_params_t	*next;
-	unsigned long	irqflags;
-#ifdef PTCDEBUG
-	ptc_params_t	*nextnext;
-	int		backlog = 0;
-#endif
-
-	if (smp_num_cpus == 1) {
-		sn1_ptc_l_range(start, end, nbits);
-		return;
-	}
-
-	if (in_interrupt()) {
-		/*
-		 *  If at interrupt level and cannot get spinlock, 
-		 *  then do something useful by flushing own tlbflush queue
-		 *  so as to avoid a possible deadlock.
-		 */
-		while (!spin_trylock(&ptcParamsLock)) {
-			local_irq_save(irqflags);
-			sn1_received_flush_tlb();
-			local_irq_restore(irqflags);
-			udelay(10);	/* take it easier on the bus */	
-		}
-	} else {
-		spin_lock(&ptcParamsLock);
-	}
-
-	if (!ptcInit) {
-		int cpu;
-		ptcInit = 1;
-		memset(ptcParamArray, 0, sizeof(ptcParamArray));
-		ptcParamsEmpty = &ptcParamArray[0];
-		for (cpu=0; cpu<NR_CPUS; cpu++)
-			ptcParamsNextByCpu[cpu*16] = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
-		memset(ptcBacklog, 0, sizeof(ptcBacklog));
-		memset(ptcParamsCounts, 0, sizeof(ptcParamsCounts));
-		memset(ptcParamsResults, 0, sizeof(ptcParamsResults));
-#endif	/* PTCDEBUG */
-	}
-
-	params = (ptc_params_t *) ptcParamsEmpty;
-	next = (ptc_params_t *) ptcParamsEmpty + 1;
-	if (next == &ptcParamArray[NUMPTC])
-		next = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
-	nextnext = next + 1;
-	if (nextnext == &ptcParamArray[NUMPTC])
-		nextnext = &ptcParamArray[0];
-
-	if (ptcCountBacklog) {
-		/* quick count of backlog */
-		ptc_params_t *ptr;
-
-		/* check the current pointer to the beginning */
-		ptr = params;
-		while(--ptr >= &ptcParamArray[0]) {
-			if (atomic_read(&ptr->ptc.unfinished_count) == 0)
-				break;
-			++backlog;
-		}
-
-		if (backlog) {
-			/* check the end of the array */
-			ptr = &ptcParamArray[NUMPTC];
-			while (--ptr > params) {
-				if (atomic_read(&ptr->ptc.unfinished_count) == 0)
-					break;
-				++backlog;
-			}
-		}
-		ptcBacklog[backlog]++;
-	}
-#endif	/* PTCDEBUG */
-
-	/* wait for the next entry to clear...should be rare */
-	if (atomic_read(&next->ptc.unfinished_count) > 0) {
-#ifdef PTCDEBUG
-		ptcParamsAllBusy++;
-
-		if (atomic_read(&nextnext->ptc.unfinished_count) == 0) {
-		    if (atomic_read(&next->ptc.unfinished_count) > 0) {
-			panic("\nnonzero next zero nextnext %lx %lx\n",
-			    (long)next, (long)nextnext);
-		    }
-		}
-#endif
-
-		/* it could be this cpu that is behind */
-		local_irq_save(irqflags);
-		sn1_received_flush_tlb();
-		local_irq_restore(irqflags);
-
-		/* now we know it's not this cpu, so just wait */
-		while (atomic_read(&next->ptc.unfinished_count) > 0) {
-			barrier();
-		}
-	}
-
-	params->ptc.start = start;
-	params->ptc.end = end;
-	params->ptc.nbits = nbits;
-	params->ptc.rid = (unsigned int) ia64_get_rr(start);
-	atomic_set(&params->ptc.unfinished_count, smp_num_cpus);
-
-	/* The atomic_set above can hit memory *after* the update
-	 * to ptcParamsEmpty below, which opens a timing window
-	 * that other cpus can squeeze into!
-	 */
-	mb();
-
-	/* everything is ready to process:
-	 *	-- global lock is held
-	 *	-- new entry + 1 is free
-	 *	-- new entry is set up
-	 * so now:
-	 *	-- update the global next pointer
-	 *	-- unlock the global lock
-	 *	-- send IPI to notify other cpus
-	 *	-- process the data ourselves
-	 */
-	ptcParamsEmpty = next;
-	spin_unlock(&ptcParamsLock);
-	smp_send_flush_tlb();
-
-	local_irq_save(irqflags);
-	sn1_received_flush_tlb();
-	local_irq_restore(irqflags);
-
-	/* Currently we don't think global TLB purges need to be atomic.
-	 * All CPUs get sent IPIs, so if they haven't done the purge,
-	 * they're busy with interrupts that are at the IPI level, which is
-	 * priority 15.  We're asserting that any code at that level
-	 * shouldn't be using user TLB entries.  To change this to wait
-	 * for all the flushes to complete, enable the following code.
-	 */
-#if defined(SN1_SYNCHRONOUS_GLOBAL_TLB_PURGE) || defined(BUS_INT_WAR)
-	/* this code is not tested */
-	/* wait for the flush to complete */
-	while (atomic_read(&params->ptc.unfinished_count) > 0)
-		barrier();
-#endif
-}
-
-/**
- * sn_send_IPI_phys - send an IPI to a Nasid and slice
- * @physid: physical cpuid to receive the interrupt.
- * @vector: command to send
- * @delivery_mode: delivery mechanism
- *
- * Sends an IPI (interprocessor interrupt) to the processor specified by
- * @physid
- *
- * @delivery_mode can be one of the following
- *
- * %IA64_IPI_DM_INT - pend an interrupt
- * %IA64_IPI_DM_PMI - pend a PMI
- * %IA64_IPI_DM_NMI - pend an NMI
- * %IA64_IPI_DM_INIT - pend an INIT interrupt
- */
-void
-sn_send_IPI_phys(long physid, int vector, int delivery_mode)
-{
-	long		*p;
-	long		nasid, slice;
-
-	static int 	off[4] = {0x1800080, 0x1800088, 0x1a00080, 0x1a00088};
-
-#ifdef BUS_INT_WAR
-	if (vector != ap_wakeup_vector) {
-		return;
-	}
-#endif
-
-	nasid = cpu_physical_id_to_nasid(physid);
-        slice = cpu_physical_id_to_slice(physid);
-
-	p = (long*)(0xc0000a0000000000LL | (nasid<<33) | off[slice]);
-
-	mb();
-	*p = (delivery_mode << 8) | (vector & 0xff);
-}
-
-
-/**
- * sn1_send_IPI - send an IPI to a processor
- * @cpuid: target of the IPI
- * @vector: command to send
- * @delivery_mode: delivery mechanism
- * @redirect: redirect the IPI?
- *
- * Sends an IPI (interprocessor interrupt) to the processor specified by
- * @cpuid.  @delivery_mode can be one of the following
- *
- * %IA64_IPI_DM_INT - pend an interrupt
- * %IA64_IPI_DM_PMI - pend a PMI
- * %IA64_IPI_DM_NMI - pend an NMI
- * %IA64_IPI_DM_INIT - pend an INIT interrupt
- */
-void
-sn1_send_IPI(int cpuid, int vector, int delivery_mode, int redirect)
-{
-	long		physid;
-
-	physid = cpu_physical_id(cpuid);
-
-	sn_send_IPI_phys(physid, vector, delivery_mode);
-}
-#ifdef CONFIG_SMP
-
-#ifdef PTC_NOTYET
-static void __init
-process_sal_ptc_domain_info(ia64_sal_ptc_domain_info_t *di, int domain)
-{
-	ia64_sal_ptc_domain_proc_entry_t	*pe;
-	int 					i, sapicid, cpuid;
-
-	pe = __va(di->proc_list);
-	for (i=0; i<di->proc_count; i++, pe++) {
-		sapicid = id_eid_to_sapicid(pe->id, pe->eid);
-		cpuid = cpu_logical_id(sapicid);
-		sn_sapicid_info[cpuid].domain = domain;
-		sn_sapicid_info[cpuid].sapicid = sapicid;
-	}
-}
-
-
-static void __init
-process_sal_desc_ptc(ia64_sal_desc_ptc_t *ptc)
-{
-	ia64_sal_ptc_domain_info_t	*di;
-	int i;
-
-	di = __va(ptc->domain_info);
-	for (i=0; i<ptc->num_domains; i++, di++) {
-		process_sal_ptc_domain_info(di, i);	
-	}
-}
-#endif /* PTC_NOTYET */
-
-/**
- * init_sn1_smp_config - setup PTC domains per processor
- */
-void __init
-init_sn1_smp_config(void)
-{
-	if (!ia64_ptc_domain_info)  {
-		printk("SMP: Can't find PTC domain info. Forcing UP mode\n");
-		smp_num_cpus = 1;
-		return;
-	}
-
-#ifdef PTC_NOTYET
-	memset (sn_sapicid_info, -1, sizeof(sn_sapicid_info));
-	process_sal_desc_ptc(ia64_ptc_domain_info);
-#endif
-}
-
-#else /* CONFIG_SMP */
-
-void __init
-init_sn1_smp_config(void)
-{
-
-#ifdef PTC_NOTYET
-	sn_sapicid_info[0].sapicid = hard_smp_processor_id();
-#endif
-}
-
-#endif /* CONFIG_SMP */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn1/synergy.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sn1/synergy.c
--- linux-2.4.21/arch/ia64/sn/kernel/sn1/synergy.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn1/synergy.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,533 +0,0 @@
-/*
- * SN1 Platform specific synergy Support
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/proc_fs.h>
-
-#include <asm/ptrace.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/smp.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/sn1/synergy.h>
-#include <asm/sn/sndrv.h>
-
-int bit_pos_to_irq(int bit);
-void setclear_mask_b(int irq, int cpuid, int set);
-void setclear_mask_a(int irq, int cpuid, int set);
-void * kmalloc(size_t size, int flags);
-
-static int synergy_perf_initialized = 0;
-
-void
-synergy_intr_alloc(int bit, int cpuid) {
-	return;
-}
-
-int
-synergy_intr_connect(int bit, 
-		int cpuid)
-{
-	int irq;
-	unsigned is_b;
-
-	irq = bit_pos_to_irq(bit);
-
-	is_b = (cpuid_to_slice(cpuid)) & 1;
-	if (is_b) {
-		setclear_mask_b(irq,cpuid,1);
-		setclear_mask_a(irq,cpuid, 0);
-	} else {
-		setclear_mask_a(irq, cpuid, 1);
-		setclear_mask_b(irq, cpuid, 0);
-	}
-	return 0;
-}
-void
-setclear_mask_a(int irq, int cpuid, int set)
-{
-	int synergy;
-	int nasid;
-	int reg_num;
-	unsigned long mask;
-	unsigned long addr;
-	unsigned long reg;
-	unsigned long val;
-	int my_cnode, my_synergy;
-	int target_cnode, target_synergy;
-
-        /*
-         * Perform some idiot checks ..
-         */
-        if ( (irq < 0) || (irq > 255) ||
-                (cpuid < 0) || (cpuid > 512) ) {
-                printk("clear_mask_a: Invalid parameter irq %d cpuid %d\n", irq, cpuid);
-		return;
-	}
-
-	target_cnode = cpuid_to_cnodeid(cpuid);
-	target_synergy = cpuid_to_synergy(cpuid);
-	my_cnode = cpuid_to_cnodeid(smp_processor_id());
-	my_synergy = cpuid_to_synergy(smp_processor_id());
-
-	reg_num = irq / 64;
-	mask = 1;
-	mask <<= (irq % 64);
-	switch (reg_num) {
-		case 0: 
-			reg = VEC_MASK0A;
-			addr = VEC_MASK0A_ADDR;
-			break;
-		case 1: 
-			reg = VEC_MASK1A;
-			addr = VEC_MASK1A_ADDR;
-			break;
-		case 2: 
-			reg = VEC_MASK2A;
-			addr = VEC_MASK2A_ADDR;
-			break;
-		case 3: 
-			reg = VEC_MASK3A;
-			addr = VEC_MASK3A_ADDR;
-			break;
-		default:
-			reg = addr = 0;
-			break;
-	}
-	if (my_cnode == target_cnode && my_synergy == target_synergy) {
-		// local synergy
-		val = READ_LOCAL_SYNERGY_REG(addr);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		WRITE_LOCAL_SYNERGY_REG(addr, val);
-		val = READ_LOCAL_SYNERGY_REG(addr);
-	} else { /* remote synergy */
-		synergy = cpuid_to_synergy(cpuid);
-		nasid = cpuid_to_nasid(cpuid);
-		val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		REMOTE_SYNERGY_STORE(nasid, synergy, reg, val);
-	}
-}
-
-void
-setclear_mask_b(int irq, int cpuid, int set)
-{
-	int synergy;
-	int nasid;
-	int reg_num;
-	unsigned long mask;
-	unsigned long addr;
-	unsigned long reg;
-	unsigned long val;
-	int my_cnode, my_synergy;
-	int target_cnode, target_synergy;
-
-	/*
-	 * Perform some idiot checks ..
-	 */
-	if ( (irq < 0) || (irq > 255) ||
-		(cpuid < 0) || (cpuid > 512) ) {
-		printk("clear_mask_b: Invalid parameter irq %d cpuid %d\n", irq, cpuid);
-		return;
-	}
-
-	target_cnode = cpuid_to_cnodeid(cpuid);
-	target_synergy = cpuid_to_synergy(cpuid);
-	my_cnode = cpuid_to_cnodeid(smp_processor_id());
-	my_synergy = cpuid_to_synergy(smp_processor_id());
-
-	reg_num = irq / 64;
-	mask = 1;
-	mask <<= (irq % 64);
-	switch (reg_num) {
-		case 0: 
-			reg = VEC_MASK0B;
-			addr = VEC_MASK0B_ADDR;
-			break;
-		case 1: 
-			reg = VEC_MASK1B;
-			addr = VEC_MASK1B_ADDR;
-			break;
-		case 2: 
-			reg = VEC_MASK2B;
-			addr = VEC_MASK2B_ADDR;
-			break;
-		case 3: 
-			reg = VEC_MASK3B;
-			addr = VEC_MASK3B_ADDR;
-			break;
-		default:
-			reg = addr = 0;
-			break;
-	}
-	if (my_cnode == target_cnode && my_synergy == target_synergy) {
-		// local synergy
-		val = READ_LOCAL_SYNERGY_REG(addr);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		WRITE_LOCAL_SYNERGY_REG(addr, val);
-		val = READ_LOCAL_SYNERGY_REG(addr);
-	} else { /* remote synergy */
-		synergy = cpuid_to_synergy(cpuid);
-		nasid = cpuid_to_nasid(cpuid);
-		val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		REMOTE_SYNERGY_STORE(nasid, synergy, reg, val);
-	}
-}
-
-/*
- * Synergy perf stats. Multiplexed via timer_interrupt.
- */
-
-static int
-synergy_perf_append(uint64_t modesel)
-{
-	int		cnode;
-	nodepda_t       *npdap;
-	synergy_perf_t	*p;
-	int		checked = 0;
-	int		err = 0;
-	unsigned long	flags;
-
-	/* bit 45 is enable */
-	modesel |= (1UL << 45);
-
-	for (cnode=0; cnode < numnodes; cnode++) {
-		/* for each node, insert a new synergy_perf entry */
-		if ((npdap = NODEPDA(cnode)) == NULL) {
-			printk("synergy_perf_append: cnode=%d NODEPDA(cnode)==NULL, nodepda=%p\n", cnode, (void *)nodepda);
-			continue;
-		}
-
-		if (npdap->synergy_perf_enabled) {
-			/* user must disable counting to append new events */
-			err = -EBUSY;
-			break;
-		}
-
-		if (!checked && npdap->synergy_perf_data != NULL) {
-			checked = 1;
-			for (p = npdap->synergy_perf_first; ;) {
-				if (p->modesel == modesel)
-					return 0; /* event already registered */
-				if ((p = p->next) == npdap->synergy_perf_first)
-					break;
-			}
-		}
-
-		/* XX use kmem_alloc_node() when it is implemented */
-		p = (synergy_perf_t *)kmalloc(sizeof(synergy_perf_t), GFP_KERNEL);
-		if ((((uint64_t)p) & 7UL) != 0)
-			BUG(); /* bad alignment */
-		if (p == NULL) {
-			err = -ENOMEM;
-			break;
-		}
-		else {
-			memset(p, 0, sizeof(synergy_perf_t));
-			p->modesel = modesel;
-
-			spin_lock_irqsave(&npdap->synergy_perf_lock, flags);
-			if (npdap->synergy_perf_data == NULL) {
-				/* circular list */
-				p->next = p;
-				npdap->synergy_perf_first = p;
-				npdap->synergy_perf_data = p;
-			}
-			else {
-				p->next = npdap->synergy_perf_data->next;
-				npdap->synergy_perf_data->next = p;
-			}
-			spin_unlock_irqrestore(&npdap->synergy_perf_lock, flags);
-		}
-	}
-
-	return err;
-}
-
-static void
-synergy_perf_set_freq(int freq)
-{
-	int		cnode;
-	nodepda_t	*npdap;
-
-	for (cnode=0; cnode < numnodes; cnode++) {
-		if ((npdap = NODEPDA(cnode)) != NULL)
-			npdap->synergy_perf_freq = freq;
-	}
-}
-
-static void
-synergy_perf_set_enable(int enable)
-{
-	int		cnode;
-	nodepda_t	*npdap;
-
-	for (cnode=0; cnode < numnodes; cnode++) {
-		if ((npdap = NODEPDA(cnode)) != NULL)
-			npdap->synergy_perf_enabled = enable;
-	}
-	printk("NOTICE: synergy perf counting %sabled on all nodes\n", enable ? "en" : "dis");
-}
-
-static int
-synergy_perf_size(nodepda_t *npdap)
-{
-	synergy_perf_t	*p;
-	int		n;
-
-	if (npdap->synergy_perf_enabled == 0) {
-		/* no stats to return */
-		return 0;
-	}
-
-	spin_lock_irq(&npdap->synergy_perf_lock);
-	for (n=0, p = npdap->synergy_perf_first; p;) {
-		n++;
-		p = p->next;
-		if (p == npdap->synergy_perf_first)
-			break;
-	}
-	spin_unlock_irq(&npdap->synergy_perf_lock);
-
-	/* bytes == n pairs of {event,counter} */
-	return n * 2 * sizeof(uint64_t);
-}
-
-static int
-synergy_perf_ioctl(struct inode *inode, struct file *file,
-        unsigned int cmd, unsigned long arg)
-{
-	int             cnode;
-	nodepda_t       *npdap;
-	synergy_perf_t	*p;
-	int		intarg;
-	int		fsb;
-	uint64_t	longarg;
-	uint64_t	*stats;
-	int		n;
-	devfs_handle_t	d;
-	arbitrary_info_t info;
-	
-	if ((d = devfs_get_handle_from_inode(inode)) == NULL)
-		return -ENODEV;
-	info = hwgraph_fastinfo_get(d);
-
-	cnode = SYNERGY_PERF_INFO_CNODE(info);
-	fsb = SYNERGY_PERF_INFO_FSB(info);
-	npdap = NODEPDA(cnode);
-
-	switch (cmd) {
-	case SNDRV_GET_SYNERGY_VERSION:
-		/* return int, version of data structure for SNDRV_GET_SYNERGYINFO */
-		intarg = 1; /* version 1 */
-		if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
-		    return -EFAULT;
-		break;
-
-	case SNDRV_GET_INFOSIZE:
-		/* return int, sizeof buf needed for SYNERGY_PERF_GET_STATS */
-		intarg = synergy_perf_size(npdap);
-		if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
-		    return -EFAULT;
-		break;
-
-	case SNDRV_GET_SYNERGYINFO:
-		/* return array of event/value pairs, this node only */
-		if ((intarg = synergy_perf_size(npdap)) <= 0)
-			return -ENODATA;
-		if ((stats = (uint64_t *)kmalloc(intarg, GFP_KERNEL)) == NULL)
-			return -ENOMEM;
-		spin_lock_irq(&npdap->synergy_perf_lock);
-		for (n=0, p = npdap->synergy_perf_first; p;) {
-			stats[n++] = p->modesel;
-			if (p->intervals > 0)
-			    stats[n++] = p->counts[fsb] * p->total_intervals / p->intervals;
-			else
-			    stats[n++] = 0;
-			p = p->next;
-			if (p == npdap->synergy_perf_first)
-				break;
-		}
-		spin_unlock_irq(&npdap->synergy_perf_lock);
-
-		if (copy_to_user((void *)arg, stats, intarg)) {
-		    kfree(stats);
-		    return -EFAULT;
-		}
-
-		kfree(stats);
-		break;
-
-	case SNDRV_SYNERGY_APPEND:
-		/* reads 64bit event, append synergy perf event to all nodes  */
-		if (copy_from_user(&longarg, (void *)arg, sizeof(longarg)))
-		    return -EFAULT;
-		return synergy_perf_append(longarg);
-		break;
-
-	case SNDRV_GET_SYNERGY_STATUS:
-		/* return int, 1 if enabled else 0 */
-		intarg = npdap->synergy_perf_enabled;
-		if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
-		    return -EFAULT;
-		break;
-
-	case SNDRV_SYNERGY_ENABLE:
-		/* read int, if true enable counting else disable */
-		if (copy_from_user(&intarg, (void *)arg, sizeof(intarg)))
-		    return -EFAULT;
-		synergy_perf_set_enable(intarg);
-		break;
-
-	case SNDRV_SYNERGY_FREQ:
-		/* read int, set jiffies per update */ 
-		if (copy_from_user(&intarg, (void *)arg, sizeof(intarg)))
-		    return -EFAULT;
-		if (intarg < 0 || intarg >= HZ)
-			return -EINVAL;
-		synergy_perf_set_freq(intarg);
-		break;
-
-	default:
-		printk("Warning: invalid ioctl %d on synergy mon for cnode=%d fsb=%d\n", cmd, cnode, fsb);
-		return -EINVAL;
-	}
-	return(0);
-}
-
-struct file_operations synergy_mon_fops = {
-        ioctl:		synergy_perf_ioctl,
-};
-
-void
-synergy_perf_update(int cpu)
-{
-	nasid_t		nasid;
-	cnodeid_t       cnode;
-	struct nodepda_s *npdap;
-
-	/*
-	 * synergy_perf_initialized is set by synergy_perf_init()
-	 * which is called last thing by sn_mp_setup(), i.e. well
-	 * after nodepda has been initialized.
-	 */
-	if (!synergy_perf_initialized)
-		return;
-
-	cnode = cpuid_to_cnodeid(cpu);
-	npdap = NODEPDA(cnode);
-
-	if (npdap == NULL || cnode < 0 || cnode >= numnodes)
-		/* this should not happen: still in early io init */
-		return;
-
-#if 0
-	/* use this to check nodepda initialization */
-	if (((uint64_t)npdap) & 0x7) {
-		printk("\nERROR on cpu %d : cnode=%d, npdap == %p, not aligned\n", cpu, cnode, npdap);
-		BUG();
-	}
-#endif
-
-	if (npdap->synergy_perf_enabled == 0 || npdap->synergy_perf_data == NULL) {
-		/* Not enabled, or no events to monitor */
-		return;
-	}
-
-	if (npdap->synergy_inactive_intervals++ % npdap->synergy_perf_freq != 0) {
-		/* don't multiplex on every timer interrupt */
-		return;
-	}
-
-	/*
-	 * Read registers for last interval and increment counters.
-	 * Hold the per-node synergy_perf_lock so concurrent readers get
-	 * consistent values.
-	 */
-	spin_lock_irq(&npdap->synergy_perf_lock);
-
-	nasid = cpuid_to_nasid(cpu);
-	npdap->synergy_active_intervals++;
-	npdap->synergy_perf_data->intervals++;
-	npdap->synergy_perf_data->total_intervals = npdap->synergy_active_intervals;
-
-	npdap->synergy_perf_data->counts[0] += 0xffffffffffUL &
-		REMOTE_SYNERGY_LOAD(nasid, 0, PERF_CNTR0_A);
-
-	npdap->synergy_perf_data->counts[1] += 0xffffffffffUL &
-		REMOTE_SYNERGY_LOAD(nasid, 1, PERF_CNTR0_B);
-
-	/* skip to next in circular list */
-	npdap->synergy_perf_data = npdap->synergy_perf_data->next;
-
-	spin_unlock_irq(&npdap->synergy_perf_lock);
-
-	/* set the counter 0 selection modes for both A and B */
-	REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTL0_A, npdap->synergy_perf_data->modesel);
-	REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTL0_B, npdap->synergy_perf_data->modesel);
-
-	/* and reset the counter registers to zero */
-	REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTR0_A, 0UL);
-	REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTR0_B, 0UL);
-}
-
-void
-synergy_perf_init(void)
-{
-	printk("synergy_perf_init(), counting is initially disabled\n");
-	synergy_perf_initialized++;
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn2/Makefile linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/Makefile
--- linux-2.4.21/arch/ia64/sn/kernel/sn2/Makefile	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/Makefile	2003-08-01 13:34:41.000000000 +0000
@@ -1,7 +1,7 @@
 #
 # arch/ia64/sn/kernel/sn2/Makefile
 #
-# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
+# Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All rights reserved.
 #
 # This program is free software; you can redistribute it and/or modify it 
 # under the terms of version 2 of the GNU General Public License 
@@ -41,7 +41,9 @@
 	$(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
 
 O_TARGET        = sn2.o
+export-objs	:= io.o
 
-obj-y          = cache.o iomv.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o
+obj-y		= cache.o io.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o \
+		  prominfo_proc.o timer.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn2/cache.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/cache.c
--- linux-2.4.21/arch/ia64/sn/kernel/sn2/cache.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/cache.c	2003-08-01 13:32:13.000000000 +0000
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  * 
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  *
  */
 
@@ -24,6 +24,5 @@
 sn_flush_all_caches(long flush_addr, long bytes)
 {
 	flush_icache_range(flush_addr, flush_addr+bytes);
+	mb();
 }
-
-
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn2/io.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/io.c
--- linux-2.4.21/arch/ia64/sn/kernel/sn2/io.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/io.c	2003-08-01 13:34:33.000000000 +0000
@@ -0,0 +1,91 @@
+/* 
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Silicon Graphics, Inc. All rights reserved.
+ *
+ * The generic kernel requires function pointers to these routines, so
+ * we wrap the inlines from asm/ia64/sn/sn2/io.h here.
+ */
+
+#include <asm/sn/sn2/io.h>
+
+unsigned int
+sn_inb (unsigned long port)
+{
+	return __sn_inb(port);
+}
+
+unsigned int
+sn_inw (unsigned long port)
+{
+	return __sn_inw(port);
+}
+
+unsigned int
+sn_inl (unsigned long port)
+{
+	return __sn_inl(port);
+}
+
+void
+sn_outb (unsigned char val, unsigned long port)
+{
+	__sn_outb(val, port);
+}
+
+void
+sn_outw (unsigned short val, unsigned long port)
+{
+	__sn_outw(val, port);
+}
+
+void
+sn_outl (unsigned int val, unsigned long port)
+{
+	__sn_outl(val, port);
+}
+
+unsigned char
+sn_readb (void *addr)
+{
+	return __sn_readb (addr);
+}
+
+unsigned short
+sn_readw (void *addr)
+{
+	return __sn_readw (addr);
+}
+
+unsigned int
+sn_readl (void *addr)
+{
+	return __sn_readl (addr);
+}
+
+unsigned long
+sn_readq (void *addr)
+{
+	return __sn_readq (addr);
+}
+
+
+/* define aliases: */
+
+asm (".global __sn_inb, __sn_inw, __sn_inl");
+asm ("__sn_inb = sn_inb");
+asm ("__sn_inw = sn_inw");
+asm ("__sn_inl = sn_inl");
+
+asm (".global __sn_outb, __sn_outw, __sn_outl");
+asm ("__sn_outb = sn_outb");
+asm ("__sn_outw = sn_outw");
+asm ("__sn_outl = sn_outl");
+
+asm (".global __sn_readb, __sn_readw, __sn_readl, __sn_readq");
+asm ("__sn_readb = sn_readb");
+asm ("__sn_readw = sn_readw");
+asm ("__sn_readl = sn_readl");
+asm ("__sn_readq = sn_readq");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn2/iomv.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/iomv.c
--- linux-2.4.21/arch/ia64/sn/kernel/sn2/iomv.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/iomv.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,68 +0,0 @@
-/* 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <asm/delay.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/pda.h>
-#include <asm/sn/sn_cpuid.h>
-
-/**
- * sn_io_addr - convert an in/out port to an i/o address
- * @port: port to convert
- *
- * Legacy in/out instructions are converted to ld/st instructions
- * on IA64.  This routine will convert a port number into a valid 
- * SN i/o address.  Used by sn_in*() and sn_out*().
- */
-void *
-sn_io_addr(unsigned long port)
-{
-	if (!IS_RUNNING_ON_SIMULATOR()) {
-		return( (void *)  (port | __IA64_UNCACHED_OFFSET));
-	} else {
-		unsigned long io_base;
-		unsigned long addr;
- 
-		/*
- 		 * word align port, but need more than 10 bits
- 		 * for accessing registers in bedrock local block
- 		 * (so we don't do port&0xfff)
- 		 */
-		if ((port >= 0x1f0 && port <= 0x1f7) ||
-			port == 0x3f6 || port == 0x3f7) {
-			io_base = (0xc000000fcc000000 | ((unsigned long)get_nasid() << 38));
-			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
-		} else {
-			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
-		}
-		return(void *) addr;
-	}
-}
-
-/**
- * sn2_mmiob - I/O space memory barrier
- *
- * Acts as a memory mapped I/O barrier for platforms that queue writes to 
- * I/O space.  This ensures that subsequent writes to I/O space arrive after
- * all previous writes.  For most ia64 platforms, this is a simple
- * 'mf.a' instruction.  For other platforms, mmiob() may have to read
- * a chipset register to ensure ordering.
- *
- * On SN2, we wait for the PIO_WRITE_STATUS SHub register to clear.
- * See PV 871084 for details about the WAR about zero value.
- *
- */
-void
-sn2_mmiob (void)
-{
-	while ((((volatile unsigned long) (*pda.pio_write_status_addr)) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) != 
-				SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK)
-		udelay(1);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn2/prominfo_proc.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/prominfo_proc.c
--- linux-2.4.21/arch/ia64/sn/kernel/sn2/prominfo_proc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/prominfo_proc.c	2003-08-01 13:33:55.000000000 +0000
@@ -0,0 +1,365 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ *
+ * Module to export the system's Firmware Interface Tables, including
+ * PROM revision numbers, in /proc
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/sn/simulator.h>
+
+/* to lookup nasids */
+#include <asm/sn/sn_cpuid.h>
+
+MODULE_DESCRIPTION("PROM version reporting for /proc");
+MODULE_AUTHOR("Chad Talbott");
+MODULE_LICENSE("GPL");
+
+#undef DEBUG_PROMINFO
+
+#define TRACE_PROMINFO
+
+#if defined(DEBUG_PROMINFO)
+#  define DPRINTK(x...) printk(KERN_DEBUG x)
+#else
+#  define DPRINTK(x...)
+#endif
+
+#if defined(TRACE_PROMINFO) && defined(DEBUG_PROMINFO)
+#  if defined(__GNUC__)
+#    define TRACE()	printk(KERN_DEBUG "%s:%d:%s\n", \
+			       __FILE__, __LINE__, __FUNCTION__)
+#  else
+#    define TRACE()	printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__)
+#  endif
+#else
+#  define TRACE()
+#endif
+
+/* Sub-regions determined by bits in Node Offset */
+#define	LB_PROM_SPACE		0x0000000700000000ul /* Local LB PROM */
+
+#define FIT_SIGNATURE		0x2020205f5449465ful
+/* Standard Intel FIT entry types */
+#define FIT_ENTRY_FIT_HEADER	0x00	/* FIT header entry */
+#define FIT_ENTRY_PAL_B		0x01	/* PAL_B entry */
+/* Entries 0x02 through 0x0D reserved by Intel */
+#define FIT_ENTRY_PAL_A_PROC	0x0E	/* Processor-specific PAL_A entry */
+#define FIT_ENTRY_PAL_A		0x0F	/* PAL_A entry, same as... */
+#define FIT_ENTRY_PAL_A_GEN	0x0F	/* ...Generic PAL_A entry */
+#define FIT_ENTRY_UNUSED	0x7F	/* Unused (reserved by Intel?) */
+/* OEM-defined entries range from 0x10 to 0x7E. */
+#define FIT_ENTRY_SAL_A		0x10	/* SAL_A entry */
+#define FIT_ENTRY_SAL_B		0x11	/* SAL_B entry */
+#define FIT_ENTRY_SALRUNTIME	0x12	/* SAL runtime entry */
+#define FIT_ENTRY_EFI		0x1F	/* EFI entry */
+#define FIT_ENTRY_FPSWA		0x20	/* embedded fpswa entry */
+#define FIT_ENTRY_VMLINUX	0x21	/* embedded vmlinux entry */
+
+#define FIT_MAJOR_SHIFT	(32 + 8)
+#define FIT_MAJOR_MASK	((1 << 8) - 1)
+#define FIT_MINOR_SHIFT	32
+#define FIT_MINOR_MASK	((1 << 8) - 1)
+
+#define FIT_MAJOR(q)	\
+	((unsigned) ((q) >> FIT_MAJOR_SHIFT) & FIT_MAJOR_MASK)
+#define FIT_MINOR(q)	\
+	((unsigned) ((q) >> FIT_MINOR_SHIFT) & FIT_MINOR_MASK)
+
+#define FIT_TYPE_SHIFT	(32 + 16)
+#define FIT_TYPE_MASK	((1 << 7) - 1)
+
+#define FIT_TYPE(q)	\
+	((unsigned) ((q) >> FIT_TYPE_SHIFT) & FIT_TYPE_MASK)
+
+#define FIT_ENTRY(type, maj, min, size)					\
+	((((unsigned long)(maj) & FIT_MAJOR_MASK) << FIT_MAJOR_SHIFT) |	\
+	 (((unsigned long)(min) & FIT_MINOR_MASK) << FIT_MINOR_SHIFT) |	\
+	 (((unsigned long)(type) & FIT_TYPE_MASK) << FIT_TYPE_SHIFT) |	\
+	 (size))
+
+struct fit_type_map_t {
+	unsigned char	type;
+	const char	*name;
+};
+
+static const struct fit_type_map_t fit_entry_types[] = {
+	{ FIT_ENTRY_FIT_HEADER, "FIT Header" },
+	{ FIT_ENTRY_PAL_A_GEN,  "Generic PAL_A" },
+	{ FIT_ENTRY_PAL_A_PROC, "Processor-specific PAL_A" },
+	{ FIT_ENTRY_PAL_A,      "PAL_A" },
+	{ FIT_ENTRY_PAL_B,      "PAL_B" },
+	{ FIT_ENTRY_SAL_A,      "SAL_A" },
+	{ FIT_ENTRY_SAL_B,      "SAL_B" },
+	{ FIT_ENTRY_SALRUNTIME, "SAL runtime" },
+	{ FIT_ENTRY_EFI,	"EFI" },
+	{ FIT_ENTRY_VMLINUX,    "Embedded Linux" },
+	{ FIT_ENTRY_FPSWA,      "Embedded FPSWA" },
+	{ FIT_ENTRY_UNUSED,     "Unused" },
+	{ 0xff,                 "Error" },
+};
+
+static const char *
+fit_type_name(unsigned char type)
+{
+	struct fit_type_map_t const*mapp;
+
+	for (mapp = fit_entry_types; mapp->type != 0xff; mapp++)
+		if (type == mapp->type)
+			return mapp->name;
+
+	if ((type > FIT_ENTRY_PAL_A) && (type < FIT_ENTRY_UNUSED))
+		return "OEM type";
+	if ((type > FIT_ENTRY_PAL_B) && (type < FIT_ENTRY_PAL_A))
+		return "Reserved";
+
+	return "Unknown type";
+}
+
+/* These two routines read the FIT table directly from the FLASH PROM
+ * on a specific node.  The PROM can only be accessed using aligned 64
+ * bit reads, so we do that and then shift and mask the result to get
+ * at each field.
+ */
+static int
+dump_fit_entry(char *page, unsigned long *fentry)
+{
+	unsigned long q1, q2;
+	unsigned type;
+
+	TRACE();
+
+	q1 = readq(fentry);
+	q2 = readq(fentry + 1);
+	type = FIT_TYPE(q2);
+	return sprintf(page, "%02x %-25s %x.%02x %016lx %u\n",
+		       type,
+		       fit_type_name(type),
+		       FIT_MAJOR(q2), FIT_MINOR(q2),
+		       q1,
+		       /* mult by sixteen to get size in bytes */
+		       (unsigned)q2 * 16);
+}
+
+/* We assume that the fit table will be small enough that we can print
+ * the whole thing into one page.  (This is true for our default 16kB
+ * pages -- each entry is about 60 chars wide when printed.)  I read
+ * somewhere that the maximum size of the FIT is 128 entries, so we're
+ * OK except for 4kB pages (and no one is going to do that on SN
+ * anyway).
+ */
+static int
+dump_fit(char *page, unsigned long *fit)
+{
+	unsigned long qw;
+	int nentries;
+	int fentry;
+	char *p;
+
+	TRACE();
+
+	DPRINTK("dumping fit from %p\n", (void *)fit);
+
+	qw = readq(fit);
+	DPRINTK("FIT signature: %016lx (%.8s)\n", qw, (char *)&qw);
+	if (qw != FIT_SIGNATURE)
+		printk(KERN_WARNING "Unrecognized FIT signature");
+
+	qw = readq(fit + 1);
+	nentries = (unsigned)qw;
+	DPRINTK("number of fit entries: %u\n", nentries);
+	/* check that we won't overflow the page -- see comment above */
+	BUG_ON(nentries * 60 > PAGE_SIZE);
+
+	p = page;
+	for (fentry = 0; fentry < nentries; fentry++)
+		/* each FIT entry is two 64 bit words */
+		p += dump_fit_entry(p, fit + 2 * fentry);
+
+	return p - page;
+}
+
+static int
+dump_version(char *page, unsigned long *fit)
+{
+	int nentries;
+	int fentry;
+	unsigned long qw;
+
+	TRACE();
+
+	nentries = (unsigned)readq(fit + 1);
+	BUG_ON(nentries * 60 > PAGE_SIZE);
+
+	for (fentry = 0; fentry < nentries; fentry++) {
+		qw = readq(fit + 2 * fentry + 1);
+		if (FIT_TYPE(qw) == FIT_ENTRY_SAL_A)
+			return sprintf(page, "%x.%02x\n",
+				       FIT_MAJOR(qw), FIT_MINOR(qw));
+	}
+	return 0;
+}
+
+/* same as in proc_misc.c */
+static int
+proc_calc_metrics(char *page, char **start, off_t off, int count, int *eof,
+		  int len)
+{
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+	return len;
+}
+
+static int
+read_version_entry(char *page, char **start, off_t off, int count, int *eof,
+		   void *data)
+{
+	int len = 0;
+
+	MOD_INC_USE_COUNT;
+	/* data holds the pointer to this node's FIT */
+	len = dump_version(page, (unsigned long *)data);
+	len = proc_calc_metrics(page, start, off, count, eof, len);
+	MOD_DEC_USE_COUNT;
+	return len;
+}
+
+static int
+read_fit_entry(char *page, char **start, off_t off, int count, int *eof,
+	       void *data)
+{
+	int len = 0;
+
+	MOD_INC_USE_COUNT;
+	/* data holds the pointer to this node's FIT */
+	len = dump_fit(page, (unsigned long *)data);
+	len = proc_calc_metrics(page, start, off, count, eof, len);
+	MOD_DEC_USE_COUNT;
+
+	return len;
+}
+
+/* this is a fake FIT that's used on the medusa simulator which
+ * doesn't usually run a complete PROM. 
+ */
+#ifdef CONFIG_IA64_SGI_SN_SIM
+static unsigned long fakefit[] = {
+	/* this is all we need to satisfy the code below */
+	FIT_SIGNATURE,
+	FIT_ENTRY(FIT_ENTRY_FIT_HEADER, 0x02, 0x60, 2),
+	/* dump something arbitrary for
+	 * /proc/sgi_prominfo/nodeX/version */
+	0xbadbeef00fa3ef17ul,
+	FIT_ENTRY(FIT_ENTRY_SAL_A, 0, 0x99, 0x100)
+};	
+#endif
+
+static unsigned long *
+lookup_fit(int nasid)
+{
+	unsigned long *fitp;
+	unsigned long fit_paddr;
+	unsigned long *fit_vaddr;
+
+#ifdef CONFIG_IA64_SGI_SN_SIM
+	if (IS_RUNNING_ON_SIMULATOR())
+		return fakefit;
+#endif
+
+	fitp = (void *)GLOBAL_MMR_ADDR(nasid, LB_PROM_SPACE - 32);
+	DPRINTK("pointer to fit at %p\n", (void *)fitp);
+	fit_paddr = readq(fitp);
+	DPRINTK("fit pointer contains %lx\n", fit_paddr);
+	/* snag just the node-relative offset */
+	fit_paddr &= ~0ul >> (63-35);
+	/* the pointer to the FIT is relative to IA-64 compatibility
+	 * space.  However, the PROM is mapped at a different offset
+	 * in MMR space (both local and global)
+	 */
+	fit_paddr += 0x700000000;
+	fit_vaddr = (void *)GLOBAL_MMR_ADDR(nasid, fit_paddr);
+	DPRINTK("fit at %p\n", (void *)fit_vaddr);
+	return fit_vaddr;
+}
+
+/* module entry points */
+int __init prominfo_init(void);
+void __exit prominfo_exit(void);
+
+module_init(prominfo_init);
+module_exit(prominfo_exit);
+
+static struct proc_dir_entry **proc_entries;
+static struct proc_dir_entry *sgi_prominfo_entry;
+
+#define NODE_NAME_LEN 11
+
+int __init
+prominfo_init(void)
+{
+	struct proc_dir_entry **entp;
+	cnodeid_t cnodeid;
+	nasid_t nasid;
+	char name[NODE_NAME_LEN];
+
+	if (!ia64_platform_is("sn2"))
+		return 0;
+
+	TRACE();
+
+	DPRINTK("running on cpu %d\n", smp_processor_id());
+	DPRINTK("numnodes %d\n", numnodes);
+
+	proc_entries = kmalloc(numnodes * sizeof(struct proc_dir_entry *),
+			       GFP_KERNEL);
+
+	sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL);
+
+	for (cnodeid = 0, entp = proc_entries;
+	     cnodeid < numnodes;
+	     cnodeid++, entp++) {
+		sprintf(name, "node%d", cnodeid);
+		*entp = proc_mkdir(name, sgi_prominfo_entry);
+		nasid = cnodeid_to_nasid(cnodeid);
+		create_proc_read_entry(
+			"fit", 0, *entp, read_fit_entry,
+			lookup_fit(nasid));
+		create_proc_read_entry(
+			"version", 0, *entp, read_version_entry,
+			lookup_fit(nasid));
+	}
+
+	return 0;
+}
+
+void __exit
+prominfo_exit(void)
+{
+	struct proc_dir_entry **entp;
+	unsigned cnodeid;
+	char name[NODE_NAME_LEN];
+
+	TRACE();
+
+	for (cnodeid = 0, entp = proc_entries;
+	     cnodeid < numnodes;
+	     cnodeid++, entp++) {
+		remove_proc_entry("fit", *entp);
+		remove_proc_entry("version", *entp);
+		sprintf(name, "node%d", cnodeid);
+		remove_proc_entry(name, sgi_prominfo_entry);
+	}
+	remove_proc_entry("sgi_prominfo", NULL);
+	kfree(proc_entries);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn2/ptc_deadlock.S linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
--- linux-2.4.21/arch/ia64/sn/kernel/sn2/ptc_deadlock.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/ptc_deadlock.S	2003-08-01 13:31:48.000000000 +0000
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <asm/sn/sn2/shub_mmr.h>
@@ -61,20 +61,22 @@
 	cmp.ne	p6,p0=zeroval,scr2
 (p6)	br.cond.sptk 5b;;
 
-	tbit.nz	p6,p7=scr1,DEADLOCKBIT;;// Test for DEADLOCK
+	tbit.nz	p8,p7=scr1,DEADLOCKBIT;;// Test for DEADLOCK
 	
 (p7)	st8.rel [ptc1]=data1;;		// Now write PTC1.
 
+5:	ld8.acq	scr1=[piowcphy];;	// Wait for PIOs to complete.
+	extr.u	scr2=scr1,WRITECOUNT,7;;// PIO count
+	cmp.ne	p6,p0=zeroval,scr2
+(p6)	br.cond.sptk 5b
+	
+	tbit.nz	p8,p0=scr1,DEADLOCKBIT;;// Test for DEADLOCK
+
 	mov psr.l=psrsave;;		// Reenable IC
 	srlz.i;;
 	////////////// END   PHYSICAL MODE ////////////////////
 
-(p6)	br.cond.spnt 1b;;		// Repeat if DEADLOCK occurred.
+(p8)	br.cond.spnt 1b;;		// Repeat if DEADLOCK occurred.
 
-5:	ld8.acq	scr1=[piowc];;		// Wait for PIOs to complete.
-	extr.u	scr2=scr1,WRITECOUNT,7;;// PIO count
-	cmp.ne	p6,p0=zeroval,scr2
-(p6)	br.cond.sptk 5b
-	
 	br.ret.sptk	rp
 	.endp sn2_ptc_deadlock_recovery_core
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn2/sn2_smp.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/sn2_smp.c
--- linux-2.4.21/arch/ia64/sn/kernel/sn2/sn2_smp.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/sn2_smp.c	2003-08-01 13:30:56.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * SN2 Platform specific SMP Support
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -79,296 +79,6 @@
 	return ws;
 }
 
-static long use_tlb_hack;
-static volatile unsigned long zz[1024] __attribute__((__aligned__(128)));
-static inline long
-get_itc(void)
-{
-        long ret;                                                                                                           
-        __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(ret));
-        return ret+1;
-}                                                                                                                           
-
-
-
-#ifdef PTCG_WAR
-/*
- * The following structure is used to pass params thru smp_call_function
- * to other cpus for flushing TLB ranges.
- */
-typedef struct {
-	unsigned long	start;
-	unsigned long	end;
-	unsigned long	nbits;
-	unsigned int	rid;
-	atomic_t	unfinished_count;
-	char		fill[96];
-} ptc_params_t;
-
-#define NUMPTC	512
-
-static ptc_params_t	ptcParamArray[NUMPTC] __attribute__((__aligned__(128)));
-
-/* use separate cache lines on ptcParamsNextByCpu to avoid false sharing */
-static ptc_params_t	*ptcParamsNextByCpu[NR_CPUS*16] __attribute__((__aligned__(128)));
-static volatile ptc_params_t	*ptcParamsEmpty __cacheline_aligned;
-
-/*REFERENCED*/
-static spinlock_t ptcParamsLock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
-
-static int ptcInit = 0;
-#ifdef PTCDEBUG
-static int ptcParamsAllBusy = 0;		/* debugging/statistics */
-static int ptcCountBacklog = 0;
-static int ptcBacklog[NUMPTC+1];
-static char ptcParamsCounts[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-static char ptcParamsResults[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-#endif
-
-/*
- * Make smp_send_flush_tlbsmp_send_flush_tlb() a weak reference,
- * so that we get a clean compile with the ia64 patch without the
- * actual SN1 specific code in arch/ia64/kernel/smp.c.
- */
-extern void smp_send_flush_tlb (void) __attribute((weak));
-
-
-/**
- * sn1_ptc_l_range - purge local translation cache
- * @start: start of virtual address range
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Purges the range specified from the local processor's translation cache
- * (as opposed to the translation registers).  Note that more than the specified
- * range *may* be cleared from the cache by some processors.
- *
- * This is probably not good enough, but I don't want to try to make it better 
- * until I get some statistics on a running system. At a minimum, we should only 
- * send IPIs to 1 processor in each TLB domain & have it issue a ptc.g on it's 
- * own FSB. Also, we only have to serialize per FSB, not globally.
- *
- * More likely, we will have to do some work to reduce the frequency of calls to
- * this routine.
- */
-static inline void
-sn1_ptc_l_range(unsigned long start, unsigned long end, unsigned long nbits)
-{
-	do {
-		__asm__ __volatile__ ("ptc.l %0,%1" :: "r"(start), "r"(nbits<<2) : "memory");
-		start += (1UL << nbits);
-	} while (start < end);
-	ia64_srlz_d();
-}
-
-/**
- * sn1_received_flush_tlb - cpu tlb flush routine
- *
- * Flushes the TLB of a given processor.
- */
-void
-sn1_received_flush_tlb(void)
-{
-	unsigned long	start, end, nbits;
-	unsigned int	rid, saved_rid;
-	int		cpu = smp_processor_id();
-	int		result;
-	ptc_params_t	*ptcParams;
-
-	ptcParams = ptcParamsNextByCpu[cpu*16];
-	if (ptcParams == ptcParamsEmpty)
-		return;
-
-	do {
-		start = ptcParams->start;
-		saved_rid = (unsigned int) ia64_get_rr(start);
-		end = ptcParams->end;
-		nbits = ptcParams->nbits;
-		rid = ptcParams->rid;
-
-		if (saved_rid != rid) {
-			ia64_set_rr(start, (unsigned long)rid);
-			ia64_srlz_d();
-		}
-
-		sn1_ptc_l_range(start, end, nbits);
-
-		if (saved_rid != rid) 
-			ia64_set_rr(start, (unsigned long)saved_rid);
-
-		ia64_srlz_i();
-
-		result = atomic_dec(&ptcParams->unfinished_count);
-#ifdef PTCDEBUG
-		{
-		    int i = ptcParams-&ptcParamArray[0];
-		    ptcParamsResults[cpu][i] = (char) result;
-		    ptcParamsCounts[cpu][i]++;
-		}
-#endif /* PTCDEBUG */
-
-		if (++ptcParams == &ptcParamArray[NUMPTC])
-			ptcParams = &ptcParamArray[0];
-
-	} while (ptcParams != ptcParamsEmpty);
-
-	ptcParamsNextByCpu[cpu*16] = ptcParams;
-}
-
-/**
- * sn1_global_tlb_purge - flush a translation cache range on all processors
- * @start: start of virtual address range to flush
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Flushes the translation cache of all processors from @start to @end.
- */
-void
-sn1_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
-{
-	ptc_params_t	*params;
-	ptc_params_t	*next;
-	unsigned long	irqflags;
-#ifdef PTCDEBUG
-	ptc_params_t	*nextnext;
-	int		backlog = 0;
-#endif
-
-	if (smp_num_cpus == 1) {
-		sn1_ptc_l_range(start, end, nbits);
-		return;
-	}
-
-	if (in_interrupt()) {
-		/*
-		 *  If at interrupt level and cannot get spinlock, 
-		 *  then do something useful by flushing own tlbflush queue
-		 *  so as to avoid a possible deadlock.
-		 */
-		while (!spin_trylock(&ptcParamsLock)) {
-			local_irq_save(irqflags);
-			sn1_received_flush_tlb();
-			local_irq_restore(irqflags);
-			udelay(10);	/* take it easier on the bus */	
-		}
-	} else {
-		spin_lock(&ptcParamsLock);
-	}
-
-	if (!ptcInit) {
-		int cpu;
-		ptcInit = 1;
-		memset(ptcParamArray, 0, sizeof(ptcParamArray));
-		ptcParamsEmpty = &ptcParamArray[0];
-		for (cpu=0; cpu<NR_CPUS; cpu++)
-			ptcParamsNextByCpu[cpu*16] = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
-		memset(ptcBacklog, 0, sizeof(ptcBacklog));
-		memset(ptcParamsCounts, 0, sizeof(ptcParamsCounts));
-		memset(ptcParamsResults, 0, sizeof(ptcParamsResults));
-#endif	/* PTCDEBUG */
-	}
-
-	params = (ptc_params_t *) ptcParamsEmpty;
-	next = (ptc_params_t *) ptcParamsEmpty + 1;
-	if (next == &ptcParamArray[NUMPTC])
-		next = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
-	nextnext = next + 1;
-	if (nextnext == &ptcParamArray[NUMPTC])
-		nextnext = &ptcParamArray[0];
-
-	if (ptcCountBacklog) {
-		/* quick count of backlog */
-		ptc_params_t *ptr;
-
-		/* check the current pointer to the beginning */
-		ptr = params;
-		while(--ptr >= &ptcParamArray[0]) {
-			if (atomic_read(&ptr->unfinished_count) == 0)
-				break;
-			++backlog;
-		}
-
-		if (backlog) {
-			/* check the end of the array */
-			ptr = &ptcParamArray[NUMPTC];
-			while (--ptr > params) {
-				if (atomic_read(&ptr->unfinished_count) == 0)
-					break;
-				++backlog;
-			}
-		}
-		ptcBacklog[backlog]++;
-	}
-#endif	/* PTCDEBUG */
-
-	/* wait for the next entry to clear...should be rare */
-	if (atomic_read(&next->unfinished_count) > 0) {
-#ifdef PTCDEBUG
-		ptcParamsAllBusy++;
-
-		if (atomic_read(&nextnext->unfinished_count) == 0) {
-		    if (atomic_read(&next->unfinished_count) > 0) {
-			panic("\nnonzero next zero nextnext %lx %lx\n",
-			    (long)next, (long)nextnext);
-		    }
-		}
-#endif
-
-		/* it could be this cpu that is behind */
-		local_irq_save(irqflags);
-		sn1_received_flush_tlb();
-		local_irq_restore(irqflags);
-
-		/* now we know it's not this cpu, so just wait */
-		while (atomic_read(&next->unfinished_count) > 0) {
-			barrier();
-		}
-	}
-
-	params->start = start;
-	params->end = end;
-	params->nbits = nbits;
-	params->rid = (unsigned int) ia64_get_rr(start);
-	atomic_set(&params->unfinished_count, smp_num_cpus);
-
-	/* The atomic_set above can hit memory *after* the update
-	 * to ptcParamsEmpty below, which opens a timing window
-	 * that other cpus can squeeze into!
-	 */
-	mb();
-
-	/* everything is ready to process:
-	 *	-- global lock is held
-	 *	-- new entry + 1 is free
-	 *	-- new entry is set up
-	 * so now:
-	 *	-- update the global next pointer
-	 *	-- unlock the global lock
-	 *	-- send IPI to notify other cpus
-	 *	-- process the data ourselves
-	 */
-	ptcParamsEmpty = next;
-	spin_unlock(&ptcParamsLock);
-	smp_send_flush_tlb();
-
-	local_irq_save(irqflags);
-	sn1_received_flush_tlb();
-	local_irq_restore(irqflags);
-
-	/* 
-	 * Since IPIs are polled event (for now), we need to wait til the
-	 * TLB flush has started.
-	 * wait for the flush to complete 
-	 */ 
-	while (atomic_read(&params->unfinished_count) > 0)
-		barrier();
-}
-
-#endif /* PTCG_WAR */
 
 
 /**
@@ -384,19 +94,10 @@
 void
 sn2_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
 {
-	int			cnode, mycnode, nasid;
+	int			cnode, mycnode, nasid, flushed=0;
 	volatile unsigned	long	*ptc0, *ptc1;
 	unsigned long		flags=0, data0, data1;
-	long 		        zzbase, zztime, zztime2;
 
-	/*
-	 * Special case 1 cpu & 1 node. Use local purges.
-	 */
-#ifdef PTCG_WAR
-	sn1_global_tlb_purge(start, end, nbits);
-	return;
-#endif /* PTCG_WAR */
-		
 	data0 = (1UL<<SH_PTC_0_A_SHFT) |
 		(nbits<<SH_PTC_0_PS_SHFT) |
 		((ia64_get_rr(start)>>8)<<SH_PTC_0_RID_SHFT) |
@@ -405,20 +106,9 @@
 	ptc0 = (long*)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_0);
 	ptc1 = (long*)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_1);
 
-	mycnode = local_cnodeid();
+	mycnode = numa_node_id();
 
-	/* 
-	 * For now, we dont want to spin uninterruptibly waiting
-	 * for the lock. Makes hangs hard to debug.
-	 */
-	zzbase = smp_processor_id()*16;
-	zz[zzbase+0] += 0x0000ffff00000001UL;
-
-	local_irq_save(flags);
-	zztime = get_itc();     
-	spin_lock(&sn2_global_ptc_lock);
-	zz[zzbase+0] += 0xffff000000000000UL;
-	zztime2 = get_itc();     
+	spin_lock_irqsave(&sn2_global_ptc_lock, flags);
 
 	do {
 		data1 = start | (1UL<<SH_PTC_1_START_SHFT);
@@ -427,16 +117,16 @@
 				continue;
 			if (cnode == mycnode) {
 				asm volatile ("ptc.ga %0,%1;;srlz.i;;" :: "r"(start), "r"(nbits<<2) : "memory");
-			} else {
+			} else if (current->shared_mm || test_bit(cnode, current->node_history)) {
 				nasid = cnodeid_to_nasid(cnode);
 				ptc0 = CHANGE_NASID(nasid, ptc0);
 				ptc1 = CHANGE_NASID(nasid, ptc1);
 				pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, data1);
+				flushed = 1;
 			}
 		}
 
-		if (wait_piowc() & SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK) {
-			zz[zzbase+1]++;
+		if (flushed && (wait_piowc() & SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK)) {
 			sn2_ptc_deadlock_recovery(data0, data1);
 		}
 
@@ -444,20 +134,8 @@
 
 	} while (start < end);
 
-	zz[zzbase+0] -= 0xffffffff00000000UL;   
-	zztime2 = get_itc() - zztime2;    
 	spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
 
-	zztime = get_itc() - zztime;    
-
-	zz[zzbase+6] += zztime;                                                                                             
-	if (zztime > zz[zzbase+7])
-	       zz[zzbase+7] = zztime; 
-
-	zz[zzbase+8] += zztime2;                                                                                             
-	if (zztime2 > zz[zzbase+9])
-	       zz[zzbase+9] = zztime2; 
-
 }
 
 /*
@@ -480,7 +158,7 @@
 	ptc1 = (long*)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_1);
 	piows = (long*)pda.pio_write_status_addr;
 
-	mycnode = local_cnodeid();
+	mycnode = numa_node_id();
 
 	for (cnode = 0; cnode < numnodes; cnode++) {
 		if (is_headless_node(cnode) || cnode == mycnode)
@@ -511,16 +189,10 @@
 void
 sn_send_IPI_phys(long physid, int vector, int delivery_mode)
 {
-	long		nasid, slice;
-	long		val;
+	long		nasid, slice, val;
+	unsigned long	flags=0;
 	volatile long	*p;
 
-#if defined(BUS_INT_WAR) && defined(CONFIG_SHUB_1_0_SPECIFIC)
-	if (vector != ap_wakeup_vector && delivery_mode == IA64_IPI_DM_INT) {
-		return;
-	}
-#endif
-
 	nasid = cpu_physical_id_to_nasid(physid);
         slice = cpu_physical_id_to_slice(physid);
 
@@ -532,12 +204,15 @@
 		(0x000feeUL<<SH_IPI_INT_BASE_SHFT);
 
 	mb();
+	if (enable_shub_wars_1_1() ) {
+		spin_lock_irqsave(&sn2_global_ptc_lock, flags);
+	}
 	pio_phys_write_mmr(p, val);
+	if (enable_shub_wars_1_1() ) {
+		wait_piowc();
+		spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
+	}
 
-#ifndef CONFIG_SHUB_1_0_SPECIFIC
-	/* doesnt work on shub 1.0 */
-	wait_piowc();
-#endif
 }
 
 /**
@@ -565,133 +240,3 @@
 
 	sn_send_IPI_phys(physid, vector, delivery_mode);
 }
-
-
-
-/* ----------------------------------------------------------------------------------------------- */
-
-#include <linux/proc_fs.h>
-
-
-static struct proc_dir_entry *ptcg_stats;
-
-static int
-ptcg_read_proc(char *buffer, char **start, off_t off, int count, int *eof, void *data)
-{
-	long cpu, *p, cnt;
-	int len = 0;
-
-	p = (long*)LOCAL_MMR_ADDR(SH_DIAG_MSG_DATA7L);
-	len += sprintf(buffer + len, "PTCG Stats (option 0x%lx)\n", use_tlb_hack);
-
-	len += sprintf(buffer + len, "%-14s", "CPU");
-	for (cpu=0; cpu<smp_num_cpus; cpu++)
-		len += sprintf(buffer + len, "%10ld", cpu);
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "flushes");
-	for (cpu=0; cpu<smp_num_cpus; cpu++)
-		len += sprintf(buffer + len, "%10ld", zz[cpu*16+0]&0xffffffff);
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "deadlocks");
-	for (cpu=0; cpu<smp_num_cpus; cpu++)
-		len += sprintf(buffer + len, "%10ld", zz[cpu*16+1]);
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "aver-us");
-	for (cpu=0; cpu<smp_num_cpus; cpu++) {
-		cnt = zz[cpu*16+0]&0xffffffff;
-		len += sprintf(buffer + len, "%10ld", cnt ? zz[cpu*16+6]/(cnt)/cpu_data(cpu)->cyc_per_usec : 0);
-	}
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "max-us");
-	for (cpu=0; cpu<smp_num_cpus; cpu++)
-		len += sprintf(buffer + len, "%10ld", zz[cpu*16+7]/cpu_data(cpu)->cyc_per_usec);
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "iaver-us");
-	for (cpu=0; cpu<smp_num_cpus; cpu++) {
-		cnt = zz[cpu*16+0]&0xffffffff;
-		len += sprintf(buffer + len, "%10ld", cnt ? zz[cpu*16+8]/(cnt)/cpu_data(cpu)->cyc_per_usec : 0);
-	}
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "imax-us");
-	for (cpu=0; cpu<smp_num_cpus; cpu++)
-		len += sprintf(buffer + len, "%10ld", zz[cpu*16+9]/cpu_data(cpu)->cyc_per_usec);
-	len += sprintf(buffer + len, "\n");
-
-	len += sprintf(buffer + len, "%-14s", "long-piowc");
-	for (cpu=0; cpu<smp_num_cpus; cpu++)
-		len += sprintf(buffer + len, "%10ld", zz[cpu*16+9]);
-	len += sprintf(buffer + len, "\n");
-
-        len += sprintf(buffer + len, "%-14s", "ipi-rp-error");
-        for (cpu=0; cpu<smp_num_cpus; cpu++) {
-                p = (long*)GLOBAL_MMR_ADDR(cpuid_to_nasid(cpu), SH_XN_IILB_LB_CMP_ENABLE0);
-                len += sprintf(buffer + len, "%10ld", *p);
-        }
-	len += sprintf(buffer + len, "\n");
-
-        len += sprintf(buffer + len, "%-14s", "lb-cb-error");
-        for (cpu=0; cpu<smp_num_cpus; cpu++) {
-                p = (long*)GLOBAL_MMR_ADDR(cpuid_to_nasid(cpu), SH_XN_IILB_LB_CMP_ENABLE1);
-                len += sprintf(buffer + len, "%10ld", *p);
-        }
-        len += sprintf(buffer + len, "\n");
-
-
-	if (len <= off+count) *eof = 1;
-	*start = buffer + off;
-	len   -= off;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-	return len;
-}
-
-
-static int
-ptcg_write_proc (struct file *file, const char *userbuf, unsigned long count, void *data)
-{
-	extern long atoi(char *);
-	char		buf[80];
-	long		val;
-	long		cpu;
-	long		*p;
-
-	if (copy_from_user(buf, userbuf, count < sizeof(buf) ? count : sizeof(buf)))
-		return -EFAULT;
-
-	val = atoi(buf);
-	if (val&4) val |= 1;
-	use_tlb_hack = val;
-
-	memset((void*)zz, 0, sizeof(zz));
-
-	for (cpu=0; cpu<smp_num_cpus; cpu++) {
-		p = (long*)GLOBAL_MMR_ADDR(cpuid_to_nasid(cpu), SH_XN_IILB_LB_CMP_ENABLE0);
-		*p = 0;
-		p = (long*)GLOBAL_MMR_ADDR(cpuid_to_nasid(cpu), SH_XN_IILB_LB_CMP_ENABLE1);
-		*p = 0;
-	}
-	return count;
-}
-
-	
-
-static int
-sn2_ptcg_stats_init(void)
-{
-	if ((ptcg_stats = create_proc_entry("ptcg_stats", 0644, NULL)) == NULL) {
-		printk("unable to create proc entry for ptcg_stats");
-		return -1;
-	}
-	ptcg_stats->read_proc = ptcg_read_proc;
-	ptcg_stats->write_proc = ptcg_write_proc;
-	return 0;
-}
-
-#include <linux/module.h>
-module_init(sn2_ptcg_stats_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn2/sn_proc_fs.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
--- linux-2.4.21/arch/ia64/sn/kernel/sn2/sn_proc_fs.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/sn_proc_fs.c	2003-08-01 13:31:24.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -31,6 +31,7 @@
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 #include <linux/config.h>
+#include <asm/uaccess.h>
 
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
@@ -43,7 +44,7 @@
 	return sprintf(page, "%d\n", sn_local_partid());
 }
 
-struct proc_dir_entry * sgi_proc_dir = NULL;
+static struct proc_dir_entry * sgi_proc_dir;
 
 void
 register_sn_partition_id(void) {
@@ -96,4 +97,99 @@
 	}
 }
 
+// Disable forced interrupts, but leave the code in, just in case.
+int sn_force_interrupt_flag = 0;
+
+static int
+sn_force_interrupt_read_proc(char *page, char **start, off_t off,
+		int count, int *eof, void *data) {
+	if (sn_force_interrupt_flag) {
+		return sprintf(page, "Force interrupt is enabled\n");
+	}
+	return sprintf(page, "Force interrupt is disabled\n");
+}
+
+static int 
+sn_force_interrupt_write_proc(struct file *file, const char *buffer,
+                                        unsigned long count, void *data)
+{
+	if (*buffer == '0') {
+		sn_force_interrupt_flag = 0;
+	} else {
+		sn_force_interrupt_flag = 1;
+	}
+	return 1;
+}
+
+void
+register_sn_force_interrupt(void) {
+	struct proc_dir_entry *entry;
+
+	if (!sgi_proc_dir) {
+		sgi_proc_dir = proc_mkdir("sgi_sn", 0);
+	}
+	entry = create_proc_entry("sn_force_interrupt",0444, sgi_proc_dir);
+	if (entry) {
+		entry->nlink = 1;
+		entry->data = 0;
+		entry->read_proc = sn_force_interrupt_read_proc;
+		entry->write_proc = sn_force_interrupt_write_proc;
+	}
+}
+
+extern int sn_linkstats_get(char *);
+extern int sn_linkstats_reset(unsigned long);
+
+static int
+sn_linkstats_read_proc(char *page, char **start, off_t off,
+		int count, int *eof, void *data) {
+       
+	return sn_linkstats_get(page);
+}
+
+static int 
+sn_linkstats_write_proc(struct file *file, const char *buffer,
+                                        unsigned long count, void *data)
+{
+	char		s[64];
+	unsigned long	msecs;
+	int		e = count;
+
+	if (copy_from_user(s, buffer, count < sizeof(s) ? count : sizeof(s)))
+		e = -EFAULT;
+	else {
+		if (sscanf(s, "%lu", &msecs) != 1 || msecs < 5)
+			/* at least 5 milliseconds between updates */
+			e = -EINVAL;
+		else
+			sn_linkstats_reset(msecs);
+	}
+
+	return e;
+}
+
+void
+register_sn_linkstats(void) {
+	struct proc_dir_entry *entry;
+
+	if (!sgi_proc_dir) {
+		sgi_proc_dir = proc_mkdir("sgi_sn", 0);
+	}
+	entry = create_proc_entry("linkstats", 0444, sgi_proc_dir);
+	if (entry) {
+		entry->nlink = 1;
+		entry->data = 0;
+		entry->read_proc = sn_linkstats_read_proc;
+		entry->write_proc = sn_linkstats_write_proc;
+	}
+}
+
+void
+register_sn_procfs(void) {
+	register_sn_partition_id();
+	register_sn_serial_numbers();
+	register_sn_force_interrupt();
+	register_sn_linkstats();
+}
+
 #endif /* CONFIG_PROC_FS */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn2/timer.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/timer.c
--- linux-2.4.21/arch/ia64/sn/kernel/sn2/timer.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn2/timer.c	2003-08-01 13:31:10.000000000 +0000
@@ -0,0 +1,100 @@
+/*
+ * linux/arch/ia64/sn/kernel/sn2/timer.c
+ *
+ * Copyright (C) 2003 Silicon Graphics, Inc.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+
+#include <asm/hw_irq.h>
+#include <asm/system.h>
+
+#include <asm/sn/leds.h>
+#include <asm/sn/clksupport.h>
+
+
+extern unsigned long sn_rtc_cycles_per_second;
+static volatile unsigned long last_wall_rtc;
+
+/**
+ * gettimeoffset - number of usecs elapsed since &xtime was last updated
+ *
+ * This function is used by do_gettimeofday() to determine the number
+ * of usecs that have elapsed since the last update to &xtime.  On SN
+ * this is accomplished using the RTC built in to each Hub chip; each
+ * is guaranteed to be synchronized by the PROM, so a local read will
+ * suffice (GET_RTC_COUNTER() does this for us).  A snapshot of the RTC
+ * value is taken every time wall_jiffies is updated by the
+ * update_wall_time_hook (sn2_update_wall_time) which means we don't
+ * have to adjust for lost jiffies ticks or anything like that.
+ */
+extern unsigned long wall_jiffies; /* from kernel/timer.c */
+
+static volatile long rtc_offset;
+static long rtc_cycles_per_usec;
+static long rtc_per_timer_tick;
+
+unsigned long
+sn_gettimeoffset(void)
+{
+	long current_rtc, elapsed_rtc, old, new_offset;
+
+	do {
+		old = rtc_offset;
+		current_rtc = GET_RTC_COUNTER();
+
+		/*
+		 * Need to address wrapping here!
+		 */
+		elapsed_rtc = (long)(current_rtc - last_wall_rtc);
+
+		/*
+		 * This case is non lethal as the max() will take care of it.
+		 */
+#if 0
+		if (elapsed_rtc < 0) {
+			printk(KERN_ERR "sn_gettimeoffset(): time goes "
+			       "backwards!\n    current_rtc 0x%016lx, "
+			       "last_wall_rtc 0x%016lx, elapsed %08lx, "
+			       "offset %li\n", current_rtc, last_wall_rtc,
+			       elapsed_rtc, max(elapsed_rtc, rtc_offset)/
+			       rtc_cycles_per_usec);
+		}
+#endif
+
+		new_offset = max(elapsed_rtc, old);
+	} while (cmpxchg(&rtc_offset, old, new_offset) != old);
+
+	return new_offset / rtc_cycles_per_usec;
+}
+
+
+void sn2_update_wall_time(void)
+{
+	rtc_offset -= min(rtc_offset, rtc_per_timer_tick);
+	last_wall_rtc = GET_RTC_COUNTER();
+}
+
+
+void sn2_reset_wall_time(void)
+{
+	rtc_offset = 0;
+	last_wall_rtc = GET_RTC_COUNTER();
+}
+
+
+void __init
+sn_timer_init(void)
+{
+	rtc_per_timer_tick = sn_rtc_cycles_per_second / HZ;
+	rtc_cycles_per_usec = sn_rtc_cycles_per_second / 1000000;
+
+	last_wall_rtc = GET_RTC_COUNTER();
+	update_wall_time_hook = sn2_update_wall_time;
+	reset_wall_time_hook = sn2_reset_wall_time;
+	gettimeoffset = sn_gettimeoffset;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn_asm.S linux-2.4.22-pre10/arch/ia64/sn/kernel/sn_asm.S
--- linux-2.4.21/arch/ia64/sn/kernel/sn_asm.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn_asm.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/config.h>
-#ifdef CONFIG_IA64_SGI_AUTOTEST
-
-// Testing only.
-// Routine will cause MCAs
-//   zzzmca(n)
-//      n=0 MCA via duplicate TLB dropin
-//      n=1 MCA via read of garbage address
-//      n=2 MCA via lfetch read of garbage address
-//
-
-#define ITIR(key, ps)           ((key<<8) | (ps<<2))
-#define TLB_PAGESIZE            28                      // Use 256MB pages for now.
-
-                        .global zzzmca
-                        .proc   zzzmca
-zzzmca:
-                        alloc   loc4       = ar.pfs,2,8,1,0;;
-                        cmp.ne  p6,p0=r32,r0;;
-                        movl    r2=0x2dead
-                        movl    r3=0x3dead
-                        movl    r15=0x15dead
-                        movl    r16=0x16dead
-                        movl    r31=0x31dead
-                        movl    loc0=0x34beef
-                        movl    loc1=0x35beef
-                        movl    loc2=0x36beef
-                        movl    loc3=0x37beef
-                        movl    out0=0x42beef
-
-                        movl    r20=0x32feed;;
-                        mov     ar32=r20
-                        movl    r20=0x36feed;;
-                        mov     ar36=r20
-                        movl    r20=0x65feed;;
-                        mov     ar65=r20
-                        movl    r20=0x66feed;;
-                        mov     ar66=r20
-
-(p6)                    br.cond.sptk    1f
-
-                        rsm      0x2000;;
-                        srlz.d;
-                        mov      r11      = 5
-                        mov      r3       = ITIR(0,TLB_PAGESIZE);;
-                        mov      cr.itir  = r3
-                        mov      r10      = 0;;
-                        itr.d    dtr[r11] = r10;;
-                        mov      r11      = 6
-
-                        itr.d    dtr[r11] = r10;;
-                        br      9f
-
-1:
-			cmp.eq	p6,p7=1,r32
-#ifdef CONFIG_IA64_SGI_SN1
-                        movl    r8=0xe00000fe00000048;;
-#else
-                        movl    r8=0xe0007fb000000048;;
-#endif
-                 (p6)   ld8     r9=[r8]
-                 (p7)   lfetch.fault.nt2  [r8]
-			;;
-                        mf
-			;;
-                        mf.a
-			;;
-                        srlz.d
-
-9:                      mov     ar.pfs=loc4
-                        br.ret.sptk     rp
-
-                        .endp   zzzmca
-
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sn_ksyms.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sn_ksyms.c
--- linux-2.4.21/arch/ia64/sn/kernel/sn_ksyms.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sn_ksyms.c	2003-08-01 13:34:44.000000000 +0000
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -18,8 +18,8 @@
 #include <asm/sn/intr.h>
 
 #include <linux/mm.h>
-#include <linux/devfs_fs_kernel.h>
-extern devfs_handle_t          base_io_scsi_ctlr_vhdl[];
+#include <asm/sn/sgi.h>
+extern vertex_hdl_t          base_io_scsi_ctlr_vhdl[];
 #include <asm/sn/types.h>
 extern cnodeid_t master_node_get(devfs_handle_t vhdl);
 #include <asm/sn/arch.h>
@@ -31,9 +31,9 @@
  * symbols referenced by the PCIBA module
  */
 #include <asm/sn/invent.h>
-#include <asm/sn/hack.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/pci/pciio.h>
+#include <asm/sn/sn_cpuid.h>
 
 devfs_handle_t
 devfn_to_vertex(unsigned char busnum, unsigned int devfn);
@@ -54,29 +54,26 @@
 EXPORT_SYMBOL(sn_send_IPI_phys);
 
 /* symbols referenced by partitioning modules */
-#include <asm/sn/bte_copy.h>
+#include <asm/sn/bte.h>
+EXPORT_SYMBOL(bte_copy);
 EXPORT_SYMBOL(bte_unaligned_copy);
 #include <asm/sal.h>
 EXPORT_SYMBOL(ia64_sal);
+EXPORT_SYMBOL(physical_node_map);
 
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/sn_sal.h>
 EXPORT_SYMBOL(sal_lock);
 EXPORT_SYMBOL(sn_partid);
 EXPORT_SYMBOL(sn_local_partid);
 EXPORT_SYMBOL(sn_system_serial_number_string);
 EXPORT_SYMBOL(sn_partition_serial_number);
-#endif
+
+EXPORT_SYMBOL(sn_mmiob);
 
 /* added by tduffy 04.08.01 to fix depmod issues */
 #include <linux/mmzone.h>
 
-#ifdef BUS_INT_WAR
-extern void sn_add_polled_interrupt(int, int);
-extern void sn_delete_polled_interrupt(int);
-EXPORT_SYMBOL(sn_add_polled_interrupt);
-EXPORT_SYMBOL(sn_delete_polled_interrupt);
-#endif
-
 extern nasid_t master_nasid;
 EXPORT_SYMBOL(master_nasid);
+
+EXPORT_SYMBOL(sn_flush_all_caches);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/kernel/sv.c linux-2.4.22-pre10/arch/ia64/sn/kernel/sv.c
--- linux-2.4.21/arch/ia64/sn/kernel/sv.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/kernel/sv.c	2003-08-01 13:33:30.000000000 +0000
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This implemenation of synchronization variables is heavily based on
  * one done by Steve Lord <lord@sgi.com>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/sn/tools/make_textsym linux-2.4.22-pre10/arch/ia64/sn/tools/make_textsym
--- linux-2.4.21/arch/ia64/sn/tools/make_textsym	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/sn/tools/make_textsym	1970-01-01 00:00:00.000000000 +0000
@@ -1,171 +0,0 @@
-#!/bin/sh
-#
-# Build a textsym file for use in the Arium ITP probe.
-#
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
-#
-
-help() {
-cat <<END
-Build a WinDD "symtxt" file for use with the Arium ECM-30 probe.
-
-	Usage: $0 [<vmlinux file> [<output file>]]
-		If no input file is specified, it defaults to vmlinux.
-		If no output file name is specified, it defaults to "textsym".
-END
-exit 1
-}
-
-err () {
-	echo "ERROR - $*" >&2
-	exit 1
-}
-
-
-OPTS="H"
-while getopts "$OPTS" c ; do
-	case $c in
-		H)  help;;
-		\?) help;;
-	esac
-
-done
-shift `expr $OPTIND - 1`
-
-LINUX=${1:-vmlinux}
-TEXTSYM=${2:-${LINUX}.sym}
-TMPSYM=${2:-${LINUX}.sym.tmp}
-trap "/bin/rm -f $TMPSYM" 0
-
-[ -f $VMLINUX ] || help
-
-$OBJDUMP -t $LINUX | egrep -v '__ks' | sort > $TMPSYM
-SN1=`egrep "dig_setup|Synergy_da_indr" $TMPSYM|wc -l`
-
-# Dataprefix and textprefix correspond to the VGLOBAL_BASE and VPERNODE_BASE.
-# Eventually, these values should be:
-#	dataprefix	ffffffff
-#	textprefix	fffffffe
-# but right now they're still changing, so make them dynamic.
-dataprefix=`awk ' / \.data	/ { print substr($1, 0, 8) ; exit ; }' $TMPSYM`
-textprefix=`awk ' / \.text	/ { print substr($1, 0, 8) ; exit ; }' $TMPSYM`
-
-# pipe everything thru sort
-echo "TEXTSYM V1.0"
-(cat <<END 
-GLOBAL | ${textprefix}00000000 | CODE | VEC_VHPT_Translation_0000
-GLOBAL | ${textprefix}00000400 | CODE | VEC_ITLB_0400
-GLOBAL | ${textprefix}00000800 | CODE | VEC_DTLB_0800
-GLOBAL | ${textprefix}00000c00 | CODE | VEC_Alt_ITLB_0c00
-GLOBAL | ${textprefix}00001000 | CODE | VEC_Alt_DTLB_1000
-GLOBAL | ${textprefix}00001400 | CODE | VEC_Data_nested_TLB_1400
-GLOBAL | ${textprefix}00001800 | CODE | VEC_Instruction_Key_Miss_1800
-GLOBAL | ${textprefix}00001c00 | CODE | VEC_Data_Key_Miss_1c00
-GLOBAL | ${textprefix}00002000 | CODE | VEC_Dirty-bit_2000
-GLOBAL | ${textprefix}00002400 | CODE | VEC_Instruction_Access-bit_2400
-GLOBAL | ${textprefix}00002800 | CODE | VEC_Data_Access-bit_2800
-GLOBAL | ${textprefix}00002c00 | CODE | VEC_Break_instruction_2c00
-GLOBAL | ${textprefix}00003000 | CODE | VEC_External_Interrupt_3000
-GLOBAL | ${textprefix}00003400 | CODE | VEC_Reserved_3400
-GLOBAL | ${textprefix}00003800 | CODE | VEC_Reserved_3800
-GLOBAL | ${textprefix}00003c00 | CODE | VEC_Reserved_3c00
-GLOBAL | ${textprefix}00004000 | CODE | VEC_Reserved_4000
-GLOBAL | ${textprefix}00004400 | CODE | VEC_Reserved_4400
-GLOBAL | ${textprefix}00004800 | CODE | VEC_Reserved_4800
-GLOBAL | ${textprefix}00004c00 | CODE | VEC_Reserved_4c00
-GLOBAL | ${textprefix}00005000 | CODE | VEC_Page_Not_Present_5000
-GLOBAL | ${textprefix}00005100 | CODE | VEC_Key_Permission_5100
-GLOBAL | ${textprefix}00005200 | CODE | VEC_Instruction_Access_Rights_5200
-GLOBAL | ${textprefix}00005300 | CODE | VEC_Data_Access_Rights_5300
-GLOBAL | ${textprefix}00005400 | CODE | VEC_General_Exception_5400
-GLOBAL | ${textprefix}00005500 | CODE | VEC_Disabled_FP-Register_5500
-GLOBAL | ${textprefix}00005600 | CODE | VEC_Nat_Consumption_5600
-GLOBAL | ${textprefix}00005700 | CODE | VEC_Speculation_5700
-GLOBAL | ${textprefix}00005800 | CODE | VEC_Reserved_5800
-GLOBAL | ${textprefix}00005900 | CODE | VEC_Debug_5900
-GLOBAL | ${textprefix}00005a00 | CODE | VEC_Unaligned_Reference_5a00
-GLOBAL | ${textprefix}00005b00 | CODE | VEC_Unsupported_Data_Reference_5b00
-GLOBAL | ${textprefix}00005c00 | CODE | VEC_Floating-Point_Fault_5c00
-GLOBAL | ${textprefix}00005d00 | CODE | VEC_Floating_Point_Trap_5d00
-GLOBAL | ${textprefix}00005e00 | CODE | VEC_Lower_Privilege_Tranfer_Trap_5e00
-GLOBAL | ${textprefix}00005f00 | CODE | VEC_Taken_Branch_Trap_5f00
-GLOBAL | ${textprefix}00006000 | CODE | VEC_Single_Step_Trap_6000
-GLOBAL | ${textprefix}00006100 | CODE | VEC_Reserved_6100
-GLOBAL | ${textprefix}00006200 | CODE | VEC_Reserved_6200
-GLOBAL | ${textprefix}00006300 | CODE | VEC_Reserved_6300
-GLOBAL | ${textprefix}00006400 | CODE | VEC_Reserved_6400
-GLOBAL | ${textprefix}00006500 | CODE | VEC_Reserved_6500
-GLOBAL | ${textprefix}00006600 | CODE | VEC_Reserved_6600
-GLOBAL | ${textprefix}00006700 | CODE | VEC_Reserved_6700
-GLOBAL | ${textprefix}00006800 | CODE | VEC_Reserved_6800
-GLOBAL | ${textprefix}00006900 | CODE | VEC_IA-32_Exeception_6900
-GLOBAL | ${textprefix}00006a00 | CODE | VEC_IA-32_Intercept_6a00
-GLOBAL | ${textprefix}00006b00 | CODE | VEC_IA-32_Interrupt_6b00
-GLOBAL | ${textprefix}00006c00 | CODE | VEC_Reserved_6c00
-GLOBAL | ${textprefix}00006d00 | CODE | VEC_Reserved_6d00
-GLOBAL | ${textprefix}00006e00 | CODE | VEC_Reserved_6e00
-GLOBAL | ${textprefix}00006f00 | CODE | VEC_Reserved_6f00
-GLOBAL | ${textprefix}00007000 | CODE | VEC_Reserved_7000
-GLOBAL | ${textprefix}00007100 | CODE | VEC_Reserved_7100
-GLOBAL | ${textprefix}00007200 | CODE | VEC_Reserved_7200
-GLOBAL | ${textprefix}00007300 | CODE | VEC_Reserved_7300
-GLOBAL | ${textprefix}00007400 | CODE | VEC_Reserved_7400
-GLOBAL | ${textprefix}00007500 | CODE | VEC_Reserved_7500
-GLOBAL | ${textprefix}00007600 | CODE | VEC_Reserved_7600
-GLOBAL | ${textprefix}00007700 | CODE | VEC_Reserved_7700
-GLOBAL | ${textprefix}00007800 | CODE | VEC_Reserved_7800
-GLOBAL | ${textprefix}00007900 | CODE | VEC_Reserved_7900
-GLOBAL | ${textprefix}00007a00 | CODE | VEC_Reserved_7a00
-GLOBAL | ${textprefix}00007b00 | CODE | VEC_Reserved_7b00
-GLOBAL | ${textprefix}00007c00 | CODE | VEC_Reserved_7c00
-GLOBAL | ${textprefix}00007d00 | CODE | VEC_Reserved_7d00
-GLOBAL | ${textprefix}00007e00 | CODE | VEC_Reserved_7e00
-GLOBAL | ${textprefix}00007f00 | CODE | VEC_Reserved_7f00
-END
-
-
-awk '
-/__start_gate_section/ {start=1}
-/^'${dataprefix}\|${textprefix}'/ {
-	if ($4 == ".kdb")
-		next
-	if (start && substr($NF,1,1) != "0") {
-		type = substr($0,26,5)
-		if (type == ".text")
-			printf "GLOBAL | %s | CODE | %s\n", $1, $NF
-		else {
-			n = 0
-			s = $(NF-1)
-			while (length(s) > 0) {
-				n = n*16 + substr(s,1,1)
-				s = substr(s,2)
-			}
-			printf "GLOBAL | %s | DATA | %s | %d\n", $1, $NF, n
-		}
-	}
-	if($NF == "_end") 
-		exit
-
-}
-' $TMPSYM ) | egrep -v " __device| __vendor" | awk -v sn1="$SN1" '
-/GLOBAL/ {
-	print $0
-	if (sn1 != 0) {
-		/* 32 bits of sn1 physical addrs, */
-		print substr($0,1,9) "04" substr($0,20,16) "Phy_" substr($0,36)
-	} else {
-		/* 38 bits of sn2 physical addrs, need addr space bits */
-		print substr($0,1,9) "3004" substr($0,20,16) "Phy_" substr($0,36)
-	}
-
-} ' | sort -k3
-
-N=`wc -l $TEXTSYM|awk '{print $1}'`
-echo "Generated TEXTSYM file" >&2
-echo "  $LINUX --> $TEXTSYM" >&2
-echo "  Found $N symbols" >&2
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/tools/print_offsets.c linux-2.4.22-pre10/arch/ia64/tools/print_offsets.c
--- linux-2.4.21/arch/ia64/tools/print_offsets.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/tools/print_offsets.c	2003-08-01 13:34:31.000000000 +0000
@@ -10,7 +10,7 @@
  * gets translated into an assembly file which, in turn, is processed
  * by awk to generate offsets.h.  So if you make any changes to this
  * file, be sure to verify that the awk procedure still works (see
- * prin_offsets.awk).
+ * print_offsets.awk).
  */
 #include <linux/config.h>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ia64/vmlinux.lds.S linux-2.4.22-pre10/arch/ia64/vmlinux.lds.S
--- linux-2.4.21/arch/ia64/vmlinux.lds.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ia64/vmlinux.lds.S	2003-08-01 13:34:23.000000000 +0000
@@ -27,6 +27,7 @@
 
   _text = .;
   _stext = .;
+
   .text : AT(ADDR(.text) - PAGE_OFFSET)
     {
 	*(.text.ivt)
@@ -47,38 +48,48 @@
 
   /* Exception table */
   . = ALIGN(16);
-  __start___ex_table = .;
   __ex_table : AT(ADDR(__ex_table) - PAGE_OFFSET)
-	{ *(__ex_table) }
-  __stop___ex_table = .;
+	{
+	  __start___ex_table = .;
+	  *(__ex_table)
+	  __stop___ex_table = .;
+	}
 
 #if defined(CONFIG_IA64_GENERIC)
   /* Machine Vector */
   . = ALIGN(16);
-  machvec_start = .;
   .machvec : AT(ADDR(.machvec) - PAGE_OFFSET)
-	{ *(.machvec) }
-  machvec_end = .;
+	{
+	  machvec_start = .;
+	  *(.machvec)
+	  machvec_end = .;
+	}
 #endif
 
-  __start___ksymtab = .;	/* Kernel symbol table */
   __ksymtab : AT(ADDR(__ksymtab) - PAGE_OFFSET)
-	{ *(__ksymtab) }
-  __stop___ksymtab = .;
+	{
+	  __start___ksymtab = .;	/* Kernel symbol table */
+	  *(__ksymtab)
+	  __stop___ksymtab = .;
+	}
 
-  __start___kallsyms = .;	/* All kernel symbols for debugging */
   __kallsyms : AT(ADDR(__kallsyms) - PAGE_OFFSET)
-	{ *(__kallsyms) }
-  __stop___kallsyms = .;
+	{
+	  __start___kallsyms = .;	/* All kernel symbols for debugging */
+	  *(__kallsyms)
+	  __stop___kallsyms = .;
+	}
 
   /* Unwind info & table: */
   . = ALIGN(8);
   .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - PAGE_OFFSET)
 	{ *(.IA_64.unwind_info*) }
-  ia64_unw_start = .;
   .IA_64.unwind : AT(ADDR(.IA_64.unwind) - PAGE_OFFSET)
-	{ *(.IA_64.unwind*) }
-  ia64_unw_end = .;
+	{
+	  ia64_unw_start = .;
+	  *(.IA_64.unwind*)
+	  ia64_unw_end = .;
+	}
 
   .rodata : AT(ADDR(.rodata) - PAGE_OFFSET)
 	{ *(.rodata) *(.rodata.*) }
@@ -97,14 +108,18 @@
   .data.init : AT(ADDR(.data.init) - PAGE_OFFSET)
 	{ *(.data.init) }
    . = ALIGN(16);
-  __setup_start = .;
   .setup.init : AT(ADDR(.setup.init) - PAGE_OFFSET)
-        { *(.setup.init) }
-  __setup_end = .;
-  __initcall_start = .;
+        {
+	  __setup_start = .;
+	  *(.setup.init)
+	  __setup_end = .;
+	}
   .initcall.init : AT(ADDR(.initcall.init) - PAGE_OFFSET)
-        { *(.initcall.init) }
-  __initcall_end = .;
+        {
+	  __initcall_start = .;
+	  *(.initcall.init)
+	  __initcall_end = .;
+	}
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/m68k/apollo/config.c linux-2.4.22-pre10/arch/m68k/apollo/config.c
--- linux-2.4.21/arch/m68k/apollo/config.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/m68k/apollo/config.c	2003-08-01 13:32:22.000000000 +0000
@@ -183,10 +183,6 @@
 	mach_hwclk           = dn_dummy_hwclk; /* */
 	mach_set_clock_mmss  = dn_dummy_set_clock_mmss; /* */
 	mach_process_int     = dn_process_int;
-#ifdef CONFIG_BLK_DEV_FD
-	mach_floppy_init     = dn_dummy_floppy_init;
-	mach_floppy_setup    = dn_dummy_floppy_setup;
-#endif
 	mach_reset	     = dn_dummy_reset;  /* */
 #ifdef CONFIG_DUMMY_CONSOLE
         conswitchp           = &dummy_con;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/m68k/config.in linux-2.4.22-pre10/arch/m68k/config.in
--- linux-2.4.21/arch/m68k/config.in	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/m68k/config.in	2003-08-01 13:34:05.000000000 +0000
@@ -562,4 +562,5 @@
 
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/m68k/kernel/m68k_ksyms.c linux-2.4.22-pre10/arch/m68k/kernel/m68k_ksyms.c
--- linux-2.4.21/arch/m68k/kernel/m68k_ksyms.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/m68k/kernel/m68k_ksyms.c	2003-08-01 13:34:25.000000000 +0000
@@ -44,7 +44,6 @@
 EXPORT_SYMBOL(mm_ptov);
 EXPORT_SYMBOL(mm_end_of_chunk);
 #endif /* !CONFIG_SINGLE_MEMORY_CHUNK */
-EXPORT_SYMBOL(mm_vtop_fallback);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
 EXPORT_SYMBOL(kernel_set_cachemode);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/m68k/mac/config.c linux-2.4.22-pre10/arch/m68k/mac/config.c
--- linux-2.4.21/arch/m68k/mac/config.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/m68k/mac/config.c	2003-08-01 13:33:00.000000000 +0000
@@ -91,7 +91,7 @@
 extern void mackbd_leds(unsigned int leds);
 extern int mackbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode);
 
-extern void mac_hid_init_hw(void);
+extern void __init mac_hid_init_hw(void);
 extern int mac_hid_kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode);
 
 #ifdef CONFIG_MAGIC_SYSRQ
@@ -202,6 +202,14 @@
 	restore_flags(cpu_flags);
 }
 
+#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID)
+static int __init mac_keyb_init(void)
+{
+	mac_hid_init_hw();
+	return 0;
+}
+#endif
+
 void __init config_mac(void)
 {
 	if (!MACH_IS_MAC) {
@@ -210,7 +218,7 @@
 
 #ifdef CONFIG_VT
 #ifdef CONFIG_INPUT_ADBHID
-	mach_keyb_init       = mac_hid_init_hw;
+	mach_keyb_init       = mac_keyb_init;
 	mach_kbd_translate   = mac_hid_kbd_translate;
 #ifdef CONFIG_MAGIC_SYSRQ
 #ifdef CONFIG_MAC_ADBKEYCODES
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/m68k/mm/memory.c linux-2.4.22-pre10/arch/m68k/mm/memory.c
--- linux-2.4.21/arch/m68k/mm/memory.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/m68k/mm/memory.c	2003-08-01 13:33:55.000000000 +0000
@@ -196,34 +196,6 @@
 	return 0;
 }
 
-static unsigned long transp_transl_matches( unsigned long regval,
-					    unsigned long vaddr )
-{
-    unsigned long base, mask;
-
-    /* enabled? */
-    if (!(regval & 0x8000))
-	return( 0 );
-
-    if (CPU_IS_030) {
-	/* function code match? */
-	base = (regval >> 4) & 7;
-	mask = ~(regval & 7);
-	if (((SUPER_DATA ^ base) & mask) != 0)
-	    return 0;
-    }
-    else {
-	/* must not be user-only */
-	if ((regval & 0x6000) == 0)
-	    return( 0 );
-    }
-
-    /* address match? */
-    base = regval & 0xff000000;
-    mask = ~(regval << 8) & 0xff000000;
-    return (((unsigned long)vaddr ^ base) & mask) == 0;
-}
-
 #if DEBUG_INVALID_PTOV
 int mm_inv_cnt = 5;
 #endif
@@ -253,134 +225,9 @@
 	if (voff == 0)
 		return m68k_memory[i-1].addr + m68k_memory[i-1].size;
 
-	return mm_vtop_fallback(vaddr);
-}
-#endif
-
-/* Separate function to make the common case faster (needs to save less
-   registers) */
-unsigned long mm_vtop_fallback(unsigned long vaddr)
-{
-	/* not in one of the memory chunks; test for applying transparent
-	 * translation */
-
-	if (CPU_IS_030) {
-	    unsigned long ttreg;
-	    
-	    asm volatile( ".chip 68030\n\t"
-			  "pmove %/tt0,%0@\n\t"
-			  ".chip 68k"
-			  : : "a" (&ttreg) );
-	    if (transp_transl_matches( ttreg, vaddr ))
-		return (unsigned long)vaddr;
-	    asm volatile( ".chip 68030\n\t"
-			  "pmove %/tt1,%0@\n\t"
-			  ".chip 68k"
-			  : : "a" (&ttreg) );
-	    if (transp_transl_matches( ttreg, vaddr ))
-		return (unsigned long)vaddr;
-	}
-	else if (CPU_IS_040_OR_060) {
-	    unsigned long ttreg;
-	    
-	    asm volatile( ".chip 68040\n\t"
-			  "movec %%dtt0,%0\n\t"
-			  ".chip 68k"
-			  : "=d" (ttreg) );
-	    if (transp_transl_matches( ttreg, vaddr ))
-		return (unsigned long)vaddr;
-	    asm volatile( ".chip 68040\n\t"
-			  "movec %%dtt1,%0\n\t"
-			  ".chip 68k"
-			  : "=d" (ttreg) );
-	    if (transp_transl_matches( ttreg, vaddr ))
-		return (unsigned long)vaddr;
-	}
-
-	/* no match, too, so get the actual physical address from the MMU. */
-
-	if (CPU_IS_060) {
-	  mm_segment_t fs = get_fs();
-	  unsigned long  paddr;
-
-	  set_fs (MAKE_MM_SEG(SUPER_DATA));
-
-	  /* The PLPAR instruction causes an access error if the translation
-	   * is not possible. To catch this we use the same exception mechanism
-	   * as for user space accesses in <asm/uaccess.h>. */
-	  asm volatile (".chip 68060\n"
-			"1: plpar (%0)\n"
-			".chip 68k\n"
-			"2:\n"
-			".section .fixup,\"ax\"\n"
-			"   .even\n"
-			"3: lea -1,%0\n"
-			"   jra 2b\n"
-			".previous\n"
-			".section __ex_table,\"a\"\n"
-			"   .align 4\n"
-			"   .long 1b,3b\n"
-			".previous"
-			: "=a" (paddr)
-			: "0" (vaddr));
-	  set_fs (fs);
-
-	  return paddr;
-
-	} else if (CPU_IS_040) {
-	  unsigned long mmusr;
-	  mm_segment_t fs = get_fs();
-
-	  set_fs (MAKE_MM_SEG(SUPER_DATA));
-
-	  asm volatile (".chip 68040\n\t"
-			"ptestr (%1)\n\t"
-			"movec %%mmusr, %0\n\t"
-			".chip 68k"
-			: "=r" (mmusr)
-			: "a" (vaddr));
-	  set_fs (fs);
-
-	  if (mmusr & MMU_T_040) {
-	    return (unsigned long)vaddr;	/* Transparent translation */
-	  }
-	  if (mmusr & MMU_R_040)
-	    return (mmusr & PAGE_MASK) | ((unsigned long)vaddr & (PAGE_SIZE-1));
-
-	  printk("VTOP040: bad virtual address %lx (%lx)", vaddr, mmusr);
-	  return -1;
-	} else {
-	  volatile unsigned short temp;
-	  unsigned short mmusr;
-	  unsigned long *descaddr;
-
-	  asm volatile ("ptestr #5,%2@,#7,%0\n\t"
-			"pmove %/psr,%1@"
-			: "=a&" (descaddr)
-			: "a" (&temp), "a" (vaddr));
-	  mmusr = temp;
-
-	  if (mmusr & (MMU_I|MMU_B|MMU_L))
-	    printk("VTOP030: bad virtual address %lx (%x)\n", vaddr, mmusr);
-
-	  descaddr = phys_to_virt((unsigned long)descaddr);
-
-	  switch (mmusr & MMU_NUM) {
-	  case 1:
-	    return (*descaddr & 0xfe000000) | ((unsigned long)vaddr & 0x01ffffff);
-	  case 2:
-	    return (*descaddr & 0xfffc0000) | ((unsigned long)vaddr & 0x0003ffff);
-	  case 3:
-	    return (*descaddr & PAGE_MASK) | ((unsigned long)vaddr & (PAGE_SIZE-1));
-	  default:
-	    printk("VTOP: bad levels (%u) for virtual address %lx\n", 
-		   mmusr & MMU_NUM, vaddr);
-	  }
-	}
-
-	printk("VTOP: bad virtual address %lx\n", vaddr);
 	return -1;
 }
+#endif
 
 #ifndef CONFIG_SINGLE_MEMORY_CHUNK
 unsigned long mm_ptov (unsigned long paddr)
@@ -406,29 +253,6 @@
 			paddr, __builtin_return_address(0));
 	}
 #endif
-	/*
-	 * assume that the kernel virtual address is the same as the
-	 * physical address.
-	 *
-	 * This should be reasonable in most situations:
-	 *  1) They shouldn't be dereferencing the virtual address
-	 *     unless they are sure that it is valid from kernel space.
-	 *  2) The only usage I see so far is converting a page table
-	 *     reference to some non-FASTMEM address space when freeing
-         *     mmaped "/dev/mem" pages.  These addresses are just passed
-	 *     to "free_page", which ignores addresses that aren't in
-	 *     the memory list anyway.
-	 *
-	 */
-
-#ifdef CONFIG_AMIGA
-	/*
-	 * if on an amiga and address is in first 16M, move it 
-	 * to the ZTWO_VADDR range
-	 */
-	if (MACH_IS_AMIGA && paddr < 16*1024*1024)
-		return ZTWO_VADDR(paddr);
-#endif
 	return -1;
 }
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/m68k/mm/motorola.c linux-2.4.22-pre10/arch/m68k/mm/motorola.c
--- linux-2.4.21/arch/m68k/mm/motorola.c	2001-04-06 17:42:48.000000000 +0000
+++ linux-2.4.22-pre10/arch/m68k/mm/motorola.c	2003-08-01 13:33:40.000000000 +0000
@@ -226,18 +226,6 @@
 		for (i = 0; i < 16; i++)
 			pgprot_val(protection_map[i]) |= _PAGE_CACHE040;
 	}
-	/* Fix the PAGE_NONE value. */
-	if (CPU_IS_040_OR_060) {
-		/* On the 680[46]0 we can use the _PAGE_SUPER bit.  */
-		pgprot_val(protection_map[0]) |= _PAGE_SUPER;
-		pgprot_val(protection_map[VM_SHARED]) |= _PAGE_SUPER;
-	} else {
-		/* Otherwise we must fake it. */
-		pgprot_val(protection_map[0]) &= ~_PAGE_PRESENT;
-		pgprot_val(protection_map[0]) |= _PAGE_FAKE_SUPER;
-		pgprot_val(protection_map[VM_SHARED]) &= ~_PAGE_PRESENT;
-		pgprot_val(protection_map[VM_SHARED]) |= _PAGE_FAKE_SUPER;
-	}
 
 	/*
 	 * Map the physical memory available into the kernel virtual
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/mips/config-shared.in linux-2.4.22-pre10/arch/mips/config-shared.in
--- linux-2.4.21/arch/mips/config-shared.in	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/mips/config-shared.in	2003-08-01 13:33:30.000000000 +0000
@@ -686,7 +686,7 @@
    bool 'Network device support' CONFIG_NETDEVICES
    if [ "$CONFIG_NETDEVICES" = "y" ]; then
       source drivers/net/Config.in
-      if [ "$CONFIG_ATM" = "y" ]; then
+      if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
 	 source drivers/atm/Config.in
       fi
    fi
@@ -800,4 +800,5 @@
 fi
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/mips/kernel/sysmips.c linux-2.4.22-pre10/arch/mips/kernel/sysmips.c
--- linux-2.4.21/arch/mips/kernel/sysmips.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/mips/kernel/sysmips.c	2003-08-01 13:32:02.000000000 +0000
@@ -65,7 +65,7 @@
 			return -EFAULT;
 
 		down_write(&uts_sem);
-		strncpy(system_utsname.nodename, name, len);
+		strncpy(system_utsname.nodename, nodename, len);
 		system_utsname.nodename[len] = '\0';
 		up_write(&uts_sem);
 		return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/mips64/kernel/syscall.c linux-2.4.22-pre10/arch/mips64/kernel/syscall.c
--- linux-2.4.21/arch/mips64/kernel/syscall.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/mips64/kernel/syscall.c	2003-08-01 13:34:02.000000000 +0000
@@ -207,7 +207,7 @@
 			return -EFAULT;
 
 		down_write(&uts_sem);
-		strncpy(system_utsname.nodename, name, len);
+		strncpy(system_utsname.nodename, nodename, len);
 		system_utsname.nodename[len] = '\0';
 		up_write(&uts_sem);
 		return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/config.in linux-2.4.22-pre10/arch/parisc/config.in
--- linux-2.4.21/arch/parisc/config.in	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/config.in	2003-08-01 13:34:53.000000000 +0000
@@ -136,7 +136,7 @@
 
    if [ "$CONFIG_NETDEVICES" = "y" ]; then
       source drivers/net/Config.in
-      if [ "$CONFIG_ATM" = "y" ]; then
+      if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
          source drivers/atm/Config.in
       fi
    fi
@@ -196,4 +196,5 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/defpalo.conf linux-2.4.22-pre10/arch/parisc/defpalo.conf
--- linux-2.4.21/arch/parisc/defpalo.conf	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/defpalo.conf	2003-08-01 13:31:10.000000000 +0000
@@ -0,0 +1,21 @@
+# This a generic Palo configuration file.  For more information about how
+# it works try 'palo -?'.
+#
+# Most people using 'make palo' want a bootable file, usable for
+# network or tape booting for example.
+--init-tape=lifimage
+--recoverykernel=vmlinux
+
+########## Pick your ROOT here! ##########
+# You need at least one 'root='!
+#
+# If you want a root ramdisk, use the next 2 lines
+#   (Edit the ramdisk image name!!!!)
+--ramdisk=ram-disk-image-file
+--commandline=0/vmlinux HOME=/ root=/dev/ram initrd=0/ramdisk
+
+# If you want NFS root, use the following command line (Edit the HOSTNAME!!!)
+#--commandline=0/vmlinux HOME=/ root=/dev/nfs nfsroot=HOSTNAME ip=bootp
+
+# If you have root on a disk partition, use this (Edit the partition name!!!)
+#--commandline=0/vmlinux HOME=/ root=/dev/sda1
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/cache.c linux-2.4.22-pre10/arch/parisc/kernel/cache.c
--- linux-2.4.21/arch/parisc/kernel/cache.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/cache.c	2003-08-01 13:33:02.000000000 +0000
@@ -194,31 +194,69 @@
 
 void disable_sr_hashing(void)
 {
-    int srhash_type;
+	int srhash_type;
 
-    if (boot_cpu_data.cpu_type == pcxl2)
-	return; /* pcxl2 doesn't support space register hashing */
+	switch (boot_cpu_data.cpu_type) {
+	case pcx: /* We shouldn't get this far.  setup.c should prevent it. */
+		BUG();
+		return;
+
+	case pcxs:
+	case pcxt:
+	case pcxt_:
+		srhash_type = SRHASH_PCXST;
+		break;
+
+	case pcxl:
+		srhash_type = SRHASH_PCXL;
+		break;
+
+	case pcxl2: /* pcxl2 doesn't support space register hashing */
+		return;
+
+	default: /* Currently all PA2.0 machines use the same ins. sequence */
+		srhash_type = SRHASH_PA20;
+		break;
+	}
 
-    switch (boot_cpu_data.cpu_type) {
-
-    case pcx:
-	BUG(); /* We shouldn't get here. code in setup.c should prevent it */
-	return;
+	disable_sr_hashing_asm(srhash_type);
+}
 
-    case pcxs:
-    case pcxt:
-    case pcxt_:
-	srhash_type = SRHASH_PCXST;
-	break;
+void __flush_dcache_page(struct page *page)
+{
+	struct mm_struct *mm = current->active_mm;
+	struct vm_area_struct *mpnt;
 
-    case pcxl:
-	srhash_type = SRHASH_PCXL;
-	break;
+	flush_kernel_dcache_page(page_address(page));
 
-    default: /* Currently all PA2.0 machines use the same ins. sequence */
-	srhash_type = SRHASH_PA20;
-	break;
-    }
+	if (!page->mapping)
+		return;
 
-    disable_sr_hashing_asm(srhash_type);
+	for (mpnt = page->mapping->i_mmap_shared;
+	     mpnt != NULL;
+	     mpnt = mpnt->vm_next_share)
+	{
+		unsigned long off;
+
+		/*
+		 * If this VMA is not in our MM, we can ignore it.
+		 */
+		if (mpnt->vm_mm != mm)
+			continue;
+
+		if (page->index < mpnt->vm_pgoff)
+			continue;
+
+		off = page->index - mpnt->vm_pgoff;
+		if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT)
+			continue;
+
+		flush_cache_page(mpnt, mpnt->vm_start + (off << PAGE_SHIFT));
+
+		/* All user shared mappings should be equivalently mapped,
+		 * so once we've flushed one we should be ok
+		 */
+		break;
+	}
 }
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/ccio-dma.c linux-2.4.22-pre10/arch/parisc/kernel/ccio-dma.c
--- linux-2.4.21/arch/parisc/kernel/ccio-dma.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/ccio-dma.c	2003-08-01 13:31:33.000000000 +0000
@@ -805,7 +805,7 @@
 
 		DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n", nents,
 			   (unsigned long)sg_dma_address(startsg), cnt,
-			   startsg->address, startsg->length
+			   sg_virt_addr(startsg), startsg->length
 		);
 
 		/*
@@ -825,7 +825,7 @@
 		** Look for a VCONTIG chunk
 		*/
 		if (cnt) {
-			unsigned long vaddr = (unsigned long)startsg->address;
+			unsigned long vaddr = (unsigned long) sg_virt_addr(startsg);
 			ASSERT(pdirp);
 
 			/* Since multiple Vcontig blocks could make up
@@ -878,8 +878,8 @@
 		*/
 		dma_sg = vcontig_sg = startsg;
 		dma_len = vcontig_len = vcontig_end = startsg->length;
-		vcontig_end += (unsigned long) startsg->address;
-		dma_offset = (unsigned long) startsg->address & ~IOVP_MASK;
+		vcontig_end += (unsigned long) sg_virt_addr(startsg);
+		dma_offset = (unsigned long) sg_virt_addr(startsg) & ~IOVP_MASK;
 
 		/* PARANOID: clear entries */
 		sg_dma_address(startsg) = 0;
@@ -893,7 +893,7 @@
 			unsigned long startsg_end;
 
 			startsg++;
-			startsg_end = (unsigned long)startsg->address + 
+			startsg_end = (unsigned long) sg_virt_addr(startsg) + 
 				startsg->length;
 
 			/* PARANOID: clear entries */
@@ -912,7 +912,7 @@
 			/*
 			** Append the next transaction?
 			*/
-			if(vcontig_end == (unsigned long) startsg->address) {
+			if(vcontig_end == (unsigned long) sg_virt_addr(startsg)) {
 				vcontig_len += startsg->length;
 				vcontig_end += startsg->length;
 				dma_len     += startsg->length;
@@ -981,7 +981,8 @@
 
 	/* Fast path single entry scatterlists. */
 	if(nents == 1) {
-		sg_dma_address(sglist)= ccio_map_single(dev, sglist->address,
+		sg_dma_address(sglist)= ccio_map_single(dev,
+							sg_virt_addr(sglist),
 							sglist->length, 
 							direction);
 		sg_dma_len(sglist)= sglist->length;
@@ -1043,7 +1044,7 @@
 	ioc = GET_IOC(dev);
 
 	DBG_RUN_SG("%s() START %d entries,  %p,%x\n",
-		__FUNCTION__, nents, sglist->address, sglist->length);
+		__FUNCTION__, nents, sg_virt_address(sglist), sglist->length);
 
 #ifdef CONFIG_PROC_FS
 	ioc->usg_calls++;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/ccio-rm-dma.c linux-2.4.22-pre10/arch/parisc/kernel/ccio-rm-dma.c
--- linux-2.4.21/arch/parisc/kernel/ccio-rm-dma.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/ccio-rm-dma.c	2003-08-01 13:31:55.000000000 +0000
@@ -118,7 +118,7 @@
 
         /* KISS: map each buffer seperately. */
 	while (nents) {
-		sg_dma_address(sglist) = ccio_map_single(dev, sglist->address, sglist->length, direction);
+		sg_dma_address(sglist) = ccio_map_single(dev, sg_virt_addr(sglist), sglist->length, direction);
 		sg_dma_len(sglist) = sglist->length;
 		nents--;
 		sglist++;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/drivers.c linux-2.4.22-pre10/arch/parisc/kernel/drivers.c
--- linux-2.4.21/arch/parisc/kernel/drivers.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/drivers.c	2003-08-01 13:32:25.000000000 +0000
@@ -9,6 +9,7 @@
  * Copyright (c) 1999 The Puffin Group
  * Copyright (c) 2001 Matthew Wilcox for Hewlett Packard
  * Copyright (c) 2001 Helge Deller <deller@gmx.de>
+ * Copyright (c) 2001,2002 Ryan Bradetich 
  * 
  * The file handles registering devices and drivers, then matching them.
  * It's the closest we get to a dating agency.
@@ -23,7 +24,6 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/pdc.h>
-#include <asm/gsc.h>
 
 /* See comments in include/asm-parisc/pci.h */
 struct pci_dma_ops *hppa_dma_ops;
@@ -416,6 +416,7 @@
 	dev->id.sversion = ((iodc_data[4] & 0x0f) << 16) |
 			(iodc_data[5] << 8) | iodc_data[6];
 	dev->hpa = hpa;
+
 	name = parisc_hardware_description(&dev->id);
 	if (name) {
 		strncpy(dev->name, name, sizeof(dev->name)-1);
@@ -461,30 +462,26 @@
 #define BC_PORT_MASK 0x8
 #define BC_LOWER_PORT 0x8
 
+#define IO_STATUS 	offsetof(struct bc_module, io_status)
+
 
 #define BUS_CONVERTER(dev) \
         ((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT))
 
 #define IS_LOWER_PORT(dev) \
-        ((gsc_readl(&((struct bc_module *)dev->hpa)->io_status) \
-                & BC_PORT_MASK) == BC_LOWER_PORT)
-
-#define READ_IO_IO_LOW(dev) \
-	(dev->id.hw_type == HPHW_IOA ? \
-	        __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_low) << 16 : \
-	        __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_low))
-
-#define READ_IO_IO_HIGH(dev) \
-	(dev->id.hw_type == HPHW_IOA ? \
-	        __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_high) << 16 : \
-	        __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_high))
+        ((__raw_readl(dev->hpa + IO_STATUS) & BC_PORT_MASK) == BC_LOWER_PORT)
 
+#define MAX_NATIVE_DEVICES 64
+#define NATIVE_DEVICE_OFFSET 0x1000
 
-static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high, 
-			    struct parisc_device *parent);
-
-#define FLEX_MASK (unsigned long)0xfffffffffffc0000
+#define FLEX_MASK 	(unsigned long)0xfffffffffffc0000
+#define IO_IO_LOW	offsetof(struct bc_module, io_io_low)
+#define IO_IO_HIGH	offsetof(struct bc_module, io_io_high)
+#define READ_IO_IO_LOW(dev)  (unsigned long)(signed int)__raw_readl(dev->hpa + IO_IO_LOW)
+#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)__raw_readl(dev->hpa + IO_IO_HIGH)
 
+static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
+                            struct parisc_device *parent);
 
 void walk_lower_bus(struct parisc_device *dev)
 {
@@ -493,15 +490,17 @@
 	if(!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev))
 		return;
 
-	io_io_low = ((unsigned long)(signed int)READ_IO_IO_LOW(dev) + ~FLEX_MASK) & FLEX_MASK;
-	io_io_high = ((unsigned long)(signed int)READ_IO_IO_HIGH(dev) + ~FLEX_MASK) & FLEX_MASK;
+	if(dev->id.hw_type == HPHW_IOA) {
+		io_io_low = (unsigned long)(signed int)(READ_IO_IO_LOW(dev) << 16);
+		io_io_high = io_io_low + MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET;
+	} else {
+		io_io_low = (READ_IO_IO_LOW(dev) + ~FLEX_MASK) & FLEX_MASK;
+		io_io_high = (READ_IO_IO_HIGH(dev)+ ~FLEX_MASK) & FLEX_MASK;
+	}
 
 	walk_native_bus(io_io_low, io_io_high, dev);
 }
 
-#define MAX_NATIVE_DEVICES 64
-#define NATIVE_DEVICE_OFFSET 0x1000
-
 /**
  * walk_native_bus -- Probe a bus for devices
  * @io_io_low: Base address of this bus.
@@ -515,7 +514,7 @@
  * keyboard ports).  This problem is not yet solved.
  */
 static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
-			    struct parisc_device *parent)
+                            struct parisc_device *parent)
 {
 	int i, devices_found = 0;
 	unsigned long hpa = io_io_low;
@@ -523,7 +522,7 @@
 
 	get_node_path(parent, &path);
 	do {
-		for (i = 0; i < MAX_NATIVE_DEVICES; i++, hpa += NATIVE_DEVICE_OFFSET) {
+		for(i = 0; i < MAX_NATIVE_DEVICES; i++, hpa += NATIVE_DEVICE_OFFSET) {
 			struct parisc_device *dev;
 
 			/* Was the device already added by Firmware? */
@@ -539,7 +538,7 @@
 			}
 			walk_lower_bus(dev);
 		}
-	} while (!devices_found && hpa < io_io_high);
+	} while(!devices_found && hpa < io_io_high);
 }
 
 #define CENTRAL_BUS_ADDR (unsigned long) 0xfffffffffff80000
@@ -552,7 +551,7 @@
  */
 void walk_central_bus(void)
 {
-	walk_native_bus(CENTRAL_BUS_ADDR, 
+	walk_native_bus(CENTRAL_BUS_ADDR,
 			CENTRAL_BUS_ADDR + (MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET),
 			&root);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/entry.S linux-2.4.22-pre10/arch/parisc/kernel/entry.S
--- linux-2.4.21/arch/parisc/kernel/entry.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/entry.S	2003-08-01 13:31:51.000000000 +0000
@@ -927,11 +927,11 @@
 	ldo		-16(%r30),%r29	/* Reference param save area */
 #endif
 
-	ldil		L%intr_restore, %r2
+	ldil		L%intr_check_sig, %r2
 	copy		%r25, %r16	/* save pt_regs */
 
 	b		handle_interruption
-	ldo		R%intr_restore(%r2), %r2
+	ldo		R%intr_check_sig(%r2), %r2
 
 
 	/*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/hardware.c linux-2.4.22-pre10/arch/parisc/kernel/hardware.c
--- linux-2.4.21/arch/parisc/kernel/hardware.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/hardware.c	2003-08-01 13:32:59.000000000 +0000
@@ -99,8 +99,8 @@
 	{HPHW_NPROC,0x481,0x4,0x81,"Wilbur (E25)"},
 	{HPHW_NPROC,0x482,0x4,0x81,"WB-80 (E35)"},
 	{HPHW_NPROC,0x483,0x4,0x81,"WB-96 (E45)"},
-	{HPHW_NPROC,0x48,0x4,0x81,"UL Proc L-100 (811/D210,D310)"},
-	{HPHW_NPROC,0x48,0x4,0x81,"UL Proc L-75 (801/D200)"},
+	{HPHW_NPROC,0x484,0x4,0x81,"UL Proc L-100 (811/D210,D310)"},
+	{HPHW_NPROC,0x485,0x4,0x81,"UL Proc L-75 (801/D200)"},
 	{HPHW_NPROC,0x501,0x4,0x81,"Merlin L2 132 (9000/778/B132L)"},
 	{HPHW_NPROC,0x502,0x4,0x81,"Merlin L2 160 (9000/778/B160L)"},
 	{HPHW_NPROC,0x503,0x4,0x81,"Merlin L2+ 132 (9000/778/B132L)"},
@@ -403,7 +403,7 @@
 	{HPHW_BA, 0x01B, 0x00078, 0x0, "Anole 100 VME BA"}, 
 	{HPHW_BA, 0x024, 0x00078, 0x0, "Fast Pace VME BA"}, 
 	{HPHW_BA, 0x034, 0x00078, 0x0, "Anole T VME BA"}, 
-	{HPHW_BA, 0x04A, 0x00078, 0x0, "Anole L2 132 BME BA"}, 
+	{HPHW_BA, 0x04A, 0x00078, 0x0, "Anole L2 132 VME BA"}, 
 	{HPHW_BA, 0x04C, 0x00078, 0x0, "Anole L2 165 VME BA"}, 
 	{HPHW_BA, 0x011, 0x00081, 0x0, "WB-96 Core BA"}, 
 	{HPHW_BA, 0x012, 0x00081, 0x0, "Orville UX Core BA"}, 
@@ -805,8 +805,8 @@
 	{HPHW_FIO, 0x04E, 0x0007B, 0x0, "Kiji L2 132 Core Audio"}, 
 	{HPHW_FIO, 0x050, 0x0007B, 0x0, "Merlin Jr 132 Core Audio"}, 
 	{HPHW_FIO, 0x051, 0x0007B, 0x0, "Firehawk Audio"}, 
-	{HPHW_FIO, 0x056, 0x0007B, 0x0, "Raven+ w SE FWSCSU Core Audio"}, 
-	{HPHW_FIO, 0x057, 0x0007B, 0x0, "Raven+ w Diff FWSCSU Core Audio"}, 
+	{HPHW_FIO, 0x056, 0x0007B, 0x0, "Raven+ w SE FWSCSI Core Audio"}, 
+	{HPHW_FIO, 0x057, 0x0007B, 0x0, "Raven+ w Diff FWSCSI Core Audio"}, 
 	{HPHW_FIO, 0x058, 0x0007B, 0x0, "FireHawk 200 Audio"}, 
 	{HPHW_FIO, 0x05C, 0x0007B, 0x0, "SummitHawk 230 Core Audio"}, 
 	{HPHW_FIO, 0x800, 0x0007B, 0x0, "Hitachi Tiny 64 Audio"}, 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/head.S linux-2.4.22-pre10/arch/parisc/kernel/head.S
--- linux-2.4.21/arch/parisc/kernel/head.S	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/head.S	2003-08-01 13:34:19.000000000 +0000
@@ -74,7 +74,7 @@
 	ldo             R%PA(_end)(%r4),%r4
 $bss_loop:
 	cmpb,<<,n       %r3,%r4,$bss_loop
-	stb,ma          %r0,1(%r3)
+	stw,ma          %r0,4(%r3)
 
 	/* Save away the arguments the boot loader passed in (32 bit args) */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/ioctl32.c linux-2.4.22-pre10/arch/parisc/kernel/ioctl32.c
--- linux-2.4.21/arch/parisc/kernel/ioctl32.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/ioctl32.c	2003-08-01 13:33:18.000000000 +0000
@@ -3123,6 +3123,11 @@
 COMPATIBLE_IOCTL(SIOCDRARP)
 COMPATIBLE_IOCTL(SIOCADDDLCI)
 COMPATIBLE_IOCTL(SIOCDELDLCI)
+COMPATIBLE_IOCTL(SIOCGMIIPHY)
+COMPATIBLE_IOCTL(SIOCGMIIREG)
+COMPATIBLE_IOCTL(SIOCSMIIREG)
+COMPATIBLE_IOCTL(SIOCGIFVLAN)
+COMPATIBLE_IOCTL(SIOCSIFVLAN)
 /* SG stuff */
 COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
 COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/irq.c linux-2.4.22-pre10/arch/parisc/kernel/irq.c
--- linux-2.4.21/arch/parisc/kernel/irq.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/irq.c	2003-08-01 13:32:48.000000000 +0000
@@ -57,7 +57,7 @@
 /* Bits in EIEM correlate with cpu_irq_action[].
 ** Numbered *Big Endian*! (ie bit 0 is MSB)
 */
-static unsigned long cpu_eiem = 0;
+static volatile unsigned long cpu_eiem = 0;
 
 static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;  /* protect IRQ regions */
 
@@ -462,7 +462,7 @@
 
 		for (irq = 0; eirr_val && bit; bit>>=1, irq++)
 		{
-			if (!(bit&eirr_val))
+			if (!(bit&eirr_val&cpu_eiem))
 				continue;
 
 			/* clear bit in mask - can exit loop sooner */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/parisc_ksyms.c linux-2.4.22-pre10/arch/parisc/kernel/parisc_ksyms.c
--- linux-2.4.21/arch/parisc/kernel/parisc_ksyms.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/parisc_ksyms.c	2003-08-01 13:34:58.000000000 +0000
@@ -67,6 +67,7 @@
 
 #include <linux/smp.h>
 EXPORT_SYMBOL(smp_num_cpus);
+EXPORT_SYMBOL(smp_call_function);
 #endif /* CONFIG_SMP */
 
 #include <asm/atomic.h>
@@ -127,7 +128,13 @@
 #include <asm/cache.h>
 EXPORT_SYMBOL(flush_kernel_dcache_range_asm);
 EXPORT_SYMBOL(flush_kernel_dcache_page);
-EXPORT_SYMBOL(flush_all_caches);
+
+/* asm/pgalloc.h doesn't include all it's dependencies */
+extern void __flush_dcache_page(struct page *page);
+EXPORT_SYMBOL(__flush_dcache_page);
+
+extern void flush_cache_all_local(void);
+EXPORT_SYMBOL(flush_cache_all_local);
 
 #include <asm/unistd.h>
 extern long sys_open(const char *, int, int);
@@ -150,6 +157,8 @@
 
 #include <asm/pdc.h>
 EXPORT_SYMBOL(pdc_add_valid);
+EXPORT_SYMBOL(pdc_tod_read);
+EXPORT_SYMBOL(pdc_tod_set);
 EXPORT_SYMBOL(pdc_lan_station_id);
 EXPORT_SYMBOL(pdc_get_initiator);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/pci-dma.c linux-2.4.22-pre10/arch/parisc/kernel/pci-dma.c
--- linux-2.4.21/arch/parisc/kernel/pci-dma.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/pci-dma.c	2003-08-01 13:34:32.000000000 +0000
@@ -428,9 +428,9 @@
 	    BUG();
 
 	for (i = 0; i < nents; i++, sglist++ ) {
-		sg_dma_address(sglist) = (dma_addr_t) virt_to_phys(sglist->address);
+		sg_dma_address(sglist) = (dma_addr_t) virt_to_phys(sg_virt_addr(sglist));
 		sg_dma_len(sglist) = sglist->length;
-		flush_kernel_dcache_range((unsigned long)sglist->address,
+		flush_kernel_dcache_range((unsigned long)sg_virt_addr(sglist),
 				sglist->length);
 	}
 	return nents;
@@ -449,7 +449,7 @@
 	/* once we do combining we'll need to use phys_to_virt(sg_dma_address(sglist)) */
 
 	for (i = 0; i < nents; i++, sglist++ )
-		flush_kernel_dcache_range((unsigned long) sglist->address, sglist->length);
+		flush_kernel_dcache_range((unsigned long) sg_virt_addr(sglist), sglist->length);
 	return;
 }
 
@@ -468,7 +468,7 @@
 	/* once we do combining we'll need to use phys_to_virt(sg_dma_address(sglist)) */
 
 	for (i = 0; i < nents; i++, sglist++ )
-		flush_kernel_dcache_range((unsigned long) sglist->address, sglist->length);
+		flush_kernel_dcache_range((unsigned long) sg_virt_addr(sglist), sglist->length);
 }
 
 struct pci_dma_ops pcxl_dma_ops = {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/perf.c linux-2.4.22-pre10/arch/parisc/kernel/perf.c
--- linux-2.4.21/arch/parisc/kernel/perf.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/perf.c	2003-08-01 13:33:36.000000000 +0000
@@ -499,6 +499,8 @@
  */
 static int __init perf_init(void)
 {
+	int ret;
+
 	/* Determine correct processor interface to use */
 	bitmask_array = perf_bitmasks;
 
@@ -517,11 +519,17 @@
 		return -ENODEV;
 	}
 
+	ret = misc_register(&perf_dev);
+	if (ret) {
+		printk(KERN_ERR "Performance monitoring counters: "
+			"cannot register misc device.\n");
+		return ret;
+	}
+
 	/* Patch the images to match the system */
     	perf_patch_images();
 
 	spin_lock_init(&perf_lock);
-	misc_register(&perf_dev);
 
 	/* TODO: this only lets us access the first cpu.. what to do for SMP? */
 	cpu_device = cpu_data[0].dev;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/processor.c linux-2.4.22-pre10/arch/parisc/kernel/processor.c
--- linux-2.4.21/arch/parisc/kernel/processor.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/processor.c	2003-08-01 13:31:22.000000000 +0000
@@ -77,8 +77,6 @@
 	unsigned long txn_addr;
 	unsigned long cpuid;
 	struct cpuinfo_parisc *p;
-	extern struct irq_region_ops cpu_irq_ops; /* arch/parisc...irq.c */
-	extern struct irqaction cpu_irq_actions[]; /* arch/parisc...irq.c */
 
 #ifndef CONFIG_SMP
 	if (boot_cpu_data.cpu_count > 0) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/sba_iommu.c linux-2.4.22-pre10/arch/parisc/kernel/sba_iommu.c
--- linux-2.4.21/arch/parisc/kernel/sba_iommu.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/sba_iommu.c	2003-08-01 13:34:09.000000000 +0000
@@ -1056,7 +1056,7 @@
 			printk(KERN_DEBUG " %2d : %08lx/%05x %p/%05x\n",
 				nents,
 				(unsigned long) sg_dma_address(startsg), cnt,
-				sg_virt_address(startsg), startsg->length
+				sg_virt_addr(startsg), startsg->length
 		);
 #else
 		DBG_RUN_SG(" %d : %08lx/%05x %p/%05x\n",
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/smp.c linux-2.4.22-pre10/arch/parisc/kernel/smp.c
--- linux-2.4.21/arch/parisc/kernel/smp.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/smp.c	2003-08-01 13:34:26.000000000 +0000
@@ -33,6 +33,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
+#include <linux/reboot.h>
 
 #include <asm/system.h>
 #include <asm/atomic.h>
@@ -434,25 +435,21 @@
 	extern void init_IRQ(void);    /* arch/parisc/kernel/irq.c */
 
 	/* Set modes and Enable floating point coprocessor */
-	(void) init_per_cpu(cpunum);
+	init_per_cpu(cpunum);
 
 	disable_sr_hashing();
-
 	mb();
 
 	/* Well, support 2.4 linux scheme as well. */
-	if (test_and_set_bit(cpunum, (unsigned long *) (&cpu_online_map)))
-	{
-		extern void machine_halt(void); /* arch/parisc.../process.c */
-
+	if (test_and_set_bit(cpunum, (unsigned long *) (&cpu_online_map))) {
 		printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum);
 		machine_halt();
-	}  
+	}
 
 	/* Initialise the idle task for this CPU */
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
-	if(current->mm)
+	if (current->mm)
 		BUG();
 	enter_lazy_tlb(&init_mm, current, cpunum);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/traps.c linux-2.4.22-pre10/arch/parisc/kernel/traps.c
--- linux-2.4.21/arch/parisc/kernel/traps.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/traps.c	2003-08-01 13:35:08.000000000 +0000
@@ -455,13 +455,6 @@
 	unsigned long fault_space = 0;
 	struct siginfo si;
 
-	/* HACK! jsm is going to fix this.
-	 * entry.S will manage I-bit - only enable I-bit if it was
-	 * enabled before we took the "trap".
-	 */
-	if (code != 1)
-		local_irq_enable();
-
 	switch(code) {
 
 	case  1:
@@ -727,6 +720,7 @@
 	    }
 	}
 
+	local_irq_enable();
 	do_page_fault(regs, code, fault_address);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/kernel/unaligned.c linux-2.4.22-pre10/arch/parisc/kernel/unaligned.c
--- linux-2.4.21/arch/parisc/kernel/unaligned.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/kernel/unaligned.c	2003-08-01 13:31:46.000000000 +0000
@@ -3,6 +3,7 @@
  *    Unaligned memory access handler
  *
  *    Copyright (C) 2001 Randolph Chung <tausq@debian.org>
+ *    Significantly tweaked by LaMont Jones <lamont@debian.org>
  *
  *    This program is free software; you can redistribute it and/or modify
  *    it under the terms of the GNU General Public License as published by
@@ -66,28 +67,28 @@
 #define OPCODE3_MASK	OPCODE3(0x3f,1)
 #define OPCODE4_MASK    OPCODE4(0x3f)
 
-/* skip LDB (index) */
+/* skip LDB - never unaligned (index) */
 #define OPCODE_LDH_I	OPCODE1(0x03,0,0x1)
 #define OPCODE_LDW_I	OPCODE1(0x03,0,0x2)
 #define OPCODE_LDD_I	OPCODE1(0x03,0,0x3)
 #define OPCODE_LDDA_I	OPCODE1(0x03,0,0x4)
-/* skip LDCD (index) */
+#define OPCODE_LDCD_I	OPCODE1(0x03,0,0x5)
 #define OPCODE_LDWA_I	OPCODE1(0x03,0,0x6)
-/* skip LDCW (index) */
-/* skip LDB (short) */
+#define OPCODE_LDCW_I	OPCODE1(0x03,0,0x7)
+/* skip LDB - never unaligned (short) */
 #define OPCODE_LDH_S	OPCODE1(0x03,1,0x1)
 #define OPCODE_LDW_S	OPCODE1(0x03,1,0x2)
 #define OPCODE_LDD_S	OPCODE1(0x03,1,0x3)
 #define OPCODE_LDDA_S	OPCODE1(0x03,1,0x4)
-/* skip LDCD (short) */
+#define OPCODE_LDCD_S	OPCODE1(0x03,1,0x5)
 #define OPCODE_LDWA_S	OPCODE1(0x03,1,0x6)
-/* skip LDCW (short) */
-/* skip STB */
+#define OPCODE_LDCW_S	OPCODE1(0x03,1,0x7)
+/* skip STB - never unaligned */
 #define OPCODE_STH	OPCODE1(0x03,1,0x9)
 #define OPCODE_STW	OPCODE1(0x03,1,0xa)
 #define OPCODE_STD	OPCODE1(0x03,1,0xb)
-/* skip STBY */
-/* skip STDBY */
+/* skip STBY - never unaligned */
+/* skip STDBY - never unaligned */
 #define OPCODE_STWA	OPCODE1(0x03,1,0xe)
 #define OPCODE_STDA	OPCODE1(0x03,1,0xf)
 
@@ -103,129 +104,200 @@
 
 #define OPCODE_LDH_L    OPCODE4(0x11)
 #define OPCODE_LDW_L    OPCODE4(0x12)
-#define OPCODE_LDW_L2   OPCODE4(0x13)
+#define OPCODE_LDWM     OPCODE4(0x13)
 #define OPCODE_STH_L    OPCODE4(0x19)
 #define OPCODE_STW_L    OPCODE4(0x1A)
-#define OPCODE_STW_L2   OPCODE4(0x1B)
+#define OPCODE_STWM     OPCODE4(0x1B)
+
+#define MAJOR_OP(i) (((i)>>26)&0x3f)
+#define R1(i) (((i)>>21)&0x1f)
+#define R2(i) (((i)>>16)&0x1f)
+#define R3(i) ((i)&0x1f)
+#define IM(i,n) (((i)>>1&((1<<(n-1))-1))|((i)&1?((0-1L)<<(n-1)):0))
+#define IM5_2(i) IM((i)>>16,5)
+#define IM5_3(i) IM((i),5)
+#define IM14(i) IM((i),14)
 
 int unaligned_enabled = 1;
 
 void die_if_kernel (char *str, struct pt_regs *regs, long err);
 
-static int emulate_load(struct pt_regs *regs, int len, int toreg)
+static int emulate_ldh(struct pt_regs *regs, int toreg)
 {
 	unsigned long saddr = regs->ior;
 	unsigned long val = 0;
-	int ret = 0;
 
-	if (regs->isr != regs->sr[7])
-	{
-		printk(KERN_CRIT "isr verification failed (isr: " RFMT ", sr7: " RFMT "\n",
-			regs->isr, regs->sr[7]);
-		return 1;
-	}
+	DPRINTF("load " RFMT ":" RFMT " to r%d for 2 bytes\n", 
+		regs->isr, regs->ior, toreg);
+
+	__asm__ __volatile__  (
+"	mtsp	%3, %%sr1\n"
+"	ldbs	0(%%sr1,%2), %%r20\n"
+"	ldbs	1(%%sr1,%2), %0\n"
+	"depw	%%r20, 23, 24, %0\n"
+	: "=r" (val)
+	: "0" (val), "r" (saddr), "r" (regs->isr)
+	: "r20" );
+
+	DPRINTF("val = 0x" RFMT "\n", val);
+
+	if (toreg)
+		regs->gr[toreg] = val;
+
+	return 0;
+}
+static int emulate_ldw(struct pt_regs *regs, int toreg)
+{
+	unsigned long saddr = regs->ior;
+	unsigned long val = 0;
 
-	DPRINTF("load " RFMT ":" RFMT " to r%d for %d bytes\n", 
-		regs->isr, regs->ior, toreg, len);
+	DPRINTF("load " RFMT ":" RFMT " to r%d for 4 bytes\n", 
+		regs->isr, regs->ior, toreg);
 
 	__asm__ __volatile__  (
-"       mfsp %%sr1, %%r20\n"
-"       mtsp %6, %%sr1\n"
-"	copy %%r0, %0\n"
-"0:	ldbs,ma	1(%%sr1,%4), %%r19\n"
-"	addi -1, %5, %5\n"
-"	cmpib,>= 0, %5, 2f\n"
-"	or %%r19, %0, %0\n"
-"	b 0b\n"
-	
-#ifdef __LP64__
-	"depd,z %0, 55, 56, %0\n"
-#else
-	"depw,z %0, 23, 24, %0\n"
-#endif
-	
-"1:	ldi	10, %1\n"
-"2:     mtsp %%r20, %%sr1\n"
-"	.section __ex_table,\"a\"\n"
+"	zdep	%2,28,2,%%r19\n"		/* r19=(ofs&3)*8 */
+"	mtsp	%3, %%sr1\n"
+"	depw	%%r0,31,2,%2\n"
+"	ldw	0(%%sr1,%2),%0\n"
+"	ldw	4(%%sr1,%2),%%r20\n"
+"	subi	32,%%r19,%%r19\n"
+"	mtctl	%%r19,11\n"
+"	vshd	%0,%%r20,%0\n"
+	: "=r" (val)
+	: "0" (val), "r" (saddr), "r" (regs->isr)
+	: "r19", "r20" );
+
+	DPRINTF("val = 0x" RFMT "\n", val);
+
+	if (toreg)
+		regs->gr[toreg] = val;
+
+	return 0;
+}
 #ifdef __LP64__
-	".dword 0b, (1b-0b)\n"
-#else
-	".word 0b, (1b-0b)\n"
-#endif
-	".previous\n" 
-	: "=r" (val), "=r" (ret)
-	: "0" (val), "1" (ret), "r" (saddr), "r" (len), "r" (regs->isr)
+static int emulate_ldd(struct pt_regs *regs, int toreg)
+{
+	unsigned long saddr = regs->ior;
+	unsigned long val = 0;
+
+	DPRINTF("load " RFMT ":" RFMT " to r%d for 8 bytes\n", 
+		regs->isr, regs->ior, toreg);
+
+	__asm__ __volatile__  (
+"	depd,z	%2,60,3,%%r19\n"		/* r19=(ofs&7)*8 */
+"	mtsp	%3, %%sr1\n"
+"	depd	%%r0,63,3,%2\n"
+"	ldd	0(%%sr1,%2),%0\n"
+"	ldd	8(%%sr1,%2),%%r20\n"
+"	subi	64,%%r19,%%r19\n"
+"	mtsar	%%r19\n"
+"	shrpd	%0,%%r20,%%sar,%0\n"
+	: "=r" (val)
+	: "0" (val), "r" (saddr), "r" (regs->isr)
 	: "r19", "r20" );
 
 	DPRINTF("val = 0x" RFMT "\n", val);
 
-	regs->gr[toreg] = val;
+	if (toreg)
+		regs->gr[toreg] = val;
 
-	return ret;
+	return 0;
 }
+#endif
 
-static int emulate_store(struct pt_regs *regs, int len, int frreg)
+static int emulate_sth(struct pt_regs *regs, int frreg)
 {
-	int ret = 0;
-#ifdef __LP64__
-	unsigned long val = regs->gr[frreg] << (64 - (len << 3));
-#else
-	unsigned long val = regs->gr[frreg] << (32 - (len << 3));
-#endif
+	unsigned long val = regs->gr[frreg];
+	if (!frreg)
+		val = 0;
 
-	if (regs->isr != regs->sr[7])
-	{
-		printk(KERN_CRIT "isr verification failed (isr: " RFMT ", sr7: " RFMT "\n",
-			regs->isr, regs->sr[7]);
-		return 1;
-	}
+	DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 2 bytes\n", frreg, 
+		regs->gr[frreg], regs->isr, regs->ior);
+
+	__asm__ __volatile__ (
+"	mtsp %2, %%sr1\n"
+"	extrw,u %0, 23, 8, %%r19\n"
+"	stb %0, 1(%%sr1, %1)\n"
+"	stb %%r19, 0(%%sr1, %1)\n"
+	:
+	: "r" (val), "r" (regs->ior), "r" (regs->isr)
+	: "r19" );
+
+	return 0;
+}
+static int emulate_stw(struct pt_regs *regs, int frreg)
+{
+	unsigned long val = regs->gr[frreg];
+	if (!frreg)
+		val = 0;
 
-	DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for %d bytes\n", frreg, 
-		regs->gr[frreg], regs->isr, regs->ior, len);
+	DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 4 bytes\n", frreg, 
+		regs->gr[frreg], regs->isr, regs->ior);
 
 
 	__asm__ __volatile__ (
-"       mfsp %%sr1, %%r20\n"		/* save sr1 */
-"       mtsp %5, %%sr1\n"
-#ifdef __LP64__
-"0:	extrd,u %2, 7, 8, %%r19\n"
-#else
-"0:	extrw,u %2, 7, 8, %%r19\n"
-#endif
-"1:	stb,ma %%r19, 1(%%sr1, %3)\n"
-"	addi -1, %4, %4\n"
-"	cmpib,>= 0, %4, 3f\n"
-	
+"	mtsp %2, %%sr1\n"
+"	zdep	%1, 28, 2, %%r19\n"
+"	dep	%%r0, 31, 2, %1\n"
+"	mtsar	%%r19\n"
+"	depwi,z	-2, %%sar, 32, %%r19\n"
+"	ldw	0(%%sr1,%1),%%r20\n"
+"	ldw	4(%%sr1,%1),%%r21\n"
+"	vshd	%%r0, %0, %%r22\n"
+"	vshd	%0, %%r0, %%r1\n"
+"	and	%%r20, %%r19, %%r20\n"
+"	andcm	%%r21, %%r19, %%r21\n"
+"	or	%%r22, %%r20, %%r20\n"
+"	or	%%r1, %%r21, %%r21\n"
+"	stw	%%r20,0(%%sr1,%1)\n"
+"	stw	%%r21,4(%%sr1,%1)\n"
+	:
+	: "r" (val), "r" (regs->ior), "r" (regs->isr)
+	: "r19", "r20", "r21", "r22", "r1" );
+
+	return 0;
+}
 #ifdef __LP64__
-	"depd,z %2, 55, 56, %2\n"
-#else
-	"depw,z %2, 23, 24, %2\n"
-#endif
+static int emulate_std(struct pt_regs *regs, int frreg)
+{
+	unsigned long val = regs->gr[frreg];
+	if (!frreg)
+		val = 0;
 
-"	b 0b\n"
-"	nop\n"
+	DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 8 bytes\n", frreg, 
+		regs->gr[frreg], regs->isr, regs->ior);
 
-"2:	ldi 11, %0\n"
-"3:     mtsp %%r20, %%sr1\n"
-"	.section __ex_table,\"a\"\n"
-#ifdef __LP64__
-	".dword 1b, (2b-1b)\n"
-#else
-	".word 1b, (2b-1b)\n"
-#endif
-	".previous\n" 
-	: "=r" (ret)
-	: "0" (ret), "r" (val), "r" (regs->ior), "r" (len), "r" (regs->isr)
-	: "r19", "r20" );
 
-	return ret;
-}
+	__asm__ __volatile__ (
+"	mtsp %2, %%sr1\n"
+"	depd,z	%1, 60, 3, %%r19\n"
+"	depd	%%r0, 63, 3, %1\n"
+"	mtsar	%%r19\n"
+"	depdi,z	-2, %%sar, 64, %%r19\n"
+"	ldd	0(%%sr1,%1),%%r20\n"
+"	ldd	8(%%sr1,%1),%%r21\n"
+"	shrpd	%%r0, %0, %%sar, %%r22\n"
+"	shrpd	%0, %%r0, %%sar, %%r1\n"
+"	and	%%r20, %%r19, %%r20\n"
+"	andcm	%%r21, %%r19, %%r21\n"
+"	or	%%r22, %%r20, %%r20\n"
+"	or	%%r1, %%r21, %%r21\n"
+"	std	%%r20,0(%%sr1,%1)\n"
+"	std	%%r21,8(%%sr1,%1)\n"
+	:
+	: "r" (val), "r" (regs->ior), "r" (regs->isr)
+	: "r19", "r20", "r21", "r22", "r1" );
 
+	return 0;
+}
+#endif
 
 void handle_unaligned(struct pt_regs *regs)
 {
 	unsigned long unaligned_count = 0;
 	unsigned long last_time = 0;
+	unsigned long newbase = regs->gr[R1(regs->iir)];
+	int modify = 0;
 	int ret = -1;
 	struct siginfo si;
 
@@ -284,83 +356,169 @@
 	if (!unaligned_enabled)
 		goto force_sigbus;
 
+	/* handle modification - OK, it's ugly, see the instruction manual */
+	switch (MAJOR_OP(regs->iir))
+	{
+	case 0x03:
+	case 0x09:
+	case 0x0b:
+		if (regs->iir&0x20)
+		{
+			modify = 1;
+			if (regs->iir&0x1000)		/* short loads */
+				if (regs->iir&0x200)
+					newbase += IM5_3(regs->iir);
+				else
+					newbase += IM5_2(regs->iir);
+			else if (regs->iir&0x2000)	/* scaled indexed */
+			{
+				int shift=0;
+				switch (regs->iir & OPCODE1_MASK)
+				{
+				case OPCODE_LDH_I:
+					shift= 1; break;
+				case OPCODE_LDW_I:
+					shift= 2; break;
+				case OPCODE_LDD_I:
+				case OPCODE_LDDA_I:
+					shift= 3; break;
+				}
+				newbase += (R2(regs->iir)?regs->gr[R2(regs->iir)]:0)<<shift;
+			} else				/* simple indexed */
+				newbase += (R2(regs->iir)?regs->gr[R2(regs->iir)]:0);
+		}
+		break;
+	case 0x13:
+	case 0x1b:
+		modify = 1;
+		newbase += IM14(regs->iir);
+		break;
+	case 0x14:
+	case 0x1c:
+		if (regs->iir&8)
+		{
+			modify = 1;
+			newbase += IM14(regs->iir&~0xe);
+		}
+		break;
+	case 0x16:
+	case 0x1e:
+		modify = 1;
+		newbase += IM14(regs->iir&6);
+		break;
+	case 0x17:
+	case 0x1f:
+		if (regs->iir&4)
+		{
+			modify = 1;
+			newbase += IM14(regs->iir&~4);
+		}
+		break;
+	}
+
+	if (regs->isr != regs->sr[7])
+	{
+		printk(KERN_CRIT "isr verification failed (isr: " RFMT ", sr7: " RFMT "\n",
+			regs->isr, regs->sr[7]);
+
+		/* don't kill him though, since he has appropriate access to the page, or we
+		 * would never have gotten here.
+		 */
+	}
+
 	/* TODO: make this cleaner... */
 	switch (regs->iir & OPCODE1_MASK)
 	{
 	case OPCODE_LDH_I:
 	case OPCODE_LDH_S:
-		ret = emulate_load(regs, 2, regs->iir & 0x1f);
+		ret = emulate_ldh(regs, R3(regs->iir));
 		break;
 
 	case OPCODE_LDW_I:
 	case OPCODE_LDWA_I:
 	case OPCODE_LDW_S:
 	case OPCODE_LDWA_S:
-		ret = emulate_load(regs, 4, regs->iir&0x1f);
-		break;
-
-	case OPCODE_LDD_I:
-	case OPCODE_LDDA_I:
-	case OPCODE_LDD_S:
-	case OPCODE_LDDA_S:
-		ret = emulate_load(regs, 8, regs->iir&0x1f);
+		ret = emulate_ldw(regs, R3(regs->iir));
 		break;
 
 	case OPCODE_STH:
-		ret = emulate_store(regs, 2, (regs->iir>>16)&0x1f);
+		ret = emulate_sth(regs, R2(regs->iir));
 		break;
 
 	case OPCODE_STW:
 	case OPCODE_STWA:
-		ret = emulate_store(regs, 4, (regs->iir>>16)&0x1f);
+		ret = emulate_stw(regs, R2(regs->iir));
+		break;
+
+#ifdef __LP64__
+	case OPCODE_LDD_I:
+	case OPCODE_LDDA_I:
+	case OPCODE_LDD_S:
+	case OPCODE_LDDA_S:
+		ret = emulate_ldd(regs, R3(regs->iir));
 		break;
 
 	case OPCODE_STD:
 	case OPCODE_STDA:
-		ret = emulate_store(regs, 8, (regs->iir>>16)&0x1f);
+		ret = emulate_std(regs, R2(regs->iir));
+		break;
+#endif
+
+	case OPCODE_LDCD_I:
+	case OPCODE_LDCW_I:
+	case OPCODE_LDCD_S:
+	case OPCODE_LDCW_S:
+		ret = -1;	/* "undefined", but lets kill them. */
 		break;
 	}
+#ifdef __LP64__
 	switch (regs->iir & OPCODE2_MASK)
 	{
 	case OPCODE_LDD_L:
 	case OPCODE_FLDD_L:
-		ret = emulate_load(regs, 8, (regs->iir>>16)&0x1f);
+		ret = emulate_ldd(regs, R2(regs->iir));
 		break;
 
 	case OPCODE_STD_L:
 	case OPCODE_FSTD_L:
-		ret = emulate_store(regs, 8, (regs->iir>>16)&0x1f);
+		ret = emulate_std(regs, R2(regs->iir));
 		break;
 	}
+#endif
 	switch (regs->iir & OPCODE3_MASK)
 	{
 	case OPCODE_LDW_M:
 	case OPCODE_FLDW_L:
-		ret = emulate_load(regs, 4, (regs->iir>>16)&0x1f);
+		ret = emulate_ldw(regs, R2(regs->iir));
 		break;
 
 	case OPCODE_FSTW_L:
 	case OPCODE_STW_M:
-		ret = emulate_store(regs, 4, (regs->iir>>16)&0x1f);
+		ret = emulate_stw(regs, R2(regs->iir));
 		break;
 	}
 	switch (regs->iir & OPCODE4_MASK)
 	{
 	case OPCODE_LDH_L:
-		ret = emulate_load(regs, 2, (regs->iir>>16)&0x1f);
+		ret = emulate_ldh(regs, R2(regs->iir));
 		break;
 	case OPCODE_LDW_L:
-	case OPCODE_LDW_L2:
-		ret = emulate_load(regs, 4, (regs->iir>>16)&0x1f);
+	case OPCODE_LDWM:
+		ret = emulate_ldw(regs, R2(regs->iir));
 		break;
 	case OPCODE_STH_L:
-		ret = emulate_store(regs, 2, (regs->iir>>16)&0x1f);
+		ret = emulate_sth(regs, R2(regs->iir));
 		break;
 	case OPCODE_STW_L:
-	case OPCODE_STW_L2:
-		ret = emulate_store(regs, 4, (regs->iir>>16)&0x1f);
+	case OPCODE_STWM:
+		ret = emulate_stw(regs, R2(regs->iir));
 		break;
 	}
+	/* XXX LJ - need to handle float load/store */
+
+	if (modify && R1(regs->iir))
+		regs->gr[R1(regs->iir)] = newbase;
+
 
 	if (ret < 0)
 		printk(KERN_CRIT "Not-handled unaligned insn 0x%08lx\n", regs->iir);
@@ -424,9 +582,9 @@
 			align_mask = 1UL;
 			break;
 		case OPCODE_LDW_L:
-		case OPCODE_LDW_L2:
+		case OPCODE_LDWM:
 		case OPCODE_STW_L:
-		case OPCODE_STW_L2:
+		case OPCODE_STWM:
 			align_mask = 3UL;
 			break;
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/dfadd.c linux-2.4.22-pre10/arch/parisc/math-emu/dfadd.c
--- linux-2.4.21/arch/parisc/math-emu/dfadd.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/dfadd.c	2003-08-01 13:34:06.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/dfadd.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/dfadd.c		$Revision: $
  *
  *  Purpose:
  *	Double_add: add two double precision values.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/dfcmp.c linux-2.4.22-pre10/arch/parisc/math-emu/dfcmp.c
--- linux-2.4.21/arch/parisc/math-emu/dfcmp.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/dfcmp.c	2003-08-01 13:30:56.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/dfcmp.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/dfcmp.c		$Revision: $
  *
  *  Purpose:
  *	dbl_cmp: compare two values
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/dfdiv.c linux-2.4.22-pre10/arch/parisc/math-emu/dfdiv.c
--- linux-2.4.21/arch/parisc/math-emu/dfdiv.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/dfdiv.c	2003-08-01 13:34:43.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/dfdiv.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/dfdiv.c		$Revision: $
  *
  *  Purpose:
  *	Double Precision Floating-point Divide
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/dfmpy.c linux-2.4.22-pre10/arch/parisc/math-emu/dfmpy.c
--- linux-2.4.21/arch/parisc/math-emu/dfmpy.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/dfmpy.c	2003-08-01 13:32:16.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/dfmpy.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/dfmpy.c		$Revision: $
  *
  *  Purpose:
  *	Double Precision Floating-point Multiply
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/dfrem.c linux-2.4.22-pre10/arch/parisc/math-emu/dfrem.c
--- linux-2.4.21/arch/parisc/math-emu/dfrem.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/dfrem.c	2003-08-01 13:34:48.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/dfrem.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/dfrem.c		$Revision: $
  *
  *  Purpose:
  *	Double Precision Floating-point Remainder
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/dfsqrt.c linux-2.4.22-pre10/arch/parisc/math-emu/dfsqrt.c
--- linux-2.4.21/arch/parisc/math-emu/dfsqrt.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/dfsqrt.c	2003-08-01 13:33:42.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/dfsqrt.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/dfsqrt.c		$Revision: $
  *
  *  Purpose:
  *	Double Floating-point Square Root
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/dfsub.c linux-2.4.22-pre10/arch/parisc/math-emu/dfsub.c
--- linux-2.4.21/arch/parisc/math-emu/dfsub.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/dfsub.c	2003-08-01 13:32:30.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/dfsub.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/dfsub.c		$Revision: $
  *
  *  Purpose:
  *	Double_subtract: subtract two double precision values.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/driver.c linux-2.4.22-pre10/arch/parisc/math-emu/driver.c
--- linux-2.4.21/arch/parisc/math-emu/driver.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/driver.c	2003-08-01 13:33:00.000000000 +0000
@@ -80,14 +80,19 @@
 int
 handle_fpe(struct pt_regs *regs)
 {
-	extern void printbinary(unsigned long x, int nbits);
+	extern int printbinary(char *buf, unsigned long x, int nbits);
 	struct siginfo si;
 	unsigned int orig_sw, sw;
 	int signalcode;
+	char buf[128];
 	/* need an intermediate copy of float regs because FPU emulation
 	 * code expects an artificial last entry which contains zero
+	 *
+	 * also, the passed in fr registers contain one word that defines
+	 * the fpu type. the fpu type information is constructed 
+	 * inside the emulation code
 	 */
-	__u64 frcopy[33];
+	__u64 frcopy[36];
 
 	memcpy(frcopy, regs->fr, sizeof regs->fr);
 	frcopy[32] = 0;
@@ -96,8 +101,8 @@
 
 	if (FPUDEBUG) {
 		printk(KERN_DEBUG "FP VZOUICxxxxCQCQCQCQCQCRMxxTDVZOUI ->\n   ");
-		printbinary(orig_sw, 32);
-		printk(KERN_DEBUG "\n");
+		printbinary(buf, orig_sw, 32);
+		printk(KERN_DEBUG "%s\n", buf);
 	}
 
 	signalcode = decode_fpu(frcopy, 0x666);
@@ -107,8 +112,8 @@
 	if (FPUDEBUG) {
 		printk(KERN_DEBUG "VZOUICxxxxCQCQCQCQCQCRMxxTDVZOUI decode_fpu returns %d|0x%x\n",
 			signalcode >> 24, signalcode & 0xffffff);
-		printbinary(sw, 32);
-		printk(KERN_DEBUG "\n");
+		printbinary(buf, sw, 32);
+		printk(KERN_DEBUG "%s\n", buf);
 	}
 
 	memcpy(regs->fr, frcopy, sizeof regs->fr);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/fcnvff.c linux-2.4.22-pre10/arch/parisc/math-emu/fcnvff.c
--- linux-2.4.21/arch/parisc/math-emu/fcnvff.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/fcnvff.c	2003-08-01 13:31:53.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/fcnvff.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/fcnvff.c		$Revision: $
  *
  *  Purpose:
  *	Single Floating-point to Double Floating-point
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/fcnvfu.c linux-2.4.22-pre10/arch/parisc/math-emu/fcnvfu.c
--- linux-2.4.21/arch/parisc/math-emu/fcnvfu.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/fcnvfu.c	2003-08-01 13:33:12.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/fcnvfu.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/fcnvfu.c		$Revision: $
  *
  *  Purpose:
  *	Floating-point to Unsigned Fixed-point Converts
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/fcnvfut.c linux-2.4.22-pre10/arch/parisc/math-emu/fcnvfut.c
--- linux-2.4.21/arch/parisc/math-emu/fcnvfut.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/fcnvfut.c	2003-08-01 13:34:01.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/fcnvfut.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/fcnvfut.c		$Revision: $
  *
  *  Purpose:
  *	Floating-point to Unsigned Fixed-point Converts with Truncation
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/fcnvfx.c linux-2.4.22-pre10/arch/parisc/math-emu/fcnvfx.c
--- linux-2.4.21/arch/parisc/math-emu/fcnvfx.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/fcnvfx.c	2003-08-01 13:31:08.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/fcnvfx.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/fcnvfx.c		$Revision: $
  *
  *  Purpose:
  *	Single Floating-point to Single Fixed-point
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/fcnvfxt.c linux-2.4.22-pre10/arch/parisc/math-emu/fcnvfxt.c
--- linux-2.4.21/arch/parisc/math-emu/fcnvfxt.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/fcnvfxt.c	2003-08-01 13:33:58.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/fcnvfxt.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/fcnvfxt.c		$Revision: $
  *
  *  Purpose:
  *	Single Floating-point to Single Fixed-point /w truncated result
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/fcnvuf.c linux-2.4.22-pre10/arch/parisc/math-emu/fcnvuf.c
--- linux-2.4.21/arch/parisc/math-emu/fcnvuf.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/fcnvuf.c	2003-08-01 13:32:44.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/fcnvuf.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/fcnvuf.c		$Revision: $
  *
  *  Purpose:
  *	Fixed point to Floating-point Converts
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/fcnvxf.c linux-2.4.22-pre10/arch/parisc/math-emu/fcnvxf.c
--- linux-2.4.21/arch/parisc/math-emu/fcnvxf.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/fcnvxf.c	2003-08-01 13:31:55.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/fcnvxf.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/fcnvxf.c		$Revision: $
  *
  *  Purpose:
  *	Single Fixed-point to Single Floating-point
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/float.h linux-2.4.22-pre10/arch/parisc/math-emu/float.h
--- linux-2.4.21/arch/parisc/math-emu/float.h	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/float.h	2003-08-01 13:31:45.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  * 
  *  File: 
- *      @(#)	pa/spmath/float.h		$Revision: 1.2 $
+ *      @(#)	pa/spmath/float.h		$Revision: 1.1 $
  * 
  *  Purpose:
  *      <<please update with a synopis of the functionality provided by this file>>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/fmpyfadd.c linux-2.4.22-pre10/arch/parisc/math-emu/fmpyfadd.c
--- linux-2.4.21/arch/parisc/math-emu/fmpyfadd.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/fmpyfadd.c	2003-08-01 13:32:16.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/fmpyfadd.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/fmpyfadd.c		$Revision: $
  *
  *  Purpose:
  *	Double Floating-point Multiply Fused Add
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/fpu.h linux-2.4.22-pre10/arch/parisc/math-emu/fpu.h
--- linux-2.4.21/arch/parisc/math-emu/fpu.h	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/fpu.h	2003-08-01 13:33:21.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  * 
  *  File: 
- *      @(#)	pa/fp/fpu.h		$Revision: 1.2 $
+ *      @(#)	pa/fp/fpu.h		$Revision: $
  * 
  *  Purpose:
  *      <<please update with a synopis of the functionality provided by this file>>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/fpudispatch.c linux-2.4.22-pre10/arch/parisc/math-emu/fpudispatch.c
--- linux-2.4.21/arch/parisc/math-emu/fpudispatch.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/fpudispatch.c	2003-08-01 13:32:26.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/fp/fpudispatch.c		$Revision: 1.1 $
+ *	@(#)	pa/fp/fpudispatch.c		$Revision: $
  *
  *  Purpose:
  *	<<please update with a synopsis of the functionality provided by this file>>
@@ -51,6 +51,7 @@
 
 #include "float.h"
 #include "types.h"
+#include <asm/processor.h>
 /* #include <sys/debug.h> */
 /* #include <machine/sys/mdep_private.h> */
 
@@ -166,6 +167,20 @@
 
 #define VASSERT(x)
 
+static void parisc_linux_get_fpu_type(u_int fpregs[])
+{
+	/* on pa-linux the fpu type is not filled in by the
+	 * caller; it is constructed here  
+	 */ 
+	if (boot_cpu_data.cpu_type == pcxs)
+		fpregs[FPU_TYPE_FLAG_POS] = TIMEX_EXTEN_FLAG;
+	else if (boot_cpu_data.cpu_type == pcxt ||
+	         boot_cpu_data.cpu_type == pcxt_)
+		fpregs[FPU_TYPE_FLAG_POS] = ROLEX_EXTEN_FLAG;
+	else if (boot_cpu_data.cpu_type >= pcxu)
+		fpregs[FPU_TYPE_FLAG_POS] = PA2_0_FPU_FLAG;
+}
+
 /*
  * this routine will decode the excepting floating point instruction and
  * call the approiate emulation routine.
@@ -184,6 +199,8 @@
 	/* All FP emulation code assumes that ints are 4-bytes in length */
 	VASSERT(sizeof(int) == 4);
 
+	parisc_linux_get_fpu_type(fpregs);
+
 	fpu_type_flags=fpregs[FPU_TYPE_FLAG_POS];  /* get fpu type flags */
 
 	class = get_class(ir);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/sfadd.c linux-2.4.22-pre10/arch/parisc/math-emu/sfadd.c
--- linux-2.4.21/arch/parisc/math-emu/sfadd.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/sfadd.c	2003-08-01 13:33:31.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/sfadd.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/sfadd.c		$Revision: $
  *
  *  Purpose:
  *	Single_add: add two single precision values.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/sfcmp.c linux-2.4.22-pre10/arch/parisc/math-emu/sfcmp.c
--- linux-2.4.21/arch/parisc/math-emu/sfcmp.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/sfcmp.c	2003-08-01 13:33:00.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/sfcmp.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/sfcmp.c		$Revision: $
  *
  *  Purpose:
  *	sgl_cmp: compare two values
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/sfdiv.c linux-2.4.22-pre10/arch/parisc/math-emu/sfdiv.c
--- linux-2.4.21/arch/parisc/math-emu/sfdiv.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/sfdiv.c	2003-08-01 13:30:54.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/sfdiv.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/sfdiv.c		$Revision: $
  *
  *  Purpose:
  *	Single Precision Floating-point Divide
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/sfmpy.c linux-2.4.22-pre10/arch/parisc/math-emu/sfmpy.c
--- linux-2.4.21/arch/parisc/math-emu/sfmpy.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/sfmpy.c	2003-08-01 13:32:24.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/sfmpy.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/sfmpy.c		$Revision: $
  *
  *  Purpose:
  *	Single Precision Floating-point Multiply
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/sfrem.c linux-2.4.22-pre10/arch/parisc/math-emu/sfrem.c
--- linux-2.4.21/arch/parisc/math-emu/sfrem.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/sfrem.c	2003-08-01 13:33:30.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/sfrem.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/sfrem.c		$Revision: $
  *
  *  Purpose:
  *	Single Precision Floating-point Remainder
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/sfsqrt.c linux-2.4.22-pre10/arch/parisc/math-emu/sfsqrt.c
--- linux-2.4.21/arch/parisc/math-emu/sfsqrt.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/sfsqrt.c	2003-08-01 13:33:14.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/sfsqrt.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/sfsqrt.c		$Revision: $
  *
  *  Purpose:
  *	Single Floating-point Square Root
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/parisc/math-emu/sfsub.c linux-2.4.22-pre10/arch/parisc/math-emu/sfsub.c
--- linux-2.4.21/arch/parisc/math-emu/sfsub.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.22-pre10/arch/parisc/math-emu/sfsub.c	2003-08-01 13:33:11.000000000 +0000
@@ -22,7 +22,7 @@
  * BEGIN_DESC
  *
  *  File:
- *	@(#)	pa/spmath/sfsub.c		$Revision: 1.1 $
+ *	@(#)	pa/spmath/sfsub.c		$Revision: $
  *
  *  Purpose:
  *	Single_subtract: subtract two single precision values.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/8260_io/enet.c linux-2.4.22-pre10/arch/ppc/8260_io/enet.c
--- linux-2.4.21/arch/ppc/8260_io/enet.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/8260_io/enet.c	2003-08-01 13:30:33.000000000 +0000
@@ -115,7 +115,7 @@
 	cbd_t	*dirty_tx;	/* The ring entries to be free()ed. */
 	scc_t	*sccp;
 	struct	net_device_stats stats;
-	uint	tx_full;
+	uint	tx_free;
 	spinlock_t lock;
 };
 
@@ -175,9 +175,9 @@
 	bdp = cep->cur_tx;
 
 #ifndef final_version
-	if (bdp->cbd_sc & BD_ENET_TX_READY) {
+	if (!cep->tx_free || (bdp->cbd_sc & BD_ENET_TX_READY)) {
 		/* Ooops.  All transmit buffers are full.  Bail out.
-		 * This should not happen, since cep->tx_full should be set.
+		 * This should not happen, since the tx queue should be stopped.
 		 */
 		printk("%s: tx queue full!.\n", dev->name);
 		return 1;
@@ -206,7 +206,7 @@
 
 	cep->stats.tx_bytes += skb->len;
 	cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK;
-	
+
 	spin_lock_irq(&cep->lock);
 
 	/* Send it on its way.  Tell CPM its ready, interrupt when done,
@@ -223,10 +223,8 @@
 	else
 		bdp++;
 
-	if (bdp->cbd_sc & BD_ENET_TX_READY) {
+	if (!--cep->tx_free)
 		netif_stop_queue(dev);
-		cep->tx_full = 1;
-	}
 
 	cep->cur_tx = (cbd_t *)bdp;
 
@@ -246,8 +244,8 @@
 	{
 		int	i;
 		cbd_t	*bdp;
-		printk(" Ring data dump: cur_tx %p%s cur_rx %p.\n",
-		       cep->cur_tx, cep->tx_full ? " (full)" : "",
+		printk(" Ring data dump: cur_tx %p tx_free %d cur_rx %p.\n",
+		       cep->cur_tx, cep->tx_free,
 		       cep->cur_rx);
 		bdp = cep->tx_bd_base;
 		printk(" Tx @base %p :\n", bdp);
@@ -265,7 +263,7 @@
 			       bdp->cbd_bufaddr);
 	}
 #endif
-	if (!cep->tx_full)
+	if (cep->tx_free)
 		netif_wake_queue(dev);
 }
 
@@ -309,7 +307,7 @@
 	    spin_lock(&cep->lock);
 	    bdp = cep->dirty_tx;
 	    while ((bdp->cbd_sc&BD_ENET_TX_READY)==0) {
-		if ((bdp==cep->cur_tx) && (cep->tx_full == 0))
+		if (cep->tx_free == TX_RING_SIZE)
 		    break;
 
 		if (bdp->cbd_sc & BD_ENET_TX_HB)	/* No heartbeat */
@@ -365,8 +363,7 @@
 		/* Since we have freed up a buffer, the ring is no longer
 		 * full.
 		 */
-		if (cep->tx_full) {
-			cep->tx_full = 0;
+		if (!cep->tx_free++) {
 			if (netif_queue_stopped(dev)) {
 				netif_wake_queue(dev);
 			}
@@ -395,13 +392,10 @@
 	}
 
 	/* Check for receive busy, i.e. packets coming but no place to
-	 * put them.  This "can't happen" because the receive interrupt
-	 * is tossing previous frames.
+	 * put them.
 	 */
-	if (int_events & SCCE_ENET_BSY) {
+	if (int_events & SCCE_ENET_BSY)
 		cep->stats.rx_dropped++;
-		printk("SCC ENET: BSY can't happen.\n");
-	}
 
 	return;
 }
@@ -429,7 +423,7 @@
 for (;;) {
 	if (bdp->cbd_sc & BD_ENET_RX_EMPTY)
 		break;
-		
+
 #ifndef final_version
 	/* Since we have allocated space to hold a complete frame, both
 	 * the first and last indicators should be set.
@@ -549,7 +543,7 @@
 	ep = (scc_enet_t *)dev->base_addr;
 
 	if (dev->flags&IFF_PROMISC) {
-	  
+
 		/* Log any net taps. */
 		printk("%s: Promiscuous mode enabled.\n", dev->name);
 		cep->sccp->scc_pmsr |= SCC_PSMR_PRO;
@@ -576,8 +570,8 @@
 
 			dmi = dev->mc_list;
 
-			for (i=0; i<dev->mc_count; i++) {
-				
+			for (i=0; i<dev->mc_count; i++, dmi = dmi->next) {
+
 				/* Only support group multicast for now.
 				*/
 				if (!(dmi->dmi_addr[0] & 1))
@@ -664,7 +658,7 @@
 		(PC_ENET_RENA | PC_ENET_CLSN | PC_ENET_TXCLK | PC_ENET_RXCLK);
 	io->iop_pdirc &=
 		~(PC_ENET_RENA | PC_ENET_CLSN | PC_ENET_TXCLK | PC_ENET_RXCLK);
-	io->iop_psorc &= 
+	io->iop_psorc &=
 		~(PC_ENET_RENA | PC_ENET_TXCLK | PC_ENET_RXCLK);
 	io->iop_psorc |= PC_ENET_CLSN;
 
@@ -693,6 +687,7 @@
 	cep->tx_bd_base = (cbd_t *)&immap->im_dprambase[i];
 
 	cep->dirty_tx = cep->cur_tx = cep->tx_bd_base;
+	cep->tx_free = TX_RING_SIZE;
 	cep->cur_rx = cep->rx_bd_base;
 
 	ep->sen_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/8260_io/fcc_enet.c linux-2.4.22-pre10/arch/ppc/8260_io/fcc_enet.c
--- linux-2.4.21/arch/ppc/8260_io/fcc_enet.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/8260_io/fcc_enet.c	2003-08-01 13:33:10.000000000 +0000
@@ -551,7 +551,7 @@
 for (;;) {
 	if (bdp->cbd_sc & BD_ENET_RX_EMPTY)
 		break;
-		
+
 #ifndef final_version
 	/* Since we have allocated space to hold a complete frame, both
 	 * the first and last indicators should be set.
@@ -662,7 +662,7 @@
 	ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec);
 	mii_reg = ep->fec_mii_data;
 #endif
-	
+
 	if ((mip = mii_head) == NULL) {
 		printk("MII and no head!\n");
 		return;
@@ -1007,7 +1007,7 @@
 	ep = (fcc_enet_t *)dev->base_addr;
 
 	if (dev->flags&IFF_PROMISC) {
-	  
+
 		/* Log any net taps. */
 		printk("%s: Promiscuous mode enabled.\n", dev->name);
 		cep->fccp->fcc_fpsmr |= FCC_PSMR_PRO;
@@ -1030,8 +1030,8 @@
 
 			dmi = dev->mc_list;
 
-			for (i=0; i<dev->mc_count; i++) {
-				
+			for (i=0; i<dev->mc_count; i++, dmi = dmi->next) {
+
 				/* Only support group multicast for now.
 				*/
 				if (!(dmi->dmi_addr[0] & 1))
@@ -1280,7 +1280,7 @@
 	ep->fen_genfcc.fcc_tiptr = mem_addr+32;
 	ep->fen_padptr = mem_addr+64;
 	memset((char *)(&(immap->im_dprambase[(mem_addr+64)])), 0x88, 32);
-	
+
 	ep->fen_genfcc.fcc_rbptr = 0;
 	ep->fen_genfcc.fcc_tbptr = 0;
 	ep->fen_genfcc.fcc_rcrc = 0;
@@ -1491,7 +1491,7 @@
 	 * updates of the registers.  I do lots of interrupt disable/enable
 	 * to ensure we don't hang out too long with interrupts disabled.
 	 */
-	
+
 	/* First, crank out 32 1-bits as preamble.
 	 * This is 64 transitions to clock the bits, with clock/data
 	 * left high.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/8260_io/uart.c linux-2.4.22-pre10/arch/ppc/8260_io/uart.c
--- linux-2.4.21/arch/ppc/8260_io/uart.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/8260_io/uart.c	2003-08-01 13:31:01.000000000 +0000
@@ -83,7 +83,7 @@
 #undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
 
 #define _INLINE_ inline
-  
+
 #define DBG_CNT(s)
 
 /* We overload some of the items in the data structure to meet our
@@ -233,7 +233,7 @@
 
 	if (serial_paranoia_check(info, tty->device, "rs_stop"))
 		return;
-	
+
 	save_flags(flags); cli();
 	if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
 		smcp = &immr->im_smc[idx];
@@ -256,7 +256,7 @@
 
 	if (serial_paranoia_check(info, tty->device, "rs_stop"))
 		return;
-	
+
 	save_flags(flags); cli();
 	if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
 		smcp = &immr->im_smc[idx];
@@ -281,7 +281,7 @@
  * rs_interrupt() should try to keep the interrupt handler as fast as
  * possible.  After you are done making modifications, it is not a bad
  * idea to do:
- * 
+ *
  * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
  *
  * and look at the resulting assemble code in serial.s.
@@ -390,7 +390,7 @@
 				}
 				 */
 				status &= info->read_status_mask;
-		
+
 				if (status & (BD_SC_BR)) {
 #ifdef SERIAL_DEBUG_INTR
 					printk("handling break....");
@@ -444,7 +444,7 @@
 
 static _INLINE_ void transmit_chars(ser_info_t *info)
 {
-	
+
 	if (info->flags & TX_WAKEUP) {
 		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
 	}
@@ -461,7 +461,7 @@
 {
 	int	status;
 	struct	async_icount *icount;
-	
+
 	status = serial_in(info, UART_MSR);
 
 	if (status & UART_MSR_ANY_DELTA) {
@@ -488,7 +488,7 @@
 #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
 		printk("ttys%d CD now %s...", info->line,
 		       (status & UART_MSR_DCD) ? "on" : "off");
-#endif		
+#endif
 		if (status & UART_MSR_DCD)
 			wake_up_interruptible(&info->open_wait);
 		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
@@ -537,7 +537,7 @@
 	ser_info_t *info;
 	volatile smc_t	*smcp;
 	volatile scc_t	*sccp;
-	
+
 	info = (ser_info_t *)dev_id;
 
 	if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
@@ -558,7 +558,7 @@
 			transmit_chars(info);
 		sccp->scc_scce = events;
 	}
-	
+
 #ifdef SERIAL_DEBUG_INTR
 	printk("rs_interrupt_single(%d, %x)...",
 					info->state->smc_scc_num, events);
@@ -597,7 +597,7 @@
 {
 	ser_info_t	*info = (ser_info_t *) private_;
 	struct tty_struct	*tty;
-	
+
 	tty = info->tty;
 	if (!tty)
 		return;
@@ -617,13 +617,13 @@
  *
  * 	serial interrupt routine -> (scheduler tqueue) ->
  * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
- * 
+ *
  */
 static void do_serial_hangup(void *private_)
 {
 	struct async_struct	*info = (struct async_struct *) private_;
 	struct tty_struct	*tty;
-	
+
 	tty = info->tty;
 	if (tty)
 		tty_hangup(tty);
@@ -672,7 +672,7 @@
 	if (info->tty->termios->c_cflag & CBAUD)
 		info->MCR = UART_MCR_DTR | UART_MCR_RTS;
 #endif
-	
+
 	if (info->tty)
 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
 
@@ -680,7 +680,7 @@
 	 * and set the speed of the serial port
 	 */
 	change_speed(info);
-	
+
 	if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
 		smcp = &immr->im_smc[idx];
 
@@ -725,7 +725,7 @@
 	info->flags |= ASYNC_INITIALIZED;
 	restore_flags(flags);
 	return 0;
-	
+
 errout:
 	restore_flags(flags);
 	return retval;
@@ -752,7 +752,7 @@
 	printk("Shutting down serial port %d (irq %d)....", info->line,
 	       state->irq);
 #endif
-	
+
 	save_flags(flags); cli(); /* Disable interrupts */
 
 	if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) {
@@ -774,7 +774,7 @@
 		sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
 		sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
 	}
-	
+
 	if (info->tty)
 		set_bit(TTY_IO_ERROR, &info->tty->flags);
 
@@ -872,7 +872,7 @@
 		info->read_status_mask |= BD_SC_FR | BD_SC_PR;
 	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
 		info->read_status_mask |= BD_SC_BR;
-	
+
 	/*
 	 * Characters to ignore
 	 */
@@ -882,7 +882,7 @@
 	if (I_IGNBRK(info->tty)) {
 		info->ignore_status_mask |= BD_SC_BR;
 		/*
-		 * If we're ignore parity and break indicators, ignore 
+		 * If we're ignore parity and break indicators, ignore
 		 * overruns too.  (For real raw support).
 		 */
 		if (I_IGNPAR(info->tty))
@@ -907,9 +907,9 @@
 		 * enables, because we want to put them back if they were
 		 * present.
 		 */
-		prev_mode = smcp->smc_smcmr;
-		smcp->smc_smcmr = smcr_mk_clen(bits) | cval |  SMCMR_SM_UART;
-		smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN));
+		prev_mode = smcp->smc_smcmr & (SMCMR_REN | SMCMR_TEN);
+		smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART
+			| prev_mode;
 	}
 	else {
 		sccp = &immr->im_scc[idx - SCC_IDX_BASE];
@@ -960,7 +960,7 @@
 	if (serial_paranoia_check(info, tty->device, "rs_write"))
 		return 0;
 
-	if (!tty) 
+	if (!tty)
 		return 0;
 
 	bdp = info->tx_cur;
@@ -1028,7 +1028,7 @@
 static int rs_8xx_chars_in_buffer(struct tty_struct *tty)
 {
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
 		return 0;
 	return 0;
@@ -1037,7 +1037,7 @@
 static void rs_8xx_flush_buffer(struct tty_struct *tty)
 {
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
 		return;
 
@@ -1084,7 +1084,7 @@
 /*
  * ------------------------------------------------------------
  * rs_throttle()
- * 
+ *
  * This routine is called by the upper-layer tty layer to signal that
  * incoming characters should be throttled.
  * ------------------------------------------------------------
@@ -1094,14 +1094,14 @@
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
-	
+
 	printk("throttle %s: %d....\n", _tty_name(tty, buf),
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
 		return;
-	
+
 	if (I_IXOFF(tty))
 		rs_8xx_send_xchar(tty, STOP_CHAR(tty));
 
@@ -1120,14 +1120,14 @@
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
-	
+
 	printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
 		return;
-	
+
 	if (I_IXOFF(tty)) {
 		if (info->x_char)
 			info->x_char = 0;
@@ -1158,7 +1158,7 @@
  * 	    release the bus after transmitting. This must be done when
  * 	    the transmit shift register is empty, not be done when the
  * 	    transmit holding register is empty.  This functionality
- * 	    allows an RS485 driver to be written in user space. 
+ * 	    allows an RS485 driver to be written in user space.
  */
 static int get_lsr_info(struct async_struct * info, unsigned int *value)
 {
@@ -1208,7 +1208,7 @@
 		return error;
 #ifdef modem_control
 	switch (cmd) {
-	case TIOCMBIS: 
+	case TIOCMBIS:
 		if (arg & TIOCM_RTS)
 			info->MCR |= UART_MCR_RTS;
 		if (arg & TIOCM_DTR)
@@ -1383,7 +1383,7 @@
 		if (tty->flags & (1 << TTY_IO_ERROR))
 		    return -EIO;
 	}
-	
+
 	switch (cmd) {
 		case TCSBRK:	/* SVID version: non-zero arg --> no break */
 			retval = tty_check_change(tty);
@@ -1462,7 +1462,7 @@
 				cli();
 				cnow = info->state->icount; /* atomic copy */
 				sti();
-				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
+				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
 				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
 					return -EIO; /* no change => error */
 				if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
@@ -1478,7 +1478,7 @@
 			return 0;
 #endif
 
-		/* 
+		/*
 		 * 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
@@ -1512,7 +1512,7 @@
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 
 	if (   (tty->termios->c_cflag == old_termios->c_cflag)
-	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
+	    && (   RELEVANT_IFLAG(tty->termios->c_iflag)
 		== RELEVANT_IFLAG(old_termios->c_iflag)))
 	  return;
 
@@ -1527,7 +1527,7 @@
 		serial_out(info, UART_MCR, info->MCR);
 		sti();
 	}
-	
+
 	/* Handle transition away from B0 status */
 	if (!(old_termios->c_cflag & CBAUD) &&
 	    (tty->termios->c_cflag & CBAUD)) {
@@ -1540,7 +1540,7 @@
 		serial_out(info, UART_MCR, info->MCR);
 		sti();
 	}
-	
+
 	/* Handle turning off CRTSCTS */
 	if ((old_termios->c_cflag & CRTSCTS) &&
 	    !(tty->termios->c_cflag & CRTSCTS)) {
@@ -1565,7 +1565,7 @@
 /*
  * ------------------------------------------------------------
  * rs_close()
- * 
+ *
  * This routine is called when the serial port gets closed.  First, we
  * wait for the last remaining data to be sent.  Then, we unlink its
  * async structure from the interrupt chain if necessary, and we free
@@ -1585,16 +1585,16 @@
 		return;
 
 	state = info->state;
-	
+
 	save_flags(flags); cli();
-	
+
 	if (tty_hung_up_p(filp)) {
 		DBG_CNT("before DEC-hung");
 		MOD_DEC_USE_COUNT;
 		restore_flags(flags);
 		return;
 	}
-	
+
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
 #endif
@@ -1631,7 +1631,7 @@
 	if (info->flags & ASYNC_CALLOUT_ACTIVE)
 		info->state->callout_termios = *tty->termios;
 	/*
-	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * Now we wait for the transmit buffer to clear; and we notify
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
@@ -1693,7 +1693,7 @@
 	unsigned long orig_jiffies, char_time;
 	/*int lsr;*/
 	volatile cbd_t *bdp;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
 		return;
 
@@ -1707,7 +1707,7 @@
 	 * Set the check interval to be 1/5 of the estimated time to
 	 * send a single character, and make it at least 1.  The check
 	 * interval should also be less than the timeout.
-	 * 
+	 *
 	 * Note: we have to use pretty tight timings here to satisfy
 	 * the NIST-PCTS.
 	 */
@@ -1750,12 +1750,12 @@
 {
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 	struct serial_state *state = info->state;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
 		return;
 
 	state = info->state;
-	
+
 	rs_8xx_flush_buffer(tty);
 	shutdown(info);
 	info->event = 0;
@@ -1816,7 +1816,7 @@
 		info->flags |= ASYNC_CALLOUT_ACTIVE;
 		return 0;
 	}
-	
+
 	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
@@ -1839,7 +1839,7 @@
 		if (tty->termios->c_cflag & CLOCAL)
 			do_clocal = 1;
 	}
-	
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1855,7 +1855,7 @@
 	       state->line, state->count);
 #endif
 	cli();
-	if (!tty_hung_up_p(filp)) 
+	if (!tty_hung_up_p(filp))
 		state->count--;
 	sti();
 	info->blocked_open++;
@@ -1874,7 +1874,7 @@
 			if (info->flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
-				retval = -ERESTARTSYS;	
+				retval = -ERESTARTSYS;
 #else
 			retval = -EAGAIN;
 #endif
@@ -1974,7 +1974,7 @@
 	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
 		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
 			*tty->termios = info->state->normal_termios;
-		else 
+		else
 			*tty->termios = info->state->callout_termios;
 		change_speed(info);
 	}
@@ -2027,7 +2027,7 @@
 	status = serial_in(info, UART_MSR);
 	control = info ? info->MCR : serial_in(info, UART_MCR);
 	sti();
-	
+
 	stat_buf[0] = 0;
 	stat_buf[1] = 0;
 	if (control & UART_MCR_RTS)
@@ -2053,12 +2053,12 @@
 
 	if (state->icount.frame)
 		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
-	
+
 	if (state->icount.parity)
 		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
-	
+
 	if (state->icount.brk)
-		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);	
+		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);
 
 	if (state->icount.overrun)
 		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
@@ -2177,7 +2177,7 @@
 		/* Send the character out. */
 		cp = __va(bdp->cbd_bufaddr);
 		*cp = *s;
-		
+
 		bdp->cbd_datlen = 1;
 		bdp->cbd_sc |= BD_SC_READY;
 
@@ -2262,13 +2262,13 @@
 	volatile	scc_uart_t	*sup;
 	volatile	immap_t		*immap;
 	volatile	iop8260_t	*io;
-	
+
 	init_bh(SERIAL_BH, do_serial_bh);
 
 	show_serial_version();
 
 	/* Initialize the tty_driver structure */
-	
+
 	/*memset(&serial_driver, 0, sizeof(struct tty_driver));*/
 	__clear_user(&serial_driver,sizeof(struct tty_driver));
 	serial_driver.magic = TTY_DRIVER_MAGIC;
@@ -2309,7 +2309,7 @@
 	serial_driver.hangup = rs_8xx_hangup;
 	serial_driver.wait_until_sent = rs_8xx_wait_until_sent;
 	serial_driver.read_proc = rs_8xx_read_proc;
-	
+
 	/*
 	 * The callout device is just like normal device except for
 	 * major number and the subtype code.
@@ -2329,7 +2329,7 @@
 		panic("Couldn't register serial driver\n");
 	if (tty_register_driver(&callout_driver))
 		panic("Couldn't register callout driver\n");
-	
+
 	immap = immr;
 	cp = &immap->im_cpm;
 	io = &immap->im_ioport;
@@ -2390,7 +2390,7 @@
 		state->closing_wait = 30*HZ;
 		state->callout_termios = callout_driver.init_termios;
 		state->normal_termios = serial_driver.init_termios;
-		state->icount.cts = state->icount.dsr = 
+		state->icount.cts = state->icount.dsr =
 			state->icount.rng = state->icount.dcd = 0;
 		state->icount.rx = state->icount.tx = 0;
 		state->icount.frame = state->icount.parity = 0;
@@ -2577,7 +2577,7 @@
 				 * Enable receive and transmit.
 				 */
 				scp->scc_gsmrh = 0;
-				scp->scc_gsmrl = 
+				scp->scc_gsmrl =
 					(SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
 
 				/* Disable all interrupts and clear all pending
@@ -2636,7 +2636,7 @@
 
 	ser = rs_table + co->index;
 
-	
+
 	immap = immr;
 	cp = &immap->im_cpm;
 	io = &immap->im_ioport;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/8xx_io/enet.c linux-2.4.22-pre10/arch/ppc/8xx_io/enet.c
--- linux-2.4.21/arch/ppc/8xx_io/enet.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/8xx_io/enet.c	2003-08-01 13:32:06.000000000 +0000
@@ -229,7 +229,7 @@
 
 	cep->stats.tx_bytes += skb->len;
 	cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK;
-	
+
 	/* Push the data cache so the CPM does not get stale memory
 	 * data.
 	 */
@@ -447,7 +447,7 @@
 for (;;) {
 	if (bdp->cbd_sc & BD_ENET_RX_EMPTY)
 		break;
-		
+
 #ifndef final_version
 	/* Since we have allocated space to hold a complete frame, both
 	 * the first and last indicators should be set.
@@ -567,7 +567,7 @@
 	ep = (scc_enet_t *)dev->base_addr;
 
 	if (dev->flags&IFF_PROMISC) {
-	  
+
 		/* Log any net taps. */
 		printk("%s: Promiscuous mode enabled.\n", dev->name);
 		cep->sccp->scc_pmsr |= SCC_PMSR_PRO;
@@ -594,8 +594,8 @@
 
 			dmi = dev->mc_list;
 
-			for (i=0; i<dev->mc_count; i++) {
-				
+			for (i=0; i<dev->mc_count; i++, dmi = dmi->next) {
+
 				/* Only support group multicast for now.
 				*/
 				if (!(dmi->dmi_addr[0] & 1))
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/8xx_io/fec.c linux-2.4.22-pre10/arch/ppc/8xx_io/fec.c
--- linux-2.4.21/arch/ppc/8xx_io/fec.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/8xx_io/fec.c	2003-08-01 13:32:48.000000000 +0000
@@ -163,7 +163,7 @@
 	cbd_t	*dirty_tx;	/* The ring entries to be free()ed. */
 	scc_t	*sccp;
 	struct	net_device_stats stats;
-	uint	tx_full;
+	uint	tx_free;
 	spinlock_t lock;
 
 #ifdef	CONFIG_USE_MDIO
@@ -229,6 +229,7 @@
 mii_list_t	*mii_free;
 mii_list_t	*mii_head;
 mii_list_t	*mii_tail;
+int         mii_stopped;
 
 typedef struct mdio_read_data {
 	u16 regval;
@@ -295,18 +296,13 @@
 	fep = dev->priv;
 	fecp = (volatile fec_t*)dev->base_addr;
 
-	if (!fep->link) {
-		/* Link is down or autonegotiation is in progress. */
-		return 1;
-	}
-
 	/* Fill in a Tx ring entry */
 	bdp = fep->cur_tx;
 
 #ifndef final_version
-	if (bdp->cbd_sc & BD_ENET_TX_READY) {
+	if (!fep->tx_free || (bdp->cbd_sc & BD_ENET_TX_READY)) {
 		/* Ooops.  All transmit buffers are full.  Bail out.
-		 * This should not happen, since dev->tbusy should be set.
+		 * This should not happen, since the tx queue should be stopped.
 		 */
 		printk("%s: tx queue full!.\n", dev->name);
 		return 1;
@@ -357,10 +353,8 @@
 		bdp++;
 	}
 
-	if (bdp->cbd_sc & BD_ENET_TX_READY) {
+	if (!--fep->tx_free)
 		netif_stop_queue(dev);
-		fep->tx_full = 1;
-	}
 
 	fep->cur_tx = (cbd_t *)bdp;
 
@@ -381,8 +375,8 @@
 	int	i;
 	cbd_t	*bdp;
 
-	printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n",
-	       (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "",
+	printk("Ring data dump: cur_tx %lx, tx_free %d, dirty_tx %lx, cur_rx %lx\n",
+	       (unsigned long)fep->cur_tx, fep->tx_free,
 	       (unsigned long)fep->dirty_tx,
 	       (unsigned long)fep->cur_rx);
 
@@ -409,7 +403,7 @@
 	}
 	}
 #endif
-	if (!fep->tx_full)
+	if (fep->tx_free)
 		netif_wake_queue(dev);
 }
 
@@ -469,7 +463,7 @@
 	bdp = fep->dirty_tx;
 
 	while ((bdp->cbd_sc&BD_ENET_TX_READY) == 0) {
-		if (bdp == fep->cur_tx && fep->tx_full == 0) break;
+		if (fep->tx_free == TX_RING_SIZE) break;
 
 		skb = fep->tx_skbuff[fep->skb_dirty];
 		/* Check for errors. */
@@ -519,8 +513,7 @@
 		/* Since we have freed up a buffer, the ring is no longer
 		 * full.
 		 */
-		if (fep->tx_full) {
-			fep->tx_full = 0;
+		if (!fep->tx_free++) {
 			if (netif_queue_stopped(dev))
 				netif_wake_queue(dev);
 		}
@@ -668,6 +661,12 @@
 	ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec);
 	mii_reg = ep->fec_mii_data;
 
+	/* Ignore this answer if the request queue has been stopped.
+	 * The request will be re-issued when the queue is restarted.
+	 */
+	if (mii_stopped)
+		return;
+
 	if ((mip = mii_head) == NULL) {
 		printk("MII and no head!\n");
 		return;
@@ -714,7 +713,8 @@
 			mii_tail = mip;
 		} else {
 			mii_head = mii_tail = mip;
-			(&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec))->fec_mii_data = regval;
+			if (!mii_stopped)
+				(&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec))->fec_mii_data = regval;
 		}
 	} else {
 		retval = 1;
@@ -725,6 +725,30 @@
 	return(retval);
 }
 
+/* Functions to stop/start the transmission of requests through the MDIO.
+ * They are intended to be used before and after a FEC reset.
+ */
+static void stop_mii_queue(struct net_device *dev)
+{
+	unsigned long flags;
+	save_flags(flags);
+	cli();
+	mii_stopped = 1;
+	restore_flags(flags);
+}
+
+static void start_mii_queue(struct net_device *dev)
+{
+	unsigned long flags;
+	volatile fec_t *ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec);
+	save_flags(flags);
+	cli();
+	mii_stopped = 0;
+	if(mii_head)
+		ep->fec_mii_data = mii_head->mii_regval;
+	restore_flags(flags);
+}
+
 static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c)
 {
 	int k;
@@ -995,7 +1019,7 @@
 		{ mk_mii_end, }
 	},
 	(const phy_cmd_t []) {  /* startup - enable interrupts */
-		{ mk_mii_write(MII_QS6612_IMR, 0x003a), NULL },
+		{ mk_mii_write(MII_QS6612_IMR, 0x0050), NULL },
 		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
 		{ mk_mii_end, }
 	},
@@ -1060,7 +1084,7 @@
 	0x020005c1,
 	"DP83843BVJE",
 
-	(const phy_cmd_t []) {  /* config */  
+	(const phy_cmd_t []) {  /* config */
 		{ mk_mii_write(MII_REG_ANAR, 0x01E1), NULL  }, /* Auto-Negociation Register Control set to    */
 		                                               /* auto-negociate 10/100MBps, Half/Full duplex */
 		{ mk_mii_read(MII_REG_CR),   mii_parse_cr   },
@@ -1132,7 +1156,7 @@
 	0x020005c2,
 	"DP83846A",
 
-	(const phy_cmd_t []) {  /* config */  
+	(const phy_cmd_t []) {  /* config */
 		{ mk_mii_write(MII_REG_ANAR, 0x01E1), NULL  }, /* Auto-Negociation Register Control set to    */
 		                                               /* auto-negociate 10/100MBps, Half/Full duplex */
 		{ mk_mii_read(MII_REG_CR),   mii_parse_cr   },
@@ -1367,31 +1391,20 @@
 #ifdef	CONFIG_USE_MDIO
 	struct	net_device *dev = dev_id;
 	struct fec_enet_private *fep = dev->priv;
-	volatile immap_t *immap = (immap_t *)IMAP_ADDR;
-	volatile fec_t *fecp = &(immap->im_cpm.cp_fec);
-	unsigned int ecntrl = fecp->fec_ecntrl;
-
-	/* We need the FEC enabled to access the MII
-	*/
-	if ((ecntrl & FEC_ECNTRL_ETHER_EN) == 0) {
-		fecp->fec_ecntrl |= FEC_ECNTRL_ETHER_EN;
-	}
-#endif	/* CONFIG_USE_MDIO */
-
-#if 0
-	disable_irq(fep->mii_irq);  /* disable now, enable later */
-#endif
 
-
-#ifdef	CONFIG_USE_MDIO
-	mii_do_cmd(dev, fep->phy->ack_int);
-	mii_do_cmd(dev, phy_cmd_relink);  /* restart and display status */
-
-	if ((ecntrl & FEC_ECNTRL_ETHER_EN) == 0) {
-		fecp->fec_ecntrl = ecntrl;	/* restore old settings */
+	/*
+	 * Acknowledge the interrupt if possible. If we have not
+	 * found the PHY yet we can't process or acknowledge the
+	 * interrupt now. Instead we ignore this interrupt for now,
+	 * which we can do since it is edge triggered. It will be
+	 * acknowledged later by fec_enet_open().
+	 */
+	if (fep->phy) {
+		mii_do_cmd(dev, fep->phy->ack_int);
+		mii_do_cmd(dev, phy_cmd_relink);  /* restart and display status */
 	}
 #else
-printk("%s[%d] %s: unexpected Link interrupt\n", __FILE__,__LINE__,__FUNCTION__);
+	printk ("FEC: unexpected Link interrupt\n");
 #endif	/* CONFIG_USE_MDIO */
 
 }
@@ -1422,7 +1435,7 @@
 		{
 			/* Initializing timers
 			 */
-			init_timer( &fep->phy_timer_list ); 
+			init_timer( &fep->phy_timer_list );
 
 			/* Starting timer for periodic link status check
 			 * After 100 milli-seconds, mdio_timer_callback function is called.
@@ -1492,7 +1505,7 @@
 	{
 		fep->phy_timer_list.expires  = jiffies + (1 * HZ); /* Sleep for 1 sec. */
 	}
-	add_timer( &fep->phy_timer_list ); 
+	add_timer( &fep->phy_timer_list );
 }
 #endif /* CONFIG_FEC_DP83846A */
 
@@ -1540,7 +1553,7 @@
 	else
 	{
 		switch(cmd)
-		{						
+		{
 		case SIOCETHTOOL:
 			return netdev_ethtool_ioctl(dev, (void*)rq->ifr_data);
 			break;
@@ -1571,7 +1584,7 @@
 		default:
 			retval = -EOPNOTSUPP;
 			break;
-		}		
+		}
 	}
 	return retval;
 }
@@ -1652,7 +1665,7 @@
 
 			dmi = dev->mc_list;
 
-			for (i=0; i<dev->mc_count; i++) {
+			for (i=0; i<dev->mc_count; i++, dmi = dmi->next) {
 
 				/* Only support group multicast for now.
 				*/
@@ -1927,6 +1940,11 @@
 
 	fep = dev->priv;
 
+#ifdef CONFIG_USE_MDIO
+	/* Stop the MDIO communication prior to reset. */
+	stop_mii_queue(dev);
+#endif
+
 	/* Whack a reset.  We should wait for this.
 	*/
 	fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
@@ -1960,6 +1978,7 @@
 	fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
 
 	fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
+	fep->tx_free = TX_RING_SIZE;
 	fep->cur_rx = fep->rx_bd_base;
 
 	/* Reset SKB transmit buffers.
@@ -2043,12 +2062,10 @@
 	fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
 	fecp->fec_r_des_active = 0x01000000;
 
-	/* The tx ring is no longer full. */
-	if(fep->tx_full)
-	{
-		fep->tx_full = 0;
-		netif_wake_queue(dev);
-	}
+#ifdef CONFIG_USE_MDIO
+	/* Re-start any pending MDIO communication. */
+	start_mii_queue(dev);
+#endif
 }
 
 static void
@@ -2080,22 +2097,7 @@
 		printk ("FEC timeout on graceful transmit stop\n");
 	}
 
-	/* Clear outstanding MII command interrupts.
-	*/
-	fecp->fec_ievent = FEC_ENET_MII;
-
-	/* Enable MII command finished interrupt
-	*/
-	fecp->fec_ivec = (FEC_INTERRUPT/2) << 29;
+	/* Disable FEC. Let only MII interrupts. */
 	fecp->fec_imask = FEC_ENET_MII;
-
-#ifdef	CONFIG_USE_MDIO
-	/* Set MII speed.
-	*/
-	fecp->fec_mii_speed = fep->phy_speed;
-#endif	/* CONFIG_USE_MDIO */
-
-	/* Disable FEC
-	*/
 	fecp->fec_ecntrl &= ~(FEC_ECNTRL_ETHER_EN);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/8xx_io/uart.c linux-2.4.22-pre10/arch/ppc/8xx_io/uart.c
--- linux-2.4.21/arch/ppc/8xx_io/uart.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/8xx_io/uart.c	2003-08-01 13:34:04.000000000 +0000
@@ -112,7 +112,7 @@
 #undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
 
 #define _INLINE_ inline
-  
+
 #define DBG_CNT(s)
 
 /* We overload some of the items in the data structure to meet our
@@ -281,7 +281,7 @@
 
 	if (serial_paranoia_check(info, tty->device, "rs_stop"))
 		return;
-	
+
 	save_flags(flags); cli();
 	idx = PORT_NUM(info->state->smc_scc_num);
 	if (PORT_IS_SCC(info->state->smc_scc_num)) {
@@ -305,7 +305,7 @@
 
 	if (serial_paranoia_check(info, tty->device, "rs_stop"))
 		return;
-	
+
 	idx = PORT_NUM(info->state->smc_scc_num);
 	save_flags(flags); cli();
 	if (PORT_IS_SCC(info->state->smc_scc_num)) {
@@ -331,7 +331,7 @@
  * rs_interrupt() should try to keep the interrupt handler as fast as
  * possible.  After you are done making modifications, it is not a bad
  * idea to do:
- * 
+ *
  * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
  *
  * and look at the resulting assemble code in serial.s.
@@ -477,7 +477,7 @@
 			}
 #if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 			if (break_pressed && info->line == sercons.index) {
-				if (ch != 0 && time_before(jiffies, 
+				if (ch != 0 && time_before(jiffies,
 							break_pressed + HZ*5)) {
 					handle_sysrq(ch, regs, NULL, NULL);
 					break_pressed = 0;
@@ -495,7 +495,7 @@
 		}
 
 #if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-	ignore_char:	
+	ignore_char:
 #endif
 		/* This BD is ready to be used again.  Clear status.
 		 * Get next BD.
@@ -543,7 +543,7 @@
 
 static _INLINE_ void transmit_chars(ser_info_t *info, struct pt_regs *regs)
 {
-	
+
 	if ((info->flags & TX_WAKEUP) ||
 	    (info->tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) {
 		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
@@ -561,7 +561,7 @@
 {
 	int	status;
 	struct	async_icount *icount;
-	
+
 	status = serial_in(info, UART_MSR);
 
 	if (status & UART_MSR_ANY_DELTA) {
@@ -588,7 +588,7 @@
 #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
 		printk("ttys%d CD now %s...", info->line,
 		       (status & UART_MSR_DCD) ? "on" : "off");
-#endif		
+#endif
 		if (status & UART_MSR_DCD)
 			wake_up_interruptible(&info->open_wait);
 		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
@@ -637,7 +637,7 @@
 	ser_info_t *info;
 	volatile smc_t	*smcp;
 	volatile scc_t	*sccp;
-	
+
 	info = (ser_info_t *)dev_id;
 
 	idx = PORT_NUM(info->state->smc_scc_num);
@@ -663,7 +663,7 @@
 			transmit_chars(info, regs);
 		smcp->smc_smce = events;
 	}
-	
+
 #ifdef SERIAL_DEBUG_INTR
 	printk("rs_interrupt_single(%d, %x)...",
 					info->state->smc_scc_num, events);
@@ -702,7 +702,7 @@
 {
 	ser_info_t	*info = (ser_info_t *) private_;
 	struct tty_struct	*tty;
-	
+
 	tty = info->tty;
 	if (!tty)
 		return;
@@ -722,13 +722,13 @@
  *
  * 	serial interrupt routine -> (scheduler tqueue) ->
  * 	do_serial_hangup() -> tty->hangup() -> rs_hangup()
- * 
+ *
  */
 static void do_serial_hangup(void *private_)
 {
 	struct async_struct	*info = (struct async_struct *) private_;
 	struct tty_struct	*tty;
-	
+
 	tty = info->tty;
 	if (tty)
 		tty_hangup(tty);
@@ -777,7 +777,7 @@
 	if (info->tty->termios->c_cflag & CBAUD)
 		info->MCR = UART_MCR_DTR | UART_MCR_RTS;
 #endif
-	
+
 	if (info->tty)
 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
 
@@ -785,7 +785,7 @@
 	 * and set the speed of the serial port
 	 */
 	change_speed(info);
-	
+
 	idx = PORT_NUM(info->state->smc_scc_num);
 	if (PORT_IS_SCC(info->state->smc_scc_num)) {
 		sccp = &cpmp->cp_scc[idx];
@@ -820,7 +820,7 @@
 	info->flags |= ASYNC_INITIALIZED;
 	restore_flags(flags);
 	return 0;
-	
+
 errout:
 	restore_flags(flags);
 	return retval;
@@ -847,7 +847,7 @@
 	printk("Shutting down serial port %d (irq %d)....", info->line,
 	       state->irq);
 #endif
-	
+
 	save_flags(flags); cli(); /* Disable interrupts */
 
 	idx = PORT_NUM(state->smc_scc_num);
@@ -876,7 +876,7 @@
 #endif
 			smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
 	}
-	
+
 	if (info->tty)
 		set_bit(TTY_IO_ERROR, &info->tty->flags);
 
@@ -977,7 +977,7 @@
 		info->read_status_mask |= BD_SC_FR | BD_SC_PR;
 	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
 		info->read_status_mask |= BD_SC_BR;
-	
+
 	/*
 	 * Characters to ignore
 	 */
@@ -987,7 +987,7 @@
 	if (I_IGNBRK(info->tty)) {
 		info->ignore_status_mask |= BD_SC_BR;
 		/*
-		 * If we're ignore parity and break indicators, ignore 
+		 * If we're ignore parity and break indicators, ignore
 		 * overruns too.  (For real raw support).
 		 */
 		if (I_IGNPAR(info->tty))
@@ -1010,7 +1010,7 @@
 		sccp = &cpmp->cp_scc[idx];
 		new_mode = (sbits << 12) | scval;
 		prev_mode = sccp->scc_pmsr;
-		if (!(prev_mode & SCU_PMSR_PEN)) 
+		if (!(prev_mode & SCU_PMSR_PEN))
 			/* If parity is disabled, mask out even/odd */
 			prev_mode &= ~(SCU_PMSR_TPM|SCU_PMSR_RPM);
 		if (prev_mode != new_mode)
@@ -1023,9 +1023,9 @@
 		 * enables, because we want to put them back if they were
 		 * present.
 		 */
-		prev_mode = smcp->smc_smcmr;
-		new_mode = smcr_mk_clen(bits) | cval |  SMCMR_SM_UART;
-		new_mode |= (prev_mode & (SMCMR_REN | SMCMR_TEN));
+		prev_mode = smcp->smc_smcmr & (SMCMR_REN | SMCMR_TEN);
+		new_mode = smcr_mk_clen(bits) | cval | SMCMR_SM_UART
+			| prev_mode;
 		if (!(prev_mode & SMCMR_PEN))
 			/* If parity is disabled, mask out even/odd */
 			prev_mode &= ~SMCMR_PM_EVEN;
@@ -1075,7 +1075,7 @@
 	volatile cbd_t *bdp;
 
 #ifdef CONFIG_KGDB_CONSOLE
-        /* Try to let stub handle output. Returns true if it did. */ 
+        /* Try to let stub handle output. Returns true if it did. */
         if (kgdb_output_string(buf, count))
             return ret;
 #endif
@@ -1083,7 +1083,7 @@
 	if (serial_paranoia_check(info, tty->device, "rs_write"))
 		return 0;
 
-	if (!tty) 
+	if (!tty)
 		return 0;
 
 	bdp = info->tx_cur;
@@ -1151,7 +1151,7 @@
 static int rs_8xx_chars_in_buffer(struct tty_struct *tty)
 {
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
 		return 0;
 	return 0;
@@ -1160,7 +1160,7 @@
 static void rs_8xx_flush_buffer(struct tty_struct *tty)
 {
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
 		return;
 
@@ -1207,7 +1207,7 @@
 /*
  * ------------------------------------------------------------
  * rs_throttle()
- * 
+ *
  * This routine is called by the upper-layer tty layer to signal that
  * incoming characters should be throttled.
  * ------------------------------------------------------------
@@ -1217,14 +1217,14 @@
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
-	
+
 	printk("throttle %s: %d....\n", _tty_name(tty, buf),
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
 		return;
-	
+
 	if (I_IXOFF(tty))
 		rs_8xx_send_xchar(tty, STOP_CHAR(tty));
 
@@ -1243,14 +1243,14 @@
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 #ifdef SERIAL_DEBUG_THROTTLE
 	char	buf[64];
-	
+
 	printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
 		return;
-	
+
 	if (I_IXOFF(tty)) {
 		if (info->x_char)
 			info->x_char = 0;
@@ -1281,7 +1281,7 @@
  * 	    release the bus after transmitting. This must be done when
  * 	    the transmit shift register is empty, not be done when the
  * 	    transmit holding register is empty.  This functionality
- * 	    allows an RS485 driver to be written in user space. 
+ * 	    allows an RS485 driver to be written in user space.
  */
 static int get_lsr_info(struct async_struct * info, unsigned int *value)
 {
@@ -1331,7 +1331,7 @@
 		return error;
 #ifdef modem_control
 	switch (cmd) {
-	case TIOCMBIS: 
+	case TIOCMBIS:
 		if (arg & TIOCM_RTS)
 			info->MCR |= UART_MCR_RTS;
 		if (arg & TIOCM_DTR)
@@ -1464,7 +1464,7 @@
 		if (tty->flags & (1 << TTY_IO_ERROR))
 		    return -EIO;
 	}
-	
+
 	switch (cmd) {
 		case TCSBRK:	/* SVID version: non-zero arg --> no break */
 			retval = tty_check_change(tty);
@@ -1543,7 +1543,7 @@
 				cli();
 				cnow = info->state->icount; /* atomic copy */
 				sti();
-				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
+				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
 				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
 					return -EIO; /* no change => error */
 				if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
@@ -1559,7 +1559,7 @@
 			return 0;
 #endif
 
-		/* 
+		/*
 		 * 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
@@ -1593,7 +1593,7 @@
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 
 	if (   (tty->termios->c_cflag == old_termios->c_cflag)
-	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
+	    && (   RELEVANT_IFLAG(tty->termios->c_iflag)
 		== RELEVANT_IFLAG(old_termios->c_iflag)))
 	  return;
 
@@ -1608,7 +1608,7 @@
 		serial_out(info, UART_MCR, info->MCR);
 		sti();
 	}
-	
+
 	/* Handle transition away from B0 status */
 	if (!(old_termios->c_cflag & CBAUD) &&
 	    (tty->termios->c_cflag & CBAUD)) {
@@ -1621,7 +1621,7 @@
 		serial_out(info, UART_MCR, info->MCR);
 		sti();
 	}
-	
+
 	/* Handle turning off CRTSCTS */
 	if ((old_termios->c_cflag & CRTSCTS) &&
 	    !(tty->termios->c_cflag & CRTSCTS)) {
@@ -1646,7 +1646,7 @@
 /*
  * ------------------------------------------------------------
  * rs_close()
- * 
+ *
  * This routine is called when the serial port gets closed.  First, we
  * wait for the last remaining data to be sent.  Then, we unlink its
  * async structure from the interrupt chain if necessary, and we free
@@ -1666,16 +1666,16 @@
 		return;
 
 	state = info->state;
-	
+
 	save_flags(flags); cli();
-	
+
 	if (tty_hung_up_p(filp)) {
 		DBG_CNT("before DEC-hung");
 		MOD_DEC_USE_COUNT;
 		restore_flags(flags);
 		return;
 	}
-	
+
 #ifdef SERIAL_DEBUG_OPEN
 	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
 #endif
@@ -1712,7 +1712,7 @@
 	if (info->flags & ASYNC_CALLOUT_ACTIVE)
 		info->state->callout_termios = *tty->termios;
 	/*
-	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * Now we wait for the transmit buffer to clear; and we notify
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
@@ -1775,7 +1775,7 @@
 	unsigned long orig_jiffies, char_time;
 	/*int lsr;*/
 	volatile cbd_t *bdp;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
 		return;
 
@@ -1789,7 +1789,7 @@
 	 * Set the check interval to be 1/5 of the estimated time to
 	 * send a single character, and make it at least 1.  The check
 	 * interval should also be less than the timeout.
-	 * 
+	 *
 	 * Note: we have to use pretty tight timings here to satisfy
 	 * the NIST-PCTS.
 	 */
@@ -1843,12 +1843,12 @@
 {
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 	struct serial_state *state = info->state;
-	
+
 	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
 		return;
 
 	state = info->state;
-	
+
 	rs_8xx_flush_buffer(tty);
 	shutdown(info);
 	info->event = 0;
@@ -1909,7 +1909,7 @@
 		info->flags |= ASYNC_CALLOUT_ACTIVE;
 		return 0;
 	}
-	
+
 	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
@@ -1932,7 +1932,7 @@
 		if (tty->termios->c_cflag & CLOCAL)
 			do_clocal = 1;
 	}
-	
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -1948,7 +1948,7 @@
 	       state->line, state->count);
 #endif
 	cli();
-	if (!tty_hung_up_p(filp)) 
+	if (!tty_hung_up_p(filp))
 		state->count--;
 	sti();
 	info->blocked_open++;
@@ -1967,7 +1967,7 @@
 			if (info->flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
-				retval = -ERESTARTSYS;	
+				retval = -ERESTARTSYS;
 #else
 			retval = -EAGAIN;
 #endif
@@ -2068,7 +2068,7 @@
 	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
 		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
 			*tty->termios = info->state->normal_termios;
-		else 
+		else
 			*tty->termios = info->state->callout_termios;
 		change_speed(info);
 	}
@@ -2121,7 +2121,7 @@
 	status = serial_in(info, UART_MSR);
 	control = info ? info->MCR : serial_in(info, UART_MCR);
 	sti();
-	
+
 	stat_buf[0] = 0;
 	stat_buf[1] = 0;
 	if (control & UART_MCR_RTS)
@@ -2147,12 +2147,12 @@
 
 	if (state->icount.frame)
 		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
-	
+
 	if (state->icount.parity)
 		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
-	
+
 	if (state->icount.brk)
-		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);	
+		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);
 
 	if (state->icount.overrun)
 		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
@@ -2278,7 +2278,7 @@
 		else
 			cp = __va(bdp->cbd_bufaddr);
 		*cp = *s;
-		
+
 		bdp->cbd_datlen = 1;
 		bdp->cbd_sc |= BD_SC_READY;
 
@@ -2318,7 +2318,7 @@
 				unsigned count)
 {
 #ifdef CONFIG_KGDB_CONSOLE
-	/* Try to let stub handle output. Returns true if it did. */ 
+	/* Try to let stub handle output. Returns true if it did. */
 	if (kgdb_output_string(s, count))
 		return;
 #endif
@@ -2536,13 +2536,13 @@
 	volatile	scc_t		*scp;
 	volatile	scc_uart_t	*sup;
 	volatile	immap_t		*immap;
-	
+
 	init_bh(SERIAL_BH, do_serial_bh);
 
 	show_serial_version();
 
 	/* Initialize the tty_driver structure */
-	
+
 	__clear_user(&serial_driver,sizeof(struct tty_driver));
 	serial_driver.magic = TTY_DRIVER_MAGIC;
 	serial_driver.driver_name = "serial";
@@ -2582,7 +2582,7 @@
 	serial_driver.hangup = rs_8xx_hangup;
 	serial_driver.wait_until_sent = rs_8xx_wait_until_sent;
 	serial_driver.read_proc = rs_8xx_read_proc;
-	
+
 	/*
 	 * The callout device is just like normal device except for
 	 * major number and the subtype code.
@@ -2602,7 +2602,7 @@
 		panic("Couldn't register serial driver\n");
 	if (tty_register_driver(&callout_driver))
 		panic("Couldn't register callout driver\n");
-	
+
 	cp = cpmp;	/* Get pointer to Communication Processor */
 	immap = (immap_t *)IMAP_ADDR;	/* and to internal registers */
 
@@ -2663,7 +2663,7 @@
 		state->closing_wait = 30*HZ;
 		state->callout_termios = callout_driver.init_termios;
 		state->normal_termios = serial_driver.init_termios;
-		state->icount.cts = state->icount.dsr = 
+		state->icount.cts = state->icount.dsr =
 			state->icount.rng = state->icount.dcd = 0;
 		state->icount.rx = state->icount.tx = 0;
 		state->icount.frame = state->icount.parity = 0;
@@ -2800,7 +2800,7 @@
 				 * Enable receive and transmit.
 				 */
 				scp->scc_gsmrh = 0;
-				scp->scc_gsmrl = 
+				scp->scc_gsmrl =
 					(SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
 
 				/* Disable all interrupts and clear all pending
@@ -3028,7 +3028,7 @@
 		 * Enable receive and transmit.
 		 */
 		scp->scc_gsmrh = 0;
-		scp->scc_gsmrl = 
+		scp->scc_gsmrl =
 			(SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
 
 		/* Disable all interrupts and clear all pending
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/Makefile linux-2.4.22-pre10/arch/ppc/Makefile
--- linux-2.4.21/arch/ppc/Makefile	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/Makefile	2003-08-01 13:30:55.000000000 +0000
@@ -16,10 +16,6 @@
 # Be sure to change PAGE_OFFSET in include/asm-ppc/page.h to match
 KERNELLOAD	=0xc0000000
 
-ifeq ($(shell uname -m),ppc)
-CHECKS		= checks
-endif
-
 LINKFLAGS	= -T arch/ppc/vmlinux.lds -Ttext $(KERNELLOAD) -Bstatic
 CPPFLAGS	:= $(CPPFLAGS) -I$(TOPDIR)/arch/$(ARCH)
 AFLAGS		:= $(AFLAGS) -I$(TOPDIR)/arch/$(ARCH)
@@ -46,7 +42,7 @@
   CFLAGS += $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
 endif
 
-ifdef CONFIG_4xx
+ifdef CONFIG_40x
   HEAD := arch/ppc/kernel/head_4xx.o
 else
   ifdef CONFIG_8xx
@@ -99,7 +95,7 @@
 # All the instructions talk about "make bzImage".
 bzImage: zImage
 
-$(BOOT_TARGETS): $(CHECKS) vmlinux
+$(BOOT_TARGETS): vmlinux
 	@$(MAKEBOOT) $@
 
 %_config: arch/ppc/configs/%_defconfig
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/amiga/config.c linux-2.4.22-pre10/arch/ppc/amiga/config.c
--- linux-2.4.21/arch/ppc/amiga/config.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/amiga/config.c	2003-08-01 13:34:23.000000000 +0000
@@ -343,7 +343,7 @@
 
   case AMI_DRACO:
     panic("No support for Draco yet");
- 
+
   default:
     panic("Unknown Amiga Model");
   }
@@ -644,7 +644,7 @@
 		volatile struct tod2000 *tod = TOD_2000;
 
 		tod->cntrl1 = TOD2000_CNTRL1_HOLD;
-	    
+
 		while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
 			;
 
@@ -709,13 +709,13 @@
 		tod->second2 = real_seconds % 10;
 		tod->minute1 = real_minutes / 10;
 		tod->minute2 = real_minutes % 10;
-		
+
 		tod->cntrl1 = TOD3000_CNTRL1_FREE;
 	} else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ {
 		volatile struct tod2000 *tod = TOD_2000;
 
 		tod->cntrl1 = TOD2000_CNTRL1_HOLD;
-	    
+
 		while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
 			;
 
@@ -974,7 +974,7 @@
 		mach_get_model(model);
 	else
 		strcpy(model, "Unknown PowerPC");
-	
+
 	len += sprintf(buffer+len, "Model:\t\t%s\n", model);
 	len += get_cpuinfo(buffer+len);
 	for (mem = 0, i = 0; i < m68k_realnum_memory; i++)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/amiga/ints.c linux-2.4.22-pre10/arch/ppc/amiga/ints.c
--- linux-2.4.21/arch/ppc/amiga/ints.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/amiga/ints.c	2003-08-01 13:30:55.000000000 +0000
@@ -76,8 +76,8 @@
 	return NULL;
 }
 
-int sys_request_irq(unsigned int irq, 
-                    void (*handler)(int, void *, struct pt_regs *), 
+int sys_request_irq(unsigned int irq,
+                    void (*handler)(int, void *, struct pt_regs *),
                     unsigned long flags, const char *devname, void *dev_id)
 {
 	if (irq < IRQ1 || irq > IRQ7) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/Makefile linux-2.4.22-pre10/arch/ppc/boot/Makefile
--- linux-2.4.21/arch/ppc/boot/Makefile	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/Makefile	2003-08-01 13:30:46.000000000 +0000
@@ -32,6 +32,7 @@
 tools-$(CONFIG_ALL_PPC)		:= addnote mknote hack-coff mkprep
 tools-$(CONFIG_4xx)		:= mktree
 tools-$(CONFIG_LOPEC)		:= mkbugboot mkprep
+tools-$(CONFIG_PPLUS)		:= mkbugboot mkprep
 tools-$(CONFIG_SPRUCE)		:= mktree
 
 # These are dirs we don't want to go into on BOOT_TARGETS.  We have them for
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/chrp/main.c linux-2.4.22-pre10/arch/ppc/boot/chrp/main.c
--- linux-2.4.21/arch/ppc/boot/chrp/main.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/chrp/main.c	2003-08-01 13:30:41.000000000 +0000
@@ -43,6 +43,8 @@
 
 static char scratch[SCRATCH_SIZE];	/* 1MB of scratch space for gunzip */
 
+typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int);
+
 void
 chrpboot(int a1, int a2, void *prom)
 {
@@ -50,7 +52,7 @@
     void *dst;
     unsigned char *im;
     unsigned int initrd_size, initrd_start;
-    
+
     printf("chrpboot starting: loaded at 0x%p\n\r", &_start);
 
     initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
@@ -89,11 +91,11 @@
     flush_cache(dst, len);
     make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_chrp,
 		    (PROG_START + PROG_SIZE));
-    
+
     sa = (unsigned long)PROG_START;
     printf("start address = 0x%x\n\r", sa);
 
-    (*(void (*)())sa)(a1, a2, prom, initrd_start, initrd_size);
+    (*(kernel_start_t)sa)(a1, a2, prom, initrd_start, initrd_size);
 
     printf("returned?\n\r");
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/common/Makefile linux-2.4.22-pre10/arch/ppc/boot/common/Makefile
--- linux-2.4.21/arch/ppc/boot/common/Makefile	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/common/Makefile	2003-08-01 13:33:37.000000000 +0000
@@ -11,7 +11,6 @@
 USE_STANDARD_AS_RULE	:= true
 
 coffcrt0.o:
-	$(CC) -I$(TOPDIR)/arch/$(ARCH)/kernel $(AFLAGS) -DXCOFF \
-		-traditional -c -o coffcrt0.o crt0.S
+	$(CC) $(AFLAGS) -DXCOFF -traditional -c -o coffcrt0.o crt0.S
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/common/crt0.S linux-2.4.22-pre10/arch/ppc/boot/common/crt0.S
--- linux-2.4.21/arch/ppc/boot/common/crt0.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/common/crt0.S	2003-08-01 13:33:58.000000000 +0000
@@ -34,9 +34,9 @@
 
 	## Flush and invalidate the caches for the range in memory covering
 	## the .text section of the boot loader
-	
+
 	lis	r9,_start@h		# r9 = &_start
-	lis	r8,_etext@ha		# 
+	lis	r8,_etext@ha		#
 	addi	r8,r8,_etext@l		# r8 = &_etext
 3:	dcbf	r0,r9			# Flush the data cache
 	icbi	r0,r9			# Invalidate the instruction cache
@@ -50,12 +50,12 @@
 
 	lis	r7,_end@ha
 	addi	r7,r7,_end@l		# r7 = &_end
-	lis	r8,__bss_start@ha	# 
+	lis	r8,__bss_start@ha	#
 	addi	r8,r8,__bss_start@l	# r8 = &_bss_start
 
 	## Determine how large an area, in number of words, to clear
-	
-	subf	r7,r8,r7		# r7 = &_end - &_bss_start + 1 
+
+	subf	r7,r8,r7		# r7 = &_end - &_bss_start + 1
 	addi	r7,r7,3			# r7 += 3
 	srwi.	r7,r7,2			# r7 = size in words.
 	beq	2f			# If the size is zero, do not bother
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/common/misc-common.c linux-2.4.22-pre10/arch/ppc/boot/common/misc-common.c
--- linux-2.4.21/arch/ppc/boot/common/misc-common.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/common/misc-common.c	2003-08-01 13:33:18.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * arch/ppc/boot/common/misc-common.c
- * 
+ *
  * Misc. bootloader code (almost) all platforms can use
  *
  * Author: Johnnie Peters <jpeters@mvista.com>
@@ -74,7 +74,7 @@
 void exit(void)
 {
 	puts("exit\n");
-	while(1); 
+	while(1);
 }
 
 int tstc(void)
@@ -102,7 +102,7 @@
 	}
 }
 
-void 
+void
 putc(const char c)
 {
 	int x,y;
@@ -129,7 +129,7 @@
 			x--;
 		}
 	} else {
-		vidmem [ ( x + cols * y ) * 2 ] = c; 
+		vidmem [ ( x + cols * y ) * 2 ] = c;
 		if ( ++x >= cols ) {
 			x = 0;
 			if ( ++y >= lines ) {
@@ -170,7 +170,7 @@
 		    x--;
 		  }
 		} else {
-			vidmem [ ( x + cols * y ) * 2 ] = c; 
+			vidmem [ ( x + cols * y ) * 2 ] = c;
 			if ( ++x >= cols ) {
 				x = 0;
 				if ( ++y >= lines ) {
@@ -199,7 +199,7 @@
 void *zalloc(void *x, unsigned items, unsigned size)
 {
 	void *p = avail_ram;
-	
+
 	size *= items;
 	size = (size + 7) & -8;
 	avail_ram += size;
@@ -226,7 +226,7 @@
 {
 	z_stream s;
 	int r, i, flags;
-	
+
 	/* skip header */
 	i = 10;
 	flags = src[3];
@@ -248,7 +248,7 @@
 		puts("gunzip: ran out of data in header\n");
 		exit();
 	}
-	
+
 	s.zalloc = zalloc;
 	s.zfree = zfree;
 	r = inflateInit2(&s, -MAX_WBITS);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/common/misc-simple.c linux-2.4.22-pre10/arch/ppc/boot/common/misc-simple.c
--- linux-2.4.21/arch/ppc/boot/common/misc-simple.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/common/misc-simple.c	2003-08-01 13:34:18.000000000 +0000
@@ -236,7 +236,7 @@
 		 	puts("\n");
 		}
 	}
- 
+
 	rec->tag = BI_FIRST;
 	rec->size = sizeof(struct bi_record);
 	rec = (struct bi_record *)((unsigned long)rec + rec->size);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/common/mpc10x_memory.c linux-2.4.22-pre10/arch/ppc/boot/common/mpc10x_memory.c
--- linux-2.4.21/arch/ppc/boot/common/mpc10x_memory.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/common/mpc10x_memory.c	2003-08-01 13:32:32.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * arch/ppc/boot/common/mpc10x_common.c
- * 
+ *
  * A routine to find out how much memory the machine has.
  *
  * Based on:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/common/ns16550.c linux-2.4.22-pre10/arch/ppc/boot/common/ns16550.c
--- linux-2.4.21/arch/ppc/boot/common/ns16550.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/common/ns16550.c	2003-08-01 13:33:02.000000000 +0000
@@ -41,7 +41,7 @@
 
 	/* How far apart the registers are. */
 	shift = rs_table[chan].iomem_reg_shift;
-	
+
 	/* save the LCR */
 	lcr = inb(com_port + (UART_LCR << shift));
 	/* Access baud rate */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/common/relocate.S linux-2.4.22-pre10/arch/ppc/boot/common/relocate.S
--- linux-2.4.21/arch/ppc/boot/common/relocate.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/common/relocate.S	2003-08-01 13:34:06.000000000 +0000
@@ -21,8 +21,8 @@
 #include <asm/ppc_asm.h>
 
 #define GETSYM(reg, sym)	\
-	lis	reg, sym@h; ori	reg, reg, sym@l	
-	
+	lis	reg, sym@h; ori	reg, reg, sym@l
+
 	.text
 	/* We get called from the early initialization code.
 	 * Register 3 has the address where we were loaded,
@@ -54,12 +54,12 @@
 	cmp	cr0,r3,r4
 	beq	start_ldr	/* If 0, we don't need to relocate */
 
-	/* Move this code somewhere safe.  This is max(load + size, end) 
-	 * BIG ASSUMPTION:  Addresses below 0x80000000 are assumed to be 
-	 * in RAM, and addresses above 0x80000000 are assumed to be in 
-	 * Flash.  The cmpw instruction below does a signed integer 
+	/* Move this code somewhere safe.  This is max(load + size, end)
+	 * BIG ASSUMPTION:  Addresses below 0x80000000 are assumed to be
+	 * in RAM, and addresses above 0x80000000 are assumed to be in
+	 * Flash.  The cmpw instruction below does a signed integer
 	 * comparison, so when comparing a RAM address to a Flash address
-	 * the RAM address will always be greater.  This allows the 
+	 * the RAM address will always be greater.  This allows the
 	 * relocation to work when the load address is in Flash.
 	 * r8 == load address
 	 */
@@ -72,10 +72,10 @@
 	cmpw	r5,r6
 	bgt	1f
 	b	2f
-1:	
-	mr	r6, r5	
-2: 
-	/* dest is in r6 */	
+1:
+	mr	r6, r5
+2:
+	/* dest is in r6 */
 	/* Ensure alignment --- this code is precautionary */
 	addi	r6,r6,4
 	li	r5,0x0003
@@ -87,20 +87,20 @@
 	GETSYM(r3, start)
 
 	/* Size to copy */
-	sub	r4,r4,r5	
+	sub	r4,r4,r5
 	srwi	r4,r4,2
-	
+
 	/* Src addr to copy (= __relocate_start - start + where_loaded) */
 	sub	r3,r5,r3
-	add	r5,r8,r3	
+	add	r5,r8,r3
 
 	/* Save dest */
 	mr	r3, r6
 
-	/* Do the copy */	
-	mtctr	r4	
+	/* Do the copy */
+	mtctr	r4
 3:	lwz	r4,0(r5)
-	stw	r4,0(r3)	
+	stw	r4,0(r3)
 	addi	r3,r3,4
 	addi	r5,r5,4
 	bdnz	3b
@@ -116,23 +116,23 @@
 	b	flush_instruction_cache
 
 	.section ".relocate_code","xa"
-			
-do_relocate:		
-	/* We have 2 cases --- start < load, or start > load  
+
+do_relocate:
+	/* We have 2 cases --- start < load, or start > load
 	 * This determines whether we copy from the end, or the start.
 	 * Its easier to have 2 loops than to have paramaterised
 	 * loops.  Sigh.
 	 */
 	li	r6,0		/* Clear checksum */
 	mtctr	r7		/* Setup for a loop */
-			
+
 	GETSYM(r4, start)
 	mr	r3,r8		/* Get the load addr */
 
 	cmp	cr0,r4,r3	/* If we need to copy from the end, do so */
 	bgt	do_relocate_from_end
-	
-do_relocate_from_start:		
+
+do_relocate_from_start:
 1:	lwz	r5,0(r3)	/* Load and decrement */
 	stw	r5,0(r4)	/* Store and decrement */
 	addi	r3,r3,4
@@ -141,7 +141,7 @@
 	bdnz	1b		/* Are we done? */
 	b	do_relocate_out	/* Finished */
 
-do_relocate_from_end:	
+do_relocate_from_end:
 	GETSYM(r3, end)
 	slwi	r4,r7,2
 	add	r4,r8,r4	/* Get the physical end */
@@ -150,7 +150,7 @@
 	xor	r6,r6,r5
 	bdnz	1b
 
-do_relocate_out:	
+do_relocate_out:
 	GETSYM(r3,start_ldr)
 	mtlr	r3		/* Easiest way to do an absolute jump */
 /* Some boards don't boot up with the I-cache enabled.  Do that
@@ -161,7 +161,7 @@
 	b	flush_instruction_cache
 
 	.previous
-		
+
 start_ldr:
 /* Clear all of BSS and set up stack for C calls */
 	lis	r3,edata@h
@@ -200,7 +200,7 @@
 
 	/*
 	 * Start at the beginning of real code (the first
-	 * three instructions are 'nop' since we 
+	 * three instructions are 'nop' since we
 	 * sometimes overwrite them).
 	 */
 	ba	0x000c
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/include/rs6000.h linux-2.4.22-pre10/arch/ppc/boot/include/rs6000.h
--- linux-2.4.21/arch/ppc/boot/include/rs6000.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/include/rs6000.h	2003-08-01 13:33:37.000000000 +0000
@@ -35,7 +35,7 @@
 /********************** AOUT "OPTIONAL HEADER" **********************/
 
 
-typedef struct 
+typedef struct
 {
   unsigned char	magic[2];	/* type of file			*/
   unsigned char	vstamp[2];	/* version stamp		*/
@@ -135,7 +135,7 @@
 #define E_FILNMLEN	14	/* # characters in a file name		*/
 #define E_DIMNUM	4	/* # array dimensions in auxiliary entry */
 
-struct external_syment 
+struct external_syment
 {
   union {
     char e_name[E_SYMNMLEN];
@@ -157,7 +157,7 @@
 #define N_TMASK		(060)
 #define N_BTSHFT	(4)
 #define N_TSHIFT	(2)
-  
+
 
 union external_auxent {
 	struct {
@@ -214,7 +214,7 @@
 };
 
 #define	SYMENT	struct external_syment
-#define	SYMESZ	18	
+#define	SYMESZ	18
 #define	AUXENT	union external_auxent
 #define	AUXESZ	18
 #define DBXMASK 0x80		/* for dbx storage mask */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/include/zlib.h linux-2.4.22-pre10/arch/ppc/boot/include/zlib.h
--- linux-2.4.21/arch/ppc/boot/include/zlib.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/include/zlib.h	2003-08-01 13:31:32.000000000 +0000
@@ -44,7 +44,7 @@
 
 /* zconf.h -- configuration of the zlib compression library
  * Copyright (C) 1995 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */
@@ -137,7 +137,7 @@
 
 #define ZLIB_VERSION "0.95P"
 
-/* 
+/*
      The 'zlib' compression library provides in-memory compression and
   decompression functions, including integrity checks of the uncompressed
   data.  This version of the library supports only one compression method
@@ -254,7 +254,7 @@
                         /* basic functions */
 
 extern int inflateInit OF((z_stream *strm));
-/* 
+/*
      Initializes the internal stream state for decompression. The fields
    zalloc and zfree must be initialized before by the caller.  If zalloc and
    zfree are set to Z_NULL, inflateInit updates them to use default allocation
@@ -333,7 +333,7 @@
 
 extern int inflateInit2 OF((z_stream *strm,
                             int  windowBits));
-/*   
+/*
      This is another version of inflateInit with more compression options. The
    fields next_out, zalloc and zfree must be initialized before by the caller.
 
@@ -365,7 +365,7 @@
 */
 
 extern int inflateSync OF((z_stream *strm));
-/* 
+/*
     Skips invalid compressed data until the special marker (see deflate()
   above) can be found, or until all available input is skipped. No output
   is provided.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/lib/zlib.c linux-2.4.22-pre10/arch/ppc/boot/lib/zlib.c
--- linux-2.4.21/arch/ppc/boot/lib/zlib.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/lib/zlib.c	2003-08-01 13:32:14.000000000 +0000
@@ -118,7 +118,7 @@
 
 /* deflate.h -- internal compression state
  * Copyright (C) 1995 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* WARNING: this file should *not* be used by applications. It is
@@ -129,7 +129,7 @@
 /*+++++*/
 /* infblock.h -- header to use infblock.c
  * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* WARNING: this file should *not* be used by applications. It is
@@ -170,7 +170,7 @@
 /*+++++*/
 /* inftrees.h -- header to use inftrees.c
  * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* WARNING: this file should *not* be used by applications. It is
@@ -232,7 +232,7 @@
 /*+++++*/
 /* infcodes.h -- header to use infcodes.c
  * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* WARNING: this file should *not* be used by applications. It is
@@ -261,7 +261,7 @@
 /*+++++*/
 /* inflate.c -- zlib interface to inflate modules
  * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* inflate private state */
@@ -293,7 +293,7 @@
   /* mode independent information */
   int  nowrap;          /* flag for no wrapper */
   uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
-  inflate_blocks_statef 
+  inflate_blocks_statef
     *blocks;            /* current inflate_blocks state */
 
 };
@@ -568,7 +568,7 @@
 /*+++++*/
 /* infutil.h -- types and macros common to blocks and codes
  * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* WARNING: this file should *not* be used by applications. It is
@@ -606,7 +606,7 @@
     } trees;            /* if DTREE, decoding info for trees */
     struct {
       inflate_huft *tl, *td;    /* trees to free */
-      inflate_codes_statef 
+      inflate_codes_statef
          *codes;
     } decode;           /* if CODES, current state */
   } sub;                /* submode */
@@ -664,7 +664,7 @@
 /*+++++*/
 /* inffast.h -- header to use inffast.c
  * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* WARNING: this file should *not* be used by applications. It is
@@ -684,7 +684,7 @@
 /*+++++*/
 /* infblock.c -- interpret and process block types to last block
  * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* Table for deflate from PKZIP's appnote.txt. */
@@ -1139,7 +1139,7 @@
 /*+++++*/
 /* inftrees.c -- generate Huffman trees for efficient decoding
  * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* simplify the use of the inflate_huft type with some defines */
@@ -1232,7 +1232,7 @@
 uInt n;                 /* number of codes (assumed <= N_MAX) */
 uInt s;                 /* number of simple-valued codes (0..s-1) */
 uIntf *d;               /* list of base values for non-simple codes */
-uIntf *e;               /* list of extra bits for non-simple codes */  
+uIntf *e;               /* list of extra bits for non-simple codes */
 inflate_huft * FAR *t;  /* result: starting table */
 uIntf *m;               /* maximum lookup bits, returns actual */
 z_stream *zs;           /* for zalloc function */
@@ -1602,14 +1602,14 @@
     q = (--p)->next;
     ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft));
     p = q;
-  } 
+  }
   return Z_OK;
 }
 
 /*+++++*/
 /* infcodes.c -- process literals and length/distance pairs
  * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* simplify the use of the inflate_huft type with some defines */
@@ -1850,7 +1850,7 @@
 /*+++++*/
 /* inflate_util.c -- data and routines common to blocks and codes
  * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* copy as much as possible from the sliding window to the output area */
@@ -1923,7 +1923,7 @@
 /*+++++*/
 /* inffast.c -- process literals and length/distance pairs fast
  * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* simplify the use of the inflate_huft type with some defines */
@@ -2084,7 +2084,7 @@
 /*+++++*/
 /* zutil.c -- target dependent utility functions for the compression library
  * Copyright (C) 1995 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */
@@ -2105,7 +2105,7 @@
 /*+++++*/
 /* adler32.c -- compute the Adler-32 checksum of a data stream
  * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
+ * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 /* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/pmac/Makefile linux-2.4.22-pre10/arch/ppc/boot/pmac/Makefile
--- linux-2.4.21/arch/ppc/boot/pmac/Makefile	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/pmac/Makefile	2003-08-01 13:32:23.000000000 +0000
@@ -30,8 +30,6 @@
 
 TFTPIMAGE=/tftpboot/zImage.pmac$(END)
 
-AFLAGS_../common/crt0.o		+= -I$(TOPDIR)/arch/$(ARCH)/kernel
-
 ../common/coffcrt0.o:
 	$(MAKE) -C ../common coffcrt0.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/pmac/chrpmain.c linux-2.4.22-pre10/arch/ppc/boot/pmac/chrpmain.c
--- linux-2.4.21/arch/ppc/boot/pmac/chrpmain.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/pmac/chrpmain.c	2003-08-01 13:30:27.000000000 +0000
@@ -38,13 +38,15 @@
 
 #define SCRATCH_SIZE	(128 << 10)
 
+typedef void (*kernel_start_t)(int, int, void *);
+
 void boot(int a1, int a2, void *prom)
 {
     unsigned sa, len;
     void *dst;
     unsigned char *im;
     unsigned initrd_start, initrd_size;
-    
+
     printf("chrpboot starting: loaded at 0x%p\n", &_start);
 
     initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
@@ -87,7 +89,7 @@
     sa = (unsigned long)PROG_START;
     printf("start address = 0x%x\n", sa);
 
-    (*(void (*)())sa)(a1, a2, prom);
+    (*(kernel_start_t)sa)(a1, a2, prom);
 
     printf("returned?\n");
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/pmac/coffmain.c linux-2.4.22-pre10/arch/ppc/boot/pmac/coffmain.c
--- linux-2.4.21/arch/ppc/boot/pmac/coffmain.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/pmac/coffmain.c	2003-08-01 13:33:32.000000000 +0000
@@ -44,13 +44,15 @@
 
 static char heap[SCRATCH_SIZE];
 
+typedef void (*kernel_start_t)(int, int, void *);
+
 void boot(int a1, int a2, void *prom)
 {
     unsigned sa, len;
     void *dst;
     unsigned char *im;
     unsigned initrd_start, initrd_size;
-    
+
     printf("coffboot starting: loaded at 0x%p\n", &_start);
     setup_bats(RAM_START);
 
@@ -92,7 +94,7 @@
     sa = (unsigned long)PROG_START;
     printf("start address = 0x%x\n", sa);
 
-    (*(void (*)())sa)(a1, a2, prom);
+    (*(kernel_start_t)sa)(a1, a2, prom);
 
     printf("returned?\n");
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/pmac/start.c linux-2.4.22-pre10/arch/ppc/boot/pmac/start.c
--- linux-2.4.21/arch/ppc/boot/pmac/start.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/pmac/start.c	2003-08-01 13:32:25.000000000 +0000
@@ -11,7 +11,7 @@
 extern int strlen(const char *s);
 extern void boot(int a1, int a2, void *prom);
 
-int (*prom)();
+int (*prom)(void *args);
 
 void *chosen_handle;
 void *stdin;
@@ -26,7 +26,7 @@
 void
 start(int a1, int a2, void *promptr)
 {
-    prom = (int (*)()) promptr;
+    prom = (int (*)(void *)) promptr;
     chosen_handle = finddevice("/chosen");
     if (chosen_handle == (void *) -1)
 	exit();
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/prep/Makefile linux-2.4.22-pre10/arch/ppc/boot/prep/Makefile
--- linux-2.4.21/arch/ppc/boot/prep/Makefile	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/prep/Makefile	2003-08-01 13:34:30.000000000 +0000
@@ -39,10 +39,6 @@
 
 # Extra include search dirs
 CFLAGS_kbd.o			+= -I$(TOPDIR)/drivers/char
-AFLAGS_head.o			+= -I$(TOPDIR)/arch/$(ARCH)/kernel
-AFLAGS_../common/util.o			+= -I$(TOPDIR)/arch/$(ARCH)/kernel
-AFLAGS_../common/relocate.o	+= -I$(TOPDIR)/arch/$(ARCH)/kernel
-AFLAGS_../simple/legacy.o	+= -I$(TOPDIR)/arch/$(ARCH)/kernel
 
 all: zImage
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/prep/misc.c linux-2.4.22-pre10/arch/ppc/boot/prep/misc.c
--- linux-2.4.21/arch/ppc/boot/prep/misc.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/prep/misc.c	2003-08-01 13:31:14.000000000 +0000
@@ -353,7 +353,7 @@
 		unsigned long initrd_loc;
 		unsigned long rec_loc = _ALIGN((unsigned long)(zimage_size) +
 				(1 << 20) - 1, (1 << 20));
-		
+
 		rec = (struct bi_record *)rec_loc;
 
 		/* We need to make sure that the initrd and bi_recs do not
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/prep/of1275.h linux-2.4.22-pre10/arch/ppc/boot/prep/of1275.h
--- linux-2.4.21/arch/ppc/boot/prep/of1275.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/prep/of1275.h	2003-08-01 13:32:04.000000000 +0000
@@ -197,7 +197,7 @@
 	const char *method;
 	int ihandle;
 	/*...*/
-	int args[0]; 
+	int args[0];
 } of_call_method_service;
 
 int of_call_method(const char *method, int ihandle, ...);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/simple/Makefile linux-2.4.22-pre10/arch/ppc/boot/simple/Makefile
--- linux-2.4.21/arch/ppc/boot/simple/Makefile	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/simple/Makefile	2003-08-01 13:30:38.000000000 +0000
@@ -33,7 +33,9 @@
 ZIMAGEINITRD			:= zImage.initrd-SMON
 TFTPIMAGE			:= /tftpboot/zImage.gemini
 endif
-ifeq ($(CONFIG_LOPEC),y)
+# kbuild-2.4 'feature', only one of these will ever by 'y' at a time.
+# The rest will be unset.
+ifeq ($(CONFIG_LOPEC)$(CONFIG_PPLUS),y)
 ZIMAGE				:= zImage-PPLUS
 ZIMAGEINITRD			:= zImage.initrd-PPLUS
 EXTRA				:= ../common/mpc10x_memory.o
@@ -41,7 +43,9 @@
 ZNETBOOT			:= zImage.pplus
 ZNETBOOTRD			:= zImage.initrd.pplus
 endif
-
+ifeq ($(CONFIG_PPLUS),y)
+EXTRA				:= legacy.o
+endif
 ifeq ($(CONFIG_PAL4),y)
 ZIMAGE				:= zImage-PAL4
 ZIMAGEINITRD			:= zImage.initrd-PAL4
@@ -74,7 +78,7 @@
 				$(MISC) ../common/misc-common.o \
 				../common/string.o ../common/util.o \
 				../common/serial_stub.o
-obj-$(CONFIG_4xx)		+= embed_config.o
+obj-$(CONFIG_40x)		+= embed_config.o
 obj-$(CONFIG_8xx)		+= embed_config.o
 obj-$(CONFIG_8260)		+= embed_config.o
 obj-$(CONFIG_BSEIP)		+= iic.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/simple/embed_config.c linux-2.4.22-pre10/arch/ppc/boot/simple/embed_config.c
--- linux-2.4.21/arch/ppc/boot/simple/embed_config.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/simple/embed_config.c	2003-08-01 13:34:19.000000000 +0000
@@ -369,8 +369,8 @@
 
 	bd->bi_memstart = 0;
 	bd->bi_memsize = (8 * 1024 * 1024);
-	bd->bi_intfreq = 40000000;
-	bd->bi_busfreq = 40000000;
+	bd->bi_intfreq = 48000000;
+	bd->bi_busfreq = 48000000;
 }
 #endif /* FADS */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/simple/iic.c linux-2.4.22-pre10/arch/ppc/boot/simple/iic.c
--- linux-2.4.21/arch/ppc/boot/simple/iic.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/simple/iic.c	2003-08-01 13:31:32.000000000 +0000
@@ -173,7 +173,7 @@
 	}
 #endif
 #endif
-	
+
 	/* Chip errata, clear enable.
 	*/
 	i2c->i2c_i2mod = 0;
@@ -207,7 +207,7 @@
 	while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
 		temp--;
 #endif
-	
+
 	/* Chip errata, clear enable.
 	*/
 	i2c->i2c_i2mod = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/simple/misc-spruce.c linux-2.4.22-pre10/arch/ppc/boot/simple/misc-spruce.c
--- linux-2.4.21/arch/ppc/boot/simple/misc-spruce.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/simple/misc-spruce.c	2003-08-01 13:33:00.000000000 +0000
@@ -395,7 +395,7 @@
 		unsigned long rec_loc = _ALIGN((unsigned long)(zimage_size) +
 				(1 << 20) - 1, (1 << 20));
 		rec = (struct bi_record *)rec_loc;
-  
+
 		/* We need to make sure that the initrd and bi_recs do not
 		 * overlap. */
 		if ( initrd_size ) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/utils/mkbugboot.c linux-2.4.22-pre10/arch/ppc/boot/utils/mkbugboot.c
--- linux-2.4.21/arch/ppc/boot/utils/mkbugboot.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/utils/mkbugboot.c	2003-08-01 13:35:07.000000000 +0000
@@ -1,8 +1,8 @@
 /*
  * arch/ppc/pp3boot/mkbugboot.c
- * 
- * Makes a Motorola PPCBUG ROM bootable image which can be flashed 
- * into one of the FLASH banks on a Motorola PowerPlus board. 
+ *
+ * Makes a Motorola PPCBUG ROM bootable image which can be flashed
+ * into one of the FLASH banks on a Motorola PowerPlus board.
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
@@ -99,7 +99,7 @@
 {
   uint8_t header_block[HEADER_SIZE];
   bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0];
-  
+
   memset(header_block, 0, HEADER_SIZE);
 
   /* Fill in the PPCBUG ROM boot header */
@@ -146,7 +146,7 @@
   }
 
   /* Get file args */
-  
+
   /* kernel image file */
     if ((image_fd = open( argv[argptr] , 0)) < 0)
       exit(-1);
@@ -182,7 +182,7 @@
   bugboot_fd = open(bugbootname, O_RDWR);
 
   /* Calculate checksum */
-  checksum = calc_checksum(bugboot_fd);  
+  checksum = calc_checksum(bugboot_fd);
 
   /* Write out the calculated checksum */
   write(bugboot_fd, &checksum, 2);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/utils/mknote.c linux-2.4.22-pre10/arch/ppc/boot/utils/mknote.c
--- linux-2.4.21/arch/ppc/boot/utils/mknote.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/utils/mknote.c	2003-08-01 13:35:07.000000000 +0000
@@ -25,7 +25,7 @@
 	PL(0x1275);
 	/* name */
 	printf("PowerPC"); printf("%c", 0);
-	
+
 /* descriptor */
 	/* real-mode */
 	PL(0xffffffff);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/utils/mkprep.c linux-2.4.22-pre10/arch/ppc/boot/utils/mkprep.c
--- linux-2.4.21/arch/ppc/boot/utils/mkprep.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/utils/mkprep.c	2003-08-01 13:33:59.000000000 +0000
@@ -96,14 +96,14 @@
   }
 
   /* needs to handle args more elegantly -- but this is a small/simple program */
-  
+
   /* check for -pbp */
   if ( !strcmp( argv[argptr], "-pbp" ) )
   {
     prep = 1;
     argptr++;
   }
-  
+
   /* check for -asm */
   if ( !strcmp( argv[argptr], "-asm" ) )
   {
@@ -130,7 +130,7 @@
   /* skip elf header in input file */
   /*if ( !prep )*/
   lseek(in_fd, elfhdr_size, SEEK_SET);
-  
+
   /* write prep partition if necessary */
   if ( prep )
 	  write_prep_partition( in_fd, out_fd );
@@ -140,7 +140,7 @@
 	  write_asm_data( in_fd, out_fd );
   else
 	  copy_image(in_fd, out_fd);
-  
+
   return 0;
 }
 
@@ -151,15 +151,15 @@
   dword_t *entry  = (dword_t *)&block[0];
   dword_t *length = (dword_t *)&block[sizeof(long)];
   struct stat info;
-  
+
   if (fstat(in, &info) < 0)
   {
     fprintf(stderr,"info failed\n");
     exit(-1);
   }
-  
+
   bzero( block, sizeof block );
- 
+
   /* set entry point and boot image size skipping over elf header */
 #ifdef __i386__
   *entry = 0x400/*+65536*/;
@@ -172,7 +172,7 @@
   /* sets magic number for msdos partition (used by linux) */
   block[510] = 0x55;
   block[511] = 0xAA;
-  
+
   /*
    * Build a "PReP" partition table entry in the boot record
    *  - "PReP" may only look at the system_indicator
@@ -203,13 +203,13 @@
 #if 0
   pe->beginning_sector  = cpu_to_le32(1);
 #else
-  /* This has to be 0 on the PowerStack? */   
+  /* This has to be 0 on the PowerStack? */
 #ifdef __i386__
   pe->beginning_sector  = 0;
 #else
   pe->beginning_sector  = cpu_to_le32(0);
 #endif /* __i386__ */
-#endif    
+#endif
 
 #ifdef __i386__
   pe->number_of_sectors = 2*18*80-1;
@@ -219,7 +219,7 @@
 
   write( out, block, sizeof(block) );
   write( out, entry, sizeof(*entry) );
-  write( out, length, sizeof(*length) );  
+  write( out, length, sizeof(*length) );
   /* set file position to 2nd sector where image will be written */
   lseek( out, 0x400, SEEK_SET );
 }
@@ -245,7 +245,7 @@
   unsigned char *lp;
   unsigned char buf[SIZE];
   unsigned char str[256];
-  
+
   write( out, "\t.data\n\t.globl input_data\ninput_data:\n",
 	 strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) );
   pos = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/boot/utils/mktree.c linux-2.4.22-pre10/arch/ppc/boot/utils/mktree.c
--- linux-2.4.21/arch/ppc/boot/utils/mktree.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/boot/utils/mktree.c	2003-08-01 13:31:22.000000000 +0000
@@ -89,7 +89,7 @@
 	cp = (uint *)&bt;
 	for (i=0; i<sizeof(bt)/sizeof(uint); i++)
 		cksum += *cp++;
-	
+
 	/* Assume zImage is an ELF file, and skip the 64K header.
 	*/
 	if (read(in_fd, tmpbuf, IMGBLK) != IMGBLK) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/config.in linux-2.4.22-pre10/arch/ppc/config.in
--- linux-2.4.21/arch/ppc/config.in	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/config.in	2003-08-01 13:33:32.000000000 +0000
@@ -29,11 +29,15 @@
 define_bool CONFIG_PPC32 y
 choice 'Processor Type'	\
 	"6xx/7xx/74xx/8260	CONFIG_6xx	\
-	 4xx			CONFIG_4xx	\
-	 POWER3               	CONFIG_POWER3	\
-	 POWER4        	        CONFIG_POWER4	\
+	 40x			CONFIG_40x	\
+	 POWER3			CONFIG_POWER3	\
+	 POWER4			CONFIG_POWER4	\
 	 8xx			CONFIG_8xx"	6xx
 
+if [ "$CONFIG_40x" = "y" ]; then
+  define_bool CONFIG_4xx y
+fi
+
 if [ "$CONFIG_6xx" = "y" ]; then
   bool 'MPC8260 CPM Support' CONFIG_8260
 fi
@@ -47,8 +51,6 @@
 if [ "$CONFIG_6xx" = "y" -o "$CONFIG_POWER3" = "y" -o \
      "$CONFIG_POWER4" = "y" ]; then
   define_bool CONFIG_PPC_STD_MMU y
-else
-  define_bool CONFIG_PPC_STD_MMU n
 fi
 
 if [ "$CONFIG_8260" = "y" ]; then
@@ -56,33 +58,31 @@
   bool 'Support for EST8260' CONFIG_EST8260
 fi
 
-if [ "$CONFIG_4xx" = "y" ]; then
-  choice 'Machine Type'			\
-	"Oak			CONFIG_OAK 	\
-	 Walnut			CONFIG_WALNUT"	Oak
-  if [ "$CONFIG_WALNUT" = "y" ]; then
-    define_bool CONFIG_IBM405_ERR77 y
-  fi
+if [ "$CONFIG_40x" = "y" ]; then
+    choice 'Machine Type'			\
+	 "Oak		CONFIG_OAK		\
+	 Walnut		CONFIG_WALNUT"		Walnut
 fi
 
 if [ "$CONFIG_8xx" = "y" ]; then
   define_bool CONFIG_SERIAL_CONSOLE y
+  define_bool CONFIG_NOT_COHERENT_CACHE y
 
   choice 'Machine Type'		\
 	"RPX-Lite	CONFIG_RPXLITE		\
 	 RPX-Classic	CONFIG_RPXCLASSIC	\
 	 BSE-IP		CONFIG_BSEIP		\
 	 FADS		CONFIG_FADS		\
- 	 TQM823L	CONFIG_TQM823L		\
- 	 TQM850L	CONFIG_TQM850L		\
- 	 TQM855L	CONFIG_TQM855L		\
-  	 TQM860L	CONFIG_TQM860L		\
- 	 FPS850L	CONFIG_FPS850L		\
-  	 TQM860		CONFIG_TQM860		\
- 	 SPD823TS	CONFIG_SPD823TS		\
- 	 IVMS8		CONFIG_IVMS8		\
+	 TQM823L	CONFIG_TQM823L		\
+	 TQM850L	CONFIG_TQM850L		\
+	 TQM855L	CONFIG_TQM855L		\
+	 TQM860L	CONFIG_TQM860L		\
+	 FPS850L	CONFIG_FPS850L		\
+	 TQM860		CONFIG_TQM860		\
+	 SPD823TS	CONFIG_SPD823TS		\
+	 IVMS8		CONFIG_IVMS8		\
 	 IVML24		CONFIG_IVML24		\
- 	 SM850		CONFIG_SM850		\
+	 SM850		CONFIG_SM850		\
 	 MBX		CONFIG_MBX		\
 	 WinCept	CONFIG_WINCEPT"		RPX-Lite
 
@@ -92,18 +92,19 @@
        "$CONFIG_TQM855L" = "y" -o \
        "$CONFIG_TQM860L" = "y" -o \
        "$CONFIG_SM850"   = "y" ]; then
- 	define_bool	CONFIG_TQM8xxL	y
+ 	define_bool CONFIG_TQM8xxL y
   fi
 fi
 
 if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ]; then
   choice 'Machine Type'		\
 	"CHRP/PowerMac/PReP	CONFIG_ALL_PPC		\
-  	 Amiga-APUS		CONFIG_APUS		\
+	 Amiga-APUS		CONFIG_APUS		\
 	 IBM-Spruce		CONFIG_SPRUCE		\
 	 Motorola-LoPEC		CONFIG_LOPEC		\
+	 Motorola-PowerPlus	CONFIG_PPLUS		\
 	 SBS-Palomar4		CONFIG_PAL4		\
-	 Synergy-Gemini        	CONFIG_GEMINI"		CHRP/PowerMac/PReP
+	 Synergy-Gemini		CONFIG_GEMINI"		CHRP/PowerMac/PReP
 fi
 
 if [ "$CONFIG_SPRUCE" = "y" ]; then
@@ -115,8 +116,8 @@
   define_bool CONFIG_GEN550 y
 fi
 
-if [ "$CONFIG_PPC_STD_MMU" != "y" ]; then
-  define_bool CONFIG_ALL_PPC n
+if [ "$CONFIG_PPLUS" = "y" ]; then
+  define_bool CONFIG_GEN550 y
 fi
 
 bool 'Symmetric multi-processing support' CONFIG_SMP
@@ -138,6 +139,30 @@
   bool 'Math emulation' CONFIG_MATH_EMULATION
 fi
 
+if [ "$CONFIG_40x" = "y" ]; then
+# It's often necessary to know the specific 4xx processor type.
+# Fortunately, it is impled (so far) from the board type, so we
+# don't need to ask more redundant questions.
+  if [ "$CONFIG_OAK" = "y" -o "$CONFIG_TIVO" = "y" ]; then
+    define_bool CONFIG_403GCX y
+    define_bool CONFIG_IBM_OPENBIOS y
+  fi
+  if [ "$CONFIG_WALNUT" = "y" ]; then
+    define_bool CONFIG_405GP y
+    define_bool CONFIG_BIOS_FIXUP y
+    define_bool CONFIG_IBM_OPENBIOS y
+    define_bool CONFIG_IBM405_ERR77 y
+    define_bool CONFIG_IBM_OCP y
+  fi
+  if [ "$CONFIG_40x" = "y" ]; then
+    choice 'TTYS0 device and default console'	\
+	"UART0  CONFIG_UART0_TTYS0		\
+	 UART1	CONFIG_UART0_TTYS1"		UART0
+  fi
+
+  define_bool CONFIG_IBM405_ERR51 y
+  define_bool CONFIG_NOT_COHERENT_CACHE y
+fi
 if [ "$CONFIG_8xx" = "y" -o "$CONFIG_8260" = "y" ]; then
     define_bool CONFIG_EMBEDDEDBOOT y
 fi
@@ -156,7 +181,8 @@
 define_bool CONFIG_MCA n
 
 if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8260" = "y" ]; then
-  define_bool CONFIG_PCI n
+  bool "Enable PCI" CONFIG_PCI
+  bool 'PC PS/2 style Keyboard' CONFIG_PC_KEYBOARD
 else
   if [ "$CONFIG_8xx" = "y" ]; then
      bool 'QSpan PCI' CONFIG_PCI_QSPAN
@@ -212,7 +238,7 @@
   dep_bool '  Support for reading of PReP Residual Data in /proc' CONFIG_PROC_PREPRESIDUAL $CONFIG_PREP_RESIDUAL
   define_bool CONFIG_PPCBUG_NVRAM y
 fi
-if [ "$CONFIG_LOPEC" = "y" ]; then
+if [ "$CONFIG_PPLUS" = "y" -o "$CONFIG_LOPEC" = "y" ]; then
   bool 'Enable reading PPCBUG NVRAM during boot' CONFIG_PPCBUG_NVRAM
 fi
 
@@ -297,7 +323,7 @@
   bool 'Network device support' CONFIG_NETDEVICES
   if [ "$CONFIG_NETDEVICES" = "y" ]; then
     source drivers/net/Config.in
-    if [ "$CONFIG_ATM" = "y" ]; then
+    if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
       source drivers/atm/Config.in
     fi
   fi
@@ -328,7 +354,7 @@
 
 mainmenu_option next_comment
 comment 'Console drivers'
-if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then
+if [ "$CONFIG_40x" != "y" -a "$CONFIG_8xx" != "y" ]; then
   bool 'Support for VGA Console' CONFIG_VGA_CONSOLE
 fi
  source drivers/video/Config.in
@@ -411,6 +437,7 @@
 
 source net/bluetooth/Config.in
 
+source crypto/Config.in
 source lib/Config.in
 
 mainmenu_option next_comment
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/configs/pplus_defconfig linux-2.4.22-pre10/arch/ppc/configs/pplus_defconfig
--- linux-2.4.21/arch/ppc/configs/pplus_defconfig	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/configs/pplus_defconfig	2003-08-01 13:32:58.000000000 +0000
@@ -0,0 +1,739 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_6xx=y
+# CONFIG_40x is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+# CONFIG_8xx is not set
+# CONFIG_8260 is not set
+CONFIG_PPC_STD_MMU=y
+# CONFIG_ALL_PPC is not set
+# CONFIG_APUS is not set
+# CONFIG_SPRUCE is not set
+# CONFIG_LOPEC is not set
+CONFIG_PPLUS=y
+# CONFIG_PAL4 is not set
+# CONFIG_GEMINI is not set
+CONFIG_GEN550=y
+# CONFIG_SMP is not set
+# CONFIG_ALTIVEC is not set
+# CONFIG_TAU is not set
+CONFIG_PPC_ISATIMER=y
+
+#
+# General setup
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+# CONFIG_GEN_RTC is not set
+CONFIG_PPC_RTC=y
+# CONFIG_PPCBUG_NVRAM is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="ip=on"
+
+#
+# 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=y
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+
+#
+#   IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_UNCLEAN=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_MIRROR=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_NAT_AMANDA=m
+# CONFIG_IP_NF_NAT_LOCAL is not set
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_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 is not set
+# 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 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_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=y
+CONFIG_BLK_DEV_SL82C105=y
+# 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=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_SR_EXTRA_DEVS=2
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# 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 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
+# 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 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
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+CONFIG_EEPRO100=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 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+CONFIG_BUSMOUSE=y
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_LOGIBUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+# 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_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+CONFIG_ISO9660_FS=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 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ 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
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/configs/walnut_defconfig linux-2.4.22-pre10/arch/ppc/configs/walnut_defconfig
--- linux-2.4.21/arch/ppc/configs/walnut_defconfig	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/configs/walnut_defconfig	2003-08-01 13:34:22.000000000 +0000
@@ -24,17 +24,24 @@
 CONFIG_PPC=y
 CONFIG_PPC32=y
 # CONFIG_6xx is not set
-CONFIG_4xx=y
+CONFIG_40x=y
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
 # CONFIG_8xx is not set
+CONFIG_4xx=y
 # CONFIG_PPC_STD_MMU is not set
 # CONFIG_OAK is not set
 CONFIG_WALNUT=y
-CONFIG_IBM405_ERR77=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
 # CONFIG_MATH_EMULATION is not set
+CONFIG_405GP=y
+CONFIG_BIOS_FIXUP=y
+CONFIG_IBM_OPENBIOS=y
+CONFIG_IBM405_ERR77=y
+CONFIG_IBM_OCP=y
+CONFIG_IBM405_ERR51=y
+CONFIG_NOT_COHERENT_CACHE=y
 
 #
 # General setup
@@ -294,7 +301,8 @@
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # I2C support
@@ -398,7 +406,7 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
@@ -437,8 +445,18 @@
 #
 # Partition Types
 #
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
+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 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 is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
@@ -460,10 +478,11 @@
 #
 # Library routines
 #
-# CONFIG_ZLIB_INFLATE is not set
-# CONFIG_ZLIB_DEFLATE is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
 
 #
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/Makefile linux-2.4.22-pre10/arch/ppc/kernel/Makefile
--- linux-2.4.21/arch/ppc/kernel/Makefile	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/Makefile	2003-08-01 13:34:30.000000000 +0000
@@ -23,22 +23,25 @@
 # Start off with 'head.o', change as needed.
 HEAD-y				:= head.o
 HEAD-$(CONFIG_6xx)		+= idle_6xx.o
-HEAD-$(CONFIG_4xx)		:= head_4xx.o
+HEAD-$(CONFIG_40x)		:= head_4xx.o
 HEAD-$(CONFIG_8xx)		:= head_8xx.o
 
 all: $(HEAD-y) kernel.o
 
 O_TARGET := kernel.o
 
-export-objs			:= ppc_ksyms.o time.o
+export-objs			:= ppc_ksyms.o time.o ocp.o ppc4xx_setup.o
 
 obj-y				:= entry.o traps.o irq.o idle.o time.o misc.o \
 					process.o signal.o ptrace.o align.o \
 					semaphore.o syscalls.o setup.o \
 					cputable.o ppc_htab.o
+ifneq ($(CONFIG_6xx),y)
+obj-y				+= idle_gen.o
+endif
 obj-$(CONFIG_6xx)		+= l2cr.o cpu_setup_6xx.o
 obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
-obj-$(CONFIG_PCI)		+= pci.o 
+obj-$(CONFIG_PCI)		+= pci.o
 obj-$(CONFIG_PCI)		+= pci-dma.o
 obj-$(CONFIG_KGDB)		+= ppc-stub.o
 obj-$(CONFIG_PPCBUG_NVRAM)	+= prep_nvram.o
@@ -48,7 +51,12 @@
 obj-$(CONFIG_KGDB)		+= gen550_kgdb.o gen550_dbg.o
 obj-$(CONFIG_SERIAL_TEXT_DEBUG)	+= gen550_dbg.o
 endif
-obj-$(CONFIG_4xx)		+= ppc4xx_pic.o
+obj-$(CONFIG_4xx)		+= todc_time.o
+obj-$(CONFIG_40x)		+= ppc4xx_setup.o ocp.o
+obj-$(CONFIG_40x)		+= ppc4xx_pic.o
+ifeq ($(CONFIG_PCI),y)
+obj-$(CONFIG_40x)		+= ppc405_pci.o indirect_pci.o pci_auto.o
+endif
 obj-$(CONFIG_8xx)		+= m8xx_setup.o ppc8xx_pic.o
 ifeq ($(CONFIG_8xx),y)
 obj-$(CONFIG_PCI)		+= qspan_pci.o
@@ -63,6 +71,8 @@
 obj-$(CONFIG_LOPEC)		+= mpc10x_common.o indirect_pci.o pci_auto.o \
 					open_pic.o i8259.o todc_time.o
 obj-$(CONFIG_PAL4)		+= indirect_pci.o pci_auto.o todc_time.o
+obj-$(CONFIG_PPLUS)		+= pplus_common.o open_pic.o i8259.o \
+				   indirect_pci.o todc_time.o pci_auto.o
 obj-$(CONFIG_SPRUCE)		+= indirect_pci.o pci_auto.o todc_time.o
 obj-$(CONFIG_8260)		+= m8260_setup.o ppc8260_pic.o
 obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/bitops.c linux-2.4.22-pre10/arch/ppc/kernel/bitops.c
--- linux-2.4.21/arch/ppc/kernel/bitops.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/bitops.c	2003-08-01 13:31:02.000000000 +0000
@@ -15,7 +15,7 @@
 	unsigned long old;
 	unsigned long mask = 1 << (nr & 0x1f);
 	unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
-	
+
 	__asm__ __volatile__(SMP_WMB "\n\
 1:	lwarx	%0,0,%3 \n\
 	or	%0,%0,%2 \n"
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/btext.c linux-2.4.22-pre10/arch/ppc/kernel/btext.c
--- linux-2.4.21/arch/ppc/kernel/btext.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/btext.c	2003-08-01 13:30:38.000000000 +0000
@@ -111,13 +111,13 @@
 /* Calc BAT values for mapping the display and store them
  * in disp_BAT.  Those values are then used from head.S to map
  * the display during identify_machine() and MMU_Init()
- * 
+ *
  * The display is mapped to virtual address 0xD0000000, rather
  * than 1:1, because some some CHRP machines put the frame buffer
  * in the region starting at 0xC0000000 (KERNELBASE).
  * This mapping is temporary and will disappear as soon as the
  * setup done by MMU_Init() is applied.
- * 
+ *
  * For now, we align the BAT and then map 8Mb on 601 and 16Mb
  * on other PPCs. This may cause trouble if the framebuffer
  * is really badly aligned, but I didn't encounter this case
@@ -141,7 +141,7 @@
 		lowbits = addr & ~0xFF000000UL;
 		addr &= 0xFF000000UL;
 		disp_BAT[0] = vaddr | (BL_16M<<2) | 2;
-		disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);		
+		disp_BAT[1] = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
 	} else {
 		/* 601 */
 		lowbits = addr & ~0xFF800000UL;
@@ -177,9 +177,9 @@
 
 /* Here's a small text engine to use during early boot
  * or for debugging purposes
- * 
+ *
  * todo:
- * 
+ *
  *  - build some kind of vgacon with it to enable early printk
  *  - move to a separate file
  *  - add a few video driver hooks to keep in sync with display
@@ -258,7 +258,7 @@
 	unsigned long width 	= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
 					(bi->dispDeviceDepth >> 3)) >> 2;
 	int i,j;
-	
+
 	for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++)
 	{
 		unsigned long *ptr = base;
@@ -280,7 +280,7 @@
 	unsigned long width 	= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
 					(bi->dispDeviceDepth >> 3)) >> 2;
 	int i,j;
-	
+
 	for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1]); i++)
 	{
 		unsigned long *ptr = base;
@@ -302,7 +302,7 @@
 	unsigned long width		= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
 						(bi->dispDeviceDepth >> 3)) >> 2;
 	int i,j;
-	
+
 #ifdef CONFIG_ADB_PMU
 	pmu_suspend();	/* PMU will not shut us down ! */
 #endif
@@ -389,7 +389,7 @@
 btext_drawhex(unsigned long v)
 {
 	static char hex_table[] = "0123456789abcdef";
-	
+
 	if (!boot_text_mapped)
 		return;
 	btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]);
@@ -410,7 +410,7 @@
 	unsigned char *base	= calc_base(bi, locX << 3, locY << 4);
 	unsigned char *font	= &vga_font[((unsigned long)c) * 16];
 	int rb			= bi->dispDeviceRowBytes;
-	
+
 	switch(bi->dispDeviceDepth) {
 	case 24:
 	case 32:
@@ -456,10 +456,10 @@
 static void BTEXT
 draw_byte_32(unsigned char *font, unsigned long *base, int rb)
 {
-	int l, bits;	
+	int l, bits;
 	int fg = 0xFFFFFFFFUL;
 	int bg = 0x00000000UL;
-	
+
 	for (l = 0; l < 16; ++l)
 	{
 		bits = *font++;
@@ -478,7 +478,7 @@
 static void BTEXT
 draw_byte_16(unsigned char *font, unsigned long *base, int rb)
 {
-	int l, bits;	
+	int l, bits;
 	int fg = 0xFFFFFFFFUL;
 	int bg = 0x00000000UL;
 	unsigned long *eb = expand_bits_16;
@@ -497,7 +497,7 @@
 static void BTEXT
 draw_byte_8(unsigned char *font, unsigned long *base, int rb)
 {
-	int l, bits;	
+	int l, bits;
 	int fg = 0x0F0F0F0FUL;
 	int bg = 0x00000000UL;
 	unsigned long *eb = expand_bits_8;
@@ -512,346 +512,346 @@
 }
 
 static unsigned char vga_font[cmapsz] BTDATA = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 
-0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff, 
-0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 
-0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 
-0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 
-0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 
-0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 
-0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e, 
-0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 
-0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 
-0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 
-0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, 
-0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 
-0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb, 
-0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 
-0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 
-0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 
-0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 
-0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 
-0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 
-0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 
-0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 
-0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 
-0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 
-0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 
-0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 
-0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
-0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 
-0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 
-0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 
-0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
-0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 
-0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 
-0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 
-0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde, 
-0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 
-0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 
-0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c, 
-0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 
-0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 
-0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 
-0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 
-0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7, 
-0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 
-0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 
-0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 
-0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 
-0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 
-0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 
-0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 
-0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 
-0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 
-0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 
-0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, 
-0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 
-0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60, 
-0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 
-0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60, 
-0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 
-0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 
-0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 
-0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 
-0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 
-0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 
-0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 
-0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 
-0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 
-0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 
-0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 
-0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 
-0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 
-0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 
-0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 
-0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 
-0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 
-0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00, 
-0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
-0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 
-0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c, 
-0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 
-0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 
-0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 
-0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 
-0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 
-0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 
-0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 
-0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 
-0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 
-0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 
-0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 
-0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 
-0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 
-0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 
-0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 
-0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, 
-0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 
-0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 
-0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 
-0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
-0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 
-0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 
-0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 
-0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 
-0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 
-0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 
-0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 
-0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 
-0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 
-0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 
-0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 
-0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 
-0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 
-0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 
-0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c, 
-0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 
-0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
+0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
+0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
+0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
+0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
+0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
+0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
+0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
+0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
+0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
+0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
+0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
+0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
+0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
+0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
+0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
+0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
+0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
+0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
+0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
+0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
+0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
+0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
+0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
+0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
+0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
+0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
+0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
+0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
+0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
+0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
+0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
+0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
+0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
+0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
+0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
+0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
+0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
+0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
+0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
+0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
+0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
+0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
+0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
+0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
+0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
+0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
+0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
+0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
+0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
+0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
+0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
+0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
+0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
+0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
+0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
+0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
+0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
+0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
+0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
+0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
+0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
+0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
+0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
+0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
+0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
+0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
+0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
+0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
+0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
+0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/checks.c linux-2.4.22-pre10/arch/ppc/kernel/checks.c
--- linux-2.4.21/arch/ppc/kernel/checks.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/checks.c	2003-08-01 13:34:40.000000000 +0000
@@ -32,7 +32,7 @@
 			sizeof(struct thread_struct)%16);
 		ret = -1;
 	}
-#endif	
+#endif
 
 	if ( sizeof(struct pt_regs) % 16 )
 	{
@@ -41,7 +41,7 @@
 			sizeof(struct pt_regs),
 			sizeof(struct pt_regs)%16);
 		ret = -1;
-		
+
 	}
 
 	printf("Task size        : %d bytes\n"
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/cpu_setup_6xx.S linux-2.4.22-pre10/arch/ppc/kernel/cpu_setup_6xx.S
--- linux-2.4.21/arch/ppc/kernel/cpu_setup_6xx.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/cpu_setup_6xx.S	2003-08-01 13:35:00.000000000 +0000
@@ -142,7 +142,7 @@
 	sync
 	isync
 	blr
-	
+
 /* 740/750/7400/7410
  * Enable Store Gathering (SGE), Address Brodcast (ABE),
  * Branch History Table (BHTE), Branch Target ICache (BTIC)
@@ -213,7 +213,7 @@
 	li	r7,CPU_FTR_CAN_NAP
 	andc	r6,r6,r7
 	stw	r6,CPU_SPEC_FEATURES(r5)
-1:	
+1:
 	mfspr	r11,HID0
 
 	/* All of the bits we have to set.....
@@ -248,20 +248,21 @@
 /* Definitions for the table use to save CPU states */
 #define CS_HID0		0
 #define CS_HID1		4
-#define	CS_MSSCR0	8
-#define CS_MSSSR0	12
-#define CS_ICTRL	16
-#define CS_LDSTCR	20
-#define CS_LDSTDB	24
-#define CS_SIZE		28
+#define CS_HID2		8
+#define	CS_MSSCR0	12
+#define CS_MSSSR0	16
+#define CS_ICTRL	20
+#define CS_LDSTCR	24
+#define CS_LDSTDB	28
+#define CS_SIZE		32
 
 	.data
 	.balign	L1_CACHE_LINE_SIZE
-cpu_state_storage:	
+cpu_state_storage:
 	.space	CS_SIZE
 	.balign	L1_CACHE_LINE_SIZE,0
 	.text
-	
+
 /* Called in normal context to backup CPU 0 state. This
  * does not include cache settings. This function is also
  * called for machine sleep. This does not include the MMU
@@ -311,11 +312,18 @@
 	stw	r4,CS_LDSTCR(r5)
 	mfspr	r4,SPRN_LDSTDB
 	stw	r4,CS_LDSTDB(r5)
-1:	
+1:
 	bne	cr5,1f
 	/* Backup 750FX specific registers */
 	mfspr	r4,SPRN_HID1
 	stw	r4,CS_HID1(r5)
+	/* If rev 2.x, backup HID2 */
+	mfspr	r3,PVR
+	andi.	r3,r3,0xff00
+	cmpi	cr0,r3,0x0200
+	bne	1f
+	mfspr	r4,SPRN_HID2
+	stw	r4,CS_HID2(r5)
 1:
 	mtcr	r7
 	blr
@@ -395,9 +403,19 @@
 	sync
 2:	bne	cr5,1f
 	/* Restore 750FX specific registers
-	 * that is restore PLL config & switch
-	 * to PLL 0
+	 * that is restore HID2 on rev 2.x and PLL config & switch
+	 * to PLL 0 on all
 	 */
+	/* If rev 2.x, restore HID2 with low voltage bit cleared */
+	mfspr	r3,PVR
+	andi.	r3,r3,0xff00
+	cmpi	cr0,r3,0x0200
+	bne	4f
+	lwz	r4,CS_HID2(r5)
+	rlwinm	r4,r4,0,19,17
+	mtspr	SPRN_HID2,r4
+	sync
+4:
 	lwz	r4,CS_HID1(r5)
 	rlwinm  r5,r4,0,16,14
 	mtspr	SPRN_HID1,r5
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/cputable.c linux-2.4.22-pre10/arch/ppc/kernel/cputable.c
--- linux-2.4.21/arch/ppc/kernel/cputable.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/cputable.c	2003-08-01 13:33:31.000000000 +0000
@@ -140,16 +140,25 @@
 	32, 32,
 	__setup_cpu_750cx
     },
+    {	/* 750FX rev 1.x */
+    	0xffffff00, 0x70000100, "750FX",
+    	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP |
+	CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM,
+	COMMON_PPC,
+	32, 32,
+	__setup_cpu_750
+    },
     {	/* 750FX rev 2.0 must disable HID0[DPM] */
     	0xffffffff, 0x70000200, "750FX",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
 	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP |
-	CPU_FTR_NO_DPM,
+	CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS | CPU_FTR_NO_DPM,
 	COMMON_PPC,
 	32, 32,
 	__setup_cpu_750
     },
-    {	/* 750FX (All revs except 2.0) */
+    {	/* 750FX (All revs > 2.0) */
     	0xffff0000, 0x70000000, "750FX",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
 	CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP |
@@ -274,7 +283,7 @@
 	32, 32,
 	__setup_cpu_generic
     },
-#endif /* CLASSIC_PPC */    
+#endif /* CLASSIC_PPC */
 #ifdef CONFIG_PPC64BRIDGE
     {	/* Power3 */
     	0xffff0000, 0x00400000, "Power3 (630)",
@@ -304,7 +313,7 @@
 		128, 128,
 		__setup_cpu_power3
 	},
-#endif /* CONFIG_PPC64BRIDGE */    
+#endif /* CONFIG_PPC64BRIDGE */
 #ifdef CONFIG_POWER4
     {	/* Power4 */
     	0xffff0000, 0x00350000, "Power4",
@@ -313,7 +322,7 @@
 	128, 128,
 	__setup_cpu_power4
     },
-#endif /* CONFIG_POWER4 */    
+#endif /* CONFIG_POWER4 */
 #ifdef CONFIG_8xx
     {	/* 8xx */
     	0xffff0000, 0x00500000, "8xx",
@@ -324,7 +333,7 @@
 	__setup_cpu_8xx	/* Empty */
     },
 #endif /* CONFIG_8xx */
-#ifdef CONFIG_4xx
+#ifdef CONFIG_40x
     {	/* 403GC */
     	0xffffff00, 0x00200200, "403GC",
     	CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/entry.S linux-2.4.22-pre10/arch/ppc/kernel/entry.S
--- linux-2.4.21/arch/ppc/kernel/entry.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/entry.S	2003-08-01 13:32:26.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- *  PowerPC version 
+ *  PowerPC version
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *  Rewritten by Cort Dougan (cort@fsmlabs.com) for PReP
  *    Copyright (C) 1996 Cort Dougan <cort@fsmlabs.com>
@@ -16,7 +16,7 @@
  *  modify it under the terms of the GNU General Public License
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
- *	
+ *
  */
 
 #include <linux/config.h>
@@ -162,7 +162,7 @@
 	blrl			/* Call handler */
 	.globl	ret_from_syscall_2
 ret_from_syscall_2:
-	stw	r3,RESULT(r1)	/* Save result */	
+	stw	r3,RESULT(r1)	/* Save result */
 	li	r10,-_LAST_ERRNO
 	cmpl	0,r3,r10
 	blt	60f
@@ -202,7 +202,7 @@
  *
  * The code which creates the new task context is in 'copy_thread'
  * in arch/ppc/kernel/process.c
- */	
+ */
 _GLOBAL(_switch)
 	stwu	r1,-INT_FRAME_SIZE(r1)
 	stw	r0,GPR0(r1)
@@ -291,7 +291,7 @@
 	bl	do_signal
 	.globl	do_signal_ret
 do_signal_ret:
-	.globl ret_to_user_hook	
+	.globl ret_to_user_hook
 ret_to_user_hook:
 	nop
 restore:
@@ -303,10 +303,13 @@
 	REST_GPR(31,r1)
 
 	/* make sure we hard disable here, even if rtl is active, to protect
-	 * SRR[01] and SPRG2 -- Cort 
+	 * SRR[01] and SPRG2 -- Cort
 	 */
 	mfmsr	r0		/* Get current interrupt state */
 	rlwinm	r0,r0,0,17,15	/* clear MSR_EE in r0 */
+#ifdef CONFIG_4xx
+ 	rlwinm	r0,r0,0,23,21	/* clear MSR_DE in r0 */
+#endif
 	SYNC			/* Some chip revs have problems here... */
 	mtmsr	r0		/* Update machine state */
 
@@ -323,6 +326,14 @@
 	mtspr	SPRN_VRSAVE,r0		/* if G4, restore VRSAVE reg */
 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 #endif /* CONFIG_ALTIVEC */
+#if defined(CONFIG_4xx) && !defined(CONFIG_BDI_SWITCH)
+	/* Restore the processor debugging state of the thread.  Only do
+	 * this if we aren't using an Abatron BDI JTAG debugger.  It doesn't
+	 * tolerate others mucking with the debug registers.
+	 */
+	lwz	r0,THREAD+THREAD_DBCR0(r2)
+	mtspr	SPRN_DBCR0,r0
+#endif
 	addi	r0,r1,INT_FRAME_SIZE	/* size of frame */
 	stw	r0,THREAD+KSP(r2)	/* save kernel stack pointer */
 	tophys(r8,r1)
@@ -340,7 +351,7 @@
 	/* We have to "dummy" load from the context save area in case
 	 * these instructions cause an MMU fault.  If this happens
 	 * after we load SRR0/SRR1, our return context is hosed.  -- Dan
-	 * 
+	 *
 	 * This workaround is not enough, we must also make sure the
 	 * actual code for this routine is in the TLB or BAT mapped.
 	 * For 6xx/Power3, we know the code is in a BAT, so this should
@@ -379,7 +390,7 @@
 
 
 /*
- * PROM code for specific machines follows.  Put it 
+ * PROM code for specific machines follows.  Put it
  * here so it's easy to add arch-specific sections later.
  * -- Cort
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/find_name.c linux-2.4.22-pre10/arch/ppc/kernel/find_name.c
--- linux-2.4.21/arch/ppc/kernel/find_name.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/find_name.c	2003-08-01 13:33:50.000000000 +0000
@@ -12,7 +12,7 @@
 	unsigned long addr, cmp, i;
 	FILE *f;
 	char s[256], last[256];
-	
+
 	if ( argc < 2 )
 	{
 		fprintf(stderr, "Usage: %s <address>\n", argv[0]);
@@ -25,13 +25,13 @@
 		/* adjust if addr is relative to kernelbase */
 		if ( addr < PAGE_OFFSET )
 			addr += PAGE_OFFSET;
-		
+
 		if ( (f = fopen( "System.map", "r" )) == NULL )
 		{
 			perror("fopen()\n");
 			exit(-1);
 		}
-		
+
 		while ( !feof(f) )
 		{
 			fgets(s, 255 , f);
@@ -40,9 +40,9 @@
 				break;
 			strcpy( last, s);
 		}
-		
+
 		printf( "%s%s", last, s );
-	}		
+	}
 	fclose(f);
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/gen550_dbg.c linux-2.4.22-pre10/arch/ppc/kernel/gen550_dbg.c
--- linux-2.4.21/arch/ppc/kernel/gen550_dbg.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/gen550_dbg.c	2003-08-01 13:31:28.000000000 +0000
@@ -56,6 +56,7 @@
 unsigned long serial_init(int chan, void *ignored)
 {
 	unsigned long com_port;
+	unsigned char lcr, dlm;
 
 	/* We need to find out which type io we're expecting.  If it's
 	 * 'SERIAL_IO_PORT', we get an offset from the isa_io_base.
@@ -78,22 +79,38 @@
 
 	/* How far apart the registers are. */
 	shift = rs_table[chan].iomem_reg_shift;
-	
+
+	/* save the LCR */
+	lcr = serial_inb(com_port + (UART_LCR << shift));
+
 	/* Access baud rate */
-	serial_outb(com_port + (UART_LCR << shift), 0x80);
+	serial_outb(com_port + (UART_LCR << shift), UART_LCR_DLAB);
+	dlm = serial_inb(com_port + (UART_DLM << shift));
 
-	/* Input clock. */
-	serial_outb(com_port + (UART_DLL << shift),
+	/*
+	 * Test if serial port is unconfigured
+	 * We assume that no-one uses less than 110 baud or
+	 * less than 7 bits per character these days.
+	 *  -- paulus.
+	 */
+	if ((dlm <= 4) && (lcr & 2)) {
+		/* port is configured, put the old LCR back */
+		serial_outb(com_port + (UART_LCR << shift), lcr);
+	}
+	else {
+		/* Input clock. */
+		serial_outb(com_port + (UART_DLL << shift),
 			(rs_table[chan].baud_base / SERIAL_BAUD) & 0xFF);
-	serial_outb(com_port + (UART_DLM << shift),
-			(rs_table[chan].baud_base / SERIAL_BAUD) >> 8);
-	/* 8 data, 1 stop, no parity */
-	serial_outb(com_port + (UART_LCR << shift), 0x03);
-	/* RTS/DTR */
-	serial_outb(com_port + (UART_MCR << shift), 0x03);
+		serial_outb(com_port + (UART_DLM << shift),
+				(rs_table[chan].baud_base / SERIAL_BAUD) >> 8);
+		/* 8 data, 1 stop, no parity */
+		serial_outb(com_port + (UART_LCR << shift), 0x03);
+		/* RTS/DTR */
+		serial_outb(com_port + (UART_MCR << shift), 0x03);
 
-	/* Clear & enable FIFOs */
-	serial_outb(com_port + (UART_FCR << shift), 0x07);
+		/* Clear & enable FIFOs */
+		serial_outb(com_port + (UART_FCR << shift), 0x07);
+	}
 
 	return (com_port);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/gen550_kgdb.c linux-2.4.22-pre10/arch/ppc/kernel/gen550_kgdb.c
--- linux-2.4.21/arch/ppc/kernel/gen550_kgdb.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/gen550_kgdb.c	2003-08-01 13:32:51.000000000 +0000
@@ -7,7 +7,7 @@
  * port(s) to be used can be accomplished by setting
  * ppc_md.early_serial_map to a platform-specific mapping function.
  *
- * Adapted from ppc4xx_kgdb.c. 
+ * Adapted from ppc4xx_kgdb.c.
  *
  * Matt Porter <mporter@mvista.com>
  *
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/head.S linux-2.4.22-pre10/arch/ppc/kernel/head.S
--- linux-2.4.21/arch/ppc/kernel/head.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/head.S	2003-08-01 13:30:36.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- *  PowerPC version 
+ *  PowerPC version
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
@@ -66,7 +66,7 @@
 	mtspr	DBAT##n##U,RA;		\
 	mtspr	DBAT##n##L,RB;		\
 1:
-#endif /* CONFIG_PPC64BRIDGE */	 
+#endif /* CONFIG_PPC64BRIDGE */
 
 	.text
 	.globl	_stext
@@ -79,7 +79,7 @@
 	.text
 	.globl	_start
 _start:
-	/* 
+	/*
 	 * These are here for legacy reasons, the kernel used to
 	 * need to look like a coff function entry for the pmac
 	 * but we're always started by some kind of bootloader now.
@@ -145,8 +145,8 @@
 	bl	early_init
 
 #ifdef CONFIG_APUS
-/* On APUS the __va/__pa constants need to be set to the correct 
- * values before continuing. 
+/* On APUS the __va/__pa constants need to be set to the correct
+ * values before continuing.
  */
 	mr	r4,r30
 	bl	fix_mem_constants
@@ -1181,7 +1181,7 @@
 
 /*
  * Map the memory where the exception handlers will
- * be copied to when hash constants have been patched.  
+ * be copied to when hash constants have been patched.
  */
 #ifdef CONFIG_APUS_FAST_EXCEPT
 	lis	r8,0xfff0
@@ -1277,7 +1277,7 @@
 	lis	r3,-KERNELBASE@h
 	bl	init_idle_6xx
 #endif /* CONFIG_6xx */
-	
+
 	/* get current */
 	lis	r2,current_set@h
 	ori	r2,r2,current_set@l
@@ -1498,13 +1498,13 @@
 	isync
 	blr
 
-/* 
+/*
  * An undocumented "feature" of 604e requires that the v bit
  * be cleared before changing BAT values.
  *
  * Also, newer IBM firmware does not clear bat3 and 4 so
  * this makes sure it's done.
- *  -- Cort 
+ *  -- Cort
  */
 clear_bats:
 	li	r20,0
@@ -1575,7 +1575,7 @@
 	sync
 	RFI
 
-#ifndef CONFIG_POWER4	
+#ifndef CONFIG_POWER4
 /*
  * Use the first pair of BAT registers to map the 1st 16MB
  * of RAM to KERNELBASE.  From this point on we can't safely
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/head_4xx.S linux-2.4.22-pre10/arch/ppc/kernel/head_4xx.S
--- linux-2.4.21/arch/ppc/kernel/head_4xx.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/head_4xx.S	2003-08-01 13:33:07.000000000 +0000
@@ -11,6 +11,13 @@
  *      PowerPC 403GCX modifications.
  *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
  *      PowerPC 403GCX/405GP modifications.
+ *    Copyright 2000 MontaVista Software Inc.
+ *	PPC405 modifications
+ *      PowerPC 403GCX/405GP modifications.
+ * 	Author: MontaVista Software, Inc.
+ *         	frank_rowand@mvista.com or source@mvista.com
+ * 	   	debbie_chu@mvista.com
+ *
  *
  *    Module name: head_4xx.S
  *
@@ -25,45 +32,32 @@
  */
 
 #include <linux/config.h>
-
 #include <asm/processor.h>
 #include <asm/page.h>
-#include <asm/pgtable.h>
 #include <asm/mmu.h>
-
+#include <asm/pgtable.h>
+#include <asm/ibm4xx.h>
+#include <asm/cputable.h>
 #include <asm/ppc_asm.h>
 #include "ppc_defs.h"
 
-
 /* Preprocessor Defines */
 
 #define	STND_EXC	0
 #define	CRIT_EXC	1
 
-###
-### Check to make sure the right processor has been defined.
-###
-
-#if !defined(CONFIG_4xx)
-#error "This file is only appropriate for kernels supporting the PPC4xx."
-#endif
-
-###
-### Execution entry point.
-###
-
-###
-### As with the other PowerPC ports, it is expected that when code
-### execution begins here, the following registers contain valid, yet
-### optional, information:
-###
-###   r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
-###   r4 - Starting address of the init RAM disk
-###   r5 - Ending address of the init RAM disk
-###   r6 - Start of kernel command line string (e.g. "mem=96m")
-###   r7 - End of kernel command line string
-### 
-	
+/* As with the other PowerPC ports, it is expected that when code
+ * execution begins here, the following registers contain valid, yet
+ * optional, information:
+ *
+ *   r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
+ *   r4 - Starting address of the init RAM disk
+ *   r5 - Ending address of the init RAM disk
+ *   r6 - Start of kernel command line string (e.g. "mem=96m")
+ *   r7 - End of kernel command line string
+ *
+ * This is all going to change RSN when we add bi_recs.......  -- Dan
+ */
 	.text
 _GLOBAL(_stext)
 _GLOBAL(_start)
@@ -75,98 +69,72 @@
 	nop
 	nop
 
-	## Save residual data, init RAM disk, and command line parameters
-	
+	/* Save parameters we are passed.
+	*/
 	mr	r31,r3
 	mr	r30,r4
 	mr	r29,r5
 	mr	r28,r6
 	mr	r27,r7
+	li	r24,0		/* CPU number */
 
-	## Set the ID for this CPU
-
-	li	r24,0
-
-	## Invalidate all TLB entries
-
-	tlbia
-	
-	## We should still be executing code at physical address 0x0000xxxx
-	## at this point. However, start_here is at virtual address
-	## 0xC000xxxx. So, set up a TLB mapping to cover this once
-	## translation is enabled.
-
-	lis	r3,KERNELBASE@h		# Load the kernel virtual address
-	ori	r3,r3,KERNELBASE@l
-	tophys(r4,r3)			# Load the kernel physical address
-
-	## Save the existing PID and load the kernel PID.
-		
-	mfspr	r7,SPRN_PID		# Save the old PID
-	li	r0,0
-	mtspr	SPRN_PID,r0		# Load the kernel PID
-
-	## Configure and load entry into TLB slot 0.
-	
-	clrrwi	r4,r4,10		# Mask off the real page number
-	ori	r4,r4,(TLB_WR | TLB_EX)	# Set the write and execute bits
-	
-	clrrwi	r3,r3,10		# Mask off the effective page number
-	ori	r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
-
-	tlbwe	r4,r0,TLB_DATA		# Load the data portion of the entry
-	tlbwe	r3,r0,TLB_TAG		# Load the tag portion of the entry
-	isync
-	
-	mtspr	SPRN_PID,r7		# Restore the existing PID
-	
-	## Establish the exception vector base
-	
-	lis	r4,KERNELBASE@h		# EVPR only uses the high 16-bits
-	tophys(r0,r4)			# Use the physical address
-	mtspr	SPRN_EVPR,r0
+	/* We have to turn on the MMU right away so we get cache modes
+	 * set correctly.
+	 */
+	bl	initial_mmu
 
-	## Enable the MMU and jump to the main PowerPC kernel start-up code
+/* We now have the lower 16 Meg mapped into TLB entries, and the caches
+ * ready to work.
+ */
+turn_on_mmu:
+	li	r0,MSR_KERNEL
+	mtspr	SRR1,r0
+	lis	r0,start_here@h
+	ori	r0,r0,start_here@l
+	mtspr	SRR0,r0
+	SYNC
+	rfi				/* enables MMU */
+	b	.			/* prevent prefetch past rfi */
 
-	mfmsr	r0			# Get the machine state register
-	ori	r0,r0,(MSR_DR | MSR_IR)	# Enable data and instr. translation
-	mtspr	SPRN_SRR1,r0		# Set up the new machine state register
-	lis	r0,start_here@h		
-	ori	r0,r0,start_here@l	
-	mtspr	SPRN_SRR0,r0		# Set up the new instruction pointer
-	rfi				# Jump to start_here w/ translation on
-
-
-###
-### Exception vector entry code. This code runs with address translation
-### turned off (i.e. using physical addresses). We assume SPRG3 has the
-### physical address of the current task thread_struct.
-### 
+#ifdef CONFIG_405LP
+	/* Reserve space for ibm405lp_wakeup_info.  This contains the physical
+	 * address of a struct ibm405lp_wakeup_info which is used by the
+	 * firmware to pass control back to the kernel on cryo wakeup.  Because
+	 * the firmware uses this, the absolute address is fixed: don't try
+	 * changing it. */
+	. = 0xfc
+	.global ibm405lp_wakeup_info
+ibm405lp_wakeup_info:
+	.long	0x0
+#endif
 
-	## Common exception code for all exception types.
+/* Exception vector entry code. This code runs with address translation
+ * turned off (i.e. using physical addresses). We assume SPRG3 has the
+ * physical address of the current task thread_struct.
+ */
 
 #define COMMON_PROLOG							     \
-0:	mtspr	SPRN_SPRG0,r20;		/* We need r20, move it to SPRG0   */\
-	mtspr	SPRN_SPRG1,r21;		/* We need r21, move it to SPRG1   */\
-	mfcr	r20;			/* We need the CR, move it to r20  */\
-	mfspr	r21,SPRN_SPRG2;		/* Exception stack to use	   */\
-	cmpwi	cr0,r21,0;		/* From user mode or RTAS?	   */\
-	bne	1f;			/* Not RTAS, branch		   */\
-	tophys(r21, r1);		/* Convert vka in r1 to pka in r21 */\
-	subi	r21,r21,INT_FRAME_SIZE;	/* Allocate an exception frame	   */\
-1:	stw	r20,_CCR(r21);		/* Save CR on the stack		   */\
-	stw	r22,GPR22(r21);		/* Save r22 on the stack	   */\
-	stw	r23,GPR23(r21);		/* r23 Save on the stack	   */\
-	mfspr	r20,SPRN_SPRG0;		/* Get r20 back out of SPRG0	   */\
-	stw	r20,GPR20(r21);		/* Save r20 on the stack	   */\
-	mfspr	r22,SPRN_SPRG1;		/* Get r21 back out of SPRG0	   */\
-	stw	r22,GPR21(r21);		/* Save r21 on the stack	   */\
-	mflr	r20;							     \
-	stw	r20,_LINK(r21);		/* Save LR on the stack		   */\
-	mfctr	r22;							     \
-	stw	r22,_CTR(r21);		/* Save CTR on the stack	   */\
-	mfspr	r20,XER;						     \
-	stw	r20,_XER(r21);		/* Save XER on the stack	   */
+0:	mtspr	SPRN_SPRG0,r20;         /* We need r20, move it to SPRG0   */\
+	mtspr	SPRN_SPRG1,r21;         /* We need r21, move it to SPRG1   */\
+	mfcr	r20;                    /* We need the CR, move it to r20  */\
+	mfspr	r21,SPRN_SPRG2;         /* Exception stack to use          */\
+	cmpwi	cr0,r21,0;              /* From user mode or RTAS?         */\
+	bne	1f;                     /* Not RTAS, branch                */\
+	tophys(r21, r1);                /* Convert vka in r1 to pka in r21 */\
+	subi	r21,r21,INT_FRAME_SIZE; /* Allocate an exception frame     */\
+1:	stw	r20,_CCR(r21);          /* Save CR on the stack            */\
+	stw	r22,GPR22(r21);         /* Save r22 on the stack           */\
+	stw	r23,GPR23(r21);         /* r23 Save on the stack           */\
+	mfspr	r20,SPRN_SPRG0;         /* Get r20 back out of SPRG0       */\
+	stw	r20,GPR20(r21);         /* Save r20 on the stack           */\
+	mfspr	r22,SPRN_SPRG1;         /* Get r21 back out of SPRG0       */\
+	stw	r22,GPR21(r21);         /* Save r21 on the stack           */\
+	mflr	r20;                                                         \
+	stw	r20,_LINK(r21);         /* Save LR on the stack            */\
+	mfctr	r22;                                                         \
+	stw	r22,_CTR(r21);          /* Save CTR on the stack           */\
+	mfspr	r20,XER;                                                     \
+	stw	r20,_XER(r21);          /* Save XER on the stack           */
 
 #define	COMMON_EPILOG							     \
 	stw	r0,GPR0(r21);		/* Save r0 on the stack		   */\
@@ -177,25 +145,22 @@
 	SAVE_4GPRS(3, r21);		/* Save r3 through r6 on the stack */\
 	SAVE_GPR(7, r21);		/* Save r7 on the stack		   */
 
-	## Common exception code for standard (non-critical) exceptions.
-
 #define	STND_EXCEPTION_PROLOG						     \
 	COMMON_PROLOG;							     \
 	mfspr	r22,SPRN_SRR0;		/* Faulting instruction address	   */\
+	lis	r20,MSR_WE@h;						     \
 	mfspr	r23,SPRN_SRR1;		/* MSR at the time of fault	   */\
+	andc	r23,r23,r20;		/* disable processor wait state    */\
 	COMMON_EPILOG;
 
-	## Common exception code for critical exceptions.
-	
 #define	CRIT_EXCEPTION_PROLOG						     \
 	COMMON_PROLOG;							     \
 	mfspr	r22,SPRN_SRR2;		/* Faulting instruction address	   */\
+	lis	r20,MSR_WE@h;						     \
 	mfspr	r23,SPRN_SRR3;		/* MSR at the time of fault	   */\
+	andc	r23,r23,r20;		/* disable processor wait state    */\
 	COMMON_EPILOG;
 
-###
-### Macros for specific exception types
-### 
 
 #define	START_EXCEPTION(n, label)					     \
 	. = n;								     \
@@ -206,8 +171,8 @@
 	bl	transfer_to_handler;					     \
 	.long	func;							     \
 	.long	ret_from_except
-	
-		
+
+
 #define STND_EXCEPTION(n, label, func)					     \
 	START_EXCEPTION(n, label);					     \
 	STND_EXCEPTION_PROLOG;						     \
@@ -216,7 +181,7 @@
 	li	r20,MSR_KERNEL;						     \
 	FINISH_EXCEPTION(func)
 
-	
+
 #define	CRIT_EXCEPTION(n, label, func)					     \
 	START_EXCEPTION(n, label);					     \
 	CRIT_EXCEPTION_PROLOG;						     \
@@ -225,47 +190,191 @@
 	li	r20,MSR_KERNEL;						     \
 	FINISH_EXCEPTION(func)
 
-	
-###
-### Exception vectors.
-### 
-	
-### 0x0100 - Critical Interrupt Exception
 
+/* Exception vectors.
+*/
+
+/* 0x0100 - Critical Interrupt Exception
+*/
 	CRIT_EXCEPTION(0x0100,	CriticalInterrupt,	UnknownException)
 
-### 0x0200 - Machine Check Exception
-	
-	CRIT_EXCEPTION(0x0200,	MachineCheck,		MachineCheckException)
+/* 0x0200 - Machine Check Exception
+*/
+	START_EXCEPTION(0x0200, MachineCheck)
+	CRIT_EXCEPTION_PROLOG
+
+	/*
+	lis	r4,0x0400
+	mtdcr	DCRN_POB0_BESR0,r4
+	*/
+#ifdef DCRN_POB0_BEAR
+	mfdcr	r4,DCRN_POB0_BEAR
+	mfdcr	r4,DCRN_POB0_BESR0
+	mfdcr	r4,DCRN_POB0_BESR1
+#endif
 
-### 0x0300 - Data Storage Exception
+#ifdef DCRN_PLB0_BEAR
+	mfdcr	r4,DCRN_PLB0_ACR
+	mfdcr	r4,DCRN_PLB0_BEAR
+	mfdcr	r4,DCRN_PLB0_BESR
+#endif
 
-	START_EXCEPTION(0x0300,	DataAccess)
-	STND_EXCEPTION_PROLOG
-	mfspr	r5,SPRN_ESR		# Grab the ESR, save it, pass as arg3
-	stw	r5,_ESR(r21)
-	mfspr	r4,SPRN_DEAR		# Grab the DEAR, save it, pass as arg2
-	stw	r4,_DEAR(r21)
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-	li	r7,STND_EXC		# This is a standard exception
+	li	r7,CRIT_EXC
 	li	r20,MSR_KERNEL
-	rlwimi	r20,r23,0,16,16		# Copy EE bit from the saved MSR
-	FINISH_EXCEPTION(do_page_fault)	# do_page_fault(regs, ESR, DEAR)
-	
-### 0x0400 - Instruction Storage Exception
+	FINISH_EXCEPTION(MachineCheckException)
+
+/* 0x0300 - Data Storage Exception
+ * This happens for just a few reasons.  U0 set (but we don't do that),
+ * or zone protection fault (user violation, write to protected page).
+ * If this is just an update of modified status, we do that quickly
+ * and exit.  Otherwise, we call heavywight functions to do the work.
+ */
+	START_EXCEPTION(0x0300,	DataStore)
+	mtspr	SPRG0, r20		/* Save some working registers */
+	mtspr	SPRG1, r21
+#ifdef CONFIG_403GCX
+	stw     r22, 0(r0)
+	stw     r23, 4(r0)
+	mfcr    r21
+	mfspr   r22, SPRN_PID
+	stw     r21, 8(r0)
+	stw     r22, 12(r0)
+#else
+	mtspr	SPRG4, r22
+	mtspr	SPRG5, r23
+	mfcr	r21
+	mfspr	r22, SPRN_PID
+	mtspr	SPRG7, r21
+	mtspr	SPRG6, r22
+#endif
+
+	/* First, check if it was a zone fault (which means a user
+	* tried to access a kernel or read-protected page - always
+	* a SEGV).  All other faults here must be stores, so no
+	* need to check ESR_DST as well. */
+	mfspr	r20, SPRN_ESR
+	andis.	r20, r20, ESR_DIZ@h
+	bne	2f
+
+	mfspr	r20, SPRN_DEAR		/* Get faulting address */
+
+	/* If we are faulting a kernel address, we have to use the
+	 * kernel page tables.
+	 */
+	andis.	r21, r20, 0x8000
+	beq	3f
+	lis	r21, swapper_pg_dir@h
+	ori	r21, r21, swapper_pg_dir@l
+	li	r23, 0
+	mtspr	SPRN_PID, r23		/* TLB will have 0 TID */
+	b	4f
 
+	/* Get the PGD for the current thread.
+	 */
+3:
+	mfspr	r21,SPRG3
+	lwz	r21,PGDIR(r21)
+4:
+	tophys(r21, r21)
+	rlwimi	r21, r20, 12, 20, 29	/* Create L1 (pgdir/pmd) address */
+	lwz	r21, 0(r21)		/* Get L1 entry */
+	rlwinm.	r22, r21, 0, 0, 19	/* Extract L2 (pte) base address */
+	beq	2f			/* Bail if no table */
+
+	tophys(r22, r22)
+	rlwimi	r22, r20, 22, 20, 29	/* Compute PTE address */
+	lwz	r21, 0(r22)		/* Get Linux PTE */
+
+	andi.	r23, r21, _PAGE_RW	/* Is it writeable? */
+	beq	2f			/* Bail if not */
+
+	/* Update 'changed'.
+	*/
+	ori	r21, r21, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
+	stw	r21, 0(r22)		/* Update Linux page table */
+
+	/* Most of the Linux PTE is ready to load into the TLB LO.
+	 * We set ZSEL, where only the LS-bit determines user access.
+	 * We set execute, because we don't have the granularity to
+	 * properly set this at the page level (Linux problem).
+	 * If shared is set, we cause a zero PID->TID load.
+	 * Many of these bits are software only.  Bits we don't set
+	 * here we (properly should) assume have the appropriate value.
+	 */
+	li	r22, 0x0ce2
+	andc	r21, r21, r22		/* Make sure 20, 21 are zero */
+
+	/* find the TLB index that caused the fault.  It has to be here.
+	*/
+	tlbsx	r23, 0, r20
+
+	tlbwe	r21, r23, TLB_DATA		/* Load TLB LO */
+
+	/* Done...restore registers and get out of here.
+	*/
+#ifdef CONFIG_403GCX
+	lwz     r22, 12(r0)
+	lwz     r21, 8(r0)
+	mtspr   SPRN_PID, r22
+	mtcr    r21
+	lwz     r23, 4(r0)
+	lwz     r22, 0(r0)
+#else
+	mfspr	r22, SPRG6
+	mfspr	r21, SPRG7
+	mtspr	SPRN_PID, r22
+	mtcr	r21
+	mfspr	r23, SPRG5
+	mfspr	r22, SPRG4
+#endif
+	mfspr	r21, SPRG1
+	mfspr	r20, SPRG0
+	PPC405_ERR77_SYNC
+	rfi			/* Should sync shadow TLBs */
+	b	.		/* prevent prefetch past rfi */
+
+2:
+	/* The bailout.  Restore registers to pre-exception conditions
+	 * and call the heavyweights to help us out.
+	 */
+#ifdef CONFIG_403GCX
+	lwz     r22, 12(r0)
+	lwz     r21, 8(r0)
+	mtspr   SPRN_PID, r22
+	mtcr    r21
+	lwz     r23, 4(r0)
+	lwz     r22, 0(r0)
+#else
+	mfspr	r22, SPRG6
+	mfspr	r21, SPRG7
+	mtspr	SPRN_PID, r22
+	mtcr	r21
+	mfspr	r23, SPRG5
+	mfspr	r22, SPRG4
+#endif
+	mfspr	r21, SPRG1
+	mfspr	r20, SPRG0
+	b	DataAccess
+
+/* 0x0400 - Instruction Storage Exception
+ * I don't know why it is called "Storage"....This is caused by a fetch
+ * from non-execute or guarded pages.
+ */
 	START_EXCEPTION(0x0400, InstructionAccess)
 	STND_EXCEPTION_PROLOG
-	mr	r4,r22			# Pass SRR0 as arg2
-	mr	r5,r23			# Pass SRR1 as arg3
+	mfspr	r5,SPRN_ESR		/* Grab the ESR, save it, not really needed */
+	stw	r5,_ESR(r21)
+	mr	r4,r22			/* Pass SRR0 as arg2 */
+	li	r5,0			/* Pass zero as arg3 */
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-	li	r7,STND_EXC		# This is a standard exception
+	li	r7,STND_EXC
 	li	r20,MSR_KERNEL
-	rlwimi	r20,r23,0,16,16		# Copy EE bit from the saved MSR
-	FINISH_EXCEPTION(do_page_fault)	# do_page_fault(regs, SRR0, SRR1)
-	
-### 0x0500 - External Interrupt Exception
+	rlwimi	r20,r23,0,16,16		/* Copy EE bit from the saved MSR */
+	FINISH_EXCEPTION(do_page_fault)	/* do_page_fault(regs, SRR0, SRR1) */
 
+/* 0x0500 - External Interrupt Exception
+*/
 	START_EXCEPTION(0x0500, HardwareInterrupt)
 	STND_EXCEPTION_PROLOG
 	addi	r3,r1,STACK_FRAME_OVERHEAD
@@ -277,54 +386,72 @@
 	.long	do_IRQ
 	.long	ret_from_intercept
 
-### 0x0600 - Alignment Exception
-	
+/* 0x0600 - Alignment Exception
+*/
 	START_EXCEPTION(0x0600, Alignment)
 	STND_EXCEPTION_PROLOG
-	mfspr	r4,SPRN_DEAR		# Grab the DEAR and save it
+	mfspr	r4,SPRN_DEAR		/* Grab the DEAR and save it */
 	stw	r4,_DEAR(r21)
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-	li	r7,STND_EXC		# This is a standard exception
+	li	r7,STND_EXC
 	li	r20,MSR_KERNEL
-	rlwimi	r20,r23,0,16,16		# Copy EE bit from the saved MSR
+	rlwimi	r20,r23,0,16,16		/* Copy EE bit from the saved MSR */
 	FINISH_EXCEPTION(AlignmentException)
 
-### 0x0700 - Program Exception
-
+/* 0x0700 - Program Exception
+*/
 	START_EXCEPTION(0x0700,	ProgramCheck)
 	STND_EXCEPTION_PROLOG
+	mfspr	r4,SPRN_ESR		/* Grab the ESR, save it */
+	stw	r4,_ESR(r21)
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-	li	r7,STND_EXC		# This is a standard exception
+	li	r7,STND_EXC
 	li	r20,MSR_KERNEL
-	rlwimi	r20,r23,0,16,16		# Copy EE bit from the saved MSR
+	rlwimi	r20,r23,0,16,16		/* Copy EE bit from the saved MSR */
 	FINISH_EXCEPTION(ProgramCheckException)
-	
-	STND_EXCEPTION(0x0800,	Trap_08,		UnknownException)
+
+
+/* I'm stealing this unused vector location to build a standard exception
+ * frame for Data TLB Access errors.  The other Data TLB exceptions will bail
+ * out to this point if they can't resolve the lightweight TLB fault.
+ */
+	START_EXCEPTION(0x0800,	DataAccess)
+	STND_EXCEPTION_PROLOG
+	mfspr	r5,SPRN_ESR		/* Grab the ESR, save it, pass arg3 */
+	stw	r5,_ESR(r21)
+	mfspr	r4,SPRN_DEAR		/* Grab the DEAR, save it, pass arg2 */
+	stw	r4,_DEAR(r21)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r7,STND_EXC
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		/* Copy EE bit from the saved MSR */
+	FINISH_EXCEPTION(do_page_fault)	/* do_page_fault(regs, ESR, DEAR) */
+
 	STND_EXCEPTION(0x0900,	Trap_09,		UnknownException)
 	STND_EXCEPTION(0x0A00,	Trap_0A,		UnknownException)
-	STND_EXCEPTION(0x0B00,	Trap_0B,		UnknownException)		
-### 0x0C00 - System Call Exception
-
+	STND_EXCEPTION(0x0B00,	Trap_0B,		UnknownException)
+/* 0x0C00 - System Call Exception
+*/
 	START_EXCEPTION(0x0C00,	SystemCall)
 	STND_EXCEPTION_PROLOG
 	stw	r3,ORIG_GPR3(r21)
-	li	r7,STND_EXC		# This is a standard exception
+	li	r7,STND_EXC
 	li	r20,MSR_KERNEL
-	rlwimi	r20,r23,0,16,16		# Copy EE bit from the saved MSR
+	rlwimi	r20,r23,0,16,16		/* Copy EE bit from the saved MSR */
 	FINISH_EXCEPTION(DoSyscall)
 
 	STND_EXCEPTION(0x0D00,	Trap_0D,		UnknownException)
 	STND_EXCEPTION(0x0E00,	Trap_0E,		UnknownException)
 	STND_EXCEPTION(0x0F00,	Trap_0F,		UnknownException)
 
-### 0x1000 - Programmable Interval Timer (PIT) Exception
-
+/* 0x1000 - Programmable Interval Timer (PIT) Exception
+*/
 	START_EXCEPTION(0x1000,	Decrementer)
 	STND_EXCEPTION_PROLOG
-	lis	r0,TSR_PIS@h		# Set-up the PIT exception mask
-	mtspr	SPRN_TSR,r0		# Clear the PIT exception
+	lis	r0,TSR_PIS@h		/* Set-up the PIT exception mask */
+	mtspr	SPRN_TSR,r0		/* Clear the PIT exception */
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-	li	r7,STND_EXC		# This is a standard exception
+	li	r7,STND_EXC
 	li	r20,MSR_KERNEL
 	bl	transfer_to_handler
 _GLOBAL(timer_interrupt_intercept)
@@ -332,28 +459,217 @@
 	.long	ret_from_intercept
 
 #if 0
-### 0x1010 - Fixed Interval Timer (FIT) Exception
-	
+/* NOTE:
+ * FIT and WDT handlers are not implemented yet.
+ */
+
+/* 0x1010 - Fixed Interval Timer (FIT) Exception
+*/
 	STND_EXCEPTION(0x1010,	FITException,		UnknownException)
 
-### 0x1020 - Watchdog Timer (WDT) Exception
+/* 0x1020 - Watchdog Timer (WDT) Exception
+*/
 
 	CRIT_EXCEPTION(0x1020,	WDTException,		UnknownException)
 #endif
 
-### 0x1100 - Data TLB Miss Exception
+/* 0x1100 - Data TLB Miss Exception
+ * As the name implies, translation is not in the MMU, so search the
+ * page tables and fix it.  The only purpose of this function is to
+ * load TLB entries from the page table if they exist.
+ */
+	START_EXCEPTION(0x1100,	DTLBMiss)
+	mtspr	SPRG0, r20		/* Save some working registers */
+	mtspr	SPRG1, r21
+#ifdef CONFIG_403GCX
+	stw     r22, 0(r0)
+	stw     r23, 4(r0)
+	mfcr    r21
+	mfspr   r22, SPRN_PID
+	stw     r21, 8(r0)
+	stw     r22, 12(r0)
+#else
+	mtspr	SPRG4, r22
+	mtspr	SPRG5, r23
+	mfcr	r21
+	mfspr	r22, SPRN_PID
+	mtspr	SPRG7, r21
+	mtspr	SPRG6, r22
+#endif
+	mfspr	r20, SPRN_DEAR		/* Get faulting address */
 
-	STND_EXCEPTION(0x1100,	DTLBMiss, 		PPC4xx_dtlb_miss)
+	/* If we are faulting a kernel address, we have to use the
+	 * kernel page tables.
+	 */
+	andis.	r21, r20, 0x8000
+	beq	3f
+	lis	r21, swapper_pg_dir@h
+	ori	r21, r21, swapper_pg_dir@l
+	li	r23, 0
+	mtspr	SPRN_PID, r23		/* TLB will have 0 TID */
+	b	4f
 
-### 0x1200 - Instruction TLB Miss Exception
+	/* Get the PGD for the current thread.
+	 */
+3:
+	mfspr	r21,SPRG3
+	lwz	r21,PGDIR(r21)
+4:
+	tophys(r21, r21)
+	rlwimi	r21, r20, 12, 20, 29	/* Create L1 (pgdir/pmd) address */
+	lwz	r21, 0(r21)		/* Get L1 entry */
+	rlwinm.	r22, r21, 0, 0, 19	/* Extract L2 (pte) base address */
+	beq	2f			/* Bail if no table */
+
+	tophys(r22, r22)
+	rlwimi	r22, r20, 22, 20, 29	/* Compute PTE address */
+	lwz	r21, 0(r22)		/* Get Linux PTE */
+	andi.	r23, r21, _PAGE_PRESENT
+	beq	2f
 
-	STND_EXCEPTION(0x1200,	ITLBMiss, 		PPC4xx_itlb_miss)
+	ori	r21, r21, _PAGE_ACCESSED
+	stw	r21, 0(r22)
+
+	/* Most of the Linux PTE is ready to load into the TLB LO.
+	 * We set ZSEL, where only the LS-bit determines user access.
+	 * We set execute, because we don't have the granularity to
+	 * properly set this at the page level (Linux problem).
+	 * If shared is set, we cause a zero PID->TID load.
+	 * Many of these bits are software only.  Bits we don't set
+	 * here we (properly should) assume have the appropriate value.
+	 */
+	li	r22, 0x0ce2
+	andc	r21, r21, r22		/* Make sure 20, 21 are zero */
+
+	b	finish_tlb_load
+
+
+2:
+	/* The bailout.  Restore registers to pre-exception conditions
+	 * and call the heavyweights to help us out.
+	 */
+#ifdef CONFIG_403GCX
+	lwz     r22, 12(r0)
+	lwz     r21, 8(r0)
+	mtspr   SPRN_PID, r22
+	mtcr    r21
+	lwz     r23, 4(r0)
+	lwz     r22, 0(r0)
+#else
+	mfspr	r22, SPRG6
+	mfspr	r21, SPRG7
+	mtspr	SPRN_PID, r22
+	mtcr	r21
+	mfspr	r23, SPRG5
+	mfspr	r22, SPRG4
+#endif
+	mfspr	r21, SPRG1
+	mfspr	r20, SPRG0
+	b	DataAccess
+
+/* 0x1200 - Instruction TLB Miss Exception
+ * Nearly the same as above, except we get our information from different
+ * registers and bailout to a different point.
+ */
+	START_EXCEPTION(0x1200,	ITLBMiss)
+	mtspr	SPRG0, r20		/* Save some working registers */
+	mtspr	SPRG1, r21
+#ifdef CONFIG_403GCX
+	stw     r22, 0(r0)
+	stw     r23, 4(r0)
+	mfcr    r21
+	mfspr   r22, SPRN_PID
+	stw     r21, 8(r0)
+	stw     r22, 12(r0)
+#else
+	mtspr	SPRG4, r22
+	mtspr	SPRG5, r23
+	mfcr	r21
+	mfspr	r22, SPRN_PID
+	mtspr	SPRG7, r21
+	mtspr	SPRG6, r22
+#endif
+	mfspr	r20, SRR0		/* Get faulting address */
+
+	/* If we are faulting a kernel address, we have to use the
+	 * kernel page tables.
+	 */
+	andis.	r21, r20, 0x8000
+	beq	3f
+	lis	r21, swapper_pg_dir@h
+	ori	r21, r21, swapper_pg_dir@l
+	li	r23, 0
+	mtspr	SPRN_PID, r23		/* TLB will have 0 TID */
+	b	4f
+
+	/* Get the PGD for the current thread.
+	 */
+3:
+	mfspr	r21,SPRG3
+	lwz	r21,PGDIR(r21)
+4:
+	tophys(r21, r21)
+	rlwimi	r21, r20, 12, 20, 29	/* Create L1 (pgdir/pmd) address */
+	lwz	r21, 0(r21)		/* Get L1 entry */
+	rlwinm.	r22, r21, 0, 0, 19	/* Extract L2 (pte) base address */
+	beq	2f			/* Bail if no table */
+
+	tophys(r22, r22)
+	rlwimi	r22, r20, 22, 20, 29	/* Compute PTE address */
+	lwz	r21, 0(r22)		/* Get Linux PTE */
+	andi.	r23, r21, _PAGE_PRESENT
+	beq	2f
+
+	ori	r21, r21, _PAGE_ACCESSED
+	stw	r21, 0(r22)
+
+	/* Most of the Linux PTE is ready to load into the TLB LO.
+	 * We set ZSEL, where only the LS-bit determines user access.
+	 * We set execute, because we don't have the granularity to
+	 * properly set this at the page level (Linux problem).
+	 * If shared is set, we cause a zero PID->TID load.
+	 * Many of these bits are software only.  Bits we don't set
+	 * here we (properly should) assume have the appropriate value.
+	 */
+	li	r22, 0x0ce2
+	andc	r21, r21, r22		/* Make sure 20, 21 are zero */
+
+	b	finish_tlb_load
+
+2:
+	/* The bailout.  Restore registers to pre-exception conditions
+	 * and call the heavyweights to help us out.
+	 */
+#ifdef CONFIG_403GCX
+	lwz     r22, 12(r0)
+	lwz     r21, 8(r0)
+	mtspr   SPRN_PID, r22
+	mtcr    r21
+	lwz     r23, 4(r0)
+	lwz     r22, 0(r0)
+#else
+	mfspr	r22, SPRG6
+	mfspr	r21, SPRG7
+	mtspr	SPRN_PID, r22
+	mtcr	r21
+	mfspr	r23, SPRG5
+	mfspr	r22, SPRG4
+#endif
+	mfspr	r21, SPRG1
+	mfspr	r20, SPRG0
+	b	InstructionAccess
 
 	STND_EXCEPTION(0x1300,	Trap_13,		UnknownException)
 	STND_EXCEPTION(0x1400,	Trap_14,		UnknownException)
 	STND_EXCEPTION(0x1500,	Trap_15,		UnknownException)
 	STND_EXCEPTION(0x1600,	Trap_16,		UnknownException)
+#ifdef CONFIG_IBM405_ERR51
+	/* 405GP errata 51 */
+	START_EXCEPTION(0x1700, Trap_17)
+	b DTLBMiss
+#else
 	STND_EXCEPTION(0x1700,	Trap_17,		UnknownException)
+#endif
 	STND_EXCEPTION(0x1800,	Trap_18,		UnknownException)
 	STND_EXCEPTION(0x1900,	Trap_19,		UnknownException)
 	STND_EXCEPTION(0x1A00,	Trap_1A,		UnknownException)
@@ -362,73 +678,214 @@
 	STND_EXCEPTION(0x1D00,	Trap_1D,		UnknownException)
 	STND_EXCEPTION(0x1E00,	Trap_1E,		UnknownException)
 	STND_EXCEPTION(0x1F00,	Trap_1F,		UnknownException)
-	
-### 0x2000 - Debug Exception
 
-	CRIT_EXCEPTION(0x2000,	DebugTrap,		UnknownException)
+/* 0x2000 - Debug Exception
+*/
+	START_EXCEPTION(0x2000, DebugTrap)
+	b	check_single_step_in_exception
+ret_to_debug_exception:
+	CRIT_EXCEPTION_PROLOG
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r7,CRIT_EXC;
+        li      r20,MSR_KERNEL
+	FINISH_EXCEPTION(DebugException)
+
+/* Make sure the final interrupt handler has not spilled past the
+ * end of its allotted space.
+ */
+        .=0x2100
 
-###
-### Other PowerPC processors, namely those derived from the 6xx-series
-### have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
-### However, for the 4xx-series processors these are neither defined nor
-### reserved.
-### 
-
-### 
-### This code finishes saving the registers to the exception frame
-### and jumps to the appropriate handler for the exception, turning
-### on address translation.
-###
+/* Check for a single step debug exception while in an exception
+ * handler before state has been saved.  This is to catch the case
+ * where an instruction that we are trying to single step causes
+ * an exception (eg ITLB miss) and thus the first instruction of
+ * the exception handler generates a single step debug exception.
+ *
+ * If we get a debug trap on the first instruction of an exception handler,
+ * we reset the MSR_DE in the _exception handlers_ MSR (the debug trap is
+ * a critical exception, so we are using SPRN_SRR3 to manipulate the MSR).
+ * The exception handler was handling a non-critical interrupt, so it will
+ * save (and later restore) the MSR via SPRN_SRR1, which will still have
+ * the MSR_DE bit set.
+ */
+check_single_step_in_exception:
 
+	/* This first instruction was already executed by the exception
+	 * handler and must be the first instruction of every exception
+	 * handler.
+	 */
+	mtspr	SPRN_SPRG0,r20		/* Save some working registers... */
+	mtspr	SPRN_SPRG1,r21
+	mfcr	r20			/* ..and the cr because we change it */
+
+	mfspr   r21,SPRN_SRR3		/* MSR at the time of fault */
+	andi.   r21,r21,MSR_PR
+	bne+    2f			/* trapped from problem state */
+
+	mfspr   r21,SPRN_SRR2		/* Faulting instruction address */
+	cmplwi  r21,0x2100
+	bgt+    2f			/* address above exception vectors */
+
+	lis     r21,DBSR_IC@h           /* Remove the trap status */
+	mtspr   SPRN_DBSR,r21
+
+	mfspr	r21,SPRN_SRR3
+	rlwinm	r21,r21,0,23,21		/* clear MSR_DE */
+	mtspr	SPRN_SRR3, r21		/* restore MSR at rcfi without DE */
+
+	mtcrf   0xff,r20                /* restore registers */
+	mfspr   r21,SPRN_SPRG1
+	mfspr   r20,SPRN_SPRG0
+
+	sync
+	rfci                            /* return to the exception handler  */
+	b	.			/* prevent prefetch past rfci */
+
+2:
+	mtcrf   0xff,r20                /* restore registers */
+	mfspr   r21,SPRN_SPRG1
+	mfspr   r20,SPRN_SPRG0
+	b       ret_to_debug_exception
+
+/* Other PowerPC processors, namely those derived from the 6xx-series
+ * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
+ * However, for the 4xx-series processors these are neither defined nor
+ * reserved.
+ */
+
+	/* Damn, I came up one instruction too many to fit into the
+	 * exception space :-).  Both the instruction and data TLB
+	 * miss get to this point to load the TLB.
+	 * 	r20 - EA of fault
+	 * 	r21 - TLB LO (info from Linux PTE)
+	 *	r22, r23 - avilable to use
+	 *	PID - loaded with proper value when we get here
+	 *	Upon exit, we reload everything and RFI.
+	 * Actually, it will fit now, but oh well.....a common place
+	 * to load the TLB.
+	 */
+tlb_4xx_index:
+	.long	0
+finish_tlb_load:
+	/* load the next available TLB index.
+	*/
+	lwz	r23, tlb_4xx_index@l(0)
+	addi	r23, r23, 1
+#ifdef CONFIG_PIN_TLB
+	cmpwi	0, r23, 61		/* reserve entries 62, 63 for kernel */
+	ble	7f
+	li	r23, 0
+7:
+#else
+	andi.	r23, r23, (PPC4XX_TLB_SIZE-1)
+#endif
+	stw	r23, tlb_4xx_index@l(0)
+
+6:
+	tlbwe	r21, r23, TLB_DATA		/* Load TLB LO */
+
+	/* Create EPN.  This is the faulting address plus a static
+	 * set of bits.  These are size, valid, E, U0, and ensure
+	 * bits 20 and 21 are zero.
+	 */
+	li	r22, 0x00c0
+	rlwimi	r20, r22, 0, 20, 31
+	tlbwe	r20, r23, TLB_TAG		/* Load TLB HI */
+
+	/* Done...restore registers and get out of here.
+	*/
+#ifdef CONFIG_403GCX
+	lwz     r22, 12(r0)
+	lwz     r21, 8(r0)
+	mtspr   SPRN_PID, r22
+	mtcr    r21
+	lwz     r23, 4(r0)
+	lwz     r22, 0(r0)
+#else
+	mfspr	r22, SPRG6
+	mfspr	r21, SPRG7
+	mtspr	SPRN_PID, r22
+	mtcr	r21
+	mfspr	r23, SPRG5
+	mfspr	r22, SPRG4
+#endif
+	mfspr	r21, SPRG1
+	mfspr	r20, SPRG0
+	PPC405_ERR77_SYNC
+	rfi			/* Should sync shadow TLBs */
+	b	.		/* prevent prefetch past rfi */
+
+/* This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception, turning
+ * on address translation.
+ */
 _GLOBAL(transfer_to_handler)
-	stw	r22,_NIP(r21)		# Save the faulting IP on the stack
-	stw	r23,_MSR(r21)		# Save the exception MSR on the stack
-	SAVE_4GPRS(8, r21)		# Save r8 through r11 on the stack
-	SAVE_8GPRS(12, r21)		# Save r12 through r19 on the stack
-	SAVE_8GPRS(24, r21)		# Save r24 through r31 on the stack
-	andi.	r23,r23,MSR_PR		# Is this from user space?
-	mfspr	r23,SPRN_SPRG3		# If from user, fix up THREAD.regs
-	beq	2f			# No, it is from the kernel; branch.
+	stw	r22,_NIP(r21)		/* Save the faulting IP on the stack */
+	stw	r23,_MSR(r21)		/* Save the exception MSR on stack */
+	SAVE_4GPRS(8, r21)		/* Save r8 through r11 on the stack */
+	SAVE_8GPRS(12, r21)		/* Save r12 through r19 on the stack */
+	SAVE_8GPRS(24, r21)		/* Save r24 through r31 on the stack */
+	andi.	r23,r23,MSR_PR		/* Is this from user space? */
+	mfspr	r23,SPRN_SPRG3		/* If from user, fix up THREAD.regs */
+	beq	2f			/* No, it is from the kernel; branch. */
+	mfspr	r24,SPRN_DBCR0
+	stw	r24,THREAD_DBCR0(r23)	/* Save Debug Control in thread_struct */
 	addi	r24,r1,STACK_FRAME_OVERHEAD
-	stw	r24,PT_REGS(r23)	# 
-2:	addi	r2,r23,-THREAD		# Set r2 to current thread
+	stw	r24,PT_REGS(r23)
+2:	addi	r2,r23,-THREAD		/* Set r2 to current thread */
 	tovirt(r2,r2)
 	mflr	r23
-	andi.	r24,r23,0x3f00		# Get vector offset
+	andi.	r24,r23,0x3f00		/* Get vector offset */
 	stw	r24,TRAP(r21)
+	li	r22,RESULT
+	/* No need to put an erratum #77 workaround here
+		because interrupts are currently disabled */
+	stwcx.	r22,r22,r21		/* Clear the reservation */
 	li	r22,0
 	stw	r22,RESULT(r21)
-	mtspr	SPRN_SPRG2,r22		# r1 is now the kernel stack pointer
-	addi	r24,r2,TASK_STRUCT_SIZE	# Check for kernel stack overflow
+	mtspr	SPRN_SPRG2,r22		/* r1 is now the kernel stack pointer */
+	addi	r24,r2,TASK_STRUCT_SIZE	/* Check for kernel stack overflow */
 	cmplw	cr0,r1,r2
 	cmplw	cr1,r1,r24
 	crand	cr1,cr1,cr4
-	bgt-	stack_ovf		# If r2 < r1 < r2 + TASK_STRUCT_SIZE
-	lwz	r24,0(r23)		# Virtual address of the handler
-	lwz	r23,4(r23)		# Handler return pointer
-	cmpwi	cr0,r7,STND_EXC		# What type of exception is this?
-	bne	3f			# It is a critical exception...
-
-	## Standard exception jump path
-	
-	mtspr	SPRN_SRR0,r24		# Set up the instruction pointer
-	mtspr	SPRN_SRR1,r20		# Set up the machine state register
-	mtlr	r23			# Set up the return pointer
+	bgt-	stack_ovf		/* If r2 < r1 < r2 + TASK_STRUCT_SIZE */
+	lwz	r24,0(r23)		/* Virtual address of the handler */
+	lwz	r23,4(r23)		/* Handler return pointer */
+	cmpwi	cr0,r7,STND_EXC		/* What type of exception is this? */
+	bne	3f			/* It is a critical exception... */
+
+	/* Standard exception jump path
+	*/
+
+	/* We have to recover r7 from the register save stack.
+	 * It was used to indicate standard/critical exception.  In
+	 * the case of a standard exception that is the system call
+	 * trap, it may have originally contained one of the syscall
+	 * parameters and we have to get it back now.
+	 */
+	lwz	r7,GPR7(r21)
+	mtspr	SPRN_SRR0,r24		/* Set up the instruction pointer */
+	mtspr	SPRN_SRR1,r20		/* Set up the machine state register */
+	mtlr	r23			/* Set up the return pointer */
 	SYNC
-	rfi				# Enable the MMU, jump to the handler
+	/* We shouldn't need a 405 erratum #77 workaround here, because we're not
+	 * actually returning to the interrupted instruction yet. */
+	rfi
+	b	.		/* prevent prefetch past rfi */
 
-	## Critical exception jump path
+	/* Critical exception jump path
+	*/
 
-3:	mtspr	SPRN_SRR2,r24		# Set up the instruction pointer
-	mtspr	SPRN_SRR3,r20		# Set up the machine state register
-	mtlr	r23			# Set up the return pointer
+3:	mtspr	SPRN_SRR2,r24		/* Set up the instruction pointer */
+	mtspr	SPRN_SRR3,r20		/* Set up the machine state register */
+	mtlr	r23			/* Set up the return pointer */
 	SYNC
-	rfci				# Enable the MMU, jump to the handler
+	rfci
+	b	.			/* prevent prefetch past rfci */
 
-###
-### On kernel stack overlow, load up an initial stack pointer and call
-### StackOverflow(regs), which should NOT return.
-### 
+/* On kernel stack overlow, load up an initial stack pointer and call
+ * StackOverflow(regs), which should NOT return.
+ */
 
 stack_ovf:
 	addi	r3,r1,STACK_FRAME_OVERHEAD
@@ -438,143 +895,226 @@
 	lis	r24,StackOverflow@ha
 	addi	r24,r24,StackOverflow@l
 	li	r20,MSR_KERNEL
-	mtspr	SPRN_SRR0,r24		# Set up the instruction pointer
-	mtspr	SPRN_SRR1,r20		# Set up the machine state register
+	mtspr	SPRN_SRR0,r24
+	mtspr	SPRN_SRR1,r20
 	SYNC
-	rfi				# Enable the MMU, jump to StackOverflow
-
-###
-### extern void giveup_altivec(struct task_struct *prev)
-###
-### The PowerPC 4xx family of processors do not have AltiVec capabilities, so
-### this just returns.
-###
+	rfi
+	b	.		/* prevent prefetch past rfi */
 
+/* extern void giveup_altivec(struct task_struct *prev)
+ *
+ * The PowerPC 4xx family of processors do not have AltiVec capabilities, so
+ * this just returns.
+ */
 _GLOBAL(giveup_altivec)
 	blr
-	
-###
-### extern void giveup_fpu(struct task_struct *prev)
-###
-### The PowerPC 4xx family of processors do not have an FPU, so this just
-### returns.
-###
 
+/* extern void giveup_fpu(struct task_struct *prev)
+ *
+ * The PowerPC 4xx family of processors do not have an FPU, so this just
+ * returns.
+ */
 _GLOBAL(giveup_fpu)
 	blr
 
-###
-### extern void abort(void)
-###
-### At present, this routine just applies a system reset.
-### 
-	
+/* extern void abort(void)
+ *
+ * At present, this routine just applies a system reset.
+ */
 _GLOBAL(abort)
-	mfspr	r13,SPRN_DBCR
-	oris	r13,r13,DBCR_RST(DBCR_RST_SYSTEM)@h
-	mtspr	SPRN_DBCR,r13
+        mfspr   r13,SPRN_DBCR0
+        oris    r13,r13,DBCR_RST(DBCR_RST_SYSTEM)@h
+        mtspr   SPRN_DBCR0,r13
 
 
-### 
-### This is where the main kernel code starts.
-### 
-
+/* This is where the main kernel code starts.
+ */
 start_here:
-	## Establish a pointer to the current task
-	
+
+	/* ptr to current */
 	lis	r2,init_task_union@h
 	ori	r2,r2,init_task_union@l
-	
-	## Clear out the BSS as per ANSI C requirements
 
-	lis	r7,_end@ha
-	addi	r7,r7,_end@l
-	lis	r8,__bss_start@ha
-	addi	r8,r8,__bss_start@l
-	subf	r7,r8,r7
-	addi	r7,r7,3
-	srwi.	r7,r7,2
-	beq	2f
-	addi	r8,r8,-4
-	mtctr	r7
-	li	r0,0
-3:	stwu	r0,4(r8)
-	bdnz	3b
+	/* ptr to phys current thread */
+	tophys(r4,r2)
+	addi	r4,r4,THREAD	/* init task's THREAD */
+	mtspr	SPRG3,r4
+	li	r3,0
+	mtspr	SPRG2,r3	/* 0 => r1 has kernel sp */
 
-	## Stack
-	
-2:	addi	r1,r2,TASK_UNION_SIZE
+	/* stack */
+	addi	r1,r2,TASK_UNION_SIZE
 	li	r0,0
 	stwu	r0,-STACK_FRAME_OVERHEAD(r1)
 
-	## Determine what type of platform this is.
+	bl	early_init	/* We have to do this with MMU on */
 
+/*
+ * Decide what sort of machine this is and initialize the MMU.
+ */
 	mr	r3,r31
 	mr	r4,r30
 	mr	r5,r29
 	mr	r6,r28
 	mr	r7,r27
-	bl	identify_machine
-	
-	## Initialize the memory management unit.
-
+	bl	machine_init
 	bl	MMU_init
 
-	## Go back to running unmapped so that we can change to our
-	## exception vectors.
-
+/* Go back to running unmapped so we can load up new values
+ * and change to using our exception vectors.
+ * On the 4xx, all we have to do is invalidate the TLB to clear
+ * the old 16M byte TLB mappings.
+ */
 	lis	r4,2f@h
 	ori	r4,r4,2f@l
 	tophys(r4,r4)
 	li	r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
-	mtspr	SPRN_SRR0,r4		# Set up the instruction pointer
-	mtspr	SPRN_SRR1,r3		# Set up the machine state register
+	mtspr	SRR0,r4
+	mtspr	SRR1,r3
 	rfi
+	b	.		/* prevent prefetch past rfi */
+
+/* Load up the kernel context */
+2:
+	SYNC			/* Force all PTE updates to finish */
+#ifndef CONFIG_PIN_TLB
+	tlbia			/* Clear all TLB entries */
+	sync			/* wait for tlbia/tlbie to finish */
+#endif
+
+	/* set up the PTE pointers for the Abatron bdiGDB.
+	*/
+	lis	r6, swapper_pg_dir@h
+	ori	r6, r6, swapper_pg_dir@l
+	lis	r5, abatron_pteptrs@h
+	ori	r5, r5, abatron_pteptrs@l
+	stw	r5, 0xf0(r0)	/* Must match your Abatron config file */
+	tophys(r5,r5)
+	stw	r6, 0(r5)
+
+/* Now turn on the MMU for real! */
+	li	r4,MSR_KERNEL
+	lis	r3,start_kernel@h
+	ori	r3,r3,start_kernel@l
+	mtspr	SRR0,r3
+	mtspr	SRR1,r4
+	rfi			/* enable MMU and jump to start_kernel */
+	b	.		/* prevent prefetch past rfi */
+
+/* Set up the initial MMU state so we can do the first level of
+ * kernel initialization.  This maps the first 16 MBytes of memory 1:1
+ * virtual to physical and more importantly sets the cache mode.
+ */
+initial_mmu:
+	tlbia			/* Invalidate all TLB entries */
+	sync
+
+	/* We should still be executing code at physical address 0x0000xxxx
+	 * at this point. However, start_here is at virtual address
+	 * 0xC000xxxx. So, set up a TLB mapping to cover this once
+	 * translation is enabled.
+	 */
+
+	lis	r3,KERNELBASE@h		/* Load the kernel virtual address */
+	ori	r3,r3,KERNELBASE@l
+	tophys(r4,r3)			/* Load the kernel physical address */
+
+	iccci	r0,r3			/* Invalidate the i-cache before use */
+
+	/* Load the kernel PID.
+	*/
+	li	r0,0
+	mtspr	SPRN_PID,r0
+	sync
+
+	/* Configure and load two entries into TLB slots 62 and 63.
+	 * In case we are pinning TLBs, these are reserved in by the
+	 * other TLB functions.  If not reserving, then it doesn't
+	 * matter where they are loaded.
+	 */
+	clrrwi	r4,r4,10		/* Mask off the real page number */
+	ori	r4,r4,(TLB_WR | TLB_EX)	/* Set the write and execute bits */
+
+	clrrwi	r3,r3,10		/* Mask off the effective page number */
+	ori	r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
+
+        li      r0,62                    /* TLB slot 62 */
+
+	tlbwe	r4,r0,TLB_DATA		/* Load the data portion of the entry */
+	tlbwe	r3,r0,TLB_TAG		/* Load the tag portion of the entry */
+
+	addis	r4, r4, 0x0100		/* Map next 16 M entries */
+	addis	r3, r3, 0x0100
+
+        li      r0,63                    /* TLB slot 63 */
 
-	## Load up the kernel context
+	tlbwe	r4,r0,TLB_DATA
+	tlbwe	r3,r0,TLB_TAG
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(SERIAL_DEBUG_IO_BASE)
+
+	/* Load a TLB entry for the UART, so that ppc4xx_progress() can use
+	 * the UARTs nice and early.  We use a 4k real==virtual mapping. */
+
+	lis	r3,SERIAL_DEBUG_IO_BASE@h
+	ori	r3,r3,SERIAL_DEBUG_IO_BASE@l
+	mr	r4,r3
+	clrrwi	r4,r4,12
+	ori	r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G)
+
+	clrrwi	r3,r3,12
+	ori	r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K))
+
+	li	r0,0			/* TLB slot 0 */
+	tlbwe	r4,r0,TLB_DATA
+	tlbwe	r3,r0,TLB_TAG
+#endif /* CONFIG_SERIAL_DEBUG_TEXT && SERIAL_DEBUG_IO_BASE */
+
+	isync
+
+	/* Establish the exception vector base
+	*/
+	lis	r4,KERNELBASE@h		/* EVPR only uses the high 16-bits */
+	tophys(r0,r4)			/* Use the physical address */
+	mtspr	SPRN_EVPR,r0
+
+	blr
 
-2:	SYNC				# Force all PTE updates to finish
-#	tlbia				# Clear all TLB entries
-#	sync				# Wait for tlbia to finish...
-
-	## Set up for using our exception vectors
-	
-	tophys(r4,r2)			# Pointer to physical current thread
-	addi	r4,r4,THREAD		# The init task thread
-	mtspr	SPRN_SPRG3,r4		# Save it for exceptions later
-	li	r3,0			# 
-	mtspr	SPRN_SPRG2,r3		# 0 implies r1 has kernel stack pointer
-	
-	## Really turn on the MMU and jump into the kernel
-
-        lis     r4,MSR_KERNEL@h
-        ori     r4,r4,MSR_KERNEL@l
-        lis     r3,start_kernel@h
-        ori     r3,r3,start_kernel@l
-        mtspr   SPRN_SRR0,r3		# Set up the instruction pointer
-        mtspr   SPRN_SRR1,r4		# Set up the machine state register
-        rfi				# Enable the MMU, jump to the kernel
 
 _GLOBAL(set_context)
+
+#ifdef CONFIG_BDI_SWITCH
+	/* Context switch the PTE pointer for the Abatron BDI2000.
+	 * The PGDIR is the second parameter.
+	 */
+	lis	r5, KERNELBASE@h
+	lwz	r5, 0xf0(r5)
+	stw	r4, 0x4(r5)
+#endif
+	sync
 	mtspr	SPRN_PID,r3
+	isync				/* Need an isync to flush shadow */
+					/* TLBs after changing PID */
 	blr
 
-###
-### We put a few things here that have to be page-aligned. This stuff
-### goes at the beginning of the data segment, which is page-aligned.
-###
-
+/* We put a few things here that have to be page-aligned. This stuff
+ * goes at the beginning of the data segment, which is page-aligned.
+ */
 	.data
 _GLOBAL(sdata)
 _GLOBAL(empty_zero_page)
 	.space	4096
 _GLOBAL(swapper_pg_dir)
-	.space	4096	
-
-###
-### This space gets a copy of optional info passed to us by the bootstrap
-### which is used to pass parameters into the kernel like root=/dev/sda1, etc.
-###
+	.space	4096
 
+/* This space gets a copy of optional info passed to us by the bootstrap
+ * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
 _GLOBAL(cmd_line)
 	.space	512
+
+/* Room for two PTE pointers, usually the kernel and current user pointers
+ * to their respective root page table.
+ */
+abatron_pteptrs:
+	.space	8
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/head_8xx.S linux-2.4.22-pre10/arch/ppc/kernel/head_8xx.S
--- linux-2.4.21/arch/ppc/kernel/head_8xx.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/head_8xx.S	2003-08-01 13:33:11.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *  arch/ppc/kernel/except_8xx.S
  *
- *  PowerPC version 
+ *  PowerPC version
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
@@ -74,6 +74,20 @@
  * I used to use SPRG2 for a temporary register in the TLB handler, but it
  * has since been put to other uses.  I now use a hack to save a register
  * and the CCR at memory location 0.....Someday I'll fix this.....
+ *
+ * With regard to resetting the CPM. The UART console has a number of subtle
+ * assumptions built around the initialization to support kgdb/xmon debugging.
+ * The quick answer is we don't want to reset the CPM so we can proper support
+ * this debugging.
+ *
+ * When the kernel is first booted, kgdb/xmon use the CPM as it was set up by
+ * the boot rom.  There is a second initialization of the UART driver, but
+ * before the console is initialized.  This changes the BDs, but the UART
+ * still operates for kgdb/xmon.  The final stage initialization occurs when
+ * the console is initialized, and all of the "normal path" debugging and
+ * messages can occur after this point.  So the only time we want to do a CPM
+ * is in the case of a microcode patch.
+ *
  *	-- Dan
  */
 
@@ -470,7 +484,16 @@
 #endif
 	rfi
 
-2:	mfspr	r20, M_TW	/* Restore registers */
+2:
+	/* Copy 20 msb from MD_EPN to DAR since the dcxx instructions fail
+	 * to update DAR when they cause a DTLB miss.
+	 */
+	mfspr	r21, MD_EPN
+	mfspr	r20, DAR
+	rlwimi	r20, r21, 0, 0, 19
+	mtspr	DAR, r20
+
+	mfspr	r20, M_TW	/* Restore registers */
 	lwz	r21, 0(r0)
 	mtcr	r21
 	lwz	r21, 4(r0)
@@ -514,20 +537,20 @@
 	andis.	r21, r20, 0x0200	/* If set, indicates store op */
 	beq	2f
 
-	/* The EA of a data TLB miss is automatically stored in the MD_EPN 
-	 * register.  The EA of a data TLB error is automatically stored in 
-	 * the DAR, but not the MD_EPN register.  We must copy the 20 most 
-	 * significant bits of the EA from the DAR to MD_EPN before we 
-	 * start walking the page tables.  We also need to copy the CASID 
+	/* The EA of a data TLB miss is automatically stored in the MD_EPN
+	 * register.  The EA of a data TLB error is automatically stored in
+	 * the DAR, but not the MD_EPN register.  We must copy the 20 most
+	 * significant bits of the EA from the DAR to MD_EPN before we
+	 * start walking the page tables.  We also need to copy the CASID
 	 * value from the M_CASID register.
-	 * Addendum:  The EA of a data TLB error is _supposed_ to be stored 
-	 * in DAR, but it seems that this doesn't happen in some cases, such 
-	 * as when the error is due to a dcbi instruction to a page with a 
-	 * TLB that doesn't have the changed bit set.  In such cases, there 
-	 * does not appear to be any way  to recover the EA of the error 
-	 * since it is neither in DAR nor MD_EPN.  As a workaround, the 
-	 * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs 
-	 * are initialized in mapin_ram().  This will avoid the problem, 
+	 * Addendum:  The EA of a data TLB error is _supposed_ to be stored
+	 * in DAR, but it seems that this doesn't happen in some cases, such
+	 * as when the error is due to a dcbi instruction to a page with a
+	 * TLB that doesn't have the changed bit set.  In such cases, there
+	 * does not appear to be any way  to recover the EA of the error
+	 * since it is neither in DAR nor MD_EPN.  As a workaround, the
+	 * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs
+	 * are initialized in mapin_ram().  This will avoid the problem,
 	 * assuming we only use the dcbi instruction on kernel addresses.
 	 */
 	mfspr	r20, DAR
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/i8259.c linux-2.4.22-pre10/arch/ppc/kernel/i8259.c
--- linux-2.4.21/arch/ppc/kernel/i8259.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/i8259.c	2003-08-01 13:33:11.000000000 +0000
@@ -93,7 +93,7 @@
 	outb(cached_A1,0xA1);
 	outb(cached_21,0x21);
 }
- 
+
 static void i8259_mask_irq(unsigned int irq_nr)
 {
 	unsigned long flags;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/idle.c linux-2.4.22-pre10/arch/ppc/kernel/idle.c
--- linux-2.4.21/arch/ppc/kernel/idle.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/idle.c	2003-08-01 13:30:40.000000000 +0000
@@ -34,9 +34,7 @@
 unsigned long powersave_nap;
 unsigned long powersave_lowspeed;
 
-#ifdef CONFIG_6xx
-extern void power_save_6xx(void);
-#endif
+extern void power_save(void);
 
 int idled(void)
 {
@@ -66,10 +64,8 @@
 			}
 		}
 #endif
-#ifdef CONFIG_6xx
 		if (do_power_save && !current->need_resched)
-			power_save_6xx();
-#endif /* CONFIG_6xx */			
+			power_save();
 
 		if (current->need_resched) {
 			schedule();
@@ -86,5 +82,5 @@
 int cpu_idle(void)
 {
 	idled();
-	return 0; 
+	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/idle_6xx.S linux-2.4.22-pre10/arch/ppc/kernel/idle_6xx.S
--- linux-2.4.21/arch/ppc/kernel/idle_6xx.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/idle_6xx.S	2003-08-01 13:33:40.000000000 +0000
@@ -56,12 +56,12 @@
 	blr
 
 /*
- * Here is the power_save_6xx function. This could eventually be
+ * Here is the power_save function. This could eventually be
  * split into several functions & changing the function pointer
  * depending on the various features.
  */
-	.globl	power_save_6xx
-power_save_6xx:
+	.globl	power_save
+power_save:
 	/* Check if we can nap or doze, put HID0 mask in r3
 	 */
 	lis	r3, 0
@@ -83,7 +83,7 @@
 	cmpi	0,r4,0
 	beq	1f
 	lis	r3,HID0_NAP@h
-1:	
+1:
 END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
 	cmpi	0,r3,0
 	beqlr
@@ -99,7 +99,7 @@
 	beq+	1f
 	mtmsr	r7	/* out of line this ? */
 	blr
-1:	
+1:
 	/* Some pre-nap cleanups needed on some CPUs */
 	andis.	r0,r3,HID0_NAP@h
 	beq	2f
@@ -127,7 +127,7 @@
 	lwz	r4,nap_enter_count@l(r6)
 	addi	r4,r4,1
 	stw	r4,nap_enter_count@l(r6)
-#endif	
+#endif
 2:
 BEGIN_FTR_SECTION
 	/* Go to low speed mode on some 750FX */
@@ -138,10 +138,10 @@
 	mfspr	r4,SPRN_HID1
 	oris	r4,r4,0x0001
 	mtspr	SPRN_HID1,r4
-1:	
+1:
 END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
 
-	/* Go to NAP or DOZE now */	
+	/* Go to NAP or DOZE now */
 	mfspr	r4,SPRN_HID0
 	lis	r5,(HID0_NAP|HID0_SLEEP)@h
 BEGIN_FTR_SECTION
@@ -167,7 +167,7 @@
 	isync
 	sync
 	blr
-	
+
 /*
  * Return from NAP/DOZE mode, restore some CPU specific registers,
  * we are called with DR/IR still off and r2 containing physical
@@ -191,7 +191,7 @@
 	stw	r24,nap_return_count@l(r22)
 1:
 #endif
-	
+
 	lwz	r24,PROCESSOR(r2)
 	slwi	r24,r24,2
 	/* Todo make sure all these are in the same page
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/idle_gen.c linux-2.4.22-pre10/arch/ppc/kernel/idle_gen.c
--- linux-2.4.21/arch/ppc/kernel/idle_gen.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/idle_gen.c	2003-08-01 13:30:41.000000000 +0000
@@ -0,0 +1,41 @@
+/*
+ * This is the old power_save() function from idle.c:
+ *
+ * Written by Cort Dougan (cort@cs.nmt.edu)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+#include <linux/sched.h>
+#include <asm/processor.h>
+#include <asm/cputable.h>
+
+void power_save(void)
+{
+	/* Make sure the CPU has the DOZE feature set. */
+	if (!(cur_cpu_spec[smp_processor_id()]->cpu_features
+				& CPU_FTR_CAN_DOZE))
+		return;
+	/*
+	 * Disable interrupts to prevent a lost wakeup
+	 * when going to sleep.  This is necessary even with
+	 * RTLinux since we are not guaranteed an interrupt
+	 * didn't come in and is waiting for a __sti() before
+	 * emulating one.  This way, we really do hard disable.
+	 *
+	 * We assume that we're sti-ed when we come in here.  We
+	 * are in the idle loop so if we're cli-ed then it's a bug
+	 * anyway.
+	 *  -- Cort
+	 */
+	_nmask_and_or_msr(MSR_EE, 0);
+	if (!current->need_resched) {
+		/* set the POW bit in the MSR, and enable interrupts
+		 * so we wake up sometime! */
+		_nmask_and_or_msr(0, MSR_POW | MSR_EE);
+	}
+	_nmask_and_or_msr(0, MSR_EE);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/indirect_pci.c linux-2.4.22-pre10/arch/ppc/kernel/indirect_pci.c
--- linux-2.4.21/arch/ppc/kernel/indirect_pci.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/indirect_pci.c	2003-08-01 13:31:08.000000000 +0000
@@ -29,10 +29,19 @@
 indirect_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
 {									 \
 	struct pci_controller *hose = dev->sysdata;			 \
+	u8 cfg_type = 0;						 \
+									 \
+	if (ppc_md.pci_exclude_device)					 \
+		if (ppc_md.pci_exclude_device(dev->bus->number, dev->devfn)) \
+			return PCIBIOS_DEVICE_NOT_FOUND;		 \
+									 \
+	if (hose->set_cfg_type)					 	 \
+		if (dev->bus->number != hose->first_busno)		 \
+			cfg_type = 1;					 \
 									 \
 	out_be32(hose->cfg_addr, 					 \
-		 ((offset & 0xfc) << 24) | (dev->devfn << 16)		 \
-		 | (dev->bus->number << 8) | 0x80);			 \
+		 (((offset & 0xfc) | cfg_type) << 24) | (dev->devfn << 16) \
+		 | ((dev->bus->number - hose->bus_offset) << 8) | 0x80); \
 	cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);	 \
 	return PCIBIOS_SUCCESSFUL;    					 \
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/irq.c linux-2.4.22-pre10/arch/ppc/kernel/irq.c
--- linux-2.4.21/arch/ppc/kernel/irq.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/irq.c	2003-08-01 13:34:21.000000000 +0000
@@ -10,7 +10,7 @@
  *  Adapted for Power Macintosh by Paul Mackerras
  *    Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
  *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
- *  
+ *
  * This file contains the code used by various IRQ handling routines:
  * asking for different IRQ's should be done through these routines
  * instead of just grabbing them. Thus setups with different IRQ numbers
@@ -68,7 +68,7 @@
 
 irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
 	{ [0 ... NR_IRQS-1] = { 0, NULL, NULL, 0, SPIN_LOCK_UNLOCKED}};
-	
+
 int ppc_spurious_interrupts = 0;
 struct irqaction *ppc_irq_action[NR_IRQS];
 unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
@@ -234,28 +234,28 @@
 		free_irq(irq, dev_id);
 		return 0;
 	}
-	
+
 	action = (struct irqaction *)
 		irq_kmalloc(sizeof(struct irqaction), GFP_KERNEL);
 	if (!action) {
 		printk(KERN_ERR "irq_kmalloc() failed for irq %d !\n", irq);
 		return -ENOMEM;
 	}
-	
+
 	action->handler = handler;
-	action->flags = irqflags;					
+	action->flags = irqflags;
 	action->mask = 0;
 	action->name = devname;
 	action->dev_id = dev_id;
 	action->next = NULL;
-	
+
 	retval = setup_irq(irq, action);
 	if (retval)
 	{
 		kfree(action);
 		return retval;
 	}
-		
+
 	return 0;
 }
 
@@ -263,9 +263,9 @@
  * Generic enable/disable code: this just calls
  * down into the PIC-specific version for the actual
  * hardware disable after having gotten the irq
- * controller lock. 
+ * controller lock.
  */
- 
+
 /**
  *	disable_irq_nosync - disable an irq without waiting
  *	@irq: Interrupt to disable
@@ -276,7 +276,7 @@
  *
  *	This function may be called from IRQ context.
  */
- 
+
  void disable_irq_nosync(unsigned int irq)
 {
 	irq_desc_t *desc = irq_desc + irq;
@@ -303,7 +303,7 @@
  *
  *	This function may be called - with care - from IRQ context.
  */
- 
+
 void disable_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
@@ -324,7 +324,7 @@
  *
  *	This function may be called from IRQ context.
  */
- 
+
 void enable_irq(unsigned int irq)
 {
 	irq_desc_t *desc = irq_desc + irq;
@@ -365,15 +365,15 @@
 		action = irq_desc[i].action;
 		if ( !action || !action->handler )
 			continue;
-		len += sprintf(buf+len, "%3d: ", i);		
+		len += sprintf(buf+len, "%3d: ", i);
 #ifdef CONFIG_SMP
 		for (j = 0; j < smp_num_cpus; j++)
 			len += sprintf(buf+len, "%10u ",
 				kstat.irqs[cpu_logical_map(j)][i]);
-#else		
+#else
 		len += sprintf(buf+len, "%10u ", kstat_irqs(i));
 #endif /* CONFIG_SMP */
-		if ( irq_desc[i].handler )		
+		if ( irq_desc[i].handler )
 			len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename );
 		else
 			len += sprintf(buf+len, "  None      ");
@@ -397,7 +397,7 @@
 	/* should this be per processor send/receive? */
 	len += sprintf(buf+len, "IPI (recv/sent): %10u/%u\n",
 		       atomic_read(&ipi_recv), atomic_read(&ipi_sent));
-#endif		
+#endif
 	len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts);
 	return len;
 }
@@ -433,7 +433,7 @@
 
 	kstat.irqs[cpu][irq]++;
 	spin_lock(&desc->lock);
-	ack_irq(irq);	
+	ack_irq(irq);
 	/*
 	   REPLAY is when Linux resends an IRQ that was dropped earlier
 	   WAITING is used by probe to mark irqs that are being tested
@@ -490,7 +490,7 @@
 		spin_unlock(&desc->lock);
 		handle_irq_event(irq, regs, action);
 		spin_lock(&desc->lock);
-		
+
 		if (!(desc->status & IRQ_PENDING))
 			break;
 		desc->status &= ~IRQ_PENDING;
@@ -561,7 +561,7 @@
 		return;
 	else
 		once++;
-	
+
 	ppc_md.init_IRQ();
 }
 
@@ -700,11 +700,11 @@
 #endif
 				}
 			} while (test_bit(0,&global_irq_lock));
-		} while (test_and_set_bit(0,&global_irq_lock));		
+		} while (test_and_set_bit(0,&global_irq_lock));
 	}
-	/* 
+	/*
 	 * We also need to make sure that nobody else is running
-	 * in an interrupt context. 
+	 * in an interrupt context.
 	 */
 	wait_on_irq(cpu);
 
@@ -729,7 +729,7 @@
 void __global_cli(void)
 {
 	unsigned long flags;
-	
+
 	__save_flags(flags);
 	if (flags & (1 << 15)) {
 		int cpu = smp_processor_id();
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/l2cr.S linux-2.4.22-pre10/arch/ppc/kernel/l2cr.S
--- linux-2.4.21/arch/ppc/kernel/l2cr.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/l2cr.S	2003-08-01 13:33:37.000000000 +0000
@@ -1,17 +1,17 @@
 /*
 	L2CR functions
 	Copyright © 1997-1998 by PowerLogix R & D, Inc.
-	
+
 	This program is free software; you can redistribute it and/or modify
 	it under the terms of the GNU General Public License as published by
 	the Free Software Foundation; either version 2 of the License, or
 	(at your option) any later version.
-	
+
 	This program is distributed in the hope that it will be useful,
 	but WITHOUT ANY WARRANTY; without even the implied warranty of
 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 	GNU General Public License for more details.
-	
+
 	You should have received a copy of the GNU General Public License
 	along with this program; if not, write to the Free Software
 	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -36,7 +36,7 @@
 		several months.  The L2CR is similar, but I'm going
 		to assume the user of this functions knows what they
 		are doing.
-	
+
 	Author:	Terry Greeniaus (tgree@phys.ualberta.ca)
 	Please e-mail updates to this file to me, thanks!
 */
@@ -47,7 +47,7 @@
 #include <asm/cache.h>
 
 /* Usage:
-	
+
 	When setting the L2CR register, you must do a few special
 	things.  If you are enabling the cache, you must perform a
 	global invalidate.  If you are disabling the cache, you must
@@ -104,7 +104,7 @@
 END_FTR_SECTION_IFCLR(CPU_FTR_L2CR)
 
 	mflr	r9
-	
+
 	/* Stop DST streams */
 BEGIN_FTR_SECTION
 	DSSALL
@@ -134,10 +134,10 @@
 	mr	r5,r3
 	bl	__flush_disable_L1
 	mr	r3,r5
-	
+
 	/* Get the current enable bit of the L2CR into r4 */
 	mfspr	r4,L2CR
-	
+
 	/* Tweak some bits */
 	rlwinm	r5,r3,0,0,0		/* r5 contains the new enable bit */
 	rlwinm	r3,r3,0,11,9		/* Turn off the invalidate bit */
@@ -152,7 +152,7 @@
 	 * the size of the L2 cache plus the size of the L1 cache, but 4MB will
 	 * cover everything just to be safe).
 	 */
-		
+
 	 /**** Might be a good idea to set L2DO here - to prevent instructions
 	       from getting into the cache.  But since we invalidate
 	       the next time we enable the cache it doesn't really matter.
@@ -170,7 +170,7 @@
 	addi	r4,r4,32		/* Go to start of next cache line */
 	bdnz	1b
 	isync
-	
+
 	/* Now, flush the first 4MB of memory */
 	lis	r4,0x0002
 	mtctr	r4
@@ -198,7 +198,7 @@
 21:	sync
 	isync
 	b	22b
-		
+
 23:
 	/* Perform a global invalidation */
 	oris	r3,r3,0x0020
@@ -220,12 +220,12 @@
 3:	mfspr	r3,L2CR
 	rlwinm.	r4,r3,0,31,31
 	bne	3b
-	
+
 11:	rlwinm	r3,r3,0,11,9		/* Turn off the L2I bit */
 	sync
 	mtspr	L2CR,r3
 	sync
-	
+
 	/* See if we need to enable the cache */
 	cmplwi	r5,0
 	beq	4f
@@ -264,7 +264,7 @@
  * Here is a similar routine for dealing with the L3 cache
  * on the 745x family of chips
  */
- 
+
 _GLOBAL(_set_L3CR)
 	/* Make sure this is a 745x chip */
 BEGIN_FTR_SECTION
@@ -275,7 +275,7 @@
 	/* Stop DST streams */
 	DSSALL
 	sync
-	
+
 	/* Turn off interrupts and data relocation. */
 	mfmsr	r7		/* Save MSR in r7 */
 	rlwinm	r4,r7,0,17,15
@@ -286,7 +286,7 @@
 
 	/* Get the current enable bit of the L3CR into r4 */
 	mfspr	r4,SPRN_L3CR
-	
+
 	/* Tweak some bits */
 	rlwinm	r5,r3,0,0,0		/* r5 contains the new enable bit */
 	rlwinm	r3,r3,0,22,20		/* Turn off the invalidate bit */
@@ -298,7 +298,7 @@
 
 	/* Flush the cache.
 	 */
-		
+
 	/* TODO: use HW flush assist */
 
 	lis	r4,0x0008
@@ -309,7 +309,7 @@
 	dcbf	0,r4
 	addi	r4,r4,32		/* Go to start of next cache line */
 	bdnz	1b
-	
+
 2:
 	/* Set up the L3CR configuration bits (and switch L3 off) */
 	sync
@@ -327,7 +327,7 @@
 	li	r0,256
 	mtctr	r0
 1:	bdnz	1b
-	
+
 	/* Perform a global invalidation */
 	ori	r3,r3,0x0400
 	sync
@@ -349,7 +349,7 @@
 	li	r0,256
 	mtctr	r0
 1:	bdnz	1b
-	
+
 	/* See if we need to enable the cache */
 	cmplwi	r5,0
 	beq	4f
@@ -389,13 +389,13 @@
  */
  	.globl	__flush_disable_L1
  __flush_disable_L1:
- 
+
 	/* Stop pending alitvec streams and memory accesses */
 BEGIN_FTR_SECTION
 	DSSALL
 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
  	sync
- 	
+ 
 	/* Load counter to 0x1000 cache lines (128k) and
 	 * load cache with datas
 	 */
@@ -426,7 +426,7 @@
 	rlwinm	r3,r3,0,18,15
 	mtspr	SPRN_HID0,r3
 	sync
-	isync	
+	isync
  	blr
 
 /* inval_enable_L1	- Invalidate and enable L1 cache
@@ -449,4 +449,4 @@
 
  	blr
 
- 
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/m8260_setup.c linux-2.4.22-pre10/arch/ppc/kernel/m8260_setup.c
--- linux-2.4.21/arch/ppc/kernel/m8260_setup.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/m8260_setup.c	2003-08-01 13:33:22.000000000 +0000
@@ -148,7 +148,7 @@
 	bd_t	*bp;
 
 	bp = (bd_t *)__res;
-			
+
 	seq_printf(m, "core clock\t: %d MHz\n"
 		   "CPM  clock\t: %d MHz\n"
 		   "bus  clock\t: %d MHz\n",
@@ -176,7 +176,7 @@
 #endif
         for ( i = 0 ; i < NR_SIU_INTS ; i++ )
                 irq_desc[i].handler = &ppc8260_pic;
-	
+
 	/* Initialize the default interrupt mapping priorities,
 	 * in case the boot rom changed something on us.
 	 */
@@ -195,7 +195,7 @@
 {
 	bd_t	*binfo;
 	extern unsigned char __res[];
-	
+
 	binfo = (bd_t *)__res;
 
 	return binfo->bi_memsize;
@@ -221,7 +221,7 @@
 
 	if ( r3 )
 		memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
-	
+
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* take care of initrd if we have one */
 	if ( r4 )
@@ -233,7 +233,7 @@
 	/* take care of cmd line */
 	if ( r6 )
 	{
-		
+
 		*(char *)(r7+KERNELBASE) = 0;
 		strcpy(cmd_line, (char *)(r6+KERNELBASE));
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/m8xx_setup.c linux-2.4.22-pre10/arch/ppc/kernel/m8xx_setup.c
--- linux-2.4.21/arch/ppc/kernel/m8xx_setup.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/m8xx_setup.c	2003-08-01 13:32:59.000000000 +0000
@@ -279,7 +279,7 @@
 	i8259_init(0);
 
 	/* The i8259 cascade interrupt must be level sensitive. */
-	((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel &= 
+	((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel &=
 		~(0x80000000 >> ISA_BRIDGE_INT);
 
 	if (request_irq(ISA_BRIDGE_INT, mbx_i8259_action, 0, "i8259 cascade",
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/misc.S linux-2.4.22-pre10/arch/ppc/kernel/misc.S
--- linux-2.4.21/arch/ppc/kernel/misc.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/misc.S	2003-08-01 13:34:32.000000000 +0000
@@ -205,7 +205,7 @@
 	mfmsr	r4
 	stw	r4,0(r3)
 	blr
-	/* 
+	/*
 	 * Need these nops here for taking over save/restore to
 	 * handle lost intrs
 	 * -- Cort
@@ -229,7 +229,7 @@
 	nop
 _GLOBAL(__save_flags_ptr_end)
 
-/* void __restore_flags(unsigned long flags) */	
+/* void __restore_flags(unsigned long flags) */
 _GLOBAL(__restore_flags)
 /*
  * Just set/clear the MSR_EE bit through restore/flags but do not
@@ -277,7 +277,7 @@
 	SYNC			/* Some chip revs have problems here... */
 	mtmsr	r0		/* Update machine state */
 	blr			/* Done */
-	/* 
+	/*
 	 * Need these nops here for taking over save/restore to
 	 * handle lost intrs
 	 * -- Cort
@@ -305,7 +305,7 @@
 	SYNC			/* Some chip revs have problems here... */
 	mtmsr	r3		/* Update machine state */
 	blr
-	/* 
+	/*
 	 * Need these nops here for taking over save/restore to
 	 * handle lost intrs
 	 * -- Cort
@@ -348,6 +348,20 @@
  * Flush MMU TLB
  */
 _GLOBAL(_tlbia)
+#if defined(CONFIG_40x) && defined(CONFIG_PIN_TLB)
+	/* This needs to be coordinated with other pinning functions since
+	 * we don't keep a memory location of number of entries to reduce
+	 * cache pollution during these operations.
+	 */
+	lis	r3, 0
+	sync
+1:
+	tlbwe	r3, r3, TLB_TAG		/* just ensure V is clear */
+	addi	r3, r3, 1		/*   so r3 works fine for that */
+	cmpwi	0, r3, 61		/* reserve last two entries */
+	ble	1b
+	isync
+#else
 #if defined(CONFIG_SMP)
 	mfmsr	r10
 	SYNC
@@ -375,12 +389,24 @@
 	mtmsr	r10
 	SYNC
 #endif /* CONFIG_SMP */
-	blr	
+#endif /* defined(CONFIG_40x) && defined(CONFIG_PIN_TLB) */
+	blr
 
 /*
  * Flush MMU TLB for a particular address
  */
 _GLOBAL(_tlbie)
+#ifdef CONFIG_40x
+	tlbsx.	r3, 0, r3
+	bne	10f
+	sync
+	/* There are only 64 TLB entries, so r3 < 64, which means bit 25, is clear.
+	 * Since 25 is the V bit in the TLB_TAG, loading this value will invalidate
+	 * the TLB entry. */
+	tlbwe	r3, r3, TLB_TAG
+	isync
+10:
+#else
 #if defined(CONFIG_SMP)
 	mfmsr	r10
 	SYNC
@@ -394,6 +420,7 @@
 10:	lwarx	r7,0,r9
 	cmpi	0,r7,0
 	bne-	10b
+	PPC405_ERR77(0,r9)
 	stwcx.	r8,0,r9
 	bne-	10b
 #endif /* CONFIG_SMP */
@@ -407,6 +434,7 @@
 	mtmsr	r10
 	SYNC
 #endif
+#endif /* CONFIG_40x */
 	blr
 
 /*
@@ -418,9 +446,18 @@
 	isync
 	lis	r5, IDC_INVALL@h
 	mtspr	IC_CST, r5
-#elif defined(CONFIG_4xx)
+#elif CONFIG_4xx
+#ifdef CONFIG_403GCX
+	li      r3, 512
+	mtctr   r3
+	lis     r4, KERNELBASE@h
+1:	iccci   0, r4
+	addi    r4, r4, 16
+	bdnz    1b
+#else
 	lis	r3, KERNELBASE@h
 	iccci	0,r3
+#endif
 #else
 	mfspr	r3,PVR
 	rlwinm	r3,r3,16,16,31
@@ -430,7 +467,7 @@
 	mfspr	r3,HID0
 	ori	r3,r3,HID0_ICFI
 	mtspr	HID0,r3
-#endif /* CONFIG_8xx */
+#endif /* CONFIG_8xx/4xx */
 	isync
 	blr
 
@@ -530,6 +567,27 @@
 	sync				/* wait for dcbi's to get to ram */
 	blr
 
+#ifdef CONFIG_NOT_COHERENT_CACHE
+/*
+ * 40x cores have 8K or 16K dcache and 32 byte line size.
+ * 440 has a 32K dcache and 32 byte line size.
+ * 8xx has 1, 2, 4, 8K variants.
+ * For now, cover the worst case of the 440.
+ * Must be called with external interrupts disabled.
+ */
+#define CACHE_NWAYS	64
+#define CACHE_NLINES	16
+
+_GLOBAL(flush_dcache_all)
+	li	r4, (2 * CACHE_NWAYS * CACHE_NLINES)
+	mtctr	r4
+	lis     r5, KERNELBASE@h
+1:	lwz	r3, 0(r5)		/* Load one word from every line */
+	addi	r5, r5, L1_CACHE_LINE_SIZE
+	bdnz    1b
+	blr
+#endif /* CONFIG_NOT_COHERENT_CACHE */
+
 /*
  * Flush a particular page from the data cache to RAM.
  * Note: this is necessary because the instruction cache does *not*
@@ -558,7 +616,7 @@
 	sync
 	isync
 	blr
-	
+
 /*
  * Clear a page using the dcbz instruction, which doesn't cause any
  * memory traffic (except to write out any cache lines which get
@@ -709,7 +767,7 @@
 	stb	r5,0(r3)
 	eieio
 	bdnz	00b
-	blr	
+	blr
 
 _GLOBAL(_insw)
 	cmpwi	0,r5,0
@@ -729,9 +787,9 @@
 	blelr-
 00:	lhzu	r5,2(r4)
 	eieio
-	sthbrx	r5,0,r3	
+	sthbrx	r5,0,r3
 	bdnz	00b
-	blr	
+	blr
 
 _GLOBAL(_insl)
 	cmpwi	0,r5,0
@@ -753,7 +811,7 @@
 	stwbrx	r5,0,r3
 	eieio
 	bdnz	00b
-	blr	
+	blr
 
 _GLOBAL(ide_insw)
 _GLOBAL(_insw_ns)
@@ -777,7 +835,7 @@
 	sth	r5,0(r3)
 	eieio
 	bdnz	00b
-	blr	
+	blr
 
 _GLOBAL(_insl_ns)
 	cmpwi	0,r5,0
@@ -799,11 +857,11 @@
 	stw	r5,0(r3)
 	eieio
 	bdnz	00b
-	blr	
+	blr
 
 /*
  * Extended precision shifts.
- * 
+ *
  * Updated to be valid for shift counts from 0 to 63 inclusive.
  * -- Gabriel
  *
@@ -811,12 +869,12 @@
  * R5    has shift count
  * result in R3/R4
  *
- *  ashrdi3: arithmetic right shift (sign propagation)	    
- *  lshrdi3: logical right shift	
+ *  ashrdi3: arithmetic right shift (sign propagation)
+ *  lshrdi3: logical right shift
  *  ashldi3: left shift
  */
 _GLOBAL(__ashrdi3)
-	subfic	r6,r5,32	
+	subfic	r6,r5,32
 	srw	r4,r4,r5	# LSW = count > 31 ? 0 : LSW >> count
 	addi	r7,r5,32	# could be xori, or addi with -32
 	slw	r6,r3,r6	# t1 = count > 31 ? 0 : MSW << (32-count)
@@ -829,7 +887,7 @@
 	blr
 
 _GLOBAL(__ashldi3)
-	subfic	r6,r5,32	
+	subfic	r6,r5,32
 	slw	r3,r3,r5	# MSW = count > 31 ? 0 : MSW << count
 	addi	r7,r5,32	# could be xori, or addi with -32
 	srw	r6,r4,r6	# t1 = count > 31 ? 0 : LSW >> (32-count)
@@ -840,14 +898,14 @@
 	blr
 
 _GLOBAL(__lshrdi3)
-	subfic	r6,r5,32	
+	subfic	r6,r5,32
 	srw	r4,r4,r5	# LSW = count > 31 ? 0 : LSW >> count
 	addi	r7,r5,32	# could be xori, or addi with -32
 	slw	r6,r3,r6	# t1 = count > 31 ? 0 : MSW << (32-count)
 	srw	r7,r3,r7	# t2 = count < 32 ? 0 : MSW >> (count-32)
 	or	r4,r4,r6	# LSW |= t1
 	srw	r3,r3,r5	# MSW = MSW >> count
-	or	r4,r4,r7	# LSW |= t2 
+	or	r4,r4,r7	# LSW |= t2
 	blr
 
 _GLOBAL(abs)
@@ -859,7 +917,7 @@
 _GLOBAL(_get_SP)
 	mr	r3,r1		/* Close enough */
 	blr
-	
+
 /*
  * These are used in the alignment trap handler when emulating
  * single-precision loads and stores.
@@ -867,7 +925,7 @@
  * and exceptions as if the cpu had performed the load or store.
  */
 
-#if defined(CONFIG_4xx)
+#ifdef CONFIG_4xx
 _GLOBAL(cvt_fd)
 	lfs	0,0(r3)
 	stfd	0,0(r4)
@@ -919,7 +977,7 @@
 
 /*
  * This routine is just here to keep GCC happy - sigh...
- */	
+ */
 _GLOBAL(__main)
 	blr
 
@@ -949,7 +1007,7 @@
 SYSCALL(lseek)
 SYSCALL(read)
 
-/* Why isn't this a) automatic, b) written in 'C'? */	
+/* Why isn't this a) automatic, b) written in 'C'? */
 	.data
 	.align 4
 _GLOBAL(sys_call_table)
@@ -1127,7 +1185,7 @@
 	.long sys_prctl
 	.long sys_rt_sigreturn
 	.long sys_rt_sigaction
-	.long sys_rt_sigprocmask	
+	.long sys_rt_sigprocmask
 	.long sys_rt_sigpending	/* 175 */
 	.long sys_rt_sigtimedwait
 	.long sys_rt_sigqueueinfo
@@ -1145,14 +1203,14 @@
 	.long sys_vfork
 	.long sys_getrlimit	/* 190 */
 	.long sys_readahead
-	.long sys_mmap2	
+	.long sys_mmap2
 	.long sys_truncate64
 	.long sys_ftruncate64
 	.long sys_stat64	/* 195 */
 	.long sys_lstat64
 	.long sys_fstat64
 	.long sys_pciconfig_read
-	.long sys_pciconfig_write 
+	.long sys_pciconfig_write
 	.long sys_pciconfig_iobase 	/* 200 */
 	.long sys_ni_syscall		/* 201 - reserved - MacOnLinux - new */
 	.long sys_getdents64
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/mk_defs.c linux-2.4.22-pre10/arch/ppc/kernel/mk_defs.c
--- linux-2.4.21/arch/ppc/kernel/mk_defs.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/mk_defs.c	2003-08-01 13:33:37.000000000 +0000
@@ -57,6 +57,9 @@
 	DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
 	DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
 #endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_4xx
+	DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
+#endif
 	/* Interrupt register frame */
 	DEFINE(TASK_UNION_SIZE, sizeof(union task_union));
 	DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/mpc10x_common.c linux-2.4.22-pre10/arch/ppc/kernel/mpc10x_common.c
--- linux-2.4.21/arch/ppc/kernel/mpc10x_common.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/mpc10x_common.c	2003-08-01 13:33:32.000000000 +0000
@@ -1,7 +1,7 @@
 
 /*
  * arch/ppc/kernel/mpc10x_common.c
- * 
+ *
  * Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge,
  * Mem ctlr, EPIC, etc.
  *
@@ -227,7 +227,7 @@
 			printk("Host bridge in Agent mode\n");
 			/* Read or Set LMBAR & PCSRBAR? */
 		}
-		       
+
 		/* Set base addr of the 8240/107 EUMB.  */
 		early_write_config_dword(hose,
 					 0,
@@ -236,7 +236,7 @@
 					 phys_eumb_base);
 
 		/* Map EPIC register part of EUMB into vitual memory */
-		OpenPIC_Addr = 
+		OpenPIC_Addr =
 			ioremap(phys_eumb_base + MPC10X_EUMB_EPIC_OFFSET,
 				MPC10X_EUMB_EPIC_SIZE);
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/ocp.c linux-2.4.22-pre10/arch/ppc/kernel/ocp.c
--- linux-2.4.21/arch/ppc/kernel/ocp.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/ocp.c	2003-08-01 13:33:32.000000000 +0000
@@ -0,0 +1,450 @@
+/*
+ * ocp.c
+ *
+ *      (c) Benjamin Herrenschmidt (benh@kernel.crashing.org)
+ *          Mipsys - France
+ *
+ "          Derived from work (c) Armin Kuster akuster@pacbell.net
+ *
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/list.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <asm/io.h>
+#include <asm/ocp.h>
+#include <asm/errno.h>
+#include <asm/rwsem.h>
+#include <asm/semaphore.h>
+
+//#define DBG(x)	printk x
+#define DBG(x)
+
+extern struct ocp_def core_ocp[];	/* Static list of devices, provided by
+					   CPU core */
+
+LIST_HEAD(ocp_devices);			/* List of all OCP devices */
+LIST_HEAD(ocp_drivers);			/* List of all OCP drivers */
+DECLARE_RWSEM(ocp_devices_sem);		/* Global semaphores for those lists */
+DECLARE_MUTEX(ocp_drivers_sem);		/* Global semaphores for those lists */
+
+static int ocp_inited;
+
+/**
+ *	ocp_driver_match	-	Match one driver to one device
+ *	@drv: driver to match
+ *	@dev: device to match
+ *
+ *	This function returns 0 if the driver and device don't match
+ */
+static int
+ocp_driver_match(struct ocp_driver *drv, struct ocp_device *dev)
+{
+	const struct ocp_device_id *ids = drv->id_table;
+
+	if (!ids)
+		return 0;
+
+	while (ids->vendor || ids->function) {
+		if ((ids->vendor == OCP_ANY_ID
+		     || ids->vendor == dev->def->vendor)
+		    && (ids->function == OCP_ANY_ID
+			|| ids->function == dev->def->function))
+		        return 1;
+		ids++;
+	}
+	return 0;
+}
+
+
+/**
+ *	ocp_bind_drivers	-	Match all drivers with all devices
+ *	@candidate: driver beeing registered
+ *
+ *	This function is called on driver registration and device discovery,
+ *	it redo the matching of all "driverless" devices with all possible
+ *	driver candidates.
+ *	The driver beeing registered can be optionally passed in, in which
+ *	case, the function will return -ENODEV is no match have been found
+ *	or if all matches failed with a different code than -EAGAIN
+ */
+static int
+ocp_bind_drivers(struct ocp_driver *candidate)
+{
+	struct list_head	*deventry, *drventry;
+	struct ocp_device	*dev;
+	struct ocp_driver	*drv;
+	int			one_again, one_match;
+	int			count = 0;
+
+	DBG(("ocp: binding drivers...\n"));
+	do {
+		/* We re-do the match loop if we had a sucess match and got one -EAGAIN
+		 */
+		one_match = one_again = 0;
+		down_read(&ocp_devices_sem);
+		list_for_each(deventry, &ocp_devices) {
+			dev = list_entry(deventry, struct ocp_device, link);
+			if (dev->driver != NULL)
+				continue;
+			DBG(("ocp: device %s unmatched, trying to match...\n", dev->name));
+			list_for_each(drventry, &ocp_drivers) {
+				drv = list_entry(drventry, struct ocp_driver, link);
+				if (ocp_driver_match(drv, dev)) {
+					int rc;
+
+					/* Hrm... shall we set dev->driver after or before ? */
+					DBG(("ocp: match with driver %s, calling probe...\n", drv->name));
+					rc = drv->probe(dev);
+					DBG(("ocp: probe result: %d\n", rc));
+					if (rc == 0) {
+						/* Driver matched, next device */
+						dev->driver = drv;
+						one_match = 1;
+						if (drv == candidate)
+							count++;
+						break;
+					} else if (rc == -EAGAIN) {
+						/* Driver matched but asked for later call, next device */
+						one_again = 1;
+						if (drv == candidate)
+							count++;
+						break;
+					}
+				}
+			}
+		}
+		up_read(&ocp_devices_sem);
+	} while(one_match && one_again);
+	DBG(("ocp: binding drivers... done.\n"));
+
+	return count;
+}
+
+/**
+ *	ocp_register_driver	-	Register an OCP driver
+ *	@drv: pointer to statically defined ocp_driver structure
+ *
+ *	The driver's probe() callback is called either recursively
+ *	by this function or upon later call of ocp_init
+ *
+ *      NOTE: Probe is called with ocp_drivers_sem heocp_find_deviceld, it shouldn't
+ *      call ocp_register/unregister_driver on his own code path.
+ *      however, it _can_ call ocp_find_device().
+ *
+ *	NOTE2: Detection of devices is a 2 pass step on this implementation,
+ *	hotswap isn't supported. First, all OCP devices are put in the device
+ *	list, _then_ all drivers are probed on each match.
+ *
+ *      NOTE3: Drivers are allowed to return -EAGAIN from the probe() routine.
+ *      this will cause them to be called again for this specific device as
+ *	soon as another device have been probed or another driver registered.
+ *	this, gives a simple way for a driver like EMAC to wait for another driver,
+ *	like MAL to be up. There is potentially a small race if MAL happens to
+ *	unregister, but this is hopefully never happening.
+ *
+ *	This function returns a count of how many devices actually matched
+ *	(wether the probe routine returned 0 or -EAGAIN, a different error
+ *	code isn't considered as a match).
+ */
+
+int
+ocp_register_driver(struct ocp_driver *drv)
+{
+	int	rc = 0;
+
+	DBG(("ocp: ocp_register_driver(%s)...\n", drv->name));
+
+	/* Add to driver list */
+	down(&ocp_drivers_sem);
+	list_add_tail(&drv->link, &ocp_drivers);
+
+	/* Check matching devices */
+	rc = ocp_bind_drivers(drv);
+
+	up(&ocp_drivers_sem);
+
+	DBG(("ocp: ocp_register_driver(%s)... done, count: %d.\n", drv->name, rc));
+
+	return rc;
+}
+
+/**
+ *	ocp_unregister_driver	-	Unregister an OCP driver
+ *	@drv: pointer to statically defined ocp_driver structure
+ *
+ *	The driver's remove() callback is called recursively
+ *	by this function for any device already registered
+ */
+
+void
+ocp_unregister_driver(struct ocp_driver *drv)
+{
+	struct ocp_device	*dev;
+	struct list_head	*entry;
+
+	DBG(("ocp: ocp_unregister_driver(%s)...\n", drv->name));
+
+	/* Call remove() routine for all devices using it */
+	down(&ocp_drivers_sem);
+	down_read(&ocp_devices_sem);
+	list_for_each(entry, &ocp_devices) {
+		dev = list_entry(entry, struct ocp_device, link);
+		if (dev->driver == drv) {
+			drv->remove(dev);
+			dev->driver = NULL;
+			dev->drvdata = NULL;
+		}
+	}
+	up_read(&ocp_devices_sem);
+
+	/* Unlink driver structure */
+	list_del_init(&drv->link);
+	up(&ocp_drivers_sem);
+
+	DBG(("ocp: ocp_unregister_driver(%s)... done.\n", drv->name));
+}
+
+/**
+ *	ocp_find_device	-	Find a device by function & index
+ *      @vendor: vendor ID of the device (or OCP_ANY_ID)
+ *	@function: function code of the device (or OCP_ANY_ID)
+ *	@idx: index of the device (or OCP_ANY_INDEX)
+ *
+ *	This function allows a lookup of a given function by it's
+ *	index, it's typically used to find the MAL or ZMII associated
+ *	with an EMAC or similar horrors.
+ *      You can pass vendor, though you usually want OCP_ANY_ID there...
+ */
+struct ocp_device *
+ocp_find_device(unsigned int vendor, unsigned int function, int index)
+{
+	struct list_head	*entry;
+	struct ocp_device	*dev, *found = NULL;
+
+	DBG(("ocp: ocp_find_device(vendor: %x, function: %x, index: %d)...\n",
+		vendor, function, index));
+
+	down_read(&ocp_devices_sem);
+	list_for_each(entry, &ocp_devices) {
+		dev = list_entry(entry, struct ocp_device, link);
+		if (vendor != OCP_ANY_ID && vendor != dev->def->vendor)
+			continue;
+		if (function != OCP_ANY_ID && function != dev->def->function)
+			continue;
+		if (index != OCP_ANY_INDEX && index != dev->def->index)
+			continue;
+		found = dev;
+		break;
+	}
+	up_read(&ocp_devices_sem);
+
+	DBG(("ocp: ocp_find_device(vendor: %x, function: %x, index: %d)... done.\n",
+		vendor, function, index));
+
+	return found;
+}
+
+/**
+ *	ocp_add_one_device	-	Add a device
+ *	@def: static device definition structure
+ *
+ *	This function is solely meant to be called by ocp_init
+ *	to add one device from the core static list to the
+ *	device list
+ */
+static void
+ocp_add_one_device(struct ocp_def *def)
+{
+	struct	ocp_device	*dev;
+
+	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL)
+		return;
+	memset(dev, 0, sizeof(*dev));
+	dev->def = def;
+	dev->current_state = 4;
+	sprintf(dev->name, "OCP device %04x:%04x:%04x",
+		dev->def->vendor, dev->def->function, dev->def->index);
+	list_add_tail(&dev->link, &ocp_devices);
+}
+
+#ifdef CONFIG_PM
+/*
+ * OCP Power management..
+ *
+ * This needs to be done centralized, so that we power manage PCI
+ * devices in the right order: we should not shut down PCI bridges
+ * before we've shut down the devices behind them, and we should
+ * not wake up devices before we've woken up the bridge to the
+ * device.. Eh?
+ *
+ * We do not touch devices that don't have a driver that exports
+ * a suspend/resume function. That is just too dangerous. If the default
+ * PCI suspend/resume functions work for a device, the driver can
+ * easily implement them (ie just have a suspend function that calls
+ * the pci_set_power_state() function).
+ *
+ * BenH: Implementation here couldn't work properly. This version
+ *       slightly modified and _might_ be more useable, but real
+ *       PM support will probably have to wait for 2.5
+ */
+
+static int ocp_pm_save_state_device(struct ocp_device *dev, u32 state)
+{
+	int error = 0;
+	if (dev) {
+		struct ocp_driver *driver = dev->driver;
+		if (driver && driver->save_state)
+			error = driver->save_state(dev,state);
+	}
+	return error;
+}
+
+static int ocp_pm_suspend_device(struct ocp_device *dev, u32 state)
+{
+	int error = 0;
+	if (dev) {
+		struct ocp_driver *driver = dev->driver;
+		if (driver && driver->suspend)
+			error = driver->suspend(dev,state);
+	}
+	return error;
+}
+
+static int ocp_pm_resume_device(struct ocp_device *dev)
+{
+	int error = 0;
+	if (dev) {
+		struct ocp_driver *driver = dev->driver;
+		if (driver && driver->resume)
+			error = driver->resume(dev);
+	}
+	return error;
+}
+
+static int
+ocp_pm_callback(struct pm_dev *pm_device, pm_request_t rqst, void *data)
+{
+	int error = 0;
+	struct list_head	*entry;
+	struct ocp_device	*dev;
+
+	down(&ocp_drivers_sem);
+	down_read(&ocp_devices_sem);
+
+	list_for_each(entry, &ocp_devices) {
+		dev = list_entry(entry, struct ocp_device, link);
+		switch (rqst) {
+		case PM_SAVE_STATE:
+			error = ocp_pm_save_state_device(dev, 3);
+			break;
+		case PM_SUSPEND:
+			error = ocp_pm_suspend_device(dev, 3);
+			break;
+		case PM_RESUME:
+			error = ocp_pm_resume_device(dev);
+			break;
+		default: break;
+		}
+		if (error)
+			break;
+	}
+	return error;
+}
+
+/*
+ * Is this ever used ?
+ */
+void
+ppc4xx_cpm_fr(u32 bits, int val)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	if (val)
+		mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) | bits);
+	else
+		mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) & ~bits);
+
+	restore_flags(flags);
+}
+#endif /* CONFIG_PM */
+
+/**
+ *	ocp_init	-	Init OCP device management
+ *
+ *	This function is meant to be called once, and only once to initialize
+ *	the OCP device management and build the list of devices. Note that
+ *	it can actually be called at any time, it's perfectly legal to
+ *	register drivers before ocp_init() is called
+ */
+int
+ocp_init(void)
+{
+	struct ocp_def	*def;
+
+	/* ocp_init is by default an initcall. If your arch requires this to
+	 * be called earlier, then go on, ocp_init is non-static for that purpose,
+	 * and can safely be called twice
+	 */
+	if (ocp_inited)
+		return 0;
+	ocp_inited = 1;
+
+	DBG(("ocp: ocp_init()...\n"));
+
+	/* Fill the devices list */
+	down_write(&ocp_devices_sem);
+	for (def = core_ocp; def->vendor != OCP_VENDOR_INVALID; def++)
+		ocp_add_one_device(def);
+	up_write(&ocp_devices_sem);
+
+	DBG(("ocp: ocp_init()... added...\n"));
+
+	/* Call drivers probes */
+	down(&ocp_drivers_sem);
+	ocp_bind_drivers(NULL);
+	up(&ocp_drivers_sem);
+
+#ifdef CONFIG_PM
+	pm_register(PM_SYS_DEV, 0, ocp_pm_callback);
+#endif
+
+	DBG(("ocp: ocp_init()... done.\n"));
+
+	return 0;
+}
+
+__initcall(ocp_init);
+
+EXPORT_SYMBOL(ocp_register_driver);
+EXPORT_SYMBOL(ocp_unregister_driver);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/open_pic.c linux-2.4.22-pre10/arch/ppc/kernel/open_pic.c
--- linux-2.4.21/arch/ppc/kernel/open_pic.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/open_pic.c	2003-08-01 13:33:40.000000000 +0000
@@ -540,7 +540,7 @@
 
 /*
  *  Send an IPI to one or more CPUs
- *  
+ *
  *  Externally called, however, it takes an IPI number (0...OPENPIC_NUM_IPI)
  *  and not a system-wide interrupt number
  */
@@ -557,12 +557,12 @@
 void openpic_request_IPIs(void)
 {
 	int i;
-	
+
 	/*
-	 * Make sure this matches what is defined in smp.c for 
-	 * smp_message_{pass|recv}() or what shows up in 
+	 * Make sure this matches what is defined in smp.c for
+	 * smp_message_{pass|recv}() or what shows up in
 	 * /proc/interrupts will be wrong!!! --Troy */
-	
+
 	if (OpenPIC == NULL)
 		return;
 
@@ -698,7 +698,7 @@
 {
 	volatile u_int *vpp;
 	u32 vp;
-	
+
 	check_arg_irq(irq);
 	vpp = &ISR[irq - open_pic_irq_offset]->Vector_Priority;
 	openpic_setfield(vpp, OPENPIC_MASK);
@@ -712,7 +712,7 @@
 #ifdef CONFIG_SMP
 /*
  *  Enable/disable an IPI interrupt source
- *  
+ *
  *  Externally called, irq is an offseted system-wide interrupt number
  */
 void openpic_enable_ipi(u_int irq)
@@ -875,7 +875,7 @@
 {
 	int	i;
 	unsigned long flags;
-	
+
 	spin_lock_irqsave(&openpic_setup_lock, flags);
 
 	for (i=0; i<NumProcessors; i++) {
@@ -903,7 +903,7 @@
 	unsigned long	flags;
 
 	spin_lock_irqsave(&openpic_setup_lock, flags);
-	
+
 	openpic_reset();
 
 	for (i=0; i<OPENPIC_NUM_IPI; i++)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/pci.c linux-2.4.22-pre10/arch/ppc/kernel/pci.c
--- linux-2.4.21/arch/ppc/kernel/pci.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/pci.c	2003-08-01 13:33:12.000000000 +0000
@@ -67,7 +67,7 @@
 	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,		PCI_ANY_ID,			pcibios_fixup_resources },
 #ifdef CONFIG_ALL_PPC
 	/* We should add per-machine fixup support in xxx_setup.c or xxx_pci.c */
-	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_TI,	PCI_ANY_ID,			pcibios_fixup_cardbus }, 
+	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_TI,	PCI_ANY_ID,			pcibios_fixup_cardbus },
 #endif /* CONFIG_ALL_PPC */
  	{ 0 }
 };
@@ -115,7 +115,7 @@
 	int reg;
 	struct pci_controller* hose = dev->sysdata;
 	unsigned long io_offset;
-	
+
 	new = res->start;
 	res->flags &= ~IORESOURCE_UNSET;
 	if (hose && res->flags & IORESOURCE_IO) {
@@ -211,7 +211,7 @@
 	    	/* Enable PCI interrupt */
 		if (pci_read_config_byte(dev, 0x91, &val) == 0)
 			pci_write_config_byte(dev, 0x91, val | 0x30);
-		/* Disable ISA interrupt mode */	
+		/* Disable ISA interrupt mode */
 		if (pci_read_config_byte(dev, 0x92, &val) == 0)
 			pci_write_config_byte(dev, 0x92, val & ~0x06);
 	}
@@ -223,7 +223,7 @@
 		   signal out the MFUNC0 pin */
 		if (pci_read_config_byte(dev, 0x8c, &val) == 0)
 			pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2);
-		/* Disable ISA interrupt mode */	
+		/* Disable ISA interrupt mode */
 		if (pci_read_config_byte(dev, 0x92, &val) == 0)
 			pci_write_config_byte(dev, 0x92, val & ~0x06);
 	}
@@ -695,7 +695,7 @@
 
 	hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose));
 	memset(hose, 0, sizeof(struct pci_controller));
-	
+
 	*hose_tail = hose;
 	hose_tail = &hose->next;
 
@@ -713,7 +713,7 @@
 {
 	int *bus_range;
 	int len;
-	
+
 	if (pci_bus >= pci_bus_count)
 		return;
 	bus_range = (int *) get_property(node, "bus-range", &len);
@@ -723,11 +723,11 @@
 		return;
 	}
 	pci_to_OF_bus_map[pci_bus] = bus_range[0];
-	
+
 	for (node=node->child; node != 0;node = node->sibling) {
 		struct pci_dev* dev;
 		unsigned int *class_code, *reg;
-		
+
 		class_code = (unsigned int *) get_property(node, "class-code", 0);
 		if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
 			(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
@@ -741,29 +741,29 @@
 		make_one_node_map(node, dev->subordinate->number);
 	}
 }
-		
+
 void __openfirmware
 pcibios_make_OF_bus_map(void)
 {
 	int i;
 	struct pci_controller* hose;
 	u8* of_prop_map;
-	
+
 	pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);
 	if (!pci_to_OF_bus_map) {
 		printk(KERN_ERR "Can't allocate OF bus map !\n");
 		return;
 	}
-	
+
 	/* We fill the bus map with invalid values, that helps
 	 * debugging.
 	 */
 	for (i=0; i<pci_bus_count; i++)
 		pci_to_OF_bus_map[i] = 0xff;
-	
+
 	/* For each hose, we begin searching bridges */
 	for(hose=hose_head; hose; hose=hose->next) {
-		struct device_node* node;		
+		struct device_node* node;
 		node = (struct device_node *)hose->arch_data;
 		if (!node)
 			continue;
@@ -779,7 +779,7 @@
 			continue;
 		printk("%d -> %d\n", i, pci_to_OF_bus_map[i]);
 	}
-#endif	
+#endif
 }
 
 typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data);
@@ -788,10 +788,10 @@
 scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data)
 {
 	struct device_node* sub_node;
-	
+
 	for (; node != 0;node = node->sibling) {
 		unsigned int *class_code;
-		
+
 		if (filter(node, data))
 			return node;
 
@@ -817,7 +817,7 @@
 {
 	unsigned int *reg;
 	u8* fdata = (u8*)data;
-		
+
 	reg = (unsigned int *) get_property(node, "reg", 0);
 	if (reg && ((reg[0] >> 8) & 0xff) == fdata[1]
 		&& ((reg[0] >> 16) & 0xff) == fdata[0])
@@ -833,7 +833,7 @@
 	return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data);
 }
 
-/* 
+/*
  * Scans the OF tree for a device node matching a PCI device
  */
 struct device_node*
@@ -842,10 +842,10 @@
 	struct pci_controller *hose;
 	struct device_node *node;
 	int bus;
-	
+
 	if (!have_of)
 		return NULL;
-		
+
 	/* Lookup the hose */
 	bus = dev->bus->number;
 	hose = pci_bus_to_hose(bus);
@@ -862,7 +862,7 @@
 		bus = pci_to_OF_bus_map[bus];
 	if (bus == 0xff)
 		return NULL;
-		
+
 	/* Now, lookup childs of the hose */
 	return scan_OF_childs_for_device(node->child, bus, dev->devfn);
 }
@@ -895,7 +895,7 @@
 	return ((void *)node == data);
 }
 
-/* 
+/*
  * Returns the PCI device matching a given OF node
  */
 int
@@ -904,7 +904,7 @@
 	unsigned int *reg;
 	struct pci_controller* hose;
 	struct pci_dev* dev;
-		
+
 	if (!have_of)
 		return -ENODEV;
 	/* Make sure it's really a PCI device */
@@ -1038,7 +1038,7 @@
 pci_create_OF_bus_map(void)
 {
 	struct property* of_prop;
-		
+
 	of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256);
 	if (of_prop && find_path_device("/")) {
 		memset(of_prop, -1, sizeof(struct property) + 256);
@@ -1053,13 +1053,13 @@
 /*
  * This set of routines checks for PCI<->PCI bridges that have closed
  * IO resources and have child devices. It tries to re-open an IO
- * window on them. 
- * 
+ * window on them.
+ *
  * This is a _temporary_ fix to workaround a problem with Apple's OF
  * closing IO windows on P2P bridges when the OF drivers of cards
  * below this bridge don't claim any IO range (typically ATI or
  * Adaptec).
- * 
+ *
  * A more complete fix would be to use drivers/pci/setup-bus.c, which
  * involves a working pcibios_fixup_pbus_ranges(), some more care about
  * ordering when creating the host bus resources, and maybe a few more
@@ -1075,7 +1075,7 @@
 	u32 l;
 	u16 w;
 	struct resource res;
-	
+
  	res = *(bus->resource[0]);
 
 	DBG("Remapping Bus %d, bridge: %s\n", bus->number, bridge->name);
@@ -1175,7 +1175,7 @@
 			break;
 	if (parent_io >= 4)
 		return;
-	
+
 	for (ln=bus->children.next; ln != &bus->children; ln=ln->next) {
 		struct pci_bus *b = pci_bus_b(ln);
 		struct pci_dev *d = b->self;
@@ -1193,7 +1193,7 @@
 		 */
 		if (tmp_res.start == 0)
 			tmp_res.start = 0x1000;
-		
+
 		if (!list_empty(&b->devices) && res && res->flags == 0 &&
 		    res != bus->resource[parent_io] &&
 		    (d->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
@@ -1222,7 +1222,7 @@
 			*res = tmp_res;
 			res->flags = IORESOURCE_IO;
 			res->name = b->name;
-			
+
 			/* Find a resource in the parent where we can allocate */
 			for (i = 0 ; i < 4; i++) {
 				struct resource *r = bus->resource[i];
@@ -1233,7 +1233,7 @@
 				DBG("Trying to allocate from %08lx, size %08lx from parent"
 				    " res %d: %08lx -> %08lx\n",
 					res->start, res->end, i, r->start, r->end);
-				
+
 				if (allocate_resource(r, res, res->end + 1, res->start, max,
 				    res->end + 1, NULL, NULL) < 0) {
 					DBG("Failed !\n");
@@ -1439,13 +1439,13 @@
 	if (ppc_md.pcibios_enable_device_hook)
 		if (ppc_md.pcibios_enable_device_hook(dev, 0))
 			return -EINVAL;
-			
+
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	old_cmd = cmd;
 	for (idx=0; idx<6; idx++) {
 		if(!(mask & (1<<idx)))
 			continue;
-			
+
 		r = &dev->resource[idx];
 		if (r->flags & IORESOURCE_UNSET) {
 			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
@@ -1709,7 +1709,7 @@
 
 	if (!hose)
 		return -ENODEV;
-	
+
 	switch (which) {
 	case IOBASE_BRIDGE_NUMBER:
 		return (long)hose->first_busno;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/pci_auto.c linux-2.4.22-pre10/arch/ppc/kernel/pci_auto.c
--- linux-2.4.21/arch/ppc/kernel/pci_auto.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/pci_auto.c	2003-08-01 13:31:30.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * arch/ppc/kernel/pci_auto.c
- * 
+ *
  * PCI autoconfiguration library
  *
  * Author: Matt Porter <mporter@mvista.com>
@@ -80,7 +80,7 @@
 			PCI_BASE_ADDRESS_MEM_TYPE_64)
 				found_mem64 = 1;
 
-			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;		
+			addr_mask = PCI_BASE_ADDRESS_MEM_MASK;
 			upper_limit = &pciauto_upper_memspc;
 			DBG("PCI Autoconfig: BAR 0x%x, Mem ", bar);
 		}
@@ -104,7 +104,7 @@
 		 * If we are a 64-bit decoder then increment to the
 		 * upper 32 bits of the bar and force it to locate
 		 * in the lower 4GB of memory.
-		 */ 
+		 */
 		if (found_mem64) {
 			bar += 4;
 			early_write_config_dword(hose,
@@ -243,7 +243,7 @@
 			pci_devfn,
 			PCI_IO_BASE_UPPER16,
 			pciauto_upper_iospc >> 16);
-	
+
 	/* Enable memory and I/O accesses, enable bus master */
 	early_read_config_dword(hose,
 			current_bus,
@@ -329,9 +329,9 @@
 	/*
 	 * Reserve an additional 4MB for mem space and 16KB for
 	 * I/O space.  This should cover any additional space
-	 * requirement of unusual CardBus devices with 
+	 * requirement of unusual CardBus devices with
 	 * additional bridges that can consume more address space.
-	 * 
+	 *
 	 * Although pcmcia-cs currently will reprogram bridge
 	 * windows, the goal is to add an option to leave them
 	 * alone and use the bridge window ranges as the regions
@@ -359,7 +359,7 @@
 			pci_devfn,
 			0x2c,
 			pciauto_upper_iospc);
-	
+
 	/* Enable memory and I/O accesses, enable bus master */
 	early_read_config_dword(hose,
 			current_bus,
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/ppc-stub.c linux-2.4.22-pre10/arch/ppc/kernel/ppc-stub.c
--- linux-2.4.21/arch/ppc/kernel/ppc-stub.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/ppc-stub.c	2003-08-01 13:34:30.000000000 +0000
@@ -716,10 +716,10 @@
 	     breakinst: .long 0x7d821008");
 }
 
-#ifdef CONFIG_KGDB_CONSOLE 
-/* 
+#ifdef CONFIG_KGDB_CONSOLE
+/*
  * Output string in GDB O-packet format if GDB has connected. If nothing
- * output, returns 0 (caller must then handle output) 
+ * output, returns 0 (caller must then handle output)
  */
 int
 kgdb_output_string (const char* s, unsigned int count)
@@ -729,7 +729,7 @@
         if (!kgdb_started)
             return 0;
 
-	count = (count <= (sizeof(buffer) / 2 - 2)) 
+	count = (count <= (sizeof(buffer) / 2 - 2))
 		? count : (sizeof(buffer) / 2 - 2);
 
 	buffer[0] = 'O';
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/ppc405_pci.c linux-2.4.22-pre10/arch/ppc/kernel/ppc405_pci.c
--- linux-2.4.21/arch/ppc/kernel/ppc405_pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/ppc405_pci.c	2003-08-01 13:33:00.000000000 +0000
@@ -0,0 +1,217 @@
+/*
+ * FILE NAME: ppc405_pci.c
+ *
+ * BRIEF MODULE DESCRIPTION:
+ * Based on arch/ppc/kernel/indirect.c, Copyright (C) 1998 Gabriel Paubert.
+ *
+ * Author: MontaVista Software, Inc.  <source@mvista.com>
+ *         Frank Rowand <frank_rowand@mvista.com>
+ *         Debbie Chu   <debbie_chu@mvista.com>
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/machdep.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <asm/ibm4xx.h>
+#include <asm/pci-bridge.h>
+#include <asm/ocp.h>
+
+#ifdef  CONFIG_DEBUG_BRINGUP
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+extern void bios_fixup(struct pci_controller *, struct pcil0_regs *);
+extern int ppc405_map_irq(struct pci_dev *dev, unsigned char idsel,
+			  unsigned char pin);
+
+void
+ppc405_pcibios_fixup_resources(struct pci_dev *dev)
+{
+	int i;
+	unsigned long max_host_addr;
+	unsigned long min_host_addr;
+	struct resource *res;
+
+	/*
+	 * openbios puts some graphics cards in the same range as the host
+	 * controller uses to map to SDRAM.  Fix it.
+	 */
+
+	min_host_addr = 0;
+	max_host_addr = PPC405_PCI_MEM_BASE - 1;
+
+	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+		res = dev->resource + i;
+		if (!res->start)
+			continue;
+		if ((res->flags & IORESOURCE_MEM) &&
+		    (((res->start >= min_host_addr)
+		      && (res->start <= max_host_addr))
+		     || ((res->end >= min_host_addr)
+			 && (res->end <= max_host_addr))
+		     || ((res->start < min_host_addr)
+			 && (res->end > max_host_addr))
+		    )
+		    ) {
+
+			DBG(KERN_ERR "PCI: 0x%lx <= resource[%d] <= 0x%lx"
+			    ", bus 0x%x dev 0x%2.2x.%1.1x,\n"
+			    KERN_ERR "  %s\n"
+			    KERN_ERR "  fixup will be attempted later\n",
+			    min_host_addr, i, max_host_addr,
+			    dev->bus->number, PCI_SLOT(dev->devfn),
+			    PCI_FUNC(dev->devfn), dev->name);
+
+			/* force pcibios_assign_resources() to assign a new address */
+			res->end -= res->start;
+			res->start = 0;
+		}
+	}
+}
+
+static int
+ppc4xx_exclude_device(unsigned char bus, unsigned char devfn)
+{
+	/* We prevent us from seeing ourselves to avoid having
+	 * the kernel try to remap our BAR #1 and fuck up bus
+	 * master from external PCI devices
+	 */
+	return (bus == 0 && devfn == 0);
+}
+
+void
+ppc4xx_find_bridges(void)
+{
+	struct pci_controller *hose_a;
+	struct pcil0_regs *pcip;
+	unsigned int new_pmm_max;
+	unsigned int new_pmm_min;
+
+	isa_io_base = 0;
+	isa_mem_base = 0;
+	pci_dram_offset = 0;
+
+#if  (PSR_PCI_ARBIT_EN > 1)
+	/* Check if running in slave mode */
+	if ((mfdcr(DCRN_CHPSR) & PSR_PCI_ARBIT_EN) == 0) {
+		printk("Running as PCI slave, kernel PCI disabled !\n");
+		return;
+	}
+#endif
+	/* Setup PCI32 hose */
+	hose_a = pcibios_alloc_controller();
+	if (!hose_a)
+		return;
+	setup_indirect_pci(hose_a, PPC405_PCI_CONFIG_ADDR,
+			   PPC405_PCI_CONFIG_DATA);
+
+#ifdef CONFIG_XILINX_OCP
+	/* Eliminate "unused variable" warning for pcip.  Optimizer removes. */
+	pcip = NULL;
+	new_pmm_min = PPC405_PCI_LOWER_MEM;
+	new_pmm_max = PPC405_PCI_UPPER_MEM;
+#else /* Must be IBM */
+	pcip = ioremap(PPC4xx_PCI_LCFG_PADDR, PAGE_SIZE);
+	if (pcip != NULL) {
+		unsigned int tmp_addr;
+		unsigned int tmp_size;
+		unsigned int reg_index;
+
+#if defined(CONFIG_BIOS_FIXUP)
+		bios_fixup(hose_a, pcip);
+#endif
+		new_pmm_min = 0xffffffff;
+		for (reg_index = 0; reg_index < 3; reg_index++) {
+			tmp_size = in_le32((void *) &(pcip->pmm[reg_index].ma));	// *_PMM0MA
+			if (tmp_size & 0x1) {
+				tmp_addr = in_le32((void *) &(pcip->pmm[reg_index].pcila));	// *_PMM0PCILA
+				if (tmp_addr < PPC405_PCI_PHY_MEM_BASE) {
+					printk(KERN_DEBUG
+					       "Disabling mapping to PCI mem addr 0x%8.8x\n",
+					       tmp_addr);
+					out_le32((void *) &(pcip->pmm[reg_index].ma), tmp_size & ~1);	// *_PMMOMA
+				} else {
+					tmp_addr = in_le32((void *) &(pcip->pmm[reg_index].la));	// *_PMMOLA
+					if (tmp_addr < new_pmm_min)
+						new_pmm_min = tmp_addr;
+					tmp_addr =
+					    tmp_addr + (0xffffffff -
+							(tmp_size &
+							 0xffffc000));
+					if (tmp_addr > PPC405_PCI_UPPER_MEM) {
+						new_pmm_max = tmp_addr;	// PPC405_PCI_UPPER_MEM
+					} else {
+						new_pmm_max =
+						    PPC405_PCI_UPPER_MEM;
+					}
+				}
+			}
+
+		}		// for
+
+		iounmap(pcip);
+	}
+#endif
+
+	hose_a->first_busno = 0;
+	hose_a->last_busno = 0xff;
+	hose_a->pci_mem_offset = 0;
+
+	/* Setup bridge memory/IO ranges & resources
+	 * TODO: Handle firmwares setting up a legacy ISA mem base
+	 */
+	hose_a->io_space.start = PPC405_PCI_LOWER_IO;
+	hose_a->io_space.end = PPC405_PCI_UPPER_IO;
+	hose_a->mem_space.start = new_pmm_min;
+	hose_a->mem_space.end = new_pmm_max;
+	hose_a->io_base_phys = PPC405_PCI_PHY_IO_BASE;
+	hose_a->io_base_virt = ioremap(hose_a->io_base_phys, 0x10000);
+	hose_a->io_resource.start = 0;
+	hose_a->io_resource.end = PPC405_PCI_UPPER_IO - PPC405_PCI_LOWER_IO;
+	hose_a->io_resource.flags = IORESOURCE_IO;
+	hose_a->io_resource.name = "PCI I/O";
+	hose_a->mem_resources[0].start = new_pmm_min;
+	hose_a->mem_resources[0].end = new_pmm_max;
+	hose_a->mem_resources[0].flags = IORESOURCE_MEM;
+	hose_a->mem_resources[0].name = "PCI Memory";
+	isa_io_base = (int) hose_a->io_base_virt;
+	isa_mem_base = 0;	/*     ISA not implemented */
+	ISA_DMA_THRESHOLD = 0x00ffffff;	/* ??? ISA not implemented */
+
+	/* Scan busses & initial setup by pci_auto */
+	hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
+
+	/* Setup ppc_md */
+	ppc_md.pcibios_fixup = NULL;
+	ppc_md.pci_exclude_device = ppc4xx_exclude_device;
+	ppc_md.pcibios_fixup_resources = ppc405_pcibios_fixup_resources;
+	ppc_md.pci_swizzle = common_swizzle;
+	ppc_md.pci_map_irq = ppc405_map_irq;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/ppc4xx_pic.c linux-2.4.22-pre10/arch/ppc/kernel/ppc4xx_pic.c
--- linux-2.4.21/arch/ppc/kernel/ppc4xx_pic.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/ppc4xx_pic.c	2003-08-01 13:30:27.000000000 +0000
@@ -15,10 +15,14 @@
  * there are eight internal interrupts for the on-chip serial port
  * (SPU), DMA controller, and JTAG controller.
  *
- * The PowerPC 405 cores' Universal Interrupt Controller (UIC) has 32
- * possible interrupts as well. There are seven, configurable external
- * interrupt pins and there are 17 internal interrupts for the on-chip
- * serial port, DMA controller, on-chip Ethernet controller, PCI, etc.
+ * The PowerPC 405/440 cores' Universal Interrupt Controller (UIC) has
+ * 32 possible interrupts as well.  Depending on the core and SoC
+ * implementation, a portion of the interrrupts are used for on-chip
+ * peripherals and a portion of the interrupts are available to be
+ * configured for external devices generating interrupts.
+ *
+ * The PowerNP and 440GP (and most likely future implementations) have
+ * cascaded UICs.
  *
  */
 
@@ -33,19 +37,31 @@
 #include <asm/ppc4xx_pic.h>
 
 /* Global Variables */
-
 struct hw_interrupt_type *ppc4xx_pic;
+/*
+ * We define 4xxIRQ_InitSenses table thusly:
+ * bit 0x1: sense, 0 for edge and 1 for level.
+ * bit 0x2: polarity, 0 for negative, 1 for positive.
+ */
+unsigned int ibm4xxPIC_NumInitSenses __initdata = 0;
+unsigned char *ibm4xxPIC_InitSenses __initdata = NULL;
+
+/* Six of one, half dozen of the other....#ifdefs, separate files,
+ * other tricks.....
+ *
+ * There are basically two types of interrupt controllers, the 403 AIC
+ * and the "others" with UIC.  I just kept them both here separated
+ * with #ifdefs, but it seems to change depending upon how supporting
+ * files (like ppc4xx.h) change.		-- Dan.
+ */
 
+#ifdef CONFIG_403
 
 /* Function Prototypes */
 
-static void	 ppc403_aic_enable(unsigned int irq);
-static void	 ppc403_aic_disable(unsigned int irq);
-static void	 ppc403_aic_disable_and_ack(unsigned int irq);
-
-static void	 ppc405_uic_enable(unsigned int irq);
-static void	 ppc405_uic_disable(unsigned int irq);
-static void	 ppc405_uic_disable_and_ack(unsigned int irq);
+static void ppc403_aic_enable(unsigned int irq);
+static void ppc403_aic_disable(unsigned int irq);
+static void ppc403_aic_disable_and_ack(unsigned int irq);
 
 static struct hw_interrupt_type ppc403_aic = {
 	"403GC AIC",
@@ -57,55 +73,11 @@
 	0
 };
 
-static struct hw_interrupt_type ppc405_uic = {
-	"405GP UIC",
-	NULL,
-	NULL,
-	ppc405_uic_enable,
-	ppc405_uic_disable,
-	ppc405_uic_disable_and_ack,
-	0
-};
-
-/*
- * Document me.
- */
-void __init
-ppc4xx_pic_init(void)
-{
-	unsigned long ver = PVR_VER(mfspr(SPRN_PVR));
-
-	switch (ver) {
-
-	case PVR_VER(PVR_403GC):
-		/*
-		 * Disable all external interrupts until they are
-		 * explicity requested.
-		 */
-		ppc_cached_irq_mask[0] = 0;
-		mtdcr(DCRN_EXIER, 0);
-
-		ppc4xx_pic = &ppc403_aic;
-		break;
-
-	case PVR_VER(PVR_405GP):
-		ppc4xx_pic = &ppc405_uic;
-		break;
-	}
-
-	return;
-}
-
-/*
- * XXX - Currently 403-specific!
- *
- * Document me.
- */
 int
-ppc4xx_pic_get_irq(struct pt_regs *regs)
+ppc403_pic_get_irq(struct pt_regs *regs)
 {
 	int irq;
-	unsigned long bits, mask = (1 << 31);
+	unsigned long bits;
 
 	/*
 	 * Only report the status of those interrupts that are actually
@@ -117,19 +89,17 @@
 	/*
 	 * Walk through the interrupts from highest priority to lowest, and
 	 * report the first pending interrupt found.
+	 * We want PPC, not C bit numbering, so just subtract the ffs()
+	 * result from 32.
 	 */
+	irq = 32 - ffs(bits);
 
-	for (irq = 0; irq < NR_IRQS; irq++, mask >>= 1) {
-		if (bits & mask)
-			break;
-	}
+	if (irq == NR_AIC_IRQS)
+		irq = -1;
 
 	return (irq);
 }
 
-/*
- * Document me.
- */
 static void
 ppc403_aic_enable(unsigned int irq)
 {
@@ -142,9 +112,6 @@
 	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
 }
 
-/*
- * Document me.
- */
 static void
 ppc403_aic_disable(unsigned int irq)
 {
@@ -157,9 +124,6 @@
 	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
 }
 
-/*
- * Document me.
- */
 static void
 ppc403_aic_disable_and_ack(unsigned int irq)
 {
@@ -173,29 +137,308 @@
 	mtdcr(DCRN_EXISR, (1 << (31 - bit)));
 }
 
-/*
- * Document me.
- */
+#else
+
+#ifndef UIC1
+#define UIC1 UIC0
+#endif
+
 static void
 ppc405_uic_enable(unsigned int irq)
 {
-	/* XXX - Implement me. */
+	int bit, word;
+	irq_desc_t *desc = irq_desc + irq;
+
+	bit = irq & 0x1f;
+	word = irq >> 5;
+
+#ifdef UIC_DEBUG
+	printk("ppc405_uic_enable - irq %d word %d bit 0x%x\n", irq, word, bit);
+#endif
+	ppc_cached_irq_mask[word] |= 1 << (31 - bit);
+	switch (word) {
+	case 0:
+		mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
+		if ((mfdcr(DCRN_UIC_TR(UIC0)) & (1 << (31 - bit))) == 0)
+			desc->status |= IRQ_LEVEL;
+		else
+		/* lets hope this works since in linux/irq.h
+		 * there is no define for EDGE and it's assumed
+		 * once you set status to LEVEL you would not
+		 * want to change it - Armin
+		 */
+		desc->status = desc->status & ~IRQ_LEVEL;
+		break;
+	case 1:
+		mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
+		if ((mfdcr(DCRN_UIC_TR(UIC1)) & (1 << (31 - bit))) == 0)
+			desc->status |= IRQ_LEVEL;
+		else
+		/* lets hope this works since in linux/irq.h
+		 * there is no define for EDGE and it's assumed
+		 * once you set status to LEVEL you would not
+		 * want to change it - Armin
+		 */
+		desc->status = desc->status & ~IRQ_LEVEL;
+	break;
+	}
+
 }
 
-/*
- * Document me.
- */
 static void
 ppc405_uic_disable(unsigned int irq)
 {
-	/* XXX - Implement me. */
+	int bit, word;
+
+	bit = irq & 0x1f;
+	word = irq >> 5;
+#ifdef UIC_DEBUG
+	printk("ppc405_uic_disable - irq %d word %d bit 0x%x\n", irq, word,
+	       bit);
+#endif
+	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
+	switch (word) {
+	case 0:
+		mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
+		break;
+	case 1:
+		mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
+		break;
+	}
 }
 
-/*
- * Document me.
- */
 static void
 ppc405_uic_disable_and_ack(unsigned int irq)
 {
-	/* XXX - Implement me. */
+	int bit, word;
+
+	bit = irq & 0x1f;
+	word = irq >> 5;
+
+#ifdef UIC_DEBUG
+	printk("ppc405_uic_disable_and_ack - irq %d word %d bit 0x%x\n", irq,
+	       word, bit);
+#endif
+	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
+	switch (word) {
+	case 0:
+		mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
+		mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - bit)));
+		break;
+#if NR_UICS > 1
+	case 1:
+		mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
+		mtdcr(DCRN_UIC_SR(UIC1), (1 << (31 - bit)));
+		/* ACK cascaded interrupt in UIC0 */
+		mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - UIC0_UIC1NC)));
+		break;
+#endif
+	}
+}
+
+static void
+ppc405_uic_end(unsigned int irq)
+{
+	int bit, word;
+	unsigned int tr_bits;
+
+	bit = irq & 0x1f;
+	word = irq >> 5;
+
+#ifdef UIC_DEBUG
+	printk("ppc405_uic_end - irq %d word %d bit 0x%x\n", irq, word, bit);
+#endif
+
+	switch (word) {
+	case 0:
+		tr_bits = mfdcr(DCRN_UIC_TR(UIC0));
+		break;
+	case 1:
+		tr_bits = mfdcr(DCRN_UIC_TR(UIC1));
+		break;
+	}
+
+	if ((tr_bits & (1 << (31 - bit))) == 0) {
+		/* level trigger */
+		switch (word) {
+		case 0:
+			mtdcr(DCRN_UIC_SR(UIC0), 1 << (31 - bit));
+			break;
+#if NR_UICS > 1
+		case 1:
+			mtdcr(DCRN_UIC_SR(UIC1), 1 << (31 - bit));
+			/* ACK cascaded interrupt in UIC0 */
+			mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - UIC0_UIC1NC)));
+			break;
+#endif
+		}
+	}
+
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		ppc_cached_irq_mask[word] |= 1 << (31 - bit);
+		switch (word) {
+		case 0:
+			mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
+			break;
+		case 1:
+			mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
+			break;
+		}
+	}
+}
+
+static struct hw_interrupt_type ppc405_uic = {
+#if (NR_UICS == 1)
+	"IBM UIC",
+#else
+	"IBM UIC Cascade",
+#endif
+	NULL,
+	NULL,
+	ppc405_uic_enable,
+	ppc405_uic_disable,
+	ppc405_uic_disable_and_ack,
+	ppc405_uic_end,
+	0
+};
+
+int
+ppc405_pic_get_irq(struct pt_regs *regs)
+{
+	int irq, cas_irq;
+	unsigned long bits;
+	cas_irq = 0;
+	/*
+	 * Only report the status of those interrupts that are actually
+	 * enabled.
+	 */
+
+	bits = mfdcr(DCRN_UIC_MSR(UIC0));
+
+#if (NR_UICS > 1)
+	if (bits & UIC_CASCADE_MASK) {
+		bits = mfdcr(DCRN_UIC_MSR(UIC1));
+		cas_irq = 32 - ffs(bits);
+		irq = 32 + cas_irq;
+	} else {
+		irq = 32 - ffs(bits);
+		if (irq == 32)
+			irq = -1;
+	}
+#else
+	/*
+	 * Walk through the interrupts from highest priority to lowest, and
+	 * report the first pending interrupt found.
+	 * We want PPC, not C bit numbering, so just subtract the ffs()
+	 * result from 32.
+	 */
+	irq = 32 - ffs(bits);
+#endif
+	if (irq == (NR_UIC_IRQS * NR_UICS))
+		irq = -1;
+
+#ifdef UIC_DEBUG
+	printk("ppc405_pic_get_irq - irq %d bit 0x%x\n", irq, bits);
+#endif
+
+	return (irq);
+}
+#endif
+
+void __init
+ppc4xx_extpic_init(void)
+{
+	unsigned int sense, irq;
+	int bit, word;
+	unsigned long ppc_cached_sense_mask[NR_MASK_WORDS];
+	unsigned long ppc_cached_pol_mask[NR_MASK_WORDS];
+	ppc_cached_sense_mask[0] = 0;
+	ppc_cached_sense_mask[1] = 0;
+	ppc_cached_pol_mask[0] = 0;
+	ppc_cached_pol_mask[1] = 0;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+
+		bit = irq & 0x1f;
+		word = irq >> 5;
+
+		sense = (irq < ibm4xxPIC_NumInitSenses) ?
+			ibm4xxPIC_InitSenses[irq] :
+			IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE;
+#ifdef PPC4xx_PIC_DEBUG
+		printk("PPC4xx_picext %d word:%x bit:%x sense:%x", irq, word,
+		       bit, sense);
+#endif
+		ppc_cached_sense_mask[word] |=
+		    (~sense & IRQ_SENSE_MASK) << (31 - bit);
+		ppc_cached_pol_mask[word] |=
+		    ((sense & IRQ_POLARITY_MASK) >> 1) << (31 - bit);
+		switch (word) {
+		case 0:
+#ifdef PPC4xx_PIC_DEBUG
+			printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC0)));
+			printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC0)));
+#endif
+			/* polarity  setting */
+			mtdcr(DCRN_UIC_PR(UIC0), ppc_cached_pol_mask[word]);
+
+			/* Level setting */
+			mtdcr(DCRN_UIC_TR(UIC0), ppc_cached_sense_mask[word]);
+
+			break;
+		case 1:
+#ifdef PPC4xx_PIC_DEBUG
+			printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC1)));
+			printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC1)));
+#endif
+			/* polarity  setting */
+			mtdcr(DCRN_UIC_PR(UIC1), ppc_cached_pol_mask[word]);
+
+			/* Level setting */
+			mtdcr(DCRN_UIC_TR(UIC1), ppc_cached_sense_mask[word]);
+
+			break;
+		}
+	}
+
+}
+void __init
+ppc4xx_pic_init(void)
+{
+
+	/*
+	 * Disable all external interrupts until they are
+	 * explicity requested.
+	 */
+	ppc_cached_irq_mask[0] = 0;
+	ppc_cached_irq_mask[1] = 0;
+
+#if defined CONFIG_403
+	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[0]);
+
+	ppc4xx_pic = &ppc403_aic;
+	ppc_md.get_irq = ppc403_pic_get_irq;
+#else
+#if  (NR_UICS > 1)
+	ppc_cached_irq_mask[0] |= 1 << (31 - UIC0_UIC1NC);	/* enable cascading interrupt */
+	mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[1]);
+	mtdcr(DCRN_UIC_CR(UIC1), 0);
+
+#endif
+	mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
+	mtdcr(DCRN_UIC_CR(UIC0), 0);
+
+	if (ibm4xxPIC_InitSenses != NULL)
+		ppc4xx_extpic_init();
+
+	/* Clear any pending interrupts */
+#if (NR_UICS > 1)
+	mtdcr(DCRN_UIC_SR(UIC1), 0xffffffff);
+#endif
+	mtdcr(DCRN_UIC_SR(UIC0), 0xffffffff);
+
+	ppc4xx_pic = &ppc405_uic;
+	ppc_md.get_irq = ppc405_pic_get_irq;
+#endif
+
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/ppc4xx_setup.c linux-2.4.22-pre10/arch/ppc/kernel/ppc4xx_setup.c
--- linux-2.4.21/arch/ppc/kernel/ppc4xx_setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/ppc4xx_setup.c	2003-08-01 13:31:30.000000000 +0000
@@ -0,0 +1,431 @@
+/*
+ *
+ *    Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
+ *
+ *    Copyright 2000-2002 MontaVista Software Inc.
+ *      Completed implementation.
+ *      Author: MontaVista Software, Inc.  <source@mvista.com>
+ *              Frank Rowand <frank_rowand@mvista.com>
+ *              Debbie Chu   <debbie_chu@mvista.com>
+ *
+ *    Module name: ppc4xx_setup.c
+ *
+ *    Description:
+ *      Architecture- / platform-specific boot-time initialization code for
+ *      IBM PowerPC 4xx based boards. Adapted from original
+ *      code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
+ *      <dan@net4x.com>.
+ *
+ * 	History: 11/09/2001 - armin
+ *	rename board_setup_nvram_access to board_init. board_init is
+ *	used for all other board specific instructions needed during
+ *	platform_init.
+ *	moved RTC to board.c files
+ *	moved VT/FB to board.c files
+ *	moved r/w4 ide to redwood.c
+ *
+ *	History: 04/18/02 - Armin
+ *	added ash to setting CETE bit in calibrate()
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/threads.h>
+#include <linux/spinlock.h>
+#include <linux/irq.h>
+#include <linux/reboot.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/blk.h>
+#include <linux/pci.h>
+#include <linux/rtc.h>
+#include <linux/console.h>
+#include <linux/ide.h>
+#include <linux/serial_reg.h>
+#include <linux/seq_file.h>
+#include <linux/module.h>
+
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/machdep.h>
+#include <asm/page.h>
+#include <asm/kgdb.h>
+#include <asm/ibm4xx.h>
+#include <asm/time.h>
+#include <asm/todc.h>
+#include <asm/ppc4xx_pic.h>
+#include <asm/pci-bridge.h>
+#include <asm/bootinfo.h>
+
+/* Function Prototypes */
+static void ppc4xx_gdb_init(void);
+
+extern void abort(void);
+extern void ppc4xx_find_bridges(void);
+
+extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int pckbd_getkeycode(unsigned int scancode);
+extern int pckbd_pretranslate(unsigned char scancode, char raw_mode);
+extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+			   char raw_mode);
+extern char pckbd_unexpected_up(unsigned char keycode);
+extern void pckbd_leds(unsigned char leds);
+extern void pckbd_init_hw(void);
+
+extern int nonpci_ide_default_irq(ide_ioreg_t base);
+extern void nonpci_ide_init_hwif_ports(hw_regs_t * hw, ide_ioreg_t data_port,
+				       ide_ioreg_t ctrl_port, int *irq);
+
+extern void ppc4xx_wdt_heartbeat(void);
+extern int wdt_enable;
+extern unsigned long wdt_period;
+//extern void early_uart_init(void);
+
+/* Board specific functions */
+extern void board_setup_arch(void);
+extern void board_io_mapping(void);
+extern void board_setup_irq(void);
+extern void board_init(void);
+
+/* Global Variables */
+unsigned char __res[sizeof (bd_t)];
+
+#if defined(EMAC_NUMS) && EMAC_NUMS > 0
+u32 emac_phy_map[EMAC_NUMS];
+EXPORT_SYMBOL(emac_phy_map);
+#endif
+
+static void __init
+ppc4xx_setup_arch(void)
+{
+
+	/* Setup PCI host bridges */
+
+#ifdef CONFIG_PCI
+	ppc4xx_find_bridges();
+#endif
+
+#if defined(CONFIG_FB)
+	conswitchp = &dummy_con;
+#endif
+#if defined (CONFIG_SERIAL) && !defined (CONFIG_RAINIER)
+//	early_uart_init();
+#endif
+	board_setup_arch();
+
+	ppc4xx_gdb_init();
+}
+
+/*
+ *   This routine pretty-prints the platform's internal CPU clock
+ *   frequencies into the buffer for usage in /proc/cpuinfo.
+ */
+
+static int
+ppc4xx_show_percpuinfo(struct seq_file *m, int i)
+{
+	bd_t *bip = (bd_t *) __res;
+
+	seq_printf(m, "clock\t\t: %ldMHz\n", (long) bip->bi_intfreq / 1000000);
+
+	return 0;
+}
+
+/*
+ *   This routine pretty-prints the platform's internal bus clock
+ *   frequencies into the buffer for usage in /proc/cpuinfo.
+ */
+static int
+ppc4xx_show_cpuinfo(struct seq_file *m)
+{
+	bd_t *bip = (bd_t *) __res;
+
+	seq_printf(m, "machine\t\t: %s\n", PPC4xx_MACHINE_NAME);
+	seq_printf(m, "plb bus clock\t: %ldMHz\n",
+		   (long) bip->bi_busfreq / 1000000);
+#ifdef CONFIG_PCI
+	seq_printf(m, "pci bus clock\t: %dMHz\n",
+		   bip->bi_pci_busfreq / 1000000);
+#endif
+
+	return 0;
+}
+
+/*
+ * Return the virtual address representing the top of physical RAM.
+ */
+static unsigned long __init
+ppc4xx_find_end_of_memory(void)
+{
+	bd_t *bip = (bd_t *) __res;
+
+	return ((unsigned long) bip->bi_memsize);
+}
+
+static void __init
+m4xx_map_io(void)
+{
+	io_block_mapping(PPC4xx_ONB_IO_VADDR,
+			 PPC4xx_ONB_IO_PADDR, PPC4xx_ONB_IO_SIZE, _PAGE_IO);
+#ifdef CONFIG_PCI
+	io_block_mapping(PPC4xx_PCI_IO_VADDR,
+			 PPC4xx_PCI_IO_PADDR, PPC4xx_PCI_IO_SIZE, _PAGE_IO);
+	io_block_mapping(PPC4xx_PCI_CFG_VADDR,
+			 PPC4xx_PCI_CFG_PADDR, PPC4xx_PCI_CFG_SIZE, _PAGE_IO);
+	io_block_mapping(PPC4xx_PCI_LCFG_VADDR,
+			 PPC4xx_PCI_LCFG_PADDR, PPC4xx_PCI_LCFG_SIZE, _PAGE_IO);
+#endif
+	board_io_mapping();
+}
+
+static void __init
+ppc4xx_init_IRQ(void)
+{
+	int i;
+
+	ppc4xx_pic_init();
+
+	for (i = 0; i < NR_IRQS; i++)
+		irq_desc[i].handler = ppc4xx_pic;
+
+	/* give board specific code a chance to setup things */
+	board_setup_irq();
+	return;
+}
+
+static void
+ppc4xx_restart(char *cmd)
+{
+	printk("%s\n", cmd);
+	abort();
+}
+
+static void
+ppc4xx_halt(void)
+{
+	printk("System Halted\n");
+	__cli();
+	while (1) ;
+}
+
+static void __init
+ppc4xx_gdb_init(void)
+{
+#if !defined(CONFIG_BDI_SWITCH)
+	/*
+	 * The Abatron BDI JTAG debugger does not tolerate others
+	 * mucking with the debug registers.
+	 */
+	mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM));
+	mtspr(SPRN_DBCR1, 0);
+#endif
+}
+
+/*
+ * This routine retrieves the internal processor frequency from the board
+ * information structure, sets up the kernel timer decrementer based on
+ * that value, enables the 4xx programmable interval timer (PIT) and sets
+ * it up for auto-reload.
+ */
+static void __init
+ppc4xx_calibrate_decr(void)
+{
+	unsigned int freq;
+	bd_t *bip = (bd_t *) __res;
+
+#if defined(CONFIG_WALNUT) || defined(CONFIG_CEDER) 	\
+	|| defined(CONFIG_ASH) || defined(CONFIG_SYCAMORE)
+	/* Openbios sets cpu  timers to CPU clk
+	 * we want to use the external clk
+	 * DCR CHCR1 (aka CPC0_CR1) bit CETE to 1 */
+
+	mtdcr(DCRN_CHCR1, mfdcr(DCRN_CHCR1) & ~CHR1_CETE);
+#endif
+
+	freq = bip->bi_tbfreq;
+//	tb_ticks_per_jiffy = freq / HZ;
+//	tb_to_us = mulhwu_scale_factor(freq, 1000000);
+	tb_ticks_per_jiffy = (freq + HZ/2) / HZ;
+	tb_to_us = mulhwu_scale_factor(tb_ticks_per_jiffy*HZ, 1000000U);
+
+	/* Set the time base to zero.
+	   ** At 200 Mhz, time base will rollover in ~2925 years.
+	 */
+
+	mtspr(SPRN_TBWL, 0);
+	mtspr(SPRN_TBWU, 0);
+
+	/* Clear any pending timer interrupts */
+
+	mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_PIS | TSR_FIS);
+	mtspr(SPRN_TCR, TCR_PIE | TCR_ARE);
+
+	/* Set the PIT reload value and just let it run. */
+	mtspr(SPRN_PIT, tb_ticks_per_jiffy);
+}
+
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+
+/* We assume that the UART has already been initialized by the
+   firmware or the boot loader */
+static void
+serial_putc(u8 * com_port, unsigned char c)
+{
+	while ((readb(com_port + (UART_LSR)) & UART_LSR_THRE) == 0) ;
+	writeb(c, com_port);
+}
+
+static void
+ppc4xx_progress(char *s, unsigned short hex)
+{
+	char c;
+#ifdef SERIAL_DEBUG_IO_BASE
+	u8 *com_port = (u8 *) SERIAL_DEBUG_IO_BASE;
+
+	while ((c = *s++) != '\0') {
+		serial_putc(com_port, c);
+	}
+	serial_putc(com_port, '\r');
+	serial_putc(com_port, '\n');
+#else
+	printk("%s\r\n", s);
+#endif
+}
+#endif				/* CONFIG_SERIAL_TEXT_DEBUG */
+
+/*
+ * IDE stuff.
+ * should be generic for every IDE PCI chipset
+ */
+#if defined(CONFIG_BLK_DEV_IDEPCI)
+static void
+ppc4xx_ide_init_hwif_ports(hw_regs_t * hw, ide_ioreg_t data_port,
+			   ide_ioreg_t ctrl_port, int *irq)
+{
+	int i;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; ++i)
+		hw->io_ports[i] = data_port + i - IDE_DATA_OFFSET;
+
+	hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+}
+#endif
+
+TODC_ALLOC();
+
+/*
+ * Input(s):
+ *   r3 - Optional pointer to a board information structure.
+ *   r4 - Optional pointer to the physical starting address of the init RAM
+ *        disk.
+ *   r5 - Optional pointer to the physical ending address of the init RAM
+ *        disk.
+ *   r6 - Optional pointer to the physical starting address of any kernel
+ *        command-line parameters.
+ *   r7 - Optional pointer to the physical ending address of any kernel
+ *        command-line parameters.
+ */
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+	      unsigned long r6, unsigned long r7)
+{
+	parse_bootinfo(find_bootinfo());
+
+	/*
+	 * If we were passed in a board information, copy it into the
+	 * residual data area.
+	 */
+	if (r3) {
+		memcpy((void *) __res, (void *) (r3 + KERNELBASE),
+		       sizeof (bd_t));
+
+	}
+#if defined(CONFIG_BLK_DEV_INITRD)
+	/*
+	 * If the init RAM disk has been configured in, and there's a valid
+	 * starting address for it, set it up.
+	 */
+	if (r4) {
+		initrd_start = r4 + KERNELBASE;
+		initrd_end = r5 + KERNELBASE;
+	}
+#endif				/* CONFIG_BLK_DEV_INITRD */
+
+	/* Copy the kernel command line arguments to a safe place. */
+
+	if (r6) {
+		*(char *) (r7 + KERNELBASE) = 0;
+		strcpy(cmd_line, (char *) (r6 + KERNELBASE));
+	}
+#if defined(CONFIG_PPC405_WDT)
+	ppc_md.heartbeat = ppc4xx_wdt_heartbeat;
+
+/* Look for wdt= option on command line */
+	if (strstr(cmd_line, "wdt=")) {
+		int valid_wdt = 0;
+		char *p, *q;
+		for (q = cmd_line; (p = strstr(q, "wdt=")) != 0;) {
+			q = p + 4;
+			if (p > cmd_line && p[-1] != ' ')
+				continue;
+			wdt_period = simple_strtoul(q, &q, 0);
+			valid_wdt = 1;
+			++q;
+		}
+		wdt_enable = valid_wdt;
+	}
+#endif
+
+	/* Initialize machine-dependency vectors */
+
+	ppc_md.setup_arch = ppc4xx_setup_arch;
+	ppc_md.show_percpuinfo = ppc4xx_show_percpuinfo;
+	ppc_md.show_cpuinfo = ppc4xx_show_cpuinfo;
+	ppc_md.init_IRQ = ppc4xx_init_IRQ;
+
+	ppc_md.restart = ppc4xx_restart;
+	ppc_md.power_off = ppc4xx_halt;
+	ppc_md.halt = ppc4xx_halt;
+
+	ppc_md.calibrate_decr = ppc4xx_calibrate_decr;
+
+	ppc_md.find_end_of_memory = ppc4xx_find_end_of_memory;
+	ppc_md.setup_io_mappings = m4xx_map_io;
+
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+	ppc_md.progress = ppc4xx_progress;
+#endif
+#ifdef CONFIG_KGDB
+//	ppc_md.early_serial_map = early_uart_init;
+#endif
+#if defined(CONFIG_VT) && defined(CONFIG_PC_KEYBOARD)
+#if defined(CONFIG_REDWOOD_4) && defined(CONFIG_STB_KB)
+	redwood_irkb_init();
+#else
+	ppc_md.kbd_setkeycode = pckbd_setkeycode;
+	ppc_md.kbd_getkeycode = pckbd_getkeycode;
+	ppc_md.kbd_translate = pckbd_translate;
+	ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
+	ppc_md.kbd_leds = pckbd_leds;
+	ppc_md.kbd_init_hw = pckbd_init_hw;
+#endif
+#endif
+
+/*
+**   m8xx_setup.c, prep_setup.c use
+**     defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+*/
+#if defined (CONFIG_IDE)
+#if defined(CONFIG_BLK_DEV_IDEPCI)
+	ppc_ide_md.ide_init_hwif = ppc4xx_ide_init_hwif_ports;
+#elif defined (CONFIG_DMA_NONPCI)	/* ON board IDE */
+	ppc_ide_md.default_irq = nonpci_ide_default_irq;
+	ppc_ide_md.ide_init_hwif = nonpci_ide_init_hwif_ports;
+#endif
+#endif
+	board_init();
+
+	return;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/ppc8xx_pic.c linux-2.4.22-pre10/arch/ppc/kernel/ppc8xx_pic.c
--- linux-2.4.21/arch/ppc/kernel/ppc8xx_pic.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/ppc8xx_pic.c	2003-08-01 13:32:26.000000000 +0000
@@ -52,7 +52,7 @@
 		word = irq_nr >> 5;
 
 		ppc_cached_irq_mask[word] |= (1 << (31-bit));
-		((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = 
+		((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
 			ppc_cached_irq_mask[word];
 	}
 }
@@ -96,7 +96,7 @@
 	irq = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec >> 26;
 
 	/*
-	 * When we read the sivec without an interrupt to process, we will 
+	 * When we read the sivec without an interrupt to process, we will
 	 * get back SIU_LEVEL7.  In this case, return -1
 	 */
         if (irq == CPM_INTERRUPT)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/ppc_htab.c linux-2.4.22-pre10/arch/ppc/kernel/ppc_htab.c
--- linux-2.4.21/arch/ppc/kernel/ppc_htab.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/ppc_htab.c	2003-08-01 13:30:55.000000000 +0000
@@ -82,7 +82,7 @@
 	default:
 		return "unknown";
 	}
-}	
+}
 
 static char *pmc2_lookup(unsigned long mmcr0)
 {
@@ -101,7 +101,7 @@
 	default:
 		return "unknown";
 	}
-}	
+}
 
 /*
  * print some useful info about the hash table.  This function
@@ -177,7 +177,7 @@
 		if (!valid)
 			zombie_ptes++;
 	}
-	
+
 	n += sprintf( buffer + n,
 		      "PTE Hash Table Information\n"
 		      "Size\t\t: %luKb\n"
@@ -208,7 +208,7 @@
 		      primary_pteg_full, htab_evicts);
 return_string:
 #endif /* CONFIG_PPC_STD_MMU */
-	
+
 	n += sprintf( buffer + n,
 		      "Non-error misses: %lu\n"
 		      "Error misses\t: %lu\n",
@@ -244,7 +244,7 @@
 		if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) {
 			asm volatile ("mtspr %0, %3 \n\t"
 			    "mtspr %1, %3 \n\t"
-			    "mtspr %2, %3 \n\t"			    
+			    "mtspr %2, %3 \n\t"
 			    :: "i" (MMCR0), "i" (PMC1), "i" (PMC2), "r" (0));
 		}
 	}
@@ -295,7 +295,7 @@
 				"i" (PMC1),  "r" (0), "i"(PMC2) );
 		}
 	}
-	
+
 	/* PMC1 values */
 	if ( !strncmp( buffer, "dtlb", 4) )
 	{
@@ -310,7 +310,7 @@
 				:: "r" (tmp), "i" (MMCR0), "i" (MMCR0_PMC1_DTLB),
 				"i" (PMC1),  "r" (0) );
 		}
-	}	
+	}
 
 	if ( !strncmp( buffer, "ic miss", 7) )
 	{
@@ -325,7 +325,7 @@
 				:: "r" (tmp), "i" (MMCR0),
 				"i" (MMCR0_PMC1_ICACHEMISS), "i" (PMC1),  "r" (0));
 		}
-	}	
+	}
 
 	/* PMC2 values */
 	if ( !strncmp( buffer, "load miss time", 14) )
@@ -343,7 +343,7 @@
 			       "i" (PMC2),  "r" (0) );
 		}
 	}
-	
+
 	if ( !strncmp( buffer, "itlb", 4) )
 	{
 		if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) {
@@ -374,21 +374,21 @@
 			       : "i" (MMCR0), "i" (MMCR0_PMC2_DCACHEMISS),
 			       "i" (PMC2),  "r" (0) );
 		}
-	}	
-	
+	}
+
 
 	return count;
-	
+
 #if 0 /* resizing htab is a bit difficult right now -- Cort */
 	unsigned long size;
 	extern void reset_SDR1(void);
-	
+
 	/* only know how to set size right now */
 	if ( strncmp( buffer, "size ", 5) )
 		return -EINVAL;
 
 	size = simple_strtoul( &buffer[5], NULL, 10 );
-	
+
 	/* only allow to shrink */
 	if ( size >= Hash_size>>10 )
 		return -EINVAL;
@@ -396,11 +396,11 @@
 	/* minimum size of htab */
 	if ( size < 64 )
 		return -EINVAL;
-	
+
 	/* make sure it's a multiple of 64k */
 	if ( size % 64 )
 		return -EINVAL;
-	
+
 	printk("Hash table resize to %luk\n", size);
 	/*
 	 * We need to rehash all kernel entries for the new htab size.
@@ -416,7 +416,7 @@
 	flush_tlb_all();
 
 	reset_SDR1();
-#endif	
+#endif
 	return count;
 #else /* CONFIG_PPC_STD_MMU */
 	return 0;
@@ -441,18 +441,18 @@
     }
 }
 
+#define TMPBUFLEN 512
 int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
 		  void *buffer, size_t *lenp)
 {
 	int vleft, first=1, len, left, val;
-	#define TMPBUFLEN 256
 	char buf[TMPBUFLEN], *p;
 	static const char *sizestrings[4] = {
 		"2MB", "256KB", "512KB", "1MB"
 	};
 	static const char *clockstrings[8] = {
-		"clock disabled", "+1 clock", "+1.5 clock", "reserved(3)",
-		"+2 clock", "+2.5 clock", "+3 clock", "reserved(7)"
+		"clock disabled", "+1 clock", "+1.5 clock", "+3.5 clock",
+		"+2 clock", "+2.5 clock", "+3 clock", "+4 clock"
 	};
 	static const char *typestrings[4] = {
 		"flow-through burst SRAM", "reserved SRAM",
@@ -464,12 +464,12 @@
 
 	if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR))
 		return -EFAULT;
-	
+
 	if ( /*!table->maxlen ||*/ (filp->f_pos && !write)) {
 		*lenp = 0;
 		return 0;
 	}
-	
+
 	vleft = table->maxlen / sizeof(int);
 	left = *lenp;
 
@@ -508,24 +508,46 @@
 				*p++ = '\t';
 			val = _get_L2CR();
 			p += sprintf(p, "0x%08x: ", val);
-			p += sprintf(p, " %s", (val >> 31) & 1 ? "enabled" :
+			p += sprintf(p, " L2 %s", (val >> 31) & 1 ? "enabled" :
 				     	"disabled");
 			p += sprintf(p, ", %sparity", (val>>30)&1 ? "" : "no ");
-			p += sprintf(p, ", %s", sizestrings[(val >> 28) & 3]);
-			p += sprintf(p, ", %s", clockstrings[(val >> 25) & 7]);
-			p += sprintf(p, ", %s", typestrings[(val >> 23) & 2]);
-			p += sprintf(p, "%s", (val>>22)&1 ? ", data only" : "");
-			p += sprintf(p, "%s", (val>>20)&1 ? ", ZZ enabled": "");
-			p += sprintf(p, ", %s", (val>>19)&1 ? "write-through" :
-					"copy-back");
-			p += sprintf(p, "%s", (val>>18)&1 ? ", testing" : "");
-			p += sprintf(p, ", %sns hold",holdstrings[(val>>16)&3]);
-			p += sprintf(p, "%s", (val>>15)&1 ? ", DLL slow" : "");
-			p += sprintf(p, "%s", (val>>14)&1 ? ", diff clock" :"");
-			p += sprintf(p, "%s", (val>>13)&1 ? ", DLL bypass" :"");
-			
+
+			/* 75x & 74x0 have different L2CR than 745x */
+			if (!(cur_cpu_spec[0]->cpu_features &
+						CPU_FTR_SPEC7450)) {
+				p += sprintf(p, ", %s",
+					sizestrings[(val >> 28) & 3]);
+				p += sprintf(p, ", %s",
+					clockstrings[(val >> 25) & 7]);
+				p += sprintf(p, ", %s",
+					typestrings[(val >> 23) & 3]);
+				p += sprintf(p, "%s", (val>>22)&1 ?
+					", data only" : "");
+				p += sprintf(p, "%s", (val>>20)&1 ?
+					", ZZ enabled": "");
+				p += sprintf(p, ", %s", (val>>19)&1 ?
+					"write-through" : "copy-back");
+				p += sprintf(p, "%s", (val>>18)&1 ?
+					", testing" : "");
+				p += sprintf(p, ", %sns hold",
+					holdstrings[(val>>16)&3]);
+				p += sprintf(p, "%s", (val>>15)&1 ?
+					", DLL slow" : "");
+				p += sprintf(p, "%s", (val>>14)&1 ?
+					", diff clock" :"");
+				p += sprintf(p, "%s", (val>>13)&1 ?
+					", DLL bypass" :"");
+			} else { /* 745x */
+				p += sprintf(p, ", %sinstn only", (val>>20)&1 ?
+					"" : "no ");
+				p += sprintf(p, ", %sdata only", (val>>16)&1 ?
+					"" : "no ");
+				p += sprintf(p, ", %s replacement",
+					(val>>12)&1 ?  "secondary" : "default");
+			}
+
 			p += sprintf(p,"\n");
-			
+
 			len = strlen(buf);
 			if (len > left)
 				len = left;
@@ -559,3 +581,95 @@
 	filp->f_pos += *lenp;
 	return 0;
 }
+
+int proc_dol3crvec(ctl_table *table, int write, struct file *filp,
+		  void *buffer, size_t *lenp)
+{
+	int vleft, first=1, len, left, val;
+	char buf[TMPBUFLEN], *p;
+	static const char *clockstrings[8] = {
+		"+6 clock", "reserved(1)", "+2 clock", "+2.5 clock",
+		"+3 clock", "+3.5 clock", "+4 clock", "+5 clock"
+	};
+	static const char *clocksampstrings[4] = {
+		"2 clock", "3 clock", "4 clock", "5 clock"
+	};
+	static const char *pclocksampstrings[8] = {
+		"0 P-clock", "1 P-clock", "2 P-clock", "3 P-clock",
+		"4 P-clock", "5 P-clock", "reserved(6)", "reserved(7)"
+	};
+	static const char *typestrings[4] = {
+		"MSUG2 DDR SRAM",
+		"Pipelined synchronous late-write SRAM",
+		"Reserved", "PB2 SRAM"
+	};
+
+	if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR))
+		return -EFAULT;
+	if (write)
+		return -EFAULT;
+
+	if (filp->f_pos && !write) {
+		*lenp = 0;
+		return 0;
+	}
+
+	vleft = table->maxlen / sizeof(int);
+	left = *lenp;
+
+	for (; left; first=0) {
+		p = buf;
+		if (!first)
+			*p++ = '\t';
+		val = _get_L3CR();
+		p += sprintf(p, "0x%08x: ", val);
+		p += sprintf(p, " L3 %s", (val >> 31) & 1 ? "enabled" :
+			     	"disabled");
+		p += sprintf(p, ", %sdata parity", (val>>30)&1 ? "" :
+				"no ");
+		p += sprintf(p, ", %saddr parity", (val>>29)&1 ? "" :
+				"no ");
+		p += sprintf(p, ", %s", (val>>28)&1 ? "2MB" : "1MB");
+		p += sprintf(p, ", clocks %s", (val>>27)&1 ? "enabled" :
+				"disabled");
+		p += sprintf(p, ", %s", clockstrings[(val >> 23) & 7]);
+		p += sprintf(p, ", %sinstn only", (val>>22)&1 ? "" :
+				"no ");
+		p += sprintf(p, ", %ssample point override",
+				(val>>18)&1 ? "" : "no ");
+		p += sprintf(p, ", %s sample point",
+				clocksampstrings[(val>>16)&3]);
+		p += sprintf(p, ", %s sample point",
+				pclocksampstrings[(val>>13)&7]);
+		p += sprintf(p, ", %s replacement", (val>>12)&1 ?
+				"secondary" : "default");
+		p += sprintf(p, ", %s", typestrings[(val >> 8) & 3]);
+		p += sprintf(p, ", %sclock cntl", (val>>7)&1 ? "" :
+				"no ");
+		p += sprintf(p, ", %sdata only", (val>>6)&1 ? "" :
+				"no ");
+		p += sprintf(p, ", private mem %s", (val>>2)&1 ?
+				"enabled" : "disabled");
+		p += sprintf(p, ", %sprivate mem", val&1 ? "2MB " :
+				"1MB ");
+		p += sprintf(p,"\n");
+
+		len = strlen(buf);
+		if (len > left)
+			len = left;
+		if(copy_to_user(buffer, buf, len))
+			return -EFAULT;
+		left -= len;
+		buffer += len;
+		break;
+	}
+
+	if (!write && !first && left) {
+		if(put_user('\n', (char *) buffer))
+			return -EFAULT;
+		left--, buffer++;
+	}
+	*lenp -= left;
+	filp->f_pos += *lenp;
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/ppc_ksyms.c linux-2.4.22-pre10/arch/ppc/kernel/ppc_ksyms.c
--- linux-2.4.21/arch/ppc/kernel/ppc_ksyms.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/ppc_ksyms.c	2003-08-01 13:34:31.000000000 +0000
@@ -353,6 +353,10 @@
 EXPORT_SYMBOL(next_mmu_context);
 EXPORT_SYMBOL(set_context);
 EXPORT_SYMBOL(handle_mm_fault); /* For MOL */
+#ifdef CONFIG_SMP
+extern int *hash_table_lock;
+EXPORT_SYMBOL_NOVERS(hash_table_lock); /* For MOL */
+#endif
 EXPORT_SYMBOL_NOVERS(disarm_decr);
 #ifdef CONFIG_PPC_STD_MMU
 EXPORT_SYMBOL(flush_hash_page); /* For MOL */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/pplus_common.c linux-2.4.22-pre10/arch/ppc/kernel/pplus_common.c
--- linux-2.4.21/arch/ppc/kernel/pplus_common.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/pplus_common.c	2003-08-01 13:31:52.000000000 +0000
@@ -0,0 +1,317 @@
+/*
+ * arch/ppc/kernel/pplus_common.c
+ *
+ * Common Motorola PowerPlus Platform--really Falcon/Raven or HAWK.
+ *
+ * Author: Mark A. Greer
+ *         mgreer@mvista.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/pci-bridge.h>
+#include <asm/open_pic.h>
+#include <asm/pplus.h>
+
+/*
+ * The Falcon/Raven and HAWK has 4 sets of registers:
+ *   1) PPC Registers which define the mappings from PPC bus to PCI bus,
+ *      etc.
+ *   2) PCI Registers which define the mappings from PCI bus to PPC bus and the
+ *      MPIC base address.
+ *   3) MPIC registers.
+ *   4) System Memory Controller (SMC) registers.
+ */
+
+/*
+ * Initialize the Motorola MCG Raven or HAWK host bridge.
+ *
+ * This means setting up the PPC bus to PCI memory and I/O space mappings,
+ * setting the PCI memory space address of the MPIC (mapped straight
+ * through), and ioremap'ing the mpic registers.
+ * This routine will set the PCI_CONFIG_ADDR or PCI_CONFIG_DATA
+ * addresses based on the PCI I/O address that is passed in.
+ * 'OpenPIC_Addr' will be set correctly by this routine.
+ */
+int __init
+pplus_init(struct pci_controller *hose,
+	     uint ppc_reg_base,
+	     ulong processor_pci_mem_start,
+	     ulong processor_pci_mem_end,
+	     ulong processor_pci_io_start,
+	     ulong processor_pci_io_end,
+	     ulong processor_mpic_base)
+{
+	uint		addr, offset;
+
+	/*
+	 * Some sanity checks...
+	 */
+	if (((processor_pci_mem_start&0xffff0000) != processor_pci_mem_start) ||
+	    ((processor_pci_io_start &0xffff0000) != processor_pci_io_start)) {
+		printk("pplus_init: %s\n",
+			"PPC to PCI mappings must start on 64 KB boundaries");
+		return -1;
+	}
+
+	if (((processor_pci_mem_end  &0x0000ffff) != 0x0000ffff) ||
+	    ((processor_pci_io_end   &0x0000ffff) != 0x0000ffff)) {
+		printk("pplus_init: PPC to PCI mappings %s\n",
+			"must end just before a 64 KB boundaries");
+		return -1;
+	}
+
+	if (((processor_pci_mem_end - processor_pci_mem_start) !=
+	     (hose->mem_space.end - hose->mem_space.start)) ||
+	    ((processor_pci_io_end - processor_pci_io_start) !=
+	     (hose->io_space.end - hose->io_space.start))) {
+		printk("pplus_init: %s\n",
+			"PPC and PCI memory or I/O space sizes don't match");
+		return -1;
+	}
+
+	if ((processor_mpic_base & 0xfffc0000) != processor_mpic_base) {
+		printk("pplus_init: %s\n",
+			"MPIC address must start on 256 MB boundary");
+		return -1;
+	}
+
+	if ((pci_dram_offset & 0xffff0000) != pci_dram_offset) {
+		printk("pplus_init: %s\n",
+			"pci_dram_offset must be multiple of 64 KB");
+		return -1;
+	}
+
+	/*
+	 * Disable previous PPC->PCI mappings.
+	 */
+	out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF0_OFF), 0x00000000);
+	out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF1_OFF), 0x00000000);
+	out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF2_OFF), 0x00000000);
+	out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF3_OFF), 0x00000000);
+
+	/*
+	 * Program the XSADD/XSOFF registers to set up the PCI Mem & I/O
+	 * space mappings.  These are the mappings going from the processor to
+	 * the PCI bus.
+	 *
+	 * Note: Don't need to 'AND' start/end addresses with 0xffff0000
+	 *	 because sanity check above ensures that they are properly
+	 *	 aligned.
+	 */
+
+	/* Set up PPC->PCI Mem mapping */
+	addr = processor_pci_mem_start | (processor_pci_mem_end >> 16);
+	offset = (hose->mem_space.start - processor_pci_mem_start) | 0xd2;
+	out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSADD0_OFF), addr);
+	out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF0_OFF), offset);
+
+	/* Set up PPC->MPIC mapping on the bridge */
+	addr = processor_mpic_base |
+	        (((processor_mpic_base + PPLUS_MPIC_SIZE) >> 16) - 1);
+	offset = 0xc2; /* No write posting for this PCI Mem space */
+	out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSADD1_OFF), addr);
+	out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF1_OFF), offset);
+
+	/* Set up PPC->PCI I/O mapping -- Contiguous I/O space */
+	addr = processor_pci_io_start | (processor_pci_io_end >> 16);
+	offset = (hose->io_space.start - processor_pci_io_start) | 0xc0;
+	out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSADD3_OFF), addr);
+	out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF3_OFF), offset);
+
+	hose->io_base_virt = (void *)ioremap(processor_pci_io_start,
+			(processor_pci_io_end - processor_pci_io_start + 1));
+
+	/*
+	 * Set up the indirect method of accessing PCI config space.
+	 * The PCI config addr/data pair based on start addr of PCI I/O space.
+	 */
+	setup_indirect_pci(hose,
+			   processor_pci_io_start + PPLUS_PCI_CONFIG_ADDR_OFF,
+			   processor_pci_io_start + PPLUS_PCI_CONFIG_DATA_OFF);
+
+	/*
+	 * Disable previous PCI->PPC mappings.
+	 */
+
+	/* XXXX Put in mappings from PCI bus to processor bus XXXX */
+
+	/*
+	 * Disable MPIC response to PCI I/O space (BAR 0).
+	 * Make MPIC respond to PCI Mem space at specified address.
+	 * (BAR 1).
+	 */
+	early_write_config_dword(hose,
+			         0,
+			         PCI_DEVFN(0,0),
+			         PCI_BASE_ADDRESS_0,
+			         0x00000000 | 0x1);
+
+	early_write_config_dword(hose,
+			         0,
+			         PCI_DEVFN(0,0),
+			         PCI_BASE_ADDRESS_1,
+			         processor_mpic_base | 0x0);
+
+	/* Map MPIC into vitual memory */
+	OpenPIC_Addr = ioremap(processor_mpic_base, PPLUS_MPIC_SIZE);
+
+	return 0;
+}
+
+/*
+ * Find the amount of RAM present.
+ * This assumes that PPCBug has initialized the memory controller (SMC)
+ * on the Falcon/HAWK correctly (i.e., it does no sanity checking).
+ * It also assumes that the memory base registers are set to configure the
+ * memory as contigous starting with "RAM A BASE", "RAM B BASE", etc.
+ * however, RAM base registers can be skipped (e.g. A, B, C are set,
+ * D is skipped but E is set is okay).
+ */
+#define	MB	(1024*1024)
+
+static uint reg_offset_table[] __initdata = {
+	PPLUS_SMC_RAM_A_SIZE_REG_OFF,
+	PPLUS_SMC_RAM_B_SIZE_REG_OFF,
+	PPLUS_SMC_RAM_C_SIZE_REG_OFF,
+	PPLUS_SMC_RAM_D_SIZE_REG_OFF,
+	PPLUS_SMC_RAM_E_SIZE_REG_OFF,
+	PPLUS_SMC_RAM_F_SIZE_REG_OFF,
+	PPLUS_SMC_RAM_G_SIZE_REG_OFF,
+	PPLUS_SMC_RAM_H_SIZE_REG_OFF
+};
+
+static uint falcon_size_table[] __initdata = {
+	   0 * MB, /* 0 ==>    0 MB */
+	  16 * MB, /* 1 ==>   16 MB */
+	  32 * MB, /* 2 ==>   32 MB */
+	  64 * MB, /* 3 ==>   64 MB */
+	 128 * MB, /* 4 ==>  128 MB */
+	 256 * MB, /* 5 ==>  256 MB */
+        1024 * MB, /* 6 ==> 1024 MB (1 GB) */
+};
+
+static uint hawk_size_table[] __initdata = {
+	  0 * MB, /* 0 ==>    0 MB */
+	 32 * MB, /* 1 ==>   32 MB */
+	 64 * MB, /* 2 ==>   64 MB */
+	 64 * MB, /* 3 ==>   64 MB */
+	128 * MB, /* 4 ==>  128 MB */
+	128 * MB, /* 5 ==>  128 MB */
+	128 * MB, /* 6 ==>  128 MB */
+	256 * MB, /* 7 ==>  256 MB */
+	256 * MB, /* 8 ==>  256 MB */
+	512 * MB, /* 9 ==>  512 MB */
+};
+
+/*
+ * *** WARNING: You MUST have a BAT set up to map in the SMC regs ***
+ *
+ * Read the memory controller's registers to determine the amount of system
+ * memory.  Assumes that the memory controller registers are already mapped
+ * into virtual memory--too early to use ioremap().
+ */
+unsigned long __init
+pplus_get_mem_size(uint smc_base)
+{
+	unsigned long	total;
+	int		i, size_table_entries, reg_limit;
+	uint		vend_dev_id;
+	uint		*size_table;
+	u_char		val;
+
+
+	vend_dev_id = in_be32((uint *)smc_base + PCI_VENDOR_ID);
+
+	if (((vend_dev_id & 0xffff0000) >> 16) != PCI_VENDOR_ID_MOTOROLA) {
+		printk("pplus_get_mem_size: %s (0x%x)\n",
+			"Not a Motorola Memory Controller", vend_dev_id);
+		return 0;
+	}
+
+	vend_dev_id &= 0x0000ffff;
+
+	if (vend_dev_id == PCI_DEVICE_ID_MOTOROLA_FALCON) {
+		size_table = falcon_size_table;
+		size_table_entries = sizeof(falcon_size_table) /
+				     sizeof(falcon_size_table[0]);
+
+		reg_limit = PPLUS_FALCON_SMC_REG_COUNT;
+	}
+	else if (vend_dev_id == PCI_DEVICE_ID_MOTOROLA_HAWK) {
+		size_table = hawk_size_table;
+		size_table_entries = sizeof(hawk_size_table) /
+				     sizeof(hawk_size_table[0]);
+		reg_limit = PPLUS_HAWK_SMC_REG_COUNT;
+	}
+	else {
+		printk("pplus_get_mem_size: %s (0x%x)\n",
+			"Not a Falcon or HAWK", vend_dev_id);
+		return 0;
+	}
+
+	total = 0;
+
+	/* Check every reg because PPCBug may skip some */
+	for (i=0; i<reg_limit; i++) {
+		val = in_8((u_char *)(smc_base + reg_offset_table[i]));
+
+		if (val & 0x80) {	/* If enabled */
+			val &= 0x0f;
+
+			/* Don't go past end of size_table */
+			if (val < size_table_entries) {
+				total += size_table[val];
+			}
+			else {	/* Register not set correctly */
+				break;
+			}
+		}
+	}
+
+	return total;
+}
+
+int __init
+pplus_mpic_init(unsigned int pci_mem_offset)
+{
+	unsigned short	devid;
+	unsigned int	pci_membase;
+
+	/* Check the first PCI device to see if it is a Raven or Hawk. */
+	early_read_config_word(0, 0, 0, PCI_DEVICE_ID, &devid);
+
+	switch (devid) {
+	case PCI_DEVICE_ID_MOTOROLA_RAVEN:
+	case PCI_DEVICE_ID_MOTOROLA_HAWK:
+		break;
+	default:
+		OpenPIC_Addr = NULL;
+		return 1;
+	}
+
+	/* Read the memory base register. */
+	early_read_config_dword(0, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase);
+
+	if (pci_membase == 0) {
+		OpenPIC_Addr = NULL;
+		return 1;
+	}
+
+	/* Map the MPIC registers to virtual memory. */
+	OpenPIC_Addr = ioremap(pci_membase + pci_mem_offset, 0x22000);
+
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/prep_nvram.c linux-2.4.22-pre10/arch/ppc/kernel/prep_nvram.c
--- linux-2.4.21/arch/ppc/kernel/prep_nvram.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/prep_nvram.c	2003-08-01 13:33:18.000000000 +0000
@@ -25,7 +25,7 @@
 	outb(addr>>8, PREP_NVRAM_AS1);
 	return inb(PREP_NVRAM_DATA);
 }
-  
+
 void __prep prep_nvram_write_val(int           addr,
 			  unsigned char val)
 {
@@ -33,7 +33,7 @@
 	outb(addr>>8, PREP_NVRAM_AS1);
    	outb(val, PREP_NVRAM_DATA);
 }
-  
+
 void __init init_prep_nvram(void)
 {
 	unsigned char *nvp;
@@ -51,7 +51,7 @@
 		*nvp = ppc_md.nvram_read_val(i);
 		nvp++;
 	}
-	
+
 	/*
 	 * The PReP NvRAM may be any size so read in the header to
 	 * determine how much we must read in order to get the complete
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/process.c linux-2.4.22-pre10/arch/ppc/kernel/process.c
--- linux-2.4.21/arch/ppc/kernel/process.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/process.c	2003-08-01 13:33:15.000000000 +0000
@@ -7,7 +7,7 @@
  *  Updated and modified by Cort Dougan (cort@cs.nmt.edu) and
  *  Paul Mackerras (paulus@cs.anu.edu.au)
  *
- *  PowerPC version 
+ *  PowerPC version
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
  *  This program is free software; you can redistribute it and/or
@@ -80,7 +80,7 @@
 	unsigned long tsk_top = task_top(tsk);
 	int ret = 0;
 
-#if 0	
+#if 0
 	/* check thread magic */
 	if ( tsk->thread.magic != THREAD_MAGIC )
 	{
@@ -91,7 +91,7 @@
 
 	if ( !tsk )
 		printk("check_stack(): tsk bad tsk %p\n",tsk);
-	
+
 	/* check if stored ksp is bad */
 	if ( (tsk->thread.ksp > stack_top) || (tsk->thread.ksp < tsk_top) )
 	{
@@ -101,7 +101,7 @@
 		       tsk_top, tsk->thread.ksp, stack_top);
 		ret |= 2;
 	}
-	
+
 	/* check if stack ptr RIGHT NOW is bad */
 	if ( (tsk == current) && ((_get_SP() > stack_top ) || (_get_SP() < tsk_top)) )
 	{
@@ -112,7 +112,7 @@
 		ret |= 4;
 	}
 
-#if 0	
+#if 0
 	/* check amount of free stack */
 	for ( i = (unsigned long *)task_top(tsk) ; i < kernel_stack_top(tsk) ; i++ )
 	{
@@ -147,7 +147,7 @@
 	return 1;
 }
 
-void 
+void
 enable_kernel_altivec(void)
 {
 #ifdef CONFIG_SMP
@@ -189,7 +189,7 @@
 {
 	struct thread_struct *new_thread, *old_thread;
 	unsigned long s;
-	
+
 	__save_flags(s);
 	__cli();
 #if CHECK_STACK
@@ -201,7 +201,7 @@
 	/* avoid complexity of lazy save/restore of fpu
 	 * by just saving it every time we switch out if
 	 * this task used the fpu during the last quantum.
-	 * 
+	 *
 	 * If it tries to use the fpu again, it'll trap and
 	 * reload its fp regs.  So we don't have to do a restore
 	 * every switch, just a save.
@@ -209,7 +209,7 @@
 	 */
 	if ( prev->thread.regs && (prev->thread.regs->msr & MSR_FP) )
 		giveup_fpu(prev);
-#ifdef CONFIG_ALTIVEC	
+#ifdef CONFIG_ALTIVEC
 	/*
 	 * If the previous thread used altivec in the last quantum
 	 * (thus changing altivec regs) then save them.
@@ -223,7 +223,7 @@
 	 */
 	if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)))
 		giveup_altivec(prev);
-#endif /* CONFIG_ALTIVEC */	
+#endif /* CONFIG_ALTIVEC */
 #endif /* CONFIG_SMP */
 
 	current_set[smp_processor_id()] = new;
@@ -250,27 +250,40 @@
 	       regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
 	       regs->msr&MSR_IR ? 1 : 0,
 	       regs->msr&MSR_DR ? 1 : 0);
+#ifdef CONFIG_4xx
+	/*
+	 * TRAP 0x800 is the hijacked FPU unavailable exception vector
+	 * on 40x used to implement the heavyweight data access
+	 * functionality.  It is an emulated value (like all trap
+	 * vectors) on 440.
+	 */
+	if (regs->trap == 0x300 || regs->trap == 0x600 || regs->trap == 0x800)
+		printk("DEAR: %08lX, ESR: %08lX\n", regs->dar, regs->dsisr);
+#else
 	if (regs->trap == 0x300 || regs->trap == 0x600)
 		printk("DAR: %08lX, DSISR: %08lX\n", regs->dar, regs->dsisr);
+#endif
 	printk("TASK = %p[%d] '%s' ",
 	       current, current->pid, current->comm);
 	printk("Last syscall: %ld ", current->thread.last_syscall);
 	printk("\nlast math %p last altivec %p", last_task_used_math,
 	       last_task_used_altivec);
 
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) && defined(DCRN_PLB0_BEAR)
 	printk("\nPLB0: bear= 0x%8.8x acr=   0x%8.8x besr=  0x%8.8x\n",
-	    mfdcr(DCRN_POB0_BEAR), mfdcr(DCRN_PLB0_ACR),
+	    mfdcr(DCRN_PLB0_BEAR), mfdcr(DCRN_PLB0_ACR),
 	    mfdcr(DCRN_PLB0_BESR));
+#endif
+#if defined(CONFIG_4xx) && defined(DCRN_POB0_BEAR)
 	printk("PLB0 to OPB: bear= 0x%8.8x besr0= 0x%8.8x besr1= 0x%8.8x\n",
-	    mfdcr(DCRN_PLB0_BEAR), mfdcr(DCRN_POB0_BESR0),
+	    mfdcr(DCRN_POB0_BEAR), mfdcr(DCRN_POB0_BESR0),
 	    mfdcr(DCRN_POB0_BESR1));
 #endif
-	
+
 #ifdef CONFIG_SMP
 	printk(" CPU: %d", current->processor);
 #endif /* CONFIG_SMP */
-	
+
 	printk("\n");
 	for (i = 0;  i < 32;  i++)
 	{
@@ -475,7 +488,7 @@
 #ifdef CONFIG_ALTIVEC
 	if (regs->msr & MSR_VEC)
 		giveup_altivec(current);
-#endif /* CONFIG_ALTIVEC */ 
+#endif /* CONFIG_ALTIVEC */
 	error = do_execve(filename, (char **) a1, (char **) a2, regs);
 	if (error == 0)
 		current->ptrace &= ~PT_DTRACE;
@@ -573,7 +586,7 @@
 		return;
 	}
 
-#if 0	
+#if 0
 	if ( have_of )
 	{
 		prom_print(s);
@@ -600,7 +613,7 @@
 				y = 0;
 			}
 		} else {
-			vidmem [ ( x + cols * y ) * 2 ] = c; 
+			vidmem [ ( x + cols * y ) * 2 ] = c;
 			if ( ++x >= cols ) {
 				x = 0;
 				if ( ++y >= lines ) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/prom.c linux-2.4.22-pre10/arch/ppc/kernel/prom.c
--- linux-2.4.21/arch/ppc/kernel/prom.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/prom.c	2003-08-01 13:31:01.000000000 +0000
@@ -1000,8 +1000,8 @@
 {
 	unsigned long mask;
 	int i;
-	
-	/* Check this one */ 
+
+	/* Check this one */
 	mask = bus_space_to_resource_flags(range->space);
 	for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
 		if ((pdev->resource[i].flags & mask) == mask &&
@@ -1049,7 +1049,7 @@
 		parent = &ioport_resource;
 	else
 		goto fail;
-		
+
 	/* Find a PCI parent if any */
 	nd = node;
 	pcidev = NULL;
@@ -1104,7 +1104,7 @@
 		parent = &ioport_resource;
 	else
 		return -EINVAL;
-		
+
 	/* Find a PCI parent if any */
 	nd = node;
 	pcidev = NULL;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/ptrace.c linux-2.4.22-pre10/arch/ppc/kernel/ptrace.c
--- linux-2.4.21/arch/ppc/kernel/ptrace.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/ptrace.c	2003-08-01 13:32:01.000000000 +0000
@@ -33,7 +33,11 @@
 /*
  * Set of msr bits that gdb can change on behalf of a process.
  */
+#if defined(CONFIG_4xx)
+#define MSR_DEBUGCHANGE	(0)
+#else
 #define MSR_DEBUGCHANGE	(MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
+#endif
 
 /*
  * does not yet catch signals sent when the child dies.
@@ -108,12 +112,12 @@
 
 	/* copy AltiVec registers VR[0] .. VR[31] */
 	for (i = 0; i < 32; i++)
-		for (j = 0; j < 4; j++, data++) 
+		for (j = 0; j < 4; j++, data++)
 			if (__get_user(task->thread.vr[i].u[j], data))
 				return -EFAULT;
 
 	/* copy VSCR */
-	for (i = 0; i < 4; i++, data++) 
+	for (i = 0; i < 4; i++, data++)
 		if (__get_user(task->thread.vscr.u[i], data))
 			return -EFAULT;
 
@@ -129,18 +133,27 @@
 set_single_step(struct task_struct *task)
 {
 	struct pt_regs *regs = task->thread.regs;
-
+#if defined(CONFIG_4xx)
+	regs->msr |= MSR_DE;
+	task->thread.dbcr0 |=  (DBCR0_IDM | DBCR0_IC);
+#else
 	if (regs != NULL)
 		regs->msr |= MSR_SE;
+#endif
+
 }
 
 static inline void
 clear_single_step(struct task_struct *task)
 {
 	struct pt_regs *regs = task->thread.regs;
-
+#if defined(CONFIG_4xx)
+	regs->msr &= ~MSR_DE;
+	task->thread.dbcr0 &=  ~DBCR0_IC;
+#else
 	if (regs != NULL)
 		regs->msr &= ~MSR_SE;
+#endif
 }
 
 /*
@@ -193,7 +206,7 @@
 
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
-	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
 	case PTRACE_PEEKDATA: {
 		unsigned long tmp;
 		int copied;
@@ -275,14 +288,20 @@
 		child->exit_code = data;
 		/* make sure the single step bit is not set. */
 		clear_single_step(child);
+#ifdef CONFIG_4xx
+		/* ...but traps may be set, so catch those....
+		*/
+		child->thread.regs->msr   |= MSR_DE;
+		child->thread.dbcr0 |= (DBCR0_IDM | DBCR0_TDE);
+#endif
 		wake_up_process(child);
 		ret = 0;
 		break;
 	}
 
 /*
- * make the child exit.  Best I can do is send it a sigkill. 
- * perhaps it should be put in the status that it wants to 
+ * make the child exit.  Best I can do is send it a sigkill.
+ * perhaps it should be put in the status that it wants to
  * exit.
  */
 	case PTRACE_KILL: {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/setup.c linux-2.4.22-pre10/arch/ppc/kernel/setup.c
--- linux-2.4.21/arch/ppc/kernel/setup.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/setup.c	2003-08-01 13:34:40.000000000 +0000
@@ -54,7 +54,7 @@
 unsigned long sysmap_size;
 
 /* Used with the BI_MEMSIZE bootinfo parameter to store the memory
-   size value reported by the boot loader. */ 
+   size value reported by the boot loader. */
 unsigned long boot_mem_size;
 
 unsigned long ISA_DMA_THRESHOLD;
@@ -89,7 +89,7 @@
 int icache_bsize;
 int ucache_bsize;
 
-#ifdef CONFIG_VGA_CONSOLE
+#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB)
 struct screen_info screen_info = {
 	0, 25,			/* orig-x, orig-y */
 	0,			/* unused */
@@ -101,18 +101,18 @@
 	1,			/* orig-video-isVGA */
 	16			/* orig-video-points */
 };
-#endif /* CONFIG_VGA_CONSOLE */
+#endif /* CONFIG_VGA_CONSOLE || CONFIG_FB */
 
 void machine_restart(char *cmd)
 {
 	ppc_md.restart(cmd);
 }
-  
+
 void machine_power_off(void)
 {
 	ppc_md.power_off();
 }
-  
+
 void machine_halt(void)
 {
 	ppc_md.halt();
@@ -207,7 +207,7 @@
 		break;
 	}
 
-	seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", 
+	seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n",
 		   maj, min, PVR_VER(pvr), PVR_REV(pvr));
 
 	seq_printf(m, "bogomips\t: %lu.%02lu\n",
@@ -304,7 +304,7 @@
 {
 	char *model;
 	struct device_node *root;
-			
+
 	/* ask the OF info if we're a chrp or pmac */
 	root = find_path_device("/");
 	if (root != 0) {
@@ -333,7 +333,7 @@
 		btext_clearscreen();
 		btext_welcome();
 	}
-#endif	
+#endif
 
 	parse_bootinfo(find_bootinfo());
 
@@ -370,7 +370,7 @@
 	 * bootargs property of the /chosen node.
 	 * If an initial ramdisk is present, r3 and r4
 	 * are used for initrd_start and initrd_size,
-	 * otherwise they contain 0xdeadbeef.  
+	 * otherwise they contain 0xdeadbeef.
 	 */
 	if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) {
 		cmd_line[0] = 0;
@@ -393,7 +393,7 @@
 	} else {
 		struct device_node *chosen;
 		char *p;
-			
+
 #ifdef CONFIG_BLK_DEV_INITRD
 		if (r3 && r4 && r4 != 0xdeadbeef) {
 			if (r3 < KERNELBASE)
@@ -454,7 +454,7 @@
 		ulong *data = rec->data;
 		switch (rec->tag) {
 		case BI_CMD_LINE:
-			memcpy(cmd_line, (void *)data, rec->size - 
+			memcpy(cmd_line, (void *)data, rec->size -
 					sizeof(struct bi_record));
 			break;
 		case BI_SYSMAP:
@@ -531,7 +531,7 @@
 {
 	/* clear the progress line */
 	if ( ppc_md.progress ) ppc_md.progress("             ", 0xffff);
-	
+
 	if (ppc_md.init != NULL) {
 		ppc_md.init();
 	}
@@ -596,7 +596,7 @@
 	init_mm.end_code = (unsigned long) _etext;
 	init_mm.end_data = (unsigned long) _edata;
 	init_mm.brk = (unsigned long) klimit;
-	
+
 	/* Save unparsed command line copy for /proc/cmdline */
 	strcpy(saved_command_line, cmd_line);
 	*cmdline_p = cmd_line;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/signal.c linux-2.4.22-pre10/arch/ppc/kernel/signal.c
--- linux-2.4.21/arch/ppc/kernel/signal.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/signal.c	2003-08-01 13:33:07.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/ppc/kernel/signal.c
  *
- *  PowerPC version 
+ *  PowerPC version
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
  *  Derived from "arch/i386/kernel/signal.c"
@@ -40,7 +40,7 @@
 
 #define GP_REGS_SIZE	MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs))
 
-/* 
+/*
  * These are the flags in the MSR that the user is allowed to change
  * by modifying the saved value of the MSR on the stack.  SE and BE
  * should not be in this list since gdb may want to change these.  I.e,
@@ -117,7 +117,7 @@
 			 * do_signal() has set R3 to the signal number (the
 			 * first argument of the signal handler), so don't
 			 * overwrite that with EINTR !
-			 * In the other cases, do_signal() doesn't touch 
+			 * In the other cases, do_signal() doesn't touch
 			 * R3, so it's still set to -EINTR (see above).
 			 */
 			return regs->gpr[3];
@@ -163,7 +163,7 @@
 	return do_sigaltstack(uss, uoss, regs->gpr[1]);
 }
 
-int 
+int
 sys_sigaction(int sig, const struct old_sigaction *act,
 	      struct old_sigaction *oact)
 {
@@ -261,8 +261,8 @@
 	rt_sf++;			/* Look at next rt_sigframe */
 	if (rt_sf == (struct rt_sigframe *)(sigctx.regs)) {
 		/* Last stacked signal - restore registers -
-		 * sigctx is initialized to point to the 
-		 * preamble frame (where registers are stored) 
+		 * sigctx is initialized to point to the
+		 * preamble frame (where registers are stored)
 		 * see handle_signal()
 		 */
 		sr = (struct sigregs *) sigctx.regs;
@@ -322,7 +322,7 @@
 	    || __copy_to_user(&frame->fp_regs, current->thread.fpr,
 			      ELF_NFPREG * sizeof(double))
 	/* Set up to return from user space.
-	   It calls the sc exception at offset 0x9999 
+	   It calls the sc exception at offset 0x9999
 	   for sys_rt_sigreturn().
 	*/
 	    || __put_user(0x38006666UL, &frame->tramp[0])	/* li r0,0x6666 */
@@ -422,7 +422,7 @@
 
 badframe:
 	do_exit(SIGSEGV);
-}	
+}
 
 /*
  * Set up a signal frame.
@@ -500,7 +500,7 @@
 		    || __put_user(0, &rt_sf->uc.uc_flags)
 		    || __put_user(0, &rt_sf->uc.uc_link)
 		    || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
-		    || __put_user(sas_ss_flags(regs->gpr[1]), 
+		    || __put_user(sas_ss_flags(regs->gpr[1]),
 				  &rt_sf->uc.uc_stack.ss_flags)
 		    || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
 		    || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset))
@@ -514,7 +514,7 @@
 		sc = (struct sigcontext_struct *) *newspp;
 		if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
 			goto badframe;
-		
+
 		if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
 		    || __put_user(oldset->sig[0], &sc->oldmask)
 #if _NSIG_WORDS > 1
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/smp.c linux-2.4.22-pre10/arch/ppc/kernel/smp.c
--- linux-2.4.21/arch/ppc/kernel/smp.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/smp.c	2003-08-01 13:34:40.000000000 +0000
@@ -67,7 +67,7 @@
 extern void __save_cpu_setup(void);
 
 /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
- * 
+ *
  * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up
  * in /proc/interrupts will be wrong!!! --Troy */
 #define PPC_MSG_CALL_FUNCTION	0
@@ -75,7 +75,7 @@
 #define PPC_MSG_INVALIDATE_TLB	2
 #define PPC_MSG_XMON_BREAK	3
 
-static inline void 
+static inline void
 smp_message_pass(int target, int msg, unsigned long data, int wait)
 {
 	if (smp_ops){
@@ -84,7 +84,7 @@
 	}
 }
 
-/* 
+/*
  * Common functions
  */
 void smp_local_timer_interrupt(struct pt_regs * regs)
@@ -100,12 +100,12 @@
 void smp_message_recv(int msg, struct pt_regs *regs)
 {
 	atomic_inc(&ipi_recv);
-	
+
 	switch( msg ) {
 	case PPC_MSG_CALL_FUNCTION:
 		smp_call_function_interrupt();
 		break;
-	case PPC_MSG_RESCHEDULE: 
+	case PPC_MSG_RESCHEDULE:
 		current->need_resched = 1;
 		break;
 	case PPC_MSG_INVALIDATE_TLB:
@@ -332,7 +332,7 @@
 
 	/* Backup CPU 0 state */
 	__save_cpu_setup();
-	
+
 	/*
 	 * only check for cpus we know exist.  We keep the callin map
 	 * with cpus at the bottom -- Cort
@@ -342,7 +342,7 @@
 	for (i = 1; i < cpu_nr; i++) {
 		int c;
 		struct pt_regs regs;
-		
+
 		/* create a process for the processor */
 		/* only regs.msr is actually used, and 0 is OK for it */
 		memset(&regs, 0, sizeof(struct pt_regs));
@@ -368,7 +368,7 @@
 
 		/* wake up cpus */
 		smp_ops->kick_cpu(i);
-		
+
 		/*
 		 * wait to see if the cpu made a callin (is actually up).
 		 * use this value that I found through experimentation.
@@ -376,7 +376,7 @@
 		 */
 		for ( c = 10000; c && !cpu_callin_map[i] ; c-- )
 			udelay(100);
-		
+
 		if ( cpu_callin_map[i] )
 		{
 			char buf[32];
@@ -394,7 +394,7 @@
 
 	/* Setup CPU 0 last (important) */
 	smp_ops->setup_cpu(0);
-	
+
 	if (smp_num_cpus < 2)
 		smp_tb_synchronized = 1;
 }
@@ -497,7 +497,7 @@
 	 */
 	if (!smp_tb_synchronized && smp_num_cpus == 2) {
 		unsigned long flags;
-		__save_and_cli(flags);	
+		__save_and_cli(flags);
 		smp_software_tb_sync(0);
 		__restore_flags(flags);
 	}
@@ -506,14 +506,14 @@
 void __init smp_callin(void)
 {
 	int cpu = current->processor;
-	
+
         smp_store_cpu_info(cpu);
 	smp_ops->setup_cpu(cpu);
 	set_dec(tb_ticks_per_jiffy);
 	cpu_online_map |= 1UL << cpu;
 	mb();
 	cpu_callin_map[cpu] = 1;
-	
+
 	while(!smp_commenced)
 		barrier();
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/softemu8xx.c linux-2.4.22-pre10/arch/ppc/kernel/softemu8xx.c
--- linux-2.4.21/arch/ppc/kernel/softemu8xx.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/softemu8xx.c	2003-08-01 13:33:31.000000000 +0000
@@ -82,7 +82,7 @@
 		if (copy_from_user(ip, ea, sizeof(double)))
 			retval = -EFAULT;
 		break;
-		
+
 	case LFDU:
 		if (copy_from_user(ip, ea, sizeof(double)))
 			retval = -EFAULT;
@@ -137,7 +137,7 @@
 			printk("Kernel VA for NIP 0x%p ", __va(pa));
 			print_8xx_pte(current->mm, (unsigned long)__va(pa));
 		}
-		
+
 	}
 
 	if (retval == 0)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/syscalls.c linux-2.4.22-pre10/arch/ppc/kernel/syscalls.c
--- linux-2.4.21/arch/ppc/kernel/syscalls.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/syscalls.c	2003-08-01 13:34:41.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * linux/arch/ppc/kernel/sys_ppc.c
  *
- *  PowerPC version 
+ *  PowerPC version
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
  * Derived from "arch/i386/kernel/sys_i386.c"
@@ -136,7 +136,7 @@
 			break;
 		}
 		break;
-	case SHMDT: 
+	case SHMDT:
 		ret = sys_shmdt ((char *)ptr);
 		break;
 	case SHMGET:
@@ -180,7 +180,7 @@
 		if (!(file = fget(fd)))
 			goto out;
 	}
-	
+
 	down_write(&current->mm->mmap_sem);
 	ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
 	up_write(&current->mm->mmap_sem);
@@ -263,7 +263,7 @@
 		return -EFAULT;
 	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
 		return -EFAULT;
-  
+
 	down_read(&uts_sem);
 	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
 	error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/temp.c linux-2.4.22-pre10/arch/ppc/kernel/temp.c
--- linux-2.4.21/arch/ppc/kernel/temp.c	2001-08-28 13:58:33.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/temp.c	2003-08-01 13:33:32.000000000 +0000
@@ -6,7 +6,7 @@
  * TODO:
  * dynamic power management to limit peak CPU temp (using ICTC)
  * calibration???
- * 
+ *
  * Silly, crazy ideas: use cpu load (from scheduler) and ICTC to extend battery
  * life in portables, and add a 'performance/watt' metric somewhere in /proc
  */
@@ -111,7 +111,7 @@
 #endif
 
 #ifndef CONFIG_TAU_INT /* tau_timeout will do this if not using interrupts */
-	set_thresholds(cpu);	
+	set_thresholds(cpu);
 #endif
 
 }
@@ -128,7 +128,7 @@
 
 	hardirq_enter(cpu);
 	tau[cpu].interrupts++;
-	
+
 	TAUupdate(cpu);
 
 	hardirq_exit(cpu);
@@ -142,14 +142,14 @@
 	unsigned long flags;
 	int size;
 	int shrink;
- 
+
 	/* disabling interrupts *should* be okay */
 	save_flags(flags); cli();
 
 #ifndef CONFIG_TAU_INT
 	TAUupdate(cpu);
 #endif
-	
+
 	size = tau[cpu].high - tau[cpu].low;
 	if (size > min_window && ! tau[cpu].grew) {
 		/* do an exponential shrink of half the amount currently over size */
@@ -168,19 +168,19 @@
 	}
 
 	tau[cpu].grew = 0;
-	
+
 	set_thresholds(cpu);
 
 	/*
 	 * Do the enable every time, since otherwise a bunch of (relatively)
 	 * complex sleep code needs to be added. One mtspr every time
 	 * tau_timeout is called is probably not a big deal.
-	 * 
+	 *
 	 * Enable thermal sensor and set up sample interval timer
 	 * need 20 us to do the compare.. until a nice 'cpu_speed' function
 	 * call is implemented, just assume a 500 mhz clock. It doesn't really
-	 * matter if we take too long for a compare since it's all interrupt 
-	 * driven anyway. 
+	 * matter if we take too long for a compare since it's all interrupt
+	 * driven anyway.
 	 *
 	 * use a extra long time.. (60 us @ 500 mhz)
 	 */
@@ -202,7 +202,7 @@
 
 /*
  * setup the TAU
- * 
+ *
  * Set things up to use THRM1 as a temperature lower bound, and THRM2 as an upper bound.
  * Start off at zero
  */
@@ -212,7 +212,7 @@
 void __init TAU_init_smp(void * info)
 {
 	unsigned long cpu = smp_processor_id();
-	
+
 	/* set these to a reasonable value and let the timer shrink the
 	 * window */
 	tau[cpu].low = 5;
@@ -238,19 +238,19 @@
 	tau_timer.function = tau_timeout_smp;
 	tau_timer.expires = jiffies + shrink_timer;
 	add_timer(&tau_timer);
-	
+
 #ifdef CONFIG_SMP
 	smp_call_function(TAU_init_smp, NULL, 1, 0);
 #endif
 	TAU_init_smp(NULL);
-	
+
 	printk("Thermal assist unit ");
 #ifdef CONFIG_TAU_INT
 	printk("using interrupts, ");
 #else
 	printk("using timers, ");
 #endif
-	printk("shrink_timer: %d jiffies\n", shrink_timer); 
+	printk("shrink_timer: %d jiffies\n", shrink_timer);
 	tau_initialized = 1;
 
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/time.c linux-2.4.22-pre10/arch/ppc/kernel/time.c
--- linux-2.4.21/arch/ppc/kernel/time.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/time.c	2003-08-01 13:34:09.000000000 +0000
@@ -149,12 +149,12 @@
 		do_IRQ(regs);
 
 	hardirq_enter(cpu);
-	
+
 	while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0) {
 		jiffy_stamp += tb_ticks_per_jiffy;
 		if (!user_mode(regs))
 			ppc_do_profile(instruction_pointer(regs));
-		if (unlikely(!heartbeat_count(cpu)--) 
+		if (unlikely(!heartbeat_count(cpu)--)
 				&& heartbeat_reset(cpu)) {
 			ppc_md.heartbeat();
 			heartbeat_count(cpu) = heartbeat_reset(cpu);
@@ -262,7 +262,7 @@
 	 * harmful to relatively short timers.
 	 */
 
-	/* This works perfectly on SMP only if the tb are in sync but 
+	/* This works perfectly on SMP only if the tb are in sync but
 	 * guarantees an error < 1 jiffy even if they are off by eons,
 	 * still reasonable when gettimeofday resolution is 1 jiffy.
 	 */
@@ -271,13 +271,13 @@
 	new_sec = tv->tv_sec;
 	new_usec = tv->tv_usec - mulhwu(tb_to_us, tb_delta);
 	while (new_usec <0) {
-		new_sec--; 
+		new_sec--;
 		new_usec += 1000000;
 	}
 	xtime.tv_usec = new_usec;
 	xtime.tv_sec = new_sec;
 
-	/* In case of a large backwards jump in time with NTP, we want the 
+	/* In case of a large backwards jump in time with NTP, we want the
 	 * clock to be updated as soon as the PLL is again in lock.
 	 */
 	last_rtc_update = new_sec - 658;
@@ -308,7 +308,7 @@
                 ppc_md.calibrate_decr();
 	}
 
-	/* Now that the decrementer is calibrated, it can be used in case the 
+	/* Now that the decrementer is calibrated, it can be used in case the
 	 * clock is stuck, but the fact that we have to handle the 601
 	 * makes things more complex. Repeatedly read the RTC until the
 	 * next second boundary to try to achieve some precision.  If there
@@ -320,7 +320,7 @@
 		sec = ppc_md.get_rtc_time();
 		elapsed = 0;
 		do {
-			old_stamp = stamp; 
+			old_stamp = stamp;
 			old_sec = sec;
 			stamp = get_native_tbl();
 			if (__USE_RTC() && stamp < old_stamp)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/todc_time.c linux-2.4.22-pre10/arch/ppc/kernel/todc_time.c
--- linux-2.4.21/arch/ppc/kernel/todc_time.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/todc_time.c	2003-08-01 13:30:54.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * arch/ppc/kernel/todc_time.c
- * 
+ *
  * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818
  * Real Time Clocks/Timekeepers.
  *
@@ -85,7 +85,7 @@
 {
 	return readb(todc_info->nvram_data + addr);
 }
-  
+
 void
 todc_direct_write_val(int addr, unsigned char val)
 {
@@ -101,7 +101,7 @@
 	outb(addr>>todc_info->as0_bits, todc_info->nvram_as1);
 	return inb(todc_info->nvram_data);
 }
-  
+
 void
 todc_m48txx_write_val(int addr, unsigned char val)
 {
@@ -118,7 +118,7 @@
 	outb(addr, todc_info->nvram_as0);
 	return inb(todc_info->nvram_data);
 }
-  
+
 void
 todc_mc146818_write_val(int addr, unsigned char val)
 {
@@ -395,7 +395,7 @@
 	todc_write_val(todc_info->month,        tm.tm_mon);
 	todc_write_val(todc_info->day_of_month, tm.tm_mday);
 	todc_write_val(todc_info->year,         tm.tm_year);
-	
+
 	todc_write_val(todc_info->control_a, save_control);
 
 	if (todc_info->rtc_type == TODC_TYPE_MC146818) {
@@ -438,7 +438,7 @@
 	}
 
 	return val;
-} 
+}
 
 /*
  * This was taken from prep_setup.c
@@ -451,7 +451,7 @@
 	ulong	tbl, tbu;
         long	i, loop_count;
         u_char	sec;
- 
+
 	todc_time_init();
 
 	/*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/kernel/traps.c linux-2.4.22-pre10/arch/ppc/kernel/traps.c
--- linux-2.4.21/arch/ppc/kernel/traps.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/kernel/traps.c	2003-08-01 13:31:50.000000000 +0000
@@ -167,7 +167,7 @@
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
 /* On 4xx, the reason for the machine check or program exception
    is in the ESR. */
-#define get_reason(regs)	mfspr(SPRN_ESR);
+#define get_reason(regs)	((regs)->dsisr)
 #define REASON_FP		0
 #define REASON_ILLEGAL		ESR_PIL
 #define REASON_PRIVILEGED	ESR_PPR
@@ -213,7 +213,7 @@
 		printk("Data");
 	printk(" machine check in kernel mode.\n");
 
-#else /* CONFIG_4xx */
+#else /* !CONFIG_4xx */
 	printk("Machine check in kernel mode.\n");
 	printk("Caused by (from SRR1=%lx): ", reason);
 	switch (reason & 0x601F0000) {
@@ -327,7 +327,14 @@
 	extern int do_mathemu(struct pt_regs *regs);
 
 #ifdef CONFIG_MATH_EMULATION
-	if ((reason & REASON_ILLEGAL) && do_mathemu(regs) == 0)
+	/* (reason & REASON_ILLEGAL) would be the obvious thing here,
+	 * but there seems to be a hardware bug on the 405GP (RevD)
+	 * that means ESR is sometimes set incorrectly - either to
+	 * ESR_DST (!?) or 0.  In the process of chasing this with the
+	 * hardware people - not sure if it can happen on any illegal
+	 * instruction or only on FP instructions, whether there is a
+	 * pattern to occurences etc. -dgibson 31/Mar/2003 */
+	if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0)
 		return;
 #endif /* CONFIG_MATH_EMULATION */
 
@@ -450,6 +457,35 @@
 }
 #endif /* CONFIG_8xx */
 
+#if defined(CONFIG_4xx)
+
+void DebugException(struct pt_regs *regs)
+{
+	unsigned long debug_status;
+
+	debug_status = mfspr(SPRN_DBSR);
+
+	regs->msr &= ~MSR_DE;  /* Turn off 'debug' bit */
+	if (debug_status & DBSR_TIE) {		/* trap instruction*/
+
+		mtspr(SPRN_DBSR, DBSR_TIE);
+
+		if (!user_mode(regs) && debugger_bpt(regs))
+			return;
+		_exception(SIGTRAP, regs, 0, 0);
+
+	} else if (debug_status & DBSR_IC) {	/* instruction completion */
+
+		mtspr(SPRN_DBSR, DBSR_IC);
+		current->thread.dbcr0 &=  ~DBCR0_IC;
+
+		if (!user_mode(regs) && debugger_sstep(regs))
+			return;
+		_exception(SIGTRAP, regs, 0, 0);
+	}
+}
+#endif /* CONFIG_4xx */
+
 #if !defined(CONFIG_TAU_INT)
 void
 TAUException(struct pt_regs *regs)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/lib/checksum.S linux-2.4.22-pre10/arch/ppc/lib/checksum.S
--- linux-2.4.21/arch/ppc/lib/checksum.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/lib/checksum.S	2003-08-01 13:32:03.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * This file contains assembly-language implementations
  * of IP-style 1's complement checksum routines.
- *	
+ *
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
  *  This program is free software; you can redistribute it and/or
@@ -43,7 +43,7 @@
 /*
  * Compute checksum of TCP or UDP pseudo-header:
  *   csum_tcpudp_magic(saddr, daddr, len, proto, sum)
- */	
+ */
 _GLOBAL(csum_tcpudp_magic)
 	rlwimi	r5,r6,16,0,15	/* put proto in upper half of len */
 	addc	r0,r3,r4	/* add 4 32-bit words together */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/lib/locks.c linux-2.4.22-pre10/arch/ppc/lib/locks.c
--- linux-2.4.21/arch/ppc/lib/locks.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/lib/locks.c	2003-08-01 13:31:52.000000000 +0000
@@ -1,6 +1,6 @@
 /*
- * Locks for smp ppc 
- * 
+ * Locks for smp ppc
+ *
  * Written by Cort Dougan (cort@cs.nmt.edu)
  */
 
@@ -70,7 +70,7 @@
 {
 	if (__spin_trylock(&lock->lock))
 		return 0;
-	lock->owner_cpu = smp_processor_id(); 
+	lock->owner_cpu = smp_processor_id();
 	lock->owner_pc = (unsigned long)__builtin_return_address(0);
 	return 1;
 }
@@ -101,7 +101,7 @@
 	unsigned long stuck = INIT_STUCK;
 	int cpu = smp_processor_id();
 
-again:	
+again:
 	/* get our read lock in there */
 	atomic_inc((atomic_t *) &(rw)->lock);
 	if ( (signed long)((rw)->lock) < 0) /* someone has a write lock */
@@ -153,7 +153,7 @@
 		}
 		goto again;
 	}
-	
+
 	if ( (rw)->lock & ~(1<<31)) /* someone has a read lock */
 	{
 		/* clear our write lock and wait for reads to go away */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/lib/string.S linux-2.4.22-pre10/arch/ppc/lib/string.S
--- linux-2.4.21/arch/ppc/lib/string.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/lib/string.S	2003-08-01 13:33:42.000000000 +0000
@@ -380,7 +380,7 @@
 	beq	2b
 	mtctr	r7
 	b	1b
-	
+
 	.globl	memcmp
 memcmp:
 	cmpwi	0,r5,0
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/math-emu/fcmpo.c linux-2.4.22-pre10/arch/ppc/math-emu/fcmpo.c
--- linux-2.4.21/arch/ppc/math-emu/fcmpo.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/math-emu/fcmpo.c	2003-08-01 13:33:09.000000000 +0000
@@ -37,7 +37,7 @@
 
 	*ccr &= ~(15 << ((7 - crfD) << 2));
 	*ccr |= (cmp << ((7 - crfD) << 2));
- 
+
 #ifdef DEBUG
 	printk("CR: %08x\n", *ccr);
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/math-emu/op-1.h linux-2.4.22-pre10/arch/ppc/math-emu/op-1.h
--- linux-2.4.21/arch/ppc/math-emu/op-1.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/math-emu/op-1.h	2003-08-01 13:32:39.000000000 +0000
@@ -197,14 +197,14 @@
     udiv_qrnnd(_q, _r, _nh, _nl, Y##_f);		\
     R##_f = _q | (_r != 0);				\
   } while (0)
-  
-  
+
+
 /*
  * Square root algorithms:
  * We have just one right now, maybe Newton approximation
  * should be added for those machines where division is fast.
  */
- 
+
 #define _FP_SQRT_MEAT_1(R, S, T, X, q)			\
   do {							\
     while (q)						\
@@ -222,7 +222,7 @@
   } while (0)
 
 /*
- * Assembly/disassembly for converting to/from integral types.  
+ * Assembly/disassembly for converting to/from integral types.
  * No shifting or overflow handled here.
  */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/math-emu/op-2.h linux-2.4.22-pre10/arch/ppc/math-emu/op-2.h
--- linux-2.4.21/arch/ppc/math-emu/op-2.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/math-emu/op-2.h	2003-08-01 13:30:32.000000000 +0000
@@ -98,7 +98,7 @@
 #define _FP_MINFRAC_2		0, 1
 
 /*
- * Internals 
+ * Internals
  */
 
 #define __FP_FRAC_SET_2(X,I1,I0)	(X##_f0 = I0, X##_f1 = I1)
@@ -210,8 +210,8 @@
 /* This next macro appears to be totally broken. Fortunately nowhere
  * seems to use it :-> The problem is that we define _z[4] but
  * then use it in _FP_FRAC_SRS_4, which will attempt to access
- * _z_f[n] which will cause an error. The fix probably involves 
- * declaring it with _FP_FRAC_DECL_4, see previous macro. -- PMM 02/1998 
+ * _z_f[n] which will cause an error. The fix probably involves
+ * declaring it with _FP_FRAC_DECL_4, see previous macro. -- PMM 02/1998
  */
 #define _FP_MUL_MEAT_2_gmp(fs, R, X, Y)					\
   do {									\
@@ -232,7 +232,7 @@
 
 /*
  * Division algorithms:
- * This seems to be giving me difficulties -- PMM 
+ * This seems to be giving me difficulties -- PMM
  * Look, NetBSD seems to be able to comment algorithms. Can't you?
  * I've thrown printks at the problem.
  * This now appears to work, but I still don't really know why.
@@ -354,7 +354,7 @@
  * We have just one right now, maybe Newton approximation
  * should be added for those machines where division is fast.
  */
- 
+
 #define _FP_SQRT_MEAT_2(R, S, T, X, q)			\
   do {							\
     while (q)						\
@@ -391,7 +391,7 @@
 
 
 /*
- * Assembly/disassembly for converting to/from integral types.  
+ * Assembly/disassembly for converting to/from integral types.
  * No shifting or overflow handled here.
  */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/math-emu/op-4.h linux-2.4.22-pre10/arch/ppc/math-emu/op-4.h
--- linux-2.4.21/arch/ppc/math-emu/op-4.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/math-emu/op-4.h	2003-08-01 13:33:03.000000000 +0000
@@ -7,14 +7,14 @@
  * _FP_MUL_MEAT_2_wide() uses _FP_FRAC_DECL_4, _FP_FRAC_WORD_4,
  * _FP_FRAC_ADD_4, _FP_FRAC_SRS_4
  * _FP_MUL_MEAT_2_gmp() uses _FP_FRAC_SRS_4 (and should use
- * _FP_FRAC_DECL_4: it appears to be broken and is not used 
+ * _FP_FRAC_DECL_4: it appears to be broken and is not used
  * anywhere anyway. )
  *
  * I've now fixed all the macros that were here from the sparc64 code.
  * [*none* of the shift macros were correct!] -- PMM 02/1998
- * 
- * The only quadword stuff that remains to be coded is: 
- * 1) the conversion to/from ints, which requires 
+ *
+ * The only quadword stuff that remains to be coded is:
+ * 1) the conversion to/from ints, which requires
  * that we check (in op-common.h) that the following do the right thing
  * for quadwords: _FP_TO_INT(Q,4,r,X,rsz,rsg), _FP_FROM_INT(Q,4,X,r,rs,rt)
  * 2) multiply, divide and sqrt, which require:
@@ -32,9 +32,9 @@
 /* The _FP_FRAC_SET_n(X,I) macro is intended for use with another
  * macro such as _FP_ZEROFRAC_n which returns n comma separated values.
  * The result is that we get an expansion of __FP_FRAC_SET_n(X,I0,I1,I2,I3)
- * which just assigns the In values to the array X##_f[]. 
+ * which just assigns the In values to the array X##_f[].
  * This is why the number of parameters doesn't appear to match
- * at first glance...      -- PMM 
+ * at first glance...      -- PMM
  */
 #define _FP_FRAC_SET_4(X,I)	__FP_FRAC_SET_4(X, I)
 #define _FP_FRAC_HIGH_4(X)	(X##_f[3])
@@ -70,7 +70,7 @@
   } while (0)
 
 
-/* Right shift with sticky-lsb. 
+/* Right shift with sticky-lsb.
  * What this actually means is that we do a standard right-shift,
  * but that if any of the bits that fall off the right hand side
  * were one then we always set the LSbit.
@@ -187,7 +187,7 @@
 
 
 /*
- * Internals 
+ * Internals
  */
 
 #define __FP_FRAC_SET_4(X,I3,I2,I1,I0)					\
@@ -218,9 +218,9 @@
 /* Convert FP values between word sizes. This appears to be more
  * complicated than I'd have expected it to be, so these might be
  * wrong... These macros are in any case somewhat bogus because they
- * use information about what various FRAC_n variables look like 
+ * use information about what various FRAC_n variables look like
  * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do
- * the ones in op-2.h and op-1.h. 
+ * the ones in op-2.h and op-1.h.
  */
 #define _FP_FRAC_CONV_1_4(dfs, sfs, D, S)                               \
    do {                                                                 \
@@ -237,7 +237,7 @@
      D##_f1 = S##_f[1];                                                  \
   } while (0)
 
-/* Assembly/disassembly for converting to/from integral types.  
+/* Assembly/disassembly for converting to/from integral types.
  * No shifting or overflow handled here.
  */
 /* Put the FP value X into r, which is an integer of size rsize. */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/math-emu/op-common.h linux-2.4.22-pre10/arch/ppc/math-emu/op-common.h
--- linux-2.4.21/arch/ppc/math-emu/op-common.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/math-emu/op-common.h	2003-08-01 13:34:22.000000000 +0000
@@ -525,7 +525,7 @@
  * Convert from FP to integer
  */
 
-/* "When a NaN, infinity, large positive argument >= 2147483648.0, or 
+/* "When a NaN, infinity, large positive argument >= 2147483648.0, or
  * large negative argument <= -2147483649.0 is converted to an integer,
  * the invalid_current bit...should be set and fp_exception_IEEE_754 should
  * be raised. If the floating point invalid trap is disabled, no trap occurs
@@ -538,7 +538,7 @@
  * -- SPARC Architecture Manual V9, Appendix B, which specifies how
  * SPARCs resolve implementation dependencies in the IEEE-754 spec.
  * I don't believe that the code below follows this. I'm not even sure
- * it's right! 
+ * it's right!
  * It doesn't cope with needing to convert to an n bit integer when there
  * is no n bit integer type. Fortunately gcc provides long long so this
  * isn't a problem for sparc32.
@@ -546,7 +546,7 @@
  *         -- PMM 02/1998
  * NB: rsigned is not 'is r declared signed?' but 'should the value stored
  * in r be signed or unsigned?'. r is always(?) declared unsigned.
- * Comments below are mine, BTW -- PMM 
+ * Comments below are mine, BTW -- PMM
  */
 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)			\
   do {									\
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/math-emu/sfp-machine.h linux-2.4.22-pre10/arch/ppc/math-emu/sfp-machine.h
--- linux-2.4.21/arch/ppc/math-emu/sfp-machine.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/math-emu/sfp-machine.h	2003-08-01 13:31:52.000000000 +0000
@@ -15,10 +15,10 @@
    You should have received a copy of the GNU Library General Public
    License along with the GNU C Library; see the file COPYING.LIB.  If
    not, write to the Free Software Foundation, Inc.,
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
    Actually, this is a PPC (32bit) version, written based on the
-   i386, sparc, and sparc64 versions, by me, 
+   i386, sparc, and sparc64 versions, by me,
    Peter Maydell (pmaydell@chiark.greenend.org.uk).
    Comments are by and large also mine, although they may be inaccurate.
 
@@ -48,12 +48,12 @@
 /* We need to know how to multiply and divide. If the host word size
  * is >= 2*fracbits you can use FP_MUL_MEAT_n_imm(t,R,X,Y) which
  * codes the multiply with whatever gcc does to 'a * b'.
- * _FP_MUL_MEAT_n_wide(t,R,X,Y,f) is used when you have an asm 
- * function that can multiply two 1W values and get a 2W result. 
+ * _FP_MUL_MEAT_n_wide(t,R,X,Y,f) is used when you have an asm
+ * function that can multiply two 1W values and get a 2W result.
  * Otherwise you're stuck with _FP_MUL_MEAT_n_hard(t,R,X,Y) which
  * does bitshifting to avoid overflow.
  * For division there is FP_DIV_MEAT_n_imm(t,R,X,Y,f) for word size
- * >= 2*fracbits, where f is either _FP_DIV_HELP_imm or 
+ * >= 2*fracbits, where f is either _FP_DIV_HELP_imm or
  * _FP_DIV_HELP_ldiv (see op-1.h).
  * _FP_DIV_MEAT_udiv() is if you have asm to do 2W/1W => (1W, 1W).
  * [GCC and glibc have longlong.h which has the asm macro udiv_qrnnd
@@ -85,7 +85,7 @@
 #define _FP_DIV_MEAT_S(R,X,Y)   _FP_DIV_MEAT_1_udiv(S,R,X,Y)
 #define _FP_DIV_MEAT_D(R,X,Y)   _FP_DIV_MEAT_2_udiv_64(D,R,X,Y)
 
-/* These macros define what NaN looks like. They're supposed to expand to 
+/* These macros define what NaN looks like. They're supposed to expand to
  * a comma-separated set of 32bit unsigned ints that encode NaN.
  */
 #define _FP_NANFRAC_S		_FP_QNANBIT_S
@@ -94,10 +94,10 @@
 
 #define _FP_KEEPNANFRACP 1
 
-/* This macro appears to be called when both X and Y are NaNs, and 
+/* This macro appears to be called when both X and Y are NaNs, and
  * has to choose one and copy it to R. i386 goes for the larger of the
  * two, sparc64 just picks Y. I don't understand this at all so I'll
- * go with sparc64 because it's shorter :->   -- PMM 
+ * go with sparc64 because it's shorter :->   -- PMM
  */
 #define _FP_CHOOSENAN(fs, wc, R, X, Y)			\
   do {							\
@@ -105,7 +105,7 @@
     _FP_FRAC_COPY_##wc(R,Y);				\
     R##_c = FP_CLS_NAN;					\
   } while (0)
-  
+
 
 extern void fp_unpack_d(long *, unsigned long *, unsigned long *,
 			long *, long *, void *);
@@ -151,7 +151,7 @@
     _flo->bits.exp  = X##_e;				\
     _flo->bits.sign = X##_s;				\
   } while (0)
-  
+
 #define __FP_PACK_RAW_2(fs, val, X)			\
   do {							\
     union _FP_UNION_##fs *_flo =			\
@@ -288,7 +288,7 @@
 		 "r" ((USItype)(bl)));					\
   } while (0)
 
-/* asm fragments for mul and div */	 
+/* asm fragments for mul and div */
 
 /* umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
  * UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/math-emu/stfd.c linux-2.4.22-pre10/arch/ppc/math-emu/stfd.c
--- linux-2.4.21/arch/ppc/math-emu/stfd.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/math-emu/stfd.c	2003-08-01 13:33:34.000000000 +0000
@@ -1,7 +1,7 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
- 
+
 int
 stfd(void *frS, void *ea)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/mm/4xx_mmu.c linux-2.4.22-pre10/arch/ppc/mm/4xx_mmu.c
--- linux-2.4.21/arch/ppc/mm/4xx_mmu.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/mm/4xx_mmu.c	2003-08-01 13:30:32.000000000 +0000
@@ -2,7 +2,7 @@
  * This file contains the routines for initializing the MMU
  * on the 4xx series of chips.
  *  -- paulus
- * 
+ *
  *  Derived from arch/ppc/mm/init.c:
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
@@ -51,11 +51,6 @@
 #include <asm/machdep.h>
 #include <asm/setup.h>
 
-/* Used by the 4xx TLB replacement exception handler.
- * Just needed it declared someplace (and initialized to zero).
- */
-unsigned int tlb_4xx_index;
-
 /*
  * MMU_init_hw does the chip-specific initialization of the MMU hardware.
  */
@@ -89,7 +84,14 @@
 	 * Cache instruction and data space where the exception
 	 * vectors and the kernel live in real-mode.
 	 */
+	/*
+	 * Once the following code is enhanced to not assume that it should
+	 * just enable caching on the first 512MB, we need to make sure that
+	 * we either are given the cache in a known state or handle correctly
+	 * the cache being enabled previously.  Currently this will clear
+	 * without flushing. -- Tom
+	 */
 
-        mtspr(SPRN_DCCR, 0x80000000);	/* 128 MB of data space at 0x0. */
-        mtspr(SPRN_ICCR, 0x80000000);	/* 128 MB of instr. space at 0x0. */
+        mtspr(SPRN_DCCR, 0xF0000000);	/* 512 MB of data space at 0x0. */
+        mtspr(SPRN_ICCR, 0xF0000000);	/* 512 MB of instr. space at 0x0. */
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/mm/4xx_tlb.c linux-2.4.22-pre10/arch/ppc/mm/4xx_tlb.c
--- linux-2.4.21/arch/ppc/mm/4xx_tlb.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/mm/4xx_tlb.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,358 +0,0 @@
-/*
- *
- *    Copyright (c) 1998-1999 TiVo, Inc.
- *      Original implementation.
- *    Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
- *      Minor rework.
- *
- *    Module name: 4xx_tlb.c
- *
- *    Description:
- *      Routines for manipulating the TLB on PowerPC 400-class processors.
- *
- */
-
-#include <linux/mm.h>
-
-#include <asm/processor.h>
-#include <asm/io.h>
-#include <asm/mmu.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-
-
-/* Preprocessor Defines */
-
-#if !defined(TRUE) || TRUE != 1
-#define TRUE    1
-#endif
-
-#if !defined(FALSE) || FALSE != 0
-#define FALSE   0
-#endif
-
-
-/* Global Variables */
-
-static int pinned = 0;
-
-
-/* Function Prototypes */
-
-static int PPC4xx_tlb_miss(struct pt_regs *, unsigned long, int);
-
-extern void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
-
-
-/*
- * ()
- *
- * Description:
- *   This routine...
- *
- * Input(s):
- *
- *
- * Output(s):
- *
- *
- * Returns:
- *
- *
- */
-static inline void
-PPC4xx_tlb_write(unsigned long tag, unsigned long data, unsigned int index)
-{
-	asm("tlbwe %0,%1,1" : : "r" (data), "r" (index));
-	asm("tlbwe %0,%1,0" : : "r" (tag), "r" (index));
-}
-
-/*
- * ()
- *
- * Description:
- *   This routine...
- *
- * Input(s):
- *
- *
- * Output(s):
- *
- *
- * Returns:
- *
- *
- */
-void
-PPC4xx_flush_tlb_all(void)
-{
-	int i;
-	unsigned long flags, pid;
-
-	save_flags(flags);
-	cli();
-
-	pid = mfspr(SPRN_PID);
-	mtspr(SPRN_PID, 0);
-
-	for (i = pinned; i < PPC4XX_TLB_SIZE; i++) {
-		PPC4xx_tlb_write(0, 0, i);
-	}
-	asm("sync;isync");
-
-	mtspr(SPRN_PID, pid);
-	restore_flags(flags);
-}
-
-/*
- * ()
- *
- * Description:
- *   This routine...
- *
- * Input(s):
- *
- *
- * Output(s):
- *
- *
- * Returns:
- *
- *
- */
-void
-PPC4xx_dtlb_miss(struct pt_regs *regs)
-{
-	unsigned long addr = mfspr(SPRN_DEAR);
-	int write = mfspr(SPRN_ESR) & ESR_DST;
-
-	if (PPC4xx_tlb_miss(regs, addr, write) < 0) {
-		sti();
-		do_page_fault(regs, addr, write);
-		cli();
-	}
-	
-}
-
-/*
- * ()
- *
- * Description:
- *   This routine...
- *
- * Input(s):
- *
- *
- * Output(s):
- *
- *
- * Returns:
- *
- *
- */
-void
-PPC4xx_itlb_miss(struct pt_regs *regs)
-{
-	unsigned long addr = regs->nip;
-
-	if (PPC4xx_tlb_miss(regs, addr, 0) < 0) {
-		sti();
-		do_page_fault(regs, addr, 0);
-		cli();
-	}
-}
-
-/*
- * ()
- *
- * Description:
- *   This routine...
- *
- * Input(s):
- *
- *
- * Output(s):
- *
- *
- * Returns:
- *
- *
- */
-void
-PPC4xx_tlb_pin(unsigned long va, unsigned long pa, int pagesz, int cache)
-{
-	unsigned long tag, data;
-	unsigned long opid;
-
-	if (pinned >= PPC4XX_TLB_SIZE)
-		return;
-
-	opid = mfspr(SPRN_PID);
-	mtspr(SPRN_PID, 0);
-
-	data = (pa & TLB_RPN_MASK) | TLB_WR;
-
-	if (cache)
-		data |= (TLB_EX);
-	else
-		data |= (TLB_G | TLB_I);
-
-	tag = (va & TLB_EPN_MASK) | TLB_VALID | pagesz;
-
-	PPC4xx_tlb_write(tag, data, pinned++);
-
-	mtspr(SPRN_PID, opid);
-	return;
-}
-
-/*
- * ()
- *
- * Description:
- *   This routine...
- *
- * Input(s):
- *
- *
- * Output(s):
- *
- *
- * Returns:
- *
- *
- */
-void
-PPC4xx_tlb_unpin(unsigned long va, unsigned long pa, int size)
-{
-	/* XXX - To be implemented. */
-}
-
-/*
- * ()
- *
- * Description:
- *   This routine...
- *
- * Input(s):
- *
- *
- * Output(s):
- *
- *
- * Returns:
- *
- *
- */
-static inline void
-PPC4xx_tlb_update(unsigned long addr, pte_t *pte)
-{
-        unsigned long data, tag, rand;
-        int i, found = 1;
-
-        /* Construct the hardware TLB entry from the Linux-style PTE */
-
-        tag = tag = (addr & PAGE_MASK) | TLB_VALID | TLB_PAGESZ(PAGESZ_4K);
-        data = data = (pte_val(*pte) & PAGE_MASK) | TLB_EX | TLB_WR;
-
-#if 0
-        if (pte_val(*pte) & _PAGE_HWWRITE)
-                data |= TLB_WR;
-#endif
-
-        if (pte_val(*pte) & _PAGE_NO_CACHE)
-                data |= TLB_I;
-
-        if (pte_val(*pte) & _PAGE_GUARDED)
-                data |= TLB_G;
-
-        if (addr < KERNELBASE)
-                data |= TLB_ZSEL(1);
-
-        /* Attempt to match the new tag to an existing entry in the TLB. */
-
-        asm("tlbsx. %0,0,%2;"
-	    "beq 1f;"
-	    "li %1,0;1:" : "=r" (i), "=r" (found) : "r" (tag));
-
-	/*
-	 * If we found a match for the tag, reuse the entry index and update
-	 * the tag and data portions. Otherwise, we did not find a match. Use
-	 * the lower 5 bits of the lower time base register as a pseudo-random
-	 * index into the TLB and replace the entry at that index.
-	 */
-
-        if (found) {
-		PPC4xx_tlb_write(tag, data, i);
-        } else {
-		rand = mfspr(SPRN_TBLO) & (PPC4XX_TLB_SIZE - 1);
-		rand += pinned;
-		if (rand >= PPC4XX_TLB_SIZE)
-			rand -= pinned;
-
-		PPC4xx_tlb_write(tag, data, rand);
-		asm("isync;sync");
-        }
-}
-
-/*
- * ()
- *
- * Description:
- *   This routine...
- *
- * Input(s):
- *
- *
- * Output(s):
- *
- *
- * Returns:
- *
- *
- */
-static int
-PPC4xx_tlb_miss(struct pt_regs *regs, unsigned long addr, int write)
-{
-        unsigned long spid, ospid;
-        struct mm_struct *mm;
-        pgd_t *pgd;
-        pmd_t *pmd;
-        pte_t *pte;
-
-        if (!user_mode(regs) && (addr >= KERNELBASE)) {
-                mm = &init_mm;
-                spid = 0;
-        } else {
-                mm = current->mm;
-                spid = mfspr(SPRN_PID);
-        }
-
-        pgd = pgd_offset(mm, addr);
-        if (pgd_none(*pgd))
-                goto bad;
-
-        pmd = pmd_offset(pgd, addr);
-        if (pmd_none(*pmd))
-                goto bad;
-
-        pte = pte_offset(pmd, addr);
-        if (pte_none(*pte) || !pte_present(*pte))
-                goto bad;
-
-        if (write) {
-                if (!pte_write(*pte))
-                        goto bad;
-
-                set_pte(pte, pte_mkdirty(*pte));
-        }
-        set_pte(pte, pte_mkyoung(*pte));
-
-        ospid = mfspr(SPRN_PID);
-        mtspr(SPRN_PID, spid);
-        PPC4xx_tlb_update(addr, pte);
-        mtspr(SPRN_PID, ospid);
-
-	return (0);
-bad:
-	return (-1);
-}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/mm/4xx_tlb.h linux-2.4.22-pre10/arch/ppc/mm/4xx_tlb.h
--- linux-2.4.21/arch/ppc/mm/4xx_tlb.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/mm/4xx_tlb.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,35 +0,0 @@
-/*
- *
- *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
- *
- *    Module name: 4xx_tlb.h
- *
- *    Description:
- *      Routines for manipulating the TLB on PowerPC 400-class processors.
- *
- */
-
-#ifndef __4XX_TLB_H__
-#define __4XX_TLB_H__
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* Function Prototypes */
-
-extern void	 PPC4xx_tlb_pin(unsigned long va, unsigned long pa,
-				int pagesz, int cache);
-extern void	 PPC4xx_tlb_unpin(unsigned long va, unsigned long pa,
-				  int size);
-extern void	 PPC4xx_tlb_flush_all(void);
-extern void	 PPC4xx_tlb_flush(unsigned long va, int pid);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __4XX_TLB_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/mm/Makefile linux-2.4.22-pre10/arch/ppc/mm/Makefile
--- linux-2.4.21/arch/ppc/mm/Makefile	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/mm/Makefile	2003-08-01 13:34:18.000000000 +0000
@@ -18,7 +18,7 @@
 					mmu_context.o pgtable.o
 
 obj-$(CONFIG_PPC_STD_MMU)	+= hashtable.o ppc_mmu.o tlb.o
-obj-$(CONFIG_4xx)		+= cachemap.o 4xx_mmu.o
-obj-$(CONFIG_8xx)		+= cachemap.o
+obj-$(CONFIG_40x)		+= 4xx_mmu.o
+obj-$(CONFIG_NOT_COHERENT_CACHE)	+= cachemap.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/mm/fault.c linux-2.4.22-pre10/arch/ppc/mm/fault.c
--- linux-2.4.21/arch/ppc/mm/fault.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/mm/fault.c	2003-08-01 13:32:13.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *  arch/ppc/mm/fault.c
  *
- *  PowerPC version 
+ *  PowerPC version
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
  *  Derived from "arch/i386/mm/fault.c"
@@ -197,7 +197,7 @@
                 /* Guarded storage error. */
 		goto bad_area;
 #endif /* CONFIG_8xx */
-	
+
 	/* a write */
 	if (is_write) {
 		if (!(vma->vm_flags & VM_WRITE))
@@ -241,7 +241,7 @@
 
 bad_area:
 	up_read(&mm->mmap_sem);
-	pte_errors++;	
+	pte_errors++;
 
 	/* User mode accesses cause a SIGSEGV */
 	if (user_mode(regs)) {
@@ -348,7 +348,7 @@
 unsigned long va_to_phys(unsigned long address)
 {
 	pte_t *pte;
-	
+
 	pte = va_to_pte(address);
 	if (pte)
 		return(((unsigned long)(pte_val(*pte)) & PAGE_MASK) | (address & ~(PAGE_MASK)));
@@ -371,7 +371,7 @@
                         if (pte) {
                                 printk(" (0x%08lx)->(0x%08lx)->0x%08lx\n",
                                         (long)pgd, (long)pte, (long)pte_val(*pte));
-#define pp ((long)pte_val(*pte))				
+#define pp ((long)pte_val(*pte))
 				printk(" RPN: %05lx PP: %lx SPS: %lx SH: %lx "
 				       "CI: %lx v: %lx\n",
 				       pp>>12,    /* rpn */
@@ -381,7 +381,7 @@
 				       (pp>>1)&1, /* cache inhibit */
 				       pp&1       /* valid */
 				       );
-#undef pp				
+#undef pp
                         }
                         else {
                                 printk("no pte\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/mm/hashtable.S linux-2.4.22-pre10/arch/ppc/mm/hashtable.S
--- linux-2.4.21/arch/ppc/mm/hashtable.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/mm/hashtable.S	2003-08-01 13:34:22.000000000 +0000
@@ -3,7 +3,7 @@
  *
  *  $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $
  *
- *  PowerPC version 
+ *  PowerPC version
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
@@ -20,7 +20,7 @@
  *  modify it under the terms of the GNU General Public License
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
- *	
+ *
  */
 
 #include <linux/config.h>
@@ -168,7 +168,7 @@
 	lwz	r23,GPR23(r21)
 	lwz	r21,GPR21(r21)
 	RFI
-	
+
 #ifdef CONFIG_SMP
 hash_page_out:
 	eieio
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/mm/init.c linux-2.4.22-pre10/arch/ppc/mm/init.c
--- linux-2.4.21/arch/ppc/mm/init.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/mm/init.c	2003-08-01 13:31:52.000000000 +0000
@@ -345,7 +345,7 @@
 
 #ifdef CONFIG_BOOTX_TEXT
 	/* By default, we are no longer mapped */
-	boot_text_mapped = 0;	
+	boot_text_mapped = 0;
 	/* Must be done last, or ppc_md.progress will die. */
 	map_boot_text();
 #endif
@@ -573,14 +573,14 @@
 	 * memory as high as possible (it must be outside of the
 	 * bus address seen as the AGP aperture). It will be used
 	 * by the r128 DRM driver
-	 * 
+	 *
 	 * FIXME: We need to make sure that page doesn't overlap any of the\
 	 * above. This could be done by improving mem_pieces_find to be able
 	 * to do a backward search from the end of the list.
 	 */
 	if (_machine == _MACH_Pmac && find_devices("uni-north-agp")) {
 		agp_special_page = (total_memory - PAGE_SIZE);
-		mem_pieces_remove(&phys_avail, agp_special_page, PAGE_SIZE, 0);	
+		mem_pieces_remove(&phys_avail, agp_special_page, PAGE_SIZE, 0);
 		agp_special_page = (unsigned long)__va(agp_special_page);
 	}
 #endif /* CONFIG_ALL_PPC */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/mm/mem_pieces.c linux-2.4.22-pre10/arch/ppc/mm/mem_pieces.c
--- linux-2.4.21/arch/ppc/mm/mem_pieces.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/mm/mem_pieces.c	2003-08-01 13:30:42.000000000 +0000
@@ -46,14 +46,14 @@
 		}
 	}
 	panic("Couldn't find %u bytes at %u alignment\n", size, align);
-	
+
 	return NULL;
 }
 
 /*
  * Remove some memory from an array of pieces
  */
-void __init 
+void __init
 mem_pieces_remove(struct mem_pieces *mp, unsigned int start, unsigned int size,
 		  int must_exist)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/mm/mmu_context.c linux-2.4.22-pre10/arch/ppc/mm/mmu_context.c
--- linux-2.4.21/arch/ppc/mm/mmu_context.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/mm/mmu_context.c	2003-08-01 13:33:35.000000000 +0000
@@ -7,7 +7,7 @@
  * specification, the need to work through the hypervisor makes
  * things sufficiently different that it is handled elsewhere.
  *  -- paulus
- * 
+ *
  *  Derived from arch/ppc/mm/init.c:
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/mm/mmu_decl.h linux-2.4.22-pre10/arch/ppc/mm/mmu_decl.h
--- linux-2.4.21/arch/ppc/mm/mmu_decl.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/mm/mmu_decl.h	2003-08-01 13:33:31.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Declarations of procedures and variables shared between files
  * in arch/ppc/mm/.
- * 
+ *
  *  Derived from arch/ppc/mm/init.c:
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/mm/pgtable.c linux-2.4.22-pre10/arch/ppc/mm/pgtable.c
--- linux-2.4.21/arch/ppc/mm/pgtable.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/mm/pgtable.c	2003-08-01 13:31:45.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * This file contains the routines setting up the linux page tables.
  *  -- paulus
- * 
+ *
  *  Derived from arch/ppc/mm/init.c:
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
@@ -122,7 +122,7 @@
 	 */
 	if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ )
 		goto out;
-	
+
 	if (mem_init_done) {
 		struct vm_struct *area;
 		area = get_vm_area(size, VM_IOREMAP);
@@ -193,13 +193,13 @@
 adjust_total_lowmem(void)
 {
 	unsigned long max_low_mem = MAX_LOW_MEM;
-	
+
 #ifdef HAVE_BATS
 	unsigned long bat_max = 0x10000000;
 	unsigned long align;
 	unsigned long ram;
 	int is601 = 0;
-	
+
 	/* 601s have smaller BATs */
 	if (PVR_VER(mfspr(PVR)) == 1) {
 		bat_max = 0x00800000;
@@ -224,7 +224,7 @@
 	if (align && align < bat_max)
 		bat_max = align;
 
-	/* Calculate BAT values */	
+	/* Calculate BAT values */
 	__bat2 = 1UL << __ilog2(ram);
 	if (__bat2 > bat_max)
 		__bat2 = bat_max;
@@ -278,11 +278,11 @@
 		/* On the MPC8xx, we want the page shared so we
 		 * don't get ASID compares on kernel space.
 		 */
-		f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED;
-#if defined(CONFIG_KGDB) || defined(CONFIG_XMON)
+		f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED | _PAGE_HWEXEC;
+#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH)
 		/* Allows stub to set breakpoints everywhere */
 		f |= _PAGE_WRENABLE;
-#else	/* !CONFIG_KGDB && !CONFIG_XMON */
+#else	/* !CONFIG_KGDB && !CONFIG_XMON && !CONFIG_BDI_SWITCH */
 		if ((char *) v < _stext || (char *) v >= etext)
 			f |= _PAGE_WRENABLE;
 #ifdef CONFIG_PPC_STD_MMU
@@ -388,7 +388,7 @@
 		mm = current->mm;
 	else
 		mm = &init_mm;
-	
+
 	pa = 0;
 	if (get_pteptr(mm, addr, &pte))
 		pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK);
@@ -421,7 +421,7 @@
 				goto exit;
 			}
 		}
-		
+
 		ret = (unsigned long) __va(paddr);
 	}
 exit:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/mm/ppc_mmu.c linux-2.4.22-pre10/arch/ppc/mm/ppc_mmu.c
--- linux-2.4.21/arch/ppc/mm/ppc_mmu.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/mm/ppc_mmu.c	2003-08-01 13:31:22.000000000 +0000
@@ -7,7 +7,7 @@
  * specification, the need to work through the hypervisor makes
  * things sufficiently different that it is handled elsewhere.
  *  -- paulus
- * 
+ *
  *  Derived from arch/ppc/mm/init.c:
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
@@ -86,13 +86,13 @@
 void __init bat_mapin_ram(unsigned long bat2, unsigned long bat3)
 {
 	unsigned long tot, done;
-	
+
 	tot = total_lowmem;
 	setbat(2, KERNELBASE, PPC_MEMSTART, bat2, _PAGE_KERNEL);
 	done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1;
 	if ((done < tot) && !bat_addrs[3].limit && bat3) {
 		tot -= done;
-		setbat(3, KERNELBASE+done, PPC_MEMSTART+done, bat3, 
+		setbat(3, KERNELBASE+done, PPC_MEMSTART+done, bat3,
 		       _PAGE_KERNEL);
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/mm/tlb.c linux-2.4.22-pre10/arch/ppc/mm/tlb.c
--- linux-2.4.21/arch/ppc/mm/tlb.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/mm/tlb.c	2003-08-01 13:33:59.000000000 +0000
@@ -1,10 +1,10 @@
 /*
  * This file contains the routines for TLB flushing.
  * On machines where the MMU uses a hash table to store virtual to
- * physical translations, these routines flush entries from the 
+ * physical translations, these routines flush entries from the
  * hash table also.
  *  -- paulus
- * 
+ *
  *  Derived from arch/ppc/mm/init.c:
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
@@ -87,7 +87,7 @@
 
 #ifdef CONFIG_SMP
 	smp_send_tlb_invalidate(0);
-#endif	
+#endif
 }
 
 void
@@ -110,7 +110,7 @@
 	}
 #ifdef CONFIG_SMP
 	smp_send_tlb_invalidate(0);
-#endif	
+#endif
 }
 
 
@@ -155,5 +155,5 @@
 
 #ifdef CONFIG_SMP
 	smp_send_tlb_invalidate(0);
-#endif	
+#endif
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/Makefile linux-2.4.22-pre10/arch/ppc/platforms/Makefile
--- linux-2.4.21/arch/ppc/platforms/Makefile	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/Makefile	2003-08-01 13:35:10.000000000 +0000
@@ -28,7 +28,7 @@
 
 export-objs			:= prep_setup.o
 
-obj-$(CONFIG_WALNUT)		+= walnut.o
+obj-$(CONFIG_WALNUT)		+= walnut.o ibm405gp.o
 
 obj-$(CONFIG_APUS)		+= apus_setup.o
 ifeq ($(CONFIG_APUS),y)
@@ -46,6 +46,7 @@
 obj-$(CONFIG_GEMINI)		+= gemini_pci.o gemini_setup.o gemini_prom.o
 obj-$(CONFIG_LOPEC)		+= lopec_setup.o lopec_pci.o
 obj-$(CONFIG_PAL4)		+= pal4_setup.o pal4_pci.o cpc700_pic.o
+obj-$(CONFIG_PPLUS)		+= pplus_pci.o pplus_setup.o
 obj-$(CONFIG_SPRUCE)		+= spruce_setup.o spruce_pci.o cpc700_pic.o
 
 ifeq ($(CONFIG_SMP),y)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/apus_pci.c linux-2.4.22-pre10/arch/ppc/platforms/apus_pci.c
--- linux-2.4.21/arch/ppc/platforms/apus_pci.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/apus_pci.c	2003-08-01 13:34:29.000000000 +0000
@@ -33,7 +33,7 @@
 #define DPRINTK(a,b...)	printk(KERN_DEBUG "apus_pci: %s: " a, __FUNCTION__ , ## b)
 #else
 #define DPRINTK(a,b...)
-#endif 
+#endif
 
 /*
  * The _DEFINITIVE_ memory mapping/unmapping functions.
@@ -124,9 +124,9 @@
 }
 
 
-/* 
+/*
  * This is from pm2fb.c again
- * 
+ *
  * Check if PCI (B/CVisionPPC) is available, initialize it and set up
  * the pcibios_* pointers
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/chrp_setup.c linux-2.4.22-pre10/arch/ppc/platforms/chrp_setup.c
--- linux-2.4.21/arch/ppc/platforms/chrp_setup.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/chrp_setup.c	2003-08-01 13:32:07.000000000 +0000
@@ -232,7 +232,7 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* this is fine for chrp */
 	initrd_below_start_ok = 1;
-	
+
 	if (initrd_start)
 		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
 	else
@@ -277,14 +277,14 @@
 		if (p && (rate = *(unsigned long *)p->value) > 0) {
 			/*
 			 * The value is the number of times per minute.
-			 * For now assign the full workload here to cpu 0.  
+			 * For now assign the full workload here to cpu 0.
 			 *
 			 * We now split the rate and spread the heartbeats
 			 * when we kick secondary cpus so we can spread
-			 * the calls evenly.   
+			 * the calls evenly.
 			 */
 			ppc_md.heartbeat = chrp_event_scan;
-			
+
 			count = (60*HZ) / rate;
 			if (!count)        /* XXX insane */
 				count = 1;
@@ -309,7 +309,7 @@
 	call_rtas( "event-scan", 4, 1, &ret, 0xffffffff, 0,
 		   __pa(log), 1024 );
 }
-	
+
 void __chrp
 chrp_restart(char *cmd)
 {
@@ -433,7 +433,7 @@
 chrp_init_irq_8259(unsigned long intack)
 {
 	int i;
-	
+
 	ppc_md.get_irq = i8259_irq;
 	for (i = 0; i < NUM_8259_INTERRUPTS; i++)
 		irq_desc[i].handler = &i8259_pic;
@@ -445,7 +445,7 @@
 	struct device_node *np;
 	unsigned long intack = 0;
 	struct device_node *main_irq_ctrler = NULL;
-#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON)	
+#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON)
 	struct device_node *kbd;
 #endif
 
@@ -491,10 +491,10 @@
 void __init
 chrp_init2(void)
 {
- 
+
 	if (chrp_is_briq)
 		briq_SPOR = (unsigned int *)ioremap(0xff0000e8, 4);
-#ifdef CONFIG_NVRAM  
+#ifdef CONFIG_NVRAM
 /* Fix me: currently, a lot of pmac_nvram routines are marked __pmac, and
  * blindly calling pmac_nvram_init() on chrp cause bad results.
  * Among others, it cracks on briQ.
@@ -563,7 +563,7 @@
 		rs_table[0].baud_base = (7372800 / 16);
 		rs_table[1].baud_base = (7372800 / 16);
 	}
-#endif /* CONFIG_SERIAL */	
+#endif /* CONFIG_SERIAL */
 
 	ppc_md.setup_arch     = chrp_setup_arch;
 	ppc_md.show_percpuinfo = of_show_percpuinfo;
@@ -631,7 +631,7 @@
 
 	/*
 	 * Print the banner, then scroll down so boot progress
-	 * can be printed.  -- Cort 
+	 * can be printed.  -- Cort
 	 */
 	if ( ppc_md.progress ) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/chrp_smp.c linux-2.4.22-pre10/arch/ppc/platforms/chrp_smp.c
--- linux-2.4.21/arch/ppc/platforms/chrp_smp.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/chrp_smp.c	2003-08-01 13:32:39.000000000 +0000
@@ -44,7 +44,7 @@
  * call event-scan periodically, not always the same
  * one.  The event-scan function needs to be called a
  * total of rtas-event-scan-rate times a minute"
- * 
+ *
  * We must call on each cpu in on a regular basis
  * so that firmware can watch for cpu unique errors.
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/chrp_time.c linux-2.4.22-pre10/arch/ppc/platforms/chrp_time.c
--- linux-2.4.21/arch/ppc/platforms/chrp_time.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/chrp_time.c	2003-08-01 13:30:54.000000000 +0000
@@ -132,10 +132,10 @@
 
 	/* Since the UIP flag is set for about 2.2 ms and the clock
 	 * is typically written with a precision of 1 jiffy, trying
-	 * to obtain a precision better than a few milliseconds is 
+	 * to obtain a precision better than a few milliseconds is
 	 * an illusion. Only consistency is interesting, this also
 	 * allows to use the routine for /dev/rtc without a potential
-	 * 1 second kernel busy loop triggered by any reader of /dev/rtc. 
+	 * 1 second kernel busy loop triggered by any reader of /dev/rtc.
 	 */
 
 	for ( i = 0; i<1000000; i++) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/cpc700.h linux-2.4.22-pre10/arch/ppc/platforms/cpc700.h
--- linux-2.4.21/arch/ppc/platforms/cpc700.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/cpc700.h	2003-08-01 13:31:57.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * include/asm-ppc/cpc700.h
- * 
+ *
  * Header file for IBM CPC700 Host Bridge, et. al.
  *
  * Author: Mark A. Greer
@@ -85,7 +85,7 @@
  */
 extern struct hw_interrupt_type cpc700_pic;
 extern unsigned int cpc700_irq_assigns[32][2];
- 
+
 extern void __init cpc700_init_IRQ(void);
 extern int cpc700_get_irq(struct pt_regs *);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/cpc700_pic.c linux-2.4.22-pre10/arch/ppc/platforms/cpc700_pic.c
--- linux-2.4.21/arch/ppc/platforms/cpc700_pic.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/cpc700_pic.c	2003-08-01 13:31:53.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * arch/ppc/platforms/cpc700_pic.c
- * 
+ *
  * Interrupt controller support for IBM Spruce
  *
  * Authors: Mark Greer, Matt Porter, and Johnnie Peters
@@ -47,7 +47,7 @@
 
 		/* Know IRQ fits in entry 0 of ppc_cached_irq_mask[] */
 		ppc_cached_irq_mask[0] |= CPC700_UIC_IRQ_BIT(irq);
-		
+
 		CPC700_OUT_32(CPC700_UIC_UICER, ppc_cached_irq_mask[0]);
 	}
 	return;
@@ -128,10 +128,10 @@
 	tmp = CPC700_IN_32(CPC700_UIC_UICCR);
 	tmp |= CPC700_UIC_IRQ_BIT(irq);
 	CPC700_OUT_32(CPC700_UIC_UICCR, tmp);
-			
+
 	return;
 }
-	
+
 __init void
 cpc700_init_IRQ(void)
 {
@@ -179,7 +179,7 @@
 		irq++;
 		irq_test <<= 1;
 	} while (irq < NR_IRQS);
-		
+
 
 	if (irq == NR_IRQS)
 	    irq = 33;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/error_log.c linux-2.4.22-pre10/arch/ppc/platforms/error_log.c
--- linux-2.4.21/arch/ppc/platforms/error_log.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/error_log.c	2003-08-01 13:34:03.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  *  arch/ppc/kernel/error_log.c
- *  
+ *
  *  Copyright (c) 2000 Tilmann Bitterberg
  *  (tilmann@bitterberg.de)
  *
@@ -15,10 +15,10 @@
 #include "error_log.h"
 
 /* ****************************************************************** */
-/* 
+/*
  * EVENT-SCAN
  * The whole stuff below here doesn't take any action when it found
- * an error, it just prints as much information as possible and 
+ * an error, it just prints as much information as possible and
  * then its up to the user to decide what to do.
  *
  * Returns 0 if no errors were found
@@ -92,7 +92,7 @@
 #endif /* VERBOSE_ERRORS */
 };
 
-const char *_errlog_initiator[] = { 
+const char *_errlog_initiator[] = {
 	"Unknown or not applicable",
 	"CPU",
 	"PCI",
@@ -101,7 +101,7 @@
 	"Power management"
 };
 
-const char *_errlog_target[] = { 
+const char *_errlog_target[] = {
 	"Unknown or not applicable",
 	"CPU",
 	"PCI",
@@ -128,7 +128,7 @@
 		return 0;
 	}
 	if (error_log.version != 1)
-		printk(KERN_WARNING "Unknown version (%d), please implement me\n", 
+		printk(KERN_WARNING "Unknown version (%d), please implement me\n",
 				error_log.version);
 
 	switch (error_log.disposition) {
@@ -139,19 +139,19 @@
 			printk("We have a really serious Problem!\n");
 		case DISP_LIMITED_RECOVERY:
 			printk("Error classification\n");
-			printk("Severity  : %s\n", 
+			printk("Severity  : %s\n",
 					ppc_rtas_errorlog_check_severity (error_log));
-			printk("Initiator : %s\n", 
+			printk("Initiator : %s\n",
 					ppc_rtas_errorlog_check_initiator (error_log));
-			printk("Target    : %s\n", 
+			printk("Target    : %s\n",
 					ppc_rtas_errorlog_check_target (error_log));
-			printk("Type      : %s\n", 
+			printk("Type      : %s\n",
 					ppc_rtas_errorlog_check_type (error_log));
-			printk("Ext. log  : %s\n", 
+			printk("Ext. log  : %s\n",
 					ppc_rtas_errorlog_check_extended (error_log));
 			if (error_log.extended)
 				ppc_rtas_errorlog_disect_extended (logdata);
-			return 1;	
+			return 1;
 		default:
 			/* nothing */
 			break;
@@ -174,8 +174,8 @@
 		"uncorrectable ECC error",
 		"corrected ECC error"			/* 10 */
 	};
-	if (error_log.type == TYPE_EPOW) 
-		return "EPOW"; 
+	if (error_log.type == TYPE_EPOW)
+		return "EPOW";
 	if (error_log.type >= TYPE_PMGM_POWER_SW_ON)
 		return "PowerMGM Event (not handled right now)";
 	return _errlog_type[error_log.type];
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/error_log.h linux-2.4.22-pre10/arch/ppc/platforms/error_log.h
--- linux-2.4.21/arch/ppc/platforms/error_log.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/error_log.h	2003-08-01 13:34:03.000000000 +0000
@@ -45,7 +45,7 @@
 #define TYPE_ECC_UNCORR		0x09
 #define TYPE_ECC_CORR		0x0a
 #define TYPE_EPOW		0x40
-/* I don't add PowerMGM events right now, this is a different topic */ 
+/* I don't add PowerMGM events right now, this is a different topic */
 #define TYPE_PMGM_POWER_SW_ON	0x60
 #define TYPE_PMGM_POWER_SW_OFF	0x61
 #define TYPE_PMGM_LID_OPEN	0x62
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/gemini.h linux-2.4.22-pre10/arch/ppc/platforms/gemini.h
--- linux-2.4.21/arch/ppc/platforms/gemini.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/gemini.h	2003-08-01 13:33:06.000000000 +0000
@@ -2,7 +2,7 @@
  *  arch/ppc/platforms/gemini.h
  *
  *
- *  Onboard registers and descriptions for Synergy Microsystems' 
+ *  Onboard registers and descriptions for Synergy Microsystems'
  *  "Gemini" boards.
  *
  */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/gemini_pci.c linux-2.4.22-pre10/arch/ppc/platforms/gemini_pci.c
--- linux-2.4.21/arch/ppc/platforms/gemini_pci.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/gemini_pci.c	2003-08-01 13:32:16.000000000 +0000
@@ -92,7 +92,7 @@
 {
 	int i;
 	struct pci_dev *dev;
-	
+
 	pci_for_each_dev(dev) {
 		for(i = 0; i < 6; i++) {
 			if (dev->resource[i].flags & IORESOURCE_IO) {
@@ -109,7 +109,7 @@
 void __init gemini_find_bridges(void)
 {
 	struct pci_controller* hose;
-	
+
 	ppc_md.pcibios_fixup = gemini_pcibios_fixup;
 
 	hose = pcibios_alloc_controller();
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/gemini_prom.S linux-2.4.22-pre10/arch/ppc/platforms/gemini_prom.S
--- linux-2.4.21/arch/ppc/platforms/gemini_prom.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/gemini_prom.S	2003-08-01 13:30:46.000000000 +0000
@@ -40,7 +40,7 @@
 	isync
 #if 0
 	/* zero out the bats now that the MMU is off */
-prom_no_mmu:	
+prom_no_mmu:
 	li	r3,0
         mtspr   IBAT0U,r3
         mtspr   IBAT0L,r3
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/gemini_setup.c linux-2.4.22-pre10/arch/ppc/platforms/gemini_setup.c
--- linux-2.4.21/arch/ppc/platforms/gemini_setup.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/gemini_setup.c	2003-08-01 13:33:23.000000000 +0000
@@ -154,7 +154,7 @@
 	if (smp_processor_id()) {
 		static short ratelimit;
 		if (!ratelimit++)
-			printk(KERN_ERR "%s: unexpected heartbeat on cpu %d\n", 
+			printk(KERN_ERR "%s: unexpected heartbeat on cpu %d\n",
 					__FUNCTION__, smp_processor_id());
 		return;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/ibm405.h linux-2.4.22-pre10/arch/ppc/platforms/ibm405.h
--- linux-2.4.21/arch/ppc/platforms/ibm405.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/ibm405.h	2003-08-01 13:30:32.000000000 +0000
@@ -0,0 +1,332 @@
+/*
+ * ibm405.h
+ *
+ *	This was derived from the ppc4xx.h and contains
+ *	common 405 offsets
+ *
+ *      Armin Kuster akuster@pacbell.net
+ *      Jan, 2002
+ *
+ *
+ * Copyright 2002 MontaVista Softare Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *	Version 1.0 (02/01/17) - A. Kuster
+ *	Initial version	 - moved 405  specific out of the other core.h's
+ *
+ *	Version 1.0 (02/08/02) - A. Kuster
+ *	removed DCRN_UIC1_BASE to NP405L & H
+ *
+ *	Version 1.2 (05/29/02) - Akuster
+ *	removed DCRN_MALRXCTP2R etc, alread in ibmnp405.h
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_IBM405_H__
+#define __ASM_IBM405_H__
+
+#ifdef DCRN_BE_BASE
+#define DCRN_BEAR	(DCRN_BE_BASE + 0x0)	/* Bus Error Address Register */
+#define DCRN_BESR	(DCRN_BE_BASE + 0x1)	/* Bus Error Syndrome Register */
+#endif
+/* DCRN_BESR */
+#define BESR_DSES	0x80000000	/* Data-Side Error Status */
+#define BESR_DMES	0x40000000	/* DMA Error Status */
+#define BESR_RWS	0x20000000	/* Read/Write Status */
+#define BESR_ETMASK	0x1C000000	/* Error Type */
+#define ET_PROT	0
+#define ET_PARITY	1
+#define ET_NCFG	2
+#define ET_BUSERR	4
+#define ET_BUSTO	6
+
+/* Clock and power management shifts for emacs */
+#define IBM_CPM_EMMII	0	/* Shift value for MII */
+#define IBM_CPM_EMRX	1	/* Shift value for recv */
+#define IBM_CPM_EMTX	2	/* Shift value for MAC */
+
+#ifdef DCRN_CHCR_BASE
+#define DCRN_CHCR0	(DCRN_CHCR_BASE + 0x0)	/* Chip Control Register 1 */
+#define DCRN_CHCR1	(DCRN_CHCR_BASE + 0x1)	/* Chip Control Register 2 */
+#endif
+#define CHR1_PCIPW	0x00008000	/* PCI Int enable/Peripheral Write enable */
+
+#ifdef DCRN_CHPSR_BASE
+#define DCRN_CHPSR	(DCRN_CHPSR_BASE + 0x0)	/* Chip Pin Strapping */
+#endif
+
+#ifdef DCRN_CPMFR_BASE
+#define DCRN_CPMFR	(DCRN_CPMFR_BASE + 0x0)	/* CPM Force */
+#endif
+
+#ifdef DCRN_CPMSR_BASE
+#define DCRN_CPMSR	(DCRN_CPMSR_BASE + 0x0)	/* CPM Status */
+#define DCRN_CPMER	(DCRN_CPMSR_BASE + 0x1)	/* CPM Enable */
+#endif
+
+#ifdef DCRN_DCP0_BASE
+/* Decompression Controller Address */
+#define DCRN_DCP0_CFGADDR	(DCRN_DCP0_BASE + 0x0)
+/* Decompression Controller Data */
+#define DCRN_DCP0_CFGDATA	(DCRN_DCP0_BASE + 0x1)
+#else
+#define DCRN_DCP0_CFGADDR	0x0
+#define DCRN_DCP0_CFGDATA	0x0
+#endif
+
+#ifdef DCRN_DMA0_BASE
+/* DMA Channel Control Register 0 */
+#define DCRN_DMACR0	(DCRN_DMA0_BASE + 0x0)
+#define DCRN_DMACT0	(DCRN_DMA0_BASE + 0x1)	/* DMA Count Register 0 */
+/* DMA Destination Address Register 0 */
+#define DCRN_DMADA0	(DCRN_DMA0_BASE + 0x2)
+/* DMA Source Address Register 0 */
+#define DCRN_DMASA0	(DCRN_DMA0_BASE + 0x3)
+#ifdef DCRNCAP_DMA_CC
+/* DMA Chained Count Register 0 */
+#define DCRN_DMACC0	(DCRN_DMA0_BASE + 0x4)
+#endif
+#ifdef DCRNCAP_DMA_SG
+/* DMA Scatter/Gather Descriptor Addr 0 */
+#define DCRN_ASG0	(DCRN_DMA0_BASE + 0x4)
+#endif
+#endif
+
+#ifdef DCRN_DMA1_BASE
+/* DMA Channel Control Register 1 */
+#define DCRN_DMACR1	(DCRN_DMA1_BASE + 0x0)
+#define DCRN_DMACT1	(DCRN_DMA1_BASE + 0x1)	/* DMA Count Register 1 */
+/* DMA Destination Address Register 1 */
+#define DCRN_DMADA1	(DCRN_DMA1_BASE + 0x2)
+/* DMA Source Address Register 1 */
+#define DCRN_DMASA1	(DCRN_DMA1_BASE + 0x3)	/* DMA Source Address Register 1 */
+#ifdef DCRNCAP_DMA_CC
+/* DMA Chained Count Register 1 */
+#define DCRN_DMACC1	(DCRN_DMA1_BASE + 0x4)
+#endif
+#ifdef DCRNCAP_DMA_SG
+/* DMA Scatter/Gather Descriptor Addr 1 */
+#define DCRN_ASG1	(DCRN_DMA1_BASE + 0x4)
+#endif
+#endif
+
+#ifdef DCRN_DMA2_BASE
+#define DCRN_DMACR2	(DCRN_DMA2_BASE + 0x0)	/* DMA Channel Control Register 2 */
+#define DCRN_DMACT2	(DCRN_DMA2_BASE + 0x1)	/* DMA Count Register 2 */
+#define DCRN_DMADA2	(DCRN_DMA2_BASE + 0x2)	/* DMA Destination Address Register 2 */
+#define DCRN_DMASA2	(DCRN_DMA2_BASE + 0x3)	/* DMA Source Address Register 2 */
+#ifdef DCRNCAP_DMA_CC
+#define DCRN_DMACC2	(DCRN_DMA2_BASE + 0x4)	/* DMA Chained Count Register 2 */
+#endif
+#ifdef DCRNCAP_DMA_SG
+#define DCRN_ASG2	(DCRN_DMA2_BASE + 0x4)	/* DMA Scatter/Gather Descriptor Addr 2 */
+#endif
+#endif
+
+#ifdef DCRN_DMA3_BASE
+#define DCRN_DMACR3	(DCRN_DMA3_BASE + 0x0)	/* DMA Channel Control Register 3 */
+#define DCRN_DMACT3	(DCRN_DMA3_BASE + 0x1)	/* DMA Count Register 3 */
+#define DCRN_DMADA3	(DCRN_DMA3_BASE + 0x2)	/* DMA Destination Address Register 3 */
+#define DCRN_DMASA3	(DCRN_DMA3_BASE + 0x3)	/* DMA Source Address Register 3 */
+#ifdef DCRNCAP_DMA_CC
+#define DCRN_DMACC3	(DCRN_DMA3_BASE + 0x4)	/* DMA Chained Count Register 3 */
+#endif
+#ifdef DCRNCAP_DMA_SG
+#define DCRN_ASG3	(DCRN_DMA3_BASE + 0x4)	/* DMA Scatter/Gather Descriptor Addr 3 */
+#endif
+#endif
+
+#ifdef DCRN_DMASR_BASE
+#define DCRN_DMASR	(DCRN_DMASR_BASE + 0x0)	/* DMA Status Register */
+#ifdef DCRNCAP_DMA_SG
+#define DCRN_ASGC	(DCRN_DMASR_BASE + 0x3)	/* DMA Scatter/Gather Command */
+/* don't know if these two registers always exist if scatter/gather exists */
+#define DCRN_POL	(DCRN_DMASR_BASE + 0x6)	/* DMA Polarity Register */
+#define DCRN_SLP	(DCRN_DMASR_BASE + 0x5)	/* DMA Sleep Register */
+#endif
+#endif
+
+#ifdef DCRN_EBC_BASE
+#define DCRN_EBCCFGADR	(DCRN_EBC_BASE + 0x0)	/* Peripheral Controller Address */
+#define DCRN_EBCCFGDATA	(DCRN_EBC_BASE + 0x1)	/* Peripheral Controller Data */
+#endif
+
+#ifdef DCRN_EXIER_BASE
+#define DCRN_EXIER	(DCRN_EXIER_BASE + 0x0)	/* External Interrupt Enable Register */
+#endif
+
+#ifdef DCRN_EXISR_BASE
+#define DCRN_EXISR	(DCRN_EXISR_BASE + 0x0)	/* External Interrupt Status Register */
+#endif
+
+#define EXIER_CIE	0x80000000	/* Critical Interrupt Enable */
+#define EXIER_SRIE	0x08000000	/* Serial Port Rx Int. Enable */
+#define EXIER_STIE	0x04000000	/* Serial Port Tx Int. Enable */
+#define EXIER_JRIE	0x02000000	/* JTAG Serial Port Rx Int. Enable */
+#define EXIER_JTIE	0x01000000	/* JTAG Serial Port Tx Int. Enable */
+#define EXIER_D0IE	0x00800000	/* DMA Channel 0 Interrupt Enable */
+#define EXIER_D1IE	0x00400000	/* DMA Channel 1 Interrupt Enable */
+#define EXIER_D2IE	0x00200000	/* DMA Channel 2 Interrupt Enable */
+#define EXIER_D3IE	0x00100000	/* DMA Channel 3 Interrupt Enable */
+#define EXIER_E0IE	0x00000010	/* External Interrupt 0 Enable */
+#define EXIER_E1IE	0x00000008	/* External Interrupt 1 Enable */
+#define EXIER_E2IE	0x00000004	/* External Interrupt 2 Enable */
+#define EXIER_E3IE	0x00000002	/* External Interrupt 3 Enable */
+#define EXIER_E4IE	0x00000001	/* External Interrupt 4 Enable */
+
+#ifdef DCRN_IOCR_BASE
+#define DCRN_IOCR	(DCRN_IOCR_BASE + 0x0)	/* Input/Output Configuration Register */
+#endif
+#define IOCR_E0TE	0x80000000
+#define IOCR_E0LP	0x40000000
+#define IOCR_E1TE	0x20000000
+#define IOCR_E1LP	0x10000000
+#define IOCR_E2TE	0x08000000
+#define IOCR_E2LP	0x04000000
+#define IOCR_E3TE	0x02000000
+#define IOCR_E3LP	0x01000000
+#define IOCR_E4TE	0x00800000
+#define IOCR_E4LP	0x00400000
+#define IOCR_EDT	0x00080000
+#define IOCR_SOR	0x00040000
+#define IOCR_EDO	0x00008000
+#define IOCR_2XC	0x00004000
+#define IOCR_ATC	0x00002000
+#define IOCR_SPD	0x00001000
+#define IOCR_BEM	0x00000800
+#define IOCR_PTD	0x00000400
+#define IOCR_ARE	0x00000080
+#define IOCR_DRC	0x00000020
+#define IOCR_RDM(x)	(((x) & 0x3) << 3)
+#define IOCR_TCS	0x00000004
+#define IOCR_SCS	0x00000002
+#define IOCR_SPC	0x00000001
+
+#define DCRN_MALCR(base)	(base + 0x0)	/* MAL Configuration */
+#define DCRN_MALDBR(base)	((base) + 0x3)	/* Debug Register */
+#define DCRN_MALESR(base)	((base) + 0x1)	/* Error Status */
+#define DCRN_MALIER(base)	((base) + 0x2)	/* Interrupt Enable */
+#define DCRN_MALTXCARR(base)	((base) + 0x5)	/* TX Channed Active Reset Register */
+#define DCRN_MALTXCASR(base)	((base) + 0x4)	/* TX Channel Active Set Register */
+#define DCRN_MALTXDEIR(base)	((base) + 0x7)	/* Tx Descriptor Error Interrupt */
+#define DCRN_MALTXEOBISR(base)	((base) + 0x6)	/* Tx End of Buffer Interrupt Status */
+#define DCRN_MALRXCARR(base)	((base) + 0x11)	/* RX Channed Active Reset Register */
+#define DCRN_MALRXCASR(base)	((base) + 0x10)	/* RX Channel Active Set Register */
+#define DCRN_MALRXDEIR(base)	((base) + 0x13)	/* Rx Descriptor Error Interrupt */
+#define DCRN_MALRXEOBISR(base)	((base) + 0x12)	/* Rx End of Buffer Interrupt Status */
+#define DCRN_MALRXCTP0R(base)	((base) + 0x40)	/* Channel Rx 0 Channel Table Pointer */
+#define DCRN_MALRXCTP1R(base)	((base) + 0x41)	/* Channel Rx 1 Channel Table Pointer */
+#define DCRN_MALTXCTP0R(base)	((base) + 0x20)	/* Channel Tx 0 Channel Table Pointer */
+#define DCRN_MALTXCTP1R(base)	((base) + 0x21)	/* Channel Tx 1 Channel Table Pointer */
+#define DCRN_MALTXCTP2R(base)	((base) + 0x22)	/* Channel Tx 2 Channel Table Pointer */
+#define DCRN_MALTXCTP3R(base)	((base) + 0x23)	/* Channel Tx 3 Channel Table Pointer */
+#define DCRN_MALRCBS0(base)	((base) + 0x60)	/* Channel Rx 0 Channel Buffer Size */
+#define DCRN_MALRCBS1(base)	((base) + 0x61)	/* Channel Rx 1 Channel Buffer Size */
+
+ /* DCRN_MALCR */
+#define MALCR_MMSR		0x80000000	/* MAL Software reset */
+#define MALCR_PLBP_1		0x00400000	/* MAL reqest priority: */
+#define MALCR_PLBP_2		0x00800000	/* lowsest is 00 */
+#define MALCR_PLBP_3		0x00C00000	/* highest */
+#define MALCR_GA		0x00200000	/* Guarded Active Bit */
+#define MALCR_OA		0x00100000	/* Ordered Active Bit */
+#define MALCR_PLBLE		0x00080000	/* PLB Lock Error Bit */
+#define MALCR_PLBLT_1		0x00040000	/* PLB Latency Timer */
+#define MALCR_PLBLT_2 		0x00020000
+#define MALCR_PLBLT_3		0x00010000
+#define MALCR_PLBLT_4		0x00008000
+#define MALCR_PLBLT_DEFAULT	0x00078000	/* JSP: Is this a valid default?? */
+#define MALCR_PLBB		0x00004000	/* PLB Burst Deactivation Bit */
+#define MALCR_OPBBL		0x00000080	/* OPB Lock Bit */
+#define MALCR_EOPIE		0x00000004	/* End Of Packet Interrupt Enable */
+#define MALCR_LEA		0x00000002	/* Locked Error Active */
+#define MALCR_MSD		0x00000001	/* MAL Scroll Descriptor Bit */
+/* DCRN_MALESR */
+#define MALESR_EVB		0x80000000	/* Error Valid Bit */
+#define MALESR_CIDRX		0x40000000	/* Channel ID Receive */
+#define MALESR_DE		0x00100000	/* Descriptor Error */
+#define MALESR_OEN		0x00080000	/* OPB Non-Fullword Error */
+#define MALESR_OTE		0x00040000	/* OPB Timeout Error */
+#define MALESR_OSE		0x00020000	/* OPB Slave Error */
+#define MALESR_PEIN		0x00010000	/* PLB Bus Error Indication */
+#define MALESR_DEI		0x00000010	/* Descriptor Error Interrupt */
+#define MALESR_ONEI		0x00000008	/* OPB Non-Fullword Error Interrupt */
+#define MALESR_OTEI		0x00000004	/* OPB Timeout Error Interrupt */
+#define MALESR_OSEI		0x00000002	/* OPB Slace Error Interrupt */
+#define MALESR_PBEI		0x00000001	/* PLB Bus Error Interrupt */
+/* DCRN_MALIER */
+#define MALIER_DE		0x00000010	/* Descriptor Error Interrupt Enable */
+#define MALIER_NE		0x00000008	/* OPB Non-word Transfer Int Enable */
+#define MALIER_TE		0x00000004	/* OPB Time Out Error Interrupt Enable */
+#define MALIER_OPBE		0x00000002	/* OPB Slave Error Interrupt Enable */
+#define MALIER_PLBE		0x00000001	/* PLB Error Interrupt Enable */
+/* DCRN_MALTXEOBISR */
+#define MALOBISR_CH0		0x80000000	/* EOB channel 1 bit */
+#define MALOBISR_CH2		0x40000000	/* EOB channel 2 bit */
+
+#ifdef DCRN_PLB0_BASE
+#define DCRN_PLB0_BESR	(DCRN_PLB0_BASE + 0x0)
+#define DCRN_PLB0_BEAR	(DCRN_PLB0_BASE + 0x2)
+/* doesn't exist on stb03xxx? */
+#define DCRN_PLB0_ACR	(DCRN_PLB0_BASE + 0x3)
+#endif
+
+#ifdef DCRN_PLB1_BASE
+#define DCRN_PLB1_BESR	(DCRN_PLB1_BASE + 0x0)
+#define DCRN_PLB1_BEAR	(DCRN_PLB1_BASE + 0x1)
+/* doesn't exist on stb03xxx? */
+#define DCRN_PLB1_ACR	(DCRN_PLB1_BASE + 0x2)
+#endif
+
+#ifdef DCRN_PLLMR_BASE
+#define DCRN_PLLMR	(DCRN_PLLMR_BASE + 0x0)	/* PL1 Mode */
+#endif
+
+#ifdef DCRN_POB0_BASE
+#define DCRN_POB0_BESR0	(DCRN_POB0_BASE + 0x0)
+#define DCRN_POB0_BEAR	(DCRN_POB0_BASE + 0x2)
+#define DCRN_POB0_BESR1	(DCRN_POB0_BASE + 0x4)
+#endif
+
+#define DCRN_UIC_SR(base)	(base + 0x0)
+#define DCRN_UIC_ER(base)	(base + 0x2)
+#define DCRN_UIC_CR(base)	(base + 0x3)
+#define DCRN_UIC_PR(base)	(base + 0x4)
+#define DCRN_UIC_TR(base)	(base + 0x5)
+#define DCRN_UIC_MSR(base)	(base + 0x6)
+#define DCRN_UIC_VR(base)	(base + 0x7)
+#define DCRN_UIC_VCR(base)	(base + 0x8)
+
+#ifdef DCRN_SDRAM0_BASE
+#define DCRN_SDRAM0_CFGADDR	(DCRN_SDRAM0_BASE + 0x0)	/* Memory Controller Address */
+#define DCRN_SDRAM0_CFGDATA	(DCRN_SDRAM0_BASE + 0x1)	/* Memory Controller Data */
+#endif
+
+#ifdef DCRN_OCM0_BASE
+#define DCRN_OCMISARC	(DCRN_OCM0_BASE + 0x0)	/* OCM Instr Side Addr Range Compare */
+#define DCRN_OCMISCR	(DCRN_OCM0_BASE + 0x1)	/* OCM Instr Side Control */
+#define DCRN_OCMDSARC	(DCRN_OCM0_BASE + 0x2)	/* OCM Data Side Addr Range Compare */
+#define DCRN_OCMDSCR	(DCRN_OCM0_BASE + 0x3)	/* OCM Data Side Control */
+#endif
+
+#endif				/* __ASM_IBM405_H__ */
+#endif				/* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/ibm405gp.c linux-2.4.22-pre10/arch/ppc/platforms/ibm405gp.c
--- linux-2.4.21/arch/ppc/platforms/ibm405gp.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/ibm405gp.c	2003-08-01 13:34:22.000000000 +0000
@@ -0,0 +1,107 @@
+/*
+ *
+ *    Copyright 2000-2001 MontaVista Software Inc.
+ *      Original author: Armin Kuster akuster@mvista.com
+ *
+ *    Module name: ibm405gp.c
+ *
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/threads.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <platforms/ibm405gp.h>
+#include <asm/ibm4xx.h>
+#include <asm/ocp.h>
+
+static struct ocp_func_emac_data ibm405gp_emac0_def = {
+	.zmii_idx	= -1,		/* ZMII device index */
+	.zmii_mux	= 0,		/* ZMII input of this EMAC */
+	.mal_idx	= 0,		/* MAL device index */
+	.mal_rx_chan	= 0,		/* MAL rx channel number */
+	.mal_tx1_chan	= 0,		/* MAL tx channel 1 number */
+	.mal_tx2_chan	= 1,		/* MAL tx channel 2 number */
+	.wol_irq	= BL_MAC_WOL,	/* WOL interrupt number */
+	.mdio_idx	= -1,		/* No shared MDIO */
+};
+
+static struct ocp_func_mal_data ibm405gp_mal0_def = {
+	.num_tx_chans	= 2*EMAC_NUMS,	/* Number of TX channels */
+	.num_rx_chans	= EMAC_NUMS,	/* Number of RX channels */
+};
+
+struct ocp_def core_ocp[]  __initdata = {
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_OPB,
+	  .index	= 0,
+	  .paddr	= OPB_BASE_START,
+	  .irq		= OCP_IRQ_NA,
+	  .pm		= OCP_CPM_NA,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_16550,
+	  .index	= 0,
+	  .paddr	= UART0_IO_BASE,
+	  .irq		= UART0_INT,
+	  .pm		= IBM_CPM_UART0
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_16550,
+	  .index	= 1,
+	  .paddr	= UART1_IO_BASE,
+	  .irq		= UART1_INT,
+	  .pm		= IBM_CPM_UART1
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_IIC,
+	  .paddr	= IIC0_BASE,
+	  .irq		= IIC0_IRQ,
+	  .pm		= IBM_CPM_IIC0
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_GPIO,
+	  .paddr	= GPIO0_BASE,
+	  .irq		= OCP_IRQ_NA,
+	  .pm		= IBM_CPM_GPIO0
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_MAL,
+	  .paddr	= OCP_PADDR_NA,
+	  .irq		= OCP_IRQ_NA,
+	  .pm		= OCP_CPM_NA,
+	  .additions	= &ibm405gp_mal0_def,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_EMAC,
+	  .index	= 0,
+	  .paddr	= EMAC0_BASE,
+	  .irq		= BL_MAC_ETH0,
+	  .pm		= IBM_CPM_EMAC0,
+	  .additions	= &ibm405gp_emac0_def,
+	},
+	{ .vendor	= OCP_VENDOR_INVALID
+	}
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/ibm405gp.h linux-2.4.22-pre10/arch/ppc/platforms/ibm405gp.h
--- linux-2.4.21/arch/ppc/platforms/ibm405gp.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/ibm405gp.h	2003-08-01 13:30:57.000000000 +0000
@@ -0,0 +1,193 @@
+/*
+ * ibm405gp.h
+ *
+ *	This was derived from the ppc4xx.h and all 405GP specific
+ *	definition and board inclusions were moved here.
+ *
+ *      Original author: Armin Kuster akuster@mvista.com
+ *      Oct, 2001
+ *
+ *
+ * Copyright 2001 MontaVista Softare Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_IBM405GP_H__
+#define __ASM_IBM405GP_H__
+
+#include <linux/config.h>
+
+/* ibm405.h is included at the bottom of this file */
+
+/* PCI
+ * PCI Bridge config reg definitions
+ * see 17-19 of manual
+ */
+
+#define PPC405_PCI_CONFIG_ADDR	0xeec00000
+#define PPC405_PCI_CONFIG_DATA	0xeec00004
+
+#define PPC405_PCI_PHY_MEM_BASE	0x80000000	/* hose_a->pci_mem_offset */
+						/* setbat */
+#define PPC405_PCI_MEM_BASE	PPC405_PCI_PHY_MEM_BASE	/* setbat */
+#define PPC405_PCI_PHY_IO_BASE	0xe8000000	/* setbat */
+#define PPC405_PCI_IO_BASE	PPC405_PCI_PHY_IO_BASE	/* setbat */
+
+#define PPC405_PCI_LOWER_MEM	0x80000000	/* hose_a->mem_space.start */
+#define PPC405_PCI_UPPER_MEM	0xBfffffff	/* hose_a->mem_space.end */
+#define PPC405_PCI_LOWER_IO	0x00000000	/* hose_a->io_space.start */
+#define PPC405_PCI_UPPER_IO	0x0000ffff	/* hose_a->io_space.end */
+
+#define PPC405_ISA_IO_BASE	PPC405_PCI_IO_BASE
+
+#define PPC4xx_PCI_IO_PADDR	((uint)PPC405_PCI_PHY_IO_BASE)
+#define PPC4xx_PCI_IO_VADDR	PPC4xx_PCI_IO_PADDR
+#define PPC4xx_PCI_IO_SIZE	((uint)64*1024)
+#define PPC4xx_PCI_CFG_PADDR	((uint)PPC405_PCI_CONFIG_ADDR)
+#define PPC4xx_PCI_CFG_VADDR	PPC4xx_PCI_CFG_PADDR
+#define PPC4xx_PCI_CFG_SIZE	((uint)4*1024)
+#define PPC4xx_PCI_LCFG_PADDR	((uint)0xef400000)
+#define PPC4xx_PCI_LCFG_VADDR	PPC4xx_PCI_LCFG_PADDR
+#define PPC4xx_PCI_LCFG_SIZE	((uint)4*1024)
+#define PPC4xx_ONB_IO_PADDR	((uint)0xef600000)
+#define PPC4xx_ONB_IO_VADDR	PPC4xx_ONB_IO_PADDR
+#define PPC4xx_ONB_IO_SIZE	((uint)4*1024)
+
+#define OPB_BASE_START	0x40000000
+#define EBIU_BASE_START	0xF0100000
+
+/* serial port defines */
+#define RS_TABLE_SIZE	2
+
+#define UART0_INT	0
+#define UART1_INT	1
+
+#define PCIL0_BASE	0xEF400000
+#define UART0_IO_BASE	0xEF600300
+#define UART1_IO_BASE	0xEF600400
+#define IIC0_BASE	0xEF600500
+#define OPB0_BASE	0xEF600600
+#define GPIO0_BASE	0xEF600700
+#define EMAC0_BASE	0xEF600800
+#define BL_MAC_WOL	9	/* WOL */
+#define BL_MAL_SERR	10	/* MAL SERR */
+#define BL_MAL_TXDE	13	/* MAL TXDE */
+#define BL_MAL_RXDE	14	/* MAL RXDE */
+#define BL_MAL_TXEOB	11	/* MAL TX EOB */
+#define BL_MAL_RXEOB	12	/* MAL RX EOB */
+#define BL_MAC_ETH0	15	/* MAC */
+
+#define EMAC_NUMS	1
+#define IIC0_IRQ	2
+#define IIC1_IRQ	0
+
+#define IIC_OWN		0x55
+#define IIC_CLOCK	50
+#define BD_EMAC_ADDR(e,i) bi_enetaddr[i]
+
+#define STD_UART_OP(num)					\
+	{ 0, BASE_BAUD, 0, UART##num##_INT,			\
+		(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),	\
+		iomem_base: (u8 *)UART##num##_IO_BASE,		\
+		io_type: SERIAL_IO_MEM},
+
+#if defined(CONFIG_UART0_TTYS0)
+#define SERIAL_DEBUG_IO_BASE	UART0_IO_BASE
+#define SERIAL_PORT_DFNS	\
+	STD_UART_OP(0)		\
+	STD_UART_OP(1)
+#endif
+
+#if defined(CONFIG_UART0_TTYS1)
+#define SERIAL_DEBUG_IO_BASE	UART1_IO_BASE
+#define SERIAL_PORT_DFNS	\
+	STD_UART_OP(1)		\
+	STD_UART_OP(0)
+#endif
+
+/* DCR defines */
+#define DCRN_CHCR_BASE		0x0B1
+#define DCRN_CHPSR_BASE		0x0B4
+#define DCRN_CPMSR_BASE		0x0B8
+#define DCRN_CPMFR_BASE		0x0BA
+
+#define CHR0_U0EC	0x00000080	/* Select external clock for UART0 */
+#define CHR0_U1EC	0x00000040	/* Select external clock for UART1 */
+#define CHR0_UDIV	0x0000003E	/* UART internal clock divisor */
+#define CHR1_CETE	0x00800000	/* CPU external timer enable */
+
+#define DCRN_CHPSR_BASE         0x0B4
+#define  PSR_PLL_FWD_MASK        0xC0000000
+#define  PSR_PLL_FDBACK_MASK     0x30000000
+#define  PSR_PLL_TUNING_MASK     0x0E000000
+#define  PSR_PLB_CPU_MASK        0x01800000
+#define  PSR_OPB_PLB_MASK        0x00600000
+#define  PSR_PCI_PLB_MASK        0x00180000
+#define  PSR_EB_PLB_MASK         0x00060000
+#define  PSR_ROM_WIDTH_MASK      0x00018000
+#define  PSR_ROM_LOC             0x00004000
+#define  PSR_PCI_ASYNC_EN        0x00001000
+#define  PSR_PCI_ARBIT_EN        0x00000400
+
+#define IBM_CPM_IIC0		0x80000000	/* IIC interface */
+#define IBM_CPM_PCI		0x40000000	/* PCI bridge */
+#define IBM_CPM_CPU		0x20000000	/* processor core */
+#define IBM_CPM_DMA		0x10000000	/* DMA controller */
+#define IBM_CPM_OPB		0x08000000	/* PLB to OPB bridge */
+#define IBM_CPM_DCP		0x04000000	/* CodePack */
+#define IBM_CPM_EBC		0x02000000	/* ROM/SRAM peripheral controller */
+#define IBM_CPM_SDRAM0		0x01000000	/* SDRAM memory controller */
+#define IBM_CPM_PLB		0x00800000	/* PLB bus arbiter */
+#define IBM_CPM_GPIO0		0x00400000	/* General Purpose IO (??) */
+#define IBM_CPM_UART0		0x00200000	/* serial port 0 */
+#define IBM_CPM_UART1		0x00100000	/* serial port 1 */
+#define IBM_CPM_UIC		0x00080000	/* Universal Interrupt Controller */
+#define IBM_CPM_TMRCLK		0x00040000	/* CPU timers */
+#define IBM_CPM_EMAC0		0x00020000	/* on-chip ethernet MM unit */
+#define DFLT_IBM4xx_PM		~(IBM_CPM_PCI | IBM_CPM_CPU | IBM_CPM_DMA \
+					| IBM_CPM_OPB | IBM_CPM_EBC \
+					| IBM_CPM_SDRAM0 | IBM_CPM_PLB \
+					| IBM_CPM_UIC | IBM_CPM_TMRCLK)
+
+#define DCRN_DMA0_BASE		0x100
+#define DCRN_DMA1_BASE		0x108
+#define DCRN_DMA2_BASE		0x110
+#define DCRN_DMA3_BASE		0x118
+#define DCRNCAP_DMA_SG		1	/* have DMA scatter/gather capability */
+#define DCRN_DMASR_BASE		0x120
+#define DCRN_EBC_BASE		0x012
+#define DCRN_DCP0_BASE		0x014
+#define DCRN_MAL_BASE		0x180
+#define DCRN_OCM0_BASE		0x018
+#define DCRN_PLB0_BASE		0x084
+#define DCRN_PLLMR_BASE		0x0B0
+#define DCRN_POB0_BASE		0x0A0
+#define DCRN_SDRAM0_BASE	0x010
+#define DCRN_UIC0_BASE		0x0C0
+#define UIC0 DCRN_UIC0_BASE
+
+#include <platforms/ibm405.h>
+
+#endif				/* __ASM_IBM405GP_H__ */
+#endif				/* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/ibm_ocp.h linux-2.4.22-pre10/arch/ppc/platforms/ibm_ocp.h
--- linux-2.4.21/arch/ppc/platforms/ibm_ocp.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/ibm_ocp.h	2003-08-01 13:32:31.000000000 +0000
@@ -0,0 +1,152 @@
+/*
+ * arch/ppc/platforms/ibm_ocp.h
+ *
+ *	Definitions for the on-chip peripherals on the IBM
+ *	PPC405GP embedded processor.
+ *
+ * Copyright 2001 MontaVista Softare Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_IBM_OCP_H__
+#define __ASM_IBM_OCP_H__
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+//
+// TODO: DEPRECATE THIS FILE !
+//
+
+ /* PCI 32 */
+
+struct pmm_regs {
+	u32 la;
+	u32 ma;
+	u32 pcila;
+	u32 pciha;
+};
+
+typedef struct pcil0_regs {
+	struct pmm_regs pmm[3];
+	u32 ptm1ms;
+	u32 ptm1la;
+	u32 ptm2ms;
+	u32 ptm2la;
+} pci0_t;
+
+/* Serial Ports */
+
+#define thr rbr
+#define iir fcr
+#define dll rbr
+#define dlm ier
+
+typedef struct NS16550 {
+	u8 rbr;			/* 0 */
+	u8 ier;			/* 1 */
+	u8 fcr;			/* 2 */
+	u8 lcr;			/* 3 */
+	u8 mcr;			/* 4 */
+	u8 lsr;			/* 5 */
+	u8 msr;			/* 6 */
+	u8 scr;			/* 7 */
+} uart_t;
+
+/* I2c */
+typedef struct iic_regs {
+	u16 mdbuf;
+	u16 sbbuf;
+	u8 lmadr;
+	u8 hmadr;
+	u8 cntl;
+	u8 mdcntl;
+	u8 sts;
+	u8 extsts;
+	u8 lsadr;
+	u8 hsadr;
+	u8 clkdiv;
+	u8 intmsk;
+	u8 xfrcnt;
+	u8 xtcntlss;
+	u8 directcntl;
+} iic_t;
+
+/* OPB arbiter */
+typedef struct opb {
+	u8 pr;
+	u8 cr;
+} opb_t;
+
+/* General purpose i/o */
+
+typedef struct gpio_regs {
+	u32 or;
+	u32 tcr;
+	u32 pad[4];
+	u32 odr;
+	u32 ir;
+} gpio_t;
+
+/* Structure of the memory mapped IDE control.
+*/
+typedef struct ide_regs {
+	unsigned int si_stat;	/* IDE status */
+	unsigned int si_intenable;	/* IDE interrupt enable */
+	unsigned int si_control;	/* IDE control */
+	unsigned int pad0[0x3d];
+	unsigned int si_c0rt;	/* Chan 0 Register transfer timing */
+	unsigned int si_c0fpt;	/* Chan 0 Fast PIO transfer timing */
+	unsigned int si_c0timo;	/* Chan 0 timeout */
+	unsigned int pad1[2];
+	unsigned int si_c0d0u;	/* Chan 0 UDMA transfer timing */
+#define si_c0d0m si_c0d0u	/* Chan 0 Multiword DMA timing */
+	unsigned int pad2;
+	unsigned int si_c0d1u;	/* Chan 0 dev 1 UDMA timing */
+#define si_c0d1m si_c0d1u	/* Chan 0 dev 1 Multiword DMA timing */
+	unsigned int si_c0c;	/* Chan 0 Control */
+	unsigned int si_c0s0;	/* Chan 0 Status 0 */
+	unsigned int si_c0ie;	/* Chan 0 Interrupt Enable */
+	unsigned int si_c0s1;	/* Chan 0 Status 0 */
+	unsigned int pad4[4];
+	unsigned int si_c0dcm;	/* Chan 0 DMA Command */
+	unsigned int si_c0tb;	/* Chan 0 PRD Table base address */
+	unsigned int si_c0dct;	/* Chan 0 DMA Count */
+	unsigned int si_c0da;	/* Chan 0 DMA Address */
+	unsigned int si_c0sr;	/* Chan 0 Slew Rate Output Control */
+	unsigned char pad5[0xa2];
+	unsigned short si_c0adc;	/* Chan 0 Alt status/control */
+	unsigned char si_c0d;	/* Chan 0 data */
+	unsigned char si_c0ef;	/* Chan 0 error/features */
+	unsigned char si_c0sct;	/* Chan 0 sector count */
+	unsigned char si_c0sn;	/* Chan 0 sector number */
+	unsigned char si_c0cl;	/* Chan 0 cylinder low */
+	unsigned char si_c0ch;	/* Chan 0 cylinder high */
+	unsigned char si_c0dh;	/* Chan 0 device/head */
+	unsigned char si_c0scm;	/* Chan 0 status/command */
+} ide_t;
+
+#endif				/* __ASSEMBLY__ */
+#endif				/* __ASM_IBM_OCP_H__ */
+#endif				/* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/lopec_pci.c linux-2.4.22-pre10/arch/ppc/platforms/lopec_pci.c
--- linux-2.4.21/arch/ppc/platforms/lopec_pci.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/lopec_pci.c	2003-08-01 13:32:02.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * arch/ppc/platforms/lopec_pci.c
- * 
+ *
  * PCI setup routines for the Motorola LoPEC.
  *
  * Author: Dan Cox
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/lopec_setup.c linux-2.4.22-pre10/arch/ppc/platforms/lopec_setup.c
--- linux-2.4.21/arch/ppc/platforms/lopec_setup.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/lopec_setup.c	2003-08-01 13:32:22.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * arch/ppc/platforms/lopec_setup.c
- * 
+ *
  * Setup routines for the Motorola LoPEC.
  *
  * Author: Dan Cox
@@ -48,7 +48,7 @@
 #include <asm/keyboard.h>
 #include <asm/prep_nvram.h>
 #include <asm/serial.h>
-  
+
 extern char saved_command_line[];
 extern void lopec_find_bridges(void);
 
@@ -314,7 +314,7 @@
 	/* Assume early_serial_setup() doesn't modify serial_req */
 	serial_req.line = 1;
 	serial_req.port = 1;
-	serial_req.irq = UART1_INT; 
+	serial_req.irq = UART1_INT;
 	serial_req.iomem_base = ioremap(UART1_PORT, 8);
 
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
@@ -327,7 +327,7 @@
 
 	serial_req.line = 2;
 	serial_req.port = 2;
-	serial_req.irq = UART2_INT; 
+	serial_req.irq = UART2_INT;
 	serial_req.iomem_base = ioremap(UART2_PORT, 8);
 
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
@@ -372,7 +372,7 @@
 #endif
 
 #ifdef CONFIG_PPCBUG_NVRAM
-	/* Read in NVRAM data */ 
+	/* Read in NVRAM data */
 	init_prep_nvram();
 
 	/* if no bootargs, look in NVRAM */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pal4.h linux-2.4.22-pre10/arch/ppc/platforms/pal4.h
--- linux-2.4.21/arch/ppc/platforms/pal4.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pal4.h	2003-08-01 13:34:18.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * arch/ppc/platforms/pal4.h
- * 
+ *
  * Definitions for SBS Palomar IV board
  *
  * Author: Dan Cox
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pal4_pci.c linux-2.4.22-pre10/arch/ppc/platforms/pal4_pci.c
--- linux-2.4.21/arch/ppc/platforms/pal4_pci.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pal4_pci.c	2003-08-01 13:32:22.000000000 +0000
@@ -1,9 +1,9 @@
 /*
  * arch/ppc/platforms/pal4_pci.c
- * 
+ *
  * PCI support for SBS Palomar IV
  *
- * Author: Dan Cox 
+ * Author: Dan Cox
  *
  * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
  * the terms of the GNU General Public License version 2.  This program
@@ -49,7 +49,7 @@
 
 	/* Could snatch these from the CPC700.... */
 	pci_init_resource(&hose->io_resource,
-			  0x0, 
+			  0x0,
 			  0x03ffffff,
 			  IORESOURCE_IO,
 			  "PCI host bridge");
@@ -65,10 +65,10 @@
 	hose->mem_space.start = 0x90000000;
 	hose->mem_space.end = 0x9fffffff;
 	hose->io_base_virt = (void *) 0xf8000000;
-	
+
 	setup_indirect_pci(hose, CPC700_PCI_CONFIG_ADDR,
 			   CPC700_PCI_CONFIG_DATA);
-	
+
 	hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
 
 	ppc_md.pci_swizzle = common_swizzle;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pal4_serial.h linux-2.4.22-pre10/arch/ppc/platforms/pal4_serial.h
--- linux-2.4.21/arch/ppc/platforms/pal4_serial.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pal4_serial.h	2003-08-01 13:30:54.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * arch/ppc/platforms/pal4_serial.h
- * 
- * Definitions for SBS PalomarIV serial support 
+ *
+ * Definitions for SBS PalomarIV serial support
  *
  * Author: Dan Cox
  *
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pal4_setup.c linux-2.4.22-pre10/arch/ppc/platforms/pal4_setup.c
--- linux-2.4.21/arch/ppc/platforms/pal4_setup.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pal4_setup.c	2003-08-01 13:31:47.000000000 +0000
@@ -133,7 +133,7 @@
 {
 	unsigned long l2;
 
-	TODC_INIT(TODC_TYPE_MK48T37, 0, 0, 
+	TODC_INIT(TODC_TYPE_MK48T37, 0, 0,
 		  ioremap(PAL4_NVRAM, PAL4_NVRAM_SIZE), 8);
 
 	pal4_find_bridges();
@@ -172,10 +172,10 @@
 
 	isa_io_base = 0 /*PAL4_ISA_IO_BASE*/;
 	pci_dram_offset = 0 /*PAL4_PCI_SYS_MEM_BASE*/;
-	
+
 	ppc_md.setup_arch = pal4_setup_arch;
 	ppc_md.show_cpuinfo = pal4_show_cpuinfo;
-	
+
 	ppc_md.find_end_of_memory = pal4_find_end_of_memory;
 	ppc_md.setup_io_mappings = pal4_map_io;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pmac_backlight.c linux-2.4.22-pre10/arch/ppc/platforms/pmac_backlight.c
--- linux-2.4.21/arch/ppc/platforms/pmac_backlight.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pmac_backlight.c	2003-08-01 13:33:16.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  * Miscellaneous procedures for dealing with the PowerMac hardware.
  * Contains support for the backlight.
- * 
+ *
  *   Copyright (C) 2000 Benjamin Herrenschmidt
  *
  */
@@ -38,7 +38,7 @@
 	int valid = 0;
 
 	bk_node = find_devices("backlight");
-	
+
 #ifdef CONFIG_ADB_PMU
 	/* Special case for the old PowerBook since I can't test on it */
 	backlight_autosave = machine_is_compatible("AAPL,3400/2400")
@@ -58,7 +58,7 @@
 		return;
 	backlighter = ctrler;
 	backlighter_data = data;
-	
+
 	if (bk_node && !backlight_autosave)
 		prop = get_property(bk_node, "bklt", NULL);
 	else
@@ -68,7 +68,7 @@
 		if (backlight_level > BACKLIGHT_MAX)
 			backlight_level = BACKLIGHT_MAX;
 	}
-	
+
 #ifdef CONFIG_ADB_PMU
 	if (backlight_autosave) {
 		struct adb_request req;
@@ -97,7 +97,7 @@
 set_backlight_enable(int enable)
 {
 	int rc;
-	
+
 	if (!backlighter)
 		return -ENODEV;
 	rc = backlighter->set_enable(enable, backlight_level, backlighter_data);
@@ -118,7 +118,7 @@
 set_backlight_level(int level)
 {
 	int rc = 0;
-	
+
 	if (!backlighter)
 		return -ENODEV;
 	if (level < BACKLIGHT_MIN)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pmac_feature.c linux-2.4.22-pre10/arch/ppc/platforms/pmac_feature.c
--- linux-2.4.21/arch/ppc/platforms/pmac_feature.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pmac_feature.c	2003-08-01 13:31:52.000000000 +0000
@@ -8,9 +8,9 @@
  *  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.
- *  
- *  TODO: 
- *  
+ *
+ *  TODO:
+ *
  *   - Replace mdelay with some schedule loop if possible
  *   - Shorten some obfuscated delays on some routines (like modem
  *     power)
@@ -66,7 +66,7 @@
 /*
  * Helper functions regarding the various flavors of mac-io
  */
- 
+
 #define MAX_MACIO_CHIPS		2
 
 enum {
@@ -82,7 +82,7 @@
 	macio_intrepid,
 };
 
-static const char* macio_names[] __pmacdata = 
+static const char* macio_names[] __pmacdata =
 {
 	"Unknown",
 	"Grand Central",
@@ -116,7 +116,7 @@
 {
 	while(child) {
 		int	i;
-	
+
 		for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++)
 			if (child == macio_chips[i].of_node &&
 			    (!type || macio_chips[i].type == type))
@@ -139,7 +139,7 @@
 /*
  * Uninorth reg. access. Note that Uni-N regs are big endian
  */
- 
+
 #define UN_REG(r)	(uninorth_base + ((r) >> 2))
 #define UN_IN(r)	(in_be32(UN_REG(r)))
 #define UN_OUT(r,v)	(out_be32(UN_REG(r), (v)))
@@ -159,7 +159,7 @@
 typedef int (*feature_call)(struct device_node* node, int param, int value);
 
 struct feature_table_entry {
-	unsigned int	selector;	
+	unsigned int	selector;
 	feature_call	function;
 };
 
@@ -182,7 +182,7 @@
 {
 	struct macio_chip*	macio;
 	unsigned long		flags;
-	
+
 	macio = macio_find(node, type);
 	if (!macio)
 		return -ENODEV;
@@ -206,7 +206,7 @@
 	unsigned long		flags;
 	int			htw, trans;
 	unsigned long		rmask;
-	
+
 	macio = macio_find(node, 0);
 	if (!macio)
 		return -ENODEV;
@@ -226,7 +226,7 @@
 #ifdef CONFIG_ADB_PMU
 		if ((param & 0xfff) == PMAC_SCC_IRDA)
 			pmu_enable_irled(1);
-#endif /* CONFIG_ADB_PMU */		
+#endif /* CONFIG_ADB_PMU */
 		LOCK(flags);
 		fcr = MACIO_IN32(OHARE_FCR);
 		/* Check if scc cell need enabling */
@@ -285,7 +285,7 @@
 #ifdef CONFIG_ADB_PMU
 		if ((param & 0xfff) == PMAC_SCC_IRDA)
 			pmu_enable_irled(0);
-#endif /* CONFIG_ADB_PMU */		
+#endif /* CONFIG_ADB_PMU */
 	}
 	return 0;
 }
@@ -352,7 +352,7 @@
 	} else if (value == 0) {
 		MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
 	}
-	
+
 	return 0;
 }
 
@@ -362,7 +362,7 @@
 	struct macio_chip*	macio;
 	u8			gpio;
 	unsigned long		flags;
-	
+
 	macio = macio_find(node, macio_unknown);
 	if (!macio)
 		return -ENODEV;
@@ -414,7 +414,7 @@
 {
 	struct macio_chip*	macio;
 	unsigned long		flags;
-	
+
 	macio = macio_find(node, macio_unknown);
 	if (!macio)
 		return -ENODEV;
@@ -441,7 +441,7 @@
 		MACIO_BIC(HEATHROW_MBCR, 0x00040000);
 	else
 		MACIO_BIS(HEATHROW_MBCR, 0x00040000);
-#endif		
+#endif
 	(void)MACIO_IN32(HEATHROW_MBCR);
 	udelay(10);
 	UNLOCK(flags);
@@ -484,7 +484,7 @@
 {
 	struct macio_chip*	macio;
 	unsigned long		flags;
-	
+
 	macio = macio_find(node, 0);
 	if (!macio)
 		return -ENODEV;
@@ -520,7 +520,7 @@
 	if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE ||
 	    pmac_mb.model_id == PMAC_TYPE_YIKES)
 		return 0;
-	
+
 	macio = macio_find(node, 0);
 	if (!macio)
 		return -ENODEV;
@@ -552,7 +552,7 @@
 dbdma_save(struct macio_chip* macio, struct dbdma_regs* save)
 {
 	int i;
-	
+
 	/* Save state & config of DBDMA channels */
 	for (i=0; i<13; i++) {
 		volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*)
@@ -569,7 +569,7 @@
 dbdma_restore(struct macio_chip* macio, struct dbdma_regs* save)
 {
 	int i;
-	
+
 	/* Save state & config of DBDMA channels */
 	for (i=0; i<13; i++) {
 		volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*)
@@ -668,7 +668,7 @@
 	unsigned long		flags;
 	unsigned long		chan_mask;
 	u32			fcr;
-	
+
 	macio = macio_find(node, 0);
 	if (!macio)
 		return -ENODEV;
@@ -682,7 +682,7 @@
 	if (value) {
 		int need_reset_scc = 0;
 		int need_reset_irda = 0;
-		
+
 		LOCK(flags);
 		fcr = MACIO_IN32(KEYLARGO_FCR0);
 		/* Check if scc cell need enabling */
@@ -770,7 +770,7 @@
 	unsigned long		flags;
 
 	/* Hack for internal USB modem */
-	if (node == NULL) {	
+	if (node == NULL) {
 		if (macio_chips[0].type != macio_keylargo)
 			return -ENODEV;
 		node = macio_chips[0].of_node;
@@ -781,7 +781,7 @@
 	gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
 	gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
 	gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
-	
+
 	if (!value) {
 		LOCK(flags);
 		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
@@ -820,9 +820,9 @@
 	struct macio_chip*	macio;
 	u8			gpio;
 	unsigned long		flags;
-	
+
 	/* Hack for internal USB modem */
-	if (node == NULL) {	
+	if (node == NULL) {
 		if (macio_chips[0].type != macio_pangea &&
 		    macio_chips[0].type != macio_intrepid)
 			return -ENODEV;
@@ -834,7 +834,7 @@
 	gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
 	gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
 	gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
-	
+
 	if (!value) {
 		LOCK(flags);
 		MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
@@ -962,7 +962,7 @@
 {
 	unsigned long flags;
 	struct macio_chip* macio;
-	
+
 	macio = &macio_chips[0];
 	if (macio->type != macio_keylargo && macio->type != macio_pangea &&
 	    macio->type != macio_intrepid)
@@ -987,7 +987,7 @@
 {
 	struct macio_chip*	macio;
 	unsigned long		flags;
-	
+
 	macio = macio_find(node, 0);
 	if (!macio)
 		return -ENODEV;
@@ -1018,11 +1018,11 @@
 	struct macio_chip*	macio;
 	unsigned long		flags;
 	int			state;
-	
+
 	macio = macio_find(node, 0);
 	if (!macio)
 		return -ENODEV;
-	
+
 	/* Hint: we allow passing of macio itself for the sake of the
 	 * sleep code
 	 */
@@ -1110,11 +1110,11 @@
 						KL_GPIO_RESET_CPU1,
 						KL_GPIO_RESET_CPU2,
 						KL_GPIO_RESET_CPU3 };
-	
+
 	macio = &macio_chips[0];
 	if (macio->type != macio_keylargo)
 		return -ENODEV;
-		
+
 	np = find_path_device("/cpus");
 	if (np == NULL)
 		return -ENODEV;
@@ -1130,7 +1130,7 @@
 	}
 	if (np == NULL || reset_io == 0)
 		reset_io = dflt_reset_lines[param];
-	
+
 	LOCK(flags);
 	MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
 	(void)MACIO_IN8(reset_io);
@@ -1151,15 +1151,12 @@
 	char* prop;
 	int number;
 	u32 reg;
-	
+
 	macio = &macio_chips[0];
 	if (macio->type != macio_keylargo && macio->type != macio_pangea &&
 	    macio->type != macio_intrepid)
 		return -ENODEV;
 
-	/* XXX Fix handling of 3rd USB controller in Intrepid, move the
-	 * port connect stuff (KL4_*) to the sleep code eventually
-	 */
 	prop = (char *)get_property(node, "AAPL,clock-id", NULL);
 	if (!prop)
 		return -ENODEV;
@@ -1167,6 +1164,8 @@
 		number = 0;
 	else if (strncmp(prop, "usb1u148", 8) == 0)
 		number = 2;
+	else if (strncmp(prop, "usb2u248", 8) == 0)
+		number = 4;
 	else
 		return -ENODEV;
 
@@ -1183,44 +1182,79 @@
 			mdelay(1);
 			LOCK(flags);
 			MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
-		} else {
+		} else if (number == 2) {
 			MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
 			UNLOCK(flags);
 			(void)MACIO_IN32(KEYLARGO_FCR0);
 			mdelay(1);
 			LOCK(flags);
 			MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
+		} else if (number == 4) {
+			MACIO_BIC(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
+			UNLOCK(flags);
+			(void)MACIO_IN32(KEYLARGO_FCR1);
+			mdelay(1);
+			LOCK(flags);
+			MACIO_BIS(KEYLARGO_FCR0, KL1_USB2_CELL_ENABLE);
+		}
+		if (number < 4) {
+			reg = MACIO_IN32(KEYLARGO_FCR4);
+			reg &=	~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
+				KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number));
+			reg &=	~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
+				KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1));
+			MACIO_OUT32(KEYLARGO_FCR4, reg);
+			(void)MACIO_IN32(KEYLARGO_FCR4);
+			udelay(10);
+		} else {
+			reg = MACIO_IN32(KEYLARGO_FCR3);
+			reg &=	~(KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
+				KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0));
+			reg &=	~(KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
+				KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1));
+			MACIO_OUT32(KEYLARGO_FCR3, reg);
+			(void)MACIO_IN32(KEYLARGO_FCR3);
+			udelay(10);
 		}
-		reg = MACIO_IN32(KEYLARGO_FCR4);
-		reg &=	~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
-			KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number));
-		reg &=	~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
-			KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1));
-		MACIO_OUT32(KEYLARGO_FCR4, reg);
-		(void)MACIO_IN32(KEYLARGO_FCR4);
-		udelay(10);
 	} else {
 		/* Turn OFF */
-		reg = MACIO_IN32(KEYLARGO_FCR4);
-		reg |=	KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
-			KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number);
-		reg |=	KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
-			KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1);
-		MACIO_OUT32(KEYLARGO_FCR4, reg);
-		(void)MACIO_IN32(KEYLARGO_FCR4);
-		udelay(1);
+		if (number < 4) {
+			reg = MACIO_IN32(KEYLARGO_FCR4);
+			reg |=	KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
+				KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number);
+			reg |=	KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
+				KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1);
+			MACIO_OUT32(KEYLARGO_FCR4, reg);
+			(void)MACIO_IN32(KEYLARGO_FCR4);
+			udelay(1);
+		} else {
+			reg = MACIO_IN32(KEYLARGO_FCR3);
+			reg |=	KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
+				KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0);
+			reg |=	KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
+				KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1);
+			MACIO_OUT32(KEYLARGO_FCR3, reg);
+			(void)MACIO_IN32(KEYLARGO_FCR3);
+			udelay(1);
+		}
 		if (number == 0) {
 			MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
 			(void)MACIO_IN32(KEYLARGO_FCR0);
 			udelay(1);
 			MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
 			(void)MACIO_IN32(KEYLARGO_FCR0);
-		} else {
+		} else if (number == 2) {
 			MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
 			(void)MACIO_IN32(KEYLARGO_FCR0);
 			udelay(1);
 			MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
 			(void)MACIO_IN32(KEYLARGO_FCR0);
+		} else if (number == 4) {
+			MACIO_BIC(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE);
+			(void)MACIO_IN32(KEYLARGO_FCR1);
+			udelay(1);
+			MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
+			(void)MACIO_IN32(KEYLARGO_FCR1);
 		}
 		udelay(1);
 	}
@@ -1241,7 +1275,7 @@
 		return -ENODEV;
 	if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
 		return -ENODEV;
-	
+
 	LOCK(flags);
 	if (value) {
 		UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
@@ -1271,7 +1305,7 @@
 		return -ENODEV;
 	if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
 		return -ENODEV;
-	
+
 	LOCK(flags);
 	if (value) {
 		MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0);
@@ -1291,7 +1325,7 @@
 core99_read_gpio(struct device_node* node, int param, int value)
 {
 	struct macio_chip* macio = &macio_chips[0];
-	
+
 	return MACIO_IN8(param);
 }
 
@@ -1321,7 +1355,7 @@
 				KL0_SCC_CELL_ENABLE |
 		      		KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE |
 		      		KL0_IRDA_CLK19_ENABLE);
-	
+
 	MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
 	MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE);
 
@@ -1344,7 +1378,7 @@
 		if (sleep_mode)
 			temp |= KL3_SHUTDOWN_PLL_TOTAL;
 	}
-	
+
 	temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
 		KL3_SHUTDOWN_PLLKW35;
 	if (sleep_mode)
@@ -1379,7 +1413,7 @@
 		MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
 
 	MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
- 	
+ 
 	temp = MACIO_IN32(KEYLARGO_FCR3);
 	temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
 		KL3_SHUTDOWN_PLLKW35;
@@ -1411,7 +1445,7 @@
 		MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
 
 	MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
- 	
+ 
 	temp = MACIO_IN32(KEYLARGO_FCR3);
 	temp |= KL3_IT_SHUTDOWN_PLL1 | KL3_IT_SHUTDOWN_PLL2 |
 		KL3_IT_SHUTDOWN_PLL3;
@@ -1435,7 +1469,7 @@
 	if (macio->type != macio_keylargo && macio->type != macio_pangea &&
 	    macio->type != macio_intrepid)
 		return -ENODEV;
-	
+
 	/* We power off the wireless slot in case it was not done
 	 * by the driver. We don't power it on automatically however
 	 */
@@ -1456,7 +1490,7 @@
 
 	/* We make sure the sound is off as well */
 	core99_sound_chip_enable(macio->of_node, 0, 0);
-	 
+
 	/*
 	 * Save various bits of KeyLargo
 	 */
@@ -1482,7 +1516,7 @@
 
 	/* Save state & config of DBDMA channels */
 	dbdma_save(macio, save_dbdma);
-	
+
 	/*
 	 * Turn off as much as we can
 	 */
@@ -1492,8 +1526,8 @@
 		intrepid_shutdown(macio, 1);
 	else if (macio->type == macio_keylargo)
 		keylargo_shutdown(macio, 1);
-	
-	/* 
+
+	/*
 	 * Put the host bridge to sleep
 	 */
 
@@ -1532,7 +1566,7 @@
 	udelay(10);
 	UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
 	udelay(10);
-	
+
 	/*
 	 * Restore KeyLargo
 	 */
@@ -1612,7 +1646,7 @@
 			return pmac_mb.model_id;
 		case PMAC_MB_INFO_FLAGS:
 			return pmac_mb.board_flags;
-		case PMAC_MB_INFO_NAME:	
+		case PMAC_MB_INFO_NAME:
 			/* hack hack hack... but should work */
 			*((const char **)value) = pmac_mb.model_name;
 			break;
@@ -1620,10 +1654,10 @@
 	return 0;
 }
 
-/* 
+/*
  * Table definitions
  */
- 
+
 /* Used on any machine
  */
 static struct feature_table_entry any_features[]  __pmacdata = {
@@ -1775,7 +1809,7 @@
 	{ PMAC_FTR_WRITE_GPIO,		core99_write_gpio },
 	{ 0, NULL }
 };
-	
+
 static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
 	/* Warning: ordering is important as some models may claim
 	 * beeing compatible with several types
@@ -1928,10 +1962,22 @@
 		PMAC_TYPE_RACKMAC,		rackmac_features,
 		0,
 	},
+	{	"RackMac1,2",			"XServe rev. 2",
+		PMAC_TYPE_RACKMAC,		rackmac_features,
+		0,
+	},
 	{	"PowerMac3,6",			"PowerMac G4 Windtunnel",
 		PMAC_TYPE_WINDTUNNEL,		rackmac_features,
 		0,
 	},
+	{	"PowerBook5,1",			"PowerBook G4 17\"",
+		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
+		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+	},
+	{	"PowerBook6,1",			"PowerBook G4 12\"",
+		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
+		PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+	},
 };
 
 /*
@@ -1944,7 +1990,7 @@
 	int param, value, i;
 	feature_call func = NULL;
 	va_list args;
-	
+
 	if (pmac_mb.features)
 		for (i=0; pmac_mb.features[i].function; i++)
 			if (pmac_mb.features[i].selector == selector) {
@@ -1976,7 +2022,7 @@
 	struct macio_chip* macio = &macio_chips[0];
 	const char* model = NULL;
 	struct device_node *dt;
-	
+
 	/* Lookup known motherboard type in device-tree. First try an
 	 * exact match on the "model" property, then try a "compatible"
 	 * match is none is found.
@@ -2028,8 +2074,8 @@
 	    	pmac_mb.features = pangea_features;
 		break;
 	    case macio_intrepid:
-		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA;
-		pmac_mb.model_name = "Unknown Pangea-based";
+		pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID;
+		pmac_mb.model_name = "Unknown Intrepid-based";
 	    	pmac_mb.features = intrepid_features;
 	    	break;
 	    default:
@@ -2083,8 +2129,8 @@
 	if (model && (strncmp(model, "PowerBook", 9) == 0
 		   || strncmp(model, "iBook", 5) == 0))
 		pmac_mb.board_flags |= PMAC_MB_MOBILE;
-	
-	
+
+
 	printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);
 	return 0;
 }
@@ -2095,7 +2141,7 @@
 probe_uninorth(void)
 {
 	unsigned long actrl;
-	
+
 	/* Locate core99 Uni-N */
 	uninorth_node = find_devices("uni-n");
 	if (uninorth_node && uninorth_node->n_addrs > 0) {
@@ -2103,10 +2149,10 @@
 		uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
 	} else
 		uninorth_node = NULL;
-		
+
 	if (!uninorth_node)
 		return;
-	
+
 	printk(KERN_INFO "Found Uninorth memory controller & host bridge, revision: %d\n",
 			uninorth_rev);
 	printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
@@ -2126,7 +2172,7 @@
 	 */
 	if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0)
 		UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff);
-}	
+}
 
 static void __init
 probe_one_macio(const char* name, const char* compat, int type)
@@ -2135,7 +2181,7 @@
 	int			i;
 	volatile u32*		base;
 	u32*			revp;
-	
+
 	node = find_devices(name);
 	if (!node || !node->n_addrs)
 		return;
@@ -2221,7 +2267,7 @@
 	char *conn;
 	int port_type = PMAC_SCC_ASYNC;
 	int modem = 0;
-	
+
 	slots = (struct slot_names_prop *)get_property(np, "slot-names", &len);
 	conn = get_property(np, "AAPL,connector", &len);
 	if (conn && (strcmp(conn, "infrared") == 0))
@@ -2243,7 +2289,7 @@
 set_initial_features(void)
 {
 	struct device_node* np;
-	
+
 	/* That hack appears to be necessary for some StarMax motherboards
 	 * but I'm not too sure it was audited for side-effects on other
 	 * ohare based machines...
@@ -2286,7 +2332,7 @@
 		while(np) {
 			if (np->parent
 			    && device_is_compatible(np->parent, "uni-north")
-			    && (device_is_compatible(np, "pci106b,18") || 
+			    && (device_is_compatible(np, "pci106b,18") ||
 	     		        device_is_compatible(np, "pci106b,30") ||
 	     		        device_is_compatible(np, "pci11c1,5811"))) {
 				macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
@@ -2294,7 +2340,7 @@
 			}
 			np = np->next;
 		}
-		
+
 		/* Enable ATA-100 before PCI probe. */
 		np = find_devices("ata-6");
 		while(np) {
@@ -2305,7 +2351,7 @@
 			}
 			np = np->next;
 		}
-		
+
 		/* Switch airport off */
 		np = find_devices("radio");
 		while(np) {
@@ -2371,7 +2417,7 @@
 pmac_feature_late_init(void)
 {
 	struct device_node* np;
-	
+
 	/* Request some resources late */
 	if (uninorth_node)
 		request_OF_resource(uninorth_node, 0, NULL);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pmac_nvram.c linux-2.4.22-pre10/arch/ppc/platforms/pmac_nvram.c
--- linux-2.4.21/arch/ppc/platforms/pmac_nvram.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pmac_nvram.c	2003-08-01 13:33:01.000000000 +0000
@@ -102,7 +102,7 @@
 	}
 	low  %= 65521UL;
 	high %= 65521UL;
-  
+
 	return (high << 16) | low;
 }
 
@@ -114,7 +114,7 @@
 	if (hdr99->hdr.signature != CORE99_SIGNATURE) {
 #ifdef DEBUG
 		printk("Invalid signature\n");
-#endif		
+#endif
 		return 0;
 	}
 	if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) {
@@ -136,9 +136,9 @@
 core99_erase_bank(int bank)
 {
 	int stat, i;
-	
+
 	u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
-	
+
 	out_8(base, CORE99_FLASH_CMD_ERASE_SETUP);
 	out_8(base, CORE99_FLASH_CMD_ERASE_CONFIRM);
 	do { stat = in_8(base); }
@@ -160,9 +160,9 @@
 core99_write_bank(int bank, u8* datas)
 {
 	int i, stat = 0;
-	
+
 	u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
-	
+
 	for (i=0; i<NVRAM_SIZE; i++) {
 		out_8(base+i, CORE99_FLASH_CMD_WRITE_SETUP);
 		out_8(base+i, datas[i]);
@@ -181,7 +181,7 @@
 			printk("nvram: flash write failed !\n");
 			return -ENXIO;
 		}
-	return 0;	
+	return 0;
 }
 
 static void __init
@@ -196,7 +196,7 @@
 		nvram_partitions[pmac_nvram_XPRAM] = -1;
 		nvram_partitions[pmac_nvram_NR] = -1;
 		hdr = (struct chrp_header *)buffer;
-	
+
 		offset = 0;
 		buffer[16] = 0;
 		do {
@@ -214,12 +214,12 @@
 		nvram_partitions[pmac_nvram_OF] = 0x1800;
 		nvram_partitions[pmac_nvram_XPRAM] = 0x1300;
 		nvram_partitions[pmac_nvram_NR] = 0x1400;
-	}	
+	}
 #ifdef DEBUG
 	printk("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]);
 	printk("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]);
 	printk("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
-#endif	
+#endif
 }
 
 void __init
@@ -239,7 +239,7 @@
 	if (is_core_99) {
 		int i;
 		u32 gen_bank0, gen_bank1;
-		
+
 		if (nvram_naddrs < 1) {
 			printk(KERN_ERR "nvram: no address\n");
 			return;
@@ -287,7 +287,7 @@
 pmac_nvram_update(void)
 {
 	struct core99_header* hdr99;
-	
+
 	if (!is_core_99 || !nvram_data || !nvram_image)
 		return;
 	if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
@@ -380,10 +380,10 @@
 pmac_xpram_read(int xpaddr)
 {
 	int offset = nvram_partitions[pmac_nvram_XPRAM];
-	
+
 	if (offset < 0)
 		return 0;
-		
+
 	return nvram_read_byte(xpaddr + offset);
 }
 
@@ -391,9 +391,9 @@
 pmac_xpram_write(int xpaddr, u8 data)
 {
 	int offset = nvram_partitions[pmac_nvram_XPRAM];
-	
+
 	if (offset < 0)
 		return;
-		
+
 	nvram_write_byte(xpaddr + offset, data);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pmac_pci.c linux-2.4.22-pre10/arch/ppc/platforms/pmac_pci.c
--- linux-2.4.21/arch/ppc/platforms/pmac_pci.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pmac_pci.c	2003-08-01 13:33:23.000000000 +0000
@@ -49,7 +49,7 @@
 {
 	for (; node != 0;node = node->sibling) {
 		int * bus_range;
-		unsigned int *class_code;			
+		unsigned int *class_code;
 		int len;
 
 		/* For PCI<->PCI bridges or CardBus bridges, we go down */
@@ -69,7 +69,7 @@
 
 /* This routine fixes the "bus-range" property of all bridges in the
  * system since they tend to have their "last" member wrong on macs
- * 
+ *
  * Note that the bus numbers manipulated here are OF bus numbers, they
  * are not Linux bus numbers.
  */
@@ -78,8 +78,8 @@
 {
 	int * bus_range;
 	int len;
-	
-	/* Lookup the "bus-range" property for the hose */		
+
+	/* Lookup the "bus-range" property for the hose */
 	bus_range = (int *) get_property(bridge, "bus-range", &len);
 	if (bus_range == NULL || len < 2 * sizeof(int)) {
 		printk(KERN_WARNING "Can't get bus-range for %s\n",
@@ -91,11 +91,11 @@
 
 /*
  * Apple MacRISC (UniNorth, Bandit, Chaos) PCI controllers.
- * 
+ *
  * The "Bandit" version is present in all early PCI PowerMacs,
  * and up to the first ones using Grackle. Some machines may
  * have 2 bandit controllers (2 PCI busses).
- * 
+ *
  * "Chaos" is used in some "Bandit"-type machines as a bridge
  * for the separate display bus. It is accessed the same
  * way as bandit, but cannot be probed for devices. It therefore
@@ -116,19 +116,19 @@
 	|(((unsigned long)(devfn)) << 8) \
 	|(((unsigned long)(off)) & 0xFCUL) \
 	|1UL)
-	
+
 static unsigned int __pmac
 macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset)
 {
 	unsigned int caddr;
-	
+
 	if (bus == hose->first_busno) {
 		if (dev_fn < (11 << 3))
 			return 0;
 		caddr = MACRISC_CFA0(dev_fn, offset);
 	} else
 		caddr = MACRISC_CFA1(bus, dev_fn, offset);
-	
+
 	/* Uninorth will return garbage if we don't read back the value ! */
 	do {
 		out_le32(hose->cfg_addr, caddr);
@@ -217,7 +217,7 @@
 CHAOS_PCI_OP(read, dword, u32 *)
 CHAOS_PCI_OP(write, byte, u8)
 CHAOS_PCI_OP(write, word, u16)
-CHAOS_PCI_OP(write, dword, u32) 
+CHAOS_PCI_OP(write, dword, u32)
 
 static struct pci_ops chaos_pci_ops =
 {
@@ -244,7 +244,7 @@
 	out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID);
 	udelay(2);
 	vendev = in_le32((volatile unsigned int *)bp->cfg_data);
-	if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) + 
+	if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) +
 			PCI_VENDOR_ID_APPLE) {
 		/* read the revision id */
 		out_le32(bp->cfg_addr,
@@ -292,17 +292,17 @@
 	if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) {
 #ifdef DEBUG
 		printk("Can't find PCI infos for PCI<->PCI bridge\n");
-#endif		
+#endif
 		return;
 	}
-	/* Warning: At this point, we have not yet renumbered all busses. 
+	/* Warning: At this point, we have not yet renumbered all busses.
 	 * So we must use OF walking to find out hose
 	 */
 	hose = pci_find_hose_for_OF_device(p2pbridge);
 	if (!hose) {
 #ifdef DEBUG
 		printk("Can't find hose for PCI<->PCI bridge\n");
-#endif		
+#endif
 		return;
 	}
 	if (early_read_config_word(hose, bus, devfn,
@@ -314,6 +314,51 @@
 	early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);
 }
 
+/*
+ * Some Apple desktop machines have a NEC PD720100A USB2 controller
+ * on the motherboard. Open Firmware, on these, will disable the
+ * EHCI part of it so it behaves like a pair of OHCI's. This fixup
+ * code re-enables it ;)
+ */
+static void __init
+fixup_nec_usb2(void)
+{
+	struct device_node *nec;
+
+	for (nec = find_devices("usb"); nec != NULL; nec = nec->next) {
+		struct pci_controller *hose;
+		u32 data, *prop;
+		u8 bus, devfn;
+		
+		prop = (u32 *)get_property(nec, "vendor-id", NULL);
+		if (prop == NULL)
+			continue;
+		if (0x1033 != *prop)
+			continue;
+		prop = (u32 *)get_property(nec, "device-id", NULL);
+		if (prop == NULL)
+			continue;
+		if (0x0035 != *prop)
+			continue;
+		prop = (u32 *)get_property(nec, "reg", 0);
+		if (prop == NULL)
+			continue;
+		devfn = (prop[0] >> 8) & 0xff;
+		bus = (prop[0] >> 16) & 0xff;
+		if (PCI_FUNC(devfn) != 0)
+			continue;
+		hose = pci_find_hose_for_OF_device(nec);
+		if (!hose)
+			continue;
+		printk("Found NEC PD720100A USB2 chip, enabling EHCI...\n");
+		early_read_config_dword(hose, bus, devfn, 0xe4, &data);
+		data &= ~1UL;
+		early_write_config_dword(hose, bus, devfn, 0xe4, data);
+		early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE,
+			nec->intrs[0].line);
+	}
+}
+
 void __init
 pmac_find_bridges(void)
 {
@@ -321,6 +366,7 @@
 	add_bridges(find_devices("chaos"));
 	add_bridges(find_devices("pci"));
 	init_p2pbridge();
+	fixup_nec_usb2();
 }
 
 #define GRACKLE_CFA(b, d, o)	(0x80 | ((b) << 8) | ((d) << 16) \
@@ -416,7 +462,7 @@
 	char* disp_name;
 	int *bus_range;
 	int first = 1, primary;
-	
+
 	for (; dev != NULL; dev = dev->next) {
 		addr = (struct reg_property *) get_property(dev, "reg", &len);
 		if (addr == NULL || len < sizeof(*addr)) {
@@ -429,7 +475,7 @@
 			printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
 				       dev->full_name);
 		}
-		
+
 		hose = pcibios_alloc_controller();
 		if (!hose)
 			continue;
@@ -459,8 +505,8 @@
 #ifdef DEBUG
 		printk(" ->Hose at 0x%08lx, cfg_addr=0x%08lx,cfg_data=0x%08lx\n",
 			hose, hose->cfg_addr, hose->cfg_data);
-#endif		
-		
+#endif
+
 		/* Interpret the "ranges" property */
 		/* This also maps the I/O region and sets isa_io/mem_base */
 		pci_process_bridge_OF_ranges(hose, dev, primary);
@@ -474,9 +520,9 @@
 
 static void __init
 pcibios_fixup_OF_interrupts(void)
-{	
+{
 	struct pci_dev* dev;
-	
+
 	/*
 	 * Open Firmware often doesn't initialize the
 	 * PCI_INTERRUPT_LINE config register properly, so we
@@ -520,19 +566,19 @@
 
 	uninorth_child = node->parent &&
 		device_is_compatible(node->parent, "uni-north");
-		
+
 	/* Firewire & GMAC were disabled after PCI probe, the driver is
 	 * claiming them, we must re-enable them now.
 	 */
-	if (uninorth_child && !strcmp(node->name, "firewire") && 
-	    (device_is_compatible(node, "pci106b,18") || 
+	if (uninorth_child && !strcmp(node->name, "firewire") &&
+	    (device_is_compatible(node, "pci106b,18") ||
 	     device_is_compatible(node, "pci106b,30") ||
 	     device_is_compatible(node, "pci11c1,5811"))) {
 		pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1);
 		pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1);
 		updatecfg = 1;
 	}
-	if (uninorth_child && !strcmp(node->name, "ethernet") && 
+	if (uninorth_child && !strcmp(node->name, "ethernet") &&
 	    device_is_compatible(node, "gmac")) {
 		pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1);
 		updatecfg = 1;
@@ -540,14 +586,14 @@
 
 	if (updatecfg) {
 		u16 cmd;
-		
+
 		/*
 		 * Make sure PCI is correctly configured
 		 *
 		 * We use old pci_bios versions of the function since, by
 		 * default, gmac is not powered up, and so will be absent
-		 * from the kernel initial PCI lookup. 
-		 * 
+		 * from the kernel initial PCI lookup.
+		 *
 		 * Should be replaced by 2.4 new PCI mecanisms and really
 		 * regiser the device.
 		 */
@@ -557,7 +603,7 @@
     		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16);
     		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
 	}
-	
+
 	return 0;
 }
 
@@ -574,12 +620,12 @@
 
 	/* OF fails to initialize IDE controllers on macs
 	 * (and maybe other machines)
-	 * 
+	 *
 	 * Ideally, this should be moved to the IDE layer, but we need
 	 * to check specifically with Andre Hedrick how to do it cleanly
 	 * since the common IDE code seem to care about the fact that the
 	 * BIOS may have disabled a controller.
-	 * 
+	 *
 	 * -- BenH
 	 */
 	pci_for_each_dev(dev) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pmac_pic.c linux-2.4.22-pre10/arch/ppc/platforms/pmac_pic.c
--- linux-2.4.21/arch/ppc/platforms/pmac_pic.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pmac_pic.c	2003-08-01 13:34:30.000000000 +0000
@@ -161,7 +161,7 @@
 static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
 {
 	int irq, bits;
-	
+
 	for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {
 		int i = irq >> 5;
 		bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
@@ -191,7 +191,7 @@
 
 #ifdef CONFIG_SMP
 	void psurge_smp_message_recv(struct pt_regs *);
-	
+
        	/* IPI's are a hack on the powersurge -- Cort */
        	if ( smp_processor_id() != 0 ) {
 		psurge_smp_message_recv(regs);
@@ -221,7 +221,7 @@
 {
 	struct device_node *node;
 	int count;
-	
+
 	memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));
 	node = gw->child;
 	count = 0;
@@ -234,7 +234,7 @@
 					node->child->intrs = &gatwick_int_pool[count];
 					count += 3;
 				}
-				node->child->n_intrs = 3;				
+				node->child->n_intrs = 3;
 				node->child->intrs[0].line = 15+irq_base;
 				node->child->intrs[1].line =  4+irq_base;
 				node->child->intrs[2].line =  5+irq_base;
@@ -253,7 +253,7 @@
 			node->intrs[0].line = 29+irq_base;
 			printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n",
 					node->intrs[0].line);
-			
+
 			ya_node = node->child;
 			while(ya_node)
 			{
@@ -267,7 +267,7 @@
 					ya_node->intrs[1].line =  1+irq_base;
 					printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n",
 						ya_node->intrs[0].line, ya_node->intrs[1].line);
-				} 
+				}
 				if (strcasecmp(ya_node->name, "ata4") == 0) {
 					if (ya_node->n_intrs < 2) {
 						ya_node->intrs = &gatwick_int_pool[count];
@@ -278,7 +278,7 @@
 					ya_node->intrs[1].line =  3+irq_base;
 					printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n",
 						ya_node->intrs[0].line, ya_node->intrs[1].line);
-				} 
+				}
 				ya_node = ya_node->sibling;
 			}
 		}
@@ -345,7 +345,7 @@
         struct device_node *irqctrler;
         unsigned long addr;
 	int irq_cascade = -1;
-	
+
 	/* We first try to detect Apple's new Core99 chipset, since mac-io
 	 * is quite different on those machines and contains an IBM MPIC2.
 	 */
@@ -403,7 +403,7 @@
 
 	/*
 	 * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,
-	 * 1998 G3 Series PowerBooks have 128, 
+	 * 1998 G3 Series PowerBooks have 128,
 	 * other powermacs have 32.
 	 * The combo ethernet/modem card for the Powerstar powerbooks
 	 * (2400/3400/3500, ohare based) has a second ohare chip
@@ -425,17 +425,17 @@
 	/* get addresses of first controller */
 	if (irqctrler) {
 		if  (irqctrler->n_addrs > 0) {
-			addr = (unsigned long) 
+			addr = (unsigned long)
 				ioremap(irqctrler->addrs[0].address, 0x40);
 			for (i = 0; i < 2; ++i)
 				pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
 					(addr + (2 - i) * 0x10);
 		}
-		
+
 		/* get addresses of second controller */
 		irqctrler = irqctrler->next;
 		if (irqctrler && irqctrler->n_addrs > 0) {
-			addr = (unsigned long) 
+			addr = (unsigned long)
 				ioremap(irqctrler->addrs[0].address, 0x40);
 			for (i = 2; i < 4; ++i)
 				pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
@@ -464,7 +464,7 @@
 	for (i = 0; i < max_irqs; i++)
 		if (level_mask[i >> 5] & (1UL << (i & 0x1f)))
 			irq_desc[i].status = IRQ_LEVEL;
-	
+
 	/* get interrupt line of secondary interrupt controller */
 	if (irq_cascade >= 0) {
 		printk(KERN_INFO "irq: secondary controller on irq %d\n",
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pmac_setup.c linux-2.4.22-pre10/arch/ppc/platforms/pmac_setup.c
--- linux-2.4.21/arch/ppc/platforms/pmac_setup.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pmac_setup.c	2003-08-01 13:33:56.000000000 +0000
@@ -1,7 +1,7 @@
 /*
  *  arch/ppc/platforms/setup.c
  *
- *  PowerPC version 
+ *  PowerPC version
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
  *  Adapted for Power Macintosh by Paul Mackerras
@@ -150,7 +150,7 @@
 {
 	struct device_node *cpu_node;
 	int *fp, s;
-			
+
 	cpu_node = find_type_devices("cpu");
 	if (!cpu_node)
 		return 0;
@@ -176,7 +176,7 @@
 
 	if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0)
 		mbname = "Unknown";
-		
+
 	/* find motherboard type */
 	seq_printf(m, "machine\t\t: ");
 	np = find_devices("device-tree");
@@ -236,7 +236,7 @@
 		int n;
 		struct reg_property *reg = (struct reg_property *)
 			get_property(np, "reg", &n);
-		
+
 		if (reg != 0) {
 			unsigned long total = 0;
 
@@ -247,9 +247,9 @@
 	}
 
 	/* Checks "l2cr-value" property in the registry */
-	np = find_devices("cpus");		
+	np = find_devices("cpus");
 	if (np == 0)
-		np = find_type_devices("cpu");		
+		np = find_type_devices("cpu");
 	if (np != 0) {
 		unsigned int *l2cr = (unsigned int *)
 			get_property(np, "l2cr-value", NULL);
@@ -257,11 +257,11 @@
 			seq_printf(m, "l2cr override\t: 0x%x\n", *l2cr);
 		}
 	}
-	
+
 	/* Indicate newworld/oldworld */
 	seq_printf(m, "pmac-generation\t: %s\n",
 		   pmac_newworld ? "NewWorld" : "OldWorld");
-	
+
 
 	return 0;
 }
@@ -285,7 +285,7 @@
 	struct device_node *cpu;
 	int *fp;
 	unsigned long pvr;
-	
+
 	pvr = PVR_VER(mfspr(PVR));
 
 	/* Set loops_per_jiffy to a half-way reasonable value,
@@ -311,12 +311,12 @@
 
 	/* Lookup PCI hosts */
 	pmac_find_bridges();
-	
+
 	/* Checks "l2cr-value" property in the registry */
 	if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) {
-		struct device_node *np = find_devices("cpus");		
+		struct device_node *np = find_devices("cpus");
 		if (np == 0)
-			np = find_type_devices("cpu");		
+			np = find_type_devices("cpu");
 		if (np != 0) {
 			unsigned int *l2cr = (unsigned int *)
 				get_property(np, "l2cr-value", NULL);
@@ -333,7 +333,7 @@
 		printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n",
 			ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000)
 				? "enabled" : "disabled");
-	
+
 #ifdef CONFIG_KGDB
 	zs_kgdb_hook(0);
 #endif
@@ -345,7 +345,7 @@
 		printk("WARNING ! Your machine is Cuda based but your kernel\n");
 		printk("          wasn't compiled with CONFIG_ADB_CUDA option !\n");
 	}
-#endif	
+#endif
 #ifdef CONFIG_ADB_PMU
 	find_via_pmu();
 #else
@@ -353,7 +353,7 @@
 		printk("WARNING ! Your machine is PMU based but your kernel\n");
 		printk("          wasn't compiled with CONFIG_ADB_PMU option !\n");
 	}
-#endif	
+#endif
 #ifdef CONFIG_NVRAM
 	pmac_nvram_init();
 #endif
@@ -520,7 +520,7 @@
 	macpart_fix_string(part->processor, 16);
 	macpart_fix_string(part->name, 32);
 	macpart_fix_string(part->type, 32);
-    
+
 	if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
 	    && strcasecmp(part->processor, "powerpc") == 0)
 		goodness++;
@@ -559,7 +559,7 @@
 	struct page* pg;
 	unsigned secsize, blocks_in_map, blk;
 	unsigned char* data;
-	
+
 	/* Check driver descriptor */
 	md = (struct mac_driver_desc *) read_one_block(bdev, 0, &pg);
 	if (!md)
@@ -568,7 +568,7 @@
 		goto fail;
 	secsize = be16_to_cpu(md->block_size);
 	page_cache_release(pg);
-	
+
 	/* Check if it looks like a mac partition map */
 	data = read_one_block(bdev, secsize/512, &pg);
 	if (!data)
@@ -591,7 +591,7 @@
 		check_bootable_part(dev, blk, part);
 	}
 fail:
-	if (pg)	
+	if (pg)
 		page_cache_release(pg);
 }
 
@@ -599,7 +599,7 @@
 walk_bootable(struct gendisk *hd, void *data)
 {
 	int drive;
-	
+
 	for (drive=0; drive<hd->nr_real; drive++) {
 		kdev_t dev;
 		struct block_device *bdev;
@@ -650,7 +650,7 @@
 #ifdef CONFIG_NVRAM
 	pmac_nvram_update();
 #endif
-	
+
 	switch (sys_ctrler) {
 #ifdef CONFIG_ADB_CUDA
 	case SYS_CTRLER_CUDA:
@@ -660,11 +660,11 @@
 			cuda_poll();
 		break;
 #endif /* CONFIG_ADB_CUDA */
-#ifdef CONFIG_ADB_PMU		
+#ifdef CONFIG_ADB_PMU
 	case SYS_CTRLER_PMU:
 		pmu_restart();
 		break;
-#endif /* CONFIG_ADB_PMU */		
+#endif /* CONFIG_ADB_PMU */
 	default: ;
 	}
 }
@@ -679,7 +679,7 @@
 #ifdef CONFIG_NVRAM
 	pmac_nvram_update();
 #endif
-	
+
 	switch (sys_ctrler) {
 #ifdef CONFIG_ADB_CUDA
 	case SYS_CTRLER_CUDA:
@@ -841,7 +841,7 @@
 	ppc_md.init_IRQ       = pmac_pic_init;
 	ppc_md.get_irq        = pmac_get_irq; /* Changed later on ... */
 	ppc_md.init           = pmac_init2;
-	
+
 	ppc_md.pcibios_fixup  = pmac_pcibios_fixup;
 	ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook;
 	ppc_md.pcibios_after_init = pmac_pcibios_after_init;
@@ -875,7 +875,7 @@
 #endif /* CONFIG_BOOTX_TEXT */
 
 	if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0);
-	
+
 }
 
 #ifdef CONFIG_BOOTX_TEXT
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pmac_sleep.S linux-2.4.22-pre10/arch/ppc/platforms/pmac_sleep.S
--- linux-2.4.21/arch/ppc/platforms/pmac_sleep.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pmac_sleep.S	2003-08-01 13:31:07.000000000 +0000
@@ -74,7 +74,7 @@
 	mftbu	r3
 	cmpw	r3,r4
 	bne	1b
-	
+
 	/* Save SPRGs */
 	mfsprg	r4,0
 	stw	r4,SL_SPRG0(r1)
@@ -162,7 +162,7 @@
 	sync
 	mtspr	SPRN_HID0,r3
 	sync
-	
+
 	/* Turn off data relocation. */
 	mfmsr	r3		/* Save MSR in r7 */
 	rlwinm	r3,r3,0,28,26	/* Turn off DR bit */
@@ -197,7 +197,7 @@
 	isync
 	b	1b
 
-/* 
+/*
  * Here is the resume code.
  */
 
@@ -217,7 +217,7 @@
 	/* Won't that cause problems on CPU that doesn't support it ? */
 	lis	r3, 0
 	mtspr	SPRN_MMCR0, r3
-	
+
 	/* sanitize MSR */
 	mfmsr	r3
 	ori	r3,r3,MSR_EE|MSR_IP
@@ -235,11 +235,11 @@
 	lwz	r1,0(r3)
 
 	/* Pass thru to older resume code ... */
-/* 
+/*
  * Here is the resume code for older machines.
  * r1 has the physical address of SL_PC(sp).
  */
-	
+
 grackle_wake_up:
 	/* Invalidate & enable L1 cache, we don't care about
 	 * whatever the ROM may have tried to write to memory
@@ -260,7 +260,7 @@
 	bdnz	3b
 	sync
 	isync
-	
+
 	subi	r1,r1,SL_PC
 
 	/* Restore various CPU config stuffs */
@@ -340,7 +340,7 @@
 
 	/* restore the MSR and turn on the MMU */
 	lwz	r3,SL_MSR(r1)
-	bl	turn_on_mmu	
+	bl	turn_on_mmu
 
 	/* get back the stack pointer */
 	tovirt(r1,r1)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pmac_smp.c linux-2.4.22-pre10/arch/ppc/platforms/pmac_smp.c
--- linux-2.4.21/arch/ppc/platforms/pmac_smp.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pmac_smp.c	2003-08-01 13:33:23.000000000 +0000
@@ -3,7 +3,7 @@
  *
  * We support both the old "powersurge" SMP architecture
  * and the current Core99 (G4 PowerMac) machines.
- * 
+ *
  * Note that we don't support the very first rev. of
  * Apple/DayStar 2 CPUs board, the one with the funky
  * watchdog. Hopefully, none of these should be there except
@@ -466,13 +466,13 @@
 
 	local_irq_save(flags);
 	local_irq_disable();
-	
+
 	/* Save reset vector */
 	save_vector = *vector;
-	
-	/* Setup fake reset vector that does	  
+
+	/* Setup fake reset vector that does
 	 *   b __secondary_start_psurge - KERNELBASE
-	 */  
+	 */
 	switch(nr) {
 		case 1:
 			new_vector = (unsigned long)__secondary_start_psurge;
@@ -485,24 +485,24 @@
 			break;
 	}
 	*vector = 0x48000002 + new_vector - KERNELBASE;
-	
+
 	/* flush data cache and inval instruction cache */
 	flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
-	
+
 	/* Put some life in our friend */
 	pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
-	
+
 	/* FIXME: We wait a bit for the CPU to take the exception, I should
 	 * instead wait for the entry code to set something for me. Well,
 	 * ideally, all that crap will be done in prom.c and the CPU left
 	 * in a RAM-based wait loop like CHRP.
 	 */
 	mdelay(1);
-	
+
 	/* Restore our exception vector */
 	*vector = save_vector;
 	flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
-	
+
 	local_irq_restore(flags);
 	if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
 }
@@ -516,7 +516,7 @@
 	 */
 	if (cpu_nr != 0)
 		core99_init_caches();
-	
+
 	/* Setup openpic */
 	do_openpic_setup_cpu();
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pmac_time.c linux-2.4.22-pre10/arch/ppc/platforms/pmac_time.c
--- linux-2.4.21/arch/ppc/platforms/pmac_time.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pmac_time.c	2003-08-01 13:32:07.000000000 +0000
@@ -63,7 +63,7 @@
 #ifdef CONFIG_NVRAM
 	s32 delta = 0;
 	int dst;
-	
+
 	delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
 	delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
 	delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
@@ -204,7 +204,7 @@
 	       tb_ticks_per_jiffy, dstart - dend);
 
 	iounmap((void *)via);
-	
+
 	return 1;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pplus_pci.c linux-2.4.22-pre10/arch/ppc/platforms/pplus_pci.c
--- linux-2.4.21/arch/ppc/platforms/pplus_pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pplus_pci.c	2003-08-01 13:30:57.000000000 +0000
@@ -0,0 +1,539 @@
+/*
+ * arch/ppc/platforms/pplus_pci.c
+ *
+ * PCI setup for MCG PowerPlus
+ *
+ * Author: Randy Vinson <rvinson@mvista.com>
+ *
+ * Derived from original PowerPlus PReP work by
+ * Cort Dougan, Johnnie Peters, Matt Porter, and
+ * Troy Benjegerdes.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/sections.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/ptrace.h>
+#include <asm/pci-bridge.h>
+#include <asm/residual.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+
+#include <asm/open_pic.h>
+#include <asm/pplus.h>
+
+unsigned char *Motherboard_map_name;
+
+/* Tables for known hardware */
+
+/* Motorola Mesquite */
+static inline int
+mesquite_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 * 	MPIC interrupts for various IDSEL values (MPIC IRQ0 =
+	 * 	Linux IRQ16 (to leave room for ISA IRQs at 0-15).
+	 *      PCI IDSEL/INTPIN->INTLINE
+	 *         A   B   C   D
+	 */
+	{
+		{ 18,  0,  0,  0 },     /* IDSEL 14 - Enet 0 */
+		{  0,  0,  0,  0 },     /* IDSEL 15 - unused */
+		{ 19, 19, 19, 19 },     /* IDSEL 16 - PMC Slot 1 */
+		{  0,  0,  0,  0 },     /* IDSEL 17 - unused */
+		{  0,  0,  0,  0 },     /* IDSEL 18 - unused */
+		{  0,  0,  0,  0 },     /* IDSEL 19 - unused */
+		{ 24, 25, 26, 27 },     /* IDSEL 20 - P2P bridge (to cPCI 1) */
+		{  0,  0,  0,  0 },     /* IDSEL 21 - unused */
+		{ 28, 29, 30, 31 }      /* IDSEL 22 - P2P bridge (to cPCI 2) */
+	};
+
+	const long min_idsel = 14, max_idsel = 22, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+/* Motorola Sitka */
+static inline int
+sitka_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 * 	MPIC interrupts for various IDSEL values (MPIC IRQ0 =
+	 * 	Linux IRQ16 (to leave room for ISA IRQs at 0-15).
+	 *      PCI IDSEL/INTPIN->INTLINE
+	 *         A   B   C   D
+	 */
+	{
+		{ 18,  0,  0,  0 },     /* IDSEL 14 - Enet 0 */
+		{  0,  0,  0,  0 },     /* IDSEL 15 - unused */
+		{ 25, 26, 27, 28 },     /* IDSEL 16 - PMC Slot 1 */
+		{ 28, 25, 26, 27 },     /* IDSEL 17 - PMC Slot 2 */
+		{  0,  0,  0,  0 },     /* IDSEL 18 - unused */
+		{  0,  0,  0,  0 },     /* IDSEL 19 - unused */
+		{ 20,  0,  0,  0 }      /* IDSEL 20 - P2P bridge (to cPCI) */
+	};
+
+	const long min_idsel = 14, max_idsel = 20, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+/* Motorola MTX */
+static inline int
+MTX_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 * 	MPIC interrupts for various IDSEL values (MPIC IRQ0 =
+	 * 	Linux IRQ16 (to leave room for ISA IRQs at 0-15).
+	 *      PCI IDSEL/INTPIN->INTLINE
+	 *         A   B   C   D
+	 */
+	{
+		{ 19,  0,  0,  0 },     /* IDSEL 12 - SCSI   */
+		{ 0,   0,  0,  0 },     /* IDSEL 13 - unused */
+		{ 18,  0,  0,  0 },     /* IDSEL 14 - Enet   */
+		{  0,  0,  0,  0 },     /* IDSEL 15 - unused */
+		{ 25, 26, 27, 28 },     /* IDSEL 16 - PMC Slot 1 */
+		{ 26, 27, 28, 25 },     /* IDSEL 17 - PMC Slot 2 */
+		{ 27, 28, 25, 26 }      /* IDSEL 18 - PCI Slot 3 */
+	};
+
+	const long min_idsel = 12, max_idsel = 18, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+/* Motorola MTX Plus */
+/* Secondary bus interrupt routing is not supported yet */
+static inline int
+MTXplus_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 * 	MPIC interrupts for various IDSEL values (MPIC IRQ0 =
+	 * 	Linux IRQ16 (to leave room for ISA IRQs at 0-15).
+	 *      PCI IDSEL/INTPIN->INTLINE
+	 *         A   B   C   D
+	 */
+	{
+		{ 19,  0,  0,  0 },     /* IDSEL 12 - SCSI   */
+		{ 0,   0,  0,  0 },     /* IDSEL 13 - unused */
+		{ 18,  0,  0,  0 },     /* IDSEL 14 - Enet 1 */
+		{  0,  0,  0,  0 },     /* IDSEL 15 - unused */
+		{ 25, 26, 27, 28 },     /* IDSEL 16 - PCI Slot 1P */
+		{ 26, 27, 28, 25 },     /* IDSEL 17 - PCI Slot 2P */
+		{ 27, 28, 25, 26 },     /* IDSEL 18 - PCI Slot 3P */
+		{ 26,  0,  0,  0 },	/* IDSEL 19 - Enet 2 */
+		{  0,  0,  0,  0 } 	/* IDSEL 20 - P2P Bridge */
+	};
+
+	const long min_idsel = 12, max_idsel = 20, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+static inline int
+Genesis2_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	/* 2600
+	 * Raven 31
+	 * ISA   11
+	 * SCSI	 12 - IRQ3
+	 * Univ  13
+	 * eth   14 - IRQ2
+	 * VGA   15 - IRQ4
+	 * PMC1  16 - IRQ9,10,11,12 = PMC1 A-D
+	 * PMC2  17 - IRQ12,9,10,11 = A-D
+	 * SCSI2 18 - IRQ11
+	 * eth2  19 - IRQ10
+	 * PCIX  20 - IRQ9,10,11,12 = PCI A-D
+	 */
+
+	/* 2400
+	 * Hawk 31
+	 * ISA	11
+	 * Univ 13
+	 * eth  14 - IRQ2
+	 * PMC1 16 - IRQ9,10,11,12 = PMC A-D
+	 * PMC2 17 - IRQ12,9,10,11 = PMC A-D
+	 * PCIX 20 - IRQ9,10,11,12 = PMC A-D
+	 */
+
+	/* 2300
+	 * Raven 31
+	 * ISA   11
+	 * Univ  13
+	 * eth   14 - IRQ2
+	 * PMC1  16 - 9,10,11,12 = A-D
+	 * PMC2  17 - 9,10,11,12 = B,C,D,A
+	 */
+
+	static char pci_irq_table[][4] =
+	/*
+	 * 	MPIC interrupts for various IDSEL values (MPIC IRQ0 =
+	 * 	Linux IRQ16 (to leave room for ISA IRQs at 0-15).
+	 *      PCI IDSEL/INTPIN->INTLINE
+	 *         A   B   C   D
+	 */
+	{
+		{ 19,  0,  0,  0 },     /* IDSEL 12 - SCSI   */
+		{ 0,   0,  0,  0 },     /* IDSEL 13 - Universe PCI - VME */
+		{ 18,  0,  0,  0 },     /* IDSEL 14 - Enet 1 */
+		{  0,  0,  0,  0 },     /* IDSEL 15 - unused */
+		{ 25, 26, 27, 28 },     /* IDSEL 16 - PCI/PMC Slot 1P */
+		{ 28, 25, 26, 27 },     /* IDSEL 17 - PCI/PMC Slot 2P */
+		{ 27, 28, 25, 26 },     /* IDSEL 18 - PCI Slot 3P */
+		{ 26,  0,  0,  0 },	/* IDSEL 19 - Enet 2 */
+		{ 25, 26, 27, 28 } 	/* IDSEL 20 - P2P Bridge */
+	};
+
+	const long min_idsel = 12, max_idsel = 20, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+#define MOTOROLA_CPUTYPE_REG	0x800
+#define MOTOROLA_BASETYPE_REG	0x803
+#define MPIC_RAVEN_ID		0x48010000
+#define	MPIC_HAWK_ID		0x48030000
+#define	MOT_PROC2_BIT		0x800
+
+static u_char pplus_openpic_initsenses[] __initdata = {
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),/* MVME2600_INT_SIO */
+	(IRQ_SENSE_EDGE  | IRQ_POLARITY_NEGATIVE),/*MVME2600_INT_FALCN_ECC_ERR*/
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/*MVME2600_INT_PCI_ETHERNET */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_SCSI */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_GRAPHICS*/
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_VME0 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_VME1 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_VME2 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_VME3 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_INTA */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_INTB */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_INTC */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_PCI_INTD */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_LM_SIG0 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),/* MVME2600_INT_LM_SIG1 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),
+};
+
+int mot_entry = -1;
+int prep_keybd_present = 1;
+int mot_multi = 0;
+
+int __init raven_init(void)
+{
+	unsigned short	devid;
+	unsigned char	base_mod;
+
+	/* set the MPIC base address */
+	early_write_config_dword(0, 0, 0, PCI_BASE_ADDRESS_1, 0x3cfc0000);
+
+	pplus_mpic_init(PREP_ISA_MEM_BASE);
+
+	OpenPIC_InitSenses = pplus_openpic_initsenses;
+	OpenPIC_NumInitSenses = sizeof(pplus_openpic_initsenses);
+
+	ppc_md.get_irq = openpic_get_irq;
+
+	/* This is a hack.  If this is a 2300 or 2400 mot board then there is
+	 * no keyboard controller and we have to indicate that.
+	 */
+
+	early_read_config_word(0, 0, 0, PCI_VENDOR_ID, &devid);
+	base_mod = inb(MOTOROLA_BASETYPE_REG);
+	if ((devid == PCI_DEVICE_ID_MOTOROLA_HAWK) ||
+	    (base_mod == 0xF9) ||
+	    (base_mod == 0xFA) || (base_mod == 0xE1))
+		prep_keybd_present = 0;
+
+	return 1;
+}
+
+struct brd_info {
+	int		cpu_type;	/* 0x100 mask assumes for Raven and Hawk boards that the level/edge are set */
+					/* 0x200 if this board has a Hawk chip. */
+	int		base_type;
+	int		max_cpu;	/* ored with 0x80 if this board should be checked for multi CPU */
+	const char	*name;
+	int		(*map_irq)(struct pci_dev *,
+			           unsigned char,
+				   unsigned char);
+};
+struct brd_info mot_info[] = {
+	{0x300, 0x00, 0x00, "MVME 2400", Genesis2_map_irq},
+	{0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)", mesquite_map_irq},
+	{0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)", sitka_map_irq},
+	{0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC", mesquite_map_irq},
+	{0x1E0, 0xF6, 0x80, "MTX Plus",	MTXplus_map_irq},
+	{0x1E0, 0xF6, 0x81, "Dual MTX Plus", MTXplus_map_irq},
+	{0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port", MTX_map_irq},
+	{0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port", MTX_map_irq},
+	{0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port", MTX_map_irq},
+	{0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port", MTX_map_irq},
+	{0x1E0, 0xF9, 0x00, "MVME 2300", Genesis2_map_irq},
+	{0x1E0, 0xFA, 0x00, "MVME 2300SC/2600",	Genesis2_map_irq},
+	{0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M", Genesis2_map_irq},
+	{0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761", Genesis2_map_irq},
+	{0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M", Genesis2_map_irq},
+	{0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M", Genesis2_map_irq},
+	{0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761", Genesis2_map_irq},
+	{0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761", Genesis2_map_irq},
+	{0x000, 0x00, 0x00, "",	NULL}
+};
+
+void __init pplus_set_board_type(void)
+{
+	unsigned char  cpu_type;
+	unsigned char  base_mod;
+	int	       entry;
+	unsigned short devid;
+	unsigned long  *ProcInfo = NULL;
+
+	cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0;
+	base_mod = inb(MOTOROLA_BASETYPE_REG);
+	early_read_config_word(0, 0, 0, PCI_VENDOR_ID, &devid);
+
+	for (entry = 0; mot_info[entry].cpu_type != 0; entry++) {
+
+		/* Check for Hawk chip */
+		if (mot_info[entry].cpu_type & 0x200) {
+			if (devid != PCI_DEVICE_ID_MOTOROLA_HAWK)
+				continue;
+		} else {
+			/* store the system config register for later use. */
+			ProcInfo = (unsigned long *)ioremap(0xfef80400, 4);
+
+			/* Check non hawk boards */
+			if ((mot_info[entry].cpu_type & 0xff) != cpu_type)
+				continue;
+
+			if (mot_info[entry].base_type == 0) {
+				mot_entry = entry;
+				break;
+			}
+
+			if (mot_info[entry].base_type != base_mod)
+				continue;
+		}
+
+		if (!(mot_info[entry].max_cpu & 0x80)) {
+			mot_entry = entry;
+			break;
+		}
+
+		/* processor 1 not present and max processor zero indicated */
+		if ((*ProcInfo & MOT_PROC2_BIT) && !(mot_info[entry].max_cpu & 0x7f)) {
+			mot_entry = entry;
+			break;
+		}
+
+		/* processor 1 present and max processor zero indicated */
+		if (!(*ProcInfo & MOT_PROC2_BIT) && (mot_info[entry].max_cpu & 0x7f)) {
+			mot_entry = entry;
+			break;
+		}
+
+		/* Indicate to system if this is a multiprocessor board */
+		if (!(*ProcInfo & MOT_PROC2_BIT)) {
+			mot_multi = 1;
+						        }
+	}
+
+	if (mot_entry == -1)
+
+		/* No particular cpu type found - assume Mesquite (MCP750) */
+		mot_entry = 1;
+
+	Motherboard_map_name = (unsigned char *)mot_info[mot_entry].name;
+	ppc_md.pci_map_irq = mot_info[mot_entry].map_irq;
+}
+void __init
+pplus_pib_init(void)
+{
+	unsigned char   reg;
+	unsigned short  short_reg;
+
+	struct pci_dev *dev = NULL;
+
+	/*
+	 * Perform specific configuration for the Via Tech or
+	 * or Winbond PCI-ISA-Bridge part.
+	 */
+	if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+					PCI_DEVICE_ID_VIA_82C586_1, dev))) {
+		/*
+		 * PPCBUG does not set the enable bits
+		 * for the IDE device. Force them on here.
+		 */
+		pci_read_config_byte(dev, 0x40, &reg);
+
+		reg |= 0x03; /* IDE: Chip Enable Bits */
+		pci_write_config_byte(dev, 0x40, reg);
+	}
+	if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+					PCI_DEVICE_ID_VIA_82C586_2,
+					dev)) && (dev->devfn = 0x5a)) {
+		/* Force correct USB interrupt */
+		dev->irq = 11;
+		pci_write_config_byte(dev,
+				PCI_INTERRUPT_LINE,
+				dev->irq);
+	}
+	if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
+					PCI_DEVICE_ID_WINBOND_83C553, dev))) {
+		/* Clear PCI Interrupt Routing Control Register. */
+		short_reg = 0x0000;
+		pci_write_config_word(dev, 0x44, short_reg);
+		/* Route IDE interrupts to IRQ 14 */
+		reg = 0xEE;
+		pci_write_config_byte(dev, 0x43, reg);
+	}
+
+	if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND,
+					PCI_DEVICE_ID_WINBOND_82C105, dev))){
+		/*
+		 * Disable LEGIRQ mode so PCI INTS are routed
+		 * directly to the 8259 and enable both channels
+		 */
+		pci_write_config_dword(dev, 0x40, 0x10ff0033);
+
+		/* Force correct IDE interrupt */
+		dev->irq = 14;
+		pci_write_config_byte(dev,
+				PCI_INTERRUPT_LINE,
+				dev->irq);
+	}
+}
+
+void __init
+pplus_set_VIA_IDE_legacy(void)
+{
+	unsigned short vend, dev;
+
+	early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend);
+	early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev);
+
+	if ((vend == PCI_VENDOR_ID_VIA) &&
+	    (dev == PCI_DEVICE_ID_VIA_82C586_1)) {
+
+		unsigned char temp;
+
+		/* put back original "standard" port base addresses */
+		early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
+				         PCI_BASE_ADDRESS_0, 0x1f1);
+		early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
+				         PCI_BASE_ADDRESS_1, 0x3f5);
+		early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
+				         PCI_BASE_ADDRESS_2, 0x171);
+		early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
+				         PCI_BASE_ADDRESS_3, 0x375);
+		early_write_config_dword(0, 0, PCI_DEVFN(0xb, 1),
+				         PCI_BASE_ADDRESS_4, 0xcc01);
+
+		/* put into legacy mode */
+		early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
+				       &temp);
+		temp &= ~0x05;
+		early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
+					temp);
+	}
+}
+
+void
+pplus_set_VIA_IDE_native(void)
+{
+	unsigned short vend, dev;
+
+	early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_VENDOR_ID, &vend);
+	early_read_config_word(0, 0, PCI_DEVFN(0xb, 1), PCI_DEVICE_ID, &dev);
+
+	if ((vend == PCI_VENDOR_ID_VIA) &&
+	    (dev == PCI_DEVICE_ID_VIA_82C586_1)) {
+
+		unsigned char temp;
+
+		/* put into native mode */
+		early_read_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
+				       &temp);
+		temp |= 0x05;
+		early_write_config_byte(0, 0, PCI_DEVFN(0xb, 1), PCI_CLASS_PROG,
+					temp);
+	}
+}
+
+void __init
+pplus_pcibios_fixup(void)
+{
+
+	printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name);
+
+	/* Setup the Winbond or Via PIB */
+	pplus_pib_init();
+}
+
+static void __init
+pplus_init_resource(struct resource *res, unsigned long start,
+		   unsigned long end, int flags)
+{
+	res->flags = flags;
+	res->start = start;
+	res->end = end;
+	res->name = "PCI host bridge";
+	res->parent = NULL;
+	res->sibling = NULL;
+	res->child = NULL;
+}
+
+void __init
+pplus_setup_hose(void)
+{
+	struct pci_controller* hose;
+
+	hose = pcibios_alloc_controller();
+	if (!hose)
+		return;
+
+	hose->first_busno = 0;
+	hose->last_busno = 0xff;
+
+	hose->pci_mem_offset = PREP_ISA_MEM_BASE;
+	hose->io_base_virt = (void *)PREP_ISA_IO_BASE;
+
+	pplus_init_resource(&hose->io_resource, 0x00000000, 0x0fffffff,
+			    IORESOURCE_IO);
+	pplus_init_resource(&hose->mem_resources[0], 0xc0000000, 0xfdffffff,
+			    IORESOURCE_MEM);
+
+	hose->io_space.start  = 0x00000000;
+	hose->io_space.end    = 0x0fffffff;
+	hose->mem_space.start = 0x00000000;
+	hose->mem_space.end   = 0x3cfbffff; /* MPIC at 0x3cfc0000-0x3dffffff */
+
+	setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc);
+
+	pplus_set_VIA_IDE_legacy();
+
+	hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+
+	ppc_md.pcibios_fixup = pplus_pcibios_fixup;
+	ppc_md.pci_swizzle = common_swizzle;
+	pplus_set_board_type();
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/pplus_setup.c linux-2.4.22-pre10/arch/ppc/platforms/pplus_setup.c
--- linux-2.4.21/arch/ppc/platforms/pplus_setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/pplus_setup.c	2003-08-01 13:31:16.000000000 +0000
@@ -0,0 +1,550 @@
+/*
+ * arch/ppc/platforms/pplus_setup.c
+ *
+ * Board setup routines for MCG PowerPlus
+ *
+ * Author: Randy Vinson <rvinson@mvista.com>
+ *
+ * Derived from original PowerPlus PReP work by
+ * Cort Dougan, Johnnie Peters, Matt Porter, and
+ * Troy Benjegerdes.
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/blk.h>
+#include <linux/ioport.h>
+#include <linux/console.h>
+#include <linux/timex.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/ide.h>
+#include <linux/kdev_t.h>
+#include <linux/seq_file.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+
+#include <asm/sections.h>
+#include <asm/mmu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/residual.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/cache.h>
+#include <asm/dma.h>
+#include <asm/machdep.h>
+#include <asm/mk48t59.h>
+#include <asm/prep_nvram.h>
+#include <asm/raven.h>
+#include <asm/keyboard.h>
+#include <asm/vga.h>
+#include <asm/time.h>
+
+#include <asm/i8259.h>
+#include <asm/open_pic.h>
+#include <asm/pplus.h>
+#include <asm/todc.h>
+#include <asm/bootinfo.h>
+#include <asm/serial.h>
+
+#undef DUMP_DBATS
+
+TODC_ALLOC();
+
+extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int pckbd_getkeycode(unsigned int scancode);
+extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+		char raw_mode);
+extern char pckbd_unexpected_up(unsigned char keycode);
+extern void pckbd_leds(unsigned char leds);
+extern void pckbd_init_hw(void);
+extern unsigned char pckbd_sysrq_xlate[128];
+
+extern char saved_command_line[];
+
+extern void pplus_setup_hose(void);
+extern void pplus_set_VIA_IDE_native(void);
+
+extern unsigned long loops_per_jiffy;
+
+extern void gen550_progress(char *, unsigned short);
+extern void gen550_init(int, struct serial_struct *);
+
+static int
+pplus_show_cpuinfo(struct seq_file *m)
+{
+	extern char *Motherboard_map_name;
+
+	seq_printf(m, "vendor\t\t: Motorola MCG\n");
+	seq_printf(m, "machine\t\t: %s\n", Motherboard_map_name);
+
+	return 0;
+}
+
+static void __init
+pplus_setup_arch(void)
+{
+	unsigned char reg;
+
+	if ( ppc_md.progress )
+		ppc_md.progress("pplus_setup_arch: enter", 0);
+
+	/* init to some ~sane value until calibrate_delay() runs */
+	loops_per_jiffy = 50000000;
+
+	if ( ppc_md.progress )
+		ppc_md.progress("pplus_setup_arch: find_bridges", 0);
+
+	/* Setup PCI host bridge */
+	pplus_setup_hose();
+
+	/* Set up floppy in PS/2 mode */
+	outb(0x09, SIO_CONFIG_RA);
+	reg = inb(SIO_CONFIG_RD);
+	reg = (reg & 0x3F) | 0x40;
+	outb(reg, SIO_CONFIG_RD);
+	outb(reg, SIO_CONFIG_RD);	/* Have to write twice to change! */
+
+	/* Enable L2.  Assume we don't need to flush -- Cort*/
+	*(unsigned char *)(0x8000081c) |= 3;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (initrd_start)
+		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
+	else
+#endif
+#ifdef CONFIG_ROOT_NFS
+		ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs */
+#else
+		ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */
+#endif
+
+	printk(KERN_INFO "Motorola PowerPlus Platform\n");
+	printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n");
+
+	if ( ppc_md.progress )
+		ppc_md.progress("pplus_setup_arch: raven_init", 0);
+
+	raven_init();
+
+#ifdef CONFIG_VGA_CONSOLE
+	/* remap the VGA memory */
+	vgacon_remap_base = 0xf0000000;
+	conswitchp = &vga_con;
+#elif defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;
+#endif
+#ifdef CONFIG_PPCBUG_NVRAM
+	/* Read in NVRAM data */
+	init_prep_nvram();
+
+	/* if no bootargs, look in NVRAM */
+	if ( cmd_line[0] == '\0' ) {
+		char *bootargs;
+		 bootargs = prep_nvram_get_var("bootargs");
+		 if (bootargs != NULL) {
+			 strcpy(cmd_line, bootargs);
+			 /* again.. */
+			 strcpy(saved_command_line, cmd_line);
+		}
+	}
+#endif
+	if ( ppc_md.progress )
+		ppc_md.progress("pplus_setup_arch: exit", 0);
+}
+
+static void
+pplus_restart(char *cmd)
+{
+	unsigned long i = 10000;
+
+	__cli();
+
+	/* set VIA IDE controller into native mode */
+	pplus_set_VIA_IDE_native();
+
+	/* set exception prefix high - to the prom */
+	_nmask_and_or_msr(0, MSR_IP);
+
+	/* make sure bit 0 (reset) is a 0 */
+	outb( inb(0x92) & ~1L , 0x92 );
+	/* signal a reset to system control port A - soft reset */
+	outb( inb(0x92) | 1 , 0x92 );
+
+	while ( i != 0 ) i++;
+	panic("restart failed\n");
+}
+
+static void
+pplus_halt(void)
+{
+	unsigned long flags;
+	__cli();
+	/* set exception prefix high - to the prom */
+	save_flags( flags );
+	restore_flags( flags|MSR_IP );
+
+	/* make sure bit 0 (reset) is a 0 */
+	outb( inb(0x92) & ~1L , 0x92 );
+	/* signal a reset to system control port A - soft reset */
+	outb( inb(0x92) | 1 , 0x92 );
+
+	while ( 1 ) ;
+	/*
+	 * Not reached
+	 */
+}
+
+static void
+pplus_power_off(void)
+{
+	pplus_halt();
+}
+
+static unsigned int
+pplus_irq_cannonicalize(u_int irq)
+{
+	if (irq == 2)
+	{
+		return 9;
+	}
+	else
+	{
+		return irq;
+	}
+}
+
+static void __init
+pplus_init_IRQ(void)
+{
+	int i;
+
+	if (OpenPIC_Addr != NULL) {
+		openpic_set_sources(0, 16, OpenPIC_Addr+0x10000);
+		openpic_init(NUM_8259_INTERRUPTS);
+		openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
+					i8259_irq);
+	}
+
+	for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
+		irq_desc[i].handler = &i8259_pic;
+	i8259_init(0);
+}
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+/*
+ * IDE stuff.
+ */
+static int
+pplus_ide_default_irq(ide_ioreg_t base)
+{
+	switch (base) {
+		case 0x1f0: return 14;
+		case 0x170: return 15;
+		default: return 0;
+	}
+}
+
+static ide_ioreg_t
+pplus_ide_default_io_base(int index)
+{
+	switch (index) {
+		case 0: return 0x1f0;
+		case 1: return 0x170;
+		default:
+			return 0;
+	}
+}
+
+static void __init
+pplus_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
+{
+	ide_ioreg_t reg = data_port;
+	int i;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = reg;
+		reg += 1;
+	}
+	if (ctrl_port) {
+		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+	} else {
+		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
+	}
+	if (irq != NULL)
+		*irq = pplus_ide_default_irq(data_port);
+}
+#endif
+
+#ifdef CONFIG_SMP
+/* PowerPlus (MTX) support */
+static int __init
+smp_pplus_probe(void)
+{
+	extern int mot_multi;
+
+	if (mot_multi) {
+		openpic_request_IPIs();
+		smp_hw_index[1] = 1;
+		return 2;
+	}
+
+	return 1;
+}
+
+static void __init
+smp_pplus_kick_cpu(int nr)
+{
+	*(unsigned long *)KERNELBASE = nr;
+	asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
+	printk("CPU1 reset, waiting\n");
+}
+
+static void __init
+smp_pplus_setup_cpu(int cpu_nr)
+{
+	if (OpenPIC_Addr)
+		do_openpic_setup_cpu();
+}
+
+static struct smp_ops_t pplus_smp_ops = {
+	smp_openpic_message_pass,
+	smp_pplus_probe,
+	smp_pplus_kick_cpu,
+	smp_pplus_setup_cpu,
+};
+#endif /* CONFIG_SMP */
+
+#ifdef DUMP_DBATS
+static void print_dbat(int idx, u32 bat) {
+
+	char str[64];
+
+	sprintf(str, "DBAT%c%c = 0x%08x\n",
+		(char)((idx - DBAT0U) / 2) + '0',
+		(idx & 1) ? 'L' : 'U', bat);
+	ppc_md.progress(str, 0);
+}
+
+#define DUMP_DBAT(x) \
+	do { \
+	u32 __temp = mfspr(x);\
+	print_dbat(x, __temp); \
+	} while (0)
+
+static void dump_dbats(void) {
+
+	if (ppc_md.progress) {
+		DUMP_DBAT(DBAT0U);
+		DUMP_DBAT(DBAT0L);
+		DUMP_DBAT(DBAT1U);
+		DUMP_DBAT(DBAT1L);
+		DUMP_DBAT(DBAT2U);
+		DUMP_DBAT(DBAT2L);
+		DUMP_DBAT(DBAT3U);
+		DUMP_DBAT(DBAT3L);
+	}
+}
+#endif
+
+static unsigned long __init
+pplus_find_end_of_memory(void)
+{
+	unsigned long total;
+
+	if (ppc_md.progress)
+		ppc_md.progress("pplus_find_end_of_memory",0);
+
+#ifdef DUMP_DBATS
+	dump_dbats();
+#endif
+
+	total = pplus_get_mem_size(0xfef80000);
+	return (total);
+}
+
+static void __init
+pplus_map_io(void)
+{
+	io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO);
+	io_block_mapping(0xf0000000, 0xc0000000, 0x08000000, _PAGE_IO);
+}
+
+static void __init
+pplus_init2(void)
+{
+#ifdef CONFIG_NVRAM
+	request_region(PREP_NVRAM_AS0, 0x8, "nvram");
+#endif
+	request_region(0x20,0x20,"pic1");
+	request_region(0xa0,0x20,"pic2");
+	request_region(0x00,0x20,"dma1");
+	request_region(0x40,0x20,"timer");
+	request_region(0x80,0x10,"dma page reg");
+	request_region(0xc0,0x20,"dma2");
+}
+
+/*
+ * Set BAT 2 to access 0x8000000 so progress messages will work and set BAT 3
+ * to 0xf0000000 to access Falcon/Raven or Hawk registers
+ */
+static __inline__ void
+pplus_set_bat(void)
+{
+	static int      mapping_set = 0;
+
+	if (!mapping_set) {
+
+		/* wait for all outstanding memory accesses to complete */
+		mb();
+
+		/* setup DBATs */
+		mtspr(DBAT2U, 0x80001ffe);
+		mtspr(DBAT2L, 0x8000002a);
+		mtspr(DBAT3U, 0xf0001ffe);
+		mtspr(DBAT3L, 0xf000002a);
+
+		/* wait for updates */
+		mb();
+
+		mapping_set = 1;
+	}
+
+	return;
+}
+
+#if defined(CONFIG_SERIAL) && \
+	(defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB))
+extern struct serial_state rs_table[];
+
+static void __init
+pplus_early_serial_map(void)
+{
+	struct serial_struct serial_req;
+
+	/* Setup serial port access */
+	memset(&serial_req, 0, sizeof(serial_req));
+
+	/*
+	 * rs_table[] already set up by <asm/pc_serial.h> so use that info for
+	 * gen550_init().  This also means early_serial_setup() doesn't
+	 * have to be called.
+	 */
+	serial_req.port = rs_table[0].port;
+	serial_req.io_type = rs_table[0].io_type;
+	serial_req.iomem_reg_shift = rs_table[0].iomem_reg_shift;
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+	gen550_init(0, &serial_req);
+#endif
+
+	serial_req.port = rs_table[1].port;
+	serial_req.io_type = rs_table[1].io_type;
+	serial_req.iomem_reg_shift = rs_table[1].iomem_reg_shift;
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+	gen550_init(1, &serial_req);
+#endif
+}
+#endif
+
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+		unsigned long r6, unsigned long r7)
+{
+	parse_bootinfo(find_bootinfo());
+
+	/* Map in board regs, etc. */
+	pplus_set_bat();
+
+	isa_io_base = PREP_ISA_IO_BASE;
+	isa_mem_base = PREP_ISA_MEM_BASE;
+	pci_dram_offset = PREP_PCI_DRAM_OFFSET;
+	ISA_DMA_THRESHOLD = 0x00ffffff;
+	DMA_MODE_READ = 0x44;
+	DMA_MODE_WRITE = 0x48;
+
+	ppc_md.setup_arch     = pplus_setup_arch;
+	ppc_md.show_percpuinfo = NULL;
+	ppc_md.show_cpuinfo    = pplus_show_cpuinfo;
+	ppc_md.irq_cannonicalize = pplus_irq_cannonicalize;
+	ppc_md.init_IRQ       = pplus_init_IRQ;
+	/* this gets changed later on if we have an OpenPIC -- Cort */
+	ppc_md.get_irq        = i8259_irq;
+	ppc_md.init           = pplus_init2;
+
+	ppc_md.restart        = pplus_restart;
+	ppc_md.power_off      = pplus_power_off;
+	ppc_md.halt           = pplus_halt;
+
+	TODC_INIT(TODC_TYPE_MK48T59, PREP_NVRAM_AS0, PREP_NVRAM_AS1,
+		  PREP_NVRAM_DATA, 8);
+
+	ppc_md.time_init      = todc_time_init;
+	ppc_md.set_rtc_time   = todc_set_rtc_time;
+	ppc_md.get_rtc_time   = todc_get_rtc_time;
+	ppc_md.calibrate_decr = todc_calibrate_decr;
+	ppc_md.nvram_read_val = todc_m48txx_read_val;
+	ppc_md.nvram_write_val = todc_m48txx_write_val;
+
+	ppc_md.find_end_of_memory = pplus_find_end_of_memory;
+	ppc_md.setup_io_mappings = pplus_map_io;
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+	ppc_ide_md.default_irq = pplus_ide_default_irq;
+	ppc_ide_md.default_io_base = pplus_ide_default_io_base;
+	ppc_ide_md.ide_init_hwif = pplus_ide_init_hwif_ports;
+#endif
+
+#ifdef CONFIG_VT
+	ppc_md.kbd_setkeycode    = pckbd_setkeycode;
+	ppc_md.kbd_getkeycode    = pckbd_getkeycode;
+	ppc_md.kbd_translate     = pckbd_translate;
+	ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
+	ppc_md.kbd_leds          = pckbd_leds;
+	ppc_md.kbd_init_hw       = pckbd_init_hw;
+#ifdef CONFIG_MAGIC_SYSRQ
+	ppc_md.ppc_kbd_sysrq_xlate	 = pckbd_sysrq_xlate;
+	SYSRQ_KEY = 0x54;
+#endif
+#endif
+
+#if defined(CONFIG_SERIAL) && \
+	(defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB))
+	pplus_early_serial_map();
+
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+	ppc_md.progress = gen550_progress;
+#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+#endif
+
+#ifdef CONFIG_SMP
+	ppc_md.smp_ops		 = &pplus_smp_ops;
+#endif /* CONFIG_SMP */
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/prep_pci.c linux-2.4.22-pre10/arch/ppc/platforms/prep_pci.c
--- linux-2.4.21/arch/ppc/platforms/prep_pci.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/prep_pci.c	2003-08-01 13:34:45.000000000 +0000
@@ -43,7 +43,7 @@
 /* Used for Motorola to store system config register */
 static unsigned long	*ProcInfo;
 
-/* Tables for known hardware */   
+/* Tables for known hardware */
 
 /* Motorola PowerStackII - Utah */
 static char Utah_pci_IRQ_map[23] __prepdata =
@@ -155,7 +155,7 @@
    	15,	/* Line 3 */
    	15	/* Line 4 */
 };
-   
+
 /* Motorola Mesquite */
 static char Mesquite_pci_IRQ_map[23] __prepdata =
 {
@@ -271,7 +271,7 @@
 {
    	0,	/* This is a dummy structure */
 };
-   
+
 /* Motorola MVME16xx */
 static char Genesis_pci_IRQ_map[16] __prepdata =
 {
@@ -301,7 +301,7 @@
    	14,	/* Line 3 */
    	15	/* Line 4 */
 };
-   
+
 static char Genesis2_pci_IRQ_map[23] __prepdata =
 {
 	0,	/* Slot 0  - unused */
@@ -616,7 +616,7 @@
 #define ELCRM_INT5_LVL          0x20
 
 #define CFGPTR(dev) (0x80800000 | (1<<(dev>>3)) | ((dev&7)<<8) | offset)
-#define DEVNO(dev)  (dev>>3)                                  
+#define DEVNO(dev)  (dev>>3)
 
 #define cfg_read(val, addr, type, op)	*val = op((type)(addr))
 #define cfg_write(val, addr, type, op)	op((type *)(addr), (val))
@@ -740,7 +740,7 @@
 	OpenPIC_NumInitSenses = sizeof(prep_openpic_initsenses);
 
 	ppc_md.get_irq = openpic_get_irq;
-	
+
 	/* If raven is present on Motorola store the system config register
 	 * for later use.
 	 */
@@ -916,7 +916,7 @@
 	unsigned char *ibc_pirq = (unsigned char *)0x80800860;
 	unsigned char *ibc_pcicon = (unsigned char *)0x80800840;
 	int i;
-	
+
 	if ( _prep_type == _PREP_Motorola)
 	{
 		unsigned short irq_mode;
@@ -989,7 +989,7 @@
 		printk("No known machine pci routing!\n");
 		return;
 	}
-	
+
 	/* Set up mapping from slots */
 	for (i = 1;  i <= 4;  i++)
 		ibc_pirq[i-1] = Motherboard_routes[i];
@@ -1010,7 +1010,7 @@
 		 * Perform specific configuration for the Via Tech or
 		 * or Winbond PCI-ISA-Bridge part.
 		 */
-		if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, 
+		if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
 					PCI_DEVICE_ID_VIA_82C586_1, dev))) {
 			/*
 			 * PPCBUG does not set the enable bits
@@ -1109,7 +1109,7 @@
 	 * the devfn of the bus bridge with secondary inputs, use those.
 	 * Otherwise, assume it's a PMC site and get the interrupt line
 	 * value from the interrupt routing table.
-	 */ 
+	 */
 	if (mot_info[mot_entry].secondary_bridge_devfn) {
 		pbus = dev->bus;
 
@@ -1183,7 +1183,7 @@
 				      (dev->resource[i].start > 0x10000000))  {
 				printk("Relocating PCI address %lx -> %lx\n",
 						dev->resource[i].start,
-						(dev->resource[i].start & 
+						(dev->resource[i].start &
 						 0x00FFFFFF)| 0x01000000);
 				dev->resource[i].start =
 					(dev->resource[i].start & 0x00FFFFFF)
@@ -1191,7 +1191,7 @@
 		                pci_write_config_dword(dev,
 						PCI_BASE_ADDRESS_0 + (i*0x4),
 						dev->resource[i].start);
-				dev->resource[i].end = 
+				dev->resource[i].end =
 					(dev->resource[i].end & 0x00FFFFFF)
 					| 0x01000000;
 		        }
@@ -1213,8 +1213,8 @@
 prep_pcibios_after_init(void)
 {
 	struct pci_dev *dev;
-	
-	/* If there is a WD 90C, reset the IO BAR to 0x0 (it started that 
+
+	/* If there is a WD 90C, reset the IO BAR to 0x0 (it started that
 	 * way, but the PCI layer relocated it because it thought 0x0 was
 	 * invalid for a BAR).
 	 * If you don't do this, the card's VGA base will be <IO BAR>+0xc0000
@@ -1263,7 +1263,7 @@
 	hose->ops = &prep_pci_ops;
 
 	printk("PReP architecture\n");
-#ifdef CONFIG_PREP_RESIDUAL	  
+#ifdef CONFIG_PREP_RESIDUAL
 	{
 		PPC_DEVICE *hostbridge;
 
@@ -1277,7 +1277,7 @@
 				3, 0);
 			if(pkt) {
 #define p pkt->L4_Pack.L4_Data.L4_PPCPack
-				setup_indirect_pci(hose, 
+				setup_indirect_pci(hose,
 					ld_le32((unsigned *) (p.PPCData)),
 					ld_le32((unsigned *) (p.PPCData+8)));
 #undef p
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/prep_setup.c linux-2.4.22-pre10/arch/ppc/platforms/prep_setup.c
--- linux-2.4.21/arch/ppc/platforms/prep_setup.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/prep_setup.c	2003-08-01 13:34:27.000000000 +0000
@@ -102,7 +102,7 @@
 /* for the mac fs */
 kdev_t boot_dev;
 
-#ifdef CONFIG_SOUND_CS4232 
+#ifdef CONFIG_SOUND_CS4232
 long ppc_cs4232_dma, ppc_cs4232_dma2;
 #endif
 
@@ -111,7 +111,7 @@
 extern int probingmem;
 extern unsigned long loops_per_jiffy;
 
-#ifdef CONFIG_SOUND_CS4232 
+#ifdef CONFIG_SOUND_CS4232
 EXPORT_SYMBOL(ppc_cs4232_dma);
 EXPORT_SYMBOL(ppc_cs4232_dma2);
 #endif
@@ -196,7 +196,7 @@
 
 	/* print info about the SCSI fuse */
 	seq_printf(m, "scsi fuse\t: ");
-	if (equip_reg & PREP_IBM_EQUIPMENT_SCSIFUSE) 
+	if (equip_reg & PREP_IBM_EQUIPMENT_SCSIFUSE)
 		seq_printf(m, "ok");
 	else
 		seq_printf(m, "bad");
@@ -210,8 +210,8 @@
 		for (i = 0; (res->ActualNumMemories) && (i < MAX_MEMS); i++) {
 			if (res->Memories[i].SIMMSize != 0)
 				seq_printf(m, "%d:%ldMiB ", i,
-					(res->Memories[i].SIMMSize > 1024) ? 
-					res->Memories[i].SIMMSize>>20 : 
+					(res->Memories[i].SIMMSize > 1024) ?
+					res->Memories[i].SIMMSize>>20 :
 					res->Memories[i].SIMMSize);
 		}
 		seq_printf(m, "\n");
@@ -374,12 +374,12 @@
 			seq_printf(m, "async, ");
 		else
 			seq_printf(m, "sync burst, ");
-		
+
 		if (l2_reg & 0x4)
 			seq_printf(m, "parity, ");
 		else
 			seq_printf(m, "no parity, ");
-		
+
 		switch (l2_reg & 0x3) {
 			case 0x0:
 				seq_printf(m, "256KiB\n");
@@ -453,8 +453,8 @@
 		for (i = 0; (res->ActualNumMemories) && (i < MAX_MEMS); i++) {
 			if (res->Memories[i].SIMMSize != 0)
 				seq_printf(m, "%d:%ldM ", i,
-					(res->Memories[i].SIMMSize > 1024) ? 
-					res->Memories[i].SIMMSize>>20 : 
+					(res->Memories[i].SIMMSize > 1024) ?
+					res->Memories[i].SIMMSize>>20 :
 					res->Memories[i].SIMMSize);
 		}
 		seq_printf(m, "\n");
@@ -570,7 +570,7 @@
 {
 	/* PREP's without residual data will give incorrect values here */
 	seq_printf(m, "clock\t\t: ");
-#ifdef CONFIG_PREP_RESIDUAL	
+#ifdef CONFIG_PREP_RESIDUAL
 	if (res->ResidualLength)
 		seq_printf(m, "%ldMHz\n",
 			   (res->VitalProductData.ProcessorHz > 1024) ?
@@ -583,7 +583,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_SOUND_CS4232 
+#ifdef CONFIG_SOUND_CS4232
 static long __init masktoint(unsigned int i)
 {
 	int t = -1;
@@ -594,7 +594,7 @@
 
 /*
  * ppc_cs4232_dma and ppc_cs4232_dma2 are used in include/asm/dma.h
- * to distinguish sound dma-channels from others. This is because 
+ * to distinguish sound dma-channels from others. This is because
  * blocksize on 16 bit dma-channels 5,6,7 is 128k, but
  * the cs4232.c uses 64k like on 8 bit dma-channels 0,1,2,3
  */
@@ -605,7 +605,7 @@
 
 	/*
 	 * Get the needed resource informations from residual data.
-	 * 
+	 *
 	 */
 #ifdef CONFIG_PREP_RESIDUAL
 	audiodevice = residual_find_device(~0, NULL, MultimediaController,
@@ -627,7 +627,7 @@
 	/*
 	 * These are the PReP specs' defaults for the cs4231.  We use these
 	 * as fallback incase we don't have residual data.
-	 * At least the IBM Thinkpad 850 with IDE DMA Channels at 6 and 7 
+	 * At least the IBM Thinkpad 850 with IDE DMA Channels at 6 and 7
 	 * will use the other values.
 	 */
 	if (audiodevice == NULL) {
@@ -636,7 +636,7 @@
 			ppc_cs4232_dma = 1;
 			ppc_cs4232_dma2 = -1;
 			break;
-		default: 
+		default:
 			ppc_cs4232_dma = 6;
 			ppc_cs4232_dma2 = 7;
 		}
@@ -659,8 +659,7 @@
 prep_init_vesa(void)
 {
 #if defined(CONFIG_PREP_RESIDUAL) && \
-	(defined(CONFIG_FB_VGA16) || defined(CONFIG_FB_VGA_16_MODULE) || \
-	 defined(CONFIG_FB_VESA))
+	(defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB))
 	PPC_DEVICE *vgadev;
 
 	vgadev = residual_find_device(~0, NULL, DisplayController, SVGAController,
@@ -700,10 +699,10 @@
 
 	/* init to some ~sane value until calibrate_delay() runs */
 	loops_per_jiffy = 50000000;
-	
+
 	/* Lookup PCI host bridges */
 	prep_find_bridges();
-	
+
 	/* Set up floppy in PS/2 mode */
 	outb(0x09, SIO_CONFIG_RA);
 	reg = inb(SIO_CONFIG_RD);
@@ -782,7 +781,7 @@
 		break;
 	}
 
-	/* Read in NVRAM data */ 
+	/* Read in NVRAM data */
 	init_prep_nvram();
 
 	/* if no bootargs, look in NVRAM */
@@ -796,7 +795,7 @@
 		}
 	}
 
-#ifdef CONFIG_SOUND_CS4232 
+#ifdef CONFIG_SOUND_CS4232
 	prep_init_sound();
 #endif /* CONFIG_SOUND_CS4232 */
 
@@ -840,7 +839,7 @@
 		tb_ticks_per_jiffy = freq / HZ / divisor;
 		return 0;
 	} else
-#endif	
+#endif
 		return 1;
 }
 
@@ -915,12 +914,12 @@
 	tmp = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB);
 	if (tmp & MK48T59_RTC_CB_STOP) {
 		printk("Warning: RTC was stopped, date will be wrong.\n");
-		ppc_md.nvram_write_val(MK48T59_RTC_CONTROLB, 
+		ppc_md.nvram_write_val(MK48T59_RTC_CONTROLB,
 					 tmp & ~MK48T59_RTC_CB_STOP);
 		/* Low frequency crystal oscillators may take a very long
 		 * time to startup and stabilize. For now just ignore the
 		 * the issue, but attempting to calibrate the decrementer
-		 * from the RTC just after this wakeup is likely to be very 
+		 * from the RTC just after this wakeup is likely to be very
 		 * inaccurate. Firmware should not allow to load
 		 * the OS with the clock stopped anyway...
 		 */
@@ -944,11 +943,11 @@
 	unsigned char save_control;
 	long i;
 	unsigned char sec;
- 
-		
+
+
 	/* Make sure the time is not stopped. */
 	save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB);
-	
+
 	ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA,
 			(save_control & (~MK48T59_RTC_CB_STOP)));
 
@@ -1135,7 +1134,7 @@
 prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
 		unsigned long r6, unsigned long r7)
 {
-#ifdef CONFIG_PREP_RESIDUAL	
+#ifdef CONFIG_PREP_RESIDUAL
 	/* make a copy of residual data */
 	if ( r3 ) {
 		memcpy((void *)res,(void *)(r3+KERNELBASE),
@@ -1151,7 +1150,7 @@
 	DMA_MODE_WRITE = 0x48;
 
 	/* figure out what kind of prep workstation we are */
-#ifdef CONFIG_PREP_RESIDUAL	
+#ifdef CONFIG_PREP_RESIDUAL
 	if ( res->ResidualLength != 0 ) {
 		if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) )
 			_prep_type = _PREP_IBM;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/prep_time.c linux-2.4.22-pre10/arch/ppc/platforms/prep_time.c
--- linux-2.4.21/arch/ppc/platforms/prep_time.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/prep_time.c	2003-08-01 13:33:19.000000000 +0000
@@ -114,10 +114,10 @@
 
 	/* Since the UIP flag is set for about 2.2 ms and the clock
 	 * is typically written with a precision of 1 jiffy, trying
-	 * to obtain a precision better than a few milliseconds is 
+	 * to obtain a precision better than a few milliseconds is
 	 * an illusion. Only consistency is interesting, this also
 	 * allows to use the routine for /dev/rtc without a potential
-	 * 1 second kernel busy loop triggered by any reader of /dev/rtc. 
+	 * 1 second kernel busy loop triggered by any reader of /dev/rtc.
 	 */
 
 	for ( i = 0; i<1000000; i++) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/proc_rtas.c linux-2.4.22-pre10/arch/ppc/platforms/proc_rtas.c
--- linux-2.4.21/arch/ppc/platforms/proc_rtas.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/proc_rtas.c	2003-08-01 13:34:59.000000000 +0000
@@ -93,7 +93,7 @@
 /* Tokens for indicators */
 #define TONE_FREQUENCY		0x0001 /* 0 - 1000 (HZ)*/
 #define TONE_VOLUME		0x0002 /* 0 - 100 (%) */
-#define SYSTEM_POWER_STATE	0x0003 
+#define SYSTEM_POWER_STATE	0x0003
 #define WARNING_LIGHT		0x0004
 #define DISK_ACTIVITY_LIGHT	0x0005
 #define HEX_DISPLAY_UNIT	0x0006
@@ -107,7 +107,7 @@
 /* 9006 - 9999: Vendor specific */
 
 /* other */
-#define MAX_SENSORS		 17  /* I only know of 17 sensors */    
+#define MAX_SENSORS		 17  /* I only know of 17 sensors */
 #define MAX_LINELENGTH          256
 #define SENSOR_PREFIX		"ibm,sensor-"
 #define cel_to_fahr(x)		((x*9/5)+32)
@@ -138,9 +138,9 @@
 /* Declarations */
 static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off,
 		int count, int *eof, void *data);
-static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, 
+static ssize_t ppc_rtas_clock_read(struct file * file, char * buf,
 		size_t count, loff_t *ppos);
-static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, 
+static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf,
 		size_t count, loff_t *ppos);
 static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
 		size_t count, loff_t *ppos);
@@ -184,7 +184,7 @@
 };
 
 int ppc_rtas_find_all_sensors (void);
-int ppc_rtas_process_sensor(struct individual_sensor s, int state, 
+int ppc_rtas_process_sensor(struct individual_sensor s, int state,
 		int error, char * buf);
 char * ppc_rtas_process_error(int error);
 int get_location_code(struct individual_sensor s, char * buf);
@@ -202,7 +202,7 @@
 	if ((rtas == 0) || (_machine != _MACH_chrp)) {
 		return;
 	}
-	
+
 	proc_rtas = proc_mkdir("rtas", 0);
 	if (proc_rtas == 0)
 		return;
@@ -212,19 +212,19 @@
 	entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, proc_rtas);
 	if (entry) entry->proc_fops = &ppc_rtas_progress_operations;
 
-	entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_rtas); 
+	entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_rtas);
 	if (entry) entry->proc_fops = &ppc_rtas_clock_operations;
 
-	entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas); 
+	entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas);
 	if (entry) entry->proc_fops = &ppc_rtas_poweron_operations;
 
-	create_proc_read_entry("sensors", S_IRUGO, proc_rtas, 
+	create_proc_read_entry("sensors", S_IRUGO, proc_rtas,
 			ppc_rtas_sensor_read, NULL);
-	
-	entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_rtas); 
+
+	entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_rtas);
 	if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations;
 
-	entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas); 
+	entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas);
 	if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations;
 }
 
@@ -248,11 +248,11 @@
 
 	to_tm(nowtime, &tm);
 
-	error = call_rtas("set-time-for-power-on", 7, 1, NULL, 
-			tm.tm_year, tm.tm_mon, tm.tm_mday, 
+	error = call_rtas("set-time-for-power-on", 7, 1, NULL,
+			tm.tm_year, tm.tm_mon, tm.tm_mday,
 			tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */);
 	if (error != 0)
-		printk(KERN_WARNING "error: setting poweron time returned: %s\n", 
+		printk(KERN_WARNING "error: setting poweron time returned: %s\n",
 				ppc_rtas_process_error(error));
 	return count;
 }
@@ -287,7 +287,7 @@
 	strcpy(progress_led, buf); /* save the string */
 	/* Lets see if the user passed hexdigits */
 	hex = simple_strtoul(buf, NULL, 10);
-	
+
 	ppc_md.progress ((char *)buf, hex);
 	return count;
 
@@ -313,7 +313,7 @@
 /* ****************************************************************** */
 /* CLOCK                                                              */
 /* ****************************************************************** */
-static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, 
+static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf,
 		size_t count, loff_t *ppos)
 {
 	struct rtc_time tm;
@@ -328,16 +328,16 @@
 	}
 
 	to_tm(nowtime, &tm);
-	error = call_rtas("set-time-of-day", 7, 1, NULL, 
-			tm.tm_year, tm.tm_mon, tm.tm_mday, 
+	error = call_rtas("set-time-of-day", 7, 1, NULL,
+			tm.tm_year, tm.tm_mon, tm.tm_mday,
 			tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
 	if (error != 0)
-		printk(KERN_WARNING "error: setting the clock returned: %s\n", 
+		printk(KERN_WARNING "error: setting the clock returned: %s\n",
 				ppc_rtas_process_error(error));
 	return count;
 }
 /* ****************************************************************** */
-static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, 
+static ssize_t ppc_rtas_clock_read(struct file * file, char * buf,
 		size_t count, loff_t *ppos)
 {
 	unsigned int year, mon, day, hour, min, sec;
@@ -345,15 +345,15 @@
 	int n, error;
 
 	error = call_rtas("get-time-of-day", 0, 8, ret);
-	
+
 	year = ret[0]; mon  = ret[1]; day  = ret[2];
 	hour = ret[3]; min  = ret[4]; sec  = ret[5];
 
 	if (error != 0){
-		printk(KERN_WARNING "error: reading the clock returned: %s\n", 
+		printk(KERN_WARNING "error: reading the clock returned: %s\n",
 				ppc_rtas_process_error(error));
 		n = sprintf (buf, "0");
-	} else { 
+	} else {
 		n = sprintf (buf, "%lu\n", mktime(year, mon, day, hour, min, sec));
 	}
 	kfree(ret);
@@ -395,7 +395,7 @@
 		j = sensors.sensor[i].quant;
 		/* A sensor may have multiple instances */
 		while (j >= 0) {
-			error =	call_rtas("get-sensor-state", 2, 2, &ret, 
+			error =	call_rtas("get-sensor-state", 2, 2, &ret,
 				  sensors.sensor[i].token, sensors.sensor[i].quant-j);
 			state = (int) ret;
 			n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n );
@@ -479,8 +479,8 @@
  * Builds a string out of what the sensor said
  */
 
-int ppc_rtas_process_sensor(struct individual_sensor s, int state, 
-		int error, char * buf) 
+int ppc_rtas_process_sensor(struct individual_sensor s, int state,
+		int error, char * buf)
 {
 	/* Defined return vales */
 	const char * key_switch[]        = { "Off\t", "Normal\t", "Secure\t", "Mainenance" };
@@ -488,7 +488,7 @@
 	const char * lid_status[]        = { " ", "Open", "Closed" };
 	const char * power_source[]      = { "AC\t", "Battery", "AC & Battery" };
 	const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" };
-	const char * epow_sensor[]       = { 
+	const char * epow_sensor[]       = {
 		"EPOW Reset", "Cooling warning", "Power warning",
 		"System shutdown", "System halt", "EPOW main enclosure",
 		"EPOW power off" };
@@ -632,8 +632,8 @@
 
 
 /* ****************************************************************** */
-/* 
- * Format: 
+/*
+ * Format:
  * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ]
  * the '.' may be an abbrevation
  */
@@ -670,7 +670,7 @@
 	len = strlen(tmp);
 	while (strlen(tmp) < 4)
 		n += sprintf (tmp+n, "0");
-	
+
 	/* invert the string */
 	while (tmp[i]) {
 		if (i<len)
@@ -721,7 +721,7 @@
 	error = call_rtas("set-indicator", 3, 1, NULL,
 			TONE_FREQUENCY, 0, freq);
 	if (error != 0)
-		printk(KERN_WARNING "error: setting tone frequency returned: %s\n", 
+		printk(KERN_WARNING "error: setting tone frequency returned: %s\n",
 				ppc_rtas_process_error(error));
 	return count;
 }
@@ -757,12 +757,12 @@
 	}
 	if (volume < 0) volume = 0;
 	if (volume > 100) volume = 100;
-	
+
         rtas_tone_volume = volume; /* save it for later */
 	error = call_rtas("set-indicator", 3, 1, NULL,
 			TONE_VOLUME, 0, volume);
 	if (error != 0)
-		printk(KERN_WARNING "error: setting tone volume returned: %s\n", 
+		printk(KERN_WARNING "error: setting tone volume returned: %s\n",
 				ppc_rtas_process_error(error));
 	return count;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/residual.c linux-2.4.22-pre10/arch/ppc/platforms/residual.c
--- linux-2.4.21/arch/ppc/platforms/residual.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/residual.c	2003-08-01 13:31:47.000000000 +0000
@@ -142,15 +142,15 @@
   "\001\002\006CHRP_Floppy",          /* CHRP Floppy in PR*P system         */
 
   "\001\003\000GeneralIPI",
-  
+
   "\002\000\000GeneralEther",
   "\002\001\000GeneralToken",
   "\002\002\000GeneralFDDI",
-  
+
   "\003\000\000GeneralVGA",
   "\003\001\000GeneralSVGA",
   "\003\002\000GeneralXGA",
-  
+
   "\004\000\000GeneralVideo",
   "\004\001\000GeneralAudio",
   "\004\001\001CS4232Audio",            /* CS 4232 Plug 'n Play Configured    */
@@ -160,7 +160,7 @@
   "\005\000\000PCIMemoryController",    /* PCI Config Method                  */
   "\005\000\001RS6KMemoryController",   /* RS6K Config Method                 */
   "\005\001\000GeneralFLASH",
-  
+
   "\006\000\000GeneralHostBridge",
   "\006\001\000GeneralISABridge",
   "\006\002\000GeneralEISABridge",
@@ -171,7 +171,7 @@
   "\006\004\002PCIBridgeRS6K",
   "\006\005\000GeneralPCMCIABridge",
   "\006\006\000GeneralVMEBridge",
-  
+
   "\007\000\000GeneralRS232",
   "\007\000\001COMx",
   "\007\000\002Compatible16450",
@@ -191,7 +191,7 @@
   "\007\001\003NS26EParPort",         /* Ports 26E and 26F                  */
   "\007\001\004NS15CParPort",         /* Ports 15C and 15D                  */
   "\007\001\005NS2EParPort",          /* Ports 2E and 2F                    */
-  
+
   "\010\000\000GeneralPIC",
   "\010\000\001ISA_PIC",
   "\010\000\002EISA_PIC",
@@ -207,7 +207,7 @@
   "\010\002\002EISA_Timer",
   "\010\003\000GeneralRTC",
   "\010\003\001ISA_RTC",
-  
+
   "\010\004\001StoreThruOnly",
   "\010\004\002StoreInEnabled",
   "\010\004\003RS6KL2Cache",
@@ -219,7 +219,7 @@
   "\010\006\000GeneralPowerManagement",
   "\010\006\001EPOWPowerManagement",
   "\010\006\002PowerControl",         // d1378
-  
+
   "\010\007\000GeneralCMOS",
 
   "\010\010\000GeneralOPPanel",
@@ -234,30 +234,30 @@
   "\010\011\000GeneralServiceProcessor",
   "\010\012\000GeneralServiceProcessor",
   "\010\013\000GeneralServiceProcessor",
-  
+
   "\010\014\001TransferData",
   "\010\014\002IGMC32",
   "\010\014\003IGMC64",
-  
+
   "\010\017\000GeneralSystemPlanar",   /* 10/5/95                            */
   NULL
   };
 
-static const unsigned char __init *PnP_SUB_TYPE_STR(unsigned char BaseType, 
+static const unsigned char __init *PnP_SUB_TYPE_STR(unsigned char BaseType,
 					     unsigned char SubType) {
 	unsigned char ** s=PnP_SUB_TYPES;
-	while (*s && !((*s)[0]==BaseType 
+	while (*s && !((*s)[0]==BaseType
 		       && (*s)[1]==SubType)) s++;
 	if (*s) return *s+2;
 	else return("Unknown !");
 };
 
-static const unsigned char __init *PnP_INTERFACE_STR(unsigned char BaseType, 
+static const unsigned char __init *PnP_INTERFACE_STR(unsigned char BaseType,
 					      unsigned char SubType,
 					      unsigned char Interface) {
 	unsigned char ** s=PnP_INTERFACES;
-	while (*s && !((*s)[0]==BaseType 
-		       && (*s)[1]==SubType 
+	while (*s && !((*s)[0]==BaseType
+		       && (*s)[1]==SubType
 		       && (*s)[2]==Interface)) s++;
 	if (*s) return *s+3;
 	else return NULL;
@@ -294,7 +294,7 @@
 
 	switch (tag_small_item_name(pkt->S1_Pack.Tag)) {
 	case PnPVersion:
-	  printk("    PnPversion 0x%x.%x\n", 
+	  printk("    PnPversion 0x%x.%x\n",
 		 pkt->S1_Pack.Version[0], /* How to interpret version ? */
 		 pkt->S1_Pack.Version[1]);
 	  break;
@@ -304,7 +304,7 @@
 	  break;
 	case IRQFormat:
 #define p pkt->S4_Pack
-	  printk("    IRQ Mask 0x%4.4x, %s %s sensitive\n", 
+	  printk("    IRQ Mask 0x%4.4x, %s %s sensitive\n",
 		 ld_le16((unsigned short *)p.IRQMask),
 		 intlevel[(size>3) ? !(p.IRQInfo&0x05) : 0],
 		 intsense[(size>3) ? !(p.IRQInfo&0x03) : 0]);
@@ -329,7 +329,7 @@
 		 p.IOInfo&ISAAddr16bit?16:10,
 		 ld_le16((unsigned short *)p.RangeMin),
  		 ld_le16((unsigned short *)p.RangeMax),
-		 p.IOAlign, p.IONum); 
+		 p.IOAlign, p.IONum);
 #undef p
 	  break;
 	case FixedIOPort:
@@ -337,20 +337,20 @@
 	  printk("    Fixed (10 decoded bits) I/O port from %3.3x to %3.3x\n",
 		 (p.Range[1]<<8)|p.Range[0],
 		 ((p.Range[1]<<8)|p.Range[0])+p.IONum-1);
-#undef p		 
+#undef p
 	  break;
 	case Res1:
 	case Res2:
 	case Res3:
-	  printk("    Undefined packet type %d!\n", 
+	  printk("    Undefined packet type %d!\n",
 		 tag_small_item_name(pkt->S1_Pack.Tag));
 	  break;
 	case SmallVendorItem:
 	  printsmallvendor(pkt,size);
 	  break;
 	default:
-	  printk("    Type 0x2.2x%d, size=%d\n", 
-		 pkt->S1_Pack.Tag, size);    
+	  printk("    Type 0x2.2x%d, size=%d\n",
+		 pkt->S1_Pack.Tag, size);
 	  break;
 	}
 }
@@ -432,7 +432,7 @@
 	  break;
 	case 7:
 	  printk("    SCSI buses: %d, id(s):", p.PPCData[0]);
-	  for(i=1; i<=p.PPCData[0]; i++) 
+	  for(i=1; i<=p.PPCData[0]; i++)
 	    printk(" %d%c", p.PPCData[i], i==p.PPCData[0] ? '\n' : ',');
 	  break;
 	case 9:
@@ -448,11 +448,11 @@
 		  p.PPCData[1]);
 
 	  printk("    ISA interrupts routed to %s\n"
-		 "      lines", 
+		 "      lines",
 		 tmpstr);
 	  for(i=0; i<16; i++) {
 	  	int line=ld_le16((unsigned short *)p.PPCData+i+1);
-		if (line!=0xffff) printk(" %d(IRQ%d)", line, i); 
+		if (line!=0xffff) printk(" %d(IRQ%d)", line, i);
 	  }
 	  printk("\n");
 	  break;
@@ -471,8 +471,8 @@
 	  printlargevendor(pkt, size);
 	  break;
 	default:
-	  printk("    Type 0x2.2x%d, size=%d\n", 
-		 pkt->S1_Pack.Tag, size);    
+	  printk("    Type 0x2.2x%d, size=%d\n",
+		 pkt->S1_Pack.Tag, size);
 	  break;
 	}
 }
@@ -486,7 +486,7 @@
 		int size;
 		if (tag_type(pkt->S1_Pack.Tag)) {
 		  	size= 3 +
-			  pkt->L1_Pack.Count0 + 
+			  pkt->L1_Pack.Count0 +
 			  pkt->L1_Pack.Count1*256;
 			printlargepacket(pkt, size);
 		} else {
@@ -502,11 +502,11 @@
 	int i;
 	PPC_DEVICE *dev;
 #define did dev->DeviceId
-	
+
 	/* make sure we have residual data first */
 	if ( res->ResidualLength == 0 )
 		return;
-	
+
 	printk("Residual: %ld devices\n", res->ActualNumDevices);
 	for ( i = 0;
 	      i < res->ActualNumDevices ;
@@ -515,23 +515,23 @@
 	  	char decomp[4], sn[20];
 		const char * s;
 		dev = &res->Devices[i];
-		s = PnP_INTERFACE_STR(did.BaseType, did.SubType, 
+		s = PnP_INTERFACE_STR(did.BaseType, did.SubType,
 				      did.Interface);
 		if(!s) {
 			sprintf(sn, "interface %d", did.Interface);
 			s=sn;
 		}
-		if ( did.BusId & PCIDEVICE ) 
+		if ( did.BusId & PCIDEVICE )
 		  printk("PCI Device, Bus %d, DevFunc 0x%x:",
 			 dev->BusAccess.PCIAccess.BusNumber,
 			 dev->BusAccess.PCIAccess.DevFuncNumber);
 	       	if ( did.BusId & PNPISADEVICE ) printk("PNPISA Device:");
-		if ( did.BusId & ISADEVICE ) 
+		if ( did.BusId & ISADEVICE )
 		  printk("ISA Device, Slot %d, LogicalDev %d:",
 			 dev->BusAccess.ISAAccess.SlotNumber,
 			 dev->BusAccess.ISAAccess.LogicalDevNumber);
 		if ( did.BusId & EISADEVICE ) printk("EISA Device:");
-		if ( did.BusId & PROCESSORDEVICE ) 
+		if ( did.BusId & PROCESSORDEVICE )
 		  printk("ProcBus Device, Bus %d, BUID %d: ",
 			 dev->BusAccess.ProcBusAccess.BusNumber,
 			 dev->BusAccess.ProcBusAccess.BUID);
@@ -544,7 +544,7 @@
 		decomp[1]='A'-1+((did.DevId>>21)&0x1F);
 		decomp[2]='A'-1+((did.DevId>>16)&0x1F);
 		decomp[3]=0;
-		printk(" %s%4.4lX, %s, %s, %s\n", 
+		printk(" %s%4.4lX, %s, %s, %s\n",
 		       decomp, did.DevId&0xffff,
 		       PnP_BASE_TYPES[did.BaseType],
 		       PnP_SUB_TYPE_STR(did.BaseType,did.SubType),
@@ -572,15 +572,15 @@
 	static const char* Usage[]={
 	  "FirmwareStack",  "FirmwareHeap",  "FirmwareCode", "BootImage",
 	  "Free", "Unpopulated", "ISAAddr", "PCIConfig",
-	  "IOMemory", "SystemIO", "SystemRegs", "PCIAddr", 
-	  "UnPopSystemRom", "SystemROM", "ResumeBlock", "Other" 
+	  "IOMemory", "SystemIO", "SystemRegs", "PCIAddr",
+	  "UnPopSystemRom", "SystemROM", "ResumeBlock", "Other"
 	};
 	static const unsigned char *FWMan[]={
 	  "IBM", "Motorola", "FirmWorks", "Bull"
 	};
 	static const unsigned char *FWFlags[]={
 	  "Conventional", "OpenFirmware", "Diagnostics", "LowDebug",
-	  "MultiBoot", "LowClient", "Hex41", "FAT", 
+	  "MultiBoot", "LowClient", "Hex41", "FAT",
 	  "ISO9660", "SCSI_ID_Override", "Tape_Boot", "FW_Boot_Path"
 	};
 	static const unsigned char *ESM[]={
@@ -596,15 +596,15 @@
 	printk("FirmwareFlags:");
 	for(j=0; j<12; j++) {
 	  	if (vpd.FirmwareSupports & (1<<j)) {
-			printk(" %s%c", FWFlags[j], 
+			printk(" %s%c", FWFlags[j],
 			       vpd.FirmwareSupports&(-2<<j) ? ',' : '\n');
 		}
 	}
 	printk("NVRamSize: %ld\n", vpd.NvramSize);
 	printk("SIMMslots: %ld\n", vpd.NumSIMMSlots);
-	printk("EndianSwitchMethod: %s\n", 
+	printk("EndianSwitchMethod: %s\n",
 	       ESM[vpd.EndianSwitchMethod>2 ? 2 : vpd.EndianSwitchMethod]);
-	printk("SpreadIOMethod: %s\n", 
+	printk("SpreadIOMethod: %s\n",
 	       SIOM[vpd.SpreadIOMethod>3 ? 3 : vpd.SpreadIOMethod]);
 	printk("Processor/Bus frequencies (Hz): %ld/%ld\n",
 	       vpd.ProcessorHz, vpd.ProcessorBusHz);
@@ -614,7 +614,7 @@
 	       vpd.CoherenceBlockSize, vpd.GranuleSize);
 	for (i=0; i<res->ActualNumMemSegs; i++) {
 		int mask=res->Segs[i].Usage, first, j;
-		printk("%8.8lx-%8.8lx ", 
+		printk("%8.8lx-%8.8lx ",
 		       res->Segs[i].BasePage*ps,
 		       (res->Segs[i].PageCount+res->Segs[i].BasePage)*ps-1);
 		for(j=15, first=1; j>=0; j--) {
@@ -637,7 +637,7 @@
 	union _PnP_TAG_PACKET *pkt;
 	PPC_DEVICE *dev;
 #define did dev->DeviceId
-	
+
 	/* make sure we have residual data first */
 	if ( res->ResidualLength == 0 )
 		return;
@@ -664,7 +664,7 @@
 				       pci_strdev(did.DevId>>16,
 						  did.DevId&0xffff)
 					);
-			
+
 			if ( did.BusId & PNPISADEVICE )
 			{
 				printk(" pnp:");
@@ -693,7 +693,7 @@
 			       did.BaseType, did.SubType);
 			printk("\n");
 			continue;
-		}		
+		}
 		/*
 		 * eisa devices
 		 */
@@ -703,7 +703,7 @@
 			       did.BaseType, did.SubType);
 			printk("\n");
 			continue;
-		}		
+		}
 		/*
 		 * proc bus devices
 		 */
@@ -723,26 +723,26 @@
 			       did.BaseType, did.SubType);
 			printk("\n");
 			continue;
-		}		
+		}
 		printk("Unknown bus access device: busid %lx\n",
 		       did.BusId);
 	}
 }
-#endif	
+#endif
 
-/* Returns the device index in the residual data, 
+/* Returns the device index in the residual data,
    any of the search items may be set as -1 for wildcard,
-   DevID number field (second halfword) is big endian ! 
+   DevID number field (second halfword) is big endian !
 
    Examples:
    - search for the Interrupt controller (8259 type), 2 methods:
-     1) i8259 = residual_find_device(~0, 
-                                     NULL, 
-				     SystemPeripheral, 
-				     ProgrammableInterruptController, 
-				     ISA_PIC, 
+     1) i8259 = residual_find_device(~0,
+                                     NULL,
+				     SystemPeripheral,
+				     ProgrammableInterruptController,
+				     ISA_PIC,
 				     0);
-     2) i8259 = residual_find_device(~0, "PNP0000", -1, -1, -1, 0) 
+     2) i8259 = residual_find_device(~0, "PNP0000", -1, -1, -1, 0)
 
    - search for the first two serial devices, whatever their type)
      iserial1 = residual_find_device(~0,NULL,
@@ -754,8 +754,8 @@
 				     RS232Device,
 				     -1, 1)
    - but search for typical COM1 and COM2 is not easy due to the
-     fact that the interface may be anything and the name "PNP0500" or 
-     "PNP0501". Quite bad. 
+     fact that the interface may be anything and the name "PNP0500" or
+     "PNP0501". Quite bad.
 
 */
 
@@ -768,7 +768,7 @@
 
 static int __init same_DevID(unsigned short vendor,
 	       unsigned short Number,
-	       char * str) 
+	       char * str)
 {
 	static unsigned const char hexdigit[]="0123456789ABCDEF";
 	if (strlen(str)!=7) return 0;
@@ -836,11 +836,11 @@
 	if (tag_type(packet_tag)) mask=0xff; else mask=0xF8;
 	masked_tag = packet_tag&mask;
 	for(; *p != END_TAG; p+=size) {
-		if ((*p & mask) == masked_tag && !(n--)) 
+		if ((*p & mask) == masked_tag && !(n--))
 			return (PnP_TAG_PACKET *) p;
 		if (tag_type(*p))
 			size=ld_le16((unsigned short *)(p+1))+3;
-		else 
+		else
 			size=tag_small_count(*p)+1;
 	}
 	return 0; /* not found */
@@ -853,7 +853,7 @@
 	int next=0;
 	while (p) {
 		p = (unsigned char *) PnP_find_packet(p, 0x70, next);
-		if (p && p[1]==packet_type && !(n--)) 
+		if (p && p[1]==packet_type && !(n--))
 			return (PnP_TAG_PACKET *) p;
 		next = 1;
 	};
@@ -867,7 +867,7 @@
 	int next=0;
 	while (p) {
 		p = (unsigned char *) PnP_find_packet(p, 0x84, next);
-		if (p && p[3]==packet_type && !(n--)) 
+		if (p && p[3]==packet_type && !(n--))
 			return (PnP_TAG_PACKET *) p;
 		next = 1;
 	};
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/spd8xx.h linux-2.4.22-pre10/arch/ppc/platforms/spd8xx.h
--- linux-2.4.21/arch/ppc/platforms/spd8xx.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/spd8xx.h	2003-08-01 13:31:05.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * Speech Design SPD8xxTS board specific definitions
- * 
+ *
  * Copyright (c) 2000,2001 Wolfgang Denk (wd@denx.de)
  */
 
@@ -9,7 +9,7 @@
 #define __ASM_SPD8XX_H__
 
 #include <linux/config.h>
- 
+
 #include <asm/ppcboot.h>
 
 #define SPD_IMMR_BASE	0xFFF00000	/* phys. addr of IMMR */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/spruce.h linux-2.4.22-pre10/arch/ppc/platforms/spruce.h
--- linux-2.4.21/arch/ppc/platforms/spruce.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/spruce.h	2003-08-01 13:33:38.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * include/asm-ppc/platforms/spruce.h
- * 
+ *
  * Definitions for IBM Spruce reference board support
  *
  * Authors: Matt Porter and Johnnie Peters
@@ -51,7 +51,7 @@
 
 /*
  * Serial port defines
- */ 
+ */
 #define SPRUCE_FPGA_REG_A	0xff820000
 #define SPRUCE_UARTCLK_33M	0x02
 #define SPRUCE_UARTCLK_IS_33M(reg)	(reg & SPRUCE_UARTCLK_33M)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/spruce_pci.c linux-2.4.22-pre10/arch/ppc/platforms/spruce_pci.c
--- linux-2.4.21/arch/ppc/platforms/spruce_pci.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/spruce_pci.c	2003-08-01 13:30:58.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * arch/ppc/platforms/spruce_pci.c
- * 
+ *
  * PCI support for IBM Spruce
  *
  * Author: Johnnie Peters
@@ -31,7 +31,7 @@
 {
 	static char pci_irq_table[][4] =
 		/*
-		 * 	PCI IDSEL/INTPIN->INTLINE 
+		 * 	PCI IDSEL/INTPIN->INTLINE
 		 * 	A	B	C	D
 		 */
 	{
@@ -52,7 +52,7 @@
 
 	/* Setup hose */
 	hose = pcibios_alloc_controller();
-	if (!hose) 
+	if (!hose)
 		return;
 
 	hose->first_busno = 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/tqm8xx.h linux-2.4.22-pre10/arch/ppc/platforms/tqm8xx.h
--- linux-2.4.21/arch/ppc/platforms/tqm8xx.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/tqm8xx.h	2003-08-01 13:32:32.000000000 +0000
@@ -1,6 +1,6 @@
 /*
  * TQM8xx(L) board specific definitions
- * 
+ *
  * Copyright (c) 1999,2000,2001 Wolfgang Denk (wd@denx.de)
  */
 
@@ -8,7 +8,7 @@
 #define __MACH_TQM8xx_H
 
 #include <linux/config.h>
- 
+
 #include <asm/ppcboot.h>
 
 #define	TQM_IMMR_BASE	0xFFF00000	/* phys. addr of IMMR */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/walnut.c linux-2.4.22-pre10/arch/ppc/platforms/walnut.c
--- linux-2.4.21/arch/ppc/platforms/walnut.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/walnut.c	2003-08-01 13:33:02.000000000 +0000
@@ -1,288 +1,250 @@
 /*
  *
- *    Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
+ *    Copyrigh t(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
  *
- *    Module name: walnut_setup.c
+ *    Copyright 2000-2002 MontaVista Software Inc.
+ *      Completed implementation.
+ *      Author: MontaVista Software, Inc.  <source@mvista.com>
+ *
+ *    Module name: walnut.c
  *
  *    Description:
  *      Architecture- / platform-specific boot-time initialization code for
- *      the IBM PowerPC 403GP "Walnut" evaluation board. Adapted from original
+ *      IBM PowerPC 4xx based boards. Adapted from original
  *      code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
  *      <dan@net4x.com>.
  *
+ * Please read the COPYING file for all license details.
  */
-
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/threads.h>
-#include <linux/interrupt.h>
 #include <linux/param.h>
 #include <linux/string.h>
 #include <linux/blk.h>
-#include <linux/seq_file.h>
+#include <linux/pci.h>
+#include <linux/rtc.h>
 
+#include <asm/system.h>
+#include <asm/pci-bridge.h>
 #include <asm/processor.h>
-#include <asm/board.h>
 #include <asm/machdep.h>
 #include <asm/page.h>
-
-#include "ppc4xx_pic.h"
 #include <asm/time.h>
-#include "walnut_setup.h"
-
-
-/* Function Prototypes */
-
-extern void abort(void);
-
-/* Global Variables */
-
-unsigned char __res[sizeof(bd_t)];
-
-
-/*
- * void __init walnut_init()
- *
- * Description:
- *   This routine...
- *
- * Input(s):
- *   r3 - Optional pointer to a board information structure.
- *   r4 - Optional pointer to the physical starting address of the init RAM
- *        disk.
- *   r5 - Optional pointer to the physical ending address of the init RAM
- *        disk.
- *   r6 - Optional pointer to the physical starting address of any kernel
- *        command-line parameters.
- *   r7 - Optional pointer to the physical ending address of any kernel
- *        command-line parameters.
- *
- * Output(s):
- *   N/A
- *
- * Returns:
- *   N/A
- *
+#include <asm/io.h>
+#include <asm/todc.h>
+#include <platforms/ibm_ocp.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+void *kb_cs;
+void *kb_data;
+void *walnut_rtc_base;
+
+#ifdef CONFIG_PCI
+/* Some IRQs unique to Walnut.
+ * Used by the generic 405 PCI setup functions in ppc4xx_pci.c
  */
+int __init
+ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	    /*
+	     *      PCI IDSEL/INTPIN->INTLINE
+	     *      A       B       C       D
+	     */
+	{
+		{28, 28, 28, 28},	/* IDSEL 1 - PCI slot 1 */
+		{29, 29, 29, 29},	/* IDSEL 2 - PCI slot 2 */
+		{30, 30, 30, 30},	/* IDSEL 3 - PCI slot 3 */
+		{31, 31, 31, 31},	/* IDSEL 4 - PCI slot 4 */
+	};
+
+	const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+};
+#endif
+
 void __init
-walnut_init(unsigned long r3, unsigned long r4, unsigned long r5, 
-	    unsigned long r6, unsigned long r7)
+board_setup_arch(void)
 {
-	/*
-	 * If we were passed in a board information, copy it into the
-	 * residual data area.
-	 */
-	if (r3) {
-		memcpy((void *)__res, (void *)(r3 + KERNELBASE), sizeof(bd_t));
-	}
+#define WALNUT_PS2_BASE		0xF0100000
+#define WALNUT_FPGA_BASE	0xF0300000
 
-#if defined(CONFIG_BLK_DEV_INITRD)
-	/*
-	 * If the init RAM disk has been configured in, and there's a valid
-	 * starting address for it, set it up.
-	 */
-	if (r4) {
-		initrd_start = r4 + KERNELBASE;
-		initrd_end = r5 + KERNELBASE;
+	void *fpga_brdc;
+	unsigned char fpga_brdc_data;
+	void *fpga_enable;
+	void *fpga_polarity;
+	void *fpga_status;
+	void *fpga_trigger;
+
+	kb_data = ioremap(WALNUT_PS2_BASE, 8);
+	if (!kb_data) {
+		printk(KERN_CRIT
+		       "walnut_setup_arch() kb_data ioremap failed\n");
+		return;
 	}
-#endif /* CONFIG_BLK_DEV_INITRD */
 
-	/* Copy the kernel command line arguments to a safe place. */
+	kb_cs = kb_data + 1;
 
-	if (r6) {
- 		*(char *)(r7 + KERNELBASE) = 0;
-		strcpy(cmd_line, (char *)(r6 + KERNELBASE));
+	fpga_status = ioremap(WALNUT_FPGA_BASE, 8);
+	if (!fpga_status) {
+		printk(KERN_CRIT
+		       "walnut_setup_arch() fpga_status ioremap failed\n");
+		return;
 	}
 
-	/* Initialize machine-dependency vectors */
+	fpga_enable = fpga_status + 1;
+	fpga_polarity = fpga_status + 2;
+	fpga_trigger = fpga_status + 3;
+	fpga_brdc = fpga_status + 4;
 
-	ppc_md.setup_arch	 	= walnut_setup_arch;
-	ppc_md.show_percpuinfo	 	= walnut_show_percpuinfo;
-	ppc_md.irq_cannonicalize 	= NULL;
-	ppc_md.init_IRQ		 	= walnut_init_IRQ;
-	ppc_md.get_irq		 	= walnut_get_irq;
-	ppc_md.init		 	= NULL;
-
-	ppc_md.restart		 	= walnut_restart;
-	ppc_md.power_off	 	= walnut_power_off;
-	ppc_md.halt		 	= walnut_halt;
-
-	ppc_md.time_init	 	= walnut_time_init;
-	ppc_md.set_rtc_time	 	= walnut_set_rtc_time;
-	ppc_md.get_rtc_time	 	= walnut_get_rtc_time;
-	ppc_md.calibrate_decr	 	= walnut_calibrate_decr;
-
-	ppc_md.kbd_setkeycode    	= NULL;
-	ppc_md.kbd_getkeycode    	= NULL;
-	ppc_md.kbd_translate     	= NULL;
-	ppc_md.kbd_unexpected_up 	= NULL;
-	ppc_md.kbd_leds          	= NULL;
-	ppc_md.kbd_init_hw       	= NULL;
-	ppc_md.ppc_kbd_sysrq_xlate	= NULL;
-}
+	/* split the keyboard and mouse interrupts */
+	fpga_brdc_data = readb(fpga_brdc);
+	fpga_brdc_data |= 0x80;
+	writeb(fpga_brdc_data, fpga_brdc);
 
-/*
- * Document me.
- */
-void __init
-walnut_setup_arch(void)
-{
-	/* XXX - Implement me */
-}
+	writeb(0x3, fpga_enable);
 
-/*
- * int walnut_show_percpuinfo()
- *
- * Description:
- *   This routine pretty-prints the platform's internal CPU and bus clock
- *   frequencies into the buffer for usage in /proc/cpuinfo.
- *
- * Input(s):
- *  *buffer - Buffer into which CPU and bus clock frequencies are to be
- *            printed.
- *
- * Output(s):
- *  *buffer - Buffer with the CPU and bus clock frequencies.
- *
- * Returns:
- *   The number of bytes copied into 'buffer' if OK, otherwise zero or less
- *   on error.
- */
-int
-walnut_show_percpuinfo(struct seq_file *m)
-{
-	bd_t *bp = (bd_t *)__res;
+	writeb(0x3, fpga_polarity);
 
-	seq_printf(m, "clock\t\t: %dMHz\n"
-		   "bus clock\t\t: %dMHz\n",
-		   bp->bi_intfreq / 1000000,
-		   bp->bi_busfreq / 1000000);
+	writeb(0x3, fpga_trigger);
 
-	return 0;
+	/* RTC step for the walnut */
+	walnut_rtc_base = (void *) WALNUT_RTC_VADDR;
+	TODC_INIT(TODC_TYPE_DS1743, walnut_rtc_base, walnut_rtc_base,
+		  walnut_rtc_base, 8);
+	/* Identify the system */
+	printk("IBM Walnut port (C) 2000-2002 MontaVista Software, Inc. (source@mvista.com)\n");
 }
 
-/*
- * Document me.
- */
+#ifdef CONFIG_PCI
 void __init
-walnut_init_IRQ(void)
+bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
 {
-	int i;
-
-	ppc4xx_pic_init();
 
-	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc[i].handler = ppc4xx_pic;
-	}
-
-	return;
-}
-
-/*
- * Document me.
- */
-int
-walnut_get_irq(struct pt_regs *regs)
-{
-	return (ppc4xx_pic_get_irq(regs));
-}
+	unsigned int bar_response, bar;
+	/*
+	 * Expected PCI mapping:
+	 *
+	 *  PLB addr             PCI memory addr
+	 *  ---------------------       ---------------------
+	 *  0000'0000 - 7fff'ffff <---  0000'0000 - 7fff'ffff
+	 *  8000'0000 - Bfff'ffff --->  8000'0000 - Bfff'ffff
+	 *
+	 *  PLB addr             PCI io addr
+	 *  ---------------------       ---------------------
+	 *  e800'0000 - e800'ffff --->  0000'0000 - 0001'0000
+	 *
+	 * The following code is simplified by assuming that the bootrom
+	 * has been well behaved in following this mapping.
+	 */
 
-/*
- * Document me.
- */
-void
-walnut_restart(char *cmd)
-{
-	abort();
-}
+#ifdef DEBUG
+	int i;
 
-/*
- * Document me.
- */
-void
-walnut_power_off(void)
-{
-	walnut_restart(NULL);
-}
+	printk("ioremap PCLIO_BASE = 0x%x\n", pcip);
+	printk("PCI bridge regs before fixup \n");
+	for (i = 0; i <= 3; i++) {
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila)));
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha)));
+	}
+	printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
+	printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
+	printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
+	printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
+
+#endif
+
+	/* added for IBM boot rom version 1.15 bios bar changes  -AK */
+
+	/* Disable region first */
+	out_le32((void *) &(pcip->pmm[0].ma), 0x00000000);
+	/* PLB starting addr, PCI: 0x80000000 */
+	out_le32((void *) &(pcip->pmm[0].la), 0x80000000);
+	/* PCI start addr, 0x80000000 */
+	out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE);
+	/* 512MB range of PLB to PCI */
+	out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000);
+	/* Enable no pre-fetch, enable region */
+	out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff -
+						(PPC405_PCI_UPPER_MEM -
+						 PPC405_PCI_MEM_BASE)) | 0x01));
+
+	/* Disable region one */
+	out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
+	out_le32((void *) &(pcip->pmm[1].la), 0x00000000);
+	out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000);
+	out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000);
+	out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
+	out_le32((void *) &(pcip->ptm1ms), 0x00000000);
+
+	/* Disable region two */
+	out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
+	out_le32((void *) &(pcip->pmm[2].la), 0x00000000);
+	out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000);
+	out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000);
+	out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
+	out_le32((void *) &(pcip->ptm2ms), 0x00000000);
+
+	/* Zero config bars */
+	for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
+		early_write_config_dword(hose, hose->first_busno,
+					 PCI_FUNC(hose->first_busno), bar,
+					 0x00000000);
+		early_read_config_dword(hose, hose->first_busno,
+					PCI_FUNC(hose->first_busno), bar,
+					&bar_response);
+		DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n",
+		    hose->first_busno, PCI_SLOT(hose->first_busno),
+		    PCI_FUNC(hose->first_busno), bar, bar_response);
+	}
+	/* end work arround */
 
-/*
- * Document me.
- */
-void
-walnut_halt(void)
-{
-	walnut_restart(NULL);
-}
+#ifdef DEBUG
+	printk("PCI bridge regs after fixup \n");
+	for (i = 0; i <= 3; i++) {
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila)));
+		printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha)));
+	}
+	printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
+	printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
+	printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
+	printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
 
-/*
- * Document me.
- */
-long __init
-walnut_time_init(void)
-{
-	/* XXX - Implement me */
-	return 0;
+#endif
 }
+#endif
 
-/*
- * Document me.
- */
-int __init
-walnut_set_rtc_time(unsigned long time)
+void __init
+board_io_mapping(void)
 {
-	/* XXX - Implement me */
-
-	return (0);
+	io_block_mapping(WALNUT_RTC_VADDR,
+			 WALNUT_RTC_PADDR, WALNUT_RTC_SIZE, _PAGE_IO);
 }
 
-/*
- * Document me.
- */
-unsigned long __init
-walnut_get_rtc_time(void)
+void __init
+board_setup_irq(void)
 {
-	/* XXX - Implement me */
-
-	return (0);
 }
 
-/*
- * void __init walnut_calibrate_decr()
- *
- * Description:
- *   This routine retrieves the internal processor frequency from the board
- *   information structure, sets up the kernel timer decrementer based on
- *   that value, enables the 403 programmable interval timer (PIT) and sets
- *   it up for auto-reload.
- *
- * Input(s):
- *   N/A
- *
- * Output(s):
- *   N/A
- *
- * Returns:
- *   N/A
- *
- */
 void __init
-walnut_calibrate_decr(void)
+board_init(void)
 {
-	unsigned int freq;
-	bd_t *bip = (bd_t *)__res;
-
-	freq = bip->bi_intfreq;
-
-	decrementer_count = freq / HZ;
-	count_period_num = 1;
-	count_period_den = freq;
-
-	/* Enable the PIT and set auto-reload of its value */
-
-	mtspr(SPRN_TCR, TCR_PIE | TCR_ARE);
-
-	/* Clear any pending timer interrupts */
-
-	mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_PIS | TSR_FIS);
+	ppc_md.time_init = todc_time_init;
+	ppc_md.set_rtc_time = todc_set_rtc_time;
+	ppc_md.get_rtc_time = todc_get_rtc_time;
+	ppc_md.nvram_read_val = todc_direct_read_val;
+	ppc_md.nvram_write_val = todc_direct_write_val;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/platforms/walnut.h linux-2.4.22-pre10/arch/ppc/platforms/walnut.h
--- linux-2.4.21/arch/ppc/platforms/walnut.h	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/platforms/walnut.h	2003-08-01 13:30:54.000000000 +0000
@@ -1,50 +1,91 @@
 /*
  *
- *    Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
  *
- *    Module name: walnut_setup.c
+ *    Copyright 2000 MontaVista Software Inc.
+ *	PPC405 modifications
+ * 	Author: MontaVista Software, Inc.
+ *         	frank_rowand@mvista.com or source@mvista.com
+ * 	   	debbie_chu@mvista.com
+ *
+ *    Module name: ppc405.h
  *
  *    Description:
- *      Architecture- / platform-specific boot-time initialization code for
- *      the IBM PowerPC 405GP "Walnut" evaluation board. Adapted from original
- *      code by Gary Thomas, Cort Dougan <cort@cs.nmt.edu>, and Dan Malek
- *      <dan@netx4.com>.
+ *      Macros, definitions, and data structures specific to the IBM PowerPC
+ *      based boards.
+ *
+ *      This includes:
+ *
+ *         405GP "Walnut" evaluation board
  *
+ * Please read the COPYING file for all license details.
  */
 
-#ifndef	__WALNUT_SETUP_H__
-#define	__WALNUT_SETUP_H__
+#ifdef __KERNEL__
+#ifndef __ASM_WALNUT_H__
+#define __ASM_WALNUT_H__
 
-#include <asm/ptrace.h>
-#include <asm/board.h>
+/* We have a 405GP core */
+#include <platforms/ibm405gp.h>
 
+#ifndef __ASSEMBLY__
+/*
+ * Data structure defining board information maintained by the boot
+ * ROM on IBM's "Walnut" evaluation board. An effort has been made to
+ * keep the field names consistent with the 8xx 'bd_t' board info
+ * structures.
+ */
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern unsigned char	 __res[sizeof(bd_t)];
+typedef struct board_info {
+	unsigned char	 bi_s_version[4];	/* Version of this structure */
+	unsigned char	 bi_r_version[30];	/* Version of the IBM ROM */
+	unsigned int	 bi_memsize;		/* DRAM installed, in bytes */
+	unsigned char	 bi_enetaddr[6];	/* Local Ethernet MAC address */
+	unsigned char	 bi_pci_enetaddr[6];	/* PCI Ethernet MAC address */
+	unsigned int	 bi_intfreq;		/* Processor speed, in Hz */
+	unsigned int	 bi_busfreq;		/* PLB Bus speed, in Hz */
+	unsigned int	 bi_pci_busfreq;	/* PCI Bus speed, in Hz */
+	unsigned int	 bi_opbfreq;		/* OPB Bus speed, in Hz */
+	int		 bi_iic_fast[1];	/* Use fast i2c mode */
+} bd_t;
+
+/* Some 4xx parts use a different timebase frequency from the internal clock.
+*/
+#define bi_tbfreq bi_intfreq
 
-extern void		 walnut_init(unsigned long r3,
-				  unsigned long ird_start,
-				  unsigned long ird_end,
-				  unsigned long cline_start,
-				  unsigned long cline_end);
-extern void		 walnut_setup_arch(void);
-extern int		 walnut_setup_residual(char *buffer);
-extern void		 walnut_init_IRQ(void);
-extern int		 walnut_get_irq(struct pt_regs *regs);
-extern void		 walnut_restart(char *cmd);
-extern void		 walnut_power_off(void);
-extern void		 walnut_halt(void);
-extern void		 walnut_time_init(void);
-extern int		 walnut_set_rtc_time(unsigned long now);
-extern unsigned long	 walnut_get_rtc_time(void);
-extern void		 walnut_calibrate_decr(void);
 
+/* Memory map for the IBM "Walnut" 405GP evaluation board.
+ * Generic 4xx plus RTC.
+ */
 
-#ifdef __cplusplus
-}
+extern void *walnut_rtc_base;
+#define WALNUT_RTC_PADDR	((uint)0xf0000000)
+#define WALNUT_RTC_VADDR	WALNUT_RTC_PADDR
+#define WALNUT_RTC_SIZE		((uint)8*1024)
+
+/* ps2 keyboard and mouse */
+#define KEYBOARD_IRQ		25
+#define AUX_IRQ			26
+
+#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
+#define BASE_BAUD		201600
+#else
+#define BASE_BAUD		691200
 #endif
 
-#endif /* __WALNUT_SETUP_H__ */
+#define WALNUT_PS2_BASE		0xF0100000
+#define WALNUT_FPGA_BASE	0xF0300000
+
+
+extern void *kb_cs;
+extern void *kb_data;
+#define kbd_read_input()	readb(kb_data)
+#define kbd_read_status()	readb(kb_cs)
+#define kbd_write_output(val)	writeb(val, kb_data)
+#define kbd_write_command(val)	writeb(val, kb_cs)
+
+#define PPC4xx_MACHINE_NAME	"IBM Walnut"
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __ASM_WALNUT_H__ */
+#endif /* __KERNEL__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/vmlinux.lds linux-2.4.22-pre10/arch/ppc/vmlinux.lds
--- linux-2.4.21/arch/ppc/vmlinux.lds	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/vmlinux.lds	2003-08-01 13:35:10.000000000 +0000
@@ -83,7 +83,7 @@
   . = ALIGN(4096);
   __init_begin = .;
   .text.init : { *(.text.init) }
-  .data.init : { 
+  .data.init : {
     *(.data.init);
     __vtop_table_begin = .;
     *(.vtop_fixup);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/xmon/ppc-opc.c linux-2.4.22-pre10/arch/ppc/xmon/ppc-opc.c
--- linux-2.4.21/arch/ppc/xmon/ppc-opc.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/xmon/ppc-opc.c	2003-08-01 13:30:41.000000000 +0000
@@ -393,7 +393,7 @@
    same.  */
 
 /*ARGSUSED*/
-static unsigned long 
+static unsigned long
 insert_bat (insn, value, errmsg)
      unsigned long insn;
      long value;
@@ -869,7 +869,7 @@
    extraction function just checks that the fields are the same.  */
 
 /*ARGSUSED*/
-static unsigned long 
+static unsigned long
 insert_rbs (insn, value, errmsg)
      unsigned long insn;
      long value;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/xmon/start.c linux-2.4.22-pre10/arch/ppc/xmon/start.c
--- linux-2.4.21/arch/ppc/xmon/start.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/xmon/start.c	2003-08-01 13:30:40.000000000 +0000
@@ -98,7 +98,7 @@
 	xmon(regs);
 }
 
-static struct sysrq_key_op sysrq_xmon_op = 
+static struct sysrq_key_op sysrq_xmon_op =
 {
 	handler:	sysrq_handle_xmon,
 	help_msg:	"Xmon",
@@ -112,7 +112,7 @@
 	volatile unsigned char *base;
 
 	use_screen = 0;
-	
+
 	if (_machine == _MACH_Pmac) {
 		struct device_node *np;
 		unsigned long addr;
@@ -176,7 +176,7 @@
 #endif
 		TXRDY = 4;
 		RXRDY = 1;
-		
+
 		np = find_devices("mac-io");
 		if (np && np->n_addrs)
 			addr = np->addrs[0].address + 0x13020;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/xmon/start_8xx.c linux-2.4.22-pre10/arch/ppc/xmon/start_8xx.c
--- linux-2.4.21/arch/ppc/xmon/start_8xx.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/xmon/start_8xx.c	2003-08-01 13:32:06.000000000 +0000
@@ -46,7 +46,7 @@
 
 	cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
 	use_screen = 0;
-	
+
 	prom_drawstring("xmon uses serial port\n");
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc/xmon/xmon.c linux-2.4.22-pre10/arch/ppc/xmon/xmon.c
--- linux-2.4.21/arch/ppc/xmon/xmon.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc/xmon/xmon.c	2003-08-01 13:30:33.000000000 +0000
@@ -716,7 +716,7 @@
 	extern char do_signal_ret, ret_from_except;
 
 	printf("backtrace:\n");
-	
+
 	if (excp != NULL)
 		sp = excp->gpr[1];
 	else
@@ -1176,7 +1176,7 @@
 byterev(unsigned char *val, int size)
 {
 	int t;
-	
+
 	switch (size) {
 	case 2:
 		SWAP(val[0], val[1], t);
@@ -1787,7 +1787,7 @@
 {
 	char *sym;
 	unsigned long saddr;
-	
+
 	printf("%08x", addr);
 	sym = xmon_find_symbol(addr, &saddr);
 	if (sym)
@@ -1807,7 +1807,7 @@
 	extern unsigned long sysmap_size;
 	if ( !sysmap || !sysmap_size )
 		return NULL;
-	
+
 	prev = 0;
 	psym = NULL;
 	p = sysmap;
@@ -1852,7 +1852,7 @@
 	char *match;
 	int goodness = 0;
 	int result = 0;
-	
+
 	extern char *sysmap;
 	extern unsigned long sysmap_size;
 	if ( !sysmap || !sysmap_size )
@@ -1883,7 +1883,7 @@
 				}
 				cur++;
 			}
-		}	
+		}
 		if (goodness) {
 			p = match;
 			while(p > sysmap && *p != 10)
@@ -1895,4 +1895,4 @@
 	}
 	debugger_fault_handler = 0;
 	return result;
-}		
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/Makefile linux-2.4.22-pre10/arch/ppc64/Makefile
--- linux-2.4.21/arch/ppc64/Makefile	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/Makefile	2003-08-01 13:34:41.000000000 +0000
@@ -19,6 +19,13 @@
 CHECKS		= checks
 endif
 
+HAS_BIARCH      := $(shell if gcc -m64 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi;)
+ifeq ($(HAS_BIARCH),y)
+AS              := $(AS) -64
+LD              := $(LD) -m elf64ppc
+CC		:= gcc -m64
+endif
+
 LINKFLAGS	= -T arch/ppc64/vmlinux.lds -Bstatic \
 		-e $(KERNELLOAD) -Ttext $(KERNELLOAD)
 CFLAGS		:= $(CFLAGS) -fsigned-char -msoft-float -pipe \
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/boot/Makefile linux-2.4.22-pre10/arch/ppc64/boot/Makefile
--- linux-2.4.21/arch/ppc64/boot/Makefile	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/boot/Makefile	2003-08-01 13:33:30.000000000 +0000
@@ -52,7 +52,7 @@
 ifeq ($(CONFIG_PPC_ISERIES),y)
 all:	vmlinux.sm
 else
-all:	$(TOPDIR)/zImage
+all:	zImage
 endif
 
 
@@ -94,7 +94,7 @@
 
 zImage.o: $(TOPDIR)/vmlinux
 
-vmlinux .config System.map: % : $(TOPDIR)/%
+vmlinux .config System.map: % : $(TOPDIR)/% zImage.o
 	gzip -cvf9 $(TOPDIR)/$@ > kernel-$@.gz
 	$(OBJCOPY) zImage.o \
 		--add-section=.kernel:$@=kernel-$@.gz \
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/boot/addnote.c linux-2.4.22-pre10/arch/ppc64/boot/addnote.c
--- linux-2.4.21/arch/ppc64/boot/addnote.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/boot/addnote.c	2003-08-01 13:33:30.000000000 +0000
@@ -14,6 +14,7 @@
  * Usage: addnote zImage
  */
 #include <stdio.h>
+#include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <string.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/boot/zlib.c linux-2.4.22-pre10/arch/ppc64/boot/zlib.c
--- linux-2.4.21/arch/ppc64/boot/zlib.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/boot/zlib.c	2003-08-01 13:33:58.000000000 +0000
@@ -735,7 +735,7 @@
       end-of-block.  Note however that the static length tree defines
       288 codes just to fill out the Huffman codes.  Codes 286 and 287
       cannot be used though, since there is no length base or extra bits
-      defined for them.  Similarily, there are up to 30 distance codes.
+      defined for them.  Similarly, there are up to 30 distance codes.
       However, static trees define 32 codes (all 5 bits) to fill out the
       Huffman codes, but the last two had better not show up in the data.
    7. Unzip can check dynamic Huffman blocks for complete code sets.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/config.in linux-2.4.22-pre10/arch/ppc64/config.in
--- linux-2.4.21/arch/ppc64/config.in	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/config.in	2003-08-01 13:31:56.000000000 +0000
@@ -39,8 +39,13 @@
 bool 'MsChunks Physical to Absolute address translation support' CONFIG_MSCHUNKS
 tristate 'Firmware flash interface' CONFIG_RTAS_FLASH
 tristate 'Scanlog Dump interface' CONFIG_SCANLOG
+bool 'Support for RTAS (RunTime Abstraction Services) in /proc' CONFIG_PPC_RTAS
+     if [ "$CONFIG_PPC_RTAS" = "y" ]; then
+	bool 'RTAS Error Inject' CONFIG_RTAS_ERRINJCT
+     fi
 fi
 
+bool 'Shared kernel/user space addressing' CONFIG_SHARED_MEMORY_ADDRESSING
 
 endmenu
 
@@ -136,7 +141,7 @@
    bool 'Network device support' CONFIG_NETDEVICES
    if [ "$CONFIG_NETDEVICES" = "y" ]; then
       source drivers/net/Config.in
-      if [ "$CONFIG_ATM" = "y" ]; then
+      if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
          source drivers/atm/Config.in
       fi
    fi
@@ -231,6 +236,8 @@
 
 source lib/Config.in
 
+source crypto/Config.in
+
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
@@ -238,6 +245,7 @@
 bool 'Include kgdb kernel debugger' CONFIG_KGDB
 bool 'Include xmon kernel debugger' CONFIG_XMON
 bool 'Include kdb kernel debugger' CONFIG_KDB
+bool 'Debug memory allocations' CONFIG_DEBUG_SLAB
 if [ "$CONFIG_KDB" = "y" ]; then
   bool '  KDB off by default' CONFIG_KDB_OFF
   define_bool CONFIG_KALLSYMS y
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/configs/iSeries_devfs_defconfig linux-2.4.22-pre10/arch/ppc64/configs/iSeries_devfs_defconfig
--- linux-2.4.21/arch/ppc64/configs/iSeries_devfs_defconfig	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/configs/iSeries_devfs_defconfig	2003-08-01 13:33:45.000000000 +0000
@@ -700,6 +700,6 @@
 # CONFIG_KDB_OFF is not set
 # CONFIG_KALLSYMS is not set
 # CONFIG_PPCDBG is not set
-CONFIG_DUMP=y
-CONFIG_DUMP_COMPRESS_RLE=y
-CONFIG_DUMP_COMPRESS_GZIP=y
+# CONFIG_DUMP is not set
+# CONFIG_DUMP_COMPRESS_RLE is not set
+# CONFIG_DUMP_COMPRESS_GZIP is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig linux-2.4.22-pre10/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig
--- linux-2.4.21/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig	2003-08-01 13:31:14.000000000 +0000
@@ -635,6 +635,6 @@
 # CONFIG_KDB_OFF is not set
 # CONFIG_KALLSYMS is not set
 # CONFIG_PPCDBG is not set
-CONFIG_DUMP=y
-CONFIG_DUMP_COMPRESS_RLE=y
-CONFIG_DUMP_COMPRESS_GZIP=y
+# CONFIG_DUMP is not set
+# CONFIG_DUMP_COMPRESS_RLE is not set
+# CONFIG_DUMP_COMPRESS_GZIP is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/configs/pSeries_defconfig linux-2.4.22-pre10/arch/ppc64/configs/pSeries_defconfig
--- linux-2.4.21/arch/ppc64/configs/pSeries_defconfig	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/configs/pSeries_defconfig	2003-08-01 13:32:31.000000000 +0000
@@ -27,6 +27,9 @@
 # CONFIG_MSCHUNKS is not set
 CONFIG_RTAS_FLASH=m
 CONFIG_SCANLOG=m
+CONFIG_PPC_RTAS=y
+# CONFIG_RTAS_ERRINJCT is not set
+# CONFIG_SHARED_MEMORY_ADDRESSING is not set
 
 #
 # Loadable module support
@@ -173,6 +176,7 @@
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
+# CONFIG_IDE_TASKFILE_IO is not set
 
 #
 # IDE chipset support/bugfixes
@@ -726,9 +730,12 @@
 #
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_KGDB is not set
-CONFIG_XMON=y
-# CONFIG_KDB is not set
-# CONFIG_KDB is not set
-# CONFIG_KALLSYMS is not set
+# CONFIG_XMON is not set
+# CONFIG_KDB  is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_KDB_OFF is not set
+CONFIG_KALLSYMS=y
 CONFIG_PPCDBG=y
 # CONFIG_DUMP is not set
+# CONFIG_DUMP_COMPRESS_RLE is not set
+# CONFIG_DUMP_COMPRESS_GZIP is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/defconfig linux-2.4.22-pre10/arch/ppc64/defconfig
--- linux-2.4.21/arch/ppc64/defconfig	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/defconfig	2003-08-01 13:33:10.000000000 +0000
@@ -27,6 +27,9 @@
 # CONFIG_MSCHUNKS is not set
 CONFIG_RTAS_FLASH=m
 CONFIG_SCANLOG=m
+CONFIG_PPC_RTAS=y
+# CONFIG_RTAS_ERRINJCT is not set
+# CONFIG_SHARED_MEMORY_ADDRESSING is not set
 
 #
 # Loadable module support
@@ -190,7 +193,7 @@
 # CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
+# CONFIG_BLK_DEV_ADMA100 is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
@@ -204,13 +207,11 @@
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_PDC202XX_BURST is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_PDC202XX_FORCE is not set
 # CONFIG_BLK_DEV_RZ1000 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_SVWKS is not set
@@ -266,6 +267,7 @@
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AACRAID 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
@@ -361,6 +363,7 @@
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
+# CONFIG_EEPRO100_PIO is not set
 CONFIG_E100=y
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
@@ -467,12 +470,14 @@
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
-CONFIG_FB_MATROX_G100=y
 # CONFIG_FB_MATROX_G450 is not set
+# CONFIG_FB_MATROX_G100A is not set
+# CONFIG_FB_MATROX_PROC is not set
 # CONFIG_FB_MATROX_MULTIHEAD is not set
 # CONFIG_FB_ATY is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
+# CONFIG_FB_INTEL is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_3DFX is not set
@@ -726,9 +731,8 @@
 #
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_KGDB is not set
-CONFIG_XMON=y
+# CONFIG_XMON is not set
 # CONFIG_KDB is not set
-# CONFIG_KDB is not set
-# CONFIG_KALLSYMS is not set
+# CONFIG_DEBUG_SLAB is not set
 CONFIG_PPCDBG=y
 # CONFIG_DUMP is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/LparData.c linux-2.4.22-pre10/arch/ppc64/kernel/LparData.c
--- linux-2.4.21/arch/ppc64/kernel/LparData.c	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/LparData.c	2003-08-01 13:30:57.000000000 +0000
@@ -71,7 +71,7 @@
 	6,		/* TEMP: This allows non-GA driver */
 	4,		/* We are v5r2m0               */
 	3,		/* Min supported PLIC = v5r1m0 */
-	3,		/* Min usuable PLIC   = v5r1m0 */
+	3,		/* Min usable PLIC   = v5r1m0 */
 	{ 0xd3, 0x89, 0x95, 0xa4, /* "Linux 2.4   "*/
 	  0xa7, 0x40, 0xf2, 0x4b,
 	  0xf4, 0x4b, 0xf6, 0xf4 },
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/Makefile linux-2.4.22-pre10/arch/ppc64/kernel/Makefile
--- linux-2.4.21/arch/ppc64/kernel/Makefile	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/Makefile	2003-08-01 13:32:58.000000000 +0000
@@ -27,7 +27,7 @@
 			pmc.o mf_proc.o proc_pmc.o proc_pcifr.o iSeries_setup.o \
 			ItLpQueue.o hvCall.o mf.o HvLpEvent.o ras.o \
 			iSeries_proc.o HvCall.o flight_recorder.o HvLpConfig.o \
-			rtc.o perfmon.o
+			rtc.o perfmon.o cputable.o
 
 obj-$(CONFIG_PCI) +=  pci.o pci_dn.o pci_dma.o pSeries_lpar.o pSeries_hvCall.o
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/XmPciLpEvent.c linux-2.4.22-pre10/arch/ppc64/kernel/XmPciLpEvent.c
--- linux-2.4.21/arch/ppc64/kernel/XmPciLpEvent.c	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/XmPciLpEvent.c	2003-08-01 13:30:37.000000000 +0000
@@ -34,7 +34,7 @@
 enum XmPciLpEvent_Subtype {
 	XmPciLpEvent_BusCreated	   = 0,		// PHB has been created
 	XmPciLpEvent_BusError	   = 1,		// PHB has failed
-	XmPciLpEvent_BusFailed	   = 2,		// Msg to Seconday, Primary failed bus
+	XmPciLpEvent_BusFailed	   = 2,		// Msg to Secondary, Primary failed bus
 	XmPciLpEvent_NodeFailed	   = 4,		// Multi-adapter bridge has failed
 	XmPciLpEvent_NodeRecovered = 5,		// Multi-adapter bridge has recovered
 	XmPciLpEvent_BusRecovered  = 12,	// PHB has been recovered
@@ -99,7 +99,7 @@
 			break;
 		}
 	}
-	else if (event) {
+	else if (eventParm) {
 		printk(KERN_ERR "XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n",(int)eventParm->xType);
 	}
 	else {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/align.c linux-2.4.22-pre10/arch/ppc64/kernel/align.c
--- linux-2.4.21/arch/ppc64/kernel/align.c	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/align.c	2003-08-01 13:32:18.000000000 +0000
@@ -21,6 +21,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/cache.h>
+#include <asm/cputable.h>
 
 struct aligninfo {
 	unsigned char len;
@@ -238,7 +239,7 @@
 	dsisr = regs->dsisr;
 
 	/* Power4 doesn't set DSISR for an alignment interrupt */
-	if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
+	if (cur_cpu_spec->cpu_features & CPU_FTR_NODSISRALIGN)
 		dsisr = make_dsisr( *((unsigned *)regs->nip) );
 
 	/* extract the operation and registers from the dsisr */
@@ -306,6 +307,7 @@
 				/* Doing stfs, have to convert to single */
 				enable_kernel_fp();
 				cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread.fpscr);
+				disable_kernel_fp();
 			}
 			else
 				data.dd = current->thread.fpr[reg];
@@ -339,6 +341,7 @@
 				/* Doing lfs, have to convert to double */
 				enable_kernel_fp();
 				cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread.fpscr);
+				disable_kernel_fp();
 			}
 			else
 				current->thread.fpr[reg] = data.dd;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/chrp_setup.c linux-2.4.22-pre10/arch/ppc64/kernel/chrp_setup.c
--- linux-2.4.21/arch/ppc64/kernel/chrp_setup.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/chrp_setup.c	2003-08-01 13:33:58.000000000 +0000
@@ -65,6 +65,7 @@
 #include "open_pic.h"
 #include "xics.h"
 #include <asm/ppcdebug.h>
+#include <asm/cputable.h>
 
 extern volatile unsigned char *chrp_int_ack_special;
 
@@ -305,6 +306,32 @@
 	SYSRQ_KEY = 0x63;	/* Print Screen */
 #endif
 #endif
+        /* Build up the firmware_features bitmask field
+         * using contents of device-tree/ibm,hypertas-functions.
+         * Ultimately this functionality may be moved into prom.c prom_init().
+         */
+	struct device_node * dn;
+	char * hypertas;
+	unsigned int len;
+	dn = find_path_device("/rtas");
+	cur_cpu_spec->firmware_features=0;
+	hypertas = get_property(dn, "ibm,hypertas-functions", &len);
+	if (hypertas) {
+	    while (len > 0){
+		int i;
+	    /* check value against table of strings */
+		for(i=0; i < FIRMWARE_MAX_FEATURES ;i++) {
+		    if ((firmware_features_table[i].name) && (strcmp(firmware_features_table[i].name,hypertas))==0) {
+		    /* we have a match */
+			cur_cpu_spec->firmware_features |= (1UL << firmware_features_table[i].val );
+			break;
+		    }
+		}
+		int hypertas_len = strlen(hypertas);
+		len -= hypertas_len +1;
+		hypertas+= hypertas_len +1;
+	    }
+	}
 }
 
 void __chrp
@@ -315,6 +342,8 @@
 	char *os;
 	static int display_character, set_indicator;
 	static int max_width;
+	static spinlock_t progress_lock = SPIN_LOCK_UNLOCKED;
+	static int pending_newline = 0;  /* did last write end with unprinted newline? */
 
 	if (!rtas.base)
 		return;
@@ -330,34 +359,79 @@
 		display_character = rtas_token("display-character");
 		set_indicator = rtas_token("set-indicator");
 	}
-	if (display_character == RTAS_UNKNOWN_SERVICE) {
-		/* use hex display */
-		if (set_indicator == RTAS_UNKNOWN_SERVICE)
-			return;
-		rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
+
+	if(display_character == RTAS_UNKNOWN_SERVICE) {
+		/* use hex display if available */
+		if(set_indicator != RTAS_UNKNOWN_SERVICE)
+			rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
 		return;
 	}
 
-	rtas_call(display_character, 1, 1, NULL, '\r');
+	spin_lock(&progress_lock);
 
+	/* Last write ended with newline, but we didn't print it since
+	 * it would just clear the bottom line of output. Print it now
+	 * instead.
+	 *
+	 * If no newline is pending, print a CR to start output at the
+	 * beginning of the line.
+	 */
+	if(pending_newline) {
+		rtas_call(display_character, 1, 1, NULL, '\r');
+		rtas_call(display_character, 1, 1, NULL, '\n');
+		pending_newline = 0;
+	} else
+		rtas_call(display_character, 1, 1, NULL, '\r');
+ 
 	width = max_width;
 	os = s;
-	while ( *os )
-	{
-		if ( (*os == '\n') || (*os == '\r') )
+	while (*os) {
+		if(*os == '\n' || *os == '\r') {
+			/* Blank to end of line. */
+			while(width-- > 0)
+				rtas_call(display_character, 1, 1, NULL, ' ');
+ 
+			/* If newline is the last character, save it
+			 * until next call to avoid bumping up the
+			 * display output.
+			 */
+			if(*os == '\n' && !os[1]) {
+				pending_newline = 1;
+				spin_unlock(&progress_lock);
+				return;
+			}
+ 
+			/* RTAS wants CR-LF, not just LF */
+ 
+			if(*os == '\n') {
+				rtas_call(display_character, 1, 1, NULL, '\r');
+				rtas_call(display_character, 1, 1, NULL, '\n');
+			} else {
+				/* CR might be used to re-draw a line, so we'll
+				 * leave it alone and not add LF.
+				 */
+				rtas_call(display_character, 1, 1, NULL, *os);
+			}
+ 
 			width = max_width;
-		else
+		} else {
 			width--;
-		rtas_call(display_character, 1, 1, NULL, *os++ );
+			rtas_call(display_character, 1, 1, NULL, *os);
+		}
+ 
+		os++;
+ 
 		/* if we overwrite the screen length */
-		if ( width == 0 )
+		if ( width <= 0 )
 			while ( (*os != 0) && (*os != '\n') && (*os != '\r') )
 				os++;
 	}
-
+ 
 	/* Blank to end of line. */
 	while ( width-- > 0 )
 		rtas_call(display_character, 1, 1, NULL, ' ' );
+
+	spin_unlock(&progress_lock);
 }
 
 extern void setup_default_decr(void);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/cputable.c linux-2.4.22-pre10/arch/ppc64/kernel/cputable.c
--- linux-2.4.21/arch/ppc64/kernel/cputable.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/cputable.c	2003-08-01 13:34:42.000000000 +0000
@@ -0,0 +1,127 @@
+/*
+ *  arch/ppc/kernel/cputable.c
+ *
+ *  Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
+ *
+ *  Modifications for ppc64:
+ *      Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com>
+ * 
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/threads.h>
+#include <linux/init.h>
+#include <asm/cputable.h>
+
+struct cpu_spec* cur_cpu_spec = NULL;
+
+extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
+
+
+/* We only set the altivec features if the kernel was compiled with altivec
+ * support
+ */
+#ifdef CONFIG_ALTIVEC
+#define CPU_FTR_ALTIVEC_COMP	CPU_FTR_ALTIVEC
+#else
+#define CPU_FTR_ALTIVEC_COMP	0
+#endif
+
+struct cpu_spec	cpu_specs[] = {
+    {	/* Power3 */
+	    0xffff0000, 0x00400000, "Power3 (630)",
+	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+	    COMMON_USER_PPC64,
+	    128, 128,
+	    __setup_cpu_power3,
+	    COMMON_PPC64_FW
+    },
+    {	/* Power3+ */
+	    0xffff0000, 0x00410000, "Power3 (630+)",
+	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+	    COMMON_USER_PPC64,
+	    128, 128,
+	    __setup_cpu_power3,
+	    COMMON_PPC64_FW
+    },
+    {	/* Northstar */
+	    0xffff0000, 0x00330000, "Northstar",
+	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+	    COMMON_USER_PPC64,
+	    128, 128,
+	    __setup_cpu_power3,
+	    COMMON_PPC64_FW
+    },
+    {	/* Pulsar */
+	    0xffff0000, 0x00340000, "Pulsar",
+	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+	    COMMON_USER_PPC64,
+	    128, 128,
+	    __setup_cpu_power3,
+	    COMMON_PPC64_FW
+    },
+    {	/* I-star */
+	    0xffff0000, 0x00360000, "I-star",
+	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+	    COMMON_USER_PPC64,
+	    128, 128,
+	    __setup_cpu_power3,
+	    COMMON_PPC64_FW
+    },
+    {	/* S-star */
+	    0xffff0000, 0x00370000, "S-star",
+	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
+	    COMMON_USER_PPC64,
+	    128, 128,
+	    __setup_cpu_power3,
+	    COMMON_PPC64_FW
+    },
+    {	/* Power4 */
+	    0xffff0000, 0x00350000, "Power4",
+	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+	    CPU_FTR_PPCAS_ARCH_V2,
+	    COMMON_USER_PPC64,
+	    128, 128,
+	    __setup_cpu_power4,
+	    COMMON_PPC64_FW
+    },
+    {	/* Power4+ */
+	    0xffff0000, 0x00380000, "Power4+",
+	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+	    CPU_FTR_PPCAS_ARCH_V2,
+	    COMMON_USER_PPC64,
+	    128, 128,
+	    __setup_cpu_power4,
+	    COMMON_PPC64_FW
+    },
+    {	/* default match */
+	    0x00000000, 0x00000000, "(Power4-Compatible)",
+  	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+	    CPU_FTR_PPCAS_ARCH_V2,
+	    COMMON_USER_PPC64,
+	    128, 128,
+	    __setup_cpu_power4,
+	    COMMON_PPC64_FW
+    }
+};
+
+firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = {
+    {FW_FEATURE_PFT,		"hcall-pft"},
+    {FW_FEATURE_TCE,		"hcall-tce"},
+    {FW_FEATURE_SPRG0,		"hcall-sprg0"},
+    {FW_FEATURE_DABR,		"hcall-dabr"},
+    {FW_FEATURE_COPY,		"hcall-copy"},
+    {FW_FEATURE_ASR,		"hcall-asr"},
+    {FW_FEATURE_DEBUG,		"hcall-debug"},
+    {FW_FEATURE_PERF,		"hcall-perf"},
+    {FW_FEATURE_DUMP,		"hcall-dump"},
+    {FW_FEATURE_INTERRUPT,	"hcall-interrupt"},
+    {FW_FEATURE_MIGRATE,	"hcall-migrate"},
+};
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/eeh.c linux-2.4.22-pre10/arch/ppc64/kernel/eeh.c
--- linux-2.4.21/arch/ppc64/kernel/eeh.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/eeh.c	2003-08-01 13:32:51.000000000 +0000
@@ -129,17 +129,16 @@
 	int adapters_enabled;
 };
 
-/* Enable eeh for the given device node. */
-static void *early_enable_eeh(struct device_node *dn, void *data)
+
+/* Enable/disable eeh for the given device node. */
+static void *early_set_eeh(struct device_node *dn, struct eeh_early_enable_info *info, int enable)
 {
-	struct eeh_early_enable_info *info = data;
 	long ret;
 	char *status = get_property(dn, "status", 0);
 	u32 *class_code = (u32 *)get_property(dn, "class-code", 0);
 	u32 *vendor_id =(u32 *) get_property(dn, "vendor-id", 0);
 	u32 *device_id = (u32 *)get_property(dn, "device-id", 0);
 	u32 *regs;
-	int enable;
 
 	if (status && strcmp(status, "ok") != 0)
 		return NULL;	/* ignore devices with bad status */
@@ -161,15 +160,19 @@
 	 * hang waiting on status bits that won't change, etc.
 	 * But there are a few cases like display devices that make sense.
 	 */
-	enable = 1;	/* i.e. we will do checking */
-	if ((*class_code >> 16) == PCI_BASE_CLASS_DISPLAY)
-		enable = 0;
 
 	if (!eeh_check_opts_config(dn, *class_code, *vendor_id, *device_id, enable)) {
 		if (enable) {
 			printk(KERN_INFO "EEH: %s user requested to run without EEH.\n", dn->full_name);
 			enable = 0;
 		}
+#if 0
+	/* Turn off EEH automatically for graphics ... 
+	* but we don't want to do this, not really. .... */
+	} else 	if ((*class_code >> 16) == PCI_BASE_CLASS_DISPLAY) {
+		printk(KERN_INFO "EEH: %s DISPLAY automatically set to run without EEH.\n", dn->full_name);
+		enable = 0;
+#endif
 	}
 
 	if (!enable)
@@ -179,6 +182,16 @@
 	if (dn->parent && (dn->parent->eeh_mode & EEH_MODE_SUPPORTED)) {
 		/* Parent supports EEH. */
 		dn->eeh_mode |= EEH_MODE_SUPPORTED;
+
+		/* Recurse to parent to set EEH, since we are probably
+		 * a non-eeh supporting pci bridge chip on some card. 
+		 * But recurse only if our eeh setting is to be different.
+		 */
+		if ((enable && (EEH_MODE_NOCHECK == dn->eeh_mode)) ||
+		    (!enable && (EEH_MODE_NOCHECK != dn->eeh_mode))) 
+		{
+			early_set_eeh (dn->parent, info, enable);
+		}
 		dn->eeh_config_addr = dn->parent->eeh_config_addr;
 		return NULL;
 	}
@@ -187,19 +200,29 @@
 	regs = (u32 *)get_property(dn, "reg", 0);
 	if (regs) {
 		/* First register entry is addr (00BBSS00)  */
-		/* Try to enable eeh */
+		/* Try to enable/disable eeh */
 		ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
 				regs[0], info->buid_hi, info->buid_lo,
-				EEH_ENABLE);
+				enable ? EEH_ENABLE : EEH_DISABLE);
 		if (ret == 0) {
 			info->adapters_enabled++;
 			dn->eeh_mode |= EEH_MODE_SUPPORTED;
 			dn->eeh_config_addr = regs[0];
+		} else {
+			printk(KERN_INFO "EEH: %s failed to %s ret=%ld\n", dn->full_name, enable ? "enable" : "disable", ret);
 		}
 	}
 	return NULL; 
 }
 
+/* Enable eeh for the given device node. */
+static void *early_enable_eeh(struct device_node *dn, void *data)
+{
+	struct eeh_early_enable_info *info = data;
+	/* Set enable to 1, i.e. we will do checking */
+	return early_set_eeh (dn, info, 1);
+}
+
 /*
  * Initialize eeh by trying to enable it for all of the adapters in the system.
  * As a side effect we can determine here if eeh is supported at all.
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/entry.S linux-2.4.22-pre10/arch/ppc64/kernel/entry.S
--- linux-2.4.21/arch/ppc64/kernel/entry.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/entry.S	2003-08-01 13:31:14.000000000 +0000
@@ -437,7 +437,7 @@
 	mfsrr1	r10
 	std	r10,_SRR1(r1)
 
-	/* Unfortunatly, the stack pointer and the MSR are also clobbered,
+	/* Unfortunately, the stack pointer and the MSR are also clobbered,
 	 * so they are saved in the PACA (SPRG3) which allows us to restore
 	 * our original state after RTAS returns.
          */
@@ -548,7 +548,7 @@
 	mfmsr	r11
 	std	r11,_MSR(r1)
 
-	/* Unfortunatly, the stack pointer is also clobbered, so it is saved
+	/* Unfortunately, the stack pointer is also clobbered, so it is saved
 	 * in the SPRG2 which allows us to restore our original state after
 	 * PROM returns.
          */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/head.S linux-2.4.22-pre10/arch/ppc64/kernel/head.S
--- linux-2.4.21/arch/ppc64/kernel/head.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/head.S	2003-08-01 13:30:34.000000000 +0000
@@ -32,6 +32,7 @@
 #include <linux/config.h>
 #include <asm/mmu.h>
 #include <asm/perfmon.h>
+#include <asm/cputable.h>
 
 #ifdef CONFIG_PPC_ISERIES
 #define DO_SOFT_DISABLE
@@ -746,6 +747,13 @@
 #ifdef CONFIG_XMON
 	bl	.xmon
 #endif
+#ifdef CONFIG_KDB
+        /*          kdb(KDB_REASON_FAULT,regs->trap,regs); */
+	li      r3,1
+	li 	r4,0x200
+	li      r5,0
+	bl	.kdb
+#endif
 4:	b	4b
 
 
@@ -781,11 +789,16 @@
 FPUnavailable_common:
 	EXCEPTION_PROLOG_COMMON
 	bne	.load_up_fpu		/* if from user, just load it up */
-	li	r20,0
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+#ifdef DO_SOFT_DISABLE
+	ld	r20,SOFTE(r1)
+#else
+	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
+#endif
 	li	r6,0x800
-	bl      .save_remaining_regs    /* if from kernel, take a trap */
-	bl      .KernelFP
-	b       .ret_from_except
+	bl      .save_remaining_regs
+	bl      .KernelFPUnavailableException
+	BUG_OPCODE
 
 	.globl SystemCall_common
 SystemCall_common:
@@ -1390,6 +1403,11 @@
 	li	r0,0
 	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
 
+	LOADADDR(r3,cpu_specs)
+	LOADADDR(r4,cur_cpu_spec)
+	li	r5,0
+	bl	.identify_cpu
+
 	LOADADDR(r2,__toc_start)
 	addi	r2,r2,0x4000
 	addi	r2,r2,0x4000
@@ -1619,21 +1637,19 @@
 	/* restore registers and return */
 	b	fast_exception_return
 
+
 /*
- * FP unavailable trap from kernel - print a message, but let
- * the task use FP in the kernel until it returns to user mode.
+ * disable_kernel_fp()
+ * Disable the FPU.
  */
-_GLOBAL(KernelFP)
-	ld	r3,_MSR(r1)
-	ori	r3,r3,MSR_FP
-	std	r3,_MSR(r1)		/* enable use of FP after return */
-	LOADADDR(r3,86f)
-	mfspr	r4,SPRG3		/* Get PACA */
-	ld	r4,PACACURRENT(r4)	/* current */
-	ld	r5,_NIP(r1)
-	b	.ret_from_except
-86:	.string	"floating point used in kernel (task=%p, pc=%x)\n"
-	.align	4
+_GLOBAL(disable_kernel_fp)
+	mfmsr   r3
+	rldicl  r0,r3,(63-MSR_FP_LG),1
+	rldicl  r3,r0,(MSR_FP_LG+1),0
+	mtmsrd  r3			/* disable use of fpu now */
+	isync
+	blr
+
 
 /*
  * giveup_fpu(tsk)
@@ -1861,6 +1877,13 @@
 	li	r0,0
 	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
 
+	LOADADDR(r3,cpu_specs)
+	sub	r3,r3,r26
+	LOADADDR(r4,cur_cpu_spec)
+	sub	r4,r4,r26
+	mr	r5,r26
+	bl	.identify_cpu
+
 	/* set up the TOC (physical address) */
 	LOADADDR(r2,__toc_start)
 	addi    r2,r2,0x4000
@@ -1949,6 +1972,9 @@
 	addi    r2,r2,0x4000
 	addi    r2,r2,0x4000
 
+	li	r3,0
+	bl	.do_cpu_ftr_fixups
+
 	/* setup the systemcfg pointer                                       */
 	LOADADDR(r9,systemcfg)
 	SET_REG_TO_CONST(r8, KERNELBASE+0x5000)
@@ -2006,6 +2032,11 @@
 
 	bl .start_kernel
 
+_GLOBAL(__setup_cpu_power3)
+	blr
+_GLOBAL(__setup_cpu_power4)
+	blr
+
 _GLOBAL(hmt_init)
 #ifdef CONFIG_HMT
 	LOADADDR(r5, hmt_thread_data)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/htab.c linux-2.4.22-pre10/arch/ppc64/kernel/htab.c
--- linux-2.4.21/arch/ppc64/kernel/htab.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/htab.c	2003-08-01 13:33:53.000000000 +0000
@@ -46,6 +46,7 @@
 #include <asm/hvcall.h>
 #include <asm/iSeries/LparData.h>
 #include <asm/iSeries/HvCallHpt.h>
+#include <asm/cputable.h>
 
 /*
  * Note:  pte   --> Linux PTE
@@ -183,7 +184,9 @@
 
 	/* XXX we currently map kernel text rw, should fix this */
 	if ((systemcfg->platform & PLATFORM_PSERIES) &&
-	   cpu_has_largepage() && (systemcfg->physicalMemorySize > 256*MB)) {
+	    (cur_cpu_spec->cpu_features & 
+	     CPU_FTR_16M_PAGE) &&
+	    (systemcfg->physicalMemorySize > 256*MB)) {
 		create_pte_mapping((unsigned long)KERNELBASE, 
 				   KERNELBASE + 256*MB, mode_rw, mask, 0);
 		create_pte_mapping((unsigned long)KERNELBASE + 256*MB, 
@@ -334,11 +337,23 @@
 	 * Check the user's access rights to the page.  If access should be
 	 * prevented then send the problem up to do_page_fault.
 	 */
+#ifdef CONFIG_SHARED_MEMORY_ADDRESSING
+	access |= _PAGE_PRESENT;
+	if (unlikely(access & ~(pte_val(*ptep)))) {
+		if(!(((ea >> SMALLOC_EA_SHIFT) == 
+		      (SMALLOC_START >> SMALLOC_EA_SHIFT)) &&
+		     ((current->thread.flags) & PPC_FLAG_SHARED))) {
+			spin_unlock(&hash_table_lock[lock_slot].lock);
+			return 1;
+		}
+	}
+#else
 	access |= _PAGE_PRESENT;
 	if (unlikely(access & ~(pte_val(*ptep)))) {
 		spin_unlock(&hash_table_lock[lock_slot].lock);
 		return 1;
 	}
+#endif
 
 	/* 
 	 * We have found a pte (which was present).
@@ -446,6 +461,19 @@
 	case VMALLOC_REGION_ID:
 		mm = &init_mm;
 		vsid = get_kernel_vsid(ea);
+#ifdef CONFIG_SHARED_MEMORY_ADDRESSING
+                /*
+                 * Check if this is a user task with shared access to kernel
+                 * data & we got a protection fault.  If it is, the kernel
+                 * must have faulted in the segment and the protection flags
+                 * on the segment are kernel access only.  Just flush the
+                 * segment table & fault in the segment with the right flags.
+                 */
+                if(((current->thread.flags) & PPC_FLAG_SHARED) &&
+                   (access & _PAGE_USER)) {
+                        flush_stab();
+                }
+#endif
 		break;
 	case EEH_REGION_ID:
 		/*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/i8259.c linux-2.4.22-pre10/arch/ppc64/kernel/i8259.c
--- linux-2.4.21/arch/ppc64/kernel/i8259.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/i8259.c	2003-08-01 13:33:40.000000000 +0000
@@ -146,7 +146,7 @@
         /* init master interrupt controller */
         outb(0x11, 0x20); /* Start init sequence */
         outb(0x00, 0x21); /* Vector base */
-        outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
+        outb(0x04, 0x21); /* edge triggered, Cascade (slave) on IRQ2 */
         outb(0x01, 0x21); /* Select 8086 mode */
         outb(0xFF, 0x21); /* Mask all */
         /* init slave interrupt controller */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/iSeries_IoMmTable.h linux-2.4.22-pre10/arch/ppc64/kernel/iSeries_IoMmTable.h
--- linux-2.4.21/arch/ppc64/kernel/iSeries_IoMmTable.h	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/iSeries_IoMmTable.h	2003-08-01 13:34:10.000000000 +0000
@@ -71,7 +71,7 @@
 /* iSeries_xlateIoMmAddress                                             */
 /************************************************************************/
 /* - Translates an I/O Memory address to Device Node that has been the  */
-/*   allocated the psuedo I/O Address.                                  */
+/*   allocated the pseudo I/O Address.                                  */
 /*                                                                      */
 /* Parameters:                                                          */
 /* IoAddress = I/O Memory Address.                                      */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/iSeries_setup.c linux-2.4.22-pre10/arch/ppc64/kernel/iSeries_setup.c
--- linux-2.4.21/arch/ppc64/kernel/iSeries_setup.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/iSeries_setup.c	2003-08-01 13:34:41.000000000 +0000
@@ -49,6 +49,7 @@
 #include <asm/proc_pmc.h>
 #include <asm/perfmon.h>
 #include <asm/iSeries/mf.h>
+#include <asm/cputable.h>
 
 /* Function Prototypes */
 
@@ -249,7 +250,8 @@
 {
 	unsigned long i;
 	unsigned long mem_blocks = 0;
-	if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
+
+	if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)
 		mem_blocks = iSeries_process_Regatta_mainstore_vpd( mb_array, max_entries );
 	else
 		mem_blocks = iSeries_process_Condor_mainstore_vpd( mb_array, max_entries );
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/ioctl32.c linux-2.4.22-pre10/arch/ppc64/kernel/ioctl32.c
--- linux-2.4.21/arch/ppc64/kernel/ioctl32.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/ioctl32.c	2003-08-01 13:33:40.000000000 +0000
@@ -581,6 +581,17 @@
 		len += sizeof(struct ethtool_regs);
 		break;
 	}
+	case ETHTOOL_GEEPROM: 
+	case ETHTOOL_SEEPROM: { 
+		struct ethtool_eeprom *promaddr = (struct ethtool_eeprom *)A(data); 
+		/* darned variable size arguments */ 
+		if (get_user(len, (u32 *)&promaddr->len)) { 
+			err = -EFAULT; 
+			goto out; 
+		} 
+		len += sizeof(struct ethtool_eeprom); 
+		break; 
+	} 
 	case ETHTOOL_GSET:
 	case ETHTOOL_SSET:	len = sizeof(struct ethtool_cmd); break;
 	default:
@@ -3070,7 +3081,7 @@
 #define DRM32_IOCTL_DMA	     DRM_IOWR(0x29, drm32_dma_t)
 
 /* RED PEN	The DRM layer blindly dereferences the send/request
- * 		indice/size arrays even though they are userland
+ * 		index/size arrays even though they are userland
  * 		pointers.  -DaveM
  */
 static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -3894,6 +3905,7 @@
 
 /* RAID */
 COMPATIBLE_IOCTL(RAID_VERSION),
+COMPATIBLE_IOCTL(RAID_AUTORUN),
 COMPATIBLE_IOCTL(GET_ARRAY_INFO),
 COMPATIBLE_IOCTL(GET_DISK_INFO),
 COMPATIBLE_IOCTL(PRINT_RAID_DEBUG),
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/mf.c linux-2.4.22-pre10/arch/ppc64/kernel/mf.c
--- linux-2.4.21/arch/ppc64/kernel/mf.c	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/mf.c	2003-08-01 13:30:27.000000000 +0000
@@ -44,7 +44,7 @@
 extern struct pci_dev * iSeries_vio_dev;
 
 /*
- * This is the structure layout for the Machine Facilites LPAR event
+ * This is the structure layout for the Machine Facilities LPAR event
  * flows.
  */
 struct VspCmdData;
@@ -402,7 +402,8 @@
  */
 static int shutdown( void )
 {
-	int rc = kill_proc(1,SIGINT,1);
+	extern int cad_pid; /* from kernel/sys.c */
+	int rc = kill_proc(cad_pid,SIGINT,1);
 
 	if ( rc )
 	{
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/misc.S linux-2.4.22-pre10/arch/ppc64/kernel/misc.S
--- linux-2.4.21/arch/ppc64/kernel/misc.S	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/misc.S	2003-08-01 13:32:18.000000000 +0000
@@ -1,5 +1,5 @@
 /*
- *  arch/ppc/kernel/misc.S
+ *  arch/ppc64/kernel/misc.S
  *
  *  
  *
@@ -25,6 +25,7 @@
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/cache.h>
+#include <asm/cputable.h>
 #include "ppc_asm.h"
 
 	.text
@@ -353,7 +354,6 @@
 	bdnz	00b
 	blr	
 
-_GLOBAL(ide_insw)
 _GLOBAL(_insw_ns)
 	cmpwi	0,r5,0
 	mtctr	r5
@@ -365,7 +365,6 @@
 	bdnz	00b
 	blr
 
-_GLOBAL(ide_outsw)
 _GLOBAL(_outsw_ns)
 	cmpwi	0,r5,0
 	mtctr	r5
@@ -480,6 +479,93 @@
 	blr
 
 /*
+ * identify_cpu,
+ * In:	 r3 = base of the cpu_specs array
+ *       r4 = address of cur_cpu_spec
+ *       r5 = relocation offset
+ */
+_GLOBAL(identify_cpu)
+	mfpvr	r7
+1:
+	lwz	r8,CPU_SPEC_PVR_MASK(r3)
+	and	r8,r8,r7
+	lwz	r9,CPU_SPEC_PVR_VALUE(r3)
+	cmplw	0,r9,r8
+	beq	1f
+	addi	r3,r3,CPU_SPEC_ENTRY_SIZE
+	b	1b
+1:
+	add	r3,r3,r5
+	std	r3,0(r4)
+	blr
+
+/*
+ * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
+ * and writes nop's over sections of code that don't apply for this cpu.
+ * r3 = data offset (not changed)
+ */
+_GLOBAL(do_cpu_ftr_fixups)
+	/* Get CPU 0 features */
+	LOADADDR(r6,cur_cpu_spec)
+	sub	r6,r6,r3
+	ld	r4,0(r6)
+	sub	r4,r4,r3
+	ld	r4,CPU_SPEC_FEATURES(r4)
+	/* Get the fixup table */
+	LOADADDR(r6,__start___ftr_fixup)
+	sub	r6,r6,r3
+	LOADADDR(r7,__stop___ftr_fixup)
+	sub	r7,r7,r3
+	/* Do the fixup */
+1:	cmpld	r6,r7
+	bgelr
+	addi	r6,r6,32
+	ld	r8,-32(r6)	/* mask */
+	and	r8,r8,r4
+	ld	r9,-24(r6)	/* value */
+	cmpld	r8,r9
+	beq	1b
+	ld	r8,-16(r6)	/* section begin */
+	ld	r9,-8(r6)	/* section end */
+	subf.	r9,r8,r9
+	beq	1b
+	/* write nops over the section of code */
+	/* todo: if large section, add a branch at the start of it */
+	srwi	r9,r9,2
+	mtctr	r9
+	sub	r8,r8,r3
+	lis	r0,0x60000000@h	/* nop */
+3:	stw	r0,0(r8)
+	andi.	r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
+	beq	2f
+	dcbst	0,r8		/* suboptimal, but simpler */
+	sync
+	icbi	0,r8
+2:	addi	r8,r8,4
+	bdnz	3b
+	sync			/* additional sync needed on g4 */
+	isync
+	b	1b
+
+/*
+ * call_setup_cpu - call the setup_cpu function for this cpu
+ * r3 = data offset
+ *
+ * Setup function is called with:
+ *   r3 = data offset
+ *   r4 = ptr to CPU spec (relocated)
+ */
+_GLOBAL(call_setup_cpu)
+	LOADADDR(r4, cur_cpu_spec)
+	sub	r4,r4,r3
+	lwz	r4,0(r4)		# load pointer to cpu_spec
+	sub	r4,r4,r3		# relocate
+	lwz	r6,CPU_SPEC_SETUP(r4)	# load function pointer
+	sub	r6,r6,r3	
+	mtctr	r6
+	bctr
+
+/*
  * Create a kernel thread
  *   arch_kernel_thread(fn, arg, flags)
  */
@@ -717,7 +803,24 @@
 	.llong .sys_madvise		/* 205 */
 	.llong .sys_mincore		/* 206 */
 	.llong .sys_gettid		/* 207 */
-	.rept NR_syscalls-208
+#if 0 /* Reserved syscalls */
+	.llong .sys_tkill		/* 208 */
+	.llong .sys_setxattr
+	.llong .sys_lsetxattr	/* 210 */
+	.llong .sys_fsetxattr
+	.llong .sys_getxattr
+	.llong .sys_lgetxattr
+	.llong .sys_fgetxattr
+	.llong .sys_listxattr	/* 215 */
+	.llong .sys_llistxattr
+	.llong .sys_flistxattr
+	.llong .sys_removexattr
+	.llong .sys_lremovexattr
+	.llong .sys_fremovexattr	/* 220 */
+	.llong .sys_futex
+#endif
+	.llong .sys_perfmonctl   /* Put this here for now ... */
+	.rept NR_syscalls-222
 		.llong .sys_ni_syscall
 	.endr
 #endif
@@ -931,6 +1034,23 @@
 	.llong .sys_madvise		/* 205 */
 	.llong .sys_mincore		/* 206 */
 	.llong .sys_gettid		/* 207 */
-	.rept NR_syscalls-208
+#if 0 /* Reserved syscalls */
+	.llong .sys_tkill		/* 208 */
+	.llong .sys_setxattr
+	.llong .sys_lsetxattr	/* 210 */
+	.llong .sys_fsetxattr
+	.llong .sys_getxattr
+	.llong .sys_lgetxattr
+	.llong .sys_fgetxattr
+	.llong .sys_listxattr	/* 215 */
+	.llong .sys_llistxattr
+	.llong .sys_flistxattr
+	.llong .sys_removexattr
+	.llong .sys_lremovexattr
+	.llong .sys_fremovexattr	/* 220 */
+	.llong .sys_futex
+#endif
+	.llong .sys_perfmonctl   /* Put this here for now ... */
+	.rept NR_syscalls-222
 	.llong .sys_ni_syscall
 	.endr
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/mk_defs.c linux-2.4.22-pre10/arch/ppc64/kernel/mk_defs.c
--- linux-2.4.21/arch/ppc64/kernel/mk_defs.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/mk_defs.c	2003-08-01 13:35:06.000000000 +0000
@@ -37,6 +37,7 @@
 #include <asm/iSeries/HvLpEvent.h>
 #include <asm/prom.h>
 #include <asm/rtas.h>
+#include <asm/cputable.h>
 
 #define DEFINE(sym, val) \
 	asm volatile("\n#define\t" #sym "\t%0" : : "i" (val))
@@ -188,5 +189,12 @@
 
 	DEFINE(CLONE_VM, CLONE_VM);
 
+	/* About the CPU features table */
+	DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
+	DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
+	DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
+	DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
+	DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
+
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/pSeries_lpar.c linux-2.4.22-pre10/arch/ppc64/kernel/pSeries_lpar.c
--- linux-2.4.21/arch/ppc64/kernel/pSeries_lpar.c	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/pSeries_lpar.c	2003-08-01 13:31:07.000000000 +0000
@@ -276,7 +276,6 @@
 
 
 
-/* Code for hvc_console.  Should move it back eventually. */
 
 int hvc_get_chars(int index, char *buf, int count)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/pci.c linux-2.4.22-pre10/arch/ppc64/kernel/pci.c
--- linux-2.4.21/arch/ppc64/kernel/pci.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/pci.c	2003-08-01 13:33:34.000000000 +0000
@@ -137,7 +137,7 @@
 	ioaddr = (addr > _IO_BASE) ? addr - _IO_BASE : 0;
 
 	pci_for_each_dev(dev) {
-		if ((dev->class >> 8) == PCI_BASE_CLASS_BRIDGE)
+  	        if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
 			continue;
 		for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
 			unsigned long start = pci_resource_start(dev,i);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/pci.h linux-2.4.22-pre10/arch/ppc64/kernel/pci.h
--- linux-2.4.21/arch/ppc64/kernel/pci.h	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/pci.h	2003-08-01 13:33:50.000000000 +0000
@@ -71,7 +71,7 @@
 static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev)
 {
 	struct device_node *dn = (struct device_node *)(dev->sysdata);
-	if (dn->devfn == dev->devfn && dn->busno == dev->bus->number)
+	if (dn->devfn == dev->devfn && dn->busno == (dev->bus->number&0xff))
 		return dn;	/* fast path.  sysdata is good */
 	else
 		return fetch_dev_dn(dev);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/pci_dma.c linux-2.4.22-pre10/arch/ppc64/kernel/pci_dma.c
--- linux-2.4.21/arch/ppc64/kernel/pci_dma.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/pci_dma.c	2003-08-01 13:34:40.000000000 +0000
@@ -713,12 +713,6 @@
 	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
 		bus = pci_bus_b(ln);
 		busdn = PCI_GET_DN(bus);
-		/* NOTE: there should never be a window declared on a bus when
-		 * child devices also have a window.  If this should ever be
-		 * architected, we probably want children to have priority.
-		 * In reality, the PHB containing ISA has the property, but otherwise
-		 * it is the pci-bridges that have the property.
-		 */
 		dma_window = (u32 *)get_property(busdn, "ibm,dma-window", 0);
 		if (dma_window) {
 			/* Busno hasn't been copied yet.
@@ -726,8 +720,9 @@
 			 */
 			busdn->busno = bus->number;
 			create_pci_bus_tce_table((unsigned long)busdn);
-		} else
-			create_tce_tables_for_busesLP(&bus->children);
+		}
+		/* look for a window on a bridge even if the PHB had one */
+		create_tce_tables_for_busesLP(&bus->children);
 	}
 }
 
@@ -1349,7 +1344,7 @@
 {
 	struct TceTable * tbl;
 	unsigned numTces;
-	int num_dma;
+	int num_dma = 0;
 	dma_addr_t dma_handle;
 
 	PPCDBG(PPCDBG_TCE, "pci_map_sg:\n");
@@ -1373,6 +1368,8 @@
 		/* Create the tces and get the dma address */ 
 		dma_handle = create_tces_sg( tbl, sg, nents, numTces, direction );
 
+		if(dma_handle == NO_TCE) return 0;
+
 		/* Fill in the dma scatterlist */
 		num_dma = fill_scatterlist_sg( sg, nents, dma_handle, numTces );
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/perfmon.c linux-2.4.22-pre10/arch/ppc64/kernel/perfmon.c
--- linux-2.4.21/arch/ppc64/kernel/perfmon.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/perfmon.c	2003-08-01 13:30:28.000000000 +0000
@@ -22,6 +22,7 @@
 #include <asm/perfmon.h>
 #include <asm/iSeries/HvCall.h>
 #include <asm/hvcall.h>
+#include <asm/cputable.h>
 
 extern char _stext[], _etext[], _end[];
 struct perfmon_base_struct perfmon_base = {0, 0, 0, 0, 0, 0, 0, PMC_STATE_INITIAL};
@@ -450,7 +451,7 @@
 	}
 	perfmon_base.state = PMC_STATE_PROFILE_KERN; 
 
-	if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) {
+	if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) {
 		for(i = 0; i < 8; i++) 
 			pdata->pmc[i] = 0x0;
 		pdata->pmc[1] = 0x7f000000;
@@ -794,7 +795,7 @@
 	 * Flood enabled is required on GP for PMC cycle profile mode
 	 *   iSeries SP sets this by default.  pSeries requires the OS to enable.
 	 */
-	if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) {
+	if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) {
 		/* Set up the debug bus to pmc mode - a feature of GP */
 		switch(systemcfg->platform) {
 		case PLATFORM_ISERIES_LPAR:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/pmc.c linux-2.4.22-pre10/arch/ppc64/kernel/pmc.c
--- linux-2.4.21/arch/ppc64/kernel/pmc.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/pmc.c	2003-08-01 13:30:33.000000000 +0000
@@ -206,7 +206,7 @@
  *            the segment table.
  *
  * Input : unsigned long size: bytes of storage to allocate.
- * Return: void * : pointer to the kernal address of the buffer.
+ * Return: void * : pointer to the kernel address of the buffer.
  */
 void* btmalloc (unsigned long size) {
 	pgd_t *pgdp;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/ppc_ksyms.c linux-2.4.22-pre10/arch/ppc64/kernel/ppc_ksyms.c
--- linux-2.4.21/arch/ppc64/kernel/ppc_ksyms.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/ppc_ksyms.c	2003-08-01 13:34:51.000000000 +0000
@@ -78,6 +78,13 @@
 extern struct pci_dev * iSeries_veth_dev;
 extern struct pci_dev * iSeries_vio_dev;
 
+#ifdef CONFIG_SHARED_MEMORY_ADDRESSING
+extern void shared_malloc(unsigned long);
+extern void shared_free(void *);
+extern int shared_task_mark();
+extern int shared_task_unmark();
+#endif
+
 EXPORT_SYMBOL(do_signal);
 EXPORT_SYMBOL(syscall_trace);
 EXPORT_SYMBOL(do_IRQ);
@@ -309,3 +316,10 @@
 extern void dump_send_ipi(int (*dump_ipi_callback)(struct pt_regs *));
 EXPORT_SYMBOL(dump_send_ipi);
 #endif
+
+#ifdef CONFIG_SHARED_MEMORY_ADDRESSING
+EXPORT_SYMBOL(shared_malloc);
+EXPORT_SYMBOL(shared_free);
+EXPORT_SYMBOL(shared_task_mark);
+EXPORT_SYMBOL(shared_task_unmark);
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/proc_pcifr.c linux-2.4.22-pre10/arch/ppc64/kernel/proc_pcifr.c
--- linux-2.4.21/arch/ppc64/kernel/proc_pcifr.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/proc_pcifr.c	2003-08-01 13:30:40.000000000 +0000
@@ -198,10 +198,18 @@
 
 			/* look for the net devices out */
 			for (dev = dev_base; dev != NULL; dev = dev->next) 	{
-				if (dev->base_addr == PciDev->resource[0].start ) {
-					BufLen += sprintf(ProcBuffer+BufLen, "     - Net device: %s\n", dev->name);
+				int j;
+                               
+				if (!dev->base_addr) /* virtual device, no base address */
 					break;
-				} /* if */
+				
+				for (j=0;j<6;j++) { /* PCI has 6 base addresses */
+					if (dev->base_addr == PciDev->resource[j].start ) {
+						BufLen += sprintf(ProcBuffer+BufLen, "     - Net device: %s\n", dev->name);
+						break;
+					} /* if */
+				}
+				if (j!=6) break; /* found one */
 			} /* for */
 		} /* if(PCI_SLOT(PciDev->devfn) != 0)  */
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/proc_pmc.c linux-2.4.22-pre10/arch/ppc64/kernel/proc_pmc.c
--- linux-2.4.21/arch/ppc64/kernel/proc_pmc.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/proc_pmc.c	2003-08-01 13:34:43.000000000 +0000
@@ -49,12 +49,12 @@
 
 static int proc_pmc_control_mode = 0;
 
-static struct proc_dir_entry *proc_ppc64_root = NULL;
+struct proc_dir_entry *proc_ppc64_root = NULL;
 static struct proc_dir_entry *proc_ppc64_pmc_root = NULL;
 static struct proc_dir_entry *proc_ppc64_pmc_system_root = NULL;
 static struct proc_dir_entry *proc_ppc64_pmc_cpu_root[NR_CPUS] = {NULL, };
 
-static spinlock_t proc_ppc64_lock;
+spinlock_t proc_ppc64_lock;
 static int proc_ppc64_page_read(char *page, char **start, off_t off,
 				int count, int *eof, void *data);
 static void proc_ppc64_create_paca(int num, struct proc_dir_entry *paca_dir);
@@ -145,8 +145,13 @@
 	 *   /proc/ppc64/pmc/cpu0 
 	 */
 	spin_lock(&proc_ppc64_lock);
-	proc_ppc64_root = proc_mkdir("ppc64", 0);
-	if (!proc_ppc64_root) return;
+	if (proc_ppc64_root == NULL) {
+		proc_ppc64_root = proc_mkdir("ppc64", 0);
+		if (!proc_ppc64_root) {
+			spin_unlock(&proc_ppc64_lock);
+			return;
+		}
+	}
 	spin_unlock(&proc_ppc64_lock);
 
 	ent = create_proc_entry("naca", S_IFREG|S_IRUGO, proc_ppc64_root);
@@ -173,7 +178,9 @@
 	}
 
 	/* Placeholder for rtas interfaces. */
-	rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root);
+	if (rtas_proc_dir == NULL) {
+		rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root);
+	}
 
 	/* Create the /proc/ppc64/pcifr for the Pci Flight Recorder.	 */
 	proc_pciFr_init(proc_ppc64_root);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/process.c linux-2.4.22-pre10/arch/ppc64/kernel/process.c
--- linux-2.4.21/arch/ppc64/kernel/process.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/process.c	2003-08-01 13:31:45.000000000 +0000
@@ -42,6 +42,7 @@
 #include <asm/ppcdebug.h>
 #include <asm/machdep.h>
 #include <asm/iSeries/HvCallHpt.h>
+#include <asm/cputable.h>
 
 int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs);
 
@@ -390,7 +391,7 @@
 	 * __get_free_pages() might give us a page > KERNBASE+256M which
 	 * is mapped with large ptes so we can't set up the guard page.
 	 */
-	if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
+	if (cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE)
 		return;
 
 	for (i=0; i < systemcfg->processorCount; i++) {
@@ -493,7 +494,7 @@
 			 * gets fixed.
 			 */
 			if (ip < first_sched || ip >= last_sched)
-				return (ip & 0xFFFFFFFF);
+				return (ip);
 		}
 	} while (count++ < 16);
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/prom.c linux-2.4.22-pre10/arch/ppc64/kernel/prom.c
--- linux-2.4.21/arch/ppc64/kernel/prom.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/prom.c	2003-08-01 13:34:38.000000000 +0000
@@ -363,7 +363,7 @@
 			 * d-cache and i-cache sizes... -Peter
 			 */
 			if ( num_cpus == 1 ) {
-				u32 size, lsize;
+				u32 size, lsize, sets;
 
 				call_prom(RELOC("getprop"), 4, 1, node,
 					  RELOC("d-cache-size"),
@@ -631,6 +631,7 @@
 	unsigned long offset = reloc_offset();
 	struct prom_t *_prom = PTRRELOC(&prom);
 	struct rtas_t *_rtas = PTRRELOC(&rtas);
+	struct naca_struct *_naca = RELOC(naca);
 	struct systemcfg *_systemcfg = RELOC(systemcfg);
 	ihandle prom_rtas;
         u32 getprop_rval;
@@ -1059,6 +1060,7 @@
         unsigned long *spinloop     = __v2a(&__secondary_hold_spinloop);
         unsigned long *acknowledge  = __v2a(&__secondary_hold_acknowledge);
         unsigned long secondary_hold = (unsigned long)__v2a(*PTRRELOC((unsigned long *)__secondary_hold));
+        struct naca_struct *_naca = RELOC(naca);
         struct systemcfg *_systemcfg = RELOC(systemcfg);
 	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
 	struct prom_t *_prom = PTRRELOC(&prom);
@@ -1237,7 +1239,7 @@
 #ifdef CONFIG_PPCDBG
 extern char *trace_names[];	/* defined in udbg.c -- need a better interface */
 
-static void parse_ppcdbg_optionlist(const char *cmd,
+void parse_ppcdbg_optionlist(const char *cmd,
 				    const char *cmdend)
 {
 	unsigned long offset = reloc_offset();
@@ -1559,7 +1561,7 @@
 	}
 
 	/* We assume the phys. address size is 3 cells */
-	RELOC(prom_mmu) = (ihandle)(unsigned long)getprop_rval;
+	prom_mmu = (ihandle)(unsigned long)getprop_rval;
 
 	if ((long)call_prom(RELOC("call-method"), 4, 4,
 				RELOC("translate"),
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/rtas-proc.c linux-2.4.22-pre10/arch/ppc64/kernel/rtas-proc.c
--- linux-2.4.21/arch/ppc64/kernel/rtas-proc.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/rtas-proc.c	2003-08-01 13:32:51.000000000 +0000
@@ -115,14 +115,18 @@
 
 
 /* Globals */
-static struct proc_dir_entry *proc_rtas;
 static struct rtas_sensors sensors;
-static struct device_node *rtas_node;
+static struct device_node *rtas_node = NULL;
 static unsigned long power_on_time = 0; /* Save the time the user set */
 static char progress_led[MAX_LINELENGTH];
 
 static unsigned long rtas_tone_frequency = 1000;
 static unsigned long rtas_tone_volume = 0;
+static unsigned int open_token = 0;
+
+extern struct proc_dir_entry *proc_ppc64_root;
+extern struct proc_dir_entry *rtas_proc_dir;
+extern spinlock_t proc_ppc64_lock;
 
 /* ****************STRUCTS******************************************* */
 struct individual_sensor {
@@ -160,6 +164,12 @@
 		size_t count, loff_t *ppos);
 static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
 		size_t count, loff_t *ppos);
+static int ppc_rtas_errinjct_open(struct inode *inode, struct file *file);
+static int ppc_rtas_errinjct_release(struct inode *inode, struct file *file);
+static ssize_t ppc_rtas_errinjct_write(struct file * file, const char * buf,
+				   size_t count, loff_t *ppos);
+static ssize_t ppc_rtas_errinjct_read(struct file *file, char *buf,
+				      size_t count, loff_t *ppos);
 
 struct file_operations ppc_rtas_poweron_operations = {
 	.read =		ppc_rtas_poweron_read,
@@ -184,6 +194,13 @@
 	.write =	ppc_rtas_tone_volume_write
 };
 
+struct file_operations ppc_rtas_errinjct_operations = {
+    .open =		ppc_rtas_errinjct_open,
+    .read = 		ppc_rtas_errinjct_read,
+    .write = 		ppc_rtas_errinjct_write,
+    .release = 		ppc_rtas_errinjct_release
+};
+
 int ppc_rtas_find_all_sensors (void);
 int ppc_rtas_process_sensor(struct individual_sensor s, int state, 
 		int error, char * buf);
@@ -200,33 +217,54 @@
 	struct proc_dir_entry *entry;
 
 	rtas_node = find_devices("rtas");
-	if ((rtas_node == 0) || (systemcfg->platform == PLATFORM_ISERIES_LPAR)) {
+	if ((rtas_node == NULL) || (systemcfg->platform == PLATFORM_ISERIES_LPAR)) {
 		return;
 	}
 	
-	proc_rtas = proc_mkdir("rtas", 0);
-	if (proc_rtas == 0)
+	spin_lock(&proc_ppc64_lock);
+	if (proc_ppc64_root == NULL) {
+		proc_ppc64_root = proc_mkdir("ppc64", 0);
+		if (!proc_ppc64_root) {
+			spin_unlock(&proc_ppc64_lock);
+			return;
+		}		
+	}
+	spin_unlock(&proc_ppc64_lock);
+	
+	if (rtas_proc_dir == NULL) {
+		rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root);
+	}
+
+	if (rtas_proc_dir == NULL) {
+		printk(KERN_ERR "Failed to create /proc/ppc64/rtas in rtas_init\n");
 		return;
+	}
 
 	/* /proc/rtas entries */
 
-	entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, proc_rtas);
+	entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, rtas_proc_dir);
 	if (entry) entry->proc_fops = &ppc_rtas_progress_operations;
 
-	entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_rtas); 
+	entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, rtas_proc_dir); 
 	if (entry) entry->proc_fops = &ppc_rtas_clock_operations;
 
-	entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas); 
+	entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, rtas_proc_dir); 
 	if (entry) entry->proc_fops = &ppc_rtas_poweron_operations;
 
-	create_proc_read_entry("sensors", S_IRUGO, proc_rtas, 
+	create_proc_read_entry("sensors", S_IRUGO, rtas_proc_dir, 
 			ppc_rtas_sensor_read, NULL);
 	
-	entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_rtas); 
+	entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, rtas_proc_dir); 
 	if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations;
 
-	entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas); 
+	entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, rtas_proc_dir); 
 	if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations;
+
+#ifdef CONFIG_RTAS_ERRINJCT
+	entry = create_proc_entry("errinjct", S_IWUSR|S_IRUGO, rtas_proc_dir);
+	if (entry) entry->proc_fops = &ppc_rtas_errinjct_operations;
+#endif
+
 }
 
 /* ****************************************************************** */
@@ -405,10 +443,14 @@
 		j = sensors.sensor[i].quant;
 		/* A sensor may have multiple instances */
 		while (j >= 0) {
+
 			error =	rtas_call(get_sensor_state, 2, 2, &ret, 
-				  sensors.sensor[i].token, sensors.sensor[i].quant-j);
+				  	  sensors.sensor[i].token, 
+				  	  sensors.sensor[i].quant - j);
+
 			state = (int) ret;
-			n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n );
+			n += ppc_rtas_process_sensor(sensors.sensor[i], state, 
+					     	     error, buffer+n );
 			n += sprintf (buffer+n, "\n");
 			j--;
 		} /* while */
@@ -426,6 +468,7 @@
 		n = count;
 	else
 		*eof = 1;
+
 	memcpy(buf, buffer + off, n);
 	*start = buf;
 	kfree(buffer);
@@ -436,10 +479,10 @@
 
 int ppc_rtas_find_all_sensors (void)
 {
-	unsigned long *utmp;
-	int len, i, j;
+	unsigned int *utmp;
+	int len, i;
 
-	utmp = (unsigned long *) get_property(rtas_node, "rtas-sensors", &len);
+	utmp = (unsigned int *) get_property(rtas_node, "rtas-sensors", &len);
 	if (utmp == NULL) {
 		printk (KERN_ERR "error: could not get rtas-sensors\n");
 		return 1;
@@ -447,9 +490,9 @@
 
 	sensors.quant = len / 8;      /* int + int */
 
-	for (i=0, j=0; j<sensors.quant; i+=2, j++) {
-		sensors.sensor[j].token = utmp[i];
-		sensors.sensor[j].quant = utmp[i+1];
+	for (i=0; i<sensors.quant; i++) {
+		sensors.sensor[i].token = *utmp++;
+		sensors.sensor[i].quant = *utmp++;
 	}
 	return 0;
 }
@@ -515,6 +558,7 @@
 	int n = 0;
 
 	/* What kind of sensor do we have here? */
+	
 	switch (s.token) {
 		case KEY_SWITCH:
 			n += sprintf(buf+n, "Key switch:\t");
@@ -698,9 +742,9 @@
 	ret = (char *) get_property(rtas_node, rstr, &llen);
 
 	n=0;
-	if (ret[0] == '\0')
+	if (ret == NULL || ret[0] == '\0') {
 		n += sprintf ( buffer+n, "--- ");/* does not have a location */
-	else {
+	} else {
 		char t[50];
 		ret += pos;
 
@@ -794,3 +838,137 @@
 	*ppos += n;
 	return n;
 }
+
+/* ****************************************************************** */
+/* ERRINJCT			                                      */
+/* ****************************************************************** */
+static int ppc_rtas_errinjct_open(struct inode *inode, struct file *file)
+{
+	int rc;
+
+	/* We will only allow one process to use error inject at a
+	   time.  Since errinjct is usually only used for testing,
+	   this shouldn't be an issue */
+	if (open_token) {
+		return -EAGAIN;
+	}
+	rc = rtas_errinjct_open();
+	if (rc < 0) {
+		return -EIO;
+	}
+	open_token = rc;
+
+	return 0;
+}
+
+static ssize_t ppc_rtas_errinjct_write(struct file * file, const char * buf,
+				       size_t count, loff_t *ppos)
+{
+ 
+	char * ei_token;
+	char * workspace = NULL;
+	size_t max_len;
+	int token_len;
+	int rc;
+
+	/* Verify the errinjct token length */
+	if (count < ERRINJCT_TOKEN_LEN) {
+		max_len = count;
+	} else {
+		max_len = ERRINJCT_TOKEN_LEN;
+	}
+
+	token_len = strnlen(buf, max_len);
+	token_len++; /* Add one for the null termination */
+    
+	ei_token = (char *)kmalloc(token_len, GFP_KERNEL);
+	if (!ei_token) {
+		printk(KERN_WARNING "error: kmalloc failed\n");
+		return -ENOMEM;
+	}
+
+	strncpy(ei_token, buf, token_len);
+    
+	if (count > token_len + WORKSPACE_SIZE) {
+		count = token_len + WORKSPACE_SIZE;
+	}
+    
+	buf += token_len;
+
+	/* check if there is a workspace */
+	if (count > token_len) {
+		/* Verify the workspace size */
+		if ((count - token_len) > WORKSPACE_SIZE) {
+			max_len = WORKSPACE_SIZE;
+		} else {
+			max_len = count - token_len;
+		}
+
+		workspace = (char *)kmalloc(max_len, GFP_KERNEL);
+		if (!workspace) {
+			printk(KERN_WARNING "error: failed kmalloc\n");
+			kfree(ei_token);
+			return -ENOMEM;
+		}
+	
+		memcpy(workspace, buf, max_len);
+	}
+
+	rc = rtas_errinjct(open_token, ei_token, workspace);
+
+	if (count > token_len) {
+		kfree(workspace);
+	}
+	kfree(ei_token);
+
+	return rc < 0 ? rc : count;
+}
+
+static int ppc_rtas_errinjct_release(struct inode *inode, struct file *file)
+{
+	int rc;
+    
+	rc = rtas_errinjct_close(open_token);
+	if (rc) {
+		return rc;
+	}
+	open_token = 0;
+	return 0;
+}
+
+static ssize_t ppc_rtas_errinjct_read(struct file *file, char *buf,
+				      size_t count, loff_t *ppos) 
+{
+	char * buffer;
+	int i;
+	int n = 0;
+
+	buffer = (char *)kmalloc(MAX_ERRINJCT_TOKENS * (ERRINJCT_TOKEN_LEN+1),
+				 GFP_KERNEL);
+	if (!buffer) {
+		printk(KERN_ERR "error: kmalloc failed\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < MAX_ERRINJCT_TOKENS && ei_token_list[i].value; i++) {
+		n += sprintf(buffer+n, ei_token_list[i].name);
+		n += sprintf(buffer+n, "\n");
+	}
+
+	if (*ppos >= strlen(buffer)) {
+		kfree(buffer);
+		return 0;
+	}
+	if (n > strlen(buffer) - *ppos)
+		n = strlen(buffer) - *ppos;
+
+	if (n > count)
+		n = count;
+
+	memcpy(buf, buffer + *ppos, n);
+
+	*ppos += n;
+
+	kfree(buffer);
+	return n;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/rtas.c linux-2.4.22-pre10/arch/ppc64/kernel/rtas.c
--- linux-2.4.21/arch/ppc64/kernel/rtas.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/rtas.c	2003-08-01 13:33:20.000000000 +0000
@@ -16,6 +16,7 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/fs.h>
+#include <linux/slab.h>
 
 #include <asm/init.h>
 #include <asm/prom.h>
@@ -27,9 +28,11 @@
 #include <asm/system.h>
 #include <asm/abs_addr.h>
 #include <asm/udbg.h>
+#include <asm/uaccess.h>
 
 struct proc_dir_entry *rtas_proc_dir;	/* /proc/ppc64/rtas dir */
 struct flash_block_list_header rtas_firmware_flash_list = {0, 0};
+struct errinjct_token ei_token_list[MAX_ERRINJCT_TOKENS];
 
 /*
  * prom_init() is called very early on, before the kernel text
@@ -59,7 +62,7 @@
 extern unsigned long reloc_offset(void);
 
 spinlock_t rtas_data_buf_lock = SPIN_LOCK_UNLOCKED;
-char rtas_data_buf[RTAS_DATA_BUF_SIZE];
+char rtas_data_buf[RTAS_DATA_BUF_SIZE]__page_aligned;
 
 void
 phys_call_rtas(int token, int nargs, int nret, ...)
@@ -219,7 +222,11 @@
 			image_size += f->blocks[i].length;
 		}
 		next = f->next;
-		f->next = (struct flash_block_list *)virt_to_absolute((unsigned long)f->next);
+		/* Don't translate final NULL pointer */
+		if(f->next)
+			f->next = (struct flash_block_list *)virt_to_absolute((unsigned long)f->next);
+		else
+			f->next = 0LL;
 		/* make num_blocks into the version/length field */
 		f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
 	}
@@ -285,3 +292,108 @@
 		rtas_flash_bypass_warning();
         rtas_power_off();
 }
+
+int
+rtas_errinjct_open(void)
+{
+	u32 ret[2];
+	int open_token;
+	int rc;
+
+	/* The rc and open_token values are backwards due to a misprint in
+	 * the RPA */ 
+	open_token = rtas_call(rtas_token("ibm,open-errinjct"), 0, 2, (void *) &ret);
+	rc = ret[0];
+
+	if (rc < 0) {
+		printk(KERN_WARNING "error: ibm,open-errinjct failed (%d)\n", rc);
+		return rc;
+	}
+
+	return open_token;
+}
+
+int
+rtas_errinjct(unsigned int open_token, char * ei_token, char * in_workspace)
+{
+	struct errinjct_token * ei;
+	int rtas_ei_token = -1;
+	int rc;
+	int i;
+
+	ei = ei_token_list;
+	for (i = 0; i < MAX_ERRINJCT_TOKENS && ei->name; i++) {
+		if (strcmp(ei_token, ei->name) == 0) {
+			rtas_ei_token = ei->value;
+			break;
+		}
+		ei++;
+	}
+	if (rtas_ei_token == -1) {
+		return -EINVAL;
+	}
+
+	spin_lock(&rtas_data_buf_lock);
+
+	if (in_workspace) 
+		memcpy(rtas_data_buf, in_workspace, RTAS_DATA_BUF_SIZE);
+
+	rc = rtas_call(rtas_token("ibm,errinjct"), 3, 1, NULL, rtas_ei_token,
+		       open_token, __pa(rtas_data_buf));   
+
+	spin_unlock(&rtas_data_buf_lock);
+
+	return rc;
+}
+
+int
+rtas_errinjct_close(unsigned int open_token)
+{
+	int rc;
+
+	rc = rtas_call(rtas_token("ibm,close-errinjct"), 1, 1, NULL, open_token);
+	if (rc != 0) {
+		printk(KERN_WARNING "error: ibm,close-errinjct failed (%d)\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+#ifndef CONFIG_PPC_ISERIES
+static int __init rtas_errinjct_init(void)
+{
+	char * token_array;
+	char * end_array;
+	int array_len = 0;
+	int len;
+	int i, j;
+
+	token_array = (char *) get_property(rtas.dev, "ibm,errinjct-tokens",
+					    &array_len);    
+	/* if token is not found, then we fall through loop */
+	end_array = token_array + array_len;
+	for (i = 0, j = 0; i < MAX_ERRINJCT_TOKENS && token_array < end_array; i++) {
+
+		len = strnlen(token_array, ERRINJCT_TOKEN_LEN) + 1;
+		ei_token_list[i].name = (char *) kmalloc(len, GFP_KERNEL);
+		if (!ei_token_list[i].name) {
+			printk(KERN_WARNING "error: kmalloc failed\n");
+			return -ENOMEM;
+		}
+
+		strcpy(ei_token_list[i].name, token_array);
+		token_array += len;
+
+		ei_token_list[i].value = *(int *)token_array;
+		token_array += sizeof(int);
+	}
+	for (; i < MAX_ERRINJCT_TOKENS; i++) {
+		ei_token_list[i].name = 0;
+		ei_token_list[i].value = 0;
+	}
+	return 0;
+}
+
+__initcall(rtas_errinjct_init);
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/rtasd.c linux-2.4.22-pre10/arch/ppc64/kernel/rtasd.c
--- linux-2.4.21/arch/ppc64/kernel/rtasd.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/rtasd.c	2003-08-01 13:31:07.000000000 +0000
@@ -49,6 +49,9 @@
 #define SURVEILLANCE_TIMEOUT	1
 #define SURVEILLANCE_SCANRATE	1
 
+extern struct proc_dir_entry *proc_ppc64_root;
+extern struct proc_dir_entry *rtas_proc_dir;
+extern spinlock_t proc_ppc64_lock;
 /*
  * Since we use 32 bit RTAS, the physical address of this must be below
  * 4G or else bad things happen. Allocate this in the kernel data and
@@ -821,12 +824,8 @@
 		current->cpus_allowed = 1UL << cpu_logical_map(cpu);
 
 		/* Check all cpus for pending events before sleeping*/
-		if (first_pass) {
-			schedule();
-		} else {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout((HZ*60/rtas_event_scan_rate) / 2);
-		}
+                set_current_state(TASK_INTERRUPTIBLE);
+                schedule_timeout(first_pass ? HZ : (HZ*60/rtas_event_scan_rate) / 2);
 	}
 
 error_vfree:
@@ -836,25 +835,45 @@
 	return -EINVAL;
 }
 
-static void __init rtas_init(void)
+static int __init rtas_init(void)
 {
-	struct proc_dir_entry *rtas_dir, *entry;
+	int ret = 0;
+	struct proc_dir_entry *entry;
 
-	rtas_dir = proc_mkdir("rtas", 0);
-	if (!rtas_dir) {
-		printk(KERN_ERR "Failed to create rtas proc directory\n");
+	spin_lock(&proc_ppc64_lock);
+	if (proc_ppc64_root == NULL) {
+		proc_ppc64_root = proc_mkdir("ppc64", 0);
+		if (!proc_ppc64_root) {
+			spin_unlock(&proc_ppc64_lock);
+			return -EINVAL;
+		}		
+	}
+	spin_unlock(&proc_ppc64_lock);
+	
+	if (rtas_proc_dir == NULL) {
+		rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root);
+	}
+
+	if (rtas_proc_dir == NULL) {
+		printk(KERN_ERR "Failed to create /proc/ppc64/rtas in rtas_init\n");
+		ret = -EINVAL;
 	} else {
-		entry = create_proc_entry("error_log", S_IRUSR, rtas_dir);
+		entry = create_proc_entry("error_log", S_IRUSR, rtas_proc_dir);
 		if (entry)
 			entry->proc_fops = &proc_rtas_log_operations;
-		else
+		else {
 			printk(KERN_ERR "Failed to create rtas/error_log proc entry\n");
+			ret = -EINVAL;
+		}
 	}
 
-	if (kernel_thread(rtasd, 0, CLONE_FS) < 0)
+	if (kernel_thread(rtasd, 0, CLONE_FS) < 0) { 
 		printk(KERN_ERR "Failed to start RTAS daemon\n");
+		ret = -EINVAL;
+	}
 
 	printk(KERN_ERR "RTAS daemon started\n");
+	return ret;
 }
 
 static int __init surveillance_setup(char *str)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/setup.c linux-2.4.22-pre10/arch/ppc64/kernel/setup.c
--- linux-2.4.21/arch/ppc64/kernel/setup.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/setup.c	2003-08-01 13:32:05.000000000 +0000
@@ -37,9 +37,7 @@
 #include <asm/paca.h>
 #include <asm/ppcdebug.h>
 #include <asm/time.h>
-#ifdef CONFIG_KDB
-#include <linux/kdb.h>
-#endif
+#include <asm/cputable.h>
 
 extern unsigned long klimit;
 /* extern void *stab; */
@@ -74,10 +72,6 @@
 extern void xmon_map_scc(void);
 #endif
 
-#ifdef CONFIG_KDB
-extern void kdb_map_scc(void);
-#endif
-
 char saved_command_line[256];
 unsigned char aux_device_present;
 
@@ -107,7 +101,7 @@
 };
 
 /*
- * Do some initial setup of the system.  The paramters are those which 
+ * Do some initial setup of the system.  The parameters are those which 
  * were passed in from the bootloader.
  */
 void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
@@ -187,6 +181,7 @@
 
 /* This is called just before console_init().
  * It will be obsolete when Linux gets real early console support (2.5?)
+ * We need to hack preferred_console to retain the correct behavior
  */
 void setup_before_console_init(void)
 {
@@ -244,6 +239,14 @@
 
 	pvr = paca[cpu_id].pvr;
 
+	if (cur_cpu_spec->pvr_mask)
+		seq_printf(m, "%s", cur_cpu_spec->cpu_name);
+	else
+		seq_printf(m, "unknown (%08x)", pvr);
+
+
+	seq_printf(m, "\n");
+#if 0
 	switch (PVR_VER(pvr)) {
 	case PV_NORTHSTAR:
 		seq_printf(m, "RS64-II (northstar)\n");
@@ -273,7 +276,7 @@
 		seq_printf(m, "Unknown (%08x)\n", pvr);
 		break;
 	}
-
+#endif
 	/*
 	 * Assume here that all clock rates are the same in a
 	 * smp system.  -- Cort
@@ -325,6 +328,7 @@
 void parse_cmd_line(unsigned long r3, unsigned long r4, unsigned long r5,
 		  unsigned long r6, unsigned long r7)
 {
+	struct device_node *chosen;
 	char *p;
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -333,6 +337,7 @@
 		initrd_end = initrd_start + r4;
 		ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
 		initrd_below_start_ok = 1;
+		lmb_reserve(__pa(initrd_start),r4);
 	}
 #endif
 
@@ -495,12 +500,6 @@
 		xmon(0);
 #endif /* CONFIG_XMON */
 
-#ifdef CONFIG_KDB
-	kdb_map_scc();	
-	if (strstr(cmd_line, "kdb=early"))
-		kdb(KDB_REASON_CALL,0,0);
-#endif
-
 #if defined(CONFIG_KGDB)
 	kgdb_map_scc();
 	set_debug_traps();
@@ -560,28 +559,28 @@
 void ppc64_boot_msg(unsigned int src, const char *msg)
 {
 	ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_IPL_MESSAGE|src, msg);
-	printk("[boot]%04x %s\n", src, msg);
+	udbg_printf("[boot]%04x %s\n", src, msg);
 }
 
 /* Print a termination message (print only -- does not stop the kernel) */
 void ppc64_terminate_msg(unsigned int src, const char *msg)
 {
 	ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg);
-	printk("[terminate]%04x %s\n", src, msg);
+	udbg_printf("[terminate]%04x %s\n", src, msg);
 }
 
 /* Print something that needs attention (device error, etc) */
 void ppc64_attention_msg(unsigned int src, const char *msg)
 {
 	ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_ATTN_MESSAGE|src, msg);
-	printk("[attention]%04x %s\n", src, msg);
+	udbg_printf("[attention]%04x %s\n", src, msg);
 }
 
 /* Print a dump progress message. */
 void ppc64_dump_msg(unsigned int src, const char *msg)
 {
 	ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_DUMP_MESSAGE|src, msg);
-	printk("[dump]%04x %s\n", src, msg);
+	udbg_printf("[dump]%04x %s\n", src, msg);
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/signal.c linux-2.4.22-pre10/arch/ppc64/kernel/signal.c
--- linux-2.4.21/arch/ppc64/kernel/signal.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/signal.c	2003-08-01 13:34:31.000000000 +0000
@@ -101,6 +101,7 @@
 		err |= __put_user(from->si_pid, &to->si_pid);
 		switch (from->si_code >> 16) {
 		case __SI_FAULT >> 16:
+			err |= __put_user(from->si_addr, &to->si_addr);
 			break;
 		case __SI_CHLD >> 16:
 			err |= __put_user(from->si_utime, &to->si_utime);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/stab.c linux-2.4.22-pre10/arch/ppc64/kernel/stab.c
--- linux-2.4.21/arch/ppc64/kernel/stab.c	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/stab.c	2003-08-01 13:32:39.000000000 +0000
@@ -17,6 +17,7 @@
 #include <asm/paca.h>
 #include <asm/naca.h>
 #include <asm/pmc.h>
+#include <asm/cputable.h>
 
 inline int make_ste(unsigned long stab, 
 		    unsigned long esid, unsigned long vsid);
@@ -35,10 +36,7 @@
 	esid = GET_ESID(KERNELBASE);
 	vsid = get_kernel_vsid(esid << SID_SHIFT); 
 
-	if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) {
-                __asm__ __volatile__("isync; slbia; isync":::"memory");
-		make_ste(stab, esid, vsid);
-	} else {
+	if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) {
                 /* Invalidate the entire SLB & all the ERATS */
                 __asm__ __volatile__("isync" : : : "memory");
 #ifndef CONFIG_PPC_ISERIES
@@ -49,7 +47,10 @@
 #else
                 __asm__ __volatile__("isync; slbia; isync":::"memory");
 #endif
-        }
+	} else {
+                __asm__ __volatile__("isync; slbia; isync":::"memory");
+		make_ste(stab, esid, vsid);
+	}
 }
 
 /*
@@ -61,6 +62,15 @@
 	unsigned long entry, group, old_esid, castout_entry, i;
 	unsigned int global_entry;
 	STE *ste, *castout_ste;
+	unsigned char kp = 1;
+	
+#ifdef CONFIG_SHARED_MEMORY_ADDRESSING
+	if(((esid >> SMALLOC_ESID_SHIFT) == 
+	    (SMALLOC_START >> SMALLOC_EA_SHIFT)) && 
+	   (current->thread.flags & PPC_FLAG_SHARED)) {
+		kp = 0;
+	}
+#endif
 
 	/* Search the primary group first. */
 	global_entry = (esid & 0x1f) << 3;
@@ -77,7 +87,7 @@
 				__asm__ __volatile__ ("eieio" : : : "memory");
 				ste->dw0.dw0.esid = esid;
 				ste->dw0.dw0.v  = 1;
-				ste->dw0.dw0.kp = 1;
+				ste->dw0.dw0.kp = kp;
 				/* Order update     */
 				__asm__ __volatile__ ("sync" : : : "memory"); 
 
@@ -135,7 +145,7 @@
 	old_esid = castout_ste->dw0.dw0.esid;
 	castout_ste->dw0.dw0.esid = esid;
 	castout_ste->dw0.dw0.v  = 1;
-	castout_ste->dw0.dw0.kp = 1;
+	castout_ste->dw0.dw0.kp = kp;
 	__asm__ __volatile__ ("slbie  %0" : : "r" (old_esid << SID_SHIFT)); 
 	/* Ensure completion of slbie */
 	__asm__ __volatile__ ("sync" : : : "memory" );  
@@ -158,6 +168,15 @@
 		unsigned long word0;
 		slb_dword1    data;
 	} vsid_data;
+	unsigned char kp = 1;
+ 	
+#ifdef CONFIG_SHARED_MEMORY_ADDRESSING
+	if(((esid >> SMALLOC_ESID_SHIFT) == 
+	    (SMALLOC_START >> SMALLOC_EA_SHIFT)) && 
+	   (current->thread.flags & PPC_FLAG_SHARED)) {
+		kp = 0;
+	}
+#endif
 	
 	/*
 	 * Find an empty entry, if one exists.
@@ -171,7 +190,7 @@
 			 */
 			vsid_data.word0 = 0;
 			vsid_data.data.vsid = vsid;
-			vsid_data.data.kp = 1;
+			vsid_data.data.kp = kp;
 			if (large)
 				vsid_data.data.l = 1;
 
@@ -220,7 +239,7 @@
 	 */
 	vsid_data.word0 = 0;
 	vsid_data.data.vsid = vsid;
-	vsid_data.data.kp = 1;
+	vsid_data.data.kp = kp;
 	if (large)
 		vsid_data.data.l = 1;
 	
@@ -264,6 +283,15 @@
 		}
 	}
 
+#ifdef CONFIG_SHARED_MEMORY_ADDRESSING
+	/* Shared segments might be mapped into a user task space,
+	 * so we need to add them to the list of entries to flush
+	 */
+	if ((ea >> SMALLOC_EA_SHIFT) == (SMALLOC_START >> SMALLOC_EA_SHIFT)) {
+		kernel_segment = 0;
+	}
+#endif
+
 	esid = GET_ESID(ea);
 	if (trap == 0x380 || trap == 0x480) {
 #ifndef CONFIG_PPC_ISERIES
@@ -305,7 +333,15 @@
 	unsigned char *segments = get_paca()->xSegments;
 	unsigned long flags, i;
 
-	if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) {
+	if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) {
+		unsigned long flags;
+
+		PMC_SW_PROCESSOR(stab_invalidations); 
+
+		__save_and_cli(flags);
+		__asm__ __volatile__("isync; slbia; isync":::"memory");
+		__restore_flags(flags);
+	} else {
 		unsigned long entry;
 		STE *ste;
 
@@ -330,7 +366,8 @@
 			    entry++, ste++) {
 				unsigned long ea;
 				ea = ste->dw0.dw0.esid << SID_SHIFT;
-				if (STAB_PRESSURE || (!REGION_ID(ea))) {
+				if (STAB_PRESSURE || (!REGION_ID(ea)) ||
+				    (REGION_ID(ea) == VMALLOC_REGION_ID)) {
 					ste->dw0.dw0.v = 0;
 					PMC_SW_PROCESSOR(stab_invalidations); 
 				}
@@ -347,13 +384,5 @@
 		__asm__ __volatile__ ("slbia" : : : "memory"); 
 		/* Force flush to complete.  */
 		__asm__ __volatile__ ("sync" : : : "memory");  
-	} else {
-		unsigned long flags;
-
-		PMC_SW_PROCESSOR(stab_invalidations); 
-
-		__save_and_cli(flags);
-		__asm__ __volatile__("isync; slbia; isync":::"memory");
-		__restore_flags(flags);
 	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/sys_ppc32.c linux-2.4.22-pre10/arch/ppc64/kernel/sys_ppc32.c
--- linux-2.4.21/arch/ppc64/kernel/sys_ppc32.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/sys_ppc32.c	2003-08-01 13:31:33.000000000 +0000
@@ -454,7 +454,7 @@
 	return err;
 }
 
-struct dqblk32 {
+struct user_dqblk32 {
     __u32 dqb_bhardlimit;
     __u32 dqb_bsoftlimit;
     __u32 dqb_curblocks;
@@ -473,13 +473,13 @@
  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
  * and the register representation of a signed int (msr in 64-bit mode) is performed.
  */
-asmlinkage long sys32_quotactl(u32 cmd_parm, const char *special, u32 id_parm, unsigned long addr)
+asmlinkage long sys32_quotactl(u32 cmd_parm, const char *special, u32 id_parm, caddr_t addr)
 {
-  int cmd = (int)cmd_parm;
-  int id  = (int)id_parm;
+	int cmd = (int)cmd_parm;
+	int id  = (int)id_parm;
 	int cmds = cmd >> SUBCMDSHIFT;
 	int err;
-	struct dqblk d;
+	struct v1c_mem_dqblk d;
 	mm_segment_t old_fs;
 	char *spec;
 	
@@ -487,35 +487,33 @@
 		    current->pid, current, current->comm);
 
 	switch (cmds) {
-	case Q_GETQUOTA:
+	case Q_V1_GETQUOTA:
 		break;
-	case Q_SETQUOTA:
-	case Q_SETUSE:
-	case Q_SETQLIM:
-		if (copy_from_user (&d, (struct dqblk32 *)addr,
-				    sizeof (struct dqblk32)))
+	case Q_V1_SETQUOTA:
+	case Q_V1_SETUSE:
+	case Q_V1_SETQLIM:
+		if (copy_from_user(&d, addr, sizeof(struct user_dqblk32)))
 			return -EFAULT;
-		d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
-		d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
+		d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime;
+		d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime;
 		break;
 	default:
-		return sys_quotactl(cmd, special,
-				    id, (caddr_t)addr);
+		return sys_quotactl(cmd, special, id, addr);
 	}
-	spec = getname (special);
+	spec = getname(special);
 	err = PTR_ERR(spec);
-	if (IS_ERR(spec)) return err;
-	old_fs = get_fs ();
+	if (IS_ERR(spec))
+		return err;
+	old_fs = get_fs();
 	set_fs (KERNEL_DS);
 	err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
 	set_fs (old_fs);
 	putname (spec);
-	if (cmds == Q_GETQUOTA) {
+	if (cmds == Q_V1_GETQUOTA) {
 		__kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
-		((struct dqblk32 *)&d)->dqb_itime = i;
-		((struct dqblk32 *)&d)->dqb_btime = b;
-		if (copy_to_user ((struct dqblk32 *)addr, &d,
-				  sizeof (struct dqblk32)))
+		((struct user_dqblk32 *)&d)->dqb_itime = i;
+		((struct user_dqblk32 *)&d)->dqb_btime = b;
+		if (copy_to_user(addr, &d, sizeof(struct user_dqblk32)))
 			return -EFAULT;
 	}
 	
@@ -2311,7 +2309,11 @@
         u32 totalswap;
         u32 freeswap;
         unsigned short procs;
-        char _f[22];
+        unsigned short pad;
+        u32 totalhigh;
+        u32 freehigh;
+        u32 mem_unit;
+        char _f[20-2*sizeof(u32)-sizeof(int)];
 };
 
 extern asmlinkage long sys_sysinfo(struct sysinfo *info);
@@ -2320,6 +2322,7 @@
 {
 	struct sysinfo s;
 	int ret, err;
+	int bitcount = 0;
 	mm_segment_t old_fs = get_fs ();
 	
 	PPCDBG(PPCDBG_SYS32, "sys32_sysinfo - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);
@@ -2327,6 +2330,24 @@
 	set_fs (KERNEL_DS);
 	ret = sys_sysinfo(&s);
 	set_fs (old_fs);
+	/* Check to see if any memory value is too large for 32-bit and scale
+	 *  down if needed
+	 */
+	if ((s.totalram >> 32) || (s.totalswap >> 32)) {
+		while (s.mem_unit < PAGE_SIZE) {
+			s.mem_unit <<= 1;
+			bitcount++;
+		}
+		s.totalram >>= bitcount;
+		s.freeram >>= bitcount;
+		s.sharedram >>= bitcount;
+		s.bufferram >>= bitcount;
+		s.totalswap >>= bitcount;
+		s.freeswap >>= bitcount;
+		s.totalhigh >>= bitcount;
+		s.freehigh >>= bitcount;
+	}
+	
 	err = put_user (s.uptime, &info->uptime);
 	err |= __put_user (s.loads[0], &info->loads[0]);
 	err |= __put_user (s.loads[1], &info->loads[1]);
@@ -2338,6 +2359,10 @@
 	err |= __put_user (s.totalswap, &info->totalswap);
 	err |= __put_user (s.freeswap, &info->freeswap);
 	err |= __put_user (s.procs, &info->procs);
+	err |= __put_user (s.totalhigh, &info->totalhigh);
+	err |= __put_user (s.freehigh, &info->freehigh);
+	err |= __put_user (s.mem_unit, &info->mem_unit);
+	
 	if (err)
 		return -EFAULT;
 	
@@ -3029,7 +3054,7 @@
 		err = do_sys32_shmctl(first, second, (void *)AA(ptr));
 		break;
 	default:
-		err = -EINVAL;
+		err = -ENOSYS;
 		break;
 	}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/syscalls.c linux-2.4.22-pre10/arch/ppc64/kernel/syscalls.c
--- linux-2.4.21/arch/ppc64/kernel/syscalls.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/syscalls.c	2003-08-01 13:33:45.000000000 +0000
@@ -72,7 +72,7 @@
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
-	ret = -EINVAL;
+	ret = -ENOSYS;
 	switch (call) {
 	case SEMOP:
 		ret = sys_semop (first, (struct sembuf *)ptr, second);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/time.c linux-2.4.22-pre10/arch/ppc64/kernel/time.c
--- linux-2.4.21/arch/ppc64/kernel/time.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/time.c	2003-08-01 13:32:06.000000000 +0000
@@ -415,8 +415,8 @@
 	time_esterror = NTP_PHASE_LIMIT;
 
 	delta_xsec = mulhdu( (tb_last_stamp-systemcfg->tb_orig_stamp), systemcfg->tb_to_xs );
-	new_xsec = (new_usec * XSEC_PER_SEC) / USEC_PER_SEC;
-	new_xsec += new_sec * XSEC_PER_SEC;
+	new_xsec = (tv->tv_usec * XSEC_PER_SEC) / USEC_PER_SEC;
+	new_xsec += tv->tv_sec * XSEC_PER_SEC;
 	if ( new_xsec > delta_xsec ) {
 		systemcfg->stamp_xsec = new_xsec - delta_xsec;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/traps.c linux-2.4.22-pre10/arch/ppc64/kernel/traps.c
--- linux-2.4.21/arch/ppc64/kernel/traps.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/traps.c	2003-08-01 13:32:31.000000000 +0000
@@ -42,6 +42,7 @@
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/ppcdebug.h>
+#include <asm/machdep.h> /* for ppc_attention_msg */
 
 extern int fix_alignment(struct pt_regs *);
 extern void bad_page_fault(struct pt_regs *, unsigned long);
@@ -75,14 +76,11 @@
 void (*debugger_fault_handler)(struct pt_regs *regs);
 #else
 #ifdef CONFIG_KDB
-/* kdb has different call parms */
-/* ... */
-void (*debugger)(struct pt_regs *regs) = kdb;
+void (*debugger)(struct pt_regs *regs);
 int (*debugger_bpt)(struct pt_regs *regs);
 int (*debugger_sstep)(struct pt_regs *regs);
 int (*debugger_iabr_match)(struct pt_regs *regs);
-int (*debugger_dabr_match)(struct pt_regs *regs) = kdb;
-/* - only defined during (xmon) mread */
+int (*debugger_dabr_match)(struct pt_regs *regs);
 void (*debugger_fault_handler)(struct pt_regs *regs);
 #endif /* kdb */
 #endif /* kgdb */
@@ -100,13 +98,9 @@
 	if (!user_mode(regs))
 	{
 		show_regs(regs);
-#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
 		debugger(regs);
 #endif
-#if defined(CONFIG_KDB)
-		if (kdb(KDB_REASON_BREAK, 0, (kdb_eframe_t) regs))
-		    return;
-#endif
 		print_backtrace((unsigned long *)regs->gpr[1]);
 		panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
 #if defined(CONFIG_PPCDBG) && (defined(CONFIG_XMON) || defined(CONFIG_KGDB))
@@ -164,30 +158,11 @@
 	}
 #if defined(CONFIG_XMON)
 	xmon(regs);
-	udbg_printf("leaving xmon...\n");
+	if (smp_processor_id() == 0)
+		udbg_printf("leaving xmon...\n");
 #endif
 #if defined(CONFIG_KDB)
-	{
-		int cpu = smp_processor_id();
-		static int reset_cpu = -1;
-		static spinlock_t reset_lock = SPIN_LOCK_UNLOCKED;
-
-		/* Give kdb some help serializing the reset */
-		spin_lock(&reset_lock);
-		if (reset_cpu == -1) {
-			reset_cpu = cpu;
-			spin_unlock(&reset_lock);
-			kdb(KDB_REASON_ENTER, regs->trap, (kdb_eframe_t) regs);
-			reset_cpu = -1;
-		} else {
-			spin_unlock(&reset_lock);
-			/* Let kdb catch this cpu with an IPI.
-			 * Ideally we need a way to enter kdb w/o it becoming
-			 * confused so we can precisely capture reset state.
-			 */
-			return;
-		}
-	}
+	kdb_reset_debugger(regs);
 #endif
 }
 
@@ -195,7 +170,6 @@
 void
 MachineCheckException(struct pt_regs *regs)
 {
-	siginfo_t info;
 
 	if (fwnmi_active) {
 		struct rtas_error_log *errhdr = FWNMI_get_errinfo(regs);
@@ -205,54 +179,31 @@
 		FWNMI_release_errinfo();
 	}
 
-	if ( !user_mode(regs) ) {
-#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
-		if (debugger_fault_handler) {
-			debugger_fault_handler(regs);
-			return;
-		}
-#endif
-		printk("Machine check in kernel mode.\n");
-		printk("Caused by (from SRR1=%lx): ", regs->msr);
-		show_regs(regs);
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
-		debugger(regs);
+	if (debugger_fault_handler) {
+		debugger_fault_handler(regs);
+		return;
+	}
 #endif
-#ifdef CONFIG_KDB
-		if (kdb(KDB_REASON_FAULT, 0, regs))
-			return ;
+	printk(KERN_EMERG "Unrecoverable Machine check.\n");
+	printk(KERN_EMERG "Caused by (from SRR1=%lx): ", regs->msr);
+	show_regs(regs);
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
+	debugger(regs);
 #endif
-		print_backtrace((unsigned long *)regs->gpr[1]);
-		panic("machine check");
-	}
-	
-	/*
-	 * XXX we should check RI bit on exception exit and kill the
-	 * task if it was cleared
-	 */
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_ADRERR;
-	info.si_addr = (void *)regs->nip;
-	_exception(SIGSEGV, &info, regs);
-
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	panic("machine check");
 }
 
 void
 SMIException(struct pt_regs *regs)
 {
-#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
 	{
 		debugger(regs);
 		return;
 	}
 #endif
-#ifdef CONFIG_KDB
-	{
-		kdb(KDB_REASON_OOPS, 0, regs);
-		return;
-	}
-#endif
 	show_regs(regs);
 	print_backtrace((unsigned long *)regs->gpr[1]);
 	panic("System Management Interrupt");
@@ -278,15 +229,10 @@
 {
 	siginfo_t info;
 	
-#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined (CONFIG_KDB)
 	if (debugger_iabr_match(regs))
 		return;
 #endif
-#ifdef CONFIG_KDB
-	if (kdb(KDB_REASON_BREAK, 0, regs))
-		return;
-#endif
-
 	info.si_signo = SIGTRAP;
 	info.si_errno = 0;
 	info.si_code = TRAP_BRKPT;
@@ -353,14 +299,10 @@
 	} else if (regs->msr & 0x20000) {
 		/* trap exception */
 
-#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
 		if (debugger_bpt(regs))
 			return;
 #endif
-#ifdef CONFIG_KDB
-		if (kdb(KDB_REASON_BREAK, 0, regs))
-			return;
-#endif
 		info.si_signo = SIGTRAP;
 		info.si_errno = 0;
 		info.si_code = TRAP_BRKPT;
@@ -377,6 +319,14 @@
 	}
 }
 
+ void
+KernelFPUnavailableException(struct pt_regs *regs)
+{
+	printk("Illegal floating point used in kernel (task=0x%016lx, pc=0x%016lx, trap=0x%08x)\n",
+		current, regs->nip, regs->trap);
+	panic("Unrecoverable FP Unavailable Exception in Kernel");
+}
+
 void
 SingleStepException(struct pt_regs *regs)
 {
@@ -384,15 +334,10 @@
 
 	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
 
-#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
 	if (debugger_sstep(regs))
 		return;
 #endif
-#ifdef CONFIG_KDB
-	if (kdb(KDB_REASON_DEBUG, 0, regs))
-		return;
-#endif
-
 	info.si_signo = SIGTRAP;
 	info.si_errno = 0;
 	info.si_code = TRAP_TRACE;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/kernel/xics.c linux-2.4.22-pre10/arch/ppc64/kernel/xics.c
--- linux-2.4.21/arch/ppc64/kernel/xics.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/kernel/xics.c	2003-08-01 13:32:06.000000000 +0000
@@ -143,18 +143,22 @@
 	u_int		irq;
 	unsigned long	status;
 	long	        call_status;
+	unsigned int    interrupt_server = default_server;
 
 	virq -= XICS_IRQ_OFFSET;
 	irq = virt_irq_to_real(virq);
 	if (irq == XICS_IPI)
 		return;
+
 #ifdef CONFIG_IRQ_ALL_CPUS
-	call_status = rtas_call(ibm_set_xive, 3, 1, (unsigned long*)&status,
-				irq, smp_threads_ready ? default_distrib_server : default_server, DEFAULT_PRIORITY);
-#else
-	call_status = rtas_call(ibm_set_xive, 3, 1, (unsigned long*)&status,
-				irq, default_server, DEFAULT_PRIORITY);
+	if((smp_num_cpus == systemcfg->processorCount) &&
+	   (smp_threads_ready)) {
+		interrupt_server = default_distrib_server;
+	}
 #endif
+	call_status = rtas_call(ibm_set_xive, 3, 1, (unsigned long*)&status,
+				irq, interrupt_server, DEFAULT_PRIORITY);
+
 	if( call_status != 0 ) {
 		printk("xics_enable_irq: irq=%x: rtas_call failed; retn=%lx, status=%lx\n",
 		       irq, call_status, status);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/lib/copyuser.S linux-2.4.22-pre10/arch/ppc64/lib/copyuser.S
--- linux-2.4.21/arch/ppc64/lib/copyuser.S	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/lib/copyuser.S	2003-08-01 13:33:11.000000000 +0000
@@ -130,7 +130,7 @@
 6:	cmpwi	cr1,r5,8
 	addi	r3,r3,32
 	sld	r9,r9,r10
-	blt	cr1,.Ldo_tail
+	ble	cr1,.Ldo_tail
 34:	ld	r0,8(r4)
 	srd	r7,r0,r11
 	or	r9,r7,r9
@@ -483,8 +483,20 @@
  * on an exception, reset to the beginning and jump back into the
  * standard __copy_tofrom_user
  */
-100:	ld	r3,-24(r1)
-	ld	r4,-24(r1)
+100:	ld	r20,-120(1)
+	ld	r21,-112(1)
+	ld	r22,-104(1)
+	ld	r23,-96(1)
+	ld	r24,-88(1)
+	ld	r25,-80(1)
+	ld	r26,-72(1)
+	ld	r27,-64(1)
+	ld	r28,-56(1)
+	ld	r29,-48(1)
+	ld	r30,-40(1)
+	ld	r31,-32(1)
+	ld	r3,-24(r1)
+	ld	r4,-16(r1)
 	li	r5,4096
 	b	.Ldst_aligned
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/mm/fault.c linux-2.4.22-pre10/arch/ppc64/mm/fault.c
--- linux-2.4.21/arch/ppc64/mm/fault.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/mm/fault.c	2003-08-01 13:32:48.000000000 +0000
@@ -65,7 +65,7 @@
 void do_page_fault(struct pt_regs *regs, unsigned long address,
 		   unsigned long error_code)
 {
-	struct vm_area_struct * vma;
+	struct vm_area_struct * vma, * prev_vma;
 	struct mm_struct *mm = current->mm;
 	siginfo_t info;
 	unsigned long code = SEGV_MAPERR;
@@ -90,8 +90,8 @@
 	}
 #endif /* CONFIG_XMON || CONFIG_KGDB */
 
-	/* On an SLB miss we can only check for a valid exception entry */
-	if (regs->trap == 0x380) {
+	/* On a kernel SLB miss we can only check for a valid exception entry */
+	if (!user_mode(regs) && (regs->trap == 0x380)) {
 		bad_page_fault(regs, address);
 		return;
 	}
@@ -99,13 +99,8 @@
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
 	if (error_code & 0x00400000) {
 		/* DABR match */
-#if defined(CONFIG_KDB)
-	    if (kdb(KDB_REASON_BREAK,regs->trap,regs))
-			return;
-#else
 		if (debugger_dabr_match(regs))
 			return;
-#endif
 	}
 #endif /* CONFIG_XMON || CONFIG_KGDB || CONFIG_KDB */
 
@@ -128,6 +123,7 @@
 		PPCDBG(PPCDBG_MM, "\tdo_page_fault: vma->vm_flags = %lx, %lx\n", vma->vm_flags, VM_GROWSDOWN);
 		goto bad_area;
 	}
+	vma = find_vma_prev(mm, address, &prev_vma);
 	if (expand_stack(vma, address)) {
 		PPCDBG(PPCDBG_MM, "\tdo_page_fault: expand_stack\n");
 		goto bad_area;
@@ -243,13 +239,10 @@
 
 	/* kernel has accessed a bad area */
 	show_regs(regs);
-#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB) || defined(CONFIG_KDB)
 	if (debugger_kernel_faults)
 		debugger(regs);
 #endif
-#if defined(CONFIG_KDB)
-	kdb(KDB_REASON_FAULT, regs->trap, regs);
-#endif	
 	print_backtrace( (unsigned long *)regs->gpr[1] );
 	panic("kernel access of bad area pc %lx lr %lx address %lX tsk %s/%d",
 	      regs->nip,regs->link,address,current->comm,current->pid);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/mm/init.c linux-2.4.22-pre10/arch/ppc64/mm/init.c
--- linux-2.4.21/arch/ppc64/mm/init.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/mm/init.c	2003-08-01 13:31:44.000000000 +0000
@@ -279,7 +279,11 @@
 	/* Implemented to just flush the vmalloc area.
 	 * vmalloc is the only user of flush_tlb_all.
 	 */
+#ifdef CONFIG_SHARED_MEMORY_ADDRESSING
+	local_flush_tlb_range( NULL, VMALLOC_START, SMALLOC_END );
+#else
 	local_flush_tlb_range( NULL, VMALLOC_START, VMALLOC_END );
+#endif
 }
 
 void
@@ -292,11 +296,6 @@
 		for ( mp = mm->mmap; mp != NULL; mp = mp->vm_next )
 			local_flush_tlb_range( mm, mp->vm_start, mp->vm_end );
 	}
-	else	/* MIKEC: It is not clear why this is needed */
-		/* paulus: it is needed to clear out stale HPTEs
-		 * when an address space (represented by an mm_struct)
-		 * is being destroyed. */
-		local_flush_tlb_range( mm, USER_START, USER_END );
 
 	spin_unlock(&mm->page_table_lock);
 }
@@ -644,3 +643,131 @@
 	maddr = (unsigned long)page_address(page) + (addr & ~PAGE_MASK);
 	flush_icache_range(maddr, maddr + len);
 }
+
+#ifdef CONFIG_SHARED_MEMORY_ADDRESSING
+static spinlock_t shared_malloc_lock = SPIN_LOCK_UNLOCKED;
+struct vm_struct *shared_list = NULL;
+static struct vm_struct *get_shared_area(unsigned long size, 
+					 unsigned long flags);
+
+void *shared_malloc(unsigned long size) {
+	pgprot_t prot;
+	struct vm_struct *area;
+	unsigned long ea;
+
+	spin_lock(&shared_malloc_lock);
+
+	printk("shared_malloc1 (no _PAGE_USER): addr = 0x%lx, size = 0x%lx\n", 
+	       SMALLOC_START, size); 
+
+	area = get_shared_area(size, 0);
+	if (!area) {
+	spin_unlock(&shared_malloc_lock);
+		return NULL;
+	}
+
+	ea = (unsigned long) area->addr;
+
+	prot = __pgprot(pgprot_val(PAGE_KERNEL));
+	if (vmalloc_area_pages(VMALLOC_VMADDR(ea), size, GFP_KERNEL, prot)) { 
+	spin_unlock(&shared_malloc_lock);
+		return NULL;
+	} 
+
+	printk("shared_malloc: addr = 0x%lx, size = 0x%lx\n", ea, size); 
+
+	spin_unlock(&shared_malloc_lock);
+	return(ea); 
+}
+
+void shared_free(void *addr) {
+	struct vm_struct **p, *tmp;
+	unsigned long size = 0;
+
+	if (!addr)
+		return;
+	if ((PAGE_SIZE-1) & (unsigned long) addr) {
+		printk(KERN_ERR "Trying to shared_free() bad address (%p)\n", 
+		       addr);
+		return;
+	}
+	spin_lock(&shared_malloc_lock);
+
+	printk("shared_free: addr = 0x%lx\n", addr); 
+
+	/* Scan the memory list for an entry matching
+	 * the address to be freed, get the size (in bytes)
+	 * and free the entry.  The list lock is not dropped
+	 * until the page table entries are removed.
+	 */
+	for(p = &shared_list; (tmp = *p); p = &tmp->next ) {
+		if (tmp->addr == addr) {
+			*p = tmp->next;
+			vmfree_area_pages(VMALLOC_VMADDR(tmp->addr),tmp->size);
+			spin_unlock(&shared_malloc_lock);
+			kfree(tmp);
+			return;
+		}
+	}
+
+	spin_unlock(&shared_malloc_lock);
+	printk("shared_free: error\n"); 
+}
+
+static struct vm_struct *get_shared_area(unsigned long size, 
+					 unsigned long flags) {
+	unsigned long addr;
+	struct vm_struct **p, *tmp, *area;
+  
+	area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
+	if (!area) return NULL;
+
+	size += PAGE_SIZE;
+	if (!size) {
+		kfree (area);
+		return NULL;
+	}
+
+	addr = SMALLOC_START;
+	for (p = &shared_list; (tmp = *p) ; p = &tmp->next) {
+		if ((size + addr) < addr) {
+			kfree(area);
+			return NULL;
+		}
+		if (size + addr <= (unsigned long) tmp->addr)
+			break;
+		addr = tmp->size + (unsigned long) tmp->addr;
+		if (addr > SMALLOC_END-size) {
+			kfree(area);
+			return NULL;
+		}
+	}
+
+	if (addr + size > SMALLOC_END) {
+		kfree(area);
+		return NULL;
+	}
+	area->flags = flags;
+	area->addr = (void *)addr;
+	area->size = size;
+	area->next = *p;
+	*p = area;
+	return area;
+}
+
+int shared_task_mark() {
+	current->thread.flags |= PPC_FLAG_SHARED;
+	printk("current->thread.flags = 0x%lx\n", current->thread.flags);
+
+	return 0;
+}
+
+int shared_task_unmark() {
+	if(current->thread.flags & PPC_FLAG_SHARED) {
+		current->thread.flags &= (~PPC_FLAG_SHARED);
+		return 0;
+	} else {
+		return -1;
+	}
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/vmlinux.lds linux-2.4.22-pre10/arch/ppc64/vmlinux.lds
--- linux-2.4.21/arch/ppc64/vmlinux.lds	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/vmlinux.lds	2003-08-01 13:30:53.000000000 +0000
@@ -73,6 +73,9 @@
   __kallsyms : { *(__kallsyms) }
   __stop___kallsyms = .;
 
+  __start___ftr_fixup = .;
+  __ftr_fixup : { *(__ftr_fixup) }
+  __stop___ftr_fixup = .;
 
   . = ALIGN(4096);
   .data.page_aligned : { *(.data.page_aligned) }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/ppc64/xmon/xmon.c linux-2.4.22-pre10/arch/ppc64/xmon/xmon.c
--- linux-2.4.21/arch/ppc64/xmon/xmon.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/ppc64/xmon/xmon.c	2003-08-01 13:32:06.000000000 +0000
@@ -26,6 +26,7 @@
 #include <asm/naca.h>
 #include <asm/paca.h>
 #include <asm/ppcdebug.h>
+#include <asm/cputable.h>
 #include "nonstdio.h"
 #include "privinst.h"
 
@@ -33,9 +34,11 @@
 #define skipbl	xmon_skipbl
 
 #ifdef CONFIG_SMP
-static unsigned long cpus_in_xmon = 0;
-static unsigned long got_xmon = 0;
+static volatile unsigned long cpus_in_xmon = 0;
+static volatile unsigned long got_xmon = 0;
 static volatile int take_xmon = -1;
+static volatile int leaving_xmon = 0;
+
 #endif /* CONFIG_SMP */
 
 static unsigned long adrs;
@@ -190,7 +193,7 @@
 	asm volatile("sync; isync");
 }
 
-/* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
+/* (Ref: 64-bit PowerPC ELF ABI Supplement; Ian Lance Taylor, Zembu Labs).
  A PPC stack frame looks like this:
 
  High Address
@@ -250,12 +253,12 @@
 xmon(struct pt_regs *excp)
 {
 	struct pt_regs regs;
-	int cmd;
+	int cmd = 0;
 	unsigned long msr;
 
 	if (excp == NULL) {
 		/* Ok, grab regs as they are now.
-		 This won't do a particularily good job because the
+		 This won't do a particularly good job because the
 		 prologue has already been executed.
 		 ToDo: We could reach back into the callers save
 		 area to do a better job of representing the
@@ -309,9 +312,15 @@
 	xmon_regs[smp_processor_id()] = excp;
 	excprint(excp);
 #ifdef CONFIG_SMP
-	if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon))
+	/* possible race condition here if a CPU is held up and gets
+	 * here while we are exiting */
+	leaving_xmon = 0;
+	if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon)) {
+		/* xmon probably caused an exception itself */
+		printf("We are already in xmon\n");
 		for (;;)
 			;
+	}
 	while (test_and_set_bit(0, &got_xmon)) {
 		if (take_xmon == smp_processor_id()) {
 			take_xmon = -1;
@@ -327,6 +336,9 @@
 	if (cmd == 's') {
 		xmon_trace[smp_processor_id()] = SSTEP;
 		excp->msr |= MSR_SE;
+#ifdef CONFIG_SMP		
+		take_xmon = smp_processor_id();
+#endif		
 	} else if (at_breakpoint(excp->nip)) {
 		xmon_trace[smp_processor_id()] = BRSTEP;
 		excp->msr |= MSR_SE;
@@ -336,7 +348,9 @@
 	}
 	xmon_regs[smp_processor_id()] = 0;
 #ifdef CONFIG_SMP
-	clear_bit(0, &got_xmon);
+	leaving_xmon = 1;
+	if (cmd != 's')
+		clear_bit(0, &got_xmon);
 	clear_bit(smp_processor_id(), &cpus_in_xmon);
 #endif /* CONFIG_SMP */
 	set_msrd(msr);		/* restore interrupt enable */
@@ -442,7 +456,7 @@
 	int i;
 	struct bpt *bp;
 
-	if (systemcfg->platform != PLATFORM_PSERIES)
+	if (!(systemcfg->platform & PLATFORM_PSERIES))
 		return;
 	bp = bpts;
 	for (i = 0; i < NBPTS; ++i, ++bp) {
@@ -458,7 +472,7 @@
 		}
 	}
 
-	if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) {
+	if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) {
 		if (dabr.enabled)
 			set_dabr(dabr.address);
 		if (iabr.enabled)
@@ -473,11 +487,13 @@
 	struct bpt *bp;
 	unsigned instr;
 
-	if (systemcfg->platform != PLATFORM_PSERIES)
+	if (!(systemcfg->platform & PLATFORM_PSERIES))
 		return;
-	if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) {
-		set_dabr(0);
-		set_iabr(0);
+	if (!(cur_cpu_spec->cpu_features & CPU_FTR_SLB)) {
+		if (dabr.enabled)
+			set_dabr(0);
+		if (iabr.enabled)
+			set_iabr(0);
 	}
 
 	bp = bpts;
@@ -500,11 +516,15 @@
 static int
 cmds(struct pt_regs *excp)
 {
-	int cmd;
+	int cmd = 0;
 
 	last_cmd = NULL;
 	for(;;) {
 #ifdef CONFIG_SMP
+		/* Need to check if we should take any commands on
+		   this CPU. */
+		if (leaving_xmon)
+			return cmd;
 		printf("%d:", smp_processor_id());
 #endif /* CONFIG_SMP */
 		printf("mon> ");
@@ -767,10 +787,11 @@
 	cmd = inchar();
 	switch (cmd) {
 	case 'd':	/* bd - hardware data breakpoint */
-		if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) {
+		if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) {
 			printf("Not implemented on POWER4\n");
 			break;
 		}
+			
 		mode = 7;
 		cmd = inchar();
 		if (cmd == 'r')
@@ -787,7 +808,7 @@
 			dabr.address = (dabr.address & ~7) | mode;
 		break;
 	case 'i':	/* bi - hardware instr breakpoint */
-		if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) {
+		if (cur_cpu_spec->cpu_features & CPU_FTR_SLB) {
 			printf("Not implemented on POWER4\n");
 			break;
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390/config.in linux-2.4.22-pre10/arch/s390/config.in
--- linux-2.4.21/arch/s390/config.in	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390/config.in	2003-08-01 13:34:18.000000000 +0000
@@ -39,6 +39,10 @@
 bool 'Fast IRQ handling' CONFIG_FAST_IRQ
 bool 'Process warning machine checks' CONFIG_MACHCHK_WARNING
 bool 'Use chscs for Common I/O' CONFIG_CHSC
+tristate 'QDIO support' CONFIG_QDIO
+if [ "$CONFIG_QDIO" != "n" ]; then
+  bool '   Performance statistics in /proc' CONFIG_QDIO_PERF_STATS
+fi
 bool 'Builtin IPL record support' CONFIG_IPL
 if [ "$CONFIG_IPL" = "y" ]; then
   choice 'IPL method generated into head.S' \
@@ -75,4 +79,5 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390/defconfig linux-2.4.22-pre10/arch/s390/defconfig
--- linux-2.4.21/arch/s390/defconfig	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390/defconfig	2003-08-01 13:34:25.000000000 +0000
@@ -35,8 +35,8 @@
 CONFIG_MACHCHK_WARNING=y
 CONFIG_CHSC=y
 CONFIG_IPL=y
-# CONFIG_IPL_TAPE is not set
-CONFIG_IPL_VM=y
+CONFIG_IPL_TAPE=y
+# CONFIG_IPL_VM is not set
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
@@ -64,7 +64,7 @@
 CONFIG_DASD=y
 CONFIG_DASD_ECKD=y
 CONFIG_DASD_FBA=y
-# CONFIG_DASD_DIAG is not set
+CONFIG_DASD_DIAG=y
 
 #
 # Multi-device support (RAID and LVM)
@@ -118,7 +118,7 @@
 # CONFIG_TUN is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_TR=y
-# CONFIG_FDDI is not set
+CONFIG_FDDI=y
 
 #
 # S/390 network device drivers
@@ -134,20 +134,98 @@
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 # CONFIG_NETLINK_DEV is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_FILTER is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_FILTER=y
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 # CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_NET_IPGRE_BROADCAST is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
 # CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+# CONFIG_IP_NF_AMANDA is not set
+# CONFIG_IP_NF_TFTP is not set
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_MAC=m
+# CONFIG_IP_NF_MATCH_PKTTYPE is not set
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_DSCP is not set
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+# CONFIG_IP_NF_MATCH_HELPER is not set
+CONFIG_IP_NF_MATCH_STATE=m
+# CONFIG_IP_NF_MATCH_CONNTRACK is not set
+# CONFIG_IP_NF_MATCH_UNCLEAN is not set
+# CONFIG_IP_NF_MATCH_OWNER is not set
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+# CONFIG_IP_NF_TARGET_MIRROR is not set
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_NAT_LOCAL=y
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+# CONFIG_IP_NF_TARGET_ECN is not set
+# CONFIG_IP_NF_TARGET_DSCP is not set
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 CONFIG_IPV6=m
+
+#
+#   IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+# CONFIG_IP6_NF_MATCH_RT is not set
+# CONFIG_IP6_NF_MATCH_OPTS is not set
+# CONFIG_IP6_NF_MATCH_FRAG is not set
+# CONFIG_IP6_NF_MATCH_HL is not set
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
+# CONFIG_IP6_NF_MATCH_AHESP is not set
+# CONFIG_IP6_NF_MATCH_LENGTH is not set
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
 CONFIG_SHARED_IPV6_CARDS=y
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
@@ -158,6 +236,11 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -166,7 +249,7 @@
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
+CONFIG_NET_FASTROUTE=y
 # CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
@@ -175,6 +258,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -187,33 +275,38 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
 # CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=m
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
@@ -230,12 +323,14 @@
 # CONFIG_CODA_FS is not set
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
-# CONFIG_NFSD_V3 is not set
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
@@ -247,27 +342,80 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
 #
 CONFIG_PARTITION_ADVANCED=y
 # CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
 CONFIG_IBM_PARTITION=y
-# CONFIG_MAC_PARTITION is not set
-# CONFIG_MSDOS_PARTITION is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_LDM_DEBUG=y
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_EFI_PARTITION=y
 # CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 
 #
 # Kernel hacking
 #
 CONFIG_MAGIC_SYSRQ=y
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390/kernel/debug.c linux-2.4.22-pre10/arch/s390/kernel/debug.c
--- linux-2.4.21/arch/s390/kernel/debug.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390/kernel/debug.c	2003-08-01 13:31:14.000000000 +0000
@@ -949,9 +949,21 @@
 	int i;
 	unsigned long flags;
 	mode_t mode = S_IFREG;
+	struct proc_dir_entry *pde;
+
 
 	if (!id)
 		goto out;
+	pde = debug_create_proc_dir_entry(id->proc_root_entry,
+					  view->name, mode,
+					  &debug_inode_ops,
+					  &debug_file_ops);
+	if(!pde){
+		printk(KERN_WARNING "debug: create_proc_entry() failed! Cannot register view %s/%s\n", id->name,view->name);
+		rc = -1;
+		goto out;
+	}
+
 	spin_lock_irqsave(&id->lock, flags);
 	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
 		if (id->views[i] == NULL)
@@ -962,6 +974,8 @@
 			id->name,view->name);
 		printk(KERN_WARNING 
 			"debug: maximum number of views reached (%i)!\n", i);
+		debug_delete_proc_dir_entry(id->proc_root_entry, pde);
+		
 		rc = -1;
 	}
 	else {
@@ -970,11 +984,7 @@
 			mode |= S_IRUSR;
 		if (view->input_proc)
 			mode |= S_IWUSR;
-		id->proc_entries[i] =
-		    debug_create_proc_dir_entry(id->proc_root_entry,
-						view->name, mode,
-						&debug_inode_ops,
-						&debug_file_ops);
+		id->proc_entries[i] = pde;
 		rc = 0;
 	}
 	spin_unlock_irqrestore(&id->lock, flags);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390/kernel/head.S linux-2.4.22-pre10/arch/s390/kernel/head.S
--- linux-2.4.21/arch/s390/kernel/head.S	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390/kernel/head.S	2003-08-01 13:32:01.000000000 +0000
@@ -587,7 +587,7 @@
         .long  .Lduct                   # cr2: dispatchable unit control table
         .long  0                        # cr3: instruction authorization
         .long  0                        # cr4: instruction authorization
-        .long  0                        # cr5:  various things
+        .long  0xffffffff               # cr5: primary-aste origin
         .long  0                        # cr6:  I/O interrupts
         .long  0                        # cr7:  secondary space segment table
         .long  0                        # cr8:  access registers translation
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390/kernel/s390_ksyms.c linux-2.4.22-pre10/arch/s390/kernel/s390_ksyms.c
--- linux-2.4.21/arch/s390/kernel/s390_ksyms.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390/kernel/s390_ksyms.c	2003-08-01 13:30:57.000000000 +0000
@@ -60,5 +60,8 @@
 EXPORT_SYMBOL(csum_fold);
 EXPORT_SYMBOL(console_mode);
 EXPORT_SYMBOL(console_device);
-EXPORT_SYMBOL(pfix_table);
+EXPORT_SYMBOL(pfix_get_addr);
+EXPORT_SYMBOL(pfix_get_page_addr);
+EXPORT_SYMBOL(get_storage_key);
 EXPORT_SYMBOL_NOVERS(do_call_softirq);
+EXPORT_SYMBOL(sys_wait4);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390/kernel/setup.c linux-2.4.22-pre10/arch/s390/kernel/setup.c
--- linux-2.4.21/arch/s390/kernel/setup.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390/kernel/setup.c	2003-08-01 13:31:05.000000000 +0000
@@ -56,7 +56,117 @@
 unsigned long cpu_initialized = 0;
 volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
 
-void* *pfix_table=NULL;
+unsigned long *pfix_table;
+unsigned int __global_storage_key;
+
+unsigned int get_storage_key(void) { return __global_storage_key; }
+
+unsigned long pfix_get_page_addr(void *addr)
+{
+	if (!MACHINE_HAS_PFIX)
+		return (unsigned long) addr;
+
+	return pfix_table[(unsigned long)virt_to_phys(addr)>>PAGE_SHIFT];
+}
+
+unsigned long pfix_get_addr(void *addr)
+{
+	if (!MACHINE_HAS_PFIX)
+		return (unsigned long) addr;
+
+	return pfix_get_page_addr(addr) + ((unsigned long)addr&(PAGE_SIZE-1));
+}
+
+/*
+ * These functions allow to lock and unlock pages in VM. They need
+ * the absolute address of the page to be locked or unlocked. This will
+ * only work if the diag98 option in the user directory is enabled for
+ * the guest.
+ */
+
+/* if result is 0, addr will become the host absolute address */
+static inline int pfix_lock_page(void *addr)
+{
+        int ret;
+
+        __asm__ __volatile__(
+		"   sske  %1,%2\n"    /* set storage key */
+                "   l     0,0(%1)\n"  /* addr into gpr 0 */
+                "   lhi   2,0\n"      /* function code is 0 */
+                "   diag  2,0,0x98\n" /* result in gpr 1 */
+                "   jnz   0f\n"
+		"   lhi   %0,0\n"     /* if cc=0: return 0 */
+	    	"   st    1,0(%1)\n"  /* gpr1 contains host absol. addr */
+		"   j     1f\n"
+		"0: lr    %0,1\n"     /* gpr1 contains error code */
+		"   sske  %1,2\n"     /* reset storage key */
+		"1:\n"
+                : "=d" (ret), "+d" ((unsigned long)addr) : "d" (__global_storage_key) 
+                : "0", "1", "2", "cc" );
+        return ret;
+}
+
+static inline void pfix_unlock_page(unsigned long addr)
+{
+        __asm__ __volatile__(
+                "   lr    0,%0\n"  /* parameter in gpr 0 */
+                "   lhi   2,4\n"   /* function code is 4 */
+                "   diag  2,0,0x98\n" /* result in gpr 1 */
+		"   sske  %0,%1\n"
+                : : "a" (addr), "d" (0)
+                : "0", "1", "2", "cc" );
+}
+
+static void unpfix_all_pages(void)
+{
+        unsigned long i;
+
+	if (!pfix_table)
+		return;
+
+	for (i=0; i<sizeof(pfix_table); i++) {
+		if (pfix_table[i]) {
+			pfix_unlock_page(i << PAGE_SHIFT);
+		}
+	}
+}
+
+static void pfix_all_pages(unsigned long start_pfn, unsigned long max_pfn)
+{
+        unsigned long i,r;
+	unsigned long size;
+
+	size = ((max_pfn - start_pfn) >> PAGE_SHIFT) * sizeof(long);
+	pfix_table = alloc_bootmem(size);
+	if (!pfix_table)
+		return;
+
+	__global_storage_key = 6 << 4;
+	for (i = 0; i < 16 && memory_chunk[i].size > 0; i++) {
+		unsigned long start;
+
+		for(start = memory_chunk[i].addr; 
+		    (start < memory_chunk[i].addr + memory_chunk[i].size &&
+		     start < max_pfn); start += PAGE_SIZE) {
+			unsigned long index;
+
+			index = start >> PAGE_SHIFT;
+			pfix_table[index] = start;
+			r = pfix_lock_page(&pfix_table[index]);
+			if (r) {
+				pfix_table[index] = 0;
+				unpfix_all_pages();
+				free_bootmem((unsigned long)pfix_table, size);
+				machine_flags &= ~128; /* MACHINE_HAS_PFIX=0 */
+				__global_storage_key = 0;
+				printk(KERN_WARNING "Error enabling PFIX at "
+				       "address 0x%08lx.\n", start);
+				return;
+			}
+		}
+        }
+	printk (KERN_INFO "PFIX enabled.\n");
+}
 
 /*
  * Setup options
@@ -303,11 +413,12 @@
         unsigned long memory_start, memory_end;
         char c = ' ', cn, *to = command_line, *from = COMMAND_LINE;
 	struct resource *res;
-	unsigned long start_pfn, end_pfn;
+	unsigned long start_pfn, end_pfn, max_pfn=0;
         static unsigned int smptrap=0;
         unsigned long delay = 0;
 	struct _lowcore *lowcore;
 	int i;
+	static int use_pfix;
 
         if (smptrap)
                 return;
@@ -380,6 +491,14 @@
 			/* now wait for the requested amount of time */
 			udelay(delay);
                 }
+		/*
+		 * "use_pfix" specifies whether we want to fix all pages,
+		 * if possible.
+		 */
+		if (c == ' ' && strncmp(from, "use_pfix", 8) == 0) {
+			use_pfix = 1;
+			from += 8;
+		}
                 cn = *(from++);
                 if (!cn)
                         break;
@@ -394,6 +513,10 @@
                         break;
                 *(to++) = c;
         }
+
+	if (!use_pfix)
+		machine_flags &= ~128; /* MACHINE_HAS_PFIX = 0 */
+
         if (c == ' ' && to > command_line) to--;
         *to = '\0';
         *cmdline_p = command_line;
@@ -429,6 +552,8 @@
 		if (start_chunk < end_chunk)
 			free_bootmem(start_chunk << PAGE_SHIFT,
 				     (end_chunk - start_chunk) << PAGE_SHIFT);
+		if (start_chunk + memory_chunk[i].size > max_pfn)
+			max_pfn = start_chunk + memory_chunk[i].size;
 	}
 
         /*
@@ -487,6 +612,10 @@
 	 */
         paging_init();
 
+	if (MACHINE_HAS_PFIX)
+		/* max_pfn may be smaller than memory_end. */
+		pfix_all_pages(start_pfn, max_pfn);
+
 	res = alloc_bootmem_low(sizeof(struct resource));
 	res->start = 0;
 	res->end = memory_end;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390/mm/init.c linux-2.4.22-pre10/arch/s390/mm/init.c
--- linux-2.4.21/arch/s390/mm/init.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390/mm/init.c	2003-08-01 13:31:44.000000000 +0000
@@ -154,11 +154,6 @@
                         if (address >= end_mem)
                                 pte_clear(&pte);
                         set_pte(pg_table, pte);
-			if (address < memory_size) /* do not set storage
-						      key outside the storage
-						      or die */
-				set_access_key(pte); /* switch to our
-							access key */
                         address += PAGE_SIZE;
                 }
         }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/config.in linux-2.4.22-pre10/arch/s390x/config.in
--- linux-2.4.21/arch/s390x/config.in	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/config.in	2003-08-01 13:31:07.000000000 +0000
@@ -42,6 +42,10 @@
 bool 'Fast IRQ handling' CONFIG_FAST_IRQ
 bool 'Process warning machine checks' CONFIG_MACHCHK_WARNING
 bool 'Use chscs for Common I/O' CONFIG_CHSC
+tristate 'QDIO support' CONFIG_QDIO
+if [ "$CONFIG_QDIO" != "n" ]; then
+  bool '   Performance statistics in /proc' CONFIG_QDIO_PERF_STATS
+fi
 bool 'Builtin IPL record support' CONFIG_IPL
 if [ "$CONFIG_IPL" = "y" ]; then
   choice 'IPL method generated into head.S' \
@@ -79,4 +83,5 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/defconfig linux-2.4.22-pre10/arch/s390x/defconfig
--- linux-2.4.21/arch/s390x/defconfig	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/defconfig	2003-08-01 13:30:32.000000000 +0000
@@ -36,8 +36,8 @@
 CONFIG_MACHCHK_WARNING=y
 CONFIG_CHSC=y
 CONFIG_IPL=y
-# CONFIG_IPL_TAPE is not set
-CONFIG_IPL_VM=y
+CONFIG_IPL_TAPE=y
+# CONFIG_IPL_VM is not set
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
@@ -118,7 +118,7 @@
 # CONFIG_TUN is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_TR=y
-# CONFIG_FDDI is not set
+CONFIG_FDDI=y
 
 #
 # S/390 network device drivers
@@ -134,20 +134,40 @@
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 # CONFIG_NETLINK_DEV is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_FILTER is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_FILTER=y
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 # CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_NET_IPGRE_BROADCAST is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
 # CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 CONFIG_IPV6=m
+
+#
+#   IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
 CONFIG_SHARED_IPV6_CARDS=y
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
@@ -158,6 +178,11 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -166,7 +191,7 @@
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
+CONFIG_NET_FASTROUTE=y
 # CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
@@ -175,6 +200,11 @@
 # CONFIG_NET_SCHED is not set
 
 #
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
 # File systems
 #
 # CONFIG_QUOTA is not set
@@ -187,33 +217,38 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
 # CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=m
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
-# CONFIG_RAMFS is not set
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
@@ -230,13 +265,17 @@
 # CONFIG_CODA_FS is not set
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
 # CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
-# CONFIG_SMB_FS is not set
+CONFIG_LOCKD_V4=y
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
 # CONFIG_NCPFS_IOCTL_LOCKING is not set
@@ -247,27 +286,80 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
 #
 CONFIG_PARTITION_ADVANCED=y
 # CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
 CONFIG_IBM_PARTITION=y
-# CONFIG_MAC_PARTITION is not set
-# CONFIG_MSDOS_PARTITION is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_LDM_DEBUG=y
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_SMB_NLS=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 
 #
 # Kernel hacking
 #
 CONFIG_MAGIC_SYSRQ=y
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/kernel/Makefile linux-2.4.22-pre10/arch/s390x/kernel/Makefile
--- linux-2.4.21/arch/s390x/kernel/Makefile	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/kernel/Makefile	2003-08-01 13:32:47.000000000 +0000
@@ -29,7 +29,7 @@
 #
 obj-$(CONFIG_REMOTE_DEBUG)	+= gdb-stub.o #gdb-low.o 
 
-obj-$(CONFIG_S390_SUPPORT)	+= linux32.o signal32.o ioctl32.o wrapper32.o exec32.o
+obj-$(CONFIG_S390_SUPPORT)	+= linux32.o signal32.o ioctl32.o wrapper32.o exec32.o exec_domain32.o
 obj-$(CONFIG_BINFMT_ELF32)	+= binfmt_elf32.o
 
 .PHONY: asm-offsets.h
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/kernel/binfmt_elf32.c linux-2.4.22-pre10/arch/s390x/kernel/binfmt_elf32.c
--- linux-2.4.21/arch/s390x/kernel/binfmt_elf32.c	2001-04-12 02:02:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/kernel/binfmt_elf32.c	2003-08-01 13:33:16.000000000 +0000
@@ -87,7 +87,13 @@
 #define ELF_PLATFORM (NULL)
 
 #ifdef __KERNEL__
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex, ibcs2)			\
+do {							\
+	if (ibcs2)                                      \
+		set_personality(PER_SVR4);              \
+	else if (current->personality != PER_LINUX32)   \
+		set_personality(PER_LINUX);             \
+} while (0)
 #endif 
 
 #include "linux32.h"
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/kernel/debug.c linux-2.4.22-pre10/arch/s390x/kernel/debug.c
--- linux-2.4.21/arch/s390x/kernel/debug.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/kernel/debug.c	2003-08-01 13:31:14.000000000 +0000
@@ -949,9 +949,21 @@
 	int i;
 	unsigned long flags;
 	mode_t mode = S_IFREG;
+	struct proc_dir_entry *pde;
+
 
 	if (!id)
 		goto out;
+	pde = debug_create_proc_dir_entry(id->proc_root_entry,
+					  view->name, mode,
+					  &debug_inode_ops,
+					  &debug_file_ops);
+	if(!pde){
+		printk(KERN_WARNING "debug: create_proc_entry() failed! Cannot register view %s/%s\n", id->name,view->name);
+		rc = -1;
+		goto out;
+	}
+
 	spin_lock_irqsave(&id->lock, flags);
 	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
 		if (id->views[i] == NULL)
@@ -962,6 +974,8 @@
 			id->name,view->name);
 		printk(KERN_WARNING 
 			"debug: maximum number of views reached (%i)!\n", i);
+		debug_delete_proc_dir_entry(id->proc_root_entry, pde);
+		
 		rc = -1;
 	}
 	else {
@@ -970,11 +984,7 @@
 			mode |= S_IRUSR;
 		if (view->input_proc)
 			mode |= S_IWUSR;
-		id->proc_entries[i] =
-		    debug_create_proc_dir_entry(id->proc_root_entry,
-						view->name, mode,
-						&debug_inode_ops,
-						&debug_file_ops);
+		id->proc_entries[i] = pde;
 		rc = 0;
 	}
 	spin_unlock_irqrestore(&id->lock, flags);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/kernel/entry.S linux-2.4.22-pre10/arch/s390x/kernel/entry.S
--- linux-2.4.21/arch/s390x/kernel/entry.S	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/kernel/entry.S	2003-08-01 13:31:58.000000000 +0000
@@ -392,7 +392,7 @@
         .long  SYSCALL(sys_oldumount,sys32_oldumount_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys32_setuid16_wrapper)   /* old setuid16 syscall*/
         .long  SYSCALL(sys_ni_syscall,sys32_getuid16)   /* old getuid16 syscall*/
-        .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 25 old stime syscall */
+        .long  SYSCALL(sys_ni_syscall,sys32_stime_wrapper) /* 25 old stime syscall */
         .long  SYSCALL(sys_ptrace,sys32_ptrace_wrapper)
         .long  SYSCALL(sys_alarm,sys32_alarm_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old fstat syscall */
@@ -489,7 +489,7 @@
         .long  SYSCALL(sys_sigreturn_glue,sys32_sigreturn_glue)
         .long  SYSCALL(sys_clone_glue,sys_clone_glue) /* 120 */
         .long  SYSCALL(sys_setdomainname,sys32_setdomainname_wrapper)
-        .long  SYSCALL(sys_newuname,sys32_newuname_wrapper)
+        .long  SYSCALL(s390x_newuname,sys32_newuname_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* modify_ldt for i386 */
         .long  SYSCALL(sys_adjtimex,sys32_adjtimex_wrapper)
         .long  SYSCALL(sys_mprotect,sys32_mprotect_wrapper) /* 125 */
@@ -503,7 +503,7 @@
         .long  SYSCALL(sys_fchdir,sys32_fchdir_wrapper)
         .long  SYSCALL(sys_bdflush,sys32_bdflush_wrapper)
         .long  SYSCALL(sys_sysfs,sys32_sysfs_wrapper)           /* 135 */
-        .long  SYSCALL(sys_personality,sys32_personality_wrapper)
+        .long  SYSCALL(s390x_personality,sys32_personality_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* for afs_syscall */
         .long  SYSCALL(sys_ni_syscall,sys32_setfsuid16_wrapper) /* old setfsuid16 syscall */
         .long  SYSCALL(sys_ni_syscall,sys32_setfsgid16_wrapper) /* old setfsgid16 syscall */
@@ -516,7 +516,7 @@
         .long  SYSCALL(sys_writev,sys32_writev_wrapper)
         .long  SYSCALL(sys_getsid,sys32_getsid_wrapper)
         .long  SYSCALL(sys_fdatasync,sys32_fdatasync_wrapper)
-        .long  SYSCALL(sys_sysctl,sys_ni_syscall)
+        .long  SYSCALL(sys_sysctl,sys32_sysctl_wrapper)
         .long  SYSCALL(sys_mlock,sys32_mlock_wrapper)           /* 150 */
         .long  SYSCALL(sys_munlock,sys32_munlock_wrapper)
         .long  SYSCALL(sys_mlockall,sys32_mlockall_wrapper)
@@ -558,7 +558,7 @@
         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* streams1 */
         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* streams2 */
         .long  SYSCALL(sys_vfork_glue,sys_vfork_glue) /* 190 */
-        .long  SYSCALL(sys_getrlimit,sys32_old_getrlimit_wrapper)
+        .long  SYSCALL(sys_getrlimit,sys32_getrlimit_wrapper)
 	.long  SYSCALL(sys_mmap2,sys32_mmap2_wrapper)
 	.long  SYSCALL(sys_ni_syscall,sys32_truncate64_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys32_ftruncate64_wrapper)
@@ -589,7 +589,7 @@
         .long  SYSCALL(sys_madvise,sys32_madvise_wrapper)
 	.long  SYSCALL(sys_getdents64,sys32_getdents64_wrapper)/* 220 */
 	.long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
-	.long  SYSCALL(sys_readahead,sys_ni_syscall)
+	.long  SYSCALL(sys_readahead,sys32_readahead)
 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for setxattr  */
 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 225 - reserved for lsetxattr */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/kernel/exec_domain32.c linux-2.4.22-pre10/arch/s390x/kernel/exec_domain32.c
--- linux-2.4.21/arch/s390x/kernel/exec_domain32.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/kernel/exec_domain32.c	2003-08-01 13:30:31.000000000 +0000
@@ -0,0 +1,30 @@
+/*
+ * Support for 32-bit Linux for S390 personality.
+ *
+ * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Gerhard Tonn (ton@de.ibm.com)
+ *
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/personality.h>
+#include <linux/sched.h>
+
+struct exec_domain s390_exec_domain;
+
+static int __init
+s390_init (void)
+{
+	s390_exec_domain.name = "Linux/s390";
+	s390_exec_domain.handler = NULL;
+	s390_exec_domain.pers_low = PER_LINUX32;
+	s390_exec_domain.pers_high = PER_LINUX32;
+	s390_exec_domain.signal_map = default_exec_domain.signal_map;
+	s390_exec_domain.signal_invmap = default_exec_domain.signal_invmap;
+	register_exec_domain(&s390_exec_domain);
+	return 0;
+}
+
+__initcall(s390_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/kernel/head.S linux-2.4.22-pre10/arch/s390x/kernel/head.S
--- linux-2.4.21/arch/s390x/kernel/head.S	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/kernel/head.S	2003-08-01 13:31:16.000000000 +0000
@@ -548,26 +548,11 @@
 	tm     __LC_CPUID,0xff          # running under VM ?
 	bno    0f-.LPG1(%r13)
         oi     7(%r12),1                # set VM flag
-#
-# we are running under VM, find out if we have PFIX
-#
-	la     %r1,0f-.LPG1(%r13)       # set program check address
-	stg    %r1,__LC_PGM_NEW_PSW+8
-        lghi   %r0,0x4000
-	lghi   %r2,0
-	.long  0x83200098               # diag 2,0,x'0098' - lock page
-	lghi   %r2,4
-	.long  0x83200098               # diag 2,0,x'0098' - unlock page
-	oi     7(%r12),128              # set PFIX flag
 0:      lh     %r0,__LC_CPUID+4         # get cpu version
         chi    %r0,0x7490               # running on a P/390 ?
         bne    1f-.LPG1(%r13)
         oi     7(%r12),4                # set P/390 flag
 1:
-	chi    %r0,0x2084		# new stidp format?
-	bne    2f-.LPG1(%r13)
-	oi     7(%r12),64		# set new stidp flag
-2:	
 
 #
 # find out if we have the MVPG instruction
@@ -601,7 +586,7 @@
         .quad  .Lduct                   # cr2: dispatchable unit control table
         .quad  0                        # cr3: instruction authorization
         .quad  0                        # cr4: instruction authorization
-        .quad  0                        # cr5:  various things
+        .quad  0xffffffffffffffff       # cr5: primary-aste origin
         .quad  0                        # cr6:  I/O interrupts
         .quad  0                        # cr7:  secondary space segment table
         .quad  0                        # cr8:  access registers translation
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/kernel/ioctl32.c linux-2.4.22-pre10/arch/s390x/kernel/ioctl32.c
--- linux-2.4.21/arch/s390x/kernel/ioctl32.c	2002-02-25 19:37:56.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/kernel/ioctl32.c	2003-08-01 13:32:45.000000000 +0000
@@ -25,6 +25,11 @@
 #include <linux/ext2_fs.h>
 #include <linux/hdreg.h>
 #include <linux/if_bonding.h>
+#include <linux/loop.h>
+#include <linux/blkpg.h>
+#include <linux/blk.h>
+#include <linux/elevator.h>
+#include <linux/raw.h>
 #include <asm/types.h>
 #include <asm/uaccess.h>
 #include <asm/dasd.h>
@@ -373,6 +378,107 @@
 	return sys_ioctl(fd, cmd, arg);
 }
 
+struct loop_info32 {
+	int			lo_number;      /* ioctl r/o */
+	__kernel_dev_t32	lo_device;      /* ioctl r/o */
+	unsigned int		lo_inode;       /* ioctl r/o */
+	__kernel_dev_t32	lo_rdevice;     /* ioctl r/o */
+	int			lo_offset;
+	int			lo_encrypt_type;
+	int			lo_encrypt_key_size;    /* ioctl w/o */
+	int			lo_flags;       /* ioctl r/o */
+	char			lo_name[LO_NAME_SIZE];
+	unsigned char		lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+	unsigned int		lo_init[2];
+	char			reserved[4];
+};
+
+static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	mm_segment_t old_fs = get_fs();
+	struct loop_info l;
+	int err = -EINVAL;
+
+	switch(cmd) {
+	case LOOP_SET_STATUS:
+		err = get_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
+		err |= __get_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
+		err |= __get_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
+		err |= __get_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
+		err |= __copy_from_user((char *)&l.lo_offset, (char *)&((struct loop_info32 *)arg)->lo_offset,
+					   8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
+		if (err) {
+			err = -EFAULT;
+		} else {
+			set_fs (KERNEL_DS);
+			err = sys_ioctl (fd, cmd, (unsigned long)&l);
+			set_fs (old_fs);
+		}
+		break;
+	case LOOP_GET_STATUS:
+		set_fs (KERNEL_DS);
+		err = sys_ioctl (fd, cmd, (unsigned long)&l);
+		set_fs (old_fs);
+		if (!err) {
+			err = put_user(l.lo_number, &((struct loop_info32 *)arg)->lo_number);
+			err |= __put_user(l.lo_device, &((struct loop_info32 *)arg)->lo_device);
+			err |= __put_user(l.lo_inode, &((struct loop_info32 *)arg)->lo_inode);
+			err |= __put_user(l.lo_rdevice, &((struct loop_info32 *)arg)->lo_rdevice);
+			err |= __copy_to_user((char *)&((struct loop_info32 *)arg)->lo_offset,
+					   (char *)&l.lo_offset, (unsigned long)l.lo_init - (unsigned long)&l.lo_offset);
+			if (err)
+				err = -EFAULT;
+		}
+		break;
+	default: {
+		static int count = 0;
+		if (++count <= 20)
+			printk("%s: Unknown loop ioctl cmd, fd(%d) "
+			       "cmd(%08x) arg(%08lx)\n",
+			       __FUNCTION__, fd, cmd, arg);
+	}
+	}
+	return err;
+}
+
+
+struct blkpg_ioctl_arg32 {
+	int op;
+	int flags;
+	int datalen;
+	u32 data;
+};
+                                
+static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioctl_arg32 *arg)
+{
+	struct blkpg_ioctl_arg a;
+	struct blkpg_partition p;
+	int err;
+	mm_segment_t old_fs = get_fs();
+	
+	err = get_user(a.op, &arg->op);
+	err |= __get_user(a.flags, &arg->flags);
+	err |= __get_user(a.datalen, &arg->datalen);
+	err |= __get_user((long)a.data, &arg->data);
+	if (err) return err;
+	switch (a.op) {
+	case BLKPG_ADD_PARTITION:
+	case BLKPG_DEL_PARTITION:
+		if (a.datalen < sizeof(struct blkpg_partition))
+			return -EINVAL;
+                if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
+			return -EFAULT;
+		a.data = &p;
+		set_fs (KERNEL_DS);
+		err = sys_ioctl(fd, cmd, (unsigned long)&a);
+		set_fs (old_fs);
+	default:
+		return -EINVAL;
+	}                                        
+	return err;
+}
+
+
 static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
 	mm_segment_t old_fs = get_fs();
@@ -413,7 +519,19 @@
 	IOCTL32_DEFAULT(BIODASDINFO),
 	IOCTL32_DEFAULT(BIODASDFMT),
 
+	IOCTL32_DEFAULT(BLKROSET),
+	IOCTL32_DEFAULT(BLKROGET),
 	IOCTL32_DEFAULT(BLKRRPART),
+	IOCTL32_DEFAULT(BLKFLSBUF),
+	IOCTL32_DEFAULT(BLKRASET),
+	IOCTL32_DEFAULT(BLKFRASET),
+	IOCTL32_DEFAULT(BLKSECTSET),
+	IOCTL32_DEFAULT(BLKSSZGET),
+	IOCTL32_DEFAULT(BLKBSZGET),
+	IOCTL32_DEFAULT(BLKGETSIZE64),
+
+	IOCTL32_DEFAULT(BLKELVGET),
+	IOCTL32_DEFAULT(BLKELVSET),
 
 	IOCTL32_HANDLER(HDIO_GETGEO, hd_geometry_ioctl),
 
@@ -422,6 +540,7 @@
 	IOCTL32_DEFAULT(TCSETAW),
 	IOCTL32_DEFAULT(TCSETAF),
 	IOCTL32_DEFAULT(TCSBRK),
+	IOCTL32_DEFAULT(TCSBRKP),
 	IOCTL32_DEFAULT(TCXONC),
 	IOCTL32_DEFAULT(TCFLSH),
 	IOCTL32_DEFAULT(TCGETS),
@@ -508,6 +627,10 @@
 
 	IOCTL32_DEFAULT(SIOCGSTAMP),
 
+	IOCTL32_DEFAULT(LOOP_SET_FD),
+	IOCTL32_DEFAULT(LOOP_CLR_FD),
+
+	IOCTL32_DEFAULT(SIOCATMARK),
 	IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
 	IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
 	IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc),
@@ -552,7 +675,18 @@
 	IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl),
 	IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl),
 
-	IOCTL32_HANDLER(BLKGETSIZE, w_long)
+	IOCTL32_HANDLER(LOOP_SET_STATUS, loop_status),
+	IOCTL32_HANDLER(LOOP_GET_STATUS, loop_status),
+
+/* Raw devices */
+	IOCTL32_DEFAULT(RAW_SETBIND),
+	IOCTL32_DEFAULT(RAW_GETBIND),
+
+	IOCTL32_HANDLER(BLKRAGET, w_long),
+	IOCTL32_HANDLER(BLKGETSIZE, w_long),
+	IOCTL32_HANDLER(BLKFRAGET, w_long),
+	IOCTL32_HANDLER(BLKSECTGET, w_long),
+	IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans)
 
 };
 
@@ -604,6 +738,8 @@
 static void ioctl32_insert(struct ioctl32_list *entry)
 {
 	int hash = ioctl32_hash(entry->handler.cmd);
+
+	entry->next = 0;
 	if (!ioctl32_hash_table[hash])
 		ioctl32_hash_table[hash] = entry;
 	else {
@@ -612,10 +748,51 @@
 		while (l->next)
 			l = l->next;
 		l->next = entry;
-		entry->next = 0;
 	}
 }
 
+int register_ioctl32_conversion(unsigned int cmd,
+				int (*handler)(unsigned int, unsigned int,
+					       unsigned long, struct file *))
+{
+	struct ioctl32_list *l, *new;
+	int hash;
+
+	hash = ioctl32_hash(cmd);
+	for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next)
+		if (l->handler.cmd == cmd)
+			return -EBUSY;
+	new = kmalloc(sizeof(struct ioctl32_list), GFP_KERNEL);
+	if (new == NULL)
+		return -ENOMEM;
+	new->handler.cmd = cmd;
+	new->handler.function = (void *) handler;
+	ioctl32_insert(new);
+	return 0;
+}
+
+int unregister_ioctl32_conversion(unsigned int cmd)
+{
+	struct ioctl32_list *p, *l;
+	int hash;
+
+	hash = ioctl32_hash(cmd);
+	p = NULL;
+	for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next) {
+		if (l->handler.cmd == cmd)
+			break;
+		p = l;
+	}
+	if (l == NULL)
+		return -ENOENT;
+	if (p == NULL)
+		ioctl32_hash_table[hash] = l->next;
+	else
+		p->next = l->next;
+	kfree(l);
+	return 0;
+}
+
 static int __init init_ioctl32(void)
 {
 	int i;
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/kernel/linux32.c linux-2.4.22-pre10/arch/s390x/kernel/linux32.c
--- linux-2.4.21/arch/s390x/kernel/linux32.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/kernel/linux32.c	2003-08-01 13:31:43.000000000 +0000
@@ -63,6 +63,7 @@
 #include <asm/semaphore.h>
 
 #include <net/scm.h>
+#include <net/sock.h>
 
 #include "linux32.h"
 
@@ -384,18 +385,18 @@
 
 struct shmid64_ds32 {
 	struct ipc64_perm_ds32	shm_perm;
-	unsigned int		__pad1;
+	__kernel_size_t32	shm_segsz;
 	__kernel_time_t32	shm_atime;
-	unsigned int		__pad2;
+	unsigned int		__unused1;
 	__kernel_time_t32	shm_dtime;
-	unsigned int		__pad3;
+	unsigned int		__unused2;
 	__kernel_time_t32	shm_ctime;
-	__kernel_size_t32	shm_segsz;
+	unsigned int		__unused3;
 	__kernel_pid_t32	shm_cpid;
 	__kernel_pid_t32	shm_lpid;
 	unsigned int		shm_nattch;
-	unsigned int		__unused1;
-	unsigned int		__unused2;
+	unsigned int		__unused4;
+	unsigned int		__unused5;
 };
 
                                                         
@@ -504,16 +505,23 @@
 
 static int do_sys32_msgsnd (int first, int second, int third, void *uptr)
 {
-	struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
+	struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf), GFP_USER);
 	struct msgbuf32 *up = (struct msgbuf32 *)uptr;
 	mm_segment_t old_fs;
 	int err;
 
 	if (!p)
 		return -ENOMEM;
-	err = get_user (p->mtype, &up->mtype);
-	err |= __copy_from_user (p->mtext, &up->mtext, second);
-	if (err)
+
+	err = -EINVAL;
+	if (second > MSGMAX || first < 0 || second < 0)
+		goto out;
+
+	err = -EFAULT;
+	if (!uptr)
+		goto out;
+	if (get_user (p->mtype, &up->mtype) ||
+	    __copy_from_user (p->mtext, &up->mtext, second))
 		goto out;
 	old_fs = get_fs ();
 	set_fs (KERNEL_DS);
@@ -532,6 +540,9 @@
 	mm_segment_t old_fs;
 	int err;
 
+	if (first < 0 || second < 0)
+		return -EINVAL;
+
 	if (!version) {
 		struct ipc_kludge_32 *uipck = (struct ipc_kludge_32 *)uptr;
 		struct ipc_kludge_32 ipck;
@@ -546,12 +557,12 @@
 		msgtyp = ipck.msgtyp;
 	}
 	err = -ENOMEM;
-	p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
+	p = kmalloc (second + sizeof (struct msgbuf), GFP_USER);
 	if (!p)
 		goto out;
 	old_fs = get_fs ();
 	set_fs (KERNEL_DS);
-	err = sys_msgrcv (first, p, second + 4, msgtyp, third);
+	err = sys_msgrcv (first, p, second, msgtyp, third);
 	set_fs (old_fs);
 	if (err < 0)
 		goto free_then_out;
@@ -879,27 +890,39 @@
 {
 	switch (cmd) {
 	case F_GETLK:
-	case F_SETLK:
-	case F_SETLKW:
 		{
 			struct flock f;
 			mm_segment_t old_fs;
 			long ret;
 			
-			if(get_flock(&f, (struct flock32 *)arg))
+			if(get_flock(&f, (struct flock32 *)A(arg)))
 				return -EFAULT;
 			old_fs = get_fs(); set_fs (KERNEL_DS);
 			ret = sys_fcntl(fd, cmd, (unsigned long)&f);
 			set_fs (old_fs);
 			if (ret) return ret;
 			if (f.l_start >= 0x7fffffffUL ||
-			    f.l_len >= 0x7fffffffUL ||
 			    f.l_start + f.l_len >= 0x7fffffffUL)
 				return -EOVERFLOW;
-			if(put_flock(&f, (struct flock32 *)arg))
+			if(put_flock(&f, (struct flock32 *)A(arg)))
 				return -EFAULT;
 			return 0;
 		}
+	case F_SETLK:
+	case F_SETLKW:
+		{
+			struct flock f;
+			mm_segment_t old_fs;
+			long ret;
+			
+			if(get_flock(&f, (struct flock32 *)A(arg)))
+				return -EFAULT;
+			old_fs = get_fs(); set_fs (KERNEL_DS);
+			ret = sys_fcntl(fd, cmd, (unsigned long)&f);
+			set_fs (old_fs);
+			if (ret) return ret;
+			return 0;
+		}
 	default:
 		return sys_fcntl(fd, cmd, (unsigned long)arg);
 	}
@@ -912,7 +935,7 @@
 	return sys32_fcntl(fd, cmd, arg);
 }
 
-struct dqblk32 {
+struct user_dqblk32 {
     __u32 dqb_bhardlimit;
     __u32 dqb_bsoftlimit;
     __u32 dqb_curblocks;
@@ -925,46 +948,45 @@
                                 
 extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
 
-asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr)
+asmlinkage int sys32_quotactl(int cmd, const char *special, int id, caddr_t addr)
 {
 	int cmds = cmd >> SUBCMDSHIFT;
 	int err;
-	struct dqblk d;
+	struct v1c_mem_dqblk d;
 	mm_segment_t old_fs;
 	char *spec;
 	
 	switch (cmds) {
-	case Q_GETQUOTA:
+	case Q_V1_GETQUOTA:
 		break;
-	case Q_SETQUOTA:
-	case Q_SETUSE:
-	case Q_SETQLIM:
-		if (copy_from_user (&d, (struct dqblk32 *)addr,
-				    sizeof (struct dqblk32)))
+	case Q_V1_SETQUOTA:
+	case Q_V1_SETUSE:
+	case Q_V1_SETQLIM:
+		if (copy_from_user(&d, addr, sizeof (struct user_dqblk32)))
 			return -EFAULT;
-		d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
-		d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
+		d.dqb_itime = ((struct user_dqblk32 *)&d)->dqb_itime;
+		d.dqb_btime = ((struct user_dqblk32 *)&d)->dqb_btime;
 		break;
 	default:
-		return sys_quotactl(cmd, special,
-				    id, (caddr_t)addr);
+		return sys_quotactl(cmd, special, id, addr);
 	}
-	spec = getname (special);
+
+	spec = getname(special);
 	err = PTR_ERR(spec);
-	if (IS_ERR(spec)) return err;
-	old_fs = get_fs ();
+	if (IS_ERR(spec))
+		return err;
+	old_fs = get_fs();
 	set_fs (KERNEL_DS);
 	err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
-	set_fs (old_fs);
-	putname (spec);
+	set_fs(old_fs);
+	putname(spec);
 	if (err)
 		return err;
-	if (cmds == Q_GETQUOTA) {
+	if (cmds == Q_V1_GETQUOTA) {
 		__kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
-		((struct dqblk32 *)&d)->dqb_itime = i;
-		((struct dqblk32 *)&d)->dqb_btime = b;
-		if (copy_to_user ((struct dqblk32 *)addr, &d,
-				  sizeof (struct dqblk32)))
+		((struct user_dqblk32 *)&d)->dqb_itime = i;
+		((struct user_dqblk32 *)&d)->dqb_btime = b;
+		if (copy_to_user(addr, &d, sizeof (struct user_dqblk32)))
 			return -EFAULT;
 	}
 	return 0;
@@ -2151,15 +2173,17 @@
 	return ret;
 }
 
-#define RLIM_INFINITY32	0x7fffffff
-#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
+#define RLIM_OLD_INFINITY32	0x7fffffff
+#define RLIM_INFINITY32		0xffffffff
+#define RESOURCE32_OLD(x)	((x > RLIM_OLD_INFINITY32) ? RLIM_OLD_INFINITY32 : x)
+#define RESOURCE32(x) 		((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
 
 struct rlimit32 {
 	u32	rlim_cur;
 	u32	rlim_max;
 };
 
-extern asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim);
+extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
 
 asmlinkage int sys32_old_getrlimit(unsigned int resource, struct rlimit32 *rlim)
 {
@@ -2168,7 +2192,23 @@
 	mm_segment_t old_fs = get_fs ();
 	
 	set_fs (KERNEL_DS);
-	ret = sys_old_getrlimit(resource, &r);
+	ret = sys_getrlimit(resource, &r);
+	set_fs (old_fs);
+	if (!ret) {
+		ret = put_user (RESOURCE32_OLD(r.rlim_cur), &rlim->rlim_cur);
+		ret |= __put_user (RESOURCE32_OLD(r.rlim_max), &rlim->rlim_max);
+	}
+	return ret;
+}
+
+asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
+{
+	struct rlimit r;
+	int ret;
+	mm_segment_t old_fs = get_fs ();
+	
+	set_fs (KERNEL_DS);
+	ret = sys_getrlimit(resource, &r);
 	set_fs (old_fs);
 	if (!ret) {
 		ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
@@ -2588,8 +2628,23 @@
 			  CMSG32_ALIGN(sizeof(struct cmsghdr32)));
 		kcmsg32->cmsg_len = clen32;
 
+		switch (kcmsg32->cmsg_type) {
+			/*
+			 * The timestamp type's data needs to be converted
+			 * from 64-bit time values to 32-bit time values
+			*/
+		case SO_TIMESTAMP: {
+			__kernel_time_t32* ptr_time32 = CMSG32_DATA(kcmsg32);
+			__kernel_time_t*   ptr_time   = CMSG_DATA(ucmsg);
+			get_user(*ptr_time32, ptr_time);
+			get_user(*(ptr_time32+1), ptr_time+1);
+			kcmsg32->cmsg_len -= 2*(sizeof(__kernel_time_t) -
+						sizeof(__kernel_time_t32));
+		}
+		default:;
+		}
 		ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
-		wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
+		wp = (((char *)kcmsg32) + CMSG32_ALIGN(kcmsg32->cmsg_len));
 	}
 
 	/* Copy back fixed up data, and adjust pointers. */
@@ -2612,6 +2667,7 @@
 	kmsg->msg_control = (void *) orig_cmsg_uptr;
 }
 
+#if 0
 asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
 {
 	struct socket *sock;
@@ -2721,7 +2777,7 @@
 		sockfd_put(sock);
 	}
 
-	if(uaddr != NULL && err >= 0)
+	if(uaddr != NULL && err >= 0 && kern_msg.msg_namelen)
 		err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
 	if(cmsg_ptr != 0 && err >= 0) {
 		unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
@@ -2737,6 +2793,222 @@
 		return err;
 	return len;
 }
+#endif
+
+/*
+ *	BSD sendmsg interface
+ */
+
+int sys32_sendmsg(int fd, struct msghdr32 *msg, unsigned flags)
+{
+	struct socket *sock;
+	char address[MAX_SOCK_ADDR];
+	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
+	unsigned char ctl[sizeof(struct cmsghdr) + 20];	/* 20 is size of ipv6_pktinfo */
+	unsigned char *ctl_buf = ctl;
+	struct msghdr msg_sys;
+	int err, ctl_len, iov_size, total_len;
+	
+	err = -EFAULT;
+	if (msghdr_from_user32_to_kern(&msg_sys, msg))
+		goto out; 
+
+	sock = sockfd_lookup(fd, &err);
+	if (!sock) 
+		goto out;
+
+	/* do not move before msg_sys is valid */
+	err = -EINVAL;
+	if (msg_sys.msg_iovlen > UIO_MAXIOV)
+		goto out_put;
+
+	/* Check whether to allocate the iovec area*/
+	err = -ENOMEM;
+	iov_size = msg_sys.msg_iovlen * sizeof(struct iovec32);
+	if (msg_sys.msg_iovlen > UIO_FASTIOV) {
+		iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
+		if (!iov)
+			goto out_put;
+	}
+
+	/* This will also move the address data into kernel space */
+	err = verify_iovec32(&msg_sys, iov, address, VERIFY_READ);
+	if (err < 0) 
+		goto out_freeiov;
+	total_len = err;
+
+	err = -ENOBUFS;
+
+	if (msg_sys.msg_controllen > INT_MAX)
+		goto out_freeiov;
+	ctl_len = msg_sys.msg_controllen; 
+	if (ctl_len) 
+	{
+		if (ctl_len > sizeof(ctl))
+		{
+			ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
+			if (ctl_buf == NULL) 
+				goto out_freeiov;
+		}
+		else if (ctl_len < sizeof(struct cmsghdr))
+		{
+			/* to get same error message as on 31 bit native */
+			err = EOPNOTSUPP;
+			goto out_freeiov;
+		}
+		err = -EFAULT;
+		if (cmsghdr_from_user32_to_kern(&msg_sys, ctl_buf, ctl_len))
+			goto out_freectl;
+//		msg_sys.msg_control = ctl_buf;
+	}
+	msg_sys.msg_flags = flags;
+
+	if (sock->file->f_flags & O_NONBLOCK)
+		msg_sys.msg_flags |= MSG_DONTWAIT;
+	err = sock_sendmsg(sock, &msg_sys, total_len);
+
+out_freectl:
+	if (ctl_buf != ctl)    
+		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
+out_freeiov:
+	if (iov != iovstack)
+		sock_kfree_s(sock->sk, iov, iov_size);
+out_put:
+	sockfd_put(sock);
+out:       
+	return err;
+}
+
+static __inline__ void
+scm_recv32(struct socket *sock, struct msghdr *msg,
+		struct scm_cookie *scm, int flags, unsigned long cmsg_ptr)
+{
+	if(!msg->msg_control)
+	{
+		if(sock->passcred || scm->fp)
+			msg->msg_flags |= MSG_CTRUNC;
+		scm_destroy(scm);
+		return;
+	}
+	/* If recvmsg processing itself placed some
+	 * control messages into user space, it's is
+	 * using 64-bit CMSG processing, so we need
+	 * to fix it up before we tack on more stuff.
+	 */
+	if((unsigned long) msg->msg_control != cmsg_ptr)
+		cmsg32_recvmsg_fixup(msg, cmsg_ptr);
+	/* Wheee... */
+	if(sock->passcred)
+		put_cmsg32(msg,
+			SOL_SOCKET, SCM_CREDENTIALS,
+			sizeof(scm->creds), &scm->creds);
+	if(!scm->fp)
+		return;
+
+	scm_detach_fds32(msg, scm);
+}
+
+static int  
+sock_recvmsg32(struct socket *sock, struct msghdr *msg, int size, int flags,
+               unsigned long cmsg_ptr)
+{
+	struct scm_cookie scm;
+
+	memset(&scm, 0, sizeof(scm));
+	size = sock->ops->recvmsg(sock, msg, size, flags, &scm);
+	if (size >= 0)
+		scm_recv32(sock, msg, &scm, flags, cmsg_ptr);
+
+	return size;
+}
+
+/*
+ *	BSD recvmsg interface
+ */
+
+int
+sys32_recvmsg (int fd, struct msghdr32 *msg, unsigned int flags)
+{
+	struct socket *sock;
+	struct iovec iovstack[UIO_FASTIOV];
+	struct iovec *iov=iovstack;
+	struct msghdr msg_sys;
+	unsigned long cmsg_ptr;
+	int err, iov_size, total_len, len;
+
+	/* kernel mode address */
+	char addr[MAX_SOCK_ADDR];
+
+	/* user mode address pointers */
+	struct sockaddr *uaddr;
+	int *uaddr_len;
+	
+	err=-EFAULT;
+	if (msghdr_from_user32_to_kern(&msg_sys, msg))
+		goto out;
+
+	sock = sockfd_lookup(fd, &err);
+	if (!sock)
+		goto out;
+
+	err = -EINVAL;
+	if (msg_sys.msg_iovlen > UIO_MAXIOV)
+		goto out_put;
+	
+	/* Check whether to allocate the iovec area*/
+	err = -ENOMEM;
+	iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
+	if (msg_sys.msg_iovlen > UIO_FASTIOV) {
+		iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
+		if (!iov)
+			goto out_put;
+	}
+
+	/*
+	 *	Save the user-mode address (verify_iovec will change the
+	 *	kernel msghdr to use the kernel address space)
+	 */
+	 
+	uaddr = msg_sys.msg_name;
+	uaddr_len = &msg->msg_namelen;
+	err = verify_iovec32(&msg_sys, iov, addr, VERIFY_WRITE);
+	if (err < 0)
+		goto out_freeiov;
+	total_len=err;
+
+	cmsg_ptr = (unsigned long)msg_sys.msg_control;
+	msg_sys.msg_flags = 0;
+	
+	if (sock->file->f_flags & O_NONBLOCK)
+		flags |= MSG_DONTWAIT;
+	err = sock_recvmsg32(sock, &msg_sys, total_len, flags, cmsg_ptr);
+	if (err < 0)
+		goto out_freeiov;
+	len = err;
+
+	if (uaddr != NULL && 
+	/* in order to get same error message as on native 31 bit */
+		msg_sys.msg_namelen > 0) {
+		err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
+		if (err < 0)
+			goto out_freeiov;
+	}
+	err = __put_user(msg_sys.msg_flags, &msg->msg_flags);
+	if (err)
+		goto out_freeiov;
+	err = __put_user((__kernel_size_t32) ((unsigned long)msg_sys.msg_control - cmsg_ptr), &msg->msg_controllen);
+	if (err)
+		goto out_freeiov;
+	err = len;
+
+out_freeiov:
+	if (iov != iovstack)
+		sock_kfree_s(sock->sk, iov, iov_size);
+out_put:
+	sockfd_put(sock);
+out:
+	return err;
+}
 
 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
 				     char *optval, int optlen);
@@ -2820,6 +3092,20 @@
 	if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)
 		return do_set_icmpv6_filter(fd, level, optname,
 					    optval, optlen);
+	if (level == SOL_SOCKET && 
+	    (optname == SO_SNDTIMEO || optname == SO_RCVTIMEO)) {
+		long ret;
+		struct timeval tmp;
+		mm_segment_t old_fs;
+
+		if (get_tv32(&tmp, (struct timeval32 *)optval ))
+			return -EFAULT;
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		ret = sys_setsockopt(fd, level, optname, (char *) &tmp, sizeof(struct timeval));
+		set_fs(old_fs);
+		return ret; 
+	}
 
 	return sys_setsockopt(fd, level, optname, optval, optlen);
 }
@@ -3669,7 +3955,7 @@
  */
 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
 {
-	return copy_to_user(res32, kres, sizeof(*res32));
+	return copy_to_user(res32, kres, sizeof(*res32)) ? -EFAULT : 0;
 }
 
 /*
@@ -3891,15 +4177,25 @@
 asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
 				 __kernel_size_t32 count, u32 poshi, u32 poslo)
 {
+	if ((ssize_t32) count < 0)
+		return -EINVAL; 
 	return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
 asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
 				  __kernel_size_t32 count, u32 poshi, u32 poslo)
 {
+	if ((ssize_t32) count < 0)
+		return -EINVAL; 
 	return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
+extern asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count);
+
+asmlinkage ssize_t32 sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count)
+{
+	return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count);
+}
 
 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
 
@@ -4344,3 +4640,22 @@
 	return ret;
 }
 
+asmlinkage ssize_t sys_read(unsigned int fd, char * buf, size_t count);
+
+asmlinkage ssize_t32 sys32_read(unsigned int fd, char * buf, size_t count)
+{
+	if ((ssize_t32) count < 0)
+		return -EINVAL; 
+
+	return sys_read(fd, buf, count);
+}
+
+asmlinkage ssize_t sys_write(unsigned int fd, const char * buf, size_t count);
+
+asmlinkage ssize_t32 sys32_write(unsigned int fd, char * buf, size_t count)
+{
+	if ((ssize_t32) count < 0)
+		return -EINVAL; 
+
+	return sys_write(fd, buf, count);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/kernel/s390_ksyms.c linux-2.4.22-pre10/arch/s390x/kernel/s390_ksyms.c
--- linux-2.4.21/arch/s390x/kernel/s390_ksyms.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/kernel/s390_ksyms.c	2003-08-01 13:32:05.000000000 +0000
@@ -62,6 +62,20 @@
 EXPORT_SYMBOL(overflowuid);
 EXPORT_SYMBOL(overflowgid);
 
+#ifdef CONFIG_S390_SUPPORT
+/*
+ * Dynamically add/remove 31 bit ioctl conversion functions.
+ */
+extern int register_ioctl32_conversion(unsigned int cmd,
+				       int (*handler)(unsigned int, 
+						      unsigned int,
+						      unsigned long,
+						      struct file *));
+int unregister_ioctl32_conversion(unsigned int cmd);
+EXPORT_SYMBOL(register_ioctl32_conversion);
+EXPORT_SYMBOL(unregister_ioctl32_conversion);
+#endif
+
 /*
  * misc.
  */
@@ -70,5 +84,5 @@
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(console_mode);
 EXPORT_SYMBOL(console_device);
-EXPORT_SYMBOL(pfix_table);
 EXPORT_SYMBOL_NOVERS(do_call_softirq);
+EXPORT_SYMBOL(sys_wait4);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/kernel/setup.c linux-2.4.22-pre10/arch/s390x/kernel/setup.c
--- linux-2.4.21/arch/s390x/kernel/setup.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/kernel/setup.c	2003-08-01 13:32:46.000000000 +0000
@@ -56,8 +56,6 @@
 unsigned long cpu_initialized = 0;
 volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
 
-void* *pfix_table=NULL;
-
 /*
  * Setup options
  */
@@ -319,10 +317,6 @@
 	printk((MACHINE_IS_VM) ?
 	       "We are running under VM (64 bit mode)\n" :
 	       "We are running native (64 bit mode)\n");
-	if (MACHINE_IS_VM)
-		printk((MACHINE_HAS_PFIX) ?
-		       "This machine has PFIX support\n" :
-		       "This machine has no PFIX support\n");
 
         ROOT_DEV = to_kdev_t(0x0100);
         memory_start = (unsigned long) &_end;    /* fixit if use $CODELO etc*/
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/kernel/signal.c linux-2.4.22-pre10/arch/s390x/kernel/signal.c
--- linux-2.4.21/arch/s390x/kernel/signal.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/kernel/signal.c	2003-08-01 13:33:49.000000000 +0000
@@ -575,10 +575,7 @@
                                 /* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/kernel/signal32.c linux-2.4.22-pre10/arch/s390x/kernel/signal32.c
--- linux-2.4.21/arch/s390x/kernel/signal32.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/kernel/signal32.c	2003-08-01 13:33:10.000000000 +0000
@@ -302,7 +302,7 @@
 		save_fp_regs(&fpregs);
 		__put_user(fpregs.fpc, &sregs->fpregs.fpc);
 		for(i=0; i<NUM_FPRS; i++)
-			err |= __put_user(fpregs.fprs[i].d, &sregs->fpregs.fprs[i].d);  
+			err |= __put_user(fpregs.fprs[i].ui, &sregs->fpregs.fprs[i].d);  
 	}
 	return(err);
 	
@@ -331,7 +331,7 @@
 		(regs->psw.addr&PSW_ADDR_DEBUGCHANGE);
 		__get_user(fpregs.fpc, &sregs->fpregs.fpc);
                 for(i=0; i<NUM_FPRS; i++)
-                        err |= __get_user(fpregs.fprs[i].d, &sregs->fpregs.fprs[i].d);              
+                        err |= __get_user(fpregs.fprs[i].ui, &sregs->fpregs.fprs[i].d);              
 		if(!err)
 			restore_fp_regs(&fpregs);
 	}
@@ -474,6 +474,10 @@
 			goto give_sigsegv;
         }
 
+	/* Set up backchain. */
+	if (__put_user((unsigned int) regs->gprs[15], (unsigned int *) frame))
+		goto give_sigsegv;
+
 	/* Set up registers for signal handler */
 	regs->gprs[15] = (addr_t)frame;
 	regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
@@ -527,6 +531,10 @@
 		                  (u16 *)(frame->retcode));
 	}
 
+	/* Set up backchain. */
+	if (__put_user((unsigned int) regs->gprs[15], (unsigned int *) frame))
+		goto give_sigsegv;
+
 	/* Set up registers for signal handler */
 	regs->gprs[15] = (addr_t)frame;
 	regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
@@ -675,7 +683,7 @@
 				continue;
 
 			switch (signr) {
-			case SIGCONT: case SIGCHLD: case SIGWINCH:
+			case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
 				continue;
 
 			case SIGTSTP: case SIGTTIN: case SIGTTOU:
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/kernel/wrapper32.S linux-2.4.22-pre10/arch/s390x/kernel/wrapper32.S
--- linux-2.4.21/arch/s390x/kernel/wrapper32.S	2002-02-25 19:37:56.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/kernel/wrapper32.S	2003-08-01 13:33:07.000000000 +0000
@@ -17,14 +17,14 @@
 	llgfr	%r2,%r2			# unsigned int
 	llgtr	%r3,%r3			# char *
 	llgfr	%r4,%r4			# size_t
-	jg	sys_read		# branch to sys_read
+	jg	sys32_read		# branch to sys_read
 
 	.globl  sys32_write_wrapper 
 sys32_write_wrapper:
 	llgfr	%r2,%r2			# unsigned int
 	llgtr	%r3,%r3			# const char *
 	llgfr	%r4,%r4			# size_t
-	jg	sys_write		# branch to system call
+	jg	sys32_write		# branch to system call
 
 	.globl  sys32_open_wrapper 
 sys32_open_wrapper:
@@ -311,6 +311,12 @@
 	llgtr	%r3,%r3			# struct rlimit_emu31 *
 	jg	sys32_old_getrlimit	# branch to system call
 
+	.globl  sys32_getrlimit_wrapper 
+sys32_getrlimit_wrapper:
+	llgfr	%r2,%r2			# unsigned int
+	llgtr	%r3,%r3			# struct rlimit_emu31 *
+	jg	sys32_getrlimit		# branch to system call
+
 	.globl  sys32_mmap2_wrapper 
 sys32_mmap2_wrapper:
 	llgtr	%r2,%r2			# struct mmap_arg_struct_emu31 *
@@ -537,7 +543,7 @@
 	.globl  sys32_newuname_wrapper 
 sys32_newuname_wrapper:
 	llgtr	%r2,%r2			# struct new_utsname *
-	jg	sys_newuname		# branch to system call
+	jg	s390x_newuname		# branch to system call
 
 	.globl  sys32_adjtimex_wrapper 
 sys32_adjtimex_wrapper:
@@ -614,7 +620,7 @@
 	.globl  sys32_personality_wrapper 
 sys32_personality_wrapper:
 	llgfr	%r2,%r2			# unsigned long
-	jg	sys_personality		# branch to system call
+	jg	s390x_personality	# branch to system call
 
 	.globl  sys32_setfsuid16_wrapper 
 sys32_setfsuid16_wrapper:
@@ -1091,3 +1097,13 @@
 	llgtr	%r3,%r3			# struct stat64 *
 	llgfr	%r4,%r4			# long
 	jg	sys32_fstat64		# branch to system call
+
+	.globl	sys32_stime_wrapper
+sys32_stime_wrapper:
+	llgtr	%r2,%r2			# int *
+	jg	sys_stime		# branch to system call
+
+	.globl  sys32_sysctl_wrapper
+sys32_sysctl_wrapper:
+	llgtr   %r2,%r2                 # struct __sysctl_args32 *
+	jg      sys32_sysctl
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/mm/init.c linux-2.4.22-pre10/arch/s390x/mm/init.c
--- linux-2.4.21/arch/s390x/mm/init.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/mm/init.c	2003-08-01 13:32:22.000000000 +0000
@@ -45,6 +45,28 @@
 pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
 char  empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
 
+static inline int
+__pgd_populate(unsigned long *pgd_slot, unsigned long offset, pmd_t *pmd)
+{
+	if (offset == 0 && 
+	    ((*pgd_slot & _PGD_ENTRY_INV) != 0 ||
+	     (*pgd_slot & _PGD_ENTRY_LEN(2)) == 0)) {
+		/* Set lower pmd, upper pmd is empty. */
+		*pgd_slot = __pa(pmd) | _PGD_ENTRY_MASK |
+				_PGD_ENTRY_OFF(0) | _PGD_ENTRY_LEN(1);
+		return 1;
+	}
+	if (offset == 4 &&
+	    ((*pgd_slot & _PGD_ENTRY_INV) != 0 ||
+	     (*pgd_slot & _PGD_ENTRY_OFF(2)) != 0)) {
+		/* Lower pmd empty, set upper pmd. */
+		*pgd_slot = (__pa(pmd) - 0x2000) | _PGD_ENTRY_MASK |
+				_PGD_ENTRY_OFF(2) | _PGD_ENTRY_LEN(3);
+		return 1;
+	}
+        return 0;
+}
+
 pmd_t *pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
 {
         unsigned long addr = (unsigned long) pgd;
@@ -52,29 +74,42 @@
         unsigned long offset = addr & 4;
 	pmd_t *new, *pmd2;
 	int i;
- 
-        if (offset == 0 && 
-	    ((*pgd_slot & _PGD_ENTRY_INV) != 0 ||
-	     (*pgd_slot & _PGD_ENTRY_LEN(2)) == 0)) {
-                /* Set lower pmd, upper pmd is empty. */
-                *pgd_slot = __pa(pmd) | _PGD_ENTRY_MASK |
-                                _PGD_ENTRY_OFF(0) | _PGD_ENTRY_LEN(1);
-                return pmd;
-        }
-        if (offset == 4 &&
-	    ((*pgd_slot & _PGD_ENTRY_INV) != 0 ||
-	     (*pgd_slot & _PGD_ENTRY_OFF(2)) != 0)) {
-                /* Lower pmd empty, set upper pmd. */
-                *pgd_slot = (__pa(pmd) - 0x2000) | _PGD_ENTRY_MASK |
-                                _PGD_ENTRY_OFF(2) | _PGD_ENTRY_LEN(3);
+
+        /* Check if we can get away with a half-sized pmd. */
+        if (__pgd_populate(pgd_slot, offset, pmd))
                 return pmd;
-        }
+
         /* We have to enlarge the pmd to 16K if we arrive here. */
+        spin_unlock(&mm->page_table_lock);
 	new = (pmd_t *) __get_free_pages(GFP_KERNEL, 2);
-	if (new == NULL) {
+        spin_lock(&mm->page_table_lock);
+
+        /*
+         * Because we dropped the lock, we should re-check the
+         * entry, as somebody else could have populated it..
+         */
+        if (!pgd_none(*pgd)) {
+                if (new)
+                        free_pages((unsigned long) new, 2);
+                pmd_free(pmd);
+                return (pmd_t *) pgd_val(*pgd);
+        }
+
+	if (!new) {
 		pmd_free(pmd);
 		return NULL;
 	}
+
+        /*
+         * Re-check if we can get away with a half-sized pmd. We
+         * dropped the lock so somebody else could have freed the
+         * other half of the pmd.
+         */
+        if (__pgd_populate(pgd_slot, offset, pmd)) {
+                free_pages((unsigned long) new, 2);
+                return pmd;
+        }
+
 	/* Set the PG_arch_1 bit on the first and the third pmd page
            so that pmd_free_fast can recognize pmds that have been
            allocated with an order 2 allocation.  */
@@ -234,11 +269,6 @@
                                         continue;
                                 }
                                 set_pte(pt_dir, pte);
-				if (address < memory_size ) /* do not set storage
-							       key outside the storage
-							       or die */
-					set_access_key(pte); /* switch to our
-								access key */
                                 address += PAGE_SIZE;
                         }
                 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/vmlinux-shared.lds linux-2.4.22-pre10/arch/s390x/vmlinux-shared.lds
--- linux-2.4.21/arch/s390x/vmlinux-shared.lds	2002-02-25 19:37:56.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/vmlinux-shared.lds	2003-08-01 13:34:10.000000000 +0000
@@ -2,7 +2,7 @@
  * Written by Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
 OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
-OUTPUT_ARCH(s390)
+OUTPUT_ARCH(s390:64-bit)
 ENTRY(_start)
 SECTIONS
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/s390x/vmlinux.lds linux-2.4.22-pre10/arch/s390x/vmlinux.lds
--- linux-2.4.21/arch/s390x/vmlinux.lds	2002-02-25 19:37:56.000000000 +0000
+++ linux-2.4.22-pre10/arch/s390x/vmlinux.lds	2003-08-01 13:34:27.000000000 +0000
@@ -2,7 +2,7 @@
  * Written by Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
 OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
-OUTPUT_ARCH(s390)
+OUTPUT_ARCH(s390:64-bit)
 ENTRY(_start)
 SECTIONS
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/Makefile linux-2.4.22-pre10/arch/sh/Makefile
--- linux-2.4.21/arch/sh/Makefile	2001-10-15 20:36:48.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/Makefile	2003-08-01 13:33:53.000000000 +0000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.6 2000/06/10 03:03:52 gniibe Exp $
+# $Id: Makefile,v 1.1.1.1.2.2 2002/05/10 17:58:54 jzs 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
@@ -24,6 +24,14 @@
 LDFLAGS		:= -EB
 endif
 
+ifdef CONFIG_SH_KGDB
+CFLAGS :=$(CFLAGS:-fomit-frame-pointer=) -g
+AFLAGS += -g
+ifdef CONFIG_KGDB_MORE
+CFLAGS += $(shell echo $(CONFIG_KGDB_OPTIONS) | sed -e 's/"//g')
+endif
+endif
+
 LD	=$(CROSS_COMPILE)ld $(LDFLAGS)
 OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -R .stab -R .stabstr -S
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/config.in linux-2.4.22-pre10/arch/sh/config.in
--- linux-2.4.21/arch/sh/config.in	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/config.in	2003-08-01 13:33:22.000000000 +0000
@@ -30,6 +30,7 @@
 	"Generic		CONFIG_SH_GENERIC		\
 	 SolutionEngine		CONFIG_SH_SOLUTION_ENGINE	\
 	 SolutionEngine7751	CONFIG_SH_7751_SOLUTION_ENGINE	\
+	 SHMobileSolutionEngine	CONFIG_SH_MOBILE_SOLUTION_ENGINE \
 	 STB1_Harp		CONFIG_SH_STB1_HARP		\
 	 STB1_Overdrive		CONFIG_SH_STB1_OVERDRIVE	\
 	 HP620			CONFIG_SH_HP620			\
@@ -42,11 +43,15 @@
 	 CAT68701		CONFIG_SH_CAT68701		\
 	 BigSur			CONFIG_SH_BIGSUR		\
 	 SH2000			CONFIG_SH_SH2000		\
+	 HS7729PCI		CONFIG_SH_HS7729PCI		\
 	 ADX			CONFIG_SH_ADX			\
+	 SecureEdge5410		CONFIG_SH_SECUREEDGE5410	\
+	 KeyWest		CONFIG_SH_KEYWEST		\
 	 BareCPU		CONFIG_SH_UNKNOWN" Generic
 
-# The SH7750 RTC module is disabled in the Dreamcast
-if [ "$CONFIG_SH_DREAMCAST" = "y" ]; then
+# The SH7750 RTC module is disabled in the Dreamcast and SH-Mobile SolutionEngine
+if [ "$CONFIG_SH_DREAMCAST" = "y" -o \
+     "$CONFIG_SH_MOBILE_SOLUTION_ENGINE" = "y" ]; then
    define_bool CONFIG_SH_RTC n
 else
    define_bool CONFIG_SH_RTC y
@@ -58,12 +63,18 @@
 fi
 
 choice 'Processor type' \
-   "SH7707 CONFIG_CPU_SUBTYPE_SH7707 \
+   "SH7300 CONFIG_CPU_SUBTYPE_SH7300 \
+    SH7707 CONFIG_CPU_SUBTYPE_SH7707 \
     SH7708 CONFIG_CPU_SUBTYPE_SH7708 \
     SH7709 CONFIG_CPU_SUBTYPE_SH7709 \
     SH7750 CONFIG_CPU_SUBTYPE_SH7750 \
     SH7751 CONFIG_CPU_SUBTYPE_SH7751 \
-    ST40STB1 CONFIG_CPU_SUBTYPE_ST40STB1" SH7708
+    ST40RA/ST40STB1 CONFIG_CPU_SUBTYPE_ST40STB1 \
+    ST40GX1 CONFIG_CPU_SUBTYPE_ST40GX1" SH7708
+if [ "$CONFIG_CPU_SUBTYPE_SH7300" = "y" ]; then
+   define_bool CONFIG_CPU_SH3 y
+   define_bool CONFIG_CPU_SH4 n
+fi
 if [ "$CONFIG_CPU_SUBTYPE_SH7707" = "y" ]; then
    define_bool CONFIG_CPU_SH3 y
    define_bool CONFIG_CPU_SH4 n
@@ -87,6 +98,12 @@
 if [ "$CONFIG_CPU_SUBTYPE_ST40STB1" = "y" ]; then
    define_bool CONFIG_CPU_SH3 n
    define_bool CONFIG_CPU_SH4 y
+   define_bool CONFIG_CPU_SUBTYPE_ST40 y
+fi
+if [ "$CONFIG_CPU_SUBTYPE_ST40GX1" = "y" ]; then
+   define_bool CONFIG_CPU_SH3 n
+   define_bool CONFIG_CPU_SH4 y
+   define_bool CONFIG_CPU_SUBTYPE_ST40 y
 fi
 bool 'Little Endian' CONFIG_CPU_LITTLE_ENDIAN
 # Platform-specific memory start and size definitions
@@ -100,13 +117,19 @@
    define_hex CONFIG_MEMORY_SIZE 04000000
    define_bool CONFIG_MEMORY_SET y
 fi
+if [ "$CONFIG_SH_MOBILE_SOLUTION_ENGINE" = "y" ]; then
+   define_hex CONFIG_MEMORY_START 0c000000
+   define_hex CONFIG_MEMORY_SIZE 04000000
+   define_bool CONFIG_MEMORY_SET y
+fi
 if [ "$CONFIG_SH_HP600" = "y" -o "$CONFIG_SH_BIGSUR" = "y" -o \
-     "$CONFIG_SH_DREAMCAST" = "y" -o "$CONFIG_SH_SH2000" = "y" ]; then
+     "$CONFIG_SH_DREAMCAST" = "y" -o "$CONFIG_SH_SH2000" = "y" -o \
+     "$CONFIG_SH_KEYWEST" = "y" ]; then
    define_hex CONFIG_MEMORY_START 0c000000
    define_hex CONFIG_MEMORY_SIZE 00400000
    define_bool CONFIG_MEMORY_SET y
 fi
-if [ "$CONFIG_CPU_SUBTYPE_ST40STB1" = "y" ]; then
+if [ "$CONFIG_CPU_SUBTYPE_ST40" = "y" ]; then
    bool 'Memory on LMI' CONFIG_ST40_LMI_MEMORY
    if [ "$CONFIG_ST40_LMI_MEMORY" = "y" ] ; then
       define_hex CONFIG_MEMORY_START 08000000
@@ -119,11 +142,29 @@
    define_hex CONFIG_MEMORY_SIZE 00400000
    define_bool CONFIG_MEMORY_SET y
 fi
+if [ "$CONFIG_SH_SECUREEDGE5410" = "y" ]; then
+   define_hex CONFIG_MEMORY_START 08000000
+   define_hex CONFIG_MEMORY_SIZE 01000000
+   define_bool CONFIG_MEMORY_SET y
+fi
+if [ "$CONFIG_SH_HS7729PCI" = "y" ]; then
+   define_hex CONFIG_MEMORY_START 0c000000
+   define_hex CONFIG_MEMORY_SIZE 04000000
+   define_bool CONFIG_MEMORY_SET y
+fi
 # If none of the above have set memory start/size, ask the user.
 if [ "$CONFIG_MEMORY_SET" != "y" ]; then
    hex 'Physical memory start address' CONFIG_MEMORY_START 08000000
    hex 'Physical memory size' CONFIG_MEMORY_SIZE 00400000
 fi
+dep_bool 'Enable OC RAM zone (experimental)' CONFIG_SCRATCH_SPACE $CONFIG_EXPERIMENTAL
+
+if [ "$CONFIG_CPU_SUBTYPE_ST40" = "y" ]; then
+   bool 'PCI emulation of on-chip peripherals' CONFIG_SH_PCI_EMULATION
+   if [ "$CONFIG_SH_PCI_EMULATION" = "y" -a "$CONFIG_CPU_SUBTYPE_ST40GX1" = "y" ]; then
+      bool '  USB OHCI Host Controller' CONFIG_SH_PCI_USB
+   fi
+fi
 endmenu
 
 if [ "$CONFIG_SH_HP690" = "y" ]; then
@@ -138,7 +179,13 @@
 # Even on SuperH devices which don't have an ISA bus,
 # this variable helps the PCMCIA modules handle
 # IRQ requesting properly -- Greg Banks.
-define_bool CONFIG_ISA y
+
+if [ "$CONFIG_SH_SECUREEDGE5410" = "y" ]; then
+   define_bool CONFIG_ISA n
+else
+   define_bool CONFIG_ISA y
+fi
+
 define_bool CONFIG_EISA n
 define_bool CONFIG_MCA n
 define_bool CONFIG_SBUS n
@@ -147,7 +194,7 @@
 
 if [ "$CONFIG_SH_GENERIC" = "y" -o "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o \
      "$CONFIG_SH_UNKNOWN" = "y" -o "$CONFIG_SH_CAT68701" = "y" -o \
-     "$CONFIG_SH_ADX" = "y" ]; then
+     "$CONFIG_SH_ADX" = "y" -o "$CONFIG_SH_HS7729PCI" = "y" ]; then
   bool 'Compact Flash Enabler support' CONFIG_CF_ENABLER
 fi
 
@@ -175,21 +222,26 @@
    int 'HD64465 IRQ' CONFIG_HD64465_IRQ 5
 fi
 
+bool 'Wakeup UBC on startup' CONFIG_UBC_WAKEUP
 bool 'DMA controller (DMAC) support' CONFIG_SH_DMA
+int  'Peripheral clock frequency(Hz) (0: auto detect)' CONFIG_SH_PCLK_FREQ 0 0 1000000000
+
+bool 'Default bootloader kernel arguments' CONFIG_CMDLINE_BOOL
+if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then
+  string 'Initial kernel command string' CONFIG_CMDLINE "console=ttySC1,115200"
+fi
 
 bool 'PCI support' CONFIG_PCI
 if [ "$CONFIG_PCI" = "y" ]; then
-   choice '  PCI access mode' \
-	"BIOS		CONFIG_PCI_GOBIOS	\
-	 Direct		CONFIG_PCI_GODIRECT	\
-	 Any		CONFIG_PCI_GOANY"	Any
-   if [ "$CONFIG_PCI_GOBIOS" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
-      define_bool CONFIG_PCI_BIOS y
-   fi
-   if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
-      define_bool CONFIG_PCI_DIRECT y
-   fi
-   bool 'Cache and PCI noncoherent' CONFIG_SH_PCIDMA_NONCOHERENT
+  if [ "$CONFIG_SH_HS7729PCI" = "y" ]; then
+     define_bool CONFIG_PCI_SD0001 y
+     define_hex CONFIG_PCI_SD0001_IRQ 0
+     define_hex CONFIG_PCI_SD0001_BASE b0000000
+     define_bool CONFIG_SH_PCIDMA_NONCOHERENT y
+  else
+     define_bool CONFIG_PCI_SD0001 n
+     bool 'Cache and PCI noncoherent' CONFIG_SH_PCIDMA_NONCOHERENT
+  fi
 fi
 
 source drivers/pci/Config.in
@@ -259,7 +311,7 @@
    bool 'Network device support' CONFIG_NETDEVICES
    if [ "$CONFIG_NETDEVICES" = "y" ]; then
       source drivers/net/Config.in
-      if [ "$CONFIG_ATM" = "y" ]; then
+      if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
          source drivers/atm/Config.in
       fi
    fi
@@ -280,9 +332,9 @@
 #
 source drivers/input/Config.in
 
-# if [ "$CONFIG_SH_DREAMCAST" = "y" ]; then
-#    source drivers/maple/Config.in
-# fi
+if [ "$CONFIG_SH_DREAMCAST" = "y" ]; then
+   source drivers/maple/Config.in
+fi
 
 mainmenu_option next_comment
 comment 'Character devices'
@@ -309,6 +361,7 @@
      "$CONFIG_SH_STB1_OVERDRIVE" = "y" -o \
      "$CONFIG_SH_BIGSUR" = "y" -o \
      "$CONFIG_SH_7751_SOLUTION_ENGINE" = "y" -o \
+     "$CONFIG_SH_MOBILE_SOLUTION_ENGINE" = "y" -o \
      "$CONFIG_SH_SOLUTION_ENGINE" = "y" ]; then
    bool 'Heartbeat LED' CONFIG_HEARTBEAT
 fi
@@ -341,7 +394,7 @@
 bool 'Watchdog Timer Support' CONFIG_WATCHDOG
 if [ "$CONFIG_WATCHDOG" != "n" ]; then
    bool '  Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
-   dep_tristate '  SH 3/4 Watchdog' CONFIG_SH_WDT $CONFIG_SUPERH
+   dep_tristate '  SuperH Watchdog' CONFIG_SH_WDT $CONFIG_SUPERH
 fi
 endmenu
 
@@ -385,6 +438,34 @@
 if [ "$CONFIG_SH_STANDARD_BIOS" = "y" ]; then
    bool 'Early printk support' CONFIG_SH_EARLY_PRINTK
 fi
+bool 'Include KGDB kernel debugger' CONFIG_SH_KGDB
+if [ "$CONFIG_SH_KGDB" = "y" ]; then
+   bool ' Enter KGDB on NMI' CONFIG_KGDB_NMI
+   bool ' Include KGDB thread support' CONFIG_KGDB_THREAD
+   bool ' Console messages through GDB' CONFIG_SH_KGDB_CONSOLE
+   bool ' Allow SysRq "G" to enter KGDB?' CONFIG_KGDB_SYSRQ
+   if [ "$CONFIG_KGDB_SYSRQ" != "n" ]; then
+      define_bool CONFIG_MAGIC_SYSRQ y
+   fi
+   bool ' Include KGDB kernel asserts' CONFIG_KGDB_KERNEL_ASSERTS
+   bool ' Add additional compile options' CONFIG_KGDB_MORE
+   if [ "$CONFIG_KGDB_MORE" = "y" ]; then
+      string ' Additional compile options' CONFIG_KGDB_OPTIONS "-O1"
+   fi
+   mainmenu_option next_comment
+   comment '     Default KGDB port setup'
+      int 'Port number (ttySCn)' CONFIG_KGDB_DEFPORT 1
+      int 'Baud rate' CONFIG_KGDB_DEFBAUD 115200
+      choice 'Parity' \
+         "None CONFIG_KGDB_DEFPARITY_N	\
+          Even CONFIG_KGDB_DEFPARITY_E	\
+          Odd  CONFIG_KGDB_DEFPARITY_O"	None
+      choice 'DataBits' \
+         "7 CONFIG_KGDB_DEFBITS_7	\
+          8 CONFIG_KGDB_DEFBITS_8"	8
+   endmenu
+fi
 endmenu
 
+source crypto/Config.in
 source lib/Config.in
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/Makefile linux-2.4.22-pre10/arch/sh/kernel/Makefile
--- linux-2.4.21/arch/sh/kernel/Makefile	2001-09-08 19:29:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/Makefile	2003-08-01 13:33:41.000000000 +0000
@@ -12,40 +12,53 @@
 
 O_TARGET := kernel.o
 
-export-objs	:= io.o io_generic.o io_hd64461.o setup_hd64461.o sh_ksyms.o
+export-objs	:= io.o io_generic.o io_hd64461.o setup_hd64461.o sh_ksyms.o \
+		   dma.o
 
 obj-y	:= process.o signal.o entry.o traps.o irq.o irq_ipr.o \
 	ptrace.o setup.o time.o sys_sh.o semaphore.o \
-	irq_imask.o io.o io_generic.o sh_ksyms.o
+	irq_imask.o io.o io_generic.o sh_ksyms.o ubc.o
 
 obj-$(CONFIG_CF_ENABLER)	+= cf-enabler.o
 obj-$(CONFIG_CPU_SH4)		+= fpu.o
 obj-$(CONFIG_SH_RTC)            += rtc.o
 obj-$(CONFIG_SH_DMA)		+= dma.o
 obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o
+obj-$(CONFIG_SH_KGDB)		+= kgdb_stub.o kgdb_jmp.o
 
 ifeq ($(CONFIG_PCI),y)
 ifeq ($(CONFIG_SH_DREAMCAST),y)
 obj-y 				+= pci-dc.o pcibios.o
 else
 obj-y                           += pci-dma.o pcibios.o
-obj-$(CONFIG_CPU_SUBTYPE_ST40STB1)+= pci_st40.o
+obj-$(CONFIG_CPU_SUBTYPE_ST40)+= pci_st40.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7751)+= pci-sh7751.o 
 obj-$(CONFIG_SH_BIGSUR)+= pci-bigsur.o
 obj-$(CONFIG_SH_7751_SOLUTION_ENGINE)+= pci-7751se.o
+obj-$(CONFIG_PCI_SD0001)+= pci-sd0001.o
+obj-$(CONFIG_SH_SECUREEDGE5410)	+= pci-snapgear.o
+obj-$(CONFIG_SH_KEYWEST)	+= pci-v320usc.o
 endif
 endif
 
 obj-$(CONFIG_SH_HP600)		+= mach_hp600.o
 machine-specific-objs		+= mach_hp600.o
 
+obj-$(CONFIG_SH_HS7729PCI)	+= mach_hs7729pci.o setup_hs7729pci.o io_hs7729pci.o
+machine-specific-objs		+= mach_hs7729pci.o setup_hs7729pci.o io_hs7729pci.o
+
 obj-$(CONFIG_SH_SOLUTION_ENGINE)+= mach_se.o setup_se.o io_se.o led_se.o
 machine-specific-objs		+= mach_se.o setup_se.o io_se.o led_se.o
 
 obj-$(CONFIG_SH_7751_SOLUTION_ENGINE)+= mach_7751se.o setup_7751se.o \
-					io_7751se.o led_7751se.o
+					io_7751se.o led_se.o
 machine-specific-objs           += mach_7751se.o 7751setup_se.o \
-				   io_7751se.o led_7751se.o pci-7751se.o
+				   io_7751se.o led_se.o pci-7751se.o
+
+obj-$(CONFIG_SH_MOBILE_SOLUTION_ENGINE)+= mach_shmse.o setup_shmse.o \
+					io_shmse.o led_se.o
+machine-specific-objs          	+= mach_shmse.o setup_shmse.o \
+				   io_shmse.o led_se.o
 
 obj-$(CONFIG_SH_BIGSUR)		+= mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o
 machine-specific-objs		+= mach_bigsur.o setup_bigsur.o io_bigsur.o led_bigsur.o
@@ -65,11 +78,21 @@
 obj-$(CONFIG_HD64461)		+= setup_hd64461.o io_hd64461.o
 machine-specific-objs		+= setup_hd64461.o io_hd64461.o
 
-obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) +=irq_intc2.o
+obj-$(CONFIG_CPU_SUBTYPE_ST40) +=irq_intc2.o
 
 obj-$(CONFIG_SH_ADX)		+= mach_adx.o setup_adx.o io_adx.o irq_maskreg.o
 machine-specific-objs		+= mach_adx.o setup_adx.o io_adx.o irq_maskreg.o
 
+obj-$(CONFIG_SH_SECUREEDGE5410)	+= mach_snapgear.o setup_snapgear.o io_snapgear.o
+machine-specific-objs		+= mach_snapgear.o setup_snapgear.o io_snapgear.o
+ifeq ($(CONFIG_RTC),y)
+obj-$(CONFIG_SH_SECUREEDGE5410)	+= rtc-snapgear.o
+machine-specific-objs		+= rtc-snapgear.o
+endif
+
+obj-$(CONFIG_SH_KEYWEST)	+= mach_keywest.o setup_keywest.o io_keywest.o
+machine-specific-objs		+= mach_keywest.o setup_keywest.o io_keywest.o
+
 # Doesn't compile well, so don't include in machine-specific-objs
 obj-$(CONFIG_HD64465)		+= setup_hd64465.o io_hd64465.o hd64465_gpio.o
 obj-$(CONFIG_SH_DMIDA)		+= mach_dmida.o
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/cf-enabler.c linux-2.4.22-pre10/arch/sh/kernel/cf-enabler.c
--- linux-2.4.21/arch/sh/kernel/cf-enabler.c	2001-09-08 19:29:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/cf-enabler.c	2003-08-01 13:31:26.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: cf-enabler.c,v 1.8 2001/07/18 12:32:21 gniibe Exp $
+/* $Id: cf-enabler.c,v 1.1.1.1.2.1 2003/06/24 08:52:51 dwmw2 Exp $
  *
  *  linux/drivers/block/cf-enabler.c
  *
@@ -11,7 +11,7 @@
 
 #include <linux/config.h>
 #include <linux/init.h>
-
+#include <linux/delay.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 
@@ -87,7 +87,7 @@
 	return 0;
 }
 
-#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_SOLUTION_ENGINE)
+#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_SOLUTION_ENGINE) || defined(CONFIG_SH_HS7729PCI)
 #include <asm/hitachi_se.h>
 
 /*
@@ -142,15 +142,31 @@
 	ctrl_outw(0x2000, MRSHPC_ICR);
 	ctrl_outb(0x00, PA_MRSHPC_MW2 + 0x206);
 	ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200);
+
+	if (MACH_HS7729PCI) {
+		/* Empirical evidence shows that we have to delay for
+		   ten milliseconds and then redo the last outb. 
+		   I have no clue why. And all the docs are in Japanese
+		   so I feel no shame in just doing it this way. Besides,
+		   all this is just a crap hack for the fact that we don't
+		   have sensible userspace-less PCMCIA support in 2.4.
+
+		   dwmw2.
+		 */
+		mdelay(10);
+		ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200);
+	}
+
 	return 0;
 }
 #endif
 
 int __init cf_init(void)
 {
-#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_SOLUTION_ENGINE)
-	if (MACH_SE)
+#if defined(CONFIG_SH_GENERIC) || defined(CONFIG_SH_SOLUTION_ENGINE) || defined(CONFIG_SH_HS7729PCI)
+	if (MACH_SE || MACH_HS7729PCI) {
 		return cf_init_se();
+	}
 #endif
 	return cf_init_default();
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/dma.c linux-2.4.22-pre10/arch/sh/kernel/dma.c
--- linux-2.4.21/arch/sh/kernel/dma.c	2001-09-08 19:29:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/dma.c	2003-08-01 13:33:12.000000000 +0000
@@ -10,6 +10,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 
 #include <asm/signal.h>
 #include <asm/dma.h>
@@ -137,6 +138,25 @@
 	return 0;
 }
 
+static void __exit exit_dma(void)
+{
+#ifdef CONFIG_CPU_SH4
+	free_irq(DMAE_IRQ);
+#endif
+}
+
 module_init(init_dma);
+module_exit(exit_dma);
+
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(setup_dma);
+EXPORT_SYMBOL(claim_dma_lock);
+EXPORT_SYMBOL(release_dma_lock);
+EXPORT_SYMBOL(enable_dma);
+EXPORT_SYMBOL(disable_dma);
+EXPORT_SYMBOL(set_dma_mode);
+EXPORT_SYMBOL(set_dma_addr);
+EXPORT_SYMBOL(set_dma_count);
+EXPORT_SYMBOL(get_dma_residue);
 
-/**/
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/entry.S linux-2.4.22-pre10/arch/sh/kernel/entry.S
--- linux-2.4.21/arch/sh/kernel/entry.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/entry.S	2003-08-01 13:32:45.000000000 +0000
@@ -1,9 +1,11 @@
-/* $Id: entry.S,v 1.71 2001/07/27 11:47:50 gniibe Exp $
+/* $Id: entry.S,v 1.1.1.1.2.16 2003/07/16 18:41:20 yoshii Exp $
  *
  *  linux/arch/sh/entry.S
  *
  *  Copyright (C) 1999, 2000  Niibe Yutaka
  *
+ *  Modified to support SH7300. Takashi Kusuda (Jun 2003).
+ *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -15,12 +17,6 @@
 #include <linux/config.h>
 
 
-/*
- * Define this to turn on compatibility with the previous
- * system call ABI.  This feature is not properly maintained.
- */
-#undef COMPAT_OLD_SYSCALL_ABI
-
 ! NOTE:
 ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
 ! to be jumped is too far, but it causes illegal slot exception.
@@ -38,6 +34,12 @@
  *
  *    jmp	@k0	    ! control-transfer instruction
  *     ldc	k1, ssr     ! delay slot
+ */
+
+/*
+ * ABI at ret_from_syscall:
+ *	r8: from_syscall (0 or 1) indicating it's from syscall or not
+ *	r9: original r0 (to restart system call)
  *
  * Stack layout in 'ret_from_syscall':
  * 	ptrace needs to have all regs on the stack.
@@ -53,8 +55,7 @@
  *	gbr
  *	mach
  *	macl
- *	syscall #
- *
+ *	dummy
  */
 
 /*
@@ -66,7 +67,6 @@
 tsk_ptrace	= 24
 
 PT_TRACESYS  = 0x00000002
-PF_USEDFPU   = 0x00100000
 
 ENOSYS = 38
 EINVAL = 22
@@ -74,7 +74,8 @@
 #if defined(__sh3__)
 TRA     = 0xffffffd0
 EXPEVT  = 0xffffffd4
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
+#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \ 
+    defined(CONFIG_CPU_SUBTYPE_SH7709)
 INTEVT  = 0xa4000000		! INTEVTE2(0xa4000000)
 #else
 INTEVT  = 0xffffffd8
@@ -87,6 +88,10 @@
 MMU_TEA = 0xff00000c		! TLB Exception Address Register
 #endif
 
+#if defined(CONFIG_KGDB_NMI)
+NMI_VEC = 0x1c0			! Must catch early for debounce
+#endif
+
 /* Offsets to the stack */
 OFF_R0         =  0		/* Return value. New ABI also arg4 */
 OFF_R1         =  4     	/* New ABI: arg5 */
@@ -97,9 +102,8 @@
 OFF_R6         =  24     	/* New ABI: arg2 */
 OFF_R7         =  28     	/* New ABI: arg3 */
 OFF_SP	   =  (15*4)
+OFF_PC	   =  (16*4)
 OFF_SR	   =  (16*4+8)
-SYSCALL_NR =  (16*4+6*4)
-
 
 #define k0	r0
 #define k1	r1
@@ -220,10 +224,36 @@
 1:	.long	MMU_TEA
 2:	.long   SYMBOL_NAME(do_address_error)
 
-#if defined(CONFIG_SH_STANDARD_BIOS)
+
+#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
+! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present.
+! If both are configured, handle the debug traps (breakpoints) in SW,
+! but still allow BIOS traps to FW.
+
 	.align	2
-	/* Unwind the stack and jmp to the debug entry */
 debug_kernel:
+#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB)
+	/* Force BIOS call to FW (debug_trap put TRA in r8) */
+	mov	r8,r0
+	shlr2	r0
+	cmp/eq	#0x3f,r0
+	bt	debug_kernel_fw
+#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */
+
+debug_enter:		
+#if defined(CONFIG_SH_KGDB)
+	/* Jump to kgdb, pass stacked regs as arg */
+debug_kernel_sw:
+	mov.l	3f, r0
+	jmp	@r0
+	 mov	r15, r4
+	.align	2
+3:	.long	SYMBOL_NAME(kgdb_handle_exception)
+#endif /* CONFIG_SH_KGDB */
+
+#if defined(CONFIG_SH_STANDARD_BIOS)
+	/* Unwind the stack and jmp to the debug entry */
+debug_kernel_fw:
 	mov.l	@r15+, r0
 	mov.l	@r15+, r1
 	mov.l	@r15+, r2
@@ -259,11 +289,14 @@
 	.align	2
 1:	.long	0x300000f0
 2:	.long	SYMBOL_NAME(gdb_vbr_vector)
-#endif
+#endif /* CONFIG_SH_STANDARD_BIOS */
+
+#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
+
 
 	.align	2
 debug_trap:	
-#if defined(CONFIG_SH_STANDARD_BIOS)
+#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
 	mov	#OFF_SR, r0
 	mov.l	@(r0,r15), r0		! get status register
 	shll	r0
@@ -304,7 +337,8 @@
 	mov.l	@(tsk_ptrace,r0), r0	! Is current PTRACE_SYSCALL'd?
 	mov	#PT_TRACESYS, r1
 	tst	r1, r0
-	bt	ret_from_syscall
+	bt/s	syscall_ret
+	 mov	#0, r0
 	bra	syscall_ret_trace
 	 nop	 
 
@@ -346,29 +380,11 @@
 	mov.l	@r9, r8
 	!
 	! Is the trap argument >= 0x20? (TRA will be >= 0x80)
-	mov	#0x20, r9
-	extu.b	r9, r9
-	shll2	r9
-	cmp/hs	r9, r8
+	mov	#0x7f, r9
+	cmp/hi	r9, r8
 	bt	debug_trap
 	!
-	mov	#SYSCALL_NR, r14
-	add	r15, r14
-	!
-#ifdef COMPAT_OLD_SYSCALL_ABI
-	mov	#0x40, r9
-	cmp/hs	r9, r8
-	bf/s	old_abi_system_call
-	 nop
-#endif
 	! New Syscall ABI
-	add	#-0x40, r8
-	shlr2	r8
-	shll8	r8
-	shll8	r8 		    	! r8 = num_args<<16
-	mov	r3, r10
-	or	r8, r10	! Encode syscall # and # of arguments
-	mov.l	r10, @r14		! set syscall_nr
 	STI()
 	!
 	stc	k_current, r11
@@ -416,6 +432,10 @@
 	mov.l	__sct, r11
 	add	r11, r9
 	mov.l	@r9, r11
+	!		    Prepare args for do_signal on syscall return
+	mov	#1, r8			! indicate it's syscall return
+	mov.l	@(OFF_R0,r15), r9	! save original r0 (syscall arg4)
+	!
 	jmp	@r11	    	! jump to specific syscall handler
 	 nop
 
@@ -427,74 +447,6 @@
 	jmp	@r1    	! Call syscall_trace() which notifies superior
 	 lds	r0, pr    	! Then return to ret_from_syscall()
 
-
-
-#ifdef COMPAT_OLD_SYSCALL_ABI
-! Handle old ABI system call.
-! Note that ptrace(SYSCALL) is not supported for the old ABI.
-! At this point:
-!   r0, r4-7 as per ABI
-!   r8  = value of TRA register (= num_args<<2)
-!   r14 = points to SYSCALL_NR in stack frame
-old_abi_system_call:
-	mov 	r0, r9    	    	! Save system call number in r9
-	!   	    	    	    	! arrange for return which pops stack
-	mov.l	__old_abi_syscall_ret, r10
-	lds	r10, pr
-	!				  Build the stack frame if TRA > 0
-	mov	r8, r10
-	cmp/pl	r10
-	bf	0f
-	mov.l	@(OFF_SP,r15), r0	! get original user stack
-7:	add	#-4, r10
-4:	mov.l	@(r0,r10), r1	! May cause address error exception..
-	mov.l	r1, @-r15
-	cmp/pl	r10
-	bt	7b
-0:
-	mov.l	r9, @r14	    	! set syscall_nr
-	STI()
-	!   	    	    Call the system call handler through the table.
-	!   	    	    First check for bad syscall number
-	mov.l	__n_sys, r10
-	cmp/hs	r10, r9
-	bf	2f
-	!   	    	    Bad syscall number
-	rts			! return to old_abi_syscall_ret
-    	 mov	#-ENOSYS, r0
-	!   	    	    Good syscall number
-2:	shll2	r9		! x4
-	mov.l	__sct, r11
-	add	r11, r9
-	mov.l	@r9, r11
-	jmp	@r11	    	! call specific syscall handler,
-	 nop
-
-    	.align 2
-__old_abi_syscall_ret:
-	.long	old_abi_syscall_ret
-
-    	! This code gets called on address error exception when copying
-	! syscall arguments from user stack to kernel stack.  It is
-	! supposed to return -EINVAL through old_abi_syscall_ret, but it
-	! appears to have been broken for a long time in that the r0
-	! return value will be saved into the kernel stack relative to r15
-	! but the value of r15 is not correct partway through the loop.
-	! So the user prog is returned its old r0 value, not -EINVAL.
-	! Greg Banks 28 Aug 2000.
-	.section	.fixup,"ax"
-fixup_syscall_argerr:
-    	! First get r15 back to 
-	rts
-    	 mov	#-EINVAL, r0
-    	.previous
-
-	.section	__ex_table, "a"
-	.align	2
-	.long	4b,fixup_syscall_argerr
-    	.previous
-#endif
-
 	.align	2
 __TRA:	.long	TRA
 __syscall_trace:
@@ -511,12 +463,28 @@
 
 	.align	2
 reschedule:
+	! gUSA handling
+	mov.l	@(OFF_SP,r15), r0	! get user space stack pointer
+	mov	r0, r1
+	shll	r0
+	bf/s	1f
+	 shll	r0
+	bf/s	1f
+	 mov	#OFF_PC, r0
+	! 				  SP >= 0xc0000000 : gUSA mark
+	mov.l	@(r0,r15), r2		! get user space PC (program counter)
+	mov.l	@(OFF_R0,r15), r3	! end point
+	cmp/hs	r3, r2			! r2 >= r3? 
+	bt	1f
+	add	r3, r1			! rewind point #2
+	mov.l	r1, @(r0,r15)		! reset PC to rewind point #2
+	!
+1:	mov.l	2f, r1
 	mova	SYMBOL_NAME(ret_from_syscall), r0
-	mov.l	1f, r1
 	jmp	@r1
 	 lds	r0, pr
 	.align	2
-1:	.long	SYMBOL_NAME(schedule)
+2:	.long	SYMBOL_NAME(schedule)
 
 ret_from_irq:
 ret_from_exception:
@@ -527,14 +495,9 @@
 	bt	restore_all	! Yes, it's from kernel, go back soon
 	!
 	bra	ret_from_syscall
-	 nop
+	 mov	#0, r8		! indicate it's *not* syscall return
 
 	.align 2
-#ifdef COMPAT_OLD_SYSCALL_ABI
-old_abi_syscall_ret:
-	add	r8, r15	! pop off the arguments
-	/* fall through */
-#endif
 syscall_ret:
 	mov.l	r0, @(OFF_R0,r15)	! save the return value
 	/* fall through */
@@ -553,9 +516,11 @@
 	tst	r0, r0
 	bt	restore_all
 signal_return:
+	mov.l	__do_signal, r1
 	mov	r15, r4
 	mov	#0, r5
-	mov.l	__do_signal, r1
+	mov	r8, r6
+	mov	r9, r7
 	mova	restore_all, r0
 	jmp	@r1
 	 lds	r0, pr
@@ -567,12 +532,6 @@
 
 	.align 2
 restore_all:
-#if defined(__SH4__)
-	mov.l	__fpu_prepare_fd, r0
-	jsr	@r0
-	 stc	sr, r4
-#endif
-	!
 	mov.l	@r15+, r0
 	mov.l	@r15+, r1
 	mov.l	@r15+, r2
@@ -585,7 +544,7 @@
 	stc	sr, r8
 	mov.l	__blrb_flags, r9	! BL =1, RB=1
 	or	r9, r8
-	ldc	r8, sr		! here, change the register bank
+	ldc	r8, sr			! here, change the register bank
 	!
 	mov.l	@r15+, r8
 	mov.l	@r15+, r9
@@ -594,25 +553,26 @@
 	mov.l	@r15+, r12
 	mov.l	@r15+, r13
 	mov.l	@r15+, r14
-	mov.l	@r15+, k4	! original stack pointer
+	mov.l	@r15+, k4		! original stack pointer
 	ldc.l	@r15+, spc
 	lds.l	@r15+, pr
-	mov.l	@r15+, k3	! original SR
+	mov.l	@r15+, k3		! original SR
 	ldc.l	@r15+, gbr
 	lds.l	@r15+, mach
 	lds.l	@r15+, macl
-	add	#4, r15	! Skip syscall number
+	add	#4, r15			! skip placeholder
+	!
 	!
 	! Calculate new SR value
-	mov	k3, k2	! original SR value
+	mov	k3, k2			! original SR value
 	mov.l	1f, k1
 	stc	sr, k0
-	and	k1, k0	! Get current FD-bit
+	and	k1, k0			! Get current FD-bit
 	mov.l	2f, k1
-	and	k1, k2	! Mask orignal SR value
-	or	k0, k2	! Inherit current FD-bit
+	and	k1, k2			! Mask orignal SR value
+	or	k0, k2			! Inherit current FD-bit
 	!
-	mov	k3, k0	! Calculate IMASK-bits
+	mov	k3, k0			! Calculate IMASK-bits
 	shlr2	k0
 	and	#0x3c, k0
 	cmp/eq	#0x3c, k0
@@ -620,54 +580,14 @@
 	 shll2	k0
 	mov	g_imask, k0
 	!
-7:	or	k0, k2	! Set the IMASK-bits
+7:	or	k0, k2			! Set the IMASK-bits
 	ldc	k2, ssr
 	!
-#if defined(__SH4__)
-	shll	k2
-	shll	k2
-	bf	9f		! user mode
-	/* Kernel to kernel transition */
-	mov.l	1f, k1
-	tst	k1, k3
-	bf	9f		! it hadn't FPU
-	! Kernel to kernel and FPU was used
-	! There's the case we don't get FPU now
-	stc	sr, k2
-	tst	k1, k2
-	bt	8f
-	! We need to grab FPU here
-	xor	k1, k2
-	ldc	k2, sr		! Grab FPU
-	mov.l	__init_task_flags, k1
-	mov.l	@k1, k2
-	mov.l	__PF_USEDFPU, k0
-	or	k0, k2
-	mov.l	k2, @k1		! Set init_task.flags |= PF_USEDFPU
-	!
-	! Restoring FPU...
-	!
-8:	mov.l	3f, k1
-	lds	k1, fpscr
-	fmov.s	@r15+, fr0
-	fmov.s	@r15+, fr1
-	fmov.s	@r15+, fr2
-	fmov.s	@r15+, fr3
-	fmov.s	@r15+, fr4
-	fmov.s	@r15+, fr5
-	fmov.s	@r15+, fr6
-	fmov.s	@r15+, fr7
-	fmov.s	@r15+, fr8
-	fmov.s	@r15+, fr9
-	fmov.s	@r15+, fr10
-	fmov.s	@r15+, fr11
-	fmov.s	@r15+, fr12
-	fmov.s	@r15+, fr13
-	fmov.s	@r15+, fr14
-	fmov.s	@r15+, fr15
-	lds.l	@r15+, fpscr
-	lds.l	@r15+, fpul
-9:
+#if defined(CONFIG_KGDB_NMI)
+	! Clear in_nmi
+	mov.l	4f, k0
+	mov	#0, k1
+	mov.b	k1, @k0
 #endif
 	mov	k4, r15
 	rte
@@ -675,17 +595,13 @@
 
 	.align	2
 __blrb_flags:	.long	0x30000000
-#if defined(__SH4__)
-__fpu_prepare_fd:
-	.long	SYMBOL_NAME(fpu_prepare_fd)
-__init_task_flags:
-	.long	SYMBOL_NAME(init_task_union)+4
-__PF_USEDFPU:
-	.long	PF_USEDFPU
-#endif
 1:	.long	0x00008000	! FD
 2:	.long	0xffff7f0f	! ~(IMASK+FD)
 3:	.long	0x00080000	! SZ=0, PR=1
+#if defined(CONFIG_KGDB_NMI)
+4:	.long	SYMBOL_NAME(in_nmi)
+#endif
+
 
 ! Exception Vector Base
 !
@@ -717,6 +633,22 @@
 interrupt:
 	mov.l	2f, k2
 	mov.l	3f, k3
+#if defined(CONFIG_KGDB_NMI)
+	! Debounce (filter nested NMI)
+	mov.l	@k2, k0
+	mov.l	5f, k1
+	cmp/eq	k1, k0
+	bf	0f
+	mov.l	6f, k1
+	tas.b	@k1
+	bt	0f
+	rte
+	 nop
+	.align	2
+5:	.long	NMI_VEC
+6:	.long	SYMBOL_NAME(in_nmi)
+0:
+#endif /* defined(CONFIG_KGDB_NMI) */
 	bra	handle_exception
 	 mov.l	@k2, k2
 
@@ -732,61 +664,21 @@
 	! Using k0, k1 for scratch registers (r0_bank1, r1_bank),
 	! save all registers onto stack.
 	!
-	stc	ssr, k0	! from kernel space?
-	shll	k0		! Check MD bit (bit30) by shifting it into the T bit
-	shll	k0
-#if defined(__SH4__)
-	bf/s	8f		! it's from user to kernel transition
-	 mov	r15, k0	! save original stack to k0
-	/* It's a kernel to kernel transition. */
-	/* Is the FPU disabled? */
-	mov.l	2f, k1
-	stc	ssr, k0
-	tst	k1, k0
-	mov.l	4f, k1
-	bf/s	9f		! FPU is not enabled, no need to save it
-	 mov	r15, k0	! save original stack to k0
-	! FPU is enabled, save it
-	! /* XXX: Need to save another bank of FPU if all FPU feature is used */
-	! /* Currently it's not the case for GCC (only udivsi3_i4, divsi3_i4) */
-	sts.l	fpul,  @-r15
-	sts.l	fpscr, @-r15
-	mov.l	6f, k1
-	lds	k1, fpscr
-	mov.l	3f, k1
-	fmov.s	fr15, @-r15
-	fmov.s	fr14, @-r15
-	fmov.s	fr13, @-r15
-	fmov.s	fr12, @-r15
-	fmov.s	fr11, @-r15
-	fmov.s	fr10, @-r15
-	fmov.s	fr9, @-r15
-	fmov.s	fr8, @-r15
-	fmov.s	fr7, @-r15
-	fmov.s	fr6, @-r15
-	fmov.s	fr5, @-r15
-	fmov.s	fr4, @-r15
-	fmov.s	fr3, @-r15
-	fmov.s	fr2, @-r15
-	fmov.s	fr1, @-r15
-	bra 9f
-	 fmov.s	fr0, @-r15
-#else
-	mov.l	3f, k1
-	bt/s	9f		! it's a kernel to kernel transition, and skip the FPU save.
-	 mov	r15, k0	! save original stack to k0 anyway
-#endif
-8:	/* User space to kernel */
+	stc	ssr, k0		! Is it from kernel space?
+	shll	k0		! Check MD bit (bit30) by shifting it into...
+	shll	k0		!       ...the T bit
+	bt/s	9f		! It's a kernel to kernel transition.
+	 mov	r15, k0		! save original stack to k0
+	/* User space to kernel */
 	mov	#0x20, k1
-	shll8	k1			! k1 <= 8192 == THREAD_SIZE
+	shll8	k1		! k1 <= 8192 == THREAD_SIZE
 	add	current, k1
 	mov	k1, r15		! change to kernel stack
 	!
-	mov.l	4f, k1			! let kernel release FPU
-9:	! Save the user registers on the stack.
-	! At this point, k1 should have been set to the new SR value
-  	mov	#-1, k4
-	mov.l	k4, @-r15		! syscall_nr (default: -1)
+9:	mov.l	3f, k1
+	!
+	! Save the user registers on the stack.
+	add	#-4, r15	! placeholder
 	!
 	sts.l	macl, @-r15
 	sts.l	mach, @-r15
@@ -806,11 +698,11 @@
 	mov.l	r9, @-r15
 	mov.l	r8, @-r15
 	!
-	stc	sr, r8	! Back to normal register bank, and
-	or	k1, r8	! Block all interrupts, may release FPU
+	stc	sr, r8		! Back to normal register bank, and
+	or	k1, r8		! Block all interrupts
 	mov.l	5f, k1
-	and	k1, r8	! ...
-	ldc	r8, sr	! ...changed here.
+	and	k1, r8		! ...
+	ldc	r8, sr		! ...changed here.
 	!
 	mov.l	r7, @-r15
 	mov.l	r6, @-r15
@@ -831,9 +723,7 @@
 	 nop
 	.align	2
 1:	.long	SYMBOL_NAME(exception_handling_table)
-2:	.long	0x00008000	! FD=1
 3:	.long	0x000000f0	! FD=0, IMASK=15
-4:	.long	0x000080f0	! FD=1, IMASK=15
 5:	.long	0xcfffffff	! RB=0, BL=0
 6:	.long	0x00080000	! SZ=0, PR=1
 
@@ -862,7 +752,11 @@
 	.long	error	! reserved_instruction      (filled by trap_init)
 	.long	error	! illegal_slot_instruction  (filled by trap_init)
 ENTRY(nmi_slot)
+#if defined (CONFIG_KGDB_NMI)
+	.long	debug_enter			! Allow trap to debugger
+#else
 	.long	none				! Not implemented yet
+#endif
 ENTRY(user_break_point_trap)
 	.long	break_point_trap
 ENTRY(interrupt_table)
@@ -900,7 +794,8 @@
 	.long	SYMBOL_NAME(do_IRQ)	!      rovi
 	.long	SYMBOL_NAME(do_IRQ)
 	.long	SYMBOL_NAME(do_IRQ)
-#if  defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
+#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7709)
 	.long	SYMBOL_NAME(do_IRQ)	! 32 IRQ  irq0
 	.long	SYMBOL_NAME(do_IRQ)	! 33      irq1
 	.long	SYMBOL_NAME(do_IRQ)	! 34      irq2
@@ -930,10 +825,57 @@
 	.long	SYMBOL_NAME(do_IRQ)	! 58      bri2
 	.long	SYMBOL_NAME(do_IRQ)	! 59      txi2
 	.long	SYMBOL_NAME(do_IRQ)	! 60 ADC  adi
-#if defined(CONFIG_CPU_SUBTYPE_SH7707)
+#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7707)
 	.long   SYMBOL_NAME(do_IRQ)	! 61 LCDC lcdi
 	.long   SYMBOL_NAME(do_IRQ)	! 62 PCC  pcc0i
 	.long   SYMBOL_NAME(do_IRQ)	! 63      pcc1i
+#if defined(CONFIG_CPU_SUBTYPE_SH7300)
+	.long   SYMBOL_NAME(do_IRQ)	! 64
+	.long   SYMBOL_NAME(do_IRQ)	! 65
+	.long   SYMBOL_NAME(do_IRQ)	! 66
+	.long   SYMBOL_NAME(do_IRQ)	! 67
+	.long   SYMBOL_NAME(do_IRQ)	! 68
+	.long   SYMBOL_NAME(do_IRQ)	! 69
+	.long   SYMBOL_NAME(do_IRQ)	! 70
+	.long   SYMBOL_NAME(do_IRQ)	! 71
+	.long   SYMBOL_NAME(do_IRQ)	! 72
+	.long   SYMBOL_NAME(do_IRQ)	! 73
+	.long   SYMBOL_NAME(do_IRQ)	! 74
+	.long   SYMBOL_NAME(do_IRQ)	! 75
+	.long   SYMBOL_NAME(do_IRQ)	! 76
+	.long   SYMBOL_NAME(do_IRQ)	! 77
+	.long   SYMBOL_NAME(do_IRQ)	! 78
+	.long   SYMBOL_NAME(do_IRQ)	! 79
+	.long   SYMBOL_NAME(do_IRQ)	! 80 SCIF0(SH7300)
+	.long   SYMBOL_NAME(do_IRQ)	! 81
+	.long   SYMBOL_NAME(do_IRQ)	! 82
+	.long   SYMBOL_NAME(do_IRQ)	! 83
+	.long   SYMBOL_NAME(do_IRQ)	! 84
+	.long   SYMBOL_NAME(do_IRQ)	! 85
+	.long   SYMBOL_NAME(do_IRQ)	! 86
+	.long   SYMBOL_NAME(do_IRQ)	! 87
+	.long   SYMBOL_NAME(do_IRQ)	! 88
+	.long   SYMBOL_NAME(do_IRQ)	! 89
+	.long   SYMBOL_NAME(do_IRQ)	! 90
+	.long   SYMBOL_NAME(do_IRQ)	! 91
+	.long   SYMBOL_NAME(do_IRQ)	! 92
+	.long   SYMBOL_NAME(do_IRQ)	! 93
+	.long   SYMBOL_NAME(do_IRQ)	! 94
+	.long   SYMBOL_NAME(do_IRQ)	! 95
+	.long   SYMBOL_NAME(do_IRQ)	! 96
+	.long   SYMBOL_NAME(do_IRQ)	! 97
+	.long   SYMBOL_NAME(do_IRQ)	! 98
+	.long   SYMBOL_NAME(do_IRQ)	! 99
+	.long   SYMBOL_NAME(do_IRQ)	! 100
+	.long   SYMBOL_NAME(do_IRQ)	! 101
+	.long   SYMBOL_NAME(do_IRQ)	! 102
+	.long   SYMBOL_NAME(do_IRQ)	! 103
+	.long   SYMBOL_NAME(do_IRQ)	! 104
+	.long   SYMBOL_NAME(do_IRQ)	! 105
+	.long   SYMBOL_NAME(do_IRQ)	! 106
+	.long   SYMBOL_NAME(do_IRQ)	! 107
+	.long   SYMBOL_NAME(do_IRQ)	! 108
+#endif
 #endif
 #elif defined(__SH4__)
 	.long	SYMBOL_NAME(do_IRQ)	! 32 Hitachi UDI
@@ -978,7 +920,7 @@
 	.long	SYMBOL_NAME(do_IRQ)	!     pwon
 	.long	SYMBOL_NAME(do_IRQ)	!     pwdwn
 	.long	SYMBOL_NAME(do_IRQ)	!     err
-#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
+#elif defined(CONFIG_CPU_SUBTYPE_ST40)
 	.long	error			!  50 0x840
 	.long	error			!  51 0x860
 	.long	error			!  52 0x880
@@ -1010,14 +952,14 @@
 	.long	SYMBOL_NAME(do_IRQ)	!  78 0xbc0 DMA ERR
 	.long	error			!  79 0xbe0
 	.long	SYMBOL_NAME(do_IRQ)	!  80 0xc00 PIO0
-	.long	SYMBOL_NAME(do_IRQ)	!  81 0xc20 PIO1
-	.long	SYMBOL_NAME(do_IRQ)	!  82 0xc40 PIO2
+	.long	error			!  81 0xc20
+	.long	error			!  82 0xc40
 	.long	error			!  83 0xc60
-	.long	error			!  84 0xc80
+	.long	SYMBOL_NAME(do_IRQ)	!  84 0xc80 PIO1
 	.long	error			!  85 0xca0
 	.long	error			!  86 0xcc0
 	.long	error			!  87 0xce0
-	.long	error			!  88 0xd00
+	.long	SYMBOL_NAME(do_IRQ)	!  88 0xd00 PIO2
 	.long	error			!  89 0xd20
 	.long	error			!  90 0xd40
 	.long	error			!  91 0xd60
@@ -1041,6 +983,7 @@
 	.long	error			! 109 0xfa0
 	.long	error			! 110 0xfc0
 	.long	error			! 111 0xfe0
+# if defined(CONFIG_CPU_SUBTYPE_ST40STB1)
 	.long	SYMBOL_NAME(do_IRQ)	! 112 0x1000 Mailbox
 	.long	error			! 113 0x1020
 	.long	error			! 114 0x1040
@@ -1073,6 +1016,74 @@
 	.long	error			! 141 0x13a0
 	.long	error			! 142 0x13c0
 	.long	error			! 143 0x13e0
+# elif defined(CONFIG_CPU_SUBTYPE_ST40GX1)
+	.long	SYMBOL_NAME(do_IRQ)	! 112 0x1000 Mailbox
+	.long	error			! 113 0x1020
+	.long	error			! 114 0x1040
+	.long	error			! 115 0x1060
+	.long	SYMBOL_NAME(do_IRQ)	! 116 0x1080 SSC0
+	.long	error			! 117 0x10a0
+	.long	error			! 118 0x10c0
+	.long	error			! 119 0x10e0
+	.long	SYMBOL_NAME(do_IRQ)	! 120 0x1100 IRBlaster IRB
+	.long	error			! 121 0x1120
+	.long	error			! 122 0x1140
+	.long	error			! 123 0x1160
+	.long	SYMBOL_NAME(do_IRQ)	! 124 0x1180 USB host
+	.long	error			! 125 0x11a0
+	.long	error			! 126 0x11c0
+	.long	error			! 127 0x11e0
+	.long	SYMBOL_NAME(do_IRQ)	! 128 0x1200 Video Processor BLITER
+	.long	error			! 129 0x1220
+	.long	error			! 130 0x1240
+	.long	error			! 131 0x1260
+	.long	SYMBOL_NAME(do_IRQ)	! 132 0x1280 UART0 UART0
+	.long	error			! 133 0x12a0
+	.long	SYMBOL_NAME(do_IRQ)	! 134 0x12c0       UART2
+	.long	error			! 135 0x12e0
+	.long	SYMBOL_NAME(do_IRQ)	! 136 0x1300 Additional PIO IO_PIO0
+	.long	error			! 137 0x1320
+	.long	error			! 138 0x1340
+	.long	error			! 139 0x1360
+	.long	SYMBOL_NAME(do_IRQ)	! 140 0x1380 EMPI INV_ADDR
+	.long	error			! 141 0x13a0
+	.long	error			! 142 0x13c0
+	.long	error			! 143 0x13e0
+	.long	SYMBOL_NAME(do_IRQ)	! 144 0x1400 MAFE
+	.long	error			! 145 0x1420
+	.long	error			! 146 0x1440
+	.long	error			! 147 0x1460
+	.long	SYMBOL_NAME(do_IRQ)	! 148 0x1480 PWM
+	.long	error			! 149 0x14a0
+	.long	error			! 150 0x14c0
+	.long	error			! 151 0x14e0
+	.long	SYMBOL_NAME(do_IRQ)	! 152 0x1500 SSC1
+	.long	error			! 153 0x1520
+	.long	error			! 154 0x1540
+	.long	error			! 155 0x1560
+	.long	SYMBOL_NAME(do_IRQ)	! 156 0x1580 Additional PIO IO_PIO1
+	.long	error			! 157 0x15a0
+	.long	error			! 158 0x15c0
+	.long	error			! 159 0x15e0
+	.long	SYMBOL_NAME(do_IRQ)	! 160 0x1600 USB target
+	.long	error			! 161 0x1620
+	.long	error			! 162 0x1640
+	.long	error			! 163 0x1660
+	.long	SYMBOL_NAME(do_IRQ)	! 164 0x1680 UART1 UART1
+	.long	error			! 165 0x16a0
+	.long	error			! 166 0x16c0
+	.long	error			! 167 0x16e0
+	.long	SYMBOL_NAME(do_IRQ)	! 168 0x1700 Teletext TTXT
+	.long	error			! 169 0x1720
+	.long	error			! 170 0x1740
+	.long	error			! 171 0x1760
+	.long	SYMBOL_NAME(do_IRQ)	! 172 0x1780 Video Sync VTG
+	.long	SYMBOL_NAME(do_IRQ)	! 173 0x17a0            DVP0
+	.long	SYMBOL_NAME(do_IRQ)	! 174 0x17c0            DVP1
+	.long	error			! 175 0x17e0
+# else
+#  error Unknown ST40 type
+# endif
 #endif
 
 ENTRY(sys_call_table)
@@ -1185,7 +1196,7 @@
 	.long SYMBOL_NAME(sys_newstat)
 	.long SYMBOL_NAME(sys_newlstat)
 	.long SYMBOL_NAME(sys_newfstat)
-	.long SYMBOL_NAME(sys_uname)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old uname */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* 110 */ /* iopl */
 	.long SYMBOL_NAME(sys_vhangup)
 	.long SYMBOL_NAME(sys_ni_syscall)	/* idle */
@@ -1199,7 +1210,7 @@
 	.long SYMBOL_NAME(sys_clone)		/* 120 */
 	.long SYMBOL_NAME(sys_setdomainname)
 	.long SYMBOL_NAME(sys_newuname)
-	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_modify_ldt */
+	.long SYMBOL_NAME(sys_cacheflush)	/* sys_modify_ldt for i386 */
 	.long SYMBOL_NAME(sys_adjtimex)
 	.long SYMBOL_NAME(sys_mprotect)		/* 125 */
 	.long SYMBOL_NAME(sys_sigprocmask)
@@ -1256,8 +1267,8 @@
 	.long SYMBOL_NAME(sys_rt_sigtimedwait)
 	.long SYMBOL_NAME(sys_rt_sigqueueinfo)
 	.long SYMBOL_NAME(sys_rt_sigsuspend)
-	.long SYMBOL_NAME(sys_pread)		/* 180 */
-	.long SYMBOL_NAME(sys_pwrite)
+	.long SYMBOL_NAME(sys_pread_wrapper)	/* 180 */
+	.long SYMBOL_NAME(sys_pwrite_wrapper)
 	.long SYMBOL_NAME(sys_chown16)
 	.long SYMBOL_NAME(sys_getcwd)
 	.long SYMBOL_NAME(sys_capget)
@@ -1299,15 +1310,16 @@
 	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
 	.long SYMBOL_NAME(sys_fcntl64)
 	.long SYMBOL_NAME(sys_gettid)
-	.long SYMBOL_NAME(sys_tkill)
-
+ 	.long SYMBOL_NAME(sys_tkill)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_readahead)	/* 225 */
 	/*
 	 * NOTE!! This doesn't have to be exact - we just have
 	 * to make sure we have _enough_ of the "sys_ni_syscall"
 	 * entries. Don't panic if you notice that this hasn't
 	 * been shrunk every time we add a new system call.
 	 */
-	.rept NR_syscalls-221
+	.rept NR_syscalls-(.-sys_call_table)/4
 		.long SYMBOL_NAME(sys_ni_syscall)
 	.endr
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/fpu.c linux-2.4.22-pre10/arch/sh/kernel/fpu.c
--- linux-2.4.21/arch/sh/kernel/fpu.c	2001-01-29 02:56:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/fpu.c	2003-08-01 13:33:36.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: fpu.c,v 1.29 2000/03/22 13:42:10 gniibe Exp $
+/* $Id: fpu.c,v 1.1.1.1.2.1 2002/01/25 00:51:42 gniibe Exp $
  *
  * linux/arch/sh/kernel/fpu.c
  *
@@ -18,6 +18,10 @@
 #include <asm/processor.h>
 #include <asm/io.h>
 
+/*
+ * Save FPU registers onto task structure.
+ * Assume called with FPU enabled (SR.FD=0).
+ */
 void
 save_fpu(struct task_struct *tsk)
 {
@@ -118,7 +122,8 @@
  * double precission represents signaling NANS.  
  */
 
-void fpu_init(void)
+static void
+fpu_init(void)
 {
 	asm volatile("lds	%0, fpul\n\t"
 		     "lds	%1, fpscr\n\t"
@@ -160,15 +165,125 @@
 		     : "r" (0), "r" (FPSCR_INIT));
 }
 
+/**
+ *	denormal_to_double - Given denormalized float number,
+ *	                     store double float
+ *
+ *	@fpu: Pointer to sh_fpu_hard structure
+ *	@n: Index to FP register
+ */
+static void
+denormal_to_double (struct sh_fpu_hard_struct *fpu, int n)
+{
+	unsigned long du, dl;
+	unsigned long x = fpu->fpul;
+	int exp = 1023 - 126;
+
+	if (x != 0 && (x & 0x7f800000) == 0) {
+		du = (x & 0x80000000);
+		while ((x & 0x00800000) == 0) {
+			x <<= 1;
+			exp--;
+		}
+		x &= 0x007fffff;
+		du |= (exp << 20) | (x >> 3);
+		dl = x << 29;
+
+		fpu->fp_regs[n] = du;
+		fpu->fp_regs[n+1] = dl;
+	}
+}
+
+/**
+ *	ieee_fpe_handler - Handle denormalized number exception
+ *
+ *	@regs: Pointer to register structure
+ *
+ *	Returns 1 when it's handled (should not cause exception).
+ */
+static int
+ieee_fpe_handler (struct pt_regs *regs)
+{
+	unsigned short insn = *(unsigned short *) regs->pc;
+	unsigned short finsn;
+	unsigned long nextpc;
+	int nib[4] = {
+		(insn >> 12) & 0xf,
+		(insn >> 8) & 0xf,
+		(insn >> 4) & 0xf,
+		insn & 0xf};
+
+	if (nib[0] == 0xb ||
+	    (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */
+		regs->pr = regs->pc + 4;
+  
+	if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */
+		nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3);
+		finsn = *(unsigned short *) (regs->pc + 2);
+	} else if (nib[0] == 0x8 && nib[1] == 0xd) { /* bt/s */
+		if (regs->sr & 1)
+			nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1);
+		else
+			nextpc = regs->pc + 4;
+		finsn = *(unsigned short *) (regs->pc + 2);
+	} else if (nib[0] == 0x8 && nib[1] == 0xf) { /* bf/s */
+		if (regs->sr & 1)
+			nextpc = regs->pc + 4;
+		else
+			nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1);
+		finsn = *(unsigned short *) (regs->pc + 2);
+	} else if (nib[0] == 0x4 && nib[3] == 0xb &&
+		 (nib[2] == 0x0 || nib[2] == 0x2)) { /* jmp & jsr */
+		nextpc = regs->regs[nib[1]];
+		finsn = *(unsigned short *) (regs->pc + 2);
+	} else if (nib[0] == 0x0 && nib[3] == 0x3 &&
+		 (nib[2] == 0x0 || nib[2] == 0x2)) { /* braf & bsrf */
+		nextpc = regs->pc + 4 + regs->regs[nib[1]];
+		finsn = *(unsigned short *) (regs->pc + 2);
+	} else if (insn == 0x000b) { /* rts */
+		nextpc = regs->pr;
+		finsn = *(unsigned short *) (regs->pc + 2);
+	} else {
+		nextpc = regs->pc + 2;
+		finsn = insn;
+	}
+
+	if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */
+		struct task_struct *tsk = current;
+
+		save_fpu(tsk);
+		if ((tsk->thread.fpu.hard.fpscr & (1 << 17))) {
+			/* FPU error */
+			denormal_to_double (&tsk->thread.fpu.hard,
+					    (finsn >> 8) & 0xf);
+			tsk->thread.fpu.hard.fpscr &=
+				~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
+			grab_fpu();
+			restore_fpu(tsk);
+			tsk->flags |= PF_USEDFPU;
+		} else {
+			tsk->thread.trap_no = 11;
+			tsk->thread.error_code = 0;
+			force_sig(SIGFPE, tsk);
+		}
+
+		regs->pc = nextpc;
+		return 1;
+	}
+
+	return 0;
+}
+
 asmlinkage void
 do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7,
 	     struct pt_regs regs)
 {
 	struct task_struct *tsk = current;
 
-	regs.pc += 2;
+	if (ieee_fpe_handler (&regs))
+		return;
 
-	grab_fpu();
+	regs.pc += 2;
 	save_fpu(tsk);
 	tsk->thread.trap_no = 11;
 	tsk->thread.error_code = 0;
@@ -181,102 +296,12 @@
 {
 	struct task_struct *tsk = current;
 
-	if (!user_mode(&regs)) {
-		if (tsk != &init_task) {
-			unlazy_fpu(tsk);
-		}
-		tsk = &init_task;
-		if (tsk->flags & PF_USEDFPU) {
-			/*
-			 * This weird situation can be occurred.
-			 *
-			 * There's race condition in __cli:
-			 *
-			 *   (1) SR --> register
-			 *   (2) Set IMASK of register
-			 *   (3) SR <-- register
-			 *
-			 * Between (1) and (2), or (2) and (3) getting
-			 * interrupt, and interrupt handler (or
-			 * softirq) may use FPU.
-			 *
-			 * Then, SR.FD is overwritten by (3).
-			 *
-			 * This results init_task.PF_USEDFPU is on,
-			 * with SR.FD == 1.
-			 *
-			 */
-			release_fpu();
-			return;
-		}
-	}
-
 	grab_fpu();
-	if (tsk->used_math) {
-		/* Using the FPU again.  */
-		restore_fpu(tsk);
-	} else	{
-		/* First time FPU user.  */
-		fpu_init();
-		tsk->used_math = 1;
-	}
-	tsk->flags |= PF_USEDFPU;
-	release_fpu();
-}
-
-/*
- * Change current FD flag to set FD flag back to exception
- */
-asmlinkage void
-fpu_prepare_fd(unsigned long sr, unsigned long r5, unsigned long r6,
-	       unsigned long r7, struct pt_regs regs)
-{
-	__cli();
 	if (!user_mode(&regs)) {
-		if (init_task.flags & PF_USEDFPU)
-			grab_fpu();
-		else {
-			if (!(sr & SR_FD)) {
-				BUG();
-				release_fpu();
-			}
-		}
+		printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
 		return;
 	}
 
-	if (sr & SR_FD) { /* Kernel doesn't grab FPU */
-		if (current->flags & PF_USEDFPU)
-			grab_fpu();
-		else {
-			if (init_task.flags & PF_USEDFPU) {
-				/*
-				 * This weird situation can be occurred.
-				 * See the comment in do_fpu_state_restore.
-				 */
-				grab_fpu();
-				save_fpu(&init_task);
-			}
-		}
-	} else {
-		if (init_task.flags & PF_USEDFPU)
-			save_fpu(&init_task);
-		else {
-			BUG();
-			release_fpu();
-		}
-	}
-}
-
-/* Short cut for the FPU exception */
-asmlinkage void
-enable_fpu_in_danger(void)
-{
-	struct task_struct *tsk = current;
-
-	if (tsk != &init_task)
-		unlazy_fpu(tsk);
-
-	tsk = &init_task;
 	if (tsk->used_math) {
 		/* Using the FPU again.  */
 		restore_fpu(tsk);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/head.S linux-2.4.22-pre10/arch/sh/kernel/head.S
--- linux-2.4.21/arch/sh/kernel/head.S	2001-01-29 02:56:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/head.S	2003-08-01 13:33:02.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.17 2000/03/06 12:44:24 gniibe Exp $
+/* $Id: head.S,v 1.1.1.1.2.1 2002/01/25 00:51:42 gniibe Exp $
  *
  *  arch/sh/kernel/head.S
  *
@@ -50,12 +50,6 @@
 	sub	r1, r0		!
 	ldc	r0, r7_bank	! ... and init_task
 	!
-#if defined(__SH4__)
-	!                       Initialize fpu
-	mov.l   7f, r0
-	jsr     @r0
-	 nop
-#endif
 	!			Enable cache
 	mov.l	6f, r0
 	jsr	@r0
@@ -74,12 +68,9 @@
 	 nop
 
 	.balign 4
-1:	.long	0x400000F0		! MD=1, RB=0, BL=0, FD=0, IMASK=0xF
+1:	.long	0x400080F0		! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
 2:	.long	SYMBOL_NAME(stack)
 3:	.long	SYMBOL_NAME(__bss_start)
 4:	.long	SYMBOL_NAME(_end)
 5:	.long	SYMBOL_NAME(start_kernel)
 6:	.long	SYMBOL_NAME(cache_init)
-#if defined(__SH4__)
-7:	.long   SYMBOL_NAME(fpu_init)
-#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/io_hs7729pci.c linux-2.4.22-pre10/arch/sh/kernel/io_hs7729pci.c
--- linux-2.4.21/arch/sh/kernel/io_hs7729pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/io_hs7729pci.c	2003-08-01 13:32:59.000000000 +0000
@@ -0,0 +1,338 @@
+/* $Id: io_hs7729pci.c,v 1.1.2.1 2003/06/24 08:45:47 dwmw2 Exp $
+ *
+ * linux/arch/sh/kernel/io_hs7729pci.c
+ *
+ * Copyright (C) 2000  Kazumoto Kojima
+ *
+ * I/O routine for Hitachi Semiconductor and Devices HS7729PCI.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/hitachi_hs7729pci.h>
+
+#include "pci-sd0001.h"
+
+#ifdef CONFIG_PCI
+#define io_is_pci(port) (port >= PCIBIOS_MIN_IO)
+#else
+#define io_is_pci(port) (0)
+#endif
+
+/* SH pcmcia io window base, start and end.  */
+int sh_pcic_io_wbase = 0xb8400000;
+int sh_pcic_io_start;
+int sh_pcic_io_stop;
+int sh_pcic_io_type;
+int sh_pcic_io_dummy;
+
+static inline void delay(void)
+{
+	ctrl_inw(0xa0000000);
+}
+
+/* MS7750 requires special versions of in*, out* routines, since
+   PC-like io ports are located at upper half byte of 16-bit word which
+   can be accessed only with 16-bit wide.  */
+
+static inline volatile __u16 *
+port2adr(unsigned long port)
+{
+	if (port >= 0x2000)
+		return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
+	else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
+		return (volatile __u16 *) (sh_pcic_io_wbase + (port &~ 1));
+	
+	else
+		return (volatile __u16 *) (PA_SUPERIO + (port << 1));
+}
+
+static inline int
+shifted_port(unsigned long port)
+{
+	/* For IDE registers, value is not shifted */
+	if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6 || 
+	    (0x170 <= port && port < 0x178) || port == 0x376 || 
+	    port >= 0x1000)
+		return 0;
+	else
+		return 1;
+}
+
+#define maybebadio(name,port) \
+  printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
+	 #name, (port), (__u32) __builtin_return_address(0))
+
+
+unsigned char hs7729pci_inb(unsigned long port)
+{
+	if (io_is_pci(port))
+		return sd0001_inb(port);
+	if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
+		return *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port); 
+	if (shifted_port(port))
+		return (*port2adr(port) >> 8); 
+#if defined(CONFIG_CF_ENABLER)
+	else if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
+		return *(__u8 *)(PA_MRSHPC_IO + port + 0x40000);
+#endif
+	else
+		return (*port2adr(port))&0xff; 
+}
+
+unsigned char hs7729pci_inb_p(unsigned long port)
+{
+	unsigned long v;
+
+	if (io_is_pci(port))
+		v =  sd0001_inb(port);
+	else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
+		v = *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port); 
+	else if (shifted_port(port))
+		v = (*port2adr(port) >> 8); 
+#if defined(CONFIG_CF_ENABLER)
+	else if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
+		v = *(__u8 *)(PA_MRSHPC_IO + port + 0x40000);
+#endif
+	else
+		v = (*port2adr(port))&0xff; 
+	delay();
+	return v;
+}
+
+unsigned short hs7729pci_inw(unsigned long port)
+{
+	if (io_is_pci(port))
+		return sd0001_inw(port);
+	if (port >= 0x2000 ||
+		 (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
+		return *port2adr(port);
+
+	maybebadio(inw, port);
+}
+
+unsigned int hs7729pci_inl(unsigned long port)
+{
+	if (io_is_pci(port))
+		return sd0001_inl(port);
+	else 
+		maybebadio(inl, port);
+}
+
+void hs7729pci_outb(unsigned char value, unsigned long port)
+{
+	if (io_is_pci(port))
+		sd0001_outb(value, port);
+	else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
+		*(__u8 *)(sh_pcic_io_wbase + port) = value; 
+	else if (shifted_port(port))
+		*(port2adr(port)) = value << 8;
+#if defined(CONFIG_CF_ENABLER)
+	else if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
+		*(__u8 *)(PA_MRSHPC_IO + port + 0x40000) = value;
+#endif
+	else
+		*(port2adr(port)) = value;
+}
+
+void hs7729pci_outb_p(unsigned char value, unsigned long port)
+{
+	if (io_is_pci(port))
+		sd0001_outb(value, port);
+	else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
+		*(__u8 *)(sh_pcic_io_wbase + port) = value; 
+	else if (shifted_port(port))
+		*(port2adr(port)) = value << 8;
+#if defined(CONFIG_CF_ENABLER)
+	else if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
+		*(__u8 *)(PA_MRSHPC_IO + port + 0x40000) = value;
+#endif
+	else
+		*(port2adr(port)) = value;
+	delay();
+}
+
+void hs7729pci_outw(unsigned short value, unsigned long port)
+{
+	if (io_is_pci(port))
+		sd0001_outw(value, port);
+	else if (port >= 0x2000 ||
+	    (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
+		*port2adr(port) = value;
+	else 
+		maybebadio(outw, port);
+}
+
+void hs7729pci_outl(unsigned int value, unsigned long port)
+{
+	if (io_is_pci(port))
+		sd0001_outl(value, port);
+	else
+		maybebadio(outl, port);
+}
+
+void hs7729pci_insb(unsigned long port, void *addr, unsigned long count)
+{
+	volatile __u16 *p = port2adr(port);
+
+	if (io_is_pci(port))
+		sd0001_insb(port, addr, count);
+	else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) {
+		volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + 0x40000 + port); 
+		while (count--)
+			*((__u8 *) addr)++ = *bp;
+	} else if (shifted_port(port)) {
+		while (count--)
+			*((__u8 *) addr)++ = *p >> 8;
+#if defined(CONFIG_CF_ENABLER)
+	} else if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) {
+		volatile __u8 *q = (__u8 *)(PA_MRSHPC_IO + port + 0x40000);
+		while (count--) {
+			*((__u8 *) addr)++ = *q;
+		}
+#endif
+	} else {
+		while (count--)
+			*((__u8 *) addr)++ = *p;
+
+	}
+}
+
+void hs7729pci_insw(unsigned long port, void *addr, unsigned long count)
+{
+	volatile __u16 *p;
+
+	 if (io_is_pci(port))
+		 return sd0001_insw(port, addr, count);
+#if defined(CONFIG_CF_ENABLER)
+	 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) {
+		p = (__u16 *)(PA_MRSHPC_IO + port);
+	 } else
+#endif
+		 p = port2adr(port);
+	 while (count--)
+		 *((__u16 *) addr)++ = *p;
+}
+
+void hs7729pci_insl(unsigned long port, void *addr, unsigned long count)
+{
+	if (io_is_pci(port))
+		sd0001_insl(port, addr, count);
+	else
+		maybebadio(insl, port);
+}
+
+void hs7729pci_outsb(unsigned long port, const void *addr, unsigned long count)
+{
+	volatile __u16 *p = port2adr(port);
+
+	if (io_is_pci(port)) {
+		sd0001_outsb(port, addr, count);
+		return;
+	}
+	if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) {
+		volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + port); 
+		while (count--)
+			*bp = *((__u8 *) addr)++;
+	} else if (shifted_port(port)) {
+		while (count--)
+			*p = *((__u8 *) addr)++ << 8;
+#if defined(CONFIG_CF_ENABLER)
+	} else if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) {
+		volatile __u8 *q = (__u8 *)(PA_MRSHPC_IO + port + 0x40000);
+		while (count--) {
+			*q = *((__u8 *) addr)++;
+		}
+#endif
+	} else while (count--)
+		*p = *((__u8 *) addr)++;
+}
+
+void hs7729pci_outsw(unsigned long port, const void *addr, unsigned long count)
+{
+	volatile __u16 *p;
+
+	if (io_is_pci(port)) {
+		sd0001_outsw(port, addr, count);
+		return;
+	}
+#if defined(CONFIG_CF_ENABLER)
+	if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) {
+		p = (__u16 *)(PA_MRSHPC_IO + port);
+	} else
+#endif
+		p = port2adr(port);
+	while (count--)
+		*p = *((__u16 *) addr)++;
+}
+
+void hs7729pci_outsl(unsigned long port, const void *addr, unsigned long count)
+{
+	if (io_is_pci(port))
+		sd0001_outsl(port, addr, count);
+	else
+		maybebadio(outsl, port);
+}
+
+/* Map ISA bus address to the real address. Only for PCMCIA.  */
+
+/* ISA page descriptor.  */
+static __u32 sh_isa_memmap[256];
+
+static int
+sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
+{
+	int idx;
+
+	if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
+		return -1;
+
+	idx = start >> 12;
+	sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
+#if 0
+	printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
+	       start, length, offset, idx, sh_isa_memmap[idx]);
+#endif
+	return 0;
+}
+
+unsigned long
+hs7729pci_isa_port2addr(unsigned long offset)
+{
+	int idx;
+
+	idx = (offset >> 12) & 0xff;
+	offset &= 0xfff;
+	return sh_isa_memmap[idx] + offset;
+}
+
+void *hs7729pci_ioremap(unsigned long phys_addr, unsigned long size)
+{
+        /* Don't allow wraparound or zero size */
+        if (!size || (phys_addr + size - 1) < phys_addr)
+                return NULL;
+
+#ifdef CONFIG_PCI
+	if (phys_addr >= PCIBIOS_MIN_MEM &&
+	    phys_addr < (PCIBIOS_MIN_MEM&0xfc000000)+0x03000000)
+		return sd0001_ioremap(phys_addr, size);
+#endif
+	   return (void *) P2SEGADDR(phys_addr);
+}
+
+void hs7729pci_iounmap(void *addr) 
+{
+#ifdef CONFIG_PCI
+	/* Ideally for cleanliness we'd have a better way of knowing
+	   if it came from the PCI controller. */
+	if ((unsigned long)addr >= VMALLOC_START && 
+	    (unsigned long)addr < VMALLOC_END)
+		sd0001_iounmap(addr);
+#endif
+}
+		
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/io_keywest.c linux-2.4.22-pre10/arch/sh/kernel/io_keywest.c
--- linux-2.4.21/arch/sh/kernel/io_keywest.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/io_keywest.c	2003-08-01 13:32:52.000000000 +0000
@@ -0,0 +1,330 @@
+/*
+ * linux/arch/sh/io_keywest.c
+ *
+ * IO functions for a Hitachi KeyWest Evaluation Board.
+ *
+ * Copyright (C) 2001 Lineo, Japan
+ *
+ * This file is subject to the terms and conditions of the GNU General Publi
+c
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+#include <asm/keywest.h>
+
+//#define KEYWEST_DEBUG 3
+#undef KEYWEST_DEBUG
+
+#ifdef KEYWEST_DEBUG
+#define DPRINTK(args...)	printk(args)
+#define DIPRINTK(n, args...)	if (KEYWEST_DEBUG>(n)) printk(args)
+#else
+#define DPRINTK(args...)
+#define DIPRINTK(n, args...)
+#endif
+
+
+/* Low iomap maps port 0-1K to addresses in 8byte chunks */
+#define KEYWEST_IOMAP_LO_THRESH 0x400
+#define KEYWEST_IOMAP_LO_SHIFT	3
+#define KEYWEST_IOMAP_LO_MASK	((1<<KEYWEST_IOMAP_LO_SHIFT)-1)
+#define KEYWEST_IOMAP_LO_NMAP	(KEYWEST_IOMAP_LO_THRESH>>KEYWEST_IOMAP_LO_SHIFT)
+static u32 keywest_iomap_lo[KEYWEST_IOMAP_LO_NMAP];
+static u8 keywest_iomap_lo_shift[KEYWEST_IOMAP_LO_NMAP];
+
+/* High iomap maps port 1K-64K to addresses in 1K chunks */
+#define KEYWEST_IOMAP_HI_THRESH 0x10000
+#define KEYWEST_IOMAP_HI_SHIFT	10
+#define KEYWEST_IOMAP_HI_MASK	((1<<KEYWEST_IOMAP_HI_SHIFT)-1)
+#define KEYWEST_IOMAP_HI_NMAP	(KEYWEST_IOMAP_HI_THRESH>>KEYWEST_IOMAP_HI_SHIFT)
+static u32 keywest_iomap_hi[KEYWEST_IOMAP_HI_NMAP];
+static u8 keywest_iomap_hi_shift[KEYWEST_IOMAP_HI_NMAP];
+
+#ifndef MAX
+#define MAX(a,b)    ((a)>(b)?(a):(b))
+#endif
+
+#define PORT2ADDR(x) keywest_isa_port2addr(x)
+//#define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
+//#define PORT2ADDR(x) (x)
+
+void keywest_port_map(u32 baseport, u32 nports, u32 addr, u8 shift)
+{
+    u32 port, endport = baseport + nports;
+
+    DPRINTK("keywest_port_map(base=0x%0x, n=0x%0x, addr=0x%08x)\n",
+	    baseport, nports, addr);
+	    
+	for (port = baseport ;
+	     port < endport && port < KEYWEST_IOMAP_LO_THRESH ;
+	     port += (1<<KEYWEST_IOMAP_LO_SHIFT)) {
+	    	DPRINTK("    maplo[0x%x] = 0x%08x\n", port, addr);
+    	    keywest_iomap_lo[port>>KEYWEST_IOMAP_LO_SHIFT] = addr;
+    	    keywest_iomap_lo_shift[port>>KEYWEST_IOMAP_LO_SHIFT] = shift;
+	    	addr += (1<<(KEYWEST_IOMAP_LO_SHIFT));
+	}
+
+	for (port = MAX(baseport, KEYWEST_IOMAP_LO_THRESH) ;
+	     port < endport && port < KEYWEST_IOMAP_HI_THRESH ;
+	     port += (1<<KEYWEST_IOMAP_HI_SHIFT)) {
+	    	DPRINTK("    maphi[0x%x] = 0x%08x\n", port, addr);
+    	    keywest_iomap_hi[port>>KEYWEST_IOMAP_HI_SHIFT] = addr;
+    	    keywest_iomap_hi_shift[port>>KEYWEST_IOMAP_HI_SHIFT] = shift;
+	    	addr += (1<<(KEYWEST_IOMAP_HI_SHIFT));
+	}
+}
+EXPORT_SYMBOL(keywest_port_map);
+
+void keywest_port_unmap(u32 baseport, u32 nports)
+{
+    u32 port, endport = baseport + nports;
+	
+    DPRINTK("keywest_port_unmap(base=0x%0x, n=0x%0x)\n", baseport, nports);
+
+	for (port = baseport ;
+	     port < endport && port < KEYWEST_IOMAP_LO_THRESH ;
+	     port += (1<<KEYWEST_IOMAP_LO_SHIFT)) {
+    	    keywest_iomap_lo[port>>KEYWEST_IOMAP_LO_SHIFT] = 0;
+	}
+
+	for (port = MAX(baseport, KEYWEST_IOMAP_LO_THRESH) ;
+	     port < endport && port < KEYWEST_IOMAP_HI_THRESH ;
+	     port += (1<<KEYWEST_IOMAP_HI_SHIFT)) {
+    	    keywest_iomap_hi[port>>KEYWEST_IOMAP_HI_SHIFT] = 0;
+	}
+}
+EXPORT_SYMBOL(keywest_port_unmap);
+
+unsigned long keywest_isa_port2addr(unsigned long port)
+{
+    unsigned long addr;
+	unsigned char shift;
+
+	/* Physical address not in P0, do nothing */
+	if (PXSEG(port))
+		return(port);
+
+	addr = 0;
+	/* physical address in P0, map to P2 */
+	if (port >= 0x30000)
+	    addr = P2SEGADDR(port);
+	/* Key West I/O + HD64465 registers 0x10000-0x30000 */
+	else if (port >= KEYWEST_IOMAP_HI_THRESH)
+	    addr = KEYWEST_INTERNAL_BASE + (port - KEYWEST_IOMAP_HI_THRESH);
+	/* Handle remapping of high IO/PCI IO ports */
+	else if (port >= KEYWEST_IOMAP_LO_THRESH) {
+	    addr = keywest_iomap_hi[port >> KEYWEST_IOMAP_HI_SHIFT];
+	    shift = keywest_iomap_hi_shift[port >> KEYWEST_IOMAP_HI_SHIFT];
+	    if (addr != 0)
+		    addr += (port & KEYWEST_IOMAP_HI_MASK) << shift;
+	}
+	/* Handle remapping of low IO ports */
+	else {
+	    addr = keywest_iomap_lo[port >> KEYWEST_IOMAP_LO_SHIFT];
+	    shift = keywest_iomap_lo_shift[port >> KEYWEST_IOMAP_LO_SHIFT];
+	    if (addr != 0)
+	    	addr += (port & KEYWEST_IOMAP_LO_MASK) << shift;
+	}
+
+    DIPRINTK(2, "PORT2ADDR(0x%08lx) = 0x%08lx\n", port, addr);
+
+	return addr;
+}
+
+static inline void delay(void)
+{
+	ctrl_inw(0xa0000000);
+}
+
+unsigned char keywest_inb(unsigned long port)
+{
+	unsigned long addr = PORT2ADDR(port);
+	unsigned long b = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
+
+	DIPRINTK(0, "inb(%08lx) = %02x\n", addr, (unsigned)b);
+	return b;
+}
+
+unsigned char keywest_inb_p(unsigned long port)
+{
+    unsigned long v;
+	unsigned long addr = PORT2ADDR(port);
+
+	v = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
+	delay();
+	DIPRINTK(0, "inb_p(%08lx) = %02x\n", addr, (unsigned)v);
+	return v;
+}
+
+unsigned short keywest_inw(unsigned long port)
+{
+    unsigned long addr = PORT2ADDR(port);
+	unsigned long b = (addr == 0 ? 0 : *(volatile unsigned short*)addr);
+	DIPRINTK(0, "inw(%08lx) = %04lx\n", addr, b);
+	return b;
+}
+
+unsigned int keywest_inl(unsigned long port)
+{
+    unsigned long addr = PORT2ADDR(port);
+	unsigned int b = (addr == 0 ? 0 : *(volatile unsigned long*)addr);
+	DIPRINTK(0, "inl(%08lx) = %08x\n", addr, b);
+	return b;
+}
+
+void keywest_insb(unsigned long port, void *buffer, unsigned long count)
+{
+	unsigned char *buf=buffer;
+	while(count--) *buf++=inb(port);
+}
+
+void keywest_insw(unsigned long port, void *buffer, unsigned long count)
+{
+	unsigned short *buf=buffer;
+	while(count--) *buf++=inw(port);
+}
+
+void keywest_insl(unsigned long port, void *buffer, unsigned long count)
+{
+#if 0
+	unsigned long *buf=buffer;
+	while(count--) *buf++=inl(port);
+#else
+	union {
+		unsigned long l;
+		unsigned short s[2];
+		unsigned char c[4];
+	} align;
+	port = (((unsigned long)(port)) & 0xe0000000) ? port :
+			keywest_isa_port2addr(port);
+	switch (((unsigned long) buffer) & 0x3) {
+	case 0: {
+		register unsigned long *buf=buffer, *endp = buf + count;
+		while (buf < endp)
+			*buf++ = * (volatile unsigned long *) port;
+		break;
+		}
+	case 2: {
+		register unsigned short *buf=buffer, *endp = buf + (count << 1);
+		while (buf < endp) {
+			align.l = * (volatile unsigned long *) port;
+			*buf++ = align.s[0];
+			*buf++ = align.s[1];
+		}
+		break;
+		}
+	case 1:
+	case 3: {
+		register unsigned char *buf=buffer, *endp = buf + (count << 2);
+		while (buf < endp) {
+			align.l = * (volatile unsigned long *) port;
+			*buf++ = align.c[0];
+			*buf++ = align.c[1];
+			*buf++ = align.c[2];
+			*buf++ = align.c[3];
+		}
+		break;
+		}
+	}
+#endif
+}
+
+void keywest_outb(unsigned char b, unsigned long port)
+{
+	unsigned long addr = PORT2ADDR(port);
+
+	DIPRINTK(0, "outb(%02x, %08lx)\n", (unsigned)b, addr);
+	if (addr != 0)
+	    *(volatile unsigned char*)addr = b;
+}
+
+void keywest_outb_p(unsigned char b, unsigned long port)
+{
+	unsigned long addr = PORT2ADDR(port);
+
+	DIPRINTK(0, "outb_p(%02x, %08lx)\n", (unsigned)b, addr);
+    if (addr != 0)
+	    *(volatile unsigned char*)addr = b;
+	delay();
+}
+
+void keywest_outw(unsigned short b, unsigned long port)
+{
+	unsigned long addr = PORT2ADDR(port);
+	DIPRINTK(0, "outw(%04x, %08lx)\n", (unsigned)b, addr);
+	if (addr != 0)
+	    *(volatile unsigned short*)addr = b;
+}
+
+void keywest_outl(unsigned int b, unsigned long port)
+{
+	unsigned long addr = PORT2ADDR(port);
+	DIPRINTK(0, "outl(%08x, %08lx)\n", b, addr);
+	if (addr != 0)
+            *(volatile unsigned long*)addr = b;
+}
+
+void keywest_outsb(unsigned long port, const void *buffer, unsigned long count)
+{
+	const unsigned char *buf=buffer;
+	while(count--) outb(*buf++, port);
+}
+
+void keywest_outsw(unsigned long port, const void *buffer, unsigned long count)
+{
+	const unsigned short *buf=buffer;
+	while(count--) outw(*buf++, port);
+}
+
+void keywest_outsl(unsigned long port, const void *buffer, unsigned long count)
+{
+#if 0
+	const unsigned long *buf=buffer;
+	while(count--) outl(*buf++, port);
+#else
+	union {
+		unsigned long l;
+		unsigned short s[2];
+		unsigned char c[4];
+	} align;
+	port = (((unsigned long)(port)) & 0xe0000000) ? port :
+			keywest_isa_port2addr(port);
+	switch (((unsigned long) buffer) & 0x3) {
+	case 0: {
+		register unsigned long *buf=buffer, *endp = buf + count;
+		while (buf < endp)
+			* (volatile unsigned long *) port = *buf++;
+		break;
+		}
+	case 2: {
+		register unsigned short *buf=buffer, *endp = buf + (count << 1);
+		while (buf < endp) {
+			align.s[0] = *buf++;
+			align.s[1] = *buf++;
+			* (volatile unsigned long *) port = align.l;
+		}
+		break;
+		}
+	case 1:
+	case 3: {
+		register unsigned char *buf=buffer, *endp = buf + (count << 2);
+		while (buf < endp) {
+			align.c[0] = *buf++;
+			align.c[1] = *buf++;
+			align.c[2] = *buf++;
+			align.c[3] = *buf++;
+			* (volatile unsigned long *) port = align.l;
+		}
+		break;
+		}
+	}
+#endif
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/io_se.c linux-2.4.22-pre10/arch/sh/kernel/io_se.c
--- linux-2.4.21/arch/sh/kernel/io_se.c	2001-10-15 20:36:48.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/io_se.c	2003-08-01 13:30:36.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: io_se.c,v 1.12 2001/08/11 01:23:28 jzs Exp $
+/* $Id: io_se.c,v 1.1.1.1.2.1 2002/02/26 11:42:29 gniibe Exp $
  *
  * linux/arch/sh/kernel/io_se.c
  *
@@ -23,6 +23,7 @@
 static inline void delay(void)
 {
 	ctrl_inw(0xa0000000);
+	ctrl_inw(0xa0000000);
 }
 
 /* MS7750 requires special versions of in*, out* routines, since
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/io_shmse.c linux-2.4.22-pre10/arch/sh/kernel/io_shmse.c
--- linux-2.4.21/arch/sh/kernel/io_shmse.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/io_shmse.c	2003-08-01 13:32:48.000000000 +0000
@@ -0,0 +1,169 @@
+/*
+ * linux/arch/sh/kernel/io_shmse.c
+ *
+ * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
+ * Based largely on io_se.c
+ *
+ * I/O routine for SH-Mobile SolutionEngine.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/hitachi_shmse.h>
+#include <asm/addrspace.h>
+
+static inline void delay(void)
+{
+	ctrl_inw(0xac000000);
+	ctrl_inw(0xac000000);
+}
+
+#define maybebadio(name,port) \
+  printk("bad PC-like io %s for port 0x%lx at 0x%08lx\n", \
+	#name, (port), (volatile unsigned long) __builtin_return_address(0))
+
+unsigned char shmse_inb(unsigned long port)
+{
+	if (PXSEG(port)){
+		return *(volatile unsigned char *) port; 
+	}else{
+		maybebadio(inb, port);
+		return 0;
+	}
+}
+
+unsigned char shmse_inb_p(unsigned long port)
+{
+	unsigned char v;
+
+	if (PXSEG(port)){
+		v = *(volatile unsigned char *)port;
+	}else{
+		maybebadio(inb_p, port);
+		return 0;
+	}
+	delay();
+	return v;
+}
+
+unsigned short shmse_inw(unsigned long port)
+{
+	if (PXSEG(port)){
+		return *(volatile unsigned short *) port; 
+	}else{
+		maybebadio(inw, port);
+		return 0;
+	}
+}
+
+unsigned int shmse_inl(unsigned long port)
+{
+	if (PXSEG(port)){
+		return *(volatile unsigned short *) port; 
+	}else{
+		maybebadio(inl, port);
+		return 0;
+	}
+}
+
+void shmse_outb(unsigned char value, unsigned long port)
+{
+	if (PXSEG(port)){
+		*(volatile unsigned char *)port = value; 
+	}else{
+		maybebadio(outb, port);
+	}
+}
+
+void shmse_outb_p(unsigned char value, unsigned long port)
+{
+	if (PXSEG(port)){
+		*(volatile unsigned char *)port = value; 
+	}else{
+		maybebadio(outb_p, port);
+	}
+	delay();
+}
+
+void shmse_outw(unsigned short value, unsigned long port)
+{
+	if (PXSEG(port)){
+		*(volatile unsigned short *)port = value; 
+	}else{
+		maybebadio(outw, port);
+	}
+}
+
+void shmse_outl(unsigned int value, unsigned long port)
+{
+	if (PXSEG(port)){
+		*(volatile unsigned long *)port = value; 
+	}else{
+		maybebadio(outl, port);
+	}
+}
+
+void shmse_insb(unsigned long port, void *addr, unsigned long count)
+{
+	unsigned char *p = addr;
+	while (count--) *p++ = shmse_inb(port);
+}
+
+void shmse_insw(unsigned long port, void *addr, unsigned long count)
+{
+	unsigned short *p = addr;
+	while (count--) *p++ = shmse_inw(port);
+}
+
+void shmse_insl(unsigned long port, void *addr, unsigned long count)
+{
+	maybebadio(insl, port);
+}
+
+void shmse_outsb(unsigned long port, const void *addr, unsigned long count)
+{
+	unsigned char *p = (unsigned char *)addr;
+	while (count--) shmse_outb(*p++, port);
+}
+
+void shmse_outsw(unsigned long port, const void *addr, unsigned long count)
+{
+	unsigned short *p = (unsigned short *)addr;
+	while (count--) shmse_outw(*p++, port);
+}
+
+void shmse_outsl(unsigned long port, const void *addr, unsigned long count)
+{
+	maybebadio(outsw, port);
+}
+
+unsigned char shmse_readb(unsigned long addr)
+{
+	return *(volatile unsigned char*)addr;
+}
+
+unsigned short shmse_readw(unsigned long addr)
+{
+	return *(volatile unsigned short*)addr;
+}
+
+unsigned int shmse_readl(unsigned long addr)
+{
+	return *(volatile unsigned long*)addr;
+}
+
+void shmse_writeb(unsigned char b, unsigned long addr)
+{
+	*(volatile unsigned char*)addr = b;
+}
+
+void shmse_writew(unsigned short b, unsigned long addr)
+{
+	*(volatile unsigned short*)addr = b;
+}
+
+void shmse_writel(unsigned int b, unsigned long addr)
+{
+        *(volatile unsigned long*)addr = b;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/io_snapgear.c linux-2.4.22-pre10/arch/sh/kernel/io_snapgear.c
--- linux-2.4.21/arch/sh/kernel/io_snapgear.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/io_snapgear.c	2003-08-01 13:34:21.000000000 +0000
@@ -0,0 +1,299 @@
+/* 
+ * linux/arch/sh/kernel/io_7751se.c
+ *
+ * Copyright (C) 2002  David McCullough <davidm@snapgear.com>
+ * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
+ * Based largely on io_se.c.
+ *
+ * I/O routine for Hitachi 7751 SolutionEngine.
+ *
+ * Initial version only to support LAN access; some
+ * placeholder code from io_se.c left in with the
+ * expectation of later SuperIO and PCMCIA access.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+
+#include <asm/pci.h>
+#include <asm/pci-sh7751.h>
+
+#ifdef CONFIG_SH_SECUREEDGE5410
+unsigned short secureedge5410_ioport;
+#endif
+
+/*
+ * The SnapGear uses the built-in PCI controller (PCIC)
+ * of the 7751 processor
+ */ 
+
+#define PCIIOBR		(volatile long *)PCI_REG(SH7751_PCIIOBR)
+#define PCIMBR          (volatile long *)PCI_REG(SH7751_PCIMBR)
+#define PCI_IO_AREA	SH7751_PCI_IO_BASE
+#define PCI_MEM_AREA	SH7751_PCI_CONFIG_BASE
+
+
+#define PCI_IOMAP(adr)	(PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
+
+
+#define maybebadio(name,port) \
+  printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
+	 #name, (port), (__u32) __builtin_return_address(0))
+
+
+static inline void delay(void)
+{
+	ctrl_inw(0xa0000000);
+}
+
+
+static inline volatile __u16 *
+port2adr(unsigned int port)
+{
+#if 0
+	if (port >= 0x2000)
+		return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
+#endif
+	maybebadio(name,port);
+	return (volatile __u16*)port;
+}
+
+
+/* In case someone configures the kernel w/o PCI support: in that */
+/* scenario, don't ever bother to check for PCI-window addresses */
+
+/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
+#if defined(CONFIG_PCI)
+#define CHECK_SH7751_PCIIO(port) \
+  ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
+#else
+#define CHECK_SH7751_PCIIO(port) (0)
+#endif
+
+/*
+ * General outline: remap really low stuff [eventually] to SuperIO,
+ * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
+ * is mapped through the PCI IO window.  Stuff with high bits (PXSEG)
+ * should be way beyond the window, and is used  w/o translation for
+ * compatibility.
+ */
+
+unsigned char snapgear_inb(unsigned long port)
+{
+	if (PXSEG(port))
+		return *(volatile unsigned char *)port;
+	else if (CHECK_SH7751_PCIIO(port))
+		return *(volatile unsigned char *)PCI_IOMAP(port);
+	else
+		return (*port2adr(port))&0xff; 
+}
+
+
+unsigned char snapgear_inb_p(unsigned long port)
+{
+	unsigned char v;
+
+	if (PXSEG(port))
+		v = *(volatile unsigned char *)port;
+	else if (CHECK_SH7751_PCIIO(port))
+		v = *(volatile unsigned char *)PCI_IOMAP(port);
+	else
+		v = (*port2adr(port))&0xff; 
+	delay();
+	return v;
+}
+
+
+unsigned short snapgear_inw(unsigned long port)
+{
+	if (PXSEG(port))
+		return *(volatile unsigned short *)port;
+	else if (CHECK_SH7751_PCIIO(port))
+		return *(volatile unsigned short *)PCI_IOMAP(port);
+	else if (port >= 0x2000)
+		return *port2adr(port);
+	else
+		maybebadio(inw, port);
+	return 0;
+}
+
+
+unsigned int snapgear_inl(unsigned long port)
+{
+	if (PXSEG(port))
+		return *(volatile unsigned long *)port;
+	else if (CHECK_SH7751_PCIIO(port))
+		return *(volatile unsigned int *)PCI_IOMAP(port);
+	else if (port >= 0x2000)
+		return *port2adr(port);
+	else
+		maybebadio(inl, port);
+	return 0;
+}
+
+
+void snapgear_outb(unsigned char value, unsigned long port)
+{
+
+	if (PXSEG(port))
+		*(volatile unsigned char *)port = value;
+	else if (CHECK_SH7751_PCIIO(port))
+		*((unsigned char*)PCI_IOMAP(port)) = value;
+	else
+		*(port2adr(port)) = value;
+}
+
+
+void snapgear_outb_p(unsigned char value, unsigned long port)
+{
+	if (PXSEG(port))
+		*(volatile unsigned char *)port = value;
+	else if (CHECK_SH7751_PCIIO(port))
+		*((unsigned char*)PCI_IOMAP(port)) = value;
+	else
+		*(port2adr(port)) = value;
+	delay();
+}
+
+
+void snapgear_outw(unsigned short value, unsigned long port)
+{
+	if (PXSEG(port))
+		*(volatile unsigned short *)port = value;
+	else if (CHECK_SH7751_PCIIO(port))
+		*((unsigned short *)PCI_IOMAP(port)) = value;
+	else if (port >= 0x2000)
+		*port2adr(port) = value;
+	else
+		maybebadio(outw, port);
+}
+
+
+void snapgear_outl(unsigned int value, unsigned long port)
+{
+	if (PXSEG(port))
+		*(volatile unsigned long *)port = value;
+	else if (CHECK_SH7751_PCIIO(port))
+		*((unsigned long*)PCI_IOMAP(port)) = value;
+	else
+		maybebadio(outl, port);
+}
+
+
+void snapgear_insb(unsigned long port, void *addr, unsigned long count)
+{
+	unsigned char *p = addr;
+	while (count--) *p++ = snapgear_inb(port);
+}
+
+
+void snapgear_insw(unsigned long port, void *addr, unsigned long count)
+{
+	unsigned short *p = addr;
+	while (count--) *p++ = snapgear_inw(port);
+}
+
+
+void snapgear_insl(unsigned long port, void *addr, unsigned long count)
+{
+	maybebadio(insl, port);
+}
+
+
+void snapgear_outsb(unsigned long port, const void *addr, unsigned long count)
+{
+	unsigned char *p = (unsigned char*)addr;
+	while (count--) snapgear_outb(*p++, port);
+}
+
+
+void snapgear_outsw(unsigned long port, const void *addr, unsigned long count)
+{
+	unsigned short *p = (unsigned short*)addr;
+	while (count--) snapgear_outw(*p++, port);
+}
+
+
+void snapgear_outsl(unsigned long port, const void *addr, unsigned long count)
+{
+	maybebadio(outsw, port);
+}
+
+
+/* For read/write calls, just copy generic (pass-thru); PCIMBR is  */
+/* already set up.  For a larger memory space, these would need to */
+/* reset PCIMBR as needed on a per-call basis...                   */
+
+unsigned char snapgear_readb(unsigned long addr)
+{
+	return (* ((volatile unsigned char *) addr));
+}
+
+
+unsigned short snapgear_readw(unsigned long addr)
+{
+	return (* ((volatile unsigned short *) addr));
+}
+
+
+unsigned int snapgear_readl(unsigned long addr)
+{
+	return (* ((volatile unsigned long *) addr));
+}
+
+
+void snapgear_writeb(unsigned char b, unsigned long addr)
+{
+	*(volatile unsigned char*)addr = b;
+}
+
+
+void snapgear_writew(unsigned short b, unsigned long addr)
+{
+	*(volatile unsigned short*)addr = b;
+}
+
+
+void snapgear_writel(unsigned int b, unsigned long addr)
+{
+	*(volatile unsigned long*)addr = b;
+}
+
+
+/* Map ISA bus address to the real address. Only for PCMCIA.  */
+
+
+/* ISA page descriptor.  */
+static __u32 sh_isa_memmap[256];
+
+
+static int
+sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
+{
+	int idx;
+
+	if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
+		return -1;
+
+	idx = start >> 12;
+	sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
+#if 0
+	printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
+	       start, length, offset, idx, sh_isa_memmap[idx]);
+#endif
+	return 0;
+}
+
+
+unsigned long
+snapgear_isa_port2addr(unsigned long offset)
+{
+	int idx;
+
+	idx = (offset >> 12) & 0xff;
+	offset &= 0xfff;
+	return sh_isa_memmap[idx] + offset;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/irq_ipr.c linux-2.4.22-pre10/arch/sh/kernel/irq_ipr.c
--- linux-2.4.21/arch/sh/kernel/irq_ipr.c	2001-09-08 19:29:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/irq_ipr.c	2003-08-01 13:32:39.000000000 +0000
@@ -1,15 +1,16 @@
-/* $Id: irq_ipr.c,v 1.20 2001/07/15 23:26:56 gniibe Exp $
+/* $Id: irq_ipr.c,v 1.1.1.1.2.1 2003/07/16 18:41:20 yoshii Exp $
  *
  * linux/arch/sh/kernel/irq_ipr.c
  *
  * Copyright (C) 1999  Niibe Yutaka & Takeshi Yaegashi
  * Copyright (C) 2000  Kazumoto Kojima
+ * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
  *
  * Interrupt handling for IPR-based IRQ.
  *
  * Supported system:
  *	On-chip supporting modules (TMU, RTC, etc.).
- *	On-chip supporting modules for SH7709/SH7709A/SH7729.
+ *	On-chip supporting modules for SH7300/SH7709/SH7709A/SH7729.
  *	Hitachi SolutionEngine external I/O:
  *		MS7709SE01, MS7709ASE01, and MS7750SE01
  *
@@ -88,7 +89,8 @@
 {
 	disable_ipr_irq(irq);
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
+#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7709)
 	/* This is needed when we use edge triggered setting */
 	/* XXX: Is it really needed? */
 	if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) {
@@ -196,7 +198,10 @@
 #endif
 
 	make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
+
+#if defined(CONFIG_SH_RTC)
 	make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
+#endif
 
 #ifdef SCI_ERI_IRQ
 	make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
@@ -211,6 +216,10 @@
 	make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
 #endif
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7300)
+	make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY);
+#endif
+
 #ifdef SCIF_ERI_IRQ
 	make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
 	make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
@@ -225,7 +234,8 @@
 	make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
 #endif
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
+#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7709)
 	/*
 	 * Initialize the Interrupt Controller (INTC)
 	 * registers to their power on values
@@ -242,6 +252,7 @@
 	make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY);
 	make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY);
 	make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY);
+#if !defined(CONFIG_CPU_SUBTYPE_SH7300)
 	make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY);
 	make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY);
 	enable_ipr_irq(PINT0_IRQ);
@@ -260,16 +271,19 @@
 		else if(i & 0x40) pint_map[i] = 6;
 		else if(i & 0x80) pint_map[i] = 7;
 	}
-#endif /* CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 */
+#endif
+#endif /* CONFIG_CPU_SUBTYPE_SH7300 || CONFIG_CPU_SUBTYPE_SH7707 || CONFIG_CPU_SUBTYPE_SH7709 */
 
 	/* Perform the machine specific initialisation */
 	if (sh_mv.mv_init_irq != NULL) {
 		sh_mv.mv_init_irq();
 	}
 }
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
+#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7707) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7709)
 int ipr_irq_demux(int irq)
 {
+#if !defined(CONFIG_CPU_SUBTYPE_SH7300)
 	unsigned long creg, dreg, d, sav;
 
 	if(irq == PINT0_IRQ)
@@ -304,6 +318,7 @@
 		if(d == 0) return irq;
 		return PINT_IRQ_BASE + 8 + pint_map[d];
 	}
+#endif
 	return irq;
 }
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/kgdb_jmp.S linux-2.4.22-pre10/arch/sh/kernel/kgdb_jmp.S
--- linux-2.4.21/arch/sh/kernel/kgdb_jmp.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/kgdb_jmp.S	2003-08-01 13:32:16.000000000 +0000
@@ -0,0 +1,33 @@
+#include <linux/linkage.h>
+
+ENTRY(kgdb_setjmp)
+	add	#(9*4), r4
+	sts.l	pr, @-r4
+	mov.l	r15, @-r4
+	mov.l	r14, @-r4
+	mov.l	r13, @-r4
+	mov.l	r12, @-r4
+	mov.l	r11, @-r4
+	mov.l	r10, @-r4
+	mov.l	r9, @-r4
+	mov.l	r8, @-r4
+	rts
+	 mov	#0, r0
+
+ENTRY(kgdb_longjmp)
+	mov.l	@r4+, r8
+	mov.l	@r4+, r9
+	mov.l	@r4+, r10
+	mov.l	@r4+, r11
+	mov.l	@r4+, r12
+	mov.l	@r4+, r13
+	mov.l	@r4+, r14
+	mov.l	@r4+, r15
+	lds.l	@r4+, pr
+	mov	r5, r0
+	tst	r0, r0
+	bf	1f
+	mov	#1, r0	! in case val==0
+1:	rts
+	 nop
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/kgdb_stub.c linux-2.4.22-pre10/arch/sh/kernel/kgdb_stub.c
--- linux-2.4.21/arch/sh/kernel/kgdb_stub.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/kgdb_stub.c	2003-08-01 13:34:44.000000000 +0000
@@ -0,0 +1,1488 @@
+/*
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Contains extracts from code by Glenn Engel, Jim Kingdon,
+ * David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>,
+ * Amit S. Kale <akale@veritas.com>,  William Gatliff <bgat@open-widgets.com>,
+ * Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>.
+ * 
+ * This version by Henry Bell <henry.bell@st.com>
+ * Minor modifications by Jeremy Siegel <jsiegel@mvista.com>
+ * 
+ * Contains low-level support for remote debug using GDB. 
+ *
+ * To enable debugger support, two things need to happen. A call to
+ * set_debug_traps() is necessary in order to allow any breakpoints
+ * or error conditions to be properly intercepted and reported to gdb.
+ * A breakpoint also needs to be generated to begin communication.  This
+ * is most easily accomplished by a call to breakpoint() which does
+ * a trapa if the initialisation phase has been successfully completed.
+ *
+ * In this case, set_debug_traps() is not used to "take over" exceptions;
+ * other kernel code is modified instead to enter the kgdb functions here
+ * when appropriate (see entry.S for breakpoint traps and NMI interrupts,
+ * see traps.c for kernel error exceptions).
+ *
+ * The following gdb commands are supported:
+ *
+ *    Command       Function                               Return value
+ *
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ *
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
+ *    XAA..AA,LLLL: Same, but data is binary (not hex)     OK or ENN
+ *
+ *    c             Resume at current address              SNN   ( signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ *    CNN;          Resume at current address with signal  SNN
+ *    CNN;AA..AA    Resume at address AA..AA with signal   SNN
+ *
+ *    s             Step one instruction                   SNN
+ *    sAA..AA       Step one instruction from AA..AA       SNN
+ *    SNN;          Step one instruction with signal       SNN
+ *    SNNAA..AA     Step one instruction from AA..AA w/NN  SNN
+ *
+ *    k             kill (Detach GDB)
+ *
+ *    d             Toggle debug flag
+ *    D             Detach GDB 
+ *
+ *    Hct           Set thread t for operations,           OK or ENN
+ *                  c = 'c' (step, cont), c = 'g' (other
+ *                  operations)
+ *
+ *    qC            Query current thread ID                QCpid
+ *    qfThreadInfo  Get list of current threads (first)    m<id>
+ *    qsThreadInfo   "    "  "     "      "   (subsequent)
+ *    qOffsets      Get section offsets                  Text=x;Data=y;Bss=z
+ * 
+ *    TXX           Find if thread XX is alive             OK or ENN
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ *    O             Output to GDB console
+ *
+ * Remote communication protocol.
+ *
+ *    A debug packet whose contents are <data> is encapsulated for
+ *    transmission in the form:
+ *
+ *       $ <data> # CSUM1 CSUM2
+ *
+ *       <data> must be ASCII alphanumeric and cannot include characters
+ *       '$' or '#'.  If <data> starts with two characters followed by
+ *       ':', then the existing stubs interpret this as a sequence number.
+ *
+ *       CSUM1 and CSUM2 are ascii hex representation of an 8-bit 
+ *       checksum of <data>, the most significant nibble is sent first.
+ *       the hex digits 0-9,a-f are used.
+ *
+ *    Receiver responds with:
+ *
+ *       +       - if CSUM is correct and ready for next packet
+ *       -       - if CSUM is incorrect
+ *
+ * Responses can be run-length encoded to save space.  A '*' means that
+ * the next character is an ASCII encoding giving a repeat count which
+ * stands for that many repititions of the character preceding the '*'.
+ * The encoding is n+29, yielding a printable character where n >=3 
+ * (which is where RLE starts to win).  Don't use an n > 126. 
+ *
+ * So "0* " means the same as "0000".
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/current.h>
+#include <asm/signal.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+#include <asm/kgdb.h>
+
+#ifdef CONFIG_SH_KGDB_CONSOLE
+#include <linux/console.h>
+#endif
+
+/* Function pointers for linkage */
+kgdb_debug_hook_t *kgdb_debug_hook;
+kgdb_bus_error_hook_t *kgdb_bus_err_hook;
+
+int (*kgdb_getchar)(void);
+void (*kgdb_putchar)(int);
+
+static void put_debug_char(int c)
+{
+	if (!kgdb_putchar)
+		return;
+	(*kgdb_putchar)(c);
+}
+static int get_debug_char(void)
+{
+	if (!kgdb_getchar)
+		return -1;
+	return (*kgdb_getchar)();
+}
+
+/* Num chars in in/out bound buffers, register packets need NUMREGBYTES * 2 */
+#define BUFMAX 1024
+#define NUMREGBYTES (MAXREG*4)
+#define OUTBUFMAX (NUMREGBYTES*2+512)
+
+enum regs {
+	R0 = 0, R1,  R2,  R3,   R4,   R5,  R6, R7,
+	R8, R9, R10, R11, R12,  R13,  R14, R15,
+	PC, PR, GBR, VBR, MACH, MACL, SR,
+	/*  */
+	MAXREG
+};
+
+static unsigned int registers[MAXREG];
+struct kgdb_regs trap_registers;
+
+char kgdb_in_gdb_mode;
+char in_nmi;			/* Set during NMI to prevent reentry */
+int kgdb_nofault;		/* Boolean to ignore bus errs (i.e. in GDB) */
+int kgdb_enabled = 1;		/* Default to enabled, cmdline can disable */
+int kgdb_halt;
+
+/* Exposed for user access */
+struct task_struct *kgdb_current;
+unsigned int kgdb_g_imask;
+int kgdb_trapa_val;
+int kgdb_excode;
+struct pt_regs *kgdb_tregs;
+
+/* Default values for SCI (can override via kernel args in setup.c) */
+#ifndef CONFIG_KGDB_DEFPORT
+#define CONFIG_KGDB_DEFPORT 1
+#endif
+
+#ifndef CONFIG_KGDB_DEFBAUD
+#define CONFIG_KGDB_DEFBAUD 115200
+#endif
+
+#if defined(CONFIG_KGDB_DEFPARITY_E)
+#define CONFIG_KGDB_DEFPARITY 'E'
+#elif defined(CONFIG_KGDB_DEFPARITY_O)
+#define CONFIG_KGDB_DEFPARITY 'O'
+#else /* CONFIG_KGDB_DEFPARITY_N */
+#define CONFIG_KGDB_DEFPARITY 'N'
+#endif
+
+#ifdef CONFIG_KGDB_DEFBITS_7
+#define CONFIG_KGDB_DEFBITS '7'
+#else /* CONFIG_KGDB_DEFBITS_8 */
+#define CONFIG_KGDB_DEFBITS '8'
+#endif
+
+/* SCI/UART settings, used in kgdb_serial_setup() */
+int (*kgdb_serial_setup)(void) = kgdb_sci_setup;
+int  kgdb_portnum = CONFIG_KGDB_DEFPORT;
+int  kgdb_baud = CONFIG_KGDB_DEFBAUD;
+char kgdb_parity = CONFIG_KGDB_DEFPARITY;
+char kgdb_bits = CONFIG_KGDB_DEFBITS;
+int  kgdb_cflag;
+
+/* Jump buffer for setjmp/longjmp */
+static jmp_buf rem_com_env;
+
+/* TRA differs sh3/4 */
+#if defined(__sh3__)
+#define TRA 0xffffffd0
+#elif defined(__SH4__)
+#define TRA 0xff000020
+#endif
+
+/* Macros for single step instruction identification */
+#define OPCODE_BT(op)         (((op) & 0xff00) == 0x8900)
+#define OPCODE_BF(op)         (((op) & 0xff00) == 0x8b00)
+#define OPCODE_BTF_DISP(op)   (((op) & 0x80) ? (((op) | 0xffffff80) << 1) : \
+			      (((op) & 0x7f ) << 1))
+#define OPCODE_BFS(op)        (((op) & 0xff00) == 0x8f00)
+#define OPCODE_BTS(op)        (((op) & 0xff00) == 0x8d00)
+#define OPCODE_BRA(op)        (((op) & 0xf000) == 0xa000)
+#define OPCODE_BRA_DISP(op)   (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
+			      (((op) & 0x7ff) << 1))
+#define OPCODE_BRAF(op)       (((op) & 0xf0ff) == 0x0023)
+#define OPCODE_BRAF_REG(op)   (((op) & 0x0f00) >> 8)
+#define OPCODE_BSR(op)        (((op) & 0xf000) == 0xb000)
+#define OPCODE_BSR_DISP(op)   (((op) & 0x800) ? (((op) | 0xfffff800) << 1) : \
+			      (((op) & 0x7ff) << 1))
+#define OPCODE_BSRF(op)       (((op) & 0xf0ff) == 0x0003)
+#define OPCODE_BSRF_REG(op)   (((op) >> 8) & 0xf)
+#define OPCODE_JMP(op)        (((op) & 0xf0ff) == 0x402b)
+#define OPCODE_JMP_REG(op)    (((op) >> 8) & 0xf)
+#define OPCODE_JSR(op)        (((op) & 0xf0ff) == 0x400b)
+#define OPCODE_JSR_REG(op)    (((op) >> 8) & 0xf)
+#define OPCODE_RTS(op)        ((op) == 0xb)
+#define OPCODE_RTE(op)        ((op) == 0x2b)
+
+#define SR_T_BIT_MASK           0x1
+#define STEP_OPCODE             0xc320
+#define BIOS_CALL_TRAP          0x3f
+
+/* Exception codes as per SH-4 core manual */
+#define ADDRESS_ERROR_LOAD_VEC   7
+#define ADDRESS_ERROR_STORE_VEC  8
+#define TRAP_VEC                 11
+#define INVALID_INSN_VEC         12
+#define INVALID_SLOT_VEC         13
+#define NMI_VEC                  14
+#define USER_BREAK_VEC           15
+#define SERIAL_BREAK_VEC         58
+
+/* Misc static */
+static int stepped_address;
+static short stepped_opcode;
+static const char hexchars[] = "0123456789abcdef";
+static char in_buffer[BUFMAX];
+static char out_buffer[OUTBUFMAX];
+
+static void kgdb_to_gdb(const char *s);
+
+#ifdef CONFIG_KGDB_THREAD
+static struct task_struct *trapped_thread;
+static struct task_struct *current_thread;
+typedef unsigned char threadref[8];
+#define BUF_THREAD_ID_SIZE 16
+#endif
+
+/* Return addr as a real volatile address */
+static inline unsigned int ctrl_inl(const unsigned long addr)
+{
+	return *(volatile unsigned long *) addr;
+}
+
+/* Correctly set *addr using volatile */
+static inline void ctrl_outl(const unsigned int b, unsigned long addr)
+{
+	*(volatile unsigned long *) addr = b;
+}
+
+/* Get high hex bits */
+static char highhex(const int x)
+{
+	return hexchars[(x >> 4) & 0xf];
+}
+
+/* Get low hex bits */
+static char lowhex(const int x)
+{
+	return hexchars[x & 0xf];
+}
+
+/* Convert ch to hex */
+static int hex(const char ch)
+{
+	if ((ch >= 'a') && (ch <= 'f'))
+		return (ch - 'a' + 10);
+	if ((ch >= '0') && (ch <= '9'))
+		return (ch - '0');
+	if ((ch >= 'A') && (ch <= 'F'))
+		return (ch - 'A' + 10);
+	return (-1);
+}
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+   Returns a pointer to the last char put in buf (null) */
+static char *mem_to_hex(const char *mem, char *buf, const int count)
+{
+	int i;
+	int ch;
+	unsigned short s_val;
+	unsigned long l_val;
+
+	/* Check for 16 or 32 */
+	if (count == 2 && ((long) mem & 1) == 0) {
+		s_val = *(unsigned short *) mem;
+		mem = (char *) &s_val;
+	} else if (count == 4 && ((long) mem & 3) == 0) {
+		l_val = *(unsigned long *) mem;
+		mem = (char *) &l_val;
+	}
+	for (i = 0; i < count; i++) {
+		ch = *mem++;
+		*buf++ = highhex(ch);
+		*buf++ = lowhex(ch);
+	}
+	*buf = 0;
+	return (buf);
+}
+
+/* Convert the hex array pointed to by buf into binary, to be placed in mem.
+   Return a pointer to the character after the last byte written */
+static char *hex_to_mem(const char *buf, char *mem, const int count)
+{
+	int i;
+	unsigned char ch;
+
+	for (i = 0; i < count; i++) {
+		ch = hex(*buf++) << 4;
+		ch = ch + hex(*buf++);
+		*mem++ = ch;
+	}
+	return (mem);
+}
+
+/* While finding valid hex chars, convert to an integer, then return it */
+static int hex_to_int(char **ptr, int *int_value)
+{
+	int num_chars = 0;
+	int hex_value;
+
+	*int_value = 0;
+
+	while (**ptr) {
+		hex_value = hex(**ptr);
+		if (hex_value >= 0) {
+			*int_value = (*int_value << 4) | hex_value;
+			num_chars++;
+		} else
+			break;
+		(*ptr)++;
+	}
+	return num_chars;
+}
+
+/*  Copy the binary array pointed to by buf into mem.  Fix $, #,
+    and 0x7d escaped with 0x7d.  Return a pointer to the character 
+    after the last byte written. */
+static char *ebin_to_mem(const char *buf, char *mem, int count)
+{
+	for (; count > 0; count--, buf++) {
+		if (*buf == 0x7d)
+			*mem++ = *(++buf) ^ 0x20;
+		else
+			*mem++ = *buf;
+	}
+	return mem;
+}
+
+/* Pack a hex byte */
+static char *pack_hex_byte(char *pkt, int byte)
+{
+	*pkt++ = hexchars[(byte >> 4) & 0xf];
+	*pkt++ = hexchars[(byte & 0xf)];
+	return pkt;
+}
+
+#ifdef CONFIG_KGDB_THREAD
+
+/* Pack a thread ID */
+static char *pack_threadid(char *pkt, threadref * id)
+{
+	char *limit;
+	unsigned char *altid;
+
+	altid = (unsigned char *) id;
+
+	limit = pkt + BUF_THREAD_ID_SIZE;
+	while (pkt < limit)
+		pkt = pack_hex_byte(pkt, *altid++);
+	return pkt;
+}
+
+/* Convert an integer into our threadref */
+static void int_to_threadref(threadref * id, const int value)
+{
+	unsigned char *scan = (unsigned char *) id;
+	int i = 4;
+
+	while (i--)
+		*scan++ = 0;
+
+	*scan++ = (value >> 24) & 0xff;
+	*scan++ = (value >> 16) & 0xff;
+	*scan++ = (value >> 8) & 0xff;
+	*scan++ = (value & 0xff);
+}
+
+/* Return a task structure ptr for a particular pid */
+static struct task_struct *get_thread(int pid)
+{
+	struct task_struct *thread;
+
+	/* Use PID_MAX w/gdb for pid 0 */
+	if (pid == PID_MAX) pid = 0;
+
+	/* First check via PID */
+	thread = find_task_by_pid(pid);
+
+	if (thread)
+		return thread;
+
+	/* Start at the start */
+	thread = init_tasks[0];
+
+	/* Walk along the linked list of tasks */
+	do {
+		if (thread->pid == pid)
+			return thread;
+		thread = thread->next_task;
+	} while (thread != init_tasks[0]);
+
+	return NULL;
+}
+
+#endif /* CONFIG_KGDB_THREAD */
+
+/* Scan for the start char '$', read the packet and check the checksum */
+static void get_packet(char *buffer, int buflen)
+{
+	unsigned char checksum;
+	unsigned char xmitcsum;
+	int i;
+	int count;
+	char ch;
+
+	do {
+		/* Ignore everything until the start character */
+		while ((ch = get_debug_char()) != '$');
+
+		checksum = 0;
+		xmitcsum = -1;
+		count = 0;
+
+		/* Now, read until a # or end of buffer is found */
+		while (count < (buflen - 1)) {
+			ch = get_debug_char();
+
+			if (ch == '#')
+				break;
+
+			checksum = checksum + ch;
+			buffer[count] = ch;
+			count = count + 1;
+		}
+
+		buffer[count] = 0;
+
+		/* Continue to read checksum following # */
+		if (ch == '#') {
+			xmitcsum = hex(get_debug_char()) << 4;
+			xmitcsum += hex(get_debug_char());
+
+			/* Checksum */
+			if (checksum != xmitcsum)
+				put_debug_char('-');	/* Failed checksum */
+			else {
+				/* Ack successful transfer */
+				put_debug_char('+');
+
+				/* If a sequence char is present, reply 
+				   the sequence ID */
+				if (buffer[2] == ':') {
+					put_debug_char(buffer[0]);
+					put_debug_char(buffer[1]);
+
+					/* Remove sequence chars from buffer */
+					count = strlen(buffer);
+					for (i = 3; i <= count; i++)
+						buffer[i - 3] = buffer[i];
+				}
+			}
+		}
+	}
+	while (checksum != xmitcsum);	/* Keep trying while we fail */
+}
+
+/* Send the packet in the buffer with run-length encoding */
+static void put_packet(char *buffer)
+{
+	int checksum;
+	char *src;
+	int runlen;
+	int encode;
+
+	do {
+		src = buffer;
+		put_debug_char('$');
+		checksum = 0;
+
+		/* Continue while we still have chars left */
+		while (*src) {
+			/* Check for runs up to 99 chars long */
+			for (runlen = 1; runlen < 99; runlen++) {
+				if (src[0] != src[runlen])
+					break;
+			}
+
+			if (runlen > 3) {
+				/* Got a useful amount, send encoding */
+				encode = runlen + ' ' - 4;
+				put_debug_char(*src);   checksum += *src;
+				put_debug_char('*');    checksum += '*';
+				put_debug_char(encode); checksum += encode;
+				src += runlen;
+			} else {
+				/* Otherwise just send the current char */
+				put_debug_char(*src);   checksum += *src;
+				src += 1;
+			}
+		}
+
+		/* '#' Separator, put high and low components of checksum */
+		put_debug_char('#');
+		put_debug_char(highhex(checksum));
+		put_debug_char(lowhex(checksum));
+	}
+	while ((get_debug_char()) != '+');	/* While no ack */
+}
+
+/* A bus error has occurred - perform a longjmp to return execution and
+   allow handling of the error */
+static void kgdb_handle_bus_error(void)
+{
+	kgdb_longjmp(rem_com_env, 1);
+}
+
+/* Translate SH-3/4 exception numbers to unix-like signal values */
+static int compute_signal(const int excep_code)
+{
+	int sigval;
+
+	switch (excep_code) {
+
+	case INVALID_INSN_VEC:
+	case INVALID_SLOT_VEC:
+		sigval = SIGILL;
+		break;
+	case ADDRESS_ERROR_LOAD_VEC:
+	case ADDRESS_ERROR_STORE_VEC:
+		sigval = SIGSEGV;
+		break;
+
+	case SERIAL_BREAK_VEC:
+	case NMI_VEC:
+		sigval = SIGINT;
+		break;
+
+	case USER_BREAK_VEC:
+	case TRAP_VEC:
+		sigval = SIGTRAP;
+		break;
+
+	default:
+		sigval = SIGBUS;	/* "software generated" */
+		break;
+	}
+
+	return (sigval);
+}
+
+/* Make a local copy of the registers passed into the handler (bletch) */
+static void kgdb_regs_to_gdb_regs(const struct kgdb_regs *regs,
+				  int *gdb_regs)
+{
+	gdb_regs[R0] = regs->regs[R0];
+	gdb_regs[R1] = regs->regs[R1];
+	gdb_regs[R2] = regs->regs[R2];
+	gdb_regs[R3] = regs->regs[R3];
+	gdb_regs[R4] = regs->regs[R4];
+	gdb_regs[R5] = regs->regs[R5];
+	gdb_regs[R6] = regs->regs[R6];
+	gdb_regs[R7] = regs->regs[R7];
+	gdb_regs[R8] = regs->regs[R8];
+	gdb_regs[R9] = regs->regs[R9];
+	gdb_regs[R10] = regs->regs[R10];
+	gdb_regs[R11] = regs->regs[R11];
+	gdb_regs[R12] = regs->regs[R12];
+	gdb_regs[R13] = regs->regs[R13];
+	gdb_regs[R14] = regs->regs[R14];
+	gdb_regs[R15] = regs->regs[R15];
+	gdb_regs[PC] = regs->pc;
+	gdb_regs[PR] = regs->pr;
+	gdb_regs[GBR] = regs->gbr;
+	gdb_regs[MACH] = regs->mach;
+	gdb_regs[MACL] = regs->macl;
+	gdb_regs[SR] = regs->sr;
+	gdb_regs[VBR] = regs->vbr;
+}
+
+/* Copy local gdb registers back to kgdb regs, for later copy to kernel */
+static void gdb_regs_to_kgdb_regs(const int *gdb_regs,
+				  struct kgdb_regs *regs)
+{
+	regs->regs[R0] = gdb_regs[R0];
+	regs->regs[R1] = gdb_regs[R1];
+	regs->regs[R2] = gdb_regs[R2];
+	regs->regs[R3] = gdb_regs[R3];
+	regs->regs[R4] = gdb_regs[R4];
+	regs->regs[R5] = gdb_regs[R5];
+	regs->regs[R6] = gdb_regs[R6];
+	regs->regs[R7] = gdb_regs[R7];
+	regs->regs[R8] = gdb_regs[R8];
+	regs->regs[R9] = gdb_regs[R9];
+	regs->regs[R10] = gdb_regs[R10];
+	regs->regs[R11] = gdb_regs[R11];
+	regs->regs[R12] = gdb_regs[R12];
+	regs->regs[R13] = gdb_regs[R13];
+	regs->regs[R14] = gdb_regs[R14];
+	regs->regs[R15] = gdb_regs[R15];
+	regs->pc = gdb_regs[PC];
+	regs->pr = gdb_regs[PR];
+	regs->gbr = gdb_regs[GBR];
+	regs->mach = gdb_regs[MACH];
+	regs->macl = gdb_regs[MACL];
+	regs->sr = gdb_regs[SR];
+	regs->vbr = gdb_regs[VBR];
+}
+
+#ifdef CONFIG_KGDB_THREAD
+/* Make a local copy of registers from the specified thread */
+asmlinkage void ret_from_fork(void);
+static void thread_regs_to_gdb_regs(const struct task_struct *thread,
+				    int *gdb_regs)
+{
+	int regno;
+	int *tregs;
+
+	/* Initialize to zero */
+	for (regno = 0; regno < MAXREG; regno++)
+		gdb_regs[regno] = 0;
+
+	/* Just making sure... */
+	if (thread == NULL)
+		return;
+
+	/* A new fork has pt_regs on the stack from a fork() call */
+	if (thread->thread.pc == (unsigned long)ret_from_fork) {
+
+		int vbr_val;
+		struct pt_regs *kregs;
+		kregs = (struct pt_regs*)thread->thread.sp;
+
+		gdb_regs[R0] = kregs->regs[R0];
+		gdb_regs[R1] = kregs->regs[R1];
+		gdb_regs[R2] = kregs->regs[R2];
+		gdb_regs[R3] = kregs->regs[R3];
+		gdb_regs[R4] = kregs->regs[R4];
+		gdb_regs[R5] = kregs->regs[R5];
+		gdb_regs[R6] = kregs->regs[R6];
+		gdb_regs[R7] = kregs->regs[R7];
+		gdb_regs[R8] = kregs->regs[R8];
+		gdb_regs[R9] = kregs->regs[R9];
+		gdb_regs[R10] = kregs->regs[R10];
+		gdb_regs[R11] = kregs->regs[R11];
+		gdb_regs[R12] = kregs->regs[R12];
+		gdb_regs[R13] = kregs->regs[R13];
+		gdb_regs[R14] = kregs->regs[R14];
+		gdb_regs[R15] = kregs->regs[R15];
+		gdb_regs[PC] = kregs->pc;
+		gdb_regs[PR] = kregs->pr;
+		gdb_regs[GBR] = kregs->gbr;
+		gdb_regs[MACH] = kregs->mach;
+		gdb_regs[MACL] = kregs->macl;
+		gdb_regs[SR] = kregs->sr;
+
+		asm("stc vbr, %0":"=r"(vbr_val));
+		gdb_regs[VBR] = vbr_val;
+		return;
+	}
+
+	/* Otherwise, we have only some registers from switch_to() */
+	tregs = (int *)thread->thread.sp;
+	gdb_regs[R15] = (int)tregs;
+	gdb_regs[R14] = *tregs++;
+	gdb_regs[R13] = *tregs++;
+	gdb_regs[R12] = *tregs++;
+	gdb_regs[R11] = *tregs++;
+	gdb_regs[R10] = *tregs++;
+	gdb_regs[R9] = *tregs++;
+	gdb_regs[R8] = *tregs++;
+	gdb_regs[PR] = *tregs++;
+	gdb_regs[GBR] = *tregs++;
+	gdb_regs[PC] = thread->thread.pc;
+}
+#endif /* CONFIG_KGDB_THREAD */
+
+/* Calculate the new address for after a step */
+static short *get_step_address(void)
+{
+	short op = *(short *) trap_registers.pc;
+	long addr;
+
+	/* BT */
+	if (OPCODE_BT(op)) {
+		if (trap_registers.sr & SR_T_BIT_MASK)
+			addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
+		else
+			addr = trap_registers.pc + 2;
+	}
+
+	/* BTS */
+	else if (OPCODE_BTS(op)) {
+		if (trap_registers.sr & SR_T_BIT_MASK)
+			addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
+		else
+			addr = trap_registers.pc + 4;	/* Not in delay slot */
+	}
+
+	/* BF */
+	else if (OPCODE_BF(op)) {
+		if (!(trap_registers.sr & SR_T_BIT_MASK))
+			addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
+		else
+			addr = trap_registers.pc + 2;
+	}
+
+	/* BFS */
+	else if (OPCODE_BFS(op)) {
+		if (!(trap_registers.sr & SR_T_BIT_MASK))
+			addr = trap_registers.pc + 4 + OPCODE_BTF_DISP(op);
+		else
+			addr = trap_registers.pc + 4;	/* Not in delay slot */
+	}
+
+	/* BRA */
+	else if (OPCODE_BRA(op))
+		addr = trap_registers.pc + 4 + OPCODE_BRA_DISP(op);
+
+	/* BRAF */
+	else if (OPCODE_BRAF(op))
+		addr = trap_registers.pc + 4
+		    + trap_registers.regs[OPCODE_BRAF_REG(op)];
+
+	/* BSR */
+	else if (OPCODE_BSR(op))
+		addr = trap_registers.pc + 4 + OPCODE_BSR_DISP(op);
+
+	/* BSRF */
+	else if (OPCODE_BSRF(op))
+		addr = trap_registers.pc + 4
+		    + trap_registers.regs[OPCODE_BSRF_REG(op)];
+
+	/* JMP */
+	else if (OPCODE_JMP(op))
+		addr = trap_registers.regs[OPCODE_JMP_REG(op)];
+
+	/* JSR */
+	else if (OPCODE_JSR(op))
+		addr = trap_registers.regs[OPCODE_JSR_REG(op)];
+
+	/* RTS */
+	else if (OPCODE_RTS(op))
+		addr = trap_registers.pr;
+
+	/* RTE */
+	else if (OPCODE_RTE(op))
+		addr = trap_registers.regs[15];
+
+	/* Other */
+	else
+		addr = trap_registers.pc + 2;
+
+	kgdb_flush_icache_range(addr, addr + 2);
+	return (short *) addr;
+}
+
+/* Set up a single-step.  Replace the instruction immediately after the 
+   current instruction (i.e. next in the expected flow of control) with a
+   trap instruction, so that returning will cause only a single instruction
+   to be executed. Note that this model is slightly broken for instructions
+   with delay slots (e.g. B[TF]S, BSR, BRA etc), where both the branch
+   and the instruction in the delay slot will be executed. */
+static void do_single_step(void)
+{
+	unsigned short *addr = 0;
+
+	/* Determine where the target instruction will send us to */
+	addr = get_step_address();
+	stepped_address = (int)addr;
+
+	/* Replace it */
+	stepped_opcode = *(short *)addr;
+	*addr = STEP_OPCODE;
+
+	/* Flush and return */
+	kgdb_flush_icache_range((long) addr, (long) addr + 2);
+	return;
+}
+
+/* Undo a single step */
+static void undo_single_step(void)
+{
+	/* If we have stepped, put back the old instruction */
+	/* Use stepped_address in case we stopped elsewhere */
+	if (stepped_opcode != 0) {
+		*(short*)stepped_address = stepped_opcode;
+		kgdb_flush_icache_range(stepped_address, stepped_address + 2);
+	}
+	stepped_opcode = 0;
+}
+
+/* Send a signal message */
+static void send_signal_msg(const int signum)
+{
+#ifndef CONFIG_KGDB_THREAD
+	out_buffer[0] = 'S';
+	out_buffer[1] = highhex(signum);
+	out_buffer[2] = lowhex(signum);
+	out_buffer[3] = 0;
+	put_packet(out_buffer);
+#else /* CONFIG_KGDB_THREAD */
+	int threadid;
+	threadref thref;
+	char *out = out_buffer;
+	const char *tstring = "thread";
+
+	*out++ = 'T';
+	*out++ = highhex(signum);
+	*out++ = lowhex(signum);
+
+	while (*tstring) {
+		*out++ = *tstring++;
+	}
+	*out++ = ':';
+
+	threadid = trapped_thread->pid;
+	if (threadid == 0) threadid = PID_MAX;
+	int_to_threadref(&thref, threadid);
+	pack_threadid(out, &thref);
+	out += BUF_THREAD_ID_SIZE;
+	*out++ = ';';
+
+	*out = 0;
+	put_packet(out_buffer);
+#endif /* CONFIG_KGDB_THREAD */
+}
+
+/* Reply that all was well */
+static void send_ok_msg(void)
+{
+	strcpy(out_buffer, "OK");
+	put_packet(out_buffer);
+}
+
+/* Reply that an error occurred */
+static void send_err_msg(void)
+{
+	strcpy(out_buffer, "E01");
+	put_packet(out_buffer);
+}
+
+/* Empty message indicates unrecognised command */
+static void send_empty_msg(void)
+{
+	put_packet("");
+}
+
+/* Read memory due to 'm' message */
+static void read_mem_msg(void)
+{
+	char *ptr;
+	int addr;
+	int length;
+
+	/* Jmp, disable bus error handler */
+	if (kgdb_setjmp(rem_com_env) == 0) {
+
+		kgdb_nofault = 1;
+
+		/* Walk through, have m<addr>,<length> */
+		ptr = &in_buffer[1];
+		if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))
+			if (hex_to_int(&ptr, &length)) {
+				ptr = 0;
+				if (length * 2 > OUTBUFMAX)
+					length = OUTBUFMAX / 2;
+				mem_to_hex((char *) addr, out_buffer, length);
+			}
+		if (ptr)
+			send_err_msg();
+		else
+			put_packet(out_buffer);
+	} else
+		send_err_msg();
+
+	/* Restore bus error handler */
+	kgdb_nofault = 0;
+}
+
+/* Write memory due to 'M' or 'X' message */
+static void write_mem_msg(int binary)
+{
+	char *ptr;
+	int addr;
+	int length;
+
+	if (kgdb_setjmp(rem_com_env) == 0) {
+
+		kgdb_nofault = 1;
+
+		/* Walk through, have M<addr>,<length>:<data> */
+		ptr = &in_buffer[1];
+		if (hex_to_int(&ptr, &addr) && (*ptr++ == ','))
+			if (hex_to_int(&ptr, &length) && (*ptr++ == ':')) {
+				if (binary)
+					ebin_to_mem(ptr, (char*)addr, length);
+				else
+					hex_to_mem(ptr, (char*)addr, length);
+				kgdb_flush_icache_range(addr, addr + length);
+				ptr = 0;
+				send_ok_msg();
+			}
+		if (ptr)
+			send_err_msg();
+	} else
+		send_err_msg();
+
+	/* Restore bus error handler */
+	kgdb_nofault = 0;
+}
+
+/* Continue message  */
+static void continue_msg(void)
+{
+	/* Try to read optional parameter, PC unchanged if none */
+	char *ptr = &in_buffer[1];
+	int addr;
+
+	if (hex_to_int(&ptr, &addr))
+		trap_registers.pc = addr;
+}
+
+/* Continue message with signal */
+static void continue_with_sig_msg(void)
+{
+	int signal;
+	char *ptr = &in_buffer[1];
+	int addr;
+
+	/* Report limitation */
+	kgdb_to_gdb("Cannot force signal in kgdb, continuing anyway.\n");
+
+	/* Signal */
+	hex_to_int(&ptr, &signal);
+	if (*ptr == ';')
+		ptr++;
+
+	/* Optional address */
+	if (hex_to_int(&ptr, &addr))
+		trap_registers.pc = addr;
+}
+
+/* Step message */
+static void step_msg(void)
+{
+	continue_msg();
+	do_single_step();
+}
+
+/* Step message with signal */
+static void step_with_sig_msg(void)
+{
+	continue_with_sig_msg();
+	do_single_step();
+}
+
+/* Send register contents */
+static void send_regs_msg(void)
+{
+#ifdef CONFIG_KGDB_THREAD
+	if (!current_thread)
+		kgdb_regs_to_gdb_regs(&trap_registers, registers);
+	else
+		thread_regs_to_gdb_regs(current_thread, registers);
+#else
+	kgdb_regs_to_gdb_regs(&trap_registers, registers);
+#endif
+
+	mem_to_hex((char *) registers, out_buffer, NUMREGBYTES);
+	put_packet(out_buffer);
+}
+
+/* Set register contents - currently can't set other thread's registers */
+static void set_regs_msg(void)
+{
+#ifdef CONFIG_KGDB_THREAD
+	if (!current_thread) {
+#endif
+		kgdb_regs_to_gdb_regs(&trap_registers, registers);
+		hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES);
+		gdb_regs_to_kgdb_regs(registers, &trap_registers);
+		send_ok_msg();
+#ifdef CONFIG_KGDB_THREAD
+	} else
+		send_err_msg();
+#endif
+}
+
+
+#ifdef CONFIG_KGDB_THREAD
+
+/* Set the status for a thread */
+void set_thread_msg(void)
+{
+	int threadid;
+	struct task_struct *thread = NULL;
+	char *ptr;
+
+	switch (in_buffer[1]) {
+
+       	/* To select which thread for gG etc messages, i.e. supported */
+	case 'g':
+
+		ptr = &in_buffer[2];
+		hex_to_int(&ptr, &threadid);
+		thread = get_thread(threadid);
+
+		/* If we haven't found it */
+		if (!thread) {
+			send_err_msg();
+			break;
+		}
+
+		/* Set current_thread (or not) */
+		if (thread == trapped_thread)
+			current_thread = NULL;
+		else
+			current_thread = thread;
+		send_ok_msg();
+		break;
+
+	/* To select which thread for cCsS messages, i.e. unsupported */
+	case 'c':
+		send_ok_msg();
+		break;
+
+	default:
+		send_empty_msg();
+		break;
+	}
+}
+
+/* Is a thread alive? */
+static void thread_status_msg(void)
+{
+	char *ptr;
+	int threadid;
+	struct task_struct *thread = NULL;
+
+	ptr = &in_buffer[1];
+	hex_to_int(&ptr, &threadid);
+	thread = get_thread(threadid);
+	if (thread)
+		send_ok_msg();
+	else
+		send_err_msg();
+}
+/* Send the current thread ID */
+static void thread_id_msg(void)
+{
+	int threadid;
+	threadref thref;
+
+	out_buffer[0] = 'Q';
+	out_buffer[1] = 'C';
+
+	if (current_thread)
+		threadid = current_thread->pid;
+	else if (trapped_thread)
+		threadid = trapped_thread->pid;
+	else /* Impossible, but just in case! */
+	{
+		send_err_msg();
+		return;
+	}
+
+	/* Translate pid 0 to PID_MAX for gdb */
+	if (threadid == 0) threadid = PID_MAX;
+
+	int_to_threadref(&thref, threadid);
+	pack_threadid(out_buffer + 2, &thref);
+	out_buffer[2 + BUF_THREAD_ID_SIZE] = '\0';
+	put_packet(out_buffer);
+}
+
+/* Send thread info */
+static void thread_info_msg(void)
+{
+	struct task_struct *thread = NULL;
+	int threadid;
+	char *pos;
+	threadref thref;
+
+	/* Start with 'm' */
+	out_buffer[0] = 'm';
+	pos = &out_buffer[1];
+
+	/* For all possible thread IDs - this will overrun if > 44 threads! */
+	/* Start at 1 and include PID_MAX (since GDB won't use pid 0...) */
+	for (threadid = 1; threadid <= PID_MAX; threadid++) {
+
+		read_lock(&tasklist_lock);
+		thread = get_thread(threadid);
+		read_unlock(&tasklist_lock);
+
+		/* If it's a valid thread */
+		if (thread) {
+			int_to_threadref(&thref, threadid);
+			pack_threadid(pos, &thref);
+			pos += BUF_THREAD_ID_SIZE;
+			*pos++ = ',';
+		}
+	}
+	*--pos = 0;		/* Lose final comma */
+	put_packet(out_buffer);
+
+}
+
+/* Return printable info for gdb's 'info threads' command */
+static void thread_extra_info_msg(void)
+{
+	int threadid;
+	struct task_struct *thread = NULL;
+	char buffer[20], *ptr;
+	int i;
+
+	/* Extract thread ID */
+	ptr = &in_buffer[17];
+	hex_to_int(&ptr, &threadid);
+	thread = get_thread(threadid);
+
+	/* If we don't recognise it, say so */
+	if (thread == NULL)
+		strcpy(buffer, "(unknown)");
+	else
+		strcpy(buffer, thread->comm);
+
+	/* Construct packet */
+	for (i = 0, ptr = out_buffer; buffer[i]; i++)
+		ptr = pack_hex_byte(ptr, buffer[i]);
+
+	if (thread->thread.pc == (unsigned long)ret_from_fork) {
+		strcpy(buffer, "<new fork>");
+		for (i = 0; buffer[i]; i++)
+			ptr = pack_hex_byte(ptr, buffer[i]);
+	}
+
+	*ptr = '\0';
+	put_packet(out_buffer);
+}
+
+/* Handle all qFooBarBaz messages - have to use an if statement as
+   opposed to a switch because q messages can have > 1 char id. */
+static void query_msg(void)
+{
+	const char *q_start = &in_buffer[1];
+
+	/* qC = return current thread ID */
+	if (strncmp(q_start, "C", 1) == 0)
+		thread_id_msg();
+
+	/* qfThreadInfo = query all threads (first) */
+	else if (strncmp(q_start, "fThreadInfo", 11) == 0)
+		thread_info_msg();
+
+	/* qsThreadInfo = query all threads (subsequent). We know we have sent
+	   them all after the qfThreadInfo message, so there are no to send */
+	else if (strncmp(q_start, "sThreadInfo", 11) == 0)
+		put_packet("l");	/* el = last */
+
+	/* qThreadExtraInfo = supply printable information per thread */
+	else if (strncmp(q_start, "ThreadExtraInfo", 15) == 0)
+		thread_extra_info_msg();
+
+	/* Unsupported - empty message as per spec */
+	else
+		send_empty_msg();
+}
+#endif /* CONFIG_KGDB_THREAD */
+
+/* The command loop, read and act on requests */
+static void kgdb_command_loop(const int excep_code, const int trapa_value)
+{
+	int sigval;
+
+	if (excep_code == NMI_VEC) {
+#ifndef CONFIG_KGDB_NMI
+		KGDB_PRINTK("Ignoring unexpected NMI?\n");
+		return;
+#else /* CONFIG_KGDB_NMI */
+		if (!kgdb_enabled) {
+			kgdb_enabled = 1;
+			kgdb_init();
+		}
+#endif /* CONFIG_KGDB_NMI */
+	}
+
+	/* Ignore if we're disabled */
+	if (!kgdb_enabled)
+		return;
+
+#ifdef CONFIG_KGDB_THREAD
+	/* Until GDB specifies a thread */
+	current_thread = NULL;
+	trapped_thread = current;
+#endif
+
+	/* Enter GDB mode (e.g. after detach) */
+	if (!kgdb_in_gdb_mode) {
+		/* Do serial setup, notify user, issue preemptive ack */
+		(void)kgdb_serial_setup();
+		KGDB_PRINTK("Waiting for GDB (on %s%d at %d baud)\n",
+			    (kgdb_porttype ? kgdb_porttype->name : ""),
+			    kgdb_portnum, kgdb_baud);
+		kgdb_in_gdb_mode = 1;
+		put_debug_char('+');
+	}
+
+	/* Reply to host that an exception has occurred */
+	sigval = compute_signal(excep_code);
+	send_signal_msg(sigval);
+
+	/* TRAP_VEC exception indicates a software trap inserted in place of
+	   code by GDB so back up PC by one instruction, as this instruction
+	   will later be replaced by its original one.  Do NOT do this for
+	   trap 0xff, since that indicates a compiled-in breakpoint which
+	   will not be replaced (and we would retake the trap forever) */
+	if ((excep_code == TRAP_VEC) && (trapa_value != (0xff << 2))) {
+		trap_registers.pc -= 2;
+	}
+
+	/* Undo any stepping we may have done */
+	undo_single_step();
+
+	while (1) {
+
+		out_buffer[0] = 0;
+		get_packet(in_buffer, BUFMAX);
+
+		/* Examine first char of buffer to see what we need to do */
+		switch (in_buffer[0]) {
+
+		case '?':	/* Send which signal we've received */
+			send_signal_msg(sigval);
+			break;
+
+		case 'g':	/* Return the values of the CPU registers */
+			send_regs_msg();
+			break;
+
+		case 'G':	/* Set the value of the CPU registers */
+			set_regs_msg();
+			break;
+
+		case 'm':	/* Read LLLL bytes address AA..AA */
+			read_mem_msg();
+			break;
+
+		case 'M':	/* Write LLLL bytes address AA..AA, ret OK */
+			write_mem_msg(0);	/* 0 = data in hex */
+			break;
+
+		case 'X':	/* Write LLLL bytes esc bin address AA..AA */
+			if (kgdb_bits == '8')
+				write_mem_msg(1); /* 1 = data in binary */
+			else
+				send_empty_msg();
+			break;
+
+		case 'C':	/* Continue, signum included, we ignore it */
+			continue_with_sig_msg();
+			return;
+
+		case 'c':	/* Continue at address AA..AA (optional) */
+			continue_msg();
+			return;
+
+		case 'S':	/* Step, signum included, we ignore it */
+			step_with_sig_msg();
+			return;
+
+		case 's':	/* Step one instruction from AA..AA */
+			step_msg();
+			return;
+
+#ifdef CONFIG_KGDB_THREAD
+
+		case 'H':	/* Task related */
+			set_thread_msg();
+			break;
+
+		case 'T':	/* Query thread status */
+			thread_status_msg();
+			break;
+
+		case 'q':	/* Handle query - currently thread-related */
+			query_msg();
+			break;
+#endif
+
+		case 'k':	/* 'Kill the program' with a kernel ? */
+			break;
+
+		case 'D':	/* Detach from program, send reply OK */
+			kgdb_in_gdb_mode = 0;
+			send_ok_msg();
+			get_debug_char();
+			return;
+
+		default:
+			send_empty_msg();
+			break;
+		}
+	}
+}
+
+/* There has been an exception, most likely a breakpoint. */
+void kgdb_handle_exception(struct pt_regs *regs)
+{
+	int excep_code, vbr_val;
+	int count;
+	int trapa_value = ctrl_inl(TRA);
+
+	/* Copy kernel regs (from stack) */
+	for (count = 0; count < 16; count++)
+		trap_registers.regs[count] = regs->regs[count];
+	trap_registers.pc = regs->pc;
+	trap_registers.pr = regs->pr;
+	trap_registers.sr = regs->sr;
+	trap_registers.gbr = regs->gbr;
+	trap_registers.mach = regs->mach;
+	trap_registers.macl = regs->macl;
+
+	asm("stc vbr, %0":"=r"(vbr_val));
+	trap_registers.vbr = vbr_val;
+
+	/* Get excode for command loop call, user access */
+	asm("stc r2_bank, %0":"=r"(excep_code));
+	kgdb_excode = excep_code;
+
+	/* Other interesting environment items for reference */
+	asm("stc r6_bank, %0":"=r"(kgdb_g_imask));
+	kgdb_current = current;
+	kgdb_trapa_val = trapa_value;
+	kgdb_tregs = regs;
+
+	/* Act on the exception */
+	kgdb_command_loop(excep_code >> 5, trapa_value);
+
+	kgdb_current = NULL;
+
+	/* Copy back the (maybe modified) registers */
+	for (count = 0; count < 16; count++)
+		regs->regs[count] = trap_registers.regs[count];
+	regs->pc = trap_registers.pc;
+	regs->pr = trap_registers.pr;
+	regs->sr = trap_registers.sr;
+	regs->gbr = trap_registers.gbr;
+	regs->mach = trap_registers.mach;
+	regs->macl = trap_registers.macl;
+
+	vbr_val = trap_registers.vbr;
+	asm("ldc %0, vbr": :"r"(vbr_val));
+
+	return;
+}
+
+/* Trigger a breakpoint by function */
+void breakpoint(void)
+{
+	if (!kgdb_enabled) {
+		kgdb_enabled = 1;
+		kgdb_init();
+	}
+	BREAKPOINT();
+}
+
+/* Initialise the KGDB data structures and serial configuration */
+int kgdb_init(void)
+{
+	if (!kgdb_enabled)
+		return 1;
+
+	in_nmi = 0;
+	kgdb_nofault = 0;
+	stepped_opcode = 0;
+	kgdb_in_gdb_mode = 0;
+
+	/* Set up for serial comms */
+	if (kgdb_serial_setup == NULL) {
+		KGDB_PRINTK("no serial init function!!\n");
+		return -1;
+	}
+
+	if (kgdb_serial_setup() != 0) {
+		KGDB_PRINTK("serial setup error\n");
+		return -1;
+	}
+
+	/* Init ptr to exception handler */
+	kgdb_debug_hook = kgdb_handle_exception;
+	kgdb_bus_err_hook = kgdb_handle_bus_error;
+
+	/* Enter kgdb now if requested, or just report init done */
+	if (kgdb_halt) {
+		kgdb_in_gdb_mode = 1;
+		put_debug_char('+');
+		breakpoint();
+	}
+	else
+	{
+		KGDB_PRINTK("stub is initialized.\n");
+	}
+
+	return 0;
+}
+
+/* Make function available for "user messages"; console will use it too. */
+
+char gdbmsgbuf[BUFMAX];
+#define MAXOUT ((BUFMAX-2)/2)
+
+static void kgdb_msg_write(const char *s, unsigned count)
+{
+	int i;
+	int wcount;
+	char *bufptr;
+
+	/* 'O'utput */
+	gdbmsgbuf[0] = 'O';
+
+	/* Fill and send buffers... */
+	while (count > 0) {
+		bufptr = gdbmsgbuf + 1;
+
+		/* Calculate how many this time */
+		wcount = (count > MAXOUT) ? MAXOUT : count;
+		
+		/* Pack in hex chars */
+		for (i = 0; i < wcount; i++)
+			bufptr = pack_hex_byte(bufptr, s[i]);
+		*bufptr = '\0';
+
+		/* Move up */
+		s += wcount;
+		count -= wcount;
+
+		/* Write packet */
+		put_packet(gdbmsgbuf);
+	}
+}
+
+static void kgdb_to_gdb(const char *s)
+{
+	kgdb_msg_write(s, strlen(s));
+}
+
+#ifdef CONFIG_SH_KGDB_CONSOLE
+void kgdb_console_write(struct console *co, const char *s, unsigned count)
+{
+	/* Bail if we're not talking to GDB */
+	if (!kgdb_in_gdb_mode)
+		return;
+
+	kgdb_msg_write(s, count);
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/led_se.c linux-2.4.22-pre10/arch/sh/kernel/led_se.c
--- linux-2.4.21/arch/sh/kernel/led_se.c	2001-09-08 19:29:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/led_se.c	2003-08-01 13:34:29.000000000 +0000
@@ -10,7 +10,14 @@
  */
 
 #include <linux/config.h>
+
+#ifdef CONFIG_SH_7751_SOLUTION_ENGINE
+#include <asm/hitachi_7751se.h>
+#elif defined(CONFIG_SH_MOBILE_SOLUTION_ENGINE)
+#include <asm/hitachi_shmse.h>
+#else
 #include <asm/hitachi_se.h>
+#endif
 
 static void mach_led(int position, int value)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/mach_7751se.c linux-2.4.22-pre10/arch/sh/kernel/mach_7751se.c
--- linux-2.4.21/arch/sh/kernel/mach_7751se.c	2001-09-08 19:29:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/mach_7751se.c	2003-08-01 13:33:30.000000000 +0000
@@ -18,7 +18,7 @@
 
 #include <asm/io_7751se.h>
 
-void heartbeat_7751se(void);
+void heartbeat_se(void);
 void setup_7751se(void);
 void init_7751se_IRQ(void);
 
@@ -67,7 +67,7 @@
 	mv_init_arch:		setup_7751se,
 	mv_init_irq:		init_7751se_IRQ,
 #ifdef CONFIG_HEARTBEAT
-	mv_heartbeat:		heartbeat_7751se,
+	mv_heartbeat:		heartbeat_se,
 #endif
 
 	mv_rtc_gettimeofday:	sh_rtc_gettimeofday,
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/mach_hs7729pci.c linux-2.4.22-pre10/arch/sh/kernel/mach_hs7729pci.c
--- linux-2.4.21/arch/sh/kernel/mach_hs7729pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/mach_hs7729pci.c	2003-08-01 13:34:32.000000000 +0000
@@ -0,0 +1,81 @@
+/*
+ * linux/arch/sh/kernel/mach_hs7729pci.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Machine vector for the Hitachi Semiconductor ans Devices HS7729PCI
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/machvec_init.h>
+#include <asm/rtc.h>
+
+#include <asm/io_hs7729pci.h>
+
+void setup_hs7729pci(void);
+void init_hs7729pci_IRQ(void);
+
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_hs7729pci __initmv = {
+	mv_name:		"HS7729PCI",
+
+#if defined(__SH4__)
+	mv_nr_irqs:		48,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
+	mv_nr_irqs:		32,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
+	mv_nr_irqs:		61,
+#endif
+
+	mv_inb:			hs7729pci_inb,
+	mv_inw:			hs7729pci_inw,
+	mv_inl:			hs7729pci_inl,
+	mv_outb:		hs7729pci_outb,
+	mv_outw:		hs7729pci_outw,
+	mv_outl:		hs7729pci_outl,
+
+	mv_inb_p:		hs7729pci_inb_p,
+	mv_inw_p:		hs7729pci_inw,
+	mv_inl_p:		hs7729pci_inl,
+	mv_outb_p:		hs7729pci_outb_p,
+	mv_outw_p:		hs7729pci_outw,
+	mv_outl_p:		hs7729pci_outl,
+
+	mv_insb:		hs7729pci_insb,
+	mv_insw:		hs7729pci_insw,
+	mv_insl:		hs7729pci_insl,
+	mv_outsb:		hs7729pci_outsb,
+	mv_outsw:		hs7729pci_outsw,
+	mv_outsl:		hs7729pci_outsl,
+
+	mv_readb:		generic_readb,
+	mv_readw:		generic_readw,
+	mv_readl:		generic_readl,
+	mv_writeb:		generic_writeb,
+	mv_writew:		generic_writew,
+	mv_writel:		generic_writel,
+
+	mv_ioremap:		hs7729pci_ioremap,
+	mv_iounmap:		hs7729pci_iounmap,
+
+	mv_isa_port2addr:	hs7729pci_isa_port2addr,
+
+	mv_init_arch:		setup_hs7729pci,
+	mv_init_irq:		init_hs7729pci_IRQ,
+
+	mv_rtc_gettimeofday:	sh_rtc_gettimeofday,
+	mv_rtc_settimeofday:	sh_rtc_settimeofday,
+
+	mv_hw_hs7729pci:	1,
+};
+ALIAS_MV(hs7729pci)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/mach_keywest.c linux-2.4.22-pre10/arch/sh/kernel/mach_keywest.c
--- linux-2.4.21/arch/sh/kernel/mach_keywest.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/mach_keywest.c	2003-08-01 13:34:39.000000000 +0000
@@ -0,0 +1,70 @@
+/*
+ * linux/arch/sh/kernel/mach_keywest.c
+ *
+ * Machine vector for HSA KeyWest Evaluiation board
+ *
+ * Copyright (C) 2001 Lineo, Japan
+ *   
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+#include <asm/io.h>
+#include <asm/io_keywest.h>
+#include <asm/irq.h>
+
+/*
+ * The Machine Vector
+ */
+extern void heartbeat_keywest(void);
+extern void setup_keywest(void);
+extern void init_keywest_IRQ(void);
+
+struct sh_machine_vector mv_keywest __initmv = {
+	mv_name:		"Key West",
+	mv_nr_irqs:		NR_IRQS,     // Defined in <asm/irq.h>
+	mv_inb:			keywest_inb,
+	mv_inw:			keywest_inw,
+	mv_inl:			keywest_inl,
+	mv_outb:		keywest_outb,
+	mv_outw:		keywest_outw,
+	mv_outl:		keywest_outl,
+
+	mv_inb_p:		keywest_inb_p,
+	mv_inw_p:		keywest_inw,
+	mv_inl_p:		keywest_inl,
+	mv_outb_p:		keywest_outb_p,
+	mv_outw_p:		keywest_outw,
+	mv_outl_p:		keywest_outl,
+
+	mv_insb:		keywest_insb,
+	mv_insw:		keywest_insw,
+	mv_insl:		keywest_insl,
+	mv_outsb:		keywest_outsb,
+	mv_outsw:		keywest_outsw,
+	mv_outsl:		keywest_outsl,
+
+	mv_readb:		generic_readb,
+	mv_readw:		generic_readw,
+	mv_readl:		generic_readl,
+	mv_writeb:		generic_writeb,
+	mv_writew:		generic_writew,
+	mv_writel:		generic_writel,
+
+	mv_ioremap:		generic_ioremap,
+	mv_iounmap:		generic_iounmap,
+
+	mv_isa_port2addr:	keywest_isa_port2addr,
+	mv_irq_demux:       keywest_irq_demux,
+
+	mv_init_arch:		setup_keywest,
+	mv_init_irq:		init_keywest_IRQ,
+	mv_rtc_gettimeofday:	sh_rtc_gettimeofday,
+	mv_rtc_settimeofday:	sh_rtc_settimeofday,
+
+};
+ALIAS_MV(keywest)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/mach_shmse.c linux-2.4.22-pre10/arch/sh/kernel/mach_shmse.c
--- linux-2.4.21/arch/sh/kernel/mach_shmse.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/mach_shmse.c	2003-08-01 13:30:33.000000000 +0000
@@ -0,0 +1,71 @@
+/*
+ * linux/arch/sh/kernel/mach_shmse.c
+ *
+ * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> 
+ * Based largely on mach_se.c
+ *
+ * Machine vector for SH-Mobile SolutionEngine
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io_shmse.h>
+
+void heartbeat_se(void);
+void setup_shmse(void);
+void init_shmse_IRQ(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_shmse __initmv = {
+	mv_name:		"SH-Mobile SE",
+
+	mv_nr_irqs:		109,
+
+	mv_inb:			shmse_inb,
+	mv_inw:			shmse_inw,
+	mv_inl:			shmse_inl,
+	mv_outb:		shmse_outb,
+	mv_outw:		shmse_outw,
+	mv_outl:		shmse_outl,
+
+	mv_inb_p:		shmse_inb_p,
+	mv_inw_p:		shmse_inw,
+	mv_inl_p:		shmse_inl,
+	mv_outb_p:		shmse_outb_p,
+	mv_outw_p:		shmse_outw,
+	mv_outl_p:		shmse_outl,
+
+	mv_insb:		shmse_insb,
+	mv_insw:		shmse_insw,
+	mv_insl:		shmse_insl,
+	mv_outsb:		shmse_outsb,
+	mv_outsw:		shmse_outsw,
+	mv_outsl:		shmse_outsl,
+
+	mv_readb:		shmse_readb,
+	mv_readw:		shmse_readw,
+	mv_readl:		shmse_readl,
+	mv_writeb:		shmse_writeb,
+	mv_writew:		shmse_writew,
+	mv_writel:		shmse_writel,
+
+	mv_ioremap:		generic_ioremap,
+	mv_iounmap:		generic_iounmap,
+
+	mv_init_arch:		setup_shmse,
+	mv_init_irq:		init_shmse_IRQ,
+#ifdef CONFIG_HEARTBEAT
+	mv_heartbeat:		heartbeat_se,
+#endif
+
+	mv_hw_shmse:		1,
+};
+ALIAS_MV(shmse)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/mach_snapgear.c linux-2.4.22-pre10/arch/sh/kernel/mach_snapgear.c
--- linux-2.4.21/arch/sh/kernel/mach_snapgear.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/mach_snapgear.c	2003-08-01 13:32:06.000000000 +0000
@@ -0,0 +1,82 @@
+/*
+ * linux/arch/sh/kernel/mach_snapgear.c
+ *
+ * Minor tweak of mach_se.c file to reference SnapGear items.
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Machine vector for the Hitachi 7751 SolutionEngine
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io_snapgear.h>
+
+extern void setup_snapgear(void);
+extern void init_snapgear_IRQ(void);
+
+extern void snapgear_rtc_gettimeofday(struct timeval *tv);
+extern int snapgear_rtc_settimeofday(const struct timeval *tv);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_snapgear __initmv = {
+	mv_name:		"SnapGear",
+
+	mv_nr_irqs:		72,
+
+	mv_inb:			snapgear_inb,
+	mv_inw:			snapgear_inw,
+	mv_inl:			snapgear_inl,
+	mv_outb:		snapgear_outb,
+	mv_outw:		snapgear_outw,
+	mv_outl:		snapgear_outl,
+
+	mv_inb_p:		snapgear_inb_p,
+	mv_inw_p:		snapgear_inw,
+	mv_inl_p:		snapgear_inl,
+	mv_outb_p:		snapgear_outb_p,
+	mv_outw_p:		snapgear_outw,
+	mv_outl_p:		snapgear_outl,
+
+	mv_insb:		snapgear_insb,
+	mv_insw:		snapgear_insw,
+	mv_insl:		snapgear_insl,
+	mv_outsb:		snapgear_outsb,
+	mv_outsw:		snapgear_outsw,
+	mv_outsl:		snapgear_outsl,
+
+	mv_readb:		snapgear_readb,
+	mv_readw:		snapgear_readw,
+	mv_readl:		snapgear_readl,
+	mv_writeb:		snapgear_writeb,
+	mv_writew:		snapgear_writew,
+	mv_writel:		snapgear_writel,
+
+	mv_ioremap:		generic_ioremap,
+	mv_iounmap:		generic_iounmap,
+
+	mv_isa_port2addr:	snapgear_isa_port2addr,
+
+	mv_init_arch:		setup_snapgear,
+	mv_init_irq:		init_snapgear_IRQ,
+
+#ifndef CONFIG_RTC
+	mv_rtc_gettimeofday:	sh_rtc_gettimeofday,
+	mv_rtc_settimeofday:	sh_rtc_settimeofday,
+#else
+	mv_rtc_gettimeofday:	snapgear_rtc_gettimeofday,
+	mv_rtc_settimeofday:	snapgear_rtc_settimeofday,
+#endif
+
+	mv_hw_snapgear:		1,
+};
+ALIAS_MV(snapgear)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/pci-sd0001.c linux-2.4.22-pre10/arch/sh/kernel/pci-sd0001.c
--- linux-2.4.21/arch/sh/kernel/pci-sd0001.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/pci-sd0001.c	2003-08-01 13:31:30.000000000 +0000
@@ -0,0 +1,795 @@
+/*
+ *   $Id: pci-sd0001.c,v 1.1.2.1 2003/06/24 08:40:50 dwmw2 Exp $
+ *
+ *   linux/arch/sh/kernel/pci-sd0001.c
+ *
+ *   Support Hitachi Semcon SD0001 SH3 PCI Host Bridge .
+ *  
+ *
+ *   Copyright (C) 2000  Hitachi ULSI Systems Co., Ltd.
+ *   All Rights Reserved.
+ *
+ *   Copyright (C) 2001-2003 Red Hat, Inc.
+ *
+ *   Authors:	Masayuki Okada (macha@adc.hitachi-ul.co.jp)
+ *              David Woodhouse (dwmw2@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, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/vmalloc.h>
+
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "pci-sd0001.h"
+
+spinlock_t sd0001_indirect_lock = SPIN_LOCK_UNLOCKED;
+
+int remap_area_pages(unsigned long address, unsigned long phys_addr,
+                     unsigned long size, unsigned long flags);
+
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+#define SD0001_INDIR_TIME	1000000		/* ´ÖÀÜ¥¢¥¯¥»¥¹´°Î»ÂÔ¤ÁºÇÂç²ó¿ô */
+
+static char *err_int_msg [] = {
+	"Detect Master Abort",
+	"Assert Master Abort",
+	"Detect Target Abort",
+	"Assert Target Abort",
+	"Assert PERR",
+	"Detect PERR",
+	"Detect SERR",
+	"Asster SERR",
+	"Bus Timeout",
+	"Bus Retry Over",
+};
+
+/*
+ * PCI¥Ð¥¹¤Î¥Ð¥¹¥ê¥»¥Ã¥È¼Â¹Ô
+ */
+static void sd0001_bus_reset(void)
+{
+	sd0001_writel(SD0001_RST_BUSRST, RESET);
+
+	udelay(64);
+
+	sd0001_writel(0, RESET);
+}
+
+/*
+ * SD0001¥½¥Õ¥È¥ê¥»¥Ã¥È
+ */
+static void sd0001_chip_reset(void)
+{
+	sd0001_writel(SD0001_RST_SWRST, RESET);
+}
+
+
+#define ROUND_UP(x, a)		(((x) + (a) - 1) & ~((a) - 1))
+
+static void
+sd0001_int_pcierr (int irq, void *dummy, struct pt_regs *regs)
+{
+	static char  errStrings[30*12];
+	u32 int_status;
+	u32 mask;
+	u32 indrct_flg;
+	int reset_fatal;
+	int   i;
+	int   to_cnt = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sd0001_indirect_lock, flags);
+
+	if ((int_status = (sd0001_readl(INT_STS1) & SD0001_INT_BUSERR))) {
+		DBG("pciIntErrorHandle Called: status 0x%08x\n", int_status, 0, 0, 0, 0, 0);
+
+		for (mask = 1 << 20, i = 0, errStrings[0] = '\0'; i < 11; i++, mask <<= 1) {
+			if (int_status & mask) {
+/* 				err_int_cnt[i] ++; */
+				strcat(errStrings, err_int_msg[i]);
+				strcat(errStrings, ", ");
+			}
+		}
+		i = strlen(errStrings);
+		errStrings[i-2]= '\0';
+
+		printk(KERN_ERR "PCI Bus 0x%08x(%s) Error\n", int_status, errStrings);
+
+		reset_fatal = 0;
+
+		if (int_status & (SD0001_INT_SSERR|SD0001_INT_RPERR
+				  |SD0001_INT_SPERR|SD0001_INT_STABT
+				  |SD0001_INT_RTABT|SD0001_INT_RMABT)) {
+			/* Clear of Configration Status Bits */
+			sd0001_writel(4, INDIRECT_ADR);
+			sd0001_writel(0xf9000000, INDIRECT_DATA);
+			sd0001_writel(0x000c0002, INDIRECT_CTL);
+			to_cnt = 0;
+			while (((indrct_flg = sd0001_readl(INDIRECT_STS)) & SD0001_INDRCTF_INDFLG)
+			       && (to_cnt++ < SD0001_INDIR_TIME))
+				;
+
+
+			if (indrct_flg & SD0001_INDRCTF_INDFLG) {
+				panic("SD0001 Fatal Error 1\n");
+			} else {
+				if (indrct_flg & SD0001_INDRCTF_MABTRCV) {
+					sd0001_writel(SD0001_INDRCTC_FLGRESET, INDIRECT_CTL);
+					reset_fatal = -1;
+				}
+			}
+			int_status = sd0001_readl(INT_STS1) & SD0001_INT_BUSERR;
+		}
+
+		if (int_status != 0) {
+			sd0001_writel(int_status, INT_STS1); /* ³ä¤ê¹þ¤ß¥¯¥ê¥¢ */
+
+			if (reset_fatal || (sd0001_readl(INT_STS2) & SD0001_INT_BUSERR)) {
+				printk(KERN_CRIT "Fatal Error:SD0001 PCI Status Can't Clear 0x%08x\n",
+				       int_status & 0x7fffffff);
+				sd0001_writel(sd0001_readl(INT_ENABLE) & ~int_status, INT_ENABLE);
+				/* Masked Error Interrupt */
+			}
+		}
+	}
+	spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
+}
+
+
+static inline u32 convert_dev_to_addr (struct pci_dev *dev, u32 reg)
+{
+	return (SD0001_CONFIG_ADDR_EN
+		| (dev->bus->number << 16)
+		| ((dev->devfn & 0xff) << 8)
+		| (reg & 0xff)
+		| ((dev->bus->number)?0x00:0x01));
+}
+
+
+static int sd0001_indirect_RW (u32  addr, u32 cmd, u32  be,
+				  u32  rw, u32  *data)
+{
+	u32 indrct_flg;
+	u32 int_sts;
+	u32 to_cnt = 0;
+	int st = PCIBIOS_SUCCESSFUL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sd0001_indirect_lock, flags);
+	if ((cmd & SD0001_INDRCTC_CMD_MASK) == SD0001_INDRCTC_CMD_MEMR
+	    || (cmd & SD0001_INDRCTC_CMD_MASK) == SD0001_INDRCTC_CMD_MEMW)
+		sd0001_writel(addr & 0xfffffffc, INDIRECT_ADR);
+	else
+		sd0001_writel(addr, INDIRECT_ADR);
+
+	if (rw == SD0001_INDRCTC_IOWT || rw == SD0001_INDRCTC_COWT)
+		sd0001_writel(*data, INDIRECT_DATA);
+
+	sd0001_writel(be | cmd | rw , INDIRECT_CTL);
+
+	while (((indrct_flg = sd0001_readl(INDIRECT_STS)) & SD0001_INDRCTF_INDFLG)
+	       && (to_cnt++ < SD0001_INDIR_TIME));
+
+	int_sts = sd0001_readl(INT_STS1) & SD0001_INT_BUSERR;
+    
+	if (indrct_flg & SD0001_INDRCTF_INDFLG) {	/* ¥¿¥¤¥à¥¢¥¦¥È */
+		printk("SD0001 Fatal Error 2\n");
+		spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
+
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	if (int_sts != 0 || (indrct_flg & SD0001_INDRCTF_MABTRCV) != 0) {
+		if ((st = (indrct_flg & SD0001_INDRCTF_MABTRCV) >> 19) != 0) {
+			sd0001_writel(SD0001_INDRCTC_FLGRESET, INDIRECT_CTL);
+			st |= 0x80000000;
+		}
+
+		st |= 0x80000000 | int_sts;
+
+		if ((int_sts & (SD0001_INT_SSERR|SD0001_INT_RPERR
+				|SD0001_INT_SPERR|SD0001_INT_STABT
+				|SD0001_INT_RTABT|SD0001_INT_RMABT))
+		    || (indrct_flg & SD0001_INDRCTF_MABTRCV)) {
+			/* Clear of Configration Status Bits */
+			sd0001_writel(4, INDIRECT_ADR);
+			sd0001_writel(0xf9000000, INDIRECT_DATA);
+			sd0001_writel(0x000c0002, INDIRECT_CTL);
+
+			to_cnt = 0;
+			while (((indrct_flg = sd0001_readl(INDIRECT_STS)) & SD0001_INDRCTF_INDFLG)
+			       && (to_cnt++ < SD0001_INDIR_TIME));
+
+			if (indrct_flg & SD0001_INDRCTF_INDFLG) {	/* ¥¿¥¤¥à¥¢¥¦¥È */
+				panic("SD0001 Fatal Error 3\n");
+			}
+
+			if (indrct_flg & SD0001_INDRCTF_MABTRCV) {
+				
+				sd0001_writel(SD0001_INDRCTC_FLGRESET, INDIRECT_CTL);
+			}
+		}
+		
+		printk(KERN_ERR "PCI Bus Error: status 0x%08x\n", st);
+
+		if ((int_sts = sd0001_readl(INT_STS1) & SD0001_INT_BUSERR) != 0) {
+			sd0001_writel(int_sts, INT_STS1);	/* ³ä¤ê¹þ¤ß¥¯¥ê¥¢ */
+			
+			if (sd0001_readl(INT_STS2) & SD0001_INT_BUSERR) {
+				printk(KERN_CRIT "Fatal Error:SD0001 PCI Status Can't Clear 0x%08x\n",
+				       sd0001_readl(INT_STS2) & SD0001_INT_BUSERR);
+				sd0001_writel(sd0001_readl(INT_ENABLE) & ~int_sts, INT_ENABLE); /* Masked Error Interrupt */
+			}
+		}
+
+		*data = 0xffffffff;
+	} else {
+		if (rw != SD0001_INDRCTC_IOWT && rw != SD0001_INDRCTC_COWT)
+			*data = sd0001_readl(INDIRECT_DATA);
+	}
+
+	spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
+	return st;
+}
+
+static inline
+int sd0001_config_RW (struct pci_dev *dev, u32 reg, u32 be, u32 rw, u32 *data)
+{
+	u32  reg_addr = convert_dev_to_addr(dev, reg);
+
+	if (reg_addr == 0) {
+		*data = 0xffffffff;
+		return PCIBIOS_SUCCESSFUL;
+	}
+    
+	return sd0001_indirect_RW (reg_addr, 0, be, rw, data);
+
+}
+
+
+static int sd0001_read_config_byte(struct pci_dev *dev, int reg, u8 *val)
+{
+	int  offset;
+	u32  be;
+	int  re;
+	union {
+		u32 ldata;
+		u8  bdata[4];
+	} work;
+
+	be = SD0001_INDRCTC_BE_BYTE << (reg & 0x03);
+	re = sd0001_config_RW (dev, reg, be, SD0001_INDRCTC_CORD, &work.ldata);
+
+#if __LITTLE_ENDIAN__
+	offset = reg & 0x03;
+#else  /* __LITTLE_ENDIAN__ */
+	offset = 3 - (reg & 0x03);
+#endif /* __LITTLE_ENDIAN__ */
+	*val = work.bdata[offset];
+
+	return re;
+
+}
+
+
+static int sd0001_read_config_word(struct pci_dev *dev, int reg, u16 *val)
+{
+	int  offset;
+	u32 be;
+	int  re;
+	union {
+		u32 ldata;
+		u16 wdata[2];
+	} work;
+
+	be = SD0001_INDRCTC_BE_WORD << (reg & 0x02);
+	
+	re = sd0001_config_RW (dev, reg, be, SD0001_INDRCTC_CORD, &work.ldata);
+	
+#if __LITTLE_ENDIAN__
+	offset = (reg >> 1) & 0x01;
+#else  /* __LITTLE_ENDIAN__ */
+	offset = 1 - ((reg >> 1) & 0x01);
+#endif /* __LITTLE_ENDIAN__ */
+	
+	*val = work.wdata[offset];
+	
+	return re;
+}
+
+
+static int sd0001_read_config_dword(struct pci_dev *dev, int reg, u32 *val)
+{
+	return sd0001_config_RW (dev, reg, SD0001_INDRCTC_BE_LONG,
+			      SD0001_INDRCTC_CORD, val);
+}
+
+static int sd0001_write_config_byte (struct pci_dev *dev, int reg, u8 val)
+{
+	int  offset;
+	u32 be;
+	union {
+		u32 ldata;
+		u8  bdata[4];
+	} work;
+
+	be = SD0001_INDRCTC_BE_BYTE << (reg & 0x03);
+#if __LITTLE_ENDIAN__
+	offset = reg & 0x03;
+#else  /* __LITTLE_ENDIAN__ */
+	offset = 3 - (reg & 0x03);
+#endif /* __LITTLE_ENDIAN__ */
+	work.bdata[offset] = val;
+
+	return sd0001_config_RW(dev, reg, be, SD0001_INDRCTC_COWT, &work.ldata);
+    
+}
+
+
+static int sd0001_write_config_word (struct pci_dev *dev, int reg, u16 val)
+{
+	int  offset;
+	u32 be;
+	union {
+		u32  ldata;
+		u16  wdata[2];
+	} work;
+
+
+	be = SD0001_INDRCTC_BE_WORD << (reg & 0x02);
+#if __LITTLE_ENDIAN__
+	offset = (reg >> 1) & 0x01;
+#else  /* __LITTLE_ENDIAN__ */
+	offset = 1 - ((reg >> 1) & 0x01);
+#endif /* __LITTLE_ENDIAN__ */
+
+	work.wdata[offset] = val;
+
+	return sd0001_config_RW (dev, reg, be, SD0001_INDRCTC_COWT, &work.ldata);
+
+}
+
+
+static int sd0001_write_config_dword (struct pci_dev *dev, int reg, u32 val)
+{
+	return sd0001_config_RW (dev, reg, SD0001_INDRCTC_BE_LONG, SD0001_INDRCTC_COWT, &val);
+}
+
+static struct pci_ops sd0001_pci_ops = 
+{
+	.read_byte =	sd0001_read_config_byte,
+	.read_word =	sd0001_read_config_word,
+	.read_dword =	sd0001_read_config_dword,
+	.write_byte =	sd0001_write_config_byte,
+	.write_word =	sd0001_write_config_word,
+	.write_dword =	sd0001_write_config_dword
+};
+
+int __init pci_setup_sd0001 (void)
+{
+	sd0001_writel(0, INT_ENABLE);		/* all Interrupt = Mask */
+
+	sd0001_bus_reset();
+
+	/*
+	 * PCI¥Ð¥¹À©¸æ¤ÎÆ°ºî¥â¡¼¥É(MCW0¥ì¥¸¥¹¥¿)ÀßÄê
+	 * ¡¦PCI¥Ð¥¹¤Î¥ê¥È¥é¥¤²ó¿ô : Ìµ¸Â²ó
+	 * ¡¦¥Ð¥¹¥°¥é¥ó¥É¤ÎÍÞ»ß¤Ê¤·
+	 */
+#if __LITTLE_ENDIAN__
+	sd0001_writel(0x0000, PCI_CTL);
+#else
+	sd0001_writel(SD0001_CTL_MASTER_SWAP | SD0001_CTL_PCI_EDCONV, PCI_CTL);
+#endif
+	sd0001_writel(0, PCI_IO_OFFSET);
+	sd0001_writel(PCIBIOS_MIN_MEM, PCI_MEM_OFFSET);
+
+
+	if (request_irq(CONFIG_PCI_SD0001_IRQ, &sd0001_int_pcierr, SA_SHIRQ, "PCI Bus Error", NULL))
+		printk(KERN_ERR "Can't Setup PCI Bus Error Interrupt\n");
+
+	/* FIXME: Enable INT[ABCD] only when devices actually want them.
+	   We should probably demux them so they appear to the kernel as
+	   separate IRQs */
+	sd0001_writel(SD0001_INT_INTEN|SD0001_INT_BUSERR
+		|SD0001_INT_INTD|SD0001_INT_INTC|SD0001_INT_INTB
+		|SD0001_INT_INTA, INT_ENABLE);
+
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+void __init
+pcibios_fixup_pbus_ranges(struct pci_bus * bus,
+	struct pbus_set_ranges_data * ranges)
+{
+	ranges->io_start -= bus->resource[0]->start;
+	ranges->io_end -= bus->resource[0]->start;
+	ranges->mem_start -= bus->resource[1]->start;
+	ranges->mem_end -= bus->resource[1]->start;
+}
+
+
+static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
+{
+        return PCI_SLOT(dev->devfn);
+}
+
+static int __init sd0001_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return CONFIG_PCI_SD0001_IRQ;
+}
+
+void __init pcibios_init(void)
+{
+	printk(KERN_NOTICE "Linux/SH SD0001 PCI Initialise\n");
+	
+	ioport_resource.end = 0xffff;
+	iomem_resource.end = 0xfeffffff;
+
+	pci_setup_sd0001();
+	pci_scan_bus(0, &sd0001_pci_ops, NULL);
+
+	pci_assign_unassigned_resources();
+
+	pci_fixup_irqs(no_swizzle, sd0001_map_irq);
+}
+
+char * __init pcibios_setup(char *str)
+{
+        return str;
+}
+
+extern unsigned long memory_start, memory_end;
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct list_head *list;
+
+	list_for_each(list, &bus->devices) {
+		struct pci_dev *dev = pci_dev_b(list);
+		u16 cmd;
+		if (dev->class >> 8 == PCI_CLASS_BRIDGE_HOST) {
+			memset(&dev->resource[1], 0, sizeof(struct resource));
+			dev->resource[1].start = __pa(memory_start);
+			dev->resource[1].end = __pa(memory_end)-1;
+			dev->resource[1].flags = IORESOURCE_MEM|IORESOURCE_PREFETCH;
+			dev->resource[1].name = "PCI Host RAM";
+			request_resource(&iomem_resource, &dev->resource[1]);
+
+#if 0
+			printk("res1 (@%p) %s %08lx %08lx %x %p %p %p\n", 
+			       &dev->resource[1],
+			       dev->resource[1].name,
+			       dev->resource[1].start,
+			       dev->resource[1].end,
+			       dev->resource[1].flags,
+			       dev->resource[1].parent,
+			       dev->resource[1].sibling,
+			       dev->resource[1].child);
+#endif
+			pcibios_update_resource(dev, bus->resource[1], 
+						&dev->resource[1], 1);
+
+			cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+			pci_write_config_word(dev, PCI_COMMAND, cmd);
+			pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
+		}
+	}
+}
+
+
+
+/* Add future fixups here... */
+struct pci_fixup pcibios_fixups[] = {
+        { 0 }
+};
+
+
+        /*
+         * Mapping for PCI Devices.
+	 * The SD0001 has a 48MiB window onto the PCI memory space, mapped
+	 * into the CPU's address space at 0xb1000000-0xb3ffffff. 
+	 * The range of the PCI space which is accessible is controlled
+	 * by the SD0001's PCI_MEM_OFFSET register, which has a granularity
+	 * of 64MiB. 
+	 *
+	 * As far as I can tell from the little I can understand of
+	 * the SD0001 documentation and from the behaviour of the
+	 * device, you have a 48MiB window which can only be moved
+	 * with 64MiB granularity. Therefore to the best of my
+	 * knowledge, you cannot access any PCI memory address where
+	 * (<addr> & 0x03000000) == 0x03000000, except by going 
+	 * indirectly through the PCI bridge like we do for configuration
+	 * and I/O cycles.
+	 *
+	 * Hopefully, this is untrue and there's some way of doing it that
+	 * I just don't know because I can't read the docs. For now, we
+	 * allow only access to the first 48MiB of PCI memory space.
+	 *
+	 * In addition to that joy, it appears that when accessing PCI
+	 * memory space directly, the SD0001 swaps address lines #21
+	 * and #22, hence the macro below to swap addresses back
+	 * again.
+	 *
+	 * Me and my baseball bat want a quiet word with someone. 
+	 *
+	 * dwmw2.
+         */
+
+#define unmunge(x) (((x) & ~0x00300000) | ( ((x)&0x00100000) << 1) | ( ((x)&0x00200000) >> 1))
+
+void *sd0001_ioremap(unsigned long phys_addr, unsigned long size)
+{
+        unsigned long offset;
+
+	if ((phys_addr & 0xFFF00000) == ((phys_addr+size) & 0xFFF00000)) {
+		/* It fits within a single mebibyte we can still use the 
+		   directly-mapped region... */
+		return (void *)(SD0001_MEM_BASE-(PCIBIOS_MIN_MEM&0xfc000000)+unmunge(phys_addr));
+	}
+
+	/* It crosses a mebibyte boundary and hence we have to
+	   play VM tricks to make the region which is physically
+	   contiguous on the PCI bus but not physically contiguous
+	   on the SH3 bus appear virtually contiguous to the kernel.
+	   Got that? Did I mention my baseball bat yet? */
+	void * addr;
+	struct vm_struct * area;
+		
+	offset = phys_addr & ~PAGE_MASK;
+	phys_addr &= PAGE_MASK;
+	size = PAGE_ALIGN(phys_addr + size - 1) - phys_addr;
+
+	area = get_vm_area(size, VM_IOREMAP);
+	if (!area)
+		return NULL;
+	addr = area->addr;
+
+	phys_addr += SD0001_MEM_BASE;
+	while (size) {
+		unsigned long this_size;
+
+		this_size = 0x100000 - (phys_addr & 0xfffff);
+		this_size = min(this_size, size);
+
+		if (remap_area_pages(VMALLOC_VMADDR(addr),
+				     unmunge(phys_addr), this_size, 
+				     _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_FLAGS_HARD)) {
+			vfree(area->addr);
+			return NULL;
+		}
+		size -= this_size;
+		phys_addr += this_size;
+		addr += this_size;
+	}
+	return (void *) (offset + (char *)area->addr);
+}
+
+void sd0001_iounmap(void *addr)
+{
+	if ((unsigned long)addr >= VMALLOC_START && 
+	    (unsigned long)addr < VMALLOC_END)
+		vfree((void *)((unsigned long)addr & ~PAGE_MASK));
+}
+
+
+static void sd0001_indirect_access_wait(unsigned long i)
+{
+
+	while((sd0001_readl(INDIRECT_STS) & SD0001_INDRCTF_INDFLG)
+	      && --i)
+		;
+
+	if (i == 0) {
+		printk("##### Long Indirect access wait #####\n");
+		mdelay(20);
+	}
+}
+
+static inline void delay(void)
+{
+	ctrl_inw(0xa0000000);
+}
+
+/* PCI IO read long word cycle */
+unsigned long sd0001_inl(unsigned long port)
+{
+	return *(volatile unsigned long *) (SD0001_IO_BASE+port);
+}
+void sd0001_outl(unsigned long value, unsigned long port)
+{
+	*(volatile unsigned long *)(SD0001_IO_BASE+port) = value;
+}
+
+/* The SD0001 doesn't correctly handle byte enables for sub-word
+   accesses, so we have to do it indirectly like we do configuration
+   cycles */
+
+/* PCI IO read byte cycle */
+unsigned char sd0001_inb(unsigned long port)
+{
+	unsigned long work, val, byte_e;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sd0001_indirect_lock, flags);
+	val = 0;
+	byte_e = 0x00010000;
+	work = (port & 0x00000003);
+	byte_e <<= work;
+
+	port &= 0xFFFFFFFC;
+	sd0001_writel(port, INDIRECT_ADR);
+	sd0001_writel(0x00008204 | byte_e, INDIRECT_CTL); /* I/O read cycle */
+	sd0001_indirect_access_wait(100);
+	val = sd0001_readl(INDIRECT_DATA);
+
+	val >>= (work*8);
+	val &= 0x000000FF;
+
+	spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
+
+	return val;
+}
+
+/* PCI IO write byte cycle */
+void sd0001_outb(unsigned char value, unsigned long port)
+{
+	unsigned long work, data, byte_e;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sd0001_indirect_lock, flags);
+	byte_e = 0x00010000;
+	work = (port & 0x00000003);
+	byte_e <<= work;
+
+	data = value;
+	data <<= (work*8);
+
+	port &= 0xFFFFFFFC;
+	sd0001_writel(data, INDIRECT_DATA);
+	sd0001_writel(port, INDIRECT_ADR);
+	sd0001_writel((0x00008308 | byte_e), INDIRECT_CTL);	/* I/O write cycle */
+	sd0001_indirect_access_wait(100);
+
+	spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
+}
+
+/* PCI IO read word cycle */
+unsigned short sd0001_inw(unsigned long port)
+{
+	unsigned long work, val, byte_e;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sd0001_indirect_lock, flags);
+	val = 0;
+	byte_e = 0x00030000;
+	work = (port & 0x00000003);
+	byte_e <<= (work & 0x00000002);
+	work >>= 1;
+
+	port &= 0xFFFFFFFC;
+	sd0001_writel(port, INDIRECT_ADR);
+	sd0001_writel((0x00008204 | byte_e), INDIRECT_CTL);	/* I/O read cycle */
+	sd0001_indirect_access_wait(100);
+	val = sd0001_readl(INDIRECT_DATA) ;
+
+	val >>= (work*16);
+	val &= 0x0000FFFF;
+
+	spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
+
+	return val;
+}
+
+/* PCI IO write word cycle */
+void sd0001_outw(unsigned short value, unsigned long port)
+{
+	unsigned long work, data, byte_e;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sd0001_indirect_lock, flags);
+	byte_e = 0x00030000;
+	work = (port & 0x00000003);
+	byte_e <<= (work & 0x00000002);
+	work >>= 1;
+
+	port &= 0xFFFFFFFC;
+	data = value;
+	data <<= (work*16);
+
+	sd0001_writel(data, INDIRECT_DATA);
+	sd0001_writel(port, INDIRECT_ADR);
+	sd0001_writel((0x00008308 | byte_e), INDIRECT_CTL);	/* I/O write cycle */
+	sd0001_indirect_access_wait(100);
+	spin_unlock_irqrestore(&sd0001_indirect_lock, flags);
+}
+
+void sd0001_insb(unsigned long port, void *addr, unsigned long count)
+{
+
+	while (count--)
+		*((unsigned char *) addr)++ = (unsigned char)sd0001_inb(port);
+}
+
+void sd0001_insw(unsigned long port, void *addr, unsigned long count)
+{
+
+	while (count--)
+		*((unsigned short *) addr)++ = (unsigned short)sd0001_inw(port);
+}
+
+void sd0001_insl(unsigned long port, void *addr, unsigned long count)
+{
+
+	while (count--)
+		*((unsigned long *) addr)++ = sd0001_inl(port);
+}
+
+void sd0001_outsb(unsigned long port, const void *addr, unsigned long count)
+{
+
+	while (count--)
+		sd0001_outb(*((unsigned char *)addr)++, port);
+}
+
+void sd0001_outsw(unsigned long port, const void *addr, unsigned long count)
+{
+
+	while (count--)
+		sd0001_outw(*((unsigned short *)addr)++, port);
+}
+
+void sd0001_outsl(unsigned long port, const void *addr, unsigned long count)
+{
+
+	while (count--)
+		sd0001_outl(*((unsigned long *)addr)++, port);
+}
+
+unsigned char sd0001_inb_p(unsigned long port)
+{
+	unsigned long v;
+
+	v = sd0001_inb(port);
+	delay();
+	return v;
+}
+
+void sd0001_outb_p(unsigned char value, unsigned long port)
+{
+
+	sd0001_outb(value, port);
+	delay();
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/pci-sd0001.h linux-2.4.22-pre10/arch/sh/kernel/pci-sd0001.h
--- linux-2.4.21/arch/sh/kernel/pci-sd0001.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/pci-sd0001.h	2003-08-01 13:35:00.000000000 +0000
@@ -0,0 +1,248 @@
+/*
+ *   $Id: pci-sd0001.h,v 1.1.2.1 2003/06/24 08:40:50 dwmw2 Exp $
+ *
+ *   linux/arch/sh/kernel/pci_sd0001.h
+ *
+ *   Support Hitachi Semcon SD0001 SH3 PCI Host Bridge .
+ *  
+ *
+ *   Copyright (C) 2000  Masayuki Okada (macha@adc.hitachi-ul.co.jp)
+ *                       Hitachi ULSI Systems Co., Ltd.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2, 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
+ *
+ *
+ *
+ *   Revision History
+ *    ----------------
+ *
+ */
+
+/*
+ * SD0001 PCI¥Ö¥ê¥Ã¥¸¡¡¥ì¥¸¥¹¥¿¡¢¥Ó¥Ã¥ÈÄêµÁ
+ */
+
+
+#ifndef __PCI_SD0001_H
+#define __PCI_SD0001_H
+
+#define SD0001_IO_BASE (P2SEGADDR(CONFIG_PCI_SD0001_BASE)+0x00800000)
+#define SD0001_MEM_BASE (P2SEGADDR(CONFIG_PCI_SD0001_BASE)+0x01000000)
+
+#define SD0001_REG(x) ((volatile u32 *)P2SEGADDR(CONFIG_PCI_SD0001_BASE + (x)))
+
+#define sd0001_writel(value, reg) do { *(SD0001_REG(SD0001_REG_##reg)) = value; } while(0)
+#define sd0001_readl(reg) (*(SD0001_REG(SD0001_REG_##reg)))
+
+#define SD0001_REG_REV			(0x00)	/* PCI Class & Revision Code */
+#define SD0001_REG_RESET		(0x08)	/* ¥ê¥»¥Ã¥È */
+#define SD0001_REG_SDRAM_CTL		(0x10)	/* SDRAM ¥â¡¼¥É/À©¸æ */
+#define SD0001_REG_INT_STS1		(0x20)	/* ³ä¤ê¹þÍ×°øÉ½¼¨ */
+#define SD0001_REG_INT_ENABLE		(0x24)	/* ³ä¤ê¹þ¤ß¥Þ¥¹¥¯ */
+#define SD0001_REG_INT_STS2		(0x28)	/* ³ä¹þ¤ß¥¹¥Æ¡¼¥¿¥¹ */
+#define SD0001_REG_DMA1_CTL_STS		(0x30)	/* DMA ¥³¥Þ¥ó¥É & ¥¹¥Æ¡¼¥¿¥¹ */
+#define SD0001_REG_DMA1_SADR		(0x34)	/* DMA ¥½¡¼¥¹¥¢¥É¥ì¥¹ */
+#define SD0001_REG_DMA1_DADR		(0x38)	/* DMA ¥Ç¥£¥¹¥Æ¥£¥Í¡¼¥·¥ç¥ó¥¢¥É¥ì¥¹ */
+#define SD0001_REG_DMA1_CNT		(0x3c)	/* DMA Å¾Á÷¥Ð¥¤¥È¿ô */
+#define SD0001_REG_DMA2_CTL_STS		(0x40)	/* DMA ¥³¥Þ¥ó¥É & ¥¹¥Æ¡¼¥¿¥¹ */
+#define SD0001_REG_DMA2_SADR		(0x44)	/* DMA ¥½¡¼¥¹¥¢¥É¥ì¥¹ */
+#define SD0001_REG_DMA2_DADR		(0x48)	/* DMA ¥Ç¥£¥¹¥Æ¥£¥Í¡¼¥·¥ç¥ó¥¢¥É¥ì¥¹ */
+#define SD0001_REG_DMA2_CNT		(0x4c)	/* DMA Å¾Á÷¥Ð¥¤¥È¿ô */
+#define SD0001_REG_PCI_CTL		(0x50)	/* PCI¥Ð¥¹Æ°ºî¥â¡¼¥É */
+#define SD0001_REG_PCI_IO_OFFSET	(0x58)	/* PCIÄ¾ÀÜI/O¥¢¥¯¥»¥¹¥ª¥Õ¥»¥Ã¥È */
+#define SD0001_REG_PCI_MEM_OFFSET	(0x5c)	/* PCIÄ¾ÀÜ¥á¥â¥ê¥¢¥¯¥»¥¹¥ª¥Õ¥»¥Ã¥È */
+#define SD0001_REG_INDIRECT_ADR		(0x60)	/* PCI Configuration¥ì¥¸¥¹¥¿¥¢¥É¥ì¥¹ */
+#define SD0001_REG_INDIRECT_DATA	(0x64)	/* PCI Configuration¥Ç¡¼¥¿¥ì¥¸¥¹¥¿ */
+#define SD0001_REG_INDIRECT_CTL		(0x68)	/* PCI¥Ð¥¹´ÖÀÜ¥¢¥¯¥»¥¹À©¸æ */
+#define SD0001_REG_INDIRECT_STS		(0x6c)	/* PCI¥Ð¥¹´ÖÀÜ¥¢¥¯¥»¥¹¥¹¥Æ¡¼¥¿¥¹ */
+#define SD0001_REG_AWAKE		(0x70)	/* AWAKE³ä¹þ¤ß */
+#define SD0001_REG_MAIL			(0x74)	/* MailÄÌ¿® */
+
+
+/*
+ * SD0001 ¥ì¥¸¥¹¥¿¤Î³Æ¥Ó¥Ã¥È¤Îµ¡Ç½¤ÎÄêµÁ
+ */
+/* MODE ¥ì¥¸¥¹¥¿ */
+
+/* RST ¥ì¥¸¥¹¥¿ */
+#define	 SD0001_RST_SWRST		0x80000000	/* SD0001¤Î¥ê¥»¥Ã¥È */
+#define	 SD0001_RST_BUSRST		0x40000000	/* PCI¥Ð¥¹¥½¥Õ¥È¥ê¥»¥Ã¥È */
+#define	 SD0001_RST_MASK		0xc0000000	/* RST¥ì¥¸¥¹¥¿ÀßÄê¥Þ¥¹¥¯ */
+
+
+/* SH3 SD0001  PCI Devices Space & Mamory Size */
+#define	 SD0001_PCI_IO_WINDOW		0x00800000	/* PCI I/O¶õ´Ö Window: 8MiB */
+#define	 SD0001_PCI_MEM_WINDOW		0x03000000	/* PCI MEM¶õ´Ö Window: 48MiB */
+#define  SD0001_PCI_WINDOW_SHIFT	22		
+#define	 SD0001_SDRAM_MAX		0x04000000	/* SDMAN¥µ¥¤¥º 64MiB */
+
+
+/* pci_ctl ¥ì¥¸¥¹¥¿ */
+#define  SD0001_CTL_MASTER_SWAP		0x80000000	/* PCI¥Ð¥¹¥Þ¥¹¥¿¡¼Å¾Á÷»þ¤Î
+							   Byte Swap ON */
+#define  SD0001_CTL_PCI_EDCONV		0x40000000	/* PCI¥Ç¥Ð¥¤¥¹¥¢¥¯¥»¥¹»þ¤Î
+							   EndianÊÑ´¹ ON */
+#define	 SD0001_CTL_RETRY_MASK		0x000000f0	/* PCI¥ê¥È¥é¥¤¥ª¡¼¥Ð¸¡½Ð¥«¥¦¥ó¥ÈÃÍ */
+#define  SD0001_CTL_NOGNT		0x00000002	/* PCI GNT¿®¹æ¤ÎÈ¯¹ÔÄä»ß */
+
+/* SD_MDCTL ¥ì¥¸¥¹¥¿ */
+#define	 SD0001_SDMD_KIND_MASK		0xc0000000	/* SDRAM ¼ïÊÌ ÀßÄê¥Þ¥¹¥¯*/
+#define	 SD0001_SDMD_KIND_16		0x00000000	/* SDRAM 16Mbits */
+#define	 SD0001_SDMD_KIND_64		0x40000000	/* SDRAM 64Mbits */
+#define	 SD0001_SDMD_KIND_128		0x80000000	/* SDRAM 128Mbits */
+#define	 SD0001_SDMD_KIND_256		0xc0000000	/* SDRAM 256Mbits */
+#define	 SD0001_SDMD_SIZE_MASK		0x30000000	/* SDRAM SIZE ÀßÄê¥Þ¥¹¥¯ */
+#define	 SD0001_SDMD_SIZE_4		0x00000000	/* ¥Ç¡¼¥¿¥Ð¥¹ 4bits */
+#define	 SD0001_SDMD_SIZE_8		0x10000000	/* ¥Ç¡¼¥¿¥Ð¥¹ 8bits */
+#define	 SD0001_SDMD_SIZE_16		0x20000000	/* ¥Ç¡¼¥¿¥Ð¥¹ 16bits */
+#define	 SD0001_SDMD_SIZE_32		0x30000000	/* ¥Ç¡¼¥¿¥Ð¥¹ 32bits */
+#define	 SD0001_SDMD_REF_MASK		0x0000f000	/* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë ÀßÄê¥Þ¥¹¥¯ */
+#define	 SD0001_SDMD_REF_DEF		0x00000000	/* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë ¥Ç¥Õ¥©¥ë¥È(128cycles) */
+#define	 SD0001_SDMD_REF_128		0x00001000	/* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 128cycles */
+#define	 SD0001_SDMD_REF_256		0x00002000	/* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 256cycles */
+#define	 SD0001_SDMD_REF_384		0x00003000	/* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 384cycles */
+#define	 SD0001_SDMD_REF_512		0x00004000	/* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 512cycles */
+#define	 SD0001_SDMD_REF_640		0x00005000	/* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 640cycles */
+#define	 SD0001_SDMD_REF_768		0x00006000	/* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 768cycles */
+#define	 SD0001_SDMD_REF_896		0x00007000	/* ¥ê¥Õ¥ì¥Ã¥·¥å¡¦¥µ¥¤¥¯¥ë 896cycles */
+#define	 SD0001_SDMD_REF_STOP		0x00008000	/* ¥ê¥Õ¥ì¥Ã¥·¥åÄä»ß */
+
+#define	 SD0001_SDMD_LMODE_MASK		0x00000070	/* CAS¥ì¥¤¥Æ¥ó¥· ÀßÄê¥Þ¥¹¥¯ */
+#define  SD0001_SDMD_LMODE_1		0x00000000	/* CAS¥ì¥¤¥Æ¥ó¥· 1 */
+#define  SD0001_SDMD_LMODE_2		0x00000010	/* CAS¥ì¥¤¥Æ¥ó¥· 2 */
+#define  SD0001_SDMD_LMODE_3		0x00000020	/* CAS¥ì¥¤¥Æ¥ó¥· 3 */
+#define  SD0001_SDMD_MASK		0xf000f070	/* SDMS ÀßÄê¥Þ¥¹¥¯ */
+
+
+/* ³ä¤ê¹þ¤ß ¥Þ¥¹¥¯ */
+#define	 SD0001_INT_INTEN		0x80000000	/* Á´³ä¤ê¹þ¤ß¥Þ¥¹¥¯ */
+#define	 SD0001_INT_RETRY		0x20000000	/* PCI¥Ð¥¹¥ê¥È¥é¥¤²ó¿ô¥ª¡¼¥Ð¡¼ */
+#define	 SD0001_INT_TO			0x10000000	/* PCI¥Ð¥¹¥¿¥¤¥à¥¢¥¦¥È */
+#define	 SD0001_INT_SSERR		0x08000000	/* SERR#¥¢¥µ¡¼¥È */
+#define	 SD0001_INT_RSERR		0x04000000	/* SERR#¸¡½Ð */
+#define	 SD0001_INT_RPERR		0x02000000	/* PERR#¸¡½Ð */
+#define	 SD0001_INT_SPERR		0x01000000	/* PERR#¥¢¥µ¡¼¥È */
+#define	 SD0001_INT_STABT		0x00800000	/* ¥¿¡¼¥²¥Ã¥È¥¢¥Ü¡¼¥ÈÈ¯¹Ô */
+#define	 SD0001_INT_RTABT		0x00400000	/* ¥¿¡¼¥²¥Ã¥È¥¢¥Ü¡¼¥È¸¡½Ð */
+#define	 SD0001_INT_LOCK		0x00200000	/* ¥Ç¥Ã¥É¥í¥Ã¥¯¸¡½Ð */
+#define	 SD0001_INT_RMABT		0x00100000	/* ¥Þ¥¹¥¿¡¼¥¢¥Ü¡¼¥È¸¡½Ð */
+#define	 SD0001_INT_BUSERR		0x3ff00000	/* PCI¥Ð¥¹¥¨¥é¡¼³ä¹þ¤ß */
+#define	 SD0001_INT_AWINT		0x00001000	/* AWAKE³ä¹þ¤ß */
+#define	 SD0001_INT_DMA1		0x00000020	/* DMA¥Á¥ã¥Í¥ë1´°Î» */
+#define	 SD0001_INT_DMA2		0x00000010	/* DMA¥Á¥ã¥Í¥ë2´°Î» */
+#define	 SD0001_INT_INTD		0x00000008	/* PCI¥Ð¥¹INTD# */
+#define	 SD0001_INT_INTC		0x00000004	/* PCI¥Ð¥¹INTC# */
+#define	 SD0001_INT_INTB		0x00000002	/* PCI¥Ð¥¹INTB# */
+#define	 SD0001_INT_INTA		0x00000001	/* PCI¥Ð¥¹INTA# */
+#define	 SD0001_INT_VAILD		0x3ff0103f	/* ³ä¤ê¹þ¤ßÍ­¸ú¥Ó¥Ã¥È */
+
+/* CONFIG_ADDRESS ¥ì¥¸¥¹¥¿ */
+#define	 SD0001_CONFIG_ADDR_EN		0x80000000	/* ¥³¥ó¥Õ¥£¥°¥ì¡¼¥·¥ç¥ó¥µ¥¤¥¯¥ë¥¤¥Í¡¼¥Ö¥ë */
+
+
+/* INDRCT_CMD ¥ì¥¸¥¹¥¿ */
+#define	 SD0001_INDRCTC_BE_MASK		0x000f0000	/* ¥Ð¥¤¥È¥¤¥Í¡¼¥Ö¥ë */
+#define	 SD0001_INDRCTC_BE_BYTE		0x00010000	/* ¥Ð¥¤¥È¥¢¥¯¥»¥¹³«»Ï°ÌÃÖ */
+#define	 SD0001_INDRCTC_BE_WORD		0x00030000	/* ¥ï¡¼¥É¥¢¥¯¥»¥¹³«»Ï°ÌÃÖ */
+#define	 SD0001_INDRCTC_BE_LONG		0x000f0000	/* ¥í¥ó¥°¥ï¡¼¥É¥¢¥¯¥»¥¹ */
+#define	 SD0001_INDRCTC_CMDEN		0x00008000	/* CMD Enable */
+#define	 SD0001_INDRCTC_CMD_IOR		0x00000200	/* I/O Read CMD */
+#define	 SD0001_INDRCTC_CMD_IOW		0x00000300	/* I/O Write CMD */
+#define	 SD0001_INDRCTC_CMD_MEMR	0x00000600	/* Memory Read CMD */
+#define	 SD0001_INDRCTC_CMD_MEMW	0x00000700	/* Memory Write CMD */
+#define	 SD0001_INDRCTC_CMD_INTA	0x00000000	/* Interrupt Ack CMD */
+#define	 SD0001_INDRCTC_CMD_MASK	0x00000f00	/* CMD ¥³¡¼¥É */
+#define	 SD0001_INDRCTC_FLGRESET	0x00000080	/* INDRCT_FLG¤Î¥¨¥é¡¼¥Õ¥é¥°¤Î¥ê¥»¥Ã¥È */
+#define	 SD0001_INDRCTC_IOWT		0x00000008	/* ´ÖÀÜI/O¥é¥¤¥È»Ø¼¨ */
+#define	 SD0001_INDRCTC_IORD		0x00000004	/* ´ÖÀÜI/O¥ê¡¼¥É»Ø¼¨ */
+#define	 SD0001_INDRCTC_COWT		0x00000002	/* ¥³¥ó¥Õ¥£¥°¥ì¡¼¥·¥ç¥ó¥é¥¤¥È»Ø¼¨ */
+#define	 SD0001_INDRCTC_CORD		0x00000001	/* ¥³¥ó¥Õ¥£¥°¥ì¡¼¥·¥ç¥ó¥ê¡¼¥É»Ø¼¨ */
+#define	 SD0001_INDRCTC_MASK		0x000f8f8f	/* INDRCT_CMD ÀßÄê»þ¥Þ¥¹¥¯ */
+
+/* INDRCT_FLG ¥ì¥¸¥¹¥¿ */
+#define	 SD0001_INDRCTF_MABTRCV		0x00080000	/* ¥Þ¥¹¥¿¡¼¥¢¥Ü¡¼¥ÈÈ¯À¸ */
+#define	 SD0001_INDRCTF_INDFLG		0x00000001	/* ´ÖÀÜ¥¢¥¯¥»¥¹¼Â¹ÔÃæ */
+
+
+/* Awake ¥ì¥¸¥¹¥¿ */
+#define	 SD0001_AWAKE_AWOK		0x80000000	/* AWAKE READÉ½¼¨ */
+#define	 SD0001_AWAKE_AWV		0x7fffffff	/* AWAKE READÉÕ¿ï¾ðÊó */
+
+/* Mail ¥ì¥¸¥¹¥¿ */
+#define	 SD0001_MAIL_FLAG		0x80000000	/* MAIL ³ä¹þ¤ßÈ¯À¸ */
+#define	 SD0001_MAIL_DATA		0x7fffffff	/* MAIL ³ä¹þ¤ßÉÕ¿ï¾ðÊó */
+
+
+/*
+ * SD0001 ÆâÂ¢ DMAC ¥ì¥¸¥¹¥¿µ¡Ç½ÄêµÁ
+ */
+
+/* DMATCR ¥ì¥¸¥¹¥¿ */
+#define	 SD0001_DMATCR_MASK		0x0fffffff	/* DMATCRÀßÄê¥Þ¥¹¥¯ */
+#define	 SD0001_DMATCR_MAX		0x04000000	/* ºÇÂçÅ¾Á÷¥Ð¥¤¥È¿ô */
+
+
+
+/* DMCMD ¥ì¥¸¥¹¥¿ */
+#define	 SD0001_DMCMD_EXEC		0x80000000	/* DMA³«»Ï»Ø¼¨ / ¼Â¹ÔÃæÉ½¼¨ */
+#define	 SD0001_DMCMD_NEND		0x40000000	/* DMAÀ®¸ù¤Ë¤è¤ë´°Î» */
+#define	 SD0001_DMCMD_AEND		0x20000000	/* DMA¼ºÇÔ¤Ë¤è¤ë´°Î» */
+#define	 SD0001_DMCMD_STATUS		0x60000000	/* DMA´°Î»¥¹¥Æ¡¼¥¿¥¹ */
+
+#define  SD0001_DMCMD_SWAP		0x00010000	/* Å¾Á÷¥Ç¡¼¥¿¤Î Byte Swap */
+#define	 SD0001_DMCMD_DSR_RAM_PCI	0x00000100	/* DMAÅ¾Á÷Êý¸þ¡§ SDRAM ¢ª PCI */
+#define	 SD0001_DMCMD_DSR_PCI_RAM	0x00000200	/* DMAÅ¾Á÷Êý¸þ¡§ PCI ¢ª SDRAM */
+#define	 SD0001_DMCMD_DSR_RAM_RAM	0x00000000	/* DMAÅ¾Á÷Êý¸þ¡§ SDRAM ¢ª SDRAM */
+#define	 SD0001_DMCMD_MASK		0xe0010f00	/* DMCMD¥ì¥¸¥¹¥¿ÀßÄê¥Þ¥¹¥¯ */
+
+
+/* INTM PCI ¥ì¥¸¥¹¥¿ */
+#define  SD0001_INTMPCI_PERR		0x80000000	/* Detected Perr ³ä¹þ¤ß¥Þ¥¹¥¯ */
+#define  SD0001_INTMPCI_SERR		0x40000000	/* Signalled SERR ³ä¹þ¤ß¥Þ¥¹¥¯ */
+#define  SD0001_INTMPCI_MBAT		0x20000000	/* Received Master Abort ³ä¹þ¤ß¥Þ¥¹¥¯ */
+#define  SD0001_INTMPCI_RTABT		0x10000000	/* Received Target Abort ³ä¹þ¤ß¥Þ¥¹¥¯ */
+#define  SD0001_INTMPCI_STABT		0x08000000	/* Signalled Target Abort ³ä¹þ¤ß¥Þ¥¹¥¯ */
+#define  SD0001_INTMPCI_DPERR		0x01000000	/* DPerr Detected ³ä¹þ¤ß¥Þ¥¹¥¯ */
+#define  SD0001_INTMPCI_MAIL		0x00800000	/* MAIL¥ì¥¸¥¹¥¿³ä¹þ¤ß */
+
+
+/* RESET PCI ¥ì¥¸¥¹¥¿*/
+#define  SD0001_RSTPCI_SWRST		0x80000000	/* ¥¿¡¼¥²¥Ã¥È¥Ç¥Ð¥¤¥¹ ¥ê¥»¥Ã¥È */
+#define  SD0001_RSTPCI_ALIVE		0x40000000	/* ¥¿¡¼¥²¥Ã¥È¥â¡¼¥É¤Î»þ¤ÎRESET¥ì¥¸¥¹¥¿¤Î */
+							/*    bit30(PCIRST)¤ÎÃÍ¡£ Read Only */
+
+
+extern int pci_setup_sd0001(void);
+
+void sd0001_outl(unsigned long, unsigned long); 
+unsigned long sd0001_inl(unsigned long);
+void sd0001_outw(unsigned short, unsigned long);
+unsigned short sd0001_inw(unsigned long);
+void sd0001_outb(unsigned char, unsigned long);
+unsigned char sd0001_inb(unsigned long);
+void sd0001_insb(unsigned long, void *, unsigned long);
+void sd0001_insw(unsigned long, void *, unsigned long);
+void sd0001_insl(unsigned long, void *, unsigned long);
+void sd0001_outsb(unsigned long, const void *, unsigned long);
+void sd0001_outsw(unsigned long, const void *, unsigned long);
+void sd0001_outsl(unsigned long, const void *, unsigned long);
+unsigned char sd0001_inb_p(unsigned long);
+void sd0001_outb_p(unsigned char, unsigned long);
+
+void *sd0001_ioremap(unsigned long, unsigned long);
+void sd0001_iounmap(void *);
+
+
+#endif /* __PCI_SD0001_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/pci-sh7751.c linux-2.4.22-pre10/arch/sh/kernel/pci-sh7751.c
--- linux-2.4.21/arch/sh/kernel/pci-sh7751.c	2001-11-04 17:31:58.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/pci-sh7751.c	2003-08-01 13:33:58.000000000 +0000
@@ -38,8 +38,6 @@
  * Direct access to PCI hardware...
  */
 
-#ifdef CONFIG_PCI_DIRECT
-
 
 #define CONFIG_CMD(dev, where) (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
 
@@ -226,20 +224,6 @@
 	return NULL;
 }
 
-#endif
-
-/*
- * BIOS32 and PCI BIOS handling.
- * 
- * The BIOS version of the pci functions is not yet implemented but it is left
- * in for completeness.  Currently an error will be generated at compile time. 
- */
- 
-#ifdef CONFIG_PCI_BIOS
-
-#error PCI BIOS is not yet supported on SH7751
-
-#endif /* CONFIG_PCI_BIOS */
 
 /***************************************************************************************/
 
@@ -342,16 +326,9 @@
 	struct pci_ops *dir = NULL;
 
 	PCIDBG(1,"PCI: Starting intialization.\n");
-#ifdef CONFIG_PCI_BIOS
-	if ((pci_probe & PCI_PROBE_BIOS) && ((bios = pci_find_bios()))) {
-		pci_probe |= PCI_BIOS_SORT;
-		pci_bios_present = 1;
-	}
-#endif
-#ifdef CONFIG_PCI_DIRECT
+
 	if (pci_probe & PCI_PROBE_CONF1 )
 		dir = pci_check_direct();
-#endif
 	if (dir) {
 		pci_root_ops = dir;
 	    if(!pcibios_init_platform())
@@ -372,11 +349,6 @@
 	pci_fixup_irqs(pcibios_swizzle, pcibios_lookup_irq);
 	pcibios_fixup_peer_bridges();
 	pcibios_resource_survey();
-
-#ifdef CONFIG_PCI_BIOS
-	if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
-		pcibios_sort();
-#endif
 }
 
 char * __init pcibios_setup(char *str)
@@ -384,29 +356,10 @@
 	if (!strcmp(str, "off")) {
 		pci_probe = 0;
 		return NULL;
-	}
-#ifdef CONFIG_PCI_BIOS
-	else if (!strcmp(str, "bios")) {
-		pci_probe = PCI_PROBE_BIOS;
-		return NULL;
-	} else if (!strcmp(str, "nobios")) {
-		pci_probe &= ~PCI_PROBE_BIOS;
-		return NULL;
-	} else if (!strcmp(str, "nosort")) {
-		pci_probe |= PCI_NO_SORT;
-		return NULL;
-	} else if (!strcmp(str, "biosirq")) {
-		pci_probe |= PCI_BIOS_IRQ_SCAN;
-		return NULL;
-	}
-#endif
-#ifdef CONFIG_PCI_DIRECT
-	else if (!strcmp(str, "conf1")) {
+	} else if (!strcmp(str, "conf1")) {
 		pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
 		return NULL;
-	}
-#endif
-	else if (!strcmp(str, "rom")) {
+	} else if (!strcmp(str, "rom")) {
 		pci_probe |= PCI_ASSIGN_ROMS;
 		return NULL;
 	} else if (!strncmp(str, "lastbus=", 8)) {
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/pci-snapgear.c linux-2.4.22-pre10/arch/sh/kernel/pci-snapgear.c
--- linux-2.4.21/arch/sh/kernel/pci-snapgear.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/pci-snapgear.c	2003-08-01 13:33:15.000000000 +0000
@@ -0,0 +1,188 @@
+/*
+ * linux/arch/sh/kernel/pci-snapgear.c
+ *
+ * Author:  David McCullough <davidm@snapgear.com>
+ *
+ * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * PCI initialization for the SnapGear boards
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+#include <asm/pci-sh7751.h>
+
+#define PCI_REG(reg)        (SH7751_PCIREG_BASE+reg)
+
+/* PCI: default LOCAL memory window sizes (seen from PCI bus) */
+#define SNAPGEAR_LSR0_SIZE    (64*(1<<20)) //64MB
+#define SNAPGEAR_LSR1_SIZE    (64*(1<<20)) //64MB
+
+/*
+ * Initialize the SnapGear PCI interface 
+ * Setup hardware to be Central Funtion
+ * Copy the BSR regs to the PCI interface
+ * Setup PCI windows into local RAM
+ */
+int __init pcibios_init_platform(void) {
+	u32 reg;
+	u32 word;
+	u32 id;
+
+	PCIDBG(1,"PCI: snapgear_pci_init called\n");
+	/* Set the BCR's to enable PCI access */
+	reg = inl(SH7751_BCR1);
+	reg |= 0x80000;
+	outl(reg, SH7751_BCR1);
+	
+	/* check for SH7751/SH7751R hardware */
+	id = inl(SH7751_PCIREG_BASE+SH7751_PCICONF0);
+	switch (id) {
+	case (SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID:
+		printk("PCI: SH7751 PCI host bridge found.\n");
+		break;
+	case (SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID:
+		printk("PCI: SH7751R PCI host bridge found.\n");
+		break;
+	default:
+		printk("PCI: Unknown PCI host bridge (id=0x%x).\n", id);
+		return(0);
+	}
+	
+	/* Turn the clocks back on (not done in reset)*/
+	outl(0, PCI_REG(SH7751_PCICLKR));
+	/* Clear Powerdown IRQ's (not done in reset) */
+	word = SH7751_PCIPINT_D3 | SH7751_PCIPINT_D0;
+	outl(word, PCI_REG(SH7751_PCICLKR));
+
+#if 0
+/*
+ *	This code is removed as it is done in the bootloader and doing it
+ *	here means the MAC addresses loaded by the bootloader get lost
+ */
+	/* toggle PCI reset pin */
+	word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST;
+	outl(word,PCI_REG(SH7751_PCICR));    
+	/* Wait for a long time... not 1 sec. but long enough */
+	mdelay(100);
+	word = SH7751_PCICR_PREFIX;
+	outl(word,PCI_REG(SH7751_PCICR)); 
+#endif
+	
+    /* set the command/status bits to:
+     * Wait Cycle Control + Parity Enable + Bus Master +
+     * Mem space enable
+     */
+    word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | 
+           SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES;
+	outl(word, PCI_REG(SH7751_PCICONF1));
+
+	/* define this host as the host bridge */
+	word = SH7751_PCI_HOST_BRIDGE << 24;
+	outl(word, PCI_REG(SH7751_PCICONF2));
+
+	/* Set IO and Mem windows to local address 
+	 * Make PCI and local address the same for easy 1 to 1 mapping 
+	 * Window0 = SNAPGEAR_LSR0_SIZE @ non-cached CS2 base = SDRAM
+	 * Window1 = SNAPGEAR_LSR1_SIZE @ cached CS2 base = SDRAM 
+	 */
+	word = SNAPGEAR_LSR0_SIZE - 1;
+	outl(word, PCI_REG(SH7751_PCILSR0));
+	word = SNAPGEAR_LSR1_SIZE - 1;
+	outl(word, PCI_REG(SH7751_PCILSR1));
+	/* Set the values on window 0 PCI config registers */
+	word = P2SEGADDR(SH7751_CS2_BASE_ADDR);
+	outl(word, PCI_REG(SH7751_PCILAR0));
+	outl(word, PCI_REG(SH7751_PCICONF5));
+	/* Set the values on window 1 PCI config registers */
+	word =  PHYSADDR(SH7751_CS2_BASE_ADDR);
+	outl(word, PCI_REG(SH7751_PCILAR1));
+	outl(word, PCI_REG(SH7751_PCICONF6));
+
+	/* Set the local 16MB PCI memory space window to 
+	 * the lowest PCI mapped address
+	 */
+	word = PCIBIOS_MIN_MEM & SH7751_PCIMBR_MASK;
+	PCIDBG(2,"PCI: Setting upper bits of Memory window to 0x%x\n", word);
+	outl(word , PCI_REG(SH7751_PCIMBR));
+
+	/* Map IO space into PCI IO window
+	 * The IO window is 64K-PCIBIOS_MIN_IO in size
+	 * IO addresses will be translated to the 
+	 * PCI IO window base address
+	 */
+	PCIDBG(3,"PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO,
+	    (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO);
+	    
+	/* Make sure the MSB's of IO window are set to access PCI space correctly */
+	word = PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK;
+	PCIDBG(2,"PCI: Setting upper bits of IO window to 0x%x\n", word);
+	outl(word, PCI_REG(SH7751_PCIIOBR));
+	
+	/* Set PCI WCRx, BCRx's, copy from BSC locations */
+	word = inl(SH7751_BCR1);
+	/* check BCR for SDRAM in area 3 */
+	if(((word >> 2) & 1) == 0) {
+		printk("PCI: Area 2 is not configured for SDRAM. BCR1=0x%x\n", word);
+		return 0;
+	}
+	outl(word, PCI_REG(SH7751_PCIBCR1));
+	word = (u16)inw(SH7751_BCR2);
+	/* check BCR2 for 32bit SDRAM interface*/
+	if(((word >> 4) & 0x3) != 0x3) {
+		printk("PCI: Area 2 is not 32 bit SDRAM. BCR2=0x%x\n", word);
+		return 0;
+	}
+	outl(word, PCI_REG(SH7751_PCIBCR2));
+	/* configure the wait control registers */
+	word = inl(SH7751_WCR1);
+	outl(word, PCI_REG(SH7751_PCIWCR1));
+	word = inl(SH7751_WCR2);
+	outl(word, PCI_REG(SH7751_PCIWCR2));
+	word = inl(SH7751_WCR3);
+	outl(word, PCI_REG(SH7751_PCIWCR3));
+	word = inl(SH7751_MCR);
+	outl(word, PCI_REG(SH7751_PCIMCR));
+
+	/* NOTE: I'm ignoring the PCI error IRQs for now..
+	 * TODO: add support for the internal error interrupts and
+	 * DMA interrupts...
+	 */
+	 
+	/* SH7751 init done, set central function init complete */
+	/* use round robin mode to stop a device starving/overruning */
+	word = SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN | SH7751_PCICR_ARBM;
+	outl(word,PCI_REG(SH7751_PCICR)); 
+	PCIDBG(2,"PCI: snapgear_pci_init finished\n");
+
+	return 1;
+}
+
+int __init pcibios_map_platform_irq(u8 slot, u8 pin)
+{
+	int irq = -1;
+
+	switch (slot) {
+	case 8:  /* the PCI bridge */ break;
+	case 11: irq = 8;  break; /* USB    */
+	case 12: irq = 11; break; /* PCMCIA */
+	case 13: irq = 5;  break; /* eth0   */
+	case 14: irq = 8;  break; /* eth1   */
+	case 15: irq = 11; break; /* safenet (unused) */
+	}
+
+    printk("PCI: Mapping SnapGear IRQ for slot %d, pin %c to irq %d\n",
+			slot, pin - 1 + 'A', irq);
+
+    return irq;
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/pci-v320usc.c linux-2.4.22-pre10/arch/sh/kernel/pci-v320usc.c
--- linux-2.4.21/arch/sh/kernel/pci-v320usc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/pci-v320usc.c	2003-08-01 13:30:57.000000000 +0000
@@ -0,0 +1,518 @@
+/****************************************************************************/
+/*
+ * pci.c: V3 Hurricane specific PCI support.
+ *
+ * Copyright (C) 1999,2000 Dan Aizenstros (dan@vcubed.com)
+ * Copyright (C) 2001, Lineo Inc., <davidm@moreton.com.au>
+ *               SH3 port.
+ */
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/autoconf.h>
+#include <asm/byteorder.h>
+#include <asm/pci.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+
+#include "pci-v320usc.h"
+
+/****************************************************************************/
+#ifdef CONFIG_PCI
+/****************************************************************************/
+
+#ifndef CONFIG_PCMCIA
+#define V320USC_MEM_SPACE	0xB8000000 /* V320 sees this as AC000000 ! */
+#define V320USC_IO_SPACE	0xB4000000
+#define V320USC_CONF_SPACE	0xB4000000
+#else
+#define V320USC_MEM_SPACE	0xab000000
+#define V320USC_IO_SPACE	0xaa000000
+#define V320USC_CONF_SPACE	0xaa000000
+#endif
+#define	V320USC_BASE		0xb1fd0000
+
+#ifdef __LITTLE_ENDIAN
+#define reg08(x)	(V320USC_BASE + (V320USC_##x))
+#define reg16(x)	(V320USC_BASE + (V320USC_##x))
+#else
+#define reg08(x)	(V320USC_BASE + ((V320USC_##x)^3))
+#define reg16(x)	(V320USC_BASE + ((V320USC_##x)^2))
+#endif
+
+#define reg32(x)	(V320USC_BASE + (V320USC_##x))
+
+#define v320usc_inb(addr)			readb(reg08(addr)
+#define v320usc_outb(value, addr)	writeb(value, reg08(addr))
+#define v320usc_inw(addr)			readw(reg16(addr))
+#define v320usc_outw(value, addr)	writew(value, reg16(addr))
+#define v320usc_inl(addr)			readl(reg32(addr))
+#define v320usc_outl(value, addr)	writel(value, reg32(addr))
+
+/****************************************************************************/
+
+/* Set the LB_PCI_BASE0 register to allow PCI Memory cycles to be used */
+
+static void set_io_cycles(void)
+{
+	u32 tempscratch;
+
+	v320usc_outl(
+		(v320usc_inl(LB_PCI_BASE0) &
+		~(LB_PCI_BASEX_PCI_CMD_MASK | LB_PCI_BASEX_ALOW_MASK))
+		| LB_PCI_BASEX_IO, LB_PCI_BASE0);
+
+	/* do a read of the register to flush the posting buffer */
+	tempscratch = v320usc_inl(LB_PCI_BASE0);
+}
+
+
+/* Set the LB_PCI_BASE0 register to allow PCI Config cycles to be used */
+static void set_config_cycles(int alow)
+{
+	u32 tempscratch;
+
+	tempscratch = v320usc_inl(LB_PCI_BASE0);
+
+	v320usc_outl((tempscratch & 
+		~(LB_PCI_BASEX_PCI_CMD_MASK | LB_PCI_BASEX_ALOW_MASK))
+		| LB_PCI_BASEX_CONFIG | alow, LB_PCI_BASE0);
+
+	/* do a read of the register to flush the posting buffer */
+	tempscratch = v320usc_inl(LB_PCI_BASE0);
+}
+
+
+static int mkaddr (unsigned char bus,
+		unsigned char devfn,
+		unsigned char where)
+{
+	int addr, alow;
+
+	if (bus) {
+		addr =  ((bus    & 0xff) << 0x10) | 
+			((devfn & 0xff) << 0x08) |
+			 (where  & 0xff);
+
+		/* set alow for type 1 configuration cycle */
+		alow = 1;
+	} else {
+		int device, function;
+
+		if (devfn >= PCI_DEVFN(12, 0))
+			return -1;
+
+		device = PCI_SLOT(devfn);
+		function = PCI_FUNC(devfn);
+
+		/* This next line assumes that the PCI backplane connects  */
+		/* the IDSEL line for each slot to a Address line with a   */
+		/* small value resistor.  Note: The PCI spec. suggests     */
+		/* several options here.  This code assumes the following  */
+		/* IDSEL to Address line mapping.                          */
+
+		/* Slot  Address Line */
+		/*  0  - AD11 */
+		/*  1  - AD12 */
+		/*  2  - AD13 */
+		/*  3  - AD14 */
+		/*  4  - AD15 */
+
+		/* 0x800 is AD11 set, shift left by the slot number (device) */
+		addr = (0x800 << device) | (function << 8) | where;
+		
+		/* set alow for type 0 configuration cycle */
+		alow = 0;
+	}
+
+	set_config_cycles(alow);
+
+	return addr;
+}
+
+
+static int v320usc_pcibios_read_config_byte (
+						struct pci_dev *dev,
+						int where,
+						u8 *val)
+{
+	int retVal = PCIBIOS_SUCCESSFUL;
+	unsigned long flags;
+	int addr;
+
+	save_and_cli(flags);
+
+	/* Clear status bits */
+	v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W);
+
+	if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
+		retVal = -1;
+	else {
+		// *val = readb(V320USC_CONF_SPACE + addr);
+		*val = * (unsigned char *) (V320USC_CONF_SPACE + addr);
+
+		/* Check for master abort */
+		if (v320usc_inw(PCI_STAT_W) & PCI_STAT_W_M_ABORT) {
+			v320usc_outw(0xffff, PCI_STAT_W);
+			// printk("Master abort byte\n");
+			*val = 0xff;
+		}
+	}
+
+	set_io_cycles();
+	restore_flags(flags);
+	return retVal;
+}
+
+
+static int v320usc_pcibios_read_config_word (
+						struct pci_dev *dev,
+						int where,
+						u16 *val)
+{
+	int retVal = PCIBIOS_SUCCESSFUL;
+	unsigned long flags;
+	int addr;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	save_and_cli(flags);
+
+	/* Clear status bits */
+	v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W);
+
+	if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
+		retVal = -1;
+	else {
+		*val = readw(V320USC_CONF_SPACE + addr);
+
+		/* Check for master abort */
+		if (v320usc_inw(PCI_STAT_W) & PCI_STAT_W_M_ABORT) {
+			v320usc_outw(0xffff, PCI_STAT_W);
+			// printk("Master abort word\n");
+			*val = 0xffff;
+		}
+	}
+
+	set_io_cycles();
+
+	restore_flags(flags);
+
+	return retVal;
+}
+
+
+static int v320usc_pcibios_read_config_dword (
+						struct pci_dev *dev,
+						int where,
+						u32 *val)
+{
+	int retVal = PCIBIOS_SUCCESSFUL;
+	unsigned long flags;
+	int addr;
+
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	save_and_cli(flags);
+
+	/* Clear status bits */
+	v320usc_outw(v320usc_inw(PCI_STAT_W), PCI_STAT_W);
+
+	if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
+		retVal = -1;
+	else {
+		*val = readl(V320USC_CONF_SPACE + addr);
+
+		/* Check for master abort */
+		if (v320usc_inw(PCI_STAT_W) & PCI_STAT_W_M_ABORT) {
+			v320usc_outw(0xffff, PCI_STAT_W);
+			// printk("Master abort long\n");
+			*val = 0xffffffff;
+		}
+	}
+
+	set_io_cycles();
+
+	restore_flags(flags);
+
+	return retVal;
+}
+
+
+static int v320usc_pcibios_write_config_byte (
+						struct pci_dev *dev,
+						int where,
+						u8 val)
+{
+	int retVal = PCIBIOS_SUCCESSFUL;
+	unsigned long flags;
+	int addr;
+
+	save_and_cli(flags);
+
+	if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
+		retVal = -1;
+	else
+		writeb(val, V320USC_CONF_SPACE + addr);
+
+	/* wait for write FIFO to empty */
+	v320usc_inw(PCI_STAT_W);
+
+	set_io_cycles();
+
+	restore_flags(flags);
+
+	return retVal;
+}
+
+
+static int v320usc_pcibios_write_config_word (
+						struct pci_dev *dev,
+						int where,
+						u16 val)
+{
+	int retVal = PCIBIOS_SUCCESSFUL;
+	unsigned long flags;
+	int addr;
+
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	save_and_cli(flags);
+
+	if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
+		retVal = -1;
+	else
+		writew(val, V320USC_CONF_SPACE + addr);
+
+	/* wait for write FIFO to empty */
+	v320usc_inw(PCI_STAT_W);
+
+	set_io_cycles();
+
+	restore_flags(flags);
+
+	return retVal;
+}
+
+
+static int v320usc_pcibios_write_config_dword (
+						struct pci_dev *dev,
+						int where,
+						u32 val)
+{
+	int retVal = PCIBIOS_SUCCESSFUL;
+	unsigned long flags;
+	int addr;
+
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	save_and_cli(flags);
+
+	if ((addr = mkaddr(dev->bus->number, dev->devfn, where)) == -1)
+		retVal = -1;
+	else
+		writel(val, V320USC_CONF_SPACE + addr);
+
+	/* wait for write FIFO to empty */
+	v320usc_inw(PCI_STAT_W);
+
+	set_io_cycles();
+
+	restore_flags(flags);
+
+	return retVal;
+}
+
+
+struct pci_ops pci_config_ops = {
+	v320usc_pcibios_read_config_byte,
+	v320usc_pcibios_read_config_word,
+	v320usc_pcibios_read_config_dword,
+	v320usc_pcibios_write_config_byte,
+	v320usc_pcibios_write_config_word,
+	v320usc_pcibios_write_config_dword
+};
+
+/****************************************************************************/
+
+/* Everything hangs off this */
+static struct pci_bus *pci_root_bus;
+
+static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
+{
+	return PCI_SLOT(dev->devfn);
+}
+
+
+static int __init map_keywest_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (pin >= 1 && pin <= 4)
+		return(PINT_IRQ_BASE + 2 + pin - 1);
+	return(-1);
+}
+
+
+char *
+pcibios_setup(char *str)
+{
+	return(str);
+}
+
+
+void __init
+pcibios_fixup_pbus_ranges(struct pci_bus *bus,
+			  struct pbus_set_ranges_data *ranges)
+{
+	ranges->io_start -= bus->resource[0]->start;
+	ranges->io_end -= bus->resource[0]->start;
+	ranges->mem_start -= bus->resource[1]->start;
+	ranges->mem_end -= bus->resource[1]->start;
+}
+
+
+void __init pcibios_init(void)
+{
+	char *mode;
+
+	if (sh_mv.mv_init_pci != NULL)
+		sh_mv.mv_init_pci();
+
+	if (v320usc_inw(PCI_VENDOR) != V3USC_PCI_VENDOR) {
+		printk("V320USC: PCI bridge chip not found\n");
+		return;
+	}
+
+	switch (v320usc_inw(PCI_DEVICE)) {
+	case V3USC_PCI_DEVICE_MIPS_9: mode = "MIPS 9-bit"; break;
+	case V3USC_PCI_DEVICE_MIPS_5: mode = "MIPS 5-bit"; break;
+	case V3USC_PCI_DEVICE_SH3:    mode = "SH-3"; break;
+	case V3USC_PCI_DEVICE_SH4:    mode = "SH-4"; break;
+	default:                      mode = "unknown !"; break;
+	}
+	printk("V3 Semiconductor V320USC bridge in %s mode\n", mode);
+
+	/*
+	 * RST_OUT de asserted
+	 */
+	v320usc_outb(0x80, SYSTEM);
+
+	/*
+	 * 16x8 latency time, GRANT, Normal arbitration, RAM Disable,
+	 * CLK_OUT Disable, SYNC_RDY, BREQ_NEG
+	 */
+	v320usc_outl(0x10120001, LB_BUS_CFG);
+
+	/*
+	 * System error enable, PCI bus master, Memory & IO Access enable
+	 */
+	v320usc_outw(0x0047, PCI_CMD_W);
+	v320usc_outw(0xf100, PCI_STAT_W); /* clear any errors */
+
+	/*
+	 * 32x8 clocks as Latency Timer
+	 */
+	v320usc_outl(0x00008800, PCI_HDR_CFG);
+
+	v320usc_outl(0x00005761, DRAM_BLK0);
+	v320usc_outl(0x02005761, DRAM_BLK1);
+	v320usc_outl(0x00000000, DRAM_BLK2);
+	v320usc_outl(0x00000000, DRAM_BLK3);
+	v320usc_outl(0x00000942, DRAM_CFG);
+	v320usc_outl(0x80030066, PCI_BUS_CFG);
+
+	v320usc_outl(v320usc_inl(INT_STAT), INT_STAT); /* clear any ints */
+
+	v320usc_outl(0x00000000, INT_CFG0);
+	v320usc_outl(0x00000000, INT_CFG1);
+	v320usc_outl(0x00000000, INT_CFG2);
+	v320usc_outl(0x00000000, INT_CFG3);
+
+#if 0
+	v320usc_outl(0x0c000000, PCI_I2O_BASE);
+	v320usc_outl(0x0c010053, PCI_I2O_MAP);
+#endif
+	v320usc_outl(0x0c000001, PCI_MEM_BASE);
+	v320usc_outl(0x00010063, PCI_MEM_MAP);
+
+	v320usc_outl(0x00000000, LB_PCU_BASE); /* Disable PCU on SuperH */
+#if 0
+	v320usc_outl(0x00000081, PCI_PCU_BASE);
+#endif
+
+#ifndef CONFIG_PCMCIA
+	v320usc_outl(0xB4002030, LB_PCI_BASE0); /* 64Mb */
+	v320usc_outl(0xACB86030, LB_PCI_BASE1); /* 64Mb */
+#else
+	v320usc_outl(0x9e002010, LB_PCI_BASE0); /* 16Mb */
+	v320usc_outl(0x9fAb6010, LB_PCI_BASE1); /* 16Mb */
+#endif
+
+	/*
+	 * do the scan
+	 */
+	pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
+	pci_assign_unassigned_resources();
+	pci_fixup_irqs(no_swizzle, map_keywest_irq);
+
+#ifndef CONFIG_PCMCIA
+	v320usc_outl(0xB4002030, LB_PCI_BASE0); /* 64Mb */
+	v320usc_outl(0xACB86030, LB_PCI_BASE1); /* 64Mb */
+#else
+	v320usc_outl(0x9e002010, LB_PCI_BASE0); /* 16Mb */
+	v320usc_outl(0x9fAb6010, LB_PCI_BASE1); /* 16Mb */
+#endif
+
+	/*
+	 * Lock the system registers
+	 */
+	v320usc_outb(0x60, SYSTEM);
+
+	/*
+	 * Map all the PCI IO space
+	 */
+	mach_port_map(PCIBIOS_MIN_IO, (64*1024) - PCIBIOS_MIN_IO,
+			V320USC_IO_SPACE+PCIBIOS_MIN_IO, 0);
+}
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+	printk("%s,%d: %s()\n", __FILE__, __LINE__, __FUNCTION__);
+}
+
+static void __init pci_fixup_ide_bases(struct pci_dev *d)
+{
+	int i;
+
+	/*
+	 * PCI IDE controllers use non-standard I/O port decoding, respect it.
+	 */
+	if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
+		return;
+	printk("PCI: IDE base address fixup for %s\n", d->slot_name);
+	for(i=0; i<4; i++) {
+		struct resource *r = &d->resource[i];
+		if ((r->start & ~0x80) == 0x374) {
+			r->start |= 2;
+			r->end = r->start;
+		}
+	}
+}
+
+/* Add future fixups here... */
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,	PCI_ANY_ID,	pci_fixup_ide_bases },
+	{ 0 }
+};
+
+/****************************************************************************/
+#endif /* CONFIG_PCI */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/pci-v320usc.h linux-2.4.22-pre10/arch/sh/kernel/pci-v320usc.h
--- linux-2.4.21/arch/sh/kernel/pci-v320usc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/pci-v320usc.h	2003-08-01 13:34:29.000000000 +0000
@@ -0,0 +1,454 @@
+/*
+ * v320usc.h: Register defines for the V320USC family of devices.
+ *
+ * Copyright (C) 1999,2000 Dan Aizenstros (dan@vcubed.com)
+ *
+ * $Id: pci-v320usc.h,v 1.1 2003/02/20 04:26:36 gerg Exp $
+ */
+
+#ifndef _V320USC_H_
+#define _V320USC_H_
+
+#include <linux/pci.h>
+
+/*
+ * General parameters
+ */
+/* set debug level 4=verbose...1=terse */
+#define DEBUG_PCI 3
+// #undef DEBUG_PCI
+
+#ifdef DEBUG_PCI
+#define PCIDBG(n, x...) { if(DEBUG_PCI>=n) printk(x); }
+#else
+#define PCIDBG(n, x...)
+#endif
+
+#if 0
+/* startup values */
+#define PCI_PROBE_BIOS 1
+#define PCI_PROBE_CONF1 2
+#define PCI_PROBE_CONF2 4
+#define PCI_NO_SORT 0x100
+#define PCI_BIOS_SORT 0x200
+#define PCI_NO_CHECKS 0x400
+#define PCI_ASSIGN_ROMS 0x1000
+#define PCI_BIOS_IRQ_SCAN 0x2000
+#endif
+
+
+/*
+ *	platform specific parameters
+ */
+ 
+/*
+ * PCI Command Register
+ * - Offset 04h, Size 16 bits
+ */
+#define PCI_CMD_W_IO_EN			0x0001		/* I/O access */
+#define PCI_CMD_W_MEM_EN		0x0002		/* Memory access */
+#define PCI_CMD_W_MASTER_EN		0x0004		/* PCI Master */
+#define PCI_CMD_W_MWI_EN		0x0010		/* Memory Write and */
+							/* Invalidate enable            */
+#define PCI_CMD_W_PAR_EN		0x0040		/* Parity error */
+#define PCI_CMD_W_SERR_EN		0x0100		/* System error */
+							/* If PAR_EN is enabled then SERR is  */
+							/* driven in response to parity error */
+#define PCI_CMD_W_FBB_EN		0x0200		/* Fast back to back */
+							/* transfers when Bus Master     */
+
+/*
+ * PCI Status Register
+ * - Offset 06h, Size 16 bits
+ */
+#define PCI_STAT_W_NEW_CAP		0x0010		/* New Capabilites          */
+#define PCI_STAT_W_UDF			0x0040		/* User Defined Feature     */
+#define PCI_STAT_W_FAST_BACK		0x0008		/* Fast Back to Back Target */
+							/* - Used to indicate ability of this   */
+							/* device to other Bus Masters          */
+#define PCI_STAT_W_PAR_REP		0x0010		/* Data Parity Report when    */
+							/* USC is a Bus Master and PERR is driven */
+#define PCI_STAT_W_DEVSEL_MASK		0x0600		/* 10-9 Bits Device Select */
+							/* Timing                              */
+#define PCI_STAT_W_DEVSEL_SHIFT		9
+
+#define PCI_STAT_W_T_ABORT		0x1000		/* Target Abort - set in */
+							/* response to a target abort detected */
+							/* while USC was a Bus Master          */
+#define PCI_STAT_W_M_ABORT		0x2000		/* Master Abort - set in   */
+							/* response to a master abort detected */
+							/* while USC was a Bus Master          */
+#define PCI_STAT_W_SYS_ERR		0x4000		/* System Error - set in */
+							/* response to a system error on the */
+							/* SERR pin                          */
+#define PCI_STAT_W_PAR_ERR		0x8000		/* Parity Error - set in */
+							/* response to a parity error on the */
+							/* PCI bus                           */
+
+/*
+ * PCI Class and Revision Register
+ * - Offset 08h, Size 32 bits
+ */
+#define PCI_CC_REV_VREV_MASK		0x0000000f	/* 3-0 Bits Stepping ID  */
+							/* Rev A = 0,Rev B0 = 1, Rev B1 = 2, */
+							/* Rev B2 = 3 */
+#define PCI_CC_REV_VREV_SHIFT		0
+
+#define PCI_CC_REV_UREV_MASK		0x000000f0	/* 7-4 Bits User Revision ID */
+							/* user definable for system revisions   */
+#define PCI_CC_REV_UREV_SHIFT		4
+
+#define PCI_CC_REV_PROG_IF_MASK		0x0000ff00	/* 15-8 Bits PCI Programming */
+							/* Interface code                        */
+#define PCI_CC_REV_PROG_IF_SHIFT	8
+
+#define PCI_CC_REV_SUB_CLASS_MASK	0x00ff0000	/* 23-16 Bits PCI Sub Class */
+#define PCI_CC_REV_SUB_CLASS_SHIFT	16
+
+#define PCI_CC_REV_BASE_CLASS_MASK	0xff000000	/* 32-24 Bits PCI Base Class */
+#define PCI_CC_REV_BASE_CLASS_SHIFT 	24
+
+/*
+ * PCI Access to local memory map access
+ * - Offset 10h, Size 32 bits (I2O mode)
+ */
+#define PCI_I2O_BASE_IO			0x00000001	/* I/O 1 - I/O space */
+							/* 0 - Memory Space              */
+#define PCI_I2O_BASE_TYPE_MASK		0x00000006	/* 2-1 Bits Address range */
+							/* type                               */
+#define PCI_I2O_BASE_TYPE_SHIFT		1		/* 0 - device can be mapped */
+							/* any where in a 32 bit address space  */
+#define PCI_I2O_BASE_PREFETCH		0x00000008	/* Prefetchable - no effect */
+#define PCI_I2O_BASE_ADR_BASE_MASK	0xfff00000	/* 31-20 Bits Base address */
+							/* of ATU                              */
+#define PCI_I2O_BASE_ADR_BASE_SHIFT	20
+
+/*
+ * PCI Access to local memory map access
+ * - Offset 14h, Size 32 bits
+ */
+#define PCI_MEM_BASE_IO			0x00000001	/* I/O 1 - I/O space */
+							/* 0 - Memory Space              */
+#define PCI_MEM_BASE_TYPE_MASK		0x00000006	/* 2-1 Bits Address range */
+							/* type                               */
+#define PCI_MEM_BASE_TYPE_SHIFT		1		/* 0 - device can be mapped */
+							/* any where in a 32 bit address space  */
+#define PCI_MEM_BASE_PREFETCH		0x00000008	/* Prefetchable - no effect */
+#define PCI_MEM_BASE_ADR_BASE_MASK	0xfff00000	/* 31-20 Bits Base address */
+							/* of ATU                              */
+#define PCI_MEM_BASE_ADR_BASE_SHIFT	20
+
+/*
+ * PCI Bus Parameters Register
+ * - Offset 3ch, Size 32 bits
+ */
+#define PCI_BPARAM_INT_LINE_MASK	0x000000ff	/* 7-0 Bits Interrupt Line */
+#define PCI_BPARAM_INT_LINE_SHIFT	0
+#define PCI_BPARAM_INT_PIN_MASK		0x00000700	/* 10-8 Bits Interrupt Pin */
+							/* 0 - disable, 1 - INTA, 2 - INT B    */
+							/* 3 - INT C, 4 - INT C                */
+#define PCI_BPARAM_INT_PIN_SHIFT	8
+#define PCI_BPARAM_MIN_GRANT_MASK	0x00ff0000	/* 23-16 Bits Minimum Grant */
+#define PCI_BPARAM_MIN_GRANT_SHIFT	16
+#define PCI_BPARAM_MAX_LAT_MASK		0xff000000	/* 31-24 Bits Maximum Latency */
+#define PCI_BPARAM_MAX_LAT_SHIFT	24
+
+/*
+ * LB_PCI_BASEx Registers
+ * - Offset 60h, Size 32 bits
+ * - Offset 64h, Size 32 bits
+ */
+#define LB_PCI_BASEX_ALOW_MASK		0x00000003	/* select value AD1:0 */
+#define LB_PCI_BASEX_ALOW_SHIFT		0x00000000
+#define LB_PCI_BASEX_ERR_EN		0x00000004
+#define LB_PCI_BASEX_PREFETCH		0x00000008	/* prefetch */
+#define LB_PCI_BASEX_SIZE_DISABLE	0x00000000
+#define LB_PCI_BASEX_SIZE_16MB		0x00000010
+#define LB_PCI_BASEX_SIZE_32MB		0x00000020
+#define LB_PCI_BASEX_SIZE_64MB		0x00000030
+#define LB_PCI_BASEX_SIZE_128MB		0x00000040
+#define LB_PCI_BASEX_SIZE_256MB		0x00000050
+#define LB_PCI_BASEX_SIZE_512MB		0x00000060
+#define LB_PCI_BASEX_SIZE_1GB		0x00000070
+#define LB_PCI_BASEX_BYTE_SWAP_NO	0x00000000	/* No swap 32 bits */
+#define LB_PCI_BASEX_BYTE_SWAP_16	0x00000100	/* 16 bits */
+#define LB_PCI_BASEX_BYTE_SWAP_8	0x00000200	/* bits */
+#define LB_PCI_BASEX_BYTE_SWAP_AUTO	0x00000300	/* Auto swap use BE[3:0] */
+#define LB_PCI_BASEX_COMBINE		0x00000800	/* Burst Write Combine */
+
+#define LB_PCI_BASEX_PCI_CMD_MASK	0x0000e000
+#define LB_PCI_BASEX_PCI_CMD_SHIFT	13
+#define LB_PCI_BASEX_INT_ACK		0x00000000	/* Interrupt Ack */
+#define LB_PCI_BASEX_IO			0x00002000	/* I/O Read/Write */
+#define LB_PCI_BASEX_MEMORY		0x00006000	/* Memory Read/Write */
+#define LB_PCI_BASEX_CONFIG		0x0000a000	/* Configuration Read/Write */
+#define LB_PCI_BASEX_MULTI_MEMORY	0x0000c000	/* Multiple Memory Read/Write */
+#define LB_PCI_BASEX_MEMORY_INVALIDATE	0x0000e000	/* Multiple Memory Read/e */
+							/* Write Invalidate       */
+#define LB_PCI_BASEX_MAP_ADR_MASK	0x00ff0000	/* PCI Address map */
+#define LB_PCI_BASEX_MAP_ADR_SHIFT	16
+#define LB_PCI_BASEX_BASE		0xff000000	/* Local Address base */
+#define LB_PCI_BASEX_BASE_ADR_SHIFT	24
+
+
+/*
+ * SDRAM Local Base Address Register 
+ * - Offset 78h, Size 32 bits
+ */
+#define LB_SDRAM_BASE_ENABLE		0x01		/* must be enabled to access */
+#define LB_SDRAM_BASE_SIZE_64M		0x00
+#define LB_SDRAM_BASE_SIZE_128M		0x10
+#define LB_SDRAM_BASE_SIZE_256M		0x20
+#define LB_SDRAM_BASE_SIZE_512M		0x30
+#define LB_SDRAM_BASE_SIZE_1G		0x40
+
+#define LB_SDRAM_BASE_MASK		0xfc000000
+#define LB_SDRAM_BASE_SHIFT		26
+
+
+/*
+ * Interrupt Configuration Register
+ * - Offset e0h, Size 32 bits
+ * - Offset e4h, Size 32 bits
+ * - Offset e8h, Size 32 bits
+ * - Offset 158h, Size 32 bits
+ */
+#define INT_CFGX_LB_MBI			0x00000001
+#define INT_CFGX_PCI_MBI		0x00000002
+#define INT_CFGX_I2O_OP_NE		0x00000008
+#define INT_CFGX_I2O_IF_NF		0x00000010
+#define INT_CFGX_I2O_IP_NE		0x00000020
+#define INT_CFGX_I2O_OP_NF		0x00000040
+#define INT_CFGX_I2O_OF_NE		0x00000080
+#define INT_CFGX_INT0			0x00000100
+#define INT_CFGX_INT1			0x00000200
+#define INT_CFGX_INT2			0x00000400
+#define INT_CFGX_INT3			0x00000800
+#define INT_CFGX_TIMER0			0x00001000
+#define INT_CFGX_TIMER1			0x00002000
+#define INT_CFGX_ENUM			0x00004000
+#define INT_CFGX_DMA0			0x00010000
+#define INT_CFGX_DMA1			0x00020000
+#define INT_CFGX_PWR_STATE		0x00100000
+#define INT_CFGX_HBI			0x00200000
+#define INT_CFGX_WDI			0x00400000
+#define INT_CFGX_BWI			0x00800000
+#define INT_CFGX_PSLAVE_PI		0x01000000
+#define INT_CFGX_PMASTER_PI		0x02000000
+#define INT_CFGX_PCI_T_ABORT		0x04000000
+#define INT_CFGX_PCI_M_ABORT		0x08000000
+#define INT_CFGX_DRA_PI			0x10000000
+#define INT_CFGX_MODE			0x20000000
+#define INT_CFGX_DI0			0x40000000
+#define INT_CFGX_DI1			0x80000000
+
+
+/*
+ * Interrupt Status Register
+ * - Offset ECh, Size 32 bits
+ */
+#define INT_STAT_BWI			0x00800000
+#define INT_STAT_WDI			0x00400000
+#define INT_STAT_HBI			0x00200000
+#define INT_STAT_DMA1			0x00020000
+#define INT_STAT_DMA0			0x00010000
+#define INT_STAT_TIMER1			0x00002000
+#define INT_STAT_TIMER0			0x00001000
+#define INT_STAT_INT3			0x00000800
+#define INT_STAT_INT2			0x00000400
+#define INT_STAT_INT1			0x00000200
+#define INT_STAT_INT0			0x00000100
+
+
+/*
+ * General Purpose Timer Control Register
+ * - Offset 150h, Size 16 bits
+ * - Offset 152h, Size 16 bits
+ */
+#define TIMER_CTLX_W_TI_MODE_0		0x0000		/* Timer input event */
+#define TIMER_CTLX_W_TI_MODE_1		0x0001
+#define TIMER_CTLX_W_TI_MODE_2		0x0002
+#define TIMER_CTLX_W_TI_MODE_3		0x0003
+
+#define TIMER_CTLX_W_CNT_EN_0		0x0000		/* Count enable */
+#define TIMER_CTLX_W_CNT_EN_1		0x0004
+#define TIMER_CTLX_W_CNT_EN_2		0x0008
+#define TIMER_CTLX_W_CNT_EN_3		0x000C
+
+#define TIMER_CTLX_W_TRG_MODE_0		0x0000		/* Trigger mode */
+#define TIMER_CTLX_W_TRG_MODE_1		0x0010
+#define TIMER_CTLX_W_TRG_MODE_2		0x0020
+#define TIMER_CTLX_W_TRG_MODE_3		0x0030
+
+#define TIMER_CTLX_W_TO_MODE_0		0x0000		/* Timer output mode */
+#define TIMER_CTLX_W_TO_MODE_1		0x0100
+#define TIMER_CTLX_W_TO_MODE_2		0x0200
+#define TIMER_CTLX_W_TO_MODE_3		0x0300
+#define TIMER_CTLX_W_TO_MODE_4		0x0400
+#define TIMER_CTLX_W_TO_MODE_5		0x0500
+
+#define TIMER_CTLX_W_DLTCH_0		0x0000		/* Data latch mode */
+#define TIMER_CTLX_W_DLTCH_1		0x0800
+#define TIMER_CTLX_W_DLTCH_2		0x1000
+
+#define TIMER_CTLX_W_ENABLE		0x8000		/* Timer enable */
+
+
+/*
+ * DMA Delay Register
+ * - Offset 16Ch, Size 8 bits
+ */
+#define DMA_DELAY_MASK			0x000000ff
+#define DMA_DELAY_SHIFT			0
+
+/*
+ * DMA Command / Status Register
+ * - Offset 170h, Size 32 bits
+ * - Offset 174h, Size 32 bits
+ */
+#define DMA_CSR_IPR			0x00000001	/* initiate DMA transfer */
+#define DMA_CSR_HALT			0x00000002	/* pause DMA transfer */
+#define DMA_CSR_DONE			0x00000004	/* DMA transfer complete */
+#define DMA_CSR_DCI			0x00000008	/* DMA control interrupt status	*/
+#define DMA_CSR_DPE			0x00000010	/* DMA PCI BUS error status */
+#define DMA_CSR_DONE_EN			0x00000400	/* DONE interrupt enable */
+#define DMA_CSR_DCI_EN			0x00000800	/* DCI interrupt enable */
+#define DMA_CSR_DPE_EN			0x00001000	/* DPE interrupt enable */
+#define DMA_CSR_PRIORITY		0x00008000	/* DMA channel priority */
+#define DMA_CSR_PCI_CMD0_MASK		0x000E0000	/* PCI Command Type 0 */
+#define DMA_CSR_PCI_CMD0_SHIFT		17
+#define DMA_CSR_PCI_CMD1_MASK		0x00E00000	/* PCI Command Type 1 */
+#define DMA_CSR_PCI_CMD1_SHIFT		21
+ 
+/*
+ * DMA Transfer Control Register
+ * - Offset 180h, Size 32 bits
+ * - Offset 190h, Size 32 bits
+ */
+#define DMA_XFER_DMA_CNT_MASK		0x000FFFFF	/* DMA transfer count */
+#define DMA_XFER_DMA_CNT_SHIFT		0
+#define DMA_XFER_DTERM_EN		0x00400000	/* External terminate count enable */
+#define DMA_XFER_BLOCK_FILL		0x00800000	/* Block fill feature enable */
+#define DMA_XFER_DST_BUS		0x01000000	/* DMA destination BUS */
+#define DMA_XFER_SRC_BUS		0x02000000	/* DMA source BUS */
+#define DMA_XFER_PDST_TYPE		0x04000000	/* PCI destination command type */
+#define DMA_XFER_PSRC_TYPE		0x08000000	/* PCI source command type */
+#define DMA_XFER_SWAP_MASK		0x30000000	/* Byte swap control */
+#define DMA_XFER_SWAP_SHIFT		28
+#define DMA_XFER_UPDT_CNT		0x40000000	/* Update count */
+#define DMA_XFER_DREQ_EN		0x80000000	/* External DRQ enable */
+
+
+/*
+ * DMA Control Block Register
+ * - Offset 180h, Size 32 bits
+ * - Offset 190h, Size 32 bits
+ */
+#define DMA_CTLB_BUS			0x00000001	/* DMA Control block address space */
+#define DMA_CTLB_SA_INC_DIS		0x00000004	/* Source address increment disable */
+#define DMA_CTLB_DA_INC_DIS		0x00000008	/* Dest address increment disable */
+#define DMA_CTLB_ADDR_MASK		0xFFFFFFF0	/* DMA Control block address mask */
+#define DMA_CTLB_ADDR_SHIFT		4
+
+
+/*
+ * V320USC registers offsets
+ */
+#define	V320USC_PCI_VENDOR		0x00
+#define	V320USC_PCI_DEVICE		0x02
+#define	V320USC_PCI_CMD_W		0x04
+#define	V320USC_PCI_STAT_W		0x06
+#define	V320USC_PCI_CC_REV		0x08
+#define	V320USC_PCI_HDR_CFG		0x0c
+#define	V320USC_PCI_I2O_BASE	0x10
+#define	V320USC_PCI_MEM_BASE	0x14
+#define	V320USC_PCI_REG_BASE	0x18
+#define	V320USC_PCI_PCU_BASE	0x1c
+#define	V320USC_PCI_BPARM		0x3c
+#define	V320USC_PCI_I2O_MAP		0x50
+#define	V320USC_PCI_MEM_MAP		0x54
+#define	V320USC_PCI_BUS_CFG		0x5c
+#define	V320USC_LB_PCI_BASE0	0x60
+#define	V320USC_LB_PCI_BASE1	0x64
+#define	V320USC_LB_PCU_BASE		0x6c
+#define	V320USC_SYSTEM			0x73
+#define	V320USC_LB_SDRAM_BASE	0x78
+#define	V320USC_LB_BUS_CFG		0x7c
+#define	V320USC_LB_PCI_CTL_W	0x84
+#define	V320USC_DRAM_CFG	0x8C
+#define	V320USC_DRAM_BLK0	0x90
+#define	V320USC_DRAM_BLK1	0x94
+#define	V320USC_DRAM_BLK2	0x98
+#define	V320USC_DRAM_BLK3	0x9c
+#define	V320USC_INT_CFG0		0xe0
+#define	V320USC_INT_CFG1		0xe4
+#define	V320USC_INT_CFG2		0xe8
+#define	V320USC_INT_STAT		0xec
+#define	V320USC_WD_HBI_W		0xf4
+#define	V320USC_TIMER_DATA0		0x140
+#define	V320USC_TIMER_DATA1		0x144
+#define	V320USC_TIMER_CTL0_W		0x150
+#define	V320USC_TIMER_CTL1_W		0x152
+#define	V320USC_INT_CFG3		0x158
+#define	V320USC_DMA_DELAY		0x16C
+#define	V320USC_DMA_CSR0		0x170
+#define	V320USC_DMA_CSR1		0x174
+#define	V320USC_DMA_XFER_CTL0		0x180
+#define	V320USC_DMA_SRC_ADR0		0x184
+#define	V320USC_DMA_DST_ADR0		0x188
+#define	V320USC_DMA_CTLB_ADR0		0x18C
+#define	V320USC_DMA_XFER_CTL1		0x190
+#define	V320USC_DMA_SRC_ADR1		0x194
+#define	V320USC_DMA_DST_ADR1		0x198
+#define	V320USC_DMA_CTLB_ADR1		0x19C
+
+/*
+ * Vendor/Device ID settings
+ */
+
+#define	V3USC_PCI_VENDOR		0x11b0
+#define	V3USC_PCI_DEVICE_MIPS_9 0x0100
+#define	V3USC_PCI_DEVICE_MIPS_5 0x0101
+#define	V3USC_PCI_DEVICE_SH3	0x0102
+#define	V3USC_PCI_DEVICE_SH4	0x0103
+
+/*
+ * Stepping of V3USC320 as read back from V3USC_PCI_CC_REV register
+ */
+#define V3USC_REV_A0 0
+#define V3USC_REV_B0 1
+#define V3USC_REV_B1 2
+
+/*
+ * PCI Bus Parameters Register
+ * - Offset 3ch, Size 32 bits
+ */
+#define INTERRUPT_PIN_DISABLE		0x0		/* Disabled */
+#define INTERRUPT_PIN_INTA		0x1		/* Use INTA */
+#define INTERRUPT_PIN_INTB		0x2		/* Use INTB */
+#define INTERRUPT_PIN_INTC		0x3		/* Use INTC */
+#define INTERRUPT_PIN_INTD		0x4		/* Use INTD */
+
+/*
+ * PCI Base Address for Peripheral Access 
+ * - Offset 1ch, Size 32 bits
+ * PCI Intelligent I/O Address Translation Unit Local Bus Address Map Register
+ * - Offset ??h, Size 32 bits
+ */
+#define BYTE_SWAP_NO			0x0		/* No swap 32 bits */
+#define BYTE_SWAP_16			0x1		/* 16 bits */
+#define BYTE_SWAP_8			0x2		/* 8 bits */
+#define BYTE_SWAP_AUTO			0x3		/* Auto swap use BE[3:0]   */
+#define APERTURE_SIZE_1M		0x0		/* Aperture size of 1 MB   */
+#define APERTURE_SIZE_2M		0x1		/* Aperture size of 2 MB   */
+#define APERTURE_SIZE_4M		0x2		/* Aperture size of 4 MB   */
+#define APERTURE_SIZE_8M		0x3		/* Aperture size of 8 MB   */
+#define APERTURE_SIZE_16M		0x4		/* Aperture size of 16 MB  */
+#define APERTURE_SIZE_32M		0x5		/* Aperture size of 32 MB  */
+#define APERTURE_SIZE_64M		0x6		/* Aperture size of 64 MB  */
+#define APERTURE_SIZE_128M		0x7		/* Aperture size of 128 MB */
+#define APERTURE_SIZE_256M		0x8		/* Aperture size of 256 MB */
+#define APERTURE_SIZE_512M		0x9		/* Aperture size of 512 MB */
+#define APERTURE_SIZE_1G		0xa		/* Aperture size of 1 GB   */
+
+#endif /* _V320USC_H_ */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/pci_st40.c linux-2.4.22-pre10/arch/sh/kernel/pci_st40.c
--- linux-2.4.21/arch/sh/kernel/pci_st40.c	2001-09-08 19:29:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/pci_st40.c	2003-08-01 13:34:30.000000000 +0000
@@ -21,6 +21,8 @@
 
 #include "pci_st40.h"
 
+static struct resource pci_io_space, pci_mem_space;
+
 /* This is in P2 of course */
 #define ST40PCI_BASE_ADDRESS     (0xb0000000)
 #define ST40PCI_MEM_ADDRESS      (ST40PCI_BASE_ADDRESS+0x0)
@@ -28,97 +30,183 @@
 #define ST40PCI_REG_ADDRESS      (ST40PCI_BASE_ADDRESS+0x07000000)
 
 #define ST40PCI_REG(x) (ST40PCI_REG_ADDRESS+(ST40PCI_##x))
-
-#define ST40PCI_WRITE(reg,val) writel((val),ST40PCI_REG(reg))
-#define ST40PCI_WRITE_SHORT(reg,val) writew((val),ST40PCI_REG(reg))
-#define ST40PCI_WRITE_BYTE(reg,val) writeb((val),ST40PCI_REG(reg))
+#define ST40PCI_REG_INDEXED(reg, index) 				\
+	(ST40PCI_REG(reg##0) +					\
+	  ((ST40PCI_REG(reg##1) - ST40PCI_REG(reg##0))*index))
+
+#define ST40PCI_WRITE(reg,val) writel((val),ST40PCI_REG(reg));udelay(2);
+#define ST40PCI_WRITE_SHORT(reg,val) writew((val),ST40PCI_REG(reg));udelay(2);
+#define ST40PCI_WRITE_BYTE(reg,val) writeb((val),ST40PCI_REG(reg));udelay(2);
+#define ST40PCI_WRITE_INDEXED(reg, index, val)				\
+	 writel((val), ST40PCI_REG_INDEXED(reg, index)); udelay(2);
 
 #define ST40PCI_READ(reg) readl(ST40PCI_REG(reg))
 #define ST40PCI_READ_SHORT(reg) readw(ST40PCI_REG(reg))
 #define ST40PCI_READ_BYTE(reg) readb(ST40PCI_REG(reg))
+#define ST40PCI_READ_INDEXED(reg, index) readl(ST40PCI_REG_INDEXED(reg, index))
 
 #define ST40PCI_SERR_IRQ        64
-#define ST40PCI_SERR_INT_GROUP  0
-#define ST40PCI_SERR_INT_POS    0
-#define ST40PCI_SERR_INT_PRI    15
-
 #define ST40PCI_ERR_IRQ        65
-#define ST40PCI_ERR_INT_GROUP   1
-#define ST40PCI_ERR_INT_POS     1
-#define ST40PCI_ERR_INT_PRI     14
+#define ST40PCI_AD_INT			66
+#define ST40PCI_PWR_DWN_INT		67
 
+#define PLLPCICR (0xbb040000+0x10)	// CLKGENA.PLL2CR
 
+/* From ST's include/asm-sh/st40_clock.h */
 /* Macros to extract PLL params */
 #define PLL_MDIV(reg)  ( ((unsigned)reg) & 0xff )
 #define PLL_NDIV(reg) ( (((unsigned)reg)>>8) & 0xff )
-#define PLL_PDIV(reg) ( (((unsigned)reg)>>16) & 0x3 )
+#define PLL_PDIV(reg) ( (((unsigned)reg)>>16) & 0x7 )
 #define PLL_SETUP(reg) ( (((unsigned)reg)>>19) & 0x1ff )
 
-/* Build up the appropriate settings */
-#define PLL_SET(mdiv,ndiv,pdiv,setup) \
-( ((mdiv)&0xff) | (((ndiv)&0xff)<<8) | (((pdiv)&3)<<16)| (((setup)&0x1ff)<<19))
+/*
+ * The pcibios_map_platform_irq function is defined in the appropraite
+ * board specific code and referenced here
+ */
+extern int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin);
+
+static void __init pcibios_assign_resources(void);
+
+static __init void SetPCIPLL(void)
+{
+	{
+		/* Lets play with the PLL values */
+		unsigned long pll1cr1;
+		unsigned long mdiv, ndiv, pdiv;
+		unsigned long muxcr;
+		unsigned int muxcr_ratios[4] = { 8, 16, 21, 1 };
+		unsigned int freq;
+
+#define CLKGENA            0xbb040000
+#define CLKGENA_PLL2_MUXCR CLKGENA + 0x48
+		pll1cr1 = ctrl_inl(PLLPCICR);
+		printk("PLL1CR1 %08x\n", pll1cr1);
+		mdiv = PLL_MDIV(pll1cr1);
+		ndiv = PLL_NDIV(pll1cr1);
+		pdiv = PLL_PDIV(pll1cr1);
+		printk("mdiv %02x ndiv %02x pdiv %02x\n", mdiv, ndiv, pdiv);
+		freq = ((2*27*ndiv)/mdiv) / (1 << pdiv);
+		printk("PLL freq %dMHz\n", freq);
+		muxcr = ctrl_inl(CLKGENA_PLL2_MUXCR);
+		printk("PCI freq %dMhz\n", freq / muxcr_ratios[muxcr & 3]);
+	}
+}
+
+
+struct pci_err {
+  unsigned mask;
+  const char *error_string;
+};
 
-#define PLLPCICR (0xbb040000+0x10)
 
-#define PLLPCICR_POWERON (1<<28)
-#define PLLPCICR_OUT_EN (1<<29)
-#define PLLPCICR_LOCKSELECT (1<<30)
-#define PLLPCICR_LOCK (1<<31)
+static struct pci_err int_error[]={
+  { INT_MNLTDIM,"MNLTDIM: Master non-lock transfer"},
+  { INT_TTADI,  "TTADI: Illegal byte enable in I/O transfer"},  
+  { INT_TMTO,   "TMTO: Target memory read/write timeout"},  
+  { INT_MDEI,   "MDEI: Master function disable error"},
+  { INT_APEDI,  "APEDI: Address parity error"},
+  { INT_SDI,    "SDI: SERR detected"},
+  { INT_DPEITW, "DPEITW: Data parity error target write"},  
+  { INT_PEDITR, "PEDITR: PERR detected"},
+  { INT_TADIM,  "TADIM: Target abort detected"},
+  { INT_MADIM,  "MADIM: Master abort detected"},
+  { INT_MWPDI,  "MWPDI: PERR from target at data write"},
+  { INT_MRDPEI, "MRDPEI: Master read data parity error"}
+};
+#define NUM_PCI_INT_ERRS (sizeof(int_error)/sizeof(struct pci_err))
 
+static struct pci_err aint_error[]={
+  { AINT_MBI,   "MBI: Master broken"},
+  { AINT_TBTOI, "TBTOI: Target bus timeout"},
+  { AINT_MBTOI, "MBTOI: Master bus timeout"},
+  { AINT_TAI,   "TAI: Target abort"},
+  { AINT_MAI,   "MAI: Master abort"},
+  { AINT_RDPEI, "RDPEI: Read data parity"},
+  { AINT_WDPE,  "WDPE: Write data parity"}
+};
 
-#define PLL_25MHZ 0x793c8512
-#define PLL_33MHZ PLL_SET(18,88,3,295)
 
+#define NUM_PCI_AINT_ERRS (sizeof(aint_error)/sizeof(struct pci_err))
 
-static __init void SetPCIPLL(void)
+static void print_pci_errors(unsigned reg,struct pci_err *error,int num_errors)
 {
-	/* Stop the PLL */
-	writel(0, PLLPCICR);
+  int i;
 
-	/* Always run at 33Mhz. The PCI clock is totally async 
-	 * to the rest of the system
-	 */
-	writel(PLL_33MHZ | PLLPCICR_POWERON, PLLPCICR);
+  for(i=0;i<num_errors;i++) {
+    if(reg & error[i].mask) {
+      printk("%s\n",error[i].error_string);
+    }
+  }
 
-	printk("ST40PCI: Waiting for PCI PLL to lock\n");
-	while ((readl(PLLPCICR) & PLLPCICR_LOCK) == 0);
-	writel(readl(PLLPCICR) | PLLPCICR_OUT_EN, PLLPCICR);
 }
 
 
+static char * pci_commands[16]={
+	"Int Ack",
+	"Special Cycle",
+	"I/O Read",
+	"I/O Write",
+	"Reserved",
+	"Reserved",
+	"Memory Read",
+	"Memory Write",
+	"Reserved",
+	"Reserved",
+	"Configuration Read",
+	"Configuration Write",
+	"Memory Read Multiple",
+	"Dual Address Cycle",
+	"Memory Read Line",
+	"Memory Write-and-Invalidate"
+};
+
+
 static void st40_pci_irq(int irq, void *dev_instance, struct pt_regs *regs)
 {
 
 	unsigned pci_int, pci_air, pci_cir, pci_aint;
+	static int count=0;
+
+
+	pci_int = ST40PCI_READ(INT);pci_aint = ST40PCI_READ(AINT);
+	pci_cir = ST40PCI_READ(CIR);pci_air = ST40PCI_READ(AIR);
+
+	/* Reset state to stop multiple interrupts */
+        ST40PCI_WRITE(INT, ~0); ST40PCI_WRITE(AINT, ~0); 
+
 
-	pci_int = ST40PCI_READ(INT);
-	pci_cir = ST40PCI_READ(CIR);
-	pci_air = ST40PCI_READ(AIR);
-
-	if (pci_int) {
-		printk("PCI INTERRUPT!\n");
-		printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
-		printk("PCI AIR -> 0x%x\n", pci_air);
-		printk("PCI CIR -> 0x%x\n", pci_cir);
-		ST40PCI_WRITE(INT, ~0);
-	}
-
-	pci_aint = ST40PCI_READ(AINT);
-	if (pci_aint) {
-		printk("PCI ARB INTERRUPT!\n");
-		printk("PCI AINT -> 0x%x\n", pci_aint);
-		printk("PCI AIR -> 0x%x\n", pci_air);
-		printk("PCI CIR -> 0x%x\n", pci_cir);
-		ST40PCI_WRITE(AINT, ~0);
+	if(++count>1) return;
+
+	printk("** PCI ERROR **\n");
+
+        if(pci_int) {
+		printk("** INT register status\n");
+		print_pci_errors(pci_int,int_error,NUM_PCI_INT_ERRS);
 	}
 
+        if(pci_aint) {
+		printk("** AINT register status\n");
+		print_pci_errors(pci_aint,aint_error,NUM_PCI_AINT_ERRS);
+	}   
+	
+	printk("** Address and command info\n");
+
+	printk("** Command  %s : Address 0x%x\n",
+	       pci_commands[pci_cir&0xf],pci_air);
+
+	if(pci_cir&CIR_PIOTEM) {
+		printk("CIR_PIOTEM:PIO transfer error for master\n");
+	}
+        if(pci_cir&CIR_RWTET) {
+		printk("CIR_RWTET:Read/Write transfer error for target\n");
+	}
 }
 
 
 /* Rounds a number UP to the nearest power of two. Used for
  * sizing the PCI window.
  */
-static u32 __init r2p2(u32 num)
+static u32 r2p2(u32 num)
 {
 	int i = 31;
 	u32 tmp = num;
@@ -161,17 +249,49 @@
 }
 
 
+static void __init pci_fixup_cache_line(struct pci_dev *d)
+{
+	pci_write_config_byte(d,PCI_CACHE_LINE_SIZE,0);
+}
+
+
 /* Add future fixups here... */
 struct pci_fixup pcibios_fixups[] = {
 	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,	PCI_ANY_ID,	pci_fixup_ide_bases },
+	{ PCI_FIXUP_FINAL,	PCI_ANY_ID,	PCI_ANY_ID,	pci_fixup_cache_line },
 	{ 0 }
 };
 
+char * __init pcibios_setup(char *str)
+{
+	return str;
+}
+
+static void __init st40pci_init_resources(void)
+{
+	pci_io_space.start = PCIBIOS_MIN_IO;
+	pci_io_space.end   = 64*1024 - PCIBIOS_MIN_IO - 1;
+	pci_io_space.name = "ST40 PCI";
+	pci_io_space.flags = IORESOURCE_IO;
+
+	request_resource(&ioport_resource, &pci_io_space);
+
+	pci_mem_space.start = PCIBIOS_MIN_MEM;
+	pci_mem_space.end   = PCIBIOS_MIN_MEM + (96*1024*1024) -1;
+	pci_mem_space.name = "ST40 PCI";
+	pci_mem_space.flags = IORESOURCE_MEM;
+
+	request_resource(&iomem_resource, &pci_mem_space);
+}
+
 int __init st40pci_init(unsigned memStart, unsigned memSize)
 {
 	u32 lsr0;
 
+ 	printk("PCI version register reads 0x%x\n",ST40PCI_READ(VCR_VERSION));
+
 	SetPCIPLL();
+	st40pci_init_resources();
 
 	/* Initialises the ST40 pci subsystem, performing a reset, then programming
 	 * up the address space decoders appropriately
@@ -184,21 +304,22 @@
 	/* Loop while core resets */
 	while (ST40PCI_READ(CR) & CR_SOFT_RESET);
 
+	/* Switch off interrupts */
+	ST40PCI_WRITE(INTM, 0);
+	ST40PCI_WRITE(AINT, 0);
+
 	/* Now, lets reset all the cards on the bus with extreme prejudice */
 	ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_RSTCTL);
 	udelay(250);
 
 	/* Set bus active, take it out of reset */
-	ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_CFINT | CR_PFCS | CR_PFE);
+	ST40PCI_WRITE(CR, CR_LOCK_MASK | CR_BMAM | CR_CFINT | CR_PFCS | CR_PFE);
 
 	/* The PCI spec says that no access must be made to the bus until 1 second
 	 * after reset. This seem ludicrously long, but some delay is needed here
 	 */
 	mdelay(1000);
 
-	/* Switch off interrupts */
-	ST40PCI_WRITE(INTM, 0);
-	ST40PCI_WRITE(AINT, 0);
 
 	/* Allow it to be a master */
 
@@ -224,47 +345,24 @@
 	/* Set up the 64K window */
 	ST40PCI_WRITE(IOBMR, 0x0);
 
-	/* Now we set up the mbars so the PCI bus can see the memory of the machine */
+	/* Now we set up the mbars so the PCI bus can see the local memory */
+	/* Expose a 256M window starting at PCI address 0... */
+	ST40PCI_WRITE(CSR_MBAR0, 0);
+	ST40PCI_WRITE(LSR0, 0x0fff0001);
 
-	if (memSize < (64 * 1024)) {
-		printk("Ridiculous memory size of 0x%x?\n",memSize);
-		return 0;
-	}
-
-	lsr0 =
-	    (memSize >
-	     (512 * 1024 * 1024)) ? 0x1fff0001 : ((r2p2(memSize) -
-						   0x10000) | 0x1);
-
-	ST40PCI_WRITE(LSR0, lsr0);
-
-	ST40PCI_WRITE(CSR_MBAR0, memStart);
-	ST40PCI_WRITE(LAR0, memStart);
+	/* ... and set up the initial incomming window to expose all of RAM */
+	pci_set_rbar_region(7, memStart, memStart, memSize);
 
 	/* Maximise timeout values */
 	ST40PCI_WRITE_BYTE(CSR_TRDY, 0xff);
 	ST40PCI_WRITE_BYTE(CSR_RETRY, 0xff);
 	ST40PCI_WRITE_BYTE(CSR_MIT, 0xff);
 
-
-	/* Install the pci interrupt handlers */
-	make_intc2_irq(ST40PCI_SERR_IRQ, INTC2_BASE0,
-		       ST40PCI_SERR_INT_GROUP, ST40PCI_SERR_INT_POS,
-		       ST40PCI_SERR_INT_PRI);
-
-	make_intc2_irq(ST40PCI_ERR_IRQ, INTC2_BASE0, ST40PCI_ERR_INT_GROUP,
-		       ST40PCI_ERR_INT_POS, ST40PCI_ERR_INT_PRI);
-
+	ST40PCI_WRITE_BYTE(PERF,PERF_MASTER_WRITE_POSTING);
 
 	return 1;
 }
 
-char * __init pcibios_setup(char *str)
-{
-	return str;
-}
-
-
 #define SET_CONFIG_BITS(bus,devfn,where)\
   (((bus) << 16) | ((devfn) << 8) | ((where) & ~3) | (bus!=0))
 
@@ -276,7 +374,7 @@
 	if (ST40PCI_READ(INT) & INT_MADIM) {
 		/* Should we clear config space version as well ??? */
 		ST40PCI_WRITE(INT, INT_MADIM);
-		ST40PCI_WRITE_SHORT(CSR_STATUS, 0);
+		ST40PCI_WRITE_SHORT(CSR_STATUS, PCI_RMA);
 		return 1;
 	}
 
@@ -287,6 +385,8 @@
 static int st40pci_read_config_byte(struct pci_dev *dev, int where,
 				    u8 * val)
 {
+	CheckForMasterAbort();
+
 	ST40PCI_WRITE(PAR, CONFIG_CMD(dev, where));
 
 	*val = ST40PCI_READ_BYTE(PDR + (where & 3));
@@ -301,6 +401,8 @@
 static int st40pci_read_config_word(struct pci_dev *dev, int where,
 				    u16 * val)
 {
+	CheckForMasterAbort();
+
 	ST40PCI_WRITE(PAR, CONFIG_CMD(dev, where));
 
 	*val = ST40PCI_READ_SHORT(PDR + (where & 2));
@@ -315,13 +417,15 @@
 static int st40pci_read_config_dword(struct pci_dev *dev, int where,
 				     u32 * val)
 {
+	CheckForMasterAbort();
 
 	ST40PCI_WRITE(PAR, CONFIG_CMD(dev, where));
 
 	*val = ST40PCI_READ(PDR);
 
-	if (CheckForMasterAbort())
+	if (CheckForMasterAbort()) {
 		*val = 0xffffffff;
+	}
 
 	return PCIBIOS_SUCCESSFUL;
 }
@@ -379,45 +483,37 @@
 
 static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
 {
+	printk("swizzle for dev %d on bus %d slot %d pin is %d\n",
+	       dev->devfn,dev->bus->number, PCI_SLOT(dev->devfn),*pin);
 	return PCI_SLOT(dev->devfn);
 }
 
+static inline u8 bridge_swizzle(u8 pin, u8 slot) 
+{
+	return (((pin-1) + slot) % 4) + 1;
+}
 
-/* This needs to be shunted out of here into the board specific bit */
-#define HARP_PCI_IRQ    1
-#define HARP_BRIDGE_IRQ 2
-#define OVERDRIVE_SLOT0_IRQ 0
-
-static int __init map_harp_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-	switch (slot) {
-#ifdef CONFIG_SH_STB1_HARP
-	case 2:		/*This is the PCI slot on the */
-		return HARP_PCI_IRQ;
-	case 1:		/* this is the bridge */
-		return HARP_BRIDGE_IRQ;
-#elif defined(CONFIG_SH_STB1_OVERDRIVE)
-	case 1:
-	case 2:
-	case 3:
-		return slot - 1;
-#else
-#error Unknown board
-#endif
-	default:
-		return -1;
+u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	if (dev->bus->number != 0) {
+		u8 pin = *pinp;
+		do {
+			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+			/* Move up the chain of bridges. */
+			dev = dev->bus->self;
+		} while (dev->bus->self);
+		*pinp = pin;
+
+		/* The slot is the slot of the last bridge. */
 	}
-}
 
+	return PCI_SLOT(dev->devfn);
+}
 
 void __init
 pcibios_fixup_pbus_ranges(struct pci_bus *bus,
 			  struct pbus_set_ranges_data *ranges)
 {
-	ranges->io_start -= bus->resource[0]->start;
-	ranges->io_end -= bus->resource[0]->start;
-	ranges->mem_start -= bus->resource[1]->start;
-	ranges->mem_end -= bus->resource[1]->start;
 }
 
 void __init pcibios_init(void)
@@ -435,12 +531,20 @@
 	st40pci_init(PHYSADDR(memory_start),
 		     PHYSADDR(memory_end) - PHYSADDR(memory_start));
 
+	if (request_irq(ST40PCI_SERR_IRQ, st40_pci_irq, 
+                        SA_INTERRUPT, "st40pci", NULL)) {
+		printk(KERN_ERR "st40pci: Cannot hook interrupt\n");
+		return;
+	}
+
 	if (request_irq(ST40PCI_ERR_IRQ, st40_pci_irq, 
                         SA_INTERRUPT, "st40pci", NULL)) {
 		printk(KERN_ERR "st40pci: Cannot hook interrupt\n");
 		return;
 	}
 
+	/* Reset state just in case any outstanding (usually SERR) */
+        ST40PCI_WRITE(INT, ~0); ST40PCI_WRITE(AINT, ~0); 
 	/* Enable the PCI interrupts on the device */
 	ST40PCI_WRITE(INTM, ~0);
 	ST40PCI_WRITE(AINT, ~0);
@@ -454,10 +558,137 @@
 	/* ok, do the scan man */
 	pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
 	pci_assign_unassigned_resources();
-	pci_fixup_irqs(no_swizzle, map_harp_irq);
+	pci_fixup_irqs(no_swizzle, pcibios_map_platform_irq);
 
 }
 
+void __init
+pcibios_fixup_resource(struct resource *res, struct resource *root)
+{
+        res->start += root->start;
+        res->end += root->start;
+}
+
+void __init
+pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
+{
+        /* Update device resources.  */
+        int i;
+
+        for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+                if (!dev->resource[i].start)
+                        continue;
+                if (dev->resource[i].flags & IORESOURCE_IO)
+                        pcibios_fixup_resource(&dev->resource[i],
+                                               &pci_io_space);
+                else if (dev->resource[i].flags & IORESOURCE_MEM)
+                        pcibios_fixup_resource(&dev->resource[i],
+                                               &pci_mem_space);
+        }
+}
+
 void __init pcibios_fixup_bus(struct pci_bus *bus)
 {
+	/* Propogate hose info into the subordinate devices.  */
+	struct list_head *ln;
+	struct pci_dev *dev = bus->self;
+
+	if (!dev) {
+		bus->resource[0] = &pci_io_space;
+		bus->resource[1] = &pci_mem_space;
+	}
+
+	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
+		struct pci_dev *dev = pci_dev_b(ln);
+		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+			pcibios_fixup_device_resources(dev, bus);
+	}
+}
+
+static void __init pcibios_assign_resources(void)
+{
+	struct pci_dev *dev;
+	int idx;
+	struct resource *r;
+	pci_for_each_dev(dev) {
+		int class = dev->class >> 8;
+
+		/* Don't touch classless devices and host bridges */
+		if (!class || class == PCI_CLASS_BRIDGE_HOST)
+			continue;
+
+		for(idx=0; idx<6; idx++) {
+			r = &dev->resource[idx];
+
+			/*
+			 *  Don't touch IDE controllers and I/O ports of video cards!
+			 */
+			if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) ||
+			    (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
+				continue;
+
+			/*
+			 *  We shall assign a new address to this resource, either because
+			 *  the BIOS forgot to do so or because we have decided the old
+			 *  address was unusable for some reason.
+			 */
+			if (!r->start && r->end)
+                        {
+                          	pci_assign_resource(dev, idx);
+                         }
+		}
+#if 0 /* don't assign ROMs */
+		if (pci_probe & PCI_ASSIGN_ROMS) {
+			r = &dev->resource[PCI_ROM_RESOURCE];
+			r->end -= r->start;
+			r->start = 0;
+			if (r->end)
+				pci_assign_resource(dev, PCI_ROM_RESOURCE);
+		}
+#endif
+        }
+}
+
+/*
+ * Publish a region of local address space over the PCI bus
+ * to other devices.
+ */
+void pci_set_rbar_region(unsigned int region,     unsigned long localAddr,
+			 unsigned long pciOffset, unsigned long regionSize)
+{
+	unsigned long mask;
+
+	if (region > 7)
+		return;
+
+	if (regionSize > (512 * 1024 * 1024))
+		return;
+
+	mask = r2p2(regionSize) - 0x10000;
+
+	/* Diable the region (in case currently in use, should never happen) */
+	ST40PCI_WRITE_INDEXED(RSR, region, 0);
+
+	/* Start of local address space to publish */
+	ST40PCI_WRITE_INDEXED(RLAR, region, PHYSADDR(localAddr) );
+
+	/* Start of region in PCI address space as an offset from MBAR0 */
+	ST40PCI_WRITE_INDEXED(RBAR, region, pciOffset);
+
+	/* Size of region */
+	ST40PCI_WRITE_INDEXED(RSR, region, mask | 1);
+} 
+
+/*
+ * Make a previously published region of local address space
+ * inaccessible to other PCI devices.
+ */ 
+void pci_clear_rbar_region(unsigned int region)
+{
+	if (region > 7)
+		return;
+
+	ST40PCI_WRITE_INDEXED(RSR, region, 0);
+	ST40PCI_WRITE_INDEXED(RBAR, region, 0);
+	ST40PCI_WRITE_INDEXED(RLAR, region, 0);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/pci_st40.h linux-2.4.22-pre10/arch/sh/kernel/pci_st40.h
--- linux-2.4.21/arch/sh/kernel/pci_st40.h	2001-04-12 04:24:52.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/pci_st40.h	2003-08-01 13:34:21.000000000 +0000
@@ -33,13 +33,37 @@
 #define ST40PCI_LAR0          0x1c
 
 #define ST40PCI_INT           0x24
+#define INT_MNLTDIM           (1<<15)
+#define INT_TTADI             (1<<14)
+#define INT_TMTO              (1<<9)
+#define INT_MDEI              (1<<8)
+#define INT_APEDI             (1<<7)
+#define INT_SDI               (1<<6)
+#define INT_DPEITW            (1<<5)
+#define INT_PEDITR            (1<<4)
+#define INT_TADIM             (1<<3)
 #define INT_MADIM             (1<<2)
+#define INT_MWPDI             (1<<1)
+#define INT_MRDPEI            (1<<0)
 
 
 #define ST40PCI_INTM          0x28
 #define ST40PCI_AIR           0x2c
+
 #define ST40PCI_CIR           0x30
+#define CIR_PIOTEM            (1<<31)
+#define CIR_RWTET             (1<<26)
+
+
 #define ST40PCI_AINT          0x40
+#define AINT_MBI              (1<<13)
+#define AINT_TBTOI            (1<<12)
+#define AINT_MBTOI            (1<<11)
+#define AINT_TAI              (1<<3)
+#define AINT_MAI              (1<<2)
+#define AINT_RDPEI            (1<<1)
+#define AINT_WDPE             (1<<0)
+
 #define ST40PCI_AINTM         0x44
 #define ST40PCI_BMIR          0x48
 #define ST40PCI_PAR           0x4c
@@ -51,11 +75,58 @@
 #define ST40PCI_IOBMR         0x74
 #define ST40PCI_PDR           0x78
 
+/* H8 specific registers start here */
+#define ST40PCI_WCBAR         0x7c
+#define ST40PCI_LOCCFG_UNLOCK 0x34
+
+#define ST40PCI_RBAR0         0x100
+#define ST40PCI_RSR0          0x104
+#define ST40PCI_RLAR0         0x108
+
+#define ST40PCI_RBAR1         0x110
+#define ST40PCI_RSR1          0x114
+#define ST40PCI_RLAR1         0x118
+
+
+#define ST40PCI_RBAR2         0x120
+#define ST40PCI_RSR2          0x124
+#define ST40PCI_RLAR2         0x128
+
+#define ST40PCI_RBAR3         0x130
+#define ST40PCI_RSR3          0x134
+#define ST40PCI_RLAR3         0x138
+
+#define ST40PCI_RBAR4         0x140
+#define ST40PCI_RSR4          0x144
+#define ST40PCI_RLAR4         0x148
+
+#define ST40PCI_RBAR5         0x150
+#define ST40PCI_RSR5          0x154
+#define ST40PCI_RLAR5         0x158
+
+#define ST40PCI_RBAR6         0x160
+#define ST40PCI_RSR6          0x164
+#define ST40PCI_RLAR6         0x168
+
+#define ST40PCI_RBAR7         0x170
+#define ST40PCI_RSR7          0x174
+#define ST40PCI_RLAR7         0x178
+
+
+#define ST40PCI_RBAR(n)      (0x100+(0x10*(n)))
+#define ST40PCI_RSR(n)       (0x104+(0x10*(n)))
+#define ST40PCI_RLAR(n)      (0x108+(0x10*(n)))
+
+#define ST40PCI_PERF               0x80
+#define PERF_MASTER_WRITE_POSTING  (1<<4)
+/* H8 specific registers end here */
+
 /* These are configs space registers */
 #define ST40PCI_CSR_VID               0x10000
 #define ST40PCI_CSR_DID               0x10002
 #define ST40PCI_CSR_CMD               0x10004
 #define ST40PCI_CSR_STATUS            0x10006
+#define   PCI_RMA			(1<<13)
 #define ST40PCI_CSR_MBAR0             0x10010
 #define ST40PCI_CSR_TRDY              0x10040
 #define ST40PCI_CSR_RETRY             0x10041
@@ -63,4 +134,10 @@
 
 #define ST40_IO_ADDR 0xb6000000       
 
+#define ST40PCI_INTPIN			0x1003d
+
+void pci_set_rbar_region(unsigned int region,     unsigned long localAddr,
+			 unsigned long pciOffset, unsigned long regionSize);
+void pci_clear_rbar_region(unsigned int region);
+
 #endif /* __PCI_ST40_H__ */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/process.c linux-2.4.22-pre10/arch/sh/kernel/process.c
--- linux-2.4.21/arch/sh/kernel/process.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/process.c	2003-08-01 13:34:03.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.35 2001/10/11 09:18:17 gniibe Exp $
+/* $Id: process.c,v 1.1.1.1.2.4 2003/05/29 04:21:33 lethal Exp $
  *
  *  linux/arch/sh/kernel/process.c
  *
@@ -21,6 +21,8 @@
 
 static int hlt_counter=0;
 
+int ubc_usercnt = 0;
+
 #define HARD_IDLE_TIMEOUT (HZ / 3)
 
 void disable_hlt(void)
@@ -45,8 +47,9 @@
 
 	while (1) {
 		if (hlt_counter) {
-			if (current->need_resched)
-				break;
+			while (1)
+				if (current->need_resched)
+					break;
 		} else {
 			__cli();
 			while (!current->need_resched) {
@@ -148,7 +151,10 @@
  */
 void exit_thread(void)
 {
-	/* Nothing to do. */
+	if (current->thread.ubc_pc1) {
+		current->thread.ubc_pc1 = 0;
+		ubc_usercnt -= 1;
+	}
 }
 
 void flush_thread(void)
@@ -179,11 +185,7 @@
 
 	fpvalid = tsk->used_math;
 	if (fpvalid) {
-		unsigned long flags;
-
-		save_and_cli(flags);
 		unlazy_fpu(tsk);
-		restore_flags(flags);
 		memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
 	}
 
@@ -203,15 +205,9 @@
 #if defined(__SH4__)
 	struct task_struct *tsk = current;
 
-	if (tsk != &init_task) {
-		unsigned long flags;
-
-		save_and_cli(flags);
-		unlazy_fpu(tsk);
-		restore_flags(flags);
-		p->thread.fpu = current->thread.fpu;
-		p->used_math = tsk->used_math;
-	}
+	unlazy_fpu(tsk);
+	p->thread.fpu = current->thread.fpu;
+	p->used_math = tsk->used_math;
 #endif
 	childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long) p)) - 1;
 	*childregs = *regs;
@@ -227,6 +223,9 @@
 	p->thread.sp = (unsigned long) childregs;
 	p->thread.pc = (unsigned long) ret_from_fork;
 
+	p->thread.ubc_pc1 = 0;
+	p->thread.ubc_pc2 = 0;
+
 	return 0;
 }
 
@@ -250,6 +249,37 @@
 	dump->u_fpvalid = dump_fpu(regs, &dump->fpu);
 }
 
+/* Tracing by user break controller.  */
+static inline void
+ubc_set_tracing(int asid, unsigned long nextpc1, unsigned nextpc2)
+{
+	ctrl_outl(nextpc1, UBC_BARA);
+	ctrl_outb(asid, UBC_BASRA);
+	if(UBC_TYPE_SH7729){
+		ctrl_outl(0, UBC_BAMRA);
+		ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
+	}else{
+		ctrl_outb(0, UBC_BAMRA);
+		ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
+	}
+
+	if (nextpc2 != (unsigned long) -1) {
+		ctrl_outl(nextpc2, UBC_BARB);
+		ctrl_outb(asid, UBC_BASRB);
+		if(UBC_TYPE_SH7729){
+			ctrl_outl(0, UBC_BAMRB);
+			ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRB);
+		}else{
+			ctrl_outb(0, UBC_BAMRB);
+			ctrl_outw(BBR_INST | BBR_READ, UBC_BBRB);
+		}
+	}
+	if(UBC_TYPE_SH7729)
+		ctrl_outl(BRCR_PCTE, UBC_BRCR);
+	else
+		ctrl_outw(0, UBC_BRCR);
+}
+
 /*
  *	switch_to(x,y) should switch tasks from x to y.
  *
@@ -257,14 +287,9 @@
 void __switch_to(struct task_struct *prev, struct task_struct *next)
 {
 #if defined(__SH4__)
-	if (prev != &init_task) {
-		unsigned long flags;
-
-		save_and_cli(flags);
-		unlazy_fpu(prev);
-		restore_flags(flags);
-	}
+	unlazy_fpu(prev);
 #endif
+
 	/*
 	 * Restore the kernel mode register
 	 *   	k7 (r7_bank1)
@@ -272,6 +297,19 @@
 	asm volatile("ldc	%0, r7_bank"
 		     : /* no output */
 		     :"r" (next));
+
+	/* If no tasks are using the UBC, we're done */
+	if (ubc_usercnt == 0)
+		return;
+
+	/* Otherwise, set or clear UBC as appropriate */
+	if (next->thread.ubc_pc1) {
+		ubc_set_tracing(next->mm->context & MMU_CONTEXT_ASID_MASK,
+				next->thread.ubc_pc1, next->thread.ubc_pc2);
+	} else {
+		ctrl_outw(0, UBC_BBRA);
+		ctrl_outw(0, UBC_BBRB);
+	}
 }
 
 asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
@@ -375,6 +413,9 @@
 	/* Clear tracing.  */
 	ctrl_outw(0, UBC_BBRA);
 	ctrl_outw(0, UBC_BBRB);
+	current->thread.ubc_pc1 = 0;
+	current->thread.ubc_pc2 = (unsigned long) -1;
+	ubc_usercnt -= 1;
 
 	force_sig(SIGTRAP, current);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/ptrace.c linux-2.4.22-pre10/arch/sh/kernel/ptrace.c
--- linux-2.4.21/arch/sh/kernel/ptrace.c	2001-10-15 20:36:48.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/ptrace.c	2003-08-01 13:31:10.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: ptrace.c,v 1.13 2001/10/01 02:21:50 gniibe Exp $
+/* $Id: ptrace.c,v 1.1.1.1.2.1 2002/11/12 02:24:19 jzs Exp $
  *
  * linux/arch/sh/kernel/ptrace.c
  *
@@ -116,37 +116,6 @@
 	return;
 }
 
-/* Tracing by user break controller.  */
-static void
-ubc_set_tracing(int asid, unsigned long nextpc1, unsigned nextpc2)
-{
-	ctrl_outl(nextpc1, UBC_BARA);
-	ctrl_outb(asid, UBC_BASRA);
-	if(UBC_TYPE_SH7729){
-		ctrl_outl(0x0fff, UBC_BAMRA);
-		ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
-	}else{
-		ctrl_outb(BAMR_12, UBC_BAMRA);
-		ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
-	}
-
-	if (nextpc2 != (unsigned long) -1) {
-		ctrl_outl(nextpc2, UBC_BARB);
-		ctrl_outb(asid, UBC_BASRB);
-		if(UBC_TYPE_SH7729){
-			ctrl_outl(0x0fff, UBC_BAMRB);
-			ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRB);
-		}else{
-			ctrl_outb(BAMR_12, UBC_BAMRB);
-			ctrl_outw(BBR_INST | BBR_READ, UBC_BBRB);
-		}
-	}
-	if(UBC_TYPE_SH7729)
-		ctrl_outl(BRCR_PCBA | BRCR_PCBB | BRCR_PCTE, UBC_BRCR);
-	else
-		ctrl_outw(BRCR_PCBA | BRCR_PCBB, UBC_BRCR);
-}
-
 /*
  * Called by kernel/ptrace.c when detaching..
  *
@@ -342,8 +311,11 @@
 		if (nextpc2 != (unsigned long) -1 && (nextpc2 & 0x80000000))
 			break;
 
-		ubc_set_tracing(child->mm->context & MMU_CONTEXT_ASID_MASK,
-				nextpc1, nextpc2);
+		/* Next scheduling will set up UBC */
+		if (child->thread.ubc_pc1 == 0)
+			ubc_usercnt += 1;
+		child->thread.ubc_pc1 = nextpc1;
+		child->thread.ubc_pc2 = nextpc2;
 
 		child->exit_code = data;
 		/* give it a chance to run. */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/rtc-snapgear.c linux-2.4.22-pre10/arch/sh/kernel/rtc-snapgear.c
--- linux-2.4.21/arch/sh/kernel/rtc-snapgear.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/rtc-snapgear.c	2003-08-01 13:31:13.000000000 +0000
@@ -0,0 +1,323 @@
+/****************************************************************************/
+/*
+ * linux/arch/sh/kernel/rtc-snapgear.c -- Secureedge5410 RTC code
+ *
+ *  Copyright (C) 2002  David McCullough <davidm@snapgear.com>
+ *
+ * The SecureEdge5410 can have one of 2 real time clocks, the SH
+ * built in version or the preferred external DS1302.  Here we work out
+ * each to see what we have and then run with it.
+ */
+/****************************************************************************/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/rtc.h>
+#include <linux/mc146818rtc.h>
+
+#include <asm/io.h>
+#include <asm/rtc.h>
+#include <asm/mc146818rtc.h>
+
+/****************************************************************************/
+
+static int use_ds1302 = 0;
+
+/****************************************************************************/
+/*
+ *	we need to implement a DS1302 driver here that can operate in
+ *	conjunction with the builtin rtc driver which is already quite friendly
+ */
+/*****************************************************************************/
+
+#define	RTC_CMD_READ	0x81		/* Read command */
+#define	RTC_CMD_WRITE	0x80		/* Write command */
+
+#define	RTC_ADDR_YEAR	0x06		/* Address of year register */
+#define	RTC_ADDR_DAY	0x05		/* Address of day of week register */
+#define	RTC_ADDR_MON	0x04		/* Address of month register */
+#define	RTC_ADDR_DATE	0x03		/* Address of day of month register */
+#define	RTC_ADDR_HOUR	0x02		/* Address of hour register */
+#define	RTC_ADDR_MIN	0x01		/* Address of minute register */
+#define	RTC_ADDR_SEC	0x00		/* Address of second register */
+
+#define	RTC_RESET	0x1000
+#define	RTC_IODATA	0x0800
+#define	RTC_SCLK	0x0400
+
+#define set_dirp(x)
+#define get_dirp(x) 0
+#define set_dp(x)	SECUREEDGE_WRITE_IOPORT(x, 0x1c00)
+#define get_dp(x)	SECUREEDGE_READ_IOPORT()
+
+static void ds1302_sendbits(unsigned int val)
+{
+	int	i;
+
+	for (i = 8; (i); i--, val >>= 1) {
+		set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ? RTC_IODATA : 0));
+		set_dp(get_dp() | RTC_SCLK);	// clock high
+		set_dp(get_dp() & ~RTC_SCLK);	// clock low
+	}
+}
+
+static unsigned int ds1302_recvbits(void)
+{
+	unsigned int	val;
+	int		i;
+
+	for (i = 0, val = 0; (i < 8); i++) {
+		val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i);
+		set_dp(get_dp() | RTC_SCLK);	// clock high
+		set_dp(get_dp() & ~RTC_SCLK);	// clock low
+	}
+	return(val);
+}
+
+static unsigned int ds1302_readbyte(unsigned int addr)
+{
+	unsigned int	val;
+	unsigned long	flags;
+
+#if 0
+	printk("SnapGear RTC: ds1302_readbyte(addr=%x)\n", addr);
+#endif
+
+	save_flags(flags); cli();
+	set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
+	set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
+
+	set_dp(get_dp() | RTC_RESET);
+	ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ);
+	set_dirp(get_dirp() & ~RTC_IODATA);
+	val = ds1302_recvbits();
+	set_dp(get_dp() & ~RTC_RESET);
+	restore_flags(flags);
+
+	return(val);
+}
+
+static void ds1302_writebyte(unsigned int addr, unsigned int val)
+{
+	unsigned long	flags;
+
+#if 0
+	printk("SnapGear RTC: ds1302_writebyte(addr=%x)\n", addr);
+#endif
+
+	save_flags(flags); cli();
+	set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
+	set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
+	set_dp(get_dp() | RTC_RESET);
+	ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE);
+	ds1302_sendbits(val);
+	set_dp(get_dp() & ~RTC_RESET);
+	restore_flags(flags);
+}
+
+static void ds1302_reset(void)
+{
+	unsigned long	flags;
+	/* Hardware dependant reset/init */
+	save_flags(flags); cli();
+	set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
+	set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
+	restore_flags(flags);
+}
+
+/*****************************************************************************/
+
+static inline int bcd2int(int val)
+{
+	return((((val & 0xf0) >> 4) * 10) + (val & 0xf));
+}
+
+static inline int int2bcd(int val)
+{
+	return(((val / 10) << 4) + (val % 10));
+}
+
+/*****************************************************************************/
+/*
+ *	Write and Read some RAM in the DS1302,  if it works assume it's there
+ *	Otherwise use the SH4 internal RTC
+ */
+
+void __init secureedge5410_rtc_init(void)
+{
+	unsigned char *test = "snapgear";
+	int i;
+
+	ds1302_reset();
+
+	use_ds1302 = 1;
+
+	for (i = 0; test[i]; i++)
+		ds1302_writebyte(32 + i, test[i]);
+
+	for (i = 0; test[i]; i++)
+		if (ds1302_readbyte(32 + i) != test[i]) {
+			use_ds1302 = 0;
+			break;
+		}
+
+	printk("SnapGear RTC: using %s rtc.\n", use_ds1302 ? "ds1302" : "internal");
+}
+
+/****************************************************************************/
+/*
+ *	our generic interface that chooses the correct code to use
+ */
+
+void snapgear_rtc_gettimeofday(struct timeval *tv)
+{
+	unsigned int sec, min, hr, day, mon, yr;
+
+	if (!use_ds1302) {
+		sh_rtc_gettimeofday(tv);
+		return;
+	}
+
+ 	sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC));
+ 	min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));
+ 	hr  = bcd2int(ds1302_readbyte(RTC_ADDR_HOUR));
+ 	day = bcd2int(ds1302_readbyte(RTC_ADDR_DATE));
+ 	mon = bcd2int(ds1302_readbyte(RTC_ADDR_MON));
+ 	yr  = bcd2int(ds1302_readbyte(RTC_ADDR_YEAR));
+
+bad_time:
+	if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
+	    hr > 23 || min > 59 || sec > 59) {
+		printk(KERN_ERR
+		       "SnapGear RTC: invalid value, resetting to 1 Jan 2000\n");
+		ds1302_writebyte(RTC_ADDR_MIN,  min = 0);
+		ds1302_writebyte(RTC_ADDR_HOUR, hr  = 0);
+		ds1302_writebyte(RTC_ADDR_DAY,        7);
+		ds1302_writebyte(RTC_ADDR_DATE, day = 1);
+		ds1302_writebyte(RTC_ADDR_MON,  mon = 1);
+		ds1302_writebyte(RTC_ADDR_YEAR, yr  = 0);
+		ds1302_writebyte(RTC_ADDR_SEC,  sec = 0);
+	}
+
+	tv->tv_sec = mktime(2000 + yr, mon, day, hr, min, sec);
+	if (tv->tv_sec < 0) {
+#if 0
+		printk("BAD TIME %d %d %d %d %d %d\n", yr, mon, day, hr, min, sec);
+#endif
+		yr = 100;
+		goto bad_time;
+	}
+	tv->tv_usec = 0;
+}
+
+int snapgear_rtc_settimeofday(const struct timeval *tv)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+	unsigned long nowtime;
+
+	if (!use_ds1302) {
+		sh_rtc_settimeofday(tv);
+		return(0);
+	}
+
+/*
+ *	This is called direct from the kernel timer handling code.
+ *	It is supposed to synchronize the kernel clock to the RTC.
+ */
+
+	nowtime = tv->tv_sec;
+
+#if 1
+	printk("SnapGear RTC: snapgear_rtc_settimeofday(nowtime=%ld)\n", nowtime);
+#endif
+
+	/* STOP RTC */
+	ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
+
+	cmos_minutes = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));
+
+	/*
+	 * since we're only adjusting minutes and seconds,
+	 * don't interfere with hour overflow. This avoids
+	 * messing with unknown time zones but requires your
+	 * RTC not to be off by more than 15 minutes
+	 */
+	real_seconds = nowtime % 60;
+	real_minutes = nowtime / 60;
+	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+		real_minutes += 30;	/* correct for half hour time zone */
+	real_minutes %= 60;
+
+	if (abs(real_minutes - cmos_minutes) < 30) {
+		ds1302_writebyte(RTC_ADDR_MIN, int2bcd(real_minutes));
+		ds1302_writebyte(RTC_ADDR_SEC, int2bcd(real_seconds));
+	} else {
+		printk(KERN_WARNING
+		       "SnapGear RTC: can't update from %d to %d\n",
+		       cmos_minutes, real_minutes);
+		retval = -1;
+	}
+
+	/* START RTC */
+	ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
+	return(0);
+}
+
+unsigned char secureedge5410_cmos_read(int addr)
+{
+	unsigned char val = 0;
+
+	if (!use_ds1302)
+		return(__CMOS_READ(addr, w));
+
+	switch(addr) {
+	case RTC_SECONDS:       val = ds1302_readbyte(RTC_ADDR_SEC);  break;
+	case RTC_SECONDS_ALARM:                                       break;
+	case RTC_MINUTES:       val = ds1302_readbyte(RTC_ADDR_MIN);  break;
+	case RTC_MINUTES_ALARM:                                       break;
+	case RTC_HOURS:         val = ds1302_readbyte(RTC_ADDR_HOUR); break;
+	case RTC_HOURS_ALARM:                                         break;
+	case RTC_DAY_OF_WEEK:   val = ds1302_readbyte(RTC_ADDR_DAY);  break;
+	case RTC_DAY_OF_MONTH:  val = ds1302_readbyte(RTC_ADDR_DATE); break;
+	case RTC_MONTH:         val = ds1302_readbyte(RTC_ADDR_MON);  break;
+	case RTC_YEAR:          val = ds1302_readbyte(RTC_ADDR_YEAR); break;
+	case RTC_REG_A:         /* RTC_FREQ_SELECT */                 break;
+	case RTC_REG_B:	        /* RTC_CONTROL */                     break;
+	case RTC_REG_C:	        /* RTC_INTR_FLAGS */                  break;
+	case RTC_REG_D:         val = RTC_VRT /* RTC_VALID */;        break;
+	default:                                                      break;
+	}
+
+	return(val);
+}
+
+void secureedge5410_cmos_write(unsigned char val, int addr)
+{
+	if (!use_ds1302) {
+		__CMOS_WRITE(val, addr, w);
+		return;
+	}
+
+	switch(addr) {
+	case RTC_SECONDS:       ds1302_writebyte(RTC_ADDR_SEC, val);  break;
+	case RTC_SECONDS_ALARM:                                       break;
+	case RTC_MINUTES:       ds1302_writebyte(RTC_ADDR_MIN, val);  break;
+	case RTC_MINUTES_ALARM:                                       break;
+	case RTC_HOURS:         ds1302_writebyte(RTC_ADDR_HOUR, val); break;
+	case RTC_HOURS_ALARM:                                         break;
+	case RTC_DAY_OF_WEEK:   ds1302_writebyte(RTC_ADDR_DAY, val);  break;
+	case RTC_DAY_OF_MONTH:  ds1302_writebyte(RTC_ADDR_DATE, val); break;
+	case RTC_MONTH:         ds1302_writebyte(RTC_ADDR_MON, val);  break;
+	case RTC_YEAR:          ds1302_writebyte(RTC_ADDR_YEAR, val); break;
+	case RTC_REG_A:         /* RTC_FREQ_SELECT */                 break;
+	case RTC_REG_B:        	/* RTC_CONTROL */                     break;
+	case RTC_REG_C:	        /* RTC_INTR_FLAGS */                  break;
+	case RTC_REG_D:	        /* RTC_VALID */                       break;
+	default:                                                      break;
+	}
+}
+
+/****************************************************************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/rtc.c linux-2.4.22-pre10/arch/sh/kernel/rtc.c
--- linux-2.4.21/arch/sh/kernel/rtc.c	2002-02-25 19:37:56.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/rtc.c	2003-08-01 13:34:28.000000000 +0000
@@ -23,7 +23,7 @@
 
 void sh_rtc_gettimeofday(struct timeval *tv)
 {
-	unsigned int sec128, sec, min, hr, wk, day, mon, yr, yr100;
+	unsigned int sec128, sec, min, hr, wk, day, mon, yr, yr100, badval;
 
  again:
 	do {
@@ -53,16 +53,21 @@
 	}
 #endif
 
-	BCD_TO_BIN(yr100);
-	BCD_TO_BIN(yr);
-	BCD_TO_BIN(mon);
-	BCD_TO_BIN(day);
-	BCD_TO_BIN(hr);
-	BCD_TO_BIN(min);
-	BCD_TO_BIN(sec);
+	badval = ((yr & 15) > 9 || (mon & 15) > 9 || (day & 15) > 9 ||
+		 (hr & 15) > 9 || (min & 15) > 9 || (sec & 15) > 9);
 
-	if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
-	    hr > 23 || min > 59 || sec > 59) {
+	if (!badval) {
+		BCD_TO_BIN(yr100);
+		BCD_TO_BIN(yr);
+		BCD_TO_BIN(mon);
+		BCD_TO_BIN(day);
+		BCD_TO_BIN(hr);
+		BCD_TO_BIN(min);
+		BCD_TO_BIN(sec);
+	}
+
+	if (badval || yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
+	    hr > 23 || min > 59 || sec > 59 || (yr100 != 19 && yr100 != 20)) {
 		printk(KERN_ERR
 		       "SH RTC: invalid value, resetting to 1 Jan 2000\n");
 		ctrl_outb(RCR2_RESET, RCR2);  /* Reset & Stop */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/setup.c linux-2.4.22-pre10/arch/sh/kernel/setup.c
--- linux-2.4.21/arch/sh/kernel/setup.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/setup.c	2003-08-01 13:33:51.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.31 2001/08/23 16:36:40 dwmw2 Exp $
+/* $Id: setup.c,v 1.1.1.1.2.7 2003/06/20 13:13:25 trent Exp $
  *
  *  linux/arch/sh/kernel/setup.c
  *
@@ -44,6 +44,11 @@
 #include <asm/sh_bios.h>
 #endif
 
+#ifdef CONFIG_SH_KGDB
+#include <asm/kgdb.h>
+static int kgdb_parse_options(char *options);
+#endif
+
 /*
  * Machine setup..
  */
@@ -298,6 +303,10 @@
 
 	parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable);
 
+#ifdef CONFIG_CMDLINE_BOOL
+	sprintf(*cmdline_p, CONFIG_CMDLINE);
+#endif
+
 #ifdef CONFIG_SH_GENERIC
 	if (mv == NULL) {
 		mv = &mv_unknown;
@@ -475,10 +484,20 @@
 	}
 
 #if defined(__SH4__)
-	/* We already grab/initialized FPU in head.S.  Make it consisitent. */
-	init_task.used_math = 1;
-	init_task.flags |= PF_USEDFPU;
+	init_task.used_math = 0;
+	init_task.flags &= ~PF_USEDFPU;
+#endif
+
+#ifdef CONFIG_UBC_WAKEUP
+	/*
+	 * Some brain-damaged loaders decided it would be a good idea to put
+	 * the UBC to sleep. This causes some issues when it comes to things
+	 * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB.  So ..
+	 * we wake it up and hope that all is well.
+	 */
+	ubc_wakeup();
 #endif
+
 	paging_init();
 }
 
@@ -528,7 +547,7 @@
 	
 	PRINT_CLOCK("CPU", boot_cpu_data.cpu_clock);
 	PRINT_CLOCK("Bus", boot_cpu_data.bus_clock);
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+#ifdef CONFIG_CPU_SUBTYPE_ST40
 	PRINT_CLOCK("Memory", boot_cpu_data.memory_clock);
 #endif
 	PRINT_CLOCK("Peripheral module", boot_cpu_data.module_clock);
@@ -553,4 +572,94 @@
 	stop:	c_stop,
 	show:	show_cpuinfo,
 };
-#endif
+#endif /* CONFIG_PROC_FS */
+
+#ifdef CONFIG_SH_KGDB
+/*
+ * Parse command-line kgdb options.  By default KGDB is enabled,
+ * entered on error (or other action) using default serial info.
+ * The command-line option can include a serial port specification
+ * and an action to override default or configured behavior.
+ */
+struct kgdb_sermap kgdb_sci_sermap =
+{ "ttySC", 5, kgdb_sci_setup, NULL };
+
+struct kgdb_sermap *kgdb_serlist = &kgdb_sci_sermap;
+struct kgdb_sermap *kgdb_porttype = &kgdb_sci_sermap;
+
+void kgdb_register_sermap(struct kgdb_sermap *map)
+{
+	struct kgdb_sermap *last;
+
+	for (last = kgdb_serlist; last->next; last = last->next)
+		;
+	last->next = map;
+	if (!map->namelen) {
+		map->namelen = strlen(map->name);
+	}
+}
+
+static int __init kgdb_parse_options(char *options)
+{
+	char c;
+	int baud;
+
+	/* Check for port spec (or use default) */
+
+	/* Determine port type and instance */
+	if (!memcmp(options, "tty", 3)) {
+		struct kgdb_sermap *map = kgdb_serlist;
+
+		while (map && memcmp(options, map->name, map->namelen))
+			map = map->next;
+
+		if (!map) {
+			KGDB_PRINTK("unknown port spec in %s\n", options);
+			return -1;
+		}
+
+		kgdb_porttype = map;
+		kgdb_serial_setup = map->setup_fn;
+		kgdb_portnum = options[map->namelen] - '0';
+		options += map->namelen + 1;
+
+		options = (*options == ',') ? options+1 : options;
+		
+		/* Read optional parameters (baud/parity/bits) */
+		baud = simple_strtoul(options, &options, 10);
+		if (baud != 0) {
+			kgdb_baud = baud;
+
+			c = toupper(*options);
+			if (c == 'E' || c == 'O' || c == 'N') {
+				kgdb_parity = c;
+				options++;
+			}
+
+			c = *options;
+			if (c == '7' || c == '8') {
+				kgdb_bits = c;
+				options++;
+			}
+			options = (*options == ',') ? options+1 : options;
+		}
+	}
+
+	/* Check for action specification */
+	if (!memcmp(options, "halt", 4)) {
+		kgdb_halt = 1;
+		options += 4;
+	} else if (!memcmp(options, "disabled", 8)) {
+		kgdb_enabled = 0;
+		options += 8;
+	}
+
+	if (*options) {
+                KGDB_PRINTK("ignored unknown options: %s\n", options);
+		return 0;
+	}
+	return 1;
+}
+__setup("kgdb=", kgdb_parse_options);
+#endif /* CONFIG_SH_KGDB */
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/setup_hs7729pci.c linux-2.4.22-pre10/arch/sh/kernel/setup_hs7729pci.c
--- linux-2.4.21/arch/sh/kernel/setup_hs7729pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/setup_hs7729pci.c	2003-08-01 13:34:08.000000000 +0000
@@ -0,0 +1,212 @@
+/* $Id: setup_hs7729pci.c,v 1.1.2.1 2003/06/24 08:45:47 dwmw2 Exp $
+ *
+ * linux/arch/sh/kernel/setup_hs7729pci.c
+ *
+ * Copyright (C) 2000  Kazumoto Kojima
+ *
+ * Hitachi Semiconductor and Devices HS7729PCI Support.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <asm/io.h>
+#include <asm/hitachi_hs7729pci.h>
+#include <asm/smc37c93x.h>
+
+static int interrupt_count;
+static int sevenseg_count;
+
+extern unsigned char aux_device_present;
+
+/*
+ * Configure the Super I/O chip
+ */
+static void __init smsc_config(int index, int data)
+{
+	outb_p(index, INDEX_PORT);
+	outb_p(data, DATA_PORT);
+}
+
+static void __init init_smsc(void)
+{
+	outb_p(CONFIG_ENTER, CONFIG_PORT);
+	outb_p(CONFIG_ENTER, CONFIG_PORT);
+
+#if defined(CONFIG_BLK_DEV_FD)
+	/* FDC */
+	smsc_config(CURRENT_LDN_INDEX, LDN_FDC);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */
+#endif
+
+#if defined(CONFIG_BLK_DEV_IDE)
+	/* IDE1 */
+	smsc_config(CURRENT_LDN_INDEX, LDN_IDE1);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */
+	smsc_config(IO_BASE_HI_INDEX, 0x01);
+        smsc_config(IO_BASE_LO_INDEX, 0x70);
+	smsc_config(0x62, 0x03);
+        smsc_config(0x63, 0x76);
+
+#if 0
+#define SMSC_RD(adr) ({ outb(adr, 0x3f0), inb(0x3f1); })
+
+	printk("IDE1 addrs 0x%02x%02x, 0x%02x%02x\n", SMSC_RD(0x60), SMSC_RD(0x61), SMSC_RD(0x62), SMSC_RD(0x63));
+	printk("IDE1 Reg 0xF0: %02x. IDE1 Reg 0xF1: %02x\n", SMSC_RD(0xf0), SMSC_RD(0xf1));
+	printk("Power reg: %02x\n", SMSC_RD(0x22));
+	smsc_config(0x22, 0x3f);
+	printk("Power reg changed to: %02x\n", SMSC_RD(0x22));
+#endif	       
+#endif
+
+	/* AUXIO (GPIO): to use IDE1 */
+	smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO);
+	smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */
+	smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */
+
+#if defined(CONFIG_SERIAL)
+	/* COM1 */
+	smsc_config(CURRENT_LDN_INDEX, LDN_COM1);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IO_BASE_HI_INDEX, 0x03);
+	smsc_config(IO_BASE_LO_INDEX, 0xf8);
+	smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */
+
+	/* COM2 */
+	smsc_config(CURRENT_LDN_INDEX, LDN_COM2);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IO_BASE_HI_INDEX, 0x02);
+	smsc_config(IO_BASE_LO_INDEX, 0xf8);
+	smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */
+#endif
+
+	/* RTC */
+	smsc_config(CURRENT_LDN_INDEX, LDN_RTC);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */
+
+#if defined(CONFIG_VT)
+	disable_irq(1);
+
+	/* KBD */
+	smsc_config(CURRENT_LDN_INDEX, LDN_KBC);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IRQ_SELECT_INDEX, 1); /* IRQ1 */
+	smsc_config(IRQ_SELECT_INDEX+2, 12); /* IRQ12 */
+
+	/* Let it probe for PS/2 port. It should find one. */
+	aux_device_present = 0;
+#endif
+
+#if defined(CONFIG_PARPORT)
+	/* PARALLEL */
+	smsc_config(CURRENT_LDN_INDEX, LDN_PARPORT);
+	smsc_config(ACTIVATE_INDEX, 0x01);
+	smsc_config(IO_BASE_HI_INDEX, 0x03);
+	smsc_config(IO_BASE_LO_INDEX, 0x78);
+	smsc_config(IRQ_SELECT_INDEX, 5); /* IRQ5 */
+#endif
+
+	outb_p(CONFIG_EXIT, CONFIG_PORT);
+}
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_hs7729pci_IRQ(void)
+{
+	/*
+	 * Super I/O (Just mimic PC):
+	 *  0: SD0001
+	 *  1: keyboard
+	 *  3: serial 0
+	 *  4: serial 1
+	 *  5: printer
+	 *  6: floppy
+	 *  8: rtc
+	 * 12: mouse
+	 * 14: ide0
+	 */
+	ctrl_outw(0x0130, BCR_ILCRA);
+	ctrl_outw(0x0070, BCR_ILCRB);
+	ctrl_outw(0x9abc, BCR_ILCRC);
+	ctrl_outw(0xef84, BCR_ILCRD);
+	ctrl_outw(0x0506, BCR_ILCRE);
+	ctrl_outw(0x0002, BCR_ILCRF);
+	ctrl_outw(0x000d, BCR_ILCRG);
+
+	make_ipr_irq(15, BCR_ILCRA, 3, 0x00); /* IRQ15 */
+	make_ipr_irq(14, BCR_ILCRA, 2, 0x01); /* IRQ14 */
+	make_ipr_irq(12, BCR_ILCRA, 1, 0x03); /* IRQ12 */
+
+	make_ipr_irq( 8, BCR_ILCRB, 1, 0x07); /* IRQ8 */
+
+	make_ipr_irq( 6, BCR_ILCRC, 3, 0x09); /* IRQ6 */
+	make_ipr_irq( 5, BCR_ILCRC, 2, 0x0a); /* IRQ5 */
+	make_ipr_irq( 4, BCR_ILCRC, 1, 0x0b); /* IRQ4 */
+	make_ipr_irq( 3, BCR_ILCRC, 0, 0x0c); /* IRQ3 */
+
+	make_ipr_irq( 1, BCR_ILCRD, 3, 0x0e); /* IRQ1 */
+	make_ipr_irq( 0, BCR_ILCRD, 2, 0x0f); /* PCI_IRQ0 */
+	make_ipr_irq( 7, BCR_ILCRD, 1, 0x08); /* USB1_IRQ */
+	make_ipr_irq(11, BCR_ILCRD, 0, 0x04); /* USB2_IRQ */
+
+	make_ipr_irq(10, BCR_ILCRE, 2, 0x05); /* PC_IRQ2 */
+	make_ipr_irq( 9, BCR_ILCRE, 0, 0x06); /* PC_IRQ1 */
+
+	make_ipr_irq(13, BCR_ILCRF, 0, 0x02); /* SLOT_IRQ5 */
+
+	make_ipr_irq( 2, BCR_ILCRG, 0, 0x0d); /* SLOT_IRQ1 */
+}
+
+/*
+ * Initialize the board
+ */
+
+void __init setup_hs7729pci(void)
+{
+	init_smsc();
+	/* XXX: RTC setting comes here */
+	interrupt_count = 0;
+	sevenseg_count = 0;
+	ctrl_outw(0xffff, PA_LED);
+	ctrl_outw(0x3f3f, PA_7SEG);
+}
+
+void debug_interrupt(void)
+{
+	ctrl_outw(interrupt_count, PA_LED);
+	if (interrupt_count == 0xffff)
+		interrupt_count = 0;
+	else
+		interrupt_count++;
+}
+
+static int sevenseg_data[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
+			  0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};
+
+void set_sevenseg(unsigned char val)
+{
+	unsigned short data;
+
+	data = sevenseg_data[(val & 0xf0) >> 4] << 8;
+	data |= sevenseg_data[val & 0x0f];
+
+	ctrl_outw(data, PA_7SEG);
+}
+
+void debug_sevenseg(void)
+{
+	set_sevenseg(sevenseg_count);
+
+	if (sevenseg_count == 0xff)
+		sevenseg_count = 0;
+	else
+		sevenseg_count++;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/setup_keywest.c linux-2.4.22-pre10/arch/sh/kernel/setup_keywest.c
--- linux-2.4.21/arch/sh/kernel/setup_keywest.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/setup_keywest.c	2003-08-01 13:34:22.000000000 +0000
@@ -0,0 +1,215 @@
+/*
+ *
+ * By Dustin McIntire (dustin@sensoria.com) (c)2001
+ * 
+ * Setup and IRQ handling code for the HD64465 companion chip.
+ * by Greg Banks <gbanks@pocketpenguins.com>
+ * Copyright (c) 2000 PocketPenguins Inc
+ *
+ * Derived from setup_hd64465.c which bore the message:
+ * Greg Banks <gbanks@pocketpenguins.com>
+ * Copyright (c) 2000 PocketPenguins Inc and
+ * Copyright (C) 2000 YAEGASHI Takeshi
+ * and setup_cqreek.c which bore message:
+ * Copyright (C) 2000  Niibe Yutaka
+ * 
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Setup and IRQ functions for a Hitachi Big Sur Evaluation Board.
+ * 
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+
+#include <asm/io_keywest.h>
+#include <asm/hd64465.h>
+#include <asm/keywest.h>
+
+//#define KEYWEST_DEBUG 3
+#undef KEYWEST_DEBUG
+
+//LED
+#define ALPHA_LED       0xb1ffe038
+
+#ifdef KEYWEST_DEBUG
+#define DPRINTK(args...)	printk(args)
+#define DIPRINTK(n, args...)	if (KEYWEST_DEBUG>(n)) printk(args)
+#else
+#define DPRINTK(args...)
+#define DIPRINTK(n, args...)
+#endif /* KEYWEST_DEBUG */
+
+#ifdef CONFIG_HD64465
+extern int hd64465_irq_demux(int irq);
+#endif /* CONFIG_HD64465 */
+
+extern void keywest_alpha(int i, char ch);
+
+int keywest_irq_demux(int irq)
+{
+	int demux_irq = irq;
+
+#ifdef CONFIG_HD64465
+	demux_irq = hd64465_irq_demux(demux_irq);
+#endif /* CONFIG_HD64465 */
+
+#ifndef CONFIG_SH_GENERIC
+	demux_irq = ipr_irq_demux(demux_irq);
+#endif
+
+	return demux_irq;
+}
+
+
+void __init init_keywest_IRQ(void)
+{
+	if (!MACH_KEYWEST) return;
+
+}
+
+void keywest_puts(const char* s)
+{
+	int n = 0;
+
+	while (*s)    { keywest_alpha(n++, *s++); }
+	while (n < 8) { keywest_alpha(n++, ' ');  }
+}
+EXPORT_SYMBOL(keywest_puts);
+
+void keywest_printf(const char* fmt, ...)
+{
+	char buffer[32];
+	va_list ap;
+
+	va_start(ap, fmt);
+        vsprintf(buffer, fmt, ap);
+	va_end(ap);
+	keywest_puts(buffer);
+}
+EXPORT_SYMBOL(keywest_printf);
+
+static void tahoe_init(void)
+{
+#ifdef CONFIG_HD64465
+	if (inw(HD64465_REG_SDID) != HD64465_SDID) {
+		printk("Tahoe board is not present.\n");
+
+		return;
+	 }
+
+	printk("Hitachi HD64465 chip support (%d.%d)\n",
+		inw(HD64465_REG_SRR) >> 8, inw(HD64465_REG_SRR) & 0xFF);
+
+	outw(~0, HD64465_REG_NIMR);
+	//outw(0x03, HD64465_REG_SPLLCR);
+#ifdef CONFIG_VT
+	outw(inw(HD64465_REG_SMSCR) & (~HD64465_SMSCR_PS2ST), HD64465_REG_SMSCR); /* PS2   */ 
+	//outw(inw(HD64465_REG_SMSCR) & (~HD64465_SMSCR_KBCST), HD64465_REG_SMSCR); /* keyboard  */ 
+#endif
+#ifdef CONFIG_SERIAL
+	outw(inw(HD64465_REG_SMSCR) & (~HD64465_SMSCR_UARTST), HD64465_REG_SMSCR); /* UART */
+#endif
+#ifdef CONFIG_PARPORT
+	outw(inw(HD64465_REG_SMSCR) & (~HD64465_SMSCR_PPST), HD64465_REG_SMSCR); /* PARPORT */
+#endif
+
+#ifdef CONFIG_PCMCIA
+	outw(inw(HD64465_REG_SMSCR) & (~HD64465_SMSCR_PC0ST), HD64465_REG_SMSCR); /* PC0    */
+	outw(inw(HD64465_REG_SMSCR) & (~HD64465_SMSCR_PC1ST), HD64465_REG_SMSCR); /* PC1    */
+
+	/* turn on PCMCIA area 5 and 6 in BCR1 */
+	* (unsigned short *) 0xffffff60 |= 0x3;
+
+	/* must put both area 5 and 6 into 8 or 16 bit mode in BCR2 */
+	* (unsigned short *) 0xffffff62 &= ~0x3c00;
+	* (unsigned short *) 0xffffff62 |= 0x2800;		/* 16 bit mode */
+
+	/* setup all the PCMCIA dual purpose pins to be PCMCIA pins */
+	* (unsigned short *) 0xa4000108 = 0x0000;   /* port E, all pins */
+	* (unsigned short *) 0xa400010a = 0x0000;   /* port F, all pins */
+	* (unsigned short *) 0xa400010c = 0x0000;   /* port G, all pins */
+
+	/* put the PCMCIA interrupts into edge triggered mode */
+	// BAD * (unsigned short *) 0xb0005004 |= 0x6000;
+
+#endif
+
+	/* 0x3c00*/
+	* (unsigned short *) 0xa400010e &= ~0x3f00; /* port H, pins 4, 5 & 6 */
+
+	printk("Hitachi HD64465 configured at 0x%x on irq %d\n",
+		CONFIG_HD64465_IOBASE, HD64465_IRQ_BASE);
+#endif
+}
+
+static void keywest_init(void)
+{
+	keywest_printf("%s", "Key West");
+#ifdef CONFIG_PCI
+	/*
+	 * make sure these pins are in PCI mode (PINT)
+	 */
+	* (unsigned short *) 0xa4000104 = 0xaaaa;	/* port C, all inputs */
+	* (unsigned short *) 0xa4000108 = 0x0000;   /* port E, all pins */
+	* (unsigned short *) 0xa4000110 = 0x0000;   /* port J, all pins */
+#ifndef CONFIG_PCMCIA
+	* (unsigned short *) 0xffffff62 |= 0x3c00;	/* Area 5/6 in 32 bit mode */
+
+	/* Make sure Area 5 & 6 are in PCI mode */
+	* (unsigned short *) 0xffffff60 &= ~0x3;   /* 5 & 6 as normal memory *
+	* (unsigned short *) 0xffffff60 &= ~0x1e0; /* ordinary memory 5 & 6 */
+#endif
+#endif
+}
+
+int __init setup_keywest(void)
+{
+	static int done = 0; /* run this only once */
+
+	if (!MACH_KEYWEST || done) return 0;
+	done = 1;
+
+	keywest_init();
+	tahoe_init();
+#if defined (CONFIG_HD64465) && defined (CONFIG_SERIAL) 
+	/* remap IO ports for first ISA serial port to HD64465 UART */
+	mach_port_map(0x3f8, 8, CONFIG_HD64465_IOBASE + 0x8000, 1);
+#endif /* CONFIG_HD64465 && CONFIG_SERIAL */
+
+    return 0;
+}
+
+void keywest_alpha(int i, char ch)
+{
+	volatile unsigned char *alpha = (unsigned char *)ALPHA_LED;
+        *(alpha + i) = ch;
+}
+
+#if 0 //keywest board(rev.4) not support status LED
+void keywest_led_on()
+{
+	volatile unsigned char *led = (unsigned char *)STATUS_LED;
+        *led = 0x82;
+}
+
+void keywest_led_off()
+{
+        volatile unsigned char *led = (unsigned char *)STATUS_LED;
+        *led = 0x02;
+}
+#endif
+
+module_init(setup_keywest);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/setup_se.c linux-2.4.22-pre10/arch/sh/kernel/setup_se.c
--- linux-2.4.21/arch/sh/kernel/setup_se.c	2000-08-09 20:59:04.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/setup_se.c	2003-08-01 13:35:00.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: setup_se.c,v 1.6 2000/05/14 08:41:25 gniibe Exp $
+/* $Id: setup_se.c,v 1.1.1.1.2.2 2002/05/10 17:58:54 jzs Exp $
  *
  * linux/arch/sh/kernel/setup_se.c
  *
@@ -18,6 +18,10 @@
 #include <asm/hitachi_se.h>
 #include <asm/smc37c93x.h>
 
+#ifdef CONFIG_SH_KGDB
+#include <asm/kgdb.h>
+#endif
+
 /*
  * Configure the Super I/O chip
  */
@@ -108,6 +112,11 @@
 	make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
 }
 
+#ifdef CONFIG_SH_KGDB
+static int kgdb_uart_setup(void);
+static struct kgdb_sermap kgdb_uart_sermap = 
+{ "ttyS", 0, kgdb_uart_setup, NULL };
+#endif
 
 /*
  * Initialize the board
@@ -116,4 +125,133 @@
 {
 	init_smsc();
 	/* XXX: RTC setting comes here */
+#ifdef CONFIG_SH_KGDB
+	kgdb_register_sermap(&kgdb_uart_sermap);
+#endif
+}
+
+/*********************************************************************
+ * Currently a hack (e.g. does not interact well w/serial.c, lots of *
+ * hardcoded stuff) but may be useful if SCI/F needs debugging.      *
+ * Mostly copied from x86 code (see files asm-i386/kgdb_local.h and  *
+ * arch/i386/lib/kgdb_serial.c).                                     *
+ *********************************************************************/
+
+#ifdef CONFIG_SH_KGDB
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+
+#define COM1_PORT 0x3f8  /* Base I/O address */
+#define COM1_IRQ  4      /* IRQ not used yet */
+#define COM2_PORT 0x2f8  /* Base I/O address */
+#define COM2_IRQ  3      /* IRQ not used yet */
+
+#define SB_CLOCK 1843200 /* Serial baud clock */
+#define SB_BASE (SB_CLOCK/16)
+#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
+
+struct uart_port {
+	int base;
+};
+#define UART_NPORTS 2
+struct uart_port uart_ports[] = {
+	{ COM1_PORT },
+	{ COM2_PORT },
+};
+struct uart_port *kgdb_uart_port;
+
+#define UART_IN(reg)	inb_p(kgdb_uart_port->base + reg)
+#define UART_OUT(reg,v)	outb_p((v), kgdb_uart_port->base + reg)
+
+/* Basic read/write functions for the UART */
+#define UART_LSR_RXCERR    (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE)
+static int kgdb_uart_getchar(void)
+{
+	int lsr;
+	int c = -1;
+
+	while (c == -1) {
+		lsr = UART_IN(UART_LSR);
+		if (lsr & UART_LSR_DR) 
+			c = UART_IN(UART_RX);
+		if ((lsr & UART_LSR_RXCERR))
+			c = -1;
+	}
+	return c;
+}
+
+static void kgdb_uart_putchar(int c)
+{
+	while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0)
+		;
+	UART_OUT(UART_TX, c);
+}
+
+/*
+ * Initialize UART to configured/requested values.
+ * (But we don't interrupts yet, or interact w/serial.c)
+ */
+static int kgdb_uart_setup(void)
+{
+	int port;
+	int lcr = 0;
+	int bdiv = 0;
+
+	if (kgdb_portnum >= UART_NPORTS) {
+		KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum);
+		return -1;
+	}
+
+	kgdb_uart_port = &uart_ports[kgdb_portnum];
+
+	/* Init sequence from gdb_hook_interrupt */
+	UART_IN(UART_RX);
+	UART_OUT(UART_IER, 0);
+
+	UART_IN(UART_RX);	/* Serial driver comments say */
+	UART_IN(UART_IIR);	/* this clears interrupt regs */
+	UART_IN(UART_MSR);
+
+	/* Figure basic LCR values */
+	switch (kgdb_bits) {
+	case '7':
+		lcr |= UART_LCR_WLEN7;
+		break;
+	default: case '8': 
+		lcr |= UART_LCR_WLEN8;
+		break;
+	}
+	switch (kgdb_parity) {
+	case 'O':
+		lcr |= UART_LCR_PARITY;
+		break;
+	case 'E':
+		lcr |= (UART_LCR_PARITY | UART_LCR_EPAR);
+		break;
+	default: break;
+	}
+
+	/* Figure the baud rate divisor */
+	bdiv = (SB_BASE/kgdb_baud);
+	
+	/* Set the baud rate and LCR values */
+	UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB));
+	UART_OUT(UART_DLL, (bdiv & 0xff));
+	UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff));
+	UART_OUT(UART_LCR, lcr);
+
+	/* Set the MCR */
+	UART_OUT(UART_MCR, SB_MCR);
+
+	/* Turn off FIFOs for now */
+	UART_OUT(UART_FCR, 0);
+
+	/* Setup complete: initialize function pointers */
+	kgdb_getchar = kgdb_uart_getchar;
+	kgdb_putchar = kgdb_uart_putchar;
+
+	return 0;
 }
+#endif /* CONFIG_SH_KGDB */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/setup_shmse.c linux-2.4.22-pre10/arch/sh/kernel/setup_shmse.c
--- linux-2.4.21/arch/sh/kernel/setup_shmse.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/setup_shmse.c	2003-08-01 13:32:13.000000000 +0000
@@ -0,0 +1,22 @@
+/*
+ * linux/arch/sh/kernel/setup_shmse.c
+ *
+ * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
+ *
+ * SH-Mobile SolutionEngine Support.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/hitachi_shmse.h>
+
+void __init init_shmse_IRQ(void)
+{
+}
+
+void __init setup_shmse(void)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/setup_snapgear.c linux-2.4.22-pre10/arch/sh/kernel/setup_snapgear.c
--- linux-2.4.21/arch/sh/kernel/setup_snapgear.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/setup_snapgear.c	2003-08-01 13:33:05.000000000 +0000
@@ -0,0 +1,187 @@
+/****************************************************************************/
+/* 
+ * linux/arch/sh/kernel/setup_snapgear.c
+ *
+ * Copyright (C) 2002  David McCullough <davidm@snapgear.com>
+ *
+ * Based on files with the following comments:
+ *
+ *           Copyright (C) 2000  Kazumoto Kojima
+ *
+ *           Modified for 7751 Solution Engine by
+ *           Ian da Silva and Jeremy Siegel, 2001.
+ */
+/****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/timer.h>
+#include <linux/ledman.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+
+/****************************************************************************/
+/*
+ * EraseConfig handling functions
+ */
+
+static void
+eraseconfig_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+#if defined(CONFIG_SH_SECUREEDGE5410)
+{
+	volatile char dummy = * (volatile char *) 0xb8000000;
+}
+#endif
+#ifdef CONFIG_LEDMAN
+	ledman_signalreset();
+#else
+	printk("SnapGear: erase switch interrupt!\n");
+#endif
+}
+
+static int __init
+eraseconfig_init(void)
+{
+	printk("SnapGear: EraseConfig init\n");
+	/* Setup "EraseConfig" switch on external IRQ 0 */
+	if (request_irq(IRL0_IRQ, eraseconfig_interrupt, SA_INTERRUPT,
+				"Erase Config", NULL))
+		printk("SnapGear: failed to register IRQ%d for Reset witch\n",
+				IRL0_IRQ);
+	else
+		printk("SnapGear: registered EraseConfig switch on IRQ%d\n",
+				IRL0_IRQ);
+	return(0);
+}
+
+module_init(eraseconfig_init);
+
+/****************************************************************************/
+/*
+ * Initialize IRQ setting
+ *
+ * IRL0 = erase switch
+ * IRL1 = eth0
+ * IRL2 = eth1
+ * IRL3 = crypto
+ */
+
+void __init
+init_snapgear_IRQ(void)
+{
+	/* enable individual interrupt mode for externals */
+	ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
+
+	printk("Setup SnapGear IRQ/IPR ...\n");
+
+	make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY);
+	make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY);
+	make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY);
+	make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY);
+}
+
+/****************************************************************************/
+/*
+ *	Fast poll interrupt simulator.
+ */
+
+#define FAST_POLL	1000
+//#define FAST_POLL_INTR
+
+#define FASTTIMER_IRQ   17
+#define FASTTIMER_IPR_ADDR  INTC_IPRA
+#define FASTTIMER_IPR_POS    2
+#define FASTTIMER_PRIORITY   3
+
+#ifdef FAST_POLL_INTR
+#define TMU1_TCR_INIT	0x0020
+#else
+#define TMU1_TCR_INIT	0
+#endif
+#define TMU_TSTR_INIT	1
+#define TMU1_TCR_CALIB	0x0000
+#define TMU_TOCR	0xffd80000	/* Byte access */
+#define TMU_TSTR	0xffd80004	/* Byte access */
+#define TMU1_TCOR	0xffd80014	/* Long access */
+#define TMU1_TCNT	0xffd80018	/* Long access */
+#define TMU1_TCR	0xffd8001c	/* Word access */
+
+
+#ifdef FAST_POLL_INTR
+static void fast_timer_irq(int irq, void *dev_instance, struct pt_regs *regs)
+{
+	unsigned long timer_status;
+    timer_status = ctrl_inw(TMU1_TCR);
+	timer_status &= ~0x100;
+	ctrl_outw(timer_status, TMU1_TCR);
+}
+#endif
+
+/*
+ * return the current ticks on the fast timer
+ */
+
+unsigned long
+fast_timer_count(void)
+{
+	return(ctrl_inl(TMU1_TCNT));
+}
+
+/*
+ * setup a fast timer for profiling etc etc
+ */
+
+static void
+setup_fast_timer()
+{
+	unsigned long interval;
+
+#ifdef FAST_POLL_INTR
+	interval = (current_cpu_data.module_clock/4 + FAST_POLL/2) / FAST_POLL;
+
+	make_ipr_irq(FASTTIMER_IRQ, FASTTIMER_IPR_ADDR, FASTTIMER_IPR_POS,
+			FASTTIMER_PRIORITY);
+
+	printk("SnapGear: %dHz fast timer on IRQ %d\n",FAST_POLL,FASTTIMER_IRQ);
+
+	if (request_irq(FASTTIMER_IRQ, fast_timer_irq, 0, "SnapGear fast timer",
+			NULL) != 0)
+		printk("%s(%d): request_irq() failed?\n", __FILE__, __LINE__);
+#else
+	printk("SnapGear: fast timer running\n",FAST_POLL,FASTTIMER_IRQ);
+	interval = 0xffffffff;
+#endif
+
+	ctrl_outb(ctrl_inb(TMU_TSTR) & ~0x2, TMU_TSTR); /* disable timer 1 */
+	ctrl_outw(TMU1_TCR_INIT, TMU1_TCR);
+	ctrl_outl(interval, TMU1_TCOR);
+	ctrl_outl(interval, TMU1_TCNT);
+	ctrl_outb(ctrl_inb(TMU_TSTR) | 0x2, TMU_TSTR); /* enable timer 1 */
+
+	printk("Timer count 1 = 0x%x\n", fast_timer_count());
+	udelay(1000);
+	printk("Timer count 2 = 0x%x\n", fast_timer_count());
+}
+
+/****************************************************************************/
+/*
+ * Initialize the board
+ */
+
+void __init
+setup_snapgear(void)
+{
+	/* XXX: RTC setting comes here */
+#ifdef CONFIG_RTC
+	secureedge5410_rtc_init();
+#endif
+ 	// setup_fast_timer();
+}
+
+/****************************************************************************/
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/sh_ksyms.c linux-2.4.22-pre10/arch/sh/kernel/sh_ksyms.c
--- linux-2.4.21/arch/sh/kernel/sh_ksyms.c	2002-02-25 19:37:56.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/sh_ksyms.c	2003-08-01 13:31:47.000000000 +0000
@@ -56,6 +56,7 @@
 #endif
 
 /* mem exports */
+EXPORT_SYMBOL(memscan);
 EXPORT_SYMBOL(memchr);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memcpy_fromio);
@@ -64,6 +65,7 @@
 EXPORT_SYMBOL(memset_io);
 EXPORT_SYMBOL(memmove);
 EXPORT_SYMBOL(memcmp);
+EXPORT_SYMBOL(__copy_user);
 
 #ifdef CONFIG_VT
 EXPORT_SYMBOL(screen_info);
@@ -77,6 +79,7 @@
 EXPORT_SYMBOL(__up);
 EXPORT_SYMBOL(__down);
 EXPORT_SYMBOL(__down_interruptible);
+EXPORT_SYMBOL(__down_trylock);
 
 EXPORT_SYMBOL(__udelay);
 EXPORT_SYMBOL(__const_udelay);
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/signal.c linux-2.4.22-pre10/arch/sh/kernel/signal.c
--- linux-2.4.21/arch/sh/kernel/signal.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/signal.c	2003-08-01 13:35:09.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.21 2000/03/11 14:06:21 gniibe Exp $
+/* $Id: signal.c,v 1.1.1.1.2.11 2002/10/23 00:57:46 mrbrown Exp $
  *
  *  linux/arch/sh/kernel/signal.c
  *
@@ -30,7 +30,8 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
+asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset,
+			 int from_syscall, unsigned long orig_r0);
 
 int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
 {
@@ -88,7 +89,7 @@
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
-		if (do_signal(&regs, &saveset))
+		if (do_signal(&regs, &saveset, 0, 0))
 			return -EINTR;
 	}
 }
@@ -117,7 +118,7 @@
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
-		if (do_signal(&regs, &saveset))
+		if (do_signal(&regs, &saveset, 0, 0))
 			return -EINTR;
 	}
 }
@@ -167,20 +168,21 @@
  * Do a signal return; undo the signal stack.
  */
 
+#define MOVW(n)	(0x9300|((n)-2))	/* Move mem word at PC+n to R3 */
+#define TRAP16	0xc310			/* Syscall w/no args (NR in R3) */
+
 struct sigframe
 {
 	struct sigcontext sc;
 	unsigned long extramask[_NSIG_WORDS-1];
-	char retcode[4];
+	u16 retcode[3];
 };
 
 struct rt_sigframe
 {
-	struct siginfo *pinfo;
-	void *puc;
 	struct siginfo info;
 	struct ucontext uc;
-	char retcode[4];
+	u16 retcode[3];
 };
 
 #if defined(__SH4__)
@@ -196,39 +198,32 @@
 static inline int save_sigcontext_fpu(struct sigcontext *sc)
 {
 	struct task_struct *tsk = current;
-	unsigned long flags;
-	int val;
 
 	if (!tsk->used_math) {
-	  val = 0;
-		__copy_to_user(&sc->sc_ownedfp, &val, sizeof(int));
+		__put_user(0, &sc->sc_ownedfp);
 		return 0;
 	}
 
-	val = 1;
-	__copy_to_user(&sc->sc_ownedfp, &val, sizeof(int));
+	__put_user(1, &sc->sc_ownedfp);
 
 	/* This will cause a "finit" to be triggered by the next
 	   attempted FPU operation by the 'current' process.
 	   */
 	tsk->used_math = 0;
 
-	save_and_cli(flags);
 	unlazy_fpu(tsk);
-	restore_flags(flags);
-
 	return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard,
 			      sizeof(long)*(16*2+2));
 }
 #endif
 
 static int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *r0_p)
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
 {
 	unsigned int err = 0;
 
 #define COPY(x)		err |= __get_user(regs->x, &sc->sc_##x)
-			COPY(regs[1]);
+	COPY(regs[0]);	COPY(regs[1]);
 	COPY(regs[2]);	COPY(regs[3]);
 	COPY(regs[4]);	COPY(regs[5]);
 	COPY(regs[6]);	COPY(regs[7]);
@@ -254,19 +249,16 @@
 			err |= restore_sigcontext_fpu(sc);
 	}
 #endif
-
-	regs->syscall_nr = -1;		/* disable syscall checks */
-	err |= __get_user(*r0_p, &sc->sc_regs[0]);
 	return err;
 }
 
+
 asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
 			     unsigned long r6, unsigned long r7,
 			     struct pt_regs regs)
 {
 	struct sigframe *frame = (struct sigframe *)regs.regs[15];
 	sigset_t set;
-	int r0;
 
 	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
@@ -284,9 +276,9 @@
 	recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
 
-	if (restore_sigcontext(&regs, &frame->sc, &r0))
+	if (restore_sigcontext(&regs, &frame->sc))
 		goto badframe;
-	return r0;
+	return regs.regs[0];
 
 badframe:
 	force_sig(SIGSEGV, current);
@@ -300,7 +292,6 @@
 	struct rt_sigframe *frame = (struct rt_sigframe *)regs.regs[15];
 	sigset_t set;
 	stack_t st;
-	int r0;
 
 	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
@@ -314,7 +305,7 @@
 	recalc_sigpending(current);
 	spin_unlock_irq(&current->sigmask_lock);
 
-	if (restore_sigcontext(&regs, &frame->uc.uc_mcontext, &r0))
+	if (restore_sigcontext(&regs, &frame->uc.uc_mcontext))
 		goto badframe;
 
 	if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
@@ -322,13 +313,12 @@
 	/* It is more difficult to avoid calling this function than to
 	   call it and ignore errors.  */
 	do_sigaltstack(&st, NULL, regs.regs[15]);
-
-	return r0;
+	return regs.regs[0];
 
 badframe:
 	force_sig(SIGSEGV, current);
 	return 0;
-}	
+}
 
 /*
  * Set up a signal frame.
@@ -406,15 +396,11 @@
 	if (ka->sa.sa_flags & SA_RESTORER) {
 		regs->pr = (unsigned long) ka->sa.sa_restorer;
 	} else {
-		/* This is : mov  #__NR_sigreturn,r3 ; trapa #0x10 */
-#ifdef __LITTLE_ENDIAN__
-		unsigned long code = 0xc310e300 | (__NR_sigreturn);
-#else
-		unsigned long code = 0xe300c310 | (__NR_sigreturn << 16);
-#endif
-
+		/* Generate return code (system call to sigreturn) */
+		err |= __put_user(MOVW(2), &frame->retcode[0]);
+		err |= __put_user(TRAP16, &frame->retcode[1]);
+		err |= __put_user((__NR_sigreturn), &frame->retcode[2]);
 		regs->pr = (unsigned long) frame->retcode;
-		err |= __put_user(code, (long *)(frame->retcode+0));
 	}
 
 	if (err)
@@ -459,8 +445,6 @@
 		? current->exec_domain->signal_invmap[sig]
 		: sig;
 
-	err |= __put_user(&frame->info, &frame->pinfo);
-	err |= __put_user(&frame->uc, &frame->puc);
 	err |= copy_siginfo_to_user(&frame->info, info);
 
 	/* Create the ucontext.  */
@@ -480,24 +464,22 @@
 	if (ka->sa.sa_flags & SA_RESTORER) {
 		regs->pr = (unsigned long) ka->sa.sa_restorer;
 	} else {
-		/* This is : mov  #__NR_rt_sigreturn,r3 ; trapa #0x10 */
-#ifdef __LITTLE_ENDIAN__
-		unsigned long code = 0xc310e300 | (__NR_rt_sigreturn);
-#else
-		unsigned long code = 0xe300c310 | (__NR_rt_sigreturn << 16);
-#endif
-
+		/* Generate return code (system call to rt_sigreturn) */
+		err |= __put_user(MOVW(2), &frame->retcode[0]);
+		err |= __put_user(TRAP16, &frame->retcode[1]);
+		err |= __put_user((__NR_rt_sigreturn), &frame->retcode[2]);
 		regs->pr = (unsigned long) frame->retcode;
-		err |= __put_user(code, (long *)(frame->retcode+0));
 	}
 
 	if (err)
 		goto give_sigsegv;
 
-	/* Set up registers for signal handler */
-	regs->regs[15] = (unsigned long) frame;
-	regs->regs[4] = signal; /* Arg for signal handler */
-	regs->pc = (unsigned long) ka->sa.sa_handler;
+	/* Set up registers (SP, PC, and args) for signal handler */
+	regs->regs[15] = (unsigned long) frame;		/* Stack pointer */
+	regs->regs[4] = signal;				/* Arg1 (signal) */
+	regs->regs[5] = (unsigned long)&frame->info;	/* Arg2 (siginfo) */
+	regs->regs[6] = (unsigned long)&frame->uc;	/* Arg3 (context) */
+	regs->pc = (unsigned long) ka->sa.sa_handler;	/* Program counter */
 
 	set_fs(USER_DS);
 
@@ -521,10 +503,11 @@
 
 static void
 handle_signal(unsigned long sig, struct k_sigaction *ka,
-	      siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
+	      siginfo_t *info, sigset_t *oldset, struct pt_regs *regs, 
+	      int from_syscall, unsigned long orig_r0)
 {
 	/* Are we from a system call? */
-	if (regs->syscall_nr >= 0) {
+	if (from_syscall) {
 		/* If so, check system call restarting.. */
 		switch (regs->regs[0]) {
 			case -ERESTARTNOHAND:
@@ -538,9 +521,20 @@
 				}
 			/* fallthrough */
 			case -ERESTARTNOINTR:
-				regs->regs[0] = regs->syscall_nr;
+				regs->regs[0] = orig_r0;
 				regs->pc -= 2;
 		}
+	} else {
+		/* gUSA handling */
+		if (regs->regs[15] >= 0xc0000000) {
+			int offset = (int)regs->regs[15];
+
+			/* Reset stack pointer: clear critical region mark */
+			regs->regs[15] = regs->regs[1];
+			if (regs->pc < regs->regs[0])
+				/* Go to rewind point #1 */
+				regs->pc = regs->regs[0] + offset - 2;
+		}
 	}
 
 	/* Set up the stack frame */
@@ -570,7 +564,8 @@
  * the kernel can handle, and then we build all the user-level signal handling
  * stack-frames in one go after that.
  */
-int do_signal(struct pt_regs *regs, sigset_t *oldset)
+int do_signal(struct pt_regs *regs, sigset_t *oldset,
+	      int from_syscall, unsigned long orig_r0)
 {
 	siginfo_t info;
 	struct k_sigaction *ka;
@@ -677,17 +672,18 @@
 		}
 
 		/* Whee!  Actually deliver the signal.  */
-		handle_signal(signr, ka, &info, oldset, regs);
+		handle_signal(signr, ka, &info, oldset, regs,
+			      from_syscall, orig_r0);
 		return 1;
 	}
 
 	/* Did we come from a system call? */
-	if (regs->syscall_nr >= 0) {
+	if (from_syscall) {
 		/* Restart the system call - no handlers present */
 		if (regs->regs[0] == -ERESTARTNOHAND ||
 		    regs->regs[0] == -ERESTARTSYS ||
 		    regs->regs[0] == -ERESTARTNOINTR) {
-			regs->regs[0] = regs->syscall_nr;
+			regs->regs[0] = orig_r0;
 			regs->pc -= 2;
 		}
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/sys_sh.c linux-2.4.22-pre10/arch/sh/kernel/sys_sh.c
--- linux-2.4.21/arch/sh/kernel/sys_sh.c	2001-10-15 20:36:48.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/sys_sh.c	2003-08-01 13:35:09.000000000 +0000
@@ -23,6 +23,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
+#include <asm/cachectl.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -221,15 +222,41 @@
 	return -EINVAL;
 }
 
-asmlinkage int sys_uname(struct old_utsname * name)
+/* sys_cacheflush -- flush (part of) the processor cache.  */
+asmlinkage int
+sys_cacheflush (unsigned long addr, unsigned long len, int op)
 {
-	int err;
-	if (!name)
+	struct vm_area_struct *vma;
+
+	if ((op < 0) || (op > (CACHEFLUSH_D_PURGE|CACHEFLUSH_I)))
+		return -EINVAL;
+
+	/*
+	 * Verify that the specified address region actually belongs
+	 * to this process.
+	 */
+	if (addr + len < addr)
 		return -EFAULT;
-	down_read(&uts_sem);
-	err=copy_to_user(name, &system_utsname, sizeof (*name));
-	up_read(&uts_sem);
-	return err?-EFAULT:0;
+	vma = find_vma (current->mm, addr);
+	if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end)
+		return -EFAULT;
+
+	switch (op & CACHEFLUSH_D_PURGE) {
+		case CACHEFLUSH_D_INVAL:
+			__flush_invalidate_region(addr, len);
+			break;
+		case CACHEFLUSH_D_WB:
+			__flush_wback_region(addr, len);
+			break;
+		case CACHEFLUSH_D_PURGE:
+			__flush_purge_region(addr, len);
+			break;
+	}
+	if (op & CACHEFLUSH_I) {
+		__flush_icache_all();
+	}
+
+	return 0;
 }
 
 asmlinkage int sys_pause(void)
@@ -238,3 +265,19 @@
 	schedule();
 	return -ERESTARTNOHAND;
 }
+
+asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char * buf,
+			     size_t count, long dummy, loff_t pos)
+{
+	extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
+					size_t count, loff_t pos);
+	return sys_pread(fd, buf, count, pos);
+}
+
+asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char * buf,
+			      size_t count, long dummy, loff_t pos)
+{
+	extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
+					size_t count, loff_t pos);
+	return sys_pwrite(fd, buf, count, pos);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/time.c linux-2.4.22-pre10/arch/sh/kernel/time.c
--- linux-2.4.21/arch/sh/kernel/time.c	2001-09-08 19:29:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/time.c	2003-08-01 13:30:33.000000000 +0000
@@ -1,9 +1,10 @@
-/* $Id: time.c,v 1.30 2001/09/01 14:34:31 mrbrown Exp $
+/* $Id: time.c,v 1.1.1.1.2.6 2003/07/16 18:43:55 yoshii Exp $
  *
  *  linux/arch/sh/kernel/time.c
  *
  *  Copyright (C) 1999  Tetsuya Okada & Niibe Yutaka
  *  Copyright (C) 2000  Philipp Rumpf <prumpf@tux.org>
+ *  Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
  *
  *  Some code taken from i386 version.
  *    Copyright (C) 1991, 1992, 1995  Linus Torvalds
@@ -29,17 +30,36 @@
 #include <asm/delay.h>
 #include <asm/machvec.h>
 #include <asm/rtc.h>
+#ifdef CONFIG_SH_KGDB
+#include <asm/kgdb.h>
+#endif
 
 #include <linux/timex.h>
 #include <linux/irq.h>
 
-#define TMU_TOCR_INIT	0x00
-#define TMU0_TCR_INIT	0x0020
-#define TMU_TSTR_INIT	1
+#define TMU_TOCR_INIT	0x00	/* Don't output RTC clock */
+
+#define TMU0_TCR_INIT	0x0020	/* Clock/4, rising edge; interrupt on */
+#define TMU0_TCR_CALIB	0x0000	/* Clock/4, rising edge; no interrupt */
+#define TMU0_TSTR_INIT	0x01	/* Bit to turn on TMU0 */
 
-#define TMU0_TCR_CALIB	0x0000
+#define TMU1_TCR_INIT	0x0000	/* Clock/4, rising edge; no interrupt */
+#define TMU1_TSTR_INIT  0x02	/* Bit to turn on TMU1 */
 
 #if defined(__sh3__)
+#if defined(CONFIG_CPU_SUBTYPE_SH7300)
+#define TMU_TSTR        0xA412FE92      /* Byte access */
+
+#define TMU0_TCOR       0xA412FE94      /* Long access */
+#define TMU0_TCNT       0xA412FE98      /* Long access */
+#define TMU0_TCR        0xA412FE9C      /* Word access */
+
+#define TMU1_TCOR	0xA412FEA0	/* Long access */
+#define TMU1_TCNT	0xA412FEA4	/* Long access */
+#define TMU1_TCR	0xA412FEA8	/* Word access */
+
+#define FRQCR           0xA415FF80
+#else
 #define TMU_TOCR	0xfffffe90	/* Byte access */
 #define TMU_TSTR	0xfffffe92	/* Byte access */
 
@@ -47,7 +67,12 @@
 #define TMU0_TCNT	0xfffffe98	/* Long access */
 #define TMU0_TCR	0xfffffe9c	/* Word access */
 
+#define TMU1_TCOR	0xfffffea0	/* Long access */
+#define TMU1_TCNT	0xfffffea4	/* Long access */
+#define TMU1_TCR	0xfffffea8	/* Word access */
+
 #define FRQCR		0xffffff80
+#endif
 #elif defined(__SH4__)
 #define TMU_TOCR	0xffd80000	/* Byte access */
 #define TMU_TSTR	0xffd80004	/* Byte access */
@@ -56,6 +81,10 @@
 #define TMU0_TCNT	0xffd8000c	/* Long access */
 #define TMU0_TCR	0xffd80010	/* Word access */
 
+#define TMU1_TCOR	0xffd80014	/* Long access */
+#define TMU1_TCNT	0xffd80018	/* Long access */
+#define TMU1_TCR	0xffd8001c	/* Word access */
+
 #define FRQCR		0xffc00000
 
 /* Core Processor Version Register */
@@ -64,10 +93,10 @@
 #define CCN_PVR_CHIP_MASK  0xff
 #define CCN_PVR_CHIP_ST40STB1 0x4
 
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+#ifdef CONFIG_CPU_SUBTYPE_ST40
 #define CLOCKGEN_MEMCLKCR 0xbb040038
 #define MEMCLKCR_RATIO_MASK 0x7
-#endif /* CONFIG_CPU_SUBTYPE_ST40STB1 */
+#endif /* CONFIG_CPU_SUBTYPE_ST40 */
 #endif /* __sh3__ or __SH4__ */
 
 extern rwlock_t xtime_lock;
@@ -176,6 +205,27 @@
 /* last time the RTC clock got updated */
 static long last_rtc_update;
 
+static __inline__ void sh_do_profile (unsigned long pc)
+{
+	extern int _stext;
+
+	if (!prof_buffer)
+		return;
+
+	if(pc >= 0xa0000000UL && pc < 0xc0000000UL)
+		pc -= 0x20000000;
+	pc -= (unsigned long) &_stext;
+	pc >>= prof_shift;
+	/*
+	 * Don't ignore out-of-bounds PC values silently,
+	 * put them into the last histogram slot, so if
+	 * present, they will show up as a sharp peak.
+	 */
+	if (pc > prof_len-1)
+		pc = prof_len-1;
+	prof_buffer[pc]++;
+}
+
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
@@ -245,7 +295,9 @@
 	 * have it count down at its natural rate.
 	 */
 	ctrl_outb(0, TMU_TSTR);
+#if !defined(CONFIG_CPU_SUBTYPE_SH7300)
 	ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
+#endif
 	ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR);
 	ctrl_outl(0xffffffff, TMU0_TCOR);
 	ctrl_outl(0xffffffff, TMU0_TCNT);
@@ -257,7 +309,7 @@
 	} while (tv1.tv_usec == tv2.tv_usec && tv1.tv_sec == tv2.tv_sec);
 
 	/* actually start the timer */
-	ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
+	ctrl_outb(TMU0_TSTR_INIT, TMU_TSTR);
 
 	do {
 		rtc_gettimeofday(&tv2);
@@ -283,27 +335,41 @@
 	return freq * factor;
 }
 
+static unsigned int sh_pclk_freq __initdata = CONFIG_SH_PCLK_FREQ;
+static int __init sh_pclk_setup(char *str)
+{
+	unsigned int freq;
+	if (get_option(&str, &freq))
+		sh_pclk_freq = freq;
+	return 1;
+}
+__setup("sh_pclk=", sh_pclk_setup);
+
 static struct irqaction irq0  = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
 
 void __init time_init(void)
 {
 	unsigned int cpu_clock, master_clock, bus_clock, module_clock;
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+#ifdef CONFIG_CPU_SUBTYPE_ST40
 	unsigned int memory_clock;
 #endif
 	unsigned int timer_freq;
 	unsigned short frqcr, ifc, pfc, bfc;
 	unsigned long interval;
 #if defined(__sh3__)
+#if defined(CONFIG_CPU_SUBTYPE_SH7300)
+	static int pfc_table[] = { 1, 2, 3, 4, 6 };
+#else
 	static int ifc_table[] = { 1, 2, 4, 1, 3, 1, 1, 1 };
 	static int pfc_table[] = { 1, 2, 4, 1, 3, 6, 1, 1 };
 	static int stc_table[] = { 1, 2, 4, 8, 3, 6, 1, 1 };
+#endif
 #elif defined(__SH4__)
 	static int ifc_table[] = { 1, 2, 3, 4, 6, 8, 1, 1 };
 #define bfc_table ifc_table	/* Same */
 	static int pfc_table[] = { 2, 3, 4, 6, 8, 2, 2, 2 };
 
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+#ifdef CONFIG_CPU_SUBTYPE_ST40
 	struct frqcr_data {
 		unsigned short frqcr;
 		struct {
@@ -359,19 +425,33 @@
 #endif
 #endif
 
-	rtc_gettimeofday(&xtime);
+	if(rtc_gettimeofday)
+		rtc_gettimeofday(&xtime);
+	else{
+        	xtime.tv_sec = mktime(2000, 1, 1, 0, 0, 0);
+        	xtime.tv_usec = 0;
+	}
 
 	setup_irq(TIMER_IRQ, &irq0);
 
-	timer_freq = get_timer_frequency();
-
-	module_clock = timer_freq * 4;
+	if( sh_pclk_freq ){
+		module_clock = sh_pclk_freq;
+	}else{
+		timer_freq = get_timer_frequency();
+		module_clock = timer_freq * 4;
+	}
 
 #if defined(__sh3__)
 	{
 		unsigned short tmp;
 
 		frqcr = ctrl_inw(FRQCR);
+#if defined(CONFIG_CPU_SUBTYPE_SH7300)
+                bfc = ((frqcr & 0x0700) >> 8)+1;
+                ifc = ((frqcr & 0x0070) >> 4)+1;
+                tmp = frqcr & 0x0007;
+                pfc = pfc_table[tmp];
+#else
 		tmp  = (frqcr & 0x8000) >> 13;
 		tmp |= (frqcr & 0x0030) >>  4;
 		bfc = stc_table[tmp];
@@ -381,10 +461,11 @@
 		tmp  = (frqcr & 0x2000) >> 11;
 		tmp |= frqcr & 0x0003;
 		pfc = pfc_table[tmp];
+#endif
 	}
 #elif defined(__SH4__)
 	{
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+#ifdef CONFIG_CPU_SUBTYPE_ST40
 		unsigned long pvr;
 
 		/* This should probably be moved into the SH3 probing code, and then use the processor
@@ -438,14 +519,14 @@
 	master_clock = module_clock * pfc;
 	bus_clock = master_clock / bfc;
 	cpu_clock = master_clock / ifc;
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+#ifdef CONFIG_CPU_SUBTYPE_ST40
  skip_calc:
 #endif
 	printk("CPU clock: %d.%02dMHz\n",
 	       (cpu_clock / 1000000), (cpu_clock % 1000000)/10000);
 	printk("Bus clock: %d.%02dMHz\n",
 	       (bus_clock/1000000), (bus_clock % 1000000)/10000);
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+#ifdef CONFIG_CPU_SUBTYPE_ST40
 	printk("Memory clock: %d.%02dMHz\n",
 	       (memory_clock/1000000), (memory_clock % 1000000)/10000);
 #endif
@@ -458,16 +539,37 @@
 	current_cpu_data.cpu_clock    = cpu_clock;
 	current_cpu_data.master_clock = master_clock;
 	current_cpu_data.bus_clock    = bus_clock;
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
+#ifdef CONFIG_CPU_SUBTYPE_ST40
 	current_cpu_data.memory_clock = memory_clock;
 #endif
 	current_cpu_data.module_clock = module_clock;
 
-	/* Start TMU0 */
+	/* Stop all timers */
 	ctrl_outb(0, TMU_TSTR);
+#if !defined(CONFIG_CPU_SUBTYPE_SH7300)
 	ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
+#endif
+
+	/* Start TMU0 (jiffy interrupts) */
 	ctrl_outw(TMU0_TCR_INIT, TMU0_TCR);
 	ctrl_outl(interval, TMU0_TCOR);
 	ctrl_outl(interval, TMU0_TCNT);
-	ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
+	ctrl_outb(TMU0_TSTR_INIT, TMU_TSTR);
+
+#if defined(CONFIG_START_TMU1)
+	/* Start TMU1 (free-running) */
+	ctrl_outw(TMU1_TCR_INIT, TMU1_TCR);
+	ctrl_outl(0xffffffff, TMU1_TCOR);
+	ctrl_outl(0xffffffff, TMU1_TCNT);
+	ctrl_outb((ctrl_inb(TMU_TSTR) | TMU1_TSTR_INIT), TMU_TSTR);
+#endif
+
+#if defined(CONFIG_SH_KGDB)
+	/*
+	 * Set up kgdb as requested. We do it here because the serial
+	 * init uses the timer vars we just set up for figuring baud.
+	 */
+        kgdb_init();
+#endif
+
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/traps.c linux-2.4.22-pre10/arch/sh/kernel/traps.c
--- linux-2.4.21/arch/sh/kernel/traps.c	2002-02-25 19:37:56.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/traps.c	2003-08-01 13:30:45.000000000 +0000
@@ -1,10 +1,11 @@
-/* $Id: traps.c,v 1.14 2001/07/24 08:07:10 gniibe Exp $
+/* $Id: traps.c,v 1.1.1.1.2.4 2002/05/10 17:58:54 jzs Exp $
  *
  *  linux/arch/sh/traps.c
  *
  *  SuperH version: Copyright (C) 1999 Niibe Yutaka
  *                  Copyright (C) 2000 Philipp Rumpf
  *                  Copyright (C) 2000 David Howells
+ *                  Copyright (C) 2002 Paul Mundt
  */
 
 /*
@@ -31,6 +32,19 @@
 #include <asm/atomic.h>
 #include <asm/processor.h>
 
+#ifdef CONFIG_SH_KGDB
+#include <asm/kgdb.h>
+#define CHK_REMOTE_DEBUG(regs)                                               \
+{                                                                            \
+  if ((kgdb_debug_hook != (kgdb_debug_hook_t *) NULL) && (!user_mode(regs))) \
+  {                                                                          \
+    (*kgdb_debug_hook)(regs);                                                \
+  }                                                                          \
+}
+#else
+#define CHK_REMOTE_DEBUG(regs)
+#endif
+
 #define DO_ERROR(trapnr, signr, str, name, tsk) \
 asmlinkage void do_##name(unsigned long r4, unsigned long r5, \
 			  unsigned long r6, unsigned long r7, \
@@ -42,6 +56,7 @@
 	sti(); \
 	tsk->thread.error_code = error_code; \
 	tsk->thread.trap_no = trapnr; \
+        CHK_REMOTE_DEBUG(&regs); \
 	force_sig(signr, tsk); \
 	die_if_no_fixup(str,&regs,error_code); \
 }
@@ -61,6 +76,7 @@
 	console_verbose();
 	spin_lock_irq(&die_lock);
 	printk("%s: %04lx\n", str, err & 0xffff);
+	CHK_REMOTE_DEBUG(regs);
 	show_regs(regs);
 	spin_unlock_irq(&die_lock);
 	do_exit(SIGSEGV);
@@ -300,10 +316,19 @@
 /*
  * handle an instruction that does an unaligned memory access
  * - have to be careful of branch delay-slot instructions that fault
+ *  SH3:
  *   - if the branch would be taken PC points to the branch
  *   - if the branch would not be taken, PC points to delay-slot
+ *  SH4:
+ *   - PC always points to delayed branch
  * - return 0 if handled, -EFAULT if failed (may not return if in kernel)
  */
+
+/* Macros to determine offset from current PC for branch instructions */
+/* Explicit type coercion is used to force sign extension where needed */
+#define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4)
+#define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4)
+
 static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
 {
 	u_int rm;
@@ -392,15 +417,27 @@
 			break;
 		case 0x0F00: /* bf/s lab */
 			ret = handle_unaligned_delayslot(regs);
-			if (ret==0)
-				regs->pc += (instruction&0x00FF)*2 + 4;
+			if (ret==0) {
+#if defined(__SH4__)
+				if ((regs->sr & 0x00000001) != 0)
+					regs->pc += 4; /* next after slot */
+				else
+#endif
+					regs->pc += SH_PC_8BIT_OFFSET(instruction);
+			}
 			break;
 		case 0x0900: /* bt   lab - no delayslot */
 			break;
 		case 0x0D00: /* bt/s lab */
 			ret = handle_unaligned_delayslot(regs);
-			if (ret==0)
-				regs->pc += (instruction&0x00FF)*2 + 4;
+			if (ret==0) {
+#if defined(__SH4__)
+				if ((regs->sr & 0x00000001) == 0)
+					regs->pc += 4; /* next after slot */
+				else
+#endif
+					regs->pc += SH_PC_8BIT_OFFSET(instruction);
+			}
 			break;
 		}
 		break;
@@ -408,14 +445,14 @@
 	case 0xA000: /* bra label */
 		ret = handle_unaligned_delayslot(regs);
 		if (ret==0)
-			regs->pc += (instruction&0x0FFF)*2 + 4;
+			regs->pc += SH_PC_12BIT_OFFSET(instruction);
 		break;
 
 	case 0xB000: /* bsr label */
 		ret = handle_unaligned_delayslot(regs);
 		if (ret==0) {
 			regs->pr = regs->pc + 4;
-			regs->pc += (instruction&0x0FFF)*2 + 4;
+			regs->pc += SH_PC_12BIT_OFFSET(instruction);
 		}
 		break;
 	}
@@ -539,29 +576,51 @@
 		     : "memory");
 }
 
-void dump_stack(void)
+void show_task(unsigned long *sp)
 {
-	unsigned long *start;
-	unsigned long *end;
-	unsigned long *p;
-
-	asm("mov	r15, %0" : "=r" (start));
-	asm("stc	r7_bank, %0" : "=r" (end));
-	end += 8192/4;
-
-	printk("%08lx:%08lx\n", (unsigned long)start, (unsigned long)end);
-	for (p=start; p < end; p++) {
-		extern long _text, _etext;
-		unsigned long v=*p;
-
-		if ((v >= (unsigned long )&_text)
-		    && (v <= (unsigned long )&_etext)) {
-			printk("%08lx\n", v);
+	unsigned long *stack, addr;
+	unsigned long module_start = VMALLOC_START;
+	unsigned long module_end = VMALLOC_END;
+	extern long _text, _etext;
+	int i = 1;
+
+	if (!sp) {
+		__asm__ __volatile__ (
+			"mov r15, %0\n\t"
+			"stc r7_bank, %1\n\t"
+			: "=r" (module_start),
+			  "=r" (module_end)
+		);
+		
+		sp = (unsigned long *)module_start;
+	}
+
+	stack = sp;
+
+	printk("\nCall trace: ");
+
+	while (((long)stack & (THREAD_SIZE - 1))) {
+		if (__get_user(addr, stack)) {
+			printk("Failing address 0x%lx\n", *stack);
+			break;
+		}
+		stack++;
+
+		if (((addr >= (unsigned long)&_text) &&
+		     (addr <= (unsigned long)&_etext)) ||
+		    ((addr >= module_start) && (addr <= module_end))) {
+			if (i && ((i % 8) == 0))
+				printk("\n       ");
+
+			printk("[<%08lx>] ", addr);
+			i++;
 		}
 	}
+
+	printk("\n");
 }
 
 void show_trace_task(struct task_struct *tsk)
 {
-	printk("Backtrace not yet implemented for SH.\n");
+	show_task((unsigned long *)tsk->thread.sp);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/kernel/ubc.S linux-2.4.22-pre10/arch/sh/kernel/ubc.S
--- linux-2.4.21/arch/sh/kernel/ubc.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/kernel/ubc.S	2003-08-01 13:30:41.000000000 +0000
@@ -0,0 +1,59 @@
+/*
+ * arch/sh/kernel/ubc.S
+ *
+ * Set of management routines for the User Break Controller (UBC)
+ *
+ * Copyright (C) 2002 Paul Mundt
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/linkage.h>
+#include <asm/ubc.h>
+
+#define STBCR2		0xffc00010
+
+ENTRY(ubc_sleep)
+	mov	#0, r0
+
+	mov.l	1f, r1		! Zero out UBC_BBRA ..
+	mov.w	r0, @r1
+
+	mov.l	2f, r1		! .. same for BBRB ..
+	mov.w	r0, @r1
+
+	mov.l	3f, r1		! .. and again for BRCR.
+	mov.w	r0, @r1
+
+	mov.w	@r1, r0		! Dummy read BRCR
+
+	mov.l	4f, r1		! Set MSTP5 in STBCR2
+	mov.b	@r1, r0
+	or	#0x01, r0
+	mov.b	r0, @r1
+
+	mov.b	@r1, r0		! Two dummy reads ..
+	mov.b	@r1, r0
+
+	rts
+	nop
+
+ENTRY(ubc_wakeup)
+	mov.l	4f, r1		! Clear MSTP5
+	mov.b	@r1, r0
+	and	#0xfe, r0
+	mov.b	r0, @r1
+
+	mov.b	@r1, r0		! Two more dummy reads ..
+	mov.b	@r1, r0
+
+	rts
+	nop
+
+1:	.long	UBC_BBRA
+2:	.long	UBC_BBRB
+3:	.long	UBC_BRCR
+4:	.long	STBCR2
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/lib/delay.c linux-2.4.22-pre10/arch/sh/lib/delay.c
--- linux-2.4.21/arch/sh/lib/delay.c	2001-01-29 02:56:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/lib/delay.c	2003-08-01 13:33:30.000000000 +0000
@@ -33,3 +33,8 @@
 {
 	__const_udelay(usecs * 0x000010c6);  /* 2**32 / 1000000 */
 }
+
+void __ndelay(unsigned long nsecs)
+{
+	__const_udelay(nsecs * 5);  /* 2**32 / 1000000000 (rounded up) */
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/mm/Makefile linux-2.4.22-pre10/arch/sh/mm/Makefile
--- linux-2.4.21/arch/sh/mm/Makefile	2001-09-08 19:29:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/mm/Makefile	2003-08-01 13:32:25.000000000 +0000
@@ -10,8 +10,9 @@
 O_TARGET := mm.o
 obj-y	 := init.o fault.o extable.o clear_page.o copy_page.o
 
+obj-$(CONFIG_PCI_SD0001) += ioremap.o
 obj-$(CONFIG_CPU_SH3) += cache-sh3.o
-obj-$(CONFIG_CPU_SH4) += cache-sh4.o __clear_user_page-sh4.o __copy_user_page-sh4.o ioremap.o
+obj-$(CONFIG_CPU_SH4) += cache-sh4.o ioremap.o
 
 USE_STANDARD_AS_RULE := true
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/mm/cache-sh4.c linux-2.4.22-pre10/arch/sh/mm/cache-sh4.c
--- linux-2.4.21/arch/sh/mm/cache-sh4.c	2001-10-15 20:36:48.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/mm/cache-sh4.c	2003-08-01 13:31:48.000000000 +0000
@@ -1,9 +1,8 @@
-/* $Id: cache-sh4.c,v 1.16 2001/09/10 11:06:35 dwmw2 Exp $
+/* $Id: cache-sh4.c,v 1.1.1.1.2.8 2003/07/09 09:59:30 trent Exp $
  *
- *  linux/arch/sh/mm/cache.c
- *
- * Copyright (C) 1999, 2000  Niibe Yutaka
+ *  linux/arch/sh/mm/cache-sh4.c
  *
+ * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
  */
 
 #include <linux/config.h>
@@ -42,6 +41,7 @@
 #define CACHE_OC_ADDRESS_ARRAY 0xf4000000
 #define CACHE_VALID	  1
 #define CACHE_UPDATED	  2
+#define CACHE_ASSOC	  8
 
 #define CACHE_OC_WAY_SHIFT       13
 #define CACHE_IC_WAY_SHIFT       13
@@ -56,8 +56,8 @@
 static void __init
 detect_cpu_and_cache_system(void)
 {
-#ifdef CONFIG_CPU_SUBTYPE_ST40STB1
-	cpu_data->type = CPU_ST40STB1;
+#ifdef CONFIG_CPU_SUBTYPE_ST40
+	cpu_data->type = CPU_ST40;
 #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)
 	cpu_data->type = CPU_SH7750;
 #else
@@ -109,7 +109,7 @@
 				    unsigned long size, unsigned long flags);
 
 	if (remap_area_pages(P3SEG, 0, PAGE_SIZE*4, _PAGE_CACHABLE))
-		panic("p3_cachie_init failed.");
+		panic("%s failed.", __FUNCTION__);
 	sema_init (&p3map_sem[0], 1);
 	sema_init (&p3map_sem[1], 1);
 	sema_init (&p3map_sem[2], 1);
@@ -177,6 +177,17 @@
 	}
 }
 
+void __flush_icache_all(void)
+{
+	unsigned long flags;
+
+	save_and_cli(flags);
+	jump_to_P2();
+	ctrl_outl(CCR_CACHE_VAL|CCR_CACHE_ICI, CCR);
+	back_to_P1();
+	restore_flags(flags);
+}
+
 /*
  * Write back the range of D-cache, and purge the I-cache.
  *
@@ -208,44 +219,26 @@
 	restore_flags(flags);
 }
 
-/*
- * Writeback&Invalidate the D-cache of the page
- */
-static void __flush_dcache_page(unsigned long phys)
+static inline void flush_cache_4096(unsigned long start,
+				    unsigned long phys)
 {
-	unsigned long addr, data;
-	unsigned long flags;
-
-	phys |= CACHE_VALID;
-
-	save_and_cli(flags);
-	jump_to_P2();
-
-	/* Loop all the D-cache */
-	for (addr = CACHE_OC_ADDRESS_ARRAY;
-	     addr < (CACHE_OC_ADDRESS_ARRAY
-		     +(CACHE_OC_NUM_ENTRIES<< CACHE_OC_ENTRY_SHIFT));
-	     addr += (1<<CACHE_OC_ENTRY_SHIFT)) {
-		data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
-		if (data == phys)
-			ctrl_outl(0, addr);
-	}
+	unsigned long flags; 
+	extern void __flush_cache_4096(unsigned long addr, unsigned long phys, unsigned long exec_offset);
 
-#if 0 /* DEBUG DEBUG */
-	/* Loop all the I-cache */
-	for (addr = CACHE_IC_ADDRESS_ARRAY;
-	     addr < (CACHE_IC_ADDRESS_ARRAY
-		     +(CACHE_IC_NUM_ENTRIES<< CACHE_IC_ENTRY_SHIFT));
-	     addr += (1<<CACHE_IC_ENTRY_SHIFT)) {
-		data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
-		if (data == phys) {
-			printk(KERN_INFO "__flush_cache_page: I-cache entry found\n");
-			ctrl_outl(0, addr);
-		}
-	}
+#if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_ST40)
+	if (start >= CACHE_OC_ADDRESS_ARRAY) {
+		/*
+		 * SH7751 and ST40 have no restriction to handle cache.
+		 * (While SH7750 must do that at P2 area.)
+		 */
+		__flush_cache_4096(start | CACHE_ASSOC, phys | 0x80000000, 0);
+	} else
 #endif
-	back_to_P1();
-	restore_flags(flags);
+	{
+		save_and_cli(flags);
+		__flush_cache_4096(start | CACHE_ASSOC, phys | 0x80000000, 0x20000000);
+		restore_flags(flags);
+	}
 }
 
 /*
@@ -254,38 +247,77 @@
  */
 void flush_dcache_page(struct page *page)
 {
-	if (test_bit(PG_mapped, &page->flags))
-		__flush_dcache_page(PHYSADDR(page_address(page)));
+	if (test_bit(PG_mapped, &page->flags)) {
+		unsigned long phys = PHYSADDR(page_address(page));
+
+		/* Loop all the D-cache */
+		flush_cache_4096(CACHE_OC_ADDRESS_ARRAY,          phys);
+		flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x1000, phys);
+		flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x2000, phys);
+		flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x3000, phys);
+	}
 }
 
-void flush_cache_all(void)
+static inline void flush_icache_all(void)
 {
-	extern unsigned long empty_zero_page[1024];
 	unsigned long flags;
-	unsigned long addr;
 
 	save_and_cli(flags);
-
-	/* Prefetch the data to write back D-cache */
-	for (addr = (unsigned long)empty_zero_page;
-	     addr < (unsigned long)empty_zero_page + 1024*16;
-	     addr += L1_CACHE_BYTES)
-		asm volatile("pref @%0"::"r" (addr));
-
 	jump_to_P2();
-	/* Flush D-cache/I-cache */
-	ctrl_outl(CCR_CACHE_INIT, CCR);
+	/* Flush I-cache */
+	ctrl_outl(CCR_CACHE_VAL|CCR_CACHE_ICI, CCR);
 	back_to_P1();
 	restore_flags(flags);
 }
 
+void flush_cache_all(void)
+{
+	extern void __flush_dcache_all(void);
+
+	__flush_dcache_all();
+	flush_icache_all();
+}
+
 void flush_cache_mm(struct mm_struct *mm)
 {
 	/* Is there any good way? */
 	/* XXX: possibly call flush_cache_range for each vm area */
+	/* 
+	 * FIXME: Really, the optimal solution here would be able to flush out
+	 * individual lines created by the specified context, but this isn't
+	 * feasible for a number of architectures (such as MIPS, and some
+	 * SPARC) .. is this possible for SuperH?
+	 *
+	 * In the meantime, we'll just flush all of the caches.. this
+	 * seems to be the simplest way to avoid at least a few wasted
+	 * cache flushes. -Lethal
+	 */
 	flush_cache_all();
 }
 
+static void __flush_cache_page(struct vm_area_struct *vma,
+			       unsigned long address,
+			       unsigned long phys)
+{
+	/* We only need to flush D-cache when we have alias */
+	if ((address^phys) & CACHE_ALIAS) {
+		/* Loop 4K of the D-cache */
+		flush_cache_4096(
+			CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS),
+			phys);
+		/* Loop another 4K of the D-cache */
+		flush_cache_4096(
+			CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS),
+			phys);
+	}
+
+	if (vma->vm_flags & VM_EXEC)
+		/* Loop 4K (half) of the I-cache */
+		flush_cache_4096(
+			CACHE_IC_ADDRESS_ARRAY | (address & 0x1000),
+			phys);
+}
+
 /*
  * Write back and invalidate D-caches.
  *
@@ -298,14 +330,53 @@
 void flush_cache_range(struct mm_struct *mm, unsigned long start,
 		       unsigned long end)
 {
-	/*
-	 * We could call flush_cache_page for the pages of these range,
-	 * but it's not efficient (scan the caches all the time...).
-	 *
-	 * We can't use A-bit magic, as there's the case we don't have
-	 * valid entry on TLB.
-	 */
-	flush_cache_all();
+	extern void flush_cache_4096_all(unsigned long start);
+
+	unsigned long p = start & PAGE_MASK;
+	pgd_t *dir;
+	pmd_t *pmd;
+	pte_t *pte;
+	pte_t entry;
+	unsigned long phys;
+	unsigned long d = 0;
+
+	dir = pgd_offset(mm, p);
+	pmd = pmd_offset(dir, p);
+
+	do {
+		if (pmd_none(*pmd) || pmd_bad(*pmd)) {
+			p &= ~((1 << PMD_SHIFT) -1);
+			p += (1 << PMD_SHIFT);
+			pmd++;
+			continue;
+		}
+		pte = pte_offset(pmd, p);
+		do {
+			entry = *pte;
+			if ((pte_val(entry) & _PAGE_PRESENT)) {
+				phys = pte_val(entry)&PTE_PHYS_MASK;
+				if ((p^phys) & CACHE_ALIAS) {
+					d |= 1 << ((p & CACHE_ALIAS)>>12); 
+					d |= 1 << ((phys & CACHE_ALIAS)>>12);
+					if (d == 0x0f)
+						goto loop_exit;
+				}
+			}
+			pte++;
+			p += PAGE_SIZE;
+		} while (p < end && (unsigned long)pte & PAGE_MASK);
+		pmd++;
+	} while (p < end);
+ loop_exit:
+	if (d & 1)
+		flush_cache_4096_all(0);
+	if (d & 2)
+		flush_cache_4096_all(0x1000);
+	if (d & 4)
+		flush_cache_4096_all(0x2000);
+	if (d & 8)
+		flush_cache_4096_all(0x3000);
+	flush_icache_all();
 }
 
 /*
@@ -319,8 +390,7 @@
 	pmd_t *pmd;
 	pte_t *pte;
 	pte_t entry;
-	unsigned long phys, addr, data;
-	unsigned long flags;
+	unsigned long phys;
 
 	dir = pgd_offset(vma->vm_mm, address);
 	pmd = pmd_offset(dir, address);
@@ -328,49 +398,11 @@
 		return;
 	pte = pte_offset(pmd, address);
 	entry = *pte;
-	if (pte_none(entry) || !pte_present(entry))
+	if (!(pte_val(entry) & _PAGE_PRESENT))
 		return;
 
 	phys = pte_val(entry)&PTE_PHYS_MASK;
-
-	phys |= CACHE_VALID;
-	save_and_cli(flags);
-	jump_to_P2();
-
-	/* We only need to flush D-cache when we have alias */
-	if ((address^phys) & CACHE_ALIAS) {
-		/* Loop 4K of the D-cache */
-		for (addr = CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS);
-		     addr < (CACHE_OC_ADDRESS_ARRAY + (address & CACHE_ALIAS) 
-			     +(CACHE_OC_NUM_ENTRIES/4<<CACHE_OC_ENTRY_SHIFT));
-		     addr += (1<<CACHE_OC_ENTRY_SHIFT)) {
-			data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
-			if (data == phys)
-				ctrl_outl(0, addr);
-		}
-		/* Loop another 4K of the D-cache */
-		for (addr = CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS);
-		     addr < (CACHE_OC_ADDRESS_ARRAY + (phys & CACHE_ALIAS) 
-			     +(CACHE_OC_NUM_ENTRIES/4<<CACHE_OC_ENTRY_SHIFT));
-		     addr += (1<<CACHE_OC_ENTRY_SHIFT)) {
-			data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
-			if (data == phys)
-				ctrl_outl(0, addr);
-		}
-	}
-
-	if (vma->vm_flags & VM_EXEC)
-		/* Loop 4K of the I-cache */
-		for (addr = CACHE_IC_ADDRESS_ARRAY|(address&0x1000);
-		     addr < ((CACHE_IC_ADDRESS_ARRAY|(address&0x1000))
-			     +(CACHE_IC_NUM_ENTRIES/2<<CACHE_IC_ENTRY_SHIFT));
-		     addr += (1<<CACHE_IC_ENTRY_SHIFT)) {
-			data = ctrl_inl(addr)&(0x1ffff000|CACHE_VALID);
-			if (data == phys)
-				ctrl_outl(0, addr);
-		}
-	back_to_P1();
-	restore_flags(flags);
+	__flush_cache_page(vma, address, phys);
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/mm/clear_page.S linux-2.4.22-pre10/arch/sh/mm/clear_page.S
--- linux-2.4.21/arch/sh/mm/clear_page.S	2001-09-08 19:29:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/mm/clear_page.S	2003-08-01 13:31:55.000000000 +0000
@@ -1,10 +1,13 @@
-/* $Id: clear_page.S,v 1.1 2001/07/23 10:08:50 gniibe Exp $
+/* $Id: clear_page.S,v 1.1.1.1.2.8 2003/04/18 10:53:25 sugioka Exp $
  *
- * clear_page implementation of SuperH
+ * __clear_user_page, __clear_user, clear_page implementation of SuperH
  *
- * Copyright (C) 2001  Niibe Yutaka & Kaz Kojima
+ * Copyright (C) 2001  Kaz Kojima
+ * Copyright (C) 2001, 2002  Niibe Yutaka
  *
  */
+#include <linux/config.h>
+#include <linux/linkage.h>
 
 /*
  * clear_page
@@ -18,7 +21,6 @@
  * r4 --- to
  * r5 --- to + 4096
  */
-#include <linux/linkage.h>
 ENTRY(clear_page)
 	mov	r4,r5
 	mov.w	.Llimit,r0
@@ -50,3 +52,244 @@
 	rts
 	 nop
 .Llimit:	.word	(4096-28)
+
+ENTRY(__clear_user)
+	!
+	mov	#0, r0
+	mov	#0xe0, r1	! 0xffffffe0
+	!
+	! r4..(r4+31)&~32 	   -------- not aligned	[ Area 0 ]
+	! (r4+31)&~32..(r4+r5)&~32 -------- aligned	[ Area 1 ]
+	! (r4+r5)&~32..r4+r5       -------- not aligned	[ Area 2 ]
+	!
+	! Clear area 0
+	mov	r4, r2
+	!
+	tst	r1, r5		! length < 32
+	bt	.Larea2		! skip to remainder
+	!
+	add	#31, r2
+	and	r1, r2
+	cmp/eq	r4, r2
+	bt	.Larea1
+	mov	r2, r3
+	sub	r4, r3
+	mov	r3, r7
+	mov	r4, r2
+	!
+.L0:	dt	r3
+0:	mov.b	r0, @r2
+	bf/s	.L0
+	 add	#1, r2
+	!
+	sub	r7, r5
+	mov	r2, r4
+.Larea1:
+	mov	r4, r3
+	add	r5, r3
+	and	r1, r3
+	cmp/hi	r2, r3
+	bf	.Larea2
+	!
+	! Clear area 1
+#if defined(__SH4__)
+1:	movca.l	r0, @r2
+#else
+1:	mov.l	r0, @r2
+#endif
+	add	#4, r2
+2:	mov.l	r0, @r2
+	add	#4, r2
+3:	mov.l	r0, @r2
+	add	#4, r2
+4:	mov.l	r0, @r2
+	add	#4, r2
+5:	mov.l	r0, @r2
+	add	#4, r2
+6:	mov.l	r0, @r2
+	add	#4, r2
+7:	mov.l	r0, @r2
+	add	#4, r2
+8:	mov.l	r0, @r2
+	add	#4, r2
+	cmp/hi	r2, r3
+	bt/s	1b
+	 nop
+	!
+	! Clear area 2
+.Larea2:
+	mov	r4, r3
+	add	r5, r3
+	cmp/hs	r3, r2
+	bt/s	.Ldone
+	 sub	r2, r3
+.L2:	dt	r3
+9:	mov.b	r0, @r2
+	bf/s	.L2
+	 add	#1, r2
+	!
+.Ldone:	rts
+	 mov	#0, r0	! return 0 as normal return
+
+	! return the number of bytes remained
+.Lbad_clear_user:
+	mov	r4, r0
+	add	r5, r0
+	rts
+	 sub	r2, r0
+
+.section __ex_table,"a"
+	.align 2
+	.long	0b, .Lbad_clear_user
+	.long	1b, .Lbad_clear_user
+	.long	2b, .Lbad_clear_user
+	.long	3b, .Lbad_clear_user
+	.long	4b, .Lbad_clear_user
+	.long	5b, .Lbad_clear_user
+	.long	6b, .Lbad_clear_user
+	.long	7b, .Lbad_clear_user
+	.long	8b, .Lbad_clear_user
+	.long	9b, .Lbad_clear_user
+.previous
+
+#if defined(__SH4__)
+/*
+ * __clear_user_page
+ * @to: P1 address (with same color)
+ * @orig_to: P1 address
+ *
+ * void __clear_user_page(void *to, void *orig_to)
+ */
+
+/*
+ * r0 --- scratch 
+ * r4 --- to
+ * r5 --- orig_to
+ * r6 --- to + 4096
+ */
+ENTRY(__clear_user_page)
+	mov.w	.L4096,r0
+	mov	r4,r6
+	add	r0,r6
+	mov	#0,r0
+	!
+1:	ocbi	@r5
+	add	#32,r5
+	movca.l	r0,@r4
+	mov	r4,r1
+	add	#32,r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	mov.l	r0,@-r4
+	add	#28,r4
+	cmp/eq	r6,r4
+	bf/s	1b
+	 ocbwb	@r1
+	!
+	rts
+	 nop
+.L4096:	.word	4096
+
+ENTRY(__flush_cache_4096)
+	mov.l	1f,r3
+	add	r6,r3
+	mov	r4,r0
+	mov	#64,r2
+	shll	r2
+	mov	#64,r6
+	jmp	@r3
+	 mov	#96,r7
+	.align	2
+1:	.long	2f
+2:
+	.rept	32
+	mov.l	r5,@r0
+	mov.l	r5,@(32,r0)
+	mov.l	r5,@(r0,r6)
+	mov.l	r5,@(r0,r7)
+	add	r2,r5
+	add	r2,r0
+	.endr
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	rts
+	 nop
+
+ENTRY(__flush_dcache_all)
+	mov.l	2f,r0
+	mov.l	3f,r4
+	and	r0,r4		! r4 = (unsigned long)&empty_zero_page[0] & ~0xffffc000
+	stc	sr,r1		! save SR
+	mov.l	4f,r2
+	or	r1,r2
+	mov	#32,r3
+	shll2	r3
+1:
+	ldc	r2,sr		! set BL bit
+	movca.l	r0,@r4
+	ocbi	@r4
+	add	#32,r4
+	movca.l	r0,@r4
+	ocbi	@r4
+	add	#32,r4
+	movca.l	r0,@r4
+	ocbi	@r4
+	add	#32,r4
+	movca.l	r0,@r4
+	ocbi	@r4
+	ldc	r1,sr		! restore SR
+	dt	r3
+	bf/s	1b
+	 add	#32,r4
+
+	rts
+	 nop
+	.align	2
+2:	.long	0xffffc000
+3:	.long	SYMBOL_NAME(empty_zero_page)
+4:	.long	0x10000000	! BL bit
+
+/* flush_cache_4096_all(unsigned long addr) */
+ENTRY(flush_cache_4096_all)
+	mov.l	2f,r0
+	mov.l	3f,r2
+	and	r0,r2
+	or	r2,r4		! r4 = addr | (unsigned long)&empty_zero_page[0] & ~0x3fff
+	stc	sr,r1		! save SR
+	mov.l	4f,r2
+	or	r1,r2
+	mov	#32,r3
+1:
+	ldc	r2,sr		! set BL bit
+	movca.l	r0,@r4
+	ocbi	@r4
+	add	#32,r4
+	movca.l	r0,@r4
+	ocbi	@r4
+	add	#32,r4
+	movca.l	r0,@r4
+	ocbi	@r4
+	add	#32,r4
+	movca.l	r0,@r4
+	ocbi	@r4
+	ldc	r1,sr		! restore SR
+	dt	r3
+	bf/s	1b
+	 add	#32,r4
+
+	rts
+	 nop
+	.align	2
+2:	.long	0xffffc000
+3:	.long	SYMBOL_NAME(empty_zero_page)
+4:	.long	0x10000000	! BL bit
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/mm/copy_page.S linux-2.4.22-pre10/arch/sh/mm/copy_page.S
--- linux-2.4.21/arch/sh/mm/copy_page.S	2001-09-08 19:29:09.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/mm/copy_page.S	2003-08-01 13:31:07.000000000 +0000
@@ -1,10 +1,12 @@
-/* $Id: copy_page.S,v 1.2 2001/07/23 10:27:25 gniibe Exp $
+/* $Id: copy_page.S,v 1.1.1.1.2.6 2003/03/23 15:30:58 sugioka Exp $
  *
- * copy_page implementation of SuperH
+ * copy_page, __copy_user_page, __copy_user implementation of SuperH
  *
  * Copyright (C) 2001  Niibe Yutaka & Kaz Kojima
+ * Copyright (C) 2002  Toshinobu Sugioka
  *
  */
+#include <linux/linkage.h>
 
 /*
  * copy_page
@@ -21,7 +23,6 @@
  * r10 --- to
  * r11 --- from
  */
-#include <linux/linkage.h>
 ENTRY(copy_page)
 	mov.l	r8,@-r15
 	mov.l	r10,@-r15
@@ -66,4 +67,331 @@
 	mov.l	@r15+,r8
 	rts
 	 nop
+
+#if defined(__SH4__)
+/*
+ * __copy_user_page
+ * @to: P1 address (with same color)
+ * @from: P1 address
+ * @orig_to: P1 address
+ *
+ * void __copy_user_page(void *to, void *from, void *orig_to)
+ */
+
+/*
+ * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch 
+ * r8 --- from + 4096
+ * r9 --- orig_to
+ * r10 --- to
+ * r11 --- from
+ */
+ENTRY(__copy_user_page)
+	mov.l	r8,@-r15
+	mov.l	r9,@-r15
+	mov.l	r10,@-r15
+	mov.l	r11,@-r15
+	mov	r4,r10
+	mov	r5,r11
+	mov	r6,r9
+	mov	r5,r8
+	mov.w	.L4096,r0
+	add	r0,r8
+	!
+1:	ocbi	@r9
+	add	#32,r9
+	mov.l	@r11+,r0
+	mov.l	@r11+,r1
+	mov.l	@r11+,r2
+	mov.l	@r11+,r3
+	mov.l	@r11+,r4
+	mov.l	@r11+,r5
+	mov.l	@r11+,r6
+	mov.l	@r11+,r7
+	movca.l	r0,@r10
+	mov	r10,r0
+	add	#32,r10
+	mov.l	r7,@-r10
+	mov.l	r6,@-r10
+	mov.l	r5,@-r10
+	mov.l	r4,@-r10
+	mov.l	r3,@-r10
+	mov.l	r2,@-r10
+	mov.l	r1,@-r10
+	ocbwb	@r0
+	cmp/eq	r11,r8
+	bf/s	1b
+	 add	#28,r10
+	!
+	mov.l	@r15+,r11
+	mov.l	@r15+,r10
+	mov.l	@r15+,r9
+	mov.l	@r15+,r8
+	rts
+	 nop
+#endif
 .L4096:	.word	4096
+/*
+ * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
+ * Return the number of bytes NOT copied
+ */
+#define EX(...)			\
+	9999: __VA_ARGS__ ;		\
+	.section __ex_table, "a";	\
+	.long 9999b, 6000f	;	\
+	.previous
+ENTRY(__copy_user)
+	tst	r6,r6		! Check explicitly for zero
+	bf	1f
+	rts
+	 mov	#0,r0		! normal return
+1:
+	mov.l	r10,@-r15
+	mov.l	r9,@-r15
+	mov.l	r8,@-r15
+	mov	r4,r3
+	add	r6,r3		! last destination address
+	mov	#12,r0		! Check if small number of bytes
+	cmp/gt	r0,r6
+	bt	2f
+	bra	.L_cleanup_loop
+	 nop
+2:
+	neg	r5,r0		! Calculate bytes needed to align source
+	add	#4,r0
+	and	#3,r0
+	tst	r0,r0
+	bt	.L_jump
+	mov	r0,r1
+
+.L_loop1:
+	! Copy bytes to align source
+EX(	mov.b	@r5+,r0		)
+	dt	r1
+EX(	mov.b	r0,@r4		)
+	add	#-1,r6
+	bf/s	.L_loop1
+	 add	#1,r4
+
+.L_jump:
+	mov	r6,r2		! Calculate number of longwords to copy
+	shlr2	r2
+	tst	r2,r2
+	bt	.L_cleanup
+
+	mov	r4,r0		! Jump to appropriate routine
+	and	#3,r0
+	mov	r0,r1
+	shll2	r1
+	mova	.L_jump_tbl,r0
+	mov.l	@(r0,r1),r1
+	jmp	@r1
+	 nop
+
+	.align 2
+.L_jump_tbl:
+	.long	.L_dest00
+	.long	.L_dest01
+	.long	.L_dest10
+	.long	.L_dest11
+
+! Destination = 00
+
+.L_dest00:
+	mov	r2,r7
+	shlr2	r7
+	shlr	r7
+	tst	r7,r7
+	mov	#7,r0
+	bt/s	1f
+	 and	r0,r2
+	.align 2
+2:
+EX(	mov.l	@r5+,r0		)
+EX(	mov.l	@r5+,r8		)
+EX(	mov.l	@r5+,r9		)
+EX(	mov.l	@r5+,r10	)
+EX(	mov.l	r0,@r4		)
+EX(	mov.l	r8,@(4,r4)	)
+EX(	mov.l	r9,@(8,r4)	)
+EX(	mov.l	r10,@(12,r4)	)
+EX(	mov.l	@r5+,r0		)
+EX(	mov.l	@r5+,r8		)
+EX(	mov.l	@r5+,r9		)
+EX(	mov.l	@r5+,r10	)
+	dt	r7
+EX(	mov.l	r0,@(16,r4)	)
+EX(	mov.l	r8,@(20,r4)	)
+EX(	mov.l	r9,@(24,r4)	)
+EX(	mov.l	r10,@(28,r4)	)
+	bf/s	2b
+	 add	#32,r4
+	tst	r2,r2
+	bt	.L_cleanup
+1:
+EX(	mov.l	@r5+,r0		)
+	dt	r2
+EX(	mov.l	r0,@r4		)
+	bf/s	1b
+	 add	#4,r4
+
+	bra	.L_cleanup
+	 nop
+
+! Destination = 10
+
+.L_dest10:
+	mov	r2,r7
+	shlr2	r7
+	shlr	r7
+	tst	r7,r7
+	mov	#7,r0
+	bt/s	1f
+	 and	r0,r2
+2:
+	dt	r7
+#ifdef __LITTLE_ENDIAN__
+EX(	mov.l	@r5+,r0		)
+EX(	mov.l	@r5+,r1		)
+EX(	mov.l	@r5+,r8		)
+EX(	mov.l	@r5+,r9		)
+EX(	mov.l	@r5+,r10	)
+EX(	mov.w	r0,@r4		)
+	add	#2,r4
+	xtrct	r1,r0
+	xtrct	r8,r1
+	xtrct	r9,r8
+	xtrct	r10,r9
+
+EX(	mov.l	r0,@r4		)
+EX(	mov.l	r1,@(4,r4)	)
+EX(	mov.l	r8,@(8,r4)	)
+EX(	mov.l	r9,@(12,r4)	)
+
+EX(	mov.l	@r5+,r1		)
+EX(	mov.l	@r5+,r8		)
+EX(	mov.l	@r5+,r0		)
+	xtrct	r1,r10
+	xtrct	r8,r1
+	xtrct	r0,r8
+	shlr16	r0
+EX(	mov.l	r10,@(16,r4)	)
+EX(	mov.l	r1,@(20,r4)	)
+EX(	mov.l	r8,@(24,r4)	)
+EX(	mov.w	r0,@(28,r4)	)
+	bf/s	2b
+	 add	#30,r4
+#else
+EX(	mov.l	@(28,r5),r0	)
+EX(	mov.l	@(24,r5),r8	)
+EX(	mov.l	@(20,r5),r9	)
+EX(	mov.l	@(16,r5),r10	)
+EX(	mov.w	r0,@(30,r4)	)
+	add	#-2,r4
+	xtrct	r8,r0
+	xtrct	r9,r8
+	xtrct	r10,r9
+EX(	mov.l	r0,@(28,r4)	)
+EX(	mov.l	r8,@(24,r4)	)
+EX(	mov.l	r9,@(20,r4)	)
+
+EX(	mov.l	@(12,r5),r0	)
+EX(	mov.l	@(8,r5),r8	)
+	xtrct	r0,r10
+EX(	mov.l	@(4,r5),r9	)
+	mov.l	r10,@(16,r4)
+EX(	mov.l	@r5,r10		)
+	xtrct	r8,r0
+	xtrct	r9,r8
+	xtrct	r10,r9
+EX(	mov.l	r0,@(12,r4)	)
+EX(	mov.l	r8,@(8,r4)	)
+	swap.w	r10,r0
+EX(	mov.l	r9,@(4,r4)	)
+EX(	mov.w	r0,@(2,r4)	)
+
+	add	#32,r5
+	bf/s	2b
+	 add	#34,r4
+#endif
+	tst	r2,r2
+	bt	.L_cleanup
+
+1:	! Read longword, write two words per iteration
+EX(	mov.l	@r5+,r0		)
+	dt	r2
+#ifdef __LITTLE_ENDIAN__
+EX(	mov.w	r0,@r4		)
+	shlr16	r0
+EX(	mov.w 	r0,@(2,r4)	)
+#else
+EX(	mov.w	r0,@(2,r4)	)
+	shlr16	r0
+EX(	mov.w	r0,@r4		)
+#endif
+	bf/s	1b
+	 add	#4,r4
+
+	bra	.L_cleanup
+	 nop
+
+! Destination = 01 or 11
+
+.L_dest01:
+.L_dest11:
+	! Read longword, write byte, word, byte per iteration
+EX(	mov.l	@r5+,r0		)
+	dt	r2
+#ifdef __LITTLE_ENDIAN__
+EX(	mov.b	r0,@r4		)
+	shlr8	r0
+	add	#1,r4
+EX(	mov.w	r0,@r4		)
+	shlr16	r0
+EX(	mov.b	r0,@(2,r4)	)
+	bf/s	.L_dest01
+	 add	#3,r4
+#else
+EX(	mov.b	r0,@(3,r4)	)
+	shlr8	r0
+	swap.w	r0,r7
+EX(	mov.b	r7,@r4		)
+	add	#1,r4
+EX(	mov.w	r0,@r4		)
+	bf/s	.L_dest01
+	 add	#3,r4
+#endif
+
+! Cleanup last few bytes
+.L_cleanup:
+	mov	r6,r0
+	and	#3,r0
+	tst	r0,r0
+	bt	.L_exit
+	mov	r0,r6
+
+.L_cleanup_loop:
+EX(	mov.b	@r5+,r0		)
+	dt	r6
+EX(	mov.b	r0,@r4		)
+	bf/s	.L_cleanup_loop
+	 add	#1,r4
+
+.L_exit:
+	mov	#0,r0		! normal return
+5000:
+
+# Exception handler:
+.section .fixup, "ax"
+6000:
+	mov.l	8000f,r1
+	mov	r3,r0
+	jmp	@r1
+	 sub	r4,r0
+	.align	2
+8000:	.long	5000b
+
+.previous
+	mov.l	@r15+,r8
+	mov.l	@r15+,r9
+	rts
+	 mov.l	@r15+,r10
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/mm/fault.c linux-2.4.22-pre10/arch/sh/mm/fault.c
--- linux-2.4.21/arch/sh/mm/fault.c	2002-11-28 23:53:11.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/mm/fault.c	2003-08-01 13:32:05.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.49 2001/10/06 19:46:00 lethal Exp $
+/* $Id: fault.c,v 1.1.1.1.2.3 2002/10/24 05:52:58 mrbrown Exp $
  *
  *  linux/arch/sh/mm/fault.c
  *  Copyright (C) 1999  Niibe Yutaka
@@ -27,6 +27,10 @@
 #include <asm/hardirq.h>
 #include <asm/mmu_context.h>
 
+#if defined(CONFIG_SH_KGDB)
+#include <asm/kgdb.h>
+#endif
+
 extern void die(const char *,struct pt_regs *,long);
 
 /*
@@ -95,6 +99,11 @@
 	unsigned long page;
 	unsigned long fixup;
 
+#if defined(CONFIG_SH_KGDB)
+	if (kgdb_nofault && kgdb_bus_err_hook)
+	  kgdb_bus_err_hook();
+#endif
+
 	tsk = current;
 	mm = tsk->mm;
 
@@ -243,10 +252,16 @@
 	pte_t *pte;
 	pte_t entry;
 
+#if defined(CONFIG_SH_KGDB)
+	if (kgdb_nofault && kgdb_bus_err_hook)
+	  kgdb_bus_err_hook();
+#endif
 	if (address >= P3SEG && address < P4SEG)
 		dir = pgd_offset_k(address);
 	else if (address >= TASK_SIZE)
 		return 1;
+	else if (!current->mm)
+		return 1;
 	else
 		dir = pgd_offset(current->mm, address);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/mm/init.c linux-2.4.22-pre10/arch/sh/mm/init.c
--- linux-2.4.21/arch/sh/mm/init.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/mm/init.c	2003-08-01 13:34:19.000000000 +0000
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.19 2001/10/01 02:21:50 gniibe Exp $
+/* $Id: init.c,v 1.1.1.1.2.2 2003/07/07 11:23:21 trent Exp $
  *
  *  linux/arch/sh/mm/init.c
  *
@@ -139,7 +139,7 @@
 void __init mem_init(void)
 {
 	extern unsigned long empty_zero_page[1024];
-	int codesize, reservedpages, datasize, initsize;
+	int codesize, reservedpages, datasize, bsssize, initsize, pagemapsize;
 	int tmp;
 
 	max_mapnr = num_physpages = MAX_LOW_PFN - START_PFN;
@@ -163,15 +163,19 @@
 			reservedpages++;
 	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
+	bsssize  =  (unsigned long) &_end - (unsigned long) &__bss_start;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+	pagemapsize = (max_mapnr + 1)*sizeof(struct page);
 
-	printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
-		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
-		max_mapnr << (PAGE_SHIFT-10),
-		codesize >> 10,
-		reservedpages << (PAGE_SHIFT-10),
-		datasize >> 10,
-		initsize >> 10);
+	printk("Memory: %luk/%luk available (%dk reserved including: %dk kernel code, %dk data, %dk BSS, %dk init, %dk page map)\n",
+	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+	       max_mapnr << (PAGE_SHIFT-10),
+	       reservedpages << (PAGE_SHIFT-10),
+	       codesize >> 10,
+	       datasize >> 10,
+	       bsssize >> 10,
+	       initsize >> 10,
+	       pagemapsize >> 10);
 
 	p3_cache_init();
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/overdrive/Makefile linux-2.4.22-pre10/arch/sh/overdrive/Makefile
--- linux-2.4.21/arch/sh/overdrive/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/overdrive/Makefile	2003-08-01 13:33:31.000000000 +0000
@@ -0,0 +1,20 @@
+#
+# Makefile for the STMicroelectronics Overdrive specific parts of the kernel
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+all: overdrive.o
+
+clean:
+
+O_TARGET := overdrive.o
+obj-y	 := mach.o setup.o io.o led.o
+
+ifneq ($(CONFIG_SH_GENERIC)$(CONFIG_SH_7750_OVERDRIVE),)
+obj-$(CONFIG_PCI) +=  irq.o fpga.o galileo.o
+endif
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/overdrive/fpga.c linux-2.4.22-pre10/arch/sh/overdrive/fpga.c
--- linux-2.4.21/arch/sh/overdrive/fpga.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/overdrive/fpga.c	2003-08-01 13:31:07.000000000 +0000
@@ -0,0 +1,134 @@
+/* 
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * This file handles programming up the Altera Flex10K that interfaces to
+ * the Galileo, and does the PS/2 keyboard and mouse
+ *
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+
+#include "gt64111.h"
+#include "overdrive.h"
+#include "fpga.h"
+
+#define FPGA_NotConfigHigh()  (*FPGA_ControlReg) = (*FPGA_ControlReg) | ENABLE_FPGA_BIT
+#define FPGA_NotConfigLow()   (*FPGA_ControlReg) = (*FPGA_ControlReg) & RESET_FPGA_MASK
+
+/* I need to find out what (if any) the real delay factor here is */
+/* The delay is definately not critical */
+#define long_delay() {int i;for(i=0;i<10000;i++);}
+#define short_delay() {int i;for(i=0;i<100;i++);}
+
+static void __init program_overdrive_fpga(const unsigned char *fpgacode,
+					  int size)
+{
+	int timeout = 0;
+	int i, j;
+	unsigned char b;
+	static volatile unsigned char *FPGA_ControlReg =
+	    (volatile unsigned char *) (OVERDRIVE_CTRL);
+	static volatile unsigned char *FPGA_ProgramReg =
+	    (volatile unsigned char *) (FPGA_DCLK_ADDRESS);
+
+	printk("FPGA:  Commencing FPGA Programming\n");
+
+	/* The PCI reset but MUST be low when programming the FPGA !!! */
+	b = (*FPGA_ControlReg) & RESET_PCI_MASK;
+
+	(*FPGA_ControlReg) = b;
+
+	/* Prepare FPGA to program */
+
+	FPGA_NotConfigHigh();
+	long_delay();
+
+	FPGA_NotConfigLow();
+	short_delay();
+
+	while ((*FPGA_ProgramReg & FPGA_NOT_STATUS) != 0) {
+		printk("FPGA:  Waiting for NotStatus to go Low ... \n");
+	}
+
+	FPGA_NotConfigHigh();
+
+	/* Wait for FPGA "ready to be programmed" signal */
+	printk("FPGA:  Waiting for NotStatus to go high (FPGA ready)... \n");
+
+	for (timeout = 0;
+	     (((*FPGA_ProgramReg & FPGA_NOT_STATUS) == 0)
+	      && (timeout < FPGA_TIMEOUT)); timeout++);
+
+	/* Check if timeout condition occured - i.e. an error */
+
+	if (timeout == FPGA_TIMEOUT) {
+		printk
+		    ("FPGA:  Failed to program - Timeout waiting for notSTATUS to go high\n");
+		return;
+	}
+
+	printk("FPGA:  Copying data to FPGA ... %d bytes\n", size);
+
+	/* Copy array to FPGA - bit at a time */
+
+	for (i = 0; i < size; i++) {
+		volatile unsigned w = 0;
+
+		for (j = 0; j < 8; j++) {
+			*FPGA_ProgramReg = (fpgacode[i] >> j) & 0x01;
+			short_delay();
+		}
+		if ((i & 0x3ff) == 0) {
+			printk(".");
+		}
+	}
+
+	/* Waiting for CONFDONE to go high - means the program is complete  */
+
+	for (timeout = 0;
+	     (((*FPGA_ProgramReg & FPGA_CONFDONE) == 0)
+	      && (timeout < FPGA_TIMEOUT)); timeout++) {
+
+		*FPGA_ProgramReg = 0x0;
+		long_delay();
+	}
+
+	if (timeout == FPGA_TIMEOUT) {
+		printk
+		    ("FPGA:  Failed to program - Timeout waiting for CONFDONE to go high\n");
+		return;
+	} else {		/* Clock another 10 times - gets the device into a working state      */
+		for (i = 0; i < 10; i++) {
+			*FPGA_ProgramReg = 0x0;
+			short_delay();
+		}
+	}
+
+	printk("FPGA:  Programming complete\n");
+}
+
+
+static const unsigned char __init fpgacode[] = {
+#include "./overdrive.ttf"	/* Code from maxplus2 compiler */
+	, 0, 0
+};
+
+
+int __init init_overdrive_fpga(void)
+{
+	program_overdrive_fpga(fpgacode, sizeof(fpgacode));
+
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/overdrive/fpga.h linux-2.4.22-pre10/arch/sh/overdrive/fpga.h
--- linux-2.4.21/arch/sh/overdrive/fpga.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/overdrive/fpga.h	2003-08-01 13:30:53.000000000 +0000
@@ -0,0 +1,15 @@
+/* 
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ */
+
+#ifndef __FPGA_OD_H__
+#define __FPGA_OD_H__
+
+/* This routine will program up the fpga which interfaces to the galileo */
+int init_overdrive_fpga(void);
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/overdrive/galileo.c linux-2.4.22-pre10/arch/sh/overdrive/galileo.c
--- linux-2.4.21/arch/sh/overdrive/galileo.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/overdrive/galileo.c	2003-08-01 13:32:53.000000000 +0000
@@ -0,0 +1,594 @@
+/* 
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * This file contains the PCI routines required for the Galileo GT6411 
+ * PCI bridge as used on the Orion and Overdrive boards.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+
+#include "overdrive.h"
+#include "gt64111.h"
+
+
+/* After boot, we shift the Galileo registers so that they appear 
+ * in BANK6, along with IO space. This means we can have one contingous
+ * lump of PCI address space without these registers appearing in the 
+ * middle of them 
+ */
+
+#define GT64111_BASE_ADDRESS  0xbb000000
+#define GT64111_IO_BASE_ADDRESS  0x1000
+/* The GT64111 registers appear at this address to the SH4 after reset */
+#define RESET_GT64111_BASE_ADDRESS           0xb4000000
+
+/* Macros used to access the Galileo registers */
+#define RESET_GT64111_REG(x) (RESET_GT64111_BASE_ADDRESS+x)
+#define GT64111_REG(x) (GT64111_BASE_ADDRESS+x)
+
+#define RESET_GT_WRITE(x,v) writel((v),RESET_GT64111_REG(x))
+
+#define RESET_GT_READ(x) readl(RESET_GT64111_REG(x))
+
+#define GT_WRITE(x,v) writel((v),GT64111_REG(x))
+#define GT_WRITE_BYTE(x,v) writeb((v),GT64111_REG(x))
+#define GT_WRITE_SHORT(x,v) writew((v),GT64111_REG(x))
+
+#define GT_READ(x)    readl(GT64111_REG(x))
+#define GT_READ_BYTE(x)  readb(GT64111_REG(x))
+#define GT_READ_SHORT(x) readw(GT64111_REG(x))
+
+
+/* Where the various SH banks start at */
+#define SH_BANK4_ADR 0xb0000000
+#define SH_BANK5_ADR 0xb4000000
+#define SH_BANK6_ADR 0xb8000000
+
+/* Masks out everything but lines 28,27,26 */
+#define BANK_SELECT_MASK 0x1c000000
+
+#define SH4_TO_BANK(x) ( (x) & BANK_SELECT_MASK)
+
+/* 
+ * Masks used for address conversaion. Bank 6 is used for IO and 
+ * has all the address bits zeroed by the FPGA. Special case this
+ */
+#define MEMORY_BANK_MASK 0x1fffffff
+#define IO_BANK_MASK  0x03ffffff
+
+/* Mark bank 6 as the bank used for IO. You can change this in the FPGA code
+ * if you want 
+ */
+#define IO_BANK_ADR PCI_GTIO_BASE
+
+/* Will select the correct mask to apply depending on the SH$ address */
+#define SELECT_BANK_MASK(x) \
+   ( (SH4_TO_BANK(x)==SH4_TO_BANK(IO_BANK_ADR)) ? IO_BANK_MASK : MEMORY_BANK_MASK)
+
+/* Converts between PCI space and P2 region */
+#define SH4_TO_PCI(x) ((x)&SELECT_BANK_MASK(x))
+
+/* Various macros for figuring out what to stick in the Galileo registers. 
+ * You *really* don't want to figure this stuff out by hand, you always get
+ * it wrong
+ */
+#define GT_MEM_LO_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7ff)
+#define GT_MEM_HI_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7f)
+#define GT_MEM_SUB_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>20)&0xff)
+
+#define PROGRAM_HI_LO(block,a,s) \
+    GT_WRITE(block##_LO_DEC_ADR,GT_MEM_LO_ADR(a));\
+    GT_WRITE(block##_HI_DEC_ADR,GT_MEM_HI_ADR(a+s-1))
+
+#define PROGRAM_SUB_HI_LO(block,a,s) \
+    GT_WRITE(block##_LO_DEC_ADR,GT_MEM_SUB_ADR(a));\
+    GT_WRITE(block##_HI_DEC_ADR,GT_MEM_SUB_ADR(a+s-1))
+
+/* We need to set the size, and the offset register */
+
+#define GT_BAR_MASK(x) ((x)&~0xfff)
+
+/* Macro to set up the BAR in the Galileo. Essentially used for the DRAM */
+#define PROGRAM_GT_BAR(block,a,s) \
+  GT_WRITE(PCI_##block##_BANK_SIZE,GT_BAR_MASK((s-1)));\
+  write_config_to_galileo(PCI_CONFIG_##block##_BASE_ADR,\
+			     GT_BAR_MASK(a))
+
+#define DISABLE_GT_BAR(block) \
+  GT_WRITE(PCI_##block##_BANK_SIZE,0),\
+  GT_CONFIG_WRITE(PCI_CONFIG_##block##_BASE_ADR,\
+    0x80000000)
+
+/* Macros to disable things we are not going to use */
+#define DISABLE_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0x7ff);\
+                          GT_WRITE(x##_HI_DEC_ADR,0x00)
+
+#define DISABLE_SUB_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0xff);\
+                              GT_WRITE(x##_HI_DEC_ADR,0x00)
+
+static void __init reset_pci(void)
+{
+	/* Set RESET_PCI bit high */
+	writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL);
+	udelay(250);
+
+	/* Set RESET_PCI bit low */
+	writeb(readb(OVERDRIVE_CTRL) & RESET_PCI_MASK, OVERDRIVE_CTRL);
+	udelay(250);
+
+	writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL);
+	udelay(250);
+}
+
+static int write_config_to_galileo(int where, u32 val);
+#define GT_CONFIG_WRITE(where,val) write_config_to_galileo(where,val)
+
+#define ENABLE_PCI_DRAM
+
+
+#ifdef TEST_DRAM
+/* Test function to check out if the PCI DRAM is working OK */
+static int  /* __init */ test_dram(unsigned *base, unsigned size)
+{
+	unsigned *p = base;
+	unsigned *end = (unsigned *) (((unsigned) base) + size);
+	unsigned w;
+
+	for (p = base; p < end; p++) {
+		*p = 0xffffffff;
+		if (*p != 0xffffffff) {
+			printk("AAARGH -write failed!!! at %p is %x\n", p,
+			       *p);
+			return 0;
+		}
+		*p = 0x0;
+		if (*p != 0x0) {
+			printk("AAARGH -write failed!!!\n");
+			return 0;
+		}
+	}
+
+	for (p = base; p < end; p++) {
+		*p = (unsigned) p;
+		if (*p != (unsigned) p) {
+			printk("Failed at 0x%p, actually is 0x%x\n", p,
+			       *p);
+			return 0;
+		}
+	}
+
+	for (p = base; p < end; p++) {
+		w = ((unsigned) p & 0xffff0000);
+		*p = w | (w >> 16);
+	}
+
+	for (p = base; p < end; p++) {
+		w = ((unsigned) p & 0xffff0000);
+		w |= (w >> 16);
+		if (*p != w) {
+			printk
+			    ("Failed at 0x%p, should be 0x%x actually is 0x%x\n",
+			     p, w, *p);
+			return 0;
+		}
+	}
+
+	return 1;
+}
+#endif
+
+
+/* Function to set up and initialise the galileo. This sets up the BARS,
+ * maps the DRAM into the address space etc,etc
+ */
+int __init galileo_init(void)
+{
+	reset_pci();
+
+	/* Now shift the galileo regs into this block */
+	RESET_GT_WRITE(INTERNAL_SPACE_DEC,
+		       GT_MEM_LO_ADR(GT64111_BASE_ADDRESS));
+
+	/* Should have a sanity check here, that you can read back  at the new
+	 * address what you just wrote 
+	 */
+
+	/* Disable decode for all regions */
+	DISABLE_DECODE(RAS10);
+	DISABLE_DECODE(RAS32);
+	DISABLE_DECODE(CS20);
+	DISABLE_DECODE(CS3);
+	DISABLE_DECODE(PCI_IO);
+	DISABLE_DECODE(PCI_MEM0);
+	DISABLE_DECODE(PCI_MEM1);
+
+	/* Disable all BARS */
+	GT_WRITE(BAR_ENABLE_ADR, 0x1ff);
+	DISABLE_GT_BAR(RAS10);
+	DISABLE_GT_BAR(RAS32);
+	DISABLE_GT_BAR(CS20);
+	DISABLE_GT_BAR(CS3);
+
+	/* Tell the BAR where the IO registers now are */
+	GT_CONFIG_WRITE(PCI_CONFIG_INT_REG_IO_ADR,GT_BAR_MASK(
+					    (GT64111_IO_BASE_ADDRESS &
+					     IO_BANK_MASK)));
+	/* set up a 112 Mb decode */
+	PROGRAM_HI_LO(PCI_MEM0, SH_BANK4_ADR, 112 * 1024 * 1024);
+
+	/* Set up a 32 MB io space decode */
+	PROGRAM_HI_LO(PCI_IO, IO_BANK_ADR, 32 * 1024 * 1024);
+
+#ifdef ENABLE_PCI_DRAM
+	/* Program up the DRAM configuration - there is DRAM only in bank 0 */
+	/* Now set up the DRAM decode */
+	PROGRAM_HI_LO(RAS10, PCI_DRAM_BASE, PCI_DRAM_SIZE);
+	/* And the sub decode */
+	PROGRAM_SUB_HI_LO(RAS0, PCI_DRAM_BASE, PCI_DRAM_SIZE);
+
+	DISABLE_SUB_DECODE(RAS1);
+
+	/* Set refresh rate */
+	GT_WRITE(DRAM_BANK0_PARMS, 0x3f);
+	GT_WRITE(DRAM_CFG, 0x100);
+
+	/* we have to lob off the top bits rememeber!! */
+	PROGRAM_GT_BAR(RAS10, SH4_TO_PCI(PCI_DRAM_BASE), PCI_DRAM_SIZE);
+
+#endif
+
+	/* We are only interested in decoding RAS10 and the Galileo's internal 
+	 * registers (as IO) on the PCI bus
+	 */
+#ifdef ENABLE_PCI_DRAM
+	GT_WRITE(BAR_ENABLE_ADR, (~((1 << 8) | (1 << 3))) & 0x1ff);
+#else
+	GT_WRITE(BAR_ENABLE_ADR, (~(1 << 3)) & 0x1ff);
+#endif
+
+	/* Change the class code to host bridge, it actually powers up 
+	 * as a memory controller
+         */
+	GT_CONFIG_WRITE(8, 0x06000011);
+
+	/* Allow the galileo to master the PCI bus */
+	GT_CONFIG_WRITE(PCI_COMMAND,
+			PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+			PCI_COMMAND_IO);
+
+
+#if 0
+        printk("Testing PCI DRAM - ");
+	if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) {
+		printk("Passed\n");
+	}else {
+		printk("FAILED\n");
+	}
+#endif
+	return 0;
+
+}
+
+
+#define SET_CONFIG_BITS(bus,devfn,where)\
+  ((1<<31) | ((bus) << 16) | ((devfn) << 8) | ((where) & ~3))
+
+#define CONFIG_CMD(dev, where) SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where)
+
+/* This write to the galileo config registers, unlike the functions below, can
+ * be used before the PCI subsystem has started up
+ */
+static int __init write_config_to_galileo(int where, u32 val)
+{
+	GT_WRITE(PCI_CFG_ADR, SET_CONFIG_BITS(0, 0, where));
+
+	GT_WRITE(PCI_CFG_DATA, val);
+	return 0;
+}
+
+/* We exclude the galileo and slot 31, the galileo because I don't know how to stop
+ * the setup code shagging up the setup I have done on it, and 31 because the whole
+ * thing locks up if you try to access that slot (which doesn't exist of course anyway
+ */
+
+#define EXCLUDED_DEV(dev) ((dev->bus->number==0) && ((PCI_SLOT(dev->devfn)==0) || (PCI_SLOT(dev->devfn) == 31)))
+
+static int galileo_read_config_byte(struct pci_dev *dev, int where,
+				    u8 * val)
+{
+
+        
+	/* I suspect this doesn't work because this drives a special cycle ? */
+	if (EXCLUDED_DEV(dev)) {
+		*val = 0xff;
+		return PCIBIOS_SUCCESSFUL;
+	}
+	/* Start the config cycle */
+	GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
+	/* Read back the result */
+	*val = GT_READ_BYTE(PCI_CFG_DATA + (where & 3));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int galileo_read_config_word(struct pci_dev *dev, int where,
+				    u16 * val)
+{
+
+        if (EXCLUDED_DEV(dev)) {
+		*val = 0xffff;
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
+	*val = GT_READ_SHORT(PCI_CFG_DATA + (where & 2));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int galileo_read_config_dword(struct pci_dev *dev, int where,
+				     u32 * val)
+{
+	if (EXCLUDED_DEV(dev)) {
+		*val = 0xffffffff;
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
+	*val = GT_READ(PCI_CFG_DATA);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_write_config_byte(struct pci_dev *dev, int where,
+				     u8 val)
+{
+	GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
+
+	GT_WRITE_BYTE(PCI_CFG_DATA + (where & 3), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int galileo_write_config_word(struct pci_dev *dev, int where,
+				     u16 val)
+{
+	GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
+
+	GT_WRITE_SHORT(PCI_CFG_DATA + (where & 2), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_write_config_dword(struct pci_dev *dev, int where,
+				      u32 val)
+{
+	GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
+
+	GT_WRITE(PCI_CFG_DATA, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_config_ops = {
+	galileo_read_config_byte,
+	galileo_read_config_word,
+	galileo_read_config_dword,
+	galileo_write_config_byte,
+	galileo_write_config_word,
+	galileo_write_config_dword
+};
+
+
+/* Everything hangs off this */
+static struct pci_bus *pci_root_bus;
+
+
+static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
+{
+	return PCI_SLOT(dev->devfn);
+}
+
+static int __init map_od_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/* Slot 1: Galileo 
+	 * Slot 2: PCI Slot 1
+	 * Slot 3: PCI Slot 2
+	 * Slot 4: ESS
+	 */
+	switch (slot) {
+	case 2: 
+		return OVERDRIVE_PCI_IRQ1;
+	case 3:
+		/* Note this assumes you have a hacked card in slot 2 */
+		return OVERDRIVE_PCI_IRQ2;
+	case 4:
+		return OVERDRIVE_ESS_IRQ;
+	default:
+		/* printk("PCI: Unexpected IRQ mapping request for slot %d\n", slot); */
+		return -1;
+	}
+}
+
+
+
+void __init
+pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
+{
+        ranges->io_start -= bus->resource[0]->start;
+        ranges->io_end -= bus->resource[0]->start;
+        ranges->mem_start -= bus->resource[1]->start;
+        ranges->mem_end -= bus->resource[1]->start;
+}                                                                                
+
+static void __init pci_fixup_ide_bases(struct pci_dev *d)
+{
+	int i;
+
+	/*
+	 * PCI IDE controllers use non-standard I/O port decoding, respect it.
+	 */
+	if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
+		return;
+	printk("PCI: IDE base address fixup for %s\n", d->slot_name);
+	for(i=0; i<4; i++) {
+		struct resource *r = &d->resource[i];
+		if ((r->start & ~0x80) == 0x374) {
+			r->start |= 2;
+			r->end = r->start;
+		}
+	}
+}
+
+
+/* Add future fixups here... */
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,	PCI_ANY_ID,	pci_fixup_ide_bases },
+	{ 0 }
+};
+
+void __init pcibios_init(void)
+{
+	static struct resource galio,galmem;
+
+        /* Allocate the registers used by the Galileo */
+        galio.flags = IORESOURCE_IO;
+        galio.name  = "Galileo GT64011";
+        galmem.flags = IORESOURCE_MEM|IORESOURCE_PREFETCH;
+        galmem.name  = "Galileo GT64011 DRAM";
+
+        allocate_resource(&ioport_resource, &galio, 256,
+		    GT64111_IO_BASE_ADDRESS,GT64111_IO_BASE_ADDRESS+256, 256, NULL, NULL);
+        allocate_resource(&iomem_resource, &galmem,PCI_DRAM_SIZE,
+		    PHYSADDR(PCI_DRAM_BASE), PHYSADDR(PCI_DRAM_BASE)+PCI_DRAM_SIZE, 
+			     PCI_DRAM_SIZE, NULL, NULL);
+
+  	/* ok, do the scan man */
+	pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
+
+        pci_assign_unassigned_resources();
+	pci_fixup_irqs(no_swizzle, map_od_irq);
+
+#ifdef TEST_DRAM
+        printk("Testing PCI DRAM - ");
+	if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) {
+		printk("Passed\n");
+	}else {
+		printk("FAILED\n");
+	}
+#endif
+
+}
+
+char * __init pcibios_setup(char *str)
+{
+	return str;
+}
+
+
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for (idx = 0; idx < 6; idx++) {
+		r = dev->resource + idx;
+		if (!r->start && r->end) {
+			printk(KERN_ERR
+			       "PCI: Device %s not available because"
+			       " of resource collisions\n",
+			       dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (cmd != old_cmd) {
+		printk("PCI: enabling device %s (%04x -> %04x)\n",
+		       dev->slot_name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+
+}
+
+/* We should do some optimisation work here I think. Ok for now though */
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+
+}
+
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size)
+{
+}
+
+void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			     struct resource *res, int resource)
+{
+
+	unsigned long where, size;
+	u32 reg;
+	
+
+	printk("PCI: Assigning %3s %08lx to %s\n",
+	       res->flags & IORESOURCE_IO ? "IO" : "MEM",
+	       res->start, dev->name);
+
+	where = PCI_BASE_ADDRESS_0 + resource * 4;
+	size = res->end - res->start;
+
+	pci_read_config_dword(dev, where, &reg);
+	reg = (reg & size) | (((u32) (res->start - root->start)) & ~size);
+	pci_write_config_dword(dev, where, reg);
+}
+
+
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+	printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name);
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+/*
+ *  If we set up a device for bus mastering, we need to check the latency
+ *  timer as certain crappy BIOSes forget to set it properly.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/overdrive/gt64111.h linux-2.4.22-pre10/arch/sh/overdrive/gt64111.h
--- linux-2.4.21/arch/sh/overdrive/gt64111.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/overdrive/gt64111.h	2003-08-01 13:33:14.000000000 +0000
@@ -0,0 +1,109 @@
+#ifndef _GT64111_H_
+#define _GT64111_H_
+
+#define MASTER_INTERFACE         0x0
+#define RAS10_LO_DEC_ADR         0x8        
+#define RAS10_HI_DEC_ADR         0x10
+#define RAS32_LO_DEC_ADR         0x18
+#define RAS32_HI_DEC_ADR         0x20
+#define CS20_LO_DEC_ADR          0x28
+#define CS20_HI_DEC_ADR          0x30
+#define CS3_LO_DEC_ADR           0x38
+#define CS3_HI_DEC_ADR           0x40
+#define PCI_IO_LO_DEC_ADR        0x48
+#define PCI_IO_HI_DEC_ADR        0x50
+#define PCI_MEM0_LO_DEC_ADR      0x58
+#define PCI_MEM0_HI_DEC_ADR      0x60
+#define INTERNAL_SPACE_DEC       0x68
+#define BUS_ERR_ADR_LO_CPU       0x70
+#define READONLY0                0x78
+#define PCI_MEM1_LO_DEC_ADR      0x80
+#define PCI_MEM1_HI_DEC_ADR      0x88
+#define RAS0_LO_DEC_ADR          0x400   
+#define RAS0_HI_DEC_ADR          0x404
+#define RAS1_LO_DEC_ADR          0x408
+#define RAS1_HI_DEC_ADR          0x40c
+#define RAS2_LO_DEC_ADR          0x410
+#define RAS2_HI_DEC_ADR          0x414
+#define RAS3_LO_DEC_ADR          0x418
+#define RAS3_HI_DEC_ADR          0x41c
+#define DEV_CS0_LO_DEC_ADR       0x420
+#define DEV_CS0_HI_DEC_ADR       0x424
+#define DEV_CS1_LO_DEC_ADR       0x428
+#define DEV_CS1_HI_DEC_ADR       0x42c
+#define DEV_CS2_LO_DEC_ADR       0x430
+#define DEV_CS2_HI_DEC_ADR       0x434
+#define DEV_CS3_LO_DEC_ADR       0x438
+#define DEV_CS3_HI_DEC_ADR       0x43c
+#define DEV_BOOTCS_LO_DEC_ADR    0x440
+#define DEV_BOOTCS_HI_DEC_ADR    0x444
+#define DEV_ADR_DEC_ERR          0x470
+#define DRAM_CFG                 0x448   
+#define DRAM_BANK0_PARMS         0x44c   
+#define DRAM_BANK1_PARMS         0x450
+#define DRAM_BANK2_PARMS         0x454
+#define DRAM_BANK3_PARMS         0x458
+#define DEV_BANK0_PARMS          0x45c
+#define DEV_BANK1_PARMS          0x460
+#define DEV_BANK2_PARMS          0x464
+#define DEV_BANK3_PARMS          0x468
+#define DEV_BOOT_BANK_PARMS      0x46c
+#define CH0_DMA_BYTECOUNT        0x800
+#define CH1_DMA_BYTECOUNT        0x804
+#define CH2_DMA_BYTECOUNT        0x808
+#define CH3_DMA_BYTECOUNT        0x80c
+#define CH0_DMA_SRC_ADR          0x810
+#define CH1_DMA_SRC_ADR          0x814
+#define CH2_DMA_SRC_ADR          0x818
+#define CH3_DMA_SRC_ADR          0x81c
+#define CH0_DMA_DST_ADR          0x820
+#define CH1_DMA_DST_ADR          0x824
+#define CH2_DMA_DST_ADR          0x828
+#define CH3_DMA_DST_ADR          0x82c
+#define CH0_NEXT_REC_PTR         0x830
+#define CH1_NEXT_REC_PTR         0x834
+#define CH2_NEXT_REC_PTR         0x838
+#define CH3_NEXT_REC_PTR         0x83c
+#define CH0_CTRL                 0x840
+#define CH1_CTRL                 0x844
+#define CH2_CTRL                 0x848
+#define CH3_CTRL                 0x84c
+#define DMA_ARBITER              0x860
+#define TIMER0                   0x850
+#define TIMER1                   0x854
+#define TIMER2                   0x858
+#define TIMER3                   0x85c
+#define TIMER_CTRL               0x864
+#define PCI_CMD                  0xc00
+#define PCI_TIMEOUT              0xc04
+#define PCI_RAS10_BANK_SIZE      0xc08
+#define PCI_RAS32_BANK_SIZE      0xc0c
+#define PCI_CS20_BANK_SIZE       0xc10
+#define PCI_CS3_BANK_SIZE        0xc14
+#define PCI_SERRMASK             0xc28
+#define PCI_INTACK               0xc34
+#define PCI_BAR_EN               0xc3c
+#define PCI_CFG_ADR              0xcf8
+#define PCI_CFG_DATA             0xcfc
+#define PCI_INTCAUSE             0xc18
+#define PCI_MAST_MASK            0xc1c
+#define PCI_PCIMASK              0xc24
+#define BAR_ENABLE_ADR           0xc3c
+
+/* These are config registers, accessible via PCI space */
+#define PCI_CONFIG_RAS10_BASE_ADR   0x010
+#define PCI_CONFIG_RAS32_BASE_ADR   0x014
+#define PCI_CONFIG_CS20_BASE_ADR    0x018
+#define PCI_CONFIG_CS3_BASE_ADR     0x01c
+#define PCI_CONFIG_INT_REG_MM_ADR   0x020
+#define PCI_CONFIG_INT_REG_IO_ADR   0x024
+#define PCI_CONFIG_BOARD_VENDOR     0x02c
+#define PCI_CONFIG_ROM_ADR          0x030
+#define PCI_CONFIG_INT_PIN_LINE     0x03c
+
+
+
+
+
+#endif
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/overdrive/io.c linux-2.4.22-pre10/arch/sh/overdrive/io.c
--- linux-2.4.21/arch/sh/overdrive/io.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/overdrive/io.c	2003-08-01 13:30:40.000000000 +0000
@@ -0,0 +1,173 @@
+/* 
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * This file contains the I/O routines for use on the overdrive board
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+
+#include "overdrive.h"
+
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the SuperH architecture, we just read/write the
+ * memory location directly.
+ */
+
+#define dprintk(x...)
+
+/* Translates an IO address to where it is mapped in memory */
+
+#define io_addr(x) (((unsigned)(x))|PCI_GTIO_BASE)
+
+unsigned char od_inb(unsigned long port)
+{
+dprintk("od_inb(%x)\n", port);
+	return readb(io_addr(port)) & 0xff;
+}
+
+
+unsigned short od_inw(unsigned long port)
+{
+dprintk("od_inw(%x)\n", port);
+	return readw(io_addr(port)) & 0xffff;
+}
+
+unsigned int od_inl(unsigned long port)
+{
+dprintk("od_inl(%x)\n", port);
+	return readl(io_addr(port));
+}
+
+void od_outb(unsigned char value, unsigned long port)
+{
+dprintk("od_outb(%x, %x)\n", value, port);
+	writeb(value, io_addr(port));
+}
+
+void od_outw(unsigned short value, unsigned long port)
+{
+dprintk("od_outw(%x, %x)\n", value, port);
+	writew(value, io_addr(port));
+}
+
+void od_outl(unsigned int value, unsigned long port)
+{
+dprintk("od_outl(%x, %x)\n", value, port);
+	writel(value, io_addr(port));
+}
+
+/* This is horrible at the moment - needs more work to do something sensible */
+#define IO_DELAY() udelay(10)
+
+#define OUT_DELAY(x,type) \
+void od_out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();}
+
+#define IN_DELAY(x,type) \
+unsigned type od_in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;}
+
+
+OUT_DELAY(b,char)
+OUT_DELAY(w,short)
+OUT_DELAY(l,int)
+
+IN_DELAY(b,char)
+IN_DELAY(w,short)
+IN_DELAY(l,int)
+
+
+/*  Now for the string version of these functions */
+void od_outsb(unsigned long port, const void *addr, unsigned long count)
+{
+	int i;
+	unsigned char *p = (unsigned char *) addr;
+
+	for (i = 0; i < count; i++, p++) {
+		outb(*p, port);
+	}
+}
+
+
+void od_insb(unsigned long port, void *addr, unsigned long count)
+{
+	int i;
+	unsigned char *p = (unsigned char *) addr;
+
+	for (i = 0; i < count; i++, p++) {
+		*p = inb(port);
+	}
+}
+
+/* For the 16 and 32 bit string functions, we have to worry about alignment.
+ * The SH does not do unaligned accesses, so we have to read as bytes and
+ * then write as a word or dword. 
+ * This can be optimised a lot more, especially in the case where the data
+ * is aligned
+ */
+
+void od_outsw(unsigned long port, const void *addr, unsigned long count)
+{
+	int i;
+	unsigned short tmp;
+	unsigned char *p = (unsigned char *) addr;
+
+	for (i = 0; i < count; i++, p += 2) {
+		tmp = (*p) | ((*(p + 1)) << 8);
+		outw(tmp, port);
+	}
+}
+
+
+void od_insw(unsigned long port, void *addr, unsigned long count)
+{
+	int i;
+	unsigned short tmp;
+	unsigned char *p = (unsigned char *) addr;
+
+	for (i = 0; i < count; i++, p += 2) {
+		tmp = inw(port);
+		p[0] = tmp & 0xff;
+		p[1] = (tmp >> 8) & 0xff;
+	}
+}
+
+
+void od_outsl(unsigned long port, const void *addr, unsigned long count)
+{
+	int i;
+	unsigned tmp;
+	unsigned char *p = (unsigned char *) addr;
+
+	for (i = 0; i < count; i++, p += 4) {
+		tmp = (*p) | ((*(p + 1)) << 8) | ((*(p + 2)) << 16) |
+		      ((*(p + 3)) << 24);
+		outl(tmp, port);
+	}
+}
+
+
+void od_insl(unsigned long port, void *addr, unsigned long count)
+{
+	int i;
+	unsigned tmp;
+	unsigned char *p = (unsigned char *) addr;
+
+	for (i = 0; i < count; i++, p += 4) {
+		tmp = inl(port);
+		p[0] = tmp & 0xff;
+		p[1] = (tmp >> 8) & 0xff;
+		p[2] = (tmp >> 16) & 0xff;
+		p[3] = (tmp >> 24) & 0xff;
+
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/overdrive/io_od.h linux-2.4.22-pre10/arch/sh/overdrive/io_od.h
--- linux-2.4.21/arch/sh/overdrive/io_od.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/overdrive/io_od.h	2003-08-01 13:32:27.000000000 +0000
@@ -0,0 +1,77 @@
+/*
+ * include/asm-sh/io_od.h
+ *
+ * Copyright 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * IO functions for an STMicroelectronics Overdrive
+ */
+
+#ifndef _ASM_SH_IO_OD_H
+#define _ASM_SH_IO_OD_H
+
+#include <asm/io_generic.h>
+
+extern unsigned char od_inb(unsigned long port);
+extern unsigned short od_inw(unsigned long port);
+extern unsigned int od_inl(unsigned long port);
+
+extern void od_outb(unsigned char value, unsigned long port);
+extern void od_outw(unsigned short value, unsigned long port);
+extern void od_outl(unsigned int value, unsigned long port);
+
+extern unsigned char od_inb_p(unsigned long port);
+extern unsigned short od_inw_p(unsigned long port);
+extern unsigned int od_inl_p(unsigned long port);
+extern void od_outb_p(unsigned char value, unsigned long port);
+extern void od_outw_p(unsigned short value, unsigned long port);
+extern void od_outl_p(unsigned int value, unsigned long port);
+
+extern void od_insb(unsigned long port, void *addr, unsigned long count);
+extern void od_insw(unsigned long port, void *addr, unsigned long count);
+extern void od_insl(unsigned long port, void *addr, unsigned long count);
+extern void od_outsb(unsigned long port, const void *addr, unsigned long count);
+extern void od_outsw(unsigned long port, const void *addr, unsigned long count);
+extern void od_outsl(unsigned long port, const void *addr, unsigned long count);
+
+extern unsigned long od_isa_port2addr(unsigned long offset);
+
+#ifdef __WANT_IO_DEF
+
+# define __inb			od_inb
+# define __inw			od_inw
+# define __inl			od_inl
+# define __outb			od_outb
+# define __outw			od_outw
+# define __outl			od_outl
+
+# define __inb_p		od_inb_p
+# define __inw_p		od_inw_p
+# define __inl_p		od_inl_p
+# define __outb_p		od_outb_p
+# define __outw_p		od_outw_p
+# define __outl_p		od_outl_p
+
+# define __insb			od_insb
+# define __insw			od_insw
+# define __insl			od_insl
+# define __outsb		od_outsb
+# define __outsw		od_outsw
+# define __outsl		od_outsl
+
+# define __readb		generic_readb
+# define __readw		generic_readw
+# define __readl		generic_readl
+# define __writeb		generic_writeb
+# define __writew		generic_writew
+# define __writel		generic_writel
+
+# define __isa_port2addr	od_isa_port2addr
+# define __ioremap		generic_ioremap
+# define __iounmap		generic_iounmap
+
+#endif
+
+#endif /* _ASM_SH_IO_OD_H */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/overdrive/irq.c linux-2.4.22-pre10/arch/sh/overdrive/irq.c
--- linux-2.4.21/arch/sh/overdrive/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/overdrive/irq.c	2003-08-01 13:33:42.000000000 +0000
@@ -0,0 +1,192 @@
+/* 
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * Looks after interrupts on the overdrive board.
+ *
+ * Bases on the IPR irq system
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+
+#include "overdrive.h"
+
+struct od_data {
+	int overdrive_irq;
+	int irq_mask;
+};
+
+#define NUM_EXTERNAL_IRQS 16
+#define EXTERNAL_IRQ_NOT_IN_USE (-1)
+#define EXTERNAL_IRQ_NOT_ASSIGNED (-1)
+
+/*
+ * This table is used to determine what to program into the FPGA's CT register
+ * for the specified Linux IRQ.
+ *
+ * The irq_mask gives the interrupt number from the PCI board (PCI_Int(6:0))
+ * but is one greater than that because the because the FPGA treats 0
+ * as disabled, a value of 1 asserts PCI_Int0, and so on.
+ *
+ * The overdrive_irq specifies which of the eight interrupt sources generates
+ * that interrupt, and but is multiplied by four to give the bit offset into
+ * the CT register.
+ *
+ * The seven interrupts levels (SH4 IRL's) we have available here is hardwired
+ * by the EPLD. The assignments here of which PCI interrupt generates each
+ * level is arbitary.
+ */
+static struct od_data od_data_table[NUM_EXTERNAL_IRQS] = {
+	/*    overdrive_irq       , irq_mask */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE},	/* 0 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, 7},	/* 1 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, 6},	/* 2 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE},	/* 3 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, 5},	/* 4 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE},	/* 5 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE},	/* 6 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, 4},	/* 7 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE},	/* 8 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE},	/* 9 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, 3},	/* 10 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, 2},	/* 11 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE},	/* 12 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, 1},	/* 13 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE},	/* 14 */
+	{EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}	/* 15 */
+};
+
+static void set_od_data(int overdrive_irq, int irq)
+{
+	if (irq >= NUM_EXTERNAL_IRQS || irq < 0)
+		return;
+	od_data_table[irq].overdrive_irq = overdrive_irq << 2;
+}
+
+static void enable_od_irq(unsigned int irq);
+void disable_od_irq(unsigned int irq);
+
+/* shutdown is same as "disable" */
+#define shutdown_od_irq disable_od_irq
+
+static void mask_and_ack_od(unsigned int);
+static void end_od_irq(unsigned int irq);
+
+static unsigned int startup_od_irq(unsigned int irq)
+{
+	enable_od_irq(irq);
+	return 0;		/* never anything pending */
+}
+
+static struct hw_interrupt_type od_irq_type = {
+	"Overdrive-IRQ",
+	startup_od_irq,
+	shutdown_od_irq,
+	enable_od_irq,
+	disable_od_irq,
+	mask_and_ack_od,
+	end_od_irq
+};
+
+static void disable_od_irq(unsigned int irq)
+{
+	unsigned val, flags;
+	int overdrive_irq;
+	unsigned mask;
+
+	/* Not a valid interrupt */
+	if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
+		return;
+
+        /* Is is necessary to use a cli here? Would a spinlock not be 
+         * mroe efficient?
+         */
+	save_and_cli(flags);
+	overdrive_irq = od_data_table[irq].overdrive_irq;
+	if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) {
+		mask = ~(0x7 << overdrive_irq);
+		val = ctrl_inl(OVERDRIVE_INT_CT);
+		val &= mask;
+		ctrl_outl(val, OVERDRIVE_INT_CT);
+	}
+	restore_flags(flags);
+}
+
+static void enable_od_irq(unsigned int irq)
+{
+	unsigned val, flags;
+	int overdrive_irq;
+	unsigned mask;
+
+	/* Not a valid interrupt */
+	if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
+		return;
+
+	/* Set priority in OD back to original value */
+	save_and_cli(flags);
+	/* This one is not in use currently */
+	overdrive_irq = od_data_table[irq].overdrive_irq;
+	if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) {
+		val = ctrl_inl(OVERDRIVE_INT_CT);
+		mask = ~(0x7 << overdrive_irq);
+		val &= mask;
+		mask = od_data_table[irq].irq_mask << overdrive_irq;
+		val |= mask;
+		ctrl_outl(val, OVERDRIVE_INT_CT);
+	}
+	restore_flags(flags);
+}
+
+
+
+/* this functions sets the desired irq handler to be an overdrive type */
+static void __init make_od_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+	irq_desc[irq].handler = &od_irq_type;
+	disable_od_irq(irq);
+}
+
+
+static void mask_and_ack_od(unsigned int irq)
+{
+	disable_od_irq(irq);
+}
+
+static void end_od_irq(unsigned int irq)
+{
+	enable_od_irq(irq);
+}
+
+void __init init_overdrive_irq(void)
+{
+	int i;
+
+	/* Disable all interrupts */
+	ctrl_outl(0, OVERDRIVE_INT_CT);
+
+	/* Update interrupt pin mode to use encoded interrupts */
+	i = ctrl_inw(INTC_ICR);
+	i &= ~INTC_ICR_IRLM;
+	ctrl_outw(i, INTC_ICR);
+
+	for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
+		if (od_data_table[i].irq_mask != EXTERNAL_IRQ_NOT_IN_USE) {
+			make_od_irq(i);
+		} else if (i != 15) {	// Cannot use imask on level 15
+			make_imask_irq(i);
+		}
+	}
+
+	/* Set up the interrupts */
+	set_od_data(OVERDRIVE_PCI_INTA, OVERDRIVE_PCI_IRQ1);
+	set_od_data(OVERDRIVE_PCI_INTB, OVERDRIVE_PCI_IRQ2);
+	set_od_data(OVERDRIVE_AUDIO_INT, OVERDRIVE_ESS_IRQ);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/overdrive/led.c linux-2.4.22-pre10/arch/sh/overdrive/led.c
--- linux-2.4.21/arch/sh/overdrive/led.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/overdrive/led.c	2003-08-01 13:33:35.000000000 +0000
@@ -0,0 +1,59 @@
+/*
+ * linux/arch/sh/overdrive/led.c
+ *
+ * Copyright (C) 1999 Stuart Menefy <stuart.menefy@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * This file contains an Overdrive specific LED feature.
+ */
+
+#include <linux/config.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include "overdrive.h"
+
+static void mach_led(int position, int value)
+{
+	unsigned long flags;
+	unsigned long reg;
+
+	save_and_cli(flags);
+	
+	reg = readl(OVERDRIVE_CTRL);
+	if (value) {
+		reg |= (1<<3);
+	} else {
+		reg &= ~(1<<3);
+	}
+	writel(reg, OVERDRIVE_CTRL);
+
+	restore_flags(flags);
+}
+
+#ifdef CONFIG_HEARTBEAT
+
+#include <linux/sched.h>
+
+/* acts like an actual heart beat -- ie thump-thump-pause... */
+void heartbeat_od(void)
+{
+	static unsigned cnt = 0, period = 0, dist = 0;
+
+	if (cnt == 0 || cnt == dist)
+		mach_led( -1, 1);
+	else if (cnt == 7 || cnt == dist+7)
+		mach_led( -1, 0);
+
+	if (++cnt > period) {
+		cnt = 0;
+		/* The hyperbolic function below modifies the heartbeat period
+		 * length in dependency of the current (5min) load. It goes
+		 * through the points f(0)=126, f(1)=86, f(5)=51,
+		 * f(inf)->30. */
+		period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+		dist = period / 4;
+	}
+}
+#endif /* CONFIG_HEARTBEAT */
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/overdrive/mach.c linux-2.4.22-pre10/arch/sh/overdrive/mach.c
--- linux-2.4.21/arch/sh/overdrive/mach.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/overdrive/mach.c	2003-08-01 13:31:00.000000000 +0000
@@ -0,0 +1,80 @@
+/*
+ * linux/arch/sh/overdrive/mach.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Machine vector for the STMicroelectronics Overdrive
+ */
+
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+#include <asm/rtc.h>
+#include <asm/machvec_init.h>
+
+#include <asm/io_unknown.h>
+#include <asm/io_generic.h>
+#include <asm/io_od.h>
+
+void heartbeat_od(void);
+void setup_od(void);
+void init_overdrive_irq(void);
+void galileo_pcibios_init(void);
+
+/*
+ * The Machine Vector
+ */
+
+struct sh_machine_vector mv_od __initmv = {
+	mv_name:		"SH7750 Overdrive",
+
+	mv_nr_irqs:		48,
+
+	mv_inb:			od_inb,
+	mv_inw:			od_inw,
+	mv_inl:			od_inl,
+	mv_outb:		od_outb,
+	mv_outw:		od_outw,
+	mv_outl:		od_outl,
+
+	mv_inb_p:		od_inb_p,
+	mv_inw_p:		od_inw_p,
+	mv_inl_p:		od_inl_p,
+	mv_outb_p:		od_outb_p,
+	mv_outw_p:		od_outw_p,
+	mv_outl_p:		od_outl_p,
+
+	mv_insb:		od_insb,
+	mv_insw:		od_insw,
+	mv_insl:		od_insl,
+	mv_outsb:		od_outsb,
+	mv_outsw:		od_outsw,
+	mv_outsl:		od_outsl,
+
+	mv_readb:		generic_readb,
+	mv_readw:		generic_readw,
+	mv_readl:		generic_readl,
+	mv_writeb:		generic_writeb,
+	mv_writew:		generic_writew,
+	mv_writel:		generic_writel,
+
+	mv_ioremap:		generic_ioremap,
+	mv_iounmap:		generic_iounmap,
+
+	mv_isa_port2addr:	generic_isa_port2addr,
+
+	mv_init_arch:		setup_od,
+#ifdef CONFIG_PCI
+	mv_init_irq:		init_overdrive_irq,
+#endif
+#ifdef CONFIG_HEARTBEAT
+	mv_heartbeat:		heartbeat_od,
+#endif
+	mv_rtc_gettimeofday:	sh_rtc_gettimeofday,
+	mv_rtc_settimeofday:	sh_rtc_settimeofday,
+};
+
+ALIAS_MV(od)
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/overdrive/overdrive.h linux-2.4.22-pre10/arch/sh/overdrive/overdrive.h
--- linux-2.4.21/arch/sh/overdrive/overdrive.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/overdrive/overdrive.h	2003-08-01 13:31:26.000000000 +0000
@@ -0,0 +1,89 @@
+/* 
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ */
+
+#include <linux/config.h>
+
+#ifndef __OVERDRIVE_H__
+#define __OVERDRIVE_H__
+
+#define OVERDRIVE_INT_CT 0xa3a00000
+#define OVERDRIVE_INT_DT 0xa3b00000
+
+#define OVERDRIVE_CTRL    0xa3000000
+
+/* Shoving all these bits into the same register is not a good idea. 
+ * As soon as I get a spare moment, I'll change the FPGA and put each 
+ * bit in a separate register
+ */
+
+#define VALID_CTRL_BITS		          0x1f
+
+#define ENABLE_RS232_MASK	  	  0x1e
+#define DISABLE_RS232_BIT		  0x01
+
+#define ENABLE_NMI_MASK			  0x1d
+#define DISABLE_NMI_BIT			  0x02
+
+#define RESET_PCI_MASK			  0x1b
+#define ENABLE_PCI_BIT			  0x04
+
+#define ENABLE_LED_MASK			  0x17
+#define DISABLE_LED_BIT			  0x08
+
+#define RESET_FPGA_MASK			  0x0f
+#define ENABLE_FPGA_BIT			  0x10
+
+
+#define FPGA_DCLK_ADDRESS           0xA3C00000
+
+#define FPGA_DATA        0x01	/*   W */
+#define FPGA_CONFDONE    0x02	/* R   */
+#define FPGA_NOT_STATUS  0x04	/* R   */
+#define FPGA_INITDONE    0x08	/* R   */
+
+#define FPGA_TIMEOUT     100000
+
+
+/* Interrupts for the overdrive. Note that these numbers have 
+ * nothing to do with the actual IRQ numbers they appear on, 
+ * this is all programmable. This is simply the position in the 
+ * INT_CT register.
+ */
+
+#define OVERDRIVE_PCI_INTA              0
+#define OVERDRIVE_PCI_INTB              1
+#define OVERDRIVE_PCI_INTC              2
+#define OVERDRIVE_PCI_INTD              3
+#define OVERDRIVE_GALILEO_INT           4
+#define OVERDRIVE_GALILEO_LOCAL_INT     5
+#define OVERDRIVE_AUDIO_INT             6
+#define OVERDRIVE_KEYBOARD_INT          7
+
+/* Which Linux IRQ should we assign to each interrupt source? */
+#define OVERDRIVE_PCI_IRQ1              2
+#ifdef CONFIG_HACKED_NE2K
+#define OVERDRIVE_PCI_IRQ2              7
+#else
+#define OVERDRIVE_PCI_IRQ2              2
+#undef OVERDRIVE_PCI_INTB 
+#define OVERDRIVE_PCI_INTB OVERDRIVE_PCI_INTA
+
+#endif
+
+/* Put the ESS solo audio chip on IRQ 4 */
+#define OVERDRIVE_ESS_IRQ               4
+
+/* Where the memory behind the PCI bus appears */
+#define PCI_DRAM_BASE   0xb7000000
+#define PCI_DRAM_SIZE (16*1024*1024)
+#define PCI_DRAM_FINISH (PCI_DRAM_BASE+PCI_DRAM_SIZE-1)
+
+/* Where the IO region appears in the memory */
+#define PCI_GTIO_BASE   0xb8000000
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/overdrive/pcidma.c linux-2.4.22-pre10/arch/sh/overdrive/pcidma.c
--- linux-2.4.21/arch/sh/overdrive/pcidma.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/overdrive/pcidma.c	2003-08-01 13:34:22.000000000 +0000
@@ -0,0 +1,46 @@
+/* 
+ * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * Dynamic DMA mapping support.
+ *
+ * On the overdrive, we can only DMA from memory behind the PCI bus!
+ * this means that all DMA'able memory must come from there. 
+ * this restriction will not apply to later boards.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+			   dma_addr_t * dma_handle)
+{
+	void *ret;
+	int gfp = GFP_ATOMIC;
+
+        printk("BUG: pci_alloc_consistent() called - not yet supported\n");
+	/* We ALWAYS need DMA memory on the overdrive hardware,
+	 * due to it's extreme wierdness
+	 * Need to flush the cache here as well, since the memory
+	 * can still be seen through the cache!
+	 */
+	gfp |= GFP_DMA;
+	ret = (void *) __get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_bus(ret);
+	}
+	return ret;
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	free_pages((unsigned long) vaddr, get_order(size));
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/overdrive/setup.c linux-2.4.22-pre10/arch/sh/overdrive/setup.c
--- linux-2.4.21/arch/sh/overdrive/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/overdrive/setup.c	2003-08-01 13:31:06.000000000 +0000
@@ -0,0 +1,32 @@
+/*
+ * arch/sh/overdrive/setup.c
+ *
+ * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * STMicroelectronics Overdrive Support.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+#include "overdrive.h"
+#include "fpga.h"
+
+/*
+ * Initialize the board
+ */
+int __init setup_od(void)
+{
+#ifdef CONFIG_PCI
+	init_overdrive_fpga();
+	galileo_init(); 
+#endif
+
+        /* Enable RS232 receive buffers */
+	writel(0x1e, OVERDRIVE_CTRL);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh/stboards/setup.c linux-2.4.22-pre10/arch/sh/stboards/setup.c
--- linux-2.4.21/arch/sh/stboards/setup.c	2001-06-27 20:55:29.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh/stboards/setup.c	2003-08-01 13:31:57.000000000 +0000
@@ -48,3 +48,31 @@
 
 	return 0;
 }
+
+#ifdef CONFIG_PCI
+/*
+ * PCI based boards need a function that maps IRQ's to given PCI
+ * slots. This code is used by the st40 pci routines in arch/sh/kernel
+ */
+ 
+int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+    	switch (slot) {
+#ifdef CONFIG_SH_STB1_HARP
+	case 2:		/*This is the PCI slot on the */
+		return HARP_PCI_IRQ;
+	case 1:		/* this is the bridge */
+		return HARP_BRIDGE_IRQ;
+#elif defined(CONFIG_SH_STB1_OVERDRIVE)
+	case 1:
+	case 2:
+	case 3:
+		return slot - 1;
+#else
+#error Unknown board
+#endif
+	default:
+		return -1;
+	}
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/Makefile linux-2.4.22-pre10/arch/sh64/Makefile
--- linux-2.4.21/arch/sh64/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/Makefile	2003-08-01 13:31:50.000000000 +0000
@@ -0,0 +1,91 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2000, 2001  Paolo Alberelli
+# Copyright (C) 2003  Paul Mundt
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# Note that top level Makefile automagically builds dependencies for SUBDIRS
+# but does not automagically clean SUBDIRS. Therefore "archclean" should clean
+# up all, "archdep" does nothing on added SUBDIRS.
+#
+
+cpu-y				:= -mb
+cpu-$(CONFIG_LITTLE_ENDIAN)	:= -ml
+
+cpu-$(CONFIG_CPU_SH5)		+= -m5-32media-nofpu
+
+ifdef CONFIG_LITTLE_ENDIAN
+LDFLAGS		+= -EL  -mshlelf32_linux
+else
+LDFLAGS		+= -EB  -mshelf32_linux
+endif
+
+# No requirements for endianess support from AFLAGS, 'as' always run through gcc
+AFLAGS		+= -m5 -isa=sh64 -traditional
+CFLAGS		+= $(cpu-y)
+
+ENTRY_POINT	= --defsym phys_stext=_stext-0x$(CONFIG_CACHED_MEMORY_OFFSET) \
+		  -e phys_stext
+OBJCOPY		= $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment \
+		  -R .stab -R .stabstr -S
+LD		= $(CROSS_COMPILE)ld $(LDFLAGS)
+
+LINKFLAGS     += -T arch/$(ARCH)/vmlinux.lds  $(ENTRY_POINT)
+
+ifdef LOADADDR
+LINKFLAGS     += -Ttext $(word 1,$(LOADADDR))
+endif
+
+machine-$(CONFIG_SH_CAYMAN)	:= cayman
+machine-$(CONFIG_SH_SIMULATOR)	:= sim
+machine-$(CONFIG_SH_HARP)	:= harp
+
+HEAD := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o
+MAKEROOTFS =
+
+SUBDIRS += $(addprefix arch/$(ARCH)/, kernel mm lib mach-$(machine-y))
+CORE_FILES := arch/$(ARCH)/kernel/kernel.o arch/$(ARCH)/mm/mm.o \
+	      arch/$(ARCH)/mach-$(machine-y)/$(machine-y).o \
+	      $(CORE_FILES) 
+
+LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+LIBS := $(TOPDIR)/arch/$(ARCH)/lib/lib.a $(LIBS) $(LIBGCC)
+
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
+#
+# override the assembly rules
+#
+#.S.o:
+#	$(CC) $(CFLAGS) $(AFLAGS) -c $< -o $*.o
+
+vmlinux: arch/$(ARCH)/vmlinux.lds
+
+arch/$(ARCH)/vmlinux.lds: arch/$(ARCH)/vmlinux.lds.S FORCE
+	$(CPP) $(TOOLCHAIN) $(AFLAGS) -C -P -I$(HPATH) -U$(ARCH) arch/$(ARCH)/vmlinux.lds.S >arch/$(ARCH)/vmlinux.lds
+
+FORCE: ;
+
+zImage: vmlinux
+	@$(MAKEBOOT) zImage
+
+compressed: zImage
+
+zdisk: vmlinux
+	@$(MAKEBOOT) zdisk
+
+archclean:
+#	@$(MAKEBOOT) clean
+
+archmrproper:
+	rm -f arch/$(ARCH)/vmlinux.lds
+
+archdep:
+#	@$(MAKEBOOT) dep
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/boot/Makefile linux-2.4.22-pre10/arch/sh64/boot/Makefile
--- linux-2.4.21/arch/sh64/boot/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/boot/Makefile	2003-08-01 13:33:13.000000000 +0000
@@ -0,0 +1,34 @@
+#
+# arch/shmedia/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002 Stuart Menefy
+#
+
+SYSTEM  =$(TOPDIR)/vmlinux
+
+Image:	$(CONFIGURE) $(SYSTEM)
+	$(OBJCOPY) $(SYSTEM) Image
+
+zImage: $(CONFIGURE) compressed/vmlinux
+	$(OBJCOPY) compressed/vmlinux zImage
+
+compressed/vmlinux: $(TOPDIR)/vmlinux
+	$(MAKE) -C compressed vmlinux
+
+install: $(CONFIGURE) Image
+	sh -x ./install.sh $(KERNELRELEASE) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
+
+zinstall: $(CONFIGURE) zImage
+	sh -x ./install.sh $(KERNELRELEASE) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
+
+dep:
+
+clean:
+	rm -f tools/build
+	rm -f setup bootsect zImage compressed/vmlinux.out
+	rm -f bsetup bbootsect bzImage compressed/bvmlinux.out
+	@$(MAKE) -C compressed clean
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/boot/compressed/Makefile linux-2.4.22-pre10/arch/sh64/boot/compressed/Makefile
--- linux-2.4.21/arch/sh64/boot/compressed/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/boot/compressed/Makefile	2003-08-01 13:31:30.000000000 +0000
@@ -0,0 +1,57 @@
+#
+# linux/arch/shmedia/boot/compressed/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2002 Stuart Menefy
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+
+# This is a temporary work around for a problem with the Linux ld.
+# We can't use the Linux linker, because it doesn't work with binary
+# files, so we use the bard machine linker instead...
+PIGGYLD=sh64-superh-elf-ld -EL # -m shlelf64
+# ...which has the knock on that we need this when doing the final link.
+EXTRAFLAGS=--no-warn-mismatch
+
+HEAD = head.o
+SYSTEM = $(TOPDIR)/vmlinux
+
+OBJECTS = $(HEAD) misc.o cache.o
+
+ZLDFLAGS = -e startup -T vmlinux.lds
+
+#
+# ZIMAGE_OFFSET is the load offset of the compression loader
+# (4M for the kernel plus 64K for this loader)
+#
+ZIMAGE_OFFSET = $(shell printf "0x%8x" $$[0x$(CONFIG_MEMORY_START)+0x400000+0x10000])
+
+ZLINKFLAGS = -Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS)
+
+all: vmlinux
+
+vmlinux.lds: vmlinux.lds.S
+	$(CPP) -traditional -C -P -I$(HPATH) -Ush vmlinux.lds.S >vmlinux.lds
+
+vmlinux: piggy.o $(OBJECTS) vmlinux.lds
+	$(LD) $(ZLINKFLAGS) $(EXTRAFLAGS) -o vmlinux $(OBJECTS) piggy.o
+
+head.o: head.S
+	$(CC) $(AFLAGS) -traditional -c head.S
+
+piggy.o:	$(SYSTEM)
+	tmppiggy=_tmp_$$$$piggy; \
+	rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \
+	$(OBJCOPY) -R .empty_zero_page $(SYSTEM) $$tmppiggy; \
+	gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
+	echo "SECTIONS { .image : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
+	$(PIGGYLD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-sh64 -T $$tmppiggy.lnk; \
+	rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
+
+clean:
+	rm -f vmlinux _tmp_*
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/boot/compressed/cache.c linux-2.4.22-pre10/arch/sh64/boot/compressed/cache.c
--- linux-2.4.21/arch/sh64/boot/compressed/cache.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/boot/compressed/cache.c	2003-08-01 13:33:31.000000000 +0000
@@ -0,0 +1,39 @@
+/*
+ * arch/shmedia/boot/compressed/cache.c -- simple cache management functions
+ *
+ * Code extracted from sh-ipl+g, sh-stub.c, which has the copyright:
+ *
+ *   This is originally based on an m68k software stub written by Glenn
+ *   Engel at HP, but has changed quite a bit. 
+ *
+ *   Modifications for the SH by Ben Lee and Steve Chamberlain
+ *
+****************************************************************************
+
+		THIS SOFTWARE IS NOT COPYRIGHTED
+
+   HP offers the following for use in the public domain.  HP makes no
+   warranty with regard to the software or it's performance and the
+   user accepts the software "AS IS" with all faults.
+
+   HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+   TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+#define CACHE_ENABLE      0
+#define CACHE_DISABLE     1
+
+int cache_control(unsigned int command)
+{
+	volatile unsigned int *p = (volatile unsigned int *) 0x80000000;
+	int i;
+
+	for (i = 0; i < (32 * 1024); i += 32) {
+		(void *) *p;
+		p += (32 / sizeof (int));
+	}
+
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/boot/compressed/head.S linux-2.4.22-pre10/arch/sh64/boot/compressed/head.S
--- linux-2.4.21/arch/sh64/boot/compressed/head.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/boot/compressed/head.S	2003-08-01 13:31:50.000000000 +0000
@@ -0,0 +1,164 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/shmedia/boot/compressed/head.S
+ *
+ * Copied from
+ *   arch/shmedia/kernel/head.S
+ * which carried the copyright:
+ *   Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * Modification for compressed loader:
+ *   Copyright (C) 2002 Stuart Menefy (stuart.menefy@st.com)
+ */
+
+#include <linux/linkage.h>
+#include <asm/registers.h>
+#include <asm/cache.h>
+#include <asm/mmu_context.h>
+
+/*
+ * Fixed TLB entries to identity map the beginning of RAM
+ */
+#define MMUIR_TEXT_H	0x0000000000000003 | CONFIG_MEMORY_START
+			/* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
+#define MMUIR_TEXT_L	0x000000000000009a | CONFIG_MEMORY_START
+			/* 512 Mb, Cacheable (Write-back), execute, Not User, Ph. Add. */
+
+#define MMUDR_CACHED_H	0x0000000000000003 | CONFIG_MEMORY_START
+			/* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
+#define MMUDR_CACHED_L	0x000000000000015a | CONFIG_MEMORY_START
+			/* 512 Mb, Cacheable (Write-back), read/write, Not User, Ph. Add. */
+
+#define	ICCR0_INIT_VAL	ICCR0_ON | ICCR0_ICI		/* ICE + ICI */
+#define	ICCR1_INIT_VAL	ICCR1_NOLOCK			/* No locking */
+
+#if 1
+#define	OCCR0_INIT_VAL	OCCR0_ON | OCCR0_OCI | OCCR0_WB	/* OCE + OCI + WB */
+#else
+#define	OCCR0_INIT_VAL	OCCR0_OFF
+#endif
+#define	OCCR1_INIT_VAL	OCCR1_NOLOCK			/* No locking */
+	
+	.text
+
+	.global	startup
+startup:
+	/*
+	 * Prevent speculative fetch on device memory due to
+	 * uninitialized target registers.
+	 * This must be executed before the first branch.
+	 */
+	ptabs/u	ZERO, t0
+	ptabs/u	ZERO, t1
+	ptabs/u	ZERO, t2
+	ptabs/u	ZERO, t3
+	ptabs/u	ZERO, t4
+	ptabs/u	ZERO, t5
+	ptabs/u	ZERO, t6
+	ptabs/u	ZERO, t7
+	synci
+
+	/*
+	 * Set initial TLB entries for cached and uncached regions.
+	 * Note: PTA/BLINK is PIC code, PTABS/BLINK isn't !
+	 */
+	/* Clear ITLBs */
+	pta	1f, t1
+	movi	ITLB_FIXED, r21
+	movi	ITLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22
+1:	putcfg	r21, 0, ZERO		/* Clear MMUIR[n].PTEH.V */
+	addi	r21, TLB_STEP, r21
+        bne	r21, r22, t1
+
+	/* Clear DTLBs */
+	pta	1f, t1
+	movi	DTLB_FIXED, r21
+	movi	DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP, r22
+1:	putcfg	r21, 0, ZERO		/* Clear MMUDR[n].PTEH.V */
+	addi	r21, TLB_STEP, r21
+        bne	r21, r22, t1
+
+	/* Map one big (512Mb) page for ITLB */
+	movi	ITLB_FIXED, r21
+	movi	MMUIR_TEXT_L, r22	/* PTEL first */
+	putcfg	r21, 1, r22		/* Set MMUIR[0].PTEL */
+	movi	MMUIR_TEXT_H, r22	/* PTEH last */
+	putcfg	r21, 0, r22		/* Set MMUIR[0].PTEH */
+	
+	/* Map one big CACHED (512Mb) page for DTLB */
+	movi	DTLB_FIXED, r21
+	movi	MMUDR_CACHED_L, r22	/* PTEL first */
+	putcfg	r21, 1, r22		/* Set MMUDR[0].PTEL */
+	movi	MMUDR_CACHED_H, r22	/* PTEH last */
+	putcfg	r21, 0, r22		/* Set MMUDR[0].PTEH */
+
+	/* ICache */
+	movi	ICCR_BASE, r21
+	movi	ICCR0_INIT_VAL, r22
+	movi	ICCR1_INIT_VAL, r23
+	putcfg	r21, ICCR_REG0, r22
+	putcfg	r21, ICCR_REG1, r23
+	synci
+
+	/* OCache */
+	movi	OCCR_BASE, r21
+	movi	OCCR0_INIT_VAL, r22
+	movi	OCCR1_INIT_VAL, r23
+	putcfg	r21, OCCR_REG0, r22
+	putcfg	r21, OCCR_REG1, r23
+	synco
+	
+	/*
+	 * Enable the MMU.
+	 * From here-on code can be non-PIC.
+	 */
+	movi	SR_HARMLESS | SR_ENABLE_MMU, r22
+	putcon	r22, SSR
+	movi	1f, r22
+	putcon	r22, SPC
+	synco
+	rte				/* And now go into the hyperspace ... */
+1:					/* ... that's the next instruction ! */
+
+	/* Set initial stack pointer */
+	movi	datalabel stack_start, r0
+	ld.l	r0, 0, r15
+
+	/*
+	 * Clear bss
+	 */
+	pt	1f, tr1
+	movi	datalabel __bss_start, r22
+	movi	datalabel _end, r23
+1:	st.l	r22, 0, ZERO 
+	addi	r22, 4, r22
+	bne	r22, r23, tr1
+
+	/*
+	 * Decompress the kernel.
+	 */
+	pt	decompress_kernel, tr0
+	blink	tr0, r18
+
+	/*
+	 * Disable the MMU.
+	 */
+	movi	SR_HARMLESS, r22
+	putcon	r22, SSR
+	movi	1f, r22
+	putcon	r22, SPC
+	synco
+	rte				/* And now go into the hyperspace ... */
+1:					/* ... that's the next instruction ! */
+
+	/* Jump into the decompressed kernel */	
+	movi	datalabel (CONFIG_MEMORY_START + 0x2000)+1, r19
+	ptabs	r19, tr0
+	blink	tr0, r18
+
+	/* Shouldn't return here, but just in case, loop forever */
+	pt	1f, tr0
+1:	blink	tr0, ZERO
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/boot/compressed/install.sh linux-2.4.22-pre10/arch/sh64/boot/compressed/install.sh
--- linux-2.4.21/arch/sh64/boot/compressed/install.sh	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/boot/compressed/install.sh	2003-08-01 13:33:36.000000000 +0000
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# arch/sh/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+# Adapted from code in arch/i386/boot/install.sh by Russell King
+# Adapted from code in arch/arm/boot/install.sh by Stuart Menefy
+#
+# "make install" script for sh architecture
+#
+# Arguments:
+#   $1 - kernel version
+#   $2 - kernel image file
+#   $3 - kernel map file
+#   $4 - default install path (blank if root directory)
+#
+
+# User may have a custom install script
+
+if [ -x /sbin/installkernel ]; then
+  exec /sbin/installkernel "$@"
+fi
+
+if [ "$2" = "zImage" ]; then
+# Compressed install
+  echo "Installing compressed kernel"
+  if [ -f $4/vmlinuz-$1 ]; then
+    mv $4/vmlinuz-$1 $4/vmlinuz.old
+  fi
+
+  if [ -f $4/System.map-$1 ]; then
+    mv $4/System.map-$1 $4/System.old
+  fi
+
+  cat $2 > $4/vmlinuz-$1
+  cp $3 $4/System.map-$1
+else
+# Normal install
+  echo "Installing normal kernel"
+  if [ -f $4/vmlinux-$1 ]; then
+    mv $4/vmlinux-$1 $4/vmlinux.old
+  fi
+
+  if [ -f $4/System.map ]; then
+    mv $4/System.map $4/System.old
+  fi
+
+  cat $2 > $4/vmlinux-$1
+  cp $3 $4/System.map
+fi
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/boot/compressed/misc.c linux-2.4.22-pre10/arch/sh64/boot/compressed/misc.c
--- linux-2.4.21/arch/sh64/boot/compressed/misc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/boot/compressed/misc.c	2003-08-01 13:30:53.000000000 +0000
@@ -0,0 +1,251 @@
+/*
+ * arch/shmedia/boot/compressed/misc.c
+ * 
+ * This is a collection of several routines from gzip-1.0.3 
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for SHmedia from sh by Stuart Menefy, May 2002
+ */
+
+#include <linux/config.h>
+#include <asm/uaccess.h>
+
+/* cache.c */
+#define CACHE_ENABLE      0
+#define CACHE_DISABLE     1
+int cache_control(unsigned int command);
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n)     memset ((s), 0, (n))
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+#define WSIZE 0x8000		/* Window size must be at least 32k, */
+				/* and a power of two */
+
+static uch *inbuf;		/* input buffer */
+static uch window[WSIZE];	/* Sliding window buffer */
+
+static unsigned insize = 0;	/* valid bytes in inbuf */
+static unsigned inptr = 0;	/* index of next byte to be processed in inbuf */
+static unsigned outcnt = 0;	/* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01	/* bit 0 set: file probably ASCII text */
+#define CONTINUATION 0x02	/* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04	/* bit 2 set: extra field present */
+#define ORIG_NAME    0x08	/* bit 3 set: original file name present */
+#define COMMENT      0x10	/* bit 4 set: file comment present */
+#define ENCRYPTED    0x20	/* bit 5 set: file is encrypted */
+#define RESERVED     0xC0	/* bit 6,7:   reserved */
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) {if(!(cond)) error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+static int fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+extern char input_data[];
+extern int input_len;
+
+static long bytes_out = 0;
+static uch *output_data;
+static unsigned long output_ptr = 0;
+
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+static void puts(const char *);
+
+extern int _text;		/* Defined in vmlinux.lds.S */
+extern int _end;
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#define HEAP_SIZE             0x10000
+
+#include "../../../../lib/inflate.c"
+
+static void *malloc(int size)
+{
+	void *p;
+
+	if (size < 0)
+		error("Malloc error\n");
+	if (free_mem_ptr == 0)
+		error("Memory error\n");
+
+	free_mem_ptr = (free_mem_ptr + 3) & ~3;	/* Align */
+
+	p = (void *) free_mem_ptr;
+	free_mem_ptr += size;
+
+	if (free_mem_ptr >= free_mem_end_ptr)
+		error("\nOut of memory\n");
+
+	return p;
+}
+
+static void free(void *where)
+{				/* Don't care */
+}
+
+static void gzip_mark(void **ptr)
+{
+	*ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+	free_mem_ptr = (long) *ptr;
+}
+
+void puts(const char *s)
+{
+}
+
+void *memset(void *s, int c, size_t n)
+{
+	int i;
+	char *ss = (char *) s;
+
+	for (i = 0; i < n; i++)
+		ss[i] = c;
+	return s;
+}
+
+void *memcpy(void *__dest, __const void *__src, size_t __n)
+{
+	int i;
+	char *d = (char *) __dest, *s = (char *) __src;
+
+	for (i = 0; i < __n; i++)
+		d[i] = s[i];
+	return __dest;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf(void)
+{
+	if (insize != 0) {
+		error("ran out of input data\n");
+	}
+
+	inbuf = input_data;
+	insize = input_len;
+	inptr = 1;
+	return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window(void)
+{
+	ulg c = crc;		/* temporary variable */
+	unsigned n;
+	uch *in, *out, ch;
+
+	in = window;
+	out = &output_data[output_ptr];
+	for (n = 0; n < outcnt; n++) {
+		ch = *out++ = *in++;
+		c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
+	}
+	crc = c;
+	bytes_out += (ulg) outcnt;
+	output_ptr += (ulg) outcnt;
+	outcnt = 0;
+	puts(".");
+}
+
+static void error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	while (1) ;		/* Halt */
+}
+
+#define STACK_SIZE (4096)
+long __attribute__ ((aligned(8))) user_stack[STACK_SIZE];
+long *stack_start = &user_stack[STACK_SIZE];
+
+void decompress_kernel(void)
+{
+	output_data = (uch *) (CONFIG_MEMORY_START + 0x2000);
+	free_mem_ptr = (unsigned long) &_end;
+	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
+	makecrc();
+	puts("Uncompressing Linux... ");
+	cache_control(CACHE_ENABLE);
+	gunzip();
+	puts("\n");
+
+#if 0
+	/* When booting from ROM may want to do something like this if the
+	 * boot loader doesn't.
+	 */
+
+	/* Set up the parameters and command line */
+	{
+		volatile unsigned int *parambase =
+		    (int *) (CONFIG_MEMORY_START + 0x1000);
+
+		parambase[0] = 0x1;	/* MOUNT_ROOT_RDONLY */
+		parambase[1] = 0x0;	/* RAMDISK_FLAGS */
+		parambase[2] = 0x0200;	/* ORIG_ROOT_DEV */
+		parambase[3] = 0x0;	/* LOADER_TYPE */
+		parambase[4] = 0x0;	/* INITRD_START */
+		parambase[5] = 0x0;	/* INITRD_SIZE */
+		parambase[6] = 0;
+
+		strcpy((char *) ((int) parambase + 0x100),
+		       "console=ttySC0,38400");
+	}
+#endif
+
+	puts("Ok, booting the kernel.\n");
+
+	cache_control(CACHE_DISABLE);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/boot/compressed/vmlinux.lds.S linux-2.4.22-pre10/arch/sh64/boot/compressed/vmlinux.lds.S
--- linux-2.4.21/arch/sh64/boot/compressed/vmlinux.lds.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/boot/compressed/vmlinux.lds.S	2003-08-01 13:34:47.000000000 +0000
@@ -0,0 +1,65 @@
+/*
+ * ld script to make compressed SuperH/shmedia Linux kernel+decompression
+		bootstrap
+ * Modified by Stuart Menefy from arch/sh/vmlinux.lds.S written by Niibe Yutaka 
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_LITTLE_ENDIAN
+/* OUTPUT_FORMAT("elf32-sh64l-linux", "elf32-sh64l-linux", "elf32-sh64l-linux") */
+#define NOP 0x6ff0fff0
+#else
+/* OUTPUT_FORMAT("elf32-sh64", "elf32-sh64", "elf32-sh64") */
+#define NOP 0xf0fff06f
+#endif
+
+OUTPUT_FORMAT("elf32-sh64-linux")
+OUTPUT_ARCH(sh)
+ENTRY(_start)
+
+#define ALIGNED_GAP(section, align) (((ADDR(section)+SIZEOF(section)+(align)-1) & ~((align)-1))-ADDR(section))
+#define FOLLOWING(section, align) AT (LOADADDR(section) + ALIGNED_GAP(section,align))
+
+SECTIONS
+{
+  _text = .;			/* Text and read-only data */
+
+  .text : {
+	*(.text)
+	*(.text64)
+	*(.text..SHmedia32)
+	*(.fixup)
+	*(.gnu.warning)
+	} = NOP
+  . = ALIGN(4);
+  .rodata : { *(.rodata) }
+
+  /* There is no 'real' reason for eight byte alignment, four would work
+   * as well, but gdb downloads much (*4) faster with this.
+   */
+  . = ALIGN(8);
+  .image : { *(.image) }
+  . = ALIGN(4);
+  _etext = .;			/* End of text section */
+
+  .data :			/* Data */
+	FOLLOWING(.image, 4)
+	{
+	_data = .;
+	*(.data)
+	}
+  _data_image = LOADADDR(.data);/* Address of data section in ROM */
+
+  _edata = .;			/* End of data section */
+
+  .stack : { stack = .;  _stack = .; }
+
+  . = ALIGN(4);
+  __bss_start = .;		/* BSS */
+  .bss : {
+	*(.bss)
+	}
+  . = ALIGN(4);
+  _end = . ;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/config.in linux-2.4.22-pre10/arch/sh64/config.in
--- linux-2.4.21/arch/sh64/config.in	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/config.in	2003-08-01 13:35:03.000000000 +0000
@@ -0,0 +1,308 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+#
+mainmenu_name "Linux/SH64 Kernel Configuration"
+
+define_bool CONFIG_SUPERH y
+
+define_bool CONFIG_UID16 y
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+   bool '  Set version information on all module symbols' CONFIG_MODVERSIONS
+   bool '  Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'System type'
+choice 'SuperH system type'					\
+	"Generic		CONFIG_SH_GENERIC		\
+	 Simulator		CONFIG_SH_SIMULATOR		\
+	 Cayman		        CONFIG_SH_CAYMAN		\
+	 ST50-Harp		CONFIG_SH_HARP" Simulator
+endmenu
+
+mainmenu_option next_comment
+comment 'Processor type and features'
+comment 'Processor options'
+choice 'Processor family'					\
+	"SH-5			CONFIG_CPU_SH5" SH-5
+
+if [ "$CONFIG_CPU_SH5" = "y" ]; then
+   choice 'Processor type' \
+   	"SH5-101		CONFIG_CPU_SUBTYPE_SH5_101	\
+	 SH5-103		CONFIG_CPU_SUBTYPE_SH5_103" SH5-101
+fi
+
+choice 'Endianness' \
+       "Little-Endian		CONFIG_LITTLE_ENDIAN		\
+	Big-Endian		CONFIG_BIG_ENDIAN" Little-Endian
+
+bool 'Flush floating point denorms to zero' CONFIG_SH64_FPU_DENORM_FLUSH
+choice 'Page table levels' \
+	"2			CONFIG_SH64_PGTABLE_2_LEVEL \
+	 3			CONFIG_SH64_PGTABLE_3_LEVEL" 2
+
+# Use 32-bit addressing for now.
+# EMI based.
+# P2 (UNCACHED) required to use identity mapping
+# P1 (CACHED) assumes non-identity.
+
+#
+# Memory options
+#
+comment 'Memory options'
+
+int 'Memory size (in MB)' CONFIG_MEMORY_SIZE_IN_MB 64
+hex 'Cached Area Offset' CONFIG_CACHED_MEMORY_OFFSET 20000000
+hex 'Uncached Area Offset' CONFIG_UNCACHED_MEMORY_OFFSET 00000000
+hex 'Physical memory start address' CONFIG_MEMORY_START 80000000
+
+#
+# Cache options
+#
+comment 'Cache options'
+bool 'DCache Disabling' CONFIG_DCACHE_DISABLED
+
+if [ "$CONFIG_SH_SIMULATOR" != "y" -a \
+     "$CONFIG_DCACHE_DISABLED" != "y" ]; then
+     choice 'DCache mode'                                 \
+         "Write-back             CONFIG_DCACHE_WRITE_BACK \
+          Write-through          CONFIG_DCACHE_WRITE_THROUGH" Write-back
+fi
+
+bool 'ICache Disabling' CONFIG_ICACHE_DISABLED
+
+
+#
+# CPU Subtype specific options (errata and such)
+#
+comment 'CPU Subtype specific options'
+if [ "$CONFIG_CPU_SUBTYPE_SH5_101" = "y" ]; then
+  bool "Include workaround for SH5-101 cut2 silicon defect ID2815" CONFIG_SH64_ID2815_WORKAROUND
+fi
+
+endmenu
+
+mainmenu_option next_comment
+comment 'General setup'
+
+define_bool CONFIG_ISA n
+define_bool CONFIG_SBUS n
+
+bool 'Networking support' CONFIG_NET
+
+bool 'PCI support' CONFIG_PCI
+if [ "$CONFIG_SH_SIMULATOR" = "y" ]; then
+  define_bool CONFIG_PCI n
+  define_bool CONFIG_NET n
+fi
+
+if [ "$CONFIG_SH_HARP" = "y" ]; then
+  define_bool CONFIG_PCI n
+  define_bool CONFIG_NET y
+  define_bool CONFIG_NET_PCI y
+fi
+
+if [ "$CONFIG_PCI" = "y" ]; then
+   choice '  PCI access mode' \
+	"BIOS		CONFIG_PCI_GOBIOS	\
+	 Direct		CONFIG_PCI_GODIRECT	\
+	 Any		CONFIG_PCI_GOANY"	Any
+   if [ "$CONFIG_PCI_GOBIOS" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
+      define_bool CONFIG_PCI_BIOS y
+   fi
+   if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
+      define_bool CONFIG_PCI_DIRECT y
+   fi
+fi
+
+source drivers/pci/Config.in
+
+# bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+# 
+define_bool CONFIG_HOTPLUG n
+
+if [ "$CONFIG_HOTPLUG" = "y" ] ; then
+   source drivers/pcmcia/Config.in
+else
+   define_bool CONFIG_PCMCIA n
+fi
+
+bool 'System V IPC' CONFIG_SYSVIPC
+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+# bool 'Sysctl support' CONFIG_SYSCTL
+define_bool CONFIG_SYSCTL y
+
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+
+# source drivers/parport/Config.in
+
+endmenu
+
+# source drivers/mtd/Config.in
+
+source drivers/block/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   source net/Config.in
+fi
+
+mainmenu_option next_comment
+comment 'ATA/IDE/MFM/RLL support'
+
+tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
+
+if [ "$CONFIG_IDE" != "n" ]; then
+  source drivers/ide/Config.in
+else
+   define_bool CONFIG_BLK_DEV_IDE_MODES n
+   define_bool CONFIG_BLK_DEV_HD n
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'SCSI support'
+
+ tristate 'SCSI support' CONFIG_SCSI
+##define_bool CONFIG_SCSI n
+
+if [ "$CONFIG_SCSI" != "n" ]; then
+   source drivers/scsi/Config.in
+fi
+endmenu
+
+# source drivers/ieee1394/Config.in
+
+if [ "$CONFIG_NET" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Network device support'
+
+   bool 'Network device support' CONFIG_NETDEVICES
+   if [ "$CONFIG_NETDEVICES" = "y" ]; then
+      source drivers/net/Config.in
+      if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
+         source drivers/atm/Config.in
+      fi
+   fi
+   endmenu
+fi
+
+#
+# input before char - char/joystick depends on it. As does USB.
+#
+source drivers/input/Config.in
+
+mainmenu_option next_comment
+comment 'Character devices'
+
+bool 'Virtual terminal' CONFIG_VT
+
+if [ "$CONFIG_VT" = "y" ]; then
+   bool '  Support for console on virtual terminal' CONFIG_VT_CONSOLE
+fi
+
+
+# insert for SCIF serial console support 
+tristate 'Serial (SCI, SCIF) support' CONFIG_SH_SCI
+tristate 'Serial (8250, 16450, 16550 or compatible) support' CONFIG_SERIAL
+
+if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_SH_SCI" = "y" ]; then
+   bool '  Support for console on serial port' CONFIG_SERIAL_CONSOLE
+fi
+
+
+comment 'Unix 98 PTY support'
+bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
+if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
+   int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
+fi
+if [ "$CONFIG_PARPORT" != "n" ]; then
+   dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
+   if [ "$CONFIG_PRINTER" != "n" ]; then
+      bool '  Support for console on line printer' CONFIG_LP_CONSOLE
+   fi
+   dep_tristate 'Support for user-space parallel port device drivers' CONFIG_PPDEV $CONFIG_PARPORT
+fi
+
+bool 'Heartbeat LED' CONFIG_HEARTBEAT
+dep_bool 'Support for HDSP-253 LED' CONFIG_HDSP253_LED $CONFIG_SH_CAYMAN
+tristate 'DMA controller (DMAC) support' CONFIG_SH_DMA
+bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
+
+mainmenu_option next_comment
+comment 'Watchdog Cards'
+bool 'Watchdog Timer Support' CONFIG_WATCHDOG
+if [ "$CONFIG_WATCHDOG" != "n" ]; then
+   bool '  Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
+   dep_tristate '  SuperH Watchdog' CONFIG_SH_WDT $CONFIG_SUPERH
+fi
+endmenu
+
+endmenu
+
+if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then
+   source drivers/char/pcmcia/Config.in
+fi
+
+source fs/Config.in
+
+source drivers/media/Config.in
+
+
+if [ "$CONFIG_VT" = "y" ]; then
+   mainmenu_option next_comment
+   comment 'Console drivers'
+   bool 'VGA text console' CONFIG_VGA_CONSOLE
+   bool 'Video mode selection support' CONFIG_VIDEO_SELECT
+   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+      source drivers/video/Config.in
+   fi
+   endmenu
+fi
+
+
+mainmenu_option next_comment
+comment 'Sound'
+
+tristate 'Sound card support' CONFIG_SOUND
+# define_bool CONFIG_SOUND n
+
+if [ "$CONFIG_SOUND" != "n" ]; then
+   source drivers/sound/Config.in
+fi
+endmenu
+
+source drivers/usb/Config.in
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+bool 'GDB Stub kernel debug' CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
+bool "Debug: audit page tables on return from syscall/exception/interrupt" CONFIG_SH64_PAGE_TABLE_AUDIT
+dep_bool "Debug: report TLB fill/purge activity through /proc/tlb" CONFIG_SH64_PROC_TLB $CONFIG_PROC_FS
+
+endmenu
+
+source lib/Config.in
+source crypto/Config.in
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/defconfig linux-2.4.22-pre10/arch/sh64/defconfig
--- linux-2.4.21/arch/sh64/defconfig	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/defconfig	2003-08-01 13:34:41.000000000 +0000
@@ -0,0 +1,491 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_SUPERH=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# System type
+#
+# CONFIG_SH_GENERIC is not set
+# CONFIG_SH_SIMULATOR is not set
+CONFIG_SH_CAYMAN=y
+# CONFIG_SH_HARP is not set
+
+#
+# Processor type and features
+#
+
+#
+# Processor options
+#
+CONFIG_CPU_SH5=y
+CONFIG_CPU_SUBTYPE_SH5_101=y
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+CONFIG_LITTLE_ENDIAN=y
+# CONFIG_BIG_ENDIAN is not set
+# CONFIG_SH64_FPU_DENORM_FLUSH is not set
+CONFIG_SH64_PGTABLE_2_LEVEL=y
+# CONFIG_SH64_PGTABLE_3_LEVEL is not set
+
+#
+# Memory options
+#
+CONFIG_MEMORY_SIZE_IN_MB=64
+CONFIG_CACHED_MEMORY_OFFSET=20000000
+CONFIG_UNCACHED_MEMORY_OFFSET=00000000
+CONFIG_MEMORY_START=80000000
+
+#
+# Cache options
+#
+# CONFIG_DCACHE_DISABLED is not set
+CONFIG_DCACHE_WRITE_BACK=y
+# CONFIG_DCACHE_WRITE_THROUGH is not set
+# CONFIG_ICACHE_DISABLED is not set
+
+#
+# CPU Subtype specific options
+#
+CONFIG_SH64_ID2815_WORKAROUND=y
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_GOBIOS is not set
+# CONFIG_PCI_GODIRECT is not set
+CONFIG_PCI_GOANY=y
+CONFIG_PCI_BIOS=y
+CONFIG_PCI_DIRECT=y
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_STATS=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_STNIC is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_EEPRO100_PIO is not set
+# CONFIG_E100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_SUNDANCE_MMIO is not set
+# CONFIG_TLAN is not set
+# CONFIG_TC35815 is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_SH_SCI=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+
+#
+# Unix 98 PTY support
+#
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+CONFIG_HEARTBEAT=y
+CONFIG_HDSP253_LED=y
+CONFIG_SH_DMA=y
+# CONFIG_PSMOUSE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_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 is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_VIDEO_SELECT is not set
+# CONFIG_MDA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+CONFIG_FB_KYRO=y
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_E1355 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_INTEL is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+# CONFIG_FBCON_CFB8 is not set
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_CFB24 is not set
+CONFIG_FBCON_CFB32=y
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set
+# CONFIG_SH64_PAGE_TABLE_AUDIT is not set
+# CONFIG_SH64_PROC_TLB is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/Makefile linux-2.4.22-pre10/arch/sh64/kernel/Makefile
--- linux-2.4.21/arch/sh64/kernel/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/Makefile	2003-08-01 13:30:32.000000000 +0000
@@ -0,0 +1,40 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2000, 2001  Paolo Alberelli
+#
+# Makefile for the Linux SH-5 kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.o:
+	$(CC) $(CFLAGS) $(AFLAGS) -c $< -o $*.o
+
+O_TARGET := kernel.o
+
+obj-y   := process.o signal.o entry.o traps.o irq.o irq_intc.o \
+	    ptrace.o setup.o time.o sys_sh64.o semaphore.o sh_ksyms.o
+
+obj-$(CONFIG_HEARTBEAT)		+= led.o
+obj-$(CONFIG_PCI)		+= pci-dma.o pcibios.o
+
+ifeq ($(CONFIG_PCI),y)
+obj-$(CONFIG_CPU_SH5)		+= pci_sh5.o
+endif
+
+obj-$(CONFIG_SH_DMA)		+= dma.o
+
+export-objs := sh_ksyms.o
+
+ifndef CONFIG_NOFPU_SUPPORT
+obj-y	+= fpu.o
+endif
+
+all: $(O_TARGET) head.o init_task.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/dma.c linux-2.4.22-pre10/arch/sh64/kernel/dma.c
--- linux-2.4.21/arch/sh64/kernel/dma.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/dma.c	2003-08-01 13:33:09.000000000 +0000
@@ -0,0 +1,293 @@
+/*
+ * arch/sh64/kernel/dma.c
+ *
+ * DMA routines for the SH-5 DMAC.
+ *
+ * Copyright (C) 2003  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */ 
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <asm/hardware.h>
+#include <asm/dma.h>
+#include <asm/signal.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+
+typedef struct {
+	unsigned long dev_addr;
+	unsigned long mem_addr;
+
+	unsigned int mode;
+	unsigned int count;
+} dma_info_t;
+
+static dma_info_t dma_info[MAX_DMA_CHANNELS];
+extern spinlock_t dma_spin_lock;
+
+/* arch/sh64/kernel/irq_intc.c */
+extern void make_intc_irq(unsigned int irq);
+
+/* DMAC Interrupts */
+#define DMA_IRQ_DMTE0	18
+#define DMA_IRQ_DERR	22
+
+#define DMAC_COMMON_BASE	(dmac_base + 0x08)
+#define DMAC_SAR_BASE		(dmac_base + 0x10)
+#define DMAC_DAR_BASE		(dmac_base + 0x18)
+#define DMAC_COUNT_BASE		(dmac_base + 0x20)
+#define DMAC_CTRL_BASE		(dmac_base + 0x28)
+#define DMAC_STATUS_BASE	(dmac_base + 0x30)
+
+#define DMAC_SAR(n)	(DMAC_SAR_BASE    + ((n) * 0x28))
+#define DMAC_DAR(n)	(DMAC_DAR_BASE    + ((n) * 0x28))
+#define DMAC_COUNT(n)	(DMAC_COUNT_BASE  + ((n) * 0x28))
+#define DMAC_CTRL(n)	(DMAC_CTRL_BASE   + ((n) * 0x28))
+#define DMAC_STATUS(n)	(DMAC_STATUS_BASE + ((n) * 0x28))
+
+/* DMAC.COMMON Bit Definitions */
+#define DMAC_COMMON_PR	0x00000001	/* Priority */
+					/* Bits 1-2 Reserved */
+#define DMAC_COMMON_ME	0x00000008	/* Master Enable */
+#define DMAC_COMMON_NMI	0x00000010	/* NMI Flag */
+					/* Bits 5-6 Reserved */
+#define DMAC_COMMON_ER	0x00000780	/* Error Response */
+#define DMAC_COMMON_AAE	0x00007800	/* Address Alignment Error */
+					/* Bits 15-63 Reserved */
+
+/* DMAC.SAR Bit Definitions */
+#define DMAC_SAR_ADDR	0xffffffff	/* Source Address */
+
+/* DMAC.DAR Bit Definitions */
+#define DMAC_DAR_ADDR	0xffffffff	/* Destination Address */
+
+/* DMAC.COUNT Bit Definitions */
+#define DMAC_COUNT_CNT	0xffffffff	/* Transfer Count */
+
+/* DMAC.CTRL Bit Definitions */
+#define DMAC_CTRL_TS	0x00000007	/* Transfer Size */
+#define DMAC_CTRL_SI	0x00000018	/* Source Increment */
+#define DMAC_CTRL_DI	0x00000060	/* Destination Increment */
+#define DMAC_CTRL_RS	0x00000780	/* Resource Select */
+#define DMAC_CTRL_IE	0x00000800	/* Interrupt Enable */
+#define DMAC_CTRL_TE	0x00001000	/* Transfer Enable */
+					/* Bits 15-63 Reserved */
+
+/* DMAC.STATUS Bit Definitions */
+#define DMAC_STATUS_TE	0x00000001	/* Transfer End */
+#define DMAC_STATUS_AAE	0x00000002	/* Address Alignment Error */
+					/* Bits 2-63 Reserved */
+
+static unsigned long dmac_base;
+
+void set_dma_count(unsigned int chan, unsigned int count);
+void set_dma_addr(unsigned int chan, unsigned int addr);
+
+static void dma_mte(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int chan = irq - DMA_IRQ_DMTE0;
+	dma_info_t *info = dma_info + chan;
+	u64 status;
+
+	if (info->mode & DMA_MODE_WRITE) {
+		sh64_out64(info->mem_addr & DMAC_SAR_ADDR, DMAC_SAR(chan));
+	} else {
+		sh64_out64(info->mem_addr & DMAC_DAR_ADDR, DMAC_DAR(chan));
+	}
+
+	set_dma_count(chan, info->count);
+
+	/* Clear the TE bit */
+	status = sh64_in64(DMAC_STATUS(chan));
+	status &= ~DMAC_STATUS_TE;
+	sh64_out64(status, DMAC_STATUS(chan));
+}
+
+static struct irqaction irq_dmte = {
+	.handler	= dma_mte,
+	.flags		= SA_INTERRUPT,
+	.name		= "DMA MTE",
+};
+
+static void dma_err(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u64 tmp;
+	u8 chan;
+
+	printk(KERN_NOTICE "DMAC: Got a DMA Error!\n");
+
+	tmp = sh64_in64(DMAC_COMMON_BASE);
+
+	/* Check for the type of error */
+	if ((chan = tmp & DMAC_COMMON_AAE)) {
+		/* It's an address alignment error.. */
+		printk(KERN_NOTICE "DMAC: Alignment error on channel %d, ", chan);
+
+		printk(KERN_NOTICE "SAR: 0x%08llx, DAR: 0x%08llx, COUNT: %lld\n",
+		       (sh64_in64(DMAC_SAR(chan)) & DMAC_SAR_ADDR),
+		       (sh64_in64(DMAC_DAR(chan)) & DMAC_DAR_ADDR),
+		       (sh64_in64(DMAC_COUNT(chan)) & DMAC_COUNT_CNT));
+
+	} else if ((chan = tmp & DMAC_COMMON_ER)) {
+		/* Something else went wrong.. */
+		printk(KERN_NOTICE "DMAC: Error on channel %d\n", chan);
+	}
+	
+	/* Reset the ME bit to clear the interrupt */
+	tmp |= DMAC_COMMON_ME;
+	sh64_out64(tmp, DMAC_COMMON_BASE);
+}
+
+static struct irqaction irq_derr = {
+	.handler	= dma_err,
+	.flags		= SA_INTERRUPT,
+	.name		= "DMA Error",
+};
+
+static inline unsigned long calc_xmit_shift(unsigned int chan)
+{
+	return sh64_in64(DMAC_CTRL(chan)) & 0x03;
+}
+
+void setup_dma(unsigned int chan, dma_info_t *info)
+{
+	unsigned int irq = DMA_IRQ_DMTE0 + chan;
+	dma_info_t *dma = dma_info + chan;
+
+	make_intc_irq(irq);
+	setup_irq(irq, &irq_dmte);
+	dma = info;
+}
+
+void enable_dma(unsigned int chan)
+{
+	u64 ctrl;
+
+	ctrl = sh64_in64(DMAC_CTRL(chan));
+	ctrl |= DMAC_CTRL_TE;
+	sh64_out64(ctrl, DMAC_CTRL(chan));
+}
+
+void disable_dma(unsigned int chan)
+{
+	u64 ctrl;
+
+	ctrl = sh64_in64(DMAC_CTRL(chan));
+	ctrl &= ~DMAC_CTRL_TE;
+	sh64_out64(ctrl, DMAC_CTRL(chan));
+}
+
+void set_dma_mode(unsigned int chan, char mode)
+{
+	dma_info_t *info = dma_info + chan;
+
+	info->mode = mode;
+
+	set_dma_addr(chan, info->mem_addr);
+	set_dma_count(chan, info->count);
+}
+
+void set_dma_addr(unsigned int chan, unsigned int addr)
+{
+	dma_info_t *info = dma_info + chan;
+	unsigned long sar, dar;
+
+	info->mem_addr = addr;
+	sar = (info->mode & DMA_MODE_WRITE) ? info->mem_addr : info->dev_addr;
+	dar = (info->mode & DMA_MODE_WRITE) ? info->dev_addr : info->mem_addr;
+
+	sh64_out64(sar & DMAC_SAR_ADDR, DMAC_SAR(chan));
+	sh64_out64(dar & DMAC_SAR_ADDR, DMAC_DAR(chan));
+}
+
+void set_dma_count(unsigned int chan, unsigned int count)
+{
+	dma_info_t *info = dma_info + chan;
+	u64 tmp;
+
+	info->count = count;
+
+	tmp = (info->count >> calc_xmit_shift(chan)) & DMAC_COUNT_CNT;
+
+	sh64_out64(tmp, DMAC_COUNT(chan));
+}
+
+unsigned long claim_dma_lock(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dma_spin_lock, flags);
+
+	return flags;
+}
+
+void release_dma_lock(unsigned long flags)
+{
+	spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+int get_dma_residue(unsigned int chan)
+{
+	return sh64_in64(DMAC_COUNT(chan) << calc_xmit_shift(chan));
+}
+
+int __init init_dma(void)
+{
+	struct vcr_info vcr;
+	u64 tmp;
+
+	/* Remap the DMAC */
+	dmac_base = onchip_remap(PHYS_DMAC_BLOCK, 1024, "DMAC");
+	if (!dmac_base) {
+		printk(KERN_ERR "Unable to remap DMAC\n");
+		return -ENOMEM;
+	}
+
+	/* Report DMAC.VCR Info */
+	vcr = sh64_get_vcr_info(dmac_base);
+	printk("DMAC: Module ID: 0x%04x, Module version: 0x%04x\n",
+	       vcr.mod_id, vcr.mod_vers);
+
+	/* Set the ME bit */
+	tmp = sh64_in64(DMAC_COMMON_BASE);
+	tmp |= DMAC_COMMON_ME; 
+	sh64_out64(tmp, DMAC_COMMON_BASE);
+
+	/* Enable the DMAC Error Interrupt */
+	make_intc_irq(DMA_IRQ_DERR);
+	setup_irq(DMA_IRQ_DERR, &irq_derr);
+
+	return 0;
+}
+
+static void __exit exit_dma(void)
+{
+	onchip_unmap(dmac_base);
+	free_irq(DMA_IRQ_DERR, 0);
+}
+
+module_init(init_dma);
+module_exit(exit_dma);
+
+MODULE_AUTHOR("Paul Mundt");
+MODULE_DESCRIPTION("DMA API for SH-5 DMAC");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(setup_dma);
+EXPORT_SYMBOL(claim_dma_lock);
+EXPORT_SYMBOL(release_dma_lock);
+EXPORT_SYMBOL(enable_dma);
+EXPORT_SYMBOL(disable_dma);
+EXPORT_SYMBOL(set_dma_mode);
+EXPORT_SYMBOL(set_dma_addr);
+EXPORT_SYMBOL(set_dma_count);
+EXPORT_SYMBOL(get_dma_residue);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/entry.S linux-2.4.22-pre10/arch/sh64/kernel/entry.S
--- linux-2.4.21/arch/sh64/kernel/entry.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/entry.S	2003-08-01 13:33:49.000000000 +0000
@@ -0,0 +1,2111 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/entry.S
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sys.h>
+
+#include <asm/processor.h>
+#include <asm/registers.h>
+#include <asm/unistd.h>
+
+/*
+ * A few defines that ought to come from sched.h referring
+ * to the task structure. Byte offsets within the task
+ * structure and related flags.
+ */
+#define flags		4
+#define sigpending	8
+#define need_resched	20
+#define ptrace		24
+
+#define PT_TRACESYS	0x00000002
+
+
+/*
+ * SR fields.
+ */
+#define SR_ASID_MASK	0x00ff0000
+#define SR_FD_MASK	0x00008000
+#define SR_SS		0x08000000
+#define SR_BL		0x10000000
+#define SR_MD		0x40000000
+#define SR_MMU		0x80000000
+
+/*
+ * Event code.
+ */
+#define	EVENT_INTERRUPT		0
+#define	EVENT_FAULT_TLB		1
+#define	EVENT_FAULT_NOT_TLB	2
+#define	EVENT_DEBUG		3
+
+/* EXPEVT values */
+#define	RESET_CAUSE		0x20
+#define DEBUGSS_CAUSE		0x980
+
+/*
+ * Frame layout. Quad index.
+ */
+#define	FRAME_T(x)	FRAME_TBASE+(x*8)
+#define	FRAME_R(x)	FRAME_RBASE+(x*8)
+#define	FRAME_S(x)	FRAME_SBASE+(x*8)
+#define FSPC		0
+#define FSSR		1
+#define FSYSCALL_ID	2
+
+/* Arrange the save frame to be a multiple of 32 bytes long */
+#define FRAME_SBASE	0
+#define FRAME_RBASE	(FRAME_SBASE+(3*8))	/* SYSCALL_ID - SSR - SPC */
+#define FRAME_TBASE	(FRAME_RBASE+(63*8))	/* r0 - r62 */
+#define FRAME_PBASE	(FRAME_TBASE+(8*8))	/* t0 -t7 */
+#define	FRAME_SIZE	(FRAME_PBASE+(2*8))	/* pad0-pad1 */
+
+#define FP_FRAME_SIZE	FP_FRAME_BASE+(33*8)	/* dr0 - dr31 + fpscr */
+#define FP_FRAME_BASE	0
+
+#define	SAVED_R2	0*8
+#define	SAVED_R3	1*8
+#define	SAVED_R4	2*8
+#define	SAVED_R5	3*8
+#define	SAVED_R18	4*8
+#define	SAVED_R6	5*8
+#define	SAVED_T0	6*8
+
+/* These are the registers saved in the TLB path that aren't saved in the first
+   level of the normal one. */
+#define	TLB_SAVED_R25	7*8
+#define	TLB_SAVED_T1	8*8
+#define	TLB_SAVED_T2	9*8
+#define	TLB_SAVED_T3	10*8
+#define	TLB_SAVED_T4	11*8
+/* Save R0/R1 : PT-migrating compiler currently dishounours -ffixed-r0 and -ffixed-r1 causing
+   breakage otherwise. */
+#define	TLB_SAVED_R0	12*8
+#define	TLB_SAVED_R1	13*8
+
+#define STI()				\
+	getcon	SR, r6;			\
+	andi	r6, ~0xf0, r6;		\
+	putcon	r6, SR;
+
+	.section	.data, "aw"
+
+#define FAST_TLBMISS_STACK_CACHELINES 4
+#define FAST_TLBMISS_STACK_QUADWORDS (4*FAST_TLBMISS_STACK_CACHELINES)
+
+/* Register back-up area for all exceptions */
+	.balign	32
+	/* Allow for 16 quadwords to be pushed by fast tlbmiss handling
+	 * register saves etc. */
+	.fill FAST_TLBMISS_STACK_QUADWORDS, 8, 0x0
+/* This is 32 byte aligned by construction */
+/* Register back-up area for all exceptions */
+reg_save_area:
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.quad	0
+	.quad   0
+
+/* Save area for RESVEC exceptions. We cannot use reg_save_area because of
+ * reentrancy. Note this area may be accessed via physical address.
+ * Align so this fits a whole single cache line, for ease of purging.
+ */
+	.balign 32,0,32
+resvec_save_area:
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.balign 32,0,32
+
+/* Jump table of 3rd level handlers  */
+trap_jtable:
+	.long	do_exception_error		/* 0x000 */
+	.long	do_exception_error		/* 0x020 */
+	.long	tlb_miss_load				/* 0x040 */
+	.long	tlb_miss_store				/* 0x060 */
+	.long	do_exception_error		/* 0x080 */
+	.long	tlb_miss_load				/* 0x0A0 */
+	.long	tlb_miss_store				/* 0x0C0 */
+	.long	do_address_error_load	/* 0x0E0 */
+	.long	do_address_error_store	/* 0x100 */
+#ifndef CONFIG_NOFPU_SUPPORT
+	.long	do_fpu_error		/* 0x120 */
+#else
+	.long	do_exception_error		/* 0x120 */
+#endif
+	.long	do_exception_error		/* 0x140 */
+	.long	system_call				/* 0x160 */
+	.long	do_reserved_inst		/* 0x180 */
+	.long	do_illegal_slot_inst	/* 0x1A0 */
+	.long	do_NMI			/* 0x1C0 */
+	.long	do_exception_error		/* 0x1E0 */
+	.rept 15
+		.long do_IRQ		/* 0x200 - 0x3C0 */
+	.endr
+	.long	do_exception_error		/* 0x3E0 */
+	.rept 32
+		.long do_IRQ		/* 0x400 - 0x7E0 */
+	.endr
+	.long	fpu_error_or_IRQA			/* 0x800 */
+	.long	fpu_error_or_IRQB			/* 0x820 */
+	.long	do_IRQ			/* 0x840 */
+	.long	do_IRQ			/* 0x860 */
+	.rept 6
+		.long do_exception_error	/* 0x880 - 0x920 */
+	.endr
+	.long	do_software_break_point	/* 0x940 */
+	.long	do_exception_error		/* 0x960 */
+	.long	do_single_step		/* 0x980 */
+
+	.rept 3
+		.long do_exception_error	/* 0x9A0 - 0x9E0 */
+	.endr
+	.long	do_IRQ			/* 0xA00 */
+	.long	do_IRQ			/* 0xA20 */
+	.long	itlb_miss_or_IRQ			/* 0xA40 */
+	.long	do_IRQ			/* 0xA60 */
+	.long	do_IRQ			/* 0xA80 */
+	.long	itlb_miss_or_IRQ			/* 0xAA0 */
+	.long	do_exception_error		/* 0xAC0 */
+	.long	do_address_error_exec	/* 0xAE0 */
+	.rept 8
+		.long do_exception_error	/* 0xB00 - 0xBE0 */
+	.endr
+	.rept 18
+		.long do_IRQ		/* 0xC00 - 0xE20 */
+	.endr
+
+
+/* System calls jump table */
+
+.globl  sys_call_table
+sys_call_table:
+	.long sys_ni_syscall	/* 0  -  old "setup()" system call  */
+	.long sys_exit
+	.long sys_fork
+	.long sys_read
+	.long sys_write
+	.long sys_open		/* 5 */
+	.long sys_close
+	.long sys_waitpid
+	.long sys_creat
+	.long sys_link
+	.long sys_unlink		/* 10 */
+	.long sys_execve
+	.long sys_chdir
+	.long sys_time
+	.long sys_mknod
+	.long sys_chmod		/* 15 */
+	.long sys_lchown16
+	.long sys_ni_syscall	/* old break syscall holder */
+	.long sys_stat
+	.long sys_lseek
+	.long sys_getpid		/* 20 */
+	.long sys_mount
+	.long sys_oldumount
+	.long sys_setuid16
+	.long sys_getuid16
+	.long sys_stime		/* 25 */
+	.long sys_ptrace
+	.long sys_alarm
+	.long sys_fstat
+	.long sys_pause
+	.long sys_utime		/* 30 */
+	.long sys_ni_syscall	/* old stty syscall holder */
+	.long sys_ni_syscall	/* old gtty syscall holder */
+	.long sys_access
+	.long sys_nice
+	.long sys_ni_syscall	/* 35 */
+						/* old ftime syscall holder */
+	.long sys_sync
+	.long sys_kill
+	.long sys_rename
+	.long sys_mkdir
+	.long sys_rmdir		/* 40 */
+	.long sys_dup
+	.long sys_pipe
+	.long sys_times
+	.long sys_ni_syscall	/* old prof syscall holder */
+	.long sys_brk		/* 45 */
+	.long sys_setgid16
+	.long sys_getgid16
+	.long sys_signal
+	.long sys_geteuid16
+	.long sys_getegid16	/* 50 */
+	.long sys_acct
+	.long sys_umount		/* recycled never used phys( */
+	.long sys_ni_syscall	/* old lock syscall holder */
+	.long sys_ioctl
+	.long sys_fcntl		/* 55 */
+	.long sys_ni_syscall	/* old mpx syscall holder */
+	.long sys_setpgid
+	.long sys_ni_syscall	/* old ulimit syscall holder */
+	.long sys_ni_syscall	/* sys_olduname */
+	.long sys_umask		/* 60 */
+	.long sys_chroot
+	.long sys_ustat
+	.long sys_dup2
+	.long sys_getppid
+	.long sys_getpgrp		/* 65 */
+	.long sys_setsid
+	.long sys_sigaction
+	.long sys_sgetmask
+	.long sys_ssetmask
+	.long sys_setreuid16	/* 70 */
+	.long sys_setregid16
+	.long sys_sigsuspend
+	.long sys_sigpending
+	.long sys_sethostname
+	.long sys_setrlimit	/* 75 */
+	.long sys_old_getrlimit
+	.long sys_getrusage
+	.long sys_gettimeofday
+	.long sys_settimeofday
+	.long sys_getgroups16	/* 80 */
+	.long sys_setgroups16
+	.long sys_ni_syscall	/* sys_oldselect */
+	.long sys_symlink
+	.long sys_lstat
+	.long sys_readlink		/* 85 */
+	.long sys_uselib
+	.long sys_swapon
+	.long sys_reboot
+	.long old_readdir
+	.long old_mmap		/* 90 */
+	.long sys_munmap
+	.long sys_truncate
+	.long sys_ftruncate
+	.long sys_fchmod
+	.long sys_fchown16		/* 95 */
+	.long sys_getpriority
+	.long sys_setpriority
+	.long sys_ni_syscall	/* old profil syscall holder */
+	.long sys_statfs
+	.long sys_fstatfs		/* 100 */
+	.long sys_ni_syscall	/* ioperm */
+	.long sys_socketcall	/* Obsolete implementation of socket syscall */
+	.long sys_syslog
+	.long sys_setitimer
+	.long sys_getitimer	/* 105 */
+	.long sys_newstat
+	.long sys_newlstat
+	.long sys_newfstat
+	.long sys_uname
+	.long sys_ni_syscall	/* 110 */ /* iopl */
+	.long sys_vhangup
+	.long sys_ni_syscall	/* idle */
+	.long sys_ni_syscall	/* vm86old */
+	.long sys_wait4
+	.long sys_swapoff		/* 115 */
+	.long sys_sysinfo
+	.long sys_ipc		/* Obsolete ipc syscall implementation */
+	.long sys_fsync
+	.long sys_sigreturn
+	.long sys_clone		/* 120 */
+	.long sys_setdomainname
+	.long sys_newuname
+	.long sys_ni_syscall	/* sys_modify_ldt */
+	.long sys_adjtimex
+	.long sys_mprotect		/* 125 */
+	.long sys_sigprocmask
+	.long sys_create_module
+	.long sys_init_module
+	.long sys_delete_module
+	.long sys_get_kernel_syms	/* 130 */
+	.long sys_quotactl
+	.long sys_getpgid
+	.long sys_fchdir
+	.long sys_bdflush
+	.long sys_sysfs		/* 135 */
+	.long sys_personality
+	.long sys_ni_syscall	/* for afs_syscall */
+	.long sys_setfsuid16
+	.long sys_setfsgid16
+	.long sys_llseek		/* 140 */
+	.long sys_getdents
+	.long sys_select
+	.long sys_flock
+	.long sys_msync
+	.long sys_readv		/* 145 */
+	.long sys_writev
+	.long sys_getsid
+	.long sys_fdatasync
+	.long sys_sysctl
+	.long sys_mlock		/* 150 */
+	.long sys_munlock
+	.long sys_mlockall
+	.long sys_munlockall
+	.long sys_sched_setparam
+	.long sys_sched_getparam   	/* 155 */
+	.long sys_sched_setscheduler
+	.long sys_sched_getscheduler
+	.long sys_sched_yield
+	.long sys_sched_get_priority_max
+	.long sys_sched_get_priority_min  /* 160 */
+	.long sys_sched_rr_get_interval
+	.long sys_nanosleep
+	.long sys_mremap
+	.long sys_setresuid16
+	.long sys_getresuid16	/* 165 */
+	.long sys_ni_syscall	/* vm86 */
+	.long sys_query_module
+	.long sys_poll
+	.long sys_nfsservctl
+	.long sys_setresgid16	/* 170 */
+	.long sys_getresgid16
+	.long sys_prctl
+	.long sys_rt_sigreturn
+	.long sys_rt_sigaction
+	.long sys_rt_sigprocmask	/* 175 */
+	.long sys_rt_sigpending
+	.long sys_rt_sigtimedwait
+	.long sys_rt_sigqueueinfo
+	.long sys_rt_sigsuspend
+	.long sys_pread		/* 180 */
+	.long sys_pwrite
+	.long sys_chown16
+	.long sys_getcwd
+	.long sys_capget
+	.long sys_capset       	/* 185 */
+	.long sys_sigaltstack
+	.long sys_sendfile
+	.long sys_ni_syscall	/* streams1 */
+	.long sys_ni_syscall	/* streams2 */
+	.long sys_vfork        	/* 190 */
+	.long sys_getrlimit
+	.long sys_mmap2
+	.long sys_truncate64
+	.long sys_ftruncate64
+	.long sys_stat64		/* 195 */
+	.long sys_lstat64
+	.long sys_fstat64
+	.long sys_lchown
+	.long sys_getuid
+	.long sys_getgid		/* 200 */
+	.long sys_geteuid
+	.long sys_getegid
+	.long sys_setreuid
+	.long sys_setregid
+	.long sys_getgroups	/* 205 */
+	.long sys_setgroups
+	.long sys_fchown
+	.long sys_setresuid
+	.long sys_getresuid
+	.long sys_setresgid	/* 210 */
+	.long sys_getresgid
+	.long sys_chown
+	.long sys_setuid
+	.long sys_setgid
+	.long sys_setfsuid		/* 215 */
+	.long sys_setfsgid
+	.long sys_pivot_root
+	.long sys_mincore
+	.long sys_madvise
+	.long sys_socket		/* 220 */
+	.long sys_bind
+	.long sys_connect
+	.long sys_listen
+	.long sys_accept
+	.long sys_getsockname	/* 225 */
+	.long sys_getpeername
+	.long sys_socketpair
+	.long sys_send
+	.long sys_sendto
+	.long sys_recv		/* 230*/
+	.long sys_recvfrom
+	.long sys_shutdown
+	.long sys_setsockopt
+	.long sys_getsockopt
+	.long sys_sendmsg		/* 235 */
+	.long sys_recvmsg
+	.long sys_semop		/* New ipc syscall implementation */
+	.long sys_semget
+	.long sys_semctl
+	.long sys_msgsnd		/* 240 */
+	.long sys_msgrcv
+	.long sys_msgget
+	.long sys_msgctl
+	.long sys_shmatcall
+	.long sys_shmdt		/* 245 */
+	.long sys_shmget
+	.long sys_shmctl
+
+	/*
+	 * NOTE!! This doesn't have to be exact - we just have
+	 * to make sure we have _enough_ of the "sys_ni_syscall"
+	 * entries. Don't panic if you notice that this hasn't
+	 * been shrunk every time we add a new system call.
+	 */
+	.rept NR_syscalls-247
+		.long sys_ni_syscall
+	.endr
+
+	.section	.text64, "ax"
+
+/*
+ * --- Exception/Interrupt/Event Handling Section
+ */
+
+/*
+ * VBR and RESVEC blocks.
+ *
+ * First level handler for VBR-based exceptions.
+ *
+ * To avoid waste of space, align to the maximum text block size.
+ * This is assumed to be at most 128 bytes or 32 instructions.
+ * DO NOT EXCEED 32 instructions on the first level handlers !
+ *
+ * Also note that RESVEC is contained within the VBR block
+ * where the room left (1KB - TEXT_SIZE) allows placing
+ * the RESVEC block (at most 512B + TEXT_SIZE). 
+ * 
+ * So first (and only) level handler for RESVEC-based exceptions.
+ *
+ * Where the fault/interrupt is handled (not_a_tlb_miss, tlb_miss
+ * and interrupt) we are a lot tight with register space until
+ * saving onto the stack frame, which is done in handle_exception().
+ *
+ */
+
+#define	TEXT_SIZE 	128
+#define	BLOCK_SIZE 	1664 		/* Dynamic check, 13*128 */
+
+	.balign TEXT_SIZE
+LVBR_block:
+	.space	256, 0			/* Power-on class handler, */
+					/* not required here       */
+not_a_tlb_miss:
+	/* Save original stack pointer into KCR1 */
+	putcon	SP, KCR1
+
+	/* Save other original registers into reg_save_area */
+        _loada  reg_save_area, SP
+	st.q	SP, SAVED_R2, r2
+	st.q	SP, SAVED_R3, r3
+	st.q	SP, SAVED_R4, r4
+	st.q	SP, SAVED_R5, r5
+	st.q	SP, SAVED_R6, r6
+	st.q	SP, SAVED_R18, r18
+	gettr	t0, r3
+	st.q	SP, SAVED_T0, r3
+
+#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT
+	/* This use of DCR is not really legal, but there's nowhere else convenient to store this and it's only for last-resort debug anyway. */
+	movi    0x100, r3
+	putcon  r3, dcr
+#endif
+	
+	/* Set args for Non-debug, Not a TLB miss class handler */
+	getcon	EXPEVT, r2
+	_loada	ret_from_exception, r3
+	ori	r3, 1, r3
+	movi	EVENT_FAULT_NOT_TLB, r4
+	or	SP, ZERO, r5
+	getcon	KCR1, SP
+	_ptar	handle_exception, t0
+	blink	t0, ZERO
+
+	/*
+	 * Instead of the natural .balign 1024 place RESVEC here
+	 * respecting the final 1KB alignment.
+	 */
+	.balign TEXT_SIZE
+	/*
+	 * Instead of '.space 1024-TEXT_SIZE' place the RESVEC
+	 * block making sure the final alignment is correct.
+	 */
+LRESVEC_block:
+	/* Panic handler. Called with MMU off. Possible causes/actions:
+	 * - Reset:		Jump to program start.
+	 * - Single Step:	Turn off Single Step & return.
+	 * - Others:		Call panic handler, passing PC as arg.
+	 *			(this may need to be extended...)
+	 */
+reset_or_panic:
+	putcon	SP, DCR
+	/* First save r0-1 and tr0, as we need to use these */
+	_loada	resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP
+	st.q	SP, 0, r0
+	st.q	SP, 8, r1
+	gettr	t0, r0
+	st.q	SP, 32, r0
+	
+	/* Check cause */
+	getcon	EXPEVT, r0
+	movi	RESET_CAUSE, r1
+	sub	r1, r0, r1		/* r1=0 if reset */
+	_loada	_stext-CONFIG_CACHED_MEMORY_OFFSET, r0
+	ori	r0, 1, r0
+	ptabs	r0, t0
+	beqi	r1, 0, t0		/* Jump to start address if reset */
+
+	getcon	EXPEVT, r0
+	movi	DEBUGSS_CAUSE, r1
+	sub	r1, r0, r1		/* r1=0 if single step */
+	_ptar	single_step_panic, t0
+	beqi	r1, 0, t0		/* jump if single step */
+
+	/* If we get here, we have an unknown panic. Just call the panic
+	 * handler, passing saved PC. We never expect to return, so we can
+	 * use any regs now. */
+	getcon	SPC,r2
+	getcon	SSR,r3
+	getcon	EXPEVT,r4
+	/* Prepare to jump to C - physical address */
+	_loada	panic_handler-CONFIG_CACHED_MEMORY_OFFSET, r1
+	ori	r1, 1, r1
+	ptabs   r1, t0
+	getcon	DCR, SP
+	blink	t0, ZERO
+
+single_step_panic:
+	/* We are in a handler with Single Step set. We need to resume the
+	 * handler, by turning on MMU & turning off Single Step. */
+	getcon	SSR, r0
+	movi	SR_MMU, r1
+	or	r0, r1, r0
+	movi	~SR_SS, r1
+	and	r0, r1, r0
+	putcon	r0, SSR
+	/* Restore EXPEVT, as the rte won't do this */
+	getcon	PEXPEVT, r0
+	putcon	r0, EXPEVT
+	/* Restore regs */
+	ld.q	SP, 32, r0
+	ptabs	r0, tr0
+	ld.q	SP, 0, r0
+	ld.q	SP, 8, r1
+	getcon	DCR, SP
+	synco
+	rte
+
+	.balign	TEXT_SIZE
+debug_exception:
+	/*
+	 * Single step/software_break_point first level handler.
+	 * Called with MMU off, so the first thing we do is enable it
+	 * by doing an rte with appropriate SSR.
+	 */
+	putcon	SP, DCR
+	/* Save SSR & SPC, together with R0 & R1, as we need to use 2 regs. */
+	_loada	resvec_save_area-CONFIG_CACHED_MEMORY_OFFSET, SP
+
+	/* With the MMU off, we are bypassing the cache, so purge any 
+         * data that will be made stale by the following stores.
+         */
+	ocbp	SP, 0
+	synco
+
+	st.q	SP, 0, r0
+	st.q	SP, 8, r1
+	getcon	SPC, r0
+	st.q	SP, 16, r0
+	getcon	SSR, r0
+	st.q	SP, 24, r0
+
+	/* Enable MMU, block exceptions, set priv mode, disable single step */
+	movi	SR_MMU | SR_BL | SR_MD, r1
+	or	r0, r1, r0
+	movi	~SR_SS, r1
+	and	r0, r1, r0
+	putcon	r0, SSR
+	/* Force control to debug_exception_2 when rte is executed */
+	_loada	debug_exeception_2, r0
+	ori	r0, 1, r0      /* force SHmedia, just in case */
+	putcon	r0, SPC
+	getcon	DCR, SP
+	synco
+	rte
+debug_exeception_2:
+	/* Restore saved regs */
+	putcon	SP, KCR1
+	_loada	resvec_save_area, SP
+	ld.q	SP, 24, r0
+	putcon	r0, SSR
+	ld.q	SP, 16, r0
+	putcon	r0, SPC
+	ld.q	SP, 0, r0
+	ld.q	SP, 8, r1
+
+	/* Save other original registers into reg_save_area */
+        _loada  reg_save_area, SP
+	st.q	SP, SAVED_R2, r2
+	st.q	SP, SAVED_R3, r3
+	st.q	SP, SAVED_R4, r4
+	st.q	SP, SAVED_R5, r5
+	st.q	SP, SAVED_R6, r6
+	st.q	SP, SAVED_R18, r18
+	gettr	t0, r3
+	st.q	SP, SAVED_T0, r3
+
+	/* Set args for debug class handler */
+	getcon	EXPEVT, r2
+	_loada	ret_from_exception, r3
+	ori	r3, 1, r3
+	movi	EVENT_DEBUG, r4
+	or	SP, ZERO, r5
+	getcon	KCR1, SP
+	_ptar	handle_exception, t0
+	blink	t0, ZERO
+
+	.balign	TEXT_SIZE
+debug_interrupt:
+	/*
+	 * Not supported. If we ever get here loop forever
+	 * We may be MMUOFF or MMUON. Just use pic code.
+	 */
+	_ptar	debug_interrupt, t0
+	blink	t0, ZERO
+	.balign	TEXT_SIZE
+
+LRESVEC_block_end:			/* Marker. Unused. */
+tlb_miss:
+	putcon	SP, KCR1
+	_loada	reg_save_area, SP
+	/* SP is guaranteed 32-byte aligned. */
+	st.q	SP, TLB_SAVED_R0 , r0
+	st.q	SP, TLB_SAVED_R1 , r1
+	st.q	SP, SAVED_R2 , r2
+	st.q	SP, SAVED_R3 , r3
+	st.q	SP, SAVED_R4 , r4
+	st.q	SP, SAVED_R5 , r5
+	st.q	SP, SAVED_R6 , r6
+	st.q	SP, SAVED_R18, r18
+
+	/* Save R25 for safety; as/ld may want to use it to achieve the call to
+	 * the code in mm/tlbmiss.c */
+	st.q	SP, TLB_SAVED_R25, r25
+	gettr	tr0, r2
+	gettr	tr1, r3
+	gettr	tr2, r4
+	gettr	tr3, r5
+	gettr	tr4, r18
+	st.q	SP, SAVED_T0 , r2
+	st.q	SP, TLB_SAVED_T1 , r3
+	st.q	SP, TLB_SAVED_T2 , r4
+	st.q	SP, TLB_SAVED_T3 , r5
+	st.q	SP, TLB_SAVED_T4 , r18
+
+	pt	do_fast_page_fault, tr0
+	getcon	SSR, r2
+	getcon	EXPEVT, r3
+	getcon	TEA, r4
+	shlri	r2, 30, r2
+	andi	r2, 1, r2	/* r2 = SSR.MD */
+	blink 	tr0, r18
+
+	pt	fixup_to_invoke_general_handler, tr1
+
+	/* If the fast path handler fixed the fault, just drop through quickly
+	   to the restore code right away to return to the excepting context.
+	   */
+	beqi/u	r2, 0, tr1
+
+fast_tlb_miss_restore:
+	ld.q	SP, SAVED_T0, r2
+	ld.q	SP, TLB_SAVED_T1, r3
+	ld.q	SP, TLB_SAVED_T2, r4
+
+	ld.q	SP, TLB_SAVED_T3, r5
+	ld.q	SP, TLB_SAVED_T4, r18
+
+	ptabs	r2, tr0
+	ptabs	r3, tr1
+	ptabs	r4, tr2
+	ptabs	r5, tr3
+	ptabs	r18, tr4
+
+	ld.q	SP, TLB_SAVED_R0, r0
+	ld.q	SP, TLB_SAVED_R1, r1
+	ld.q	SP, SAVED_R2, r2
+	ld.q	SP, SAVED_R3, r3
+	ld.q	SP, SAVED_R4, r4
+	ld.q	SP, SAVED_R5, r5
+	ld.q	SP, SAVED_R6, r6
+	ld.q	SP, SAVED_R18, r18
+	ld.q	SP, TLB_SAVED_R25, r25
+
+	getcon	KCR1, SP
+	rte
+	nop /* for safety, in case the code is run on sh5-101 cut1.x */
+
+fixup_to_invoke_general_handler:
+
+	/* OK, new method.  Restore stuff that's not expected to get saved into
+	   the 'first-level' reg save area, then just fall through to setting
+	   up the registers and calling the second-level handler. */
+
+	/* 2nd level expects r2,3,4,5,6,18,tr0 to be saved.  So we must restore
+	   r25,tr1-4 and save r6 to get into the right state.  */
+
+	ld.q	SP, TLB_SAVED_T1, r3
+	ld.q	SP, TLB_SAVED_T2, r4
+	ld.q	SP, TLB_SAVED_T3, r5
+	ld.q	SP, TLB_SAVED_T4, r18
+	ld.q	SP, TLB_SAVED_R25, r25
+	
+	ld.q	SP, TLB_SAVED_R0, r0
+	ld.q	SP, TLB_SAVED_R1, r1
+
+	ptabs/u	r3, tr1
+	ptabs/u	r4, tr2
+	ptabs/u	r5, tr3
+	ptabs/u	r18, tr4
+
+#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT
+	/* This use of DCR is not really legal, but there's nowhere else convenient to store this and it's only for last-resort debug anyway. */
+	movi    0x400, r3
+	putcon  r3, dcr
+#endif
+
+	/* Set args for Non-debug, TLB miss class handler */
+	getcon	EXPEVT, r2
+	_loada	ret_from_exception, r3
+	ori	r3, 1, r3
+	movi	EVENT_FAULT_TLB, r4
+	or	SP, ZERO, r5
+	getcon	KCR1, SP
+	_ptar	handle_exception, t0
+	blink	t0, ZERO
+
+/* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE
+   DOES END UP AT VBR+0x600 */
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+#if 0
+	.balign 256
+	nop
+#endif
+	.balign 256
+	/* VBR + 0x600 */
+
+interrupt:
+	/* Save original stack pointer into KCR1 */
+	putcon	SP, KCR1
+
+	/* Save other original registers into reg_save_area */
+        _loada  reg_save_area, SP
+	st.q	SP, SAVED_R2, r2
+	st.q	SP, SAVED_R3, r3
+	st.q	SP, SAVED_R4, r4
+	st.q	SP, SAVED_R5, r5
+	st.q	SP, SAVED_R6, r6
+	st.q	SP, SAVED_R18, r18
+	gettr	t0, r3
+	st.q	SP, SAVED_T0, r3
+
+#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT
+	/* This use of DCR is not really legal, but there's nowhere else convenient to store this and it's only for last-resort debug anyway. */
+	movi    0x600, r3
+	putcon  r3, dcr
+#endif
+
+	/* Set args for interrupt class handler */
+	getcon	INTEVT, r2
+	_loada	ret_from_irq, r3
+	ori	r3, 1, r3
+	movi	EVENT_INTERRUPT, r4
+	or	SP, ZERO, r5
+	getcon	KCR1, SP
+	_ptar	handle_exception, t0
+	blink	t0, ZERO
+	.balign	TEXT_SIZE		/* let's waste the bare minimum */
+
+LVBR_block_end:				/* Marker. Used for total checking */
+	
+
+/*
+ * Second level handler for VBR-based exceptions. Pre-handler.
+ * In common to all stack-frame sensitive handlers.
+ *
+ * Inputs:
+ * (KCR0) Current [current task union]
+ * (KCR1) Original SP
+ * (r2)   INTEVT/EXPEVT
+ * (r3)   appropriate return address
+ * (r4)   Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault, 3=debug)
+ * (r5)   Pointer to reg_save_area
+ * (SP)   Original SP
+ *
+ * Available registers:
+ * (r6)
+ * (r18)
+ * (t0)
+ *
+ */
+handle_exception:
+	/* Common 2nd level handler. */
+
+	/* First thing we need an appropriate stack pointer */
+	getcon	SSR, r6
+	shlri	r6, 30, r6
+	andi	r6, 1, r6
+	_ptar	stack_ok, t0
+	bne	r6, ZERO, t0		/* Original stack pointer is fine */
+
+	/* Set stack pointer for user fault */
+	getcon	KCR0, SP
+	movi	THREAD_SIZE, r6		/* Point to the end */
+	add	SP, r6, SP
+
+stack_ok:
+	/* Make some room for the BASIC frame. */
+	movi	-(FRAME_SIZE), r6
+	add	SP, r6, SP
+
+/* Could do this with no stalling if we had another spare register, but the
+   code below will be OK. */
+	ld.q	r5, SAVED_R2, r6
+	ld.q	r5, SAVED_R3, r18
+	st.q	SP, FRAME_R(2), r6
+	ld.q	r5, SAVED_R4, r6
+	st.q	SP, FRAME_R(3), r18
+	ld.q	r5, SAVED_R5, r18
+	st.q	SP, FRAME_R(4), r6
+	ld.q	r5, SAVED_R6, r6
+	st.q	SP, FRAME_R(5), r18
+	ld.q	r5, SAVED_R18, r18
+	st.q	SP, FRAME_R(6), r6
+	ld.q	r5, SAVED_T0, r6
+	st.q	SP, FRAME_R(18), r18
+	st.q	SP, FRAME_T(0), r6
+
+	/* Keep old SP around */
+	getcon	KCR1, r6
+
+	/* Save the rest of the general purpose registers */
+	st.q	SP, FRAME_R(0), r0
+	st.q	SP, FRAME_R(1), r1
+	st.q	SP, FRAME_R(7), r7
+	st.q	SP, FRAME_R(8), r8
+	st.q	SP, FRAME_R(9), r9
+	st.q	SP, FRAME_R(10), r10
+	st.q	SP, FRAME_R(11), r11
+	st.q	SP, FRAME_R(12), r12
+	st.q	SP, FRAME_R(13), r13
+	st.q	SP, FRAME_R(14), r14
+
+	/* SP is somewhere else */
+	st.q	SP, FRAME_R(15), r6
+
+	st.q	SP, FRAME_R(16), r16
+	st.q	SP, FRAME_R(17), r17
+	/* r18 is saved earlier. */
+	st.q	SP, FRAME_R(19), r19
+	st.q	SP, FRAME_R(20), r20
+	st.q	SP, FRAME_R(21), r21
+	st.q	SP, FRAME_R(22), r22
+	st.q	SP, FRAME_R(23), r23
+	st.q	SP, FRAME_R(24), r24
+	st.q	SP, FRAME_R(25), r25
+	st.q	SP, FRAME_R(26), r26
+	st.q	SP, FRAME_R(27), r27
+	st.q	SP, FRAME_R(28), r28
+	st.q	SP, FRAME_R(29), r29
+	st.q	SP, FRAME_R(30), r30
+	st.q	SP, FRAME_R(31), r31
+	st.q	SP, FRAME_R(32), r32
+	st.q	SP, FRAME_R(33), r33
+	st.q	SP, FRAME_R(34), r34
+	st.q	SP, FRAME_R(35), r35
+	st.q	SP, FRAME_R(36), r36
+	st.q	SP, FRAME_R(37), r37
+	st.q	SP, FRAME_R(38), r38
+	st.q	SP, FRAME_R(39), r39
+	st.q	SP, FRAME_R(40), r40
+	st.q	SP, FRAME_R(41), r41
+	st.q	SP, FRAME_R(42), r42
+	st.q	SP, FRAME_R(43), r43
+	st.q	SP, FRAME_R(44), r44
+	st.q	SP, FRAME_R(45), r45
+	st.q	SP, FRAME_R(46), r46
+	st.q	SP, FRAME_R(47), r47
+	st.q	SP, FRAME_R(48), r48
+	st.q	SP, FRAME_R(49), r49
+	st.q	SP, FRAME_R(50), r50
+	st.q	SP, FRAME_R(51), r51
+	st.q	SP, FRAME_R(52), r52
+	st.q	SP, FRAME_R(53), r53
+	st.q	SP, FRAME_R(54), r54
+	st.q	SP, FRAME_R(55), r55
+	st.q	SP, FRAME_R(56), r56
+	st.q	SP, FRAME_R(57), r57
+	st.q	SP, FRAME_R(58), r58
+	st.q	SP, FRAME_R(59), r59
+	st.q	SP, FRAME_R(60), r60
+	st.q	SP, FRAME_R(61), r61
+	st.q	SP, FRAME_R(62), r62
+
+	/*
+	 * Save the S* registers.
+	 */
+	getcon	SSR, r61
+	st.q	SP, FRAME_S(FSSR), r61
+	getcon	SPC, r62
+	st.q	SP, FRAME_S(FSPC), r62
+	movi	-1, r62			/* Reset syscall_nr */
+	st.q	SP, FRAME_S(FSYSCALL_ID), r62
+
+	/* Save the rest of the target registers */
+	gettr	t1, r6
+	st.q	SP, FRAME_T(1), r6
+	gettr	t2, r6
+	st.q	SP, FRAME_T(2), r6
+	gettr	t3, r6
+	st.q	SP, FRAME_T(3), r6
+	gettr	t4, r6
+	st.q	SP, FRAME_T(4), r6
+	gettr	t5, r6
+	st.q	SP, FRAME_T(5), r6
+	gettr	t6, r6
+	st.q	SP, FRAME_T(6), r6
+	gettr	t7, r6
+	st.q	SP, FRAME_T(7), r6
+
+/*#define POOR_MANS_STRACE 1*/
+	
+#ifdef POOR_MANS_STRACE
+	/* We've pushed all the registers now, so only r2-r4 hold anything
+	 * useful. Move them into callee save registers */
+	or	r2, ZERO, r28
+	or	r3, ZERO, r29
+	or	r4, ZERO, r30
+
+	/* Preserve r2 as the event code */
+	_loada	evt_debug, r3
+	ori	r3, 1, r3
+	ptabs	r3, t0
+
+	/* or	SP, ZERO, r5 */
+	getcon	TRA, r5
+	blink	t0, LINK
+
+	or	r28, ZERO, r2
+	or	r29, ZERO, r3
+	or	r30, ZERO, r4
+#endif
+
+	
+	/* For syscall and debug race condition, get TRA now */
+	getcon	TRA, r5
+	
+	/* We are in a safe position to turn SR.BL off, but set IMASK=0xf
+	 * Also set FD, to catch FPU usage in the kernel.
+	 *
+	 * benedict.gaster@superh.com 29/07/2002
+	 *
+	 * On all SH5-101 revisions it is unsafe to raise the IMASK and at the 
+	 * same time change BL from 1->0, as any pending interrupt of a level
+	 * higher than he previous value of IMASK will leak through and be 
+	 * taken unexpectedly.
+	 *
+	 * To avoid this we raise the IMASK and then issue another PUTCON to
+	 * enable interrupts.
+         */
+	getcon	SR, r6
+	movi	SR_IMASK | SR_FD, r7
+	or	r6, r7, r6
+	putcon	r6, SR
+	movi	SR_UNBLOCK_EXC, r7
+	and	r6, r7, r6
+	putcon	r6, SR
+
+	
+	/* Now call the appropriate 3rd level handler */
+	or	r3, ZERO, LINK
+	_loada	trap_jtable, r3
+	shlri	r2, 3, r2
+	ldx.l	r2, r3, r3
+	shlri	r2, 2, r2
+	ptabs	r3, t0
+	or	SP, ZERO, r3
+	blink	t0, ZERO
+
+/*
+ * Second level handler for VBR-based exceptions. Post-handlers.
+ *
+ * Post-handlers for interrupts (ret_from_irq), exceptions
+ * (ret_from_exception) and common reentrance doors (restore_all
+ * to get back to the original context, ret_from_syscall loop to
+ * check kernel exiting).
+ *
+ * ret_with_reschedule and check_signals are an inner lables of
+ * the ret_from_syscall loop.
+ *
+ * In common to all stack-frame sensitive handlers.
+ *
+ * Inputs:
+ * (SP)   struct pt_regs *, original register's frame pointer (basic)
+ *
+ */
+ret_from_irq:
+	ld.q	SP, FRAME_S(FSSR), r6
+	shlri	r6, 30, r6
+	andi	r6, 1, r6
+	_ptar	restore_all, t0
+	bne	r6, ZERO, t0		/* no further checks */
+	STI()
+	_ptar	ret_with_reschedule, t0
+	blink	t0, ZERO		/* Do not check softirqs */
+	
+ret_from_exception:
+	ld.q	SP, FRAME_S(FSSR), r6
+	shlri	r6, 30, r6
+	andi	r6, 1, r6
+	_ptar	restore_all, t0
+	bne	r6, ZERO, t0		/* no further checks */
+
+	/* Check softirqs */
+
+	/*
+	 * Fall-through:
+	 * _ptar   ret_from_syscall, t0
+	 * blink   t0, ZERO
+	 */
+
+ret_from_syscall:
+	
+ret_with_reschedule:
+	getcon	KCR0, r6
+	ld.l	r6, need_resched, r7
+	_ptar	check_signals, t0
+	beq	r7, ZERO, t0
+
+	_ptar	ret_from_syscall, t0
+	gettr	t0, LINK
+	_loada	schedule, r6
+	ptabs	r6, t0
+	blink	t0, ZERO		/* Call schedule(), return on top */
+
+check_signals:
+	getcon	KCR0, r6
+	ld.l	r6, sigpending, r7
+	_ptar	restore_all, t0
+	beq	r7, ZERO, t0
+
+	_loada	do_signal, r6
+	ptabs	r6, t0
+	or	SP, ZERO, r2
+	or	ZERO, ZERO, r3
+	blink	t0, LINK	    /* Call do_signal(regs, 0), return here */
+	
+#ifdef CONFIG_SH64_PAGE_TABLE_AUDIT
+	/* Check page tables before returning (with obvious performance penalty). */
+	_loada  audit_mm, r6
+	ptabs   r6, t0
+	getcon  expevt, r2
+	getcon  intevt, r3
+	getcon  tra, r4
+	getcon  dcr, r5
+	blink   t0, LINK
+#endif
+
+restore_all:
+	/* Do prefetches */
+	
+	ld.q	SP, FRAME_T(0), r6
+	ld.q	SP, FRAME_T(1), r7
+	ld.q	SP, FRAME_T(2), r8
+	ld.q	SP, FRAME_T(3), r9
+	ptabs	r6, t0
+	ptabs	r7, t1
+	ptabs	r8, t2
+	ptabs	r9, t3
+	ld.q	SP, FRAME_T(4), r6
+	ld.q	SP, FRAME_T(5), r7
+	ld.q	SP, FRAME_T(6), r8
+	ld.q	SP, FRAME_T(7), r9
+	ptabs	r6, t4
+	ptabs	r7, t5
+	ptabs	r8, t6
+	ptabs	r9, t7
+
+	ld.q	SP, FRAME_R(0), r0
+	ld.q	SP, FRAME_R(1), r1
+	ld.q	SP, FRAME_R(2), r2
+	ld.q	SP, FRAME_R(3), r3
+	ld.q	SP, FRAME_R(4), r4
+	ld.q	SP, FRAME_R(5), r5
+	ld.q	SP, FRAME_R(6), r6
+	ld.q	SP, FRAME_R(7), r7
+	ld.q	SP, FRAME_R(8), r8
+	ld.q	SP, FRAME_R(9), r9
+	ld.q	SP, FRAME_R(10), r10
+	ld.q	SP, FRAME_R(11), r11
+	ld.q	SP, FRAME_R(12), r12
+	ld.q	SP, FRAME_R(13), r13
+	ld.q	SP, FRAME_R(14), r14
+
+	ld.q	SP, FRAME_R(16), r16
+	ld.q	SP, FRAME_R(17), r17
+	ld.q	SP, FRAME_R(18), r18
+	ld.q	SP, FRAME_R(19), r19
+	ld.q	SP, FRAME_R(20), r20
+	ld.q	SP, FRAME_R(21), r21
+	ld.q	SP, FRAME_R(22), r22
+	ld.q	SP, FRAME_R(23), r23
+	ld.q	SP, FRAME_R(24), r24
+	ld.q	SP, FRAME_R(25), r25
+	ld.q	SP, FRAME_R(26), r26
+	ld.q	SP, FRAME_R(27), r27
+	ld.q	SP, FRAME_R(28), r28
+	ld.q	SP, FRAME_R(29), r29
+	ld.q	SP, FRAME_R(30), r30
+	ld.q	SP, FRAME_R(31), r31
+	ld.q	SP, FRAME_R(32), r32
+	ld.q	SP, FRAME_R(33), r33
+	ld.q	SP, FRAME_R(34), r34
+	ld.q	SP, FRAME_R(35), r35
+	ld.q	SP, FRAME_R(36), r36
+	ld.q	SP, FRAME_R(37), r37
+	ld.q	SP, FRAME_R(38), r38
+	ld.q	SP, FRAME_R(39), r39
+	ld.q	SP, FRAME_R(40), r40
+	ld.q	SP, FRAME_R(41), r41
+	ld.q	SP, FRAME_R(42), r42
+	ld.q	SP, FRAME_R(43), r43
+	ld.q	SP, FRAME_R(44), r44
+	ld.q	SP, FRAME_R(45), r45
+	ld.q	SP, FRAME_R(46), r46
+	ld.q	SP, FRAME_R(47), r47
+	ld.q	SP, FRAME_R(48), r48
+	ld.q	SP, FRAME_R(49), r49
+	ld.q	SP, FRAME_R(50), r50
+	ld.q	SP, FRAME_R(51), r51
+	ld.q	SP, FRAME_R(52), r52
+	ld.q	SP, FRAME_R(53), r53
+	ld.q	SP, FRAME_R(54), r54
+	ld.q	SP, FRAME_R(55), r55
+	ld.q	SP, FRAME_R(56), r56
+	ld.q	SP, FRAME_R(57), r57
+	ld.q	SP, FRAME_R(58), r58
+
+	getcon	SR, r59
+	movi	SR_BLOCK_EXC, r60
+	or	r59, r60, r59
+	putcon	r59, SR			/* SR.BL = 1, keep nesting out */
+	ld.q	SP, FRAME_S(FSSR), r61
+	ld.q	SP, FRAME_S(FSPC), r62
+	movi	SR_ASID_MASK, r60
+	and	r59, r60, r59
+	andc	r61, r60, r61		/* Clear out older ASID */
+	or	r59, r61, r61		/* Retain current ASID */
+	putcon	r61, SSR
+	putcon	r62, SPC
+
+	/* Ignore FSYSCALL_ID */
+
+	ld.q	SP, FRAME_R(59), r59
+	ld.q	SP, FRAME_R(60), r60
+	ld.q	SP, FRAME_R(61), r61
+	ld.q	SP, FRAME_R(62), r62
+
+	/* Last touch */
+	ld.q	SP, FRAME_R(15), SP
+	rte
+	nop
+
+/*
+ * Third level handlers for VBR-based exceptions. Adapting args to
+ * and/or deflecting to fourth level handlers.
+ *
+ * Fourth level handlers interface.
+ * Most are C-coded handlers directly pointed by the trap_jtable.
+ * (Third = Fourth level)
+ * Inputs:
+ * (r2)   fault/interrupt code, entry number (e.g. NMI = 14,
+ *	  IRL0-3 (0000) = 16, RTLBMISS = 2, SYSCALL = 11, etc ...)
+ * (r3)   struct pt_regs *, original register's frame pointer
+ * (r4)   Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault)
+ * (r5)   TRA control register (for syscall/debug benefit only)
+ * (LINK) return address
+ * (SP)   = r3
+ *
+ * Kernel TLB fault handlers will get a slightly different interface.
+ * (r2)   struct pt_regs *, original register's frame pointer
+ * (r3)   writeaccess, whether it's a store fault as opposed to load fault
+ * (r4)   execaccess, whether it's a ITLB fault as opposed to DTLB fault
+ * (r5)   Effective Address of fault
+ * (LINK) return address
+ * (SP)   = r2
+ *
+ * fpu_error_or_IRQ? is a helper to deflect to the right cause.
+ *
+ */
+tlb_miss_load:
+	or	SP, ZERO, r2
+	or	ZERO, ZERO, r3		/* Read */
+	or	ZERO, ZERO, r4		/* Data */
+	getcon	TEA, r5
+	_ptar	call_do_page_fault, t0
+	beq	ZERO, ZERO, tr0
+
+tlb_miss_store:
+	or	SP, ZERO, r2
+	movi	1, r3			/* Write */
+	or	ZERO, ZERO, r4		/* Data */
+	getcon	TEA, r5
+	_ptar	call_do_page_fault, t0
+	beq	ZERO, ZERO, tr0
+
+itlb_miss_or_IRQ:
+	_ptar	its_IRQ, t0
+	beqi/u	r4, EVENT_INTERRUPT, t0
+	or	SP, ZERO, r2
+	or	ZERO, ZERO, r3		/* Read */
+	movi	1, r4			/* Text */
+	getcon	TEA, r5
+	/* Fall through */
+
+call_do_page_fault:
+	_loada	do_page_fault, r6
+        ptabs	r6, t0
+        blink	t0, ZERO	
+	
+fpu_error_or_IRQA:
+	_ptar	its_IRQ, t0
+	beqi/l	r4, EVENT_INTERRUPT, t0
+#ifndef CONFIG_NOFPU_SUPPORT 
+	_loada	do_fpu_state_restore, r6
+#else
+	_loada	do_exception_error, r6
+#endif
+	ptabs	r6, t0
+	blink	t0, ZERO
+
+fpu_error_or_IRQB:
+	_ptar	its_IRQ, t0
+	beqi/l	r4, EVENT_INTERRUPT, t0
+#ifndef CONFIG_NOFPU_SUPPORT
+	_loada	do_fpu_state_restore, r6
+#else
+	_loada	do_exception_error, r6
+#endif
+	ptabs	r6, t0
+	blink	t0, ZERO
+
+its_IRQ:
+	_loada	do_IRQ, r6
+	ptabs	r6, t0
+	blink	t0, ZERO
+
+/*
+ * system_call/unknown_trap third level handler:
+ * 
+ * Inputs:
+ * (r2)   fault/interrupt code, entry number (TRAP = 11)
+ * (r3)   struct pt_regs *, original register's frame pointer
+ * (r4)   Not used. Event (0=interrupt, 1=TLB miss fault, 2=Not TLB miss fault)
+ * (r5)   TRA Control Reg (0x00xyzzzz: x=1 SYSCALL, y = #args, z=nr)
+ * (SP)   = r3
+ * (LINK) return address: ret_from_exception
+ * (*r3)  Syscall parms: SC#, arg0, arg1, ..., arg5 in order (Saved r2/r7)
+ *
+ * Outputs:
+ * (*r3)  Syscall reply (Saved r2)
+ * (LINK) In case of syscall only it can be scrapped.
+ *        Common second level post handler will be ret_from_syscall.
+ *        Common (non-trace) exit point to that is syscall_ret (saving
+ *        result to r2). Common bad exit point is syscall_bad (returning
+ *        ENOSYS then saved to r2).
+ *
+ */
+
+unknown_trap:
+	/* Unknown Trap or User Trace */
+	_loada	do_unknown_trapa, r6
+	ptabs	r6, t0
+        ld.q    r3, FRAME_R(9), r2	/* r2 = #arg << 16 | syscall # */
+        andi    r2, 0x1ff, r2		/* r2 = syscall # */
+	blink	t0, LINK
+
+	_ptar	syscall_ret, t0
+	blink	t0, ZERO
+
+        /* New syscall implementation*/
+system_call:
+	_ptar	unknown_trap, t0
+        or      r5, ZERO, r4            /* TRA (=r5) -> r4 */
+        shlri   r4, 20, r4
+	bnei	r4, 1, t0		/* unknown_trap if not 0x1yzzzz */
+
+        /* It's a system call */
+	st.q    r3, FRAME_S(FSYSCALL_ID), r5 	/* ID (0x1yzzzz) -> stack */
+	andi    r5, 0x1ff, r5			/* syscall # -> r5	  */
+
+	STI()
+
+	_ptar	syscall_allowed, t0
+	movi	NR_syscalls - 1, r4	/* Last valid */
+	bgeu/l	r4, r5, t0
+
+syscall_bad:
+	/* Return ENOSYS ! */
+	movi	-(ENOSYS), r2		/* Fall-through */
+syscall_ret:
+	st.q	SP, FRAME_R(9), r2	/* Expecting SP back to BASIC frame */
+
+#ifdef POOR_MANS_STRACE
+	/* nothing useful in registers at this point */
+
+	_loada	evt_debug2, r5
+	ori	r5, 1, r5
+	ptabs	r5, t0
+	ld.q	SP, FRAME_R(9), r2
+	or	SP, ZERO, r3
+	blink	t0, LINK
+#endif
+	
+	ld.q	SP, FRAME_S(FSPC), r2
+	addi	r2, 4, r2		/* Move PC, being pre-execution event */
+	st.q	SP, FRAME_S(FSPC), r2
+	_ptar	ret_from_syscall, t0
+	blink	t0, ZERO
+
+
+/*  A different return path for ret_from_fork, because we now need 
+ *  to call schedule_tail with the later kernels. Because prev is
+ *  loaded into r2 by switch_to() means we can just call it straight  away
+ */
+	
+.global	ret_from_fork
+ret_from_fork:
+
+	_loada	schedule_tail,r5
+	ori	r5, 1, r5
+	ptabs	r5, t0
+	blink	t0, LINK
+	
+#ifdef POOR_MANS_STRACE
+	/* nothing useful in registers at this point */
+
+	_loada	evt_debug2, r5
+	ori	r5, 1, r5
+	ptabs	r5, t0
+	ld.q	SP, FRAME_R(9), r2
+	or	SP, ZERO, r3
+	blink	t0, LINK
+#endif
+	
+	ld.q	SP, FRAME_S(FSPC), r2
+	addi	r2, 4, r2		/* Move PC, being pre-execution event */
+	st.q	SP, FRAME_S(FSPC), r2
+	_ptar	ret_from_syscall, t0
+	blink	t0, ZERO
+	
+	
+		
+syscall_allowed:
+	/* Use LINK to deflect the exit point, default is syscall_ret */
+	_ptar	syscall_ret, t0
+	gettr	t0, LINK
+	_ptar	syscall_notrace, t0
+
+	getcon	KCR0, r2
+	ld.l	r2, ptrace, r4
+	andi	r4, PT_TRACESYS, r4
+	beq/l	r4, ZERO, t0
+
+	/* Trace it by calling syscall_trace before and after */
+	_loada	syscall_trace, r4
+	ptabs	r4, t0
+	blink	t0, LINK
+	/* Reload syscall number as r5 is trashed by syscall_trace */
+	ld.q	SP, FRAME_S(FSYSCALL_ID), r5
+	andi	r5, 0x1ff, r5
+
+	_ptar	syscall_ret_trace, t0
+	gettr	t0, LINK
+
+syscall_notrace:
+	/* Now point to the appropriate 4th level syscall handler */
+	_loada	sys_call_table, r4
+	shlli	r5, 2, r5
+	ldx.l	r4, r5, r5
+	ptabs	r5, t0
+
+	/* Prepare original args */
+	ld.q	SP, FRAME_R(2), r2
+	ld.q	SP, FRAME_R(3), r3
+	ld.q	SP, FRAME_R(4), r4
+	ld.q	SP, FRAME_R(5), r5
+	ld.q	SP, FRAME_R(6), r6
+	ld.q	SP, FRAME_R(7), r7
+
+	/* And now the trick for those syscalls requiring regs * ! */
+	or	SP, ZERO, r8
+
+	/* Call it */
+	blink	t0, ZERO	/* LINK is already properly set */
+
+syscall_ret_trace:
+	/* We get back here only if under trace */
+	st.q	SP, FRAME_R(9), r2	/* Save return value */
+
+	/*  ... usage of a pt relative (_ptar _syscall_trace) fails on CDC */
+	_loada	syscall_trace, LINK
+	ptabs	LINK, t0
+	blink	t0, LINK
+
+	/* This needs to be done after any syscall tracing */
+	ld.q	SP, FRAME_S(FSPC), r2
+	addi	r2, 4, r2	/* Move PC, being pre-execution event */
+	st.q	SP, FRAME_S(FSPC), r2
+
+	_ptar	ret_from_syscall, t0
+	blink	t0, ZERO		/* Resume normal return sequence */
+
+/*
+ * --- Switch to running under a particular ASID and return the previous ASID value
+ * --- The caller is assumed to have done a cli before calling this.
+ *
+ * Input r2 : new ASID
+ * Output r2 : old ASID
+ */
+
+	.global switch_and_save_asid
+switch_and_save_asid:
+	getcon	sr, r0
+	movi	255, r4
+	shlli 	r4, 16, r4	/* r4 = mask to select ASID */
+	and	r0, r4, r3	/* r3 = shifted old ASID */
+	andi	r2, 255, r2	/* mask down new ASID */
+	shlli	r2, 16, r2	/* align new ASID against SR.ASID */
+	andc	r0, r4, r0	/* efface old ASID from SR */
+	or	r0, r2, r0	/* insert the new ASID */
+	putcon	r0, ssr
+	_loada	1f, r0
+	putcon	r0, spc
+	rte
+	nop
+1:
+	ptabs	r18, tr0
+	shlri	r3, 16, r2	/* r2 = old ASID */
+	blink tr0, r63
+
+	.global	route_to_panic_handler
+route_to_panic_handler:
+	/* Switch to real mode, goto panic_handler, don't return.  Useful for
+	   last-chance debugging, e.g. if no output wants to go to the console.
+	   */
+
+	_loada	panic_handler - CONFIG_CACHED_MEMORY_OFFSET, r1
+	ptabs	r1, tr0
+	pta	1f, tr1
+	gettr	tr1, r0
+	putcon	r0, spc
+	getcon	sr, r0
+	movi	1, r1
+	shlli	r1, 31, r1
+	andc	r0, r1, r0
+	putcon	r0, ssr
+	rte
+	nop
+1:	/* Now in real mode */
+	blink tr0, r63
+	nop
+
+	.global peek_real_address_q
+peek_real_address_q:
+	/* Two args:
+	   r2 : real mode address to peek
+	   r2(out) : result quadword
+
+	   This is provided as a cheapskate way of manipulating device
+	   registers for debugging (to avoid the need to onchip_remap the debug
+	   module, and to avoid the need to onchip_remap the watchpoint
+	   controller in a way that identity maps sufficient bits to avoid the
+	   SH5-101 cut2 silicon defect).
+
+	   This code is not performance critical
+	*/
+
+	add.l	r2, r63, r2	/* sign extend address */
+	getcon	sr, r0		/* r0 = saved original SR */
+	movi	1, r1
+	shlli	r1, 28, r1
+	or	r0, r1, r1	/* r0 with block bit set */
+	putcon	r1, sr		/* now in critical section */
+	movi	1, r36
+	shlli	r36, 31, r36
+	andc	r1, r36, r1	/* turn sr.mmu off in real mode section */
+
+	putcon	r1, ssr
+	_loada	.peek0 - CONFIG_CACHED_MEMORY_OFFSET, r36 /* real mode target address */
+	_loada	1f, r37		/* virtual mode return addr */
+	putcon	r36, spc
+
+	synco
+	rte
+	nop
+
+.peek0:	/* come here in real mode, don't touch caches!!
+           still in critical section (sr.bl==1) */
+	putcon	r0, ssr
+	putcon	r37, spc
+	/* Here's the actual peek.  If the address is bad, all bets are now off
+	 * what will happen (handlers invoked in real-mode = bad news) */
+	ld.q	r2, 0, r2
+	synco
+	rte	/* Back to virtual mode */
+	nop
+
+1:
+	ptabs	r18, tr0
+	blink	tr0, r63
+
+	.global poke_real_address_q
+poke_real_address_q:
+	/* Two args:
+	   r2 : real mode address to poke
+	   r3 : quadword value to write.
+
+	   This is provided as a cheapskate way of manipulating device
+	   registers for debugging (to avoid the need to onchip_remap the debug
+	   module, and to avoid the need to onchip_remap the watchpoint
+	   controller in a way that identity maps sufficient bits to avoid the
+	   SH5-101 cut2 silicon defect).
+
+	   This code is not performance critical
+	*/
+
+	add.l	r2, r63, r2	/* sign extend address */
+	getcon	sr, r0		/* r0 = saved original SR */
+	movi	1, r1
+	shlli	r1, 28, r1
+	or	r0, r1, r1	/* r0 with block bit set */
+	putcon	r1, sr		/* now in critical section */
+	movi	1, r36
+	shlli	r36, 31, r36
+	andc	r1, r36, r1	/* turn sr.mmu off in real mode section */
+
+	/* Bodge : force sr.watch high on return.  Can't understand why else this
+	   isn't happening. */
+	movi	1, r38
+	shlli	r38, 26, r38
+	or	r38, r0, r0
+
+	putcon	r1, ssr
+	_loada	.poke0-CONFIG_CACHED_MEMORY_OFFSET, r36 /* real mode target address */
+	_loada	1f, r37		/* virtual mode return addr */
+	putcon	r36, spc
+
+	synco
+	rte
+	nop
+
+.poke0:	/* come here in real mode, don't touch caches!!
+           still in critical section (sr.bl==1) */
+	putcon	r0, ssr
+	putcon	r37, spc
+	/* Here's the actual poke.  If the address is bad, all bets are now off
+	 * what will happen (handlers invoked in real-mode = bad news) */
+	st.q	r2, 0, r3
+	synco
+	rte	/* Back to virtual mode */
+	nop
+
+1:
+	ptabs	r18, tr0
+	blink	tr0, r63
+
+/*
+ * --- User Access Handling Section
+ */
+
+/*
+ * User Access support. It all moved to non inlined Assembler
+ * functions in here.
+ *
+ * __kernel_size_t __copy_user(void *__to, const void *__from,
+ *			       __kernel_size_t __n)
+ *
+ * Inputs:
+ * (r2)  target address
+ * (r3)  source address
+ * (r4)  size in bytes
+ *
+ * Ouputs:
+ * (*r2) target data
+ * (r2)  non-copied bytes
+ *
+ * If a fault occurs on the user pointer, bail out early and return the
+ * number of bytes not copied in r2.
+ * Strategy : for large blocks, call a real memcpy function which can
+ * move >1 byte at a time using unaligned ld/st instructions, and can
+ * manipulate the cache using prefetch + alloco to improve the speed
+ * further.  If a fault occurs in that function, just revert to the
+ * byte-by-byte approach used for small blocks; this is rare so the
+ * performance hit for that case does not matter.
+ *
+ * For small blocks it's not worth the overhead of setting up and calling
+ * the memcpy routine; do the copy a byte at a time.
+ *
+ */
+	.global	__copy_user
+__copy_user:
+	_ptar	__copy_user_byte_by_byte, t1
+	movi	16, r0 ! this value is a best guess, should tune it by benchmarking
+	bge/u	r0, r4, t1
+	_ptar copy_user_memcpy, t0
+	addi	r15, -32, r15
+	/* Save arguments in case we have to fix-up unhandled page fault */
+	st.q	r15, 0, r2
+	st.q	r15, 8, r3
+	st.q	r15, 16, r4
+	st.q	r15, 24, r35 ! r35 is callee-save
+	/* Save LINK in a register to reduce RTS time later (otherwise
+	   ld r15,*,LINK;ptabs LINK;trn;blink trn,r63 becomes a critical path) */
+	ori	LINK, 0, r35
+	blink	t0, LINK
+
+	/* Copy completed normally if we get back here */
+	ptabs	r35, tr0
+	ld.q	r15, 24, r35
+	/* don't restore r2-r4, pointless */
+	/* set result=r2 to zero as the copy must have succeeded. */
+	or	r63, r63, r2
+	addi	r15, 32, r15
+	blink	tr0, r63 ! RTS
+
+	.global __copy_user_fixup
+__copy_user_fixup:
+	/* Restore stack frame */
+	ori	r35, 0, LINK
+	ld.q	r15, 24, r35
+	ld.q	r15, 16, r4
+	ld.q	r15,  8, r3
+	ld.q	r15,  0, r2
+	addi	r15, 32, r15
+	/* Fall through to original code, in the 'same' state we entered with */
+
+/* The slow byte-by-byte method is used if the fast copy traps due to a bad
+   user address.  In that rare case, the speed drop can be tolerated. */
+__copy_user_byte_by_byte:
+	_ptar	___copy_user_exit, t1
+	_ptar	___copy_user1, t0
+	beq/u	r4, r63, t1	/* early exit for zero length copy */
+	sub	r2, r3, r0
+	addi	r0, -1, r0
+
+___copy_user1:
+	ld.b	r3, 0, r5		/* Fault address 1 */
+
+	/* Could rewrite this to use just 1 add, but the second comes 'free'
+	   due to load latency */
+	addi	r3, 1, r3
+	addi	r4, -1, r4		/* No real fixup required */
+___copy_user2:
+	stx.b	r3, r0, r5		/* Fault address 2 */
+	bne     r4, ZERO, t0
+
+___copy_user_exit:
+	or	r4, ZERO, r2
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+/*
+ * __kernel_size_t __clear_user(void *addr, __kernel_size_t size)
+ *
+ * Inputs:
+ * (r2)  target address
+ * (r3)  size in bytes
+ *
+ * Ouputs:
+ * (*r2) zero-ed target data
+ * (r2)  non-zero-ed bytes
+ */
+	.global	__clear_user
+__clear_user:
+	_ptar	___clear_user_exit, t1
+	_ptar	___clear_user1, t0
+	beq/u	r3, r63, t1
+
+___clear_user1:
+	st.b	r2, 0, ZERO		/* Fault address */
+	addi	r2, 1, r2
+	addi	r3, -1, r3		/* No real fixup required */
+	bne     r3, ZERO, t0
+
+___clear_user_exit:
+	or	r3, ZERO, r2
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+/*
+ * int __strncpy_from_user(unsigned long __dest, unsigned long __src,
+ *			   int __count)
+ *
+ * Inputs:
+ * (r2)  target address
+ * (r3)  source address
+ * (r4)  maximum size in bytes
+ *
+ * Ouputs:
+ * (*r2) copied data
+ * (r2)  -EFAULT (in case of faulting)
+ *       copied data (otherwise)
+ */
+	.global	__strncpy_from_user
+__strncpy_from_user:
+	_ptar	___strncpy_from_user1, t0
+	_ptar	___strncpy_from_user_done, t1
+	or	r4, ZERO, r5		/* r5 = original count */
+	beq/u	r4, r63, t1		/* early exit if r4==0 */
+	movi	-(EFAULT), r6		/* r6 = reply, no real fixup */
+	or	ZERO, ZERO, r7		/* r7 = data, clear top byte of data */
+
+___strncpy_from_user1:
+	ld.b	r3, 0, r7		/* Fault address: only in reading */
+	st.b	r2, 0, r7
+	addi	r2, 1, r2
+	addi	r3, 1, r3
+	beq/u	ZERO, r7, t1
+	addi	r4, -1, r4		/* return real number of copied bytes */
+	bne/l	ZERO, r4, t0
+
+___strncpy_from_user_done:
+	sub	r5, r4, r6		/* If done, return copied */
+	
+___strncpy_from_user_exit:
+	or	r6, ZERO, r2
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+/*
+ * extern long __strnlen_user(const char *__s, long __n)
+ *
+ * Inputs:
+ * (r2)  source address
+ * (r3)  source size in bytes
+ *
+ * Ouputs:
+ * (r2)  -EFAULT (in case of faulting)
+ *       string length (otherwise)
+ */
+	.global	__strnlen_user
+__strnlen_user:
+	_ptar	___strnlen_user_set_reply, t0
+	_ptar	___strnlen_user1, t1
+	or	ZERO, ZERO, r5		/* r5 = counter */
+	movi	-(EFAULT), r6		/* r6 = reply, no real fixup */
+	or	ZERO, ZERO, r7		/* r7 = data, clear top byte of data */
+	beq	r3, ZERO, t0
+
+___strnlen_user1:
+	ldx.b	r2, r5, r7		/* Fault address: only in reading */
+	addi	r3, -1, r3		/* No real fixup */
+	addi	r5, 1, r5
+	beq	r3, ZERO, t0
+	bne	r7, ZERO, t1
+! The line below used to be active.  This meant led to a junk byte lying between each pair
+! of entries in the argv & envp structures in memory.  Whilst the program saw the right data
+! via the argv and envp arguments to main, it meant the 'flat' representation visible through
+! /proc/$pid/cmdline was corrupt, causing trouble with ps, for example.
+!	addi	r5, 1, r5		/* Include '\0' */
+
+___strnlen_user_set_reply:
+	or	r5, ZERO, r6		/* If done, return counter */
+	
+___strnlen_user_exit:
+	or	r6, ZERO, r2
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+/*
+ * extern long __get_user_asm_?(void *val, long addr)
+ *
+ * Inputs:
+ * (r2)  dest address
+ * (r3)  source address (in User Space)
+ *
+ * Ouputs:
+ * (r2)  -EFAULT (faulting)
+ *       0 	 (not faulting)
+ */
+	.global	__get_user_asm_b
+__get_user_asm_b:
+	or	r2, ZERO, r4
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___get_user_asm_b1:
+	ld.b	r3, 0, r5		/* r5 = data */
+	st.b	r4, 0, r5
+	or	ZERO, ZERO, r2
+	
+___get_user_asm_b_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+	.global	__get_user_asm_w
+__get_user_asm_w:
+	or	r2, ZERO, r4
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___get_user_asm_w1:
+	ld.w	r3, 0, r5		/* r5 = data */
+	st.w	r4, 0, r5
+	or	ZERO, ZERO, r2
+	
+___get_user_asm_w_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+	.global	__get_user_asm_l
+__get_user_asm_l:
+	or	r2, ZERO, r4
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___get_user_asm_l1:
+	ld.l	r3, 0, r5		/* r5 = data */
+	st.l	r4, 0, r5
+	or	ZERO, ZERO, r2
+	
+___get_user_asm_l_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+	.global	__get_user_asm_q
+__get_user_asm_q:
+	or	r2, ZERO, r4
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___get_user_asm_q1:
+	ld.q	r3, 0, r5		/* r5 = data */
+	st.q	r4, 0, r5
+	or	ZERO, ZERO, r2
+	
+___get_user_asm_q_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+/*
+ * extern long __put_user_asm_?(void *pval, long addr)
+ *
+ * Inputs:
+ * (r2)  kernel pointer to value
+ * (r3)  dest address (in User Space)
+ *
+ * Ouputs:
+ * (r2)  -EFAULT (faulting)
+ *       0 	 (not faulting)
+ */
+	.global	__put_user_asm_b
+__put_user_asm_b:
+	ld.b	r2, 0, r4		/* r4 = data */
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___put_user_asm_b1:
+	st.b	r3, 0, r4
+	or	ZERO, ZERO, r2
+	
+___put_user_asm_b_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+	.global	__put_user_asm_w
+__put_user_asm_w:
+	ld.w	r2, 0, r4		/* r4 = data */
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___put_user_asm_w1:
+	st.w	r3, 0, r4
+	or	ZERO, ZERO, r2
+	
+___put_user_asm_w_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+	.global	__put_user_asm_l
+__put_user_asm_l:
+	ld.l	r2, 0, r4		/* r4 = data */
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___put_user_asm_l1:
+	st.l	r3, 0, r4
+	or	ZERO, ZERO, r2
+	
+___put_user_asm_l_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+	.global	__put_user_asm_q
+__put_user_asm_q:
+	ld.q	r2, 0, r4		/* r4 = data */
+	movi	-(EFAULT), r2		/* r2 = reply, no real fixup */
+	
+___put_user_asm_q1:
+	st.q	r3, 0, r4
+	or	ZERO, ZERO, r2
+	
+___put_user_asm_q_exit:
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
+
+/*
+ * --- Signal Handling Section
+ */
+
+/*
+ * extern long long _sa_default_rt_restorer
+ * extern long long _sa_default_restorer
+ *
+ *		 or, better,
+ *
+ * extern void _sa_default_rt_restorer(void)
+ * extern void _sa_default_restorer(void)
+ *
+ * Code prototypes to do a sys_rt_sigreturn() or sys_sysreturn()
+ * from user space. Copied into user space by signal management.
+ * Both must be quad aligned and 2 quad long (4 instructions).
+ *
+ */
+	.balign 8
+	.global sa_default_rt_restorer
+sa_default_rt_restorer:
+	movi	0x10, r9
+	shori	__NR_rt_sigreturn, r9
+	trapa	r9
+	nop
+	
+	.balign 8
+	.global sa_default_restorer
+sa_default_restorer:
+	movi	0x10, r9
+	shori	__NR_sigreturn, r9
+	trapa	r9
+	nop
+	
+/*
+ * --- __ex_table Section
+ */
+
+/*
+ * User Access Exception Table.
+ */
+	.section	__ex_table,  "a"
+
+	.global asm_uaccess_start	/* Just a marker */
+asm_uaccess_start:
+
+	.long	___copy_user1, ___copy_user_exit
+	.long	___copy_user2, ___copy_user_exit
+	.long	___clear_user1, ___clear_user_exit
+	.long	___strncpy_from_user1, ___strncpy_from_user_exit
+	.long	___strnlen_user1, ___strnlen_user_exit
+	.long	___get_user_asm_b1, ___get_user_asm_b_exit
+	.long	___get_user_asm_w1, ___get_user_asm_w_exit
+	.long	___get_user_asm_l1, ___get_user_asm_l_exit
+	.long	___get_user_asm_q1, ___get_user_asm_q_exit
+	.long	___put_user_asm_b1, ___put_user_asm_b_exit
+	.long	___put_user_asm_w1, ___put_user_asm_w_exit
+	.long	___put_user_asm_l1, ___put_user_asm_l_exit
+	.long	___put_user_asm_q1, ___put_user_asm_q_exit
+
+	.global asm_uaccess_end		/* Just a marker */
+asm_uaccess_end:
+	
+
+
+
+/*
+ * --- .text.init Section
+ */
+
+	.section	.text.init, "ax"
+
+/*
+ * void trap_init (void)
+ *
+ */
+	.global	trap_init
+trap_init:
+	addi	SP, -24, SP			/* Room to save r28/r29/r30 */
+	st.q	SP, 0, r28
+	st.q	SP, 8, r29
+	st.q	SP, 16, r30
+
+	/* Set VBR and RESVEC */
+	_loada	LVBR_block, r19
+	andi	r19, -4, r19			/* reset MMUOFF + reserved */
+	/* For RESVEC exceptions we force the MMU off, which means we need the
+	   physical address. */
+	_loada	LRESVEC_block-CONFIG_CACHED_MEMORY_OFFSET, r20
+	andi	r20, -4, r20			/* reset reserved */
+	ori	r20, 1, r20			/* set MMUOFF */
+	putcon	r19, VBR
+	putcon	r20, RESVEC
+
+	/* Sanity check */
+	_loada	LVBR_block_end, r21
+	andi	r21, -4, r21
+	movi	BLOCK_SIZE, r29			/* r29 = expected size */
+	or	r19, ZERO, r30
+	add	r19, r29, r19
+
+	/*
+	 * Ugly, but better loop forever now than crash afterwards.
+	 * We should print a message, but if we touch LVBR or
+	 * LRESVEC blocks we should not be surprised if we get stuck
+	 * in trap_init().
+	 */
+	_ptar	trap_init_loop, t1
+	gettr	t1, r28				/* r28 = trap_init_loop */
+	sub	r21, r30, r30			/* r30 = actual size */
+
+	/*
+	 * VBR/RESVEC handlers overlap by being bigger than
+	 * allowed. Very bad. Just loop forever.
+	 * (r28) panic/loop address
+	 * (r29) expected size
+	 * (r30) actual size
+	 */
+trap_init_loop:
+	bne	r19, r21, t1
+
+	/* Now that exception vectors are set up reset SR.BL */
+	getcon 	SR, r22
+	movi	SR_UNBLOCK_EXC, r23
+	and	r22, r23, r22
+	putcon	r22, SR
+
+	addi	SP, 24, SP
+	ptabs	LINK, t0
+	blink	t0, ZERO
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/fpu.c linux-2.4.22-pre10/arch/sh64/kernel/fpu.c
--- linux-2.4.21/arch/sh64/kernel/fpu.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/fpu.c	2003-08-01 13:33:10.000000000 +0000
@@ -0,0 +1,171 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/fpu.c
+ *
+ * Copyright (C) 2001  Manuela Cirronis, Paolo Alberelli
+ *
+ * Started from SH4 version:
+ *   Copyright (C) 1999, 2000  Kaz Kojima & Niibe Yutaka
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <asm/processor.h>
+#include <asm/user.h>
+#include <asm/io.h>
+
+/*
+ * Initially load the FPU with signalling NANS.  This bit pattern
+ * has the property that no matter whether considered as single or as
+ * double precision, it still represents a signalling NAN.  
+ */
+#define sNAN64		0xFFFFFFFFFFFFFFFF
+
+static struct sh_fpu_hard_struct init_fpuregs = {
+	{ [0 ... 31] = sNAN64 },
+	FPSCR_INIT
+};
+
+inline void fpsave(struct sh_fpu_hard_struct *fpregs)
+{
+	asm volatile("fst.d     %0, (0*8),"  __d(0)  "\n\t"
+		     "fst.d     %0, (1*8),"  __d(2)  "\n\t"
+		     "fst.d     %0, (2*8),"  __d(4)  "\n\t"
+		     "fst.d     %0, (3*8),"  __d(6)  "\n\t"
+		     "fst.d     %0, (4*8),"  __d(8)  "\n\t"
+		     "fst.d     %0, (5*8),"  __d(10) "\n\t"
+		     "fst.d     %0, (6*8),"  __d(12) "\n\t"
+		     "fst.d     %0, (7*8),"  __d(14) "\n\t"
+		     "fst.d     %0, (8*8),"  __d(16) "\n\t"
+		     "fst.d     %0, (9*8),"  __d(18) "\n\t"
+		     "fst.d     %0, (10*8)," __d(20) "\n\t"
+		     "fst.d     %0, (11*8)," __d(22) "\n\t"
+		     "fst.d     %0, (12*8)," __d(24) "\n\t"
+		     "fst.d     %0, (13*8)," __d(26) "\n\t"
+		     "fst.d     %0, (14*8)," __d(28) "\n\t"
+		     "fst.d     %0, (15*8)," __d(30) "\n\t"
+		     "fst.d     %0, (16*8)," __d(32) "\n\t"
+		     "fst.d     %0, (17*8)," __d(34) "\n\t"
+		     "fst.d     %0, (18*8)," __d(36) "\n\t"
+		     "fst.d     %0, (19*8)," __d(38) "\n\t"
+		     "fst.d     %0, (20*8)," __d(40) "\n\t"
+		     "fst.d     %0, (21*8)," __d(42) "\n\t"
+		     "fst.d     %0, (22*8)," __d(44) "\n\t"
+		     "fst.d     %0, (23*8)," __d(46) "\n\t"
+		     "fst.d     %0, (24*8)," __d(48) "\n\t"
+		     "fst.d     %0, (25*8)," __d(50) "\n\t"
+		     "fst.d     %0, (26*8)," __d(52) "\n\t"
+		     "fst.d     %0, (27*8)," __d(54) "\n\t"
+		     "fst.d     %0, (28*8)," __d(56) "\n\t"
+		     "fst.d     %0, (29*8)," __d(58) "\n\t"
+		     "fst.d     %0, (30*8)," __d(60) "\n\t"
+		     "fst.d     %0, (31*8)," __d(62) "\n\t"
+
+		     "_fgetscr  " __f(63) 	     "\n\t"
+		     "fst.s     %0, (32*8)," __f(63) "\n\t"
+		: /* no output */
+		: "r" (fpregs)
+		: "memory");
+}
+
+
+static inline void
+fpload(struct sh_fpu_hard_struct *fpregs)
+{
+	asm volatile("fld.d     %0, (0*8),"  __d(0)  "\n\t"
+		     "fld.d     %0, (1*8),"  __d(2)  "\n\t"
+		     "fld.d     %0, (2*8),"  __d(4)  "\n\t"
+		     "fld.d     %0, (3*8),"  __d(6)  "\n\t"
+		     "fld.d     %0, (4*8),"  __d(8)  "\n\t"
+		     "fld.d     %0, (5*8),"  __d(10) "\n\t"
+		     "fld.d     %0, (6*8),"  __d(12) "\n\t"
+		     "fld.d     %0, (7*8),"  __d(14) "\n\t"
+		     "fld.d     %0, (8*8),"  __d(16) "\n\t"
+		     "fld.d     %0, (9*8),"  __d(18) "\n\t"
+		     "fld.d     %0, (10*8)," __d(20) "\n\t"
+		     "fld.d     %0, (11*8)," __d(22) "\n\t"
+		     "fld.d     %0, (12*8)," __d(24) "\n\t"
+		     "fld.d     %0, (13*8)," __d(26) "\n\t"
+		     "fld.d     %0, (14*8)," __d(28) "\n\t"
+		     "fld.d     %0, (15*8)," __d(30) "\n\t"
+		     "fld.d     %0, (16*8)," __d(32) "\n\t"
+		     "fld.d     %0, (17*8)," __d(34) "\n\t"
+		     "fld.d     %0, (18*8)," __d(36) "\n\t"
+		     "fld.d     %0, (19*8)," __d(38) "\n\t"
+		     "fld.d     %0, (20*8)," __d(40) "\n\t"
+		     "fld.d     %0, (21*8)," __d(42) "\n\t"
+		     "fld.d     %0, (22*8)," __d(44) "\n\t"
+		     "fld.d     %0, (23*8)," __d(46) "\n\t"
+		     "fld.d     %0, (24*8)," __d(48) "\n\t"
+		     "fld.d     %0, (25*8)," __d(50) "\n\t"
+		     "fld.d     %0, (26*8)," __d(52) "\n\t"
+		     "fld.d     %0, (27*8)," __d(54) "\n\t"
+		     "fld.d     %0, (28*8)," __d(56) "\n\t"
+		     "fld.d     %0, (29*8)," __d(58) "\n\t"
+		     "fld.d     %0, (30*8)," __d(60) "\n\t"
+
+		     "fld.s     %0, (32*8)," __f(63) "\n\t"
+		     "_fputscr  " __f(63) 	     "\n\t"
+
+	     	     "fld.d     %0, (31*8)," __d(62) "\n\t"
+		: /* no output */
+		: "r" (fpregs) );
+}
+
+void fpinit(struct sh_fpu_hard_struct *fpregs)
+{
+	*fpregs = init_fpuregs;
+}
+
+asmlinkage void
+do_fpu_error(unsigned long ex, struct pt_regs *regs)
+{
+	struct task_struct *tsk = current;
+
+	regs->pc += 4;
+
+	tsk->thread.trap_no = 11;
+	tsk->thread.error_code = 0;
+	force_sig(SIGFPE, tsk);
+}
+
+
+asmlinkage void
+do_fpu_state_restore(unsigned long ex, struct pt_regs *regs)
+{
+	void die(const char * str, struct pt_regs * regs, long err);
+
+#if 0
+printk("do_fpu_state_restore (pid %d, used_math %d, last_used_math pid %d)\n",
+       current->pid, current->used_math,
+       last_task_used_math ? last_task_used_math->pid : -1);
+#endif
+
+	if (! user_mode(regs))
+		die("FPU used in kernel", regs, ex);
+
+	regs->sr &= ~SR_FD;
+
+	if (last_task_used_math == current)
+		return;
+
+	grab_fpu();
+	if (last_task_used_math != NULL) {
+		/* Other processes fpu state, save away */
+		fpsave(&last_task_used_math->thread.fpu.hard);
+        }
+        last_task_used_math = current;
+        if (current->used_math) {
+                fpload(&current->thread.fpu.hard);
+        } else {
+		/* First time FPU user.  */
+		fpload(&init_fpuregs);
+                current->used_math = 1;
+        }
+	release_fpu();
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/head.S linux-2.4.22-pre10/arch/sh64/kernel/head.S
--- linux-2.4.21/arch/sh64/kernel/head.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/head.S	2003-08-01 13:32:41.000000000 +0000
@@ -0,0 +1,347 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh5/kernel/head.S
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ *
+ * benedict.gaster@superh.com:	 2nd May 2002
+ *    Moved definition of empty_zero_page to its own section allowing
+ *    it to be placed at an absolute address known at load time.
+ *
+ * lethal@linux-sh.org:          9th May 2003
+ *    Kill off GLOBAL_NAME() usage.
+ */
+
+#include <linux/config.h>
+
+#include <asm/page.h>
+#include <asm/mmu_context.h>
+#include <asm/cache.h>
+#include <asm/tlb.h>
+#include <asm/processor.h>
+#include <asm/registers.h>
+
+/*
+ * MMU defines: TLB boundaries.
+ */
+
+#define MMUIR_FIRST	ITLB_FIXED	
+#define MMUIR_END	ITLB_LAST_VAR_UNRESTRICTED+TLB_STEP
+#define MMUIR_STEP	TLB_STEP
+
+#define MMUDR_FIRST	DTLB_FIXED
+#define MMUDR_END	DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP
+#define MMUDR_STEP	TLB_STEP
+
+/*
+ * MMU defines: Fixed TLBs.
+ */
+#define MMUIR_TEXT_H	0x0000000000000003 | (CONFIG_CACHED_MEMORY_OFFSET + CONFIG_MEMORY_START)
+			/* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
+
+#define MMUIR_TEXT_L	0x000000000000009a | (CONFIG_MEMORY_START)
+			/* 512 Mb, Cacheable, Write-back, execute, Not User, Ph. Add. */
+
+#define MMUDR_CACHED_H	0x0000000000000003 | (CONFIG_CACHED_MEMORY_OFFSET + CONFIG_MEMORY_START)
+			/* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
+#define MMUDR_CACHED_L	0x000000000000015a | (CONFIG_MEMORY_START)
+			/* 512 Mb, Cacheable, Write-back, read/write, Not User, Ph. Add. */
+
+#ifdef CONFIG_ICACHE_DISABLED
+#define	ICCR0_INIT_VAL	ICCR0_OFF			/* ICACHE off */
+#else
+#define	ICCR0_INIT_VAL	ICCR0_ON | ICCR0_ICI		/* ICE + ICI */
+#endif
+#define	ICCR1_INIT_VAL	ICCR1_NOLOCK			/* No locking */
+
+#if defined (CONFIG_DCACHE_DISABLED)
+#define	OCCR0_INIT_VAL	OCCR0_OFF			   /* D-cache: off  */
+#elif defined (CONFIG_DCACHE_WRITE_THROUGH)
+#define	OCCR0_INIT_VAL	OCCR0_ON | OCCR0_OCI | OCCR0_WT	   /* D-cache: on,   */
+							   /* WT, invalidate */
+#elif defined (CONFIG_DCACHE_WRITE_BACK)
+#define	OCCR0_INIT_VAL	OCCR0_ON | OCCR0_OCI | OCCR0_WB	   /* D-cache: on,   */
+							   /* WB, invalidate */
+#else
+#error preprocessor flag CONFIG_DCACHE_... not recognized!
+#endif
+
+#define	OCCR1_INIT_VAL	OCCR1_NOLOCK			   /* No locking     */
+
+	.section	.empty_zero_page, "aw"
+	.global empty_zero_page
+	
+empty_zero_page:	
+	.long	1		/* MOUNT_ROOT_RDONLY */
+	.long	0		/* RAMDISK_FLAGS */
+	.long	0x0200		/* ORIG_ROOT_DEV */
+	.long	1		/* LOADER_TYPE */
+	.long	0x00360000	/* INITRD_START */
+	.long	0x000a0000	/* INITRD_SIZE */
+	.long	0
+
+	.text	
+	.balign 4096,0,4096	
+
+	.section	.data, "aw"
+	.balign	PAGE_SIZE
+
+	.section	.data, "aw"
+	.balign	PAGE_SIZE
+
+	.global swapper_pg_dir
+swapper_pg_dir:
+	.space PAGE_SIZE, 0
+
+	.global empty_bad_page
+empty_bad_page:
+	.space PAGE_SIZE, 0
+
+	.global empty_bad_pte_table
+empty_bad_pte_table:
+	.space PAGE_SIZE, 0
+
+variables:
+	.global	fpu_in_use
+fpu_in_use:	.quad	0
+
+
+	.section	.text, "ax"
+	.balign L1_CACHE_BYTES
+/*
+ * Condition at the entry of __stext:
+ * . Reset state:
+ *   . SR.FD    = 1		(FPU disabled)
+ *   . SR.BL    = 1		(Exceptions disabled)
+ *   . SR.MD    = 1		(Privileged Mode)
+ *   . SR.MMU   = 0		(MMU Disabled)
+ *   . SR.CD    = 0		(CTC User Visible)
+ *   . SR.IMASK = Undefined	(Interrupt Mask)
+ *
+ * Operations supposed to be performed by __stext:
+ * . prevent speculative fetch onto device memory while MMU is off
+ * . reflect as much as possible SH5 ABI (r15, r26, r27, r18)
+ * . first, save CPU state and set it to something harmless
+ * . any CPU detection and/or endianness settings (?)
+ * . initialize EMI/LMI (but not TMU/RTC/INTC/SCIF): TBD
+ * . set initial TLB entries for cached and uncached regions
+ *   (no fine granularity paging)
+ * . set initial cache state
+ * . enable MMU and caches
+ * . set CPU to a consistent state
+ *   . registers (including stack pointer and current/KCR0)
+ *   . NOT expecting to set Exception handling nor VBR/RESVEC/DCR
+ *     at this stage. This is all to later Linux initialization steps.
+ *   . initialize FPU
+ * . clear BSS
+ * . jump into start_kernel()
+ * . be prepared to hopeless start_kernel() returns.
+ *
+ */
+	.global _stext
+_stext:
+	/*
+	 * Prevent speculative fetch on device memory due to
+	 * uninitialized target registers.
+	 */
+	ptabs/u	ZERO, t0
+	ptabs/u	ZERO, t1
+	ptabs/u	ZERO, t2
+	ptabs/u	ZERO, t3
+	ptabs/u	ZERO, t4
+	ptabs/u	ZERO, t5
+	ptabs/u	ZERO, t6
+	ptabs/u	ZERO, t7
+	synci
+
+	/*
+	 * Set variable/constant pointers according to SH5 ABI.
+	 */
+	_loada	constants, GCDT
+
+	_loada	variables, GVDT
+
+	/*
+	 * Read/Set CPU state. After this block:
+	 * r29 = Initial SR
+	 */
+	getcon	SR, r29
+	movi	SR_HARMLESS, r20
+	putcon	r20, SR
+
+	/*
+	 * Initialize EMI/LMI. To Be Done.
+	 */
+
+	/*
+	 * CPU detection and/or endianness settings (?). To Be Done.
+	 * Pure PIC code here, please ! Just save state into r30.
+         * After this block:
+	 * r30 = CPU type/Platform Endianness
+	 */
+
+	/*
+	 * Set initial TLB entries for cached and uncached regions.
+	 * Note: PTA/BLINK is PIC code, PTABS/BLINK isn't !
+	 */
+	/* Clear ITLBs */
+	_ptar	clear_ITLB, t1
+	movi	MMUIR_FIRST, r21
+	movi	MMUIR_END, r22
+clear_ITLB:
+	putcfg	r21, 0, ZERO		/* Clear MMUIR[n].PTEH.V */
+	addi	r21, MMUIR_STEP, r21
+        bne	r21, r22, t1
+
+	/* Clear DTLBs */
+	_ptar	clear_DTLB, t1
+	movi	MMUDR_FIRST, r21
+	movi	MMUDR_END, r22
+clear_DTLB:
+	putcfg	r21, 0, ZERO		/* Clear MMUDR[n].PTEH.V */
+	addi	r21, MMUDR_STEP, r21
+        bne	r21, r22, t1
+
+	/* Map one big (512Mb) page for ITLB */
+	movi	MMUIR_FIRST, r21
+	movi	MMUIR_TEXT_L, r22	/* PTEL first */
+	putcfg	r21, 1, r22		/* Set MMUIR[0].PTEL */
+	movi	MMUIR_TEXT_H, r22	/* PTEH last */
+	putcfg	r21, 0, r22		/* Set MMUIR[0].PTEH */
+	
+	/* Map one big CACHED (512Mb) page for DTLB */
+	movi	MMUDR_FIRST, r21
+	movi	MMUDR_CACHED_L, r22	/* PTEL first */
+	putcfg	r21, 1, r22		/* Set MMUDR[0].PTEL */
+	movi	MMUDR_CACHED_H, r22	/* PTEH last */
+	putcfg	r21, 0, r22		/* Set MMUDR[0].PTEH */
+	
+	/*
+	 * Set cache behaviours.
+	 */
+	/* ICache */
+	movi	ICCR_BASE, r21
+	movi	ICCR0_INIT_VAL, r22
+	movi	ICCR1_INIT_VAL, r23
+	putcfg	r21, ICCR_REG0, r22
+	putcfg	r21, ICCR_REG1, r23
+
+	/* OCache */
+	movi	OCCR_BASE, r21
+	movi	OCCR0_INIT_VAL, r22
+	movi	OCCR1_INIT_VAL, r23
+	putcfg	r21, OCCR_REG0, r22
+	putcfg	r21, OCCR_REG1, r23
+
+
+	/*
+	 * Enable Caches and MMU. Do the first non-PIC jump.
+         * Now head.S global variables, constants and externs
+	 * can be used.
+	 */
+	getcon	SR, r21
+	movi	SR_ENABLE_MMU, r22
+	or	r21, r22, r21
+	putcon	r21, SSR
+	_loada	hyperspace, r22
+	ori	r22, 1, r22	    /* Make it SHmedia, not required but..*/
+	putcon	r22, SPC
+	synco
+	rte			    /* And now go into the hyperspace ... */
+hyperspace:			    /* ... that's the next instruction !  */
+
+	/*
+	 * Set CPU to a consistent state.
+	 * r31 = FPU support flag
+	 * t0/t7 in use. Others give a chance to loop somewhere safe
+	 */
+	_loada	start_kernel, r32
+	ori	r32, 1, r32
+
+	ptabs	r32, t0		    /* r32 = _start_kernel address        */
+	_ptaru	hopeless, t1
+	_ptaru	hopeless, t2
+	_ptaru	hopeless, t3
+	_ptaru	hopeless, t4
+	_ptaru	hopeless, t5
+	_ptaru	hopeless, t6
+	_ptar	hopeless, t7
+	gettr	t1, r28			/* r28 = hopeless address */
+
+	/* Set initial stack pointer */
+	_loada	init_task_union, SP
+	putcon	SP, KCR0		/* Set current to init_task */
+	movi	THREAD_SIZE, r22	/* Point to the end */
+	add	SP, r22, SP
+
+	/*
+	 * Initialize FPU.
+	 * Keep FPU flag in r31. After this block:	
+	 * r31 = FPU flag
+	 */
+	addi	GVDT, fpu_in_use - variables, r31	/* Temporary */
+
+#ifndef CONFIG_NOFPU_SUPPORT
+	getcon	SR, r21
+	movi	SR_ENABLE_FPU, r22
+	and	r21, r22, r22
+	putcon	r22, SR			/* Try to enable */
+	getcon	SR, r22
+	xor	r21, r22, r21
+	shlri	r21, 15, r21		/* Supposedly 0/1 */
+	st.q	r31, 0 , r21		/* Set fpu_in_use */
+#else
+	movi	0, r21
+	st.q	r31, 0 , r21		/* Set fpu_in_use */
+#endif
+	or	r21, ZERO, r31		/* Set FPU flag at last */
+
+	/*
+	 * Clear bss
+	 */
+	_ptar	clear_quad, t1
+	_loada	__bss_start, r22
+	_loada	_end, r23
+clear_quad:
+	st.q	r22, 0, ZERO 
+	addi	r22, 8, r22
+	bne	r22, r23, t1		/* Both quad aligned, see vmlinux.lds.S */
+	_ptaru	hopeless, t1
+
+	/* Say bye to head.S but be prepared to wrongly get back ... */
+	blink	t0, LINK
+
+	/* If we ever get back here through LINK/t1-t7 */
+	_ptaru	hopeless, t7
+
+hopeless:
+	/*
+	 * Something's badly wrong here. Loop endlessly,
+         * there's nothing more we can do about it.
+	 *
+	 * Note on hopeless: it can be jumped into invariably
+	 * before or after jumping into hyperspace. The only
+	 * requirement is to be PIC called (PTA) before and
+	 * any way (PTA/PTABS) after. According to Virtual
+	 * to Physical mapping a simulator/emulator can easily
+	 * tell where we came here from just looking at hopeless
+	 * (PC) address.
+	 *
+	 * For debugging purposes:
+	 * (r28) hopeless/loop address
+	 * (r29) Original SR
+	 * (r30) CPU type/Platform endianness
+	 * (r31) FPU Support
+	 * (r32) _start_kernel address
+	 */
+	blink	t7, ZERO
+
+
+	.balign L1_CACHE_BYTES
+constants:
+dummyc:	.quad 0
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/init_task.c linux-2.4.22-pre10/arch/sh64/kernel/init_task.c
--- linux-2.4.21/arch/sh64/kernel/init_task.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/init_task.c	2003-08-01 13:34:09.000000000 +0000
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/init_task.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS;
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+
+struct pt_regs fake_swapper_regs;
+
+/*
+ * Initial task structure.
+ *
+ * We need to make sure that this is INIT_TASK_SIZE-byte aligned due
+ * to the way process stacks are handled. This is done by having a
+ * special "init_task" linker map entry..
+ */
+union task_union init_task_union 
+	__attribute__((__section__(".data.init_task"))) =
+		{ INIT_TASK(init_task_union.task) };
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/irq.c linux-2.4.22-pre10/arch/sh64/kernel/irq.c
--- linux-2.4.21/arch/sh64/kernel/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/irq.c	2003-08-01 13:32:18.000000000 +0000
@@ -0,0 +1,706 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/irq.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ */
+
+/*
+ * IRQs are in fact implemented a bit like signal handlers for the kernel.
+ * Naturally it's not a 1:1 relation, but there are similarities.
+ */
+
+#include <linux/config.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/smp.h>
+#include <asm/pgalloc.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <linux/irq.h>
+
+/*
+ * Controller mappings for all interrupt sources:
+ */
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
+	{ [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
+
+/*
+ * Special irq handlers.
+ */
+
+void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+
+/*
+ * Generic no controller code
+ */
+
+static void enable_none(unsigned int irq) { }
+static unsigned int startup_none(unsigned int irq) { return 0; }
+static void disable_none(unsigned int irq) { }
+static void ack_none(unsigned int irq)
+{
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves, it doesnt deserve
+ * a generic callback i think.
+ */
+	printk("unexpected IRQ trap at irq %02x\n", irq);
+}
+
+/* startup is the same as "enable", shutdown is same as "disable" */
+#define shutdown_none	disable_none
+#define end_none	enable_none
+
+struct hw_interrupt_type no_irq_type = {
+	"none",
+	startup_none,
+	shutdown_none,
+	enable_none,
+	disable_none,
+	ack_none,
+	end_none
+};
+
+
+/*
+ * do_NMI handles all Non-Maskable Interrupts.
+ */
+asmlinkage void do_NMI(unsigned long vector_num, struct pt_regs * regs)
+{	
+	if (regs->sr & 0x40000000)
+		printk("unexpected NMI trap in system mode\n");
+	else
+		printk("unexpected NMI trap in user mode\n");
+
+	/* No statistics */
+}
+
+
+/*
+ * Generic, controller-independent functions:
+ */
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
+int get_irq_list(char *buf)
+{
+	int i, j;
+	struct irqaction * action;
+	char *p = buf;
+
+	p += sprintf(p, "           ");
+	for (j=0; j<smp_num_cpus; j++)
+		p += sprintf(p, "CPU%d       ",j);
+	*p++ = '\n';
+
+	for (i = 0 ; i < NR_IRQS ; i++) {
+		action = irq_desc[i].action;
+		if (!action) 
+			continue;
+		p += sprintf(p, "%3d: ",i);
+		p += sprintf(p, "%10u ", kstat_irqs(i));
+		p += sprintf(p, " %14s", irq_desc[i].handler->typename);
+		p += irq_describe(p, i);
+		p += sprintf(p, "  %s", action->name);
+
+		for (action=action->next; action; action = action->next)
+			p += sprintf(p, ", %s", action->name);
+		*p++ = '\n';
+	}
+#if 0
+	p += sprintf(p, "NMI: ");
+	for (j = 0; j < smp_num_cpus; j++)
+		p += sprintf(p, "%10u ",
+			atomic_read(&nmi_counter(cpu_logical_map(j))));
+	p += sprintf(p, "\n");
+#endif
+
+	return p - buf;
+}
+#endif
+
+/*
+ * This should really return information about whether
+ * we should do bottom half handling etc. Right now we
+ * end up _always_ checking the bottom half, which is a
+ * waste of time and is not what some drivers would
+ * prefer.
+ */
+int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
+{
+	int status;
+	int cpu = smp_processor_id();
+
+	irq_enter(cpu, irq);
+
+	status = 1;	/* Force the "do bottom halves" bit */
+
+        if (!(action->flags & SA_INTERRUPT))
+                __sti();
+
+	do {
+		status |= action->flags;
+		action->handler(irq, action->dev_id, regs);
+		action = action->next;
+	} while (action);
+	if (status & SA_SAMPLE_RANDOM)
+		add_interrupt_randomness(irq);
+
+	__cli();
+
+	irq_exit(cpu, irq);
+
+	return status;
+}
+
+/*
+ * Generic enable/disable code: this just calls
+ * down into the PIC-specific version for the actual
+ * hardware disable after having gotten the irq
+ * controller lock. 
+ */
+
+/**
+ *	disable_irq_nosync - disable an irq without waiting
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. Unlike disable_irq(), this function does not ensure existing
+ *	instances of the IRQ handler have completed before returning.
+ *
+ *	This function may be called from IRQ context.
+ */
+void disable_irq_nosync(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	if (!desc->depth++) {
+		desc->status |= IRQ_DISABLED;
+		desc->handler->disable(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/**
+ *	disable_irq - disable an irq and wait for completion
+ *	@irq: Interrupt to disable
+ *
+ *	Disable the selected interrupt line. Disables of an interrupt
+ *	stack. That is for two disables you need two enables. This
+ *	function waits for any pending IRQ handlers for this interrupt
+ *	to complete before returning. If you use this function while
+ *	holding a resource the IRQ handler may need you will deadlock.
+ *
+ *	This function may be called - with care - from IRQ context.
+ */
+void disable_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+
+	if (!local_irq_count(smp_processor_id())) {
+		do {
+			barrier();
+		} while (irq_desc[irq].status & IRQ_INPROGRESS);
+	}
+}
+
+/**
+ *	enable_irq - enable interrupt handling on an irq
+ *	@irq: Interrupt to enable
+ *
+ *	Re-enables the processing of interrupts on this IRQ line
+ *	providing no disable_irq calls are now in effect.
+ *
+ *	This function may be called from IRQ context.
+ */
+void enable_irq(unsigned int irq)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&desc->lock, flags);
+	switch (desc->depth) {
+	case 1: {
+		unsigned int status = desc->status & ~IRQ_DISABLED;
+		desc->status = status;
+		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+			desc->status = status | IRQ_REPLAY;
+			hw_resend_irq(desc->handler,irq);
+		}
+		desc->handler->enable(irq);
+		/* fall-through */
+	}
+	default:
+		desc->depth--;
+		break;
+	case 0:
+		printk("enable_irq() unbalanced from %p\n",
+		       __builtin_return_address(0));
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+/*
+ * do_IRQ handles all normal device IRQ's.
+ */
+asmlinkage int do_IRQ(unsigned long vector_num, struct pt_regs * regs)
+{	
+	/* 
+	 * We ack quickly, we don't want the irq controller
+	 * thinking we're snobs just because some other CPU has
+	 * disabled global interrupts (we have already done the
+	 * INT_ACK cycles, it's too late to try to pretend to the
+	 * controller that we aren't taking the interrupt).
+	 *
+	 * 0 return value means that this irq is already being
+	 * handled by some other CPU. (or is disabled)
+	 */
+	int irq;
+	int cpu = smp_processor_id();
+	irq_desc_t *desc;
+	struct irqaction * action;
+	unsigned int status;
+
+	irq = irq_demux(vector_num);
+
+	/*
+	 * Should never happen, if it does check
+	 * vectorN_to_IRQ[] against trap_jtable[].
+	 */
+	if (irq == -1) {
+		printk("unexpected IRQ trap at vector %03lx\n", vector_num);
+		return 1;
+	}
+
+	desc = irq_desc + irq;
+
+	kstat.irqs[cpu][irq]++;
+	spin_lock(&desc->lock);
+	desc->handler->ack(irq);
+	/*
+	   REPLAY is when Linux resends an IRQ that was dropped earlier
+	   WAITING is used by probe to mark irqs that are being tested
+	   */
+	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
+	status |= IRQ_PENDING; /* we _want_ to handle it */
+
+	/*
+	 * If the IRQ is disabled for whatever reason, we cannot
+	 * use the action we have.
+	 */
+	action = NULL;
+	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+		action = desc->action;
+		status &= ~IRQ_PENDING; /* we commit to handling */
+		status |= IRQ_INPROGRESS; /* we are handling it */
+	}
+	desc->status = status;
+
+	/*
+	 * If there is no IRQ handler or it was disabled, exit early.
+	   Since we set PENDING, if another processor is handling
+	   a different instance of this same irq, the other processor
+	   will take care of it.
+	 */
+	if (!action)
+		goto out;
+
+	/*
+	 * Edge triggered interrupts need to remember
+	 * pending events.
+	 * This applies to any hw interrupts that allow a second
+	 * instance of the same irq to arrive while we are in do_IRQ
+	 * or in the handler. But the code here only handles the _second_
+	 * instance of the irq, not the third or fourth. So it is mostly
+	 * useful for irq hardware that does not mask cleanly in an
+	 * SMP environment.
+	 */
+	for (;;) {
+		spin_unlock(&desc->lock);
+		handle_IRQ_event(irq, regs, action);
+		spin_lock(&desc->lock);
+
+		if (!(desc->status & IRQ_PENDING))
+			break;
+		desc->status &= ~IRQ_PENDING;
+	}
+	desc->status &= ~IRQ_INPROGRESS;
+out:
+	/*
+	 * The ->end() handler has to deal with interrupts which got
+	 * disabled while the handler was running.
+	 */
+	desc->handler->end(irq);
+	spin_unlock(&desc->lock);
+
+	if (softirq_pending(cpu))
+		do_softirq();
+	return 1;
+}
+
+/**
+ *	request_irq - allocate an interrupt line
+ *	@irq: Interrupt line to allocate
+ *	@handler: Function to be called when the IRQ occurs
+ *	@irqflags: Interrupt type flags
+ *	@devname: An ascii name for the claiming device
+ *	@dev_id: A cookie passed back to the handler function
+ *
+ *	This call allocates interrupt resources and enables the
+ *	interrupt line and IRQ handling. From the point this
+ *	call is made your handler function may be invoked. Since
+ *	your handler function must clear any interrupt the board
+ *	raises, you must take care both to initialise your hardware
+ *	and to set up the interrupt handler in the right order.
+ *
+ *	Dev_id must be globally unique. Normally the address of the
+ *	device data structure is used as the cookie. Since the handler
+ *	receives this value it makes sense to use it.
+ *
+ *	If your interrupt is shared you must pass a non NULL dev_id
+ *	as this is required when freeing the interrupt.
+ *
+ *	Flags:
+ *
+ *	SA_SHIRQ		Interrupt is shared
+ *
+ *	SA_INTERRUPT		Disable local interrupts while processing
+ *
+ *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
+ *
+ */
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
+{
+	int retval;
+	struct irqaction * action;
+
+#if 1
+	/*
+	 * Sanity-check: shared interrupts should REALLY pass in
+	 * a real dev-ID, otherwise we'll have trouble later trying
+	 * to figure out which interrupt is which (messes up the
+	 * interrupt freeing logic etc).
+	 */
+	if (irqflags & SA_SHIRQ) {
+		if (!dev_id)
+			printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
+	}
+#endif
+
+	if (irq >= NR_IRQS)
+		return -EINVAL;
+	if (!handler)
+		return -EINVAL;
+
+	action = (struct irqaction *)
+			kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_irq(irq, action);
+	if (retval)
+		kfree(action);
+	return retval;
+}
+
+/**
+ *	free_irq - free an interrupt
+ *	@irq: Interrupt line to free
+ *	@dev_id: Device identity to free
+ *
+ *	Remove an interrupt handler. The handler is removed and if the
+ *	interrupt line is no longer in use by any driver it is disabled.
+ *	On a shared IRQ the caller must ensure the interrupt is disabled
+ *	on the card it drives before calling this function. The function
+ *	does not return until any executing interrupts for this IRQ
+ *	have completed.
+ *
+ *	This function may be called from interrupt context.
+ *
+ *	Bugs: Attempting to free an irq in a handler for the same irq hangs
+ *	      the machine.
+ */
+void free_irq(unsigned int irq, void *dev_id)
+{
+	irq_desc_t *desc;
+	struct irqaction **p;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS)
+		return;
+
+	desc = irq_desc + irq;
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	for (;;) {
+		struct irqaction * action = *p;
+		if (action) {
+			struct irqaction **pp = p;
+			p = &action->next;
+			if (action->dev_id != dev_id)
+				continue;
+
+			/* Found it - now remove it from the list of entries */
+			*pp = action->next;
+			if (!desc->action) {
+				desc->status |= IRQ_DISABLED;
+				desc->handler->shutdown(irq);
+			}
+			spin_unlock_irqrestore(&desc->lock,flags);
+			kfree(action);
+			return;
+		}
+		printk("Trying to free free IRQ%d\n",irq);
+		spin_unlock_irqrestore(&desc->lock,flags);
+		return;
+	}
+}
+
+/*
+ * IRQ autodetection code..
+ *
+ * This depends on the fact that any interrupt that
+ * comes in on to an unassigned handler will get stuck
+ * with "IRQ_WAITING" cleared and the interrupt
+ * disabled.
+ */
+
+/**
+ *	probe_irq_on	- begin an interrupt autodetect
+ *
+ *	Commence probing for an interrupt. The interrupts are scanned
+ *	and a mask of potential interrupt lines is returned.
+ *
+ */
+unsigned long probe_irq_on(void)
+{
+	unsigned int i;
+	irq_desc_t *desc;
+	unsigned long val;
+	unsigned long delay;
+
+	/*
+	 * something may have generated an irq long ago and we want to
+	 * flush such a longstanding irq before considering it as spurious.
+	 */
+	for (i = NR_IRQS-1; i >= 0; i--) {
+		desc = irq_desc + i;
+
+		spin_lock_irq(&desc->lock);
+		if (!irq_desc[i].action) {
+			irq_desc[i].handler->startup(i);
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/* Wait for longstanding interrupts to trigger. */
+	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
+		/* about 20ms delay */ synchronize_irq();
+
+	/*
+	 * enable any unassigned irqs
+	 * (we must startup again here because if a longstanding irq
+	 * happened in the previous stage, it may have masked itself)
+	 */
+	for (i = NR_IRQS-1; i >= 0; i--) {
+		desc = irq_desc + 1;
+
+		spin_lock_irq(&desc->lock);
+		if (!desc->action) {
+			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
+			if (desc->handler->startup(i))
+				desc->status |= IRQ_PENDING;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	/*
+	 * Wait for spurious interrupts to trigger
+	 */
+	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
+		/* about 100ms delay */ synchronize_irq();
+
+	/*
+	 * Now filter out any obviously spurious interrupts
+	 */
+	val = 0;
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+
+		if (status & IRQ_AUTODETECT) {
+			/* It triggered already - consider it spurious. */
+			if (!(status & IRQ_WAITING)) {
+				desc->status = status & ~IRQ_AUTODETECT;
+				desc->handler->shutdown(i);
+			} else
+				if (i < 32)
+					val |= 1 << i;
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	return val;
+}
+
+/*
+ * Return the one interrupt that triggered (this can
+ * handle any interrupt source).
+ */
+
+/**
+ *	probe_irq_off   - end an interrupt autodetect
+ *	@val: mask of potential interrupts (unused)
+ *
+ *	Scans the unused interrupt lines and returns the line which
+ *	appears to have triggered the interrupt. If no interrupt was
+ *	found then zero is returned. If more than one interrupt is
+ *	found then minus the first candidate is returned to indicate
+ *	their is doubt.
+ *
+ *	The interrupt probe logic state is returned to its previous
+ *	value.
+ *
+ *	BUGS: When used in a module (which arguably shouldnt happen)
+ *	nothing prevents two IRQ probe callers from overlapping. The
+ *	results of this are non-optimal.
+ */
+int probe_irq_off(unsigned long val)
+{
+	int i, irq_found, nr_irqs;
+
+	nr_irqs = 0;
+	irq_found = 0;
+	for (i=0; i<NR_IRQS; i++) {
+		irq_desc_t *desc = irq_desc + i;
+		unsigned int status;
+
+		spin_lock_irq(&desc->lock);
+		status = desc->status;
+		if (!(status & IRQ_AUTODETECT))
+			continue;
+
+		if (status & IRQ_AUTODETECT) {
+			if (!(status & IRQ_WAITING)) {
+				if (!nr_irqs)
+					irq_found = i;
+				nr_irqs++;
+			}
+
+			desc->status = status & ~IRQ_AUTODETECT;
+			desc->handler->shutdown(i);
+		}
+		spin_unlock_irq(&desc->lock);
+	}
+
+	if (nr_irqs > 1)
+		irq_found = -irq_found;
+	return irq_found;
+}
+
+int setup_irq(unsigned int irq, struct irqaction * new)
+{
+	int shared = 0;
+	unsigned long flags;
+	struct irqaction *old, **p;
+	irq_desc_t *desc = irq_desc + irq;
+
+	/*
+	 * Some drivers like serial.c use request_irq() heavily,
+	 * so we have to be careful not to interfere with a
+	 * running system.
+	 */
+	if (new->flags & SA_SAMPLE_RANDOM) {
+		/*
+		 * This function might sleep, we want to call it first,
+		 * outside of the atomic block.
+		 * Yes, this might clear the entropy pool if the wrong
+		 * driver is attempted to be loaded, without actually
+		 * installing a new handler, but is this really a problem,
+		 * only the sysadmin is able to do this.
+		 */
+		rand_initialize_irq(irq);
+	}
+
+	/*
+	 * The following block of code has to be executed atomically
+	 */
+	spin_lock_irqsave(&desc->lock,flags);
+	p = &desc->action;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ)) {
+			spin_unlock_irqrestore(&desc->lock,flags);
+			return -EBUSY;
+		}
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+
+	*p = new;
+
+	if (!shared) {
+		desc->depth = 0;
+		desc->status &= ~IRQ_DISABLED;
+		desc->handler->startup(irq);
+	}
+	spin_unlock_irqrestore(&desc->lock,flags);
+
+	/*
+	 * No PROC FS support for interrupts.
+	 * For improvements in this area please check
+	 * the i386 branch.
+	 */
+	return 0;
+}
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
+
+void init_irq_proc(void)
+{
+	/*
+	 * No PROC FS support for interrupts.
+	 * For improvements in this area please check
+	 * the i386 branch.
+	 */
+}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/irq_intc.c linux-2.4.22-pre10/arch/sh64/kernel/irq_intc.c
--- linux-2.4.21/arch/sh64/kernel/irq_intc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/irq_intc.c	2003-08-01 13:34:06.000000000 +0000
@@ -0,0 +1,269 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/irq_intc.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ *
+ * Interrupt Controller support for SH5 INTC.
+ * Per-interrupt selective. IRLM=0 (Fixed priority) is not
+ * supported being useless without a cascaded interrupt
+ * controller.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+
+#include <asm/hardware.h>
+#include <asm/platform.h>
+#include <asm/bitops.h>		/* this includes also <asm/registers.h */
+				/* which is required to remap register */
+				/* names used into __asm__ blocks...   */
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+/*
+ * Maybe the generic Peripheral block could move to a more
+ * generic include file. INTC Block will be defined here
+ * and only here to make INTC self-contained in a single
+ * file.
+ */
+#define	INTC_BLOCK_OFFSET	0x01000000
+
+/* Base */
+#define INTC_BASE		PHYS_PERIPHERAL_BLOCK + \
+				INTC_BLOCK_OFFSET
+
+/* Address */
+#define INTC_ICR_SET		(intc_virt + 0x0)
+#define INTC_ICR_CLEAR		(intc_virt + 0x8)
+#define INTC_INTPRI_0		(intc_virt + 0x10)
+#define INTC_INTSRC_0		(intc_virt + 0x50)
+#define INTC_INTSRC_1		(intc_virt + 0x58)
+#define INTC_INTREQ_0		(intc_virt + 0x60)
+#define INTC_INTREQ_1		(intc_virt + 0x68)
+#define INTC_INTENB_0		(intc_virt + 0x70)
+#define INTC_INTENB_1		(intc_virt + 0x78)
+#define INTC_INTDSB_0		(intc_virt + 0x80)
+#define INTC_INTDSB_1		(intc_virt + 0x88)
+
+#define INTC_ICR_IRLM		0x1
+#define	INTC_INTPRI_PREGS	8		/* 8 Priority Registers */
+#define	INTC_INTPRI_PPREG	8		/* 8 Priorities per Register */
+
+
+/*
+ * Mapper between the vector ordinal and the IRQ number
+ * passed to kernel/device drivers.
+ */
+int intc_evt_to_irq[(0xE20/0x20)+1] = {
+	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0x000 - 0x0E0 */
+	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0x100 - 0x1E0 */
+	 0,  0,  0,  0,  0,  1,  0,  0,	/* 0x200 - 0x2E0 */
+	 2,  0,  0,  3,  0,  0,  0, -1,	/* 0x300 - 0x3E0 */
+	32, 33, 34, 35, 36, 37, 38, -1,	/* 0x400 - 0x4E0 */
+	-1, -1, -1, 63, -1, -1, -1, -1,	/* 0x500 - 0x5E0 */
+	-1, -1, 18, 19, 20, 21, 22, -1,	/* 0x600 - 0x6E0 */
+	39, 40, 41, 42, -1, -1, -1, -1,	/* 0x700 - 0x7E0 */
+	 4,  5,  6,  7, -1, -1, -1, -1,	/* 0x800 - 0x8E0 */
+	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0x900 - 0x9E0 */
+	12, 13, 14, 15, 16, 17, -1, -1,	/* 0xA00 - 0xAE0 */
+	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0xB00 - 0xBE0 */
+	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0xC00 - 0xCE0 */
+	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0xD00 - 0xDE0 */
+	-1, -1				/* 0xE00 - 0xE20 */
+};
+
+/*
+ * Opposite mapper.
+ */
+static int IRQ_to_vectorN[NR_INTC_IRQS] = {
+	0x12, 0x15, 0x18, 0x1B, 0x40, 0x41, 0x42, 0x43, /*  0- 7 */
+	  -1,   -1,   -1,   -1, 0x50, 0x51, 0x52, 0x53,	/*  8-15 */
+	0x54, 0x55, 0x32, 0x33, 0x34, 0x35, 0x36,   -1, /* 16-23 */
+	  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, /* 24-31 */
+	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x38,	/* 32-39 */
+        0x39, 0x3A, 0x3B,   -1,   -1,   -1,   -1,   -1, /* 40-47 */
+	  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, /* 48-55 */
+	  -1,   -1,   -1,   -1,   -1,   -1,   -1, 0x2B, /* 56-63 */
+	  
+};
+
+static unsigned long intc_virt;
+
+static unsigned int startup_intc_irq(unsigned int irq);
+static void shutdown_intc_irq(unsigned int irq);
+static void enable_intc_irq(unsigned int irq);
+static void disable_intc_irq(unsigned int irq);
+static void mask_and_ack_intc(unsigned int);
+static void end_intc_irq(unsigned int irq);
+
+static struct hw_interrupt_type intc_irq_type = {
+	"INTC",
+	startup_intc_irq,
+	shutdown_intc_irq,
+	enable_intc_irq,
+	disable_intc_irq,
+	mask_and_ack_intc,
+	end_intc_irq
+};
+
+static int irlm;		/* IRL mode */
+
+static unsigned int startup_intc_irq(unsigned int irq)
+{ 
+	enable_intc_irq(irq);
+	return 0; /* never anything pending */
+}
+
+static void shutdown_intc_irq(unsigned int irq)
+{
+	disable_intc_irq(irq);
+}
+
+static void enable_intc_irq(unsigned int irq)
+{
+	unsigned long reg;
+	unsigned long bitmask;
+
+	if ((irq <= IRQ_IRL3) && (irlm == NO_PRIORITY))
+		printk("Trying to use straight IRL0-3 with an encoding platform.\n");
+
+	if (irq < 32) {
+		reg = INTC_INTENB_0;
+		bitmask = 1 << irq;
+	} else {
+		reg = INTC_INTENB_1;
+		bitmask = 1 << (irq - 32);
+	}
+
+	ctrl_outl(bitmask, reg);
+}
+
+static void disable_intc_irq(unsigned int irq)
+{
+	unsigned long reg;
+	unsigned long bitmask;
+
+	if (irq < 32) {
+		reg = INTC_INTDSB_0;
+		bitmask = 1 << irq;
+	} else {
+		reg = INTC_INTDSB_1;
+		bitmask = 1 << (irq - 32);
+	}
+
+	ctrl_outl(bitmask, reg);
+}
+
+static void mask_and_ack_intc(unsigned int irq)
+{
+	disable_intc_irq(irq);
+}
+
+static void end_intc_irq(unsigned int irq)
+{
+	enable_intc_irq(irq);	
+}
+
+/* For future use, if we ever support IRLM=0) */
+void make_intc_irq(unsigned int irq)
+{
+	disable_irq_nosync(irq);
+	irq_desc[irq].handler = &intc_irq_type;
+	disable_intc_irq(irq);
+}
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
+int intc_irq_describe(char* p, int irq)
+{
+	if (irq < NR_INTC_IRQS)
+		return sprintf(p, "(0x%3x)", IRQ_to_vectorN[irq]*0x20);
+	else
+		return 0;
+}
+#endif
+
+void __init init_IRQ(void)
+{
+        unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
+	unsigned long reg;
+	unsigned long data;
+	int i;
+
+	intc_virt = onchip_remap(INTC_BASE, 1024, "INTC");
+	if (!intc_virt) {
+		panic("Unable to remap INTC\n");
+	}
+
+
+	/* Set default: per-line enable/disable, priority driven ack/eoi */
+	for (i = 0; i < NR_INTC_IRQS; i++) {
+		if (platform_int_priority[i] != NO_PRIORITY) {
+			irq_desc[i].handler = &intc_irq_type;
+		}
+	}
+
+
+	/* Disable all interrupts and set all priorities to 0 to avoid trouble */
+	ctrl_outl(-1, INTC_INTDSB_0);
+	ctrl_outl(-1, INTC_INTDSB_1);
+
+	for (reg = INTC_INTPRI_0, i = 0; i < INTC_INTPRI_PREGS; i++, reg += 8)
+		ctrl_outl( NO_PRIORITY, reg);
+		
+
+	/* Set IRLM */
+	/* If all the priorities are set to 'no priority', then
+	 * assume we are using encoded mode.
+	 */
+	irlm = platform_int_priority[IRQ_IRL0] + platform_int_priority[IRQ_IRL1] + \
+		platform_int_priority[IRQ_IRL2] + platform_int_priority[IRQ_IRL3];
+
+	if (irlm == NO_PRIORITY) {
+		/* IRLM = 0 */
+		reg = INTC_ICR_CLEAR;
+		i = IRQ_INTA;
+		printk("Trying to use encoded IRL0-3. IRLs unsupported.\n");
+	} else {
+		/* IRLM = 1 */
+		reg = INTC_ICR_SET;
+		i = IRQ_IRL0;
+	}
+	ctrl_outl(INTC_ICR_IRLM, reg);
+
+	/* Set interrupt priorities according to platform description */
+	for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
+		data |= platform_int_priority[i] << ((i % INTC_INTPRI_PPREG) * 4);
+		if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
+			/* Upon the 7th, set Priority Register */
+			ctrl_outl(data, reg);
+			data = 0;
+			reg += 8;
+		}
+	}
+
+#ifdef CONFIG_SH_CAYMAN
+	extern void init_cayman_irq(void);
+
+	init_cayman_irq();
+#endif
+
+	/*
+	 * And now let interrupts come in.
+	 * sti() is not enough, we need to
+	 * lower priority, too.
+	 */
+        __asm__ __volatile__("getcon    " __c0 ", %0\n\t"
+                             "and       %0, %1, %0\n\t"
+                             "putcon    %0, " __c0 "\n\t"
+                             : "=&r" (__dummy0)
+                             : "r" (__dummy1));
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/led.c linux-2.4.22-pre10/arch/sh64/kernel/led.c
--- linux-2.4.21/arch/sh64/kernel/led.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/led.c	2003-08-01 13:33:51.000000000 +0000
@@ -0,0 +1,69 @@
+/*
+ * arch/sh64/kernel/led.c
+ *
+ * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Flash the LEDs
+ */
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+
+void mach_alphanum(int pos, unsigned char val);
+void mach_led(int pos, int val);
+
+void print_seg(char *file, int line)
+{
+	int i;
+	unsigned int nibble;
+
+	for (i = 0; i < 5; i++) {
+		mach_alphanum(i, file[i]);
+	}
+
+	for (i = 0; i < 3; i++) {
+		nibble = ((line >> (i * 4)) & 0xf);
+		mach_alphanum(7 - i, nibble + ((nibble > 9) ? 55 : 48));
+	}
+}
+
+void print_seg_num(unsigned num)
+{
+	int i;
+	unsigned int nibble;
+
+	for (i = 0; i < 8; i++) {
+		nibble = ((num >> (i * 4)) & 0xf);
+
+		mach_alphanum(7 - i, nibble + ((nibble > 9) ? 55 : 48));
+	}
+}
+
+/* acts like an actual heart beat -- ie thump-thump-pause... */
+void heartbeat(void)
+{
+	static unsigned int cnt = 0, period = 0, dist = 0;
+
+	if (cnt == 0 || cnt == dist) {
+		mach_led(-1, 1);
+	} else if (cnt == 7 || cnt == dist + 7) {
+		mach_led(-1, 0);
+	}
+
+	if (++cnt > period) {
+		cnt = 0;
+
+		/* 
+		 * The hyperbolic function below modifies the heartbeat period
+		 * length in dependency of the current (5min) load. It goes
+		 * through the points f(0)=126, f(1)=86, f(5)=51, f(inf)->30.
+		 */
+		period = ((672 << FSHIFT) / (5 * avenrun[0] +
+					    (7 << FSHIFT))) + 30;
+		dist = period / 4;
+	}
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/pci-dma.c linux-2.4.22-pre10/arch/sh64/kernel/pci-dma.c
--- linux-2.4.21/arch/sh64/kernel/pci-dma.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/pci-dma.c	2003-08-01 13:34:05.000000000 +0000
@@ -0,0 +1,50 @@
+/* 
+ * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
+ * Copyright (C) 2003 Paul Mundt (lethal@linux-sh.org)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * Dynamic DMA mapping support.
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+			   dma_addr_t *dma_handle)
+{
+	void *ret;
+	int gfp = GFP_ATOMIC;
+        void *vp;
+
+	if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
+		gfp |= GFP_DMA;
+
+	ret = (void *)__get_free_pages(gfp, get_order(size));
+
+	/* now call our friend ioremap_nocache to give us an uncached area */
+        vp = ioremap_nocache(virt_to_phys(ret), size);
+
+	if (vp != NULL) {
+		memset(vp, 0, size);
+		*dma_handle = virt_to_bus(ret);
+		dma_cache_wback_inv((unsigned long)ret, size);
+	}
+
+	return vp;
+}
+
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	void *alloc;
+
+	alloc = bus_to_virt((unsigned long)dma_handle);
+	free_pages((unsigned long)alloc, get_order(size));
+
+	iounmap(vaddr);
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/pci_sh5.c linux-2.4.22-pre10/arch/sh64/kernel/pci_sh5.c
--- linux-2.4.21/arch/sh64/kernel/pci_sh5.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/pci_sh5.c	2003-08-01 13:30:27.000000000 +0000
@@ -0,0 +1,620 @@
+/* 
+ * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * Support functions for the SH5 PCI hardware.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <asm/pci.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include "pci_sh5.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#  define dprintk(x...)  printk(KERN_DEBUG x)
+#else
+#  define dprintk(x...)  do { } while (0)
+#endif /* DEBUG */
+
+static unsigned long pcicr_virt;
+unsigned long pciio_virt;
+
+static void __init pci_fixup_ide_bases(struct pci_dev *d)
+{
+	int i;
+
+	/*
+	 * PCI IDE controllers use non-standard I/O port decoding, respect it.
+	 */
+	if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
+		return;
+	printk("PCI: IDE base address fixup for %s\n", d->slot_name);
+	for(i=0; i<4; i++) {
+		struct resource *r = &d->resource[i];
+		if ((r->start & ~0x80) == 0x374) {
+			r->start |= 2;
+			r->end = r->start;
+		}
+	}
+}
+
+/* Add future fixups here... */
+struct pci_fixup pcibios_fixups[] = {
+	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,	PCI_ANY_ID,	pci_fixup_ide_bases },
+	{ 0 }
+};
+
+char * __init pcibios_setup(char *str)
+{
+	return str;
+}
+
+/* Rounds a number UP to the nearest power of two. Used for
+ * sizing the PCI window.
+ */
+static u32 __init r2p2(u32 num)
+{
+	int i = 31;
+	u32 tmp = num;
+
+	if (num == 0)
+		return 0;
+
+	do {
+		if (tmp & (1 << 31))
+			break;
+		i--;
+		tmp <<= 1;
+	} while (i >= 0);
+
+	tmp = 1 << i;
+	/* If the original number isn't a power of 2, round it up */
+	if (tmp != num)
+		tmp <<= 1;
+
+	return tmp;
+}
+
+extern unsigned long long memory_start, memory_end;
+
+int __init sh5pci_init(unsigned memStart, unsigned memSize)
+{
+	u32 lsr0;
+	u32 uval;
+
+	pcicr_virt = onchip_remap(SH5PCI_ICR_BASE, 1024, "PCICR");
+	if (!pcicr_virt) {
+		panic("Unable to remap PCICR\n");
+	}
+
+	pciio_virt = onchip_remap(SH5PCI_IO_BASE, 0x10000, "PCIIO");
+	if (!pciio_virt) {
+		panic("Unable to remap PCIIO\n");
+	}
+
+	dprintk("Register base addres is 0x%08lx\n", pcicr_virt);
+
+	/* Clear snoop registers */
+        SH5PCI_WRITE(CSCR0, 0);
+        SH5PCI_WRITE(CSCR1, 0);
+
+	dprintk("Wrote to reg\n");
+
+        /* Switch off interrupts */
+        SH5PCI_WRITE(INTM,  0);
+        SH5PCI_WRITE(AINTM, 0);
+        SH5PCI_WRITE(PINTM, 0);
+
+        /* Set bus active, take it out of reset */
+        uval = SH5PCI_READ(CR);
+
+	/* Set command Register */
+        SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE | CR_PFCS | CR_BMAM );
+
+	uval=SH5PCI_READ(CR);
+        dprintk("CR is actually 0x%08x\n",uval);
+
+        /* Allow it to be a master */
+	/* NB - WE DISABLE I/O ACCESS to stop overlap */
+        /* set WAIT bit to enable stepping, an attempt to improve stability */
+	SH5PCI_WRITE_SHORT(CSR_CMD,
+			    PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_WAIT);
+
+        /* 
+        ** Set translation mapping memory in order to convert the address
+        ** used for the main bus, to the PCI internal address.
+        */
+        SH5PCI_WRITE(MBR,0x40000000);
+
+        /* Always set the max size 512M */
+        SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
+
+        /* 
+        ** I/O addresses are mapped at internal PCI specific address
+        ** as is described into the configuration bridge table.
+        ** These are changed to 0, to allow cards that have legacy 
+        ** io such as vga to function correctly. We set the SH5 IOBAR to
+        ** 256K, which is a bit big as we can only have 64K of address space
+        */
+
+        SH5PCI_WRITE(IOBR,0x0);
+      	
+	dprintk("PCI:Writing 0x%08x to IOBR\n",0);
+
+        /* Set up a 256K window. Totally pointless waste  of address space */
+        SH5PCI_WRITE(IOBMR,0);
+	dprintk("PCI:Writing 0x%08x to IOBMR\n",0);
+
+	/* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec. Ideally, 
+         * we would want to map the I/O region somewhere, but it is so big this is not
+         * that easy!
+         */
+	SH5PCI_WRITE(CSR_IBAR0,~0);
+	/* Set memory size value */
+        memSize = memory_end - memory_start;
+
+        /* Now we set up the mbars so the PCI bus can see the memory of the machine */
+        if (memSize < (1024 * 1024)) {
+                printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%x?\n", memSize);
+                return(-1);
+        }
+
+        /* Set LSR 0 */
+        lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 : ((r2p2(memSize) - 0x100000) | 0x1);
+        SH5PCI_WRITE(LSR0, lsr0);
+
+	dprintk("PCI:Writing 0x%08x to LSR0\n",lsr0);
+
+        /* Set MBAR 0 */
+        SH5PCI_WRITE(CSR_MBAR0, memory_start);
+        SH5PCI_WRITE(LAR0, memory_start);
+
+
+        SH5PCI_WRITE(CSR_MBAR1,0);
+        SH5PCI_WRITE(LAR1,0);
+        SH5PCI_WRITE(LSR1,0);
+
+	dprintk("PCI:Writing 0x%08llx to CSR_MBAR0\n",memory_start);         
+	dprintk("PCI:Writing 0x%08llx to LAR0\n",memory_start);         
+
+        /* Enable the PCI interrupts on the device */
+
+#if 1
+        SH5PCI_WRITE(INTM,  ~0);
+        SH5PCI_WRITE(AINTM, ~0);
+        SH5PCI_WRITE(PINTM, ~0);
+#endif
+
+	dprintk("Switching on all error interrupts\n");
+
+        return(0);
+}
+
+
+
+/* Write to config register */
+static int sh5pci_read_config_byte(struct pci_dev *dev, int where,
+				    u8 * val)
+{
+	SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
+
+	*val = SH5PCI_READ_BYTE(PDR + (where & 3));
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int sh5pci_read_config_word(struct pci_dev *dev, int where,
+				    u16 * val)
+{
+	SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
+
+	*val = SH5PCI_READ_SHORT(PDR + (where & 2));
+
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int sh5pci_read_config_dword(struct pci_dev *dev, int where,
+				     u32 * val)
+{
+	SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
+
+	*val = SH5PCI_READ(PDR);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int sh5pci_write_config_byte(struct pci_dev *dev, int where,
+				     u8 val)
+{
+	SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
+
+	SH5PCI_WRITE_BYTE(PDR + (where & 3), val);
+
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int sh5pci_write_config_word(struct pci_dev *dev, int where,
+				     u16 val)
+{
+	SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
+
+	SH5PCI_WRITE_SHORT(PDR + (where & 2), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int sh5pci_write_config_dword(struct pci_dev *dev, int where,
+				      u32 val)
+{
+	SH5PCI_WRITE(PAR, CONFIG_CMD(dev, where));
+
+	SH5PCI_WRITE(PDR, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static struct pci_ops pci_config_ops = {
+	sh5pci_read_config_byte,
+	sh5pci_read_config_word,
+	sh5pci_read_config_dword,
+	sh5pci_write_config_byte,
+	sh5pci_write_config_word,
+	sh5pci_write_config_dword
+};
+
+/* Everything hangs off this */
+static struct pci_bus *pci_root_bus;
+
+
+static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
+{
+	dprintk("swizzle for dev %d on bus %d slot %d pin is %d\n",
+	       dev->devfn,dev->bus->number, PCI_SLOT(dev->devfn),*pin);
+	return PCI_SLOT(dev->devfn);
+}
+
+static inline u8 bridge_swizzle(u8 pin, u8 slot) 
+{
+	return (((pin-1) + slot) % 4) + 1;
+}
+
+u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	if (dev->bus->number != 0) {
+		u8 pin = *pinp;
+		do {
+			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+			/* Move up the chain of bridges. */
+			dev = dev->bus->self;
+		} while (dev->bus->self);
+		*pinp = pin;
+
+		/* The slot is the slot of the last bridge. */
+	}
+
+	return PCI_SLOT(dev->devfn);
+}
+
+/* This needs to be shunted out of here into the board specific bit */
+
+static int __init map_cayman_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int result = -1;
+
+	if (dev->bus->number == 0) {
+	        switch ((slot + (pin-1)) & 3) {
+	        case 0:
+	          result = IRQ_INTA;
+		  break;
+                case 1:
+	          result = IRQ_INTB;
+		  break;
+                case 2:
+	          result = IRQ_INTC;
+		  break;
+		case 3:
+		  result = IRQ_INTD;
+		  break;
+                }
+        }
+
+	if (dev->bus->number == 2) {
+	        switch((slot + (pin-1)) & 3) {
+	        case 0:
+	          result = IRQ_P2INTA;
+		  break;
+                case 1:
+	          result = IRQ_P2INTB;
+		  break;
+                case 2:
+	          result = IRQ_P2INTC;
+		  break;
+                case 3:
+	          result = IRQ_P2INTD;
+		  break;
+                }
+        }
+
+	dprintk("map_cayman_irq for dev %d on bus %d slot %d, pin is %d : irq=%d\n",
+	       dev->devfn,dev->bus->number,slot,pin,result);
+
+	return result;
+}
+
+#ifdef DEBUG
+void print_resource(struct resource *r) 
+{
+	if (r == NULL)
+		return;
+
+	//printk("Resource %s\n",r->name);
+	printk("Start 0x%lx end 0x%lx\n",r->start,r->end);
+}
+
+void print_set_ranges_data(struct pbus_set_ranges_data *ranges)
+{
+
+	if (!ranges) {
+		printk("NO RANGES\n");
+		return;
+	}
+
+	printk("io_start is 0x%lx\n", ranges->io_start);
+	printk("io_end is 0x%lx\n", ranges->io_end);
+	printk("mem_start is 0x%lx\n", ranges->mem_start);
+	printk("mem_end is 0x%lx\n", ranges->mem_end);
+}
+#endif /* DEBUG */
+
+void __init
+  pcibios_fixup_pbus_ranges(struct pci_bus *bus,
+	        struct pbus_set_ranges_data *ranges)
+{
+#ifdef DEBUG
+	int i;
+
+	dprintk("%s, bus number %d\n",__FUNCTION__,bus->number);
+
+	print_set_ranges_data(ranges);
+
+	for (i = 0; i < 2; i++)
+		print_resource(bus->resource[i]);
+#endif
+}
+
+void  pcish5_err_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned pci_int, pci_air, pci_cir, pci_aint;
+
+	pci_int = SH5PCI_READ(INT);
+	pci_cir = SH5PCI_READ(CIR);
+	pci_air = SH5PCI_READ(AIR);
+
+	if (pci_int) {
+		printk("PCI INTERRUPT (at %08llx)!\n", regs->pc);
+		printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
+		printk("PCI AIR -> 0x%x\n", pci_air);
+		printk("PCI CIR -> 0x%x\n", pci_cir);
+		SH5PCI_WRITE(INT, ~0);
+	}
+
+	pci_aint = SH5PCI_READ(AINT);
+	if (pci_aint) {
+		printk("PCI ARB INTERRUPT!\n");
+		printk("PCI AINT -> 0x%x\n", pci_aint);
+		printk("PCI AIR -> 0x%x\n", pci_air);
+		printk("PCI CIR -> 0x%x\n", pci_cir);
+		SH5PCI_WRITE(AINT, ~0);
+	}
+
+}
+
+
+void pcish5_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+  printk("SERR IRQ\n");
+
+}
+
+#define ROUND_UP(x, a)		(((x) + (a) - 1) & ~((a) - 1))
+
+static void __init
+pcibios_size_bridge(struct pci_bus *bus, struct pbus_set_ranges_data *outer)
+{
+	struct pbus_set_ranges_data inner;
+	struct pci_dev *dev;
+	struct pci_dev *bridge = bus->self;
+	struct list_head *ln;
+
+	if (!bridge)
+		return;	/* host bridge, nothing to do */
+
+	/* set reasonable default locations for pcibios_align_resource */
+	inner.io_start = PCIBIOS_MIN_IO;
+	inner.mem_start = PCIBIOS_MIN_MEM;
+	inner.io_end = inner.io_start;
+	inner.mem_end = inner.mem_start;
+
+	/* Collect information about how our direct children are layed out. */
+	for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
+		int i;
+		dev = pci_dev_b(ln);
+
+		/* Skip bridges for now */
+		if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI)
+			continue;
+
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			struct resource res;
+			unsigned long size;
+
+			memcpy(&res, &dev->resource[i], sizeof(res));
+			size = res.end - res.start + 1;
+
+			if (res.flags & IORESOURCE_IO) {
+				res.start = inner.io_end;
+				pcibios_align_resource(dev, &res, size, 0);
+				inner.io_end = res.start + size;
+			} else if (res.flags & IORESOURCE_MEM) {
+				res.start = inner.mem_end;
+				pcibios_align_resource(dev, &res, size, 0);
+				inner.mem_end = res.start + size;
+			}
+		}
+	}
+
+	/* And for all of the subordinate busses. */
+	for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
+		pcibios_size_bridge(pci_bus_b(ln), &inner);
+
+	/* turn the ending locations into sizes (subtract start) */
+	inner.io_end -= inner.io_start;
+	inner.mem_end -= inner.mem_start;
+
+	/* Align the sizes up by bridge rules */
+	inner.io_end = ROUND_UP(inner.io_end, 4*1024) - 1;
+	inner.mem_end = ROUND_UP(inner.mem_end, 1*1024*1024) - 1;
+
+	/* Adjust the bridge's allocation requirements */
+	bridge->resource[0].end = bridge->resource[0].start + inner.io_end;
+	bridge->resource[1].end = bridge->resource[1].start + inner.mem_end;
+
+	bridge->resource[PCI_BRIDGE_RESOURCES].end =
+	    bridge->resource[PCI_BRIDGE_RESOURCES].start + inner.io_end;
+	bridge->resource[PCI_BRIDGE_RESOURCES+1].end =
+	    bridge->resource[PCI_BRIDGE_RESOURCES+1].start + inner.mem_end;
+
+	/* adjust parent's resource requirements */
+	if (outer) {
+		outer->io_end = ROUND_UP(outer->io_end, 4*1024);
+		outer->io_end += inner.io_end;
+
+		outer->mem_end = ROUND_UP(outer->mem_end, 1*1024*1024);
+		outer->mem_end += inner.mem_end;
+	}
+}
+
+#undef ROUND_UP
+
+static void __init 
+pcibios_size_bridges(void)
+{
+	struct pbus_set_ranges_data outer;
+
+	memset(&outer,0,sizeof(outer));
+	pcibios_size_bridge(pci_root_bus,&outer);
+}
+
+void __init
+common_init_pci(void)
+{
+	pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
+	pcibios_size_bridges();
+	pci_assign_unassigned_resources();
+	pci_fixup_irqs(no_swizzle, map_cayman_irq);
+	//	pci_set_bus_ranges();
+}
+
+void __init pcibios_init(void)
+{
+
+        if (request_irq(IRQ_ERR, pcish5_err_irq,
+                        SA_INTERRUPT, "PCI Error",NULL) < 0) {
+                printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
+		return;
+        }
+
+
+        if (request_irq(IRQ_SERR, pcish5_serr_irq,
+                        SA_INTERRUPT, "PCI SERR interrupt", NULL) < 0) {
+                printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
+		return;
+        }
+
+
+	/* The pci subsytem needs to know where memory is and how much 
+	 * of it there is. I've simply made these globals. A better mechanism
+	 * is probably needed. 
+	 */
+	sh5pci_init(__pa(memory_start),
+		     __pa(memory_end) - __pa(memory_start));
+
+
+	common_init_pci();
+
+#if 0
+	pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
+
+	pci_assign_unassigned_resources();
+
+	pci_fixup_irqs(no_swizzle, map_cayman_irq);
+
+	pci_set_bus_ranges();
+#endif
+
+}
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_dev *dev = bus->self;
+	int i;
+
+#if 1
+	if(dev) {
+		for(i=0; i<3; i++) {
+			bus->resource[i] =
+				&dev->resource[PCI_BRIDGE_RESOURCES+i];
+			bus->resource[i]->name = bus->name;
+		}
+		bus->resource[0]->flags |= IORESOURCE_IO;
+		bus->resource[1]->flags |= IORESOURCE_MEM;
+
+		/* For now, propogate host limits to the bus;
+		 * we'll adjust them later. */
+
+#if 1
+		bus->resource[0]->end = 64*1024 - 1 ;
+		bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1;
+		bus->resource[0]->start = PCIBIOS_MIN_IO;
+		bus->resource[1]->start = PCIBIOS_MIN_MEM;
+#else
+		bus->resource[0]->end = 0
+		bus->resource[1]->end = 0
+		bus->resource[0]->start =0
+		  bus->resource[1]->start = 0;
+#endif
+
+#ifdef DEBUG
+		dprintk("in fixup bus resource 0 is:\n");
+		print_resource(bus->resource[0]);
+		dprintk("in fixup bus resource 1 is:\n");
+		print_resource(bus->resource[1]);
+#endif /* DEBUG */
+		
+		/* Turn off downstream PF memory address range by default */
+		bus->resource[2]->start = 1024*1024;
+		bus->resource[2]->end = bus->resource[2]->start - 1;
+	}
+#endif 
+
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/pci_sh5.h linux-2.4.22-pre10/arch/sh64/kernel/pci_sh5.h
--- linux-2.4.21/arch/sh64/kernel/pci_sh5.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/pci_sh5.h	2003-08-01 13:33:05.000000000 +0000
@@ -0,0 +1,107 @@
+/* 
+ * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.                            
+ *
+ * Defintions for the SH5 PCI hardware.
+ */
+
+/* Product ID */
+#define PCISH5_PID		0x350d
+
+/* vendor ID */
+#define PCISH5_VID		0x1054
+
+/* Configuration types */
+#define ST_TYPE0                0x00    /* Configuration cycle type 0 */
+#define ST_TYPE1                0x01    /* Configuration cycle type 1 */
+
+/* VCR data */
+#define PCISH5_VCR_STATUS      0x00
+#define PCISH5_VCR_VERSION     0x08
+
+/*
+** ICR register offsets and bits
+*/ 
+#define PCISH5_ICR_CR          0x100   /* PCI control register values */
+#define CR_PBAM                 (1<<12)
+#define CR_PFCS                 (1<<11)
+#define CR_FTO                  (1<<10)
+#define CR_PFE                  (1<<9)
+#define CR_TBS                  (1<<8)
+#define CR_SPUE                 (1<<7)
+#define CR_BMAM                 (1<<6)
+#define CR_HOST                 (1<<5)
+#define CR_CLKEN                (1<<4)
+#define CR_SOCS                 (1<<3)
+#define CR_IOCS                 (1<<2)
+#define CR_RSTCTL               (1<<1)
+#define CR_CFINT                (1<<0)
+#define CR_LOCK_MASK            0xa5000000
+
+#define PCISH5_ICR_INT         0x114   /* Interrupt registert values     */
+#define INT_MADIM               (1<<2)
+
+#define PCISH5_ICR_LSR0        0X104   /* Local space register values    */
+#define PCISH5_ICR_LSR1        0X108   /* Local space register values    */
+#define PCISH5_ICR_LAR0        0x10c   /* Local address register values  */
+#define PCISH5_ICR_LAR1        0x110   /* Local address register values  */
+#define PCISH5_ICR_INTM        0x118   /* Interrupt mask register values                         */
+#define PCISH5_ICR_AIR         0x11c   /* Interrupt error address information register values    */
+#define PCISH5_ICR_CIR         0x120   /* Interrupt error command information register values    */
+#define PCISH5_ICR_AINT        0x130   /* Interrupt error arbiter interrupt register values      */
+#define PCISH5_ICR_AINTM       0x134   /* Interrupt error arbiter interrupt mask register values */
+#define PCISH5_ICR_BMIR        0x138   /* Interrupt error info register of bus master values     */
+#define PCISH5_ICR_PAR         0x1c0   /* Pio address register values                            */
+#define PCISH5_ICR_MBR         0x1c4   /* Memory space bank register values                      */
+#define PCISH5_ICR_IOBR        0x1c8   /* I/O space bank register values                         */
+#define PCISH5_ICR_PINT        0x1cc   /* power management interrupt register values             */
+#define PCISH5_ICR_PINTM       0x1d0   /* power management interrupt mask register values        */
+#define PCISH5_ICR_MBMR        0x1d8   /* memory space bank mask register values                 */
+#define PCISH5_ICR_IOBMR       0x1dc   /* I/O space bank mask register values                    */
+#define PCISH5_ICR_CSCR0       0x210   /* PCI cache snoop control register 0                     */
+#define PCISH5_ICR_CSCR1       0x214   /* PCI cache snoop control register 1                     */
+#define PCISH5_ICR_PDR         0x220   /* Pio data register values                               */
+
+/* These are configs space registers */
+#define PCISH5_ICR_CSR_VID     0x000	/* Vendor id                           */
+#define PCISH5_ICR_CSR_DID     0x002   /* Device id                           */
+#define PCISH5_ICR_CSR_CMD     0x004   /* Command register                    */
+#define PCISH5_ICR_CSR_STATUS  0x006   /* Stautus                             */
+#define PCISH5_ICR_CSR_IBAR0   0x010   /* I/O base address register           */
+#define PCISH5_ICR_CSR_MBAR0   0x014   /* First  Memory base address register */
+#define PCISH5_ICR_CSR_MBAR1   0x018   /* Second Memory base address register */
+
+
+
+/* Base address of registers */
+#define SH5PCI_ICR_BASE (PHYS_PCI_BLOCK + 0x00040000) 
+#define SH5PCI_IO_BASE  (PHYS_PCI_BLOCK + 0x00800000)
+/* #define SH5PCI_VCR_BASE (P2SEG_PCICB_BLOCK + P2SEG)    */
+
+/* Register selection macro */
+#define PCISH5_ICR_REG(x)                ( pcicr_virt + (PCISH5_ICR_##x))
+/* #define PCISH5_VCR_REG(x)                ( SH5PCI_VCR_BASE (PCISH5_VCR_##x)) */
+
+/* Write I/O functions */
+#define SH5PCI_WRITE(reg,val)        ctrl_outl((u32)(val),PCISH5_ICR_REG(reg))
+#define SH5PCI_WRITE_SHORT(reg,val)  ctrl_outw((u16)(val),PCISH5_ICR_REG(reg))
+#define SH5PCI_WRITE_BYTE(reg,val)   ctrl_outb((u8)(val),PCISH5_ICR_REG(reg))
+
+/* Read I/O functions */
+#define SH5PCI_READ(reg)             ctrl_inl(PCISH5_ICR_REG(reg))
+#define SH5PCI_READ_SHORT(reg)       ctrl_inw(PCISH5_ICR_REG(reg))
+#define SH5PCI_READ_BYTE(reg)        ctrl_inb(PCISH5_ICR_REG(reg))
+
+/* Set PCI config bits */
+#define SET_CONFIG_BITS(bus,devfn,where)  ((((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) | 0x80000000)
+
+/* Set PCI command register */
+#define CONFIG_CMD(dev, where)            SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where)
+
+/* Size converters */
+#define PCISH5_MEM_SIZCONV(x)		  (((x / 0x40000) - 1) << 18)
+#define PCISH5_IO_SIZCONV(x)		  (((x / 0x40000) - 1) << 18)
+
+
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/pcibios.c linux-2.4.22-pre10/arch/sh64/kernel/pcibios.c
--- linux-2.4.21/arch/sh64/kernel/pcibios.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/pcibios.c	2003-08-01 13:31:51.000000000 +0000
@@ -0,0 +1,129 @@
+/*
+ * $Id: pcibios.c,v 1.1 2001/08/24 12:38:19 dwmw2 Exp $
+ *
+ * arch/sh/kernel/pcibios.c
+ *
+ * This is GPL'd.
+ *
+ * Provided here are generic versions of:
+ *	pcibios_update_resource()
+ *	pcibios_align_resource()
+ *	pcibios_enable_device()
+ *	pcibios_set_master()
+ *	pcibios_update_irq()
+ *
+ * These functions are collected here to reduce duplication of common
+ * code amongst the many platform-specific PCI support code files.
+ *
+ * Platform-specific files are expected to provide:
+ *	pcibios_fixup_bus()
+ *	pcibios_init()
+ *	pcibios_setup()
+ *	pcibios_fixup_pbus_ranges()
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4*resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		new |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/* Somebody might have asked allocation of a non-standard resource */
+		return;
+	}
+	
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+		       new, check);
+	}
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ */
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size, unsigned long align)
+{
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		if (start & 0x300) {
+			start = (start + 0x3ff) & ~0x3ff;
+			res->start = start;
+		}
+	}
+}
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for(idx=0; idx<6; idx++) {
+		if (!(mask & (1 << idx)))
+			continue;
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (dev->resource[PCI_ROM_RESOURCE].start)
+		cmd |= PCI_COMMAND_MEMORY;
+	if (cmd != old_cmd) {
+		printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", dev->name, old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+/*
+ *  If we set up a device for bus mastering, we need to check and set
+ *  the latency timer as it may not be properly set.
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	if (lat < 16)
+		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+	else if (lat > pcibios_max_latency)
+		lat = pcibios_max_latency;
+	else
+		return;
+	printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", dev->name, lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.21/arch/sh64/kernel/process.c linux-2.4.22-pre10/arch/sh64/kernel/process.c
--- linux-2.4.21/arch/sh64/kernel/process.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.22-pre10/arch/sh64/kernel/process.c	2003-08-01 13:31:22.000000000 +0000
@@ -0,0 +1,939 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * arch/sh64/kernel/process.c
+ *
+ * Copyright (C) 2000, 2001  Paolo Alberelli
+ * Copyright (C) 2003  Paul Mundt
+ *
+ * Started from SH3/4 version:
+ *   Copyright (C) 1999, 2000  Niibe Yutaka & Kaz Kojima
+ *
+ *   In turn started from i386 version:
+ *     Copyright (C) 1995  Linus Torvalds
+ *
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+/* Temporary flags/tests. All to be removed/undefined. BEGIN */
+#define IDLE_TRACE
+#define VM_SHOW_TABLES
+#define VM_TEST_FAULT
+#define VM_TEST_RTLBMISS
+#define VM_TEST_WTLBMISS
+
+#undef VM_SHOW_TABLES
+#undef IDLE_TRACE
+/* Temporary flags/tests. All to be removed/undefined. END */
+
+#define __KERNEL_SYSCALLS__
+#include <stdarg.h>
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/interrupt.h>
+#include <linux/unistd.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/processor.h>		/* includes also <asm/registers.h> */
+#include <asm/mmu_context.h>
+#include <asm/elf.h>
+#include <asm/page.h>
+
+#include <linux/irq.h>
+
+struct task_struct *last_task_used_math = NULL;
+
+#ifdef IDLE_TRACE
+#ifdef VM_SHOW_TABLES
+/* For testing */
+static void print_PTE(long base)
+{
+	int i, skip=0;
+	long long x, y, *p = (long long *) base;
+
+	for (i=0; i< 512; i++, p++){
+		if (*p == 0) {
+			if (!skip) {	
+				skip++;
+				printk("(0s) ");
+			}
+		} else {	
+			skip=0;
+			x = (*p) >> 32;
+			y = (*p) & 0xffffffff;
+			printk("%08Lx%08Lx ", x, y);
+			if (!((i+1)&0x3)) printk("\n");
+		}
+	}
+}
+
+/* For testing */
+static void print_DIR(long base)
+{
+	int i, skip=0;
+	long *p = (long *) base;
+
+	for (i=0; i< 512; i++, p++){
+		if (*p == 0) {
+			if (!skip) {	
+				skip++;
+				printk("(0s) ");
+			}
+		} else {	
+			skip=0;
+			printk("%08lx ", *p);
+			if (!((i+1)&0x7)) printk("\n");
+		}
+	}
+}
+
+/* For testing */
+static void print_vmalloc_first_tables(void)
+{
+
+#define PRESENT	0x800	/* Bit 11 */
+
+	/*
+	 * Do it really dirty by looking at raw addresses,
+         * raw offsets, no types. If we used pgtable/pgalloc
+	 * macros/definitions we could hide potential bugs.
+	 *
+	 * Note that pointers are 32-bit for CDC.
+	 */
+	long pgdt, pmdt, ptet;
+
+	pgdt = (long) &swapper_pg_dir;
+	printk("-->PGD (0x%08lx):\n", pgdt);
+	print_DIR(pgdt);
+	printk("\n");
+
+	/* VMALLOC pool is mapped at 0xc0000000, second (pointer) entry in PGD */
+	pgdt += 4;
+	pmdt = (long) (* (long *) pgdt);
+	if (!(pmdt & PRESENT)) {
+		printk("No PMD\n");
+		return;
+	} else pmdt &= 0xfffff000;
+
+	printk("-->PMD (0x%08lx):\n", pmdt);
+	print_DIR(pmdt);
+	printk("\n");
+
+	/* Get the pmdt displacement for 0xc0000000 */
+	pmdt += 2048;
+
+	/* just look at first two address ranges ... */
+        /* ... 0xc0000000 ... */
+	ptet = (long) (* (long *) pmdt);
+	if (!(ptet & PRESENT)) {
+		printk("No PTE0\n");
+		return;
+	} else ptet &= 0xfffff000;
+
+	printk("-->PTE0 (0x%08lx):\n", ptet);
+	print_PTE(ptet);
+	printk("\n");
+
+        /* ... 0xc0001000 ... */
+	ptet += 4;
+	if (!(ptet & PRESENT)) {
+		printk("No PTE1\n");
+		return;
+	} else ptet &= 0xfffff000;
+	printk("-->PTE1 (0x%08lx):\n", ptet);
+	print_PTE(ptet);
+	printk("\n");
+}
+#else
+#define print_vmalloc_first_tables()
+#endif	/* VM_SHOW_TABLES */
+
+static void test_VM(void)
+{
+	void *a, *b, *c;
+
+#ifdef VM_SHOW_TABLES
+	printk("Initial PGD/PMD/PTE\n");
+#endif
+        print_vmalloc_first_tables();
+
+	printk("Allocating 2 bytes\n");
+	a = vmalloc(2);
+        print_vmalloc_first_tables();
+        
+	printk("Allocating 4100 bytes\n");
+	b = vmalloc(4100);
+        print_vmalloc_first_tables();
+
+	printk("Allocating 20234 bytes\n");
+	c = vmalloc(20234);
+        print_vmalloc_first_tables();
+
+#ifdef VM_TEST_FAULT
+	/* Here you may want to fault ! */
+
+#ifdef VM_TEST_RTLBMISS
+	printk("Ready to fault upon read.\n");
+	if (* (char *) a) {
+		printk("RTLBMISSed on area a !\n");
+	}
+	printk("RTLBMISSed on area a !\n");
+#endif
+
+#ifdef VM_TEST_WTLBMISS
+	printk("Ready to fault upon write.\n");
+	*((char *) b) = 'L';
+	printk("WTLBMISSed on area b !\n");
+#endif
+
+#endif	/* VM_TEST_FAULT */
+
+	printk("Deallocating the 4100 byte chunk\n");
+	vfree(b);
+        print_vmalloc_first_tables();
+
+	printk("Deallocating the 2 byte chunk\n");
+	vfree(a);
+        print_vmalloc_first_tables();
+
+	printk("Deallocating the last chunk\n");
+	vfree(c);
+        print_vmalloc_first_tables();
+}
+
+extern unsigned long volatile jiffies;
+int once = 0;
+unsigned long old_jiffies;
+int pid = -1, pgid = -1;
+
+void idle_trace(void)
+{
+
+	_syscall0(int, getpid)
+	_syscall1(int, getpgid, int, pid)
+
+	if (!once) {
+        	/* VM allocation/deallocation simple test */
+		test_VM();
+		pid = getpid();
+
+        	printk("Got all through to Idle !!\n");
+        	printk("I'm now going to loop forever ...\n");
+        	printk("Any ! below is a timer tick.\n");
+		printk("Any . below is a getpgid system call from pid = %d.\n", pid);
+
+
+        	old_jiffies = jiffies;
+		once++;
+	}
+
+	if (old_jiffies != jiffies) {
+		old_jiffies = jiffies - old_jiffies;
+		switch (old_jiffies) {
+		case 1:
+			printk("!");
+			break;
+		case 2:
+			printk("!!");
+			break;
+		case 3:
+			printk("!!!");
+			break;
+		case 4:
+			printk("!!!!");
+			break;
+		default:
+			printk("(%d!)", (int) old_jiffies);
+		}
+		old_jiffies = jiffies;
+	}
+	pgid = getpgid(pid);
+	printk(".");
+}
+#else
+#define idle_trace()	do { } while (0)
+#endif	/* IDLE_TRACE */
+
+static int hlt_counter = 1;
+
+#define HARD_IDLE_TIMEOUT (HZ / 3)
+
+void disable_hlt(void)
+{
+	hlt_counter++;
+}
+
+void enable_hlt(void)
+{
+	hlt_counter--;
+}
+
+static int __init nohlt_setup(char *__unused)
+{
+	hlt_counter = 1;
+	return 1;
+}
+
+static int __init hlt_setup(char *__unused)
+{
+	hlt_counter = 0;
+	return 1;
+}
+
+__setup("nohlt", nohlt_setup);
+__setup("hlt", hlt_setup);
+
+static inline void hlt(void)
+{
+	if (hlt_counter)
+		return;
+
+	/* 
+	 * FIXME: Is there any reason why we can't just do a "sleep"
+	 * instead of this crap?
+	 */
+	__asm__ __volatile__ (
+		".int %0\n\t"
+		: /* no outputs */
+		: "g" (le32_to_cpu(0x6ff7fff0))
+		: "memory"
+	);
+}
+
+/*
+ * The idle loop on a uniprocessor SH..
+ */ 
+void cpu_idle(void *unused)
+{
+	/* endless idle loop with no priority at all */
+	init_idle();
+	current->nice = 20;
+	current->counter = -100;
+
+	while (1) {
+		while (!current->need_resched) {
+			if (hlt_counter)
+				continue;
+			__sti();
+			idle_trace();
+			hlt();
+		}
+		schedule();
+		check_pgt_cache();
+	}
+}
+
+void machine_restart(char * __unused)
+{
+	extern void phys_stext(void);
+
+	phys_stext();
+}
+
+void machine_halt(void)
+{
+	for (;;);
+}
+
+void machine_power_off(void)
+{
+	enter_deep_standby();
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	unsigned long long ah, al, bh, bl, ch, cl;
+
+	printk("\n");
+
+	ah = (regs->pc) >> 32;
+	al = (regs->pc) & 0xffffffff;
+	bh = (regs->regs[18]) >> 32;
+	bl = (regs->regs[18]) & 0xffffffff;
+	ch = (regs->regs[15]) >> 32;
+	cl = (regs->regs[15]) & 0xffffffff;
+	printk("PC  : %08Lx%08Lx LINK: %08Lx%08Lx SP  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->sr) >> 32;
+	al = (regs->sr) & 0xffffffff;
+        asm volatile ("getcon   " __c13 ", %0" : "=r" (bh));
+        asm volatile ("getcon   " __c13 ", %0" : "=r" (bl));
+	bh = (bh) >> 32;
+	bl = (bl) & 0xffffffff;
+        asm volatile ("getcon   " __c17 ", %0" : "=r" (ch));
+        asm volatile ("getcon   " __c17 ", %0" : "=r" (cl));
+	ch = (ch) >> 32;
+	cl = (cl) & 0xffffffff;
+	printk("SR  : %08Lx%08Lx TEA : %08Lx%08Lx KCR0: %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[0]) >> 32;
+	al = (regs->regs[0]) & 0xffffffff;
+	bh = (regs->regs[1]) >> 32;
+	bl = (regs->regs[1]) & 0xffffffff;
+	ch = (regs->regs[2]) >> 32;
+	cl = (regs->regs[2]) & 0xffffffff;
+	printk("R0  : %08Lx%08Lx R1  : %08Lx%08Lx R2  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[3]) >> 32;
+	al = (regs->regs[3]) & 0xffffffff;
+	bh = (regs->regs[4]) >> 32;
+	bl = (regs->regs[4]) & 0xffffffff;
+	ch = (regs->regs[5]) >> 32;
+	cl = (regs->regs[5]) & 0xffffffff;
+	printk("R3  : %08Lx%08Lx R4  : %08Lx%08Lx R5  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[6]) >> 32;
+	al = (regs->regs[6]) & 0xffffffff;
+	bh = (regs->regs[7]) >> 32;
+	bl = (regs->regs[7]) & 0xffffffff;
+	ch = (regs->regs[8]) >> 32;
+	cl = (regs->regs[8]) & 0xffffffff;
+	printk("R6  : %08Lx%08Lx R7  : %08Lx%08Lx R8  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[9]) >> 32;
+	al = (regs->regs[9]) & 0xffffffff;
+	bh = (regs->regs[10]) >> 32;
+	bl = (regs->regs[10]) & 0xffffffff;
+	ch = (regs->regs[11]) >> 32;
+	cl = (regs->regs[11]) & 0xffffffff;
+	printk("R9  : %08Lx%08Lx R10 : %08Lx%08Lx R11 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[12]) >> 32;
+	al = (regs->regs[12]) & 0xffffffff;
+	bh = (regs->regs[13]) >> 32;
+	bl = (regs->regs[13]) & 0xffffffff;
+	ch = (regs->regs[14]) >> 32;
+	cl = (regs->regs[14]) & 0xffffffff;
+	printk("R12 : %08Lx%08Lx R13 : %08Lx%08Lx R14 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[16]) >> 32;
+	al = (regs->regs[16]) & 0xffffffff;
+	bh = (regs->regs[17]) >> 32;
+	bl = (regs->regs[17]) & 0xffffffff;
+	ch = (regs->regs[19]) >> 32;
+	cl = (regs->regs[19]) & 0xffffffff;
+	printk("R16 : %08Lx%08Lx R17 : %08Lx%08Lx R19 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[20]) >> 32;
+	al = (regs->regs[20]) & 0xffffffff;
+	bh = (regs->regs[21]) >> 32;
+	bl = (regs->regs[21]) & 0xffffffff;
+	ch = (regs->regs[22]) >> 32;
+	cl = (regs->regs[22]) & 0xffffffff;
+	printk("R20 : %08Lx%08Lx R21 : %08Lx%08Lx R22 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[23]) >> 32;
+	al = (regs->regs[23]) & 0xffffffff;
+	bh = (regs->regs[24]) >> 32;
+	bl = (regs->regs[24]) & 0xffffffff;
+	ch = (regs->regs[25]) >> 32;
+	cl = (regs->regs[25]) & 0xffffffff;
+	printk("R23 : %08Lx%08Lx R24 : %08Lx%08Lx R25 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[26]) >> 32;
+	al = (regs->regs[26]) & 0xffffffff;
+	bh = (regs->regs[27]) >> 32;
+	bl = (regs->regs[27]) & 0xffffffff;
+	ch = (regs->regs[28]) >> 32;
+	cl = (regs->regs[28]) & 0xffffffff;
+	printk("R26 : %08Lx%08Lx R27 : %08Lx%08Lx R28 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[29]) >> 32;
+	al = (regs->regs[29]) & 0xffffffff;
+	bh = (regs->regs[30]) >> 32;
+	bl = (regs->regs[30]) & 0xffffffff;
+	ch = (regs->regs[31]) >> 32;
+	cl = (regs->regs[31]) & 0xffffffff;
+	printk("R29 : %08Lx%08Lx R30 : %08Lx%08Lx R31 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[32]) >> 32;
+	al = (regs->regs[32]) & 0xffffffff;
+	bh = (regs->regs[33]) >> 32;
+	bl = (regs->regs[33]) & 0xffffffff;
+	ch = (regs->regs[34]) >> 32;
+	cl = (regs->regs[34]) & 0xffffffff;
+	printk("R32 : %08Lx%08Lx R33 : %08Lx%08Lx R34 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[35]) >> 32;
+	al = (regs->regs[35]) & 0xffffffff;
+	bh = (regs->regs[36]) >> 32;
+	bl = (regs->regs[36]) & 0xffffffff;
+	ch = (regs->regs[37]) >> 32;
+	cl = (regs->regs[37]) & 0xffffffff;
+	printk("R35 : %08Lx%08Lx R36 : %08Lx%08Lx R37 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[38]) >> 32;
+	al = (regs->regs[38]) & 0xffffffff;
+	bh = (regs->regs[39]) >> 32;
+	bl = (regs->regs[39]) & 0xffffffff;
+	ch = (regs->regs[40]) >> 32;
+	cl = (regs->regs[40]) & 0xffffffff;
+	printk("R38 : %08Lx%08Lx R39 : %08Lx%08Lx R40 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[41]) >> 32;
+	al = (regs->regs[41]) & 0xffffffff;
+	bh = (regs->regs[42]) >> 32;
+	bl = (regs->regs[42]) & 0xffffffff;
+	ch = (regs->regs[43]) >> 32;
+	cl = (regs->regs[43]) & 0xffffffff;
+	printk("R41 : %08Lx%08Lx R42 : %08Lx%08Lx R43 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[44]) >> 32;
+	al = (regs->regs[44]) & 0xffffffff;
+	bh = (regs->regs[45]) >> 32;
+	bl = (regs->regs[45]) & 0xffffffff;
+	ch = (regs->regs[46]) >> 32;
+	cl = (regs->regs[46]) & 0xffffffff;
+	printk("R44 : %08Lx%08Lx R45 : %08Lx%08Lx R46 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[47]) >> 32;
+	al = (regs->regs[47]) & 0xffffffff;
+	bh = (regs->regs[48]) >> 32;
+	bl = (regs->regs[48]) & 0xffffffff;
+	ch = (regs->regs[49]) >> 32;
+	cl = (regs->regs[49]) & 0xffffffff;
+	printk("R47 : %08Lx%08Lx R48 : %08Lx%08Lx R49 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[50]) >> 32;
+	al = (regs->regs[50]) & 0xffffffff;
+	bh = (regs->regs[51]) >> 32;
+	bl = (regs->regs[51]) & 0xffffffff;
+	ch = (regs->regs[52]) >> 32;
+	cl = (regs->regs[52]) & 0xffffffff;
+	printk("R50 : %08Lx%08Lx R51 : %08Lx%08Lx R52 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[53]) >> 32;
+	al = (regs->regs[53]) & 0xffffffff;
+	bh = (regs->regs[54]) >> 32;
+	bl = (regs->regs[54]) & 0xffffffff;
+	ch = (regs->regs[55]) >> 32;
+	cl = (regs->regs[55]) & 0xffffffff;
+	printk("R53 : %08Lx%08Lx R54 : %08Lx%08Lx R55 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[56]) >> 32;
+	al = (regs->regs[56]) & 0xffffffff;
+	bh = (regs->regs[57]) >> 32;
+	bl = (regs->regs[57]) & 0xffffffff;
+	ch = (regs->regs[58]) >> 32;
+	cl = (regs->regs[58]) & 0xffffffff;
+	printk("R56 : %08Lx%08Lx R57 : %08Lx%08Lx R58 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[59]) >> 32;
+	al = (regs->regs[59]) & 0xffffffff;
+	bh = (regs->regs[60]) >> 32;
+	bl = (regs->regs[60]) & 0xffffffff;
+	ch = (regs->regs[61]) >> 32;
+	cl = (regs->regs[61]) & 0xffffffff;
+	printk("R59 : %08Lx%08Lx R60 : %08Lx%08Lx R61 : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->regs[62]) >> 32;
+	al = (regs->regs[62]) & 0xffffffff;
+	bh = (regs->tregs[0]) >> 32;
+	bl = (regs->tregs[0]) & 0xffffffff;
+	ch = (regs->tregs[1]) >> 32;
+	cl = (regs->tregs[1]) & 0xffffffff;
+	printk("R62 : %08Lx%08Lx T0  : %08Lx%08Lx T1  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->tregs[2]) >> 32;
+	al = (regs->tregs[2]) & 0xffffffff;
+	bh = (regs->tregs[3]) >> 32;
+	bl = (regs->tregs[3]) & 0xffffffff;
+	ch = (regs->tregs[4]) >> 32;
+	cl = (regs->tregs[4]) & 0xffffffff;
+	printk("T2  : %08Lx%08Lx T3  : %08Lx%08Lx T4  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	ah = (regs->tregs[5]) >> 32;
+	al = (regs->tregs[5]) & 0xffffffff;
+	bh = (regs->tregs[6]) >> 32;
+	bl = (regs->tregs[6]) & 0xffffffff;
+	ch = (regs->tregs[7]) >> 32;
+	cl = (regs->tregs[7]) & 0xffffffff;
+	printk("T5  : %08Lx%08Lx T6  : %08Lx%08Lx T7  : %08Lx%08Lx\n",
+	       ah, al, bh, bl, ch, cl);
+
+	/*
+	 * If we're in kernel mode, dump the stack too..
+	 */
+	if (!user_mode(regs)) {
+		extern void show_task(unsigned long *sp);
+		unsigned long sp = regs->regs[15] & 0xffffffff;
+
+		show_task((unsigned long *)sp);
+	}
+}
+
+struct task_struct * alloc_task_struct(void)
+{
+	/* Get task descriptor pages */
+	return (struct task_struct *)
+		__get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE));
+}
+
+void free_task_struct(struct task_struct *p)
+{
+	free_pages((unsigned long) p, get_order(THREAD_SIZE));
+}
+
+/*
+ * Create a kernel thread
+ */
+
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process(ie the swapper or direct descendants
+ * who haven't done an "execve()") should use this: it will work within
+ * a system call from a "real" process, but the process memory space will
+ * not be free'd until both the parent and the child have exited.
+ */
+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	/* A bit less processor dependent than older sh ... */
+
+	unsigned int reply;
+
+static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp)
+static __inline__ _syscall1(int,exit,int,ret)
+
+	reply = clone(flags | CLONE_VM, 0);
+	if (!reply) {
+		/* Child */
+		reply = exit(fn(arg));
+	}
+
+	return reply;
+}
+
+/*
+ * Free current thread data structures etc..
+ */
+ext;
+
+		if (!map) {s->r);
+	}
+
+		eturh reply;
+}
+
+/*
+ * Free curr,nt thread data structures etc..
+ */+		eeu = m linux))